@pixerate/editor 0.55.0 → 0.57.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agent/index.cjs +18 -17
- package/dist/agent/index.cjs.map +1 -1
- package/dist/agent/index.js +3 -2
- package/dist/agent/index.js.map +1 -1
- package/dist/animation-editor/index.cjs +25 -7
- package/dist/animation-editor/index.cjs.map +1 -1
- package/dist/animation-editor/index.d.cts +21 -5
- package/dist/animation-editor/index.d.ts +21 -5
- package/dist/animation-editor/index.js +25 -7
- package/dist/animation-editor/index.js.map +1 -1
- package/dist/canvas/index.cjs +2105 -172
- package/dist/canvas/index.cjs.map +1 -1
- package/dist/canvas/index.d.cts +319 -23
- package/dist/canvas/index.d.ts +319 -23
- package/dist/canvas/index.js +2081 -148
- package/dist/canvas/index.js.map +1 -1
- package/dist/chart/index.cjs +32 -30
- package/dist/chart/index.cjs.map +1 -1
- package/dist/chart/index.d.cts +4 -2
- package/dist/chart/index.d.ts +4 -2
- package/dist/chart/index.js +20 -18
- package/dist/chart/index.js.map +1 -1
- package/dist/{chunk-C3JHII3M.cjs → chunk-3I6V7PI4.cjs} +45 -45
- package/dist/{chunk-C3JHII3M.cjs.map → chunk-3I6V7PI4.cjs.map} +1 -1
- package/dist/{chunk-P43HUQRX.cjs → chunk-AHCENCU4.cjs} +12 -10
- package/dist/chunk-AHCENCU4.cjs.map +1 -0
- package/dist/chunk-II77MLHN.cjs +11106 -0
- package/dist/chunk-II77MLHN.cjs.map +1 -0
- package/dist/{chunk-OIKYP7XC.js → chunk-LMUDHBWR.js} +2 -2
- package/dist/{chunk-VODBAO32.js → chunk-OEFCLWZ3.js} +4 -1425
- package/dist/chunk-OEFCLWZ3.js.map +1 -0
- package/dist/{chunk-NK3WL5TJ.cjs → chunk-P2CTDJNF.cjs} +27 -1448
- package/dist/chunk-P2CTDJNF.cjs.map +1 -0
- package/dist/chunk-TKPPIVW7.cjs +1443 -0
- package/dist/chunk-TKPPIVW7.cjs.map +1 -0
- package/dist/chunk-WJSCGBJ2.js +11106 -0
- package/dist/chunk-WJSCGBJ2.js.map +1 -0
- package/dist/{chunk-RIXTW3C4.js → chunk-WLVZ235X.js} +5 -3
- package/dist/{chunk-RIXTW3C4.js.map → chunk-WLVZ235X.js.map} +1 -1
- package/dist/chunk-ZOH6X3VR.js +1443 -0
- package/dist/chunk-ZOH6X3VR.js.map +1 -0
- package/dist/{controller-DscWQbjO.d.ts → controller-D2rj5umx.d.ts} +2 -362
- package/dist/{controller-CX0QfSv0.d.cts → controller-R2biKk_E.d.cts} +2 -362
- package/dist/diagram/index.cjs +1457 -47
- package/dist/diagram/index.cjs.map +1 -1
- package/dist/diagram/index.d.cts +1734 -15
- package/dist/diagram/index.d.ts +1734 -15
- package/dist/diagram/index.js +1436 -26
- package/dist/diagram/index.js.map +1 -1
- package/dist/extensions/index.cjs +5 -4
- package/dist/extensions/index.cjs.map +1 -1
- package/dist/extensions/index.d.cts +4 -3
- package/dist/extensions/index.d.ts +4 -3
- package/dist/extensions/index.js +4 -3
- package/dist/{index-DIWB6xMf.d.cts → index-BcHyG0Wq.d.cts} +2 -1
- package/dist/{index-CALDD35B.d.ts → index-CTCc3m3C.d.ts} +2 -1
- package/dist/index.cjs +10 -9
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +4 -3
- package/dist/index.d.ts +4 -3
- package/dist/index.js +4 -3
- package/dist/index.js.map +1 -1
- package/dist/types-BRp-6zkY.d.cts +362 -0
- package/dist/types-BRp-6zkY.d.ts +362 -0
- package/dist/{types-BULrFyuQ.d.cts → types-DYkjhzdz.d.cts} +1 -1
- package/dist/{types-BULrFyuQ.d.ts → types-DYkjhzdz.d.ts} +1 -1
- package/package.json +1 -1
- package/dist/chunk-H5K77C7Y.cjs +0 -3848
- package/dist/chunk-H5K77C7Y.cjs.map +0 -1
- package/dist/chunk-NK3WL5TJ.cjs.map +0 -1
- package/dist/chunk-P43HUQRX.cjs.map +0 -1
- package/dist/chunk-VODBAO32.js.map +0 -1
- package/dist/chunk-WWJNC7SX.js +0 -3848
- package/dist/chunk-WWJNC7SX.js.map +0 -1
- /package/dist/{chunk-OIKYP7XC.js.map → chunk-LMUDHBWR.js.map} +0 -0
package/dist/diagram/index.js
CHANGED
|
@@ -1,46 +1,121 @@
|
|
|
1
1
|
import {
|
|
2
|
+
ARCH_METRICS,
|
|
3
|
+
C4_METRICS,
|
|
2
4
|
CLASS_RELATIONS,
|
|
3
5
|
ER_CARDINALITIES,
|
|
4
6
|
ER_PATTERNS,
|
|
5
7
|
FLOWCHART_SHAPES,
|
|
8
|
+
GANTT_CONFIG_KEYS,
|
|
9
|
+
GANTT_METRICS,
|
|
10
|
+
GANTT_TAGS,
|
|
6
11
|
META_COMMENT_PREFIX,
|
|
7
12
|
META_FRONTMATTER_KEY,
|
|
13
|
+
POINT_BOX,
|
|
14
|
+
QUADRANT_METRICS,
|
|
15
|
+
RADAR_CHART_BOX,
|
|
16
|
+
SEQUENCE_METRICS,
|
|
8
17
|
STATE_SHAPES,
|
|
18
|
+
XY_CHART_BOX,
|
|
19
|
+
afterIds,
|
|
9
20
|
applyEdit,
|
|
10
21
|
applyEdits,
|
|
22
|
+
applyStatementEdit,
|
|
23
|
+
architectureAdapter,
|
|
24
|
+
architectureArrow,
|
|
25
|
+
architectureEdgeRoute,
|
|
26
|
+
architectureGrammar,
|
|
27
|
+
architectureLayout,
|
|
28
|
+
c4Adapter,
|
|
29
|
+
c4ArrowHead,
|
|
30
|
+
c4BoundaryText,
|
|
31
|
+
c4ElementGeometry,
|
|
32
|
+
c4ElementType,
|
|
33
|
+
c4Grammar,
|
|
34
|
+
c4Layout,
|
|
35
|
+
c4RelGeometry,
|
|
36
|
+
c4Stereotype,
|
|
11
37
|
canonicalShape,
|
|
12
38
|
classGrammar,
|
|
13
39
|
createLineAdapter,
|
|
14
40
|
createPassthroughAdapter,
|
|
41
|
+
createStatementAdapter,
|
|
15
42
|
detectFamily,
|
|
16
43
|
detectFamilyFromHeader,
|
|
44
|
+
dropMetaKeys,
|
|
17
45
|
emptyMeta,
|
|
18
46
|
erGrammar,
|
|
47
|
+
filterInPlace,
|
|
19
48
|
flowchartAdapter,
|
|
49
|
+
formatAxis,
|
|
20
50
|
formatChain,
|
|
51
|
+
formatGanttDate,
|
|
21
52
|
formatLink,
|
|
22
53
|
formatNode,
|
|
54
|
+
ganttAdapter,
|
|
55
|
+
ganttGeometry,
|
|
56
|
+
ganttGrammar,
|
|
23
57
|
getDiagramAdapter,
|
|
58
|
+
getFamilyLayout,
|
|
59
|
+
gitGraphAdapter,
|
|
60
|
+
gitGraphGrammar,
|
|
61
|
+
indentOf,
|
|
24
62
|
isMetaEmpty,
|
|
63
|
+
journeyAdapter,
|
|
64
|
+
journeyGrammar,
|
|
65
|
+
journeyLayout,
|
|
25
66
|
mergeMeta,
|
|
67
|
+
mindmapAdapter,
|
|
68
|
+
mindmapGrammar,
|
|
26
69
|
parseAttributes,
|
|
27
70
|
parseChain,
|
|
28
71
|
parseFlowchartSource,
|
|
72
|
+
parseGanttDate,
|
|
29
73
|
parseLink,
|
|
30
74
|
parseMembers,
|
|
31
75
|
parseMermaid,
|
|
32
76
|
parseStatement,
|
|
77
|
+
parseStatementDocument,
|
|
78
|
+
pieAdapter,
|
|
79
|
+
pieGrammar,
|
|
80
|
+
pointCentre,
|
|
81
|
+
pointPosition,
|
|
82
|
+
positionToData,
|
|
83
|
+
quadrantAdapter,
|
|
84
|
+
quadrantGeometry,
|
|
85
|
+
quadrantGrammar,
|
|
86
|
+
quadrantSpace,
|
|
87
|
+
quote,
|
|
33
88
|
quoteLabelIfNeeded,
|
|
89
|
+
radarAdapter,
|
|
90
|
+
radarGrammar,
|
|
34
91
|
registerDiagramAdapter,
|
|
92
|
+
registerFamilyLayout,
|
|
35
93
|
relationFor,
|
|
94
|
+
renameMetaKey,
|
|
36
95
|
resolveShape,
|
|
96
|
+
sequenceAdapter,
|
|
97
|
+
sequenceGeometry,
|
|
98
|
+
sequenceGrammar,
|
|
37
99
|
serializeMermaid,
|
|
38
100
|
serializeMeta,
|
|
101
|
+
serializeStatementDocument,
|
|
102
|
+
serviceLabelLines,
|
|
103
|
+
sharedFrameLayout,
|
|
104
|
+
slugId,
|
|
105
|
+
spaceInput,
|
|
106
|
+
splitOutsideQuotes,
|
|
39
107
|
splitSource,
|
|
40
108
|
splitStatements,
|
|
41
109
|
stateGrammar,
|
|
42
|
-
supportTierOf
|
|
43
|
-
|
|
110
|
+
supportTierOf,
|
|
111
|
+
timelineAdapter,
|
|
112
|
+
timelineGrammar,
|
|
113
|
+
timelineLayout,
|
|
114
|
+
uniqueId,
|
|
115
|
+
unquote,
|
|
116
|
+
xyChartAdapter,
|
|
117
|
+
xyChartGrammar
|
|
118
|
+
} from "../chunk-WJSCGBJ2.js";
|
|
44
119
|
import {
|
|
45
120
|
PRESENCE_COLORS,
|
|
46
121
|
PerformanceQueue,
|
|
@@ -114,17 +189,1151 @@ function headingText(line) {
|
|
|
114
189
|
return text || void 0;
|
|
115
190
|
}
|
|
116
191
|
|
|
192
|
+
// src/diagram/families/pie.ts
|
|
193
|
+
var pieUI = {
|
|
194
|
+
family: "pie",
|
|
195
|
+
title: "Pie chart",
|
|
196
|
+
shapes: [{ value: "slice", label: "Slice" }],
|
|
197
|
+
edgeKinds: [],
|
|
198
|
+
patterns: [],
|
|
199
|
+
arrowHeads: [],
|
|
200
|
+
groups: { supported: false, label: "Group" },
|
|
201
|
+
labels: true,
|
|
202
|
+
nodeNoun: "Slice",
|
|
203
|
+
nextId: (g) => `slice${g.nodes.length + 1}`,
|
|
204
|
+
canDetach: false,
|
|
205
|
+
styling: false,
|
|
206
|
+
connectable: false,
|
|
207
|
+
directions: false,
|
|
208
|
+
arrange: false,
|
|
209
|
+
preview: false,
|
|
210
|
+
nodeFields: [{ key: "value", label: "Value", type: "number", min: 0 }],
|
|
211
|
+
diagramFields: [{ key: "showData", label: "Show values in legend", type: "boolean" }],
|
|
212
|
+
newNode: () => ({ label: "New slice", data: { value: 10 } })
|
|
213
|
+
};
|
|
214
|
+
|
|
215
|
+
// src/diagram/families/mindmap.ts
|
|
216
|
+
var mindmapUI = {
|
|
217
|
+
family: "mindmap",
|
|
218
|
+
title: "Mind map",
|
|
219
|
+
shapes: [
|
|
220
|
+
{ value: "text", label: "Topic" },
|
|
221
|
+
{ value: "rounded", label: "Rounded" },
|
|
222
|
+
{ value: "rect", label: "Square" },
|
|
223
|
+
{ value: "circle", label: "Circle" },
|
|
224
|
+
{ value: "odd", label: "Bang" },
|
|
225
|
+
{ value: "stadium", label: "Cloud" },
|
|
226
|
+
{ value: "hex", label: "Hexagon" }
|
|
227
|
+
],
|
|
228
|
+
edgeKinds: [
|
|
229
|
+
{ value: "branch", label: "Branch", arrowStart: "none", arrowEnd: "none", pattern: "solid" }
|
|
230
|
+
],
|
|
231
|
+
patterns: [{ value: "solid", label: "Solid" }],
|
|
232
|
+
arrowHeads: [{ value: "none", label: "None" }],
|
|
233
|
+
groups: { supported: false, label: "Group" },
|
|
234
|
+
labels: true,
|
|
235
|
+
nodeNoun: "Topic",
|
|
236
|
+
edgeNoun: "Branch",
|
|
237
|
+
nextId: (g) => `topic${g.nodes.length + 1}`,
|
|
238
|
+
canDetach: false,
|
|
239
|
+
hierarchy: true,
|
|
240
|
+
styling: false,
|
|
241
|
+
connectable: false,
|
|
242
|
+
directions: false,
|
|
243
|
+
arrange: false,
|
|
244
|
+
preview: false,
|
|
245
|
+
nodeFields: [{ key: "icon", label: "Icon", type: "text", placeholder: "fa fa-book" }],
|
|
246
|
+
newNode: () => ({ label: "New topic" })
|
|
247
|
+
};
|
|
248
|
+
|
|
249
|
+
// src/diagram/families/quadrant.ts
|
|
250
|
+
var quadrantUI = {
|
|
251
|
+
family: "quadrant",
|
|
252
|
+
title: "Quadrant chart",
|
|
253
|
+
shapes: [{ value: "point", label: "Point" }],
|
|
254
|
+
edgeKinds: [],
|
|
255
|
+
patterns: [],
|
|
256
|
+
arrowHeads: [],
|
|
257
|
+
groups: { supported: false, label: "Quadrant" },
|
|
258
|
+
labels: true,
|
|
259
|
+
nodeNoun: "Point",
|
|
260
|
+
nextId: (g) => `point${g.nodes.length + 1}`,
|
|
261
|
+
canDetach: false,
|
|
262
|
+
styling: false,
|
|
263
|
+
connectable: false,
|
|
264
|
+
directions: false,
|
|
265
|
+
arrange: false,
|
|
266
|
+
preview: false,
|
|
267
|
+
nodeFields: [
|
|
268
|
+
{ key: "x", label: "X", type: "number", min: 0, max: 1, step: 0.05 },
|
|
269
|
+
{ key: "y", label: "Y", type: "number", min: 0, max: 1, step: 0.05 },
|
|
270
|
+
{ key: "radius", label: "Radius", type: "number", min: 1 },
|
|
271
|
+
{ key: "color", label: "Colour", type: "text", placeholder: "#ff9900" }
|
|
272
|
+
],
|
|
273
|
+
diagramFields: [
|
|
274
|
+
{ key: "xAxisLeft", label: "X axis (left)", type: "text" },
|
|
275
|
+
{ key: "xAxisRight", label: "X axis (right)", type: "text" },
|
|
276
|
+
{ key: "yAxisBottom", label: "Y axis (bottom)", type: "text" },
|
|
277
|
+
{ key: "yAxisTop", label: "Y axis (top)", type: "text" }
|
|
278
|
+
],
|
|
279
|
+
newNode: () => ({ label: "New point", data: { x: 0.5, y: 0.5 } })
|
|
280
|
+
};
|
|
281
|
+
|
|
282
|
+
// src/diagram/families/c4.ts
|
|
283
|
+
var c4UI = {
|
|
284
|
+
family: "c4",
|
|
285
|
+
title: "C4 diagram",
|
|
286
|
+
shapes: [
|
|
287
|
+
{ value: "c4-person", label: "Person" },
|
|
288
|
+
{ value: "c4-person-ext", label: "External person" },
|
|
289
|
+
{ value: "c4-system", label: "System" },
|
|
290
|
+
{ value: "c4-system-ext", label: "External system" },
|
|
291
|
+
{ value: "c4-container", label: "Container" },
|
|
292
|
+
{ value: "c4-container-ext", label: "External container" },
|
|
293
|
+
{ value: "c4-component", label: "Component" },
|
|
294
|
+
{ value: "c4-component-ext", label: "External component" },
|
|
295
|
+
{ value: "c4-db", label: "Database" },
|
|
296
|
+
{ value: "c4-queue", label: "Queue" }
|
|
297
|
+
],
|
|
298
|
+
edgeKinds: [
|
|
299
|
+
{
|
|
300
|
+
value: "Rel",
|
|
301
|
+
label: "Relation",
|
|
302
|
+
arrowStart: "none",
|
|
303
|
+
arrowEnd: "arrow_point",
|
|
304
|
+
pattern: "solid"
|
|
305
|
+
},
|
|
306
|
+
{
|
|
307
|
+
value: "BiRel",
|
|
308
|
+
label: "Bidirectional",
|
|
309
|
+
arrowStart: "arrow_point",
|
|
310
|
+
arrowEnd: "arrow_point",
|
|
311
|
+
pattern: "solid"
|
|
312
|
+
},
|
|
313
|
+
{
|
|
314
|
+
value: "Rel_Back",
|
|
315
|
+
label: "Reverse",
|
|
316
|
+
arrowStart: "arrow_point",
|
|
317
|
+
arrowEnd: "none",
|
|
318
|
+
pattern: "solid"
|
|
319
|
+
}
|
|
320
|
+
],
|
|
321
|
+
patterns: [{ value: "solid", label: "Solid" }],
|
|
322
|
+
arrowHeads: [
|
|
323
|
+
{ value: "none", label: "None" },
|
|
324
|
+
{ value: "arrow_point", label: "Arrow" }
|
|
325
|
+
],
|
|
326
|
+
groups: { supported: true, label: "Boundary" },
|
|
327
|
+
labels: true,
|
|
328
|
+
nodeNoun: "Element",
|
|
329
|
+
edgeNoun: "Relation",
|
|
330
|
+
nextId: (g) => {
|
|
331
|
+
const taken = /* @__PURE__ */ new Set([...g.nodes.map((n) => n.id), ...g.groups.map((x) => x.id)]);
|
|
332
|
+
let i = g.nodes.length + 1;
|
|
333
|
+
while (taken.has(`el${i}`)) i++;
|
|
334
|
+
return `el${i}`;
|
|
335
|
+
},
|
|
336
|
+
canDetach: true,
|
|
337
|
+
styling: false,
|
|
338
|
+
directions: false,
|
|
339
|
+
// Positions are Mermaid's own layout (plus where the user dragged): "Arrange"
|
|
340
|
+
// would pin a dagre layout Mermaid never draws.
|
|
341
|
+
// "Tidy up" resets dragged positions to Mermaid's own layout (the registered family layout).
|
|
342
|
+
arrange: true,
|
|
343
|
+
preview: false,
|
|
344
|
+
connectable: true,
|
|
345
|
+
nodeFields: [
|
|
346
|
+
{ key: "tech", label: "Technology", type: "text" },
|
|
347
|
+
{ key: "descr", label: "Description", type: "text" }
|
|
348
|
+
],
|
|
349
|
+
edgeFields: [{ key: "tech", label: "Technology", type: "text" }],
|
|
350
|
+
newNode: () => ({ label: "New element" })
|
|
351
|
+
};
|
|
352
|
+
|
|
353
|
+
// src/diagram/families/architecture.ts
|
|
354
|
+
var SIDE_OPTIONS = [
|
|
355
|
+
{ value: "L", label: "Left" },
|
|
356
|
+
{ value: "R", label: "Right" },
|
|
357
|
+
{ value: "T", label: "Top" },
|
|
358
|
+
{ value: "B", label: "Bottom" }
|
|
359
|
+
];
|
|
360
|
+
var architectureUI = {
|
|
361
|
+
family: "architecture",
|
|
362
|
+
title: "Architecture diagram",
|
|
363
|
+
shapes: [
|
|
364
|
+
{ value: "arch-service", label: "Service" },
|
|
365
|
+
{ value: "sm-circ", label: "Junction" }
|
|
366
|
+
],
|
|
367
|
+
edgeKinds: [
|
|
368
|
+
{ value: "--", label: "Line", arrowStart: "none", arrowEnd: "none", pattern: "solid" },
|
|
369
|
+
{ value: "-->", label: "Arrow", arrowStart: "none", arrowEnd: "arrow_point", pattern: "solid" },
|
|
370
|
+
{
|
|
371
|
+
value: "<-->",
|
|
372
|
+
label: "Bidirectional",
|
|
373
|
+
arrowStart: "arrow_point",
|
|
374
|
+
arrowEnd: "arrow_point",
|
|
375
|
+
pattern: "solid"
|
|
376
|
+
}
|
|
377
|
+
],
|
|
378
|
+
patterns: [{ value: "solid", label: "Solid" }],
|
|
379
|
+
arrowHeads: [
|
|
380
|
+
{ value: "none", label: "None" },
|
|
381
|
+
{ value: "arrow_point", label: "Arrow" }
|
|
382
|
+
],
|
|
383
|
+
groups: { supported: true, label: "Group" },
|
|
384
|
+
labels: true,
|
|
385
|
+
nodeNoun: "Service",
|
|
386
|
+
edgeNoun: "Connection",
|
|
387
|
+
nextId: (g) => {
|
|
388
|
+
const taken = /* @__PURE__ */ new Set([...g.nodes.map((n) => n.id), ...g.groups.map((x) => x.id)]);
|
|
389
|
+
let i = g.nodes.length + 1;
|
|
390
|
+
while (taken.has(`svc${i}`)) i++;
|
|
391
|
+
return `svc${i}`;
|
|
392
|
+
},
|
|
393
|
+
canDetach: true,
|
|
394
|
+
styling: false,
|
|
395
|
+
directions: false,
|
|
396
|
+
// Positions are Mermaid's own layout (plus where the user dragged): "Arrange"
|
|
397
|
+
// would pin a dagre layout Mermaid never draws.
|
|
398
|
+
// "Tidy up" resets dragged positions to Mermaid's own layout (the registered family layout).
|
|
399
|
+
arrange: true,
|
|
400
|
+
preview: false,
|
|
401
|
+
connectable: true,
|
|
402
|
+
nodeFields: [
|
|
403
|
+
{
|
|
404
|
+
key: "icon",
|
|
405
|
+
label: "Icon",
|
|
406
|
+
type: "select",
|
|
407
|
+
options: ["cloud", "database", "disk", "internet", "server"].map((v) => ({
|
|
408
|
+
value: v,
|
|
409
|
+
label: v
|
|
410
|
+
}))
|
|
411
|
+
}
|
|
412
|
+
],
|
|
413
|
+
edgeFields: [
|
|
414
|
+
{ key: "sourceSide", label: "From side", type: "select", options: SIDE_OPTIONS },
|
|
415
|
+
{ key: "targetSide", label: "To side", type: "select", options: SIDE_OPTIONS }
|
|
416
|
+
],
|
|
417
|
+
newNode: () => ({ label: "New service", data: { icon: "server" } })
|
|
418
|
+
};
|
|
419
|
+
|
|
420
|
+
// src/diagram/families/sequence.ts
|
|
421
|
+
function nextParticipantId(graph) {
|
|
422
|
+
const taken = /* @__PURE__ */ new Set([...graph.nodes.map((n) => n.id), ...graph.groups.map((g) => g.id)]);
|
|
423
|
+
let i = 1;
|
|
424
|
+
while (taken.has(`P${i}`)) i++;
|
|
425
|
+
return `P${i}`;
|
|
426
|
+
}
|
|
427
|
+
var kind = (value, label, pattern, arrowEnd, arrowStart = "none") => ({ value, label, pattern, arrowStart, arrowEnd });
|
|
428
|
+
var sequenceUI = {
|
|
429
|
+
family: "sequence",
|
|
430
|
+
title: "Sequence diagram",
|
|
431
|
+
shapes: [
|
|
432
|
+
{ value: "rect", label: "Participant" },
|
|
433
|
+
{ value: "actor", label: "Actor" }
|
|
434
|
+
],
|
|
435
|
+
edgeKinds: [
|
|
436
|
+
kind("->>", "Sync", "solid", "arrow_point"),
|
|
437
|
+
kind("-->>", "Reply", "dotted", "arrow_point"),
|
|
438
|
+
kind("->", "Line", "solid", "none"),
|
|
439
|
+
kind("-->", "Dotted line", "dotted", "none"),
|
|
440
|
+
kind("-x", "Lost", "solid", "arrow_cross"),
|
|
441
|
+
kind("--x", "Dotted lost", "dotted", "arrow_cross"),
|
|
442
|
+
kind("-)", "Async", "solid", "arrow_open"),
|
|
443
|
+
kind("--)", "Dotted async", "dotted", "arrow_open"),
|
|
444
|
+
kind("<<->>", "Bidirectional", "solid", "arrow_point", "arrow_point")
|
|
445
|
+
],
|
|
446
|
+
patterns: [
|
|
447
|
+
{ value: "solid", label: "Solid" },
|
|
448
|
+
{ value: "dotted", label: "Dotted" }
|
|
449
|
+
],
|
|
450
|
+
arrowHeads: [
|
|
451
|
+
{ value: "none", label: "None" },
|
|
452
|
+
{ value: "arrow_point", label: "Arrow" },
|
|
453
|
+
{ value: "arrow_cross", label: "Cross" },
|
|
454
|
+
{ value: "arrow_open", label: "Open" }
|
|
455
|
+
],
|
|
456
|
+
groups: { supported: true, label: "Box" },
|
|
457
|
+
labels: true,
|
|
458
|
+
nodeNoun: "Participant",
|
|
459
|
+
edgeNoun: "Message",
|
|
460
|
+
nextId: nextParticipantId,
|
|
461
|
+
canDetach: true,
|
|
462
|
+
styling: false,
|
|
463
|
+
directions: false,
|
|
464
|
+
arrange: false,
|
|
465
|
+
endpoints: true,
|
|
466
|
+
preview: false,
|
|
467
|
+
edgeFields: [
|
|
468
|
+
{ key: "activate", label: "Activate target", type: "boolean" },
|
|
469
|
+
{ key: "deactivate", label: "Deactivate source", type: "boolean" },
|
|
470
|
+
{ key: "index", label: "Position (0 = first)", type: "number", min: 0 }
|
|
471
|
+
],
|
|
472
|
+
diagramFields: [{ key: "autonumber", label: "Number messages", type: "boolean" }],
|
|
473
|
+
newNode: () => ({ label: "New participant" })
|
|
474
|
+
};
|
|
475
|
+
|
|
476
|
+
// src/diagram/families/gitgraph.ts
|
|
477
|
+
function nextCommitId(graph) {
|
|
478
|
+
const taken = /* @__PURE__ */ new Set([...graph.nodes.map((n) => n.id), ...graph.groups.map((g) => g.id)]);
|
|
479
|
+
let i = graph.nodes.length + 1;
|
|
480
|
+
while (taken.has(`commit${i}`)) i++;
|
|
481
|
+
return `commit${i}`;
|
|
482
|
+
}
|
|
483
|
+
var gitGraphUI = {
|
|
484
|
+
family: "gitGraph",
|
|
485
|
+
title: "Git graph",
|
|
486
|
+
shapes: [{ value: "commit", label: "Commit" }],
|
|
487
|
+
edgeKinds: [
|
|
488
|
+
{
|
|
489
|
+
value: "parent",
|
|
490
|
+
label: "Parent",
|
|
491
|
+
arrowStart: "none",
|
|
492
|
+
arrowEnd: "arrow_point",
|
|
493
|
+
pattern: "solid"
|
|
494
|
+
}
|
|
495
|
+
],
|
|
496
|
+
patterns: [{ value: "solid", label: "Solid" }],
|
|
497
|
+
arrowHeads: [{ value: "arrow_point", label: "Arrow" }],
|
|
498
|
+
groups: { supported: true, label: "Branch" },
|
|
499
|
+
labels: true,
|
|
500
|
+
nodeNoun: "Commit",
|
|
501
|
+
edgeNoun: "Parent link",
|
|
502
|
+
nextId: nextCommitId,
|
|
503
|
+
canDetach: false,
|
|
504
|
+
styling: false,
|
|
505
|
+
connectable: true,
|
|
506
|
+
directions: true,
|
|
507
|
+
groupDirections: false,
|
|
508
|
+
arrange: false,
|
|
509
|
+
preview: false,
|
|
510
|
+
nodeFields: [
|
|
511
|
+
{ key: "tag", label: "Tag", type: "text" },
|
|
512
|
+
{
|
|
513
|
+
key: "type",
|
|
514
|
+
label: "Type",
|
|
515
|
+
type: "select",
|
|
516
|
+
options: [
|
|
517
|
+
{ value: "NORMAL", label: "Normal" },
|
|
518
|
+
{ value: "REVERSE", label: "Reverse" },
|
|
519
|
+
{ value: "HIGHLIGHT", label: "Highlight" }
|
|
520
|
+
]
|
|
521
|
+
},
|
|
522
|
+
{ key: "msg", label: "Message", type: "text" }
|
|
523
|
+
],
|
|
524
|
+
newNode: () => ({ label: "New commit" })
|
|
525
|
+
};
|
|
526
|
+
|
|
527
|
+
// src/diagram/families/gantt.ts
|
|
528
|
+
function nextTaskId(graph) {
|
|
529
|
+
const taken = /* @__PURE__ */ new Set([...graph.nodes.map((n) => n.id), ...graph.groups.map((g) => g.id)]);
|
|
530
|
+
let i = graph.nodes.length + 1;
|
|
531
|
+
while (taken.has(`task${i}`)) i++;
|
|
532
|
+
return `task${i}`;
|
|
533
|
+
}
|
|
534
|
+
function newTaskStart(graph) {
|
|
535
|
+
const format = typeof graph.data?.dateFormat === "string" ? graph.data.dateFormat : void 0;
|
|
536
|
+
const ends = graph.nodes.map((n) => n.data?.endTime).filter((t) => typeof t === "number" && Number.isFinite(t));
|
|
537
|
+
if (ends.length) return formatGanttDate(Math.max(...ends), format);
|
|
538
|
+
const starts = graph.nodes.map((n) => n.data?.startTime).filter((t) => typeof t === "number" && Number.isFinite(t));
|
|
539
|
+
if (starts.length) return formatGanttDate(Math.min(...starts), format);
|
|
540
|
+
return "2026-01-01";
|
|
541
|
+
}
|
|
542
|
+
var ganttUI = {
|
|
543
|
+
family: "gantt",
|
|
544
|
+
title: "Gantt chart",
|
|
545
|
+
shapes: [
|
|
546
|
+
{ value: "task", label: "Task" },
|
|
547
|
+
{ value: "milestone", label: "Milestone" }
|
|
548
|
+
],
|
|
549
|
+
edgeKinds: [
|
|
550
|
+
{
|
|
551
|
+
value: "depends",
|
|
552
|
+
label: "Depends on",
|
|
553
|
+
arrowStart: "none",
|
|
554
|
+
arrowEnd: "arrow_point",
|
|
555
|
+
pattern: "solid"
|
|
556
|
+
}
|
|
557
|
+
],
|
|
558
|
+
patterns: [],
|
|
559
|
+
arrowHeads: [],
|
|
560
|
+
groups: { supported: true, label: "Section" },
|
|
561
|
+
labels: true,
|
|
562
|
+
nodeNoun: "Task",
|
|
563
|
+
edgeNoun: "Dependency",
|
|
564
|
+
nextId: nextTaskId,
|
|
565
|
+
canDetach: true,
|
|
566
|
+
styling: false,
|
|
567
|
+
// Connecting A → B writes `after A` into B's start.
|
|
568
|
+
connectable: true,
|
|
569
|
+
directions: false,
|
|
570
|
+
arrange: false,
|
|
571
|
+
preview: false,
|
|
572
|
+
nodeFields: [
|
|
573
|
+
{ key: "start", label: "Start", type: "text", placeholder: "2026-10-01 or after ds" },
|
|
574
|
+
{ key: "end", label: "End or duration", type: "text", placeholder: "14d" },
|
|
575
|
+
{
|
|
576
|
+
key: "tags",
|
|
577
|
+
label: "Tags",
|
|
578
|
+
type: "tags",
|
|
579
|
+
hint: "done, active, crit, milestone, vert",
|
|
580
|
+
options: GANTT_TAGS.map((t) => ({ value: t, label: t }))
|
|
581
|
+
},
|
|
582
|
+
{ key: "id", label: "Task id", type: "text" }
|
|
583
|
+
],
|
|
584
|
+
diagramFields: [
|
|
585
|
+
{ key: "dateFormat", label: "Date format", type: "text", placeholder: "YYYY-MM-DD" },
|
|
586
|
+
{ key: "axisFormat", label: "Axis format", type: "text", placeholder: "%b %d" },
|
|
587
|
+
{ key: "excludes", label: "Excludes", type: "text", placeholder: "weekends" },
|
|
588
|
+
{ key: "tickInterval", label: "Tick interval", type: "text", placeholder: "1week" },
|
|
589
|
+
{ key: "todayMarker", label: "Today marker", type: "text", placeholder: "off" }
|
|
590
|
+
],
|
|
591
|
+
newNode: (graph) => ({
|
|
592
|
+
label: "New task",
|
|
593
|
+
shape: "task",
|
|
594
|
+
data: { start: newTaskStart(graph), end: "7d" }
|
|
595
|
+
})
|
|
596
|
+
};
|
|
597
|
+
|
|
598
|
+
// src/diagram/families/timeline.ts
|
|
599
|
+
function nextPeriodId(graph) {
|
|
600
|
+
const taken = /* @__PURE__ */ new Set([...graph.nodes.map((n) => n.id), ...graph.groups.map((g) => g.id)]);
|
|
601
|
+
let i = graph.nodes.length + 1;
|
|
602
|
+
while (taken.has(`period${i}`)) i++;
|
|
603
|
+
return `period${i}`;
|
|
604
|
+
}
|
|
605
|
+
var timelineUI = {
|
|
606
|
+
family: "timeline",
|
|
607
|
+
title: "Timeline",
|
|
608
|
+
shapes: [{ value: "rounded", label: "Period" }],
|
|
609
|
+
edgeKinds: [],
|
|
610
|
+
patterns: [],
|
|
611
|
+
arrowHeads: [],
|
|
612
|
+
groups: { supported: true, label: "Section" },
|
|
613
|
+
labels: true,
|
|
614
|
+
nodeNoun: "Period",
|
|
615
|
+
nextId: nextPeriodId,
|
|
616
|
+
canDetach: true,
|
|
617
|
+
styling: false,
|
|
618
|
+
connectable: false,
|
|
619
|
+
directions: false,
|
|
620
|
+
arrange: false,
|
|
621
|
+
preview: false,
|
|
622
|
+
nodeFields: [{ key: "events", label: "Events (one per line)", type: "lines" }],
|
|
623
|
+
newNode: () => ({ label: "New period", shape: "rounded", data: { events: ["Event"] } })
|
|
624
|
+
};
|
|
625
|
+
|
|
626
|
+
// src/diagram/families/journey.ts
|
|
627
|
+
function nextTaskId2(graph) {
|
|
628
|
+
const taken = /* @__PURE__ */ new Set([...graph.nodes.map((n) => n.id), ...graph.groups.map((g) => g.id)]);
|
|
629
|
+
let i = graph.nodes.length + 1;
|
|
630
|
+
while (taken.has(`task${i}`)) i++;
|
|
631
|
+
return `task${i}`;
|
|
632
|
+
}
|
|
633
|
+
var journeyUI = {
|
|
634
|
+
family: "journey",
|
|
635
|
+
title: "User journey",
|
|
636
|
+
shapes: [{ value: "rect", label: "Task" }],
|
|
637
|
+
edgeKinds: [],
|
|
638
|
+
patterns: [],
|
|
639
|
+
arrowHeads: [],
|
|
640
|
+
groups: { supported: true, label: "Section" },
|
|
641
|
+
labels: true,
|
|
642
|
+
nodeNoun: "Task",
|
|
643
|
+
nextId: nextTaskId2,
|
|
644
|
+
canDetach: true,
|
|
645
|
+
styling: false,
|
|
646
|
+
connectable: false,
|
|
647
|
+
directions: false,
|
|
648
|
+
arrange: false,
|
|
649
|
+
preview: false,
|
|
650
|
+
nodeFields: [
|
|
651
|
+
{ key: "score", label: "Score", type: "number", min: 1, max: 5, step: 1 },
|
|
652
|
+
{ key: "actors", label: "Actors", type: "tags" }
|
|
653
|
+
],
|
|
654
|
+
newNode: () => ({ label: "New task", shape: "rect", data: { score: 3, actors: [] } })
|
|
655
|
+
};
|
|
656
|
+
|
|
657
|
+
// src/diagram/families/xychart.ts
|
|
658
|
+
var xyChartUI = {
|
|
659
|
+
family: "xychart",
|
|
660
|
+
title: "XY chart",
|
|
661
|
+
shapes: [
|
|
662
|
+
{ value: "bar", label: "Bar" },
|
|
663
|
+
{ value: "line", label: "Line" }
|
|
664
|
+
],
|
|
665
|
+
edgeKinds: [],
|
|
666
|
+
patterns: [],
|
|
667
|
+
arrowHeads: [],
|
|
668
|
+
groups: { supported: false, label: "Group" },
|
|
669
|
+
labels: true,
|
|
670
|
+
nodeNoun: "Series",
|
|
671
|
+
nextId: (g) => `series${g.nodes.length + 1}`,
|
|
672
|
+
canDetach: false,
|
|
673
|
+
styling: false,
|
|
674
|
+
connectable: false,
|
|
675
|
+
directions: false,
|
|
676
|
+
arrange: false,
|
|
677
|
+
preview: false,
|
|
678
|
+
nodeFields: [
|
|
679
|
+
{ key: "values", label: "Values", type: "numbers", hint: "One per x-axis category" }
|
|
680
|
+
],
|
|
681
|
+
diagramFields: [
|
|
682
|
+
{ key: "categories", label: "X-axis categories", type: "lines", placeholder: "One per line" },
|
|
683
|
+
{ key: "xTitle", label: "X-axis title", type: "text" },
|
|
684
|
+
{ key: "yTitle", label: "Y-axis title", type: "text" },
|
|
685
|
+
{ key: "yMin", label: "Y-axis min", type: "number" },
|
|
686
|
+
{ key: "yMax", label: "Y-axis max", type: "number" },
|
|
687
|
+
{ key: "horizontal", label: "Horizontal", type: "boolean" }
|
|
688
|
+
],
|
|
689
|
+
newNode: () => ({ label: "New series", shape: "bar" })
|
|
690
|
+
};
|
|
691
|
+
|
|
692
|
+
// src/diagram/families/radar.ts
|
|
693
|
+
var radarUI = {
|
|
694
|
+
family: "radar",
|
|
695
|
+
title: "Radar chart",
|
|
696
|
+
shapes: [{ value: "curve", label: "Curve" }],
|
|
697
|
+
edgeKinds: [],
|
|
698
|
+
patterns: [],
|
|
699
|
+
arrowHeads: [],
|
|
700
|
+
groups: { supported: false, label: "Group" },
|
|
701
|
+
labels: true,
|
|
702
|
+
nodeNoun: "Curve",
|
|
703
|
+
nextId: (g) => {
|
|
704
|
+
const taken = new Set(g.nodes.map((n) => n.id));
|
|
705
|
+
let i = g.nodes.length + 1;
|
|
706
|
+
while (taken.has(`curve${i}`)) i++;
|
|
707
|
+
return `curve${i}`;
|
|
708
|
+
},
|
|
709
|
+
canDetach: false,
|
|
710
|
+
styling: false,
|
|
711
|
+
connectable: false,
|
|
712
|
+
directions: false,
|
|
713
|
+
arrange: false,
|
|
714
|
+
preview: false,
|
|
715
|
+
nodeFields: [{ key: "values", label: "Values", type: "numbers", hint: "One per axis" }],
|
|
716
|
+
diagramFields: [
|
|
717
|
+
{ key: "axes", label: "Axes", type: "lines", placeholder: "One per line" },
|
|
718
|
+
{ key: "max", label: "Max", type: "number" },
|
|
719
|
+
{ key: "min", label: "Min", type: "number" },
|
|
720
|
+
{ key: "ticks", label: "Ticks", type: "number", min: 1 },
|
|
721
|
+
{
|
|
722
|
+
key: "graticule",
|
|
723
|
+
label: "Grid",
|
|
724
|
+
type: "select",
|
|
725
|
+
options: [
|
|
726
|
+
{ value: "circle", label: "Circles" },
|
|
727
|
+
{ value: "polygon", label: "Polygons" }
|
|
728
|
+
]
|
|
729
|
+
},
|
|
730
|
+
{ key: "showLegend", label: "Show legend", type: "boolean" }
|
|
731
|
+
],
|
|
732
|
+
newNode: () => ({ label: "New curve" })
|
|
733
|
+
};
|
|
734
|
+
|
|
735
|
+
// src/diagram/families/fields.ts
|
|
736
|
+
function describeFields(fields) {
|
|
737
|
+
return (fields ?? []).map((f) => ({
|
|
738
|
+
key: f.key,
|
|
739
|
+
label: f.label,
|
|
740
|
+
type: f.type,
|
|
741
|
+
...f.options ? { options: f.options.map((o) => o.value) } : {},
|
|
742
|
+
...f.min !== void 0 ? { min: f.min } : {},
|
|
743
|
+
...f.max !== void 0 ? { max: f.max } : {},
|
|
744
|
+
...f.hint ? { hint: f.hint } : {},
|
|
745
|
+
...f.shapes ? { shapes: f.shapes } : {}
|
|
746
|
+
}));
|
|
747
|
+
}
|
|
748
|
+
function pickFieldData(fields, data) {
|
|
749
|
+
const out = {};
|
|
750
|
+
for (const f of fields ?? []) {
|
|
751
|
+
const value = data?.[f.key];
|
|
752
|
+
if (value !== void 0 && value !== null && !(Array.isArray(value) && !value.length)) out[f.key] = value;
|
|
753
|
+
}
|
|
754
|
+
return out;
|
|
755
|
+
}
|
|
756
|
+
var list = (items) => items.map((s) => `"${s}"`).join(", ");
|
|
757
|
+
function checkFieldData(fields, data, what, shape) {
|
|
758
|
+
const all = fields ?? [];
|
|
759
|
+
const usable = all.filter((f) => !f.shapes || shape === void 0 || f.shapes.includes(shape));
|
|
760
|
+
if (!all.length) throw new Error(`${what} has no data fields to set.`);
|
|
761
|
+
const keys = Object.keys(data);
|
|
762
|
+
if (!keys.length) throw new Error(`Give at least one field to set; ${what} has ${list(usable.map((f) => f.key))}.`);
|
|
763
|
+
const out = {};
|
|
764
|
+
for (const key of keys) {
|
|
765
|
+
const field = all.find((f) => f.key === key);
|
|
766
|
+
if (!field) throw new Error(`Unknown field "${key}" for ${what}; use one of ${list(usable.map((f) => f.key))}.`);
|
|
767
|
+
if (!usable.includes(field))
|
|
768
|
+
throw new Error(`Field "${key}" only applies to ${list(field.shapes)} nodes, not "${shape}".`);
|
|
769
|
+
const value = data[key];
|
|
770
|
+
if (value === null || value === "") {
|
|
771
|
+
out[key] = void 0;
|
|
772
|
+
continue;
|
|
773
|
+
}
|
|
774
|
+
const bad = (expected) => new Error(`Field "${key}" (${field.label}) takes ${expected}; got ${JSON.stringify(value)}.`);
|
|
775
|
+
switch (field.type) {
|
|
776
|
+
case "number": {
|
|
777
|
+
if (typeof value !== "number" || !Number.isFinite(value)) throw bad("a number");
|
|
778
|
+
if (field.min !== void 0 && value < field.min) throw bad(`a number of at least ${field.min}`);
|
|
779
|
+
if (field.max !== void 0 && value > field.max) throw bad(`a number of at most ${field.max}`);
|
|
780
|
+
break;
|
|
781
|
+
}
|
|
782
|
+
case "numbers":
|
|
783
|
+
if (!Array.isArray(value) || !value.every((n) => typeof n === "number" && Number.isFinite(n))) throw bad("an array of numbers");
|
|
784
|
+
break;
|
|
785
|
+
case "lines":
|
|
786
|
+
case "tags":
|
|
787
|
+
if (!Array.isArray(value) || !value.every((s) => typeof s === "string")) throw bad("an array of strings");
|
|
788
|
+
break;
|
|
789
|
+
case "boolean":
|
|
790
|
+
if (typeof value !== "boolean") throw bad("true or false");
|
|
791
|
+
break;
|
|
792
|
+
case "select": {
|
|
793
|
+
const options = (field.options ?? []).map((o) => o.value);
|
|
794
|
+
if (typeof value !== "string" || options.length && !options.includes(value)) throw bad(`one of ${list(options)}`);
|
|
795
|
+
break;
|
|
796
|
+
}
|
|
797
|
+
default:
|
|
798
|
+
if (typeof value !== "string") throw bad("a string");
|
|
799
|
+
}
|
|
800
|
+
out[key] = value;
|
|
801
|
+
}
|
|
802
|
+
return out;
|
|
803
|
+
}
|
|
804
|
+
|
|
805
|
+
// src/diagram/families/index.ts
|
|
806
|
+
function counterId(prefix, graph) {
|
|
807
|
+
const taken = /* @__PURE__ */ new Set([...graph.nodes.map((n) => n.id), ...graph.groups.map((g) => g.id)]);
|
|
808
|
+
let i = graph.nodes.length + 1;
|
|
809
|
+
while (taken.has(`${prefix}${i}`)) i++;
|
|
810
|
+
return `${prefix}${i}`;
|
|
811
|
+
}
|
|
812
|
+
var FLOW_HEADS = [
|
|
813
|
+
{ value: "none", label: "None" },
|
|
814
|
+
{ value: "arrow_point", label: "Arrow" },
|
|
815
|
+
{ value: "arrow_circle", label: "Circle" },
|
|
816
|
+
{ value: "arrow_cross", label: "Cross" }
|
|
817
|
+
];
|
|
818
|
+
var IMAGE_FIELDS = [
|
|
819
|
+
{
|
|
820
|
+
key: "img",
|
|
821
|
+
label: "Image URL",
|
|
822
|
+
type: "text",
|
|
823
|
+
placeholder: "https://\u2026/picture.png",
|
|
824
|
+
shapes: ["image"]
|
|
825
|
+
},
|
|
826
|
+
{
|
|
827
|
+
key: "pos",
|
|
828
|
+
label: "Label",
|
|
829
|
+
type: "select",
|
|
830
|
+
options: [
|
|
831
|
+
{ value: "b", label: "Below" },
|
|
832
|
+
{ value: "t", label: "Above" }
|
|
833
|
+
],
|
|
834
|
+
shapes: ["image"]
|
|
835
|
+
},
|
|
836
|
+
{ key: "w", label: "Width", type: "number", min: 8, step: 1, shapes: ["image"] },
|
|
837
|
+
{ key: "h", label: "Height", type: "number", min: 8, step: 1, shapes: ["image"] },
|
|
838
|
+
{
|
|
839
|
+
key: "constraint",
|
|
840
|
+
label: "Keep aspect ratio",
|
|
841
|
+
type: "select",
|
|
842
|
+
options: [
|
|
843
|
+
{ value: "on", label: "On" },
|
|
844
|
+
{ value: "off", label: "Off" }
|
|
845
|
+
],
|
|
846
|
+
shapes: ["image"]
|
|
847
|
+
}
|
|
848
|
+
];
|
|
849
|
+
var flowchartUI = {
|
|
850
|
+
family: "flowchart",
|
|
851
|
+
nodeFields: IMAGE_FIELDS,
|
|
852
|
+
title: "Flowchart",
|
|
853
|
+
shapes: FLOWCHART_SHAPES.map((s) => ({ value: s.name, label: s.title, category: s.category })),
|
|
854
|
+
edgeKinds: [
|
|
855
|
+
{
|
|
856
|
+
value: "arrow",
|
|
857
|
+
label: "Arrow",
|
|
858
|
+
arrowStart: "none",
|
|
859
|
+
arrowEnd: "arrow_point",
|
|
860
|
+
pattern: "solid"
|
|
861
|
+
},
|
|
862
|
+
{ value: "open", label: "Line", arrowStart: "none", arrowEnd: "none", pattern: "solid" },
|
|
863
|
+
{
|
|
864
|
+
value: "dotted",
|
|
865
|
+
label: "Dotted arrow",
|
|
866
|
+
arrowStart: "none",
|
|
867
|
+
arrowEnd: "arrow_point",
|
|
868
|
+
pattern: "dotted"
|
|
869
|
+
},
|
|
870
|
+
{
|
|
871
|
+
value: "thick",
|
|
872
|
+
label: "Thick arrow",
|
|
873
|
+
arrowStart: "none",
|
|
874
|
+
arrowEnd: "arrow_point",
|
|
875
|
+
pattern: "thick"
|
|
876
|
+
},
|
|
877
|
+
{
|
|
878
|
+
value: "bidir",
|
|
879
|
+
label: "Bidirectional",
|
|
880
|
+
arrowStart: "arrow_point",
|
|
881
|
+
arrowEnd: "arrow_point",
|
|
882
|
+
pattern: "solid"
|
|
883
|
+
},
|
|
884
|
+
{
|
|
885
|
+
value: "invisible",
|
|
886
|
+
label: "Invisible (layout)",
|
|
887
|
+
arrowStart: "none",
|
|
888
|
+
arrowEnd: "none",
|
|
889
|
+
pattern: "invisible"
|
|
890
|
+
}
|
|
891
|
+
],
|
|
892
|
+
patterns: [
|
|
893
|
+
{ value: "solid", label: "Solid" },
|
|
894
|
+
{ value: "dotted", label: "Dotted" },
|
|
895
|
+
{ value: "thick", label: "Thick" },
|
|
896
|
+
{ value: "invisible", label: "Invisible" }
|
|
897
|
+
],
|
|
898
|
+
arrowHeads: FLOW_HEADS,
|
|
899
|
+
groups: { supported: true, label: "Subgraph" },
|
|
900
|
+
labels: true,
|
|
901
|
+
nodeNoun: "Node",
|
|
902
|
+
nextId: (g) => counterId("n", g),
|
|
903
|
+
canDetach: false
|
|
904
|
+
};
|
|
905
|
+
var stateUI = {
|
|
906
|
+
family: "state",
|
|
907
|
+
title: "State diagram",
|
|
908
|
+
shapes: [
|
|
909
|
+
{ value: "rect", label: "State" },
|
|
910
|
+
{ value: "choice", label: "Choice" },
|
|
911
|
+
{ value: "fork", label: "Fork" },
|
|
912
|
+
{ value: "join", label: "Join" }
|
|
913
|
+
],
|
|
914
|
+
edgeKinds: [
|
|
915
|
+
{
|
|
916
|
+
value: "transition",
|
|
917
|
+
label: "Transition",
|
|
918
|
+
arrowStart: "none",
|
|
919
|
+
arrowEnd: "arrow_barb",
|
|
920
|
+
pattern: "solid"
|
|
921
|
+
}
|
|
922
|
+
],
|
|
923
|
+
patterns: [{ value: "solid", label: "Solid" }],
|
|
924
|
+
arrowHeads: [{ value: "arrow_barb", label: "Arrow" }],
|
|
925
|
+
groups: { supported: true, label: "Composite state" },
|
|
926
|
+
labels: true,
|
|
927
|
+
nodeNoun: "State",
|
|
928
|
+
nextId: (g) => counterId("State", g),
|
|
929
|
+
canDetach: true
|
|
930
|
+
};
|
|
931
|
+
var classUI = {
|
|
932
|
+
family: "class",
|
|
933
|
+
title: "Class diagram",
|
|
934
|
+
shapes: [{ value: "classBox", label: "Class" }],
|
|
935
|
+
edgeKinds: CLASS_RELATIONS.filter((r) => !r.title.includes("reversed")).map((r) => ({
|
|
936
|
+
value: r.token,
|
|
937
|
+
label: r.title,
|
|
938
|
+
arrowStart: r.arrowStart,
|
|
939
|
+
arrowEnd: r.arrowEnd,
|
|
940
|
+
pattern: r.pattern
|
|
941
|
+
})),
|
|
942
|
+
patterns: [
|
|
943
|
+
{ value: "solid", label: "Solid" },
|
|
944
|
+
{ value: "dotted", label: "Dashed" }
|
|
945
|
+
],
|
|
946
|
+
arrowHeads: [
|
|
947
|
+
{ value: "none", label: "None" },
|
|
948
|
+
{ value: "extension", label: "Inheritance" },
|
|
949
|
+
{ value: "composition", label: "Composition" },
|
|
950
|
+
{ value: "aggregation", label: "Aggregation" },
|
|
951
|
+
{ value: "dependency", label: "Arrow" },
|
|
952
|
+
{ value: "lollipop", label: "Lollipop" }
|
|
953
|
+
],
|
|
954
|
+
groups: { supported: true, label: "Namespace" },
|
|
955
|
+
labels: true,
|
|
956
|
+
nodeNoun: "Class",
|
|
957
|
+
nextId: (g) => counterId("Class", g),
|
|
958
|
+
canDetach: true
|
|
959
|
+
};
|
|
960
|
+
var erUI = {
|
|
961
|
+
family: "er",
|
|
962
|
+
title: "Entity relationship",
|
|
963
|
+
shapes: [{ value: "erBox", label: "Entity" }],
|
|
964
|
+
edgeKinds: [
|
|
965
|
+
{
|
|
966
|
+
value: "one-many",
|
|
967
|
+
label: "One to many",
|
|
968
|
+
arrowStart: "only_one",
|
|
969
|
+
arrowEnd: "zero_or_more",
|
|
970
|
+
pattern: "solid"
|
|
971
|
+
},
|
|
972
|
+
{
|
|
973
|
+
value: "one-one",
|
|
974
|
+
label: "One to one",
|
|
975
|
+
arrowStart: "only_one",
|
|
976
|
+
arrowEnd: "only_one",
|
|
977
|
+
pattern: "solid"
|
|
978
|
+
},
|
|
979
|
+
{
|
|
980
|
+
value: "many-many",
|
|
981
|
+
label: "Many to many",
|
|
982
|
+
arrowStart: "zero_or_more",
|
|
983
|
+
arrowEnd: "zero_or_more",
|
|
984
|
+
pattern: "solid"
|
|
985
|
+
},
|
|
986
|
+
{
|
|
987
|
+
value: "one-many-ni",
|
|
988
|
+
label: "One to many (non-identifying)",
|
|
989
|
+
arrowStart: "only_one",
|
|
990
|
+
arrowEnd: "zero_or_more",
|
|
991
|
+
pattern: "dotted"
|
|
992
|
+
}
|
|
993
|
+
],
|
|
994
|
+
patterns: [
|
|
995
|
+
{ value: "solid", label: "Identifying" },
|
|
996
|
+
{ value: "dotted", label: "Non-identifying" }
|
|
997
|
+
],
|
|
998
|
+
arrowHeads: Array.from(
|
|
999
|
+
new Map(ER_CARDINALITIES.map((c) => [c.head, { value: c.head, label: c.title }])).values()
|
|
1000
|
+
),
|
|
1001
|
+
groups: { supported: false, label: "Group" },
|
|
1002
|
+
labels: true,
|
|
1003
|
+
nodeNoun: "Entity",
|
|
1004
|
+
nextId: (g) => counterId("ENTITY_", g),
|
|
1005
|
+
canDetach: true
|
|
1006
|
+
};
|
|
1007
|
+
var FAMILY_UI = {
|
|
1008
|
+
flowchart: flowchartUI,
|
|
1009
|
+
state: stateUI,
|
|
1010
|
+
class: classUI,
|
|
1011
|
+
er: erUI,
|
|
1012
|
+
pie: pieUI,
|
|
1013
|
+
mindmap: mindmapUI,
|
|
1014
|
+
quadrant: quadrantUI,
|
|
1015
|
+
c4: c4UI,
|
|
1016
|
+
architecture: architectureUI,
|
|
1017
|
+
sequence: sequenceUI,
|
|
1018
|
+
gitGraph: gitGraphUI,
|
|
1019
|
+
gantt: ganttUI,
|
|
1020
|
+
timeline: timelineUI,
|
|
1021
|
+
journey: journeyUI,
|
|
1022
|
+
xychart: xyChartUI,
|
|
1023
|
+
radar: radarUI
|
|
1024
|
+
};
|
|
1025
|
+
function familyUI(family) {
|
|
1026
|
+
return FAMILY_UI[family] ?? null;
|
|
1027
|
+
}
|
|
1028
|
+
var FAMILY_TITLES = {
|
|
1029
|
+
flowchart: "Flowchart",
|
|
1030
|
+
state: "State diagram",
|
|
1031
|
+
class: "Class diagram",
|
|
1032
|
+
er: "Entity relationship",
|
|
1033
|
+
requirement: "Requirement diagram",
|
|
1034
|
+
mindmap: "Mind map",
|
|
1035
|
+
sequence: "Sequence diagram",
|
|
1036
|
+
gantt: "Gantt chart",
|
|
1037
|
+
pie: "Pie chart",
|
|
1038
|
+
journey: "User journey",
|
|
1039
|
+
timeline: "Timeline",
|
|
1040
|
+
gitGraph: "Git graph",
|
|
1041
|
+
c4: "C4 diagram",
|
|
1042
|
+
quadrant: "Quadrant chart",
|
|
1043
|
+
sankey: "Sankey diagram",
|
|
1044
|
+
xychart: "XY chart",
|
|
1045
|
+
block: "Block diagram",
|
|
1046
|
+
architecture: "Architecture diagram",
|
|
1047
|
+
packet: "Packet diagram",
|
|
1048
|
+
kanban: "Kanban board",
|
|
1049
|
+
radar: "Radar chart",
|
|
1050
|
+
treemap: "Treemap",
|
|
1051
|
+
info: "Info",
|
|
1052
|
+
unknown: "Unknown diagram"
|
|
1053
|
+
};
|
|
1054
|
+
var FAMILY_TEMPLATES = {
|
|
1055
|
+
flowchart: "flowchart TD\n A[Start] --> B{Decision}\n B -->|Yes| C[Do it]\n B -->|No| D[Skip]\n C --> E[End]\n D --> E\n",
|
|
1056
|
+
state: "stateDiagram-v2\n [*] --> Idle\n Idle --> Active : start\n Active --> Idle : stop\n Active --> [*] : finish\n",
|
|
1057
|
+
class: 'classDiagram\n class Account {\n +String id\n +deposit(amount)\n }\n class Customer\n Customer "1" --> "*" Account : owns\n',
|
|
1058
|
+
er: "erDiagram\n CUSTOMER ||--o{ ORDER : places\n ORDER ||--|{ LINE_ITEM : contains\n CUSTOMER {\n string name PK\n string email\n }\n",
|
|
1059
|
+
sequence: "sequenceDiagram\n participant U as User\n participant S as Service\n U->>S: Request\n S-->>U: Response\n",
|
|
1060
|
+
pie: 'pie showData\n title Share by segment\n "Segment A" : 40\n "Segment B" : 35\n "Segment C" : 25\n',
|
|
1061
|
+
mindmap: "mindmap\n root((Central idea))\n Topic A\n Detail\n Topic B\n Topic C\n",
|
|
1062
|
+
timeline: "timeline\n title Milestones\n 2024 : First release\n 2025 : Second release\n : Expansion\n 2026 : Next chapter\n",
|
|
1063
|
+
journey: "journey\n title Customer journey\n section Discover\n Find the product: 3: Customer\n section Buy\n Check out: 4: Customer\n Confirm order: 5: Customer, Support\n",
|
|
1064
|
+
gantt: "gantt\n title Plan\n dateFormat YYYY-MM-DD\n section Phase 1\n Research :a1, 2026-01-05, 10d\n Design :a2, after a1, 7d\n section Phase 2\n Build :a3, after a2, 14d\n",
|
|
1065
|
+
gitGraph: 'gitGraph\n commit id: "init"\n branch develop\n checkout develop\n commit id: "feature"\n checkout main\n merge develop tag: "v1.0"\n',
|
|
1066
|
+
c4: 'C4Context\n title System context\n Person(user, "User", "Uses the system")\n System(sys, "System", "Does the work")\n System_Ext(ext, "External service", "Provides data")\n Rel(user, sys, "Uses")\n Rel(sys, ext, "Calls")\n',
|
|
1067
|
+
architecture: "architecture-beta\n group app(cloud)[Application]\n service web(server)[Web] in app\n service db(database)[Database] in app\n service edge(internet)[Edge]\n edge:R --> L:web\n web:B --> T:db\n",
|
|
1068
|
+
quadrant: "quadrantChart\n title Prioritisation\n x-axis Low effort --> High effort\n y-axis Low value --> High value\n quadrant-1 Plan\n quadrant-2 Do first\n quadrant-3 Drop\n quadrant-4 Fill-ins\n Idea A: [0.3, 0.8]\n Idea B: [0.7, 0.6]\n Idea C: [0.2, 0.3]\n",
|
|
1069
|
+
xychart: 'xychart-beta\n title "Monthly sales"\n x-axis [Jan, Feb, Mar, Apr]\n y-axis "Units" 0 --> 100\n bar [42, 58, 71, 64]\n line "Target" [50, 55, 60, 65]\n',
|
|
1070
|
+
radar: 'radar-beta\n title Option comparison\n axis cost["Cost"], speed["Speed"], quality["Quality"], risk["Risk"]\n curve a["Option A"]{80, 60, 90, 40}\n curve b["Option B"]{50, 90, 60, 70}\n max 100\n'
|
|
1071
|
+
};
|
|
1072
|
+
var FAMILY_BLANKS = {
|
|
1073
|
+
flowchart: "flowchart TD\n",
|
|
1074
|
+
state: "stateDiagram-v2\n",
|
|
1075
|
+
class: "classDiagram\n direction TB\n",
|
|
1076
|
+
er: "erDiagram\n",
|
|
1077
|
+
sequence: "sequenceDiagram\n",
|
|
1078
|
+
pie: "pie\n",
|
|
1079
|
+
mindmap: "mindmap\n",
|
|
1080
|
+
timeline: "timeline\n",
|
|
1081
|
+
journey: "journey\n",
|
|
1082
|
+
gantt: "gantt\n dateFormat YYYY-MM-DD\n",
|
|
1083
|
+
gitGraph: "gitGraph\n",
|
|
1084
|
+
c4: "C4Context\n title System context\n",
|
|
1085
|
+
architecture: "architecture-beta\n",
|
|
1086
|
+
quadrant: "quadrantChart\n",
|
|
1087
|
+
xychart: "xychart-beta\n",
|
|
1088
|
+
radar: "radar-beta\n"
|
|
1089
|
+
};
|
|
1090
|
+
var FAMILY_DESCRIPTIONS = {
|
|
1091
|
+
flowchart: "Steps, decisions and the paths between them.",
|
|
1092
|
+
state: "The states something moves through and what triggers each change.",
|
|
1093
|
+
class: "Types with their fields and methods, and how they relate.",
|
|
1094
|
+
er: "Entities, their attributes and the relationships between them.",
|
|
1095
|
+
sequence: "Messages exchanged between participants over time.",
|
|
1096
|
+
pie: "Parts of a whole as slices.",
|
|
1097
|
+
mindmap: "Ideas branching out from a central topic.",
|
|
1098
|
+
timeline: "Events grouped by period, in order.",
|
|
1099
|
+
journey: "A user's tasks, section by section, scored by how they feel.",
|
|
1100
|
+
gantt: "Tasks on a calendar with durations and dependencies.",
|
|
1101
|
+
gitGraph: "Branches, commits and merges of a repository.",
|
|
1102
|
+
c4: "People and software systems, and how they interact.",
|
|
1103
|
+
architecture: "Services and infrastructure grouped by where they run.",
|
|
1104
|
+
quadrant: "Items placed on two axes in four quadrants.",
|
|
1105
|
+
xychart: "Bars and lines over categories or a numeric axis.",
|
|
1106
|
+
radar: "Scores across several axes, one curve per item compared."
|
|
1107
|
+
};
|
|
1108
|
+
|
|
1109
|
+
// src/diagram/sankey/index.ts
|
|
1110
|
+
function parseSankey(source) {
|
|
1111
|
+
const split = splitSource(source);
|
|
1112
|
+
if (!/^\s*sankey(?:-beta)?\b/i.test(split.header)) {
|
|
1113
|
+
return { error: "Not a sankey diagram: the first line should be `sankey-beta`." };
|
|
1114
|
+
}
|
|
1115
|
+
const firstLine = split.headerIndex + 2;
|
|
1116
|
+
const kept = [];
|
|
1117
|
+
split.bodyLines.forEach((text, i) => {
|
|
1118
|
+
if (/^\s*%%/.test(text)) return;
|
|
1119
|
+
kept.push({ text: text.trim(), line: firstLine + i });
|
|
1120
|
+
});
|
|
1121
|
+
const records = readRecords(kept);
|
|
1122
|
+
if ("error" in records) return records;
|
|
1123
|
+
const nodes = [];
|
|
1124
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1125
|
+
const add = (name) => {
|
|
1126
|
+
if (!seen.has(name)) {
|
|
1127
|
+
seen.add(name);
|
|
1128
|
+
nodes.push(name);
|
|
1129
|
+
}
|
|
1130
|
+
};
|
|
1131
|
+
const links = [];
|
|
1132
|
+
for (const { fields, line } of records) {
|
|
1133
|
+
if (fields.length !== 3) {
|
|
1134
|
+
return {
|
|
1135
|
+
error: `Expected three fields (source,target,value), found ${fields.length}.`,
|
|
1136
|
+
line
|
|
1137
|
+
};
|
|
1138
|
+
}
|
|
1139
|
+
const [source2, target, raw] = fields;
|
|
1140
|
+
const value = Number.parseFloat(raw);
|
|
1141
|
+
if (!Number.isFinite(value)) {
|
|
1142
|
+
return { error: `"${raw}" is not a number.`, line };
|
|
1143
|
+
}
|
|
1144
|
+
add(source2);
|
|
1145
|
+
add(target);
|
|
1146
|
+
links.push({ source: source2, target, value });
|
|
1147
|
+
}
|
|
1148
|
+
if (!links.length) return { error: "No links: add lines like `A,B,10`." };
|
|
1149
|
+
return { data: { nodes, links } };
|
|
1150
|
+
}
|
|
1151
|
+
function readRecords(lines) {
|
|
1152
|
+
const records = [];
|
|
1153
|
+
let i = 0;
|
|
1154
|
+
while (i < lines.length) {
|
|
1155
|
+
const start = lines[i];
|
|
1156
|
+
if (start.text === "") {
|
|
1157
|
+
i++;
|
|
1158
|
+
continue;
|
|
1159
|
+
}
|
|
1160
|
+
const fields = [];
|
|
1161
|
+
let text = start.text;
|
|
1162
|
+
let pos = 0;
|
|
1163
|
+
let field = "";
|
|
1164
|
+
let quoted = false;
|
|
1165
|
+
for (; ; ) {
|
|
1166
|
+
if (quoted) {
|
|
1167
|
+
const close = text.indexOf('"', pos);
|
|
1168
|
+
if (close < 0) {
|
|
1169
|
+
field += text.slice(pos);
|
|
1170
|
+
i++;
|
|
1171
|
+
if (i >= lines.length)
|
|
1172
|
+
return { error: "A quoted field is never closed.", line: start.line };
|
|
1173
|
+
field += "\n";
|
|
1174
|
+
text = lines[i].text;
|
|
1175
|
+
pos = 0;
|
|
1176
|
+
continue;
|
|
1177
|
+
}
|
|
1178
|
+
field += text.slice(pos, close);
|
|
1179
|
+
if (text[close + 1] === '"') {
|
|
1180
|
+
field += '"';
|
|
1181
|
+
pos = close + 2;
|
|
1182
|
+
continue;
|
|
1183
|
+
}
|
|
1184
|
+
quoted = false;
|
|
1185
|
+
pos = close + 1;
|
|
1186
|
+
const rest = /^[ \t]*/.exec(text.slice(pos))[0].length;
|
|
1187
|
+
pos += rest;
|
|
1188
|
+
if (pos < text.length && text[pos] !== ",") {
|
|
1189
|
+
return { error: "Unexpected text after a quoted field.", line: lines[i].line };
|
|
1190
|
+
}
|
|
1191
|
+
continue;
|
|
1192
|
+
}
|
|
1193
|
+
if (pos >= text.length) {
|
|
1194
|
+
fields.push(field.trim());
|
|
1195
|
+
break;
|
|
1196
|
+
}
|
|
1197
|
+
const ch = text[pos];
|
|
1198
|
+
if (ch === ",") {
|
|
1199
|
+
fields.push(field.trim());
|
|
1200
|
+
field = "";
|
|
1201
|
+
pos++;
|
|
1202
|
+
} else if (ch === '"' && field.trim() === "") {
|
|
1203
|
+
quoted = true;
|
|
1204
|
+
field = "";
|
|
1205
|
+
pos++;
|
|
1206
|
+
} else if (ch === '"') {
|
|
1207
|
+
return { error: "A quote inside an unquoted field.", line: lines[i].line };
|
|
1208
|
+
} else {
|
|
1209
|
+
field += ch;
|
|
1210
|
+
pos++;
|
|
1211
|
+
}
|
|
1212
|
+
}
|
|
1213
|
+
records.push({ fields, line: start.line });
|
|
1214
|
+
i++;
|
|
1215
|
+
}
|
|
1216
|
+
return records;
|
|
1217
|
+
}
|
|
1218
|
+
|
|
1219
|
+
// src/diagram/treemap/index.ts
|
|
1220
|
+
var NAME = String.raw`(?:"([^"]*)"|'([^']*)')`;
|
|
1221
|
+
var CLASS = String.raw`(?:\s*:::\s*([A-Za-z_]\w*))?`;
|
|
1222
|
+
var SECTION_RE = new RegExp(String.raw`^${NAME}${CLASS}$`);
|
|
1223
|
+
var LEAF_RE = new RegExp(String.raw`^${NAME}\s*[:,]\s*([0-9_.,]+)${CLASS}$`);
|
|
1224
|
+
function parseTreemap(source) {
|
|
1225
|
+
const split = splitSource(source);
|
|
1226
|
+
if (!/^\s*treemap(?:-beta)?\b/i.test(split.header)) {
|
|
1227
|
+
return { error: "Not a treemap: the first line should be `treemap-beta`." };
|
|
1228
|
+
}
|
|
1229
|
+
const data = { items: [] };
|
|
1230
|
+
const stack = [];
|
|
1231
|
+
const firstLine = split.headerIndex + 2;
|
|
1232
|
+
const lines = split.bodyLines;
|
|
1233
|
+
for (let i = 0; i < lines.length; i++) {
|
|
1234
|
+
const raw = lines[i];
|
|
1235
|
+
const line = firstLine + i;
|
|
1236
|
+
const indent = /^[ \t]*/.exec(raw)[0].length;
|
|
1237
|
+
const text = stripComment(raw).trim();
|
|
1238
|
+
if (!text) continue;
|
|
1239
|
+
const accBlock = /^accDescr\s*\{(.*)$/.exec(text);
|
|
1240
|
+
if (accBlock) {
|
|
1241
|
+
let body = accBlock[1];
|
|
1242
|
+
while (!body.includes("}") && i + 1 < lines.length) body += `
|
|
1243
|
+
${lines[++i]}`;
|
|
1244
|
+
if (!body.includes("}")) return { error: "`accDescr {` is never closed.", line };
|
|
1245
|
+
data.accDescr = body.slice(0, body.indexOf("}")).trim();
|
|
1246
|
+
continue;
|
|
1247
|
+
}
|
|
1248
|
+
const acc = /^(accTitle|accDescr)\s*:(.*)$/.exec(text);
|
|
1249
|
+
if (acc) {
|
|
1250
|
+
data[acc[1]] = acc[2].trim();
|
|
1251
|
+
continue;
|
|
1252
|
+
}
|
|
1253
|
+
const title = /^title(?:[ \t]+(.*))?$/.exec(text);
|
|
1254
|
+
if (title) {
|
|
1255
|
+
data.title = (title[1] ?? "").trim() || void 0;
|
|
1256
|
+
continue;
|
|
1257
|
+
}
|
|
1258
|
+
if (/^classDef\s/.test(text)) continue;
|
|
1259
|
+
let item;
|
|
1260
|
+
const leaf = LEAF_RE.exec(text);
|
|
1261
|
+
const section = leaf ? null : SECTION_RE.exec(text);
|
|
1262
|
+
if (leaf) {
|
|
1263
|
+
const value = Number.parseFloat(leaf[3].replace(/,/g, ""));
|
|
1264
|
+
if (!Number.isFinite(value)) return { error: `"${leaf[3]}" is not a number.`, line };
|
|
1265
|
+
item = { name: leaf[1] ?? leaf[2], value };
|
|
1266
|
+
if (leaf[4]) item.className = leaf[4];
|
|
1267
|
+
} else if (section) {
|
|
1268
|
+
item = { name: section[1] ?? section[2], children: [] };
|
|
1269
|
+
if (section[3]) item.className = section[3];
|
|
1270
|
+
} else {
|
|
1271
|
+
return {
|
|
1272
|
+
error: /^["']/.test(text) ? 'Expected `"Name"` for a section or `"Name": value` for a leaf.' : 'Names must be in quotes, e.g. `"Sales": 120`.',
|
|
1273
|
+
line
|
|
1274
|
+
};
|
|
1275
|
+
}
|
|
1276
|
+
while (stack.length && stack[stack.length - 1].indent >= indent) stack.pop();
|
|
1277
|
+
const parent = stack[stack.length - 1]?.item;
|
|
1278
|
+
if (parent) parent.children.push(item);
|
|
1279
|
+
else data.items.push(item);
|
|
1280
|
+
if (item.children) stack.push({ item, indent });
|
|
1281
|
+
}
|
|
1282
|
+
if (!data.items.length) return { error: 'No items: add lines like `"Sales": 120`.' };
|
|
1283
|
+
return { data };
|
|
1284
|
+
}
|
|
1285
|
+
function stripComment(line) {
|
|
1286
|
+
let quote3 = null;
|
|
1287
|
+
for (let i = 0; i < line.length; i++) {
|
|
1288
|
+
const ch = line[i];
|
|
1289
|
+
if (quote3) {
|
|
1290
|
+
if (ch === quote3) quote3 = null;
|
|
1291
|
+
} else if (ch === '"' || ch === "'") {
|
|
1292
|
+
quote3 = ch;
|
|
1293
|
+
} else if (ch === "%" && line[i + 1] === "%") {
|
|
1294
|
+
return line.slice(0, i);
|
|
1295
|
+
}
|
|
1296
|
+
}
|
|
1297
|
+
return line;
|
|
1298
|
+
}
|
|
1299
|
+
function treemapValue(item) {
|
|
1300
|
+
if (!item.children) return item.value ?? 0;
|
|
1301
|
+
return item.children.reduce((sum, child) => sum + treemapValue(child), 0);
|
|
1302
|
+
}
|
|
1303
|
+
|
|
117
1304
|
// src/diagram/controller.ts
|
|
118
|
-
var EDITABLE_DIAGRAM_FAMILIES = [
|
|
1305
|
+
var EDITABLE_DIAGRAM_FAMILIES = [
|
|
1306
|
+
"flowchart",
|
|
1307
|
+
"state",
|
|
1308
|
+
"class",
|
|
1309
|
+
"er",
|
|
1310
|
+
"pie",
|
|
1311
|
+
"mindmap",
|
|
1312
|
+
"quadrant",
|
|
1313
|
+
"c4",
|
|
1314
|
+
"architecture",
|
|
1315
|
+
"sequence",
|
|
1316
|
+
"gitGraph",
|
|
1317
|
+
"gantt",
|
|
1318
|
+
"timeline",
|
|
1319
|
+
"journey",
|
|
1320
|
+
"xychart",
|
|
1321
|
+
"radar"
|
|
1322
|
+
];
|
|
119
1323
|
function diagramShapes(family) {
|
|
120
1324
|
if (family === "flowchart") return FLOWCHART_SHAPES.map((shape) => shape.name);
|
|
121
1325
|
if (family === "state") return STATE_SHAPES.map((shape) => shape.name);
|
|
122
|
-
return [];
|
|
1326
|
+
if (family === "class" || family === "er") return [];
|
|
1327
|
+
const shapes = familyUI(family)?.shapes ?? [];
|
|
1328
|
+
return shapes.length > 1 ? shapes.map((shape) => shape.value) : [];
|
|
123
1329
|
}
|
|
124
1330
|
function diagramSupportsGroups(family) {
|
|
125
|
-
return family
|
|
1331
|
+
return familyUI(family)?.groups.supported ?? false;
|
|
126
1332
|
}
|
|
127
|
-
|
|
1333
|
+
function diagramSupportsDirection(family) {
|
|
1334
|
+
return familyUI(family)?.directions !== false;
|
|
1335
|
+
}
|
|
1336
|
+
var quote2 = (ids) => [...ids].map((id) => `"${id}"`).join(", ");
|
|
128
1337
|
function validateDiagramEdit(doc, op) {
|
|
129
1338
|
const { graph, family } = doc;
|
|
130
1339
|
if (op.type === "replaceSource") return null;
|
|
@@ -133,15 +1342,15 @@ function validateDiagramEdit(doc, op) {
|
|
|
133
1342
|
const nodes = new Set(graph.nodes.map((n) => n.id));
|
|
134
1343
|
const groups = new Set(graph.groups.map((g) => g.id));
|
|
135
1344
|
const edges = new Set(graph.edges.map((e) => e.id));
|
|
136
|
-
const anyIds = () => nodes.size ? `existing node ids are ${
|
|
1345
|
+
const anyIds = () => nodes.size ? `existing node ids are ${quote2([...nodes].slice(0, 20))}` : "the diagram has no nodes yet";
|
|
137
1346
|
const node = (id, allowGroup = false) => nodes.has(id) || allowGroup && groups.has(id) ? null : `There is no node "${id}"; ${anyIds()}.`;
|
|
138
|
-
const group = (id) => id === void 0 || groups.has(id) ? null : `There is no group "${id}"; ${groups.size ? `existing groups are ${
|
|
139
|
-
const edge = (id) => edges.has(id) ? null : `There is no edge "${id}"; ${edges.size ? `existing edge ids are ${
|
|
1347
|
+
const group = (id) => id === void 0 || groups.has(id) ? null : `There is no group "${id}"; ${groups.size ? `existing groups are ${quote2(groups)}` : "the diagram has no groups"}.`;
|
|
1348
|
+
const edge = (id) => edges.has(id) ? null : `There is no edge "${id}"; ${edges.size ? `existing edge ids are ${quote2([...edges].slice(0, 20))}` : "the diagram has no edges yet"}.`;
|
|
140
1349
|
const shape = (name) => {
|
|
141
1350
|
if (name === void 0) return null;
|
|
142
1351
|
const shapes = diagramShapes(family);
|
|
143
1352
|
if (!shapes.length) return `Nodes of a ${family} diagram have no shapes to choose from.`;
|
|
144
|
-
return shapes.includes(name) ? null : `Unknown shape "${name}"; use one of ${
|
|
1353
|
+
return shapes.includes(name) ? null : `Unknown shape "${name}"; use one of ${quote2(shapes)}.`;
|
|
145
1354
|
};
|
|
146
1355
|
const free = (id) => !/^[A-Za-z0-9_][\w.-]*$/.test(id) ? `Id "${id}" is not a valid Mermaid id; use letters, digits, "_", "-" or ".".` : nodes.has(id) || groups.has(id) ? `Id "${id}" is already used; choose another.` : null;
|
|
147
1356
|
const first = (...problems) => problems.find((p) => p) ?? null;
|
|
@@ -183,7 +1392,8 @@ function validateDiagramEdit(doc, op) {
|
|
|
183
1392
|
case "setNodeParent":
|
|
184
1393
|
return first(...op.ids.map((id) => node(id, true)), group(op.parentId));
|
|
185
1394
|
case "setDirection":
|
|
186
|
-
|
|
1395
|
+
if (!diagramSupportsDirection(family)) return `${family} diagrams have no direction.`;
|
|
1396
|
+
return DIRECTIONS.includes(op.direction) ? null : `Unknown direction "${op.direction}"; use one of ${quote2(DIRECTIONS)}.`;
|
|
187
1397
|
default:
|
|
188
1398
|
return null;
|
|
189
1399
|
}
|
|
@@ -309,10 +1519,10 @@ var DiagramController = class {
|
|
|
309
1519
|
* document as it stands after the edits before it, and nothing changes when one fails.
|
|
310
1520
|
*/
|
|
311
1521
|
apply(ops, label = "Edit diagram") {
|
|
312
|
-
const
|
|
1522
|
+
const list2 = Array.isArray(ops) ? ops : [ops];
|
|
313
1523
|
if (this.readOnly) return this.reject("The diagram is read-only.");
|
|
314
1524
|
let doc = this.doc;
|
|
315
|
-
for (const op of
|
|
1525
|
+
for (const op of list2) {
|
|
316
1526
|
const problem = validateDiagramEdit(doc, op);
|
|
317
1527
|
if (problem) return this.reject(problem);
|
|
318
1528
|
doc = applyEdits(doc, [op]);
|
|
@@ -382,6 +1592,7 @@ var ID = { type: "string", minLength: 1, description: 'A node id from get_diagra
|
|
|
382
1592
|
var IDS = (what) => ({ type: "array", items: { type: "string", minLength: 1 }, minItems: 1, description: what });
|
|
383
1593
|
var EDGE_ID = { type: "string", minLength: 1, description: 'An edge id from get_diagram (e.g. "L_A_B_0").' };
|
|
384
1594
|
var LABEL = (what) => ({ type: "string", description: what });
|
|
1595
|
+
var FIELD_VALUE = { type: ["string", "number", "boolean", "array", "null"] };
|
|
385
1596
|
var object = (properties, required = []) => ({
|
|
386
1597
|
type: "object",
|
|
387
1598
|
properties,
|
|
@@ -390,6 +1601,8 @@ var object = (properties, required = []) => ({
|
|
|
390
1601
|
});
|
|
391
1602
|
function describeDiagram(doc) {
|
|
392
1603
|
const { graph } = doc;
|
|
1604
|
+
const ui = familyUI(doc.family);
|
|
1605
|
+
const settings = pickFieldData(ui?.diagramFields, graph.data);
|
|
393
1606
|
return {
|
|
394
1607
|
family: doc.family,
|
|
395
1608
|
editable: doc.tier === "editable",
|
|
@@ -402,7 +1615,8 @@ function describeDiagram(doc) {
|
|
|
402
1615
|
...n.parentId ? { parentId: n.parentId } : {},
|
|
403
1616
|
...n.classes.length ? { classes: n.classes } : {},
|
|
404
1617
|
...n.styles.length ? { styles: n.styles } : {},
|
|
405
|
-
...n.data?.synthetic ? { synthetic: true } : {}
|
|
1618
|
+
...n.data?.synthetic ? { synthetic: true } : {},
|
|
1619
|
+
...ui?.nodeFields && Object.keys(pickFieldData(ui.nodeFields, n.data)).length ? { data: pickFieldData(ui.nodeFields, n.data) } : {}
|
|
406
1620
|
})),
|
|
407
1621
|
edges: graph.edges.map((e) => ({
|
|
408
1622
|
id: e.id,
|
|
@@ -410,7 +1624,8 @@ function describeDiagram(doc) {
|
|
|
410
1624
|
target: e.target,
|
|
411
1625
|
...e.label ? { label: e.label } : {},
|
|
412
1626
|
pattern: e.pattern,
|
|
413
|
-
arrowEnd: e.arrowEnd
|
|
1627
|
+
arrowEnd: e.arrowEnd,
|
|
1628
|
+
...ui?.edgeFields && Object.keys(pickFieldData(ui.edgeFields, e.data)).length ? { data: pickFieldData(ui.edgeFields, e.data) } : {}
|
|
414
1629
|
})),
|
|
415
1630
|
groups: graph.groups.map((g) => ({
|
|
416
1631
|
id: g.id,
|
|
@@ -419,6 +1634,14 @@ function describeDiagram(doc) {
|
|
|
419
1634
|
...g.direction ? { direction: g.direction } : {}
|
|
420
1635
|
})),
|
|
421
1636
|
shapes: diagramShapes(doc.family),
|
|
1637
|
+
...Object.keys(settings).length ? { settings } : {},
|
|
1638
|
+
...ui && (ui.nodeFields?.length || ui.edgeFields?.length || ui.diagramFields?.length) ? {
|
|
1639
|
+
fields: {
|
|
1640
|
+
...ui.nodeFields?.length ? { node: describeFields(ui.nodeFields) } : {},
|
|
1641
|
+
...ui.edgeFields?.length ? { edge: describeFields(ui.edgeFields) } : {},
|
|
1642
|
+
...ui.diagramFields?.length ? { diagram: describeFields(ui.diagramFields) } : {}
|
|
1643
|
+
}
|
|
1644
|
+
} : {},
|
|
422
1645
|
positions: Object.fromEntries(Object.entries(doc.meta.layout ?? {}).map(([id, [x, y]]) => [id, { x: Math.round(x), y: Math.round(y) }])),
|
|
423
1646
|
...doc.diagnostics.length ? { diagnostics: doc.diagnostics.map((d) => ({ severity: d.severity, message: d.message, ...d.line ? { line: d.line } : {} })) } : {}
|
|
424
1647
|
};
|
|
@@ -456,7 +1679,7 @@ function createDiagramToolProvider(controller, options = {}) {
|
|
|
456
1679
|
const getDiagram = {
|
|
457
1680
|
name: "get_diagram",
|
|
458
1681
|
title: "Read the diagram",
|
|
459
|
-
description:
|
|
1682
|
+
description: 'Returns the diagram: its Mermaid family (flowchart, state, class, er, pie, mindmap, quadrant, c4, architecture, sequence, gitGraph, gantt, timeline, journey, xychart, radar; sankey, block, packet, kanban and treemap are text only), direction, title, nodes (id, label, shape, parentId, data), edges (id, source, target, label, data), groups (subgraphs, composite states, sections, boxes\u2026), the shapes nodes can take, diagram settings, the data fields each family offers ("fields": node, edge and diagram field keys with their types), stored canvas positions, any parse diagnostics and the selection. Use the ids and field keys it returns with the write tools.',
|
|
460
1683
|
inputSchema: object({ includeSource: { type: "boolean", description: "Also return the Mermaid text (default false)." } }),
|
|
461
1684
|
annotations: { title: "Read the diagram", ...READ },
|
|
462
1685
|
handler: async ({ includeSource = false }) => {
|
|
@@ -491,7 +1714,7 @@ function createDiagramToolProvider(controller, options = {}) {
|
|
|
491
1714
|
const loadMermaid = {
|
|
492
1715
|
name: "load_diagram_mermaid",
|
|
493
1716
|
title: "Replace the diagram with Mermaid",
|
|
494
|
-
description: "Replaces the whole diagram with Mermaid text (one undo step). Flowchart, state, class and
|
|
1717
|
+
description: "Replaces the whole diagram with Mermaid text (one undo step). Flowchart, state, class, ER, pie, mindmap, quadrant, C4, architecture, sequence, gitGraph, Gantt, timeline, journey, XY and radar diagrams become editable; sankey, block, packet, kanban and treemap are kept as text. Returns the family, node and edge counts and any parse diagnostics. Prefer the per-operation tools for small changes: they keep the rest of the text as written.",
|
|
495
1718
|
inputSchema: object({ source: { type: "string", minLength: 1, description: 'Mermaid text, starting with a header such as "flowchart LR".' } }, ["source"]),
|
|
496
1719
|
annotations: { title: "Replace the diagram with Mermaid", ...DESTRUCTIVE },
|
|
497
1720
|
handler: async ({ source }) => {
|
|
@@ -520,8 +1743,9 @@ function createDiagramToolProvider(controller, options = {}) {
|
|
|
520
1743
|
inputSchema: object(
|
|
521
1744
|
{
|
|
522
1745
|
label: LABEL("Text shown in the node."),
|
|
523
|
-
id: { type: "string", pattern: "^[A-Za-z0-9_][\\w.-]*$", description: 'Mermaid id (default: the next free "
|
|
524
|
-
shape: { type: "string", description:
|
|
1746
|
+
id: { type: "string", pattern: "^[A-Za-z0-9_][\\w.-]*$", description: 'Mermaid id (default: the next free id for the family, e.g. "n3", "slice4", "task2").' },
|
|
1747
|
+
shape: { type: "string", description: `One of the shapes get_diagram lists (default: the family's usual node, e.g. "rect").` },
|
|
1748
|
+
data: { type: "object", additionalProperties: FIELD_VALUE, description: `Values for the family's node fields (get_diagram "fields.node"), e.g. {"value": 40} for a pie slice. Defaults fill in the rest.` },
|
|
525
1749
|
parentId: { type: "string", description: "Group (subgraph) to add the node to." },
|
|
526
1750
|
from: { type: "string", description: "An existing node to connect to the new node." },
|
|
527
1751
|
edgeLabel: LABEL('Label of the edge from "from" (needs "from").'),
|
|
@@ -531,14 +1755,22 @@ function createDiagramToolProvider(controller, options = {}) {
|
|
|
531
1755
|
["label"]
|
|
532
1756
|
),
|
|
533
1757
|
annotations: { title: "Add a node", ...WRITE },
|
|
534
|
-
handler: async ({ label, id, shape, parentId, from, edgeLabel, x, y }) => {
|
|
1758
|
+
handler: async ({ label, id, shape, parentId, from, edgeLabel, x, y, data }) => {
|
|
535
1759
|
requireEditable();
|
|
536
1760
|
if (x === void 0 !== (y === void 0)) throw new Error("Give both x and y, or neither to place the node automatically.");
|
|
537
1761
|
if (edgeLabel !== void 0 && from === void 0) throw new Error('edgeLabel needs "from", the node the edge starts at.');
|
|
538
|
-
const
|
|
1762
|
+
const ui = familyUI(doc().family);
|
|
1763
|
+
const nodeId = id ?? (ui && !["flowchart", "state", "class", "er"].includes(ui.family) ? ui.nextId(doc().graph) : controller.nextId());
|
|
1764
|
+
const defaults = ui?.newNode?.(doc().graph, parentId) ?? {};
|
|
1765
|
+
const nodeShape = shape ?? defaults.shape;
|
|
1766
|
+
const nodeData = { ...defaults.data ?? {}, ...data ? checkFieldData(ui?.nodeFields, data, `a ${doc().family} node`, nodeShape) : {} };
|
|
539
1767
|
const before = edgeIds();
|
|
540
1768
|
const ops = [
|
|
541
|
-
{
|
|
1769
|
+
{
|
|
1770
|
+
type: "addNode",
|
|
1771
|
+
node: { ...defaults, id: nodeId, label, ...nodeShape ? { shape: nodeShape } : {}, ...parentId ? { parentId } : {}, ...Object.keys(nodeData).length ? { data: nodeData } : {} },
|
|
1772
|
+
...x !== void 0 ? { position: [x, y] } : {}
|
|
1773
|
+
}
|
|
542
1774
|
];
|
|
543
1775
|
if (from !== void 0) ops.push({ type: "addEdge", edge: { source: from, target: nodeId, ...edgeLabel ? { label: edgeLabel } : {} } });
|
|
544
1776
|
const d = await apply(ops, "Add node");
|
|
@@ -713,9 +1945,9 @@ function createDiagramToolProvider(controller, options = {}) {
|
|
|
713
1945
|
),
|
|
714
1946
|
annotations: { title: "Move nodes", ...WRITE_IDEMPOTENT },
|
|
715
1947
|
handler: async ({ moves }) => {
|
|
716
|
-
const
|
|
1948
|
+
const list2 = moves;
|
|
717
1949
|
requireEditable();
|
|
718
|
-
await apply({ type: "moveNodes", moves: pinned(
|
|
1950
|
+
await apply({ type: "moveNodes", moves: pinned(list2.map((m) => ({ id: m.id, position: [m.x, m.y] }))) }, "Move");
|
|
719
1951
|
return { moved: moves };
|
|
720
1952
|
}
|
|
721
1953
|
};
|
|
@@ -743,6 +1975,81 @@ function createDiagramToolProvider(controller, options = {}) {
|
|
|
743
1975
|
return { redone, ...redone ? { label } : {} };
|
|
744
1976
|
}
|
|
745
1977
|
};
|
|
1978
|
+
const fieldsOf = (kind2) => {
|
|
1979
|
+
const ui = familyUI(doc().family);
|
|
1980
|
+
return kind2 === "node" ? ui?.nodeFields : kind2 === "edge" ? ui?.edgeFields : ui?.diagramFields;
|
|
1981
|
+
};
|
|
1982
|
+
const setNodeData = {
|
|
1983
|
+
name: "set_diagram_node_data",
|
|
1984
|
+
title: "Set a node's data fields",
|
|
1985
|
+
description: `Sets values of a node's data fields: a pie slice's value, a Gantt task's start and end, a quadrant point's x and y, a journey task's score, an XY series' values, a C4 element's technology\u2026 Field keys and types are listed in get_diagram "fields.node"; null clears a field. Returns the node with its data.`,
|
|
1986
|
+
inputSchema: object(
|
|
1987
|
+
{
|
|
1988
|
+
id: ID,
|
|
1989
|
+
data: { type: "object", additionalProperties: FIELD_VALUE, description: 'Field key \u2192 value, e.g. {"value": 40} or {"x": 0.3, "y": 0.8}. null clears the field.' }
|
|
1990
|
+
},
|
|
1991
|
+
["id", "data"]
|
|
1992
|
+
),
|
|
1993
|
+
annotations: { title: "Set a node's data fields", ...WRITE_IDEMPOTENT },
|
|
1994
|
+
handler: async ({ id, data }) => {
|
|
1995
|
+
requireEditable();
|
|
1996
|
+
const node = doc().graph.nodes.find((n) => n.id === id);
|
|
1997
|
+
if (!node) throw new Error(`There is no node "${id}"; call get_diagram for the node ids.`);
|
|
1998
|
+
const patch = checkFieldData(fieldsOf("node"), data, `a ${doc().family} node`, node.shape);
|
|
1999
|
+
const d = await apply({ type: "setNodeData", id, data: patch }, "Edit data");
|
|
2000
|
+
const after = d.graph.nodes.find((n) => n.id === id);
|
|
2001
|
+
return { node: { ...nodeOut(d, id), data: pickFieldData(fieldsOf("node"), after?.data) } };
|
|
2002
|
+
}
|
|
2003
|
+
};
|
|
2004
|
+
const setEdgeData = {
|
|
2005
|
+
name: "set_diagram_edge_data",
|
|
2006
|
+
title: "Set an edge's data fields",
|
|
2007
|
+
description: `Sets values of an edge's data fields: a sequence message's activation, a C4 relation's technology, an architecture edge's sides\u2026 Field keys and types are listed in get_diagram "fields.edge"; null clears a field. Returns the edge with its data.`,
|
|
2008
|
+
inputSchema: object(
|
|
2009
|
+
{
|
|
2010
|
+
id: EDGE_ID,
|
|
2011
|
+
data: { type: "object", additionalProperties: FIELD_VALUE, description: "Field key \u2192 value. null clears the field." }
|
|
2012
|
+
},
|
|
2013
|
+
["id", "data"]
|
|
2014
|
+
),
|
|
2015
|
+
annotations: { title: "Set an edge's data fields", ...WRITE_IDEMPOTENT },
|
|
2016
|
+
handler: async ({ id, data }) => {
|
|
2017
|
+
requireEditable();
|
|
2018
|
+
if (!doc().graph.edges.some((e) => e.id === id)) throw new Error(`There is no edge "${id}"; call get_diagram for the edge ids.`);
|
|
2019
|
+
const patch = checkFieldData(fieldsOf("edge"), data, `a ${doc().family} edge`);
|
|
2020
|
+
const d = await apply({ type: "setEdgeData", id, data: patch }, "Edit data");
|
|
2021
|
+
const edge = d.graph.edges.find((e) => e.id === id);
|
|
2022
|
+
return { edge: { id, ...edge ? { source: edge.source, target: edge.target } : {}, data: pickFieldData(fieldsOf("edge"), edge?.data) } };
|
|
2023
|
+
}
|
|
2024
|
+
};
|
|
2025
|
+
const setSettings = {
|
|
2026
|
+
name: "set_diagram_settings",
|
|
2027
|
+
title: "Change diagram settings",
|
|
2028
|
+
description: `Sets diagram-level fields: a pie chart's showData, a Gantt chart's dateFormat and excludes, a quadrant chart's axis labels, an XY chart's categories and axis range, sequence autonumbering\u2026 Field keys and types are listed in get_diagram "fields.diagram"; null clears a field. Returns all settings.`,
|
|
2029
|
+
inputSchema: object(
|
|
2030
|
+
{ data: { type: "object", additionalProperties: FIELD_VALUE, description: "Field key \u2192 value. null clears the field." } },
|
|
2031
|
+
["data"]
|
|
2032
|
+
),
|
|
2033
|
+
annotations: { title: "Change diagram settings", ...WRITE_IDEMPOTENT },
|
|
2034
|
+
handler: async ({ data }) => {
|
|
2035
|
+
requireEditable();
|
|
2036
|
+
const patch = checkFieldData(fieldsOf("diagram"), data, `a ${doc().family} diagram`);
|
|
2037
|
+
const d = await apply({ type: "setGraphData", data: patch }, "Edit settings");
|
|
2038
|
+
return { settings: pickFieldData(fieldsOf("diagram"), d.graph.data) };
|
|
2039
|
+
}
|
|
2040
|
+
};
|
|
2041
|
+
const setTitle = {
|
|
2042
|
+
name: "set_diagram_title",
|
|
2043
|
+
title: "Set the diagram title",
|
|
2044
|
+
description: "Sets the title shown above the diagram (a title statement, or frontmatter for families without one), or removes it with null. Returns the title.",
|
|
2045
|
+
inputSchema: object({ title: { type: ["string", "null"], description: "The new title, or null to remove it." } }, ["title"]),
|
|
2046
|
+
annotations: { title: "Set the diagram title", ...WRITE_IDEMPOTENT },
|
|
2047
|
+
handler: async ({ title }) => {
|
|
2048
|
+
requireEditable();
|
|
2049
|
+
const d = await apply({ type: "setTitle", title: title === null || title === "" ? void 0 : title }, "Set title");
|
|
2050
|
+
return { title: d.graph.title ?? null };
|
|
2051
|
+
}
|
|
2052
|
+
};
|
|
746
2053
|
const renderDiagram = {
|
|
747
2054
|
name: "render_diagram",
|
|
748
2055
|
title: "Render the diagram",
|
|
@@ -765,7 +2072,7 @@ function createDiagramToolProvider(controller, options = {}) {
|
|
|
765
2072
|
}
|
|
766
2073
|
};
|
|
767
2074
|
const reads = [getDiagram, exportMermaid, findDiagrams, ...options.renderSvg ? [renderDiagram] : []];
|
|
768
|
-
const writes = [loadMermaid, addNode, removeElements, renameNode, setShape, setStyle, connect, removeEdges, labelEdge, reconnect, setDirection, group, ungroup, move, undo, redo];
|
|
2075
|
+
const writes = [loadMermaid, addNode, removeElements, renameNode, setShape, setStyle, setNodeData, connect, removeEdges, labelEdge, setEdgeData, reconnect, setDirection, setTitle, setSettings, group, ungroup, move, undo, redo];
|
|
769
2076
|
return {
|
|
770
2077
|
id: options.id ?? "diagram",
|
|
771
2078
|
namespace: options.namespace,
|
|
@@ -1103,6 +2410,8 @@ function planDiagramEdits(source, place, ops, speed = 1) {
|
|
|
1103
2410
|
});
|
|
1104
2411
|
}
|
|
1105
2412
|
export {
|
|
2413
|
+
ARCH_METRICS,
|
|
2414
|
+
C4_METRICS,
|
|
1106
2415
|
CLASS_RELATIONS,
|
|
1107
2416
|
DIRECTIONS,
|
|
1108
2417
|
DiagramController,
|
|
@@ -1110,58 +2419,159 @@ export {
|
|
|
1110
2419
|
EDITABLE_DIAGRAM_FAMILIES,
|
|
1111
2420
|
ER_CARDINALITIES,
|
|
1112
2421
|
ER_PATTERNS,
|
|
2422
|
+
FAMILY_BLANKS,
|
|
2423
|
+
FAMILY_DESCRIPTIONS,
|
|
2424
|
+
FAMILY_TEMPLATES,
|
|
2425
|
+
FAMILY_TITLES,
|
|
1113
2426
|
FLOWCHART_SHAPES,
|
|
2427
|
+
GANTT_CONFIG_KEYS,
|
|
2428
|
+
GANTT_METRICS,
|
|
2429
|
+
GANTT_TAGS,
|
|
1114
2430
|
META_COMMENT_PREFIX,
|
|
1115
2431
|
META_FRONTMATTER_KEY,
|
|
2432
|
+
POINT_BOX,
|
|
1116
2433
|
PRESENCE_COLORS,
|
|
1117
2434
|
PerformanceQueue,
|
|
1118
2435
|
PresenceStore,
|
|
2436
|
+
QUADRANT_METRICS,
|
|
2437
|
+
RADAR_CHART_BOX,
|
|
2438
|
+
SEQUENCE_METRICS,
|
|
1119
2439
|
STATE_SHAPES,
|
|
2440
|
+
XY_CHART_BOX,
|
|
2441
|
+
afterIds,
|
|
1120
2442
|
applyEdit,
|
|
1121
2443
|
applyEdits,
|
|
2444
|
+
applyStatementEdit,
|
|
2445
|
+
architectureAdapter,
|
|
2446
|
+
architectureArrow,
|
|
2447
|
+
architectureEdgeRoute,
|
|
2448
|
+
architectureGrammar,
|
|
2449
|
+
architectureLayout,
|
|
2450
|
+
architectureUI,
|
|
2451
|
+
c4Adapter,
|
|
2452
|
+
c4ArrowHead,
|
|
2453
|
+
c4BoundaryText,
|
|
2454
|
+
c4ElementGeometry,
|
|
2455
|
+
c4ElementType,
|
|
2456
|
+
c4Grammar,
|
|
2457
|
+
c4Layout,
|
|
2458
|
+
c4RelGeometry,
|
|
2459
|
+
c4Stereotype,
|
|
2460
|
+
c4UI,
|
|
1122
2461
|
canonicalShape,
|
|
1123
2462
|
changedItems,
|
|
2463
|
+
checkFieldData,
|
|
1124
2464
|
classGrammar,
|
|
2465
|
+
classUI,
|
|
1125
2466
|
createDiagramToolProvider,
|
|
1126
2467
|
createInstantPresenceClock,
|
|
1127
2468
|
createLineAdapter,
|
|
1128
2469
|
createPassthroughAdapter,
|
|
2470
|
+
createStatementAdapter,
|
|
1129
2471
|
describeDiagram,
|
|
2472
|
+
describeFields,
|
|
1130
2473
|
detectFamily,
|
|
1131
2474
|
detectFamilyFromHeader,
|
|
1132
2475
|
diagramShapes,
|
|
2476
|
+
diagramSupportsDirection,
|
|
1133
2477
|
diagramSupportsGroups,
|
|
1134
2478
|
draftFrames,
|
|
2479
|
+
dropMetaKeys,
|
|
1135
2480
|
emptyMeta,
|
|
1136
2481
|
erGrammar,
|
|
2482
|
+
erUI,
|
|
2483
|
+
familyUI,
|
|
2484
|
+
filterInPlace,
|
|
1137
2485
|
findMermaidSources,
|
|
1138
2486
|
flowchartAdapter,
|
|
2487
|
+
flowchartUI,
|
|
2488
|
+
formatAxis,
|
|
1139
2489
|
formatChain,
|
|
2490
|
+
formatGanttDate,
|
|
1140
2491
|
formatLink,
|
|
1141
2492
|
formatNode,
|
|
2493
|
+
ganttAdapter,
|
|
2494
|
+
ganttGeometry,
|
|
2495
|
+
ganttGrammar,
|
|
2496
|
+
ganttUI,
|
|
1142
2497
|
getDiagramAdapter,
|
|
2498
|
+
getFamilyLayout,
|
|
2499
|
+
gitGraphAdapter,
|
|
2500
|
+
gitGraphGrammar,
|
|
2501
|
+
gitGraphUI,
|
|
2502
|
+
indentOf,
|
|
1143
2503
|
isMetaEmpty,
|
|
2504
|
+
journeyAdapter,
|
|
2505
|
+
journeyGrammar,
|
|
2506
|
+
journeyLayout,
|
|
2507
|
+
journeyUI,
|
|
1144
2508
|
mergeMeta,
|
|
2509
|
+
mindmapAdapter,
|
|
2510
|
+
mindmapGrammar,
|
|
2511
|
+
mindmapUI,
|
|
1145
2512
|
parseAttributes,
|
|
1146
2513
|
parseChain,
|
|
1147
2514
|
parseFlowchartSource,
|
|
2515
|
+
parseGanttDate,
|
|
1148
2516
|
parseLink,
|
|
1149
2517
|
parseMembers,
|
|
1150
2518
|
parseMermaid,
|
|
2519
|
+
parseSankey,
|
|
1151
2520
|
parseStatement,
|
|
2521
|
+
parseStatementDocument,
|
|
2522
|
+
parseTreemap,
|
|
2523
|
+
pickFieldData,
|
|
2524
|
+
pieAdapter,
|
|
2525
|
+
pieGrammar,
|
|
2526
|
+
pieUI,
|
|
1152
2527
|
planDiagramEdit,
|
|
1153
2528
|
planDiagramEdits,
|
|
2529
|
+
pointCentre,
|
|
2530
|
+
pointPosition,
|
|
2531
|
+
positionToData,
|
|
2532
|
+
quadrantAdapter,
|
|
2533
|
+
quadrantGeometry,
|
|
2534
|
+
quadrantGrammar,
|
|
2535
|
+
quadrantSpace,
|
|
2536
|
+
quadrantUI,
|
|
2537
|
+
quote,
|
|
1154
2538
|
quoteLabelIfNeeded,
|
|
2539
|
+
radarAdapter,
|
|
2540
|
+
radarGrammar,
|
|
2541
|
+
radarUI,
|
|
1155
2542
|
realPresenceClock,
|
|
1156
2543
|
registerDiagramAdapter,
|
|
2544
|
+
registerFamilyLayout,
|
|
1157
2545
|
relationFor,
|
|
2546
|
+
renameMetaKey,
|
|
1158
2547
|
resolveShape,
|
|
2548
|
+
sequenceAdapter,
|
|
2549
|
+
sequenceGeometry,
|
|
2550
|
+
sequenceGrammar,
|
|
2551
|
+
sequenceUI,
|
|
1159
2552
|
serializeMermaid,
|
|
1160
2553
|
serializeMeta,
|
|
2554
|
+
serializeStatementDocument,
|
|
2555
|
+
serviceLabelLines,
|
|
2556
|
+
sharedFrameLayout,
|
|
2557
|
+
slugId,
|
|
2558
|
+
spaceInput,
|
|
2559
|
+
splitOutsideQuotes,
|
|
1161
2560
|
splitSource,
|
|
1162
2561
|
splitStatements,
|
|
1163
2562
|
stateGrammar,
|
|
2563
|
+
stateUI,
|
|
1164
2564
|
supportTierOf,
|
|
1165
|
-
|
|
2565
|
+
timelineAdapter,
|
|
2566
|
+
timelineGrammar,
|
|
2567
|
+
timelineLayout,
|
|
2568
|
+
timelineUI,
|
|
2569
|
+
treemapValue,
|
|
2570
|
+
uniqueId,
|
|
2571
|
+
unquote,
|
|
2572
|
+
validateDiagramEdit,
|
|
2573
|
+
xyChartAdapter,
|
|
2574
|
+
xyChartGrammar,
|
|
2575
|
+
xyChartUI
|
|
1166
2576
|
};
|
|
1167
2577
|
//# sourceMappingURL=index.js.map
|