sketchmark 1.1.5 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +148 -77
- package/dist/animation/index.d.ts +2 -0
- package/dist/animation/index.d.ts.map +1 -1
- package/dist/ast/types.d.ts +14 -1
- package/dist/ast/types.d.ts.map +1 -1
- package/dist/index.cjs +279 -95
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +279 -95
- package/dist/index.js.map +1 -1
- package/dist/layout/entity-rect.d.ts +2 -0
- package/dist/layout/entity-rect.d.ts.map +1 -1
- package/dist/layout/index.d.ts +8 -0
- package/dist/layout/index.d.ts.map +1 -1
- package/dist/parser/index.d.ts +2 -1
- package/dist/parser/index.d.ts.map +1 -1
- package/dist/parser/tokenizer.d.ts.map +1 -1
- package/dist/plugins.d.ts +12 -0
- package/dist/plugins.d.ts.map +1 -0
- package/dist/render.d.ts +2 -0
- package/dist/render.d.ts.map +1 -1
- package/dist/renderer/shared.d.ts +1 -1
- package/dist/renderer/shared.d.ts.map +1 -1
- package/dist/renderer/svg/index.d.ts.map +1 -1
- package/dist/scene/index.d.ts +13 -1
- package/dist/scene/index.d.ts.map +1 -1
- package/dist/sketchmark.iife.js +279 -95
- package/dist/ui/canvas.d.ts +2 -0
- package/dist/ui/canvas.d.ts.map +1 -1
- package/dist/ui/embed.d.ts +2 -0
- package/dist/ui/embed.d.ts.map +1 -1
- package/package.json +18 -1
package/dist/sketchmark.iife.js
CHANGED
|
@@ -147,10 +147,16 @@ var AIDiagram = (function (exports) {
|
|
|
147
147
|
val += "\n";
|
|
148
148
|
else if (esc === "t")
|
|
149
149
|
val += "\t";
|
|
150
|
+
else if (esc === "r")
|
|
151
|
+
val += "\r";
|
|
150
152
|
else if (esc === "\\")
|
|
151
153
|
val += "\\";
|
|
154
|
+
else if (esc === q)
|
|
155
|
+
val += q;
|
|
156
|
+
else if (esc)
|
|
157
|
+
val += `\\${esc}`;
|
|
152
158
|
else
|
|
153
|
-
val +=
|
|
159
|
+
val += "\\";
|
|
154
160
|
}
|
|
155
161
|
else
|
|
156
162
|
val += src[i];
|
|
@@ -227,6 +233,47 @@ var AIDiagram = (function (exports) {
|
|
|
227
233
|
return tokens;
|
|
228
234
|
}
|
|
229
235
|
|
|
236
|
+
function pluginMessage(plugin, stage, error) {
|
|
237
|
+
const detail = error instanceof Error ? error.message : String(error);
|
|
238
|
+
return `Plugin "${plugin.name}" ${stage} failed: ${detail}`;
|
|
239
|
+
}
|
|
240
|
+
function applyPluginPreprocessors(source, plugins = []) {
|
|
241
|
+
let nextSource = source;
|
|
242
|
+
for (const plugin of plugins) {
|
|
243
|
+
if (!plugin.preprocess)
|
|
244
|
+
continue;
|
|
245
|
+
try {
|
|
246
|
+
const transformed = plugin.preprocess(nextSource);
|
|
247
|
+
if (typeof transformed !== "string") {
|
|
248
|
+
throw new Error("preprocess must return a string");
|
|
249
|
+
}
|
|
250
|
+
nextSource = transformed;
|
|
251
|
+
}
|
|
252
|
+
catch (error) {
|
|
253
|
+
throw new Error(pluginMessage(plugin, "preprocess", error));
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
return nextSource;
|
|
257
|
+
}
|
|
258
|
+
function applyPluginAstTransforms(ast, plugins = []) {
|
|
259
|
+
let nextAst = ast;
|
|
260
|
+
for (const plugin of plugins) {
|
|
261
|
+
if (!plugin.transformAst)
|
|
262
|
+
continue;
|
|
263
|
+
try {
|
|
264
|
+
const transformed = plugin.transformAst(nextAst);
|
|
265
|
+
if (!transformed || transformed.kind !== "diagram") {
|
|
266
|
+
throw new Error('transformAst must return a DiagramAST with kind="diagram"');
|
|
267
|
+
}
|
|
268
|
+
nextAst = transformed;
|
|
269
|
+
}
|
|
270
|
+
catch (error) {
|
|
271
|
+
throw new Error(pluginMessage(plugin, "transformAst", error));
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
return nextAst;
|
|
275
|
+
}
|
|
276
|
+
|
|
230
277
|
// ============================================================
|
|
231
278
|
// sketchmark - Parser (Tokens -> DiagramAST)
|
|
232
279
|
// ============================================================
|
|
@@ -313,9 +360,10 @@ var AIDiagram = (function (exports) {
|
|
|
313
360
|
function isPropKeyToken(t) {
|
|
314
361
|
return !!t && (t.type === "IDENT" || t.type === "KEYWORD");
|
|
315
362
|
}
|
|
316
|
-
function parse(src) {
|
|
363
|
+
function parse(src, options = {}) {
|
|
317
364
|
resetUid();
|
|
318
|
-
const
|
|
365
|
+
const preparedSource = applyPluginPreprocessors(src, options.plugins);
|
|
366
|
+
const tokens = tokenize$1(preparedSource).filter((t) => t.type !== "NEWLINE" || t.value === "\n");
|
|
319
367
|
const flat = [];
|
|
320
368
|
let lastNL = false;
|
|
321
369
|
for (const t of tokens) {
|
|
@@ -498,6 +546,7 @@ var AIDiagram = (function (exports) {
|
|
|
498
546
|
const toks = lineTokens();
|
|
499
547
|
const id = requireExplicitId(keywordTok, toks);
|
|
500
548
|
const props = parseSimpleProps(toks, 1);
|
|
549
|
+
const meta = extractNodeMeta(props);
|
|
501
550
|
const node = {
|
|
502
551
|
kind: "node",
|
|
503
552
|
id,
|
|
@@ -505,11 +554,14 @@ var AIDiagram = (function (exports) {
|
|
|
505
554
|
label: props.label || "",
|
|
506
555
|
...(props.width ? { width: parseFloat(props.width) } : {}),
|
|
507
556
|
...(props.height ? { height: parseFloat(props.height) } : {}),
|
|
557
|
+
...(props.x ? { x: parseFloat(props.x) } : {}),
|
|
558
|
+
...(props.y ? { y: parseFloat(props.y) } : {}),
|
|
508
559
|
...(props.deg ? { deg: parseFloat(props.deg) } : {}),
|
|
509
560
|
...(props.dx ? { dx: parseFloat(props.dx) } : {}),
|
|
510
561
|
...(props.dy ? { dy: parseFloat(props.dy) } : {}),
|
|
511
562
|
...(props.factor ? { factor: parseFloat(props.factor) } : {}),
|
|
512
563
|
...(props.theme ? { theme: props.theme } : {}),
|
|
564
|
+
...(meta ? { meta } : {}),
|
|
513
565
|
style: propsToStyle(props),
|
|
514
566
|
};
|
|
515
567
|
if (props.url)
|
|
@@ -534,17 +586,32 @@ var AIDiagram = (function (exports) {
|
|
|
534
586
|
j = 2;
|
|
535
587
|
}
|
|
536
588
|
Object.assign(props, parseSimpleProps(toks, j));
|
|
589
|
+
const meta = extractNodeMeta(props);
|
|
537
590
|
return {
|
|
538
591
|
kind: "node",
|
|
539
592
|
id,
|
|
540
593
|
shape: "note",
|
|
541
594
|
label: (props.label ?? "").replace(/\\n/g, "\n"),
|
|
542
595
|
theme: props.theme,
|
|
596
|
+
...(meta ? { meta } : {}),
|
|
543
597
|
style: propsToStyle(props),
|
|
544
598
|
...(props.width ? { width: parseFloat(props.width) } : {}),
|
|
545
599
|
...(props.height ? { height: parseFloat(props.height) } : {}),
|
|
600
|
+
...(props.x ? { x: parseFloat(props.x) } : {}),
|
|
601
|
+
...(props.y ? { y: parseFloat(props.y) } : {}),
|
|
602
|
+
...(props.deg ? { deg: parseFloat(props.deg) } : {}),
|
|
603
|
+
...(props.dx ? { dx: parseFloat(props.dx) } : {}),
|
|
604
|
+
...(props.dy ? { dy: parseFloat(props.dy) } : {}),
|
|
605
|
+
...(props.factor ? { factor: parseFloat(props.factor) } : {}),
|
|
546
606
|
};
|
|
547
607
|
}
|
|
608
|
+
function extractNodeMeta(props) {
|
|
609
|
+
const meta = {};
|
|
610
|
+
if (props["animation-parent"]) {
|
|
611
|
+
meta.animationParent = props["animation-parent"];
|
|
612
|
+
}
|
|
613
|
+
return Object.keys(meta).length ? meta : undefined;
|
|
614
|
+
}
|
|
548
615
|
function parseGroup() {
|
|
549
616
|
const keywordTok = cur();
|
|
550
617
|
skip();
|
|
@@ -582,6 +649,8 @@ var AIDiagram = (function (exports) {
|
|
|
582
649
|
justify: props.justify,
|
|
583
650
|
theme: props.theme,
|
|
584
651
|
style: propsToStyle(props),
|
|
652
|
+
x: props.x !== undefined ? parseFloat(props.x) : undefined,
|
|
653
|
+
y: props.y !== undefined ? parseFloat(props.y) : undefined,
|
|
585
654
|
width: props.width !== undefined ? parseFloat(props.width) : undefined,
|
|
586
655
|
height: props.height !== undefined ? parseFloat(props.height) : undefined,
|
|
587
656
|
};
|
|
@@ -615,6 +684,8 @@ var AIDiagram = (function (exports) {
|
|
|
615
684
|
to: toTok.value,
|
|
616
685
|
connector: connector,
|
|
617
686
|
label: props.label,
|
|
687
|
+
fromAnchor: props["anchor-from"],
|
|
688
|
+
toAnchor: props["anchor-to"],
|
|
618
689
|
dashed,
|
|
619
690
|
bidirectional,
|
|
620
691
|
style: propsToStyle(props),
|
|
@@ -753,6 +824,8 @@ var AIDiagram = (function (exports) {
|
|
|
753
824
|
chartType: chartType.replace("-chart", ""),
|
|
754
825
|
label: props.label ?? props.title,
|
|
755
826
|
data: { headers, rows },
|
|
827
|
+
x: props.x ? parseFloat(props.x) : undefined,
|
|
828
|
+
y: props.y ? parseFloat(props.y) : undefined,
|
|
756
829
|
width: props.width ? parseFloat(props.width) : undefined,
|
|
757
830
|
height: props.height ? parseFloat(props.height) : undefined,
|
|
758
831
|
theme: props.theme,
|
|
@@ -778,6 +851,8 @@ var AIDiagram = (function (exports) {
|
|
|
778
851
|
id,
|
|
779
852
|
label: props.label ?? "",
|
|
780
853
|
rows: [],
|
|
854
|
+
x: props.x ? parseFloat(props.x) : undefined,
|
|
855
|
+
y: props.y ? parseFloat(props.y) : undefined,
|
|
781
856
|
theme: props.theme,
|
|
782
857
|
style: propsToStyle(props),
|
|
783
858
|
};
|
|
@@ -833,6 +908,8 @@ var AIDiagram = (function (exports) {
|
|
|
833
908
|
kind: "markdown",
|
|
834
909
|
id,
|
|
835
910
|
content: content.trim(),
|
|
911
|
+
x: props.x ? parseFloat(props.x) : undefined,
|
|
912
|
+
y: props.y ? parseFloat(props.y) : undefined,
|
|
836
913
|
width: props.width ? parseFloat(props.width) : undefined,
|
|
837
914
|
height: props.height ? parseFloat(props.height) : undefined,
|
|
838
915
|
theme: props.theme,
|
|
@@ -922,6 +999,7 @@ var AIDiagram = (function (exports) {
|
|
|
922
999
|
registerAuthoredId(grp.id, "group", t);
|
|
923
1000
|
if (isBare) {
|
|
924
1001
|
grp.label = "";
|
|
1002
|
+
grp.padding = grp.padding ?? 0;
|
|
925
1003
|
grp.style = {
|
|
926
1004
|
...grp.style,
|
|
927
1005
|
fill: grp.style?.fill ?? "none",
|
|
@@ -1092,7 +1170,7 @@ var AIDiagram = (function (exports) {
|
|
|
1092
1170
|
node.style = { ...ast.styles[node.id], ...node.style };
|
|
1093
1171
|
}
|
|
1094
1172
|
}
|
|
1095
|
-
return ast;
|
|
1173
|
+
return applyPluginAstTransforms(ast, options.plugins);
|
|
1096
1174
|
}
|
|
1097
1175
|
|
|
1098
1176
|
// ============================================================
|
|
@@ -3441,6 +3519,8 @@ var AIDiagram = (function (exports) {
|
|
|
3441
3519
|
groupId: nodeParentById.get(n.id),
|
|
3442
3520
|
width: n.width,
|
|
3443
3521
|
height: n.height,
|
|
3522
|
+
authoredX: n.x,
|
|
3523
|
+
authoredY: n.y,
|
|
3444
3524
|
deg: n.deg,
|
|
3445
3525
|
dx: n.dx,
|
|
3446
3526
|
dy: n.dy,
|
|
@@ -3469,6 +3549,8 @@ var AIDiagram = (function (exports) {
|
|
|
3469
3549
|
align: (g.align ?? "start"),
|
|
3470
3550
|
justify: (g.justify ?? "start"),
|
|
3471
3551
|
style: { ...ast.styles[g.id], ...themeStyle, ...g.style },
|
|
3552
|
+
authoredX: g.x,
|
|
3553
|
+
authoredY: g.y,
|
|
3472
3554
|
width: g.width,
|
|
3473
3555
|
height: g.height,
|
|
3474
3556
|
x: 0,
|
|
@@ -3488,6 +3570,8 @@ var AIDiagram = (function (exports) {
|
|
|
3488
3570
|
headerH: TABLE.headerH,
|
|
3489
3571
|
labelH: TABLE.labelH,
|
|
3490
3572
|
style: { ...ast.styles[t.id], ...themeStyle, ...t.style },
|
|
3573
|
+
authoredX: t.x,
|
|
3574
|
+
authoredY: t.y,
|
|
3491
3575
|
x: 0,
|
|
3492
3576
|
y: 0,
|
|
3493
3577
|
w: 0,
|
|
@@ -3502,6 +3586,8 @@ var AIDiagram = (function (exports) {
|
|
|
3502
3586
|
label: c.label,
|
|
3503
3587
|
data: c.data,
|
|
3504
3588
|
style: { ...ast.styles[c.id], ...themeStyle, ...c.style },
|
|
3589
|
+
authoredX: c.x,
|
|
3590
|
+
authoredY: c.y,
|
|
3505
3591
|
x: 0,
|
|
3506
3592
|
y: 0,
|
|
3507
3593
|
w: c.width ?? CHART.defaultW,
|
|
@@ -3517,6 +3603,8 @@ var AIDiagram = (function (exports) {
|
|
|
3517
3603
|
style: { ...ast.styles[m.id], ...themeStyle, ...m.style },
|
|
3518
3604
|
width: m.width,
|
|
3519
3605
|
height: m.height,
|
|
3606
|
+
authoredX: m.x,
|
|
3607
|
+
authoredY: m.y,
|
|
3520
3608
|
x: 0,
|
|
3521
3609
|
y: 0,
|
|
3522
3610
|
w: 0,
|
|
@@ -3529,6 +3617,8 @@ var AIDiagram = (function (exports) {
|
|
|
3529
3617
|
to: e.to,
|
|
3530
3618
|
connector: e.connector,
|
|
3531
3619
|
label: e.label,
|
|
3620
|
+
fromAnchor: e.fromAnchor,
|
|
3621
|
+
toAnchor: e.toAnchor,
|
|
3532
3622
|
dashed: e.dashed ?? false,
|
|
3533
3623
|
bidirectional: e.bidirectional ?? false,
|
|
3534
3624
|
style: e.style ?? {},
|
|
@@ -4106,28 +4196,13 @@ var AIDiagram = (function (exports) {
|
|
|
4106
4196
|
return { arrowAt: "start", dashed };
|
|
4107
4197
|
return { arrowAt: "end", dashed };
|
|
4108
4198
|
}
|
|
4109
|
-
// ── Generic rect connection point ────────────────────────────────────────
|
|
4110
|
-
function rectConnPoint$1(rx, ry, rw, rh, ox, oy) {
|
|
4111
|
-
const cx = rx + rw / 2, cy = ry + rh / 2;
|
|
4112
|
-
const dx = ox - cx, dy = oy - cy;
|
|
4113
|
-
if (Math.abs(dx) < 0.01 && Math.abs(dy) < 0.01)
|
|
4114
|
-
return [cx, cy];
|
|
4115
|
-
const hw = rw / 2 - 2, hh = rh / 2 - 2;
|
|
4116
|
-
const tx = Math.abs(dx) > 0.01 ? hw / Math.abs(dx) : 1e9;
|
|
4117
|
-
const ty = Math.abs(dy) > 0.01 ? hh / Math.abs(dy) : 1e9;
|
|
4118
|
-
const t = Math.min(tx, ty);
|
|
4119
|
-
return [cx + t * dx, cy + t * dy];
|
|
4120
|
-
}
|
|
4121
4199
|
// ── Resolve an endpoint entity by ID across all maps ─────────────────────
|
|
4122
4200
|
function resolveEndpoint(id, nm, tm, gm, cm) {
|
|
4123
4201
|
return nm.get(id) ?? tm.get(id) ?? gm.get(id) ?? cm.get(id) ?? null;
|
|
4124
4202
|
}
|
|
4125
4203
|
// ── Get connection point for any entity ──────────────────────────────────
|
|
4126
|
-
function getConnPoint(src, dstCX, dstCY) {
|
|
4127
|
-
|
|
4128
|
-
return connPoint(src, { x: dstCX - 1, y: dstCY - 1, w: 2, h: 2});
|
|
4129
|
-
}
|
|
4130
|
-
return rectConnPoint$1(src.x, src.y, src.w, src.h, dstCX, dstCY);
|
|
4204
|
+
function getConnPoint(src, dstCX, dstCY, anchor) {
|
|
4205
|
+
return anchoredConnPoint(src, anchor, dstCX, dstCY);
|
|
4131
4206
|
}
|
|
4132
4207
|
// ── Group depth (for paint order) ────────────────────────────────────────
|
|
4133
4208
|
function groupDepth(g, gm) {
|
|
@@ -4364,6 +4439,12 @@ var AIDiagram = (function (exports) {
|
|
|
4364
4439
|
function iH(r, em) {
|
|
4365
4440
|
return em.get(r.id).h;
|
|
4366
4441
|
}
|
|
4442
|
+
function iAuthX(r, em) {
|
|
4443
|
+
return em.get(r.id).authoredX ?? 0;
|
|
4444
|
+
}
|
|
4445
|
+
function iAuthY(r, em) {
|
|
4446
|
+
return em.get(r.id).authoredY ?? 0;
|
|
4447
|
+
}
|
|
4367
4448
|
function setPos(r, x, y, em) {
|
|
4368
4449
|
const e = em.get(r.id);
|
|
4369
4450
|
e.x = Math.round(x);
|
|
@@ -4410,6 +4491,12 @@ var AIDiagram = (function (exports) {
|
|
|
4410
4491
|
g.w = cols * cellW + (cols - 1) * gap + pad * 2;
|
|
4411
4492
|
g.h = rows * cellH + (rows - 1) * gap + pad * 2 + labelH;
|
|
4412
4493
|
}
|
|
4494
|
+
else if (layout === "absolute") {
|
|
4495
|
+
const maxRight = Math.max(0, ...kids.map((r) => iAuthX(r, em) + iW(r, em)));
|
|
4496
|
+
const maxBottom = Math.max(0, ...kids.map((r) => iAuthY(r, em) + iH(r, em)));
|
|
4497
|
+
g.w = maxRight + pad * 2;
|
|
4498
|
+
g.h = maxBottom + pad * 2 + labelH;
|
|
4499
|
+
}
|
|
4413
4500
|
else {
|
|
4414
4501
|
// column (default)
|
|
4415
4502
|
g.w = Math.max(...ws) + pad * 2;
|
|
@@ -4500,6 +4587,11 @@ var AIDiagram = (function (exports) {
|
|
|
4500
4587
|
setPos(ref, contentX + (i % cols) * (cellW + gap), contentY + Math.floor(i / cols) * (cellH + gap), em);
|
|
4501
4588
|
});
|
|
4502
4589
|
}
|
|
4590
|
+
else if (layout === "absolute") {
|
|
4591
|
+
kids.forEach((ref) => {
|
|
4592
|
+
setPos(ref, contentX + iAuthX(ref, em), contentY + iAuthY(ref, em), em);
|
|
4593
|
+
});
|
|
4594
|
+
}
|
|
4503
4595
|
else {
|
|
4504
4596
|
// column (default)
|
|
4505
4597
|
const ws = kids.map((r) => iW(r, em));
|
|
@@ -4545,6 +4637,50 @@ var AIDiagram = (function (exports) {
|
|
|
4545
4637
|
const t = Math.min(tx, ty);
|
|
4546
4638
|
return [cx + t * dx, cy + t * dy];
|
|
4547
4639
|
}
|
|
4640
|
+
function clampInset(value) {
|
|
4641
|
+
return Math.max(2, value);
|
|
4642
|
+
}
|
|
4643
|
+
function anchoredConnPoint(entity, anchor, otherCX, otherCY) {
|
|
4644
|
+
if (!anchor) {
|
|
4645
|
+
if (entity.shape && otherCX != null && otherCY != null) {
|
|
4646
|
+
return connPoint(entity, { x: otherCX - 1, y: otherCY - 1, w: 2, h: 2});
|
|
4647
|
+
}
|
|
4648
|
+
if (otherCX != null && otherCY != null) {
|
|
4649
|
+
return rectConnPoint(entity.x, entity.y, entity.w, entity.h, otherCX, otherCY);
|
|
4650
|
+
}
|
|
4651
|
+
return [entity.x + entity.w / 2, entity.y + entity.h / 2];
|
|
4652
|
+
}
|
|
4653
|
+
const insetX = clampInset(Math.min(10, entity.w / 2));
|
|
4654
|
+
const insetY = clampInset(Math.min(10, entity.h / 2));
|
|
4655
|
+
const left = entity.x + insetX;
|
|
4656
|
+
const right = entity.x + entity.w - insetX;
|
|
4657
|
+
const top = entity.y + insetY;
|
|
4658
|
+
const bottom = entity.y + entity.h - insetY;
|
|
4659
|
+
const cx = entity.x + entity.w / 2;
|
|
4660
|
+
const cy = entity.y + entity.h / 2;
|
|
4661
|
+
switch (anchor) {
|
|
4662
|
+
case "top":
|
|
4663
|
+
return [cx, top];
|
|
4664
|
+
case "right":
|
|
4665
|
+
return [right, cy];
|
|
4666
|
+
case "bottom":
|
|
4667
|
+
return [cx, bottom];
|
|
4668
|
+
case "left":
|
|
4669
|
+
return [left, cy];
|
|
4670
|
+
case "center":
|
|
4671
|
+
return [cx, cy];
|
|
4672
|
+
case "top-left":
|
|
4673
|
+
return [left, top];
|
|
4674
|
+
case "top-right":
|
|
4675
|
+
return [right, top];
|
|
4676
|
+
case "bottom-left":
|
|
4677
|
+
return [left, bottom];
|
|
4678
|
+
case "bottom-right":
|
|
4679
|
+
return [right, bottom];
|
|
4680
|
+
default:
|
|
4681
|
+
return [cx, cy];
|
|
4682
|
+
}
|
|
4683
|
+
}
|
|
4548
4684
|
function rectConnPoint(rx, ry, rw, rh, ox, oy) {
|
|
4549
4685
|
const cx = rx + rw / 2, cy = ry + rh / 2;
|
|
4550
4686
|
const dx = ox - cx, dy = oy - cy;
|
|
@@ -4576,17 +4712,6 @@ var AIDiagram = (function (exports) {
|
|
|
4576
4712
|
return c;
|
|
4577
4713
|
return null;
|
|
4578
4714
|
}
|
|
4579
|
-
function connPt(src, dstCX, dstCY) {
|
|
4580
|
-
// SceneNode has a .shape field; use the existing connPoint for it
|
|
4581
|
-
if ("shape" in src && src.shape) {
|
|
4582
|
-
return connPoint(src, {
|
|
4583
|
-
x: dstCX - 1,
|
|
4584
|
-
y: dstCY - 1,
|
|
4585
|
-
w: 2,
|
|
4586
|
-
h: 2});
|
|
4587
|
-
}
|
|
4588
|
-
return rectConnPoint(src.x, src.y, src.w, src.h, dstCX, dstCY);
|
|
4589
|
-
}
|
|
4590
4715
|
for (const e of sg.edges) {
|
|
4591
4716
|
const src = resolve(e.from);
|
|
4592
4717
|
const dst = resolve(e.to);
|
|
@@ -4596,7 +4721,10 @@ var AIDiagram = (function (exports) {
|
|
|
4596
4721
|
}
|
|
4597
4722
|
const dstCX = dst.x + dst.w / 2, dstCY = dst.y + dst.h / 2;
|
|
4598
4723
|
const srcCX = src.x + src.w / 2, srcCY = src.y + src.h / 2;
|
|
4599
|
-
e.points = [
|
|
4724
|
+
e.points = [
|
|
4725
|
+
anchoredConnPoint(src, e.fromAnchor, dstCX, dstCY),
|
|
4726
|
+
anchoredConnPoint(dst, e.toAnchor, srcCX, srcCY),
|
|
4727
|
+
];
|
|
4600
4728
|
}
|
|
4601
4729
|
}
|
|
4602
4730
|
function computeBounds(sg, margin) {
|
|
@@ -4682,6 +4810,7 @@ var AIDiagram = (function (exports) {
|
|
|
4682
4810
|
const rootCols = Number(sg.config["columns"] ?? 1);
|
|
4683
4811
|
const useGrid = rootLayout === "grid" && rootCols > 0;
|
|
4684
4812
|
const useColumn = rootLayout === "column";
|
|
4813
|
+
const useAbsolute = rootLayout === "absolute";
|
|
4685
4814
|
if (useGrid) {
|
|
4686
4815
|
// ── Grid: per-row heights, per-column widths (no wasted space) ──
|
|
4687
4816
|
const cols = rootCols;
|
|
@@ -4713,6 +4842,13 @@ var AIDiagram = (function (exports) {
|
|
|
4713
4842
|
e.y = rowY[Math.floor(idx / cols)];
|
|
4714
4843
|
});
|
|
4715
4844
|
}
|
|
4845
|
+
else if (useAbsolute) {
|
|
4846
|
+
for (const ref of rootOrder) {
|
|
4847
|
+
const e = em.get(ref.id);
|
|
4848
|
+
e.x = MARGIN + (e.authoredX ?? 0);
|
|
4849
|
+
e.y = MARGIN + (e.authoredY ?? 0);
|
|
4850
|
+
}
|
|
4851
|
+
}
|
|
4716
4852
|
else {
|
|
4717
4853
|
// ── Row or Column linear flow ──────────────────────────
|
|
4718
4854
|
let pos = MARGIN;
|
|
@@ -7729,8 +7865,8 @@ var AIDiagram = (function (exports) {
|
|
|
7729
7865
|
continue;
|
|
7730
7866
|
const dstCX = dst.x + dst.w / 2, dstCY = dst.y + dst.h / 2;
|
|
7731
7867
|
const srcCX = src.x + src.w / 2, srcCY = src.y + src.h / 2;
|
|
7732
|
-
const [x1, y1] = getConnPoint(src, dstCX, dstCY);
|
|
7733
|
-
const [x2, y2] = getConnPoint(dst, srcCX, srcCY);
|
|
7868
|
+
const [x1, y1] = getConnPoint(src, dstCX, dstCY, e.fromAnchor);
|
|
7869
|
+
const [x2, y2] = getConnPoint(dst, srcCX, srcCY, e.toAnchor);
|
|
7734
7870
|
const eg = mkGroup(`edge-${e.from}-${e.to}`, "eg");
|
|
7735
7871
|
if (e.style?.opacity != null)
|
|
7736
7872
|
eg.setAttribute("opacity", String(e.style.opacity));
|
|
@@ -7807,6 +7943,8 @@ var AIDiagram = (function (exports) {
|
|
|
7807
7943
|
ng.dataset.h = String(n.h);
|
|
7808
7944
|
if (n.pathData)
|
|
7809
7945
|
ng.dataset.pathData = n.pathData;
|
|
7946
|
+
if (n.meta?.animationParent)
|
|
7947
|
+
ng.dataset.animationParent = n.meta.animationParent;
|
|
7810
7948
|
if (n.style?.opacity != null)
|
|
7811
7949
|
ng.setAttribute("opacity", String(n.style.opacity));
|
|
7812
7950
|
// ── Static transform (deg, dx, dy, factor) ──────────
|
|
@@ -8460,8 +8598,8 @@ var AIDiagram = (function (exports) {
|
|
|
8460
8598
|
continue;
|
|
8461
8599
|
const dstCX = dst.x + dst.w / 2, dstCY = dst.y + dst.h / 2;
|
|
8462
8600
|
const srcCX = src.x + src.w / 2, srcCY = src.y + src.h / 2;
|
|
8463
|
-
const [x1, y1] = getConnPoint(src, dstCX, dstCY);
|
|
8464
|
-
const [x2, y2] = getConnPoint(dst, srcCX, srcCY);
|
|
8601
|
+
const [x1, y1] = getConnPoint(src, dstCX, dstCY, e.fromAnchor);
|
|
8602
|
+
const [x2, y2] = getConnPoint(dst, srcCX, srcCY, e.toAnchor);
|
|
8465
8603
|
if (e.style?.opacity != null)
|
|
8466
8604
|
ctx.globalAlpha = Number(e.style.opacity);
|
|
8467
8605
|
const ecol = String(e.style?.stroke ?? palette.edgeStroke);
|
|
@@ -9318,6 +9456,13 @@ var AIDiagram = (function (exports) {
|
|
|
9318
9456
|
this.drawTargetNodes.delete(`node-${s.target}`);
|
|
9319
9457
|
}
|
|
9320
9458
|
}
|
|
9459
|
+
this._relatedElementIdsByPrimaryId = this._buildRelatedElementIndex();
|
|
9460
|
+
for (const nodeId of Array.from(this.drawTargetNodes)) {
|
|
9461
|
+
const relatedIds = this._relatedElementIdsByPrimaryId.get(nodeId);
|
|
9462
|
+
if (!relatedIds)
|
|
9463
|
+
continue;
|
|
9464
|
+
relatedIds.forEach((id) => this.drawTargetNodes.add(id));
|
|
9465
|
+
}
|
|
9321
9466
|
this._drawStepIndexByElementId = this._buildDrawStepIndex();
|
|
9322
9467
|
const { parentGroupByElementId, groupDescendantIds } = this._buildGroupVisibilityIndex();
|
|
9323
9468
|
this._parentGroupByElementId = parentGroupByElementId;
|
|
@@ -9348,10 +9493,30 @@ var AIDiagram = (function (exports) {
|
|
|
9348
9493
|
const el = resolveNonEdgeDrawEl(this.svg, step.target);
|
|
9349
9494
|
if (el && !drawStepIndexByElementId.has(el.id)) {
|
|
9350
9495
|
drawStepIndexByElementId.set(el.id, stepIndex);
|
|
9496
|
+
this._relatedElementIdsByPrimaryId.get(el.id)?.forEach((relatedId) => {
|
|
9497
|
+
if (!drawStepIndexByElementId.has(relatedId)) {
|
|
9498
|
+
drawStepIndexByElementId.set(relatedId, stepIndex);
|
|
9499
|
+
}
|
|
9500
|
+
});
|
|
9351
9501
|
}
|
|
9352
9502
|
});
|
|
9353
9503
|
return drawStepIndexByElementId;
|
|
9354
9504
|
}
|
|
9505
|
+
_buildRelatedElementIndex() {
|
|
9506
|
+
const relatedElementIdsByPrimaryId = new Map();
|
|
9507
|
+
this.svg.querySelectorAll(POSITIONABLE_SELECTOR).forEach((el) => {
|
|
9508
|
+
const animationParent = el.dataset.animationParent;
|
|
9509
|
+
if (!animationParent)
|
|
9510
|
+
return;
|
|
9511
|
+
const primaryEl = resolveNonEdgeDrawEl(this.svg, animationParent);
|
|
9512
|
+
if (!primaryEl || primaryEl.id === el.id)
|
|
9513
|
+
return;
|
|
9514
|
+
const related = relatedElementIdsByPrimaryId.get(primaryEl.id) ?? new Set();
|
|
9515
|
+
related.add(el.id);
|
|
9516
|
+
relatedElementIdsByPrimaryId.set(primaryEl.id, related);
|
|
9517
|
+
});
|
|
9518
|
+
return relatedElementIdsByPrimaryId;
|
|
9519
|
+
}
|
|
9355
9520
|
_buildGroupVisibilityIndex() {
|
|
9356
9521
|
const parentGroupByElementId = new Map();
|
|
9357
9522
|
const directChildIdsByGroup = new Map();
|
|
@@ -9430,10 +9595,18 @@ var AIDiagram = (function (exports) {
|
|
|
9430
9595
|
const el = resolveEl(this.svg, target);
|
|
9431
9596
|
if (!el)
|
|
9432
9597
|
return [];
|
|
9433
|
-
if (!el.id.startsWith("group-"))
|
|
9434
|
-
|
|
9598
|
+
if (!el.id.startsWith("group-")) {
|
|
9599
|
+
const ids = new Set([el.id]);
|
|
9600
|
+
this._relatedElementIdsByPrimaryId.get(el.id)?.forEach((id) => ids.add(id));
|
|
9601
|
+
return Array.from(ids)
|
|
9602
|
+
.map((id) => getEl(this.svg, id))
|
|
9603
|
+
.filter((candidate) => candidate != null);
|
|
9604
|
+
}
|
|
9435
9605
|
const ids = new Set([el.id]);
|
|
9436
9606
|
this._groupDescendantIds.get(el.id)?.forEach((id) => ids.add(id));
|
|
9607
|
+
Array.from(ids).forEach((id) => {
|
|
9608
|
+
this._relatedElementIdsByPrimaryId.get(id)?.forEach((relatedId) => ids.add(relatedId));
|
|
9609
|
+
});
|
|
9437
9610
|
return Array.from(ids)
|
|
9438
9611
|
.map((id) => getEl(this.svg, id))
|
|
9439
9612
|
.filter((candidate) => candidate != null);
|
|
@@ -9842,9 +10015,11 @@ var AIDiagram = (function (exports) {
|
|
|
9842
10015
|
// ── highlight ────────────────────────────────────────────
|
|
9843
10016
|
_doHighlight(target) {
|
|
9844
10017
|
this.svg
|
|
9845
|
-
.querySelectorAll(".ng.hl, .tg.hl, .ntg.hl, .cg.hl, .eg.hl")
|
|
10018
|
+
.querySelectorAll(".ng.hl, .gg.hl, .tg.hl, .ntg.hl, .cg.hl, .mdg.hl, .eg.hl")
|
|
9846
10019
|
.forEach((e) => e.classList.remove("hl"));
|
|
9847
|
-
|
|
10020
|
+
for (const el of this._resolveCascadeTargets(target)) {
|
|
10021
|
+
el.classList.add("hl");
|
|
10022
|
+
}
|
|
9848
10023
|
}
|
|
9849
10024
|
// ── fade / unfade ─────────────────────────────────────────
|
|
9850
10025
|
_doFade(target, doFade) {
|
|
@@ -9880,8 +10055,8 @@ var AIDiagram = (function (exports) {
|
|
|
9880
10055
|
}
|
|
9881
10056
|
// ── move ──────────────────────────────────────────────────
|
|
9882
10057
|
_doMove(target, step, silent) {
|
|
9883
|
-
const
|
|
9884
|
-
if (!
|
|
10058
|
+
const targets = this._resolveCascadeTargets(target);
|
|
10059
|
+
if (!targets.length)
|
|
9885
10060
|
return;
|
|
9886
10061
|
const cur = this._transforms.get(target) ?? {
|
|
9887
10062
|
tx: 0,
|
|
@@ -9894,12 +10069,14 @@ var AIDiagram = (function (exports) {
|
|
|
9894
10069
|
tx: cur.tx + (step.dx ?? 0),
|
|
9895
10070
|
ty: cur.ty + (step.dy ?? 0),
|
|
9896
10071
|
});
|
|
9897
|
-
|
|
10072
|
+
for (const el of targets) {
|
|
10073
|
+
this._writeTransform(el, target, silent, step.duration ?? 420);
|
|
10074
|
+
}
|
|
9898
10075
|
}
|
|
9899
10076
|
// ── scale ─────────────────────────────────────────────────
|
|
9900
10077
|
_doScale(target, step, silent) {
|
|
9901
|
-
const
|
|
9902
|
-
if (!
|
|
10078
|
+
const targets = this._resolveCascadeTargets(target);
|
|
10079
|
+
if (!targets.length)
|
|
9903
10080
|
return;
|
|
9904
10081
|
const cur = this._transforms.get(target) ?? {
|
|
9905
10082
|
tx: 0,
|
|
@@ -9908,12 +10085,14 @@ var AIDiagram = (function (exports) {
|
|
|
9908
10085
|
rotate: 0,
|
|
9909
10086
|
};
|
|
9910
10087
|
this._transforms.set(target, { ...cur, scale: step.factor ?? 1 });
|
|
9911
|
-
|
|
10088
|
+
for (const el of targets) {
|
|
10089
|
+
this._writeTransform(el, target, silent, step.duration ?? 350);
|
|
10090
|
+
}
|
|
9912
10091
|
}
|
|
9913
10092
|
// ── rotate ────────────────────────────────────────────────
|
|
9914
10093
|
_doRotate(target, step, silent) {
|
|
9915
|
-
const
|
|
9916
|
-
if (!
|
|
10094
|
+
const targets = this._resolveCascadeTargets(target);
|
|
10095
|
+
if (!targets.length)
|
|
9917
10096
|
return;
|
|
9918
10097
|
const cur = this._transforms.get(target) ?? {
|
|
9919
10098
|
tx: 0,
|
|
@@ -9925,7 +10104,9 @@ var AIDiagram = (function (exports) {
|
|
|
9925
10104
|
...cur,
|
|
9926
10105
|
rotate: cur.rotate + (step.deg ?? 0),
|
|
9927
10106
|
});
|
|
9928
|
-
|
|
10107
|
+
for (const el of targets) {
|
|
10108
|
+
this._writeTransform(el, target, silent, step.duration ?? 400);
|
|
10109
|
+
}
|
|
9929
10110
|
}
|
|
9930
10111
|
_doDraw(step, silent) {
|
|
9931
10112
|
const { target } = step;
|
|
@@ -10069,18 +10250,20 @@ var AIDiagram = (function (exports) {
|
|
|
10069
10250
|
return;
|
|
10070
10251
|
}
|
|
10071
10252
|
// ── Node draw ──────────────────────────────────────
|
|
10072
|
-
const
|
|
10073
|
-
if (!
|
|
10253
|
+
const nodeEls = this._resolveCascadeTargets(target).filter((el) => el.classList.contains("ng"));
|
|
10254
|
+
if (!nodeEls.length)
|
|
10074
10255
|
return;
|
|
10075
|
-
|
|
10076
|
-
|
|
10077
|
-
|
|
10078
|
-
|
|
10079
|
-
|
|
10080
|
-
|
|
10081
|
-
|
|
10256
|
+
for (const nodeEl of nodeEls) {
|
|
10257
|
+
showDrawEl(nodeEl);
|
|
10258
|
+
if (silent) {
|
|
10259
|
+
revealNodeInstant(nodeEl);
|
|
10260
|
+
}
|
|
10261
|
+
else {
|
|
10262
|
+
if (!nodeGuidePathEl(nodeEl) && !nodeEl.querySelector("path")?.style.strokeDasharray) {
|
|
10263
|
+
prepareNodeForDraw(nodeEl);
|
|
10264
|
+
}
|
|
10265
|
+
animateNodeDraw(nodeEl, step.duration ?? ANIMATION.nodeStrokeDur, step.duration ?? ANIMATION.textRevealMs);
|
|
10082
10266
|
}
|
|
10083
|
-
animateNodeDraw(nodeEl, step.duration ?? ANIMATION.nodeStrokeDur, step.duration ?? ANIMATION.textRevealMs);
|
|
10084
10267
|
}
|
|
10085
10268
|
}
|
|
10086
10269
|
// ── erase ─────────────────────────────────────────────────
|
|
@@ -10101,45 +10284,44 @@ var AIDiagram = (function (exports) {
|
|
|
10101
10284
|
}
|
|
10102
10285
|
// ── pulse ─────────────────────────────────────────────────
|
|
10103
10286
|
_doPulse(target, duration = 500) {
|
|
10104
|
-
|
|
10105
|
-
|
|
10106
|
-
|
|
10107
|
-
|
|
10108
|
-
|
|
10287
|
+
for (const el of this._resolveCascadeTargets(target)) {
|
|
10288
|
+
el.animate([
|
|
10289
|
+
{ filter: "brightness(1)" },
|
|
10290
|
+
{ filter: "brightness(1.6)" },
|
|
10291
|
+
{ filter: "brightness(1)" },
|
|
10292
|
+
], { duration, iterations: 3 });
|
|
10293
|
+
}
|
|
10109
10294
|
}
|
|
10110
10295
|
// ── color ─────────────────────────────────────────────────
|
|
10111
10296
|
_doColor(target, color) {
|
|
10112
10297
|
if (!color)
|
|
10113
10298
|
return;
|
|
10114
|
-
const el
|
|
10115
|
-
|
|
10116
|
-
|
|
10117
|
-
|
|
10118
|
-
|
|
10119
|
-
|
|
10120
|
-
|
|
10121
|
-
|
|
10122
|
-
|
|
10123
|
-
|
|
10124
|
-
|
|
10125
|
-
|
|
10126
|
-
|
|
10127
|
-
|
|
10128
|
-
|
|
10129
|
-
|
|
10130
|
-
|
|
10131
|
-
|
|
10132
|
-
|
|
10133
|
-
|
|
10134
|
-
if (attrFill === null && c.tagName === "path")
|
|
10135
|
-
return;
|
|
10136
|
-
c.style.fill = color;
|
|
10137
|
-
hit = true;
|
|
10138
|
-
});
|
|
10139
|
-
if (!hit) {
|
|
10140
|
-
el.querySelectorAll("text").forEach((t) => {
|
|
10141
|
-
t.style.fill = color;
|
|
10299
|
+
for (const el of this._resolveCascadeTargets(target)) {
|
|
10300
|
+
if (parseEdgeTarget(target)) {
|
|
10301
|
+
el.querySelectorAll("path, line, polyline").forEach((p) => {
|
|
10302
|
+
p.style.stroke = color;
|
|
10303
|
+
});
|
|
10304
|
+
el.querySelectorAll("polygon").forEach((p) => {
|
|
10305
|
+
p.style.fill = color;
|
|
10306
|
+
p.style.stroke = color;
|
|
10307
|
+
});
|
|
10308
|
+
continue;
|
|
10309
|
+
}
|
|
10310
|
+
let hit = false;
|
|
10311
|
+
el.querySelectorAll("path, rect, ellipse, polygon").forEach((c) => {
|
|
10312
|
+
const attrFill = c.getAttribute("fill");
|
|
10313
|
+
if (attrFill === "none")
|
|
10314
|
+
return;
|
|
10315
|
+
if (attrFill === null && c.tagName === "path")
|
|
10316
|
+
return;
|
|
10317
|
+
c.style.fill = color;
|
|
10318
|
+
hit = true;
|
|
10142
10319
|
});
|
|
10320
|
+
if (!hit) {
|
|
10321
|
+
el.querySelectorAll("text").forEach((t) => {
|
|
10322
|
+
t.style.fill = color;
|
|
10323
|
+
});
|
|
10324
|
+
}
|
|
10143
10325
|
}
|
|
10144
10326
|
}
|
|
10145
10327
|
// ── narration ───────────────────────────────────────────
|
|
@@ -10733,7 +10915,7 @@ var AIDiagram = (function (exports) {
|
|
|
10733
10915
|
}
|
|
10734
10916
|
|
|
10735
10917
|
function render(options) {
|
|
10736
|
-
const { container: rawContainer, dsl, renderer = "svg", injectCSS = true, tts, svgOptions = {}, canvasOptions = {}, onNodeClick, onReady, } = options;
|
|
10918
|
+
const { container: rawContainer, dsl, plugins, renderer = "svg", injectCSS = true, tts, svgOptions = {}, canvasOptions = {}, onNodeClick, onReady, } = options;
|
|
10737
10919
|
if (injectCSS && !document.getElementById("ai-diagram-css")) {
|
|
10738
10920
|
const style = document.createElement("style");
|
|
10739
10921
|
style.id = "ai-diagram-css";
|
|
@@ -10749,7 +10931,7 @@ var AIDiagram = (function (exports) {
|
|
|
10749
10931
|
else {
|
|
10750
10932
|
el = rawContainer;
|
|
10751
10933
|
}
|
|
10752
|
-
const ast = parse(dsl);
|
|
10934
|
+
const ast = parse(dsl, { plugins });
|
|
10753
10935
|
const scene = buildSceneGraph(ast);
|
|
10754
10936
|
layout(scene);
|
|
10755
10937
|
let svg;
|
|
@@ -11093,6 +11275,7 @@ var AIDiagram = (function (exports) {
|
|
|
11093
11275
|
const instance = render({
|
|
11094
11276
|
container: this.diagramWrap,
|
|
11095
11277
|
dsl: this.dsl,
|
|
11278
|
+
plugins: this.options.plugins,
|
|
11096
11279
|
renderer: this.renderer,
|
|
11097
11280
|
svgOptions: { interactive: true, showTitle: true, theme: this.options.svgOptions?.theme ?? this.theme, ...this.options.svgOptions },
|
|
11098
11281
|
canvasOptions: this.options.canvasOptions,
|
|
@@ -12170,6 +12353,7 @@ var AIDiagram = (function (exports) {
|
|
|
12170
12353
|
const instance = render({
|
|
12171
12354
|
container: this.diagramWrap,
|
|
12172
12355
|
dsl: this.dsl,
|
|
12356
|
+
plugins: this.options.plugins,
|
|
12173
12357
|
renderer: "svg",
|
|
12174
12358
|
svgOptions: {
|
|
12175
12359
|
showTitle: true,
|