schematex 0.6.9 → 0.7.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/ai/ai-sdk.cjs +8 -8
- package/dist/ai/ai-sdk.js +3 -3
- package/dist/ai/index.cjs +14 -14
- package/dist/ai/index.js +3 -3
- package/dist/browser.cjs +9 -9
- package/dist/browser.js +3 -3
- package/dist/{chunk-25TO5A4F.cjs → chunk-CTMJ3XP2.cjs} +156 -9
- package/dist/chunk-CTMJ3XP2.cjs.map +1 -0
- package/dist/{chunk-HL5PS6MG.js → chunk-EENA7KNU.js} +324 -27
- package/dist/chunk-EENA7KNU.js.map +1 -0
- package/dist/{chunk-5IZL57YJ.cjs → chunk-HFATQXFN.cjs} +1455 -158
- package/dist/chunk-HFATQXFN.cjs.map +1 -0
- package/dist/{chunk-3DPWFWQU.js → chunk-IFNNV54X.js} +1454 -157
- package/dist/chunk-IFNNV54X.js.map +1 -0
- package/dist/{chunk-Q5V4LUQR.js → chunk-IFXHIYZE.js} +154 -7
- package/dist/chunk-IFXHIYZE.js.map +1 -0
- package/dist/{chunk-BL57NQKN.cjs → chunk-JAYJ2G4R.cjs} +324 -27
- package/dist/chunk-JAYJ2G4R.cjs.map +1 -0
- package/dist/diagrams/phylo/index.cjs +6 -6
- package/dist/diagrams/phylo/index.d.cts +21 -0
- package/dist/diagrams/phylo/index.d.ts +21 -0
- package/dist/diagrams/phylo/index.js +1 -1
- package/dist/index.cjs +25 -25
- package/dist/index.js +3 -3
- package/dist/react.cjs +3 -3
- package/dist/react.js +2 -2
- package/package.json +1 -1
- package/dist/chunk-25TO5A4F.cjs.map +0 -1
- package/dist/chunk-3DPWFWQU.js.map +0 -1
- package/dist/chunk-5IZL57YJ.cjs.map +0 -1
- package/dist/chunk-BL57NQKN.cjs.map +0 -1
- package/dist/chunk-HL5PS6MG.js.map +0 -1
- package/dist/chunk-Q5V4LUQR.js.map +0 -1
|
@@ -13,7 +13,7 @@ var chunkNFZMNKOR_cjs = require('./chunk-NFZMNKOR.cjs');
|
|
|
13
13
|
var chunk2SZJQVPN_cjs = require('./chunk-2SZJQVPN.cjs');
|
|
14
14
|
var chunkKGOZBABH_cjs = require('./chunk-KGOZBABH.cjs');
|
|
15
15
|
var chunk3KRL2EGN_cjs = require('./chunk-3KRL2EGN.cjs');
|
|
16
|
-
var
|
|
16
|
+
var chunkJAYJ2G4R_cjs = require('./chunk-JAYJ2G4R.cjs');
|
|
17
17
|
var chunk5FYPSIGD_cjs = require('./chunk-5FYPSIGD.cjs');
|
|
18
18
|
var chunk2F45Y2ON_cjs = require('./chunk-2F45Y2ON.cjs');
|
|
19
19
|
var chunkZ3A2UNK2_cjs = require('./chunk-Z3A2UNK2.cjs');
|
|
@@ -21,6 +21,207 @@ var chunkNZT5P2XZ_cjs = require('./chunk-NZT5P2XZ.cjs');
|
|
|
21
21
|
var chunkNAGUZFXX_cjs = require('./chunk-NAGUZFXX.cjs');
|
|
22
22
|
var chunk3WNW5Y7P_cjs = require('./chunk-3WNW5Y7P.cjs');
|
|
23
23
|
|
|
24
|
+
// src/diagrams/decisiontree/influence-parser.ts
|
|
25
|
+
function preprocess(src) {
|
|
26
|
+
const out = [];
|
|
27
|
+
const lines = src.split(/\r?\n/);
|
|
28
|
+
for (let i = 0; i < lines.length; i++) {
|
|
29
|
+
const raw = lines[i];
|
|
30
|
+
if (raw === void 0) continue;
|
|
31
|
+
const trimmed = raw.trim();
|
|
32
|
+
if (!trimmed || trimmed.startsWith("#") || trimmed.startsWith("//")) continue;
|
|
33
|
+
out.push({ text: trimmed, line: i + 1 });
|
|
34
|
+
}
|
|
35
|
+
return out;
|
|
36
|
+
}
|
|
37
|
+
function tokenize(s, lineNum) {
|
|
38
|
+
const tokens = [];
|
|
39
|
+
let i = 0;
|
|
40
|
+
while (i < s.length) {
|
|
41
|
+
const ch = s[i];
|
|
42
|
+
if (/\s/.test(ch)) {
|
|
43
|
+
i++;
|
|
44
|
+
continue;
|
|
45
|
+
}
|
|
46
|
+
if (ch === '"') {
|
|
47
|
+
const end = s.indexOf('"', i + 1);
|
|
48
|
+
if (end < 0) throw new DTreeParseError(`Unterminated string: ${s}`, lineNum);
|
|
49
|
+
tokens.push(s.slice(i, end + 1));
|
|
50
|
+
i = end + 1;
|
|
51
|
+
continue;
|
|
52
|
+
}
|
|
53
|
+
let j = i;
|
|
54
|
+
while (j < s.length && !/\s/.test(s[j]) && s[j] !== '"') j++;
|
|
55
|
+
tokens.push(s.slice(i, j));
|
|
56
|
+
i = j;
|
|
57
|
+
}
|
|
58
|
+
return tokens;
|
|
59
|
+
}
|
|
60
|
+
function unquote(s) {
|
|
61
|
+
if (s.startsWith('"') && s.endsWith('"')) return s.slice(1, -1);
|
|
62
|
+
return s;
|
|
63
|
+
}
|
|
64
|
+
function isQuoted(s) {
|
|
65
|
+
return s.startsWith('"') && s.endsWith('"') && s.length >= 2;
|
|
66
|
+
}
|
|
67
|
+
function toKind(kw) {
|
|
68
|
+
if (kw === "decision" || kw === "dec") return "decision";
|
|
69
|
+
if (kw === "chance" || kw === "uncertainty" || kw === "event") return "chance";
|
|
70
|
+
if (kw === "value" || kw === "utility" || kw === "objective") return "value";
|
|
71
|
+
return void 0;
|
|
72
|
+
}
|
|
73
|
+
var NODE_KEYWORDS = /* @__PURE__ */ new Set([
|
|
74
|
+
"decision",
|
|
75
|
+
"dec",
|
|
76
|
+
"chance",
|
|
77
|
+
"uncertainty",
|
|
78
|
+
"event",
|
|
79
|
+
"value",
|
|
80
|
+
"utility",
|
|
81
|
+
"objective",
|
|
82
|
+
"node"
|
|
83
|
+
]);
|
|
84
|
+
function parseInfluence(src, title2) {
|
|
85
|
+
const lines = preprocess(src);
|
|
86
|
+
const nodes = [];
|
|
87
|
+
const nodeById = /* @__PURE__ */ new Map();
|
|
88
|
+
const arcDecls = [];
|
|
89
|
+
let direction = "left-right";
|
|
90
|
+
for (const { text: text2, line: line2 } of lines) {
|
|
91
|
+
const cfg = text2.match(/^([a-zA-Z][\w-]*)\s*:\s*(.+)$/);
|
|
92
|
+
if (cfg && !text2.includes("->") && !NODE_KEYWORDS.has(cfg[1].toLowerCase())) {
|
|
93
|
+
const key = cfg[1].toLowerCase();
|
|
94
|
+
const val = cfg[2].trim().toLowerCase();
|
|
95
|
+
if (key === "direction") {
|
|
96
|
+
direction = val === "top-down" || val === "td" ? "top-down" : "left-right";
|
|
97
|
+
}
|
|
98
|
+
continue;
|
|
99
|
+
}
|
|
100
|
+
if (text2.includes("->")) {
|
|
101
|
+
const arrowIdx = text2.indexOf("->");
|
|
102
|
+
const fromPart = text2.slice(0, arrowIdx).trim();
|
|
103
|
+
const afterTokens = tokenize(text2.slice(arrowIdx + 2).trim(), line2);
|
|
104
|
+
const to = afterTokens[0];
|
|
105
|
+
if (!fromPart || !to) {
|
|
106
|
+
throw new DTreeParseError(`Malformed arc: "${text2}"`, line2);
|
|
107
|
+
}
|
|
108
|
+
let label2;
|
|
109
|
+
if (afterTokens[1] !== void 0 && isQuoted(afterTokens[1])) {
|
|
110
|
+
label2 = unquote(afterTokens[1]);
|
|
111
|
+
}
|
|
112
|
+
arcDecls.push({ from: fromPart, to: unquote(to), label: label2, line: line2 });
|
|
113
|
+
continue;
|
|
114
|
+
}
|
|
115
|
+
const tokens = tokenize(text2, line2);
|
|
116
|
+
const kw = tokens[0];
|
|
117
|
+
if (!kw) continue;
|
|
118
|
+
let kind;
|
|
119
|
+
let idIdx = 1;
|
|
120
|
+
if (kw === "node") {
|
|
121
|
+
kind = void 0;
|
|
122
|
+
} else {
|
|
123
|
+
kind = toKind(kw.toLowerCase());
|
|
124
|
+
if (!kind) {
|
|
125
|
+
throw new DTreeParseError(
|
|
126
|
+
`Unknown influence statement "${kw}" (expected decision/chance/value or an arc "a -> b")`,
|
|
127
|
+
line2
|
|
128
|
+
);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
const id = tokens[idIdx];
|
|
132
|
+
if (!id || isQuoted(id)) {
|
|
133
|
+
throw new DTreeParseError(`Node declaration requires an id: "${text2}"`, line2);
|
|
134
|
+
}
|
|
135
|
+
idIdx++;
|
|
136
|
+
let label = "";
|
|
137
|
+
let utility;
|
|
138
|
+
for (let k = idIdx; k < tokens.length; k++) {
|
|
139
|
+
const tok = tokens[k];
|
|
140
|
+
if (isQuoted(tok)) {
|
|
141
|
+
label = unquote(tok);
|
|
142
|
+
} else if (tok.includes("=")) {
|
|
143
|
+
const eq = tok.indexOf("=");
|
|
144
|
+
const key = tok.slice(0, eq).toLowerCase();
|
|
145
|
+
const value = tok.slice(eq + 1);
|
|
146
|
+
if (key === "utility" || key === "payoff" || key === "value") {
|
|
147
|
+
const num = Number(value);
|
|
148
|
+
if (!Number.isNaN(num)) utility = num;
|
|
149
|
+
} else if (key === "kind") {
|
|
150
|
+
const resolved = toKind(value.toLowerCase());
|
|
151
|
+
if (!resolved) throw new DTreeParseError(`Unknown node kind "${value}"`, line2);
|
|
152
|
+
kind = resolved;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
if (!kind) {
|
|
157
|
+
throw new DTreeParseError(`node "${id}" is missing a kind (use kind=decision|chance|value)`, line2);
|
|
158
|
+
}
|
|
159
|
+
if (nodeById.has(id)) {
|
|
160
|
+
throw new DTreeParseError(`Duplicate node id "${id}"`, line2);
|
|
161
|
+
}
|
|
162
|
+
const node = { id, kind, label: label || id };
|
|
163
|
+
if (utility !== void 0) node.utility = utility;
|
|
164
|
+
nodes.push(node);
|
|
165
|
+
nodeById.set(id, node);
|
|
166
|
+
}
|
|
167
|
+
if (nodes.length === 0) {
|
|
168
|
+
throw new DTreeParseError("Influence diagram has no nodes");
|
|
169
|
+
}
|
|
170
|
+
const valueNodes = nodes.filter((n) => n.kind === "value");
|
|
171
|
+
if (valueNodes.length === 0) {
|
|
172
|
+
throw new DTreeParseError(
|
|
173
|
+
'Influence diagram requires at least one value node (declare `value <id> "..."`)'
|
|
174
|
+
);
|
|
175
|
+
}
|
|
176
|
+
const arcs = [];
|
|
177
|
+
for (const a of arcDecls) {
|
|
178
|
+
const fromNode = nodeById.get(a.from);
|
|
179
|
+
const toNode = nodeById.get(a.to);
|
|
180
|
+
if (!fromNode) throw new DTreeParseError(`Arc references undefined node "${a.from}"`, a.line);
|
|
181
|
+
if (!toNode) throw new DTreeParseError(`Arc references undefined node "${a.to}"`, a.line);
|
|
182
|
+
if (a.from === a.to) throw new DTreeParseError(`Self-loop on node "${a.from}" is not allowed`, a.line);
|
|
183
|
+
const kind = toNode.kind === "decision" ? "information" : toNode.kind === "value" ? "functional" : "relevance";
|
|
184
|
+
const arc = { from: a.from, to: a.to, kind };
|
|
185
|
+
if (a.label !== void 0) arc.label = a.label;
|
|
186
|
+
arcs.push(arc);
|
|
187
|
+
}
|
|
188
|
+
detectCycle(nodes, arcs);
|
|
189
|
+
return {
|
|
190
|
+
type: "decisiontree",
|
|
191
|
+
mode: "influence",
|
|
192
|
+
title: title2,
|
|
193
|
+
direction,
|
|
194
|
+
nodes,
|
|
195
|
+
arcs
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
function detectCycle(nodes, arcs) {
|
|
199
|
+
const adj = /* @__PURE__ */ new Map();
|
|
200
|
+
for (const n of nodes) adj.set(n.id, []);
|
|
201
|
+
for (const a of arcs) adj.get(a.from).push(a.to);
|
|
202
|
+
const state2 = /* @__PURE__ */ new Map();
|
|
203
|
+
for (const n of nodes) state2.set(n.id, 0);
|
|
204
|
+
const stackPath = [];
|
|
205
|
+
function visit(id) {
|
|
206
|
+
state2.set(id, 1);
|
|
207
|
+
stackPath.push(id);
|
|
208
|
+
for (const next of adj.get(id) ?? []) {
|
|
209
|
+
const s = state2.get(next) ?? 0;
|
|
210
|
+
if (s === 1) {
|
|
211
|
+
const cycleStart = stackPath.indexOf(next);
|
|
212
|
+
const cycle = [...stackPath.slice(cycleStart), next].join(" -> ");
|
|
213
|
+
throw new DTreeParseError(`Influence diagram must be acyclic \u2014 cycle detected: ${cycle}`);
|
|
214
|
+
}
|
|
215
|
+
if (s === 0) visit(next);
|
|
216
|
+
}
|
|
217
|
+
stackPath.pop();
|
|
218
|
+
state2.set(id, 2);
|
|
219
|
+
}
|
|
220
|
+
for (const n of nodes) {
|
|
221
|
+
if (state2.get(n.id) === 0) visit(n.id);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
|
|
24
225
|
// src/diagrams/decisiontree/parser.ts
|
|
25
226
|
var DTreeParseError = class extends Error {
|
|
26
227
|
constructor(message, line2, column, source) {
|
|
@@ -34,7 +235,7 @@ var DTreeParseError = class extends Error {
|
|
|
34
235
|
column;
|
|
35
236
|
source;
|
|
36
237
|
};
|
|
37
|
-
function
|
|
238
|
+
function preprocess2(src) {
|
|
38
239
|
const out = [];
|
|
39
240
|
const lines = src.split(/\r?\n/);
|
|
40
241
|
for (let i = 0; i < lines.length; i++) {
|
|
@@ -46,7 +247,7 @@ function preprocess(src) {
|
|
|
46
247
|
}
|
|
47
248
|
return out;
|
|
48
249
|
}
|
|
49
|
-
function
|
|
250
|
+
function tokenize2(s) {
|
|
50
251
|
const tokens = [];
|
|
51
252
|
let i = 0;
|
|
52
253
|
while (i < s.length) {
|
|
@@ -77,7 +278,7 @@ function tokenize(s) {
|
|
|
77
278
|
}
|
|
78
279
|
return tokens;
|
|
79
280
|
}
|
|
80
|
-
function
|
|
281
|
+
function unquote2(s) {
|
|
81
282
|
if (s.startsWith('"') && s.endsWith('"')) return s.slice(1, -1);
|
|
82
283
|
return s;
|
|
83
284
|
}
|
|
@@ -87,7 +288,7 @@ function parseKV(tokens) {
|
|
|
87
288
|
const rest = [];
|
|
88
289
|
for (const tok of tokens) {
|
|
89
290
|
if (tok.startsWith('"') && tok.endsWith('"')) {
|
|
90
|
-
labels.push(
|
|
291
|
+
labels.push(unquote2(tok));
|
|
91
292
|
} else if (tok.includes("=")) {
|
|
92
293
|
const idx = tok.indexOf("=");
|
|
93
294
|
const k = tok.slice(0, idx);
|
|
@@ -116,7 +317,7 @@ function parseDecisionLine(tokens, _ctx, lineNum) {
|
|
|
116
317
|
idx++;
|
|
117
318
|
const next = tokens[idx];
|
|
118
319
|
if (!next || !next.startsWith('"')) throw new DTreeParseError(`"choice" requires a label`, lineNum);
|
|
119
|
-
incomingChoice =
|
|
320
|
+
incomingChoice = unquote2(next);
|
|
120
321
|
idx++;
|
|
121
322
|
if (idx >= tokens.length) {
|
|
122
323
|
return {
|
|
@@ -215,7 +416,7 @@ function parseTaxonomyLine(tokens, _ctx, lineNum) {
|
|
|
215
416
|
idx++;
|
|
216
417
|
const lbl = tokens[idx];
|
|
217
418
|
if (!lbl || !lbl.startsWith('"')) throw new DTreeParseError(`"label" requires a quoted string`, lineNum);
|
|
218
|
-
branchLabel =
|
|
419
|
+
branchLabel = unquote2(lbl.replace(/":?$/, '"'));
|
|
219
420
|
if (lbl.endsWith(':"')) ;
|
|
220
421
|
idx++;
|
|
221
422
|
if (tokens[idx] === ":") idx++;
|
|
@@ -239,7 +440,7 @@ function parseTaxonomyLine(tokens, _ctx, lineNum) {
|
|
|
239
440
|
}
|
|
240
441
|
function parseNodeLine(text2, mode, ctx, lineNum) {
|
|
241
442
|
const normalized = text2.replace(/"\s*:\s*/g, '" : ');
|
|
242
|
-
const tokens =
|
|
443
|
+
const tokens = tokenize2(normalized).filter((t) => t !== ":");
|
|
243
444
|
if (mode === "decision") return parseDecisionLine(tokens, ctx, lineNum);
|
|
244
445
|
if (mode === "ml") return parseMlLine(tokens, ctx, lineNum);
|
|
245
446
|
return parseTaxonomyLine(tokens, ctx, lineNum);
|
|
@@ -307,14 +508,19 @@ function validateDecision(node, lineMap) {
|
|
|
307
508
|
}
|
|
308
509
|
function parseDecisionTree(src) {
|
|
309
510
|
idCounter = 0;
|
|
310
|
-
const lines =
|
|
511
|
+
const lines = preprocess2(src);
|
|
311
512
|
if (lines.length === 0) throw new DTreeParseError("Empty input");
|
|
312
513
|
const header = lines.shift();
|
|
313
514
|
const headerMatch = header.text.match(/^decisiontree(?::(\w+))?(?:\s+"([^"]*)")?\s*$/i);
|
|
314
515
|
if (!headerMatch) throw new DTreeParseError(`Invalid header: ${header.text}`, header.line);
|
|
315
516
|
const modeRaw = (headerMatch[1] ?? "taxonomy").toLowerCase();
|
|
316
|
-
const mode = modeRaw === "decision" || modeRaw === "da" ? "decision" : modeRaw === "ml" ? "ml" : "taxonomy";
|
|
317
517
|
const title2 = headerMatch[2];
|
|
518
|
+
const wantsInfluence = modeRaw === "influence" || modeRaw === "id" || lines.some((l) => /^(mode|layout)\s*:\s*influence\s*$/i.test(l.text));
|
|
519
|
+
if (wantsInfluence) {
|
|
520
|
+
const body = lines.map((l) => l.text).join("\n");
|
|
521
|
+
return parseInfluence(body, title2);
|
|
522
|
+
}
|
|
523
|
+
const mode = modeRaw === "decision" || modeRaw === "da" ? "decision" : modeRaw === "ml" ? "ml" : "taxonomy";
|
|
318
524
|
const nodeKeywords = /* @__PURE__ */ new Set([
|
|
319
525
|
"decision",
|
|
320
526
|
"chance",
|
|
@@ -625,7 +831,7 @@ function layoutDecisionTree(ast) {
|
|
|
625
831
|
enforceSibGap(root, sibH, sibGap);
|
|
626
832
|
const levelOffsets = computeLevelOffsets(root, sibH, levelGap);
|
|
627
833
|
setFinal(root, sibH, levelOffsets);
|
|
628
|
-
const
|
|
834
|
+
const PADDING4 = 40;
|
|
629
835
|
const extraLeft = ast.mode === "decision" && !sibH ? 110 : 0;
|
|
630
836
|
let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity;
|
|
631
837
|
for (const n of all) {
|
|
@@ -650,8 +856,8 @@ function layoutDecisionTree(ast) {
|
|
|
650
856
|
maxX = Math.max(maxX, n.xFinal + n.size.w / 2);
|
|
651
857
|
}
|
|
652
858
|
}
|
|
653
|
-
const offsetX =
|
|
654
|
-
const offsetY =
|
|
859
|
+
const offsetX = PADDING4 + extraLeft - minX;
|
|
860
|
+
const offsetY = PADDING4 - minY;
|
|
655
861
|
const layoutNodes = all.map((w) => ({
|
|
656
862
|
node: w.node,
|
|
657
863
|
x: w.xFinal + offsetX,
|
|
@@ -712,8 +918,8 @@ function layoutDecisionTree(ast) {
|
|
|
712
918
|
for (const n of layoutNodes) if (n.node.kind === "end") endX = Math.max(endX, n.x + n.width / 2);
|
|
713
919
|
payoffColumnX = endX + payoffColGap;
|
|
714
920
|
}
|
|
715
|
-
const width = Math.ceil(maxX - minX +
|
|
716
|
-
const height = Math.ceil(maxY - minY +
|
|
921
|
+
const width = Math.ceil(maxX - minX + PADDING4 * 2 + extraRight + extraLeft);
|
|
922
|
+
const height = Math.ceil(maxY - minY + PADDING4 * 2);
|
|
717
923
|
return {
|
|
718
924
|
width,
|
|
719
925
|
height,
|
|
@@ -743,6 +949,296 @@ function formatProb(p) {
|
|
|
743
949
|
return `p=${p}`;
|
|
744
950
|
}
|
|
745
951
|
|
|
952
|
+
// src/diagrams/decisiontree/influence-layout.ts
|
|
953
|
+
function sizeOf2(node) {
|
|
954
|
+
const labelW = Math.min(180, Math.max(72, node.label.length * 8 + 28));
|
|
955
|
+
if (node.kind === "decision") return { w: labelW, h: 48 };
|
|
956
|
+
if (node.kind === "value") return { w: labelW + 12, h: 54 };
|
|
957
|
+
return { w: labelW, h: 52 };
|
|
958
|
+
}
|
|
959
|
+
var LAYER_GAP = 80;
|
|
960
|
+
var CROSS_GAP = 36;
|
|
961
|
+
var PADDING = 36;
|
|
962
|
+
function assignLayers(nodes, arcs) {
|
|
963
|
+
const adj = /* @__PURE__ */ new Map();
|
|
964
|
+
const indeg = /* @__PURE__ */ new Map();
|
|
965
|
+
for (const n of nodes) {
|
|
966
|
+
adj.set(n.id, []);
|
|
967
|
+
indeg.set(n.id, 0);
|
|
968
|
+
}
|
|
969
|
+
for (const a of arcs) {
|
|
970
|
+
adj.get(a.from).push(a.to);
|
|
971
|
+
indeg.set(a.to, (indeg.get(a.to) ?? 0) + 1);
|
|
972
|
+
}
|
|
973
|
+
const queue = [];
|
|
974
|
+
for (const n of nodes) if ((indeg.get(n.id) ?? 0) === 0) queue.push(n.id);
|
|
975
|
+
const layer = /* @__PURE__ */ new Map();
|
|
976
|
+
for (const n of nodes) layer.set(n.id, 0);
|
|
977
|
+
const indegWork = new Map(indeg);
|
|
978
|
+
while (queue.length > 0) {
|
|
979
|
+
const id = queue.shift();
|
|
980
|
+
for (const next of adj.get(id) ?? []) {
|
|
981
|
+
const cand = (layer.get(id) ?? 0) + 1;
|
|
982
|
+
if (cand > (layer.get(next) ?? 0)) layer.set(next, cand);
|
|
983
|
+
indegWork.set(next, (indegWork.get(next) ?? 0) - 1);
|
|
984
|
+
if ((indegWork.get(next) ?? 0) === 0) queue.push(next);
|
|
985
|
+
}
|
|
986
|
+
}
|
|
987
|
+
const maxLayer = Math.max(0, ...nodes.map((n) => layer.get(n.id) ?? 0));
|
|
988
|
+
for (const n of nodes) {
|
|
989
|
+
if (n.kind === "value") layer.set(n.id, maxLayer);
|
|
990
|
+
}
|
|
991
|
+
return layer;
|
|
992
|
+
}
|
|
993
|
+
function layoutInfluence(ast) {
|
|
994
|
+
const flowVertical = ast.direction === "top-down";
|
|
995
|
+
const layerOf = assignLayers(ast.nodes, ast.arcs);
|
|
996
|
+
const sizes = new Map(ast.nodes.map((n) => [n.id, sizeOf2(n)]));
|
|
997
|
+
const layers = /* @__PURE__ */ new Map();
|
|
998
|
+
for (const n of ast.nodes) {
|
|
999
|
+
const l = layerOf.get(n.id) ?? 0;
|
|
1000
|
+
if (!layers.has(l)) layers.set(l, []);
|
|
1001
|
+
layers.get(l).push(n);
|
|
1002
|
+
}
|
|
1003
|
+
const layerIndices = Array.from(layers.keys()).sort((a, b) => a - b);
|
|
1004
|
+
const flowExtent = (s) => flowVertical ? s.h : s.w;
|
|
1005
|
+
const crossExtent = (s) => flowVertical ? s.w : s.h;
|
|
1006
|
+
const layerFlowSize = /* @__PURE__ */ new Map();
|
|
1007
|
+
for (const l of layerIndices) {
|
|
1008
|
+
let maxF = 0;
|
|
1009
|
+
for (const n of layers.get(l)) maxF = Math.max(maxF, flowExtent(sizes.get(n.id)));
|
|
1010
|
+
layerFlowSize.set(l, maxF);
|
|
1011
|
+
}
|
|
1012
|
+
const layerFlowCentre = /* @__PURE__ */ new Map();
|
|
1013
|
+
let acc = PADDING;
|
|
1014
|
+
for (const l of layerIndices) {
|
|
1015
|
+
const half = layerFlowSize.get(l) / 2;
|
|
1016
|
+
acc += half;
|
|
1017
|
+
layerFlowCentre.set(l, acc);
|
|
1018
|
+
acc += half + LAYER_GAP;
|
|
1019
|
+
}
|
|
1020
|
+
const flowTotal = acc - LAYER_GAP + PADDING;
|
|
1021
|
+
const layerCrossExtent = /* @__PURE__ */ new Map();
|
|
1022
|
+
for (const l of layerIndices) {
|
|
1023
|
+
const ns = layers.get(l);
|
|
1024
|
+
let total = 0;
|
|
1025
|
+
for (let i = 0; i < ns.length; i++) {
|
|
1026
|
+
total += crossExtent(sizes.get(ns[i].id));
|
|
1027
|
+
if (i < ns.length - 1) total += CROSS_GAP;
|
|
1028
|
+
}
|
|
1029
|
+
layerCrossExtent.set(l, total);
|
|
1030
|
+
}
|
|
1031
|
+
const maxCross = Math.max(PADDING, ...Array.from(layerCrossExtent.values()));
|
|
1032
|
+
const crossTotal = maxCross + PADDING * 2;
|
|
1033
|
+
const crossCentre = PADDING + maxCross / 2;
|
|
1034
|
+
const placed = /* @__PURE__ */ new Map();
|
|
1035
|
+
for (const l of layerIndices) {
|
|
1036
|
+
const ns = layers.get(l);
|
|
1037
|
+
const bandLen = layerCrossExtent.get(l);
|
|
1038
|
+
let cursor = crossCentre - bandLen / 2;
|
|
1039
|
+
const flowPos = layerFlowCentre.get(l);
|
|
1040
|
+
for (const n of ns) {
|
|
1041
|
+
const s = sizes.get(n.id);
|
|
1042
|
+
const crossCentrePos = cursor + crossExtent(s) / 2;
|
|
1043
|
+
cursor += crossExtent(s) + CROSS_GAP;
|
|
1044
|
+
const x = flowVertical ? crossCentrePos : flowPos;
|
|
1045
|
+
const y = flowVertical ? flowPos : crossCentrePos;
|
|
1046
|
+
placed.set(n.id, {
|
|
1047
|
+
node: n,
|
|
1048
|
+
x,
|
|
1049
|
+
y,
|
|
1050
|
+
width: s.w,
|
|
1051
|
+
height: s.h,
|
|
1052
|
+
layer: l
|
|
1053
|
+
});
|
|
1054
|
+
}
|
|
1055
|
+
}
|
|
1056
|
+
const width = Math.ceil(flowVertical ? crossTotal : flowTotal);
|
|
1057
|
+
const height = Math.ceil(flowVertical ? flowTotal : crossTotal);
|
|
1058
|
+
const arcs = [];
|
|
1059
|
+
for (const a of ast.arcs) {
|
|
1060
|
+
const from = placed.get(a.from);
|
|
1061
|
+
const to = placed.get(a.to);
|
|
1062
|
+
if (!from || !to) continue;
|
|
1063
|
+
const start = boundaryPoint(from, to.x, to.y);
|
|
1064
|
+
const end = boundaryPoint(to, from.x, from.y);
|
|
1065
|
+
const angle = Math.atan2(end.y - start.y, end.x - start.x) * 180 / Math.PI;
|
|
1066
|
+
const arc = {
|
|
1067
|
+
from: a.from,
|
|
1068
|
+
to: a.to,
|
|
1069
|
+
kind: a.kind,
|
|
1070
|
+
path: `M ${round(start.x)} ${round(start.y)} L ${round(end.x)} ${round(end.y)}`,
|
|
1071
|
+
tip: { x: end.x, y: end.y, angle },
|
|
1072
|
+
labelAt: { x: (start.x + end.x) / 2, y: (start.y + end.y) / 2 }
|
|
1073
|
+
};
|
|
1074
|
+
if (a.label !== void 0) arc.label = a.label;
|
|
1075
|
+
arcs.push(arc);
|
|
1076
|
+
}
|
|
1077
|
+
return {
|
|
1078
|
+
width,
|
|
1079
|
+
height,
|
|
1080
|
+
nodes: Array.from(placed.values()),
|
|
1081
|
+
arcs,
|
|
1082
|
+
title: ast.title,
|
|
1083
|
+
direction: ast.direction
|
|
1084
|
+
};
|
|
1085
|
+
}
|
|
1086
|
+
function boundaryPoint(n, tx, ty) {
|
|
1087
|
+
const dx = tx - n.x;
|
|
1088
|
+
const dy = ty - n.y;
|
|
1089
|
+
if (dx === 0 && dy === 0) return { x: n.x, y: n.y };
|
|
1090
|
+
const hw = n.width / 2;
|
|
1091
|
+
const hh = n.height / 2;
|
|
1092
|
+
if (n.node.kind === "chance") {
|
|
1093
|
+
const denom = Math.sqrt(dx * dx / (hw * hw) + dy * dy / (hh * hh));
|
|
1094
|
+
return { x: n.x + dx / denom, y: n.y + dy / denom };
|
|
1095
|
+
}
|
|
1096
|
+
const scaleX = dx !== 0 ? hw / Math.abs(dx) : Infinity;
|
|
1097
|
+
const scaleY = dy !== 0 ? hh / Math.abs(dy) : Infinity;
|
|
1098
|
+
const scale = Math.min(scaleX, scaleY);
|
|
1099
|
+
return { x: n.x + dx * scale, y: n.y + dy * scale };
|
|
1100
|
+
}
|
|
1101
|
+
function round(n) {
|
|
1102
|
+
return Math.round(n * 100) / 100;
|
|
1103
|
+
}
|
|
1104
|
+
|
|
1105
|
+
// src/diagrams/decisiontree/influence-renderer.ts
|
|
1106
|
+
function buildCss(t) {
|
|
1107
|
+
return `
|
|
1108
|
+
.lt-dtree { font-family: system-ui, -apple-system, sans-serif; }
|
|
1109
|
+
.lt-dtree-title { font: 500 16px sans-serif; fill: ${t.text}; }
|
|
1110
|
+
.lt-dtree-decision { fill: #dbeafe; stroke: #1d4ed8; stroke-width: 1.6; }
|
|
1111
|
+
.lt-dtree-chance { fill: #fef3c7; stroke: #b45309; stroke-width: 1.6; }
|
|
1112
|
+
.lt-dtree-value { fill: #dcfce7; stroke: #15803d; stroke-width: 1.6; }
|
|
1113
|
+
.lt-dtree-node-label { font: 500 12px sans-serif; fill: ${t.text}; text-anchor: middle; dominant-baseline: middle; }
|
|
1114
|
+
.lt-dtree-value-util { font: 600 10px "SF Mono", monospace; fill: ${t.textMuted}; text-anchor: middle; }
|
|
1115
|
+
.lt-dtree-arc { fill: none; stroke: ${t.stroke}; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }
|
|
1116
|
+
.lt-dtree-arc-information { fill: none; stroke: ${t.stroke}; stroke-width: 1.6; stroke-dasharray: 5 4; stroke-linecap: round; }
|
|
1117
|
+
.lt-dtree-arc-head { fill: ${t.stroke}; stroke: none; }
|
|
1118
|
+
.lt-dtree-arc-label { font: 500 10px sans-serif; fill: ${t.textMuted}; text-anchor: middle; dominant-baseline: middle; }
|
|
1119
|
+
.lt-dtree-arc-label-bg { fill: ${t.bg}; stroke: none; }
|
|
1120
|
+
`.trim();
|
|
1121
|
+
}
|
|
1122
|
+
function renderNode(ln) {
|
|
1123
|
+
const n = ln.node;
|
|
1124
|
+
const parts = [];
|
|
1125
|
+
const hw = ln.width / 2;
|
|
1126
|
+
const hh = ln.height / 2;
|
|
1127
|
+
if (n.kind === "decision") {
|
|
1128
|
+
parts.push(chunk3WNW5Y7P_cjs.rect({
|
|
1129
|
+
x: ln.x - hw,
|
|
1130
|
+
y: ln.y - hh,
|
|
1131
|
+
width: ln.width,
|
|
1132
|
+
height: ln.height,
|
|
1133
|
+
rx: 3,
|
|
1134
|
+
ry: 3,
|
|
1135
|
+
class: "lt-dtree-decision"
|
|
1136
|
+
}));
|
|
1137
|
+
} else if (n.kind === "chance") {
|
|
1138
|
+
parts.push(chunk3WNW5Y7P_cjs.el("ellipse", {
|
|
1139
|
+
cx: ln.x,
|
|
1140
|
+
cy: ln.y,
|
|
1141
|
+
rx: hw,
|
|
1142
|
+
ry: hh,
|
|
1143
|
+
class: "lt-dtree-chance"
|
|
1144
|
+
}));
|
|
1145
|
+
} else {
|
|
1146
|
+
const ix = Math.min(14, ln.width * 0.2);
|
|
1147
|
+
const iy = Math.min(10, hh * 0.55);
|
|
1148
|
+
const pts = [
|
|
1149
|
+
`${ln.x - hw + ix},${ln.y - hh}`,
|
|
1150
|
+
`${ln.x + hw - ix},${ln.y - hh}`,
|
|
1151
|
+
`${ln.x + hw},${ln.y - hh + iy}`,
|
|
1152
|
+
`${ln.x + hw},${ln.y + hh - iy}`,
|
|
1153
|
+
`${ln.x + hw - ix},${ln.y + hh}`,
|
|
1154
|
+
`${ln.x - hw + ix},${ln.y + hh}`,
|
|
1155
|
+
`${ln.x - hw},${ln.y + hh - iy}`,
|
|
1156
|
+
`${ln.x - hw},${ln.y - hh + iy}`
|
|
1157
|
+
].join(" ");
|
|
1158
|
+
parts.push(chunk3WNW5Y7P_cjs.polygon({ points: pts, class: "lt-dtree-value" }));
|
|
1159
|
+
}
|
|
1160
|
+
const hasUtil = n.kind === "value" && n.utility !== void 0;
|
|
1161
|
+
const labelY = hasUtil ? ln.y - 6 : ln.y;
|
|
1162
|
+
parts.push(chunk3WNW5Y7P_cjs.text({ x: ln.x, y: labelY, class: "lt-dtree-node-label" }, n.label));
|
|
1163
|
+
if (hasUtil) {
|
|
1164
|
+
parts.push(chunk3WNW5Y7P_cjs.text({ x: ln.x, y: ln.y + 11, class: "lt-dtree-value-util" }, `U=${formatNum(n.utility)}`));
|
|
1165
|
+
}
|
|
1166
|
+
return chunk3WNW5Y7P_cjs.group({
|
|
1167
|
+
"data-node-id": n.id,
|
|
1168
|
+
"data-node-kind": n.kind,
|
|
1169
|
+
"data-layer": String(ln.layer)
|
|
1170
|
+
}, parts);
|
|
1171
|
+
}
|
|
1172
|
+
function arrowHead(arc) {
|
|
1173
|
+
const size = 9;
|
|
1174
|
+
const rad = arc.tip.angle * Math.PI / 180;
|
|
1175
|
+
const tx = arc.tip.x;
|
|
1176
|
+
const ty = arc.tip.y;
|
|
1177
|
+
const spread = 25 * Math.PI / 180;
|
|
1178
|
+
const bx1 = tx - size * Math.cos(rad - spread);
|
|
1179
|
+
const by1 = ty - size * Math.sin(rad - spread);
|
|
1180
|
+
const bx2 = tx - size * Math.cos(rad + spread);
|
|
1181
|
+
const by2 = ty - size * Math.sin(rad + spread);
|
|
1182
|
+
const pts = `${round2(tx)},${round2(ty)} ${round2(bx1)},${round2(by1)} ${round2(bx2)},${round2(by2)}`;
|
|
1183
|
+
return chunk3WNW5Y7P_cjs.polygon({ points: pts, class: "lt-dtree-arc-head" });
|
|
1184
|
+
}
|
|
1185
|
+
function renderArc(arc) {
|
|
1186
|
+
const parts = [];
|
|
1187
|
+
const cls = arc.kind === "information" ? "lt-dtree-arc-information" : "lt-dtree-arc";
|
|
1188
|
+
parts.push(chunk3WNW5Y7P_cjs.path({ d: arc.path, class: cls, "data-arc": `${arc.from}->${arc.to}`, "data-arc-kind": arc.kind }));
|
|
1189
|
+
parts.push(arrowHead(arc));
|
|
1190
|
+
if (arc.label && arc.labelAt) {
|
|
1191
|
+
const w = Math.max(arc.label.length * 5.6 + 8, 16);
|
|
1192
|
+
parts.push(chunk3WNW5Y7P_cjs.rect({
|
|
1193
|
+
x: arc.labelAt.x - w / 2,
|
|
1194
|
+
y: arc.labelAt.y - 7,
|
|
1195
|
+
width: w,
|
|
1196
|
+
height: 14,
|
|
1197
|
+
rx: 3,
|
|
1198
|
+
ry: 3,
|
|
1199
|
+
class: "lt-dtree-arc-label-bg"
|
|
1200
|
+
}));
|
|
1201
|
+
parts.push(chunk3WNW5Y7P_cjs.text({ x: arc.labelAt.x, y: arc.labelAt.y, class: "lt-dtree-arc-label" }, arc.label));
|
|
1202
|
+
}
|
|
1203
|
+
return chunk3WNW5Y7P_cjs.group({}, parts);
|
|
1204
|
+
}
|
|
1205
|
+
function formatNum(n) {
|
|
1206
|
+
if (Math.abs(n) >= 1e4) return n.toLocaleString(void 0, { maximumFractionDigits: 0 });
|
|
1207
|
+
if (Number.isInteger(n)) return String(n);
|
|
1208
|
+
return n.toFixed(2);
|
|
1209
|
+
}
|
|
1210
|
+
function round2(n) {
|
|
1211
|
+
return Math.round(n * 100) / 100;
|
|
1212
|
+
}
|
|
1213
|
+
function renderInfluence(ast, config) {
|
|
1214
|
+
const t = chunkNZT5P2XZ_cjs.resolveBaseTheme(config?.theme ?? "default");
|
|
1215
|
+
const layout = layoutInfluence(ast);
|
|
1216
|
+
const titleOffset = ast.title ? 36 : 10;
|
|
1217
|
+
const width = Math.ceil(layout.width);
|
|
1218
|
+
const height = Math.ceil(layout.height + titleOffset);
|
|
1219
|
+
const children = [];
|
|
1220
|
+
children.push(chunk3WNW5Y7P_cjs.title(ast.title ?? "Influence Diagram"));
|
|
1221
|
+
children.push(chunk3WNW5Y7P_cjs.desc(
|
|
1222
|
+
`Influence diagram with ${layout.nodes.length} nodes and ${layout.arcs.length} arcs`
|
|
1223
|
+
));
|
|
1224
|
+
children.push(chunk3WNW5Y7P_cjs.el("style", {}, buildCss(t)));
|
|
1225
|
+
if (ast.title) {
|
|
1226
|
+
children.push(chunk3WNW5Y7P_cjs.text({ x: 20, y: 24, class: "lt-dtree-title" }, ast.title));
|
|
1227
|
+
}
|
|
1228
|
+
const inner = [];
|
|
1229
|
+
for (const arc of layout.arcs) inner.push(renderArc(arc));
|
|
1230
|
+
for (const ln of layout.nodes) inner.push(renderNode(ln));
|
|
1231
|
+
children.push(chunk3WNW5Y7P_cjs.group({ transform: `translate(0, ${titleOffset})`, "data-mode": "influence" }, inner));
|
|
1232
|
+
return chunk3WNW5Y7P_cjs.svgRoot({
|
|
1233
|
+
class: "lt-dtree",
|
|
1234
|
+
role: "img",
|
|
1235
|
+
"aria-label": chunk3WNW5Y7P_cjs.escapeXml(ast.title ?? "Influence diagram"),
|
|
1236
|
+
width,
|
|
1237
|
+
height,
|
|
1238
|
+
viewBox: `0 0 ${width} ${height}`
|
|
1239
|
+
}, children);
|
|
1240
|
+
}
|
|
1241
|
+
|
|
746
1242
|
// src/diagrams/decisiontree/renderer.ts
|
|
747
1243
|
var CLASS_PALETTE = [
|
|
748
1244
|
"#0ea5e9",
|
|
@@ -756,7 +1252,7 @@ var CLASS_PALETTE = [
|
|
|
756
1252
|
"#06b6d4",
|
|
757
1253
|
"#f97316"
|
|
758
1254
|
];
|
|
759
|
-
function
|
|
1255
|
+
function buildCss2(t) {
|
|
760
1256
|
return `
|
|
761
1257
|
.lt-dtree { font-family: system-ui, -apple-system, sans-serif; }
|
|
762
1258
|
.lt-dtree-title { font: 500 16px sans-serif; fill: ${t.text}; }
|
|
@@ -821,7 +1317,7 @@ function renderDecisionNode(ln, layout) {
|
|
|
821
1317
|
y: ln.y + ln.height / 2 + 13,
|
|
822
1318
|
class: "lt-dtree-ev",
|
|
823
1319
|
"text-anchor": "middle"
|
|
824
|
-
}, `EV=${
|
|
1320
|
+
}, `EV=${formatNum2(n.ev)}`));
|
|
825
1321
|
}
|
|
826
1322
|
} else if (n.kind === "chance") {
|
|
827
1323
|
parts.push(chunk3WNW5Y7P_cjs.circle({
|
|
@@ -853,7 +1349,7 @@ function renderDecisionNode(ln, layout) {
|
|
|
853
1349
|
y: ln.y + ln.height / 2 + 13,
|
|
854
1350
|
class: n.optimal ? "lt-dtree-ev-optimal" : "lt-dtree-ev",
|
|
855
1351
|
"text-anchor": "middle"
|
|
856
|
-
}, `EV=${
|
|
1352
|
+
}, `EV=${formatNum2(n.ev)}`));
|
|
857
1353
|
}
|
|
858
1354
|
} else if (n.kind === "end") {
|
|
859
1355
|
const halfW = ln.width / 2;
|
|
@@ -909,7 +1405,7 @@ function renderDecisionNode(ln, layout) {
|
|
|
909
1405
|
"data-ev": n.ev !== void 0 ? String(n.ev) : ""
|
|
910
1406
|
}, parts);
|
|
911
1407
|
}
|
|
912
|
-
function
|
|
1408
|
+
function formatNum2(n) {
|
|
913
1409
|
if (Math.abs(n) >= 1e4) return n.toLocaleString(void 0, { maximumFractionDigits: 0 });
|
|
914
1410
|
if (Number.isInteger(n)) return String(n);
|
|
915
1411
|
return n.toFixed(2);
|
|
@@ -960,7 +1456,7 @@ function renderMlNode(ln, ast) {
|
|
|
960
1456
|
let textY = y + 16;
|
|
961
1457
|
const lineH = 14;
|
|
962
1458
|
if (n.kind === "split" && n.feature) {
|
|
963
|
-
const thresh = typeof n.threshold === "number" ?
|
|
1459
|
+
const thresh = typeof n.threshold === "number" ? formatNum2(n.threshold) : n.threshold ?? "";
|
|
964
1460
|
parts.push(chunk3WNW5Y7P_cjs.text(
|
|
965
1461
|
{ x: textX, y: textY, class: "lt-dtree-ml-line-1", "text-anchor": "middle" },
|
|
966
1462
|
`${n.feature} ${n.op ?? ""} ${thresh}`
|
|
@@ -974,7 +1470,7 @@ function renderMlNode(ln, ast) {
|
|
|
974
1470
|
const impName = ast.impurityName ?? "gini";
|
|
975
1471
|
parts.push(chunk3WNW5Y7P_cjs.text(
|
|
976
1472
|
{ x: textX, y: textY, class: "lt-dtree-ml-line-muted", "text-anchor": "middle" },
|
|
977
|
-
`${impName} = ${
|
|
1473
|
+
`${impName} = ${formatNum2(n.impurity)}`
|
|
978
1474
|
));
|
|
979
1475
|
textY += lineH;
|
|
980
1476
|
}
|
|
@@ -986,7 +1482,7 @@ function renderMlNode(ln, ast) {
|
|
|
986
1482
|
textY += lineH;
|
|
987
1483
|
}
|
|
988
1484
|
if (n.value !== void 0) {
|
|
989
|
-
const vStr = Array.isArray(n.value) ? `value = [${n.value.join(", ")}]` : `value = ${
|
|
1485
|
+
const vStr = Array.isArray(n.value) ? `value = [${n.value.join(", ")}]` : `value = ${formatNum2(n.value)}`;
|
|
990
1486
|
parts.push(chunk3WNW5Y7P_cjs.text({ x: textX, y: textY, class: "lt-dtree-ml-mono", "text-anchor": "middle" }, vStr));
|
|
991
1487
|
textY += lineH;
|
|
992
1488
|
}
|
|
@@ -1004,7 +1500,7 @@ function renderMlNode(ln, ast) {
|
|
|
1004
1500
|
} else if (typeof n.value === "number") {
|
|
1005
1501
|
parts.push(chunk3WNW5Y7P_cjs.text(
|
|
1006
1502
|
{ x: textX, y: textY, class: "lt-dtree-ml-class", "text-anchor": "middle", fill: "#0f172a" },
|
|
1007
|
-
`predicted = ${
|
|
1503
|
+
`predicted = ${formatNum2(n.value)}`
|
|
1008
1504
|
));
|
|
1009
1505
|
textY += lineH;
|
|
1010
1506
|
}
|
|
@@ -1080,6 +1576,7 @@ function wrapText(text2, maxChars) {
|
|
|
1080
1576
|
return lines.slice(0, 2);
|
|
1081
1577
|
}
|
|
1082
1578
|
function renderDecisionTree(ast, config) {
|
|
1579
|
+
if ("arcs" in ast) return renderInfluence(ast, config);
|
|
1083
1580
|
const t = chunkNZT5P2XZ_cjs.resolveBaseTheme(config?.theme ?? "default");
|
|
1084
1581
|
const layout = layoutDecisionTree(ast);
|
|
1085
1582
|
const titleOffset = ast.title ? 36 : 10;
|
|
@@ -1088,7 +1585,7 @@ function renderDecisionTree(ast, config) {
|
|
|
1088
1585
|
const children = [];
|
|
1089
1586
|
children.push(chunk3WNW5Y7P_cjs.title(ast.title ?? "Decision Tree"));
|
|
1090
1587
|
children.push(chunk3WNW5Y7P_cjs.desc(`Decision tree (${ast.mode} mode) with ${layout.nodes.length} nodes and ${layout.edges.length} edges`));
|
|
1091
|
-
children.push(chunk3WNW5Y7P_cjs.el("style", {},
|
|
1588
|
+
children.push(chunk3WNW5Y7P_cjs.el("style", {}, buildCss2(t)));
|
|
1092
1589
|
if (ast.title) {
|
|
1093
1590
|
children.push(chunk3WNW5Y7P_cjs.text({ x: 20, y: 24, class: "lt-dtree-title" }, ast.title));
|
|
1094
1591
|
}
|
|
@@ -1251,7 +1748,7 @@ var TimelineParseError = class extends Error {
|
|
|
1251
1748
|
column;
|
|
1252
1749
|
source;
|
|
1253
1750
|
};
|
|
1254
|
-
function
|
|
1751
|
+
function preprocess3(src) {
|
|
1255
1752
|
const out = [];
|
|
1256
1753
|
const lines = src.split(/\r?\n/);
|
|
1257
1754
|
for (let i = 0; i < lines.length; i++) {
|
|
@@ -1365,7 +1862,7 @@ function splitDateAndBody(s, lineNum) {
|
|
|
1365
1862
|
return { date: datePart, body };
|
|
1366
1863
|
}
|
|
1367
1864
|
function parseTimeline(src) {
|
|
1368
|
-
const lines =
|
|
1865
|
+
const lines = preprocess3(src);
|
|
1369
1866
|
if (!lines.length) throw new TimelineParseError("Empty timeline");
|
|
1370
1867
|
const ast = {
|
|
1371
1868
|
type: "timeline",
|
|
@@ -2704,7 +3201,7 @@ var MERMAID_STEREOTYPE = {
|
|
|
2704
3201
|
join: "join",
|
|
2705
3202
|
end: "final"
|
|
2706
3203
|
};
|
|
2707
|
-
function
|
|
3204
|
+
function preprocess4(src) {
|
|
2708
3205
|
const out = [];
|
|
2709
3206
|
const lines = src.split(/\r?\n/);
|
|
2710
3207
|
for (let i = 0; i < lines.length; i++) {
|
|
@@ -2718,7 +3215,7 @@ function preprocess3(src) {
|
|
|
2718
3215
|
}
|
|
2719
3216
|
return out;
|
|
2720
3217
|
}
|
|
2721
|
-
function
|
|
3218
|
+
function unquote3(s) {
|
|
2722
3219
|
if (s.length >= 2 && s.startsWith('"') && s.endsWith('"')) {
|
|
2723
3220
|
return s.slice(1, -1);
|
|
2724
3221
|
}
|
|
@@ -2731,7 +3228,7 @@ function parseProps(s) {
|
|
|
2731
3228
|
for (const part of inner.split(",")) {
|
|
2732
3229
|
const idx = part.indexOf(":");
|
|
2733
3230
|
if (idx < 0) continue;
|
|
2734
|
-
out[part.slice(0, idx).trim()] =
|
|
3231
|
+
out[part.slice(0, idx).trim()] = unquote3(part.slice(idx + 1).trim());
|
|
2735
3232
|
}
|
|
2736
3233
|
return out;
|
|
2737
3234
|
}
|
|
@@ -2872,7 +3369,7 @@ function isIdent(tok) {
|
|
|
2872
3369
|
return /^[A-Za-z_][A-Za-z0-9_]*$/.test(tok);
|
|
2873
3370
|
}
|
|
2874
3371
|
function parseStateDiagram(src) {
|
|
2875
|
-
const lines =
|
|
3372
|
+
const lines = preprocess4(src);
|
|
2876
3373
|
if (lines.length === 0) {
|
|
2877
3374
|
throw new StateParseError("Empty document");
|
|
2878
3375
|
}
|
|
@@ -2894,7 +3391,7 @@ function parseStateDiagram(src) {
|
|
|
2894
3391
|
if (props.direction === "TB" || props.direction === "LR") direction = props.direction;
|
|
2895
3392
|
beforeProps = headerRest.slice(0, propsMatch.index).trim();
|
|
2896
3393
|
}
|
|
2897
|
-
if (beforeProps.startsWith('"')) title2 =
|
|
3394
|
+
if (beforeProps.startsWith('"')) title2 = unquote3(beforeProps);
|
|
2898
3395
|
else if (beforeProps.length > 0) title2 = beforeProps;
|
|
2899
3396
|
const ctx = {
|
|
2900
3397
|
states: [],
|
|
@@ -2981,7 +3478,7 @@ function parseStateDiagram(src) {
|
|
|
2981
3478
|
const stateLabelMatch = text2.match(/^state\s+([A-Za-z_][A-Za-z0-9_]*)\s*:\s*(.+)$/);
|
|
2982
3479
|
if (stateLabelMatch) {
|
|
2983
3480
|
const node = ensureSimpleState(ctx, stateLabelMatch[1], parent);
|
|
2984
|
-
node.label =
|
|
3481
|
+
node.label = unquote3(stateLabelMatch[2].trim());
|
|
2985
3482
|
i++;
|
|
2986
3483
|
continue;
|
|
2987
3484
|
}
|
|
@@ -3116,7 +3613,7 @@ function parseStateDiagram(src) {
|
|
|
3116
3613
|
const labelOnlyMatch = text2.match(/^([A-Za-z_][A-Za-z0-9_]*)\s*:\s*(.+)$/);
|
|
3117
3614
|
if (labelOnlyMatch && isIdent(labelOnlyMatch[1])) {
|
|
3118
3615
|
const node = ensureSimpleState(ctx, labelOnlyMatch[1], parent);
|
|
3119
|
-
node.label =
|
|
3616
|
+
node.label = unquote3(labelOnlyMatch[2].trim());
|
|
3120
3617
|
i++;
|
|
3121
3618
|
continue;
|
|
3122
3619
|
}
|
|
@@ -3844,7 +4341,7 @@ function renderPseudo(node) {
|
|
|
3844
4341
|
return "";
|
|
3845
4342
|
}
|
|
3846
4343
|
}
|
|
3847
|
-
function
|
|
4344
|
+
function renderNode2(node) {
|
|
3848
4345
|
if (node.node.kind === "pseudo") return renderPseudo(node);
|
|
3849
4346
|
return renderSimple(node);
|
|
3850
4347
|
}
|
|
@@ -3926,7 +4423,7 @@ function renderLayout(layout) {
|
|
|
3926
4423
|
titleNode,
|
|
3927
4424
|
// Composite clusters first so simple-state bodies sit on top.
|
|
3928
4425
|
chunk3WNW5Y7P_cjs.group({ class: "lt-clusters" }, layout.clusters.map(renderComposite)),
|
|
3929
|
-
chunk3WNW5Y7P_cjs.group({ class: "lt-state-bodies" }, layout.nodes.map(
|
|
4426
|
+
chunk3WNW5Y7P_cjs.group({ class: "lt-state-bodies" }, layout.nodes.map(renderNode2)),
|
|
3930
4427
|
chunk3WNW5Y7P_cjs.group({ class: "lt-edges" }, layout.edges.map(renderEdge)),
|
|
3931
4428
|
chunk3WNW5Y7P_cjs.group({ class: "lt-notes" }, layout.notes.map(renderNote))
|
|
3932
4429
|
]
|
|
@@ -4007,7 +4504,7 @@ var INST_CATEGORIES = /* @__PURE__ */ new Set([
|
|
|
4007
4504
|
"local_discrete",
|
|
4008
4505
|
"local_shared"
|
|
4009
4506
|
]);
|
|
4010
|
-
function
|
|
4507
|
+
function preprocess5(src) {
|
|
4011
4508
|
const out = [];
|
|
4012
4509
|
const lines = src.split(/\r?\n/);
|
|
4013
4510
|
for (let i = 0; i < lines.length; i++) {
|
|
@@ -4027,7 +4524,7 @@ function preprocess4(src) {
|
|
|
4027
4524
|
}
|
|
4028
4525
|
return out;
|
|
4029
4526
|
}
|
|
4030
|
-
function
|
|
4527
|
+
function unquote4(s) {
|
|
4031
4528
|
const t = s.trim();
|
|
4032
4529
|
if (t.length >= 2 && t.startsWith('"') && t.endsWith('"')) {
|
|
4033
4530
|
return t.slice(1, -1).replace(/\\"/g, '"');
|
|
@@ -4056,7 +4553,7 @@ function parseAttrList(inside) {
|
|
|
4056
4553
|
const idx = p.indexOf(":");
|
|
4057
4554
|
if (idx < 0) continue;
|
|
4058
4555
|
const key = p.slice(0, idx).trim();
|
|
4059
|
-
const val =
|
|
4556
|
+
const val = unquote4(p.slice(idx + 1).trim());
|
|
4060
4557
|
out[key] = val;
|
|
4061
4558
|
}
|
|
4062
4559
|
return out;
|
|
@@ -4091,7 +4588,7 @@ function parseAnchor(tok) {
|
|
|
4091
4588
|
return { id: tok.slice(0, dot), port: tok.slice(dot + 1) };
|
|
4092
4589
|
}
|
|
4093
4590
|
function parsePid(src) {
|
|
4094
|
-
const lines =
|
|
4591
|
+
const lines = preprocess5(src);
|
|
4095
4592
|
if (lines.length === 0) {
|
|
4096
4593
|
throw new PidParseError("Empty document");
|
|
4097
4594
|
}
|
|
@@ -4105,7 +4602,7 @@ function parsePid(src) {
|
|
|
4105
4602
|
const { rest, attrs: headerAttrs } = extractAttrs(headerRest);
|
|
4106
4603
|
if (headerAttrs.direction === "TB") direction = "TB";
|
|
4107
4604
|
if (headerAttrs.direction === "LR") direction = "LR";
|
|
4108
|
-
if (rest) title2 =
|
|
4605
|
+
if (rest) title2 = unquote4(rest);
|
|
4109
4606
|
const equipment = [];
|
|
4110
4607
|
const linesAst = [];
|
|
4111
4608
|
const instruments = [];
|
|
@@ -5078,7 +5575,7 @@ function renderInstrument(category, letterCode, loopNumber) {
|
|
|
5078
5575
|
}
|
|
5079
5576
|
|
|
5080
5577
|
// src/diagrams/pid/layout.ts
|
|
5081
|
-
var
|
|
5578
|
+
var PADDING2 = 30;
|
|
5082
5579
|
var TITLE_AREA = 26;
|
|
5083
5580
|
var EQUIP_GAP_X = 70;
|
|
5084
5581
|
var INST_RADIUS = 14;
|
|
@@ -5145,8 +5642,8 @@ function layoutPid(ast) {
|
|
|
5145
5642
|
const equipById = /* @__PURE__ */ new Map();
|
|
5146
5643
|
const heights = ast.equipment.map((e) => GEOMETRY[e.equipType]?.height ?? 60);
|
|
5147
5644
|
const maxH = Math.max(...heights, 0);
|
|
5148
|
-
const rowY =
|
|
5149
|
-
let cursorX =
|
|
5645
|
+
const rowY = PADDING2 + TITLE_AREA + maxH / 2 + 30;
|
|
5646
|
+
let cursorX = PADDING2 + 40;
|
|
5150
5647
|
for (const equip of ast.equipment) {
|
|
5151
5648
|
const geo = GEOMETRY[equip.equipType] ?? { width: 60, height: 40, ports: {} };
|
|
5152
5649
|
const cx = cursorX + geo.width / 2;
|
|
@@ -5171,29 +5668,42 @@ function layoutPid(ast) {
|
|
|
5171
5668
|
equipById.set(equip.id, layoutEq);
|
|
5172
5669
|
cursorX += geo.width + EQUIP_GAP_X;
|
|
5173
5670
|
}
|
|
5671
|
+
const lineMidById = /* @__PURE__ */ new Map();
|
|
5672
|
+
for (const ln of ast.lines) {
|
|
5673
|
+
const from = equipById.get(ln.from.id);
|
|
5674
|
+
const to = equipById.get(ln.to.id);
|
|
5675
|
+
if (!from || !to) continue;
|
|
5676
|
+
const fa = getAnchor(from, ln.from.port, "out");
|
|
5677
|
+
const ta = getAnchor(to, ln.to.port, "in");
|
|
5678
|
+
lineMidById.set(ln.id, { x: (fa.x + ta.x) / 2, y: (fa.y + ta.y) / 2 });
|
|
5679
|
+
}
|
|
5680
|
+
const targetX = (tgt, fallback) => {
|
|
5681
|
+
const eq = equipById.get(tgt);
|
|
5682
|
+
if (eq) return eq.cx;
|
|
5683
|
+
const lm = lineMidById.get(tgt);
|
|
5684
|
+
if (lm) return lm.x;
|
|
5685
|
+
return fallback;
|
|
5686
|
+
};
|
|
5174
5687
|
const instruments = [];
|
|
5175
5688
|
const instById = /* @__PURE__ */ new Map();
|
|
5176
|
-
const crBandY =
|
|
5689
|
+
const crBandY = PADDING2 + TITLE_AREA + 40;
|
|
5177
5690
|
let crSlot = 0;
|
|
5178
5691
|
for (const inst of ast.instruments) {
|
|
5179
5692
|
let cx = 0;
|
|
5180
5693
|
let cy = 0;
|
|
5181
5694
|
if (inst.category.startsWith("cr_")) {
|
|
5182
5695
|
const tgt = inst.controls ?? inst.measures ?? "";
|
|
5183
|
-
|
|
5184
|
-
cx = tgtEq ? tgtEq.cx : PADDING + 80 + crSlot * (INST_RADIUS * 2 + 28);
|
|
5696
|
+
cx = targetX(tgt, PADDING2 + 80 + crSlot * (INST_RADIUS * 2 + 28));
|
|
5185
5697
|
cy = crBandY;
|
|
5186
5698
|
crSlot += 1;
|
|
5187
5699
|
} else if (inst.category.startsWith("local_")) {
|
|
5188
5700
|
cy = rowY + maxH / 2 + INST_OFFSET + INST_RADIUS;
|
|
5189
5701
|
const tgt = inst.measures ?? inst.controls ?? "";
|
|
5190
|
-
|
|
5191
|
-
cx = tgtEq ? tgtEq.cx : PADDING + 80;
|
|
5702
|
+
cx = targetX(tgt, PADDING2 + 80);
|
|
5192
5703
|
} else {
|
|
5193
5704
|
cy = rowY + maxH / 2 + INST_OFFSET;
|
|
5194
5705
|
const tgt = inst.measures ?? inst.controls ?? "";
|
|
5195
|
-
|
|
5196
|
-
cx = tgtEq ? tgtEq.cx : PADDING + 80;
|
|
5706
|
+
cx = targetX(tgt, PADDING2 + 80);
|
|
5197
5707
|
}
|
|
5198
5708
|
const lay = {
|
|
5199
5709
|
inst,
|
|
@@ -5204,13 +5714,14 @@ function layoutPid(ast) {
|
|
|
5204
5714
|
instruments.push(lay);
|
|
5205
5715
|
instById.set(inst.tag, lay);
|
|
5206
5716
|
}
|
|
5207
|
-
const
|
|
5717
|
+
const INST_FANOUT = INST_RADIUS * 2 + 12;
|
|
5718
|
+
const sameYRow = (a, b) => Math.abs(a.cy - b.cy) < INST_RADIUS;
|
|
5208
5719
|
const sortedByX = [...instruments].sort((a, b) => a.cx - b.cx);
|
|
5209
5720
|
for (let i = 1; i < sortedByX.length; i++) {
|
|
5210
5721
|
const prev = sortedByX[i - 1];
|
|
5211
5722
|
const cur = sortedByX[i];
|
|
5212
|
-
if (
|
|
5213
|
-
cur.cx = prev.cx +
|
|
5723
|
+
if (sameYRow(prev, cur) && cur.cx < prev.cx + INST_FANOUT) {
|
|
5724
|
+
cur.cx = prev.cx + INST_FANOUT;
|
|
5214
5725
|
}
|
|
5215
5726
|
}
|
|
5216
5727
|
const lines = [];
|
|
@@ -5236,8 +5747,8 @@ function layoutPid(ast) {
|
|
|
5236
5747
|
const maxX = Math.max(...allX);
|
|
5237
5748
|
const maxY = Math.max(...allY);
|
|
5238
5749
|
return {
|
|
5239
|
-
width: Math.max(maxX +
|
|
5240
|
-
height: Math.max(maxY +
|
|
5750
|
+
width: Math.max(maxX + PADDING2, 400),
|
|
5751
|
+
height: Math.max(maxY + PADDING2, 200),
|
|
5241
5752
|
equipment,
|
|
5242
5753
|
instruments,
|
|
5243
5754
|
lines,
|
|
@@ -5300,6 +5811,7 @@ var STYLE2 = `
|
|
|
5300
5811
|
.lt-inst-local-line { stroke: #1d1d1d; stroke-width: 1; stroke-dasharray: 2 2; }
|
|
5301
5812
|
.lt-pid-valve-body { fill: #ffffff; stroke: #1d1d1d; stroke-width: 1.4; }
|
|
5302
5813
|
|
|
5814
|
+
.lt-pid-line-path { fill: none; }
|
|
5303
5815
|
.lt-pid-line-tag-bg { fill: #ffffff; stroke: #1d1d1d; stroke-width: 0.6; }
|
|
5304
5816
|
.lt-pid-line-tag-text { font: 9px ui-monospace, monospace; fill: #1d1d1d; }
|
|
5305
5817
|
|
|
@@ -5310,15 +5822,37 @@ var STYLE2 = `
|
|
|
5310
5822
|
.lt-pid-unknown-type { font: 9px ui-monospace, monospace; fill: #6a6a6a; }
|
|
5311
5823
|
`;
|
|
5312
5824
|
var ARROW_ID = "lt-pid-arrow";
|
|
5825
|
+
var LINE_CLASS = {
|
|
5826
|
+
process: "lt-pid-process",
|
|
5827
|
+
process_minor: "lt-pid-process-min",
|
|
5828
|
+
pneumatic: "lt-pid-pneumatic",
|
|
5829
|
+
electric: "lt-pid-electric",
|
|
5830
|
+
hydraulic: "lt-pid-hydraulic",
|
|
5831
|
+
capillary: "lt-pid-capillary",
|
|
5832
|
+
software: "lt-pid-software",
|
|
5833
|
+
mechanical: "lt-pid-mechanical"
|
|
5834
|
+
};
|
|
5835
|
+
var SIGNAL_LINE_TYPES = /* @__PURE__ */ new Set([
|
|
5836
|
+
"pneumatic",
|
|
5837
|
+
"electric",
|
|
5838
|
+
"hydraulic",
|
|
5839
|
+
"capillary",
|
|
5840
|
+
"software",
|
|
5841
|
+
"mechanical"
|
|
5842
|
+
]);
|
|
5313
5843
|
function lineClass(t) {
|
|
5314
|
-
return `lt-pid-${t.replace(
|
|
5844
|
+
return LINE_CLASS[t] ?? `lt-pid-${String(t).replace(/_/g, "-")}`;
|
|
5845
|
+
}
|
|
5846
|
+
function isSignalLine(l) {
|
|
5847
|
+
return SIGNAL_LINE_TYPES.has(l.line.lineType);
|
|
5315
5848
|
}
|
|
5316
5849
|
function renderLine(l) {
|
|
5317
5850
|
const cls = lineClass(l.line.lineType);
|
|
5318
5851
|
const parts = [
|
|
5319
5852
|
chunk3WNW5Y7P_cjs.path({
|
|
5320
5853
|
d: l.path,
|
|
5321
|
-
class
|
|
5854
|
+
// Type class + a shared no-fill guard class on every line path.
|
|
5855
|
+
class: `${cls} lt-pid-line-path`,
|
|
5322
5856
|
"data-line-id": l.line.id,
|
|
5323
5857
|
"data-service": l.line.service ?? ""
|
|
5324
5858
|
})
|
|
@@ -5485,9 +6019,16 @@ function renderLayout2(layout) {
|
|
|
5485
6019
|
chunk3WNW5Y7P_cjs.el("style", {}, STYLE2)
|
|
5486
6020
|
]),
|
|
5487
6021
|
titleNode,
|
|
6022
|
+
// Z-order: process pipes behind equipment; signal lines + instruments above.
|
|
6023
|
+
chunk3WNW5Y7P_cjs.group(
|
|
6024
|
+
{ class: "lt-pid-lines lt-pid-process-lines" },
|
|
6025
|
+
layout.lines.filter((l) => !isSignalLine(l)).map(renderLine)
|
|
6026
|
+
),
|
|
5488
6027
|
chunk3WNW5Y7P_cjs.group({ class: "lt-pid-equipment" }, equipNodes),
|
|
5489
|
-
chunk3WNW5Y7P_cjs.group(
|
|
5490
|
-
|
|
6028
|
+
chunk3WNW5Y7P_cjs.group(
|
|
6029
|
+
{ class: "lt-pid-lines lt-pid-signal-lines" },
|
|
6030
|
+
[...layout.lines.filter(isSignalLine).map(renderLine), ...autoSignals]
|
|
6031
|
+
),
|
|
5491
6032
|
chunk3WNW5Y7P_cjs.group({ class: "lt-pid-instruments" }, instNodes)
|
|
5492
6033
|
]
|
|
5493
6034
|
);
|
|
@@ -5638,7 +6179,7 @@ var PrismaParseError = class extends Error {
|
|
|
5638
6179
|
}
|
|
5639
6180
|
line;
|
|
5640
6181
|
};
|
|
5641
|
-
function
|
|
6182
|
+
function preprocess6(src) {
|
|
5642
6183
|
const out = [];
|
|
5643
6184
|
const rows = src.split(/\r?\n/);
|
|
5644
6185
|
for (let i = 0; i < rows.length; i++) {
|
|
@@ -5911,7 +6452,7 @@ var STAGE_KEYS = /* @__PURE__ */ new Set([
|
|
|
5911
6452
|
"included"
|
|
5912
6453
|
]);
|
|
5913
6454
|
function parsePrisma(src) {
|
|
5914
|
-
const lines =
|
|
6455
|
+
const lines = preprocess6(src);
|
|
5915
6456
|
if (lines.length === 0) throw new PrismaParseError("empty input");
|
|
5916
6457
|
const header = lines.shift();
|
|
5917
6458
|
if (header.indent !== 0 || header.text.toLowerCase() !== "prisma") {
|
|
@@ -5939,10 +6480,10 @@ function parsePrisma(src) {
|
|
|
5939
6480
|
validateCounts = parseValidate(value, l.line);
|
|
5940
6481
|
break;
|
|
5941
6482
|
case "title":
|
|
5942
|
-
title2 =
|
|
6483
|
+
title2 = unquote5(value);
|
|
5943
6484
|
break;
|
|
5944
6485
|
case "review-id":
|
|
5945
|
-
reviewId =
|
|
6486
|
+
reviewId = unquote5(value);
|
|
5946
6487
|
break;
|
|
5947
6488
|
case "direction":
|
|
5948
6489
|
if (!/^(TB|TD)$/i.test(value.trim())) {
|
|
@@ -6030,7 +6571,7 @@ function parsePrisma(src) {
|
|
|
6030
6571
|
runArithmeticValidation(ast);
|
|
6031
6572
|
return ast;
|
|
6032
6573
|
}
|
|
6033
|
-
function
|
|
6574
|
+
function unquote5(s) {
|
|
6034
6575
|
const t = s.trim();
|
|
6035
6576
|
if (t.startsWith('"') && t.endsWith('"')) return t.slice(1, -1);
|
|
6036
6577
|
return t;
|
|
@@ -6844,7 +7385,7 @@ function headerHeightFor(lineCount) {
|
|
|
6844
7385
|
}
|
|
6845
7386
|
|
|
6846
7387
|
// src/diagrams/prisma/renderer.ts
|
|
6847
|
-
function
|
|
7388
|
+
function buildCss3(t) {
|
|
6848
7389
|
return `
|
|
6849
7390
|
.prisma { font-family: system-ui, -apple-system, sans-serif; }
|
|
6850
7391
|
.prisma-title { font: 600 17px sans-serif; fill: ${t.text}; }
|
|
@@ -7074,7 +7615,7 @@ function renderPrismaLayout(layout, config) {
|
|
|
7074
7615
|
`PRISMA 2020 flow diagram (${layout.mode}, ${layout.kind}) \u2014 ${layout.boxes.length} boxes, ${layout.edges.length} arrows` + (layout.warnings.length > 0 ? `. Warnings: ${layout.warnings.join("; ")}` : "")
|
|
7075
7616
|
)
|
|
7076
7617
|
);
|
|
7077
|
-
children.push(chunk3WNW5Y7P_cjs.el("style", {},
|
|
7618
|
+
children.push(chunk3WNW5Y7P_cjs.el("style", {}, buildCss3(t)));
|
|
7078
7619
|
children.push(arrowMarker(t));
|
|
7079
7620
|
if (layout.title) {
|
|
7080
7621
|
children.push(
|
|
@@ -7166,7 +7707,7 @@ var UsecaseParseError = class extends Error {
|
|
|
7166
7707
|
if (line2 !== void 0) this.line = line2;
|
|
7167
7708
|
}
|
|
7168
7709
|
};
|
|
7169
|
-
function
|
|
7710
|
+
function preprocess7(src) {
|
|
7170
7711
|
const out = [];
|
|
7171
7712
|
const rows = src.split(/\r?\n/);
|
|
7172
7713
|
for (let i = 0; i < rows.length; i++) {
|
|
@@ -7649,7 +8190,7 @@ function parseUsecase(src) {
|
|
|
7649
8190
|
const state2 = {
|
|
7650
8191
|
ast,
|
|
7651
8192
|
idTable: /* @__PURE__ */ new Map(),
|
|
7652
|
-
lines:
|
|
8193
|
+
lines: preprocess7(src),
|
|
7653
8194
|
i: 0
|
|
7654
8195
|
};
|
|
7655
8196
|
parseHeader(state2);
|
|
@@ -8097,10 +8638,10 @@ function layoutUsecase(ast) {
|
|
|
8097
8638
|
const maxY2 = Math.max(...ys);
|
|
8098
8639
|
if (useTree) {
|
|
8099
8640
|
const legPaths2 = [
|
|
8100
|
-
`M ${
|
|
8641
|
+
`M ${round3(busX)} ${round3(minY2)} L ${round3(busX)} ${round3(maxY2)}`
|
|
8101
8642
|
];
|
|
8102
8643
|
for (const c of childAnchors) {
|
|
8103
|
-
legPaths2.push(`M ${
|
|
8644
|
+
legPaths2.push(`M ${round3(c.p.x)} ${round3(c.p.y)} L ${round3(busX)} ${round3(c.p.y)}`);
|
|
8104
8645
|
handledGen.add(c.r);
|
|
8105
8646
|
}
|
|
8106
8647
|
trees.push({
|
|
@@ -8109,14 +8650,14 @@ function layoutUsecase(ast) {
|
|
|
8109
8650
|
stemX: busX,
|
|
8110
8651
|
stemTop: minY2,
|
|
8111
8652
|
stemBottom: maxY2,
|
|
8112
|
-
trunkD: `M ${
|
|
8653
|
+
trunkD: `M ${round3(busX)} ${round3(pAnchor.y)} L ${round3(pAnchor.x)} ${round3(pAnchor.y)}`,
|
|
8113
8654
|
legPaths: legPaths2
|
|
8114
8655
|
});
|
|
8115
8656
|
} else {
|
|
8116
8657
|
for (const c of childAnchors) {
|
|
8117
8658
|
edges.push({
|
|
8118
8659
|
relation: c.r,
|
|
8119
|
-
d: `M ${
|
|
8660
|
+
d: `M ${round3(c.p.x)} ${round3(c.p.y)} L ${round3(busX)} ${round3(c.p.y)} L ${round3(busX)} ${round3(pAnchor.y)} L ${round3(pAnchor.x)} ${round3(pAnchor.y)}`,
|
|
8120
8661
|
arrowKind: "hollow",
|
|
8121
8662
|
dashed: false
|
|
8122
8663
|
});
|
|
@@ -8141,7 +8682,7 @@ function layoutUsecase(ast) {
|
|
|
8141
8682
|
const legPaths = [];
|
|
8142
8683
|
for (const r5 of rels) {
|
|
8143
8684
|
const cPt = perimeter(r5.source, jx, jy);
|
|
8144
|
-
legPaths.push(`M ${
|
|
8685
|
+
legPaths.push(`M ${round3(cPt.x)} ${round3(cPt.y)} L ${round3(jx)} ${round3(jy)}`);
|
|
8145
8686
|
handledGen.add(r5);
|
|
8146
8687
|
}
|
|
8147
8688
|
trees.push({
|
|
@@ -8150,7 +8691,7 @@ function layoutUsecase(ast) {
|
|
|
8150
8691
|
stemX: jx,
|
|
8151
8692
|
stemTop: jy,
|
|
8152
8693
|
stemBottom: jy,
|
|
8153
|
-
trunkD: `M ${
|
|
8694
|
+
trunkD: `M ${round3(jx)} ${round3(jy)} L ${round3(pPt.x)} ${round3(pPt.y)}`,
|
|
8154
8695
|
legPaths
|
|
8155
8696
|
});
|
|
8156
8697
|
}
|
|
@@ -8166,7 +8707,7 @@ function layoutUsecase(ast) {
|
|
|
8166
8707
|
const busX = side === "left" ? Math.min(pAnchor.x, cAnchor.x) - 20 : Math.max(pAnchor.x, cAnchor.x) + 20;
|
|
8167
8708
|
edges.push({
|
|
8168
8709
|
relation: r5,
|
|
8169
|
-
d: `M ${
|
|
8710
|
+
d: `M ${round3(cAnchor.x)} ${round3(cAnchor.y)} L ${round3(busX)} ${round3(cAnchor.y)} L ${round3(busX)} ${round3(pAnchor.y)} L ${round3(pAnchor.x)} ${round3(pAnchor.y)}`,
|
|
8170
8711
|
arrowKind: "hollow",
|
|
8171
8712
|
dashed: false
|
|
8172
8713
|
});
|
|
@@ -8192,7 +8733,7 @@ function layoutUsecase(ast) {
|
|
|
8192
8733
|
else if (r5.kind === "generalization") arrowKind2 = "hollow";
|
|
8193
8734
|
const edge = {
|
|
8194
8735
|
relation: r5,
|
|
8195
|
-
d: `M ${
|
|
8736
|
+
d: `M ${round3(pa.x)} ${round3(pa.y)} L ${round3(pb.x)} ${round3(pb.y)}`,
|
|
8196
8737
|
arrowKind: arrowKind2,
|
|
8197
8738
|
dashed
|
|
8198
8739
|
};
|
|
@@ -8261,14 +8802,14 @@ function placeMultiplicity(near, far, text2) {
|
|
|
8261
8802
|
const oy = dy / len * 14;
|
|
8262
8803
|
const px = -dy / len * 9;
|
|
8263
8804
|
const py = dx / len * 9;
|
|
8264
|
-
return { text: text2, x:
|
|
8805
|
+
return { text: text2, x: round3(near.x + ox + px), y: round3(near.y + oy + py) };
|
|
8265
8806
|
}
|
|
8266
|
-
function
|
|
8807
|
+
function round3(n) {
|
|
8267
8808
|
return Math.round(n * 100) / 100;
|
|
8268
8809
|
}
|
|
8269
8810
|
|
|
8270
8811
|
// src/diagrams/usecase/renderer.ts
|
|
8271
|
-
function
|
|
8812
|
+
function buildCss4(t) {
|
|
8272
8813
|
const ucFill = "#eaf2fc";
|
|
8273
8814
|
const ucStroke = "#5b85c0";
|
|
8274
8815
|
const subjectStroke = "#c2cede";
|
|
@@ -8547,7 +9088,7 @@ function renderUsecaseLayout(layout, config) {
|
|
|
8547
9088
|
`${layout.subject ? "Subject: " + layout.subject.name + ". " : ""}${layout.actors.length} actors, ${layout.usecases.length} use cases, ${nInclude} include, ${nExtend} extend.`
|
|
8548
9089
|
)
|
|
8549
9090
|
);
|
|
8550
|
-
children.push(chunk3WNW5Y7P_cjs.el("style", {},
|
|
9091
|
+
children.push(chunk3WNW5Y7P_cjs.el("style", {}, buildCss4(t)));
|
|
8551
9092
|
children.push(markers(t));
|
|
8552
9093
|
if (layout.title) {
|
|
8553
9094
|
children.push(
|
|
@@ -8644,7 +9185,7 @@ var UNIT_SUFFIX = {
|
|
|
8644
9185
|
function normalizeQuotes(s) {
|
|
8645
9186
|
return s.replace(/[“”〝〞"]/g, '"').replace(/[‘’]/g, "'").replace(/[「」『』]/g, '"');
|
|
8646
9187
|
}
|
|
8647
|
-
function
|
|
9188
|
+
function preprocess8(src) {
|
|
8648
9189
|
const out = [];
|
|
8649
9190
|
const rows = normalizeQuotes(src).split(/\r?\n/);
|
|
8650
9191
|
for (let i = 0; i < rows.length; i++) {
|
|
@@ -8894,7 +9435,7 @@ function parsePert(src) {
|
|
|
8894
9435
|
tasks: [],
|
|
8895
9436
|
warnings: []
|
|
8896
9437
|
};
|
|
8897
|
-
const lines =
|
|
9438
|
+
const lines = preprocess8(src);
|
|
8898
9439
|
if (lines.length === 0) {
|
|
8899
9440
|
throw new PertParseError("empty document \u2014 expected 'pert' header", 1);
|
|
8900
9441
|
}
|
|
@@ -9094,13 +9635,13 @@ function schedulePert(ast) {
|
|
|
9094
9635
|
const realOrder = order.filter((n) => n !== START && n !== FINISH);
|
|
9095
9636
|
let negativeSlack = false;
|
|
9096
9637
|
for (const id of realOrder) {
|
|
9097
|
-
const slack =
|
|
9638
|
+
const slack = round4(ls.get(id) - es.get(id));
|
|
9098
9639
|
if (slack < -1e-9) negativeSlack = true;
|
|
9099
9640
|
computed.set(id, {
|
|
9100
|
-
es:
|
|
9101
|
-
ef:
|
|
9102
|
-
ls:
|
|
9103
|
-
lf:
|
|
9641
|
+
es: round4(es.get(id)),
|
|
9642
|
+
ef: round4(ef.get(id)),
|
|
9643
|
+
ls: round4(ls.get(id)),
|
|
9644
|
+
lf: round4(lf.get(id)),
|
|
9104
9645
|
slack,
|
|
9105
9646
|
critical: slack <= tol + 1e-9
|
|
9106
9647
|
});
|
|
@@ -9115,8 +9656,8 @@ function schedulePert(ast) {
|
|
|
9115
9656
|
for (const t of ast.tasks) {
|
|
9116
9657
|
if (t.variance !== void 0 && computed.get(t.id).critical) sum += t.variance;
|
|
9117
9658
|
}
|
|
9118
|
-
projectVariance =
|
|
9119
|
-
projectStdDev =
|
|
9659
|
+
projectVariance = round4(sum);
|
|
9660
|
+
projectStdDev = round4(Math.sqrt(sum));
|
|
9120
9661
|
}
|
|
9121
9662
|
const depCount = ast.tasks.reduce((n, t) => n + t.deps.length, 0);
|
|
9122
9663
|
if (negativeSlack) {
|
|
@@ -9127,7 +9668,7 @@ function schedulePert(ast) {
|
|
|
9127
9668
|
const result = {
|
|
9128
9669
|
computed,
|
|
9129
9670
|
order: realOrder,
|
|
9130
|
-
projectDuration:
|
|
9671
|
+
projectDuration: round4(projectDuration),
|
|
9131
9672
|
criticalPath,
|
|
9132
9673
|
criticalCount,
|
|
9133
9674
|
depCount
|
|
@@ -9169,7 +9710,7 @@ function extractCriticalPath(ast, g, computed) {
|
|
|
9169
9710
|
}
|
|
9170
9711
|
return path2;
|
|
9171
9712
|
}
|
|
9172
|
-
function
|
|
9713
|
+
function round4(n) {
|
|
9173
9714
|
return Math.round(n * 1e4) / 1e4;
|
|
9174
9715
|
}
|
|
9175
9716
|
|
|
@@ -9320,8 +9861,8 @@ function layoutAoa(ast, schedule) {
|
|
|
9320
9861
|
x: cx[e],
|
|
9321
9862
|
y: cy[e],
|
|
9322
9863
|
r: AOA.R,
|
|
9323
|
-
te:
|
|
9324
|
-
tl:
|
|
9864
|
+
te: round5(te[e]),
|
|
9865
|
+
tl: round5(tl[e]),
|
|
9325
9866
|
critical: eventCritical(e)
|
|
9326
9867
|
}));
|
|
9327
9868
|
const outArcs = arcs.map((a) => {
|
|
@@ -9380,7 +9921,7 @@ function arcGeometry(tx, ty, hx, hy, r5) {
|
|
|
9380
9921
|
const sy = ty + uy * r5;
|
|
9381
9922
|
const ex = hx - ux * r5;
|
|
9382
9923
|
const ey = hy - uy * r5;
|
|
9383
|
-
return { d: `M ${
|
|
9924
|
+
return { d: `M ${round5(sx)} ${round5(sy)} L ${round5(ex)} ${round5(ey)}`, mx: (sx + ex) / 2, my: (sy + ey) / 2 };
|
|
9384
9925
|
}
|
|
9385
9926
|
function buildAoaSummary(ast, sched) {
|
|
9386
9927
|
const summary = {
|
|
@@ -9394,7 +9935,7 @@ function buildAoaSummary(ast, sched) {
|
|
|
9394
9935
|
if (sched.projectStdDev !== void 0) summary.projectStdDev = sched.projectStdDev;
|
|
9395
9936
|
return summary;
|
|
9396
9937
|
}
|
|
9397
|
-
function
|
|
9938
|
+
function round5(n) {
|
|
9398
9939
|
return Math.round(n * 1e3) / 1e3;
|
|
9399
9940
|
}
|
|
9400
9941
|
|
|
@@ -10011,7 +10552,7 @@ var PALETTE = {
|
|
|
10011
10552
|
axisBaseline: "#8497ad",
|
|
10012
10553
|
grid: "#e3eaf3"
|
|
10013
10554
|
};
|
|
10014
|
-
function
|
|
10555
|
+
function buildCss5(t) {
|
|
10015
10556
|
const P = PALETTE;
|
|
10016
10557
|
return `
|
|
10017
10558
|
.sx-pert { font-family: system-ui, -apple-system, sans-serif; }
|
|
@@ -10335,7 +10876,7 @@ function renderPertLayout(layout, config) {
|
|
|
10335
10876
|
`${layout.summary.taskCount} activities, project duration ${fmtVal(layout.summary.projectDuration)} ${unitWord(layout.unit)}` + (cp.length ? `, critical path ${cp.join(" \u2192 ")}` : "") + "."
|
|
10336
10877
|
)
|
|
10337
10878
|
);
|
|
10338
|
-
children.push(chunk3WNW5Y7P_cjs.el("style", {},
|
|
10879
|
+
children.push(chunk3WNW5Y7P_cjs.el("style", {}, buildCss5(t)));
|
|
10339
10880
|
children.push(markers2());
|
|
10340
10881
|
if (layout.title) {
|
|
10341
10882
|
children.push(
|
|
@@ -11250,7 +11791,7 @@ function layoutSequence(ast) {
|
|
|
11250
11791
|
// src/diagrams/sequence/renderer.ts
|
|
11251
11792
|
var HEAD = "#e8f0fb";
|
|
11252
11793
|
var HEAD_STROKE = "#5b85c0";
|
|
11253
|
-
function
|
|
11794
|
+
function buildCss6(t) {
|
|
11254
11795
|
return `
|
|
11255
11796
|
.sx-seq { font-family: system-ui, -apple-system, sans-serif; }
|
|
11256
11797
|
.sx-seq-axis { stroke: ${t.neutral}; stroke-width: 1; stroke-dasharray: 4 4; }
|
|
@@ -11545,7 +12086,7 @@ function renderSequenceLayout(layout, config) {
|
|
|
11545
12086
|
`${layout.lifelines.length} participants, ${nMsg} messages, ${nFrag} combined fragments.`
|
|
11546
12087
|
)
|
|
11547
12088
|
);
|
|
11548
|
-
children.push(chunk3WNW5Y7P_cjs.el("style", {},
|
|
12089
|
+
children.push(chunk3WNW5Y7P_cjs.el("style", {}, buildCss6(t)));
|
|
11549
12090
|
children.push(markers3(t));
|
|
11550
12091
|
const titleBand = layout.title ? 32 : 0;
|
|
11551
12092
|
if (layout.title) {
|
|
@@ -11616,7 +12157,7 @@ var PetriParseError = class extends Error {
|
|
|
11616
12157
|
};
|
|
11617
12158
|
var OPENERS = ['"', "\u201C", "\u300C", "\u300E", "\xAB"];
|
|
11618
12159
|
var CLOSERS = ['"', "\u201D", "\u300D", "\u300F", "\xBB"];
|
|
11619
|
-
function
|
|
12160
|
+
function tokenize4(s) {
|
|
11620
12161
|
const out = [];
|
|
11621
12162
|
let i = 0;
|
|
11622
12163
|
while (i < s.length) {
|
|
@@ -11683,7 +12224,7 @@ function parsePetri(text2) {
|
|
|
11683
12224
|
if (trimmed.startsWith("#") || trimmed.startsWith("//")) continue;
|
|
11684
12225
|
if (!sawHeader && /^petri(net)?\b/i.test(trimmed)) {
|
|
11685
12226
|
sawHeader = true;
|
|
11686
|
-
const toks =
|
|
12227
|
+
const toks = tokenize4(trimmed);
|
|
11687
12228
|
const titleTok = toks.find((t, idx) => idx > 0 && t.quoted);
|
|
11688
12229
|
if (titleTok) ast.title = titleTok.text;
|
|
11689
12230
|
else if (toks[1] && !toks[1].quoted) ast.title = toks.slice(1).map((t) => t.text).join(" ");
|
|
@@ -11745,7 +12286,7 @@ function declareDup(id, lineNo, placeIds, transIds) {
|
|
|
11745
12286
|
}
|
|
11746
12287
|
}
|
|
11747
12288
|
function parsePlace(line2, lineNo, placeIds, transIds) {
|
|
11748
|
-
const toks =
|
|
12289
|
+
const toks = tokenize4(normalizeKeyNums(line2));
|
|
11749
12290
|
const idTok = toks[1];
|
|
11750
12291
|
if (!idTok || idTok.quoted) throw new PetriParseError(`place is missing an id`, lineNo);
|
|
11751
12292
|
const id = idTok.text;
|
|
@@ -11784,7 +12325,7 @@ function parseTransition(line2, lineNo, placeIds, transIds) {
|
|
|
11784
12325
|
guard = String(g).trim();
|
|
11785
12326
|
return " ";
|
|
11786
12327
|
});
|
|
11787
|
-
const toks =
|
|
12328
|
+
const toks = tokenize4(normalizeKeyNums(stripped));
|
|
11788
12329
|
const idTok = toks[1];
|
|
11789
12330
|
if (!idTok || idTok.quoted) throw new PetriParseError(`transition is missing an id`, lineNo);
|
|
11790
12331
|
const id = idTok.text;
|
|
@@ -11842,7 +12383,7 @@ function parseArc(m, lineNo, placeIds, transIds) {
|
|
|
11842
12383
|
throw new PetriParseError(`${type} arcs are place\u2192transition only`, lineNo);
|
|
11843
12384
|
}
|
|
11844
12385
|
const arc = { from, to, type, weight: 1, line: lineNo };
|
|
11845
|
-
const toks =
|
|
12386
|
+
const toks = tokenize4(normalizeKeyNums(rest));
|
|
11846
12387
|
const labelParts = [];
|
|
11847
12388
|
for (const t of toks) {
|
|
11848
12389
|
if (t.quoted) {
|
|
@@ -11979,7 +12520,7 @@ function layoutPetri(ast) {
|
|
|
11979
12520
|
reindex();
|
|
11980
12521
|
}
|
|
11981
12522
|
}
|
|
11982
|
-
const
|
|
12523
|
+
const sizeOf3 = (id) => {
|
|
11983
12524
|
if (kindOf.get(id) === "place") return { halfW: C2.PLACE_R, halfH: C2.PLACE_R, r: C2.PLACE_R };
|
|
11984
12525
|
const tr = ast.transitions.find((t) => t.id === id);
|
|
11985
12526
|
const long = tr.kind === "timed" ? C2.TRANS_BOX_H : C2.TRANS_BAR_H;
|
|
@@ -11989,11 +12530,11 @@ function layoutPetri(ast) {
|
|
|
11989
12530
|
return { halfW, halfH, r: 0 };
|
|
11990
12531
|
};
|
|
11991
12532
|
const flowHalf = (id) => {
|
|
11992
|
-
const s =
|
|
12533
|
+
const s = sizeOf3(id);
|
|
11993
12534
|
return dir === "lr" ? s.halfW : s.halfH;
|
|
11994
12535
|
};
|
|
11995
12536
|
const crossHalf = (id) => {
|
|
11996
|
-
const s =
|
|
12537
|
+
const s = sizeOf3(id);
|
|
11997
12538
|
return dir === "lr" ? s.halfH : s.halfW;
|
|
11998
12539
|
};
|
|
11999
12540
|
const layerHalf = layers.map((arr) => Math.max(0, ...arr.map(flowHalf)));
|
|
@@ -12016,7 +12557,7 @@ function layoutPetri(ast) {
|
|
|
12016
12557
|
const flow = flowCenter[L];
|
|
12017
12558
|
const cx = dir === "lr" ? flow : cross;
|
|
12018
12559
|
const cy = dir === "lr" ? cross : flow;
|
|
12019
|
-
const s =
|
|
12560
|
+
const s = sizeOf3(id);
|
|
12020
12561
|
geom.set(id, { id, kind: kindOf.get(id), cx, cy, halfW: s.halfW, halfH: s.halfH, r: s.r, layer: L });
|
|
12021
12562
|
});
|
|
12022
12563
|
});
|
|
@@ -12210,7 +12751,7 @@ function detectSubclass(ast) {
|
|
|
12210
12751
|
}
|
|
12211
12752
|
|
|
12212
12753
|
// src/diagrams/petri/renderer.ts
|
|
12213
|
-
function
|
|
12754
|
+
function buildCss7(t) {
|
|
12214
12755
|
return `
|
|
12215
12756
|
.sx-petri { font-family: system-ui, -apple-system, sans-serif; }
|
|
12216
12757
|
.sx-petri-place { fill: ${t.placeFill}; stroke: ${t.placeStroke}; stroke-width: 2; }
|
|
@@ -12354,7 +12895,7 @@ function arcPath(ag) {
|
|
|
12354
12895
|
}
|
|
12355
12896
|
return `M ${p[0].x} ${p[0].y} L ${p[p.length - 1].x} ${p[p.length - 1].y}`;
|
|
12356
12897
|
}
|
|
12357
|
-
function
|
|
12898
|
+
function renderArc2(ag) {
|
|
12358
12899
|
const parts = [];
|
|
12359
12900
|
let cls = "sx-petri-arc";
|
|
12360
12901
|
let markerEnd;
|
|
@@ -12401,14 +12942,14 @@ function renderPetriLayout(layout, config) {
|
|
|
12401
12942
|
].filter(Boolean);
|
|
12402
12943
|
children.push(chunk3WNW5Y7P_cjs.title(`Petri net${layout.title ? " \u2014 " + layout.title : ""}`));
|
|
12403
12944
|
children.push(chunk3WNW5Y7P_cjs.desc(descParts.join(" ")));
|
|
12404
|
-
children.push(chunk3WNW5Y7P_cjs.el("style", {},
|
|
12945
|
+
children.push(chunk3WNW5Y7P_cjs.el("style", {}, buildCss7(t)));
|
|
12405
12946
|
children.push(markers4(t));
|
|
12406
12947
|
const titleBand = layout.title ? 32 : 0;
|
|
12407
12948
|
if (layout.title) {
|
|
12408
12949
|
children.push(chunk3WNW5Y7P_cjs.text({ x: layout.width / 2, y: 22, class: "sx-petri-title", "text-anchor": "middle" }, layout.title));
|
|
12409
12950
|
}
|
|
12410
12951
|
const body = [];
|
|
12411
|
-
body.push(chunk3WNW5Y7P_cjs.group({ class: "sx-petri-arcs" }, layout.arcs.map(
|
|
12952
|
+
body.push(chunk3WNW5Y7P_cjs.group({ class: "sx-petri-arcs" }, layout.arcs.map(renderArc2)));
|
|
12412
12953
|
body.push(chunk3WNW5Y7P_cjs.group({ class: "sx-petri-places" }, layout.places.map((p) => renderPlace(p, layout.ast.tokenStyle))));
|
|
12413
12954
|
body.push(chunk3WNW5Y7P_cjs.group({ class: "sx-petri-transitions" }, layout.transitions.map(renderTransition)));
|
|
12414
12955
|
children.push(titleBand ? chunk3WNW5Y7P_cjs.group({ transform: `translate(0, ${titleBand})` }, body) : chunk3WNW5Y7P_cjs.group({}, body));
|
|
@@ -12581,7 +13122,7 @@ function splitStatements(line2) {
|
|
|
12581
13122
|
out.push(buf);
|
|
12582
13123
|
return out;
|
|
12583
13124
|
}
|
|
12584
|
-
function
|
|
13125
|
+
function tokenize5(raw) {
|
|
12585
13126
|
const line2 = stripComment2(raw);
|
|
12586
13127
|
const strings = [];
|
|
12587
13128
|
const masked = line2.replace(QUOTE_RE, (...m) => {
|
|
@@ -12736,7 +13277,7 @@ function parseNetwork(text2) {
|
|
|
12736
13277
|
});
|
|
12737
13278
|
for (const stmt of statements) {
|
|
12738
13279
|
const lineNo = stmt.no;
|
|
12739
|
-
const toks =
|
|
13280
|
+
const toks = tokenize5(stmt.text);
|
|
12740
13281
|
if (toks.length === 0) continue;
|
|
12741
13282
|
const t0 = toks[0];
|
|
12742
13283
|
if (!headerSeen) {
|
|
@@ -13722,7 +14263,7 @@ function layoutNetwork2(ast) {
|
|
|
13722
14263
|
|
|
13723
14264
|
// src/diagrams/network/renderer.ts
|
|
13724
14265
|
var r22 = (n) => Math.round(n * 100) / 100;
|
|
13725
|
-
function
|
|
14266
|
+
function buildCss8(t) {
|
|
13726
14267
|
return `
|
|
13727
14268
|
.sx-net { font-family: system-ui, -apple-system, sans-serif; }
|
|
13728
14269
|
.sx-net-body { fill: ${t.deviceFill}; stroke: ${t.deviceStroke}; stroke-width: 2; }
|
|
@@ -13782,7 +14323,7 @@ function annotation(link) {
|
|
|
13782
14323
|
if (link.label) parts.push(link.label);
|
|
13783
14324
|
return parts.join(" \xB7 ");
|
|
13784
14325
|
}
|
|
13785
|
-
function
|
|
14326
|
+
function arrowHead2(x1, y1, x2, y2, color, hs = 6) {
|
|
13786
14327
|
const ang = Math.atan2(y2 - y1, x2 - x1);
|
|
13787
14328
|
const a1 = ang + Math.PI - 0.45;
|
|
13788
14329
|
const a2 = ang + Math.PI + 0.45;
|
|
@@ -13807,7 +14348,7 @@ function renderLink(lg, t) {
|
|
|
13807
14348
|
} else {
|
|
13808
14349
|
parts.push(chunk3WNW5Y7P_cjs.el("polyline", { class: cls, stroke: color, points: lg.points.map((p) => `${r22(p.x)},${r22(p.y)}`).join(" ") }));
|
|
13809
14350
|
}
|
|
13810
|
-
if (link.directed) parts.push(
|
|
14351
|
+
if (link.directed) parts.push(arrowHead2(p1.x, p1.y, p2.x, p2.y, color));
|
|
13811
14352
|
if (link.linkType === "fiber") {
|
|
13812
14353
|
const ang = Math.atan2(p2.y - p1.y, p2.x - p1.x) + Math.PI / 2;
|
|
13813
14354
|
for (const f of [0.4, 0.55]) {
|
|
@@ -13881,7 +14422,7 @@ function renderNetworkLayout(layout, config) {
|
|
|
13881
14422
|
].filter(Boolean);
|
|
13882
14423
|
children.push(chunk3WNW5Y7P_cjs.title(`Network diagram${layout.title ? " \u2014 " + layout.title : ""}`));
|
|
13883
14424
|
children.push(chunk3WNW5Y7P_cjs.desc(descParts.join(" ")));
|
|
13884
|
-
children.push(chunk3WNW5Y7P_cjs.el("style", {},
|
|
14425
|
+
children.push(chunk3WNW5Y7P_cjs.el("style", {}, buildCss8(t)));
|
|
13885
14426
|
const titleBand = layout.title ? 30 : 0;
|
|
13886
14427
|
if (layout.title) {
|
|
13887
14428
|
children.push(chunk3WNW5Y7P_cjs.text({ x: r22(layout.width / 2), y: 21, class: "sx-net-title", "text-anchor": "middle" }, layout.title));
|
|
@@ -15520,10 +16061,10 @@ function buildTree2(kind, parent, children, vertical) {
|
|
|
15520
16061
|
const avgChildX = childXs.reduce((a, b) => a + b, 0) / childXs.length;
|
|
15521
16062
|
const trunkX = Math.max(parent.x + 10, Math.min(parent.x + parent.width - 10, avgChildX));
|
|
15522
16063
|
const trunkBaseY = parentBottom + UMLCLASS_CONST.TRIANGLE_H;
|
|
15523
|
-
const trunkD2 = `M ${
|
|
16064
|
+
const trunkD2 = `M ${round6(trunkX)} ${round6(junctionY)} L ${round6(trunkX)} ${round6(trunkBaseY)}`;
|
|
15524
16065
|
const legPaths2 = children.map((c) => {
|
|
15525
16066
|
const cx = c.box.x + c.box.width / 2;
|
|
15526
|
-
return `M ${
|
|
16067
|
+
return `M ${round6(cx)} ${round6(c.box.y)} L ${round6(cx)} ${round6(junctionY)} L ${round6(trunkX)} ${round6(junctionY)}`;
|
|
15527
16068
|
});
|
|
15528
16069
|
return {
|
|
15529
16070
|
parentId: parent.classifier.id,
|
|
@@ -15543,10 +16084,10 @@ function buildTree2(kind, parent, children, vertical) {
|
|
|
15543
16084
|
const avgChildY = childYs.reduce((a, b) => a + b, 0) / childYs.length;
|
|
15544
16085
|
const trunkY = Math.max(parent.y + 10, Math.min(parent.y + parent.height - 10, avgChildY));
|
|
15545
16086
|
const trunkBaseX = parentRight + UMLCLASS_CONST.TRIANGLE_H;
|
|
15546
|
-
const trunkD = `M ${
|
|
16087
|
+
const trunkD = `M ${round6(junctionX)} ${round6(trunkY)} L ${round6(trunkBaseX)} ${round6(trunkY)}`;
|
|
15547
16088
|
const legPaths = children.map((c) => {
|
|
15548
16089
|
const cy = c.box.y + c.box.height / 2;
|
|
15549
|
-
return `M ${
|
|
16090
|
+
return `M ${round6(c.box.x)} ${round6(cy)} L ${round6(junctionX)} ${round6(cy)} L ${round6(junctionX)} ${round6(trunkY)}`;
|
|
15550
16091
|
});
|
|
15551
16092
|
return {
|
|
15552
16093
|
parentId: parent.classifier.id,
|
|
@@ -15609,7 +16150,7 @@ function adornmentBase(end, outset) {
|
|
|
15609
16150
|
}
|
|
15610
16151
|
}
|
|
15611
16152
|
function polyline(pts) {
|
|
15612
|
-
return pts.map((p, i) => `${i === 0 ? "M" : "L"} ${
|
|
16153
|
+
return pts.map((p, i) => `${i === 0 ? "M" : "L"} ${round6(p.x)} ${round6(p.y)}`).join(" ");
|
|
15613
16154
|
}
|
|
15614
16155
|
function midOf(pts) {
|
|
15615
16156
|
if (pts.length === 0) return { x: 0, y: 0 };
|
|
@@ -15617,7 +16158,7 @@ function midOf(pts) {
|
|
|
15617
16158
|
const a = pts[i], b = pts[i + 1] ?? pts[i];
|
|
15618
16159
|
return { x: (a.x + b.x) / 2, y: (a.y + b.y) / 2 };
|
|
15619
16160
|
}
|
|
15620
|
-
function
|
|
16161
|
+
function round6(n) {
|
|
15621
16162
|
return Math.round(n * 10) / 10;
|
|
15622
16163
|
}
|
|
15623
16164
|
|
|
@@ -18206,6 +18747,24 @@ function splitWordsWithTrailingSpace(s) {
|
|
|
18206
18747
|
return out.length > 0 ? out : [s];
|
|
18207
18748
|
}
|
|
18208
18749
|
|
|
18750
|
+
// src/diagrams/mindmap/modes.ts
|
|
18751
|
+
var EXTENDED_MODES = [
|
|
18752
|
+
"futureswheel",
|
|
18753
|
+
"driver"
|
|
18754
|
+
];
|
|
18755
|
+
function baseStyleFor(mode) {
|
|
18756
|
+
if (mode === "futureswheel") return "map";
|
|
18757
|
+
if (mode === "driver") return "logic-right";
|
|
18758
|
+
return mode;
|
|
18759
|
+
}
|
|
18760
|
+
var modeRegistry = /* @__PURE__ */ new WeakMap();
|
|
18761
|
+
function setMode(ast, mode) {
|
|
18762
|
+
modeRegistry.set(ast, mode);
|
|
18763
|
+
}
|
|
18764
|
+
function modeOf(ast) {
|
|
18765
|
+
return modeRegistry.get(ast) ?? ast.style;
|
|
18766
|
+
}
|
|
18767
|
+
|
|
18209
18768
|
// src/diagrams/mindmap/parser.ts
|
|
18210
18769
|
var MindmapParseError = class extends Error {
|
|
18211
18770
|
constructor(message, line2, column, source) {
|
|
@@ -18229,6 +18788,10 @@ function parseDirective(line2, out) {
|
|
|
18229
18788
|
const val = body.slice(idx + 1).trim();
|
|
18230
18789
|
if (key === "style" && VALID_STYLES.includes(val)) {
|
|
18231
18790
|
out.style = val;
|
|
18791
|
+
out.mode = val;
|
|
18792
|
+
} else if (key === "style" && EXTENDED_MODES.includes(val)) {
|
|
18793
|
+
out.mode = val;
|
|
18794
|
+
out.style = baseStyleFor(out.mode);
|
|
18232
18795
|
} else if (key === "theme") {
|
|
18233
18796
|
out.themeOverride = val;
|
|
18234
18797
|
} else if (key === "maxlabelwidth") {
|
|
@@ -18247,7 +18810,7 @@ function parseMindmap(text2) {
|
|
|
18247
18810
|
lineOffset = 1;
|
|
18248
18811
|
}
|
|
18249
18812
|
const lines = allLines;
|
|
18250
|
-
const directives = { style: "map", maxLabelWidth: DEFAULT_MAX_LABEL_WIDTH };
|
|
18813
|
+
const directives = { style: "map", mode: "map", maxLabelWidth: DEFAULT_MAX_LABEL_WIDTH };
|
|
18251
18814
|
let root = null;
|
|
18252
18815
|
let rootInferred;
|
|
18253
18816
|
let idCounter2 = 0;
|
|
@@ -18322,6 +18885,7 @@ function parseMindmap(text2) {
|
|
|
18322
18885
|
};
|
|
18323
18886
|
if (rootInferred) ast.rootInferred = rootInferred;
|
|
18324
18887
|
if (directives.themeOverride) ast.themeOverride = directives.themeOverride;
|
|
18888
|
+
setMode(ast, directives.mode);
|
|
18325
18889
|
return ast;
|
|
18326
18890
|
}
|
|
18327
18891
|
|
|
@@ -18354,8 +18918,127 @@ function lintMindmap(text2) {
|
|
|
18354
18918
|
return out;
|
|
18355
18919
|
}
|
|
18356
18920
|
|
|
18921
|
+
// src/diagrams/mindmap/futureswheel.ts
|
|
18922
|
+
var RING_GAP = 150;
|
|
18923
|
+
function spokePath(x1, y1, x2, y2) {
|
|
18924
|
+
return `M ${x1.toFixed(1)} ${y1.toFixed(1)} L ${x2.toFixed(1)} ${y2.toFixed(1)}`;
|
|
18925
|
+
}
|
|
18926
|
+
function edgeWidthForOrder(order) {
|
|
18927
|
+
if (order <= 1) return 2.2;
|
|
18928
|
+
if (order === 2) return 1.6;
|
|
18929
|
+
return 1.2;
|
|
18930
|
+
}
|
|
18931
|
+
function leafCount(node) {
|
|
18932
|
+
if (node.children.length === 0) return 1;
|
|
18933
|
+
let sum = 0;
|
|
18934
|
+
for (const c of node.children) sum += leafCount(c);
|
|
18935
|
+
return sum;
|
|
18936
|
+
}
|
|
18937
|
+
function layoutFuturesWheel(ast) {
|
|
18938
|
+
const root = ast.root;
|
|
18939
|
+
const mw = ast.maxLabelWidth;
|
|
18940
|
+
const nodes = [];
|
|
18941
|
+
const placed = /* @__PURE__ */ new Map();
|
|
18942
|
+
const rootM = measureLabel(root, widthBudget(0, mw));
|
|
18943
|
+
const rootLayout = {
|
|
18944
|
+
node: root,
|
|
18945
|
+
x: 0,
|
|
18946
|
+
y: 0,
|
|
18947
|
+
side: "center",
|
|
18948
|
+
branchIndex: -1,
|
|
18949
|
+
labelWidth: rootM.width,
|
|
18950
|
+
labelHeight: rootM.height,
|
|
18951
|
+
fontSize: fontSizeOf(0),
|
|
18952
|
+
lines: rootM.lines
|
|
18953
|
+
};
|
|
18954
|
+
nodes.push(rootLayout);
|
|
18955
|
+
placed.set(root.id, { layout: rootLayout, angle: 0 });
|
|
18956
|
+
const placeChildren = (node, a0, a1, branchIndex) => {
|
|
18957
|
+
const kids = node.children;
|
|
18958
|
+
if (kids.length === 0) return;
|
|
18959
|
+
const weights = kids.map(leafCount);
|
|
18960
|
+
const totalW = weights.reduce((s, w) => s + w, 0);
|
|
18961
|
+
const span = a1 - a0;
|
|
18962
|
+
let cursor = a0;
|
|
18963
|
+
for (let i = 0; i < kids.length; i++) {
|
|
18964
|
+
const child = kids[i];
|
|
18965
|
+
const slice = weights[i] / totalW * span;
|
|
18966
|
+
const sliceStart = cursor;
|
|
18967
|
+
const sliceEnd = cursor + slice;
|
|
18968
|
+
const mid = (sliceStart + sliceEnd) / 2;
|
|
18969
|
+
cursor = sliceEnd;
|
|
18970
|
+
const order = child.depth;
|
|
18971
|
+
const radius = order * RING_GAP;
|
|
18972
|
+
const m = measureLabel(child, widthBudget(child.depth, mw));
|
|
18973
|
+
const childBranch = node.depth === 0 ? i : branchIndex;
|
|
18974
|
+
const layout = {
|
|
18975
|
+
node: child,
|
|
18976
|
+
x: radius * Math.cos(mid),
|
|
18977
|
+
y: radius * Math.sin(mid),
|
|
18978
|
+
// Right half-plane → label extends right; left half-plane → left.
|
|
18979
|
+
side: Math.cos(mid) >= 0 ? "right" : "left",
|
|
18980
|
+
branchIndex: childBranch,
|
|
18981
|
+
labelWidth: m.width,
|
|
18982
|
+
labelHeight: m.height,
|
|
18983
|
+
fontSize: fontSizeOf(child.depth),
|
|
18984
|
+
lines: m.lines
|
|
18985
|
+
};
|
|
18986
|
+
nodes.push(layout);
|
|
18987
|
+
placed.set(child.id, { layout, angle: mid });
|
|
18988
|
+
placeChildren(child, sliceStart, sliceEnd, childBranch);
|
|
18989
|
+
}
|
|
18990
|
+
};
|
|
18991
|
+
const START2 = -Math.PI / 2;
|
|
18992
|
+
placeChildren(root, START2, START2 + Math.PI * 2, -1);
|
|
18993
|
+
const edges = [];
|
|
18994
|
+
const walkEdges = (parent) => {
|
|
18995
|
+
const p = placed.get(parent.id);
|
|
18996
|
+
if (!p) return;
|
|
18997
|
+
for (const c of parent.children) {
|
|
18998
|
+
const cp = placed.get(c.id);
|
|
18999
|
+
if (!cp) continue;
|
|
19000
|
+
edges.push({
|
|
19001
|
+
from: parent.id,
|
|
19002
|
+
to: c.id,
|
|
19003
|
+
path: spokePath(p.layout.x, p.layout.y, cp.layout.x, cp.layout.y),
|
|
19004
|
+
color: "",
|
|
19005
|
+
width: edgeWidthForOrder(c.depth)
|
|
19006
|
+
});
|
|
19007
|
+
walkEdges(c);
|
|
19008
|
+
}
|
|
19009
|
+
};
|
|
19010
|
+
walkEdges(root);
|
|
19011
|
+
const { width, height } = normalize(nodes);
|
|
19012
|
+
const byId = new Map(nodes.map((n) => [n.node.id, n]));
|
|
19013
|
+
for (const e of edges) {
|
|
19014
|
+
const f = byId.get(e.from);
|
|
19015
|
+
const t = byId.get(e.to);
|
|
19016
|
+
if (f && t) e.path = spokePath(f.x, f.y, t.x, t.y);
|
|
19017
|
+
}
|
|
19018
|
+
return {
|
|
19019
|
+
width,
|
|
19020
|
+
height,
|
|
19021
|
+
// `style` is constrained to the base union; futureswheel renders on `map`.
|
|
19022
|
+
style: "map",
|
|
19023
|
+
nodes,
|
|
19024
|
+
edges,
|
|
19025
|
+
title: ast.title
|
|
19026
|
+
};
|
|
19027
|
+
}
|
|
19028
|
+
function wheelCenter(result) {
|
|
19029
|
+
for (const n of result.nodes) {
|
|
19030
|
+
if (n.node.depth === 0) return { cx: n.x, cy: n.y };
|
|
19031
|
+
}
|
|
19032
|
+
return { cx: result.width / 2, cy: result.height / 2 };
|
|
19033
|
+
}
|
|
19034
|
+
function maxOrder(result) {
|
|
19035
|
+
let max = 0;
|
|
19036
|
+
for (const n of result.nodes) if (n.node.depth > max) max = n.node.depth;
|
|
19037
|
+
return max;
|
|
19038
|
+
}
|
|
19039
|
+
|
|
18357
19040
|
// src/diagrams/mindmap/layout.ts
|
|
18358
|
-
var
|
|
19041
|
+
var PADDING3 = 40;
|
|
18359
19042
|
var SIBLING_GAP = 18;
|
|
18360
19043
|
var MAIN_GAP = 44;
|
|
18361
19044
|
var UNDERLINE_GAP = 4;
|
|
@@ -18502,13 +19185,13 @@ function normalize(nodes) {
|
|
|
18502
19185
|
minY = Math.min(minY, n.y - lh / 2);
|
|
18503
19186
|
maxY = Math.max(maxY, n.y + lh / 2);
|
|
18504
19187
|
}
|
|
18505
|
-
const dx =
|
|
18506
|
-
const dy =
|
|
19188
|
+
const dx = PADDING3 - minX;
|
|
19189
|
+
const dy = PADDING3 - minY;
|
|
18507
19190
|
for (const n of nodes) {
|
|
18508
19191
|
n.x += dx;
|
|
18509
19192
|
n.y += dy;
|
|
18510
19193
|
}
|
|
18511
|
-
return { width: maxX - minX +
|
|
19194
|
+
return { width: maxX - minX + PADDING3 * 2, height: maxY - minY + PADDING3 * 2 };
|
|
18512
19195
|
}
|
|
18513
19196
|
function underlineY(n) {
|
|
18514
19197
|
return n.y + n.labelHeight / 2 - UNDERLINE_GAP / 2;
|
|
@@ -18623,6 +19306,9 @@ function layoutLogicRight(ast) {
|
|
|
18623
19306
|
return { width, height, style: "logic-right", nodes, edges, title: ast.title };
|
|
18624
19307
|
}
|
|
18625
19308
|
function layoutMindmap(ast) {
|
|
19309
|
+
const mode = modeOf(ast);
|
|
19310
|
+
if (mode === "futureswheel") return layoutFuturesWheel(ast);
|
|
19311
|
+
if (mode === "driver") return layoutLogicRight(ast);
|
|
18626
19312
|
const style = ast.style;
|
|
18627
19313
|
if (style === "logic-right") return layoutLogicRight(ast);
|
|
18628
19314
|
return layoutMap(ast);
|
|
@@ -18751,7 +19437,7 @@ function tspan(attrs, content) {
|
|
|
18751
19437
|
}
|
|
18752
19438
|
return `<tspan ${pairs.join(" ")}>${chunk3WNW5Y7P_cjs.escapeXml(content)}</tspan>`;
|
|
18753
19439
|
}
|
|
18754
|
-
function
|
|
19440
|
+
function renderNode3(n, color, theme, fontFamily, orderClass) {
|
|
18755
19441
|
const isRoot = n.node.depth === 0;
|
|
18756
19442
|
const isMain = n.node.depth === 1;
|
|
18757
19443
|
const fs = n.fontSize;
|
|
@@ -18784,12 +19470,14 @@ function renderNode2(n, color, theme, fontFamily) {
|
|
|
18784
19470
|
"stroke-linecap": "round"
|
|
18785
19471
|
})
|
|
18786
19472
|
);
|
|
18787
|
-
const
|
|
19473
|
+
const baseCls = isRoot ? "schematex-mindmap-central" : isMain ? "schematex-mindmap-main" : "schematex-mindmap-leaf";
|
|
19474
|
+
const cls = orderClass ? `${baseCls} mm-order-${n.node.depth}` : baseCls;
|
|
18788
19475
|
return chunk3WNW5Y7P_cjs.group(
|
|
18789
19476
|
{
|
|
18790
19477
|
class: cls,
|
|
18791
19478
|
"data-node-id": n.node.id,
|
|
18792
19479
|
"data-depth": n.node.depth,
|
|
19480
|
+
"data-order": orderClass ? n.node.depth : void 0,
|
|
18793
19481
|
"data-branch-idx": n.branchIndex
|
|
18794
19482
|
},
|
|
18795
19483
|
[...decorations, ...children]
|
|
@@ -18797,8 +19485,30 @@ function renderNode2(n, color, theme, fontFamily) {
|
|
|
18797
19485
|
}
|
|
18798
19486
|
function renderMindmapAST(ast, themeName = "default", fontFamily = "system-ui, -apple-system, sans-serif") {
|
|
18799
19487
|
const theme = chunkNZT5P2XZ_cjs.resolveMindmapTheme(ast.themeOverride ?? themeName);
|
|
19488
|
+
const mode = modeOf(ast);
|
|
19489
|
+
const isWheel = mode === "futureswheel";
|
|
18800
19490
|
const layout = layoutMindmap(ast);
|
|
18801
19491
|
const byId = new Map(layout.nodes.map((n) => [n.node.id, n]));
|
|
19492
|
+
const ringSvgs = [];
|
|
19493
|
+
if (isWheel) {
|
|
19494
|
+
const { cx, cy } = wheelCenter(layout);
|
|
19495
|
+
const rings = maxOrder(layout);
|
|
19496
|
+
for (let order = 1; order <= rings; order++) {
|
|
19497
|
+
ringSvgs.push(
|
|
19498
|
+
chunk3WNW5Y7P_cjs.circle({
|
|
19499
|
+
cx: cx.toFixed(1),
|
|
19500
|
+
cy: cy.toFixed(1),
|
|
19501
|
+
r: (order * RING_GAP).toFixed(1),
|
|
19502
|
+
fill: "none",
|
|
19503
|
+
stroke: theme.centralFill,
|
|
19504
|
+
"stroke-width": 1,
|
|
19505
|
+
"stroke-dasharray": "3 5",
|
|
19506
|
+
opacity: 0.25,
|
|
19507
|
+
class: `mm-ring mm-ring-${order}`
|
|
19508
|
+
})
|
|
19509
|
+
);
|
|
19510
|
+
}
|
|
19511
|
+
}
|
|
18802
19512
|
const edgeSvgs = [];
|
|
18803
19513
|
for (const e of layout.edges) {
|
|
18804
19514
|
const target = byId.get(e.to);
|
|
@@ -18817,9 +19527,10 @@ function renderMindmapAST(ast, themeName = "default", fontFamily = "system-ui, -
|
|
|
18817
19527
|
const nodeSvgs = [];
|
|
18818
19528
|
for (const n of layout.nodes) {
|
|
18819
19529
|
const color = n.node.depth === 0 ? theme.centralFill : paletteColor(theme, n.branchIndex);
|
|
18820
|
-
nodeSvgs.push(
|
|
19530
|
+
nodeSvgs.push(renderNode3(n, color, theme, fontFamily, isWheel));
|
|
18821
19531
|
}
|
|
18822
19532
|
const title2 = ast.title ?? tokensToPlainText(ast.root.tokens);
|
|
19533
|
+
const descLabel = isWheel ? `futures-wheel mindmap with ${layout.nodes.length} nodes` : `${layout.style} mindmap with ${layout.nodes.length} nodes`;
|
|
18823
19534
|
return chunk3WNW5Y7P_cjs.svgRoot(
|
|
18824
19535
|
{
|
|
18825
19536
|
viewBox: `0 0 ${layout.width.toFixed(1)} ${layout.height.toFixed(1)}`,
|
|
@@ -18830,8 +19541,9 @@ function renderMindmapAST(ast, themeName = "default", fontFamily = "system-ui, -
|
|
|
18830
19541
|
},
|
|
18831
19542
|
[
|
|
18832
19543
|
chunk3WNW5Y7P_cjs.title(title2),
|
|
18833
|
-
chunk3WNW5Y7P_cjs.desc(
|
|
19544
|
+
chunk3WNW5Y7P_cjs.desc(descLabel),
|
|
18834
19545
|
chunk3WNW5Y7P_cjs.rect({ x: 0, y: 0, width: layout.width, height: layout.height, fill: theme.bg }),
|
|
19546
|
+
chunk3WNW5Y7P_cjs.group({ class: "schematex-mindmap-rings", "aria-hidden": "true" }, ringSvgs),
|
|
18835
19547
|
chunk3WNW5Y7P_cjs.group({ class: "schematex-mindmap-edges", "aria-hidden": "true" }, edgeSvgs),
|
|
18836
19548
|
chunk3WNW5Y7P_cjs.group({ class: "schematex-mindmap-nodes" }, nodeSvgs)
|
|
18837
19549
|
]
|
|
@@ -19022,6 +19734,30 @@ var DEFAULT_CONFIG = {
|
|
|
19022
19734
|
function emptyAxis() {
|
|
19023
19735
|
return { low: "", high: "" };
|
|
19024
19736
|
}
|
|
19737
|
+
function emptySipoc() {
|
|
19738
|
+
return { suppliers: [], inputs: [], process: [], outputs: [], customers: [] };
|
|
19739
|
+
}
|
|
19740
|
+
function emptyQfd() {
|
|
19741
|
+
return { whats: [], hows: [], relationships: [], roof: [], normalize: false };
|
|
19742
|
+
}
|
|
19743
|
+
function parseItemList(raw) {
|
|
19744
|
+
return parseNumberList2(raw);
|
|
19745
|
+
}
|
|
19746
|
+
function parseStrength(tok) {
|
|
19747
|
+
const t = tok.trim().toLowerCase();
|
|
19748
|
+
if (t === "9" || t === "strong" || t === "\u25CF" || t === "\u25C9" || t === "\u2B24") return 9;
|
|
19749
|
+
if (t === "3" || t === "medium" || t === "\u25CB" || t === "\u25EF" || t === "o") return 3;
|
|
19750
|
+
if (t === "1" || t === "weak" || t === "\u25B3" || t === "\u25BD" || t === "\u25B2") return 1;
|
|
19751
|
+
return void 0;
|
|
19752
|
+
}
|
|
19753
|
+
function parseCorrelation(tok) {
|
|
19754
|
+
const t = tok.trim();
|
|
19755
|
+
if (t === "++" || /^strong\+?$/i.test(t) || t === "\u25CE") return "++";
|
|
19756
|
+
if (t === "+" || /^pos(itive)?$/i.test(t) || t === "\u25CB") return "+";
|
|
19757
|
+
if (t === "--" || t === "\u2212\u2212" || /^strong-$/i.test(t) || t === "\u2715" || t === "\u2716" || t === "\xD7") return "--";
|
|
19758
|
+
if (t === "-" || t === "\u2212" || /^neg(ative)?$/i.test(t) || t === "\u2717") return "-";
|
|
19759
|
+
return void 0;
|
|
19760
|
+
}
|
|
19025
19761
|
function quadrantToCell(q) {
|
|
19026
19762
|
switch (q) {
|
|
19027
19763
|
case 1:
|
|
@@ -19174,6 +19910,91 @@ function parseCellLine(line2, st) {
|
|
|
19174
19910
|
}
|
|
19175
19911
|
return true;
|
|
19176
19912
|
}
|
|
19913
|
+
var SIPOC_KEYS = [
|
|
19914
|
+
"suppliers",
|
|
19915
|
+
"inputs",
|
|
19916
|
+
"process",
|
|
19917
|
+
"outputs",
|
|
19918
|
+
"customers"
|
|
19919
|
+
];
|
|
19920
|
+
function parseSipocLine(line2, ast) {
|
|
19921
|
+
if (!ast.sipoc) return false;
|
|
19922
|
+
const m = line2.match(/^([a-zA-Z]+)\s*:\s*(.*)$/);
|
|
19923
|
+
if (!m) return false;
|
|
19924
|
+
let key = m[1].toLowerCase();
|
|
19925
|
+
if (key === "supplier") key = "suppliers";
|
|
19926
|
+
else if (key === "input") key = "inputs";
|
|
19927
|
+
else if (key === "output") key = "outputs";
|
|
19928
|
+
else if (key === "customer") key = "customers";
|
|
19929
|
+
const col = SIPOC_KEYS.find((k) => k === key);
|
|
19930
|
+
if (!col) return false;
|
|
19931
|
+
const items = parseItemList(m[2]);
|
|
19932
|
+
ast.sipoc[col].push(...items);
|
|
19933
|
+
return true;
|
|
19934
|
+
}
|
|
19935
|
+
function parseQfdLine(line2, ast) {
|
|
19936
|
+
const qfd = ast.qfd;
|
|
19937
|
+
if (!qfd) return false;
|
|
19938
|
+
const normMatch = line2.match(/^normali[sz]e\s*:\s*(.+)$/i);
|
|
19939
|
+
if (normMatch) {
|
|
19940
|
+
const v = normMatch[1].trim().toLowerCase();
|
|
19941
|
+
qfd.normalize = v === "true" || v === "on" || v === "1" || v === "percent" || v === "%";
|
|
19942
|
+
return true;
|
|
19943
|
+
}
|
|
19944
|
+
const whatMatch = line2.match(/^what\s*:\s*(.*)$/i);
|
|
19945
|
+
if (whatMatch) {
|
|
19946
|
+
const q = readQuoted2(whatMatch[1], 0);
|
|
19947
|
+
if (!q) return true;
|
|
19948
|
+
const rest = whatMatch[1].slice(q.next);
|
|
19949
|
+
const wMatch = rest.match(/(?:weight|wt|imp(?:ortance)?)\s*:\s*(-?\d+(?:\.\d+)?)/i);
|
|
19950
|
+
const weight = wMatch ? Number(wMatch[1]) : 1;
|
|
19951
|
+
qfd.whats.push({ label: q.text, weight });
|
|
19952
|
+
return true;
|
|
19953
|
+
}
|
|
19954
|
+
const howMatch = line2.match(/^how\s*:\s*(.*)$/i);
|
|
19955
|
+
if (howMatch) {
|
|
19956
|
+
const q = readQuoted2(howMatch[1], 0);
|
|
19957
|
+
if (!q) return true;
|
|
19958
|
+
const rest = howMatch[1].slice(q.next);
|
|
19959
|
+
const dMatch = rest.match(/(?:dir(?:ection)?|target)\s*:\s*([a-zA-Z↑↓○]+)/i);
|
|
19960
|
+
let direction;
|
|
19961
|
+
if (dMatch) {
|
|
19962
|
+
const d = dMatch[1].toLowerCase();
|
|
19963
|
+
if (d === "up" || d === "max" || d === "maximise" || d === "maximize" || d === "\u2191") direction = "up";
|
|
19964
|
+
else if (d === "down" || d === "min" || d === "minimise" || d === "minimize" || d === "\u2193") direction = "down";
|
|
19965
|
+
else if (d === "target" || d === "nominal" || d === "\u25CB") direction = "target";
|
|
19966
|
+
}
|
|
19967
|
+
qfd.hows.push(direction ? { label: q.text, direction } : { label: q.text });
|
|
19968
|
+
return true;
|
|
19969
|
+
}
|
|
19970
|
+
const relMatch = line2.match(/^rel\s*\(\s*(\d+)\s*,\s*(\d+)\s*\)\s*:?\s*(.+)$/i);
|
|
19971
|
+
if (relMatch) {
|
|
19972
|
+
const what = Number(relMatch[1]);
|
|
19973
|
+
const how = Number(relMatch[2]);
|
|
19974
|
+
const strength = parseStrength(relMatch[3]);
|
|
19975
|
+
if (strength !== void 0) qfd.relationships.push({ what, how, strength });
|
|
19976
|
+
return true;
|
|
19977
|
+
}
|
|
19978
|
+
const cellMatch = line2.match(/^cell\s*\(\s*(\d+)\s*,\s*(\d+)\s*\)\s*(.*)$/i);
|
|
19979
|
+
if (cellMatch) {
|
|
19980
|
+
const how = Number(cellMatch[1]);
|
|
19981
|
+
const what = Number(cellMatch[2]);
|
|
19982
|
+
const valMatch = cellMatch[3].match(/value\s*:\s*(\d+)/i);
|
|
19983
|
+
const strength = valMatch ? parseStrength(valMatch[1]) : void 0;
|
|
19984
|
+
if (strength !== void 0) qfd.relationships.push({ what, how, strength });
|
|
19985
|
+
return true;
|
|
19986
|
+
}
|
|
19987
|
+
const roofMatch = line2.match(/^roof\s*\(\s*(\d+)\s*,\s*(\d+)\s*\)\s*:?\s*(.+)$/i);
|
|
19988
|
+
if (roofMatch) {
|
|
19989
|
+
let a = Number(roofMatch[1]);
|
|
19990
|
+
let b = Number(roofMatch[2]);
|
|
19991
|
+
if (a > b) [a, b] = [b, a];
|
|
19992
|
+
const correlation = parseCorrelation(roofMatch[3]);
|
|
19993
|
+
if (correlation !== void 0 && a !== b) qfd.roof.push({ a, b, correlation });
|
|
19994
|
+
return true;
|
|
19995
|
+
}
|
|
19996
|
+
return false;
|
|
19997
|
+
}
|
|
19177
19998
|
function parseConfigLine(key, value, ast) {
|
|
19178
19999
|
const k = key.trim().toLowerCase();
|
|
19179
20000
|
const v = value.trim();
|
|
@@ -19216,6 +20037,26 @@ function parseHeader2(line2, ast) {
|
|
|
19216
20037
|
if (title2) ast.title = stripQuotes4(title2);
|
|
19217
20038
|
return void 0;
|
|
19218
20039
|
}
|
|
20040
|
+
const sipocMatch = rest.match(/^sipoc\b\s*(.*)$/i);
|
|
20041
|
+
if (sipocMatch) {
|
|
20042
|
+
ast.mode = "sipoc";
|
|
20043
|
+
ast.grid = "NxM";
|
|
20044
|
+
ast.cols = 5;
|
|
20045
|
+
ast.rows = 0;
|
|
20046
|
+
ast.sipoc = emptySipoc();
|
|
20047
|
+
const title2 = sipocMatch[1].trim();
|
|
20048
|
+
if (title2) ast.title = stripQuotes4(title2);
|
|
20049
|
+
return void 0;
|
|
20050
|
+
}
|
|
20051
|
+
const qfdMatch = rest.match(/^qfd\b\s*(.*)$/i);
|
|
20052
|
+
if (qfdMatch) {
|
|
20053
|
+
ast.mode = "qfd";
|
|
20054
|
+
ast.grid = "NxM";
|
|
20055
|
+
ast.qfd = emptyQfd();
|
|
20056
|
+
const title2 = qfdMatch[1].trim();
|
|
20057
|
+
if (title2) ast.title = stripQuotes4(title2);
|
|
20058
|
+
return void 0;
|
|
20059
|
+
}
|
|
19219
20060
|
const tokenMatch = rest.match(/^([a-zA-Z0-9_-]+)\s*(.*)$/);
|
|
19220
20061
|
if (tokenMatch) {
|
|
19221
20062
|
const tok = tokenMatch[1].toLowerCase();
|
|
@@ -19266,6 +20107,8 @@ function parseMatrix(text2) {
|
|
|
19266
20107
|
st.ast.title = stripQuotes4(line2.replace(/^title\s*:\s*/i, ""));
|
|
19267
20108
|
continue;
|
|
19268
20109
|
}
|
|
20110
|
+
if (st.ast.mode === "sipoc" && parseSipocLine(line2, st.ast)) continue;
|
|
20111
|
+
if (st.ast.mode === "qfd" && parseQfdLine(line2, st.ast)) continue;
|
|
19269
20112
|
if (/^x-axis\s*:/i.test(line2)) {
|
|
19270
20113
|
st.ast.xAxis = parseAxis(line2.replace(/^x-axis\s*:\s*/i, ""));
|
|
19271
20114
|
continue;
|
|
@@ -19364,10 +20207,27 @@ function parseMatrix(text2) {
|
|
|
19364
20207
|
st.ast.template = templateName;
|
|
19365
20208
|
}
|
|
19366
20209
|
}
|
|
19367
|
-
if (st.ast.cols === 3 && st.ast.rows === 3 && st.ast.grid !== "NxM") {
|
|
20210
|
+
if (st.ast.cols === 3 && st.ast.rows === 3 && st.ast.grid !== "NxM" && st.ast.mode !== "sipoc" && st.ast.mode !== "qfd") {
|
|
19368
20211
|
st.ast.grid = "3x3";
|
|
19369
20212
|
}
|
|
19370
|
-
if (st.ast.mode === "heatmap" || st.ast.mode === "correlation"
|
|
20213
|
+
if (st.ast.mode === "heatmap" || st.ast.mode === "correlation" || st.ast.mode === "sipoc" || st.ast.mode === "qfd") {
|
|
20214
|
+
st.ast.grid = "NxM";
|
|
20215
|
+
}
|
|
20216
|
+
if (st.ast.mode === "sipoc" && st.ast.sipoc) {
|
|
20217
|
+
const s = st.ast.sipoc;
|
|
20218
|
+
st.ast.cols = 5;
|
|
20219
|
+
st.ast.rows = Math.max(
|
|
20220
|
+
s.suppliers.length,
|
|
20221
|
+
s.inputs.length,
|
|
20222
|
+
s.process.length,
|
|
20223
|
+
s.outputs.length,
|
|
20224
|
+
s.customers.length
|
|
20225
|
+
);
|
|
20226
|
+
}
|
|
20227
|
+
if (st.ast.mode === "qfd" && st.ast.qfd) {
|
|
20228
|
+
st.ast.cols = st.ast.qfd.hows.length;
|
|
20229
|
+
st.ast.rows = st.ast.qfd.whats.length;
|
|
20230
|
+
}
|
|
19371
20231
|
return st.ast;
|
|
19372
20232
|
}
|
|
19373
20233
|
function findCommentStart(line2) {
|
|
@@ -19385,6 +20245,23 @@ function findCommentStart(line2) {
|
|
|
19385
20245
|
return -1;
|
|
19386
20246
|
}
|
|
19387
20247
|
|
|
20248
|
+
// src/diagrams/matrix/types.ts
|
|
20249
|
+
function computeQfdImportance(qfd) {
|
|
20250
|
+
const raw = qfd.hows.map(() => 0);
|
|
20251
|
+
for (const r5 of qfd.relationships) {
|
|
20252
|
+
if (r5.how < 0 || r5.how >= qfd.hows.length) continue;
|
|
20253
|
+
if (r5.what < 0 || r5.what >= qfd.whats.length) continue;
|
|
20254
|
+
const w = qfd.whats[r5.what].weight;
|
|
20255
|
+
raw[r5.how] += w * r5.strength;
|
|
20256
|
+
}
|
|
20257
|
+
const total = raw.reduce((acc, v) => acc + v, 0);
|
|
20258
|
+
return raw.map((importance, how) => ({
|
|
20259
|
+
how,
|
|
20260
|
+
importance,
|
|
20261
|
+
percent: total > 0 ? Math.round(importance / total * 100) : 0
|
|
20262
|
+
}));
|
|
20263
|
+
}
|
|
20264
|
+
|
|
19388
20265
|
// src/diagrams/matrix/layout.ts
|
|
19389
20266
|
var CANVAS_W = 720;
|
|
19390
20267
|
var CANVAS_H = 560;
|
|
@@ -19494,6 +20371,65 @@ function resolveLabelCollisions(points, plot, mode) {
|
|
|
19494
20371
|
}
|
|
19495
20372
|
}
|
|
19496
20373
|
}
|
|
20374
|
+
var SIPOC_COL_W = 168;
|
|
20375
|
+
var SIPOC_X0 = 24;
|
|
20376
|
+
var SIPOC_Y0 = 24;
|
|
20377
|
+
var SIPOC_HEADER_H = 40;
|
|
20378
|
+
var SIPOC_ROW_H = 44;
|
|
20379
|
+
function layoutSipoc(ast) {
|
|
20380
|
+
const rows = Math.max(1, ast.rows);
|
|
20381
|
+
const titleH = ast.title ? 40 : 0;
|
|
20382
|
+
const y0 = SIPOC_Y0 + titleH;
|
|
20383
|
+
const canvasWidth = SIPOC_X0 * 2 + SIPOC_COL_W * 5;
|
|
20384
|
+
const canvasHeight = y0 + SIPOC_HEADER_H + rows * SIPOC_ROW_H + SIPOC_Y0;
|
|
20385
|
+
return {
|
|
20386
|
+
canvasWidth,
|
|
20387
|
+
canvasHeight,
|
|
20388
|
+
x0: SIPOC_X0,
|
|
20389
|
+
y0,
|
|
20390
|
+
colW: SIPOC_COL_W,
|
|
20391
|
+
headerH: SIPOC_HEADER_H,
|
|
20392
|
+
rowH: SIPOC_ROW_H,
|
|
20393
|
+
rows
|
|
20394
|
+
};
|
|
20395
|
+
}
|
|
20396
|
+
var QFD_CELL = 46;
|
|
20397
|
+
var QFD_WHAT_LABEL_W = 190;
|
|
20398
|
+
var QFD_WEIGHT_W = 46;
|
|
20399
|
+
var QFD_HOW_LABEL_H = 130;
|
|
20400
|
+
var QFD_FOOTER_H = 64;
|
|
20401
|
+
var QFD_PAD = 24;
|
|
20402
|
+
function layoutQfd(ast) {
|
|
20403
|
+
const cols = Math.max(1, ast.cols);
|
|
20404
|
+
const rows = Math.max(1, ast.rows);
|
|
20405
|
+
const cellW = QFD_CELL;
|
|
20406
|
+
const cellH = QFD_CELL;
|
|
20407
|
+
const titleH = ast.title ? 40 : 0;
|
|
20408
|
+
const roofH = Math.ceil(cellW / 2 * cols) + 8;
|
|
20409
|
+
const whatLabelW = QFD_WHAT_LABEL_W;
|
|
20410
|
+
const weightW = QFD_WEIGHT_W;
|
|
20411
|
+
const howLabelH = QFD_HOW_LABEL_H;
|
|
20412
|
+
const footerH = QFD_FOOTER_H;
|
|
20413
|
+
const gridX0 = QFD_PAD + whatLabelW + weightW;
|
|
20414
|
+
const gridY0 = QFD_PAD + titleH + roofH + howLabelH;
|
|
20415
|
+
const canvasWidth = gridX0 + cols * cellW + QFD_PAD;
|
|
20416
|
+
const canvasHeight = gridY0 + rows * cellH + footerH + QFD_PAD;
|
|
20417
|
+
return {
|
|
20418
|
+
canvasWidth,
|
|
20419
|
+
canvasHeight,
|
|
20420
|
+
gridX0,
|
|
20421
|
+
gridY0,
|
|
20422
|
+
cellW,
|
|
20423
|
+
cellH,
|
|
20424
|
+
cols,
|
|
20425
|
+
rows,
|
|
20426
|
+
whatLabelW,
|
|
20427
|
+
weightW,
|
|
20428
|
+
howLabelH,
|
|
20429
|
+
roofH,
|
|
20430
|
+
footerH
|
|
20431
|
+
};
|
|
20432
|
+
}
|
|
19497
20433
|
function layoutMatrix(ast) {
|
|
19498
20434
|
const canvasWidth = CANVAS_W;
|
|
19499
20435
|
const canvasHeight = CANVAS_H;
|
|
@@ -19593,6 +20529,35 @@ var CSS = `
|
|
|
19593
20529
|
.sx-matrix-leader { stroke: #94a3b8; stroke-width: 0.6; opacity: 0.7; fill: none; }
|
|
19594
20530
|
.sx-matrix-legend-text { font: 500 11px sans-serif; fill: #374151; }
|
|
19595
20531
|
.sx-matrix-offchart { fill: #ea580c; }
|
|
20532
|
+
.sx-sipoc-header { font: 700 13px sans-serif; fill: #fff; text-anchor: middle; dominant-baseline: central; }
|
|
20533
|
+
.sx-sipoc-headbox { stroke: #fff; stroke-width: 1; }
|
|
20534
|
+
.sx-sipoc-cell { fill: #fff; stroke: #cbd5e1; stroke-width: 1; }
|
|
20535
|
+
.sx-sipoc-cell-alt { fill: #f8fafc; stroke: #cbd5e1; stroke-width: 1; }
|
|
20536
|
+
.sx-sipoc-process { fill: #eff6ff; stroke: #cbd5e1; stroke-width: 1; }
|
|
20537
|
+
.sx-sipoc-item { font: 500 12px sans-serif; fill: #1f2937; text-anchor: middle; dominant-baseline: central; }
|
|
20538
|
+
.sx-sipoc-step { font: 600 12px sans-serif; fill: #1e3a8a; text-anchor: middle; dominant-baseline: central; }
|
|
20539
|
+
.sx-qfd-grid { stroke: #cbd5e1; stroke-width: 1; fill: none; }
|
|
20540
|
+
.sx-qfd-cellbg { fill: #fff; }
|
|
20541
|
+
.sx-qfd-cellbg-alt { fill: #f8fafc; }
|
|
20542
|
+
.sx-qfd-what { font: 500 12px sans-serif; fill: #1f2937; text-anchor: end; dominant-baseline: central; }
|
|
20543
|
+
.sx-qfd-how { font: 500 11.5px sans-serif; fill: #1f2937; }
|
|
20544
|
+
.sx-qfd-weight { font: 600 12px sans-serif; fill: #111; text-anchor: middle; dominant-baseline: central; }
|
|
20545
|
+
.sx-qfd-weight-head { font: 600 10px sans-serif; fill: #475569; text-anchor: middle; dominant-baseline: central; }
|
|
20546
|
+
.sx-qfd-rel-strong { fill: #2563eb; }
|
|
20547
|
+
.sx-qfd-rel-medium { fill: #93c5fd; stroke: #2563eb; stroke-width: 1.4; }
|
|
20548
|
+
.sx-qfd-rel-weak { fill: none; stroke: #2563eb; stroke-width: 1.4; }
|
|
20549
|
+
.sx-qfd-roof-cell { fill: #f8fafc; stroke: #94a3b8; stroke-width: 0.8; }
|
|
20550
|
+
.sx-qfd-roof-cell-filled { fill: #eef2ff; stroke: #64748b; stroke-width: 0.9; }
|
|
20551
|
+
.sx-qfd-corr { font: 700 13px sans-serif; text-anchor: middle; dominant-baseline: central; }
|
|
20552
|
+
.sx-qfd-corr-strong-pos { fill: #15803d; }
|
|
20553
|
+
.sx-qfd-corr-pos { fill: #16a34a; }
|
|
20554
|
+
.sx-qfd-corr-neg { fill: #dc2626; }
|
|
20555
|
+
.sx-qfd-corr-strong-neg { fill: #b91c1c; }
|
|
20556
|
+
.sx-qfd-imp-band { fill: #eff6ff; stroke: #cbd5e1; stroke-width: 1; }
|
|
20557
|
+
.sx-qfd-imp-head { font: 600 11px sans-serif; fill: #1e3a8a; text-anchor: end; dominant-baseline: central; }
|
|
20558
|
+
.sx-qfd-imp-value { font: 700 13px sans-serif; fill: #1e3a8a; text-anchor: middle; dominant-baseline: central; }
|
|
20559
|
+
.sx-qfd-imp-value-top { font: 800 14px sans-serif; fill: #dc2626; text-anchor: middle; dominant-baseline: central; }
|
|
20560
|
+
.sx-qfd-dir { font: 700 13px sans-serif; fill: #475569; text-anchor: middle; dominant-baseline: central; }
|
|
19596
20561
|
`.trim();
|
|
19597
20562
|
function axisArrow() {
|
|
19598
20563
|
return chunk3WNW5Y7P_cjs.el(
|
|
@@ -20379,7 +21344,339 @@ function renderTitle(ast, lay) {
|
|
|
20379
21344
|
ast.title
|
|
20380
21345
|
);
|
|
20381
21346
|
}
|
|
21347
|
+
var SIPOC_COLUMN_DEFS = [
|
|
21348
|
+
{ key: "suppliers", label: "Suppliers", color: "#2563eb" },
|
|
21349
|
+
{ key: "inputs", label: "Inputs", color: "#0891b2" },
|
|
21350
|
+
{ key: "process", label: "Process", color: "#1e3a8a" },
|
|
21351
|
+
{ key: "outputs", label: "Outputs", color: "#0891b2" },
|
|
21352
|
+
{ key: "customers", label: "Customers", color: "#2563eb" }
|
|
21353
|
+
];
|
|
21354
|
+
function wrapToLines(textStr, maxChars, maxLines) {
|
|
21355
|
+
const lines = wrapLabel(textStr, maxChars);
|
|
21356
|
+
if (lines.length <= maxLines) return lines;
|
|
21357
|
+
const kept = lines.slice(0, maxLines);
|
|
21358
|
+
kept[maxLines - 1] = kept[maxLines - 1].replace(/\s+\S*$/, "") + "\u2026";
|
|
21359
|
+
return kept;
|
|
21360
|
+
}
|
|
21361
|
+
function renderSipocAST(ast) {
|
|
21362
|
+
const sipoc = ast.sipoc ?? { suppliers: [], inputs: [], process: [], outputs: [], customers: [] };
|
|
21363
|
+
const lay = layoutSipoc(ast);
|
|
21364
|
+
const nodes = [];
|
|
21365
|
+
if (ast.title) {
|
|
21366
|
+
nodes.push(
|
|
21367
|
+
chunk3WNW5Y7P_cjs.text(
|
|
21368
|
+
{ x: lay.canvasWidth / 2, y: 24, class: "sx-matrix-title", "text-anchor": "middle" },
|
|
21369
|
+
ast.title
|
|
21370
|
+
)
|
|
21371
|
+
);
|
|
21372
|
+
}
|
|
21373
|
+
const maxChars = Math.max(10, Math.floor((lay.colW - 16) / 6.4));
|
|
21374
|
+
SIPOC_COLUMN_DEFS.forEach((def, ci) => {
|
|
21375
|
+
const colX = lay.x0 + ci * lay.colW;
|
|
21376
|
+
nodes.push(
|
|
21377
|
+
chunk3WNW5Y7P_cjs.rect({
|
|
21378
|
+
x: colX,
|
|
21379
|
+
y: lay.y0,
|
|
21380
|
+
width: lay.colW,
|
|
21381
|
+
height: lay.headerH,
|
|
21382
|
+
fill: def.color,
|
|
21383
|
+
class: "sx-sipoc-headbox"
|
|
21384
|
+
})
|
|
21385
|
+
);
|
|
21386
|
+
nodes.push(
|
|
21387
|
+
chunk3WNW5Y7P_cjs.text(
|
|
21388
|
+
{ x: colX + lay.colW / 2, y: lay.y0 + lay.headerH / 2, class: "sx-sipoc-header" },
|
|
21389
|
+
def.label
|
|
21390
|
+
)
|
|
21391
|
+
);
|
|
21392
|
+
const items = sipoc[def.key];
|
|
21393
|
+
const isProcess = def.key === "process";
|
|
21394
|
+
const cellNodes = [];
|
|
21395
|
+
for (let r5 = 0; r5 < lay.rows; r5++) {
|
|
21396
|
+
const cellY = lay.y0 + lay.headerH + r5 * lay.rowH;
|
|
21397
|
+
const item = items[r5];
|
|
21398
|
+
const cellClass = isProcess ? "sx-sipoc-process" : r5 % 2 === 0 ? "sx-sipoc-cell" : "sx-sipoc-cell-alt";
|
|
21399
|
+
cellNodes.push(
|
|
21400
|
+
chunk3WNW5Y7P_cjs.rect({ x: colX, y: cellY, width: lay.colW, height: lay.rowH, class: cellClass })
|
|
21401
|
+
);
|
|
21402
|
+
if (item) {
|
|
21403
|
+
const label = isProcess ? `${r5 + 1}. ${item}` : item;
|
|
21404
|
+
const lines = wrapToLines(label, maxChars, 2);
|
|
21405
|
+
const lineH = 14;
|
|
21406
|
+
const startY = cellY + lay.rowH / 2 - (lines.length - 1) * lineH / 2;
|
|
21407
|
+
for (let i = 0; i < lines.length; i++) {
|
|
21408
|
+
cellNodes.push(
|
|
21409
|
+
chunk3WNW5Y7P_cjs.text(
|
|
21410
|
+
{
|
|
21411
|
+
x: colX + lay.colW / 2,
|
|
21412
|
+
y: startY + i * lineH,
|
|
21413
|
+
class: isProcess ? "sx-sipoc-step" : "sx-sipoc-item"
|
|
21414
|
+
},
|
|
21415
|
+
lines[i]
|
|
21416
|
+
)
|
|
21417
|
+
);
|
|
21418
|
+
}
|
|
21419
|
+
}
|
|
21420
|
+
}
|
|
21421
|
+
nodes.push(
|
|
21422
|
+
chunk3WNW5Y7P_cjs.group({ class: "sx-sipoc-column", "data-column": def.key }, [
|
|
21423
|
+
chunk3WNW5Y7P_cjs.title(`${def.label}: ${items.join(", ")}`),
|
|
21424
|
+
...cellNodes
|
|
21425
|
+
])
|
|
21426
|
+
);
|
|
21427
|
+
});
|
|
21428
|
+
return chunk3WNW5Y7P_cjs.svgRoot(
|
|
21429
|
+
{
|
|
21430
|
+
class: "sx-matrix sx-sipoc",
|
|
21431
|
+
"data-diagram-type": "matrix",
|
|
21432
|
+
"data-mode": "sipoc",
|
|
21433
|
+
width: lay.canvasWidth,
|
|
21434
|
+
height: lay.canvasHeight,
|
|
21435
|
+
viewBox: `0 0 ${lay.canvasWidth} ${lay.canvasHeight}`,
|
|
21436
|
+
role: "graphics-document"
|
|
21437
|
+
},
|
|
21438
|
+
[
|
|
21439
|
+
chunk3WNW5Y7P_cjs.title(ast.title ? `SIPOC \u2014 ${chunk3WNW5Y7P_cjs.escapeXml(ast.title)}` : "SIPOC diagram"),
|
|
21440
|
+
chunk3WNW5Y7P_cjs.desc(
|
|
21441
|
+
`SIPOC scoping table \u2014 ${sipoc.suppliers.length} supplier(s), ${sipoc.inputs.length} input(s), ${sipoc.process.length} process step(s), ${sipoc.outputs.length} output(s), ${sipoc.customers.length} customer(s)`
|
|
21442
|
+
),
|
|
21443
|
+
chunk3WNW5Y7P_cjs.defs([chunk3WNW5Y7P_cjs.el("style", {}, CSS)]),
|
|
21444
|
+
...nodes
|
|
21445
|
+
]
|
|
21446
|
+
);
|
|
21447
|
+
}
|
|
21448
|
+
var CORR_GLYPH = {
|
|
21449
|
+
"++": "\u25CF",
|
|
21450
|
+
"+": "\u25CB",
|
|
21451
|
+
"-": "\u2212",
|
|
21452
|
+
"--": "\u2715"
|
|
21453
|
+
};
|
|
21454
|
+
var CORR_CLASS = {
|
|
21455
|
+
"++": "sx-qfd-corr-strong-pos",
|
|
21456
|
+
"+": "sx-qfd-corr-pos",
|
|
21457
|
+
"-": "sx-qfd-corr-neg",
|
|
21458
|
+
"--": "sx-qfd-corr-strong-neg"
|
|
21459
|
+
};
|
|
21460
|
+
var CORR_LABEL = {
|
|
21461
|
+
"++": "strong positive",
|
|
21462
|
+
"+": "positive",
|
|
21463
|
+
"-": "negative",
|
|
21464
|
+
"--": "strong negative"
|
|
21465
|
+
};
|
|
21466
|
+
function renderQfdRelationshipSymbol(strength, cx, cy, r5) {
|
|
21467
|
+
if (strength === 9) {
|
|
21468
|
+
return chunk3WNW5Y7P_cjs.group({}, [
|
|
21469
|
+
chunk3WNW5Y7P_cjs.circle({ cx, cy, r: r5, fill: "none", stroke: "#2563eb", "stroke-width": 1.4 }),
|
|
21470
|
+
chunk3WNW5Y7P_cjs.circle({ cx, cy, r: r5 * 0.5, class: "sx-qfd-rel-strong" })
|
|
21471
|
+
]);
|
|
21472
|
+
}
|
|
21473
|
+
if (strength === 3) {
|
|
21474
|
+
return chunk3WNW5Y7P_cjs.circle({ cx, cy, r: r5, class: "sx-qfd-rel-medium" });
|
|
21475
|
+
}
|
|
21476
|
+
const t = r5 * 0.95;
|
|
21477
|
+
return chunk3WNW5Y7P_cjs.polygon({
|
|
21478
|
+
points: `${cx},${cy - t} ${cx + t},${cy + t * 0.85} ${cx - t},${cy + t * 0.85}`,
|
|
21479
|
+
class: "sx-qfd-rel-weak"
|
|
21480
|
+
});
|
|
21481
|
+
}
|
|
21482
|
+
function renderQfdAST(ast) {
|
|
21483
|
+
const qfd = ast.qfd ?? { whats: [], hows: [], relationships: [], roof: [], normalize: false };
|
|
21484
|
+
const lay = layoutQfd(ast);
|
|
21485
|
+
const importance = computeQfdImportance(qfd);
|
|
21486
|
+
const maxImp = importance.reduce((m, c) => Math.max(m, c.importance), 0);
|
|
21487
|
+
const nodes = [];
|
|
21488
|
+
if (ast.title) {
|
|
21489
|
+
nodes.push(
|
|
21490
|
+
chunk3WNW5Y7P_cjs.text(
|
|
21491
|
+
{ x: lay.canvasWidth / 2, y: 24, class: "sx-matrix-title", "text-anchor": "middle" },
|
|
21492
|
+
ast.title
|
|
21493
|
+
)
|
|
21494
|
+
);
|
|
21495
|
+
}
|
|
21496
|
+
const gridRight = lay.gridX0 + lay.cols * lay.cellW;
|
|
21497
|
+
const gridBottom = lay.gridY0 + lay.rows * lay.cellH;
|
|
21498
|
+
const roofNodes = [];
|
|
21499
|
+
const half = lay.cellW / 2;
|
|
21500
|
+
const roofBaseY = lay.gridY0 - lay.howLabelH;
|
|
21501
|
+
const corrByPair = /* @__PURE__ */ new Map();
|
|
21502
|
+
for (const rc of qfd.roof) {
|
|
21503
|
+
const a = Math.min(rc.a, rc.b);
|
|
21504
|
+
const b = Math.max(rc.a, rc.b);
|
|
21505
|
+
corrByPair.set(`${a},${b}`, rc.correlation);
|
|
21506
|
+
}
|
|
21507
|
+
for (let i = 0; i < lay.cols; i++) {
|
|
21508
|
+
for (let j = i + 1; j < lay.cols; j++) {
|
|
21509
|
+
const depth = j - i;
|
|
21510
|
+
const cx = lay.gridX0 + ((i + j) / 2 + 0.5) * lay.cellW;
|
|
21511
|
+
const cy = roofBaseY - (depth - 0.5) * half;
|
|
21512
|
+
const corr = corrByPair.get(`${i},${j}`);
|
|
21513
|
+
const diamond = chunk3WNW5Y7P_cjs.polygon({
|
|
21514
|
+
points: `${cx},${cy - half} ${cx + half},${cy} ${cx},${cy + half} ${cx - half},${cy}`,
|
|
21515
|
+
class: corr ? "sx-qfd-roof-cell-filled" : "sx-qfd-roof-cell"
|
|
21516
|
+
});
|
|
21517
|
+
const cellChildren = [
|
|
21518
|
+
chunk3WNW5Y7P_cjs.title(
|
|
21519
|
+
corr ? `${qfd.hows[i]?.label ?? `HOW ${i}`} \u2194 ${qfd.hows[j]?.label ?? `HOW ${j}`}: ${CORR_LABEL[corr]}` : `${qfd.hows[i]?.label ?? `HOW ${i}`} \u2194 ${qfd.hows[j]?.label ?? `HOW ${j}`}: no correlation`
|
|
21520
|
+
),
|
|
21521
|
+
diamond
|
|
21522
|
+
];
|
|
21523
|
+
if (corr) {
|
|
21524
|
+
cellChildren.push(
|
|
21525
|
+
chunk3WNW5Y7P_cjs.text(
|
|
21526
|
+
{ x: cx, y: cy, class: `sx-qfd-corr ${CORR_CLASS[corr]}` },
|
|
21527
|
+
CORR_GLYPH[corr]
|
|
21528
|
+
)
|
|
21529
|
+
);
|
|
21530
|
+
}
|
|
21531
|
+
roofNodes.push(
|
|
21532
|
+
chunk3WNW5Y7P_cjs.group(
|
|
21533
|
+
{
|
|
21534
|
+
class: "sx-qfd-roof-pair",
|
|
21535
|
+
"data-pair": `${i},${j}`,
|
|
21536
|
+
...corr ? { "data-corr": corr } : {}
|
|
21537
|
+
},
|
|
21538
|
+
cellChildren
|
|
21539
|
+
)
|
|
21540
|
+
);
|
|
21541
|
+
}
|
|
21542
|
+
}
|
|
21543
|
+
nodes.push(chunk3WNW5Y7P_cjs.group({ class: "sx-qfd-roof" }, [chunk3WNW5Y7P_cjs.title("Roof: engineering correlation matrix"), ...roofNodes]));
|
|
21544
|
+
qfd.hows.forEach((how, ci) => {
|
|
21545
|
+
const cx = lay.gridX0 + (ci + 0.5) * lay.cellW;
|
|
21546
|
+
const baseY = lay.gridY0 - 8;
|
|
21547
|
+
nodes.push(
|
|
21548
|
+
chunk3WNW5Y7P_cjs.text(
|
|
21549
|
+
{
|
|
21550
|
+
x: cx,
|
|
21551
|
+
y: baseY,
|
|
21552
|
+
class: "sx-qfd-how",
|
|
21553
|
+
"text-anchor": "start",
|
|
21554
|
+
transform: `rotate(-60 ${cx} ${baseY})`
|
|
21555
|
+
},
|
|
21556
|
+
how.label
|
|
21557
|
+
)
|
|
21558
|
+
);
|
|
21559
|
+
if (how.direction) {
|
|
21560
|
+
const glyph = how.direction === "up" ? "\u25B2" : how.direction === "down" ? "\u25BC" : "\u25C7";
|
|
21561
|
+
nodes.push(
|
|
21562
|
+
chunk3WNW5Y7P_cjs.text({ x: cx, y: lay.gridY0 - 4, class: "sx-qfd-dir" }, glyph)
|
|
21563
|
+
);
|
|
21564
|
+
}
|
|
21565
|
+
});
|
|
21566
|
+
nodes.push(
|
|
21567
|
+
chunk3WNW5Y7P_cjs.text(
|
|
21568
|
+
{ x: lay.gridX0 - lay.weightW / 2, y: lay.gridY0 - 8, class: "sx-qfd-weight-head" },
|
|
21569
|
+
"Wt"
|
|
21570
|
+
)
|
|
21571
|
+
);
|
|
21572
|
+
const gridNodes = [];
|
|
21573
|
+
for (let r5 = 0; r5 < lay.rows; r5++) {
|
|
21574
|
+
const y = lay.gridY0 + r5 * lay.cellH;
|
|
21575
|
+
gridNodes.push(
|
|
21576
|
+
chunk3WNW5Y7P_cjs.rect({
|
|
21577
|
+
x: lay.gridX0,
|
|
21578
|
+
y,
|
|
21579
|
+
width: lay.cols * lay.cellW,
|
|
21580
|
+
height: lay.cellH,
|
|
21581
|
+
class: r5 % 2 === 0 ? "sx-qfd-cellbg" : "sx-qfd-cellbg-alt"
|
|
21582
|
+
})
|
|
21583
|
+
);
|
|
21584
|
+
}
|
|
21585
|
+
for (let i = 0; i <= lay.cols; i++) {
|
|
21586
|
+
const x = lay.gridX0 + i * lay.cellW;
|
|
21587
|
+
gridNodes.push(chunk3WNW5Y7P_cjs.line({ x1: x, y1: lay.gridY0, x2: x, y2: gridBottom, class: "sx-qfd-grid" }));
|
|
21588
|
+
}
|
|
21589
|
+
for (let j = 0; j <= lay.rows; j++) {
|
|
21590
|
+
const y = lay.gridY0 + j * lay.cellH;
|
|
21591
|
+
gridNodes.push(chunk3WNW5Y7P_cjs.line({ x1: lay.gridX0, y1: y, x2: gridRight, y2: y, class: "sx-qfd-grid" }));
|
|
21592
|
+
}
|
|
21593
|
+
nodes.push(chunk3WNW5Y7P_cjs.group({ class: "sx-qfd-gridlines" }, gridNodes));
|
|
21594
|
+
const whatMaxChars = Math.max(10, Math.floor((lay.whatLabelW - 12) / 6.4));
|
|
21595
|
+
qfd.whats.forEach((what, ri) => {
|
|
21596
|
+
const cy = lay.gridY0 + (ri + 0.5) * lay.cellH;
|
|
21597
|
+
const lines = wrapToLines(what.label, whatMaxChars, 2);
|
|
21598
|
+
const lineH = 13;
|
|
21599
|
+
const startY = cy - (lines.length - 1) * lineH / 2;
|
|
21600
|
+
const labelNodes = lines.map(
|
|
21601
|
+
(ln, i) => chunk3WNW5Y7P_cjs.text({ x: lay.gridX0 - lay.weightW - 8, y: startY + i * lineH, class: "sx-qfd-what" }, ln)
|
|
21602
|
+
);
|
|
21603
|
+
labelNodes.push(
|
|
21604
|
+
chunk3WNW5Y7P_cjs.text({ x: lay.gridX0 - lay.weightW / 2, y: cy, class: "sx-qfd-weight" }, String(what.weight))
|
|
21605
|
+
);
|
|
21606
|
+
nodes.push(
|
|
21607
|
+
chunk3WNW5Y7P_cjs.group({ class: "sx-qfd-what-row", "data-what": String(ri) }, [
|
|
21608
|
+
chunk3WNW5Y7P_cjs.title(`${what.label} (weight ${what.weight})`),
|
|
21609
|
+
...labelNodes
|
|
21610
|
+
])
|
|
21611
|
+
);
|
|
21612
|
+
});
|
|
21613
|
+
const relNodes = [];
|
|
21614
|
+
const symR = Math.min(lay.cellW, lay.cellH) * 0.3;
|
|
21615
|
+
for (const rel of qfd.relationships) {
|
|
21616
|
+
if (rel.how < 0 || rel.how >= lay.cols || rel.what < 0 || rel.what >= lay.rows) continue;
|
|
21617
|
+
const cx = lay.gridX0 + (rel.how + 0.5) * lay.cellW;
|
|
21618
|
+
const cy = lay.gridY0 + (rel.what + 0.5) * lay.cellH;
|
|
21619
|
+
relNodes.push(
|
|
21620
|
+
chunk3WNW5Y7P_cjs.group(
|
|
21621
|
+
{ class: "sx-qfd-rel", "data-strength": String(rel.strength) },
|
|
21622
|
+
[
|
|
21623
|
+
chunk3WNW5Y7P_cjs.title(`${qfd.whats[rel.what]?.label ?? ""} \xD7 ${qfd.hows[rel.how]?.label ?? ""} = ${rel.strength}`),
|
|
21624
|
+
renderQfdRelationshipSymbol(rel.strength, cx, cy, symR)
|
|
21625
|
+
]
|
|
21626
|
+
)
|
|
21627
|
+
);
|
|
21628
|
+
}
|
|
21629
|
+
nodes.push(chunk3WNW5Y7P_cjs.group({ class: "sx-qfd-relationships" }, relNodes));
|
|
21630
|
+
const footerNodes = [];
|
|
21631
|
+
const impRowY = gridBottom;
|
|
21632
|
+
const impH = lay.footerH;
|
|
21633
|
+
footerNodes.push(
|
|
21634
|
+
chunk3WNW5Y7P_cjs.rect({ x: lay.gridX0, y: impRowY, width: lay.cols * lay.cellW, height: impH, class: "sx-qfd-imp-band" })
|
|
21635
|
+
);
|
|
21636
|
+
for (let i = 1; i < lay.cols; i++) {
|
|
21637
|
+
const x = lay.gridX0 + i * lay.cellW;
|
|
21638
|
+
footerNodes.push(chunk3WNW5Y7P_cjs.line({ x1: x, y1: impRowY, x2: x, y2: impRowY + impH, class: "sx-qfd-grid" }));
|
|
21639
|
+
}
|
|
21640
|
+
const footerLabel = qfd.normalize ? "Importance %" : "Technical importance \u03A3(wt\xD7rel)";
|
|
21641
|
+
footerNodes.push(
|
|
21642
|
+
chunk3WNW5Y7P_cjs.text({ x: lay.gridX0 - 8, y: impRowY + impH / 2, class: "sx-qfd-imp-head" }, footerLabel)
|
|
21643
|
+
);
|
|
21644
|
+
importance.forEach((col) => {
|
|
21645
|
+
const cx = lay.gridX0 + (col.how + 0.5) * lay.cellW;
|
|
21646
|
+
const cy = impRowY + impH / 2;
|
|
21647
|
+
const isTop = col.importance === maxImp && maxImp > 0;
|
|
21648
|
+
const display = qfd.normalize ? `${col.percent}%` : String(col.importance);
|
|
21649
|
+
footerNodes.push(
|
|
21650
|
+
chunk3WNW5Y7P_cjs.text(
|
|
21651
|
+
{ x: cx, y: cy, class: isTop ? "sx-qfd-imp-value-top" : "sx-qfd-imp-value" },
|
|
21652
|
+
display
|
|
21653
|
+
)
|
|
21654
|
+
);
|
|
21655
|
+
});
|
|
21656
|
+
nodes.push(chunk3WNW5Y7P_cjs.group({ class: "sx-qfd-importance" }, [chunk3WNW5Y7P_cjs.title("Computed technical importance per engineering characteristic"), ...footerNodes]));
|
|
21657
|
+
return chunk3WNW5Y7P_cjs.svgRoot(
|
|
21658
|
+
{
|
|
21659
|
+
class: "sx-matrix sx-qfd",
|
|
21660
|
+
"data-diagram-type": "matrix",
|
|
21661
|
+
"data-mode": "qfd",
|
|
21662
|
+
width: lay.canvasWidth,
|
|
21663
|
+
height: lay.canvasHeight,
|
|
21664
|
+
viewBox: `0 0 ${lay.canvasWidth} ${lay.canvasHeight}`,
|
|
21665
|
+
role: "graphics-document"
|
|
21666
|
+
},
|
|
21667
|
+
[
|
|
21668
|
+
chunk3WNW5Y7P_cjs.title(ast.title ? `QFD House of Quality \u2014 ${chunk3WNW5Y7P_cjs.escapeXml(ast.title)}` : "QFD House of Quality"),
|
|
21669
|
+
chunk3WNW5Y7P_cjs.desc(
|
|
21670
|
+
`QFD House of Quality \u2014 ${qfd.whats.length} customer requirement(s), ${qfd.hows.length} engineering characteristic(s), ${qfd.relationships.length} relationship(s); technical importance computed per column`
|
|
21671
|
+
),
|
|
21672
|
+
chunk3WNW5Y7P_cjs.defs([chunk3WNW5Y7P_cjs.el("style", {}, CSS)]),
|
|
21673
|
+
...nodes
|
|
21674
|
+
]
|
|
21675
|
+
);
|
|
21676
|
+
}
|
|
20382
21677
|
function renderMatrixAST(ast) {
|
|
21678
|
+
if (ast.mode === "sipoc") return renderSipocAST(ast);
|
|
21679
|
+
if (ast.mode === "qfd") return renderQfdAST(ast);
|
|
20383
21680
|
const lay = layoutMatrix(ast);
|
|
20384
21681
|
const needsLegendSpace = lay.categories.length > 0 || ast.mode === "correlation";
|
|
20385
21682
|
const extraWidth = needsLegendSpace && lay.plot.x0 + lay.plot.w + 140 > lay.canvasWidth ? 160 : 0;
|
|
@@ -20459,7 +21756,7 @@ function stripComment6(s) {
|
|
|
20459
21756
|
}
|
|
20460
21757
|
return out;
|
|
20461
21758
|
}
|
|
20462
|
-
function
|
|
21759
|
+
function unquote6(v) {
|
|
20463
21760
|
const t = v.trim();
|
|
20464
21761
|
if (t.length >= 2 && t.startsWith('"') && t.endsWith('"')) return t.slice(1, -1);
|
|
20465
21762
|
return t;
|
|
@@ -20548,7 +21845,7 @@ function parseErd(text2) {
|
|
|
20548
21845
|
continue;
|
|
20549
21846
|
}
|
|
20550
21847
|
if (lower.startsWith("title:")) {
|
|
20551
|
-
title2 =
|
|
21848
|
+
title2 = unquote6(t.slice("title:".length).trim());
|
|
20552
21849
|
i++;
|
|
20553
21850
|
continue;
|
|
20554
21851
|
}
|
|
@@ -20748,7 +22045,7 @@ function parseAttributeLine(raw, lineNumber, tableId) {
|
|
|
20748
22045
|
let comment;
|
|
20749
22046
|
const colonIdx = findUnquotedChar(s, ":");
|
|
20750
22047
|
if (colonIdx >= 0) {
|
|
20751
|
-
comment =
|
|
22048
|
+
comment = unquote6(s.slice(colonIdx + 1).trim());
|
|
20752
22049
|
s = s.slice(0, colonIdx).trim();
|
|
20753
22050
|
}
|
|
20754
22051
|
let fkTarget;
|
|
@@ -20800,7 +22097,7 @@ function parseRefLine(raw, lineNumber, outRefs) {
|
|
|
20800
22097
|
let label;
|
|
20801
22098
|
const colonIdx = findUnquotedChar(s, ":");
|
|
20802
22099
|
if (colonIdx >= 0) {
|
|
20803
|
-
label =
|
|
22100
|
+
label = unquote6(s.slice(colonIdx + 1).trim());
|
|
20804
22101
|
s = s.slice(0, colonIdx).trim();
|
|
20805
22102
|
}
|
|
20806
22103
|
const merm = /^(\S+)\s+([}|o][o|]|\|\||\|o)(\.\.|--|~~)([}|o][{|]|\|\||o\|)\s+(\S+)$/.exec(s);
|
|
@@ -21249,7 +22546,7 @@ function sideAnchor(e, side, col) {
|
|
|
21249
22546
|
}
|
|
21250
22547
|
|
|
21251
22548
|
// src/diagrams/erd/renderer.ts
|
|
21252
|
-
function
|
|
22549
|
+
function buildCss9(t) {
|
|
21253
22550
|
return `
|
|
21254
22551
|
.lt-erd { font-family: system-ui, -apple-system, sans-serif; }
|
|
21255
22552
|
.lt-erd-title { font: bold 16px sans-serif; fill: ${t.text}; }
|
|
@@ -21559,7 +22856,7 @@ function renderEdge5(edge) {
|
|
|
21559
22856
|
function renderErdAst(result, themeName = "default") {
|
|
21560
22857
|
const theme = chunkNZT5P2XZ_cjs.resolveBaseTheme(themeName);
|
|
21561
22858
|
const { entities, edges, width, height, ast } = result;
|
|
21562
|
-
const cssBlock = chunk3WNW5Y7P_cjs.el("style", {},
|
|
22859
|
+
const cssBlock = chunk3WNW5Y7P_cjs.el("style", {}, buildCss9(theme));
|
|
21563
22860
|
const titleNode = chunk3WNW5Y7P_cjs.title(ast.title ?? "Schematex ERD");
|
|
21564
22861
|
const descNode = chunk3WNW5Y7P_cjs.desc(
|
|
21565
22862
|
`Entity-Relationship Diagram with ${entities.length} entities and ${edges.length} relationships.`
|
|
@@ -21640,7 +22937,7 @@ function stripComment7(s) {
|
|
|
21640
22937
|
}
|
|
21641
22938
|
return out;
|
|
21642
22939
|
}
|
|
21643
|
-
function
|
|
22940
|
+
function unquote7(v) {
|
|
21644
22941
|
const t = v.trim();
|
|
21645
22942
|
if (t.length >= 2 && t.startsWith('"') && t.endsWith('"')) return t.slice(1, -1);
|
|
21646
22943
|
return t;
|
|
@@ -21882,7 +23179,7 @@ function parseBreadboard(text2) {
|
|
|
21882
23179
|
continue;
|
|
21883
23180
|
}
|
|
21884
23181
|
if (lower.startsWith("title:")) {
|
|
21885
|
-
title2 =
|
|
23182
|
+
title2 = unquote7(line2.text.slice("title:".length).trim());
|
|
21886
23183
|
i++;
|
|
21887
23184
|
continue;
|
|
21888
23185
|
}
|
|
@@ -22629,7 +23926,7 @@ var WIRE_COLOR_MAP = {
|
|
|
22629
23926
|
brown: "#78350f",
|
|
22630
23927
|
grey: "#64748b"
|
|
22631
23928
|
};
|
|
22632
|
-
function
|
|
23929
|
+
function buildCss10(t) {
|
|
22633
23930
|
return `
|
|
22634
23931
|
.lt-bb { font-family: system-ui, -apple-system, sans-serif; }
|
|
22635
23932
|
.lt-bb-title { font: 600 16px sans-serif; fill: ${t.text}; }
|
|
@@ -22777,7 +24074,7 @@ function renderWire(lw) {
|
|
|
22777
24074
|
}
|
|
22778
24075
|
function renderBreadboardLayout(layout, config) {
|
|
22779
24076
|
const theme = chunkNZT5P2XZ_cjs.resolveBaseTheme(config?.theme ?? "default");
|
|
22780
|
-
const css =
|
|
24077
|
+
const css = buildCss10(theme);
|
|
22781
24078
|
const titleStr = layout.ast.title ?? "Breadboard";
|
|
22782
24079
|
const titleNode = layout.ast.title ? chunk3WNW5Y7P_cjs.text({ x: BB_CONST.MARGIN, y: 22, class: "lt-bb-title" }, layout.ast.title) : "";
|
|
22783
24080
|
const substrate = renderSubstrate(layout.substrate);
|
|
@@ -22836,7 +24133,7 @@ var BpmnParseError = class extends Error {
|
|
|
22836
24133
|
}
|
|
22837
24134
|
line;
|
|
22838
24135
|
};
|
|
22839
|
-
function
|
|
24136
|
+
function unquote8(s) {
|
|
22840
24137
|
return s.replace(/^"|"$/g, "").replace(/\\"/g, '"');
|
|
22841
24138
|
}
|
|
22842
24139
|
function takeQuoted(rest) {
|
|
@@ -23006,7 +24303,7 @@ function parsePool(lines, startIdx, pools, lanesById, events, activities, gatewa
|
|
|
23006
24303
|
const ln = lines[startIdx];
|
|
23007
24304
|
const m = ln.text.match(/^pool\s+("(?:\\.|[^"\\])*")\s*(.*)$/);
|
|
23008
24305
|
if (!m) throw new BpmnParseError("malformed pool declaration", ln.no);
|
|
23009
|
-
const label =
|
|
24306
|
+
const label = unquote8(m[1]);
|
|
23010
24307
|
const tail = m[2].trim();
|
|
23011
24308
|
let blackbox = false;
|
|
23012
24309
|
let hasBrace = false;
|
|
@@ -23058,7 +24355,7 @@ function parseLane(lines, startIdx, pool, lanesById, events, activities, gateway
|
|
|
23058
24355
|
const ln = lines[startIdx];
|
|
23059
24356
|
const m = ln.text.match(/^lane\s+("(?:\\.|[^"\\])*")\s*\{?\s*$/);
|
|
23060
24357
|
if (!m) throw new BpmnParseError("malformed lane declaration", ln.no);
|
|
23061
|
-
const label =
|
|
24358
|
+
const label = unquote8(m[1]);
|
|
23062
24359
|
const hasBrace = ln.text.endsWith("{");
|
|
23063
24360
|
if (pool.blackbox) {
|
|
23064
24361
|
throw new BpmnParseError(
|
|
@@ -25143,7 +26440,7 @@ function buildGraph2(network2) {
|
|
|
25143
26440
|
}
|
|
25144
26441
|
return { incoming, outgoing, inputVars, outputVars };
|
|
25145
26442
|
}
|
|
25146
|
-
function
|
|
26443
|
+
function assignLayers2(network2, graph) {
|
|
25147
26444
|
const layer = /* @__PURE__ */ new Map();
|
|
25148
26445
|
const visiting = /* @__PURE__ */ new Set();
|
|
25149
26446
|
const visit = (id) => {
|
|
@@ -25167,7 +26464,7 @@ function layoutNetwork3(network2, originX, originY) {
|
|
|
25167
26464
|
const graph = buildGraph2(network2);
|
|
25168
26465
|
const sizes = /* @__PURE__ */ new Map();
|
|
25169
26466
|
for (const b of network2.blocks) sizes.set(b.id, computeBlockSize(b));
|
|
25170
|
-
const layerOf =
|
|
26467
|
+
const layerOf = assignLayers2(network2, graph);
|
|
25171
26468
|
const maxLayer = Math.max(0, ...Array.from(layerOf.values()));
|
|
25172
26469
|
const byLayer = Array.from({ length: maxLayer + 1 }, () => []);
|
|
25173
26470
|
for (const b of network2.blocks) byLayer[layerOf.get(b.id)].push(b.id);
|
|
@@ -26533,7 +27830,7 @@ var plugins = [
|
|
|
26533
27830
|
chunkNFZMNKOR_cjs.genogram,
|
|
26534
27831
|
chunk2SZJQVPN_cjs.ecomap,
|
|
26535
27832
|
chunkKGOZBABH_cjs.pedigree,
|
|
26536
|
-
|
|
27833
|
+
chunkJAYJ2G4R_cjs.phylo,
|
|
26537
27834
|
chunk5FYPSIGD_cjs.sociogram,
|
|
26538
27835
|
chunk2F45Y2ON_cjs.timing,
|
|
26539
27836
|
chunkZ3A2UNK2_cjs.logic,
|
|
@@ -26604,7 +27901,7 @@ function normalizeHeader(text2, type) {
|
|
|
26604
27901
|
}
|
|
26605
27902
|
return text2;
|
|
26606
27903
|
}
|
|
26607
|
-
function
|
|
27904
|
+
function preprocess9(text2) {
|
|
26608
27905
|
const { data, body } = chunk3KRL2EGN_cjs.parseFrontmatter(stripCodeFences(text2));
|
|
26609
27906
|
if (!data.title) return body;
|
|
26610
27907
|
const safeTitle = data.title.replace(/"/g, '\\"');
|
|
@@ -26619,7 +27916,7 @@ function preprocess8(text2) {
|
|
|
26619
27916
|
return body;
|
|
26620
27917
|
}
|
|
26621
27918
|
function parse(text2, config) {
|
|
26622
|
-
const prepared0 =
|
|
27919
|
+
const prepared0 = preprocess9(text2);
|
|
26623
27920
|
const plugin = detectPlugin(prepared0, config);
|
|
26624
27921
|
const prepared = normalizeHeader(prepared0, plugin.type);
|
|
26625
27922
|
if (plugin.parse) return plugin.parse(prepared);
|
|
@@ -26630,7 +27927,7 @@ function parse(text2, config) {
|
|
|
26630
27927
|
function parseResult(text2, config) {
|
|
26631
27928
|
let plugin;
|
|
26632
27929
|
try {
|
|
26633
|
-
const prepared0 =
|
|
27930
|
+
const prepared0 = preprocess9(text2);
|
|
26634
27931
|
plugin = detectPlugin(prepared0, config);
|
|
26635
27932
|
if (!plugin.parse) {
|
|
26636
27933
|
throw new Error(
|
|
@@ -26666,7 +27963,7 @@ function runLint(plugin, prepared) {
|
|
|
26666
27963
|
}
|
|
26667
27964
|
function render(text2, config) {
|
|
26668
27965
|
if (config?.mode === "preview") return renderResult(text2, config).svg;
|
|
26669
|
-
const prepared0 =
|
|
27966
|
+
const prepared0 = preprocess9(text2);
|
|
26670
27967
|
const plugin = detectPlugin(prepared0, config);
|
|
26671
27968
|
const prepared = normalizeHeader(prepared0, plugin.type);
|
|
26672
27969
|
return renderWithPlugin(prepared, plugin, config);
|
|
@@ -26674,7 +27971,7 @@ function render(text2, config) {
|
|
|
26674
27971
|
function renderResult(text2, config) {
|
|
26675
27972
|
let plugin;
|
|
26676
27973
|
try {
|
|
26677
|
-
const prepared0 =
|
|
27974
|
+
const prepared0 = preprocess9(text2);
|
|
26678
27975
|
plugin = detectPlugin(prepared0, config);
|
|
26679
27976
|
const prepared = normalizeHeader(prepared0, plugin.type);
|
|
26680
27977
|
const svg = renderWithPlugin(prepared, plugin, config);
|
|
@@ -26735,5 +28032,5 @@ exports.state = state;
|
|
|
26735
28032
|
exports.timeline = timeline;
|
|
26736
28033
|
exports.umlclass = umlclass;
|
|
26737
28034
|
exports.usecase = usecase;
|
|
26738
|
-
//# sourceMappingURL=chunk-
|
|
26739
|
-
//# sourceMappingURL=chunk-
|
|
28035
|
+
//# sourceMappingURL=chunk-HFATQXFN.cjs.map
|
|
28036
|
+
//# sourceMappingURL=chunk-HFATQXFN.cjs.map
|