lineadraw 0.8.0 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +249 -198
- package/bin/lineadraw.mjs +15 -110
- package/dist/bridge.d.ts +102 -0
- package/dist/bridge.js +16 -0
- package/dist/{chunk-VWED6V6F.js → chunk-BQCSFVAF.js} +401 -81
- package/dist/chunk-BQCSFVAF.js.map +1 -0
- package/dist/chunk-L2CWZAKW.js +141 -0
- package/dist/chunk-L2CWZAKW.js.map +1 -0
- package/dist/exportDxf-T2RTSTH5.js +10 -0
- package/dist/exportDxf-T2RTSTH5.js.map +1 -0
- package/dist/sdk.d.ts +469 -234
- package/dist/sdk.js +164 -168
- package/dist/sdk.js.map +1 -1
- package/lineadraw.d.ts +304 -1617
- package/package.json +2 -2
- package/templates/sample.block.ts +2 -2
- package/dist/chunk-VWED6V6F.js.map +0 -1
- package/dist/exportDxf-2VU5475O.js +0 -8
- /package/dist/{exportDxf-2VU5475O.js.map → bridge.js.map} +0 -0
package/dist/sdk.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/document.ts","../../core/src/geometry/arcs.ts","../../core/src/geometry/ellipse.ts","../../core/src/geometry/bounds.ts","../../core/src/geometry/polyline.ts","../../core/src/model/document.ts","../../core/src/model/paperLayout.ts","../../core/src/model/scale.ts","../../core/src/model/defaults.ts","../../core/src/model/assets.ts","../../core/src/serialize.ts","../../core/src/export/svg/svgSink.ts","../../core/src/paint/painters/line.ts","../../core/src/paint/painters/point.ts","../../core/src/paint/painters/polyline.ts","../../core/src/paint/painters/circle.ts","../../core/src/paint/painters/arc.ts","../../core/src/paint/painters/ellipse.ts","../../core/src/paint/painters/hatch.ts","../../core/src/paint/painters/arrows.ts","../../core/src/paint/painters/text.ts","../../core/src/paint/painters/dimension.ts","../../core/src/paint/lineTypes.ts","../../core/src/paint/painters/block.ts","../../core/src/paint/painters/viewport.ts","../../core/src/paint/painters/image.ts","../../core/src/paint/painters/table.ts","../../core/src/snap/nearIndex.ts","../../core/src/snap/buildEntry.ts","../../core/src/import/dxf/importDxf.ts","../../core/src/import/dxf/styleTables.ts","../../core/src/geometry/nurbs.ts","../../core/src/geometry/band.ts","../../core/src/import/dxf/blockDefinitions.ts","../../core/src/import/dxf/dxfLines.ts","../../core/src/import/dxf/entityLedger.ts","../../core/src/import/dxf/extraEntities.ts","../../core/src/import/dxf/objectsSection.ts","../../core/src/reference/reference.ts","../../core/src/paint/style.ts","../../core/src/paint/rebaseSink.ts","../../core/src/paint/painters/reference.ts","../../core/src/paint/painters/index.ts","../../core/src/extensions/blockThumbnail.ts","../../core/src/extensions/scriptModules.ts","../../core/src/marketplace/catalog.ts","../../core/src/extensions/commandModules.ts","../../core/src/marketplace/github.ts","../../core/src/paint/fontCoverage.ts","../../core/src/paint/layoutPaint.ts","../../core/src/paint/printPalette.ts","../../core/src/operations/diff.ts","../../core/src/import/dxf/importPlan.ts","../../core/src/dwg.ts","../../core/src/export/pdf/exportPdf.ts","../../core/src/export/pdf/pdfSink.ts","../../core/src/export/svg/renderSvg.ts","../../core/src/import/pdf/convertPage.ts","../../core/src/import/pdf/importPdf.ts","../../core/src/operations/types.ts","../../core/src/operations/apply.ts","../../core/src/operations/kernel.ts","../../core/src/drawing/localDrawing.ts","../../core/src/drawing/runCommand.ts","../../core/src/export/png/renderPng.ts"],"sourcesContent":["// The scripting-first document handle: core's browser-safe `LocalDrawing`\n// (the `Drawing` interface over one DocumentKernel — docs/interaction-\n// surface.md) plus the Node-only pieces: file open/save, PNG rasterization,\n// PDF export with the embedded fonts, and path-taking import/export helpers.\n// Ergonomics only — never new semantics. See docs/agent-sdk-mcp.md.\n\nimport { readFile, writeFile } from \"node:fs/promises\";\nimport { dirname, isAbsolute, resolve } from \"node:path\";\nimport {\n approximateTextMeasurer,\n contentFromDocument,\n documentFromDxf,\n documentFromImage,\n documentFromJson,\n dwgToDxf,\n emptyDocument,\n imagePixelSize,\n measureContentBounds,\n pdfToModel,\n documentWithObjects,\n type LineaDocument as CoreDocument,\n type ReferenceObject,\n type ReferenceContent,\n type ReferenceSource,\n rebaseReferenceSource,\n LocalDrawing,\n memoryMarketplaceHost,\n normalizeMarketplaces,\n type MarketplaceConfig,\n renderLayoutsToPdf,\n selectPdfLayouts,\n runCommandModule,\n runDocumentCommand,\n usedEmbedFontIds,\n type DxfImportOptions,\n type DxfImportReport,\n type LineaDocument,\n type PdfImportOptions,\n type PdfImportReport,\n type PointInput,\n type RenderPdfOptions,\n type RenderPngOptions,\n} from \"@lineadraw/core\";\nimport {\n embeddedPdfFonts,\n renderLayoutToPng,\n renderModelToPng,\n} from \"@lineadraw/core/node\";\nimport type { DwgVersion } from \"@lineadraw/core\";\n\nexport type {\n AddOptions,\n DocumentSummary,\n DxfImportOptions,\n DxfImportReport,\n LayoutOptions,\n ObjectInput,\n PdfImportReport,\n PointInput,\n QueryFilter,\n RenderPdfOptions as PdfOptions,\n RenderPngOptions as PngOptions,\n RenderSvgOptions as SvgOptions,\n SheetName,\n ViewportOptions,\n} from \"@lineadraw/core\";\nexport { parseScale } from \"@lineadraw/core\";\n\n/** A drawing's name from its file: the base name without the extension. */\nconst nameOfPath = (path: string): string =>\n (path.split(/[/\\\\]/).pop() ?? path).replace(/\\.(linea|lineadraw)$/i, \"\");\n\n/** A referenced file's bytes → a document, by format (Node: a raster PDF\n * reference draws as vectors — there is no canvas to rasterize with). */\nconst referenceDocument = async (\n ref: ReferenceObject,\n bytes: Uint8Array,\n): Promise<CoreDocument> => {\n switch (ref.format) {\n case \"linea\":\n return documentFromJson(new TextDecoder().decode(bytes));\n case \"dxf\":\n return documentFromDxf(new TextDecoder().decode(bytes));\n case \"dwg\":\n return documentFromDxf(await dwgToDxf(bytes));\n case \"pdf\": {\n const result = await pdfToModel(bytes, { page: ref.pdfPage ?? 1 });\n return documentWithObjects((d) => ({\n objects: result.objects.map((o) => ({ ...o, layerId: d.layers[0].id })),\n }));\n }\n case \"png\":\n case \"jpg\": {\n const size = imagePixelSize(bytes);\n if (!size) throw new Error(`${ref.name}: not a PNG/JPEG`);\n const mime = ref.format === \"png\" ? \"image/png\" : \"image/jpeg\";\n const px = 25.4 / 96;\n return documentFromImage(\n `data:${mime};base64,${Buffer.from(bytes).toString(\"base64\")}`,\n size.width * px,\n size.height * px,\n );\n }\n }\n};\n\nexport class Drawing extends LocalDrawing {\n private path?: string;\n\n constructor(\n doc: LineaDocument,\n filePath?: string,\n migration: { from: number; to: number } | null = null,\n ) {\n super(doc, migration);\n this.path = filePath;\n if (filePath) this.name = nameOfPath(filePath);\n // Node can read local folder marketplaces; the list starts with the\n // public collection (configureMarketplaces / addMarketplaces extend it).\n this.setMarketplaceHost(\n memoryMarketplaceHost({\n readFile: (folder, rel) => readFile(resolve(folder, rel), \"utf8\"),\n }),\n );\n }\n\n /** The marketplaces this drawing searches and installs from, in priority\n * order (the public collection is always present, last by default) —\n * process configuration, nothing is written to the file. */\n configureMarketplaces(list: readonly MarketplaceConfig[]): void {\n const host = memoryMarketplaceHost({\n readFile: (folder, rel) => readFile(resolve(folder, rel), \"utf8\"),\n });\n host.set(normalizeMarketplaces(list));\n this.setMarketplaceHost(host);\n }\n\n /** The file this drawing was opened from / last saved to, if any. */\n get filePath(): string | undefined {\n return this.path;\n }\n\n /** Block scripts compiled AND referenced files loaded (relative paths\n * against this drawing's folder) — renders include their content. A file\n * that can't be read stays a frame. */\n override async ready(): Promise<void> {\n await super.ready();\n const refs = [\n ...this.objects,\n ...this.layouts.flatMap((l) => l.objects),\n ].filter((o): o is ReferenceObject => o.type === \"reference\");\n for (const ref of refs) {\n const content = await this.loadReference(ref, ref.source, 0, new Set());\n if (content) this.referenceContent.set(ref.id, content);\n else this.referenceContent.delete(ref.id); // missing → frame\n }\n }\n\n /** One reference's content (null when unreadable); a .linea's own\n * references load relative to it — depth-limited, never re-entering a\n * file above in the chain (the editor's rules). */\n private async loadReference(\n ref: ReferenceObject,\n source: ReferenceSource,\n depth: number,\n seen: ReadonlySet<string>,\n ): Promise<ReferenceContent | null> {\n let doc: CoreDocument;\n try {\n doc = await referenceDocument(ref, await this.readSource(source));\n } catch {\n return null;\n }\n const content = contentFromDocument(doc, ref.id);\n if (ref.format === \"linea\" && depth + 1 < 4) {\n const above = new Set(seen).add(JSON.stringify(source));\n const nested = new Map<string, ReferenceContent>();\n for (const child of content.objects) {\n if (child.type !== \"reference\") continue;\n const childSource = rebaseReferenceSource(child.source, source);\n if (above.has(JSON.stringify(childSource))) continue;\n const c = await this.loadReference(\n child,\n childSource,\n depth + 1,\n above,\n );\n if (c) nested.set(child.id, c);\n }\n content.resolveReference = (r) => nested.get(r.id) ?? null;\n }\n return {\n ...content,\n bounds: measureContentBounds(content, approximateTextMeasurer),\n };\n }\n\n private async readSource(source: ReferenceSource): Promise<Uint8Array> {\n if (source.kind === \"url\") {\n const res = await fetch(source.url);\n if (!res.ok) throw new Error(`HTTP ${res.status}`);\n return new Uint8Array(await res.arrayBuffer());\n }\n const p = source.path;\n const abs =\n isAbsolute(p) || !this.path ? p : resolve(dirname(this.path), p);\n return new Uint8Array(await readFile(abs));\n }\n\n // --- render / export (Node) ------------------------------------------------\n\n /** Rasterize model space (or a paper layout via `layout`) to PNG bytes\n * (Node only — lazy native rasterizer). */\n async renderPng(opts: RenderPngOptions = {}): Promise<Uint8Array> {\n if (opts.layout !== undefined)\n return renderLayoutToPng(\n this.resolveLayout(opts.layout),\n this.paintContext(),\n opts,\n );\n return renderModelToPng(this.paintContext(), opts);\n }\n\n /** Multi-page PDF of the layouts (default: all) with the embedded fonts. */\n async renderPdf(opts: RenderPdfOptions = {}): Promise<Uint8Array> {\n const doc = this.state;\n const layouts = selectPdfLayouts(doc.layouts, opts, () =>\n this.makeLayout(\"Layout 1\"),\n );\n const pdf = renderLayoutsToPdf(\n layouts,\n this.paintContext(),\n embeddedPdfFonts(usedEmbedFontIds(doc)),\n );\n return new Uint8Array(pdf.output(\"arraybuffer\"));\n }\n\n async exportSvg(\n path: string,\n opts?: Parameters<LocalDrawing[\"renderSvg\"]>[0],\n ): Promise<void> {\n await writeFile(path, this.renderSvg(opts), \"utf8\");\n }\n async exportPng(path: string, opts?: RenderPngOptions): Promise<void> {\n await writeFile(path, await this.renderPng(opts));\n }\n async exportDxf(path: string): Promise<void> {\n await writeFile(path, await this.toDxf(), \"utf8\");\n }\n async exportDwg(\n path: string,\n opts?: { version?: DwgVersion },\n ): Promise<void> {\n await writeFile(path, await this.toDwg(opts));\n }\n async exportPdf(path: string, opts?: RenderPdfOptions): Promise<void> {\n await writeFile(path, await this.renderPdf(opts));\n }\n /** Write the `.linea` JSON; `path` defaults to (and updates) filePath. */\n async save(path?: string): Promise<string> {\n const target = path ?? this.path;\n if (!target)\n throw new Error(\n \"save() needs a path (document was not opened from a file)\",\n );\n this.path = target;\n this.name = nameOfPath(target); // the file name IS the name\n await writeFile(target, this.toLinea(), \"utf8\");\n return target;\n }\n\n // --- import from files (the in-memory imports are core's LocalDrawing) -----------------------------------------------------\n\n async importDxf(\n path: string,\n opts?: DxfImportOptions,\n ): Promise<DxfImportReport> {\n return this.importDxfText(await readFile(path, \"utf8\"), opts);\n }\n\n async importDwg(\n path: string,\n opts?: DxfImportOptions,\n ): Promise<DxfImportReport> {\n return this.importDwgData(await readFile(path), opts);\n }\n\n async importPdf(\n path: string,\n opts?: PdfImportOptions,\n ): Promise<PdfImportReport> {\n const data = await readFile(path);\n return this.importPdfData(\n data.buffer.slice(data.byteOffset, data.byteOffset + data.byteLength),\n opts,\n );\n }\n\n // --- scripts ---------------------------------------------------------------\n\n /** Run a command module source (`defineCommand`) against this drawing as\n * ONE undo step, headlessly: declared `inputs` must be supplied; declared\n * `params` take their defaults unless given by name (unknown names and\n * wrong types throw). Resolves with the script's return value. */\n runScript(\n source: string,\n inputs?: readonly PointInput[],\n params?: Readonly<Record<string, unknown>>,\n ): Promise<unknown> {\n return runCommandModule(source, { document: this, inputs, params });\n }\n\n /** Run one of the document's own commands (by exported id). */\n runUserCommand(\n id: string,\n inputs?: readonly PointInput[],\n params?: Readonly<Record<string, unknown>>,\n ): Promise<unknown> {\n return runDocumentCommand(id, { document: this, inputs, params });\n }\n}\n\n// --- entry points ----------------------------------------------------------\n\n/** A fresh empty document, optionally named (until saved to a file, whose\n * name then takes over). */\nexport interface DrawingOptions {\n /** Marketplaces to search and install from, in priority order (the\n * public collection is appended when missing). Default: the public\n * collection alone. */\n marketplaces?: readonly MarketplaceConfig[];\n}\n\nexport function newDrawing(\n name?: string,\n options: DrawingOptions = {},\n): Drawing {\n const drawing = new Drawing(emptyDocument());\n if (name !== undefined) drawing.name = name;\n if (options.marketplaces) drawing.configureMarketplaces(options.marketplaces);\n return drawing;\n}\n\n/** The pre-migration schema version of raw `.linea` JSON (best effort). */\nconst rawVersion = (text: string): number | null => {\n try {\n const v = (JSON.parse(text) as { version?: unknown }).version;\n return typeof v === \"number\" ? v : null;\n } catch {\n return null;\n }\n};\n\nconst withMigration = (text: string, filePath?: string): Drawing => {\n const from = rawVersion(text);\n const doc = documentFromJson(text);\n const migration =\n from !== null && from !== doc.version ? { from, to: doc.version } : null;\n return new Drawing(doc, filePath, migration);\n};\n\n/** Parse a `.linea` JSON string. */\nexport function drawingFromJson(text: string): Drawing {\n return withMigration(text);\n}\n\n/** Open a `.linea` file (parse + migrate) into an in-process kernel. */\nexport async function openDrawing(\n path: string,\n options: DrawingOptions = {},\n): Promise<Drawing> {\n const doc = withMigration(await readFile(path, \"utf8\"), path);\n if (options.marketplaces) doc.configureMarketplaces(options.marketplaces);\n await doc.ready(); // block scripts evaluate definitively from the start\n return doc;\n}\n","// Arc math, including DXF-style bulge conversion.\n// A bulge is tan(sweep/4): 0 = straight, positive = CCW arc from a to b.\n\nimport type { Vec2 } from \"./vec2\";\nimport {\n add,\n angle,\n cross,\n dist,\n dot,\n len,\n mid,\n norm,\n normAngle,\n perp,\n rot,\n scale,\n sub,\n} from \"./vec2\";\n\nexport interface ArcGeom {\n center: Vec2;\n radius: number;\n /** Start angle, radians CCW from +X. */\n startAngle: number;\n /** End angle. The arc always runs CCW from startAngle to endAngle. */\n endAngle: number;\n}\n\n/** CCW sweep of an arc in (0, 2π]. */\nexport const arcSweep = (a: ArcGeom): number => {\n const s = normAngle(a.endAngle - a.startAngle);\n return s === 0 ? Math.PI * 2 : s;\n};\n\nexport const pointOnArc = (a: ArcGeom, angle: number): Vec2 => ({\n x: a.center.x + Math.cos(angle) * a.radius,\n y: a.center.y + Math.sin(angle) * a.radius,\n});\n\nexport const arcStartPoint = (a: ArcGeom): Vec2 => pointOnArc(a, a.startAngle);\nexport const arcEndPoint = (a: ArcGeom): Vec2 => pointOnArc(a, a.endAngle);\nexport const arcMidPoint = (a: ArcGeom): Vec2 =>\n pointOnArc(a, a.startAngle + arcSweep(a) / 2);\n\n/** Is the angle within the CCW range [startAngle, endAngle]? */\nexport const angleInArc = (a: ArcGeom, angle: number): boolean =>\n normAngle(angle - a.startAngle) <= arcSweep(a) + 1e-12;\n\n/**\n * Convert a bulged polyline segment (a → b, bulge) to arc geometry.\n * Returns null for straight segments (bulge ≈ 0) or degenerate points.\n * Negative bulge = CW visual arc; we normalize so the ArcGeom is always CCW\n * by swapping start/end angles.\n */\nexport const bulgeToArc = (a: Vec2, b: Vec2, bulge: number): ArcGeom | null => {\n if (Math.abs(bulge) < 1e-12) return null;\n const chord = dist(a, b);\n if (chord < 1e-12) return null;\n const sweep = 4 * Math.atan(bulge); // signed, CCW positive\n const radius = Math.abs(chord / (2 * Math.sin(sweep / 2)));\n // Sagitta-based center: offset from chord midpoint along the perpendicular.\n const m = mid(a, b);\n const dir = scale(sub(b, a), 1 / chord);\n // Signed distance from chord midpoint to center, along the left normal of\n // a→b: positive bulge (CCW) puts the center on the left for a minor arc,\n // on the right for a major arc (tan flips sign past π); negative mirrors.\n const h = chord / 2 / Math.tan(sweep / 2);\n const center = add(m, scale(perp(dir), h));\n const angA = angle(sub(a, center));\n const angB = angle(sub(b, center));\n return bulge > 0\n ? { center, radius, startAngle: angA, endAngle: angB }\n : { center, radius, startAngle: angB, endAngle: angA };\n};\n\n/** Bulge value for an arc from a to b through point m (all on the arc). */\nexport const bulgeFrom3Points = (a: Vec2, m: Vec2, b: Vec2): number => {\n // The heading change from chord a→m to chord m→b is half the arc's sweep\n // (inscribed angle), so bulge = tan(sweep/4) = tan(turn/2).\n let turn = angle(sub(b, m)) - angle(sub(m, a));\n while (turn > Math.PI) turn -= 2 * Math.PI;\n while (turn < -Math.PI) turn += 2 * Math.PI;\n return Math.tan(turn / 2);\n};\n\n/**\n * Unit tangent at the END of a bulged segment a → b, pointing in the direction\n * of travel (a → b). Straight segment (bulge ≈ 0) → norm(b - a); an arc's end\n * tangent leads the chord by half the sweep.\n */\nexport const bulgeEndTangent = (a: Vec2, b: Vec2, bulge: number): Vec2 =>\n rot(norm(sub(b, a)), 2 * Math.atan(bulge));\n\n/**\n * Bulge of the circular arc from `start` to `end` whose tangent at `start` is\n * `tangent` (need not be unit) — the tangent-continuous arc. Positive = CCW,\n * 0 when the tangent aligns with the chord (a straight segment). The signed\n * tangent-to-chord angle is half the sweep, so bulge = tan(angle / 2).\n */\nexport const bulgeFromTangent = (\n start: Vec2,\n tangent: Vec2,\n end: Vec2,\n): number => {\n const chord = sub(end, start);\n if (len(chord) < 1e-12 || len(tangent) < 1e-12) return 0;\n const half = Math.atan2(cross(tangent, chord), dot(tangent, chord));\n return Math.tan(half / 2);\n};\n\n/** Circle through 3 points; null when collinear. */\nexport const circleFrom3Points = (\n p1: Vec2,\n p2: Vec2,\n p3: Vec2,\n): { center: Vec2; radius: number } | null => {\n const ax = p1.x;\n const ay = p1.y;\n const bx = p2.x;\n const by = p2.y;\n const cx = p3.x;\n const cy = p3.y;\n const d = 2 * (ax * (by - cy) + bx * (cy - ay) + cx * (ay - by));\n if (Math.abs(d) < 1e-12) return null;\n const a2 = ax * ax + ay * ay;\n const b2 = bx * bx + by * by;\n const c2 = cx * cx + cy * cy;\n const center = {\n x: (a2 * (by - cy) + b2 * (cy - ay) + c2 * (ay - by)) / d,\n y: (a2 * (cx - bx) + b2 * (ax - cx) + c2 * (bx - ax)) / d,\n };\n return { center, radius: dist(center, p1) };\n};\n\n/**\n * Arc through 3 points: start, a point on the arc, end.\n * Returns CCW geometry from start to end passing through the middle point.\n */\nexport const arcFrom3Points = (\n start: Vec2,\n on: Vec2,\n end: Vec2,\n): ArcGeom | null => {\n const c = circleFrom3Points(start, on, end);\n if (!c) return null;\n const angS = angle(sub(start, c.center));\n const angO = angle(sub(on, c.center));\n const angE = angle(sub(end, c.center));\n // CCW from start: does \"on\" lie within the CCW range start→end?\n const ccw: ArcGeom = {\n center: c.center,\n radius: c.radius,\n startAngle: angS,\n endAngle: angE,\n };\n if (angleInArc(ccw, angO)) return ccw;\n return {\n center: c.center,\n radius: c.radius,\n startAngle: angE,\n endAngle: angS,\n };\n};\n\n/** Closest point on an arc to p (accounting for angular range; falls back to nearest endpoint). */\nexport const closestPointOnArc = (a: ArcGeom, p: Vec2): Vec2 => {\n const v = sub(p, a.center);\n const ang = angle(v);\n if (angleInArc(a, ang)) return pointOnArc(a, ang);\n const s = arcStartPoint(a);\n const e = arcEndPoint(a);\n return dist(p, s) <= dist(p, e) ? s : e;\n};\n\n/** Distance from p to the arc curve. */\nexport const distToArc = (a: ArcGeom, p: Vec2): number =>\n dist(p, closestPointOnArc(a, p));\n\n/** Tessellate an arc into points (including both endpoints), targeting a chord tolerance in mm. */\nexport const tessellateArc = (a: ArcGeom, chordTolerance = 0.1): Vec2[] => {\n const sweep = arcSweep(a);\n // chord error e = r(1 - cos(dθ/2)) → dθ = 2·acos(1 - e/r)\n const maxStep =\n a.radius <= chordTolerance\n ? sweep\n : 2 * Math.acos(Math.max(-1, 1 - chordTolerance / a.radius));\n const n = Math.max(2, Math.ceil(sweep / Math.max(maxStep, 1e-3)));\n const pts: Vec2[] = [];\n for (let i = 0; i <= n; i++) {\n pts.push(pointOnArc(a, a.startAngle + (sweep * i) / n));\n }\n return pts;\n};\n","// Ellipse math in DXF form: center + majorAxis endpoint vector + ratio\n// (minor/major). Points are parameterized by t: p(t) = c + M·cos t + m·sin t,\n// where m = perp(M)·ratio. startAngle/endAngle bound a CCW parametric range.\n\nimport type { Vec2 } from \"./vec2\";\nimport { add, distSq, len, normAngle, perp, scale } from \"./vec2\";\n\nexport interface EllipseGeom {\n center: Vec2;\n majorAxis: Vec2;\n /** minor/major in (0, 1]. */\n ratio: number;\n startAngle: number;\n endAngle: number;\n}\n\nexport const ellipseSweep = (e: EllipseGeom): number => {\n const s = normAngle(e.endAngle - e.startAngle);\n return s === 0 ? Math.PI * 2 : s;\n};\n\nexport const isFullEllipse = (e: EllipseGeom): boolean =>\n Math.abs(ellipseSweep(e) - Math.PI * 2) < 1e-9;\n\n/** Area of the full ellipse (π·rx·ry), independent of the angular range. */\nexport const ellipseArea = (e: EllipseGeom): number =>\n Math.PI * len(e.majorAxis) ** 2 * e.ratio;\n\nexport const pointOnEllipse = (e: EllipseGeom, t: number): Vec2 => {\n const minor = scale(perp(e.majorAxis), e.ratio);\n return add(\n add(e.center, scale(e.majorAxis, Math.cos(t))),\n scale(minor, Math.sin(t)),\n );\n};\n\nexport const paramInEllipse = (e: EllipseGeom, t: number): boolean =>\n normAngle(t - e.startAngle) <= ellipseSweep(e) + 1e-12;\n\n/** Max chord deviation (mm) of ellipse tessellations from the true curve. */\nconst ELLIPSE_CHORD_TOLERANCE = 0.1;\n\n/**\n * Tessellate into points (both endpoints included). Parametric steps sized so\n * chord error stays under ~tolerance for the major radius.\n */\nexport const tessellateEllipse = (\n e: EllipseGeom,\n tolerance = ELLIPSE_CHORD_TOLERANCE,\n): Vec2[] => {\n const major = len(e.majorAxis);\n const sweep = ellipseSweep(e);\n const maxStep =\n major <= tolerance\n ? sweep\n : 2 * Math.acos(Math.max(-1, 1 - tolerance / major));\n const n = Math.max(8, Math.ceil(sweep / Math.max(maxStep, 1e-3)));\n const pts: Vec2[] = [];\n for (let i = 0; i <= n; i++) {\n pts.push(pointOnEllipse(e, e.startAngle + (sweep * i) / n));\n }\n return pts;\n};\n\n/**\n * Closest point on the ellipse curve to p — coarse parametric scan refined by\n * golden-section iterations. Good to well under render tolerance; exact\n * root-finding isn't worth it for snapping/hit-testing.\n */\nexport const closestPointOnEllipse = (e: EllipseGeom, p: Vec2): Vec2 => {\n const sweep = ellipseSweep(e);\n const SCAN = 64;\n let bestT = e.startAngle;\n let bestD = Infinity;\n for (let i = 0; i <= SCAN; i++) {\n const t = e.startAngle + (sweep * i) / SCAN;\n const d = distSq(p, pointOnEllipse(e, t));\n if (d < bestD) {\n bestD = d;\n bestT = t;\n }\n }\n // Refine around bestT.\n let lo = bestT - sweep / SCAN;\n let hi = bestT + sweep / SCAN;\n for (let i = 0; i < 24; i++) {\n const m1 = lo + (hi - lo) * 0.382;\n const m2 = lo + (hi - lo) * 0.618;\n if (distSq(p, pointOnEllipse(e, m1)) < distSq(p, pointOnEllipse(e, m2)))\n hi = m2;\n else lo = m1;\n }\n const t = (lo + hi) / 2;\n const clamped = paramInEllipse(e, t) ? t : bestT;\n return pointOnEllipse(e, clamped);\n};\n","// Axis-aligned bounding boxes in world mm.\n\nimport type { Vec2 } from \"./vec2\";\n\nexport interface AABB {\n minX: number;\n minY: number;\n maxX: number;\n maxY: number;\n}\n\nexport const emptyBounds = (): AABB => ({\n minX: Infinity,\n minY: Infinity,\n maxX: -Infinity,\n maxY: -Infinity,\n});\n\nexport const boundsOfPoints = (pts: Vec2[]): AABB => {\n const b = emptyBounds();\n for (const p of pts) {\n if (p.x < b.minX) b.minX = p.x;\n if (p.y < b.minY) b.minY = p.y;\n if (p.x > b.maxX) b.maxX = p.x;\n if (p.y > b.maxY) b.maxY = p.y;\n }\n return b;\n};\n\nexport const unionBounds = (a: AABB, b: AABB): AABB => ({\n minX: Math.min(a.minX, b.minX),\n minY: Math.min(a.minY, b.minY),\n maxX: Math.max(a.maxX, b.maxX),\n maxY: Math.max(a.maxY, b.maxY),\n});\n\nexport const addPointToBounds = (b: AABB, p: Vec2): void => {\n if (p.x < b.minX) b.minX = p.x;\n if (p.y < b.minY) b.minY = p.y;\n if (p.x > b.maxX) b.maxX = p.x;\n if (p.y > b.maxY) b.maxY = p.y;\n};\n\nexport const boundsIntersect = (a: AABB, b: AABB): boolean =>\n a.minX <= b.maxX && a.maxX >= b.minX && a.minY <= b.maxY && a.maxY >= b.minY;\n\nexport const boundsContainBounds = (outer: AABB, inner: AABB): boolean =>\n inner.minX >= outer.minX &&\n inner.maxX <= outer.maxX &&\n inner.minY >= outer.minY &&\n inner.maxY <= outer.maxY;\n\nexport const isEmptyBounds = (b: AABB): boolean =>\n b.minX > b.maxX || b.minY > b.maxY;\n\nexport const boundsCenter = (b: AABB): Vec2 => ({\n x: (b.minX + b.maxX) / 2,\n y: (b.minY + b.maxY) / 2,\n});\n\n/** AABB spanned by two arbitrary corner points. */\nexport const boundsOfCorners = (a: Vec2, b: Vec2): AABB => ({\n minX: Math.min(a.x, b.x),\n minY: Math.min(a.y, b.y),\n maxX: Math.max(a.x, b.x),\n maxY: Math.max(a.y, b.y),\n});\n","// Shared derived geometry for bulged vertex chains (polylines, hatch loops).\n\nimport type { Vec2 } from \"./vec2\";\nimport { angle, dist, dot, normAngle, sub } from \"./vec2\";\nimport type { Segment } from \"./line\";\nimport type { ArcGeom } from \"./arcs\";\nimport {\n arcSweep,\n bulgeFrom3Points,\n bulgeToArc,\n pointOnArc,\n tessellateArc,\n} from \"./arcs\";\n\n/**\n * A vertex of a bulged chain; bulge = tan(sweep/4), 0 = straight (DXF\n * LWPOLYLINE convention). Structurally compatible with the model's\n * zod-derived PolylineVertex — geometry stays model-free.\n */\nexport interface PolylineVertex {\n x: number;\n y: number;\n bulge: number;\n}\n\nexport interface Curves {\n segments: Segment[];\n arcs: ArcGeom[];\n}\n\n/** Exact curves (straight segments + analytic arcs) of a vertex chain. */\nexport const verticesToCurves = (\n vertices: PolylineVertex[],\n closed: boolean,\n): Curves => {\n const segments: Segment[] = [];\n const arcs: ArcGeom[] = [];\n const n = vertices.length;\n const segCount = closed ? n : n - 1;\n for (let i = 0; i < segCount; i++) {\n const va = vertices[i];\n const vb = vertices[(i + 1) % n];\n const a = { x: va.x, y: va.y };\n const b = { x: vb.x, y: vb.y };\n const arc = bulgeToArc(a, b, va.bulge);\n if (arc) arcs.push(arc);\n else segments.push({ a, b });\n }\n return { segments, arcs };\n};\n\n/** Tessellated closed polygon ring of a vertex chain (arc segments flattened). */\nexport const verticesToPolygon = (\n vertices: PolylineVertex[],\n chordTolerance = 0.1,\n): Vec2[] => {\n const ring: Vec2[] = [];\n const n = vertices.length;\n for (let i = 0; i < n; i++) {\n const va = vertices[i];\n const vb = vertices[(i + 1) % n];\n const a = { x: va.x, y: va.y };\n const b = { x: vb.x, y: vb.y };\n ring.push(a);\n const arc = bulgeToArc(a, b, va.bulge);\n if (arc) {\n const pts = tessellateArc(arc, chordTolerance);\n // pts includes endpoints; keep interior points in travel order (a → b).\n const interior = pts.slice(1, -1);\n if (va.bulge < 0) interior.reverse();\n ring.push(...interior);\n }\n }\n return ring;\n};\n\n/** Absolute area enclosed by a polygon ring (shoelace formula). */\nexport const polygonArea = (ring: Vec2[]): number => {\n let sum = 0;\n const n = ring.length;\n for (let i = 0; i < n; i++) {\n const p = ring[i];\n const q = ring[(i + 1) % n];\n sum += p.x * q.y - q.x * p.y;\n }\n return Math.abs(sum) / 2;\n};\n\n/** Length of a vertex chain in mm, bulge arcs exact; `closed` adds the\n * last → first segment. */\nexport const chainLength = (\n points: readonly { x: number; y: number; bulge: number }[],\n closed: boolean,\n): number => {\n let sum = 0;\n const n = closed ? points.length : points.length - 1;\n for (let i = 0; i < n; i++) {\n const a = points[i];\n const b = points[(i + 1) % points.length];\n const arc = bulgeToArc(a, b, a.bulge);\n sum += arc ? arc.radius * arcSweep(arc) : dist(a, b);\n }\n return sum;\n};\n\n/** Area enclosed by a closed polyline (bulge-aware via tessellation). */\nexport const polylineArea = (points: PolylineVertex[]): number =>\n polygonArea(verticesToPolygon(points));\n\n/** Net hatch area: outer loop minus holes (even-odd). */\nexport const hatchArea = (loops: { points: PolylineVertex[] }[]): number => {\n const areas = loops.map((l) => polygonArea(verticesToPolygon(l.points)));\n if (areas.length === 0) return 0;\n const holes = areas.slice(1).reduce((a, b) => a + b, 0);\n return Math.max(areas[0] - holes, 0);\n};\n\n// ---------------------------------------------------------------------------\n// Chain editing (grip editing, add/remove vertex). All functions are pure and\n// return the input array unchanged (same reference) on out-of-range indices.\n// ---------------------------------------------------------------------------\n\n/** Clamp a bulge to the sane editing range: snap |b| < 0.02 to straight, cap ±4. */\nexport const clampBulge = (b: number): number => {\n if (!Number.isFinite(b) || Math.abs(b) < 0.02) return 0;\n return Math.max(-4, Math.min(4, b));\n};\n\n/** Both endpoints of segment segIndex moved by delta; every bulge is kept, so\n * the segment's own arc translates rigidly while its neighbors reshape. */\nexport const translateChainSegment = (\n vertices: PolylineVertex[],\n closed: boolean,\n segIndex: number,\n delta: Vec2,\n): PolylineVertex[] => {\n const n = vertices.length;\n const segCount = closed ? n : n - 1;\n if (segIndex < 0 || segIndex >= segCount) return vertices;\n const j = (segIndex + 1) % n;\n return vertices.map((v, i) =>\n i === segIndex || i === j\n ? { ...v, x: v.x + delta.x, y: v.y + delta.y }\n : v,\n );\n};\n\n/**\n * Insert a vertex on segment segIndex at (the projection of) p; the new\n * vertex lands at index segIndex + 1. A bulged segment splits by sweep\n * fraction so both halves reconstruct the original circle (bulge = tan of a\n * quarter of each half's signed sweep); straight segments stay straight.\n * No-op when p coincides with an endpoint.\n */\nexport const insertChainVertex = (\n vertices: PolylineVertex[],\n closed: boolean,\n segIndex: number,\n p: Vec2,\n): PolylineVertex[] => {\n const n = vertices.length;\n const segCount = closed ? n : n - 1;\n if (segIndex < 0 || segIndex >= segCount) return vertices;\n const va = vertices[segIndex];\n const vb = vertices[(segIndex + 1) % n];\n const a = { x: va.x, y: va.y };\n const b = { x: vb.x, y: vb.y };\n if (dist(p, a) < 1e-9 || dist(p, b) < 1e-9) return vertices;\n const arc = bulgeToArc(a, b, va.bulge);\n let pos: Vec2;\n let bulgeA: number;\n let bulgeB: number;\n if (arc) {\n // Travel fraction t of p's angular projection. ArcGeom is normalized\n // CCW, so for a negative bulge travel a→b runs from endAngle backwards.\n const sweep = arcSweep(arc);\n const ang = angle(sub(p, arc.center));\n const from =\n va.bulge > 0\n ? normAngle(ang - arc.startAngle)\n : normAngle(arc.endAngle - ang);\n let t = from / sweep;\n if (!Number.isFinite(t)) t = 0.5;\n t = Math.min(0.99, Math.max(0.01, t));\n const theta = 4 * Math.atan(va.bulge); // signed total sweep\n bulgeA = Math.tan((t * theta) / 4);\n bulgeB = Math.tan(((1 - t) * theta) / 4);\n pos = pointOnArc(\n arc,\n va.bulge > 0 ? arc.startAngle + t * sweep : arc.endAngle - t * sweep,\n );\n } else {\n const ab = sub(b, a);\n const l2 = dot(ab, ab);\n let t = l2 < 1e-18 ? 0.5 : dot(sub(p, a), ab) / l2;\n t = Math.min(0.99, Math.max(0.01, t));\n pos = { x: a.x + ab.x * t, y: a.y + ab.y * t };\n bulgeA = 0;\n bulgeB = 0;\n }\n const out = vertices.slice();\n out[segIndex] = { ...va, bulge: bulgeA };\n out.splice(segIndex + 1, 0, { x: pos.x, y: pos.y, bulge: bulgeB });\n return out;\n};\n\n/**\n * Remove vertex i, merging its two adjacent segments. Two straight segments\n * merging stay straight (removing a corner shouldn't invent an arc); anything\n * arced re-solves through the removed vertex to roughly preserve the shape.\n * Open-chain endpoints just drop (the adjoining segment disappears).\n * Returns null at the minimum vertex count (open: 2, closed: 3).\n */\nexport const removeChainVertex = (\n vertices: PolylineVertex[],\n closed: boolean,\n i: number,\n): PolylineVertex[] | null => {\n const n = vertices.length;\n if (i < 0 || i >= n) return null;\n if (n <= (closed ? 3 : 2)) return null;\n const out = vertices.slice();\n if (!closed && (i === 0 || i === n - 1)) {\n out.splice(i, 1);\n // Zero the new last vertex's (unused) bulge so closing the chain later\n // doesn't resurrect a stale arc.\n if (i === n - 1) out[out.length - 1] = { ...out[out.length - 1], bulge: 0 };\n return out;\n }\n const j = (i - 1 + n) % n;\n const prev = vertices[j];\n const removed = vertices[i];\n const next = vertices[(i + 1) % n];\n const merged =\n Math.abs(prev.bulge) < 1e-12 && Math.abs(removed.bulge) < 1e-12\n ? 0\n : clampBulge(\n bulgeFrom3Points(\n { x: prev.x, y: prev.y },\n { x: removed.x, y: removed.y },\n { x: next.x, y: next.y },\n ),\n );\n out[j] = { ...prev, bulge: merged };\n out.splice(i, 1);\n return out;\n};\n\n/**\n * Insert a coincident copy right after vertex i. The copy takes over the\n * outgoing segment's bulge (the zero-length lead-in stays straight), so the\n * geometry is unchanged until the copy is dragged apart.\n */\nexport const duplicateChainVertex = (\n vertices: PolylineVertex[],\n i: number,\n): PolylineVertex[] => {\n const n = vertices.length;\n if (i < 0 || i >= n) return vertices;\n const out = vertices.slice();\n out[i] = { ...vertices[i], bulge: 0 };\n out.splice(i + 1, 0, { ...vertices[i] });\n return out;\n};\n\n/** Even-odd point-in-polygon over multiple rings. */\nexport const pointInRings = (rings: Vec2[][], p: Vec2): boolean => {\n let inside = false;\n for (const ring of rings) {\n for (let i = 0, j = ring.length - 1; i < ring.length; j = i++) {\n const a = ring[i];\n const b = ring[j];\n if (\n a.y > p.y !== b.y > p.y &&\n p.x < ((b.x - a.x) * (p.y - a.y)) / (b.y - a.y) + a.x\n ) {\n inside = !inside;\n }\n }\n }\n return inside;\n};\n","import { z } from \"zod\";\nimport { ColorSchema } from \"./common\";\nimport {\n DEFAULT_DIM_STYLE,\n DEFAULT_TEXT_STYLE,\n DimStyleSchema,\n ModelObjectSchema,\n TextStyleSchema,\n} from \"./objects\";\nimport { PaperLayoutSchema } from \"./paperLayout\";\nimport { LineTypeSchema } from \"./lineTypes\";\nimport { HatchPatternSchema } from \"./hatchPatterns\";\nimport { CURRENT_DOCUMENT_VERSION, migrateDocument } from \"./migrations\";\n\nexport const LayerSchema = z.object({\n id: z.string().default(() => crypto.randomUUID()),\n name: z.string().default(\"Layer\"),\n color: ColorSchema.default(\"#e8e8e8\"),\n /** Default line type for objects on this layer. */\n lineType: z.string().default(\"continuous\"),\n /** Default lineweight in mm for objects on this layer. */\n lineWidth: z.number().positive().default(0.25),\n /** Default paint opacity for objects on this layer (objects without their\n * own `opacity` inherit it, like color/lineWidth). */\n opacity: z.number().min(0).max(1).default(1),\n visible: z.boolean().default(true),\n locked: z.boolean().default(false),\n /** Plot flag (AutoCAD-style): false = shown on screen but excluded from\n * PDF/print output. */\n print: z.boolean().default(true),\n});\nexport type Layer = z.infer<typeof LayerSchema>;\n\n/** What hosts call a drawing that has no file (and no name) yet. A\n * document carries no name of its own: the file name IS the name (hosts own\n * it — desktop: the file path, web: the project record). Files that still\n * hold a legacy `name` key parse fine; it is dropped. */\nexport const DEFAULT_DOCUMENT_NAME = \"Untitled project\";\n\n/** Document-wide settings. `units` is declarative so far: geometry is\n * stored in mm and nothing renders in inches yet. */\nexport const DocumentSettingsSchema = z.object({\n units: z.enum([\"mm\", \"in\"]).default(\"mm\"),\n});\nexport type DocumentSettings = z.infer<typeof DocumentSettingsSchema>;\n\nexport const LineaDocumentSchema = z.preprocess(\n migrateDocument,\n z.object({\n /**\n * Stable document identity, stored IN the file so re-opening the same\n * file updates the same project record. Files that predate this field\n * get a fresh id on parse (it sticks after the next save). Save As to a\n * NEW file assigns a fresh id, keeping ids 1:1 with files.\n */\n id: z.string().default(() => crypto.randomUUID()),\n type: z.literal(\"lineadraw\").default(\"lineadraw\"),\n version: z.literal(CURRENT_DOCUMENT_VERSION),\n /** Document-wide settings (`DocumentSettingsSchema`). `units` is\n * declarative for now: geometry is always stored in mm and nothing\n * renders in inches yet. */\n settings: DocumentSettingsSchema.default({ units: \"mm\" }),\n layers: z.array(LayerSchema).min(1),\n currentLayerId: z.string(),\n /** Array order is draw order (bottom to top).\n * Resilient object parsing (calculus pattern): a single corrupt object must\n * not fail the whole document — skip it with a warning instead.\n */\n objects: z.preprocess((raw) => {\n if (!Array.isArray(raw)) return raw;\n return raw.filter((o) => {\n const r = ModelObjectSchema.safeParse(o);\n if (!r.success)\n console.warn(\"Skipping invalid model object:\", o, r.error.message);\n return r.success;\n });\n }, z.array(ModelObjectSchema)),\n layouts: z.array(PaperLayoutSchema).default([]),\n /** Named text styles; objects reference one by styleId (first =\n * default for objects without one). */\n textStyles: z\n .array(TextStyleSchema)\n .min(1)\n .default(() => [{ ...DEFAULT_TEXT_STYLE }]),\n /** Named dimension styles, same referencing model. */\n dimStyles: z\n .array(DimStyleSchema)\n .min(1)\n .default(() => [{ ...DEFAULT_DIM_STYLE }]),\n /**\n * Document-defined line types (model/lineTypes.ts): the definitions a\n * DXF/DWG brought along or a user imported. Objects and layers reference\n * them by NAME, ahead of the built-in catalogue. Additive — absent in\n * older files.\n */\n lineTypes: z.array(LineTypeSchema).default([]),\n /** Document-defined hatch patterns (model/hatchPatterns.ts), same model. */\n hatchPatterns: z.array(HatchPatternSchema).default([]),\n /**\n * Embedded binary assets for image objects: content hash → data URL.\n * Kept IN the document so the .linea file stays self-contained (the\n * cost is base64 in the JSON). Entries orphaned by deleted images just\n * ride along (no GC — deletion is undoable, so eager sweeps would break\n * redo).\n */\n assets: z.record(z.string(), z.string()).default({}),\n /**\n * The block library: raw ES-module sources (JS or TS). Each module\n * exports its own `id`/`name`/`params` metadata plus `draw` (and\n * optionally `place`; the pre-rename `main`/`defineInput` names are\n * frozen aliases) — see blocks/evalBlock.ts.\n */\n blockDefinitions: z.array(z.string()).default([]),\n /**\n * Document-embedded user commands (macro scripts): raw ES-module\n * sources, one `export default defineCommand({...})` per module — see\n * blocks/commandModules.ts. The user's per-device library lives outside\n * the document; these travel with the file.\n */\n commands: z.array(z.string()).default([]),\n }),\n);\nexport type LineaDocument = z.infer<typeof LineaDocumentSchema>;\n","import { z } from \"zod\";\nimport { ModelObjectSchema } from \"./objects\";\n\n/** ISO A-series portrait sizes in mm [width, height]. */\nexport const SHEET_PRESETS = {\n A4: [210, 297],\n A3: [297, 420],\n A2: [420, 594],\n A1: [594, 841],\n A0: [841, 1189],\n} as const satisfies Record<string, readonly [number, number]>;\n\nexport type SheetName = keyof typeof SHEET_PRESETS;\nexport type SheetOrientation = \"portrait\" | \"landscape\";\n/**\n * How callers name a sheet: a bare preset (`\"A3\"` — orientation from\n * context: landscape for a new layout, the current one when patching), a\n * preset with its orientation, or explicit millimetres (orientation baked\n * in).\n */\nexport type SheetSpec =\n | SheetName\n | { name: SheetName; orientation: SheetOrientation }\n | { width: number; height: number };\n\n/**\n * Sheet spec → millimetres. Presets are stored portrait. The ONE place every\n * API (createLayout, updateLayout, tools) resolves sheets; `defaultOrientation`\n * applies to a bare preset name only.\n */\nexport const resolveSheetSize = (\n sheet: SheetSpec = \"A3\",\n defaultOrientation: SheetOrientation = \"landscape\",\n): { width: number; height: number } => {\n if (typeof sheet !== \"string\" && \"width\" in sheet)\n return { width: sheet.width, height: sheet.height };\n const name = typeof sheet === \"string\" ? sheet : sheet.name;\n const orientation =\n typeof sheet === \"string\" ? defaultOrientation : sheet.orientation;\n const preset = SHEET_PRESETS[name];\n if (!preset) throw new Error(`Unknown sheet \"${String(name)}\"`);\n const [w, h] = preset;\n return orientation === \"landscape\"\n ? { width: h, height: w }\n : { width: w, height: h };\n};\n\n/** The orientation a sheet size implies (square counts as portrait). */\nexport const sheetOrientation = (sheet: {\n width: number;\n height: number;\n}): SheetOrientation => (sheet.width > sheet.height ? \"landscape\" : \"portrait\");\n\n/**\n * How authored model colors map to print colors for this layout (paper space\n * previews the same mapping — what you see is what prints):\n * - \"color\": keep colors; near-white neutrals become black (white paper).\n * - \"grayscale\": ink-weight grays — the lighter a color was authored on the\n * dark canvas, the darker it prints.\n * - \"monochrome\": everything black.\n */\nexport const PrintPaletteSchema = z.enum([\"color\", \"grayscale\", \"monochrome\"]);\nexport type PrintPalette = z.infer<typeof PrintPaletteSchema>;\n\nexport const PaperLayoutSchema = z.object({\n id: z.string().default(() => crypto.randomUUID()),\n name: z.string().default(\"Layout\"),\n /** Orientation is baked into width/height at creation. */\n sheet: z\n .object({\n width: z.number().positive(),\n height: z.number().positive(),\n })\n .default({ width: 210, height: 297 }), // A4 portrait\n printPalette: PrintPaletteSchema.default(\"color\"),\n /**\n * Sheet-space objects reuse model primitives (drawn in sheet mm).\n * Viewports live here too, as \"viewport\" objects.\n */\n objects: z.array(ModelObjectSchema).default([]),\n});\nexport type PaperLayout = z.infer<typeof PaperLayoutSchema>;\n","/**\n * Drawing scale → the stored 1:N denominator (model mm per paper mm):\n * `\"1:50\"` → 50, `\"2:1\"` → 0.5; numbers pass through (50 means 1:50), as\n * does a plain numeric string (`\"50\"`).\n */\nexport const parseScale = (scale: number | string): number => {\n if (typeof scale === \"number\") {\n if (!Number.isFinite(scale) || scale <= 0)\n throw new Error(`Invalid scale ${scale}`);\n return scale;\n }\n if (/^\\s*\\d+(?:\\.\\d+)?\\s*$/.test(scale)) return parseScale(Number(scale));\n const m = /^\\s*(\\d+(?:\\.\\d+)?)\\s*:\\s*(\\d+(?:\\.\\d+)?)\\s*$/.exec(scale);\n const paper = m ? Number(m[1]) : NaN;\n const model = m ? Number(m[2]) : NaN;\n if (!(paper > 0) || !(model > 0))\n throw new Error(\n `Invalid scale \"${scale}\" (use \"1:50\", \"2:1\", or a number)`,\n );\n return model / paper;\n};\n","import { LineaDocumentSchema, type LineaDocument } from \"./document\";\nimport { CURRENT_DOCUMENT_VERSION } from \"./migrations\";\n\nexport function emptyDocument(): LineaDocument {\n const layerId = crypto.randomUUID();\n\n return LineaDocumentSchema.parse({\n version: CURRENT_DOCUMENT_VERSION,\n layers: [\n {\n id: layerId,\n name: \"Layer 0\",\n color: \"#e8e8e8\",\n lineWidth: 0.25,\n visible: true,\n locked: false,\n },\n ],\n currentLayerId: layerId,\n objects: [],\n // Deliberately layout-less: a hidden default \"Layout 1\" surprises SDK\n // users (blank first PDF page, layouts.length off by one) and the PDF\n // export already falls back to an auto-fitted sheet. Layouts are created\n // explicitly (editor command / createLayout).\n layouts: [],\n });\n}\n","/**\n * djb2 over the data URL, plus its length — the assets-map content key.\n * Content-keyed so re-adding the same pixels reuses the existing entry.\n */\nexport const hashAsset = (data: string): string => {\n let h = 5381;\n for (let i = 0; i < data.length; i++)\n h = ((h << 5) + h + data.charCodeAt(i)) | 0;\n return `${(h >>> 0).toString(16)}-${data.length.toString(16)}`;\n};\n","import { LineaDocumentSchema, type LineaDocument } from \"./model/document\";\n\n/** Pretty JSON — .linea files are meant to be diffable and inspectable. */\nexport const documentToJson = (doc: LineaDocument): string =>\n JSON.stringify(doc, null, 2);\n\n/** Parse + validate + migrate. Throws on unrecoverable input. */\nexport const documentFromJson = (text: string): LineaDocument =>\n LineaDocumentSchema.parse(JSON.parse(text));\n\n/** How long one synchronous slice of `documentToJsonAsync` may run before\n * it yields (ms). */\nconst SLICE_MS = 30;\n/** Array items stringified per call (one call per item is ~3× slower). */\nconst BATCH = 1000;\n\n// Every piece is stringified inside a one-key wrapper so JSON.stringify lays\n// it out at its real depth, then the wrapper's text is cut off:\n// `{⏎ \"k\": [⏎ a,⏎ b⏎ ]⏎}` → `a,⏎ b` (a batch of array items),\n// `{⏎ \"k\": {⏎ \"h\": v⏎ }⏎}` → `\"h\": v` (one record entry).\nconst ITEMS_HEAD = '{\\n \"k\": [\\n '.length;\nconst ITEMS_TAIL = \"\\n ]\\n}\".length;\nconst ENTRY_HEAD = '{\\n \"k\": {\\n '.length;\nconst ENTRY_TAIL = \"\\n }\\n}\".length;\n\n/**\n * `documentToJson` in slices — byte-identical output, but the top-level\n * arrays (objects, layouts…) are stringified in batches and record members\n * (assets: embedded images) entry by entry, yielding the thread between\n * ~30 ms slices so a save can paint its progress. `onProgress` hears the\n * fraction done at each yield (never for a fast save). The document must\n * not change meanwhile — store snapshots never do.\n */\nexport const documentToJsonAsync = async (\n doc: LineaDocument,\n onProgress?: (fraction: number) => void,\n): Promise<string> => {\n const entries = Object.entries(doc as Record<string, unknown>);\n const isRecord = (v: unknown): v is Record<string, unknown> =>\n typeof v === \"object\" && v !== null && !Array.isArray(v);\n const total = entries.reduce(\n (n, [, v]) =>\n n +\n (Array.isArray(v)\n ? v.length\n : isRecord(v)\n ? Object.keys(v).length || 1\n : 1),\n 0,\n );\n let done = 0;\n let sliceStart = Date.now();\n const tick = async (count: number) => {\n done += count;\n if (Date.now() - sliceStart < SLICE_MS) return;\n onProgress?.(done / total);\n await new Promise((resolve) => setTimeout(resolve, 0));\n sliceStart = Date.now();\n };\n\n const members: string[] = [];\n for (const [key, value] of entries) {\n const name = JSON.stringify(key);\n if (Array.isArray(value) && value.length > 0) {\n const batches: string[] = [];\n for (let i = 0; i < value.length; i += BATCH) {\n batches.push(\n JSON.stringify({ k: value.slice(i, i + BATCH) }, null, 2).slice(\n ITEMS_HEAD,\n -ITEMS_TAIL,\n ),\n );\n await tick(Math.min(BATCH, value.length - i));\n }\n members.push(`${name}: [\\n ${batches.join(\",\\n \")}\\n ]`);\n } else if (isRecord(value) && Object.keys(value).length > 0) {\n const parts: string[] = [];\n for (const [k, v] of Object.entries(value)) {\n if (v === undefined) continue;\n parts.push(\n JSON.stringify({ k: { [k]: v } }, null, 2).slice(\n ENTRY_HEAD,\n -ENTRY_TAIL,\n ),\n );\n await tick(1);\n }\n members.push(\n parts.length\n ? `${name}: {\\n ${parts.join(\",\\n \")}\\n }`\n : `${name}: {}`,\n );\n } else {\n const json = JSON.stringify({ [key]: value }, null, 2);\n if (json !== \"{}\") members.push(json.slice(4, -2));\n await tick(1);\n }\n }\n return members.length ? `{\\n ${members.join(\",\\n \")}\\n}` : \"{}\";\n};\n","// A GeometrySink that emits SVG — the headless render target so agents/CLIs\n// can *see* a drawing instead of re-reading JSON (sibling to PdfSink). World\n// is mm, Y-up; SVG is Y-down, so coordinates are emitted with Y negated\n// (world-up renders up) and the viewBox uses -maxY as its top. Curves are\n// decomposed to cubic béziers via the shared helpers, so screen/PDF/SVG\n// output cannot drift.\n//\n// Transforms are baked into coordinates (viewport projection works), and clip\n// rects are honored via <clipPath> groups — so paper-layout viewport content\n// is clipped to its frame, like the canvas/PDF sinks.\n\nimport {\n arcToBeziers,\n ellipseArcToBeziers,\n matApply,\n matIdentity,\n matMultiply,\n signedArcSweep,\n type FillStyle,\n type GeometrySink,\n type Mat2x3,\n type Rect,\n type ImageSpec,\n type StrokeStyle,\n type TextSpec,\n} from \"../../paint/sink\";\nimport { approximateTextMeasurer } from \"../../paint/textMeasurer\";\nimport type { TextMeasurer } from \"../../paint/textMetrics\";\nimport { parseFontFace, resolveFont } from \"../../model/fonts\";\nimport type { Vec2 } from \"../../geometry/vec2\";\n\nconst n = (v: number): string => {\n const r = Math.round(v * 1000) / 1000;\n return Object.is(r, -0) ? \"0\" : String(r);\n};\n\nconst escapeXml = (s: string): string =>\n s.replace(/[&<>\"]/g, (c) =>\n c === \"&\" ? \"&\" : c === \"<\" ? \"<\" : c === \">\" ? \">\" : \""\",\n );\n\nexport interface SvgSinkOptions {\n /** Text width measurement (defaults to the approximate Inter table). */\n measure?: TextMeasurer;\n /**\n * Clamp every stroke to at least this width (world mm). Thumbnails render\n * a whole drawing into a ~256px image, where authored 0.25 mm lineweights\n * become sub-pixel and the picture rasterizes to nothing — clamping at the\n * SINK catches everything (block children and dimension hairlines resolve\n * their own widths past any per-object style override).\n */\n minStrokeWidthMm?: number;\n}\n\nexport class SvgSink implements GeometrySink {\n private els: string[] = [];\n private path: string[] = [];\n private hasCurrent = false;\n private m: Mat2x3 = matIdentity;\n private stack: Mat2x3[] = [];\n private defs: string[] = [];\n private clipId = 0;\n private gradId = 0;\n private measurer: TextMeasurer;\n private objectStart: number | null = null;\n private minStroke: number;\n\n constructor(opts: SvgSinkOptions = {}) {\n this.measurer = opts.measure ?? approximateTextMeasurer;\n this.minStroke = opts.minStrokeWidthMm ?? 0;\n }\n\n /** Transformed + Y-flipped point, as an \"x y\" token. */\n private p(pt: Vec2): string {\n const t = matApply(this.m, pt);\n return `${n(t.x)} ${n(-t.y)}`;\n }\n\n beginPath(): void {\n this.path = [];\n this.hasCurrent = false;\n }\n moveTo(pt: Vec2): void {\n this.path.push(`M${this.p(pt)}`);\n this.hasCurrent = true;\n }\n lineTo(pt: Vec2): void {\n this.path.push(`L${this.p(pt)}`);\n this.hasCurrent = true;\n }\n bezierTo(c1: Vec2, c2: Vec2, end: Vec2): void {\n this.path.push(`C${this.p(c1)} ${this.p(c2)} ${this.p(end)}`);\n this.hasCurrent = true;\n }\n private emitBeziers(\n bs: { start: Vec2; c1: Vec2; c2: Vec2; end: Vec2 }[],\n ): void {\n if (bs.length === 0) return;\n this.path.push(`${this.hasCurrent ? \"L\" : \"M\"}${this.p(bs[0].start)}`);\n for (const b of bs)\n this.path.push(`C${this.p(b.c1)} ${this.p(b.c2)} ${this.p(b.end)}`);\n this.hasCurrent = true;\n }\n arc(\n center: Vec2,\n r: number,\n startAngle: number,\n endAngle: number,\n ccw: boolean,\n ): void {\n this.emitBeziers(\n arcToBeziers(\n center,\n r,\n startAngle,\n signedArcSweep(startAngle, endAngle, ccw),\n ),\n );\n }\n ellipse(\n center: Vec2,\n rx: number,\n ry: number,\n rotation: number,\n startAngle: number,\n endAngle: number,\n ): void {\n this.emitBeziers(\n ellipseArcToBeziers(\n center,\n rx,\n ry,\n rotation,\n startAngle,\n signedArcSweep(startAngle, endAngle, true),\n ),\n );\n }\n closePath(): void {\n this.path.push(\"Z\");\n }\n stroke(s: StrokeStyle): void {\n if (this.path.length === 0) return;\n const width = Math.max(s.widthMm, this.minStroke);\n // Dash patterns are proportioned to the authored width — rescale them\n // with the clamp so boosted strokes still read as dashed, not solid-ish\n // noise at sub-pixel dash lengths.\n const boost = s.widthMm > 0 ? width / s.widthMm : 1;\n const dash =\n s.dashMm && s.dashMm.length\n ? ` stroke-dasharray=\"${s.dashMm.map((d) => n(d * boost)).join(\",\")}\"`\n : \"\";\n const alpha =\n s.opacity !== undefined && s.opacity < 1\n ? ` stroke-opacity=\"${n(s.opacity)}\"`\n : \"\";\n this.els.push(\n `<path d=\"${this.path.join(\" \")}\" fill=\"none\" stroke=\"${s.color}\" stroke-width=\"${n(width)}\"${dash}${alpha} stroke-linecap=\"round\" stroke-linejoin=\"round\"/>`,\n );\n }\n fill(f: FillStyle): void {\n if (this.path.length === 0) return;\n const alpha =\n f.opacity !== undefined && f.opacity < 1\n ? ` fill-opacity=\"${n(f.opacity)}\"`\n : \"\";\n let paint = f.color;\n if (f.gradient) {\n // Endpoints go through the same transform + Y-flip as path points, in\n // user space so the ramp stays anchored to the geometry.\n const a = matApply(this.m, f.gradient.from);\n const b = matApply(this.m, f.gradient.to);\n const id = `grad${this.gradId++}`;\n const stops =\n `<stop offset=\"0\" stop-color=\"${f.color}\"/>` +\n `<stop offset=\"1\" stop-color=\"${f.gradient.color2}\"/>`;\n this.defs.push(\n f.gradient.shape === \"radial\"\n ? `<radialGradient id=\"${id}\" gradientUnits=\"userSpaceOnUse\" ` +\n `cx=\"${n(a.x)}\" cy=\"${n(-a.y)}\" ` +\n `r=\"${n(Math.hypot(b.x - a.x, b.y - a.y))}\">${stops}</radialGradient>`\n : `<linearGradient id=\"${id}\" gradientUnits=\"userSpaceOnUse\" ` +\n `x1=\"${n(a.x)}\" y1=\"${n(-a.y)}\" x2=\"${n(b.x)}\" y2=\"${n(-b.y)}\">` +\n `${stops}</linearGradient>`,\n );\n paint = `url(#${id})`;\n }\n this.els.push(\n `<path d=\"${this.path.join(\" \")}\" fill=\"${paint}\"${alpha} fill-rule=\"evenodd\" stroke=\"none\"/>`,\n );\n }\n text(t: TextSpec): void {\n const def = resolveFont(t.font);\n const { bold, italic } = parseFontFace(t.font);\n // osifont-italic's TTF family is plain \"osifont\": only font-style lets a\n // TTF-family matcher (resvg) pick the italic file.\n const face =\n (bold ? ` font-weight=\"bold\"` : \"\") +\n (italic || def.id === \"osifont-italic\" ? ` font-style=\"italic\"` : \"\");\n // Model vAlign is in CAP-height terms (bottom = baseline at the anchor;\n // center/top shift the baseline down by half/full cap height). Compute\n // the baseline point in WORLD space so the shift rotates with the text,\n // then let SVG's default alphabetic baseline do the rest.\n const drop =\n t.vAlign === \"center\"\n ? t.heightMm / 2\n : t.vAlign === \"top\"\n ? t.heightMm\n : 0;\n const baselineWorld = {\n x: t.anchor.x + Math.sin(t.rotation) * drop,\n y: t.anchor.y - Math.cos(t.rotation) * drop,\n };\n const tp = matApply(this.m, baselineWorld);\n // The anchor is baked through the transform, so the glyph height must be\n // too — otherwise text inside a scaled viewport (e.g. a 1:50 paper layout)\n // keeps its full world size. Viewport transforms are uniform-scale, so the\n // matrix's x-basis length is the scale factor.\n const scale = Math.hypot(this.m[0], this.m[1]) || 1;\n const anchor =\n t.hAlign === \"left\" ? \"start\" : t.hAlign === \"right\" ? \"end\" : \"middle\";\n // World rotation is CCW (Y-up); with Y negated per point it maps to the\n // negated SVG rotation.\n const deg = (-t.rotation * 180) / Math.PI;\n const w = t.widthFactor ?? 1;\n const transforms: string[] = [];\n if (deg !== 0) transforms.push(`rotate(${n(deg)} ${n(tp.x)} ${n(-tp.y)})`);\n // Width factor: horizontal glyph scale about the anchor (applied before\n // the rotation, so it stretches along the text's own run direction).\n if (w !== 1)\n transforms.push(\n `translate(${n(tp.x)} ${n(-tp.y)}) scale(${n(w)} 1) translate(${n(-tp.x)} ${n(tp.y)})`,\n );\n const rot =\n transforms.length > 0 ? ` transform=\"${transforms.join(\" \")}\"` : \"\";\n const alpha =\n t.opacity !== undefined && t.opacity < 1\n ? ` fill-opacity=\"${n(t.opacity)}\"`\n : \"\";\n // font-size is the em; model heights are cap heights.\n this.els.push(\n `<text x=\"${n(tp.x)}\" y=\"${n(-tp.y)}\" font-size=\"${n((t.heightMm / def.capHeight) * scale)}\" font-family=\"${def.cssStack}\"${face} fill=\"${t.color}\"${alpha} text-anchor=\"${anchor}\"${rot}>${escapeXml(t.text)}</text>`,\n );\n }\n measureText(\n text: string,\n heightMm: number,\n font?: string,\n widthFactor?: number,\n ): { width: number } {\n return {\n width: this.measurer.measureTextWidth(text, heightMm, font, widthFactor),\n };\n }\n image(i: ImageSpec): void {\n // Anchor at the image's TOP-LEFT world corner (SVG images are y-down);\n // sizes bake the (uniform) matrix scale, rotation rides as a transform —\n // the text() approach.\n const topLeft = matApply(this.m, {\n x: i.origin.x - Math.sin(i.rotation) * i.heightMm,\n y: i.origin.y + Math.cos(i.rotation) * i.heightMm,\n });\n const scale = Math.hypot(this.m[0], this.m[1]) || 1;\n const deg = (-i.rotation * 180) / Math.PI;\n const rot =\n deg !== 0\n ? ` transform=\"rotate(${n(deg)} ${n(topLeft.x)} ${n(-topLeft.y)})\"`\n : \"\";\n const opacity = i.opacity < 1 ? ` opacity=\"${n(i.opacity)}\"` : \"\";\n this.els.push(\n `<image x=\"${n(topLeft.x)}\" y=\"${n(-topLeft.y)}\" width=\"${n(i.widthMm * scale)}\" height=\"${n(i.heightMm * scale)}\" preserveAspectRatio=\"none\"${opacity}${rot} href=\"${i.data}\"/>`,\n );\n }\n pushTransform(m: Mat2x3): void {\n this.stack.push(this.m);\n this.m = matMultiply(this.m, m);\n }\n popTransform(): void {\n this.m = this.stack.pop() ?? matIdentity;\n }\n /**\n * Group one object's elements as `<g data-object-id data-layer>` so the\n * SVG is navigable by viewers and agents (locate visually → id →\n * update()). Empty groups (nothing emitted) are dropped.\n */\n beginObject(id: string, layer?: string): void {\n this.objectStart = this.els.length;\n this.els.push(\n `<g data-object-id=\"${escapeXml(id)}\"${layer !== undefined ? ` data-layer=\"${escapeXml(layer)}\"` : \"\"}>`,\n );\n }\n endObject(): void {\n if (this.objectStart === null) return;\n if (this.els.length === this.objectStart + 1) this.els.pop();\n else this.els.push(\"</g>\");\n this.objectStart = null;\n }\n\n pushClipRect(r: Rect): void {\n // Bake the rect's corners through the current transform (+Y-flip) so the\n // clip lives in the same root user space as the content it wraps.\n const id = `clip${this.clipId++}`;\n const corners = [\n { x: r.x, y: r.y },\n { x: r.x + r.w, y: r.y },\n { x: r.x + r.w, y: r.y + r.h },\n { x: r.x, y: r.y + r.h },\n ];\n const d = `M${this.p(corners[0])}L${this.p(corners[1])}L${this.p(corners[2])}L${this.p(corners[3])}Z`;\n this.defs.push(`<clipPath id=\"${id}\"><path d=\"${d}\"/></clipPath>`);\n this.els.push(`<g clip-path=\"url(#${id})\">`);\n }\n popClip(): void {\n this.els.push(\"</g>\");\n }\n\n /** Wrap the accumulated elements in an <svg> with the given world bbox. */\n toSvg(\n bbox: { minX: number; minY: number; maxX: number; maxY: number },\n pad = 5,\n ): string {\n const minX = bbox.minX - pad;\n const w = bbox.maxX - bbox.minX + pad * 2;\n const h = bbox.maxY - bbox.minY + pad * 2;\n // Top of the viewBox is -maxY because we negated Y on every point.\n const minY = -bbox.maxY - pad;\n const defs = this.defs.length ? `<defs>${this.defs.join(\"\")}</defs>` : \"\";\n return (\n `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"${n(minX)} ${n(minY)} ${n(w)} ${n(h)}\">` +\n defs +\n this.els.join(\"\") +\n `</svg>`\n );\n }\n}\n","import type { Line } from \"../../model/objects\";\nimport type { GeometrySink } from \"../sink\";\nimport type { PaintEnv } from \"./index\";\n\nexport const paintLine = (\n obj: Line,\n sink: GeometrySink,\n env: PaintEnv,\n): void => {\n sink.beginPath();\n sink.moveTo(obj.a);\n sink.lineTo(obj.b);\n sink.stroke(env.style);\n};\n","import type { Point } from \"../../model/objects\";\nimport type { GeometrySink } from \"../sink\";\nimport type { PaintEnv } from \"./index\";\n\n/**\n * A point paints as a round dot whose diameter IS the stroke width: a\n * near-zero-length segment under the sinks' round line caps. That inherits\n * each sink's lineweight realization (canvas px floor, PDF/SVG verbatim mm,\n * viewport-scale compensation) instead of inventing a second sizing rule.\n * The 0.002 mm nudge keeps the segment non-degenerate everywhere — canvas\n * prunes zero-length subpaths, and the SVG sink rounds to 0.001 mm.\n */\nexport const paintPoint = (\n obj: Point,\n sink: GeometrySink,\n env: PaintEnv,\n): void => {\n sink.beginPath();\n sink.moveTo(obj.p);\n sink.lineTo({ x: obj.p.x + 0.002, y: obj.p.y });\n // Never dashed: a dash gap at phase zero would swallow the dot entirely.\n sink.stroke({ ...env.style, dashMm: undefined });\n};\n","import type { Polyline, PolylineVertex } from \"../../model/objects\";\nimport { bulgeToArc } from \"../../geometry/arcs\";\nimport { angle, sub } from \"../../geometry/vec2\";\nimport type { GeometrySink } from \"../sink\";\nimport type { PaintEnv } from \"./index\";\n\n/** Emit one polyline segment (straight or bulged arc) into an open path. */\nconst segmentTo = (\n sink: GeometrySink,\n from: PolylineVertex,\n to: PolylineVertex,\n): void => {\n const a = { x: from.x, y: from.y };\n const b = { x: to.x, y: to.y };\n const arc = bulgeToArc(a, b, from.bulge);\n if (!arc) {\n sink.lineTo(b);\n return;\n }\n // Travel direction matters for path continuity: positive bulge runs CCW\n // (increasing angle) from a to b, negative runs CW.\n const angA = angle(sub(a, arc.center));\n const angB = angle(sub(b, arc.center));\n sink.arc(arc.center, arc.radius, angA, angB, from.bulge > 0);\n};\n\n/**\n * Emit a vertex chain as a subpath (no beginPath — callers compose multiple\n * chains into one even-odd path, e.g. hatch loops).\n */\nexport const emitVertexPath = (\n sink: GeometrySink,\n vertices: PolylineVertex[],\n closed: boolean,\n): void => {\n sink.moveTo({ x: vertices[0].x, y: vertices[0].y });\n for (let i = 1; i < vertices.length; i++) {\n segmentTo(sink, vertices[i - 1], vertices[i]);\n }\n if (closed) {\n segmentTo(sink, vertices[vertices.length - 1], vertices[0]);\n sink.closePath();\n }\n};\n\nconst buildPolylinePath = (obj: Polyline, sink: GeometrySink): void => {\n sink.beginPath();\n emitVertexPath(sink, obj.points, obj.closed);\n};\n\nexport const paintPolyline = (\n obj: Polyline,\n sink: GeometrySink,\n env: PaintEnv,\n): void => {\n buildPolylinePath(obj, sink);\n sink.stroke(env.style);\n};\n","import type { Circle } from \"../../model/objects\";\nimport type { GeometrySink } from \"../sink\";\nimport type { PaintEnv } from \"./index\";\n\nexport const paintCircle = (\n obj: Circle,\n sink: GeometrySink,\n env: PaintEnv,\n): void => {\n sink.beginPath();\n sink.arc(obj.center, obj.radius, 0, Math.PI * 2, true);\n sink.closePath();\n sink.stroke(env.style);\n};\n","import type { Arc } from \"../../model/objects\";\nimport type { GeometrySink } from \"../sink\";\nimport type { PaintEnv } from \"./index\";\n\nexport const paintArc = (obj: Arc, sink: GeometrySink, env: PaintEnv): void => {\n sink.beginPath();\n sink.arc(obj.center, obj.radius, obj.startAngle, obj.endAngle, true);\n sink.stroke(env.style);\n};\n","import type { Ellipse } from \"../../model/objects\";\nimport { angle, len } from \"../../geometry/vec2\";\nimport { ellipseSweep } from \"../../geometry/ellipse\";\nimport type { GeometrySink } from \"../sink\";\nimport type { PaintEnv } from \"./index\";\n\nexport const paintEllipse = (\n obj: Ellipse,\n sink: GeometrySink,\n env: PaintEnv,\n): void => {\n const rx = len(obj.majorAxis);\n if (rx < 1e-12) return;\n const sweep = ellipseSweep(obj);\n sink.beginPath();\n sink.ellipse(\n obj.center,\n rx,\n rx * obj.ratio,\n angle(obj.majorAxis),\n obj.startAngle,\n obj.startAngle + sweep,\n );\n sink.stroke(env.style);\n};\n","import type { Hatch } from \"../../model/objects\";\nimport {\n computePatternGeometry,\n estimatePatternSegments,\n resolveHatchPattern,\n MAX_HATCH_SEGMENTS,\n} from \"../../model/hatchPatterns\";\nimport { verticesToPolygon } from \"../../geometry/polyline\";\nimport { computeHatchLines, type GeometrySink } from \"../sink\";\nimport { ANSI31_BASE_SPACING } from \"../../export/dxf/hatchPattern\";\nimport type { PaintEnv } from \"./index\";\nimport { emitVertexPath } from \"./polyline\";\n\n/** Stand-in for the single-family fills (\"lines\" / unknown pattern name):\n * deltaY 1 so the estimator's `scale` argument IS the line spacing. */\nconst SINGLE_FAMILY = {\n name: \"\",\n lines: [{ angle: 0, origin: { x: 0, y: 0 }, deltaX: 0, deltaY: 1 }],\n};\n\nconst paintSolid = (obj: Hatch, sink: GeometrySink, env: PaintEnv): void => {\n // All loops as one even-odd path: loop[0] outer, the rest are holes.\n sink.beginPath();\n for (const loop of obj.loops) emitVertexPath(sink, loop.points, true);\n sink.fill({ color: env.style.color, opacity: env.style.opacity });\n};\n\n/** Gradient geometry from the loops' bbox. linear: an axis through the\n * center along the fill angle, spanning the bbox's projection onto that\n * direction — the full color ramp is always visible whatever the region's\n * shape and rotation. radial: color1 at the center fading to color2 at the\n * farthest bbox corner. */\nconst paintGradient = (\n obj: Hatch,\n fill: {\n shape: \"linear\" | \"radial\";\n color1: string;\n color2: string;\n angle: number;\n },\n sink: GeometrySink,\n env: PaintEnv,\n): void => {\n let minX = Infinity;\n let minY = Infinity;\n let maxX = -Infinity;\n let maxY = -Infinity;\n for (const loop of obj.loops)\n for (const p of loop.points) {\n if (p.x < minX) minX = p.x;\n if (p.y < minY) minY = p.y;\n if (p.x > maxX) maxX = p.x;\n if (p.y > maxY) maxY = p.y;\n }\n if (minX > maxX) return;\n const c = { x: (minX + maxX) / 2, y: (minY + maxY) / 2 };\n const hw = (maxX - minX) / 2;\n const hh = (maxY - minY) / 2;\n let from: { x: number; y: number };\n let to: { x: number; y: number };\n if (fill.shape === \"radial\") {\n from = c;\n const r = Math.max(Math.hypot(hw, hh), 1e-6);\n to = { x: c.x + r, y: c.y };\n } else {\n const dir = { x: Math.cos(fill.angle), y: Math.sin(fill.angle) };\n const r = Math.max(Math.abs(dir.x) * hw + Math.abs(dir.y) * hh, 1e-6);\n from = { x: c.x - dir.x * r, y: c.y - dir.y * r };\n to = { x: c.x + dir.x * r, y: c.y + dir.y * r };\n }\n sink.beginPath();\n for (const loop of obj.loops) emitVertexPath(sink, loop.points, true);\n sink.fill({\n color: fill.color1,\n opacity: env.style.opacity,\n gradient: { shape: fill.shape, from, to, color2: fill.color2 },\n });\n};\n\nexport const paintHatch = (\n obj: Hatch,\n sink: GeometrySink,\n env: PaintEnv,\n): void => {\n if (obj.fill.kind === \"solid\") {\n paintSolid(obj, sink, env);\n return;\n }\n if (obj.fill.kind === \"gradient\") {\n paintGradient(obj, obj.fill, sink, env);\n return;\n }\n // Pattern lines clipped to the loops (pure math — no canvas clip needed,\n // and the identical segments feed PDF/DXF export later). The clipping is\n // the expensive part, so it is cached per object when the caller keeps one.\n let lines = env.cache?.hatchLines.get(obj);\n if (!lines) {\n const rings = obj.loops.map((loop) => verticesToPolygon(loop.points));\n // fill.scale × obj.scale is the effective world-mm multiplier (obj.scale\n // is the shared annotation-scale knob, like the \"lines\" fill uses).\n const s =\n obj.fill.kind === \"pattern\" ? obj.fill.scale * obj.scale : obj.scale;\n const pat =\n obj.fill.kind === \"pattern\"\n ? resolveHatchPattern(obj.fill.name, env.hatchPatterns)\n : undefined;\n // MaxHatch-style ceiling (estimated BEFORE generating): a pattern this\n // dense reads as tone and its segments would stall paint/export — draw\n // it as a faint solid instead. Estimated per paint, never cached — the\n // estimate is a bbox scan, and caching would need a sentinel type.\n const estimate = pat\n ? estimatePatternSegments(rings, pat, s)\n : estimatePatternSegments(\n rings,\n SINGLE_FAMILY,\n obj.fill.kind === \"pattern\"\n ? s * ANSI31_BASE_SPACING\n : obj.fill.spacing * obj.scale,\n );\n if (estimate > MAX_HATCH_SEGMENTS) {\n paintSolid(obj, sink, {\n ...env,\n style: { ...env.style, opacity: 0.25 * (env.style.opacity ?? 1) },\n });\n return;\n }\n if (obj.fill.kind === \"pattern\") {\n lines = pat\n ? computePatternGeometry(rings, pat, obj.fill.angle, s, obj.fill.origin)\n : // Unknown name: fall back to a single ANSI31-style family.\n computeHatchLines(rings, obj.fill.angle, s * ANSI31_BASE_SPACING);\n } else {\n lines = computeHatchLines(\n rings,\n obj.fill.angle,\n obj.fill.spacing * obj.scale,\n );\n }\n env.cache?.hatchLines.set(obj, lines);\n }\n if (lines.length === 0) return;\n sink.beginPath();\n for (const seg of lines) {\n sink.moveTo(seg.a);\n sink.lineTo(seg.b);\n }\n sink.stroke({\n color: env.style.color,\n widthMm: Math.min(env.style.widthMm, 0.18),\n opacity: env.style.opacity,\n });\n};\n","import type { ArrowType } from \"../../model/objects\";\nimport type { Vec2 } from \"../../geometry/vec2\";\nimport { add, norm, perp, scale, sub } from \"../../geometry/vec2\";\nimport type { GeometrySink } from \"../sink\";\n\n/**\n * Arrowhead at `tip`, body extending toward `toward`. Styles follow the\n * standard DXF arrowhead blocks: filled (ClosedFilled), open (Open 30°),\n * tick (ArchTick — oblique stroke across the line), dot (filled circle),\n * none.\n */\nexport const paintArrowhead = (\n sink: GeometrySink,\n tip: Vec2,\n toward: Vec2,\n size: number,\n color: string,\n type: ArrowType = \"filled\",\n opacity?: number,\n): void => {\n if (type === \"none\") return;\n const dir = norm(sub(toward, tip));\n if (dir.x === 0 && dir.y === 0) return;\n\n switch (type) {\n case \"filled\": {\n const base = add(tip, scale(dir, size));\n const half = scale(perp(dir), size / 3);\n sink.beginPath();\n sink.moveTo(tip);\n sink.lineTo(add(base, half));\n sink.lineTo(sub(base, half));\n sink.closePath();\n sink.fill({ color, opacity });\n break;\n }\n case \"open\": {\n const base = add(tip, scale(dir, size));\n const half = scale(perp(dir), size / 3);\n sink.beginPath();\n sink.moveTo(add(base, half));\n sink.lineTo(tip);\n sink.lineTo(sub(base, half));\n sink.stroke({ color, widthMm: Math.min(size / 10, 0.25), opacity });\n break;\n }\n case \"tick\": {\n // 45° oblique stroke centered on the tip (architectural tick).\n const diag = scale(norm(add(dir, perp(dir))), size / 2);\n sink.beginPath();\n sink.moveTo(sub(tip, diag));\n sink.lineTo(add(tip, diag));\n sink.stroke({ color, widthMm: Math.min(size / 8, 0.35), opacity });\n break;\n }\n case \"dot\": {\n sink.beginPath();\n sink.arc(tip, size / 4, 0, Math.PI * 2, true);\n sink.fill({ color, opacity });\n break;\n }\n }\n};\n","// Text painter. The alignment involutions and box-corner geometry live in\n// ../textGeometry (shared with snap/hit-testing); this file is the sink\n// drawing pass. Text WIDTH measurement is the one non-geometric input — it is\n// taken from the sink's own `measureText` (canvas-backed on screen,\n// font-metric in a headless/PDF sink), so no DOM leaks into the kernel.\n\nimport type { Text } from \"../../model/objects\";\nimport { effectiveTextFont } from \"../../model/objects\";\nimport { add, fromAngle, perp, scale } from \"../../geometry/vec2\";\nimport { lineSegments, textBlock, type TextMeasurer } from \"../textMetrics\";\nimport { approximateTextMeasurer } from \"../textMeasurer\";\nimport {\n textArrowSize,\n textArrowType,\n textFrameGeometry,\n textHeight,\n textWidth,\n} from \"../textGeometry\";\nimport type { GeometrySink } from \"../sink\";\nimport type { PaintEnv } from \"./index\";\nimport { paintArrowhead } from \"./arrows\";\nimport { emitVertexPath } from \"./polyline\";\nimport { richTextBlock, type RichBlock } from \"../richText\";\n\nexport const paintText = (\n obj: Text,\n sink: GeometrySink,\n env: PaintEnv,\n): void => {\n // Bind the object's effective font (own, else document text style) so\n // wrap/frame measurement matches what the sink will draw.\n const { font, widthFactor } = effectiveTextFont(obj, env.textStyles);\n const measure: TextMeasurer = {\n measureTextWidth: (text, heightMm) =>\n sink.measureText(text, heightMm, font, widthFactor).width,\n };\n // Tab-cell advancement uses the DETERMINISTIC approximate measurer, not\n // the sink's: each sink measures with its own font metrics (canvas glyphs,\n // jsPDF Helvetica, the Inter table), and a near-boundary cell would land\n // on a different tab stop per output — columns misaligning between the\n // canvas/PNG and the PDF. With a shared measurer every output picks the\n // same stops by construction; a real glyph run may over/underfill its\n // cell by the approximation error instead.\n const tabStopMeasure: TextMeasurer = {\n measureTextWidth: (text, heightMm) =>\n approximateTextMeasurer.measureTextWidth(\n text,\n heightMm,\n font,\n widthFactor,\n ),\n };\n\n const { color, widthMm, opacity } = env.style;\n\n // Leader lines first (annotative geometry under the glyphs).\n for (const line of obj.leaderLines) {\n sink.beginPath();\n sink.moveTo(line[0]);\n for (let i = 1; i < line.length; i++) sink.lineTo(line[i]);\n sink.stroke({ color, widthMm, opacity });\n\n paintArrowhead(\n sink,\n line[0],\n line[1],\n textArrowSize(obj, env.textStyles),\n color,\n textArrowType(obj, env.textStyles),\n opacity,\n );\n }\n\n // Frame border under the glyphs.\n for (const part of textFrameGeometry(obj, measure, env.textStyles)) {\n sink.beginPath();\n emitVertexPath(sink, part.points, part.closed);\n sink.stroke({ color, widthMm, opacity });\n }\n\n const height = textHeight(obj, env.textStyles);\n if (obj.spans?.length) {\n paintRichText(obj, sink, env, height, font, widthFactor, tabStopMeasure);\n return;\n }\n\n // Wrapping re-measures every word; cache the block per object. The cache\n // is per consumer (PaintEnv.cache), so different measurers never mix. The\n // `base` guard drops entries when the document text style is edited (an\n // inherited-font text rewraps without the object itself changing).\n const cached = env.cache?.textBlocks.get(obj);\n let block = cached?.base === env.textStyles ? cached.block : undefined;\n if (!block) {\n block = textBlock(obj.content, height, measure, textWidth(obj));\n env.cache?.textBlocks.set(obj, { base: env.textStyles, block });\n }\n const u = fromAngle(obj.rotation);\n const vUp = perp(u);\n // Shift the first line up so the whole block (not just line 0) honours\n // vAlign: top-aligned blocks grow down, bottom-aligned grow up.\n const vA = obj.vAlign;\n const up =\n vA === \"top\"\n ? 0\n : vA === \"center\"\n ? ((block.lines.length - 1) * block.lineHeight) / 2\n : (block.lines.length - 1) * block.lineHeight;\n const hA = obj.hAlign;\n for (let i = 0; i < block.lines.length; i++) {\n const lineAnchor = add(obj.position, scale(vUp, up - i * block.lineHeight));\n const spec = {\n heightMm: height,\n rotation: obj.rotation,\n vAlign: vA,\n color: env.style.color,\n font,\n widthFactor,\n opacity: env.style.opacity,\n };\n const segs = lineSegments(block.lines[i], height, tabStopMeasure);\n if (segs.length === 1) {\n sink.text({\n ...spec,\n text: segs[0].text,\n anchor: lineAnchor,\n hAlign: hA,\n });\n continue;\n }\n // Tabbed line: one left-anchored run per segment at its tab-stop offset.\n // Offsets measure from the BLOCK's left edge (not the line's own width),\n // so columns stay aligned across rows under every alignment — the MTEXT\n // model, where tabs run from the paragraph box edge.\n const start =\n hA === \"left\" ? 0 : hA === \"center\" ? -block.width / 2 : -block.width;\n for (const seg of segs) {\n if (!seg.text) continue; // consecutive tabs: the stop still advanced\n sink.text({\n ...spec,\n text: seg.text,\n anchor: add(lineAnchor, scale(u, start + seg.x)),\n hAlign: \"left\",\n });\n }\n }\n};\n\n/** Texts with spans: one left-anchored baseline run per formatted piece\n * (paint/richText.ts lays them out; same alignment rules as above). */\nconst paintRichText = (\n obj: Text,\n sink: GeometrySink,\n env: PaintEnv,\n height: number,\n font: string | undefined,\n widthFactor: number,\n tabStopMeasure: TextMeasurer,\n): void => {\n const measure = sinkMeasurer(sink);\n const cached = env.cache?.richBlocks.get(obj);\n let block = cached?.base === env.textStyles ? cached.block : undefined;\n if (!block) {\n block = richTextBlock(\n obj.content,\n obj.spans,\n { face: font, heightMm: height, widthFactor },\n measure,\n tabStopMeasure,\n textWidth(obj),\n );\n env.cache?.richBlocks.set(obj, { base: env.textStyles, block });\n }\n drawRichBlock(block, obj, sink, env, widthFactor);\n};\n\n/** A sink-measuring TextMeasurer (the painter's per-run widths). */\nexport const sinkMeasurer = (sink: GeometrySink): TextMeasurer => ({\n measureTextWidth: (text, h, face, wf) =>\n sink.measureText(text, h, face, wf).width,\n});\n\n/** Draw a laid-out formatted block at a placement: one left-anchored\n * baseline run per piece plus underlines, lines aligned as the plain\n * painter aligns them. Shared by texts and dimension labels. */\nexport const drawRichBlock = (\n block: RichBlock,\n at0: Pick<Text, \"position\" | \"rotation\" | \"hAlign\" | \"vAlign\">,\n sink: GeometrySink,\n env: PaintEnv,\n widthFactor: number,\n): void => {\n const u = fromAngle(at0.rotation);\n const vUp = perp(u);\n const hA = at0.hAlign;\n const top =\n at0.vAlign === \"top\"\n ? 0\n : at0.vAlign === \"center\"\n ? block.height / 2\n : block.height;\n const blockLeft =\n hA === \"left\" ? 0 : hA === \"center\" ? -block.width / 2 : -block.width;\n const { color, opacity } = env.style;\n for (const line of block.lines) {\n const left = line.fromBlockEdge\n ? blockLeft\n : hA === \"left\"\n ? 0\n : hA === \"center\"\n ? -line.width / 2\n : -line.width;\n for (const p of line.pieces) {\n const at = (dx: number, dy: number) =>\n add(add(at0.position, scale(u, left + p.x + dx)), scale(vUp, dy));\n const y = top - line.baseline + p.dy;\n const c = p.color ?? color;\n if (p.text)\n sink.text({\n text: p.text,\n anchor: at(0, y),\n heightMm: p.heightMm,\n rotation: at0.rotation,\n hAlign: \"left\",\n vAlign: \"bottom\",\n color: c,\n font: p.face,\n widthFactor,\n opacity,\n });\n if (p.underline && p.width > 0) {\n const uy = y - p.heightMm * UNDERLINE_DROP;\n sink.beginPath();\n sink.moveTo(at(0, uy));\n sink.lineTo(at(p.width, uy));\n sink.stroke({ color: c, widthMm: env.style.widthMm, opacity });\n }\n }\n }\n};\n\n/** Underline below the baseline, × the piece's cap height. */\nconst UNDERLINE_DROP = 0.18;\n","// Dimension painter (all kinds). The geometry derivation is shared with\n// snap/hit-testing and DXF explosion — it lives in ../dimensionGeometry so\n// this file is purely the sink drawing pass.\n\nimport type { Dimension } from \"../../model/objects\";\nimport { add, fromAngle, scale } from \"../../geometry/vec2\";\nimport { dimensionGeometry } from \"../dimensionGeometry\";\nimport type { GeometrySink } from \"../sink\";\nimport type { PaintEnv } from \"./index\";\nimport { paintArrowhead } from \"./arrows\";\nimport { approximateTextMeasurer } from \"../textMeasurer\";\nimport { richTextBlock } from \"../richText\";\nimport { drawRichBlock, sinkMeasurer } from \"./text\";\n\nexport const paintDimension = (\n obj: Dimension,\n sink: GeometrySink,\n env: PaintEnv,\n): void => {\n // The derivation is pure in (obj, dimStyles) — both are replaced on edit,\n // so a cached entry is valid exactly while both references match.\n const cached = env.cache?.dimGeometry.get(obj);\n const geom =\n cached && cached.base === env.dimStyles\n ? cached.geom\n : dimensionGeometry(obj, env.dimStyles);\n env.cache?.dimGeometry.set(obj, { base: env.dimStyles, geom });\n if (!geom) return;\n // Dimension linework follows the object/layer linetype (dashMm) like any\n // other stroke; arrowheads and text stay solid. Only the width is capped —\n // annotation linework stays hairline even on heavy layers.\n const stroke = {\n color: env.style.color,\n widthMm: Math.min(env.style.widthMm, 0.18),\n dashMm: env.style.dashMm,\n opacity: env.style.opacity,\n };\n\n sink.beginPath();\n for (const seg of [\n ...geom.extensionLines,\n ...geom.dimLines,\n ...geom.leaders,\n ]) {\n sink.moveTo(seg.a);\n sink.lineTo(seg.b);\n }\n if (geom.dimArc) {\n const arc = geom.dimArc;\n sink.moveTo(add(arc.center, scale(fromAngle(arc.startAngle), arc.radius)));\n sink.arc(arc.center, arc.radius, arc.startAngle, arc.endAngle, true);\n }\n sink.stroke(stroke);\n\n for (const arrow of geom.arrows) {\n paintArrowhead(\n sink,\n arrow.tip,\n arrow.toward,\n arrow.size,\n env.style.color,\n geom.arrowType,\n env.style.opacity,\n );\n }\n\n for (const text of geom.labels) {\n if (text.spans?.length) {\n drawRichBlock(\n richTextBlock(\n text.content,\n text.spans,\n {\n face: text.font,\n heightMm: text.height,\n widthFactor: text.widthFactor ?? 1,\n },\n sinkMeasurer(sink),\n approximateTextMeasurer,\n ),\n {\n position: text.anchor,\n rotation: text.rotation,\n hAlign: \"center\",\n vAlign: \"center\",\n },\n sink,\n env,\n text.widthFactor ?? 1,\n );\n continue;\n }\n sink.text({\n text: text.content,\n anchor: text.anchor,\n heightMm: text.height,\n rotation: text.rotation,\n hAlign: \"center\",\n vAlign: \"center\",\n color: env.style.color,\n font: text.font,\n widthFactor: text.widthFactor,\n opacity: env.style.opacity,\n });\n }\n};\n","// Dash resolution for the paint layer. Line-type definitions now live in the\n// named library (model/lineTypes.ts, curated set + embedded built-in catalogue);\n// this module turns a line-type NAME into the mm dash array the sinks consume,\n// so screen output matches print (both use true mm; only overlay chrome is\n// screen-constant). Patterns are defined per 1 mm of line width — callers\n// scale them by resolvedWidth × lineTypeScale (CELTSCALE) via scaleDash.\n\nimport {\n renderDashes,\n resolveLineType,\n type LineType,\n} from \"../model/lineTypes\";\n\nexport const dashForLineType = (\n lineType: string | undefined,\n /** The document's own line types, resolved ahead of the catalogue. */\n lineTypes?: readonly LineType[],\n): number[] | undefined => {\n if (!lineType) return undefined;\n const pattern = resolveLineType(lineType, lineTypes);\n return pattern ? renderDashes(pattern) : undefined;\n};\n\n/** Apply a length multiplier (resolved width × CELTSCALE) to a dash pattern. */\nexport const scaleDash = (\n dash: number[] | undefined,\n multiplier: number | undefined,\n): number[] | undefined =>\n dash && multiplier !== undefined && multiplier !== 1\n ? dash.map((d) => d * multiplier)\n : dash;\n","import { blockPivot, type Block, type ModelObject } from \"../../model/objects\";\nimport {\n getBlockError,\n getEvaluatedWorldChildren,\n} from \"../../extensions/evalBlock\";\nimport { dashForLineType, scaleDash } from \"../lineTypes\";\nimport type { GeometrySink } from \"../sink\";\nimport type { PaintEnv } from \"./index\";\nimport { paintObject } from \"./index\";\n\nconst ERROR_COLOR = \"#ef4444\";\n\nexport const paintBlockInstance = (\n obj: Block,\n sink: GeometrySink,\n env: PaintEnv,\n): void => {\n const children = getEvaluatedWorldChildren(\n obj,\n env.blockDefinitions,\n env.resolveObject,\n env, // its text / dim styles: what draw's `styles` reads\n );\n const error = getBlockError(obj.id);\n\n if (error) {\n // Dashed red placeholder at the pivot (first point input).\n const pivot = blockPivot(obj);\n const s = 6;\n sink.beginPath();\n sink.moveTo({ x: pivot.x - s, y: pivot.y - s });\n sink.lineTo({ x: pivot.x + s, y: pivot.y - s });\n sink.lineTo({ x: pivot.x + s, y: pivot.y + s });\n sink.lineTo({ x: pivot.x - s, y: pivot.y + s });\n sink.closePath();\n sink.stroke({ color: ERROR_COLOR, widthMm: 0.35, dashMm: [1, 1] });\n sink.text({\n text: \"!\",\n anchor: pivot,\n heightMm: s,\n rotation: 0,\n hAlign: \"center\",\n vAlign: \"center\",\n color: ERROR_COLOR,\n });\n return;\n }\n\n paintChildren(children, sink, env, obj.layerId);\n};\n\n/** Paint derived world children (block instances, tables): highlight paints\n * (forceStyle) keep the caller's style so the whole object reads as one\n * silhouette; normal paints resolve style per child over the parent's. */\nexport const paintChildren = (\n children: readonly ModelObject[],\n sink: GeometrySink,\n env: PaintEnv,\n /** The parent's layer: a child on ANOTHER layer (imported DXF blocks draw\n * across layers) is hidden with that layer. */\n parentLayerId?: string,\n): void => {\n for (const child of children) {\n if (\n env.layers &&\n parentLayerId !== undefined &&\n child.layerId !== parentLayerId &&\n env.layers.find((l) => l.id === child.layerId)?.visible === false\n )\n continue;\n paintObject(\n child,\n sink,\n env.forceStyle\n ? env\n : {\n style: {\n color: child.color ?? env.style.color,\n widthMm: child.lineWidth ?? env.style.widthMm,\n // Same width-proportional dash rule as resolveStyle.\n dashMm:\n scaleDash(\n dashForLineType(child.lineType, env.lineTypes),\n (child.lineWidth ?? env.style.widthMm) *\n (child.lineTypeScale ?? 1),\n ) ?? env.style.dashMm,\n opacity: child.opacity ?? env.style.opacity,\n },\n layers: env.layers,\n dimStyles: env.dimStyles,\n textStyles: env.textStyles,\n lineTypes: env.lineTypes,\n hatchPatterns: env.hatchPatterns,\n blockDefinitions: env.blockDefinitions,\n resolveObject: env.resolveObject,\n assets: env.assets,\n },\n );\n }\n};\n","// Viewport frame outline. This painter serves selection/hover highlights on\n// the overlay; the paper scene draws viewport CONTENT via layoutPaint and its\n// own chrome-colored frame pass, and the frame never reaches print output.\n\nimport type { Viewport } from \"../../model/objects\";\nimport type { GeometrySink } from \"../sink\";\nimport type { PaintEnv } from \"./index\";\n\nexport const paintViewport = (\n obj: Viewport,\n sink: GeometrySink,\n env: PaintEnv,\n): void => {\n const { x, y, w, h } = obj.rect;\n sink.beginPath();\n sink.moveTo({ x, y });\n sink.lineTo({ x: x + w, y });\n sink.lineTo({ x: x + w, y: y + h });\n sink.lineTo({ x, y: y + h });\n sink.closePath();\n sink.stroke({ color: env.style.color, widthMm: env.style.widthMm });\n};\n","import type { ImageObject } from \"../../model/objects\";\nimport { imageCorners } from \"../../transform\";\nimport type { GeometrySink } from \"../sink\";\nimport type { PaintEnv } from \"./index\";\n\nexport const paintImage = (\n obj: ImageObject,\n sink: GeometrySink,\n env: PaintEnv,\n): void => {\n const data = env.assets?.[obj.assetId];\n // forceStyle = selection/hover highlight: a bitmap can't take a highlight\n // color, so the footprint outline stands in for it.\n if (data !== undefined && !env.forceStyle) {\n sink.image({\n data,\n origin: obj.origin,\n widthMm: obj.width,\n heightMm: obj.height,\n rotation: obj.rotation,\n opacity: env.style.opacity ?? 1,\n });\n return;\n }\n // Frame; crossed diagonals only when the asset is actually missing.\n const [a, b, c, d] = imageCorners(obj);\n sink.beginPath();\n sink.moveTo(a);\n sink.lineTo(b);\n sink.lineTo(c);\n sink.lineTo(d);\n sink.closePath();\n if (data === undefined) {\n sink.moveTo(a);\n sink.lineTo(c);\n sink.moveTo(b);\n sink.lineTo(d);\n }\n sink.stroke(env.style);\n};\n","// Table painter: the derived world children (rules + cell texts) from\n// ../tableLayout, painted like block-instance children.\n\nimport type { Table } from \"../../model/objects\";\nimport type { GeometrySink } from \"../sink\";\nimport { tableLayout } from \"../tableLayout\";\nimport { paintChildren } from \"./block\";\nimport type { PaintEnv } from \"./index\";\n\nexport const paintTable = (\n obj: Table,\n sink: GeometrySink,\n env: PaintEnv,\n): void => paintChildren(tableLayout(obj, env.textStyles).children, sink, env);\n","// A uniform-grid index over one snap entry's primitives (see\n// SnapCacheEntry.near): built on first query, it hands back only what lies\n// in a box — a referenced site plan has 10⁵+ segments, and scanning them all\n// on every pointer move made snapping lag and forced a cap that left most\n// edges unsnappable.\n\nimport { boundsIntersect, isEmptyBounds, type AABB } from \"../geometry/bounds\";\nimport type { SnapCacheEntry } from \"./types\";\n\n/** Cells per side of the grid over the entry's geometry. */\nconst GRID = 256;\n/** An arc/ellipse box spanning more cells than this goes in the\n * always-checked list instead (few curves are that big). Segments never do:\n * they are indexed along the cells they actually cross. */\nconst MAX_CELLS = 64;\n\ntype Kind = 0 | 1 | 2 | 3; // point, segment, arc, ellipse\n\nconst segmentBox = (s: {\n a: { x: number; y: number };\n b: { x: number; y: number };\n}): AABB => ({\n minX: Math.min(s.a.x, s.b.x),\n maxX: Math.max(s.a.x, s.b.x),\n minY: Math.min(s.a.y, s.b.y),\n maxY: Math.max(s.a.y, s.b.y),\n});\n\nexport const withNearIndex = (entry: SnapCacheEntry): SnapCacheEntry => {\n // The grid covers the entry's GEOMETRY bounds, not pointBounds: a\n // reference's insertion point can sit 10¹⁰ mm from its content (a survey\n // file placed back at the origin), which would squash everything into one\n // cell. Primitives outside the grid go in the always-checked list.\n const b = isEmptyBounds(entry.bounds) ? entry.pointBounds : entry.bounds;\n const size = Math.max(b.maxX - b.minX, b.maxY - b.minY, 1e-9) / GRID;\n const cell = (v: number, min: number) =>\n Math.min(GRID - 1, Math.max(0, Math.floor((v - min) / size)));\n const outside = (box: AABB) =>\n box.minX < b.minX ||\n box.maxX > b.maxX ||\n box.minY < b.minY ||\n box.maxY > b.maxY;\n // Packed ids: kind in the low 2 bits.\n const id = (kind: Kind, i: number) => i * 4 + kind;\n\n let index: { cells: Map<number, number[]>; big: number[] } | null = null;\n const build = () => {\n const cells = new Map<number, number[]>();\n const big: number[] = [];\n const add = (k: number, key: number) => {\n const list = cells.get(k);\n if (list) {\n if (list[list.length - 1] !== key) list.push(key);\n } else cells.set(k, [key]);\n };\n const insert = (key: number, box: AABB) => {\n const x0 = cell(box.minX, b.minX);\n const x1 = cell(box.maxX, b.minX);\n const y0 = cell(box.minY, b.minY);\n const y1 = cell(box.maxY, b.minY);\n if (outside(box) || (x1 - x0 + 1) * (y1 - y0 + 1) > MAX_CELLS) {\n big.push(key);\n return;\n }\n for (let x = x0; x <= x1; x++)\n for (let y = y0; y <= y1; y++) add(x * GRID + y, key);\n };\n entry.points.forEach((sp, i) =>\n insert(id(0, i), {\n minX: sp.p.x,\n maxX: sp.p.x,\n minY: sp.p.y,\n maxY: sp.p.y,\n }),\n );\n // Segments go in the cells along them — a site plan's long hatch and\n // boundary lines would otherwise fill whole rows or be scanned always.\n entry.segments.forEach((s, i) => {\n const key = id(1, i);\n if (outside(segmentBox(s))) {\n big.push(key);\n return;\n }\n // ponytail: sampled every quarter cell, so a line clipping a cell\n // corner by less than that can miss it — the query box (pick/snap\n // tolerance) usually overlaps the neighbour; exact grid traversal if\n // that ever shows.\n const n =\n Math.ceil(Math.hypot(s.b.x - s.a.x, s.b.y - s.a.y) / (size / 4)) + 1;\n let last = -1;\n for (let t = 0; t <= n; t++) {\n const k =\n cell(s.a.x + ((s.b.x - s.a.x) * t) / n, b.minX) * GRID +\n cell(s.a.y + ((s.b.y - s.a.y) * t) / n, b.minY);\n if (k !== last) add(k, key);\n last = k;\n }\n });\n entry.arcs.forEach((a, i) =>\n insert(id(2, i), {\n minX: a.center.x - a.radius,\n maxX: a.center.x + a.radius,\n minY: a.center.y - a.radius,\n maxY: a.center.y + a.radius,\n }),\n );\n (entry.ellipses ?? []).forEach((e, i) => {\n const r = Math.hypot(e.majorAxis.x, e.majorAxis.y);\n insert(id(3, i), {\n minX: e.center.x - r,\n maxX: e.center.x + r,\n minY: e.center.y - r,\n maxY: e.center.y + r,\n });\n });\n return { cells, big };\n };\n\n const near = (box: AABB): SnapCacheEntry => {\n const out: SnapCacheEntry = {\n bounds: entry.bounds,\n pointBounds: entry.pointBounds,\n points: [],\n segments: [],\n arcs: [],\n ellipses: [],\n };\n const take = (k: number): void => {\n const i = k >> 2;\n switch ((k & 3) as Kind) {\n case 0:\n out.points.push(entry.points[i]);\n break;\n case 1:\n out.segments.push(entry.segments[i]);\n break;\n case 2:\n out.arcs.push(entry.arcs[i]);\n break;\n case 3:\n out.ellipses!.push(entry.ellipses![i]);\n break;\n }\n };\n if (!boundsIntersect(box, entry.pointBounds)) return out;\n index ??= build();\n // Off the geometry: only the outliers (e.g. a far insertion point).\n if (isEmptyBounds(b) || !boundsIntersect(box, b)) {\n for (const k of index.big) take(k);\n return out;\n }\n const seen = new Set<number>(index.big);\n const x0 = cell(box.minX, b.minX);\n const x1 = cell(box.maxX, b.minX);\n const y0 = cell(box.minY, b.minY);\n const y1 = cell(box.maxY, b.minY);\n for (let x = x0; x <= x1; x++)\n for (let y = y0; y <= y1; y++)\n for (const k of index.cells.get(x * GRID + y) ?? []) seen.add(k);\n for (const k of seen) take(k);\n return out;\n };\n\n return { ...entry, near };\n};\n","// Per-object snap/geometry derivation — the single source of derived geometry\n// for both snapping and hit-testing.\n//\n// KERNEL SEAM: `buildEntry` is PURE. The cache lifecycle (subscription to\n// store invalidation, id→object lookup) stays with the mutation owner; it\n// calls `buildSnapEntry` and memoizes the result. Everything the derivation\n// needs that would otherwise come from a store — the document dim style, the\n// block definitions, and a text measurer — is passed in via `SnapGeometryContext`.\n\nimport type {\n Dimension,\n DimStyle,\n Ellipse,\n Hatch,\n ModelObject,\n Polyline,\n Text,\n TextStyle,\n} from \"../model/objects\";\nimport { blockPivot } from \"../model/objects\";\nimport { imageCenter, imageCorners } from \"../transform\";\nimport type { TextMeasurer } from \"../paint/textMetrics\";\nimport { textBoxCorners, textFrameGeometry } from \"../paint/textGeometry\";\nimport { dimensionGeometry } from \"../paint/dimensionGeometry\";\nimport { getEvaluatedWorldChildren } from \"../extensions/evalBlock\";\nimport { verticesToCurves, verticesToPolygon } from \"../geometry/polyline\";\nimport {\n addPointToBounds,\n boundsOfPoints,\n emptyBounds,\n isEmptyBounds,\n unionBounds,\n type AABB,\n} from \"../geometry/bounds\";\nimport {\n arcMidPoint,\n arcSweep,\n pointOnArc,\n angleInArc,\n type ArcGeom,\n} from \"../geometry/arcs\";\nimport { mid, normAngle, type Vec2 } from \"../geometry/vec2\";\nimport {\n pointOnEllipse,\n paramInEllipse,\n tessellateEllipse,\n isFullEllipse,\n type EllipseGeom,\n} from \"../geometry/ellipse\";\nimport type { Segment } from \"../geometry/line\";\nimport type { SnapCacheEntry, SnapPoint, SnapSegment } from \"./types\";\nimport { tableLayout } from \"../paint/tableLayout\";\nimport { withNearIndex } from \"./nearIndex\";\nimport type { ReferenceObject } from \"../model/objects\";\nimport {\n applyMat,\n clipSegment,\n placedBounds,\n placedCorners,\n referenceTransform,\n type ReferenceContent,\n} from \"../reference/reference\";\n\n/** Everything the derivation needs that a store would otherwise supply. */\nexport interface SnapGeometryContext {\n /** Document dimension style (dimension geometry resolves overrides on it). */\n dimStyles: readonly DimStyle[];\n /** Document text style (texts without their own font inherit from it). */\n textStyles: readonly TextStyle[];\n /** The document's block module sources, for evaluating instance children. */\n blockDefinitions: readonly string[];\n /**\n * Document-wide object lookup for block object-reference inputs; absent →\n * referenced inputs evaluate as null (see BlockObjectResolver).\n */\n resolveObject?: (id: string) => ModelObject | undefined;\n /** Text width measurement (canvas-backed in editor, font-metric in Node). */\n measure: TextMeasurer;\n /** Loaded reference content (see PaintEnv.resolveReference); absent or\n * null → a reference snaps and picks by its frame only. */\n resolveReference?: (ref: ReferenceObject) => ReferenceContent | null;\n}\n\n/** buildEntry output; `pointBounds` is derived centrally in buildSnapEntry. */\nexport type BuiltEntry = Omit<SnapCacheEntry, \"pointBounds\">;\n\n/** Tight AABB of an arc: endpoints plus axis-crossing extremes within range. */\nconst arcBoundsInto = (a: ArcGeom, b: AABB): void => {\n addPointToBounds(b, pointOnArc(a, a.startAngle));\n addPointToBounds(b, pointOnArc(a, a.endAngle));\n for (const ang of [0, Math.PI / 2, Math.PI, (3 * Math.PI) / 2]) {\n if (angleInArc(a, ang)) addPointToBounds(b, pointOnArc(a, ang));\n }\n};\n\nconst curveBounds = (segments: Segment[], arcs: ArcGeom[]): AABB => {\n const bounds = emptyBounds();\n for (const s of segments) {\n addPointToBounds(bounds, s.a);\n addPointToBounds(bounds, s.b);\n }\n for (const a of arcs) arcBoundsInto(a, bounds);\n return bounds;\n};\n\nconst buildPolyline = (\n obj: Pick<Polyline, \"points\" | \"closed\">,\n): BuiltEntry => {\n const { segments, arcs } = verticesToCurves(obj.points, obj.closed);\n const points: SnapPoint[] = obj.points.map((v) => ({\n p: { x: v.x, y: v.y },\n type: \"endpoint\" as const,\n }));\n for (const s of segments) points.push({ p: mid(s.a, s.b), type: \"midpoint\" });\n for (const a of arcs) {\n points.push({ p: arcMidPoint(a), type: \"midpoint\" });\n points.push({ p: a.center, type: \"center\" });\n }\n return { bounds: curveBounds(segments, arcs), points, segments, arcs };\n};\n\nconst buildEllipse = (obj: Ellipse): BuiltEntry => {\n const pts = tessellateEllipse(obj);\n const segments: SnapSegment[] = [];\n for (let i = 1; i < pts.length; i++)\n segments.push({ a: pts[i - 1], b: pts[i], chord: true });\n const points: SnapPoint[] = [{ p: obj.center, type: \"center\" }];\n // Axis endpoints act as quadrants; range-filtered for partial ellipses.\n for (const t of [0, Math.PI / 2, Math.PI, (3 * Math.PI) / 2]) {\n if (paramInEllipse(obj, t))\n points.push({ p: pointOnEllipse(obj, t), type: \"quadrant\" });\n }\n if (!isFullEllipse(obj)) {\n points.push({ p: pointOnEllipse(obj, obj.startAngle), type: \"endpoint\" });\n points.push({ p: pointOnEllipse(obj, obj.endAngle), type: \"endpoint\" });\n }\n return {\n bounds: boundsOfPoints(pts),\n points,\n segments,\n arcs: [],\n ellipses: [\n {\n center: obj.center,\n majorAxis: obj.majorAxis,\n ratio: obj.ratio,\n startAngle: obj.startAngle,\n endAngle: obj.endAngle,\n },\n ],\n };\n};\n\nconst buildHatch = (obj: Hatch): BuiltEntry => {\n let bounds = emptyBounds();\n const points: SnapPoint[] = [];\n const segments: Segment[] = [];\n const arcs: ArcGeom[] = [];\n const rings: Vec2[][] = [];\n for (const loop of obj.loops) {\n const curves = verticesToCurves(loop.points, true);\n segments.push(...curves.segments);\n arcs.push(...curves.arcs);\n for (const v of loop.points)\n points.push({ p: { x: v.x, y: v.y }, type: \"endpoint\" });\n rings.push(verticesToPolygon(loop.points));\n bounds = unionBounds(bounds, curveBounds(curves.segments, curves.arcs));\n }\n return { bounds, points, segments, arcs, rings };\n};\n\nconst buildText = (\n obj: Text,\n measure: TextMeasurer,\n textStyles: readonly TextStyle[],\n): BuiltEntry => {\n // The text box: inside-clicks select (ring), edges support crossing select.\n // A visible frame is real, snappable geometry (snaps like a polyline): a\n // closed frame REPLACES the invisible box outline; a rule is added\n // alongside the box.\n const parts = textFrameGeometry(obj, measure, textStyles);\n const closed = parts.find((p) => p.closed);\n const box = textBoxCorners(obj, measure, textStyles);\n const outline = closed ? verticesToPolygon(closed.points) : box;\n const segments: Segment[] = closed\n ? []\n : box.map((c, i) => ({ a: c, b: box[(i + 1) % box.length] }));\n const points: SnapPoint[] = [{ p: obj.position, type: \"endpoint\" }];\n const arcs: ArcGeom[] = [];\n const bounds = boundsOfPoints(outline);\n for (const part of parts) {\n const e = buildPolyline(part);\n segments.push(...e.segments);\n arcs.push(...e.arcs);\n points.push(...e.points);\n addPointToBounds(bounds, { x: e.bounds.minX, y: e.bounds.minY });\n addPointToBounds(bounds, { x: e.bounds.maxX, y: e.bounds.maxY });\n }\n // Leader lines snap and hit-test like polylines.\n for (const line of obj.leaderLines) {\n for (let i = 1; i < line.length; i++) {\n segments.push({ a: line[i - 1], b: line[i] });\n }\n for (const p of line) {\n points.push({ p, type: \"endpoint\" });\n addPointToBounds(bounds, p);\n }\n }\n return {\n bounds,\n points,\n segments,\n arcs,\n rings: [outline],\n };\n};\n\nconst buildDimension = (\n obj: Dimension,\n dimStyles: readonly DimStyle[],\n measure: TextMeasurer,\n textStyles: readonly TextStyle[],\n): BuiltEntry => {\n const geom = dimensionGeometry(obj, dimStyles);\n const points: SnapPoint[] = obj.points.map((p) => ({\n p,\n type: \"endpoint\" as const,\n }));\n if (!geom) {\n return {\n bounds: boundsOfPoints(obj.points),\n points,\n segments: [],\n arcs: [],\n };\n }\n const segments = [...geom.extensionLines, ...geom.dimLines, ...geom.leaders];\n // The measurement text boxes: inside-clicks select the dimension (rings),\n // edges support crossing selection — same treatment as text objects.\n const rings: Vec2[][] = [];\n for (const text of geom.labels) {\n const corners = textBoxCorners(\n {\n type: \"text\",\n id: obj.id,\n layerId: obj.layerId,\n position: text.anchor,\n content: text.content,\n rotation: text.rotation,\n hAlign: \"center\",\n vAlign: \"center\",\n leaderLines: [],\n scale: 1,\n // The dim style's resolved metrics, pinned as overrides so the\n // document TEXT style can't leak into dimension text boxes.\n styleOverride: {\n textHeight: text.height,\n font: text.font,\n widthFactor: text.widthFactor,\n },\n },\n measure,\n textStyles,\n );\n rings.push(corners);\n segments.push(\n ...corners.map((c, i) => ({\n a: c,\n b: corners[(i + 1) % corners.length],\n })),\n );\n }\n const arcs = geom.dimArc\n ? [\n {\n center: geom.dimArc.center,\n radius: geom.dimArc.radius,\n startAngle: geom.dimArc.startAngle,\n endAngle: geom.dimArc.endAngle,\n },\n ]\n : [];\n const bounds = curveBounds(segments, arcs);\n for (const p of obj.points) addPointToBounds(bounds, p);\n for (const seg of geom.dimLines)\n points.push({ p: mid(seg.a, seg.b), type: \"midpoint\" });\n return { bounds, points, segments, arcs, rings };\n};\n\n/**\n * Derived snap/hit-test geometry for one object (without `pointBounds`, which\n * `buildSnapEntry` adds). Pure: pass `ctx` for the store-derived inputs.\n */\nexport const buildEntry = (\n obj: ModelObject,\n ctx: SnapGeometryContext,\n): BuiltEntry => {\n switch (obj.type) {\n case \"line\": {\n const bounds = emptyBounds();\n addPointToBounds(bounds, obj.a);\n addPointToBounds(bounds, obj.b);\n return {\n bounds,\n points: [\n { p: obj.a, type: \"endpoint\" },\n { p: obj.b, type: \"endpoint\" },\n { p: mid(obj.a, obj.b), type: \"midpoint\" },\n ],\n segments: [{ a: obj.a, b: obj.b }],\n arcs: [],\n };\n }\n case \"point\": {\n // One snap point (node); the degenerate segment is what makes the dot\n // click-pickable — distanceToObject only measures segments/arcs/rings.\n const bounds = emptyBounds();\n addPointToBounds(bounds, obj.p);\n return {\n bounds,\n points: [{ p: obj.p, type: \"endpoint\" }],\n segments: [{ a: obj.p, b: obj.p }],\n arcs: [],\n };\n }\n case \"polyline\":\n return buildPolyline(obj);\n case \"circle\": {\n const { center: center, radius } = obj;\n const bounds: AABB = {\n minX: center.x - radius,\n minY: center.y - radius,\n maxX: center.x + radius,\n maxY: center.y + radius,\n };\n const geom: ArcGeom = {\n center,\n radius,\n startAngle: 0,\n endAngle: Math.PI * 2 - 1e-9,\n };\n const quadrants: SnapPoint[] = [\n 0,\n Math.PI / 2,\n Math.PI,\n (3 * Math.PI) / 2,\n ].map((ang) => ({\n p: pointOnArc(geom, ang),\n type: \"quadrant\" as const,\n }));\n return {\n bounds,\n points: [{ p: center, type: \"center\" }, ...quadrants],\n segments: [],\n arcs: [geom],\n };\n }\n case \"arc\": {\n const geom: ArcGeom = {\n center: obj.center,\n radius: obj.radius,\n startAngle: normAngle(obj.startAngle),\n endAngle: normAngle(obj.endAngle),\n };\n const bounds = emptyBounds();\n arcBoundsInto(geom, bounds);\n return {\n bounds,\n points: [\n { p: pointOnArc(geom, geom.startAngle), type: \"endpoint\" },\n { p: pointOnArc(geom, geom.endAngle), type: \"endpoint\" },\n {\n p: pointOnArc(geom, geom.startAngle + arcSweep(geom) / 2),\n type: \"midpoint\",\n },\n { p: geom.center, type: \"center\" },\n ],\n segments: [],\n arcs: [geom],\n };\n }\n case \"ellipse\":\n return buildEllipse(obj);\n case \"hatch\":\n return buildHatch(obj);\n case \"text\":\n return buildText(obj, ctx.measure, ctx.textStyles);\n case \"dimension\":\n return buildDimension(obj, ctx.dimStyles, ctx.measure, ctx.textStyles);\n case \"viewport\": {\n // Frame corners/edges snap and hit-test; the interior ring makes\n // clicks inside the viewport select it (annotations still win —\n // pickObjectAt prefers non-viewport hits).\n const { x, y, w, h } = obj.rect;\n const corners: Vec2[] = [\n { x, y },\n { x: x + w, y },\n { x: x + w, y: y + h },\n { x, y: y + h },\n ];\n const segments: Segment[] = corners.map((c, i) => ({\n a: c,\n b: corners[(i + 1) % corners.length],\n }));\n const points: SnapPoint[] = corners.map((p) => ({\n p,\n type: \"endpoint\" as const,\n }));\n for (const s of segments)\n points.push({ p: mid(s.a, s.b), type: \"midpoint\" });\n return {\n bounds: { minX: x, minY: y, maxX: x + w, maxY: y + h },\n points,\n segments,\n arcs: [],\n rings: [corners],\n };\n }\n case \"block\": {\n // Merge the entries of the evaluated (world-space) children, so block\n // internals snap and hit-test exactly like native geometry.\n // Every point input snaps as an endpoint — the first one IS the\n // pivot (blockPivot falls back to {0,0} for point-less instances).\n const inputPoints = obj.inputs.filter(\n (v): v is Vec2 => typeof v !== \"string\",\n );\n const points: SnapPoint[] = (\n inputPoints.length > 0 ? inputPoints : [blockPivot(obj)]\n ).map((p) => ({ p, type: \"endpoint\" }));\n const segments: Segment[] = [];\n const arcs: ArcGeom[] = [];\n const ellipses: EllipseGeom[] = [];\n const rings: Vec2[][] = [];\n const regions: Vec2[][][] = [];\n let bounds = emptyBounds();\n for (const { p } of points) addPointToBounds(bounds, p);\n for (const child of getEvaluatedWorldChildren(\n obj,\n ctx.blockDefinitions,\n ctx.resolveObject,\n ctx, // its text / dim styles: what draw's `styles` reads\n )) {\n const entry = buildEntry(child, ctx);\n points.push(...entry.points);\n segments.push(...entry.segments);\n arcs.push(...entry.arcs);\n if (entry.ellipses) ellipses.push(...entry.ellipses);\n // Text/dimension boxes keep their inside-click hit area (rings).\n // Hatch fills become REGIONS — one even-odd set per hatch, ranked\n // by pickObjectAt like a top-level hatch, so a click on a hatched\n // block's pattern selects the block while geometry drawn over the\n // fill still wins. Nested blocks pass their regions up.\n // ponytail: rings merge under even-odd, so overlapping text boxes\n // cancel in the overlap — per-child ring sets if that ever matters.\n if (child.type === \"hatch\") {\n if (entry.rings && entry.rings.length > 0) regions.push(entry.rings);\n } else if (entry.rings) rings.push(...entry.rings);\n if (entry.regions) regions.push(...entry.regions);\n bounds = unionBounds(bounds, entry.bounds);\n }\n return { bounds, points, segments, arcs, ellipses, rings, regions };\n }\n case \"table\": {\n // The rules snap and hit-test like lines (endpoints at the grid\n // crossings they start/end on); the outline ring makes clicks\n // anywhere inside pick the table, like text.\n const { outline, children } = tableLayout(obj, ctx.textStyles);\n const segments: Segment[] = [];\n const points: SnapPoint[] = outline.map((p) => ({\n p,\n type: \"endpoint\" as const,\n }));\n for (const c of children) {\n if (c.type !== \"line\") continue;\n segments.push({ a: c.a, b: c.b });\n points.push({ p: c.a, type: \"endpoint\" }, { p: c.b, type: \"endpoint\" });\n }\n return {\n bounds: boundsOfPoints(outline),\n points,\n segments,\n arcs: [],\n rings: [outline],\n };\n }\n case \"image\": {\n // Corners/edges snap and hit-test. Deliberately NO interior ring:\n // a reference image is picked by its outline frame only, so geometry\n // traced over it stays hoverable everywhere inside.\n const corners = imageCorners(obj);\n const segments: Segment[] = corners.map((c, i) => ({\n a: c,\n b: corners[(i + 1) % corners.length],\n }));\n const points: SnapPoint[] = corners.map((p) => ({\n p,\n type: \"endpoint\" as const,\n }));\n for (const s of segments)\n points.push({ p: mid(s.a, s.b), type: \"midpoint\" });\n points.push({ p: imageCenter(obj), type: \"center\" });\n return {\n bounds: boundsOfPoints(corners),\n points,\n segments,\n arcs: [],\n };\n }\n case \"comment\": {\n // Cache entries are camera-independent; the marker is screen-fixed, so\n // only the pin point lives here (tip snaps as an endpoint, marquees\n // catch the tip). The zoom-scaled bubble hit-test is the editor's\n // pickObjectAt special case.\n const bounds = emptyBounds();\n addPointToBounds(bounds, obj.position);\n return {\n bounds,\n points: [{ p: obj.position, type: \"endpoint\" }],\n segments: [{ a: obj.position, b: obj.position }],\n arcs: [],\n };\n }\n case \"reference\":\n return referenceEntry(obj, ctx);\n default: {\n // Every type has a case (a new one fails typecheck here); at runtime\n // an unknown type gets no snap geometry — empty bounds keeps it out\n // of queries.\n obj satisfies never;\n return { bounds: emptyBounds(), points: [], segments: [], arcs: [] };\n }\n }\n};\n\n/** A safety limit only: snapping and picking query a reference's geometry\n * through a spatial index (withNearIndex), so even a 10⁵–10⁶-segment site\n * plan stays fully snappable. Past this a file still draws, unsnapped. */\nexport const MAX_REFERENCE_SNAP_SEGMENTS = 2_000_000;\n\n/**\n * A reference snaps and picks by its CONTENT's geometry, placed by the\n * reference's transform (rotation + uniform scale + optional mirror keep\n * arcs arcs and ellipses ellipses). Deliberately no interior ring: like an\n * image, geometry drawn over a reference stays hoverable. Not loaded → its\n * frame (last known extent, else a small square at the insertion point).\n */\nconst referenceEntry = (\n obj: ReferenceObject,\n ctx: SnapGeometryContext,\n): BuiltEntry => {\n // Switched off: out of every query (empty bounds), like an empty object.\n if (obj.hidden)\n return { bounds: emptyBounds(), points: [], segments: [], arcs: [] };\n const m = referenceTransform(obj);\n const content = ctx.resolveReference?.(obj) ?? null;\n if (!content) {\n const corners = placedCorners(\n m,\n obj.extent ?? {\n minX: 0,\n minY: 0,\n maxX: 5 / obj.scale,\n maxY: 5 / obj.scale,\n },\n );\n const segments = corners.map((a, i) => ({ a, b: corners[(i + 1) % 4] }));\n return {\n bounds: boundsOfPoints(corners),\n points: [\n ...corners.map((p) => ({ p, type: \"endpoint\" as const })),\n { p: obj.position, type: \"endpoint\" as const },\n ],\n segments,\n arcs: [],\n };\n }\n const s = obj.scale;\n const flip = obj.mirrored ? -1 : 1;\n // A file angle → host angle (mirroring reflects across the file's X axis).\n // A left-right flip maps a file angle t to π − t.\n const ang = (t: number) =>\n normAngle((flip < 0 ? Math.PI - t : t) + obj.rotation);\n const linear = (v: Vec2): Vec2 => {\n const o = applyMat(m, { x: 0, y: 0 });\n const p = applyMat(m, v);\n return { x: p.x - o.x, y: p.y - o.y };\n };\n const childCtx: SnapGeometryContext = {\n dimStyles: content.dimStyles,\n textStyles: content.textStyles,\n blockDefinitions: content.blockDefinitions,\n resolveObject: content.resolveObject,\n resolveReference: content.resolveReference,\n measure: ctx.measure,\n };\n const hidden = new Set(obj.hiddenLayers);\n const shown = new Map(\n content.layers.map((l) => [l.id, l.visible && !hidden.has(l.name)]),\n );\n const points: SnapPoint[] = [{ p: obj.position, type: \"endpoint\" }];\n const segments: SnapSegment[] = [];\n const arcs: ArcGeom[] = [];\n const ellipses: EllipseGeom[] = [];\n // A clip crops snapping like drawing. ponytail: curves snap only when\n // wholly inside the clip (no curve/box clipping) — clipped arcs still draw.\n const clip = obj.clip;\n const inClip = (p: Vec2) =>\n !clip ||\n (p.x >= clip.minX &&\n p.x <= clip.maxX &&\n p.y >= clip.minY &&\n p.y <= clip.maxY);\n const curveInClip = (c: Vec2, r: number) =>\n !clip ||\n (c.x - r >= clip.minX &&\n c.x + r <= clip.maxX &&\n c.y - r >= clip.minY &&\n c.y + r <= clip.maxY);\n /** Add one file-space entry, clipped and placed. */\n const add = (e: {\n points: readonly SnapPoint[];\n segments: readonly SnapSegment[];\n arcs: readonly ArcGeom[];\n ellipses?: readonly EllipseGeom[];\n }): void => {\n for (const sp of e.points)\n if (inClip(sp.p)) points.push({ p: applyMat(m, sp.p), type: sp.type });\n for (const seg of e.segments) {\n const kept = clip ? clipSegment(seg.a, seg.b, clip) : [seg.a, seg.b];\n if (kept)\n segments.push({\n a: applyMat(m, kept[0]),\n b: applyMat(m, kept[1]),\n chord: seg.chord,\n });\n }\n for (const a of e.arcs) {\n if (!curveInClip(a.center, a.radius)) continue;\n // Mirroring reverses the sweep: the CCW range swaps ends.\n const [start, end] =\n flip < 0 ? [a.endAngle, a.startAngle] : [a.startAngle, a.endAngle];\n arcs.push({\n center: applyMat(m, a.center),\n radius: a.radius * s,\n startAngle: ang(start),\n endAngle: ang(end),\n });\n }\n for (const el of e.ellipses ?? []) {\n if (!curveInClip(el.center, Math.hypot(el.majorAxis.x, el.majorAxis.y)))\n continue;\n const [start, end] =\n flip < 0\n ? [-el.endAngle, -el.startAngle]\n : [el.startAngle, el.endAngle];\n ellipses.push({\n center: applyMat(m, el.center),\n majorAxis: linear(el.majorAxis),\n ratio: el.ratio,\n startAngle: normAngle(start),\n endAngle: normAngle(end),\n });\n }\n };\n const layerShown = (layer: string) => shown.get(layer) !== false;\n if (content.snap) {\n // Precomputed off the main thread (and, for a raster PDF, the page's\n // vector lines under the image): filter by layer, clip, place.\n const f = content.snap;\n add({\n points: f.points.filter((p) => layerShown(p.layer)),\n segments: f.segments\n .filter((sg) => layerShown(sg.layer))\n .slice(0, MAX_REFERENCE_SNAP_SEGMENTS),\n arcs: f.arcs.filter((ar) => layerShown(ar.layer)),\n ellipses: f.ellipses.filter((el) => layerShown(el.layer)),\n });\n }\n for (const child of content.objects) {\n if (segments.length >= MAX_REFERENCE_SNAP_SEGMENTS) break;\n if (!layerShown(child.layerId)) continue;\n // With precomputed geometry only nested references are left to build.\n if (content.snap && child.type !== \"reference\") continue;\n add(buildEntry(child, childCtx));\n }\n const shownBounds = clip\n ? {\n minX: Math.max(content.bounds.minX, clip.minX),\n minY: Math.max(content.bounds.minY, clip.minY),\n maxX: Math.min(content.bounds.maxX, clip.maxX),\n maxY: Math.min(content.bounds.maxY, clip.maxY),\n }\n : content.bounds;\n const bounds =\n isEmptyBounds(shownBounds) || shownBounds.minX > shownBounds.maxX\n ? boundsOfPoints(points.map((p) => p.p))\n : placedBounds(m, shownBounds);\n return { bounds, points, segments, arcs, ellipses };\n};\n\n/**\n * Full snap-cache entry for an object: `buildEntry` plus the `pointBounds`\n * query box (bounds unioned with every snap point, so off-curve points like\n * an arc's center still fall inside the candidate box). Pure — the caller\n * owns caching and invalidation.\n */\nexport const buildSnapEntry = (\n obj: ModelObject,\n ctx: SnapGeometryContext,\n): SnapCacheEntry => {\n const built = buildEntry(obj, ctx);\n const pointBounds = { ...built.bounds };\n for (const sp of built.points) addPointToBounds(pointBounds, sp.p);\n // A reference can carry a whole site plan: answer \"near the cursor\" from\n // a spatial index instead of scanning it all (SnapCacheEntry.near).\n return obj.type === \"reference\"\n ? withNearIndex({ ...built, pointBounds })\n : { ...built, pointBounds };\n};\n","// DXF import: parse, scale to mm ($INSUNITS), create missing layers, convert\n// entities, add everything in ONE undoable transaction. Paper space comes\n// back too: *Paper_Space blocks (+ the flat inPaperSpace entities of the\n// active layout) are rebuilt as PaperLayouts, VIEWPORT entities become\n// viewport objects, and LAYOUT objects (parsed from the raw OBJECTS section\n// — dxf-parser skips it) supply names, tab order, and sheet sizes.\n\nimport DxfParser from \"dxf-parser\";\nimport type { IEntity, IDxf, IBlock } from \"dxf-parser\";\nimport type {\n DimStyle,\n ModelObject,\n ModelObjectDto,\n PolylineVertex,\n TextStyle,\n} from \"../../model/objects\";\nimport {\n DEFAULT_DIM_STYLE,\n DEFAULT_TEXT_STYLE,\n ModelObjectSchema,\n} from \"../../model/objects\";\nimport {\n dimStyleFromRecord,\n dimValuesFromGroups,\n emptyStyleRecord,\n mergeStyles,\n overrideAgainst,\n sameDimStyle,\n sameTextStyle,\n textStyleFromRecord,\n type DimStyleRecord,\n type DimValues,\n type HeightHistogram,\n type StyleRecord,\n} from \"./styleTables\";\nimport {\n dimensionRawToLabels,\n dimensionRawToOffset,\n} from \"../../model/migrations\";\nimport * as v2 from \"../../geometry/vec2\";\nimport {\n interpolateFitPoints,\n isValidNurbs,\n sampleNurbs,\n type NurbsCurve,\n} from \"../../geometry/nurbs\";\nimport { polylineBand } from \"../../geometry/band\";\nimport {\n blockDefinitionModule,\n type ImportedBlockDefinition,\n} from \"./blockDefinitions\";\nimport { linearAxis } from \"../../paint/dimensionGeometry\";\nimport type { Layer } from \"../../model/document\";\nimport type { PaperLayout } from \"../../model/paperLayout\";\nimport { PaperLayoutSchema } from \"../../model/paperLayout\";\nimport {\n bump,\n emptyLedger,\n total,\n reconcileLedger,\n scanEntityHistogram,\n type ImportLedger,\n} from \"./entityLedger\";\nimport type { Vec2 } from \"../../geometry/vec2\";\nimport { dist } from \"../../geometry/vec2\";\nimport {\n arcEndPoint,\n arcFrom3Points,\n arcMidPoint,\n arcStartPoint,\n bulgeFrom3Points,\n bulgeToArc,\n} from \"../../geometry/arcs\";\nimport { aciToHex, hexToRgb, rgbToHex } from \"../../export/dxf/aci\";\nimport { normalizeSpans } from \"../../paint/richText\";\nimport {\n cleanText,\n decodeTextEscapes,\n lineWeightToMm,\n cleanRichText,\n mtextFontFlags,\n mtextWidthFactor,\n} from \"../../export/dxf/codecs\";\nimport {\n getHatchPattern,\n hatchPatternKey,\n type DocumentHatchPattern,\n} from \"../../model/hatchPatterns\";\nimport { getLineType, lineTypeKey, type LineType } from \"../../model/lineTypes\";\nimport {\n ViewportHandler,\n HatchHandler,\n AcadTableHandler,\n type AcadTableData,\n LeaderHandler,\n MultiLeaderHandler,\n AttribHandler,\n MlineHandler,\n TraceHandler,\n} from \"./extraEntities\";\nimport {\n parseLayoutObjects,\n parseMlineStyles,\n type DxfMlineStyle,\n} from \"./objectsSection\";\nimport { referenceFormatOf } from \"../../reference/reference\";\nimport { dxfLines } from \"./dxfLines\";\n\nconst DEG2RAD = Math.PI / 180;\n\n/** Zoom-lock bit of the VIEWPORT status flags (group 90). */\n/** Group 90 bit: the viewport is turned off. */\nconst VIEWPORT_OFF_FLAG = 0x20000;\nconst VIEWPORT_LOCKED_FLAG = 16384;\n\n/** mm per drawing unit, from $INSUNITS. */\nconst unitFactor = (insunits: unknown): number => {\n switch (insunits) {\n case 1:\n return 25.4; // inches\n case 2:\n return 304.8; // feet\n case 5:\n return 10; // cm\n case 6:\n return 1000; // m\n case 4:\n case 0:\n default:\n return 1; // mm / unspecified\n }\n};\n\n/** Lineweight every imported layer/entity gets (DXF weights aren't read). */\nconst IMPORT_LINE_WIDTH_MM = 0.25;\n/** Chord tolerance for sampling SPLINE curves into polylines (world mm). */\nconst SPLINE_TOLERANCE_MM = 0.02;\n\ninterface ImportContext extends ImportLedger {\n f: number;\n layerIdByName: Map<string, string>;\n /** Layers whose line type dashes — their entities inherit a dash pattern,\n * so group 48 conversion applies even without an entity-level line type. */\n dashedLayerIds: Set<string>;\n defaultLayerId: string;\n /** The document's styles after the merge, by id — what an entity's\n * override is relative to. */\n textStyleById: Map<string, TextStyle>;\n dimStyleById: Map<string, DimStyle>;\n /** DXF style name (lower-cased) → document style id. */\n textStyleIdByName: Map<string, string>;\n dimStyleIdByName: Map<string, string>;\n /** Each merged dim style's DIMSCALE — ours is the object's `scale`. */\n dimScaleByStyleId: Map<string, number>;\n /** What an unstyled entity follows: the document's first style. */\n defaultTextStyle: TextStyle;\n defaultDimStyle: DimStyle;\n /** DIMSTYLE groups → values, bound to this file's tables (for the\n * per-dimension DSTYLE xdata overrides). */\n dimValuesFrom: (groups: Map<number, string>) => DimValues;\n /** Overall dimension scale ($DIMSCALE); 1 = none. Applied to dimensions\n * whose own style the file does not define. */\n dimScale: number;\n /** Global line type scale ($LTSCALE); 1 = none. */\n ltScale: number;\n /** LAYER record handle → name, to resolve a viewport's frozen layers (331). */\n layerNameByHandle: Map<string, string>;\n /** Groups dxf-parser drops or mangles, read off the raw tag stream. */\n tags: RawTags;\n /** MLINESTYLE objects, for MLINE caps and the no-parameter fallback. */\n mlineStyles: ReturnType<typeof parseMlineStyles>;\n /** The file's LTYPE definitions the catalogue lacks, by name key — a\n * document line type is created on first use (`usedLineTypes`). */\n customLineTypes: Map<string, LineType>;\n usedLineTypes: Map<string, LineType>;\n /** Document hatch patterns rebuilt from HATCH definition lines, by key\n * (first definition of a name wins). */\n hatchPatterns: Map<string, DocumentHatchPattern>;\n /** Block definitions generated for INSERTs, by upper-cased block name:\n * null = this block explodes (mixed layers, no visible geometry). */\n blockDefinitions: Map<string, ImportedBlockDefinition | null>;\n /** The generated modules the document lacks, in first-use order. */\n newBlockDefinitions: ImportedBlockDefinition[];\n /** The document's block modules (id + name). */\n existingBlocks: readonly { id: string; name: string }[];\n /** Lineweight (mm) of each layer created by this import — the width an\n * inherited dash pattern scales by. */\n layerWidthById: Map<string, number>;\n /** Color of each layer created by this import (existing layers arrive\n * as id + name only) — what a ByBlock child of a ByLayer insert, or a\n * ByLayer child on its own layer inside a definition, bakes to. */\n layerColorById: Map<string, string>;\n}\n\n/** LAYER table groups dxf-parser leaves unread. */\ninterface LayerTags {\n handle?: string;\n lineType?: string;\n /** Group 370 in 1/100 mm; negative = default. */\n lineWeight?: number;\n locked?: boolean;\n plot?: boolean;\n}\n\ninterface RawTags {\n /** Exact colors (group 420) by entity handle. */\n trueColorByHandle: Map<string, string>;\n trueColorByLayerName: Map<string, string>;\n /** Entity lineweight (370, 1/100 mm; −1 ByLayer, −2 ByBlock, −3 default). */\n lineWeightByHandle: Map<string, number>;\n /** Entities whose extrusion (230) points down: their OCS x axis is the\n * mirror of the world's. */\n mirroredHandles: Set<string>;\n layers: Map<string, LayerTags>;\n /** STYLE table records by name (shape files left out) and by handle. */\n textStyles: Map<string, StyleRecord>;\n textStyleByHandle: Map<string, StyleRecord>;\n /** DIMSTYLE table records by name. */\n dimStyles: Map<string, DimStyleRecord>;\n /** BLOCK_RECORD name by handle (arrowhead blocks). */\n blockNameByHandle: Map<string, string>;\n /** TEXT / MTEXT / ATTRIB / ATTDEF group 7 (style name) by entity handle. */\n textStyleNameByHandle: Map<string, string>;\n /** DIMENSION / LEADER group 3 (dim style name) by entity handle. */\n dimStyleNameByHandle: Map<string, string>;\n /** DIMENSION DSTYLE xdata: DIMSTYLE group → value, by entity handle. */\n dimOverridesByHandle: Map<string, Map<number, string>>;\n /** Per text style name (lower-cased; \"\" = the default), the heights its\n * texts use — the style's height when the record fixes none. */\n textHeightsByStyle: Map<string, HeightHistogram>;\n /** SPLINE weights (41, one per control point) by handle — dxf-parser\n * drops them, and a rational spline (a circle as NURBS) needs them. */\n splineWeightsByHandle: Map<string, number[]>;\n}\n\n/** Entity types whose group 7 names a text style. */\nconst TEXT_TYPES = new Set([\"TEXT\", \"MTEXT\", \"ATTRIB\", \"ATTDEF\"]);\n/** Entity types whose group 3 names a dimension style. */\nconst DIM_TYPES = new Set([\"DIMENSION\", \"LEADER\"]);\n\n/**\n * One pass over the raw tag stream for what dxf-parser cannot give us. It\n * applies group codes last-wins, so a 62 written AFTER a 420 (our own\n * writer's order) clobbers the exact color; its LAYER table parser reads\n * only name, color and flags (no line type, lineweight, plot flag); its\n * custom-handler entities (hatch, leaders, tables) never see 370; and only\n * some of its handlers expose the extrusion direction.\n */\nconst scanTags = (lines: readonly string[]): RawTags => {\n const out: RawTags = {\n trueColorByHandle: new Map(),\n trueColorByLayerName: new Map(),\n lineWeightByHandle: new Map(),\n mirroredHandles: new Set(),\n layers: new Map(),\n textStyles: new Map(),\n textStyleByHandle: new Map(),\n dimStyles: new Map(),\n blockNameByHandle: new Map(),\n textStyleNameByHandle: new Map(),\n dimStyleNameByHandle: new Map(),\n dimOverridesByHandle: new Map(),\n textHeightsByStyle: new Map(),\n splineWeightsByHandle: new Map(),\n };\n const hex24 = (value: string): string | undefined => {\n const v = Number(value);\n return Number.isFinite(v)\n ? rgbToHex((v >> 16) & 0xff, (v >> 8) & 0xff, v & 0xff)\n : undefined;\n };\n let type = \"\";\n let handle = \"\";\n let name = \"\";\n let layer: LayerTags | null = null;\n let style: StyleRecord | null = null;\n let dim: DimStyleRecord | null = null;\n // Text entity: style (7) + height (40) land in the histogram at its end.\n let textStyle = \"\";\n let textHeight = 0;\n // xdata state: the application after 1001; a DIMENSION's ACAD DSTYLE\n // block is `1000 DSTYLE / 1002 { / (1070 code, value)… / 1002 }`.\n let xApp = \"\";\n let dstyleArmed = false;\n let dstyle: Map<number, string> | null = null;\n let pendingCode: number | undefined;\n const flushText = () => {\n if (TEXT_TYPES.has(type) && textHeight > 0) {\n const key = textStyle.toLowerCase();\n let hist = out.textHeightsByStyle.get(key);\n if (!hist) out.textHeightsByStyle.set(key, (hist = new Map()));\n hist.set(textHeight, (hist.get(textHeight) ?? 0) + 1);\n }\n textStyle = \"\";\n textHeight = 0;\n };\n for (let i = 0; i + 1 < lines.length; i += 2) {\n const code = lines[i].trim();\n const value = lines[i + 1].trim();\n if (code === \"0\") {\n flushText();\n type = value;\n handle = \"\";\n name = \"\";\n layer = value === \"LAYER\" ? {} : null;\n style = value === \"STYLE\" ? emptyStyleRecord() : null;\n dim = value === \"DIMSTYLE\" ? { name: \"\", groups: new Map() } : null;\n xApp = \"\";\n dstyleArmed = false;\n dstyle = null;\n pendingCode = undefined;\n } else if (code === \"1001\") {\n xApp = value;\n dstyleArmed = false;\n dstyle = null;\n pendingCode = undefined;\n } else if (xApp) {\n // Extended data (1000–1071) closes a record; only two kinds matter.\n if (style) {\n if (code === \"1000\") style.typeface = value;\n else if (code === \"1071\") style.flags = Number(value) || 0;\n } else if (xApp === \"ACAD\" && type === \"DIMENSION\") {\n if (code === \"1000\" && value === \"DSTYLE\") dstyleArmed = true;\n else if (code === \"1002\" && value === \"{\" && dstyleArmed)\n dstyle = new Map();\n else if (code === \"1002\" && value === \"}\") {\n if (dstyle && handle) out.dimOverridesByHandle.set(handle, dstyle);\n dstyle = null;\n dstyleArmed = false;\n } else if (dstyle) {\n if (pendingCode === undefined) {\n if (code === \"1070\") pendingCode = Number(value);\n } else {\n dstyle.set(pendingCode, value);\n pendingCode = undefined;\n }\n }\n }\n } else if (dim) {\n // DIMSTYLE: 105 is the handle; 5/6/7 are the R12 arrow block NAMES.\n if (code === \"105\") dim.handle = value;\n else if (code === \"2\") {\n dim.name = value;\n out.dimStyles.set(value, dim);\n } else if (code !== \"100\" && code !== \"330\" && code !== \"70\")\n dim.groups.set(Number(code), value);\n } else if (code === \"5\") {\n handle = value;\n if (layer) layer.handle = value;\n if (style) style.handle = value;\n } else if (code === \"2\") {\n name = value;\n if (layer) out.layers.set(name, layer);\n if (type === \"BLOCK_RECORD\" && handle)\n out.blockNameByHandle.set(handle.toUpperCase(), value);\n } else if (style) {\n if (code === \"2\") style.name = value;\n else if (code === \"3\") style.fontFile = value;\n else if (code === \"40\") style.fixedHeight = Number(value) || 0;\n else if (code === \"41\") style.widthFactor = Number(value) || 1;\n else if (code === \"50\") style.oblique = Number(value) || 0;\n else if (code === \"70\") {\n style.shape = (Number(value) & 1) !== 0;\n if (!style.shape && name) {\n style.name = name;\n out.textStyles.set(name, style);\n if (style.handle)\n out.textStyleByHandle.set(style.handle.toUpperCase(), style);\n }\n }\n } else if (layer) {\n if (code === \"6\") layer.lineType = value;\n else if (code === \"70\") layer.locked = (Number(value) & 4) !== 0;\n else if (code === \"290\") layer.plot = value !== \"0\";\n else if (code === \"370\") layer.lineWeight = Number(value);\n else if (code === \"420\" && name) {\n const hex = hex24(value);\n if (hex) out.trueColorByLayerName.set(name, hex);\n }\n } else if (handle) {\n if (code === \"420\") {\n const hex = hex24(value);\n if (hex) out.trueColorByHandle.set(handle, hex);\n } else if (code === \"370\") {\n const v = Number(value);\n if (Number.isFinite(v)) out.lineWeightByHandle.set(handle, v);\n } else if (code === \"230\" && Number(value) < 0) {\n out.mirroredHandles.add(handle);\n } else if (code === \"7\" && TEXT_TYPES.has(type)) {\n out.textStyleNameByHandle.set(handle, value);\n textStyle = value;\n } else if (code === \"40\" && TEXT_TYPES.has(type)) {\n textHeight = Number(value) || 0;\n } else if (code === \"3\" && DIM_TYPES.has(type)) {\n out.dimStyleNameByHandle.set(handle, value);\n } else if (code === \"41\" && type === \"SPLINE\") {\n let weights = out.splineWeightsByHandle.get(handle);\n if (!weights) out.splineWeightsByHandle.set(handle, (weights = []));\n weights.push(Number(value));\n }\n }\n }\n flushText();\n return out;\n};\n\n// dxf-parser's types are loose; a pragmatic any-view keeps readers readable.\n/* eslint-disable @typescript-eslint/no-explicit-any */\n\nconst pt = (p: { x: number; y: number }, f: number): Vec2 => ({\n x: p.x * f,\n y: p.y * f,\n});\n\n/**\n * Map a DXF linetype name onto our named library. Prefers an exact match\n * (case/punctuation-insensitive — ACAD names, ISO, JIS); the acad `NAME2` /\n * `NAMEX2` scale-variant convention resolves to the BASE type with the\n * variant's factor (0.5 / 2) reported so callers fold it into\n * lineTypeScale — the library stores only base patterns. Unknown names fall\n * back to a substring heuristic onto the curated set.\n * ByLayer / Continuous / unknown → undefined.\n */\nconst lineTypeFromDxf = (\n name: unknown,\n /** The file's own LTYPE definitions (document line types on first use). */\n custom?: Pick<ImportContext, \"customLineTypes\" | \"usedLineTypes\">,\n): { name: string; factor: number } | undefined => {\n if (typeof name !== \"string\") return undefined;\n const n = name.trim();\n if (!n || /^(bylayer|byblock|continuous)$/i.test(n)) return undefined;\n const own = custom?.customLineTypes.get(lineTypeKey(n));\n if (own) {\n custom!.usedLineTypes.set(lineTypeKey(own.name), own);\n return { name: own.name, factor: 1 };\n }\n const match = getLineType(n);\n if (match) return { name: match.name, factor: 1 };\n // acad scale variants: DASHED2 = half, DASHEDX2 = double.\n const variant = /x2$/i.test(n)\n ? { base: n.slice(0, -2), factor: 2 }\n : /2$/.test(n)\n ? { base: n.slice(0, -1), factor: 0.5 }\n : undefined;\n if (variant) {\n const baseMatch = getLineType(variant.base);\n if (baseMatch) return { name: baseMatch.name, factor: variant.factor };\n }\n const u = n.toUpperCase();\n const heuristic = u.includes(\"PHANTOM\")\n ? \"phantom\"\n : u.includes(\"DASHDOT\") || u.includes(\"DASH_DOT\")\n ? \"dashdot\"\n : u.includes(\"CENTER\") || u.includes(\"CENTRE\")\n ? \"center\"\n : u.includes(\"HIDDEN\")\n ? \"hidden\"\n : u.includes(\"DASH\")\n ? \"dashed\"\n : u.includes(\"DOT\")\n ? \"dotted\"\n : undefined;\n return heuristic ? { name: heuristic, factor: 1 } : undefined;\n};\n\nconst baseFor = (e: IEntity, ctx: ImportContext) => {\n const layerId =\n ctx.layerIdByName.get(e.layer?.toLowerCase()) ?? ctx.defaultLayerId;\n const anyE = e as any;\n // Resolve the entity's own color. dxf-parser resolves built-in entities'\n // ACI/true-color into a 24-bit `color`; our custom handlers (hatch, leader,\n // multileader, viewport) only carry `colorIndex`/`trueColor`, so resolve\n // those too. ByLayer (256) / ByBlock (0) / absent → inherit from the layer.\n const rgb24 = (v: number) =>\n rgbToHex((v >> 16) & 0xff, (v >> 8) & 0xff, v & 0xff);\n const ci = anyE.colorIndex;\n const scanned = ctx.tags.trueColorByHandle.get(String(anyE.handle));\n const color =\n typeof anyE.trueColor === \"number\"\n ? rgb24(anyE.trueColor)\n : scanned !== undefined\n ? scanned\n : // ci 0 = ByBlock: dxf-parser pre-resolves it to BLACK in `color`,\n // so it must be excluded like ByLayer. Approximated as inherit-\n // from-layer (exact only when the reference itself has no color —\n // true for tables; an explicitly colored INSERT's ByBlock children\n // would need the reference color threaded through convertInsert).\n typeof anyE.color === \"number\" &&\n ci !== 256 &&\n ci !== 0 &&\n ci !== undefined\n ? rgb24(anyE.color)\n : typeof ci === \"number\"\n ? aciToHex(ci) // undefined for 0/256 (inherit)\n : undefined;\n const resolved = lineTypeFromDxf(anyE.lineType, ctx);\n const lineType = resolved?.name;\n // Lineweight (370): an explicit value becomes the object's own width;\n // ByLayer / ByBlock / default inherit.\n const lineWidth = lineWeightToMm(\n ctx.tags.lineWeightByHandle.get(String(anyE.handle)),\n );\n // Group 48 (CELTSCALE). We render dashes width-proportionally while DXF\n // consumers render pattern × 48 — so divide by the width the entity will\n // resolve to (its own 370, else its layer's, else the 0.25 mm default) to\n // keep AutoCAD's dash lengths (export multiplies the width back in, so\n // round-trips are exact). A 2/X2 scale-variant LTYPE name multiplies on\n // top (the variant resolved to its base pattern). Only entities whose\n // effective line type dashes get the field stamped.\n const raw48 =\n typeof anyE.lineTypeScale === \"number\" && anyE.lineTypeScale > 0\n ? anyE.lineTypeScale\n : 1;\n const widthMm =\n lineWidth ?? ctx.layerWidthById.get(layerId) ?? IMPORT_LINE_WIDTH_MM;\n const scale = ((raw48 * ctx.ltScale) / widthMm) * (resolved?.factor ?? 1);\n const dashed = lineType !== undefined || ctx.dashedLayerIds.has(layerId);\n const lineTypeScale = dashed && scale !== 1 ? scale : undefined;\n return {\n layerId,\n color,\n lineType,\n lineTypeScale,\n ...(lineWidth !== undefined ? { lineWidth } : {}),\n hidden: false,\n };\n};\n\n/** Hatch boundary path (from the custom handler) → polyline loop points. */\nconst hatchLoopPoints = (\n path: any,\n f: number,\n mirrored: boolean,\n): PolylineVertex[] => {\n const points = hatchLoopPointsOcs(path, f);\n return mirrored\n ? points.map((p) => ({ x: -p.x, y: p.y, bulge: -p.bulge }))\n : points;\n};\n\n/** Max chord deviation (mm) when an ellipse edge is sampled into a loop. */\nconst HATCH_ELLIPSE_TOLERANCE_MM = 0.1;\n\nconst hatchLoopPointsOcs = (path: any, f: number): PolylineVertex[] => {\n if (path.isPolyline) {\n return (path.vertices ?? []).map((v: any) => ({\n x: v.x * f,\n y: v.y * f,\n bulge: v.bulge ?? 0,\n }));\n }\n // Edge form: edges are contiguous, so each contributes its START (and\n // interior samples) — the next edge's start is its end, and the loop\n // closes back to the first. Arcs contribute a bulge; ellipse and spline\n // edges are sampled within tolerance.\n const points: PolylineVertex[] = [];\n const push = (x: number, y: number, bulge = 0) =>\n points.push({ x: x * f, y: y * f, bulge });\n for (const edge of path.edges ?? []) {\n switch (edge.kind) {\n case 1: {\n // Line: 10 = start (11 = end, supplied by the next edge's start).\n const p = edge.points[0];\n if (p) push(p.x, p.y);\n break;\n }\n case 2: {\n // Arc: 10 center, 40 radius, 50/51 angles in degrees, 73 ccw. A\n // CLOCKWISE arc (73 = 0) has its angles measured clockwise — the\n // arc runs from −start to −end (AutoCAD's convention, verified on\n // its own files: the end meets the next edge's start). Sweeps past\n // 180° split in two so a full circle becomes two half-arcs.\n const c = edge.points[0];\n if (!c || !(edge.r40 > 0)) break;\n const ccw = edge.ccw !== false;\n const a0 = (edge.startAngle ?? 0) * DEG2RAD;\n let a1 = (edge.endAngle ?? 360) * DEG2RAD;\n if (a1 <= a0 + 1e-12) a1 += Math.PI * 2;\n const sweep = Math.min(a1 - a0, Math.PI * 2);\n const sign = ccw ? 1 : -1;\n const start = sign * a0;\n const pieces = sweep > Math.PI + 1e-9 ? 2 : 1;\n const bulge = sign * Math.tan(sweep / pieces / 4);\n for (let i = 0; i < pieces; i++) {\n const ang = start + (sign * sweep * i) / pieces;\n push(\n c.x + edge.r40 * Math.cos(ang),\n c.y + edge.r40 * Math.sin(ang),\n bulge,\n );\n }\n break;\n }\n case 3: {\n // Elliptic arc: 10 center, 11 major-axis endpoint relative to the\n // center, 40 minor/major ratio, 50/51 TRUE angles (degrees, from\n // the major axis — not ellipse parameters), 73 ccw with the same\n // negation rule as arcs. Sampled so the chord error stays under\n // tolerance for the major radius.\n const c = edge.points[0];\n const major = edge.end;\n if (!c || !major) break;\n const ratio = edge.r40 > 0 ? edge.r40 : 1;\n const ccw = edge.ccw !== false;\n const a0 = (edge.startAngle ?? 0) * DEG2RAD;\n let a1 = (edge.endAngle ?? 360) * DEG2RAD;\n if (a1 <= a0 + 1e-12) a1 += Math.PI * 2;\n const sweep = Math.min(a1 - a0, Math.PI * 2);\n const sign = ccw ? 1 : -1;\n const L = Math.hypot(major.x, major.y);\n const tol = HATCH_ELLIPSE_TOLERANCE_MM / f;\n const maxStep =\n L <= tol ? sweep : 2 * Math.acos(Math.max(-1, 1 - tol / L));\n const n = Math.max(8, Math.ceil(sweep / Math.max(maxStep, 1e-3)));\n for (let i = 0; i < n; i++) {\n const theta = sign * (a0 + (sweep * i) / n);\n // True angle (from the major axis) → ellipse parameter.\n const t = Math.atan2(Math.sin(theta) / ratio, Math.cos(theta));\n push(\n c.x + major.x * Math.cos(t) - major.y * ratio * Math.sin(t),\n c.y + major.y * Math.cos(t) + major.x * ratio * Math.sin(t),\n );\n }\n break;\n }\n case 4: {\n // Spline: the curve itself when the control data is complete, else\n // the cubic through its fit points, else the control polygon — the\n // same ladder as the SPLINE entity.\n const control: Vec2[] = (edge.points ?? []).map((p: any) => ({\n x: p.x,\n y: p.y,\n }));\n const weights: number[] = edge.weights ?? [];\n const curve: NurbsCurve = {\n degree: edge.degree ?? 3,\n controlPoints: control,\n knots: edge.knots ?? [],\n ...(edge.rational && weights.length === control.length\n ? { weights }\n : {}),\n };\n const fit: Vec2[] = (edge.fitPoints ?? []).map((p: any) => ({\n x: p.x,\n y: p.y,\n }));\n const fitted = isValidNurbs(curve) ? null : interpolateFitPoints(fit);\n const sampled = isValidNurbs(curve)\n ? sampleNurbs(curve, SPLINE_TOLERANCE_MM / f)\n : fitted\n ? sampleNurbs(fitted, SPLINE_TOLERANCE_MM / f)\n : fit.length >= 2\n ? fit\n : control;\n // All but the end point — the next edge starts there.\n for (const p of sampled.slice(0, -1)) push(p.x, p.y);\n break;\n }\n }\n }\n // Consecutive duplicates (a writer repeating a shared vertex) would add\n // zero-length segments.\n return points.filter(\n (p, i) =>\n i === 0 ||\n Math.abs(p.x - points[i - 1].x) > 1e-9 ||\n Math.abs(p.y - points[i - 1].y) > 1e-9 ||\n points[i - 1].bulge !== 0,\n );\n};\n\n/** A two-vertex loop whose segments bulge is a closed shape (a circle as two\n * half-arcs, a lens, a \"D\") — the model wants three vertices per loop, so\n * each bulged segment splits at its arc midpoint into two quarter-bulges.\n * Anything else with fewer than three vertices stays as is (and is dropped). */\nconst atLeastThreeVertices = (points: PolylineVertex[]): PolylineVertex[] => {\n if (points.length !== 2 || points.every((p) => p.bulge === 0)) return points;\n const out: PolylineVertex[] = [];\n for (let i = 0; i < 2; i++) {\n const a = points[i];\n const b = points[1 - i];\n out.push(a);\n const arc = a.bulge === 0 ? null : bulgeToArc(a, b, a.bulge);\n if (!arc) continue;\n const half = Math.tan(Math.atan(a.bulge) / 2); // tan(θ/8), θ = 4·atan(bulge)\n const mid = arcMidPoint(arc);\n out[out.length - 1] = { ...a, bulge: half };\n out.push({ x: mid.x, y: mid.y, bulge: half });\n }\n return out;\n};\n\nconst convertHatch = (e: IEntity, ctx: ImportContext): ModelObjectDto[] => {\n const anyE = e as any;\n const base = baseFor(e, ctx);\n const mirrored = ctx.tags.mirroredHandles.has(String(anyE.handle));\n const flip = mirrored ? -1 : 1; // pattern angles mirror with the OCS\n const loops = (anyE.boundaryPaths ?? [])\n .map((path: any) => ({\n points: atLeastThreeVertices(hatchLoopPoints(path, ctx.f, mirrored)),\n }))\n .filter((loop: { points: PolylineVertex[] }) => loop.points.length >= 3);\n if (loops.length === 0) return [];\n\n let fill:\n | { kind: \"solid\" }\n | { kind: \"lines\"; angle: number; spacing: number }\n | {\n kind: \"pattern\";\n name: string;\n angle: number;\n scale: number;\n origin?: Vec2;\n }\n | {\n kind: \"gradient\";\n shape: \"linear\" | \"radial\";\n color1: string;\n color2: string;\n angle: number;\n };\n const patternMatch =\n typeof anyE.patternName === \"string\"\n ? getHatchPattern(anyE.patternName)\n : undefined;\n const gradient = anyE.gradient;\n if (gradient) {\n // Two colors (or one color fading to its tint): spherical shapes are\n // our radial, every other AutoCAD shape reads as linear along 460.\n const colors: string[] = (gradient.colors ?? [])\n .map((c: { aci?: number; rgb?: number }) =>\n typeof c.rgb === \"number\"\n ? rgbToHex((c.rgb >> 16) & 0xff, (c.rgb >> 8) & 0xff, c.rgb & 0xff)\n : typeof c.aci === \"number\"\n ? aciToHex(c.aci)\n : undefined,\n )\n .filter((c: string | undefined): c is string => c !== undefined);\n const color1 = colors[0] ?? \"#808080\";\n const color2 =\n !gradient.oneColor && colors[1] !== undefined\n ? colors[1]\n : mixHex(color1, \"#ffffff\", gradient.tint ?? 1);\n fill = {\n kind: \"gradient\",\n shape: /spherical/i.test(gradient.name ?? \"\") ? \"radial\" : \"linear\",\n color1,\n color2,\n angle: (gradient.angle ?? 0) * flip,\n };\n } else if (anyE.solid || anyE.patternName === \"SOLID\") {\n fill = { kind: \"solid\" };\n } else if (patternMatch) {\n // A recognized built-in pattern (including ANSI31) → carry it losslessly as\n // a named pattern fill. The DXF pattern angle (code 52) and scale (code 41)\n // are the pattern's rotation/scale, matching the export mapping.\n const angle52 = (anyE.patternAngle ?? 0) * DEG2RAD;\n const scaleMm = (anyE.patternScale || 1) * ctx.f;\n fill = {\n kind: \"pattern\",\n name: patternMatch.name,\n angle: angle52 * flip,\n scale: scaleMm,\n };\n // The hatch's own origin (HPORIGIN) is folded into the baked 43/44 of\n // every definition line: the first line's base, less the catalogue\n // line's own origin baked the same way, is the fill's anchor.\n const first = anyE.patternLines?.[0];\n if (first && !mirrored) {\n const lineAngle = (first.angle ?? 0) * DEG2RAD - angle52;\n const own = patternMatch.lines.reduce<\n (typeof patternMatch.lines)[number] | null\n >(\n (best, l) =>\n best === null ||\n Math.abs(lineAngleDiff(l.angle, lineAngle)) <\n Math.abs(lineAngleDiff(best.angle, lineAngle))\n ? l\n : best,\n null,\n )?.origin ?? { x: 0, y: 0 };\n const cos = Math.cos(angle52);\n const sin = Math.sin(angle52);\n const anchor = {\n x: (first.baseX ?? 0) * ctx.f - (cos * own.x - sin * own.y) * scaleMm,\n y: (first.baseY ?? 0) * ctx.f - (sin * own.x + cos * own.y) * scaleMm,\n };\n if (Math.hypot(anchor.x, anchor.y) > 1e-6)\n fill = { ...fill, origin: anchor };\n }\n } else if (\n !anyE.solid &&\n typeof anyE.patternName === \"string\" &&\n anyE.patternName.trim() &&\n (anyE.patternLines?.length ?? 0) > 0 &&\n !mirrored\n ) {\n // A pattern the catalogue lacks: the HATCH carries its definition lines\n // — already rotated by 52 and scaled by 41 — so un-bake them into a\n // document pattern (mm) that this and every later hatch of the name\n // references by name (first definition wins). Frames: 43/44 (origin)\n // and 45/46 (the step between successive lines) are vectors in the\n // hatch's frame; the .pat model (ours) gives the step RELATIVE TO THE\n // LINE — deltaX along it (dash phase), deltaY across it (spacing). The\n // baked line angle (53) already includes 52.\n const name = anyE.patternName.trim();\n const key = hatchPatternKey(name);\n const angle52 = (anyE.patternAngle ?? 0) * DEG2RAD;\n const scale41: number = anyE.patternScale > 0 ? anyE.patternScale : 1;\n // The HATCH's own origin (HPORIGIN — a block's hatch anchors to the\n // block) is folded into every line's 43/44. The definition is taken\n // with its first line at the .pat origin, and the common offset\n // becomes the fill's `origin`, so the same pattern drawn at different\n // anchors stays ONE definition.\n let anchor: Vec2 | undefined;\n {\n const cos = Math.cos(-angle52);\n const sin = Math.sin(-angle52);\n const unrot = (x: number, y: number) => ({\n x: ((cos * x - sin * y) / scale41) * ctx.f,\n y: ((sin * x + cos * y) / scale41) * ctx.f,\n });\n const first = anyE.patternLines[0];\n const shift = unrot(first.baseX ?? 0, first.baseY ?? 0);\n if (Math.hypot(shift.x, shift.y) > 1e-9)\n anchor = {\n x:\n (Math.cos(angle52) * shift.x - Math.sin(angle52) * shift.y) *\n scale41,\n y:\n (Math.sin(angle52) * shift.x + Math.cos(angle52) * shift.y) *\n scale41,\n };\n const lines = (anyE.patternLines as any[])\n .map((l) => {\n const o = unrot(l.baseX ?? 0, l.baseY ?? 0);\n const origin = { x: o.x - shift.x, y: o.y - shift.y };\n const baked = (l.angle ?? 0) * DEG2RAD;\n const c = Math.cos(-baked);\n const sn = Math.sin(-baked);\n const ox = l.offsetX ?? 0;\n const oy = l.offsetY ?? 0;\n let delta = {\n x: ((c * ox - sn * oy) / scale41) * ctx.f,\n y: ((sn * ox + c * oy) / scale41) * ctx.f,\n };\n // A negative perpendicular spacing describes the same family\n // from the other side.\n if (delta.y < 0) delta = { x: -delta.x, y: -delta.y };\n const dashes: number[] | undefined = Array.isArray(l.dashes)\n ? l.dashes.map((d: number) => (d / scale41) * ctx.f)\n : undefined;\n return {\n angle: (l.angle ?? 0) * DEG2RAD - angle52,\n origin,\n deltaX: delta.x,\n deltaY: delta.y,\n ...(dashes && dashes.length > 0 ? { dashesMm: dashes } : {}),\n };\n })\n .filter((l) => l.deltaY > 1e-9);\n if (lines.length > 0 && !ctx.hatchPatterns.has(key))\n ctx.hatchPatterns.set(key, { name, lines });\n }\n const own = ctx.hatchPatterns.get(key);\n if (own) {\n fill = {\n kind: \"pattern\",\n name: own.name,\n angle: angle52 * flip,\n scale: scale41,\n ...(anchor ? { origin: anchor } : {}),\n };\n } else {\n bump(ctx.degraded, \"HATCH→lines\");\n const line = anyE.patternLines?.[0];\n const offset = line\n ? Math.hypot(line.offsetX ?? 0, line.offsetY ?? 0)\n : 0;\n fill = {\n kind: \"lines\",\n angle: (line?.angle ?? anyE.patternAngle ?? 45) * DEG2RAD * flip,\n spacing: (offset > 0 ? offset : 3) * ctx.f,\n };\n }\n } else {\n // Generic pattern: approximate with the first definition line family.\n bump(ctx.degraded, \"HATCH→lines\");\n const line = anyE.patternLines?.[0];\n const offset = line ? Math.hypot(line.offsetX ?? 0, line.offsetY ?? 0) : 0;\n fill = {\n kind: \"lines\",\n angle: (line?.angle ?? anyE.patternAngle ?? 45) * DEG2RAD * flip,\n spacing: (offset > 0 ? offset : 3) * ctx.f,\n };\n }\n return [{ type: \"hatch\", loops, fill, scale: 1, ...base }];\n};\n\n/** Difference between two UNDIRECTED line angles, in (−π/2, π/2]. */\nconst lineAngleDiff = (a: number, b: number): number => {\n const d = (((a - b) % Math.PI) + Math.PI * 1.5) % Math.PI;\n return d > Math.PI / 2 ? d - Math.PI : d;\n};\n\n/** Linear blend of two hex colors, t = 0 → a, 1 → b. */\nconst mixHex = (a: string, b: string, t: number): string => {\n const ra = hexToRgb(a);\n const rb = hexToRgb(b);\n if (!ra || !rb) return a;\n const k = Math.max(0, Math.min(1, t));\n return rgbToHex(\n Math.round(ra[0] + (rb[0] - ra[0]) * k),\n Math.round(ra[1] + (rb[1] - ra[1]) * k),\n Math.round(ra[2] + (rb[2] - ra[2]) * k),\n );\n};\n\n/** Text placement past a leader's last point (mirror of the painter). */\nconst leaderTextPlacement = (\n line: Vec2[],\n height: number,\n): { position: Vec2; hAlign: \"left\" | \"right\" } => {\n const last = line[line.length - 1];\n const prev = line[line.length - 2] ?? last;\n const rightward = last.x - prev.x >= 0;\n const gap = height * 0.6;\n return {\n position: { x: last.x + (rightward ? gap : -gap), y: last.y },\n // Justification: text right of the leader starts at its point.\n hAlign: rightward ? \"left\" : \"right\",\n };\n};\n\n/**\n * The dimension style an entity's group 3 names (DIMENSION, LEADER): the\n * merged document style + its DIMSCALE, or the document default + the\n * header's $DIMSCALE when the file defines no such style.\n */\nconst dimStyleOf = (\n e: IEntity,\n ctx: ImportContext,\n): { id?: string; style: DimStyle; scale: number } => {\n const name = ctx.tags.dimStyleNameByHandle.get(String((e as any).handle));\n const id = name ? ctx.dimStyleIdByName.get(name.toLowerCase()) : undefined;\n const style = id ? ctx.dimStyleById.get(id) : undefined;\n if (id && style)\n return { id, style, scale: ctx.dimScaleByStyleId.get(id) ?? 1 };\n return { style: ctx.defaultDimStyle, scale: ctx.dimScale };\n};\n\n/**\n * `styleId` / `styleOverride` / `scale` for a converted dimension: the named\n * style, its DSTYLE xdata as a sparse override (only keys that differ from\n * the style), and the style's DIMSCALE as the object's scale.\n */\nconst dimStyleRef = (\n e: IEntity,\n ctx: ImportContext,\n): Partial<\n Pick<\n Extract<ModelObjectDto, { type: \"dimension\" }>,\n \"styleId\" | \"styleOverride\" | \"scale\"\n >\n> => {\n const { id, style, scale } = dimStyleOf(e, ctx);\n const xdata = ctx.tags.dimOverridesByHandle.get(String((e as any).handle));\n const { scale: ownScale, ...values } = xdata ? ctx.dimValuesFrom(xdata) : {};\n const override = overrideAgainst(style, values);\n const effScale = ownScale ?? scale;\n return {\n ...(id ? { styleId: id } : {}),\n ...(Object.keys(override).length > 0 ? { styleOverride: override } : {}),\n ...(effScale !== 1 ? { scale: effScale } : {}),\n };\n};\n\n/**\n * `styleId` / `styleOverride` for a converted text: the style its group 7\n * names (absent = the file's \"Standard\", like AutoCAD) and, as a sparse\n * override, only the explicit entity values that differ from it. Heights\n * and sizes are mm; `widthFactor` undefined = inherit.\n */\nconst textStyleRef = (\n e: IEntity,\n ctx: ImportContext,\n values: {\n textHeight: number;\n widthFactor?: number;\n bold?: true;\n italic?: true;\n font?: string;\n arrowSize?: number;\n arrowType?: TextStyle[\"arrowType\"];\n },\n): Pick<\n Extract<ModelObjectDto, { type: \"text\" }>,\n \"styleId\" | \"styleOverride\"\n> => {\n const name =\n ctx.tags.textStyleNameByHandle.get(String((e as any).handle)) ?? \"Standard\";\n const id = ctx.textStyleIdByName.get(name.toLowerCase());\n const style = (id && ctx.textStyleById.get(id)) || ctx.defaultTextStyle;\n const override = overrideAgainst(style, values);\n return {\n ...(id ? { styleId: id } : {}),\n ...(Object.keys(override).length > 0 ? { styleOverride: override } : {}),\n };\n};\n\nconst convertLeader = (e: IEntity, ctx: ImportContext): ModelObjectDto[] => {\n const anyE = e as any;\n const points: Vec2[] = (anyE.vertices ?? []).map((p: any) => pt(p, ctx.f));\n if (points.length < 2) return [];\n // The leader's DIMSTYLE sizes its text gap and arrowhead (× DIMSCALE).\n const { style, scale } = dimStyleOf(e, ctx);\n const placement = leaderTextPlacement(points, style.textHeight * scale);\n return [\n {\n type: \"text\",\n position: placement.position,\n content: \"\", // LEADER's annotation is a separate entity\n rotation: 0,\n hAlign: placement.hAlign,\n vAlign: \"center\",\n leaderLines: [points],\n // The dim style's DIMTXT/DIMASZ are explicit — overrides against the\n // TEXT style this note follows, so it renders as the source did.\n ...textStyleRef(e, ctx, {\n textHeight: style.textHeight * scale,\n arrowSize: style.arrowSize * scale,\n arrowType: style.arrowType,\n }),\n scale: 1,\n ...baseFor(e, ctx),\n },\n ];\n};\n\nconst convertMultiLeader = (\n e: IEntity,\n ctx: ImportContext,\n): ModelObjectDto[] => {\n const anyE = e as any;\n const f = ctx.f;\n // Rebuild full lines: each LEADER_LINE's vertices + its LEADER's junction.\n const lines: Vec2[][] = [];\n for (const leader of anyE.leaders ?? []) {\n for (const raw of leader.lines ?? []) {\n const points: Vec2[] = raw.map((p: any) => pt(p, f));\n if (leader.junction) points.push(pt(leader.junction, f));\n if (points.length >= 2) lines.push(points);\n }\n }\n if (lines.length === 0) return [];\n // CONTEXT_DATA sizes are FINAL (already multiplied by the overall scale);\n // un-bake them so height/arrowSize stay base values, like our model's.\n const overall = anyE.overallScale > 0 ? anyE.overallScale : 1;\n const height =\n (anyE.textHeight > 0\n ? anyE.textHeight / overall\n : ctx.defaultDimStyle.textHeight) * f;\n const fallback = leaderTextPlacement(lines[0], height * overall);\n const position = anyE.textLocation\n ? pt(anyE.textLocation, f)\n : fallback.position;\n const junction = lines[0][lines[0].length - 1];\n // Text attachment point 1–9 (TL TC TR / ML MC MR / BL BC BR) when the\n // context carries one; else the note sits on the far side of its leader.\n const ap =\n typeof anyE.attachment === \"number\" &&\n anyE.attachment >= 1 &&\n anyE.attachment <= 9\n ? anyE.attachment\n : undefined;\n return [\n {\n type: \"text\",\n position,\n content: cleanText(String(anyE.content ?? \"\"), true),\n rotation: 0,\n hAlign:\n ap !== undefined\n ? ([\"left\", \"center\", \"right\"] as const)[(ap - 1) % 3]\n : position.x >= junction.x\n ? \"left\"\n : \"right\",\n vAlign:\n ap !== undefined\n ? ap <= 3\n ? \"top\"\n : ap <= 6\n ? \"center\"\n : \"bottom\"\n : \"center\",\n leaderLines: lines,\n ...textStyleRef(e, ctx, {\n textHeight: height,\n arrowSize:\n (anyE.arrowSize > 0\n ? anyE.arrowSize / overall\n : ctx.defaultDimStyle.arrowSize) * f,\n }),\n // MLEADER's overall scale is a unitless multiplier, like ours.\n scale: overall,\n ...baseFor(e, ctx),\n },\n ];\n};\n\n// DXF dimensions arrive in the legacy linePoint/rotation shape; the shared\n// converters (also used by the migrations and block-script DTOs) turn them\n// into the current form — projecting axis-locked linear dims onto their\n// measuring axis, then the v21 scalars + labels.\nconst legacyDim = (raw: Record<string, unknown>): ModelObjectDto[] => [\n dimensionRawToLabels(dimensionRawToOffset(raw)) as unknown as ModelObjectDto,\n];\n\nconst convertDimension = (\n e: IEntity,\n dxf: IDxf,\n ctx: ImportContext,\n): ModelObjectDto[] => {\n const anyE = e as any;\n const kind = (anyE.dimensionType ?? 0) & 7;\n // The dimension's named style, its xdata overrides, and its DIMSCALE.\n const styleScale = dimStyleRef(e, ctx);\n const p1 = anyE.linearOrAngularPoint1;\n const p2 = anyE.linearOrAngularPoint2;\n const line = anyE.anchorPoint;\n\n if ((kind === 0 || kind === 1) && p1 && p2 && line) {\n const points = [pt(p1, ctx.f), pt(p2, ctx.f)];\n // Group 1 usually just repeats the measured value — keep it only when it\n // genuinely overrides (so re-imported dimensions stay live).\n const raw = typeof anyE.text === \"string\" ? anyE.text.trim() : \"\";\n const rotation = (anyE.angle ?? 0) * DEG2RAD;\n // Linear dims measure the projection onto the rotation axis.\n const measured =\n kind === 0\n ? Math.abs(\n (points[1].x - points[0].x) * Math.cos(rotation) +\n (points[1].y - points[0].y) * Math.sin(rotation),\n )\n : dist(points[0], points[1]);\n const asNumber = Number(raw.replace(\",\", \".\"));\n const isComputed =\n raw === \"\" ||\n raw === \"<>\" ||\n (Number.isFinite(asNumber) &&\n measured > 0 &&\n Math.abs(asNumber * ctx.f - measured) / measured < 0.01);\n return legacyDim({\n type: \"dimension\",\n ...styleScale,\n kind: kind === 0 ? \"linear\" : \"aligned\",\n points,\n linePoint: pt(line, ctx.f),\n rotation: kind === 0 ? rotation : 0,\n ...(isComputed ? {} : { textOverride: decodeTextEscapes(raw) }),\n ...baseFor(e, ctx),\n });\n }\n\n // Diameter (3): 10 and 15 are opposite points on the curve.\n if (kind === 3 && line && anyE.diameterOrRadiusPoint) {\n const a = pt(anyE.diameterOrRadiusPoint, ctx.f);\n const b = pt(line, ctx.f);\n return legacyDim({\n type: \"dimension\",\n ...styleScale,\n kind: \"diameter\",\n points: [a, b],\n linePoint: anyE.middleOfText\n ? pt(anyE.middleOfText, ctx.f)\n : { x: (a.x + b.x) / 2, y: (a.y + b.y) / 2 },\n ...baseFor(e, ctx),\n });\n }\n\n // Radial (4): 10 = center, 15 = point on the curve.\n if (kind === 4 && line && anyE.diameterOrRadiusPoint) {\n const center = pt(line, ctx.f);\n const p = pt(anyE.diameterOrRadiusPoint, ctx.f);\n return legacyDim({\n type: \"dimension\",\n ...styleScale,\n kind: \"radial\",\n points: [center, p],\n linePoint: anyE.middleOfText ? pt(anyE.middleOfText, ctx.f) : p,\n ...baseFor(e, ctx),\n });\n }\n\n // Angular 3-point (5): 15 = vertex, 13/14 = ray points, 10 = arc position.\n if (kind === 5 && p1 && p2 && line && anyE.diameterOrRadiusPoint) {\n return legacyDim({\n type: \"dimension\",\n ...styleScale,\n kind: \"angular\",\n points: [\n pt(anyE.diameterOrRadiusPoint, ctx.f),\n pt(p1, ctx.f),\n pt(p2, ctx.f),\n ],\n linePoint: pt(line, ctx.f),\n ...baseFor(e, ctx),\n });\n }\n\n // Two-line angular/ordinate/etc.: fall back to the dimension's rendered\n // geometry block (already in world coordinates).\n const block = anyE.block ? dxf.blocks?.[anyE.block] : undefined;\n if (!block?.entities) return [];\n const result: ModelObjectDto[] = [];\n for (const child of block.entities)\n result.push(...convertEntity(child, dxf, ctx));\n if (result.length > 0) bump(ctx.degraded, \"DIMENSION→exploded\");\n return result;\n};\n\n/**\n * Ledger bookkeeping (rule R8) around a converter: a hidden entity → skipped\n * \"hidden\", nothing produced → skipped by type, something produced →\n * imported unless the converter marked this type degraded. Wraps the\n * recursive paths too, so block children are counted.\n */\nconst account = (\n e: IEntity,\n ctx: ImportContext,\n convert: () => ModelObjectDto[],\n): ModelObjectDto[] => {\n ctx.seen.add(e.type);\n // Entities AutoCAD hides (group 60 = 1) — chiefly the inactive\n // visibility-state geometry inside dynamic blocks, which would otherwise\n // all render on top of each other.\n // Also hidden: an attribute with the invisible bit (70 & 1), and a\n // non-constant ATTDEF — the block's attribute DEFINITION, which AutoCAD\n // never draws; the INSERT's ATTRIBs carry the values. Constant ATTDEFs\n // have no ATTRIB and are drawn from the definition.\n const anyE = e as any;\n if (\n anyE.visible === false ||\n anyE.invisible === true ||\n (e.type === \"ATTDEF\" && anyE.constant !== true)\n ) {\n bump(ctx.skipped, `${e.type} (hidden)`);\n return [];\n }\n const ownDegraded = () => {\n let n = 0;\n for (const [k, v] of ctx.degraded) if (k.startsWith(e.type + \"→\")) n += v;\n return n;\n };\n const before = ownDegraded();\n const skippedBefore = total(ctx.skipped);\n const out = convert();\n // A converter that recorded its own skip reason is not double-counted.\n if (out.length === 0) {\n if (total(ctx.skipped) === skippedBefore) bump(ctx.skipped, e.type);\n } else if (ownDegraded() === before) bump(ctx.imported, e.type);\n return out;\n};\n\n/**\n * THE entity entry point — model space, paper space, block children and a\n * dimension's geometry block all convert through it, so ledger accounting\n * (hidden entities included), native tables and xrefs behave the same in\n * every context. `depth` > 0 is a block child (`inheritedColor` its ByBlock\n * color — see convertInsertInner). An xref becomes a reference only at the\n * top of a space: inside a block it is block geometry, which a reference\n * can't be, and its content is not in this file anyway.\n */\nconst convertEntity = (\n e: IEntity,\n dxf: IDxf,\n ctx: ImportContext,\n depth = 0,\n inheritedColor?: string,\n): ModelObjectDto[] =>\n account(e, ctx, () => {\n // ACAD_TABLE is INSERT-shaped: native when its payload is complete,\n // else its anonymous *T block explodes like any insert.\n const table = e.type === \"ACAD_TABLE\" ? convertAcadTable(e, ctx) : null;\n if (table) return [table];\n const ref =\n e.type === \"INSERT\" && depth === 0 ? xrefReference(e, dxf, ctx) : null;\n if (ref) return [ref];\n if (e.type === \"INSERT\" || e.type === \"ACAD_TABLE\")\n return convertInsertInner(e, dxf, ctx, depth, inheritedColor);\n return convertEntityInner(e, dxf, ctx);\n });\n\n/**\n * MLINE → one polyline per style element (counted degraded: the multiline\n * structure is lost, the drawn lines are not). Element points come from the\n * entity's own miter parameters (MlineHandler); a vertex without them falls\n * back to the style offsets × scale along the miter, shifted by the\n * justification (0 top = largest offset on the path, 1 zero, 2 bottom).\n * Square end caps (style 70 bits 16 / 256, unless the entity suppresses\n * them with 71 bits 4 / 8) close the outer elements with a line.\n */\nconst convertMline = (e: IEntity, ctx: ImportContext): ModelObjectDto[] => {\n const anyE = e as any;\n const base = baseFor(e, ctx);\n const f = ctx.f;\n const style: DxfMlineStyle | undefined =\n (anyE.styleHandle && anyE.styleHandle !== \"0\"\n ? ctx.mlineStyles.byHandle.get(anyE.styleHandle)\n : undefined) ??\n ctx.mlineStyles.byName.get(String(anyE.styleName ?? \"\").toLowerCase());\n const vertices: {\n point: { x: number; y: number };\n miter?: { x: number; y: number };\n direction?: { x: number; y: number };\n elements: { params: number[] }[];\n }[] = anyE.vertices ?? [];\n if (vertices.length < 2) return [];\n const count: number = Math.max(\n anyE.elementCount ?? 0,\n style?.elements.length ?? 0,\n ...vertices.map((v) => v.elements.length),\n );\n if (count === 0) return [];\n const scale: number = anyE.scale > 0 ? anyE.scale : 1;\n const offsets = style?.elements.map((el) => el.offset) ?? [];\n const ref =\n offsets.length === 0\n ? 0\n : anyE.justification === 0\n ? Math.max(...offsets)\n : anyE.justification === 2\n ? Math.min(...offsets)\n : 0;\n const miterAt = (v: (typeof vertices)[number]): Vec2 => {\n if (v.miter && (v.miter.x !== 0 || v.miter.y !== 0)) {\n const len = Math.hypot(v.miter.x, v.miter.y);\n return { x: v.miter.x / len, y: v.miter.y / len };\n }\n const d = v.direction ?? { x: 1, y: 0 };\n const len = Math.hypot(d.x, d.y) || 1;\n return { x: -d.y / len, y: d.x / len }; // left of the direction\n };\n const elementPoint = (v: (typeof vertices)[number], i: number): Vec2 => {\n const param = v.elements[i]?.params[0];\n const distance =\n param !== undefined ? param : ((offsets[i] ?? 0) - ref) * scale;\n const m = miterAt(v);\n return {\n x: (v.point.x + m.x * distance) * f,\n y: (v.point.y + m.y * distance) * f,\n };\n };\n const closed = ((anyE.flags ?? 0) & 2) !== 0;\n const out: ModelObjectDto[] = [];\n const firstPts: Vec2[] = [];\n const lastPts: Vec2[] = [];\n for (let i = 0; i < count; i++) {\n const points = vertices.map((v) => elementPoint(v, i));\n firstPts.push(points[0]);\n lastPts.push(points[points.length - 1]);\n const el = style?.elements[i];\n const color =\n el?.colorIndex !== undefined &&\n el.colorIndex !== 256 &&\n el.colorIndex !== 0\n ? aciToHex(el.colorIndex)\n : undefined;\n const lineType = lineTypeFromDxf(el?.lineType, ctx)?.name;\n out.push({\n type: \"polyline\",\n points: points.map((p) => ({ ...p, bulge: 0 })),\n closed,\n ...base,\n ...(color ? { color } : {}),\n ...(lineType ? { lineType } : {}),\n });\n }\n // Square caps join the two outermost elements at the open ends.\n if (!closed && count >= 2 && style) {\n const outer = (pts: Vec2[], v: (typeof vertices)[number]) => {\n const m = miterAt(v);\n const along = pts.map((p) => p.x * m.x + p.y * m.y);\n const lo = along.indexOf(Math.min(...along));\n const hi = along.indexOf(Math.max(...along));\n return lo === hi ? null : ([pts[lo], pts[hi]] as const);\n };\n const flags: number = anyE.flags ?? 0;\n if ((style.flags & 16) !== 0 && (flags & 4) === 0) {\n const cap = outer(firstPts, vertices[0]);\n if (cap) out.push({ type: \"line\", a: cap[0], b: cap[1], ...base });\n }\n if ((style.flags & 256) !== 0 && (flags & 8) === 0) {\n const cap = outer(lastPts, vertices[vertices.length - 1]);\n if (cap) out.push({ type: \"line\", a: cap[0], b: cap[1], ...base });\n }\n }\n if (out.length > 0) bump(ctx.degraded, \"MLINE→polylines\");\n return out;\n};\n\nconst convertEntityInner = (\n e: IEntity,\n dxf: IDxf,\n ctx: ImportContext,\n): ModelObjectDto[] => {\n const anyE = e as any;\n const f = ctx.f;\n const base = baseFor(e, ctx);\n // Extrusion (0,0,−1): by the arbitrary axis algorithm the entity's OCS is\n // the world mirrored about the Y axis — x flips, angles mirror (θ → π−θ,\n // sweep direction reverses), bulges change sign. AutoCAD's MIRROR writes\n // this routinely for arcs, circles, polylines, inserts and text; LINE,\n // POINT, SPLINE and ELLIPSE coordinates are world coordinates already.\n const mirrored = ctx.tags.mirroredHandles.has(String(anyE.handle));\n const ocs = (p: { x: number; y: number }): Vec2 =>\n mirrored ? { x: -p.x * f, y: p.y * f } : pt(p, f);\n const ocsAngle = (a: number): number => (mirrored ? Math.PI - a : a);\n\n switch (e.type) {\n case \"LINE\": {\n const [a, b] = anyE.vertices;\n if (!a || !b) return [];\n return [{ type: \"line\", a: pt(a, f), b: pt(b, f), ...base }];\n }\n case \"POINT\": {\n if (!anyE.position) return [];\n return [{ type: \"point\", p: pt(anyE.position, f), ...base }];\n }\n case \"LWPOLYLINE\":\n case \"POLYLINE\": {\n const vertices: PolylineVertex[] = (anyE.vertices ?? []).map(\n (v: any) => ({\n ...ocs(v),\n bulge: mirrored ? -(v.bulge ?? 0) : (v.bulge ?? 0),\n }),\n );\n if (vertices.length < 2) return [];\n // Width: LWPOLYLINE 43 (constant), or per-vertex 40/41. AutoCAD draws\n // a wide polyline as a filled band in drawing units — so does the\n // import (a solid hatch, geometry/band.ts) when the width is constant\n // and the path has no bulges; a tapered or bulged wide polyline stays\n // a thin polyline, counted.\n const widths: number[] = [];\n if (typeof anyE.width === \"number\" && anyE.width > 0)\n widths.push(anyE.width);\n for (const v of anyE.vertices ?? [])\n for (const w of [v.startWidth, v.endWidth])\n if (typeof w === \"number\" && w > 0) widths.push(w);\n const closed = anyE.shape === true;\n if (widths.length > 0) {\n const constant = widths.every((w) => Math.abs(w - widths[0]) < 1e-9);\n const straight = vertices.every((v) => v.bulge === 0);\n const loops =\n constant && straight\n ? polylineBand(vertices, widths[0] * f, closed)\n : null;\n if (loops && loops.every((l) => l.length >= 3)) {\n bump(ctx.degraded, `${e.type} (width)→hatch`);\n return [\n {\n type: \"hatch\",\n loops: loops.map((l) => ({\n points: l.map((p) => ({ ...p, bulge: 0 })),\n })),\n fill: { kind: \"solid\" },\n scale: 1,\n ...base,\n },\n ];\n }\n bump(ctx.degraded, `${e.type} (width)→thin`);\n }\n return [{ type: \"polyline\", points: vertices, closed, ...base }];\n }\n case \"CIRCLE\": {\n const radius = anyE.radius * f;\n if (!(radius > 0)) return []; // zero/negative/NaN radius\n return [\n {\n type: \"circle\",\n center: ocs(anyE.center),\n radius,\n ...base,\n },\n ];\n }\n case \"ARC\": {\n const radius = anyE.radius * f;\n if (!(radius > 0)) return [];\n // dxf-parser converts arc angles to radians.\n return [\n {\n type: \"arc\",\n center: ocs(anyE.center),\n radius,\n // A mirrored arc runs CCW from the mirror of its end to the mirror\n // of its start.\n startAngle: mirrored ? ocsAngle(anyE.endAngle) : anyE.startAngle,\n endAngle: mirrored ? ocsAngle(anyE.startAngle) : anyE.endAngle,\n ...base,\n },\n ];\n }\n case \"ELLIPSE\": {\n const ratio = Math.min(Math.max(anyE.axisRatio, 1e-3), 1);\n // Center and major axis are world coordinates; only the minor axis\n // (normal × major) flips with a downward normal, so the parameter\n // runs the other way: a partial ellipse from u0 to u1 becomes one\n // from −u1 to −u0.\n const u0 = anyE.startAngle ?? 0;\n const u1 = anyE.endAngle ?? Math.PI * 2;\n const full = u1 - u0 >= Math.PI * 2 - 1e-9;\n const wrap = (a: number) =>\n ((a % (Math.PI * 2)) + Math.PI * 2) % (Math.PI * 2);\n return [\n {\n type: \"ellipse\",\n center: pt(anyE.center, f),\n majorAxis: pt(anyE.majorAxisEndPoint, f), // relative vector\n ratio,\n startAngle: mirrored && !full ? wrap(-u1) : u0,\n endAngle: mirrored && !full ? wrap(-u0) : u1,\n ...base,\n },\n ];\n }\n case \"TEXT\":\n case \"ATTRIB\":\n case \"ATTDEF\": {\n // ATTRIB (our handler) uses TEXT's field names; dxf-parser's ATTDEF\n // names the same groups differently.\n const halign = anyE.halign ?? anyE.horizontalJustification ?? 0;\n const valign = anyE.valign ?? anyE.verticalJustification ?? 0;\n const widthFactor = anyE.xScale ?? anyE.scale;\n // With a non-default alignment the anchor is the SECOND alignment\n // point (codes 11/21). \"Aligned\" (3) and \"fit\" (5) stretch between\n // both points — approximated as plain left/baseline at the first.\n const usesSecondPoint =\n (halign !== 0 && halign !== 3 && halign !== 5) || valign !== 0;\n const anchor =\n usesSecondPoint && anyE.endPoint ? anyE.endPoint : anyE.startPoint;\n // DXF justification = the model's alignment (which edge sits on the\n // point).\n const hAlign =\n halign === 1 || halign === 4\n ? \"center\"\n : halign === 2\n ? \"right\"\n : \"left\";\n // valign: 0 baseline, 1 bottom, 2 middle, 3 top; halign 4 = \"middle\"\n // centers both axes. Baseline maps to bottom (closest anchor we have).\n const vAlign =\n valign === 3\n ? \"top\"\n : valign === 2 || halign === 4\n ? \"center\"\n : \"bottom\";\n return [\n {\n type: \"text\",\n position: ocs(anchor),\n content: cleanText(anyE.text ?? \"\", false),\n rotation: ocsAngle((anyE.rotation ?? 0) * DEG2RAD),\n hAlign,\n vAlign,\n leaderLines: [],\n scale: 1,\n // Style (7) + the entity's own explicit height (40) and width\n // factor (41 — stored per TEXT, default 1) as overrides only\n // where they differ from the style.\n ...textStyleRef(e, ctx, {\n textHeight: (anyE.textHeight > 0 ? anyE.textHeight : 2.5) * f,\n widthFactor:\n typeof widthFactor === \"number\" && widthFactor > 0\n ? widthFactor\n : 1,\n }),\n ...base,\n },\n ];\n }\n case \"MTEXT\": {\n // Attachment point 1–9: TL TC TR / ML MC MR / BL BC BR.\n const ap = anyE.attachmentPoint ?? 1;\n const hAlign = ([\"left\", \"center\", \"right\"] as const)[(ap - 1) % 3];\n const vAlign = ap <= 3 ? \"top\" : ap <= 6 ? \"center\" : \"bottom\";\n // Rotation comes as a degree angle (50) or an X-axis direction\n // vector (11); the vector wins when present.\n const dv = anyE.directionVector;\n const rotation = ocsAngle(\n dv && (dv.x !== 0 || dv.y !== 0)\n ? Math.atan2(dv.y, dv.x)\n : (anyE.rotation ?? 0) * DEG2RAD,\n );\n // Inline formatting → spans (\\H heights relative to the entity's).\n const rich = cleanRichText(\n anyE.text ?? \"\",\n anyE.height > 0 ? anyE.height : 2.5,\n );\n return [\n {\n type: \"text\",\n position: ocs(anyE.position),\n content: rich.content,\n ...(rich.spans.length ? { spans: rich.spans } : {}),\n rotation,\n hAlign,\n vAlign,\n leaderLines: [],\n scale: 1,\n // MTEXT reference rectangle width (group 41) → wrap width.\n ...(anyE.width > 0 ? { width: anyE.width * f } : {}),\n // Style (7) + the explicit height and the inline \\W / \\f codes\n // (cleanText strips them) as overrides where they differ.\n ...textStyleRef(e, ctx, {\n textHeight: (anyE.height > 0 ? anyE.height : 2.5) * f,\n widthFactor: mtextWidthFactor(anyE.text ?? \"\"),\n ...mtextFontFlags(anyE.text ?? \"\"),\n }),\n ...base,\n },\n ];\n }\n case \"MLINE\":\n return convertMline(e, ctx);\n case \"SPLINE\": {\n // The curve itself, sampled within SPLINE_TOLERANCE_MM, when the\n // control data is complete (degree, n + p + 1 knots, optional\n // weights from the raw scan); else the fit points (on the curve,\n // sparse), else the control polygon.\n const control: any[] = anyE.controlPoints ?? [];\n const weights = ctx.tags.splineWeightsByHandle.get(String(anyE.handle));\n const curve: NurbsCurve = {\n degree: anyE.degreeOfSplineCurve ?? 3,\n controlPoints: control.map((p) => ({ x: p.x, y: p.y })),\n knots: anyE.knotValues ?? [],\n ...(weights && weights.length === control.length ? { weights } : {}),\n };\n // Fit-point splines (a DWG transcode keeps only those): the cubic\n // THROUGH the points, sampled the same way.\n const fit: any[] = anyE.fitPoints ?? [];\n const fitted = isValidNurbs(curve)\n ? null\n : interpolateFitPoints(fit.map((p) => ({ x: p.x, y: p.y })));\n let points: Vec2[];\n if (isValidNurbs(curve)) {\n points = sampleNurbs(curve, SPLINE_TOLERANCE_MM / f);\n bump(ctx.degraded, \"SPLINE→polyline\");\n } else if (fitted) {\n points = sampleNurbs(fitted, SPLINE_TOLERANCE_MM / f);\n bump(ctx.degraded, \"SPLINE→polyline (fit points)\");\n } else {\n const raw: any[] = fit.length >= 2 ? fit : control;\n if (raw.length < 2) return [];\n points = raw.map((p) => ({ x: p.x, y: p.y }));\n bump(ctx.degraded, \"SPLINE→polyline (control points)\");\n }\n if (points.length < 2) return [];\n return [\n {\n type: \"polyline\",\n points: points.map((p) => ({ x: p.x * f, y: p.y * f, bulge: 0 })),\n closed: anyE.closed === true,\n ...base,\n },\n ];\n }\n case \"3DFACE\": {\n // A face: its edges in order (no SOLID bow-tie). Drawn as a solid\n // fill — what a shaded view shows; wireframe shows only the edges.\n // dxf-parser pads the vertex list with an empty record; keep real,\n // distinct corners only.\n const points: any[] = (anyE.vertices ?? []).filter(\n (p: any, i: number, all: any[]) =>\n typeof p.x === \"number\" &&\n typeof p.y === \"number\" &&\n !all.slice(0, i).some((q: any) => q.x === p.x && q.y === p.y),\n );\n if (points.length < 3) return [];\n bump(ctx.degraded, \"3DFACE→hatch\");\n return [\n {\n type: \"hatch\",\n loops: [{ points: points.map((p) => ({ ...pt(p, f), bulge: 0 })) }],\n fill: { kind: \"solid\" },\n scale: 1,\n ...base,\n },\n ];\n }\n case \"TRACE\":\n case \"SOLID\": {\n const points: any[] = anyE.points ?? [];\n if (points.length < 3) return [];\n // DXF SOLID vertex order is 1,2,4,3.\n const ordered =\n points.length >= 4\n ? [points[0], points[1], points[3], points[2]]\n : points;\n return [\n {\n type: \"hatch\",\n loops: [\n {\n points: ordered.map((p) => ({ ...ocs(p), bulge: 0 })),\n },\n ],\n fill: { kind: \"solid\" },\n scale: 1,\n ...base,\n },\n ];\n }\n case \"HATCH\":\n return convertHatch(e, ctx);\n case \"LEADER\":\n return convertLeader(e, ctx);\n case \"MULTILEADER\":\n return convertMultiLeader(e, ctx);\n case \"DIMENSION\":\n return convertDimension(e, dxf, ctx);\n default:\n return [];\n }\n};\n\n/**\n * Blocks indexed by their owner BLOCK_RECORD handle (group 330), built\n * lazily once per parsed document. ACAD_TABLE via the DWG transcode\n * references its content block by that HANDLE (AutoCAD's native DXF puts\n * the `*T<n>` block NAME in the same field), so the name lookup misses and\n * this resolves the join.\n */\nconst blocksByOwner = new WeakMap<object, Map<string, IBlock>>();\nconst blockByOwnerHandle = (dxf: IDxf, handle: string): IBlock | undefined => {\n let map = blocksByOwner.get(dxf);\n if (!map) {\n map = new Map();\n for (const b of Object.values(dxf.blocks ?? {})) {\n const oh = (b as { ownerHandle?: unknown }).ownerHandle;\n if (oh !== undefined) map.set(String(oh).toUpperCase(), b);\n }\n blocksByOwner.set(dxf, map);\n }\n return map.get(handle.toUpperCase());\n};\n\n/**\n * An INSERT of an XREF block (group-70 bit 4, path in group 1) → a Linea\n * reference to the same file, placed like the insert (docs/references.md):\n * the linked file's content is NOT part of this DXF, so exploding it would\n * yield nothing.\n */\nconst xrefReference = (\n e: IEntity,\n dxf: IDxf,\n ctx: ImportContext,\n): ModelObjectDto | null => {\n const anyE = e as any;\n const block = dxf.blocks?.[anyE.name] as IBlock | undefined;\n if (!block) return null;\n // An external reference: the xref flag (70 bit 4), or a group-1 path that\n // IS a path (a folder or a file extension). A DWG transcode writes group 1\n // = the block's own name on ordinary blocks (FIN04A's ARK$VAR marker),\n // which is not a reference to anything.\n const rawPath = block.xrefPath ?? \"\";\n const isXref =\n (block.type & 4) !== 0 ||\n (rawPath !== \"\" &&\n rawPath !== block.name &&\n (/[\\\\/]/.test(rawPath) || referenceFormatOf(rawPath) !== null));\n if (!isXref) return null;\n const path = (rawPath || `${block.name}.dwg`).replace(/\\\\/g, \"/\");\n const sx = anyE.xScale ?? 1;\n const sy = anyE.yScale ?? 1;\n // Linea mirrors left-right (−X); a negative Y scale is that flip turned\n // half a turn.\n const rotation = (anyE.rotation ?? 0) * DEG2RAD + (sy < 0 ? Math.PI : 0);\n return {\n ...baseFor(e, ctx),\n type: \"reference\",\n format: referenceFormatOf(path) ?? \"dwg\",\n name: block.name,\n source: { kind: \"path\", path },\n position: pt(anyE.position ?? { x: 0, y: 0 }, ctx.f),\n rotation,\n scale: Math.abs(sx) || 1,\n ...(sx * sy < 0 ? { mirrored: true } : {}),\n hiddenLayers: [],\n } as ModelObjectDto;\n};\n\n/** Explode INSERTs by converting the block's entities and transforming them. */\n/**\n * ACAD_TABLE → native table, from the legacy AcDbTable payload\n * (AcadTableHandler): grid, row heights (as floors — rows still grow to fit),\n * column widths, merges, per-cell alignment / height / bold-italic and the\n * cleaned MTEXT. Null when the payload is missing, inconsistent or holds a\n * non-text cell — the caller then explodes the *T block as before.\n */\nconst convertAcadTable = (\n e: IEntity,\n ctx: ImportContext,\n): ModelObjectDto | null => {\n const anyE = e as any;\n const t: AcadTableData | undefined = anyE.table;\n if (!t || !anyE.position) return null;\n const { cols, cells } = t;\n // A DWG transcode can report the ALLOCATED row count (91) with trailing\n // rows that have no cells (their heights are 0 or uninitialized); the\n // cells are the truth when they fill a whole number of rows.\n let rows = t.rows;\n let rowHeights = t.rowHeights;\n if (\n cols > 0 &&\n cells.length !== rows * cols &&\n cells.length % cols === 0 &&\n cells.length / cols < rows &&\n rowHeights.length === rows\n ) {\n rows = cells.length / cols;\n rowHeights = rowHeights.slice(0, rows);\n }\n if (\n rows === 0 ||\n cells.length !== rows * cols ||\n rowHeights.length !== rows ||\n t.colWidths.length !== cols ||\n cells.some((c) => c.type !== 1)\n )\n return null;\n const f = ctx.f;\n const fallbackRowHeight = Math.min(\n ...rowHeights.filter((h) => h > 0),\n Infinity,\n );\n const H = [\"left\", \"center\", \"right\"] as const;\n const grid = Array.from({ length: rows }, (_, r) =>\n Array.from({ length: cols }, (_, c) => {\n const cell = cells[r * cols + c];\n // Text cells carry group 1; numeric cells only the display string.\n const raw = cell.text || cell.display || \"\";\n const a = cell.alignment;\n const rich = cleanRichText(\n raw,\n cell.height && cell.height > 0 ? cell.height : 2.5,\n );\n // Trailing blank lines / spaces (a DWG transcode pads cells) would\n // add empty lines to the row.\n const text = rich.content.replace(/\\s+$/, \"\");\n // Formatting of PART of the cell; whole-cell bold/italic rides on the\n // style override below (mtextFontFlags), as before.\n const spans = normalizeSpans(rich.spans, text).filter(\n (s) => s.start > 0 || s.end < text.length,\n );\n return {\n content: text,\n ...(spans.length ? { spans } : {}),\n ...(cell.cols > 1 || cell.rows > 1\n ? { span: { cols: cell.cols, rows: cell.rows } }\n : {}),\n ...(a !== undefined && a >= 1 && a <= 9\n ? {\n hAlign: H[(a - 1) % 3],\n vAlign:\n a <= 3\n ? (\"top\" as const)\n : a <= 6\n ? (\"center\" as const)\n : (\"bottom\" as const),\n }\n : {}),\n styleOverride: {\n ...(cell.height && cell.height > 0\n ? { textHeight: cell.height * f }\n : {}),\n ...mtextFontFlags(raw),\n },\n };\n }),\n );\n const parsed = ModelObjectSchema.safeParse({\n type: \"table\",\n id: \"acad-table\",\n position: pt(anyE.position, f),\n rotation: (anyE.rotation ?? 0) * DEG2RAD,\n scale: 1,\n columns: t.colWidths.map((w) => w * f),\n // AutoCAD's row heights are the drawn ones: keep them as floors. A DWG\n // transcode writes 0 for some rows (FIN04A: the last row of 64 tables,\n // 49 of them empty) — an empty row would collapse to its margins and\n // look deleted, so a zero height takes the table's smallest real row\n // height (a one-line row), else the row's content decides.\n rows: rowHeights.map((h) =>\n h > 0\n ? { minHeight: h * f }\n : fallbackRowHeight > 0\n ? { minHeight: fallbackRowHeight * f }\n : {},\n ),\n cells: grid,\n // Margin (40) — absent in a DWG transcode (its TABLESTYLE is dropped):\n // AutoCAD's Standard style pads a cell by a third of its text height,\n // so a missing margin takes that, from the cells' height or the style.\n cellMargin:\n t.margin !== undefined\n ? t.margin * f\n : 0.3 *\n (Math.max(0, ...cells.map((c) => (c.height ?? 0) * f)) ||\n ctx.defaultTextStyle.textHeight),\n ...baseFor(e, ctx),\n });\n if (!parsed.success) return null;\n const { id: _id, ...dto } = parsed.data;\n void _id;\n return dto as ModelObjectDto;\n};\n\n/**\n * The definition for a DXF block, generated on first use (cached per\n * block) when its visible entities convert to at least one object. The\n * children are the block's entities converted at the origin (a unit insert\n * at 0,0), so their coordinates are block-local millimetres; a child on\n * layer `0` drops its layer and follows the instance (ByBlock), the others\n * keep theirs.\n */\nconst blockDefinitionFor = (\n block: IBlock,\n dxf: IDxf,\n ctx: ImportContext,\n): ImportedBlockDefinition | null => {\n const key = block.name.toUpperCase();\n const cached = ctx.blockDefinitions.get(key);\n if (cached !== undefined) return cached;\n let def: ImportedBlockDefinition | null = null;\n {\n const unit = {\n type: \"INSERT\",\n name: block.name,\n position: { x: 0, y: 0 },\n xScale: 1,\n yScale: 1,\n rotation: 0,\n layer: \"0\",\n } as unknown as IEntity;\n const children = convertInsertInner(unit, dxf, ctx, 1);\n if (children.length > 0) {\n // A name clash → suffixed, the library's merge rule\n // (mergeScriptModules). The id ignores the name, so a module already\n // here (same content hash) is still found below and reused as is.\n const taken = (n: string) =>\n [...ctx.existingBlocks, ...ctx.newBlockDefinitions].some(\n (b) => b.name.toLowerCase() === n.toLowerCase(),\n );\n let name = block.name.replace(/^\\*/, \"\");\n while (taken(name)) name = `${name} (imported)`;\n def = blockDefinitionModule(\n block.name,\n children,\n inheritLayerIds(ctx),\n name,\n );\n const id = def.id;\n const same = ctx.newBlockDefinitions.find((d) => d.id === id);\n if (same) def = same;\n else if (!ctx.existingBlocks.some((b) => b.id === id))\n ctx.newBlockDefinitions.push(def);\n }\n }\n ctx.blockDefinitions.set(key, def);\n return def;\n};\n\n/** Layers whose children follow the insert: DXF layer `0` and the import's\n * fallback layer (entities whose layer is unknown). */\nconst inheritLayerIds = (ctx: ImportContext): ReadonlySet<string> =>\n new Set(\n [ctx.layerIdByName.get(\"0\"), ctx.defaultLayerId].filter(\n (id): id is string => id !== undefined,\n ),\n );\n\nconst convertInsertInner = (\n e: IEntity,\n dxf: IDxf,\n ctx: ImportContext,\n depth: number,\n /** What a ByBlock child resolves to: an enclosing insert's own color.\n * Undefined inside a definition build (the instance supplies it at paint\n * time) — the explode path falls back to the insert's layer color. */\n inheritedColor?: string,\n): ModelObjectDto[] => {\n const anyE = e as any;\n if (depth > 16) return []; // guard against self-referential blocks\n // Tables may reference their content block by BLOCK_RECORD handle instead\n // of name (the DWG transcode does); scoped to ACAD_TABLE so an INSERT with\n // a genuinely missing block can't collide with a handle by accident.\n const block =\n dxf.blocks?.[anyE.name] ??\n (e.type === \"ACAD_TABLE\"\n ? blockByOwnerHandle(dxf, String(anyE.name ?? \"\"))\n : undefined);\n if (!block) return [];\n if (!block.entities?.length) {\n // An insert of an empty block (marker blocks like FIN04A's ARK$VAR)\n // shows nothing in AutoCAD either — accounted, not lost.\n bump(ctx.skipped, \"INSERT (empty block)\");\n return [];\n }\n\n // DXF INSERT carries independent x/y/z scales (groups 41/42/43); a negative\n // scale is a mirror. Build the full affine — scale each axis, rotate, then\n // translate to the insertion point.\n // A downward extrusion mirrors the OCS about Y: M·R(θ)·S = R(π−θ)·diag(1,−1)·S,\n // so the insert becomes position (−x, y), rotation π−θ, y scale negated.\n const mirrored = ctx.tags.mirroredHandles.has(String(anyE.handle));\n // MINSERT: a column × row array of the block. Spacings are measured in\n // the insert's rotated frame, unscaled; each copy converts as one INSERT.\n const columns: number = anyE.columnCount > 1 ? anyE.columnCount : 1;\n const rows: number = anyE.rowCount > 1 ? anyE.rowCount : 1;\n if (columns > 1 || rows > 1) {\n const cs: number = anyE.columnSpacing ?? 0;\n const rs: number = anyE.rowSpacing ?? 0;\n const theta = (anyE.rotation ?? 0) * DEG2RAD;\n const p0 = anyE.position ?? { x: 0, y: 0 };\n const out: ModelObjectDto[] = [];\n for (let j = 0; j < rows; j++)\n for (let i = 0; i < columns; i++) {\n const dx = i * cs;\n const dy = j * rs;\n const copy = {\n ...anyE,\n columnCount: 1,\n rowCount: 1,\n position: {\n x: p0.x + dx * Math.cos(theta) - dy * Math.sin(theta),\n y: p0.y + dx * Math.sin(theta) + dy * Math.cos(theta),\n },\n };\n out.push(...convertInsertInner(copy as IEntity, dxf, ctx, depth));\n }\n return out;\n }\n const sx = anyE.xScale ?? 1;\n const sy = (anyE.yScale ?? 1) * (mirrored ? -1 : 1);\n const rot0 = (anyE.rotation ?? 0) * DEG2RAD;\n const rot = mirrored ? Math.PI - rot0 : rot0;\n const pos = anyE.position ?? { x: 0, y: 0 };\n const insert = mirrored\n ? { x: -pos.x * ctx.f, y: pos.y * ctx.f }\n : pt(pos, ctx.f);\n\n // A top-level INSERT with a uniform positive scale becomes an INSTANCE of\n // a generated definition (blockDefinitions.ts); everything else —\n // mirrors, anisotropic scales, nested inserts (baked into their parent's\n // definition), tables — explodes below.\n if (\n e.type === \"INSERT\" &&\n depth === 0 &&\n !mirrored &&\n sx > 0 &&\n sy > 0 &&\n Math.abs(sx - sy) < 1e-9\n ) {\n const def = blockDefinitionFor(block, dxf, ctx);\n if (def)\n return [\n {\n type: \"block\",\n definitionId: def.id,\n inputs: [insert],\n rotation: rot,\n scale: sx,\n params: {},\n ...baseFor(e, ctx),\n },\n ];\n }\n if (e.type === \"INSERT\" && depth === 0) bump(ctx.degraded, \"INSERT→exploded\");\n // The block's base point (BLOCK 10/20) is its origin: world =\n // insert + R·S·(entity − base).\n const base = pt(block.position ?? { x: 0, y: 0 }, ctx.f);\n const cos = Math.cos(rot);\n const sin = Math.sin(rot);\n const reflect = sx * sy < 0;\n const meanScale = Math.sqrt(Math.abs(sx * sy)) || 1e-6;\n const lin = (v: Vec2): Vec2 => ({\n x: cos * (v.x * sx) - sin * (v.y * sy),\n y: sin * (v.x * sx) + cos * (v.y * sy),\n });\n const map = (p: Vec2): Vec2 => {\n const l = lin({ x: p.x - base.x, y: p.y - base.y });\n return { x: l.x + insert.x, y: l.y + insert.y };\n };\n\n // Re-fit a bulged vertex list through the affine: map the vertices, then\n // recompute each segment's bulge from the transformed endpoints + arc\n // midpoint (so rotation, per-axis scale, and mirror sign flips are handled).\n const mapBulged = (\n verts: PolylineVertex[],\n closed: boolean,\n ): PolylineVertex[] => {\n const out = verts.map((v) => {\n const m = map(v);\n return { x: m.x, y: m.y, bulge: 0 };\n });\n const n = verts.length;\n const segs = closed ? n : n - 1;\n for (let i = 0; i < segs; i++) {\n const b = verts[i].bulge;\n if (!b) continue;\n const j = (i + 1) % n;\n const arc = bulgeToArc(\n { x: verts[i].x, y: verts[i].y },\n { x: verts[j].x, y: verts[j].y },\n b,\n );\n if (!arc) continue;\n const nb = bulgeFrom3Points(out[i], map(arcMidPoint(arc)), out[j]);\n out[i].bulge = Number.isFinite(nb) ? Math.max(-4, Math.min(4, nb)) : 0;\n }\n return out;\n };\n\n const transform = (dto: ModelObjectDto): ModelObjectDto | null => {\n const t = structuredClone(dto);\n switch (t.type) {\n case \"line\":\n t.a = map(t.a);\n t.b = map(t.b);\n return t;\n case \"polyline\":\n t.points = mapBulged(t.points, t.closed);\n return t;\n case \"circle\": {\n const ax = Math.abs(sx) * t.radius;\n const ay = Math.abs(sy) * t.radius;\n const center = map(t.center);\n if (Math.abs(ax - ay) <= 1e-6 * Math.max(ax, ay, 1)) {\n t.center = center;\n t.radius = Math.max((ax + ay) / 2, 1e-6);\n return t;\n }\n // Anisotropic scale turns the circle into a rotated ellipse.\n const majorLen = Math.max(ax, ay);\n const ang = rot + (ax >= ay ? 0 : Math.PI / 2);\n return {\n type: \"ellipse\",\n center,\n majorAxis: {\n x: majorLen * Math.cos(ang),\n y: majorLen * Math.sin(ang),\n },\n ratio: Math.min(1, Math.max(1e-3, Math.min(ax, ay) / majorLen)),\n startAngle: 0,\n endAngle: Math.PI * 2,\n layerId: t.layerId,\n ...(t.color ? { color: t.color } : {}),\n ...(t.lineType ? { lineType: t.lineType } : {}),\n ...(t.lineTypeScale !== undefined\n ? { lineTypeScale: t.lineTypeScale }\n : {}),\n ...(t.lineWidth !== undefined ? { lineWidth: t.lineWidth } : {}),\n };\n }\n case \"arc\": {\n // Reconstruct through three transformed points — exact for any\n // similarity (rotation / uniform scale / mirror); a circular\n // approximation for the rare anisotropic case.\n const g = {\n center: t.center,\n radius: t.radius,\n startAngle: t.startAngle,\n endAngle: t.endAngle,\n };\n const solved = arcFrom3Points(\n map(arcStartPoint(g)),\n map(arcMidPoint(g)),\n map(arcEndPoint(g)),\n );\n if (!solved) return null;\n t.center = solved.center;\n t.radius = solved.radius;\n t.startAngle = solved.startAngle;\n t.endAngle = solved.endAngle;\n return t;\n }\n case \"ellipse\":\n t.center = map(t.center);\n t.majorAxis = lin(t.majorAxis);\n if (reflect) {\n const s0 = t.startAngle;\n t.startAngle = -t.endAngle;\n t.endAngle = -s0;\n }\n return t;\n case \"hatch\": {\n t.loops = t.loops.map((loop: { points: PolylineVertex[] }) => ({\n points: mapBulged(loop.points, true),\n }));\n // The pattern is part of the block: its lines turn (and reflect)\n // with the insert, the spacing scales, and the frame — anchored at\n // the block origin in AutoCAD — follows the insertion point.\n if (t.fill.kind === \"pattern\" || t.fill.kind === \"lines\") {\n const d = lin({\n x: Math.cos(t.fill.angle),\n y: Math.sin(t.fill.angle),\n });\n const angle = Math.atan2(d.y, d.x);\n t.fill =\n t.fill.kind === \"pattern\"\n ? {\n ...t.fill,\n angle,\n scale: t.fill.scale * meanScale,\n origin: map(t.fill.origin ?? { x: 0, y: 0 }),\n }\n : { ...t.fill, angle, spacing: t.fill.spacing * meanScale };\n }\n return t;\n }\n case \"text\":\n t.position = map(t.position);\n t.rotation += rot;\n // Sizes a scaled insert multiplies: the text's own override, or\n // (when it follows its style's) the style value — made explicit.\n if (meanScale !== 1) {\n const style =\n (t.styleId && ctx.textStyleById.get(t.styleId)) ||\n ctx.defaultTextStyle;\n const o = t.styleOverride ?? {};\n t.styleOverride = {\n ...o,\n textHeight: (o.textHeight ?? style.textHeight) * meanScale,\n ...(o.arrowSize === undefined\n ? {}\n : { arrowSize: o.arrowSize * meanScale }),\n };\n }\n if (t.width !== undefined) t.width *= meanScale;\n t.leaderLines = t.leaderLines.map((l) => l.map(map));\n return t;\n case \"dimension\": {\n // Scalar placement re-derived from mapped points: the dimension\n // line point maps like any point, a locked axis maps by direction,\n // the arc radius scales (a reflection picks the other arc), label\n // distances scale (a reflection flips the handed radial/diameter\n // frames' `across`).\n const before = t.points;\n t.points = t.points.map(map);\n if (t.kind === \"linear\") {\n const axis = linearAxis({ points: before, rotation: t.rotation });\n const linePoint = v2.add(before[0], v2.scale(axis.n, t.offset ?? 0));\n if (t.rotation !== undefined) t.rotation = v2.angle(lin(axis.u));\n t.offset = v2.dot(\n v2.sub(map(linePoint), t.points[0]),\n linearAxis(t).n,\n );\n } else if (t.kind === \"angular\")\n t.offset = (t.offset ?? 0) * meanScale * (reflect ? -1 : 1);\n const handed = t.kind === \"radial\" || t.kind === \"diameter\";\n t.labels = t.labels.map((l) => ({\n ...l,\n ...(l.along === undefined ? {} : { along: l.along * meanScale }),\n ...(l.across === undefined\n ? {}\n : { across: l.across * meanScale * (handed && reflect ? -1 : 1) }),\n }));\n return t;\n }\n }\n return t;\n };\n\n // Colors inside a block follow AutoCAD's rules: a ByBlock child takes the\n // insert's own color, else the insert's layer color; a ByLayer child on\n // layer 0 takes the insert's layer; a ByLayer child on its own layer keeps\n // that layer's color. The unit insert of a definition build (depth 1,\n // `inheritedColor` undefined, layer 0) leaves ByBlock children uncolored —\n // the instance supplies its color at paint time — and bakes ByLayer\n // children's own-layer colors, since an instance paints every colorless\n // child in its own color.\n const insertBase = baseFor(e, ctx);\n const insertLayerInherits = inheritLayerIds(ctx).has(insertBase.layerId);\n const byBlockColor =\n insertBase.color ??\n inheritedColor ??\n (depth === 0 && !insertLayerInherits\n ? ctx.layerColorById.get(insertBase.layerId)\n : undefined);\n const inDefinition = inheritedColor === undefined && depth >= 1;\n const result: ModelObjectDto[] = [];\n for (const child of block.entities) {\n // Recurse into nested block references, then apply this insert's transform\n // to the exploded children (composing the nested + outer scales/mirrors).\n // A table inside a block converts native first (its *T block is often\n // absent from a DWG transcode, which would leave nothing).\n const childDtos = convertEntity(child, dxf, ctx, depth + 1, byBlockColor);\n const isRef = child.type === \"INSERT\" || child.type === \"ACAD_TABLE\";\n const ci = (child as any).colorIndex as number | undefined;\n const childByBlock = !isRef && ci === 0;\n const childByLayer = !isRef && (ci === undefined || ci === 256);\n for (const dto of childDtos) {\n const t = transform(dto);\n if (!t) continue;\n if (t.color === undefined) {\n if (childByBlock && byBlockColor !== undefined) t.color = byBlockColor;\n else if (\n childByLayer &&\n inDefinition &&\n !inheritLayerIds(ctx).has(t.layerId)\n ) {\n const own = ctx.layerColorById.get(t.layerId);\n if (own !== undefined) t.color = own;\n }\n }\n // Layer 0 inside a block means \"the insert's layer\".\n if (inheritLayerIds(ctx).has(t.layerId) && !insertLayerInherits)\n t.layerId = insertBase.layerId;\n result.push(t);\n }\n }\n // A table whose AcDbTable payload didn't yield a native table is drawn\n // from its *T block: lines + texts, no longer a table.\n if (e.type === \"ACAD_TABLE\" && result.length > 0)\n bump(ctx.degraded, \"ACAD_TABLE→exploded\");\n return result;\n};\n\n/** Paper-space VIEWPORT entity → viewport object (null = not importable). */\nconst convertViewport = (\n e: IEntity,\n ctx: ImportContext,\n): ModelObjectDto | null => {\n const anyE = e as any;\n if (!anyE.center || !(anyE.width > 0) || !(anyE.height > 0)) return null;\n if (!(anyE.viewHeight > 0)) return null;\n const f = ctx.f;\n return {\n type: \"viewport\",\n rect: {\n x: (anyE.center.x - anyE.width / 2) * f,\n y: (anyE.center.y - anyE.height / 2) * f,\n w: anyE.width * f,\n h: anyE.height * f,\n },\n modelCenter: anyE.viewCenter ? pt(anyE.viewCenter, f) : { x: 0, y: 0 },\n // Both in the same unit → the ratio is the 1:N denominator (model mm\n // shown per paper mm).\n scale: anyE.viewHeight / anyE.height,\n locked: ((anyE.statusFlags ?? 0) & VIEWPORT_LOCKED_FLAG) !== 0,\n // 331 = LAYER record handles frozen in this viewport (raw-scanned table).\n hiddenLayerIds: ((anyE.frozenLayerHandles ?? []) as string[]).flatMap(\n (h) => {\n const name = ctx.layerNameByHandle.get(h.toUpperCase());\n const id = name && ctx.layerIdByName.get(name.toLowerCase());\n return id ? [id] : [];\n },\n ),\n ...baseFor(e, ctx),\n };\n};\n\n/** Document state the conversion needs — supplied by the caller (no store). */\nexport interface DxfImportContext {\n /** Existing layers, so DXF layers matched by name reuse the same id. */\n existingLayers: { id: string; name: string }[];\n /** Layer id for entities whose DXF layer has no match. */\n defaultLayerId: string;\n /** The document's text / dimension styles. A file style (STYLE /\n * DIMSTYLE record) matching one by name AND values reuses it; the others\n * are created — a name clash with different values gets a `_2` suffix.\n * Absent = none (the document default is the schema default). */\n existingTextStyles?: readonly TextStyle[];\n existingDimStyles?: readonly DimStyle[];\n /** The document has no content yet: a clashing file style REPLACES the\n * document style's values (same id), and the file's current style\n * ($TEXTSTYLE / $DIMSTYLE) becomes the first = default one. */\n adoptStyles?: boolean;\n /** The document's own line type / hatch pattern definitions: a file\n * definition of a name the document already defines is not re-added (the\n * document's wins). */\n existingLineTypes?: readonly LineType[];\n existingHatchPatterns?: readonly DocumentHatchPattern[];\n /** mm per drawing unit; overrides the file's $INSUNITS when set. */\n unitOverride?: number;\n /** The document's block modules: a generated module the document already\n * holds (same content-hashed id) is reused, not re-added; one whose name\n * a different block takes is suffixed \" (imported)\". */\n existingBlocks?: readonly { id: string; name: string }[];\n}\n\n/** What a DXF import yields — the caller adds these to the document. */\nexport interface DxfImportResult {\n /** Model-space objects to add (DTOs — ids assigned by the caller/funnel). */\n objects: ModelObjectDto[];\n /** Layers that must be created (DXF layers with no name match). */\n newLayers: Layer[];\n /** The document's style arrays AFTER the import: the existing styles\n * (values replaced only under `adoptStyles`), then the created ones —\n * hand them to the whole-array setters, which diff. */\n textStyles: TextStyle[];\n dimStyles: DimStyle[];\n /** The document's line type / hatch pattern arrays AFTER the import: the\n * existing ones, then the file's definitions something used (LTYPE table\n * entries the catalogue lacks; HATCH definition lines). */\n lineTypes: LineType[];\n hatchPatterns: DocumentHatchPattern[];\n /** Paper layouts rebuilt from *Paper_Space blocks (ids already assigned). */\n layouts: PaperLayout[];\n /** Block module sources for the DXF blocks that became instances\n * (blockDefinitions.ts) — merge into `document.blockDefinitions`. */\n newBlockDefinitions: string[];\n /** Source entity type → entities imported as-is (rule R8, entityLedger.ts). */\n imported: Map<string, number>;\n /** `SOURCE→what` → entities imported as an approximation. */\n degraded: Map<string, number>;\n /** Entity type or reason → entities that produced nothing — including the\n * types dxf-parser drops before the importer sees them (ATTRIB, MLINE…). */\n skipped: Map<string, number>;\n}\n\n/**\n * Parse DXF text into model objects, new layers, and paper layouts. Pure and\n * headless — throws on an unparseable file; the editor wraps this with the\n * store read, the undo transaction, zoom-to-fit, and toasts.\n */\nexport const dxfToModel = (\n text: string,\n input: DxfImportContext,\n): DxfImportResult => {\n let dxf: IDxf;\n {\n const parser = new DxfParser();\n parser.registerEntityHandler(ViewportHandler as any);\n parser.registerEntityHandler(HatchHandler as any);\n parser.registerEntityHandler(AcadTableHandler as any);\n parser.registerEntityHandler(LeaderHandler as any);\n parser.registerEntityHandler(MultiLeaderHandler as any);\n parser.registerEntityHandler(AttribHandler as any);\n parser.registerEntityHandler(MlineHandler as any);\n parser.registerEntityHandler(TraceHandler as any);\n const parsed = parser.parseSync(text);\n if (!parsed) throw new Error(\"DXF parse produced no result\");\n dxf = parsed;\n }\n\n const header = dxf.header as Record<string, unknown> | undefined;\n const f =\n input.unitOverride !== undefined && input.unitOverride > 0\n ? input.unitOverride\n : unitFactor(header?.[\"$INSUNITS\"]);\n // Overall dimension scale (DIMSCALE): multiplies text/arrow sizes so a 1:N\n // drawing's dimensions come in at the right size. dxf-parser exposes no\n // DIMSTYLE table or per-dimension style, so the header's current-dimstyle\n // value is the source; carry it onto each dimension's style override.\n const dimScaleRaw = header?.[\"$DIMSCALE\"];\n const dimScale =\n typeof dimScaleRaw === \"number\" && dimScaleRaw > 0 ? dimScaleRaw : 1;\n // Global line type scale: AutoCAD draws every dash pattern × $LTSCALE ×\n // the entity's 48; fold it into each imported lineTypeScale.\n const ltScaleRaw = header?.[\"$LTSCALE\"];\n const ltScale =\n typeof ltScaleRaw === \"number\" && ltScaleRaw > 0 ? ltScaleRaw : 1;\n\n // Split ONCE for every raw-tag pass below (dxfLines.ts): each split of a\n // large file allocates millions of strings, and four passes each doing\n // their own was most of the import's time (mostly garbage collection).\n const lines = dxfLines(text);\n const tags = scanTags(lines);\n\n // Styles: the STYLE / DIMSTYLE records something references (texts by\n // group 7 — absent = \"Standard\" —, dimensions and leaders by group 3,\n // plus the file's current styles on a fresh document) become document\n // styles, merged by name (styleTables.ts).\n const existingText = input.existingTextStyles ?? [];\n const existingDim = input.existingDimStyles ?? [];\n const adopt = input.adoptStyles === true;\n const headerStr = (key: string): string | undefined => {\n const v = header?.[key];\n return typeof v === \"string\" && v.trim() ? v.trim() : undefined;\n };\n const currentText = headerStr(\"$TEXTSTYLE\");\n const currentDim = headerStr(\"$DIMSTYLE\");\n const defaultTextHeight = (existingText[0] ?? DEFAULT_TEXT_STYLE).textHeight;\n const styleRecordNamed = (name: string): StyleRecord | undefined =>\n tags.textStyles.get(name) ??\n [...tags.textStyles.values()].find(\n (r) => r.name.toLowerCase() === name.toLowerCase(),\n );\n const usedTextStyles = new Set<string>();\n for (const name of tags.textStyleNameByHandle.values())\n usedTextStyles.add(name.toLowerCase());\n for (const key of tags.textHeightsByStyle.keys())\n usedTextStyles.add(key || \"standard\");\n if (adopt && currentText) usedTextStyles.add(currentText.toLowerCase());\n const incomingText: {\n name: string;\n values: Omit<TextStyle, \"id\" | \"name\">;\n }[] = [];\n for (const key of usedTextStyles) {\n const rec = styleRecordNamed(key);\n if (!rec) continue;\n const heights = new Map(tags.textHeightsByStyle.get(key) ?? []);\n if (key === \"standard\")\n for (const [h, n] of tags.textHeightsByStyle.get(\"\") ?? [])\n heights.set(h, (heights.get(h) ?? 0) + n);\n incomingText.push({\n name: rec.name,\n values: textStyleFromRecord(rec, heights, f, defaultTextHeight),\n });\n }\n const mergedText = mergeStyles(existingText, incomingText, sameTextStyle, {\n adopt,\n current: currentText,\n });\n\n const dimValueCtx = {\n f,\n textStyleByHandle: tags.textStyleByHandle,\n blockNameByHandle: tags.blockNameByHandle,\n };\n // The header's current dimension variables, keyed like DIMSTYLE groups —\n // what a record that leaves a group out falls back to.\n const headerDim = new Map<number, string>();\n for (const [key, code] of [\n [\"$DIMTXT\", 140],\n [\"$DIMASZ\", 41],\n [\"$DIMTSZ\", 142],\n [\"$DIMEXO\", 42],\n [\"$DIMEXE\", 44],\n [\"$DIMGAP\", 147],\n [\"$DIMDEC\", 271],\n ] as const) {\n const v = header?.[key];\n if (typeof v === \"number\") headerDim.set(code, String(v));\n }\n const usedDimStyles = new Set<string>();\n for (const name of tags.dimStyleNameByHandle.values())\n usedDimStyles.add(name.toLowerCase());\n if (adopt && currentDim) usedDimStyles.add(currentDim.toLowerCase());\n const incomingDim: { name: string; values: Omit<DimStyle, \"id\" | \"name\"> }[] =\n [];\n const dimScaleByName = new Map<string, number>();\n for (const key of usedDimStyles) {\n const rec = [...tags.dimStyles.values()].find(\n (r) => r.name.toLowerCase() === key,\n );\n if (!rec) continue;\n const { values, scale } = dimStyleFromRecord(rec, headerDim, dimValueCtx);\n incomingDim.push({ name: rec.name, values });\n dimScaleByName.set(key, scale);\n }\n const mergedDim = mergeStyles(existingDim, incomingDim, sameDimStyle, {\n adopt,\n current: currentDim,\n });\n const dimScaleByStyleId = new Map<string, number>();\n for (const [key, id] of mergedDim.idByName)\n dimScaleByStyleId.set(id, dimScaleByName.get(key) ?? 1);\n\n // The file's LTYPE table: definitions the catalogue does not know become\n // document line types when something uses them (dashes × f; a known name\n // keeps mapping to the catalogue). Complex line types keep their dash\n // skeleton — the embedded shapes/text are not rendered.\n const customLineTypes = {\n customLineTypes: new Map<string, LineType>(),\n usedLineTypes: new Map<string, LineType>(),\n };\n const ltypes = (dxf.tables as any)?.lineType?.lineTypes ?? {};\n for (const [name, rec] of Object.entries(ltypes) as [string, any][]) {\n const n = String(rec?.name ?? name).trim();\n if (!n || /^(bylayer|byblock|continuous)$/i.test(n)) continue;\n if (getLineType(n)) continue;\n const pattern: unknown[] = Array.isArray(rec?.pattern) ? rec.pattern : [];\n const dashes = pattern\n .map((v) => Number(v))\n .filter((v) => Number.isFinite(v))\n .map((v) => v * f);\n if (dashes.length === 0 || dashes.every((v) => v === 0)) continue;\n const description =\n typeof rec?.description === \"string\" && rec.description.trim()\n ? rec.description.trim()\n : undefined;\n // The document's own definition of this name wins (its spelling, its\n // dashes); the file's is only a reference to it.\n const existing = (input.existingLineTypes ?? []).find(\n (t) => lineTypeKey(t.name) === lineTypeKey(n),\n );\n customLineTypes.customLineTypes.set(\n lineTypeKey(n),\n existing ?? {\n name: n,\n ...(description ? { description } : {}),\n dashesMm: dashes,\n },\n );\n }\n\n // Layers: match by name, create the missing ones. Keys are lowercased:\n // DXF layer names are case-insensitive, and so are Linea's (one layer\n // per name, op layer) — \"Walls\" and \"WALLS\" are the same layer.\n const layerIdByName = new Map<string, string>();\n for (const layer of input.existingLayers)\n layerIdByName.set(layer.name.toLowerCase(), layer.id);\n const newLayers: Layer[] = [];\n const dxfLayers = dxf.tables?.layer?.layers ?? {};\n for (const [name, dxfLayer] of Object.entries(dxfLayers)) {\n if (layerIdByName.has(name.toLowerCase())) continue;\n const colorInt = (dxfLayer as { color?: number }).color ?? 0xffffff;\n const layerTags = tags.layers.get(name);\n newLayers.push({\n id: crypto.randomUUID(),\n name,\n color:\n tags.trueColorByLayerName.get(name) ??\n rgbToHex(\n (colorInt >> 16) & 0xff,\n (colorInt >> 8) & 0xff,\n colorInt & 0xff,\n ),\n // Line type (6), lineweight (370), lock bit (70) and plot flag (290)\n // come from the raw scan — dxf-parser reads only name, color and\n // frozen. A 2/X2 variant's factor is dropped (layers have no\n // lineTypeScale) — still the closest rendering.\n lineType:\n lineTypeFromDxf(layerTags?.lineType, customLineTypes)?.name ??\n \"continuous\",\n lineWidth: lineWeightToMm(layerTags?.lineWeight) ?? IMPORT_LINE_WIDTH_MM,\n opacity: 1,\n // Off (62 < 0) and frozen (70 bit 1) both hide the layer.\n visible:\n (dxfLayer as { visible?: boolean }).visible !== false &&\n (dxfLayer as { frozen?: boolean }).frozen !== true,\n locked: layerTags?.locked ?? false,\n print: layerTags?.plot ?? true,\n });\n layerIdByName.set(name.toLowerCase(), newLayers[newLayers.length - 1].id);\n }\n const ctx: ImportContext = {\n f,\n layerIdByName,\n // Existing layers ({id,name} only) can't be classified — entity-level\n // line types still gate correctly; byLayer dashes there stay unscaled.\n dashedLayerIds: new Set(\n newLayers\n .filter((l) => (getLineType(l.lineType)?.dashesMm.length ?? 0) > 0)\n .map((l) => l.id),\n ),\n defaultLayerId: input.defaultLayerId,\n ...emptyLedger(),\n textStyleById: new Map(mergedText.styles.map((s) => [s.id, s])),\n dimStyleById: new Map(mergedDim.styles.map((s) => [s.id, s])),\n textStyleIdByName: mergedText.idByName,\n dimStyleIdByName: mergedDim.idByName,\n dimScaleByStyleId,\n defaultTextStyle: mergedText.styles[0] ?? DEFAULT_TEXT_STYLE,\n defaultDimStyle: mergedDim.styles[0] ?? DEFAULT_DIM_STYLE,\n dimValuesFrom: (groups) => dimValuesFromGroups(groups, dimValueCtx),\n dimScale,\n ltScale,\n tags,\n mlineStyles: parseMlineStyles(lines),\n ...customLineTypes,\n // Pre-seeded with the document's own patterns: a file hatch naming one\n // references it (the document's spelling) instead of redefining it.\n hatchPatterns: new Map(\n (input.existingHatchPatterns ?? []).map((h) => [\n hatchPatternKey(h.name),\n h,\n ]),\n ),\n blockDefinitions: new Map(),\n newBlockDefinitions: [],\n existingBlocks: input.existingBlocks ?? [],\n layerWidthById: new Map(newLayers.map((l) => [l.id, l.lineWidth])),\n layerColorById: new Map(newLayers.map((l) => [l.id, l.color])),\n layerNameByHandle: new Map(\n [...tags.layers]\n .filter(([, t]) => t.handle !== undefined)\n .map(([name, t]) => [t.handle!.toUpperCase(), name]),\n ),\n };\n\n // Paper spaces: entities live inside *Paper_Space blocks, EXCEPT the\n // active layout's, which sit flat in ENTITIES with the paper-space flag.\n const paperBlocks = Object.values(dxf.blocks ?? {}).filter((b) =>\n /^\\*paper_space/i.test((b as IBlock).name ?? \"\"),\n ) as IBlock[];\n const primaryPaper =\n paperBlocks.find((b) => b.name.toLowerCase() === \"*paper_space\") ??\n paperBlocks[0];\n const paperEntities = new Map<IBlock, IEntity[]>(\n paperBlocks.map((b) => [b, [...(b.entities ?? [])]]),\n );\n\n const dtos: ModelObjectDto[] = [];\n for (const entity of dxf.entities ?? []) {\n if ((entity as any).inPaperSpace) {\n if (primaryPaper) paperEntities.get(primaryPaper)?.push(entity);\n else {\n ctx.seen.add(entity.type);\n bump(ctx.skipped, `${entity.type} (paper space)`);\n }\n continue;\n }\n if (entity.type === \"VIEWPORT\") {\n // Stray model-space viewport: nothing to show.\n ctx.seen.add(\"VIEWPORT\");\n bump(ctx.skipped, \"VIEWPORT\");\n continue;\n }\n dtos.push(...convertEntity(entity, dxf, ctx));\n }\n\n // Rebuild paper layouts. LAYOUT objects (raw OBJECTS scan) supply name,\n // tab order, and sheet size; the layout's own id-1 viewport is the sheet\n // fallback. Empty spaces are skipped.\n const layoutInfos = parseLayoutObjects(lines);\n const infoFor = (block: IBlock) =>\n layoutInfos.find(\n (li) =>\n li.blockRecordHandle !== undefined &&\n li.blockRecordHandle === String(block.ownerHandle ?? \"\").toUpperCase(),\n );\n const orderedBlocks = [...paperEntities.keys()].sort(\n (a, b) =>\n (infoFor(a)?.tabOrder ?? Number.MAX_SAFE_INTEGER) -\n (infoFor(b)?.tabOrder ?? Number.MAX_SAFE_INTEGER),\n );\n\n const newLayouts: PaperLayout[] = [];\n for (const block of orderedBlocks) {\n const entities = paperEntities.get(block) ?? [];\n if (entities.length === 0) continue;\n const info = infoFor(block);\n let sheetFallback: { w: number; h: number } | null = null;\n const objects: ModelObject[] = [];\n for (const e of entities) {\n const anyE = e as any;\n if (e.type === \"VIEWPORT\") {\n ctx.seen.add(\"VIEWPORT\");\n if (anyE.viewportId === 1) {\n // The layout's own paper view — remember its size for the sheet.\n if (anyE.width > 0 && anyE.height > 0)\n sheetFallback = { w: anyE.width * f, h: anyE.height * f };\n bump(ctx.imported, \"VIEWPORT\");\n continue;\n }\n // Switched-off viewport (90 bit 0x20000): nothing is displayed. (68\n // is NOT the switch — AutoCAD writes 68 = 0 for every viewport of a\n // layout that was not current when the file was saved.)\n if (((anyE.statusFlags ?? 0) & VIEWPORT_OFF_FLAG) !== 0) {\n bump(ctx.skipped, \"VIEWPORT (hidden)\");\n continue;\n }\n const vp = convertViewport(e, ctx);\n if (vp) {\n objects.push({ ...vp, id: crypto.randomUUID() } as ModelObject);\n bump(ctx.imported, \"VIEWPORT\");\n } else bump(ctx.skipped, \"VIEWPORT\");\n continue;\n }\n for (const dto of convertEntity(e, dxf, ctx))\n objects.push({ ...dto, id: crypto.randomUUID() } as ModelObject);\n }\n if (objects.length === 0) continue;\n try {\n newLayouts.push(\n PaperLayoutSchema.parse({\n id: crypto.randomUUID(),\n name: info?.name || `Layout ${newLayouts.length + 1}`,\n sheet: {\n width: info?.paperWidth ?? sheetFallback?.w ?? 297,\n height: info?.paperHeight ?? sheetFallback?.h ?? 210,\n },\n objects,\n }),\n );\n } catch (err) {\n console.error(\"layout import failed\", block.name, err);\n bump(ctx.skipped, \"layout\");\n }\n }\n\n // Resilience: drop any object that fails schema validation (counting it as\n // skipped) so a single malformed entity can't abort the whole import — the\n // funnel validates the batch all-or-nothing.\n const validObjects: ModelObjectDto[] = [];\n for (const dto of dtos) {\n if (ModelObjectSchema.safeParse({ ...dto, id: \"_\" }).success) {\n validObjects.push(dto);\n } else {\n const key = `invalid ${dto.type}`;\n bump(ctx.skipped, key);\n }\n }\n\n // Types dxf-parser dropped before any converter saw them (R8).\n reconcileLedger(ctx, scanEntityHistogram(lines));\n return {\n objects: validObjects,\n newLayers,\n textStyles: mergedText.styles,\n dimStyles: mergedDim.styles,\n lineTypes: [\n ...(input.existingLineTypes ?? []),\n ...[...ctx.usedLineTypes.values()].filter(\n (t) =>\n !(input.existingLineTypes ?? []).some(\n (x) => lineTypeKey(x.name) === lineTypeKey(t.name),\n ),\n ),\n ],\n hatchPatterns: [\n ...(input.existingHatchPatterns ?? []),\n ...[...ctx.hatchPatterns.values()].filter(\n (h) =>\n !(input.existingHatchPatterns ?? []).some(\n (x) => hatchPatternKey(x.name) === hatchPatternKey(h.name),\n ),\n ),\n ],\n newBlockDefinitions: ctx.newBlockDefinitions.map((d) => d.source),\n layouts: newLayouts,\n imported: ctx.imported,\n degraded: ctx.degraded,\n skipped: ctx.skipped,\n };\n};\n","// DXF STYLE / DIMSTYLE tables → the document's named text and dimension\n// styles (docs/dxf-dwg-fidelity.md §3 rows 5–6). The raw records come from\n// the importer's tag scan (dxf-parser reads neither table); this module is\n// the pure mapping: record values → Linea style values, the same mapping\n// for a DIMENSION's DSTYLE xdata (the per-entity overrides AutoCAD stores\n// as DIMSTYLE group → value pairs), and the merge rule against the styles\n// the document already has.\n//\n// Merge rule (mirrors layers: match by name, else create): a file style\n// whose name AND values agree with a document style reuses it; a name clash\n// with different values creates `Name_2` — unless the document has no\n// content yet (`adopt`), in which case the file's values replace the\n// document style's (same id) and the file's CURRENT style becomes the first\n// (= default) style. Only styles something references are created.\n\nimport {\n DEFAULT_DIM_STYLE,\n DEFAULT_TEXT_STYLE,\n type ArrowType,\n type DimStyle,\n type TextStyle,\n} from \"../../model/objects\";\nimport { fontFromDxfStyle } from \"../../model/fonts\";\n\n/** A STYLE table record (groups dxf-parser never reads). */\nexport interface StyleRecord {\n handle?: string;\n name: string;\n /** Group 3 — font file (`arial.ttf`, `romans.shx`). */\n fontFile?: string;\n /** ACAD xdata 1000 — TrueType family AutoCAD resolved the file to. */\n typeface?: string;\n /** Group 40 — fixed height (0 = asked per text). */\n fixedHeight: number;\n /** Group 41. */\n widthFactor: number;\n /** Group 50 — oblique angle in degrees. */\n oblique: number;\n /** ACAD xdata 1071 — packed font flags (italic 0x1000000, bold 0x2000000). */\n flags: number;\n /** Group 70 bit 1 — a shape file, not a text style. */\n shape: boolean;\n}\n\n/** A DIMSTYLE record: group code → raw value, plus its 105 handle. */\nexport interface DimStyleRecord {\n handle?: string;\n name: string;\n groups: Map<number, string>;\n}\n\nexport const emptyStyleRecord = (): StyleRecord => ({\n name: \"\",\n fixedHeight: 0,\n widthFactor: 1,\n oblique: 0,\n flags: 0,\n shape: false,\n});\n\n/** Standard arrowhead block names → our arrow types (\"\" = ClosedFilled). */\nexport const arrowTypeFromBlock = (name: string): ArrowType => {\n const n = name.replace(/^_/, \"\").toLowerCase();\n if (n === \"\" || n === \"closedfilled\") return \"filled\";\n if (/^(open|open30|open90|closed|closedblank)$/.test(n)) return \"open\";\n if (/^(archtick|oblique|integral)$/.test(n)) return \"tick\";\n if (\n /^(dot|dotsmall|dotblank|small|origin|origin2|boxblank|boxfilled|datumblank|datumfilled)$/.test(\n n,\n )\n )\n return \"dot\";\n if (n === \"none\") return \"none\";\n return \"filled\";\n};\n\n/** The text-side values a STYLE record carries (no height — see\n * `textStyleFromRecord`). */\nexport const textFaceFromRecord = (\n rec: Pick<\n StyleRecord,\n \"fontFile\" | \"typeface\" | \"widthFactor\" | \"oblique\" | \"flags\"\n >,\n): Pick<TextStyle, \"font\" | \"widthFactor\" | \"bold\" | \"italic\"> => {\n const face = fontFromDxfStyle(rec.fontFile, rec.typeface);\n const bold = face.bold === true || (rec.flags & 0x2000000) !== 0;\n // AutoCAD's italic flag, or an oblique angle — the SHX way to slant.\n const italic =\n face.italic === true || (rec.flags & 0x1000000) !== 0 || rec.oblique > 0;\n return {\n font: face.font,\n widthFactor: rec.widthFactor > 0 ? rec.widthFactor : 1,\n ...(bold ? { bold: true } : {}),\n ...(italic ? { italic: true } : {}),\n };\n};\n\n/** Height → count of the texts using a style (the scan collects it). */\nexport type HeightHistogram = Map<number, number>;\n\nconst modeOf = (hist: HeightHistogram | undefined): number | undefined => {\n let best: number | undefined;\n let bestN = 0;\n for (const [h, n] of hist ?? [])\n if (n > bestN || (n === bestN && best !== undefined && h < best)) {\n best = h;\n bestN = n;\n }\n return best;\n};\n\n/**\n * STYLE record → text style values (mm). A fixed height is the style's; a\n * style with none (AutoCAD asks per text) takes the height most of its\n * texts use, so most of them need no override.\n */\nexport const textStyleFromRecord = (\n rec: StyleRecord,\n heights: HeightHistogram | undefined,\n f: number,\n fallbackHeight: number,\n): Omit<TextStyle, \"id\" | \"name\"> => ({\n ...textFaceFromRecord(rec),\n textHeight:\n rec.fixedHeight > 0\n ? rec.fixedHeight * f\n : (modeOf(heights) ?? fallbackHeight / f) * f,\n arrowType: DEFAULT_TEXT_STYLE.arrowType,\n arrowSize: DEFAULT_TEXT_STYLE.arrowSize,\n});\n\n/** What a DIMSTYLE group mapping needs to resolve handles. */\nexport interface DimValueContext {\n /** mm per drawing unit. */\n f: number;\n /** STYLE record by handle (DIMTXSTY 340). */\n textStyleByHandle: Map<string, StyleRecord>;\n /** BLOCK_RECORD name by handle (DIMBLK 342 / DIMBLK1 343 / DIMBLK2 344). */\n blockNameByHandle: Map<string, string>;\n}\n\n/** Dim style values plus the style's DIMSCALE — ours lives on the object. */\nexport type DimValues = Partial<Omit<DimStyle, \"id\" | \"name\">> & {\n scale?: number;\n};\n\nconst num = (v: string | undefined): number | undefined => {\n if (v === undefined) return undefined;\n const n = Number(v);\n return Number.isFinite(n) ? n : undefined;\n};\n\n/**\n * DIMSTYLE groups → the style values they set (SPARSE: only present groups,\n * so the same mapping yields a record's values and an entity's DSTYLE\n * overrides). Lengths scale to mm; DIMTSZ > 0 means oblique ticks instead\n * of arrowheads; DIMSAH picks the first-end block.\n */\nexport const dimValuesFromGroups = (\n groups: Map<number, string>,\n ctx: DimValueContext,\n): DimValues => {\n const out: DimValues = {};\n const g = (code: number) => num(groups.get(code));\n const txt = g(140);\n if (txt !== undefined && txt > 0) out.textHeight = txt * ctx.f;\n const asz = g(41);\n if (asz !== undefined && asz > 0) out.arrowSize = asz * ctx.f;\n const tsz = g(142);\n if (tsz !== undefined && tsz > 0) {\n out.arrowType = \"tick\";\n out.arrowSize = tsz * ctx.f;\n } else {\n // The block: by R12 name (5/6), by BLOCK_RECORD handle (342/343), or —\n // some writers, ours included, put the NAME in 342 — the raw value.\n const separate = g(173) === 1;\n const ref = groups.get(separate ? 343 : 342);\n const legacy = groups.get(separate ? 6 : 5);\n const blockName =\n legacy ??\n (ref !== undefined\n ? (ctx.blockNameByHandle.get(ref.toUpperCase()) ??\n (/^[0-9A-Fa-f]+$/.test(ref) ? undefined : ref))\n : undefined);\n if (blockName !== undefined) out.arrowType = arrowTypeFromBlock(blockName);\n else if (ref !== undefined) out.arrowType = \"filled\";\n }\n const gap = g(147);\n if (gap !== undefined) out.textOffset = Math.abs(gap) * ctx.f; // < 0 = boxed text\n const exo = g(42);\n if (exo !== undefined) out.extensionOffset = exo * ctx.f;\n const exe = g(44);\n if (exe !== undefined) out.extensionOvershoot = exe * ctx.f;\n const dec = g(271);\n if (dec !== undefined)\n out.precision = Math.max(0, Math.min(6, Math.round(dec)));\n const scale = g(40);\n // 0 = \"computed from the viewport\" — model space draws it at 1.\n if (scale !== undefined) out.scale = scale > 0 ? scale : 1;\n const txsty = groups.get(340);\n if (txsty !== undefined) {\n const rec = ctx.textStyleByHandle.get(txsty.toUpperCase());\n if (rec) Object.assign(out, textFaceFromRecord(rec));\n }\n return out;\n};\n\n/** AutoCAD's own defaults for groups a DIMSTYLE record leaves out (drawing\n * units — acad.dwt's inch values; metric templates write every group). */\nconst DIMSTYLE_DEFAULTS: Map<number, string> = new Map([\n [140, \"0.18\"],\n [41, \"0.18\"],\n [42, \"0.0625\"],\n [44, \"0.18\"],\n [147, \"0.09\"],\n [271, \"4\"],\n]);\n\n/**\n * DIMSTYLE record → a full dim style (mm). Groups the record leaves out fall\n * back to the HEADER's current values (`$DIMTXT`…, keyed by the same group\n * codes), then AutoCAD's defaults.\n */\nexport const dimStyleFromRecord = (\n rec: DimStyleRecord,\n header: Map<number, string>,\n ctx: DimValueContext,\n): { values: Omit<DimStyle, \"id\" | \"name\">; scale: number } => {\n const groups = new Map(DIMSTYLE_DEFAULTS);\n for (const [k, v] of header) groups.set(k, v);\n for (const [k, v] of rec.groups) groups.set(k, v);\n const { scale, ...values } = dimValuesFromGroups(groups, ctx);\n const base = DEFAULT_DIM_STYLE;\n return {\n values: {\n font: values.font ?? base.font,\n widthFactor: values.widthFactor ?? base.widthFactor,\n ...(values.bold ? { bold: true } : {}),\n ...(values.italic ? { italic: true } : {}),\n textHeight: values.textHeight ?? base.textHeight,\n textOffset: values.textOffset ?? base.textOffset,\n arrowType: values.arrowType ?? \"filled\",\n arrowSize: values.arrowSize ?? base.arrowSize,\n extensionType: \"long\",\n extensionOffset: values.extensionOffset ?? base.extensionOffset,\n extensionOvershoot: values.extensionOvershoot ?? base.extensionOvershoot,\n precision: values.precision ?? base.precision,\n },\n scale: scale ?? 1,\n };\n};\n\nconst near = (a: number, b: number) =>\n Math.abs(a - b) <= 1e-6 * Math.max(1, Math.abs(a));\n\nconst sameFace = (\n a: Pick<TextStyle, \"font\" | \"widthFactor\" | \"bold\" | \"italic\">,\n b: Pick<TextStyle, \"font\" | \"widthFactor\" | \"bold\" | \"italic\">,\n) =>\n a.font === b.font &&\n near(a.widthFactor, b.widthFactor) &&\n (a.bold ?? false) === (b.bold ?? false) &&\n (a.italic ?? false) === (b.italic ?? false);\n\nexport const sameTextStyle = (\n a: Omit<TextStyle, \"id\" | \"name\">,\n b: Omit<TextStyle, \"id\" | \"name\">,\n): boolean => sameFace(a, b) && near(a.textHeight, b.textHeight);\n\nexport const sameDimStyle = (\n a: Omit<DimStyle, \"id\" | \"name\">,\n b: Omit<DimStyle, \"id\" | \"name\">,\n): boolean =>\n sameFace(a, b) &&\n near(a.textHeight, b.textHeight) &&\n near(a.textOffset, b.textOffset) &&\n a.arrowType === b.arrowType &&\n near(a.arrowSize, b.arrowSize) &&\n a.extensionType === b.extensionType &&\n near(a.extensionOffset, b.extensionOffset) &&\n near(a.extensionOvershoot, b.extensionOvershoot) &&\n a.precision === b.precision;\n\n/**\n * The keys of `values` that differ from `base` — a sparse override, the\n * same discipline as the schema's (never bake equal values in).\n */\nexport const overrideAgainst = <T extends Record<string, unknown>>(\n base: T,\n values: Partial<T>,\n): Partial<T> => {\n const out: Partial<T> = {};\n for (const key of Object.keys(values) as (keyof T)[]) {\n const v = values[key];\n if (v === undefined) continue;\n const b = base[key];\n const equal =\n typeof v === \"number\" && typeof b === \"number\"\n ? near(v, b)\n : typeof v === \"boolean\"\n ? v === (b ?? false)\n : v === b;\n if (!equal) out[key] = v;\n }\n return out;\n};\n\n/** One merge of file styles into the document's. */\nexport interface MergedStyles<S extends { id: string; name: string }> {\n /** The document's styles after the import (existing first, then created). */\n styles: S[];\n /** DXF style name (lower-cased) → the document style id it resolves to. */\n idByName: Map<string, string>;\n created: number;\n}\n\nexport const mergeStyles = <S extends { id: string; name: string }>(\n existing: readonly S[],\n incoming: { name: string; values: Omit<S, \"id\" | \"name\"> }[],\n same: (a: Omit<S, \"id\" | \"name\">, b: Omit<S, \"id\" | \"name\">) => boolean,\n opts: { adopt: boolean; current?: string },\n): MergedStyles<S> => {\n const styles: S[] = [...existing];\n const idByName = new Map<string, string>();\n const taken = new Set(existing.map((s) => s.name.toLowerCase()));\n let created = 0;\n for (const { name, values } of incoming) {\n const key = name.toLowerCase();\n if (idByName.has(key)) continue;\n const at = styles.findIndex((s) => s.name.toLowerCase() === key);\n if (at !== -1) {\n const ex = styles[at];\n if (same(ex, values)) {\n idByName.set(key, ex.id);\n continue;\n }\n if (opts.adopt) {\n styles[at] = { ...values, id: ex.id, name: ex.name } as S;\n idByName.set(key, ex.id);\n continue;\n }\n }\n let unique = name;\n for (let i = 2; taken.has(unique.toLowerCase()); i++)\n unique = `${name}_${i}`;\n taken.add(unique.toLowerCase());\n const style = { ...values, id: crypto.randomUUID(), name: unique } as S;\n styles.push(style);\n idByName.set(key, style.id);\n created++;\n }\n // The file's current style is what its author draws new objects with —\n // on a fresh document, make it ours too.\n if (opts.adopt && opts.current) {\n const id = idByName.get(opts.current.toLowerCase());\n const at = id ? styles.findIndex((s) => s.id === id) : -1;\n if (at > 0) styles.unshift(...styles.splice(at, 1));\n }\n return { styles, idByName, created };\n};\n","// NURBS evaluation for DXF SPLINE import (docs/dxf-dwg-fidelity.md §3 row\n// 13): de Boor's algorithm in homogeneous coordinates (rational when weights\n// are given), plus an adaptive sampler that turns a curve into a polyline\n// within a chord tolerance. Pure; no model types.\n\nimport type { Vec2 } from \"./vec2\";\n\nexport interface NurbsCurve {\n degree: number;\n /** Control points, n of them. */\n controlPoints: Vec2[];\n /** Knot vector, n + degree + 1 values, non-decreasing. */\n knots: number[];\n /** One weight per control point; absent = non-rational (all 1). */\n weights?: number[];\n}\n\n/** The parameter range the curve is defined on: [knots[p], knots[n]]. */\nexport const nurbsDomain = (c: NurbsCurve): [number, number] => {\n const n = c.controlPoints.length;\n return [c.knots[c.degree], c.knots[n]];\n};\n\n/** Index of the knot span containing u (the last span for u at the end). */\nconst findSpan = (c: NurbsCurve, u: number): number => {\n const n = c.controlPoints.length;\n const p = c.degree;\n if (u >= c.knots[n]) return n - 1;\n if (u <= c.knots[p]) return p;\n let lo = p;\n let hi = n;\n let mid = (lo + hi) >> 1;\n while (u < c.knots[mid] || u >= c.knots[mid + 1]) {\n if (u < c.knots[mid]) hi = mid;\n else lo = mid;\n mid = (lo + hi) >> 1;\n }\n return mid;\n};\n\n/** The curve point at parameter u (de Boor, homogeneous). */\nexport const evaluateNurbs = (c: NurbsCurve, u: number): Vec2 => {\n const p = c.degree;\n const k = findSpan(c, u);\n // Working copy of the p+1 affected control points as (wx, wy, w).\n const d: [number, number, number][] = [];\n for (let j = 0; j <= p; j++) {\n const i = k - p + j;\n const cp = c.controlPoints[i];\n const w = c.weights?.[i] ?? 1;\n d.push([cp.x * w, cp.y * w, w]);\n }\n for (let r = 1; r <= p; r++)\n for (let j = p; j >= r; j--) {\n const i = k - p + j;\n const den = c.knots[i + p - r + 1] - c.knots[i];\n const a = den === 0 ? 0 : (u - c.knots[i]) / den;\n d[j] = [\n (1 - a) * d[j - 1][0] + a * d[j][0],\n (1 - a) * d[j - 1][1] + a * d[j][1],\n (1 - a) * d[j - 1][2] + a * d[j][2],\n ];\n }\n const [x, y, w] = d[p];\n return w === 0 ? { x, y } : { x: x / w, y: y / w };\n};\n\n/** A curve is well-formed when the knot count matches n + p + 1 and there\n * are more control points than the degree. */\nexport const isValidNurbs = (c: NurbsCurve): boolean =>\n c.degree >= 1 &&\n c.controlPoints.length > c.degree &&\n c.knots.length === c.controlPoints.length + c.degree + 1 &&\n (c.weights === undefined || c.weights.length === c.controlPoints.length) &&\n c.knots.every((v, i) => i === 0 || v >= c.knots[i - 1]);\n\n/**\n * Sample the curve into a polyline: each knot span is split until the\n * chord's midpoint lies within `tolerance` of the curve (depth-capped), so\n * straight runs stay sparse and tight bends get dense. Degenerate (zero\n * length) spans contribute nothing.\n */\nexport const sampleNurbs = (\n c: NurbsCurve,\n tolerance: number,\n maxDepth = 10,\n): Vec2[] => {\n const [u0, u1] = nurbsDomain(c);\n const out: Vec2[] = [evaluateNurbs(c, u0)];\n const push = (q: Vec2) => {\n const last = out[out.length - 1];\n if (Math.hypot(q.x - last.x, q.y - last.y) > 1e-9) out.push(q);\n };\n const refine = (a: number, pa: Vec2, b: number, pb: Vec2, depth: number) => {\n const m = (a + b) / 2;\n const pm = evaluateNurbs(c, m);\n const chord = { x: (pa.x + pb.x) / 2, y: (pa.y + pb.y) / 2 };\n const dev = Math.hypot(pm.x - chord.x, pm.y - chord.y);\n if (depth >= maxDepth || dev <= tolerance) {\n // A flat chord may still hide an S-bend symmetric about the middle:\n // keep the midpoint when the chord is long relative to the tolerance.\n if (dev > tolerance / 4) push(pm);\n push(pb);\n return;\n }\n refine(a, pa, m, pm, depth + 1);\n refine(m, pm, b, pb, depth + 1);\n };\n // Span by span, so every knot (a possible tangent break) is a vertex.\n const spans: number[] = [];\n for (let i = c.degree; i < c.controlPoints.length; i++) {\n const a = Math.max(c.knots[i], u0);\n const b = Math.min(c.knots[i + 1], u1);\n if (b > a) spans.push(a, b);\n }\n for (let i = 0; i < spans.length; i += 2) {\n const a = spans[i];\n const b = spans[i + 1];\n const pa = evaluateNurbs(c, a);\n const pb = evaluateNurbs(c, b);\n // Two levels unconditionally: a chord between span ends can be flat by\n // symmetry (a full-circle span, say) while the curve is not.\n const m = (a + b) / 2;\n const pm = evaluateNurbs(c, m);\n refine(a, pa, m, pm, 1);\n refine(m, pm, b, pb, 1);\n }\n return dropCollinear(out, tolerance / 10);\n};\n\n/** Drop interior vertices that lie within `eps` of the chord between their\n * neighbours — the unconditional span midpoints on a straight run. */\nconst dropCollinear = (pts: Vec2[], eps: number): Vec2[] => {\n if (pts.length < 3) return pts;\n const out: Vec2[] = [pts[0]];\n for (let i = 1; i < pts.length - 1; i++) {\n const a = out[out.length - 1];\n const b = pts[i + 1];\n const q = pts[i];\n const abx = b.x - a.x;\n const aby = b.y - a.y;\n const len2 = abx * abx + aby * aby;\n const t =\n len2 === 0\n ? 0\n : Math.max(\n 0,\n Math.min(1, ((q.x - a.x) * abx + (q.y - a.y) * aby) / len2),\n );\n const dist = Math.hypot(q.x - (a.x + t * abx), q.y - (a.y + t * aby));\n if (dist > eps) out.push(q);\n }\n out.push(pts[pts.length - 1]);\n return out;\n};\n\n/**\n * The clamped B-spline of the given degree that passes THROUGH `points`\n * (global curve interpolation, Piegl & Tiller A9.1: chord-length parameters,\n * averaged knots, one linear solve). A DXF SPLINE that carries only fit\n * points (74 / 11) is this curve. Fewer points than degree + 1 lower the\n * degree; two points give the segment between them.\n */\nexport const interpolateFitPoints = (\n points: Vec2[],\n degree = 3,\n): NurbsCurve | null => {\n const n = points.length;\n if (n < 2) return null;\n const p = Math.min(degree, n - 1);\n // Chord-length parameters.\n const u: number[] = [0];\n let total = 0;\n for (let i = 1; i < n; i++) {\n total += Math.hypot(\n points[i].x - points[i - 1].x,\n points[i].y - points[i - 1].y,\n );\n u.push(total);\n }\n if (total === 0) return null;\n for (let i = 0; i < n; i++) u[i] /= total;\n // Averaged knots: p+1 zeros, n−p−1 interior averages, p+1 ones.\n const knots: number[] = new Array(p + 1).fill(0);\n for (let j = 1; j <= n - p - 1; j++) {\n let s = 0;\n for (let i = j; i <= j + p - 1; i++) s += u[i];\n knots.push(s / p);\n }\n knots.push(...new Array(p + 1).fill(1));\n // Basis matrix N[i][j] = N_{j,p}(u_i), solved by Gaussian elimination\n // (n is small for a drawing's spline).\n const basisRow = (ui: number): number[] => {\n const row = new Array(n).fill(0);\n const probe: NurbsCurve = {\n degree: p,\n controlPoints: points.map(() => ({ x: 0, y: 0 })),\n knots,\n };\n // N_{j,p}(u) is the curve with a unit x at control point j.\n for (let j = 0; j < n; j++) {\n probe.controlPoints = points.map((_, k) => ({\n x: k === j ? 1 : 0,\n y: 0,\n }));\n row[j] = evaluateNurbs(probe, ui).x;\n }\n return row;\n };\n const A = u.map((ui) => basisRow(ui));\n const bx = points.map((q) => q.x);\n const by = points.map((q) => q.y);\n for (let col = 0; col < n; col++) {\n let pivot = col;\n for (let r = col + 1; r < n; r++)\n if (Math.abs(A[r][col]) > Math.abs(A[pivot][col])) pivot = r;\n if (Math.abs(A[pivot][col]) < 1e-12) return null;\n [A[col], A[pivot]] = [A[pivot], A[col]];\n [bx[col], bx[pivot]] = [bx[pivot], bx[col]];\n [by[col], by[pivot]] = [by[pivot], by[col]];\n for (let r = 0; r < n; r++) {\n if (r === col) continue;\n const k = A[r][col] / A[col][col];\n if (k === 0) continue;\n for (let c = col; c < n; c++) A[r][c] -= k * A[col][c];\n bx[r] -= k * bx[col];\n by[r] -= k * by[col];\n }\n }\n const controlPoints = points.map((_, i) => ({\n x: bx[i] / A[i][i],\n y: by[i] / A[i][i],\n }));\n return { degree: p, controlPoints, knots };\n};\n","// The filled band a constant-width polyline draws (AutoCAD's wide\n// LWPOLYLINE / TRACE look): both sides offset by half the width with miter\n// joins, as hatch loops. Straight segments only — a bulged segment's\n// offsets are arcs of other radii that need their own joins.\n\nimport type { Vec2 } from \"./vec2\";\n\nconst left = (d: Vec2): Vec2 => ({ x: -d.y, y: d.x });\nconst unit = (a: Vec2, b: Vec2): Vec2 | null => {\n const len = Math.hypot(b.x - a.x, b.y - a.y);\n return len < 1e-12 ? null : { x: (b.x - a.x) / len, y: (b.y - a.y) / len };\n};\n\n/** Miter limit: a join sharper than this falls back to a bevel-ish square\n * offset (AutoCAD draws unlimited spikes; a cap keeps imports sane). */\nconst MITER_LIMIT = 10;\n\n/**\n * Loops of the band around `points` (consecutive duplicates removed):\n * an open path gives ONE loop (left side out, right side back); a closed\n * path gives two concentric loops (even-odd fills the ring). null when the\n * path has fewer than two distinct points.\n */\nexport const polylineBand = (\n points: Vec2[],\n width: number,\n closed: boolean,\n): Vec2[][] | null => {\n const pts: Vec2[] = [];\n for (const p of points) {\n const last = pts[pts.length - 1];\n if (!last || Math.hypot(p.x - last.x, p.y - last.y) > 1e-12) pts.push(p);\n }\n if (closed && pts.length > 2) {\n const a = pts[0];\n const b = pts[pts.length - 1];\n if (Math.hypot(a.x - b.x, a.y - b.y) <= 1e-12) pts.pop();\n }\n const n = pts.length;\n if (n < 2 || !(width > 0)) return null;\n const half = width / 2;\n const isClosed = closed && n >= 3;\n // Offset direction + distance per vertex.\n const offsets: Vec2[] = pts.map((p, i) => {\n const prev = i > 0 ? pts[i - 1] : isClosed ? pts[n - 1] : null;\n const next = i < n - 1 ? pts[i + 1] : isClosed ? pts[0] : null;\n const dIn = prev ? unit(prev, p) : null;\n const dOut = next ? unit(p, next) : null;\n if (dIn && dOut) {\n const n0 = left(dIn);\n const n1 = left(dOut);\n const m = { x: n0.x + n1.x, y: n0.y + n1.y };\n const len = Math.hypot(m.x, m.y);\n if (len < 1e-9) return { x: n0.x * half, y: n0.y * half }; // reversal\n const mu = { x: m.x / len, y: m.y / len };\n const cos = mu.x * n0.x + mu.y * n0.y; // cos(half the turn)\n const s = Math.min(half / Math.max(cos, 1e-9), half * MITER_LIMIT);\n return { x: mu.x * s, y: mu.y * s };\n }\n const d = dIn ?? dOut!;\n const nn = left(d);\n return { x: nn.x * half, y: nn.y * half };\n });\n const leftSide = pts.map((p, i) => ({\n x: p.x + offsets[i].x,\n y: p.y + offsets[i].y,\n }));\n const rightSide = pts.map((p, i) => ({\n x: p.x - offsets[i].x,\n y: p.y - offsets[i].y,\n }));\n return isClosed\n ? [leftSide, rightSide]\n : [[...leftSide, ...rightSide.reverse()]];\n};\n","// DXF BLOCK → Linea block definition (dwg-dxf-compatibility.md §8). A DXF\n// block is static geometry; a Linea block module's `draw` returns children —\n// so a block's converted children, serialized as a literal, ARE a module.\n// Each INSERT with a uniform positive scale then becomes an instance\n// (pivot = insertion point, rotation, scale) instead of N loose copies:\n// the structure survives, the file stays small, and editing one definition\n// edits every placement. Children on layer `0` follow the instance's layer\n// (AutoCAD's ByBlock rule); children on other layers keep theirs. Mirrored /\n// non-uniform inserts keep the explode path.\n\nimport type { ModelObjectDto } from \"../../model/objects\";\nimport { BlockChildSchema } from \"../../extensions/blockDtos\";\n\n/** FNV-1a, 32-bit, as 8 hex chars — content identity for a definition. */\nexport const contentHash = (s: string): string => {\n let h = 0x811c9dc5;\n for (let i = 0; i < s.length; i++) {\n h ^= s.charCodeAt(i);\n h = Math.imul(h, 0x01000193);\n }\n return (h >>> 0).toString(16).padStart(8, \"0\");\n};\n\n/** A block name as an id fragment: lower-case kebab, `*U3` → `u3`. */\nexport const blockSlug = (name: string): string =>\n name\n .replace(/^\\*/, \"\")\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, \"-\")\n .replace(/^-+|-+$/g, \"\") || \"block\";\n\nconst IDENTIFIER = /^[A-Za-z_$][\\w$]*$/;\nconst jsKey = (k: string): string =>\n IDENTIFIER.test(k) ? k : JSON.stringify(k);\nconst num = (n: number): string => String(Math.round(n * 1e6) / 1e6);\nconst isNum = (v: unknown): v is number => typeof v === \"number\";\n\n/** A value as compact JavaScript: points as `[x, y]`, vertices as `[x, y]`\n * or `[x, y, bulge]` (the schemas accept both), unquoted keys. */\nconst jsValue = (value: unknown): string => {\n if (isNum(value)) return num(value);\n if (value === null || typeof value === \"boolean\") return String(value);\n if (typeof value === \"string\") return JSON.stringify(value);\n if (Array.isArray(value)) return `[${value.map(jsValue).join(\", \")}]`;\n if (typeof value === \"object\") {\n const o = value as Record<string, unknown>;\n const keys = Object.keys(o).filter((k) => o[k] !== undefined);\n if (\n keys.length === 2 &&\n keys.includes(\"x\") &&\n keys.includes(\"y\") &&\n isNum(o.x) &&\n isNum(o.y)\n )\n return `[${num(o.x)}, ${num(o.y)}]`;\n if (\n keys.length === 3 &&\n keys.includes(\"x\") &&\n keys.includes(\"y\") &&\n keys.includes(\"bulge\") &&\n isNum(o.x) &&\n isNum(o.y) &&\n isNum(o.bulge)\n )\n return o.bulge === 0\n ? `[${num(o.x)}, ${num(o.y)}]`\n : `[${num(o.x)}, ${num(o.y)}, ${num(o.bulge)}]`;\n return `{ ${keys.map((k) => `${jsKey(k)}: ${jsValue(o[k])}`).join(\", \")} }`;\n }\n return \"undefined\";\n};\n\n/** Whether leaving `key` out of `child` parses to the same value — i.e. the\n * value IS the schema default (rotation 0, scale 1, an empty leader list…)\n * and the module reads better without it. Primitive answers are memoized\n * per type / key / value. */\nconst defaultMemo = new Map<string, boolean>();\nconst isSchemaDefault = (\n child: Record<string, unknown>,\n key: string,\n): boolean => {\n const value = child[key];\n const primitive = value === null || typeof value !== \"object\";\n const memoKey = primitive\n ? `${String(child.type)}\\0${key}\\0${JSON.stringify(value)}`\n : null;\n if (memoKey !== null) {\n const hit = defaultMemo.get(memoKey);\n if (hit !== undefined) return hit;\n }\n const { [key]: _omitted, ...rest } = child;\n void _omitted;\n const parsed = BlockChildSchema.safeParse(rest);\n const result =\n parsed.success &&\n JSON.stringify((parsed.data as Record<string, unknown>)[key]) ===\n JSON.stringify(value);\n if (memoKey !== null) defaultMemo.set(memoKey, result);\n return result;\n};\n\nconst MAX_LINE = 100;\n\n/** One child as a JavaScript object literal: `type` first, `layerId` last,\n * schema-default fields dropped; multi-line (one field per line, point\n * lists wrapped) once the one-line form gets long. */\nconst childLiteral = (\n child: Record<string, unknown>,\n indent: string,\n): string => {\n const keys = Object.keys(child).filter(\n (k) => child[k] !== undefined && k !== \"type\" && k !== \"layerId\",\n );\n // Only a primitive or an empty list / record can be a schema default\n // (geometry never is) — keeps the parse-based check off the big arrays.\n const mayDefault = (v: unknown): boolean =>\n v === null ||\n typeof v !== \"object\" ||\n (Array.isArray(v) ? v.length === 0 : Object.keys(v).length === 0);\n const kept = keys.filter(\n (k) => !mayDefault(child[k]) || !isSchemaDefault(child, k),\n );\n const ordered = [\n \"type\",\n ...kept,\n ...(child.layerId !== undefined ? [\"layerId\"] : []),\n ];\n const fields = ordered.map((k) => `${jsKey(k)}: ${jsValue(child[k])}`);\n const oneLine = `{ ${fields.join(\", \")} }`;\n if (indent.length + oneLine.length <= MAX_LINE) return oneLine;\n const inner = indent + \" \";\n const lines = ordered.map((k) => {\n const v = child[k];\n // A long list (points, cells) wraps a few items per line.\n if (Array.isArray(v) && `${jsKey(k)}: ${jsValue(v)}`.length > MAX_LINE) {\n const items = v.map(jsValue);\n const rows: string[] = [];\n let row = \"\";\n for (const item of items) {\n if (row && inner.length + 2 + row.length + 2 + item.length > MAX_LINE) {\n rows.push(row);\n row = \"\";\n }\n row += (row ? \", \" : \"\") + item;\n }\n if (row) rows.push(row);\n return `${inner}${jsKey(k)}: [\\n${rows.map((r) => `${inner} ${r},`).join(\"\\n\")}\\n${inner}]`;\n }\n return `${inner}${jsKey(k)}: ${jsValue(v)}`;\n });\n return `{\\n${lines.join(\",\\n\")},\\n${indent}}`;\n};\n\n/** Children as the `draw` result literal — plain JavaScript, one child per\n * line: no ids or hidden flags; a child on one of the `inheritLayerIds`\n * (DXF layer 0, or the import's fallback layer for entities whose layer is\n * unknown) drops its layer and follows the instance; numbers rounded to\n * the nanometre. `indent` is the array's own indentation in the module. */\nexport const childrenLiteral = (\n children: readonly ModelObjectDto[],\n inheritLayerIds: ReadonlySet<string> = new Set(),\n indent = \" \",\n): string => {\n if (children.length === 0) return \"[]\";\n const inner = indent + \" \";\n const items = children.map((c) => {\n const {\n layerId,\n hidden: _h,\n ...rest\n } = c as ModelObjectDto & {\n layerId?: string;\n hidden?: boolean;\n };\n void _h;\n const child =\n layerId === undefined || inheritLayerIds.has(layerId)\n ? rest\n : { ...rest, layerId };\n return inner + childLiteral(child as Record<string, unknown>, inner);\n });\n return `[\\n${items.join(\",\\n\")},\\n${indent}]`;\n};\n\nexport interface ImportedBlockDefinition {\n id: string;\n name: string;\n source: string;\n}\n\n/**\n * The module for one DXF block: `defineBlock` with the children literal as\n * `draw`'s result. The id carries a content hash, so the same block\n * imported twice merges to one definition and a same-named block with other\n * geometry never replaces it.\n */\nexport const blockDefinitionModule = (\n blockName: string,\n children: readonly ModelObjectDto[],\n inheritLayerIds?: ReadonlySet<string>,\n /** The library name, when the block's own clashes (the id keeps the\n * block's, so a re-import still finds this module). */\n displayName?: string,\n): ImportedBlockDefinition => {\n const literal = childrenLiteral(children, inheritLayerIds);\n const id = `dxf-${blockSlug(blockName)}-${contentHash(literal)}`;\n const name = displayName ?? blockName.replace(/^\\*/, \"\");\n const source = `// Imported from DXF block ${JSON.stringify(blockName)}: static geometry,\n// ${children.length} object${children.length === 1 ? \"\" : \"s\"}. Edit freely — every instance follows.\nimport { defineBlock } from \"lineadraw\";\n\nexport default defineBlock({\n id: ${JSON.stringify(id)},\n name: ${JSON.stringify(name)},\n description: ${JSON.stringify(`Imported DXF block ${blockName}`)},\n draw: () => ${literal},\n});\n`;\n return { id, name, source };\n};\n","// The DXF text as its lines. A large file is millions of lines, and every\n// split allocates them all again: dxfToModel splits ONCE and hands the array\n// to each raw-tag scanner (scanTags, the OBJECTS readers, the entity\n// histogram), which also still take the text on their own (tests, tools).\n\n/** DXF text, or its lines already split. */\nexport type DxfSource = string | readonly string[];\n\nexport const dxfLines = (source: DxfSource): readonly string[] =>\n typeof source === \"string\" ? source.split(/\\r\\n|\\r|\\n/) : source;\n","import { dxfLines, type DxfSource } from \"./dxfLines\";\n// Import ledger — rule R8 of docs/dxf-dwg-fidelity.md: every entity in the\n// file is accounted for as imported, degraded (imported as an approximation)\n// or skipped (with a reason). dxf-parser drops entity types it has no handler\n// for BEFORE the importer sees them (ATTRIB, MLINE, WIPEOUT, …), so the\n// importer pairs its own bookkeeping with a raw `0`-group histogram of the\n// tag stream and reports the difference as skipped.\n\n/** Counts the import keeps per source entity type / reason. */\nexport interface ImportLedger {\n /** DXF entity type → entities that produced objects as-is. */\n imported: Map<string, number>;\n /** `SOURCE→what` → entities imported as an approximation (SPLINE→polyline,\n * ACAD_TABLE→exploded, …). Disjoint from `imported`. */\n degraded: Map<string, number>;\n /** Entity type or reason → entities that produced nothing. */\n skipped: Map<string, number>;\n /** Every source type a converter was handed (hidden or not). */\n seen: Set<string>;\n}\n\nexport const emptyLedger = (): ImportLedger => ({\n imported: new Map(),\n degraded: new Map(),\n skipped: new Map(),\n seen: new Set(),\n});\n\nexport const bump = (m: Map<string, number>, key: string, n = 1): void => {\n m.set(key, (m.get(key) ?? 0) + n);\n};\n\nexport const total = (m: Map<string, number>): number => {\n let n = 0;\n for (const v of m.values()) n += v;\n return n;\n};\n\n/** `0`-group values that structure the file rather than name an entity;\n * VERTEX/SEQEND are consumed by their owning POLYLINE/INSERT. */\nconst STRUCTURAL = new Set([\n \"SECTION\",\n \"ENDSEC\",\n \"BLOCK\",\n \"ENDBLK\",\n \"SEQEND\",\n \"VERTEX\",\n \"EOF\",\n]);\n\n/**\n * Raw entity histogram of what the drawing can show: the ENTITIES section\n * plus the blocks reachable from it (every `*Paper_Space*` block and the\n * closure of INSERT / ACAD_TABLE block references), each block's entities\n * counted once. Uninserted block definitions are invisible and therefore not\n * counted; a DIMENSION's geometry block is the dimension's own rendering\n * (definition points included), so it is not followed either.\n */\nexport const scanEntityHistogram = (source: DxfSource): Map<string, number> => {\n const lines = dxfLines(source);\n const entities = new Map<string, number>();\n const entityRefs = new Set<string>();\n const blocks = new Map<\n string,\n { types: Map<string, number>; refs: Set<string> }\n >();\n\n let section = \"\";\n let afterSection = false;\n let block: { types: Map<string, number>; refs: Set<string> } | null = null;\n let pendingBlockName = false;\n let entityType = \"\";\n for (let i = 0; i + 1 < lines.length; i += 2) {\n const code = lines[i].trim();\n const value = lines[i + 1].trim();\n if (code === \"0\") {\n afterSection = value === \"SECTION\";\n if (value === \"ENDSEC\") section = \"\";\n entityType = value;\n if (section === \"BLOCKS\") {\n if (value === \"BLOCK\") {\n block = { types: new Map(), refs: new Set() };\n pendingBlockName = true;\n } else if (value === \"ENDBLK\") block = null;\n else if (block && !STRUCTURAL.has(value)) bump(block.types, value);\n } else if (section === \"ENTITIES\" && !STRUCTURAL.has(value)) {\n bump(entities, value);\n }\n } else if (code === \"2\") {\n if (afterSection) {\n section = value.toUpperCase();\n afterSection = false;\n } else if (pendingBlockName && block) {\n blocks.set(value.toUpperCase(), block);\n pendingBlockName = false;\n } else if (entityType === \"INSERT\" || entityType === \"ACAD_TABLE\") {\n (block ? block.refs : entityRefs).add(value.toUpperCase());\n }\n }\n }\n\n const queue = [...entityRefs];\n for (const name of blocks.keys())\n if (name.startsWith(\"*PAPER_SPACE\")) queue.push(name);\n const visited = new Set<string>();\n while (queue.length > 0) {\n const name = queue.pop()!;\n if (visited.has(name)) continue;\n visited.add(name);\n const b = blocks.get(name);\n if (!b) continue;\n for (const [type, n] of b.types) bump(entities, type, n);\n queue.push(...b.refs);\n }\n return entities;\n};\n\n/** Report every raw type no converter saw as skipped (parser-dropped). */\nexport const reconcileLedger = (\n ledger: ImportLedger,\n raw: Map<string, number>,\n): void => {\n for (const [type, n] of raw)\n if (!ledger.seen.has(type)) bump(ledger.skipped, type, n);\n};\n","// Custom dxf-parser entity handlers for types the library doesn't ship:\n// VIEWPORT, HATCH, LEADER. Each follows the library's handler contract —\n// a class with ForEntityName + parseEntity(scanner, curr) — registered via\n// DxfParser.registerEntityHandler. dxf-parser's helpers aren't exported, so\n// the point/common-code readers are re-implemented here (same semantics).\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\n\ninterface Tag {\n code: number;\n value: any;\n}\n\ninterface Scanner {\n next(): Tag;\n rewind(): void;\n isEOF(): boolean;\n}\n\n/**\n * Read a 2D/3D point whose X group was just consumed (mirror of the\n * library's parsePoint: rewind, re-read X, expect +10 for Y, optional +20).\n */\nconst parsePoint = (scanner: Scanner): { x: number; y: number } => {\n scanner.rewind();\n let curr = scanner.next();\n let code = curr.code;\n const point = { x: curr.value as number, y: 0 };\n code += 10;\n curr = scanner.next();\n if (curr.code !== code)\n throw new Error(`Expected code ${code} for point Y, got ${curr.code}`);\n point.y = curr.value as number;\n curr = scanner.next();\n if (curr.code !== code + 10) scanner.rewind(); // no Z — let caller advance\n return point;\n};\n\n/** Common entity codes (subset of the library's checkCommonEntityProperties). */\nconst commonProp = (entity: any, curr: Tag): void => {\n switch (curr.code) {\n case 5:\n entity.handle = curr.value;\n break;\n case 6:\n entity.lineType = curr.value;\n break;\n case 8:\n entity.layer = curr.value;\n break;\n case 48:\n entity.lineTypeScale = curr.value;\n break;\n case 60:\n // Invisibility flag (1 = hidden) — chiefly dynamic-block visibility\n // states, whose inactive entities import as all-states-at-once\n // otherwise. Same field dxf-parser's built-in handlers set.\n entity.visible = curr.value === 0;\n break;\n case 62:\n entity.colorIndex = curr.value;\n break;\n case 420:\n entity.trueColor = curr.value; // 24-bit RGB (overrides the ACI index)\n break;\n case 67:\n entity.inPaperSpace = curr.value !== 0;\n break;\n }\n};\n\n/**\n * ATTRIB — an attribute VALUE following an INSERT (title-block fields). Same\n * groups as TEXT plus the tag (2) and flags (70: 1 invisible, 2 constant);\n * dxf-parser ships an ATTDEF handler but none for ATTRIB. Field names match\n * dxf-parser's TEXT so the importer's text conversion applies unchanged.\n */\nexport class AttribHandler {\n ForEntityName = \"ATTRIB\";\n\n parseEntity(scanner: Scanner, curr: Tag): any {\n const entity: any = { type: curr.value };\n curr = scanner.next();\n while (!scanner.isEOF()) {\n if (curr.code === 0) break;\n switch (curr.code) {\n case 1:\n entity.text = curr.value;\n break;\n case 2:\n entity.tag = curr.value;\n break;\n case 7:\n entity.textStyle = curr.value;\n break;\n case 10:\n entity.startPoint = parsePoint(scanner);\n break;\n case 11:\n entity.endPoint = parsePoint(scanner);\n break;\n case 40:\n entity.textHeight = curr.value;\n break;\n case 41:\n entity.xScale = curr.value;\n break;\n case 50:\n entity.rotation = curr.value;\n break;\n case 70:\n entity.invisible = ((curr.value as number) & 1) !== 0;\n entity.constant = ((curr.value as number) & 2) !== 0;\n break;\n case 72:\n entity.halign = curr.value;\n break;\n case 74:\n entity.valign = curr.value;\n break;\n default:\n commonProp(entity, curr);\n break;\n }\n curr = scanner.next();\n }\n return entity;\n }\n}\n\n/** Paper-space VIEWPORT entity (frames a model view on a layout sheet). */\nexport class ViewportHandler {\n ForEntityName = \"VIEWPORT\";\n\n parseEntity(scanner: Scanner, curr: Tag): any {\n const entity: any = { type: curr.value, frozenLayerHandles: [] };\n curr = scanner.next();\n while (!scanner.isEOF()) {\n if (curr.code === 0) break;\n switch (curr.code) {\n case 10:\n entity.center = parsePoint(scanner);\n break;\n case 12:\n entity.viewCenter = parsePoint(scanner);\n break;\n case 40:\n entity.width = curr.value;\n break;\n case 41:\n entity.height = curr.value;\n break;\n case 45:\n entity.viewHeight = curr.value;\n break;\n case 68:\n entity.status = curr.value;\n break;\n case 69:\n entity.viewportId = curr.value;\n break;\n case 90:\n entity.statusFlags = curr.value;\n break;\n case 331:\n entity.frozenLayerHandles.push(String(curr.value));\n break;\n default:\n commonProp(entity, curr);\n break;\n }\n curr = scanner.next();\n }\n return entity;\n }\n}\n\n/**\n * HATCH entity. Parses boundary paths (polyline or edge form), the pattern\n * header (name / solid flag / angle / scale), pattern definition lines, and\n * the gradient block (450 flag, 452 one-/two-color, 460 angle, 462 tint,\n * 470 name, then per color 463 value / 63 ACI / 421 RGB). Seed points are\n * consumed and ignored.\n */\nexport class HatchHandler {\n ForEntityName = \"HATCH\";\n\n parseEntity(scanner: Scanner, curr: Tag): any {\n const entity: any = {\n type: curr.value,\n boundaryPaths: [],\n patternLines: [],\n };\n let path: any = null;\n let edge: any = null;\n let patternLine: any = null;\n let mode: \"header\" | \"pattern\" | \"seeds\" | \"gradient\" = \"header\";\n let gradientColor: { aci?: number; rgb?: number } | null = null;\n\n curr = scanner.next();\n while (!scanner.isEOF()) {\n if (curr.code === 0) break;\n switch (curr.code) {\n case 2:\n entity.patternName = curr.value;\n break;\n case 450:\n mode = \"gradient\";\n if (curr.value === 1)\n entity.gradient = { colors: [], oneColor: false, angle: 0 };\n break;\n case 452:\n if (entity.gradient) entity.gradient.oneColor = curr.value === 1;\n break;\n case 460:\n if (entity.gradient) entity.gradient.angle = curr.value; // radians\n break;\n case 462:\n if (entity.gradient) entity.gradient.tint = curr.value;\n break;\n case 470:\n if (entity.gradient) entity.gradient.name = String(curr.value);\n break;\n case 463:\n if (entity.gradient) {\n gradientColor = {};\n entity.gradient.colors.push(gradientColor);\n }\n break;\n case 63:\n if (gradientColor) gradientColor.aci = curr.value;\n break;\n case 421:\n if (gradientColor) gradientColor.rgb = curr.value;\n break;\n case 70:\n entity.solid = curr.value === 1;\n break;\n case 75:\n entity.hatchStyle = curr.value;\n break;\n case 76:\n entity.patternType = curr.value;\n break;\n case 52:\n entity.patternAngle = curr.value;\n break;\n case 41:\n entity.patternScale = curr.value;\n break;\n case 92:\n // New boundary path; bit 2 = polyline form.\n path = {\n flags: curr.value,\n isPolyline: (curr.value & 2) !== 0,\n vertices: [],\n edges: [],\n };\n edge = null;\n entity.boundaryPaths.push(path);\n break;\n case 72:\n if (!path) break;\n if (path.isPolyline) path.hasBulge = curr.value !== 0;\n else {\n // New edge; 1 line, 2 arc, 3 ellipse, 4 spline. A spline edge\n // carries its own groups: 94 degree, 73 rational, 74 periodic,\n // 40 knots, 10 control points, 42 weights, 11 fit points.\n edge = { kind: curr.value, points: [] };\n if (curr.value === 4) {\n edge.knots = [];\n edge.weights = [];\n edge.fitPoints = [];\n }\n path.edges.push(edge);\n }\n break;\n case 73:\n if (path?.isPolyline) path.closed = curr.value !== 0;\n else if (edge?.kind === 4) edge.rational = curr.value !== 0;\n else if (edge) edge.ccw = curr.value !== 0;\n break;\n case 74:\n if (edge?.kind === 4) edge.periodic = curr.value !== 0;\n break;\n case 94:\n if (edge?.kind === 4) edge.degree = curr.value;\n break;\n case 330:\n // Inside a boundary path: a source-boundary object handle (97\n // counts them) — not the entity's owner.\n if (!path) commonProp(entity, curr);\n break;\n case 78:\n mode = \"pattern\";\n break;\n case 98:\n mode = \"seeds\";\n break;\n case 53:\n if (mode === \"pattern\") {\n patternLine = { angle: curr.value };\n entity.patternLines.push(patternLine);\n }\n break;\n case 43:\n if (patternLine) patternLine.baseX = curr.value;\n break;\n case 44:\n if (patternLine) patternLine.baseY = curr.value;\n break;\n case 45:\n if (patternLine) patternLine.offsetX = curr.value;\n break;\n case 46:\n if (patternLine) patternLine.offsetY = curr.value;\n break;\n case 79:\n if (patternLine) patternLine.dashes = [];\n break;\n case 49:\n if (patternLine) (patternLine.dashes ??= []).push(curr.value);\n break;\n case 10: {\n const p = parsePoint(scanner);\n if (mode === \"seeds\" || mode === \"gradient\") break; // seed points — ignore\n if (path?.isPolyline) path.vertices.push({ ...p, bulge: 0 });\n else if (edge) edge.points.push(p);\n break;\n }\n case 11: {\n const p = parsePoint(scanner);\n if (edge?.kind === 4) edge.fitPoints.push(p);\n else if (edge) edge.end = p;\n break;\n }\n case 42:\n if (path?.isPolyline && path.vertices.length > 0)\n path.vertices[path.vertices.length - 1].bulge = curr.value;\n else if (edge?.kind === 4) edge.weights.push(curr.value);\n break;\n case 40:\n if (edge?.kind === 4) edge.knots.push(curr.value);\n else if (edge) edge.r40 = curr.value;\n break;\n case 50:\n if (edge) edge.startAngle = curr.value;\n break;\n case 51:\n if (edge) edge.endAngle = curr.value;\n break;\n default:\n commonProp(entity, curr);\n break;\n }\n curr = scanner.next();\n }\n return entity;\n }\n}\n\n/** One cell of an ACAD_TABLE's legacy AcDbTable payload. */\nexport interface AcadTableCell {\n /** 171: 1 = text, 2 = block. */\n type: number;\n /** 175 / 176: merge extent on the anchor cell. */\n cols: number;\n rows: number;\n /** 173: covered by a merge. */\n merged?: boolean;\n /** 170: attachment 1–9 (TL TC TR / ML MC MR / BL BC BR). */\n alignment?: number;\n /** 7: text style name. */\n style?: string;\n /** 140: text height. */\n height?: number;\n /** 145: text rotation (radians). */\n rotation?: number;\n /** 1 (+ 3 chunks): MTEXT content. */\n text?: string;\n /** 302: formatted display string (numeric cells' only text). */\n display?: string;\n}\n\n/** The table structure ACAD_TABLE carries next to its *T block. */\nexport interface AcadTableData {\n rows: number;\n cols: number;\n rowHeights: number[];\n colWidths: number[];\n /** 40: horizontal cell margin. */\n margin?: number;\n cells: AcadTableCell[];\n}\n\n/**\n * ACAD_TABLE entity. A table's rendered geometry (grid lines + cell text)\n * lives in an anonymous *T block named by the AcDbBlockReference subclass\n * (group 2, insertion point 10, optional direction vector 11) — the importer\n * explodes that block like an INSERT. The AcDbTable payload that follows\n * REUSES the same group codes for per-cell data (2 = cell text, 62 = cell\n * color overrides, …), so all capturing stops at its subclass marker and the\n * rest is skimmed to the entity boundary.\n */\nexport class AcadTableHandler {\n ForEntityName = \"ACAD_TABLE\";\n\n parseEntity(scanner: Scanner, curr: Tag): any {\n const entity: any = { type: curr.value };\n let inTableData = false;\n // The legacy AcDbTable payload (still written by current AutoCAD next to\n // its TABLECONTENT objects): table-level groups first, then one run per\n // cell starting at 171. Codes 91/92/140 recur INSIDE cells with other\n // meanings, so table-level values are only read before the first cell.\n const table: AcadTableData = {\n rows: 0,\n cols: 0,\n rowHeights: [],\n colWidths: [],\n cells: [],\n };\n let cell: AcadTableCell | null = null;\n let textChunks = \"\";\n curr = scanner.next();\n while (!scanner.isEOF()) {\n if (curr.code === 0) break;\n if (curr.code === 100 && curr.value === \"AcDbTable\") inTableData = true;\n if (inTableData && curr.code !== 100) {\n const num = () => Number(curr.value);\n if (curr.code === 171) {\n cell = { type: num(), cols: 1, rows: 1 };\n table.cells.push(cell);\n textChunks = \"\";\n } else if (!cell) {\n if (curr.code === 91) table.rows = num();\n else if (curr.code === 92) table.cols = num();\n else if (curr.code === 141) table.rowHeights.push(num());\n else if (curr.code === 142) table.colWidths.push(num());\n else if (curr.code === 40) table.margin = num();\n else if (curr.code === 11) {\n // Horizontal direction → rotation (degrees, INSERT-style). Only\n // a sane unit-ish vector counts: DWG transcodes write this\n // group uninitialized (1e59 / 1e-308 garbage) for some tables,\n // which used to rotate them arbitrarily.\n const dir = parsePoint(scanner);\n const len = Math.hypot(dir.x, dir.y);\n if (Number.isFinite(len) && len > 0.5 && len < 2)\n entity.rotation = (Math.atan2(dir.y, dir.x) * 180) / Math.PI;\n }\n } else if (curr.code === 175) cell.cols = num();\n else if (curr.code === 176) cell.rows = num();\n else if (curr.code === 173) cell.merged = num() !== 0;\n else if (curr.code === 170) cell.alignment = num();\n else if (curr.code === 7) cell.style ??= String(curr.value);\n else if (curr.code === 140) cell.height ??= num();\n else if (curr.code === 145) cell.rotation ??= num();\n // Long cell text arrives as 3-chunks then the final 1 (MTEXT style);\n // later 1s (ACVALUE copies) are ignored.\n else if (curr.code === 3) textChunks += String(curr.value);\n else if (curr.code === 1 && cell.text === undefined)\n cell.text = textChunks + String(curr.value ?? \"\");\n // The formatted display string: the only text a NUMERIC cell has\n // (its value rides as 90 = type / 91 = number, no group 1).\n else if (curr.code === 302 && cell.display === undefined)\n cell.display = String(curr.value ?? \"\");\n }\n if (!inTableData) {\n switch (curr.code) {\n case 2:\n entity.name = curr.value;\n break;\n case 10:\n entity.position = parsePoint(scanner);\n break;\n case 11: {\n // Horizontal direction vector → rotation (degrees, like INSERT's\n // group 50, so convertInsert consumes it unchanged). Same\n // sanity gate as the table-level 11.\n const dir = parsePoint(scanner);\n const len = Math.hypot(dir.x, dir.y);\n if (Number.isFinite(len) && len > 0.5 && len < 2)\n entity.rotation = (Math.atan2(dir.y, dir.x) * 180) / Math.PI;\n break;\n }\n default:\n commonProp(entity, curr);\n break;\n }\n }\n curr = scanner.next();\n }\n if (table.rows > 0 && table.cols > 0) entity.table = table;\n return entity;\n }\n}\n\n/** Plain LEADER entity (arrow polyline; any annotation stays separate). */\nexport class LeaderHandler {\n ForEntityName = \"LEADER\";\n\n parseEntity(scanner: Scanner, curr: Tag): any {\n const entity: any = { type: curr.value, vertices: [] };\n curr = scanner.next();\n while (!scanner.isEOF()) {\n if (curr.code === 0) break;\n switch (curr.code) {\n case 3:\n entity.styleName = curr.value;\n break;\n case 10:\n entity.vertices.push(parsePoint(scanner));\n break;\n case 71:\n entity.arrowheadFlag = curr.value;\n break;\n case 72:\n entity.pathType = curr.value;\n break;\n default:\n commonProp(entity, curr);\n break;\n }\n curr = scanner.next();\n }\n return entity;\n }\n}\n\n/**\n * MULTILEADER entity. Parses the CONTEXT_DATA block's mtext content and\n * text/arrow sizes, plus every LEADER node's junction and LEADER_LINE vertex\n * runs. Marker tags: 300/301 context, 302/303 leader, 304/305 leader line\n * (304 doubles as the mtext content code — disambiguated by value).\n */\nexport class MultiLeaderHandler {\n ForEntityName = \"MULTILEADER\";\n\n parseEntity(scanner: Scanner, curr: Tag): any {\n const entity: any = { type: curr.value, leaders: [] };\n let inContext = false;\n let leader: any = null;\n let line: any = null;\n\n curr = scanner.next();\n while (!scanner.isEOF()) {\n if (curr.code === 0) break;\n switch (curr.code) {\n case 300:\n inContext = true;\n break;\n case 301:\n inContext = false;\n break;\n case 302:\n leader = { junction: null, lines: [] };\n entity.leaders.push(leader);\n break;\n case 303:\n leader = null;\n break;\n case 304:\n if (curr.value === \"LEADER_LINE{\" && leader) {\n line = [];\n leader.lines.push(line);\n } else if (inContext && !leader && entity.content === undefined) {\n entity.content = curr.value;\n }\n break;\n case 305:\n line = null;\n break;\n case 40:\n if (inContext && !leader) entity.overallScale = curr.value;\n break;\n case 41:\n if (inContext && !leader) entity.textHeight = curr.value;\n break;\n case 140:\n if (inContext && !leader) entity.arrowSize = curr.value;\n break;\n case 171:\n // Context-level text attachment point (1–9, MTEXT-style).\n if (inContext && !leader) entity.attachment = curr.value;\n break;\n case 12: {\n const p = parsePoint(scanner);\n if (inContext && !leader) entity.textLocation = p;\n break;\n }\n case 10: {\n const p = parsePoint(scanner);\n if (line) line.push(p);\n else if (leader) leader.junction = p;\n break;\n }\n default:\n commonProp(entity, curr);\n break;\n }\n curr = scanner.next();\n }\n return entity;\n }\n}\n\n/**\n * MLINE — a multiline (walls): N parallel element lines, one per offset of\n * its MLINESTYLE, along a vertex path. dxf-parser has no handler. Per vertex\n * the entity stores the vertex (11), the segment direction (12), the MITER\n * direction (13) and, per element, its parameters (74 count, 41 values):\n * the FIRST parameter is the distance along the miter from the vertex to\n * that element's line — AutoCAD's own justification + miter arithmetic, so\n * the importer needs no style to place the elements. Fill parameters\n * (75/42) are skipped.\n */\nexport class MlineHandler {\n ForEntityName = \"MLINE\";\n\n parseEntity(scanner: Scanner, curr: Tag): any {\n const entity: any = {\n type: curr.value,\n styleName: \"\",\n styleHandle: \"\",\n scale: 1,\n justification: 0,\n flags: 0,\n elementCount: 0,\n vertices: [],\n };\n let vertex: any = null;\n let element: { params: number[] } | null = null;\n let inFill = false;\n curr = scanner.next();\n while (!scanner.isEOF()) {\n if (curr.code === 0) break;\n switch (curr.code) {\n case 2:\n entity.styleName = String(curr.value);\n break;\n case 340:\n entity.styleHandle = String(curr.value).toUpperCase();\n break;\n case 40:\n entity.scale = curr.value;\n break;\n case 70:\n entity.justification = curr.value;\n break;\n case 71:\n entity.flags = curr.value;\n break;\n case 73:\n entity.elementCount = curr.value;\n break;\n case 10:\n entity.start = parsePoint(scanner);\n break;\n case 11:\n vertex = { point: parsePoint(scanner), elements: [] };\n entity.vertices.push(vertex);\n element = null;\n inFill = false;\n break;\n case 12:\n if (vertex) vertex.direction = parsePoint(scanner);\n break;\n case 13:\n if (vertex) vertex.miter = parsePoint(scanner);\n break;\n case 74:\n if (vertex) {\n element = { params: [] };\n vertex.elements.push(element);\n inFill = false;\n }\n break;\n case 41:\n if (element && !inFill) element.params.push(curr.value);\n break;\n case 75:\n inFill = true;\n break;\n default:\n commonProp(entity, curr);\n break;\n }\n curr = scanner.next();\n }\n return entity;\n }\n}\n\n/**\n * TRACE — a filled quadrilateral with SOLID's exact groups (10–13, in\n * SOLID's 1-2-4-3 vertex order) and no dxf-parser handler. Field names match\n * dxf-parser's SOLID so the importer's SOLID conversion applies unchanged.\n */\nexport class TraceHandler {\n ForEntityName = \"TRACE\";\n\n parseEntity(scanner: Scanner, curr: Tag): any {\n const entity: any = { type: curr.value, points: [] };\n curr = scanner.next();\n while (!scanner.isEOF()) {\n if (curr.code === 0) break;\n switch (curr.code) {\n case 10:\n case 11:\n case 12:\n case 13:\n entity.points[curr.code - 10] = parsePoint(scanner);\n break;\n default:\n commonProp(entity, curr);\n break;\n }\n curr = scanner.next();\n }\n return entity;\n }\n}\n","import { dxfLines, type DxfSource } from \"./dxfLines\";\n// Minimal OBJECTS-section reader. dxf-parser skips the whole section, but\n// LAYOUT objects live there — without them imported paper spaces would lose\n// their names, tab order, and sheet sizes. This scans the raw tag stream and\n// extracts just the LAYOUT records.\n\nexport interface DxfLayoutInfo {\n name: string;\n tabOrder: number;\n /** Plot paper size, mm (PlotSettings groups 44/45). */\n paperWidth?: number;\n paperHeight?: number;\n /** BLOCK_RECORD handle of the owning space (uppercased). */\n blockRecordHandle?: string;\n}\n\nexport const parseLayoutObjects = (source: DxfSource): DxfLayoutInfo[] => {\n const lines = dxfLines(source);\n const layouts: DxfLayoutInfo[] = [];\n\n let inObjects = false;\n let prevZeroValue = \"\"; // value of the last (0, …) tag\n let current: DxfLayoutInfo | null = null;\n let subclass = \"\";\n\n const commit = () => {\n if (current && current.name) layouts.push(current);\n current = null;\n subclass = \"\";\n };\n\n for (let i = 0; i + 1 < lines.length; i += 2) {\n const code = parseInt(lines[i], 10);\n if (Number.isNaN(code)) continue;\n const value = lines[i + 1].trim();\n\n if (code === 0) {\n commit();\n if (value === \"ENDSEC\" && inObjects) break;\n if (inObjects && value === \"LAYOUT\") current = { name: \"\", tabOrder: 0 };\n prevZeroValue = value;\n continue;\n }\n if (code === 2 && prevZeroValue === \"SECTION\") {\n inObjects = value === \"OBJECTS\";\n continue;\n }\n if (!current) continue;\n\n if (code === 100) {\n subclass = value;\n continue;\n }\n if (subclass === \"AcDbPlotSettings\") {\n if (code === 44) current.paperWidth = parseFloat(value) || undefined;\n else if (code === 45)\n current.paperHeight = parseFloat(value) || undefined;\n } else if (subclass === \"AcDbLayout\") {\n if (code === 1) current.name = value;\n else if (code === 71) current.tabOrder = parseInt(value, 10) || 0;\n else if (code === 330 && !current.blockRecordHandle)\n current.blockRecordHandle = value.toUpperCase();\n }\n }\n commit();\n\n return layouts.sort((a, b) => a.tabOrder - b.tabOrder);\n};\n\n/** One MLINESTYLE element: its offset from the multiline's zero line\n * (positive = left of the drawing direction) and optional own color /\n * line type (62 = 256 ByLayer, 6 = BYLAYER). */\nexport interface DxfMlineStyleElement {\n offset: number;\n colorIndex?: number;\n lineType?: string;\n}\n\nexport interface DxfMlineStyle {\n handle?: string;\n name: string;\n /** Group 70: 1 fill, 2 miters, 16 / 256 start / end square caps,\n * 32 / 512 inner arcs, 64 / 1024 round caps. */\n flags: number;\n elements: DxfMlineStyleElement[];\n}\n\n/** MLINESTYLE objects (OBJECTS section), by upper-cased handle and by\n * lower-cased name — a DWG transcode can zero the entity's style handle\n * while keeping the name. */\nexport const parseMlineStyles = (\n source: DxfSource,\n): {\n byHandle: Map<string, DxfMlineStyle>;\n byName: Map<string, DxfMlineStyle>;\n} => {\n const lines = dxfLines(source);\n const byHandle = new Map<string, DxfMlineStyle>();\n const byName = new Map<string, DxfMlineStyle>();\n let inObjects = false;\n let prevZeroValue = \"\";\n let current: DxfMlineStyle | null = null;\n let element: DxfMlineStyleElement | null = null;\n let afterCount = false;\n\n const commit = () => {\n if (current && current.name) {\n if (current.handle) byHandle.set(current.handle, current);\n byName.set(current.name.toLowerCase(), current);\n }\n current = null;\n element = null;\n afterCount = false;\n };\n\n for (let i = 0; i + 1 < lines.length; i += 2) {\n const code = parseInt(lines[i], 10);\n if (Number.isNaN(code)) continue;\n const value = lines[i + 1].trim();\n if (code === 0) {\n commit();\n if (value === \"ENDSEC\" && inObjects) break;\n if (inObjects && value === \"MLINESTYLE\")\n current = { name: \"\", flags: 0, elements: [] };\n prevZeroValue = value;\n continue;\n }\n if (code === 2 && prevZeroValue === \"SECTION\") {\n inObjects = value === \"OBJECTS\";\n continue;\n }\n if (!current) continue;\n switch (code) {\n case 5:\n current.handle = value.toUpperCase();\n break;\n case 2:\n current.name = value;\n break;\n case 70:\n current.flags = parseInt(value, 10) || 0;\n break;\n case 71:\n afterCount = true;\n break;\n case 49:\n element = { offset: parseFloat(value) || 0 };\n current.elements.push(element);\n break;\n case 62:\n // Before 71 it is the fill color; after, the element's.\n if (afterCount && element) element.colorIndex = parseInt(value, 10);\n break;\n case 6:\n if (element) element.lineType = value;\n break;\n }\n }\n commit();\n return { byHandle, byName };\n};\n","// References: LINKED files drawn in place (docs/references.md). The document\n// holds only the `reference` record (format, placement, `source`); the file's\n// bytes live host-side, reached through `ReferenceFileAccess`. Every format\n// loads into the same shape — a `ReferenceContent`, the file's model space as\n// Linea objects — so painting, snapping and binding never care what the file\n// was. This module is pure: loading bytes and caching content is the host's.\n\nimport type { AABB } from \"../geometry/bounds\";\nimport {\n addPointToBounds,\n emptyBounds,\n isEmptyBounds,\n} from \"../geometry/bounds\";\nimport type { Vec2 } from \"../geometry/vec2\";\nimport type { LineaDocument } from \"../model/document\";\nimport { emptyDocument } from \"../model/defaults\";\nimport { hashAsset } from \"../model/assets\";\nimport { buildSnapEntry } from \"../snap/buildEntry\";\nimport type { TextMeasurer } from \"../paint/textMetrics\";\nimport type { ArcGeom } from \"../geometry/arcs\";\nimport type { EllipseGeom } from \"../geometry/ellipse\";\nimport type { SnapPointType } from \"../snap/types\";\nimport { unionBounds } from \"../geometry/bounds\";\nimport { dxfToModel } from \"../import/dxf/importDxf\";\nimport {\n mirrorObject,\n rotateObject,\n scaleObjectUniform,\n translateObject,\n} from \"../transform\";\nimport {\n REFERENCE_FORMATS,\n type ModelObject,\n type ReferenceFormat,\n type ReferenceObject,\n type ReferenceSource,\n} from \"../model/objects\";\nimport type { LayoutModelContext } from \"../paint/layoutPaint\";\nimport type { Mat2x3 } from \"../paint/sink\";\n\n/**\n * How a host reaches the files references point at (calculus's seam,\n * verbatim). Desktop: real paths. A browser can't read paths — it keeps a\n * copy of the bytes under `source.cacheKey` instead (editor-side store).\n */\nexport interface ReferenceFileAccess {\n /** Native picker filtered to the reference formats; absolute paths, or\n * null on cancel. */\n pick(): Promise<string[] | null>;\n /** A file's bytes by its STORED path (relative paths resolve against the\n * document's folder). Rejects when missing. */\n read(path: string): Promise<Uint8Array>;\n /** Size + mtime of a stored path (reload detection); null when missing. */\n stat(path: string): Promise<{ size: number; mtimeMs: number } | null>;\n /** The path to store for a picked absolute path: relative (POSIX\n * separators) when inside the document's folder, else absolute. */\n toStoredPath(absolutePath: string): Promise<string>;\n /** Stored path → absolute path (display, cache keys). */\n toAbsolutePath(storedPath: string): Promise<string>;\n}\n\n/** A loaded reference: the file's model space as Linea objects (ids\n * prefixed per reference — see `contentFromDocument`) plus its bounds. */\nexport interface ReferenceContent extends LayoutModelContext {\n /** Content bounds in FILE coordinates (empty for an empty file). */\n bounds: AABB;\n /** PDF: how many pages the file has (the page field's range). */\n pageCount?: number;\n /**\n * Snap geometry precomputed in FILE coordinates (off the main thread —\n * see `referenceSnapOf`); absent → derived from `objects`. A raster PDF\n * carries its page's VECTOR geometry here: it paints the image and snaps\n * to the lines.\n */\n snap?: ReferenceSnap;\n}\n\n/** File-space snap primitives, each tagged with its layer id (so the\n * reference's hidden layers still filter them). */\nexport interface ReferenceSnap {\n points: { p: Vec2; type: SnapPointType; layer: string }[];\n segments: { a: Vec2; b: Vec2; chord?: boolean; layer: string }[];\n arcs: (ArcGeom & { layer: string })[];\n ellipses: (EllipseGeom & { layer: string })[];\n}\n\n/** A document's snap geometry in its own coordinates (references inside it\n * excluded — they resolve per placement). Heavy for big files: hosts run it\n * off the main thread with the file's conversion. */\nexport const referenceSnapOf = (\n doc: Pick<\n LineaDocument,\n \"objects\" | \"dimStyles\" | \"textStyles\" | \"blockDefinitions\"\n >,\n measure: TextMeasurer,\n): ReferenceSnap => {\n const snap: ReferenceSnap = {\n points: [],\n segments: [],\n arcs: [],\n ellipses: [],\n };\n const byId = new Map(doc.objects.map((o) => [o.id, o]));\n const ctx = {\n dimStyles: doc.dimStyles,\n textStyles: doc.textStyles,\n blockDefinitions: doc.blockDefinitions,\n resolveObject: (id: string) => byId.get(id),\n measure,\n };\n for (const o of doc.objects) {\n if (o.type === \"reference\") continue;\n const e = buildSnapEntry(o, ctx);\n const layer = o.layerId;\n for (const p of e.points) snap.points.push({ ...p, layer });\n for (const s of e.segments) snap.segments.push({ ...s, layer });\n for (const a of e.arcs) snap.arcs.push({ ...a, layer });\n for (const el of e.ellipses ?? []) snap.ellipses.push({ ...el, layer });\n }\n return snap;\n};\n\n/** A nested reference's source as seen from the HOST document: a relative\n * path inside a referenced file is relative to THAT file's folder. */\nexport const rebaseReferenceSource = (\n child: ReferenceSource,\n parent: ReferenceSource,\n): ReferenceSource => {\n if (child.kind === \"url\" || parent.kind === \"url\") return child;\n if (/^([A-Za-z]:[\\\\/]|[\\\\/])/.test(child.path)) return child;\n const folder = parent.path.replace(/\\\\/g, \"/\").replace(/\\/?[^/]*$/, \"\");\n return { ...child, path: folder ? `${folder}/${child.path}` : child.path };\n};\n\n/** The reference format a file name implies, or null. */\nexport const referenceFormatOf = (fileName: string): ReferenceFormat | null => {\n const ext = /\\.([^./\\\\]+)$/.exec(fileName)?.[1]?.toLowerCase();\n if (ext === \"jpeg\") return \"jpg\";\n if (ext === \"lineadraw\") return \"linea\";\n return REFERENCE_FORMATS.find((f) => f === ext) ?? null;\n};\n\n/** The file-picker `accept` list for references. */\nexport const REFERENCE_ACCEPT = REFERENCE_FORMATS.flatMap((f) =>\n f === \"jpg\"\n ? [\".jpg\", \".jpeg\"]\n : f === \"linea\"\n ? [\".linea\", \".lineadraw\"]\n : [`.${f}`],\n).join(\",\");\n\n/** File coordinates → the host document: rotation + uniform scale about the\n * file origin (mirrored: the file flips LEFT-RIGHT first, x → −x — what\n * \"mirror\" means to a user), then `position`. */\nexport const referenceTransform = (ref: ReferenceObject): Mat2x3 => {\n const s = ref.scale;\n const m = ref.mirrored ? -1 : 1;\n const c = Math.cos(ref.rotation);\n const n = Math.sin(ref.rotation);\n return [m * s * c, m * s * n, -s * n, s * c, ref.position.x, ref.position.y];\n};\n\nexport const applyMat = (m: Mat2x3, p: Vec2): Vec2 => ({\n x: m[0] * p.x + m[2] * p.y + m[4],\n y: m[1] * p.x + m[3] * p.y + m[5],\n});\n\n/** The four corners of a file-space box placed by `m`. */\nexport const placedCorners = (m: Mat2x3, b: AABB): Vec2[] =>\n [\n { x: b.minX, y: b.minY },\n { x: b.maxX, y: b.minY },\n { x: b.maxX, y: b.maxY },\n { x: b.minX, y: b.maxY },\n ].map((p) => applyMat(m, p));\n\n/** The placed (host) bounds of a file-space box. */\nexport const placedBounds = (m: Mat2x3, b: AABB): AABB => {\n const out = emptyBounds();\n if (isEmptyBounds(b)) return out;\n for (const p of placedCorners(m, b)) addPointToBounds(out, p);\n return out;\n};\n\n/**\n * A document's model space as reference content. Object ids are prefixed\n * with the reference's id (and block object-reference inputs with them), so\n * per-id caches — block evaluation, its errors and dependencies — never mix a\n * referenced file's objects with the host's own, even when the file is a\n * copy of the drawing that references it.\n */\nexport const contentFromDocument = (\n doc: LineaDocument,\n refId: string,\n bounds: AABB = emptyBounds(),\n): ReferenceContent => {\n const prefix = `ref:${refId}:`;\n const objects: ModelObject[] = doc.objects.map((o) =>\n o.type === \"block\"\n ? {\n ...o,\n id: prefix + o.id,\n inputs: o.inputs.map((v) => (typeof v === \"string\" ? prefix + v : v)),\n }\n : { ...o, id: prefix + o.id },\n );\n const byId = new Map(objects.map((o) => [o.id, o]));\n return {\n objects,\n layers: doc.layers,\n dimStyles: doc.dimStyles,\n textStyles: doc.textStyles,\n blockDefinitions: doc.blockDefinitions,\n lineTypes: doc.lineTypes,\n hatchPatterns: doc.hatchPatterns,\n assets: doc.assets,\n resolveObject: (id) => byId.get(id),\n bounds,\n };\n};\n\n/** A fresh document holding DTOs (ids assigned) — what non-.linea formats\n * convert into before `contentFromDocument`. */\nexport const documentWithObjects = (\n build: (doc: LineaDocument) => {\n objects: readonly Record<string, unknown>[];\n layers?: LineaDocument[\"layers\"];\n textStyles?: LineaDocument[\"textStyles\"];\n dimStyles?: LineaDocument[\"dimStyles\"];\n lineTypes?: LineaDocument[\"lineTypes\"];\n hatchPatterns?: LineaDocument[\"hatchPatterns\"];\n blockDefinitions?: LineaDocument[\"blockDefinitions\"];\n },\n): LineaDocument => {\n const doc = emptyDocument();\n const {\n objects,\n layers,\n textStyles,\n dimStyles,\n lineTypes,\n hatchPatterns,\n blockDefinitions,\n } = build(doc);\n if (layers) doc.layers = layers;\n if (textStyles) doc.textStyles = textStyles;\n if (dimStyles) doc.dimStyles = dimStyles;\n if (lineTypes) doc.lineTypes = lineTypes;\n if (hatchPatterns) doc.hatchPatterns = hatchPatterns;\n if (blockDefinitions) doc.blockDefinitions = blockDefinitions;\n doc.objects = objects.map(\n (o) =>\n ({ ...o, id: crypto.randomUUID() }) as LineaDocument[\"objects\"][number],\n );\n return doc;\n};\n\n/** DXF text → a document (units converted to mm by the importer; blocks\n * come exploded, layouts are ignored — a reference shows model space). */\nexport const documentFromDxf = (text: string): LineaDocument =>\n documentWithObjects((doc) => {\n const result = dxfToModel(text, {\n existingLayers: doc.layers.map((l) => ({ id: l.id, name: l.name })),\n defaultLayerId: doc.layers[0].id,\n existingTextStyles: doc.textStyles,\n existingDimStyles: doc.dimStyles,\n existingLineTypes: doc.lineTypes,\n existingHatchPatterns: doc.hatchPatterns,\n adoptStyles: true,\n });\n return {\n objects: result.objects,\n layers: [...doc.layers, ...result.newLayers],\n textStyles: result.textStyles,\n dimStyles: result.dimStyles,\n lineTypes: result.lineTypes,\n hatchPatterns: result.hatchPatterns,\n blockDefinitions: [\n ...doc.blockDefinitions,\n ...result.newBlockDefinitions,\n ],\n };\n });\n\n/** A content object as native geometry where the reference draws it —\n * Bind's per-object step: mirror (left-right), scale about the file origin,\n * rotate, then move to the insertion point (the order referenceTransform\n * composes). */\nexport const placeReferenceObject = (\n obj: ModelObject,\n ref: ReferenceObject,\n): ModelObject => {\n const origin = { x: 0, y: 0 };\n let o = ref.mirrored ? mirrorObject(obj, origin, { x: 0, y: 1 }) : obj;\n if (ref.scale !== 1) o = scaleObjectUniform(o, ref.scale);\n if (ref.rotation !== 0) o = rotateObject(o, origin, ref.rotation);\n return translateObject(o, ref.position);\n};\n\n/** A document holding one image (bottom-left at the origin) — the content\n * of a PNG/JPEG reference or a raster PDF page. */\nexport const documentFromImage = (\n dataUrl: string,\n widthMm: number,\n heightMm: number,\n): LineaDocument => {\n const doc = emptyDocument();\n const assetId = hashAsset(dataUrl);\n doc.assets = { [assetId]: dataUrl };\n doc.objects = [\n {\n id: \"image\",\n type: \"image\",\n layerId: doc.layers[0].id,\n assetId,\n origin: { x: 0, y: 0 },\n width: widthMm,\n height: heightMm,\n rotation: 0,\n },\n ];\n return doc;\n};\n\n/** A PNG's / JPEG's pixel size from its header (no decoder — Node has\n * none); null when the bytes aren't one. */\nexport const imagePixelSize = (\n b: Uint8Array,\n): { width: number; height: number } | null => {\n const u32 = (i: number) =>\n ((b[i] << 24) | (b[i + 1] << 16) | (b[i + 2] << 8) | b[i + 3]) >>> 0;\n const u16 = (i: number) => (b[i] << 8) | b[i + 1];\n if (b[0] === 0x89 && b[1] === 0x50 && b[2] === 0x4e && b[3] === 0x47)\n return { width: u32(16), height: u32(20) }; // IHDR\n if (b[0] !== 0xff || b[1] !== 0xd8) return null;\n // JPEG: walk the segments to the first start-of-frame (SOF0..SOF15\n // except DHT/JPG/DAC), whose payload holds height then width.\n for (let i = 2; i + 9 < b.length;) {\n if (b[i] !== 0xff) return null;\n const marker = b[i + 1];\n const len = u16(i + 2);\n if (\n marker >= 0xc0 &&\n marker <= 0xcf &&\n marker !== 0xc4 &&\n marker !== 0xc8 &&\n marker !== 0xcc\n )\n return { width: u16(i + 7), height: u16(i + 5) };\n i += 2 + len;\n }\n return null;\n};\n\n/** Content bounds in file coordinates (text measured by `measure`); the\n * origin for an empty file, so a frame still has a corner. */\nexport const measureContentBounds = (\n content: Omit<ReferenceContent, \"bounds\">,\n measure: TextMeasurer,\n): AABB => {\n const ctx = {\n dimStyles: content.dimStyles,\n textStyles: content.textStyles,\n blockDefinitions: content.blockDefinitions,\n lineTypes: content.lineTypes,\n hatchPatterns: content.hatchPatterns,\n resolveObject: content.resolveObject,\n resolveReference: content.resolveReference,\n measure,\n };\n let bounds = emptyBounds();\n for (const o of content.objects) {\n const b = buildSnapEntry(o, ctx).bounds;\n if (!isEmptyBounds(b)) bounds = unionBounds(bounds, b);\n }\n if (isEmptyBounds(bounds)) addPointToBounds(bounds, { x: 0, y: 0 });\n return bounds;\n};\n\n/** Host → file coordinates (the inverse of referenceTransform) — clip\n * rectangles are picked in the drawing and stored in the file's frame. */\nexport const toReferenceCoords = (ref: ReferenceObject, p: Vec2): Vec2 => {\n const dx = p.x - ref.position.x;\n const dy = p.y - ref.position.y;\n const c = Math.cos(-ref.rotation);\n const n = Math.sin(-ref.rotation);\n const x = (c * dx - n * dy) / ref.scale;\n const y = (n * dx + c * dy) / ref.scale;\n return { x: ref.mirrored ? -x : x, y };\n};\n\n/** A segment clipped to a box (Liang–Barsky), or null when outside. */\nexport const clipSegment = (\n a: Vec2,\n b: Vec2,\n box: AABB,\n): [Vec2, Vec2] | null => {\n let t0 = 0;\n let t1 = 1;\n const dx = b.x - a.x;\n const dy = b.y - a.y;\n const edges: [number, number][] = [\n [-dx, a.x - box.minX],\n [dx, box.maxX - a.x],\n [-dy, a.y - box.minY],\n [dy, box.maxY - a.y],\n ];\n for (const [p, q] of edges) {\n if (p === 0) {\n if (q < 0) return null;\n } else {\n const t = q / p;\n if (p < 0) t0 = Math.max(t0, t);\n else t1 = Math.min(t1, t);\n if (t0 > t1) return null;\n }\n }\n return [\n { x: a.x + t0 * dx, y: a.y + t0 * dy },\n { x: a.x + t1 * dx, y: a.y + t1 * dy },\n ];\n};\n","import type { Layer } from \"../model/document\";\nimport type { LineType } from \"../model/lineTypes\";\nimport type { ModelObject } from \"../model/objects\";\nimport { dashForLineType, scaleDash } from \"./lineTypes\";\n\nexport interface ResolvedStyle {\n color: string;\n widthMm: number;\n /** Dash pattern in mm (undefined = continuous). */\n dashMm?: number[];\n /** Paint opacity 0..1 (undefined = opaque). */\n opacity?: number;\n}\n\nconst FALLBACK_STYLE: ResolvedStyle = {\n color: \"#e8e8e8\",\n widthMm: 0.25,\n};\n\n/** Resolve byLayer color/lineweight/linetype through the object's layer. */\nexport const resolveStyle = (\n obj: ModelObject,\n layers: readonly Layer[],\n /** The document's own line types (resolved ahead of the catalogue). */\n lineTypes?: readonly LineType[],\n): ResolvedStyle => {\n const layer = layers.find((l) => l.id === obj.layerId);\n const widthMm = obj.lineWidth ?? layer?.lineWidth ?? FALLBACK_STYLE.widthMm;\n return {\n color: obj.color ?? layer?.color ?? FALLBACK_STYLE.color,\n widthMm,\n // Dash patterns are defined per 1 mm of line width (ISO 128 style —\n // pattern legibility tracks stroke weight), so the resolved lineweight\n // scales them; lineTypeScale (CELTSCALE) multiplies on top.\n dashMm: scaleDash(\n dashForLineType(obj.lineType ?? layer?.lineType, lineTypes),\n widthMm * (obj.lineTypeScale ?? 1),\n ),\n opacity: obj.opacity ?? layer?.opacity,\n };\n};\n","// Drawing far from the origin. Survey-grid drawings (a masterplan in\n// ETRS-GK coordinates: ~2·10¹⁰ mm) lose all precision once their coordinates\n// reach a float32 pipeline — the canvas, PDF and SVG viewers — which at that\n// magnitude can only step in metres. `rebaseSink` subtracts a nearby origin\n// in float64 BEFORE anything reaches the sink, so the sink only ever sees\n// small numbers (\"relative to eye\", as CAD/GIS viewers do). The data stays\n// absolute; only what is drawn is shifted.\n//\n// The shift applies at the TOP level only: a pushed transform (a reference's\n// placement, a viewport's projection) maps its own space into the shifted\n// one by having the shift folded into its translation, and coordinates\n// inside it pass through untouched.\n\nimport type { Vec2 } from \"../geometry/vec2\";\nimport type { GeometrySink, Mat2x3 } from \"./sink\";\n\nexport const rebaseSink = (sink: GeometrySink, origin: Vec2): GeometrySink => {\n if (origin.x === 0 && origin.y === 0) return sink;\n let depth = 0;\n const at = (p: Vec2): Vec2 =>\n depth === 0 ? { x: p.x - origin.x, y: p.y - origin.y } : p;\n return {\n beginPath: () => sink.beginPath(),\n moveTo: (p) => sink.moveTo(at(p)),\n lineTo: (p) => sink.lineTo(at(p)),\n bezierTo: (c1, c2, end) => sink.bezierTo(at(c1), at(c2), at(end)),\n arc: (center, r, a0, a1, ccw) => sink.arc(at(center), r, a0, a1, ccw),\n ellipse: (center, rx, ry, rot, a0, a1) =>\n sink.ellipse(at(center), rx, ry, rot, a0, a1),\n closePath: () => sink.closePath(),\n stroke: (s) => sink.stroke(s),\n fill: (f) =>\n sink.fill(\n f.gradient\n ? {\n ...f,\n gradient: {\n ...f.gradient,\n from: at(f.gradient.from),\n to: at(f.gradient.to),\n },\n }\n : f,\n ),\n text: (t) => sink.text({ ...t, anchor: at(t.anchor) }),\n image: (i) => sink.image({ ...i, origin: at(i.origin) }),\n measureText: (text, h, font, wf) => sink.measureText(text, h, font, wf),\n pushTransform: (m: Mat2x3) => {\n sink.pushTransform(\n depth === 0\n ? [m[0], m[1], m[2], m[3], m[4] - origin.x, m[5] - origin.y]\n : m,\n );\n depth++;\n },\n popTransform: () => {\n depth = Math.max(0, depth - 1);\n sink.popTransform();\n },\n pushClipRect: (r) => {\n const p = at({ x: r.x, y: r.y });\n sink.pushClipRect({ ...r, x: p.x, y: p.y });\n },\n popClip: () => sink.popClip(),\n beginObject: sink.beginObject\n ? (id, layer) => sink.beginObject!(id, layer)\n : undefined,\n endObject: sink.endObject ? () => sink.endObject!() : undefined,\n };\n};\n","// A reference paints its file's content (resolved by the host — see\n// PaintEnv.resolveReference) through the reference's placement, each object\n// styled by the FILE's layers; a file that isn't loaded (missing, loading)\n// paints a dashed frame of its last known extent with its name.\n\nimport type { ModelObject, ReferenceObject } from \"../../model/objects\";\nimport { placedCorners, referenceTransform } from \"../../reference/reference\";\nimport { resolveStyle } from \"../style\";\nimport { matMultiply, type GeometrySink } from \"../sink\";\nimport { rebaseSink } from \"../rebaseSink\";\nimport { isEmptyBounds } from \"../../geometry/bounds\";\nimport { paintObject, type PaintEnv } from \"./index\";\n\nexport const paintReference = (\n obj: ReferenceObject,\n sink: GeometrySink,\n env: PaintEnv,\n): void => {\n if (obj.hidden) return;\n const content = env.resolveReference?.(obj) ?? null;\n const m = referenceTransform(obj);\n if (!content) {\n paintReferenceFrame(obj, sink, env);\n return;\n }\n const hidden = new Set(obj.hiddenLayers);\n const shown = new Map(\n content.layers.map((l) => [l.id, l.visible && !hidden.has(l.name)]),\n );\n const mapColor = env.mapColor ?? ((c: string) => c);\n const fade = env.style.opacity ?? 1;\n // Draw the content relative to its own centre: a survey-grid file placed\n // back near the origin would otherwise hand the sink its ~10¹⁰-mm file\n // coordinates and a ~−10¹⁰ placement, cancelled in float32 (distortion).\n // The shift is folded into the placement here, in float64 (rebaseSink).\n const b = content.bounds;\n const c = isEmptyBounds(b)\n ? { x: 0, y: 0 }\n : { x: (b.minX + b.maxX) / 2, y: (b.minY + b.maxY) / 2 };\n sink.pushTransform(matMultiply(m, [1, 0, 0, 1, c.x, c.y]));\n const out = rebaseSink(sink, c);\n const clip = obj.clip;\n if (clip)\n out.pushClipRect({\n x: clip.minX,\n y: clip.minY,\n w: clip.maxX - clip.minX,\n h: clip.maxY - clip.minY,\n });\n for (const child of content.objects) {\n if (shown.get(child.layerId) === false) continue;\n const own = resolveStyle(\n child as ModelObject,\n content.layers,\n content.lineTypes,\n );\n paintObject(child, out, {\n // A highlight paints the whole reference in one style.\n style: env.forceStyle\n ? env.style\n : {\n ...own,\n color: mapColor(own.color),\n opacity: (own.opacity ?? 1) * fade,\n },\n forceStyle: env.forceStyle,\n // The FILE's own resources — nested references resolve through its\n // resolver too (the host loads them relative to that file,\n // depth-limited, cycle-safe).\n ...content,\n cache: env.cache,\n mapColor: env.mapColor,\n });\n }\n if (clip) sink.popClip();\n sink.popTransform();\n};\n\n/** Not loaded: a dashed frame over the last known extent (or a small square\n * at the insertion point) and the reference's name. */\nconst paintReferenceFrame = (\n obj: ReferenceObject,\n sink: GeometrySink,\n env: PaintEnv,\n): void => {\n const s = 5;\n const corners = obj.extent\n ? placedCorners(referenceTransform(obj), obj.extent)\n : [\n { x: obj.position.x, y: obj.position.y },\n { x: obj.position.x + s, y: obj.position.y },\n { x: obj.position.x + s, y: obj.position.y + s },\n { x: obj.position.x, y: obj.position.y + s },\n ];\n sink.beginPath();\n sink.moveTo(corners[0]);\n for (const c of corners.slice(1)) sink.lineTo(c);\n sink.closePath();\n sink.stroke({\n color: env.style.color,\n widthMm: env.style.widthMm,\n dashMm: [1.5, 1],\n opacity: env.style.opacity,\n });\n sink.text({\n text: obj.name,\n anchor: corners[0],\n heightMm: 2.5,\n rotation: obj.rotation,\n hAlign: \"left\",\n vAlign: \"bottom\",\n color: env.style.color,\n opacity: env.style.opacity,\n });\n};\n","import type { LineType } from \"../../model/lineTypes\";\nimport type { Layer, LineaDocument } from \"../../model/document\";\nimport { documentObjectResolver } from \"../../model/objectLookup\";\nimport type { DocumentHatchPattern } from \"../../model/hatchPatterns\";\nimport type {\n DimStyle,\n ModelObject,\n ModelObjectType,\n ReferenceObject,\n TextStyle,\n} from \"../../model/objects\";\nimport type { ReferenceContent } from \"../../reference/reference\";\nimport type { GeometrySink } from \"../sink\";\nimport type { ResolvedStyle } from \"../style\";\nimport type { PaintGeometryCache } from \"../paintCache\";\nimport { paintLine } from \"./line\";\nimport { paintPoint } from \"./point\";\nimport { paintPolyline } from \"./polyline\";\nimport { paintCircle } from \"./circle\";\nimport { paintArc } from \"./arc\";\nimport { paintEllipse } from \"./ellipse\";\nimport { paintHatch } from \"./hatch\";\nimport { paintText } from \"./text\";\nimport { paintDimension } from \"./dimension\";\nimport { paintBlockInstance } from \"./block\";\nimport { paintViewport } from \"./viewport\";\nimport { paintImage } from \"./image\";\nimport { paintTable } from \"./table\";\nimport { paintReference } from \"./reference\";\n\n/**\n * The document half of a paint environment: everything a painter resolves\n * by id or name against the document. The array fields are REQUIRED so a\n * caller can't drop one by accident (an omitted `hatchPatterns` silently\n * painted the catalogue fallback); consumers without a document pass [].\n * `LayoutModelContext` and `ReferenceContent` extend it, so a paint env\n * spreads either one whole.\n */\nexport interface DocumentPaintResources {\n /** Document layers — a block child that names its OWN layer hides with\n * it (its color still follows the instance unless it sets one). */\n layers: readonly Layer[];\n /** Document dimension styles — dimensions pick theirs by styleId. */\n dimStyles: readonly DimStyle[];\n /** Document text styles — texts pick theirs by styleId. */\n textStyles: readonly TextStyle[];\n /** Document-defined line types / hatch patterns, resolved by NAME ahead\n * of the built-in catalogue (block children and hatch fills). */\n lineTypes: readonly LineType[];\n hatchPatterns: readonly DocumentHatchPattern[];\n /**\n * The document's block definitions — the block painter evaluates instance\n * children against these. The kernel holds no store, so they are threaded\n * through the paint environment (mirrors buildEntry's SnapGeometryContext).\n */\n blockDefinitions: readonly string[];\n /**\n * Document-wide object lookup for block object-reference inputs (see\n * BlockObjectResolver). Optional: without it, referenced inputs evaluate\n * as null (consumers that cannot reach a document, e.g. style previews).\n */\n resolveObject?: (id: string) => ModelObject | undefined;\n /**\n * The document's embedded assets (hash → data URL) — the image painter\n * resolves `assetId` against these. Optional: consumers that can't show\n * images (or documents without any) paint a crossed placeholder frame.\n */\n assets?: Readonly<Record<string, string>>;\n /**\n * A reference's loaded file content (docs/references.md) — the host owns\n * loading and caching. Absent, or null for a file not loaded (yet), → the\n * reference paints as a dashed frame.\n */\n resolveReference?: (ref: ReferenceObject) => ReferenceContent | null;\n}\n\n/** The paint resources of a whole document — what a headless renderer\n * (SDK render, thumbnails, export) hands its painters. Hosts with their own\n * object/reference resolvers override those two fields. Picked, not\n * spread: a whole document would carry its `objects` over the caller's. */\nexport const documentPaintResources = (\n doc: LineaDocument,\n): DocumentPaintResources => ({\n layers: doc.layers,\n dimStyles: doc.dimStyles,\n textStyles: doc.textStyles,\n lineTypes: doc.lineTypes,\n hatchPatterns: doc.hatchPatterns,\n blockDefinitions: doc.blockDefinitions,\n assets: doc.assets,\n resolveObject: documentObjectResolver(doc),\n});\n\n/** Environment passed to painters — style already resolved by the caller. */\nexport interface PaintEnv extends DocumentPaintResources {\n style: ResolvedStyle;\n /**\n * Optional cache for camera-independent derived geometry (hatch lines,\n * dimension geometry, text blocks). Supply one per long-lived consumer\n * (the canvas renderer keeps one across frames); omit for one-shot paints.\n */\n cache?: PaintGeometryCache;\n /**\n * Paint everything in `style` verbatim, ignoring per-child style overrides\n * (block children carrying their own color/lineType). Selection/hover\n * highlights set this so a block highlights as one uniform silhouette.\n */\n forceStyle?: boolean;\n /** The output medium's color map (print palettes): content painted with\n * its OWN styles (a reference's file) maps through it too. */\n mapColor?: (color: string) => string;\n}\n\nexport type Painter = (\n obj: ModelObject,\n sink: GeometrySink,\n env: PaintEnv,\n) => void;\n\nconst painters: Record<ModelObjectType, Painter> = {\n line: paintLine as Painter,\n point: paintPoint as Painter,\n polyline: paintPolyline as Painter,\n circle: paintCircle as Painter,\n arc: paintArc as Painter,\n ellipse: paintEllipse as Painter,\n hatch: paintHatch as Painter,\n text: paintText as Painter,\n dimension: paintDimension as Painter,\n block: paintBlockInstance as Painter,\n viewport: paintViewport as Painter,\n image: paintImage as Painter,\n table: paintTable as Painter,\n reference: paintReference as Painter,\n // Screen-fixed editor chrome — painted by the editor's canvas renderer\n // only, never by the shared path (exports don't show it).\n comment: () => {},\n};\n\nexport const paintObject = (\n obj: ModelObject,\n sink: GeometrySink,\n env: PaintEnv,\n): void => {\n painters[obj.type]?.(obj, sink, env);\n};\n","// Headless SVG thumbnail of a block module — the same dry-run render the\n// editor's BlockPreview shows, emitted as a self-contained <svg> for\n// marketplace manifests (`lineadraw manifest` bakes it into thumbnailSvg;\n// the palette/browser display it without running any module code).\n// Deterministic by construction: stand-in picks are fixed, text measures\n// via the approximate table, and the SvgSink rounds coordinates — so\n// manifest generation stays a byte-stable operation.\n\nimport type { LineType } from \"../model/lineTypes\";\nimport type { DocumentHatchPattern } from \"../model/hatchPatterns\";\nimport type { Block } from \"../model/objects\";\nimport { DEFAULT_DIM_STYLE, DEFAULT_TEXT_STYLE } from \"../model/objects\";\nimport { isEmptyBounds } from \"../geometry/bounds\";\nimport { SvgSink } from \"../export/svg/svgSink\";\nimport { approximateTextMeasurer } from \"../paint/textMeasurer\";\nimport { paintObject } from \"../paint/painters\";\nimport { buildSnapEntry } from \"../snap/buildEntry\";\nimport {\n blockScriptId,\n dryRunBlockInputs,\n dryRunObjectResolver,\n ensureScriptTranspiler,\n getBlockError,\n getBlockMeta,\n} from \"./evalBlock\";\n\nexport interface BlockThumbnailOptions {\n /** Extra module sources nested instances resolve against (the repo's or\n * catalog's other blocks); ids the module itself provides win. */\n definitions?: readonly string[];\n /** Skip (return null) when the SVG exceeds this many characters — a\n * manifest should stay a light index, not an asset bundle. */\n maxChars?: number;\n /** The document's own line types / hatch patterns, when the block's\n * children reference them by name (the catalogue needs no help). */\n lineTypes?: readonly LineType[];\n hatchPatterns?: readonly DocumentHatchPattern[];\n}\n\n/**\n * Render a block module to a small standalone SVG (viewBox-sized, strokes\n * in `currentColor` so the host UI's theme colors it). Returns null for\n * blocks with nothing visible to draw or oversized output; throws when the\n * module itself fails its dry run (same errors testBlockDefinition\n * reports).\n */\nexport const renderBlockThumbnailSvg = async (\n script: string,\n {\n definitions = [],\n maxChars = 20_000,\n lineTypes,\n hatchPatterns,\n }: BlockThumbnailOptions = {},\n): Promise<string | null> => {\n await ensureScriptTranspiler();\n const defId = getBlockMeta(script).id;\n const inputs = await dryRunBlockInputs(script);\n\n // The module shadows any same-id definition; extras fill remaining ids.\n const defs = [script];\n const present = new Set([defId]);\n for (const extra of definitions) {\n const id = blockScriptId(extra);\n if (id === undefined || present.has(id)) continue;\n present.add(id);\n defs.push(extra);\n }\n\n const instance: Block = {\n type: \"block\",\n id: `thumbnail:${defId}`,\n layerId: \"thumbnail\",\n definitionId: defId,\n rotation: 0,\n scale: 1,\n params: {},\n inputs,\n };\n const env = {\n layers: [],\n dimStyles: [DEFAULT_DIM_STYLE],\n textStyles: [DEFAULT_TEXT_STYLE],\n lineTypes: lineTypes ?? [],\n hatchPatterns: hatchPatterns ?? [],\n blockDefinitions: defs,\n // Object-reference inputs preview against the dry-run stand-in object.\n resolveObject: dryRunObjectResolver,\n };\n const entry = buildSnapEntry(instance, {\n ...env,\n measure: approximateTextMeasurer,\n });\n const error = getBlockError(instance.id);\n if (error !== undefined && error !== null) throw new Error(error);\n // A no-geometry block collapses to a point at the pivot (buildSnapEntry\n // still yields degenerate 0×0 bounds there) — nothing worth a thumbnail.\n const bw = entry.bounds.maxX - entry.bounds.minX;\n const bh = entry.bounds.maxY - entry.bounds.minY;\n if (isEmptyBounds(entry.bounds) || (bw === 0 && bh === 0)) return null;\n\n const sink = new SvgSink({ measure: approximateTextMeasurer });\n paintObject(instance, sink, {\n ...env,\n // currentColor: the thumbnail inherits the surrounding UI text color,\n // so one render works in light and dark hosts alike. Children with\n // authored colors keep them. Stroke width scales with the extent —\n // thumbnails display at ~icon size, where a fixed mm width would turn\n // a meters-wide block into invisible hairlines.\n style: { color: \"currentColor\", widthMm: Math.max(bw, bh) / 56 },\n });\n const pad = Math.max(((bw + bh) / 2) * 0.06, 1);\n const svg = sink.toSvg(entry.bounds, pad);\n return svg.length > maxChars ? null : svg;\n};\n","// Block-library merging over raw module sources. A \"library file\" is just a\n// `.ts`/`.js` module (one module = one block); moving blocks between\n// documents is moving text. PURE — the browser download, file pickers,\n// toasts, and the store merge stay editor-side; this module owns the\n// collision invariants:\n// · a source already present verbatim is skipped\n// · an id match with DIFFERENT content REPLACES that module in place —\n// the id IS the block's identity, so importing it again is an update\n// (instances keep their definitionId and re-evaluate with the new source)\n// · a name clash with a DIFFERENT block is suffixed \"(imported)\" via a\n// literal rewrite of `export const name` (best-effort — an unrewritable\n// name is left alone)\n// · a module that does not compile/validate is rejected with its error\n// Callers must await `ensureScriptTranspiler()` first — merging compiles.\n\nimport { blockScriptId, getBlockMetaResult, type BlockMeta } from \"./evalBlock\";\n\n/**\n * Replace the string literal of `export const <name> = \"…\"` — or, for a\n * defineBlock module, the `<name>: \"…\"` property at the TOP level of the\n * spec object (nested occurrences like a params entry's `name:` are never\n * touched). Null when neither form has a rewritable literal\n * (dynamic/computed) — callers must treat that as \"don't touch\", never\n * mangle. Also used by the editor's Duplicate.\n */\nexport const rewriteExportString = (\n script: string,\n exportName: string,\n value: string,\n): string | null => {\n const re = new RegExp(\n `(export\\\\s+const\\\\s+${exportName}\\\\s*=\\\\s*)(\"(?:[^\"\\\\\\\\]|\\\\\\\\.)*\"|'(?:[^'\\\\\\\\]|\\\\\\\\.)*')`,\n );\n if (re.test(script)) return script.replace(re, `$1${JSON.stringify(value)}`);\n return rewriteSpecProperty(script, exportName, value);\n};\n\n/**\n * Rewrite `<prop>: \"…\"` at brace depth 1 of the `defineBlock({...})` /\n * `defineCommand({...})` (or plain default-exported object) spec. A small\n * scanner rather than a bare regex: strings, template literals, and comments\n * are skipped wholesale, and depth tracking keeps nested literals (params\n * entries also have a `name:`) out of reach. Best-effort — anything\n * unrecognized returns null.\n */\nconst rewriteSpecProperty = (\n script: string,\n prop: string,\n value: string,\n): string | null => {\n const call = script.search(\n /define(?:Block|Command)\\s*\\(|export\\s+default\\s*\\{/,\n );\n if (call === -1) return null;\n const open = script.indexOf(\"{\", call);\n if (open === -1) return null;\n const propRe = new RegExp(\n `^${prop}\\\\s*:\\\\s*(\"(?:[^\"\\\\\\\\]|\\\\\\\\.)*\"|'(?:[^'\\\\\\\\]|\\\\\\\\.)*')`,\n );\n let depth = 0;\n for (let i = open; i < script.length; i++) {\n const ch = script[i];\n if (ch === '\"' || ch === \"'\" || ch === \"`\") {\n i++;\n while (i < script.length && script[i] !== ch) {\n if (script[i] === \"\\\\\") i++;\n i++;\n }\n continue;\n }\n if (ch === \"/\" && script[i + 1] === \"/\") {\n while (i < script.length && script[i] !== \"\\n\") i++;\n continue;\n }\n if (ch === \"/\" && script[i + 1] === \"*\") {\n i += 2;\n while (i < script.length && !(script[i] === \"*\" && script[i + 1] === \"/\"))\n i++;\n i++;\n continue;\n }\n if (ch === \"{\" || ch === \"(\" || ch === \"[\") {\n depth++;\n continue;\n }\n if (ch === \"}\" || ch === \")\" || ch === \"]\") {\n depth--;\n if (depth === 0) return null; // spec object ended without the prop\n continue;\n }\n if (depth !== 1 || !/[A-Za-z_$]/.test(ch)) continue;\n const prev = i > 0 ? script[i - 1] : \"\";\n const m = /[A-Za-z0-9_$.]/.test(prev) ? null : propRe.exec(script.slice(i));\n if (m) {\n const start = i + m[0].length - m[1].length;\n return (\n script.slice(0, start) +\n JSON.stringify(value) +\n script.slice(start + m[1].length)\n );\n }\n // Skip the rest of this identifier so mid-word positions aren't tested.\n while (i + 1 < script.length && /[A-Za-z0-9_$]/.test(script[i + 1])) i++;\n }\n return null;\n};\n\nexport interface MergeModulesResult<M> {\n /** The full library to install (replacements in place + new appended). */\n merged: string[];\n /** Modules added as new entries (possibly renamed), with their meta. */\n added: { script: string; meta: M }[];\n /** Modules that replaced an existing entry with the same exported id. */\n replaced: { script: string; meta: M }[];\n /** How many incoming modules were already present verbatim. */\n skipped: number;\n /** Modules that could not be imported, with the reason. */\n rejected: { script: string; error: string }[];\n}\n\nexport type MergeBlockModulesResult = MergeModulesResult<BlockMeta>;\n\n/** How a module family (blocks, commands) derives identity from a source. */\nexport interface ScriptModuleAccess<M extends { id: string; name: string }> {\n /** Best-effort exported id (compiled meta or a source-level scan). */\n idOf(script: string): string | undefined;\n /** Non-throwing compile + meta validation. */\n metaOf(script: string): { ok: true; meta: M } | { ok: false; error: string };\n}\n\n/**\n * Merge incoming module sources into an existing library — the shared\n * engine under block AND command import (same collision invariants for\n * both; see the header comment).\n */\nexport const mergeScriptModules = <M extends { id: string; name: string }>(\n existing: readonly string[],\n incoming: readonly string[],\n access: ScriptModuleAccess<M>,\n): MergeModulesResult<M> => {\n const merged = [...existing];\n const indexById = new Map<string, number>();\n merged.forEach((s, i) => {\n const id = access.idOf(s);\n if (id !== undefined && !indexById.has(id)) indexById.set(id, i);\n });\n // Parallel name list (undefined = module does not compile).\n const names: (string | undefined)[] = merged.map((s) => {\n const r = access.metaOf(s);\n return r.ok ? r.meta.name : undefined;\n });\n const nameTaken = (name: string, except: number | undefined): boolean =>\n names.some((n, i) => n === name && i !== except);\n\n const added: MergeModulesResult<M>[\"added\"] = [];\n const replaced: MergeModulesResult<M>[\"replaced\"] = [];\n const rejected: MergeModulesResult<M>[\"rejected\"] = [];\n let skipped = 0;\n\n for (const original of incoming) {\n if (merged.includes(original)) {\n skipped++; // identical module already present\n continue;\n }\n let script = original;\n let result = access.metaOf(script);\n if (!result.ok) {\n rejected.push({ script: original, error: result.error });\n continue;\n }\n\n // Same exported id → the incoming module replaces that entry (its slot's\n // own name is not a clash, so a same-name update keeps its name).\n const replaceIdx = indexById.get(result.meta.id);\n\n // Name collision with a different block → suffix (best-effort rewrite).\n if (nameTaken(result.meta.name, replaceIdx)) {\n let name = result.meta.name;\n while (nameTaken(name, replaceIdx)) name = `${name} (imported)`;\n const renamed = rewriteExportString(script, \"name\", name);\n if (renamed !== null) script = renamed;\n }\n\n if (script !== original) {\n result = access.metaOf(script);\n if (!result.ok) {\n // A rewrite broke the module — should not happen; keep the original\n // out rather than installing something unparseable.\n rejected.push({ script: original, error: result.error });\n continue;\n }\n }\n\n if (replaceIdx !== undefined) {\n merged[replaceIdx] = script;\n names[replaceIdx] = result.meta.name;\n replaced.push({ script, meta: result.meta });\n } else {\n indexById.set(result.meta.id, merged.length);\n names.push(result.meta.name);\n merged.push(script);\n added.push({ script, meta: result.meta });\n }\n }\n\n return { merged, added, replaced, skipped, rejected };\n};\n\n/** Merge incoming block module sources into an existing library. */\nexport const mergeBlockModules = (\n existing: readonly string[],\n incoming: readonly string[],\n): MergeBlockModulesResult =>\n mergeScriptModules(existing, incoming, {\n idOf: blockScriptId,\n metaOf: getBlockMetaResult,\n });\n","// Marketplaces, headless (docs/block-marketplace.md): a marketplace is a\n// git repo (or a local folder) carrying a CI-generated catalog of block and\n// command modules. This module is the half every host shares — the config\n// record and its identity, the manifest schema, catalog + source fetching\n// with caches, search, install status against a document's vendored\n// modules, and the dependency-closure plan an install needs. What a host\n// adds is I/O (`fetch` is the platform's; a folder reader comes from the\n// desktop host or Node's fs) and where the module sources end up (the\n// editor's stores, a LocalDrawing's ops). The editor's\n// `marketplace/client.ts` and `LocalDrawing` both sit on `MarketplaceClient`.\n\nimport { z } from \"zod\";\nimport {\n blockDefinitionExists,\n blockScriptId,\n getBlockMetaResult,\n} from \"../extensions/evalBlock\";\nimport {\n commandScriptId,\n getCommandMetaResult,\n} from \"../extensions/commandModules\";\nimport {\n apiHeaders,\n manifestUrls,\n parseMarketplaceSpec,\n rawToApiUrl,\n sourcePathUrl,\n} from \"./github\";\n\n// ---- Configuration ----------------------------------------------------------\n\n/** One configured marketplace. `kind` discriminates so new source types\n * are one more variant; identity (for dedupe/remove/reorder) is\n * `marketplaceKey`. The built-in public collection is always present\n * exactly once (`normalizeMarketplaces`). Tokens never enter a document. */\nexport const MarketplaceConfigSchema = z.discriminatedUnion(\"kind\", [\n z.object({ kind: z.literal(\"builtin\") }),\n z.object({\n kind: z.literal(\"github\"),\n /** `owner/repo` or `owner/repo@branch`. */\n spec: z.string(),\n /** Fine-grained PAT for a private repo (read-only Contents). */\n token: z.string().optional(),\n }),\n /** A local directory with the same generated manifest layout; the folder\n * key is opaque to core (an absolute path on the desktop and in Node). */\n z.object({ kind: z.literal(\"folder\"), folder: z.string() }),\n]);\nexport type MarketplaceConfig = z.infer<typeof MarketplaceConfigSchema>;\n\nexport const BUILTIN_MARKETPLACE_SPEC = \"lineadraw/lineadraw@main\";\nexport const BUILTIN_MARKETPLACE_NAME = \"Linea public collection\";\n\nexport const marketplaceKey = (m: MarketplaceConfig): string =>\n m.kind === \"builtin\"\n ? \"builtin\"\n : m.kind === \"github\"\n ? `github:${m.spec}`\n : `folder:${m.folder}`;\n\n/** Drop duplicate keys (first occurrence wins) and guarantee exactly one\n * built-in entry — appended LAST when missing, so user sources outrank the\n * public collection by default. */\nexport const normalizeMarketplaces = (\n list: readonly MarketplaceConfig[],\n): MarketplaceConfig[] => {\n const seen = new Set<string>();\n const out: MarketplaceConfig[] = [];\n for (const m of list) {\n const key = marketplaceKey(m);\n if (seen.has(key)) continue;\n seen.add(key);\n out.push(m);\n }\n if (!seen.has(\"builtin\")) out.push({ kind: \"builtin\" });\n return out;\n};\n\n/** Display name before (or without) a loaded manifest header. */\nexport const marketplaceLabel = (m: MarketplaceConfig): string =>\n m.kind === \"builtin\"\n ? BUILTIN_MARKETPLACE_NAME\n : m.kind === \"github\"\n ? m.spec\n : // Folder basename beats the full path in a header.\n (m.folder.split(/[\\\\/]/).filter(Boolean).pop() ?? m.folder);\n\n/** What agents and the SDK see of a configured marketplace — never the\n * token itself. */\nexport interface MarketplaceInfo {\n key: string;\n kind: MarketplaceConfig[\"kind\"];\n label: string;\n spec?: string;\n folder?: string;\n hasToken: boolean;\n}\n\nexport const marketplaceInfo = (m: MarketplaceConfig): MarketplaceInfo => ({\n key: marketplaceKey(m),\n kind: m.kind,\n label: marketplaceLabel(m),\n ...(m.kind === \"github\" ? { spec: m.spec } : {}),\n ...(m.kind === \"folder\" ? { folder: m.folder } : {}),\n hasToken: m.kind === \"github\" && m.token !== undefined,\n});\n\n/** Does `needle` name this marketplace — by key, spec, folder or label? */\nexport const matchesMarketplace = (\n m: MarketplaceConfig,\n needle: string,\n): boolean => {\n const info = marketplaceInfo(m);\n return [info.key, info.spec, info.folder, info.label].some(\n (v) => v !== undefined && v.toLowerCase() === needle.trim().toLowerCase(),\n );\n};\n\n// ---- Catalog ----------------------------------------------------------------\n\n/** One manifest row — the minimal-manifest scheme (docs/marketplace-devx.md)\n * with the legacy pinned-URL fields still accepted. Exported so tooling\n * tests can verify generated manifests parse. */\nexport const MarketplaceEntrySchema = z\n .object({\n kind: z.enum([\"block\", \"command\"]),\n /** Qualified id — `@collection/slug`; also the module's exported id. */\n id: z.string(),\n name: z.string(),\n version: z.string(),\n description: z.string().optional(),\n tags: z.array(z.string()).default([]),\n authors: z.array(z.string()).default([]),\n /** Qualified ids of blocks this block emits instances of — install\n * resolves them from the catalog first (blocks only). */\n dependencies: z.array(z.string()).default([]),\n /** Repo-relative module path (POSIX, unencoded), resolved against the\n * marketplace repo at the ref the manifest was fetched from. */\n source: z.string().optional(),\n /** Legacy: commit-SHA-pinned raw URL of the module source. */\n sourceUrl: z.string().url().optional(),\n /** Legacy: sha-256 (hex) of the module source — no longer read. */\n contentHash: z.string().optional(),\n /** Inline SVG thumbnail markup (blocks only). */\n thumbnailSvg: z.string().optional(),\n })\n .refine((e) => e.source !== undefined || e.sourceUrl !== undefined, {\n message: \"entry needs source or sourceUrl\",\n });\nexport type MarketplaceEntry = z.infer<typeof MarketplaceEntrySchema>;\n\n// Rows the client cannot parse are DROPPED, not fatal — a newer manifest\n// format must never blank the whole marketplace for older clients.\nconst ManifestSchema = z.object({\n /** Marketplace display name (the `.lineadraw/marketplace.json` header). */\n name: z.string().optional(),\n entries: z.array(z.unknown()),\n});\n\nexport type MarketplaceCatalog =\n | { state: \"ready\"; name?: string; entries: MarketplaceEntry[] }\n | { state: \"unavailable\"; reason: string };\n\n/** Both manifest locations, in preference order (the CLI writes the first;\n * root manifest.json is the transition fallback). */\nexport const MANIFEST_PATHS = [\".lineadraw/marketplace.json\", \"manifest.json\"];\n\n/** Parse raw manifest JSON into a catalog (shared by both source kinds). */\nexport const catalogFromJson = (data: unknown): MarketplaceCatalog => {\n const parsed = ManifestSchema.safeParse(data);\n if (!parsed.success)\n return { state: \"unavailable\", reason: \"Malformed catalog.\" };\n const entries: MarketplaceEntry[] = [];\n for (const row of parsed.data.entries) {\n const entry = MarketplaceEntrySchema.safeParse(row);\n if (entry.success) entries.push(entry.data);\n }\n return { state: \"ready\", name: parsed.data.name, entries };\n};\n\n/** Search predicate over an entry's name/id/description/tags. */\nexport const entryMatches = (entry: MarketplaceEntry, q: string): boolean => {\n const needle = q.trim().toLowerCase();\n if (needle === \"\") return true;\n return [entry.name, entry.id, entry.description ?? \"\", ...entry.tags]\n .join(\" \")\n .toLowerCase()\n .includes(needle);\n};\n\n/** How a catalog entry relates to what the document already has. */\nexport type InstallStatus =\n | { kind: \"absent\" }\n | { kind: \"installed\"; version?: string }\n | { kind: \"update\"; from?: string };\n\n/** The document's module sources an install compares against. */\nexport interface VendoredModules {\n blockDefinitions: readonly string[];\n commands: readonly string[];\n}\n\n/** Compare an entry against the document's vendored modules (by id, then\n * version — content hashing is the registry milestone's refinement).\n * In the editor, `doc` must be the CALLER'S SUBSCRIBED slices, not\n * getState(): the React Compiler memoizes badge JSX by the values it\n * references, so a hidden getState() read leaves stale badges on screen. */\nexport const installStatusOf = (\n entry: MarketplaceEntry,\n doc: VendoredModules,\n): InstallStatus => {\n const scripts = entry.kind === \"block\" ? doc.blockDefinitions : doc.commands;\n const idOf = entry.kind === \"block\" ? blockScriptId : commandScriptId;\n const local = scripts.find((s) => idOf(s) === entry.id);\n if (local === undefined) return { kind: \"absent\" };\n const meta =\n entry.kind === \"block\"\n ? getBlockMetaResult(local)\n : getCommandMetaResult(local);\n const localVersion = meta.ok ? meta.meta.version : undefined;\n if (localVersion !== undefined && localVersion !== entry.version)\n return { kind: \"update\", from: localVersion };\n return { kind: \"installed\", version: localVersion };\n};\n\n/** The string that identifies an entry's module source — repo-relative\n * path, or the legacy pinned URL. Also a stable React key. */\nexport const entrySourceRef = (entry: MarketplaceEntry): string =>\n entry.source ?? entry.sourceUrl ?? entry.id;\n\n// ---- Client -----------------------------------------------------------------\n\n/** What a host lends the client: the platform's fetch (default\n * `globalThis.fetch`) and, for folder marketplaces, a reader of UTF-8\n * files by folder key + folder-relative POSIX path (reject when missing).\n * Without a reader, folder marketplaces report themselves unavailable. */\nexport interface MarketplaceIO {\n fetch?: typeof globalThis.fetch;\n readFile?: (folderKey: string, relPath: string) => Promise<string>;\n}\n\n/** A search hit: the entry, where it came from, and its install status. */\nexport interface MarketplaceHit extends MarketplaceEntry {\n marketplace: MarketplaceInfo;\n status: InstallStatus;\n}\n\nexport interface MarketplaceQuery {\n /** Case-insensitive substring over name, id, description and tags. */\n query?: string;\n kind?: MarketplaceEntry[\"kind\"];\n /** Restrict to one marketplace — by key, spec, folder or label. */\n marketplace?: string;\n}\n\n/**\n * Catalog + source access over configured marketplaces, with per-instance\n * caches: one download of a module serves preview and install, and a\n * catalog is fetched once until `refresh`. One instance per host.\n */\nexport class MarketplaceClient {\n private readonly catalogs = new Map<string, Promise<MarketplaceCatalog>>();\n private readonly sources = new Map<string, Promise<string>>();\n\n private readonly io: MarketplaceIO;\n\n constructor(io: MarketplaceIO = {}) {\n this.io = io;\n }\n\n private fetch(url: string, init?: RequestInit): Promise<Response> {\n const f = this.io.fetch ?? globalThis.fetch;\n if (f === undefined)\n return Promise.reject(new Error(\"fetch is not available in this host\"));\n return f(url, init);\n }\n\n private cacheKey(m: MarketplaceConfig): string {\n return `${marketplaceKey(m)}|${m.kind === \"github\" ? (m.token ?? \"\") : \"\"}`;\n }\n\n private async loadFolderCatalog(folder: string): Promise<MarketplaceCatalog> {\n const read = this.io.readFile;\n if (read === undefined)\n return {\n state: \"unavailable\",\n reason: \"Local folder marketplaces aren't supported in this host.\",\n };\n for (const rel of MANIFEST_PATHS) {\n let text: string;\n try {\n text = await read(folder, rel);\n } catch {\n continue; // missing file — try the fallback location\n }\n try {\n return catalogFromJson(JSON.parse(text));\n } catch {\n return { state: \"unavailable\", reason: \"Malformed catalog.\" };\n }\n }\n return {\n state: \"unavailable\",\n reason:\n \"No marketplace manifest found in this folder. Run `lineadraw manifest` there.\",\n };\n }\n\n private async loadCatalog(m: MarketplaceConfig): Promise<MarketplaceCatalog> {\n if (m.kind === \"folder\") return this.loadFolderCatalog(m.folder);\n const specText = m.kind === \"builtin\" ? BUILTIN_MARKETPLACE_SPEC : m.spec;\n const token = m.kind === \"github\" ? m.token : undefined;\n const spec = parseMarketplaceSpec(specText);\n if (spec === null)\n return {\n state: \"unavailable\",\n reason: `\"${specText}\" is not owner/repo[@branch].`,\n };\n const headers = token !== undefined ? apiHeaders(token) : undefined;\n try {\n let status = 404;\n for (const url of manifestUrls(spec, token !== undefined)) {\n const res = await this.fetch(url, { cache: \"no-cache\", headers });\n status = res.status;\n if (res.status === 404) continue; // try the fallback location\n if (!res.ok) break;\n return catalogFromJson(await res.json());\n }\n return {\n state: \"unavailable\",\n reason:\n status === 404\n ? \"No marketplace manifest found in this repository (private repos need a token).\"\n : status === 401 || status === 403\n ? \"Access denied. Check the token.\"\n : `Catalog request failed (${status}).`,\n };\n } catch {\n return {\n state: \"unavailable\",\n reason: \"Could not reach the marketplace (offline?).\",\n };\n }\n }\n\n /** Fetch (and cache) a marketplace's catalog; `refresh` bypasses the\n * cache AND drops the marketplace's cached module sources — `source`\n * rows track a branch ref, so they are only immutable within one catalog\n * snapshot. */\n catalog(m: MarketplaceConfig, refresh = false): Promise<MarketplaceCatalog> {\n const key = this.cacheKey(m);\n if (refresh) {\n this.catalogs.delete(key);\n for (const k of [...this.sources.keys()])\n if (k.startsWith(`${key}\\n`)) this.sources.delete(k);\n }\n let cached = this.catalogs.get(key);\n if (!cached) {\n cached = this.loadCatalog(m);\n this.catalogs.set(key, cached);\n }\n return cached;\n }\n\n /** An entry's module source. `source` rows resolve against the\n * marketplace repo at the manifest's ref; with a token the contents API\n * serves them instead of the raw host. */\n source(m: MarketplaceConfig, entry: MarketplaceEntry): Promise<string> {\n const key = `${this.cacheKey(m)}\\n${entrySourceRef(entry)}`;\n let cached = this.sources.get(key);\n if (!cached) {\n cached = (async () => {\n if (m.kind === \"folder\") {\n const read = this.io.readFile;\n if (read === undefined)\n throw new Error(\n \"Local folder marketplaces aren't supported in this host.\",\n );\n if (entry.source === undefined)\n throw new Error(`${entry.id} has no folder-relative source path`);\n return read(m.folder, entry.source);\n }\n const specText =\n m.kind === \"builtin\" ? BUILTIN_MARKETPLACE_SPEC : m.spec;\n const token = m.kind === \"github\" ? m.token : undefined;\n const withToken = token !== undefined;\n let url: string;\n if (entry.source !== undefined) {\n const spec = parseMarketplaceSpec(specText);\n if (spec === null)\n throw new Error(`\"${specText}\" is not owner/repo[@branch]`);\n url = sourcePathUrl(spec, withToken, entry.source);\n } else {\n const legacy = entry.sourceUrl!; // schema: source or sourceUrl\n url = withToken ? (rawToApiUrl(legacy) ?? legacy) : legacy;\n }\n const headers = withToken ? apiHeaders(token) : undefined;\n const res = await this.fetch(url, { headers });\n if (!res.ok)\n throw new Error(`Source download failed (${res.status}): ${url}`);\n return res.text();\n })();\n // A failed fetch must not poison the cache — retry on next call.\n cached.catch(() => this.sources.delete(key));\n this.sources.set(key, cached);\n }\n return cached;\n }\n\n /**\n * Sources of an entry's declared dependency CLOSURE (the entry itself\n * excluded), resolved from the catalog recursively — what a preview\n * needs so nested instances (Grid → Axis) evaluate before anything is\n * installed. Missing catalog entries are skipped (the preview then shows\n * the eval error for that id, same as a dangling reference).\n */\n async closureSources(\n m: MarketplaceConfig,\n entry: MarketplaceEntry,\n ): Promise<string[]> {\n if (entry.kind !== \"block\" || entry.dependencies.length === 0) return [];\n const catalog = await this.catalog(m);\n if (catalog.state !== \"ready\") return [];\n const sources: string[] = [];\n const visited = new Set<string>([entry.id]);\n const queue = [...entry.dependencies];\n while (queue.length > 0) {\n const id = queue.pop()!;\n if (visited.has(id)) continue;\n visited.add(id);\n const dep = catalog.entries.find(\n (e) => e.kind === \"block\" && e.id === id,\n );\n if (dep === undefined) continue;\n try {\n sources.push(await this.source(m, dep));\n } catch {\n continue; // unreachable source — preview shows the dangling id\n }\n queue.push(...dep.dependencies);\n }\n return sources;\n }\n\n /**\n * The module sources an install of `entry` merges, in order: declared\n * block dependencies first (resolved from the catalog, recursively,\n * skipping ids the document already vendors — a dependency is never\n * force-updated), the entry itself last. Throws when a dependency is\n * missing from the catalog.\n */\n async installSources(\n m: MarketplaceConfig,\n entry: MarketplaceEntry,\n vendored: VendoredModules,\n visited: Set<string> = new Set(),\n ): Promise<string[]> {\n if (visited.has(entry.id)) return []; // dependency cycle — handled\n visited.add(entry.id);\n const sources: string[] = [];\n if (entry.kind === \"block\" && entry.dependencies.length > 0) {\n const catalog = await this.catalog(m);\n for (const depId of entry.dependencies) {\n if (blockDefinitionExists(vendored.blockDefinitions, depId)) continue;\n const dep =\n catalog.state === \"ready\"\n ? catalog.entries.find((e) => e.kind === \"block\" && e.id === depId)\n : undefined;\n if (dep === undefined)\n throw new Error(`dependency ${depId} is not in the catalog`);\n sources.push(...(await this.installSources(m, dep, vendored, visited)));\n }\n }\n sources.push(await this.source(m, entry));\n return sources;\n }\n\n /** Entries across the configured marketplaces (priority order; the first\n * marketplace publishing an id wins), filtered by the query. */\n async search(\n configs: readonly MarketplaceConfig[],\n q: MarketplaceQuery,\n vendored: VendoredModules,\n ): Promise<MarketplaceHit[]> {\n const hits: MarketplaceHit[] = [];\n const seen = new Set<string>();\n for (const m of configs) {\n if (q.marketplace !== undefined && !matchesMarketplace(m, q.marketplace))\n continue;\n const catalog = await this.catalog(m);\n if (catalog.state !== \"ready\") continue;\n const info = marketplaceInfo(m);\n for (const entry of catalog.entries) {\n if (seen.has(entry.id)) continue;\n if (q.kind !== undefined && entry.kind !== q.kind) continue;\n if (!entryMatches(entry, q.query ?? \"\")) continue;\n seen.add(entry.id);\n hits.push({\n ...entry,\n marketplace: info,\n status: installStatusOf(entry, vendored),\n });\n }\n }\n return hits;\n }\n\n /** The first marketplace (in priority order, or the named one) that\n * publishes `id`, with its entry; null when none does. */\n async find(\n configs: readonly MarketplaceConfig[],\n id: string,\n marketplace?: string,\n ): Promise<{ config: MarketplaceConfig; entry: MarketplaceEntry } | null> {\n for (const config of configs) {\n if (marketplace !== undefined && !matchesMarketplace(config, marketplace))\n continue;\n const catalog = await this.catalog(config);\n if (catalog.state !== \"ready\") continue;\n const entry = catalog.entries.find((e) => e.id === id);\n if (entry) return { config, entry };\n }\n return null;\n }\n}\n","// User commands (macro scripts) as ES modules — the command-side sibling of\n// evalBlock. The document's `commands` array and the editor's per-device\n// library both hold raw module sources; one module = one command, authored\n// as `export default defineCommand({...})` (defineCommand is a runtime\n// identity resolved by the shared require shim). Everything the app knows\n// about a command derives from the compiled module:\n// id → identity (palette entries, hotkey overrides, import merge)\n// name → palette/list label\n// description / version / authors / tags → optional metadata\n// run(ctx) → the macro body. The HOST supplies ctx (document API,\n// pickers, selection, prompt, toast — typed as\n// CommandContext in lineadraw.d.ts) and wraps the whole call\n// in one undo transaction. `run` is interactive, so there is\n// no dry run — save-time validation is compile + meta.\n// Shares the lazy transpiler with blocks: callers that cannot tolerate the\n// transient \"Compiling…\" error await `ensureScriptTranspiler()` first.\n\nimport { z } from \"zod\";\nimport {\n executeScriptModule,\n parseParamsExport,\n scriptTranspilerReady,\n} from \"./evalBlock\";\nimport type { BlockParameter } from \"../model/blockDefinition\";\nimport { mergeScriptModules, type MergeModulesResult } from \"./scriptModules\";\n\n/** Identity + metadata derived from a command module's exports. */\nexport interface CommandMeta {\n id: string;\n name: string;\n description?: string;\n version?: string;\n authors?: string[];\n tags?: string[];\n /** Declared point inputs (labels): picked one by one in the editor before\n * `run`, or supplied up front by a headless/remote caller. */\n inputs?: string[];\n /** Declared parameters (the blocks' ParamDef table): prompted in the\n * editor before `run`, or passed by a headless caller; arrive as\n * `ctx.params`. Absent when the command declares none. */\n params?: BlockParameter[];\n}\n\n/** The compiled `run` — its ctx is host-supplied (CommandContext). */\nexport type CommandRunFn = (ctx: unknown) => unknown;\n\ninterface CompiledCommand {\n meta: CommandMeta;\n run: CommandRunFn;\n}\n\nconst OptionalMetaSchema = z.object({\n description: z.string().optional(),\n version: z.string().optional(),\n authors: z.array(z.string()).optional(),\n tags: z.array(z.string()).optional(),\n inputs: z.array(z.string().min(1)).optional(),\n});\n\n/** Validate a module's identity/metadata exports with author-facing errors. */\nconst extractCommandMeta = (mod: Record<string, unknown>): CommandMeta => {\n if (typeof mod.id !== \"string\" || mod.id.trim() === \"\")\n throw new Error(\"Command script must export a non-empty string `id`\");\n if (typeof mod.name !== \"string\" || mod.name.trim() === \"\")\n throw new Error(\"Command script must export a non-empty string `name`\");\n const parsed = OptionalMetaSchema.safeParse(mod);\n if (!parsed.success) {\n const issue = parsed.error.issues[0];\n throw new Error(\n `Invalid command metadata${\n issue ? ` — ${issue.path.join(\".\")}: ${issue.message}` : \"\"\n }`,\n );\n }\n const params = parseParamsExport(mod.params);\n return {\n id: mod.id,\n name: mod.name,\n ...parsed.data,\n ...(params.length > 0 ? { params } : {}),\n };\n};\n\n/** Compile cache keyed by the raw source (same rationale as evalBlock's). */\nconst compileCache = new Map<string, CompiledCommand>();\nconst COMPILE_CACHE_MAX = 100;\n\nconst compileCommand = (script: string): CompiledCommand => {\n const cached = compileCache.get(script);\n if (cached) {\n // Refresh recency so live-edited drafts don't evict installed commands.\n compileCache.delete(script);\n compileCache.set(script, cached);\n return cached;\n }\n const mod = executeScriptModule(script);\n const meta = extractCommandMeta(mod);\n const run = mod.run;\n if (typeof run !== \"function\")\n throw new Error(\"Command script must export a `run` function\");\n if (compileCache.size >= COMPILE_CACHE_MAX) {\n const oldest = compileCache.keys().next().value;\n if (oldest !== undefined) compileCache.delete(oldest);\n }\n const compiled = { meta, run: run as CommandRunFn };\n compileCache.set(script, compiled);\n return compiled;\n};\n\n/** Non-throwing meta lookup for list UIs. */\nexport type CommandMetaResult =\n | { ok: true; meta: CommandMeta }\n | {\n ok: false;\n error: string;\n /** True while the transient transpiler load is the only problem. */\n loading: boolean;\n };\n\nexport const getCommandMetaResult = (script: string): CommandMetaResult => {\n try {\n return { ok: true, meta: compileCommand(script).meta };\n } catch (e) {\n return {\n ok: false,\n error: e instanceof Error ? e.message : String(e),\n loading: !scriptTranspilerReady(),\n };\n }\n};\n\n/** Meta for each script in a library (invalid entries report their error). */\nexport const listCommandMeta = (\n scripts: readonly string[],\n): CommandMetaResult[] => scripts.map(getCommandMetaResult);\n\n/**\n * The compiled `run` function. Sync; throws the transient\n * \"Compiling script…\" until the lazy transpiler is loaded, and a\n * descriptive error for invalid modules.\n */\nexport const getCommandRun = (script: string): CommandRunFn =>\n compileCommand(script).run;\n\n/** Source-level `export const id = \"…\"` matcher (broken-module fallback). */\nconst ID_EXPORT_RE = /export\\s+const\\s+id\\s*=\\s*[\"']([^\"']+)[\"']/;\n\n/**\n * A module's exported id without requiring it to be valid: compiled meta\n * when possible, a source-level scan (the named-export form, or the first\n * `id: \"…\"` after the spec opener) otherwise — so merge/replace semantics\n * survive a module that no longer compiles (or the transpiler still loading).\n */\nexport const commandScriptId = (script: string): string | undefined => {\n try {\n return compileCommand(script).meta.id;\n } catch {\n const named = ID_EXPORT_RE.exec(script);\n if (named) return named[1];\n const call = script.search(/defineCommand\\s*\\(|export\\s+default\\s*\\{/);\n if (call === -1) return undefined;\n return /\\bid\\s*:\\s*[\"']([^\"']+)[\"']/.exec(script.slice(call))?.[1];\n }\n};\n\nexport type MergeCommandModulesResult = MergeModulesResult<CommandMeta>;\n\n/** Merge incoming command module sources into an existing library (same\n * invariants as blocks: verbatim → skip, id match → replace in place, name\n * clash → suffix). Await `ensureScriptTranspiler()` first — merging compiles. */\nexport const mergeCommandModules = (\n existing: readonly string[],\n incoming: readonly string[],\n): MergeCommandModulesResult =>\n mergeScriptModules(existing, incoming, {\n idOf: commandScriptId,\n metaOf: getCommandMetaResult,\n });\n","// Pure GitHub URL helpers for marketplace sources — no store imports, so\n// the spec parsing and URL rewriting stay unit-testable.\n//\n// Two fetch paths, each used where it actually works:\n// - no token → raw.githubusercontent.com (CDN, CORS *, effectively\n// unlimited; unauthenticated api.github.com is 60 req/h per IP).\n// - token (private repos) → api.github.com contents endpoint (reliable\n// Authorization CORS, 5000 req/h per token; raw does not reliably accept\n// Authorization from browsers).\n\n/** Parsed `owner/repo` or `owner/repo@branch`. */\nexport type MarketplaceSpec = {\n owner: string;\n repo: string;\n branch?: string;\n};\n\nconst SPEC_RE = /^([A-Za-z0-9_.-]+)\\/([A-Za-z0-9_.-]+)(?:@([^\\s@]+))?$/;\n\nexport const parseMarketplaceSpec = (spec: string): MarketplaceSpec | null => {\n const m = SPEC_RE.exec(spec.trim());\n if (m === null) return null;\n return { owner: m[1], repo: m[2], ...(m[3] ? { branch: m[3] } : {}) };\n};\n\nconst apiContentsUrl = (\n owner: string,\n repo: string,\n path: string,\n ref?: string,\n): string =>\n `https://api.github.com/repos/${owner}/${repo}/contents/${path}` +\n (ref !== undefined ? `?ref=${encodeURIComponent(ref)}` : \"\");\n\n/** Manifest URL candidates, preferred location first (the root\n * `manifest.json` is the pre-`.lineadraw/` transition fallback). */\nexport const manifestUrls = (\n spec: MarketplaceSpec,\n withToken: boolean,\n): string[] => {\n const paths = [\".lineadraw/marketplace.json\", \"manifest.json\"];\n if (withToken)\n return paths.map((p) =>\n apiContentsUrl(spec.owner, spec.repo, p, spec.branch),\n );\n // `HEAD` resolves to the default branch on the raw host.\n return paths.map(\n (p) =>\n `https://raw.githubusercontent.com/${spec.owner}/${spec.repo}/${spec.branch ?? \"HEAD\"}/${p}`,\n );\n};\n\n/** URL of a repo-relative module path (a manifest row's `source`) at the\n * ref the catalog itself was fetched from — raw host tokenless, contents\n * API with a token. Path segments are percent-encoded here (manifests\n * store them unencoded; filenames may contain spaces). */\nexport const sourcePathUrl = (\n spec: MarketplaceSpec,\n withToken: boolean,\n path: string,\n): string => {\n const encoded = path.split(\"/\").map(encodeURIComponent).join(\"/\");\n if (withToken)\n return apiContentsUrl(spec.owner, spec.repo, encoded, spec.branch);\n return `https://raw.githubusercontent.com/${spec.owner}/${spec.repo}/${spec.branch ?? \"HEAD\"}/${encoded}`;\n};\n\n/** Rewrite a commit-pinned raw.githubusercontent.com URL to the equivalent\n * contents-API URL (same pin via ?ref=). Returns null for non-raw URLs.\n * Legacy-manifest path only — `source` rows use sourcePathUrl. */\nexport const rawToApiUrl = (rawUrl: string): string | null => {\n const m =\n /^https:\\/\\/raw\\.githubusercontent\\.com\\/([^/]+)\\/([^/]+)\\/([^/]+)\\/(.+)$/.exec(\n rawUrl,\n );\n if (m === null) return null;\n return apiContentsUrl(m[1], m[2], m[4], m[3]);\n};\n\n/** Headers that make the contents API return raw file bytes. */\nexport const apiHeaders = (token: string): Record<string, string> => ({\n Accept: \"application/vnd.github.raw+json\",\n Authorization: `Bearer ${token}`,\n});\n","// PDF font-coverage checks. The PDF export has two ways to lose characters:\n// a font that renders as base-14 Helvetica (an \"embed\" font whose TTF the\n// host didn't register) encodes WinAnsi only, so Cyrillic becomes mojibake;\n// and an embedded TTF simply missing the glyphs (the handwriting fonts have\n// no Cyrillic) renders tofu. The PdfSink uses these checks to substitute\n// PDF_FALLBACK_FONT per string — on screen the CSS font stacks already fall\n// back natively.\n\nimport {\n ADVANCE_TABLES,\n EXTRACTED_EXTRAS,\n EXTRACTED_RANGES,\n} from \"./advanceTables\";\nimport { resolveFont, type FontId } from \"../model/fonts\";\n\n/** Substitute for text the chosen font cannot render in PDF: the default\n * font — embedded as Liberation Sans with full Cyrillic (model/fonts.ts). */\nexport const PDF_FALLBACK_FONT: FontId = \"arial\";\n\n/** WinAnsi's printable extras above U+00FF — base-14 fonts CAN encode\n * these (curly quotes, dashes, €, …), so they must not trigger fallback. */\nconst WINANSI_EXTRA = new Set(\"€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ\");\n\n/** Can base-14 Helvetica (WinAnsi) encode this text? */\nexport const winAnsiEncodable = (text: string): boolean => {\n for (const ch of text) {\n const code = ch.codePointAt(0)!;\n if (code > 0xff && !WINANSI_EXTRA.has(ch)) return false;\n }\n return true;\n};\n\nconst extracted = (ch: string, code: number): boolean =>\n EXTRACTED_RANGES.some(([a, b]) => code >= a && code <= b) ||\n EXTRACTED_EXTRAS.includes(ch);\n\n/**\n * Can this font's EMBEDDED program render `text`? Checked against the\n * extracted advance tables — a character inside the extracted ranges but\n * absent from the font's table is a REAL coverage gap. Characters outside\n * the extracted ranges are unknown and get the benefit of the doubt (the\n * chosen font is kept). Callers must use `winAnsiEncodable` instead when\n * the font actually renders as base-14 (its TTF was not registered).\n */\nexport const pdfFontCovers = (\n font: string | undefined,\n text: string,\n): boolean => {\n const def = resolveFont(font);\n if (def.pdf !== \"embed\") return winAnsiEncodable(text);\n const table = ADVANCE_TABLES[def.id];\n for (const ch of text) {\n const code = ch.codePointAt(0)!;\n if (code > 0x7e && extracted(ch, code) && table.advances[ch] === undefined)\n return false;\n }\n return true;\n};\n","// Paint a paper layout's CONTENT (viewports into model space + sheet\n// annotations) through any GeometrySink. Shared verbatim by the canvas\n// paper-space renderer and the PDF exporter — what you see is what prints.\n\nimport type { PaperLayout } from \"../model/paperLayout\";\nimport type { ModelObject, Viewport } from \"../model/objects\";\nimport { buildSnapEntry } from \"../snap/buildEntry\";\nimport { boundsIntersect, isEmptyBounds, type AABB } from \"../geometry/bounds\";\nimport type { GeometrySink, Mat2x3 } from \"./sink\";\nimport type { TextMeasurer } from \"./textMetrics\";\nimport { paintObject, type DocumentPaintResources } from \"./painters\";\nimport { rebaseSink } from \"./rebaseSink\";\nimport type { PaintGeometryCache } from \"./paintCache\";\nimport { resolveStyle } from \"./style\";\n\nexport interface LayoutPaintOptions {\n /** Map object colors for the output medium (e.g. light→black for print). */\n mapColor?: (color: string) => string;\n /**\n * Viewport-culling bounds for a model object. Defaults to\n * `buildSnapEntry(obj).bounds`; the editor passes its cached snap-entry\n * bounds instead (avoiding a per-frame recompute). Return `null` to skip\n * culling for that object.\n */\n boundsOf?: (obj: ModelObject) => AABB | null;\n /** Derived-geometry cache forwarded to the painters (see PaintEnv.cache). */\n cache?: PaintGeometryCache;\n}\n\n/**\n * The slice of document state layout painting reads. The kernel holds no\n * store, so it is passed in (the editor sources it from useModel; a headless\n * caller from the loaded document).\n */\nexport interface LayoutModelContext extends DocumentPaintResources {\n objects: readonly ModelObject[];\n}\n\n/** The viewport objects of a layout (in draw order). */\nexport const layoutViewports = (layout: PaperLayout): Viewport[] =>\n layout.objects.filter((o): o is Viewport => o.type === \"viewport\");\n\n/** Paper mm per model mm (`scale` stores the 1:N denominator). */\nconst viewportPaperPerModel = (vp: Viewport): number => 1 / vp.scale;\n\n/** Model-space window visible through a viewport. */\nexport const viewportWorldBounds = (vp: Viewport): AABB => {\n const halfW = (vp.rect.w / 2) * vp.scale;\n const halfH = (vp.rect.h / 2) * vp.scale;\n return {\n minX: vp.modelCenter.x - halfW,\n minY: vp.modelCenter.y - halfH,\n maxX: vp.modelCenter.x + halfW,\n maxY: vp.modelCenter.y + halfH,\n };\n};\n\n/** Sheet ← model transform of a viewport, for coordinates RELATIVE TO its\n * model centre (paint through `rebaseSink(sink, vp.modelCenter)`): a\n * survey-grid model (~10¹⁰ mm) would otherwise reach the canvas/PDF as huge\n * numbers and lose its precision there. */\nconst viewportTransform = (vp: Viewport): Mat2x3 => {\n const k = viewportPaperPerModel(vp);\n return [k, 0, 0, k, vp.rect.x + vp.rect.w / 2, vp.rect.y + vp.rect.h / 2];\n};\n\nconst resolveBoundsOf = (\n sink: GeometrySink,\n model: LayoutModelContext,\n opts: LayoutPaintOptions,\n): ((obj: ModelObject) => AABB | null) => {\n if (opts.boundsOf) return opts.boundsOf;\n // Bounds culling reuses the pure snap-entry geometry; text/dimension bounds\n // need measurement, taken from the sink (no DOM).\n const measure: TextMeasurer = {\n measureTextWidth: (t, h) => sink.measureText(t, h).width,\n };\n return (obj) =>\n buildSnapEntry(obj, {\n dimStyles: model.dimStyles,\n textStyles: model.textStyles,\n blockDefinitions: model.blockDefinitions,\n resolveObject: model.resolveObject,\n resolveReference: model.resolveReference,\n measure,\n }).bounds;\n};\n\n/**\n * ONE viewport's clipped, transformed model projection. The sink must be in\n * sheet-mm coordinates (the same space `paintLayoutContent` paints in), so a\n * caller can also point it at an offscreen bitmap of just the rect.\n */\nexport const paintViewportContent = (\n vp: Viewport,\n sink: GeometrySink,\n model: LayoutModelContext,\n opts: LayoutPaintOptions = {},\n): void => {\n const { objects, layers } = model;\n const layerVisible = new Map(layers.map((l) => [l.id, l.visible]));\n const layerName = new Map(layers.map((l) => [l.id, l.name]));\n const mapColor = opts.mapColor ?? ((c: string) => c);\n const boundsOf = resolveBoundsOf(sink, model, opts);\n\n sink.pushClipRect(vp.rect);\n sink.pushTransform(viewportTransform(vp));\n const content = rebaseSink(sink, vp.modelCenter);\n const visible = viewportWorldBounds(vp);\n const hiddenLayers = new Set(vp.hiddenLayerIds);\n\n for (const obj of objects) {\n if (layerVisible.get(obj.layerId) === false) continue;\n if (hiddenLayers.has(obj.layerId)) continue;\n const bounds = boundsOf(obj);\n if (bounds && !isEmptyBounds(bounds) && !boundsIntersect(bounds, visible))\n continue;\n const style = resolveStyle(obj, layers, model.lineTypes);\n sink.beginObject?.(obj.id, layerName.get(obj.layerId));\n paintObject(obj, content, {\n style: { ...style, color: mapColor(style.color) },\n ...model,\n cache: opts.cache,\n mapColor,\n });\n sink.endObject?.();\n }\n\n sink.popTransform();\n sink.popClip();\n};\n\n/** Sheet-space annotations (drawn in sheet mm). Viewport frames are screen\n * chrome (drawn by the scene renderer), so they never reach print output. */\nexport const paintLayoutAnnotations = (\n layout: PaperLayout,\n sink: GeometrySink,\n model: LayoutModelContext,\n opts: LayoutPaintOptions = {},\n): void => {\n const { layers } = model;\n const layerVisible = new Map(layers.map((l) => [l.id, l.visible]));\n const layerName = new Map(layers.map((l) => [l.id, l.name]));\n const mapColor = opts.mapColor ?? ((c: string) => c);\n for (const obj of layout.objects) {\n if (obj.type === \"viewport\") continue;\n if (layerVisible.get(obj.layerId) === false) continue;\n const style = resolveStyle(obj, layers, model.lineTypes);\n sink.beginObject?.(obj.id, layerName.get(obj.layerId));\n paintObject(obj, sink, {\n style: { ...style, color: mapColor(style.color) },\n ...model,\n cache: opts.cache,\n mapColor,\n });\n sink.endObject?.();\n }\n};\n\nexport const paintLayoutContent = (\n layout: PaperLayout,\n sink: GeometrySink,\n model: LayoutModelContext,\n opts: LayoutPaintOptions = {},\n): void => {\n // Viewport content always renders under the sheet annotations, regardless\n // of array position.\n for (const vp of layoutViewports(layout)) {\n paintViewportContent(vp, sink, model, opts);\n }\n paintLayoutAnnotations(layout, sink, model, opts);\n};\n","// Per-layout print color mapping — what authored (dark-canvas) colors become\n// on white paper. Shared by the paper-space canvas renderer and the PDF\n// exporter, so the layout on screen always previews the printed output.\n\nimport type { PrintPalette } from \"../model/paperLayout\";\nimport { hexToRgb } from \"../export/dxf/aci\";\n\nconst luminance = (r: number, g: number, b: number): number =>\n (0.2126 * r + 0.7152 * g + 0.0722 * b) / 255;\n\nconst grayHex = (level: number): string => {\n const v = Math.round(Math.min(Math.max(level, 0), 1) * 255)\n .toString(16)\n .padStart(2, \"0\");\n return `#${v}${v}${v}`;\n};\n\n/** Authored-color → print-color mapper for LayoutPaintOptions.mapColor. */\nexport const printColorMapper =\n (palette: PrintPalette): ((hex: string) => string) =>\n (hex) => {\n const rgb = hexToRgb(hex);\n if (!rgb) return hex;\n const [r, g, b] = rgb;\n const lum = luminance(r, g, b);\n switch (palette) {\n case \"color\": {\n // Only light NEUTRALS flip to black (white/light-gray lines would\n // vanish on paper); saturated colors — yellow, cyan — keep their hue.\n const saturation = (Math.max(r, g, b) - Math.min(r, g, b)) / 255;\n return lum > 0.75 && saturation < 0.25 ? \"#000000\" : hex;\n }\n case \"grayscale\":\n // Ink weight: colors authored bright on the dark canvas print dark.\n // Clamped so even dark-authored colors keep a visible gray.\n return grayHex(Math.min(1 - lum, 0.75));\n case \"monochrome\":\n return \"#000000\";\n }\n };\n","// Diff whole-collection replacements into granular operations. The editor's\n// and SDK's \"set the whole array\" surfaces stay ergonomic for callers, but\n// what goes on the wire (and into undo history) are precise per-item ops —\n// a concurrent edit to a DIFFERENT item of the same collection survives,\n// where a coarse set-op would silently clobber it. The decomposition is\n// total: updates → removes → reorder of the survivors (when their relative\n// order changed) → indexed adds reconstruct `next` exactly. The legacy\n// set-* ops are only emitted for arrays with duplicate ids/sources, which\n// nothing granular can express. See docs/granular-ops.md.\n\nimport { blockScriptId } from \"../extensions/evalBlock\";\nimport type { Layer, LineaDocument } from \"../model/document\";\nimport type { DimStyle, ModelObject, TextStyle } from \"../model/objects\";\nimport { lineTypeKey, type LineType } from \"../model/lineTypes\";\nimport {\n hatchPatternKey,\n type DocumentHatchPattern,\n} from \"../model/hatchPatterns\";\nimport type { OpSpace, Operation } from \"./types\";\n\nconst sameJson = (a: unknown, b: unknown): boolean =>\n a === b || JSON.stringify(a) === JSON.stringify(b);\n\n/** Id-keyed collection diff. `added` indices refer to the FINAL array. */\nconst diffById = <T extends { id: string }>(\n prev: readonly T[],\n next: readonly T[],\n) => {\n const prevById = new Map(prev.map((x) => [x.id, x]));\n const nextIds = new Set(next.map((x) => x.id));\n const removed = prev.filter((x) => !nextIds.has(x.id));\n const added: { item: T; index: number }[] = [];\n const updated: T[] = [];\n next.forEach((x, i) => {\n const p = prevById.get(x.id);\n if (!p) added.push({ item: x, index: i });\n else if (!sameJson(p, x)) updated.push(x);\n });\n const surviving = (arr: readonly T[], has: (id: string) => boolean) =>\n arr.filter((x) => has(x.id)).map((x) => x.id);\n /** Survivor ids in `next` order — the reorder payload when it changed. */\n const survivorOrder = surviving(next, (id) => prevById.has(id));\n const orderChanged =\n surviving(prev, (id) => nextIds.has(id)).join(\" \") !==\n survivorOrder.join(\" \");\n const duplicateIds =\n prevById.size !== prev.length || nextIds.size !== next.length;\n return { added, updated, removed, orderChanged, survivorOrder, duplicateIds };\n};\n\nexport const diffLayerOps = (\n prev: readonly Layer[],\n next: readonly Layer[],\n): Operation[] => {\n const d = diffById(prev, next);\n if (d.duplicateIds) return [{ type: \"set-layers\", layers: [...next] }];\n const ops: Operation[] = d.updated.map((layer) => ({\n type: \"update-layer\",\n layer,\n }));\n for (const l of d.removed) ops.push({ type: \"remove-layer\", id: l.id });\n if (d.orderChanged)\n ops.push({ type: \"reorder-layers\", ids: d.survivorOrder });\n for (const { item, index } of d.added)\n ops.push({ type: \"add-layer\", layer: item, index });\n return ops;\n};\n\nexport const diffTextStyleOps = (\n prev: readonly TextStyle[],\n next: readonly TextStyle[],\n): Operation[] => {\n const d = diffById(prev, next);\n if (d.duplicateIds)\n return [{ type: \"set-text-styles\", textStyles: [...next] }];\n const ops: Operation[] = d.updated.map((style) => ({\n type: \"update-text-style\",\n style,\n }));\n for (const s of d.removed) ops.push({ type: \"remove-text-style\", id: s.id });\n if (d.orderChanged)\n ops.push({ type: \"reorder-text-styles\", ids: d.survivorOrder });\n for (const { item, index } of d.added)\n ops.push({ type: \"add-text-style\", style: item, index });\n return ops;\n};\n\n/** Name-keyed collection diff (line types, hatch patterns): updates, removes,\n * then indexed adds — no reorder, order carries no meaning. */\nconst diffNamedOps = <T extends { name: string }>(\n prev: readonly T[],\n next: readonly T[],\n key: (name: string) => string,\n make: {\n update(item: T): Operation;\n add(item: T, index: number): Operation;\n remove(name: string): Operation;\n },\n): Operation[] => {\n const prevByKey = new Map(prev.map((x) => [key(x.name), x]));\n const nextKeys = new Set(next.map((x) => key(x.name)));\n const ops: Operation[] = [];\n next.forEach((x) => {\n const p = prevByKey.get(key(x.name));\n if (p && !sameJson(p, x)) ops.push(make.update(x));\n });\n for (const x of prev)\n if (!nextKeys.has(key(x.name))) ops.push(make.remove(x.name));\n next.forEach((x, i) => {\n if (!prevByKey.has(key(x.name))) ops.push(make.add(x, i));\n });\n return ops;\n};\n\nexport const diffLineTypeOps = (\n prev: readonly LineType[],\n next: readonly LineType[],\n): Operation[] =>\n diffNamedOps(prev, next, lineTypeKey, {\n update: (lineType) => ({ type: \"update-line-type\", lineType }),\n add: (lineType, index) => ({ type: \"add-line-type\", lineType, index }),\n remove: (name) => ({ type: \"remove-line-type\", name }),\n });\n\nexport const diffHatchPatternOps = (\n prev: readonly DocumentHatchPattern[],\n next: readonly DocumentHatchPattern[],\n): Operation[] =>\n diffNamedOps(prev, next, hatchPatternKey, {\n update: (hatchPattern) => ({ type: \"update-hatch-pattern\", hatchPattern }),\n add: (hatchPattern, index) => ({\n type: \"add-hatch-pattern\",\n hatchPattern,\n index,\n }),\n remove: (name) => ({ type: \"remove-hatch-pattern\", name }),\n });\n\nexport const diffDimStyleOps = (\n prev: readonly DimStyle[],\n next: readonly DimStyle[],\n): Operation[] => {\n const d = diffById(prev, next);\n if (d.duplicateIds) return [{ type: \"set-dim-styles\", dimStyles: [...next] }];\n const ops: Operation[] = d.updated.map((style) => ({\n type: \"update-dim-style\",\n style,\n }));\n for (const s of d.removed) ops.push({ type: \"remove-dim-style\", id: s.id });\n if (d.orderChanged)\n ops.push({ type: \"reorder-dim-styles\", ids: d.survivorOrder });\n for (const { item, index } of d.added)\n ops.push({ type: \"add-dim-style\", style: item, index });\n return ops;\n};\n\n/**\n * Diff two module-source arrays (block definitions or document commands)\n * into content-addressed ops. The single in-place edit — one source replaced\n * at the same slot, everything else untouched — becomes ONE update op (the\n * Monaco-save / marketplace-upgrade hot path). Everything else decomposes\n * into removes → survivor reorder (when needed) → indexed adds. Arrays with\n * duplicate sources (which content addressing cannot tell apart) fall back\n * to the legacy set op.\n */\nexport const diffModuleOps = (\n prev: readonly string[],\n next: readonly string[],\n field: \"blockDefinitions\" | \"commands\",\n): Operation[] => {\n const block = field === \"blockDefinitions\";\n const prevSet = new Set(prev);\n const nextSet = new Set(next);\n if (prevSet.size !== prev.length || nextSet.size !== next.length)\n return [\n block\n ? { type: \"set-block-definitions\", blockDefinitions: [...next] }\n : { type: \"set-document-commands\", commands: [...next] },\n ];\n if (block) {\n // A removed and an added module with the same block id is an in-place\n // REPLACE (edit, import by id), not delete + add: as an update it keeps\n // its slot and never trips remove-block-definition's in-use rule.\n const addedById = new Map<string, string>();\n for (const s of next)\n if (!prevSet.has(s)) {\n const id = blockScriptId(s);\n if (id !== undefined && !addedById.has(id)) addedById.set(id, s);\n }\n const updates: Operation[] = [];\n const replaced = prev.map((s) => {\n if (nextSet.has(s)) return s;\n const id = blockScriptId(s);\n const to = id === undefined ? undefined : addedById.get(id);\n if (to === undefined || id === undefined) return s;\n addedById.delete(id);\n updates.push({\n type: \"update-block-definition\",\n prevSource: s,\n source: to,\n });\n return to;\n });\n if (updates.length > 0)\n return [...updates, ...diffModuleOps(replaced, next, field)];\n }\n const removed = prev.filter((s) => !nextSet.has(s));\n const added: { source: string; index: number }[] = [];\n next.forEach((s, i) => {\n if (!prevSet.has(s)) added.push({ source: s, index: i });\n });\n const survivorOrder = next.filter((s) => prevSet.has(s));\n const orderChanged =\n prev.filter((s) => nextSet.has(s)).join(\" \") !== survivorOrder.join(\" \");\n if (\n !orderChanged &&\n removed.length === 1 &&\n added.length === 1 &&\n added[0].index === prev.indexOf(removed[0])\n )\n return [\n block\n ? {\n type: \"update-block-definition\",\n prevSource: removed[0],\n source: added[0].source,\n }\n : {\n type: \"update-document-command\",\n prevSource: removed[0],\n source: added[0].source,\n },\n ];\n const ops: Operation[] = removed.map((source) =>\n block\n ? { type: \"remove-block-definition\", source }\n : { type: \"remove-document-command\", source },\n );\n if (orderChanged)\n ops.push(\n block\n ? { type: \"reorder-block-definitions\", sources: survivorOrder }\n : { type: \"reorder-document-commands\", sources: survivorOrder },\n );\n for (const { source, index } of added)\n ops.push(\n block\n ? { type: \"add-block-definition\", source, index }\n : { type: \"add-document-command\", source, index },\n );\n return ops;\n};\n\n/**\n * Diff one space's object array into granular object ops: updates →\n * removes → a reorder of the survivors (when their relative order changed)\n * → indexed adds. Arrays with duplicate ids fall back to a remove-all +\n * add-all pair (nothing granular can express them).\n */\nexport const diffObjectOps = (\n prev: readonly ModelObject[],\n next: readonly ModelObject[],\n space: OpSpace,\n): Operation[] => {\n const d = diffById(prev, next);\n if (d.duplicateIds) {\n const ops: Operation[] = [];\n if (prev.length > 0)\n ops.push({ type: \"remove-objects\", space, ids: prev.map((o) => o.id) });\n if (next.length > 0)\n ops.push({ type: \"add-objects\", space, objects: [...next] });\n return ops;\n }\n const ops: Operation[] = [];\n if (d.updated.length > 0)\n ops.push({ type: \"update-objects\", space, objects: d.updated });\n if (d.removed.length > 0)\n ops.push({\n type: \"remove-objects\",\n space,\n ids: d.removed.map((o) => o.id),\n });\n if (d.orderChanged && d.survivorOrder.length > 0)\n ops.push({\n type: \"reorder-objects\",\n space,\n ids: d.survivorOrder,\n placement: \"back\",\n });\n if (d.added.length > 0)\n ops.push({\n type: \"add-objects\",\n space,\n objects: d.added.map((a) => a.item),\n indices: d.added.map((a) => a.index),\n });\n return ops;\n};\n\n/**\n * Granular ops for an id-keyed resource collection (layers, styles), split\n * into the phase that must run BEFORE dependents change (updates + adds —\n * objects may start referencing the new items) and the phase that must run\n * AFTER (removes — nothing references them any more — plus one reorder when\n * the order the two phases leave behind differs from `next`).\n */\nconst phasedResourceOps = <T extends { id: string }>(\n prev: readonly T[],\n next: readonly T[],\n make: {\n update(item: T): Operation;\n add(item: T, index: number): Operation;\n remove(id: string): Operation;\n reorder(ids: string[]): Operation;\n /** Legacy whole-array op for arrays with duplicate ids. */\n set(items: T[]): Operation;\n },\n): { before: Operation[]; after: Operation[] } => {\n const d = diffById(prev, next);\n if (d.duplicateIds) return { before: [], after: [make.set([...next])] };\n const before: Operation[] = d.updated.map((item) => make.update(item));\n for (const { item, index } of d.added) before.push(make.add(item, index));\n const after: Operation[] = d.removed.map((r) => make.remove(r.id));\n // Adds land at their FINAL index while removed items are still present, so\n // simulate what the two phases leave behind and fix the order if needed.\n const order = prev.map((x) => x.id);\n for (const { item, index } of d.added) order.splice(index, 0, item.id);\n const gone = new Set(d.removed.map((r) => r.id));\n const left = order.filter((id) => !gone.has(id)).join(\" \");\n const target = next.map((x) => x.id);\n if (left !== target.join(\" \")) after.push(make.reorder(target));\n return { before, after };\n};\n\n/**\n * Diff two whole documents into ONE op batch that turns `prev` into `next`\n * — the wire/history-shaped replacement for a wholesale document load. Ops\n * are ordered so referential integrity holds at every step: resources\n * (layers, styles, modules, assets) are added before the objects that use\n * them and removed after; existing layouts are patched by meta + a\n * per-space object diff, missing ones removed, new ones added whole. The\n * document id is NOT an op (identity is the sync scope itself) and must\n * match.\n */\nexport const diffDocumentOps = (\n prev: LineaDocument,\n next: LineaDocument,\n): Operation[] => {\n if (prev.id !== next.id)\n throw new Error(\n `diffDocumentOps: document id mismatch (\"${prev.id}\" vs \"${next.id}\")`,\n );\n const layers = phasedResourceOps(prev.layers, next.layers, {\n update: (layer) => ({ type: \"update-layer\", layer }),\n add: (layer, index) => ({ type: \"add-layer\", layer, index }),\n remove: (id) => ({ type: \"remove-layer\", id }),\n reorder: (ids) => ({ type: \"reorder-layers\", ids }),\n set: (layers) => ({ type: \"set-layers\", layers }),\n });\n const textStyles = phasedResourceOps(prev.textStyles, next.textStyles, {\n update: (style) => ({ type: \"update-text-style\", style }),\n add: (style, index) => ({ type: \"add-text-style\", style, index }),\n remove: (id) => ({ type: \"remove-text-style\", id }),\n reorder: (ids) => ({ type: \"reorder-text-styles\", ids }),\n set: (textStyles) => ({ type: \"set-text-styles\", textStyles }),\n });\n const dimStyles = phasedResourceOps(prev.dimStyles, next.dimStyles, {\n update: (style) => ({ type: \"update-dim-style\", style }),\n add: (style, index) => ({ type: \"add-dim-style\", style, index }),\n remove: (id) => ({ type: \"remove-dim-style\", id }),\n reorder: (ids) => ({ type: \"reorder-dim-styles\", ids }),\n set: (dimStyles) => ({ type: \"set-dim-styles\", dimStyles }),\n });\n\n const ops: Operation[] = [];\n ops.push(...layers.before, ...textStyles.before, ...dimStyles.before);\n ops.push(\n ...diffLineTypeOps(prev.lineTypes, next.lineTypes),\n ...diffHatchPatternOps(prev.hatchPatterns, next.hatchPatterns),\n );\n ops.push(\n ...diffModuleOps(\n prev.blockDefinitions,\n next.blockDefinitions,\n \"blockDefinitions\",\n ),\n ...diffModuleOps(prev.commands, next.commands, \"commands\"),\n );\n for (const [id, dataUrl] of Object.entries(next.assets))\n if (prev.assets[id] !== dataUrl)\n ops.push({ type: \"set-asset\", id, dataUrl });\n\n // Layouts: survivors by meta patch + object diff on their own space, then\n // removes → survivor reorder → indexed adds (the same decomposition as\n // diffObjectOps, so the result is exactly `next`).\n const prevLayouts = new Map(prev.layouts.map((l) => [l.id, l]));\n const nextLayoutIds = new Set(next.layouts.map((l) => l.id));\n for (const layout of next.layouts) {\n const before = prevLayouts.get(layout.id);\n if (!before) continue;\n const patch: Record<string, unknown> = {};\n if (before.name !== layout.name) patch.name = layout.name;\n if (!sameJson(before.sheet, layout.sheet)) patch.sheet = layout.sheet;\n if (before.printPalette !== layout.printPalette)\n patch.printPalette = layout.printPalette;\n if (Object.keys(patch).length > 0)\n ops.push({ type: \"update-layout-meta\", id: layout.id, ...patch });\n ops.push(\n ...diffObjectOps(before.objects, layout.objects, {\n layoutId: layout.id,\n }),\n );\n }\n ops.push(...diffObjectOps(prev.objects, next.objects, \"model\"));\n for (const l of prev.layouts)\n if (!nextLayoutIds.has(l.id)) ops.push({ type: \"remove-layout\", id: l.id });\n const survivors = next.layouts.filter((l) => prevLayouts.has(l.id));\n if (\n survivors.length > 0 &&\n prev.layouts\n .filter((l) => nextLayoutIds.has(l.id))\n .map((l) => l.id)\n .join(\" \") !== survivors.map((l) => l.id).join(\" \")\n )\n ops.push({ type: \"reorder-layouts\", ids: survivors.map((l) => l.id) });\n next.layouts.forEach((layout, index) => {\n if (!prevLayouts.has(layout.id))\n ops.push({ type: \"add-layout\", layout, index });\n });\n\n // Removals, now that nothing references them.\n for (const id of Object.keys(prev.assets))\n if (!(id in next.assets)) ops.push({ type: \"remove-asset\", id });\n if (prev.currentLayerId !== next.currentLayerId)\n ops.push({ type: \"set-current-layer\", id: next.currentLayerId });\n if (JSON.stringify(prev.settings) !== JSON.stringify(next.settings))\n ops.push({ type: \"set-document-settings\", settings: next.settings });\n ops.push(...dimStyles.after, ...textStyles.after, ...layers.after);\n return ops;\n};\n","// Applying a DXF conversion to a document — ONE rule for every host (the\n// SDK / agent `importDxfText`, the editor's file drop and Import menu), so\n// an import is the same edit everywhere: the same block-module merge and\n// one batch of operations = one undo step. The conversion itself\n// (dxfToModel) stays pure and worker-safe; this is the main-thread half.\n\nimport type { LineaDocument } from \"../../model/document\";\nimport { ModelObjectSchema, type ModelObject } from \"../../model/objects\";\nimport { getBlockMetaResult, blockScriptId } from \"../../extensions/evalBlock\";\nimport {\n diffDimStyleOps,\n diffHatchPatternOps,\n diffLineTypeOps,\n diffModuleOps,\n diffTextStyleOps,\n} from \"../../operations/diff\";\nimport type { Operation } from \"../../operations/types\";\nimport type { DxfImportContext, DxfImportResult } from \"./importDxf\";\n\n/** What the conversion needs from the document it merges into. Block names\n * resolve only once the script transpiler is up (`ensureScriptTranspiler`);\n * before that a clash goes unsuffixed. */\nexport const dxfImportContextOf = (\n doc: LineaDocument,\n unitOverride?: number,\n): DxfImportContext => ({\n existingLayers: doc.layers.map((l) => ({ id: l.id, name: l.name })),\n defaultLayerId: doc.currentLayerId,\n existingTextStyles: doc.textStyles,\n existingDimStyles: doc.dimStyles,\n existingLineTypes: doc.lineTypes,\n existingHatchPatterns: doc.hatchPatterns,\n existingBlocks: doc.blockDefinitions.flatMap((source) => {\n const meta = getBlockMetaResult(source);\n if (meta.ok) return [{ id: meta.meta.id, name: meta.meta.name }];\n const id = blockScriptId(source);\n return id ? [{ id, name: \"\" }] : [];\n }),\n // Nothing drawn yet: the file's styles become the document's.\n adoptStyles:\n doc.objects.length === 0 &&\n doc.layouts.every((l) => l.objects.length === 0),\n unitOverride,\n});\n\n/** The operations that merge a conversion into `doc`: layers, styles and\n * definitions before the objects that reference them, block modules, the\n * model-space objects (ids assigned here), then the layouts. */\nexport const dxfImportOps = (\n doc: LineaDocument,\n result: DxfImportResult,\n): { ops: Operation[]; objects: ModelObject[] } => {\n const objects = result.objects.map((o) =>\n ModelObjectSchema.parse({ ...o, id: crypto.randomUUID() }),\n );\n const ops: Operation[] = [\n ...result.newLayers.map((layer) => ({ type: \"add-layer\" as const, layer })),\n ...diffTextStyleOps(doc.textStyles, result.textStyles),\n ...diffDimStyleOps(doc.dimStyles, result.dimStyles),\n ...diffLineTypeOps(doc.lineTypes, result.lineTypes),\n ...diffHatchPatternOps(doc.hatchPatterns, result.hatchPatterns),\n // The conversion already left out modules the document holds and\n // suffixed name clashes (DxfImportContext.existingBlocks).\n ...diffModuleOps(\n doc.blockDefinitions,\n [...doc.blockDefinitions, ...result.newBlockDefinitions],\n \"blockDefinitions\",\n ),\n ...(objects.length > 0\n ? [{ type: \"add-objects\" as const, space: \"model\" as const, objects }]\n : []),\n ...result.layouts.map((layout) => ({\n type: \"add-layout\" as const,\n layout,\n })),\n ];\n return { ops, objects };\n};\n","// DWG support is a byte-level transcode at the file boundary: DWG bytes ↔\n// DXF text via @lineadraw/dwg-wasm (acadrust compiled to WebAssembly, lazy-loaded\n// on first use — instantiation is cached inside the package's loader).\n// Callers compose these with dxfToModel / buildDxf; core's model stays\n// DXF-shaped and never sees acadrust's document.\n\nexport type DwgVersion =\n | \"AC1015\" // AutoCAD 2000\n | \"AC1018\" // AutoCAD 2004\n | \"AC1021\" // AutoCAD 2007\n | \"AC1024\" // AutoCAD 2010\n | \"AC1027\" // AutoCAD 2013\n | \"AC1032\"; // AutoCAD 2018\n\nconst loadDwg = () => import(\"@lineadraw/dwg-wasm\").then((m) => m.loadDwg());\n\n/** DWG bytes → ASCII DXF text (compose with dxfToModel). */\nexport const dwgToDxf = async (data: Uint8Array): Promise<string> => {\n const { dwg_to_dxf } = await loadDwg();\n return dwg_to_dxf(data);\n};\n\n/** DXF text (e.g. buildDxf output) → DWG bytes. Defaults to AC1027 when the\n * DXF carries no usable $ACADVER. */\nexport const dxfToDwg = async (\n dxf: string,\n version?: DwgVersion,\n): Promise<Uint8Array> => {\n const { dxf_to_dwg } = await loadDwg();\n // acadrust cannot parse xdata on STYLE table records — strip the typeface\n // triplets buildDxf injects for CAD font resolution (see exportDxf's\n // injectStyleTypefaces) before transcoding. DWG output keeps the plain\n // file-name reference; lifting this needs xdata support in acadrust.\n return dxf_to_dwg(\n dxf.replace(/\\n1001\\nACAD\\n1000\\n[^\\n]*\\n1071\\n0(?=\\n)/g, \"\"),\n version,\n );\n};\n","// Vector PDF export: one page per layout, rendered through the very same\n// paintLayoutContent (and per-layout print palette) as the on-screen paper\n// space, so what you see is what prints. Pure/headless — the editor wraps\n// this with the store read, file naming, and save/toast.\n\nimport { jsPDF } from \"jspdf\";\nimport type { PaperLayout } from \"../../model/paperLayout\";\nimport type { LineaDocument } from \"../../model/document\";\nimport {\n dimFontFace,\n dimStyleFor,\n effectiveTextFont,\n type ModelObject,\n type TextSpan,\n} from \"../../model/objects\";\nimport {\n FONTS,\n fontFace,\n parseFontFace,\n REAL_FACES,\n realFace,\n resolveFont,\n} from \"../../model/fonts\";\nimport { PDF_FALLBACK_FONT, pdfFontCovers } from \"../../paint/fontCoverage\";\nimport {\n paintLayoutContent,\n type LayoutModelContext,\n} from \"../../paint/layoutPaint\";\nimport { printColorMapper } from \"../../paint/printPalette\";\nimport { PdfSink } from \"./pdfSink\";\nimport { tableLayout } from \"../../paint/tableLayout\";\n\n/** A TTF to embed, registered under its font id (see PaintEnv fonts). */\nexport interface PdfEmbedFont {\n /** Font id from model/fonts.ts — texts reference it via TextSpec.font —\n * or a bundled styled face (\"arial;b\", model/fonts.ts REAL_FACES). */\n id: string;\n /** TrueType (glyf) file as base64 — jsPDF cannot embed CFF/OTF. */\n ttfBase64: string;\n}\n\n/** Embeddable (pdf: \"embed\") font ids the document's text/dimensions\n * actually use — so exports only carry the TTFs they need. Block instances\n * are counted conservatively (their scripts may emit text in any font).\n * When a text's font cannot encode its content in PDF (arial + Cyrillic,\n * a handwriting font's missing glyphs), the sink substitutes\n * PDF_FALLBACK_FONT per string — so its TTF must ride along too. */\nexport const usedEmbedFontIds = (doc: LineaDocument): Set<string> => {\n const ids = new Set<string>();\n let hasBlocks = false;\n const add = (font: string | undefined, content: string) => {\n ids.add(resolveFont(font).id);\n // A bundled bold/italic face embeds as its own TTF.\n const face = realFace(font);\n if (face) ids.add(face);\n if (!pdfFontCovers(font, content)) ids.add(PDF_FALLBACK_FONT);\n };\n /** A base face over `content`, plus the faces its spans switch to. */\n const addFormatted = (\n base: string | undefined,\n content: string,\n spans: readonly TextSpan[] | undefined,\n ) => {\n add(base, content);\n const { font, bold, italic } = parseFontFace(base);\n for (const s of spans ?? [])\n add(\n fontFace(s.font ?? font, s.bold ?? bold, s.italic ?? italic),\n content.slice(s.start, s.end),\n );\n };\n const visit = (o: ModelObject) => {\n if (o.type === \"text\")\n addFormatted(\n effectiveTextFont(o, doc.textStyles).font,\n o.content,\n o.spans,\n );\n else if (o.type === \"dimension\") {\n const face = dimFontFace({\n ...dimStyleFor(o, doc.dimStyles),\n ...o.styleOverride,\n });\n // Computed measurement text is ASCII; only label content can need more.\n for (const l of o.labels) addFormatted(face, l.content ?? \"\", l.spans);\n } else if (o.type === \"table\") {\n // Every cell is a text child (same derivation the painter draws).\n for (const c of tableLayout(o, doc.textStyles).children) {\n if (c.type === \"text\")\n addFormatted(\n effectiveTextFont(c, doc.textStyles).font,\n c.content,\n c.spans,\n );\n }\n } else if (o.type === \"block\") hasBlocks = true;\n };\n doc.objects.forEach(visit);\n for (const layout of doc.layouts) layout.objects.forEach(visit);\n if (hasBlocks)\n for (const id of [...Object.keys(FONTS), ...REAL_FACES]) ids.add(id);\n for (const id of [...ids])\n if (resolveFont(id).pdf !== \"embed\") ids.delete(id);\n return ids;\n};\n\n/**\n * Strip objects on non-print layers (Layer.print === false — the AutoCAD\n * plot flag) from the model and the sheets. Viewports are kept regardless of\n * their layer: they are windows, and their frames never print anyway.\n */\nexport const stripNonPrintLayers = (\n layouts: PaperLayout[],\n model: LayoutModelContext,\n): { layouts: PaperLayout[]; model: LayoutModelContext } => {\n const noPrint = new Set(\n model.layers.filter((l) => l.print === false).map((l) => l.id),\n );\n if (noPrint.size === 0) return { layouts, model };\n return {\n model: {\n ...model,\n objects: model.objects.filter((o) => !noPrint.has(o.layerId)),\n },\n layouts: layouts.map((layout) => ({\n ...layout,\n objects: layout.objects.filter(\n (o) => o.type === \"viewport\" || !noPrint.has(o.layerId),\n ),\n })),\n };\n};\n\n/**\n * Render one or more paper layouts to a vector PDF (one page each).\n * `layouts` must be non-empty (the first sets the initial page size).\n * Fonts with pdf=\"embed\" render as Helvetica unless supplied in `fonts`.\n * Layers with `print: false` are excluded (screen-only layers).\n */\nexport const renderLayoutsToPdf = (\n printLayouts: PaperLayout[],\n printModel: LayoutModelContext,\n fonts: PdfEmbedFont[] = [],\n): jsPDF => {\n const { layouts, model } = stripNonPrintLayers(printLayouts, printModel);\n const first = layouts[0];\n const pdf = new jsPDF({\n unit: \"mm\",\n format: [first.sheet.width, first.sheet.height],\n orientation:\n first.sheet.width >= first.sheet.height ? \"landscape\" : \"portrait\",\n compress: true,\n });\n for (const font of fonts) {\n pdf.addFileToVFS(`${font.id}.ttf`, font.ttfBase64);\n pdf.addFont(`${font.id}.ttf`, font.id, \"normal\");\n }\n // One advancedAPI scope PER PAGE: jsPDF installs its mm→pt change-of-basis\n // matrix only on the page that is current when the mode switches (and\n // writes the balancing restore to the page current when it ends), so\n // adding pages inside a single advanced scope leaves every later page\n // without the matrix — content lands unscaled (pt-sized) in the corner\n // and the state stack unbalances.\n layouts.forEach((layout, index) => {\n if (index > 0) {\n pdf.addPage(\n [layout.sheet.width, layout.sheet.height],\n layout.sheet.width >= layout.sheet.height ? \"landscape\" : \"portrait\",\n );\n }\n pdf.advancedAPI((advanced) => {\n const sink = new PdfSink(advanced, layout.sheet.height);\n paintLayoutContent(layout, sink, model, {\n mapColor: printColorMapper(layout.printPalette),\n });\n });\n });\n return pdf;\n};\n","// GeometrySink over jsPDF. Note: jsPDF's \"advanced\" API mode is NOT\n// PDF-native y-up — it installs a global CTM of [s 0 0 -s 0 pageHeight],\n// so user coordinates are y-DOWN millimeters from the TOP-LEFT (verified\n// against the generated content stream). Our sheet space is y-up from the\n// bottom-left, so the matrix stack bottoms out at a y-flip.\n// Transforms are baked in JS, so clipping and lineweights stay trivially\n// correct.\n\nimport type jsPDF from \"jspdf\";\nimport type {\n FillStyle,\n GeometrySink,\n ImageSpec,\n Mat2x3,\n Rect,\n StrokeStyle,\n TextSpec,\n} from \"../../paint/sink\";\nimport {\n arcToBeziers,\n ellipseArcToBeziers,\n matApply,\n matMultiply,\n signedArcSweep,\n} from \"../../paint/sink\";\nimport { parseFontFace, realFace, resolveFont } from \"../../model/fonts\";\nimport {\n PDF_FALLBACK_FONT,\n pdfFontCovers,\n winAnsiEncodable,\n} from \"../../paint/fontCoverage\";\nimport type { Vec2 } from \"../../geometry/vec2\";\n\nconst PT_PER_MM = 72 / 25.4;\n\n/** Synthesized italic slant (tan of the skew angle, ~14°) — Skia's fake\n * italic, so a synthesized PDF face leans like the canvas one. */\nconst SYNTH_ITALIC_SKEW = 0.25;\n/** Synthesized bold: outline stroke width as a fraction of the cap height. */\nconst SYNTH_BOLD_STROKE = 0.04;\n\n/** #rrggbb → [r, g, b] 0-255 (jsPDF shading stop format). */\nconst hexToRgb255 = (hex: string): number[] => {\n const m = /^#?([0-9a-f]{6})$/i.exec(hex.trim());\n const v = m ? Number.parseInt(m[1], 16) : 0;\n return [(v >> 16) & 0xff, (v >> 8) & 0xff, v & 0xff];\n};\n\nexport class PdfSink implements GeometrySink {\n private readonly doc: jsPDF;\n private matrixStack: Mat2x3[];\n private pathOpen = false;\n private pathStart: Vec2 | null = null;\n private current: Vec2 | null = null;\n private gradId = 0;\n\n constructor(doc: jsPDF, sheetHeightMm: number) {\n this.doc = doc;\n // Base flip: sheet (y-up, origin bottom-left) → jsPDF advanced user\n // space (y-down, origin top-left).\n this.matrixStack = [[1, 0, 0, -1, 0, sheetHeightMm]];\n }\n\n private get matrix(): Mat2x3 {\n return this.matrixStack[this.matrixStack.length - 1];\n }\n\n private map(p: Vec2): Vec2 {\n return matApply(this.matrix, p);\n }\n\n /** Uniform scale of the current transform (for angle-preserving checks). */\n private get scaleFactor(): number {\n const m = this.matrix;\n return Math.hypot(m[0], m[1]);\n }\n\n /**\n * The font DEFINITION a string actually renders with: the requested font,\n * unless it cannot render the text in PDF — an embedded TTF lacking the\n * glyphs (the handwriting fonts + Cyrillic = tofu), or a font degrading to\n * base-14 Helvetica because its TTF was not registered (WinAnsi-only →\n * Cyrillic mojibake) — in which case the fallback substitutes per string\n * when IT can render the text. Size must then use THIS def's capHeight,\n * so callers take the def, not just a name.\n */\n private pdfFontDef(font: string | undefined, text: string) {\n // Coverage of what will ACTUALLY render: an unregistered \"embed\" font\n // becomes base-14 Helvetica, so it is judged by WinAnsi, not its table.\n const usable = (def: ReturnType<typeof resolveFont>) =>\n def.pdf === \"embed\" && this.doc.getFontList()[def.id]\n ? pdfFontCovers(def.id, text)\n : winAnsiEncodable(text);\n const def = resolveFont(font);\n if (usable(def)) return def;\n const fallback = resolveFont(PDF_FALLBACK_FONT);\n return usable(fallback) ? fallback : def;\n }\n\n /**\n * jsPDF font name for a font def: built-ins map directly; \"embed\" fonts\n * must have been registered (addFileToVFS/addFont under the font id) by\n * the exporting host — fall back to helvetica when they weren't.\n */\n private pdfFontName(def: ReturnType<typeof resolveFont>): string {\n if (def.pdf !== \"embed\") return def.pdf;\n return this.doc.getFontList()[def.id] ? def.id : \"helvetica\";\n }\n\n beginPath(): void {\n this.pathOpen = false;\n this.pathStart = null;\n this.current = null;\n }\n\n moveTo(p: Vec2): void {\n const q = this.map(p);\n this.doc.moveTo(q.x, q.y);\n this.pathOpen = true;\n this.pathStart = q;\n this.current = q;\n }\n\n lineTo(p: Vec2): void {\n const q = this.map(p);\n this.doc.lineTo(q.x, q.y);\n this.current = q;\n }\n\n bezierTo(c1: Vec2, c2: Vec2, end: Vec2): void {\n const q1 = this.map(c1);\n const q2 = this.map(c2);\n const qe = this.map(end);\n this.doc.curveTo(q1.x, q1.y, q2.x, q2.y, qe.x, qe.y);\n this.current = qe;\n }\n\n arc(\n center: Vec2,\n r: number,\n startAngle: number,\n endAngle: number,\n ccw: boolean,\n ): void {\n // Emit in the LOCAL frame and map each bezier point — uniform transforms\n // preserve circles as scaled circles, and beziers survive any affine map.\n const beziers = arcToBeziers(\n center,\n r,\n startAngle,\n signedArcSweep(startAngle, endAngle, ccw),\n );\n this.emitBeziers(beziers);\n }\n\n ellipse(\n center: Vec2,\n rx: number,\n ry: number,\n rotation: number,\n startAngle: number,\n endAngle: number,\n ): void {\n this.emitBeziers(\n ellipseArcToBeziers(\n center,\n rx,\n ry,\n rotation,\n startAngle,\n signedArcSweep(startAngle, endAngle, true),\n ),\n );\n }\n\n private emitBeziers(\n beziers: { start: Vec2; c1: Vec2; c2: Vec2; end: Vec2 }[],\n ): void {\n if (beziers.length === 0) return;\n const first = this.map(beziers[0].start);\n if (!this.pathOpen || !this.current) {\n this.doc.moveTo(first.x, first.y);\n this.pathOpen = true;\n this.pathStart = first;\n } else if (\n Math.hypot(this.current.x - first.x, this.current.y - first.y) > 1e-6\n ) {\n this.doc.lineTo(first.x, first.y);\n }\n for (const b of beziers) {\n const q1 = this.map(b.c1);\n const q2 = this.map(b.c2);\n const qe = this.map(b.end);\n this.doc.curveTo(q1.x, q1.y, q2.x, q2.y, qe.x, qe.y);\n this.current = qe;\n }\n }\n\n closePath(): void {\n this.doc.close();\n this.current = this.pathStart;\n }\n\n /**\n * Run `paint` with a per-op transparency GState when opacity < 1. jsPDF\n * buffers path construction until the painting call, so the q/gs pair\n * lands BEFORE the path in the content stream (the image() pattern).\n */\n private withOpacity(opacity: number | undefined, paint: () => void): void {\n const translucent = opacity !== undefined && opacity < 1;\n if (translucent) {\n this.doc.saveGraphicsState();\n this.doc.setGState(\n this.doc.GState({ opacity, \"stroke-opacity\": opacity }),\n );\n }\n paint();\n if (translucent) this.doc.restoreGraphicsState();\n }\n\n stroke(s: StrokeStyle): void {\n if (!this.pathOpen) return;\n this.doc.setDrawColor(s.color);\n this.doc.setLineWidth(Math.max(s.widthMm, 0.05));\n this.doc.setLineCap(\"round\");\n this.doc.setLineJoin(\"round\");\n this.doc.setLineDashPattern(s.dashMm ?? [], 0);\n this.withOpacity(s.opacity, () => this.doc.stroke());\n this.doc.setLineDashPattern([], 0);\n this.beginPath();\n }\n\n fill(f: FillStyle): void {\n if (!this.pathOpen) return;\n if (f.gradient) {\n // Axial/radial shading between the two colors; endpoints go through\n // the same matrix as the path, so the ramp stays anchored to the\n // geometry. Radial radius scales by the (uniform) transform.\n const a = this.map(f.gradient.from);\n const b = this.map(f.gradient.to);\n const key = `linea-grad-${this.gradId++}`;\n const coords =\n f.gradient.shape === \"radial\"\n ? [a.x, a.y, 0, a.x, a.y, Math.hypot(b.x - a.x, b.y - a.y)]\n : [a.x, a.y, b.x, b.y];\n this.doc.addShadingPattern(\n key,\n this.doc.ShadingPattern(\n f.gradient.shape === \"radial\" ? \"radial\" : \"axial\",\n coords,\n [\n { offset: 0, color: hexToRgb255(f.color) },\n { offset: 1, color: hexToRgb255(f.gradient.color2) },\n ],\n ),\n );\n // jsPDF requires a pattern matrix for shading fills (it stringifies\n // it unconditionally); identity keeps coords in path user space.\n this.withOpacity(f.opacity, () =>\n this.doc.fillEvenOdd({ key, matrix: this.doc.unitMatrix }),\n );\n this.beginPath();\n return;\n }\n this.doc.setFillColor(f.color);\n this.withOpacity(f.opacity, () => this.doc.fillEvenOdd());\n this.beginPath();\n }\n\n /**\n * The jsPDF font a face renders with + what must be synthesized: a styled\n * face uses its bundled TTF when the host registered it, otherwise the\n * regular font with fake bold (fill+stroke) / italic (skew). A coverage\n * fallback (pdfFontDef swapped the font) synthesizes too.\n */\n private pdfFace(font: string | undefined, text: string) {\n const def = this.pdfFontDef(font, text);\n const { bold, italic } = parseFontFace(font);\n const face = def.id === resolveFont(font).id ? realFace(font) : null;\n const real = face && this.doc.getFontList()[face] ? face : null;\n return {\n def,\n name: real ?? this.pdfFontName(def),\n synthBold: bold && !real,\n synthItalic: italic && !real,\n };\n }\n\n text(t: TextSpec): void {\n const heightMm = t.heightMm * this.scaleFactor;\n const { def, name, synthBold, synthItalic } = this.pdfFace(t.font, t.text);\n this.doc.setFont(name, \"normal\");\n // Model heights are CAP heights; PDF font size is the em.\n this.doc.setFontSize((heightMm / def.capHeight) * PT_PER_MM);\n this.doc.setTextColor(t.color);\n const widthFactor = t.widthFactor ?? 1;\n // jsPDF's own align/baseline offsets are broken in advanced mode (it\n // divides them by scaleFactor although text space is already mm-scaled),\n // so we place the exact baseline-left anchor ourselves — in cap-height\n // terms, matching canvasSink: bottom = baseline at the anchor, center /\n // top shift the baseline by half / full cap height.\n const width =\n (this.doc.getTextWidth(t.text) / this.scaleFactor) * widthFactor;\n const dx =\n t.hAlign === \"center\" ? -width / 2 : t.hAlign === \"right\" ? -width : 0;\n const dy =\n t.vAlign === \"center\"\n ? t.heightMm / 2\n : t.vAlign === \"top\"\n ? t.heightMm\n : 0;\n // Local text frame (y-up): run along the rotation, baseline dy below.\n const cos = Math.cos(t.rotation);\n const sin = Math.sin(t.rotation);\n const anchor = this.map({\n x: t.anchor.x + cos * dx + sin * dy,\n y: t.anchor.y + sin * dx - cos * dy,\n });\n const m = this.matrix;\n const extraRotation = Math.atan2(m[1], m[0]);\n const draw = () =>\n this.doc.text(t.text, anchor.x, anchor.y, {\n angle: ((t.rotation + extraRotation) * 180) / Math.PI,\n align: \"left\",\n baseline: \"alphabetic\",\n // AutoCAD-style width factor → PDF Tz horizontal scaling. ALWAYS\n // set: Tz is graphics state and persists across BT/ET, so an\n // omitted value inherits whatever the previous text left behind\n // (a 0.8-factor text would silently squeeze every later text).\n horizontalScale: widthFactor,\n // Same reason: Tr persists, so plain text resets it to fill.\n renderingMode: synthBold ? \"fillThenStroke\" : \"fill\",\n });\n if (!synthBold && !synthItalic) {\n this.withOpacity(t.opacity, draw);\n return;\n }\n this.doc.saveGraphicsState();\n if (synthBold) {\n this.doc.setDrawColor(t.color);\n this.doc.setLineWidth(heightMm * SYNTH_BOLD_STROKE);\n }\n if (synthItalic) {\n // Shear about the anchor along the text's page-space baseline: a\n // point h above the baseline moves k·h along it. Directions come from\n // the current transform, so any y-flip in it can't invert the slant.\n const w0 = t.anchor;\n const p0 = this.map(w0);\n const unit = (p: Vec2) => {\n const v = { x: p.x - p0.x, y: p.y - p0.y };\n const l = Math.hypot(v.x, v.y) || 1;\n return { x: v.x / l, y: v.y / l };\n };\n const d = unit(this.map({ x: w0.x + cos, y: w0.y + sin }));\n const u = unit(this.map({ x: w0.x - sin, y: w0.y + cos }));\n const k = SYNTH_ITALIC_SKEW;\n const a = 1 + k * d.x * u.x;\n const b = k * d.y * u.x;\n const c = k * d.x * u.y;\n const e = 1 + k * d.y * u.y;\n this.doc.setCurrentTransformationMatrix(\n this.doc.Matrix(\n a,\n b,\n c,\n e,\n anchor.x - (a * anchor.x + c * anchor.y),\n anchor.y - (b * anchor.x + e * anchor.y),\n ),\n );\n }\n this.withOpacity(t.opacity, draw);\n this.doc.restoreGraphicsState();\n }\n\n measureText(\n text: string,\n heightMm: number,\n font?: string,\n widthFactor = 1,\n ): { width: number } {\n const { def, name } = this.pdfFace(font, text);\n this.doc.setFont(name, \"normal\");\n this.doc.setFontSize((heightMm / def.capHeight) * PT_PER_MM);\n return { width: this.doc.getTextWidth(text) * widthFactor };\n }\n\n image(i: ImageSpec): void {\n // Compose a local frame whose y-DOWN [0..w]×[0..h] box (top-left at the\n // local origin — jsPDF advanced user-space semantics) is exactly the\n // image footprint, and install it as the CTM for one addImage call.\n const cos = Math.cos(i.rotation);\n const sin = Math.sin(i.rotation);\n const place: Mat2x3 = [cos, sin, -sin, cos, i.origin.x, i.origin.y];\n const flip: Mat2x3 = [1, 0, 0, -1, 0, i.heightMm];\n const m = matMultiply(matMultiply(this.matrix, place), flip);\n this.doc.saveGraphicsState();\n if (i.opacity < 1)\n this.doc.setGState(this.doc.GState({ opacity: i.opacity }));\n this.doc.setCurrentTransformationMatrix(\n this.doc.Matrix(m[0], m[1], m[2], m[3], m[4], m[5]),\n );\n const format = i.data.startsWith(\"data:image/png\") ? \"PNG\" : \"JPEG\";\n this.doc.addImage(\n i.data,\n format,\n 0,\n 0,\n i.widthMm,\n i.heightMm,\n undefined,\n \"FAST\",\n );\n this.doc.restoreGraphicsState();\n this.beginPath();\n }\n\n pushTransform(m: Mat2x3): void {\n this.matrixStack.push(matMultiply(this.matrix, m));\n }\n\n popTransform(): void {\n if (this.matrixStack.length > 1) this.matrixStack.pop();\n }\n\n pushClipRect(r: Rect): void {\n const p = this.map({ x: r.x, y: r.y });\n const q = this.map({ x: r.x + r.w, y: r.y + r.h });\n this.doc.saveGraphicsState();\n this.doc.moveTo(Math.min(p.x, q.x), Math.min(p.y, q.y));\n this.doc.lineTo(Math.max(p.x, q.x), Math.min(p.y, q.y));\n this.doc.lineTo(Math.max(p.x, q.x), Math.max(p.y, q.y));\n this.doc.lineTo(Math.min(p.x, q.x), Math.max(p.y, q.y));\n this.doc.close();\n this.doc.clip();\n this.doc.discardPath();\n this.beginPath();\n }\n\n popClip(): void {\n this.doc.restoreGraphicsState();\n }\n}\n","// High-level SVG rendering — the SVG counterpart to renderLayoutsToPdf. Paints\n// through the shared painters into an SvgSink, so SVG output matches screen and\n// PDF. `renderModelToSvg` frames the content bbox; `renderLayoutToSvg` frames a\n// sheet.\n\nimport { SvgSink } from \"./svgSink\";\nimport {\n paintLayoutContent,\n type LayoutModelContext,\n} from \"../../paint/layoutPaint\";\nimport { paintObject } from \"../../paint/painters\";\nimport { rebaseSink } from \"../../paint/rebaseSink\";\nimport { printColorMapper } from \"../../paint/printPalette\";\nimport { resolveStyle } from \"../../paint/style\";\nimport type { PrintPalette } from \"../../model/paperLayout\";\nimport { approximateTextMeasurer } from \"../../paint/textMeasurer\";\nimport type { TextMeasurer } from \"../../paint/textMetrics\";\nimport { buildSnapEntry } from \"../../snap/buildEntry\";\nimport {\n addPointToBounds,\n boundsIntersect,\n emptyBounds,\n isEmptyBounds,\n unionBounds,\n type AABB,\n} from \"../../geometry/bounds\";\nimport type { PaperLayout } from \"../../model/paperLayout\";\n\nexport interface SvgRenderOptions {\n /** Frame this world box instead of the content bounds. */\n bbox?: AABB;\n /** Text width measurement (defaults to the approximate Inter table). */\n measure?: TextMeasurer;\n /** Padding around the frame, world mm. */\n padding?: number;\n /**\n * Print-style color remap (same mapper as the PDF export): \"monochrome\"\n * turns every stroke black — the fix for light editor-theme layers\n * vanishing on a white background. Model render default: \"color\" (none);\n * layout render default: the layout's own printPalette.\n */\n palette?: PrintPalette;\n /**\n * Minimum stroke width as a FRACTION of the frame's larger side —\n * for thumbnails, where a fixed-mm lineweight scaled to a ~256px image\n * turns sub-pixel and the render rasterizes to nothing. E.g. a value of\n * 1.5/256 keeps every stroke ≥ ~1.5px when the render is displayed 256px\n * wide, regardless of drawing extents. Model render only.\n */\n minStrokeFrac?: number;\n}\n\n/** Render model space (the given objects) to an SVG string. */\nexport const renderModelToSvg = (\n model: LayoutModelContext,\n opts: SvgRenderOptions = {},\n): string => {\n const measure = opts.measure ?? approximateTextMeasurer;\n // No palette = as-authored colors verbatim: even \"color\" flips light\n // neutrals for paper, which would silently change every existing\n // dark-canvas model render. Mapping is strictly opt-in here.\n const mapColor = opts.palette\n ? printColorMapper(opts.palette)\n : (c: string) => c;\n const layerVisible = new Map(model.layers.map((l) => [l.id, l.visible]));\n const layerName = new Map(model.layers.map((l) => [l.id, l.name]));\n // Pass 1 — the frame: minStrokeFrac needs the final extents before any\n // stroke is emitted, so bounds are collected ahead of painting.\n const toPaint: (typeof model.objects)[number][] = [];\n let bbox = opts.bbox ?? emptyBounds();\n for (const obj of model.objects) {\n if (layerVisible.get(obj.layerId) === false) continue;\n const b = buildSnapEntry(obj, {\n dimStyles: model.dimStyles,\n textStyles: model.textStyles,\n blockDefinitions: model.blockDefinitions,\n resolveObject: model.resolveObject,\n resolveReference: model.resolveReference,\n measure,\n }).bounds;\n if (opts.bbox) {\n // A bbox crop culls, not just frames: off-view geometry must not ride\n // along invisibly in the file (size, and it leaks unshared content).\n if (isEmptyBounds(b) || !boundsIntersect(b, opts.bbox)) continue;\n } else if (!isEmptyBounds(b)) {\n bbox = unionBounds(bbox, b);\n }\n toPaint.push(obj);\n }\n if (isEmptyBounds(bbox)) addPointToBounds(bbox, { x: 0, y: 0 });\n\n // Pass 2 — paint into a sink that clamps hairlines relative to the frame.\n const minStrokeWidthMm = opts.minStrokeFrac\n ? opts.minStrokeFrac *\n Math.max(bbox.maxX - bbox.minX, bbox.maxY - bbox.minY)\n : undefined;\n const sink = new SvgSink({ measure, minStrokeWidthMm });\n // A drawing far from the origin (survey coordinates) is written relative\n // to its frame's corner: SVG viewers render in float32 and would quantize\n // 10¹⁰-mm coordinates to metres. ponytail: below FAR_MM it stays absolute\n // (readers/agents may rely on real coordinates) — always rebase if that\n // ever matters less than consistency.\n const far =\n Math.max(\n Math.abs(bbox.minX),\n Math.abs(bbox.maxX),\n Math.abs(bbox.minY),\n Math.abs(bbox.maxY),\n ) > FAR_MM;\n const origin = far ? { x: bbox.minX, y: bbox.minY } : { x: 0, y: 0 };\n const out = rebaseSink(sink, origin);\n for (const obj of toPaint) {\n const style = resolveStyle(obj, model.layers, model.lineTypes);\n sink.beginObject(obj.id, layerName.get(obj.layerId));\n paintObject(obj, out, {\n style: { ...style, color: mapColor(style.color) },\n ...model,\n mapColor,\n });\n sink.endObject();\n }\n return sink.toSvg(\n {\n minX: bbox.minX - origin.x,\n minY: bbox.minY - origin.y,\n maxX: bbox.maxX - origin.x,\n maxY: bbox.maxY - origin.y,\n },\n opts.padding,\n );\n};\n\n/** Beyond 10 km from the origin an SVG is written relative to its frame. */\nconst FAR_MM = 1e7;\n\n/**\n * Render a paper layout (viewport content + sheet annotations) to SVG, framed\n * to the sheet. Note: viewport clipping is not yet enforced by SvgSink (v1).\n */\nexport const renderLayoutToSvg = (\n layout: PaperLayout,\n model: LayoutModelContext,\n opts: SvgRenderOptions = {},\n): string => {\n const sink = new SvgSink({ measure: opts.measure });\n // Honor the layout's own print palette (like the PDF export) unless the\n // caller overrides it.\n paintLayoutContent(layout, sink, model, {\n mapColor: printColorMapper(opts.palette ?? layout.printPalette),\n });\n const bbox = opts.bbox ?? {\n minX: 0,\n minY: 0,\n maxX: layout.sheet.width,\n maxY: layout.sheet.height,\n };\n return sink.toSvg(bbox, opts.padding ?? 0);\n};\n","// One PDF page → model object DTOs: STROKED paths become lines/polylines,\n// text runs become text objects. Pure — it consumes pdf.js v6\n// getOperatorList()/getTextContent() output with the OPS enum injected, so\n// tests can drive it with the node-safe legacy build.\n//\n// pdf.js v6 fuses path construction with its paint op: constructPath args are\n// [paintOp, [flatPathData], minMax] where the flat data interleaves DrawOPS\n// codes (0 moveTo, 1 lineTo, 2 cubic, 3 quadratic, 4 closePath) with coords.\n// Colors arrive pre-normalized as \"#rrggbb\" strings.\n\nimport type { ModelObjectDto } from \"../../model/objects\";\nimport type { Vec2 } from \"../../geometry/vec2\";\nimport {\n matApply,\n matIdentity,\n matMultiply,\n type Mat2x3,\n} from \"../../paint/sink\";\n\nconst PT2MM = 25.4 / 72;\nconst BEZIER_STEPS = 12;\n\n/**\n * Colors in PDFs are authored for white paper; dark neutrals (black/dark-gray\n * ink) map to byLayer (undefined) so they stay visible on the dark canvas.\n */\nconst importColor = (hex: string): string | undefined => {\n const m = /^#([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})$/i.exec(hex);\n if (!m) return undefined;\n const [r, g, b] = [m[1], m[2], m[3]].map((h) => parseInt(h, 16));\n const lum = (0.2126 * r + 0.7152 * g + 0.0722 * b) / 255;\n const saturation = (Math.max(r, g, b) - Math.min(r, g, b)) / 255;\n return lum < 0.35 && saturation < 0.25 ? undefined : hex.toLowerCase();\n};\n\nexport interface PdfTextItem {\n str: string;\n /** Text matrix in page space (pt, y-up): [a, b, c, d, tx, ty]. */\n transform: number[];\n}\n\nexport interface PdfPageInput {\n fnArray: number[];\n argsArray: unknown[];\n textItems: PdfTextItem[];\n /** MediaBox [x0, y0, x1, y1] in pt. */\n view: number[];\n /** pdf.js OPS enum (injected — differs per build flavor, values stable). */\n ops: Record<string, number>;\n /** The page's /Rotate (degrees CLOCKWISE, a multiple of 90): viewers show\n * the page turned by it, so the import does too. */\n rotate?: number;\n /** Also take FILLED paths, as their outlines (a raster PDF reference's\n * snap geometry — frames and borders are often drawn as fills). */\n fills?: boolean;\n}\n\ntype DistributiveOmit<T, K extends PropertyKey> = T extends unknown\n ? Omit<T, K>\n : never;\n\n/** Object base fields left for the caller: layerId. */\nexport type PdfDto = DistributiveOmit<ModelObjectDto, \"layerId\">;\n\nexport const convertPdfPage = (input: PdfPageInput): PdfDto[] => {\n const { fnArray, argsArray, view, ops } = input;\n const strokeOps = new Set(\n [\n ops.stroke,\n ops.closeStroke,\n ops.fillStroke,\n ops.eoFillStroke,\n ops.closeFillStroke,\n ops.closeEOFillStroke,\n ].filter((v) => v !== undefined),\n );\n\n // Page space → mm with the page's /Rotate applied (clockwise, Y-up), so\n // the result sits upright in the positive quadrant as a viewer shows it.\n const w = (view[2] - view[0]) * PT2MM;\n const h = (view[3] - view[1]) * PT2MM;\n const turn = ((((input.rotate ?? 0) % 360) + 360) % 360) / 90;\n const fillOps = new Set(\n [ops.fill, ops.eoFill].filter((v) => v !== undefined),\n );\n const toMm = (p: Vec2): Vec2 => {\n const x = (p.x - view[0]) * PT2MM;\n const y = (p.y - view[1]) * PT2MM;\n return turn === 1\n ? { x: y, y: w - x }\n : turn === 2\n ? { x: w - x, y: h - y }\n : turn === 3\n ? { x: h - y, y: x }\n : { x, y };\n };\n const turnRad = (-turn * Math.PI) / 2;\n\n const dtos: PdfDto[] = [];\n const stack: Mat2x3[] = [];\n let ctm: Mat2x3 = matIdentity;\n let strokeColor: string | undefined;\n let lineWidth = 1;\n\n const emitSubpath = (points: Vec2[], closed: boolean): void => {\n if (points.length < 2) return;\n const scale = Math.hypot(ctm[0], ctm[1]) || 1;\n const widthMm = Math.max(lineWidth * scale * PT2MM, 0.05);\n const base = {\n color: strokeColor,\n lineWidth: Math.round(widthMm * 100) / 100,\n };\n if (points.length === 2 && !closed) {\n dtos.push({ type: \"line\", a: points[0], b: points[1], ...base });\n return;\n }\n dtos.push({\n type: \"polyline\",\n points: points.map((p) => ({ x: p.x, y: p.y, bulge: 0 })),\n closed,\n ...base,\n });\n };\n\n const flushPath = (data: number[]): void => {\n let current: Vec2 | null = null;\n let subpath: Vec2[] = [];\n let closed = false;\n const flush = () => {\n emitSubpath(subpath, closed);\n subpath = [];\n closed = false;\n };\n const push = (p: Vec2) => {\n current = p;\n subpath.push(toMm(matApply(ctm, p)));\n };\n const sample = (f: (t: number) => Vec2) => {\n for (let s = 1; s <= BEZIER_STEPS; s++) push(f(s / BEZIER_STEPS));\n };\n let i = 0;\n while (i < data.length) {\n switch (data[i]) {\n case 0: // moveTo\n if (subpath.length > 1) flush();\n else subpath = [];\n push({ x: data[i + 1], y: data[i + 2] });\n i += 3;\n break;\n case 1: // lineTo\n push({ x: data[i + 1], y: data[i + 2] });\n i += 3;\n break;\n case 2: {\n // cubic bezier\n const [p0, c1, c2, p1] = [\n current ?? { x: data[i + 1], y: data[i + 2] },\n { x: data[i + 1], y: data[i + 2] },\n { x: data[i + 3], y: data[i + 4] },\n { x: data[i + 5], y: data[i + 6] },\n ];\n sample((t) => {\n const u = 1 - t;\n return {\n x:\n u * u * u * p0.x +\n 3 * u * u * t * c1.x +\n 3 * u * t * t * c2.x +\n t * t * t * p1.x,\n y:\n u * u * u * p0.y +\n 3 * u * u * t * c1.y +\n 3 * u * t * t * c2.y +\n t * t * t * p1.y,\n };\n });\n i += 7;\n break;\n }\n case 3: {\n // quadratic bezier\n const p0 = current ?? { x: data[i + 1], y: data[i + 2] };\n const c = { x: data[i + 1], y: data[i + 2] };\n const p1 = { x: data[i + 3], y: data[i + 4] };\n sample((t) => {\n const u = 1 - t;\n return {\n x: u * u * p0.x + 2 * u * t * c.x + t * t * p1.x,\n y: u * u * p0.y + 2 * u * t * c.y + t * t * p1.y,\n };\n });\n i += 5;\n break;\n }\n case 4: // closePath\n closed = true;\n i += 1;\n break;\n default:\n // Unknown sub-op — bail on this path rather than misparse.\n return flush();\n }\n }\n flush();\n };\n\n for (let i = 0; i < fnArray.length; i++) {\n const fn = fnArray[i];\n const args = argsArray[i] as unknown[] | null;\n if (fn === ops.save) stack.push(ctm);\n else if (fn === ops.restore) ctm = stack.pop() ?? matIdentity;\n else if (fn === ops.transform && args)\n ctm = matMultiply(ctm, args as unknown as Mat2x3);\n else if (fn === ops.setStrokeRGBColor && args)\n strokeColor = importColor(String(args[0]));\n else if (fn === ops.setLineWidth && args) lineWidth = Number(args[0]);\n else if (fn === ops.constructPath && args) {\n const [paintOp, pathData] = args as [\n number,\n ArrayLike<number> | ArrayLike<number>[],\n ];\n // Lines-only import (fills, clips skipped) unless outlines are asked for.\n if (!strokeOps.has(paintOp) && !(input.fills && fillOps.has(paintOp)))\n continue;\n // Path data arrives as Float32Array chunks (or one flat run).\n const flat: number[] =\n typeof (pathData as ArrayLike<number>)[0] === \"number\"\n ? Array.from(pathData as ArrayLike<number>)\n : Array.from(pathData as ArrayLike<ArrayLike<number>>, (part) =>\n Array.from(part),\n ).flat();\n flushPath(flat);\n }\n }\n\n // Text runs: transform = [a, b, c, d, tx, ty] in page space (pt, y-up);\n // the y basis length is the effective font size, (tx, ty) the\n // baseline-left origin → left / bottom justified.\n for (const item of input.textItems) {\n if (!item.str.trim()) continue;\n const [a, b, c, d, tx, ty] = item.transform;\n const height = Math.hypot(c, d) * PT2MM;\n if (!(height > 0)) continue;\n dtos.push({\n type: \"text\",\n position: toMm({ x: tx, y: ty }),\n content: item.str,\n // The PDF glyph size is explicit — keep it as an override.\n styleOverride: { textHeight: Math.round(height * 1000) / 1000 },\n rotation: Math.atan2(b, a) + turnRad,\n // A PDF run starts at its baseline origin: text right of and above it.\n hAlign: \"left\",\n vAlign: \"bottom\",\n leaderLines: [],\n scale: 1,\n });\n }\n\n return dtos;\n};\n","// PDF → model objects. Stroked vector paths become lines/polylines and text\n// runs become text objects — PDFs don't preserve dimensions/leaders as\n// objects, so those arrive as exploded geometry. Multi-page files lay pages\n// out left-to-right.\n//\n// HEADLESS: imports pdf.js's `legacy` build (the main build needs the DOM),\n// which runs in Node with no worker configuration. A browser caller may pass\n// a bundled `workerSrc`. Pure conversion is delegated to convertPdfPage; this\n// module only drives pdf.js. The caller assigns a layer and applies the DTOs.\n\nimport { convertPdfPage, type PdfDto } from \"./convertPage\";\n\nconst PAGE_GAP_MM = 10;\n\n/** Shift a converted page right (multi-page files lay out left-to-right). */\nconst shiftX = (dto: PdfDto, dx: number): PdfDto => {\n switch (dto.type) {\n case \"line\":\n return {\n ...dto,\n a: { x: dto.a.x + dx, y: dto.a.y },\n b: { x: dto.b.x + dx, y: dto.b.y },\n };\n case \"polyline\":\n return {\n ...dto,\n points: dto.points.map((p) => ({ ...p, x: p.x + dx })),\n };\n case \"text\":\n return {\n ...dto,\n position: { x: dto.position.x + dx, y: dto.position.y },\n };\n default:\n return dto;\n }\n};\n\nexport interface PdfImportOptions {\n /**\n * pdf.js worker source. Node needs none (the legacy build runs on a fake\n * worker). In a browser, pass the bundled worker URL. Set only when given.\n */\n workerSrc?: string;\n /** Called before converting each page (1-based), e.g. for a progress UI. */\n onProgress?: (page: number, pageCount: number) => void | Promise<void>;\n /** Convert only this 1-based page, at the origin (a PDF reference). */\n page?: number;\n /** Filled paths too, as outlines (see PdfPageInput.fills). */\n fills?: boolean;\n}\n\nexport interface PdfImportResult {\n /** Converted objects as layer-less DTOs — the caller assigns a layer. */\n objects: PdfDto[];\n pageCount: number;\n}\n\n/**\n * Parse PDF bytes into model-object DTOs. Pure of any store/UI; throws if\n * pdf.js cannot parse the data. The editor/CLI wraps this with the layer\n * assignment, the undo transaction, and toasts.\n */\nexport const pdfToModel = async (\n data: ArrayBuffer | Uint8Array,\n opts: PdfImportOptions = {},\n): Promise<PdfImportResult> => {\n // Lazy: pdfjs is by far the heaviest dependency and only PDF *import*\n // needs it — loaded statically it would weigh on (or, where its native\n // pieces misbehave, take down) every consumer that never touches PDFs.\n const { getDocument, GlobalWorkerOptions, OPS } =\n await import(\"pdfjs-dist/legacy/build/pdf.mjs\");\n if (opts.workerSrc !== undefined)\n GlobalWorkerOptions.workerSrc = opts.workerSrc;\n\n const objects: PdfDto[] = [];\n const doc = await getDocument({ data }).promise;\n const pageCount = doc.numPages;\n let offsetX = 0;\n const pages =\n opts.page !== undefined\n ? [Math.min(Math.max(1, opts.page), pageCount)]\n : Array.from({ length: pageCount }, (_, i) => i + 1);\n for (const n of pages) {\n await opts.onProgress?.(n, pageCount);\n const page = await doc.getPage(n);\n const [list, text] = await Promise.all([\n page.getOperatorList(),\n page.getTextContent(),\n ]);\n const pageDtos = convertPdfPage({\n fnArray: list.fnArray,\n argsArray: list.argsArray,\n textItems: text.items.filter(\n (i): i is Extract<(typeof text.items)[number], { str: string }> =>\n \"str\" in i && \"transform\" in i,\n ),\n view: page.view,\n ops: OPS as unknown as Record<string, number>,\n rotate: page.rotate,\n fills: opts.fills,\n });\n for (const dto of pageDtos) objects.push(shiftX(dto, offsetX));\n // A quarter-turned page is as wide as its box is tall.\n const quarter = page.rotate % 180 !== 0;\n offsetX +=\n (quarter ? page.view[3] - page.view[1] : page.view[2] - page.view[0]) *\n (25.4 / 72) +\n PAGE_GAP_MM;\n }\n await doc.cleanup();\n return { objects, pageCount };\n};\n","// Semantic operation DTOs — the shared mutation contract for the SDK, CLI,\n// MCP tools, and cloud sync (see docs/kernel-op-layer.md). Every op is\n// self-contained, id-based, space-addressed, versioned, and invertible.\n\nimport { z } from \"zod\";\nimport { LayerSchema } from \"../model/document\";\nimport {\n DimStyleSchema,\n ModelObjectSchema,\n TextStyleSchema,\n} from \"../model/objects\";\nimport { LineTypeSchema } from \"../model/lineTypes\";\nimport { HatchPatternSchema } from \"../model/hatchPatterns\";\nimport { PaperLayoutSchema, PrintPaletteSchema } from \"../model/paperLayout\";\nimport { DocumentSettingsSchema } from \"../model/document\";\n\n// --- document field ops ----------------------------------------------------\n\n/** Replace the document-wide settings (the whole record; callers merge). */\nconst SetDocumentSettingsOpSchema = z.object({\n type: z.literal(\"set-document-settings\"),\n settings: DocumentSettingsSchema,\n});\n\n// --- layer ops -------------------------------------------------------------\n\nconst AddLayerOpSchema = z.object({\n type: z.literal(\"add-layer\"),\n layer: LayerSchema,\n /** Insertion index (defaults to append); carried so undo restores order. */\n index: z.number().int().nonnegative().optional(),\n});\n\nconst UpdateLayerOpSchema = z.object({\n type: z.literal(\"update-layer\"),\n layer: LayerSchema,\n});\n\nconst RemoveLayerOpSchema = z.object({\n type: z.literal(\"remove-layer\"),\n id: z.string(),\n});\n\n/** Explicit total order — every current layer id exactly once. Ids only, so\n * a concurrent property edit to a layer survives a reorder. */\nconst ReorderLayersOpSchema = z.object({\n type: z.literal(\"reorder-layers\"),\n ids: z.array(z.string()).min(1),\n});\n\nconst SetCurrentLayerOpSchema = z.object({\n type: z.literal(\"set-current-layer\"),\n id: z.string(),\n});\n\n/** LEGACY full layer-list replace — accepted for wire/history compat, no\n * longer emitted (diffLayerOps decomposes into the granular ops + reorder).\n * Validated like the granular ops: the current layer and every layer still\n * in use must survive. */\nconst SetLayersOpSchema = z.object({\n type: z.literal(\"set-layers\"),\n layers: z.array(LayerSchema).min(1),\n});\n\n// --- object ops (the funnel core) -----------------------------------------\n\n/** Target collection of an op: model space or a specific paper layout. */\nexport const OpSpaceSchema = z.union([\n z.literal(\"model\"),\n z.object({ layoutId: z.string() }),\n]);\nexport type OpSpace = z.infer<typeof OpSpaceSchema>;\n\nconst AddObjectsOpSchema = z.object({\n type: z.literal(\"add-objects\"),\n space: OpSpaceSchema,\n /** Ids are pre-assigned by the caller (never stamped here). */\n objects: z.array(ModelObjectSchema).min(1),\n /**\n * Optional insertion indices into the space's draw order, matched 1:1 to\n * `objects` and referring to positions in the FINAL array (ascending).\n * Omitted = append. Carried by remove-objects inverses so undoing a delete\n * restores exact draw order.\n */\n indices: z.array(z.number().int().nonnegative()).optional(),\n});\n\nconst UpdateObjectsOpSchema = z.object({\n type: z.literal(\"update-objects\"),\n space: OpSpaceSchema,\n /** Full replacement states, matched to existing objects by id. */\n objects: z.array(ModelObjectSchema).min(1),\n});\n\nconst RemoveObjectsOpSchema = z.object({\n type: z.literal(\"remove-objects\"),\n space: OpSpaceSchema,\n ids: z.array(z.string()).min(1),\n});\n\n/**\n * Where a reorder places the moved objects: the top/bottom of the space's\n * draw order, or immediately above/below a reference object (by id).\n */\nconst ReorderPlacementSchema = z.union([\n z.literal(\"front\"),\n z.literal(\"back\"),\n z.object({ above: z.string() }),\n z.object({ below: z.string() }),\n]);\nexport type ReorderPlacement = z.infer<typeof ReorderPlacementSchema>;\n\nconst ReorderObjectsOpSchema = z.object({\n type: z.literal(\"reorder-objects\"),\n space: OpSpaceSchema,\n /**\n * Moved as one contiguous run in the order GIVEN here (bottom → top).\n * Passing every id of the space with placement \"back\" therefore sets an\n * explicit total order — which is how inverses restore exactly.\n */\n ids: z.array(z.string()).min(1),\n placement: ReorderPlacementSchema,\n});\n\n// --- layout ops ------------------------------------------------------------\n\nconst AddLayoutOpSchema = z.object({\n type: z.literal(\"add-layout\"),\n layout: PaperLayoutSchema,\n index: z.number().int().nonnegative().optional(),\n});\n\n/** Sheet metadata only — layout CONTENT is edited via object ops on its space. */\nconst UpdateLayoutMetaOpSchema = z.object({\n type: z.literal(\"update-layout-meta\"),\n id: z.string(),\n name: z.string().optional(),\n sheet: z.object({ width: z.number(), height: z.number() }).optional(),\n printPalette: PrintPaletteSchema.optional(),\n});\n\nconst RemoveLayoutOpSchema = z.object({\n type: z.literal(\"remove-layout\"),\n id: z.string(),\n});\n\n/** Explicit total order — every current layout id exactly once. Layout\n * order is semantic: it is the sheet order of multi-page PDF export. */\nconst ReorderLayoutsOpSchema = z.object({\n type: z.literal(\"reorder-layouts\"),\n ids: z.array(z.string()).min(1),\n});\n\n/** Full layout replace by id (sheet AND content — page setup, bulk edits).\n * The granular path (update-layout-meta + object ops on the layout's space)\n * stays preferred; this mirrors the editor's coarse updateLayouts. */\nconst UpdateLayoutsOpSchema = z.object({\n type: z.literal(\"update-layouts\"),\n layouts: z.array(PaperLayoutSchema).min(1),\n});\n\n// --- text style ops ---------------------------------------------------------------\n\nconst AddTextStyleOpSchema = z.object({\n type: z.literal(\"add-text-style\"),\n style: TextStyleSchema,\n /** Insertion index (defaults to append); carried so undo restores order. */\n index: z.number().int().nonnegative().optional(),\n});\n\nconst UpdateTextStyleOpSchema = z.object({\n type: z.literal(\"update-text-style\"),\n /** Full replacement state, matched by id. */\n style: TextStyleSchema,\n});\n\nconst RemoveTextStyleOpSchema = z.object({\n type: z.literal(\"remove-text-style\"),\n id: z.string(),\n});\n\n/** Explicit total order of style ids (first style = the document default,\n * so order is semantic, not just display). */\nconst ReorderTextStylesOpSchema = z.object({\n type: z.literal(\"reorder-text-styles\"),\n ids: z.array(z.string()).min(1),\n});\n\n/** LEGACY full replace — accepted for wire/history compat, no longer\n * emitted; edits decompose into the granular trio + reorder. */\nconst SetTextStylesOpSchema = z.object({\n type: z.literal(\"set-text-styles\"),\n textStyles: z.array(TextStyleSchema),\n});\n\n// --- line type / hatch pattern definition ops -----------------------------------\n//\n// Named by `name` (objects reference them by name; there is no id). The\n// trio per resource; no reorder — order carries no meaning for these.\n\nconst AddLineTypeOpSchema = z.object({\n type: z.literal(\"add-line-type\"),\n lineType: LineTypeSchema,\n index: z.number().int().nonnegative().optional(),\n});\nconst UpdateLineTypeOpSchema = z.object({\n type: z.literal(\"update-line-type\"),\n /** Full replacement, matched by (case-insensitive) name. */\n lineType: LineTypeSchema,\n});\nconst RemoveLineTypeOpSchema = z.object({\n type: z.literal(\"remove-line-type\"),\n name: z.string(),\n});\n\nconst AddHatchPatternOpSchema = z.object({\n type: z.literal(\"add-hatch-pattern\"),\n hatchPattern: HatchPatternSchema,\n index: z.number().int().nonnegative().optional(),\n});\nconst UpdateHatchPatternOpSchema = z.object({\n type: z.literal(\"update-hatch-pattern\"),\n hatchPattern: HatchPatternSchema,\n});\nconst RemoveHatchPatternOpSchema = z.object({\n type: z.literal(\"remove-hatch-pattern\"),\n name: z.string(),\n});\n\n// --- dim style ops ---------------------------------------------------------------\n\nconst AddDimStyleOpSchema = z.object({\n type: z.literal(\"add-dim-style\"),\n style: DimStyleSchema,\n index: z.number().int().nonnegative().optional(),\n});\n\nconst UpdateDimStyleOpSchema = z.object({\n type: z.literal(\"update-dim-style\"),\n style: DimStyleSchema,\n});\n\nconst RemoveDimStyleOpSchema = z.object({\n type: z.literal(\"remove-dim-style\"),\n id: z.string(),\n});\n\nconst ReorderDimStylesOpSchema = z.object({\n type: z.literal(\"reorder-dim-styles\"),\n ids: z.array(z.string()).min(1),\n});\n\n/** LEGACY full replace — same role as set-text-styles. */\nconst SetDimStylesOpSchema = z.object({\n type: z.literal(\"set-dim-styles\"),\n dimStyles: z.array(DimStyleSchema),\n});\n\n// --- asset ops ---------------------------------------------------------------\n\nconst SetAssetOpSchema = z.object({\n type: z.literal(\"set-asset\"),\n /** Content key (hashAsset of the data URL, by convention). */\n id: z.string(),\n dataUrl: z.string(),\n});\n\nconst RemoveAssetOpSchema = z.object({\n type: z.literal(\"remove-asset\"),\n id: z.string(),\n});\n\n// --- block definition ops ---------------------------------------------------------------\n//\n// Module ops (blocks and document commands) are CONTENT-addressed: a module\n// is an opaque source string whose semantic id only exists after compiling,\n// which pure op validation cannot do — and identical strings are genuinely\n// indistinguishable, so exact-source addressing is precise. A stale\n// `prevSource`/`source` no longer in the document REJECTS (unknown-module)\n// instead of silently clobbering a concurrent edit. See docs/granular-ops.md.\n\nconst AddBlockDefinitionOpSchema = z.object({\n type: z.literal(\"add-block-definition\"),\n source: z.string(),\n /** Insertion index (defaults to append); carried so undo restores order. */\n index: z.number().int().nonnegative().optional(),\n});\n\nconst UpdateBlockDefinitionOpSchema = z.object({\n type: z.literal(\"update-block-definition\"),\n /** The exact current source this edit was computed against. */\n prevSource: z.string(),\n source: z.string(),\n});\n\nconst RemoveBlockDefinitionOpSchema = z.object({\n type: z.literal(\"remove-block-definition\"),\n source: z.string(),\n});\n\n/** Explicit total order of the current sources. Same payload size as the\n * set op, but SAME-SET validated: a stale reorder rejects instead of\n * deleting a module a peer added concurrently. */\nconst ReorderBlockDefinitionsOpSchema = z.object({\n type: z.literal(\"reorder-block-definitions\"),\n sources: z.array(z.string()).min(1),\n});\n\n/** LEGACY full replace — accepted for wire/history compat and as the only\n * op that can express duplicate sources; no longer emitted otherwise. */\nconst SetBlockDefinitionsOpSchema = z.object({\n type: z.literal(\"set-block-definitions\"),\n /** Raw block module sources (semantic validation happens at compile). */\n blockDefinitions: z.array(z.string()),\n});\n\n// --- document command ops ----------------------------------------------------\n\nconst AddDocumentCommandOpSchema = z.object({\n type: z.literal(\"add-document-command\"),\n source: z.string(),\n index: z.number().int().nonnegative().optional(),\n});\n\nconst UpdateDocumentCommandOpSchema = z.object({\n type: z.literal(\"update-document-command\"),\n prevSource: z.string(),\n source: z.string(),\n});\n\nconst RemoveDocumentCommandOpSchema = z.object({\n type: z.literal(\"remove-document-command\"),\n source: z.string(),\n});\n\nconst ReorderDocumentCommandsOpSchema = z.object({\n type: z.literal(\"reorder-document-commands\"),\n sources: z.array(z.string()).min(1),\n});\n\n/** LEGACY full replace — same role as set-block-definitions. */\nconst SetDocumentCommandsOpSchema = z.object({\n type: z.literal(\"set-document-commands\"),\n /** Raw user-command module sources (document scope). */\n commands: z.array(z.string()),\n});\n\nexport const OperationSchema = z.discriminatedUnion(\"type\", [\n // document\n // objects\n AddObjectsOpSchema,\n UpdateObjectsOpSchema,\n RemoveObjectsOpSchema,\n ReorderObjectsOpSchema,\n // layers\n AddLayerOpSchema,\n UpdateLayerOpSchema,\n RemoveLayerOpSchema,\n ReorderLayersOpSchema,\n SetLayersOpSchema,\n SetCurrentLayerOpSchema,\n SetDocumentSettingsOpSchema,\n // layouts\n AddLayoutOpSchema,\n UpdateLayoutMetaOpSchema,\n RemoveLayoutOpSchema,\n ReorderLayoutsOpSchema,\n UpdateLayoutsOpSchema,\n // text styles\n AddTextStyleOpSchema,\n UpdateTextStyleOpSchema,\n RemoveTextStyleOpSchema,\n ReorderTextStylesOpSchema,\n SetTextStylesOpSchema,\n // line types / hatch patterns\n AddLineTypeOpSchema,\n UpdateLineTypeOpSchema,\n RemoveLineTypeOpSchema,\n AddHatchPatternOpSchema,\n UpdateHatchPatternOpSchema,\n RemoveHatchPatternOpSchema,\n // dim styles\n AddDimStyleOpSchema,\n UpdateDimStyleOpSchema,\n RemoveDimStyleOpSchema,\n ReorderDimStylesOpSchema,\n SetDimStylesOpSchema,\n // assets\n SetAssetOpSchema,\n RemoveAssetOpSchema,\n // block definitions\n AddBlockDefinitionOpSchema,\n UpdateBlockDefinitionOpSchema,\n RemoveBlockDefinitionOpSchema,\n ReorderBlockDefinitionsOpSchema,\n SetBlockDefinitionsOpSchema,\n // commands\n AddDocumentCommandOpSchema,\n UpdateDocumentCommandOpSchema,\n RemoveDocumentCommandOpSchema,\n ReorderDocumentCommandsOpSchema,\n SetDocumentCommandsOpSchema,\n]);\n\nexport type Operation = z.infer<typeof OperationSchema>;\n\n/** An op batch from outside the kernel's own code (scripts, agents, the\n * SDK): schema-checked so a malformed op fails here with a readable message\n * instead of being saved and failing the document schema on reopen. */\nexport const parseOperations = (ops: readonly unknown[]): Operation[] => {\n const result = z.array(OperationSchema).safeParse(ops);\n if (!result.success)\n throw new Error(`applyOps(): invalid operation\n${z.prettifyError(result.error)}`);\n return result.data;\n};\n","// Pure operation applier + validator. `applyOperation(doc, op)` validates the\n// op against full document state (referential integrity), returns the next\n// document and the INVERSE op. No store, no indexes, no invalidation — the\n// cloud server runs this against authoritative state; DocumentKernel wraps it\n// with indexes + invalidation. See docs/kernel-op-layer.md.\n\nimport {\n blockDefinitionExists,\n blockScriptId,\n getBlockMetaResult,\n} from \"../extensions/evalBlock\";\nimport type { LineaDocument } from \"../model/document\";\nimport { dimStyleFor, textStyleFor, type ModelObject } from \"../model/objects\";\nimport type { PaperLayout } from \"../model/paperLayout\";\nimport type { OpSpace, Operation } from \"./types\";\nimport { lineTypeKey } from \"../model/lineTypes\";\nimport { hatchPatternKey } from \"../model/hatchPatterns\";\n\n/** Machine-readable validation/apply failure. */\nexport type OpErrorCode =\n | \"unknown-space\"\n | \"unknown-object\"\n | \"duplicate-id\"\n | \"missing-layer\"\n | \"missing-definition\"\n | \"viewport-in-model\"\n | \"invalid-reorder\"\n | \"unknown-layer\"\n | \"layer-in-use\"\n | \"last-layer\"\n | \"current-layer\"\n | \"unknown-layout\"\n | \"duplicate-layout\"\n | \"invalid-dimension\"\n | \"unknown-asset\"\n | \"asset-in-use\"\n | \"unknown-style\"\n | \"last-style\"\n | \"style-in-use\"\n | \"unknown-module\"\n | \"definition-in-use\"\n | \"duplicate-name\"\n | \"not-found\";\n\nexport class OpError extends Error {\n readonly code: OpErrorCode;\n constructor(code: OpErrorCode, message: string) {\n super(message);\n this.name = \"OpError\";\n this.code = code;\n }\n}\n\nexport interface ApplyResult {\n document: LineaDocument;\n /** The op that undoes this one exactly. */\n inverse: Operation;\n}\n\n// --- space helpers ---------------------------------------------------------\n\nconst spaceLabel = (s: OpSpace): string =>\n s === \"model\" ? \"model\" : `layout ${s.layoutId}`;\n\nconst getSpaceObjects = (doc: LineaDocument, space: OpSpace): ModelObject[] => {\n if (space === \"model\") return doc.objects;\n const layout = doc.layouts.find((l) => l.id === space.layoutId);\n if (!layout)\n throw new OpError(\"unknown-space\", `No layout ${space.layoutId}`);\n return layout.objects;\n};\n\nconst setSpaceObjects = (\n doc: LineaDocument,\n space: OpSpace,\n objects: ModelObject[],\n): LineaDocument =>\n space === \"model\"\n ? { ...doc, objects }\n : {\n ...doc,\n layouts: doc.layouts.map((l) =>\n l.id === space.layoutId ? { ...l, objects } : l,\n ),\n };\n\n// --- referential integrity -------------------------------------------------\n\nconst assertObjectRefs = (\n doc: LineaDocument,\n obj: ModelObject,\n space: OpSpace,\n): void => {\n if (!doc.layers.some((l) => l.id === obj.layerId))\n throw new OpError(\n \"missing-layer\",\n `Object ${obj.id} references unknown layer ${obj.layerId}`,\n );\n // Definition ids are module exports — the check compiles (cached) and is\n // PERMISSIVE while the lazy transpiler is still loading; evaluation reports\n // the definitive per-instance error either way.\n if (\n obj.type === \"block\" &&\n !blockDefinitionExists(doc.blockDefinitions, obj.definitionId)\n )\n throw new OpError(\n \"missing-definition\",\n `Block ${obj.id} references unknown definition ${obj.definitionId}`,\n );\n if (obj.type === \"viewport\" && space === \"model\")\n throw new OpError(\n \"viewport-in-model\",\n `Viewport ${obj.id} cannot live in model space`,\n );\n if (obj.type === \"dimension\") {\n // What each kind's geometry derivation actually needs (fewer points\n // renders as nothing, which hides authoring bugs).\n const min = { linear: 2, angular: 3, radial: 2, diameter: 2 }[obj.kind];\n if (obj.points.length < min)\n throw new OpError(\n \"invalid-dimension\",\n `Dimension ${obj.id}: a ${obj.kind} dimension needs at least ${min} points, got ${obj.points.length}`,\n );\n }\n};\n\n// --- object ops ------------------------------------------------------------\n\nconst applyAddObjects = (\n doc: LineaDocument,\n op: Extract<Operation, { type: \"add-objects\" }>,\n): ApplyResult => {\n const existing = getSpaceObjects(doc, op.space);\n const ids = new Set(existing.map((o) => o.id));\n for (const obj of op.objects) {\n if (ids.has(obj.id))\n throw new OpError(\n \"duplicate-id\",\n `Object ${obj.id} already exists in ${spaceLabel(op.space)}`,\n );\n assertObjectRefs(doc, obj, op.space);\n }\n let next: ModelObject[];\n if (op.indices && op.indices.length === op.objects.length) {\n // Positional insert: indices refer to the FINAL array, ascending —\n // exactly what a remove-objects inverse recorded. Out-of-range indices\n // clamp to append so a stale inverse still lands every object.\n next = [...existing];\n op.objects\n .map((obj, i) => ({ obj, at: op.indices![i] }))\n .sort((a, b) => a.at - b.at)\n .forEach(({ obj, at }) => next.splice(Math.min(at, next.length), 0, obj));\n } else {\n next = [...existing, ...op.objects];\n }\n return {\n document: setSpaceObjects(doc, op.space, next),\n inverse: {\n type: \"remove-objects\",\n space: op.space,\n ids: op.objects.map((o) => o.id),\n },\n };\n};\n\nconst applyUpdateObjects = (\n doc: LineaDocument,\n op: Extract<Operation, { type: \"update-objects\" }>,\n): ApplyResult => {\n const existing = getSpaceObjects(doc, op.space);\n const byId = new Map(existing.map((o) => [o.id, o]));\n const previous: ModelObject[] = [];\n for (const obj of op.objects) {\n const prev = byId.get(obj.id);\n if (!prev)\n throw new OpError(\n \"unknown-object\",\n `Object ${obj.id} not found in ${spaceLabel(op.space)}`,\n );\n previous.push(prev);\n assertObjectRefs(doc, obj, op.space);\n }\n const patch = new Map(op.objects.map((o) => [o.id, o]));\n return {\n document: setSpaceObjects(\n doc,\n op.space,\n existing.map((o) => patch.get(o.id) ?? o),\n ),\n inverse: { type: \"update-objects\", space: op.space, objects: previous },\n };\n};\n\nconst applyRemoveObjects = (\n doc: LineaDocument,\n op: Extract<Operation, { type: \"remove-objects\" }>,\n): ApplyResult => {\n const existing = getSpaceObjects(doc, op.space);\n const byId = new Map(existing.map((o) => [o.id, o]));\n for (const id of op.ids) {\n if (!byId.has(id))\n throw new OpError(\n \"unknown-object\",\n `Object ${id} not found in ${spaceLabel(op.space)}`,\n );\n }\n const drop = new Set(op.ids);\n // Record removed objects with their ORIGINAL indices so the inverse\n // restores exact draw order (positional insert into the final array).\n const removed: ModelObject[] = [];\n const indices: number[] = [];\n existing.forEach((o, i) => {\n if (drop.has(o.id)) {\n removed.push(o);\n indices.push(i);\n }\n });\n return {\n document: setSpaceObjects(\n doc,\n op.space,\n existing.filter((o) => !drop.has(o.id)),\n ),\n inverse: {\n type: \"add-objects\",\n space: op.space,\n objects: removed,\n indices,\n },\n };\n};\n\nconst applyReorderObjects = (\n doc: LineaDocument,\n op: Extract<Operation, { type: \"reorder-objects\" }>,\n): ApplyResult => {\n const existing = getSpaceObjects(doc, op.space);\n const byId = new Map(existing.map((o) => [o.id, o]));\n const moving = new Set(op.ids);\n if (moving.size !== op.ids.length)\n throw new OpError(\"invalid-reorder\", `Duplicate ids in reorder`);\n const moved: ModelObject[] = op.ids.map((id) => {\n const obj = byId.get(id);\n if (!obj)\n throw new OpError(\n \"unknown-object\",\n `Object ${id} not found in ${spaceLabel(op.space)}`,\n );\n return obj;\n });\n const rest = existing.filter((o) => !moving.has(o.id));\n let at: number;\n const p = op.placement;\n if (p === \"back\") at = 0;\n else if (p === \"front\") at = rest.length;\n else {\n const refId = \"above\" in p ? p.above : p.below;\n if (moving.has(refId))\n throw new OpError(\n \"invalid-reorder\",\n `Reference object ${refId} is part of the moved set`,\n );\n const refIndex = rest.findIndex((o) => o.id === refId);\n if (refIndex === -1)\n throw new OpError(\n \"unknown-object\",\n `Reference object ${refId} not found in ${spaceLabel(op.space)}`,\n );\n at = \"above\" in p ? refIndex + 1 : refIndex;\n }\n return {\n document: setSpaceObjects(doc, op.space, [\n ...rest.slice(0, at),\n ...moved,\n ...rest.slice(at),\n ]),\n // Full previous order + \"back\" = explicit total order — exact restore.\n inverse: {\n type: \"reorder-objects\",\n space: op.space,\n ids: existing.map((o) => o.id),\n placement: \"back\",\n },\n };\n};\n\n// --- layer ops -------------------------------------------------------------\n\n/** Layer names are addressed by name (scripts, DXF) and DXF treats them\n * case-insensitively — no two layers may share one. Only new names are\n * checked: documents that already hold duplicates still load and edit. */\nconst assertLayerNameFree = (\n doc: LineaDocument,\n name: string,\n exceptId: string,\n): void => {\n const clash = doc.layers.find(\n (l) => l.id !== exceptId && l.name.toLowerCase() === name.toLowerCase(),\n );\n if (clash)\n throw new OpError(\n \"duplicate-name\",\n `A layer named \"${clash.name}\" already exists`,\n );\n};\n\nconst applyAddLayer = (\n doc: LineaDocument,\n op: Extract<Operation, { type: \"add-layer\" }>,\n): ApplyResult => {\n if (doc.layers.some((l) => l.id === op.layer.id))\n throw new OpError(\"duplicate-id\", `Layer ${op.layer.id} already exists`);\n assertLayerNameFree(doc, op.layer.name, op.layer.id);\n const layers = [...doc.layers];\n layers.splice(op.index ?? layers.length, 0, op.layer);\n return {\n document: { ...doc, layers },\n inverse: { type: \"remove-layer\", id: op.layer.id },\n };\n};\n\nconst applyUpdateLayer = (\n doc: LineaDocument,\n op: Extract<Operation, { type: \"update-layer\" }>,\n): ApplyResult => {\n const prev = doc.layers.find((l) => l.id === op.layer.id);\n if (!prev)\n throw new OpError(\"unknown-layer\", `Layer ${op.layer.id} not found`);\n if (op.layer.name !== prev.name)\n assertLayerNameFree(doc, op.layer.name, op.layer.id);\n return {\n document: {\n ...doc,\n layers: doc.layers.map((l) => (l.id === op.layer.id ? op.layer : l)),\n },\n inverse: { type: \"update-layer\", layer: prev },\n };\n};\n\n/** How many objects, in every space, `match` accepts. */\nconst countObjects = (\n doc: LineaDocument,\n match: (o: ModelObject) => boolean,\n): number =>\n [doc.objects, ...doc.layouts.map((l) => l.objects)].reduce(\n (n, objs) => n + objs.filter(match).length,\n 0,\n );\n\nconst plural = (n: number, word: string) => `${n} ${word}${n === 1 ? \"\" : \"s\"}`;\n\nconst applyRemoveLayer = (\n doc: LineaDocument,\n op: Extract<Operation, { type: \"remove-layer\" }>,\n): ApplyResult => {\n const index = doc.layers.findIndex((l) => l.id === op.id);\n if (index === -1)\n throw new OpError(\"unknown-layer\", `Layer ${op.id} not found`);\n const prev = doc.layers[index];\n if (doc.layers.length === 1)\n throw new OpError(\"last-layer\", `Cannot remove the last layer`);\n if (doc.currentLayerId === op.id)\n throw new OpError(\n \"current-layer\",\n `Layer \"${prev.name}\" is the current layer — switch to another first`,\n );\n const users = countObjects(doc, (o) => o.layerId === op.id);\n if (users > 0)\n throw new OpError(\n \"layer-in-use\",\n `Layer \"${prev.name}\" still has ${plural(users, \"object\")} on it`,\n );\n return {\n document: { ...doc, layers: doc.layers.filter((l) => l.id !== op.id) },\n inverse: { type: \"add-layer\", layer: prev, index },\n };\n};\n\nconst applySetLayers = (\n doc: LineaDocument,\n op: Extract<Operation, { type: \"set-layers\" }>,\n): ApplyResult => {\n const ids = new Set(op.layers.map((l) => l.id));\n if (ids.size !== op.layers.length)\n throw new OpError(\"duplicate-id\", `Duplicate layer ids in set-layers`);\n if (!ids.has(doc.currentLayerId))\n throw new OpError(\n \"current-layer\",\n `set-layers would drop the current layer ${doc.currentLayerId}`,\n );\n const used = (objs: ModelObject[]) => objs.find((o) => !ids.has(o.layerId));\n const orphan =\n used(doc.objects) ?? doc.layouts.map((l) => used(l.objects)).find(Boolean);\n if (orphan)\n throw new OpError(\n \"layer-in-use\",\n `set-layers would orphan object ${orphan.id} (layer ${orphan.layerId})`,\n );\n return {\n document: { ...doc, layers: op.layers },\n inverse: { type: \"set-layers\", layers: doc.layers },\n };\n};\n\n/** Reorder an id-keyed collection to an explicit total order (same-set\n * validated: every current id exactly once, nothing added or dropped). */\nconst reorderById = <T extends { id: string }>(\n arr: T[],\n ids: string[],\n what: string,\n): T[] => {\n const byId = new Map(arr.map((x) => [x.id, x]));\n if (ids.length !== arr.length || new Set(ids).size !== ids.length)\n throw new OpError(\n \"invalid-reorder\",\n `Reorder must list every current ${what} id exactly once`,\n );\n return ids.map((id) => {\n const item = byId.get(id);\n if (!item) throw new OpError(\"invalid-reorder\", `Unknown ${what} id ${id}`);\n return item;\n });\n};\n\nconst applyReorderLayers = (\n doc: LineaDocument,\n op: Extract<Operation, { type: \"reorder-layers\" }>,\n): ApplyResult => ({\n document: { ...doc, layers: reorderById(doc.layers, op.ids, \"layer\") },\n inverse: { type: \"reorder-layers\", ids: doc.layers.map((l) => l.id) },\n});\n\nconst applySetCurrentLayer = (\n doc: LineaDocument,\n op: Extract<Operation, { type: \"set-current-layer\" }>,\n): ApplyResult => {\n if (!doc.layers.some((l) => l.id === op.id))\n throw new OpError(\"unknown-layer\", `Layer ${op.id} not found`);\n return {\n document: { ...doc, currentLayerId: op.id },\n inverse: { type: \"set-current-layer\", id: doc.currentLayerId },\n };\n};\n\n// --- document field ops ----------------------------------------------------\n\nconst applySetDocumentSettings = (\n doc: LineaDocument,\n op: Extract<Operation, { type: \"set-document-settings\" }>,\n): ApplyResult => ({\n document: { ...doc, settings: op.settings },\n inverse: { type: \"set-document-settings\", settings: doc.settings },\n});\n\nconst applySetDimStyles = (\n doc: LineaDocument,\n op: Extract<Operation, { type: \"set-dim-styles\" }>,\n): ApplyResult => ({\n document: { ...doc, dimStyles: op.dimStyles },\n inverse: { type: \"set-dim-styles\", dimStyles: doc.dimStyles },\n});\n\nconst applySetTextStyles = (\n doc: LineaDocument,\n op: Extract<Operation, { type: \"set-text-styles\" }>,\n): ApplyResult => ({\n document: { ...doc, textStyles: op.textStyles },\n inverse: { type: \"set-text-styles\", textStyles: doc.textStyles },\n});\n\n// Shared array plumbing for the granular text/dim style trios. Dangling\n// styleId references are LEGAL by design (they resolve to the first style),\n// so remove needs no in-use check — only the schema's min-1 invariant.\n\nconst addStyleIn = <T extends { id: string }>(\n arr: T[],\n style: T,\n index: number | undefined,\n): T[] => {\n if (arr.some((s) => s.id === style.id))\n throw new OpError(\"duplicate-id\", `Style ${style.id} already exists`);\n const next = [...arr];\n // Out-of-range indices clamp to append so a stale inverse still lands.\n next.splice(Math.min(index ?? next.length, next.length), 0, style);\n return next;\n};\n\nconst updateStyleIn = <T extends { id: string }>(\n arr: T[],\n style: T,\n): { next: T[]; prev: T } => {\n const prev = arr.find((s) => s.id === style.id);\n if (!prev) throw new OpError(\"unknown-style\", `Style ${style.id} not found`);\n return { next: arr.map((s) => (s.id === style.id ? style : s)), prev };\n};\n\nconst removeStyleIn = <T extends { id: string }>(\n arr: T[],\n id: string,\n): { next: T[]; prev: T; index: number } => {\n const index = arr.findIndex((s) => s.id === id);\n if (index === -1) throw new OpError(\"unknown-style\", `Style ${id} not found`);\n if (arr.length === 1)\n throw new OpError(\"last-style\", `Cannot remove the last style`);\n return { next: arr.filter((s) => s.id !== id), prev: arr[index], index };\n};\n\nconst applyAddTextStyle = (\n doc: LineaDocument,\n op: Extract<Operation, { type: \"add-text-style\" }>,\n): ApplyResult => ({\n document: {\n ...doc,\n textStyles: addStyleIn(doc.textStyles, op.style, op.index),\n },\n inverse: { type: \"remove-text-style\", id: op.style.id },\n});\n\nconst applyUpdateTextStyle = (\n doc: LineaDocument,\n op: Extract<Operation, { type: \"update-text-style\" }>,\n): ApplyResult => {\n const { next, prev } = updateStyleIn(doc.textStyles, op.style);\n return {\n document: { ...doc, textStyles: next },\n inverse: { type: \"update-text-style\", style: prev },\n };\n};\n\n/** Refuse removing a style objects resolve to — by `styleId`, or as the\n * first style that unstyled (and dangling) references fall back to. */\nconst assertStyleUnused = (users: number, name: string): void => {\n if (users > 0)\n throw new OpError(\n \"style-in-use\",\n `Style \"${name}\" is used by ${plural(users, \"object\")} — restyle them first`,\n );\n};\n\n/** Objects (every space) whose text style resolves to `id`. */\nexport const textStyleUsers = (doc: LineaDocument, id: string): number =>\n countObjects(doc, (o) => {\n if (o.type === \"text\") return textStyleFor(o, doc.textStyles).id === id;\n if (o.type !== \"table\") return false;\n return (\n textStyleFor(o, doc.textStyles).id === id ||\n o.cells.some((row) => row.some((c) => c.styleId === id))\n );\n });\n\nconst applyRemoveTextStyle = (\n doc: LineaDocument,\n op: Extract<Operation, { type: \"remove-text-style\" }>,\n): ApplyResult => {\n const { next, prev, index } = removeStyleIn(doc.textStyles, op.id);\n assertStyleUnused(textStyleUsers(doc, op.id), prev.name);\n return {\n document: { ...doc, textStyles: next },\n inverse: { type: \"add-text-style\", style: prev, index },\n };\n};\n\nconst applyReorderTextStyles = (\n doc: LineaDocument,\n op: Extract<Operation, { type: \"reorder-text-styles\" }>,\n): ApplyResult => ({\n document: {\n ...doc,\n textStyles: reorderById(doc.textStyles, op.ids, \"text style\"),\n },\n inverse: {\n type: \"reorder-text-styles\",\n ids: doc.textStyles.map((s) => s.id),\n },\n});\n\n// Name-keyed resource trios (line types, hatch patterns): names compare\n// case-insensitively like DXF table names. Dangling names are legal (they\n// fall back to the catalogue or continuous), so remove needs no in-use check.\nconst namedIndex = <T extends { name: string }>(\n arr: readonly T[],\n name: string,\n key: (n: string) => string,\n): number => {\n const k = key(name);\n return arr.findIndex((t) => key(t.name) === k);\n};\nconst addNamedIn = <T extends { name: string }>(\n arr: readonly T[],\n item: T,\n index: number | undefined,\n key: (n: string) => string,\n what: string,\n): T[] => {\n if (namedIndex(arr, item.name, key) !== -1)\n throw new OpError(\n \"duplicate-name\",\n `A ${what} named \"${item.name}\" already exists`,\n );\n const at = index === undefined ? arr.length : Math.min(index, arr.length);\n return [...arr.slice(0, at), item, ...arr.slice(at)];\n};\nconst updateNamedIn = <T extends { name: string }>(\n arr: readonly T[],\n item: T,\n key: (n: string) => string,\n what: string,\n): { next: T[]; prev: T } => {\n const i = namedIndex(arr, item.name, key);\n if (i === -1)\n throw new OpError(\"not-found\", `No ${what} named \"${item.name}\"`);\n const next = [...arr];\n next[i] = item;\n return { next, prev: arr[i] };\n};\nconst removeNamedIn = <T extends { name: string }>(\n arr: readonly T[],\n name: string,\n key: (n: string) => string,\n what: string,\n): { next: T[]; prev: T; index: number } => {\n const i = namedIndex(arr, name, key);\n if (i === -1) throw new OpError(\"not-found\", `No ${what} named \"${name}\"`);\n return { next: arr.filter((_, j) => j !== i), prev: arr[i], index: i };\n};\n\nconst applyAddLineType = (\n doc: LineaDocument,\n op: Extract<Operation, { type: \"add-line-type\" }>,\n): ApplyResult => ({\n document: {\n ...doc,\n lineTypes: addNamedIn(\n doc.lineTypes,\n op.lineType,\n op.index,\n lineTypeKey,\n \"line type\",\n ),\n },\n inverse: { type: \"remove-line-type\", name: op.lineType.name },\n});\nconst applyUpdateLineType = (\n doc: LineaDocument,\n op: Extract<Operation, { type: \"update-line-type\" }>,\n): ApplyResult => {\n const { next, prev } = updateNamedIn(\n doc.lineTypes,\n op.lineType,\n lineTypeKey,\n \"line type\",\n );\n return {\n document: { ...doc, lineTypes: next },\n inverse: { type: \"update-line-type\", lineType: prev },\n };\n};\nconst applyRemoveLineType = (\n doc: LineaDocument,\n op: Extract<Operation, { type: \"remove-line-type\" }>,\n): ApplyResult => {\n const { next, prev, index } = removeNamedIn(\n doc.lineTypes,\n op.name,\n lineTypeKey,\n \"line type\",\n );\n return {\n document: { ...doc, lineTypes: next },\n inverse: { type: \"add-line-type\", lineType: prev, index },\n };\n};\n\nconst applyAddHatchPattern = (\n doc: LineaDocument,\n op: Extract<Operation, { type: \"add-hatch-pattern\" }>,\n): ApplyResult => ({\n document: {\n ...doc,\n hatchPatterns: addNamedIn(\n doc.hatchPatterns,\n op.hatchPattern,\n op.index,\n hatchPatternKey,\n \"hatch pattern\",\n ),\n },\n inverse: { type: \"remove-hatch-pattern\", name: op.hatchPattern.name },\n});\nconst applyUpdateHatchPattern = (\n doc: LineaDocument,\n op: Extract<Operation, { type: \"update-hatch-pattern\" }>,\n): ApplyResult => {\n const { next, prev } = updateNamedIn(\n doc.hatchPatterns,\n op.hatchPattern,\n hatchPatternKey,\n \"hatch pattern\",\n );\n return {\n document: { ...doc, hatchPatterns: next },\n inverse: { type: \"update-hatch-pattern\", hatchPattern: prev },\n };\n};\nconst applyRemoveHatchPattern = (\n doc: LineaDocument,\n op: Extract<Operation, { type: \"remove-hatch-pattern\" }>,\n): ApplyResult => {\n const { next, prev, index } = removeNamedIn(\n doc.hatchPatterns,\n op.name,\n hatchPatternKey,\n \"hatch pattern\",\n );\n return {\n document: { ...doc, hatchPatterns: next },\n inverse: { type: \"add-hatch-pattern\", hatchPattern: prev, index },\n };\n};\n\nconst applyReorderDimStyles = (\n doc: LineaDocument,\n op: Extract<Operation, { type: \"reorder-dim-styles\" }>,\n): ApplyResult => ({\n document: {\n ...doc,\n dimStyles: reorderById(doc.dimStyles, op.ids, \"dim style\"),\n },\n inverse: { type: \"reorder-dim-styles\", ids: doc.dimStyles.map((s) => s.id) },\n});\n\nconst applyAddDimStyle = (\n doc: LineaDocument,\n op: Extract<Operation, { type: \"add-dim-style\" }>,\n): ApplyResult => ({\n document: {\n ...doc,\n dimStyles: addStyleIn(doc.dimStyles, op.style, op.index),\n },\n inverse: { type: \"remove-dim-style\", id: op.style.id },\n});\n\nconst applyUpdateDimStyle = (\n doc: LineaDocument,\n op: Extract<Operation, { type: \"update-dim-style\" }>,\n): ApplyResult => {\n const { next, prev } = updateStyleIn(doc.dimStyles, op.style);\n return {\n document: { ...doc, dimStyles: next },\n inverse: { type: \"update-dim-style\", style: prev },\n };\n};\n\n/** Dimensions (every space) whose dim style resolves to `id`. */\nexport const dimStyleUsers = (doc: LineaDocument, id: string): number =>\n countObjects(\n doc,\n (o) => o.type === \"dimension\" && dimStyleFor(o, doc.dimStyles).id === id,\n );\n\nconst applyRemoveDimStyle = (\n doc: LineaDocument,\n op: Extract<Operation, { type: \"remove-dim-style\" }>,\n): ApplyResult => {\n const { next, prev, index } = removeStyleIn(doc.dimStyles, op.id);\n assertStyleUnused(dimStyleUsers(doc, op.id), prev.name);\n return {\n document: { ...doc, dimStyles: next },\n inverse: { type: \"add-dim-style\", style: prev, index },\n };\n};\n\nconst applySetDocumentCommands = (\n doc: LineaDocument,\n op: Extract<Operation, { type: \"set-document-commands\" }>,\n): ApplyResult => ({\n document: { ...doc, commands: op.commands },\n inverse: { type: \"set-document-commands\", commands: doc.commands },\n});\n\nconst applySetBlockDefinitions = (\n doc: LineaDocument,\n op: Extract<Operation, { type: \"set-block-definitions\" }>,\n): ApplyResult => ({\n document: { ...doc, blockDefinitions: op.blockDefinitions },\n inverse: {\n type: \"set-block-definitions\",\n blockDefinitions: doc.blockDefinitions,\n },\n});\n\n// Shared array plumbing for the content-addressed module trios (block\n// definitions and document commands — both opaque source-string arrays; see\n// the addressing rationale in types.ts).\n\nconst addModuleIn = (\n arr: string[],\n source: string,\n index: number | undefined,\n what: string,\n): string[] => {\n if (arr.includes(source))\n throw new OpError(\n \"duplicate-id\",\n `This exact ${what} module is already in the document`,\n );\n const next = [...arr];\n next.splice(Math.min(index ?? next.length, next.length), 0, source);\n return next;\n};\n\nconst updateModuleIn = (\n arr: string[],\n prevSource: string,\n source: string,\n what: string,\n): string[] => {\n const at = arr.indexOf(prevSource);\n if (at === -1)\n throw new OpError(\n \"unknown-module\",\n `The ${what} module targeted by this update is not in the document (stale source)`,\n );\n if (source !== prevSource && arr.includes(source))\n throw new OpError(\n \"duplicate-id\",\n `This exact ${what} module is already in the document`,\n );\n return arr.map((s, i) => (i === at ? source : s));\n};\n\nconst removeModuleIn = (\n arr: string[],\n source: string,\n what: string,\n): { next: string[]; index: number } => {\n const index = arr.indexOf(source);\n if (index === -1)\n throw new OpError(\n \"unknown-module\",\n `The ${what} module to remove is not in the document (stale source)`,\n );\n return { next: arr.filter((_, i) => i !== index), index };\n};\n\n/** Same-multiset reorder for module sources: identical strings are\n * interchangeable, so sorted-equality is an exact check. */\nconst reorderModulesIn = (\n arr: string[],\n sources: string[],\n what: string,\n): string[] => {\n if (\n sources.length !== arr.length ||\n [...sources].sort().join(\"\") !== [...arr].sort().join(\"\")\n )\n throw new OpError(\n \"invalid-reorder\",\n `Reorder must list every current ${what} module source exactly once (stale set)`,\n );\n return sources;\n};\n\nconst applyReorderBlockDefinitions = (\n doc: LineaDocument,\n op: Extract<Operation, { type: \"reorder-block-definitions\" }>,\n): ApplyResult => ({\n document: {\n ...doc,\n blockDefinitions: reorderModulesIn(\n doc.blockDefinitions,\n op.sources,\n \"block\",\n ),\n },\n inverse: {\n type: \"reorder-block-definitions\",\n sources: doc.blockDefinitions,\n },\n});\n\nconst applyReorderDocumentCommands = (\n doc: LineaDocument,\n op: Extract<Operation, { type: \"reorder-document-commands\" }>,\n): ApplyResult => ({\n document: {\n ...doc,\n commands: reorderModulesIn(doc.commands, op.sources, \"command\"),\n },\n inverse: { type: \"reorder-document-commands\", sources: doc.commands },\n});\n\nconst applyAddBlockDefinition = (\n doc: LineaDocument,\n op: Extract<Operation, { type: \"add-block-definition\" }>,\n): ApplyResult => ({\n document: {\n ...doc,\n blockDefinitions: addModuleIn(\n doc.blockDefinitions,\n op.source,\n op.index,\n \"block\",\n ),\n },\n inverse: { type: \"remove-block-definition\", source: op.source },\n});\n\nconst applyUpdateBlockDefinition = (\n doc: LineaDocument,\n op: Extract<Operation, { type: \"update-block-definition\" }>,\n): ApplyResult => ({\n document: {\n ...doc,\n blockDefinitions: updateModuleIn(\n doc.blockDefinitions,\n op.prevSource,\n op.source,\n \"block\",\n ),\n },\n inverse: {\n type: \"update-block-definition\",\n prevSource: op.source,\n source: op.prevSource,\n },\n});\n\n/** Why a block module can't go: placed instances (model or any layout) or\n * another module declaring it as a dependency — the Library's rule, here so\n * scripts, agents and the SDK can't orphan instances either. A module whose\n * id another module in the document still defines is free to go. */\nconst assertBlockRemovable = (doc: LineaDocument, source: string): void => {\n const id = blockScriptId(source);\n if (id === undefined) return;\n const others = doc.blockDefinitions.filter((s) => s !== source);\n if (others.some((s) => blockScriptId(s) === id)) return;\n const placed = countObjects(\n doc,\n (o) => o.type === \"block\" && o.definitionId === id,\n );\n if (placed > 0)\n throw new OpError(\n \"definition-in-use\",\n `Block \"${id}\" still has ${plural(placed, \"placed instance\")} — explode or delete them first`,\n );\n for (const s of others) {\n const m = getBlockMetaResult(s);\n if (m.ok && (m.meta.dependencies ?? []).includes(id))\n throw new OpError(\n \"definition-in-use\",\n `Block \"${id}\" is required by block \"${m.meta.id}\" (its dependencies)`,\n );\n }\n};\n\nconst applyRemoveBlockDefinition = (\n doc: LineaDocument,\n op: Extract<Operation, { type: \"remove-block-definition\" }>,\n): ApplyResult => {\n assertBlockRemovable(doc, op.source);\n const { next, index } = removeModuleIn(\n doc.blockDefinitions,\n op.source,\n \"block\",\n );\n return {\n document: { ...doc, blockDefinitions: next },\n inverse: { type: \"add-block-definition\", source: op.source, index },\n };\n};\n\nconst applyAddDocumentCommand = (\n doc: LineaDocument,\n op: Extract<Operation, { type: \"add-document-command\" }>,\n): ApplyResult => ({\n document: {\n ...doc,\n commands: addModuleIn(doc.commands, op.source, op.index, \"command\"),\n },\n inverse: { type: \"remove-document-command\", source: op.source },\n});\n\nconst applyUpdateDocumentCommand = (\n doc: LineaDocument,\n op: Extract<Operation, { type: \"update-document-command\" }>,\n): ApplyResult => ({\n document: {\n ...doc,\n commands: updateModuleIn(doc.commands, op.prevSource, op.source, \"command\"),\n },\n inverse: {\n type: \"update-document-command\",\n prevSource: op.source,\n source: op.prevSource,\n },\n});\n\nconst applyRemoveDocumentCommand = (\n doc: LineaDocument,\n op: Extract<Operation, { type: \"remove-document-command\" }>,\n): ApplyResult => {\n const { next, index } = removeModuleIn(doc.commands, op.source, \"command\");\n return {\n document: { ...doc, commands: next },\n inverse: { type: \"add-document-command\", source: op.source, index },\n };\n};\n\n// --- asset ops ---------------------------------------------------------------\n\nconst applySetAsset = (\n doc: LineaDocument,\n op: Extract<Operation, { type: \"set-asset\" }>,\n): ApplyResult => {\n const prev = doc.assets[op.id];\n return {\n document: { ...doc, assets: { ...doc.assets, [op.id]: op.dataUrl } },\n inverse:\n prev !== undefined\n ? { type: \"set-asset\", id: op.id, dataUrl: prev }\n : { type: \"remove-asset\", id: op.id },\n };\n};\n\nconst assetInUse = (doc: LineaDocument, id: string): boolean => {\n const used = (objs: ModelObject[]) =>\n objs.some((o) => o.type === \"image\" && o.assetId === id);\n return used(doc.objects) || doc.layouts.some((l) => used(l.objects));\n};\n\nconst applyRemoveAsset = (\n doc: LineaDocument,\n op: Extract<Operation, { type: \"remove-asset\" }>,\n): ApplyResult => {\n const prev = doc.assets[op.id];\n if (prev === undefined)\n throw new OpError(\"unknown-asset\", `Asset ${op.id} not found`);\n if (assetInUse(doc, op.id))\n throw new OpError(\n \"asset-in-use\",\n `Asset ${op.id} is still referenced by an image object`,\n );\n const assets = { ...doc.assets };\n delete assets[op.id];\n return {\n document: { ...doc, assets },\n inverse: { type: \"set-asset\", id: op.id, dataUrl: prev },\n };\n};\n\n// --- layout ops ------------------------------------------------------------\n\nconst applyAddLayout = (\n doc: LineaDocument,\n op: Extract<Operation, { type: \"add-layout\" }>,\n): ApplyResult => {\n if (doc.layouts.some((l) => l.id === op.layout.id))\n throw new OpError(\"duplicate-layout\", `Layout ${op.layout.id} exists`);\n const layouts = [...doc.layouts];\n layouts.splice(op.index ?? layouts.length, 0, op.layout);\n return {\n document: { ...doc, layouts },\n inverse: { type: \"remove-layout\", id: op.layout.id },\n };\n};\n\nconst applyRemoveLayout = (\n doc: LineaDocument,\n op: Extract<Operation, { type: \"remove-layout\" }>,\n): ApplyResult => {\n const index = doc.layouts.findIndex((l) => l.id === op.id);\n if (index === -1)\n throw new OpError(\"unknown-layout\", `Layout ${op.id} not found`);\n const prev = doc.layouts[index];\n return {\n document: { ...doc, layouts: doc.layouts.filter((l) => l.id !== op.id) },\n inverse: { type: \"add-layout\", layout: prev, index },\n };\n};\n\nconst applyReorderLayouts = (\n doc: LineaDocument,\n op: Extract<Operation, { type: \"reorder-layouts\" }>,\n): ApplyResult => ({\n document: { ...doc, layouts: reorderById(doc.layouts, op.ids, \"layout\") },\n inverse: { type: \"reorder-layouts\", ids: doc.layouts.map((l) => l.id) },\n});\n\nconst applyUpdateLayoutMeta = (\n doc: LineaDocument,\n op: Extract<Operation, { type: \"update-layout-meta\" }>,\n): ApplyResult => {\n const prev = doc.layouts.find((l) => l.id === op.id);\n if (!prev) throw new OpError(\"unknown-layout\", `Layout ${op.id} not found`);\n const next: PaperLayout = {\n ...prev,\n ...(op.name !== undefined ? { name: op.name } : {}),\n ...(op.sheet !== undefined ? { sheet: op.sheet } : {}),\n ...(op.printPalette !== undefined ? { printPalette: op.printPalette } : {}),\n };\n return {\n document: {\n ...doc,\n layouts: doc.layouts.map((l) => (l.id === op.id ? next : l)),\n },\n inverse: {\n type: \"update-layout-meta\",\n id: op.id,\n name: prev.name,\n sheet: prev.sheet,\n printPalette: prev.printPalette,\n },\n };\n};\n\nconst applyUpdateLayouts = (\n doc: LineaDocument,\n op: Extract<Operation, { type: \"update-layouts\" }>,\n): ApplyResult => {\n const previous: PaperLayout[] = [];\n for (const layout of op.layouts) {\n const prev = doc.layouts.find((l) => l.id === layout.id);\n if (!prev)\n throw new OpError(\"unknown-layout\", `Layout ${layout.id} not found`);\n previous.push(prev);\n for (const obj of layout.objects)\n assertObjectRefs(doc, obj, { layoutId: layout.id });\n }\n const byId = new Map(op.layouts.map((l) => [l.id, l]));\n return {\n document: {\n ...doc,\n layouts: doc.layouts.map((l) => byId.get(l.id) ?? l),\n },\n inverse: { type: \"update-layouts\", layouts: previous },\n };\n};\n\n/**\n * Validate + apply one operation against full document state. Returns the\n * next document and the inverse op. Throws `OpError` on any integrity\n * violation, leaving `doc` untouched (it is never mutated).\n */\nexport const applyOperation = (\n doc: LineaDocument,\n op: Operation,\n): ApplyResult => {\n switch (op.type) {\n case \"add-objects\":\n return applyAddObjects(doc, op);\n case \"update-objects\":\n return applyUpdateObjects(doc, op);\n case \"remove-objects\":\n return applyRemoveObjects(doc, op);\n case \"reorder-objects\":\n return applyReorderObjects(doc, op);\n case \"add-layer\":\n return applyAddLayer(doc, op);\n case \"update-layer\":\n return applyUpdateLayer(doc, op);\n case \"remove-layer\":\n return applyRemoveLayer(doc, op);\n case \"set-layers\":\n return applySetLayers(doc, op);\n case \"reorder-layers\":\n return applyReorderLayers(doc, op);\n case \"set-current-layer\":\n return applySetCurrentLayer(doc, op);\n case \"set-document-settings\":\n return applySetDocumentSettings(doc, op);\n case \"set-dim-styles\":\n return applySetDimStyles(doc, op);\n case \"add-dim-style\":\n return applyAddDimStyle(doc, op);\n case \"update-dim-style\":\n return applyUpdateDimStyle(doc, op);\n case \"remove-dim-style\":\n return applyRemoveDimStyle(doc, op);\n case \"reorder-dim-styles\":\n return applyReorderDimStyles(doc, op);\n case \"set-text-styles\":\n return applySetTextStyles(doc, op);\n case \"add-text-style\":\n return applyAddTextStyle(doc, op);\n case \"update-text-style\":\n return applyUpdateTextStyle(doc, op);\n case \"remove-text-style\":\n return applyRemoveTextStyle(doc, op);\n case \"reorder-text-styles\":\n return applyReorderTextStyles(doc, op);\n case \"add-line-type\":\n return applyAddLineType(doc, op);\n case \"update-line-type\":\n return applyUpdateLineType(doc, op);\n case \"remove-line-type\":\n return applyRemoveLineType(doc, op);\n case \"add-hatch-pattern\":\n return applyAddHatchPattern(doc, op);\n case \"update-hatch-pattern\":\n return applyUpdateHatchPattern(doc, op);\n case \"remove-hatch-pattern\":\n return applyRemoveHatchPattern(doc, op);\n case \"set-block-definitions\":\n return applySetBlockDefinitions(doc, op);\n case \"add-block-definition\":\n return applyAddBlockDefinition(doc, op);\n case \"update-block-definition\":\n return applyUpdateBlockDefinition(doc, op);\n case \"remove-block-definition\":\n return applyRemoveBlockDefinition(doc, op);\n case \"reorder-block-definitions\":\n return applyReorderBlockDefinitions(doc, op);\n case \"set-document-commands\":\n return applySetDocumentCommands(doc, op);\n case \"add-document-command\":\n return applyAddDocumentCommand(doc, op);\n case \"update-document-command\":\n return applyUpdateDocumentCommand(doc, op);\n case \"remove-document-command\":\n return applyRemoveDocumentCommand(doc, op);\n case \"reorder-document-commands\":\n return applyReorderDocumentCommands(doc, op);\n case \"set-asset\":\n return applySetAsset(doc, op);\n case \"remove-asset\":\n return applyRemoveAsset(doc, op);\n case \"add-layout\":\n return applyAddLayout(doc, op);\n case \"remove-layout\":\n return applyRemoveLayout(doc, op);\n case \"reorder-layouts\":\n return applyReorderLayouts(doc, op);\n case \"update-layout-meta\":\n return applyUpdateLayoutMeta(doc, op);\n case \"update-layouts\":\n return applyUpdateLayouts(doc, op);\n }\n};\n\n/** Which object ids an op invalidates (`null` = everything; `[]` = nothing). */\nexport const invalidationIds = (op: Operation): string[] | null => {\n switch (op.type) {\n case \"add-objects\":\n case \"update-objects\":\n return op.objects.map((o) => o.id);\n case \"remove-objects\":\n return op.ids;\n case \"set-current-layer\":\n case \"set-document-settings\":\n case \"set-document-commands\":\n case \"add-document-command\":\n case \"update-document-command\":\n case \"remove-document-command\":\n case \"reorder-document-commands\":\n return []; // no rendered change\n case \"add-layer\": // fresh id — validation guarantees nothing references it\n case \"remove-layer\": // validation guarantees the layer had no members\n case \"reorder-layers\": // layer order is panel display order only\n case \"reorder-block-definitions\": // library display order only\n case \"reorder-layouts\": // PDF page order — no per-object cache depends on it\n return [];\n case \"reorder-objects\":\n // Z-order only: per-object caches (snap entries, block eval) don't\n // depend on order; repaint comes from the document change itself.\n return [];\n default:\n // layer/style/blockDefs/layout changes affect everything. Style ADDS\n // included: a dangling styleId legally resolves to the first style, so\n // adding the missing style can restyle existing text/dimensions.\n return null;\n }\n};\n","// DocumentKernel — the stateful wrapper around applyOperation. Holds a\n// LineaDocument plus the id/type indexes for the active space, fires cache\n// invalidation (block eval + any subscriber), and returns inverse ops. This\n// is what the editor's modelStore will delegate to; the cloud server uses the\n// pure applyOperation directly. See docs/kernel-op-layer.md.\n\nimport type { Layer, LineaDocument } from \"../model/document\";\nimport type { ModelObject, ModelObjectType } from \"../model/objects\";\nimport {\n expandWithBlockDependents,\n invalidateBlockCache,\n} from \"../extensions/evalBlock\";\nimport { applyOperation, invalidationIds } from \"./apply\";\nimport type { OpSpace, Operation } from \"./types\";\n\nexport type InvalidationListener = (ids: string[] | null) => void;\n\nexport class DocumentKernel {\n private doc: LineaDocument;\n private activeSpace: OpSpace = \"model\";\n private idIndex = new Map<string, ModelObject>();\n private typeIndex = new Map<ModelObjectType, Set<string>>();\n private listeners = new Set<InvalidationListener>();\n\n constructor(doc: LineaDocument) {\n this.doc = doc;\n this.rebuildIndexes();\n }\n\n get document(): LineaDocument {\n return this.doc;\n }\n\n get space(): OpSpace {\n return this.activeSpace;\n }\n\n /** Replace the whole document (file open / new). Rebuilds, invalidates all. */\n load(doc: LineaDocument): void {\n this.doc = doc;\n this.rebuildIndexes();\n this.invalidate(null);\n }\n\n /** Switch the active space the indexes target (model or a layout). */\n setActiveSpace(space: OpSpace): void {\n this.activeSpace = space;\n this.rebuildIndexes();\n this.invalidate(null);\n }\n\n onInvalidate(fn: InvalidationListener): () => void {\n this.listeners.add(fn);\n return () => this.listeners.delete(fn);\n }\n\n getObject(id: string): ModelObject | undefined {\n return this.idIndex.get(id);\n }\n\n getObjectsByType<T extends ModelObjectType>(\n type: T,\n ): Extract<ModelObject, { type: T }>[] {\n const ids = this.typeIndex.get(type);\n if (!ids) return [];\n const out: Extract<ModelObject, { type: T }>[] = [];\n for (const id of ids) {\n const obj = this.idIndex.get(id);\n if (obj) out.push(obj as Extract<ModelObject, { type: T }>);\n }\n return out;\n }\n\n getLayer(id: string): Layer | undefined {\n return this.doc.layers.find((l) => l.id === id);\n }\n\n /** Objects of the active space (the index source). */\n activeObjects(): ModelObject[] {\n const space = this.activeSpace;\n if (space === \"model\") return this.doc.objects;\n return this.doc.layouts.find((l) => l.id === space.layoutId)?.objects ?? [];\n }\n\n /**\n * Validate + apply one op, refresh indexes/caches, return the INVERSE op.\n * Throws `OpError` (document untouched) on an integrity violation.\n */\n apply(op: Operation): Operation {\n const { document, inverse } = applyOperation(this.doc, op);\n this.doc = document;\n this.reindexForOp(op);\n this.invalidate(invalidationIds(op));\n return inverse;\n }\n\n /**\n * Apply a batch: validates + applies in order; on any `OpError` rolls the\n * document back to the pre-batch snapshot and rethrows (nothing partially\n * applied). Returns inverse ops in REVERSE order, so applying them in turn\n * undoes the whole batch.\n */\n applyMany(ops: Operation[]): Operation[] {\n const snapshot = this.doc;\n const inverses: Operation[] = [];\n try {\n for (const op of ops) inverses.push(this.apply(op));\n } catch (e) {\n this.doc = snapshot;\n this.rebuildIndexes();\n this.invalidate(null);\n throw e;\n }\n return inverses.reverse();\n }\n\n private rebuildIndexes(): void {\n this.idIndex.clear();\n this.typeIndex.clear();\n for (const obj of this.activeObjects()) this.indexAdd(obj);\n }\n\n private indexAdd(obj: ModelObject): void {\n this.idIndex.set(obj.id, obj);\n let bucket = this.typeIndex.get(obj.type);\n if (!bucket) {\n bucket = new Set();\n this.typeIndex.set(obj.type, bucket);\n }\n bucket.add(obj.id);\n }\n\n private indexRemoveById(id: string): void {\n const prev = this.idIndex.get(id);\n if (!prev) return;\n this.idIndex.delete(id);\n this.typeIndex.get(prev.type)?.delete(id);\n }\n\n private opTargetsActiveSpace(op: Operation): boolean {\n if (!(\"space\" in op)) return false;\n const s = op.space;\n return s === \"model\"\n ? this.activeSpace === \"model\"\n : this.activeSpace !== \"model\" &&\n this.activeSpace.layoutId === s.layoutId;\n }\n\n /**\n * Incrementally maintain the active-space index after an op — O(changed)\n * for object ops (the interactive hot path) rather than a full rebuild.\n */\n private reindexForOp(op: Operation): void {\n switch (op.type) {\n case \"add-objects\":\n if (this.opTargetsActiveSpace(op))\n for (const o of op.objects) this.indexAdd(o);\n return;\n case \"remove-objects\":\n if (this.opTargetsActiveSpace(op))\n for (const id of op.ids) this.indexRemoveById(id);\n return;\n case \"update-objects\":\n if (this.opTargetsActiveSpace(op))\n for (const o of op.objects) {\n this.indexRemoveById(o.id);\n this.indexAdd(o);\n }\n return;\n case \"reorder-objects\":\n // Same object set, new order — the indexes are order-independent.\n return;\n case \"add-layout\":\n case \"remove-layout\":\n case \"update-layouts\":\n // Could change which objects the active space exposes (e.g. the\n // active layout was removed or its content replaced) — rebuild.\n this.rebuildIndexes();\n return;\n default:\n // layer / dim-style / name / current-layer / block-defs / layout-meta:\n // no change to the active-space object set.\n return;\n }\n }\n\n private invalidate(ids: string[] | null): void {\n // Instances whose inputs reference a mutated object are stale too —\n // expand BEFORE dropping caches so listeners see the same id list.\n const expanded = ids === null ? null : expandWithBlockDependents(ids);\n invalidateBlockCache(expanded);\n for (const fn of this.listeners) fn(expanded);\n }\n}\n","// The in-process `Drawing` — its ONE implementation: mutations mapped 1:1 to\n// validated ops, reads and renders through the headless paint paths. The\n// document lives in a DocumentKernel with op-based undo stacks, or — given\n// DrawingHooks — in a host's stores (the editor's subclass routes ops through\n// its mutation funnel and history). Browser-safe (no Node imports); hosts\n// subclass it for their I/O: the SDK (files, PNG/PDF, imports), the editor\n// (PDF/PNG). Ergonomics only (layer-by-name, array points via the schema,\n// batching) — never new semantics.\n\nimport { lineTypeKey, LineTypeSchema, type LineType } from \"../model/lineTypes\";\nimport {\n hatchPatternKey,\n HatchPatternSchema,\n type DocumentHatchPattern,\n} from \"../model/hatchPatterns\";\nimport { z } from \"zod\";\nimport { arcSweep, distToArc } from \"../geometry/arcs\";\nimport {\n boundsIntersect,\n emptyBounds,\n isEmptyBounds,\n unionBounds,\n type AABB,\n} from \"../geometry/bounds\";\nimport { closestPointOnSegment } from \"../geometry/line\";\nimport { chainLength, hatchArea, polylineArea } from \"../geometry/polyline\";\nimport { dist, type Vec2 } from \"../geometry/vec2\";\nimport { hashAsset } from \"../model/assets\";\nimport { Vec2Schema } from \"../model/common\";\nimport {\n DEFAULT_DOCUMENT_NAME,\n LayerSchema,\n type Layer,\n type LineaDocument,\n} from \"../model/document\";\nimport {\n documentObjectResolver,\n resolveDocumentObject,\n} from \"../model/objectLookup\";\nimport {\n assertKnownStyleOverrideKeys,\n DimStyleSchema,\n ModelObjectSchema,\n TextStyleSchema,\n type DimStyle,\n type ModelObject,\n type ReferenceObject,\n type TextStyle,\n} from \"../model/objects\";\nimport {\n dimensionRawToLabels,\n dimensionRawToOffset,\n} from \"../model/migrations\";\nimport type { ReferenceContent } from \"../reference/reference\";\nimport {\n PaperLayoutSchema,\n resolveSheetSize,\n sheetOrientation,\n type PaperLayout,\n} from \"../model/paperLayout\";\nimport { parseScale } from \"../model/scale\";\nimport { documentPaintResources } from \"../paint/painters\";\nimport { approximateTextMeasurer } from \"../paint/textMeasurer\";\nimport type { TextMeasurer } from \"../paint/textMetrics\";\nimport { buildSnapEntry, type SnapGeometryContext } from \"../snap/buildEntry\";\nimport type { SnapCacheEntry } from \"../snap/types\";\nimport { renderLayoutToSvg, renderModelToSvg } from \"../export/svg/renderSvg\";\nimport { dwgToDxf, dxfToDwg, type DwgVersion } from \"../dwg\";\nimport { dxfToModel } from \"../import/dxf/importDxf\";\nimport { dxfImportContextOf, dxfImportOps } from \"../import/dxf/importPlan\";\nimport { pdfToModel } from \"../import/pdf/importPdf\";\nimport { documentToJson } from \"../serialize\";\nimport {\n mirrorObject,\n remapBlockInputRefs,\n rotateObject,\n scaleObjectUniform,\n translateObject,\n} from \"../transform\";\nimport { listBlockMeta, type BlockMeta } from \"../extensions/evalBlock\";\nimport {\n listCommandMeta,\n mergeCommandModules,\n type CommandMeta,\n} from \"../extensions/commandModules\";\nimport { mergeBlockModules } from \"../extensions/scriptModules\";\nimport {\n MarketplaceClient,\n MarketplaceConfigSchema,\n marketplaceInfo,\n marketplaceKey,\n marketplaceLabel,\n matchesMarketplace,\n normalizeMarketplaces,\n type MarketplaceConfig,\n type MarketplaceHit,\n type MarketplaceInfo,\n type MarketplaceIO,\n type MarketplaceQuery,\n} from \"../marketplace/catalog\";\nimport { ensureScriptTranspiler } from \"../extensions/scriptRuntime\";\nimport {\n diffDimStyleOps,\n diffModuleOps,\n diffTextStyleOps,\n} from \"../operations/diff\";\nimport { DocumentKernel } from \"../operations/kernel\";\nimport {\n parseOperations,\n type Operation,\n type OpSpace,\n type ReorderPlacement,\n} from \"../operations/types\";\nimport type {\n AddOptions,\n DocumentSummary,\n Drawing,\n LayerInfo,\n LayoutOptions,\n LayoutPatch,\n Measurement,\n MergeReport,\n ObjectInput,\n PointInput,\n QueryFilter,\n RenderPdfOptions,\n RenderSvgOptions,\n} from \"./types\";\n\nconst toVec = (p: PointInput): Vec2 => Vec2Schema.parse(p);\n\n/** Zod issues → one readable error, prefixed with the failing call/object. */\nconst wrapZod = (e: unknown, context: string): Error => {\n if (!(e instanceof z.ZodError))\n return e instanceof Error ? e : new Error(String(e));\n return new Error(`${context}: ${z.prettifyError(e)}`);\n};\n\nexport interface DxfImportOptions {\n /** mm per drawing unit; overrides the file's $INSUNITS header. */\n unitOverride?: number;\n}\n\nexport interface DxfImportReport {\n objects: number;\n layers: number;\n layouts: number;\n objectIds: string[];\n layoutIds: string[];\n /** `SOURCE→what` → entities imported as an approximation. */\n degraded: Record<string, number>;\n /** Entity type or reason → entities that produced nothing. */\n skipped: Record<string, number>;\n /** Text / dimension styles the file's STYLE / DIMSTYLE tables added\n * (styles matching an existing one by name and values are reused). */\n textStyles: number;\n dimStyles: number;\n /** Block definitions generated for the file's INSERTs (uniform-scale\n * inserts become instances of them). */\n blockDefinitions: number;\n /** Line type / hatch pattern definitions the file added (LTYPE table\n * entries the catalogue lacks; HATCH definition lines). */\n lineTypes: number;\n hatchPatterns: number;\n}\n\nexport interface PdfImportReport {\n objects: number;\n pageCount: number;\n objectIds: string[];\n}\n\nexport interface PdfImportOptions {\n /** \"vectors\" (default): lines and text runs. \"image\": every page\n * rasterized and placed as an image at true page scale — a host\n * capability (`rasterizePdf`), refused where it is missing. */\n as?: \"vectors\" | \"image\";\n /** Bottom-left corner of the first page (image mode; default 0,0). Pages\n * line up to the right. */\n origin?: PointInput;\n}\n\n/** One PDF page rasterized: PNG pixels plus its true size in mm. */\nexport interface RasterPdfPage {\n dataUrl: string;\n widthMm: number;\n heightMm: number;\n}\n\n/** An embedded image asset as `listAssets` reports it. */\nexport interface AssetInfo {\n id: string;\n /** From the data URL, e.g. \"image/png\". */\n mimeType: string;\n /** Decoded size in bytes. */\n bytes: number;\n /** Image objects (every space) that show it. */\n users: number;\n}\n\n/** Gap between PDF pages placed side by side (image import), mm. */\nconst PDF_PAGE_GAP_MM = 50;\n\ntype Step = { forwards: Operation[]; inverses: Operation[] };\n\n/**\n * Which layouts a PDF render prints (shared by every renderPdf host): the\n * named ones in the order given, else every layout in document order, else\n * — for a layout-less document — one ephemeral fitted sheet from `fallback`\n * (the document itself gains no layout). `palette` overrides each page's.\n */\nexport const selectPdfLayouts = (\n layouts: readonly PaperLayout[],\n opts: RenderPdfOptions,\n fallback: () => PaperLayout,\n): PaperLayout[] => {\n const byRef = (ref: string) => {\n const l = layouts.find((x) => x.name === ref || x.id === ref);\n if (!l) throw new Error(`Unknown layout \"${ref}\"`);\n return l;\n };\n let selected =\n opts.layouts !== undefined\n ? opts.layouts.map(byRef)\n : layouts.length > 0\n ? [...layouts]\n : [fallback()];\n if (opts.palette)\n selected = selected.map((l) => ({ ...l, printPalette: opts.palette! }));\n if (selected.length === 0) throw new Error(\"No layouts selected\");\n return selected;\n};\n\n/** Reject duplicate ids in a whole-array style replace, so the diff always\n * decomposes into granular per-item ops and never falls back to the legacy\n * coarse set-* op (docs/granular-ops.md). */\nconst assertUniqueIds = (\n items: readonly { id: string }[],\n where: string,\n): void => {\n const seen = new Set<string>();\n for (const { id } of items) {\n if (seen.has(id))\n throw new Error(`${where}: duplicate style id ${JSON.stringify(id)}`);\n seen.add(id);\n }\n};\n\n/**\n * Where a LocalDrawing's document lives and how its edits are recorded. Absent\n * (constructed from a document), LocalDrawing owns a kernel and its own undo\n * stacks; the editor passes hooks over its live stores so agent and script\n * edits go through the mutation funnel and the user's history.\n */\nexport interface DrawingHooks {\n /** The live document — read only, never handed out. */\n document(): LineaDocument;\n /** Apply one validated op (throws when refused). */\n apply(op: Operation): void;\n /** One undo step for everything `fn` applies; a throw (or rejection)\n * rolls it back and rethrows. Nested calls join the outer step. */\n transaction<T>(fn: () => T): T;\n inTransaction(): boolean;\n undo(): boolean;\n redo(): boolean;\n canUndo(): boolean;\n canRedo(): boolean;\n /** Bumped by every change the drawing should report (agents poll it). */\n revision(): number;\n /** Text metrics for bounds and DXF (default: approximate font metrics). */\n measure?: TextMeasurer;\n /** Document-wide object lookup for block reference inputs. */\n resolveObject?: (id: string) => ModelObject | undefined;\n /** Loaded reference content (default: the drawing's referenceContent). */\n resolveReference?: (ref: ReferenceObject) => ReferenceContent | null;\n /** Snap/hit-test geometry, e.g. from a cache (default: built per call). */\n snapEntry?: (obj: ModelObject) => SnapCacheEntry;\n /** Where the host keeps its marketplace list and how it reaches them\n * (default: an in-memory list holding the public collection, fetched\n * with the platform's fetch — folder marketplaces then need a reader). */\n marketplaces?: MarketplaceHost;\n}\n\n/** A host's marketplace configuration: the list (the editor's settings, a\n * process's config) and the client that fetches from it. */\nexport interface MarketplaceHost {\n list(): MarketplaceConfig[];\n set(list: MarketplaceConfig[]): void;\n client: MarketplaceClient;\n}\n\nexport const memoryMarketplaceHost = (io?: MarketplaceIO): MarketplaceHost => {\n let list: MarketplaceConfig[] = [{ kind: \"builtin\" }];\n return {\n list: () => list,\n set: (next) => {\n list = next;\n },\n client: new MarketplaceClient(io),\n };\n};\n\n/** The headless hooks: one DocumentKernel plus op-based undo stacks. */\nconst kernelHooks = (doc: LineaDocument): DrawingHooks => {\n const kernel = new DocumentKernel(doc);\n const undoStack: Step[] = [];\n const redoStack: Step[] = [];\n let txn: Step | null = null;\n let rev = 0;\n const replay = (ops: readonly Operation[]) => {\n for (const op of ops) kernel.apply(op);\n rev++;\n };\n return {\n document: () => kernel.document,\n apply(op) {\n const inverse = kernel.apply(op);\n rev++;\n if (txn) {\n txn.forwards.push(op);\n txn.inverses.push(inverse);\n } else {\n undoStack.push({ forwards: [op], inverses: [inverse] });\n redoStack.length = 0;\n }\n },\n transaction<T>(fn: () => T): T {\n if (txn) return fn(); // nested → part of the outer step\n const step: Step = { forwards: [], inverses: [] };\n txn = step;\n const commit = () => {\n txn = null;\n if (step.forwards.length > 0) {\n undoStack.push(step);\n redoStack.length = 0;\n }\n };\n const rollback = () => {\n txn = null;\n if (step.forwards.length > 0) replay([...step.inverses].reverse());\n };\n let result: T;\n try {\n result = fn();\n } catch (e) {\n rollback();\n throw e;\n }\n if (result instanceof Promise) {\n return result.then(\n (v) => {\n commit();\n return v;\n },\n (e: unknown) => {\n rollback();\n throw e;\n },\n ) as T;\n }\n commit();\n return result;\n },\n inTransaction: () => txn !== null,\n undo() {\n const step = undoStack.pop();\n if (!step) return false;\n replay([...step.inverses].reverse());\n redoStack.push(step);\n return true;\n },\n redo() {\n const step = redoStack.pop();\n if (!step) return false;\n replay(step.forwards);\n undoStack.push(step);\n return true;\n },\n canUndo: () => undoStack.length > 0,\n canRedo: () => redoStack.length > 0,\n revision: () => rev,\n };\n};\n\n/** Layer patches may say `hidden` (the tool texts long advertised it) —\n * the stored field is `visible`. */\nconst withVisible = <T extends object>(layer: T): T => {\n const { hidden, ...rest } = layer as T & { hidden?: unknown };\n if (hidden === undefined) return layer;\n return { ...rest, visible: !hidden } as T;\n};\n\nexport class LocalDrawing implements Drawing {\n private hooks: DrawingHooks;\n /** Schema-version migration applied on open; null when none was needed. */\n readonly migration: { from: number; to: number } | null;\n /** Display name (summary, default export names). Host state — a document\n * carries no name: the SDK keeps it in step with the file name. */\n name = DEFAULT_DOCUMENT_NAME;\n /** Loaded reference content by reference id. Hosts that can read files\n * fill it (the Node SDK, in `ready()`); empty → references paint and\n * snap as frames. docs/references.md. */\n protected referenceContent = new Map<string, ReferenceContent>();\n private resolveReference = (ref: ReferenceObject): ReferenceContent | null =>\n this.hooks.resolveReference\n ? this.hooks.resolveReference(ref)\n : (this.referenceContent.get(ref.id) ?? null);\n\n /** A document (owned here: kernel + undo stacks), or hooks over a document\n * that lives elsewhere (the editor's stores). */\n constructor(\n source: LineaDocument | DrawingHooks,\n migration: { from: number; to: number } | null = null,\n ) {\n this.hooks = \"apply\" in source ? source : kernelHooks(source);\n this.migration = migration;\n // Block identity/metadata are module exports — start the (lazy)\n // transpiler now so meta-dependent paths (ops validation, evaluation,\n // rendering) go definitive as early as possible. Until it lands the\n // checks are permissive, never wrong.\n if (this.state.blockDefinitions.length > 0) void ensureScriptTranspiler();\n }\n\n /** The live document — internal reads only; NEVER handed out. */\n protected get state(): LineaDocument {\n return this.hooks.document();\n }\n\n get id(): string {\n return this.state.id;\n }\n\n get revision(): number {\n return this.hooks.revision();\n }\n\n // Public reads return detached deep clones: mutating them cannot corrupt\n // the document (all edits must go through the validated ops, which also\n // keep undo history and the block caches correct).\n get document(): LineaDocument {\n return structuredClone(this.state);\n }\n get layers(): Layer[] {\n return structuredClone(this.state.layers);\n }\n get objects(): ModelObject[] {\n return structuredClone(this.state.objects);\n }\n get layouts(): PaperLayout[] {\n return structuredClone(this.state.layouts);\n }\n\n listLayouts(): PaperLayout[] {\n return this.layouts;\n }\n\n /** Look up an object in ANY space (model or a layout's sheet objects). */\n getObject(id: string): ModelObject | undefined {\n const obj = resolveDocumentObject(this.state, id);\n return obj && structuredClone(obj);\n }\n\n private findObject(id: string): { obj: ModelObject; space: OpSpace } {\n const doc = this.state;\n const obj = resolveDocumentObject(doc, id);\n if (!obj) throw new Error(`Unknown object \"${id}\"`);\n // ponytail: linear scan of layout sheets (few, small); index if it shows.\n const layout = doc.layouts.find((l) => l.objects.includes(obj));\n return { obj, space: layout ? { layoutId: layout.id } : \"model\" };\n }\n\n private groupBySpace<T>(\n entries: { space: OpSpace; item: T }[],\n ): { space: OpSpace; items: T[] }[] {\n const groups = new Map<string, { space: OpSpace; items: T[] }>();\n for (const { space, item } of entries) {\n const key = space === \"model\" ? \"model\" : space.layoutId;\n const group = groups.get(key) ?? { space, items: [] };\n group.items.push(item);\n groups.set(key, group);\n }\n return [...groups.values()];\n }\n\n /** One op per space, all in one undo step. */\n private applyBySpace(\n entries: { space: OpSpace; obj: ModelObject }[],\n make: (space: OpSpace, objects: ModelObject[]) => Operation,\n ): void {\n const groups = this.groupBySpace(\n entries.map(({ space, obj }) => ({ space, item: obj })),\n );\n this.transaction(() => {\n for (const g of groups) this.applyForward(make(g.space, g.items));\n });\n }\n\n // --- op plumbing ---------------------------------------------------------\n\n private applyForward(op: Operation): void {\n this.hooks.apply(op);\n }\n\n /** Emit an op list as one undo step. */\n private applyForwardAll(ops: readonly Operation[]): void {\n this.transaction(() => {\n for (const op of ops) this.applyForward(op);\n });\n }\n\n /** Escape hatch: a raw op batch — schema-checked (parseOperations), then\n * applied atomically as one step (the kernel checks references). */\n applyOps(ops: readonly Operation[]): void {\n this.applyForwardAll(parseOperations(ops));\n }\n\n /**\n * Group mutations into ONE undo step. A throw (sync, or an async fn's\n * rejection) rolls back everything the transaction applied and rethrows.\n * Nested calls join the outer step.\n */\n transaction<T>(fn: () => T): T {\n return this.hooks.transaction(fn);\n }\n\n private assertNoTransaction(what: string): void {\n if (this.hooks.inTransaction())\n throw new Error(\n `${what}() inside a transaction — return or throw to roll back instead`,\n );\n }\n\n undo(): boolean {\n this.assertNoTransaction(\"undo\");\n return this.hooks.undo();\n }\n redo(): boolean {\n this.assertNoTransaction(\"redo\");\n return this.hooks.redo();\n }\n get canUndo(): boolean {\n return this.hooks.canUndo();\n }\n get canRedo(): boolean {\n return this.hooks.canRedo();\n }\n\n // --- layers --------------------------------------------------------------\n\n private resolveLayerId(layerName?: string, layerId?: string): string {\n if (layerId) return layerId;\n if (layerName) return this.resolveLayer(layerName).id;\n return this.state.currentLayerId;\n }\n\n listLayers(): LayerInfo[] {\n const current = this.state.currentLayerId;\n return this.layers.map((l) => ({ ...l, current: l.id === current }));\n }\n\n /** Create a layer; returns its id. */\n addLayer(layer: Partial<Layer> & { name: string }): string {\n // Names are how layers are addressed everywhere (layer-by-name in add,\n // query filters) — a silent duplicate would resolve to the first match.\n const clash = this.state.layers.find(\n (l) => l.name.toLowerCase() === layer.name.toLowerCase(),\n );\n if (clash)\n throw new Error(`addLayer(): layer \"${clash.name}\" already exists`);\n const full = LayerSchema.parse(withVisible(layer));\n this.applyForward({ type: \"add-layer\", layer: full });\n return full.id;\n }\n\n private resolveLayer(nameOrId: string): Layer {\n const l = this.state.layers.find(\n (x) => x.id === nameOrId || x.name === nameOrId,\n );\n if (!l) throw new Error(`Unknown layer \"${nameOrId}\"`);\n return l;\n }\n\n /** Patch a layer (rename, color, lineWidth, visible, locked) by name or id. */\n updateLayer(nameOrId: string, patch: Partial<Omit<Layer, \"id\">>): void {\n const cur = this.resolveLayer(nameOrId);\n if (\n patch.name !== undefined &&\n patch.name.toLowerCase() !== cur.name.toLowerCase()\n ) {\n const clash = this.state.layers.find(\n (l) => l.name.toLowerCase() === patch.name!.toLowerCase(),\n );\n if (clash)\n throw new Error(`updateLayer(): layer \"${clash.name}\" already exists`);\n }\n this.applyForward({\n type: \"update-layer\",\n layer: LayerSchema.parse({ ...cur, ...withVisible(patch), id: cur.id }),\n });\n }\n\n /** Remove an EMPTY, non-current layer (the kernel refuses otherwise). */\n removeLayer(nameOrId: string): void {\n this.applyForward({\n type: \"remove-layer\",\n id: this.resolveLayer(nameOrId).id,\n });\n }\n\n /** Reorder the layers (names or ids, every layer exactly once). */\n reorderLayers(order: readonly string[]): void {\n this.applyForward({\n type: \"reorder-layers\",\n ids: order.map((l) => this.resolveLayer(l).id),\n });\n }\n\n /** The layer newly added objects default to. */\n setCurrentLayer(nameOrId: string): void {\n this.applyForward({\n type: \"set-current-layer\",\n id: this.resolveLayer(nameOrId).id,\n });\n }\n\n updateSettings(patch: Partial<LineaDocument[\"settings\"]>): void {\n this.applyForward({\n type: \"set-document-settings\",\n settings: { ...this.state.settings, ...patch },\n });\n }\n\n // --- document meta / assets ------------------------------------------------\n\n /**\n * Embed image pixels (a data URL) and return the assetId that `image`\n * objects reference. Content-keyed: the same data reuses one entry.\n */\n addAsset(dataUrl: string): string {\n const id = hashAsset(dataUrl);\n if (this.state.assets[id] !== dataUrl)\n this.applyForward({ type: \"set-asset\", id, dataUrl });\n return id;\n }\n\n /** Remove an asset (the kernel refuses while an image references it). */\n removeAsset(id: string): void {\n this.applyForward({ type: \"remove-asset\", id });\n }\n\n listAssets(): AssetInfo[] {\n const users = new Map<string, number>();\n for (const objs of [\n this.state.objects,\n ...this.state.layouts.map((l) => l.objects),\n ])\n for (const o of objs)\n if (o.type === \"image\")\n users.set(o.assetId, (users.get(o.assetId) ?? 0) + 1);\n return Object.entries(this.state.assets).map(([id, dataUrl]) => {\n const comma = dataUrl.indexOf(\",\");\n const base64 = dataUrl.slice(comma + 1);\n return {\n id,\n mimeType: /^data:([^;,]+)/.exec(dataUrl)?.[1] ?? \"\",\n bytes:\n Math.floor((base64.length * 3) / 4) -\n (base64.match(/=+$/)?.[0].length ?? 0),\n users: users.get(id) ?? 0,\n };\n });\n }\n\n // --- import (merge into this document) -------------------------------------\n\n /** Merge DXF text into the document (new layers, objects, layouts). */\n importDxfText(text: string, opts: DxfImportOptions = {}): DxfImportReport {\n const doc = this.state;\n const result = dxfToModel(text, dxfImportContextOf(doc, opts.unitOverride));\n const { ops, objects } = dxfImportOps(doc, result);\n this.applyOps(ops);\n return {\n objects: objects.length,\n layers: result.newLayers.length,\n layouts: result.layouts.length,\n objectIds: objects.map((o) => o.id),\n layoutIds: result.layouts.map((l) => l.id),\n degraded: Object.fromEntries(result.degraded),\n skipped: Object.fromEntries(result.skipped),\n textStyles: result.textStyles.length - doc.textStyles.length,\n dimStyles: result.dimStyles.length - doc.dimStyles.length,\n blockDefinitions: result.newBlockDefinitions.length,\n lineTypes: result.lineTypes.length - doc.lineTypes.length,\n hatchPatterns: result.hatchPatterns.length - doc.hatchPatterns.length,\n };\n }\n\n /** Merge DWG bytes into the document (wasm transcode → the DXF path). */\n async importDwgData(\n data: Uint8Array,\n opts?: DxfImportOptions,\n ): Promise<DxfImportReport> {\n return this.importDxfText(await dwgToDxf(data), opts);\n }\n\n /** Merge a PDF: its vector/text content onto the current layer, or\n * (`as: \"image\"`) every page as an image at true page scale. */\n async importPdfData(\n data: ArrayBuffer | Uint8Array,\n opts: PdfImportOptions = {},\n ): Promise<PdfImportReport> {\n if (opts.as === \"image\") {\n if (!this.rasterizePdf)\n throw new Error(\n 'PDF as image is not available on this host yet; import it with as: \"vectors\"',\n );\n const pages = await this.rasterizePdf(data);\n const at = toVec(opts.origin ?? [0, 0]);\n const layerId = this.state.currentLayerId;\n let x = at.x;\n const placed = pages.map((p) => {\n const object = {\n type: \"image\",\n layerId,\n assetId: this.addAsset(p.dataUrl),\n origin: { x, y: at.y },\n width: p.widthMm,\n height: p.heightMm,\n } as ObjectInput;\n x += p.widthMm + PDF_PAGE_GAP_MM;\n return object;\n });\n const objectIds = placed.length > 0 ? this.add(placed) : [];\n return { objects: objectIds.length, pageCount: pages.length, objectIds };\n }\n const result = await pdfToModel(data, { workerSrc: this.pdfWorkerSrc });\n const layerId = this.state.currentLayerId;\n const objectIds =\n result.objects.length > 0\n ? this.add(\n result.objects.map((o) => ({ ...o, layerId }) as ObjectInput),\n )\n : [];\n return {\n objects: result.objects.length,\n pageCount: result.pageCount,\n objectIds,\n };\n }\n\n /** Host capability: every PDF page rasterized. Absent → PDF-as-image\n * import is refused (headless Node, until it has a rasterizer). */\n rasterizePdf?(data: ArrayBuffer | Uint8Array): Promise<RasterPdfPage[]>;\n\n /** pdf.js worker URL for hosts that need one (the browser). */\n protected pdfWorkerSrc?: string;\n\n // --- styles ----------------------------------------------------------------\n\n // Styles are addressed by name or id, like layers, so names stay unique\n // (case-insensitive) on add and rename.\n private resolveStyle<T extends { id: string; name: string }>(\n styles: readonly T[],\n nameOrId: string,\n what: string,\n ): T {\n const s = styles.find((x) => x.id === nameOrId || x.name === nameOrId);\n if (!s) throw new Error(`Unknown ${what} \"${nameOrId}\"`);\n return s;\n }\n\n private assertStyleName(\n styles: readonly { id: string; name: string }[],\n name: string,\n context: string,\n except?: string,\n ): void {\n const clash = styles.find(\n (s) => s.id !== except && s.name.toLowerCase() === name.toLowerCase(),\n );\n if (clash)\n throw new Error(`${context}: style \"${clash.name}\" already exists`);\n }\n\n /** Layouts are addressed by name everywhere (`layout` on the object\n * tools, remove, reorder, render) — a duplicate would silently resolve to\n * the first match. */\n private assertLayoutName(name: string, context: string, except?: string) {\n const clash = this.state.layouts.find(\n (l) => l.id !== except && l.name.toLowerCase() === name.toLowerCase(),\n );\n if (clash)\n throw new Error(`${context}: layout \"${clash.name}\" already exists`);\n }\n\n /** Objects reference styles by id, but callers often pass the NAME:\n * resolve it (text/table → text styles, dimension → dim styles). An\n * unknown value is refused rather than stored dangling — a dangling\n * reference renders with the first style and nothing says why. */\n private styleRef(\n obj: { type?: unknown; styleId?: unknown },\n context: string,\n ): { styleId?: string } {\n if (typeof obj.styleId !== \"string\") return {}; // zod reports the rest\n const styles =\n obj.type === \"dimension\"\n ? this.state.dimStyles\n : obj.type === \"text\" || obj.type === \"table\"\n ? this.state.textStyles\n : null;\n if (!styles) return {};\n const s =\n styles.find((x) => x.id === obj.styleId) ??\n styles.find((x) => x.name === obj.styleId);\n if (!s)\n throw new Error(\n `${context}: unknown ${obj.type === \"dimension\" ? \"dim\" : \"text\"} style \"${obj.styleId}\"`,\n );\n return { styleId: s.id };\n }\n\n listTextStyles(): TextStyle[] {\n return this.state.textStyles.map((s) => ({ ...s }));\n }\n\n listDimStyles(): DimStyle[] {\n return this.state.dimStyles.map((s) => ({ ...s }));\n }\n\n /** Create a text style (unique name; unset fields take the defaults);\n * returns its id. */\n addTextStyle(\n props: { name: string } & Partial<Omit<TextStyle, \"id\">>,\n ): string {\n this.assertStyleName(this.state.textStyles, props.name, \"addTextStyle()\");\n const style = TextStyleSchema.parse(props);\n this.applyForward({ type: \"add-text-style\", style });\n return style.id;\n }\n\n updateTextStyle(\n nameOrId: string,\n patch: Partial<Omit<TextStyle, \"id\">>,\n ): void {\n const cur = this.resolveStyle(\n this.state.textStyles,\n nameOrId,\n \"text style\",\n );\n if (patch.name !== undefined)\n this.assertStyleName(\n this.state.textStyles,\n patch.name,\n \"updateTextStyle()\",\n cur.id,\n );\n this.applyForward({\n type: \"update-text-style\",\n style: TextStyleSchema.parse({ ...cur, ...patch, id: cur.id }),\n });\n }\n\n // --- line types / hatch patterns (name-keyed definitions) -----------------\n\n listLineTypes(): LineType[] {\n return this.state.lineTypes.map((t) => ({ ...t }));\n }\n\n addLineTypes(lineTypes: readonly LineType[]): void {\n this.transaction(() => {\n for (const raw of lineTypes) {\n const lineType = LineTypeSchema.parse(raw);\n this.applyForward({ type: \"add-line-type\", lineType });\n }\n });\n }\n\n updateLineType(name: string, patch: Partial<LineType>): void {\n const cur = this.state.lineTypes.find(\n (t) => lineTypeKey(t.name) === lineTypeKey(name),\n );\n if (!cur) throw new Error(`Unknown line type \"${name}\"`);\n const next = LineTypeSchema.parse({ ...cur, ...patch });\n if (lineTypeKey(next.name) !== lineTypeKey(cur.name)) {\n // A rename: the trio has no rename op — remove + add keeps history\n // granular and the name unique.\n this.transaction(() => {\n this.applyForward({ type: \"remove-line-type\", name: cur.name });\n this.applyForward({ type: \"add-line-type\", lineType: next });\n });\n } else this.applyForward({ type: \"update-line-type\", lineType: next });\n }\n\n removeLineType(name: string): void {\n this.applyForward({ type: \"remove-line-type\", name });\n }\n\n listHatchPatterns(): DocumentHatchPattern[] {\n return this.state.hatchPatterns.map((p) => ({ ...p }));\n }\n\n addHatchPatterns(patterns: readonly DocumentHatchPattern[]): void {\n this.transaction(() => {\n for (const raw of patterns) {\n const hatchPattern = HatchPatternSchema.parse(raw);\n this.applyForward({ type: \"add-hatch-pattern\", hatchPattern });\n }\n });\n }\n\n updateHatchPattern(name: string, patch: Partial<DocumentHatchPattern>): void {\n const cur = this.state.hatchPatterns.find(\n (p) => hatchPatternKey(p.name) === hatchPatternKey(name),\n );\n if (!cur) throw new Error(`Unknown hatch pattern \"${name}\"`);\n const next = HatchPatternSchema.parse({ ...cur, ...patch });\n if (hatchPatternKey(next.name) !== hatchPatternKey(cur.name)) {\n this.transaction(() => {\n this.applyForward({ type: \"remove-hatch-pattern\", name: cur.name });\n this.applyForward({ type: \"add-hatch-pattern\", hatchPattern: next });\n });\n } else\n this.applyForward({ type: \"update-hatch-pattern\", hatchPattern: next });\n }\n\n removeHatchPattern(name: string): void {\n this.applyForward({ type: \"remove-hatch-pattern\", name });\n }\n\n /** Remove a text style no object uses (the kernel refuses otherwise). */\n removeTextStyle(nameOrId: string): void {\n this.applyForward({\n type: \"remove-text-style\",\n id: this.resolveStyle(this.state.textStyles, nameOrId, \"text style\").id,\n });\n }\n\n /** Create a dimension style (unique name; unset fields take the\n * defaults); returns its id. */\n addDimStyle(props: { name: string } & Partial<Omit<DimStyle, \"id\">>): string {\n this.assertStyleName(this.state.dimStyles, props.name, \"addDimStyle()\");\n const style = DimStyleSchema.parse(props);\n this.applyForward({ type: \"add-dim-style\", style });\n return style.id;\n }\n\n updateDimStyle(nameOrId: string, patch: Partial<Omit<DimStyle, \"id\">>): void {\n const cur = this.resolveStyle(this.state.dimStyles, nameOrId, \"dim style\");\n if (patch.name !== undefined)\n this.assertStyleName(\n this.state.dimStyles,\n patch.name,\n \"updateDimStyle()\",\n cur.id,\n );\n this.applyForward({\n type: \"update-dim-style\",\n style: DimStyleSchema.parse({ ...cur, ...patch, id: cur.id }),\n });\n }\n\n /** Remove a dimension style no dimension uses (the kernel refuses\n * otherwise). */\n removeDimStyle(nameOrId: string): void {\n this.applyForward({\n type: \"remove-dim-style\",\n id: this.resolveStyle(this.state.dimStyles, nameOrId, \"dim style\").id,\n });\n }\n\n /** @deprecated Use updateDimStyle (default here: the first style). */\n setDimStyle(patch: Partial<DimStyle>, styleId?: string): void {\n this.updateDimStyle(styleId ?? this.state.dimStyles[0].id, patch);\n }\n\n /** Replace the document's dimension styles (min 1; objects reference by\n * id). Diffed into granular per-style ops. */\n setDimStyles(styles: DimStyle[]): void {\n const parsed = styles.map((s) => DimStyleSchema.parse(s));\n assertUniqueIds(parsed, \"setDimStyles()\");\n this.applyForwardAll(diffDimStyleOps(this.state.dimStyles, parsed));\n }\n\n /** @deprecated Use updateTextStyle (default here: the first style). */\n setTextStyle(patch: Partial<TextStyle>, styleId?: string): void {\n this.updateTextStyle(styleId ?? this.state.textStyles[0].id, patch);\n }\n\n /** Replace the document's text styles (min 1; objects reference by id).\n * Diffed into granular per-style ops. */\n setTextStyles(styles: TextStyle[]): void {\n const parsed = styles.map((s) => TextStyleSchema.parse(s));\n assertUniqueIds(parsed, \"setTextStyles()\");\n this.applyForwardAll(diffTextStyleOps(this.state.textStyles, parsed));\n }\n\n // --- modules (blocks + commands) -------------------------------------------\n\n private assertModuleSources(\n defs: readonly unknown[],\n where: string,\n ): string[] {\n const sources = defs.map((d) => {\n if (typeof d !== \"string\")\n throw new Error(\n `${where}: modules are ES-module SOURCES (strings) — each exports its own id/name`,\n );\n return d;\n });\n if (new Set(sources).size !== sources.length)\n throw new Error(\n `${where}: duplicate module source — modules are content-addressed (two identical sources are indistinguishable); deduplicate before setting`,\n );\n return sources;\n }\n\n /**\n * Replace the block library (raw module sources — each exports its own\n * id/name/params; semantic validation happens at compile). Async: awaits\n * the lazy transpiler, so block evaluation (bboxOf, renders, exports) is\n * definitive as soon as this resolves — never silently placeholder.\n */\n async setBlockDefinitions(defs: unknown[]): Promise<void> {\n const sources = this.assertModuleSources(defs, \"setBlockDefinitions()\");\n if (sources.length > 0) await ensureScriptTranspiler();\n this.applyForwardAll(\n diffModuleOps(this.state.blockDefinitions, sources, \"blockDefinitions\"),\n );\n }\n\n /** Replace the document's command modules (same rules as blocks). */\n async setCommands(defs: unknown[]): Promise<void> {\n const sources = this.assertModuleSources(defs, \"setCommands()\");\n if (sources.length > 0) await ensureScriptTranspiler();\n this.applyForwardAll(\n diffModuleOps(this.state.commands, sources, \"commands\"),\n );\n }\n\n /** Compilable block definitions (broken modules are skipped). */\n listBlockDefinitions(): BlockMeta[] {\n return listBlockMeta(this.state.blockDefinitions).flatMap((r) =>\n r.ok ? [r.meta] : [],\n );\n }\n\n /** Compilable document commands (broken modules are skipped). */\n listUserCommands(): CommandMeta[] {\n return listCommandMeta(this.state.commands).flatMap((r) =>\n r.ok ? [r.meta] : [],\n );\n }\n\n async addBlockDefinitions(sources: readonly string[]): Promise<MergeReport> {\n await ensureScriptTranspiler();\n const report = mergeBlockModules(this.state.blockDefinitions, sources);\n this.applyForwardAll(\n diffModuleOps(\n this.state.blockDefinitions,\n report.merged,\n \"blockDefinitions\",\n ),\n );\n return report;\n }\n\n async addUserCommands(sources: readonly string[]): Promise<MergeReport> {\n await ensureScriptTranspiler();\n const report = mergeCommandModules(this.state.commands, sources);\n this.applyForwardAll(\n diffModuleOps(this.state.commands, report.merged, \"commands\"),\n );\n return report;\n }\n\n // --- marketplaces ----------------------------------------------------------\n\n /** The host's marketplace list + client; a bare drawing gets an in-memory\n * list holding the public collection. */\n protected get marketplaceHost(): MarketplaceHost {\n return (this.hooks.marketplaces ??= memoryMarketplaceHost());\n }\n\n /** Replace the host's marketplace configuration (SDK / server config). */\n setMarketplaceHost(host: MarketplaceHost): void {\n this.hooks.marketplaces = host;\n }\n\n listMarketplaces(): MarketplaceInfo[] {\n return this.marketplaceHost.list().map(marketplaceInfo);\n }\n\n async addMarketplaces(\n list: readonly MarketplaceConfig[],\n ): Promise<MarketplaceInfo[]> {\n const host = this.marketplaceHost;\n const parsed = list.map((m) => MarketplaceConfigSchema.parse(m));\n for (const m of parsed) {\n const catalog = await host.client.catalog(m, true);\n if (catalog.state !== \"ready\")\n throw new Error(`${marketplaceLabel(m)}: ${catalog.reason}`);\n }\n // New ones go on top (highest priority); a repeated key replaces in\n // place, e.g. to update a token.\n let next = [...host.list()];\n for (const m of parsed) {\n const key = marketplaceKey(m);\n const i = next.findIndex((x) => marketplaceKey(x) === key);\n if (i >= 0) next[i] = m;\n else next = [m, ...next];\n }\n host.set(normalizeMarketplaces(next));\n return this.listMarketplaces();\n }\n\n removeMarketplaces(names: readonly string[]): MarketplaceInfo[] {\n const host = this.marketplaceHost;\n const current = host.list();\n for (const name of names) {\n const hit = current.find((m) => matchesMarketplace(m, name));\n if (hit === undefined)\n throw new Error(\n `No marketplace \"${name}\" is configured (see listMarketplaces)`,\n );\n if (hit.kind === \"builtin\")\n throw new Error(\"The built-in public collection can't be removed\");\n }\n host.set(\n normalizeMarketplaces(\n current.filter((m) => !names.some((n) => matchesMarketplace(m, n))),\n ),\n );\n return this.listMarketplaces();\n }\n\n async searchMarketplaces(\n q: MarketplaceQuery = {},\n ): Promise<MarketplaceHit[]> {\n await ensureScriptTranspiler(); // install status reads module exports\n const host = this.marketplaceHost;\n return host.client.search(host.list(), q, this.state);\n }\n\n async installMarketplaceEntries(\n ids: readonly string[],\n marketplace?: string,\n ): Promise<MergeReport> {\n await ensureScriptTranspiler(); // vendored checks must be definitive\n const host = this.marketplaceHost;\n const plans: { kind: \"block\" | \"command\"; sources: string[] }[] = [];\n for (const id of ids) {\n const found = await host.client.find(host.list(), id, marketplace);\n if (found === null)\n throw new Error(\n `No marketplace entry \"${id}\"${\n marketplace === undefined ? \"\" : ` in ${marketplace}`\n } (see searchMarketplaces)`,\n );\n plans.push({\n kind: found.entry.kind,\n sources: await host.client.installSources(\n found.config,\n found.entry,\n this.state,\n ),\n });\n }\n // Everything fetched: merge as ONE undo step.\n return this.transaction(async () => {\n const report: MergeReport = {\n merged: [],\n added: [],\n replaced: [],\n skipped: 0,\n rejected: [],\n };\n for (const plan of plans) {\n const r =\n plan.kind === \"block\"\n ? await this.addBlockDefinitions(plan.sources)\n : await this.addUserCommands(plan.sources);\n if (r.rejected.length > 0) throw new Error(r.rejected[0].error);\n report.merged = r.merged;\n report.added.push(...r.added);\n report.replaced.push(...r.replaced);\n report.skipped += r.skipped;\n }\n return report;\n });\n }\n\n /** Remove a block module by its exported id (unknown id → error). */\n removeBlockDefinition(id: string): void {\n const source = this.state.blockDefinitions.find((s) =>\n listBlockMeta([s]).some((r) => r.ok && r.meta.id === id),\n );\n if (source === undefined) throw new Error(`Unknown block \"${id}\"`);\n this.applyForward({ type: \"remove-block-definition\", source });\n }\n\n /** Remove a command module by its exported id (unknown id → error). */\n removeUserCommand(id: string): void {\n const source = this.state.commands.find((s) =>\n listCommandMeta([s]).some((r) => r.ok && r.meta.id === id),\n );\n if (source === undefined) throw new Error(`Unknown command \"${id}\"`);\n this.applyForward({ type: \"remove-document-command\", source });\n }\n\n /**\n * Resolves when block scripts evaluate definitively (the transpiler is\n * loaded). Await this before sync reads/renders of a document that was\n * constructed with block definitions (file opens and the module setters\n * already wait).\n */\n async ready(): Promise<void> {\n if (this.state.blockDefinitions.length > 0) await ensureScriptTranspiler();\n }\n\n // --- layouts ---------------------------------------------------------------\n\n private modelExtents(): AABB {\n let bbox = emptyBounds();\n for (const o of this.state.objects) {\n const b = this.boundsOf(o);\n if (!isEmptyBounds(b)) bbox = unionBounds(bbox, b);\n }\n return bbox;\n }\n\n /** Fitted scale + center for a viewport frame (editor createLayout rules). */\n private fitViewport(rect: { w: number; h: number }): {\n scale: number;\n modelCenter: Vec2;\n } {\n const bbox = this.modelExtents();\n if (isEmptyBounds(bbox)) return { scale: 50, modelCenter: { x: 0, y: 0 } };\n const presets = [1, 2, 5, 10, 20, 50, 100, 200, 500, 1000];\n const needed = Math.max(\n (bbox.maxX - bbox.minX) / (rect.w * 0.9),\n (bbox.maxY - bbox.minY) / (rect.h * 0.9),\n );\n return {\n scale: presets.find((s) => s >= needed) ?? presets[presets.length - 1],\n modelCenter: {\n x: (bbox.minX + bbox.maxX) / 2,\n y: (bbox.minY + bbox.maxY) / 2,\n },\n };\n }\n\n protected makeLayout(name: string, opts: LayoutOptions = {}): PaperLayout {\n const { width, height } = resolveSheetSize(opts.sheet);\n\n const objects: unknown[] = [];\n if (opts.viewport !== false) {\n const vp = opts.viewport ?? {};\n const scale = vp.scale ?? opts.scale;\n const margin = 20;\n const rect = vp.rect ?? {\n x: margin,\n y: margin,\n w: width - margin * 2,\n h: height - margin * 2,\n };\n const fitted = this.fitViewport(rect);\n objects.push({\n id: crypto.randomUUID(),\n type: \"viewport\",\n layerId: this.state.currentLayerId,\n rect,\n modelCenter: vp.center ? toVec(vp.center) : fitted.modelCenter,\n scale: scale !== undefined ? parseScale(scale) : fitted.scale,\n locked: false,\n hiddenLayerIds: [],\n });\n }\n\n return PaperLayoutSchema.parse({\n id: crypto.randomUUID(),\n name,\n sheet: { width, height },\n printPalette: \"color\",\n objects,\n });\n }\n\n /**\n * Create a paper layout — by default A3 landscape with one viewport fitted\n * to the model extents. Returns the layout id.\n */\n addLayout(name: string, opts: LayoutOptions = {}): string {\n this.assertLayoutName(name, \"addLayout()\");\n const layout = this.makeLayout(name, opts);\n this.applyForward({ type: \"add-layout\", layout, index: opts.index });\n return layout.id;\n }\n\n /** Remove a layout by name or id. */\n removeLayout(nameOrId: string): void {\n this.applyForward({\n type: \"remove-layout\",\n id: this.resolveLayout(nameOrId).id,\n });\n }\n\n /** Reorder the layouts (names or ids, every layout exactly once). Layout\n * order is the sheet order of multi-page PDF export. */\n reorderLayouts(order: readonly string[]): void {\n this.applyForward({\n type: \"reorder-layouts\",\n ids: order.map((l) => this.resolveLayout(l).id),\n });\n }\n\n /** Patch a layout's name / sheet (preset or mm) / print palette. */\n updateLayout(nameOrId: string, patch: LayoutPatch): void {\n const layout = this.resolveLayout(nameOrId);\n if (patch.name !== undefined)\n this.assertLayoutName(patch.name, \"updateLayout()\", layout.id);\n const { sheet, ...rest } = patch;\n this.applyForward({\n type: \"update-layout-meta\",\n id: layout.id,\n ...rest,\n ...(sheet !== undefined\n ? { sheet: resolveSheetSize(sheet, sheetOrientation(layout.sheet)) }\n : {}),\n });\n }\n\n // --- object mutations ----------------------------------------------------\n\n private normalize(input: ObjectInput, index?: number): ModelObject {\n const { layer, layerId, id, ...rest } = input as ObjectInput & {\n layer?: string;\n layerId?: string;\n id?: string;\n };\n const context = `add(): objects[${index ?? 0}] (${String(input.type ?? \"?\")})`;\n assertKnownStyleOverrideKeys(input as Record<string, unknown>, context);\n const styleRef = this.styleRef(rest, context);\n try {\n const raw: Record<string, unknown> = {\n ...rest,\n ...styleRef,\n layerId: this.resolveLayerId(layer, layerId),\n id: id ?? crypto.randomUUID(),\n };\n // Agents and scripts may still send the pre-v21 dimension shape\n // (vector offset / textOverride): the migration's converter accepts\n // both shapes.\n return ModelObjectSchema.parse(\n raw.type === \"dimension\"\n ? dimensionRawToLabels(dimensionRawToOffset(raw))\n : raw,\n );\n } catch (e) {\n throw wrapZod(\n e,\n `add(): objects[${index ?? 0}] (${String(input.type ?? \"?\")})`,\n );\n }\n }\n\n /**\n * Add objects (points may be `[x, y]`; `layer` resolves by name) to model\n * space, or to a paper layout's sheet via `{ layout }`. Returns ids.\n */\n add(objects: readonly ObjectInput[], opts: AddOptions = {}): string[] {\n if (objects.length === 0) return [];\n const space: OpSpace =\n opts.layout !== undefined\n ? { layoutId: this.resolveLayout(opts.layout).id }\n : \"model\";\n const created = objects.map((o, i) => this.normalize(o, i));\n this.applyForward({ type: \"add-objects\", space, objects: created });\n return created.map((o) => o.id);\n }\n\n private patched(\n id: string,\n patch: Record<string, unknown>,\n ): { space: OpSpace; obj: ModelObject } {\n const { layer, layerId, ...rest } = patch as Record<string, unknown> & {\n layer?: string;\n layerId?: string;\n };\n const { obj: cur, space } = this.findObject(id);\n assertKnownStyleOverrideKeys(\n { type: cur.type, styleOverride: rest.styleOverride },\n `update(): \"${id}\" (${cur.type})`,\n );\n const resolvedLayerId =\n layer !== undefined || layerId !== undefined\n ? this.resolveLayerId(layer, layerId)\n : undefined;\n const styleRef =\n \"styleId\" in rest\n ? this.styleRef(\n { type: cur.type, styleId: rest.styleId },\n `update(): \"${id}\" (${cur.type})`,\n )\n : {};\n // New text without new spans drops the old ones: their offsets index\n // the previous string (docs/rich-text.md §4).\n const staleSpans =\n cur.type === \"text\" && \"content\" in rest && !(\"spans\" in rest)\n ? { spans: undefined }\n : {};\n try {\n return {\n space,\n obj: ModelObjectSchema.parse({\n ...cur,\n ...rest,\n ...staleSpans,\n ...styleRef,\n ...(resolvedLayerId ? { layerId: resolvedLayerId } : {}),\n id,\n }),\n };\n } catch (e) {\n throw wrapZod(e, `update(): \"${id}\" (${cur.type})`);\n }\n }\n\n /** Apply one patch to several ids. */\n update(ids: readonly string[], patch: Record<string, unknown>): void;\n /** Apply per-object patches (`{id, ...fields}`) in one undo step. */\n update(entries: readonly ({ id: string } & Record<string, unknown>)[]): void;\n update(\n idsOrEntries:\n readonly string[] | readonly ({ id: string } & Record<string, unknown>)[],\n patch?: Record<string, unknown>,\n ): void {\n if (idsOrEntries.length === 0) return;\n const next =\n typeof idsOrEntries[0] === \"string\"\n ? (idsOrEntries as readonly string[]).map((id) =>\n this.patched(id, patch ?? {}),\n )\n : (\n idsOrEntries as readonly ({ id: string } & Record<\n string,\n unknown\n >)[]\n ).map(({ id, ...fields }) => this.patched(id, fields));\n this.applyBySpace(next, (space, objects) => ({\n type: \"update-objects\",\n space,\n objects,\n }));\n }\n\n /** Delete objects by id (unknown ids are skipped); returns how many went. */\n remove(ids: readonly string[]): number {\n const entries: { space: OpSpace; item: string }[] = [];\n for (const id of ids) {\n try {\n entries.push({ space: this.findObject(id).space, item: id });\n } catch {\n continue;\n }\n }\n const groups = this.groupBySpace(entries);\n if (groups.length === 0) return 0;\n this.transaction(() => {\n for (const g of groups)\n this.applyForward({\n type: \"remove-objects\",\n space: g.space,\n ids: g.items,\n });\n });\n return entries.length;\n }\n\n /** Draw order: move the given objects (bottom → top) to a placement. */\n reorder(ids: readonly string[], placement: ReorderPlacement): void {\n const entries = ids.map((id) => ({\n space: this.findObject(id).space,\n item: id,\n }));\n const groups = this.groupBySpace(entries);\n if (groups.length === 0) return;\n this.transaction(() => {\n for (const g of groups)\n this.applyForward({\n type: \"reorder-objects\",\n space: g.space,\n ids: g.items,\n placement,\n });\n });\n }\n\n // --- transforms ------------------------------------------------------------\n\n private transformEach(\n ids: readonly string[],\n fn: (o: ModelObject) => ModelObject,\n ): void {\n if (ids.length === 0) return;\n const next = ids.map((id) => {\n const { obj, space } = this.findObject(id);\n return { space, obj: ModelObjectSchema.parse(fn(obj)) };\n });\n this.applyBySpace(next, (space, objects) => ({\n type: \"update-objects\",\n space,\n objects,\n }));\n }\n\n /** Selection bbox center — the default pivot for rotate/scale. */\n private pivotOf(ids: readonly string[], center?: PointInput): Vec2 {\n if (center) return toVec(center);\n const bbox = this.bboxOf(ids);\n if (!bbox)\n throw new Error(\"No default pivot (empty bounds) — pass a center\");\n return { x: (bbox.minX + bbox.maxX) / 2, y: (bbox.minY + bbox.maxY) / 2 };\n }\n\n /** Translate objects by a world-mm delta. */\n move(ids: readonly string[], delta: PointInput): void {\n const d = toVec(delta);\n this.transformEach(ids, (o) => translateObject(o, d));\n }\n\n /** Rotate objects by `angle` radians CCW about `center` (default: selection bbox center). */\n rotate(ids: readonly string[], angle: number, center?: PointInput): void {\n const c = this.pivotOf(ids, center);\n this.transformEach(ids, (o) => rotateObject(o, c, angle));\n }\n\n /** Uniformly scale objects about `center` (default: selection bbox center). */\n scale(ids: readonly string[], factor: number, center?: PointInput): void {\n if (!Number.isFinite(factor) || factor <= 0)\n throw new Error(`Invalid scale factor ${factor}`);\n const c = this.pivotOf(ids, center);\n this.transformEach(ids, (o) =>\n translateObject(\n scaleObjectUniform(translateObject(o, { x: -c.x, y: -c.y }), factor),\n c,\n ),\n );\n }\n\n /** Mirror objects across the line a → b. */\n mirror(ids: readonly string[], a: PointInput, b: PointInput): void {\n const pa = toVec(a);\n const pb = toVec(b);\n this.transformEach(ids, (o) => mirrorObject(o, pa, pb));\n }\n\n /** Duplicate objects (into their own space) displaced by `delta`. */\n copy(ids: readonly string[], delta: PointInput): string[] {\n if (ids.length === 0) return [];\n const d = toVec(delta);\n // Fresh ids first, so block object-reference inputs pointing INSIDE the\n // copied set can follow to the clones (outside refs keep the originals).\n const idMap = new Map(ids.map((id) => [id, crypto.randomUUID()]));\n const clones = ids.map((id) => {\n const { obj, space } = this.findObject(id);\n return {\n space,\n obj: ModelObjectSchema.parse({\n ...remapBlockInputRefs(translateObject(obj, d), idMap),\n id: idMap.get(id),\n }),\n };\n });\n this.applyBySpace(clones, (space, objects) => ({\n type: \"add-objects\",\n space,\n objects,\n }));\n return clones.map((c) => c.obj.id);\n }\n\n /**\n * Linear array: `count` TOTAL instances (including the originals) stepped\n * by `delta`. Returns the new ids, one batch per step, in one undo step.\n */\n array(ids: readonly string[], count: number, delta: PointInput): string[] {\n if (!Number.isInteger(count) || count < 1)\n throw new Error(`Invalid array count ${count}`);\n const d = toVec(delta);\n return this.transaction(() => {\n const created: string[] = [];\n for (let i = 1; i < count; i++)\n created.push(...this.copy(ids, { x: d.x * i, y: d.y * i }));\n return created;\n });\n }\n\n // --- reads ---------------------------------------------------------------\n\n private get measurer(): TextMeasurer {\n return this.hooks.measure ?? approximateTextMeasurer;\n }\n\n private resolveObject(): (id: string) => ModelObject | undefined {\n return this.hooks.resolveObject ?? documentObjectResolver(this.state);\n }\n\n private ctx(): SnapGeometryContext {\n return {\n dimStyles: this.state.dimStyles,\n textStyles: this.state.textStyles,\n blockDefinitions: this.state.blockDefinitions,\n resolveObject: this.resolveObject(),\n resolveReference: this.resolveReference,\n measure: this.measurer,\n };\n }\n\n private entryOf(obj: ModelObject): SnapCacheEntry {\n return this.hooks.snapEntry\n ? this.hooks.snapEntry(obj)\n : buildSnapEntry(obj, this.ctx());\n }\n\n private boundsOf(obj: ModelObject): AABB {\n return this.entryOf(obj).bounds;\n }\n\n /** Union bounds of the given objects; null when nothing has bounds. */\n bboxOf(ids: readonly string[]): AABB | null {\n let bbox = emptyBounds();\n for (const id of ids) {\n const b = this.boundsOf(this.findObject(id).obj);\n if (!isEmptyBounds(b)) bbox = unionBounds(bbox, b);\n }\n return isEmptyBounds(bbox) ? null : bbox;\n }\n\n /**\n * Curve length in mm (bulge-exact for polylines); null for object types\n * without a natural length (text, dimensions, hatches, blocks, partial\n * ellipses).\n */\n length(id: string): number | null {\n const o = this.findObject(id).obj;\n switch (o.type) {\n case \"line\":\n return dist(o.a, o.b);\n case \"circle\":\n return 2 * Math.PI * o.radius;\n case \"arc\":\n return o.radius * arcSweep(o);\n case \"polyline\":\n return chainLength(o.points, o.closed);\n default:\n return null;\n }\n }\n\n /**\n * Enclosed area in mm² (bulge arcs tessellated): circles, closed\n * polylines, and hatches (outer loop minus holes); null otherwise.\n */\n area(id: string): number | null {\n const o = this.findObject(id).obj;\n switch (o.type) {\n case \"circle\":\n return Math.PI * o.radius * o.radius;\n case \"polyline\":\n return o.closed ? polylineArea(o.points) : null;\n case \"hatch\":\n return hatchArea(o.loops);\n default:\n return null;\n }\n }\n\n measure(id: string): Measurement {\n return {\n bbox: this.bboxOf([id]),\n length: this.length(id),\n area: this.area(id),\n };\n }\n\n /** Min distance from a point to the object's geometry (bounds fallback). */\n private distanceTo(obj: ModelObject, p: Vec2): number {\n const entry = this.entryOf(obj);\n let best = Infinity;\n for (const s of entry.segments)\n best = Math.min(best, dist(p, closestPointOnSegment(p, s.a, s.b)));\n for (const a of entry.arcs) best = Math.min(best, distToArc(a, p));\n if (best !== Infinity) return best;\n const b = entry.bounds;\n if (isEmptyBounds(b)) return Infinity;\n const cx = Math.max(b.minX, Math.min(p.x, b.maxX));\n const cy = Math.max(b.minY, Math.min(p.y, b.maxY));\n return Math.hypot(p.x - cx, p.y - cy);\n }\n\n /** Query model-space objects — or one paper layout's sheet objects\n * (viewports, annotations) via `filter.layout`. */\n listObjects(filter: QueryFilter = {}): ModelObject[] {\n const layerId =\n filter.layer !== undefined\n ? this.resolveLayerId(filter.layer)\n : undefined;\n const nearP = filter.near ? toVec(filter.near.point) : null;\n const wanted = filter.ids ? new Set(filter.ids) : null;\n const pool =\n filter.layout !== undefined\n ? structuredClone(this.resolveLayout(filter.layout).objects)\n : this.objects;\n return pool.filter((o) => {\n if (wanted && !wanted.has(o.id)) return false;\n if (filter.type && o.type !== filter.type) return false;\n if (layerId && o.layerId !== layerId) return false;\n if (filter.color !== undefined && o.color !== filter.color) return false;\n if (filter.lineType !== undefined && o.lineType !== filter.lineType)\n return false;\n if (\n filter.content !== undefined &&\n !(o.type === \"text\" && o.content.includes(filter.content))\n )\n return false;\n if (filter.bbox) {\n const b = this.boundsOf(o);\n if (isEmptyBounds(b) || !boundsIntersect(b, filter.bbox)) return false;\n }\n if (filter.inside) {\n const b = this.boundsOf(o);\n const box = filter.inside;\n if (\n isEmptyBounds(b) ||\n b.minX < box.minX ||\n b.maxX > box.maxX ||\n b.minY < box.minY ||\n b.maxY > box.maxY\n )\n return false;\n }\n if (nearP && filter.near && this.distanceTo(o, nearP) > filter.near.tol)\n return false;\n return true;\n });\n }\n\n summary(): DocumentSummary {\n const doc = this.state;\n const layerName = new Map(doc.layers.map((l) => [l.id, l.name]));\n const byType: Record<string, number> = {};\n const byLayer: Record<string, number> = {};\n let bbox = emptyBounds();\n for (const o of doc.objects) {\n byType[o.type] = (byType[o.type] ?? 0) + 1;\n const ln = layerName.get(o.layerId) ?? o.layerId;\n byLayer[ln] = (byLayer[ln] ?? 0) + 1;\n const b = this.boundsOf(o);\n if (!isEmptyBounds(b)) bbox = unionBounds(bbox, b);\n }\n return {\n name: this.name,\n objectCount: doc.objects.length,\n byType,\n byLayer,\n bbox: isEmptyBounds(bbox) ? null : bbox,\n layers: doc.layers.map((l) => l.name),\n settings: doc.settings,\n layouts: doc.layouts.map((l) => ({\n name: l.name,\n objectCount: l.objects.length,\n })),\n };\n }\n\n // --- render / export (browser-safe) ----------------------------------------\n\n protected paintContext() {\n const doc = this.state;\n return {\n objects: doc.objects,\n ...documentPaintResources(doc),\n resolveObject: this.resolveObject(),\n resolveReference: this.resolveReference,\n };\n }\n\n protected resolveLayout(nameOrId: string): PaperLayout {\n const layout = this.state.layouts.find(\n (l) => l.name === nameOrId || l.id === nameOrId,\n );\n if (!layout) throw new Error(`Unknown layout \"${nameOrId}\"`);\n return layout;\n }\n\n /** Render model space (or a paper layout via `layout`) to an SVG string. */\n renderSvg(opts: RenderSvgOptions = {}): string {\n if (opts.layout !== undefined)\n return renderLayoutToSvg(\n this.resolveLayout(opts.layout),\n this.paintContext(),\n opts,\n );\n return renderModelToSvg(this.paintContext(), opts);\n }\n\n /** Export the document to a DXF string. */\n async toDxf(): Promise<string> {\n const { buildDxf } = await import(\"../export/dxf/exportDxf\");\n return buildDxf(this.state, this.measurer).content;\n }\n\n /** Export the document to DWG bytes (the DXF content, wasm-transcoded).\n * Defaults to AC1027 (AutoCAD 2013) — readable by every current CAD tool.\n * Dimensions transcode as real DIMENSION objects; leaders are exploded to\n * plain geometry (acadrust's MULTILEADER DWG output is unproven in real\n * CADs — exploded geometry always displays). */\n async toDwg(opts?: { version?: DwgVersion }): Promise<Uint8Array> {\n const { buildDxf } = await import(\"../export/dxf/exportDxf\");\n const dxf = buildDxf(this.state, this.measurer, {\n explodeLeaders: true,\n }).content;\n return dxfToDwg(dxf, opts?.version ?? \"AC1027\");\n }\n\n toLinea(): string {\n return documentToJson(this.state);\n }\n}\n","// Run one command module (`export default defineCommand({...})`) against a\n// Drawing — the ONE runner behind the editor palette, the SDK's\n// `runScript`/`runCommand`, and the `linea_run_script` tool. Declared\n// `inputs` are acquired first (picked through the EditorSurface when there\n// is one, otherwise they must be supplied), then the whole `run` executes\n// inside ONE `document.transaction`: mutations apply live (later picks can\n// snap to earlier edits) and a throw — the user pressing Escape in a pick,\n// or any error — rolls everything back. Scripts run unsandboxed in-process\n// (`new Function`, same as blocks); the host's trust toggle is the boundary.\n\nimport { Vec2Schema } from \"../model/common\";\nimport type { Vec2 } from \"../geometry/vec2\";\nimport {\n getCommandMetaResult,\n getCommandRun,\n type CommandMeta,\n} from \"../extensions/commandModules\";\nimport { ensureScriptTranspiler } from \"../extensions/scriptRuntime\";\nimport {\n HEX_COLOR,\n valueParams,\n type ValueParameter,\n} from \"../model/blockDefinition\";\nimport type { Drawing, EditorSurface, PointInput } from \"./types\";\n\nexport interface RunCommandOptions {\n document: Drawing;\n /** The interactive surface; absent for headless runs. */\n editor?: EditorSurface;\n /** Values for the command's declared `inputs` (label order). Missing\n * ones are picked in the editor, or the run fails without one. */\n inputs?: readonly PointInput[];\n /** Values for the command's declared `params` by name; omitted ones take\n * their defaults. Unknown names or wrong types are an error. */\n params?: Readonly<Record<string, unknown>>;\n}\n\nconst needsEditor = (what: string) => (): never => {\n throw new Error(`${what} needs an editor (this command runs headlessly)`);\n};\n\n/** The `ctx` handed to `run` — mirrors CommandContext in lineadraw.d.ts. */\nconst makeContext = (\n opts: RunCommandOptions,\n inputs: readonly Vec2[],\n params: Record<string, unknown>,\n): Record<string, unknown> => {\n const { document, editor } = opts;\n return {\n document,\n editor,\n inputs,\n params,\n // Deprecated shorthands (pre-`editor` wire form) — one release.\n pickPoint: editor\n ? (label?: string) => editor.pickPoint({ label })\n : needsEditor(\"pickPoint\"),\n pickObject: editor\n ? (label?: string) => editor.pickObject({ label })\n : needsEditor(\"pickObject\"),\n selection: editor\n ? () => editor.state().selectedIds\n : needsEditor(\"selection\"),\n setSelection: editor\n ? (ids: readonly string[]) => editor.setSelection(ids)\n : needsEditor(\"setSelection\"),\n prompt: editor\n ? (message: string, o?: { initial?: string; placeholder?: string }) =>\n editor.prompt(message, o)\n : needsEditor(\"prompt\"),\n showToast: editor\n ? (message: string, kind?: \"info\" | \"success\" | \"error\") =>\n editor.toast(message, kind)\n : () => {},\n };\n};\n\n/** Why `value` doesn't fit `def`, or null when it does. */\nconst paramMismatch = (def: ValueParameter, value: unknown): string | null => {\n switch (def.type) {\n case \"number\":\n if (typeof value !== \"number\" || !Number.isFinite(value))\n return \"expected a number\";\n if (def.integer && !Number.isInteger(value))\n return \"expected a whole number\";\n if (def.min !== undefined && value < def.min)\n return `below the minimum ${def.min}`;\n if (def.max !== undefined && value > def.max)\n return `above the maximum ${def.max}`;\n return null;\n case \"string\":\n case \"textStyle\":\n case \"dimStyle\":\n case \"font\":\n case \"lineType\":\n case \"hatchPattern\":\n // Resource ids / names: an unknown one falls back where it's used\n // (first style, default font…), like a stored object's would.\n return typeof value === \"string\" ? null : \"expected a string\";\n case \"boolean\":\n return typeof value === \"boolean\" ? null : \"expected true or false\";\n case \"numberList\": {\n if (\n !Array.isArray(value) ||\n !value.every((v) => typeof v === \"number\" && Number.isFinite(v))\n )\n return \"expected an array of numbers\";\n const low = value.find((v) => def.min !== undefined && v < def.min);\n if (low !== undefined) return `${low} is below the minimum ${def.min}`;\n const high = value.find((v) => def.max !== undefined && v > def.max);\n if (high !== undefined) return `${high} is above the maximum ${def.max}`;\n return null;\n }\n case \"color\":\n return typeof value === \"string\" && HEX_COLOR.test(value)\n ? null\n : 'expected a \"#rrggbb\" color';\n case \"stringList\":\n return Array.isArray(value) && value.every((v) => typeof v === \"string\")\n ? null\n : \"expected an array of strings\";\n case \"enum\":\n return def.options.some((o) => o.value === value)\n ? null\n : `expected one of ${def.options.map((o) => JSON.stringify(o.value)).join(\", \")}`;\n default:\n return \"a label carries no value\";\n }\n};\n\n/**\n * The `params` record `run` receives: each declared parameter's default,\n * overridden by `given` — which is checked strictly (an unknown name or a\n * value of the wrong type throws, naming the command and parameter), so a\n * headless or agent caller can't silently run with a typo.\n */\nexport const resolveCommandParams = (\n meta: CommandMeta,\n given: Readonly<Record<string, unknown>> = {},\n): Record<string, unknown> => {\n const defs = valueParams(meta.params ?? []);\n // Null prototype: a param named `constructor` stays a plain property.\n const params: Record<string, unknown> = Object.create(null);\n for (const def of defs) params[def.name] = def.default;\n for (const [name, value] of Object.entries(given)) {\n const def = defs.find((d) => d.name === name);\n if (!def)\n throw new Error(\n `${meta.name}: unknown parameter \"${name}\"${\n defs.length ? ` (declares ${defs.map((d) => d.name).join(\", \")})` : \"\"\n }`,\n );\n const mismatch = paramMismatch(def, value);\n if (mismatch)\n throw new Error(`${meta.name}: parameter \"${name}\" — ${mismatch}`);\n params[name] = value;\n }\n return params;\n};\n\n/**\n * Resolve a command's declared inputs: supplied values first (validated as\n * points), then editor picks for the rest (rubber-band from the previous\n * point). Without an editor, missing inputs are an error naming them.\n */\nexport const acquireCommandInputs = async (\n meta: CommandMeta,\n opts: RunCommandOptions,\n): Promise<Vec2[]> => {\n const labels = meta.inputs ?? [];\n const given = (opts.inputs ?? []).map((p, i) => {\n try {\n return Vec2Schema.parse(p);\n } catch {\n throw new Error(\n `${meta.name}: inputs[${i}] (${labels[i] ?? \"extra\"}) is not a point`,\n );\n }\n });\n if (given.length > labels.length)\n throw new Error(\n `${meta.name}: ${given.length} inputs supplied, declares ${labels.length}`,\n );\n const missing = labels.slice(given.length);\n if (missing.length === 0) return given;\n if (!opts.editor)\n throw new Error(\n `${meta.name} needs an editor for: ${missing.join(\", \")} — supply inputs`,\n );\n const points = [...given];\n for (const label of missing) {\n const referencePoint = points[points.length - 1];\n points.push(await opts.editor.pickPoint({ label, referencePoint }));\n }\n return points;\n};\n\n/**\n * Compile + run a command module source against a Drawing as ONE undo step.\n * Resolves with the script's return value; rejects with the script's error\n * (or the pick cancellation) after the transaction rolled back. Compile\n * errors reject before anything runs.\n */\nexport const runCommandModule = async (\n source: string,\n opts: RunCommandOptions,\n): Promise<unknown> => {\n await ensureScriptTranspiler();\n const result = getCommandMetaResult(source);\n if (!result.ok) throw new Error(`Command failed to compile: ${result.error}`);\n const run = getCommandRun(source);\n // Params before inputs: a bad value fails before the user picks anything.\n const params = resolveCommandParams(result.meta, opts.params);\n const inputs = await acquireCommandInputs(result.meta, opts);\n return opts.document.transaction(\n () => run(makeContext(opts, inputs, params)),\n result.meta.name,\n );\n};\n\n/** Run a DOCUMENT command (a module in `document.commands`) by exported id. */\nexport const runDocumentCommand = async (\n id: string,\n opts: RunCommandOptions,\n): Promise<unknown> => {\n await ensureScriptTranspiler();\n const source = opts.document.document.commands.find((s) => {\n const r = getCommandMetaResult(s);\n return r.ok && r.meta.id === id;\n });\n if (source === undefined) throw new Error(`Unknown document command \"${id}\"`);\n return runCommandModule(source, opts);\n};\n","// PNG rendering = SVG (renderSvg) rasterized with resvg. The rasterizer is a\n// NATIVE Node addon, so it is imported LAZILY: a static import would poison\n// the editor's browser bundle (which also consumes @lineadraw/core). This module\n// is therefore Node-only — call it from the SDK/CLI/server, never the editor.\n\nimport {\n renderLayoutToSvg,\n renderModelToSvg,\n type SvgRenderOptions,\n} from \"../svg/renderSvg\";\nimport type { LayoutModelContext } from \"../../paint/layoutPaint\";\nimport type { PaperLayout } from \"../../model/paperLayout\";\n\nexport interface PngRenderOptions extends SvgRenderOptions {\n /** Output width in px (height follows the aspect ratio). Default 1024. */\n width?: number;\n /** Background fill (SVG has none). Default matches the dark canvas so\n * as-authored colors stay visible; pass \"#ffffff\" / \"transparent\" to change. */\n background?: string;\n}\n\nconst rasterize = async (\n svg: string,\n width: number,\n background: string,\n): Promise<Uint8Array> => {\n // Lazy: keeps the native addon out of any browser bundle of @lineadraw/core.\n const { Resvg } = await import(\"@resvg/resvg-js\");\n const { embeddedFontFiles } = await import(\"../../fonts/embedded\");\n const resvg = new Resvg(svg, {\n fitTo: { mode: \"width\", value: Math.max(1, Math.round(width)) },\n background,\n // Bundled fonts (osifont & co. are not system fonts); system fonts stay\n // loaded so the Arial default still resolves.\n font: { fontFiles: embeddedFontFiles(), loadSystemFonts: true },\n });\n return resvg.render().asPng();\n};\n\n/** Render model space to a PNG (Node only). */\nexport const renderModelToPng = async (\n model: LayoutModelContext,\n opts: PngRenderOptions = {},\n): Promise<Uint8Array> =>\n rasterize(\n renderModelToSvg(model, opts),\n opts.width ?? 1024,\n opts.background ?? \"#1e1e1e\",\n );\n\n/** Render a paper layout to a PNG (Node only); white sheet background. */\nexport const renderLayoutToPng = async (\n layout: PaperLayout,\n model: LayoutModelContext,\n opts: PngRenderOptions = {},\n): Promise<Uint8Array> =>\n rasterize(\n renderLayoutToSvg(layout, model, opts),\n opts.width ?? 1024,\n opts.background ?? \"#ffffff\",\n );\n"],"mappings":"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","names":["angle","n","n","n","z","z","scale","pt","scale","rot","left","add","n","near","segments","add","n","scale","n","mid","w","dist","total","len","n","num","n","inheritLayerIds","n","num","len","textHeight","n","scale","mid","len","_","unit","rot","angle","n","len","rot","c","n","z","z","z","z","def","unit","add","scale","n","z","z","n","z","z","layerId","objectIds","n","scale","angle","embeddedFontFiles"]}
|
|
1
|
+
{"version":3,"sources":["../src/document.ts","../../core/src/geometry/arcs.ts","../../core/src/geometry/ellipse.ts","../../core/src/geometry/bounds.ts","../../core/src/geometry/polyline.ts","../../core/src/model/document.ts","../../core/src/model/paperLayout.ts","../../core/src/model/scale.ts","../../core/src/model/defaults.ts","../../core/src/serialize.ts","../../core/src/export/svg/svgSink.ts","../../core/src/paint/painters/line.ts","../../core/src/paint/painters/point.ts","../../core/src/paint/painters/polyline.ts","../../core/src/paint/painters/circle.ts","../../core/src/paint/painters/arc.ts","../../core/src/paint/painters/ellipse.ts","../../core/src/paint/painters/hatch.ts","../../core/src/paint/painters/arrows.ts","../../core/src/paint/painters/text.ts","../../core/src/paint/painters/dimension.ts","../../core/src/paint/lineTypes.ts","../../core/src/paint/painters/block.ts","../../core/src/paint/painters/viewport.ts","../../core/src/paint/painters/table.ts","../../core/src/snap/nearIndex.ts","../../core/src/snap/buildEntry.ts","../../core/src/import/dxf/importDxf.ts","../../core/src/import/dxf/styleTables.ts","../../core/src/geometry/nurbs.ts","../../core/src/geometry/band.ts","../../core/src/import/dxf/blockDefinitions.ts","../../core/src/import/dxf/dxfLines.ts","../../core/src/import/dxf/entityLedger.ts","../../core/src/import/dxf/extraEntities.ts","../../core/src/import/dxf/objectsSection.ts","../../core/src/reference/reference.ts","../../core/src/paint/style.ts","../../core/src/paint/rebaseSink.ts","../../core/src/paint/painters/reference.ts","../../core/src/paint/painters/index.ts","../../core/src/extensions/blockThumbnail.ts","../../core/src/extensions/scriptModules.ts","../../core/src/marketplace/catalog.ts","../../core/src/extensions/commandModules.ts","../../core/src/marketplace/github.ts","../../core/src/paint/fontCoverage.ts","../../core/src/paint/layoutPaint.ts","../../core/src/paint/printPalette.ts","../../core/src/operations/diff.ts","../../core/src/import/dxf/importPlan.ts","../../core/src/dwg.ts","../../core/src/export/pdf/exportPdf.ts","../../core/src/export/pdf/pdfSink.ts","../../core/src/export/svg/renderSvg.ts","../../core/src/import/pdf/convertPage.ts","../../core/src/import/pdf/importPdf.ts","../../core/src/operations/types.ts","../../core/src/operations/apply.ts","../../core/src/operations/kernel.ts","../../core/src/drawing/localDrawing.ts","../../core/src/drawing/runCommand.ts","../../core/src/export/png/renderPng.ts"],"sourcesContent":["// The scripting-first document handle: core's browser-safe `LocalDrawing`\n// (the `Drawing` interface over one DocumentKernel — docs/interaction-\n// surface.md) plus the Node-only pieces: file open/save, PNG rasterization,\n// PDF export with the embedded fonts, and path-taking import/export helpers.\n// Ergonomics only — never new semantics. See docs/agent-sdk-mcp.md.\n\nimport { readFile, writeFile } from \"node:fs/promises\";\nimport { dirname, isAbsolute, resolve } from \"node:path\";\nimport {\n approximateTextMeasurer,\n contentFromDocument,\n documentFromDxf,\n contentFromRaster,\n dataUrlBytes,\n documentFromJson,\n dwgToDxf,\n emptyDocument,\n imagePixelSize,\n PX_TO_MM,\n measureContentBounds,\n pdfToModel,\n documentWithObjects,\n type LineaDocument as CoreDocument,\n type Reference,\n type ReferenceContent,\n type ReferenceSource,\n rebaseReferenceSource,\n LocalDrawing,\n memoryMarketplaceHost,\n normalizeMarketplaces,\n type MarketplaceConfig,\n renderLayoutsToPdf,\n selectPdfLayouts,\n runCommandModule,\n runDocumentCommand,\n usedEmbedFontIds,\n type DxfImportOptions,\n type DxfImportReport,\n type LineaDocument,\n type PdfImportOptions,\n type PdfImportReport,\n type PointInput,\n type RenderPdfOptions,\n type RenderPngOptions,\n} from \"@lineadraw/core\";\nimport {\n embeddedPdfFonts,\n renderLayoutToPng,\n renderModelToPng,\n} from \"@lineadraw/core/node\";\nimport type { DwgVersion } from \"@lineadraw/core\";\n\nexport type {\n AddOptions,\n DocumentSummary,\n DxfImportOptions,\n DxfImportReport,\n LayoutOptions,\n ModelObjectInput,\n PdfImportReport,\n PointInput,\n ObjectQuery,\n RenderPdfOptions as PdfOptions,\n RenderPngOptions as PngOptions,\n RenderSvgOptions as SvgOptions,\n SheetName,\n ViewportOptions,\n} from \"@lineadraw/core\";\nexport { parseScale } from \"@lineadraw/core\";\n\n/** A drawing's name from its file: the base name without the extension. */\nconst nameOfPath = (path: string): string =>\n (path.split(/[/\\\\]/).pop() ?? path).replace(/\\.(linea|lineadraw)$/i, \"\");\n\n/** A referenced file's bytes → a document, by format (Node: a raster PDF\n * reference draws as vectors — there is no canvas to rasterize with). */\nconst referenceDocument = async (\n ref: Reference,\n bytes: Uint8Array,\n): Promise<CoreDocument> => {\n switch (ref.format) {\n case \"linea\":\n return documentFromJson(new TextDecoder().decode(bytes));\n case \"dxf\":\n return documentFromDxf(new TextDecoder().decode(bytes));\n case \"dwg\":\n return documentFromDxf(await dwgToDxf(bytes));\n case \"pdf\": {\n const result = await pdfToModel(bytes, { page: ref.pdfPage ?? 1 });\n return documentWithObjects((d) => ({\n objects: result.objects.map((o) => ({ ...o, layerId: d.layers[0].id })),\n }));\n }\n case \"png\":\n case \"jpg\":\n throw new Error(\"pictures load as raster content\"); // referenceContent\n }\n};\n\n/** A file's bytes → reference content (a picture: its raster at 96 dpi). */\nconst referenceContent = async (\n ref: Reference,\n bytes: Uint8Array,\n): Promise<ReferenceContent> => {\n if (ref.format === \"png\" || ref.format === \"jpg\") {\n const size = imagePixelSize(bytes);\n if (!size) throw new Error(`${ref.name}: not a PNG/JPEG`);\n const mime = ref.format === \"png\" ? \"image/png\" : \"image/jpeg\";\n return contentFromRaster(\n ref.id,\n `data:${mime};base64,${Buffer.from(bytes).toString(\"base64\")}`,\n size.width * PX_TO_MM,\n size.height * PX_TO_MM,\n );\n }\n const content = contentFromDocument(\n await referenceDocument(ref, bytes),\n ref.id,\n );\n return {\n ...content,\n bounds: measureContentBounds(content, approximateTextMeasurer),\n };\n};\n\nexport class Drawing extends LocalDrawing {\n private path?: string;\n\n constructor(\n doc: LineaDocument,\n filePath?: string,\n migration: { from: number; to: number } | null = null,\n ) {\n super(doc, migration);\n this.path = filePath;\n if (filePath) this.name = nameOfPath(filePath);\n // Node can read local folder marketplaces; the list starts with the\n // public collection (configureMarketplaces / addMarketplaces extend it).\n this.setMarketplaceHost(\n memoryMarketplaceHost({\n readFile: (folder, rel) => readFile(resolve(folder, rel), \"utf8\"),\n }),\n );\n }\n\n /** The marketplaces this drawing searches and installs from, in priority\n * order (the public collection is always present, last by default) —\n * process configuration, nothing is written to the file. */\n configureMarketplaces(list: readonly MarketplaceConfig[]): void {\n const host = memoryMarketplaceHost({\n readFile: (folder, rel) => readFile(resolve(folder, rel), \"utf8\"),\n });\n host.set(normalizeMarketplaces(list));\n this.setMarketplaceHost(host);\n }\n\n /** The file this drawing was opened from / last saved to, if any. */\n get filePath(): string | undefined {\n return this.path;\n }\n\n /** Block scripts compiled AND referenced files loaded (relative paths\n * against this drawing's folder) — renders include their content. A file\n * that can't be read stays a frame. */\n override async ready(): Promise<void> {\n await super.ready();\n const refs = [\n ...this.objects,\n ...this.layouts.flatMap((l) => l.objects),\n ].filter((o): o is Reference => o.type === \"reference\");\n for (const ref of refs) {\n const content = await this.loadReference(\n ref,\n ref.source,\n this.state.assets,\n 0,\n new Set(),\n );\n if (content) this.referenceContent.set(ref.id, content);\n else this.referenceContent.delete(ref.id); // missing → frame\n }\n }\n\n /** One reference's content (null when unreadable); a .linea's own\n * references load relative to it — and its embedded ones from ITS assets —\n * depth-limited, never re-entering a file above in the chain (the\n * editor's rules). */\n private async loadReference(\n ref: Reference,\n source: ReferenceSource,\n /** The assets of the document holding `ref` (embedded sources). */\n assets: Readonly<Record<string, string>>,\n depth: number,\n seen: ReadonlySet<string>,\n ): Promise<ReferenceContent | null> {\n let content: ReferenceContent;\n try {\n content = await referenceContent(\n ref,\n await this.readSource(source, assets),\n );\n } catch {\n return null;\n }\n if (ref.format === \"linea\" && depth + 1 < 4) {\n const above = new Set(seen).add(JSON.stringify(source));\n const nested = new Map<string, ReferenceContent>();\n for (const child of content.objects) {\n if (child.type !== \"reference\") continue;\n const childSource = rebaseReferenceSource(child.source, source);\n if (above.has(JSON.stringify(childSource))) continue;\n const c = await this.loadReference(\n child,\n childSource,\n content.assets ?? {},\n depth + 1,\n above,\n );\n if (c) nested.set(child.id, c);\n }\n content.resolveReference = (r) => nested.get(r.id) ?? null;\n // Nested references weren't in the measured bounds (they resolve now).\n content.bounds = measureContentBounds(content, approximateTextMeasurer);\n }\n return content;\n }\n\n private async readSource(\n source: ReferenceSource,\n assets: Readonly<Record<string, string>>,\n ): Promise<Uint8Array> {\n if (source.kind === \"asset\") {\n const data = assets[source.assetId];\n if (data === undefined) throw new Error(\"embedded file missing\");\n return dataUrlBytes(data);\n }\n if (source.kind === \"url\") {\n const res = await fetch(source.url);\n if (!res.ok) throw new Error(`HTTP ${res.status}`);\n return new Uint8Array(await res.arrayBuffer());\n }\n const p = source.path;\n const abs =\n isAbsolute(p) || !this.path ? p : resolve(dirname(this.path), p);\n return new Uint8Array(await readFile(abs));\n }\n\n // --- render / export (Node) ------------------------------------------------\n\n /** Rasterize model space (or a paper layout via `layout`) to PNG bytes\n * (Node only — lazy native rasterizer). */\n async renderPng(opts: RenderPngOptions = {}): Promise<Uint8Array> {\n if (opts.layout !== undefined)\n return renderLayoutToPng(\n this.resolveLayout(opts.layout),\n this.paintContext(),\n opts,\n );\n return renderModelToPng(this.paintContext(), opts);\n }\n\n /** Multi-page PDF of the layouts (default: all) with the embedded fonts. */\n async renderPdf(opts: RenderPdfOptions = {}): Promise<Uint8Array> {\n const doc = this.state;\n const layouts = selectPdfLayouts(doc.layouts, opts, () =>\n this.makeLayout(\"Layout 1\"),\n );\n const pdf = renderLayoutsToPdf(\n layouts,\n this.paintContext(),\n embeddedPdfFonts(usedEmbedFontIds(doc)),\n );\n return new Uint8Array(pdf.output(\"arraybuffer\"));\n }\n\n async exportSvg(\n path: string,\n opts?: Parameters<LocalDrawing[\"renderSvg\"]>[0],\n ): Promise<void> {\n await writeFile(path, this.renderSvg(opts), \"utf8\");\n }\n async exportPng(path: string, opts?: RenderPngOptions): Promise<void> {\n await writeFile(path, await this.renderPng(opts));\n }\n async exportDxf(path: string): Promise<void> {\n await writeFile(path, await this.toDxf(), \"utf8\");\n }\n async exportDwg(\n path: string,\n opts?: { version?: DwgVersion },\n ): Promise<void> {\n await writeFile(path, await this.toDwg(opts));\n }\n async exportPdf(path: string, opts?: RenderPdfOptions): Promise<void> {\n await writeFile(path, await this.renderPdf(opts));\n }\n /** Write the `.linea` JSON; `path` defaults to (and updates) filePath. */\n async save(path?: string): Promise<string> {\n const target = path ?? this.path;\n if (!target)\n throw new Error(\n \"save() needs a path (document was not opened from a file)\",\n );\n this.path = target;\n this.name = nameOfPath(target); // the file name IS the name\n await writeFile(target, this.toLinea(), \"utf8\");\n return target;\n }\n\n // --- import from files (the in-memory imports are core's LocalDrawing) -----------------------------------------------------\n\n async importDxf(\n path: string,\n opts?: DxfImportOptions,\n ): Promise<DxfImportReport> {\n return this.importDxfText(await readFile(path, \"utf8\"), opts);\n }\n\n async importDwg(\n path: string,\n opts?: DxfImportOptions,\n ): Promise<DxfImportReport> {\n return this.importDwgData(await readFile(path), opts);\n }\n\n async importPdf(\n path: string,\n opts?: PdfImportOptions,\n ): Promise<PdfImportReport> {\n const data = await readFile(path);\n return this.importPdfData(\n data.buffer.slice(data.byteOffset, data.byteOffset + data.byteLength),\n opts,\n );\n }\n\n // --- scripts ---------------------------------------------------------------\n\n /** Run a command module source (`defineCommand`) against this drawing as\n * ONE undo step, headlessly: declared `inputs` must be supplied; declared\n * `params` take their defaults unless given by name (unknown names and\n * wrong types throw). Resolves with the script's return value. */\n runScript(\n source: string,\n inputs?: readonly PointInput[],\n params?: Readonly<Record<string, unknown>>,\n ): Promise<unknown> {\n return runCommandModule(source, { document: this, inputs, params });\n }\n\n /** Run one of the document's own commands (by exported id). */\n runUserCommand(\n id: string,\n inputs?: readonly PointInput[],\n params?: Readonly<Record<string, unknown>>,\n ): Promise<unknown> {\n return runDocumentCommand(id, { document: this, inputs, params });\n }\n}\n\n// --- entry points ----------------------------------------------------------\n\n/** A fresh empty document, optionally named (until saved to a file, whose\n * name then takes over). */\nexport interface DrawingOptions {\n /** Marketplaces to search and install from, in priority order (the\n * public collection is appended when missing). Default: the public\n * collection alone. */\n marketplaces?: readonly MarketplaceConfig[];\n}\n\nexport function newDrawing(\n name?: string,\n options: DrawingOptions = {},\n): Drawing {\n const drawing = new Drawing(emptyDocument());\n if (name !== undefined) drawing.name = name;\n if (options.marketplaces) drawing.configureMarketplaces(options.marketplaces);\n return drawing;\n}\n\n/** The pre-migration schema version of raw `.linea` JSON (best effort). */\nconst rawVersion = (text: string): number | null => {\n try {\n const v = (JSON.parse(text) as { version?: unknown }).version;\n return typeof v === \"number\" ? v : null;\n } catch {\n return null;\n }\n};\n\nconst withMigration = (text: string, filePath?: string): Drawing => {\n const from = rawVersion(text);\n const doc = documentFromJson(text);\n const migration =\n from !== null && from !== doc.version ? { from, to: doc.version } : null;\n return new Drawing(doc, filePath, migration);\n};\n\n/** Parse a `.linea` JSON string. */\nexport function drawingFromJson(text: string): Drawing {\n return withMigration(text);\n}\n\n/** Open a `.linea` file (parse + migrate) into an in-process kernel. */\nexport async function openDrawing(\n path: string,\n options: DrawingOptions = {},\n): Promise<Drawing> {\n const doc = withMigration(await readFile(path, \"utf8\"), path);\n if (options.marketplaces) doc.configureMarketplaces(options.marketplaces);\n await doc.ready(); // block scripts evaluate definitively from the start\n return doc;\n}\n","// Arc math, including DXF-style bulge conversion.\n// A bulge is tan(sweep/4): 0 = straight, positive = CCW arc from a to b.\n\nimport type { Vec2 } from \"./vec2\";\nimport {\n add,\n angle,\n cross,\n dist,\n dot,\n len,\n mid,\n norm,\n normAngle,\n perp,\n rot,\n scale,\n sub,\n} from \"./vec2\";\n\nexport interface ArcGeom {\n center: Vec2;\n radius: number;\n /** Start angle, radians CCW from +X. */\n startAngle: number;\n /** End angle. The arc always runs CCW from startAngle to endAngle. */\n endAngle: number;\n}\n\n/** CCW sweep of an arc in (0, 2π]. */\nexport const arcSweep = (a: ArcGeom): number => {\n const s = normAngle(a.endAngle - a.startAngle);\n return s === 0 ? Math.PI * 2 : s;\n};\n\nexport const pointOnArc = (a: ArcGeom, angle: number): Vec2 => ({\n x: a.center.x + Math.cos(angle) * a.radius,\n y: a.center.y + Math.sin(angle) * a.radius,\n});\n\nexport const arcStartPoint = (a: ArcGeom): Vec2 => pointOnArc(a, a.startAngle);\nexport const arcEndPoint = (a: ArcGeom): Vec2 => pointOnArc(a, a.endAngle);\nexport const arcMidPoint = (a: ArcGeom): Vec2 =>\n pointOnArc(a, a.startAngle + arcSweep(a) / 2);\n\n/** Is the angle within the CCW range [startAngle, endAngle]? */\nexport const angleInArc = (a: ArcGeom, angle: number): boolean =>\n normAngle(angle - a.startAngle) <= arcSweep(a) + 1e-12;\n\n/**\n * Convert a bulged polyline segment (a → b, bulge) to arc geometry.\n * Returns null for straight segments (bulge ≈ 0) or degenerate points.\n * Negative bulge = CW visual arc; we normalize so the ArcGeom is always CCW\n * by swapping start/end angles.\n */\nexport const bulgeToArc = (a: Vec2, b: Vec2, bulge: number): ArcGeom | null => {\n if (Math.abs(bulge) < 1e-12) return null;\n const chord = dist(a, b);\n if (chord < 1e-12) return null;\n const sweep = 4 * Math.atan(bulge); // signed, CCW positive\n const radius = Math.abs(chord / (2 * Math.sin(sweep / 2)));\n // Sagitta-based center: offset from chord midpoint along the perpendicular.\n const m = mid(a, b);\n const dir = scale(sub(b, a), 1 / chord);\n // Signed distance from chord midpoint to center, along the left normal of\n // a→b: positive bulge (CCW) puts the center on the left for a minor arc,\n // on the right for a major arc (tan flips sign past π); negative mirrors.\n const h = chord / 2 / Math.tan(sweep / 2);\n const center = add(m, scale(perp(dir), h));\n const angA = angle(sub(a, center));\n const angB = angle(sub(b, center));\n return bulge > 0\n ? { center, radius, startAngle: angA, endAngle: angB }\n : { center, radius, startAngle: angB, endAngle: angA };\n};\n\n/** Bulge value for an arc from a to b through point m (all on the arc). */\nexport const bulgeFrom3Points = (a: Vec2, m: Vec2, b: Vec2): number => {\n // The heading change from chord a→m to chord m→b is half the arc's sweep\n // (inscribed angle), so bulge = tan(sweep/4) = tan(turn/2).\n let turn = angle(sub(b, m)) - angle(sub(m, a));\n while (turn > Math.PI) turn -= 2 * Math.PI;\n while (turn < -Math.PI) turn += 2 * Math.PI;\n return Math.tan(turn / 2);\n};\n\n/**\n * Unit tangent at the END of a bulged segment a → b, pointing in the direction\n * of travel (a → b). Straight segment (bulge ≈ 0) → norm(b - a); an arc's end\n * tangent leads the chord by half the sweep.\n */\nexport const bulgeEndTangent = (a: Vec2, b: Vec2, bulge: number): Vec2 =>\n rot(norm(sub(b, a)), 2 * Math.atan(bulge));\n\n/**\n * Bulge of the circular arc from `start` to `end` whose tangent at `start` is\n * `tangent` (need not be unit) — the tangent-continuous arc. Positive = CCW,\n * 0 when the tangent aligns with the chord (a straight segment). The signed\n * tangent-to-chord angle is half the sweep, so bulge = tan(angle / 2).\n */\nexport const bulgeFromTangent = (\n start: Vec2,\n tangent: Vec2,\n end: Vec2,\n): number => {\n const chord = sub(end, start);\n if (len(chord) < 1e-12 || len(tangent) < 1e-12) return 0;\n const half = Math.atan2(cross(tangent, chord), dot(tangent, chord));\n return Math.tan(half / 2);\n};\n\n/** Circle through 3 points; null when collinear. */\nexport const circleFrom3Points = (\n p1: Vec2,\n p2: Vec2,\n p3: Vec2,\n): { center: Vec2; radius: number } | null => {\n const ax = p1.x;\n const ay = p1.y;\n const bx = p2.x;\n const by = p2.y;\n const cx = p3.x;\n const cy = p3.y;\n const d = 2 * (ax * (by - cy) + bx * (cy - ay) + cx * (ay - by));\n if (Math.abs(d) < 1e-12) return null;\n const a2 = ax * ax + ay * ay;\n const b2 = bx * bx + by * by;\n const c2 = cx * cx + cy * cy;\n const center = {\n x: (a2 * (by - cy) + b2 * (cy - ay) + c2 * (ay - by)) / d,\n y: (a2 * (cx - bx) + b2 * (ax - cx) + c2 * (bx - ax)) / d,\n };\n return { center, radius: dist(center, p1) };\n};\n\n/**\n * Arc through 3 points: start, a point on the arc, end.\n * Returns CCW geometry from start to end passing through the middle point.\n */\nexport const arcFrom3Points = (\n start: Vec2,\n on: Vec2,\n end: Vec2,\n): ArcGeom | null => {\n const c = circleFrom3Points(start, on, end);\n if (!c) return null;\n const angS = angle(sub(start, c.center));\n const angO = angle(sub(on, c.center));\n const angE = angle(sub(end, c.center));\n // CCW from start: does \"on\" lie within the CCW range start→end?\n const ccw: ArcGeom = {\n center: c.center,\n radius: c.radius,\n startAngle: angS,\n endAngle: angE,\n };\n if (angleInArc(ccw, angO)) return ccw;\n return {\n center: c.center,\n radius: c.radius,\n startAngle: angE,\n endAngle: angS,\n };\n};\n\n/** Closest point on an arc to p (accounting for angular range; falls back to nearest endpoint). */\nexport const closestPointOnArc = (a: ArcGeom, p: Vec2): Vec2 => {\n const v = sub(p, a.center);\n const ang = angle(v);\n if (angleInArc(a, ang)) return pointOnArc(a, ang);\n const s = arcStartPoint(a);\n const e = arcEndPoint(a);\n return dist(p, s) <= dist(p, e) ? s : e;\n};\n\n/** Distance from p to the arc curve. */\nexport const distToArc = (a: ArcGeom, p: Vec2): number =>\n dist(p, closestPointOnArc(a, p));\n\n/** Tessellate an arc into points (including both endpoints), targeting a chord tolerance in mm. */\nexport const tessellateArc = (a: ArcGeom, chordTolerance = 0.1): Vec2[] => {\n const sweep = arcSweep(a);\n // chord error e = r(1 - cos(dθ/2)) → dθ = 2·acos(1 - e/r)\n const maxStep =\n a.radius <= chordTolerance\n ? sweep\n : 2 * Math.acos(Math.max(-1, 1 - chordTolerance / a.radius));\n const n = Math.max(2, Math.ceil(sweep / Math.max(maxStep, 1e-3)));\n const pts: Vec2[] = [];\n for (let i = 0; i <= n; i++) {\n pts.push(pointOnArc(a, a.startAngle + (sweep * i) / n));\n }\n return pts;\n};\n","// Ellipse math in DXF form: center + majorAxis endpoint vector + ratio\n// (minor/major). Points are parameterized by t: p(t) = c + M·cos t + m·sin t,\n// where m = perp(M)·ratio. startAngle/endAngle bound a CCW parametric range.\n\nimport type { Vec2 } from \"./vec2\";\nimport { add, distSq, len, normAngle, perp, scale } from \"./vec2\";\n\nexport interface EllipseGeom {\n center: Vec2;\n majorAxis: Vec2;\n /** minor/major in (0, 1]. */\n ratio: number;\n startAngle: number;\n endAngle: number;\n}\n\nexport const ellipseSweep = (e: EllipseGeom): number => {\n const s = normAngle(e.endAngle - e.startAngle);\n return s === 0 ? Math.PI * 2 : s;\n};\n\nexport const isFullEllipse = (e: EllipseGeom): boolean =>\n Math.abs(ellipseSweep(e) - Math.PI * 2) < 1e-9;\n\n/** Area of the full ellipse (π·rx·ry), independent of the angular range. */\nexport const ellipseArea = (e: EllipseGeom): number =>\n Math.PI * len(e.majorAxis) ** 2 * e.ratio;\n\nexport const pointOnEllipse = (e: EllipseGeom, t: number): Vec2 => {\n const minor = scale(perp(e.majorAxis), e.ratio);\n return add(\n add(e.center, scale(e.majorAxis, Math.cos(t))),\n scale(minor, Math.sin(t)),\n );\n};\n\nexport const paramInEllipse = (e: EllipseGeom, t: number): boolean =>\n normAngle(t - e.startAngle) <= ellipseSweep(e) + 1e-12;\n\n/** Max chord deviation (mm) of ellipse tessellations from the true curve. */\nconst ELLIPSE_CHORD_TOLERANCE = 0.1;\n\n/**\n * Tessellate into points (both endpoints included). Parametric steps sized so\n * chord error stays under ~tolerance for the major radius.\n */\nexport const tessellateEllipse = (\n e: EllipseGeom,\n tolerance = ELLIPSE_CHORD_TOLERANCE,\n): Vec2[] => {\n const major = len(e.majorAxis);\n const sweep = ellipseSweep(e);\n const maxStep =\n major <= tolerance\n ? sweep\n : 2 * Math.acos(Math.max(-1, 1 - tolerance / major));\n const n = Math.max(8, Math.ceil(sweep / Math.max(maxStep, 1e-3)));\n const pts: Vec2[] = [];\n for (let i = 0; i <= n; i++) {\n pts.push(pointOnEllipse(e, e.startAngle + (sweep * i) / n));\n }\n return pts;\n};\n\n/**\n * Closest point on the ellipse curve to p — coarse parametric scan refined by\n * golden-section iterations. Good to well under render tolerance; exact\n * root-finding isn't worth it for snapping/hit-testing.\n */\nexport const closestPointOnEllipse = (e: EllipseGeom, p: Vec2): Vec2 => {\n const sweep = ellipseSweep(e);\n const SCAN = 64;\n let bestT = e.startAngle;\n let bestD = Infinity;\n for (let i = 0; i <= SCAN; i++) {\n const t = e.startAngle + (sweep * i) / SCAN;\n const d = distSq(p, pointOnEllipse(e, t));\n if (d < bestD) {\n bestD = d;\n bestT = t;\n }\n }\n // Refine around bestT.\n let lo = bestT - sweep / SCAN;\n let hi = bestT + sweep / SCAN;\n for (let i = 0; i < 24; i++) {\n const m1 = lo + (hi - lo) * 0.382;\n const m2 = lo + (hi - lo) * 0.618;\n if (distSq(p, pointOnEllipse(e, m1)) < distSq(p, pointOnEllipse(e, m2)))\n hi = m2;\n else lo = m1;\n }\n const t = (lo + hi) / 2;\n const clamped = paramInEllipse(e, t) ? t : bestT;\n return pointOnEllipse(e, clamped);\n};\n","// Axis-aligned bounding boxes in world mm.\n\nimport type { Vec2 } from \"./vec2\";\n\nexport interface AABB {\n minX: number;\n minY: number;\n maxX: number;\n maxY: number;\n}\n\nexport const emptyBounds = (): AABB => ({\n minX: Infinity,\n minY: Infinity,\n maxX: -Infinity,\n maxY: -Infinity,\n});\n\nexport const boundsOfPoints = (pts: Vec2[]): AABB => {\n const b = emptyBounds();\n for (const p of pts) {\n if (p.x < b.minX) b.minX = p.x;\n if (p.y < b.minY) b.minY = p.y;\n if (p.x > b.maxX) b.maxX = p.x;\n if (p.y > b.maxY) b.maxY = p.y;\n }\n return b;\n};\n\nexport const unionBounds = (a: AABB, b: AABB): AABB => ({\n minX: Math.min(a.minX, b.minX),\n minY: Math.min(a.minY, b.minY),\n maxX: Math.max(a.maxX, b.maxX),\n maxY: Math.max(a.maxY, b.maxY),\n});\n\nexport const addPointToBounds = (b: AABB, p: Vec2): void => {\n if (p.x < b.minX) b.minX = p.x;\n if (p.y < b.minY) b.minY = p.y;\n if (p.x > b.maxX) b.maxX = p.x;\n if (p.y > b.maxY) b.maxY = p.y;\n};\n\nexport const boundsIntersect = (a: AABB, b: AABB): boolean =>\n a.minX <= b.maxX && a.maxX >= b.minX && a.minY <= b.maxY && a.maxY >= b.minY;\n\nexport const boundsContainBounds = (outer: AABB, inner: AABB): boolean =>\n inner.minX >= outer.minX &&\n inner.maxX <= outer.maxX &&\n inner.minY >= outer.minY &&\n inner.maxY <= outer.maxY;\n\nexport const isEmptyBounds = (b: AABB): boolean =>\n b.minX > b.maxX || b.minY > b.maxY;\n\nexport const boundsCenter = (b: AABB): Vec2 => ({\n x: (b.minX + b.maxX) / 2,\n y: (b.minY + b.maxY) / 2,\n});\n\n/** AABB spanned by two arbitrary corner points. */\nexport const boundsOfCorners = (a: Vec2, b: Vec2): AABB => ({\n minX: Math.min(a.x, b.x),\n minY: Math.min(a.y, b.y),\n maxX: Math.max(a.x, b.x),\n maxY: Math.max(a.y, b.y),\n});\n","// Shared derived geometry for bulged vertex chains (polylines, hatch loops).\n\nimport type { Vec2 } from \"./vec2\";\nimport { angle, dist, dot, normAngle, sub } from \"./vec2\";\nimport type { Segment } from \"./line\";\nimport type { ArcGeom } from \"./arcs\";\nimport {\n arcSweep,\n bulgeFrom3Points,\n bulgeToArc,\n pointOnArc,\n tessellateArc,\n} from \"./arcs\";\n\n/**\n * A vertex of a bulged chain; bulge = tan(sweep/4), 0 = straight (DXF\n * LWPOLYLINE convention). Structurally compatible with the model's\n * zod-derived PolylineVertex — geometry stays model-free.\n */\nexport interface PolylineVertex {\n x: number;\n y: number;\n bulge: number;\n}\n\nexport interface Curves {\n segments: Segment[];\n arcs: ArcGeom[];\n}\n\n/** Exact curves (straight segments + analytic arcs) of a vertex chain. */\nexport const verticesToCurves = (\n vertices: PolylineVertex[],\n closed: boolean,\n): Curves => {\n const segments: Segment[] = [];\n const arcs: ArcGeom[] = [];\n const n = vertices.length;\n const segCount = closed ? n : n - 1;\n for (let i = 0; i < segCount; i++) {\n const va = vertices[i];\n const vb = vertices[(i + 1) % n];\n const a = { x: va.x, y: va.y };\n const b = { x: vb.x, y: vb.y };\n const arc = bulgeToArc(a, b, va.bulge);\n if (arc) arcs.push(arc);\n else segments.push({ a, b });\n }\n return { segments, arcs };\n};\n\n/** Tessellated closed polygon ring of a vertex chain (arc segments flattened). */\nexport const verticesToPolygon = (\n vertices: PolylineVertex[],\n chordTolerance = 0.1,\n): Vec2[] => {\n const ring: Vec2[] = [];\n const n = vertices.length;\n for (let i = 0; i < n; i++) {\n const va = vertices[i];\n const vb = vertices[(i + 1) % n];\n const a = { x: va.x, y: va.y };\n const b = { x: vb.x, y: vb.y };\n ring.push(a);\n const arc = bulgeToArc(a, b, va.bulge);\n if (arc) {\n const pts = tessellateArc(arc, chordTolerance);\n // pts includes endpoints; keep interior points in travel order (a → b).\n const interior = pts.slice(1, -1);\n if (va.bulge < 0) interior.reverse();\n ring.push(...interior);\n }\n }\n return ring;\n};\n\n/** Absolute area enclosed by a polygon ring (shoelace formula). */\nexport const polygonArea = (ring: Vec2[]): number => {\n let sum = 0;\n const n = ring.length;\n for (let i = 0; i < n; i++) {\n const p = ring[i];\n const q = ring[(i + 1) % n];\n sum += p.x * q.y - q.x * p.y;\n }\n return Math.abs(sum) / 2;\n};\n\n/** Length of a vertex chain in mm, bulge arcs exact; `closed` adds the\n * last → first segment. */\nexport const chainLength = (\n points: readonly { x: number; y: number; bulge: number }[],\n closed: boolean,\n): number => {\n let sum = 0;\n const n = closed ? points.length : points.length - 1;\n for (let i = 0; i < n; i++) {\n const a = points[i];\n const b = points[(i + 1) % points.length];\n const arc = bulgeToArc(a, b, a.bulge);\n sum += arc ? arc.radius * arcSweep(arc) : dist(a, b);\n }\n return sum;\n};\n\n/** Area enclosed by a closed polyline (bulge-aware via tessellation). */\nexport const polylineArea = (points: PolylineVertex[]): number =>\n polygonArea(verticesToPolygon(points));\n\n/** Net hatch area: outer loop minus holes (even-odd). */\nexport const hatchArea = (loops: { points: PolylineVertex[] }[]): number => {\n const areas = loops.map((l) => polygonArea(verticesToPolygon(l.points)));\n if (areas.length === 0) return 0;\n const holes = areas.slice(1).reduce((a, b) => a + b, 0);\n return Math.max(areas[0] - holes, 0);\n};\n\n// ---------------------------------------------------------------------------\n// Chain editing (grip editing, add/remove vertex). All functions are pure and\n// return the input array unchanged (same reference) on out-of-range indices.\n// ---------------------------------------------------------------------------\n\n/** Clamp a bulge to the sane editing range: snap |b| < 0.02 to straight, cap ±4. */\nexport const clampBulge = (b: number): number => {\n if (!Number.isFinite(b) || Math.abs(b) < 0.02) return 0;\n return Math.max(-4, Math.min(4, b));\n};\n\n/** Both endpoints of segment segIndex moved by delta; every bulge is kept, so\n * the segment's own arc translates rigidly while its neighbors reshape. */\nexport const translateChainSegment = (\n vertices: PolylineVertex[],\n closed: boolean,\n segIndex: number,\n delta: Vec2,\n): PolylineVertex[] => {\n const n = vertices.length;\n const segCount = closed ? n : n - 1;\n if (segIndex < 0 || segIndex >= segCount) return vertices;\n const j = (segIndex + 1) % n;\n return vertices.map((v, i) =>\n i === segIndex || i === j\n ? { ...v, x: v.x + delta.x, y: v.y + delta.y }\n : v,\n );\n};\n\n/**\n * Insert a vertex on segment segIndex at (the projection of) p; the new\n * vertex lands at index segIndex + 1. A bulged segment splits by sweep\n * fraction so both halves reconstruct the original circle (bulge = tan of a\n * quarter of each half's signed sweep); straight segments stay straight.\n * No-op when p coincides with an endpoint.\n */\nexport const insertChainVertex = (\n vertices: PolylineVertex[],\n closed: boolean,\n segIndex: number,\n p: Vec2,\n): PolylineVertex[] => {\n const n = vertices.length;\n const segCount = closed ? n : n - 1;\n if (segIndex < 0 || segIndex >= segCount) return vertices;\n const va = vertices[segIndex];\n const vb = vertices[(segIndex + 1) % n];\n const a = { x: va.x, y: va.y };\n const b = { x: vb.x, y: vb.y };\n if (dist(p, a) < 1e-9 || dist(p, b) < 1e-9) return vertices;\n const arc = bulgeToArc(a, b, va.bulge);\n let pos: Vec2;\n let bulgeA: number;\n let bulgeB: number;\n if (arc) {\n // Travel fraction t of p's angular projection. ArcGeom is normalized\n // CCW, so for a negative bulge travel a→b runs from endAngle backwards.\n const sweep = arcSweep(arc);\n const ang = angle(sub(p, arc.center));\n const from =\n va.bulge > 0\n ? normAngle(ang - arc.startAngle)\n : normAngle(arc.endAngle - ang);\n let t = from / sweep;\n if (!Number.isFinite(t)) t = 0.5;\n t = Math.min(0.99, Math.max(0.01, t));\n const theta = 4 * Math.atan(va.bulge); // signed total sweep\n bulgeA = Math.tan((t * theta) / 4);\n bulgeB = Math.tan(((1 - t) * theta) / 4);\n pos = pointOnArc(\n arc,\n va.bulge > 0 ? arc.startAngle + t * sweep : arc.endAngle - t * sweep,\n );\n } else {\n const ab = sub(b, a);\n const l2 = dot(ab, ab);\n let t = l2 < 1e-18 ? 0.5 : dot(sub(p, a), ab) / l2;\n t = Math.min(0.99, Math.max(0.01, t));\n pos = { x: a.x + ab.x * t, y: a.y + ab.y * t };\n bulgeA = 0;\n bulgeB = 0;\n }\n const out = vertices.slice();\n out[segIndex] = { ...va, bulge: bulgeA };\n out.splice(segIndex + 1, 0, { x: pos.x, y: pos.y, bulge: bulgeB });\n return out;\n};\n\n/**\n * Remove vertex i, merging its two adjacent segments. Two straight segments\n * merging stay straight (removing a corner shouldn't invent an arc); anything\n * arced re-solves through the removed vertex to roughly preserve the shape.\n * Open-chain endpoints just drop (the adjoining segment disappears).\n * Returns null at the minimum vertex count (open: 2, closed: 3).\n */\nexport const removeChainVertex = (\n vertices: PolylineVertex[],\n closed: boolean,\n i: number,\n): PolylineVertex[] | null => {\n const n = vertices.length;\n if (i < 0 || i >= n) return null;\n if (n <= (closed ? 3 : 2)) return null;\n const out = vertices.slice();\n if (!closed && (i === 0 || i === n - 1)) {\n out.splice(i, 1);\n // Zero the new last vertex's (unused) bulge so closing the chain later\n // doesn't resurrect a stale arc.\n if (i === n - 1) out[out.length - 1] = { ...out[out.length - 1], bulge: 0 };\n return out;\n }\n const j = (i - 1 + n) % n;\n const prev = vertices[j];\n const removed = vertices[i];\n const next = vertices[(i + 1) % n];\n const merged =\n Math.abs(prev.bulge) < 1e-12 && Math.abs(removed.bulge) < 1e-12\n ? 0\n : clampBulge(\n bulgeFrom3Points(\n { x: prev.x, y: prev.y },\n { x: removed.x, y: removed.y },\n { x: next.x, y: next.y },\n ),\n );\n out[j] = { ...prev, bulge: merged };\n out.splice(i, 1);\n return out;\n};\n\n/**\n * Insert a coincident copy right after vertex i. The copy takes over the\n * outgoing segment's bulge (the zero-length lead-in stays straight), so the\n * geometry is unchanged until the copy is dragged apart.\n */\nexport const duplicateChainVertex = (\n vertices: PolylineVertex[],\n i: number,\n): PolylineVertex[] => {\n const n = vertices.length;\n if (i < 0 || i >= n) return vertices;\n const out = vertices.slice();\n out[i] = { ...vertices[i], bulge: 0 };\n out.splice(i + 1, 0, { ...vertices[i] });\n return out;\n};\n\n/** Even-odd point-in-polygon over multiple rings. */\nexport const pointInRings = (rings: Vec2[][], p: Vec2): boolean => {\n let inside = false;\n for (const ring of rings) {\n for (let i = 0, j = ring.length - 1; i < ring.length; j = i++) {\n const a = ring[i];\n const b = ring[j];\n if (\n a.y > p.y !== b.y > p.y &&\n p.x < ((b.x - a.x) * (p.y - a.y)) / (b.y - a.y) + a.x\n ) {\n inside = !inside;\n }\n }\n }\n return inside;\n};\n","import { z } from \"zod\";\nimport { ColorSchema } from \"./common\";\nimport {\n DEFAULT_DIM_STYLE,\n DEFAULT_TEXT_STYLE,\n DimStyleSchema,\n ModelObjectSchema,\n TextStyleSchema,\n} from \"./objects\";\nimport { PaperLayoutSchema } from \"./paperLayout\";\nimport { LineTypeSchema } from \"./lineTypes\";\nimport { HatchPatternSchema } from \"./hatchPatterns\";\nimport { CURRENT_DOCUMENT_VERSION, migrateDocument } from \"./migrations\";\n\nexport const LayerSchema = z.object({\n id: z.string().default(() => crypto.randomUUID()),\n name: z.string().default(\"Layer\"),\n color: ColorSchema.default(\"#e8e8e8\"),\n /** Default line type for objects on this layer. */\n lineType: z.string().default(\"continuous\"),\n /** Default lineweight in mm for objects on this layer. */\n lineWidth: z.number().positive().default(0.25),\n /** Default paint opacity for objects on this layer (objects without their\n * own `opacity` inherit it, like color/lineWidth). */\n opacity: z.number().min(0).max(1).default(1),\n visible: z.boolean().default(true),\n locked: z.boolean().default(false),\n /** Plot flag (AutoCAD-style): false = shown on screen but excluded from\n * PDF/print output. */\n print: z.boolean().default(true),\n});\nexport type Layer = z.infer<typeof LayerSchema>;\n\n/** What hosts call a drawing that has no file (and no name) yet. A\n * document carries no name of its own: the file name IS the name (hosts own\n * it — desktop: the file path, web: the project record). Files that still\n * hold a legacy `name` key parse fine; it is dropped. */\nexport const DEFAULT_DOCUMENT_NAME = \"Untitled project\";\n\n/** Document-wide settings. `units` is declarative so far: geometry is\n * stored in mm and nothing renders in inches yet. */\nexport const DocumentSettingsSchema = z.object({\n units: z.enum([\"mm\", \"in\"]).default(\"mm\"),\n});\nexport type DocumentSettings = z.infer<typeof DocumentSettingsSchema>;\n\nexport const LineaDocumentSchema = z.preprocess(\n migrateDocument,\n z.object({\n /**\n * Stable document identity, stored IN the file so re-opening the same\n * file updates the same project record. Files that predate this field\n * get a fresh id on parse (it sticks after the next save). Save As to a\n * NEW file assigns a fresh id, keeping ids 1:1 with files.\n */\n id: z.string().default(() => crypto.randomUUID()),\n type: z.literal(\"lineadraw\").default(\"lineadraw\"),\n version: z.literal(CURRENT_DOCUMENT_VERSION),\n /** Document-wide settings (`DocumentSettingsSchema`). `units` is\n * declarative for now: geometry is always stored in mm and nothing\n * renders in inches yet. */\n settings: DocumentSettingsSchema.default({ units: \"mm\" }),\n layers: z.array(LayerSchema).min(1),\n currentLayerId: z.string(),\n /** Array order is draw order (bottom to top).\n * Resilient object parsing (calculus pattern): a single corrupt object must\n * not fail the whole document — skip it with a warning instead.\n */\n objects: z.preprocess((raw) => {\n if (!Array.isArray(raw)) return raw;\n return raw.filter((o) => {\n const r = ModelObjectSchema.safeParse(o);\n if (!r.success)\n console.warn(\"Skipping invalid model object:\", o, r.error.message);\n return r.success;\n });\n }, z.array(ModelObjectSchema)),\n layouts: z.array(PaperLayoutSchema).default([]),\n /** Named text styles; objects reference one by styleId (first =\n * default for objects without one). */\n textStyles: z\n .array(TextStyleSchema)\n .min(1)\n .default(() => [{ ...DEFAULT_TEXT_STYLE }]),\n /** Named dimension styles, same referencing model. */\n dimStyles: z\n .array(DimStyleSchema)\n .min(1)\n .default(() => [{ ...DEFAULT_DIM_STYLE }]),\n /**\n * Document-defined line types (model/lineTypes.ts): the definitions a\n * DXF/DWG brought along or a user imported. Objects and layers reference\n * them by NAME, ahead of the built-in catalogue. Additive — absent in\n * older files.\n */\n lineTypes: z.array(LineTypeSchema).default([]),\n /** Document-defined hatch patterns (model/hatchPatterns.ts), same model. */\n hatchPatterns: z.array(HatchPatternSchema).default([]),\n /**\n * Embedded files (the bytes of `asset`-source references — PNG, JPEG,\n * PDF, DXF, DWG, .linea): content hash → data URL. Kept IN the document\n * so the .linea file stays self-contained (the cost is base64 in the\n * JSON). Entries orphaned by deleted references just\n * ride along (no GC — deletion is undoable, so eager sweeps would break\n * redo).\n */\n assets: z.record(z.string(), z.string()).default({}),\n /**\n * The block library: raw ES-module sources (JS or TS). Each module\n * exports its own `id`/`name`/`params` metadata plus `draw` (and\n * optionally `place`; the pre-rename `main`/`defineInput` names are\n * frozen aliases) — see blocks/evalBlock.ts.\n */\n blockDefinitions: z.array(z.string()).default([]),\n /**\n * Document-embedded user commands (macro scripts): raw ES-module\n * sources, one `export default defineCommand({...})` per module — see\n * blocks/commandModules.ts. The user's per-device library lives outside\n * the document; these travel with the file.\n */\n commands: z.array(z.string()).default([]),\n }),\n);\nexport type LineaDocument = z.infer<typeof LineaDocumentSchema>;\n","import { z } from \"zod\";\nimport { ModelObjectSchema } from \"./objects\";\n\n/** ISO A-series portrait sizes in mm [width, height]. */\nexport const SHEET_PRESETS = {\n A4: [210, 297],\n A3: [297, 420],\n A2: [420, 594],\n A1: [594, 841],\n A0: [841, 1189],\n} as const satisfies Record<string, readonly [number, number]>;\n\nexport type SheetName = keyof typeof SHEET_PRESETS;\nexport type SheetOrientation = \"portrait\" | \"landscape\";\n/**\n * How callers name a sheet: a bare preset (`\"A3\"` — orientation from\n * context: landscape for a new layout, the current one when patching), a\n * preset with its orientation, or explicit millimetres (orientation baked\n * in).\n */\nexport type SheetSpec =\n | SheetName\n | { name: SheetName; orientation: SheetOrientation }\n | { width: number; height: number };\n\n/**\n * Sheet spec → millimetres. Presets are stored portrait. The ONE place every\n * API (createLayout, updateLayout, tools) resolves sheets; `defaultOrientation`\n * applies to a bare preset name only.\n */\nexport const resolveSheetSize = (\n sheet: SheetSpec = \"A3\",\n defaultOrientation: SheetOrientation = \"landscape\",\n): { width: number; height: number } => {\n if (typeof sheet !== \"string\" && \"width\" in sheet)\n return { width: sheet.width, height: sheet.height };\n const name = typeof sheet === \"string\" ? sheet : sheet.name;\n const orientation =\n typeof sheet === \"string\" ? defaultOrientation : sheet.orientation;\n const preset = SHEET_PRESETS[name];\n if (!preset) throw new Error(`Unknown sheet \"${String(name)}\"`);\n const [w, h] = preset;\n return orientation === \"landscape\"\n ? { width: h, height: w }\n : { width: w, height: h };\n};\n\n/** The orientation a sheet size implies (square counts as portrait). */\nexport const sheetOrientation = (sheet: {\n width: number;\n height: number;\n}): SheetOrientation => (sheet.width > sheet.height ? \"landscape\" : \"portrait\");\n\n/**\n * How authored model colors map to print colors for this layout (paper space\n * previews the same mapping — what you see is what prints):\n * - \"color\": keep colors; near-white neutrals become black (white paper).\n * - \"grayscale\": ink-weight grays — the lighter a color was authored on the\n * dark canvas, the darker it prints.\n * - \"monochrome\": everything black.\n */\nexport const PrintPaletteSchema = z.enum([\"color\", \"grayscale\", \"monochrome\"]);\nexport type PrintPalette = z.infer<typeof PrintPaletteSchema>;\n\nexport const PaperLayoutSchema = z.object({\n id: z.string().default(() => crypto.randomUUID()),\n name: z.string().default(\"Layout\"),\n /** Orientation is baked into width/height at creation. */\n sheet: z\n .object({\n width: z.number().positive(),\n height: z.number().positive(),\n })\n .default({ width: 210, height: 297 }), // A4 portrait\n printPalette: PrintPaletteSchema.default(\"color\"),\n /**\n * Sheet-space objects reuse model primitives (drawn in sheet mm).\n * Viewports live here too, as \"viewport\" objects.\n */\n objects: z.array(ModelObjectSchema).default([]),\n});\nexport type PaperLayout = z.infer<typeof PaperLayoutSchema>;\n","/**\n * Drawing scale → the stored 1:N denominator (model mm per paper mm):\n * `\"1:50\"` → 50, `\"2:1\"` → 0.5; numbers pass through (50 means 1:50), as\n * does a plain numeric string (`\"50\"`).\n */\nexport const parseScale = (scale: number | string): number => {\n if (typeof scale === \"number\") {\n if (!Number.isFinite(scale) || scale <= 0)\n throw new Error(`Invalid scale ${scale}`);\n return scale;\n }\n if (/^\\s*\\d+(?:\\.\\d+)?\\s*$/.test(scale)) return parseScale(Number(scale));\n const m = /^\\s*(\\d+(?:\\.\\d+)?)\\s*:\\s*(\\d+(?:\\.\\d+)?)\\s*$/.exec(scale);\n const paper = m ? Number(m[1]) : NaN;\n const model = m ? Number(m[2]) : NaN;\n if (!(paper > 0) || !(model > 0))\n throw new Error(\n `Invalid scale \"${scale}\" (use \"1:50\", \"2:1\", or a number)`,\n );\n return model / paper;\n};\n","import { LineaDocumentSchema, type LineaDocument } from \"./document\";\nimport { CURRENT_DOCUMENT_VERSION } from \"./migrations\";\n\nexport function emptyDocument(): LineaDocument {\n const layerId = crypto.randomUUID();\n\n return LineaDocumentSchema.parse({\n version: CURRENT_DOCUMENT_VERSION,\n layers: [\n {\n id: layerId,\n name: \"Layer 0\",\n color: \"#e8e8e8\",\n lineWidth: 0.25,\n visible: true,\n locked: false,\n },\n ],\n currentLayerId: layerId,\n objects: [],\n // Deliberately layout-less: a hidden default \"Layout 1\" surprises SDK\n // users (blank first PDF page, layouts.length off by one) and the PDF\n // export already falls back to an auto-fitted sheet. Layouts are created\n // explicitly (editor command / createLayout).\n layouts: [],\n });\n}\n","import { LineaDocumentSchema, type LineaDocument } from \"./model/document\";\n\n/** Pretty JSON — .linea files are meant to be diffable and inspectable. */\nexport const documentToJson = (doc: LineaDocument): string =>\n JSON.stringify(doc, null, 2);\n\n/** Parse + validate + migrate. Throws on unrecoverable input. */\nexport const documentFromJson = (text: string): LineaDocument =>\n LineaDocumentSchema.parse(JSON.parse(text));\n\n/** How long one synchronous slice of `documentToJsonAsync` may run before\n * it yields (ms). */\nconst SLICE_MS = 30;\n/** Array items stringified per call (one call per item is ~3× slower). */\nconst BATCH = 1000;\n\n// Every piece is stringified inside a one-key wrapper so JSON.stringify lays\n// it out at its real depth, then the wrapper's text is cut off:\n// `{⏎ \"k\": [⏎ a,⏎ b⏎ ]⏎}` → `a,⏎ b` (a batch of array items),\n// `{⏎ \"k\": {⏎ \"h\": v⏎ }⏎}` → `\"h\": v` (one record entry).\nconst ITEMS_HEAD = '{\\n \"k\": [\\n '.length;\nconst ITEMS_TAIL = \"\\n ]\\n}\".length;\nconst ENTRY_HEAD = '{\\n \"k\": {\\n '.length;\nconst ENTRY_TAIL = \"\\n }\\n}\".length;\n\n/**\n * `documentToJson` in slices — byte-identical output, but the top-level\n * arrays (objects, layouts…) are stringified in batches and record members\n * (assets: embedded images) entry by entry, yielding the thread between\n * ~30 ms slices so a save can paint its progress. `onProgress` hears the\n * fraction done at each yield (never for a fast save). The document must\n * not change meanwhile — store snapshots never do.\n */\nexport const documentToJsonAsync = async (\n doc: LineaDocument,\n onProgress?: (fraction: number) => void,\n): Promise<string> => {\n const entries = Object.entries(doc as Record<string, unknown>);\n const isRecord = (v: unknown): v is Record<string, unknown> =>\n typeof v === \"object\" && v !== null && !Array.isArray(v);\n const total = entries.reduce(\n (n, [, v]) =>\n n +\n (Array.isArray(v)\n ? v.length\n : isRecord(v)\n ? Object.keys(v).length || 1\n : 1),\n 0,\n );\n let done = 0;\n let sliceStart = Date.now();\n const tick = async (count: number) => {\n done += count;\n if (Date.now() - sliceStart < SLICE_MS) return;\n onProgress?.(done / total);\n await new Promise((resolve) => setTimeout(resolve, 0));\n sliceStart = Date.now();\n };\n\n const members: string[] = [];\n for (const [key, value] of entries) {\n const name = JSON.stringify(key);\n if (Array.isArray(value) && value.length > 0) {\n const batches: string[] = [];\n for (let i = 0; i < value.length; i += BATCH) {\n batches.push(\n JSON.stringify({ k: value.slice(i, i + BATCH) }, null, 2).slice(\n ITEMS_HEAD,\n -ITEMS_TAIL,\n ),\n );\n await tick(Math.min(BATCH, value.length - i));\n }\n members.push(`${name}: [\\n ${batches.join(\",\\n \")}\\n ]`);\n } else if (isRecord(value) && Object.keys(value).length > 0) {\n const parts: string[] = [];\n for (const [k, v] of Object.entries(value)) {\n if (v === undefined) continue;\n parts.push(\n JSON.stringify({ k: { [k]: v } }, null, 2).slice(\n ENTRY_HEAD,\n -ENTRY_TAIL,\n ),\n );\n await tick(1);\n }\n members.push(\n parts.length\n ? `${name}: {\\n ${parts.join(\",\\n \")}\\n }`\n : `${name}: {}`,\n );\n } else {\n const json = JSON.stringify({ [key]: value }, null, 2);\n if (json !== \"{}\") members.push(json.slice(4, -2));\n await tick(1);\n }\n }\n return members.length ? `{\\n ${members.join(\",\\n \")}\\n}` : \"{}\";\n};\n","// A GeometrySink that emits SVG — the headless render target so agents/CLIs\n// can *see* a drawing instead of re-reading JSON (sibling to PdfSink). World\n// is mm, Y-up; SVG is Y-down, so coordinates are emitted with Y negated\n// (world-up renders up) and the viewBox uses -maxY as its top. Curves are\n// decomposed to cubic béziers via the shared helpers, so screen/PDF/SVG\n// output cannot drift.\n//\n// Transforms are baked into coordinates (viewport projection works), and clip\n// rects are honored via <clipPath> groups — so paper-layout viewport content\n// is clipped to its frame, like the canvas/PDF sinks.\n\nimport {\n arcToBeziers,\n ellipseArcToBeziers,\n matApply,\n matIdentity,\n matMultiply,\n signedArcSweep,\n type FillStyle,\n type GeometrySink,\n type Mat2x3,\n type Rect,\n type ImageSpec,\n type StrokeStyle,\n type TextSpec,\n} from \"../../paint/sink\";\nimport { approximateTextMeasurer } from \"../../paint/textMeasurer\";\nimport type { TextMeasurer } from \"../../paint/textMetrics\";\nimport { parseFontFace, resolveFont } from \"../../model/fonts\";\nimport type { Vec2 } from \"../../geometry/vec2\";\n\nconst n = (v: number): string => {\n const r = Math.round(v * 1000) / 1000;\n return Object.is(r, -0) ? \"0\" : String(r);\n};\n\nconst escapeXml = (s: string): string =>\n s.replace(/[&<>\"]/g, (c) =>\n c === \"&\" ? \"&\" : c === \"<\" ? \"<\" : c === \">\" ? \">\" : \""\",\n );\n\nexport interface SvgSinkOptions {\n /** Text width measurement (defaults to the approximate Inter table). */\n measure?: TextMeasurer;\n /**\n * Clamp every stroke to at least this width (world mm). Thumbnails render\n * a whole drawing into a ~256px image, where authored 0.25 mm lineweights\n * become sub-pixel and the picture rasterizes to nothing — clamping at the\n * SINK catches everything (block children and dimension hairlines resolve\n * their own widths past any per-object style override).\n */\n minStrokeWidthMm?: number;\n}\n\nexport class SvgSink implements GeometrySink {\n private els: string[] = [];\n private path: string[] = [];\n private hasCurrent = false;\n private m: Mat2x3 = matIdentity;\n private stack: Mat2x3[] = [];\n private defs: string[] = [];\n private clipId = 0;\n private gradId = 0;\n private measurer: TextMeasurer;\n private objectStart: number | null = null;\n private minStroke: number;\n\n constructor(opts: SvgSinkOptions = {}) {\n this.measurer = opts.measure ?? approximateTextMeasurer;\n this.minStroke = opts.minStrokeWidthMm ?? 0;\n }\n\n /** Transformed + Y-flipped point, as an \"x y\" token. */\n private p(pt: Vec2): string {\n const t = matApply(this.m, pt);\n return `${n(t.x)} ${n(-t.y)}`;\n }\n\n beginPath(): void {\n this.path = [];\n this.hasCurrent = false;\n }\n moveTo(pt: Vec2): void {\n this.path.push(`M${this.p(pt)}`);\n this.hasCurrent = true;\n }\n lineTo(pt: Vec2): void {\n this.path.push(`L${this.p(pt)}`);\n this.hasCurrent = true;\n }\n bezierTo(c1: Vec2, c2: Vec2, end: Vec2): void {\n this.path.push(`C${this.p(c1)} ${this.p(c2)} ${this.p(end)}`);\n this.hasCurrent = true;\n }\n private emitBeziers(\n bs: { start: Vec2; c1: Vec2; c2: Vec2; end: Vec2 }[],\n ): void {\n if (bs.length === 0) return;\n this.path.push(`${this.hasCurrent ? \"L\" : \"M\"}${this.p(bs[0].start)}`);\n for (const b of bs)\n this.path.push(`C${this.p(b.c1)} ${this.p(b.c2)} ${this.p(b.end)}`);\n this.hasCurrent = true;\n }\n arc(\n center: Vec2,\n r: number,\n startAngle: number,\n endAngle: number,\n ccw: boolean,\n ): void {\n this.emitBeziers(\n arcToBeziers(\n center,\n r,\n startAngle,\n signedArcSweep(startAngle, endAngle, ccw),\n ),\n );\n }\n ellipse(\n center: Vec2,\n rx: number,\n ry: number,\n rotation: number,\n startAngle: number,\n endAngle: number,\n ): void {\n this.emitBeziers(\n ellipseArcToBeziers(\n center,\n rx,\n ry,\n rotation,\n startAngle,\n signedArcSweep(startAngle, endAngle, true),\n ),\n );\n }\n closePath(): void {\n this.path.push(\"Z\");\n }\n stroke(s: StrokeStyle): void {\n if (this.path.length === 0) return;\n const width = Math.max(s.widthMm, this.minStroke);\n // Dash patterns are proportioned to the authored width — rescale them\n // with the clamp so boosted strokes still read as dashed, not solid-ish\n // noise at sub-pixel dash lengths.\n const boost = s.widthMm > 0 ? width / s.widthMm : 1;\n const dash =\n s.dashMm && s.dashMm.length\n ? ` stroke-dasharray=\"${s.dashMm.map((d) => n(d * boost)).join(\",\")}\"`\n : \"\";\n const alpha =\n s.opacity !== undefined && s.opacity < 1\n ? ` stroke-opacity=\"${n(s.opacity)}\"`\n : \"\";\n this.els.push(\n `<path d=\"${this.path.join(\" \")}\" fill=\"none\" stroke=\"${s.color}\" stroke-width=\"${n(width)}\"${dash}${alpha} stroke-linecap=\"round\" stroke-linejoin=\"round\"/>`,\n );\n }\n fill(f: FillStyle): void {\n if (this.path.length === 0) return;\n const alpha =\n f.opacity !== undefined && f.opacity < 1\n ? ` fill-opacity=\"${n(f.opacity)}\"`\n : \"\";\n let paint = f.color;\n if (f.gradient) {\n // Endpoints go through the same transform + Y-flip as path points, in\n // user space so the ramp stays anchored to the geometry.\n const a = matApply(this.m, f.gradient.from);\n const b = matApply(this.m, f.gradient.to);\n const id = `grad${this.gradId++}`;\n const stops =\n `<stop offset=\"0\" stop-color=\"${f.color}\"/>` +\n `<stop offset=\"1\" stop-color=\"${f.gradient.color2}\"/>`;\n this.defs.push(\n f.gradient.shape === \"radial\"\n ? `<radialGradient id=\"${id}\" gradientUnits=\"userSpaceOnUse\" ` +\n `cx=\"${n(a.x)}\" cy=\"${n(-a.y)}\" ` +\n `r=\"${n(Math.hypot(b.x - a.x, b.y - a.y))}\">${stops}</radialGradient>`\n : `<linearGradient id=\"${id}\" gradientUnits=\"userSpaceOnUse\" ` +\n `x1=\"${n(a.x)}\" y1=\"${n(-a.y)}\" x2=\"${n(b.x)}\" y2=\"${n(-b.y)}\">` +\n `${stops}</linearGradient>`,\n );\n paint = `url(#${id})`;\n }\n this.els.push(\n `<path d=\"${this.path.join(\" \")}\" fill=\"${paint}\"${alpha} fill-rule=\"evenodd\" stroke=\"none\"/>`,\n );\n }\n text(t: TextSpec): void {\n const def = resolveFont(t.font);\n const { bold, italic } = parseFontFace(t.font);\n // osifont-italic's TTF family is plain \"osifont\": only font-style lets a\n // TTF-family matcher (resvg) pick the italic file.\n const face =\n (bold ? ` font-weight=\"bold\"` : \"\") +\n (italic || def.id === \"osifont-italic\" ? ` font-style=\"italic\"` : \"\");\n // Model vAlign is in CAP-height terms (bottom = baseline at the anchor;\n // center/top shift the baseline down by half/full cap height). Compute\n // the baseline point in WORLD space so the shift rotates with the text,\n // then let SVG's default alphabetic baseline do the rest.\n const drop =\n t.vAlign === \"center\"\n ? t.heightMm / 2\n : t.vAlign === \"top\"\n ? t.heightMm\n : 0;\n const baselineWorld = {\n x: t.anchor.x + Math.sin(t.rotation) * drop,\n y: t.anchor.y - Math.cos(t.rotation) * drop,\n };\n const tp = matApply(this.m, baselineWorld);\n // The anchor is baked through the transform, so the glyph height must be\n // too — otherwise text inside a scaled viewport (e.g. a 1:50 paper layout)\n // keeps its full world size. Viewport transforms are uniform-scale, so the\n // matrix's x-basis length is the scale factor.\n const scale = Math.hypot(this.m[0], this.m[1]) || 1;\n const anchor =\n t.hAlign === \"left\" ? \"start\" : t.hAlign === \"right\" ? \"end\" : \"middle\";\n // World rotation is CCW (Y-up); with Y negated per point it maps to the\n // negated SVG rotation.\n const deg = (-t.rotation * 180) / Math.PI;\n const w = t.widthFactor ?? 1;\n const transforms: string[] = [];\n if (deg !== 0) transforms.push(`rotate(${n(deg)} ${n(tp.x)} ${n(-tp.y)})`);\n // Width factor: horizontal glyph scale about the anchor (applied before\n // the rotation, so it stretches along the text's own run direction).\n if (w !== 1)\n transforms.push(\n `translate(${n(tp.x)} ${n(-tp.y)}) scale(${n(w)} 1) translate(${n(-tp.x)} ${n(tp.y)})`,\n );\n const rot =\n transforms.length > 0 ? ` transform=\"${transforms.join(\" \")}\"` : \"\";\n const alpha =\n t.opacity !== undefined && t.opacity < 1\n ? ` fill-opacity=\"${n(t.opacity)}\"`\n : \"\";\n // font-size is the em; model heights are cap heights.\n this.els.push(\n `<text x=\"${n(tp.x)}\" y=\"${n(-tp.y)}\" font-size=\"${n((t.heightMm / def.capHeight) * scale)}\" font-family=\"${def.cssStack}\"${face} fill=\"${t.color}\"${alpha} text-anchor=\"${anchor}\"${rot}>${escapeXml(t.text)}</text>`,\n );\n }\n measureText(\n text: string,\n heightMm: number,\n font?: string,\n widthFactor?: number,\n ): { width: number } {\n return {\n width: this.measurer.measureTextWidth(text, heightMm, font, widthFactor),\n };\n }\n image(i: ImageSpec): void {\n // Anchor at the image's TOP-LEFT world corner (SVG images are y-down);\n // sizes bake the (uniform) matrix scale, rotation rides as a transform —\n // the text() approach.\n const topLeft = matApply(this.m, {\n x: i.origin.x - Math.sin(i.rotation) * i.heightMm,\n y: i.origin.y + Math.cos(i.rotation) * i.heightMm,\n });\n const scale = Math.hypot(this.m[0], this.m[1]) || 1;\n const deg = (-i.rotation * 180) / Math.PI;\n const rot =\n deg !== 0\n ? ` transform=\"rotate(${n(deg)} ${n(topLeft.x)} ${n(-topLeft.y)})\"`\n : \"\";\n const opacity = i.opacity < 1 ? ` opacity=\"${n(i.opacity)}\"` : \"\";\n this.els.push(\n `<image x=\"${n(topLeft.x)}\" y=\"${n(-topLeft.y)}\" width=\"${n(i.widthMm * scale)}\" height=\"${n(i.heightMm * scale)}\" preserveAspectRatio=\"none\"${opacity}${rot} href=\"${i.data}\"/>`,\n );\n }\n pushTransform(m: Mat2x3): void {\n this.stack.push(this.m);\n this.m = matMultiply(this.m, m);\n }\n popTransform(): void {\n this.m = this.stack.pop() ?? matIdentity;\n }\n /**\n * Group one object's elements as `<g data-object-id data-layer>` so the\n * SVG is navigable by viewers and agents (locate visually → id →\n * update()). Empty groups (nothing emitted) are dropped.\n */\n beginObject(id: string, layer?: string): void {\n this.objectStart = this.els.length;\n this.els.push(\n `<g data-object-id=\"${escapeXml(id)}\"${layer !== undefined ? ` data-layer=\"${escapeXml(layer)}\"` : \"\"}>`,\n );\n }\n endObject(): void {\n if (this.objectStart === null) return;\n if (this.els.length === this.objectStart + 1) this.els.pop();\n else this.els.push(\"</g>\");\n this.objectStart = null;\n }\n\n pushClipRect(r: Rect): void {\n // Bake the rect's corners through the current transform (+Y-flip) so the\n // clip lives in the same root user space as the content it wraps.\n const id = `clip${this.clipId++}`;\n const corners = [\n { x: r.x, y: r.y },\n { x: r.x + r.w, y: r.y },\n { x: r.x + r.w, y: r.y + r.h },\n { x: r.x, y: r.y + r.h },\n ];\n const d = `M${this.p(corners[0])}L${this.p(corners[1])}L${this.p(corners[2])}L${this.p(corners[3])}Z`;\n this.defs.push(`<clipPath id=\"${id}\"><path d=\"${d}\"/></clipPath>`);\n this.els.push(`<g clip-path=\"url(#${id})\">`);\n }\n popClip(): void {\n this.els.push(\"</g>\");\n }\n\n /** Wrap the accumulated elements in an <svg> with the given world bbox. */\n toSvg(\n bbox: { minX: number; minY: number; maxX: number; maxY: number },\n pad = 5,\n ): string {\n const minX = bbox.minX - pad;\n const w = bbox.maxX - bbox.minX + pad * 2;\n const h = bbox.maxY - bbox.minY + pad * 2;\n // Top of the viewBox is -maxY because we negated Y on every point.\n const minY = -bbox.maxY - pad;\n const defs = this.defs.length ? `<defs>${this.defs.join(\"\")}</defs>` : \"\";\n return (\n `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"${n(minX)} ${n(minY)} ${n(w)} ${n(h)}\">` +\n defs +\n this.els.join(\"\") +\n `</svg>`\n );\n }\n}\n","import type { Line } from \"../../model/objects\";\nimport type { GeometrySink } from \"../sink\";\nimport type { PaintEnv } from \"./index\";\n\nexport const paintLine = (\n obj: Line,\n sink: GeometrySink,\n env: PaintEnv,\n): void => {\n sink.beginPath();\n sink.moveTo(obj.a);\n sink.lineTo(obj.b);\n sink.stroke(env.style);\n};\n","import type { Point } from \"../../model/objects\";\nimport type { GeometrySink } from \"../sink\";\nimport type { PaintEnv } from \"./index\";\n\n/**\n * A point paints as a round dot whose diameter IS the stroke width: a\n * near-zero-length segment under the sinks' round line caps. That inherits\n * each sink's lineweight realization (canvas px floor, PDF/SVG verbatim mm,\n * viewport-scale compensation) instead of inventing a second sizing rule.\n * The 0.002 mm nudge keeps the segment non-degenerate everywhere — canvas\n * prunes zero-length subpaths, and the SVG sink rounds to 0.001 mm.\n */\nexport const paintPoint = (\n obj: Point,\n sink: GeometrySink,\n env: PaintEnv,\n): void => {\n sink.beginPath();\n sink.moveTo(obj.p);\n sink.lineTo({ x: obj.p.x + 0.002, y: obj.p.y });\n // Never dashed: a dash gap at phase zero would swallow the dot entirely.\n sink.stroke({ ...env.style, dashMm: undefined });\n};\n","import type { Polyline, PolylineVertex } from \"../../model/objects\";\nimport { bulgeToArc } from \"../../geometry/arcs\";\nimport { angle, sub } from \"../../geometry/vec2\";\nimport type { GeometrySink } from \"../sink\";\nimport type { PaintEnv } from \"./index\";\n\n/** Emit one polyline segment (straight or bulged arc) into an open path. */\nconst segmentTo = (\n sink: GeometrySink,\n from: PolylineVertex,\n to: PolylineVertex,\n): void => {\n const a = { x: from.x, y: from.y };\n const b = { x: to.x, y: to.y };\n const arc = bulgeToArc(a, b, from.bulge);\n if (!arc) {\n sink.lineTo(b);\n return;\n }\n // Travel direction matters for path continuity: positive bulge runs CCW\n // (increasing angle) from a to b, negative runs CW.\n const angA = angle(sub(a, arc.center));\n const angB = angle(sub(b, arc.center));\n sink.arc(arc.center, arc.radius, angA, angB, from.bulge > 0);\n};\n\n/**\n * Emit a vertex chain as a subpath (no beginPath — callers compose multiple\n * chains into one even-odd path, e.g. hatch loops).\n */\nexport const emitVertexPath = (\n sink: GeometrySink,\n vertices: PolylineVertex[],\n closed: boolean,\n): void => {\n sink.moveTo({ x: vertices[0].x, y: vertices[0].y });\n for (let i = 1; i < vertices.length; i++) {\n segmentTo(sink, vertices[i - 1], vertices[i]);\n }\n if (closed) {\n segmentTo(sink, vertices[vertices.length - 1], vertices[0]);\n sink.closePath();\n }\n};\n\nconst buildPolylinePath = (obj: Polyline, sink: GeometrySink): void => {\n sink.beginPath();\n emitVertexPath(sink, obj.points, obj.closed);\n};\n\nexport const paintPolyline = (\n obj: Polyline,\n sink: GeometrySink,\n env: PaintEnv,\n): void => {\n buildPolylinePath(obj, sink);\n sink.stroke(env.style);\n};\n","import type { Circle } from \"../../model/objects\";\nimport type { GeometrySink } from \"../sink\";\nimport type { PaintEnv } from \"./index\";\n\nexport const paintCircle = (\n obj: Circle,\n sink: GeometrySink,\n env: PaintEnv,\n): void => {\n sink.beginPath();\n sink.arc(obj.center, obj.radius, 0, Math.PI * 2, true);\n sink.closePath();\n sink.stroke(env.style);\n};\n","import type { Arc } from \"../../model/objects\";\nimport type { GeometrySink } from \"../sink\";\nimport type { PaintEnv } from \"./index\";\n\nexport const paintArc = (obj: Arc, sink: GeometrySink, env: PaintEnv): void => {\n sink.beginPath();\n sink.arc(obj.center, obj.radius, obj.startAngle, obj.endAngle, true);\n sink.stroke(env.style);\n};\n","import type { Ellipse } from \"../../model/objects\";\nimport { angle, len } from \"../../geometry/vec2\";\nimport { ellipseSweep } from \"../../geometry/ellipse\";\nimport type { GeometrySink } from \"../sink\";\nimport type { PaintEnv } from \"./index\";\n\nexport const paintEllipse = (\n obj: Ellipse,\n sink: GeometrySink,\n env: PaintEnv,\n): void => {\n const rx = len(obj.majorAxis);\n if (rx < 1e-12) return;\n const sweep = ellipseSweep(obj);\n sink.beginPath();\n sink.ellipse(\n obj.center,\n rx,\n rx * obj.ratio,\n angle(obj.majorAxis),\n obj.startAngle,\n obj.startAngle + sweep,\n );\n sink.stroke(env.style);\n};\n","import type { Hatch } from \"../../model/objects\";\nimport {\n computePatternGeometry,\n estimatePatternSegments,\n resolveHatchPattern,\n MAX_HATCH_SEGMENTS,\n} from \"../../model/hatchPatterns\";\nimport { verticesToPolygon } from \"../../geometry/polyline\";\nimport { computeHatchLines, type GeometrySink } from \"../sink\";\nimport { ANSI31_BASE_SPACING } from \"../../export/dxf/hatchPattern\";\nimport type { PaintEnv } from \"./index\";\nimport { emitVertexPath } from \"./polyline\";\n\n/** Stand-in for the single-family fills (\"lines\" / unknown pattern name):\n * deltaY 1 so the estimator's `scale` argument IS the line spacing. */\nconst SINGLE_FAMILY = {\n name: \"\",\n lines: [{ angle: 0, origin: { x: 0, y: 0 }, deltaX: 0, deltaY: 1 }],\n};\n\nconst paintSolid = (obj: Hatch, sink: GeometrySink, env: PaintEnv): void => {\n // All loops as one even-odd path: loop[0] outer, the rest are holes.\n sink.beginPath();\n for (const loop of obj.loops) emitVertexPath(sink, loop.points, true);\n sink.fill({ color: env.style.color, opacity: env.style.opacity });\n};\n\n/** Gradient geometry from the loops' bbox. linear: an axis through the\n * center along the fill angle, spanning the bbox's projection onto that\n * direction — the full color ramp is always visible whatever the region's\n * shape and rotation. radial: color1 at the center fading to color2 at the\n * farthest bbox corner. */\nconst paintGradient = (\n obj: Hatch,\n fill: {\n shape: \"linear\" | \"radial\";\n color1: string;\n color2: string;\n angle: number;\n },\n sink: GeometrySink,\n env: PaintEnv,\n): void => {\n let minX = Infinity;\n let minY = Infinity;\n let maxX = -Infinity;\n let maxY = -Infinity;\n for (const loop of obj.loops)\n for (const p of loop.points) {\n if (p.x < minX) minX = p.x;\n if (p.y < minY) minY = p.y;\n if (p.x > maxX) maxX = p.x;\n if (p.y > maxY) maxY = p.y;\n }\n if (minX > maxX) return;\n const c = { x: (minX + maxX) / 2, y: (minY + maxY) / 2 };\n const hw = (maxX - minX) / 2;\n const hh = (maxY - minY) / 2;\n let from: { x: number; y: number };\n let to: { x: number; y: number };\n if (fill.shape === \"radial\") {\n from = c;\n const r = Math.max(Math.hypot(hw, hh), 1e-6);\n to = { x: c.x + r, y: c.y };\n } else {\n const dir = { x: Math.cos(fill.angle), y: Math.sin(fill.angle) };\n const r = Math.max(Math.abs(dir.x) * hw + Math.abs(dir.y) * hh, 1e-6);\n from = { x: c.x - dir.x * r, y: c.y - dir.y * r };\n to = { x: c.x + dir.x * r, y: c.y + dir.y * r };\n }\n sink.beginPath();\n for (const loop of obj.loops) emitVertexPath(sink, loop.points, true);\n sink.fill({\n color: fill.color1,\n opacity: env.style.opacity,\n gradient: { shape: fill.shape, from, to, color2: fill.color2 },\n });\n};\n\nexport const paintHatch = (\n obj: Hatch,\n sink: GeometrySink,\n env: PaintEnv,\n): void => {\n if (obj.fill.kind === \"solid\") {\n paintSolid(obj, sink, env);\n return;\n }\n if (obj.fill.kind === \"gradient\") {\n paintGradient(obj, obj.fill, sink, env);\n return;\n }\n // Pattern lines clipped to the loops (pure math — no canvas clip needed,\n // and the identical segments feed PDF/DXF export later). The clipping is\n // the expensive part, so it is cached per object when the caller keeps one.\n let lines = env.cache?.hatchLines.get(obj);\n if (!lines) {\n const rings = obj.loops.map((loop) => verticesToPolygon(loop.points));\n // fill.scale × obj.scale is the effective world-mm multiplier (obj.scale\n // is the shared annotation-scale knob, like the \"lines\" fill uses).\n const s =\n obj.fill.kind === \"pattern\" ? obj.fill.scale * obj.scale : obj.scale;\n const pat =\n obj.fill.kind === \"pattern\"\n ? resolveHatchPattern(obj.fill.name, env.hatchPatterns)\n : undefined;\n // MaxHatch-style ceiling (estimated BEFORE generating): a pattern this\n // dense reads as tone and its segments would stall paint/export — draw\n // it as a faint solid instead. Estimated per paint, never cached — the\n // estimate is a bbox scan, and caching would need a sentinel type.\n const estimate = pat\n ? estimatePatternSegments(rings, pat, s)\n : estimatePatternSegments(\n rings,\n SINGLE_FAMILY,\n obj.fill.kind === \"pattern\"\n ? s * ANSI31_BASE_SPACING\n : obj.fill.spacing * obj.scale,\n );\n if (estimate > MAX_HATCH_SEGMENTS) {\n paintSolid(obj, sink, {\n ...env,\n style: { ...env.style, opacity: 0.25 * (env.style.opacity ?? 1) },\n });\n return;\n }\n if (obj.fill.kind === \"pattern\") {\n lines = pat\n ? computePatternGeometry(rings, pat, obj.fill.angle, s, obj.fill.origin)\n : // Unknown name: fall back to a single ANSI31-style family.\n computeHatchLines(rings, obj.fill.angle, s * ANSI31_BASE_SPACING);\n } else {\n lines = computeHatchLines(\n rings,\n obj.fill.angle,\n obj.fill.spacing * obj.scale,\n );\n }\n env.cache?.hatchLines.set(obj, lines);\n }\n if (lines.length === 0) return;\n sink.beginPath();\n for (const seg of lines) {\n sink.moveTo(seg.a);\n sink.lineTo(seg.b);\n }\n sink.stroke({\n color: env.style.color,\n widthMm: Math.min(env.style.widthMm, 0.18),\n opacity: env.style.opacity,\n });\n};\n","import type { ArrowType } from \"../../model/objects\";\nimport type { Vec2 } from \"../../geometry/vec2\";\nimport { add, norm, perp, scale, sub } from \"../../geometry/vec2\";\nimport type { GeometrySink } from \"../sink\";\n\n/**\n * Arrowhead at `tip`, body extending toward `toward`. Styles follow the\n * standard DXF arrowhead blocks: filled (ClosedFilled), open (Open 30°),\n * tick (ArchTick — oblique stroke across the line), dot (filled circle),\n * none.\n */\nexport const paintArrowhead = (\n sink: GeometrySink,\n tip: Vec2,\n toward: Vec2,\n size: number,\n color: string,\n type: ArrowType = \"filled\",\n opacity?: number,\n): void => {\n if (type === \"none\") return;\n const dir = norm(sub(toward, tip));\n if (dir.x === 0 && dir.y === 0) return;\n\n switch (type) {\n case \"filled\": {\n const base = add(tip, scale(dir, size));\n const half = scale(perp(dir), size / 3);\n sink.beginPath();\n sink.moveTo(tip);\n sink.lineTo(add(base, half));\n sink.lineTo(sub(base, half));\n sink.closePath();\n sink.fill({ color, opacity });\n break;\n }\n case \"open\": {\n const base = add(tip, scale(dir, size));\n const half = scale(perp(dir), size / 3);\n sink.beginPath();\n sink.moveTo(add(base, half));\n sink.lineTo(tip);\n sink.lineTo(sub(base, half));\n sink.stroke({ color, widthMm: Math.min(size / 10, 0.25), opacity });\n break;\n }\n case \"tick\": {\n // 45° oblique stroke centered on the tip (architectural tick).\n const diag = scale(norm(add(dir, perp(dir))), size / 2);\n sink.beginPath();\n sink.moveTo(sub(tip, diag));\n sink.lineTo(add(tip, diag));\n sink.stroke({ color, widthMm: Math.min(size / 8, 0.35), opacity });\n break;\n }\n case \"dot\": {\n sink.beginPath();\n sink.arc(tip, size / 4, 0, Math.PI * 2, true);\n sink.fill({ color, opacity });\n break;\n }\n }\n};\n","// Text painter. The alignment involutions and box-corner geometry live in\n// ../textGeometry (shared with snap/hit-testing); this file is the sink\n// drawing pass. Text WIDTH measurement is the one non-geometric input — it is\n// taken from the sink's own `measureText` (canvas-backed on screen,\n// font-metric in a headless/PDF sink), so no DOM leaks into the kernel.\n\nimport type { Text } from \"../../model/objects\";\nimport { effectiveTextFont } from \"../../model/objects\";\nimport { add, fromAngle, perp, scale } from \"../../geometry/vec2\";\nimport { lineSegments, textBlock, type TextMeasurer } from \"../textMetrics\";\nimport { approximateTextMeasurer } from \"../textMeasurer\";\nimport {\n textArrowSize,\n textArrowType,\n textFrameGeometry,\n textHeight,\n textWidth,\n} from \"../textGeometry\";\nimport type { GeometrySink } from \"../sink\";\nimport type { PaintEnv } from \"./index\";\nimport { paintArrowhead } from \"./arrows\";\nimport { emitVertexPath } from \"./polyline\";\nimport { richTextBlock, type RichBlock } from \"../richText\";\n\nexport const paintText = (\n obj: Text,\n sink: GeometrySink,\n env: PaintEnv,\n): void => {\n // Bind the object's effective font (own, else document text style) so\n // wrap/frame measurement matches what the sink will draw.\n const { font, widthFactor } = effectiveTextFont(obj, env.textStyles);\n const measure: TextMeasurer = {\n measureTextWidth: (text, heightMm) =>\n sink.measureText(text, heightMm, font, widthFactor).width,\n };\n // Tab-cell advancement uses the DETERMINISTIC approximate measurer, not\n // the sink's: each sink measures with its own font metrics (canvas glyphs,\n // jsPDF Helvetica, the Inter table), and a near-boundary cell would land\n // on a different tab stop per output — columns misaligning between the\n // canvas/PNG and the PDF. With a shared measurer every output picks the\n // same stops by construction; a real glyph run may over/underfill its\n // cell by the approximation error instead.\n const tabStopMeasure: TextMeasurer = {\n measureTextWidth: (text, heightMm) =>\n approximateTextMeasurer.measureTextWidth(\n text,\n heightMm,\n font,\n widthFactor,\n ),\n };\n\n const { color, widthMm, opacity } = env.style;\n\n // Leader lines first (annotative geometry under the glyphs).\n for (const line of obj.leaderLines) {\n sink.beginPath();\n sink.moveTo(line[0]);\n for (let i = 1; i < line.length; i++) sink.lineTo(line[i]);\n sink.stroke({ color, widthMm, opacity });\n\n paintArrowhead(\n sink,\n line[0],\n line[1],\n textArrowSize(obj, env.textStyles),\n color,\n textArrowType(obj, env.textStyles),\n opacity,\n );\n }\n\n // Frame border under the glyphs.\n for (const part of textFrameGeometry(obj, measure, env.textStyles)) {\n sink.beginPath();\n emitVertexPath(sink, part.points, part.closed);\n sink.stroke({ color, widthMm, opacity });\n }\n\n const height = textHeight(obj, env.textStyles);\n if (obj.spans?.length) {\n paintRichText(obj, sink, env, height, font, widthFactor, tabStopMeasure);\n return;\n }\n\n // Wrapping re-measures every word; cache the block per object. The cache\n // is per consumer (PaintEnv.cache), so different measurers never mix. The\n // `base` guard drops entries when the document text style is edited (an\n // inherited-font text rewraps without the object itself changing).\n const cached = env.cache?.textBlocks.get(obj);\n let block = cached?.base === env.textStyles ? cached.block : undefined;\n if (!block) {\n block = textBlock(obj.content, height, measure, textWidth(obj));\n env.cache?.textBlocks.set(obj, { base: env.textStyles, block });\n }\n const u = fromAngle(obj.rotation);\n const vUp = perp(u);\n // Shift the first line up so the whole block (not just line 0) honours\n // vAlign: top-aligned blocks grow down, bottom-aligned grow up.\n const vA = obj.vAlign;\n const up =\n vA === \"top\"\n ? 0\n : vA === \"center\"\n ? ((block.lines.length - 1) * block.lineHeight) / 2\n : (block.lines.length - 1) * block.lineHeight;\n const hA = obj.hAlign;\n for (let i = 0; i < block.lines.length; i++) {\n const lineAnchor = add(obj.position, scale(vUp, up - i * block.lineHeight));\n const spec = {\n heightMm: height,\n rotation: obj.rotation,\n vAlign: vA,\n color: env.style.color,\n font,\n widthFactor,\n opacity: env.style.opacity,\n };\n const segs = lineSegments(block.lines[i], height, tabStopMeasure);\n if (segs.length === 1) {\n sink.text({\n ...spec,\n text: segs[0].text,\n anchor: lineAnchor,\n hAlign: hA,\n });\n continue;\n }\n // Tabbed line: one left-anchored run per segment at its tab-stop offset.\n // Offsets measure from the BLOCK's left edge (not the line's own width),\n // so columns stay aligned across rows under every alignment — the MTEXT\n // model, where tabs run from the paragraph box edge.\n const start =\n hA === \"left\" ? 0 : hA === \"center\" ? -block.width / 2 : -block.width;\n for (const seg of segs) {\n if (!seg.text) continue; // consecutive tabs: the stop still advanced\n sink.text({\n ...spec,\n text: seg.text,\n anchor: add(lineAnchor, scale(u, start + seg.x)),\n hAlign: \"left\",\n });\n }\n }\n};\n\n/** Texts with spans: one left-anchored baseline run per formatted piece\n * (paint/richText.ts lays them out; same alignment rules as above). */\nconst paintRichText = (\n obj: Text,\n sink: GeometrySink,\n env: PaintEnv,\n height: number,\n font: string | undefined,\n widthFactor: number,\n tabStopMeasure: TextMeasurer,\n): void => {\n const measure = sinkMeasurer(sink);\n const cached = env.cache?.richBlocks.get(obj);\n let block = cached?.base === env.textStyles ? cached.block : undefined;\n if (!block) {\n block = richTextBlock(\n obj.content,\n obj.spans,\n { face: font, heightMm: height, widthFactor },\n measure,\n tabStopMeasure,\n textWidth(obj),\n );\n env.cache?.richBlocks.set(obj, { base: env.textStyles, block });\n }\n drawRichBlock(block, obj, sink, env, widthFactor);\n};\n\n/** A sink-measuring TextMeasurer (the painter's per-run widths). */\nexport const sinkMeasurer = (sink: GeometrySink): TextMeasurer => ({\n measureTextWidth: (text, h, face, wf) =>\n sink.measureText(text, h, face, wf).width,\n});\n\n/** Draw a laid-out formatted block at a placement: one left-anchored\n * baseline run per piece plus underlines, lines aligned as the plain\n * painter aligns them. Shared by texts and dimension labels. */\nexport const drawRichBlock = (\n block: RichBlock,\n at0: Pick<Text, \"position\" | \"rotation\" | \"hAlign\" | \"vAlign\">,\n sink: GeometrySink,\n env: PaintEnv,\n widthFactor: number,\n): void => {\n const u = fromAngle(at0.rotation);\n const vUp = perp(u);\n const hA = at0.hAlign;\n const top =\n at0.vAlign === \"top\"\n ? 0\n : at0.vAlign === \"center\"\n ? block.height / 2\n : block.height;\n const blockLeft =\n hA === \"left\" ? 0 : hA === \"center\" ? -block.width / 2 : -block.width;\n const { color, opacity } = env.style;\n for (const line of block.lines) {\n const left = line.fromBlockEdge\n ? blockLeft\n : hA === \"left\"\n ? 0\n : hA === \"center\"\n ? -line.width / 2\n : -line.width;\n for (const p of line.pieces) {\n const at = (dx: number, dy: number) =>\n add(add(at0.position, scale(u, left + p.x + dx)), scale(vUp, dy));\n const y = top - line.baseline + p.dy;\n const c = p.color ?? color;\n if (p.text)\n sink.text({\n text: p.text,\n anchor: at(0, y),\n heightMm: p.heightMm,\n rotation: at0.rotation,\n hAlign: \"left\",\n vAlign: \"bottom\",\n color: c,\n font: p.face,\n widthFactor,\n opacity,\n });\n if (p.underline && p.width > 0) {\n const uy = y - p.heightMm * UNDERLINE_DROP;\n sink.beginPath();\n sink.moveTo(at(0, uy));\n sink.lineTo(at(p.width, uy));\n sink.stroke({ color: c, widthMm: env.style.widthMm, opacity });\n }\n }\n }\n};\n\n/** Underline below the baseline, × the piece's cap height. */\nconst UNDERLINE_DROP = 0.18;\n","// Dimension painter (all kinds). The geometry derivation is shared with\n// snap/hit-testing and DXF explosion — it lives in ../dimensionGeometry so\n// this file is purely the sink drawing pass.\n\nimport type { Dimension } from \"../../model/objects\";\nimport { add, fromAngle, scale } from \"../../geometry/vec2\";\nimport { dimensionGeometry } from \"../dimensionGeometry\";\nimport type { GeometrySink } from \"../sink\";\nimport type { PaintEnv } from \"./index\";\nimport { paintArrowhead } from \"./arrows\";\nimport { approximateTextMeasurer } from \"../textMeasurer\";\nimport { richTextBlock } from \"../richText\";\nimport { drawRichBlock, sinkMeasurer } from \"./text\";\n\nexport const paintDimension = (\n obj: Dimension,\n sink: GeometrySink,\n env: PaintEnv,\n): void => {\n // The derivation is pure in (obj, dimStyles) — both are replaced on edit,\n // so a cached entry is valid exactly while both references match.\n const cached = env.cache?.dimGeometry.get(obj);\n const geom =\n cached && cached.base === env.dimStyles\n ? cached.geom\n : dimensionGeometry(obj, env.dimStyles);\n env.cache?.dimGeometry.set(obj, { base: env.dimStyles, geom });\n if (!geom) return;\n // Dimension linework follows the object/layer linetype (dashMm) like any\n // other stroke; arrowheads and text stay solid. Only the width is capped —\n // annotation linework stays hairline even on heavy layers.\n const stroke = {\n color: env.style.color,\n widthMm: Math.min(env.style.widthMm, 0.18),\n dashMm: env.style.dashMm,\n opacity: env.style.opacity,\n };\n\n sink.beginPath();\n for (const seg of [\n ...geom.extensionLines,\n ...geom.dimLines,\n ...geom.leaders,\n ]) {\n sink.moveTo(seg.a);\n sink.lineTo(seg.b);\n }\n if (geom.dimArc) {\n const arc = geom.dimArc;\n sink.moveTo(add(arc.center, scale(fromAngle(arc.startAngle), arc.radius)));\n sink.arc(arc.center, arc.radius, arc.startAngle, arc.endAngle, true);\n }\n sink.stroke(stroke);\n\n for (const arrow of geom.arrows) {\n paintArrowhead(\n sink,\n arrow.tip,\n arrow.toward,\n arrow.size,\n env.style.color,\n geom.arrowType,\n env.style.opacity,\n );\n }\n\n for (const text of geom.labels) {\n if (text.spans?.length) {\n drawRichBlock(\n richTextBlock(\n text.content,\n text.spans,\n {\n face: text.font,\n heightMm: text.height,\n widthFactor: text.widthFactor ?? 1,\n },\n sinkMeasurer(sink),\n approximateTextMeasurer,\n ),\n {\n position: text.anchor,\n rotation: text.rotation,\n hAlign: \"center\",\n vAlign: \"center\",\n },\n sink,\n env,\n text.widthFactor ?? 1,\n );\n continue;\n }\n sink.text({\n text: text.content,\n anchor: text.anchor,\n heightMm: text.height,\n rotation: text.rotation,\n hAlign: \"center\",\n vAlign: \"center\",\n color: env.style.color,\n font: text.font,\n widthFactor: text.widthFactor,\n opacity: env.style.opacity,\n });\n }\n};\n","// Dash resolution for the paint layer. Line-type definitions now live in the\n// named library (model/lineTypes.ts, curated set + embedded built-in catalogue);\n// this module turns a line-type NAME into the mm dash array the sinks consume,\n// so screen output matches print (both use true mm; only overlay chrome is\n// screen-constant). Patterns are defined per 1 mm of line width — callers\n// scale them by resolvedWidth × lineTypeScale (CELTSCALE) via scaleDash.\n\nimport {\n renderDashes,\n resolveLineType,\n type LineType,\n} from \"../model/lineTypes\";\n\nexport const dashForLineType = (\n lineType: string | undefined,\n /** The document's own line types, resolved ahead of the catalogue. */\n lineTypes?: readonly LineType[],\n): number[] | undefined => {\n if (!lineType) return undefined;\n const pattern = resolveLineType(lineType, lineTypes);\n return pattern ? renderDashes(pattern) : undefined;\n};\n\n/** Apply a length multiplier (resolved width × CELTSCALE) to a dash pattern. */\nexport const scaleDash = (\n dash: number[] | undefined,\n multiplier: number | undefined,\n): number[] | undefined =>\n dash && multiplier !== undefined && multiplier !== 1\n ? dash.map((d) => d * multiplier)\n : dash;\n","import { blockPivot, type Block, type ModelObject } from \"../../model/objects\";\nimport {\n getBlockError,\n getEvaluatedWorldChildren,\n} from \"../../extensions/evalBlock\";\nimport { dashForLineType, scaleDash } from \"../lineTypes\";\nimport type { GeometrySink } from \"../sink\";\nimport type { PaintEnv } from \"./index\";\nimport { paintObject } from \"./index\";\n\nconst ERROR_COLOR = \"#ef4444\";\n\nexport const paintBlockInstance = (\n obj: Block,\n sink: GeometrySink,\n env: PaintEnv,\n): void => {\n const children = getEvaluatedWorldChildren(\n obj,\n env.blockDefinitions,\n env.resolveObject,\n env, // its text / dim styles: what draw's `styles` reads\n );\n const error = getBlockError(obj.id);\n\n if (error) {\n // Dashed red placeholder at the pivot (first point input).\n const pivot = blockPivot(obj);\n const s = 6;\n sink.beginPath();\n sink.moveTo({ x: pivot.x - s, y: pivot.y - s });\n sink.lineTo({ x: pivot.x + s, y: pivot.y - s });\n sink.lineTo({ x: pivot.x + s, y: pivot.y + s });\n sink.lineTo({ x: pivot.x - s, y: pivot.y + s });\n sink.closePath();\n sink.stroke({ color: ERROR_COLOR, widthMm: 0.35, dashMm: [1, 1] });\n sink.text({\n text: \"!\",\n anchor: pivot,\n heightMm: s,\n rotation: 0,\n hAlign: \"center\",\n vAlign: \"center\",\n color: ERROR_COLOR,\n });\n return;\n }\n\n paintChildren(children, sink, env, obj.layerId);\n};\n\n/** Paint derived world children (block instances, tables): highlight paints\n * (forceStyle) keep the caller's style so the whole object reads as one\n * silhouette; normal paints resolve style per child over the parent's. */\nexport const paintChildren = (\n children: readonly ModelObject[],\n sink: GeometrySink,\n env: PaintEnv,\n /** The parent's layer: a child on ANOTHER layer (imported DXF blocks draw\n * across layers) is hidden with that layer. */\n parentLayerId?: string,\n): void => {\n for (const child of children) {\n if (\n env.layers &&\n parentLayerId !== undefined &&\n child.layerId !== parentLayerId &&\n env.layers.find((l) => l.id === child.layerId)?.visible === false\n )\n continue;\n paintObject(\n child,\n sink,\n env.forceStyle\n ? env\n : {\n style: {\n color: child.color ?? env.style.color,\n widthMm: child.lineWidth ?? env.style.widthMm,\n // Same width-proportional dash rule as resolveStyle.\n dashMm:\n scaleDash(\n dashForLineType(child.lineType, env.lineTypes),\n (child.lineWidth ?? env.style.widthMm) *\n (child.lineTypeScale ?? 1),\n ) ?? env.style.dashMm,\n opacity: child.opacity ?? env.style.opacity,\n },\n layers: env.layers,\n dimStyles: env.dimStyles,\n textStyles: env.textStyles,\n lineTypes: env.lineTypes,\n hatchPatterns: env.hatchPatterns,\n blockDefinitions: env.blockDefinitions,\n resolveObject: env.resolveObject,\n assets: env.assets,\n // A reference child (linked / embedded file) loads like any other.\n resolveReference: env.resolveReference,\n },\n );\n }\n};\n","// Viewport frame outline. This painter serves selection/hover highlights on\n// the overlay; the paper scene draws viewport CONTENT via layoutPaint and its\n// own chrome-colored frame pass, and the frame never reaches print output.\n\nimport type { Viewport } from \"../../model/objects\";\nimport type { GeometrySink } from \"../sink\";\nimport type { PaintEnv } from \"./index\";\n\nexport const paintViewport = (\n obj: Viewport,\n sink: GeometrySink,\n env: PaintEnv,\n): void => {\n const { x, y, w, h } = obj.rect;\n sink.beginPath();\n sink.moveTo({ x, y });\n sink.lineTo({ x: x + w, y });\n sink.lineTo({ x: x + w, y: y + h });\n sink.lineTo({ x, y: y + h });\n sink.closePath();\n sink.stroke({ color: env.style.color, widthMm: env.style.widthMm });\n};\n","// Table painter: the derived world children (rules + cell texts) from\n// ../tableLayout, painted like block-instance children.\n\nimport type { Table } from \"../../model/objects\";\nimport type { GeometrySink } from \"../sink\";\nimport { tableLayout } from \"../tableLayout\";\nimport { paintChildren } from \"./block\";\nimport type { PaintEnv } from \"./index\";\n\nexport const paintTable = (\n obj: Table,\n sink: GeometrySink,\n env: PaintEnv,\n): void => paintChildren(tableLayout(obj, env.textStyles).children, sink, env);\n","// A uniform-grid index over one snap entry's primitives (see\n// SnapCacheEntry.near): built on first query, it hands back only what lies\n// in a box — a referenced site plan has 10⁵+ segments, and scanning them all\n// on every pointer move made snapping lag and forced a cap that left most\n// edges unsnappable.\n\nimport { boundsIntersect, isEmptyBounds, type AABB } from \"../geometry/bounds\";\nimport type { SnapCacheEntry } from \"./types\";\n\n/** Cells per side of the grid over the entry's geometry. */\nconst GRID = 256;\n/** An arc/ellipse box spanning more cells than this goes in the\n * always-checked list instead (few curves are that big). Segments never do:\n * they are indexed along the cells they actually cross. */\nconst MAX_CELLS = 64;\n\ntype Kind = 0 | 1 | 2 | 3; // point, segment, arc, ellipse\n\nconst segmentBox = (s: {\n a: { x: number; y: number };\n b: { x: number; y: number };\n}): AABB => ({\n minX: Math.min(s.a.x, s.b.x),\n maxX: Math.max(s.a.x, s.b.x),\n minY: Math.min(s.a.y, s.b.y),\n maxY: Math.max(s.a.y, s.b.y),\n});\n\nexport const withNearIndex = (entry: SnapCacheEntry): SnapCacheEntry => {\n // The grid covers the entry's GEOMETRY bounds, not pointBounds: a\n // reference's insertion point can sit 10¹⁰ mm from its content (a survey\n // file placed back at the origin), which would squash everything into one\n // cell. Primitives outside the grid go in the always-checked list.\n const b = isEmptyBounds(entry.bounds) ? entry.pointBounds : entry.bounds;\n const size = Math.max(b.maxX - b.minX, b.maxY - b.minY, 1e-9) / GRID;\n const cell = (v: number, min: number) =>\n Math.min(GRID - 1, Math.max(0, Math.floor((v - min) / size)));\n const outside = (box: AABB) =>\n box.minX < b.minX ||\n box.maxX > b.maxX ||\n box.minY < b.minY ||\n box.maxY > b.maxY;\n // Packed ids: kind in the low 2 bits.\n const id = (kind: Kind, i: number) => i * 4 + kind;\n\n let index: { cells: Map<number, number[]>; big: number[] } | null = null;\n const build = () => {\n const cells = new Map<number, number[]>();\n const big: number[] = [];\n const add = (k: number, key: number) => {\n const list = cells.get(k);\n if (list) {\n if (list[list.length - 1] !== key) list.push(key);\n } else cells.set(k, [key]);\n };\n const insert = (key: number, box: AABB) => {\n const x0 = cell(box.minX, b.minX);\n const x1 = cell(box.maxX, b.minX);\n const y0 = cell(box.minY, b.minY);\n const y1 = cell(box.maxY, b.minY);\n if (outside(box) || (x1 - x0 + 1) * (y1 - y0 + 1) > MAX_CELLS) {\n big.push(key);\n return;\n }\n for (let x = x0; x <= x1; x++)\n for (let y = y0; y <= y1; y++) add(x * GRID + y, key);\n };\n entry.points.forEach((sp, i) =>\n insert(id(0, i), {\n minX: sp.p.x,\n maxX: sp.p.x,\n minY: sp.p.y,\n maxY: sp.p.y,\n }),\n );\n // Segments go in the cells along them — a site plan's long hatch and\n // boundary lines would otherwise fill whole rows or be scanned always.\n entry.segments.forEach((s, i) => {\n const key = id(1, i);\n if (outside(segmentBox(s))) {\n big.push(key);\n return;\n }\n // ponytail: sampled every quarter cell, so a line clipping a cell\n // corner by less than that can miss it — the query box (pick/snap\n // tolerance) usually overlaps the neighbour; exact grid traversal if\n // that ever shows.\n const n =\n Math.ceil(Math.hypot(s.b.x - s.a.x, s.b.y - s.a.y) / (size / 4)) + 1;\n let last = -1;\n for (let t = 0; t <= n; t++) {\n const k =\n cell(s.a.x + ((s.b.x - s.a.x) * t) / n, b.minX) * GRID +\n cell(s.a.y + ((s.b.y - s.a.y) * t) / n, b.minY);\n if (k !== last) add(k, key);\n last = k;\n }\n });\n entry.arcs.forEach((a, i) =>\n insert(id(2, i), {\n minX: a.center.x - a.radius,\n maxX: a.center.x + a.radius,\n minY: a.center.y - a.radius,\n maxY: a.center.y + a.radius,\n }),\n );\n (entry.ellipses ?? []).forEach((e, i) => {\n const r = Math.hypot(e.majorAxis.x, e.majorAxis.y);\n insert(id(3, i), {\n minX: e.center.x - r,\n maxX: e.center.x + r,\n minY: e.center.y - r,\n maxY: e.center.y + r,\n });\n });\n return { cells, big };\n };\n\n const near = (box: AABB): SnapCacheEntry => {\n const out: SnapCacheEntry = {\n bounds: entry.bounds,\n pointBounds: entry.pointBounds,\n points: [],\n segments: [],\n arcs: [],\n ellipses: [],\n };\n const take = (k: number): void => {\n const i = k >> 2;\n switch ((k & 3) as Kind) {\n case 0:\n out.points.push(entry.points[i]);\n break;\n case 1:\n out.segments.push(entry.segments[i]);\n break;\n case 2:\n out.arcs.push(entry.arcs[i]);\n break;\n case 3:\n out.ellipses!.push(entry.ellipses![i]);\n break;\n }\n };\n if (!boundsIntersect(box, entry.pointBounds)) return out;\n index ??= build();\n // Off the geometry: only the outliers (e.g. a far insertion point).\n if (isEmptyBounds(b) || !boundsIntersect(box, b)) {\n for (const k of index.big) take(k);\n return out;\n }\n const seen = new Set<number>(index.big);\n const x0 = cell(box.minX, b.minX);\n const x1 = cell(box.maxX, b.minX);\n const y0 = cell(box.minY, b.minY);\n const y1 = cell(box.maxY, b.minY);\n for (let x = x0; x <= x1; x++)\n for (let y = y0; y <= y1; y++)\n for (const k of index.cells.get(x * GRID + y) ?? []) seen.add(k);\n for (const k of seen) take(k);\n return out;\n };\n\n return { ...entry, near };\n};\n","// Per-object snap/geometry derivation — the single source of derived geometry\n// for both snapping and hit-testing.\n//\n// KERNEL SEAM: `buildEntry` is PURE. The cache lifecycle (subscription to\n// store invalidation, id→object lookup) stays with the mutation owner; it\n// calls `buildSnapEntry` and memoizes the result. Everything the derivation\n// needs that would otherwise come from a store — the document dim style, the\n// block definitions, and a text measurer — is passed in via `SnapGeometryContext`.\n\nimport type {\n Dimension,\n DimStyle,\n Ellipse,\n Hatch,\n ModelObject,\n Polyline,\n Text,\n TextStyle,\n} from \"../model/objects\";\nimport { blockPivot } from \"../model/objects\";\nimport type { TextMeasurer } from \"../paint/textMetrics\";\nimport { textBoxCorners, textFrameGeometry } from \"../paint/textGeometry\";\nimport { dimensionGeometry } from \"../paint/dimensionGeometry\";\nimport { getEvaluatedWorldChildren } from \"../extensions/evalBlock\";\nimport { verticesToCurves, verticesToPolygon } from \"../geometry/polyline\";\nimport {\n addPointToBounds,\n boundsOfPoints,\n emptyBounds,\n isEmptyBounds,\n unionBounds,\n type AABB,\n} from \"../geometry/bounds\";\nimport {\n arcMidPoint,\n arcSweep,\n pointOnArc,\n angleInArc,\n type ArcGeom,\n} from \"../geometry/arcs\";\nimport { mid, normAngle, type Vec2 } from \"../geometry/vec2\";\nimport {\n pointOnEllipse,\n paramInEllipse,\n tessellateEllipse,\n isFullEllipse,\n type EllipseGeom,\n} from \"../geometry/ellipse\";\nimport type { Segment } from \"../geometry/line\";\nimport type { SnapCacheEntry, SnapPoint, SnapSegment } from \"./types\";\nimport { tableLayout } from \"../paint/tableLayout\";\nimport { withNearIndex } from \"./nearIndex\";\nimport type { Reference } from \"../model/objects\";\nimport {\n applyMat,\n clipSegment,\n placedBounds,\n placedCorners,\n referenceTransform,\n type ReferenceContent,\n} from \"../reference/reference\";\n\n/** Everything the derivation needs that a store would otherwise supply. */\nexport interface SnapGeometryContext {\n /** Document dimension style (dimension geometry resolves overrides on it). */\n dimStyles: readonly DimStyle[];\n /** Document text style (texts without their own font inherit from it). */\n textStyles: readonly TextStyle[];\n /** The document's layers (a block child's `layer` name resolves). */\n layers?: readonly { id: string; name: string }[];\n /** The document's block module sources, for evaluating instance children. */\n blockDefinitions: readonly string[];\n /**\n * Document-wide object lookup for block object-reference inputs; absent →\n * referenced inputs evaluate as null (see BlockObjectResolver).\n */\n resolveObject?: (id: string) => ModelObject | undefined;\n /** Text width measurement (canvas-backed in editor, font-metric in Node). */\n measure: TextMeasurer;\n /** Loaded reference content (see PaintEnv.resolveReference); absent or\n * null → a reference snaps and picks by its frame only. */\n resolveReference?: (ref: Reference) => ReferenceContent | null;\n}\n\n/** buildEntry output; `pointBounds` is derived centrally in buildSnapEntry. */\nexport type BuiltEntry = Omit<SnapCacheEntry, \"pointBounds\">;\n\n/** Tight AABB of an arc: endpoints plus axis-crossing extremes within range. */\nconst arcBoundsInto = (a: ArcGeom, b: AABB): void => {\n addPointToBounds(b, pointOnArc(a, a.startAngle));\n addPointToBounds(b, pointOnArc(a, a.endAngle));\n for (const ang of [0, Math.PI / 2, Math.PI, (3 * Math.PI) / 2]) {\n if (angleInArc(a, ang)) addPointToBounds(b, pointOnArc(a, ang));\n }\n};\n\nconst curveBounds = (segments: Segment[], arcs: ArcGeom[]): AABB => {\n const bounds = emptyBounds();\n for (const s of segments) {\n addPointToBounds(bounds, s.a);\n addPointToBounds(bounds, s.b);\n }\n for (const a of arcs) arcBoundsInto(a, bounds);\n return bounds;\n};\n\nconst buildPolyline = (\n obj: Pick<Polyline, \"points\" | \"closed\">,\n): BuiltEntry => {\n const { segments, arcs } = verticesToCurves(obj.points, obj.closed);\n const points: SnapPoint[] = obj.points.map((v) => ({\n p: { x: v.x, y: v.y },\n type: \"endpoint\" as const,\n }));\n for (const s of segments) points.push({ p: mid(s.a, s.b), type: \"midpoint\" });\n for (const a of arcs) {\n points.push({ p: arcMidPoint(a), type: \"midpoint\" });\n points.push({ p: a.center, type: \"center\" });\n }\n return { bounds: curveBounds(segments, arcs), points, segments, arcs };\n};\n\nconst buildEllipse = (obj: Ellipse): BuiltEntry => {\n const pts = tessellateEllipse(obj);\n const segments: SnapSegment[] = [];\n for (let i = 1; i < pts.length; i++)\n segments.push({ a: pts[i - 1], b: pts[i], chord: true });\n const points: SnapPoint[] = [{ p: obj.center, type: \"center\" }];\n // Axis endpoints act as quadrants; range-filtered for partial ellipses.\n for (const t of [0, Math.PI / 2, Math.PI, (3 * Math.PI) / 2]) {\n if (paramInEllipse(obj, t))\n points.push({ p: pointOnEllipse(obj, t), type: \"quadrant\" });\n }\n if (!isFullEllipse(obj)) {\n points.push({ p: pointOnEllipse(obj, obj.startAngle), type: \"endpoint\" });\n points.push({ p: pointOnEllipse(obj, obj.endAngle), type: \"endpoint\" });\n }\n return {\n bounds: boundsOfPoints(pts),\n points,\n segments,\n arcs: [],\n ellipses: [\n {\n center: obj.center,\n majorAxis: obj.majorAxis,\n ratio: obj.ratio,\n startAngle: obj.startAngle,\n endAngle: obj.endAngle,\n },\n ],\n };\n};\n\nconst buildHatch = (obj: Hatch): BuiltEntry => {\n let bounds = emptyBounds();\n const points: SnapPoint[] = [];\n const segments: Segment[] = [];\n const arcs: ArcGeom[] = [];\n const rings: Vec2[][] = [];\n for (const loop of obj.loops) {\n const curves = verticesToCurves(loop.points, true);\n segments.push(...curves.segments);\n arcs.push(...curves.arcs);\n for (const v of loop.points)\n points.push({ p: { x: v.x, y: v.y }, type: \"endpoint\" });\n rings.push(verticesToPolygon(loop.points));\n bounds = unionBounds(bounds, curveBounds(curves.segments, curves.arcs));\n }\n return { bounds, points, segments, arcs, rings };\n};\n\nconst buildText = (\n obj: Text,\n measure: TextMeasurer,\n textStyles: readonly TextStyle[],\n): BuiltEntry => {\n // The text box: inside-clicks select (ring), edges support crossing select.\n // A visible frame is real, snappable geometry (snaps like a polyline): a\n // closed frame REPLACES the invisible box outline; a rule is added\n // alongside the box.\n const parts = textFrameGeometry(obj, measure, textStyles);\n const closed = parts.find((p) => p.closed);\n const box = textBoxCorners(obj, measure, textStyles);\n const outline = closed ? verticesToPolygon(closed.points) : box;\n const segments: Segment[] = closed\n ? []\n : box.map((c, i) => ({ a: c, b: box[(i + 1) % box.length] }));\n const points: SnapPoint[] = [{ p: obj.position, type: \"endpoint\" }];\n const arcs: ArcGeom[] = [];\n const bounds = boundsOfPoints(outline);\n for (const part of parts) {\n const e = buildPolyline(part);\n segments.push(...e.segments);\n arcs.push(...e.arcs);\n points.push(...e.points);\n addPointToBounds(bounds, { x: e.bounds.minX, y: e.bounds.minY });\n addPointToBounds(bounds, { x: e.bounds.maxX, y: e.bounds.maxY });\n }\n // Leader lines snap and hit-test like polylines.\n for (const line of obj.leaderLines) {\n for (let i = 1; i < line.length; i++) {\n segments.push({ a: line[i - 1], b: line[i] });\n }\n for (const p of line) {\n points.push({ p, type: \"endpoint\" });\n addPointToBounds(bounds, p);\n }\n }\n return {\n bounds,\n points,\n segments,\n arcs,\n rings: [outline],\n };\n};\n\nconst buildDimension = (\n obj: Dimension,\n dimStyles: readonly DimStyle[],\n measure: TextMeasurer,\n textStyles: readonly TextStyle[],\n): BuiltEntry => {\n const geom = dimensionGeometry(obj, dimStyles);\n const points: SnapPoint[] = obj.points.map((p) => ({\n p,\n type: \"endpoint\" as const,\n }));\n if (!geom) {\n return {\n bounds: boundsOfPoints(obj.points),\n points,\n segments: [],\n arcs: [],\n };\n }\n const segments = [...geom.extensionLines, ...geom.dimLines, ...geom.leaders];\n // The measurement text boxes: inside-clicks select the dimension (rings),\n // edges support crossing selection — same treatment as text objects.\n const rings: Vec2[][] = [];\n for (const text of geom.labels) {\n const corners = textBoxCorners(\n {\n type: \"text\",\n id: obj.id,\n layerId: obj.layerId,\n position: text.anchor,\n content: text.content,\n rotation: text.rotation,\n hAlign: \"center\",\n vAlign: \"center\",\n leaderLines: [],\n scale: 1,\n // The dim style's resolved metrics, pinned as overrides so the\n // document TEXT style can't leak into dimension text boxes.\n styleOverride: {\n textHeight: text.height,\n font: text.font,\n widthFactor: text.widthFactor,\n },\n },\n measure,\n textStyles,\n );\n rings.push(corners);\n segments.push(\n ...corners.map((c, i) => ({\n a: c,\n b: corners[(i + 1) % corners.length],\n })),\n );\n }\n const arcs = geom.dimArc\n ? [\n {\n center: geom.dimArc.center,\n radius: geom.dimArc.radius,\n startAngle: geom.dimArc.startAngle,\n endAngle: geom.dimArc.endAngle,\n },\n ]\n : [];\n const bounds = curveBounds(segments, arcs);\n for (const p of obj.points) addPointToBounds(bounds, p);\n for (const seg of geom.dimLines)\n points.push({ p: mid(seg.a, seg.b), type: \"midpoint\" });\n return { bounds, points, segments, arcs, rings };\n};\n\n/**\n * Derived snap/hit-test geometry for one object (without `pointBounds`, which\n * `buildSnapEntry` adds). Pure: pass `ctx` for the store-derived inputs.\n */\nexport const buildEntry = (\n obj: ModelObject,\n ctx: SnapGeometryContext,\n): BuiltEntry => {\n switch (obj.type) {\n case \"line\": {\n const bounds = emptyBounds();\n addPointToBounds(bounds, obj.a);\n addPointToBounds(bounds, obj.b);\n return {\n bounds,\n points: [\n { p: obj.a, type: \"endpoint\" },\n { p: obj.b, type: \"endpoint\" },\n { p: mid(obj.a, obj.b), type: \"midpoint\" },\n ],\n segments: [{ a: obj.a, b: obj.b }],\n arcs: [],\n };\n }\n case \"point\": {\n // One snap point (node); the degenerate segment is what makes the dot\n // click-pickable — distanceToObject only measures segments/arcs/rings.\n const bounds = emptyBounds();\n addPointToBounds(bounds, obj.p);\n return {\n bounds,\n points: [{ p: obj.p, type: \"endpoint\" }],\n segments: [{ a: obj.p, b: obj.p }],\n arcs: [],\n };\n }\n case \"polyline\":\n return buildPolyline(obj);\n case \"circle\": {\n const { center: center, radius } = obj;\n const bounds: AABB = {\n minX: center.x - radius,\n minY: center.y - radius,\n maxX: center.x + radius,\n maxY: center.y + radius,\n };\n const geom: ArcGeom = {\n center,\n radius,\n startAngle: 0,\n endAngle: Math.PI * 2 - 1e-9,\n };\n const quadrants: SnapPoint[] = [\n 0,\n Math.PI / 2,\n Math.PI,\n (3 * Math.PI) / 2,\n ].map((ang) => ({\n p: pointOnArc(geom, ang),\n type: \"quadrant\" as const,\n }));\n return {\n bounds,\n points: [{ p: center, type: \"center\" }, ...quadrants],\n segments: [],\n arcs: [geom],\n };\n }\n case \"arc\": {\n const geom: ArcGeom = {\n center: obj.center,\n radius: obj.radius,\n startAngle: normAngle(obj.startAngle),\n endAngle: normAngle(obj.endAngle),\n };\n const bounds = emptyBounds();\n arcBoundsInto(geom, bounds);\n return {\n bounds,\n points: [\n { p: pointOnArc(geom, geom.startAngle), type: \"endpoint\" },\n { p: pointOnArc(geom, geom.endAngle), type: \"endpoint\" },\n {\n p: pointOnArc(geom, geom.startAngle + arcSweep(geom) / 2),\n type: \"midpoint\",\n },\n { p: geom.center, type: \"center\" },\n ],\n segments: [],\n arcs: [geom],\n };\n }\n case \"ellipse\":\n return buildEllipse(obj);\n case \"hatch\":\n return buildHatch(obj);\n case \"text\":\n return buildText(obj, ctx.measure, ctx.textStyles);\n case \"dimension\":\n return buildDimension(obj, ctx.dimStyles, ctx.measure, ctx.textStyles);\n case \"viewport\": {\n // Frame corners/edges snap and hit-test; the interior ring makes\n // clicks inside the viewport select it (annotations still win —\n // pickObjectAt prefers non-viewport hits).\n const { x, y, w, h } = obj.rect;\n const corners: Vec2[] = [\n { x, y },\n { x: x + w, y },\n { x: x + w, y: y + h },\n { x, y: y + h },\n ];\n const segments: Segment[] = corners.map((c, i) => ({\n a: c,\n b: corners[(i + 1) % corners.length],\n }));\n const points: SnapPoint[] = corners.map((p) => ({\n p,\n type: \"endpoint\" as const,\n }));\n for (const s of segments)\n points.push({ p: mid(s.a, s.b), type: \"midpoint\" });\n return {\n bounds: { minX: x, minY: y, maxX: x + w, maxY: y + h },\n points,\n segments,\n arcs: [],\n rings: [corners],\n };\n }\n case \"block\": {\n // Merge the entries of the evaluated (world-space) children, so block\n // internals snap and hit-test exactly like native geometry.\n // Every point input snaps as an endpoint — the first one IS the\n // pivot (blockPivot falls back to {0,0} for point-less instances).\n const inputPoints = obj.inputs.filter(\n (v): v is Vec2 => typeof v !== \"string\",\n );\n const points: SnapPoint[] = (\n inputPoints.length > 0 ? inputPoints : [blockPivot(obj)]\n ).map((p) => ({ p, type: \"endpoint\" }));\n const segments: Segment[] = [];\n const arcs: ArcGeom[] = [];\n const ellipses: EllipseGeom[] = [];\n const rings: Vec2[][] = [];\n const regions: Vec2[][][] = [];\n let bounds = emptyBounds();\n for (const { p } of points) addPointToBounds(bounds, p);\n for (const child of getEvaluatedWorldChildren(\n obj,\n ctx.blockDefinitions,\n ctx.resolveObject,\n ctx, // its text / dim styles: what draw's `styles` reads\n )) {\n const entry = buildEntry(child, ctx);\n points.push(...entry.points);\n segments.push(...entry.segments);\n arcs.push(...entry.arcs);\n if (entry.ellipses) ellipses.push(...entry.ellipses);\n // Text/dimension boxes keep their inside-click hit area (rings).\n // Hatch fills become REGIONS — one even-odd set per hatch, ranked\n // by pickObjectAt like a top-level hatch, so a click on a hatched\n // block's pattern selects the block while geometry drawn over the\n // fill still wins. Nested blocks pass their regions up.\n // ponytail: rings merge under even-odd, so overlapping text boxes\n // cancel in the overlap — per-child ring sets if that ever matters.\n if (child.type === \"hatch\") {\n if (entry.rings && entry.rings.length > 0) regions.push(entry.rings);\n } else if (entry.rings) rings.push(...entry.rings);\n if (entry.regions) regions.push(...entry.regions);\n bounds = unionBounds(bounds, entry.bounds);\n }\n return { bounds, points, segments, arcs, ellipses, rings, regions };\n }\n case \"table\": {\n // The rules snap and hit-test like lines (endpoints at the grid\n // crossings they start/end on); the outline ring makes clicks\n // anywhere inside pick the table, like text.\n const { outline, children } = tableLayout(obj, ctx.textStyles);\n const segments: Segment[] = [];\n const points: SnapPoint[] = outline.map((p) => ({\n p,\n type: \"endpoint\" as const,\n }));\n for (const c of children) {\n if (c.type !== \"line\") continue;\n segments.push({ a: c.a, b: c.b });\n points.push({ p: c.a, type: \"endpoint\" }, { p: c.b, type: \"endpoint\" });\n }\n return {\n bounds: boundsOfPoints(outline),\n points,\n segments,\n arcs: [],\n rings: [outline],\n };\n }\n case \"comment\": {\n // Cache entries are camera-independent; the marker is screen-fixed, so\n // only the pin point lives here (tip snaps as an endpoint, marquees\n // catch the tip). The zoom-scaled bubble hit-test is the editor's\n // pickObjectAt special case.\n const bounds = emptyBounds();\n addPointToBounds(bounds, obj.position);\n return {\n bounds,\n points: [{ p: obj.position, type: \"endpoint\" }],\n segments: [{ a: obj.position, b: obj.position }],\n arcs: [],\n };\n }\n case \"reference\":\n return referenceEntry(obj, ctx);\n default: {\n // Every type has a case (a new one fails typecheck here); at runtime\n // an unknown type gets no snap geometry — empty bounds keeps it out\n // of queries.\n obj satisfies never;\n return { bounds: emptyBounds(), points: [], segments: [], arcs: [] };\n }\n }\n};\n\n/** A safety limit only: snapping and picking query a reference's geometry\n * through a spatial index (withNearIndex), so even a 10⁵–10⁶-segment site\n * plan stays fully snappable. Past this a file still draws, unsnapped. */\nexport const MAX_REFERENCE_SNAP_SEGMENTS = 2_000_000;\n\n/**\n * A reference snaps and picks by its CONTENT's geometry, placed by the\n * reference's transform (rotation + uniform scale + optional mirror keep\n * arcs arcs and ellipses ellipses). Deliberately no interior ring: like a\n * picture, geometry drawn over a reference stays hoverable. Not loaded → its\n * frame (last known extent, else a small square at the insertion point).\n */\nconst referenceEntry = (\n obj: Reference,\n ctx: SnapGeometryContext,\n): BuiltEntry => {\n // Switched off: out of every query (empty bounds), like an empty object.\n if (obj.hidden)\n return { bounds: emptyBounds(), points: [], segments: [], arcs: [] };\n const m = referenceTransform(obj);\n const content = ctx.resolveReference?.(obj) ?? null;\n if (!content) {\n const corners = placedCorners(\n m,\n obj.extent ?? {\n minX: 0,\n minY: 0,\n maxX: 5 / obj.scale,\n maxY: 5 / obj.scale,\n },\n );\n const segments = corners.map((a, i) => ({ a, b: corners[(i + 1) % 4] }));\n return {\n bounds: boundsOfPoints(corners),\n points: [\n ...corners.map((p) => ({ p, type: \"endpoint\" as const })),\n { p: obj.position, type: \"endpoint\" as const },\n ],\n segments,\n arcs: [],\n };\n }\n const s = obj.scale;\n const flip = obj.mirrored ? -1 : 1;\n // A file angle → host angle (mirroring reflects across the file's X axis).\n // A left-right flip maps a file angle t to π − t.\n const ang = (t: number) =>\n normAngle((flip < 0 ? Math.PI - t : t) + obj.rotation);\n const linear = (v: Vec2): Vec2 => {\n const o = applyMat(m, { x: 0, y: 0 });\n const p = applyMat(m, v);\n return { x: p.x - o.x, y: p.y - o.y };\n };\n const childCtx: SnapGeometryContext = {\n dimStyles: content.dimStyles,\n textStyles: content.textStyles,\n blockDefinitions: content.blockDefinitions,\n resolveObject: content.resolveObject,\n resolveReference: content.resolveReference,\n measure: ctx.measure,\n };\n const hidden = new Set(obj.hiddenLayers);\n const shown = new Map(\n content.layers.map((l) => [l.id, l.visible && !hidden.has(l.name)]),\n );\n const points: SnapPoint[] = [{ p: obj.position, type: \"endpoint\" }];\n const segments: SnapSegment[] = [];\n const arcs: ArcGeom[] = [];\n const ellipses: EllipseGeom[] = [];\n // A clip crops snapping like drawing. ponytail: curves snap only when\n // wholly inside the clip (no curve/box clipping) — clipped arcs still draw.\n const clip = obj.clip;\n const inClip = (p: Vec2) =>\n !clip ||\n (p.x >= clip.minX &&\n p.x <= clip.maxX &&\n p.y >= clip.minY &&\n p.y <= clip.maxY);\n const curveInClip = (c: Vec2, r: number) =>\n !clip ||\n (c.x - r >= clip.minX &&\n c.x + r <= clip.maxX &&\n c.y - r >= clip.minY &&\n c.y + r <= clip.maxY);\n /** Add one file-space entry, clipped and placed. */\n const add = (e: {\n points: readonly SnapPoint[];\n segments: readonly SnapSegment[];\n arcs: readonly ArcGeom[];\n ellipses?: readonly EllipseGeom[];\n }): void => {\n for (const sp of e.points)\n if (inClip(sp.p)) points.push({ p: applyMat(m, sp.p), type: sp.type });\n for (const seg of e.segments) {\n const kept = clip ? clipSegment(seg.a, seg.b, clip) : [seg.a, seg.b];\n if (kept)\n segments.push({\n a: applyMat(m, kept[0]),\n b: applyMat(m, kept[1]),\n chord: seg.chord,\n });\n }\n for (const a of e.arcs) {\n if (!curveInClip(a.center, a.radius)) continue;\n // Mirroring reverses the sweep: the CCW range swaps ends.\n const [start, end] =\n flip < 0 ? [a.endAngle, a.startAngle] : [a.startAngle, a.endAngle];\n arcs.push({\n center: applyMat(m, a.center),\n radius: a.radius * s,\n startAngle: ang(start),\n endAngle: ang(end),\n });\n }\n for (const el of e.ellipses ?? []) {\n if (!curveInClip(el.center, Math.hypot(el.majorAxis.x, el.majorAxis.y)))\n continue;\n const [start, end] =\n flip < 0\n ? [-el.endAngle, -el.startAngle]\n : [el.startAngle, el.endAngle];\n ellipses.push({\n center: applyMat(m, el.center),\n majorAxis: linear(el.majorAxis),\n ratio: el.ratio,\n startAngle: normAngle(start),\n endAngle: normAngle(end),\n });\n }\n };\n const layerShown = (layer: string) => shown.get(layer) !== false;\n if (content.snap) {\n // Precomputed off the main thread (and, for a raster PDF, the page's\n // vector lines under the image): filter by layer, clip, place.\n const f = content.snap;\n add({\n points: f.points.filter((p) => layerShown(p.layer)),\n segments: f.segments\n .filter((sg) => layerShown(sg.layer))\n .slice(0, MAX_REFERENCE_SNAP_SEGMENTS),\n arcs: f.arcs.filter((ar) => layerShown(ar.layer)),\n ellipses: f.ellipses.filter((el) => layerShown(el.layer)),\n });\n }\n for (const child of content.objects) {\n if (segments.length >= MAX_REFERENCE_SNAP_SEGMENTS) break;\n if (!layerShown(child.layerId)) continue;\n // With precomputed geometry only nested references are left to build.\n if (content.snap && child.type !== \"reference\") continue;\n add(buildEntry(child, childCtx));\n }\n const shownBounds = clip\n ? {\n minX: Math.max(content.bounds.minX, clip.minX),\n minY: Math.max(content.bounds.minY, clip.minY),\n maxX: Math.min(content.bounds.maxX, clip.maxX),\n maxY: Math.min(content.bounds.maxY, clip.maxY),\n }\n : content.bounds;\n const bounds =\n isEmptyBounds(shownBounds) || shownBounds.minX > shownBounds.maxX\n ? boundsOfPoints(points.map((p) => p.p))\n : placedBounds(m, shownBounds);\n return { bounds, points, segments, arcs, ellipses };\n};\n\n/**\n * Full snap-cache entry for an object: `buildEntry` plus the `pointBounds`\n * query box (bounds unioned with every snap point, so off-curve points like\n * an arc's center still fall inside the candidate box). Pure — the caller\n * owns caching and invalidation.\n */\nexport const buildSnapEntry = (\n obj: ModelObject,\n ctx: SnapGeometryContext,\n): SnapCacheEntry => {\n const built = buildEntry(obj, ctx);\n const pointBounds = { ...built.bounds };\n for (const sp of built.points) addPointToBounds(pointBounds, sp.p);\n // A reference can carry a whole site plan: answer \"near the cursor\" from\n // a spatial index instead of scanning it all (SnapCacheEntry.near).\n return obj.type === \"reference\"\n ? withNearIndex({ ...built, pointBounds })\n : { ...built, pointBounds };\n};\n","// DXF import: parse, scale to mm ($INSUNITS), create missing layers, convert\n// entities, add everything in ONE undoable transaction. Paper space comes\n// back too: *Paper_Space blocks (+ the flat inPaperSpace entities of the\n// active layout) are rebuilt as PaperLayouts, VIEWPORT entities become\n// viewport objects, and LAYOUT objects (parsed from the raw OBJECTS section\n// — dxf-parser skips it) supply names, tab order, and sheet sizes.\n\nimport DxfParser from \"dxf-parser\";\nimport type { IEntity, IDxf, IBlock } from \"dxf-parser\";\nimport type {\n DimStyle,\n ModelObject,\n ModelObjectDto,\n PolylineVertex,\n TextStyle,\n} from \"../../model/objects\";\nimport {\n DEFAULT_DIM_STYLE,\n DEFAULT_TEXT_STYLE,\n ModelObjectSchema,\n} from \"../../model/objects\";\nimport {\n dimStyleFromRecord,\n dimValuesFromGroups,\n emptyStyleRecord,\n mergeStyles,\n overrideAgainst,\n sameDimStyle,\n sameTextStyle,\n textStyleFromRecord,\n type DimStyleRecord,\n type DimValues,\n type HeightHistogram,\n type StyleRecord,\n} from \"./styleTables\";\nimport {\n dimensionRawToLabels,\n dimensionRawToOffset,\n} from \"../../model/migrations\";\nimport * as v2 from \"../../geometry/vec2\";\nimport {\n interpolateFitPoints,\n isValidNurbs,\n sampleNurbs,\n type NurbsCurve,\n} from \"../../geometry/nurbs\";\nimport { polylineBand } from \"../../geometry/band\";\nimport {\n blockDefinitionModule,\n type ImportedBlockDefinition,\n} from \"./blockDefinitions\";\nimport { linearAxis } from \"../../paint/dimensionGeometry\";\nimport type { Layer } from \"../../model/document\";\nimport type { PaperLayout } from \"../../model/paperLayout\";\nimport { PaperLayoutSchema } from \"../../model/paperLayout\";\nimport {\n bump,\n emptyLedger,\n total,\n reconcileLedger,\n scanEntityHistogram,\n type ImportLedger,\n} from \"./entityLedger\";\nimport type { Vec2 } from \"../../geometry/vec2\";\nimport { dist } from \"../../geometry/vec2\";\nimport {\n arcEndPoint,\n arcFrom3Points,\n arcMidPoint,\n arcStartPoint,\n bulgeFrom3Points,\n bulgeToArc,\n} from \"../../geometry/arcs\";\nimport { aciToHex, hexToRgb, rgbToHex } from \"../../export/dxf/aci\";\nimport { normalizeSpans } from \"../../paint/richText\";\nimport {\n cleanText,\n decodeTextEscapes,\n lineWeightToMm,\n cleanRichText,\n mtextFontFlags,\n mtextWidthFactor,\n} from \"../../export/dxf/codecs\";\nimport {\n getHatchPattern,\n hatchPatternKey,\n type DocumentHatchPattern,\n} from \"../../model/hatchPatterns\";\nimport { getLineType, lineTypeKey, type LineType } from \"../../model/lineTypes\";\nimport {\n ViewportHandler,\n HatchHandler,\n AcadTableHandler,\n type AcadTableData,\n LeaderHandler,\n MultiLeaderHandler,\n AttribHandler,\n MlineHandler,\n TraceHandler,\n} from \"./extraEntities\";\nimport {\n parseLayoutObjects,\n parseMlineStyles,\n type DxfMlineStyle,\n} from \"./objectsSection\";\nimport { referenceFormatOf } from \"../../reference/reference\";\nimport { dxfLines } from \"./dxfLines\";\n\nconst DEG2RAD = Math.PI / 180;\n\n/** Zoom-lock bit of the VIEWPORT status flags (group 90). */\n/** Group 90 bit: the viewport is turned off. */\nconst VIEWPORT_OFF_FLAG = 0x20000;\nconst VIEWPORT_LOCKED_FLAG = 16384;\n\n/** mm per drawing unit, from $INSUNITS. */\nconst unitFactor = (insunits: unknown): number => {\n switch (insunits) {\n case 1:\n return 25.4; // inches\n case 2:\n return 304.8; // feet\n case 5:\n return 10; // cm\n case 6:\n return 1000; // m\n case 4:\n case 0:\n default:\n return 1; // mm / unspecified\n }\n};\n\n/** Lineweight every imported layer/entity gets (DXF weights aren't read). */\nconst IMPORT_LINE_WIDTH_MM = 0.25;\n/** Chord tolerance for sampling SPLINE curves into polylines (world mm). */\nconst SPLINE_TOLERANCE_MM = 0.02;\n\ninterface ImportContext extends ImportLedger {\n f: number;\n layerIdByName: Map<string, string>;\n /** Layers whose line type dashes — their entities inherit a dash pattern,\n * so group 48 conversion applies even without an entity-level line type. */\n dashedLayerIds: Set<string>;\n defaultLayerId: string;\n /** The document's styles after the merge, by id — what an entity's\n * override is relative to. */\n textStyleById: Map<string, TextStyle>;\n dimStyleById: Map<string, DimStyle>;\n /** DXF style name (lower-cased) → document style id. */\n textStyleIdByName: Map<string, string>;\n dimStyleIdByName: Map<string, string>;\n /** Each merged dim style's DIMSCALE — ours is the object's `scale`. */\n dimScaleByStyleId: Map<string, number>;\n /** What an unstyled entity follows: the document's first style. */\n defaultTextStyle: TextStyle;\n defaultDimStyle: DimStyle;\n /** DIMSTYLE groups → values, bound to this file's tables (for the\n * per-dimension DSTYLE xdata overrides). */\n dimValuesFrom: (groups: Map<number, string>) => DimValues;\n /** Overall dimension scale ($DIMSCALE); 1 = none. Applied to dimensions\n * whose own style the file does not define. */\n dimScale: number;\n /** Global line type scale ($LTSCALE); 1 = none. */\n ltScale: number;\n /** LAYER record handle → name, to resolve a viewport's frozen layers (331). */\n layerNameByHandle: Map<string, string>;\n /** Groups dxf-parser drops or mangles, read off the raw tag stream. */\n tags: RawTags;\n /** MLINESTYLE objects, for MLINE caps and the no-parameter fallback. */\n mlineStyles: ReturnType<typeof parseMlineStyles>;\n /** The file's LTYPE definitions the catalogue lacks, by name key — a\n * document line type is created on first use (`usedLineTypes`). */\n customLineTypes: Map<string, LineType>;\n usedLineTypes: Map<string, LineType>;\n /** Document hatch patterns rebuilt from HATCH definition lines, by key\n * (first definition of a name wins). */\n hatchPatterns: Map<string, DocumentHatchPattern>;\n /** Block definitions generated for INSERTs, by upper-cased block name:\n * null = this block explodes (mixed layers, no visible geometry). */\n blockDefinitions: Map<string, ImportedBlockDefinition | null>;\n /** The generated modules the document lacks, in first-use order. */\n newBlockDefinitions: ImportedBlockDefinition[];\n /** The document's block modules (id + name). */\n existingBlocks: readonly { id: string; name: string }[];\n /** Lineweight (mm) of each layer created by this import — the width an\n * inherited dash pattern scales by. */\n layerWidthById: Map<string, number>;\n /** Color of each layer created by this import (existing layers arrive\n * as id + name only) — what a ByBlock child of a ByLayer insert, or a\n * ByLayer child on its own layer inside a definition, bakes to. */\n layerColorById: Map<string, string>;\n}\n\n/** LAYER table groups dxf-parser leaves unread. */\ninterface LayerTags {\n handle?: string;\n lineType?: string;\n /** Group 370 in 1/100 mm; negative = default. */\n lineWeight?: number;\n locked?: boolean;\n plot?: boolean;\n}\n\ninterface RawTags {\n /** Exact colors (group 420) by entity handle. */\n trueColorByHandle: Map<string, string>;\n trueColorByLayerName: Map<string, string>;\n /** Entity lineweight (370, 1/100 mm; −1 ByLayer, −2 ByBlock, −3 default). */\n lineWeightByHandle: Map<string, number>;\n /** Entities whose extrusion (230) points down: their OCS x axis is the\n * mirror of the world's. */\n mirroredHandles: Set<string>;\n layers: Map<string, LayerTags>;\n /** STYLE table records by name (shape files left out) and by handle. */\n textStyles: Map<string, StyleRecord>;\n textStyleByHandle: Map<string, StyleRecord>;\n /** DIMSTYLE table records by name. */\n dimStyles: Map<string, DimStyleRecord>;\n /** BLOCK_RECORD name by handle (arrowhead blocks). */\n blockNameByHandle: Map<string, string>;\n /** TEXT / MTEXT / ATTRIB / ATTDEF group 7 (style name) by entity handle. */\n textStyleNameByHandle: Map<string, string>;\n /** DIMENSION / LEADER group 3 (dim style name) by entity handle. */\n dimStyleNameByHandle: Map<string, string>;\n /** DIMENSION DSTYLE xdata: DIMSTYLE group → value, by entity handle. */\n dimOverridesByHandle: Map<string, Map<number, string>>;\n /** Per text style name (lower-cased; \"\" = the default), the heights its\n * texts use — the style's height when the record fixes none. */\n textHeightsByStyle: Map<string, HeightHistogram>;\n /** SPLINE weights (41, one per control point) by handle — dxf-parser\n * drops them, and a rational spline (a circle as NURBS) needs them. */\n splineWeightsByHandle: Map<string, number[]>;\n}\n\n/** Entity types whose group 7 names a text style. */\nconst TEXT_TYPES = new Set([\"TEXT\", \"MTEXT\", \"ATTRIB\", \"ATTDEF\"]);\n/** Entity types whose group 3 names a dimension style. */\nconst DIM_TYPES = new Set([\"DIMENSION\", \"LEADER\"]);\n\n/**\n * One pass over the raw tag stream for what dxf-parser cannot give us. It\n * applies group codes last-wins, so a 62 written AFTER a 420 (our own\n * writer's order) clobbers the exact color; its LAYER table parser reads\n * only name, color and flags (no line type, lineweight, plot flag); its\n * custom-handler entities (hatch, leaders, tables) never see 370; and only\n * some of its handlers expose the extrusion direction.\n */\nconst scanTags = (lines: readonly string[]): RawTags => {\n const out: RawTags = {\n trueColorByHandle: new Map(),\n trueColorByLayerName: new Map(),\n lineWeightByHandle: new Map(),\n mirroredHandles: new Set(),\n layers: new Map(),\n textStyles: new Map(),\n textStyleByHandle: new Map(),\n dimStyles: new Map(),\n blockNameByHandle: new Map(),\n textStyleNameByHandle: new Map(),\n dimStyleNameByHandle: new Map(),\n dimOverridesByHandle: new Map(),\n textHeightsByStyle: new Map(),\n splineWeightsByHandle: new Map(),\n };\n const hex24 = (value: string): string | undefined => {\n const v = Number(value);\n return Number.isFinite(v)\n ? rgbToHex((v >> 16) & 0xff, (v >> 8) & 0xff, v & 0xff)\n : undefined;\n };\n let type = \"\";\n let handle = \"\";\n let name = \"\";\n let layer: LayerTags | null = null;\n let style: StyleRecord | null = null;\n let dim: DimStyleRecord | null = null;\n // Text entity: style (7) + height (40) land in the histogram at its end.\n let textStyle = \"\";\n let textHeight = 0;\n // xdata state: the application after 1001; a DIMENSION's ACAD DSTYLE\n // block is `1000 DSTYLE / 1002 { / (1070 code, value)… / 1002 }`.\n let xApp = \"\";\n let dstyleArmed = false;\n let dstyle: Map<number, string> | null = null;\n let pendingCode: number | undefined;\n const flushText = () => {\n if (TEXT_TYPES.has(type) && textHeight > 0) {\n const key = textStyle.toLowerCase();\n let hist = out.textHeightsByStyle.get(key);\n if (!hist) out.textHeightsByStyle.set(key, (hist = new Map()));\n hist.set(textHeight, (hist.get(textHeight) ?? 0) + 1);\n }\n textStyle = \"\";\n textHeight = 0;\n };\n for (let i = 0; i + 1 < lines.length; i += 2) {\n const code = lines[i].trim();\n const value = lines[i + 1].trim();\n if (code === \"0\") {\n flushText();\n type = value;\n handle = \"\";\n name = \"\";\n layer = value === \"LAYER\" ? {} : null;\n style = value === \"STYLE\" ? emptyStyleRecord() : null;\n dim = value === \"DIMSTYLE\" ? { name: \"\", groups: new Map() } : null;\n xApp = \"\";\n dstyleArmed = false;\n dstyle = null;\n pendingCode = undefined;\n } else if (code === \"1001\") {\n xApp = value;\n dstyleArmed = false;\n dstyle = null;\n pendingCode = undefined;\n } else if (xApp) {\n // Extended data (1000–1071) closes a record; only two kinds matter.\n if (style) {\n if (code === \"1000\") style.typeface = value;\n else if (code === \"1071\") style.flags = Number(value) || 0;\n } else if (xApp === \"ACAD\" && type === \"DIMENSION\") {\n if (code === \"1000\" && value === \"DSTYLE\") dstyleArmed = true;\n else if (code === \"1002\" && value === \"{\" && dstyleArmed)\n dstyle = new Map();\n else if (code === \"1002\" && value === \"}\") {\n if (dstyle && handle) out.dimOverridesByHandle.set(handle, dstyle);\n dstyle = null;\n dstyleArmed = false;\n } else if (dstyle) {\n if (pendingCode === undefined) {\n if (code === \"1070\") pendingCode = Number(value);\n } else {\n dstyle.set(pendingCode, value);\n pendingCode = undefined;\n }\n }\n }\n } else if (dim) {\n // DIMSTYLE: 105 is the handle; 5/6/7 are the R12 arrow block NAMES.\n if (code === \"105\") dim.handle = value;\n else if (code === \"2\") {\n dim.name = value;\n out.dimStyles.set(value, dim);\n } else if (code !== \"100\" && code !== \"330\" && code !== \"70\")\n dim.groups.set(Number(code), value);\n } else if (code === \"5\") {\n handle = value;\n if (layer) layer.handle = value;\n if (style) style.handle = value;\n } else if (code === \"2\") {\n name = value;\n if (layer) out.layers.set(name, layer);\n if (type === \"BLOCK_RECORD\" && handle)\n out.blockNameByHandle.set(handle.toUpperCase(), value);\n } else if (style) {\n if (code === \"2\") style.name = value;\n else if (code === \"3\") style.fontFile = value;\n else if (code === \"40\") style.fixedHeight = Number(value) || 0;\n else if (code === \"41\") style.widthFactor = Number(value) || 1;\n else if (code === \"50\") style.oblique = Number(value) || 0;\n else if (code === \"70\") {\n style.shape = (Number(value) & 1) !== 0;\n if (!style.shape && name) {\n style.name = name;\n out.textStyles.set(name, style);\n if (style.handle)\n out.textStyleByHandle.set(style.handle.toUpperCase(), style);\n }\n }\n } else if (layer) {\n if (code === \"6\") layer.lineType = value;\n else if (code === \"70\") layer.locked = (Number(value) & 4) !== 0;\n else if (code === \"290\") layer.plot = value !== \"0\";\n else if (code === \"370\") layer.lineWeight = Number(value);\n else if (code === \"420\" && name) {\n const hex = hex24(value);\n if (hex) out.trueColorByLayerName.set(name, hex);\n }\n } else if (handle) {\n if (code === \"420\") {\n const hex = hex24(value);\n if (hex) out.trueColorByHandle.set(handle, hex);\n } else if (code === \"370\") {\n const v = Number(value);\n if (Number.isFinite(v)) out.lineWeightByHandle.set(handle, v);\n } else if (code === \"230\" && Number(value) < 0) {\n out.mirroredHandles.add(handle);\n } else if (code === \"7\" && TEXT_TYPES.has(type)) {\n out.textStyleNameByHandle.set(handle, value);\n textStyle = value;\n } else if (code === \"40\" && TEXT_TYPES.has(type)) {\n textHeight = Number(value) || 0;\n } else if (code === \"3\" && DIM_TYPES.has(type)) {\n out.dimStyleNameByHandle.set(handle, value);\n } else if (code === \"41\" && type === \"SPLINE\") {\n let weights = out.splineWeightsByHandle.get(handle);\n if (!weights) out.splineWeightsByHandle.set(handle, (weights = []));\n weights.push(Number(value));\n }\n }\n }\n flushText();\n return out;\n};\n\n// dxf-parser's types are loose; a pragmatic any-view keeps readers readable.\n/* eslint-disable @typescript-eslint/no-explicit-any */\n\nconst pt = (p: { x: number; y: number }, f: number): Vec2 => ({\n x: p.x * f,\n y: p.y * f,\n});\n\n/**\n * Map a DXF linetype name onto our named library. Prefers an exact match\n * (case/punctuation-insensitive — ACAD names, ISO, JIS); the acad `NAME2` /\n * `NAMEX2` scale-variant convention resolves to the BASE type with the\n * variant's factor (0.5 / 2) reported so callers fold it into\n * lineTypeScale — the library stores only base patterns. Unknown names fall\n * back to a substring heuristic onto the curated set.\n * ByLayer / Continuous / unknown → undefined.\n */\nconst lineTypeFromDxf = (\n name: unknown,\n /** The file's own LTYPE definitions (document line types on first use). */\n custom?: Pick<ImportContext, \"customLineTypes\" | \"usedLineTypes\">,\n): { name: string; factor: number } | undefined => {\n if (typeof name !== \"string\") return undefined;\n const n = name.trim();\n if (!n || /^(bylayer|byblock|continuous)$/i.test(n)) return undefined;\n const own = custom?.customLineTypes.get(lineTypeKey(n));\n if (own) {\n custom!.usedLineTypes.set(lineTypeKey(own.name), own);\n return { name: own.name, factor: 1 };\n }\n const match = getLineType(n);\n if (match) return { name: match.name, factor: 1 };\n // acad scale variants: DASHED2 = half, DASHEDX2 = double.\n const variant = /x2$/i.test(n)\n ? { base: n.slice(0, -2), factor: 2 }\n : /2$/.test(n)\n ? { base: n.slice(0, -1), factor: 0.5 }\n : undefined;\n if (variant) {\n const baseMatch = getLineType(variant.base);\n if (baseMatch) return { name: baseMatch.name, factor: variant.factor };\n }\n const u = n.toUpperCase();\n const heuristic = u.includes(\"PHANTOM\")\n ? \"phantom\"\n : u.includes(\"DASHDOT\") || u.includes(\"DASH_DOT\")\n ? \"dashdot\"\n : u.includes(\"CENTER\") || u.includes(\"CENTRE\")\n ? \"center\"\n : u.includes(\"HIDDEN\")\n ? \"hidden\"\n : u.includes(\"DASH\")\n ? \"dashed\"\n : u.includes(\"DOT\")\n ? \"dotted\"\n : undefined;\n return heuristic ? { name: heuristic, factor: 1 } : undefined;\n};\n\nconst baseFor = (e: IEntity, ctx: ImportContext) => {\n const layerId =\n ctx.layerIdByName.get(e.layer?.toLowerCase()) ?? ctx.defaultLayerId;\n const anyE = e as any;\n // Resolve the entity's own color. dxf-parser resolves built-in entities'\n // ACI/true-color into a 24-bit `color`; our custom handlers (hatch, leader,\n // multileader, viewport) only carry `colorIndex`/`trueColor`, so resolve\n // those too. ByLayer (256) / ByBlock (0) / absent → inherit from the layer.\n const rgb24 = (v: number) =>\n rgbToHex((v >> 16) & 0xff, (v >> 8) & 0xff, v & 0xff);\n const ci = anyE.colorIndex;\n const scanned = ctx.tags.trueColorByHandle.get(String(anyE.handle));\n const color =\n typeof anyE.trueColor === \"number\"\n ? rgb24(anyE.trueColor)\n : scanned !== undefined\n ? scanned\n : // ci 0 = ByBlock: dxf-parser pre-resolves it to BLACK in `color`,\n // so it must be excluded like ByLayer. Approximated as inherit-\n // from-layer (exact only when the reference itself has no color —\n // true for tables; an explicitly colored INSERT's ByBlock children\n // would need the reference color threaded through convertInsert).\n typeof anyE.color === \"number\" &&\n ci !== 256 &&\n ci !== 0 &&\n ci !== undefined\n ? rgb24(anyE.color)\n : typeof ci === \"number\"\n ? aciToHex(ci) // undefined for 0/256 (inherit)\n : undefined;\n const resolved = lineTypeFromDxf(anyE.lineType, ctx);\n const lineType = resolved?.name;\n // Lineweight (370): an explicit value becomes the object's own width;\n // ByLayer / ByBlock / default inherit.\n const lineWidth = lineWeightToMm(\n ctx.tags.lineWeightByHandle.get(String(anyE.handle)),\n );\n // Group 48 (CELTSCALE). We render dashes width-proportionally while DXF\n // consumers render pattern × 48 — so divide by the width the entity will\n // resolve to (its own 370, else its layer's, else the 0.25 mm default) to\n // keep AutoCAD's dash lengths (export multiplies the width back in, so\n // round-trips are exact). A 2/X2 scale-variant LTYPE name multiplies on\n // top (the variant resolved to its base pattern). Only entities whose\n // effective line type dashes get the field stamped.\n const raw48 =\n typeof anyE.lineTypeScale === \"number\" && anyE.lineTypeScale > 0\n ? anyE.lineTypeScale\n : 1;\n const widthMm =\n lineWidth ?? ctx.layerWidthById.get(layerId) ?? IMPORT_LINE_WIDTH_MM;\n const scale = ((raw48 * ctx.ltScale) / widthMm) * (resolved?.factor ?? 1);\n const dashed = lineType !== undefined || ctx.dashedLayerIds.has(layerId);\n const lineTypeScale = dashed && scale !== 1 ? scale : undefined;\n return {\n layerId,\n color,\n lineType,\n lineTypeScale,\n ...(lineWidth !== undefined ? { lineWidth } : {}),\n hidden: false,\n };\n};\n\n/** Hatch boundary path (from the custom handler) → polyline loop points. */\nconst hatchLoopPoints = (\n path: any,\n f: number,\n mirrored: boolean,\n): PolylineVertex[] => {\n const points = hatchLoopPointsOcs(path, f);\n return mirrored\n ? points.map((p) => ({ x: -p.x, y: p.y, bulge: -p.bulge }))\n : points;\n};\n\n/** Max chord deviation (mm) when an ellipse edge is sampled into a loop. */\nconst HATCH_ELLIPSE_TOLERANCE_MM = 0.1;\n\nconst hatchLoopPointsOcs = (path: any, f: number): PolylineVertex[] => {\n if (path.isPolyline) {\n return (path.vertices ?? []).map((v: any) => ({\n x: v.x * f,\n y: v.y * f,\n bulge: v.bulge ?? 0,\n }));\n }\n // Edge form: edges are contiguous, so each contributes its START (and\n // interior samples) — the next edge's start is its end, and the loop\n // closes back to the first. Arcs contribute a bulge; ellipse and spline\n // edges are sampled within tolerance.\n const points: PolylineVertex[] = [];\n const push = (x: number, y: number, bulge = 0) =>\n points.push({ x: x * f, y: y * f, bulge });\n for (const edge of path.edges ?? []) {\n switch (edge.kind) {\n case 1: {\n // Line: 10 = start (11 = end, supplied by the next edge's start).\n const p = edge.points[0];\n if (p) push(p.x, p.y);\n break;\n }\n case 2: {\n // Arc: 10 center, 40 radius, 50/51 angles in degrees, 73 ccw. A\n // CLOCKWISE arc (73 = 0) has its angles measured clockwise — the\n // arc runs from −start to −end (AutoCAD's convention, verified on\n // its own files: the end meets the next edge's start). Sweeps past\n // 180° split in two so a full circle becomes two half-arcs.\n const c = edge.points[0];\n if (!c || !(edge.r40 > 0)) break;\n const ccw = edge.ccw !== false;\n const a0 = (edge.startAngle ?? 0) * DEG2RAD;\n let a1 = (edge.endAngle ?? 360) * DEG2RAD;\n if (a1 <= a0 + 1e-12) a1 += Math.PI * 2;\n const sweep = Math.min(a1 - a0, Math.PI * 2);\n const sign = ccw ? 1 : -1;\n const start = sign * a0;\n const pieces = sweep > Math.PI + 1e-9 ? 2 : 1;\n const bulge = sign * Math.tan(sweep / pieces / 4);\n for (let i = 0; i < pieces; i++) {\n const ang = start + (sign * sweep * i) / pieces;\n push(\n c.x + edge.r40 * Math.cos(ang),\n c.y + edge.r40 * Math.sin(ang),\n bulge,\n );\n }\n break;\n }\n case 3: {\n // Elliptic arc: 10 center, 11 major-axis endpoint relative to the\n // center, 40 minor/major ratio, 50/51 TRUE angles (degrees, from\n // the major axis — not ellipse parameters), 73 ccw with the same\n // negation rule as arcs. Sampled so the chord error stays under\n // tolerance for the major radius.\n const c = edge.points[0];\n const major = edge.end;\n if (!c || !major) break;\n const ratio = edge.r40 > 0 ? edge.r40 : 1;\n const ccw = edge.ccw !== false;\n const a0 = (edge.startAngle ?? 0) * DEG2RAD;\n let a1 = (edge.endAngle ?? 360) * DEG2RAD;\n if (a1 <= a0 + 1e-12) a1 += Math.PI * 2;\n const sweep = Math.min(a1 - a0, Math.PI * 2);\n const sign = ccw ? 1 : -1;\n const L = Math.hypot(major.x, major.y);\n const tol = HATCH_ELLIPSE_TOLERANCE_MM / f;\n const maxStep =\n L <= tol ? sweep : 2 * Math.acos(Math.max(-1, 1 - tol / L));\n const n = Math.max(8, Math.ceil(sweep / Math.max(maxStep, 1e-3)));\n for (let i = 0; i < n; i++) {\n const theta = sign * (a0 + (sweep * i) / n);\n // True angle (from the major axis) → ellipse parameter.\n const t = Math.atan2(Math.sin(theta) / ratio, Math.cos(theta));\n push(\n c.x + major.x * Math.cos(t) - major.y * ratio * Math.sin(t),\n c.y + major.y * Math.cos(t) + major.x * ratio * Math.sin(t),\n );\n }\n break;\n }\n case 4: {\n // Spline: the curve itself when the control data is complete, else\n // the cubic through its fit points, else the control polygon — the\n // same ladder as the SPLINE entity.\n const control: Vec2[] = (edge.points ?? []).map((p: any) => ({\n x: p.x,\n y: p.y,\n }));\n const weights: number[] = edge.weights ?? [];\n const curve: NurbsCurve = {\n degree: edge.degree ?? 3,\n controlPoints: control,\n knots: edge.knots ?? [],\n ...(edge.rational && weights.length === control.length\n ? { weights }\n : {}),\n };\n const fit: Vec2[] = (edge.fitPoints ?? []).map((p: any) => ({\n x: p.x,\n y: p.y,\n }));\n const fitted = isValidNurbs(curve) ? null : interpolateFitPoints(fit);\n const sampled = isValidNurbs(curve)\n ? sampleNurbs(curve, SPLINE_TOLERANCE_MM / f)\n : fitted\n ? sampleNurbs(fitted, SPLINE_TOLERANCE_MM / f)\n : fit.length >= 2\n ? fit\n : control;\n // All but the end point — the next edge starts there.\n for (const p of sampled.slice(0, -1)) push(p.x, p.y);\n break;\n }\n }\n }\n // Consecutive duplicates (a writer repeating a shared vertex) would add\n // zero-length segments.\n return points.filter(\n (p, i) =>\n i === 0 ||\n Math.abs(p.x - points[i - 1].x) > 1e-9 ||\n Math.abs(p.y - points[i - 1].y) > 1e-9 ||\n points[i - 1].bulge !== 0,\n );\n};\n\n/** A two-vertex loop whose segments bulge is a closed shape (a circle as two\n * half-arcs, a lens, a \"D\") — the model wants three vertices per loop, so\n * each bulged segment splits at its arc midpoint into two quarter-bulges.\n * Anything else with fewer than three vertices stays as is (and is dropped). */\nconst atLeastThreeVertices = (points: PolylineVertex[]): PolylineVertex[] => {\n if (points.length !== 2 || points.every((p) => p.bulge === 0)) return points;\n const out: PolylineVertex[] = [];\n for (let i = 0; i < 2; i++) {\n const a = points[i];\n const b = points[1 - i];\n out.push(a);\n const arc = a.bulge === 0 ? null : bulgeToArc(a, b, a.bulge);\n if (!arc) continue;\n const half = Math.tan(Math.atan(a.bulge) / 2); // tan(θ/8), θ = 4·atan(bulge)\n const mid = arcMidPoint(arc);\n out[out.length - 1] = { ...a, bulge: half };\n out.push({ x: mid.x, y: mid.y, bulge: half });\n }\n return out;\n};\n\nconst convertHatch = (e: IEntity, ctx: ImportContext): ModelObjectDto[] => {\n const anyE = e as any;\n const base = baseFor(e, ctx);\n const mirrored = ctx.tags.mirroredHandles.has(String(anyE.handle));\n const flip = mirrored ? -1 : 1; // pattern angles mirror with the OCS\n const loops = (anyE.boundaryPaths ?? [])\n .map((path: any) => ({\n points: atLeastThreeVertices(hatchLoopPoints(path, ctx.f, mirrored)),\n }))\n .filter((loop: { points: PolylineVertex[] }) => loop.points.length >= 3);\n if (loops.length === 0) return [];\n\n let fill:\n | { kind: \"solid\" }\n | { kind: \"lines\"; angle: number; spacing: number }\n | {\n kind: \"pattern\";\n name: string;\n angle: number;\n scale: number;\n origin?: Vec2;\n }\n | {\n kind: \"gradient\";\n shape: \"linear\" | \"radial\";\n color1: string;\n color2: string;\n angle: number;\n };\n const patternMatch =\n typeof anyE.patternName === \"string\"\n ? getHatchPattern(anyE.patternName)\n : undefined;\n const gradient = anyE.gradient;\n if (gradient) {\n // Two colors (or one color fading to its tint): spherical shapes are\n // our radial, every other AutoCAD shape reads as linear along 460.\n const colors: string[] = (gradient.colors ?? [])\n .map((c: { aci?: number; rgb?: number }) =>\n typeof c.rgb === \"number\"\n ? rgbToHex((c.rgb >> 16) & 0xff, (c.rgb >> 8) & 0xff, c.rgb & 0xff)\n : typeof c.aci === \"number\"\n ? aciToHex(c.aci)\n : undefined,\n )\n .filter((c: string | undefined): c is string => c !== undefined);\n const color1 = colors[0] ?? \"#808080\";\n const color2 =\n !gradient.oneColor && colors[1] !== undefined\n ? colors[1]\n : mixHex(color1, \"#ffffff\", gradient.tint ?? 1);\n fill = {\n kind: \"gradient\",\n shape: /spherical/i.test(gradient.name ?? \"\") ? \"radial\" : \"linear\",\n color1,\n color2,\n angle: (gradient.angle ?? 0) * flip,\n };\n } else if (anyE.solid || anyE.patternName === \"SOLID\") {\n fill = { kind: \"solid\" };\n } else if (patternMatch) {\n // A recognized built-in pattern (including ANSI31) → carry it losslessly as\n // a named pattern fill. The DXF pattern angle (code 52) and scale (code 41)\n // are the pattern's rotation/scale, matching the export mapping.\n const angle52 = (anyE.patternAngle ?? 0) * DEG2RAD;\n const scaleMm = (anyE.patternScale || 1) * ctx.f;\n fill = {\n kind: \"pattern\",\n name: patternMatch.name,\n angle: angle52 * flip,\n scale: scaleMm,\n };\n // The hatch's own origin (HPORIGIN) is folded into the baked 43/44 of\n // every definition line: the first line's base, less the catalogue\n // line's own origin baked the same way, is the fill's anchor.\n const first = anyE.patternLines?.[0];\n if (first && !mirrored) {\n const lineAngle = (first.angle ?? 0) * DEG2RAD - angle52;\n const own = patternMatch.lines.reduce<\n (typeof patternMatch.lines)[number] | null\n >(\n (best, l) =>\n best === null ||\n Math.abs(lineAngleDiff(l.angle, lineAngle)) <\n Math.abs(lineAngleDiff(best.angle, lineAngle))\n ? l\n : best,\n null,\n )?.origin ?? { x: 0, y: 0 };\n const cos = Math.cos(angle52);\n const sin = Math.sin(angle52);\n const anchor = {\n x: (first.baseX ?? 0) * ctx.f - (cos * own.x - sin * own.y) * scaleMm,\n y: (first.baseY ?? 0) * ctx.f - (sin * own.x + cos * own.y) * scaleMm,\n };\n if (Math.hypot(anchor.x, anchor.y) > 1e-6)\n fill = { ...fill, origin: anchor };\n }\n } else if (\n !anyE.solid &&\n typeof anyE.patternName === \"string\" &&\n anyE.patternName.trim() &&\n (anyE.patternLines?.length ?? 0) > 0 &&\n !mirrored\n ) {\n // A pattern the catalogue lacks: the HATCH carries its definition lines\n // — already rotated by 52 and scaled by 41 — so un-bake them into a\n // document pattern (mm) that this and every later hatch of the name\n // references by name (first definition wins). Frames: 43/44 (origin)\n // and 45/46 (the step between successive lines) are vectors in the\n // hatch's frame; the .pat model (ours) gives the step RELATIVE TO THE\n // LINE — deltaX along it (dash phase), deltaY across it (spacing). The\n // baked line angle (53) already includes 52.\n const name = anyE.patternName.trim();\n const key = hatchPatternKey(name);\n const angle52 = (anyE.patternAngle ?? 0) * DEG2RAD;\n const scale41: number = anyE.patternScale > 0 ? anyE.patternScale : 1;\n // The HATCH's own origin (HPORIGIN — a block's hatch anchors to the\n // block) is folded into every line's 43/44. The definition is taken\n // with its first line at the .pat origin, and the common offset\n // becomes the fill's `origin`, so the same pattern drawn at different\n // anchors stays ONE definition.\n let anchor: Vec2 | undefined;\n {\n const cos = Math.cos(-angle52);\n const sin = Math.sin(-angle52);\n const unrot = (x: number, y: number) => ({\n x: ((cos * x - sin * y) / scale41) * ctx.f,\n y: ((sin * x + cos * y) / scale41) * ctx.f,\n });\n const first = anyE.patternLines[0];\n const shift = unrot(first.baseX ?? 0, first.baseY ?? 0);\n if (Math.hypot(shift.x, shift.y) > 1e-9)\n anchor = {\n x:\n (Math.cos(angle52) * shift.x - Math.sin(angle52) * shift.y) *\n scale41,\n y:\n (Math.sin(angle52) * shift.x + Math.cos(angle52) * shift.y) *\n scale41,\n };\n const lines = (anyE.patternLines as any[])\n .map((l) => {\n const o = unrot(l.baseX ?? 0, l.baseY ?? 0);\n const origin = { x: o.x - shift.x, y: o.y - shift.y };\n const baked = (l.angle ?? 0) * DEG2RAD;\n const c = Math.cos(-baked);\n const sn = Math.sin(-baked);\n const ox = l.offsetX ?? 0;\n const oy = l.offsetY ?? 0;\n let delta = {\n x: ((c * ox - sn * oy) / scale41) * ctx.f,\n y: ((sn * ox + c * oy) / scale41) * ctx.f,\n };\n // A negative perpendicular spacing describes the same family\n // from the other side.\n if (delta.y < 0) delta = { x: -delta.x, y: -delta.y };\n const dashes: number[] | undefined = Array.isArray(l.dashes)\n ? l.dashes.map((d: number) => (d / scale41) * ctx.f)\n : undefined;\n return {\n angle: (l.angle ?? 0) * DEG2RAD - angle52,\n origin,\n deltaX: delta.x,\n deltaY: delta.y,\n ...(dashes && dashes.length > 0 ? { dashesMm: dashes } : {}),\n };\n })\n .filter((l) => l.deltaY > 1e-9);\n if (lines.length > 0 && !ctx.hatchPatterns.has(key))\n ctx.hatchPatterns.set(key, { name, lines });\n }\n const own = ctx.hatchPatterns.get(key);\n if (own) {\n fill = {\n kind: \"pattern\",\n name: own.name,\n angle: angle52 * flip,\n scale: scale41,\n ...(anchor ? { origin: anchor } : {}),\n };\n } else {\n bump(ctx.degraded, \"HATCH→lines\");\n const line = anyE.patternLines?.[0];\n const offset = line\n ? Math.hypot(line.offsetX ?? 0, line.offsetY ?? 0)\n : 0;\n fill = {\n kind: \"lines\",\n angle: (line?.angle ?? anyE.patternAngle ?? 45) * DEG2RAD * flip,\n spacing: (offset > 0 ? offset : 3) * ctx.f,\n };\n }\n } else {\n // Generic pattern: approximate with the first definition line family.\n bump(ctx.degraded, \"HATCH→lines\");\n const line = anyE.patternLines?.[0];\n const offset = line ? Math.hypot(line.offsetX ?? 0, line.offsetY ?? 0) : 0;\n fill = {\n kind: \"lines\",\n angle: (line?.angle ?? anyE.patternAngle ?? 45) * DEG2RAD * flip,\n spacing: (offset > 0 ? offset : 3) * ctx.f,\n };\n }\n return [{ type: \"hatch\", loops, fill, scale: 1, ...base }];\n};\n\n/** Difference between two UNDIRECTED line angles, in (−π/2, π/2]. */\nconst lineAngleDiff = (a: number, b: number): number => {\n const d = (((a - b) % Math.PI) + Math.PI * 1.5) % Math.PI;\n return d > Math.PI / 2 ? d - Math.PI : d;\n};\n\n/** Linear blend of two hex colors, t = 0 → a, 1 → b. */\nconst mixHex = (a: string, b: string, t: number): string => {\n const ra = hexToRgb(a);\n const rb = hexToRgb(b);\n if (!ra || !rb) return a;\n const k = Math.max(0, Math.min(1, t));\n return rgbToHex(\n Math.round(ra[0] + (rb[0] - ra[0]) * k),\n Math.round(ra[1] + (rb[1] - ra[1]) * k),\n Math.round(ra[2] + (rb[2] - ra[2]) * k),\n );\n};\n\n/** Text placement past a leader's last point (mirror of the painter). */\nconst leaderTextPlacement = (\n line: Vec2[],\n height: number,\n): { position: Vec2; hAlign: \"left\" | \"right\" } => {\n const last = line[line.length - 1];\n const prev = line[line.length - 2] ?? last;\n const rightward = last.x - prev.x >= 0;\n const gap = height * 0.6;\n return {\n position: { x: last.x + (rightward ? gap : -gap), y: last.y },\n // Justification: text right of the leader starts at its point.\n hAlign: rightward ? \"left\" : \"right\",\n };\n};\n\n/**\n * The dimension style an entity's group 3 names (DIMENSION, LEADER): the\n * merged document style + its DIMSCALE, or the document default + the\n * header's $DIMSCALE when the file defines no such style.\n */\nconst dimStyleOf = (\n e: IEntity,\n ctx: ImportContext,\n): { id?: string; style: DimStyle; scale: number } => {\n const name = ctx.tags.dimStyleNameByHandle.get(String((e as any).handle));\n const id = name ? ctx.dimStyleIdByName.get(name.toLowerCase()) : undefined;\n const style = id ? ctx.dimStyleById.get(id) : undefined;\n if (id && style)\n return { id, style, scale: ctx.dimScaleByStyleId.get(id) ?? 1 };\n return { style: ctx.defaultDimStyle, scale: ctx.dimScale };\n};\n\n/**\n * `styleId` / `styleOverride` / `scale` for a converted dimension: the named\n * style, its DSTYLE xdata as a sparse override (only keys that differ from\n * the style), and the style's DIMSCALE as the object's scale.\n */\nconst dimStyleRef = (\n e: IEntity,\n ctx: ImportContext,\n): Partial<\n Pick<\n Extract<ModelObjectDto, { type: \"dimension\" }>,\n \"styleId\" | \"styleOverride\" | \"scale\"\n >\n> => {\n const { id, style, scale } = dimStyleOf(e, ctx);\n const xdata = ctx.tags.dimOverridesByHandle.get(String((e as any).handle));\n const { scale: ownScale, ...values } = xdata ? ctx.dimValuesFrom(xdata) : {};\n const override = overrideAgainst(style, values);\n const effScale = ownScale ?? scale;\n return {\n ...(id ? { styleId: id } : {}),\n ...(Object.keys(override).length > 0 ? { styleOverride: override } : {}),\n ...(effScale !== 1 ? { scale: effScale } : {}),\n };\n};\n\n/**\n * `styleId` / `styleOverride` for a converted text: the style its group 7\n * names (absent = the file's \"Standard\", like AutoCAD) and, as a sparse\n * override, only the explicit entity values that differ from it. Heights\n * and sizes are mm; `widthFactor` undefined = inherit.\n */\nconst textStyleRef = (\n e: IEntity,\n ctx: ImportContext,\n values: {\n textHeight: number;\n widthFactor?: number;\n bold?: true;\n italic?: true;\n font?: string;\n arrowSize?: number;\n arrowType?: TextStyle[\"arrowType\"];\n },\n): Pick<\n Extract<ModelObjectDto, { type: \"text\" }>,\n \"styleId\" | \"styleOverride\"\n> => {\n const name =\n ctx.tags.textStyleNameByHandle.get(String((e as any).handle)) ?? \"Standard\";\n const id = ctx.textStyleIdByName.get(name.toLowerCase());\n const style = (id && ctx.textStyleById.get(id)) || ctx.defaultTextStyle;\n const override = overrideAgainst(style, values);\n return {\n ...(id ? { styleId: id } : {}),\n ...(Object.keys(override).length > 0 ? { styleOverride: override } : {}),\n };\n};\n\nconst convertLeader = (e: IEntity, ctx: ImportContext): ModelObjectDto[] => {\n const anyE = e as any;\n const points: Vec2[] = (anyE.vertices ?? []).map((p: any) => pt(p, ctx.f));\n if (points.length < 2) return [];\n // The leader's DIMSTYLE sizes its text gap and arrowhead (× DIMSCALE).\n const { style, scale } = dimStyleOf(e, ctx);\n const placement = leaderTextPlacement(points, style.textHeight * scale);\n return [\n {\n type: \"text\",\n position: placement.position,\n content: \"\", // LEADER's annotation is a separate entity\n rotation: 0,\n hAlign: placement.hAlign,\n vAlign: \"center\",\n leaderLines: [points],\n // The dim style's DIMTXT/DIMASZ are explicit — overrides against the\n // TEXT style this note follows, so it renders as the source did.\n ...textStyleRef(e, ctx, {\n textHeight: style.textHeight * scale,\n arrowSize: style.arrowSize * scale,\n arrowType: style.arrowType,\n }),\n scale: 1,\n ...baseFor(e, ctx),\n },\n ];\n};\n\nconst convertMultiLeader = (\n e: IEntity,\n ctx: ImportContext,\n): ModelObjectDto[] => {\n const anyE = e as any;\n const f = ctx.f;\n // Rebuild full lines: each LEADER_LINE's vertices + its LEADER's junction.\n const lines: Vec2[][] = [];\n for (const leader of anyE.leaders ?? []) {\n for (const raw of leader.lines ?? []) {\n const points: Vec2[] = raw.map((p: any) => pt(p, f));\n if (leader.junction) points.push(pt(leader.junction, f));\n if (points.length >= 2) lines.push(points);\n }\n }\n if (lines.length === 0) return [];\n // CONTEXT_DATA sizes are FINAL (already multiplied by the overall scale);\n // un-bake them so height/arrowSize stay base values, like our model's.\n const overall = anyE.overallScale > 0 ? anyE.overallScale : 1;\n const height =\n (anyE.textHeight > 0\n ? anyE.textHeight / overall\n : ctx.defaultDimStyle.textHeight) * f;\n const fallback = leaderTextPlacement(lines[0], height * overall);\n const position = anyE.textLocation\n ? pt(anyE.textLocation, f)\n : fallback.position;\n const junction = lines[0][lines[0].length - 1];\n // Text attachment point 1–9 (TL TC TR / ML MC MR / BL BC BR) when the\n // context carries one; else the note sits on the far side of its leader.\n const ap =\n typeof anyE.attachment === \"number\" &&\n anyE.attachment >= 1 &&\n anyE.attachment <= 9\n ? anyE.attachment\n : undefined;\n return [\n {\n type: \"text\",\n position,\n content: cleanText(String(anyE.content ?? \"\"), true),\n rotation: 0,\n hAlign:\n ap !== undefined\n ? ([\"left\", \"center\", \"right\"] as const)[(ap - 1) % 3]\n : position.x >= junction.x\n ? \"left\"\n : \"right\",\n vAlign:\n ap !== undefined\n ? ap <= 3\n ? \"top\"\n : ap <= 6\n ? \"center\"\n : \"bottom\"\n : \"center\",\n leaderLines: lines,\n ...textStyleRef(e, ctx, {\n textHeight: height,\n arrowSize:\n (anyE.arrowSize > 0\n ? anyE.arrowSize / overall\n : ctx.defaultDimStyle.arrowSize) * f,\n }),\n // MLEADER's overall scale is a unitless multiplier, like ours.\n scale: overall,\n ...baseFor(e, ctx),\n },\n ];\n};\n\n// DXF dimensions arrive in the legacy linePoint/rotation shape; the shared\n// converters (also used by the migrations and block-script DTOs) turn them\n// into the current form — projecting axis-locked linear dims onto their\n// measuring axis, then the v21 scalars + labels.\nconst legacyDim = (raw: Record<string, unknown>): ModelObjectDto[] => [\n dimensionRawToLabels(dimensionRawToOffset(raw)) as unknown as ModelObjectDto,\n];\n\nconst convertDimension = (\n e: IEntity,\n dxf: IDxf,\n ctx: ImportContext,\n): ModelObjectDto[] => {\n const anyE = e as any;\n const kind = (anyE.dimensionType ?? 0) & 7;\n // The dimension's named style, its xdata overrides, and its DIMSCALE.\n const styleScale = dimStyleRef(e, ctx);\n const p1 = anyE.linearOrAngularPoint1;\n const p2 = anyE.linearOrAngularPoint2;\n const line = anyE.anchorPoint;\n\n if ((kind === 0 || kind === 1) && p1 && p2 && line) {\n const points = [pt(p1, ctx.f), pt(p2, ctx.f)];\n // Group 1 usually just repeats the measured value — keep it only when it\n // genuinely overrides (so re-imported dimensions stay live).\n const raw = typeof anyE.text === \"string\" ? anyE.text.trim() : \"\";\n const rotation = (anyE.angle ?? 0) * DEG2RAD;\n // Linear dims measure the projection onto the rotation axis.\n const measured =\n kind === 0\n ? Math.abs(\n (points[1].x - points[0].x) * Math.cos(rotation) +\n (points[1].y - points[0].y) * Math.sin(rotation),\n )\n : dist(points[0], points[1]);\n const asNumber = Number(raw.replace(\",\", \".\"));\n const isComputed =\n raw === \"\" ||\n raw === \"<>\" ||\n (Number.isFinite(asNumber) &&\n measured > 0 &&\n Math.abs(asNumber * ctx.f - measured) / measured < 0.01);\n return legacyDim({\n type: \"dimension\",\n ...styleScale,\n kind: kind === 0 ? \"linear\" : \"aligned\",\n points,\n linePoint: pt(line, ctx.f),\n rotation: kind === 0 ? rotation : 0,\n ...(isComputed ? {} : { textOverride: decodeTextEscapes(raw) }),\n ...baseFor(e, ctx),\n });\n }\n\n // Diameter (3): 10 and 15 are opposite points on the curve.\n if (kind === 3 && line && anyE.diameterOrRadiusPoint) {\n const a = pt(anyE.diameterOrRadiusPoint, ctx.f);\n const b = pt(line, ctx.f);\n return legacyDim({\n type: \"dimension\",\n ...styleScale,\n kind: \"diameter\",\n points: [a, b],\n linePoint: anyE.middleOfText\n ? pt(anyE.middleOfText, ctx.f)\n : { x: (a.x + b.x) / 2, y: (a.y + b.y) / 2 },\n ...baseFor(e, ctx),\n });\n }\n\n // Radial (4): 10 = center, 15 = point on the curve.\n if (kind === 4 && line && anyE.diameterOrRadiusPoint) {\n const center = pt(line, ctx.f);\n const p = pt(anyE.diameterOrRadiusPoint, ctx.f);\n return legacyDim({\n type: \"dimension\",\n ...styleScale,\n kind: \"radial\",\n points: [center, p],\n linePoint: anyE.middleOfText ? pt(anyE.middleOfText, ctx.f) : p,\n ...baseFor(e, ctx),\n });\n }\n\n // Angular 3-point (5): 15 = vertex, 13/14 = ray points, 10 = arc position.\n if (kind === 5 && p1 && p2 && line && anyE.diameterOrRadiusPoint) {\n return legacyDim({\n type: \"dimension\",\n ...styleScale,\n kind: \"angular\",\n points: [\n pt(anyE.diameterOrRadiusPoint, ctx.f),\n pt(p1, ctx.f),\n pt(p2, ctx.f),\n ],\n linePoint: pt(line, ctx.f),\n ...baseFor(e, ctx),\n });\n }\n\n // Two-line angular/ordinate/etc.: fall back to the dimension's rendered\n // geometry block (already in world coordinates).\n const block = anyE.block ? dxf.blocks?.[anyE.block] : undefined;\n if (!block?.entities) return [];\n const result: ModelObjectDto[] = [];\n for (const child of block.entities)\n result.push(...convertEntity(child, dxf, ctx));\n if (result.length > 0) bump(ctx.degraded, \"DIMENSION→exploded\");\n return result;\n};\n\n/**\n * Ledger bookkeeping (rule R8) around a converter: a hidden entity → skipped\n * \"hidden\", nothing produced → skipped by type, something produced →\n * imported unless the converter marked this type degraded. Wraps the\n * recursive paths too, so block children are counted.\n */\nconst account = (\n e: IEntity,\n ctx: ImportContext,\n convert: () => ModelObjectDto[],\n): ModelObjectDto[] => {\n ctx.seen.add(e.type);\n // Entities AutoCAD hides (group 60 = 1) — chiefly the inactive\n // visibility-state geometry inside dynamic blocks, which would otherwise\n // all render on top of each other.\n // Also hidden: an attribute with the invisible bit (70 & 1), and a\n // non-constant ATTDEF — the block's attribute DEFINITION, which AutoCAD\n // never draws; the INSERT's ATTRIBs carry the values. Constant ATTDEFs\n // have no ATTRIB and are drawn from the definition.\n const anyE = e as any;\n if (\n anyE.visible === false ||\n anyE.invisible === true ||\n (e.type === \"ATTDEF\" && anyE.constant !== true)\n ) {\n bump(ctx.skipped, `${e.type} (hidden)`);\n return [];\n }\n const ownDegraded = () => {\n let n = 0;\n for (const [k, v] of ctx.degraded) if (k.startsWith(e.type + \"→\")) n += v;\n return n;\n };\n const before = ownDegraded();\n const skippedBefore = total(ctx.skipped);\n const out = convert();\n // A converter that recorded its own skip reason is not double-counted.\n if (out.length === 0) {\n if (total(ctx.skipped) === skippedBefore) bump(ctx.skipped, e.type);\n } else if (ownDegraded() === before) bump(ctx.imported, e.type);\n return out;\n};\n\n/**\n * THE entity entry point — model space, paper space, block children and a\n * dimension's geometry block all convert through it, so ledger accounting\n * (hidden entities included), native tables and xrefs behave the same in\n * every context. `depth` > 0 is a block child (`inheritedColor` its ByBlock\n * color — see convertInsertInner). An xref becomes a reference only at the\n * top of a space: inside a block it is block geometry, which a reference\n * can't be, and its content is not in this file anyway.\n */\nconst convertEntity = (\n e: IEntity,\n dxf: IDxf,\n ctx: ImportContext,\n depth = 0,\n inheritedColor?: string,\n): ModelObjectDto[] =>\n account(e, ctx, () => {\n // ACAD_TABLE is INSERT-shaped: native when its payload is complete,\n // else its anonymous *T block explodes like any insert.\n const table = e.type === \"ACAD_TABLE\" ? convertAcadTable(e, ctx) : null;\n if (table) return [table];\n const ref =\n e.type === \"INSERT\" && depth === 0 ? xrefReference(e, dxf, ctx) : null;\n if (ref) return [ref];\n if (e.type === \"INSERT\" || e.type === \"ACAD_TABLE\")\n return convertInsertInner(e, dxf, ctx, depth, inheritedColor);\n return convertEntityInner(e, dxf, ctx);\n });\n\n/**\n * MLINE → one polyline per style element (counted degraded: the multiline\n * structure is lost, the drawn lines are not). Element points come from the\n * entity's own miter parameters (MlineHandler); a vertex without them falls\n * back to the style offsets × scale along the miter, shifted by the\n * justification (0 top = largest offset on the path, 1 zero, 2 bottom).\n * Square end caps (style 70 bits 16 / 256, unless the entity suppresses\n * them with 71 bits 4 / 8) close the outer elements with a line.\n */\nconst convertMline = (e: IEntity, ctx: ImportContext): ModelObjectDto[] => {\n const anyE = e as any;\n const base = baseFor(e, ctx);\n const f = ctx.f;\n const style: DxfMlineStyle | undefined =\n (anyE.styleHandle && anyE.styleHandle !== \"0\"\n ? ctx.mlineStyles.byHandle.get(anyE.styleHandle)\n : undefined) ??\n ctx.mlineStyles.byName.get(String(anyE.styleName ?? \"\").toLowerCase());\n const vertices: {\n point: { x: number; y: number };\n miter?: { x: number; y: number };\n direction?: { x: number; y: number };\n elements: { params: number[] }[];\n }[] = anyE.vertices ?? [];\n if (vertices.length < 2) return [];\n const count: number = Math.max(\n anyE.elementCount ?? 0,\n style?.elements.length ?? 0,\n ...vertices.map((v) => v.elements.length),\n );\n if (count === 0) return [];\n const scale: number = anyE.scale > 0 ? anyE.scale : 1;\n const offsets = style?.elements.map((el) => el.offset) ?? [];\n const ref =\n offsets.length === 0\n ? 0\n : anyE.justification === 0\n ? Math.max(...offsets)\n : anyE.justification === 2\n ? Math.min(...offsets)\n : 0;\n const miterAt = (v: (typeof vertices)[number]): Vec2 => {\n if (v.miter && (v.miter.x !== 0 || v.miter.y !== 0)) {\n const len = Math.hypot(v.miter.x, v.miter.y);\n return { x: v.miter.x / len, y: v.miter.y / len };\n }\n const d = v.direction ?? { x: 1, y: 0 };\n const len = Math.hypot(d.x, d.y) || 1;\n return { x: -d.y / len, y: d.x / len }; // left of the direction\n };\n const elementPoint = (v: (typeof vertices)[number], i: number): Vec2 => {\n const param = v.elements[i]?.params[0];\n const distance =\n param !== undefined ? param : ((offsets[i] ?? 0) - ref) * scale;\n const m = miterAt(v);\n return {\n x: (v.point.x + m.x * distance) * f,\n y: (v.point.y + m.y * distance) * f,\n };\n };\n const closed = ((anyE.flags ?? 0) & 2) !== 0;\n const out: ModelObjectDto[] = [];\n const firstPts: Vec2[] = [];\n const lastPts: Vec2[] = [];\n for (let i = 0; i < count; i++) {\n const points = vertices.map((v) => elementPoint(v, i));\n firstPts.push(points[0]);\n lastPts.push(points[points.length - 1]);\n const el = style?.elements[i];\n const color =\n el?.colorIndex !== undefined &&\n el.colorIndex !== 256 &&\n el.colorIndex !== 0\n ? aciToHex(el.colorIndex)\n : undefined;\n const lineType = lineTypeFromDxf(el?.lineType, ctx)?.name;\n out.push({\n type: \"polyline\",\n points: points.map((p) => ({ ...p, bulge: 0 })),\n closed,\n ...base,\n ...(color ? { color } : {}),\n ...(lineType ? { lineType } : {}),\n });\n }\n // Square caps join the two outermost elements at the open ends.\n if (!closed && count >= 2 && style) {\n const outer = (pts: Vec2[], v: (typeof vertices)[number]) => {\n const m = miterAt(v);\n const along = pts.map((p) => p.x * m.x + p.y * m.y);\n const lo = along.indexOf(Math.min(...along));\n const hi = along.indexOf(Math.max(...along));\n return lo === hi ? null : ([pts[lo], pts[hi]] as const);\n };\n const flags: number = anyE.flags ?? 0;\n if ((style.flags & 16) !== 0 && (flags & 4) === 0) {\n const cap = outer(firstPts, vertices[0]);\n if (cap) out.push({ type: \"line\", a: cap[0], b: cap[1], ...base });\n }\n if ((style.flags & 256) !== 0 && (flags & 8) === 0) {\n const cap = outer(lastPts, vertices[vertices.length - 1]);\n if (cap) out.push({ type: \"line\", a: cap[0], b: cap[1], ...base });\n }\n }\n if (out.length > 0) bump(ctx.degraded, \"MLINE→polylines\");\n return out;\n};\n\nconst convertEntityInner = (\n e: IEntity,\n dxf: IDxf,\n ctx: ImportContext,\n): ModelObjectDto[] => {\n const anyE = e as any;\n const f = ctx.f;\n const base = baseFor(e, ctx);\n // Extrusion (0,0,−1): by the arbitrary axis algorithm the entity's OCS is\n // the world mirrored about the Y axis — x flips, angles mirror (θ → π−θ,\n // sweep direction reverses), bulges change sign. AutoCAD's MIRROR writes\n // this routinely for arcs, circles, polylines, inserts and text; LINE,\n // POINT, SPLINE and ELLIPSE coordinates are world coordinates already.\n const mirrored = ctx.tags.mirroredHandles.has(String(anyE.handle));\n const ocs = (p: { x: number; y: number }): Vec2 =>\n mirrored ? { x: -p.x * f, y: p.y * f } : pt(p, f);\n const ocsAngle = (a: number): number => (mirrored ? Math.PI - a : a);\n\n switch (e.type) {\n case \"LINE\": {\n const [a, b] = anyE.vertices;\n if (!a || !b) return [];\n return [{ type: \"line\", a: pt(a, f), b: pt(b, f), ...base }];\n }\n case \"POINT\": {\n if (!anyE.position) return [];\n return [{ type: \"point\", p: pt(anyE.position, f), ...base }];\n }\n case \"LWPOLYLINE\":\n case \"POLYLINE\": {\n const vertices: PolylineVertex[] = (anyE.vertices ?? []).map(\n (v: any) => ({\n ...ocs(v),\n bulge: mirrored ? -(v.bulge ?? 0) : (v.bulge ?? 0),\n }),\n );\n if (vertices.length < 2) return [];\n // Width: LWPOLYLINE 43 (constant), or per-vertex 40/41. AutoCAD draws\n // a wide polyline as a filled band in drawing units — so does the\n // import (a solid hatch, geometry/band.ts) when the width is constant\n // and the path has no bulges; a tapered or bulged wide polyline stays\n // a thin polyline, counted.\n const widths: number[] = [];\n if (typeof anyE.width === \"number\" && anyE.width > 0)\n widths.push(anyE.width);\n for (const v of anyE.vertices ?? [])\n for (const w of [v.startWidth, v.endWidth])\n if (typeof w === \"number\" && w > 0) widths.push(w);\n const closed = anyE.shape === true;\n if (widths.length > 0) {\n const constant = widths.every((w) => Math.abs(w - widths[0]) < 1e-9);\n const straight = vertices.every((v) => v.bulge === 0);\n const loops =\n constant && straight\n ? polylineBand(vertices, widths[0] * f, closed)\n : null;\n if (loops && loops.every((l) => l.length >= 3)) {\n bump(ctx.degraded, `${e.type} (width)→hatch`);\n return [\n {\n type: \"hatch\",\n loops: loops.map((l) => ({\n points: l.map((p) => ({ ...p, bulge: 0 })),\n })),\n fill: { kind: \"solid\" },\n scale: 1,\n ...base,\n },\n ];\n }\n bump(ctx.degraded, `${e.type} (width)→thin`);\n }\n return [{ type: \"polyline\", points: vertices, closed, ...base }];\n }\n case \"CIRCLE\": {\n const radius = anyE.radius * f;\n if (!(radius > 0)) return []; // zero/negative/NaN radius\n return [\n {\n type: \"circle\",\n center: ocs(anyE.center),\n radius,\n ...base,\n },\n ];\n }\n case \"ARC\": {\n const radius = anyE.radius * f;\n if (!(radius > 0)) return [];\n // dxf-parser converts arc angles to radians.\n return [\n {\n type: \"arc\",\n center: ocs(anyE.center),\n radius,\n // A mirrored arc runs CCW from the mirror of its end to the mirror\n // of its start.\n startAngle: mirrored ? ocsAngle(anyE.endAngle) : anyE.startAngle,\n endAngle: mirrored ? ocsAngle(anyE.startAngle) : anyE.endAngle,\n ...base,\n },\n ];\n }\n case \"ELLIPSE\": {\n const ratio = Math.min(Math.max(anyE.axisRatio, 1e-3), 1);\n // Center and major axis are world coordinates; only the minor axis\n // (normal × major) flips with a downward normal, so the parameter\n // runs the other way: a partial ellipse from u0 to u1 becomes one\n // from −u1 to −u0.\n const u0 = anyE.startAngle ?? 0;\n const u1 = anyE.endAngle ?? Math.PI * 2;\n const full = u1 - u0 >= Math.PI * 2 - 1e-9;\n const wrap = (a: number) =>\n ((a % (Math.PI * 2)) + Math.PI * 2) % (Math.PI * 2);\n return [\n {\n type: \"ellipse\",\n center: pt(anyE.center, f),\n majorAxis: pt(anyE.majorAxisEndPoint, f), // relative vector\n ratio,\n startAngle: mirrored && !full ? wrap(-u1) : u0,\n endAngle: mirrored && !full ? wrap(-u0) : u1,\n ...base,\n },\n ];\n }\n case \"TEXT\":\n case \"ATTRIB\":\n case \"ATTDEF\": {\n // ATTRIB (our handler) uses TEXT's field names; dxf-parser's ATTDEF\n // names the same groups differently.\n const halign = anyE.halign ?? anyE.horizontalJustification ?? 0;\n const valign = anyE.valign ?? anyE.verticalJustification ?? 0;\n const widthFactor = anyE.xScale ?? anyE.scale;\n // With a non-default alignment the anchor is the SECOND alignment\n // point (codes 11/21). \"Aligned\" (3) and \"fit\" (5) stretch between\n // both points — approximated as plain left/baseline at the first.\n const usesSecondPoint =\n (halign !== 0 && halign !== 3 && halign !== 5) || valign !== 0;\n const anchor =\n usesSecondPoint && anyE.endPoint ? anyE.endPoint : anyE.startPoint;\n // DXF justification = the model's alignment (which edge sits on the\n // point).\n const hAlign =\n halign === 1 || halign === 4\n ? \"center\"\n : halign === 2\n ? \"right\"\n : \"left\";\n // valign: 0 baseline, 1 bottom, 2 middle, 3 top; halign 4 = \"middle\"\n // centers both axes. Baseline maps to bottom (closest anchor we have).\n const vAlign =\n valign === 3\n ? \"top\"\n : valign === 2 || halign === 4\n ? \"center\"\n : \"bottom\";\n return [\n {\n type: \"text\",\n position: ocs(anchor),\n content: cleanText(anyE.text ?? \"\", false),\n rotation: ocsAngle((anyE.rotation ?? 0) * DEG2RAD),\n hAlign,\n vAlign,\n leaderLines: [],\n scale: 1,\n // Style (7) + the entity's own explicit height (40) and width\n // factor (41 — stored per TEXT, default 1) as overrides only\n // where they differ from the style.\n ...textStyleRef(e, ctx, {\n textHeight: (anyE.textHeight > 0 ? anyE.textHeight : 2.5) * f,\n widthFactor:\n typeof widthFactor === \"number\" && widthFactor > 0\n ? widthFactor\n : 1,\n }),\n ...base,\n },\n ];\n }\n case \"MTEXT\": {\n // Attachment point 1–9: TL TC TR / ML MC MR / BL BC BR.\n const ap = anyE.attachmentPoint ?? 1;\n const hAlign = ([\"left\", \"center\", \"right\"] as const)[(ap - 1) % 3];\n const vAlign = ap <= 3 ? \"top\" : ap <= 6 ? \"center\" : \"bottom\";\n // Rotation comes as a degree angle (50) or an X-axis direction\n // vector (11); the vector wins when present.\n const dv = anyE.directionVector;\n const rotation = ocsAngle(\n dv && (dv.x !== 0 || dv.y !== 0)\n ? Math.atan2(dv.y, dv.x)\n : (anyE.rotation ?? 0) * DEG2RAD,\n );\n // Inline formatting → spans (\\H heights relative to the entity's).\n const rich = cleanRichText(\n anyE.text ?? \"\",\n anyE.height > 0 ? anyE.height : 2.5,\n );\n return [\n {\n type: \"text\",\n position: ocs(anyE.position),\n content: rich.content,\n ...(rich.spans.length ? { spans: rich.spans } : {}),\n rotation,\n hAlign,\n vAlign,\n leaderLines: [],\n scale: 1,\n // MTEXT reference rectangle width (group 41) → wrap width.\n ...(anyE.width > 0 ? { width: anyE.width * f } : {}),\n // Style (7) + the explicit height and the inline \\W / \\f codes\n // (cleanText strips them) as overrides where they differ.\n ...textStyleRef(e, ctx, {\n textHeight: (anyE.height > 0 ? anyE.height : 2.5) * f,\n widthFactor: mtextWidthFactor(anyE.text ?? \"\"),\n ...mtextFontFlags(anyE.text ?? \"\"),\n }),\n ...base,\n },\n ];\n }\n case \"MLINE\":\n return convertMline(e, ctx);\n case \"SPLINE\": {\n // The curve itself, sampled within SPLINE_TOLERANCE_MM, when the\n // control data is complete (degree, n + p + 1 knots, optional\n // weights from the raw scan); else the fit points (on the curve,\n // sparse), else the control polygon.\n const control: any[] = anyE.controlPoints ?? [];\n const weights = ctx.tags.splineWeightsByHandle.get(String(anyE.handle));\n const curve: NurbsCurve = {\n degree: anyE.degreeOfSplineCurve ?? 3,\n controlPoints: control.map((p) => ({ x: p.x, y: p.y })),\n knots: anyE.knotValues ?? [],\n ...(weights && weights.length === control.length ? { weights } : {}),\n };\n // Fit-point splines (a DWG transcode keeps only those): the cubic\n // THROUGH the points, sampled the same way.\n const fit: any[] = anyE.fitPoints ?? [];\n const fitted = isValidNurbs(curve)\n ? null\n : interpolateFitPoints(fit.map((p) => ({ x: p.x, y: p.y })));\n let points: Vec2[];\n if (isValidNurbs(curve)) {\n points = sampleNurbs(curve, SPLINE_TOLERANCE_MM / f);\n bump(ctx.degraded, \"SPLINE→polyline\");\n } else if (fitted) {\n points = sampleNurbs(fitted, SPLINE_TOLERANCE_MM / f);\n bump(ctx.degraded, \"SPLINE→polyline (fit points)\");\n } else {\n const raw: any[] = fit.length >= 2 ? fit : control;\n if (raw.length < 2) return [];\n points = raw.map((p) => ({ x: p.x, y: p.y }));\n bump(ctx.degraded, \"SPLINE→polyline (control points)\");\n }\n if (points.length < 2) return [];\n return [\n {\n type: \"polyline\",\n points: points.map((p) => ({ x: p.x * f, y: p.y * f, bulge: 0 })),\n closed: anyE.closed === true,\n ...base,\n },\n ];\n }\n case \"3DFACE\": {\n // A face: its edges in order (no SOLID bow-tie). Drawn as a solid\n // fill — what a shaded view shows; wireframe shows only the edges.\n // dxf-parser pads the vertex list with an empty record; keep real,\n // distinct corners only.\n const points: any[] = (anyE.vertices ?? []).filter(\n (p: any, i: number, all: any[]) =>\n typeof p.x === \"number\" &&\n typeof p.y === \"number\" &&\n !all.slice(0, i).some((q: any) => q.x === p.x && q.y === p.y),\n );\n if (points.length < 3) return [];\n bump(ctx.degraded, \"3DFACE→hatch\");\n return [\n {\n type: \"hatch\",\n loops: [{ points: points.map((p) => ({ ...pt(p, f), bulge: 0 })) }],\n fill: { kind: \"solid\" },\n scale: 1,\n ...base,\n },\n ];\n }\n case \"TRACE\":\n case \"SOLID\": {\n const points: any[] = anyE.points ?? [];\n if (points.length < 3) return [];\n // DXF SOLID vertex order is 1,2,4,3.\n const ordered =\n points.length >= 4\n ? [points[0], points[1], points[3], points[2]]\n : points;\n return [\n {\n type: \"hatch\",\n loops: [\n {\n points: ordered.map((p) => ({ ...ocs(p), bulge: 0 })),\n },\n ],\n fill: { kind: \"solid\" },\n scale: 1,\n ...base,\n },\n ];\n }\n case \"HATCH\":\n return convertHatch(e, ctx);\n case \"LEADER\":\n return convertLeader(e, ctx);\n case \"MULTILEADER\":\n return convertMultiLeader(e, ctx);\n case \"DIMENSION\":\n return convertDimension(e, dxf, ctx);\n default:\n return [];\n }\n};\n\n/**\n * Blocks indexed by their owner BLOCK_RECORD handle (group 330), built\n * lazily once per parsed document. ACAD_TABLE via the DWG transcode\n * references its content block by that HANDLE (AutoCAD's native DXF puts\n * the `*T<n>` block NAME in the same field), so the name lookup misses and\n * this resolves the join.\n */\nconst blocksByOwner = new WeakMap<object, Map<string, IBlock>>();\nconst blockByOwnerHandle = (dxf: IDxf, handle: string): IBlock | undefined => {\n let map = blocksByOwner.get(dxf);\n if (!map) {\n map = new Map();\n for (const b of Object.values(dxf.blocks ?? {})) {\n const oh = (b as { ownerHandle?: unknown }).ownerHandle;\n if (oh !== undefined) map.set(String(oh).toUpperCase(), b);\n }\n blocksByOwner.set(dxf, map);\n }\n return map.get(handle.toUpperCase());\n};\n\n/**\n * An INSERT of an XREF block (group-70 bit 4, path in group 1) → a Linea\n * reference to the same file, placed like the insert (docs/references.md):\n * the linked file's content is NOT part of this DXF, so exploding it would\n * yield nothing.\n */\nconst xrefReference = (\n e: IEntity,\n dxf: IDxf,\n ctx: ImportContext,\n): ModelObjectDto | null => {\n const anyE = e as any;\n const block = dxf.blocks?.[anyE.name] as IBlock | undefined;\n if (!block) return null;\n // An external reference: the xref flag (70 bit 4), or a group-1 path that\n // IS a path (a folder or a file extension). A DWG transcode writes group 1\n // = the block's own name on ordinary blocks (FIN04A's ARK$VAR marker),\n // which is not a reference to anything.\n const rawPath = block.xrefPath ?? \"\";\n const isXref =\n (block.type & 4) !== 0 ||\n (rawPath !== \"\" &&\n rawPath !== block.name &&\n (/[\\\\/]/.test(rawPath) || referenceFormatOf(rawPath) !== null));\n if (!isXref) return null;\n const path = (rawPath || `${block.name}.dwg`).replace(/\\\\/g, \"/\");\n const sx = anyE.xScale ?? 1;\n const sy = anyE.yScale ?? 1;\n // Linea mirrors left-right (−X); a negative Y scale is that flip turned\n // half a turn.\n const rotation = (anyE.rotation ?? 0) * DEG2RAD + (sy < 0 ? Math.PI : 0);\n return {\n ...baseFor(e, ctx),\n type: \"reference\",\n format: referenceFormatOf(path) ?? \"dwg\",\n name: block.name,\n source: { kind: \"path\", path },\n position: pt(anyE.position ?? { x: 0, y: 0 }, ctx.f),\n rotation,\n scale: Math.abs(sx) || 1,\n ...(sx * sy < 0 ? { mirrored: true } : {}),\n hiddenLayers: [],\n } as ModelObjectDto;\n};\n\n/** Explode INSERTs by converting the block's entities and transforming them. */\n/**\n * ACAD_TABLE → native table, from the legacy AcDbTable payload\n * (AcadTableHandler): grid, row heights (as floors — rows still grow to fit),\n * column widths, merges, per-cell alignment / height / bold-italic and the\n * cleaned MTEXT. Null when the payload is missing, inconsistent or holds a\n * non-text cell — the caller then explodes the *T block as before.\n */\nconst convertAcadTable = (\n e: IEntity,\n ctx: ImportContext,\n): ModelObjectDto | null => {\n const anyE = e as any;\n const t: AcadTableData | undefined = anyE.table;\n if (!t || !anyE.position) return null;\n const { cols, cells } = t;\n // A DWG transcode can report the ALLOCATED row count (91) with trailing\n // rows that have no cells (their heights are 0 or uninitialized); the\n // cells are the truth when they fill a whole number of rows.\n let rows = t.rows;\n let rowHeights = t.rowHeights;\n if (\n cols > 0 &&\n cells.length !== rows * cols &&\n cells.length % cols === 0 &&\n cells.length / cols < rows &&\n rowHeights.length === rows\n ) {\n rows = cells.length / cols;\n rowHeights = rowHeights.slice(0, rows);\n }\n if (\n rows === 0 ||\n cells.length !== rows * cols ||\n rowHeights.length !== rows ||\n t.colWidths.length !== cols ||\n cells.some((c) => c.type !== 1)\n )\n return null;\n const f = ctx.f;\n const fallbackRowHeight = Math.min(\n ...rowHeights.filter((h) => h > 0),\n Infinity,\n );\n const H = [\"left\", \"center\", \"right\"] as const;\n const grid = Array.from({ length: rows }, (_, r) =>\n Array.from({ length: cols }, (_, c) => {\n const cell = cells[r * cols + c];\n // Text cells carry group 1; numeric cells only the display string.\n const raw = cell.text || cell.display || \"\";\n const a = cell.alignment;\n // The cell's text height: its 140, else the absolute \\H the MTEXT\n // opens with (AutoCAD 2018's legacy cells and Linea's own export\n // carry it inline; a relative \"\\H0.5x;\" is a span, not the height).\n const inlineHeight = Number(/\\\\H(\\d+(?:\\.\\d+)?);/.exec(raw)?.[1]);\n const height =\n cell.height && cell.height > 0\n ? cell.height\n : inlineHeight > 0\n ? inlineHeight\n : undefined;\n const rich = cleanRichText(raw, height ?? 2.5);\n // Trailing blank lines / spaces (a DWG transcode pads cells) would\n // add empty lines to the row.\n const text = rich.content.replace(/\\s+$/, \"\");\n // Formatting of PART of the cell; whole-cell bold/italic rides on the\n // style override below (mtextFontFlags), as before.\n const spans = normalizeSpans(rich.spans, text).filter(\n (s) => s.start > 0 || s.end < text.length,\n );\n return {\n content: text,\n ...(spans.length ? { spans } : {}),\n ...(cell.cols > 1 || cell.rows > 1\n ? { span: { cols: cell.cols, rows: cell.rows } }\n : {}),\n ...(a !== undefined && a >= 1 && a <= 9\n ? {\n hAlign: H[(a - 1) % 3],\n vAlign:\n a <= 3\n ? (\"top\" as const)\n : a <= 6\n ? (\"center\" as const)\n : (\"bottom\" as const),\n }\n : {}),\n styleOverride: {\n ...(height !== undefined ? { textHeight: height * f } : {}),\n ...mtextFontFlags(raw),\n },\n };\n }),\n );\n const parsed = ModelObjectSchema.safeParse({\n type: \"table\",\n id: \"acad-table\",\n position: pt(anyE.position, f),\n rotation: (anyE.rotation ?? 0) * DEG2RAD,\n scale: 1,\n columns: t.colWidths.map((w) => w * f),\n // AutoCAD's row heights are the drawn ones: keep them as floors. A DWG\n // transcode writes 0 for some rows (FIN04A: the last row of 64 tables,\n // 49 of them empty) — an empty row would collapse to its margins and\n // look deleted, so a zero height takes the table's smallest real row\n // height (a one-line row), else the row's content decides.\n rows: rowHeights.map((h) =>\n h > 0\n ? { minHeight: h * f }\n : fallbackRowHeight > 0\n ? { minHeight: fallbackRowHeight * f }\n : {},\n ),\n cells: grid,\n // Margin (40) — absent in a DWG transcode (its TABLESTYLE is dropped):\n // AutoCAD's Standard style pads a cell by a third of its text height,\n // so a missing margin takes that, from the cells' height or the style.\n cellMargin:\n t.margin !== undefined\n ? t.margin * f\n : 0.3 *\n (Math.max(0, ...cells.map((c) => (c.height ?? 0) * f)) ||\n ctx.defaultTextStyle.textHeight),\n ...baseFor(e, ctx),\n });\n if (!parsed.success) return null;\n const { id: _id, ...dto } = parsed.data;\n void _id;\n return dto as ModelObjectDto;\n};\n\n/**\n * The definition for a DXF block, generated on first use (cached per\n * block) when its visible entities convert to at least one object. The\n * children are the block's entities converted at the origin (a unit insert\n * at 0,0), so their coordinates are block-local millimetres; a child on\n * layer `0` drops its layer and follows the instance (ByBlock), the others\n * keep theirs.\n */\nconst blockDefinitionFor = (\n block: IBlock,\n dxf: IDxf,\n ctx: ImportContext,\n): ImportedBlockDefinition | null => {\n const key = block.name.toUpperCase();\n const cached = ctx.blockDefinitions.get(key);\n if (cached !== undefined) return cached;\n let def: ImportedBlockDefinition | null = null;\n {\n const unit = {\n type: \"INSERT\",\n name: block.name,\n position: { x: 0, y: 0 },\n xScale: 1,\n yScale: 1,\n rotation: 0,\n layer: \"0\",\n } as unknown as IEntity;\n const children = convertInsertInner(unit, dxf, ctx, 1);\n if (children.length > 0) {\n // A name clash → suffixed, the library's merge rule\n // (mergeScriptModules). The id ignores the name, so a module already\n // here (same content hash) is still found below and reused as is.\n const taken = (n: string) =>\n [...ctx.existingBlocks, ...ctx.newBlockDefinitions].some(\n (b) => b.name.toLowerCase() === n.toLowerCase(),\n );\n let name = block.name.replace(/^\\*/, \"\");\n while (taken(name)) name = `${name} (imported)`;\n def = blockDefinitionModule(\n block.name,\n children,\n inheritLayerIds(ctx),\n name,\n );\n const id = def.id;\n const same = ctx.newBlockDefinitions.find((d) => d.id === id);\n if (same) def = same;\n else if (!ctx.existingBlocks.some((b) => b.id === id))\n ctx.newBlockDefinitions.push(def);\n }\n }\n ctx.blockDefinitions.set(key, def);\n return def;\n};\n\n/** Layers whose children follow the insert: DXF layer `0` and the import's\n * fallback layer (entities whose layer is unknown). */\nconst inheritLayerIds = (ctx: ImportContext): ReadonlySet<string> =>\n new Set(\n [ctx.layerIdByName.get(\"0\"), ctx.defaultLayerId].filter(\n (id): id is string => id !== undefined,\n ),\n );\n\nconst convertInsertInner = (\n e: IEntity,\n dxf: IDxf,\n ctx: ImportContext,\n depth: number,\n /** What a ByBlock child resolves to: an enclosing insert's own color.\n * Undefined inside a definition build (the instance supplies it at paint\n * time) — the explode path falls back to the insert's layer color. */\n inheritedColor?: string,\n): ModelObjectDto[] => {\n const anyE = e as any;\n if (depth > 16) return []; // guard against self-referential blocks\n // Tables may reference their content block by BLOCK_RECORD handle instead\n // of name (the DWG transcode does); scoped to ACAD_TABLE so an INSERT with\n // a genuinely missing block can't collide with a handle by accident.\n const block =\n dxf.blocks?.[anyE.name] ??\n (e.type === \"ACAD_TABLE\"\n ? blockByOwnerHandle(dxf, String(anyE.name ?? \"\"))\n : undefined);\n if (!block) return [];\n if (!block.entities?.length) {\n // An insert of an empty block (marker blocks like FIN04A's ARK$VAR)\n // shows nothing in AutoCAD either — accounted, not lost.\n bump(ctx.skipped, \"INSERT (empty block)\");\n return [];\n }\n\n // DXF INSERT carries independent x/y/z scales (groups 41/42/43); a negative\n // scale is a mirror. Build the full affine — scale each axis, rotate, then\n // translate to the insertion point.\n // A downward extrusion mirrors the OCS about Y: M·R(θ)·S = R(π−θ)·diag(1,−1)·S,\n // so the insert becomes position (−x, y), rotation π−θ, y scale negated.\n const mirrored = ctx.tags.mirroredHandles.has(String(anyE.handle));\n // MINSERT: a column × row array of the block. Spacings are measured in\n // the insert's rotated frame, unscaled; each copy converts as one INSERT.\n const columns: number = anyE.columnCount > 1 ? anyE.columnCount : 1;\n const rows: number = anyE.rowCount > 1 ? anyE.rowCount : 1;\n if (columns > 1 || rows > 1) {\n const cs: number = anyE.columnSpacing ?? 0;\n const rs: number = anyE.rowSpacing ?? 0;\n const theta = (anyE.rotation ?? 0) * DEG2RAD;\n const p0 = anyE.position ?? { x: 0, y: 0 };\n const out: ModelObjectDto[] = [];\n for (let j = 0; j < rows; j++)\n for (let i = 0; i < columns; i++) {\n const dx = i * cs;\n const dy = j * rs;\n const copy = {\n ...anyE,\n columnCount: 1,\n rowCount: 1,\n position: {\n x: p0.x + dx * Math.cos(theta) - dy * Math.sin(theta),\n y: p0.y + dx * Math.sin(theta) + dy * Math.cos(theta),\n },\n };\n out.push(...convertInsertInner(copy as IEntity, dxf, ctx, depth));\n }\n return out;\n }\n const sx = anyE.xScale ?? 1;\n const sy = (anyE.yScale ?? 1) * (mirrored ? -1 : 1);\n const rot0 = (anyE.rotation ?? 0) * DEG2RAD;\n const rot = mirrored ? Math.PI - rot0 : rot0;\n const pos = anyE.position ?? { x: 0, y: 0 };\n const insert = mirrored\n ? { x: -pos.x * ctx.f, y: pos.y * ctx.f }\n : pt(pos, ctx.f);\n\n // A top-level INSERT with a uniform positive scale becomes an INSTANCE of\n // a generated definition (blockDefinitions.ts); everything else —\n // mirrors, anisotropic scales, nested inserts (baked into their parent's\n // definition), tables — explodes below.\n if (\n e.type === \"INSERT\" &&\n depth === 0 &&\n !mirrored &&\n sx > 0 &&\n sy > 0 &&\n Math.abs(sx - sy) < 1e-9\n ) {\n const def = blockDefinitionFor(block, dxf, ctx);\n if (def)\n return [\n {\n type: \"block\",\n definitionId: def.id,\n inputs: [insert],\n rotation: rot,\n scale: sx,\n params: {},\n ...baseFor(e, ctx),\n },\n ];\n }\n if (e.type === \"INSERT\" && depth === 0) bump(ctx.degraded, \"INSERT→exploded\");\n // The block's base point (BLOCK 10/20) is its origin: world =\n // insert + R·S·(entity − base).\n const base = pt(block.position ?? { x: 0, y: 0 }, ctx.f);\n const cos = Math.cos(rot);\n const sin = Math.sin(rot);\n const reflect = sx * sy < 0;\n const meanScale = Math.sqrt(Math.abs(sx * sy)) || 1e-6;\n const lin = (v: Vec2): Vec2 => ({\n x: cos * (v.x * sx) - sin * (v.y * sy),\n y: sin * (v.x * sx) + cos * (v.y * sy),\n });\n const map = (p: Vec2): Vec2 => {\n const l = lin({ x: p.x - base.x, y: p.y - base.y });\n return { x: l.x + insert.x, y: l.y + insert.y };\n };\n\n // Re-fit a bulged vertex list through the affine: map the vertices, then\n // recompute each segment's bulge from the transformed endpoints + arc\n // midpoint (so rotation, per-axis scale, and mirror sign flips are handled).\n const mapBulged = (\n verts: PolylineVertex[],\n closed: boolean,\n ): PolylineVertex[] => {\n const out = verts.map((v) => {\n const m = map(v);\n return { x: m.x, y: m.y, bulge: 0 };\n });\n const n = verts.length;\n const segs = closed ? n : n - 1;\n for (let i = 0; i < segs; i++) {\n const b = verts[i].bulge;\n if (!b) continue;\n const j = (i + 1) % n;\n const arc = bulgeToArc(\n { x: verts[i].x, y: verts[i].y },\n { x: verts[j].x, y: verts[j].y },\n b,\n );\n if (!arc) continue;\n const nb = bulgeFrom3Points(out[i], map(arcMidPoint(arc)), out[j]);\n out[i].bulge = Number.isFinite(nb) ? Math.max(-4, Math.min(4, nb)) : 0;\n }\n return out;\n };\n\n const transform = (dto: ModelObjectDto): ModelObjectDto | null => {\n const t = structuredClone(dto);\n switch (t.type) {\n case \"line\":\n t.a = map(t.a);\n t.b = map(t.b);\n return t;\n case \"polyline\":\n t.points = mapBulged(t.points, t.closed);\n return t;\n case \"circle\": {\n const ax = Math.abs(sx) * t.radius;\n const ay = Math.abs(sy) * t.radius;\n const center = map(t.center);\n if (Math.abs(ax - ay) <= 1e-6 * Math.max(ax, ay, 1)) {\n t.center = center;\n t.radius = Math.max((ax + ay) / 2, 1e-6);\n return t;\n }\n // Anisotropic scale turns the circle into a rotated ellipse.\n const majorLen = Math.max(ax, ay);\n const ang = rot + (ax >= ay ? 0 : Math.PI / 2);\n return {\n type: \"ellipse\",\n center,\n majorAxis: {\n x: majorLen * Math.cos(ang),\n y: majorLen * Math.sin(ang),\n },\n ratio: Math.min(1, Math.max(1e-3, Math.min(ax, ay) / majorLen)),\n startAngle: 0,\n endAngle: Math.PI * 2,\n layerId: t.layerId,\n ...(t.color ? { color: t.color } : {}),\n ...(t.lineType ? { lineType: t.lineType } : {}),\n ...(t.lineTypeScale !== undefined\n ? { lineTypeScale: t.lineTypeScale }\n : {}),\n ...(t.lineWidth !== undefined ? { lineWidth: t.lineWidth } : {}),\n };\n }\n case \"arc\": {\n // Reconstruct through three transformed points — exact for any\n // similarity (rotation / uniform scale / mirror); a circular\n // approximation for the rare anisotropic case.\n const g = {\n center: t.center,\n radius: t.radius,\n startAngle: t.startAngle,\n endAngle: t.endAngle,\n };\n const solved = arcFrom3Points(\n map(arcStartPoint(g)),\n map(arcMidPoint(g)),\n map(arcEndPoint(g)),\n );\n if (!solved) return null;\n t.center = solved.center;\n t.radius = solved.radius;\n t.startAngle = solved.startAngle;\n t.endAngle = solved.endAngle;\n return t;\n }\n case \"ellipse\":\n t.center = map(t.center);\n t.majorAxis = lin(t.majorAxis);\n if (reflect) {\n const s0 = t.startAngle;\n t.startAngle = -t.endAngle;\n t.endAngle = -s0;\n }\n return t;\n case \"hatch\": {\n t.loops = t.loops.map((loop: { points: PolylineVertex[] }) => ({\n points: mapBulged(loop.points, true),\n }));\n // The pattern is part of the block: its lines turn (and reflect)\n // with the insert, the spacing scales, and the frame — anchored at\n // the block origin in AutoCAD — follows the insertion point.\n if (t.fill.kind === \"pattern\" || t.fill.kind === \"lines\") {\n const d = lin({\n x: Math.cos(t.fill.angle),\n y: Math.sin(t.fill.angle),\n });\n const angle = Math.atan2(d.y, d.x);\n t.fill =\n t.fill.kind === \"pattern\"\n ? {\n ...t.fill,\n angle,\n scale: t.fill.scale * meanScale,\n origin: map(t.fill.origin ?? { x: 0, y: 0 }),\n }\n : { ...t.fill, angle, spacing: t.fill.spacing * meanScale };\n }\n return t;\n }\n case \"text\":\n t.position = map(t.position);\n t.rotation += rot;\n // Sizes a scaled insert multiplies: the text's own override, or\n // (when it follows its style's) the style value — made explicit.\n if (meanScale !== 1) {\n const style =\n (t.styleId && ctx.textStyleById.get(t.styleId)) ||\n ctx.defaultTextStyle;\n const o = t.styleOverride ?? {};\n t.styleOverride = {\n ...o,\n textHeight: (o.textHeight ?? style.textHeight) * meanScale,\n ...(o.arrowSize === undefined\n ? {}\n : { arrowSize: o.arrowSize * meanScale }),\n };\n }\n if (t.width !== undefined) t.width *= meanScale;\n t.leaderLines = t.leaderLines.map((l) => l.map(map));\n return t;\n case \"dimension\": {\n // Scalar placement re-derived from mapped points: the dimension\n // line point maps like any point, a locked axis maps by direction,\n // the arc radius scales (a reflection picks the other arc), label\n // distances scale (a reflection flips the handed radial/diameter\n // frames' `across`).\n const before = t.points;\n t.points = t.points.map(map);\n if (t.kind === \"linear\") {\n const axis = linearAxis({ points: before, rotation: t.rotation });\n const linePoint = v2.add(before[0], v2.scale(axis.n, t.offset ?? 0));\n if (t.rotation !== undefined) t.rotation = v2.angle(lin(axis.u));\n t.offset = v2.dot(\n v2.sub(map(linePoint), t.points[0]),\n linearAxis(t).n,\n );\n } else if (t.kind === \"angular\")\n t.offset = (t.offset ?? 0) * meanScale * (reflect ? -1 : 1);\n const handed = t.kind === \"radial\" || t.kind === \"diameter\";\n t.labels = t.labels.map((l) => ({\n ...l,\n ...(l.along === undefined ? {} : { along: l.along * meanScale }),\n ...(l.across === undefined\n ? {}\n : { across: l.across * meanScale * (handed && reflect ? -1 : 1) }),\n }));\n return t;\n }\n }\n return t;\n };\n\n // Colors inside a block follow AutoCAD's rules: a ByBlock child takes the\n // insert's own color, else the insert's layer color; a ByLayer child on\n // layer 0 takes the insert's layer; a ByLayer child on its own layer keeps\n // that layer's color. The unit insert of a definition build (depth 1,\n // `inheritedColor` undefined, layer 0) leaves ByBlock children uncolored —\n // the instance supplies its color at paint time — and bakes ByLayer\n // children's own-layer colors, since an instance paints every colorless\n // child in its own color.\n const insertBase = baseFor(e, ctx);\n const insertLayerInherits = inheritLayerIds(ctx).has(insertBase.layerId);\n const byBlockColor =\n insertBase.color ??\n inheritedColor ??\n (depth === 0 && !insertLayerInherits\n ? ctx.layerColorById.get(insertBase.layerId)\n : undefined);\n const inDefinition = inheritedColor === undefined && depth >= 1;\n const result: ModelObjectDto[] = [];\n for (const child of block.entities) {\n // Recurse into nested block references, then apply this insert's transform\n // to the exploded children (composing the nested + outer scales/mirrors).\n // A table inside a block converts native first (its *T block is often\n // absent from a DWG transcode, which would leave nothing).\n const childDtos = convertEntity(child, dxf, ctx, depth + 1, byBlockColor);\n const isRef = child.type === \"INSERT\" || child.type === \"ACAD_TABLE\";\n const ci = (child as any).colorIndex as number | undefined;\n const childByBlock = !isRef && ci === 0;\n const childByLayer = !isRef && (ci === undefined || ci === 256);\n for (const dto of childDtos) {\n const t = transform(dto);\n if (!t) continue;\n if (t.color === undefined) {\n if (childByBlock && byBlockColor !== undefined) t.color = byBlockColor;\n else if (\n childByLayer &&\n inDefinition &&\n !inheritLayerIds(ctx).has(t.layerId)\n ) {\n const own = ctx.layerColorById.get(t.layerId);\n if (own !== undefined) t.color = own;\n }\n }\n // Layer 0 inside a block means \"the insert's layer\".\n if (inheritLayerIds(ctx).has(t.layerId) && !insertLayerInherits)\n t.layerId = insertBase.layerId;\n result.push(t);\n }\n }\n // A table whose AcDbTable payload didn't yield a native table is drawn\n // from its *T block: lines + texts, no longer a table.\n if (e.type === \"ACAD_TABLE\" && result.length > 0)\n bump(ctx.degraded, \"ACAD_TABLE→exploded\");\n return result;\n};\n\n/** Paper-space VIEWPORT entity → viewport object (null = not importable). */\nconst convertViewport = (\n e: IEntity,\n ctx: ImportContext,\n): ModelObjectDto | null => {\n const anyE = e as any;\n if (!anyE.center || !(anyE.width > 0) || !(anyE.height > 0)) return null;\n if (!(anyE.viewHeight > 0)) return null;\n const f = ctx.f;\n return {\n type: \"viewport\",\n rect: {\n x: (anyE.center.x - anyE.width / 2) * f,\n y: (anyE.center.y - anyE.height / 2) * f,\n w: anyE.width * f,\n h: anyE.height * f,\n },\n modelCenter: anyE.viewCenter ? pt(anyE.viewCenter, f) : { x: 0, y: 0 },\n // Both in the same unit → the ratio is the 1:N denominator (model mm\n // shown per paper mm).\n scale: anyE.viewHeight / anyE.height,\n locked: ((anyE.statusFlags ?? 0) & VIEWPORT_LOCKED_FLAG) !== 0,\n // 331 = LAYER record handles frozen in this viewport (raw-scanned table).\n hiddenLayerIds: ((anyE.frozenLayerHandles ?? []) as string[]).flatMap(\n (h) => {\n const name = ctx.layerNameByHandle.get(h.toUpperCase());\n const id = name && ctx.layerIdByName.get(name.toLowerCase());\n return id ? [id] : [];\n },\n ),\n ...baseFor(e, ctx),\n };\n};\n\n/** Document state the conversion needs — supplied by the caller (no store). */\nexport interface DxfImportContext {\n /** Existing layers, so DXF layers matched by name reuse the same id. */\n existingLayers: { id: string; name: string }[];\n /** Layer id for entities whose DXF layer has no match. */\n defaultLayerId: string;\n /** The document's text / dimension styles. A file style (STYLE /\n * DIMSTYLE record) matching one by name AND values reuses it; the others\n * are created — a name clash with different values gets a `_2` suffix.\n * Absent = none (the document default is the schema default). */\n existingTextStyles?: readonly TextStyle[];\n existingDimStyles?: readonly DimStyle[];\n /** The document has no content yet: a clashing file style REPLACES the\n * document style's values (same id), and the file's current style\n * ($TEXTSTYLE / $DIMSTYLE) becomes the first = default one. */\n adoptStyles?: boolean;\n /** The document's own line type / hatch pattern definitions: a file\n * definition of a name the document already defines is not re-added (the\n * document's wins). */\n existingLineTypes?: readonly LineType[];\n existingHatchPatterns?: readonly DocumentHatchPattern[];\n /** mm per drawing unit; overrides the file's $INSUNITS when set. */\n unitOverride?: number;\n /** The document's block modules: a generated module the document already\n * holds (same content-hashed id) is reused, not re-added; one whose name\n * a different block takes is suffixed \" (imported)\". */\n existingBlocks?: readonly { id: string; name: string }[];\n}\n\n/** What a DXF import yields — the caller adds these to the document. */\nexport interface DxfImportResult {\n /** Model-space objects to add (DTOs — ids assigned by the caller/funnel). */\n objects: ModelObjectDto[];\n /** Layers that must be created (DXF layers with no name match). */\n newLayers: Layer[];\n /** The document's style arrays AFTER the import: the existing styles\n * (values replaced only under `adoptStyles`), then the created ones —\n * hand them to the whole-array setters, which diff. */\n textStyles: TextStyle[];\n dimStyles: DimStyle[];\n /** The document's line type / hatch pattern arrays AFTER the import: the\n * existing ones, then the file's definitions something used (LTYPE table\n * entries the catalogue lacks; HATCH definition lines). */\n lineTypes: LineType[];\n hatchPatterns: DocumentHatchPattern[];\n /** Paper layouts rebuilt from *Paper_Space blocks (ids already assigned). */\n layouts: PaperLayout[];\n /** Block module sources for the DXF blocks that became instances\n * (blockDefinitions.ts) — merge into `document.blockDefinitions`. */\n newBlockDefinitions: string[];\n /** Source entity type → entities imported as-is (rule R8, entityLedger.ts). */\n imported: Map<string, number>;\n /** `SOURCE→what` → entities imported as an approximation. */\n degraded: Map<string, number>;\n /** Entity type or reason → entities that produced nothing — including the\n * types dxf-parser drops before the importer sees them (ATTRIB, MLINE…). */\n skipped: Map<string, number>;\n}\n\n/**\n * Parse DXF text into model objects, new layers, and paper layouts. Pure and\n * headless — throws on an unparseable file; the editor wraps this with the\n * store read, the undo transaction, zoom-to-fit, and toasts.\n */\nexport const dxfToModel = (\n text: string,\n input: DxfImportContext,\n): DxfImportResult => {\n let dxf: IDxf;\n {\n const parser = new DxfParser();\n parser.registerEntityHandler(ViewportHandler as any);\n parser.registerEntityHandler(HatchHandler as any);\n parser.registerEntityHandler(AcadTableHandler as any);\n parser.registerEntityHandler(LeaderHandler as any);\n parser.registerEntityHandler(MultiLeaderHandler as any);\n parser.registerEntityHandler(AttribHandler as any);\n parser.registerEntityHandler(MlineHandler as any);\n parser.registerEntityHandler(TraceHandler as any);\n const parsed = parser.parseSync(text);\n if (!parsed) throw new Error(\"DXF parse produced no result\");\n dxf = parsed;\n }\n\n const header = dxf.header as Record<string, unknown> | undefined;\n const f =\n input.unitOverride !== undefined && input.unitOverride > 0\n ? input.unitOverride\n : unitFactor(header?.[\"$INSUNITS\"]);\n // Overall dimension scale (DIMSCALE): multiplies text/arrow sizes so a 1:N\n // drawing's dimensions come in at the right size. dxf-parser exposes no\n // DIMSTYLE table or per-dimension style, so the header's current-dimstyle\n // value is the source; carry it onto each dimension's style override.\n const dimScaleRaw = header?.[\"$DIMSCALE\"];\n const dimScale =\n typeof dimScaleRaw === \"number\" && dimScaleRaw > 0 ? dimScaleRaw : 1;\n // Global line type scale: AutoCAD draws every dash pattern × $LTSCALE ×\n // the entity's 48; fold it into each imported lineTypeScale.\n const ltScaleRaw = header?.[\"$LTSCALE\"];\n const ltScale =\n typeof ltScaleRaw === \"number\" && ltScaleRaw > 0 ? ltScaleRaw : 1;\n\n // Split ONCE for every raw-tag pass below (dxfLines.ts): each split of a\n // large file allocates millions of strings, and four passes each doing\n // their own was most of the import's time (mostly garbage collection).\n const lines = dxfLines(text);\n const tags = scanTags(lines);\n\n // Styles: the STYLE / DIMSTYLE records something references (texts by\n // group 7 — absent = \"Standard\" —, dimensions and leaders by group 3,\n // plus the file's current styles on a fresh document) become document\n // styles, merged by name (styleTables.ts).\n const existingText = input.existingTextStyles ?? [];\n const existingDim = input.existingDimStyles ?? [];\n const adopt = input.adoptStyles === true;\n const headerStr = (key: string): string | undefined => {\n const v = header?.[key];\n return typeof v === \"string\" && v.trim() ? v.trim() : undefined;\n };\n const currentText = headerStr(\"$TEXTSTYLE\");\n const currentDim = headerStr(\"$DIMSTYLE\");\n const defaultTextHeight = (existingText[0] ?? DEFAULT_TEXT_STYLE).textHeight;\n const styleRecordNamed = (name: string): StyleRecord | undefined =>\n tags.textStyles.get(name) ??\n [...tags.textStyles.values()].find(\n (r) => r.name.toLowerCase() === name.toLowerCase(),\n );\n const usedTextStyles = new Set<string>();\n for (const name of tags.textStyleNameByHandle.values())\n usedTextStyles.add(name.toLowerCase());\n for (const key of tags.textHeightsByStyle.keys())\n usedTextStyles.add(key || \"standard\");\n if (adopt && currentText) usedTextStyles.add(currentText.toLowerCase());\n const incomingText: {\n name: string;\n values: Omit<TextStyle, \"id\" | \"name\">;\n }[] = [];\n for (const key of usedTextStyles) {\n const rec = styleRecordNamed(key);\n if (!rec) continue;\n const heights = new Map(tags.textHeightsByStyle.get(key) ?? []);\n if (key === \"standard\")\n for (const [h, n] of tags.textHeightsByStyle.get(\"\") ?? [])\n heights.set(h, (heights.get(h) ?? 0) + n);\n incomingText.push({\n name: rec.name,\n values: textStyleFromRecord(rec, heights, f, defaultTextHeight),\n });\n }\n const mergedText = mergeStyles(existingText, incomingText, sameTextStyle, {\n adopt,\n current: currentText,\n });\n\n const dimValueCtx = {\n f,\n textStyleByHandle: tags.textStyleByHandle,\n blockNameByHandle: tags.blockNameByHandle,\n };\n // The header's current dimension variables, keyed like DIMSTYLE groups —\n // what a record that leaves a group out falls back to.\n const headerDim = new Map<number, string>();\n for (const [key, code] of [\n [\"$DIMTXT\", 140],\n [\"$DIMASZ\", 41],\n [\"$DIMTSZ\", 142],\n [\"$DIMEXO\", 42],\n [\"$DIMEXE\", 44],\n [\"$DIMGAP\", 147],\n [\"$DIMDEC\", 271],\n ] as const) {\n const v = header?.[key];\n if (typeof v === \"number\") headerDim.set(code, String(v));\n }\n const usedDimStyles = new Set<string>();\n for (const name of tags.dimStyleNameByHandle.values())\n usedDimStyles.add(name.toLowerCase());\n if (adopt && currentDim) usedDimStyles.add(currentDim.toLowerCase());\n const incomingDim: { name: string; values: Omit<DimStyle, \"id\" | \"name\"> }[] =\n [];\n const dimScaleByName = new Map<string, number>();\n for (const key of usedDimStyles) {\n const rec = [...tags.dimStyles.values()].find(\n (r) => r.name.toLowerCase() === key,\n );\n if (!rec) continue;\n const { values, scale } = dimStyleFromRecord(rec, headerDim, dimValueCtx);\n incomingDim.push({ name: rec.name, values });\n dimScaleByName.set(key, scale);\n }\n const mergedDim = mergeStyles(existingDim, incomingDim, sameDimStyle, {\n adopt,\n current: currentDim,\n });\n const dimScaleByStyleId = new Map<string, number>();\n for (const [key, id] of mergedDim.idByName)\n dimScaleByStyleId.set(id, dimScaleByName.get(key) ?? 1);\n\n // The file's LTYPE table: definitions the catalogue does not know become\n // document line types when something uses them (dashes × f; a known name\n // keeps mapping to the catalogue). Complex line types keep their dash\n // skeleton — the embedded shapes/text are not rendered.\n const customLineTypes = {\n customLineTypes: new Map<string, LineType>(),\n usedLineTypes: new Map<string, LineType>(),\n };\n const ltypes = (dxf.tables as any)?.lineType?.lineTypes ?? {};\n for (const [name, rec] of Object.entries(ltypes) as [string, any][]) {\n const n = String(rec?.name ?? name).trim();\n if (!n || /^(bylayer|byblock|continuous)$/i.test(n)) continue;\n if (getLineType(n)) continue;\n const pattern: unknown[] = Array.isArray(rec?.pattern) ? rec.pattern : [];\n const dashes = pattern\n .map((v) => Number(v))\n .filter((v) => Number.isFinite(v))\n .map((v) => v * f);\n if (dashes.length === 0 || dashes.every((v) => v === 0)) continue;\n const description =\n typeof rec?.description === \"string\" && rec.description.trim()\n ? rec.description.trim()\n : undefined;\n // The document's own definition of this name wins (its spelling, its\n // dashes); the file's is only a reference to it.\n const existing = (input.existingLineTypes ?? []).find(\n (t) => lineTypeKey(t.name) === lineTypeKey(n),\n );\n customLineTypes.customLineTypes.set(\n lineTypeKey(n),\n existing ?? {\n name: n,\n ...(description ? { description } : {}),\n dashesMm: dashes,\n },\n );\n }\n\n // Layers: match by name, create the missing ones. Keys are lowercased:\n // DXF layer names are case-insensitive, and so are Linea's (one layer\n // per name, op layer) — \"Walls\" and \"WALLS\" are the same layer.\n const layerIdByName = new Map<string, string>();\n for (const layer of input.existingLayers)\n layerIdByName.set(layer.name.toLowerCase(), layer.id);\n const newLayers: Layer[] = [];\n const dxfLayers = dxf.tables?.layer?.layers ?? {};\n for (const [name, dxfLayer] of Object.entries(dxfLayers)) {\n if (layerIdByName.has(name.toLowerCase())) continue;\n const colorInt = (dxfLayer as { color?: number }).color ?? 0xffffff;\n const layerTags = tags.layers.get(name);\n newLayers.push({\n id: crypto.randomUUID(),\n name,\n color:\n tags.trueColorByLayerName.get(name) ??\n rgbToHex(\n (colorInt >> 16) & 0xff,\n (colorInt >> 8) & 0xff,\n colorInt & 0xff,\n ),\n // Line type (6), lineweight (370), lock bit (70) and plot flag (290)\n // come from the raw scan — dxf-parser reads only name, color and\n // frozen. A 2/X2 variant's factor is dropped (layers have no\n // lineTypeScale) — still the closest rendering.\n lineType:\n lineTypeFromDxf(layerTags?.lineType, customLineTypes)?.name ??\n \"continuous\",\n lineWidth: lineWeightToMm(layerTags?.lineWeight) ?? IMPORT_LINE_WIDTH_MM,\n opacity: 1,\n // Off (62 < 0) and frozen (70 bit 1) both hide the layer.\n visible:\n (dxfLayer as { visible?: boolean }).visible !== false &&\n (dxfLayer as { frozen?: boolean }).frozen !== true,\n locked: layerTags?.locked ?? false,\n print: layerTags?.plot ?? true,\n });\n layerIdByName.set(name.toLowerCase(), newLayers[newLayers.length - 1].id);\n }\n const ctx: ImportContext = {\n f,\n layerIdByName,\n // Existing layers ({id,name} only) can't be classified — entity-level\n // line types still gate correctly; byLayer dashes there stay unscaled.\n dashedLayerIds: new Set(\n newLayers\n .filter((l) => (getLineType(l.lineType)?.dashesMm.length ?? 0) > 0)\n .map((l) => l.id),\n ),\n defaultLayerId: input.defaultLayerId,\n ...emptyLedger(),\n textStyleById: new Map(mergedText.styles.map((s) => [s.id, s])),\n dimStyleById: new Map(mergedDim.styles.map((s) => [s.id, s])),\n textStyleIdByName: mergedText.idByName,\n dimStyleIdByName: mergedDim.idByName,\n dimScaleByStyleId,\n defaultTextStyle: mergedText.styles[0] ?? DEFAULT_TEXT_STYLE,\n defaultDimStyle: mergedDim.styles[0] ?? DEFAULT_DIM_STYLE,\n dimValuesFrom: (groups) => dimValuesFromGroups(groups, dimValueCtx),\n dimScale,\n ltScale,\n tags,\n mlineStyles: parseMlineStyles(lines),\n ...customLineTypes,\n // Pre-seeded with the document's own patterns: a file hatch naming one\n // references it (the document's spelling) instead of redefining it.\n hatchPatterns: new Map(\n (input.existingHatchPatterns ?? []).map((h) => [\n hatchPatternKey(h.name),\n h,\n ]),\n ),\n blockDefinitions: new Map(),\n newBlockDefinitions: [],\n existingBlocks: input.existingBlocks ?? [],\n layerWidthById: new Map(newLayers.map((l) => [l.id, l.lineWidth])),\n layerColorById: new Map(newLayers.map((l) => [l.id, l.color])),\n layerNameByHandle: new Map(\n [...tags.layers]\n .filter(([, t]) => t.handle !== undefined)\n .map(([name, t]) => [t.handle!.toUpperCase(), name]),\n ),\n };\n\n // Paper spaces: entities live inside *Paper_Space blocks, EXCEPT the\n // active layout's, which sit flat in ENTITIES with the paper-space flag.\n const paperBlocks = Object.values(dxf.blocks ?? {}).filter((b) =>\n /^\\*paper_space/i.test((b as IBlock).name ?? \"\"),\n ) as IBlock[];\n const primaryPaper =\n paperBlocks.find((b) => b.name.toLowerCase() === \"*paper_space\") ??\n paperBlocks[0];\n const paperEntities = new Map<IBlock, IEntity[]>(\n paperBlocks.map((b) => [b, [...(b.entities ?? [])]]),\n );\n\n const dtos: ModelObjectDto[] = [];\n for (const entity of dxf.entities ?? []) {\n if ((entity as any).inPaperSpace) {\n if (primaryPaper) paperEntities.get(primaryPaper)?.push(entity);\n else {\n ctx.seen.add(entity.type);\n bump(ctx.skipped, `${entity.type} (paper space)`);\n }\n continue;\n }\n if (entity.type === \"VIEWPORT\") {\n // Stray model-space viewport: nothing to show.\n ctx.seen.add(\"VIEWPORT\");\n bump(ctx.skipped, \"VIEWPORT\");\n continue;\n }\n dtos.push(...convertEntity(entity, dxf, ctx));\n }\n\n // Rebuild paper layouts. LAYOUT objects (raw OBJECTS scan) supply name,\n // tab order, and sheet size; the layout's own id-1 viewport is the sheet\n // fallback. Empty spaces are skipped.\n const layoutInfos = parseLayoutObjects(lines);\n const infoFor = (block: IBlock) =>\n layoutInfos.find(\n (li) =>\n li.blockRecordHandle !== undefined &&\n li.blockRecordHandle === String(block.ownerHandle ?? \"\").toUpperCase(),\n );\n const orderedBlocks = [...paperEntities.keys()].sort(\n (a, b) =>\n (infoFor(a)?.tabOrder ?? Number.MAX_SAFE_INTEGER) -\n (infoFor(b)?.tabOrder ?? Number.MAX_SAFE_INTEGER),\n );\n\n const newLayouts: PaperLayout[] = [];\n for (const block of orderedBlocks) {\n const entities = paperEntities.get(block) ?? [];\n if (entities.length === 0) continue;\n const info = infoFor(block);\n let sheetFallback: { w: number; h: number } | null = null;\n const objects: ModelObject[] = [];\n for (const e of entities) {\n const anyE = e as any;\n if (e.type === \"VIEWPORT\") {\n ctx.seen.add(\"VIEWPORT\");\n if (anyE.viewportId === 1) {\n // The layout's own paper view — remember its size for the sheet.\n if (anyE.width > 0 && anyE.height > 0)\n sheetFallback = { w: anyE.width * f, h: anyE.height * f };\n bump(ctx.imported, \"VIEWPORT\");\n continue;\n }\n // Switched-off viewport (90 bit 0x20000): nothing is displayed. (68\n // is NOT the switch — AutoCAD writes 68 = 0 for every viewport of a\n // layout that was not current when the file was saved.)\n if (((anyE.statusFlags ?? 0) & VIEWPORT_OFF_FLAG) !== 0) {\n bump(ctx.skipped, \"VIEWPORT (hidden)\");\n continue;\n }\n const vp = convertViewport(e, ctx);\n if (vp) {\n objects.push({ ...vp, id: crypto.randomUUID() } as ModelObject);\n bump(ctx.imported, \"VIEWPORT\");\n } else bump(ctx.skipped, \"VIEWPORT\");\n continue;\n }\n for (const dto of convertEntity(e, dxf, ctx))\n objects.push({ ...dto, id: crypto.randomUUID() } as ModelObject);\n }\n if (objects.length === 0) continue;\n try {\n newLayouts.push(\n PaperLayoutSchema.parse({\n id: crypto.randomUUID(),\n name: info?.name || `Layout ${newLayouts.length + 1}`,\n sheet: {\n width: info?.paperWidth ?? sheetFallback?.w ?? 297,\n height: info?.paperHeight ?? sheetFallback?.h ?? 210,\n },\n objects,\n }),\n );\n } catch (err) {\n console.error(\"layout import failed\", block.name, err);\n bump(ctx.skipped, \"layout\");\n }\n }\n\n // Resilience: drop any object that fails schema validation (counting it as\n // skipped) so a single malformed entity can't abort the whole import — the\n // funnel validates the batch all-or-nothing.\n const validObjects: ModelObjectDto[] = [];\n for (const dto of dtos) {\n if (ModelObjectSchema.safeParse({ ...dto, id: \"_\" }).success) {\n validObjects.push(dto);\n } else {\n const key = `invalid ${dto.type}`;\n bump(ctx.skipped, key);\n }\n }\n\n // Types dxf-parser dropped before any converter saw them (R8).\n reconcileLedger(ctx, scanEntityHistogram(lines));\n return {\n objects: validObjects,\n newLayers,\n textStyles: mergedText.styles,\n dimStyles: mergedDim.styles,\n lineTypes: [\n ...(input.existingLineTypes ?? []),\n ...[...ctx.usedLineTypes.values()].filter(\n (t) =>\n !(input.existingLineTypes ?? []).some(\n (x) => lineTypeKey(x.name) === lineTypeKey(t.name),\n ),\n ),\n ],\n hatchPatterns: [\n ...(input.existingHatchPatterns ?? []),\n ...[...ctx.hatchPatterns.values()].filter(\n (h) =>\n !(input.existingHatchPatterns ?? []).some(\n (x) => hatchPatternKey(x.name) === hatchPatternKey(h.name),\n ),\n ),\n ],\n newBlockDefinitions: ctx.newBlockDefinitions.map((d) => d.source),\n layouts: newLayouts,\n imported: ctx.imported,\n degraded: ctx.degraded,\n skipped: ctx.skipped,\n };\n};\n","// DXF STYLE / DIMSTYLE tables → the document's named text and dimension\n// styles (docs/dxf-dwg-fidelity.md §3 rows 5–6). The raw records come from\n// the importer's tag scan (dxf-parser reads neither table); this module is\n// the pure mapping: record values → Linea style values, the same mapping\n// for a DIMENSION's DSTYLE xdata (the per-entity overrides AutoCAD stores\n// as DIMSTYLE group → value pairs), and the merge rule against the styles\n// the document already has.\n//\n// Merge rule (mirrors layers: match by name, else create): a file style\n// whose name AND values agree with a document style reuses it; a name clash\n// with different values creates `Name_2` — unless the document has no\n// content yet (`adopt`), in which case the file's values replace the\n// document style's (same id) and the file's CURRENT style becomes the first\n// (= default) style. Only styles something references are created.\n\nimport {\n DEFAULT_DIM_STYLE,\n DEFAULT_TEXT_STYLE,\n type ArrowType,\n type DimStyle,\n type TextStyle,\n} from \"../../model/objects\";\nimport { fontFromDxfStyle } from \"../../model/fonts\";\n\n/** A STYLE table record (groups dxf-parser never reads). */\nexport interface StyleRecord {\n handle?: string;\n name: string;\n /** Group 3 — font file (`arial.ttf`, `romans.shx`). */\n fontFile?: string;\n /** ACAD xdata 1000 — TrueType family AutoCAD resolved the file to. */\n typeface?: string;\n /** Group 40 — fixed height (0 = asked per text). */\n fixedHeight: number;\n /** Group 41. */\n widthFactor: number;\n /** Group 50 — oblique angle in degrees. */\n oblique: number;\n /** ACAD xdata 1071 — packed font flags (italic 0x1000000, bold 0x2000000). */\n flags: number;\n /** Group 70 bit 1 — a shape file, not a text style. */\n shape: boolean;\n}\n\n/** A DIMSTYLE record: group code → raw value, plus its 105 handle. */\nexport interface DimStyleRecord {\n handle?: string;\n name: string;\n groups: Map<number, string>;\n}\n\nexport const emptyStyleRecord = (): StyleRecord => ({\n name: \"\",\n fixedHeight: 0,\n widthFactor: 1,\n oblique: 0,\n flags: 0,\n shape: false,\n});\n\n/** Standard arrowhead block names → our arrow types (\"\" = ClosedFilled). */\nexport const arrowTypeFromBlock = (name: string): ArrowType => {\n const n = name.replace(/^_/, \"\").toLowerCase();\n if (n === \"\" || n === \"closedfilled\") return \"filled\";\n if (/^(open|open30|open90|closed|closedblank)$/.test(n)) return \"open\";\n if (/^(archtick|oblique|integral)$/.test(n)) return \"tick\";\n if (\n /^(dot|dotsmall|dotblank|small|origin|origin2|boxblank|boxfilled|datumblank|datumfilled)$/.test(\n n,\n )\n )\n return \"dot\";\n if (n === \"none\") return \"none\";\n return \"filled\";\n};\n\n/** The text-side values a STYLE record carries (no height — see\n * `textStyleFromRecord`). */\nexport const textFaceFromRecord = (\n rec: Pick<\n StyleRecord,\n \"fontFile\" | \"typeface\" | \"widthFactor\" | \"oblique\" | \"flags\"\n >,\n): Pick<TextStyle, \"font\" | \"widthFactor\" | \"bold\" | \"italic\"> => {\n const face = fontFromDxfStyle(rec.fontFile, rec.typeface);\n const bold = face.bold === true || (rec.flags & 0x2000000) !== 0;\n // AutoCAD's italic flag, or an oblique angle — the SHX way to slant.\n const italic =\n face.italic === true || (rec.flags & 0x1000000) !== 0 || rec.oblique > 0;\n return {\n font: face.font,\n widthFactor: rec.widthFactor > 0 ? rec.widthFactor : 1,\n ...(bold ? { bold: true } : {}),\n ...(italic ? { italic: true } : {}),\n };\n};\n\n/** Height → count of the texts using a style (the scan collects it). */\nexport type HeightHistogram = Map<number, number>;\n\nconst modeOf = (hist: HeightHistogram | undefined): number | undefined => {\n let best: number | undefined;\n let bestN = 0;\n for (const [h, n] of hist ?? [])\n if (n > bestN || (n === bestN && best !== undefined && h < best)) {\n best = h;\n bestN = n;\n }\n return best;\n};\n\n/**\n * STYLE record → text style values (mm). A fixed height is the style's; a\n * style with none (AutoCAD asks per text) takes the height most of its\n * texts use, so most of them need no override.\n */\nexport const textStyleFromRecord = (\n rec: StyleRecord,\n heights: HeightHistogram | undefined,\n f: number,\n fallbackHeight: number,\n): Omit<TextStyle, \"id\" | \"name\"> => ({\n ...textFaceFromRecord(rec),\n textHeight:\n rec.fixedHeight > 0\n ? rec.fixedHeight * f\n : (modeOf(heights) ?? fallbackHeight / f) * f,\n arrowType: DEFAULT_TEXT_STYLE.arrowType,\n arrowSize: DEFAULT_TEXT_STYLE.arrowSize,\n});\n\n/** What a DIMSTYLE group mapping needs to resolve handles. */\nexport interface DimValueContext {\n /** mm per drawing unit. */\n f: number;\n /** STYLE record by handle (DIMTXSTY 340). */\n textStyleByHandle: Map<string, StyleRecord>;\n /** BLOCK_RECORD name by handle (DIMBLK 342 / DIMBLK1 343 / DIMBLK2 344). */\n blockNameByHandle: Map<string, string>;\n}\n\n/** Dim style values plus the style's DIMSCALE — ours lives on the object. */\nexport type DimValues = Partial<Omit<DimStyle, \"id\" | \"name\">> & {\n scale?: number;\n};\n\nconst num = (v: string | undefined): number | undefined => {\n if (v === undefined) return undefined;\n const n = Number(v);\n return Number.isFinite(n) ? n : undefined;\n};\n\n/**\n * DIMSTYLE groups → the style values they set (SPARSE: only present groups,\n * so the same mapping yields a record's values and an entity's DSTYLE\n * overrides). Lengths scale to mm; DIMTSZ > 0 means oblique ticks instead\n * of arrowheads; DIMSAH picks the first-end block.\n */\nexport const dimValuesFromGroups = (\n groups: Map<number, string>,\n ctx: DimValueContext,\n): DimValues => {\n const out: DimValues = {};\n const g = (code: number) => num(groups.get(code));\n const txt = g(140);\n if (txt !== undefined && txt > 0) out.textHeight = txt * ctx.f;\n const asz = g(41);\n if (asz !== undefined && asz > 0) out.arrowSize = asz * ctx.f;\n const tsz = g(142);\n if (tsz !== undefined && tsz > 0) {\n out.arrowType = \"tick\";\n out.arrowSize = tsz * ctx.f;\n } else {\n // The block: by R12 name (5/6), by BLOCK_RECORD handle (342/343), or —\n // some writers, ours included, put the NAME in 342 — the raw value.\n const separate = g(173) === 1;\n const ref = groups.get(separate ? 343 : 342);\n const legacy = groups.get(separate ? 6 : 5);\n const blockName =\n legacy ??\n (ref !== undefined\n ? (ctx.blockNameByHandle.get(ref.toUpperCase()) ??\n (/^[0-9A-Fa-f]+$/.test(ref) ? undefined : ref))\n : undefined);\n if (blockName !== undefined) out.arrowType = arrowTypeFromBlock(blockName);\n else if (ref !== undefined) out.arrowType = \"filled\";\n }\n const gap = g(147);\n if (gap !== undefined) out.textOffset = Math.abs(gap) * ctx.f; // < 0 = boxed text\n const exo = g(42);\n if (exo !== undefined) out.extensionOffset = exo * ctx.f;\n const exe = g(44);\n if (exe !== undefined) out.extensionOvershoot = exe * ctx.f;\n const dec = g(271);\n if (dec !== undefined)\n out.precision = Math.max(0, Math.min(6, Math.round(dec)));\n const scale = g(40);\n // 0 = \"computed from the viewport\" — model space draws it at 1.\n if (scale !== undefined) out.scale = scale > 0 ? scale : 1;\n const txsty = groups.get(340);\n if (txsty !== undefined) {\n const rec = ctx.textStyleByHandle.get(txsty.toUpperCase());\n if (rec) Object.assign(out, textFaceFromRecord(rec));\n }\n return out;\n};\n\n/** AutoCAD's own defaults for groups a DIMSTYLE record leaves out (drawing\n * units — acad.dwt's inch values; metric templates write every group). */\nconst DIMSTYLE_DEFAULTS: Map<number, string> = new Map([\n [140, \"0.18\"],\n [41, \"0.18\"],\n [42, \"0.0625\"],\n [44, \"0.18\"],\n [147, \"0.09\"],\n [271, \"4\"],\n]);\n\n/**\n * DIMSTYLE record → a full dim style (mm). Groups the record leaves out fall\n * back to the HEADER's current values (`$DIMTXT`…, keyed by the same group\n * codes), then AutoCAD's defaults.\n */\nexport const dimStyleFromRecord = (\n rec: DimStyleRecord,\n header: Map<number, string>,\n ctx: DimValueContext,\n): { values: Omit<DimStyle, \"id\" | \"name\">; scale: number } => {\n const groups = new Map(DIMSTYLE_DEFAULTS);\n for (const [k, v] of header) groups.set(k, v);\n for (const [k, v] of rec.groups) groups.set(k, v);\n const { scale, ...values } = dimValuesFromGroups(groups, ctx);\n const base = DEFAULT_DIM_STYLE;\n return {\n values: {\n font: values.font ?? base.font,\n widthFactor: values.widthFactor ?? base.widthFactor,\n ...(values.bold ? { bold: true } : {}),\n ...(values.italic ? { italic: true } : {}),\n textHeight: values.textHeight ?? base.textHeight,\n textOffset: values.textOffset ?? base.textOffset,\n arrowType: values.arrowType ?? \"filled\",\n arrowSize: values.arrowSize ?? base.arrowSize,\n extensionType: \"long\",\n extensionOffset: values.extensionOffset ?? base.extensionOffset,\n extensionOvershoot: values.extensionOvershoot ?? base.extensionOvershoot,\n precision: values.precision ?? base.precision,\n },\n scale: scale ?? 1,\n };\n};\n\nconst near = (a: number, b: number) =>\n Math.abs(a - b) <= 1e-6 * Math.max(1, Math.abs(a));\n\nconst sameFace = (\n a: Pick<TextStyle, \"font\" | \"widthFactor\" | \"bold\" | \"italic\">,\n b: Pick<TextStyle, \"font\" | \"widthFactor\" | \"bold\" | \"italic\">,\n) =>\n a.font === b.font &&\n near(a.widthFactor, b.widthFactor) &&\n (a.bold ?? false) === (b.bold ?? false) &&\n (a.italic ?? false) === (b.italic ?? false);\n\nexport const sameTextStyle = (\n a: Omit<TextStyle, \"id\" | \"name\">,\n b: Omit<TextStyle, \"id\" | \"name\">,\n): boolean => sameFace(a, b) && near(a.textHeight, b.textHeight);\n\nexport const sameDimStyle = (\n a: Omit<DimStyle, \"id\" | \"name\">,\n b: Omit<DimStyle, \"id\" | \"name\">,\n): boolean =>\n sameFace(a, b) &&\n near(a.textHeight, b.textHeight) &&\n near(a.textOffset, b.textOffset) &&\n a.arrowType === b.arrowType &&\n near(a.arrowSize, b.arrowSize) &&\n a.extensionType === b.extensionType &&\n near(a.extensionOffset, b.extensionOffset) &&\n near(a.extensionOvershoot, b.extensionOvershoot) &&\n a.precision === b.precision;\n\n/**\n * The keys of `values` that differ from `base` — a sparse override, the\n * same discipline as the schema's (never bake equal values in).\n */\nexport const overrideAgainst = <T extends Record<string, unknown>>(\n base: T,\n values: Partial<T>,\n): Partial<T> => {\n const out: Partial<T> = {};\n for (const key of Object.keys(values) as (keyof T)[]) {\n const v = values[key];\n if (v === undefined) continue;\n const b = base[key];\n const equal =\n typeof v === \"number\" && typeof b === \"number\"\n ? near(v, b)\n : typeof v === \"boolean\"\n ? v === (b ?? false)\n : v === b;\n if (!equal) out[key] = v;\n }\n return out;\n};\n\n/** One merge of file styles into the document's. */\nexport interface MergedStyles<S extends { id: string; name: string }> {\n /** The document's styles after the import (existing first, then created). */\n styles: S[];\n /** DXF style name (lower-cased) → the document style id it resolves to. */\n idByName: Map<string, string>;\n created: number;\n}\n\nexport const mergeStyles = <S extends { id: string; name: string }>(\n existing: readonly S[],\n incoming: { name: string; values: Omit<S, \"id\" | \"name\"> }[],\n same: (a: Omit<S, \"id\" | \"name\">, b: Omit<S, \"id\" | \"name\">) => boolean,\n opts: { adopt: boolean; current?: string },\n): MergedStyles<S> => {\n const styles: S[] = [...existing];\n const idByName = new Map<string, string>();\n const taken = new Set(existing.map((s) => s.name.toLowerCase()));\n let created = 0;\n for (const { name, values } of incoming) {\n const key = name.toLowerCase();\n if (idByName.has(key)) continue;\n const at = styles.findIndex((s) => s.name.toLowerCase() === key);\n if (at !== -1) {\n const ex = styles[at];\n if (same(ex, values)) {\n idByName.set(key, ex.id);\n continue;\n }\n if (opts.adopt) {\n styles[at] = { ...values, id: ex.id, name: ex.name } as S;\n idByName.set(key, ex.id);\n continue;\n }\n }\n let unique = name;\n for (let i = 2; taken.has(unique.toLowerCase()); i++)\n unique = `${name}_${i}`;\n taken.add(unique.toLowerCase());\n const style = { ...values, id: crypto.randomUUID(), name: unique } as S;\n styles.push(style);\n idByName.set(key, style.id);\n created++;\n }\n // The file's current style is what its author draws new objects with —\n // on a fresh document, make it ours too.\n if (opts.adopt && opts.current) {\n const id = idByName.get(opts.current.toLowerCase());\n const at = id ? styles.findIndex((s) => s.id === id) : -1;\n if (at > 0) styles.unshift(...styles.splice(at, 1));\n }\n return { styles, idByName, created };\n};\n","// NURBS evaluation for DXF SPLINE import (docs/dxf-dwg-fidelity.md §3 row\n// 13): de Boor's algorithm in homogeneous coordinates (rational when weights\n// are given), plus an adaptive sampler that turns a curve into a polyline\n// within a chord tolerance. Pure; no model types.\n\nimport type { Vec2 } from \"./vec2\";\n\nexport interface NurbsCurve {\n degree: number;\n /** Control points, n of them. */\n controlPoints: Vec2[];\n /** Knot vector, n + degree + 1 values, non-decreasing. */\n knots: number[];\n /** One weight per control point; absent = non-rational (all 1). */\n weights?: number[];\n}\n\n/** The parameter range the curve is defined on: [knots[p], knots[n]]. */\nexport const nurbsDomain = (c: NurbsCurve): [number, number] => {\n const n = c.controlPoints.length;\n return [c.knots[c.degree], c.knots[n]];\n};\n\n/** Index of the knot span containing u (the last span for u at the end). */\nconst findSpan = (c: NurbsCurve, u: number): number => {\n const n = c.controlPoints.length;\n const p = c.degree;\n if (u >= c.knots[n]) return n - 1;\n if (u <= c.knots[p]) return p;\n let lo = p;\n let hi = n;\n let mid = (lo + hi) >> 1;\n while (u < c.knots[mid] || u >= c.knots[mid + 1]) {\n if (u < c.knots[mid]) hi = mid;\n else lo = mid;\n mid = (lo + hi) >> 1;\n }\n return mid;\n};\n\n/** The curve point at parameter u (de Boor, homogeneous). */\nexport const evaluateNurbs = (c: NurbsCurve, u: number): Vec2 => {\n const p = c.degree;\n const k = findSpan(c, u);\n // Working copy of the p+1 affected control points as (wx, wy, w).\n const d: [number, number, number][] = [];\n for (let j = 0; j <= p; j++) {\n const i = k - p + j;\n const cp = c.controlPoints[i];\n const w = c.weights?.[i] ?? 1;\n d.push([cp.x * w, cp.y * w, w]);\n }\n for (let r = 1; r <= p; r++)\n for (let j = p; j >= r; j--) {\n const i = k - p + j;\n const den = c.knots[i + p - r + 1] - c.knots[i];\n const a = den === 0 ? 0 : (u - c.knots[i]) / den;\n d[j] = [\n (1 - a) * d[j - 1][0] + a * d[j][0],\n (1 - a) * d[j - 1][1] + a * d[j][1],\n (1 - a) * d[j - 1][2] + a * d[j][2],\n ];\n }\n const [x, y, w] = d[p];\n return w === 0 ? { x, y } : { x: x / w, y: y / w };\n};\n\n/** A curve is well-formed when the knot count matches n + p + 1 and there\n * are more control points than the degree. */\nexport const isValidNurbs = (c: NurbsCurve): boolean =>\n c.degree >= 1 &&\n c.controlPoints.length > c.degree &&\n c.knots.length === c.controlPoints.length + c.degree + 1 &&\n (c.weights === undefined || c.weights.length === c.controlPoints.length) &&\n c.knots.every((v, i) => i === 0 || v >= c.knots[i - 1]);\n\n/**\n * Sample the curve into a polyline: each knot span is split until the\n * chord's midpoint lies within `tolerance` of the curve (depth-capped), so\n * straight runs stay sparse and tight bends get dense. Degenerate (zero\n * length) spans contribute nothing.\n */\nexport const sampleNurbs = (\n c: NurbsCurve,\n tolerance: number,\n maxDepth = 10,\n): Vec2[] => {\n const [u0, u1] = nurbsDomain(c);\n const out: Vec2[] = [evaluateNurbs(c, u0)];\n const push = (q: Vec2) => {\n const last = out[out.length - 1];\n if (Math.hypot(q.x - last.x, q.y - last.y) > 1e-9) out.push(q);\n };\n const refine = (a: number, pa: Vec2, b: number, pb: Vec2, depth: number) => {\n const m = (a + b) / 2;\n const pm = evaluateNurbs(c, m);\n const chord = { x: (pa.x + pb.x) / 2, y: (pa.y + pb.y) / 2 };\n const dev = Math.hypot(pm.x - chord.x, pm.y - chord.y);\n if (depth >= maxDepth || dev <= tolerance) {\n // A flat chord may still hide an S-bend symmetric about the middle:\n // keep the midpoint when the chord is long relative to the tolerance.\n if (dev > tolerance / 4) push(pm);\n push(pb);\n return;\n }\n refine(a, pa, m, pm, depth + 1);\n refine(m, pm, b, pb, depth + 1);\n };\n // Span by span, so every knot (a possible tangent break) is a vertex.\n const spans: number[] = [];\n for (let i = c.degree; i < c.controlPoints.length; i++) {\n const a = Math.max(c.knots[i], u0);\n const b = Math.min(c.knots[i + 1], u1);\n if (b > a) spans.push(a, b);\n }\n for (let i = 0; i < spans.length; i += 2) {\n const a = spans[i];\n const b = spans[i + 1];\n const pa = evaluateNurbs(c, a);\n const pb = evaluateNurbs(c, b);\n // Two levels unconditionally: a chord between span ends can be flat by\n // symmetry (a full-circle span, say) while the curve is not.\n const m = (a + b) / 2;\n const pm = evaluateNurbs(c, m);\n refine(a, pa, m, pm, 1);\n refine(m, pm, b, pb, 1);\n }\n return dropCollinear(out, tolerance / 10);\n};\n\n/** Drop interior vertices that lie within `eps` of the chord between their\n * neighbours — the unconditional span midpoints on a straight run. */\nconst dropCollinear = (pts: Vec2[], eps: number): Vec2[] => {\n if (pts.length < 3) return pts;\n const out: Vec2[] = [pts[0]];\n for (let i = 1; i < pts.length - 1; i++) {\n const a = out[out.length - 1];\n const b = pts[i + 1];\n const q = pts[i];\n const abx = b.x - a.x;\n const aby = b.y - a.y;\n const len2 = abx * abx + aby * aby;\n const t =\n len2 === 0\n ? 0\n : Math.max(\n 0,\n Math.min(1, ((q.x - a.x) * abx + (q.y - a.y) * aby) / len2),\n );\n const dist = Math.hypot(q.x - (a.x + t * abx), q.y - (a.y + t * aby));\n if (dist > eps) out.push(q);\n }\n out.push(pts[pts.length - 1]);\n return out;\n};\n\n/**\n * The clamped B-spline of the given degree that passes THROUGH `points`\n * (global curve interpolation, Piegl & Tiller A9.1: chord-length parameters,\n * averaged knots, one linear solve). A DXF SPLINE that carries only fit\n * points (74 / 11) is this curve. Fewer points than degree + 1 lower the\n * degree; two points give the segment between them.\n */\nexport const interpolateFitPoints = (\n points: Vec2[],\n degree = 3,\n): NurbsCurve | null => {\n const n = points.length;\n if (n < 2) return null;\n const p = Math.min(degree, n - 1);\n // Chord-length parameters.\n const u: number[] = [0];\n let total = 0;\n for (let i = 1; i < n; i++) {\n total += Math.hypot(\n points[i].x - points[i - 1].x,\n points[i].y - points[i - 1].y,\n );\n u.push(total);\n }\n if (total === 0) return null;\n for (let i = 0; i < n; i++) u[i] /= total;\n // Averaged knots: p+1 zeros, n−p−1 interior averages, p+1 ones.\n const knots: number[] = new Array(p + 1).fill(0);\n for (let j = 1; j <= n - p - 1; j++) {\n let s = 0;\n for (let i = j; i <= j + p - 1; i++) s += u[i];\n knots.push(s / p);\n }\n knots.push(...new Array(p + 1).fill(1));\n // Basis matrix N[i][j] = N_{j,p}(u_i), solved by Gaussian elimination\n // (n is small for a drawing's spline).\n const basisRow = (ui: number): number[] => {\n const row = new Array(n).fill(0);\n const probe: NurbsCurve = {\n degree: p,\n controlPoints: points.map(() => ({ x: 0, y: 0 })),\n knots,\n };\n // N_{j,p}(u) is the curve with a unit x at control point j.\n for (let j = 0; j < n; j++) {\n probe.controlPoints = points.map((_, k) => ({\n x: k === j ? 1 : 0,\n y: 0,\n }));\n row[j] = evaluateNurbs(probe, ui).x;\n }\n return row;\n };\n const A = u.map((ui) => basisRow(ui));\n const bx = points.map((q) => q.x);\n const by = points.map((q) => q.y);\n for (let col = 0; col < n; col++) {\n let pivot = col;\n for (let r = col + 1; r < n; r++)\n if (Math.abs(A[r][col]) > Math.abs(A[pivot][col])) pivot = r;\n if (Math.abs(A[pivot][col]) < 1e-12) return null;\n [A[col], A[pivot]] = [A[pivot], A[col]];\n [bx[col], bx[pivot]] = [bx[pivot], bx[col]];\n [by[col], by[pivot]] = [by[pivot], by[col]];\n for (let r = 0; r < n; r++) {\n if (r === col) continue;\n const k = A[r][col] / A[col][col];\n if (k === 0) continue;\n for (let c = col; c < n; c++) A[r][c] -= k * A[col][c];\n bx[r] -= k * bx[col];\n by[r] -= k * by[col];\n }\n }\n const controlPoints = points.map((_, i) => ({\n x: bx[i] / A[i][i],\n y: by[i] / A[i][i],\n }));\n return { degree: p, controlPoints, knots };\n};\n","// The filled band a constant-width polyline draws (AutoCAD's wide\n// LWPOLYLINE / TRACE look): both sides offset by half the width with miter\n// joins, as hatch loops. Straight segments only — a bulged segment's\n// offsets are arcs of other radii that need their own joins.\n\nimport type { Vec2 } from \"./vec2\";\n\nconst left = (d: Vec2): Vec2 => ({ x: -d.y, y: d.x });\nconst unit = (a: Vec2, b: Vec2): Vec2 | null => {\n const len = Math.hypot(b.x - a.x, b.y - a.y);\n return len < 1e-12 ? null : { x: (b.x - a.x) / len, y: (b.y - a.y) / len };\n};\n\n/** Miter limit: a join sharper than this falls back to a bevel-ish square\n * offset (AutoCAD draws unlimited spikes; a cap keeps imports sane). */\nconst MITER_LIMIT = 10;\n\n/**\n * Loops of the band around `points` (consecutive duplicates removed):\n * an open path gives ONE loop (left side out, right side back); a closed\n * path gives two concentric loops (even-odd fills the ring). null when the\n * path has fewer than two distinct points.\n */\nexport const polylineBand = (\n points: Vec2[],\n width: number,\n closed: boolean,\n): Vec2[][] | null => {\n const pts: Vec2[] = [];\n for (const p of points) {\n const last = pts[pts.length - 1];\n if (!last || Math.hypot(p.x - last.x, p.y - last.y) > 1e-12) pts.push(p);\n }\n if (closed && pts.length > 2) {\n const a = pts[0];\n const b = pts[pts.length - 1];\n if (Math.hypot(a.x - b.x, a.y - b.y) <= 1e-12) pts.pop();\n }\n const n = pts.length;\n if (n < 2 || !(width > 0)) return null;\n const half = width / 2;\n const isClosed = closed && n >= 3;\n // Offset direction + distance per vertex.\n const offsets: Vec2[] = pts.map((p, i) => {\n const prev = i > 0 ? pts[i - 1] : isClosed ? pts[n - 1] : null;\n const next = i < n - 1 ? pts[i + 1] : isClosed ? pts[0] : null;\n const dIn = prev ? unit(prev, p) : null;\n const dOut = next ? unit(p, next) : null;\n if (dIn && dOut) {\n const n0 = left(dIn);\n const n1 = left(dOut);\n const m = { x: n0.x + n1.x, y: n0.y + n1.y };\n const len = Math.hypot(m.x, m.y);\n if (len < 1e-9) return { x: n0.x * half, y: n0.y * half }; // reversal\n const mu = { x: m.x / len, y: m.y / len };\n const cos = mu.x * n0.x + mu.y * n0.y; // cos(half the turn)\n const s = Math.min(half / Math.max(cos, 1e-9), half * MITER_LIMIT);\n return { x: mu.x * s, y: mu.y * s };\n }\n const d = dIn ?? dOut!;\n const nn = left(d);\n return { x: nn.x * half, y: nn.y * half };\n });\n const leftSide = pts.map((p, i) => ({\n x: p.x + offsets[i].x,\n y: p.y + offsets[i].y,\n }));\n const rightSide = pts.map((p, i) => ({\n x: p.x - offsets[i].x,\n y: p.y - offsets[i].y,\n }));\n return isClosed\n ? [leftSide, rightSide]\n : [[...leftSide, ...rightSide.reverse()]];\n};\n","// DXF BLOCK → Linea block definition (dwg-dxf-compatibility.md §8). A DXF\n// block is static geometry; a Linea block module's `draw` returns children —\n// so a block's converted children, serialized as a literal, ARE a module.\n// Each INSERT with a uniform positive scale then becomes an instance\n// (pivot = insertion point, rotation, scale) instead of N loose copies:\n// the structure survives, the file stays small, and editing one definition\n// edits every placement. Children on layer `0` follow the instance's layer\n// (AutoCAD's ByBlock rule); children on other layers keep theirs. Mirrored /\n// non-uniform inserts keep the explode path.\n\nimport type { ModelObjectDto } from \"../../model/objects\";\nimport { BlockChildSchema } from \"../../extensions/blockDtos\";\n\n/** FNV-1a, 32-bit, as 8 hex chars — content identity for a definition. */\nexport const contentHash = (s: string): string => {\n let h = 0x811c9dc5;\n for (let i = 0; i < s.length; i++) {\n h ^= s.charCodeAt(i);\n h = Math.imul(h, 0x01000193);\n }\n return (h >>> 0).toString(16).padStart(8, \"0\");\n};\n\n/** A block name as an id fragment: lower-case kebab, `*U3` → `u3`. */\nexport const blockSlug = (name: string): string =>\n name\n .replace(/^\\*/, \"\")\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, \"-\")\n .replace(/^-+|-+$/g, \"\") || \"block\";\n\nconst IDENTIFIER = /^[A-Za-z_$][\\w$]*$/;\nconst jsKey = (k: string): string =>\n IDENTIFIER.test(k) ? k : JSON.stringify(k);\nconst num = (n: number): string => String(Math.round(n * 1e6) / 1e6);\nconst isNum = (v: unknown): v is number => typeof v === \"number\";\n\n/** A value as compact JavaScript: points as `[x, y]`, vertices as `[x, y]`\n * or `[x, y, bulge]` (the schemas accept both), unquoted keys. */\nconst jsValue = (value: unknown): string => {\n if (isNum(value)) return num(value);\n if (value === null || typeof value === \"boolean\") return String(value);\n if (typeof value === \"string\") return JSON.stringify(value);\n if (Array.isArray(value)) return `[${value.map(jsValue).join(\", \")}]`;\n if (typeof value === \"object\") {\n const o = value as Record<string, unknown>;\n const keys = Object.keys(o).filter((k) => o[k] !== undefined);\n if (\n keys.length === 2 &&\n keys.includes(\"x\") &&\n keys.includes(\"y\") &&\n isNum(o.x) &&\n isNum(o.y)\n )\n return `[${num(o.x)}, ${num(o.y)}]`;\n if (\n keys.length === 3 &&\n keys.includes(\"x\") &&\n keys.includes(\"y\") &&\n keys.includes(\"bulge\") &&\n isNum(o.x) &&\n isNum(o.y) &&\n isNum(o.bulge)\n )\n return o.bulge === 0\n ? `[${num(o.x)}, ${num(o.y)}]`\n : `[${num(o.x)}, ${num(o.y)}, ${num(o.bulge)}]`;\n return `{ ${keys.map((k) => `${jsKey(k)}: ${jsValue(o[k])}`).join(\", \")} }`;\n }\n return \"undefined\";\n};\n\n/** Whether leaving `key` out of `child` parses to the same value — i.e. the\n * value IS the schema default (rotation 0, scale 1, an empty leader list…)\n * and the module reads better without it. Primitive answers are memoized\n * per type / key / value. */\nconst defaultMemo = new Map<string, boolean>();\nconst isSchemaDefault = (\n child: Record<string, unknown>,\n key: string,\n): boolean => {\n const value = child[key];\n const primitive = value === null || typeof value !== \"object\";\n const memoKey = primitive\n ? `${String(child.type)}\\0${key}\\0${JSON.stringify(value)}`\n : null;\n if (memoKey !== null) {\n const hit = defaultMemo.get(memoKey);\n if (hit !== undefined) return hit;\n }\n const { [key]: _omitted, ...rest } = child;\n void _omitted;\n const parsed = BlockChildSchema.safeParse(rest);\n const result =\n parsed.success &&\n JSON.stringify((parsed.data as Record<string, unknown>)[key]) ===\n JSON.stringify(value);\n if (memoKey !== null) defaultMemo.set(memoKey, result);\n return result;\n};\n\nconst MAX_LINE = 100;\n\n/** One child as a JavaScript object literal: `type` first, `layerId` last,\n * schema-default fields dropped; multi-line (one field per line, point\n * lists wrapped) once the one-line form gets long. */\nconst childLiteral = (\n child: Record<string, unknown>,\n indent: string,\n): string => {\n const keys = Object.keys(child).filter(\n (k) => child[k] !== undefined && k !== \"type\" && k !== \"layerId\",\n );\n // Only a primitive or an empty list / record can be a schema default\n // (geometry never is) — keeps the parse-based check off the big arrays.\n const mayDefault = (v: unknown): boolean =>\n v === null ||\n typeof v !== \"object\" ||\n (Array.isArray(v) ? v.length === 0 : Object.keys(v).length === 0);\n const kept = keys.filter(\n (k) => !mayDefault(child[k]) || !isSchemaDefault(child, k),\n );\n const ordered = [\n \"type\",\n ...kept,\n ...(child.layerId !== undefined ? [\"layerId\"] : []),\n ];\n const fields = ordered.map((k) => `${jsKey(k)}: ${jsValue(child[k])}`);\n const oneLine = `{ ${fields.join(\", \")} }`;\n if (indent.length + oneLine.length <= MAX_LINE) return oneLine;\n const inner = indent + \" \";\n const lines = ordered.map((k) => {\n const v = child[k];\n // A long list (points, cells) wraps a few items per line.\n if (Array.isArray(v) && `${jsKey(k)}: ${jsValue(v)}`.length > MAX_LINE) {\n const items = v.map(jsValue);\n const rows: string[] = [];\n let row = \"\";\n for (const item of items) {\n if (row && inner.length + 2 + row.length + 2 + item.length > MAX_LINE) {\n rows.push(row);\n row = \"\";\n }\n row += (row ? \", \" : \"\") + item;\n }\n if (row) rows.push(row);\n return `${inner}${jsKey(k)}: [\\n${rows.map((r) => `${inner} ${r},`).join(\"\\n\")}\\n${inner}]`;\n }\n return `${inner}${jsKey(k)}: ${jsValue(v)}`;\n });\n return `{\\n${lines.join(\",\\n\")},\\n${indent}}`;\n};\n\n/** Children as the `draw` result literal — plain JavaScript, one child per\n * line: no ids or hidden flags; a child on one of the `inheritLayerIds`\n * (DXF layer 0, or the import's fallback layer for entities whose layer is\n * unknown) drops its layer and follows the instance; numbers rounded to\n * the nanometre. `indent` is the array's own indentation in the module. */\nexport const childrenLiteral = (\n children: readonly ModelObjectDto[],\n inheritLayerIds: ReadonlySet<string> = new Set(),\n indent = \" \",\n): string => {\n if (children.length === 0) return \"[]\";\n const inner = indent + \" \";\n const items = children.map((c) => {\n const {\n layerId,\n hidden: _h,\n ...rest\n } = c as ModelObjectDto & {\n layerId?: string;\n hidden?: boolean;\n };\n void _h;\n const child =\n layerId === undefined || inheritLayerIds.has(layerId)\n ? rest\n : { ...rest, layerId };\n return inner + childLiteral(child as Record<string, unknown>, inner);\n });\n return `[\\n${items.join(\",\\n\")},\\n${indent}]`;\n};\n\nexport interface ImportedBlockDefinition {\n id: string;\n name: string;\n source: string;\n}\n\n/**\n * The module for one DXF block: `defineBlock` with the children literal as\n * `draw`'s result. The id carries a content hash, so the same block\n * imported twice merges to one definition and a same-named block with other\n * geometry never replaces it.\n */\nexport const blockDefinitionModule = (\n blockName: string,\n children: readonly ModelObjectDto[],\n inheritLayerIds?: ReadonlySet<string>,\n /** The library name, when the block's own clashes (the id keeps the\n * block's, so a re-import still finds this module). */\n displayName?: string,\n): ImportedBlockDefinition => {\n const literal = childrenLiteral(children, inheritLayerIds);\n const id = `dxf-${blockSlug(blockName)}-${contentHash(literal)}`;\n const name = displayName ?? blockName.replace(/^\\*/, \"\");\n const source = `// Imported from DXF block ${JSON.stringify(blockName)}: static geometry,\n// ${children.length} object${children.length === 1 ? \"\" : \"s\"}. Edit freely — every instance follows.\nimport { defineBlock } from \"lineadraw\";\n\nexport default defineBlock({\n id: ${JSON.stringify(id)},\n name: ${JSON.stringify(name)},\n description: ${JSON.stringify(`Imported DXF block ${blockName}`)},\n draw: () => ${literal},\n});\n`;\n return { id, name, source };\n};\n","// The DXF text as its lines. A large file is millions of lines, and every\n// split allocates them all again: dxfToModel splits ONCE and hands the array\n// to each raw-tag scanner (scanTags, the OBJECTS readers, the entity\n// histogram), which also still take the text on their own (tests, tools).\n\n/** DXF text, or its lines already split. */\nexport type DxfSource = string | readonly string[];\n\nexport const dxfLines = (source: DxfSource): readonly string[] =>\n typeof source === \"string\" ? source.split(/\\r\\n|\\r|\\n/) : source;\n","import { dxfLines, type DxfSource } from \"./dxfLines\";\n// Import ledger — rule R8 of docs/dxf-dwg-fidelity.md: every entity in the\n// file is accounted for as imported, degraded (imported as an approximation)\n// or skipped (with a reason). dxf-parser drops entity types it has no handler\n// for BEFORE the importer sees them (ATTRIB, MLINE, WIPEOUT, …), so the\n// importer pairs its own bookkeeping with a raw `0`-group histogram of the\n// tag stream and reports the difference as skipped.\n\n/** Counts the import keeps per source entity type / reason. */\nexport interface ImportLedger {\n /** DXF entity type → entities that produced objects as-is. */\n imported: Map<string, number>;\n /** `SOURCE→what` → entities imported as an approximation (SPLINE→polyline,\n * ACAD_TABLE→exploded, …). Disjoint from `imported`. */\n degraded: Map<string, number>;\n /** Entity type or reason → entities that produced nothing. */\n skipped: Map<string, number>;\n /** Every source type a converter was handed (hidden or not). */\n seen: Set<string>;\n}\n\nexport const emptyLedger = (): ImportLedger => ({\n imported: new Map(),\n degraded: new Map(),\n skipped: new Map(),\n seen: new Set(),\n});\n\nexport const bump = (m: Map<string, number>, key: string, n = 1): void => {\n m.set(key, (m.get(key) ?? 0) + n);\n};\n\nexport const total = (m: Map<string, number>): number => {\n let n = 0;\n for (const v of m.values()) n += v;\n return n;\n};\n\n/** `0`-group values that structure the file rather than name an entity;\n * VERTEX/SEQEND are consumed by their owning POLYLINE/INSERT. */\nconst STRUCTURAL = new Set([\n \"SECTION\",\n \"ENDSEC\",\n \"BLOCK\",\n \"ENDBLK\",\n \"SEQEND\",\n \"VERTEX\",\n \"EOF\",\n]);\n\n/**\n * Raw entity histogram of what the drawing can show: the ENTITIES section\n * plus the blocks reachable from it (every `*Paper_Space*` block and the\n * closure of INSERT / ACAD_TABLE block references), each block's entities\n * counted once. Uninserted block definitions are invisible and therefore not\n * counted; a DIMENSION's geometry block is the dimension's own rendering\n * (definition points included), so it is not followed either.\n */\nexport const scanEntityHistogram = (source: DxfSource): Map<string, number> => {\n const lines = dxfLines(source);\n const entities = new Map<string, number>();\n const entityRefs = new Set<string>();\n const blocks = new Map<\n string,\n { types: Map<string, number>; refs: Set<string> }\n >();\n\n let section = \"\";\n let afterSection = false;\n let block: { types: Map<string, number>; refs: Set<string> } | null = null;\n let pendingBlockName = false;\n let entityType = \"\";\n for (let i = 0; i + 1 < lines.length; i += 2) {\n const code = lines[i].trim();\n const value = lines[i + 1].trim();\n if (code === \"0\") {\n afterSection = value === \"SECTION\";\n if (value === \"ENDSEC\") section = \"\";\n entityType = value;\n if (section === \"BLOCKS\") {\n if (value === \"BLOCK\") {\n block = { types: new Map(), refs: new Set() };\n pendingBlockName = true;\n } else if (value === \"ENDBLK\") block = null;\n else if (block && !STRUCTURAL.has(value)) bump(block.types, value);\n } else if (section === \"ENTITIES\" && !STRUCTURAL.has(value)) {\n bump(entities, value);\n }\n } else if (code === \"2\") {\n if (afterSection) {\n section = value.toUpperCase();\n afterSection = false;\n } else if (pendingBlockName && block) {\n blocks.set(value.toUpperCase(), block);\n pendingBlockName = false;\n } else if (entityType === \"INSERT\" || entityType === \"ACAD_TABLE\") {\n (block ? block.refs : entityRefs).add(value.toUpperCase());\n }\n }\n }\n\n const queue = [...entityRefs];\n for (const name of blocks.keys())\n if (name.startsWith(\"*PAPER_SPACE\")) queue.push(name);\n const visited = new Set<string>();\n while (queue.length > 0) {\n const name = queue.pop()!;\n if (visited.has(name)) continue;\n visited.add(name);\n const b = blocks.get(name);\n if (!b) continue;\n for (const [type, n] of b.types) bump(entities, type, n);\n queue.push(...b.refs);\n }\n return entities;\n};\n\n/** Report every raw type no converter saw as skipped (parser-dropped). */\nexport const reconcileLedger = (\n ledger: ImportLedger,\n raw: Map<string, number>,\n): void => {\n for (const [type, n] of raw)\n if (!ledger.seen.has(type)) bump(ledger.skipped, type, n);\n};\n","// Custom dxf-parser entity handlers for types the library doesn't ship:\n// VIEWPORT, HATCH, LEADER. Each follows the library's handler contract —\n// a class with ForEntityName + parseEntity(scanner, curr) — registered via\n// DxfParser.registerEntityHandler. dxf-parser's helpers aren't exported, so\n// the point/common-code readers are re-implemented here (same semantics).\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\n\ninterface Tag {\n code: number;\n value: any;\n}\n\ninterface Scanner {\n next(): Tag;\n rewind(): void;\n isEOF(): boolean;\n}\n\n/**\n * Read a 2D/3D point whose X group was just consumed (mirror of the\n * library's parsePoint: rewind, re-read X, expect +10 for Y, optional +20).\n */\nconst parsePoint = (scanner: Scanner): { x: number; y: number } => {\n scanner.rewind();\n let curr = scanner.next();\n let code = curr.code;\n const point = { x: curr.value as number, y: 0 };\n code += 10;\n curr = scanner.next();\n if (curr.code !== code)\n throw new Error(`Expected code ${code} for point Y, got ${curr.code}`);\n point.y = curr.value as number;\n curr = scanner.next();\n if (curr.code !== code + 10) scanner.rewind(); // no Z — let caller advance\n return point;\n};\n\n/** Common entity codes (subset of the library's checkCommonEntityProperties). */\nconst commonProp = (entity: any, curr: Tag): void => {\n switch (curr.code) {\n case 5:\n entity.handle = curr.value;\n break;\n case 6:\n entity.lineType = curr.value;\n break;\n case 8:\n entity.layer = curr.value;\n break;\n case 48:\n entity.lineTypeScale = curr.value;\n break;\n case 60:\n // Invisibility flag (1 = hidden) — chiefly dynamic-block visibility\n // states, whose inactive entities import as all-states-at-once\n // otherwise. Same field dxf-parser's built-in handlers set.\n entity.visible = curr.value === 0;\n break;\n case 62:\n entity.colorIndex = curr.value;\n break;\n case 420:\n entity.trueColor = curr.value; // 24-bit RGB (overrides the ACI index)\n break;\n case 67:\n entity.inPaperSpace = curr.value !== 0;\n break;\n }\n};\n\n/**\n * ATTRIB — an attribute VALUE following an INSERT (title-block fields). Same\n * groups as TEXT plus the tag (2) and flags (70: 1 invisible, 2 constant);\n * dxf-parser ships an ATTDEF handler but none for ATTRIB. Field names match\n * dxf-parser's TEXT so the importer's text conversion applies unchanged.\n */\nexport class AttribHandler {\n ForEntityName = \"ATTRIB\";\n\n parseEntity(scanner: Scanner, curr: Tag): any {\n const entity: any = { type: curr.value };\n curr = scanner.next();\n while (!scanner.isEOF()) {\n if (curr.code === 0) break;\n switch (curr.code) {\n case 1:\n entity.text = curr.value;\n break;\n case 2:\n entity.tag = curr.value;\n break;\n case 7:\n entity.textStyle = curr.value;\n break;\n case 10:\n entity.startPoint = parsePoint(scanner);\n break;\n case 11:\n entity.endPoint = parsePoint(scanner);\n break;\n case 40:\n entity.textHeight = curr.value;\n break;\n case 41:\n entity.xScale = curr.value;\n break;\n case 50:\n entity.rotation = curr.value;\n break;\n case 70:\n entity.invisible = ((curr.value as number) & 1) !== 0;\n entity.constant = ((curr.value as number) & 2) !== 0;\n break;\n case 72:\n entity.halign = curr.value;\n break;\n case 74:\n entity.valign = curr.value;\n break;\n default:\n commonProp(entity, curr);\n break;\n }\n curr = scanner.next();\n }\n return entity;\n }\n}\n\n/** Paper-space VIEWPORT entity (frames a model view on a layout sheet). */\nexport class ViewportHandler {\n ForEntityName = \"VIEWPORT\";\n\n parseEntity(scanner: Scanner, curr: Tag): any {\n const entity: any = { type: curr.value, frozenLayerHandles: [] };\n curr = scanner.next();\n while (!scanner.isEOF()) {\n if (curr.code === 0) break;\n switch (curr.code) {\n case 10:\n entity.center = parsePoint(scanner);\n break;\n case 12:\n entity.viewCenter = parsePoint(scanner);\n break;\n case 40:\n entity.width = curr.value;\n break;\n case 41:\n entity.height = curr.value;\n break;\n case 45:\n entity.viewHeight = curr.value;\n break;\n case 68:\n entity.status = curr.value;\n break;\n case 69:\n entity.viewportId = curr.value;\n break;\n case 90:\n entity.statusFlags = curr.value;\n break;\n case 331:\n entity.frozenLayerHandles.push(String(curr.value));\n break;\n default:\n commonProp(entity, curr);\n break;\n }\n curr = scanner.next();\n }\n return entity;\n }\n}\n\n/**\n * HATCH entity. Parses boundary paths (polyline or edge form), the pattern\n * header (name / solid flag / angle / scale), pattern definition lines, and\n * the gradient block (450 flag, 452 one-/two-color, 460 angle, 462 tint,\n * 470 name, then per color 463 value / 63 ACI / 421 RGB). Seed points are\n * consumed and ignored.\n */\nexport class HatchHandler {\n ForEntityName = \"HATCH\";\n\n parseEntity(scanner: Scanner, curr: Tag): any {\n const entity: any = {\n type: curr.value,\n boundaryPaths: [],\n patternLines: [],\n };\n let path: any = null;\n let edge: any = null;\n let patternLine: any = null;\n let mode: \"header\" | \"pattern\" | \"seeds\" | \"gradient\" = \"header\";\n let gradientColor: { aci?: number; rgb?: number } | null = null;\n\n curr = scanner.next();\n while (!scanner.isEOF()) {\n if (curr.code === 0) break;\n switch (curr.code) {\n case 2:\n entity.patternName = curr.value;\n break;\n case 450:\n mode = \"gradient\";\n if (curr.value === 1)\n entity.gradient = { colors: [], oneColor: false, angle: 0 };\n break;\n case 452:\n if (entity.gradient) entity.gradient.oneColor = curr.value === 1;\n break;\n case 460:\n if (entity.gradient) entity.gradient.angle = curr.value; // radians\n break;\n case 462:\n if (entity.gradient) entity.gradient.tint = curr.value;\n break;\n case 470:\n if (entity.gradient) entity.gradient.name = String(curr.value);\n break;\n case 463:\n if (entity.gradient) {\n gradientColor = {};\n entity.gradient.colors.push(gradientColor);\n }\n break;\n case 63:\n if (gradientColor) gradientColor.aci = curr.value;\n break;\n case 421:\n if (gradientColor) gradientColor.rgb = curr.value;\n break;\n case 70:\n entity.solid = curr.value === 1;\n break;\n case 75:\n entity.hatchStyle = curr.value;\n break;\n case 76:\n entity.patternType = curr.value;\n break;\n case 52:\n entity.patternAngle = curr.value;\n break;\n case 41:\n entity.patternScale = curr.value;\n break;\n case 92:\n // New boundary path; bit 2 = polyline form.\n path = {\n flags: curr.value,\n isPolyline: (curr.value & 2) !== 0,\n vertices: [],\n edges: [],\n };\n edge = null;\n entity.boundaryPaths.push(path);\n break;\n case 72:\n if (!path) break;\n if (path.isPolyline) path.hasBulge = curr.value !== 0;\n else {\n // New edge; 1 line, 2 arc, 3 ellipse, 4 spline. A spline edge\n // carries its own groups: 94 degree, 73 rational, 74 periodic,\n // 40 knots, 10 control points, 42 weights, 11 fit points.\n edge = { kind: curr.value, points: [] };\n if (curr.value === 4) {\n edge.knots = [];\n edge.weights = [];\n edge.fitPoints = [];\n }\n path.edges.push(edge);\n }\n break;\n case 73:\n if (path?.isPolyline) path.closed = curr.value !== 0;\n else if (edge?.kind === 4) edge.rational = curr.value !== 0;\n else if (edge) edge.ccw = curr.value !== 0;\n break;\n case 74:\n if (edge?.kind === 4) edge.periodic = curr.value !== 0;\n break;\n case 94:\n if (edge?.kind === 4) edge.degree = curr.value;\n break;\n case 330:\n // Inside a boundary path: a source-boundary object handle (97\n // counts them) — not the entity's owner.\n if (!path) commonProp(entity, curr);\n break;\n case 78:\n mode = \"pattern\";\n break;\n case 98:\n mode = \"seeds\";\n break;\n case 53:\n if (mode === \"pattern\") {\n patternLine = { angle: curr.value };\n entity.patternLines.push(patternLine);\n }\n break;\n case 43:\n if (patternLine) patternLine.baseX = curr.value;\n break;\n case 44:\n if (patternLine) patternLine.baseY = curr.value;\n break;\n case 45:\n if (patternLine) patternLine.offsetX = curr.value;\n break;\n case 46:\n if (patternLine) patternLine.offsetY = curr.value;\n break;\n case 79:\n if (patternLine) patternLine.dashes = [];\n break;\n case 49:\n if (patternLine) (patternLine.dashes ??= []).push(curr.value);\n break;\n case 10: {\n const p = parsePoint(scanner);\n if (mode === \"seeds\" || mode === \"gradient\") break; // seed points — ignore\n if (path?.isPolyline) path.vertices.push({ ...p, bulge: 0 });\n else if (edge) edge.points.push(p);\n break;\n }\n case 11: {\n const p = parsePoint(scanner);\n if (edge?.kind === 4) edge.fitPoints.push(p);\n else if (edge) edge.end = p;\n break;\n }\n case 42:\n if (path?.isPolyline && path.vertices.length > 0)\n path.vertices[path.vertices.length - 1].bulge = curr.value;\n else if (edge?.kind === 4) edge.weights.push(curr.value);\n break;\n case 40:\n if (edge?.kind === 4) edge.knots.push(curr.value);\n else if (edge) edge.r40 = curr.value;\n break;\n case 50:\n if (edge) edge.startAngle = curr.value;\n break;\n case 51:\n if (edge) edge.endAngle = curr.value;\n break;\n default:\n commonProp(entity, curr);\n break;\n }\n curr = scanner.next();\n }\n return entity;\n }\n}\n\n/** One cell of an ACAD_TABLE's legacy AcDbTable payload. */\nexport interface AcadTableCell {\n /** 171: 1 = text, 2 = block. */\n type: number;\n /** 175 / 176: merge extent on the anchor cell. */\n cols: number;\n rows: number;\n /** 173: covered by a merge. */\n merged?: boolean;\n /** 170: attachment 1–9 (TL TC TR / ML MC MR / BL BC BR). */\n alignment?: number;\n /** 7: text style name. */\n style?: string;\n /** 140: text height. */\n height?: number;\n /** 145: text rotation (radians). */\n rotation?: number;\n /** 1 (+ 3 chunks): MTEXT content. */\n text?: string;\n /** 302: formatted display string (numeric cells' only text). */\n display?: string;\n}\n\n/** The table structure ACAD_TABLE carries next to its *T block. */\nexport interface AcadTableData {\n rows: number;\n cols: number;\n rowHeights: number[];\n colWidths: number[];\n /** 40: horizontal cell margin. */\n margin?: number;\n cells: AcadTableCell[];\n}\n\n/**\n * ACAD_TABLE entity. A table's rendered geometry (grid lines + cell text)\n * lives in an anonymous *T block named by the AcDbBlockReference subclass\n * (group 2, insertion point 10, optional direction vector 11) — the importer\n * explodes that block like an INSERT. The AcDbTable payload that follows\n * REUSES the same group codes for per-cell data (2 = cell text, 62 = cell\n * color overrides, …), so all capturing stops at its subclass marker and the\n * rest is skimmed to the entity boundary.\n */\nexport class AcadTableHandler {\n ForEntityName = \"ACAD_TABLE\";\n\n parseEntity(scanner: Scanner, curr: Tag): any {\n const entity: any = { type: curr.value };\n let inTableData = false;\n // The legacy AcDbTable payload (still written by current AutoCAD next to\n // its TABLECONTENT objects): table-level groups first, then one run per\n // cell starting at 171. Codes 91/92/140 recur INSIDE cells with other\n // meanings, so table-level values are only read before the first cell.\n const table: AcadTableData = {\n rows: 0,\n cols: 0,\n rowHeights: [],\n colWidths: [],\n cells: [],\n };\n let cell: AcadTableCell | null = null;\n let textChunks = \"\";\n curr = scanner.next();\n while (!scanner.isEOF()) {\n if (curr.code === 0) break;\n if (curr.code === 100 && curr.value === \"AcDbTable\") inTableData = true;\n if (inTableData && curr.code !== 100) {\n const num = () => Number(curr.value);\n if (curr.code === 171) {\n cell = { type: num(), cols: 1, rows: 1 };\n table.cells.push(cell);\n textChunks = \"\";\n } else if (!cell) {\n if (curr.code === 91) table.rows = num();\n else if (curr.code === 92) table.cols = num();\n else if (curr.code === 141) table.rowHeights.push(num());\n else if (curr.code === 142) table.colWidths.push(num());\n else if (curr.code === 40) table.margin = num();\n else if (curr.code === 11) {\n // Horizontal direction → rotation (degrees, INSERT-style). Only\n // a sane unit-ish vector counts: DWG transcodes write this\n // group uninitialized (1e59 / 1e-308 garbage) for some tables,\n // which used to rotate them arbitrarily.\n const dir = parsePoint(scanner);\n const len = Math.hypot(dir.x, dir.y);\n if (Number.isFinite(len) && len > 0.5 && len < 2)\n entity.rotation = (Math.atan2(dir.y, dir.x) * 180) / Math.PI;\n }\n } else if (curr.code === 175) cell.cols = num();\n else if (curr.code === 176) cell.rows = num();\n else if (curr.code === 173) cell.merged = num() !== 0;\n else if (curr.code === 170) cell.alignment = num();\n else if (curr.code === 7) cell.style ??= String(curr.value);\n else if (curr.code === 140) cell.height ??= num();\n else if (curr.code === 145) cell.rotation ??= num();\n // Long cell text arrives as 3-chunks then the final 1 (MTEXT style);\n // later 1s (ACVALUE copies) are ignored.\n else if (curr.code === 3) textChunks += String(curr.value);\n else if (curr.code === 1 && cell.text === undefined)\n cell.text = textChunks + String(curr.value ?? \"\");\n // The formatted display string: the only text a NUMERIC cell has\n // (its value rides as 90 = type / 91 = number, no group 1).\n else if (curr.code === 302 && cell.display === undefined)\n cell.display = String(curr.value ?? \"\");\n }\n if (!inTableData) {\n switch (curr.code) {\n case 2:\n entity.name = curr.value;\n break;\n case 10:\n entity.position = parsePoint(scanner);\n break;\n case 11: {\n // Horizontal direction vector → rotation (degrees, like INSERT's\n // group 50, so convertInsert consumes it unchanged). Same\n // sanity gate as the table-level 11.\n const dir = parsePoint(scanner);\n const len = Math.hypot(dir.x, dir.y);\n if (Number.isFinite(len) && len > 0.5 && len < 2)\n entity.rotation = (Math.atan2(dir.y, dir.x) * 180) / Math.PI;\n break;\n }\n default:\n commonProp(entity, curr);\n break;\n }\n }\n curr = scanner.next();\n }\n if (table.rows > 0 && table.cols > 0) entity.table = table;\n return entity;\n }\n}\n\n/** Plain LEADER entity (arrow polyline; any annotation stays separate). */\nexport class LeaderHandler {\n ForEntityName = \"LEADER\";\n\n parseEntity(scanner: Scanner, curr: Tag): any {\n const entity: any = { type: curr.value, vertices: [] };\n curr = scanner.next();\n while (!scanner.isEOF()) {\n if (curr.code === 0) break;\n switch (curr.code) {\n case 3:\n entity.styleName = curr.value;\n break;\n case 10:\n entity.vertices.push(parsePoint(scanner));\n break;\n case 71:\n entity.arrowheadFlag = curr.value;\n break;\n case 72:\n entity.pathType = curr.value;\n break;\n default:\n commonProp(entity, curr);\n break;\n }\n curr = scanner.next();\n }\n return entity;\n }\n}\n\n/**\n * MULTILEADER entity. Parses the CONTEXT_DATA block's mtext content and\n * text/arrow sizes, plus every LEADER node's junction and LEADER_LINE vertex\n * runs. Marker tags: 300/301 context, 302/303 leader, 304/305 leader line\n * (304 doubles as the mtext content code — disambiguated by value).\n */\nexport class MultiLeaderHandler {\n ForEntityName = \"MULTILEADER\";\n\n parseEntity(scanner: Scanner, curr: Tag): any {\n const entity: any = { type: curr.value, leaders: [] };\n let inContext = false;\n let leader: any = null;\n let line: any = null;\n\n curr = scanner.next();\n while (!scanner.isEOF()) {\n if (curr.code === 0) break;\n switch (curr.code) {\n case 300:\n inContext = true;\n break;\n case 301:\n inContext = false;\n break;\n case 302:\n leader = { junction: null, lines: [] };\n entity.leaders.push(leader);\n break;\n case 303:\n leader = null;\n break;\n case 304:\n if (curr.value === \"LEADER_LINE{\" && leader) {\n line = [];\n leader.lines.push(line);\n } else if (inContext && !leader && entity.content === undefined) {\n entity.content = curr.value;\n }\n break;\n case 305:\n line = null;\n break;\n case 40:\n if (inContext && !leader) entity.overallScale = curr.value;\n break;\n case 41:\n if (inContext && !leader) entity.textHeight = curr.value;\n break;\n case 140:\n if (inContext && !leader) entity.arrowSize = curr.value;\n break;\n case 171:\n // Context-level text attachment point (1–9, MTEXT-style).\n if (inContext && !leader) entity.attachment = curr.value;\n break;\n case 12: {\n const p = parsePoint(scanner);\n if (inContext && !leader) entity.textLocation = p;\n break;\n }\n case 10: {\n const p = parsePoint(scanner);\n if (line) line.push(p);\n else if (leader) leader.junction = p;\n break;\n }\n default:\n commonProp(entity, curr);\n break;\n }\n curr = scanner.next();\n }\n return entity;\n }\n}\n\n/**\n * MLINE — a multiline (walls): N parallel element lines, one per offset of\n * its MLINESTYLE, along a vertex path. dxf-parser has no handler. Per vertex\n * the entity stores the vertex (11), the segment direction (12), the MITER\n * direction (13) and, per element, its parameters (74 count, 41 values):\n * the FIRST parameter is the distance along the miter from the vertex to\n * that element's line — AutoCAD's own justification + miter arithmetic, so\n * the importer needs no style to place the elements. Fill parameters\n * (75/42) are skipped.\n */\nexport class MlineHandler {\n ForEntityName = \"MLINE\";\n\n parseEntity(scanner: Scanner, curr: Tag): any {\n const entity: any = {\n type: curr.value,\n styleName: \"\",\n styleHandle: \"\",\n scale: 1,\n justification: 0,\n flags: 0,\n elementCount: 0,\n vertices: [],\n };\n let vertex: any = null;\n let element: { params: number[] } | null = null;\n let inFill = false;\n curr = scanner.next();\n while (!scanner.isEOF()) {\n if (curr.code === 0) break;\n switch (curr.code) {\n case 2:\n entity.styleName = String(curr.value);\n break;\n case 340:\n entity.styleHandle = String(curr.value).toUpperCase();\n break;\n case 40:\n entity.scale = curr.value;\n break;\n case 70:\n entity.justification = curr.value;\n break;\n case 71:\n entity.flags = curr.value;\n break;\n case 73:\n entity.elementCount = curr.value;\n break;\n case 10:\n entity.start = parsePoint(scanner);\n break;\n case 11:\n vertex = { point: parsePoint(scanner), elements: [] };\n entity.vertices.push(vertex);\n element = null;\n inFill = false;\n break;\n case 12:\n if (vertex) vertex.direction = parsePoint(scanner);\n break;\n case 13:\n if (vertex) vertex.miter = parsePoint(scanner);\n break;\n case 74:\n if (vertex) {\n element = { params: [] };\n vertex.elements.push(element);\n inFill = false;\n }\n break;\n case 41:\n if (element && !inFill) element.params.push(curr.value);\n break;\n case 75:\n inFill = true;\n break;\n default:\n commonProp(entity, curr);\n break;\n }\n curr = scanner.next();\n }\n return entity;\n }\n}\n\n/**\n * TRACE — a filled quadrilateral with SOLID's exact groups (10–13, in\n * SOLID's 1-2-4-3 vertex order) and no dxf-parser handler. Field names match\n * dxf-parser's SOLID so the importer's SOLID conversion applies unchanged.\n */\nexport class TraceHandler {\n ForEntityName = \"TRACE\";\n\n parseEntity(scanner: Scanner, curr: Tag): any {\n const entity: any = { type: curr.value, points: [] };\n curr = scanner.next();\n while (!scanner.isEOF()) {\n if (curr.code === 0) break;\n switch (curr.code) {\n case 10:\n case 11:\n case 12:\n case 13:\n entity.points[curr.code - 10] = parsePoint(scanner);\n break;\n default:\n commonProp(entity, curr);\n break;\n }\n curr = scanner.next();\n }\n return entity;\n }\n}\n","import { dxfLines, type DxfSource } from \"./dxfLines\";\n// Minimal OBJECTS-section reader. dxf-parser skips the whole section, but\n// LAYOUT objects live there — without them imported paper spaces would lose\n// their names, tab order, and sheet sizes. This scans the raw tag stream and\n// extracts just the LAYOUT records.\n\nexport interface DxfLayoutInfo {\n name: string;\n tabOrder: number;\n /** Plot paper size, mm (PlotSettings groups 44/45). */\n paperWidth?: number;\n paperHeight?: number;\n /** BLOCK_RECORD handle of the owning space (uppercased). */\n blockRecordHandle?: string;\n}\n\nexport const parseLayoutObjects = (source: DxfSource): DxfLayoutInfo[] => {\n const lines = dxfLines(source);\n const layouts: DxfLayoutInfo[] = [];\n\n let inObjects = false;\n let prevZeroValue = \"\"; // value of the last (0, …) tag\n let current: DxfLayoutInfo | null = null;\n let subclass = \"\";\n\n const commit = () => {\n if (current && current.name) layouts.push(current);\n current = null;\n subclass = \"\";\n };\n\n for (let i = 0; i + 1 < lines.length; i += 2) {\n const code = parseInt(lines[i], 10);\n if (Number.isNaN(code)) continue;\n const value = lines[i + 1].trim();\n\n if (code === 0) {\n commit();\n if (value === \"ENDSEC\" && inObjects) break;\n if (inObjects && value === \"LAYOUT\") current = { name: \"\", tabOrder: 0 };\n prevZeroValue = value;\n continue;\n }\n if (code === 2 && prevZeroValue === \"SECTION\") {\n inObjects = value === \"OBJECTS\";\n continue;\n }\n if (!current) continue;\n\n if (code === 100) {\n subclass = value;\n continue;\n }\n if (subclass === \"AcDbPlotSettings\") {\n if (code === 44) current.paperWidth = parseFloat(value) || undefined;\n else if (code === 45)\n current.paperHeight = parseFloat(value) || undefined;\n } else if (subclass === \"AcDbLayout\") {\n if (code === 1) current.name = value;\n else if (code === 71) current.tabOrder = parseInt(value, 10) || 0;\n else if (code === 330 && !current.blockRecordHandle)\n current.blockRecordHandle = value.toUpperCase();\n }\n }\n commit();\n\n return layouts.sort((a, b) => a.tabOrder - b.tabOrder);\n};\n\n/** One MLINESTYLE element: its offset from the multiline's zero line\n * (positive = left of the drawing direction) and optional own color /\n * line type (62 = 256 ByLayer, 6 = BYLAYER). */\nexport interface DxfMlineStyleElement {\n offset: number;\n colorIndex?: number;\n lineType?: string;\n}\n\nexport interface DxfMlineStyle {\n handle?: string;\n name: string;\n /** Group 70: 1 fill, 2 miters, 16 / 256 start / end square caps,\n * 32 / 512 inner arcs, 64 / 1024 round caps. */\n flags: number;\n elements: DxfMlineStyleElement[];\n}\n\n/** MLINESTYLE objects (OBJECTS section), by upper-cased handle and by\n * lower-cased name — a DWG transcode can zero the entity's style handle\n * while keeping the name. */\nexport const parseMlineStyles = (\n source: DxfSource,\n): {\n byHandle: Map<string, DxfMlineStyle>;\n byName: Map<string, DxfMlineStyle>;\n} => {\n const lines = dxfLines(source);\n const byHandle = new Map<string, DxfMlineStyle>();\n const byName = new Map<string, DxfMlineStyle>();\n let inObjects = false;\n let prevZeroValue = \"\";\n let current: DxfMlineStyle | null = null;\n let element: DxfMlineStyleElement | null = null;\n let afterCount = false;\n\n const commit = () => {\n if (current && current.name) {\n if (current.handle) byHandle.set(current.handle, current);\n byName.set(current.name.toLowerCase(), current);\n }\n current = null;\n element = null;\n afterCount = false;\n };\n\n for (let i = 0; i + 1 < lines.length; i += 2) {\n const code = parseInt(lines[i], 10);\n if (Number.isNaN(code)) continue;\n const value = lines[i + 1].trim();\n if (code === 0) {\n commit();\n if (value === \"ENDSEC\" && inObjects) break;\n if (inObjects && value === \"MLINESTYLE\")\n current = { name: \"\", flags: 0, elements: [] };\n prevZeroValue = value;\n continue;\n }\n if (code === 2 && prevZeroValue === \"SECTION\") {\n inObjects = value === \"OBJECTS\";\n continue;\n }\n if (!current) continue;\n switch (code) {\n case 5:\n current.handle = value.toUpperCase();\n break;\n case 2:\n current.name = value;\n break;\n case 70:\n current.flags = parseInt(value, 10) || 0;\n break;\n case 71:\n afterCount = true;\n break;\n case 49:\n element = { offset: parseFloat(value) || 0 };\n current.elements.push(element);\n break;\n case 62:\n // Before 71 it is the fill color; after, the element's.\n if (afterCount && element) element.colorIndex = parseInt(value, 10);\n break;\n case 6:\n if (element) element.lineType = value;\n break;\n }\n }\n commit();\n return { byHandle, byName };\n};\n","// References: files drawn in place (docs/references.md). The document holds\n// the `reference` record (format, placement, `source`); a LINKED file's bytes\n// live host-side, reached through `ReferenceFileAccess`, an EMBEDDED one's in\n// the document's `assets` (docs/adr/0005). Every format loads into the same\n// shape — a `ReferenceContent`, the file's model space as Linea objects plus,\n// for pictures, a raster — so painting, snapping and binding never care what\n// the file was. This module is pure: loading bytes and caching content is the host's.\n\nimport type { AABB } from \"../geometry/bounds\";\nimport {\n addPointToBounds,\n emptyBounds,\n isEmptyBounds,\n} from \"../geometry/bounds\";\nimport type { Vec2 } from \"../geometry/vec2\";\nimport type { LineaDocument } from \"../model/document\";\nimport { emptyDocument } from \"../model/defaults\";\nimport { buildSnapEntry } from \"../snap/buildEntry\";\nimport type { TextMeasurer } from \"../paint/textMetrics\";\nimport type { ArcGeom } from \"../geometry/arcs\";\nimport type { EllipseGeom } from \"../geometry/ellipse\";\nimport type { SnapPointType } from \"../snap/types\";\nimport { unionBounds } from \"../geometry/bounds\";\nimport { dxfToModel } from \"../import/dxf/importDxf\";\nimport {\n mirrorObject,\n rotateObject,\n scaleObjectUniform,\n translateObject,\n} from \"../transform\";\nimport {\n REFERENCE_FORMATS,\n type ModelObject,\n type ReferenceFormat,\n type Reference,\n type ReferenceSource,\n} from \"../model/objects\";\nimport type { LayoutModelContext } from \"../paint/layoutPaint\";\nimport type { Mat2x3 } from \"../paint/sink\";\n\n/**\n * How a host reaches the files references point at (calculus's seam,\n * verbatim). Desktop: real paths. A browser can't read paths — it keeps a\n * copy of the bytes under `source.cacheKey` instead (editor-side store).\n */\nexport interface ReferenceFileAccess {\n /** Native picker filtered to the reference formats; absolute paths, or\n * null on cancel. */\n pick(): Promise<string[] | null>;\n /** A file's bytes by its STORED path (relative paths resolve against the\n * document's folder). Rejects when missing. */\n read(path: string): Promise<Uint8Array>;\n /** Size + mtime of a stored path (reload detection); null when missing. */\n stat(path: string): Promise<{ size: number; mtimeMs: number } | null>;\n /** The path to store for a picked absolute path: relative (POSIX\n * separators) when inside the document's folder, else absolute. */\n toStoredPath(absolutePath: string): Promise<string>;\n /** Stored path → absolute path (display, cache keys). */\n toAbsolutePath(storedPath: string): Promise<string>;\n}\n\n/** A loaded reference: the file's model space as Linea objects (ids\n * prefixed per reference — see `contentFromDocument`) plus its bounds. */\nexport interface ReferenceContent extends LayoutModelContext {\n /** Content bounds in FILE coordinates (empty for an empty file). */\n bounds: AABB;\n /** PDF: how many pages the file has (the page field's range). */\n pageCount?: number;\n /** A bitmap drawn under `objects` (PNG/JPEG, raster PDF page). */\n raster?: ReferenceRaster;\n /**\n * Snap geometry precomputed in FILE coordinates (off the main thread —\n * see `referenceSnapOf`); absent → derived from `objects`. A raster PDF\n * carries its page's VECTOR geometry here: it paints the image and snaps\n * to the lines.\n */\n snap?: ReferenceSnap;\n}\n\n/** File-space snap primitives, each tagged with its layer id (so the\n * reference's hidden layers still filter them). */\nexport interface ReferenceSnap {\n points: { p: Vec2; type: SnapPointType; layer: string }[];\n segments: { a: Vec2; b: Vec2; chord?: boolean; layer: string }[];\n arcs: (ArcGeom & { layer: string })[];\n ellipses: (EllipseGeom & { layer: string })[];\n}\n\n/** A document's snap geometry in its own coordinates (references inside it\n * excluded — they resolve per placement). Heavy for big files: hosts run it\n * off the main thread with the file's conversion. */\nexport const referenceSnapOf = (\n doc: Pick<\n LineaDocument,\n \"objects\" | \"dimStyles\" | \"textStyles\" | \"blockDefinitions\"\n >,\n measure: TextMeasurer,\n): ReferenceSnap => {\n const snap: ReferenceSnap = {\n points: [],\n segments: [],\n arcs: [],\n ellipses: [],\n };\n const byId = new Map(doc.objects.map((o) => [o.id, o]));\n const ctx = {\n dimStyles: doc.dimStyles,\n textStyles: doc.textStyles,\n blockDefinitions: doc.blockDefinitions,\n resolveObject: (id: string) => byId.get(id),\n measure,\n };\n for (const o of doc.objects) {\n if (o.type === \"reference\") continue;\n const e = buildSnapEntry(o, ctx);\n const layer = o.layerId;\n for (const p of e.points) snap.points.push({ ...p, layer });\n for (const s of e.segments) snap.segments.push({ ...s, layer });\n for (const a of e.arcs) snap.arcs.push({ ...a, layer });\n for (const el of e.ellipses ?? []) snap.ellipses.push({ ...el, layer });\n }\n return snap;\n};\n\n/** A nested reference's source as seen from the HOST document: a relative\n * path inside a referenced file is relative to THAT file's folder. */\nexport const rebaseReferenceSource = (\n child: ReferenceSource,\n parent: ReferenceSource,\n): ReferenceSource => {\n // An embedded child resolves in the file that holds it; a url is absolute.\n if (child.kind !== \"path\" || parent.kind !== \"path\") return child;\n if (/^([A-Za-z]:[\\\\/]|[\\\\/])/.test(child.path)) return child;\n const folder = parent.path.replace(/\\\\/g, \"/\").replace(/\\/?[^/]*$/, \"\");\n return { ...child, path: folder ? `${folder}/${child.path}` : child.path };\n};\n\n/** A reference that draws a picture (PNG/JPEG, or a PDF page as raster). */\nexport const isPictureReference = (\n ref: Pick<Reference, \"format\" | \"pdfMode\">,\n): boolean =>\n ref.format === \"png\" ||\n ref.format === \"jpg\" ||\n (ref.format === \"pdf\" && ref.pdfMode === \"raster\");\n\n/** How the UI names where a reference's file lives. */\nexport const referenceSourceLabel = (source: ReferenceSource): string =>\n source.kind === \"url\"\n ? source.url\n : source.kind === \"path\"\n ? source.path\n : \"Embedded in this drawing\";\n\n/** The reference format a file name implies, or null. */\nexport const referenceFormatOf = (fileName: string): ReferenceFormat | null => {\n const ext = /\\.([^./\\\\]+)$/.exec(fileName)?.[1]?.toLowerCase();\n if (ext === \"jpeg\") return \"jpg\";\n if (ext === \"lineadraw\") return \"linea\";\n return REFERENCE_FORMATS.find((f) => f === ext) ?? null;\n};\n\n/** The MIME type an embedded file of each format is stored under (the data\n * URL in `document.assets`) — what tells an asset's format back. */\nexport const REFERENCE_MIME: Record<ReferenceFormat, string> = {\n linea: \"application/vnd.lineadraw+json\",\n dxf: \"image/vnd.dxf\",\n dwg: \"image/vnd.dwg\",\n pdf: \"application/pdf\",\n png: \"image/png\",\n jpg: \"image/jpeg\",\n};\n\n/** The reference format an embedded file's MIME type names, or null. */\nexport const referenceFormatOfMime = (mime: string): ReferenceFormat | null =>\n REFERENCE_FORMATS.find((f) => REFERENCE_MIME[f] === mime) ?? null;\n\n/** The file-picker `accept` list for references. */\nexport const REFERENCE_ACCEPT = REFERENCE_FORMATS.flatMap((f) =>\n f === \"jpg\"\n ? [\".jpg\", \".jpeg\"]\n : f === \"linea\"\n ? [\".linea\", \".lineadraw\"]\n : [`.${f}`],\n).join(\",\");\n\n/** File coordinates → the host document: rotation + uniform scale about the\n * file origin (mirrored: the file flips LEFT-RIGHT first, x → −x — what\n * \"mirror\" means to a user), then `position`. */\nexport const referenceTransform = (ref: Reference): Mat2x3 => {\n const s = ref.scale;\n const m = ref.mirrored ? -1 : 1;\n const c = Math.cos(ref.rotation);\n const n = Math.sin(ref.rotation);\n return [m * s * c, m * s * n, -s * n, s * c, ref.position.x, ref.position.y];\n};\n\nexport const applyMat = (m: Mat2x3, p: Vec2): Vec2 => ({\n x: m[0] * p.x + m[2] * p.y + m[4],\n y: m[1] * p.x + m[3] * p.y + m[5],\n});\n\n/** The four corners of a file-space box placed by `m`. */\nexport const placedCorners = (m: Mat2x3, b: AABB): Vec2[] =>\n [\n { x: b.minX, y: b.minY },\n { x: b.maxX, y: b.minY },\n { x: b.maxX, y: b.maxY },\n { x: b.minX, y: b.maxY },\n ].map((p) => applyMat(m, p));\n\n/** The placed (host) bounds of a file-space box. */\nexport const placedBounds = (m: Mat2x3, b: AABB): AABB => {\n const out = emptyBounds();\n if (isEmptyBounds(b)) return out;\n for (const p of placedCorners(m, b)) addPointToBounds(out, p);\n return out;\n};\n\n/**\n * A document's model space as reference content. Object ids are prefixed\n * with the reference's id (and block object-reference inputs with them), so\n * per-id caches — block evaluation, its errors and dependencies — never mix a\n * referenced file's objects with the host's own, even when the file is a\n * copy of the drawing that references it.\n */\nexport const contentFromDocument = (\n doc: LineaDocument,\n refId: string,\n bounds: AABB = emptyBounds(),\n): ReferenceContent => {\n const prefix = `ref:${refId}:`;\n const objects: ModelObject[] = doc.objects.map((o) =>\n o.type === \"block\"\n ? {\n ...o,\n id: prefix + o.id,\n inputs: o.inputs.map((v) => (typeof v === \"string\" ? prefix + v : v)),\n }\n : { ...o, id: prefix + o.id },\n );\n const byId = new Map(objects.map((o) => [o.id, o]));\n return {\n objects,\n layers: doc.layers,\n dimStyles: doc.dimStyles,\n textStyles: doc.textStyles,\n blockDefinitions: doc.blockDefinitions,\n lineTypes: doc.lineTypes,\n hatchPatterns: doc.hatchPatterns,\n assets: doc.assets,\n resolveObject: (id) => byId.get(id),\n bounds,\n };\n};\n\n/** A fresh document holding DTOs (ids assigned) — what non-.linea formats\n * convert into before `contentFromDocument`. */\nexport const documentWithObjects = (\n build: (doc: LineaDocument) => {\n objects: readonly Record<string, unknown>[];\n layers?: LineaDocument[\"layers\"];\n textStyles?: LineaDocument[\"textStyles\"];\n dimStyles?: LineaDocument[\"dimStyles\"];\n lineTypes?: LineaDocument[\"lineTypes\"];\n hatchPatterns?: LineaDocument[\"hatchPatterns\"];\n blockDefinitions?: LineaDocument[\"blockDefinitions\"];\n },\n): LineaDocument => {\n const doc = emptyDocument();\n const {\n objects,\n layers,\n textStyles,\n dimStyles,\n lineTypes,\n hatchPatterns,\n blockDefinitions,\n } = build(doc);\n if (layers) doc.layers = layers;\n if (textStyles) doc.textStyles = textStyles;\n if (dimStyles) doc.dimStyles = dimStyles;\n if (lineTypes) doc.lineTypes = lineTypes;\n if (hatchPatterns) doc.hatchPatterns = hatchPatterns;\n if (blockDefinitions) doc.blockDefinitions = blockDefinitions;\n doc.objects = objects.map(\n (o) =>\n ({ ...o, id: crypto.randomUUID() }) as LineaDocument[\"objects\"][number],\n );\n return doc;\n};\n\n/** DXF text → a document (units converted to mm by the importer; blocks\n * come exploded, layouts are ignored — a reference shows model space). */\nexport const documentFromDxf = (text: string): LineaDocument =>\n documentWithObjects((doc) => {\n const result = dxfToModel(text, {\n existingLayers: doc.layers.map((l) => ({ id: l.id, name: l.name })),\n defaultLayerId: doc.layers[0].id,\n existingTextStyles: doc.textStyles,\n existingDimStyles: doc.dimStyles,\n existingLineTypes: doc.lineTypes,\n existingHatchPatterns: doc.hatchPatterns,\n adoptStyles: true,\n });\n return {\n objects: result.objects,\n layers: [...doc.layers, ...result.newLayers],\n textStyles: result.textStyles,\n dimStyles: result.dimStyles,\n lineTypes: result.lineTypes,\n hatchPatterns: result.hatchPatterns,\n blockDefinitions: [\n ...doc.blockDefinitions,\n ...result.newBlockDefinitions,\n ],\n };\n });\n\n/** A content object as native geometry where the reference draws it —\n * Bind's per-object step: mirror (left-right), scale about the file origin,\n * rotate, then move to the insertion point (the order referenceTransform\n * composes). */\nexport const placeReferenceObject = (\n obj: ModelObject,\n ref: Reference,\n): ModelObject => {\n const origin = { x: 0, y: 0 };\n let o = ref.mirrored ? mirrorObject(obj, origin, { x: 0, y: 1 }) : obj;\n if (ref.scale !== 1) o = scaleObjectUniform(o, ref.scale);\n if (ref.rotation !== 0) o = rotateObject(o, origin, ref.rotation);\n return translateObject(o, ref.position);\n};\n\n/** Raster content: one bitmap, bottom-left at the file origin, `width` ×\n * `height` mm — a PNG/JPEG reference or a raster PDF page. */\nexport interface ReferenceRaster {\n /** The bitmap as a data URL (what the sink's `image()` op draws). */\n data: string;\n width: number;\n height: number;\n}\n\n/** A raster's frame as file-space snap geometry: corners, edge midpoints,\n * centre — the frame a picture snaps and picks by (no interior ring). */\nexport const rasterSnap = (w: number, h: number, layer: string): ReferenceSnap => {\n const corners = [\n { x: 0, y: 0 },\n { x: w, y: 0 },\n { x: w, y: h },\n { x: 0, y: h },\n ];\n return {\n points: [\n ...corners.map((p) => ({ p, type: \"endpoint\" as const, layer })),\n ...corners.map((p, i) => {\n const q = corners[(i + 1) % 4];\n return {\n p: { x: (p.x + q.x) / 2, y: (p.y + q.y) / 2 },\n type: \"midpoint\" as const,\n layer,\n };\n }),\n { p: { x: w / 2, y: h / 2 }, type: \"center\" as const, layer },\n ],\n segments: corners.map((a, i) => ({ a, b: corners[(i + 1) % 4], layer })),\n arcs: [],\n ellipses: [],\n };\n};\n\n/** PNG/JPEG reference content: the bitmap at its natural size (96 dpi). */\nexport const contentFromRaster = (\n refId: string,\n data: string,\n width: number,\n height: number,\n): ReferenceContent => {\n const content = contentFromDocument(emptyDocument(), refId, {\n minX: 0,\n minY: 0,\n maxX: width,\n maxY: height,\n });\n return {\n ...content,\n raster: { data, width, height },\n snap: rasterSnap(width, height, content.layers[0].id),\n };\n};\n\n/** Content bounds in file coordinates (text measured by `measure`); the\n * origin for an empty file, so a frame still has a corner. */\nexport const measureContentBounds = (\n content: Omit<ReferenceContent, \"bounds\">,\n measure: TextMeasurer,\n): AABB => {\n const ctx = {\n dimStyles: content.dimStyles,\n textStyles: content.textStyles,\n blockDefinitions: content.blockDefinitions,\n lineTypes: content.lineTypes,\n hatchPatterns: content.hatchPatterns,\n resolveObject: content.resolveObject,\n resolveReference: content.resolveReference,\n measure,\n };\n let bounds = emptyBounds();\n for (const o of content.objects) {\n const b = buildSnapEntry(o, ctx).bounds;\n if (!isEmptyBounds(b)) bounds = unionBounds(bounds, b);\n }\n if (isEmptyBounds(bounds)) addPointToBounds(bounds, { x: 0, y: 0 });\n return bounds;\n};\n\n/** Host → file coordinates (the inverse of referenceTransform) — clip\n * rectangles are picked in the drawing and stored in the file's frame. */\nexport const toReferenceCoords = (ref: Reference, p: Vec2): Vec2 => {\n const dx = p.x - ref.position.x;\n const dy = p.y - ref.position.y;\n const c = Math.cos(-ref.rotation);\n const n = Math.sin(-ref.rotation);\n const x = (c * dx - n * dy) / ref.scale;\n const y = (n * dx + c * dy) / ref.scale;\n return { x: ref.mirrored ? -x : x, y };\n};\n\n/** A segment clipped to a box (Liang–Barsky), or null when outside. */\nexport const clipSegment = (\n a: Vec2,\n b: Vec2,\n box: AABB,\n): [Vec2, Vec2] | null => {\n let t0 = 0;\n let t1 = 1;\n const dx = b.x - a.x;\n const dy = b.y - a.y;\n const edges: [number, number][] = [\n [-dx, a.x - box.minX],\n [dx, box.maxX - a.x],\n [-dy, a.y - box.minY],\n [dy, box.maxY - a.y],\n ];\n for (const [p, q] of edges) {\n if (p === 0) {\n if (q < 0) return null;\n } else {\n const t = q / p;\n if (p < 0) t0 = Math.max(t0, t);\n else t1 = Math.min(t1, t);\n if (t0 > t1) return null;\n }\n }\n return [\n { x: a.x + t0 * dx, y: a.y + t0 * dy },\n { x: a.x + t1 * dx, y: a.y + t1 * dy },\n ];\n};\n","import type { Layer } from \"../model/document\";\nimport type { LineType } from \"../model/lineTypes\";\nimport type { ModelObject } from \"../model/objects\";\nimport { dashForLineType, scaleDash } from \"./lineTypes\";\n\nexport interface ResolvedStyle {\n color: string;\n widthMm: number;\n /** Dash pattern in mm (undefined = continuous). */\n dashMm?: number[];\n /** Paint opacity 0..1 (undefined = opaque). */\n opacity?: number;\n}\n\nconst FALLBACK_STYLE: ResolvedStyle = {\n color: \"#e8e8e8\",\n widthMm: 0.25,\n};\n\n/** Resolve byLayer color/lineweight/linetype through the object's layer. */\nexport const resolveStyle = (\n obj: ModelObject,\n layers: readonly Layer[],\n /** The document's own line types (resolved ahead of the catalogue). */\n lineTypes?: readonly LineType[],\n): ResolvedStyle => {\n const layer = layers.find((l) => l.id === obj.layerId);\n const widthMm = obj.lineWidth ?? layer?.lineWidth ?? FALLBACK_STYLE.widthMm;\n return {\n color: obj.color ?? layer?.color ?? FALLBACK_STYLE.color,\n widthMm,\n // Dash patterns are defined per 1 mm of line width (ISO 128 style —\n // pattern legibility tracks stroke weight), so the resolved lineweight\n // scales them; lineTypeScale (CELTSCALE) multiplies on top.\n dashMm: scaleDash(\n dashForLineType(obj.lineType ?? layer?.lineType, lineTypes),\n widthMm * (obj.lineTypeScale ?? 1),\n ),\n opacity: obj.opacity ?? layer?.opacity,\n };\n};\n","// Drawing far from the origin. Survey-grid drawings (a masterplan in\n// ETRS-GK coordinates: ~2·10¹⁰ mm) lose all precision once their coordinates\n// reach a float32 pipeline — the canvas, PDF and SVG viewers — which at that\n// magnitude can only step in metres. `rebaseSink` subtracts a nearby origin\n// in float64 BEFORE anything reaches the sink, so the sink only ever sees\n// small numbers (\"relative to eye\", as CAD/GIS viewers do). The data stays\n// absolute; only what is drawn is shifted.\n//\n// The shift applies at the TOP level only: a pushed transform (a reference's\n// placement, a viewport's projection) maps its own space into the shifted\n// one by having the shift folded into its translation, and coordinates\n// inside it pass through untouched.\n\nimport type { Vec2 } from \"../geometry/vec2\";\nimport type { GeometrySink, Mat2x3 } from \"./sink\";\n\nexport const rebaseSink = (sink: GeometrySink, origin: Vec2): GeometrySink => {\n if (origin.x === 0 && origin.y === 0) return sink;\n let depth = 0;\n const at = (p: Vec2): Vec2 =>\n depth === 0 ? { x: p.x - origin.x, y: p.y - origin.y } : p;\n return {\n beginPath: () => sink.beginPath(),\n moveTo: (p) => sink.moveTo(at(p)),\n lineTo: (p) => sink.lineTo(at(p)),\n bezierTo: (c1, c2, end) => sink.bezierTo(at(c1), at(c2), at(end)),\n arc: (center, r, a0, a1, ccw) => sink.arc(at(center), r, a0, a1, ccw),\n ellipse: (center, rx, ry, rot, a0, a1) =>\n sink.ellipse(at(center), rx, ry, rot, a0, a1),\n closePath: () => sink.closePath(),\n stroke: (s) => sink.stroke(s),\n fill: (f) =>\n sink.fill(\n f.gradient\n ? {\n ...f,\n gradient: {\n ...f.gradient,\n from: at(f.gradient.from),\n to: at(f.gradient.to),\n },\n }\n : f,\n ),\n text: (t) => sink.text({ ...t, anchor: at(t.anchor) }),\n image: (i) => sink.image({ ...i, origin: at(i.origin) }),\n measureText: (text, h, font, wf) => sink.measureText(text, h, font, wf),\n pushTransform: (m: Mat2x3) => {\n sink.pushTransform(\n depth === 0\n ? [m[0], m[1], m[2], m[3], m[4] - origin.x, m[5] - origin.y]\n : m,\n );\n depth++;\n },\n popTransform: () => {\n depth = Math.max(0, depth - 1);\n sink.popTransform();\n },\n pushClipRect: (r) => {\n const p = at({ x: r.x, y: r.y });\n sink.pushClipRect({ ...r, x: p.x, y: p.y });\n },\n popClip: () => sink.popClip(),\n beginObject: sink.beginObject\n ? (id, layer) => sink.beginObject!(id, layer)\n : undefined,\n endObject: sink.endObject ? () => sink.endObject!() : undefined,\n };\n};\n","// A reference paints its file's content (resolved by the host — see\n// PaintEnv.resolveReference) through the reference's placement, each object\n// styled by the FILE's layers; a file that isn't loaded (missing, loading)\n// paints a dashed frame of its last known extent with its name.\n\nimport type { ModelObject, Reference } from \"../../model/objects\";\nimport { placedCorners, referenceTransform } from \"../../reference/reference\";\nimport { resolveStyle } from \"../style\";\nimport { matMultiply, type GeometrySink } from \"../sink\";\nimport { rebaseSink } from \"../rebaseSink\";\nimport { isEmptyBounds } from \"../../geometry/bounds\";\nimport { paintObject, type PaintEnv } from \"./index\";\n\nexport const paintReference = (\n obj: Reference,\n sink: GeometrySink,\n env: PaintEnv,\n): void => {\n if (obj.hidden) return;\n const content = env.resolveReference?.(obj) ?? null;\n const m = referenceTransform(obj);\n if (!content) {\n paintReferenceFrame(obj, sink, env);\n return;\n }\n const hidden = new Set(obj.hiddenLayers);\n const shown = new Map(\n content.layers.map((l) => [l.id, l.visible && !hidden.has(l.name)]),\n );\n const mapColor = env.mapColor ?? ((c: string) => c);\n const fade = env.style.opacity ?? 1;\n // Draw the content relative to its own centre: a survey-grid file placed\n // back near the origin would otherwise hand the sink its ~10¹⁰-mm file\n // coordinates and a ~−10¹⁰ placement, cancelled in float32 (distortion).\n // The shift is folded into the placement here, in float64 (rebaseSink).\n const b = content.bounds;\n const c = isEmptyBounds(b)\n ? { x: 0, y: 0 }\n : { x: (b.minX + b.maxX) / 2, y: (b.minY + b.maxY) / 2 };\n sink.pushTransform(matMultiply(m, [1, 0, 0, 1, c.x, c.y]));\n const out = rebaseSink(sink, c);\n const clip = obj.clip;\n if (clip)\n out.pushClipRect({\n x: clip.minX,\n y: clip.minY,\n w: clip.maxX - clip.minX,\n h: clip.maxY - clip.minY,\n });\n const raster = content.raster;\n if (raster) {\n // A bitmap can't take a highlight colour: a highlight outlines it.\n if (env.forceStyle) {\n out.beginPath();\n out.moveTo({ x: 0, y: 0 });\n out.lineTo({ x: raster.width, y: 0 });\n out.lineTo({ x: raster.width, y: raster.height });\n out.lineTo({ x: 0, y: raster.height });\n out.closePath();\n out.stroke(env.style);\n } else\n out.image({\n data: raster.data,\n origin: { x: 0, y: 0 },\n widthMm: raster.width,\n heightMm: raster.height,\n rotation: 0,\n opacity: fade,\n });\n }\n for (const child of content.objects) {\n if (shown.get(child.layerId) === false) continue;\n const own = resolveStyle(\n child as ModelObject,\n content.layers,\n content.lineTypes,\n );\n paintObject(child, out, {\n // A highlight paints the whole reference in one style.\n style: env.forceStyle\n ? env.style\n : {\n ...own,\n color: mapColor(own.color),\n opacity: (own.opacity ?? 1) * fade,\n },\n forceStyle: env.forceStyle,\n // The FILE's own resources — nested references resolve through its\n // resolver too (the host loads them relative to that file,\n // depth-limited, cycle-safe).\n ...content,\n cache: env.cache,\n mapColor: env.mapColor,\n });\n }\n if (clip) sink.popClip();\n sink.popTransform();\n};\n\n/** Not loaded: a dashed frame over the last known extent (or a small square\n * at the insertion point) and the reference's name. */\nconst paintReferenceFrame = (\n obj: Reference,\n sink: GeometrySink,\n env: PaintEnv,\n): void => {\n const s = 5;\n const corners = obj.extent\n ? placedCorners(referenceTransform(obj), obj.extent)\n : [\n { x: obj.position.x, y: obj.position.y },\n { x: obj.position.x + s, y: obj.position.y },\n { x: obj.position.x + s, y: obj.position.y + s },\n { x: obj.position.x, y: obj.position.y + s },\n ];\n sink.beginPath();\n sink.moveTo(corners[0]);\n for (const c of corners.slice(1)) sink.lineTo(c);\n sink.closePath();\n sink.stroke({\n color: env.style.color,\n widthMm: env.style.widthMm,\n dashMm: [1.5, 1],\n opacity: env.style.opacity,\n });\n sink.text({\n text: obj.name,\n anchor: corners[0],\n heightMm: 2.5,\n rotation: obj.rotation,\n hAlign: \"left\",\n vAlign: \"bottom\",\n color: env.style.color,\n opacity: env.style.opacity,\n });\n};\n","import type { LineType } from \"../../model/lineTypes\";\nimport type { Layer, LineaDocument } from \"../../model/document\";\nimport { documentObjectResolver } from \"../../model/objectLookup\";\nimport type { DocumentHatchPattern } from \"../../model/hatchPatterns\";\nimport type {\n DimStyle,\n ModelObject,\n ModelObjectType,\n Reference,\n TextStyle,\n} from \"../../model/objects\";\nimport type { ReferenceContent } from \"../../reference/reference\";\nimport type { GeometrySink } from \"../sink\";\nimport type { ResolvedStyle } from \"../style\";\nimport type { PaintGeometryCache } from \"../paintCache\";\nimport { paintLine } from \"./line\";\nimport { paintPoint } from \"./point\";\nimport { paintPolyline } from \"./polyline\";\nimport { paintCircle } from \"./circle\";\nimport { paintArc } from \"./arc\";\nimport { paintEllipse } from \"./ellipse\";\nimport { paintHatch } from \"./hatch\";\nimport { paintText } from \"./text\";\nimport { paintDimension } from \"./dimension\";\nimport { paintBlockInstance } from \"./block\";\nimport { paintViewport } from \"./viewport\";\nimport { paintTable } from \"./table\";\nimport { paintReference } from \"./reference\";\n\n/**\n * The document half of a paint environment: everything a painter resolves\n * by id or name against the document. The array fields are REQUIRED so a\n * caller can't drop one by accident (an omitted `hatchPatterns` silently\n * painted the catalogue fallback); consumers without a document pass [].\n * `LayoutModelContext` and `ReferenceContent` extend it, so a paint env\n * spreads either one whole.\n */\nexport interface DocumentPaintResources {\n /** Document layers — a block child that names its OWN layer hides with\n * it (its color still follows the instance unless it sets one). */\n layers: readonly Layer[];\n /** Document dimension styles — dimensions pick theirs by styleId. */\n dimStyles: readonly DimStyle[];\n /** Document text styles — texts pick theirs by styleId. */\n textStyles: readonly TextStyle[];\n /** Document-defined line types / hatch patterns, resolved by NAME ahead\n * of the built-in catalogue (block children and hatch fills). */\n lineTypes: readonly LineType[];\n hatchPatterns: readonly DocumentHatchPattern[];\n /**\n * The document's block definitions — the block painter evaluates instance\n * children against these. The kernel holds no store, so they are threaded\n * through the paint environment (mirrors buildEntry's SnapGeometryContext).\n */\n blockDefinitions: readonly string[];\n /**\n * Document-wide object lookup for block object-reference inputs (see\n * BlockObjectResolver). Optional: without it, referenced inputs evaluate\n * as null (consumers that cannot reach a document, e.g. style previews).\n */\n resolveObject?: (id: string) => ModelObject | undefined;\n /**\n * The document's embedded assets (hash → data URL) — the bytes behind\n * `asset`-source references, which a host's `resolveReference` reads.\n */\n assets?: Readonly<Record<string, string>>;\n /**\n * A reference's loaded file content (docs/references.md) — the host owns\n * loading and caching. Absent, or null for a file not loaded (yet), → the\n * reference paints as a dashed frame.\n */\n resolveReference?: (ref: Reference) => ReferenceContent | null;\n}\n\n/** The paint resources of a whole document — what a headless renderer\n * (SDK render, thumbnails, export) hands its painters. Hosts with their own\n * object/reference resolvers override those two fields. Picked, not\n * spread: a whole document would carry its `objects` over the caller's. */\nexport const documentPaintResources = (\n doc: LineaDocument,\n): DocumentPaintResources => ({\n layers: doc.layers,\n dimStyles: doc.dimStyles,\n textStyles: doc.textStyles,\n lineTypes: doc.lineTypes,\n hatchPatterns: doc.hatchPatterns,\n blockDefinitions: doc.blockDefinitions,\n assets: doc.assets,\n resolveObject: documentObjectResolver(doc),\n});\n\n/** Environment passed to painters — style already resolved by the caller. */\nexport interface PaintEnv extends DocumentPaintResources {\n style: ResolvedStyle;\n /**\n * Optional cache for camera-independent derived geometry (hatch lines,\n * dimension geometry, text blocks). Supply one per long-lived consumer\n * (the canvas renderer keeps one across frames); omit for one-shot paints.\n */\n cache?: PaintGeometryCache;\n /**\n * Paint everything in `style` verbatim, ignoring per-child style overrides\n * (block children carrying their own color/lineType). Selection/hover\n * highlights set this so a block highlights as one uniform silhouette.\n */\n forceStyle?: boolean;\n /** The output medium's color map (print palettes): content painted with\n * its OWN styles (a reference's file) maps through it too. */\n mapColor?: (color: string) => string;\n}\n\nexport type Painter = (\n obj: ModelObject,\n sink: GeometrySink,\n env: PaintEnv,\n) => void;\n\nconst painters: Record<ModelObjectType, Painter> = {\n line: paintLine as Painter,\n point: paintPoint as Painter,\n polyline: paintPolyline as Painter,\n circle: paintCircle as Painter,\n arc: paintArc as Painter,\n ellipse: paintEllipse as Painter,\n hatch: paintHatch as Painter,\n text: paintText as Painter,\n dimension: paintDimension as Painter,\n block: paintBlockInstance as Painter,\n viewport: paintViewport as Painter,\n table: paintTable as Painter,\n reference: paintReference as Painter,\n // Screen-fixed editor chrome — painted by the editor's canvas renderer\n // only, never by the shared path (exports don't show it).\n comment: () => {},\n};\n\nexport const paintObject = (\n obj: ModelObject,\n sink: GeometrySink,\n env: PaintEnv,\n): void => {\n painters[obj.type]?.(obj, sink, env);\n};\n","// Headless SVG thumbnail of a block module — the same dry-run render the\n// editor's BlockPreview shows, emitted as a self-contained <svg> for\n// marketplace manifests (`lineadraw manifest` bakes it into thumbnailSvg;\n// the palette/browser display it without running any module code).\n// Deterministic by construction: stand-in picks are fixed, text measures\n// via the approximate table, and the SvgSink rounds coordinates — so\n// manifest generation stays a byte-stable operation.\n\nimport type { LineType } from \"../model/lineTypes\";\nimport type { DocumentHatchPattern } from \"../model/hatchPatterns\";\nimport type { Block } from \"../model/objects\";\nimport { DEFAULT_DIM_STYLE, DEFAULT_TEXT_STYLE } from \"../model/objects\";\nimport { isEmptyBounds } from \"../geometry/bounds\";\nimport { SvgSink } from \"../export/svg/svgSink\";\nimport { approximateTextMeasurer } from \"../paint/textMeasurer\";\nimport { paintObject } from \"../paint/painters\";\nimport { buildSnapEntry } from \"../snap/buildEntry\";\nimport {\n blockScriptId,\n dryRunBlockInputs,\n dryRunObjectResolver,\n ensureScriptTranspiler,\n getBlockError,\n getBlockMeta,\n} from \"./evalBlock\";\n\nexport interface BlockThumbnailOptions {\n /** Extra module sources nested instances resolve against (the repo's or\n * catalog's other blocks); ids the module itself provides win. */\n definitions?: readonly string[];\n /** Skip (return null) when the SVG exceeds this many characters — a\n * manifest should stay a light index, not an asset bundle. */\n maxChars?: number;\n /** The document's own line types / hatch patterns, when the block's\n * children reference them by name (the catalogue needs no help). */\n lineTypes?: readonly LineType[];\n hatchPatterns?: readonly DocumentHatchPattern[];\n}\n\n/**\n * Render a block module to a small standalone SVG (viewBox-sized, strokes\n * in `currentColor` so the host UI's theme colors it). Returns null for\n * blocks with nothing visible to draw or oversized output; throws when the\n * module itself fails its dry run (same errors testBlockDefinition\n * reports).\n */\nexport const renderBlockThumbnailSvg = async (\n script: string,\n {\n definitions = [],\n maxChars = 20_000,\n lineTypes,\n hatchPatterns,\n }: BlockThumbnailOptions = {},\n): Promise<string | null> => {\n await ensureScriptTranspiler();\n const defId = getBlockMeta(script).id;\n const inputs = await dryRunBlockInputs(script);\n\n // The module shadows any same-id definition; extras fill remaining ids.\n const defs = [script];\n const present = new Set([defId]);\n for (const extra of definitions) {\n const id = blockScriptId(extra);\n if (id === undefined || present.has(id)) continue;\n present.add(id);\n defs.push(extra);\n }\n\n const instance: Block = {\n type: \"block\",\n id: `thumbnail:${defId}`,\n layerId: \"thumbnail\",\n definitionId: defId,\n rotation: 0,\n scale: 1,\n params: {},\n inputs,\n };\n const env = {\n layers: [],\n dimStyles: [DEFAULT_DIM_STYLE],\n textStyles: [DEFAULT_TEXT_STYLE],\n lineTypes: lineTypes ?? [],\n hatchPatterns: hatchPatterns ?? [],\n blockDefinitions: defs,\n // Object-reference inputs preview against the dry-run stand-in object.\n resolveObject: dryRunObjectResolver,\n };\n const entry = buildSnapEntry(instance, {\n ...env,\n measure: approximateTextMeasurer,\n });\n const error = getBlockError(instance.id);\n if (error !== undefined && error !== null) throw new Error(error);\n // A no-geometry block collapses to a point at the pivot (buildSnapEntry\n // still yields degenerate 0×0 bounds there) — nothing worth a thumbnail.\n const bw = entry.bounds.maxX - entry.bounds.minX;\n const bh = entry.bounds.maxY - entry.bounds.minY;\n if (isEmptyBounds(entry.bounds) || (bw === 0 && bh === 0)) return null;\n\n const sink = new SvgSink({ measure: approximateTextMeasurer });\n paintObject(instance, sink, {\n ...env,\n // currentColor: the thumbnail inherits the surrounding UI text color,\n // so one render works in light and dark hosts alike. Children with\n // authored colors keep them. Stroke width scales with the extent —\n // thumbnails display at ~icon size, where a fixed mm width would turn\n // a meters-wide block into invisible hairlines.\n style: { color: \"currentColor\", widthMm: Math.max(bw, bh) / 56 },\n });\n const pad = Math.max(((bw + bh) / 2) * 0.06, 1);\n const svg = sink.toSvg(entry.bounds, pad);\n return svg.length > maxChars ? null : svg;\n};\n","// Block-library merging over raw module sources. A \"library file\" is just a\n// `.ts`/`.js` module (one module = one block); moving blocks between\n// documents is moving text. PURE — the browser download, file pickers,\n// toasts, and the store merge stay editor-side; this module owns the\n// collision invariants:\n// · a source already present verbatim is skipped\n// · an id match with DIFFERENT content REPLACES that module in place —\n// the id IS the block's identity, so importing it again is an update\n// (instances keep their definitionId and re-evaluate with the new source)\n// · a name clash with a DIFFERENT block is suffixed \"(imported)\" via a\n// literal rewrite of `export const name` (best-effort — an unrewritable\n// name is left alone)\n// · a module that does not compile/validate is rejected with its error\n// Callers must await `ensureScriptTranspiler()` first — merging compiles.\n\nimport { blockScriptId, getBlockMetaResult, type BlockMeta } from \"./evalBlock\";\n\n/**\n * Replace the string literal of `export const <name> = \"…\"` — or, for a\n * defineBlock module, the `<name>: \"…\"` property at the TOP level of the\n * spec object (nested occurrences like a params entry's `name:` are never\n * touched). Null when neither form has a rewritable literal\n * (dynamic/computed) — callers must treat that as \"don't touch\", never\n * mangle. Also used by the editor's Duplicate.\n */\nexport const rewriteExportString = (\n script: string,\n exportName: string,\n value: string,\n): string | null => {\n const re = new RegExp(\n `(export\\\\s+const\\\\s+${exportName}\\\\s*=\\\\s*)(\"(?:[^\"\\\\\\\\]|\\\\\\\\.)*\"|'(?:[^'\\\\\\\\]|\\\\\\\\.)*')`,\n );\n if (re.test(script)) return script.replace(re, `$1${JSON.stringify(value)}`);\n return rewriteSpecProperty(script, exportName, value);\n};\n\n/**\n * Rewrite `<prop>: \"…\"` at brace depth 1 of the `defineBlock({...})` /\n * `defineCommand({...})` (or plain default-exported object) spec. A small\n * scanner rather than a bare regex: strings, template literals, and comments\n * are skipped wholesale, and depth tracking keeps nested literals (params\n * entries also have a `name:`) out of reach. Best-effort — anything\n * unrecognized returns null.\n */\nconst rewriteSpecProperty = (\n script: string,\n prop: string,\n value: string,\n): string | null => {\n const call = script.search(\n /define(?:Block|Command)\\s*\\(|export\\s+default\\s*\\{/,\n );\n if (call === -1) return null;\n const open = script.indexOf(\"{\", call);\n if (open === -1) return null;\n const propRe = new RegExp(\n `^${prop}\\\\s*:\\\\s*(\"(?:[^\"\\\\\\\\]|\\\\\\\\.)*\"|'(?:[^'\\\\\\\\]|\\\\\\\\.)*')`,\n );\n let depth = 0;\n for (let i = open; i < script.length; i++) {\n const ch = script[i];\n if (ch === '\"' || ch === \"'\" || ch === \"`\") {\n i++;\n while (i < script.length && script[i] !== ch) {\n if (script[i] === \"\\\\\") i++;\n i++;\n }\n continue;\n }\n if (ch === \"/\" && script[i + 1] === \"/\") {\n while (i < script.length && script[i] !== \"\\n\") i++;\n continue;\n }\n if (ch === \"/\" && script[i + 1] === \"*\") {\n i += 2;\n while (i < script.length && !(script[i] === \"*\" && script[i + 1] === \"/\"))\n i++;\n i++;\n continue;\n }\n if (ch === \"{\" || ch === \"(\" || ch === \"[\") {\n depth++;\n continue;\n }\n if (ch === \"}\" || ch === \")\" || ch === \"]\") {\n depth--;\n if (depth === 0) return null; // spec object ended without the prop\n continue;\n }\n if (depth !== 1 || !/[A-Za-z_$]/.test(ch)) continue;\n const prev = i > 0 ? script[i - 1] : \"\";\n const m = /[A-Za-z0-9_$.]/.test(prev) ? null : propRe.exec(script.slice(i));\n if (m) {\n const start = i + m[0].length - m[1].length;\n return (\n script.slice(0, start) +\n JSON.stringify(value) +\n script.slice(start + m[1].length)\n );\n }\n // Skip the rest of this identifier so mid-word positions aren't tested.\n while (i + 1 < script.length && /[A-Za-z0-9_$]/.test(script[i + 1])) i++;\n }\n return null;\n};\n\nexport interface MergeModulesResult<M> {\n /** The full library to install (replacements in place + new appended). */\n merged: string[];\n /** Modules added as new entries (possibly renamed), with their meta. */\n added: { script: string; meta: M }[];\n /** Modules that replaced an existing entry with the same exported id. */\n replaced: { script: string; meta: M }[];\n /** How many incoming modules were already present verbatim. */\n skipped: number;\n /** Modules that could not be imported, with the reason. */\n rejected: { script: string; error: string }[];\n}\n\nexport type MergeBlockModulesResult = MergeModulesResult<BlockMeta>;\n\n/** How a module family (blocks, commands) derives identity from a source. */\nexport interface ScriptModuleAccess<M extends { id: string; name: string }> {\n /** Best-effort exported id (compiled meta or a source-level scan). */\n idOf(script: string): string | undefined;\n /** Non-throwing compile + meta validation. */\n metaOf(script: string): { ok: true; meta: M } | { ok: false; error: string };\n}\n\n/**\n * Merge incoming module sources into an existing library — the shared\n * engine under block AND command import (same collision invariants for\n * both; see the header comment).\n */\nexport const mergeScriptModules = <M extends { id: string; name: string }>(\n existing: readonly string[],\n incoming: readonly string[],\n access: ScriptModuleAccess<M>,\n): MergeModulesResult<M> => {\n const merged = [...existing];\n const indexById = new Map<string, number>();\n merged.forEach((s, i) => {\n const id = access.idOf(s);\n if (id !== undefined && !indexById.has(id)) indexById.set(id, i);\n });\n // Parallel name list (undefined = module does not compile).\n const names: (string | undefined)[] = merged.map((s) => {\n const r = access.metaOf(s);\n return r.ok ? r.meta.name : undefined;\n });\n const nameTaken = (name: string, except: number | undefined): boolean =>\n names.some((n, i) => n === name && i !== except);\n\n const added: MergeModulesResult<M>[\"added\"] = [];\n const replaced: MergeModulesResult<M>[\"replaced\"] = [];\n const rejected: MergeModulesResult<M>[\"rejected\"] = [];\n let skipped = 0;\n\n for (const original of incoming) {\n if (merged.includes(original)) {\n skipped++; // identical module already present\n continue;\n }\n let script = original;\n let result = access.metaOf(script);\n if (!result.ok) {\n rejected.push({ script: original, error: result.error });\n continue;\n }\n\n // Same exported id → the incoming module replaces that entry (its slot's\n // own name is not a clash, so a same-name update keeps its name).\n const replaceIdx = indexById.get(result.meta.id);\n\n // Name collision with a different block → suffix (best-effort rewrite).\n if (nameTaken(result.meta.name, replaceIdx)) {\n let name = result.meta.name;\n while (nameTaken(name, replaceIdx)) name = `${name} (imported)`;\n const renamed = rewriteExportString(script, \"name\", name);\n if (renamed !== null) script = renamed;\n }\n\n if (script !== original) {\n result = access.metaOf(script);\n if (!result.ok) {\n // A rewrite broke the module — should not happen; keep the original\n // out rather than installing something unparseable.\n rejected.push({ script: original, error: result.error });\n continue;\n }\n }\n\n if (replaceIdx !== undefined) {\n merged[replaceIdx] = script;\n names[replaceIdx] = result.meta.name;\n replaced.push({ script, meta: result.meta });\n } else {\n indexById.set(result.meta.id, merged.length);\n names.push(result.meta.name);\n merged.push(script);\n added.push({ script, meta: result.meta });\n }\n }\n\n return { merged, added, replaced, skipped, rejected };\n};\n\n/** Merge incoming block module sources into an existing library. */\nexport const mergeBlockModules = (\n existing: readonly string[],\n incoming: readonly string[],\n): MergeBlockModulesResult =>\n mergeScriptModules(existing, incoming, {\n idOf: blockScriptId,\n metaOf: getBlockMetaResult,\n });\n","// Marketplaces, headless (docs/block-marketplace.md): a marketplace is a\n// git repo (or a local folder) carrying a CI-generated catalog of block and\n// command modules. This module is the half every host shares — the config\n// record and its identity, the manifest schema, catalog + source fetching\n// with caches, search, install status against a document's vendored\n// modules, and the dependency-closure plan an install needs. What a host\n// adds is I/O (`fetch` is the platform's; a folder reader comes from the\n// desktop host or Node's fs) and where the module sources end up (the\n// editor's stores, a LocalDrawing's ops). The editor's\n// `marketplace/client.ts` and `LocalDrawing` both sit on `MarketplaceClient`.\n\nimport { z } from \"zod\";\nimport {\n blockDefinitionExists,\n blockScriptId,\n getBlockMetaResult,\n} from \"../extensions/evalBlock\";\nimport {\n commandScriptId,\n getCommandMetaResult,\n} from \"../extensions/commandModules\";\nimport {\n apiHeaders,\n manifestUrls,\n parseMarketplaceSpec,\n rawToApiUrl,\n sourcePathUrl,\n} from \"./github\";\n\n// ---- Configuration ----------------------------------------------------------\n\n/** One configured marketplace. `kind` discriminates so new source types\n * are one more variant; identity (for dedupe/remove/reorder) is\n * `marketplaceKey`. The built-in public collection is always present\n * exactly once (`normalizeMarketplaces`). Tokens never enter a document. */\nexport const MarketplaceConfigSchema = z.discriminatedUnion(\"kind\", [\n z.object({ kind: z.literal(\"builtin\") }),\n z.object({\n kind: z.literal(\"github\"),\n /** `owner/repo` or `owner/repo@branch`. */\n spec: z.string(),\n /** Fine-grained PAT for a private repo (read-only Contents). */\n token: z.string().optional(),\n }),\n /** A local directory with the same generated manifest layout; the folder\n * key is opaque to core (an absolute path on the desktop and in Node). */\n z.object({ kind: z.literal(\"folder\"), folder: z.string() }),\n]);\nexport type MarketplaceConfig = z.infer<typeof MarketplaceConfigSchema>;\n\nexport const BUILTIN_MARKETPLACE_SPEC = \"lineadraw/lineadraw@main\";\nexport const BUILTIN_MARKETPLACE_NAME = \"Linea public collection\";\n\nexport const marketplaceKey = (m: MarketplaceConfig): string =>\n m.kind === \"builtin\"\n ? \"builtin\"\n : m.kind === \"github\"\n ? `github:${m.spec}`\n : `folder:${m.folder}`;\n\n/** Drop duplicate keys (first occurrence wins) and guarantee exactly one\n * built-in entry — appended LAST when missing, so user sources outrank the\n * public collection by default. */\nexport const normalizeMarketplaces = (\n list: readonly MarketplaceConfig[],\n): MarketplaceConfig[] => {\n const seen = new Set<string>();\n const out: MarketplaceConfig[] = [];\n for (const m of list) {\n const key = marketplaceKey(m);\n if (seen.has(key)) continue;\n seen.add(key);\n out.push(m);\n }\n if (!seen.has(\"builtin\")) out.push({ kind: \"builtin\" });\n return out;\n};\n\n/** Display name before (or without) a loaded manifest header. */\nexport const marketplaceLabel = (m: MarketplaceConfig): string =>\n m.kind === \"builtin\"\n ? BUILTIN_MARKETPLACE_NAME\n : m.kind === \"github\"\n ? m.spec\n : // Folder basename beats the full path in a header.\n (m.folder.split(/[\\\\/]/).filter(Boolean).pop() ?? m.folder);\n\n/** What agents and the SDK see of a configured marketplace — never the\n * token itself. */\nexport interface MarketplaceInfo {\n key: string;\n kind: MarketplaceConfig[\"kind\"];\n label: string;\n spec?: string;\n folder?: string;\n hasToken: boolean;\n}\n\nexport const marketplaceInfo = (m: MarketplaceConfig): MarketplaceInfo => ({\n key: marketplaceKey(m),\n kind: m.kind,\n label: marketplaceLabel(m),\n ...(m.kind === \"github\" ? { spec: m.spec } : {}),\n ...(m.kind === \"folder\" ? { folder: m.folder } : {}),\n hasToken: m.kind === \"github\" && m.token !== undefined,\n});\n\n/** Does `needle` name this marketplace — by key, spec, folder or label? */\nexport const matchesMarketplace = (\n m: MarketplaceConfig,\n needle: string,\n): boolean => {\n const info = marketplaceInfo(m);\n return [info.key, info.spec, info.folder, info.label].some(\n (v) => v !== undefined && v.toLowerCase() === needle.trim().toLowerCase(),\n );\n};\n\n// ---- Catalog ----------------------------------------------------------------\n\n/** One manifest row — the minimal-manifest scheme (docs/marketplace-devx.md)\n * with the legacy pinned-URL fields still accepted. Exported so tooling\n * tests can verify generated manifests parse. */\nexport const MarketplaceEntrySchema = z\n .object({\n kind: z.enum([\"block\", \"command\"]),\n /** Qualified id — `@collection/slug`; also the module's exported id. */\n id: z.string(),\n name: z.string(),\n version: z.string(),\n description: z.string().optional(),\n tags: z.array(z.string()).default([]),\n authors: z.array(z.string()).default([]),\n /** Qualified ids of blocks this block emits instances of — install\n * resolves them from the catalog first (blocks only). */\n dependencies: z.array(z.string()).default([]),\n /** Repo-relative module path (POSIX, unencoded), resolved against the\n * marketplace repo at the ref the manifest was fetched from. */\n source: z.string().optional(),\n /** Legacy: commit-SHA-pinned raw URL of the module source. */\n sourceUrl: z.string().url().optional(),\n /** Legacy: sha-256 (hex) of the module source — no longer read. */\n contentHash: z.string().optional(),\n /** Inline SVG thumbnail markup (blocks only). */\n thumbnailSvg: z.string().optional(),\n })\n .refine((e) => e.source !== undefined || e.sourceUrl !== undefined, {\n message: \"entry needs source or sourceUrl\",\n });\nexport type MarketplaceEntry = z.infer<typeof MarketplaceEntrySchema>;\n\n// Rows the client cannot parse are DROPPED, not fatal — a newer manifest\n// format must never blank the whole marketplace for older clients.\nconst ManifestSchema = z.object({\n /** Marketplace display name (the `.lineadraw/marketplace.json` header). */\n name: z.string().optional(),\n entries: z.array(z.unknown()),\n});\n\nexport type MarketplaceCatalog =\n | { state: \"ready\"; name?: string; entries: MarketplaceEntry[] }\n | { state: \"unavailable\"; reason: string };\n\n/** Both manifest locations, in preference order (the CLI writes the first;\n * root manifest.json is the transition fallback). */\nexport const MANIFEST_PATHS = [\".lineadraw/marketplace.json\", \"manifest.json\"];\n\n/** Parse raw manifest JSON into a catalog (shared by both source kinds). */\nexport const catalogFromJson = (data: unknown): MarketplaceCatalog => {\n const parsed = ManifestSchema.safeParse(data);\n if (!parsed.success)\n return { state: \"unavailable\", reason: \"Malformed catalog.\" };\n const entries: MarketplaceEntry[] = [];\n for (const row of parsed.data.entries) {\n const entry = MarketplaceEntrySchema.safeParse(row);\n if (entry.success) entries.push(entry.data);\n }\n return { state: \"ready\", name: parsed.data.name, entries };\n};\n\n/** Search predicate over an entry's name/id/description/tags. */\nexport const entryMatches = (entry: MarketplaceEntry, q: string): boolean => {\n const needle = q.trim().toLowerCase();\n if (needle === \"\") return true;\n return [entry.name, entry.id, entry.description ?? \"\", ...entry.tags]\n .join(\" \")\n .toLowerCase()\n .includes(needle);\n};\n\n/** How a catalog entry relates to what the document already has. */\nexport type InstallStatus =\n | { kind: \"absent\" }\n | { kind: \"installed\"; version?: string }\n | { kind: \"update\"; from?: string };\n\n/** The document's module sources an install compares against. */\nexport interface VendoredModules {\n blockDefinitions: readonly string[];\n commands: readonly string[];\n}\n\n/** Compare an entry against the document's vendored modules (by id, then\n * version — content hashing is the registry milestone's refinement).\n * In the editor, `doc` must be the CALLER'S SUBSCRIBED slices, not\n * getState(): the React Compiler memoizes badge JSX by the values it\n * references, so a hidden getState() read leaves stale badges on screen. */\nexport const installStatusOf = (\n entry: MarketplaceEntry,\n doc: VendoredModules,\n): InstallStatus => {\n const scripts = entry.kind === \"block\" ? doc.blockDefinitions : doc.commands;\n const idOf = entry.kind === \"block\" ? blockScriptId : commandScriptId;\n const local = scripts.find((s) => idOf(s) === entry.id);\n if (local === undefined) return { kind: \"absent\" };\n const meta =\n entry.kind === \"block\"\n ? getBlockMetaResult(local)\n : getCommandMetaResult(local);\n const localVersion = meta.ok ? meta.meta.version : undefined;\n if (localVersion !== undefined && localVersion !== entry.version)\n return { kind: \"update\", from: localVersion };\n return { kind: \"installed\", version: localVersion };\n};\n\n/** The string that identifies an entry's module source — repo-relative\n * path, or the legacy pinned URL. Also a stable React key. */\nexport const entrySourceRef = (entry: MarketplaceEntry): string =>\n entry.source ?? entry.sourceUrl ?? entry.id;\n\n// ---- Client -----------------------------------------------------------------\n\n/** What a host lends the client: the platform's fetch (default\n * `globalThis.fetch`) and, for folder marketplaces, a reader of UTF-8\n * files by folder key + folder-relative POSIX path (reject when missing).\n * Without a reader, folder marketplaces report themselves unavailable. */\nexport interface MarketplaceIO {\n fetch?: typeof globalThis.fetch;\n readFile?: (folderKey: string, relPath: string) => Promise<string>;\n}\n\n/** A search hit: the entry, where it came from, and its install status. */\nexport interface MarketplaceHit extends MarketplaceEntry {\n marketplace: MarketplaceInfo;\n status: InstallStatus;\n}\n\nexport interface MarketplaceQuery {\n /** Case-insensitive substring over name, id, description and tags. */\n query?: string;\n kind?: MarketplaceEntry[\"kind\"];\n /** Restrict to one marketplace — by key, spec, folder or label. */\n marketplace?: string;\n}\n\n/**\n * Catalog + source access over configured marketplaces, with per-instance\n * caches: one download of a module serves preview and install, and a\n * catalog is fetched once until `refresh`. One instance per host.\n */\nexport class MarketplaceClient {\n private readonly catalogs = new Map<string, Promise<MarketplaceCatalog>>();\n private readonly sources = new Map<string, Promise<string>>();\n\n private readonly io: MarketplaceIO;\n\n constructor(io: MarketplaceIO = {}) {\n this.io = io;\n }\n\n private fetch(url: string, init?: RequestInit): Promise<Response> {\n const f = this.io.fetch ?? globalThis.fetch;\n if (f === undefined)\n return Promise.reject(new Error(\"fetch is not available in this host\"));\n return f(url, init);\n }\n\n private cacheKey(m: MarketplaceConfig): string {\n return `${marketplaceKey(m)}|${m.kind === \"github\" ? (m.token ?? \"\") : \"\"}`;\n }\n\n private async loadFolderCatalog(folder: string): Promise<MarketplaceCatalog> {\n const read = this.io.readFile;\n if (read === undefined)\n return {\n state: \"unavailable\",\n reason: \"Local folder marketplaces aren't supported in this host.\",\n };\n for (const rel of MANIFEST_PATHS) {\n let text: string;\n try {\n text = await read(folder, rel);\n } catch {\n continue; // missing file — try the fallback location\n }\n try {\n return catalogFromJson(JSON.parse(text));\n } catch {\n return { state: \"unavailable\", reason: \"Malformed catalog.\" };\n }\n }\n return {\n state: \"unavailable\",\n reason:\n \"No marketplace manifest found in this folder. Run `lineadraw manifest` there.\",\n };\n }\n\n private async loadCatalog(m: MarketplaceConfig): Promise<MarketplaceCatalog> {\n if (m.kind === \"folder\") return this.loadFolderCatalog(m.folder);\n const specText = m.kind === \"builtin\" ? BUILTIN_MARKETPLACE_SPEC : m.spec;\n const token = m.kind === \"github\" ? m.token : undefined;\n const spec = parseMarketplaceSpec(specText);\n if (spec === null)\n return {\n state: \"unavailable\",\n reason: `\"${specText}\" is not owner/repo[@branch].`,\n };\n const headers = token !== undefined ? apiHeaders(token) : undefined;\n try {\n let status = 404;\n for (const url of manifestUrls(spec, token !== undefined)) {\n const res = await this.fetch(url, { cache: \"no-cache\", headers });\n status = res.status;\n if (res.status === 404) continue; // try the fallback location\n if (!res.ok) break;\n return catalogFromJson(await res.json());\n }\n return {\n state: \"unavailable\",\n reason:\n status === 404\n ? \"No marketplace manifest found in this repository (private repos need a token).\"\n : status === 401 || status === 403\n ? \"Access denied. Check the token.\"\n : `Catalog request failed (${status}).`,\n };\n } catch {\n return {\n state: \"unavailable\",\n reason: \"Could not reach the marketplace (offline?).\",\n };\n }\n }\n\n /** Fetch (and cache) a marketplace's catalog; `refresh` bypasses the\n * cache AND drops the marketplace's cached module sources — `source`\n * rows track a branch ref, so they are only immutable within one catalog\n * snapshot. */\n catalog(m: MarketplaceConfig, refresh = false): Promise<MarketplaceCatalog> {\n const key = this.cacheKey(m);\n if (refresh) {\n this.catalogs.delete(key);\n for (const k of [...this.sources.keys()])\n if (k.startsWith(`${key}\\n`)) this.sources.delete(k);\n }\n let cached = this.catalogs.get(key);\n if (!cached) {\n cached = this.loadCatalog(m);\n this.catalogs.set(key, cached);\n }\n return cached;\n }\n\n /** An entry's module source. `source` rows resolve against the\n * marketplace repo at the manifest's ref; with a token the contents API\n * serves them instead of the raw host. */\n source(m: MarketplaceConfig, entry: MarketplaceEntry): Promise<string> {\n const key = `${this.cacheKey(m)}\\n${entrySourceRef(entry)}`;\n let cached = this.sources.get(key);\n if (!cached) {\n cached = (async () => {\n if (m.kind === \"folder\") {\n const read = this.io.readFile;\n if (read === undefined)\n throw new Error(\n \"Local folder marketplaces aren't supported in this host.\",\n );\n if (entry.source === undefined)\n throw new Error(`${entry.id} has no folder-relative source path`);\n return read(m.folder, entry.source);\n }\n const specText =\n m.kind === \"builtin\" ? BUILTIN_MARKETPLACE_SPEC : m.spec;\n const token = m.kind === \"github\" ? m.token : undefined;\n const withToken = token !== undefined;\n let url: string;\n if (entry.source !== undefined) {\n const spec = parseMarketplaceSpec(specText);\n if (spec === null)\n throw new Error(`\"${specText}\" is not owner/repo[@branch]`);\n url = sourcePathUrl(spec, withToken, entry.source);\n } else {\n const legacy = entry.sourceUrl!; // schema: source or sourceUrl\n url = withToken ? (rawToApiUrl(legacy) ?? legacy) : legacy;\n }\n const headers = withToken ? apiHeaders(token) : undefined;\n const res = await this.fetch(url, { headers });\n if (!res.ok)\n throw new Error(`Source download failed (${res.status}): ${url}`);\n return res.text();\n })();\n // A failed fetch must not poison the cache — retry on next call.\n cached.catch(() => this.sources.delete(key));\n this.sources.set(key, cached);\n }\n return cached;\n }\n\n /**\n * Sources of an entry's declared dependency CLOSURE (the entry itself\n * excluded), resolved from the catalog recursively — what a preview\n * needs so nested instances (Grid → Axis) evaluate before anything is\n * installed. Missing catalog entries are skipped (the preview then shows\n * the eval error for that id, same as a dangling reference).\n */\n async closureSources(\n m: MarketplaceConfig,\n entry: MarketplaceEntry,\n ): Promise<string[]> {\n if (entry.kind !== \"block\" || entry.dependencies.length === 0) return [];\n const catalog = await this.catalog(m);\n if (catalog.state !== \"ready\") return [];\n const sources: string[] = [];\n const visited = new Set<string>([entry.id]);\n const queue = [...entry.dependencies];\n while (queue.length > 0) {\n const id = queue.pop()!;\n if (visited.has(id)) continue;\n visited.add(id);\n const dep = catalog.entries.find(\n (e) => e.kind === \"block\" && e.id === id,\n );\n if (dep === undefined) continue;\n try {\n sources.push(await this.source(m, dep));\n } catch {\n continue; // unreachable source — preview shows the dangling id\n }\n queue.push(...dep.dependencies);\n }\n return sources;\n }\n\n /**\n * The module sources an install of `entry` merges, in order: declared\n * block dependencies first (resolved from the catalog, recursively,\n * skipping ids the document already vendors — a dependency is never\n * force-updated), the entry itself last. Throws when a dependency is\n * missing from the catalog.\n */\n async installSources(\n m: MarketplaceConfig,\n entry: MarketplaceEntry,\n vendored: VendoredModules,\n visited: Set<string> = new Set(),\n ): Promise<string[]> {\n if (visited.has(entry.id)) return []; // dependency cycle — handled\n visited.add(entry.id);\n const sources: string[] = [];\n if (entry.kind === \"block\" && entry.dependencies.length > 0) {\n const catalog = await this.catalog(m);\n for (const depId of entry.dependencies) {\n if (blockDefinitionExists(vendored.blockDefinitions, depId)) continue;\n const dep =\n catalog.state === \"ready\"\n ? catalog.entries.find((e) => e.kind === \"block\" && e.id === depId)\n : undefined;\n if (dep === undefined)\n throw new Error(`dependency ${depId} is not in the catalog`);\n sources.push(...(await this.installSources(m, dep, vendored, visited)));\n }\n }\n sources.push(await this.source(m, entry));\n return sources;\n }\n\n /** Entries across the configured marketplaces (priority order; the first\n * marketplace publishing an id wins), filtered by the query. */\n async search(\n configs: readonly MarketplaceConfig[],\n q: MarketplaceQuery,\n vendored: VendoredModules,\n ): Promise<MarketplaceHit[]> {\n const hits: MarketplaceHit[] = [];\n const seen = new Set<string>();\n for (const m of configs) {\n if (q.marketplace !== undefined && !matchesMarketplace(m, q.marketplace))\n continue;\n const catalog = await this.catalog(m);\n if (catalog.state !== \"ready\") continue;\n const info = marketplaceInfo(m);\n for (const entry of catalog.entries) {\n if (seen.has(entry.id)) continue;\n if (q.kind !== undefined && entry.kind !== q.kind) continue;\n if (!entryMatches(entry, q.query ?? \"\")) continue;\n seen.add(entry.id);\n hits.push({\n ...entry,\n marketplace: info,\n status: installStatusOf(entry, vendored),\n });\n }\n }\n return hits;\n }\n\n /** The first marketplace (in priority order, or the named one) that\n * publishes `id`, with its entry; null when none does. */\n async find(\n configs: readonly MarketplaceConfig[],\n id: string,\n marketplace?: string,\n ): Promise<{ config: MarketplaceConfig; entry: MarketplaceEntry } | null> {\n for (const config of configs) {\n if (marketplace !== undefined && !matchesMarketplace(config, marketplace))\n continue;\n const catalog = await this.catalog(config);\n if (catalog.state !== \"ready\") continue;\n const entry = catalog.entries.find((e) => e.id === id);\n if (entry) return { config, entry };\n }\n return null;\n }\n}\n","// User commands (macro scripts) as ES modules — the command-side sibling of\n// evalBlock. The document's `commands` array and the editor's per-device\n// library both hold raw module sources; one module = one command, authored\n// as `export default defineCommand({...})` (defineCommand is a runtime\n// identity resolved by the shared require shim). Everything the app knows\n// about a command derives from the compiled module:\n// id → identity (palette entries, hotkey overrides, import merge)\n// name → palette/list label\n// description / version / authors / tags → optional metadata\n// run(ctx) → the macro body. The HOST supplies ctx (document API,\n// pickers, selection, prompt, toast — typed as\n// CommandContext in lineadraw.d.ts) and wraps the whole call\n// in one undo transaction. `run` is interactive, so there is\n// no dry run — save-time validation is compile + meta.\n// Shares the lazy transpiler with blocks: callers that cannot tolerate the\n// transient \"Compiling…\" error await `ensureScriptTranspiler()` first.\n\nimport { z } from \"zod\";\nimport {\n executeScriptModule,\n parseParamsExport,\n scriptTranspilerReady,\n} from \"./evalBlock\";\nimport type { ParamDef } from \"../model/blockDefinition\";\nimport { mergeScriptModules, type MergeModulesResult } from \"./scriptModules\";\n\n/** Identity + metadata derived from a command module's exports. */\nexport interface CommandMeta {\n id: string;\n name: string;\n description?: string;\n version?: string;\n authors?: string[];\n tags?: string[];\n /** Declared point inputs (labels): picked one by one in the editor before\n * `run`, or supplied up front by a headless/remote caller. */\n inputs?: string[];\n /** Declared parameters (the blocks' ParamDef table): prompted in the\n * editor before `run`, or passed by a headless caller; arrive as\n * `ctx.params`. Absent when the command declares none. */\n params?: ParamDef[];\n}\n\n/** The compiled `run` — its ctx is host-supplied (CommandContext). */\nexport type CommandRunFn = (ctx: unknown) => unknown;\n\ninterface CompiledCommand {\n meta: CommandMeta;\n run: CommandRunFn;\n}\n\nconst OptionalMetaSchema = z.object({\n description: z.string().optional(),\n version: z.string().optional(),\n authors: z.array(z.string()).optional(),\n tags: z.array(z.string()).optional(),\n inputs: z.array(z.string().min(1)).optional(),\n});\n\n/** Validate a module's identity/metadata exports with author-facing errors. */\nconst extractCommandMeta = (mod: Record<string, unknown>): CommandMeta => {\n if (typeof mod.id !== \"string\" || mod.id.trim() === \"\")\n throw new Error(\"Command script must export a non-empty string `id`\");\n if (typeof mod.name !== \"string\" || mod.name.trim() === \"\")\n throw new Error(\"Command script must export a non-empty string `name`\");\n const parsed = OptionalMetaSchema.safeParse(mod);\n if (!parsed.success) {\n const issue = parsed.error.issues[0];\n throw new Error(\n `Invalid command metadata${\n issue ? ` — ${issue.path.join(\".\")}: ${issue.message}` : \"\"\n }`,\n );\n }\n const params = parseParamsExport(mod.params);\n return {\n id: mod.id,\n name: mod.name,\n ...parsed.data,\n ...(params.length > 0 ? { params } : {}),\n };\n};\n\n/** Compile cache keyed by the raw source (same rationale as evalBlock's). */\nconst compileCache = new Map<string, CompiledCommand>();\nconst COMPILE_CACHE_MAX = 100;\n\nconst compileCommand = (script: string): CompiledCommand => {\n const cached = compileCache.get(script);\n if (cached) {\n // Refresh recency so live-edited drafts don't evict installed commands.\n compileCache.delete(script);\n compileCache.set(script, cached);\n return cached;\n }\n const mod = executeScriptModule(script);\n const meta = extractCommandMeta(mod);\n const run = mod.run;\n if (typeof run !== \"function\")\n throw new Error(\"Command script must export a `run` function\");\n if (compileCache.size >= COMPILE_CACHE_MAX) {\n const oldest = compileCache.keys().next().value;\n if (oldest !== undefined) compileCache.delete(oldest);\n }\n const compiled = { meta, run: run as CommandRunFn };\n compileCache.set(script, compiled);\n return compiled;\n};\n\n/** Non-throwing meta lookup for list UIs. */\nexport type CommandMetaResult =\n | { ok: true; meta: CommandMeta }\n | {\n ok: false;\n error: string;\n /** True while the transient transpiler load is the only problem. */\n loading: boolean;\n };\n\nexport const getCommandMetaResult = (script: string): CommandMetaResult => {\n try {\n return { ok: true, meta: compileCommand(script).meta };\n } catch (e) {\n return {\n ok: false,\n error: e instanceof Error ? e.message : String(e),\n loading: !scriptTranspilerReady(),\n };\n }\n};\n\n/** Meta for each script in a library (invalid entries report their error). */\nexport const listCommandMeta = (\n scripts: readonly string[],\n): CommandMetaResult[] => scripts.map(getCommandMetaResult);\n\n/**\n * The compiled `run` function. Sync; throws the transient\n * \"Compiling script…\" until the lazy transpiler is loaded, and a\n * descriptive error for invalid modules.\n */\nexport const getCommandRun = (script: string): CommandRunFn =>\n compileCommand(script).run;\n\n/** Source-level `export const id = \"…\"` matcher (broken-module fallback). */\nconst ID_EXPORT_RE = /export\\s+const\\s+id\\s*=\\s*[\"']([^\"']+)[\"']/;\n\n/**\n * A module's exported id without requiring it to be valid: compiled meta\n * when possible, a source-level scan (the named-export form, or the first\n * `id: \"…\"` after the spec opener) otherwise — so merge/replace semantics\n * survive a module that no longer compiles (or the transpiler still loading).\n */\nexport const commandScriptId = (script: string): string | undefined => {\n try {\n return compileCommand(script).meta.id;\n } catch {\n const named = ID_EXPORT_RE.exec(script);\n if (named) return named[1];\n const call = script.search(/defineCommand\\s*\\(|export\\s+default\\s*\\{/);\n if (call === -1) return undefined;\n return /\\bid\\s*:\\s*[\"']([^\"']+)[\"']/.exec(script.slice(call))?.[1];\n }\n};\n\nexport type MergeCommandModulesResult = MergeModulesResult<CommandMeta>;\n\n/** Merge incoming command module sources into an existing library (same\n * invariants as blocks: verbatim → skip, id match → replace in place, name\n * clash → suffix). Await `ensureScriptTranspiler()` first — merging compiles. */\nexport const mergeCommandModules = (\n existing: readonly string[],\n incoming: readonly string[],\n): MergeCommandModulesResult =>\n mergeScriptModules(existing, incoming, {\n idOf: commandScriptId,\n metaOf: getCommandMetaResult,\n });\n","// Pure GitHub URL helpers for marketplace sources — no store imports, so\n// the spec parsing and URL rewriting stay unit-testable.\n//\n// Two fetch paths, each used where it actually works:\n// - no token → raw.githubusercontent.com (CDN, CORS *, effectively\n// unlimited; unauthenticated api.github.com is 60 req/h per IP).\n// - token (private repos) → api.github.com contents endpoint (reliable\n// Authorization CORS, 5000 req/h per token; raw does not reliably accept\n// Authorization from browsers).\n\n/** Parsed `owner/repo` or `owner/repo@branch`. */\nexport type MarketplaceSpec = {\n owner: string;\n repo: string;\n branch?: string;\n};\n\nconst SPEC_RE = /^([A-Za-z0-9_.-]+)\\/([A-Za-z0-9_.-]+)(?:@([^\\s@]+))?$/;\n\nexport const parseMarketplaceSpec = (spec: string): MarketplaceSpec | null => {\n const m = SPEC_RE.exec(spec.trim());\n if (m === null) return null;\n return { owner: m[1], repo: m[2], ...(m[3] ? { branch: m[3] } : {}) };\n};\n\nconst apiContentsUrl = (\n owner: string,\n repo: string,\n path: string,\n ref?: string,\n): string =>\n `https://api.github.com/repos/${owner}/${repo}/contents/${path}` +\n (ref !== undefined ? `?ref=${encodeURIComponent(ref)}` : \"\");\n\n/** Manifest URL candidates, preferred location first (the root\n * `manifest.json` is the pre-`.lineadraw/` transition fallback). */\nexport const manifestUrls = (\n spec: MarketplaceSpec,\n withToken: boolean,\n): string[] => {\n const paths = [\".lineadraw/marketplace.json\", \"manifest.json\"];\n if (withToken)\n return paths.map((p) =>\n apiContentsUrl(spec.owner, spec.repo, p, spec.branch),\n );\n // `HEAD` resolves to the default branch on the raw host.\n return paths.map(\n (p) =>\n `https://raw.githubusercontent.com/${spec.owner}/${spec.repo}/${spec.branch ?? \"HEAD\"}/${p}`,\n );\n};\n\n/** URL of a repo-relative module path (a manifest row's `source`) at the\n * ref the catalog itself was fetched from — raw host tokenless, contents\n * API with a token. Path segments are percent-encoded here (manifests\n * store them unencoded; filenames may contain spaces). */\nexport const sourcePathUrl = (\n spec: MarketplaceSpec,\n withToken: boolean,\n path: string,\n): string => {\n const encoded = path.split(\"/\").map(encodeURIComponent).join(\"/\");\n if (withToken)\n return apiContentsUrl(spec.owner, spec.repo, encoded, spec.branch);\n return `https://raw.githubusercontent.com/${spec.owner}/${spec.repo}/${spec.branch ?? \"HEAD\"}/${encoded}`;\n};\n\n/** Rewrite a commit-pinned raw.githubusercontent.com URL to the equivalent\n * contents-API URL (same pin via ?ref=). Returns null for non-raw URLs.\n * Legacy-manifest path only — `source` rows use sourcePathUrl. */\nexport const rawToApiUrl = (rawUrl: string): string | null => {\n const m =\n /^https:\\/\\/raw\\.githubusercontent\\.com\\/([^/]+)\\/([^/]+)\\/([^/]+)\\/(.+)$/.exec(\n rawUrl,\n );\n if (m === null) return null;\n return apiContentsUrl(m[1], m[2], m[4], m[3]);\n};\n\n/** Headers that make the contents API return raw file bytes. */\nexport const apiHeaders = (token: string): Record<string, string> => ({\n Accept: \"application/vnd.github.raw+json\",\n Authorization: `Bearer ${token}`,\n});\n","// PDF font-coverage checks. The PDF export has two ways to lose characters:\n// a font that renders as base-14 Helvetica (an \"embed\" font whose TTF the\n// host didn't register) encodes WinAnsi only, so Cyrillic becomes mojibake;\n// and an embedded TTF simply missing the glyphs (the handwriting fonts have\n// no Cyrillic) renders tofu. The PdfSink uses these checks to substitute\n// PDF_FALLBACK_FONT per string — on screen the CSS font stacks already fall\n// back natively.\n\nimport {\n ADVANCE_TABLES,\n EXTRACTED_EXTRAS,\n EXTRACTED_RANGES,\n} from \"./advanceTables\";\nimport { resolveFont, type FontId } from \"../model/fonts\";\n\n/** Substitute for text the chosen font cannot render in PDF: the default\n * font — embedded as Liberation Sans with full Cyrillic (model/fonts.ts). */\nexport const PDF_FALLBACK_FONT: FontId = \"arial\";\n\n/** WinAnsi's printable extras above U+00FF — base-14 fonts CAN encode\n * these (curly quotes, dashes, €, …), so they must not trigger fallback. */\nconst WINANSI_EXTRA = new Set(\"€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ\");\n\n/** Can base-14 Helvetica (WinAnsi) encode this text? */\nexport const winAnsiEncodable = (text: string): boolean => {\n for (const ch of text) {\n const code = ch.codePointAt(0)!;\n if (code > 0xff && !WINANSI_EXTRA.has(ch)) return false;\n }\n return true;\n};\n\nconst extracted = (ch: string, code: number): boolean =>\n EXTRACTED_RANGES.some(([a, b]) => code >= a && code <= b) ||\n EXTRACTED_EXTRAS.includes(ch);\n\n/**\n * Can this font's EMBEDDED program render `text`? Checked against the\n * extracted advance tables — a character inside the extracted ranges but\n * absent from the font's table is a REAL coverage gap. Characters outside\n * the extracted ranges are unknown and get the benefit of the doubt (the\n * chosen font is kept). Callers must use `winAnsiEncodable` instead when\n * the font actually renders as base-14 (its TTF was not registered).\n */\nexport const pdfFontCovers = (\n font: string | undefined,\n text: string,\n): boolean => {\n const def = resolveFont(font);\n if (def.pdf !== \"embed\") return winAnsiEncodable(text);\n const table = ADVANCE_TABLES[def.id];\n for (const ch of text) {\n const code = ch.codePointAt(0)!;\n if (code > 0x7e && extracted(ch, code) && table.advances[ch] === undefined)\n return false;\n }\n return true;\n};\n","// Paint a paper layout's CONTENT (viewports into model space + sheet\n// annotations) through any GeometrySink. Shared verbatim by the canvas\n// paper-space renderer and the PDF exporter — what you see is what prints.\n\nimport type { PaperLayout } from \"../model/paperLayout\";\nimport type { ModelObject, Viewport } from \"../model/objects\";\nimport { buildSnapEntry } from \"../snap/buildEntry\";\nimport { boundsIntersect, isEmptyBounds, type AABB } from \"../geometry/bounds\";\nimport type { GeometrySink, Mat2x3 } from \"./sink\";\nimport type { TextMeasurer } from \"./textMetrics\";\nimport { paintObject, type DocumentPaintResources } from \"./painters\";\nimport { rebaseSink } from \"./rebaseSink\";\nimport type { PaintGeometryCache } from \"./paintCache\";\nimport { resolveStyle } from \"./style\";\n\nexport interface LayoutPaintOptions {\n /** Map object colors for the output medium (e.g. light→black for print). */\n mapColor?: (color: string) => string;\n /**\n * Viewport-culling bounds for a model object. Defaults to\n * `buildSnapEntry(obj).bounds`; the editor passes its cached snap-entry\n * bounds instead (avoiding a per-frame recompute). Return `null` to skip\n * culling for that object.\n */\n boundsOf?: (obj: ModelObject) => AABB | null;\n /** Derived-geometry cache forwarded to the painters (see PaintEnv.cache). */\n cache?: PaintGeometryCache;\n}\n\n/**\n * The slice of document state layout painting reads. The kernel holds no\n * store, so it is passed in (the editor sources it from useModel; a headless\n * caller from the loaded document).\n */\nexport interface LayoutModelContext extends DocumentPaintResources {\n objects: readonly ModelObject[];\n}\n\n/** The viewport objects of a layout (in draw order). */\nexport const layoutViewports = (layout: PaperLayout): Viewport[] =>\n layout.objects.filter((o): o is Viewport => o.type === \"viewport\");\n\n/** Paper mm per model mm (`scale` stores the 1:N denominator). */\nconst viewportPaperPerModel = (vp: Viewport): number => 1 / vp.scale;\n\n/** Model-space window visible through a viewport. */\nexport const viewportWorldBounds = (vp: Viewport): AABB => {\n const halfW = (vp.rect.w / 2) * vp.scale;\n const halfH = (vp.rect.h / 2) * vp.scale;\n return {\n minX: vp.modelCenter.x - halfW,\n minY: vp.modelCenter.y - halfH,\n maxX: vp.modelCenter.x + halfW,\n maxY: vp.modelCenter.y + halfH,\n };\n};\n\n/** Sheet ← model transform of a viewport, for coordinates RELATIVE TO its\n * model centre (paint through `rebaseSink(sink, vp.modelCenter)`): a\n * survey-grid model (~10¹⁰ mm) would otherwise reach the canvas/PDF as huge\n * numbers and lose its precision there. */\nconst viewportTransform = (vp: Viewport): Mat2x3 => {\n const k = viewportPaperPerModel(vp);\n return [k, 0, 0, k, vp.rect.x + vp.rect.w / 2, vp.rect.y + vp.rect.h / 2];\n};\n\nconst resolveBoundsOf = (\n sink: GeometrySink,\n model: LayoutModelContext,\n opts: LayoutPaintOptions,\n): ((obj: ModelObject) => AABB | null) => {\n if (opts.boundsOf) return opts.boundsOf;\n // Bounds culling reuses the pure snap-entry geometry; text/dimension bounds\n // need measurement, taken from the sink (no DOM).\n const measure: TextMeasurer = {\n measureTextWidth: (t, h) => sink.measureText(t, h).width,\n };\n return (obj) =>\n buildSnapEntry(obj, {\n dimStyles: model.dimStyles,\n textStyles: model.textStyles,\n blockDefinitions: model.blockDefinitions,\n resolveObject: model.resolveObject,\n resolveReference: model.resolveReference,\n measure,\n }).bounds;\n};\n\n/**\n * ONE viewport's clipped, transformed model projection. The sink must be in\n * sheet-mm coordinates (the same space `paintLayoutContent` paints in), so a\n * caller can also point it at an offscreen bitmap of just the rect.\n */\nexport const paintViewportContent = (\n vp: Viewport,\n sink: GeometrySink,\n model: LayoutModelContext,\n opts: LayoutPaintOptions = {},\n): void => {\n const { objects, layers } = model;\n const layerVisible = new Map(layers.map((l) => [l.id, l.visible]));\n const layerName = new Map(layers.map((l) => [l.id, l.name]));\n const mapColor = opts.mapColor ?? ((c: string) => c);\n const boundsOf = resolveBoundsOf(sink, model, opts);\n\n sink.pushClipRect(vp.rect);\n sink.pushTransform(viewportTransform(vp));\n const content = rebaseSink(sink, vp.modelCenter);\n const visible = viewportWorldBounds(vp);\n const hiddenLayers = new Set(vp.hiddenLayerIds);\n\n for (const obj of objects) {\n if (layerVisible.get(obj.layerId) === false) continue;\n if (hiddenLayers.has(obj.layerId)) continue;\n const bounds = boundsOf(obj);\n if (bounds && !isEmptyBounds(bounds) && !boundsIntersect(bounds, visible))\n continue;\n const style = resolveStyle(obj, layers, model.lineTypes);\n sink.beginObject?.(obj.id, layerName.get(obj.layerId));\n paintObject(obj, content, {\n style: { ...style, color: mapColor(style.color) },\n ...model,\n cache: opts.cache,\n mapColor,\n });\n sink.endObject?.();\n }\n\n sink.popTransform();\n sink.popClip();\n};\n\n/** Sheet-space annotations (drawn in sheet mm). Viewport frames are screen\n * chrome (drawn by the scene renderer), so they never reach print output. */\nexport const paintLayoutAnnotations = (\n layout: PaperLayout,\n sink: GeometrySink,\n model: LayoutModelContext,\n opts: LayoutPaintOptions = {},\n): void => {\n const { layers } = model;\n const layerVisible = new Map(layers.map((l) => [l.id, l.visible]));\n const layerName = new Map(layers.map((l) => [l.id, l.name]));\n const mapColor = opts.mapColor ?? ((c: string) => c);\n for (const obj of layout.objects) {\n if (obj.type === \"viewport\") continue;\n if (layerVisible.get(obj.layerId) === false) continue;\n const style = resolveStyle(obj, layers, model.lineTypes);\n sink.beginObject?.(obj.id, layerName.get(obj.layerId));\n paintObject(obj, sink, {\n style: { ...style, color: mapColor(style.color) },\n ...model,\n cache: opts.cache,\n mapColor,\n });\n sink.endObject?.();\n }\n};\n\nexport const paintLayoutContent = (\n layout: PaperLayout,\n sink: GeometrySink,\n model: LayoutModelContext,\n opts: LayoutPaintOptions = {},\n): void => {\n // Viewport content always renders under the sheet annotations, regardless\n // of array position.\n for (const vp of layoutViewports(layout)) {\n paintViewportContent(vp, sink, model, opts);\n }\n paintLayoutAnnotations(layout, sink, model, opts);\n};\n","// Per-layout print color mapping — what authored (dark-canvas) colors become\n// on white paper. Shared by the paper-space canvas renderer and the PDF\n// exporter, so the layout on screen always previews the printed output.\n\nimport type { PrintPalette } from \"../model/paperLayout\";\nimport { hexToRgb } from \"../export/dxf/aci\";\n\nconst luminance = (r: number, g: number, b: number): number =>\n (0.2126 * r + 0.7152 * g + 0.0722 * b) / 255;\n\nconst grayHex = (level: number): string => {\n const v = Math.round(Math.min(Math.max(level, 0), 1) * 255)\n .toString(16)\n .padStart(2, \"0\");\n return `#${v}${v}${v}`;\n};\n\n/** Authored-color → print-color mapper for LayoutPaintOptions.mapColor. */\nexport const printColorMapper =\n (palette: PrintPalette): ((hex: string) => string) =>\n (hex) => {\n const rgb = hexToRgb(hex);\n if (!rgb) return hex;\n const [r, g, b] = rgb;\n const lum = luminance(r, g, b);\n switch (palette) {\n case \"color\": {\n // Only light NEUTRALS flip to black (white/light-gray lines would\n // vanish on paper); saturated colors — yellow, cyan — keep their hue.\n const saturation = (Math.max(r, g, b) - Math.min(r, g, b)) / 255;\n return lum > 0.75 && saturation < 0.25 ? \"#000000\" : hex;\n }\n case \"grayscale\":\n // Ink weight: colors authored bright on the dark canvas print dark.\n // Clamped so even dark-authored colors keep a visible gray.\n return grayHex(Math.min(1 - lum, 0.75));\n case \"monochrome\":\n return \"#000000\";\n }\n };\n","// Diff whole-collection replacements into granular operations. The editor's\n// and SDK's \"set the whole array\" surfaces stay ergonomic for callers, but\n// what goes on the wire (and into undo history) are precise per-item ops —\n// a concurrent edit to a DIFFERENT item of the same collection survives,\n// where a coarse set-op would silently clobber it. The decomposition is\n// total: updates → removes → reorder of the survivors (when their relative\n// order changed) → indexed adds reconstruct `next` exactly. The legacy\n// set-* ops are only emitted for arrays with duplicate ids/sources, which\n// nothing granular can express. See docs/granular-ops.md.\n\nimport { blockScriptId } from \"../extensions/evalBlock\";\nimport type { Layer, LineaDocument } from \"../model/document\";\nimport type { DimStyle, ModelObject, TextStyle } from \"../model/objects\";\nimport { lineTypeKey, type LineType } from \"../model/lineTypes\";\nimport {\n hatchPatternKey,\n type DocumentHatchPattern,\n} from \"../model/hatchPatterns\";\nimport type { OpSpace, Operation } from \"./types\";\n\nconst sameJson = (a: unknown, b: unknown): boolean =>\n a === b || JSON.stringify(a) === JSON.stringify(b);\n\n/** Id-keyed collection diff. `added` indices refer to the FINAL array. */\nconst diffById = <T extends { id: string }>(\n prev: readonly T[],\n next: readonly T[],\n) => {\n const prevById = new Map(prev.map((x) => [x.id, x]));\n const nextIds = new Set(next.map((x) => x.id));\n const removed = prev.filter((x) => !nextIds.has(x.id));\n const added: { item: T; index: number }[] = [];\n const updated: T[] = [];\n next.forEach((x, i) => {\n const p = prevById.get(x.id);\n if (!p) added.push({ item: x, index: i });\n else if (!sameJson(p, x)) updated.push(x);\n });\n const surviving = (arr: readonly T[], has: (id: string) => boolean) =>\n arr.filter((x) => has(x.id)).map((x) => x.id);\n /** Survivor ids in `next` order — the reorder payload when it changed. */\n const survivorOrder = surviving(next, (id) => prevById.has(id));\n const orderChanged =\n surviving(prev, (id) => nextIds.has(id)).join(\" \") !==\n survivorOrder.join(\" \");\n const duplicateIds =\n prevById.size !== prev.length || nextIds.size !== next.length;\n return { added, updated, removed, orderChanged, survivorOrder, duplicateIds };\n};\n\nexport const diffLayerOps = (\n prev: readonly Layer[],\n next: readonly Layer[],\n): Operation[] => {\n const d = diffById(prev, next);\n if (d.duplicateIds) return [{ type: \"set-layers\", layers: [...next] }];\n const ops: Operation[] = d.updated.map((layer) => ({\n type: \"update-layer\",\n layer,\n }));\n for (const l of d.removed) ops.push({ type: \"remove-layer\", id: l.id });\n if (d.orderChanged)\n ops.push({ type: \"reorder-layers\", ids: d.survivorOrder });\n for (const { item, index } of d.added)\n ops.push({ type: \"add-layer\", layer: item, index });\n return ops;\n};\n\nexport const diffTextStyleOps = (\n prev: readonly TextStyle[],\n next: readonly TextStyle[],\n): Operation[] => {\n const d = diffById(prev, next);\n if (d.duplicateIds)\n return [{ type: \"set-text-styles\", textStyles: [...next] }];\n const ops: Operation[] = d.updated.map((style) => ({\n type: \"update-text-style\",\n style,\n }));\n for (const s of d.removed) ops.push({ type: \"remove-text-style\", id: s.id });\n if (d.orderChanged)\n ops.push({ type: \"reorder-text-styles\", ids: d.survivorOrder });\n for (const { item, index } of d.added)\n ops.push({ type: \"add-text-style\", style: item, index });\n return ops;\n};\n\n/** Name-keyed collection diff (line types, hatch patterns): updates, removes,\n * then indexed adds — no reorder, order carries no meaning. */\nconst diffNamedOps = <T extends { name: string }>(\n prev: readonly T[],\n next: readonly T[],\n key: (name: string) => string,\n make: {\n update(item: T): Operation;\n add(item: T, index: number): Operation;\n remove(name: string): Operation;\n },\n): Operation[] => {\n const prevByKey = new Map(prev.map((x) => [key(x.name), x]));\n const nextKeys = new Set(next.map((x) => key(x.name)));\n const ops: Operation[] = [];\n next.forEach((x) => {\n const p = prevByKey.get(key(x.name));\n if (p && !sameJson(p, x)) ops.push(make.update(x));\n });\n for (const x of prev)\n if (!nextKeys.has(key(x.name))) ops.push(make.remove(x.name));\n next.forEach((x, i) => {\n if (!prevByKey.has(key(x.name))) ops.push(make.add(x, i));\n });\n return ops;\n};\n\nexport const diffLineTypeOps = (\n prev: readonly LineType[],\n next: readonly LineType[],\n): Operation[] =>\n diffNamedOps(prev, next, lineTypeKey, {\n update: (lineType) => ({ type: \"update-line-type\", lineType }),\n add: (lineType, index) => ({ type: \"add-line-type\", lineType, index }),\n remove: (name) => ({ type: \"remove-line-type\", name }),\n });\n\nexport const diffHatchPatternOps = (\n prev: readonly DocumentHatchPattern[],\n next: readonly DocumentHatchPattern[],\n): Operation[] =>\n diffNamedOps(prev, next, hatchPatternKey, {\n update: (hatchPattern) => ({ type: \"update-hatch-pattern\", hatchPattern }),\n add: (hatchPattern, index) => ({\n type: \"add-hatch-pattern\",\n hatchPattern,\n index,\n }),\n remove: (name) => ({ type: \"remove-hatch-pattern\", name }),\n });\n\nexport const diffDimStyleOps = (\n prev: readonly DimStyle[],\n next: readonly DimStyle[],\n): Operation[] => {\n const d = diffById(prev, next);\n if (d.duplicateIds) return [{ type: \"set-dim-styles\", dimStyles: [...next] }];\n const ops: Operation[] = d.updated.map((style) => ({\n type: \"update-dim-style\",\n style,\n }));\n for (const s of d.removed) ops.push({ type: \"remove-dim-style\", id: s.id });\n if (d.orderChanged)\n ops.push({ type: \"reorder-dim-styles\", ids: d.survivorOrder });\n for (const { item, index } of d.added)\n ops.push({ type: \"add-dim-style\", style: item, index });\n return ops;\n};\n\n/**\n * Diff two module-source arrays (block definitions or document commands)\n * into content-addressed ops. The single in-place edit — one source replaced\n * at the same slot, everything else untouched — becomes ONE update op (the\n * Monaco-save / marketplace-upgrade hot path). Everything else decomposes\n * into removes → survivor reorder (when needed) → indexed adds. Arrays with\n * duplicate sources (which content addressing cannot tell apart) fall back\n * to the legacy set op.\n */\nexport const diffModuleOps = (\n prev: readonly string[],\n next: readonly string[],\n field: \"blockDefinitions\" | \"commands\",\n): Operation[] => {\n const block = field === \"blockDefinitions\";\n const prevSet = new Set(prev);\n const nextSet = new Set(next);\n if (prevSet.size !== prev.length || nextSet.size !== next.length)\n return [\n block\n ? { type: \"set-block-definitions\", blockDefinitions: [...next] }\n : { type: \"set-document-commands\", commands: [...next] },\n ];\n if (block) {\n // A removed and an added module with the same block id is an in-place\n // REPLACE (edit, import by id), not delete + add: as an update it keeps\n // its slot and never trips remove-block-definition's in-use rule.\n const addedById = new Map<string, string>();\n for (const s of next)\n if (!prevSet.has(s)) {\n const id = blockScriptId(s);\n if (id !== undefined && !addedById.has(id)) addedById.set(id, s);\n }\n const updates: Operation[] = [];\n const replaced = prev.map((s) => {\n if (nextSet.has(s)) return s;\n const id = blockScriptId(s);\n const to = id === undefined ? undefined : addedById.get(id);\n if (to === undefined || id === undefined) return s;\n addedById.delete(id);\n updates.push({\n type: \"update-block-definition\",\n prevSource: s,\n source: to,\n });\n return to;\n });\n if (updates.length > 0)\n return [...updates, ...diffModuleOps(replaced, next, field)];\n }\n const removed = prev.filter((s) => !nextSet.has(s));\n const added: { source: string; index: number }[] = [];\n next.forEach((s, i) => {\n if (!prevSet.has(s)) added.push({ source: s, index: i });\n });\n const survivorOrder = next.filter((s) => prevSet.has(s));\n const orderChanged =\n prev.filter((s) => nextSet.has(s)).join(\" \") !== survivorOrder.join(\" \");\n if (\n !orderChanged &&\n removed.length === 1 &&\n added.length === 1 &&\n added[0].index === prev.indexOf(removed[0])\n )\n return [\n block\n ? {\n type: \"update-block-definition\",\n prevSource: removed[0],\n source: added[0].source,\n }\n : {\n type: \"update-document-command\",\n prevSource: removed[0],\n source: added[0].source,\n },\n ];\n const ops: Operation[] = removed.map((source) =>\n block\n ? { type: \"remove-block-definition\", source }\n : { type: \"remove-document-command\", source },\n );\n if (orderChanged)\n ops.push(\n block\n ? { type: \"reorder-block-definitions\", sources: survivorOrder }\n : { type: \"reorder-document-commands\", sources: survivorOrder },\n );\n for (const { source, index } of added)\n ops.push(\n block\n ? { type: \"add-block-definition\", source, index }\n : { type: \"add-document-command\", source, index },\n );\n return ops;\n};\n\n/**\n * Diff one space's object array into granular object ops: updates →\n * removes → a reorder of the survivors (when their relative order changed)\n * → indexed adds. Arrays with duplicate ids fall back to a remove-all +\n * add-all pair (nothing granular can express them).\n */\nexport const diffObjectOps = (\n prev: readonly ModelObject[],\n next: readonly ModelObject[],\n space: OpSpace,\n): Operation[] => {\n const d = diffById(prev, next);\n if (d.duplicateIds) {\n const ops: Operation[] = [];\n if (prev.length > 0)\n ops.push({ type: \"remove-objects\", space, ids: prev.map((o) => o.id) });\n if (next.length > 0)\n ops.push({ type: \"add-objects\", space, objects: [...next] });\n return ops;\n }\n const ops: Operation[] = [];\n if (d.updated.length > 0)\n ops.push({ type: \"update-objects\", space, objects: d.updated });\n if (d.removed.length > 0)\n ops.push({\n type: \"remove-objects\",\n space,\n ids: d.removed.map((o) => o.id),\n });\n if (d.orderChanged && d.survivorOrder.length > 0)\n ops.push({\n type: \"reorder-objects\",\n space,\n ids: d.survivorOrder,\n placement: \"back\",\n });\n if (d.added.length > 0)\n ops.push({\n type: \"add-objects\",\n space,\n objects: d.added.map((a) => a.item),\n indices: d.added.map((a) => a.index),\n });\n return ops;\n};\n\n/**\n * Granular ops for an id-keyed resource collection (layers, styles), split\n * into the phase that must run BEFORE dependents change (updates + adds —\n * objects may start referencing the new items) and the phase that must run\n * AFTER (removes — nothing references them any more — plus one reorder when\n * the order the two phases leave behind differs from `next`).\n */\nconst phasedResourceOps = <T extends { id: string }>(\n prev: readonly T[],\n next: readonly T[],\n make: {\n update(item: T): Operation;\n add(item: T, index: number): Operation;\n remove(id: string): Operation;\n reorder(ids: string[]): Operation;\n /** Legacy whole-array op for arrays with duplicate ids. */\n set(items: T[]): Operation;\n },\n): { before: Operation[]; after: Operation[] } => {\n const d = diffById(prev, next);\n if (d.duplicateIds) return { before: [], after: [make.set([...next])] };\n const before: Operation[] = d.updated.map((item) => make.update(item));\n for (const { item, index } of d.added) before.push(make.add(item, index));\n const after: Operation[] = d.removed.map((r) => make.remove(r.id));\n // Adds land at their FINAL index while removed items are still present, so\n // simulate what the two phases leave behind and fix the order if needed.\n const order = prev.map((x) => x.id);\n for (const { item, index } of d.added) order.splice(index, 0, item.id);\n const gone = new Set(d.removed.map((r) => r.id));\n const left = order.filter((id) => !gone.has(id)).join(\" \");\n const target = next.map((x) => x.id);\n if (left !== target.join(\" \")) after.push(make.reorder(target));\n return { before, after };\n};\n\n/**\n * Diff two whole documents into ONE op batch that turns `prev` into `next`\n * — the wire/history-shaped replacement for a wholesale document load. Ops\n * are ordered so referential integrity holds at every step: resources\n * (layers, styles, modules, assets) are added before the objects that use\n * them and removed after; existing layouts are patched by meta + a\n * per-space object diff, missing ones removed, new ones added whole. The\n * document id is NOT an op (identity is the sync scope itself) and must\n * match.\n */\nexport const diffDocumentOps = (\n prev: LineaDocument,\n next: LineaDocument,\n): Operation[] => {\n if (prev.id !== next.id)\n throw new Error(\n `diffDocumentOps: document id mismatch (\"${prev.id}\" vs \"${next.id}\")`,\n );\n const layers = phasedResourceOps(prev.layers, next.layers, {\n update: (layer) => ({ type: \"update-layer\", layer }),\n add: (layer, index) => ({ type: \"add-layer\", layer, index }),\n remove: (id) => ({ type: \"remove-layer\", id }),\n reorder: (ids) => ({ type: \"reorder-layers\", ids }),\n set: (layers) => ({ type: \"set-layers\", layers }),\n });\n const textStyles = phasedResourceOps(prev.textStyles, next.textStyles, {\n update: (style) => ({ type: \"update-text-style\", style }),\n add: (style, index) => ({ type: \"add-text-style\", style, index }),\n remove: (id) => ({ type: \"remove-text-style\", id }),\n reorder: (ids) => ({ type: \"reorder-text-styles\", ids }),\n set: (textStyles) => ({ type: \"set-text-styles\", textStyles }),\n });\n const dimStyles = phasedResourceOps(prev.dimStyles, next.dimStyles, {\n update: (style) => ({ type: \"update-dim-style\", style }),\n add: (style, index) => ({ type: \"add-dim-style\", style, index }),\n remove: (id) => ({ type: \"remove-dim-style\", id }),\n reorder: (ids) => ({ type: \"reorder-dim-styles\", ids }),\n set: (dimStyles) => ({ type: \"set-dim-styles\", dimStyles }),\n });\n\n const ops: Operation[] = [];\n ops.push(...layers.before, ...textStyles.before, ...dimStyles.before);\n ops.push(\n ...diffLineTypeOps(prev.lineTypes, next.lineTypes),\n ...diffHatchPatternOps(prev.hatchPatterns, next.hatchPatterns),\n );\n ops.push(\n ...diffModuleOps(\n prev.blockDefinitions,\n next.blockDefinitions,\n \"blockDefinitions\",\n ),\n ...diffModuleOps(prev.commands, next.commands, \"commands\"),\n );\n for (const [id, dataUrl] of Object.entries(next.assets))\n if (prev.assets[id] !== dataUrl)\n ops.push({ type: \"set-asset\", id, dataUrl });\n\n // Layouts: survivors by meta patch + object diff on their own space, then\n // removes → survivor reorder → indexed adds (the same decomposition as\n // diffObjectOps, so the result is exactly `next`).\n const prevLayouts = new Map(prev.layouts.map((l) => [l.id, l]));\n const nextLayoutIds = new Set(next.layouts.map((l) => l.id));\n for (const layout of next.layouts) {\n const before = prevLayouts.get(layout.id);\n if (!before) continue;\n const patch: Record<string, unknown> = {};\n if (before.name !== layout.name) patch.name = layout.name;\n if (!sameJson(before.sheet, layout.sheet)) patch.sheet = layout.sheet;\n if (before.printPalette !== layout.printPalette)\n patch.printPalette = layout.printPalette;\n if (Object.keys(patch).length > 0)\n ops.push({ type: \"update-layout-meta\", id: layout.id, ...patch });\n ops.push(\n ...diffObjectOps(before.objects, layout.objects, {\n layoutId: layout.id,\n }),\n );\n }\n ops.push(...diffObjectOps(prev.objects, next.objects, \"model\"));\n for (const l of prev.layouts)\n if (!nextLayoutIds.has(l.id)) ops.push({ type: \"remove-layout\", id: l.id });\n const survivors = next.layouts.filter((l) => prevLayouts.has(l.id));\n if (\n survivors.length > 0 &&\n prev.layouts\n .filter((l) => nextLayoutIds.has(l.id))\n .map((l) => l.id)\n .join(\" \") !== survivors.map((l) => l.id).join(\" \")\n )\n ops.push({ type: \"reorder-layouts\", ids: survivors.map((l) => l.id) });\n next.layouts.forEach((layout, index) => {\n if (!prevLayouts.has(layout.id))\n ops.push({ type: \"add-layout\", layout, index });\n });\n\n // Removals, now that nothing references them.\n for (const id of Object.keys(prev.assets))\n if (!(id in next.assets)) ops.push({ type: \"remove-asset\", id });\n if (prev.currentLayerId !== next.currentLayerId)\n ops.push({ type: \"set-current-layer\", id: next.currentLayerId });\n if (JSON.stringify(prev.settings) !== JSON.stringify(next.settings))\n ops.push({ type: \"set-document-settings\", settings: next.settings });\n ops.push(...dimStyles.after, ...textStyles.after, ...layers.after);\n return ops;\n};\n","// Applying a DXF conversion to a document — ONE rule for every host (the\n// SDK / agent `importDxfText`, the editor's file drop and Import menu), so\n// an import is the same edit everywhere: the same block-module merge and\n// one batch of operations = one undo step. The conversion itself\n// (dxfToModel) stays pure and worker-safe; this is the main-thread half.\n\nimport type { LineaDocument } from \"../../model/document\";\nimport { ModelObjectSchema, type ModelObject } from \"../../model/objects\";\nimport { getBlockMetaResult, blockScriptId } from \"../../extensions/evalBlock\";\nimport {\n diffDimStyleOps,\n diffHatchPatternOps,\n diffLineTypeOps,\n diffModuleOps,\n diffTextStyleOps,\n} from \"../../operations/diff\";\nimport type { Operation } from \"../../operations/types\";\nimport type { DxfImportContext, DxfImportResult } from \"./importDxf\";\n\n/** What the conversion needs from the document it merges into. Block names\n * resolve only once the script transpiler is up (`ensureScriptTranspiler`);\n * before that a clash goes unsuffixed. */\nexport const dxfImportContextOf = (\n doc: LineaDocument,\n unitOverride?: number,\n): DxfImportContext => ({\n existingLayers: doc.layers.map((l) => ({ id: l.id, name: l.name })),\n defaultLayerId: doc.currentLayerId,\n existingTextStyles: doc.textStyles,\n existingDimStyles: doc.dimStyles,\n existingLineTypes: doc.lineTypes,\n existingHatchPatterns: doc.hatchPatterns,\n existingBlocks: doc.blockDefinitions.flatMap((source) => {\n const meta = getBlockMetaResult(source);\n if (meta.ok) return [{ id: meta.meta.id, name: meta.meta.name }];\n const id = blockScriptId(source);\n return id ? [{ id, name: \"\" }] : [];\n }),\n // Nothing drawn yet: the file's styles become the document's.\n adoptStyles:\n doc.objects.length === 0 &&\n doc.layouts.every((l) => l.objects.length === 0),\n unitOverride,\n});\n\n/** The operations that merge a conversion into `doc`: layers, styles and\n * definitions before the objects that reference them, block modules, the\n * model-space objects (ids assigned here), then the layouts. */\nexport const dxfImportOps = (\n doc: LineaDocument,\n result: DxfImportResult,\n): { ops: Operation[]; objects: ModelObject[] } => {\n const objects = result.objects.map((o) =>\n ModelObjectSchema.parse({ ...o, id: crypto.randomUUID() }),\n );\n const ops: Operation[] = [\n ...result.newLayers.map((layer) => ({ type: \"add-layer\" as const, layer })),\n ...diffTextStyleOps(doc.textStyles, result.textStyles),\n ...diffDimStyleOps(doc.dimStyles, result.dimStyles),\n ...diffLineTypeOps(doc.lineTypes, result.lineTypes),\n ...diffHatchPatternOps(doc.hatchPatterns, result.hatchPatterns),\n // The conversion already left out modules the document holds and\n // suffixed name clashes (DxfImportContext.existingBlocks).\n ...diffModuleOps(\n doc.blockDefinitions,\n [...doc.blockDefinitions, ...result.newBlockDefinitions],\n \"blockDefinitions\",\n ),\n ...(objects.length > 0\n ? [{ type: \"add-objects\" as const, space: \"model\" as const, objects }]\n : []),\n ...result.layouts.map((layout) => ({\n type: \"add-layout\" as const,\n layout,\n })),\n ];\n return { ops, objects };\n};\n","// DWG support is a byte-level transcode at the file boundary: DWG bytes ↔\n// DXF text via @lineadraw/dwg-wasm (acadrust compiled to WebAssembly, lazy-loaded\n// on first use — instantiation is cached inside the package's loader).\n// Callers compose these with dxfToModel / buildDxf; core's model stays\n// DXF-shaped and never sees acadrust's document.\n\nexport type DwgVersion =\n | \"AC1015\" // AutoCAD 2000\n | \"AC1018\" // AutoCAD 2004\n | \"AC1021\" // AutoCAD 2007\n | \"AC1024\" // AutoCAD 2010\n | \"AC1027\" // AutoCAD 2013\n | \"AC1032\"; // AutoCAD 2018\n\nconst loadDwg = () => import(\"@lineadraw/dwg-wasm\").then((m) => m.loadDwg());\n\n/** DWG bytes → ASCII DXF text (compose with dxfToModel). */\nexport const dwgToDxf = async (data: Uint8Array): Promise<string> => {\n const { dwg_to_dxf } = await loadDwg();\n return dwg_to_dxf(data);\n};\n\n/** DXF text (e.g. buildDxf output) → DWG bytes. Defaults to AC1027 when the\n * DXF carries no usable $ACADVER. */\nexport const dxfToDwg = async (\n dxf: string,\n version?: DwgVersion,\n): Promise<Uint8Array> => {\n const { dxf_to_dwg } = await loadDwg();\n // acadrust cannot parse xdata on STYLE table records — strip the typeface\n // triplets buildDxf injects for CAD font resolution (see exportDxf's\n // injectStyleTypefaces) before transcoding. DWG output keeps the plain\n // file-name reference; lifting this needs xdata support in acadrust.\n return dxf_to_dwg(\n dxf.replace(/\\n1001\\nACAD\\n1000\\n[^\\n]*\\n1071\\n0(?=\\n)/g, \"\"),\n version,\n );\n};\n","// Vector PDF export: one page per layout, rendered through the very same\n// paintLayoutContent (and per-layout print palette) as the on-screen paper\n// space, so what you see is what prints. Pure/headless — the editor wraps\n// this with the store read, file naming, and save/toast.\n\nimport { jsPDF } from \"jspdf\";\nimport type { PaperLayout } from \"../../model/paperLayout\";\nimport type { LineaDocument } from \"../../model/document\";\nimport {\n dimFontFace,\n dimStyleFor,\n effectiveTextFont,\n type ModelObject,\n type TextSpan,\n} from \"../../model/objects\";\nimport {\n FONTS,\n fontFace,\n parseFontFace,\n REAL_FACES,\n realFace,\n resolveFont,\n} from \"../../model/fonts\";\nimport { PDF_FALLBACK_FONT, pdfFontCovers } from \"../../paint/fontCoverage\";\nimport {\n paintLayoutContent,\n type LayoutModelContext,\n} from \"../../paint/layoutPaint\";\nimport { printColorMapper } from \"../../paint/printPalette\";\nimport { PdfSink } from \"./pdfSink\";\nimport { tableLayout } from \"../../paint/tableLayout\";\n\n/** A TTF to embed, registered under its font id (see PaintEnv fonts). */\nexport interface PdfEmbedFont {\n /** Font id from model/fonts.ts — texts reference it via TextSpec.font —\n * or a bundled styled face (\"arial;b\", model/fonts.ts REAL_FACES). */\n id: string;\n /** TrueType (glyf) file as base64 — jsPDF cannot embed CFF/OTF. */\n ttfBase64: string;\n}\n\n/** Embeddable (pdf: \"embed\") font ids the document's text/dimensions\n * actually use — so exports only carry the TTFs they need. Block instances\n * are counted conservatively (their scripts may emit text in any font).\n * When a text's font cannot encode its content in PDF (arial + Cyrillic,\n * a handwriting font's missing glyphs), the sink substitutes\n * PDF_FALLBACK_FONT per string — so its TTF must ride along too. */\nexport const usedEmbedFontIds = (doc: LineaDocument): Set<string> => {\n const ids = new Set<string>();\n let hasBlocks = false;\n const add = (font: string | undefined, content: string) => {\n ids.add(resolveFont(font).id);\n // A bundled bold/italic face embeds as its own TTF.\n const face = realFace(font);\n if (face) ids.add(face);\n if (!pdfFontCovers(font, content)) ids.add(PDF_FALLBACK_FONT);\n };\n /** A base face over `content`, plus the faces its spans switch to. */\n const addFormatted = (\n base: string | undefined,\n content: string,\n spans: readonly TextSpan[] | undefined,\n ) => {\n add(base, content);\n const { font, bold, italic } = parseFontFace(base);\n for (const s of spans ?? [])\n add(\n fontFace(s.font ?? font, s.bold ?? bold, s.italic ?? italic),\n content.slice(s.start, s.end),\n );\n };\n const visit = (o: ModelObject) => {\n if (o.type === \"text\")\n addFormatted(\n effectiveTextFont(o, doc.textStyles).font,\n o.content,\n o.spans,\n );\n else if (o.type === \"dimension\") {\n const face = dimFontFace({\n ...dimStyleFor(o, doc.dimStyles),\n ...o.styleOverride,\n });\n // Computed measurement text is ASCII; only label content can need more.\n for (const l of o.labels) addFormatted(face, l.content ?? \"\", l.spans);\n } else if (o.type === \"table\") {\n // Every cell is a text child (same derivation the painter draws).\n for (const c of tableLayout(o, doc.textStyles).children) {\n if (c.type === \"text\")\n addFormatted(\n effectiveTextFont(c, doc.textStyles).font,\n c.content,\n c.spans,\n );\n }\n } else if (o.type === \"block\") hasBlocks = true;\n };\n doc.objects.forEach(visit);\n for (const layout of doc.layouts) layout.objects.forEach(visit);\n if (hasBlocks)\n for (const id of [...Object.keys(FONTS), ...REAL_FACES]) ids.add(id);\n for (const id of [...ids])\n if (resolveFont(id).pdf !== \"embed\") ids.delete(id);\n return ids;\n};\n\n/**\n * Strip objects on non-print layers (Layer.print === false — the AutoCAD\n * plot flag) from the model and the sheets. Viewports are kept regardless of\n * their layer: they are windows, and their frames never print anyway.\n */\nexport const stripNonPrintLayers = (\n layouts: PaperLayout[],\n model: LayoutModelContext,\n): { layouts: PaperLayout[]; model: LayoutModelContext } => {\n const noPrint = new Set(\n model.layers.filter((l) => l.print === false).map((l) => l.id),\n );\n if (noPrint.size === 0) return { layouts, model };\n return {\n model: {\n ...model,\n objects: model.objects.filter((o) => !noPrint.has(o.layerId)),\n },\n layouts: layouts.map((layout) => ({\n ...layout,\n objects: layout.objects.filter(\n (o) => o.type === \"viewport\" || !noPrint.has(o.layerId),\n ),\n })),\n };\n};\n\n/**\n * Render one or more paper layouts to a vector PDF (one page each).\n * `layouts` must be non-empty (the first sets the initial page size).\n * Fonts with pdf=\"embed\" render as Helvetica unless supplied in `fonts`.\n * Layers with `print: false` are excluded (screen-only layers).\n */\nexport const renderLayoutsToPdf = (\n printLayouts: PaperLayout[],\n printModel: LayoutModelContext,\n fonts: PdfEmbedFont[] = [],\n): jsPDF => {\n const { layouts, model } = stripNonPrintLayers(printLayouts, printModel);\n const first = layouts[0];\n const pdf = new jsPDF({\n unit: \"mm\",\n format: [first.sheet.width, first.sheet.height],\n orientation:\n first.sheet.width >= first.sheet.height ? \"landscape\" : \"portrait\",\n compress: true,\n });\n for (const font of fonts) {\n pdf.addFileToVFS(`${font.id}.ttf`, font.ttfBase64);\n pdf.addFont(`${font.id}.ttf`, font.id, \"normal\");\n }\n // One advancedAPI scope PER PAGE: jsPDF installs its mm→pt change-of-basis\n // matrix only on the page that is current when the mode switches (and\n // writes the balancing restore to the page current when it ends), so\n // adding pages inside a single advanced scope leaves every later page\n // without the matrix — content lands unscaled (pt-sized) in the corner\n // and the state stack unbalances.\n layouts.forEach((layout, index) => {\n if (index > 0) {\n pdf.addPage(\n [layout.sheet.width, layout.sheet.height],\n layout.sheet.width >= layout.sheet.height ? \"landscape\" : \"portrait\",\n );\n }\n pdf.advancedAPI((advanced) => {\n const sink = new PdfSink(advanced, layout.sheet.height);\n paintLayoutContent(layout, sink, model, {\n mapColor: printColorMapper(layout.printPalette),\n });\n });\n });\n return pdf;\n};\n","// GeometrySink over jsPDF. Note: jsPDF's \"advanced\" API mode is NOT\n// PDF-native y-up — it installs a global CTM of [s 0 0 -s 0 pageHeight],\n// so user coordinates are y-DOWN millimeters from the TOP-LEFT (verified\n// against the generated content stream). Our sheet space is y-up from the\n// bottom-left, so the matrix stack bottoms out at a y-flip.\n// Transforms are baked in JS, so clipping and lineweights stay trivially\n// correct.\n\nimport type jsPDF from \"jspdf\";\nimport type {\n FillStyle,\n GeometrySink,\n ImageSpec,\n Mat2x3,\n Rect,\n StrokeStyle,\n TextSpec,\n} from \"../../paint/sink\";\nimport {\n arcToBeziers,\n ellipseArcToBeziers,\n matApply,\n matMultiply,\n signedArcSweep,\n} from \"../../paint/sink\";\nimport { parseFontFace, realFace, resolveFont } from \"../../model/fonts\";\nimport {\n PDF_FALLBACK_FONT,\n pdfFontCovers,\n winAnsiEncodable,\n} from \"../../paint/fontCoverage\";\nimport type { Vec2 } from \"../../geometry/vec2\";\n\nconst PT_PER_MM = 72 / 25.4;\n\n/** Synthesized italic slant (tan of the skew angle, ~14°) — Skia's fake\n * italic, so a synthesized PDF face leans like the canvas one. */\nconst SYNTH_ITALIC_SKEW = 0.25;\n/** Synthesized bold: outline stroke width as a fraction of the cap height. */\nconst SYNTH_BOLD_STROKE = 0.04;\n\n/** #rrggbb → [r, g, b] 0-255 (jsPDF shading stop format). */\nconst hexToRgb255 = (hex: string): number[] => {\n const m = /^#?([0-9a-f]{6})$/i.exec(hex.trim());\n const v = m ? Number.parseInt(m[1], 16) : 0;\n return [(v >> 16) & 0xff, (v >> 8) & 0xff, v & 0xff];\n};\n\nexport class PdfSink implements GeometrySink {\n private readonly doc: jsPDF;\n private matrixStack: Mat2x3[];\n private pathOpen = false;\n private pathStart: Vec2 | null = null;\n private current: Vec2 | null = null;\n private gradId = 0;\n\n constructor(doc: jsPDF, sheetHeightMm: number) {\n this.doc = doc;\n // Base flip: sheet (y-up, origin bottom-left) → jsPDF advanced user\n // space (y-down, origin top-left).\n this.matrixStack = [[1, 0, 0, -1, 0, sheetHeightMm]];\n }\n\n private get matrix(): Mat2x3 {\n return this.matrixStack[this.matrixStack.length - 1];\n }\n\n private map(p: Vec2): Vec2 {\n return matApply(this.matrix, p);\n }\n\n /** Uniform scale of the current transform (for angle-preserving checks). */\n private get scaleFactor(): number {\n const m = this.matrix;\n return Math.hypot(m[0], m[1]);\n }\n\n /**\n * The font DEFINITION a string actually renders with: the requested font,\n * unless it cannot render the text in PDF — an embedded TTF lacking the\n * glyphs (the handwriting fonts + Cyrillic = tofu), or a font degrading to\n * base-14 Helvetica because its TTF was not registered (WinAnsi-only →\n * Cyrillic mojibake) — in which case the fallback substitutes per string\n * when IT can render the text. Size must then use THIS def's capHeight,\n * so callers take the def, not just a name.\n */\n private pdfFontDef(font: string | undefined, text: string) {\n // Coverage of what will ACTUALLY render: an unregistered \"embed\" font\n // becomes base-14 Helvetica, so it is judged by WinAnsi, not its table.\n const usable = (def: ReturnType<typeof resolveFont>) =>\n def.pdf === \"embed\" && this.doc.getFontList()[def.id]\n ? pdfFontCovers(def.id, text)\n : winAnsiEncodable(text);\n const def = resolveFont(font);\n if (usable(def)) return def;\n const fallback = resolveFont(PDF_FALLBACK_FONT);\n return usable(fallback) ? fallback : def;\n }\n\n /**\n * jsPDF font name for a font def: built-ins map directly; \"embed\" fonts\n * must have been registered (addFileToVFS/addFont under the font id) by\n * the exporting host — fall back to helvetica when they weren't.\n */\n private pdfFontName(def: ReturnType<typeof resolveFont>): string {\n if (def.pdf !== \"embed\") return def.pdf;\n return this.doc.getFontList()[def.id] ? def.id : \"helvetica\";\n }\n\n beginPath(): void {\n this.pathOpen = false;\n this.pathStart = null;\n this.current = null;\n }\n\n moveTo(p: Vec2): void {\n const q = this.map(p);\n this.doc.moveTo(q.x, q.y);\n this.pathOpen = true;\n this.pathStart = q;\n this.current = q;\n }\n\n lineTo(p: Vec2): void {\n const q = this.map(p);\n this.doc.lineTo(q.x, q.y);\n this.current = q;\n }\n\n bezierTo(c1: Vec2, c2: Vec2, end: Vec2): void {\n const q1 = this.map(c1);\n const q2 = this.map(c2);\n const qe = this.map(end);\n this.doc.curveTo(q1.x, q1.y, q2.x, q2.y, qe.x, qe.y);\n this.current = qe;\n }\n\n arc(\n center: Vec2,\n r: number,\n startAngle: number,\n endAngle: number,\n ccw: boolean,\n ): void {\n // Emit in the LOCAL frame and map each bezier point — uniform transforms\n // preserve circles as scaled circles, and beziers survive any affine map.\n const beziers = arcToBeziers(\n center,\n r,\n startAngle,\n signedArcSweep(startAngle, endAngle, ccw),\n );\n this.emitBeziers(beziers);\n }\n\n ellipse(\n center: Vec2,\n rx: number,\n ry: number,\n rotation: number,\n startAngle: number,\n endAngle: number,\n ): void {\n this.emitBeziers(\n ellipseArcToBeziers(\n center,\n rx,\n ry,\n rotation,\n startAngle,\n signedArcSweep(startAngle, endAngle, true),\n ),\n );\n }\n\n private emitBeziers(\n beziers: { start: Vec2; c1: Vec2; c2: Vec2; end: Vec2 }[],\n ): void {\n if (beziers.length === 0) return;\n const first = this.map(beziers[0].start);\n if (!this.pathOpen || !this.current) {\n this.doc.moveTo(first.x, first.y);\n this.pathOpen = true;\n this.pathStart = first;\n } else if (\n Math.hypot(this.current.x - first.x, this.current.y - first.y) > 1e-6\n ) {\n this.doc.lineTo(first.x, first.y);\n }\n for (const b of beziers) {\n const q1 = this.map(b.c1);\n const q2 = this.map(b.c2);\n const qe = this.map(b.end);\n this.doc.curveTo(q1.x, q1.y, q2.x, q2.y, qe.x, qe.y);\n this.current = qe;\n }\n }\n\n closePath(): void {\n this.doc.close();\n this.current = this.pathStart;\n }\n\n /**\n * Run `paint` with a per-op transparency GState when opacity < 1. jsPDF\n * buffers path construction until the painting call, so the q/gs pair\n * lands BEFORE the path in the content stream (the image() pattern).\n */\n private withOpacity(opacity: number | undefined, paint: () => void): void {\n const translucent = opacity !== undefined && opacity < 1;\n if (translucent) {\n this.doc.saveGraphicsState();\n this.doc.setGState(\n this.doc.GState({ opacity, \"stroke-opacity\": opacity }),\n );\n }\n paint();\n if (translucent) this.doc.restoreGraphicsState();\n }\n\n stroke(s: StrokeStyle): void {\n if (!this.pathOpen) return;\n this.doc.setDrawColor(s.color);\n this.doc.setLineWidth(Math.max(s.widthMm, 0.05));\n this.doc.setLineCap(\"round\");\n this.doc.setLineJoin(\"round\");\n this.doc.setLineDashPattern(s.dashMm ?? [], 0);\n this.withOpacity(s.opacity, () => this.doc.stroke());\n this.doc.setLineDashPattern([], 0);\n this.beginPath();\n }\n\n fill(f: FillStyle): void {\n if (!this.pathOpen) return;\n if (f.gradient) {\n // Axial/radial shading between the two colors; endpoints go through\n // the same matrix as the path, so the ramp stays anchored to the\n // geometry. Radial radius scales by the (uniform) transform.\n const a = this.map(f.gradient.from);\n const b = this.map(f.gradient.to);\n const key = `linea-grad-${this.gradId++}`;\n const coords =\n f.gradient.shape === \"radial\"\n ? [a.x, a.y, 0, a.x, a.y, Math.hypot(b.x - a.x, b.y - a.y)]\n : [a.x, a.y, b.x, b.y];\n this.doc.addShadingPattern(\n key,\n this.doc.ShadingPattern(\n f.gradient.shape === \"radial\" ? \"radial\" : \"axial\",\n coords,\n [\n { offset: 0, color: hexToRgb255(f.color) },\n { offset: 1, color: hexToRgb255(f.gradient.color2) },\n ],\n ),\n );\n // jsPDF requires a pattern matrix for shading fills (it stringifies\n // it unconditionally); identity keeps coords in path user space.\n this.withOpacity(f.opacity, () =>\n this.doc.fillEvenOdd({ key, matrix: this.doc.unitMatrix }),\n );\n this.beginPath();\n return;\n }\n this.doc.setFillColor(f.color);\n this.withOpacity(f.opacity, () => this.doc.fillEvenOdd());\n this.beginPath();\n }\n\n /**\n * The jsPDF font a face renders with + what must be synthesized: a styled\n * face uses its bundled TTF when the host registered it, otherwise the\n * regular font with fake bold (fill+stroke) / italic (skew). A coverage\n * fallback (pdfFontDef swapped the font) synthesizes too.\n */\n private pdfFace(font: string | undefined, text: string) {\n const def = this.pdfFontDef(font, text);\n const { bold, italic } = parseFontFace(font);\n const face = def.id === resolveFont(font).id ? realFace(font) : null;\n const real = face && this.doc.getFontList()[face] ? face : null;\n return {\n def,\n name: real ?? this.pdfFontName(def),\n synthBold: bold && !real,\n synthItalic: italic && !real,\n };\n }\n\n text(t: TextSpec): void {\n const heightMm = t.heightMm * this.scaleFactor;\n const { def, name, synthBold, synthItalic } = this.pdfFace(t.font, t.text);\n this.doc.setFont(name, \"normal\");\n // Model heights are CAP heights; PDF font size is the em.\n this.doc.setFontSize((heightMm / def.capHeight) * PT_PER_MM);\n this.doc.setTextColor(t.color);\n const widthFactor = t.widthFactor ?? 1;\n // jsPDF's own align/baseline offsets are broken in advanced mode (it\n // divides them by scaleFactor although text space is already mm-scaled),\n // so we place the exact baseline-left anchor ourselves — in cap-height\n // terms, matching canvasSink: bottom = baseline at the anchor, center /\n // top shift the baseline by half / full cap height.\n const width =\n (this.doc.getTextWidth(t.text) / this.scaleFactor) * widthFactor;\n const dx =\n t.hAlign === \"center\" ? -width / 2 : t.hAlign === \"right\" ? -width : 0;\n const dy =\n t.vAlign === \"center\"\n ? t.heightMm / 2\n : t.vAlign === \"top\"\n ? t.heightMm\n : 0;\n // Local text frame (y-up): run along the rotation, baseline dy below.\n const cos = Math.cos(t.rotation);\n const sin = Math.sin(t.rotation);\n const anchor = this.map({\n x: t.anchor.x + cos * dx + sin * dy,\n y: t.anchor.y + sin * dx - cos * dy,\n });\n const m = this.matrix;\n const extraRotation = Math.atan2(m[1], m[0]);\n const draw = () =>\n this.doc.text(t.text, anchor.x, anchor.y, {\n angle: ((t.rotation + extraRotation) * 180) / Math.PI,\n align: \"left\",\n baseline: \"alphabetic\",\n // AutoCAD-style width factor → PDF Tz horizontal scaling. ALWAYS\n // set: Tz is graphics state and persists across BT/ET, so an\n // omitted value inherits whatever the previous text left behind\n // (a 0.8-factor text would silently squeeze every later text).\n horizontalScale: widthFactor,\n // Same reason: Tr persists, so plain text resets it to fill.\n renderingMode: synthBold ? \"fillThenStroke\" : \"fill\",\n });\n if (!synthBold && !synthItalic) {\n this.withOpacity(t.opacity, draw);\n return;\n }\n this.doc.saveGraphicsState();\n if (synthBold) {\n this.doc.setDrawColor(t.color);\n this.doc.setLineWidth(heightMm * SYNTH_BOLD_STROKE);\n }\n if (synthItalic) {\n // Shear about the anchor along the text's page-space baseline: a\n // point h above the baseline moves k·h along it. Directions come from\n // the current transform, so any y-flip in it can't invert the slant.\n const w0 = t.anchor;\n const p0 = this.map(w0);\n const unit = (p: Vec2) => {\n const v = { x: p.x - p0.x, y: p.y - p0.y };\n const l = Math.hypot(v.x, v.y) || 1;\n return { x: v.x / l, y: v.y / l };\n };\n const d = unit(this.map({ x: w0.x + cos, y: w0.y + sin }));\n const u = unit(this.map({ x: w0.x - sin, y: w0.y + cos }));\n const k = SYNTH_ITALIC_SKEW;\n const a = 1 + k * d.x * u.x;\n const b = k * d.y * u.x;\n const c = k * d.x * u.y;\n const e = 1 + k * d.y * u.y;\n this.doc.setCurrentTransformationMatrix(\n this.doc.Matrix(\n a,\n b,\n c,\n e,\n anchor.x - (a * anchor.x + c * anchor.y),\n anchor.y - (b * anchor.x + e * anchor.y),\n ),\n );\n }\n this.withOpacity(t.opacity, draw);\n this.doc.restoreGraphicsState();\n }\n\n measureText(\n text: string,\n heightMm: number,\n font?: string,\n widthFactor = 1,\n ): { width: number } {\n const { def, name } = this.pdfFace(font, text);\n this.doc.setFont(name, \"normal\");\n this.doc.setFontSize((heightMm / def.capHeight) * PT_PER_MM);\n return { width: this.doc.getTextWidth(text) * widthFactor };\n }\n\n image(i: ImageSpec): void {\n // Compose a local frame whose y-DOWN [0..w]×[0..h] box (top-left at the\n // local origin — jsPDF advanced user-space semantics) is exactly the\n // image footprint, and install it as the CTM for one addImage call.\n const cos = Math.cos(i.rotation);\n const sin = Math.sin(i.rotation);\n const place: Mat2x3 = [cos, sin, -sin, cos, i.origin.x, i.origin.y];\n const flip: Mat2x3 = [1, 0, 0, -1, 0, i.heightMm];\n const m = matMultiply(matMultiply(this.matrix, place), flip);\n this.doc.saveGraphicsState();\n if (i.opacity < 1)\n this.doc.setGState(this.doc.GState({ opacity: i.opacity }));\n this.doc.setCurrentTransformationMatrix(\n this.doc.Matrix(m[0], m[1], m[2], m[3], m[4], m[5]),\n );\n const format = i.data.startsWith(\"data:image/png\") ? \"PNG\" : \"JPEG\";\n this.doc.addImage(\n i.data,\n format,\n 0,\n 0,\n i.widthMm,\n i.heightMm,\n undefined,\n \"FAST\",\n );\n this.doc.restoreGraphicsState();\n this.beginPath();\n }\n\n pushTransform(m: Mat2x3): void {\n this.matrixStack.push(matMultiply(this.matrix, m));\n }\n\n popTransform(): void {\n if (this.matrixStack.length > 1) this.matrixStack.pop();\n }\n\n pushClipRect(r: Rect): void {\n const p = this.map({ x: r.x, y: r.y });\n const q = this.map({ x: r.x + r.w, y: r.y + r.h });\n this.doc.saveGraphicsState();\n this.doc.moveTo(Math.min(p.x, q.x), Math.min(p.y, q.y));\n this.doc.lineTo(Math.max(p.x, q.x), Math.min(p.y, q.y));\n this.doc.lineTo(Math.max(p.x, q.x), Math.max(p.y, q.y));\n this.doc.lineTo(Math.min(p.x, q.x), Math.max(p.y, q.y));\n this.doc.close();\n this.doc.clip();\n this.doc.discardPath();\n this.beginPath();\n }\n\n popClip(): void {\n this.doc.restoreGraphicsState();\n }\n}\n","// High-level SVG rendering — the SVG counterpart to renderLayoutsToPdf. Paints\n// through the shared painters into an SvgSink, so SVG output matches screen and\n// PDF. `renderModelToSvg` frames the content bbox; `renderLayoutToSvg` frames a\n// sheet.\n\nimport { SvgSink } from \"./svgSink\";\nimport {\n paintLayoutContent,\n type LayoutModelContext,\n} from \"../../paint/layoutPaint\";\nimport { paintObject } from \"../../paint/painters\";\nimport { rebaseSink } from \"../../paint/rebaseSink\";\nimport { printColorMapper } from \"../../paint/printPalette\";\nimport { resolveStyle } from \"../../paint/style\";\nimport type { PrintPalette } from \"../../model/paperLayout\";\nimport { approximateTextMeasurer } from \"../../paint/textMeasurer\";\nimport type { TextMeasurer } from \"../../paint/textMetrics\";\nimport { buildSnapEntry } from \"../../snap/buildEntry\";\nimport {\n addPointToBounds,\n boundsIntersect,\n emptyBounds,\n isEmptyBounds,\n unionBounds,\n type AABB,\n} from \"../../geometry/bounds\";\nimport type { PaperLayout } from \"../../model/paperLayout\";\n\nexport interface SvgRenderOptions {\n /** Frame this world box instead of the content bounds. */\n bbox?: AABB;\n /** Text width measurement (defaults to the approximate Inter table). */\n measure?: TextMeasurer;\n /** Padding around the frame, world mm. */\n padding?: number;\n /**\n * Print-style color remap (same mapper as the PDF export): \"monochrome\"\n * turns every stroke black — the fix for light editor-theme layers\n * vanishing on a white background. Model render default: \"color\" (none);\n * layout render default: the layout's own printPalette.\n */\n palette?: PrintPalette;\n /**\n * Minimum stroke width as a FRACTION of the frame's larger side —\n * for thumbnails, where a fixed-mm lineweight scaled to a ~256px image\n * turns sub-pixel and the render rasterizes to nothing. E.g. a value of\n * 1.5/256 keeps every stroke ≥ ~1.5px when the render is displayed 256px\n * wide, regardless of drawing extents. Model render only.\n */\n minStrokeFrac?: number;\n}\n\n/** Render model space (the given objects) to an SVG string. */\nexport const renderModelToSvg = (\n model: LayoutModelContext,\n opts: SvgRenderOptions = {},\n): string => {\n const measure = opts.measure ?? approximateTextMeasurer;\n // No palette = as-authored colors verbatim: even \"color\" flips light\n // neutrals for paper, which would silently change every existing\n // dark-canvas model render. Mapping is strictly opt-in here.\n const mapColor = opts.palette\n ? printColorMapper(opts.palette)\n : (c: string) => c;\n const layerVisible = new Map(model.layers.map((l) => [l.id, l.visible]));\n const layerName = new Map(model.layers.map((l) => [l.id, l.name]));\n // Pass 1 — the frame: minStrokeFrac needs the final extents before any\n // stroke is emitted, so bounds are collected ahead of painting.\n const toPaint: (typeof model.objects)[number][] = [];\n let bbox = opts.bbox ?? emptyBounds();\n for (const obj of model.objects) {\n if (layerVisible.get(obj.layerId) === false) continue;\n const b = buildSnapEntry(obj, {\n dimStyles: model.dimStyles,\n textStyles: model.textStyles,\n blockDefinitions: model.blockDefinitions,\n resolveObject: model.resolveObject,\n resolveReference: model.resolveReference,\n measure,\n }).bounds;\n if (opts.bbox) {\n // A bbox crop culls, not just frames: off-view geometry must not ride\n // along invisibly in the file (size, and it leaks unshared content).\n if (isEmptyBounds(b) || !boundsIntersect(b, opts.bbox)) continue;\n } else if (!isEmptyBounds(b)) {\n bbox = unionBounds(bbox, b);\n }\n toPaint.push(obj);\n }\n if (isEmptyBounds(bbox)) addPointToBounds(bbox, { x: 0, y: 0 });\n\n // Pass 2 — paint into a sink that clamps hairlines relative to the frame.\n const minStrokeWidthMm = opts.minStrokeFrac\n ? opts.minStrokeFrac *\n Math.max(bbox.maxX - bbox.minX, bbox.maxY - bbox.minY)\n : undefined;\n const sink = new SvgSink({ measure, minStrokeWidthMm });\n // A drawing far from the origin (survey coordinates) is written relative\n // to its frame's corner: SVG viewers render in float32 and would quantize\n // 10¹⁰-mm coordinates to metres. ponytail: below FAR_MM it stays absolute\n // (readers/agents may rely on real coordinates) — always rebase if that\n // ever matters less than consistency.\n const far =\n Math.max(\n Math.abs(bbox.minX),\n Math.abs(bbox.maxX),\n Math.abs(bbox.minY),\n Math.abs(bbox.maxY),\n ) > FAR_MM;\n const origin = far ? { x: bbox.minX, y: bbox.minY } : { x: 0, y: 0 };\n const out = rebaseSink(sink, origin);\n for (const obj of toPaint) {\n const style = resolveStyle(obj, model.layers, model.lineTypes);\n sink.beginObject(obj.id, layerName.get(obj.layerId));\n paintObject(obj, out, {\n style: { ...style, color: mapColor(style.color) },\n ...model,\n mapColor,\n });\n sink.endObject();\n }\n return sink.toSvg(\n {\n minX: bbox.minX - origin.x,\n minY: bbox.minY - origin.y,\n maxX: bbox.maxX - origin.x,\n maxY: bbox.maxY - origin.y,\n },\n opts.padding,\n );\n};\n\n/** Beyond 10 km from the origin an SVG is written relative to its frame. */\nconst FAR_MM = 1e7;\n\n/**\n * Render a paper layout (viewport content + sheet annotations) to SVG, framed\n * to the sheet. Note: viewport clipping is not yet enforced by SvgSink (v1).\n */\nexport const renderLayoutToSvg = (\n layout: PaperLayout,\n model: LayoutModelContext,\n opts: SvgRenderOptions = {},\n): string => {\n const sink = new SvgSink({ measure: opts.measure });\n // Honor the layout's own print palette (like the PDF export) unless the\n // caller overrides it.\n paintLayoutContent(layout, sink, model, {\n mapColor: printColorMapper(opts.palette ?? layout.printPalette),\n });\n const bbox = opts.bbox ?? {\n minX: 0,\n minY: 0,\n maxX: layout.sheet.width,\n maxY: layout.sheet.height,\n };\n return sink.toSvg(bbox, opts.padding ?? 0);\n};\n","// One PDF page → model object DTOs: STROKED paths become lines/polylines,\n// text runs become text objects. Pure — it consumes pdf.js v6\n// getOperatorList()/getTextContent() output with the OPS enum injected, so\n// tests can drive it with the node-safe legacy build.\n//\n// pdf.js v6 fuses path construction with its paint op: constructPath args are\n// [paintOp, [flatPathData], minMax] where the flat data interleaves DrawOPS\n// codes (0 moveTo, 1 lineTo, 2 cubic, 3 quadratic, 4 closePath) with coords.\n// Colors arrive pre-normalized as \"#rrggbb\" strings.\n\nimport type { ModelObjectDto } from \"../../model/objects\";\nimport type { Vec2 } from \"../../geometry/vec2\";\nimport {\n matApply,\n matIdentity,\n matMultiply,\n type Mat2x3,\n} from \"../../paint/sink\";\n\nconst PT2MM = 25.4 / 72;\nconst BEZIER_STEPS = 12;\n\n/**\n * Colors in PDFs are authored for white paper; dark neutrals (black/dark-gray\n * ink) map to byLayer (undefined) so they stay visible on the dark canvas.\n */\nconst importColor = (hex: string): string | undefined => {\n const m = /^#([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})$/i.exec(hex);\n if (!m) return undefined;\n const [r, g, b] = [m[1], m[2], m[3]].map((h) => parseInt(h, 16));\n const lum = (0.2126 * r + 0.7152 * g + 0.0722 * b) / 255;\n const saturation = (Math.max(r, g, b) - Math.min(r, g, b)) / 255;\n return lum < 0.35 && saturation < 0.25 ? undefined : hex.toLowerCase();\n};\n\nexport interface PdfTextItem {\n str: string;\n /** Text matrix in page space (pt, y-up): [a, b, c, d, tx, ty]. */\n transform: number[];\n}\n\nexport interface PdfPageInput {\n fnArray: number[];\n argsArray: unknown[];\n textItems: PdfTextItem[];\n /** MediaBox [x0, y0, x1, y1] in pt. */\n view: number[];\n /** pdf.js OPS enum (injected — differs per build flavor, values stable). */\n ops: Record<string, number>;\n /** The page's /Rotate (degrees CLOCKWISE, a multiple of 90): viewers show\n * the page turned by it, so the import does too. */\n rotate?: number;\n /** Also take FILLED paths, as their outlines (a raster PDF reference's\n * snap geometry — frames and borders are often drawn as fills). */\n fills?: boolean;\n}\n\ntype DistributiveOmit<T, K extends PropertyKey> = T extends unknown\n ? Omit<T, K>\n : never;\n\n/** Object base fields left for the caller: layerId. */\nexport type PdfDto = DistributiveOmit<ModelObjectDto, \"layerId\">;\n\nexport const convertPdfPage = (input: PdfPageInput): PdfDto[] => {\n const { fnArray, argsArray, view, ops } = input;\n const strokeOps = new Set(\n [\n ops.stroke,\n ops.closeStroke,\n ops.fillStroke,\n ops.eoFillStroke,\n ops.closeFillStroke,\n ops.closeEOFillStroke,\n ].filter((v) => v !== undefined),\n );\n\n // Page space → mm with the page's /Rotate applied (clockwise, Y-up), so\n // the result sits upright in the positive quadrant as a viewer shows it.\n const w = (view[2] - view[0]) * PT2MM;\n const h = (view[3] - view[1]) * PT2MM;\n const turn = ((((input.rotate ?? 0) % 360) + 360) % 360) / 90;\n const fillOps = new Set(\n [ops.fill, ops.eoFill].filter((v) => v !== undefined),\n );\n const toMm = (p: Vec2): Vec2 => {\n const x = (p.x - view[0]) * PT2MM;\n const y = (p.y - view[1]) * PT2MM;\n return turn === 1\n ? { x: y, y: w - x }\n : turn === 2\n ? { x: w - x, y: h - y }\n : turn === 3\n ? { x: h - y, y: x }\n : { x, y };\n };\n const turnRad = (-turn * Math.PI) / 2;\n\n const dtos: PdfDto[] = [];\n const stack: Mat2x3[] = [];\n let ctm: Mat2x3 = matIdentity;\n let strokeColor: string | undefined;\n let lineWidth = 1;\n\n const emitSubpath = (points: Vec2[], closed: boolean): void => {\n if (points.length < 2) return;\n const scale = Math.hypot(ctm[0], ctm[1]) || 1;\n const widthMm = Math.max(lineWidth * scale * PT2MM, 0.05);\n const base = {\n color: strokeColor,\n lineWidth: Math.round(widthMm * 100) / 100,\n };\n if (points.length === 2 && !closed) {\n dtos.push({ type: \"line\", a: points[0], b: points[1], ...base });\n return;\n }\n dtos.push({\n type: \"polyline\",\n points: points.map((p) => ({ x: p.x, y: p.y, bulge: 0 })),\n closed,\n ...base,\n });\n };\n\n const flushPath = (data: number[]): void => {\n let current: Vec2 | null = null;\n let subpath: Vec2[] = [];\n let closed = false;\n const flush = () => {\n emitSubpath(subpath, closed);\n subpath = [];\n closed = false;\n };\n const push = (p: Vec2) => {\n current = p;\n subpath.push(toMm(matApply(ctm, p)));\n };\n const sample = (f: (t: number) => Vec2) => {\n for (let s = 1; s <= BEZIER_STEPS; s++) push(f(s / BEZIER_STEPS));\n };\n let i = 0;\n while (i < data.length) {\n switch (data[i]) {\n case 0: // moveTo\n if (subpath.length > 1) flush();\n else subpath = [];\n push({ x: data[i + 1], y: data[i + 2] });\n i += 3;\n break;\n case 1: // lineTo\n push({ x: data[i + 1], y: data[i + 2] });\n i += 3;\n break;\n case 2: {\n // cubic bezier\n const [p0, c1, c2, p1] = [\n current ?? { x: data[i + 1], y: data[i + 2] },\n { x: data[i + 1], y: data[i + 2] },\n { x: data[i + 3], y: data[i + 4] },\n { x: data[i + 5], y: data[i + 6] },\n ];\n sample((t) => {\n const u = 1 - t;\n return {\n x:\n u * u * u * p0.x +\n 3 * u * u * t * c1.x +\n 3 * u * t * t * c2.x +\n t * t * t * p1.x,\n y:\n u * u * u * p0.y +\n 3 * u * u * t * c1.y +\n 3 * u * t * t * c2.y +\n t * t * t * p1.y,\n };\n });\n i += 7;\n break;\n }\n case 3: {\n // quadratic bezier\n const p0 = current ?? { x: data[i + 1], y: data[i + 2] };\n const c = { x: data[i + 1], y: data[i + 2] };\n const p1 = { x: data[i + 3], y: data[i + 4] };\n sample((t) => {\n const u = 1 - t;\n return {\n x: u * u * p0.x + 2 * u * t * c.x + t * t * p1.x,\n y: u * u * p0.y + 2 * u * t * c.y + t * t * p1.y,\n };\n });\n i += 5;\n break;\n }\n case 4: // closePath\n closed = true;\n i += 1;\n break;\n default:\n // Unknown sub-op — bail on this path rather than misparse.\n return flush();\n }\n }\n flush();\n };\n\n for (let i = 0; i < fnArray.length; i++) {\n const fn = fnArray[i];\n const args = argsArray[i] as unknown[] | null;\n if (fn === ops.save) stack.push(ctm);\n else if (fn === ops.restore) ctm = stack.pop() ?? matIdentity;\n else if (fn === ops.transform && args)\n ctm = matMultiply(ctm, args as unknown as Mat2x3);\n else if (fn === ops.setStrokeRGBColor && args)\n strokeColor = importColor(String(args[0]));\n else if (fn === ops.setLineWidth && args) lineWidth = Number(args[0]);\n else if (fn === ops.constructPath && args) {\n const [paintOp, pathData] = args as [\n number,\n ArrayLike<number> | ArrayLike<number>[],\n ];\n // Lines-only import (fills, clips skipped) unless outlines are asked for.\n if (!strokeOps.has(paintOp) && !(input.fills && fillOps.has(paintOp)))\n continue;\n // Path data arrives as Float32Array chunks (or one flat run).\n const flat: number[] =\n typeof (pathData as ArrayLike<number>)[0] === \"number\"\n ? Array.from(pathData as ArrayLike<number>)\n : Array.from(pathData as ArrayLike<ArrayLike<number>>, (part) =>\n Array.from(part),\n ).flat();\n flushPath(flat);\n }\n }\n\n // Text runs: transform = [a, b, c, d, tx, ty] in page space (pt, y-up);\n // the y basis length is the effective font size, (tx, ty) the\n // baseline-left origin → left / bottom justified.\n for (const item of input.textItems) {\n if (!item.str.trim()) continue;\n const [a, b, c, d, tx, ty] = item.transform;\n const height = Math.hypot(c, d) * PT2MM;\n if (!(height > 0)) continue;\n dtos.push({\n type: \"text\",\n position: toMm({ x: tx, y: ty }),\n content: item.str,\n // The PDF glyph size is explicit — keep it as an override.\n styleOverride: { textHeight: Math.round(height * 1000) / 1000 },\n rotation: Math.atan2(b, a) + turnRad,\n // A PDF run starts at its baseline origin: text right of and above it.\n hAlign: \"left\",\n vAlign: \"bottom\",\n leaderLines: [],\n scale: 1,\n });\n }\n\n return dtos;\n};\n","// PDF → model objects. Stroked vector paths become lines/polylines and text\n// runs become text objects — PDFs don't preserve dimensions/leaders as\n// objects, so those arrive as exploded geometry. Multi-page files lay pages\n// out left-to-right.\n//\n// HEADLESS: imports pdf.js's `legacy` build (the main build needs the DOM),\n// which runs in Node with no worker configuration. A browser caller may pass\n// a bundled `workerSrc`. Pure conversion is delegated to convertPdfPage; this\n// module only drives pdf.js. The caller assigns a layer and applies the DTOs.\n\nimport { convertPdfPage, type PdfDto } from \"./convertPage\";\n\nconst PAGE_GAP_MM = 10;\n\n/** Shift a converted page right (multi-page files lay out left-to-right). */\nconst shiftX = (dto: PdfDto, dx: number): PdfDto => {\n switch (dto.type) {\n case \"line\":\n return {\n ...dto,\n a: { x: dto.a.x + dx, y: dto.a.y },\n b: { x: dto.b.x + dx, y: dto.b.y },\n };\n case \"polyline\":\n return {\n ...dto,\n points: dto.points.map((p) => ({ ...p, x: p.x + dx })),\n };\n case \"text\":\n return {\n ...dto,\n position: { x: dto.position.x + dx, y: dto.position.y },\n };\n default:\n return dto;\n }\n};\n\nexport interface PdfImportOptions {\n /**\n * pdf.js worker source. Node needs none (the legacy build runs on a fake\n * worker). In a browser, pass the bundled worker URL. Set only when given.\n */\n workerSrc?: string;\n /** Called before converting each page (1-based), e.g. for a progress UI. */\n onProgress?: (page: number, pageCount: number) => void | Promise<void>;\n /** Convert only this 1-based page, at the origin (a PDF reference). */\n page?: number;\n /** Filled paths too, as outlines (see PdfPageInput.fills). */\n fills?: boolean;\n}\n\nexport interface PdfImportResult {\n /** Converted objects as layer-less DTOs — the caller assigns a layer. */\n objects: PdfDto[];\n pageCount: number;\n}\n\n/**\n * Parse PDF bytes into model-object DTOs. Pure of any store/UI; throws if\n * pdf.js cannot parse the data. The editor/CLI wraps this with the layer\n * assignment, the undo transaction, and toasts.\n */\nexport const pdfToModel = async (\n data: ArrayBuffer | Uint8Array,\n opts: PdfImportOptions = {},\n): Promise<PdfImportResult> => {\n // Lazy: pdfjs is by far the heaviest dependency and only PDF *import*\n // needs it — loaded statically it would weigh on (or, where its native\n // pieces misbehave, take down) every consumer that never touches PDFs.\n const { getDocument, GlobalWorkerOptions, OPS } =\n await import(\"pdfjs-dist/legacy/build/pdf.mjs\");\n if (opts.workerSrc !== undefined)\n GlobalWorkerOptions.workerSrc = opts.workerSrc;\n\n const objects: PdfDto[] = [];\n const doc = await getDocument({ data }).promise;\n const pageCount = doc.numPages;\n let offsetX = 0;\n const pages =\n opts.page !== undefined\n ? [Math.min(Math.max(1, opts.page), pageCount)]\n : Array.from({ length: pageCount }, (_, i) => i + 1);\n for (const n of pages) {\n await opts.onProgress?.(n, pageCount);\n const page = await doc.getPage(n);\n const [list, text] = await Promise.all([\n page.getOperatorList(),\n page.getTextContent(),\n ]);\n const pageDtos = convertPdfPage({\n fnArray: list.fnArray,\n argsArray: list.argsArray,\n textItems: text.items.filter(\n (i): i is Extract<(typeof text.items)[number], { str: string }> =>\n \"str\" in i && \"transform\" in i,\n ),\n view: page.view,\n ops: OPS as unknown as Record<string, number>,\n rotate: page.rotate,\n fills: opts.fills,\n });\n for (const dto of pageDtos) objects.push(shiftX(dto, offsetX));\n // A quarter-turned page is as wide as its box is tall.\n const quarter = page.rotate % 180 !== 0;\n offsetX +=\n (quarter ? page.view[3] - page.view[1] : page.view[2] - page.view[0]) *\n (25.4 / 72) +\n PAGE_GAP_MM;\n }\n await doc.cleanup();\n return { objects, pageCount };\n};\n","// Semantic operation DTOs — the shared mutation contract for the SDK, CLI,\n// MCP tools, and cloud sync (see docs/kernel-op-layer.md). Every op is\n// self-contained, id-based, space-addressed, versioned, and invertible.\n\nimport { z } from \"zod\";\nimport { LayerSchema } from \"../model/document\";\nimport {\n DimStyleSchema,\n ModelObjectSchema,\n TextStyleSchema,\n} from \"../model/objects\";\nimport { LineTypeSchema } from \"../model/lineTypes\";\nimport { HatchPatternSchema } from \"../model/hatchPatterns\";\nimport { PaperLayoutSchema, PrintPaletteSchema } from \"../model/paperLayout\";\nimport { DocumentSettingsSchema } from \"../model/document\";\n\n// --- document field ops ----------------------------------------------------\n\n/** Replace the document-wide settings (the whole record; callers merge). */\nconst SetDocumentSettingsOpSchema = z.object({\n type: z.literal(\"set-document-settings\"),\n settings: DocumentSettingsSchema,\n});\n\n// --- layer ops -------------------------------------------------------------\n\nconst AddLayerOpSchema = z.object({\n type: z.literal(\"add-layer\"),\n layer: LayerSchema,\n /** Insertion index (defaults to append); carried so undo restores order. */\n index: z.number().int().nonnegative().optional(),\n});\n\nconst UpdateLayerOpSchema = z.object({\n type: z.literal(\"update-layer\"),\n layer: LayerSchema,\n});\n\nconst RemoveLayerOpSchema = z.object({\n type: z.literal(\"remove-layer\"),\n id: z.string(),\n});\n\n/** Explicit total order — every current layer id exactly once. Ids only, so\n * a concurrent property edit to a layer survives a reorder. */\nconst ReorderLayersOpSchema = z.object({\n type: z.literal(\"reorder-layers\"),\n ids: z.array(z.string()).min(1),\n});\n\nconst SetCurrentLayerOpSchema = z.object({\n type: z.literal(\"set-current-layer\"),\n id: z.string(),\n});\n\n/** LEGACY full layer-list replace — accepted for wire/history compat, no\n * longer emitted (diffLayerOps decomposes into the granular ops + reorder).\n * Validated like the granular ops: the current layer and every layer still\n * in use must survive. */\nconst SetLayersOpSchema = z.object({\n type: z.literal(\"set-layers\"),\n layers: z.array(LayerSchema).min(1),\n});\n\n// --- object ops (the funnel core) -----------------------------------------\n\n/** Target collection of an op: model space or a specific paper layout. */\nexport const OpSpaceSchema = z.union([\n z.literal(\"model\"),\n z.object({ layoutId: z.string() }),\n]);\nexport type OpSpace = z.infer<typeof OpSpaceSchema>;\n\nconst AddObjectsOpSchema = z.object({\n type: z.literal(\"add-objects\"),\n space: OpSpaceSchema,\n /** Ids are pre-assigned by the caller (never stamped here). */\n objects: z.array(ModelObjectSchema).min(1),\n /**\n * Optional insertion indices into the space's draw order, matched 1:1 to\n * `objects` and referring to positions in the FINAL array (ascending).\n * Omitted = append. Carried by remove-objects inverses so undoing a delete\n * restores exact draw order.\n */\n indices: z.array(z.number().int().nonnegative()).optional(),\n});\n\nconst UpdateObjectsOpSchema = z.object({\n type: z.literal(\"update-objects\"),\n space: OpSpaceSchema,\n /** Full replacement states, matched to existing objects by id. */\n objects: z.array(ModelObjectSchema).min(1),\n});\n\nconst RemoveObjectsOpSchema = z.object({\n type: z.literal(\"remove-objects\"),\n space: OpSpaceSchema,\n ids: z.array(z.string()).min(1),\n});\n\n/**\n * Where a reorder places the moved objects: the top/bottom of the space's\n * draw order, or immediately above/below a reference object (by id).\n */\nconst ReorderPlacementSchema = z.union([\n z.literal(\"front\"),\n z.literal(\"back\"),\n z.object({ above: z.string() }),\n z.object({ below: z.string() }),\n]);\nexport type ReorderPlacement = z.infer<typeof ReorderPlacementSchema>;\n\nconst ReorderObjectsOpSchema = z.object({\n type: z.literal(\"reorder-objects\"),\n space: OpSpaceSchema,\n /**\n * Moved as one contiguous run in the order GIVEN here (bottom → top).\n * Passing every id of the space with placement \"back\" therefore sets an\n * explicit total order — which is how inverses restore exactly.\n */\n ids: z.array(z.string()).min(1),\n placement: ReorderPlacementSchema,\n});\n\n// --- layout ops ------------------------------------------------------------\n\nconst AddLayoutOpSchema = z.object({\n type: z.literal(\"add-layout\"),\n layout: PaperLayoutSchema,\n index: z.number().int().nonnegative().optional(),\n});\n\n/** Sheet metadata only — layout CONTENT is edited via object ops on its space. */\nconst UpdateLayoutMetaOpSchema = z.object({\n type: z.literal(\"update-layout-meta\"),\n id: z.string(),\n name: z.string().optional(),\n sheet: z.object({ width: z.number(), height: z.number() }).optional(),\n printPalette: PrintPaletteSchema.optional(),\n});\n\nconst RemoveLayoutOpSchema = z.object({\n type: z.literal(\"remove-layout\"),\n id: z.string(),\n});\n\n/** Explicit total order — every current layout id exactly once. Layout\n * order is semantic: it is the sheet order of multi-page PDF export. */\nconst ReorderLayoutsOpSchema = z.object({\n type: z.literal(\"reorder-layouts\"),\n ids: z.array(z.string()).min(1),\n});\n\n/** Full layout replace by id (sheet AND content — page setup, bulk edits).\n * The granular path (update-layout-meta + object ops on the layout's space)\n * stays preferred; this mirrors the editor's coarse updateLayouts. */\nconst UpdateLayoutsOpSchema = z.object({\n type: z.literal(\"update-layouts\"),\n layouts: z.array(PaperLayoutSchema).min(1),\n});\n\n// --- text style ops ---------------------------------------------------------------\n\nconst AddTextStyleOpSchema = z.object({\n type: z.literal(\"add-text-style\"),\n style: TextStyleSchema,\n /** Insertion index (defaults to append); carried so undo restores order. */\n index: z.number().int().nonnegative().optional(),\n});\n\nconst UpdateTextStyleOpSchema = z.object({\n type: z.literal(\"update-text-style\"),\n /** Full replacement state, matched by id. */\n style: TextStyleSchema,\n});\n\nconst RemoveTextStyleOpSchema = z.object({\n type: z.literal(\"remove-text-style\"),\n id: z.string(),\n});\n\n/** Explicit total order of style ids (first style = the document default,\n * so order is semantic, not just display). */\nconst ReorderTextStylesOpSchema = z.object({\n type: z.literal(\"reorder-text-styles\"),\n ids: z.array(z.string()).min(1),\n});\n\n/** LEGACY full replace — accepted for wire/history compat, no longer\n * emitted; edits decompose into the granular trio + reorder. */\nconst SetTextStylesOpSchema = z.object({\n type: z.literal(\"set-text-styles\"),\n textStyles: z.array(TextStyleSchema),\n});\n\n// --- line type / hatch pattern definition ops -----------------------------------\n//\n// Named by `name` (objects reference them by name; there is no id). The\n// trio per resource; no reorder — order carries no meaning for these.\n\nconst AddLineTypeOpSchema = z.object({\n type: z.literal(\"add-line-type\"),\n lineType: LineTypeSchema,\n index: z.number().int().nonnegative().optional(),\n});\nconst UpdateLineTypeOpSchema = z.object({\n type: z.literal(\"update-line-type\"),\n /** Full replacement, matched by (case-insensitive) name. */\n lineType: LineTypeSchema,\n});\nconst RemoveLineTypeOpSchema = z.object({\n type: z.literal(\"remove-line-type\"),\n name: z.string(),\n});\n\nconst AddHatchPatternOpSchema = z.object({\n type: z.literal(\"add-hatch-pattern\"),\n hatchPattern: HatchPatternSchema,\n index: z.number().int().nonnegative().optional(),\n});\nconst UpdateHatchPatternOpSchema = z.object({\n type: z.literal(\"update-hatch-pattern\"),\n hatchPattern: HatchPatternSchema,\n});\nconst RemoveHatchPatternOpSchema = z.object({\n type: z.literal(\"remove-hatch-pattern\"),\n name: z.string(),\n});\n\n// --- dim style ops ---------------------------------------------------------------\n\nconst AddDimStyleOpSchema = z.object({\n type: z.literal(\"add-dim-style\"),\n style: DimStyleSchema,\n index: z.number().int().nonnegative().optional(),\n});\n\nconst UpdateDimStyleOpSchema = z.object({\n type: z.literal(\"update-dim-style\"),\n style: DimStyleSchema,\n});\n\nconst RemoveDimStyleOpSchema = z.object({\n type: z.literal(\"remove-dim-style\"),\n id: z.string(),\n});\n\nconst ReorderDimStylesOpSchema = z.object({\n type: z.literal(\"reorder-dim-styles\"),\n ids: z.array(z.string()).min(1),\n});\n\n/** LEGACY full replace — same role as set-text-styles. */\nconst SetDimStylesOpSchema = z.object({\n type: z.literal(\"set-dim-styles\"),\n dimStyles: z.array(DimStyleSchema),\n});\n\n// --- asset ops ---------------------------------------------------------------\n\nconst SetAssetOpSchema = z.object({\n type: z.literal(\"set-asset\"),\n /** Content key (hashAsset of the data URL, by convention). */\n id: z.string(),\n dataUrl: z.string(),\n});\n\nconst RemoveAssetOpSchema = z.object({\n type: z.literal(\"remove-asset\"),\n id: z.string(),\n});\n\n// --- block definition ops ---------------------------------------------------------------\n//\n// Module ops (blocks and document commands) are CONTENT-addressed: a module\n// is an opaque source string whose semantic id only exists after compiling,\n// which pure op validation cannot do — and identical strings are genuinely\n// indistinguishable, so exact-source addressing is precise. A stale\n// `prevSource`/`source` no longer in the document REJECTS (unknown-module)\n// instead of silently clobbering a concurrent edit. See docs/granular-ops.md.\n\nconst AddBlockDefinitionOpSchema = z.object({\n type: z.literal(\"add-block-definition\"),\n source: z.string(),\n /** Insertion index (defaults to append); carried so undo restores order. */\n index: z.number().int().nonnegative().optional(),\n});\n\nconst UpdateBlockDefinitionOpSchema = z.object({\n type: z.literal(\"update-block-definition\"),\n /** The exact current source this edit was computed against. */\n prevSource: z.string(),\n source: z.string(),\n});\n\nconst RemoveBlockDefinitionOpSchema = z.object({\n type: z.literal(\"remove-block-definition\"),\n source: z.string(),\n});\n\n/** Explicit total order of the current sources. Same payload size as the\n * set op, but SAME-SET validated: a stale reorder rejects instead of\n * deleting a module a peer added concurrently. */\nconst ReorderBlockDefinitionsOpSchema = z.object({\n type: z.literal(\"reorder-block-definitions\"),\n sources: z.array(z.string()).min(1),\n});\n\n/** LEGACY full replace — accepted for wire/history compat and as the only\n * op that can express duplicate sources; no longer emitted otherwise. */\nconst SetBlockDefinitionsOpSchema = z.object({\n type: z.literal(\"set-block-definitions\"),\n /** Raw block module sources (semantic validation happens at compile). */\n blockDefinitions: z.array(z.string()),\n});\n\n// --- document command ops ----------------------------------------------------\n\nconst AddDocumentCommandOpSchema = z.object({\n type: z.literal(\"add-document-command\"),\n source: z.string(),\n index: z.number().int().nonnegative().optional(),\n});\n\nconst UpdateDocumentCommandOpSchema = z.object({\n type: z.literal(\"update-document-command\"),\n prevSource: z.string(),\n source: z.string(),\n});\n\nconst RemoveDocumentCommandOpSchema = z.object({\n type: z.literal(\"remove-document-command\"),\n source: z.string(),\n});\n\nconst ReorderDocumentCommandsOpSchema = z.object({\n type: z.literal(\"reorder-document-commands\"),\n sources: z.array(z.string()).min(1),\n});\n\n/** LEGACY full replace — same role as set-block-definitions. */\nconst SetDocumentCommandsOpSchema = z.object({\n type: z.literal(\"set-document-commands\"),\n /** Raw user-command module sources (document scope). */\n commands: z.array(z.string()),\n});\n\nexport const OperationSchema = z.discriminatedUnion(\"type\", [\n // document\n // objects\n AddObjectsOpSchema,\n UpdateObjectsOpSchema,\n RemoveObjectsOpSchema,\n ReorderObjectsOpSchema,\n // layers\n AddLayerOpSchema,\n UpdateLayerOpSchema,\n RemoveLayerOpSchema,\n ReorderLayersOpSchema,\n SetLayersOpSchema,\n SetCurrentLayerOpSchema,\n SetDocumentSettingsOpSchema,\n // layouts\n AddLayoutOpSchema,\n UpdateLayoutMetaOpSchema,\n RemoveLayoutOpSchema,\n ReorderLayoutsOpSchema,\n UpdateLayoutsOpSchema,\n // text styles\n AddTextStyleOpSchema,\n UpdateTextStyleOpSchema,\n RemoveTextStyleOpSchema,\n ReorderTextStylesOpSchema,\n SetTextStylesOpSchema,\n // line types / hatch patterns\n AddLineTypeOpSchema,\n UpdateLineTypeOpSchema,\n RemoveLineTypeOpSchema,\n AddHatchPatternOpSchema,\n UpdateHatchPatternOpSchema,\n RemoveHatchPatternOpSchema,\n // dim styles\n AddDimStyleOpSchema,\n UpdateDimStyleOpSchema,\n RemoveDimStyleOpSchema,\n ReorderDimStylesOpSchema,\n SetDimStylesOpSchema,\n // assets\n SetAssetOpSchema,\n RemoveAssetOpSchema,\n // block definitions\n AddBlockDefinitionOpSchema,\n UpdateBlockDefinitionOpSchema,\n RemoveBlockDefinitionOpSchema,\n ReorderBlockDefinitionsOpSchema,\n SetBlockDefinitionsOpSchema,\n // commands\n AddDocumentCommandOpSchema,\n UpdateDocumentCommandOpSchema,\n RemoveDocumentCommandOpSchema,\n ReorderDocumentCommandsOpSchema,\n SetDocumentCommandsOpSchema,\n]);\n\nexport type Operation = z.infer<typeof OperationSchema>;\n\n/** An op batch from outside the kernel's own code (scripts, agents, the\n * SDK): schema-checked so a malformed op fails here with a readable message\n * instead of being saved and failing the document schema on reopen. */\nexport const parseOperations = (ops: readonly unknown[]): Operation[] => {\n const result = z.array(OperationSchema).safeParse(ops);\n if (!result.success)\n throw new Error(`applyOps(): invalid operation\n${z.prettifyError(result.error)}`);\n return result.data;\n};\n","// Pure operation applier + validator. `applyOperation(doc, op)` validates the\n// op against full document state (referential integrity), returns the next\n// document and the INVERSE op. No store, no indexes, no invalidation — the\n// cloud server runs this against authoritative state; DocumentKernel wraps it\n// with indexes + invalidation. See docs/kernel-op-layer.md.\n\nimport { embeddedAssetId } from \"../model/assets\";\nimport {\n blockDefinitionExists,\n blockScriptId,\n getBlockMetaResult,\n} from \"../extensions/evalBlock\";\nimport type { LineaDocument } from \"../model/document\";\nimport { dimStyleFor, textStyleFor, type ModelObject } from \"../model/objects\";\nimport type { PaperLayout } from \"../model/paperLayout\";\nimport type { OpSpace, Operation } from \"./types\";\nimport { lineTypeKey } from \"../model/lineTypes\";\nimport { hatchPatternKey } from \"../model/hatchPatterns\";\n\n/** Machine-readable validation/apply failure. */\nexport type OpErrorCode =\n | \"unknown-space\"\n | \"unknown-object\"\n | \"duplicate-id\"\n | \"missing-layer\"\n | \"missing-definition\"\n | \"viewport-in-model\"\n | \"invalid-reorder\"\n | \"unknown-layer\"\n | \"layer-in-use\"\n | \"last-layer\"\n | \"current-layer\"\n | \"unknown-layout\"\n | \"duplicate-layout\"\n | \"invalid-dimension\"\n | \"unknown-asset\"\n | \"asset-in-use\"\n | \"unknown-style\"\n | \"last-style\"\n | \"style-in-use\"\n | \"unknown-module\"\n | \"definition-in-use\"\n | \"duplicate-name\"\n | \"not-found\";\n\nexport class OpError extends Error {\n readonly code: OpErrorCode;\n constructor(code: OpErrorCode, message: string) {\n super(message);\n this.name = \"OpError\";\n this.code = code;\n }\n}\n\nexport interface ApplyResult {\n document: LineaDocument;\n /** The op that undoes this one exactly. */\n inverse: Operation;\n}\n\n// --- space helpers ---------------------------------------------------------\n\nconst spaceLabel = (s: OpSpace): string =>\n s === \"model\" ? \"model\" : `layout ${s.layoutId}`;\n\nconst getSpaceObjects = (doc: LineaDocument, space: OpSpace): ModelObject[] => {\n if (space === \"model\") return doc.objects;\n const layout = doc.layouts.find((l) => l.id === space.layoutId);\n if (!layout)\n throw new OpError(\"unknown-space\", `No layout ${space.layoutId}`);\n return layout.objects;\n};\n\nconst setSpaceObjects = (\n doc: LineaDocument,\n space: OpSpace,\n objects: ModelObject[],\n): LineaDocument =>\n space === \"model\"\n ? { ...doc, objects }\n : {\n ...doc,\n layouts: doc.layouts.map((l) =>\n l.id === space.layoutId ? { ...l, objects } : l,\n ),\n };\n\n// --- referential integrity -------------------------------------------------\n\nconst assertObjectRefs = (\n doc: LineaDocument,\n obj: ModelObject,\n space: OpSpace,\n): void => {\n if (!doc.layers.some((l) => l.id === obj.layerId))\n throw new OpError(\n \"missing-layer\",\n `Object ${obj.id} references unknown layer ${obj.layerId}`,\n );\n // Definition ids are module exports — the check compiles (cached) and is\n // PERMISSIVE while the lazy transpiler is still loading; evaluation reports\n // the definitive per-instance error either way.\n if (\n obj.type === \"block\" &&\n !blockDefinitionExists(doc.blockDefinitions, obj.definitionId)\n )\n throw new OpError(\n \"missing-definition\",\n `Block ${obj.id} references unknown definition ${obj.definitionId}`,\n );\n if (obj.type === \"viewport\" && space === \"model\")\n throw new OpError(\n \"viewport-in-model\",\n `Viewport ${obj.id} cannot live in model space`,\n );\n if (obj.type === \"dimension\") {\n // What each kind's geometry derivation actually needs (fewer points\n // renders as nothing, which hides authoring bugs).\n const min = { linear: 2, angular: 3, radial: 2, diameter: 2 }[obj.kind];\n if (obj.points.length < min)\n throw new OpError(\n \"invalid-dimension\",\n `Dimension ${obj.id}: a ${obj.kind} dimension needs at least ${min} points, got ${obj.points.length}`,\n );\n }\n};\n\n// --- object ops ------------------------------------------------------------\n\nconst applyAddObjects = (\n doc: LineaDocument,\n op: Extract<Operation, { type: \"add-objects\" }>,\n): ApplyResult => {\n const existing = getSpaceObjects(doc, op.space);\n const ids = new Set(existing.map((o) => o.id));\n for (const obj of op.objects) {\n if (ids.has(obj.id))\n throw new OpError(\n \"duplicate-id\",\n `Object ${obj.id} already exists in ${spaceLabel(op.space)}`,\n );\n assertObjectRefs(doc, obj, op.space);\n }\n let next: ModelObject[];\n if (op.indices && op.indices.length === op.objects.length) {\n // Positional insert: indices refer to the FINAL array, ascending —\n // exactly what a remove-objects inverse recorded. Out-of-range indices\n // clamp to append so a stale inverse still lands every object.\n next = [...existing];\n op.objects\n .map((obj, i) => ({ obj, at: op.indices![i] }))\n .sort((a, b) => a.at - b.at)\n .forEach(({ obj, at }) => next.splice(Math.min(at, next.length), 0, obj));\n } else {\n next = [...existing, ...op.objects];\n }\n return {\n document: setSpaceObjects(doc, op.space, next),\n inverse: {\n type: \"remove-objects\",\n space: op.space,\n ids: op.objects.map((o) => o.id),\n },\n };\n};\n\nconst applyUpdateObjects = (\n doc: LineaDocument,\n op: Extract<Operation, { type: \"update-objects\" }>,\n): ApplyResult => {\n const existing = getSpaceObjects(doc, op.space);\n const byId = new Map(existing.map((o) => [o.id, o]));\n const previous: ModelObject[] = [];\n for (const obj of op.objects) {\n const prev = byId.get(obj.id);\n if (!prev)\n throw new OpError(\n \"unknown-object\",\n `Object ${obj.id} not found in ${spaceLabel(op.space)}`,\n );\n previous.push(prev);\n assertObjectRefs(doc, obj, op.space);\n }\n const patch = new Map(op.objects.map((o) => [o.id, o]));\n return {\n document: setSpaceObjects(\n doc,\n op.space,\n existing.map((o) => patch.get(o.id) ?? o),\n ),\n inverse: { type: \"update-objects\", space: op.space, objects: previous },\n };\n};\n\nconst applyRemoveObjects = (\n doc: LineaDocument,\n op: Extract<Operation, { type: \"remove-objects\" }>,\n): ApplyResult => {\n const existing = getSpaceObjects(doc, op.space);\n const byId = new Map(existing.map((o) => [o.id, o]));\n for (const id of op.ids) {\n if (!byId.has(id))\n throw new OpError(\n \"unknown-object\",\n `Object ${id} not found in ${spaceLabel(op.space)}`,\n );\n }\n const drop = new Set(op.ids);\n // Record removed objects with their ORIGINAL indices so the inverse\n // restores exact draw order (positional insert into the final array).\n const removed: ModelObject[] = [];\n const indices: number[] = [];\n existing.forEach((o, i) => {\n if (drop.has(o.id)) {\n removed.push(o);\n indices.push(i);\n }\n });\n return {\n document: setSpaceObjects(\n doc,\n op.space,\n existing.filter((o) => !drop.has(o.id)),\n ),\n inverse: {\n type: \"add-objects\",\n space: op.space,\n objects: removed,\n indices,\n },\n };\n};\n\nconst applyReorderObjects = (\n doc: LineaDocument,\n op: Extract<Operation, { type: \"reorder-objects\" }>,\n): ApplyResult => {\n const existing = getSpaceObjects(doc, op.space);\n const byId = new Map(existing.map((o) => [o.id, o]));\n const moving = new Set(op.ids);\n if (moving.size !== op.ids.length)\n throw new OpError(\"invalid-reorder\", `Duplicate ids in reorder`);\n const moved: ModelObject[] = op.ids.map((id) => {\n const obj = byId.get(id);\n if (!obj)\n throw new OpError(\n \"unknown-object\",\n `Object ${id} not found in ${spaceLabel(op.space)}`,\n );\n return obj;\n });\n const rest = existing.filter((o) => !moving.has(o.id));\n let at: number;\n const p = op.placement;\n if (p === \"back\") at = 0;\n else if (p === \"front\") at = rest.length;\n else {\n const refId = \"above\" in p ? p.above : p.below;\n if (moving.has(refId))\n throw new OpError(\n \"invalid-reorder\",\n `Reference object ${refId} is part of the moved set`,\n );\n const refIndex = rest.findIndex((o) => o.id === refId);\n if (refIndex === -1)\n throw new OpError(\n \"unknown-object\",\n `Reference object ${refId} not found in ${spaceLabel(op.space)}`,\n );\n at = \"above\" in p ? refIndex + 1 : refIndex;\n }\n return {\n document: setSpaceObjects(doc, op.space, [\n ...rest.slice(0, at),\n ...moved,\n ...rest.slice(at),\n ]),\n // Full previous order + \"back\" = explicit total order — exact restore.\n inverse: {\n type: \"reorder-objects\",\n space: op.space,\n ids: existing.map((o) => o.id),\n placement: \"back\",\n },\n };\n};\n\n// --- layer ops -------------------------------------------------------------\n\n/** Layer names are addressed by name (scripts, DXF) and DXF treats them\n * case-insensitively — no two layers may share one. Only new names are\n * checked: documents that already hold duplicates still load and edit. */\nconst assertLayerNameFree = (\n doc: LineaDocument,\n name: string,\n exceptId: string,\n): void => {\n const clash = doc.layers.find(\n (l) => l.id !== exceptId && l.name.toLowerCase() === name.toLowerCase(),\n );\n if (clash)\n throw new OpError(\n \"duplicate-name\",\n `A layer named \"${clash.name}\" already exists`,\n );\n};\n\nconst applyAddLayer = (\n doc: LineaDocument,\n op: Extract<Operation, { type: \"add-layer\" }>,\n): ApplyResult => {\n if (doc.layers.some((l) => l.id === op.layer.id))\n throw new OpError(\"duplicate-id\", `Layer ${op.layer.id} already exists`);\n assertLayerNameFree(doc, op.layer.name, op.layer.id);\n const layers = [...doc.layers];\n layers.splice(op.index ?? layers.length, 0, op.layer);\n return {\n document: { ...doc, layers },\n inverse: { type: \"remove-layer\", id: op.layer.id },\n };\n};\n\nconst applyUpdateLayer = (\n doc: LineaDocument,\n op: Extract<Operation, { type: \"update-layer\" }>,\n): ApplyResult => {\n const prev = doc.layers.find((l) => l.id === op.layer.id);\n if (!prev)\n throw new OpError(\"unknown-layer\", `Layer ${op.layer.id} not found`);\n if (op.layer.name !== prev.name)\n assertLayerNameFree(doc, op.layer.name, op.layer.id);\n return {\n document: {\n ...doc,\n layers: doc.layers.map((l) => (l.id === op.layer.id ? op.layer : l)),\n },\n inverse: { type: \"update-layer\", layer: prev },\n };\n};\n\n/** How many objects, in every space, `match` accepts. */\nconst countObjects = (\n doc: LineaDocument,\n match: (o: ModelObject) => boolean,\n): number =>\n [doc.objects, ...doc.layouts.map((l) => l.objects)].reduce(\n (n, objs) => n + objs.filter(match).length,\n 0,\n );\n\nconst plural = (n: number, word: string) => `${n} ${word}${n === 1 ? \"\" : \"s\"}`;\n\nconst applyRemoveLayer = (\n doc: LineaDocument,\n op: Extract<Operation, { type: \"remove-layer\" }>,\n): ApplyResult => {\n const index = doc.layers.findIndex((l) => l.id === op.id);\n if (index === -1)\n throw new OpError(\"unknown-layer\", `Layer ${op.id} not found`);\n const prev = doc.layers[index];\n if (doc.layers.length === 1)\n throw new OpError(\"last-layer\", `Cannot remove the last layer`);\n if (doc.currentLayerId === op.id)\n throw new OpError(\n \"current-layer\",\n `Layer \"${prev.name}\" is the current layer — switch to another first`,\n );\n const users = countObjects(doc, (o) => o.layerId === op.id);\n if (users > 0)\n throw new OpError(\n \"layer-in-use\",\n `Layer \"${prev.name}\" still has ${plural(users, \"object\")} on it`,\n );\n return {\n document: { ...doc, layers: doc.layers.filter((l) => l.id !== op.id) },\n inverse: { type: \"add-layer\", layer: prev, index },\n };\n};\n\nconst applySetLayers = (\n doc: LineaDocument,\n op: Extract<Operation, { type: \"set-layers\" }>,\n): ApplyResult => {\n const ids = new Set(op.layers.map((l) => l.id));\n if (ids.size !== op.layers.length)\n throw new OpError(\"duplicate-id\", `Duplicate layer ids in set-layers`);\n if (!ids.has(doc.currentLayerId))\n throw new OpError(\n \"current-layer\",\n `set-layers would drop the current layer ${doc.currentLayerId}`,\n );\n const used = (objs: ModelObject[]) => objs.find((o) => !ids.has(o.layerId));\n const orphan =\n used(doc.objects) ?? doc.layouts.map((l) => used(l.objects)).find(Boolean);\n if (orphan)\n throw new OpError(\n \"layer-in-use\",\n `set-layers would orphan object ${orphan.id} (layer ${orphan.layerId})`,\n );\n return {\n document: { ...doc, layers: op.layers },\n inverse: { type: \"set-layers\", layers: doc.layers },\n };\n};\n\n/** Reorder an id-keyed collection to an explicit total order (same-set\n * validated: every current id exactly once, nothing added or dropped). */\nconst reorderById = <T extends { id: string }>(\n arr: T[],\n ids: string[],\n what: string,\n): T[] => {\n const byId = new Map(arr.map((x) => [x.id, x]));\n if (ids.length !== arr.length || new Set(ids).size !== ids.length)\n throw new OpError(\n \"invalid-reorder\",\n `Reorder must list every current ${what} id exactly once`,\n );\n return ids.map((id) => {\n const item = byId.get(id);\n if (!item) throw new OpError(\"invalid-reorder\", `Unknown ${what} id ${id}`);\n return item;\n });\n};\n\nconst applyReorderLayers = (\n doc: LineaDocument,\n op: Extract<Operation, { type: \"reorder-layers\" }>,\n): ApplyResult => ({\n document: { ...doc, layers: reorderById(doc.layers, op.ids, \"layer\") },\n inverse: { type: \"reorder-layers\", ids: doc.layers.map((l) => l.id) },\n});\n\nconst applySetCurrentLayer = (\n doc: LineaDocument,\n op: Extract<Operation, { type: \"set-current-layer\" }>,\n): ApplyResult => {\n if (!doc.layers.some((l) => l.id === op.id))\n throw new OpError(\"unknown-layer\", `Layer ${op.id} not found`);\n return {\n document: { ...doc, currentLayerId: op.id },\n inverse: { type: \"set-current-layer\", id: doc.currentLayerId },\n };\n};\n\n// --- document field ops ----------------------------------------------------\n\nconst applySetDocumentSettings = (\n doc: LineaDocument,\n op: Extract<Operation, { type: \"set-document-settings\" }>,\n): ApplyResult => ({\n document: { ...doc, settings: op.settings },\n inverse: { type: \"set-document-settings\", settings: doc.settings },\n});\n\nconst applySetDimStyles = (\n doc: LineaDocument,\n op: Extract<Operation, { type: \"set-dim-styles\" }>,\n): ApplyResult => ({\n document: { ...doc, dimStyles: op.dimStyles },\n inverse: { type: \"set-dim-styles\", dimStyles: doc.dimStyles },\n});\n\nconst applySetTextStyles = (\n doc: LineaDocument,\n op: Extract<Operation, { type: \"set-text-styles\" }>,\n): ApplyResult => ({\n document: { ...doc, textStyles: op.textStyles },\n inverse: { type: \"set-text-styles\", textStyles: doc.textStyles },\n});\n\n// Shared array plumbing for the granular text/dim style trios. Dangling\n// styleId references are LEGAL by design (they resolve to the first style),\n// so remove needs no in-use check — only the schema's min-1 invariant.\n\nconst addStyleIn = <T extends { id: string }>(\n arr: T[],\n style: T,\n index: number | undefined,\n): T[] => {\n if (arr.some((s) => s.id === style.id))\n throw new OpError(\"duplicate-id\", `Style ${style.id} already exists`);\n const next = [...arr];\n // Out-of-range indices clamp to append so a stale inverse still lands.\n next.splice(Math.min(index ?? next.length, next.length), 0, style);\n return next;\n};\n\nconst updateStyleIn = <T extends { id: string }>(\n arr: T[],\n style: T,\n): { next: T[]; prev: T } => {\n const prev = arr.find((s) => s.id === style.id);\n if (!prev) throw new OpError(\"unknown-style\", `Style ${style.id} not found`);\n return { next: arr.map((s) => (s.id === style.id ? style : s)), prev };\n};\n\nconst removeStyleIn = <T extends { id: string }>(\n arr: T[],\n id: string,\n): { next: T[]; prev: T; index: number } => {\n const index = arr.findIndex((s) => s.id === id);\n if (index === -1) throw new OpError(\"unknown-style\", `Style ${id} not found`);\n if (arr.length === 1)\n throw new OpError(\"last-style\", `Cannot remove the last style`);\n return { next: arr.filter((s) => s.id !== id), prev: arr[index], index };\n};\n\nconst applyAddTextStyle = (\n doc: LineaDocument,\n op: Extract<Operation, { type: \"add-text-style\" }>,\n): ApplyResult => ({\n document: {\n ...doc,\n textStyles: addStyleIn(doc.textStyles, op.style, op.index),\n },\n inverse: { type: \"remove-text-style\", id: op.style.id },\n});\n\nconst applyUpdateTextStyle = (\n doc: LineaDocument,\n op: Extract<Operation, { type: \"update-text-style\" }>,\n): ApplyResult => {\n const { next, prev } = updateStyleIn(doc.textStyles, op.style);\n return {\n document: { ...doc, textStyles: next },\n inverse: { type: \"update-text-style\", style: prev },\n };\n};\n\n/** Refuse removing a style objects resolve to — by `styleId`, or as the\n * first style that unstyled (and dangling) references fall back to. */\nconst assertStyleUnused = (users: number, name: string): void => {\n if (users > 0)\n throw new OpError(\n \"style-in-use\",\n `Style \"${name}\" is used by ${plural(users, \"object\")} — restyle them first`,\n );\n};\n\n/** Objects (every space) whose text style resolves to `id`. */\nexport const textStyleUsers = (doc: LineaDocument, id: string): number =>\n countObjects(doc, (o) => {\n if (o.type === \"text\") return textStyleFor(o, doc.textStyles).id === id;\n if (o.type !== \"table\") return false;\n return (\n textStyleFor(o, doc.textStyles).id === id ||\n o.cells.some((row) => row.some((c) => c.styleId === id))\n );\n });\n\nconst applyRemoveTextStyle = (\n doc: LineaDocument,\n op: Extract<Operation, { type: \"remove-text-style\" }>,\n): ApplyResult => {\n const { next, prev, index } = removeStyleIn(doc.textStyles, op.id);\n assertStyleUnused(textStyleUsers(doc, op.id), prev.name);\n return {\n document: { ...doc, textStyles: next },\n inverse: { type: \"add-text-style\", style: prev, index },\n };\n};\n\nconst applyReorderTextStyles = (\n doc: LineaDocument,\n op: Extract<Operation, { type: \"reorder-text-styles\" }>,\n): ApplyResult => ({\n document: {\n ...doc,\n textStyles: reorderById(doc.textStyles, op.ids, \"text style\"),\n },\n inverse: {\n type: \"reorder-text-styles\",\n ids: doc.textStyles.map((s) => s.id),\n },\n});\n\n// Name-keyed resource trios (line types, hatch patterns): names compare\n// case-insensitively like DXF table names. Dangling names are legal (they\n// fall back to the catalogue or continuous), so remove needs no in-use check.\nconst namedIndex = <T extends { name: string }>(\n arr: readonly T[],\n name: string,\n key: (n: string) => string,\n): number => {\n const k = key(name);\n return arr.findIndex((t) => key(t.name) === k);\n};\nconst addNamedIn = <T extends { name: string }>(\n arr: readonly T[],\n item: T,\n index: number | undefined,\n key: (n: string) => string,\n what: string,\n): T[] => {\n if (namedIndex(arr, item.name, key) !== -1)\n throw new OpError(\n \"duplicate-name\",\n `A ${what} named \"${item.name}\" already exists`,\n );\n const at = index === undefined ? arr.length : Math.min(index, arr.length);\n return [...arr.slice(0, at), item, ...arr.slice(at)];\n};\nconst updateNamedIn = <T extends { name: string }>(\n arr: readonly T[],\n item: T,\n key: (n: string) => string,\n what: string,\n): { next: T[]; prev: T } => {\n const i = namedIndex(arr, item.name, key);\n if (i === -1)\n throw new OpError(\"not-found\", `No ${what} named \"${item.name}\"`);\n const next = [...arr];\n next[i] = item;\n return { next, prev: arr[i] };\n};\nconst removeNamedIn = <T extends { name: string }>(\n arr: readonly T[],\n name: string,\n key: (n: string) => string,\n what: string,\n): { next: T[]; prev: T; index: number } => {\n const i = namedIndex(arr, name, key);\n if (i === -1) throw new OpError(\"not-found\", `No ${what} named \"${name}\"`);\n return { next: arr.filter((_, j) => j !== i), prev: arr[i], index: i };\n};\n\nconst applyAddLineType = (\n doc: LineaDocument,\n op: Extract<Operation, { type: \"add-line-type\" }>,\n): ApplyResult => ({\n document: {\n ...doc,\n lineTypes: addNamedIn(\n doc.lineTypes,\n op.lineType,\n op.index,\n lineTypeKey,\n \"line type\",\n ),\n },\n inverse: { type: \"remove-line-type\", name: op.lineType.name },\n});\nconst applyUpdateLineType = (\n doc: LineaDocument,\n op: Extract<Operation, { type: \"update-line-type\" }>,\n): ApplyResult => {\n const { next, prev } = updateNamedIn(\n doc.lineTypes,\n op.lineType,\n lineTypeKey,\n \"line type\",\n );\n return {\n document: { ...doc, lineTypes: next },\n inverse: { type: \"update-line-type\", lineType: prev },\n };\n};\nconst applyRemoveLineType = (\n doc: LineaDocument,\n op: Extract<Operation, { type: \"remove-line-type\" }>,\n): ApplyResult => {\n const { next, prev, index } = removeNamedIn(\n doc.lineTypes,\n op.name,\n lineTypeKey,\n \"line type\",\n );\n return {\n document: { ...doc, lineTypes: next },\n inverse: { type: \"add-line-type\", lineType: prev, index },\n };\n};\n\nconst applyAddHatchPattern = (\n doc: LineaDocument,\n op: Extract<Operation, { type: \"add-hatch-pattern\" }>,\n): ApplyResult => ({\n document: {\n ...doc,\n hatchPatterns: addNamedIn(\n doc.hatchPatterns,\n op.hatchPattern,\n op.index,\n hatchPatternKey,\n \"hatch pattern\",\n ),\n },\n inverse: { type: \"remove-hatch-pattern\", name: op.hatchPattern.name },\n});\nconst applyUpdateHatchPattern = (\n doc: LineaDocument,\n op: Extract<Operation, { type: \"update-hatch-pattern\" }>,\n): ApplyResult => {\n const { next, prev } = updateNamedIn(\n doc.hatchPatterns,\n op.hatchPattern,\n hatchPatternKey,\n \"hatch pattern\",\n );\n return {\n document: { ...doc, hatchPatterns: next },\n inverse: { type: \"update-hatch-pattern\", hatchPattern: prev },\n };\n};\nconst applyRemoveHatchPattern = (\n doc: LineaDocument,\n op: Extract<Operation, { type: \"remove-hatch-pattern\" }>,\n): ApplyResult => {\n const { next, prev, index } = removeNamedIn(\n doc.hatchPatterns,\n op.name,\n hatchPatternKey,\n \"hatch pattern\",\n );\n return {\n document: { ...doc, hatchPatterns: next },\n inverse: { type: \"add-hatch-pattern\", hatchPattern: prev, index },\n };\n};\n\nconst applyReorderDimStyles = (\n doc: LineaDocument,\n op: Extract<Operation, { type: \"reorder-dim-styles\" }>,\n): ApplyResult => ({\n document: {\n ...doc,\n dimStyles: reorderById(doc.dimStyles, op.ids, \"dim style\"),\n },\n inverse: { type: \"reorder-dim-styles\", ids: doc.dimStyles.map((s) => s.id) },\n});\n\nconst applyAddDimStyle = (\n doc: LineaDocument,\n op: Extract<Operation, { type: \"add-dim-style\" }>,\n): ApplyResult => ({\n document: {\n ...doc,\n dimStyles: addStyleIn(doc.dimStyles, op.style, op.index),\n },\n inverse: { type: \"remove-dim-style\", id: op.style.id },\n});\n\nconst applyUpdateDimStyle = (\n doc: LineaDocument,\n op: Extract<Operation, { type: \"update-dim-style\" }>,\n): ApplyResult => {\n const { next, prev } = updateStyleIn(doc.dimStyles, op.style);\n return {\n document: { ...doc, dimStyles: next },\n inverse: { type: \"update-dim-style\", style: prev },\n };\n};\n\n/** Dimensions (every space) whose dim style resolves to `id`. */\nexport const dimStyleUsers = (doc: LineaDocument, id: string): number =>\n countObjects(\n doc,\n (o) => o.type === \"dimension\" && dimStyleFor(o, doc.dimStyles).id === id,\n );\n\nconst applyRemoveDimStyle = (\n doc: LineaDocument,\n op: Extract<Operation, { type: \"remove-dim-style\" }>,\n): ApplyResult => {\n const { next, prev, index } = removeStyleIn(doc.dimStyles, op.id);\n assertStyleUnused(dimStyleUsers(doc, op.id), prev.name);\n return {\n document: { ...doc, dimStyles: next },\n inverse: { type: \"add-dim-style\", style: prev, index },\n };\n};\n\nconst applySetDocumentCommands = (\n doc: LineaDocument,\n op: Extract<Operation, { type: \"set-document-commands\" }>,\n): ApplyResult => ({\n document: { ...doc, commands: op.commands },\n inverse: { type: \"set-document-commands\", commands: doc.commands },\n});\n\nconst applySetBlockDefinitions = (\n doc: LineaDocument,\n op: Extract<Operation, { type: \"set-block-definitions\" }>,\n): ApplyResult => ({\n document: { ...doc, blockDefinitions: op.blockDefinitions },\n inverse: {\n type: \"set-block-definitions\",\n blockDefinitions: doc.blockDefinitions,\n },\n});\n\n// Shared array plumbing for the content-addressed module trios (block\n// definitions and document commands — both opaque source-string arrays; see\n// the addressing rationale in types.ts).\n\nconst addModuleIn = (\n arr: string[],\n source: string,\n index: number | undefined,\n what: string,\n): string[] => {\n if (arr.includes(source))\n throw new OpError(\n \"duplicate-id\",\n `This exact ${what} module is already in the document`,\n );\n const next = [...arr];\n next.splice(Math.min(index ?? next.length, next.length), 0, source);\n return next;\n};\n\nconst updateModuleIn = (\n arr: string[],\n prevSource: string,\n source: string,\n what: string,\n): string[] => {\n const at = arr.indexOf(prevSource);\n if (at === -1)\n throw new OpError(\n \"unknown-module\",\n `The ${what} module targeted by this update is not in the document (stale source)`,\n );\n if (source !== prevSource && arr.includes(source))\n throw new OpError(\n \"duplicate-id\",\n `This exact ${what} module is already in the document`,\n );\n return arr.map((s, i) => (i === at ? source : s));\n};\n\nconst removeModuleIn = (\n arr: string[],\n source: string,\n what: string,\n): { next: string[]; index: number } => {\n const index = arr.indexOf(source);\n if (index === -1)\n throw new OpError(\n \"unknown-module\",\n `The ${what} module to remove is not in the document (stale source)`,\n );\n return { next: arr.filter((_, i) => i !== index), index };\n};\n\n/** Same-multiset reorder for module sources: identical strings are\n * interchangeable, so sorted-equality is an exact check. */\nconst reorderModulesIn = (\n arr: string[],\n sources: string[],\n what: string,\n): string[] => {\n if (\n sources.length !== arr.length ||\n [...sources].sort().join(\"\") !== [...arr].sort().join(\"\")\n )\n throw new OpError(\n \"invalid-reorder\",\n `Reorder must list every current ${what} module source exactly once (stale set)`,\n );\n return sources;\n};\n\nconst applyReorderBlockDefinitions = (\n doc: LineaDocument,\n op: Extract<Operation, { type: \"reorder-block-definitions\" }>,\n): ApplyResult => ({\n document: {\n ...doc,\n blockDefinitions: reorderModulesIn(\n doc.blockDefinitions,\n op.sources,\n \"block\",\n ),\n },\n inverse: {\n type: \"reorder-block-definitions\",\n sources: doc.blockDefinitions,\n },\n});\n\nconst applyReorderDocumentCommands = (\n doc: LineaDocument,\n op: Extract<Operation, { type: \"reorder-document-commands\" }>,\n): ApplyResult => ({\n document: {\n ...doc,\n commands: reorderModulesIn(doc.commands, op.sources, \"command\"),\n },\n inverse: { type: \"reorder-document-commands\", sources: doc.commands },\n});\n\nconst applyAddBlockDefinition = (\n doc: LineaDocument,\n op: Extract<Operation, { type: \"add-block-definition\" }>,\n): ApplyResult => ({\n document: {\n ...doc,\n blockDefinitions: addModuleIn(\n doc.blockDefinitions,\n op.source,\n op.index,\n \"block\",\n ),\n },\n inverse: { type: \"remove-block-definition\", source: op.source },\n});\n\nconst applyUpdateBlockDefinition = (\n doc: LineaDocument,\n op: Extract<Operation, { type: \"update-block-definition\" }>,\n): ApplyResult => ({\n document: {\n ...doc,\n blockDefinitions: updateModuleIn(\n doc.blockDefinitions,\n op.prevSource,\n op.source,\n \"block\",\n ),\n },\n inverse: {\n type: \"update-block-definition\",\n prevSource: op.source,\n source: op.prevSource,\n },\n});\n\n/** Why a block module can't go: placed instances (model or any layout) or\n * another module declaring it as a dependency — the Library's rule, here so\n * scripts, agents and the SDK can't orphan instances either. A module whose\n * id another module in the document still defines is free to go. */\nconst assertBlockRemovable = (doc: LineaDocument, source: string): void => {\n const id = blockScriptId(source);\n if (id === undefined) return;\n const others = doc.blockDefinitions.filter((s) => s !== source);\n if (others.some((s) => blockScriptId(s) === id)) return;\n const placed = countObjects(\n doc,\n (o) => o.type === \"block\" && o.definitionId === id,\n );\n if (placed > 0)\n throw new OpError(\n \"definition-in-use\",\n `Block \"${id}\" still has ${plural(placed, \"placed instance\")} — explode or delete them first`,\n );\n for (const s of others) {\n const m = getBlockMetaResult(s);\n if (m.ok && (m.meta.dependencies ?? []).includes(id))\n throw new OpError(\n \"definition-in-use\",\n `Block \"${id}\" is required by block \"${m.meta.id}\" (its dependencies)`,\n );\n }\n};\n\nconst applyRemoveBlockDefinition = (\n doc: LineaDocument,\n op: Extract<Operation, { type: \"remove-block-definition\" }>,\n): ApplyResult => {\n assertBlockRemovable(doc, op.source);\n const { next, index } = removeModuleIn(\n doc.blockDefinitions,\n op.source,\n \"block\",\n );\n return {\n document: { ...doc, blockDefinitions: next },\n inverse: { type: \"add-block-definition\", source: op.source, index },\n };\n};\n\nconst applyAddDocumentCommand = (\n doc: LineaDocument,\n op: Extract<Operation, { type: \"add-document-command\" }>,\n): ApplyResult => ({\n document: {\n ...doc,\n commands: addModuleIn(doc.commands, op.source, op.index, \"command\"),\n },\n inverse: { type: \"remove-document-command\", source: op.source },\n});\n\nconst applyUpdateDocumentCommand = (\n doc: LineaDocument,\n op: Extract<Operation, { type: \"update-document-command\" }>,\n): ApplyResult => ({\n document: {\n ...doc,\n commands: updateModuleIn(doc.commands, op.prevSource, op.source, \"command\"),\n },\n inverse: {\n type: \"update-document-command\",\n prevSource: op.source,\n source: op.prevSource,\n },\n});\n\nconst applyRemoveDocumentCommand = (\n doc: LineaDocument,\n op: Extract<Operation, { type: \"remove-document-command\" }>,\n): ApplyResult => {\n const { next, index } = removeModuleIn(doc.commands, op.source, \"command\");\n return {\n document: { ...doc, commands: next },\n inverse: { type: \"add-document-command\", source: op.source, index },\n };\n};\n\n// --- asset ops ---------------------------------------------------------------\n\nconst applySetAsset = (\n doc: LineaDocument,\n op: Extract<Operation, { type: \"set-asset\" }>,\n): ApplyResult => {\n const prev = doc.assets[op.id];\n return {\n document: { ...doc, assets: { ...doc.assets, [op.id]: op.dataUrl } },\n inverse:\n prev !== undefined\n ? { type: \"set-asset\", id: op.id, dataUrl: prev }\n : { type: \"remove-asset\", id: op.id },\n };\n};\n\nconst assetInUse = (doc: LineaDocument, id: string): boolean => {\n const used = (objs: ModelObject[]) =>\n objs.some((o) => embeddedAssetId(o) === id);\n return used(doc.objects) || doc.layouts.some((l) => used(l.objects));\n};\n\nconst applyRemoveAsset = (\n doc: LineaDocument,\n op: Extract<Operation, { type: \"remove-asset\" }>,\n): ApplyResult => {\n const prev = doc.assets[op.id];\n if (prev === undefined)\n throw new OpError(\"unknown-asset\", `Asset ${op.id} not found`);\n if (assetInUse(doc, op.id))\n throw new OpError(\n \"asset-in-use\",\n `Asset ${op.id} is still referenced by an image object`,\n );\n const assets = { ...doc.assets };\n delete assets[op.id];\n return {\n document: { ...doc, assets },\n inverse: { type: \"set-asset\", id: op.id, dataUrl: prev },\n };\n};\n\n// --- layout ops ------------------------------------------------------------\n\nconst applyAddLayout = (\n doc: LineaDocument,\n op: Extract<Operation, { type: \"add-layout\" }>,\n): ApplyResult => {\n if (doc.layouts.some((l) => l.id === op.layout.id))\n throw new OpError(\"duplicate-layout\", `Layout ${op.layout.id} exists`);\n const layouts = [...doc.layouts];\n layouts.splice(op.index ?? layouts.length, 0, op.layout);\n return {\n document: { ...doc, layouts },\n inverse: { type: \"remove-layout\", id: op.layout.id },\n };\n};\n\nconst applyRemoveLayout = (\n doc: LineaDocument,\n op: Extract<Operation, { type: \"remove-layout\" }>,\n): ApplyResult => {\n const index = doc.layouts.findIndex((l) => l.id === op.id);\n if (index === -1)\n throw new OpError(\"unknown-layout\", `Layout ${op.id} not found`);\n const prev = doc.layouts[index];\n return {\n document: { ...doc, layouts: doc.layouts.filter((l) => l.id !== op.id) },\n inverse: { type: \"add-layout\", layout: prev, index },\n };\n};\n\nconst applyReorderLayouts = (\n doc: LineaDocument,\n op: Extract<Operation, { type: \"reorder-layouts\" }>,\n): ApplyResult => ({\n document: { ...doc, layouts: reorderById(doc.layouts, op.ids, \"layout\") },\n inverse: { type: \"reorder-layouts\", ids: doc.layouts.map((l) => l.id) },\n});\n\nconst applyUpdateLayoutMeta = (\n doc: LineaDocument,\n op: Extract<Operation, { type: \"update-layout-meta\" }>,\n): ApplyResult => {\n const prev = doc.layouts.find((l) => l.id === op.id);\n if (!prev) throw new OpError(\"unknown-layout\", `Layout ${op.id} not found`);\n const next: PaperLayout = {\n ...prev,\n ...(op.name !== undefined ? { name: op.name } : {}),\n ...(op.sheet !== undefined ? { sheet: op.sheet } : {}),\n ...(op.printPalette !== undefined ? { printPalette: op.printPalette } : {}),\n };\n return {\n document: {\n ...doc,\n layouts: doc.layouts.map((l) => (l.id === op.id ? next : l)),\n },\n inverse: {\n type: \"update-layout-meta\",\n id: op.id,\n name: prev.name,\n sheet: prev.sheet,\n printPalette: prev.printPalette,\n },\n };\n};\n\nconst applyUpdateLayouts = (\n doc: LineaDocument,\n op: Extract<Operation, { type: \"update-layouts\" }>,\n): ApplyResult => {\n const previous: PaperLayout[] = [];\n for (const layout of op.layouts) {\n const prev = doc.layouts.find((l) => l.id === layout.id);\n if (!prev)\n throw new OpError(\"unknown-layout\", `Layout ${layout.id} not found`);\n previous.push(prev);\n for (const obj of layout.objects)\n assertObjectRefs(doc, obj, { layoutId: layout.id });\n }\n const byId = new Map(op.layouts.map((l) => [l.id, l]));\n return {\n document: {\n ...doc,\n layouts: doc.layouts.map((l) => byId.get(l.id) ?? l),\n },\n inverse: { type: \"update-layouts\", layouts: previous },\n };\n};\n\n/**\n * Validate + apply one operation against full document state. Returns the\n * next document and the inverse op. Throws `OpError` on any integrity\n * violation, leaving `doc` untouched (it is never mutated).\n */\nexport const applyOperation = (\n doc: LineaDocument,\n op: Operation,\n): ApplyResult => {\n switch (op.type) {\n case \"add-objects\":\n return applyAddObjects(doc, op);\n case \"update-objects\":\n return applyUpdateObjects(doc, op);\n case \"remove-objects\":\n return applyRemoveObjects(doc, op);\n case \"reorder-objects\":\n return applyReorderObjects(doc, op);\n case \"add-layer\":\n return applyAddLayer(doc, op);\n case \"update-layer\":\n return applyUpdateLayer(doc, op);\n case \"remove-layer\":\n return applyRemoveLayer(doc, op);\n case \"set-layers\":\n return applySetLayers(doc, op);\n case \"reorder-layers\":\n return applyReorderLayers(doc, op);\n case \"set-current-layer\":\n return applySetCurrentLayer(doc, op);\n case \"set-document-settings\":\n return applySetDocumentSettings(doc, op);\n case \"set-dim-styles\":\n return applySetDimStyles(doc, op);\n case \"add-dim-style\":\n return applyAddDimStyle(doc, op);\n case \"update-dim-style\":\n return applyUpdateDimStyle(doc, op);\n case \"remove-dim-style\":\n return applyRemoveDimStyle(doc, op);\n case \"reorder-dim-styles\":\n return applyReorderDimStyles(doc, op);\n case \"set-text-styles\":\n return applySetTextStyles(doc, op);\n case \"add-text-style\":\n return applyAddTextStyle(doc, op);\n case \"update-text-style\":\n return applyUpdateTextStyle(doc, op);\n case \"remove-text-style\":\n return applyRemoveTextStyle(doc, op);\n case \"reorder-text-styles\":\n return applyReorderTextStyles(doc, op);\n case \"add-line-type\":\n return applyAddLineType(doc, op);\n case \"update-line-type\":\n return applyUpdateLineType(doc, op);\n case \"remove-line-type\":\n return applyRemoveLineType(doc, op);\n case \"add-hatch-pattern\":\n return applyAddHatchPattern(doc, op);\n case \"update-hatch-pattern\":\n return applyUpdateHatchPattern(doc, op);\n case \"remove-hatch-pattern\":\n return applyRemoveHatchPattern(doc, op);\n case \"set-block-definitions\":\n return applySetBlockDefinitions(doc, op);\n case \"add-block-definition\":\n return applyAddBlockDefinition(doc, op);\n case \"update-block-definition\":\n return applyUpdateBlockDefinition(doc, op);\n case \"remove-block-definition\":\n return applyRemoveBlockDefinition(doc, op);\n case \"reorder-block-definitions\":\n return applyReorderBlockDefinitions(doc, op);\n case \"set-document-commands\":\n return applySetDocumentCommands(doc, op);\n case \"add-document-command\":\n return applyAddDocumentCommand(doc, op);\n case \"update-document-command\":\n return applyUpdateDocumentCommand(doc, op);\n case \"remove-document-command\":\n return applyRemoveDocumentCommand(doc, op);\n case \"reorder-document-commands\":\n return applyReorderDocumentCommands(doc, op);\n case \"set-asset\":\n return applySetAsset(doc, op);\n case \"remove-asset\":\n return applyRemoveAsset(doc, op);\n case \"add-layout\":\n return applyAddLayout(doc, op);\n case \"remove-layout\":\n return applyRemoveLayout(doc, op);\n case \"reorder-layouts\":\n return applyReorderLayouts(doc, op);\n case \"update-layout-meta\":\n return applyUpdateLayoutMeta(doc, op);\n case \"update-layouts\":\n return applyUpdateLayouts(doc, op);\n }\n};\n\n/** Which object ids an op invalidates (`null` = everything; `[]` = nothing). */\nexport const invalidationIds = (op: Operation): string[] | null => {\n switch (op.type) {\n case \"add-objects\":\n case \"update-objects\":\n return op.objects.map((o) => o.id);\n case \"remove-objects\":\n return op.ids;\n case \"set-current-layer\":\n case \"set-document-settings\":\n case \"set-document-commands\":\n case \"add-document-command\":\n case \"update-document-command\":\n case \"remove-document-command\":\n case \"reorder-document-commands\":\n return []; // no rendered change\n case \"add-layer\": // fresh id — validation guarantees nothing references it\n case \"remove-layer\": // validation guarantees the layer had no members\n case \"reorder-layers\": // layer order is panel display order only\n case \"reorder-block-definitions\": // library display order only\n case \"reorder-layouts\": // PDF page order — no per-object cache depends on it\n return [];\n case \"reorder-objects\":\n // Z-order only: per-object caches (snap entries, block eval) don't\n // depend on order; repaint comes from the document change itself.\n return [];\n default:\n // layer/style/blockDefs/layout changes affect everything. Style ADDS\n // included: a dangling styleId legally resolves to the first style, so\n // adding the missing style can restyle existing text/dimensions.\n return null;\n }\n};\n","// DocumentKernel — the stateful wrapper around applyOperation. Holds a\n// LineaDocument plus the id/type indexes for the active space, fires cache\n// invalidation (block eval + any subscriber), and returns inverse ops. This\n// is what the editor's modelStore will delegate to; the cloud server uses the\n// pure applyOperation directly. See docs/kernel-op-layer.md.\n\nimport type { Layer, LineaDocument } from \"../model/document\";\nimport type { ModelObject, ModelObjectType } from \"../model/objects\";\nimport {\n expandWithBlockDependents,\n invalidateBlockCache,\n} from \"../extensions/evalBlock\";\nimport { applyOperation, invalidationIds } from \"./apply\";\nimport type { OpSpace, Operation } from \"./types\";\n\nexport type InvalidationListener = (ids: string[] | null) => void;\n\nexport class DocumentKernel {\n private doc: LineaDocument;\n private activeSpace: OpSpace = \"model\";\n private idIndex = new Map<string, ModelObject>();\n private typeIndex = new Map<ModelObjectType, Set<string>>();\n private listeners = new Set<InvalidationListener>();\n\n constructor(doc: LineaDocument) {\n this.doc = doc;\n this.rebuildIndexes();\n }\n\n get document(): LineaDocument {\n return this.doc;\n }\n\n get space(): OpSpace {\n return this.activeSpace;\n }\n\n /** Replace the whole document (file open / new). Rebuilds, invalidates all. */\n load(doc: LineaDocument): void {\n this.doc = doc;\n this.rebuildIndexes();\n this.invalidate(null);\n }\n\n /** Switch the active space the indexes target (model or a layout). */\n setActiveSpace(space: OpSpace): void {\n this.activeSpace = space;\n this.rebuildIndexes();\n this.invalidate(null);\n }\n\n onInvalidate(fn: InvalidationListener): () => void {\n this.listeners.add(fn);\n return () => this.listeners.delete(fn);\n }\n\n getObject(id: string): ModelObject | undefined {\n return this.idIndex.get(id);\n }\n\n getObjectsByType<T extends ModelObjectType>(\n type: T,\n ): Extract<ModelObject, { type: T }>[] {\n const ids = this.typeIndex.get(type);\n if (!ids) return [];\n const out: Extract<ModelObject, { type: T }>[] = [];\n for (const id of ids) {\n const obj = this.idIndex.get(id);\n if (obj) out.push(obj as Extract<ModelObject, { type: T }>);\n }\n return out;\n }\n\n getLayer(id: string): Layer | undefined {\n return this.doc.layers.find((l) => l.id === id);\n }\n\n /** Objects of the active space (the index source). */\n activeObjects(): ModelObject[] {\n const space = this.activeSpace;\n if (space === \"model\") return this.doc.objects;\n return this.doc.layouts.find((l) => l.id === space.layoutId)?.objects ?? [];\n }\n\n /**\n * Validate + apply one op, refresh indexes/caches, return the INVERSE op.\n * Throws `OpError` (document untouched) on an integrity violation.\n */\n apply(op: Operation): Operation {\n const { document, inverse } = applyOperation(this.doc, op);\n this.doc = document;\n this.reindexForOp(op);\n this.invalidate(invalidationIds(op));\n return inverse;\n }\n\n /**\n * Apply a batch: validates + applies in order; on any `OpError` rolls the\n * document back to the pre-batch snapshot and rethrows (nothing partially\n * applied). Returns inverse ops in REVERSE order, so applying them in turn\n * undoes the whole batch.\n */\n applyMany(ops: Operation[]): Operation[] {\n const snapshot = this.doc;\n const inverses: Operation[] = [];\n try {\n for (const op of ops) inverses.push(this.apply(op));\n } catch (e) {\n this.doc = snapshot;\n this.rebuildIndexes();\n this.invalidate(null);\n throw e;\n }\n return inverses.reverse();\n }\n\n private rebuildIndexes(): void {\n this.idIndex.clear();\n this.typeIndex.clear();\n for (const obj of this.activeObjects()) this.indexAdd(obj);\n }\n\n private indexAdd(obj: ModelObject): void {\n this.idIndex.set(obj.id, obj);\n let bucket = this.typeIndex.get(obj.type);\n if (!bucket) {\n bucket = new Set();\n this.typeIndex.set(obj.type, bucket);\n }\n bucket.add(obj.id);\n }\n\n private indexRemoveById(id: string): void {\n const prev = this.idIndex.get(id);\n if (!prev) return;\n this.idIndex.delete(id);\n this.typeIndex.get(prev.type)?.delete(id);\n }\n\n private opTargetsActiveSpace(op: Operation): boolean {\n if (!(\"space\" in op)) return false;\n const s = op.space;\n return s === \"model\"\n ? this.activeSpace === \"model\"\n : this.activeSpace !== \"model\" &&\n this.activeSpace.layoutId === s.layoutId;\n }\n\n /**\n * Incrementally maintain the active-space index after an op — O(changed)\n * for object ops (the interactive hot path) rather than a full rebuild.\n */\n private reindexForOp(op: Operation): void {\n switch (op.type) {\n case \"add-objects\":\n if (this.opTargetsActiveSpace(op))\n for (const o of op.objects) this.indexAdd(o);\n return;\n case \"remove-objects\":\n if (this.opTargetsActiveSpace(op))\n for (const id of op.ids) this.indexRemoveById(id);\n return;\n case \"update-objects\":\n if (this.opTargetsActiveSpace(op))\n for (const o of op.objects) {\n this.indexRemoveById(o.id);\n this.indexAdd(o);\n }\n return;\n case \"reorder-objects\":\n // Same object set, new order — the indexes are order-independent.\n return;\n case \"add-layout\":\n case \"remove-layout\":\n case \"update-layouts\":\n // Could change which objects the active space exposes (e.g. the\n // active layout was removed or its content replaced) — rebuild.\n this.rebuildIndexes();\n return;\n default:\n // layer / dim-style / name / current-layer / block-defs / layout-meta:\n // no change to the active-space object set.\n return;\n }\n }\n\n private invalidate(ids: string[] | null): void {\n // Instances whose inputs reference a mutated object are stale too —\n // expand BEFORE dropping caches so listeners see the same id list.\n const expanded = ids === null ? null : expandWithBlockDependents(ids);\n invalidateBlockCache(expanded);\n for (const fn of this.listeners) fn(expanded);\n }\n}\n","// The in-process `Drawing` — its ONE implementation: mutations mapped 1:1 to\n// validated ops, reads and renders through the headless paint paths. The\n// document lives in a DocumentKernel with op-based undo stacks, or — given\n// DrawingHooks — in a host's stores (the editor's subclass routes ops through\n// its mutation funnel and history). Browser-safe (no Node imports); hosts\n// subclass it for their I/O: the SDK (files, PNG/PDF, imports), the editor\n// (PDF/PNG). Ergonomics only (layer-by-name, array points via the schema,\n// batching) — never new semantics.\n\nimport { lineTypeKey, LineTypeSchema, type LineType } from \"../model/lineTypes\";\nimport {\n hatchPatternKey,\n HatchPatternSchema,\n type DocumentHatchPattern,\n} from \"../model/hatchPatterns\";\nimport { z } from \"zod\";\nimport { arcSweep, distToArc } from \"../geometry/arcs\";\nimport {\n boundsIntersect,\n emptyBounds,\n isEmptyBounds,\n unionBounds,\n type AABB,\n} from \"../geometry/bounds\";\nimport { closestPointOnSegment } from \"../geometry/line\";\nimport { chainLength, hatchArea, polylineArea } from \"../geometry/polyline\";\nimport { dist, type Vec2 } from \"../geometry/vec2\";\nimport {\n bytesToDataUrl,\n embeddedAssetId,\n hashAsset,\n} from \"../model/assets\";\nimport { Vec2Schema } from \"../model/common\";\nimport {\n DEFAULT_DOCUMENT_NAME,\n LayerSchema,\n type Layer,\n type LineaDocument,\n} from \"../model/document\";\nimport {\n documentObjectResolver,\n resolveDocumentObject,\n} from \"../model/objectLookup\";\nimport {\n assertKnownStyleOverrideKeys,\n DimStyleSchema,\n ModelObjectSchema,\n TextStyleSchema,\n type DimStyle,\n type ModelObject,\n type Reference,\n type TextStyle,\n} from \"../model/objects\";\nimport {\n dimensionRawToLabels,\n dimensionRawToOffset,\n} from \"../model/migrations\";\nimport type { ReferenceContent } from \"../reference/reference\";\nimport {\n PaperLayoutSchema,\n resolveSheetSize,\n sheetOrientation,\n type PaperLayout,\n} from \"../model/paperLayout\";\nimport { parseScale } from \"../model/scale\";\nimport { documentPaintResources } from \"../paint/painters\";\nimport { approximateTextMeasurer } from \"../paint/textMeasurer\";\nimport type { TextMeasurer } from \"../paint/textMetrics\";\nimport { buildSnapEntry, type SnapGeometryContext } from \"../snap/buildEntry\";\nimport type { SnapCacheEntry } from \"../snap/types\";\nimport { renderLayoutToSvg, renderModelToSvg } from \"../export/svg/renderSvg\";\nimport { dwgToDxf, dxfToDwg, type DwgVersion } from \"../dwg\";\nimport { dxfToModel } from \"../import/dxf/importDxf\";\nimport { dxfImportContextOf, dxfImportOps } from \"../import/dxf/importPlan\";\nimport { pdfToModel } from \"../import/pdf/importPdf\";\nimport { documentToJson } from \"../serialize\";\nimport {\n mirrorObject,\n remapBlockInputRefs,\n rotateObject,\n scaleObjectUniform,\n translateObject,\n} from \"../transform\";\nimport { listBlockMeta, type BlockMeta } from \"../extensions/evalBlock\";\nimport {\n listCommandMeta,\n mergeCommandModules,\n type CommandMeta,\n} from \"../extensions/commandModules\";\nimport { mergeBlockModules } from \"../extensions/scriptModules\";\nimport {\n MarketplaceClient,\n MarketplaceConfigSchema,\n marketplaceInfo,\n marketplaceKey,\n marketplaceLabel,\n matchesMarketplace,\n normalizeMarketplaces,\n type MarketplaceConfig,\n type MarketplaceHit,\n type MarketplaceInfo,\n type MarketplaceIO,\n type MarketplaceQuery,\n} from \"../marketplace/catalog\";\nimport { ensureScriptTranspiler } from \"../extensions/scriptRuntime\";\nimport {\n diffDimStyleOps,\n diffModuleOps,\n diffTextStyleOps,\n} from \"../operations/diff\";\nimport { DocumentKernel } from \"../operations/kernel\";\nimport {\n parseOperations,\n type Operation,\n type OpSpace,\n type ReorderPlacement,\n} from \"../operations/types\";\nimport type {\n AddOptions,\n DocumentSummary,\n Drawing,\n LayerInfo,\n LayoutOptions,\n LayoutPatch,\n Measurement,\n MergeReport,\n ModelObjectInput,\n PointInput,\n ObjectQuery,\n RenderPdfOptions,\n RenderSvgOptions,\n} from \"./types\";\n\nconst toVec = (p: PointInput): Vec2 => Vec2Schema.parse(p);\n\n/** Zod issues → one readable error, prefixed with the failing call/object. */\nconst wrapZod = (e: unknown, context: string): Error => {\n if (!(e instanceof z.ZodError))\n return e instanceof Error ? e : new Error(String(e));\n return new Error(`${context}: ${z.prettifyError(e)}`);\n};\n\nexport interface DxfImportOptions {\n /** mm per drawing unit; overrides the file's $INSUNITS header. */\n unitOverride?: number;\n}\n\nexport interface DxfImportReport {\n objects: number;\n layers: number;\n layouts: number;\n objectIds: string[];\n layoutIds: string[];\n /** `SOURCE→what` → entities imported as an approximation. */\n degraded: Record<string, number>;\n /** Entity type or reason → entities that produced nothing. */\n skipped: Record<string, number>;\n /** Text / dimension styles the file's STYLE / DIMSTYLE tables added\n * (styles matching an existing one by name and values are reused). */\n textStyles: number;\n dimStyles: number;\n /** Block definitions generated for the file's INSERTs (uniform-scale\n * inserts become instances of them). */\n blockDefinitions: number;\n /** Line type / hatch pattern definitions the file added (LTYPE table\n * entries the catalogue lacks; HATCH definition lines). */\n lineTypes: number;\n hatchPatterns: number;\n}\n\nexport interface PdfImportReport {\n objects: number;\n pageCount: number;\n objectIds: string[];\n}\n\nexport interface PdfImportOptions {\n /** \"vectors\" (default): lines and text runs. \"image\": the PDF embedded\n * and every page placed as a raster reference at true page scale — a host\n * capability (`rasterizePdf`, for the page sizes), refused where it is\n * missing. */\n as?: \"vectors\" | \"image\";\n /** Bottom-left corner of the first page (image mode; default 0,0). Pages\n * line up to the right. */\n origin?: PointInput;\n}\n\n/** One PDF page rasterized: PNG pixels plus its true size in mm. */\nexport interface RasterPdfPage {\n dataUrl: string;\n widthMm: number;\n heightMm: number;\n}\n\n/** An embedded image asset as `listAssets` reports it. */\nexport interface AssetInfo {\n id: string;\n /** From the data URL, e.g. \"image/png\". */\n mimeType: string;\n /** Decoded size in bytes. */\n bytes: number;\n /** References (every space) that embed it. */\n users: number;\n}\n\n/** Gap between PDF pages placed side by side (raster import), mm. */\nconst PDF_PAGE_GAP_MM = 50;\n\ntype Step = { forwards: Operation[]; inverses: Operation[] };\n\n/**\n * Which layouts a PDF render prints (shared by every renderPdf host): the\n * named ones in the order given, else every layout in document order, else\n * — for a layout-less document — one ephemeral fitted sheet from `fallback`\n * (the document itself gains no layout). `palette` overrides each page's.\n */\nexport const selectPdfLayouts = (\n layouts: readonly PaperLayout[],\n opts: RenderPdfOptions,\n fallback: () => PaperLayout,\n): PaperLayout[] => {\n const byRef = (ref: string) => {\n const l = layouts.find((x) => x.name === ref || x.id === ref);\n if (!l) throw new Error(`Unknown layout \"${ref}\"`);\n return l;\n };\n let selected =\n opts.layouts !== undefined\n ? opts.layouts.map(byRef)\n : layouts.length > 0\n ? [...layouts]\n : [fallback()];\n if (opts.palette)\n selected = selected.map((l) => ({ ...l, printPalette: opts.palette! }));\n if (selected.length === 0) throw new Error(\"No layouts selected\");\n return selected;\n};\n\n/** Reject duplicate ids in a whole-array style replace, so the diff always\n * decomposes into granular per-item ops and never falls back to the legacy\n * coarse set-* op (docs/granular-ops.md). */\nconst assertUniqueIds = (\n items: readonly { id: string }[],\n where: string,\n): void => {\n const seen = new Set<string>();\n for (const { id } of items) {\n if (seen.has(id))\n throw new Error(`${where}: duplicate style id ${JSON.stringify(id)}`);\n seen.add(id);\n }\n};\n\n/**\n * Where a LocalDrawing's document lives and how its edits are recorded. Absent\n * (constructed from a document), LocalDrawing owns a kernel and its own undo\n * stacks; the editor passes hooks over its live stores so agent and script\n * edits go through the mutation funnel and the user's history.\n */\nexport interface DrawingHooks {\n /** The live document — read only, never handed out. */\n document(): LineaDocument;\n /** Apply one validated op (throws when refused). */\n apply(op: Operation): void;\n /** One undo step for everything `fn` applies; a throw (or rejection)\n * rolls it back and rethrows. Nested calls join the outer step. */\n transaction<T>(fn: () => T): T;\n inTransaction(): boolean;\n undo(): boolean;\n redo(): boolean;\n canUndo(): boolean;\n canRedo(): boolean;\n /** Bumped by every change the drawing should report (agents poll it). */\n revision(): number;\n /** Text metrics for bounds and DXF (default: approximate font metrics). */\n measure?: TextMeasurer;\n /** Document-wide object lookup for block reference inputs. */\n resolveObject?: (id: string) => ModelObject | undefined;\n /** Loaded reference content (default: the drawing's referenceContent). */\n resolveReference?: (ref: Reference) => ReferenceContent | null;\n /** Snap/hit-test geometry, e.g. from a cache (default: built per call). */\n snapEntry?: (obj: ModelObject) => SnapCacheEntry;\n /** Where the host keeps its marketplace list and how it reaches them\n * (default: an in-memory list holding the public collection, fetched\n * with the platform's fetch — folder marketplaces then need a reader). */\n marketplaces?: MarketplaceHost;\n}\n\n/** A host's marketplace configuration: the list (the editor's settings, a\n * process's config) and the client that fetches from it. */\nexport interface MarketplaceHost {\n list(): MarketplaceConfig[];\n set(list: MarketplaceConfig[]): void;\n client: MarketplaceClient;\n}\n\nexport const memoryMarketplaceHost = (io?: MarketplaceIO): MarketplaceHost => {\n let list: MarketplaceConfig[] = [{ kind: \"builtin\" }];\n return {\n list: () => list,\n set: (next) => {\n list = next;\n },\n client: new MarketplaceClient(io),\n };\n};\n\n/** The headless hooks: one DocumentKernel plus op-based undo stacks. */\nconst kernelHooks = (doc: LineaDocument): DrawingHooks => {\n const kernel = new DocumentKernel(doc);\n const undoStack: Step[] = [];\n const redoStack: Step[] = [];\n let txn: Step | null = null;\n let rev = 0;\n const replay = (ops: readonly Operation[]) => {\n for (const op of ops) kernel.apply(op);\n rev++;\n };\n return {\n document: () => kernel.document,\n apply(op) {\n const inverse = kernel.apply(op);\n rev++;\n if (txn) {\n txn.forwards.push(op);\n txn.inverses.push(inverse);\n } else {\n undoStack.push({ forwards: [op], inverses: [inverse] });\n redoStack.length = 0;\n }\n },\n transaction<T>(fn: () => T): T {\n if (txn) return fn(); // nested → part of the outer step\n const step: Step = { forwards: [], inverses: [] };\n txn = step;\n const commit = () => {\n txn = null;\n if (step.forwards.length > 0) {\n undoStack.push(step);\n redoStack.length = 0;\n }\n };\n const rollback = () => {\n txn = null;\n if (step.forwards.length > 0) replay([...step.inverses].reverse());\n };\n let result: T;\n try {\n result = fn();\n } catch (e) {\n rollback();\n throw e;\n }\n if (result instanceof Promise) {\n return result.then(\n (v) => {\n commit();\n return v;\n },\n (e: unknown) => {\n rollback();\n throw e;\n },\n ) as T;\n }\n commit();\n return result;\n },\n inTransaction: () => txn !== null,\n undo() {\n const step = undoStack.pop();\n if (!step) return false;\n replay([...step.inverses].reverse());\n redoStack.push(step);\n return true;\n },\n redo() {\n const step = redoStack.pop();\n if (!step) return false;\n replay(step.forwards);\n undoStack.push(step);\n return true;\n },\n canUndo: () => undoStack.length > 0,\n canRedo: () => redoStack.length > 0,\n revision: () => rev,\n };\n};\n\n/** Layer patches may say `hidden` (the tool texts long advertised it) —\n * the stored field is `visible`. */\nconst withVisible = <T extends object>(layer: T): T => {\n const { hidden, ...rest } = layer as T & { hidden?: unknown };\n if (hidden === undefined) return layer;\n return { ...rest, visible: !hidden } as T;\n};\n\nexport class LocalDrawing implements Drawing {\n private hooks: DrawingHooks;\n /** Schema-version migration applied on open; null when none was needed. */\n readonly migration: { from: number; to: number } | null;\n /** Display name (summary, default export names). Host state — a document\n * carries no name: the SDK keeps it in step with the file name. */\n name = DEFAULT_DOCUMENT_NAME;\n /** Loaded reference content by reference id. Hosts that can read files\n * fill it (the Node SDK, in `ready()`); empty → references paint and\n * snap as frames. docs/references.md. */\n protected referenceContent = new Map<string, ReferenceContent>();\n private resolveReference = (ref: Reference): ReferenceContent | null =>\n this.hooks.resolveReference\n ? this.hooks.resolveReference(ref)\n : (this.referenceContent.get(ref.id) ?? null);\n\n /** A document (owned here: kernel + undo stacks), or hooks over a document\n * that lives elsewhere (the editor's stores). */\n constructor(\n source: LineaDocument | DrawingHooks,\n migration: { from: number; to: number } | null = null,\n ) {\n this.hooks = \"apply\" in source ? source : kernelHooks(source);\n this.migration = migration;\n // Block identity/metadata are module exports — start the (lazy)\n // transpiler now so meta-dependent paths (ops validation, evaluation,\n // rendering) go definitive as early as possible. Until it lands the\n // checks are permissive, never wrong.\n if (this.state.blockDefinitions.length > 0) void ensureScriptTranspiler();\n }\n\n /** The live document — internal reads only; NEVER handed out. */\n protected get state(): LineaDocument {\n return this.hooks.document();\n }\n\n get id(): string {\n return this.state.id;\n }\n\n get revision(): number {\n return this.hooks.revision();\n }\n\n // Public reads return detached deep clones: mutating them cannot corrupt\n // the document (all edits must go through the validated ops, which also\n // keep undo history and the block caches correct).\n get document(): LineaDocument {\n return structuredClone(this.state);\n }\n get layers(): Layer[] {\n return structuredClone(this.state.layers);\n }\n get objects(): ModelObject[] {\n return structuredClone(this.state.objects);\n }\n get layouts(): PaperLayout[] {\n return structuredClone(this.state.layouts);\n }\n\n listLayouts(): PaperLayout[] {\n return this.layouts;\n }\n\n /** Look up an object in ANY space (model or a layout's sheet objects). */\n getObject(id: string): ModelObject | undefined {\n const obj = resolveDocumentObject(this.state, id);\n return obj && structuredClone(obj);\n }\n\n private findObject(id: string): { obj: ModelObject; space: OpSpace } {\n const doc = this.state;\n const obj = resolveDocumentObject(doc, id);\n if (!obj) throw new Error(`Unknown object \"${id}\"`);\n // ponytail: linear scan of layout sheets (few, small); index if it shows.\n const layout = doc.layouts.find((l) => l.objects.includes(obj));\n return { obj, space: layout ? { layoutId: layout.id } : \"model\" };\n }\n\n private groupBySpace<T>(\n entries: { space: OpSpace; item: T }[],\n ): { space: OpSpace; items: T[] }[] {\n const groups = new Map<string, { space: OpSpace; items: T[] }>();\n for (const { space, item } of entries) {\n const key = space === \"model\" ? \"model\" : space.layoutId;\n const group = groups.get(key) ?? { space, items: [] };\n group.items.push(item);\n groups.set(key, group);\n }\n return [...groups.values()];\n }\n\n /** One op per space, all in one undo step. */\n private applyBySpace(\n entries: { space: OpSpace; obj: ModelObject }[],\n make: (space: OpSpace, objects: ModelObject[]) => Operation,\n ): void {\n const groups = this.groupBySpace(\n entries.map(({ space, obj }) => ({ space, item: obj })),\n );\n this.transaction(() => {\n for (const g of groups) this.applyForward(make(g.space, g.items));\n });\n }\n\n // --- op plumbing ---------------------------------------------------------\n\n private applyForward(op: Operation): void {\n this.hooks.apply(op);\n }\n\n /** Emit an op list as one undo step. */\n private applyForwardAll(ops: readonly Operation[]): void {\n this.transaction(() => {\n for (const op of ops) this.applyForward(op);\n });\n }\n\n /** Escape hatch: a raw op batch — schema-checked (parseOperations), then\n * applied atomically as one step (the kernel checks references). */\n applyOps(ops: readonly Operation[]): void {\n this.applyForwardAll(parseOperations(ops));\n }\n\n /**\n * Group mutations into ONE undo step. A throw (sync, or an async fn's\n * rejection) rolls back everything the transaction applied and rethrows.\n * Nested calls join the outer step.\n */\n transaction<T>(fn: () => T): T {\n return this.hooks.transaction(fn);\n }\n\n private assertNoTransaction(what: string): void {\n if (this.hooks.inTransaction())\n throw new Error(\n `${what}() inside a transaction — return or throw to roll back instead`,\n );\n }\n\n undo(): boolean {\n this.assertNoTransaction(\"undo\");\n return this.hooks.undo();\n }\n redo(): boolean {\n this.assertNoTransaction(\"redo\");\n return this.hooks.redo();\n }\n get canUndo(): boolean {\n return this.hooks.canUndo();\n }\n get canRedo(): boolean {\n return this.hooks.canRedo();\n }\n\n // --- layers --------------------------------------------------------------\n\n private resolveLayerId(layerName?: string, layerId?: string): string {\n if (layerId) return layerId;\n if (layerName) return this.resolveLayer(layerName).id;\n return this.state.currentLayerId;\n }\n\n listLayers(): LayerInfo[] {\n const current = this.state.currentLayerId;\n return this.layers.map((l) => ({ ...l, current: l.id === current }));\n }\n\n /** Create a layer; returns its id. */\n addLayer(layer: Partial<Layer> & { name: string }): string {\n // Names are how layers are addressed everywhere (layer-by-name in add,\n // query filters) — a silent duplicate would resolve to the first match.\n const clash = this.state.layers.find(\n (l) => l.name.toLowerCase() === layer.name.toLowerCase(),\n );\n if (clash)\n throw new Error(`addLayer(): layer \"${clash.name}\" already exists`);\n const full = LayerSchema.parse(withVisible(layer));\n this.applyForward({ type: \"add-layer\", layer: full });\n return full.id;\n }\n\n private resolveLayer(nameOrId: string): Layer {\n const l = this.state.layers.find(\n (x) => x.id === nameOrId || x.name === nameOrId,\n );\n if (!l) throw new Error(`Unknown layer \"${nameOrId}\"`);\n return l;\n }\n\n /** Patch a layer (rename, color, lineWidth, visible, locked) by name or id. */\n updateLayer(nameOrId: string, patch: Partial<Omit<Layer, \"id\">>): void {\n const cur = this.resolveLayer(nameOrId);\n if (\n patch.name !== undefined &&\n patch.name.toLowerCase() !== cur.name.toLowerCase()\n ) {\n const clash = this.state.layers.find(\n (l) => l.name.toLowerCase() === patch.name!.toLowerCase(),\n );\n if (clash)\n throw new Error(`updateLayer(): layer \"${clash.name}\" already exists`);\n }\n this.applyForward({\n type: \"update-layer\",\n layer: LayerSchema.parse({ ...cur, ...withVisible(patch), id: cur.id }),\n });\n }\n\n /** Remove an EMPTY, non-current layer (the kernel refuses otherwise). */\n removeLayer(nameOrId: string): void {\n this.applyForward({\n type: \"remove-layer\",\n id: this.resolveLayer(nameOrId).id,\n });\n }\n\n /** Reorder the layers (names or ids, every layer exactly once). */\n reorderLayers(order: readonly string[]): void {\n this.applyForward({\n type: \"reorder-layers\",\n ids: order.map((l) => this.resolveLayer(l).id),\n });\n }\n\n /** The layer newly added objects default to. */\n setCurrentLayer(nameOrId: string): void {\n this.applyForward({\n type: \"set-current-layer\",\n id: this.resolveLayer(nameOrId).id,\n });\n }\n\n updateSettings(patch: Partial<LineaDocument[\"settings\"]>): void {\n this.applyForward({\n type: \"set-document-settings\",\n settings: { ...this.state.settings, ...patch },\n });\n }\n\n // --- document meta / assets ------------------------------------------------\n\n /**\n * Embed a file (a data URL — PNG, JPEG, PDF…) and return the assetId an\n * embedded reference's `source: { kind: \"asset\", assetId }` names.\n * Content-keyed: the same data reuses one entry.\n */\n addAsset(dataUrl: string): string {\n const id = hashAsset(dataUrl);\n if (this.state.assets[id] !== dataUrl)\n this.applyForward({ type: \"set-asset\", id, dataUrl });\n return id;\n }\n\n /** Remove an asset (the kernel refuses while a reference embeds it). */\n removeAsset(id: string): void {\n this.applyForward({ type: \"remove-asset\", id });\n }\n\n listAssets(): AssetInfo[] {\n const users = new Map<string, number>();\n for (const objs of [\n this.state.objects,\n ...this.state.layouts.map((l) => l.objects),\n ])\n for (const o of objs) {\n const id = embeddedAssetId(o);\n if (id !== undefined) users.set(id, (users.get(id) ?? 0) + 1);\n }\n return Object.entries(this.state.assets).map(([id, dataUrl]) => {\n const comma = dataUrl.indexOf(\",\");\n const base64 = dataUrl.slice(comma + 1);\n return {\n id,\n mimeType: /^data:([^;,]+)/.exec(dataUrl)?.[1] ?? \"\",\n bytes:\n Math.floor((base64.length * 3) / 4) -\n (base64.match(/=+$/)?.[0].length ?? 0),\n users: users.get(id) ?? 0,\n };\n });\n }\n\n // --- import (merge into this document) -------------------------------------\n\n /** Merge DXF text into the document (new layers, objects, layouts). */\n importDxfText(text: string, opts: DxfImportOptions = {}): DxfImportReport {\n const doc = this.state;\n const result = dxfToModel(text, dxfImportContextOf(doc, opts.unitOverride));\n const { ops, objects } = dxfImportOps(doc, result);\n this.applyOps(ops);\n return {\n objects: objects.length,\n layers: result.newLayers.length,\n layouts: result.layouts.length,\n objectIds: objects.map((o) => o.id),\n layoutIds: result.layouts.map((l) => l.id),\n degraded: Object.fromEntries(result.degraded),\n skipped: Object.fromEntries(result.skipped),\n textStyles: result.textStyles.length - doc.textStyles.length,\n dimStyles: result.dimStyles.length - doc.dimStyles.length,\n blockDefinitions: result.newBlockDefinitions.length,\n lineTypes: result.lineTypes.length - doc.lineTypes.length,\n hatchPatterns: result.hatchPatterns.length - doc.hatchPatterns.length,\n };\n }\n\n /** Merge DWG bytes into the document (wasm transcode → the DXF path). */\n async importDwgData(\n data: Uint8Array,\n opts?: DxfImportOptions,\n ): Promise<DxfImportReport> {\n return this.importDxfText(await dwgToDxf(data), opts);\n }\n\n /** Merge a PDF: its vector/text content onto the current layer, or\n * (`as: \"image\"`) embedded, every page a raster reference at true page\n * scale. */\n async importPdfData(\n data: ArrayBuffer | Uint8Array,\n opts: PdfImportOptions = {},\n ): Promise<PdfImportReport> {\n if (opts.as === \"image\") {\n if (!this.rasterizePdf)\n throw new Error(\n 'PDF as image is not available on this host yet; import it with as: \"vectors\"',\n );\n // ponytail: rasterized only for the page sizes — the PDF itself is\n // embedded (raster-mode references keep page + mode switchable).\n const pages = await this.rasterizePdf(data);\n const at = toVec(opts.origin ?? [0, 0]);\n const layerId = this.state.currentLayerId;\n const bytes = data instanceof Uint8Array ? data : new Uint8Array(data);\n const assetId = this.addAsset(bytesToDataUrl(bytes, \"application/pdf\"));\n let x = at.x;\n const placed = pages.map((p, i) => {\n const object = {\n type: \"reference\",\n layerId,\n format: \"pdf\",\n name: pages.length > 1 ? `PDF page ${i + 1}` : \"PDF\",\n source: { kind: \"asset\", assetId },\n pdfPage: i + 1,\n pdfMode: \"raster\",\n position: { x, y: at.y },\n extent: { minX: 0, minY: 0, maxX: p.widthMm, maxY: p.heightMm },\n } as ModelObjectInput;\n x += p.widthMm + PDF_PAGE_GAP_MM;\n return object;\n });\n const objectIds = placed.length > 0 ? this.add(placed) : [];\n return { objects: objectIds.length, pageCount: pages.length, objectIds };\n }\n const result = await pdfToModel(data, { workerSrc: this.pdfWorkerSrc });\n const layerId = this.state.currentLayerId;\n const objectIds =\n result.objects.length > 0\n ? this.add(\n result.objects.map((o) => ({ ...o, layerId }) as ModelObjectInput),\n )\n : [];\n return {\n objects: result.objects.length,\n pageCount: result.pageCount,\n objectIds,\n };\n }\n\n /** Host capability: every PDF page rasterized. Absent → PDF-as-image\n * import is refused (headless Node, until it has a rasterizer). */\n rasterizePdf?(data: ArrayBuffer | Uint8Array): Promise<RasterPdfPage[]>;\n\n /** pdf.js worker URL for hosts that need one (the browser). */\n protected pdfWorkerSrc?: string;\n\n // --- styles ----------------------------------------------------------------\n\n // Styles are addressed by name or id, like layers, so names stay unique\n // (case-insensitive) on add and rename.\n private resolveStyle<T extends { id: string; name: string }>(\n styles: readonly T[],\n nameOrId: string,\n what: string,\n ): T {\n const s = styles.find((x) => x.id === nameOrId || x.name === nameOrId);\n if (!s) throw new Error(`Unknown ${what} \"${nameOrId}\"`);\n return s;\n }\n\n private assertStyleName(\n styles: readonly { id: string; name: string }[],\n name: string,\n context: string,\n except?: string,\n ): void {\n const clash = styles.find(\n (s) => s.id !== except && s.name.toLowerCase() === name.toLowerCase(),\n );\n if (clash)\n throw new Error(`${context}: style \"${clash.name}\" already exists`);\n }\n\n /** Layouts are addressed by name everywhere (`layout` on the object\n * tools, remove, reorder, render) — a duplicate would silently resolve to\n * the first match. */\n private assertLayoutName(name: string, context: string, except?: string) {\n const clash = this.state.layouts.find(\n (l) => l.id !== except && l.name.toLowerCase() === name.toLowerCase(),\n );\n if (clash)\n throw new Error(`${context}: layout \"${clash.name}\" already exists`);\n }\n\n /** Objects reference styles by id, but callers often pass the NAME:\n * resolve it (text/table → text styles, dimension → dim styles). An\n * unknown value is refused rather than stored dangling — a dangling\n * reference renders with the first style and nothing says why. */\n private styleRef(\n obj: { type?: unknown; styleId?: unknown },\n context: string,\n ): { styleId?: string } {\n if (typeof obj.styleId !== \"string\") return {}; // zod reports the rest\n const styles =\n obj.type === \"dimension\"\n ? this.state.dimStyles\n : obj.type === \"text\" || obj.type === \"table\"\n ? this.state.textStyles\n : null;\n if (!styles) return {};\n const s =\n styles.find((x) => x.id === obj.styleId) ??\n styles.find((x) => x.name === obj.styleId);\n if (!s)\n throw new Error(\n `${context}: unknown ${obj.type === \"dimension\" ? \"dim\" : \"text\"} style \"${obj.styleId}\"`,\n );\n return { styleId: s.id };\n }\n\n listTextStyles(): TextStyle[] {\n return this.state.textStyles.map((s) => ({ ...s }));\n }\n\n listDimStyles(): DimStyle[] {\n return this.state.dimStyles.map((s) => ({ ...s }));\n }\n\n /** Create a text style (unique name; unset fields take the defaults);\n * returns its id. */\n addTextStyle(\n props: { name: string } & Partial<Omit<TextStyle, \"id\">>,\n ): string {\n this.assertStyleName(this.state.textStyles, props.name, \"addTextStyle()\");\n const style = TextStyleSchema.parse(props);\n this.applyForward({ type: \"add-text-style\", style });\n return style.id;\n }\n\n updateTextStyle(\n nameOrId: string,\n patch: Partial<Omit<TextStyle, \"id\">>,\n ): void {\n const cur = this.resolveStyle(\n this.state.textStyles,\n nameOrId,\n \"text style\",\n );\n if (patch.name !== undefined)\n this.assertStyleName(\n this.state.textStyles,\n patch.name,\n \"updateTextStyle()\",\n cur.id,\n );\n this.applyForward({\n type: \"update-text-style\",\n style: TextStyleSchema.parse({ ...cur, ...patch, id: cur.id }),\n });\n }\n\n // --- line types / hatch patterns (name-keyed definitions) -----------------\n\n listLineTypes(): LineType[] {\n return this.state.lineTypes.map((t) => ({ ...t }));\n }\n\n addLineTypes(lineTypes: readonly LineType[]): void {\n this.transaction(() => {\n for (const raw of lineTypes) {\n const lineType = LineTypeSchema.parse(raw);\n this.applyForward({ type: \"add-line-type\", lineType });\n }\n });\n }\n\n updateLineType(name: string, patch: Partial<LineType>): void {\n const cur = this.state.lineTypes.find(\n (t) => lineTypeKey(t.name) === lineTypeKey(name),\n );\n if (!cur) throw new Error(`Unknown line type \"${name}\"`);\n const next = LineTypeSchema.parse({ ...cur, ...patch });\n if (lineTypeKey(next.name) !== lineTypeKey(cur.name)) {\n // A rename: the trio has no rename op — remove + add keeps history\n // granular and the name unique.\n this.transaction(() => {\n this.applyForward({ type: \"remove-line-type\", name: cur.name });\n this.applyForward({ type: \"add-line-type\", lineType: next });\n });\n } else this.applyForward({ type: \"update-line-type\", lineType: next });\n }\n\n removeLineType(name: string): void {\n this.applyForward({ type: \"remove-line-type\", name });\n }\n\n listHatchPatterns(): DocumentHatchPattern[] {\n return this.state.hatchPatterns.map((p) => ({ ...p }));\n }\n\n addHatchPatterns(patterns: readonly DocumentHatchPattern[]): void {\n this.transaction(() => {\n for (const raw of patterns) {\n const hatchPattern = HatchPatternSchema.parse(raw);\n this.applyForward({ type: \"add-hatch-pattern\", hatchPattern });\n }\n });\n }\n\n updateHatchPattern(name: string, patch: Partial<DocumentHatchPattern>): void {\n const cur = this.state.hatchPatterns.find(\n (p) => hatchPatternKey(p.name) === hatchPatternKey(name),\n );\n if (!cur) throw new Error(`Unknown hatch pattern \"${name}\"`);\n const next = HatchPatternSchema.parse({ ...cur, ...patch });\n if (hatchPatternKey(next.name) !== hatchPatternKey(cur.name)) {\n this.transaction(() => {\n this.applyForward({ type: \"remove-hatch-pattern\", name: cur.name });\n this.applyForward({ type: \"add-hatch-pattern\", hatchPattern: next });\n });\n } else\n this.applyForward({ type: \"update-hatch-pattern\", hatchPattern: next });\n }\n\n removeHatchPattern(name: string): void {\n this.applyForward({ type: \"remove-hatch-pattern\", name });\n }\n\n /** Remove a text style no object uses (the kernel refuses otherwise). */\n removeTextStyle(nameOrId: string): void {\n this.applyForward({\n type: \"remove-text-style\",\n id: this.resolveStyle(this.state.textStyles, nameOrId, \"text style\").id,\n });\n }\n\n /** Create a dimension style (unique name; unset fields take the\n * defaults); returns its id. */\n addDimStyle(props: { name: string } & Partial<Omit<DimStyle, \"id\">>): string {\n this.assertStyleName(this.state.dimStyles, props.name, \"addDimStyle()\");\n const style = DimStyleSchema.parse(props);\n this.applyForward({ type: \"add-dim-style\", style });\n return style.id;\n }\n\n updateDimStyle(nameOrId: string, patch: Partial<Omit<DimStyle, \"id\">>): void {\n const cur = this.resolveStyle(this.state.dimStyles, nameOrId, \"dim style\");\n if (patch.name !== undefined)\n this.assertStyleName(\n this.state.dimStyles,\n patch.name,\n \"updateDimStyle()\",\n cur.id,\n );\n this.applyForward({\n type: \"update-dim-style\",\n style: DimStyleSchema.parse({ ...cur, ...patch, id: cur.id }),\n });\n }\n\n /** Remove a dimension style no dimension uses (the kernel refuses\n * otherwise). */\n removeDimStyle(nameOrId: string): void {\n this.applyForward({\n type: \"remove-dim-style\",\n id: this.resolveStyle(this.state.dimStyles, nameOrId, \"dim style\").id,\n });\n }\n\n /** Replace the document's dimension styles (min 1; objects reference by\n * id). Diffed into granular per-style ops. */\n setDimStyles(styles: DimStyle[]): void {\n const parsed = styles.map((s) => DimStyleSchema.parse(s));\n assertUniqueIds(parsed, \"setDimStyles()\");\n this.applyForwardAll(diffDimStyleOps(this.state.dimStyles, parsed));\n }\n\n /** Replace the document's text styles (min 1; objects reference by id).\n * Diffed into granular per-style ops. */\n setTextStyles(styles: TextStyle[]): void {\n const parsed = styles.map((s) => TextStyleSchema.parse(s));\n assertUniqueIds(parsed, \"setTextStyles()\");\n this.applyForwardAll(diffTextStyleOps(this.state.textStyles, parsed));\n }\n\n // --- modules (blocks + commands) -------------------------------------------\n\n private assertModuleSources(\n defs: readonly unknown[],\n where: string,\n ): string[] {\n const sources = defs.map((d) => {\n if (typeof d !== \"string\")\n throw new Error(\n `${where}: modules are ES-module SOURCES (strings) — each exports its own id/name`,\n );\n return d;\n });\n if (new Set(sources).size !== sources.length)\n throw new Error(\n `${where}: duplicate module source — modules are content-addressed (two identical sources are indistinguishable); deduplicate before setting`,\n );\n return sources;\n }\n\n /**\n * Replace the block library (raw module sources — each exports its own\n * id/name/params; semantic validation happens at compile). Async: awaits\n * the lazy transpiler, so block evaluation (bboxOf, renders, exports) is\n * definitive as soon as this resolves — never silently placeholder.\n */\n async setBlockDefinitions(defs: unknown[]): Promise<void> {\n const sources = this.assertModuleSources(defs, \"setBlockDefinitions()\");\n if (sources.length > 0) await ensureScriptTranspiler();\n this.applyForwardAll(\n diffModuleOps(this.state.blockDefinitions, sources, \"blockDefinitions\"),\n );\n }\n\n /** Replace the document's command modules (same rules as blocks). */\n async setCommands(defs: unknown[]): Promise<void> {\n const sources = this.assertModuleSources(defs, \"setCommands()\");\n if (sources.length > 0) await ensureScriptTranspiler();\n this.applyForwardAll(\n diffModuleOps(this.state.commands, sources, \"commands\"),\n );\n }\n\n /** Compilable block definitions (broken modules are skipped). */\n listBlockDefinitions(): BlockMeta[] {\n return listBlockMeta(this.state.blockDefinitions).flatMap((r) =>\n r.ok ? [r.meta] : [],\n );\n }\n\n /** Compilable document commands (broken modules are skipped). */\n listUserCommands(): CommandMeta[] {\n return listCommandMeta(this.state.commands).flatMap((r) =>\n r.ok ? [r.meta] : [],\n );\n }\n\n async addBlockDefinitions(sources: readonly string[]): Promise<MergeReport> {\n await ensureScriptTranspiler();\n const report = mergeBlockModules(this.state.blockDefinitions, sources);\n this.applyForwardAll(\n diffModuleOps(\n this.state.blockDefinitions,\n report.merged,\n \"blockDefinitions\",\n ),\n );\n return report;\n }\n\n async addUserCommands(sources: readonly string[]): Promise<MergeReport> {\n await ensureScriptTranspiler();\n const report = mergeCommandModules(this.state.commands, sources);\n this.applyForwardAll(\n diffModuleOps(this.state.commands, report.merged, \"commands\"),\n );\n return report;\n }\n\n // --- marketplaces ----------------------------------------------------------\n\n /** The host's marketplace list + client; a bare drawing gets an in-memory\n * list holding the public collection. */\n protected get marketplaceHost(): MarketplaceHost {\n return (this.hooks.marketplaces ??= memoryMarketplaceHost());\n }\n\n /** Replace the host's marketplace configuration (SDK / server config). */\n setMarketplaceHost(host: MarketplaceHost): void {\n this.hooks.marketplaces = host;\n }\n\n listMarketplaces(): MarketplaceInfo[] {\n return this.marketplaceHost.list().map(marketplaceInfo);\n }\n\n async addMarketplaces(\n list: readonly MarketplaceConfig[],\n ): Promise<MarketplaceInfo[]> {\n const host = this.marketplaceHost;\n const parsed = list.map((m) => MarketplaceConfigSchema.parse(m));\n for (const m of parsed) {\n const catalog = await host.client.catalog(m, true);\n if (catalog.state !== \"ready\")\n throw new Error(`${marketplaceLabel(m)}: ${catalog.reason}`);\n }\n // New ones go on top (highest priority); a repeated key replaces in\n // place, e.g. to update a token.\n let next = [...host.list()];\n for (const m of parsed) {\n const key = marketplaceKey(m);\n const i = next.findIndex((x) => marketplaceKey(x) === key);\n if (i >= 0) next[i] = m;\n else next = [m, ...next];\n }\n host.set(normalizeMarketplaces(next));\n return this.listMarketplaces();\n }\n\n removeMarketplaces(names: readonly string[]): MarketplaceInfo[] {\n const host = this.marketplaceHost;\n const current = host.list();\n for (const name of names) {\n const hit = current.find((m) => matchesMarketplace(m, name));\n if (hit === undefined)\n throw new Error(\n `No marketplace \"${name}\" is configured (see listMarketplaces)`,\n );\n if (hit.kind === \"builtin\")\n throw new Error(\"The built-in public collection can't be removed\");\n }\n host.set(\n normalizeMarketplaces(\n current.filter((m) => !names.some((n) => matchesMarketplace(m, n))),\n ),\n );\n return this.listMarketplaces();\n }\n\n async searchMarketplaces(\n q: MarketplaceQuery = {},\n ): Promise<MarketplaceHit[]> {\n await ensureScriptTranspiler(); // install status reads module exports\n const host = this.marketplaceHost;\n return host.client.search(host.list(), q, this.state);\n }\n\n async installMarketplaceEntries(\n ids: readonly string[],\n marketplace?: string,\n ): Promise<MergeReport> {\n await ensureScriptTranspiler(); // vendored checks must be definitive\n const host = this.marketplaceHost;\n const plans: { kind: \"block\" | \"command\"; sources: string[] }[] = [];\n for (const id of ids) {\n const found = await host.client.find(host.list(), id, marketplace);\n if (found === null)\n throw new Error(\n `No marketplace entry \"${id}\"${\n marketplace === undefined ? \"\" : ` in ${marketplace}`\n } (see searchMarketplaces)`,\n );\n plans.push({\n kind: found.entry.kind,\n sources: await host.client.installSources(\n found.config,\n found.entry,\n this.state,\n ),\n });\n }\n // Everything fetched: merge as ONE undo step.\n return this.transaction(async () => {\n const report: MergeReport = {\n merged: [],\n added: [],\n replaced: [],\n skipped: 0,\n rejected: [],\n };\n for (const plan of plans) {\n const r =\n plan.kind === \"block\"\n ? await this.addBlockDefinitions(plan.sources)\n : await this.addUserCommands(plan.sources);\n if (r.rejected.length > 0) throw new Error(r.rejected[0].error);\n report.merged = r.merged;\n report.added.push(...r.added);\n report.replaced.push(...r.replaced);\n report.skipped += r.skipped;\n }\n return report;\n });\n }\n\n /** Remove a block module by its exported id (unknown id → error). */\n removeBlockDefinition(id: string): void {\n const source = this.state.blockDefinitions.find((s) =>\n listBlockMeta([s]).some((r) => r.ok && r.meta.id === id),\n );\n if (source === undefined) throw new Error(`Unknown block \"${id}\"`);\n this.applyForward({ type: \"remove-block-definition\", source });\n }\n\n /** Remove a command module by its exported id (unknown id → error). */\n removeUserCommand(id: string): void {\n const source = this.state.commands.find((s) =>\n listCommandMeta([s]).some((r) => r.ok && r.meta.id === id),\n );\n if (source === undefined) throw new Error(`Unknown command \"${id}\"`);\n this.applyForward({ type: \"remove-document-command\", source });\n }\n\n /**\n * Resolves when block scripts evaluate definitively (the transpiler is\n * loaded). Await this before sync reads/renders of a document that was\n * constructed with block definitions (file opens and the module setters\n * already wait).\n */\n async ready(): Promise<void> {\n if (this.state.blockDefinitions.length > 0) await ensureScriptTranspiler();\n }\n\n // --- layouts ---------------------------------------------------------------\n\n private modelExtents(): AABB {\n let bbox = emptyBounds();\n for (const o of this.state.objects) {\n const b = this.boundsOf(o);\n if (!isEmptyBounds(b)) bbox = unionBounds(bbox, b);\n }\n return bbox;\n }\n\n /** Fitted scale + center for a viewport frame (editor createLayout rules). */\n private fitViewport(rect: { w: number; h: number }): {\n scale: number;\n modelCenter: Vec2;\n } {\n const bbox = this.modelExtents();\n if (isEmptyBounds(bbox)) return { scale: 50, modelCenter: { x: 0, y: 0 } };\n const presets = [1, 2, 5, 10, 20, 50, 100, 200, 500, 1000];\n const needed = Math.max(\n (bbox.maxX - bbox.minX) / (rect.w * 0.9),\n (bbox.maxY - bbox.minY) / (rect.h * 0.9),\n );\n return {\n scale: presets.find((s) => s >= needed) ?? presets[presets.length - 1],\n modelCenter: {\n x: (bbox.minX + bbox.maxX) / 2,\n y: (bbox.minY + bbox.maxY) / 2,\n },\n };\n }\n\n protected makeLayout(name: string, opts: LayoutOptions = {}): PaperLayout {\n const { width, height } = resolveSheetSize(opts.sheet);\n\n const objects: unknown[] = [];\n if (opts.viewport !== false) {\n const vp = opts.viewport ?? {};\n const scale = vp.scale ?? opts.scale;\n const margin = 20;\n const rect = vp.rect ?? {\n x: margin,\n y: margin,\n w: width - margin * 2,\n h: height - margin * 2,\n };\n const fitted = this.fitViewport(rect);\n objects.push({\n id: crypto.randomUUID(),\n type: \"viewport\",\n layerId: this.state.currentLayerId,\n rect,\n modelCenter: vp.center ? toVec(vp.center) : fitted.modelCenter,\n scale: scale !== undefined ? parseScale(scale) : fitted.scale,\n locked: false,\n hiddenLayerIds: [],\n });\n }\n\n return PaperLayoutSchema.parse({\n id: crypto.randomUUID(),\n name,\n sheet: { width, height },\n printPalette: \"color\",\n objects,\n });\n }\n\n /**\n * Create a paper layout — by default A3 landscape with one viewport fitted\n * to the model extents. Returns the layout id.\n */\n addLayout(name: string, opts: LayoutOptions = {}): string {\n this.assertLayoutName(name, \"addLayout()\");\n const layout = this.makeLayout(name, opts);\n this.applyForward({ type: \"add-layout\", layout, index: opts.index });\n return layout.id;\n }\n\n /** Remove a layout by name or id. */\n removeLayout(nameOrId: string): void {\n this.applyForward({\n type: \"remove-layout\",\n id: this.resolveLayout(nameOrId).id,\n });\n }\n\n /** Reorder the layouts (names or ids, every layout exactly once). Layout\n * order is the sheet order of multi-page PDF export. */\n reorderLayouts(order: readonly string[]): void {\n this.applyForward({\n type: \"reorder-layouts\",\n ids: order.map((l) => this.resolveLayout(l).id),\n });\n }\n\n /** Patch a layout's name / sheet (preset or mm) / print palette. */\n updateLayout(nameOrId: string, patch: LayoutPatch): void {\n const layout = this.resolveLayout(nameOrId);\n if (patch.name !== undefined)\n this.assertLayoutName(patch.name, \"updateLayout()\", layout.id);\n const { sheet, ...rest } = patch;\n this.applyForward({\n type: \"update-layout-meta\",\n id: layout.id,\n ...rest,\n ...(sheet !== undefined\n ? { sheet: resolveSheetSize(sheet, sheetOrientation(layout.sheet)) }\n : {}),\n });\n }\n\n // --- object mutations ----------------------------------------------------\n\n private normalize(input: ModelObjectInput, index?: number): ModelObject {\n const { layer, layerId, id, ...rest } = input as ModelObjectInput & {\n layer?: string;\n layerId?: string;\n id?: string;\n };\n const context = `add(): objects[${index ?? 0}] (${String(input.type ?? \"?\")})`;\n assertKnownStyleOverrideKeys(input as Record<string, unknown>, context);\n const styleRef = this.styleRef(rest, context);\n try {\n const raw: Record<string, unknown> = {\n ...rest,\n ...styleRef,\n layerId: this.resolveLayerId(layer, layerId),\n id: id ?? crypto.randomUUID(),\n };\n // Agents and scripts may still send the pre-v21 dimension shape\n // (vector offset / textOverride): the migration's converter accepts\n // both shapes.\n return ModelObjectSchema.parse(\n raw.type === \"dimension\"\n ? dimensionRawToLabels(dimensionRawToOffset(raw))\n : raw,\n );\n } catch (e) {\n throw wrapZod(\n e,\n `add(): objects[${index ?? 0}] (${String(input.type ?? \"?\")})`,\n );\n }\n }\n\n /**\n * Add objects (points may be `[x, y]`; `layer` resolves by name) to model\n * space, or to a paper layout's sheet via `{ layout }`. Returns ids.\n */\n add(objects: readonly ModelObjectInput[], opts: AddOptions = {}): string[] {\n if (objects.length === 0) return [];\n const space: OpSpace =\n opts.layout !== undefined\n ? { layoutId: this.resolveLayout(opts.layout).id }\n : \"model\";\n const created = objects.map((o, i) => this.normalize(o, i));\n this.applyForward({ type: \"add-objects\", space, objects: created });\n return created.map((o) => o.id);\n }\n\n private patched(\n id: string,\n patch: Record<string, unknown>,\n ): { space: OpSpace; obj: ModelObject } {\n const { layer, layerId, ...rest } = patch as Record<string, unknown> & {\n layer?: string;\n layerId?: string;\n };\n const { obj: cur, space } = this.findObject(id);\n assertKnownStyleOverrideKeys(\n { type: cur.type, styleOverride: rest.styleOverride },\n `update(): \"${id}\" (${cur.type})`,\n );\n const resolvedLayerId =\n layer !== undefined || layerId !== undefined\n ? this.resolveLayerId(layer, layerId)\n : undefined;\n const styleRef =\n \"styleId\" in rest\n ? this.styleRef(\n { type: cur.type, styleId: rest.styleId },\n `update(): \"${id}\" (${cur.type})`,\n )\n : {};\n // New text without new spans drops the old ones: their offsets index\n // the previous string (docs/rich-text.md §4).\n const staleSpans =\n cur.type === \"text\" && \"content\" in rest && !(\"spans\" in rest)\n ? { spans: undefined }\n : {};\n try {\n return {\n space,\n obj: ModelObjectSchema.parse({\n ...cur,\n ...rest,\n ...staleSpans,\n ...styleRef,\n ...(resolvedLayerId ? { layerId: resolvedLayerId } : {}),\n id,\n }),\n };\n } catch (e) {\n throw wrapZod(e, `update(): \"${id}\" (${cur.type})`);\n }\n }\n\n /** Apply one patch to several ids. */\n update(ids: readonly string[], patch: Record<string, unknown>): void;\n /** Apply per-object patches (`{id, ...fields}`) in one undo step. */\n update(entries: readonly ({ id: string } & Record<string, unknown>)[]): void;\n update(\n idsOrEntries:\n readonly string[] | readonly ({ id: string } & Record<string, unknown>)[],\n patch?: Record<string, unknown>,\n ): void {\n if (idsOrEntries.length === 0) return;\n const next =\n typeof idsOrEntries[0] === \"string\"\n ? (idsOrEntries as readonly string[]).map((id) =>\n this.patched(id, patch ?? {}),\n )\n : (\n idsOrEntries as readonly ({ id: string } & Record<\n string,\n unknown\n >)[]\n ).map(({ id, ...fields }) => this.patched(id, fields));\n this.applyBySpace(next, (space, objects) => ({\n type: \"update-objects\",\n space,\n objects,\n }));\n }\n\n /** Delete objects by id (unknown ids are skipped); returns how many went. */\n remove(ids: readonly string[]): number {\n const entries: { space: OpSpace; item: string }[] = [];\n for (const id of ids) {\n try {\n entries.push({ space: this.findObject(id).space, item: id });\n } catch {\n continue;\n }\n }\n const groups = this.groupBySpace(entries);\n if (groups.length === 0) return 0;\n this.transaction(() => {\n for (const g of groups)\n this.applyForward({\n type: \"remove-objects\",\n space: g.space,\n ids: g.items,\n });\n });\n return entries.length;\n }\n\n /** Draw order: move the given objects (bottom → top) to a placement. */\n reorder(ids: readonly string[], placement: ReorderPlacement): void {\n const entries = ids.map((id) => ({\n space: this.findObject(id).space,\n item: id,\n }));\n const groups = this.groupBySpace(entries);\n if (groups.length === 0) return;\n this.transaction(() => {\n for (const g of groups)\n this.applyForward({\n type: \"reorder-objects\",\n space: g.space,\n ids: g.items,\n placement,\n });\n });\n }\n\n // --- transforms ------------------------------------------------------------\n\n private transformEach(\n ids: readonly string[],\n fn: (o: ModelObject) => ModelObject,\n ): void {\n if (ids.length === 0) return;\n const next = ids.map((id) => {\n const { obj, space } = this.findObject(id);\n return { space, obj: ModelObjectSchema.parse(fn(obj)) };\n });\n this.applyBySpace(next, (space, objects) => ({\n type: \"update-objects\",\n space,\n objects,\n }));\n }\n\n /** Selection bbox center — the default pivot for rotate/scale. */\n private pivotOf(ids: readonly string[], center?: PointInput): Vec2 {\n if (center) return toVec(center);\n const bbox = this.bboxOf(ids);\n if (!bbox)\n throw new Error(\"No default pivot (empty bounds) — pass a center\");\n return { x: (bbox.minX + bbox.maxX) / 2, y: (bbox.minY + bbox.maxY) / 2 };\n }\n\n /** Translate objects by a world-mm delta. */\n move(ids: readonly string[], delta: PointInput): void {\n const d = toVec(delta);\n this.transformEach(ids, (o) => translateObject(o, d));\n }\n\n /** Rotate objects by `angle` radians CCW about `center` (default: selection bbox center). */\n rotate(ids: readonly string[], angle: number, center?: PointInput): void {\n const c = this.pivotOf(ids, center);\n this.transformEach(ids, (o) => rotateObject(o, c, angle));\n }\n\n /** Uniformly scale objects about `center` (default: selection bbox center). */\n scale(ids: readonly string[], factor: number, center?: PointInput): void {\n if (!Number.isFinite(factor) || factor <= 0)\n throw new Error(`Invalid scale factor ${factor}`);\n const c = this.pivotOf(ids, center);\n this.transformEach(ids, (o) =>\n translateObject(\n scaleObjectUniform(translateObject(o, { x: -c.x, y: -c.y }), factor),\n c,\n ),\n );\n }\n\n /** Mirror objects across the line a → b. */\n mirror(ids: readonly string[], a: PointInput, b: PointInput): void {\n const pa = toVec(a);\n const pb = toVec(b);\n this.transformEach(ids, (o) => mirrorObject(o, pa, pb));\n }\n\n /** Duplicate objects (into their own space) displaced by `delta`. */\n copy(ids: readonly string[], delta: PointInput): string[] {\n if (ids.length === 0) return [];\n const d = toVec(delta);\n // Fresh ids first, so block object-reference inputs pointing INSIDE the\n // copied set can follow to the clones (outside refs keep the originals).\n const idMap = new Map(ids.map((id) => [id, crypto.randomUUID()]));\n const clones = ids.map((id) => {\n const { obj, space } = this.findObject(id);\n return {\n space,\n obj: ModelObjectSchema.parse({\n ...remapBlockInputRefs(translateObject(obj, d), idMap),\n id: idMap.get(id),\n }),\n };\n });\n this.applyBySpace(clones, (space, objects) => ({\n type: \"add-objects\",\n space,\n objects,\n }));\n return clones.map((c) => c.obj.id);\n }\n\n /**\n * Linear array: `count` TOTAL instances (including the originals) stepped\n * by `delta`. Returns the new ids, one batch per step, in one undo step.\n */\n array(ids: readonly string[], count: number, delta: PointInput): string[] {\n if (!Number.isInteger(count) || count < 1)\n throw new Error(`Invalid array count ${count}`);\n const d = toVec(delta);\n return this.transaction(() => {\n const created: string[] = [];\n for (let i = 1; i < count; i++)\n created.push(...this.copy(ids, { x: d.x * i, y: d.y * i }));\n return created;\n });\n }\n\n // --- reads ---------------------------------------------------------------\n\n private get measurer(): TextMeasurer {\n return this.hooks.measure ?? approximateTextMeasurer;\n }\n\n private resolveObject(): (id: string) => ModelObject | undefined {\n return this.hooks.resolveObject ?? documentObjectResolver(this.state);\n }\n\n private ctx(): SnapGeometryContext {\n return {\n dimStyles: this.state.dimStyles,\n textStyles: this.state.textStyles,\n layers: this.state.layers,\n blockDefinitions: this.state.blockDefinitions,\n resolveObject: this.resolveObject(),\n resolveReference: this.resolveReference,\n measure: this.measurer,\n };\n }\n\n private entryOf(obj: ModelObject): SnapCacheEntry {\n return this.hooks.snapEntry\n ? this.hooks.snapEntry(obj)\n : buildSnapEntry(obj, this.ctx());\n }\n\n private boundsOf(obj: ModelObject): AABB {\n return this.entryOf(obj).bounds;\n }\n\n /** Union bounds of the given objects; null when nothing has bounds. */\n bboxOf(ids: readonly string[]): AABB | null {\n let bbox = emptyBounds();\n for (const id of ids) {\n const b = this.boundsOf(this.findObject(id).obj);\n if (!isEmptyBounds(b)) bbox = unionBounds(bbox, b);\n }\n return isEmptyBounds(bbox) ? null : bbox;\n }\n\n /**\n * Curve length in mm (bulge-exact for polylines); null for object types\n * without a natural length (text, dimensions, hatches, blocks, partial\n * ellipses).\n */\n length(id: string): number | null {\n const o = this.findObject(id).obj;\n switch (o.type) {\n case \"line\":\n return dist(o.a, o.b);\n case \"circle\":\n return 2 * Math.PI * o.radius;\n case \"arc\":\n return o.radius * arcSweep(o);\n case \"polyline\":\n return chainLength(o.points, o.closed);\n default:\n return null;\n }\n }\n\n /**\n * Enclosed area in mm² (bulge arcs tessellated): circles, closed\n * polylines, and hatches (outer loop minus holes); null otherwise.\n */\n area(id: string): number | null {\n const o = this.findObject(id).obj;\n switch (o.type) {\n case \"circle\":\n return Math.PI * o.radius * o.radius;\n case \"polyline\":\n return o.closed ? polylineArea(o.points) : null;\n case \"hatch\":\n return hatchArea(o.loops);\n default:\n return null;\n }\n }\n\n measure(id: string): Measurement {\n return {\n bbox: this.bboxOf([id]),\n length: this.length(id),\n area: this.area(id),\n };\n }\n\n /** Min distance from a point to the object's geometry (bounds fallback). */\n private distanceTo(obj: ModelObject, p: Vec2): number {\n const entry = this.entryOf(obj);\n let best = Infinity;\n for (const s of entry.segments)\n best = Math.min(best, dist(p, closestPointOnSegment(p, s.a, s.b)));\n for (const a of entry.arcs) best = Math.min(best, distToArc(a, p));\n if (best !== Infinity) return best;\n const b = entry.bounds;\n if (isEmptyBounds(b)) return Infinity;\n const cx = Math.max(b.minX, Math.min(p.x, b.maxX));\n const cy = Math.max(b.minY, Math.min(p.y, b.maxY));\n return Math.hypot(p.x - cx, p.y - cy);\n }\n\n /** Query model-space objects — or one paper layout's sheet objects\n * (viewports, annotations) via `filter.layout`. */\n listObjects(filter: ObjectQuery = {}): ModelObject[] {\n const layerId =\n filter.layer !== undefined\n ? this.resolveLayerId(filter.layer)\n : undefined;\n const nearP = filter.near ? toVec(filter.near.point) : null;\n const wanted = filter.ids ? new Set(filter.ids) : null;\n const pool =\n filter.layout !== undefined\n ? structuredClone(this.resolveLayout(filter.layout).objects)\n : this.objects;\n return pool.filter((o) => {\n if (wanted && !wanted.has(o.id)) return false;\n if (filter.type && o.type !== filter.type) return false;\n if (layerId && o.layerId !== layerId) return false;\n if (filter.color !== undefined && o.color !== filter.color) return false;\n if (filter.lineType !== undefined && o.lineType !== filter.lineType)\n return false;\n if (\n filter.content !== undefined &&\n !(o.type === \"text\" && o.content.includes(filter.content))\n )\n return false;\n if (filter.bbox) {\n const b = this.boundsOf(o);\n if (isEmptyBounds(b) || !boundsIntersect(b, filter.bbox)) return false;\n }\n if (filter.inside) {\n const b = this.boundsOf(o);\n const box = filter.inside;\n if (\n isEmptyBounds(b) ||\n b.minX < box.minX ||\n b.maxX > box.maxX ||\n b.minY < box.minY ||\n b.maxY > box.maxY\n )\n return false;\n }\n if (nearP && filter.near && this.distanceTo(o, nearP) > filter.near.tol)\n return false;\n return true;\n });\n }\n\n summary(): DocumentSummary {\n const doc = this.state;\n const layerName = new Map(doc.layers.map((l) => [l.id, l.name]));\n const byType: Record<string, number> = {};\n const byLayer: Record<string, number> = {};\n let bbox = emptyBounds();\n for (const o of doc.objects) {\n byType[o.type] = (byType[o.type] ?? 0) + 1;\n const ln = layerName.get(o.layerId) ?? o.layerId;\n byLayer[ln] = (byLayer[ln] ?? 0) + 1;\n const b = this.boundsOf(o);\n if (!isEmptyBounds(b)) bbox = unionBounds(bbox, b);\n }\n return {\n name: this.name,\n objectCount: doc.objects.length,\n byType,\n byLayer,\n bbox: isEmptyBounds(bbox) ? null : bbox,\n layers: doc.layers.map((l) => l.name),\n settings: doc.settings,\n layouts: doc.layouts.map((l) => ({\n name: l.name,\n objectCount: l.objects.length,\n })),\n };\n }\n\n // --- render / export (browser-safe) ----------------------------------------\n\n protected paintContext() {\n const doc = this.state;\n return {\n objects: doc.objects,\n ...documentPaintResources(doc),\n resolveObject: this.resolveObject(),\n resolveReference: this.resolveReference,\n };\n }\n\n protected resolveLayout(nameOrId: string): PaperLayout {\n const layout = this.state.layouts.find(\n (l) => l.name === nameOrId || l.id === nameOrId,\n );\n if (!layout) throw new Error(`Unknown layout \"${nameOrId}\"`);\n return layout;\n }\n\n /** Render model space (or a paper layout via `layout`) to an SVG string. */\n renderSvg(opts: RenderSvgOptions = {}): string {\n if (opts.layout !== undefined)\n return renderLayoutToSvg(\n this.resolveLayout(opts.layout),\n this.paintContext(),\n opts,\n );\n return renderModelToSvg(this.paintContext(), opts);\n }\n\n /** Export the document to a DXF string. */\n async toDxf(): Promise<string> {\n const { buildDxf } = await import(\"../export/dxf/exportDxf\");\n return buildDxf(this.state, this.measurer).content;\n }\n\n /** Export the document to DWG bytes (the DXF content, wasm-transcoded).\n * Defaults to AC1027 (AutoCAD 2013) — readable by every current CAD tool.\n * Dimensions transcode as real DIMENSION objects; leaders and tables are\n * exploded to plain geometry (DWG_DXF_OPTIONS — the transcoder's DWG\n * output for them is not accepted by AutoCAD). */\n async toDwg(opts?: { version?: DwgVersion }): Promise<Uint8Array> {\n const { buildDxf, DWG_DXF_OPTIONS } = await import(\n \"../export/dxf/exportDxf\"\n );\n const dxf = buildDxf(this.state, this.measurer, DWG_DXF_OPTIONS).content;\n return dxfToDwg(dxf, opts?.version ?? \"AC1027\");\n }\n\n toLinea(): string {\n return documentToJson(this.state);\n }\n}\n","// Run one command module (`export default defineCommand({...})`) against a\n// Drawing — the ONE runner behind the editor palette, the SDK's\n// `runScript`/`runCommand`, and the `linea_run_script` tool. Declared\n// `inputs` are acquired first (picked through the EditorSurface when there\n// is one, otherwise they must be supplied), then the whole `run` executes\n// inside ONE `document.transaction`: mutations apply live (later picks can\n// snap to earlier edits) and a throw — the user pressing Escape in a pick,\n// or any error — rolls everything back. Scripts run unsandboxed in-process\n// (`new Function`, same as blocks); the host's trust toggle is the boundary.\n\nimport { Vec2Schema } from \"../model/common\";\nimport type { Vec2 } from \"../geometry/vec2\";\nimport {\n getCommandMetaResult,\n getCommandRun,\n type CommandMeta,\n} from \"../extensions/commandModules\";\nimport { ensureScriptTranspiler } from \"../extensions/scriptRuntime\";\nimport {\n HEX_COLOR,\n valueParams,\n type ValueParamDef,\n} from \"../model/blockDefinition\";\nimport type { Drawing, EditorSurface, PointInput } from \"./types\";\n\nexport interface RunCommandOptions {\n document: Drawing;\n /** The interactive surface; absent for headless runs. */\n editor?: EditorSurface;\n /** Values for the command's declared `inputs` (label order). Missing\n * ones are picked in the editor, or the run fails without one. */\n inputs?: readonly PointInput[];\n /** Values for the command's declared `params` by name; omitted ones take\n * their defaults. Unknown names or wrong types are an error. */\n params?: Readonly<Record<string, unknown>>;\n}\n\n/** The `ctx` handed to `run` — mirrors CommandContext in lineadraw.d.ts. */\nconst makeContext = (\n opts: RunCommandOptions,\n inputs: readonly Vec2[],\n params: Record<string, unknown>,\n): Record<string, unknown> => {\n const { document, editor } = opts;\n return {\n document,\n editor,\n inputs,\n params,\n };\n};\n\n/** Why `value` doesn't fit `def`, or null when it does. */\nconst paramMismatch = (def: ValueParamDef, value: unknown): string | null => {\n switch (def.type) {\n case \"number\":\n if (typeof value !== \"number\" || !Number.isFinite(value))\n return \"expected a number\";\n if (def.integer && !Number.isInteger(value))\n return \"expected a whole number\";\n if (def.min !== undefined && value < def.min)\n return `below the minimum ${def.min}`;\n if (def.max !== undefined && value > def.max)\n return `above the maximum ${def.max}`;\n return null;\n case \"string\":\n case \"textStyle\":\n case \"dimStyle\":\n case \"font\":\n case \"lineType\":\n case \"hatchPattern\":\n // Resource ids / names: an unknown one falls back where it's used\n // (first style, default font…), like a stored object's would.\n return typeof value === \"string\" ? null : \"expected a string\";\n case \"boolean\":\n return typeof value === \"boolean\" ? null : \"expected true or false\";\n case \"numberList\": {\n if (\n !Array.isArray(value) ||\n !value.every((v) => typeof v === \"number\" && Number.isFinite(v))\n )\n return \"expected an array of numbers\";\n const low = value.find((v) => def.min !== undefined && v < def.min);\n if (low !== undefined) return `${low} is below the minimum ${def.min}`;\n const high = value.find((v) => def.max !== undefined && v > def.max);\n if (high !== undefined) return `${high} is above the maximum ${def.max}`;\n return null;\n }\n case \"color\":\n return typeof value === \"string\" && HEX_COLOR.test(value)\n ? null\n : 'expected a \"#rrggbb\" color';\n case \"stringList\":\n return Array.isArray(value) && value.every((v) => typeof v === \"string\")\n ? null\n : \"expected an array of strings\";\n case \"enum\":\n return def.options.some((o) => o.value === value)\n ? null\n : `expected one of ${def.options.map((o) => JSON.stringify(o.value)).join(\", \")}`;\n default:\n return \"a label carries no value\";\n }\n};\n\n/**\n * The `params` record `run` receives: each declared parameter's default,\n * overridden by `given` — which is checked strictly (an unknown name or a\n * value of the wrong type throws, naming the command and parameter), so a\n * headless or agent caller can't silently run with a typo.\n */\nexport const resolveCommandParams = (\n meta: CommandMeta,\n given: Readonly<Record<string, unknown>> = {},\n): Record<string, unknown> => {\n const defs = valueParams(meta.params ?? []);\n // Null prototype: a param named `constructor` stays a plain property.\n const params: Record<string, unknown> = Object.create(null);\n for (const def of defs) params[def.name] = def.default;\n for (const [name, value] of Object.entries(given)) {\n const def = defs.find((d) => d.name === name);\n if (!def)\n throw new Error(\n `${meta.name}: unknown parameter \"${name}\"${\n defs.length ? ` (declares ${defs.map((d) => d.name).join(\", \")})` : \"\"\n }`,\n );\n const mismatch = paramMismatch(def, value);\n if (mismatch)\n throw new Error(`${meta.name}: parameter \"${name}\" — ${mismatch}`);\n params[name] = value;\n }\n return params;\n};\n\n/**\n * Resolve a command's declared inputs: supplied values first (validated as\n * points), then editor picks for the rest (rubber-band from the previous\n * point). Without an editor, missing inputs are an error naming them.\n */\nexport const acquireCommandInputs = async (\n meta: CommandMeta,\n opts: RunCommandOptions,\n): Promise<Vec2[]> => {\n const labels = meta.inputs ?? [];\n const given = (opts.inputs ?? []).map((p, i) => {\n try {\n return Vec2Schema.parse(p);\n } catch {\n throw new Error(\n `${meta.name}: inputs[${i}] (${labels[i] ?? \"extra\"}) is not a point`,\n );\n }\n });\n if (given.length > labels.length)\n throw new Error(\n `${meta.name}: ${given.length} inputs supplied, declares ${labels.length}`,\n );\n const missing = labels.slice(given.length);\n if (missing.length === 0) return given;\n if (!opts.editor)\n throw new Error(\n `${meta.name} needs an editor for: ${missing.join(\", \")} — supply inputs`,\n );\n const points = [...given];\n for (const label of missing) {\n const referencePoint = points[points.length - 1];\n points.push(await opts.editor.pickPoint({ label, referencePoint }));\n }\n return points;\n};\n\n/**\n * Compile + run a command module source against a Drawing as ONE undo step.\n * Resolves with the script's return value; rejects with the script's error\n * (or the pick cancellation) after the transaction rolled back. Compile\n * errors reject before anything runs.\n */\nexport const runCommandModule = async (\n source: string,\n opts: RunCommandOptions,\n): Promise<unknown> => {\n await ensureScriptTranspiler();\n const result = getCommandMetaResult(source);\n if (!result.ok) throw new Error(`Command failed to compile: ${result.error}`);\n const run = getCommandRun(source);\n // Params before inputs: a bad value fails before the user picks anything.\n const params = resolveCommandParams(result.meta, opts.params);\n const inputs = await acquireCommandInputs(result.meta, opts);\n return opts.document.transaction(\n () => run(makeContext(opts, inputs, params)),\n result.meta.name,\n );\n};\n\n/** Run a DOCUMENT command (a module in `document.commands`) by exported id. */\nexport const runDocumentCommand = async (\n id: string,\n opts: RunCommandOptions,\n): Promise<unknown> => {\n await ensureScriptTranspiler();\n const source = opts.document.document.commands.find((s) => {\n const r = getCommandMetaResult(s);\n return r.ok && r.meta.id === id;\n });\n if (source === undefined) throw new Error(`Unknown document command \"${id}\"`);\n return runCommandModule(source, opts);\n};\n","// PNG rendering = SVG (renderSvg) rasterized with resvg. The rasterizer is a\n// NATIVE Node addon, so it is imported LAZILY: a static import would poison\n// the editor's browser bundle (which also consumes @lineadraw/core). This module\n// is therefore Node-only — call it from the SDK/CLI/server, never the editor.\n\nimport {\n renderLayoutToSvg,\n renderModelToSvg,\n type SvgRenderOptions,\n} from \"../svg/renderSvg\";\nimport type { LayoutModelContext } from \"../../paint/layoutPaint\";\nimport type { PaperLayout } from \"../../model/paperLayout\";\n\nexport interface PngRenderOptions extends SvgRenderOptions {\n /** Output width in px (height follows the aspect ratio). Default 1024. */\n width?: number;\n /** Background fill (SVG has none). Default matches the dark canvas so\n * as-authored colors stay visible; pass \"#ffffff\" / \"transparent\" to change. */\n background?: string;\n}\n\nconst rasterize = async (\n svg: string,\n width: number,\n background: string,\n): Promise<Uint8Array> => {\n // Lazy: keeps the native addon out of any browser bundle of @lineadraw/core.\n const { Resvg } = await import(\"@resvg/resvg-js\");\n const { embeddedFontFiles } = await import(\"../../fonts/embedded\");\n const resvg = new Resvg(svg, {\n fitTo: { mode: \"width\", value: Math.max(1, Math.round(width)) },\n background,\n // Bundled fonts (osifont & co. are not system fonts); system fonts stay\n // loaded so the Arial default still resolves.\n font: { fontFiles: embeddedFontFiles(), loadSystemFonts: true },\n });\n return resvg.render().asPng();\n};\n\n/** Render model space to a PNG (Node only). */\nexport const renderModelToPng = async (\n model: LayoutModelContext,\n opts: PngRenderOptions = {},\n): Promise<Uint8Array> =>\n rasterize(\n renderModelToSvg(model, opts),\n opts.width ?? 1024,\n opts.background ?? \"#1e1e1e\",\n );\n\n/** Render a paper layout to a PNG (Node only); white sheet background. */\nexport const renderLayoutToPng = async (\n layout: PaperLayout,\n model: LayoutModelContext,\n opts: PngRenderOptions = {},\n): Promise<Uint8Array> =>\n rasterize(\n renderLayoutToSvg(layout, model, opts),\n opts.width ?? 1024,\n opts.background ?? \"#ffffff\",\n );\n"],"mappings":"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","names":["angle","n","n","n","z","z","scale","pt","scale","rot","left","add","n","near","segments","add","n","scale","n","mid","w","dist","total","len","n","num","n","inheritLayerIds","n","num","len","textHeight","n","scale","mid","len","_","unit","rot","angle","n","rot","c","n","z","z","z","z","def","unit","add","scale","n","z","z","n","z","z","layerId","objectIds","n","scale","angle","embeddedFontFiles"]}
|