@stocksharp/diagram 1.2.2 → 1.3.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.
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/headless.ts", "../src/svg-surface.ts", "../src/color.ts", "../src/core/json.ts", "../src/core/model.ts", "../src/core/document.ts", "../src/core/history.ts", "../src/core/state.ts", "../src/canvas-renderer.ts"],
4
- "sourcesContent": ["import { Diagram, type DiagramScreenshotOptions } from './canvas-renderer.js';\nimport { parseDiagramDocument } from './core/document.js';\n\n/**\n * Drawing a diagram where there is no browser -- a server producing a picture for a chat message, an\n * e-mail or a report. The renderer itself never needed one: it draws through a surface, and the SVG\n * surface builds a string. What needed a browser was the control around it, which creates a canvas and\n * listens for pointers; so the few things it reaches for are stood in for here, for the length of one\n * drawing, and taken away again.\n *\n * Text is measured by the SVG surface's own estimate rather than by a real font, so a label's box can sit\n * a pixel or two off where a browser would put it. The alternative is a native canvas dependency on every\n * machine that renders, which is a steep price for that.\n */\nexport interface HeadlessRenderOptions extends DiagramScreenshotOptions {\n /** Width of the frame the drawing is laid out in, in CSS pixels. Defaults to 1200. */\n hostWidth?: number;\n /** Height of that frame. Defaults to 800. */\n hostHeight?: number;\n}\n\n/** A 2D context that answers every call and remembers nothing: the drawing goes to the SVG surface. */\nfunction createContext(): CanvasRenderingContext2D {\n const own = {\n globalAlpha: 1,\n measureText: (text: string) => ({ width: text.length * 7 }),\n };\n\n return new Proxy(own, {\n get: (target, property) => property in target ? target[property as keyof typeof own] : () => undefined,\n set: (target, property, value) => {\n (target as Record<PropertyKey, unknown>)[property] = value;\n return true;\n },\n }) as unknown as CanvasRenderingContext2D;\n}\n\nclass StubElement {\n style: Record<string, string> = {};\n className = '';\n tabIndex = 0;\n width = 0;\n height = 0;\n textContent = '';\n readonly children: StubElement[] = [];\n readonly classList = { toggle: () => false, add: () => undefined, remove: () => undefined };\n\n private readonly context = createContext();\n\n appendChild<T extends StubElement>(child: T): T {\n this.children.push(child);\n return child;\n }\n\n removeChild(child: StubElement): StubElement {\n const at = this.children.indexOf(child);\n if (at >= 0) this.children.splice(at, 1);\n return child;\n }\n\n remove(): void { /* detached already */ }\n setAttribute(): void { /* nothing reads it here */ }\n focus(): void { /* no focus without a browser */ }\n addEventListener(): void { /* nothing to fire the events */ }\n removeEventListener(): void { /* see above */ }\n getContext(): CanvasRenderingContext2D { return this.context; }\n\n getBoundingClientRect(): DOMRect {\n return { left: 0, top: 0, right: this.width, bottom: this.height, width: this.width, height: this.height, x: 0, y: 0, toJSON: () => ({}) } as DOMRect;\n }\n\n get clientWidth(): number { return this.width; }\n get clientHeight(): number { return this.height; }\n}\n\nconst GLOBAL_KEYS = ['window', 'document', 'requestAnimationFrame', 'cancelAnimationFrame', 'Image', 'getComputedStyle', 'performance'] as const;\n\n/** Puts the stubs in place, and hands back the function that removes exactly what it added. */\nfunction installGlobals(): () => void {\n const target = globalThis as Record<string, unknown>;\n\n if (target.document !== undefined)\n return () => undefined;\n\n const before = new Map<string, unknown>();\n for (const key of GLOBAL_KEYS) before.set(key, target[key]);\n\n const stubDocument = Object.assign(new StubElement(), {\n documentElement: new StubElement(),\n createElement: () => new StubElement(),\n });\n\n Object.assign(target, {\n window: Object.assign(new StubElement(), { devicePixelRatio: 1 }),\n document: stubDocument,\n requestAnimationFrame: () => 1,\n cancelAnimationFrame: () => undefined,\n Image: class { },\n getComputedStyle: () => ({ getPropertyValue: () => '' }),\n // A host without a browser may have no clock either -- an embedded JS engine has none. The drawing\n // reads it for animation, and a still picture has no animation to advance.\n performance: (globalThis as { performance?: { now(): number } }).performance ?? { now: () => 0 },\n });\n\n return () => {\n for (const [key, value] of before) {\n if (value === undefined) delete target[key];\n else target[key] = value;\n }\n };\n}\n\n/**\n * Draws a saved diagram and returns the SVG for it. The source is the document as text or as an object;\n * the frame follows the content by default, since a picture made without a viewport has none to crop to.\n */\nexport function renderDiagramSvg(source: string | unknown, options: HeadlessRenderOptions = {}): string {\n const { hostWidth = 1200, hostHeight = 800, ...screenshot } = options;\n const restore = installGlobals();\n\n try {\n const host = new StubElement();\n host.width = hostWidth;\n host.height = hostHeight;\n\n const diagram = new Diagram({ host: host as unknown as HTMLElement });\n\n try {\n // Whatever shape it arrived in -- text off the wire, an object already in hand -- the library's\n // own reader decides what a document is.\n diagram.loadDocument(parseDiagramDocument(source));\n return diagram.takeSvg({ scope: 'content', ...screenshot });\n } finally {\n diagram.destroy();\n }\n } finally {\n restore();\n }\n}\n", "import type { DrawSurface } from './draw-surface.js';\n\n/**\n * A DrawSurface that writes SVG instead of pixels.\n *\n * The renderer is not aware of it: it issues the same calls it issues to a 2D context, and they are\n * recorded as elements rather than painted. That is the whole point -- one renderer, so the vector\n * output cannot drift from what the screen shows.\n *\n * Canvas semantics are followed rather than approximated, because the difference is visible:\n * - a transform is baked into each element as a matrix, so nesting never has to be reconstructed;\n * - arcTo is resolved the way canvas resolves it (tangent point, then a real arc), which is what\n * draws every rounded node corner;\n * - arc emits the leading straight segment canvas draws when a subpath is already open, and\n * splits a full circle in two, since a single SVG arc cannot close on itself;\n * - text metrics come from a real 2D context, so glyphs land where the on-screen layout put them.\n */\n\ntype Matrix = [number, number, number, number, number, number]; // a b c d e f\n\nconst IDENTITY: Matrix = [1, 0, 0, 1, 0, 0];\n\nfunction multiply(m: Matrix, n: Matrix): Matrix {\n return [\n m[0] * n[0] + m[2] * n[1],\n m[1] * n[0] + m[3] * n[1],\n m[0] * n[2] + m[2] * n[3],\n m[1] * n[2] + m[3] * n[3],\n m[0] * n[4] + m[2] * n[5] + m[4],\n m[1] * n[4] + m[3] * n[5] + m[5],\n ];\n}\n\nfunction isIdentity(m: Matrix): boolean {\n return m[0] === 1 && m[1] === 0 && m[2] === 0 && m[3] === 1 && m[4] === 0 && m[5] === 0;\n}\n\n/** Trims float noise: coordinates carry three decimals, which is finer than any renderer needs. */\nfunction n(value: number): string {\n if (!Number.isFinite(value)) return '0';\n return (Math.round(value * 1000) / 1000).toString();\n}\n\nfunction escapeXml(value: string): string {\n return value\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\"/g, '&quot;');\n}\n\ninterface SurfaceState {\n fillStyle: string;\n strokeStyle: string;\n lineWidth: number;\n lineJoin: CanvasLineJoin;\n lineCap: CanvasLineCap;\n globalAlpha: number;\n font: string;\n textAlign: CanvasTextAlign;\n textBaseline: CanvasTextBaseline;\n dash: readonly number[];\n matrix: Matrix;\n clipId: string | null;\n}\n\nconst ANCHOR: Record<string, string> = {\n left: 'start', start: 'start',\n center: 'middle',\n right: 'end', end: 'end',\n};\n\n// dominant-baseline rather than alignment-baseline: it is the one browsers and renderers agree on\n// for <text>, and these four are the values the renderer actually sets.\nconst BASELINE: Record<string, string> = {\n top: 'text-before-edge',\n hanging: 'hanging',\n middle: 'central',\n alphabetic: 'alphabetic',\n ideographic: 'ideographic',\n bottom: 'text-after-edge',\n};\n\nexport interface SvgSurfaceOptions {\n width: number;\n height: number;\n /** Painted as a full-size rect before anything else. Omit to leave the drawing transparent. */\n background?: string;\n /** Borrowed only for measureText; the SVG never draws on it. */\n metrics?: CanvasRenderingContext2D;\n}\n\nexport class SvgSurface implements DrawSurface {\n private readonly width: number;\n private readonly height: number;\n private readonly background: string | undefined;\n private readonly metrics: CanvasRenderingContext2D | null;\n\n private readonly body: string[] = [];\n private readonly defs: string[] = [];\n private readonly stack: SurfaceState[] = [];\n\n private state: SurfaceState = {\n fillStyle: '#000000',\n strokeStyle: '#000000',\n lineWidth: 1,\n lineJoin: 'miter',\n lineCap: 'butt',\n globalAlpha: 1,\n font: '10px sans-serif',\n textAlign: 'start',\n textBaseline: 'alphabetic',\n dash: [],\n matrix: IDENTITY,\n clipId: null,\n };\n\n /** Path being built by moveTo/lineTo/arc/arcTo, in the units the caller passes. */\n private path: string[] = [];\n private cursor: [number, number] | null = null;\n private subpathStart: [number, number] | null = null;\n private clipSeq = 0;\n\n constructor(options: SvgSurfaceOptions) {\n this.width = options.width;\n this.height = options.height;\n this.background = options.background;\n this.metrics = options.metrics ?? null;\n }\n\n // ===== state =========================================================\n\n get fillStyle(): string | CanvasGradient | CanvasPattern { return this.state.fillStyle; }\n set fillStyle(value: string | CanvasGradient | CanvasPattern) {\n // Gradients and patterns are canvas objects with no serialisable form here. The renderer\n // uses plain colours; anything else is left as the previous colour rather than guessed at.\n if (typeof value === 'string') this.state.fillStyle = value;\n }\n\n get strokeStyle(): string | CanvasGradient | CanvasPattern { return this.state.strokeStyle; }\n set strokeStyle(value: string | CanvasGradient | CanvasPattern) {\n if (typeof value === 'string') this.state.strokeStyle = value;\n }\n\n get lineWidth(): number { return this.state.lineWidth; }\n set lineWidth(value: number) { this.state.lineWidth = value; }\n\n get lineJoin(): CanvasLineJoin { return this.state.lineJoin; }\n set lineJoin(value: CanvasLineJoin) { this.state.lineJoin = value; }\n\n get lineCap(): CanvasLineCap { return this.state.lineCap; }\n set lineCap(value: CanvasLineCap) { this.state.lineCap = value; }\n\n get globalAlpha(): number { return this.state.globalAlpha; }\n set globalAlpha(value: number) { this.state.globalAlpha = value; }\n\n get font(): string { return this.state.font; }\n set font(value: string) {\n this.state.font = value;\n if (this.metrics !== null) this.metrics.font = value;\n }\n\n get textAlign(): CanvasTextAlign { return this.state.textAlign; }\n set textAlign(value: CanvasTextAlign) { this.state.textAlign = value; }\n\n get textBaseline(): CanvasTextBaseline { return this.state.textBaseline; }\n set textBaseline(value: CanvasTextBaseline) { this.state.textBaseline = value; }\n\n save(): void {\n this.stack.push({ ...this.state, dash: [...this.state.dash], matrix: [...this.state.matrix] as Matrix });\n }\n\n restore(): void {\n const previous = this.stack.pop();\n if (previous !== undefined) this.state = previous;\n }\n\n setLineDash(segments: readonly number[]): void {\n this.state.dash = [...segments];\n }\n\n // ===== transform =====================================================\n\n setTransform(a: number, b: number, c: number, d: number, e: number, f: number): void {\n this.state.matrix = [a, b, c, d, e, f];\n }\n\n translate(x: number, y: number): void {\n this.state.matrix = multiply(this.state.matrix, [1, 0, 0, 1, x, y]);\n }\n\n rotate(angle: number): void {\n const cos = Math.cos(angle);\n const sin = Math.sin(angle);\n this.state.matrix = multiply(this.state.matrix, [cos, sin, -sin, cos, 0, 0]);\n }\n\n // ===== paths =========================================================\n\n beginPath(): void {\n this.path = [];\n this.cursor = null;\n this.subpathStart = null;\n }\n\n closePath(): void {\n if (this.cursor === null) return;\n this.path.push('Z');\n if (this.subpathStart !== null) this.cursor = [...this.subpathStart] as [number, number];\n }\n\n moveTo(x: number, y: number): void {\n this.path.push(`M${n(x)} ${n(y)}`);\n this.cursor = [x, y];\n this.subpathStart = [x, y];\n }\n\n lineTo(x: number, y: number): void {\n if (this.cursor === null) { this.moveTo(x, y); return; }\n this.path.push(`L${n(x)} ${n(y)}`);\n this.cursor = [x, y];\n }\n\n arc(cx: number, cy: number, r: number, start: number, end: number, ccw = false): void {\n const sx = cx + r * Math.cos(start);\n const sy = cy + r * Math.sin(start);\n\n // Canvas joins an open subpath to the arc's first point with a straight line.\n if (this.cursor === null) this.moveTo(sx, sy);\n else this.lineTo(sx, sy);\n\n let delta = end - start;\n\n if (ccw) {\n while (delta > 0) delta -= Math.PI * 2;\n if (delta <= -Math.PI * 2) delta = -Math.PI * 2;\n } else {\n while (delta < 0) delta += Math.PI * 2;\n if (delta >= Math.PI * 2) delta = Math.PI * 2;\n }\n\n const sweep = ccw ? 0 : 1;\n\n // A single SVG arc cannot end where it began, so a full turn is drawn as two halves.\n if (Math.abs(delta) >= Math.PI * 2 - 1e-9) {\n const mid = start + delta / 2;\n const mx = cx + r * Math.cos(mid);\n const my = cy + r * Math.sin(mid);\n this.path.push(`A${n(r)} ${n(r)} 0 0 ${sweep} ${n(mx)} ${n(my)}`);\n this.path.push(`A${n(r)} ${n(r)} 0 0 ${sweep} ${n(sx)} ${n(sy)}`);\n this.cursor = [sx, sy];\n return;\n }\n\n const ex = cx + r * Math.cos(start + delta);\n const ey = cy + r * Math.sin(start + delta);\n const large = Math.abs(delta) > Math.PI ? 1 : 0;\n\n this.path.push(`A${n(r)} ${n(r)} 0 ${large} ${sweep} ${n(ex)} ${n(ey)}`);\n this.cursor = [ex, ey];\n }\n\n arcTo(x1: number, y1: number, x2: number, y2: number, r: number): void {\n if (this.cursor === null) { this.moveTo(x1, y1); return; }\n\n const [x0, y0] = this.cursor;\n\n // Canvas degenerates to a straight line when there is no corner to round.\n const a = [x0 - x1, y0 - y1];\n const b = [x2 - x1, y2 - y1];\n const la = Math.hypot(a[0], a[1]);\n const lb = Math.hypot(b[0], b[1]);\n\n if (la === 0 || lb === 0 || r === 0) { this.lineTo(x1, y1); return; }\n\n const ua = [a[0] / la, a[1] / la];\n const ub = [b[0] / lb, b[1] / lb];\n const cross = ua[0] * ub[1] - ua[1] * ub[0];\n\n if (Math.abs(cross) < 1e-9) { this.lineTo(x1, y1); return; } // collinear\n\n const angle = Math.acos(Math.max(-1, Math.min(1, ua[0] * ub[0] + ua[1] * ub[1])));\n const tangent = r / Math.tan(angle / 2);\n\n // The corner cannot swallow more than the shorter arm.\n const t = Math.min(tangent, la, lb);\n const radius = t * Math.tan(angle / 2);\n\n const t1 = [x1 + ua[0] * t, y1 + ua[1] * t];\n const t2 = [x1 + ub[0] * t, y1 + ub[1] * t];\n\n this.lineTo(t1[0], t1[1]);\n\n // Turning left in screen coordinates (y down) is a counter-clockwise sweep.\n const sweep = cross < 0 ? 1 : 0;\n this.path.push(`A${n(radius)} ${n(radius)} 0 0 ${sweep} ${n(t2[0])} ${n(t2[1])}`);\n this.cursor = [t2[0], t2[1]];\n }\n\n fill(): void {\n if (this.path.length === 0) return;\n this.emit(`<path d=\"${this.path.join(' ')}\" ${this.fillAttrs()}/>`);\n }\n\n stroke(): void {\n if (this.path.length === 0) return;\n this.emit(`<path d=\"${this.path.join(' ')}\" fill=\"none\" ${this.strokeAttrs()}/>`);\n }\n\n clip(): void {\n if (this.path.length === 0) return;\n\n const id = `clip${++this.clipSeq}`;\n this.defs.push(`<clipPath id=\"${id}\"><path d=\"${this.path.join(' ')}\"/></clipPath>`);\n this.state.clipId = id;\n }\n\n // ===== rectangles ====================================================\n\n clearRect(x: number, y: number, w: number, h: number): void {\n // Nothing to clear in a document that is built up rather than painted over: SVG has no\n // eraser, and the first thing written is the background anyway.\n void x; void y; void w; void h;\n }\n\n fillRect(x: number, y: number, w: number, h: number): void {\n this.emit(`<rect x=\"${n(x)}\" y=\"${n(y)}\" width=\"${n(w)}\" height=\"${n(h)}\" ${this.fillAttrs()}/>`);\n }\n\n strokeRect(x: number, y: number, w: number, h: number): void {\n this.emit(`<rect x=\"${n(x)}\" y=\"${n(y)}\" width=\"${n(w)}\" height=\"${n(h)}\" fill=\"none\" ${this.strokeAttrs()}/>`);\n }\n\n // ===== text ==========================================================\n\n fillText(text: string, x: number, y: number, maxWidth?: number): void {\n if (text === '') return;\n\n const anchor = ANCHOR[this.state.textAlign] ?? 'start';\n const baseline = BASELINE[this.state.textBaseline] ?? 'alphabetic';\n\n // Canvas squeezes the glyphs to fit maxWidth; SVG needs to be told, and only when the text\n // would actually overflow -- textLength on text that already fits would stretch it.\n // Dropping the argument left node titles and zone captions running past the box the\n // renderer had sized for them, so the vector export disagreed with the raster one.\n let constraint = '';\n if (maxWidth !== undefined && maxWidth > 0 && this.measureText(text).width > maxWidth) {\n constraint = ` textLength=\"${n(maxWidth)}\" lengthAdjust=\"spacingAndGlyphs\"`;\n }\n\n // The canvas font string is CSS font shorthand, so it transfers verbatim -- no parsing, and\n // no chance of losing the weight or the fallback list on the way.\n this.emit(\n `<text x=\"${n(x)}\" y=\"${n(y)}\" style=\"font:${escapeXml(this.state.font)}\" ` +\n `text-anchor=\"${anchor}\" dominant-baseline=\"${baseline}\"${constraint} ${this.fillAttrs()}>` +\n `${escapeXml(text)}</text>`);\n }\n\n measureText(text: string): { width: number } {\n if (this.metrics !== null) return { width: this.metrics.measureText(text).width };\n\n // Without a context to ask, a rough advance keeps layout sane rather than collapsing to\n // zero and stacking every label at one point.\n const size = parseFloat(this.state.font) || 10;\n return { width: text.length * size * 0.55 };\n }\n\n // ===== images ========================================================\n\n drawImage(image: CanvasImageSource, dx: number, dy: number, dw: number, dh: number): void {\n const href = this.imageHref(image);\n if (href === null) return;\n\n this.emit(`<image x=\"${n(dx)}\" y=\"${n(dy)}\" width=\"${n(dw)}\" height=\"${n(dh)}\" href=\"${escapeXml(href)}\"${this.commonAttrs()}/>`);\n }\n\n private imageHref(image: CanvasImageSource): string | null {\n try {\n if (typeof HTMLCanvasElement !== 'undefined' && image instanceof HTMLCanvasElement) return image.toDataURL();\n if (typeof HTMLImageElement !== 'undefined' && image instanceof HTMLImageElement) return image.src;\n } catch {\n // A canvas tainted by a cross-origin draw refuses toDataURL. Dropping the image beats\n // failing the whole export for one picture.\n return null;\n }\n return null;\n }\n\n // ===== output ========================================================\n\n /** The finished document. Safe to call more than once; it does not consume the recording. */\n toSvg(): string {\n const background = this.background === undefined\n ? ''\n : `<rect width=\"100%\" height=\"100%\" fill=\"${escapeXml(this.background)}\"/>`;\n\n const defs = this.defs.length === 0 ? '' : `<defs>${this.defs.join('')}</defs>`;\n\n return `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"${n(this.width)}\" height=\"${n(this.height)}\" ` +\n `viewBox=\"0 0 ${n(this.width)} ${n(this.height)}\">` +\n `${defs}${background}${this.body.join('')}</svg>`;\n }\n\n // ===== internals =====================================================\n\n private emit(element: string): void {\n this.body.push(element);\n }\n\n private commonAttrs(): string {\n const parts: string[] = [];\n\n if (!isIdentity(this.state.matrix)) {\n parts.push(` transform=\"matrix(${this.state.matrix.map(n).join(' ')})\"`);\n }\n\n if (this.state.globalAlpha !== 1) parts.push(` opacity=\"${n(this.state.globalAlpha)}\"`);\n if (this.state.clipId !== null) parts.push(` clip-path=\"url(#${this.state.clipId})\"`);\n\n return parts.join('');\n }\n\n private fillAttrs(): string {\n return `fill=\"${escapeXml(this.state.fillStyle)}\"${this.commonAttrs()}`;\n }\n\n private strokeAttrs(): string {\n const parts = [\n `stroke=\"${escapeXml(this.state.strokeStyle)}\"`,\n `stroke-width=\"${n(this.state.lineWidth)}\"`,\n ];\n\n if (this.state.lineJoin !== 'miter') parts.push(`stroke-linejoin=\"${this.state.lineJoin}\"`);\n if (this.state.lineCap !== 'butt') parts.push(`stroke-linecap=\"${this.state.lineCap}\"`);\n if (this.state.dash.length > 0) parts.push(`stroke-dasharray=\"${this.state.dash.map(n).join(' ')}\"`);\n\n return parts.join(' ') + this.commonAttrs();\n }\n}\n", "// Colour arithmetic shared by the parts that have to stay readable against a\n// fill they do not choose: the embed host reading a page's background, and the\n// renderer drawing a title on a node whose colour comes from the scheme.\n\nconst CSS_COLOR_KEYWORDS: Readonly<Record<string, [number, number, number]>> = {\n\twhite: [255, 255, 255],\n\tblack: [0, 0, 0],\n\ttransparent: [255, 255, 255],\n};\n\n/**\n * Channels of a CSS colour, or null when it cannot be read.\n *\n * Understands the keywords above, three-, six- and eight-digit hex (the alpha is\n * ignored), and rgb()/rgba() in both the comma and the space syntax.\n */\nfunction parseRgb(color: string): [number, number, number] | null {\n\tconst value = color.trim().toLowerCase();\n\tif (value === '')\n\t\treturn null;\n\n\tconst keyword = CSS_COLOR_KEYWORDS[value];\n\tif (keyword !== undefined)\n\t\treturn [...keyword];\n\n\tconst long = value.match(/^#?([0-9a-f]{6})$/);\n\tif (long !== null) {\n\t\tconst n = parseInt(long[1], 16);\n\t\treturn [(n >> 16) & 255, (n >> 8) & 255, n & 255];\n\t}\n\n\t// #abc is shorthand for #aabbcc, and the eight-digit forms carry an alpha we ignore.\n\tconst short = value.match(/^#?([0-9a-f]{3})([0-9a-f])?$/);\n\tif (short !== null) {\n\t\tconst [r, g, b] = [...short[1]].map((digit) => parseInt(digit + digit, 16));\n\t\treturn [r, g, b];\n\t}\n\n\tconst long8 = value.match(/^#?([0-9a-f]{6})[0-9a-f]{2}$/);\n\tif (long8 !== null) {\n\t\tconst n = parseInt(long8[1], 16);\n\t\treturn [(n >> 16) & 255, (n >> 8) & 255, n & 255];\n\t}\n\n\tconst rgb = value.match(/^rgba?\\(([^)]+)\\)$/);\n\tif (rgb !== null) {\n\t\tconst parts = rgb[1].split(/[\\s,/]+/).filter((part) => part !== '');\n\t\tif (parts.length >= 3) {\n\t\t\tconst [r, g, b] = parts.slice(0, 3).map((part) => part.endsWith('%')\n\t\t\t\t? (parseFloat(part) / 100) * 255\n\t\t\t\t: parseFloat(part));\n\t\t\tif ([r, g, b].every((channel) => Number.isFinite(channel)))\n\t\t\t\treturn [r, g, b];\n\t\t}\n\t}\n\n\treturn null;\n}\n\n/**\n * Perceived brightness of a CSS colour, or -1 when it cannot be read.\n *\n * Six-digit hex was the only form understood, and everything else answered 0 -- black. A page\n * writing --diagram-bg as #fff, white or rgb(255 255 255) therefore had its white canvas\n * classified as dark and got the dark link palette: near-white wires on a near-white background.\n * Unreadable is now -1 rather than 0, so the caller can keep its own default instead of being\n * told the page is black.\n */\nexport function luminance(color: string): number {\n\tconst rgb = parseRgb(color);\n\tif (rgb === null)\n\t\treturn -1;\n\n\tconst [r, g, b] = rgb;\n\treturn 0.299 * r + 0.587 * g + 0.114 * b;\n}\n\nconst DARK_TEXT = '#1b1b1b';\nconst LIGHT_TEXT = '#f5f5f5';\n\n/// One channel on the scale contrast is measured on, where equal steps look\n/// equally different rather than merely being equal numbers.\nfunction toLinear(channel: number): number {\n\tconst v = channel / 255;\n\treturn v <= 0.03928 ? v / 12.92 : Math.pow((v + 0.055) / 1.055, 2.4);\n}\n\n/// Relative luminance as WCAG defines it, or -1 for a colour that cannot be read.\nfunction relativeLuminance(color: string): number {\n\tconst rgb = parseRgb(color);\n\tif (rgb === null)\n\t\treturn -1;\n\n\tconst [r, g, b] = rgb;\n\treturn 0.2126 * toLinear(r) + 0.7152 * toLinear(g) + 0.0722 * toLinear(b);\n}\n\n/// WCAG contrast ratio between two relative luminances: 1 for identical, 21 for\n/// black against white.\nfunction contrast(a: number, b: number): number {\n\tconst [lighter, darker] = a > b ? [a, b] : [b, a];\n\treturn (lighter + 0.05) / (darker + 0.05);\n}\n\n/// Title colour for a body filled with `fill`.\n///\n/// A node's fill comes from the scheme rather than the theme, so it can be any\n/// colour, and a title fixed to one shade disappears as soon as a node is filled\n/// close to it. Rather than split the range at a brightness someone has to pick,\n/// this measures both candidates against the fill and takes whichever stands out\n/// more. That is also why a saturated orange keeps its dark title where a plain\n/// brightness test, which reads such a colour as darker than it looks, flips it.\n///\n/// A fill this cannot read keeps the dark title: every node shipped so far is\n/// light, so guessing light text would fail on more of them than it fixes.\nexport function readableTextOn(fill: string): string {\n\tconst background = relativeLuminance(fill);\n\tif (background < 0)\n\t\treturn DARK_TEXT;\n\n\treturn contrast(background, relativeLuminance(LIGHT_TEXT))\n\t\t> contrast(background, relativeLuminance(DARK_TEXT))\n\t\t? LIGHT_TEXT\n\t\t: DARK_TEXT;\n}\n", "/**\n * Stores a key that JSON can legitimately carry but plain assignment cannot hold.\n *\n * `JSON.parse` produces `__proto__` as an ordinary own key, yet writing it back\n * with `target[key] = value` hits the inherited `__proto__` setter: the value is\n * dropped and the object's prototype is replaced instead. A document parsed that\n * way loses data and stops satisfying the parser's own \"plain object\" guard, so\n * anything the parser accepted could no longer be serialized or cloned.\n */\nexport function setJsonKey<T>(target: Record<string, T>, key: string, value: T): void {\n if (key === '__proto__') {\n Object.defineProperty(target, key, { value, enumerable: true, writable: true, configurable: true });\n return;\n }\n target[key] = value;\n}\n\n/**\n * The read that matches setJsonKey.\n *\n * `target[key]` for `__proto__` answers with the inherited prototype rather than the entry, so a\n * plain lookup reports a value for a key that was never stored -- and callers that fall back on\n * `?? create()` never do, then use `Object.prototype` as if it were their own record.\n */\nexport function getJsonKey<T>(target: Record<string, T>, key: string): T | undefined {\n return Object.prototype.hasOwnProperty.call(target, key) ? target[key] : undefined;\n}\n", "export type JsonPrimitive = string | number | boolean | null;\nexport type JsonValue = JsonPrimitive | JsonObject | JsonValue[];\n\nexport interface JsonObject {\n [key: string]: JsonValue;\n}\n\nexport interface DiagramParameterSchema {\n name: string;\n displayName: string;\n description: string;\n type: string;\n defaultValue: string;\n options: string[];\n min: number | null;\n max: number | null;\n displayOrder: number;\n category: string;\n isBasic: boolean;\n editorType: string;\n}\n\n/**\n * How a dynamic port grows. Only 'onConnect' makes the editor add a typed\n * sibling when a link lands on the port; '' and 'manual' leave it to the host.\n * The renderer compares this with ===, so a value outside the set silently\n * selects the do-nothing branch -- hence a union rather than a string.\n */\nexport type PortDynamicMode = '' | 'manual' | 'onConnect';\n\n/** Narrows an untyped value to the closed set, defaulting to the inert mode. */\nexport function toPortDynamicMode(value: unknown): PortDynamicMode {\n return value === 'manual' || value === 'onConnect' ? value : '';\n}\n\nexport interface DiagramDocumentPort {\n id: string;\n name: string;\n description: string;\n type: string;\n maxLinks: number;\n availableTypes: string[];\n isDynamic: boolean;\n dynamicMode: PortDynamicMode;\n isSibling: boolean;\n metadata: JsonObject;\n}\n\nexport interface DiagramDocumentNode {\n id: string;\n typeId: string;\n name: string;\n description: string;\n groupName: string;\n x: number;\n y: number;\n color: string;\n border: string;\n icon: string;\n /** Persistent host text. Runtime and load errors belong to DiagramRuntimeState. */\n message: string;\n openAction: string;\n inPorts: DiagramDocumentPort[];\n outPorts: DiagramDocumentPort[];\n parameters: DiagramParameterSchema[];\n paramValues: Record<string, string>;\n metadata: JsonObject;\n}\n\nexport interface DiagramDocumentEndpoint {\n nodeId: string;\n portId: string;\n}\n\n/**\n * How a link is drawn. A dashed link reads as one that may or may not be there -\n * an optional hop, a path taken only in some deployments - which a solid line\n * cannot say. The renderer compares this with ===, so a value outside the set\n * would silently fall through to solid; hence a union rather than a string.\n */\nexport type DiagramLinkStyle = 'solid' | 'dashed';\n\n/** Narrows an untyped value to the closed set, defaulting to a plain line. */\nexport function toDiagramLinkStyle(value: unknown): DiagramLinkStyle {\n return value === 'dashed' ? 'dashed' : 'solid';\n}\n\nexport interface DiagramDocumentLink {\n /** Stable identity used by selection, relinking and history. */\n id: string;\n from: DiagramDocumentEndpoint;\n to: DiagramDocumentEndpoint;\n style: DiagramLinkStyle;\n metadata: JsonObject;\n}\n\n/**\n * A labelled rectangle drawn behind the nodes. It says where things are rather\n * than what they do - a colocation cage, a tenant boundary, a process - which no\n * arrangement of nodes and links can state on its own. A zone owns nothing: the\n * nodes that sit on it are not its children, so moving one changes no membership.\n */\nexport interface DiagramDocumentZone {\n id: string;\n name: string;\n x: number;\n y: number;\n width: number;\n height: number;\n /** Empty means the renderer picks its own neutral tint. */\n color: string;\n metadata: JsonObject;\n}\n\nexport const DIAGRAM_DOCUMENT_VERSION = 1 as const;\nexport type DiagramDocumentVersion = typeof DIAGRAM_DOCUMENT_VERSION;\n\nexport interface DiagramDocument {\n version: DiagramDocumentVersion;\n nodes: DiagramDocumentNode[];\n links: DiagramDocumentLink[];\n zones: DiagramDocumentZone[];\n metadata: JsonObject;\n}\n\nexport type DiagramDocumentPortInput = Pick<DiagramDocumentPort, 'id' | 'name'>\n & Partial<Omit<DiagramDocumentPort, 'id' | 'name'>>;\n\nexport type DiagramDocumentNodeInput = Pick<DiagramDocumentNode, 'id' | 'name'>\n & Partial<Omit<DiagramDocumentNode, 'id' | 'name' | 'inPorts' | 'outPorts'>>\n & {\n inPorts?: readonly DiagramDocumentPortInput[];\n outPorts?: readonly DiagramDocumentPortInput[];\n };\n\nexport type DiagramDocumentLinkInput = Omit<DiagramDocumentLink, 'id' | 'style' | 'metadata'> & {\n id?: string;\n style?: DiagramLinkStyle;\n metadata?: JsonObject;\n};\n\nexport type DiagramDocumentZoneInput = Omit<DiagramDocumentZone, 'color' | 'metadata'> & {\n color?: string;\n metadata?: JsonObject;\n};\n\nexport interface DiagramDocumentInput {\n nodes?: readonly DiagramDocumentNodeInput[];\n links?: readonly DiagramDocumentLinkInput[];\n zones?: readonly DiagramDocumentZoneInput[];\n metadata?: JsonObject;\n}\n", "import { setJsonKey } from './json.js';\nimport { toPortDynamicMode } from './model.js';\nimport {\n DIAGRAM_DOCUMENT_VERSION,\n type DiagramDocument,\n type DiagramDocumentEndpoint,\n type DiagramDocumentInput,\n type DiagramDocumentLink,\n type DiagramLinkStyle,\n type DiagramDocumentNode,\n type DiagramDocumentPort,\n type DiagramDocumentZone,\n type DiagramParameterSchema,\n type PortDynamicMode,\n type JsonObject,\n type JsonValue,\n} from './model.js';\n\nexport { DIAGRAM_DOCUMENT_VERSION } from './model.js';\nexport type {\n DiagramDocument,\n DiagramDocumentEndpoint,\n DiagramDocumentInput,\n DiagramDocumentLink,\n DiagramDocumentLinkInput,\n DiagramLinkStyle,\n DiagramDocumentNode,\n DiagramDocumentNodeInput,\n DiagramDocumentPort,\n DiagramDocumentPortInput,\n DiagramDocumentZone,\n DiagramDocumentZoneInput,\n DiagramDocumentVersion,\n DiagramParameterSchema,\n JsonObject,\n JsonPrimitive,\n JsonValue,\n} from './model.js';\n\nexport class DiagramDocumentError extends Error {\n constructor(message: string, readonly path: string = '$') {\n super(`${path}: ${message}`);\n this.name = 'DiagramDocumentError';\n }\n}\n\nexport function createDiagramDocument(input: DiagramDocumentInput = {}): DiagramDocument {\n // DiagramDocumentInput is a structural interface, so its shape is a claim by\n // the caller, not a guarantee. Elements are checked the same way parsed ones\n // are, otherwise a malformed one surfaces as a TypeError naming no path.\n const rawNodes = mapElements(input.nodes, '$.nodes');\n const rawLinks = mapElements(input.links, '$.links');\n const nodes = rawNodes.map((node, index) => normalizeNode(node, `$.nodes[${index}]`));\n const usedLinkIds = new Set<string>();\n\n for (let index = 0; index < rawLinks.length; index++) {\n const raw = rawLinks[index].id;\n if (raw === undefined) continue;\n const id = requireIdentifier(raw, `$.links[${index}].id`);\n if (usedLinkIds.has(id)) {\n throw new DiagramDocumentError(`duplicate link id \"${id}\"`, `$.links[${index}].id`);\n }\n usedLinkIds.add(id);\n }\n\n let sequence = 1;\n const links = rawLinks.map((link, index) => {\n let id = link.id;\n if (id === undefined) {\n let generated: string;\n do generated = `link_${sequence++}`;\n while (usedLinkIds.has(generated));\n usedLinkIds.add(generated);\n id = generated;\n }\n return normalizeLink({ ...link, id }, `$.links[${index}]`);\n });\n const rawZones = mapElements(input.zones, '$.zones');\n const zones = rawZones.map((zone, index) => normalizeZone(zone, `$.zones[${index}]`));\n validateUniqueZones(zones);\n\n const document: DiagramDocument = {\n version: DIAGRAM_DOCUMENT_VERSION,\n nodes,\n links,\n zones,\n metadata: cloneJsonObject(input.metadata ?? {}, '$.metadata'),\n };\n validateDocument(document);\n return document;\n}\n\nexport function cloneDiagramDocument(document: DiagramDocument): DiagramDocument {\n return parseDiagramDocument(document);\n}\n\nexport function serializeDiagramDocument(document: DiagramDocument, space?: number): string {\n return JSON.stringify(parseDiagramDocument(document), null, space);\n}\n\nexport function parseDiagramDocument(source: string | unknown): DiagramDocument {\n let value: unknown = source;\n if (typeof source === 'string') {\n try {\n value = JSON.parse(source) as unknown;\n } catch (error) {\n const reason = error instanceof Error ? error.message : 'invalid JSON';\n throw new DiagramDocumentError(reason);\n }\n }\n\n const root = requireStructure(value, '$');\n const version = requireNumber(root.version, '$.version');\n if (version !== DIAGRAM_DOCUMENT_VERSION) {\n throw new DiagramDocumentError(`unsupported document version ${version}`, '$.version');\n }\n const document: DiagramDocument = {\n version: DIAGRAM_DOCUMENT_VERSION,\n nodes: requireArray(root.nodes, '$.nodes').map((node, index) => parseNode(node, `$.nodes[${index}]`)),\n links: requireArray(root.links, '$.links').map((link, index) => parseLink(link, `$.links[${index}]`)),\n // Zones arrived after the first documents were written, so their absence is not a fault:\n // an older file simply has none, and reading it must not need a migration step.\n zones: root.zones === undefined || root.zones === null\n ? []\n : requireArray(root.zones, '$.zones').map((zone, index) => normalizeZone(zone, `$.zones[${index}]`)),\n metadata: cloneJsonObject(root.metadata, '$.metadata'),\n };\n validateDocument(document);\n return document;\n}\n\nfunction normalizeNode(value: unknown, path: string): DiagramDocumentNode {\n const input = requireStructure(value, path);\n const id = requireIdentifier(input.id, `${path}.id`);\n return {\n id,\n typeId: requireIdentifier(input.typeId ?? id, `${path}.typeId`),\n name: requireString(input.name, `${path}.name`),\n description: requireString(input.description ?? '', `${path}.description`),\n groupName: requireString(input.groupName ?? 'Common', `${path}.groupName`),\n x: requireFiniteNumber(input.x ?? 0, `${path}.x`),\n y: requireFiniteNumber(input.y ?? 0, `${path}.y`),\n color: requireString(input.color ?? '#d7d7d7', `${path}.color`),\n border: requireString(input.border ?? '#8c8c8c', `${path}.border`),\n icon: requireString(input.icon ?? '', `${path}.icon`),\n message: requireString(input.message ?? '', `${path}.message`),\n openAction: requireString(input.openAction ?? '', `${path}.openAction`),\n inPorts: mapElements(input.inPorts, `${path}.inPorts`)\n .map((port, index) => normalizePort(port, `${path}.inPorts[${index}]`)),\n outPorts: mapElements(input.outPorts, `${path}.outPorts`)\n .map((port, index) => normalizePort(port, `${path}.outPorts[${index}]`)),\n parameters: mapElements(input.parameters, `${path}.parameters`)\n .map((parameter, index) => normalizeParameter(parameter, `${path}.parameters[${index}]`)),\n paramValues: cloneStringRecord(input.paramValues ?? {}, `${path}.paramValues`),\n metadata: cloneJsonObject(input.metadata ?? {}, `${path}.metadata`),\n };\n}\n\nfunction normalizePort(value: unknown, path: string): DiagramDocumentPort {\n const input = requireStructure(value, path);\n return {\n id: requireIdentifier(input.id, `${path}.id`),\n name: requireString(input.name, `${path}.name`),\n description: requireString(input.description ?? '', `${path}.description`),\n type: requireString(input.type ?? '', `${path}.type`),\n maxLinks: requireNonNegativeInteger(input.maxLinks ?? 0, `${path}.maxLinks`),\n availableTypes: requireArray(input.availableTypes ?? [], `${path}.availableTypes`)\n .map((type, index) => requireString(type, `${path}.availableTypes[${index}]`)),\n isDynamic: requireBoolean(input.isDynamic ?? false, `${path}.isDynamic`),\n dynamicMode: requirePortDynamicMode(input.dynamicMode ?? '', `${path}.dynamicMode`),\n isSibling: requireBoolean(input.isSibling ?? false, `${path}.isSibling`),\n metadata: cloneJsonObject(input.metadata ?? {}, `${path}.metadata`),\n };\n}\n\nfunction normalizeParameter(value: unknown, path: string): DiagramParameterSchema {\n const input = requireStructure(value, path);\n return {\n name: requireIdentifier(input.name, `${path}.name`),\n displayName: requireString(input.displayName, `${path}.displayName`),\n description: requireString(input.description, `${path}.description`),\n type: requireString(input.type, `${path}.type`),\n defaultValue: requireString(input.defaultValue, `${path}.defaultValue`),\n options: requireArray(input.options, `${path}.options`).map((option, index) => requireString(option, `${path}.options[${index}]`)),\n min: requireNullableFiniteNumber(input.min, `${path}.min`),\n max: requireNullableFiniteNumber(input.max, `${path}.max`),\n displayOrder: requireFiniteNumber(input.displayOrder, `${path}.displayOrder`),\n category: requireString(input.category, `${path}.category`),\n isBasic: requireBoolean(input.isBasic, `${path}.isBasic`),\n editorType: requireString(input.editorType, `${path}.editorType`),\n };\n}\n\nfunction normalizeLink(value: unknown, path: string): DiagramDocumentLink {\n const input = requireStructure(value, path);\n return {\n id: requireIdentifier(input.id, `${path}.id`),\n from: normalizeEndpoint(input.from, `${path}.from`),\n to: normalizeEndpoint(input.to, `${path}.to`),\n style: requireLinkStyle(input.style, `${path}.style`),\n metadata: cloneJsonObject(input.metadata ?? {}, `${path}.metadata`),\n };\n}\n\n// A style the caller misspelled is a drawing that quietly loses its meaning, so it is refused\n// rather than defaulted - unlike an absent one, which simply means a plain line.\nfunction requireLinkStyle(value: unknown, path: string): DiagramLinkStyle {\n if (value === undefined || value === null) return 'solid';\n if (value !== 'solid' && value !== 'dashed') {\n throw new DiagramDocumentError(`unknown link style \"${String(value)}\"`, path);\n }\n return value;\n}\n\nfunction normalizeZone(value: unknown, path: string): DiagramDocumentZone {\n const input = requireStructure(value, path);\n return {\n id: requireIdentifier(input.id, `${path}.id`),\n name: requireString(input.name, `${path}.name`),\n // Finite, like node coordinates: NaN survives every arithmetic check and writes as null.\n x: requireFiniteNumber(input.x, `${path}.x`),\n y: requireFiniteNumber(input.y, `${path}.y`),\n width: requirePositiveSize(input.width, `${path}.width`),\n height: requirePositiveSize(input.height, `${path}.height`),\n color: input.color === undefined || input.color === null ? '' : requireString(input.color, `${path}.color`),\n metadata: cloneJsonObject(input.metadata ?? {}, `${path}.metadata`),\n };\n}\n\n// A zone with no area cannot be pointed at, and a negative one paints outside itself, so the\n// size is refused rather than clamped - a caller that computed it wrong wants to hear about it.\nfunction requirePositiveSize(value: unknown, path: string): number {\n // Finite, not merely positive: Infinity satisfies `> 0` and then serializes to null, so the\n // document would save without complaint and fail to parse back.\n const size = requireFiniteNumber(value, path);\n if (!(size > 0)) throw new DiagramDocumentError('size must be greater than zero', path);\n return size;\n}\n\nfunction normalizeEndpoint(value: unknown, path: string): DiagramDocumentEndpoint {\n const input = requireStructure(value, path);\n return {\n nodeId: requireIdentifier(input.nodeId, `${path}.nodeId`),\n portId: requireIdentifier(input.portId, `${path}.portId`),\n };\n}\n\nfunction parseNode(value: unknown, path: string): DiagramDocumentNode {\n const node = requireStructure(value, path);\n return normalizeNode({\n id: requireString(node.id, `${path}.id`),\n typeId: requireString(node.typeId, `${path}.typeId`),\n name: requireString(node.name, `${path}.name`),\n description: requireString(node.description, `${path}.description`),\n groupName: requireString(node.groupName, `${path}.groupName`),\n x: requireNumber(node.x, `${path}.x`),\n y: requireNumber(node.y, `${path}.y`),\n color: requireString(node.color, `${path}.color`),\n border: requireString(node.border, `${path}.border`),\n icon: requireString(node.icon, `${path}.icon`),\n message: requireString(node.message, `${path}.message`),\n openAction: requireString(node.openAction, `${path}.openAction`),\n inPorts: requireArray(node.inPorts, `${path}.inPorts`).map((port, index) => parsePort(port, `${path}.inPorts[${index}]`)),\n outPorts: requireArray(node.outPorts, `${path}.outPorts`).map((port, index) => parsePort(port, `${path}.outPorts[${index}]`)),\n parameters: requireArray(node.parameters, `${path}.parameters`).map((parameter, index) => parseParameter(parameter, `${path}.parameters[${index}]`)),\n paramValues: cloneStringRecord(node.paramValues, `${path}.paramValues`),\n metadata: cloneJsonObject(node.metadata, `${path}.metadata`),\n }, path);\n}\n\nfunction parsePort(value: unknown, path: string): DiagramDocumentPort {\n const port = requireStructure(value, path);\n return normalizePort({\n id: requireString(port.id, `${path}.id`),\n name: requireString(port.name, `${path}.name`),\n description: requireString(port.description, `${path}.description`),\n type: requireString(port.type, `${path}.type`),\n maxLinks: requireNumber(port.maxLinks, `${path}.maxLinks`),\n availableTypes: requireArray(port.availableTypes, `${path}.availableTypes`).map((type, index) => requireString(type, `${path}.availableTypes[${index}]`)),\n isDynamic: requireBoolean(port.isDynamic, `${path}.isDynamic`),\n dynamicMode: requirePortDynamicMode(port.dynamicMode, `${path}.dynamicMode`),\n isSibling: requireBoolean(port.isSibling, `${path}.isSibling`),\n metadata: cloneJsonObject(port.metadata, `${path}.metadata`),\n }, path);\n}\n\nfunction parseParameter(value: unknown, path: string): DiagramParameterSchema {\n const parameter = requireStructure(value, path);\n return normalizeParameter({\n name: requireString(parameter.name, `${path}.name`),\n displayName: requireString(parameter.displayName, `${path}.displayName`),\n description: requireString(parameter.description, `${path}.description`),\n type: requireString(parameter.type, `${path}.type`),\n defaultValue: requireString(parameter.defaultValue, `${path}.defaultValue`),\n options: requireArray(parameter.options, `${path}.options`).map((option, index) => requireString(option, `${path}.options[${index}]`)),\n min: requireNullableFiniteNumber(parameter.min, `${path}.min`),\n max: requireNullableFiniteNumber(parameter.max, `${path}.max`),\n displayOrder: requireNumber(parameter.displayOrder, `${path}.displayOrder`),\n category: requireString(parameter.category, `${path}.category`),\n isBasic: requireBoolean(parameter.isBasic, `${path}.isBasic`),\n editorType: requireString(parameter.editorType, `${path}.editorType`),\n }, path);\n}\n\nfunction parseLink(value: unknown, path: string): DiagramDocumentLink {\n const link = requireStructure(value, path);\n return normalizeLink({\n id: requireString(link.id, `${path}.id`),\n from: parseEndpoint(link.from, `${path}.from`),\n to: parseEndpoint(link.to, `${path}.to`),\n style: link.style === undefined ? undefined : requireLinkStyle(link.style, `${path}.style`),\n metadata: cloneJsonObject(link.metadata, `${path}.metadata`),\n }, path);\n}\n\nfunction parseEndpoint(value: unknown, path: string): DiagramDocumentEndpoint {\n const endpoint = requireStructure(value, path);\n return {\n nodeId: requireIdentifier(endpoint.nodeId, `${path}.nodeId`),\n portId: requireIdentifier(endpoint.portId, `${path}.portId`),\n };\n}\n\n/**\n * Zone ids have to be unique wherever a document comes from. Keeping the check here, rather than\n * inside createDiagramDocument alone, is what stops a file being loadable and unsaveable: the\n * parser used to let a duplicate through and the very next saveDocument() -- which rebuilds\n * through createDiagramDocument -- threw on it.\n */\nfunction validateUniqueZones(zones: readonly DiagramDocumentZone[]): void {\n const seen = new Set<string>();\n for (let index = 0; index < zones.length; index++) {\n const zone = zones[index];\n if (seen.has(zone.id)) throw new DiagramDocumentError(`duplicate zone id \"${zone.id}\"`, `$.zones[${index}].id`);\n seen.add(zone.id);\n }\n}\n\nfunction validateDocument(document: DiagramDocument): void {\n const nodes = new Map<string, DiagramDocumentNode>();\n for (let index = 0; index < document.nodes.length; index++) {\n const node = document.nodes[index];\n if (nodes.has(node.id)) throw new DiagramDocumentError(`duplicate node id \"${node.id}\"`, `$.nodes[${index}].id`);\n validateUniquePorts(node.inPorts, `$.nodes[${index}].inPorts`);\n validateUniquePorts(node.outPorts, `$.nodes[${index}].outPorts`);\n nodes.set(node.id, node);\n }\n\n const linkIds = new Set<string>();\n const endpoints = new Set<string>();\n for (let index = 0; index < document.links.length; index++) {\n const link = document.links[index];\n const path = `$.links[${index}]`;\n if (linkIds.has(link.id)) throw new DiagramDocumentError(`duplicate link id \"${link.id}\"`, `${path}.id`);\n linkIds.add(link.id);\n const fromNode = nodes.get(link.from.nodeId);\n const toNode = nodes.get(link.to.nodeId);\n if (fromNode === undefined) throw new DiagramDocumentError(`unknown source node \"${link.from.nodeId}\"`, `${path}.from.nodeId`);\n if (toNode === undefined) throw new DiagramDocumentError(`unknown target node \"${link.to.nodeId}\"`, `${path}.to.nodeId`);\n if (!fromNode.outPorts.some((port) => port.id === link.from.portId)) {\n throw new DiagramDocumentError(`unknown output port \"${link.from.portId}\"`, `${path}.from.portId`);\n }\n if (!toNode.inPorts.some((port) => port.id === link.to.portId)) {\n throw new DiagramDocumentError(`unknown input port \"${link.to.portId}\"`, `${path}.to.portId`);\n }\n const key = `${link.from.nodeId}\\u0000${link.from.portId}\\u0000${link.to.nodeId}\\u0000${link.to.portId}`;\n if (endpoints.has(key)) throw new DiagramDocumentError('duplicate link endpoints', path);\n endpoints.add(key);\n }\n\n validateUniqueZones(document.zones);\n}\n\nfunction validateUniquePorts(ports: readonly DiagramDocumentPort[], path: string): void {\n const ids = new Set<string>();\n for (let index = 0; index < ports.length; index++) {\n const id = ports[index].id;\n if (ids.has(id)) throw new DiagramDocumentError(`duplicate port id \"${id}\"`, `${path}[${index}].id`);\n ids.add(id);\n }\n}\n\nfunction cloneStringRecord(value: unknown, path: string): Record<string, string> {\n const object = requireObject(value, path);\n const result: Record<string, string> = {};\n for (const [key, item] of Object.entries(object)) setJsonKey(result, key, requireString(item, `${path}.${key}`));\n return result;\n}\n\nfunction cloneJsonObject(value: unknown, path: string, ancestors = new WeakSet<object>()): JsonObject {\n const object = requireObject(value, path);\n if (ancestors.has(object)) throw new DiagramDocumentError('circular JSON value', path);\n ancestors.add(object);\n const result: JsonObject = {};\n try {\n for (const [key, item] of Object.entries(object)) {\n setJsonKey(result, key, cloneJsonValue(item, `${path}.${key}`, ancestors));\n }\n } finally {\n ancestors.delete(object);\n }\n return result;\n}\n\nfunction cloneJsonValue(value: unknown, path: string, ancestors: WeakSet<object>): JsonValue {\n if (value === null || typeof value === 'string' || typeof value === 'boolean') return value;\n if (typeof value === 'number') return requireFiniteNumber(value, path);\n if (Array.isArray(value)) {\n if (ancestors.has(value)) throw new DiagramDocumentError('circular JSON value', path);\n ancestors.add(value);\n try {\n return value.map((item, index) => cloneJsonValue(item, `${path}[${index}]`, ancestors));\n } finally {\n ancestors.delete(value);\n }\n }\n if (isObject(value)) return cloneJsonObject(value, path, ancestors);\n throw new DiagramDocumentError('expected a JSON value', path);\n}\n\n/**\n * A container whose fields are read individually. Any object will do, including\n * a class instance: hosts build schemes out of DiagramNode and Port, not object\n * literals, and every field is validated on its own below.\n */\nfunction requireStructure(value: unknown, path: string): Record<string, unknown> {\n if (typeof value !== 'object' || value === null || Array.isArray(value)) {\n throw new DiagramDocumentError('expected an object', path);\n }\n return value as Record<string, unknown>;\n}\n\n/**\n * A value that has to survive JSON round-tripping unchanged. Stricter than\n * requireStructure on purpose: a Date or any other class instance would\n * serialize to something the parser could not read back.\n */\nfunction requireObject(value: unknown, path: string): Record<string, unknown> {\n if (!isObject(value)) throw new DiagramDocumentError('expected an object', path);\n return value;\n}\n\nfunction isObject(value: unknown): value is Record<string, unknown> {\n if (typeof value !== 'object' || value === null || Array.isArray(value)) return false;\n const prototype = Object.getPrototypeOf(value) as object | null;\n return prototype === Object.prototype || prototype === null;\n}\n\n/**\n * Reads an optional array of objects, rejecting a non-array, a hole or a\n * non-object element. null counts as absent, like the `?? []` every other\n * optional field is read through.\n */\nfunction mapElements(value: unknown, path: string): Record<string, unknown>[] {\n if (value === undefined || value === null) return [];\n // Array.from rather than map: map skips holes, carrying an undefined element\n // into the result instead of reporting it.\n return Array.from(\n requireArray(value, path),\n (element, index) => requireStructure(element, `${path}[${index}]`),\n );\n}\n\nfunction requireArray(value: unknown, path: string): unknown[] {\n if (!Array.isArray(value)) throw new DiagramDocumentError('expected an array', path);\n return value;\n}\n\nfunction requireString(value: unknown, path: string): string {\n if (typeof value !== 'string') throw new DiagramDocumentError('expected a string', path);\n return value;\n}\n\n/**\n * Coerces rather than rejects. The set is closed in the types, which is where a\n * typo gets caught, but a persisted scheme can carry anything a JavaScript host\n * wrote before that -- and refusing to load it would brick the whole document\n * over a field whose every value except 'onConnect' behaves identically. The\n * type must still be a string, so a number or an object is a real error.\n */\nfunction requirePortDynamicMode(value: unknown, path: string): PortDynamicMode {\n const mode = requireString(value, path);\n return toPortDynamicMode(mode);\n}\n\nfunction requireIdentifier(value: unknown, path: string): string {\n const id = requireString(value, path);\n if (id.trim().length === 0) throw new DiagramDocumentError('identifier cannot be empty', path);\n return id;\n}\n\nfunction requireNumber(value: unknown, path: string): number {\n if (typeof value !== 'number') throw new DiagramDocumentError('expected a number', path);\n return value;\n}\n\nfunction requireFiniteNumber(value: unknown, path: string): number {\n const number = requireNumber(value, path);\n if (!Number.isFinite(number)) throw new DiagramDocumentError('expected a finite number', path);\n return number;\n}\n\nfunction requireNullableFiniteNumber(value: unknown, path: string): number | null {\n return value === null ? null : requireFiniteNumber(value, path);\n}\n\nfunction requireNonNegativeInteger(value: unknown, path: string): number {\n const number = requireFiniteNumber(value, path);\n if (!Number.isInteger(number) || number < 0) throw new DiagramDocumentError('expected a non-negative integer', path);\n return number;\n}\n\nfunction requireBoolean(value: unknown, path: string): boolean {\n if (typeof value !== 'boolean') throw new DiagramDocumentError('expected a boolean', path);\n return value;\n}\n", "export interface DiagramCommand {\n readonly label: string;\n execute(): void;\n undo(): void;\n}\n\nexport interface DiagramHistoryState {\n canUndo: boolean;\n canRedo: boolean;\n undoDepth: number;\n redoDepth: number;\n undoLabel: string | null;\n redoLabel: string | null;\n}\n\nexport type DiagramHistoryListener = (state: DiagramHistoryState) => void;\n\ninterface TransactionFrame {\n label: string;\n commands: DiagramCommand[];\n}\n\nexport class DiagramCommandHistory {\n private readonly undoCommands: DiagramCommand[] = [];\n private readonly redoCommands: DiagramCommand[] = [];\n private readonly transactions: TransactionFrame[] = [];\n private replaying = false;\n\n constructor(private readonly listener?: DiagramHistoryListener) {}\n\n get state(): DiagramHistoryState {\n return {\n canUndo: this.undoCommands.length > 0,\n canRedo: this.redoCommands.length > 0,\n undoDepth: this.undoCommands.length,\n redoDepth: this.redoCommands.length,\n undoLabel: this.undoCommands[this.undoCommands.length - 1]?.label ?? null,\n redoLabel: this.redoCommands[this.redoCommands.length - 1]?.label ?? null,\n };\n }\n\n execute(command: DiagramCommand): void {\n if (this.replaying) {\n command.execute();\n return;\n }\n command.execute();\n this.recordApplied(command);\n }\n\n /** Records a gesture that already changed the document, such as pointer drag. */\n recordApplied(command: DiagramCommand): void {\n if (this.replaying) return;\n const transaction = this.transactions[this.transactions.length - 1];\n if (transaction !== undefined) {\n transaction.commands.push(command);\n return;\n }\n this.undoCommands.push(command);\n this.redoCommands.length = 0;\n this.notify();\n }\n\n transaction<T>(label: string, action: () => T): T {\n const frame: TransactionFrame = { label, commands: [] };\n this.transactions.push(frame);\n try {\n const result = action();\n this.transactions.pop();\n const command = compose(frame);\n if (command !== null) this.recordApplied(command);\n return result;\n } catch (error) {\n this.transactions.pop();\n this.replay(() => {\n for (const command of frame.commands.slice().reverse()) command.undo();\n });\n throw error;\n }\n }\n\n private assertNoOpenTransaction(operation: string): void {\n if (this.transactions.length > 0) {\n throw new Error(`Cannot ${operation} command history inside a transaction.`);\n }\n }\n\n undo(): boolean {\n // Same guard clear() already has: running history while a transaction is open takes a\n // committed step out from under the frame being built and breaks the LIFO invariant the\n // stacks rely on. Reachable synchronously from a host handler for an event emitted from\n // inside a transaction, so it is not a theoretical misuse.\n this.assertNoOpenTransaction('undo');\n const command = this.undoCommands.pop();\n if (command === undefined) return false;\n try {\n this.replay(() => command.undo());\n } catch (error) {\n this.undoCommands.push(command);\n throw error;\n }\n this.redoCommands.push(command);\n this.notify();\n return true;\n }\n\n redo(): boolean {\n this.assertNoOpenTransaction('redo');\n const command = this.redoCommands.pop();\n if (command === undefined) return false;\n try {\n this.replay(() => command.execute());\n } catch (error) {\n this.redoCommands.push(command);\n throw error;\n }\n this.undoCommands.push(command);\n this.notify();\n return true;\n }\n\n clear(): void {\n this.assertNoOpenTransaction('clear');\n this.undoCommands.length = 0;\n this.redoCommands.length = 0;\n this.notify();\n }\n\n private replay(action: () => void): void {\n const previous = this.replaying;\n this.replaying = true;\n try {\n action();\n } finally {\n this.replaying = previous;\n }\n }\n\n private notify(): void {\n this.listener?.(this.state);\n }\n}\n\nfunction compose(frame: TransactionFrame): DiagramCommand | null {\n if (frame.commands.length === 0) return null;\n if (frame.commands.length === 1) {\n const command = frame.commands[0];\n return frame.label === command.label ? command : {\n label: frame.label,\n execute: () => command.execute(),\n undo: () => command.undo(),\n };\n }\n const commands = [...frame.commands];\n return {\n label: frame.label,\n execute: () => {\n for (const command of commands) command.execute();\n },\n undo: () => {\n for (const command of commands.slice().reverse()) command.undo();\n },\n };\n}\n", "/**\n * Recursively read-only view of a state object. The snapshot accessors hand back\n * detached copies, so writing to one is silently discarded -- this makes that a\n * compile error instead. The setters accept it, so a snapshot still round-trips.\n */\nexport type DiagramSnapshot<T> = {\n readonly [K in keyof T]: DiagramSnapshotValue<T[K]>;\n};\n\n// Distributes over unions, so an optional or nullable object property keeps\n// being descended into instead of falling through as its writable self.\ntype DiagramSnapshotValue<T> = T extends readonly (infer TItem)[]\n ? readonly DiagramSnapshotValue<TItem>[]\n : T extends object\n ? DiagramSnapshot<T>\n : T;\n\nexport type DiagramPortDirection = 'in' | 'out';\nexport type DiagramNodeErrorKind = 'runtime' | 'load';\nexport type DiagramGlobalErrorKind = 'invalid' | 'load' | 'locked' | 'encrypted';\n\nexport interface DiagramErrorState<TKind extends string> {\n kind: TKind;\n message: string;\n /** Incrementing this value requests a fresh renderer animation. */\n pulse: number;\n}\n\nexport interface DiagramPortRuntimeState {\n active: boolean;\n selected: boolean;\n breakpoint: boolean;\n breakpointActive: boolean;\n value: string | null;\n error: string | null;\n}\n\nexport interface DiagramNodePortRuntimeState {\n in: Record<string, DiagramPortRuntimeState>;\n out: Record<string, DiagramPortRuntimeState>;\n}\n\n/**\n * At most one error per kind. A node can carry a load error and a runtime error\n * at the same time -- the tooltip shows both -- so a single slot could not hold\n * what the editor already models, and every state write dropped one of them.\n */\nexport type DiagramNodeErrors = {\n [TKind in DiagramNodeErrorKind]?: DiagramErrorState<TKind>;\n};\n\nexport interface DiagramNodeRuntimeState {\n active: boolean;\n errors: DiagramNodeErrors;\n ports: DiagramNodePortRuntimeState;\n}\n\nexport interface DiagramRuntimeState {\n activeNodeId: string | null;\n nodes: Record<string, DiagramNodeRuntimeState>;\n globalError: DiagramErrorState<DiagramGlobalErrorKind> | null;\n}\n\nexport interface DiagramViewState {\n zoom: number;\n panX: number;\n panY: number;\n overviewVisible: boolean;\n}\n\nexport interface DiagramSelectedPort {\n nodeId: string;\n portId: string;\n direction: DiagramPortDirection;\n}\n\nexport interface DiagramSelection {\n nodeIds: string[];\n linkIds: string[];\n port: DiagramSelectedPort | null;\n primaryNodeId: string | null;\n primaryLinkId: string | null;\n}\n\nexport interface DiagramInteractionPermissions {\n select: boolean;\n inspect: boolean;\n copy: boolean;\n moveNodes: boolean;\n createLinks: boolean;\n deleteSelection: boolean;\n paste: boolean;\n history: boolean;\n}\n\nexport function createDiagramRuntimeState(): DiagramRuntimeState {\n return { activeNodeId: null, nodes: {}, globalError: null };\n}\n\nexport function cloneDiagramRuntimeState(state: DiagramRuntimeState): DiagramRuntimeState {\n return {\n activeNodeId: state.activeNodeId,\n globalError: state.globalError === null ? null : { ...state.globalError },\n nodes: Object.fromEntries(Object.entries(state.nodes).map(([nodeId, node]) => [nodeId, {\n active: node.active,\n errors: cloneDiagramNodeErrors(node.errors),\n ports: {\n in: Object.fromEntries(Object.entries(node.ports.in)\n .map(([portId, port]) => [portId, { ...port }])),\n out: Object.fromEntries(Object.entries(node.ports.out)\n .map(([portId, port]) => [portId, { ...port }])),\n },\n }])),\n };\n}\n\nexport function createDiagramViewState(): DiagramViewState {\n return { zoom: 1, panX: 0, panY: 0, overviewVisible: true };\n}\n\nexport function createDiagramSelection(): DiagramSelection {\n return {\n nodeIds: [],\n linkIds: [],\n port: null,\n primaryNodeId: null,\n primaryLinkId: null,\n };\n}\n\nexport function createDiagramPortRuntimeState(): DiagramPortRuntimeState {\n return {\n active: false,\n selected: false,\n breakpoint: false,\n breakpointActive: false,\n value: null,\n error: null,\n };\n}\n\nexport function createEditableDiagramPermissions(): DiagramInteractionPermissions {\n return {\n select: true,\n inspect: true,\n copy: true,\n moveNodes: true,\n createLinks: true,\n deleteSelection: true,\n paste: true,\n history: true,\n };\n}\n\nexport function createReadOnlyDiagramPermissions(): DiagramInteractionPermissions {\n return {\n select: true,\n inspect: true,\n copy: true,\n moveNodes: false,\n createLinks: false,\n deleteSelection: false,\n paste: false,\n history: false,\n };\n}\n\nexport function createDiagramNodeRuntimeState(): DiagramNodeRuntimeState {\n return {\n active: false,\n errors: {},\n ports: { in: {}, out: {} },\n };\n}\n\n/**\n * Tolerates a missing map: hosts persist runtime snapshots and build them by\n * hand, so a state written before this field existed still has to be readable.\n */\nexport function cloneDiagramNodeErrors(errors: DiagramNodeErrors | undefined | null): DiagramNodeErrors {\n const result: DiagramNodeErrors = {};\n if (errors === undefined || errors === null) return result;\n if (errors.runtime !== undefined) result.runtime = { ...errors.runtime };\n if (errors.load !== undefined) result.load = { ...errors.load };\n return result;\n}\n", "import type { DrawSurface } from './draw-surface.js';\nimport { SvgSurface } from './svg-surface.js';\nimport { readableTextOn } from './color.js';\n// Internal dependency-free canvas renderer used by StockSharpDiagram.\n//\n// Dependency-free, pure 2D canvas. Demonstrates the hard parts: typed\n// in/out ports, bezier links, node drag, drag-to-link with validation,\n// selection, delete, zoom/pan, load/save round-trip.\n\nimport { createDiagramDocument, parseDiagramDocument } from './core/document.js';\nimport { DiagramCommandHistory } from './core/history.js';\nimport { getJsonKey, setJsonKey } from './core/json.js';\nimport { toPortDynamicMode } from './core/model.js';\nimport type {\n DiagramDocumentZone,\n DiagramLinkStyle,\n DiagramDocument,\n DiagramParameterSchema,\n JsonObject,\n JsonValue,\n PortDynamicMode,\n} from './core/model.js';\nimport type {\n DiagramGlobalErrorKind,\n DiagramInteractionPermissions,\n DiagramPortRuntimeState,\n DiagramRuntimeState,\n DiagramSelection,\n DiagramViewState,\n} from './core/state.js';\nimport {\n cloneDiagramRuntimeState,\n createDiagramNodeRuntimeState,\n createDiagramPortRuntimeState,\n createDiagramRuntimeState,\n createEditableDiagramPermissions,\n createReadOnlyDiagramPermissions,\n} from './core/state.js';\n\nexport type PortDirection = 'in' | 'out';\nexport type PortClickAction = 'leftClick' | 'rightClick';\n\nexport interface PortInit {\n id: string;\n name: string;\n description?: string;\n type?: string;\n maxLinks?: number;\n availableTypes?: string[];\n isDynamic?: boolean;\n dynamicMode?: PortDynamicMode;\n isSibling?: boolean;\n metadata?: JsonObject;\n}\n\n/** Mutable port properties. Port identity and direction remain stable. */\nexport type PortUpdate = Partial<Omit<PortInit, 'id'>>;\n\nexport interface DiagramNodeInit {\n id?: string;\n typeId?: string;\n name: string;\n description?: string;\n groupName?: string;\n color?: string;\n border?: string;\n icon?: string;\n x?: number;\n y?: number;\n inPorts?: PortInit[];\n outPorts?: PortInit[];\n /** Non-empty host action enables node double-click tracking. */\n openAction?: string;\n /** Transient error discovered while loading a scheme. */\n loadError?: string;\n /** Persistent host text. Runtime/load errors are stored separately. */\n message?: string;\n parameters?: DiagramParameterSchema[];\n paramValues?: Record<string, string>;\n metadata?: JsonObject;\n /** Transient missing-catalog marker; excluded from saveDocument(). */\n isPlaceholder?: boolean;\n}\n\nexport interface LinkInit {\n id?: string;\n from: string;\n fromPort: string;\n to: string;\n toPort: string;\n /** Solid unless the link is one that may not be there - see DiagramLinkStyle. */\n style?: DiagramLinkStyle;\n metadata?: JsonObject;\n}\n\nexport type DiagramNodeSnapshot = DiagramNodeInit\n & Required<Pick<DiagramNodeInit, 'id' | 'typeId' | 'name' | 'color' | 'border' | 'x' | 'y'>>\n & { inPorts: PortInit[]; outPorts: PortInit[] };\n\nexport interface DiagramSnapshot {\n nodes: DiagramNodeSnapshot[];\n // Endpoints alone made the snapshot lossy: a save()/load() round-trip dropped every link's\n // identity, style and metadata, and the links carried in loadFinished / undoRequested /\n // redoRequested arrived with an empty id, so selectLink(payload.link.id) matched nothing.\n links: Array<Required<Pick<LinkInit, 'id' | 'from' | 'fromPort' | 'to' | 'toPort' | 'style'>> & Pick<LinkInit, 'metadata'>>;\n}\n\nexport interface DiagramOptions {\n host: HTMLElement;\n background?: string;\n gridColor?: string;\n /** Snap dragged nodes to a world-space grid. Defaults to false for the low-level renderer. */\n gridSnap?: boolean;\n /** Tint for a zone that names no colour of its own. */\n zoneColor?: string;\n /** Positive world-space grid step. Defaults to 28. */\n gridSize?: number;\n /** Optional explicit socket-type \u2192 colour map; unknown types hash to a hue. */\n typeColors?: Record<string, string>;\n /** Ceiling (0..1) for link/socket colour lightness. Unset = full palette (tuned for a dark\n * canvas). A light theme sets a low ceiling so the otherwise-light link colours darken enough\n * to stay visible on a light canvas. */\n linkMaxLightness?: number;\n /** When true, colour links by their source socket type; the default draws links in the neutral grey. */\n typedLinkColors?: boolean;\n /** Optional minimap colours. When omitted they are derived from the\n * current canvas background, so a normal light/dark theme switch also\n * rethemes the overview. */\n overviewBackground?: string;\n overviewBorderColor?: string;\n overviewViewportColor?: string;\n overviewViewportFill?: string;\n}\n\nexport type DiagramScreenshotScope = 'viewport' | 'content';\n\nexport interface DiagramScreenshotOptions {\n /** Current viewport (Charts/WPF parity) or the complete graph bounds. Defaults to viewport. */\n scope?: DiagramScreenshotScope;\n /** World-to-CSS-pixel scale for content export. Defaults to 1. */\n scale?: number;\n /** CSS-pixel padding around content export. Defaults to 32. */\n padding?: number;\n /** Output pixel density. Defaults to the renderer's current device pixel ratio. */\n pixelRatio?: number;\n /** Optional export-only background override. */\n background?: string;\n /** Defaults to true. */\n includeGrid?: boolean;\n /** Defaults to the current value for viewport and false for content. */\n includeOverview?: boolean;\n /** Defaults to true for viewport and false for content. */\n includeSelection?: boolean;\n /** Include debugger and error state. Defaults to true. */\n includeRuntimeState?: boolean;\n}\n\nexport interface LinkValidatorArgs {\n fromNode: NodeModel;\n fromPort: PortModel;\n toNode: NodeModel;\n toPort: PortModel;\n}\nexport type LinkValidator = (args: LinkValidatorArgs) => boolean;\n\nexport type LinkValidationReason =\n | 'allowed'\n | 'missing-link'\n | 'missing-node'\n | 'missing-port'\n | 'same-node'\n | 'invalid-direction'\n | 'incompatible-type'\n | 'duplicate-link'\n | 'source-limit'\n | 'target-limit'\n | 'host-rejected';\n\nexport interface LinkValidationResult {\n allowed: boolean;\n reason: LinkValidationReason;\n}\n\nexport type NodeErrorKind = 'runtime' | 'load';\n\nexport interface NodeErrorOptions {\n /** Runtime errors flash the border; load errors use a red background. */\n kind?: NodeErrorKind;\n /** Disable the initial runtime-error border flash. Defaults to true. */\n animate?: boolean;\n}\n\nexport interface DiagramEvents {\n nodeAdded: { node: NodeModel };\n nodeRemoved: { node: NodeModel };\n nodeMoved: { node: NodeModel };\n nodeChanged: { node: NodeModel };\n nodeSelected: { node: NodeModel | null; selected: boolean };\n nodeHover: { node: NodeModel; hovering: boolean };\n linkAdded: { link: LinkModel };\n linkRemoved: { link: LinkModel };\n linkRelinked: { link: LinkModel; previous: LinkInit & { id: string } };\n linkSelected: { link: LinkModel | null; selected: boolean };\n linkHover: { link: LinkModel; hovering: boolean };\n linkValidation: {\n fromNode: NodeModel;\n from: PortModel;\n toNode: NodeModel;\n to: PortModel;\n allowed: boolean;\n reason: LinkValidationReason;\n };\n portSelected: { node: NodeModel; port: PortModel };\n portClicked: {\n node: NodeModel;\n port: PortModel;\n action: PortClickAction;\n ctrlKey: boolean;\n shiftKey: boolean;\n altKey: boolean;\n metaKey: boolean;\n };\n portHover: { node: NodeModel; port: PortModel; hovering: boolean };\n nodeOpen: { node: NodeModel };\n loadFinished: { nodes: NodeModel[]; links: LinkModel[] };\n zoomChanged: { scale: number };\n viewChanged: DiagramViewState;\n // Long-press on touch / right-click on desktop. (x, y) are page coords\n // so the host can position a DOM menu directly. Port, link or node\n // (or all null for empty-space) describe the target.\n contextMenu: {\n x: number;\n y: number;\n link: LinkModel | null;\n node: NodeModel | null;\n port: { node: NodeModel; port: PortModel } | null;\n };\n // Fires whenever the undo or redo stacks change so the host can\n // enable/disable Undo/Redo toolbar buttons live.\n undoStackChanged: { canUndo: boolean; canRedo: boolean };\n selectionChanged: DiagramSelection;\n runtimeStateChanged: { state: DiagramRuntimeState };\n}\n\ninterface DiagramRenderOptions {\n grid: boolean;\n overview: boolean;\n selection: boolean;\n runtime: boolean;\n transient: boolean;\n}\n\nconst SCREEN_RENDER_OPTIONS: DiagramRenderOptions = {\n grid: true,\n overview: true,\n selection: true,\n runtime: true,\n transient: true,\n};\n// One reversible operation. `do` re-applies it (redo), `undo` reverses\n// it. Both must be idempotent w.r.t. repeated undo/redo. label is for\n// telemetry/debug only.\ninterface AppliedAction { do: () => void; undo: () => void; label: string }\ntype EvName = keyof DiagramEvents;\n\n// ---- model ----------------------------------------------------------\nfunction copyJsonValue(value: JsonValue): JsonValue {\n if (Array.isArray(value)) return value.map(copyJsonValue);\n if (value !== null && typeof value === 'object') return copyJsonObject(value);\n return value;\n}\n\nfunction copyJsonObject(value: JsonObject | undefined): JsonObject {\n if (value === undefined) return {};\n const result: JsonObject = {};\n for (const [key, item] of Object.entries(value)) setJsonKey(result, key, copyJsonValue(item));\n return result;\n}\n\nfunction copyParameters(value: readonly DiagramParameterSchema[] | undefined): DiagramParameterSchema[] {\n return (value ?? []).map((parameter) => ({ ...parameter, options: [...parameter.options] }));\n}\n\nfunction normalizePortType(type: string): string {\n return type.trim().toLowerCase();\n}\n\nfunction isWildcardPortType(type: string): boolean {\n const normalized = normalizePortType(type);\n return normalized === ''\n || normalized === '*'\n || normalized === 'any'\n || normalized === 'anydata'\n || normalized === 'any data'\n || normalized === 'object'\n || normalized === 'system.object'\n || normalized.startsWith('system.object,');\n}\n\n// The empty socket a grow-on-connect input spawns its siblings from. The scheme records it\n// first, but it accepts nothing until something is wired into it, so it belongs under the\n// sockets that do carry data.\nfunction isGrowAnchor(port: PortModel): boolean {\n return port.isDynamic && !port.isSibling;\n}\n\nfunction arePortTypesCompatible(fromType: string, toType: string, availableTypes: readonly string[]): boolean {\n if (isWildcardPortType(fromType) || isWildcardPortType(toType)) return true;\n const normalizedFrom = normalizePortType(fromType);\n return [toType, ...availableTypes].some((type) =>\n isWildcardPortType(type) || normalizePortType(type) === normalizedFrom);\n}\n\nexport class PortModel {\n id: string;\n name: string;\n description: string;\n type: string;\n direction: PortDirection;\n maxLinks: number;\n availableTypes: string[];\n isDynamic: boolean;\n dynamicMode: PortDynamicMode;\n isSibling: boolean;\n metadata: JsonObject;\n // layout cache (world coords), filled at draw time\n cx = 0;\n cy = 0;\n constructor(init: PortInit, dir: PortDirection) {\n this.id = init.id;\n this.name = init.name;\n this.description = init.description ?? '';\n this.type = init.type ?? '';\n this.direction = dir;\n this.maxLinks = typeof init.maxLinks === 'number' ? init.maxLinks : 0;\n this.availableTypes = [...(init.availableTypes ?? [])];\n this.isDynamic = init.isDynamic ?? false;\n this.dynamicMode = toPortDynamicMode(init.dynamicMode);\n this.isSibling = init.isSibling ?? false;\n this.metadata = copyJsonObject(init.metadata);\n }\n\n toInit(): PortInit {\n return {\n id: this.id,\n name: this.name,\n description: this.description,\n type: this.type,\n maxLinks: this.maxLinks,\n availableTypes: [...this.availableTypes],\n isDynamic: this.isDynamic,\n dynamicMode: this.dynamicMode,\n isSibling: this.isSibling,\n metadata: copyJsonObject(this.metadata),\n };\n }\n}\n\nexport class NodeModel {\n id: string;\n typeId: string;\n name: string;\n description: string;\n groupName: string;\n color: string;\n border: string;\n icon: string;\n openAction: string;\n message: string;\n parameters: DiagramParameterSchema[];\n paramValues: Record<string, string>;\n metadata: JsonObject;\n isPlaceholder: boolean;\n loadError: string;\n runtimeError = '';\n errorFlashStart: number | null = null;\n x: number;\n y: number;\n inPorts: PortModel[];\n outPorts: PortModel[];\n // layout cache\n w = 160;\n h = 48;\n constructor(init: DiagramNodeInit, id: string) {\n this.id = id;\n this.typeId = init.typeId ?? id;\n this.name = init.name;\n this.description = init.description ?? '';\n this.groupName = init.groupName ?? 'Common';\n this.color = init.color ?? '#d7d7d7';\n this.border = init.border ?? '#8c8c8c';\n this.icon = init.icon ?? '';\n this.openAction = init.openAction ?? '';\n this.message = init.message ?? '';\n this.parameters = copyParameters(init.parameters);\n this.paramValues = { ...(init.paramValues ?? {}) };\n this.metadata = copyJsonObject(init.metadata);\n this.isPlaceholder = init.isPlaceholder ?? false;\n this.loadError = init.loadError ?? '';\n this.x = typeof init.x === 'number' ? init.x : 0;\n this.y = typeof init.y === 'number' ? init.y : 0;\n this.inPorts = (init.inPorts ?? []).map((p) => new PortModel(p, 'in'));\n this.outPorts = (init.outPorts ?? []).map((p) => new PortModel(p, 'out'));\n }\n port(id: string): PortModel | undefined {\n return this.inPorts.find((p) => p.id === id) ?? this.outPorts.find((p) => p.id === id);\n }\n\n toInit(includeRuntimeState: boolean = true): DiagramNodeInit & { id: string } {\n const init: DiagramNodeInit & { id: string } = {\n id: this.id,\n typeId: this.typeId,\n name: this.name,\n description: this.description,\n groupName: this.groupName,\n color: this.color,\n border: this.border,\n icon: this.icon,\n openAction: this.openAction,\n message: this.message,\n parameters: copyParameters(this.parameters),\n paramValues: { ...this.paramValues },\n metadata: copyJsonObject(this.metadata),\n isPlaceholder: this.isPlaceholder,\n x: this.x,\n y: this.y,\n inPorts: this.inPorts.map((port) => port.toInit()),\n outPorts: this.outPorts.map((port) => port.toInit()),\n };\n if (includeRuntimeState && this.loadError.length > 0) init.loadError = this.loadError;\n return init;\n }\n}\n\nexport class LinkModel {\n readonly id: string;\n readonly metadata: JsonObject;\n\n constructor(\n public from: string,\n public fromPort: string,\n public to: string,\n public toPort: string,\n id: string = '',\n metadata?: JsonObject,\n public style: DiagramLinkStyle = 'solid',\n ) {\n this.id = id;\n this.metadata = copyJsonObject(metadata);\n }\n key(): string { return `${this.from}|${this.fromPort}|${this.to}|${this.toPort}`; }\n\n toInit(): LinkInit & { id: string } {\n return {\n id: this.id,\n from: this.from,\n fromPort: this.fromPort,\n to: this.to,\n toPort: this.toPort,\n style: this.style,\n metadata: copyJsonObject(this.metadata),\n };\n }\n}\n\nconst PORT_R = 6;\nconst PORT_ROW_H = 20;\nconst RELINK_HANDLE_PX = 8; // WPF relink adornment is an 8x8 diamond\nconst RELINK_DRAG_THRESHOLD_PX = 4;\nconst PORT_SQ = 9; // socket square size \u2014 sits outside the node\nconst LINK_STUB = 22; // min horizontal lead-in/out before the elbow\nconst LINK_HOP = 5; // jump-over arc radius at crossings\nconst LINK_CORNER = 8; // corner rounding radius at elbows\nconst SNAP_PX = 32; // plug\u2194socket magnet radius (screen px)\nconst DEFAULT_GRID_SIZE = 28;\nconst ZOOM_MIN = 0.15;\nconst ZOOM_MAX = 4;\nconst INTRO_MS = 520; // entrance animation duration\nconst INTRO_RISE = 70; // px the scheme rises from below\nconst ERROR_FLASH_MS = 1100;\nconst ERROR_RED = '#f6465d';\nconst ERROR_BACKGROUND = '#7d2632';\n\nconst clamp = (v: number, lo: number, hi: number): number => Math.min(hi, Math.max(lo, v));\n\nfunction hashHue(s: string): number {\n let h = 0;\n for (let i = 0; i < s.length; i += 1) h = (h * 31 + s.charCodeAt(i)) | 0;\n return ((h % 360) + 360) % 360;\n}\n\n// Clamp an hsl() colour's lightness to a ceiling (0..1), keeping its hue and saturation. The link\n// palette is tuned for a dark canvas (light, ~58%-lightness colours), so on a light canvas those\n// wash out; a light theme passes a low ceiling to darken the links just enough to stay readable\n// while keeping each hue distinct. Non-hsl inputs are returned untouched.\nfunction clampLightness(color: string, maxL: number): string {\n const m = color.match(/^hsl\\(\\s*([\\d.]+)\\s*,\\s*([\\d.]+)%\\s*,\\s*([\\d.]+)%\\s*\\)$/i);\n if (m === null) return color;\n return `hsl(${m[1]}, ${m[2]}%, ${Math.min(+m[3], maxL * 100)}%)`;\n}\n\nfunction colorLuminance(color: string | undefined): number {\n if (color === undefined) return 0;\n const hex = color.trim().match(/^#([0-9a-f]{3}|[0-9a-f]{6})$/i);\n if (hex !== null) {\n const raw = hex[1].length === 3\n ? hex[1].split('').map((x) => x + x).join('')\n : hex[1];\n const value = parseInt(raw, 16);\n return 0.299 * ((value >> 16) & 255)\n + 0.587 * ((value >> 8) & 255)\n + 0.114 * (value & 255);\n }\n const rgb = color.match(/^rgba?\\(\\s*([\\d.]+)\\s*,\\s*([\\d.]+)\\s*,\\s*([\\d.]+)/i);\n if (rgb !== null)\n return 0.299 * +rgb[1] + 0.587 * +rgb[2] + 0.114 * +rgb[3];\n return 0;\n}\n\nexport class Diagram {\n private readonly host: HTMLElement;\n private readonly canvas: HTMLCanvasElement;\n // Typed as the surface, not the context: the on-screen path still passes the browser's own\n // 2D context (it satisfies the interface structurally), while export can hand in an SVG one.\n private ctx: DrawSurface;\n private readonly opts: DiagramOptions;\n\n private nodes: NodeModel[] = [];\n private links: LinkModel[] = [];\n private zones: DiagramDocumentZone[] = [];\n private idSeq = 1;\n private linkSeq = 1;\n private documentMetadata: JsonObject = {};\n private runtimeState: DiagramRuntimeState = createDiagramRuntimeState();\n private runtimePulse = 0;\n private globalErrorFlashStart: number | null = null;\n\n // viewport transform: screen = world * scale + offset\n private scale = 1;\n private offX = 0;\n private offY = 0;\n\n private width = 0;\n private height = 0;\n private dpr = 1;\n private drawScheduled = false;\n private gridSnapEnabled: boolean;\n private gridSize: number;\n\n // interaction state\n private selectedNode: NodeModel | null = null; // primary (last) selected\n private selectedNodes = new Set<NodeModel>(); // multi-selection\n private selectedLink: LinkModel | null = null;\n private selectedPort: { node: NodeModel; port: PortModel } | null = null;\n private dragNode: NodeModel | null = null;\n private dragStart: Array<{ n: NodeModel; x: number; y: number }> = []; // group-drag origin\n private dragAnchor = { wx: 0, wy: 0 };\n private panning = false;\n private panX = 0;\n private panY = 0;\n private permissions = createEditableDiagramPermissions();\n private showNodeMessages = true;\n private iconCache = new Map<string, HTMLImageElement | null>(); // node icon images by URL (null = loading/failed)\n private rubber: { x0: number; y0: number; x: number; y: number } | null = null; // world rect\n private clip: DiagramDocument | null = null;\n private linking: { node: NodeModel; port: PortModel } | null = null;\n private relinking: { link: LinkModel; end: 'from' | 'to' } | null = null;\n private relinkCandidate: {\n link: LinkModel;\n end: 'from' | 'to';\n sx: number;\n sy: number;\n } | null = null;\n private linkSnap: { node: NodeModel; port: PortModel } | null = null;\n private cursor = { x: 0, y: 0 }; // screen\n private hoverPort: { node: NodeModel; port: PortModel } | null = null;\n private hoverNode: NodeModel | null = null;\n private hoveredLink: LinkModel | null = null;\n // Type feeding each wired input, keyed by node and port, rebuilt for every frame.\n private portFeed: ReadonlyMap<PortModel, string> = new Map();\n private tipTimer: ReturnType<typeof setTimeout> | null = null;\n private tipShow = false;\n private tipTarget: PortModel | NodeModel | null = null;\n // Long-press (touch) / right-click (desktop) \u2192 contextMenu event.\n private lpTimer: ReturnType<typeof setTimeout> | null = null;\n private lpStart: { sx: number; sy: number; px: number; py: number } | null = null;\n private readonly lpDelayMs = 550;\n private readonly lpMoveTol = 7;\n private readonly history: DiagramCommandHistory;\n private readonly domDisposables: Array<() => void> = [];\n private destroyed = false;\n\n // Overview minimap.\n private introStart: number | null = null;\n private overviewVisible = true;\n private ovDragging = false;\n private historyShortcut: (direction: 'undo' | 'redo') => void =\n (direction) => { if (direction === 'undo') this.undo(); else this.redo(); };\n private ovGeo: { x: number; y: number; w: number; h: number; s: number; minX: number; minY: number } | null = null;\n\n private validator: LinkValidator | null = null;\n private handlers = new Map<EvName, Set<(p: never) => void>>();\n\n constructor(opts: DiagramOptions) {\n this.opts = opts;\n // Same normalization setTypeColors applies, so a palette handed in at construction is\n // keyed like one handed in later.\n if (opts.typeColors !== undefined) this.setTypeColorsInternal(opts.typeColors);\n this.host = opts.host;\n this.gridSnapEnabled = opts.gridSnap ?? false;\n this.gridSize = this.normalizeGridSize(opts.gridSize ?? DEFAULT_GRID_SIZE);\n this.history = new DiagramCommandHistory(() => {\n // The gated values, not the raw stack: setInteractionPermissions and setReadOnly\n // already publish canUndo()/canRedo(), and a toolbar fed the raw pair enabled its\n // Undo button for a call that undo() would refuse.\n this.emit('undoStackChanged', { canUndo: this.canUndo(), canRedo: this.canRedo() });\n });\n this.canvas = document.createElement('canvas');\n this.canvas.style.display = 'block';\n this.canvas.tabIndex = 0; // focusable \u2192 key events\n this.canvas.style.outline = 'none';\n // Eat browser-native touch gestures (page scroll / pinch-zoom) so\n // fingers actually drive our pan/zoom on mobile instead of the page.\n this.canvas.style.touchAction = 'none';\n // No OS text-selection on long-press (would pop the iOS magnifier\n // and select node/link captions instead of firing our menu).\n this.canvas.style.userSelect = 'none';\n (this.canvas.style as unknown as { webkitUserSelect: string }).webkitUserSelect = 'none';\n (this.canvas.style as unknown as { webkitTouchCallout: string }).webkitTouchCallout = 'none';\n this.host.appendChild(this.canvas);\n const ctx = this.canvas.getContext('2d');\n if (ctx === null) throw new Error('ssdiagram: 2d context unavailable');\n this.ctx = ctx;\n this.resize(this.host.clientWidth || 800, this.host.clientHeight || 480);\n this.observeHostSize();\n this.bind();\n }\n\n /// The control creates the canvas, so it keeps it the size of the element it was mounted in.\n /// A host that lays its panels out after construction - a docking shell, a tab that opens\n /// hidden - measures nothing at that point, and the fallback size above would then outlive\n /// the layout: a strip of the panel that draws nothing and answers no clicks. resize()\n /// ignores anything smaller than two pixels, so a panel switched away from keeps its view.\n private observeHostSize(): void {\n if (typeof ResizeObserver === 'undefined') return;\n\n const observer = new ResizeObserver(() => this.resize(this.host.clientWidth, this.host.clientHeight));\n observer.observe(this.host);\n this.domDisposables.push(() => observer.disconnect());\n }\n\n // ---- events -----------------------------------------------------\n on<K extends EvName>(ev: K, h: (p: DiagramEvents[K]) => void): () => void {\n let set = this.handlers.get(ev);\n if (set === undefined) { set = new Set(); this.handlers.set(ev, set); }\n set.add(h as (p: never) => void);\n return () => set!.delete(h as (p: never) => void);\n }\n private emit<K extends EvName>(ev: K, p: DiagramEvents[K]): void {\n const set = this.handlers.get(ev);\n if (set === undefined) return;\n for (const h of set) { try { (h as (x: DiagramEvents[K]) => void)(p); } catch (e) { console.error(e); } }\n }\n\n // ---- public API (Layer-A-shaped) --------------------------------\n setLinkValidator(fn: LinkValidator | null): void { this.validator = fn; }\n setGridSnap(enabled: boolean, size?: number): void {\n const nextSize = size === undefined ? this.gridSize : this.normalizeGridSize(size);\n this.gridSnapEnabled = enabled;\n this.gridSize = nextSize;\n this.scheduleDraw();\n }\n getGridSnap(): { enabled: boolean; size: number } {\n return { enabled: this.gridSnapEnabled, size: this.gridSize };\n }\n\n private normalizeGridSize(size: number): number {\n if (!Number.isFinite(size) || size <= 0) throw new RangeError('ssdiagram: grid size must be a positive finite number');\n return size;\n }\n\n private nextNodeId(): string {\n let id: string;\n do id = `n${this.idSeq++}`;\n while (this.nodes.some((node) => node.id === id));\n return id;\n }\n\n private nextLinkId(): string {\n let id: string;\n do id = `link_${this.linkSeq++}`;\n while (this.links.some((link) => link.id === id));\n return id;\n }\n\n addDiagramNode(init: DiagramNodeInit): string {\n const id = init.id ?? this.nextNodeId();\n if (id.trim().length === 0) throw new Error('ssdiagram: node id cannot be empty');\n if (this.nodes.some((node) => node.id === id)) throw new Error(`ssdiagram: duplicate node id \"${id}\"`);\n const fullInit: DiagramNodeInit = { ...init, id };\n this.doAddNode(fullInit);\n this.record({\n do: () => { this.doAddNode(fullInit); },\n undo: () => { this.doRemoveNode(id); },\n label: 'add node',\n });\n return id;\n }\n private doAddNode(init: DiagramNodeInit): void {\n const id = init.id ?? this.nextNodeId();\n if (this.nodes.some((node) => node.id === id)) return;\n const node = new NodeModel(init, id);\n this.layoutNode(node);\n this.nodes.push(node);\n this.emit('nodeAdded', { node });\n this.scheduleDraw();\n }\n removeDiagramNode(id: string): void {\n const node = this.nodes.find((n) => n.id === id);\n if (node === undefined) return;\n // Capture full state for undo BEFORE mutating \u2014 we need both\n // the node init AND every link that gets cascaded out, so undo\n // can rebuild them in one shot.\n const snapshot = node.toInit(false);\n const cascaded = this.links\n .map((link, index) => ({ link, index }))\n .filter(({ link }) => link.from === id || link.to === id)\n .map(({ link, index }) => ({ init: link.toInit(), index }));\n const siblingTargets: Array<{ nodeId: string; portId: string }> = [];\n for (const { init } of cascaded) {\n if (init.from !== id || init.to === id) continue;\n const targetPort = this.findNode(init.to)?.inPorts.find((port) => port.id === init.toPort);\n if (targetPort?.isSibling !== true) continue;\n if (!siblingTargets.some((target) => target.nodeId === init.to && target.portId === init.toPort)) {\n siblingTargets.push({ nodeId: init.to, portId: init.toPort });\n }\n }\n const remove = (): void => {\n this.doRemoveNode(id);\n this.record({\n do: () => { this.doRemoveNode(id); },\n undo: () => {\n this.doAddNode(snapshot);\n for (const { init, index } of cascaded) this.doAddLink(init, false, index);\n },\n label: 'remove node',\n });\n };\n if (siblingTargets.length === 0) {\n remove();\n } else {\n this.withTransaction('remove node', () => {\n remove();\n for (const target of siblingTargets) this.pruneDynamicSibling(target.nodeId, target.portId);\n });\n }\n }\n private doRemoveNode(id: string): void {\n const node = this.nodes.find((n) => n.id === id);\n if (node === undefined) return;\n const removedLinks = this.links.filter((l) => l.from === id || l.to === id);\n this.links = this.links.filter((l) => l.from !== id && l.to !== id);\n this.nodes = this.nodes.filter((n) => n !== node);\n let selectionChanged = this.selectedNodes.delete(node);\n if (this.selectedNode === node) {\n const remaining = [...this.selectedNodes];\n this.selectedNode = remaining[remaining.length - 1] ?? null;\n selectionChanged = true;\n }\n if (this.selectedPort?.node === node) {\n this.selectedPort = null;\n selectionChanged = true;\n }\n if (this.selectedLink !== null && removedLinks.includes(this.selectedLink)) {\n this.selectedLink = null;\n selectionChanged = true;\n }\n if (selectionChanged) this.emitSelectionChanged();\n for (const l of removedLinks) this.emit('linkRemoved', { link: l });\n this.emit('nodeRemoved', { node });\n this.scheduleDraw();\n }\n moveNode(id: string, x: number, y: number): void {\n const node = this.nodes.find((n) => n.id === id);\n if (node === undefined) return;\n const fromX = node.x, fromY = node.y;\n this.doMoveNode(id, x, y);\n if (fromX !== x || fromY !== y) {\n this.record({\n do: () => { this.doMoveNode(id, x, y); },\n undo: () => { this.doMoveNode(id, fromX, fromY); },\n label: 'move node',\n });\n }\n }\n nudgeSelection(dx: number, dy: number): boolean {\n if (!Number.isFinite(dx) || !Number.isFinite(dy)) throw new RangeError('ssdiagram: nudge delta must be finite');\n if ((dx === 0 && dy === 0) || this.selectedNodes.size === 0) return false;\n const moves = [...this.selectedNodes].map((node) => ({\n id: node.id,\n fromX: node.x,\n fromY: node.y,\n toX: node.x + dx,\n toY: node.y + dy,\n }));\n for (const move of moves) this.doMoveNode(move.id, move.toX, move.toY);\n this.record({\n do: () => { for (const move of moves) this.doMoveNode(move.id, move.toX, move.toY); },\n undo: () => { for (const move of moves) this.doMoveNode(move.id, move.fromX, move.fromY); },\n label: 'nudge',\n });\n return true;\n }\n private doMoveNode(id: string, x: number, y: number): void {\n const node = this.nodes.find((n) => n.id === id);\n if (node === undefined) return;\n node.x = x; node.y = y;\n this.layoutNode(node);\n this.emit('nodeMoved', { node });\n this.scheduleDraw();\n }\n addLink(init: LinkInit): boolean {\n const fullInit: LinkInit = {\n ...init,\n id: init.id ?? this.nextLinkId(),\n metadata: copyJsonObject(init.metadata),\n };\n if (fullInit.id !== undefined && this.links.some((link) => link.id === fullInit.id)) return false;\n const fromNode = this.nodes.find((node) => node.id === fullInit.from);\n const toNode = this.nodes.find((node) => node.id === fullInit.to);\n const fromPort = fromNode?.outPorts.find((port) => port.id === fullInit.fromPort);\n const toPort = toNode?.inPorts.find((port) => port.id === fullInit.toPort);\n if (fromNode !== undefined && toNode !== undefined && fromPort !== undefined && toPort !== undefined\n && toPort.isDynamic && toPort.dynamicMode === 'onConnect' && !toPort.isSibling) {\n const validation = this.validateLinkModels(fromNode, fromPort, toNode, toPort);\n this.emit('linkValidation', { fromNode, from: fromPort, toNode, to: toPort, ...validation });\n if (!validation.allowed) return false;\n const sibling = this.createDynamicSibling(toNode, toPort, fromPort);\n let added = false;\n const failed = new Error('ssdiagram: dynamic link transaction failed');\n try {\n this.withTransaction('add dynamic link', () => {\n if (!this.addPort(toNode.id, 'in', sibling)) throw failed;\n added = this.addLinkApplied({ ...fullInit, toPort: sibling.id }, false);\n if (!added) throw failed;\n });\n } catch (error) {\n if (error === failed) return false;\n throw error;\n }\n return added;\n }\n return this.addLinkApplied(fullInit, true);\n }\n private addLinkApplied(init: LinkInit, validate: boolean): boolean {\n const ok = this.doAddLink(init, validate);\n if (ok) {\n this.record({\n do: () => { this.doAddLink(init, false); },\n undo: () => { this.doRemoveLink(init); },\n label: 'add link',\n });\n }\n return ok;\n }\n private doAddLink(init: LinkInit, validate = true, index = this.links.length): boolean {\n const fn = this.nodes.find((n) => n.id === init.from);\n const tn = this.nodes.find((n) => n.id === init.to);\n if (fn === undefined || tn === undefined) return false;\n const fp = fn.outPorts.find((p) => p.id === init.fromPort);\n const tp = tn.inPorts.find((p) => p.id === init.toPort);\n if (fp === undefined || tp === undefined) return false;\n if (validate) {\n const validation = this.validateLinkModels(fn, fp, tn, tp);\n this.emit('linkValidation', { fromNode: fn, from: fp, toNode: tn, to: tp, ...validation });\n if (!validation.allowed) return false;\n }\n const link = new LinkModel(init.from, init.fromPort, init.to, init.toPort, init.id ?? this.nextLinkId(), init.metadata, init.style ?? 'solid');\n if (this.links.some((l) => l.id === link.id)) return false;\n this.links.splice(clamp(Math.trunc(index), 0, this.links.length), 0, link);\n this.emit('linkAdded', { link });\n this.scheduleDraw();\n return true;\n }\n removeLink(link: { id?: string; from: string; fromPort: string; to: string; toPort: string }): void {\n this.removeLinkInternal(link, true);\n }\n private removeLinkInternal(\n link: { id?: string; from: string; fromPort: string; to: string; toPort: string },\n pruneDynamicSibling: boolean,\n ): void {\n const key = new LinkModel(link.from, link.fromPort, link.to, link.toPort).key();\n const found = link.id === undefined || link.id.length === 0\n ? this.links.find((candidate) => candidate.key() === key)\n : this.links.find((candidate) => candidate.id === link.id);\n if (found === undefined) return;\n const init = found.toInit();\n const index = this.links.indexOf(found);\n const targetPort = this.findNode(found.to)?.inPorts.find((port) => port.id === found.toPort);\n const remove = (): void => {\n this.doRemoveLink(init);\n this.record({\n do: () => { this.doRemoveLink(init); },\n undo: () => { this.doAddLink(init, false, index); },\n label: 'remove link',\n });\n };\n if (pruneDynamicSibling && targetPort?.isSibling === true) {\n this.withTransaction('remove dynamic link', () => {\n remove();\n this.pruneDynamicSibling(init.to, init.toPort);\n });\n } else {\n remove();\n }\n }\n private doRemoveLink(link: { from: string; fromPort: string; to: string; toPort: string }): void {\n const k = new LinkModel(link.from, link.fromPort, link.to, link.toPort).key();\n const found = this.links.find((l) => l.key() === k);\n if (found === undefined) return;\n this.links = this.links.filter((l) => l !== found);\n if (this.selectedLink === found) this.selectLink(null);\n this.emit('linkRemoved', { link: found });\n this.scheduleDraw();\n }\n private createDynamicSibling(toNode: NodeModel, anchor: PortModel, source: PortModel): PortInit {\n let sequence = 1;\n while (toNode.inPorts.some((port) => port.id === `${anchor.id}_${sequence}`)) sequence += 1;\n return {\n id: `${anchor.id}_${sequence}`,\n name: `${anchor.name} ${sequence}`,\n description: anchor.description,\n type: source.type || anchor.type,\n maxLinks: 1,\n availableTypes: [...anchor.availableTypes],\n isDynamic: false,\n dynamicMode: '',\n isSibling: true,\n metadata: copyJsonObject(anchor.metadata),\n };\n }\n private pruneDynamicSibling(nodeId: string, portId: string): void {\n const node = this.findNode(nodeId);\n const port = node?.inPorts.find((candidate) => candidate.id === portId);\n if (port?.isSibling !== true) return;\n if (this.links.some((link) => link.to === nodeId && link.toPort === portId)) return;\n this.removePort(nodeId, 'in', portId);\n }\n // ---- undo / redo public surface ---------------------------------\n canUndo(): boolean { return this.permissions.history && this.history.state.canUndo; }\n canRedo(): boolean { return this.permissions.history && this.history.state.canRedo; }\n undo(): void { if (this.permissions.history) this.history.undo(); }\n redo(): void { if (this.permissions.history) this.history.redo(); }\n cutSelection(): void {\n if (!this.permissions.copy || !this.permissions.deleteSelection) return;\n // The copy/delete pair is observable as ONE undo step.\n this.copySelection();\n this.withTransaction('cut', () => { this.deleteSelection(); });\n }\n // Group multiple mutations into one undo step (paste of N nodes,\n // bulk delete, multi-drag, etc.). Re-entrant: nested calls flatten\n // into the outer batch.\n withTransaction<T>(label: string, fn: () => T): T {\n return this.history.transaction(label, fn);\n }\n private record(action: AppliedAction): void {\n this.history.recordApplied({\n label: action.label,\n execute: action.do,\n undo: action.undo,\n });\n }\n deleteSelection(): void {\n if (!this.permissions.deleteSelection) return;\n if (this.selectedNodes.size > 0) {\n this.withTransaction('delete selection', () => {\n for (const id of [...this.selectedNodes].map((n) => n.id)) this.removeDiagramNode(id);\n });\n this.selectedNodes.clear();\n this.selectedNode = null;\n return;\n }\n if (this.selectedLink !== null) { this.removeLink(this.selectedLink); }\n }\n clear(): void {\n this.nodes = []; this.links = [];\n // Zones belong to the document like everything else here. Leaving them behind meant a\n // discarded strategy kept drawing its zones over the next one and, worse, saveDocument()\n // wrote them into that unrelated strategy's file.\n this.zones = [];\n // Every other path that empties the selection announces it. Staying silent here left a\n // host's property panel showing a node from the document that had just been thrown away.\n const hadSelection = this.selectedNode !== null || this.selectedNodes.size > 0\n || this.selectedLink !== null || this.selectedPort !== null;\n this.selectedNode = null; this.selectedNodes.clear(); this.selectedLink = null; this.selectedPort = null;\n this.documentMetadata = {};\n this.runtimeState = createDiagramRuntimeState();\n this.runtimePulse = 0;\n this.globalErrorFlashStart = null;\n this.history.clear();\n if (hadSelection) this.emitSelectionChanged();\n this.emitRuntimeStateChanged();\n }\n relink(\n linkId: string,\n next: Pick<LinkInit, 'from' | 'fromPort' | 'to' | 'toPort'>,\n ): LinkValidationResult {\n const link = this.links.find((candidate) => candidate.id === linkId);\n if (link === undefined) return { allowed: false, reason: 'missing-link' };\n\n const validation = this.validateLink(next, linkId);\n const fromNode = this.nodes.find((node) => node.id === next.from);\n const toNode = this.nodes.find((node) => node.id === next.to);\n const fromPort = fromNode?.outPorts.find((port) => port.id === next.fromPort);\n const toPort = toNode?.inPorts.find((port) => port.id === next.toPort);\n if (fromNode !== undefined && toNode !== undefined && fromPort !== undefined && toPort !== undefined) {\n this.emit('linkValidation', { fromNode, from: fromPort, toNode, to: toPort, ...validation });\n }\n if (!validation.allowed) return validation;\n\n const before = link.toInit();\n if (before.from === next.from && before.fromPort === next.fromPort\n && before.to === next.to && before.toPort === next.toPort) return validation;\n const dynamicSibling = fromPort !== undefined && toNode !== undefined && toPort !== undefined\n && toPort.isDynamic && toPort.dynamicMode === 'onConnect' && !toPort.isSibling\n ? this.createDynamicSibling(toNode, toPort, fromPort)\n : null;\n const after: LinkInit & { id: string } = {\n ...before,\n ...next,\n toPort: dynamicSibling?.id ?? next.toPort,\n };\n const oldTargetPort = this.findNode(before.to)?.inPorts.find((port) => port.id === before.toPort);\n const apply = (): void => {\n this.doRelink(linkId, after);\n this.record({\n do: () => { this.doRelink(linkId, after); },\n undo: () => { this.doRelink(linkId, before); },\n label: 'relink',\n });\n };\n const pruneOldSibling = oldTargetPort?.isSibling === true\n && (before.to !== after.to || before.toPort !== after.toPort);\n if (dynamicSibling !== null || pruneOldSibling) {\n this.withTransaction('relink dynamic link', () => {\n if (dynamicSibling !== null && !this.addPort(after.to, 'in', dynamicSibling)) {\n throw new Error('ssdiagram: could not create a dynamic sibling port');\n }\n apply();\n if (pruneOldSibling) this.pruneDynamicSibling(before.to, before.toPort);\n });\n } else {\n apply();\n }\n return validation;\n }\n private doRelink(linkId: string, next: LinkInit & { id: string }): void {\n const link = this.links.find((candidate) => candidate.id === linkId);\n if (link === undefined) return;\n const previous = link.toInit();\n link.from = next.from;\n link.fromPort = next.fromPort;\n link.to = next.to;\n link.toPort = next.toPort;\n this.emit('linkRelinked', { link, previous });\n this.scheduleDraw();\n }\n\n addPort(nodeId: string, direction: PortDirection, init: PortInit): boolean {\n const node = this.findNode(nodeId);\n if (node === undefined) return false;\n const ports = direction === 'in' ? node.inPorts : node.outPorts;\n if (ports.some((port) => port.id === init.id)) return false;\n return this.updateNodeState(nodeId, 'add port', (target) => {\n const list = direction === 'in' ? target.inPorts : target.outPorts;\n list.push(new PortModel(init, direction));\n });\n }\n\n removePort(nodeId: string, direction: PortDirection, portId: string): boolean {\n const node = this.findNode(nodeId);\n if (node === undefined) return false;\n const ports = direction === 'in' ? node.inPorts : node.outPorts;\n if (!ports.some((port) => port.id === portId)) return false;\n let changed = false;\n this.withTransaction('remove port', () => {\n const affected = this.links.filter((link) => direction === 'in'\n ? link.to === nodeId && link.toPort === portId\n : link.from === nodeId && link.fromPort === portId);\n for (const link of affected) this.removeLinkInternal(link, false);\n changed = this.updateNodeState(nodeId, 'remove port', (target) => {\n if (direction === 'in') target.inPorts = target.inPorts.filter((port) => port.id !== portId);\n else target.outPorts = target.outPorts.filter((port) => port.id !== portId);\n });\n });\n return changed;\n }\n\n updatePortType(nodeId: string, direction: PortDirection, portId: string, type: string): boolean {\n return this.updatePort(nodeId, direction, portId, { type });\n }\n\n updatePort(nodeId: string, direction: PortDirection, portId: string, patch: PortUpdate): boolean {\n const node = this.findNode(nodeId);\n const port = direction === 'in'\n ? node?.inPorts.find((candidate) => candidate.id === portId)\n : node?.outPorts.find((candidate) => candidate.id === portId);\n if (port === undefined) return false;\n if (patch.maxLinks !== undefined && (!Number.isInteger(patch.maxLinks) || patch.maxLinks < 0)) {\n throw new RangeError('ssdiagram: port maxLinks must be a non-negative integer');\n }\n const compatibilityChanged = (patch.type !== undefined && patch.type !== port.type)\n || (patch.availableTypes !== undefined\n && JSON.stringify(patch.availableTypes) !== JSON.stringify(port.availableTypes));\n let changed = false;\n this.withTransaction('update port', () => {\n changed = this.updateNodeState(nodeId, 'update port', (target) => {\n const targetPort = direction === 'in'\n ? target.inPorts.find((candidate) => candidate.id === portId)\n : target.outPorts.find((candidate) => candidate.id === portId);\n if (targetPort === undefined) return;\n if (patch.name !== undefined) targetPort.name = patch.name;\n if (patch.description !== undefined) targetPort.description = patch.description;\n if (patch.type !== undefined) targetPort.type = patch.type;\n if (patch.maxLinks !== undefined) targetPort.maxLinks = patch.maxLinks;\n if (patch.availableTypes !== undefined) targetPort.availableTypes = [...patch.availableTypes];\n if (patch.isDynamic !== undefined) targetPort.isDynamic = patch.isDynamic;\n if (patch.dynamicMode !== undefined) targetPort.dynamicMode = patch.dynamicMode;\n if (patch.isSibling !== undefined) targetPort.isSibling = patch.isSibling;\n if (patch.metadata !== undefined) targetPort.metadata = copyJsonObject(patch.metadata);\n });\n if (changed && compatibilityChanged) {\n this.removeIncompatibleLinks((link) => direction === 'in'\n ? link.to === nodeId && link.toPort === portId\n : link.from === nodeId && link.fromPort === portId);\n }\n });\n return changed;\n }\n\n setNodePorts(nodeId: string, inPorts: readonly PortInit[], outPorts: readonly PortInit[]): boolean {\n const node = this.findNode(nodeId);\n if (node === undefined) return false;\n const inputIds = new Set(inPorts.map((port) => port.id));\n const outputIds = new Set(outPorts.map((port) => port.id));\n let changed = false;\n this.withTransaction('set node ports', () => {\n const invalid = this.links.filter((link) =>\n (link.to === nodeId && !inputIds.has(link.toPort))\n || (link.from === nodeId && !outputIds.has(link.fromPort)));\n for (const link of invalid) this.removeLinkInternal(link, false);\n changed = this.updateNodeState(nodeId, 'set node ports', (target) => {\n target.inPorts = inPorts.map((port) => new PortModel(port, 'in'));\n target.outPorts = outPorts.map((port) => new PortModel(port, 'out'));\n });\n if (changed) {\n this.removeIncompatibleLinks((link) => link.from === nodeId || link.to === nodeId);\n }\n });\n return changed;\n }\n\n updateNode(\n nodeId: string,\n patch: Partial<Pick<DiagramNodeInit, 'name' | 'description' | 'color' | 'border' | 'message' | 'openAction'>>,\n ): boolean {\n return this.updateNodeState(nodeId, 'update node', (node) => {\n if (patch.name !== undefined) node.name = patch.name;\n if (patch.description !== undefined) node.description = patch.description;\n if (patch.color !== undefined) node.color = patch.color;\n if (patch.border !== undefined) node.border = patch.border;\n if (patch.message !== undefined) node.message = patch.message;\n if (patch.openAction !== undefined) node.openAction = patch.openAction;\n });\n }\n\n setNodeParamValue(nodeId: string, name: string, value: string | undefined): boolean {\n return this.updateNodeState(nodeId, 'set node parameter', (node) => {\n if (value === undefined) delete node.paramValues[name];\n else setJsonKey(node.paramValues, name, value);\n });\n }\n\n setShowNodeMessages(show: boolean): void {\n this.showNodeMessages = show;\n this.scheduleDraw();\n }\n\n private updateNodeState(nodeId: string, label: string, mutate: (node: NodeModel) => void): boolean {\n const node = this.findNode(nodeId);\n if (node === undefined) return false;\n const before = node.toInit(false);\n mutate(node);\n if (this.reconcileSelectedPort(node)) this.emitSelectionChanged();\n const after = node.toInit(false);\n if (JSON.stringify(before) === JSON.stringify(after)) return false;\n this.layoutNode(node);\n this.emit('nodeChanged', { node });\n this.scheduleDraw();\n this.record({\n do: () => { this.applyNodeSnapshot(nodeId, after); },\n undo: () => { this.applyNodeSnapshot(nodeId, before); },\n label,\n });\n return true;\n }\n\n private applyNodeSnapshot(nodeId: string, snapshot: DiagramNodeInit): void {\n const node = this.findNode(nodeId);\n if (node === undefined) return;\n const restored = new NodeModel(snapshot, nodeId);\n node.typeId = restored.typeId;\n node.name = restored.name;\n node.description = restored.description;\n node.groupName = restored.groupName;\n node.color = restored.color;\n node.border = restored.border;\n node.icon = restored.icon;\n node.openAction = restored.openAction;\n node.message = restored.message;\n node.parameters = restored.parameters;\n node.paramValues = restored.paramValues;\n node.metadata = restored.metadata;\n node.isPlaceholder = restored.isPlaceholder;\n node.x = restored.x;\n node.y = restored.y;\n node.inPorts = restored.inPorts;\n node.outPorts = restored.outPorts;\n if (this.reconcileSelectedPort(node)) this.emitSelectionChanged();\n this.layoutNode(node);\n this.emit('nodeChanged', { node });\n this.scheduleDraw();\n }\n\n private reconcileSelectedPort(node: NodeModel): boolean {\n if (this.selectedPort?.node !== node) return false;\n const selected = this.selectedPort.port;\n const ports = selected.direction === 'in' ? node.inPorts : node.outPorts;\n const replacement = ports.find((port) => port.id === selected.id);\n if (replacement === selected) return false;\n this.selectedPort = replacement === undefined ? null : { node, port: replacement };\n return true;\n }\n load(nodes: DiagramNodeInit[], links: LinkInit[]): void {\n this.clear();\n this.idSeq = 1;\n this.linkSeq = 1;\n // Initial load is \"model seed\" \u2014 should NOT be undoable, and\n // shouldn't leave the user with 12 entries to Ctrl+Z through\n // before their stack reaches their first real action.\n // Validate before applying anything. doAddNode returns silently on a duplicate id, so a\n // second node with the same id simply vanished and every wire meant for it attached to the\n // first -- a quietly miswired strategy. The link check used to sit mid-loop, which threw\n // with the diagram already half loaded and no loadFinished.\n const seenNodeIds = new Set<string>();\n for (const node of nodes) {\n const id = node.id ?? '';\n if (id === '') continue;\n if (seenNodeIds.has(id)) throw new Error(`ssdiagram: duplicate node id \"${id}\"`);\n seenNodeIds.add(id);\n }\n const seenLinkIds = new Set<string>();\n for (const link of links) {\n const id = link.id ?? '';\n if (id === '') continue;\n if (seenLinkIds.has(id)) throw new Error(`ssdiagram: duplicate link id \"${id}\"`);\n seenLinkIds.add(id);\n }\n\n for (const node of nodes) {\n const id = node.id ?? this.nextNodeId();\n this.doAddNode({ ...node, id });\n }\n for (const link of links) {\n const id = link.id ?? this.nextLinkId();\n if (this.links.some((existing) => existing.id === id)) {\n throw new Error(`ssdiagram: duplicate link id \"${id}\"`);\n }\n const model = new LinkModel(link.from, link.fromPort, link.to, link.toPort, id, link.metadata, link.style ?? 'solid');\n if (!this.links.some((existing) => existing.key() === model.key())) this.links.push(model);\n }\n for (const node of this.nodes) {\n if (node.loadError.length === 0) continue;\n const state = createDiagramNodeRuntimeState();\n state.errors.load = { kind: 'load', message: node.loadError, pulse: ++this.runtimePulse };\n setJsonKey(this.runtimeState.nodes as unknown as JsonObject, node.id, state as unknown as JsonValue);\n }\n if (Object.keys(this.runtimeState.nodes).length > 0) this.emitRuntimeStateChanged();\n this.history.clear();\n this.emit('loadFinished', { nodes: this.nodes.slice(), links: this.links.slice() });\n this.zoomToFit();\n this.playIntro();\n }\n save(): DiagramSnapshot {\n return {\n nodes: this.nodes.map((node) => node.toInit(false) as DiagramNodeSnapshot),\n links: this.links.map((l) => ({\n id: l.id,\n from: l.from,\n fromPort: l.fromPort,\n to: l.to,\n toPort: l.toPort,\n style: l.style,\n metadata: copyJsonObject(l.metadata),\n })),\n };\n }\n\n loadDocument(source: DiagramDocument | string): void {\n const document = parseDiagramDocument(source);\n this.load(\n document.nodes,\n document.links.map((link) => ({\n id: link.id,\n from: link.from.nodeId,\n fromPort: link.from.portId,\n to: link.to.nodeId,\n toPort: link.to.portId,\n style: link.style,\n metadata: link.metadata,\n })),\n );\n this.zones = document.zones.map((zone) => ({ ...zone, metadata: copyJsonObject(zone.metadata) }));\n this.documentMetadata = copyJsonObject(document.metadata);\n }\n\n saveDocument(): DiagramDocument {\n return createDiagramDocument({\n nodes: this.nodes.map((node) => node.toInit(false)),\n links: this.links.map((link) => ({\n id: link.id,\n from: { nodeId: link.from, portId: link.fromPort },\n to: { nodeId: link.to, portId: link.toPort },\n style: link.style,\n metadata: link.metadata,\n })),\n zones: this.zones.map((zone) => ({ ...zone, metadata: copyJsonObject(zone.metadata) })),\n metadata: this.documentMetadata,\n });\n }\n selectedNodeId(): string | null { return this.selectedNode?.id ?? null; }\n getSelection(): DiagramSelection {\n return {\n nodeIds: [...this.selectedNodes].map((node) => node.id),\n linkIds: this.selectedLink === null ? [] : [this.selectedLink.id],\n port: this.selectedPort === null ? null : {\n nodeId: this.selectedPort.node.id,\n portId: this.selectedPort.port.id,\n direction: this.selectedPort.port.direction,\n },\n primaryNodeId: this.selectedNode?.id ?? null,\n primaryLinkId: this.selectedLink?.id ?? null,\n };\n }\n selectNodesById(ids: readonly string[]): void {\n const wanted = new Set(ids);\n this.setSelection(this.nodes.filter((node) => wanted.has(node.id)));\n }\n selectLinkById(id: string | null): void {\n this.selectLink(id === null ? null : (this.links.find((link) => link.id === id) ?? null));\n }\n selectPortById(nodeId: string, direction: PortDirection, portId: string): void {\n const node = this.findNode(nodeId);\n const port = direction === 'in'\n ? node?.inPorts.find((candidate) => candidate.id === portId)\n : node?.outPorts.find((candidate) => candidate.id === portId);\n if (node !== undefined && port !== undefined) this.selectPort({ node, port });\n }\n getViewState(): DiagramViewState {\n return {\n zoom: this.scale,\n panX: this.offX,\n panY: this.offY,\n overviewVisible: this.overviewVisible,\n };\n }\n /**\n * Replaces what Ctrl+Z / Ctrl+Y do. Passing null restores the built-in behaviour, which is\n * plain undo()/redo() -- so a renderer used on its own keeps its keyboard history.\n */\n setHistoryShortcutHandler(handler: ((direction: 'undo' | 'redo') => void) | null): void {\n this.historyShortcut = handler ?? ((direction) => { if (direction === 'undo') this.undo(); else this.redo(); });\n }\n\n setViewState(state: DiagramViewState): void {\n if (!Number.isFinite(state.zoom) || !Number.isFinite(state.panX) || !Number.isFinite(state.panY)) {\n throw new RangeError('ssdiagram: view state zoom and pan must be finite numbers');\n }\n this.scale = clamp(state.zoom, ZOOM_MIN, ZOOM_MAX);\n this.offX = state.panX;\n this.offY = state.panY;\n this.overviewVisible = state.overviewVisible;\n this.emitViewChanged(true);\n this.scheduleDraw();\n }\n // Renderer operations consumed by the high-level component.\n findNode(id: string): NodeModel | undefined { return this.nodes.find((n) => n.id === id); }\n requestRedraw(): void { this.relayout(); this.scheduleDraw(); }\n /**\n * Creates a detached canvas. With no options it is an exact copy of the\n * current frame, matching Charts.takeScreenshot(). Content scope renders\n * the whole graph without changing the visible viewport.\n */\n takeScreenshot(options: DiagramScreenshotOptions = {}): HTMLCanvasElement {\n if (this.destroyed) throw new Error('ssdiagram: cannot export a destroyed diagram');\n const scope = options.scope ?? 'viewport';\n if (scope !== 'viewport' && scope !== 'content') {\n throw new RangeError(`ssdiagram: unsupported screenshot scope \"${String(scope)}\"`);\n }\n\n if (scope === 'viewport' && Object.keys(options).length === 0) {\n // Mutations only schedule a repaint, so the bitmap on screen is still the previous\n // frame until it lands. Copying it as-is handed back a picture of the state before the\n // edit -- or a blank one right after construction -- while the very same call with any\n // option took the redraw path and came out current.\n if (this.drawScheduled) this.draw();\n const copy = document.createElement('canvas');\n copy.width = this.canvas.width;\n copy.height = this.canvas.height;\n const copyContext = copy.getContext('2d');\n if (copyContext === null) throw new Error('ssdiagram: screenshot 2d context unavailable');\n copyContext.drawImage(this.canvas, 0, 0);\n return copy;\n }\n\n const layout = this.exportLayout(scope, options);\n const { pixelRatio, exportScale, padding, bounds, width, height, pixelWidth, pixelHeight } = layout;\n\n const output = document.createElement('canvas');\n output.width = pixelWidth;\n output.height = pixelHeight;\n output.style.width = `${width}px`;\n output.style.height = `${height}px`;\n const outputContext = output.getContext('2d');\n if (outputContext === null) throw new Error('ssdiagram: screenshot 2d context unavailable');\n\n const previous = {\n ctx: this.ctx,\n width: this.width,\n height: this.height,\n dpr: this.dpr,\n scale: this.scale,\n offX: this.offX,\n offY: this.offY,\n overviewVisible: this.overviewVisible,\n background: this.opts.background,\n // Drawing the overview recomputes this from the export frame. Left behind, the next\n // click on the on-screen minimap panned to a point in the export's coordinates.\n ovGeo: this.ovGeo,\n };\n try {\n this.ctx = outputContext;\n this.width = width;\n this.height = height;\n this.dpr = pixelRatio;\n this.scale = exportScale;\n this.offX = scope === 'content' && bounds !== null ? padding - bounds.minX * exportScale : previous.offX;\n this.offY = scope === 'content' && bounds !== null ? padding - bounds.minY * exportScale : previous.offY;\n this.overviewVisible = options.includeOverview ?? (scope === 'viewport' && previous.overviewVisible);\n if (options.background !== undefined) this.opts.background = options.background;\n outputContext.setTransform(pixelRatio, 0, 0, pixelRatio, 0, 0);\n this.draw({\n grid: options.includeGrid ?? true,\n overview: this.overviewVisible,\n selection: options.includeSelection ?? scope === 'viewport',\n runtime: options.includeRuntimeState ?? true,\n transient: false,\n });\n } finally {\n this.ctx = previous.ctx;\n this.width = previous.width;\n this.height = previous.height;\n this.dpr = previous.dpr;\n this.scale = previous.scale;\n this.offX = previous.offX;\n this.offY = previous.offY;\n this.overviewVisible = previous.overviewVisible;\n this.opts.background = previous.background;\n this.ovGeo = previous.ovGeo;\n }\n return output;\n }\n\n // Everything an export needs to know about size and placement, for either output. Shared on\n // purpose: a raster and a vector export of the same scope must frame the picture identically,\n // and two copies of this arithmetic would eventually disagree about padding or where the origin\n // sits. A block comment here would be lifted onto the next public member in the .d.ts.\n private exportLayout(scope: DiagramScreenshotScope, options: DiagramScreenshotOptions) {\n const pixelRatio = this.positiveScreenshotNumber(options.pixelRatio ?? this.dpr, 'pixelRatio');\n const exportScale = scope === 'content'\n ? this.positiveScreenshotNumber(options.scale ?? 1, 'scale')\n : this.scale;\n const padding = scope === 'content'\n ? this.nonNegativeScreenshotNumber(options.padding ?? 32, 'padding')\n : 0;\n const bounds = scope === 'content' ? this.graphBounds() : null;\n const width = scope === 'content'\n ? Math.max(1, Math.ceil(((bounds?.maxX ?? 1) - (bounds?.minX ?? 0)) * exportScale + padding * 2))\n : this.width;\n const height = scope === 'content'\n ? Math.max(1, Math.ceil(((bounds?.maxY ?? 1) - (bounds?.minY ?? 0)) * exportScale + padding * 2))\n : this.height;\n const pixelWidth = Math.ceil(width * pixelRatio);\n const pixelHeight = Math.ceil(height * pixelRatio);\n\n if (pixelWidth > 16384 || pixelHeight > 16384 || pixelWidth * pixelHeight > 268_435_456) {\n throw new RangeError(`ssdiagram: screenshot is too large (${pixelWidth}x${pixelHeight})`);\n }\n\n return { pixelRatio, exportScale, padding, bounds, width, height, pixelWidth, pixelHeight };\n }\n\n /**\n * The same picture takeScreenshot produces, as SVG.\n *\n * It is the renderer that draws it -- the surface underneath simply records instead of paints --\n * so the vector output cannot drift from what the screen and the raster export show. Text keeps\n * the on-screen metrics by measuring through a real 2D context.\n *\n * Scale and pixelRatio still frame the picture (they decide the viewBox), but nothing is\n * resampled: the result is resolution-independent, which is the point of asking for it.\n */\n takeSvg(options: DiagramScreenshotOptions = {}): string {\n if (this.destroyed) throw new Error('ssdiagram: cannot export a destroyed diagram');\n\n const scope = options.scope ?? 'viewport';\n if (scope !== 'viewport' && scope !== 'content') {\n throw new RangeError(`ssdiagram: unsupported screenshot scope \"${String(scope)}\"`);\n }\n\n const { exportScale, padding, bounds, width, height } = this.exportLayout(scope, options);\n\n const metrics = this.canvas.getContext('2d');\n const surface = new SvgSurface({\n width,\n height,\n background: options.background ?? this.opts.background ?? '#1b1b1f',\n metrics: metrics ?? undefined,\n });\n\n const previous = {\n ctx: this.ctx,\n width: this.width,\n height: this.height,\n dpr: this.dpr,\n scale: this.scale,\n offX: this.offX,\n offY: this.offY,\n overviewVisible: this.overviewVisible,\n background: this.opts.background,\n // Drawing the overview recomputes this from the export frame. Left behind, the next\n // click on the on-screen minimap panned to a point in the export's coordinates.\n ovGeo: this.ovGeo,\n };\n\n try {\n this.ctx = surface;\n // draw() fills the frame with the theme background unconditionally, straight over the\n // backdrop the surface was given -- so passing the override to SvgSurface alone left it\n // invisible and the SVG disagreed with the PNG of the same options. takeScreenshot\n // swaps the theme value for the duration of the export; this does the same.\n if (options.background !== undefined) this.opts.background = options.background;\n this.width = width;\n this.height = height;\n // 1: an SVG has no device pixels to multiply by, and the viewBox carries the size.\n this.dpr = 1;\n this.scale = exportScale;\n this.offX = scope === 'content' && bounds !== null ? padding - bounds.minX * exportScale : previous.offX;\n this.offY = scope === 'content' && bounds !== null ? padding - bounds.minY * exportScale : previous.offY;\n this.overviewVisible = options.includeOverview ?? (scope === 'viewport' && previous.overviewVisible);\n\n this.draw({\n grid: options.includeGrid ?? true,\n overview: this.overviewVisible,\n selection: options.includeSelection ?? scope === 'viewport',\n runtime: options.includeRuntimeState ?? true,\n transient: false,\n });\n } finally {\n this.ctx = previous.ctx;\n this.width = previous.width;\n this.height = previous.height;\n this.dpr = previous.dpr;\n this.scale = previous.scale;\n this.offX = previous.offX;\n this.offY = previous.offY;\n this.overviewVisible = previous.overviewVisible;\n this.opts.background = previous.background;\n this.ovGeo = previous.ovGeo;\n }\n\n return surface.toSvg();\n }\n\n private positiveScreenshotNumber(value: number, name: string): number {\n if (!Number.isFinite(value) || value <= 0) {\n throw new RangeError(`ssdiagram: screenshot ${name} must be a positive finite number`);\n }\n return value;\n }\n\n private nonNegativeScreenshotNumber(value: number, name: string): number {\n if (!Number.isFinite(value) || value < 0) {\n throw new RangeError(`ssdiagram: screenshot ${name} must be a non-negative finite number`);\n }\n return value;\n }\n getRuntimeState(): DiagramRuntimeState {\n return cloneDiagramRuntimeState(this.runtimeState);\n }\n setRuntimeState(state: DiagramRuntimeState): void {\n const previous = this.runtimeState;\n this.runtimeState = cloneDiagramRuntimeState(state);\n if (this.runtimeState.globalError === null) {\n this.globalErrorFlashStart = null;\n } else if (previous.globalError?.pulse !== this.runtimeState.globalError.pulse) {\n this.globalErrorFlashStart = performance.now();\n }\n this.runtimePulse = Math.max(\n this.runtimePulse,\n this.runtimeState.globalError?.pulse ?? 0,\n ...Object.values(this.runtimeState.nodes)\n .flatMap((node) => [node.errors.runtime?.pulse ?? 0, node.errors.load?.pulse ?? 0]),\n );\n for (const node of this.nodes) {\n const errors = getJsonKey(this.runtimeState.nodes, node.id)?.errors;\n const previousRuntime = getJsonKey(previous.nodes, node.id)?.errors.runtime;\n const runtimeError = errors?.runtime;\n node.runtimeError = runtimeError?.message ?? '';\n node.loadError = errors?.load?.message ?? '';\n if (runtimeError !== undefined) {\n if (previousRuntime === undefined || previousRuntime.pulse !== runtimeError.pulse) {\n node.errorFlashStart = performance.now();\n }\n } else {\n node.errorFlashStart = null;\n }\n }\n this.emitRuntimeStateChanged();\n }\n clearRuntimeState(): void {\n this.setRuntimeState(createDiagramRuntimeState());\n }\n setActiveNode(nodeId: string | null): boolean {\n if (nodeId !== null && this.findNode(nodeId) === undefined) return false;\n const state = this.getRuntimeState();\n state.activeNodeId = nodeId;\n this.setRuntimeState(state);\n return true;\n }\n setPortRuntimeState(\n nodeId: string,\n direction: PortDirection,\n portId: string,\n patch: Partial<DiagramPortRuntimeState>,\n ): boolean {\n const node = this.findNode(nodeId);\n const port = direction === 'in'\n ? node?.inPorts.find((candidate) => candidate.id === portId)\n : node?.outPorts.find((candidate) => candidate.id === portId);\n if (node === undefined || port === undefined) return false;\n const state = this.getRuntimeState();\n // Node ids come from documents, so \"__proto__\" is reachable: a bare assignment there\n // writes the prototype instead of creating an entry, and the next read of it throws.\n const nodeState = getJsonKey(state.nodes, nodeId) ?? createDiagramNodeRuntimeState();\n setJsonKey(state.nodes as unknown as JsonObject, nodeId, nodeState as unknown as JsonValue);\n const current = nodeState.ports[direction][portId] ?? createDiagramPortRuntimeState();\n nodeState.ports[direction][portId] = { ...current, ...patch };\n this.setRuntimeState(state);\n return true;\n }\n setGlobalError(message: string | null, kind: DiagramGlobalErrorKind = 'invalid'): void {\n const state = this.getRuntimeState();\n state.globalError = message === null || message.length === 0\n ? null\n : { kind, message, pulse: ++this.runtimePulse };\n this.setRuntimeState(state);\n }\n setNodeError(id: string, message: string, options: NodeErrorOptions = {}): boolean {\n const node = this.findNode(id);\n if (node === undefined) return false;\n const kind = options.kind ?? 'runtime';\n if (kind === 'load') {\n node.loadError = message;\n } else {\n node.runtimeError = message;\n node.errorFlashStart = message.length > 0 && options.animate !== false\n ? performance.now()\n : null;\n }\n const state = this.getRuntimeState();\n const nodeState = getJsonKey(state.nodes, id) ?? createDiagramNodeRuntimeState();\n setJsonKey(state.nodes as unknown as JsonObject, id, nodeState as unknown as JsonValue);\n // Only this kind's slot is written, so an error of the other kind that is\n // already on the node survives.\n if (message.length === 0) delete nodeState.errors[kind];\n else if (kind === 'load') nodeState.errors.load = { kind, message, pulse: ++this.runtimePulse };\n else nodeState.errors.runtime = { kind, message, pulse: ++this.runtimePulse };\n this.runtimeState = state;\n this.emitRuntimeStateChanged();\n return true;\n }\n clearNodeError(id: string, kind?: NodeErrorKind): boolean {\n const node = this.findNode(id);\n if (node === undefined) return false;\n if (kind === undefined || kind === 'runtime') {\n node.runtimeError = '';\n node.errorFlashStart = null;\n }\n if (kind === undefined || kind === 'load') node.loadError = '';\n const state = this.getRuntimeState();\n const nodeState = getJsonKey(state.nodes, id);\n if (nodeState !== undefined) {\n if (kind === undefined || kind === 'runtime') delete nodeState.errors.runtime;\n if (kind === undefined || kind === 'load') delete nodeState.errors.load;\n }\n this.runtimeState = state;\n this.emitRuntimeStateChanged();\n return true;\n }\n private emitRuntimeStateChanged(): void {\n this.emit('runtimeStateChanged', { state: this.getRuntimeState() });\n this.scheduleDraw();\n }\n viewToWorld(sx: number, sy: number): [number, number] { return this.toWorld(sx, sy); }\n worldToView(wx: number, wy: number): [number, number] { return this.toScreen(wx, wy); }\n selectNodeById(id: string | null): void {\n const node = id === null ? null : (this.nodes.find((n) => n.id === id) ?? null);\n this.selectNode(node);\n }\n\n setZoom(scale: number): void {\n // clamp() passes NaN straight through, and a NaN scale poisons offX/offY on the very next\n // line -- after which hit-testing, drawing and saveViewState are all dead, permanently.\n if (!Number.isFinite(scale)) throw new RangeError('ssdiagram: zoom must be a finite number');\n const cx = this.width / 2;\n const cy = this.height / 2;\n const wx = (cx - this.offX) / this.scale;\n const wy = (cy - this.offY) / this.scale;\n this.scale = clamp(scale, ZOOM_MIN, ZOOM_MAX);\n this.offX = cx - wx * this.scale;\n this.offY = cy - wy * this.scale;\n this.emitViewChanged(true);\n this.scheduleDraw();\n }\n zoomToFit(): void {\n const gb = this.graphBounds();\n if (gb === null) { this.scale = 1; this.offX = 0; this.offY = 0; this.emitViewChanged(true); this.scheduleDraw(); return; }\n const pad = 40;\n const gw = (gb.maxX - gb.minX) + pad * 2;\n const gh = (gb.maxY - gb.minY) + pad * 2;\n // Cap at 1.0 \u2014 never blow a small graph up past 100%.\n this.scale = clamp(Math.min(this.width / gw, this.height / gh), ZOOM_MIN, 1);\n this.offX = (this.width - (gb.maxX + gb.minX) * this.scale) / 2;\n this.offY = (this.height - (gb.maxY + gb.minY) * this.scale) / 2;\n this.emitViewChanged(true);\n this.scheduleDraw();\n }\n // Entrance animation: the whole scheme rises from below + fades in.\n playIntro(): void { this.introStart = performance.now(); this.scheduleDraw(); }\n setOverviewVisible(v: boolean): void {\n if (this.overviewVisible === v) return;\n this.overviewVisible = v;\n this.emitViewChanged(false);\n this.scheduleDraw();\n }\n setTypeColors(colors: Readonly<Record<string, string>>): void {\n this.setTypeColorsInternal(colors);\n this.scheduleDraw();\n }\n\n /**\n * Keyed the way port types are compared everywhere else. Connection compatibility is case- and\n * space-insensitive, so an imported scheme spelling a socket \"candle \" connects to \"Candle\" and\n * then fell through to a hash colour, showing one logical type in two colours in one diagram.\n */\n private setTypeColorsInternal(colors: Readonly<Record<string, string>>): void {\n const normalized: Record<string, string> = {};\n for (const [type, color] of Object.entries(colors)) {\n setJsonKey(normalized, normalizePortType(type), color);\n }\n this.opts.typeColors = normalized;\n }\n setTheme(t: {\n background?: string;\n gridColor?: string;\n linkMaxLightness?: number;\n typedLinkColors?: boolean;\n overviewBackground?: string;\n overviewBorderColor?: string;\n overviewViewportColor?: string;\n overviewViewportFill?: string;\n }): void {\n if (t.background !== undefined) this.opts.background = t.background;\n if (t.gridColor !== undefined) this.opts.gridColor = t.gridColor;\n if (t.linkMaxLightness !== undefined) this.opts.linkMaxLightness = t.linkMaxLightness;\n if (t.typedLinkColors !== undefined) this.opts.typedLinkColors = t.typedLinkColors;\n if (t.overviewBackground !== undefined) this.opts.overviewBackground = t.overviewBackground;\n if (t.overviewBorderColor !== undefined) this.opts.overviewBorderColor = t.overviewBorderColor;\n if (t.overviewViewportColor !== undefined) this.opts.overviewViewportColor = t.overviewViewportColor;\n if (t.overviewViewportFill !== undefined) this.opts.overviewViewportFill = t.overviewViewportFill;\n this.scheduleDraw();\n }\n private graphBounds(): { minX: number; minY: number; maxX: number; maxY: number } | null {\n if (this.nodes.length === 0) return null;\n let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity;\n for (const n of this.nodes) {\n minX = Math.min(minX, n.x); minY = Math.min(minY, n.y);\n maxX = Math.max(maxX, n.x + n.w); maxY = Math.max(maxY, n.y + n.h);\n }\n return { minX, minY, maxX, maxY };\n }\n resize(w: number, h: number): void {\n if (w < 2 || h < 2) return;\n this.width = w; this.height = h;\n this.dpr = window.devicePixelRatio || 1;\n this.canvas.width = Math.round(w * this.dpr);\n this.canvas.height = Math.round(h * this.dpr);\n this.canvas.style.width = `${w}px`;\n this.canvas.style.height = `${h}px`;\n this.ctx.setTransform(this.dpr, 0, 0, this.dpr, 0, 0);\n this.scheduleDraw();\n }\n getInteractionPermissions(): DiagramInteractionPermissions {\n return { ...this.permissions };\n }\n setInteractionPermissions(patch: Partial<DiagramInteractionPermissions>): void {\n this.permissions = { ...this.permissions, ...patch };\n if (!this.permissions.select) {\n this.selectedNode = null;\n this.selectedNodes.clear();\n this.selectedLink = null;\n this.selectedPort = null;\n this.emitSelectionChanged();\n }\n this.emit('undoStackChanged', { canUndo: this.canUndo(), canRedo: this.canRedo() });\n this.scheduleDraw();\n }\n /** View-only mode keeps selection, inspection and copy enabled. */\n setReadOnly(value: boolean): void {\n this.permissions = value\n ? createReadOnlyDiagramPermissions()\n : createEditableDiagramPermissions();\n this.emit('undoStackChanged', { canUndo: this.canUndo(), canRedo: this.canRedo() });\n this.scheduleDraw();\n }\n destroy(): void {\n if (this.destroyed) return;\n this.destroyed = true;\n this.cancelLongPress();\n if (this.tipTimer !== null) {\n clearTimeout(this.tipTimer);\n this.tipTimer = null;\n }\n for (const dispose of this.domDisposables.splice(0).reverse()) dispose();\n this.handlers.clear();\n this.iconCache.clear();\n this.canvas.remove();\n }\n\n // ---- geometry ---------------------------------------------------\n private layoutNode(n: NodeModel): void {\n const ctx = this.ctx;\n ctx.font = '600 12px Segoe UI, Tahoma, sans-serif';\n const titleW = ctx.measureText(n.name).width;\n const rows = Math.max(n.inPorts.length, n.outPorts.length, 1);\n // Node sizing: min 170 wide, height grows by rows.\n n.w = Math.max(170, Math.ceil(titleW) + 28);\n n.h = Math.max(48, rows * PORT_ROW_H + 16);\n // Each side's port stack is vertically centred; the socket\n // square sits OUTSIDE the body (its inner edge flush with the\n // node border).\n const off = PORT_SQ / 2;\n const place = (ports: PortModel[], x: number): void => {\n const stack = ports.some(isGrowAnchor)\n ? [...ports.filter((p) => !isGrowAnchor(p)), ...ports.filter(isGrowAnchor)]\n : ports;\n const startY = n.y + (n.h - stack.length * PORT_ROW_H) / 2 + PORT_ROW_H / 2;\n stack.forEach((p, i) => { p.cx = x; p.cy = startY + i * PORT_ROW_H; });\n };\n place(n.inPorts, n.x - off);\n place(n.outPorts, n.x + n.w + off);\n }\n private relayout(): void { for (const n of this.nodes) this.layoutNode(n); }\n\n private toScreen(wx: number, wy: number): [number, number] {\n return [wx * this.scale + this.offX, wy * this.scale + this.offY];\n }\n private toWorld(sx: number, sy: number): [number, number] {\n return [(sx - this.offX) / this.scale, (sy - this.offY) / this.scale];\n }\n /// Type of the output wired into each connected input. First link wins, which is the one\n /// drawn first, so a socket accepting several links agrees with the wire on top.\n private feedTypes(): Map<PortModel, string> {\n const feed = new Map<PortModel, string>();\n for (const l of this.links) {\n const from = this.findNode(l.from)?.outPorts.find((p) => p.id === l.fromPort);\n if (from === undefined || isWildcardPortType(from.type)) continue;\n const to = this.findNode(l.to)?.inPorts.find((p) => p.id === l.toPort);\n if (to === undefined || feed.has(to)) continue;\n feed.set(to, from.type);\n }\n return feed;\n }\n\n /// Colour type of a socket: its own, unless it is a wildcard input with something wired in.\n /// A wildcard promises to take whatever arrives, so once something has arrived the socket\n /// shows what that is. An untyped socket ('') promises nothing and keeps its neutral fill.\n private portFillType(p: PortModel): string {\n if (p.direction !== 'in' || p.type === '' || !isWildcardPortType(p.type)) return p.type;\n return this.portFeed.get(p) ?? p.type;\n }\n\n private portColor(type: string): string {\n const maxL = this.opts.linkMaxLightness;\n const light = maxL !== undefined && maxL < 0.5;\n if (type === '') return light ? '#585c62' : '#9aa0a6';\n const map = this.opts.typeColors ?? {};\n const normalized = normalizePortType(type);\n const base = getJsonKey(map, normalized) ?? `hsl(${hashHue(normalized)}, 62%, 58%)`;\n return maxL !== undefined ? clampLightness(base, maxL) : base;\n }\n // Selection/hover accent. The dark-canvas blue washes out on a light canvas, so a light theme\n // (linkMaxLightness < 0.5) inverts to a darker, more saturated blue that stays clearly visible.\n private selectionColor(): string {\n const maxL = this.opts.linkMaxLightness;\n return maxL !== undefined && maxL < 0.5 ? '#0d6efd' : '#4aa3ff';\n }\n private linkHoverColor(): string {\n const maxL = this.opts.linkMaxLightness;\n return maxL !== undefined && maxL < 0.5 ? '#6aa9f0' : '#cfe3ff';\n }\n\n // ---- hit testing (world coords) ---------------------------------\n private portAt(wx: number, wy: number): { node: NodeModel; port: PortModel } | null {\n // Walks front to back and stops at the first node whose BODY covers the point, so a socket\n // hidden underneath a node drawn on top of it can no longer win the hit test. Without that\n // stop, clicking the visible body of the front node selected the one behind it, and on an\n // output socket started dragging a wire out of a port that is not on screen.\n for (let i = this.nodes.length - 1; i >= 0; i -= 1) {\n const n = this.nodes[i];\n for (const p of [...n.inPorts, ...n.outPorts]) {\n if ((wx - p.cx) ** 2 + (wy - p.cy) ** 2 <= (PORT_R + 4) ** 2) return { node: n, port: p };\n }\n if (wx >= n.x && wx <= n.x + n.w && wy >= n.y && wy <= n.y + n.h) return null;\n }\n return null;\n }\n private selectedLinkEndpointAt(wx: number, wy: number): 'from' | 'to' | null {\n if (this.selectedLink === null) return null;\n const radius = (PORT_R + 7) / this.scale;\n for (const end of ['from', 'to'] as const) {\n const point = this.endpoint(this.selectedLink, end);\n if (point !== null && (wx - point[0]) ** 2 + (wy - point[1]) ** 2 <= radius ** 2) return end;\n }\n return null;\n }\n private directRelinkAtPort(node: NodeModel, port: PortModel): {\n link: LinkModel;\n end: 'from' | 'to';\n } | null {\n if (port.direction !== 'in') return null;\n const incoming = this.links.filter((link) => link.to === node.id && link.toPort === port.id);\n return incoming.length === 1 ? { link: incoming[0], end: 'to' } : null;\n }\n private nodeAt(wx: number, wy: number): NodeModel | null {\n for (let i = this.nodes.length - 1; i >= 0; i -= 1) {\n const n = this.nodes[i];\n if (wx >= n.x && wx <= n.x + n.w && wy >= n.y && wy <= n.y + n.h) return n;\n }\n return null;\n }\n // Other nodes (not the link's own endpoints) become obstacles,\n // inflated so links keep a little clearance \u2014 the AvoidsNodes margin.\n private obstaclesFor(exclude: Set<string>): Rect[] {\n const inf = 12;\n const out: Rect[] = [];\n for (const n of this.nodes) {\n if (exclude.has(n.id)) continue;\n out.push([n.x - inf, n.y - inf, n.w + inf * 2, n.h + inf * 2]);\n }\n return out;\n }\n private routeLink(a: [number, number], b: [number, number], exclude: Set<string>): number[][] {\n return routeAvoid(a, b, this.obstaclesFor(exclude));\n }\n private linkAt(wx: number, wy: number): LinkModel | null {\n const tol = 5 / this.scale;\n // topmost first so the hovered/selected one wins\n for (let i = this.links.length - 1; i >= 0; i -= 1) {\n const l = this.links[i];\n const a = this.endpoint(l, 'from');\n const b = this.endpoint(l, 'to');\n if (a === null || b === null) continue;\n const pts = this.routeLink(a, b, new Set([l.from, l.to]));\n for (let k = 1; k < pts.length; k += 1) {\n if (ptSegDist(wx, wy, pts[k - 1][0], pts[k - 1][1], pts[k][0], pts[k][1]) <= tol) return l;\n }\n }\n return null;\n }\n private endpoint(l: LinkModel, end: 'from' | 'to'): [number, number] | null {\n const node = this.nodes.find((n) => n.id === (end === 'from' ? l.from : l.to));\n if (node === undefined) return null;\n const port = end === 'from'\n ? node.outPorts.find((p) => p.id === l.fromPort)\n : node.inPorts.find((p) => p.id === l.toPort);\n if (port === undefined) return null;\n return [port.cx, port.cy];\n }\n\n // ---- linking rules ----------------------------------------------\n validateLink(init: Pick<LinkInit, 'from' | 'fromPort' | 'to' | 'toPort'>, excludeLinkId?: string): LinkValidationResult {\n const fromNode = this.nodes.find((node) => node.id === init.from);\n const toNode = this.nodes.find((node) => node.id === init.to);\n if (fromNode === undefined || toNode === undefined) return { allowed: false, reason: 'missing-node' };\n const fromPort = fromNode.outPorts.find((port) => port.id === init.fromPort);\n const toPort = toNode.inPorts.find((port) => port.id === init.toPort);\n if (fromPort === undefined || toPort === undefined) return { allowed: false, reason: 'missing-port' };\n return this.validateLinkModels(fromNode, fromPort, toNode, toPort, excludeLinkId);\n }\n\n private validateLinkModels(\n fromNode: NodeModel,\n fromPort: PortModel,\n toNode: NodeModel,\n toPort: PortModel,\n excludeLinkId?: string,\n ): LinkValidationResult {\n if (fromNode === toNode) return { allowed: false, reason: 'same-node' };\n if (fromPort.direction !== 'out' || toPort.direction !== 'in') {\n return { allowed: false, reason: 'invalid-direction' };\n }\n const relevantLinks = this.links.filter((link) => link.id !== excludeLinkId);\n if (relevantLinks.some((link) => link.from === fromNode.id\n && link.fromPort === fromPort.id\n && link.to === toNode.id\n && link.toPort === toPort.id)) {\n return { allowed: false, reason: 'duplicate-link' };\n }\n if (fromPort.maxLinks > 0) {\n const used = relevantLinks.filter((link) => link.from === fromNode.id && link.fromPort === fromPort.id).length;\n if (used >= fromPort.maxLinks) return { allowed: false, reason: 'source-limit' };\n }\n if (toPort.maxLinks > 0) {\n const used = relevantLinks.filter((link) => link.to === toNode.id && link.toPort === toPort.id).length;\n if (used >= toPort.maxLinks) return { allowed: false, reason: 'target-limit' };\n }\n if (!arePortTypesCompatible(fromPort.type, toPort.type, toPort.availableTypes)) {\n return { allowed: false, reason: 'incompatible-type' };\n }\n if (this.validator !== null && !this.validator({ fromNode, fromPort, toNode, toPort })) {\n return { allowed: false, reason: 'host-rejected' };\n }\n return { allowed: true, reason: 'allowed' };\n }\n\n private removeIncompatibleLinks(matches: (link: LinkModel) => boolean): void {\n const incompatible = this.links.filter((link) => matches(link) && !this.canExistingLinkRemain(link));\n for (const link of incompatible) this.removeLinkInternal(link, true);\n }\n\n private canExistingLinkRemain(link: LinkModel): boolean {\n const fromNode = this.nodes.find((node) => node.id === link.from);\n const toNode = this.nodes.find((node) => node.id === link.to);\n const fromPort = fromNode?.outPorts.find((port) => port.id === link.fromPort);\n const toPort = toNode?.inPorts.find((port) => port.id === link.toPort);\n if (fromNode === undefined || toNode === undefined || fromPort === undefined || toPort === undefined) {\n return false;\n }\n if (!arePortTypesCompatible(fromPort.type, toPort.type, toPort.availableTypes)) return false;\n return this.validator === null || this.validator({ fromNode, fromPort, toNode, toPort });\n }\n // Plug\u2194socket magnet: while dragging from an out-port, find the\n // nearest in-port (within SNAP_PX, screen space) the link is allowed\n // to land on. Returns null when none is close \u2192 the pending link\n // detaches and follows the cursor again.\n private findSnap(): { node: NodeModel; port: PortModel } | null {\n if (this.linking === null && this.relinking === null) return null;\n let direction: PortDirection;\n let accepts: (node: NodeModel, port: PortModel) => boolean;\n if (this.linking !== null) {\n const source = this.linking;\n direction = 'in';\n accepts = (node, port) => this.validateLinkModels(source.node, source.port, node, port).allowed;\n } else {\n const gesture = this.relinking!;\n if (gesture.end === 'to') {\n const sourceNode = this.nodes.find((node) => node.id === gesture.link.from);\n const sourcePort = sourceNode?.outPorts.find((port) => port.id === gesture.link.fromPort);\n if (sourceNode === undefined || sourcePort === undefined) return null;\n direction = 'in';\n accepts = (node, port) => this.validateLinkModels(\n sourceNode, sourcePort, node, port, gesture.link.id,\n ).allowed;\n } else {\n const targetNode = this.nodes.find((node) => node.id === gesture.link.to);\n const targetPort = targetNode?.inPorts.find((port) => port.id === gesture.link.toPort);\n if (targetNode === undefined || targetPort === undefined) return null;\n direction = 'out';\n accepts = (node, port) => this.validateLinkModels(\n node, port, targetNode, targetPort, gesture.link.id,\n ).allowed;\n }\n }\n let best: { node: NodeModel; port: PortModel } | null = null;\n let bestD = SNAP_PX;\n for (const n of this.nodes) {\n const ports = direction === 'in' ? n.inPorts : n.outPorts;\n for (const p of ports) {\n if (!accepts(n, p)) continue;\n const [sx, sy] = this.toScreen(p.cx, p.cy);\n const dpx = Math.hypot(sx - this.cursor.x, sy - this.cursor.y);\n if (dpx <= bestD) { bestD = dpx; best = { node: n, port: p }; }\n }\n }\n return best;\n }\n\n private selectNode(n: NodeModel | null): void {\n this.selectedLink = null;\n this.selectedPort = null;\n this.selectedNodes.clear();\n if (n !== null) this.selectedNodes.add(n);\n this.selectedNode = n;\n this.emit('nodeSelected', { node: n, selected: n !== null });\n this.emitSelectionChanged();\n this.scheduleDraw();\n }\n private toggleSelect(n: NodeModel): void {\n this.selectedLink = null;\n this.selectedPort = null;\n if (this.selectedNodes.has(n)) {\n this.selectedNodes.delete(n);\n if (this.selectedNode === n) this.selectedNode = null;\n } else {\n this.selectedNodes.add(n);\n this.selectedNode = n;\n }\n this.emit('nodeSelected', { node: this.selectedNode, selected: this.selectedNodes.size > 0 });\n this.emitSelectionChanged();\n this.scheduleDraw();\n }\n private setSelection(ns: NodeModel[]): void {\n this.selectedLink = null;\n this.selectedPort = null;\n this.selectedNodes = new Set(ns);\n this.selectedNode = ns.length > 0 ? ns[ns.length - 1] : null;\n this.emit('nodeSelected', { node: this.selectedNode, selected: ns.length > 0 });\n this.emitSelectionChanged();\n this.scheduleDraw();\n }\n private selectLink(l: LinkModel | null): void {\n if (this.selectedLink === l) return;\n this.selectedNode = null;\n this.selectedNodes.clear();\n this.selectedPort = null;\n this.selectedLink = l;\n this.emit('linkSelected', { link: l, selected: l !== null });\n this.emitSelectionChanged();\n this.scheduleDraw();\n }\n private selectPort(target: { node: NodeModel; port: PortModel }): void {\n this.selectedPort = target;\n this.emit('portSelected', target);\n this.emitSelectionChanged();\n this.scheduleDraw();\n }\n private emitSelectionChanged(): void {\n this.emit('selectionChanged', this.getSelection());\n }\n // ---- clipboard (copy / paste of the selection) ------------------\n copySelection(): void {\n this.copySelectionDocument();\n }\n copySelectionDocument(): DiagramDocument | null {\n if (!this.permissions.copy) return null;\n if (this.selectedNodes.size === 0) { this.clip = null; return null; }\n const ids = new Set([...this.selectedNodes].map((n) => n.id));\n const all = this.saveDocument();\n this.clip = createDiagramDocument({\n nodes: all.nodes.filter((n) => ids.has(n.id)),\n links: all.links.filter((link) => ids.has(link.from.nodeId) && ids.has(link.to.nodeId)),\n });\n return parseDiagramDocument(this.clip);\n }\n hasClipboard(): boolean {\n return this.clip !== null && this.clip.nodes.length > 0;\n }\n getClipboardDocument(): DiagramDocument | null {\n return this.clip === null ? null : parseDiagramDocument(this.clip);\n }\n setClipboardDocument(source: DiagramDocument | string): void {\n this.clip = parseDiagramDocument(source);\n }\n pasteSelection(): string[] {\n if (this.clip === null) return [];\n return this.pasteDocument(this.clip);\n }\n pasteDocument(source: DiagramDocument | string, offset?: { x: number; y: number }): string[] {\n if (!this.permissions.paste) return [];\n const clipboard = parseDiagramDocument(source);\n if (clipboard.nodes.length === 0) return [];\n const pasteOffset = offset ?? { x: this.gridSize, y: this.gridSize };\n this.clip = clipboard;\n const map = new Map<string, string>();\n const added: NodeModel[] = [];\n // Paste of N nodes + M links collapses into ONE undo step.\n this.withTransaction('paste', () => {\n for (const sn of clipboard.nodes) {\n const nid = this.nextNodeId();\n map.set(sn.id, nid);\n const id = this.addDiagramNode({\n ...sn,\n id: nid,\n x: sn.x + pasteOffset.x,\n y: sn.y + pasteOffset.y,\n });\n const nn = this.nodes.find((x) => x.id === id);\n if (nn !== undefined) added.push(nn);\n }\n for (const l of clipboard.links) {\n const f = map.get(l.from.nodeId);\n const t = map.get(l.to.nodeId);\n if (f !== undefined && t !== undefined)\n this.addLink({\n from: f,\n fromPort: l.from.portId,\n to: t,\n toPort: l.to.portId,\n // The clipboard is built from saveDocument(), so it carries the style;\n // rebuilding without it silently turned every pasted dashed link solid.\n style: l.style,\n metadata: l.metadata,\n });\n }\n });\n this.setSelection(added);\n return added.map((node) => node.id);\n }\n\n // ---- input ------------------------------------------------------\n // Ends hover and everything hanging off it: highlight, cursor and the delayed tooltip.\n private clearHover(): void {\n if (this.hoverPort !== null) this.emit('portHover', { node: this.hoverPort.node, port: this.hoverPort.port, hovering: false });\n if (this.hoverNode !== null) this.emit('nodeHover', { node: this.hoverNode, hovering: false });\n if (this.hoveredLink !== null) this.emit('linkHover', { link: this.hoveredLink, hovering: false });\n this.hoverPort = null; this.hoverNode = null; this.hoveredLink = null;\n this.tipTarget = null; this.tipShow = false;\n if (this.tipTimer !== null) { clearTimeout(this.tipTimer); this.tipTimer = null; }\n this.canvas.style.cursor = 'default';\n this.scheduleDraw();\n }\n\n private cancelLongPress(): void {\n if (this.lpTimer !== null) { clearTimeout(this.lpTimer); this.lpTimer = null; }\n this.lpStart = null;\n }\n /// Ends a node drag the way releasing the pointer does: the whole multi-node move becomes\n /// one undo step, and every node that actually moved is announced. Nodes are moved in place\n /// as the pointer travels, so a caller that clears the drag without coming through here\n /// leaves them where the drag put them with nothing in the history and the host unaware.\n private commitNodeDrag(): void {\n if (this.dragNode === null) return;\n\n // Capture before/after positions so the whole multi-node\n // drag is ONE undo step. Skip the action if nothing\n // actually moved (a \"click\" that bypassed the threshold).\n const moves = this.dragStart\n .map((it) => ({ id: it.n.id, fromX: it.x, fromY: it.y, toX: it.n.x, toY: it.n.y }))\n .filter((m) => m.fromX !== m.toX || m.fromY !== m.toY);\n // Announce the same set the undo step records. Emitting for every node the drag\n // touched reported a move for a plain selection click -- one per selected node --\n // and a host doing dirty tracking marked the strategy modified for nothing.\n const moved = new Set(moves.map((m) => m.id));\n for (const it of this.dragStart) {\n if (moved.has(it.n.id)) this.emit('nodeMoved', { node: it.n });\n }\n this.dragNode = null;\n this.dragStart = [];\n if (moves.length > 0) {\n this.record({\n do: () => { for (const m of moves) this.doMoveNode(m.id, m.toX, m.toY); },\n undo: () => { for (const m of moves) this.doMoveNode(m.id, m.fromX, m.fromY); },\n label: 'drag',\n });\n }\n }\n\n // Hit-test at screen coords and emit a contextMenu event. Ends whatever gesture was in\n // flight \u2014 once the menu opens we don't want a half-drag racing it \u2014 and a node drag ends\n // properly rather than being dropped, because its nodes have already moved.\n private fireContextMenu(sx: number, sy: number, pageX: number, pageY: number): void {\n this.commitNodeDrag();\n const [wx, wy] = this.toWorld(sx, sy);\n const port = this.portAt(wx, wy);\n const node = port?.node ?? this.nodeAt(wx, wy);\n const link = port === null && node === null ? this.linkAt(wx, wy) : null;\n if (this.permissions.select) {\n if (port !== null) {\n const selectedLink = this.selectedLink;\n const isSelectedEndpoint = selectedLink !== null\n && ((selectedLink.from === port.node.id && selectedLink.fromPort === port.port.id)\n || (selectedLink.to === port.node.id && selectedLink.toPort === port.port.id));\n if (!isSelectedEndpoint && !this.selectedNodes.has(port.node)) this.selectNode(port.node);\n this.selectPort(port);\n } else if (node !== null && !this.selectedNodes.has(node)) this.selectNode(node);\n else if (link !== null && this.selectedLink !== link) this.selectLink(link);\n }\n this.dragNode = null; this.dragStart = []; this.rubber = null;\n this.linking = null; this.relinking = null; this.relinkCandidate = null; this.linkSnap = null;\n // A pan ends here too, and it ends settled: a host that persists the viewport on the\n // settled event would otherwise keep the position the pan started from.\n const viewportMoved = this.panning || this.ovDragging;\n this.panning = false;\n this.ovDragging = false;\n if (viewportMoved) this.emitViewChanged(false);\n // A menu is about to cover this spot, and it opens under a cursor that has not moved --\n // which fires no boundary event, so nothing else would end the hover. Without this the\n // tooltip armed by the last pointermove appears 400ms later, through the open menu.\n this.clearHover();\n this.emit('contextMenu', { x: pageX, y: pageY, link, node, port });\n }\n\n private listen<K extends keyof HTMLElementEventMap>(\n target: HTMLElement,\n type: K,\n listener: (event: HTMLElementEventMap[K]) => void,\n options?: boolean | AddEventListenerOptions,\n ): void;\n private listen<K extends keyof WindowEventMap>(\n target: Window,\n type: K,\n listener: (event: WindowEventMap[K]) => void,\n options?: boolean | AddEventListenerOptions,\n ): void;\n private listen(\n target: EventTarget,\n type: string,\n listener: EventListener,\n options?: boolean | AddEventListenerOptions,\n ): void {\n target.addEventListener(type, listener, options);\n this.domDisposables.push(() => target.removeEventListener(type, listener, options));\n }\n\n private bind(): void {\n const localXY = (e: MouseEvent | PointerEvent): [number, number] => {\n const r = this.canvas.getBoundingClientRect();\n return [e.clientX - r.left, e.clientY - r.top];\n };\n this.listen(this.canvas, 'pointerdown', (e) => {\n try { (this.canvas as Element).setPointerCapture(e.pointerId); } catch { /* unsupported */ }\n // Arm a long-press timer on every pointerdown. Cancelled by\n // move-beyond-tolerance, pointerup, or any other gesture.\n this.cancelLongPress();\n this.relinkCandidate = null;\n // Touch only. A mouse has a button for this, and arming the timer for it meant holding\n // the left button still -- which is what positioning a node precisely looks like --\n // opened the menu after half a second and wiped the drag in progress: the pixels the\n // node had already travelled stayed, but never reached history, so Ctrl+Z could not\n // take them back.\n if (e.pointerType !== 'mouse') {\n this.lpStart = { sx: e.clientX, sy: e.clientY, px: e.clientX, py: e.clientY };\n const downSx = e.clientX, downSy = e.clientY;\n const r0 = this.canvas.getBoundingClientRect();\n const localSx = downSx - r0.left, localSy = downSy - r0.top;\n this.lpTimer = setTimeout(() => {\n this.lpTimer = null;\n this.fireContextMenu(localSx, localSy, downSx, downSy);\n }, this.lpDelayMs);\n }\n this.canvas.focus();\n const [sx, sy] = localXY(e);\n if (this.ovHit(sx, sy)) { this.ovDragging = true; this.ovPanTo(sx, sy); return; }\n if (!this.permissions.inspect) this.cancelLongPress();\n const [wx, wy] = this.toWorld(sx, sy);\n const selectedEndpoint = this.selectedLinkEndpointAt(wx, wy);\n if (e.button === 0 && this.permissions.createLinks && this.selectedLink !== null\n && selectedEndpoint !== null) {\n this.relinking = { link: this.selectedLink, end: selectedEndpoint };\n this.linking = null;\n this.linkSnap = null;\n this.cursor = { x: sx, y: sy };\n return;\n }\n const portHit = this.portAt(wx, wy);\n if (portHit !== null) {\n const selectedLink = this.selectedLink;\n const isFrom = selectedLink !== null\n && portHit.port.direction === 'out'\n && selectedLink.from === portHit.node.id\n && selectedLink.fromPort === portHit.port.id;\n const isTo = selectedLink !== null\n && portHit.port.direction === 'in'\n && selectedLink.to === portHit.node.id\n && selectedLink.toPort === portHit.port.id;\n if (this.permissions.inspect) {\n if (this.permissions.select && !isFrom && !isTo && !this.selectedNodes.has(portHit.node)) {\n this.selectNode(portHit.node);\n }\n this.selectPort(portHit);\n if (e.button === 0 || e.button === 2) {\n this.emit('portClicked', {\n ...portHit,\n action: e.button === 2 ? 'rightClick' : 'leftClick',\n ctrlKey: e.ctrlKey,\n shiftKey: e.shiftKey,\n altKey: e.altKey,\n metaKey: e.metaKey,\n });\n }\n }\n if (e.button !== 0) return;\n if (this.permissions.createLinks && selectedLink !== null) {\n if (isFrom || isTo) {\n this.relinking = { link: selectedLink, end: isFrom ? 'from' : 'to' };\n this.linking = null;\n this.linkSnap = null;\n this.cursor = { x: sx, y: sy };\n return;\n }\n }\n // A single existing input link can be rewired in one drag\n // without a separate selection click.\n const directRelink = this.permissions.createLinks\n ? this.directRelinkAtPort(portHit.node, portHit.port)\n : null;\n if (directRelink !== null) {\n this.relinkCandidate = { ...directRelink, sx, sy };\n this.linking = null;\n this.relinking = null;\n this.linkSnap = null;\n this.cursor = { x: sx, y: sy };\n return;\n }\n // Other output sockets start an additional link; input sockets\n // consume the gesture so they never drag the whole diagram.\n if (this.permissions.createLinks && portHit.port.direction === 'out') {\n this.linking = portHit;\n this.relinking = null;\n this.linkSnap = null;\n this.cursor = { x: sx, y: sy };\n }\n return;\n }\n const node = this.nodeAt(wx, wy);\n if (node !== null) {\n const add = e.shiftKey || e.ctrlKey || e.metaKey;\n if (this.permissions.select) {\n // A right-click still selects what it landed on, so the menu that follows acts\n // on the node under the cursor -- but only the primary button may drag it.\n if (add && e.button === 0) { this.toggleSelect(node); return; }\n if (!this.selectedNodes.has(node)) this.selectNode(node);\n }\n if (this.permissions.moveNodes && e.button === 0) {\n this.dragNode = node;\n this.dragAnchor = { wx, wy };\n const moving = this.selectedNodes.has(node) ? [...this.selectedNodes] : [node];\n this.dragStart = moving.map((item) => ({ n: item, x: item.x, y: item.y }));\n const selected = new Set(moving);\n this.nodes = this.nodes.filter((item) => !selected.has(item)).concat(moving);\n }\n return;\n }\n const link = this.linkAt(wx, wy);\n if (link !== null) {\n if (this.permissions.select) this.selectLink(link);\n return;\n }\n // A secondary button on empty canvas is on its way to the context menu: it must not\n // clear the selection the menu is about to act on, nor start a rubber band.\n if (e.button !== 0 && e.button !== 1) return;\n // empty space: middle-button / Ctrl / Alt / touch = pan;\n // else rubber-band select. Touch always pans because mobile\n // users can't hold modifier keys and rubber-band drag-select\n // is awkward with a finger.\n const wantPan = !this.permissions.select || e.button === 1 || e.ctrlKey || e.altKey || e.pointerType === 'touch';\n if (wantPan) {\n if (this.permissions.select && !e.shiftKey) this.selectNode(null);\n this.panning = true; this.panX = sx; this.panY = sy;\n } else {\n if (!e.shiftKey) this.selectNode(null);\n this.rubber = { x0: wx, y0: wy, x: wx, y: wy };\n }\n });\n this.listen(this.canvas, 'pointermove', (e) => {\n const [sx, sy] = localXY(e);\n this.cursor = { x: sx, y: sy };\n // movement past tolerance \u2192 not a long-press anymore\n if (this.lpStart !== null) {\n const dx = e.clientX - this.lpStart.px;\n const dy = e.clientY - this.lpStart.py;\n if (Math.hypot(dx, dy) > this.lpMoveTol) this.cancelLongPress();\n }\n if (this.ovDragging) { this.ovPanTo(sx, sy); return; }\n const [wx, wy] = this.toWorld(sx, sy);\n if (this.relinkCandidate !== null) {\n const candidate = this.relinkCandidate;\n if (Math.hypot(sx - candidate.sx, sy - candidate.sy) <= RELINK_DRAG_THRESHOLD_PX) return;\n this.relinkCandidate = null;\n this.relinking = { link: candidate.link, end: candidate.end };\n if (this.permissions.select) this.selectLink(candidate.link);\n this.linkSnap = this.findSnap();\n this.scheduleDraw();\n return;\n }\n if (this.dragNode !== null) {\n let ddx = wx - this.dragAnchor.wx;\n let ddy = wy - this.dragAnchor.wy;\n if (this.gridSnapEnabled) {\n const primary = this.dragStart.find((item) => item.n === this.dragNode);\n if (primary !== undefined) {\n ddx = Math.round((primary.x + ddx) / this.gridSize) * this.gridSize - primary.x;\n ddy = Math.round((primary.y + ddy) / this.gridSize) * this.gridSize - primary.y;\n }\n }\n for (const it of this.dragStart) {\n it.n.x = it.x + ddx;\n it.n.y = it.y + ddy;\n this.layoutNode(it.n);\n }\n this.scheduleDraw();\n return;\n }\n if (this.rubber !== null) {\n this.rubber.x = wx; this.rubber.y = wy;\n this.scheduleDraw();\n return;\n }\n if (this.panning) {\n this.offX += sx - this.panX;\n this.offY += sy - this.panY;\n this.panX = sx; this.panY = sy;\n this.scheduleDraw();\n return;\n }\n if (this.linking !== null || this.relinking !== null) {\n this.linkSnap = this.findSnap();\n this.scheduleDraw();\n return;\n }\n if (!this.permissions.inspect) return;\n let dirty = false;\n // port hover\n const hit = this.portAt(wx, wy);\n if ((hit?.port ?? null) !== (this.hoverPort?.port ?? null)) {\n if (this.hoverPort !== null)\n this.emit('portHover', { node: this.hoverPort.node, port: this.hoverPort.port, hovering: false });\n this.hoverPort = hit;\n if (hit !== null) this.emit('portHover', { node: hit.node, port: hit.port, hovering: true });\n dirty = true;\n }\n // node hover (for tooltip)\n const nodeHit = hit === null ? this.nodeAt(wx, wy) : null;\n if (nodeHit !== this.hoverNode) {\n if (this.hoverNode !== null) this.emit('nodeHover', { node: this.hoverNode, hovering: false });\n this.hoverNode = nodeHit;\n if (nodeHit !== null) this.emit('nodeHover', { node: nodeHit, hovering: true });\n dirty = true;\n }\n // hover-delay before the tooltip appears\n const tipTgt: PortModel | NodeModel | null = this.hoverPort?.port ?? this.hoverNode;\n if (tipTgt !== this.tipTarget) {\n this.tipTarget = tipTgt;\n this.tipShow = false;\n if (this.tipTimer !== null) { clearTimeout(this.tipTimer); this.tipTimer = null; }\n if (tipTgt !== null) {\n this.tipTimer = setTimeout(() => {\n this.tipTimer = null;\n this.tipShow = true;\n this.scheduleDraw();\n }, 400);\n }\n dirty = true;\n }\n // link hover (only when not over a port/node)\n const overNode = nodeHit !== null;\n const linkHit = hit === null && !overNode ? this.linkAt(wx, wy) : null;\n if (linkHit !== this.hoveredLink) {\n if (this.hoveredLink !== null) this.emit('linkHover', { link: this.hoveredLink, hovering: false });\n this.hoveredLink = linkHit;\n if (linkHit !== null) this.emit('linkHover', { link: linkHit, hovering: true });\n dirty = true;\n }\n const endpointHit = this.permissions.createLinks ? this.selectedLinkEndpointAt(wx, wy) : null;\n const directRelinkHit = this.permissions.createLinks && hit !== null\n ? this.directRelinkAtPort(hit.node, hit.port)\n : null;\n this.canvas.style.cursor = endpointHit !== null || directRelinkHit !== null ? 'grab'\n : hit !== null ? 'pointer'\n : overNode ? 'move'\n : linkHit !== null ? 'pointer' : 'default';\n if (dirty) this.scheduleDraw();\n });\n const finish = (e: MouseEvent | PointerEvent): void => {\n this.cancelLongPress();\n this.relinkCandidate = null;\n this.commitNodeDrag();\n if (this.rubber !== null) {\n const rx0 = Math.min(this.rubber.x0, this.rubber.x);\n const ry0 = Math.min(this.rubber.y0, this.rubber.y);\n const rx1 = Math.max(this.rubber.x0, this.rubber.x);\n const ry1 = Math.max(this.rubber.y0, this.rubber.y);\n this.rubber = null;\n if (rx1 - rx0 > 3 || ry1 - ry0 > 3) {\n const inRect = this.nodes.filter((n) =>\n n.x < rx1 && n.x + n.w > rx0 && n.y < ry1 && n.y + n.h > ry0);\n const merge = e.shiftKey ? [...this.selectedNodes, ...inRect] : inRect;\n this.setSelection([...new Set(merge)]);\n }\n this.scheduleDraw();\n }\n const viewportMoved = this.panning || this.ovDragging;\n this.panning = false;\n this.ovDragging = false;\n if (viewportMoved) this.emitViewChanged(false);\n if (this.linking !== null) {\n const [sx, sy] = localXY(e);\n const [wx, wy] = this.toWorld(sx, sy);\n // Commit to the magnetised socket if one is engaged;\n // otherwise fall back to whatever is exactly under the\n // cursor (covers a precise drop without a snap).\n const direct = this.portAt(wx, wy);\n const target = this.linkSnap\n ?? (direct !== null && direct.port.direction === 'in' ? direct : null);\n if (target !== null) {\n this.addLink({\n from: this.linking.node.id, fromPort: this.linking.port.id,\n to: target.node.id, toPort: target.port.id,\n });\n }\n this.linking = null;\n this.linkSnap = null;\n this.scheduleDraw();\n }\n if (this.relinking !== null) {\n const gesture = this.relinking;\n const [sx, sy] = localXY(e);\n const [wx, wy] = this.toWorld(sx, sy);\n const direct = this.portAt(wx, wy);\n const expectedDirection: PortDirection = gesture.end === 'from' ? 'out' : 'in';\n const target = this.linkSnap\n ?? (direct !== null && direct.port.direction === expectedDirection ? direct : null);\n if (target !== null) {\n this.relink(gesture.link.id, {\n from: gesture.end === 'from' ? target.node.id : gesture.link.from,\n fromPort: gesture.end === 'from' ? target.port.id : gesture.link.fromPort,\n to: gesture.end === 'to' ? target.node.id : gesture.link.to,\n toPort: gesture.end === 'to' ? target.port.id : gesture.link.toPort,\n });\n }\n this.relinking = null;\n this.linkSnap = null;\n this.scheduleDraw();\n }\n };\n this.listen(window, 'pointerup', finish);\n this.listen(window, 'pointercancel', finish);\n this.listen(this.canvas, 'wheel', (e) => {\n e.preventDefault();\n const [sx, sy] = localXY(e);\n const [wx, wy] = this.toWorld(sx, sy);\n // Smooth, device-consistent: zoom amount tracks wheel delta\n // magnitude instead of a fixed step (no more big jumps).\n const factor = Math.exp(-e.deltaY * 0.0015);\n this.scale = clamp(this.scale * factor, ZOOM_MIN, ZOOM_MAX);\n this.offX = sx - wx * this.scale;\n this.offY = sy - wy * this.scale;\n this.emitViewChanged(true);\n this.scheduleDraw();\n }, { passive: false });\n this.listen(this.canvas, 'pointerleave', () => this.clearHover());\n this.listen(this.canvas, 'dblclick', (e) => {\n const [sx, sy] = localXY(e);\n const [wx, wy] = this.toWorld(sx, sy);\n if (this.portAt(wx, wy) !== null) return;\n // A wire is something, not empty canvas: without this the zoomToFit fallback below\n // threw away the zoom and pan the user had set, on a double click aimed at a link.\n if (this.linkAt(wx, wy) !== null) return;\n const node = this.nodeAt(wx, wy);\n if (node !== null) {\n if (this.permissions.inspect && node.openAction.length > 0) {\n e.preventDefault();\n this.emit('nodeOpen', { node });\n }\n return;\n }\n this.zoomToFit();\n });\n // Desktop right-click \u2192 same contextMenu event as touch long-press.\n const openContextMenu = (e: MouseEvent): void => {\n e.preventDefault();\n if (!this.permissions.inspect) return;\n const [sx, sy] = localXY(e);\n this.cancelLongPress();\n this.fireContextMenu(sx, sy, e.clientX, e.clientY);\n };\n this.listen(this.canvas, 'contextmenu', openContextMenu);\n // The control is more than its canvas: its own buttons sit over the corners, and a\n // right-click on one of those stops at the button, so the browser drew its own menu\n // there. The canvas keeps its own handler, and this one skips what that already took.\n this.listen(this.host, 'contextmenu', (e) => {\n if (e.target !== this.canvas) openContextMenu(e);\n });\n // Two-finger pinch \u2192 uniform zoom around the initial midpoint\n // between the fingers. Mobile analog of mouse wheel.\n let pinchDist = 0;\n let pinchScale = 1;\n let pinchPivotW: [number, number] = [0, 0];\n let pinchPivotS: [number, number] = [0, 0];\n let pinching = false;\n this.listen(this.canvas, 'touchstart', (e) => {\n if (e.touches.length === 2) {\n e.preventDefault();\n const r = this.canvas.getBoundingClientRect();\n const t0 = e.touches[0], t1 = e.touches[1];\n const x0 = t0.clientX - r.left, y0 = t0.clientY - r.top;\n const x1 = t1.clientX - r.left, y1 = t1.clientY - r.top;\n pinchDist = Math.max(1, Math.hypot(x1 - x0, y1 - y0));\n pinchScale = this.scale;\n const mx = (x0 + x1) / 2, my = (y0 + y1) / 2;\n pinchPivotS = [mx, my];\n pinchPivotW = this.toWorld(mx, my);\n pinching = true;\n this.dragNode = null; this.dragStart = [];\n this.panning = false; this.rubber = null; this.linking = null;\n this.relinking = null; this.relinkCandidate = null;\n // The two the block used to miss: a finger that started on the minimap kept\n // panning the viewport against the pinch, and a cancelled wire drag left its\n // magnet highlight burned onto a socket until something else redrew it.\n this.ovDragging = false; this.linkSnap = null;\n }\n }, { passive: false });\n this.listen(this.canvas, 'touchmove', (e) => {\n if (pinching && e.touches.length === 2) {\n e.preventDefault();\n const r = this.canvas.getBoundingClientRect();\n const t0 = e.touches[0], t1 = e.touches[1];\n const x0 = t0.clientX - r.left, y0 = t0.clientY - r.top;\n const x1 = t1.clientX - r.left, y1 = t1.clientY - r.top;\n const d = Math.max(1, Math.hypot(x1 - x0, y1 - y0));\n const ns = clamp(pinchScale * (d / pinchDist), ZOOM_MIN, ZOOM_MAX);\n this.scale = ns;\n // Keep the pinch midpoint anchored at the world point it\n // started on (pivot stays put under the fingers).\n this.offX = pinchPivotS[0] - pinchPivotW[0] * ns;\n this.offY = pinchPivotS[1] - pinchPivotW[1] * ns;\n this.emitViewChanged(true);\n this.scheduleDraw();\n }\n }, { passive: false });\n const endPinch = (): void => { pinching = false; };\n this.listen(this.canvas, 'touchend', endPinch);\n this.listen(this.canvas, 'touchcancel', endPinch);\n this.listen(this.canvas, 'keydown', (e) => {\n if (this.permissions.moveNodes && !e.ctrlKey && !e.metaKey && !e.altKey) {\n const step = (this.gridSnapEnabled ? this.gridSize : 1) * (e.shiftKey ? 5 : 1);\n const delta = e.key === 'ArrowLeft' ? [-step, 0]\n : e.key === 'ArrowRight' ? [step, 0]\n : e.key === 'ArrowUp' ? [0, -step]\n : e.key === 'ArrowDown' ? [0, step]\n : null;\n if (delta !== null && this.nudgeSelection(delta[0], delta[1])) {\n e.preventDefault();\n return;\n }\n }\n if (this.permissions.deleteSelection && (e.key === 'Delete' || e.key === 'Backspace')) {\n e.preventDefault(); this.deleteSelection(); return;\n }\n const mod = e.ctrlKey || e.metaKey;\n if (mod && this.permissions.copy && e.code === 'KeyC') { e.preventDefault(); this.copySelection(); return; }\n if (mod && this.permissions.paste && e.code === 'KeyV') { e.preventDefault(); this.pasteSelection(); return; }\n if (mod && this.permissions.copy && this.permissions.deleteSelection && e.code === 'KeyX') {\n e.preventDefault(); this.cutSelection(); return;\n }\n if (mod && this.permissions.select && e.code === 'KeyA') { e.preventDefault(); this.setSelection(this.nodes.slice()); return; }\n // Ctrl+Z = undo; Ctrl+Y or Ctrl+Shift+Z = redo. Routed through a handler rather than\n // called directly: a component wrapping this renderer has its own rules about when\n // history may run and its own events to announce it, and the keyboard must obey them\n // like every other entry point.\n if (mod && this.permissions.history && e.code === 'KeyZ' && !e.shiftKey) { e.preventDefault(); this.historyShortcut('undo'); return; }\n if (mod && this.permissions.history && (e.code === 'KeyY' || (e.code === 'KeyZ' && e.shiftKey))) {\n e.preventDefault(); this.historyShortcut('redo'); return;\n }\n });\n }\n\n // ---- drawing ----------------------------------------------------\n private scheduleDraw(): void {\n if (this.destroyed || this.drawScheduled) return;\n this.drawScheduled = true;\n requestAnimationFrame(() => {\n this.drawScheduled = false;\n if (!this.destroyed) this.draw();\n });\n }\n private draw(options: DiagramRenderOptions = SCREEN_RENDER_OPTIONS): void {\n const ctx = this.ctx;\n ctx.clearRect(0, 0, this.width, this.height);\n ctx.fillStyle = this.opts.background ?? '#1b1b1f';\n ctx.fillRect(0, 0, this.width, this.height);\n // Entrance animation \u2014 scheme rises from below + fades in over\n // the opaque background.\n let introDy = 0;\n let introAlpha = 1;\n if (options.transient && this.introStart !== null) {\n const e = Math.min(1, (performance.now() - this.introStart) / INTRO_MS);\n const k = 1 - Math.pow(1 - e, 3); // easeOutCubic\n introAlpha = k;\n introDy = (1 - k) * INTRO_RISE;\n if (e >= 1) this.introStart = null;\n }\n ctx.save();\n ctx.globalAlpha = introAlpha;\n if (options.grid) this.drawGrid();\n ctx.setTransform(this.dpr * this.scale, 0, 0, this.dpr * this.scale,\n this.dpr * this.offX, this.dpr * (this.offY + introDy));\n // Zones sit under everything: they say where things are, and a place that painted over\n // its occupants would be worse than no place at all.\n this.drawZones();\n // Links next. Each link jumps over the verticals of the links\n // drawn before it (deterministic bridge \u2014 Link.JumpOver parity).\n const prior: Seg[] = []; // segments of links already drawn\n const hoveredNode = this.hoverPort?.node ?? this.hoverNode;\n for (const l of this.links) {\n const a = this.endpoint(l, 'from');\n const b = this.endpoint(l, 'to');\n if (a === null || b === null) continue;\n const fp = this.nodes.find((n) => n.id === l.from)?.outPorts.find((p) => p.id === l.fromPort);\n const baseColor = (this.opts.typedLinkColors ?? false) && fp !== undefined\n ? this.portColor(fp.type)\n : this.portColor('');\n const state = options.selection && l === this.selectedLink\n ? 'sel'\n : options.transient && (l === this.hoveredLink\n || (hoveredNode !== null && (l.from === hoveredNode.id || l.to === hoveredNode.id)))\n ? 'hov'\n : 'norm';\n const color = state === 'sel' ? this.selectionColor() : state === 'hov' ? this.linkHoverColor() : baseColor;\n const width = state === 'sel' ? 3 : state === 'hov' ? 2.6 : 2;\n const pts = this.routeLink(a, b, new Set([l.from, l.to]));\n this.strokeRoute(pts, color, width, prior, l.style);\n this.drawArrow(pts, color);\n for (let k = 1; k < pts.length; k += 1) {\n const [x1, y1] = pts[k - 1];\n const [x2, y2] = pts[k];\n if (x1 === x2 && y1 !== y2) prior.push({ h: false, c: x1, a: Math.min(y1, y2), b: Math.max(y1, y2) });\n else if (y1 === y2 && x1 !== x2) prior.push({ h: true, c: y1, a: Math.min(x1, x2), b: Math.max(x1, x2) });\n }\n }\n if (options.transient && (this.linking !== null || this.relinking !== null)) this.drawPendingLink();\n this.portFeed = this.feedTypes();\n for (const n of this.nodes) this.drawNode(n, options.selection && this.selectedNodes.has(n), options);\n if (options.selection && this.permissions.createLinks && this.relinking === null)\n this.drawSelectedLinkEndpoints();\n if (options.transient && this.rubber !== null) {\n const rx = Math.min(this.rubber.x0, this.rubber.x);\n const ry = Math.min(this.rubber.y0, this.rubber.y);\n const rw = Math.abs(this.rubber.x - this.rubber.x0);\n const rh = Math.abs(this.rubber.y - this.rubber.y0);\n ctx.fillStyle = 'rgba(74,163,255,0.12)';\n ctx.fillRect(rx, ry, rw, rh);\n ctx.strokeStyle = '#4aa3ff';\n ctx.lineWidth = 1 / this.scale;\n ctx.strokeRect(rx, ry, rw, rh);\n }\n ctx.restore();\n if (options.overview) this.drawOverview();\n if (options.runtime) this.drawGlobalError(options.transient);\n if (options.transient) this.drawTooltip();\n if (options.transient && (this.introStart !== null || this.globalErrorFlashStart !== null\n || this.nodes.some((n) => n.errorFlashStart !== null)))\n this.scheduleDraw(); // keep entrance / error feedback animating\n }\n /**\n * `transient` gates the flash exactly as it gates every other animation, which an export must\n * not see: it would bake in whatever point of the pulse it caught, so the same export taken\n * twice differed in opacity. The gate also keeps the export from consuming the animation --\n * clearing globalErrorFlashStart from an export cut the flash short on screen.\n */\n private drawGlobalError(transient: boolean): void {\n const error = this.runtimeState.globalError;\n if (error === null) return;\n const ctx = this.ctx;\n let flashAlpha = 1;\n if (transient && this.globalErrorFlashStart !== null) {\n const elapsed = performance.now() - this.globalErrorFlashStart;\n if (elapsed >= ERROR_FLASH_MS) {\n this.globalErrorFlashStart = null;\n } else {\n flashAlpha = 0.7 + 0.3 * (0.5 + 0.5 * Math.sin(\n elapsed / ERROR_FLASH_MS * Math.PI * 6 - Math.PI / 2));\n }\n }\n const neutral = error.kind === 'locked' || error.kind === 'encrypted';\n ctx.save();\n ctx.globalAlpha = flashAlpha;\n ctx.fillStyle = neutral ? 'rgba(18,20,26,0.82)' : 'rgba(55,16,22,0.78)';\n ctx.fillRect(0, 0, this.width, this.height);\n ctx.font = '600 15px Segoe UI, Tahoma, sans-serif';\n const lines = this.wrapTooltip(error.message, Math.max(120, Math.min(520, this.width - 80)));\n const lineHeight = 21;\n const boxWidth = Math.min(this.width - 32,\n Math.max(180, ...lines.map((line) => ctx.measureText(line).width + 36)));\n const boxHeight = lines.length * lineHeight + 32;\n const x = (this.width - boxWidth) / 2;\n const y = (this.height - boxHeight) / 2;\n roundRect(ctx, x, y, boxWidth, boxHeight, 8);\n ctx.fillStyle = neutral ? 'rgba(36,39,48,0.98)' : 'rgba(75,22,31,0.98)';\n ctx.fill();\n ctx.strokeStyle = neutral ? '#858b98' : ERROR_RED;\n ctx.lineWidth = 2;\n ctx.stroke();\n ctx.fillStyle = '#ffffff';\n ctx.textAlign = 'center';\n ctx.textBaseline = 'middle';\n lines.forEach((line, index) => {\n ctx.fillText(line, this.width / 2, y + 16 + lineHeight * index + lineHeight / 2);\n });\n ctx.restore();\n }\n private drawTooltip(): void {\n if (!this.tipShow) return; // wait out the hover delay\n if (this.dragNode !== null || this.linking !== null || this.relinking !== null || this.panning || this.ovDragging) return;\n let text = '';\n let isError = false;\n if (this.hoverPort !== null) {\n const p = this.hoverPort.port;\n text = p.type ? `${p.name} \u00B7 ${p.type}` : p.name;\n const runtime = this.portRuntimeState(this.hoverPort.node, p);\n if (runtime?.value !== null && runtime?.value !== undefined) text += `\\nValue: ${runtime.value}`;\n if (runtime?.error !== null && runtime?.error !== undefined) {\n text += `\\n${runtime.error}`;\n isError = true;\n }\n } else if (this.hoverNode !== null) {\n const n = this.hoverNode;\n const errors = [n.runtimeError, n.loadError].filter((value) => value.length > 0);\n if (errors.length > 0) {\n text = errors.join('\\n');\n isError = true;\n } else if (this.showNodeMessages && n.message.length > 0) {\n text = n.message;\n } else if (n.description.length > 0) {\n text = n.description;\n } else {\n text = n.typeId && n.typeId !== n.name ? `${n.name} [${n.typeId}]` : n.name;\n }\n } else {\n return;\n }\n const ctx = this.ctx;\n ctx.font = '11px Segoe UI, Tahoma, sans-serif';\n const padX = 9;\n const padY = 6;\n const lineH = 15;\n const lines = this.wrapTooltip(text, 340);\n const h = lines.length * lineH + padY * 2;\n const w = Math.max(...lines.map((line) => ctx.measureText(line).width)) + padX * 2;\n let x = this.cursor.x + 14;\n let y = this.cursor.y + 18;\n if (x + w > this.width) x = this.width - w - 4;\n if (y + h > this.height) y = this.cursor.y - h - 10;\n roundRect(ctx, x, y, w, h, 4);\n ctx.fillStyle = isError ? 'rgba(55,16,22,0.97)' : 'rgba(18,20,26,0.96)';\n ctx.fill();\n ctx.lineWidth = 1;\n ctx.strokeStyle = isError ? ERROR_RED : '#3a3a46';\n ctx.stroke();\n ctx.fillStyle = '#e8e8ee';\n ctx.textBaseline = 'middle';\n ctx.textAlign = 'left';\n lines.forEach((line, index) => {\n ctx.fillText(line, x + padX, y + padY + lineH * index + lineH / 2);\n });\n }\n private wrapTooltip(text: string, maxWidth: number): string[] {\n const lines: string[] = [];\n for (const paragraph of text.split(/\\r?\\n/)) {\n const words = paragraph.split(/\\s+/).filter(Boolean);\n if (words.length === 0) { lines.push(''); continue; }\n let line = words[0];\n for (let i = 1; i < words.length; i += 1) {\n const next = `${line} ${words[i]}`;\n if (this.ctx.measureText(next).width <= maxWidth) line = next;\n else { lines.push(line); line = words[i]; }\n }\n lines.push(line);\n }\n return lines.length > 0 ? lines : [''];\n }\n private drawZones(): void {\n if (this.zones.length === 0) return;\n\n const ctx = this.ctx;\n\n for (const zone of this.zones) {\n const tint = zone.color.length > 0 ? zone.color : (this.opts.zoneColor ?? '#8a8f98');\n ctx.save();\n roundRect(ctx, zone.x, zone.y, zone.width, zone.height, 10);\n ctx.globalAlpha = 0.12;\n ctx.fillStyle = tint;\n ctx.fill();\n ctx.globalAlpha = 0.5;\n ctx.setLineDash([10, 6]);\n ctx.lineWidth = 1.5;\n ctx.strokeStyle = tint;\n ctx.stroke();\n ctx.restore();\n\n if (zone.name.length === 0) continue;\n\n ctx.save();\n ctx.globalAlpha = 0.75;\n ctx.fillStyle = tint;\n ctx.font = '600 12px Segoe UI, Tahoma, sans-serif';\n ctx.textAlign = 'left';\n ctx.textBaseline = 'top';\n // Inside the top-left corner: a caption outside the box would collide with whatever\n // sits above it, and the corner is the one spot a rectangle always has to spare.\n ctx.fillText(zone.name, zone.x + 12, zone.y + 9, Math.max(0, zone.width - 24));\n ctx.restore();\n }\n }\n\n private drawGrid(): void {\n const ctx = this.ctx;\n const step = this.gridSize * this.scale;\n if (step < 6) return;\n ctx.strokeStyle = this.opts.gridColor ?? '#26262c';\n ctx.lineWidth = 1;\n const ox = this.offX % step;\n const oy = this.offY % step;\n ctx.beginPath();\n for (let x = ox; x < this.width; x += step) { ctx.moveTo(x + 0.5, 0); ctx.lineTo(x + 0.5, this.height); }\n for (let y = oy; y < this.height; y += step) { ctx.moveTo(0, y + 0.5); ctx.lineTo(this.width, y + 0.5); }\n ctx.stroke();\n }\n // Lazily load + cache a node-icon image by URL; repaints once it decodes.\n private getIcon(url: string): HTMLImageElement | null {\n const cached = this.iconCache.get(url);\n if (cached !== undefined) return cached; // img = ready; null = loading/failed\n this.iconCache.set(url, null); // mark in-flight to avoid duplicate loads\n const img = new Image();\n img.onload = () => { this.iconCache.set(url, img); this.scheduleDraw(); };\n img.onerror = () => { this.iconCache.set(url, null); };\n img.src = url;\n return null;\n }\n private drawNode(n: NodeModel, selected: boolean, options: DiagramRenderOptions): void {\n const ctx = this.ctx;\n const hasLoadError = options.runtime && n.loadError.length > 0;\n const hasRuntimeError = options.runtime && n.runtimeError.length > 0;\n const runtime = options.runtime ? getJsonKey(this.runtimeState.nodes, n.id) : undefined;\n const active = options.runtime\n && (this.runtimeState.activeNodeId === n.id || runtime?.active === true);\n roundRect(ctx, n.x, n.y, n.w, n.h, 6);\n ctx.fillStyle = hasLoadError ? ERROR_BACKGROUND : active ? '#ffd1dc' : n.color;\n ctx.fill();\n ctx.lineWidth = selected ? 2 : 1.5;\n ctx.strokeStyle = selected ? this.selectionColor() : n.border;\n ctx.stroke();\n if (hasLoadError || hasRuntimeError) {\n let alpha = 1;\n if (options.transient && hasRuntimeError && n.errorFlashStart !== null) {\n const elapsed = performance.now() - n.errorFlashStart;\n if (elapsed >= ERROR_FLASH_MS) {\n n.errorFlashStart = null;\n } else {\n // Three clear pulses before the border settles on red.\n alpha = 0.12 + 0.88 * (0.5 + 0.5 * Math.sin(\n elapsed / ERROR_FLASH_MS * Math.PI * 6 - Math.PI / 2));\n }\n }\n ctx.save();\n ctx.globalAlpha *= alpha;\n roundRect(ctx, n.x, n.y, n.w, n.h, 6);\n ctx.lineWidth = hasRuntimeError ? 3 : 2;\n ctx.strokeStyle = ERROR_RED;\n ctx.stroke();\n ctx.restore();\n }\n // Element icon on the left, vertically centred (lazy-loaded, cached).\n const iconW = 18;\n if (n.icon) {\n const img = this.getIcon(n.icon);\n if (img) { try { ctx.drawImage(img, n.x + 8, n.y + (n.h - iconW) / 2, iconW, iconW); } catch { /* undecodable */ } }\n }\n // Bold title centred on the body (nudged right when an icon shows so they\n // don't overlap); ports are bare colour squares on the edges. The title\n // takes its colour from the fill it sits on: that fill comes from the\n // scheme, so a node may well be darker than the title used to assume.\n const titleShift = n.icon ? iconW + 4 : 0;\n ctx.fillStyle = hasLoadError\n ? '#ffffff'\n : readableTextOn(active ? '#ffd1dc' : n.color);\n ctx.font = '600 12px Segoe UI, Tahoma, sans-serif';\n ctx.textAlign = 'center';\n ctx.textBaseline = 'middle';\n ctx.fillText(n.name, n.x + titleShift + (n.w - titleShift) / 2, n.y + n.h / 2, n.w - titleShift - 14);\n for (const p of n.inPorts) this.drawPort(n, p, options);\n for (const p of n.outPorts) this.drawPort(n, p, options);\n }\n private drawPort(node: NodeModel, p: PortModel, options: DiagramRenderOptions): void {\n const ctx = this.ctx;\n const hovered = options.transient && this.hoverPort?.port === p;\n const magnet = options.transient && this.linkSnap?.port === p;\n const runtime = options.runtime ? this.portRuntimeState(node, p) : null;\n const s = magnet ? PORT_SQ + 4 : hovered ? PORT_SQ + 2 : PORT_SQ;\n const x = p.cx - s / 2;\n const y = p.cy - s / 2;\n const r = Math.min(2.5, s / 4);\n if (magnet) {\n roundRect(ctx, x - 4, y - 4, s + 8, s + 8, r + 2);\n ctx.fillStyle = 'rgba(255,255,255,0.16)';\n ctx.fill();\n }\n // Single rounded path filled + stroked (aligned, anti-aliased \u2014\n // no half-pixel double edge).\n roundRect(ctx, x, y, s, s, r);\n ctx.fillStyle = this.portColor(this.portFillType(p));\n ctx.fill();\n ctx.lineWidth = magnet ? 1.5 : 1;\n ctx.strokeStyle = magnet ? '#ffffff' : 'rgba(12,12,16,0.55)';\n ctx.stroke();\n const runtimeSelected = runtime?.selected === true || (options.selection && this.selectedPort?.port === p);\n const breakpoint = runtime?.breakpoint === true;\n const breakpointActive = runtime?.breakpointActive === true;\n const runtimeActive = runtime?.active === true;\n const hasError = runtime?.error !== null && runtime?.error !== undefined;\n if (runtimeSelected || breakpoint || breakpointActive || runtimeActive || hasError) {\n ctx.beginPath();\n ctx.arc(p.cx, p.cy, s / 2 + 4, 0, Math.PI * 2);\n if (breakpointActive) {\n ctx.fillStyle = '#8b0000';\n ctx.fill();\n } else if (runtimeSelected) {\n ctx.fillStyle = 'rgba(211,211,211,0.56)';\n ctx.fill();\n }\n ctx.lineWidth = 2;\n ctx.strokeStyle = hasError || breakpointActive ? ERROR_RED\n : breakpoint ? '#ffb6c1'\n : runtimeActive ? '#ffffff'\n : '#d3d3d3';\n ctx.stroke();\n }\n }\n private portRuntimeState(node: NodeModel, port: PortModel): DiagramPortRuntimeState | null {\n return getJsonKey(this.runtimeState.nodes, node.id)?.ports[port.direction][port.id] ?? null;\n }\n // Symmetric jump-over: any segment of THIS link hops the perpendicular\n // segments of links drawn before it (H over earlier V, V over earlier\n // H). Exactly one bridge per real crossing, consistent everywhere.\n private strokeRoute(pts: number[][], color: string, width: number, prior: Seg[], style: DiagramLinkStyle = 'solid'): void {\n const ctx = this.ctx;\n ctx.strokeStyle = color;\n ctx.lineWidth = width;\n // The dash is measured in world units, so it keeps its rhythm as the canvas is zoomed.\n if (style === 'dashed') ctx.setLineDash([9, 6]);\n ctx.lineJoin = 'miter';\n ctx.lineCap = 'butt';\n ctx.beginPath();\n ctx.moveTo(pts[0][0], pts[0][1]);\n const H = LINK_HOP;\n // End a segment at its elbow with a rounded corner toward the next point (arcTo), clamped so it never\n // eats more than half of either adjacent segment. The final segment ends straight into the port.\n const finish = (i: number, x1: number, y1: number, x2: number, y2: number): void => {\n if (i < pts.length - 1) {\n const nx = pts[i + 1][0];\n const ny = pts[i + 1][1];\n const seg1 = Math.abs(x2 - x1) + Math.abs(y2 - y1);\n const seg2 = Math.abs(nx - x2) + Math.abs(ny - y2);\n ctx.arcTo(x2, y2, nx, ny, Math.min(LINK_CORNER, seg1 / 2, seg2 / 2));\n } else {\n ctx.lineTo(x2, y2);\n }\n };\n for (let i = 1; i < pts.length; i += 1) {\n const [x1, y1] = pts[i - 1];\n const [x2, y2] = pts[i];\n if (y1 === y2 && x1 !== x2) {\n const dir = x2 > x1 ? 1 : -1;\n const cuts = prior\n .filter((s) => !s.h && s.a < y1 - 0.5 && y1 + 0.5 < s.b &&\n Math.min(x1, x2) + H < s.c && s.c < Math.max(x1, x2) - H)\n .map((s) => s.c)\n .sort((p, q) => dir * (p - q));\n for (const cx of cuts) {\n ctx.lineTo(cx - dir * H, y1);\n if (dir > 0) ctx.arc(cx, y1, H, Math.PI, 2 * Math.PI, false);\n else ctx.arc(cx, y1, H, 0, Math.PI, true);\n }\n finish(i, x1, y1, x2, y2);\n } else if (x1 === x2 && y1 !== y2) {\n const dir = y2 > y1 ? 1 : -1;\n const cuts = prior\n .filter((s) => s.h && s.a < x1 - 0.5 && x1 + 0.5 < s.b &&\n Math.min(y1, y2) + H < s.c && s.c < Math.max(y1, y2) - H)\n .map((s) => s.c)\n .sort((p, q) => dir * (p - q));\n for (const cy of cuts) {\n ctx.lineTo(x1, cy - dir * H);\n if (dir > 0) ctx.arc(x1, cy, H, -Math.PI / 2, Math.PI / 2, false);\n else ctx.arc(x1, cy, H, Math.PI / 2, -Math.PI / 2, true);\n }\n finish(i, x1, y1, x2, y2);\n } else {\n ctx.lineTo(x2, y2);\n }\n }\n ctx.stroke();\n ctx.setLineDash([]);\n }\n private drawArrow(pts: number[][], color: string): void {\n const n = pts.length;\n const [px, py] = pts[n - 2];\n const [ex, ey] = pts[n - 1];\n const ang = Math.atan2(ey - py, ex - px);\n const ctx = this.ctx;\n ctx.save();\n ctx.translate(ex, ey);\n ctx.rotate(ang);\n ctx.fillStyle = color;\n ctx.beginPath();\n ctx.moveTo(0, 0); ctx.lineTo(-9, -4.5); ctx.lineTo(-9, 4.5); ctx.closePath();\n ctx.fill();\n ctx.restore();\n }\n private drawSelectedLinkEndpoints(): void {\n if (this.selectedLink === null) return;\n const ctx = this.ctx;\n const halfSize = RELINK_HANDLE_PX / 2 / this.scale;\n for (const end of ['from', 'to'] as const) {\n const point = this.endpoint(this.selectedLink, end);\n if (point === null) continue;\n ctx.beginPath();\n ctx.moveTo(point[0], point[1] - halfSize);\n ctx.lineTo(point[0] + halfSize, point[1]);\n ctx.lineTo(point[0], point[1] + halfSize);\n ctx.lineTo(point[0] - halfSize, point[1]);\n ctx.closePath();\n ctx.fillStyle = '#00ffff';\n ctx.fill();\n ctx.strokeStyle = '#000000';\n ctx.lineWidth = 1 / this.scale;\n ctx.stroke();\n }\n }\n private drawPendingLink(): void {\n if (this.linking === null && this.relinking === null) return;\n const ctx = this.ctx;\n const snapped = this.linkSnap;\n const cursor = this.toWorld(this.cursor.x, this.cursor.y) as [number, number];\n let a: [number, number];\n let b: [number, number];\n let colorType = '';\n let snapPoint: [number, number] | null = null;\n const excludedNodes = new Set<string>();\n\n if (this.linking !== null) {\n a = [this.linking.port.cx, this.linking.port.cy];\n b = snapped === null ? cursor : [snapped.port.cx, snapped.port.cy];\n colorType = this.linking.port.type;\n excludedNodes.add(this.linking.node.id);\n if (snapped !== null) snapPoint = b;\n } else {\n const gesture = this.relinking!;\n const fixed = this.endpoint(gesture.link, gesture.end === 'from' ? 'to' : 'from');\n if (fixed === null) return;\n const sourcePort = this.nodes.find((node) => node.id === gesture.link.from)?.outPorts\n .find((port) => port.id === gesture.link.fromPort);\n if (gesture.end === 'from') {\n a = snapped === null ? cursor : [snapped.port.cx, snapped.port.cy];\n b = fixed;\n colorType = snapped?.port.type ?? sourcePort?.type ?? '';\n excludedNodes.add(gesture.link.to);\n if (snapped !== null) snapPoint = a;\n } else {\n a = fixed;\n b = snapped === null ? cursor : [snapped.port.cx, snapped.port.cy];\n colorType = sourcePort?.type ?? '';\n excludedNodes.add(gesture.link.from);\n if (snapped !== null) snapPoint = b;\n }\n }\n if (snapped !== null) excludedNodes.add(snapped.node.id);\n const points = this.routeLink(a, b, excludedNodes);\n ctx.strokeStyle = this.portColor(colorType);\n if (snapped !== null) { ctx.setLineDash([]); ctx.lineWidth = 2.6; }\n else { ctx.setLineDash([5, 4]); ctx.lineWidth = 2; }\n ctx.beginPath();\n ctx.moveTo(points[0][0], points[0][1]);\n for (let index = 1; index < points.length; index += 1) ctx.lineTo(points[index][0], points[index][1]);\n ctx.stroke();\n ctx.setLineDash([]);\n if (snapPoint !== null) {\n ctx.beginPath();\n ctx.arc(snapPoint[0], snapPoint[1], PORT_R + 4, 0, Math.PI * 2);\n ctx.strokeStyle = '#ffffff';\n ctx.lineWidth = 2;\n ctx.stroke();\n }\n }\n\n // ---- overview minimap -------------------------------------------\n private overviewRect(): { x: number; y: number; w: number; h: number } | null {\n if (!this.overviewVisible || this.width < 320 || this.height < 220) return null;\n const w = 190, h = 130, m = 14;\n return { x: this.width - w - m, y: this.height - h - m, w, h };\n }\n private drawOverview(): void {\n const r = this.overviewRect();\n const gb = this.graphBounds();\n if (r === null || gb === null) { this.ovGeo = null; return; }\n const ctx = this.ctx;\n const pad = 8;\n const gw = (gb.maxX - gb.minX) || 1;\n const gh = (gb.maxY - gb.minY) || 1;\n const s = Math.min((r.w - pad * 2) / gw, (r.h - pad * 2) / gh);\n const ox = r.x + pad + ((r.w - pad * 2) - gw * s) / 2;\n const oy = r.y + pad + ((r.h - pad * 2) - gh * s) / 2;\n this.ovGeo = { x: ox, y: oy, w: r.w, h: r.h, s, minX: gb.minX, minY: gb.minY };\n const mx = (wx: number): number => ox + (wx - gb.minX) * s;\n const my = (wy: number): number => oy + (wy - gb.minY) * s;\n const light = colorLuminance(this.opts.background) >= 150;\n const overviewBackground = this.opts.overviewBackground\n ?? (light ? 'rgba(255,255,255,0.94)' : 'rgba(16,16,20,0.88)');\n const overviewBorder = this.opts.overviewBorderColor\n ?? (light ? '#cbd5e1' : '#3a3a44');\n const viewportColor = this.opts.overviewViewportColor\n ?? (light ? '#d97706' : '#4aa3ff');\n const viewportFill = this.opts.overviewViewportFill\n ?? (light ? 'rgba(217,119,6,0.10)' : 'rgba(74,163,255,0.10)');\n\n ctx.save();\n roundRect(ctx, r.x, r.y, r.w, r.h, 6);\n ctx.fillStyle = overviewBackground;\n ctx.fill();\n ctx.strokeStyle = overviewBorder;\n ctx.lineWidth = 1;\n ctx.stroke();\n ctx.clip();\n for (const n of this.nodes) {\n ctx.fillStyle = n.color;\n ctx.fillRect(mx(n.x), my(n.y), Math.max(2, n.w * s), Math.max(2, n.h * s));\n ctx.strokeStyle = n.border;\n ctx.lineWidth = 1;\n ctx.strokeRect(mx(n.x), my(n.y), Math.max(2, n.w * s), Math.max(2, n.h * s));\n }\n // viewport rectangle (what the main canvas currently shows)\n const [vx0, vy0] = this.toWorld(0, 0);\n const [vx1, vy1] = this.toWorld(this.width, this.height);\n ctx.strokeStyle = viewportColor;\n ctx.lineWidth = 1.5;\n ctx.strokeRect(mx(vx0), my(vy0), (vx1 - vx0) * s, (vy1 - vy0) * s);\n ctx.fillStyle = viewportFill;\n ctx.fillRect(mx(vx0), my(vy0), (vx1 - vx0) * s, (vy1 - vy0) * s);\n ctx.restore();\n }\n private ovHit(sx: number, sy: number): boolean {\n const r = this.overviewRect();\n return r !== null && sx >= r.x && sx <= r.x + r.w && sy >= r.y && sy <= r.y + r.h;\n }\n private ovPanTo(sx: number, sy: number): void {\n if (this.ovGeo === null) return;\n const g = this.ovGeo;\n const wx = g.minX + (sx - g.x) / g.s;\n const wy = g.minY + (sy - g.y) / g.s;\n this.offX = this.width / 2 - wx * this.scale;\n this.offY = this.height / 2 - wy * this.scale;\n this.scheduleDraw();\n }\n\n private emitViewChanged(zoomChanged: boolean): void {\n if (zoomChanged) this.emit('zoomChanged', { scale: this.scale });\n this.emit('viewChanged', this.getViewState());\n }\n}\n\nfunction roundRect(ctx: DrawSurface, x: number, y: number, w: number, h: number, r: number): void {\n const rr = Math.min(r, w / 2, h / 2);\n ctx.beginPath();\n ctx.moveTo(x + rr, y);\n ctx.arcTo(x + w, y, x + w, y + h, rr);\n ctx.arcTo(x + w, y + h, x, y + h, rr);\n ctx.arcTo(x, y + h, x, y, rr);\n ctx.arcTo(x, y, x + w, y, rr);\n ctx.closePath();\n}\n// Orthogonal route out-port \u2192 in-port. Forward (target to the right):\n// a 3-segment mid-X elbow. Backward/too-close: a 5-segment detour that\n// leaves the source rightward and re-enters the target from the left\n// (AvoidsNodes-style, never a diagonal).\nfunction route(a: [number, number], b: [number, number]): number[][] {\n const [ax, ay] = a;\n const [bx, by] = b;\n if (bx - ax >= LINK_STUB * 2) {\n const mx = (ax + bx) / 2;\n return [[ax, ay], [mx, ay], [mx, by], [bx, by]];\n }\n const midY = (ay + by) / 2;\n return [[ax, ay], [ax + LINK_STUB, ay], [ax + LINK_STUB, midY],\n [bx - LINK_STUB, midY], [bx - LINK_STUB, by], [bx, by]];\n}\n\n// --- AvoidsNodes routing ------------------------------------------------\n// Obstacle rects are [x,y,w,h] (already inflated by the caller). Fast\n// path: the plain elbow when it doesn't touch any box (only bend when\n// you must). Otherwise an orthogonal A* around the boxes \u2014 so a node\n// dropped on a link makes it re-route (\"push apart\") instead of passing\n// underneath.\nconst ROUTE_CELL = 14;\nconst A_STEP = 10;\nconst A_TURN = 40; // heavy turn cost \u2192 A* strongly prefers straight runs\n\ntype Rect = [number, number, number, number];\n// A drawn link segment for jump-over: h = horizontal (line y=c, x\u2208[a,b]),\n// else vertical (line x=c, y\u2208[a,b]).\ntype Seg = { h: boolean; c: number; a: number; b: number };\n\nfunction segHitsRect(x1: number, y1: number, x2: number, y2: number, r: Rect): boolean {\n const rx2 = r[0] + r[2];\n const ry2 = r[1] + r[3];\n if (y1 === y2) {\n if (y1 <= r[1] || y1 >= ry2) return false;\n return Math.min(x1, x2) < rx2 && Math.max(x1, x2) > r[0];\n }\n if (x1 === x2) {\n if (x1 <= r[0] || x1 >= rx2) return false;\n return Math.min(y1, y2) < ry2 && Math.max(y1, y2) > r[1];\n }\n return false;\n}\nfunction polyHitsRects(pts: number[][], rects: Rect[]): boolean {\n for (let i = 1; i < pts.length; i += 1)\n for (const r of rects)\n if (segHitsRect(pts[i - 1][0], pts[i - 1][1], pts[i][0], pts[i][1], r)) return true;\n return false;\n}\nfunction orthogonalize(ps: number[][]): number[][] {\n const o: number[][] = [ps[0]];\n for (let i = 1; i < ps.length; i += 1) {\n const pr = o[o.length - 1];\n const p = ps[i];\n if (pr[0] !== p[0] && pr[1] !== p[1]) o.push([p[0], pr[1]]);\n o.push(p);\n }\n return o;\n}\nfunction collapse(ps: number[][]): number[][] {\n const o: number[][] = [];\n for (const p of ps) {\n if (o.length > 0) {\n const last = o[o.length - 1];\n if (last[0] === p[0] && last[1] === p[1]) continue;\n }\n if (o.length >= 2) {\n const a = o[o.length - 2];\n const b = o[o.length - 1];\n if ((a[0] === b[0] && b[0] === p[0]) || (a[1] === b[1] && b[1] === p[1])) {\n o[o.length - 1] = p;\n continue;\n }\n }\n o.push(p);\n }\n return o;\n}\nfunction hitsAny(x1: number, y1: number, x2: number, y2: number, rects: Rect[]): boolean {\n for (const r of rects) if (segHitsRect(x1, y1, x2, y2, r)) return true;\n return false;\n}\n// Staircase \u2192 L: repeatedly try to replace two consecutive bends with a\n// single corner when the shortcut stays orthogonal and clear of boxes.\n// Cuts the A* zig-zag down to the minimum number of bends.\nfunction simplifyOrtho(pts: number[][], rects: Rect[]): number[][] {\n let p = pts.slice();\n let changed = true;\n let guard = 0;\n while (changed && guard < 40) {\n changed = false;\n guard += 1;\n // Keep the first/last two points (port \u2192 stub) untouched so the\n // entry/exit stays a clean horizontal run into the socket.\n for (let i = 2; i + 3 < p.length; i += 1) {\n const A = p[i - 1];\n const D = p[i + 2];\n for (const E of [[D[0], A[1]], [A[0], D[1]]] as number[][]) {\n if ((E[0] === A[0] && E[1] === A[1]) || (E[0] === D[0] && E[1] === D[1])) continue;\n if (hitsAny(A[0], A[1], E[0], E[1], rects)) continue;\n if (hitsAny(E[0], E[1], D[0], D[1], rects)) continue;\n p = p.slice(0, i).concat([E], p.slice(i + 2));\n changed = true;\n break;\n }\n if (changed) break;\n }\n }\n return p;\n}\nfunction aStarGrid(start: [number, number], goal: [number, number], rects: Rect[]): number[][] | null {\n let minX = Math.min(start[0], goal[0]);\n let minY = Math.min(start[1], goal[1]);\n let maxX = Math.max(start[0], goal[0]);\n let maxY = Math.max(start[1], goal[1]);\n for (const r of rects) {\n minX = Math.min(minX, r[0]); minY = Math.min(minY, r[1]);\n maxX = Math.max(maxX, r[0] + r[2]); maxY = Math.max(maxY, r[1] + r[3]);\n }\n const pad = LINK_STUB + ROUTE_CELL * 2;\n minX -= pad; minY -= pad; maxX += pad; maxY += pad;\n let cell = ROUTE_CELL;\n let cols = Math.ceil((maxX - minX) / cell);\n let rows = Math.ceil((maxY - minY) / cell);\n const CAP = 260;\n if (cols > CAP || rows > CAP) {\n cell = Math.max((maxX - minX) / CAP, (maxY - minY) / CAP);\n cols = Math.ceil((maxX - minX) / cell);\n rows = Math.ceil((maxY - minY) / cell);\n }\n const n = cols * rows;\n if (n <= 0 || n > 80000) return null;\n const cx = (c: number): number => minX + (c + 0.5) * cell;\n const cy = (r: number): number => minY + (r + 0.5) * cell;\n const blocked = new Uint8Array(n);\n for (const r of rects) {\n const c0 = Math.max(0, Math.floor((r[0] - minX) / cell));\n const c1 = Math.min(cols - 1, Math.floor((r[0] + r[2] - minX) / cell));\n const r0 = Math.max(0, Math.floor((r[1] - minY) / cell));\n const r1 = Math.min(rows - 1, Math.floor((r[1] + r[3] - minY) / cell));\n for (let rr = r0; rr <= r1; rr += 1)\n for (let cc = c0; cc <= c1; cc += 1) blocked[rr * cols + cc] = 1;\n }\n const sc = clamp(Math.floor((start[0] - minX) / cell), 0, cols - 1);\n const sr = clamp(Math.floor((start[1] - minY) / cell), 0, rows - 1);\n const gc = clamp(Math.floor((goal[0] - minX) / cell), 0, cols - 1);\n const gr = clamp(Math.floor((goal[1] - minY) / cell), 0, rows - 1);\n const si = sr * cols + sc;\n const gi = gr * cols + gc;\n blocked[si] = 0;\n blocked[gi] = 0;\n\n const g = new Float64Array(n).fill(Infinity);\n const prev = new Int32Array(n).fill(-1);\n const dir = new Int8Array(n).fill(-1); // 0=h,1=v incoming move\n g[si] = 0;\n // binary heap of indices keyed by f\n const heap: number[] = [si];\n const f = new Float64Array(n);\n f[si] = (Math.abs(gc - sc) + Math.abs(gr - sr)) * A_STEP;\n const swap = (i: number, j: number): void => { const t = heap[i]; heap[i] = heap[j]; heap[j] = t; };\n const push = (v: number): void => {\n heap.push(v);\n let i = heap.length - 1;\n while (i > 0) { const p = (i - 1) >> 1; if (f[heap[p]] <= f[heap[i]]) break; swap(i, p); i = p; }\n };\n const pop = (): number => {\n const top = heap[0];\n const last = heap.pop() as number;\n if (heap.length > 0) {\n heap[0] = last;\n let i = 0;\n for (;;) {\n const l = 2 * i + 1;\n const r = 2 * i + 2;\n let s = i;\n if (l < heap.length && f[heap[l]] < f[heap[s]]) s = l;\n if (r < heap.length && f[heap[r]] < f[heap[s]]) s = r;\n if (s === i) break;\n swap(i, s); i = s;\n }\n }\n return top;\n };\n const seen = new Uint8Array(n);\n while (heap.length > 0) {\n const cur = pop();\n if (cur === gi) break;\n if (seen[cur]) continue;\n seen[cur] = 1;\n const ccol = cur % cols;\n const crow = (cur - ccol) / cols;\n const steps: Array<[number, number, number]> = [\n [1, 0, 0], [-1, 0, 0], [0, 1, 1], [0, -1, 1],\n ];\n for (const [dc, dr, md] of steps) {\n const nc = ccol + dc;\n const nr = crow + dr;\n if (nc < 0 || nc >= cols || nr < 0 || nr >= rows) continue;\n const ni = nr * cols + nc;\n if (blocked[ni]) continue;\n const turn = dir[cur] !== -1 && dir[cur] !== md ? A_TURN : 0;\n const ng = g[cur] + A_STEP + turn;\n if (ng < g[ni]) {\n g[ni] = ng;\n prev[ni] = cur;\n dir[ni] = md as number;\n f[ni] = ng + (Math.abs(gc - nc) + Math.abs(gr - nr)) * A_STEP;\n push(ni);\n }\n }\n }\n if (prev[gi] === -1 && gi !== si) return null;\n const out: number[][] = [];\n let p = gi;\n while (p !== -1) { out.push([cx(p % cols), cy((p - (p % cols)) / cols)]); p = prev[p]; }\n out.reverse();\n return out;\n}\nfunction routeAvoid(a: [number, number], b: [number, number], rects: Rect[]): number[][] {\n const simple = route(a, b);\n if (rects.length === 0 || !polyHitsRects(simple, rects)) return simple;\n const A2: [number, number] = [a[0] + LINK_STUB, a[1]];\n const B2: [number, number] = [b[0] - LINK_STUB, b[1]];\n const grid = aStarGrid(A2, B2, rects);\n if (grid === null) return simple;\n // Keep the approach monotonic: clamp interior X into the corridor\n // between the two stubs so the path can't overshoot past the port\n // and double back (the \u2293 \"hook\" at the socket). The vertical\n // alignment then lands cleanly at the stub X, STUB away from the\n // port \u2014 a straight horizontal entry.\n const lo = Math.min(A2[0], B2[0]);\n const hi = Math.max(A2[0], B2[0]);\n const clipped = grid.map((p) => [clamp(p[0], lo, hi), p[1]] as number[]);\n const poly = collapse(orthogonalize([a, A2, ...clipped, B2, b]));\n return collapse(simplifyOrtho(poly, rects));\n}\nfunction ptSegDist(px: number, py: number, x1: number, y1: number, x2: number, y2: number): number {\n const dx = x2 - x1;\n const dy = y2 - y1;\n const len2 = dx * dx + dy * dy;\n let t = len2 === 0 ? 0 : ((px - x1) * dx + (py - y1) * dy) / len2;\n t = clamp(t, 0, 1);\n const cx = x1 + t * dx;\n const cy = y1 + t * dy;\n return Math.hypot(px - cx, py - cy);\n}\n\nexport const version = '0.1.0';\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { Diagram, type DiagramScreenshotOptions } from './canvas-renderer.js';\nimport { parseDiagramDocument } from './core/document.js';\n\n/**\n * Drawing a diagram where there is no browser -- a server producing a picture for a chat message, an\n * e-mail or a report. The renderer itself never needed one: it draws through a surface, and the SVG\n * surface builds a string. What needed a browser was the control around it, which creates a canvas and\n * listens for pointers; so the few things it reaches for are stood in for here, for the length of one\n * drawing, and taken away again.\n *\n * Text is measured by the SVG surface's own estimate rather than by a real font, so a label's box can sit\n * a pixel or two off where a browser would put it. The alternative is a native canvas dependency on every\n * machine that renders, which is a steep price for that.\n */\nexport interface HeadlessRenderOptions extends DiagramScreenshotOptions {\n /** Width of the frame the drawing is laid out in, in CSS pixels. Defaults to 1200. */\n hostWidth?: number;\n /** Height of that frame. Defaults to 800. */\n hostHeight?: number;\n}\n\n/** A 2D context that answers every call and remembers nothing: the drawing goes to the SVG surface. */\nfunction createContext(): CanvasRenderingContext2D {\n const own = {\n globalAlpha: 1,\n measureText: (text: string) => ({ width: text.length * 7 }),\n };\n\n return new Proxy(own, {\n get: (target, property) => property in target ? target[property as keyof typeof own] : () => undefined,\n set: (target, property, value) => {\n (target as Record<PropertyKey, unknown>)[property] = value;\n return true;\n },\n }) as unknown as CanvasRenderingContext2D;\n}\n\nclass StubElement {\n style: Record<string, string> = {};\n className = '';\n tabIndex = 0;\n width = 0;\n height = 0;\n textContent = '';\n readonly children: StubElement[] = [];\n readonly classList = { toggle: () => false, add: () => undefined, remove: () => undefined };\n\n private readonly context = createContext();\n\n appendChild<T extends StubElement>(child: T): T {\n this.children.push(child);\n return child;\n }\n\n removeChild(child: StubElement): StubElement {\n const at = this.children.indexOf(child);\n if (at >= 0) this.children.splice(at, 1);\n return child;\n }\n\n remove(): void { /* detached already */ }\n setAttribute(): void { /* nothing reads it here */ }\n focus(): void { /* no focus without a browser */ }\n addEventListener(): void { /* nothing to fire the events */ }\n removeEventListener(): void { /* see above */ }\n getContext(): CanvasRenderingContext2D { return this.context; }\n\n getBoundingClientRect(): DOMRect {\n return { left: 0, top: 0, right: this.width, bottom: this.height, width: this.width, height: this.height, x: 0, y: 0, toJSON: () => ({}) } as DOMRect;\n }\n\n get clientWidth(): number { return this.width; }\n get clientHeight(): number { return this.height; }\n}\n\nconst GLOBAL_KEYS = ['window', 'document', 'requestAnimationFrame', 'cancelAnimationFrame', 'Image', 'getComputedStyle', 'performance'] as const;\n\n/** Puts the stubs in place, and hands back the function that removes exactly what it added. */\nfunction installGlobals(): () => void {\n const target = globalThis as Record<string, unknown>;\n\n if (target.document !== undefined)\n return () => undefined;\n\n const before = new Map<string, unknown>();\n for (const key of GLOBAL_KEYS) before.set(key, target[key]);\n\n const stubDocument = Object.assign(new StubElement(), {\n documentElement: new StubElement(),\n createElement: () => new StubElement(),\n });\n\n Object.assign(target, {\n window: Object.assign(new StubElement(), { devicePixelRatio: 1 }),\n document: stubDocument,\n requestAnimationFrame: () => 1,\n cancelAnimationFrame: () => undefined,\n Image: class { },\n getComputedStyle: () => ({ getPropertyValue: () => '' }),\n // A host without a browser may have no clock either -- an embedded JS engine has none. The drawing\n // reads it for animation, and a still picture has no animation to advance.\n performance: (globalThis as { performance?: { now(): number } }).performance ?? { now: () => 0 },\n });\n\n return () => {\n for (const [key, value] of before) {\n if (value === undefined) delete target[key];\n else target[key] = value;\n }\n };\n}\n\n/**\n * Draws a saved diagram and returns the SVG for it. The source is the document as text or as an object;\n * the frame follows the content by default, since a picture made without a viewport has none to crop to.\n */\nexport function renderDiagramSvg(source: string | unknown, options: HeadlessRenderOptions = {}): string {\n const { hostWidth = 1200, hostHeight = 800, ...screenshot } = options;\n const restore = installGlobals();\n\n try {\n const host = new StubElement();\n host.width = hostWidth;\n host.height = hostHeight;\n\n const diagram = new Diagram({ host: host as unknown as HTMLElement });\n\n try {\n // Whatever shape it arrived in -- text off the wire, an object already in hand -- the library's\n // own reader decides what a document is.\n diagram.loadDocument(parseDiagramDocument(source));\n return diagram.takeSvg({ scope: 'content', ...screenshot });\n } finally {\n diagram.destroy();\n }\n } finally {\n restore();\n }\n}\n", "import type { DrawSurface } from './draw-surface.js';\n\n/**\n * A DrawSurface that writes SVG instead of pixels.\n *\n * The renderer is not aware of it: it issues the same calls it issues to a 2D context, and they are\n * recorded as elements rather than painted. That is the whole point -- one renderer, so the vector\n * output cannot drift from what the screen shows.\n *\n * Canvas semantics are followed rather than approximated, because the difference is visible:\n * - a transform is baked into each element as a matrix, so nesting never has to be reconstructed;\n * - arcTo is resolved the way canvas resolves it (tangent point, then a real arc), which is what\n * draws every rounded node corner;\n * - arc emits the leading straight segment canvas draws when a subpath is already open, and\n * splits a full circle in two, since a single SVG arc cannot close on itself;\n * - text metrics come from a real 2D context, so glyphs land where the on-screen layout put them.\n */\n\ntype Matrix = [number, number, number, number, number, number]; // a b c d e f\n\nconst IDENTITY: Matrix = [1, 0, 0, 1, 0, 0];\n\nfunction multiply(m: Matrix, n: Matrix): Matrix {\n return [\n m[0] * n[0] + m[2] * n[1],\n m[1] * n[0] + m[3] * n[1],\n m[0] * n[2] + m[2] * n[3],\n m[1] * n[2] + m[3] * n[3],\n m[0] * n[4] + m[2] * n[5] + m[4],\n m[1] * n[4] + m[3] * n[5] + m[5],\n ];\n}\n\nfunction isIdentity(m: Matrix): boolean {\n return m[0] === 1 && m[1] === 0 && m[2] === 0 && m[3] === 1 && m[4] === 0 && m[5] === 0;\n}\n\n/** Trims float noise: coordinates carry three decimals, which is finer than any renderer needs. */\nfunction n(value: number): string {\n if (!Number.isFinite(value)) return '0';\n return (Math.round(value * 1000) / 1000).toString();\n}\n\nfunction escapeXml(value: string): string {\n return value\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\"/g, '&quot;');\n}\n\ninterface SurfaceState {\n fillStyle: string;\n strokeStyle: string;\n lineWidth: number;\n lineJoin: CanvasLineJoin;\n lineCap: CanvasLineCap;\n globalAlpha: number;\n font: string;\n textAlign: CanvasTextAlign;\n textBaseline: CanvasTextBaseline;\n dash: readonly number[];\n matrix: Matrix;\n clipId: string | null;\n}\n\nconst ANCHOR: Record<string, string> = {\n left: 'start', start: 'start',\n center: 'middle',\n right: 'end', end: 'end',\n};\n\n// dominant-baseline rather than alignment-baseline: it is the one browsers and renderers agree on\n// for <text>, and these four are the values the renderer actually sets.\nconst BASELINE: Record<string, string> = {\n top: 'text-before-edge',\n hanging: 'hanging',\n middle: 'central',\n alphabetic: 'alphabetic',\n ideographic: 'ideographic',\n bottom: 'text-after-edge',\n};\n\nexport interface SvgSurfaceOptions {\n width: number;\n height: number;\n /** Painted as a full-size rect before anything else. Omit to leave the drawing transparent. */\n background?: string;\n /** Borrowed only for measureText; the SVG never draws on it. */\n metrics?: CanvasRenderingContext2D;\n}\n\nexport class SvgSurface implements DrawSurface {\n private readonly width: number;\n private readonly height: number;\n private readonly background: string | undefined;\n private readonly metrics: CanvasRenderingContext2D | null;\n\n private readonly body: string[] = [];\n private readonly defs: string[] = [];\n private readonly stack: SurfaceState[] = [];\n\n private state: SurfaceState = {\n fillStyle: '#000000',\n strokeStyle: '#000000',\n lineWidth: 1,\n lineJoin: 'miter',\n lineCap: 'butt',\n globalAlpha: 1,\n font: '10px sans-serif',\n textAlign: 'start',\n textBaseline: 'alphabetic',\n dash: [],\n matrix: IDENTITY,\n clipId: null,\n };\n\n /** Path being built by moveTo/lineTo/arc/arcTo, in the units the caller passes. */\n private path: string[] = [];\n private cursor: [number, number] | null = null;\n private subpathStart: [number, number] | null = null;\n private clipSeq = 0;\n\n constructor(options: SvgSurfaceOptions) {\n this.width = options.width;\n this.height = options.height;\n this.background = options.background;\n this.metrics = options.metrics ?? null;\n }\n\n // ===== state =========================================================\n\n get fillStyle(): string | CanvasGradient | CanvasPattern { return this.state.fillStyle; }\n set fillStyle(value: string | CanvasGradient | CanvasPattern) {\n // Gradients and patterns are canvas objects with no serialisable form here. The renderer\n // uses plain colours; anything else is left as the previous colour rather than guessed at.\n if (typeof value === 'string') this.state.fillStyle = value;\n }\n\n get strokeStyle(): string | CanvasGradient | CanvasPattern { return this.state.strokeStyle; }\n set strokeStyle(value: string | CanvasGradient | CanvasPattern) {\n if (typeof value === 'string') this.state.strokeStyle = value;\n }\n\n get lineWidth(): number { return this.state.lineWidth; }\n set lineWidth(value: number) { this.state.lineWidth = value; }\n\n get lineJoin(): CanvasLineJoin { return this.state.lineJoin; }\n set lineJoin(value: CanvasLineJoin) { this.state.lineJoin = value; }\n\n get lineCap(): CanvasLineCap { return this.state.lineCap; }\n set lineCap(value: CanvasLineCap) { this.state.lineCap = value; }\n\n get globalAlpha(): number { return this.state.globalAlpha; }\n set globalAlpha(value: number) { this.state.globalAlpha = value; }\n\n get font(): string { return this.state.font; }\n set font(value: string) {\n this.state.font = value;\n if (this.metrics !== null) this.metrics.font = value;\n }\n\n get textAlign(): CanvasTextAlign { return this.state.textAlign; }\n set textAlign(value: CanvasTextAlign) { this.state.textAlign = value; }\n\n get textBaseline(): CanvasTextBaseline { return this.state.textBaseline; }\n set textBaseline(value: CanvasTextBaseline) { this.state.textBaseline = value; }\n\n save(): void {\n this.stack.push({ ...this.state, dash: [...this.state.dash], matrix: [...this.state.matrix] as Matrix });\n }\n\n restore(): void {\n const previous = this.stack.pop();\n if (previous !== undefined) this.state = previous;\n }\n\n setLineDash(segments: readonly number[]): void {\n this.state.dash = [...segments];\n }\n\n // ===== transform =====================================================\n\n setTransform(a: number, b: number, c: number, d: number, e: number, f: number): void {\n this.state.matrix = [a, b, c, d, e, f];\n }\n\n translate(x: number, y: number): void {\n this.state.matrix = multiply(this.state.matrix, [1, 0, 0, 1, x, y]);\n }\n\n rotate(angle: number): void {\n const cos = Math.cos(angle);\n const sin = Math.sin(angle);\n this.state.matrix = multiply(this.state.matrix, [cos, sin, -sin, cos, 0, 0]);\n }\n\n // ===== paths =========================================================\n\n beginPath(): void {\n this.path = [];\n this.cursor = null;\n this.subpathStart = null;\n }\n\n closePath(): void {\n if (this.cursor === null) return;\n this.path.push('Z');\n if (this.subpathStart !== null) this.cursor = [...this.subpathStart] as [number, number];\n }\n\n moveTo(x: number, y: number): void {\n this.path.push(`M${n(x)} ${n(y)}`);\n this.cursor = [x, y];\n this.subpathStart = [x, y];\n }\n\n lineTo(x: number, y: number): void {\n if (this.cursor === null) { this.moveTo(x, y); return; }\n this.path.push(`L${n(x)} ${n(y)}`);\n this.cursor = [x, y];\n }\n\n arc(cx: number, cy: number, r: number, start: number, end: number, ccw = false): void {\n const sx = cx + r * Math.cos(start);\n const sy = cy + r * Math.sin(start);\n\n // Canvas joins an open subpath to the arc's first point with a straight line.\n if (this.cursor === null) this.moveTo(sx, sy);\n else this.lineTo(sx, sy);\n\n let delta = end - start;\n\n if (ccw) {\n while (delta > 0) delta -= Math.PI * 2;\n if (delta <= -Math.PI * 2) delta = -Math.PI * 2;\n } else {\n while (delta < 0) delta += Math.PI * 2;\n if (delta >= Math.PI * 2) delta = Math.PI * 2;\n }\n\n const sweep = ccw ? 0 : 1;\n\n // A single SVG arc cannot end where it began, so a full turn is drawn as two halves.\n if (Math.abs(delta) >= Math.PI * 2 - 1e-9) {\n const mid = start + delta / 2;\n const mx = cx + r * Math.cos(mid);\n const my = cy + r * Math.sin(mid);\n this.path.push(`A${n(r)} ${n(r)} 0 0 ${sweep} ${n(mx)} ${n(my)}`);\n this.path.push(`A${n(r)} ${n(r)} 0 0 ${sweep} ${n(sx)} ${n(sy)}`);\n this.cursor = [sx, sy];\n return;\n }\n\n const ex = cx + r * Math.cos(start + delta);\n const ey = cy + r * Math.sin(start + delta);\n const large = Math.abs(delta) > Math.PI ? 1 : 0;\n\n this.path.push(`A${n(r)} ${n(r)} 0 ${large} ${sweep} ${n(ex)} ${n(ey)}`);\n this.cursor = [ex, ey];\n }\n\n arcTo(x1: number, y1: number, x2: number, y2: number, r: number): void {\n if (this.cursor === null) { this.moveTo(x1, y1); return; }\n\n const [x0, y0] = this.cursor;\n\n // Canvas degenerates to a straight line when there is no corner to round.\n const a = [x0 - x1, y0 - y1];\n const b = [x2 - x1, y2 - y1];\n const la = Math.hypot(a[0], a[1]);\n const lb = Math.hypot(b[0], b[1]);\n\n if (la === 0 || lb === 0 || r === 0) { this.lineTo(x1, y1); return; }\n\n const ua = [a[0] / la, a[1] / la];\n const ub = [b[0] / lb, b[1] / lb];\n const cross = ua[0] * ub[1] - ua[1] * ub[0];\n\n if (Math.abs(cross) < 1e-9) { this.lineTo(x1, y1); return; } // collinear\n\n const angle = Math.acos(Math.max(-1, Math.min(1, ua[0] * ub[0] + ua[1] * ub[1])));\n const tangent = r / Math.tan(angle / 2);\n\n // The corner cannot swallow more than the shorter arm.\n const t = Math.min(tangent, la, lb);\n const radius = t * Math.tan(angle / 2);\n\n const t1 = [x1 + ua[0] * t, y1 + ua[1] * t];\n const t2 = [x1 + ub[0] * t, y1 + ub[1] * t];\n\n this.lineTo(t1[0], t1[1]);\n\n // Turning left in screen coordinates (y down) is a counter-clockwise sweep.\n const sweep = cross < 0 ? 1 : 0;\n this.path.push(`A${n(radius)} ${n(radius)} 0 0 ${sweep} ${n(t2[0])} ${n(t2[1])}`);\n this.cursor = [t2[0], t2[1]];\n }\n\n fill(): void {\n if (this.path.length === 0) return;\n this.emit(`<path d=\"${this.path.join(' ')}\" ${this.fillAttrs()}/>`);\n }\n\n stroke(): void {\n if (this.path.length === 0) return;\n this.emit(`<path d=\"${this.path.join(' ')}\" fill=\"none\" ${this.strokeAttrs()}/>`);\n }\n\n clip(): void {\n if (this.path.length === 0) return;\n\n const id = `clip${++this.clipSeq}`;\n this.defs.push(`<clipPath id=\"${id}\"><path d=\"${this.path.join(' ')}\"/></clipPath>`);\n this.state.clipId = id;\n }\n\n // ===== rectangles ====================================================\n\n clearRect(x: number, y: number, w: number, h: number): void {\n // Nothing to clear in a document that is built up rather than painted over: SVG has no\n // eraser, and the first thing written is the background anyway.\n void x; void y; void w; void h;\n }\n\n fillRect(x: number, y: number, w: number, h: number): void {\n this.emit(`<rect x=\"${n(x)}\" y=\"${n(y)}\" width=\"${n(w)}\" height=\"${n(h)}\" ${this.fillAttrs()}/>`);\n }\n\n strokeRect(x: number, y: number, w: number, h: number): void {\n this.emit(`<rect x=\"${n(x)}\" y=\"${n(y)}\" width=\"${n(w)}\" height=\"${n(h)}\" fill=\"none\" ${this.strokeAttrs()}/>`);\n }\n\n // ===== text ==========================================================\n\n fillText(text: string, x: number, y: number, maxWidth?: number): void {\n if (text === '') return;\n\n const anchor = ANCHOR[this.state.textAlign] ?? 'start';\n const baseline = BASELINE[this.state.textBaseline] ?? 'alphabetic';\n\n // Canvas squeezes the glyphs to fit maxWidth; SVG needs to be told, and only when the text\n // would actually overflow -- textLength on text that already fits would stretch it.\n // Dropping the argument left node titles and zone captions running past the box the\n // renderer had sized for them, so the vector export disagreed with the raster one.\n let constraint = '';\n if (maxWidth !== undefined && maxWidth > 0 && this.measureText(text).width > maxWidth) {\n constraint = ` textLength=\"${n(maxWidth)}\" lengthAdjust=\"spacingAndGlyphs\"`;\n }\n\n // The canvas font string is CSS font shorthand, so it transfers verbatim -- no parsing, and\n // no chance of losing the weight or the fallback list on the way.\n this.emit(\n `<text x=\"${n(x)}\" y=\"${n(y)}\" style=\"font:${escapeXml(this.state.font)}\" ` +\n `text-anchor=\"${anchor}\" dominant-baseline=\"${baseline}\"${constraint} ${this.fillAttrs()}>` +\n `${escapeXml(text)}</text>`);\n }\n\n measureText(text: string): { width: number } {\n if (this.metrics !== null) return { width: this.metrics.measureText(text).width };\n\n // Without a context to ask, a rough advance keeps layout sane rather than collapsing to\n // zero and stacking every label at one point.\n const size = parseFloat(this.state.font) || 10;\n return { width: text.length * size * 0.55 };\n }\n\n // ===== images ========================================================\n\n drawImage(image: CanvasImageSource, dx: number, dy: number, dw: number, dh: number): void {\n const href = this.imageHref(image);\n if (href === null) return;\n\n this.emit(`<image x=\"${n(dx)}\" y=\"${n(dy)}\" width=\"${n(dw)}\" height=\"${n(dh)}\" href=\"${escapeXml(href)}\"${this.commonAttrs()}/>`);\n }\n\n private imageHref(image: CanvasImageSource): string | null {\n try {\n if (typeof HTMLCanvasElement !== 'undefined' && image instanceof HTMLCanvasElement) return image.toDataURL();\n if (typeof HTMLImageElement !== 'undefined' && image instanceof HTMLImageElement) return image.src;\n } catch {\n // A canvas tainted by a cross-origin draw refuses toDataURL. Dropping the image beats\n // failing the whole export for one picture.\n return null;\n }\n return null;\n }\n\n // ===== output ========================================================\n\n /** The finished document. Safe to call more than once; it does not consume the recording. */\n toSvg(): string {\n const background = this.background === undefined\n ? ''\n : `<rect width=\"100%\" height=\"100%\" fill=\"${escapeXml(this.background)}\"/>`;\n\n const defs = this.defs.length === 0 ? '' : `<defs>${this.defs.join('')}</defs>`;\n\n return `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"${n(this.width)}\" height=\"${n(this.height)}\" ` +\n `viewBox=\"0 0 ${n(this.width)} ${n(this.height)}\">` +\n `${defs}${background}${this.body.join('')}</svg>`;\n }\n\n // ===== internals =====================================================\n\n private emit(element: string): void {\n this.body.push(element);\n }\n\n private commonAttrs(): string {\n const parts: string[] = [];\n\n if (!isIdentity(this.state.matrix)) {\n parts.push(` transform=\"matrix(${this.state.matrix.map(n).join(' ')})\"`);\n }\n\n if (this.state.globalAlpha !== 1) parts.push(` opacity=\"${n(this.state.globalAlpha)}\"`);\n if (this.state.clipId !== null) parts.push(` clip-path=\"url(#${this.state.clipId})\"`);\n\n return parts.join('');\n }\n\n private fillAttrs(): string {\n return `fill=\"${escapeXml(this.state.fillStyle)}\"${this.commonAttrs()}`;\n }\n\n private strokeAttrs(): string {\n const parts = [\n `stroke=\"${escapeXml(this.state.strokeStyle)}\"`,\n `stroke-width=\"${n(this.state.lineWidth)}\"`,\n ];\n\n if (this.state.lineJoin !== 'miter') parts.push(`stroke-linejoin=\"${this.state.lineJoin}\"`);\n if (this.state.lineCap !== 'butt') parts.push(`stroke-linecap=\"${this.state.lineCap}\"`);\n if (this.state.dash.length > 0) parts.push(`stroke-dasharray=\"${this.state.dash.map(n).join(' ')}\"`);\n\n return parts.join(' ') + this.commonAttrs();\n }\n}\n", "// Colour arithmetic shared by the parts that have to stay readable against a\n// fill they do not choose: the embed host reading a page's background, and the\n// renderer drawing a title on a node whose colour comes from the scheme.\n\nconst CSS_COLOR_KEYWORDS: Readonly<Record<string, [number, number, number]>> = {\n\twhite: [255, 255, 255],\n\tblack: [0, 0, 0],\n\ttransparent: [255, 255, 255],\n};\n\n/**\n * Channels of a CSS colour, or null when it cannot be read.\n *\n * Understands the keywords above, three-, six- and eight-digit hex (the alpha is\n * ignored), and rgb()/rgba() in both the comma and the space syntax.\n */\nfunction parseRgb(color: string): [number, number, number] | null {\n\tconst value = color.trim().toLowerCase();\n\tif (value === '')\n\t\treturn null;\n\n\tconst keyword = CSS_COLOR_KEYWORDS[value];\n\tif (keyword !== undefined)\n\t\treturn [...keyword];\n\n\tconst long = value.match(/^#?([0-9a-f]{6})$/);\n\tif (long !== null) {\n\t\tconst n = parseInt(long[1], 16);\n\t\treturn [(n >> 16) & 255, (n >> 8) & 255, n & 255];\n\t}\n\n\t// #abc is shorthand for #aabbcc, and the eight-digit forms carry an alpha we ignore.\n\tconst short = value.match(/^#?([0-9a-f]{3})([0-9a-f])?$/);\n\tif (short !== null) {\n\t\tconst [r, g, b] = [...short[1]].map((digit) => parseInt(digit + digit, 16));\n\t\treturn [r, g, b];\n\t}\n\n\tconst long8 = value.match(/^#?([0-9a-f]{6})[0-9a-f]{2}$/);\n\tif (long8 !== null) {\n\t\tconst n = parseInt(long8[1], 16);\n\t\treturn [(n >> 16) & 255, (n >> 8) & 255, n & 255];\n\t}\n\n\tconst rgb = value.match(/^rgba?\\(([^)]+)\\)$/);\n\tif (rgb !== null) {\n\t\tconst parts = rgb[1].split(/[\\s,/]+/).filter((part) => part !== '');\n\t\tif (parts.length >= 3) {\n\t\t\tconst [r, g, b] = parts.slice(0, 3).map((part) => part.endsWith('%')\n\t\t\t\t? (parseFloat(part) / 100) * 255\n\t\t\t\t: parseFloat(part));\n\t\t\tif ([r, g, b].every((channel) => Number.isFinite(channel)))\n\t\t\t\treturn [r, g, b];\n\t\t}\n\t}\n\n\treturn null;\n}\n\n/**\n * Perceived brightness of a CSS colour, or -1 when it cannot be read.\n *\n * Six-digit hex was the only form understood, and everything else answered 0 -- black. A page\n * writing --diagram-bg as #fff, white or rgb(255 255 255) therefore had its white canvas\n * classified as dark and got the dark link palette: near-white wires on a near-white background.\n * Unreadable is now -1 rather than 0, so the caller can keep its own default instead of being\n * told the page is black.\n */\nexport function luminance(color: string): number {\n\tconst rgb = parseRgb(color);\n\tif (rgb === null)\n\t\treturn -1;\n\n\tconst [r, g, b] = rgb;\n\treturn 0.299 * r + 0.587 * g + 0.114 * b;\n}\n\nconst DARK_TEXT = '#1b1b1b';\nconst LIGHT_TEXT = '#f5f5f5';\n\n/// One channel on the scale contrast is measured on, where equal steps look\n/// equally different rather than merely being equal numbers.\nfunction toLinear(channel: number): number {\n\tconst v = channel / 255;\n\treturn v <= 0.03928 ? v / 12.92 : Math.pow((v + 0.055) / 1.055, 2.4);\n}\n\n/// Relative luminance as WCAG defines it, or -1 for a colour that cannot be read.\nfunction relativeLuminance(color: string): number {\n\tconst rgb = parseRgb(color);\n\tif (rgb === null)\n\t\treturn -1;\n\n\tconst [r, g, b] = rgb;\n\treturn 0.2126 * toLinear(r) + 0.7152 * toLinear(g) + 0.0722 * toLinear(b);\n}\n\n/// WCAG contrast ratio between two relative luminances: 1 for identical, 21 for\n/// black against white.\nfunction contrast(a: number, b: number): number {\n\tconst [lighter, darker] = a > b ? [a, b] : [b, a];\n\treturn (lighter + 0.05) / (darker + 0.05);\n}\n\n/// Title colour for a body filled with `fill`.\n///\n/// A node's fill comes from the scheme rather than the theme, so it can be any\n/// colour, and a title fixed to one shade disappears as soon as a node is filled\n/// close to it. Rather than split the range at a brightness someone has to pick,\n/// this measures both candidates against the fill and takes whichever stands out\n/// more. That is also why a saturated orange keeps its dark title where a plain\n/// brightness test, which reads such a colour as darker than it looks, flips it.\n///\n/// A fill this cannot read keeps the dark title: every node shipped so far is\n/// light, so guessing light text would fail on more of them than it fixes.\nexport function readableTextOn(fill: string): string {\n\tconst background = relativeLuminance(fill);\n\tif (background < 0)\n\t\treturn DARK_TEXT;\n\n\treturn contrast(background, relativeLuminance(LIGHT_TEXT))\n\t\t> contrast(background, relativeLuminance(DARK_TEXT))\n\t\t? LIGHT_TEXT\n\t\t: DARK_TEXT;\n}\n\n// Opaque on purpose: a translucent edge takes part of its colour from the fill underneath, so\n// two sockets side by side end up with visibly different edges and the one rule looks like two.\nconst DARK_OUTLINE = '#3a3d45';\nconst LIGHT_OUTLINE = '#c8ccd4';\n\n/// Outline colour for a shape drawn on `surface`.\n///\n/// A socket is filled with its type's colour, which comes from the host and spans the whole\n/// range -- StockSharp sends #000000 for Any. What the outline has to separate the socket\n/// from is the canvas, so it is measured against the canvas: one outline for every socket on\n/// it, and none of them left without an edge. Choosing per fill instead would edge two\n/// neighbouring sockets differently, which reads as a mistake rather than as a rule.\n///\n/// A surface this cannot read keeps the dark outline, for the same reason the title stays\n/// dark: the canvas shipped so far is dark, and a light outline on a light one would vanish.\nexport function readableOutlineOn(surface: string): string {\n\tconst background = relativeLuminance(surface);\n\tif (background < 0)\n\t\treturn DARK_OUTLINE;\n\n\treturn contrast(background, relativeLuminance(LIGHT_OUTLINE))\n\t\t> contrast(background, relativeLuminance(DARK_OUTLINE))\n\t\t? LIGHT_OUTLINE\n\t\t: DARK_OUTLINE;\n}\n", "/**\n * Stores a key that JSON can legitimately carry but plain assignment cannot hold.\n *\n * `JSON.parse` produces `__proto__` as an ordinary own key, yet writing it back\n * with `target[key] = value` hits the inherited `__proto__` setter: the value is\n * dropped and the object's prototype is replaced instead. A document parsed that\n * way loses data and stops satisfying the parser's own \"plain object\" guard, so\n * anything the parser accepted could no longer be serialized or cloned.\n */\nexport function setJsonKey<T>(target: Record<string, T>, key: string, value: T): void {\n if (key === '__proto__') {\n Object.defineProperty(target, key, { value, enumerable: true, writable: true, configurable: true });\n return;\n }\n target[key] = value;\n}\n\n/**\n * The read that matches setJsonKey.\n *\n * `target[key]` for `__proto__` answers with the inherited prototype rather than the entry, so a\n * plain lookup reports a value for a key that was never stored -- and callers that fall back on\n * `?? create()` never do, then use `Object.prototype` as if it were their own record.\n */\nexport function getJsonKey<T>(target: Record<string, T>, key: string): T | undefined {\n return Object.prototype.hasOwnProperty.call(target, key) ? target[key] : undefined;\n}\n", "export type JsonPrimitive = string | number | boolean | null;\nexport type JsonValue = JsonPrimitive | JsonObject | JsonValue[];\n\nexport interface JsonObject {\n [key: string]: JsonValue;\n}\n\nexport interface DiagramParameterSchema {\n name: string;\n displayName: string;\n description: string;\n type: string;\n defaultValue: string;\n options: string[];\n min: number | null;\n max: number | null;\n displayOrder: number;\n category: string;\n isBasic: boolean;\n editorType: string;\n}\n\n/**\n * How a dynamic port grows. Only 'onConnect' makes the editor add a typed\n * sibling when a link lands on the port; '' and 'manual' leave it to the host.\n * The renderer compares this with ===, so a value outside the set silently\n * selects the do-nothing branch -- hence a union rather than a string.\n */\nexport type PortDynamicMode = '' | 'manual' | 'onConnect';\n\n/** Narrows an untyped value to the closed set, defaulting to the inert mode. */\nexport function toPortDynamicMode(value: unknown): PortDynamicMode {\n return value === 'manual' || value === 'onConnect' ? value : '';\n}\n\nexport interface DiagramDocumentPort {\n id: string;\n name: string;\n description: string;\n type: string;\n maxLinks: number;\n availableTypes: string[];\n isDynamic: boolean;\n dynamicMode: PortDynamicMode;\n isSibling: boolean;\n metadata: JsonObject;\n}\n\nexport interface DiagramDocumentNode {\n id: string;\n typeId: string;\n name: string;\n description: string;\n groupName: string;\n x: number;\n y: number;\n color: string;\n border: string;\n icon: string;\n /** Persistent host text. Runtime and load errors belong to DiagramRuntimeState. */\n message: string;\n openAction: string;\n inPorts: DiagramDocumentPort[];\n outPorts: DiagramDocumentPort[];\n parameters: DiagramParameterSchema[];\n paramValues: Record<string, string>;\n metadata: JsonObject;\n}\n\nexport interface DiagramDocumentEndpoint {\n nodeId: string;\n portId: string;\n}\n\n/**\n * How a link is drawn. A dashed link reads as one that may or may not be there -\n * an optional hop, a path taken only in some deployments - which a solid line\n * cannot say. The renderer compares this with ===, so a value outside the set\n * would silently fall through to solid; hence a union rather than a string.\n */\nexport type DiagramLinkStyle = 'solid' | 'dashed';\n\n/** Narrows an untyped value to the closed set, defaulting to a plain line. */\nexport function toDiagramLinkStyle(value: unknown): DiagramLinkStyle {\n return value === 'dashed' ? 'dashed' : 'solid';\n}\n\nexport interface DiagramDocumentLink {\n /** Stable identity used by selection, relinking and history. */\n id: string;\n from: DiagramDocumentEndpoint;\n to: DiagramDocumentEndpoint;\n style: DiagramLinkStyle;\n metadata: JsonObject;\n}\n\n/**\n * A labelled rectangle drawn behind the nodes. It says where things are rather\n * than what they do - a colocation cage, a tenant boundary, a process - which no\n * arrangement of nodes and links can state on its own. A zone owns nothing: the\n * nodes that sit on it are not its children, so moving one changes no membership.\n */\nexport interface DiagramDocumentZone {\n id: string;\n name: string;\n x: number;\n y: number;\n width: number;\n height: number;\n /** Empty means the renderer picks its own neutral tint. */\n color: string;\n metadata: JsonObject;\n}\n\nexport const DIAGRAM_DOCUMENT_VERSION = 1 as const;\nexport type DiagramDocumentVersion = typeof DIAGRAM_DOCUMENT_VERSION;\n\nexport interface DiagramDocument {\n version: DiagramDocumentVersion;\n nodes: DiagramDocumentNode[];\n links: DiagramDocumentLink[];\n zones: DiagramDocumentZone[];\n metadata: JsonObject;\n}\n\nexport type DiagramDocumentPortInput = Pick<DiagramDocumentPort, 'id' | 'name'>\n & Partial<Omit<DiagramDocumentPort, 'id' | 'name'>>;\n\nexport type DiagramDocumentNodeInput = Pick<DiagramDocumentNode, 'id' | 'name'>\n & Partial<Omit<DiagramDocumentNode, 'id' | 'name' | 'inPorts' | 'outPorts'>>\n & {\n inPorts?: readonly DiagramDocumentPortInput[];\n outPorts?: readonly DiagramDocumentPortInput[];\n };\n\nexport type DiagramDocumentLinkInput = Omit<DiagramDocumentLink, 'id' | 'style' | 'metadata'> & {\n id?: string;\n style?: DiagramLinkStyle;\n metadata?: JsonObject;\n};\n\nexport type DiagramDocumentZoneInput = Omit<DiagramDocumentZone, 'color' | 'metadata'> & {\n color?: string;\n metadata?: JsonObject;\n};\n\nexport interface DiagramDocumentInput {\n nodes?: readonly DiagramDocumentNodeInput[];\n links?: readonly DiagramDocumentLinkInput[];\n zones?: readonly DiagramDocumentZoneInput[];\n metadata?: JsonObject;\n}\n", "import { setJsonKey } from './json.js';\nimport { toPortDynamicMode } from './model.js';\nimport {\n DIAGRAM_DOCUMENT_VERSION,\n type DiagramDocument,\n type DiagramDocumentEndpoint,\n type DiagramDocumentInput,\n type DiagramDocumentLink,\n type DiagramLinkStyle,\n type DiagramDocumentNode,\n type DiagramDocumentPort,\n type DiagramDocumentZone,\n type DiagramParameterSchema,\n type PortDynamicMode,\n type JsonObject,\n type JsonValue,\n} from './model.js';\n\nexport { DIAGRAM_DOCUMENT_VERSION } from './model.js';\nexport type {\n DiagramDocument,\n DiagramDocumentEndpoint,\n DiagramDocumentInput,\n DiagramDocumentLink,\n DiagramDocumentLinkInput,\n DiagramLinkStyle,\n DiagramDocumentNode,\n DiagramDocumentNodeInput,\n DiagramDocumentPort,\n DiagramDocumentPortInput,\n DiagramDocumentZone,\n DiagramDocumentZoneInput,\n DiagramDocumentVersion,\n DiagramParameterSchema,\n JsonObject,\n JsonPrimitive,\n JsonValue,\n} from './model.js';\n\nexport class DiagramDocumentError extends Error {\n constructor(message: string, readonly path: string = '$') {\n super(`${path}: ${message}`);\n this.name = 'DiagramDocumentError';\n }\n}\n\nexport function createDiagramDocument(input: DiagramDocumentInput = {}): DiagramDocument {\n // DiagramDocumentInput is a structural interface, so its shape is a claim by\n // the caller, not a guarantee. Elements are checked the same way parsed ones\n // are, otherwise a malformed one surfaces as a TypeError naming no path.\n const rawNodes = mapElements(input.nodes, '$.nodes');\n const rawLinks = mapElements(input.links, '$.links');\n const nodes = rawNodes.map((node, index) => normalizeNode(node, `$.nodes[${index}]`));\n const usedLinkIds = new Set<string>();\n\n for (let index = 0; index < rawLinks.length; index++) {\n const raw = rawLinks[index].id;\n if (raw === undefined) continue;\n const id = requireIdentifier(raw, `$.links[${index}].id`);\n if (usedLinkIds.has(id)) {\n throw new DiagramDocumentError(`duplicate link id \"${id}\"`, `$.links[${index}].id`);\n }\n usedLinkIds.add(id);\n }\n\n let sequence = 1;\n const links = rawLinks.map((link, index) => {\n let id = link.id;\n if (id === undefined) {\n let generated: string;\n do generated = `link_${sequence++}`;\n while (usedLinkIds.has(generated));\n usedLinkIds.add(generated);\n id = generated;\n }\n return normalizeLink({ ...link, id }, `$.links[${index}]`);\n });\n const rawZones = mapElements(input.zones, '$.zones');\n const zones = rawZones.map((zone, index) => normalizeZone(zone, `$.zones[${index}]`));\n validateUniqueZones(zones);\n\n const document: DiagramDocument = {\n version: DIAGRAM_DOCUMENT_VERSION,\n nodes,\n links,\n zones,\n metadata: cloneJsonObject(input.metadata ?? {}, '$.metadata'),\n };\n validateDocument(document);\n return document;\n}\n\nexport function cloneDiagramDocument(document: DiagramDocument): DiagramDocument {\n return parseDiagramDocument(document);\n}\n\nexport function serializeDiagramDocument(document: DiagramDocument, space?: number): string {\n return JSON.stringify(parseDiagramDocument(document), null, space);\n}\n\nexport function parseDiagramDocument(source: string | unknown): DiagramDocument {\n let value: unknown = source;\n if (typeof source === 'string') {\n try {\n value = JSON.parse(source) as unknown;\n } catch (error) {\n const reason = error instanceof Error ? error.message : 'invalid JSON';\n throw new DiagramDocumentError(reason);\n }\n }\n\n const root = requireStructure(value, '$');\n const version = requireNumber(root.version, '$.version');\n if (version !== DIAGRAM_DOCUMENT_VERSION) {\n throw new DiagramDocumentError(`unsupported document version ${version}`, '$.version');\n }\n const document: DiagramDocument = {\n version: DIAGRAM_DOCUMENT_VERSION,\n nodes: requireArray(root.nodes, '$.nodes').map((node, index) => parseNode(node, `$.nodes[${index}]`)),\n links: requireArray(root.links, '$.links').map((link, index) => parseLink(link, `$.links[${index}]`)),\n // Zones arrived after the first documents were written, so their absence is not a fault:\n // an older file simply has none, and reading it must not need a migration step.\n zones: root.zones === undefined || root.zones === null\n ? []\n : requireArray(root.zones, '$.zones').map((zone, index) => normalizeZone(zone, `$.zones[${index}]`)),\n metadata: cloneJsonObject(root.metadata, '$.metadata'),\n };\n validateDocument(document);\n return document;\n}\n\nfunction normalizeNode(value: unknown, path: string): DiagramDocumentNode {\n const input = requireStructure(value, path);\n const id = requireIdentifier(input.id, `${path}.id`);\n return {\n id,\n typeId: requireIdentifier(input.typeId ?? id, `${path}.typeId`),\n name: requireString(input.name, `${path}.name`),\n description: requireString(input.description ?? '', `${path}.description`),\n groupName: requireString(input.groupName ?? 'Common', `${path}.groupName`),\n x: requireFiniteNumber(input.x ?? 0, `${path}.x`),\n y: requireFiniteNumber(input.y ?? 0, `${path}.y`),\n color: requireString(input.color ?? '#d7d7d7', `${path}.color`),\n border: requireString(input.border ?? '#8c8c8c', `${path}.border`),\n icon: requireString(input.icon ?? '', `${path}.icon`),\n message: requireString(input.message ?? '', `${path}.message`),\n openAction: requireString(input.openAction ?? '', `${path}.openAction`),\n inPorts: mapElements(input.inPorts, `${path}.inPorts`)\n .map((port, index) => normalizePort(port, `${path}.inPorts[${index}]`)),\n outPorts: mapElements(input.outPorts, `${path}.outPorts`)\n .map((port, index) => normalizePort(port, `${path}.outPorts[${index}]`)),\n parameters: mapElements(input.parameters, `${path}.parameters`)\n .map((parameter, index) => normalizeParameter(parameter, `${path}.parameters[${index}]`)),\n paramValues: cloneStringRecord(input.paramValues ?? {}, `${path}.paramValues`),\n metadata: cloneJsonObject(input.metadata ?? {}, `${path}.metadata`),\n };\n}\n\nfunction normalizePort(value: unknown, path: string): DiagramDocumentPort {\n const input = requireStructure(value, path);\n return {\n id: requireIdentifier(input.id, `${path}.id`),\n name: requireString(input.name, `${path}.name`),\n description: requireString(input.description ?? '', `${path}.description`),\n type: requireString(input.type ?? '', `${path}.type`),\n maxLinks: requireNonNegativeInteger(input.maxLinks ?? 0, `${path}.maxLinks`),\n availableTypes: requireArray(input.availableTypes ?? [], `${path}.availableTypes`)\n .map((type, index) => requireString(type, `${path}.availableTypes[${index}]`)),\n isDynamic: requireBoolean(input.isDynamic ?? false, `${path}.isDynamic`),\n dynamicMode: requirePortDynamicMode(input.dynamicMode ?? '', `${path}.dynamicMode`),\n isSibling: requireBoolean(input.isSibling ?? false, `${path}.isSibling`),\n metadata: cloneJsonObject(input.metadata ?? {}, `${path}.metadata`),\n };\n}\n\nfunction normalizeParameter(value: unknown, path: string): DiagramParameterSchema {\n const input = requireStructure(value, path);\n return {\n name: requireIdentifier(input.name, `${path}.name`),\n displayName: requireString(input.displayName, `${path}.displayName`),\n description: requireString(input.description, `${path}.description`),\n type: requireString(input.type, `${path}.type`),\n defaultValue: requireString(input.defaultValue, `${path}.defaultValue`),\n options: requireArray(input.options, `${path}.options`).map((option, index) => requireString(option, `${path}.options[${index}]`)),\n min: requireNullableFiniteNumber(input.min, `${path}.min`),\n max: requireNullableFiniteNumber(input.max, `${path}.max`),\n displayOrder: requireFiniteNumber(input.displayOrder, `${path}.displayOrder`),\n category: requireString(input.category, `${path}.category`),\n isBasic: requireBoolean(input.isBasic, `${path}.isBasic`),\n editorType: requireString(input.editorType, `${path}.editorType`),\n };\n}\n\nfunction normalizeLink(value: unknown, path: string): DiagramDocumentLink {\n const input = requireStructure(value, path);\n return {\n id: requireIdentifier(input.id, `${path}.id`),\n from: normalizeEndpoint(input.from, `${path}.from`),\n to: normalizeEndpoint(input.to, `${path}.to`),\n style: requireLinkStyle(input.style, `${path}.style`),\n metadata: cloneJsonObject(input.metadata ?? {}, `${path}.metadata`),\n };\n}\n\n// A style the caller misspelled is a drawing that quietly loses its meaning, so it is refused\n// rather than defaulted - unlike an absent one, which simply means a plain line.\nfunction requireLinkStyle(value: unknown, path: string): DiagramLinkStyle {\n if (value === undefined || value === null) return 'solid';\n if (value !== 'solid' && value !== 'dashed') {\n throw new DiagramDocumentError(`unknown link style \"${String(value)}\"`, path);\n }\n return value;\n}\n\nfunction normalizeZone(value: unknown, path: string): DiagramDocumentZone {\n const input = requireStructure(value, path);\n return {\n id: requireIdentifier(input.id, `${path}.id`),\n name: requireString(input.name, `${path}.name`),\n // Finite, like node coordinates: NaN survives every arithmetic check and writes as null.\n x: requireFiniteNumber(input.x, `${path}.x`),\n y: requireFiniteNumber(input.y, `${path}.y`),\n width: requirePositiveSize(input.width, `${path}.width`),\n height: requirePositiveSize(input.height, `${path}.height`),\n color: input.color === undefined || input.color === null ? '' : requireString(input.color, `${path}.color`),\n metadata: cloneJsonObject(input.metadata ?? {}, `${path}.metadata`),\n };\n}\n\n// A zone with no area cannot be pointed at, and a negative one paints outside itself, so the\n// size is refused rather than clamped - a caller that computed it wrong wants to hear about it.\nfunction requirePositiveSize(value: unknown, path: string): number {\n // Finite, not merely positive: Infinity satisfies `> 0` and then serializes to null, so the\n // document would save without complaint and fail to parse back.\n const size = requireFiniteNumber(value, path);\n if (!(size > 0)) throw new DiagramDocumentError('size must be greater than zero', path);\n return size;\n}\n\nfunction normalizeEndpoint(value: unknown, path: string): DiagramDocumentEndpoint {\n const input = requireStructure(value, path);\n return {\n nodeId: requireIdentifier(input.nodeId, `${path}.nodeId`),\n portId: requireIdentifier(input.portId, `${path}.portId`),\n };\n}\n\nfunction parseNode(value: unknown, path: string): DiagramDocumentNode {\n const node = requireStructure(value, path);\n return normalizeNode({\n id: requireString(node.id, `${path}.id`),\n typeId: requireString(node.typeId, `${path}.typeId`),\n name: requireString(node.name, `${path}.name`),\n description: requireString(node.description, `${path}.description`),\n groupName: requireString(node.groupName, `${path}.groupName`),\n x: requireNumber(node.x, `${path}.x`),\n y: requireNumber(node.y, `${path}.y`),\n color: requireString(node.color, `${path}.color`),\n border: requireString(node.border, `${path}.border`),\n icon: requireString(node.icon, `${path}.icon`),\n message: requireString(node.message, `${path}.message`),\n openAction: requireString(node.openAction, `${path}.openAction`),\n inPorts: requireArray(node.inPorts, `${path}.inPorts`).map((port, index) => parsePort(port, `${path}.inPorts[${index}]`)),\n outPorts: requireArray(node.outPorts, `${path}.outPorts`).map((port, index) => parsePort(port, `${path}.outPorts[${index}]`)),\n parameters: requireArray(node.parameters, `${path}.parameters`).map((parameter, index) => parseParameter(parameter, `${path}.parameters[${index}]`)),\n paramValues: cloneStringRecord(node.paramValues, `${path}.paramValues`),\n metadata: cloneJsonObject(node.metadata, `${path}.metadata`),\n }, path);\n}\n\nfunction parsePort(value: unknown, path: string): DiagramDocumentPort {\n const port = requireStructure(value, path);\n return normalizePort({\n id: requireString(port.id, `${path}.id`),\n name: requireString(port.name, `${path}.name`),\n description: requireString(port.description, `${path}.description`),\n type: requireString(port.type, `${path}.type`),\n maxLinks: requireNumber(port.maxLinks, `${path}.maxLinks`),\n availableTypes: requireArray(port.availableTypes, `${path}.availableTypes`).map((type, index) => requireString(type, `${path}.availableTypes[${index}]`)),\n isDynamic: requireBoolean(port.isDynamic, `${path}.isDynamic`),\n dynamicMode: requirePortDynamicMode(port.dynamicMode, `${path}.dynamicMode`),\n isSibling: requireBoolean(port.isSibling, `${path}.isSibling`),\n metadata: cloneJsonObject(port.metadata, `${path}.metadata`),\n }, path);\n}\n\nfunction parseParameter(value: unknown, path: string): DiagramParameterSchema {\n const parameter = requireStructure(value, path);\n return normalizeParameter({\n name: requireString(parameter.name, `${path}.name`),\n displayName: requireString(parameter.displayName, `${path}.displayName`),\n description: requireString(parameter.description, `${path}.description`),\n type: requireString(parameter.type, `${path}.type`),\n defaultValue: requireString(parameter.defaultValue, `${path}.defaultValue`),\n options: requireArray(parameter.options, `${path}.options`).map((option, index) => requireString(option, `${path}.options[${index}]`)),\n min: requireNullableFiniteNumber(parameter.min, `${path}.min`),\n max: requireNullableFiniteNumber(parameter.max, `${path}.max`),\n displayOrder: requireNumber(parameter.displayOrder, `${path}.displayOrder`),\n category: requireString(parameter.category, `${path}.category`),\n isBasic: requireBoolean(parameter.isBasic, `${path}.isBasic`),\n editorType: requireString(parameter.editorType, `${path}.editorType`),\n }, path);\n}\n\nfunction parseLink(value: unknown, path: string): DiagramDocumentLink {\n const link = requireStructure(value, path);\n return normalizeLink({\n id: requireString(link.id, `${path}.id`),\n from: parseEndpoint(link.from, `${path}.from`),\n to: parseEndpoint(link.to, `${path}.to`),\n style: link.style === undefined ? undefined : requireLinkStyle(link.style, `${path}.style`),\n metadata: cloneJsonObject(link.metadata, `${path}.metadata`),\n }, path);\n}\n\nfunction parseEndpoint(value: unknown, path: string): DiagramDocumentEndpoint {\n const endpoint = requireStructure(value, path);\n return {\n nodeId: requireIdentifier(endpoint.nodeId, `${path}.nodeId`),\n portId: requireIdentifier(endpoint.portId, `${path}.portId`),\n };\n}\n\n/**\n * Zone ids have to be unique wherever a document comes from. Keeping the check here, rather than\n * inside createDiagramDocument alone, is what stops a file being loadable and unsaveable: the\n * parser used to let a duplicate through and the very next saveDocument() -- which rebuilds\n * through createDiagramDocument -- threw on it.\n */\nfunction validateUniqueZones(zones: readonly DiagramDocumentZone[]): void {\n const seen = new Set<string>();\n for (let index = 0; index < zones.length; index++) {\n const zone = zones[index];\n if (seen.has(zone.id)) throw new DiagramDocumentError(`duplicate zone id \"${zone.id}\"`, `$.zones[${index}].id`);\n seen.add(zone.id);\n }\n}\n\nfunction validateDocument(document: DiagramDocument): void {\n const nodes = new Map<string, DiagramDocumentNode>();\n for (let index = 0; index < document.nodes.length; index++) {\n const node = document.nodes[index];\n if (nodes.has(node.id)) throw new DiagramDocumentError(`duplicate node id \"${node.id}\"`, `$.nodes[${index}].id`);\n validateUniquePorts(node.inPorts, `$.nodes[${index}].inPorts`);\n validateUniquePorts(node.outPorts, `$.nodes[${index}].outPorts`);\n nodes.set(node.id, node);\n }\n\n const linkIds = new Set<string>();\n const endpoints = new Set<string>();\n for (let index = 0; index < document.links.length; index++) {\n const link = document.links[index];\n const path = `$.links[${index}]`;\n if (linkIds.has(link.id)) throw new DiagramDocumentError(`duplicate link id \"${link.id}\"`, `${path}.id`);\n linkIds.add(link.id);\n const fromNode = nodes.get(link.from.nodeId);\n const toNode = nodes.get(link.to.nodeId);\n if (fromNode === undefined) throw new DiagramDocumentError(`unknown source node \"${link.from.nodeId}\"`, `${path}.from.nodeId`);\n if (toNode === undefined) throw new DiagramDocumentError(`unknown target node \"${link.to.nodeId}\"`, `${path}.to.nodeId`);\n if (!fromNode.outPorts.some((port) => port.id === link.from.portId)) {\n throw new DiagramDocumentError(`unknown output port \"${link.from.portId}\"`, `${path}.from.portId`);\n }\n if (!toNode.inPorts.some((port) => port.id === link.to.portId)) {\n throw new DiagramDocumentError(`unknown input port \"${link.to.portId}\"`, `${path}.to.portId`);\n }\n const key = `${link.from.nodeId}\\u0000${link.from.portId}\\u0000${link.to.nodeId}\\u0000${link.to.portId}`;\n if (endpoints.has(key)) throw new DiagramDocumentError('duplicate link endpoints', path);\n endpoints.add(key);\n }\n\n validateUniqueZones(document.zones);\n}\n\nfunction validateUniquePorts(ports: readonly DiagramDocumentPort[], path: string): void {\n const ids = new Set<string>();\n for (let index = 0; index < ports.length; index++) {\n const id = ports[index].id;\n if (ids.has(id)) throw new DiagramDocumentError(`duplicate port id \"${id}\"`, `${path}[${index}].id`);\n ids.add(id);\n }\n}\n\nfunction cloneStringRecord(value: unknown, path: string): Record<string, string> {\n const object = requireObject(value, path);\n const result: Record<string, string> = {};\n for (const [key, item] of Object.entries(object)) setJsonKey(result, key, requireString(item, `${path}.${key}`));\n return result;\n}\n\nfunction cloneJsonObject(value: unknown, path: string, ancestors = new WeakSet<object>()): JsonObject {\n const object = requireObject(value, path);\n if (ancestors.has(object)) throw new DiagramDocumentError('circular JSON value', path);\n ancestors.add(object);\n const result: JsonObject = {};\n try {\n for (const [key, item] of Object.entries(object)) {\n setJsonKey(result, key, cloneJsonValue(item, `${path}.${key}`, ancestors));\n }\n } finally {\n ancestors.delete(object);\n }\n return result;\n}\n\nfunction cloneJsonValue(value: unknown, path: string, ancestors: WeakSet<object>): JsonValue {\n if (value === null || typeof value === 'string' || typeof value === 'boolean') return value;\n if (typeof value === 'number') return requireFiniteNumber(value, path);\n if (Array.isArray(value)) {\n if (ancestors.has(value)) throw new DiagramDocumentError('circular JSON value', path);\n ancestors.add(value);\n try {\n return value.map((item, index) => cloneJsonValue(item, `${path}[${index}]`, ancestors));\n } finally {\n ancestors.delete(value);\n }\n }\n if (isObject(value)) return cloneJsonObject(value, path, ancestors);\n throw new DiagramDocumentError('expected a JSON value', path);\n}\n\n/**\n * A container whose fields are read individually. Any object will do, including\n * a class instance: hosts build schemes out of DiagramNode and Port, not object\n * literals, and every field is validated on its own below.\n */\nfunction requireStructure(value: unknown, path: string): Record<string, unknown> {\n if (typeof value !== 'object' || value === null || Array.isArray(value)) {\n throw new DiagramDocumentError('expected an object', path);\n }\n return value as Record<string, unknown>;\n}\n\n/**\n * A value that has to survive JSON round-tripping unchanged. Stricter than\n * requireStructure on purpose: a Date or any other class instance would\n * serialize to something the parser could not read back.\n */\nfunction requireObject(value: unknown, path: string): Record<string, unknown> {\n if (!isObject(value)) throw new DiagramDocumentError('expected an object', path);\n return value;\n}\n\nfunction isObject(value: unknown): value is Record<string, unknown> {\n if (typeof value !== 'object' || value === null || Array.isArray(value)) return false;\n const prototype = Object.getPrototypeOf(value) as object | null;\n return prototype === Object.prototype || prototype === null;\n}\n\n/**\n * Reads an optional array of objects, rejecting a non-array, a hole or a\n * non-object element. null counts as absent, like the `?? []` every other\n * optional field is read through.\n */\nfunction mapElements(value: unknown, path: string): Record<string, unknown>[] {\n if (value === undefined || value === null) return [];\n // Array.from rather than map: map skips holes, carrying an undefined element\n // into the result instead of reporting it.\n return Array.from(\n requireArray(value, path),\n (element, index) => requireStructure(element, `${path}[${index}]`),\n );\n}\n\nfunction requireArray(value: unknown, path: string): unknown[] {\n if (!Array.isArray(value)) throw new DiagramDocumentError('expected an array', path);\n return value;\n}\n\nfunction requireString(value: unknown, path: string): string {\n if (typeof value !== 'string') throw new DiagramDocumentError('expected a string', path);\n return value;\n}\n\n/**\n * Coerces rather than rejects. The set is closed in the types, which is where a\n * typo gets caught, but a persisted scheme can carry anything a JavaScript host\n * wrote before that -- and refusing to load it would brick the whole document\n * over a field whose every value except 'onConnect' behaves identically. The\n * type must still be a string, so a number or an object is a real error.\n */\nfunction requirePortDynamicMode(value: unknown, path: string): PortDynamicMode {\n const mode = requireString(value, path);\n return toPortDynamicMode(mode);\n}\n\nfunction requireIdentifier(value: unknown, path: string): string {\n const id = requireString(value, path);\n if (id.trim().length === 0) throw new DiagramDocumentError('identifier cannot be empty', path);\n return id;\n}\n\nfunction requireNumber(value: unknown, path: string): number {\n if (typeof value !== 'number') throw new DiagramDocumentError('expected a number', path);\n return value;\n}\n\nfunction requireFiniteNumber(value: unknown, path: string): number {\n const number = requireNumber(value, path);\n if (!Number.isFinite(number)) throw new DiagramDocumentError('expected a finite number', path);\n return number;\n}\n\nfunction requireNullableFiniteNumber(value: unknown, path: string): number | null {\n return value === null ? null : requireFiniteNumber(value, path);\n}\n\nfunction requireNonNegativeInteger(value: unknown, path: string): number {\n const number = requireFiniteNumber(value, path);\n if (!Number.isInteger(number) || number < 0) throw new DiagramDocumentError('expected a non-negative integer', path);\n return number;\n}\n\nfunction requireBoolean(value: unknown, path: string): boolean {\n if (typeof value !== 'boolean') throw new DiagramDocumentError('expected a boolean', path);\n return value;\n}\n", "export interface DiagramCommand {\n readonly label: string;\n execute(): void;\n undo(): void;\n}\n\nexport interface DiagramHistoryState {\n canUndo: boolean;\n canRedo: boolean;\n undoDepth: number;\n redoDepth: number;\n undoLabel: string | null;\n redoLabel: string | null;\n}\n\nexport type DiagramHistoryListener = (state: DiagramHistoryState) => void;\n\ninterface TransactionFrame {\n label: string;\n commands: DiagramCommand[];\n}\n\nexport class DiagramCommandHistory {\n private readonly undoCommands: DiagramCommand[] = [];\n private readonly redoCommands: DiagramCommand[] = [];\n private readonly transactions: TransactionFrame[] = [];\n private replaying = false;\n\n constructor(private readonly listener?: DiagramHistoryListener) {}\n\n get state(): DiagramHistoryState {\n return {\n canUndo: this.undoCommands.length > 0,\n canRedo: this.redoCommands.length > 0,\n undoDepth: this.undoCommands.length,\n redoDepth: this.redoCommands.length,\n undoLabel: this.undoCommands[this.undoCommands.length - 1]?.label ?? null,\n redoLabel: this.redoCommands[this.redoCommands.length - 1]?.label ?? null,\n };\n }\n\n execute(command: DiagramCommand): void {\n if (this.replaying) {\n command.execute();\n return;\n }\n command.execute();\n this.recordApplied(command);\n }\n\n /** Records a gesture that already changed the document, such as pointer drag. */\n recordApplied(command: DiagramCommand): void {\n if (this.replaying) return;\n const transaction = this.transactions[this.transactions.length - 1];\n if (transaction !== undefined) {\n transaction.commands.push(command);\n return;\n }\n this.undoCommands.push(command);\n this.redoCommands.length = 0;\n this.notify();\n }\n\n transaction<T>(label: string, action: () => T): T {\n const frame: TransactionFrame = { label, commands: [] };\n this.transactions.push(frame);\n try {\n const result = action();\n this.transactions.pop();\n const command = compose(frame);\n if (command !== null) this.recordApplied(command);\n return result;\n } catch (error) {\n this.transactions.pop();\n this.replay(() => {\n for (const command of frame.commands.slice().reverse()) command.undo();\n });\n throw error;\n }\n }\n\n private assertNoOpenTransaction(operation: string): void {\n if (this.transactions.length > 0) {\n throw new Error(`Cannot ${operation} command history inside a transaction.`);\n }\n }\n\n undo(): boolean {\n // Same guard clear() already has: running history while a transaction is open takes a\n // committed step out from under the frame being built and breaks the LIFO invariant the\n // stacks rely on. Reachable synchronously from a host handler for an event emitted from\n // inside a transaction, so it is not a theoretical misuse.\n this.assertNoOpenTransaction('undo');\n const command = this.undoCommands.pop();\n if (command === undefined) return false;\n try {\n this.replay(() => command.undo());\n } catch (error) {\n this.undoCommands.push(command);\n throw error;\n }\n this.redoCommands.push(command);\n this.notify();\n return true;\n }\n\n redo(): boolean {\n this.assertNoOpenTransaction('redo');\n const command = this.redoCommands.pop();\n if (command === undefined) return false;\n try {\n this.replay(() => command.execute());\n } catch (error) {\n this.redoCommands.push(command);\n throw error;\n }\n this.undoCommands.push(command);\n this.notify();\n return true;\n }\n\n clear(): void {\n this.assertNoOpenTransaction('clear');\n this.undoCommands.length = 0;\n this.redoCommands.length = 0;\n this.notify();\n }\n\n private replay(action: () => void): void {\n const previous = this.replaying;\n this.replaying = true;\n try {\n action();\n } finally {\n this.replaying = previous;\n }\n }\n\n private notify(): void {\n this.listener?.(this.state);\n }\n}\n\nfunction compose(frame: TransactionFrame): DiagramCommand | null {\n if (frame.commands.length === 0) return null;\n if (frame.commands.length === 1) {\n const command = frame.commands[0];\n return frame.label === command.label ? command : {\n label: frame.label,\n execute: () => command.execute(),\n undo: () => command.undo(),\n };\n }\n const commands = [...frame.commands];\n return {\n label: frame.label,\n execute: () => {\n for (const command of commands) command.execute();\n },\n undo: () => {\n for (const command of commands.slice().reverse()) command.undo();\n },\n };\n}\n", "/**\n * Recursively read-only view of a state object. The snapshot accessors hand back\n * detached copies, so writing to one is silently discarded -- this makes that a\n * compile error instead. The setters accept it, so a snapshot still round-trips.\n */\nexport type DiagramSnapshot<T> = {\n readonly [K in keyof T]: DiagramSnapshotValue<T[K]>;\n};\n\n// Distributes over unions, so an optional or nullable object property keeps\n// being descended into instead of falling through as its writable self.\ntype DiagramSnapshotValue<T> = T extends readonly (infer TItem)[]\n ? readonly DiagramSnapshotValue<TItem>[]\n : T extends object\n ? DiagramSnapshot<T>\n : T;\n\nexport type DiagramPortDirection = 'in' | 'out';\nexport type DiagramNodeErrorKind = 'runtime' | 'load';\nexport type DiagramGlobalErrorKind = 'invalid' | 'load' | 'locked' | 'encrypted';\n\nexport interface DiagramErrorState<TKind extends string> {\n kind: TKind;\n message: string;\n /** Incrementing this value requests a fresh renderer animation. */\n pulse: number;\n}\n\nexport interface DiagramPortRuntimeState {\n active: boolean;\n selected: boolean;\n breakpoint: boolean;\n breakpointActive: boolean;\n value: string | null;\n error: string | null;\n}\n\nexport interface DiagramNodePortRuntimeState {\n in: Record<string, DiagramPortRuntimeState>;\n out: Record<string, DiagramPortRuntimeState>;\n}\n\n/**\n * At most one error per kind. A node can carry a load error and a runtime error\n * at the same time -- the tooltip shows both -- so a single slot could not hold\n * what the editor already models, and every state write dropped one of them.\n */\nexport type DiagramNodeErrors = {\n [TKind in DiagramNodeErrorKind]?: DiagramErrorState<TKind>;\n};\n\nexport interface DiagramNodeRuntimeState {\n active: boolean;\n errors: DiagramNodeErrors;\n ports: DiagramNodePortRuntimeState;\n}\n\nexport interface DiagramRuntimeState {\n activeNodeId: string | null;\n nodes: Record<string, DiagramNodeRuntimeState>;\n globalError: DiagramErrorState<DiagramGlobalErrorKind> | null;\n}\n\nexport interface DiagramViewState {\n zoom: number;\n panX: number;\n panY: number;\n overviewVisible: boolean;\n}\n\nexport interface DiagramSelectedPort {\n nodeId: string;\n portId: string;\n direction: DiagramPortDirection;\n}\n\nexport interface DiagramSelection {\n nodeIds: string[];\n linkIds: string[];\n port: DiagramSelectedPort | null;\n primaryNodeId: string | null;\n primaryLinkId: string | null;\n}\n\nexport interface DiagramInteractionPermissions {\n select: boolean;\n inspect: boolean;\n copy: boolean;\n moveNodes: boolean;\n createLinks: boolean;\n deleteSelection: boolean;\n paste: boolean;\n history: boolean;\n}\n\nexport function createDiagramRuntimeState(): DiagramRuntimeState {\n return { activeNodeId: null, nodes: {}, globalError: null };\n}\n\nexport function cloneDiagramRuntimeState(state: DiagramRuntimeState): DiagramRuntimeState {\n return {\n activeNodeId: state.activeNodeId,\n globalError: state.globalError === null ? null : { ...state.globalError },\n nodes: Object.fromEntries(Object.entries(state.nodes).map(([nodeId, node]) => [nodeId, {\n active: node.active,\n errors: cloneDiagramNodeErrors(node.errors),\n ports: {\n in: Object.fromEntries(Object.entries(node.ports.in)\n .map(([portId, port]) => [portId, { ...port }])),\n out: Object.fromEntries(Object.entries(node.ports.out)\n .map(([portId, port]) => [portId, { ...port }])),\n },\n }])),\n };\n}\n\nexport function createDiagramViewState(): DiagramViewState {\n return { zoom: 1, panX: 0, panY: 0, overviewVisible: true };\n}\n\nexport function createDiagramSelection(): DiagramSelection {\n return {\n nodeIds: [],\n linkIds: [],\n port: null,\n primaryNodeId: null,\n primaryLinkId: null,\n };\n}\n\nexport function createDiagramPortRuntimeState(): DiagramPortRuntimeState {\n return {\n active: false,\n selected: false,\n breakpoint: false,\n breakpointActive: false,\n value: null,\n error: null,\n };\n}\n\nexport function createEditableDiagramPermissions(): DiagramInteractionPermissions {\n return {\n select: true,\n inspect: true,\n copy: true,\n moveNodes: true,\n createLinks: true,\n deleteSelection: true,\n paste: true,\n history: true,\n };\n}\n\nexport function createReadOnlyDiagramPermissions(): DiagramInteractionPermissions {\n return {\n select: true,\n inspect: true,\n copy: true,\n moveNodes: false,\n createLinks: false,\n deleteSelection: false,\n paste: false,\n history: false,\n };\n}\n\nexport function createDiagramNodeRuntimeState(): DiagramNodeRuntimeState {\n return {\n active: false,\n errors: {},\n ports: { in: {}, out: {} },\n };\n}\n\n/**\n * Tolerates a missing map: hosts persist runtime snapshots and build them by\n * hand, so a state written before this field existed still has to be readable.\n */\nexport function cloneDiagramNodeErrors(errors: DiagramNodeErrors | undefined | null): DiagramNodeErrors {\n const result: DiagramNodeErrors = {};\n if (errors === undefined || errors === null) return result;\n if (errors.runtime !== undefined) result.runtime = { ...errors.runtime };\n if (errors.load !== undefined) result.load = { ...errors.load };\n return result;\n}\n", "import type { DrawSurface } from './draw-surface.js';\nimport { SvgSurface } from './svg-surface.js';\nimport { readableOutlineOn, readableTextOn } from './color.js';\n// Internal dependency-free canvas renderer used by StockSharpDiagram.\n//\n// Dependency-free, pure 2D canvas. Demonstrates the hard parts: typed\n// in/out ports, bezier links, node drag, drag-to-link with validation,\n// selection, delete, zoom/pan, load/save round-trip.\n\nimport { createDiagramDocument, parseDiagramDocument } from './core/document.js';\nimport { DiagramCommandHistory } from './core/history.js';\nimport { getJsonKey, setJsonKey } from './core/json.js';\nimport { toPortDynamicMode } from './core/model.js';\nimport type {\n DiagramDocumentZone,\n DiagramLinkStyle,\n DiagramDocument,\n DiagramParameterSchema,\n JsonObject,\n JsonValue,\n PortDynamicMode,\n} from './core/model.js';\nimport type {\n DiagramGlobalErrorKind,\n DiagramInteractionPermissions,\n DiagramPortRuntimeState,\n DiagramRuntimeState,\n DiagramSelection,\n DiagramViewState,\n} from './core/state.js';\nimport {\n cloneDiagramRuntimeState,\n createDiagramNodeRuntimeState,\n createDiagramPortRuntimeState,\n createDiagramRuntimeState,\n createEditableDiagramPermissions,\n createReadOnlyDiagramPermissions,\n} from './core/state.js';\n\nexport type PortDirection = 'in' | 'out';\nexport type PortClickAction = 'leftClick' | 'rightClick';\n\nexport interface PortInit {\n id: string;\n name: string;\n description?: string;\n type?: string;\n maxLinks?: number;\n availableTypes?: string[];\n isDynamic?: boolean;\n dynamicMode?: PortDynamicMode;\n isSibling?: boolean;\n metadata?: JsonObject;\n}\n\n/** Mutable port properties. Port identity and direction remain stable. */\nexport type PortUpdate = Partial<Omit<PortInit, 'id'>>;\n\nexport interface DiagramNodeInit {\n id?: string;\n typeId?: string;\n name: string;\n description?: string;\n groupName?: string;\n color?: string;\n border?: string;\n icon?: string;\n x?: number;\n y?: number;\n inPorts?: PortInit[];\n outPorts?: PortInit[];\n /** Non-empty host action enables node double-click tracking. */\n openAction?: string;\n /** Transient error discovered while loading a scheme. */\n loadError?: string;\n /** Persistent host text. Runtime/load errors are stored separately. */\n message?: string;\n parameters?: DiagramParameterSchema[];\n paramValues?: Record<string, string>;\n metadata?: JsonObject;\n /** Transient missing-catalog marker; excluded from saveDocument(). */\n isPlaceholder?: boolean;\n}\n\nexport interface LinkInit {\n id?: string;\n from: string;\n fromPort: string;\n to: string;\n toPort: string;\n /** Solid unless the link is one that may not be there - see DiagramLinkStyle. */\n style?: DiagramLinkStyle;\n metadata?: JsonObject;\n}\n\nexport type DiagramNodeSnapshot = DiagramNodeInit\n & Required<Pick<DiagramNodeInit, 'id' | 'typeId' | 'name' | 'color' | 'border' | 'x' | 'y'>>\n & { inPorts: PortInit[]; outPorts: PortInit[] };\n\nexport interface DiagramSnapshot {\n nodes: DiagramNodeSnapshot[];\n // Endpoints alone made the snapshot lossy: a save()/load() round-trip dropped every link's\n // identity, style and metadata, and the links carried in loadFinished / undoRequested /\n // redoRequested arrived with an empty id, so selectLink(payload.link.id) matched nothing.\n links: Array<Required<Pick<LinkInit, 'id' | 'from' | 'fromPort' | 'to' | 'toPort' | 'style'>> & Pick<LinkInit, 'metadata'>>;\n}\n\nexport interface DiagramOptions {\n host: HTMLElement;\n background?: string;\n gridColor?: string;\n /** Snap dragged nodes to a world-space grid. Defaults to false for the low-level renderer. */\n gridSnap?: boolean;\n /** Tint for a zone that names no colour of its own. */\n zoneColor?: string;\n /** Positive world-space grid step. Defaults to 28. */\n gridSize?: number;\n /** Optional explicit socket-type \u2192 colour map; unknown types hash to a hue. */\n typeColors?: Record<string, string>;\n /** Ceiling (0..1) for link/socket colour lightness. Unset = full palette (tuned for a dark\n * canvas). A light theme sets a low ceiling so the otherwise-light link colours darken enough\n * to stay visible on a light canvas. */\n linkMaxLightness?: number;\n /** When true, colour links by their source socket type; the default draws links in the neutral grey. */\n typedLinkColors?: boolean;\n /** Optional minimap colours. When omitted they are derived from the\n * current canvas background, so a normal light/dark theme switch also\n * rethemes the overview. */\n overviewBackground?: string;\n overviewBorderColor?: string;\n overviewViewportColor?: string;\n overviewViewportFill?: string;\n}\n\nexport type DiagramScreenshotScope = 'viewport' | 'content';\n\nexport interface DiagramScreenshotOptions {\n /** Current viewport (Charts/WPF parity) or the complete graph bounds. Defaults to viewport. */\n scope?: DiagramScreenshotScope;\n /** World-to-CSS-pixel scale for content export. Defaults to 1. */\n scale?: number;\n /** CSS-pixel padding around content export. Defaults to 32. */\n padding?: number;\n /** Output pixel density. Defaults to the renderer's current device pixel ratio. */\n pixelRatio?: number;\n /** Optional export-only background override. */\n background?: string;\n /** Defaults to true. */\n includeGrid?: boolean;\n /** Defaults to the current value for viewport and false for content. */\n includeOverview?: boolean;\n /** Defaults to true for viewport and false for content. */\n includeSelection?: boolean;\n /** Include debugger and error state. Defaults to true. */\n includeRuntimeState?: boolean;\n}\n\nexport interface LinkValidatorArgs {\n fromNode: NodeModel;\n fromPort: PortModel;\n toNode: NodeModel;\n toPort: PortModel;\n}\nexport type LinkValidator = (args: LinkValidatorArgs) => boolean;\n\nexport type LinkValidationReason =\n | 'allowed'\n | 'missing-link'\n | 'missing-node'\n | 'missing-port'\n | 'same-node'\n | 'invalid-direction'\n | 'incompatible-type'\n | 'duplicate-link'\n | 'source-limit'\n | 'target-limit'\n | 'host-rejected';\n\nexport interface LinkValidationResult {\n allowed: boolean;\n reason: LinkValidationReason;\n}\n\nexport type NodeErrorKind = 'runtime' | 'load';\n\nexport interface NodeErrorOptions {\n /** Runtime errors flash the border; load errors use a red background. */\n kind?: NodeErrorKind;\n /** Disable the initial runtime-error border flash. Defaults to true. */\n animate?: boolean;\n}\n\nexport interface DiagramEvents {\n nodeAdded: { node: NodeModel };\n nodeRemoved: { node: NodeModel };\n nodeMoved: { node: NodeModel };\n nodeChanged: { node: NodeModel };\n nodeSelected: { node: NodeModel | null; selected: boolean };\n nodeHover: { node: NodeModel; hovering: boolean };\n linkAdded: { link: LinkModel };\n linkRemoved: { link: LinkModel };\n linkRelinked: { link: LinkModel; previous: LinkInit & { id: string } };\n linkSelected: { link: LinkModel | null; selected: boolean };\n linkHover: { link: LinkModel; hovering: boolean };\n linkValidation: {\n fromNode: NodeModel;\n from: PortModel;\n toNode: NodeModel;\n to: PortModel;\n allowed: boolean;\n reason: LinkValidationReason;\n };\n portSelected: { node: NodeModel; port: PortModel };\n portClicked: {\n node: NodeModel;\n port: PortModel;\n action: PortClickAction;\n ctrlKey: boolean;\n shiftKey: boolean;\n altKey: boolean;\n metaKey: boolean;\n };\n portHover: { node: NodeModel; port: PortModel; hovering: boolean };\n nodeOpen: { node: NodeModel };\n loadFinished: { nodes: NodeModel[]; links: LinkModel[] };\n zoomChanged: { scale: number };\n viewChanged: DiagramViewState;\n // Long-press on touch / right-click on desktop. (x, y) are page coords\n // so the host can position a DOM menu directly. Port, link or node\n // (or all null for empty-space) describe the target.\n contextMenu: {\n x: number;\n y: number;\n link: LinkModel | null;\n node: NodeModel | null;\n port: { node: NodeModel; port: PortModel } | null;\n };\n // Fires whenever the undo or redo stacks change so the host can\n // enable/disable Undo/Redo toolbar buttons live.\n undoStackChanged: { canUndo: boolean; canRedo: boolean };\n selectionChanged: DiagramSelection;\n runtimeStateChanged: { state: DiagramRuntimeState };\n}\n\ninterface DiagramRenderOptions {\n grid: boolean;\n overview: boolean;\n selection: boolean;\n runtime: boolean;\n transient: boolean;\n}\n\nconst SCREEN_RENDER_OPTIONS: DiagramRenderOptions = {\n grid: true,\n overview: true,\n selection: true,\n runtime: true,\n transient: true,\n};\n// One reversible operation. `do` re-applies it (redo), `undo` reverses\n// it. Both must be idempotent w.r.t. repeated undo/redo. label is for\n// telemetry/debug only.\ninterface AppliedAction { do: () => void; undo: () => void; label: string }\ntype EvName = keyof DiagramEvents;\n\n// ---- model ----------------------------------------------------------\nfunction copyJsonValue(value: JsonValue): JsonValue {\n if (Array.isArray(value)) return value.map(copyJsonValue);\n if (value !== null && typeof value === 'object') return copyJsonObject(value);\n return value;\n}\n\nfunction copyJsonObject(value: JsonObject | undefined): JsonObject {\n if (value === undefined) return {};\n const result: JsonObject = {};\n for (const [key, item] of Object.entries(value)) setJsonKey(result, key, copyJsonValue(item));\n return result;\n}\n\nfunction copyParameters(value: readonly DiagramParameterSchema[] | undefined): DiagramParameterSchema[] {\n return (value ?? []).map((parameter) => ({ ...parameter, options: [...parameter.options] }));\n}\n\nfunction normalizePortType(type: string): string {\n return type.trim().toLowerCase();\n}\n\nfunction isWildcardPortType(type: string): boolean {\n const normalized = normalizePortType(type);\n return normalized === ''\n || normalized === '*'\n || normalized === 'any'\n || normalized === 'anydata'\n || normalized === 'any data'\n || normalized === 'object'\n || normalized === 'system.object'\n || normalized.startsWith('system.object,');\n}\n\n// The empty socket a grow-on-connect input spawns its siblings from. The scheme records it\n// first, but it accepts nothing until something is wired into it, so it belongs under the\n// sockets that do carry data.\nfunction isGrowAnchor(port: PortModel): boolean {\n return port.isDynamic && !port.isSibling;\n}\n\nfunction arePortTypesCompatible(fromType: string, toType: string, availableTypes: readonly string[]): boolean {\n if (isWildcardPortType(fromType) || isWildcardPortType(toType)) return true;\n const normalizedFrom = normalizePortType(fromType);\n return [toType, ...availableTypes].some((type) =>\n isWildcardPortType(type) || normalizePortType(type) === normalizedFrom);\n}\n\nexport class PortModel {\n id: string;\n name: string;\n description: string;\n type: string;\n direction: PortDirection;\n maxLinks: number;\n availableTypes: string[];\n isDynamic: boolean;\n dynamicMode: PortDynamicMode;\n isSibling: boolean;\n metadata: JsonObject;\n // layout cache (world coords), filled at draw time\n cx = 0;\n cy = 0;\n constructor(init: PortInit, dir: PortDirection) {\n this.id = init.id;\n this.name = init.name;\n this.description = init.description ?? '';\n this.type = init.type ?? '';\n this.direction = dir;\n this.maxLinks = typeof init.maxLinks === 'number' ? init.maxLinks : 0;\n this.availableTypes = [...(init.availableTypes ?? [])];\n this.isDynamic = init.isDynamic ?? false;\n this.dynamicMode = toPortDynamicMode(init.dynamicMode);\n this.isSibling = init.isSibling ?? false;\n this.metadata = copyJsonObject(init.metadata);\n }\n\n toInit(): PortInit {\n return {\n id: this.id,\n name: this.name,\n description: this.description,\n type: this.type,\n maxLinks: this.maxLinks,\n availableTypes: [...this.availableTypes],\n isDynamic: this.isDynamic,\n dynamicMode: this.dynamicMode,\n isSibling: this.isSibling,\n metadata: copyJsonObject(this.metadata),\n };\n }\n}\n\nexport class NodeModel {\n id: string;\n typeId: string;\n name: string;\n description: string;\n groupName: string;\n color: string;\n border: string;\n icon: string;\n openAction: string;\n message: string;\n parameters: DiagramParameterSchema[];\n paramValues: Record<string, string>;\n metadata: JsonObject;\n isPlaceholder: boolean;\n loadError: string;\n runtimeError = '';\n errorFlashStart: number | null = null;\n x: number;\n y: number;\n inPorts: PortModel[];\n outPorts: PortModel[];\n // layout cache\n w = 160;\n h = 48;\n constructor(init: DiagramNodeInit, id: string) {\n this.id = id;\n this.typeId = init.typeId ?? id;\n this.name = init.name;\n this.description = init.description ?? '';\n this.groupName = init.groupName ?? 'Common';\n this.color = init.color ?? '#d7d7d7';\n this.border = init.border ?? '#8c8c8c';\n this.icon = init.icon ?? '';\n this.openAction = init.openAction ?? '';\n this.message = init.message ?? '';\n this.parameters = copyParameters(init.parameters);\n this.paramValues = { ...(init.paramValues ?? {}) };\n this.metadata = copyJsonObject(init.metadata);\n this.isPlaceholder = init.isPlaceholder ?? false;\n this.loadError = init.loadError ?? '';\n this.x = typeof init.x === 'number' ? init.x : 0;\n this.y = typeof init.y === 'number' ? init.y : 0;\n this.inPorts = (init.inPorts ?? []).map((p) => new PortModel(p, 'in'));\n this.outPorts = (init.outPorts ?? []).map((p) => new PortModel(p, 'out'));\n }\n port(id: string): PortModel | undefined {\n return this.inPorts.find((p) => p.id === id) ?? this.outPorts.find((p) => p.id === id);\n }\n\n toInit(includeRuntimeState: boolean = true): DiagramNodeInit & { id: string } {\n const init: DiagramNodeInit & { id: string } = {\n id: this.id,\n typeId: this.typeId,\n name: this.name,\n description: this.description,\n groupName: this.groupName,\n color: this.color,\n border: this.border,\n icon: this.icon,\n openAction: this.openAction,\n message: this.message,\n parameters: copyParameters(this.parameters),\n paramValues: { ...this.paramValues },\n metadata: copyJsonObject(this.metadata),\n isPlaceholder: this.isPlaceholder,\n x: this.x,\n y: this.y,\n inPorts: this.inPorts.map((port) => port.toInit()),\n outPorts: this.outPorts.map((port) => port.toInit()),\n };\n if (includeRuntimeState && this.loadError.length > 0) init.loadError = this.loadError;\n return init;\n }\n}\n\nexport class LinkModel {\n readonly id: string;\n readonly metadata: JsonObject;\n\n constructor(\n public from: string,\n public fromPort: string,\n public to: string,\n public toPort: string,\n id: string = '',\n metadata?: JsonObject,\n public style: DiagramLinkStyle = 'solid',\n ) {\n this.id = id;\n this.metadata = copyJsonObject(metadata);\n }\n key(): string { return `${this.from}|${this.fromPort}|${this.to}|${this.toPort}`; }\n\n toInit(): LinkInit & { id: string } {\n return {\n id: this.id,\n from: this.from,\n fromPort: this.fromPort,\n to: this.to,\n toPort: this.toPort,\n style: this.style,\n metadata: copyJsonObject(this.metadata),\n };\n }\n}\n\nconst PORT_R = 6;\nconst PORT_ROW_H = 20;\nconst RELINK_HANDLE_PX = 8; // WPF relink adornment is an 8x8 diamond\nconst RELINK_DRAG_THRESHOLD_PX = 4;\nconst PORT_SQ = 9; // socket square size \u2014 sits outside the node\nconst LINK_STUB = 22; // min horizontal lead-in/out before the elbow\nconst LINK_HOP = 5; // jump-over arc radius at crossings\nconst LINK_CORNER = 8; // corner rounding radius at elbows\nconst SNAP_PX = 32; // plug\u2194socket magnet radius (screen px)\nconst DEFAULT_GRID_SIZE = 28;\nconst ZOOM_MIN = 0.15;\nconst ZOOM_MAX = 4;\nconst INTRO_MS = 520; // entrance animation duration\nconst INTRO_RISE = 70; // px the scheme rises from below\nconst ERROR_FLASH_MS = 1100;\nconst ERROR_RED = '#f6465d';\nconst ERROR_BACKGROUND = '#7d2632';\n\nconst clamp = (v: number, lo: number, hi: number): number => Math.min(hi, Math.max(lo, v));\n\nfunction hashHue(s: string): number {\n let h = 0;\n for (let i = 0; i < s.length; i += 1) h = (h * 31 + s.charCodeAt(i)) | 0;\n return ((h % 360) + 360) % 360;\n}\n\n// Clamp an hsl() colour's lightness to a ceiling (0..1), keeping its hue and saturation. The link\n// palette is tuned for a dark canvas (light, ~58%-lightness colours), so on a light canvas those\n// wash out; a light theme passes a low ceiling to darken the links just enough to stay readable\n// while keeping each hue distinct. Non-hsl inputs are returned untouched.\nfunction clampLightness(color: string, maxL: number): string {\n const m = color.match(/^hsl\\(\\s*([\\d.]+)\\s*,\\s*([\\d.]+)%\\s*,\\s*([\\d.]+)%\\s*\\)$/i);\n if (m === null) return color;\n return `hsl(${m[1]}, ${m[2]}%, ${Math.min(+m[3], maxL * 100)}%)`;\n}\n\nfunction colorLuminance(color: string | undefined): number {\n if (color === undefined) return 0;\n const hex = color.trim().match(/^#([0-9a-f]{3}|[0-9a-f]{6})$/i);\n if (hex !== null) {\n const raw = hex[1].length === 3\n ? hex[1].split('').map((x) => x + x).join('')\n : hex[1];\n const value = parseInt(raw, 16);\n return 0.299 * ((value >> 16) & 255)\n + 0.587 * ((value >> 8) & 255)\n + 0.114 * (value & 255);\n }\n const rgb = color.match(/^rgba?\\(\\s*([\\d.]+)\\s*,\\s*([\\d.]+)\\s*,\\s*([\\d.]+)/i);\n if (rgb !== null)\n return 0.299 * +rgb[1] + 0.587 * +rgb[2] + 0.114 * +rgb[3];\n return 0;\n}\n\nexport class Diagram {\n /// Outline every socket is edged with, refreshed from the background each draw.\n private portOutline = readableOutlineOn('#1b1b1f');\n private readonly host: HTMLElement;\n private readonly canvas: HTMLCanvasElement;\n // Typed as the surface, not the context: the on-screen path still passes the browser's own\n // 2D context (it satisfies the interface structurally), while export can hand in an SVG one.\n private ctx: DrawSurface;\n private readonly opts: DiagramOptions;\n\n private nodes: NodeModel[] = [];\n private links: LinkModel[] = [];\n private zones: DiagramDocumentZone[] = [];\n private idSeq = 1;\n private linkSeq = 1;\n private documentMetadata: JsonObject = {};\n private runtimeState: DiagramRuntimeState = createDiagramRuntimeState();\n private runtimePulse = 0;\n private globalErrorFlashStart: number | null = null;\n\n // viewport transform: screen = world * scale + offset\n private scale = 1;\n private offX = 0;\n private offY = 0;\n\n private width = 0;\n private height = 0;\n private dpr = 1;\n private drawScheduled = false;\n private gridSnapEnabled: boolean;\n private gridSize: number;\n\n // interaction state\n private selectedNode: NodeModel | null = null; // primary (last) selected\n private selectedNodes = new Set<NodeModel>(); // multi-selection\n private selectedLink: LinkModel | null = null;\n private selectedPort: { node: NodeModel; port: PortModel } | null = null;\n private dragNode: NodeModel | null = null;\n private dragStart: Array<{ n: NodeModel; x: number; y: number }> = []; // group-drag origin\n private dragAnchor = { wx: 0, wy: 0 };\n private panning = false;\n private panX = 0;\n private panY = 0;\n private permissions = createEditableDiagramPermissions();\n private showNodeMessages = true;\n private iconCache = new Map<string, HTMLImageElement | null>(); // node icon images by URL (null = loading/failed)\n private rubber: { x0: number; y0: number; x: number; y: number } | null = null; // world rect\n private clip: DiagramDocument | null = null;\n private linking: { node: NodeModel; port: PortModel } | null = null;\n private relinking: { link: LinkModel; end: 'from' | 'to' } | null = null;\n private relinkCandidate: {\n link: LinkModel;\n end: 'from' | 'to';\n sx: number;\n sy: number;\n } | null = null;\n private linkSnap: { node: NodeModel; port: PortModel } | null = null;\n private cursor = { x: 0, y: 0 }; // screen\n private hoverPort: { node: NodeModel; port: PortModel } | null = null;\n private hoverNode: NodeModel | null = null;\n private hoveredLink: LinkModel | null = null;\n // Type feeding each wired input, keyed by node and port, rebuilt for every frame.\n private portFeed: ReadonlyMap<PortModel, string> = new Map();\n private tipTimer: ReturnType<typeof setTimeout> | null = null;\n private tipShow = false;\n private tipTarget: PortModel | NodeModel | null = null;\n // Long-press (touch) / right-click (desktop) \u2192 contextMenu event.\n private lpTimer: ReturnType<typeof setTimeout> | null = null;\n private lpStart: { sx: number; sy: number; px: number; py: number } | null = null;\n private readonly lpDelayMs = 550;\n private readonly lpMoveTol = 7;\n private readonly history: DiagramCommandHistory;\n private readonly domDisposables: Array<() => void> = [];\n private destroyed = false;\n\n // Overview minimap.\n private introStart: number | null = null;\n private overviewVisible = true;\n private ovDragging = false;\n private historyShortcut: (direction: 'undo' | 'redo') => void =\n (direction) => { if (direction === 'undo') this.undo(); else this.redo(); };\n private ovGeo: { x: number; y: number; w: number; h: number; s: number; minX: number; minY: number } | null = null;\n\n private validator: LinkValidator | null = null;\n private handlers = new Map<EvName, Set<(p: never) => void>>();\n\n constructor(opts: DiagramOptions) {\n this.opts = opts;\n // Same normalization setTypeColors applies, so a palette handed in at construction is\n // keyed like one handed in later.\n if (opts.typeColors !== undefined) this.setTypeColorsInternal(opts.typeColors);\n this.host = opts.host;\n this.gridSnapEnabled = opts.gridSnap ?? false;\n this.gridSize = this.normalizeGridSize(opts.gridSize ?? DEFAULT_GRID_SIZE);\n this.history = new DiagramCommandHistory(() => {\n // The gated values, not the raw stack: setInteractionPermissions and setReadOnly\n // already publish canUndo()/canRedo(), and a toolbar fed the raw pair enabled its\n // Undo button for a call that undo() would refuse.\n this.emit('undoStackChanged', { canUndo: this.canUndo(), canRedo: this.canRedo() });\n });\n this.canvas = document.createElement('canvas');\n this.canvas.style.display = 'block';\n this.canvas.tabIndex = 0; // focusable \u2192 key events\n this.canvas.style.outline = 'none';\n // Eat browser-native touch gestures (page scroll / pinch-zoom) so\n // fingers actually drive our pan/zoom on mobile instead of the page.\n this.canvas.style.touchAction = 'none';\n // No OS text-selection on long-press (would pop the iOS magnifier\n // and select node/link captions instead of firing our menu).\n this.canvas.style.userSelect = 'none';\n (this.canvas.style as unknown as { webkitUserSelect: string }).webkitUserSelect = 'none';\n (this.canvas.style as unknown as { webkitTouchCallout: string }).webkitTouchCallout = 'none';\n this.host.appendChild(this.canvas);\n const ctx = this.canvas.getContext('2d');\n if (ctx === null) throw new Error('ssdiagram: 2d context unavailable');\n this.ctx = ctx;\n this.resize(this.host.clientWidth || 800, this.host.clientHeight || 480);\n this.observeHostSize();\n this.bind();\n }\n\n /// The control creates the canvas, so it keeps it the size of the element it was mounted in.\n /// A host that lays its panels out after construction - a docking shell, a tab that opens\n /// hidden - measures nothing at that point, and the fallback size above would then outlive\n /// the layout: a strip of the panel that draws nothing and answers no clicks. resize()\n /// ignores anything smaller than two pixels, so a panel switched away from keeps its view.\n private observeHostSize(): void {\n if (typeof ResizeObserver === 'undefined') return;\n\n const observer = new ResizeObserver(() => this.resize(this.host.clientWidth, this.host.clientHeight));\n observer.observe(this.host);\n this.domDisposables.push(() => observer.disconnect());\n }\n\n // ---- events -----------------------------------------------------\n on<K extends EvName>(ev: K, h: (p: DiagramEvents[K]) => void): () => void {\n let set = this.handlers.get(ev);\n if (set === undefined) { set = new Set(); this.handlers.set(ev, set); }\n set.add(h as (p: never) => void);\n return () => set!.delete(h as (p: never) => void);\n }\n private emit<K extends EvName>(ev: K, p: DiagramEvents[K]): void {\n const set = this.handlers.get(ev);\n if (set === undefined) return;\n for (const h of set) { try { (h as (x: DiagramEvents[K]) => void)(p); } catch (e) { console.error(e); } }\n }\n\n // ---- public API (Layer-A-shaped) --------------------------------\n setLinkValidator(fn: LinkValidator | null): void { this.validator = fn; }\n setGridSnap(enabled: boolean, size?: number): void {\n const nextSize = size === undefined ? this.gridSize : this.normalizeGridSize(size);\n this.gridSnapEnabled = enabled;\n this.gridSize = nextSize;\n this.scheduleDraw();\n }\n getGridSnap(): { enabled: boolean; size: number } {\n return { enabled: this.gridSnapEnabled, size: this.gridSize };\n }\n\n private normalizeGridSize(size: number): number {\n if (!Number.isFinite(size) || size <= 0) throw new RangeError('ssdiagram: grid size must be a positive finite number');\n return size;\n }\n\n private nextNodeId(): string {\n let id: string;\n do id = `n${this.idSeq++}`;\n while (this.nodes.some((node) => node.id === id));\n return id;\n }\n\n private nextLinkId(): string {\n let id: string;\n do id = `link_${this.linkSeq++}`;\n while (this.links.some((link) => link.id === id));\n return id;\n }\n\n addDiagramNode(init: DiagramNodeInit): string {\n const id = init.id ?? this.nextNodeId();\n if (id.trim().length === 0) throw new Error('ssdiagram: node id cannot be empty');\n if (this.nodes.some((node) => node.id === id)) throw new Error(`ssdiagram: duplicate node id \"${id}\"`);\n const fullInit: DiagramNodeInit = { ...init, id };\n this.doAddNode(fullInit);\n this.record({\n do: () => { this.doAddNode(fullInit); },\n undo: () => { this.doRemoveNode(id); },\n label: 'add node',\n });\n return id;\n }\n private doAddNode(init: DiagramNodeInit): void {\n const id = init.id ?? this.nextNodeId();\n if (this.nodes.some((node) => node.id === id)) return;\n const node = new NodeModel(init, id);\n this.layoutNode(node);\n this.nodes.push(node);\n this.emit('nodeAdded', { node });\n this.scheduleDraw();\n }\n removeDiagramNode(id: string): void {\n const node = this.nodes.find((n) => n.id === id);\n if (node === undefined) return;\n // Capture full state for undo BEFORE mutating \u2014 we need both\n // the node init AND every link that gets cascaded out, so undo\n // can rebuild them in one shot.\n const snapshot = node.toInit(false);\n const cascaded = this.links\n .map((link, index) => ({ link, index }))\n .filter(({ link }) => link.from === id || link.to === id)\n .map(({ link, index }) => ({ init: link.toInit(), index }));\n const siblingTargets: Array<{ nodeId: string; portId: string }> = [];\n for (const { init } of cascaded) {\n if (init.from !== id || init.to === id) continue;\n const targetPort = this.findNode(init.to)?.inPorts.find((port) => port.id === init.toPort);\n if (targetPort?.isSibling !== true) continue;\n if (!siblingTargets.some((target) => target.nodeId === init.to && target.portId === init.toPort)) {\n siblingTargets.push({ nodeId: init.to, portId: init.toPort });\n }\n }\n const remove = (): void => {\n this.doRemoveNode(id);\n this.record({\n do: () => { this.doRemoveNode(id); },\n undo: () => {\n this.doAddNode(snapshot);\n for (const { init, index } of cascaded) this.doAddLink(init, false, index);\n },\n label: 'remove node',\n });\n };\n if (siblingTargets.length === 0) {\n remove();\n } else {\n this.withTransaction('remove node', () => {\n remove();\n for (const target of siblingTargets) this.pruneDynamicSibling(target.nodeId, target.portId);\n });\n }\n }\n private doRemoveNode(id: string): void {\n const node = this.nodes.find((n) => n.id === id);\n if (node === undefined) return;\n const removedLinks = this.links.filter((l) => l.from === id || l.to === id);\n this.links = this.links.filter((l) => l.from !== id && l.to !== id);\n this.nodes = this.nodes.filter((n) => n !== node);\n let selectionChanged = this.selectedNodes.delete(node);\n if (this.selectedNode === node) {\n const remaining = [...this.selectedNodes];\n this.selectedNode = remaining[remaining.length - 1] ?? null;\n selectionChanged = true;\n }\n if (this.selectedPort?.node === node) {\n this.selectedPort = null;\n selectionChanged = true;\n }\n if (this.selectedLink !== null && removedLinks.includes(this.selectedLink)) {\n this.selectedLink = null;\n selectionChanged = true;\n }\n if (selectionChanged) this.emitSelectionChanged();\n for (const l of removedLinks) this.emit('linkRemoved', { link: l });\n this.emit('nodeRemoved', { node });\n this.scheduleDraw();\n }\n moveNode(id: string, x: number, y: number): void {\n const node = this.nodes.find((n) => n.id === id);\n if (node === undefined) return;\n const fromX = node.x, fromY = node.y;\n this.doMoveNode(id, x, y);\n if (fromX !== x || fromY !== y) {\n this.record({\n do: () => { this.doMoveNode(id, x, y); },\n undo: () => { this.doMoveNode(id, fromX, fromY); },\n label: 'move node',\n });\n }\n }\n nudgeSelection(dx: number, dy: number): boolean {\n if (!Number.isFinite(dx) || !Number.isFinite(dy)) throw new RangeError('ssdiagram: nudge delta must be finite');\n if ((dx === 0 && dy === 0) || this.selectedNodes.size === 0) return false;\n const moves = [...this.selectedNodes].map((node) => ({\n id: node.id,\n fromX: node.x,\n fromY: node.y,\n toX: node.x + dx,\n toY: node.y + dy,\n }));\n for (const move of moves) this.doMoveNode(move.id, move.toX, move.toY);\n this.record({\n do: () => { for (const move of moves) this.doMoveNode(move.id, move.toX, move.toY); },\n undo: () => { for (const move of moves) this.doMoveNode(move.id, move.fromX, move.fromY); },\n label: 'nudge',\n });\n return true;\n }\n private doMoveNode(id: string, x: number, y: number): void {\n const node = this.nodes.find((n) => n.id === id);\n if (node === undefined) return;\n node.x = x; node.y = y;\n this.layoutNode(node);\n this.emit('nodeMoved', { node });\n this.scheduleDraw();\n }\n addLink(init: LinkInit): boolean {\n const fullInit: LinkInit = {\n ...init,\n id: init.id ?? this.nextLinkId(),\n metadata: copyJsonObject(init.metadata),\n };\n if (fullInit.id !== undefined && this.links.some((link) => link.id === fullInit.id)) return false;\n const fromNode = this.nodes.find((node) => node.id === fullInit.from);\n const toNode = this.nodes.find((node) => node.id === fullInit.to);\n const fromPort = fromNode?.outPorts.find((port) => port.id === fullInit.fromPort);\n const toPort = toNode?.inPorts.find((port) => port.id === fullInit.toPort);\n if (fromNode !== undefined && toNode !== undefined && fromPort !== undefined && toPort !== undefined\n && toPort.isDynamic && toPort.dynamicMode === 'onConnect' && !toPort.isSibling) {\n const validation = this.validateLinkModels(fromNode, fromPort, toNode, toPort);\n this.emit('linkValidation', { fromNode, from: fromPort, toNode, to: toPort, ...validation });\n if (!validation.allowed) return false;\n const sibling = this.createDynamicSibling(toNode, toPort, fromPort);\n let added = false;\n const failed = new Error('ssdiagram: dynamic link transaction failed');\n try {\n this.withTransaction('add dynamic link', () => {\n if (!this.addPort(toNode.id, 'in', sibling)) throw failed;\n added = this.addLinkApplied({ ...fullInit, toPort: sibling.id }, false);\n if (!added) throw failed;\n });\n } catch (error) {\n if (error === failed) return false;\n throw error;\n }\n return added;\n }\n return this.addLinkApplied(fullInit, true);\n }\n private addLinkApplied(init: LinkInit, validate: boolean): boolean {\n const ok = this.doAddLink(init, validate);\n if (ok) {\n this.record({\n do: () => { this.doAddLink(init, false); },\n undo: () => { this.doRemoveLink(init); },\n label: 'add link',\n });\n }\n return ok;\n }\n private doAddLink(init: LinkInit, validate = true, index = this.links.length): boolean {\n const fn = this.nodes.find((n) => n.id === init.from);\n const tn = this.nodes.find((n) => n.id === init.to);\n if (fn === undefined || tn === undefined) return false;\n const fp = fn.outPorts.find((p) => p.id === init.fromPort);\n const tp = tn.inPorts.find((p) => p.id === init.toPort);\n if (fp === undefined || tp === undefined) return false;\n if (validate) {\n const validation = this.validateLinkModels(fn, fp, tn, tp);\n this.emit('linkValidation', { fromNode: fn, from: fp, toNode: tn, to: tp, ...validation });\n if (!validation.allowed) return false;\n }\n const link = new LinkModel(init.from, init.fromPort, init.to, init.toPort, init.id ?? this.nextLinkId(), init.metadata, init.style ?? 'solid');\n if (this.links.some((l) => l.id === link.id)) return false;\n this.links.splice(clamp(Math.trunc(index), 0, this.links.length), 0, link);\n this.emit('linkAdded', { link });\n this.scheduleDraw();\n return true;\n }\n removeLink(link: { id?: string; from: string; fromPort: string; to: string; toPort: string }): void {\n this.removeLinkInternal(link, true);\n }\n private removeLinkInternal(\n link: { id?: string; from: string; fromPort: string; to: string; toPort: string },\n pruneDynamicSibling: boolean,\n ): void {\n const key = new LinkModel(link.from, link.fromPort, link.to, link.toPort).key();\n const found = link.id === undefined || link.id.length === 0\n ? this.links.find((candidate) => candidate.key() === key)\n : this.links.find((candidate) => candidate.id === link.id);\n if (found === undefined) return;\n const init = found.toInit();\n const index = this.links.indexOf(found);\n const targetPort = this.findNode(found.to)?.inPorts.find((port) => port.id === found.toPort);\n const remove = (): void => {\n this.doRemoveLink(init);\n this.record({\n do: () => { this.doRemoveLink(init); },\n undo: () => { this.doAddLink(init, false, index); },\n label: 'remove link',\n });\n };\n if (pruneDynamicSibling && targetPort?.isSibling === true) {\n this.withTransaction('remove dynamic link', () => {\n remove();\n this.pruneDynamicSibling(init.to, init.toPort);\n });\n } else {\n remove();\n }\n }\n private doRemoveLink(link: { from: string; fromPort: string; to: string; toPort: string }): void {\n const k = new LinkModel(link.from, link.fromPort, link.to, link.toPort).key();\n const found = this.links.find((l) => l.key() === k);\n if (found === undefined) return;\n this.links = this.links.filter((l) => l !== found);\n if (this.selectedLink === found) this.selectLink(null);\n this.emit('linkRemoved', { link: found });\n this.scheduleDraw();\n }\n private createDynamicSibling(toNode: NodeModel, anchor: PortModel, source: PortModel): PortInit {\n let sequence = 1;\n while (toNode.inPorts.some((port) => port.id === `${anchor.id}_${sequence}`)) sequence += 1;\n return {\n id: `${anchor.id}_${sequence}`,\n name: `${anchor.name} ${sequence}`,\n description: anchor.description,\n type: source.type || anchor.type,\n maxLinks: 1,\n availableTypes: [...anchor.availableTypes],\n isDynamic: false,\n dynamicMode: '',\n isSibling: true,\n metadata: copyJsonObject(anchor.metadata),\n };\n }\n private pruneDynamicSibling(nodeId: string, portId: string): void {\n const node = this.findNode(nodeId);\n const port = node?.inPorts.find((candidate) => candidate.id === portId);\n if (port?.isSibling !== true) return;\n if (this.links.some((link) => link.to === nodeId && link.toPort === portId)) return;\n this.removePort(nodeId, 'in', portId);\n }\n // ---- undo / redo public surface ---------------------------------\n canUndo(): boolean { return this.permissions.history && this.history.state.canUndo; }\n canRedo(): boolean { return this.permissions.history && this.history.state.canRedo; }\n undo(): void { if (this.permissions.history) this.history.undo(); }\n redo(): void { if (this.permissions.history) this.history.redo(); }\n cutSelection(): void {\n if (!this.permissions.copy || !this.permissions.deleteSelection) return;\n // The copy/delete pair is observable as ONE undo step.\n this.copySelection();\n this.withTransaction('cut', () => { this.deleteSelection(); });\n }\n // Group multiple mutations into one undo step (paste of N nodes,\n // bulk delete, multi-drag, etc.). Re-entrant: nested calls flatten\n // into the outer batch.\n withTransaction<T>(label: string, fn: () => T): T {\n return this.history.transaction(label, fn);\n }\n private record(action: AppliedAction): void {\n this.history.recordApplied({\n label: action.label,\n execute: action.do,\n undo: action.undo,\n });\n }\n deleteSelection(): void {\n if (!this.permissions.deleteSelection) return;\n if (this.selectedNodes.size > 0) {\n this.withTransaction('delete selection', () => {\n for (const id of [...this.selectedNodes].map((n) => n.id)) this.removeDiagramNode(id);\n });\n this.selectedNodes.clear();\n this.selectedNode = null;\n return;\n }\n if (this.selectedLink !== null) { this.removeLink(this.selectedLink); }\n }\n clear(): void {\n this.nodes = []; this.links = [];\n // Zones belong to the document like everything else here. Leaving them behind meant a\n // discarded strategy kept drawing its zones over the next one and, worse, saveDocument()\n // wrote them into that unrelated strategy's file.\n this.zones = [];\n // Every other path that empties the selection announces it. Staying silent here left a\n // host's property panel showing a node from the document that had just been thrown away.\n const hadSelection = this.selectedNode !== null || this.selectedNodes.size > 0\n || this.selectedLink !== null || this.selectedPort !== null;\n this.selectedNode = null; this.selectedNodes.clear(); this.selectedLink = null; this.selectedPort = null;\n this.documentMetadata = {};\n this.runtimeState = createDiagramRuntimeState();\n this.runtimePulse = 0;\n this.globalErrorFlashStart = null;\n this.history.clear();\n if (hadSelection) this.emitSelectionChanged();\n this.emitRuntimeStateChanged();\n }\n relink(\n linkId: string,\n next: Pick<LinkInit, 'from' | 'fromPort' | 'to' | 'toPort'>,\n ): LinkValidationResult {\n const link = this.links.find((candidate) => candidate.id === linkId);\n if (link === undefined) return { allowed: false, reason: 'missing-link' };\n\n const validation = this.validateLink(next, linkId);\n const fromNode = this.nodes.find((node) => node.id === next.from);\n const toNode = this.nodes.find((node) => node.id === next.to);\n const fromPort = fromNode?.outPorts.find((port) => port.id === next.fromPort);\n const toPort = toNode?.inPorts.find((port) => port.id === next.toPort);\n if (fromNode !== undefined && toNode !== undefined && fromPort !== undefined && toPort !== undefined) {\n this.emit('linkValidation', { fromNode, from: fromPort, toNode, to: toPort, ...validation });\n }\n if (!validation.allowed) return validation;\n\n const before = link.toInit();\n if (before.from === next.from && before.fromPort === next.fromPort\n && before.to === next.to && before.toPort === next.toPort) return validation;\n const dynamicSibling = fromPort !== undefined && toNode !== undefined && toPort !== undefined\n && toPort.isDynamic && toPort.dynamicMode === 'onConnect' && !toPort.isSibling\n ? this.createDynamicSibling(toNode, toPort, fromPort)\n : null;\n const after: LinkInit & { id: string } = {\n ...before,\n ...next,\n toPort: dynamicSibling?.id ?? next.toPort,\n };\n const oldTargetPort = this.findNode(before.to)?.inPorts.find((port) => port.id === before.toPort);\n const apply = (): void => {\n this.doRelink(linkId, after);\n this.record({\n do: () => { this.doRelink(linkId, after); },\n undo: () => { this.doRelink(linkId, before); },\n label: 'relink',\n });\n };\n const pruneOldSibling = oldTargetPort?.isSibling === true\n && (before.to !== after.to || before.toPort !== after.toPort);\n if (dynamicSibling !== null || pruneOldSibling) {\n this.withTransaction('relink dynamic link', () => {\n if (dynamicSibling !== null && !this.addPort(after.to, 'in', dynamicSibling)) {\n throw new Error('ssdiagram: could not create a dynamic sibling port');\n }\n apply();\n if (pruneOldSibling) this.pruneDynamicSibling(before.to, before.toPort);\n });\n } else {\n apply();\n }\n return validation;\n }\n private doRelink(linkId: string, next: LinkInit & { id: string }): void {\n const link = this.links.find((candidate) => candidate.id === linkId);\n if (link === undefined) return;\n const previous = link.toInit();\n link.from = next.from;\n link.fromPort = next.fromPort;\n link.to = next.to;\n link.toPort = next.toPort;\n this.emit('linkRelinked', { link, previous });\n this.scheduleDraw();\n }\n\n addPort(nodeId: string, direction: PortDirection, init: PortInit): boolean {\n const node = this.findNode(nodeId);\n if (node === undefined) return false;\n const ports = direction === 'in' ? node.inPorts : node.outPorts;\n if (ports.some((port) => port.id === init.id)) return false;\n return this.updateNodeState(nodeId, 'add port', (target) => {\n const list = direction === 'in' ? target.inPorts : target.outPorts;\n list.push(new PortModel(init, direction));\n });\n }\n\n removePort(nodeId: string, direction: PortDirection, portId: string): boolean {\n const node = this.findNode(nodeId);\n if (node === undefined) return false;\n const ports = direction === 'in' ? node.inPorts : node.outPorts;\n if (!ports.some((port) => port.id === portId)) return false;\n let changed = false;\n this.withTransaction('remove port', () => {\n const affected = this.links.filter((link) => direction === 'in'\n ? link.to === nodeId && link.toPort === portId\n : link.from === nodeId && link.fromPort === portId);\n for (const link of affected) this.removeLinkInternal(link, false);\n changed = this.updateNodeState(nodeId, 'remove port', (target) => {\n if (direction === 'in') target.inPorts = target.inPorts.filter((port) => port.id !== portId);\n else target.outPorts = target.outPorts.filter((port) => port.id !== portId);\n });\n });\n return changed;\n }\n\n updatePortType(nodeId: string, direction: PortDirection, portId: string, type: string): boolean {\n return this.updatePort(nodeId, direction, portId, { type });\n }\n\n updatePort(nodeId: string, direction: PortDirection, portId: string, patch: PortUpdate): boolean {\n const node = this.findNode(nodeId);\n const port = direction === 'in'\n ? node?.inPorts.find((candidate) => candidate.id === portId)\n : node?.outPorts.find((candidate) => candidate.id === portId);\n if (port === undefined) return false;\n if (patch.maxLinks !== undefined && (!Number.isInteger(patch.maxLinks) || patch.maxLinks < 0)) {\n throw new RangeError('ssdiagram: port maxLinks must be a non-negative integer');\n }\n const compatibilityChanged = (patch.type !== undefined && patch.type !== port.type)\n || (patch.availableTypes !== undefined\n && JSON.stringify(patch.availableTypes) !== JSON.stringify(port.availableTypes));\n let changed = false;\n this.withTransaction('update port', () => {\n changed = this.updateNodeState(nodeId, 'update port', (target) => {\n const targetPort = direction === 'in'\n ? target.inPorts.find((candidate) => candidate.id === portId)\n : target.outPorts.find((candidate) => candidate.id === portId);\n if (targetPort === undefined) return;\n if (patch.name !== undefined) targetPort.name = patch.name;\n if (patch.description !== undefined) targetPort.description = patch.description;\n if (patch.type !== undefined) targetPort.type = patch.type;\n if (patch.maxLinks !== undefined) targetPort.maxLinks = patch.maxLinks;\n if (patch.availableTypes !== undefined) targetPort.availableTypes = [...patch.availableTypes];\n if (patch.isDynamic !== undefined) targetPort.isDynamic = patch.isDynamic;\n if (patch.dynamicMode !== undefined) targetPort.dynamicMode = patch.dynamicMode;\n if (patch.isSibling !== undefined) targetPort.isSibling = patch.isSibling;\n if (patch.metadata !== undefined) targetPort.metadata = copyJsonObject(patch.metadata);\n });\n if (changed && compatibilityChanged) {\n this.removeIncompatibleLinks((link) => direction === 'in'\n ? link.to === nodeId && link.toPort === portId\n : link.from === nodeId && link.fromPort === portId);\n }\n });\n return changed;\n }\n\n setNodePorts(nodeId: string, inPorts: readonly PortInit[], outPorts: readonly PortInit[]): boolean {\n const node = this.findNode(nodeId);\n if (node === undefined) return false;\n const inputIds = new Set(inPorts.map((port) => port.id));\n const outputIds = new Set(outPorts.map((port) => port.id));\n let changed = false;\n this.withTransaction('set node ports', () => {\n const invalid = this.links.filter((link) =>\n (link.to === nodeId && !inputIds.has(link.toPort))\n || (link.from === nodeId && !outputIds.has(link.fromPort)));\n for (const link of invalid) this.removeLinkInternal(link, false);\n changed = this.updateNodeState(nodeId, 'set node ports', (target) => {\n target.inPorts = inPorts.map((port) => new PortModel(port, 'in'));\n target.outPorts = outPorts.map((port) => new PortModel(port, 'out'));\n });\n if (changed) {\n this.removeIncompatibleLinks((link) => link.from === nodeId || link.to === nodeId);\n }\n });\n return changed;\n }\n\n updateNode(\n nodeId: string,\n patch: Partial<Pick<DiagramNodeInit, 'name' | 'description' | 'color' | 'border' | 'message' | 'openAction'>>,\n ): boolean {\n return this.updateNodeState(nodeId, 'update node', (node) => {\n if (patch.name !== undefined) node.name = patch.name;\n if (patch.description !== undefined) node.description = patch.description;\n if (patch.color !== undefined) node.color = patch.color;\n if (patch.border !== undefined) node.border = patch.border;\n if (patch.message !== undefined) node.message = patch.message;\n if (patch.openAction !== undefined) node.openAction = patch.openAction;\n });\n }\n\n setNodeParamValue(nodeId: string, name: string, value: string | undefined): boolean {\n return this.updateNodeState(nodeId, 'set node parameter', (node) => {\n if (value === undefined) delete node.paramValues[name];\n else setJsonKey(node.paramValues, name, value);\n });\n }\n\n setShowNodeMessages(show: boolean): void {\n this.showNodeMessages = show;\n this.scheduleDraw();\n }\n\n private updateNodeState(nodeId: string, label: string, mutate: (node: NodeModel) => void): boolean {\n const node = this.findNode(nodeId);\n if (node === undefined) return false;\n const before = node.toInit(false);\n mutate(node);\n if (this.reconcileSelectedPort(node)) this.emitSelectionChanged();\n const after = node.toInit(false);\n if (JSON.stringify(before) === JSON.stringify(after)) return false;\n this.layoutNode(node);\n this.emit('nodeChanged', { node });\n this.scheduleDraw();\n this.record({\n do: () => { this.applyNodeSnapshot(nodeId, after); },\n undo: () => { this.applyNodeSnapshot(nodeId, before); },\n label,\n });\n return true;\n }\n\n private applyNodeSnapshot(nodeId: string, snapshot: DiagramNodeInit): void {\n const node = this.findNode(nodeId);\n if (node === undefined) return;\n const restored = new NodeModel(snapshot, nodeId);\n node.typeId = restored.typeId;\n node.name = restored.name;\n node.description = restored.description;\n node.groupName = restored.groupName;\n node.color = restored.color;\n node.border = restored.border;\n node.icon = restored.icon;\n node.openAction = restored.openAction;\n node.message = restored.message;\n node.parameters = restored.parameters;\n node.paramValues = restored.paramValues;\n node.metadata = restored.metadata;\n node.isPlaceholder = restored.isPlaceholder;\n node.x = restored.x;\n node.y = restored.y;\n node.inPorts = restored.inPorts;\n node.outPorts = restored.outPorts;\n if (this.reconcileSelectedPort(node)) this.emitSelectionChanged();\n this.layoutNode(node);\n this.emit('nodeChanged', { node });\n this.scheduleDraw();\n }\n\n private reconcileSelectedPort(node: NodeModel): boolean {\n if (this.selectedPort?.node !== node) return false;\n const selected = this.selectedPort.port;\n const ports = selected.direction === 'in' ? node.inPorts : node.outPorts;\n const replacement = ports.find((port) => port.id === selected.id);\n if (replacement === selected) return false;\n this.selectedPort = replacement === undefined ? null : { node, port: replacement };\n return true;\n }\n load(nodes: DiagramNodeInit[], links: LinkInit[]): void {\n this.clear();\n this.idSeq = 1;\n this.linkSeq = 1;\n // Initial load is \"model seed\" \u2014 should NOT be undoable, and\n // shouldn't leave the user with 12 entries to Ctrl+Z through\n // before their stack reaches their first real action.\n // Validate before applying anything. doAddNode returns silently on a duplicate id, so a\n // second node with the same id simply vanished and every wire meant for it attached to the\n // first -- a quietly miswired strategy. The link check used to sit mid-loop, which threw\n // with the diagram already half loaded and no loadFinished.\n const seenNodeIds = new Set<string>();\n for (const node of nodes) {\n const id = node.id ?? '';\n if (id === '') continue;\n if (seenNodeIds.has(id)) throw new Error(`ssdiagram: duplicate node id \"${id}\"`);\n seenNodeIds.add(id);\n }\n const seenLinkIds = new Set<string>();\n for (const link of links) {\n const id = link.id ?? '';\n if (id === '') continue;\n if (seenLinkIds.has(id)) throw new Error(`ssdiagram: duplicate link id \"${id}\"`);\n seenLinkIds.add(id);\n }\n\n for (const node of nodes) {\n const id = node.id ?? this.nextNodeId();\n this.doAddNode({ ...node, id });\n }\n for (const link of links) {\n const id = link.id ?? this.nextLinkId();\n if (this.links.some((existing) => existing.id === id)) {\n throw new Error(`ssdiagram: duplicate link id \"${id}\"`);\n }\n const model = new LinkModel(link.from, link.fromPort, link.to, link.toPort, id, link.metadata, link.style ?? 'solid');\n if (!this.links.some((existing) => existing.key() === model.key())) this.links.push(model);\n }\n for (const node of this.nodes) {\n if (node.loadError.length === 0) continue;\n const state = createDiagramNodeRuntimeState();\n state.errors.load = { kind: 'load', message: node.loadError, pulse: ++this.runtimePulse };\n setJsonKey(this.runtimeState.nodes as unknown as JsonObject, node.id, state as unknown as JsonValue);\n }\n if (Object.keys(this.runtimeState.nodes).length > 0) this.emitRuntimeStateChanged();\n this.history.clear();\n this.emit('loadFinished', { nodes: this.nodes.slice(), links: this.links.slice() });\n this.zoomToFit();\n this.playIntro();\n }\n save(): DiagramSnapshot {\n return {\n nodes: this.nodes.map((node) => node.toInit(false) as DiagramNodeSnapshot),\n links: this.links.map((l) => ({\n id: l.id,\n from: l.from,\n fromPort: l.fromPort,\n to: l.to,\n toPort: l.toPort,\n style: l.style,\n metadata: copyJsonObject(l.metadata),\n })),\n };\n }\n\n loadDocument(source: DiagramDocument | string): void {\n const document = parseDiagramDocument(source);\n this.load(\n document.nodes,\n document.links.map((link) => ({\n id: link.id,\n from: link.from.nodeId,\n fromPort: link.from.portId,\n to: link.to.nodeId,\n toPort: link.to.portId,\n style: link.style,\n metadata: link.metadata,\n })),\n );\n this.zones = document.zones.map((zone) => ({ ...zone, metadata: copyJsonObject(zone.metadata) }));\n this.documentMetadata = copyJsonObject(document.metadata);\n }\n\n saveDocument(): DiagramDocument {\n return createDiagramDocument({\n nodes: this.nodes.map((node) => node.toInit(false)),\n links: this.links.map((link) => ({\n id: link.id,\n from: { nodeId: link.from, portId: link.fromPort },\n to: { nodeId: link.to, portId: link.toPort },\n style: link.style,\n metadata: link.metadata,\n })),\n zones: this.zones.map((zone) => ({ ...zone, metadata: copyJsonObject(zone.metadata) })),\n metadata: this.documentMetadata,\n });\n }\n selectedNodeId(): string | null { return this.selectedNode?.id ?? null; }\n getSelection(): DiagramSelection {\n return {\n nodeIds: [...this.selectedNodes].map((node) => node.id),\n linkIds: this.selectedLink === null ? [] : [this.selectedLink.id],\n port: this.selectedPort === null ? null : {\n nodeId: this.selectedPort.node.id,\n portId: this.selectedPort.port.id,\n direction: this.selectedPort.port.direction,\n },\n primaryNodeId: this.selectedNode?.id ?? null,\n primaryLinkId: this.selectedLink?.id ?? null,\n };\n }\n selectNodesById(ids: readonly string[]): void {\n const wanted = new Set(ids);\n this.setSelection(this.nodes.filter((node) => wanted.has(node.id)));\n }\n selectLinkById(id: string | null): void {\n this.selectLink(id === null ? null : (this.links.find((link) => link.id === id) ?? null));\n }\n selectPortById(nodeId: string, direction: PortDirection, portId: string): void {\n const node = this.findNode(nodeId);\n const port = direction === 'in'\n ? node?.inPorts.find((candidate) => candidate.id === portId)\n : node?.outPorts.find((candidate) => candidate.id === portId);\n if (node !== undefined && port !== undefined) this.selectPort({ node, port });\n }\n getViewState(): DiagramViewState {\n return {\n zoom: this.scale,\n panX: this.offX,\n panY: this.offY,\n overviewVisible: this.overviewVisible,\n };\n }\n /**\n * Replaces what Ctrl+Z / Ctrl+Y do. Passing null restores the built-in behaviour, which is\n * plain undo()/redo() -- so a renderer used on its own keeps its keyboard history.\n */\n setHistoryShortcutHandler(handler: ((direction: 'undo' | 'redo') => void) | null): void {\n this.historyShortcut = handler ?? ((direction) => { if (direction === 'undo') this.undo(); else this.redo(); });\n }\n\n setViewState(state: DiagramViewState): void {\n if (!Number.isFinite(state.zoom) || !Number.isFinite(state.panX) || !Number.isFinite(state.panY)) {\n throw new RangeError('ssdiagram: view state zoom and pan must be finite numbers');\n }\n this.scale = clamp(state.zoom, ZOOM_MIN, ZOOM_MAX);\n this.offX = state.panX;\n this.offY = state.panY;\n this.overviewVisible = state.overviewVisible;\n this.emitViewChanged(true);\n this.scheduleDraw();\n }\n // Renderer operations consumed by the high-level component.\n findNode(id: string): NodeModel | undefined { return this.nodes.find((n) => n.id === id); }\n requestRedraw(): void { this.relayout(); this.scheduleDraw(); }\n /**\n * Creates a detached canvas. With no options it is an exact copy of the\n * current frame, matching Charts.takeScreenshot(). Content scope renders\n * the whole graph without changing the visible viewport.\n */\n takeScreenshot(options: DiagramScreenshotOptions = {}): HTMLCanvasElement {\n if (this.destroyed) throw new Error('ssdiagram: cannot export a destroyed diagram');\n const scope = options.scope ?? 'viewport';\n if (scope !== 'viewport' && scope !== 'content') {\n throw new RangeError(`ssdiagram: unsupported screenshot scope \"${String(scope)}\"`);\n }\n\n if (scope === 'viewport' && Object.keys(options).length === 0) {\n // Mutations only schedule a repaint, so the bitmap on screen is still the previous\n // frame until it lands. Copying it as-is handed back a picture of the state before the\n // edit -- or a blank one right after construction -- while the very same call with any\n // option took the redraw path and came out current.\n if (this.drawScheduled) this.draw();\n const copy = document.createElement('canvas');\n copy.width = this.canvas.width;\n copy.height = this.canvas.height;\n const copyContext = copy.getContext('2d');\n if (copyContext === null) throw new Error('ssdiagram: screenshot 2d context unavailable');\n copyContext.drawImage(this.canvas, 0, 0);\n return copy;\n }\n\n const layout = this.exportLayout(scope, options);\n const { pixelRatio, exportScale, padding, bounds, width, height, pixelWidth, pixelHeight } = layout;\n\n const output = document.createElement('canvas');\n output.width = pixelWidth;\n output.height = pixelHeight;\n output.style.width = `${width}px`;\n output.style.height = `${height}px`;\n const outputContext = output.getContext('2d');\n if (outputContext === null) throw new Error('ssdiagram: screenshot 2d context unavailable');\n\n const previous = {\n ctx: this.ctx,\n width: this.width,\n height: this.height,\n dpr: this.dpr,\n scale: this.scale,\n offX: this.offX,\n offY: this.offY,\n overviewVisible: this.overviewVisible,\n background: this.opts.background,\n // Drawing the overview recomputes this from the export frame. Left behind, the next\n // click on the on-screen minimap panned to a point in the export's coordinates.\n ovGeo: this.ovGeo,\n };\n try {\n this.ctx = outputContext;\n this.width = width;\n this.height = height;\n this.dpr = pixelRatio;\n this.scale = exportScale;\n this.offX = scope === 'content' && bounds !== null ? padding - bounds.minX * exportScale : previous.offX;\n this.offY = scope === 'content' && bounds !== null ? padding - bounds.minY * exportScale : previous.offY;\n this.overviewVisible = options.includeOverview ?? (scope === 'viewport' && previous.overviewVisible);\n if (options.background !== undefined) this.opts.background = options.background;\n outputContext.setTransform(pixelRatio, 0, 0, pixelRatio, 0, 0);\n this.draw({\n grid: options.includeGrid ?? true,\n overview: this.overviewVisible,\n selection: options.includeSelection ?? scope === 'viewport',\n runtime: options.includeRuntimeState ?? true,\n transient: false,\n });\n } finally {\n this.ctx = previous.ctx;\n this.width = previous.width;\n this.height = previous.height;\n this.dpr = previous.dpr;\n this.scale = previous.scale;\n this.offX = previous.offX;\n this.offY = previous.offY;\n this.overviewVisible = previous.overviewVisible;\n this.opts.background = previous.background;\n this.ovGeo = previous.ovGeo;\n }\n return output;\n }\n\n // Everything an export needs to know about size and placement, for either output. Shared on\n // purpose: a raster and a vector export of the same scope must frame the picture identically,\n // and two copies of this arithmetic would eventually disagree about padding or where the origin\n // sits. A block comment here would be lifted onto the next public member in the .d.ts.\n private exportLayout(scope: DiagramScreenshotScope, options: DiagramScreenshotOptions) {\n const pixelRatio = this.positiveScreenshotNumber(options.pixelRatio ?? this.dpr, 'pixelRatio');\n const exportScale = scope === 'content'\n ? this.positiveScreenshotNumber(options.scale ?? 1, 'scale')\n : this.scale;\n const padding = scope === 'content'\n ? this.nonNegativeScreenshotNumber(options.padding ?? 32, 'padding')\n : 0;\n const bounds = scope === 'content' ? this.graphBounds() : null;\n const width = scope === 'content'\n ? Math.max(1, Math.ceil(((bounds?.maxX ?? 1) - (bounds?.minX ?? 0)) * exportScale + padding * 2))\n : this.width;\n const height = scope === 'content'\n ? Math.max(1, Math.ceil(((bounds?.maxY ?? 1) - (bounds?.minY ?? 0)) * exportScale + padding * 2))\n : this.height;\n const pixelWidth = Math.ceil(width * pixelRatio);\n const pixelHeight = Math.ceil(height * pixelRatio);\n\n if (pixelWidth > 16384 || pixelHeight > 16384 || pixelWidth * pixelHeight > 268_435_456) {\n throw new RangeError(`ssdiagram: screenshot is too large (${pixelWidth}x${pixelHeight})`);\n }\n\n return { pixelRatio, exportScale, padding, bounds, width, height, pixelWidth, pixelHeight };\n }\n\n /**\n * The same picture takeScreenshot produces, as SVG.\n *\n * It is the renderer that draws it -- the surface underneath simply records instead of paints --\n * so the vector output cannot drift from what the screen and the raster export show. Text keeps\n * the on-screen metrics by measuring through a real 2D context.\n *\n * Scale and pixelRatio still frame the picture (they decide the viewBox), but nothing is\n * resampled: the result is resolution-independent, which is the point of asking for it.\n */\n takeSvg(options: DiagramScreenshotOptions = {}): string {\n if (this.destroyed) throw new Error('ssdiagram: cannot export a destroyed diagram');\n\n const scope = options.scope ?? 'viewport';\n if (scope !== 'viewport' && scope !== 'content') {\n throw new RangeError(`ssdiagram: unsupported screenshot scope \"${String(scope)}\"`);\n }\n\n const { exportScale, padding, bounds, width, height } = this.exportLayout(scope, options);\n\n const metrics = this.canvas.getContext('2d');\n const surface = new SvgSurface({\n width,\n height,\n background: options.background ?? this.opts.background ?? '#1b1b1f',\n metrics: metrics ?? undefined,\n });\n\n const previous = {\n ctx: this.ctx,\n width: this.width,\n height: this.height,\n dpr: this.dpr,\n scale: this.scale,\n offX: this.offX,\n offY: this.offY,\n overviewVisible: this.overviewVisible,\n background: this.opts.background,\n // Drawing the overview recomputes this from the export frame. Left behind, the next\n // click on the on-screen minimap panned to a point in the export's coordinates.\n ovGeo: this.ovGeo,\n };\n\n try {\n this.ctx = surface;\n // draw() fills the frame with the theme background unconditionally, straight over the\n // backdrop the surface was given -- so passing the override to SvgSurface alone left it\n // invisible and the SVG disagreed with the PNG of the same options. takeScreenshot\n // swaps the theme value for the duration of the export; this does the same.\n if (options.background !== undefined) this.opts.background = options.background;\n this.width = width;\n this.height = height;\n // 1: an SVG has no device pixels to multiply by, and the viewBox carries the size.\n this.dpr = 1;\n this.scale = exportScale;\n this.offX = scope === 'content' && bounds !== null ? padding - bounds.minX * exportScale : previous.offX;\n this.offY = scope === 'content' && bounds !== null ? padding - bounds.minY * exportScale : previous.offY;\n this.overviewVisible = options.includeOverview ?? (scope === 'viewport' && previous.overviewVisible);\n\n this.draw({\n grid: options.includeGrid ?? true,\n overview: this.overviewVisible,\n selection: options.includeSelection ?? scope === 'viewport',\n runtime: options.includeRuntimeState ?? true,\n transient: false,\n });\n } finally {\n this.ctx = previous.ctx;\n this.width = previous.width;\n this.height = previous.height;\n this.dpr = previous.dpr;\n this.scale = previous.scale;\n this.offX = previous.offX;\n this.offY = previous.offY;\n this.overviewVisible = previous.overviewVisible;\n this.opts.background = previous.background;\n this.ovGeo = previous.ovGeo;\n }\n\n return surface.toSvg();\n }\n\n private positiveScreenshotNumber(value: number, name: string): number {\n if (!Number.isFinite(value) || value <= 0) {\n throw new RangeError(`ssdiagram: screenshot ${name} must be a positive finite number`);\n }\n return value;\n }\n\n private nonNegativeScreenshotNumber(value: number, name: string): number {\n if (!Number.isFinite(value) || value < 0) {\n throw new RangeError(`ssdiagram: screenshot ${name} must be a non-negative finite number`);\n }\n return value;\n }\n getRuntimeState(): DiagramRuntimeState {\n return cloneDiagramRuntimeState(this.runtimeState);\n }\n setRuntimeState(state: DiagramRuntimeState): void {\n const previous = this.runtimeState;\n this.runtimeState = cloneDiagramRuntimeState(state);\n if (this.runtimeState.globalError === null) {\n this.globalErrorFlashStart = null;\n } else if (previous.globalError?.pulse !== this.runtimeState.globalError.pulse) {\n this.globalErrorFlashStart = performance.now();\n }\n this.runtimePulse = Math.max(\n this.runtimePulse,\n this.runtimeState.globalError?.pulse ?? 0,\n ...Object.values(this.runtimeState.nodes)\n .flatMap((node) => [node.errors.runtime?.pulse ?? 0, node.errors.load?.pulse ?? 0]),\n );\n for (const node of this.nodes) {\n const errors = getJsonKey(this.runtimeState.nodes, node.id)?.errors;\n const previousRuntime = getJsonKey(previous.nodes, node.id)?.errors.runtime;\n const runtimeError = errors?.runtime;\n node.runtimeError = runtimeError?.message ?? '';\n node.loadError = errors?.load?.message ?? '';\n if (runtimeError !== undefined) {\n if (previousRuntime === undefined || previousRuntime.pulse !== runtimeError.pulse) {\n node.errorFlashStart = performance.now();\n }\n } else {\n node.errorFlashStart = null;\n }\n }\n this.emitRuntimeStateChanged();\n }\n clearRuntimeState(): void {\n this.setRuntimeState(createDiagramRuntimeState());\n }\n setActiveNode(nodeId: string | null): boolean {\n if (nodeId !== null && this.findNode(nodeId) === undefined) return false;\n const state = this.getRuntimeState();\n state.activeNodeId = nodeId;\n this.setRuntimeState(state);\n return true;\n }\n setPortRuntimeState(\n nodeId: string,\n direction: PortDirection,\n portId: string,\n patch: Partial<DiagramPortRuntimeState>,\n ): boolean {\n const node = this.findNode(nodeId);\n const port = direction === 'in'\n ? node?.inPorts.find((candidate) => candidate.id === portId)\n : node?.outPorts.find((candidate) => candidate.id === portId);\n if (node === undefined || port === undefined) return false;\n const state = this.getRuntimeState();\n // Node ids come from documents, so \"__proto__\" is reachable: a bare assignment there\n // writes the prototype instead of creating an entry, and the next read of it throws.\n const nodeState = getJsonKey(state.nodes, nodeId) ?? createDiagramNodeRuntimeState();\n setJsonKey(state.nodes as unknown as JsonObject, nodeId, nodeState as unknown as JsonValue);\n const current = nodeState.ports[direction][portId] ?? createDiagramPortRuntimeState();\n nodeState.ports[direction][portId] = { ...current, ...patch };\n this.setRuntimeState(state);\n return true;\n }\n setGlobalError(message: string | null, kind: DiagramGlobalErrorKind = 'invalid'): void {\n const state = this.getRuntimeState();\n state.globalError = message === null || message.length === 0\n ? null\n : { kind, message, pulse: ++this.runtimePulse };\n this.setRuntimeState(state);\n }\n setNodeError(id: string, message: string, options: NodeErrorOptions = {}): boolean {\n const node = this.findNode(id);\n if (node === undefined) return false;\n const kind = options.kind ?? 'runtime';\n if (kind === 'load') {\n node.loadError = message;\n } else {\n node.runtimeError = message;\n node.errorFlashStart = message.length > 0 && options.animate !== false\n ? performance.now()\n : null;\n }\n const state = this.getRuntimeState();\n const nodeState = getJsonKey(state.nodes, id) ?? createDiagramNodeRuntimeState();\n setJsonKey(state.nodes as unknown as JsonObject, id, nodeState as unknown as JsonValue);\n // Only this kind's slot is written, so an error of the other kind that is\n // already on the node survives.\n if (message.length === 0) delete nodeState.errors[kind];\n else if (kind === 'load') nodeState.errors.load = { kind, message, pulse: ++this.runtimePulse };\n else nodeState.errors.runtime = { kind, message, pulse: ++this.runtimePulse };\n this.runtimeState = state;\n this.emitRuntimeStateChanged();\n return true;\n }\n clearNodeError(id: string, kind?: NodeErrorKind): boolean {\n const node = this.findNode(id);\n if (node === undefined) return false;\n if (kind === undefined || kind === 'runtime') {\n node.runtimeError = '';\n node.errorFlashStart = null;\n }\n if (kind === undefined || kind === 'load') node.loadError = '';\n const state = this.getRuntimeState();\n const nodeState = getJsonKey(state.nodes, id);\n if (nodeState !== undefined) {\n if (kind === undefined || kind === 'runtime') delete nodeState.errors.runtime;\n if (kind === undefined || kind === 'load') delete nodeState.errors.load;\n }\n this.runtimeState = state;\n this.emitRuntimeStateChanged();\n return true;\n }\n private emitRuntimeStateChanged(): void {\n this.emit('runtimeStateChanged', { state: this.getRuntimeState() });\n this.scheduleDraw();\n }\n viewToWorld(sx: number, sy: number): [number, number] { return this.toWorld(sx, sy); }\n worldToView(wx: number, wy: number): [number, number] { return this.toScreen(wx, wy); }\n selectNodeById(id: string | null): void {\n const node = id === null ? null : (this.nodes.find((n) => n.id === id) ?? null);\n this.selectNode(node);\n }\n\n setZoom(scale: number): void {\n // clamp() passes NaN straight through, and a NaN scale poisons offX/offY on the very next\n // line -- after which hit-testing, drawing and saveViewState are all dead, permanently.\n if (!Number.isFinite(scale)) throw new RangeError('ssdiagram: zoom must be a finite number');\n const cx = this.width / 2;\n const cy = this.height / 2;\n const wx = (cx - this.offX) / this.scale;\n const wy = (cy - this.offY) / this.scale;\n this.scale = clamp(scale, ZOOM_MIN, ZOOM_MAX);\n this.offX = cx - wx * this.scale;\n this.offY = cy - wy * this.scale;\n this.emitViewChanged(true);\n this.scheduleDraw();\n }\n zoomToFit(): void {\n const gb = this.graphBounds();\n if (gb === null) { this.scale = 1; this.offX = 0; this.offY = 0; this.emitViewChanged(true); this.scheduleDraw(); return; }\n const pad = 40;\n const gw = (gb.maxX - gb.minX) + pad * 2;\n const gh = (gb.maxY - gb.minY) + pad * 2;\n // Cap at 1.0 \u2014 never blow a small graph up past 100%.\n this.scale = clamp(Math.min(this.width / gw, this.height / gh), ZOOM_MIN, 1);\n this.offX = (this.width - (gb.maxX + gb.minX) * this.scale) / 2;\n this.offY = (this.height - (gb.maxY + gb.minY) * this.scale) / 2;\n this.emitViewChanged(true);\n this.scheduleDraw();\n }\n // Entrance animation: the whole scheme rises from below + fades in.\n playIntro(): void { this.introStart = performance.now(); this.scheduleDraw(); }\n setOverviewVisible(v: boolean): void {\n if (this.overviewVisible === v) return;\n this.overviewVisible = v;\n this.emitViewChanged(false);\n this.scheduleDraw();\n }\n setTypeColors(colors: Readonly<Record<string, string>>): void {\n this.setTypeColorsInternal(colors);\n this.scheduleDraw();\n }\n\n /**\n * Keyed the way port types are compared everywhere else. Connection compatibility is case- and\n * space-insensitive, so an imported scheme spelling a socket \"candle \" connects to \"Candle\" and\n * then fell through to a hash colour, showing one logical type in two colours in one diagram.\n */\n private setTypeColorsInternal(colors: Readonly<Record<string, string>>): void {\n const normalized: Record<string, string> = {};\n for (const [type, color] of Object.entries(colors)) {\n setJsonKey(normalized, normalizePortType(type), color);\n }\n this.opts.typeColors = normalized;\n }\n setTheme(t: {\n background?: string;\n gridColor?: string;\n linkMaxLightness?: number;\n typedLinkColors?: boolean;\n overviewBackground?: string;\n overviewBorderColor?: string;\n overviewViewportColor?: string;\n overviewViewportFill?: string;\n }): void {\n if (t.background !== undefined) this.opts.background = t.background;\n if (t.gridColor !== undefined) this.opts.gridColor = t.gridColor;\n if (t.linkMaxLightness !== undefined) this.opts.linkMaxLightness = t.linkMaxLightness;\n if (t.typedLinkColors !== undefined) this.opts.typedLinkColors = t.typedLinkColors;\n if (t.overviewBackground !== undefined) this.opts.overviewBackground = t.overviewBackground;\n if (t.overviewBorderColor !== undefined) this.opts.overviewBorderColor = t.overviewBorderColor;\n if (t.overviewViewportColor !== undefined) this.opts.overviewViewportColor = t.overviewViewportColor;\n if (t.overviewViewportFill !== undefined) this.opts.overviewViewportFill = t.overviewViewportFill;\n this.scheduleDraw();\n }\n private graphBounds(): { minX: number; minY: number; maxX: number; maxY: number } | null {\n if (this.nodes.length === 0) return null;\n let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity;\n for (const n of this.nodes) {\n minX = Math.min(minX, n.x); minY = Math.min(minY, n.y);\n maxX = Math.max(maxX, n.x + n.w); maxY = Math.max(maxY, n.y + n.h);\n }\n return { minX, minY, maxX, maxY };\n }\n resize(w: number, h: number): void {\n if (w < 2 || h < 2) return;\n this.width = w; this.height = h;\n this.dpr = window.devicePixelRatio || 1;\n this.canvas.width = Math.round(w * this.dpr);\n this.canvas.height = Math.round(h * this.dpr);\n this.canvas.style.width = `${w}px`;\n this.canvas.style.height = `${h}px`;\n this.ctx.setTransform(this.dpr, 0, 0, this.dpr, 0, 0);\n this.scheduleDraw();\n }\n getInteractionPermissions(): DiagramInteractionPermissions {\n return { ...this.permissions };\n }\n setInteractionPermissions(patch: Partial<DiagramInteractionPermissions>): void {\n this.permissions = { ...this.permissions, ...patch };\n if (!this.permissions.select) {\n this.selectedNode = null;\n this.selectedNodes.clear();\n this.selectedLink = null;\n this.selectedPort = null;\n this.emitSelectionChanged();\n }\n this.emit('undoStackChanged', { canUndo: this.canUndo(), canRedo: this.canRedo() });\n this.scheduleDraw();\n }\n /** View-only mode keeps selection, inspection and copy enabled. */\n setReadOnly(value: boolean): void {\n this.permissions = value\n ? createReadOnlyDiagramPermissions()\n : createEditableDiagramPermissions();\n this.emit('undoStackChanged', { canUndo: this.canUndo(), canRedo: this.canRedo() });\n this.scheduleDraw();\n }\n destroy(): void {\n if (this.destroyed) return;\n this.destroyed = true;\n this.cancelLongPress();\n if (this.tipTimer !== null) {\n clearTimeout(this.tipTimer);\n this.tipTimer = null;\n }\n for (const dispose of this.domDisposables.splice(0).reverse()) dispose();\n this.handlers.clear();\n this.iconCache.clear();\n this.canvas.remove();\n }\n\n // ---- geometry ---------------------------------------------------\n private layoutNode(n: NodeModel): void {\n const ctx = this.ctx;\n ctx.font = '600 12px Segoe UI, Tahoma, sans-serif';\n const titleW = ctx.measureText(n.name).width;\n const rows = Math.max(n.inPorts.length, n.outPorts.length, 1);\n // Node sizing: min 170 wide, height grows by rows.\n n.w = Math.max(170, Math.ceil(titleW) + 28);\n n.h = Math.max(48, rows * PORT_ROW_H + 16);\n // Each side's port stack is vertically centred; the socket\n // square sits OUTSIDE the body (its inner edge flush with the\n // node border).\n const off = PORT_SQ / 2;\n const place = (ports: PortModel[], x: number): void => {\n const stack = ports.some(isGrowAnchor)\n ? [...ports.filter((p) => !isGrowAnchor(p)), ...ports.filter(isGrowAnchor)]\n : ports;\n const startY = n.y + (n.h - stack.length * PORT_ROW_H) / 2 + PORT_ROW_H / 2;\n stack.forEach((p, i) => { p.cx = x; p.cy = startY + i * PORT_ROW_H; });\n };\n place(n.inPorts, n.x - off);\n place(n.outPorts, n.x + n.w + off);\n }\n private relayout(): void { for (const n of this.nodes) this.layoutNode(n); }\n\n private toScreen(wx: number, wy: number): [number, number] {\n return [wx * this.scale + this.offX, wy * this.scale + this.offY];\n }\n private toWorld(sx: number, sy: number): [number, number] {\n return [(sx - this.offX) / this.scale, (sy - this.offY) / this.scale];\n }\n /// Type of the output wired into each connected input. First link wins, which is the one\n /// drawn first, so a socket accepting several links agrees with the wire on top.\n private feedTypes(): Map<PortModel, string> {\n const feed = new Map<PortModel, string>();\n for (const l of this.links) {\n const from = this.findNode(l.from)?.outPorts.find((p) => p.id === l.fromPort);\n if (from === undefined || isWildcardPortType(from.type)) continue;\n const to = this.findNode(l.to)?.inPorts.find((p) => p.id === l.toPort);\n if (to === undefined || feed.has(to)) continue;\n feed.set(to, from.type);\n }\n return feed;\n }\n\n /// Colour type of a socket: its own, unless it is a wildcard input with something wired in.\n /// A wildcard promises to take whatever arrives, so once something has arrived the socket\n /// shows what that is. An untyped socket ('') promises nothing and keeps its neutral fill.\n private portFillType(p: PortModel): string {\n if (p.direction !== 'in' || p.type === '' || !isWildcardPortType(p.type)) return p.type;\n return this.portFeed.get(p) ?? p.type;\n }\n\n private portColor(type: string): string {\n const maxL = this.opts.linkMaxLightness;\n const light = maxL !== undefined && maxL < 0.5;\n if (type === '') return light ? '#585c62' : '#9aa0a6';\n const map = this.opts.typeColors ?? {};\n const normalized = normalizePortType(type);\n const base = getJsonKey(map, normalized) ?? `hsl(${hashHue(normalized)}, 62%, 58%)`;\n return maxL !== undefined ? clampLightness(base, maxL) : base;\n }\n // Selection/hover accent. The dark-canvas blue washes out on a light canvas, so a light theme\n // (linkMaxLightness < 0.5) inverts to a darker, more saturated blue that stays clearly visible.\n private selectionColor(): string {\n const maxL = this.opts.linkMaxLightness;\n return maxL !== undefined && maxL < 0.5 ? '#0d6efd' : '#4aa3ff';\n }\n private linkHoverColor(): string {\n const maxL = this.opts.linkMaxLightness;\n return maxL !== undefined && maxL < 0.5 ? '#6aa9f0' : '#cfe3ff';\n }\n\n // ---- hit testing (world coords) ---------------------------------\n private portAt(wx: number, wy: number): { node: NodeModel; port: PortModel } | null {\n // Walks front to back and stops at the first node whose BODY covers the point, so a socket\n // hidden underneath a node drawn on top of it can no longer win the hit test. Without that\n // stop, clicking the visible body of the front node selected the one behind it, and on an\n // output socket started dragging a wire out of a port that is not on screen.\n for (let i = this.nodes.length - 1; i >= 0; i -= 1) {\n const n = this.nodes[i];\n for (const p of [...n.inPorts, ...n.outPorts]) {\n if ((wx - p.cx) ** 2 + (wy - p.cy) ** 2 <= (PORT_R + 4) ** 2) return { node: n, port: p };\n }\n if (wx >= n.x && wx <= n.x + n.w && wy >= n.y && wy <= n.y + n.h) return null;\n }\n return null;\n }\n private selectedLinkEndpointAt(wx: number, wy: number): 'from' | 'to' | null {\n if (this.selectedLink === null) return null;\n const radius = (PORT_R + 7) / this.scale;\n for (const end of ['from', 'to'] as const) {\n const point = this.endpoint(this.selectedLink, end);\n if (point !== null && (wx - point[0]) ** 2 + (wy - point[1]) ** 2 <= radius ** 2) return end;\n }\n return null;\n }\n private directRelinkAtPort(node: NodeModel, port: PortModel): {\n link: LinkModel;\n end: 'from' | 'to';\n } | null {\n if (port.direction !== 'in') return null;\n const incoming = this.links.filter((link) => link.to === node.id && link.toPort === port.id);\n return incoming.length === 1 ? { link: incoming[0], end: 'to' } : null;\n }\n private nodeAt(wx: number, wy: number): NodeModel | null {\n for (let i = this.nodes.length - 1; i >= 0; i -= 1) {\n const n = this.nodes[i];\n if (wx >= n.x && wx <= n.x + n.w && wy >= n.y && wy <= n.y + n.h) return n;\n }\n return null;\n }\n // Other nodes (not the link's own endpoints) become obstacles,\n // inflated so links keep a little clearance \u2014 the AvoidsNodes margin.\n private obstaclesFor(exclude: Set<string>): Rect[] {\n const inf = 12;\n const out: Rect[] = [];\n for (const n of this.nodes) {\n if (exclude.has(n.id)) continue;\n out.push([n.x - inf, n.y - inf, n.w + inf * 2, n.h + inf * 2]);\n }\n return out;\n }\n private routeLink(a: [number, number], b: [number, number], exclude: Set<string>): number[][] {\n return routeAvoid(a, b, this.obstaclesFor(exclude));\n }\n private linkAt(wx: number, wy: number): LinkModel | null {\n const tol = 5 / this.scale;\n // topmost first so the hovered/selected one wins\n for (let i = this.links.length - 1; i >= 0; i -= 1) {\n const l = this.links[i];\n const a = this.endpoint(l, 'from');\n const b = this.endpoint(l, 'to');\n if (a === null || b === null) continue;\n const pts = this.routeLink(a, b, new Set([l.from, l.to]));\n for (let k = 1; k < pts.length; k += 1) {\n if (ptSegDist(wx, wy, pts[k - 1][0], pts[k - 1][1], pts[k][0], pts[k][1]) <= tol) return l;\n }\n }\n return null;\n }\n private endpoint(l: LinkModel, end: 'from' | 'to'): [number, number] | null {\n const node = this.nodes.find((n) => n.id === (end === 'from' ? l.from : l.to));\n if (node === undefined) return null;\n const port = end === 'from'\n ? node.outPorts.find((p) => p.id === l.fromPort)\n : node.inPorts.find((p) => p.id === l.toPort);\n if (port === undefined) return null;\n return [port.cx, port.cy];\n }\n\n // ---- linking rules ----------------------------------------------\n validateLink(init: Pick<LinkInit, 'from' | 'fromPort' | 'to' | 'toPort'>, excludeLinkId?: string): LinkValidationResult {\n const fromNode = this.nodes.find((node) => node.id === init.from);\n const toNode = this.nodes.find((node) => node.id === init.to);\n if (fromNode === undefined || toNode === undefined) return { allowed: false, reason: 'missing-node' };\n const fromPort = fromNode.outPorts.find((port) => port.id === init.fromPort);\n const toPort = toNode.inPorts.find((port) => port.id === init.toPort);\n if (fromPort === undefined || toPort === undefined) return { allowed: false, reason: 'missing-port' };\n return this.validateLinkModels(fromNode, fromPort, toNode, toPort, excludeLinkId);\n }\n\n private validateLinkModels(\n fromNode: NodeModel,\n fromPort: PortModel,\n toNode: NodeModel,\n toPort: PortModel,\n excludeLinkId?: string,\n ): LinkValidationResult {\n if (fromNode === toNode) return { allowed: false, reason: 'same-node' };\n if (fromPort.direction !== 'out' || toPort.direction !== 'in') {\n return { allowed: false, reason: 'invalid-direction' };\n }\n const relevantLinks = this.links.filter((link) => link.id !== excludeLinkId);\n if (relevantLinks.some((link) => link.from === fromNode.id\n && link.fromPort === fromPort.id\n && link.to === toNode.id\n && link.toPort === toPort.id)) {\n return { allowed: false, reason: 'duplicate-link' };\n }\n if (fromPort.maxLinks > 0) {\n const used = relevantLinks.filter((link) => link.from === fromNode.id && link.fromPort === fromPort.id).length;\n if (used >= fromPort.maxLinks) return { allowed: false, reason: 'source-limit' };\n }\n if (toPort.maxLinks > 0) {\n const used = relevantLinks.filter((link) => link.to === toNode.id && link.toPort === toPort.id).length;\n if (used >= toPort.maxLinks) return { allowed: false, reason: 'target-limit' };\n }\n if (!arePortTypesCompatible(fromPort.type, toPort.type, toPort.availableTypes)) {\n return { allowed: false, reason: 'incompatible-type' };\n }\n if (this.validator !== null && !this.validator({ fromNode, fromPort, toNode, toPort })) {\n return { allowed: false, reason: 'host-rejected' };\n }\n return { allowed: true, reason: 'allowed' };\n }\n\n private removeIncompatibleLinks(matches: (link: LinkModel) => boolean): void {\n const incompatible = this.links.filter((link) => matches(link) && !this.canExistingLinkRemain(link));\n for (const link of incompatible) this.removeLinkInternal(link, true);\n }\n\n private canExistingLinkRemain(link: LinkModel): boolean {\n const fromNode = this.nodes.find((node) => node.id === link.from);\n const toNode = this.nodes.find((node) => node.id === link.to);\n const fromPort = fromNode?.outPorts.find((port) => port.id === link.fromPort);\n const toPort = toNode?.inPorts.find((port) => port.id === link.toPort);\n if (fromNode === undefined || toNode === undefined || fromPort === undefined || toPort === undefined) {\n return false;\n }\n if (!arePortTypesCompatible(fromPort.type, toPort.type, toPort.availableTypes)) return false;\n return this.validator === null || this.validator({ fromNode, fromPort, toNode, toPort });\n }\n // Plug\u2194socket magnet: while dragging from an out-port, find the\n // nearest in-port (within SNAP_PX, screen space) the link is allowed\n // to land on. Returns null when none is close \u2192 the pending link\n // detaches and follows the cursor again.\n private findSnap(): { node: NodeModel; port: PortModel } | null {\n if (this.linking === null && this.relinking === null) return null;\n let direction: PortDirection;\n let accepts: (node: NodeModel, port: PortModel) => boolean;\n if (this.linking !== null) {\n const source = this.linking;\n direction = 'in';\n accepts = (node, port) => this.validateLinkModels(source.node, source.port, node, port).allowed;\n } else {\n const gesture = this.relinking!;\n if (gesture.end === 'to') {\n const sourceNode = this.nodes.find((node) => node.id === gesture.link.from);\n const sourcePort = sourceNode?.outPorts.find((port) => port.id === gesture.link.fromPort);\n if (sourceNode === undefined || sourcePort === undefined) return null;\n direction = 'in';\n accepts = (node, port) => this.validateLinkModels(\n sourceNode, sourcePort, node, port, gesture.link.id,\n ).allowed;\n } else {\n const targetNode = this.nodes.find((node) => node.id === gesture.link.to);\n const targetPort = targetNode?.inPorts.find((port) => port.id === gesture.link.toPort);\n if (targetNode === undefined || targetPort === undefined) return null;\n direction = 'out';\n accepts = (node, port) => this.validateLinkModels(\n node, port, targetNode, targetPort, gesture.link.id,\n ).allowed;\n }\n }\n let best: { node: NodeModel; port: PortModel } | null = null;\n let bestD = SNAP_PX;\n for (const n of this.nodes) {\n const ports = direction === 'in' ? n.inPorts : n.outPorts;\n for (const p of ports) {\n if (!accepts(n, p)) continue;\n const [sx, sy] = this.toScreen(p.cx, p.cy);\n const dpx = Math.hypot(sx - this.cursor.x, sy - this.cursor.y);\n if (dpx <= bestD) { bestD = dpx; best = { node: n, port: p }; }\n }\n }\n return best;\n }\n\n private selectNode(n: NodeModel | null): void {\n this.selectedLink = null;\n this.selectedPort = null;\n this.selectedNodes.clear();\n if (n !== null) this.selectedNodes.add(n);\n this.selectedNode = n;\n this.emit('nodeSelected', { node: n, selected: n !== null });\n this.emitSelectionChanged();\n this.scheduleDraw();\n }\n private toggleSelect(n: NodeModel): void {\n this.selectedLink = null;\n this.selectedPort = null;\n if (this.selectedNodes.has(n)) {\n this.selectedNodes.delete(n);\n if (this.selectedNode === n) this.selectedNode = null;\n } else {\n this.selectedNodes.add(n);\n this.selectedNode = n;\n }\n this.emit('nodeSelected', { node: this.selectedNode, selected: this.selectedNodes.size > 0 });\n this.emitSelectionChanged();\n this.scheduleDraw();\n }\n private setSelection(ns: NodeModel[]): void {\n this.selectedLink = null;\n this.selectedPort = null;\n this.selectedNodes = new Set(ns);\n this.selectedNode = ns.length > 0 ? ns[ns.length - 1] : null;\n this.emit('nodeSelected', { node: this.selectedNode, selected: ns.length > 0 });\n this.emitSelectionChanged();\n this.scheduleDraw();\n }\n private selectLink(l: LinkModel | null): void {\n if (this.selectedLink === l) return;\n this.selectedNode = null;\n this.selectedNodes.clear();\n this.selectedPort = null;\n this.selectedLink = l;\n this.emit('linkSelected', { link: l, selected: l !== null });\n this.emitSelectionChanged();\n this.scheduleDraw();\n }\n private selectPort(target: { node: NodeModel; port: PortModel }): void {\n this.selectedPort = target;\n this.emit('portSelected', target);\n this.emitSelectionChanged();\n this.scheduleDraw();\n }\n private emitSelectionChanged(): void {\n this.emit('selectionChanged', this.getSelection());\n }\n // ---- clipboard (copy / paste of the selection) ------------------\n copySelection(): void {\n this.copySelectionDocument();\n }\n copySelectionDocument(): DiagramDocument | null {\n if (!this.permissions.copy) return null;\n if (this.selectedNodes.size === 0) { this.clip = null; return null; }\n const ids = new Set([...this.selectedNodes].map((n) => n.id));\n const all = this.saveDocument();\n this.clip = createDiagramDocument({\n nodes: all.nodes.filter((n) => ids.has(n.id)),\n links: all.links.filter((link) => ids.has(link.from.nodeId) && ids.has(link.to.nodeId)),\n });\n return parseDiagramDocument(this.clip);\n }\n hasClipboard(): boolean {\n return this.clip !== null && this.clip.nodes.length > 0;\n }\n getClipboardDocument(): DiagramDocument | null {\n return this.clip === null ? null : parseDiagramDocument(this.clip);\n }\n setClipboardDocument(source: DiagramDocument | string): void {\n this.clip = parseDiagramDocument(source);\n }\n pasteSelection(): string[] {\n if (this.clip === null) return [];\n return this.pasteDocument(this.clip);\n }\n pasteDocument(source: DiagramDocument | string, offset?: { x: number; y: number }): string[] {\n if (!this.permissions.paste) return [];\n const clipboard = parseDiagramDocument(source);\n if (clipboard.nodes.length === 0) return [];\n const pasteOffset = offset ?? { x: this.gridSize, y: this.gridSize };\n this.clip = clipboard;\n const map = new Map<string, string>();\n const added: NodeModel[] = [];\n // Paste of N nodes + M links collapses into ONE undo step.\n this.withTransaction('paste', () => {\n for (const sn of clipboard.nodes) {\n const nid = this.nextNodeId();\n map.set(sn.id, nid);\n const id = this.addDiagramNode({\n ...sn,\n id: nid,\n x: sn.x + pasteOffset.x,\n y: sn.y + pasteOffset.y,\n });\n const nn = this.nodes.find((x) => x.id === id);\n if (nn !== undefined) added.push(nn);\n }\n for (const l of clipboard.links) {\n const f = map.get(l.from.nodeId);\n const t = map.get(l.to.nodeId);\n if (f !== undefined && t !== undefined)\n this.addLink({\n from: f,\n fromPort: l.from.portId,\n to: t,\n toPort: l.to.portId,\n // The clipboard is built from saveDocument(), so it carries the style;\n // rebuilding without it silently turned every pasted dashed link solid.\n style: l.style,\n metadata: l.metadata,\n });\n }\n });\n this.setSelection(added);\n return added.map((node) => node.id);\n }\n\n // ---- input ------------------------------------------------------\n // Ends hover and everything hanging off it: highlight, cursor and the delayed tooltip.\n private clearHover(): void {\n if (this.hoverPort !== null) this.emit('portHover', { node: this.hoverPort.node, port: this.hoverPort.port, hovering: false });\n if (this.hoverNode !== null) this.emit('nodeHover', { node: this.hoverNode, hovering: false });\n if (this.hoveredLink !== null) this.emit('linkHover', { link: this.hoveredLink, hovering: false });\n this.hoverPort = null; this.hoverNode = null; this.hoveredLink = null;\n this.tipTarget = null; this.tipShow = false;\n if (this.tipTimer !== null) { clearTimeout(this.tipTimer); this.tipTimer = null; }\n this.canvas.style.cursor = 'default';\n this.scheduleDraw();\n }\n\n private cancelLongPress(): void {\n if (this.lpTimer !== null) { clearTimeout(this.lpTimer); this.lpTimer = null; }\n this.lpStart = null;\n }\n /// Ends a node drag the way releasing the pointer does: the whole multi-node move becomes\n /// one undo step, and every node that actually moved is announced. Nodes are moved in place\n /// as the pointer travels, so a caller that clears the drag without coming through here\n /// leaves them where the drag put them with nothing in the history and the host unaware.\n private commitNodeDrag(): void {\n if (this.dragNode === null) return;\n\n // Capture before/after positions so the whole multi-node\n // drag is ONE undo step. Skip the action if nothing\n // actually moved (a \"click\" that bypassed the threshold).\n const moves = this.dragStart\n .map((it) => ({ id: it.n.id, fromX: it.x, fromY: it.y, toX: it.n.x, toY: it.n.y }))\n .filter((m) => m.fromX !== m.toX || m.fromY !== m.toY);\n // Announce the same set the undo step records. Emitting for every node the drag\n // touched reported a move for a plain selection click -- one per selected node --\n // and a host doing dirty tracking marked the strategy modified for nothing.\n const moved = new Set(moves.map((m) => m.id));\n for (const it of this.dragStart) {\n if (moved.has(it.n.id)) this.emit('nodeMoved', { node: it.n });\n }\n this.dragNode = null;\n this.dragStart = [];\n if (moves.length > 0) {\n this.record({\n do: () => { for (const m of moves) this.doMoveNode(m.id, m.toX, m.toY); },\n undo: () => { for (const m of moves) this.doMoveNode(m.id, m.fromX, m.fromY); },\n label: 'drag',\n });\n }\n }\n\n // Hit-test at screen coords and emit a contextMenu event. Ends whatever gesture was in\n // flight \u2014 once the menu opens we don't want a half-drag racing it \u2014 and a node drag ends\n // properly rather than being dropped, because its nodes have already moved.\n private fireContextMenu(sx: number, sy: number, pageX: number, pageY: number): void {\n this.commitNodeDrag();\n const [wx, wy] = this.toWorld(sx, sy);\n const port = this.portAt(wx, wy);\n const node = port?.node ?? this.nodeAt(wx, wy);\n const link = port === null && node === null ? this.linkAt(wx, wy) : null;\n if (this.permissions.select) {\n if (port !== null) {\n const selectedLink = this.selectedLink;\n const isSelectedEndpoint = selectedLink !== null\n && ((selectedLink.from === port.node.id && selectedLink.fromPort === port.port.id)\n || (selectedLink.to === port.node.id && selectedLink.toPort === port.port.id));\n if (!isSelectedEndpoint && !this.selectedNodes.has(port.node)) this.selectNode(port.node);\n this.selectPort(port);\n } else if (node !== null && !this.selectedNodes.has(node)) this.selectNode(node);\n else if (link !== null && this.selectedLink !== link) this.selectLink(link);\n }\n this.dragNode = null; this.dragStart = []; this.rubber = null;\n this.linking = null; this.relinking = null; this.relinkCandidate = null; this.linkSnap = null;\n // A pan ends here too, and it ends settled: a host that persists the viewport on the\n // settled event would otherwise keep the position the pan started from.\n const viewportMoved = this.panning || this.ovDragging;\n this.panning = false;\n this.ovDragging = false;\n if (viewportMoved) this.emitViewChanged(false);\n // A menu is about to cover this spot, and it opens under a cursor that has not moved --\n // which fires no boundary event, so nothing else would end the hover. Without this the\n // tooltip armed by the last pointermove appears 400ms later, through the open menu.\n this.clearHover();\n this.emit('contextMenu', { x: pageX, y: pageY, link, node, port });\n }\n\n private listen<K extends keyof HTMLElementEventMap>(\n target: HTMLElement,\n type: K,\n listener: (event: HTMLElementEventMap[K]) => void,\n options?: boolean | AddEventListenerOptions,\n ): void;\n private listen<K extends keyof WindowEventMap>(\n target: Window,\n type: K,\n listener: (event: WindowEventMap[K]) => void,\n options?: boolean | AddEventListenerOptions,\n ): void;\n private listen(\n target: EventTarget,\n type: string,\n listener: EventListener,\n options?: boolean | AddEventListenerOptions,\n ): void {\n target.addEventListener(type, listener, options);\n this.domDisposables.push(() => target.removeEventListener(type, listener, options));\n }\n\n private bind(): void {\n const localXY = (e: MouseEvent | PointerEvent): [number, number] => {\n const r = this.canvas.getBoundingClientRect();\n return [e.clientX - r.left, e.clientY - r.top];\n };\n this.listen(this.canvas, 'pointerdown', (e) => {\n try { (this.canvas as Element).setPointerCapture(e.pointerId); } catch { /* unsupported */ }\n // Arm a long-press timer on every pointerdown. Cancelled by\n // move-beyond-tolerance, pointerup, or any other gesture.\n this.cancelLongPress();\n this.relinkCandidate = null;\n // Touch only. A mouse has a button for this, and arming the timer for it meant holding\n // the left button still -- which is what positioning a node precisely looks like --\n // opened the menu after half a second and wiped the drag in progress: the pixels the\n // node had already travelled stayed, but never reached history, so Ctrl+Z could not\n // take them back.\n if (e.pointerType !== 'mouse') {\n this.lpStart = { sx: e.clientX, sy: e.clientY, px: e.clientX, py: e.clientY };\n const downSx = e.clientX, downSy = e.clientY;\n const r0 = this.canvas.getBoundingClientRect();\n const localSx = downSx - r0.left, localSy = downSy - r0.top;\n this.lpTimer = setTimeout(() => {\n this.lpTimer = null;\n this.fireContextMenu(localSx, localSy, downSx, downSy);\n }, this.lpDelayMs);\n }\n this.canvas.focus();\n const [sx, sy] = localXY(e);\n if (this.ovHit(sx, sy)) { this.ovDragging = true; this.ovPanTo(sx, sy); return; }\n if (!this.permissions.inspect) this.cancelLongPress();\n const [wx, wy] = this.toWorld(sx, sy);\n const selectedEndpoint = this.selectedLinkEndpointAt(wx, wy);\n if (e.button === 0 && this.permissions.createLinks && this.selectedLink !== null\n && selectedEndpoint !== null) {\n this.relinking = { link: this.selectedLink, end: selectedEndpoint };\n this.linking = null;\n this.linkSnap = null;\n this.cursor = { x: sx, y: sy };\n return;\n }\n const portHit = this.portAt(wx, wy);\n if (portHit !== null) {\n const selectedLink = this.selectedLink;\n const isFrom = selectedLink !== null\n && portHit.port.direction === 'out'\n && selectedLink.from === portHit.node.id\n && selectedLink.fromPort === portHit.port.id;\n const isTo = selectedLink !== null\n && portHit.port.direction === 'in'\n && selectedLink.to === portHit.node.id\n && selectedLink.toPort === portHit.port.id;\n if (this.permissions.inspect) {\n if (this.permissions.select && !isFrom && !isTo && !this.selectedNodes.has(portHit.node)) {\n this.selectNode(portHit.node);\n }\n this.selectPort(portHit);\n if (e.button === 0 || e.button === 2) {\n this.emit('portClicked', {\n ...portHit,\n action: e.button === 2 ? 'rightClick' : 'leftClick',\n ctrlKey: e.ctrlKey,\n shiftKey: e.shiftKey,\n altKey: e.altKey,\n metaKey: e.metaKey,\n });\n }\n }\n if (e.button !== 0) return;\n if (this.permissions.createLinks && selectedLink !== null) {\n if (isFrom || isTo) {\n this.relinking = { link: selectedLink, end: isFrom ? 'from' : 'to' };\n this.linking = null;\n this.linkSnap = null;\n this.cursor = { x: sx, y: sy };\n return;\n }\n }\n // A single existing input link can be rewired in one drag\n // without a separate selection click.\n const directRelink = this.permissions.createLinks\n ? this.directRelinkAtPort(portHit.node, portHit.port)\n : null;\n if (directRelink !== null) {\n this.relinkCandidate = { ...directRelink, sx, sy };\n this.linking = null;\n this.relinking = null;\n this.linkSnap = null;\n this.cursor = { x: sx, y: sy };\n return;\n }\n // Other output sockets start an additional link; input sockets\n // consume the gesture so they never drag the whole diagram.\n if (this.permissions.createLinks && portHit.port.direction === 'out') {\n this.linking = portHit;\n this.relinking = null;\n this.linkSnap = null;\n this.cursor = { x: sx, y: sy };\n }\n return;\n }\n const node = this.nodeAt(wx, wy);\n if (node !== null) {\n const add = e.shiftKey || e.ctrlKey || e.metaKey;\n if (this.permissions.select) {\n // A right-click still selects what it landed on, so the menu that follows acts\n // on the node under the cursor -- but only the primary button may drag it.\n if (add && e.button === 0) { this.toggleSelect(node); return; }\n if (!this.selectedNodes.has(node)) this.selectNode(node);\n }\n if (this.permissions.moveNodes && e.button === 0) {\n this.dragNode = node;\n this.dragAnchor = { wx, wy };\n const moving = this.selectedNodes.has(node) ? [...this.selectedNodes] : [node];\n this.dragStart = moving.map((item) => ({ n: item, x: item.x, y: item.y }));\n const selected = new Set(moving);\n this.nodes = this.nodes.filter((item) => !selected.has(item)).concat(moving);\n }\n return;\n }\n const link = this.linkAt(wx, wy);\n if (link !== null) {\n if (this.permissions.select) this.selectLink(link);\n return;\n }\n // A secondary button on empty canvas is on its way to the context menu: it must not\n // clear the selection the menu is about to act on, nor start a rubber band.\n if (e.button !== 0 && e.button !== 1) return;\n // empty space: middle-button / Ctrl / Alt / touch = pan;\n // else rubber-band select. Touch always pans because mobile\n // users can't hold modifier keys and rubber-band drag-select\n // is awkward with a finger.\n const wantPan = !this.permissions.select || e.button === 1 || e.ctrlKey || e.altKey || e.pointerType === 'touch';\n if (wantPan) {\n if (this.permissions.select && !e.shiftKey) this.selectNode(null);\n this.panning = true; this.panX = sx; this.panY = sy;\n } else {\n if (!e.shiftKey) this.selectNode(null);\n this.rubber = { x0: wx, y0: wy, x: wx, y: wy };\n }\n });\n this.listen(this.canvas, 'pointermove', (e) => {\n const [sx, sy] = localXY(e);\n this.cursor = { x: sx, y: sy };\n // movement past tolerance \u2192 not a long-press anymore\n if (this.lpStart !== null) {\n const dx = e.clientX - this.lpStart.px;\n const dy = e.clientY - this.lpStart.py;\n if (Math.hypot(dx, dy) > this.lpMoveTol) this.cancelLongPress();\n }\n if (this.ovDragging) { this.ovPanTo(sx, sy); return; }\n const [wx, wy] = this.toWorld(sx, sy);\n if (this.relinkCandidate !== null) {\n const candidate = this.relinkCandidate;\n if (Math.hypot(sx - candidate.sx, sy - candidate.sy) <= RELINK_DRAG_THRESHOLD_PX) return;\n this.relinkCandidate = null;\n this.relinking = { link: candidate.link, end: candidate.end };\n if (this.permissions.select) this.selectLink(candidate.link);\n this.linkSnap = this.findSnap();\n this.scheduleDraw();\n return;\n }\n if (this.dragNode !== null) {\n let ddx = wx - this.dragAnchor.wx;\n let ddy = wy - this.dragAnchor.wy;\n if (this.gridSnapEnabled) {\n const primary = this.dragStart.find((item) => item.n === this.dragNode);\n if (primary !== undefined) {\n ddx = Math.round((primary.x + ddx) / this.gridSize) * this.gridSize - primary.x;\n ddy = Math.round((primary.y + ddy) / this.gridSize) * this.gridSize - primary.y;\n }\n }\n for (const it of this.dragStart) {\n it.n.x = it.x + ddx;\n it.n.y = it.y + ddy;\n this.layoutNode(it.n);\n }\n this.scheduleDraw();\n return;\n }\n if (this.rubber !== null) {\n this.rubber.x = wx; this.rubber.y = wy;\n this.scheduleDraw();\n return;\n }\n if (this.panning) {\n this.offX += sx - this.panX;\n this.offY += sy - this.panY;\n this.panX = sx; this.panY = sy;\n this.scheduleDraw();\n return;\n }\n if (this.linking !== null || this.relinking !== null) {\n this.linkSnap = this.findSnap();\n this.scheduleDraw();\n return;\n }\n if (!this.permissions.inspect) return;\n let dirty = false;\n // port hover\n const hit = this.portAt(wx, wy);\n if ((hit?.port ?? null) !== (this.hoverPort?.port ?? null)) {\n if (this.hoverPort !== null)\n this.emit('portHover', { node: this.hoverPort.node, port: this.hoverPort.port, hovering: false });\n this.hoverPort = hit;\n if (hit !== null) this.emit('portHover', { node: hit.node, port: hit.port, hovering: true });\n dirty = true;\n }\n // node hover (for tooltip)\n const nodeHit = hit === null ? this.nodeAt(wx, wy) : null;\n if (nodeHit !== this.hoverNode) {\n if (this.hoverNode !== null) this.emit('nodeHover', { node: this.hoverNode, hovering: false });\n this.hoverNode = nodeHit;\n if (nodeHit !== null) this.emit('nodeHover', { node: nodeHit, hovering: true });\n dirty = true;\n }\n // hover-delay before the tooltip appears\n const tipTgt: PortModel | NodeModel | null = this.hoverPort?.port ?? this.hoverNode;\n if (tipTgt !== this.tipTarget) {\n this.tipTarget = tipTgt;\n this.tipShow = false;\n if (this.tipTimer !== null) { clearTimeout(this.tipTimer); this.tipTimer = null; }\n if (tipTgt !== null) {\n this.tipTimer = setTimeout(() => {\n this.tipTimer = null;\n this.tipShow = true;\n this.scheduleDraw();\n }, 400);\n }\n dirty = true;\n }\n // link hover (only when not over a port/node)\n const overNode = nodeHit !== null;\n const linkHit = hit === null && !overNode ? this.linkAt(wx, wy) : null;\n if (linkHit !== this.hoveredLink) {\n if (this.hoveredLink !== null) this.emit('linkHover', { link: this.hoveredLink, hovering: false });\n this.hoveredLink = linkHit;\n if (linkHit !== null) this.emit('linkHover', { link: linkHit, hovering: true });\n dirty = true;\n }\n const endpointHit = this.permissions.createLinks ? this.selectedLinkEndpointAt(wx, wy) : null;\n const directRelinkHit = this.permissions.createLinks && hit !== null\n ? this.directRelinkAtPort(hit.node, hit.port)\n : null;\n this.canvas.style.cursor = endpointHit !== null || directRelinkHit !== null ? 'grab'\n : hit !== null ? 'pointer'\n : overNode ? 'move'\n : linkHit !== null ? 'pointer' : 'default';\n if (dirty) this.scheduleDraw();\n });\n const finish = (e: MouseEvent | PointerEvent): void => {\n this.cancelLongPress();\n this.relinkCandidate = null;\n this.commitNodeDrag();\n if (this.rubber !== null) {\n const rx0 = Math.min(this.rubber.x0, this.rubber.x);\n const ry0 = Math.min(this.rubber.y0, this.rubber.y);\n const rx1 = Math.max(this.rubber.x0, this.rubber.x);\n const ry1 = Math.max(this.rubber.y0, this.rubber.y);\n this.rubber = null;\n if (rx1 - rx0 > 3 || ry1 - ry0 > 3) {\n const inRect = this.nodes.filter((n) =>\n n.x < rx1 && n.x + n.w > rx0 && n.y < ry1 && n.y + n.h > ry0);\n const merge = e.shiftKey ? [...this.selectedNodes, ...inRect] : inRect;\n this.setSelection([...new Set(merge)]);\n }\n this.scheduleDraw();\n }\n const viewportMoved = this.panning || this.ovDragging;\n this.panning = false;\n this.ovDragging = false;\n if (viewportMoved) this.emitViewChanged(false);\n if (this.linking !== null) {\n const [sx, sy] = localXY(e);\n const [wx, wy] = this.toWorld(sx, sy);\n // Commit to the magnetised socket if one is engaged;\n // otherwise fall back to whatever is exactly under the\n // cursor (covers a precise drop without a snap).\n const direct = this.portAt(wx, wy);\n const target = this.linkSnap\n ?? (direct !== null && direct.port.direction === 'in' ? direct : null);\n if (target !== null) {\n this.addLink({\n from: this.linking.node.id, fromPort: this.linking.port.id,\n to: target.node.id, toPort: target.port.id,\n });\n }\n this.linking = null;\n this.linkSnap = null;\n this.scheduleDraw();\n }\n if (this.relinking !== null) {\n const gesture = this.relinking;\n const [sx, sy] = localXY(e);\n const [wx, wy] = this.toWorld(sx, sy);\n const direct = this.portAt(wx, wy);\n const expectedDirection: PortDirection = gesture.end === 'from' ? 'out' : 'in';\n const target = this.linkSnap\n ?? (direct !== null && direct.port.direction === expectedDirection ? direct : null);\n if (target !== null) {\n this.relink(gesture.link.id, {\n from: gesture.end === 'from' ? target.node.id : gesture.link.from,\n fromPort: gesture.end === 'from' ? target.port.id : gesture.link.fromPort,\n to: gesture.end === 'to' ? target.node.id : gesture.link.to,\n toPort: gesture.end === 'to' ? target.port.id : gesture.link.toPort,\n });\n }\n this.relinking = null;\n this.linkSnap = null;\n this.scheduleDraw();\n }\n };\n this.listen(window, 'pointerup', finish);\n this.listen(window, 'pointercancel', finish);\n this.listen(this.canvas, 'wheel', (e) => {\n e.preventDefault();\n const [sx, sy] = localXY(e);\n const [wx, wy] = this.toWorld(sx, sy);\n // Smooth, device-consistent: zoom amount tracks wheel delta\n // magnitude instead of a fixed step (no more big jumps).\n const factor = Math.exp(-e.deltaY * 0.0015);\n this.scale = clamp(this.scale * factor, ZOOM_MIN, ZOOM_MAX);\n this.offX = sx - wx * this.scale;\n this.offY = sy - wy * this.scale;\n this.emitViewChanged(true);\n this.scheduleDraw();\n }, { passive: false });\n this.listen(this.canvas, 'pointerleave', () => this.clearHover());\n this.listen(this.canvas, 'dblclick', (e) => {\n const [sx, sy] = localXY(e);\n const [wx, wy] = this.toWorld(sx, sy);\n if (this.portAt(wx, wy) !== null) return;\n // A wire is something, not empty canvas: without this the zoomToFit fallback below\n // threw away the zoom and pan the user had set, on a double click aimed at a link.\n if (this.linkAt(wx, wy) !== null) return;\n const node = this.nodeAt(wx, wy);\n if (node !== null) {\n if (this.permissions.inspect && node.openAction.length > 0) {\n e.preventDefault();\n this.emit('nodeOpen', { node });\n }\n return;\n }\n this.zoomToFit();\n });\n // Desktop right-click \u2192 same contextMenu event as touch long-press.\n const openContextMenu = (e: MouseEvent): void => {\n e.preventDefault();\n if (!this.permissions.inspect) return;\n const [sx, sy] = localXY(e);\n this.cancelLongPress();\n this.fireContextMenu(sx, sy, e.clientX, e.clientY);\n };\n this.listen(this.canvas, 'contextmenu', openContextMenu);\n // The control is more than its canvas: its own buttons sit over the corners, and a\n // right-click on one of those stops at the button, so the browser drew its own menu\n // there. The canvas keeps its own handler, and this one skips what that already took.\n this.listen(this.host, 'contextmenu', (e) => {\n if (e.target !== this.canvas) openContextMenu(e);\n });\n // Two-finger pinch \u2192 uniform zoom around the initial midpoint\n // between the fingers. Mobile analog of mouse wheel.\n let pinchDist = 0;\n let pinchScale = 1;\n let pinchPivotW: [number, number] = [0, 0];\n let pinchPivotS: [number, number] = [0, 0];\n let pinching = false;\n this.listen(this.canvas, 'touchstart', (e) => {\n if (e.touches.length === 2) {\n e.preventDefault();\n const r = this.canvas.getBoundingClientRect();\n const t0 = e.touches[0], t1 = e.touches[1];\n const x0 = t0.clientX - r.left, y0 = t0.clientY - r.top;\n const x1 = t1.clientX - r.left, y1 = t1.clientY - r.top;\n pinchDist = Math.max(1, Math.hypot(x1 - x0, y1 - y0));\n pinchScale = this.scale;\n const mx = (x0 + x1) / 2, my = (y0 + y1) / 2;\n pinchPivotS = [mx, my];\n pinchPivotW = this.toWorld(mx, my);\n pinching = true;\n this.dragNode = null; this.dragStart = [];\n this.panning = false; this.rubber = null; this.linking = null;\n this.relinking = null; this.relinkCandidate = null;\n // The two the block used to miss: a finger that started on the minimap kept\n // panning the viewport against the pinch, and a cancelled wire drag left its\n // magnet highlight burned onto a socket until something else redrew it.\n this.ovDragging = false; this.linkSnap = null;\n }\n }, { passive: false });\n this.listen(this.canvas, 'touchmove', (e) => {\n if (pinching && e.touches.length === 2) {\n e.preventDefault();\n const r = this.canvas.getBoundingClientRect();\n const t0 = e.touches[0], t1 = e.touches[1];\n const x0 = t0.clientX - r.left, y0 = t0.clientY - r.top;\n const x1 = t1.clientX - r.left, y1 = t1.clientY - r.top;\n const d = Math.max(1, Math.hypot(x1 - x0, y1 - y0));\n const ns = clamp(pinchScale * (d / pinchDist), ZOOM_MIN, ZOOM_MAX);\n this.scale = ns;\n // Keep the pinch midpoint anchored at the world point it\n // started on (pivot stays put under the fingers).\n this.offX = pinchPivotS[0] - pinchPivotW[0] * ns;\n this.offY = pinchPivotS[1] - pinchPivotW[1] * ns;\n this.emitViewChanged(true);\n this.scheduleDraw();\n }\n }, { passive: false });\n const endPinch = (): void => { pinching = false; };\n this.listen(this.canvas, 'touchend', endPinch);\n this.listen(this.canvas, 'touchcancel', endPinch);\n this.listen(this.canvas, 'keydown', (e) => {\n if (this.permissions.moveNodes && !e.ctrlKey && !e.metaKey && !e.altKey) {\n const step = (this.gridSnapEnabled ? this.gridSize : 1) * (e.shiftKey ? 5 : 1);\n const delta = e.key === 'ArrowLeft' ? [-step, 0]\n : e.key === 'ArrowRight' ? [step, 0]\n : e.key === 'ArrowUp' ? [0, -step]\n : e.key === 'ArrowDown' ? [0, step]\n : null;\n if (delta !== null && this.nudgeSelection(delta[0], delta[1])) {\n e.preventDefault();\n return;\n }\n }\n if (this.permissions.deleteSelection && (e.key === 'Delete' || e.key === 'Backspace')) {\n e.preventDefault(); this.deleteSelection(); return;\n }\n const mod = e.ctrlKey || e.metaKey;\n if (mod && this.permissions.copy && e.code === 'KeyC') { e.preventDefault(); this.copySelection(); return; }\n if (mod && this.permissions.paste && e.code === 'KeyV') { e.preventDefault(); this.pasteSelection(); return; }\n if (mod && this.permissions.copy && this.permissions.deleteSelection && e.code === 'KeyX') {\n e.preventDefault(); this.cutSelection(); return;\n }\n if (mod && this.permissions.select && e.code === 'KeyA') { e.preventDefault(); this.setSelection(this.nodes.slice()); return; }\n // Ctrl+Z = undo; Ctrl+Y or Ctrl+Shift+Z = redo. Routed through a handler rather than\n // called directly: a component wrapping this renderer has its own rules about when\n // history may run and its own events to announce it, and the keyboard must obey them\n // like every other entry point.\n if (mod && this.permissions.history && e.code === 'KeyZ' && !e.shiftKey) { e.preventDefault(); this.historyShortcut('undo'); return; }\n if (mod && this.permissions.history && (e.code === 'KeyY' || (e.code === 'KeyZ' && e.shiftKey))) {\n e.preventDefault(); this.historyShortcut('redo'); return;\n }\n });\n }\n\n // ---- drawing ----------------------------------------------------\n private scheduleDraw(): void {\n if (this.destroyed || this.drawScheduled) return;\n this.drawScheduled = true;\n requestAnimationFrame(() => {\n this.drawScheduled = false;\n if (!this.destroyed) this.draw();\n });\n }\n private draw(options: DiagramRenderOptions = SCREEN_RENDER_OPTIONS): void {\n const ctx = this.ctx;\n ctx.clearRect(0, 0, this.width, this.height);\n const background = this.opts.background ?? '#1b1b1f';\n ctx.fillStyle = background;\n ctx.fillRect(0, 0, this.width, this.height);\n // Read here rather than per socket: an export swaps the background for the duration of\n // one draw, so this is the only point that sees the colour the sockets land on.\n this.portOutline = readableOutlineOn(background);\n // Entrance animation \u2014 scheme rises from below + fades in over\n // the opaque background.\n let introDy = 0;\n let introAlpha = 1;\n if (options.transient && this.introStart !== null) {\n const e = Math.min(1, (performance.now() - this.introStart) / INTRO_MS);\n const k = 1 - Math.pow(1 - e, 3); // easeOutCubic\n introAlpha = k;\n introDy = (1 - k) * INTRO_RISE;\n if (e >= 1) this.introStart = null;\n }\n ctx.save();\n ctx.globalAlpha = introAlpha;\n if (options.grid) this.drawGrid();\n ctx.setTransform(this.dpr * this.scale, 0, 0, this.dpr * this.scale,\n this.dpr * this.offX, this.dpr * (this.offY + introDy));\n // Zones sit under everything: they say where things are, and a place that painted over\n // its occupants would be worse than no place at all.\n this.drawZones();\n // Links next. Each link jumps over the verticals of the links\n // drawn before it (deterministic bridge \u2014 Link.JumpOver parity).\n const prior: Seg[] = []; // segments of links already drawn\n const hoveredNode = this.hoverPort?.node ?? this.hoverNode;\n for (const l of this.links) {\n const a = this.endpoint(l, 'from');\n const b = this.endpoint(l, 'to');\n if (a === null || b === null) continue;\n const fp = this.nodes.find((n) => n.id === l.from)?.outPorts.find((p) => p.id === l.fromPort);\n const baseColor = (this.opts.typedLinkColors ?? false) && fp !== undefined\n ? this.portColor(fp.type)\n : this.portColor('');\n const state = options.selection && l === this.selectedLink\n ? 'sel'\n : options.transient && (l === this.hoveredLink\n || (hoveredNode !== null && (l.from === hoveredNode.id || l.to === hoveredNode.id)))\n ? 'hov'\n : 'norm';\n const color = state === 'sel' ? this.selectionColor() : state === 'hov' ? this.linkHoverColor() : baseColor;\n const width = state === 'sel' ? 3 : state === 'hov' ? 2.6 : 2;\n const pts = this.routeLink(a, b, new Set([l.from, l.to]));\n this.strokeRoute(pts, color, width, prior, l.style);\n this.drawArrow(pts, color);\n for (let k = 1; k < pts.length; k += 1) {\n const [x1, y1] = pts[k - 1];\n const [x2, y2] = pts[k];\n if (x1 === x2 && y1 !== y2) prior.push({ h: false, c: x1, a: Math.min(y1, y2), b: Math.max(y1, y2) });\n else if (y1 === y2 && x1 !== x2) prior.push({ h: true, c: y1, a: Math.min(x1, x2), b: Math.max(x1, x2) });\n }\n }\n if (options.transient && (this.linking !== null || this.relinking !== null)) this.drawPendingLink();\n this.portFeed = this.feedTypes();\n for (const n of this.nodes) this.drawNode(n, options.selection && this.selectedNodes.has(n), options);\n if (options.selection && this.permissions.createLinks && this.relinking === null)\n this.drawSelectedLinkEndpoints();\n if (options.transient && this.rubber !== null) {\n const rx = Math.min(this.rubber.x0, this.rubber.x);\n const ry = Math.min(this.rubber.y0, this.rubber.y);\n const rw = Math.abs(this.rubber.x - this.rubber.x0);\n const rh = Math.abs(this.rubber.y - this.rubber.y0);\n ctx.fillStyle = 'rgba(74,163,255,0.12)';\n ctx.fillRect(rx, ry, rw, rh);\n ctx.strokeStyle = '#4aa3ff';\n ctx.lineWidth = 1 / this.scale;\n ctx.strokeRect(rx, ry, rw, rh);\n }\n ctx.restore();\n if (options.overview) this.drawOverview();\n if (options.runtime) this.drawGlobalError(options.transient);\n if (options.transient) this.drawTooltip();\n if (options.transient && (this.introStart !== null || this.globalErrorFlashStart !== null\n || this.nodes.some((n) => n.errorFlashStart !== null)))\n this.scheduleDraw(); // keep entrance / error feedback animating\n }\n /**\n * `transient` gates the flash exactly as it gates every other animation, which an export must\n * not see: it would bake in whatever point of the pulse it caught, so the same export taken\n * twice differed in opacity. The gate also keeps the export from consuming the animation --\n * clearing globalErrorFlashStart from an export cut the flash short on screen.\n */\n private drawGlobalError(transient: boolean): void {\n const error = this.runtimeState.globalError;\n if (error === null) return;\n const ctx = this.ctx;\n let flashAlpha = 1;\n if (transient && this.globalErrorFlashStart !== null) {\n const elapsed = performance.now() - this.globalErrorFlashStart;\n if (elapsed >= ERROR_FLASH_MS) {\n this.globalErrorFlashStart = null;\n } else {\n flashAlpha = 0.7 + 0.3 * (0.5 + 0.5 * Math.sin(\n elapsed / ERROR_FLASH_MS * Math.PI * 6 - Math.PI / 2));\n }\n }\n const neutral = error.kind === 'locked' || error.kind === 'encrypted';\n ctx.save();\n ctx.globalAlpha = flashAlpha;\n ctx.fillStyle = neutral ? 'rgba(18,20,26,0.82)' : 'rgba(55,16,22,0.78)';\n ctx.fillRect(0, 0, this.width, this.height);\n ctx.font = '600 15px Segoe UI, Tahoma, sans-serif';\n const lines = this.wrapTooltip(error.message, Math.max(120, Math.min(520, this.width - 80)));\n const lineHeight = 21;\n const boxWidth = Math.min(this.width - 32,\n Math.max(180, ...lines.map((line) => ctx.measureText(line).width + 36)));\n const boxHeight = lines.length * lineHeight + 32;\n const x = (this.width - boxWidth) / 2;\n const y = (this.height - boxHeight) / 2;\n roundRect(ctx, x, y, boxWidth, boxHeight, 8);\n ctx.fillStyle = neutral ? 'rgba(36,39,48,0.98)' : 'rgba(75,22,31,0.98)';\n ctx.fill();\n ctx.strokeStyle = neutral ? '#858b98' : ERROR_RED;\n ctx.lineWidth = 2;\n ctx.stroke();\n ctx.fillStyle = '#ffffff';\n ctx.textAlign = 'center';\n ctx.textBaseline = 'middle';\n lines.forEach((line, index) => {\n ctx.fillText(line, this.width / 2, y + 16 + lineHeight * index + lineHeight / 2);\n });\n ctx.restore();\n }\n private drawTooltip(): void {\n if (!this.tipShow) return; // wait out the hover delay\n if (this.dragNode !== null || this.linking !== null || this.relinking !== null || this.panning || this.ovDragging) return;\n let text = '';\n let isError = false;\n if (this.hoverPort !== null) {\n const p = this.hoverPort.port;\n text = p.type ? `${p.name} \u00B7 ${p.type}` : p.name;\n const runtime = this.portRuntimeState(this.hoverPort.node, p);\n if (runtime?.value !== null && runtime?.value !== undefined) text += `\\nValue: ${runtime.value}`;\n if (runtime?.error !== null && runtime?.error !== undefined) {\n text += `\\n${runtime.error}`;\n isError = true;\n }\n } else if (this.hoverNode !== null) {\n const n = this.hoverNode;\n const errors = [n.runtimeError, n.loadError].filter((value) => value.length > 0);\n if (errors.length > 0) {\n text = errors.join('\\n');\n isError = true;\n } else if (this.showNodeMessages && n.message.length > 0) {\n text = n.message;\n } else if (n.description.length > 0) {\n text = n.description;\n } else {\n text = n.typeId && n.typeId !== n.name ? `${n.name} [${n.typeId}]` : n.name;\n }\n } else {\n return;\n }\n const ctx = this.ctx;\n ctx.font = '11px Segoe UI, Tahoma, sans-serif';\n const padX = 9;\n const padY = 6;\n const lineH = 15;\n const lines = this.wrapTooltip(text, 340);\n const h = lines.length * lineH + padY * 2;\n const w = Math.max(...lines.map((line) => ctx.measureText(line).width)) + padX * 2;\n let x = this.cursor.x + 14;\n let y = this.cursor.y + 18;\n if (x + w > this.width) x = this.width - w - 4;\n if (y + h > this.height) y = this.cursor.y - h - 10;\n roundRect(ctx, x, y, w, h, 4);\n ctx.fillStyle = isError ? 'rgba(55,16,22,0.97)' : 'rgba(18,20,26,0.96)';\n ctx.fill();\n ctx.lineWidth = 1;\n ctx.strokeStyle = isError ? ERROR_RED : '#3a3a46';\n ctx.stroke();\n ctx.fillStyle = '#e8e8ee';\n ctx.textBaseline = 'middle';\n ctx.textAlign = 'left';\n lines.forEach((line, index) => {\n ctx.fillText(line, x + padX, y + padY + lineH * index + lineH / 2);\n });\n }\n private wrapTooltip(text: string, maxWidth: number): string[] {\n const lines: string[] = [];\n for (const paragraph of text.split(/\\r?\\n/)) {\n const words = paragraph.split(/\\s+/).filter(Boolean);\n if (words.length === 0) { lines.push(''); continue; }\n let line = words[0];\n for (let i = 1; i < words.length; i += 1) {\n const next = `${line} ${words[i]}`;\n if (this.ctx.measureText(next).width <= maxWidth) line = next;\n else { lines.push(line); line = words[i]; }\n }\n lines.push(line);\n }\n return lines.length > 0 ? lines : [''];\n }\n private drawZones(): void {\n if (this.zones.length === 0) return;\n\n const ctx = this.ctx;\n\n for (const zone of this.zones) {\n const tint = zone.color.length > 0 ? zone.color : (this.opts.zoneColor ?? '#8a8f98');\n ctx.save();\n roundRect(ctx, zone.x, zone.y, zone.width, zone.height, 10);\n ctx.globalAlpha = 0.12;\n ctx.fillStyle = tint;\n ctx.fill();\n ctx.globalAlpha = 0.5;\n ctx.setLineDash([10, 6]);\n ctx.lineWidth = 1.5;\n ctx.strokeStyle = tint;\n ctx.stroke();\n ctx.restore();\n\n if (zone.name.length === 0) continue;\n\n ctx.save();\n ctx.globalAlpha = 0.75;\n ctx.fillStyle = tint;\n ctx.font = '600 12px Segoe UI, Tahoma, sans-serif';\n ctx.textAlign = 'left';\n ctx.textBaseline = 'top';\n // Inside the top-left corner: a caption outside the box would collide with whatever\n // sits above it, and the corner is the one spot a rectangle always has to spare.\n ctx.fillText(zone.name, zone.x + 12, zone.y + 9, Math.max(0, zone.width - 24));\n ctx.restore();\n }\n }\n\n private drawGrid(): void {\n const ctx = this.ctx;\n const step = this.gridSize * this.scale;\n if (step < 6) return;\n ctx.strokeStyle = this.opts.gridColor ?? '#26262c';\n ctx.lineWidth = 1;\n const ox = this.offX % step;\n const oy = this.offY % step;\n ctx.beginPath();\n for (let x = ox; x < this.width; x += step) { ctx.moveTo(x + 0.5, 0); ctx.lineTo(x + 0.5, this.height); }\n for (let y = oy; y < this.height; y += step) { ctx.moveTo(0, y + 0.5); ctx.lineTo(this.width, y + 0.5); }\n ctx.stroke();\n }\n // Lazily load + cache a node-icon image by URL; repaints once it decodes.\n private getIcon(url: string): HTMLImageElement | null {\n const cached = this.iconCache.get(url);\n if (cached !== undefined) return cached; // img = ready; null = loading/failed\n this.iconCache.set(url, null); // mark in-flight to avoid duplicate loads\n const img = new Image();\n img.onload = () => { this.iconCache.set(url, img); this.scheduleDraw(); };\n img.onerror = () => { this.iconCache.set(url, null); };\n img.src = url;\n return null;\n }\n private drawNode(n: NodeModel, selected: boolean, options: DiagramRenderOptions): void {\n const ctx = this.ctx;\n const hasLoadError = options.runtime && n.loadError.length > 0;\n const hasRuntimeError = options.runtime && n.runtimeError.length > 0;\n const runtime = options.runtime ? getJsonKey(this.runtimeState.nodes, n.id) : undefined;\n const active = options.runtime\n && (this.runtimeState.activeNodeId === n.id || runtime?.active === true);\n roundRect(ctx, n.x, n.y, n.w, n.h, 6);\n ctx.fillStyle = hasLoadError ? ERROR_BACKGROUND : active ? '#ffd1dc' : n.color;\n ctx.fill();\n ctx.lineWidth = selected ? 2 : 1.5;\n ctx.strokeStyle = selected ? this.selectionColor() : n.border;\n ctx.stroke();\n if (hasLoadError || hasRuntimeError) {\n let alpha = 1;\n if (options.transient && hasRuntimeError && n.errorFlashStart !== null) {\n const elapsed = performance.now() - n.errorFlashStart;\n if (elapsed >= ERROR_FLASH_MS) {\n n.errorFlashStart = null;\n } else {\n // Three clear pulses before the border settles on red.\n alpha = 0.12 + 0.88 * (0.5 + 0.5 * Math.sin(\n elapsed / ERROR_FLASH_MS * Math.PI * 6 - Math.PI / 2));\n }\n }\n ctx.save();\n ctx.globalAlpha *= alpha;\n roundRect(ctx, n.x, n.y, n.w, n.h, 6);\n ctx.lineWidth = hasRuntimeError ? 3 : 2;\n ctx.strokeStyle = ERROR_RED;\n ctx.stroke();\n ctx.restore();\n }\n // Element icon on the left, vertically centred (lazy-loaded, cached).\n const iconW = 18;\n if (n.icon) {\n const img = this.getIcon(n.icon);\n if (img) { try { ctx.drawImage(img, n.x + 8, n.y + (n.h - iconW) / 2, iconW, iconW); } catch { /* undecodable */ } }\n }\n // Bold title centred on the body (nudged right when an icon shows so they\n // don't overlap); ports are bare colour squares on the edges. The title\n // takes its colour from the fill it sits on: that fill comes from the\n // scheme, so a node may well be darker than the title used to assume.\n const titleShift = n.icon ? iconW + 4 : 0;\n ctx.fillStyle = hasLoadError\n ? '#ffffff'\n : readableTextOn(active ? '#ffd1dc' : n.color);\n ctx.font = '600 12px Segoe UI, Tahoma, sans-serif';\n ctx.textAlign = 'center';\n ctx.textBaseline = 'middle';\n ctx.fillText(n.name, n.x + titleShift + (n.w - titleShift) / 2, n.y + n.h / 2, n.w - titleShift - 14);\n for (const p of n.inPorts) this.drawPort(n, p, options);\n for (const p of n.outPorts) this.drawPort(n, p, options);\n }\n private drawPort(node: NodeModel, p: PortModel, options: DiagramRenderOptions): void {\n const ctx = this.ctx;\n const hovered = options.transient && this.hoverPort?.port === p;\n const magnet = options.transient && this.linkSnap?.port === p;\n const runtime = options.runtime ? this.portRuntimeState(node, p) : null;\n const s = magnet ? PORT_SQ + 4 : hovered ? PORT_SQ + 2 : PORT_SQ;\n const x = p.cx - s / 2;\n const y = p.cy - s / 2;\n const r = Math.min(2.5, s / 4);\n if (magnet) {\n roundRect(ctx, x - 4, y - 4, s + 8, s + 8, r + 2);\n ctx.fillStyle = 'rgba(255,255,255,0.16)';\n ctx.fill();\n }\n // Single rounded path filled + stroked (aligned, anti-aliased \u2014\n // no half-pixel double edge).\n roundRect(ctx, x, y, s, s, r);\n ctx.fillStyle = this.portColor(this.portFillType(p));\n ctx.fill();\n ctx.lineWidth = magnet ? 1.5 : 1;\n ctx.strokeStyle = magnet ? '#ffffff' : this.portOutline;\n ctx.stroke();\n const runtimeSelected = runtime?.selected === true || (options.selection && this.selectedPort?.port === p);\n const breakpoint = runtime?.breakpoint === true;\n const breakpointActive = runtime?.breakpointActive === true;\n const runtimeActive = runtime?.active === true;\n const hasError = runtime?.error !== null && runtime?.error !== undefined;\n if (runtimeSelected || breakpoint || breakpointActive || runtimeActive || hasError) {\n ctx.beginPath();\n ctx.arc(p.cx, p.cy, s / 2 + 4, 0, Math.PI * 2);\n if (breakpointActive) {\n ctx.fillStyle = '#8b0000';\n ctx.fill();\n } else if (runtimeSelected) {\n ctx.fillStyle = 'rgba(211,211,211,0.56)';\n ctx.fill();\n }\n ctx.lineWidth = 2;\n ctx.strokeStyle = hasError || breakpointActive ? ERROR_RED\n : breakpoint ? '#ffb6c1'\n : runtimeActive ? '#ffffff'\n : '#d3d3d3';\n ctx.stroke();\n }\n }\n private portRuntimeState(node: NodeModel, port: PortModel): DiagramPortRuntimeState | null {\n return getJsonKey(this.runtimeState.nodes, node.id)?.ports[port.direction][port.id] ?? null;\n }\n // Symmetric jump-over: any segment of THIS link hops the perpendicular\n // segments of links drawn before it (H over earlier V, V over earlier\n // H). Exactly one bridge per real crossing, consistent everywhere.\n private strokeRoute(pts: number[][], color: string, width: number, prior: Seg[], style: DiagramLinkStyle = 'solid'): void {\n const ctx = this.ctx;\n ctx.strokeStyle = color;\n ctx.lineWidth = width;\n // The dash is measured in world units, so it keeps its rhythm as the canvas is zoomed.\n if (style === 'dashed') ctx.setLineDash([9, 6]);\n ctx.lineJoin = 'miter';\n ctx.lineCap = 'butt';\n ctx.beginPath();\n ctx.moveTo(pts[0][0], pts[0][1]);\n const H = LINK_HOP;\n // End a segment at its elbow with a rounded corner toward the next point (arcTo), clamped so it never\n // eats more than half of either adjacent segment. The final segment ends straight into the port.\n const finish = (i: number, x1: number, y1: number, x2: number, y2: number): void => {\n if (i < pts.length - 1) {\n const nx = pts[i + 1][0];\n const ny = pts[i + 1][1];\n const seg1 = Math.abs(x2 - x1) + Math.abs(y2 - y1);\n const seg2 = Math.abs(nx - x2) + Math.abs(ny - y2);\n ctx.arcTo(x2, y2, nx, ny, Math.min(LINK_CORNER, seg1 / 2, seg2 / 2));\n } else {\n ctx.lineTo(x2, y2);\n }\n };\n for (let i = 1; i < pts.length; i += 1) {\n const [x1, y1] = pts[i - 1];\n const [x2, y2] = pts[i];\n if (y1 === y2 && x1 !== x2) {\n const dir = x2 > x1 ? 1 : -1;\n const cuts = prior\n .filter((s) => !s.h && s.a < y1 - 0.5 && y1 + 0.5 < s.b &&\n Math.min(x1, x2) + H < s.c && s.c < Math.max(x1, x2) - H)\n .map((s) => s.c)\n .sort((p, q) => dir * (p - q));\n for (const cx of cuts) {\n ctx.lineTo(cx - dir * H, y1);\n if (dir > 0) ctx.arc(cx, y1, H, Math.PI, 2 * Math.PI, false);\n else ctx.arc(cx, y1, H, 0, Math.PI, true);\n }\n finish(i, x1, y1, x2, y2);\n } else if (x1 === x2 && y1 !== y2) {\n const dir = y2 > y1 ? 1 : -1;\n const cuts = prior\n .filter((s) => s.h && s.a < x1 - 0.5 && x1 + 0.5 < s.b &&\n Math.min(y1, y2) + H < s.c && s.c < Math.max(y1, y2) - H)\n .map((s) => s.c)\n .sort((p, q) => dir * (p - q));\n for (const cy of cuts) {\n ctx.lineTo(x1, cy - dir * H);\n if (dir > 0) ctx.arc(x1, cy, H, -Math.PI / 2, Math.PI / 2, false);\n else ctx.arc(x1, cy, H, Math.PI / 2, -Math.PI / 2, true);\n }\n finish(i, x1, y1, x2, y2);\n } else {\n ctx.lineTo(x2, y2);\n }\n }\n ctx.stroke();\n ctx.setLineDash([]);\n }\n private drawArrow(pts: number[][], color: string): void {\n const n = pts.length;\n const [px, py] = pts[n - 2];\n const [ex, ey] = pts[n - 1];\n const ang = Math.atan2(ey - py, ex - px);\n const ctx = this.ctx;\n ctx.save();\n ctx.translate(ex, ey);\n ctx.rotate(ang);\n ctx.fillStyle = color;\n ctx.beginPath();\n ctx.moveTo(0, 0); ctx.lineTo(-9, -4.5); ctx.lineTo(-9, 4.5); ctx.closePath();\n ctx.fill();\n ctx.restore();\n }\n private drawSelectedLinkEndpoints(): void {\n if (this.selectedLink === null) return;\n const ctx = this.ctx;\n const halfSize = RELINK_HANDLE_PX / 2 / this.scale;\n for (const end of ['from', 'to'] as const) {\n const point = this.endpoint(this.selectedLink, end);\n if (point === null) continue;\n ctx.beginPath();\n ctx.moveTo(point[0], point[1] - halfSize);\n ctx.lineTo(point[0] + halfSize, point[1]);\n ctx.lineTo(point[0], point[1] + halfSize);\n ctx.lineTo(point[0] - halfSize, point[1]);\n ctx.closePath();\n ctx.fillStyle = '#00ffff';\n ctx.fill();\n ctx.strokeStyle = '#000000';\n ctx.lineWidth = 1 / this.scale;\n ctx.stroke();\n }\n }\n private drawPendingLink(): void {\n if (this.linking === null && this.relinking === null) return;\n const ctx = this.ctx;\n const snapped = this.linkSnap;\n const cursor = this.toWorld(this.cursor.x, this.cursor.y) as [number, number];\n let a: [number, number];\n let b: [number, number];\n let colorType = '';\n let snapPoint: [number, number] | null = null;\n const excludedNodes = new Set<string>();\n\n if (this.linking !== null) {\n a = [this.linking.port.cx, this.linking.port.cy];\n b = snapped === null ? cursor : [snapped.port.cx, snapped.port.cy];\n colorType = this.linking.port.type;\n excludedNodes.add(this.linking.node.id);\n if (snapped !== null) snapPoint = b;\n } else {\n const gesture = this.relinking!;\n const fixed = this.endpoint(gesture.link, gesture.end === 'from' ? 'to' : 'from');\n if (fixed === null) return;\n const sourcePort = this.nodes.find((node) => node.id === gesture.link.from)?.outPorts\n .find((port) => port.id === gesture.link.fromPort);\n if (gesture.end === 'from') {\n a = snapped === null ? cursor : [snapped.port.cx, snapped.port.cy];\n b = fixed;\n colorType = snapped?.port.type ?? sourcePort?.type ?? '';\n excludedNodes.add(gesture.link.to);\n if (snapped !== null) snapPoint = a;\n } else {\n a = fixed;\n b = snapped === null ? cursor : [snapped.port.cx, snapped.port.cy];\n colorType = sourcePort?.type ?? '';\n excludedNodes.add(gesture.link.from);\n if (snapped !== null) snapPoint = b;\n }\n }\n if (snapped !== null) excludedNodes.add(snapped.node.id);\n const points = this.routeLink(a, b, excludedNodes);\n ctx.strokeStyle = this.portColor(colorType);\n if (snapped !== null) { ctx.setLineDash([]); ctx.lineWidth = 2.6; }\n else { ctx.setLineDash([5, 4]); ctx.lineWidth = 2; }\n ctx.beginPath();\n ctx.moveTo(points[0][0], points[0][1]);\n for (let index = 1; index < points.length; index += 1) ctx.lineTo(points[index][0], points[index][1]);\n ctx.stroke();\n ctx.setLineDash([]);\n if (snapPoint !== null) {\n ctx.beginPath();\n ctx.arc(snapPoint[0], snapPoint[1], PORT_R + 4, 0, Math.PI * 2);\n ctx.strokeStyle = '#ffffff';\n ctx.lineWidth = 2;\n ctx.stroke();\n }\n }\n\n // ---- overview minimap -------------------------------------------\n private overviewRect(): { x: number; y: number; w: number; h: number } | null {\n if (!this.overviewVisible || this.width < 320 || this.height < 220) return null;\n const w = 190, h = 130, m = 14;\n return { x: this.width - w - m, y: this.height - h - m, w, h };\n }\n private drawOverview(): void {\n const r = this.overviewRect();\n const gb = this.graphBounds();\n if (r === null || gb === null) { this.ovGeo = null; return; }\n const ctx = this.ctx;\n const pad = 8;\n const gw = (gb.maxX - gb.minX) || 1;\n const gh = (gb.maxY - gb.minY) || 1;\n const s = Math.min((r.w - pad * 2) / gw, (r.h - pad * 2) / gh);\n const ox = r.x + pad + ((r.w - pad * 2) - gw * s) / 2;\n const oy = r.y + pad + ((r.h - pad * 2) - gh * s) / 2;\n this.ovGeo = { x: ox, y: oy, w: r.w, h: r.h, s, minX: gb.minX, minY: gb.minY };\n const mx = (wx: number): number => ox + (wx - gb.minX) * s;\n const my = (wy: number): number => oy + (wy - gb.minY) * s;\n const light = colorLuminance(this.opts.background) >= 150;\n const overviewBackground = this.opts.overviewBackground\n ?? (light ? 'rgba(255,255,255,0.94)' : 'rgba(16,16,20,0.88)');\n const overviewBorder = this.opts.overviewBorderColor\n ?? (light ? '#cbd5e1' : '#3a3a44');\n const viewportColor = this.opts.overviewViewportColor\n ?? (light ? '#d97706' : '#4aa3ff');\n const viewportFill = this.opts.overviewViewportFill\n ?? (light ? 'rgba(217,119,6,0.10)' : 'rgba(74,163,255,0.10)');\n\n ctx.save();\n roundRect(ctx, r.x, r.y, r.w, r.h, 6);\n ctx.fillStyle = overviewBackground;\n ctx.fill();\n ctx.strokeStyle = overviewBorder;\n ctx.lineWidth = 1;\n ctx.stroke();\n ctx.clip();\n for (const n of this.nodes) {\n ctx.fillStyle = n.color;\n ctx.fillRect(mx(n.x), my(n.y), Math.max(2, n.w * s), Math.max(2, n.h * s));\n ctx.strokeStyle = n.border;\n ctx.lineWidth = 1;\n ctx.strokeRect(mx(n.x), my(n.y), Math.max(2, n.w * s), Math.max(2, n.h * s));\n }\n // viewport rectangle (what the main canvas currently shows)\n const [vx0, vy0] = this.toWorld(0, 0);\n const [vx1, vy1] = this.toWorld(this.width, this.height);\n ctx.strokeStyle = viewportColor;\n ctx.lineWidth = 1.5;\n ctx.strokeRect(mx(vx0), my(vy0), (vx1 - vx0) * s, (vy1 - vy0) * s);\n ctx.fillStyle = viewportFill;\n ctx.fillRect(mx(vx0), my(vy0), (vx1 - vx0) * s, (vy1 - vy0) * s);\n ctx.restore();\n }\n private ovHit(sx: number, sy: number): boolean {\n const r = this.overviewRect();\n return r !== null && sx >= r.x && sx <= r.x + r.w && sy >= r.y && sy <= r.y + r.h;\n }\n private ovPanTo(sx: number, sy: number): void {\n if (this.ovGeo === null) return;\n const g = this.ovGeo;\n const wx = g.minX + (sx - g.x) / g.s;\n const wy = g.minY + (sy - g.y) / g.s;\n this.offX = this.width / 2 - wx * this.scale;\n this.offY = this.height / 2 - wy * this.scale;\n this.scheduleDraw();\n }\n\n private emitViewChanged(zoomChanged: boolean): void {\n if (zoomChanged) this.emit('zoomChanged', { scale: this.scale });\n this.emit('viewChanged', this.getViewState());\n }\n}\n\nfunction roundRect(ctx: DrawSurface, x: number, y: number, w: number, h: number, r: number): void {\n const rr = Math.min(r, w / 2, h / 2);\n ctx.beginPath();\n ctx.moveTo(x + rr, y);\n ctx.arcTo(x + w, y, x + w, y + h, rr);\n ctx.arcTo(x + w, y + h, x, y + h, rr);\n ctx.arcTo(x, y + h, x, y, rr);\n ctx.arcTo(x, y, x + w, y, rr);\n ctx.closePath();\n}\n// Orthogonal route out-port \u2192 in-port. Forward (target to the right):\n// a 3-segment mid-X elbow. Backward/too-close: a 5-segment detour that\n// leaves the source rightward and re-enters the target from the left\n// (AvoidsNodes-style, never a diagonal).\nfunction route(a: [number, number], b: [number, number]): number[][] {\n const [ax, ay] = a;\n const [bx, by] = b;\n if (bx - ax >= LINK_STUB * 2) {\n const mx = (ax + bx) / 2;\n return [[ax, ay], [mx, ay], [mx, by], [bx, by]];\n }\n const midY = (ay + by) / 2;\n return [[ax, ay], [ax + LINK_STUB, ay], [ax + LINK_STUB, midY],\n [bx - LINK_STUB, midY], [bx - LINK_STUB, by], [bx, by]];\n}\n\n// --- AvoidsNodes routing ------------------------------------------------\n// Obstacle rects are [x,y,w,h] (already inflated by the caller). Fast\n// path: the plain elbow when it doesn't touch any box (only bend when\n// you must). Otherwise an orthogonal A* around the boxes \u2014 so a node\n// dropped on a link makes it re-route (\"push apart\") instead of passing\n// underneath.\nconst ROUTE_CELL = 14;\nconst A_STEP = 10;\nconst A_TURN = 40; // heavy turn cost \u2192 A* strongly prefers straight runs\n\ntype Rect = [number, number, number, number];\n// A drawn link segment for jump-over: h = horizontal (line y=c, x\u2208[a,b]),\n// else vertical (line x=c, y\u2208[a,b]).\ntype Seg = { h: boolean; c: number; a: number; b: number };\n\nfunction segHitsRect(x1: number, y1: number, x2: number, y2: number, r: Rect): boolean {\n const rx2 = r[0] + r[2];\n const ry2 = r[1] + r[3];\n if (y1 === y2) {\n if (y1 <= r[1] || y1 >= ry2) return false;\n return Math.min(x1, x2) < rx2 && Math.max(x1, x2) > r[0];\n }\n if (x1 === x2) {\n if (x1 <= r[0] || x1 >= rx2) return false;\n return Math.min(y1, y2) < ry2 && Math.max(y1, y2) > r[1];\n }\n return false;\n}\nfunction polyHitsRects(pts: number[][], rects: Rect[]): boolean {\n for (let i = 1; i < pts.length; i += 1)\n for (const r of rects)\n if (segHitsRect(pts[i - 1][0], pts[i - 1][1], pts[i][0], pts[i][1], r)) return true;\n return false;\n}\nfunction orthogonalize(ps: number[][]): number[][] {\n const o: number[][] = [ps[0]];\n for (let i = 1; i < ps.length; i += 1) {\n const pr = o[o.length - 1];\n const p = ps[i];\n if (pr[0] !== p[0] && pr[1] !== p[1]) o.push([p[0], pr[1]]);\n o.push(p);\n }\n return o;\n}\nfunction collapse(ps: number[][]): number[][] {\n const o: number[][] = [];\n for (const p of ps) {\n if (o.length > 0) {\n const last = o[o.length - 1];\n if (last[0] === p[0] && last[1] === p[1]) continue;\n }\n if (o.length >= 2) {\n const a = o[o.length - 2];\n const b = o[o.length - 1];\n if ((a[0] === b[0] && b[0] === p[0]) || (a[1] === b[1] && b[1] === p[1])) {\n o[o.length - 1] = p;\n continue;\n }\n }\n o.push(p);\n }\n return o;\n}\nfunction hitsAny(x1: number, y1: number, x2: number, y2: number, rects: Rect[]): boolean {\n for (const r of rects) if (segHitsRect(x1, y1, x2, y2, r)) return true;\n return false;\n}\n// Staircase \u2192 L: repeatedly try to replace two consecutive bends with a\n// single corner when the shortcut stays orthogonal and clear of boxes.\n// Cuts the A* zig-zag down to the minimum number of bends.\nfunction simplifyOrtho(pts: number[][], rects: Rect[]): number[][] {\n let p = pts.slice();\n let changed = true;\n let guard = 0;\n while (changed && guard < 40) {\n changed = false;\n guard += 1;\n // Keep the first/last two points (port \u2192 stub) untouched so the\n // entry/exit stays a clean horizontal run into the socket.\n for (let i = 2; i + 3 < p.length; i += 1) {\n const A = p[i - 1];\n const D = p[i + 2];\n for (const E of [[D[0], A[1]], [A[0], D[1]]] as number[][]) {\n if ((E[0] === A[0] && E[1] === A[1]) || (E[0] === D[0] && E[1] === D[1])) continue;\n if (hitsAny(A[0], A[1], E[0], E[1], rects)) continue;\n if (hitsAny(E[0], E[1], D[0], D[1], rects)) continue;\n p = p.slice(0, i).concat([E], p.slice(i + 2));\n changed = true;\n break;\n }\n if (changed) break;\n }\n }\n return p;\n}\nfunction aStarGrid(start: [number, number], goal: [number, number], rects: Rect[]): number[][] | null {\n let minX = Math.min(start[0], goal[0]);\n let minY = Math.min(start[1], goal[1]);\n let maxX = Math.max(start[0], goal[0]);\n let maxY = Math.max(start[1], goal[1]);\n for (const r of rects) {\n minX = Math.min(minX, r[0]); minY = Math.min(minY, r[1]);\n maxX = Math.max(maxX, r[0] + r[2]); maxY = Math.max(maxY, r[1] + r[3]);\n }\n const pad = LINK_STUB + ROUTE_CELL * 2;\n minX -= pad; minY -= pad; maxX += pad; maxY += pad;\n let cell = ROUTE_CELL;\n let cols = Math.ceil((maxX - minX) / cell);\n let rows = Math.ceil((maxY - minY) / cell);\n const CAP = 260;\n if (cols > CAP || rows > CAP) {\n cell = Math.max((maxX - minX) / CAP, (maxY - minY) / CAP);\n cols = Math.ceil((maxX - minX) / cell);\n rows = Math.ceil((maxY - minY) / cell);\n }\n const n = cols * rows;\n if (n <= 0 || n > 80000) return null;\n const cx = (c: number): number => minX + (c + 0.5) * cell;\n const cy = (r: number): number => minY + (r + 0.5) * cell;\n const blocked = new Uint8Array(n);\n for (const r of rects) {\n const c0 = Math.max(0, Math.floor((r[0] - minX) / cell));\n const c1 = Math.min(cols - 1, Math.floor((r[0] + r[2] - minX) / cell));\n const r0 = Math.max(0, Math.floor((r[1] - minY) / cell));\n const r1 = Math.min(rows - 1, Math.floor((r[1] + r[3] - minY) / cell));\n for (let rr = r0; rr <= r1; rr += 1)\n for (let cc = c0; cc <= c1; cc += 1) blocked[rr * cols + cc] = 1;\n }\n const sc = clamp(Math.floor((start[0] - minX) / cell), 0, cols - 1);\n const sr = clamp(Math.floor((start[1] - minY) / cell), 0, rows - 1);\n const gc = clamp(Math.floor((goal[0] - minX) / cell), 0, cols - 1);\n const gr = clamp(Math.floor((goal[1] - minY) / cell), 0, rows - 1);\n const si = sr * cols + sc;\n const gi = gr * cols + gc;\n blocked[si] = 0;\n blocked[gi] = 0;\n\n const g = new Float64Array(n).fill(Infinity);\n const prev = new Int32Array(n).fill(-1);\n const dir = new Int8Array(n).fill(-1); // 0=h,1=v incoming move\n g[si] = 0;\n // binary heap of indices keyed by f\n const heap: number[] = [si];\n const f = new Float64Array(n);\n f[si] = (Math.abs(gc - sc) + Math.abs(gr - sr)) * A_STEP;\n const swap = (i: number, j: number): void => { const t = heap[i]; heap[i] = heap[j]; heap[j] = t; };\n const push = (v: number): void => {\n heap.push(v);\n let i = heap.length - 1;\n while (i > 0) { const p = (i - 1) >> 1; if (f[heap[p]] <= f[heap[i]]) break; swap(i, p); i = p; }\n };\n const pop = (): number => {\n const top = heap[0];\n const last = heap.pop() as number;\n if (heap.length > 0) {\n heap[0] = last;\n let i = 0;\n for (;;) {\n const l = 2 * i + 1;\n const r = 2 * i + 2;\n let s = i;\n if (l < heap.length && f[heap[l]] < f[heap[s]]) s = l;\n if (r < heap.length && f[heap[r]] < f[heap[s]]) s = r;\n if (s === i) break;\n swap(i, s); i = s;\n }\n }\n return top;\n };\n const seen = new Uint8Array(n);\n while (heap.length > 0) {\n const cur = pop();\n if (cur === gi) break;\n if (seen[cur]) continue;\n seen[cur] = 1;\n const ccol = cur % cols;\n const crow = (cur - ccol) / cols;\n const steps: Array<[number, number, number]> = [\n [1, 0, 0], [-1, 0, 0], [0, 1, 1], [0, -1, 1],\n ];\n for (const [dc, dr, md] of steps) {\n const nc = ccol + dc;\n const nr = crow + dr;\n if (nc < 0 || nc >= cols || nr < 0 || nr >= rows) continue;\n const ni = nr * cols + nc;\n if (blocked[ni]) continue;\n const turn = dir[cur] !== -1 && dir[cur] !== md ? A_TURN : 0;\n const ng = g[cur] + A_STEP + turn;\n if (ng < g[ni]) {\n g[ni] = ng;\n prev[ni] = cur;\n dir[ni] = md as number;\n f[ni] = ng + (Math.abs(gc - nc) + Math.abs(gr - nr)) * A_STEP;\n push(ni);\n }\n }\n }\n if (prev[gi] === -1 && gi !== si) return null;\n const out: number[][] = [];\n let p = gi;\n while (p !== -1) { out.push([cx(p % cols), cy((p - (p % cols)) / cols)]); p = prev[p]; }\n out.reverse();\n return out;\n}\nfunction routeAvoid(a: [number, number], b: [number, number], rects: Rect[]): number[][] {\n const simple = route(a, b);\n if (rects.length === 0 || !polyHitsRects(simple, rects)) return simple;\n const A2: [number, number] = [a[0] + LINK_STUB, a[1]];\n const B2: [number, number] = [b[0] - LINK_STUB, b[1]];\n const grid = aStarGrid(A2, B2, rects);\n if (grid === null) return simple;\n // Keep the approach monotonic: clamp interior X into the corridor\n // between the two stubs so the path can't overshoot past the port\n // and double back (the \u2293 \"hook\" at the socket). The vertical\n // alignment then lands cleanly at the stub X, STUB away from the\n // port \u2014 a straight horizontal entry.\n const lo = Math.min(A2[0], B2[0]);\n const hi = Math.max(A2[0], B2[0]);\n const clipped = grid.map((p) => [clamp(p[0], lo, hi), p[1]] as number[]);\n const poly = collapse(orthogonalize([a, A2, ...clipped, B2, b]));\n return collapse(simplifyOrtho(poly, rects));\n}\nfunction ptSegDist(px: number, py: number, x1: number, y1: number, x2: number, y2: number): number {\n const dx = x2 - x1;\n const dy = y2 - y1;\n const len2 = dx * dx + dy * dy;\n let t = len2 === 0 ? 0 : ((px - x1) * dx + (py - y1) * dy) / len2;\n t = clamp(t, 0, 1);\n const cx = x1 + t * dx;\n const cy = y1 + t * dy;\n return Math.hypot(px - cx, py - cy);\n}\n\nexport const version = '0.1.0';\n"],
5
+ "mappings": "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",
6
6
  "names": ["n", "n", "document", "document", "node", "n", "document", "p"]
7
7
  }