@diagrammo/dgmo 0.8.18 → 0.8.20
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/cli.cjs +89 -130
- package/dist/index.cjs +1202 -993
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +216 -114
- package/dist/index.d.ts +216 -114
- package/dist/index.js +1211 -985
- package/dist/index.js.map +1 -1
- package/docs/language-reference.md +73 -0
- package/package.json +22 -9
- package/src/boxes-and-lines/parser.ts +8 -3
- package/src/c4/parser.ts +8 -7
- package/src/class/parser.ts +6 -0
- package/src/cli.ts +1 -9
- package/src/d3.ts +16 -234
- package/src/dgmo-router.ts +97 -5
- package/src/diagnostics.ts +16 -6
- package/src/echarts.ts +43 -10
- package/src/er/parser.ts +22 -2
- package/src/gantt/renderer.ts +153 -91
- package/src/graph/flowchart-parser.ts +89 -52
- package/src/graph/state-parser.ts +60 -35
- package/src/index.ts +23 -18
- package/src/infra/parser.ts +9 -2
- package/src/kanban/renderer.ts +2 -2
- package/src/palettes/color-utils.ts +4 -12
- package/src/palettes/index.ts +0 -4
- package/src/render.ts +30 -16
- package/src/sequence/collapse.ts +169 -0
- package/src/sequence/parser.ts +21 -4
- package/src/sequence/renderer.ts +198 -52
- package/src/sharing.ts +86 -49
- package/src/sitemap/renderer.ts +1 -6
- package/src/utils/arrows.ts +180 -11
- package/src/utils/d3-types.ts +4 -0
- package/src/utils/legend-constants.ts +11 -4
- package/src/utils/legend-d3.ts +171 -0
- package/src/utils/legend-layout.ts +140 -13
- package/src/utils/legend-types.ts +45 -0
- package/src/utils/time-ticks.ts +213 -0
- package/src/branding.ts +0 -67
- package/src/dgmo-mermaid.ts +0 -262
- package/src/palettes/mermaid-bridge.ts +0 -220
package/dist/index.js
CHANGED
|
@@ -32,8 +32,8 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
32
32
|
));
|
|
33
33
|
|
|
34
34
|
// src/diagnostics.ts
|
|
35
|
-
function makeDgmoError(line10, message, severity = "error") {
|
|
36
|
-
return { line: line10, message, severity };
|
|
35
|
+
function makeDgmoError(line10, message, severity = "error", code) {
|
|
36
|
+
return code !== void 0 ? { line: line10, message, severity, code } : { line: line10, message, severity };
|
|
37
37
|
}
|
|
38
38
|
function formatDgmoError(err) {
|
|
39
39
|
return err.line > 0 ? `Line ${err.line}: ${err.message}` : err.message;
|
|
@@ -74,74 +74,227 @@ var init_diagnostics = __esm({
|
|
|
74
74
|
}
|
|
75
75
|
});
|
|
76
76
|
|
|
77
|
-
// src/
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
77
|
+
// src/colors.ts
|
|
78
|
+
function isRecognizedColorName(name) {
|
|
79
|
+
return Object.prototype.hasOwnProperty.call(colorNames, name.toLowerCase());
|
|
80
|
+
}
|
|
81
|
+
function resolveColor(color, palette) {
|
|
82
|
+
if (!color) return null;
|
|
83
|
+
if (color.startsWith("#")) return null;
|
|
84
|
+
const lower = color.toLowerCase();
|
|
85
|
+
if (!isRecognizedColorName(lower)) return null;
|
|
86
|
+
if (palette) {
|
|
87
|
+
const named = palette.colors[lower];
|
|
88
|
+
if (named) return named;
|
|
89
|
+
}
|
|
90
|
+
return colorNames[lower];
|
|
91
|
+
}
|
|
92
|
+
function resolveColorWithDiagnostic(color, line10, diagnostics, palette) {
|
|
93
|
+
const resolved = resolveColor(color, palette);
|
|
94
|
+
if (resolved !== null) return resolved;
|
|
95
|
+
const hint = suggest(color, RECOGNIZED_COLOR_NAMES);
|
|
96
|
+
const suggestion = hint ? ` ${hint}` : "";
|
|
97
|
+
diagnostics.push(
|
|
98
|
+
makeDgmoError(
|
|
99
|
+
line10,
|
|
100
|
+
`Unknown color "${color}". Allowed: ${RECOGNIZED_COLOR_NAMES.join(", ")}.${suggestion}`,
|
|
101
|
+
"warning"
|
|
102
|
+
)
|
|
103
|
+
);
|
|
104
|
+
return void 0;
|
|
105
|
+
}
|
|
106
|
+
var nord, colorNames, RECOGNIZED_COLOR_NAMES, seriesColors;
|
|
107
|
+
var init_colors = __esm({
|
|
108
|
+
"src/colors.ts"() {
|
|
81
109
|
"use strict";
|
|
82
|
-
|
|
110
|
+
init_diagnostics();
|
|
111
|
+
nord = {
|
|
112
|
+
// Polar Night (dark)
|
|
113
|
+
nord0: "#2e3440",
|
|
114
|
+
nord1: "#3b4252",
|
|
115
|
+
nord2: "#434c5e",
|
|
116
|
+
nord3: "#4c566a",
|
|
117
|
+
// Snow Storm (light)
|
|
118
|
+
nord4: "#d8dee9",
|
|
119
|
+
nord5: "#e5e9f0",
|
|
120
|
+
nord6: "#eceff4",
|
|
121
|
+
// Frost (accent blues)
|
|
122
|
+
nord7: "#8fbcbb",
|
|
123
|
+
nord8: "#88c0d0",
|
|
124
|
+
nord9: "#81a1c1",
|
|
125
|
+
nord10: "#5e81ac",
|
|
126
|
+
// Aurora (colors)
|
|
127
|
+
nord11: "#bf616a",
|
|
128
|
+
// red
|
|
129
|
+
nord12: "#d08770",
|
|
130
|
+
// orange
|
|
131
|
+
nord13: "#ebcb8b",
|
|
132
|
+
// yellow
|
|
133
|
+
nord14: "#a3be8c",
|
|
134
|
+
// green
|
|
135
|
+
nord15: "#b48ead"
|
|
136
|
+
// purple
|
|
137
|
+
};
|
|
138
|
+
colorNames = {
|
|
139
|
+
red: nord.nord11,
|
|
140
|
+
orange: nord.nord12,
|
|
141
|
+
yellow: nord.nord13,
|
|
142
|
+
green: nord.nord14,
|
|
143
|
+
blue: nord.nord10,
|
|
144
|
+
purple: nord.nord15,
|
|
145
|
+
teal: nord.nord7,
|
|
146
|
+
cyan: nord.nord8,
|
|
147
|
+
gray: nord.nord3,
|
|
148
|
+
black: nord.nord0,
|
|
149
|
+
white: nord.nord6
|
|
150
|
+
};
|
|
151
|
+
RECOGNIZED_COLOR_NAMES = Object.freeze([
|
|
152
|
+
"red",
|
|
153
|
+
"orange",
|
|
154
|
+
"yellow",
|
|
155
|
+
"green",
|
|
156
|
+
"blue",
|
|
157
|
+
"purple",
|
|
158
|
+
"teal",
|
|
159
|
+
"cyan",
|
|
160
|
+
"gray",
|
|
161
|
+
"black",
|
|
162
|
+
"white"
|
|
163
|
+
]);
|
|
164
|
+
seriesColors = [
|
|
165
|
+
nord.nord10,
|
|
166
|
+
// blue
|
|
167
|
+
nord.nord14,
|
|
168
|
+
// green
|
|
169
|
+
nord.nord13,
|
|
170
|
+
// yellow
|
|
171
|
+
nord.nord12,
|
|
172
|
+
// orange
|
|
173
|
+
nord.nord15,
|
|
174
|
+
// purple
|
|
175
|
+
nord.nord11,
|
|
176
|
+
// red
|
|
177
|
+
nord.nord7,
|
|
178
|
+
// teal
|
|
179
|
+
nord.nord8
|
|
180
|
+
// light blue
|
|
181
|
+
];
|
|
83
182
|
}
|
|
84
183
|
});
|
|
85
184
|
|
|
86
|
-
// src/
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
if (parts.length === 4) {
|
|
99
|
-
const [vx, vy, vw, vh] = parts;
|
|
100
|
-
const newVh = vh + BRANDING_HEIGHT;
|
|
101
|
-
const textX = vx + vw - 4;
|
|
102
|
-
const textY = vy + vh + BRANDING_HEIGHT - 6;
|
|
103
|
-
const positioned = brandingText.replace('x="0" y="0"', `x="${textX}" y="${textY}"`);
|
|
104
|
-
let result = svgHtml.replace(
|
|
105
|
-
/viewBox="[^"]+"/,
|
|
106
|
-
`viewBox="${vx} ${vy} ${vw} ${newVh}"`
|
|
107
|
-
);
|
|
108
|
-
if (heightAttrMatch) {
|
|
109
|
-
const oldH = parseFloat(heightAttrMatch[1]);
|
|
110
|
-
if (!isNaN(oldH)) {
|
|
111
|
-
result = result.replace(
|
|
112
|
-
`height="${heightAttrMatch[1]}"`,
|
|
113
|
-
`height="${oldH + BRANDING_HEIGHT}"`
|
|
114
|
-
);
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
result = result.replace("</svg>", `${positioned}</svg>`);
|
|
118
|
-
return result;
|
|
119
|
-
}
|
|
185
|
+
// src/utils/arrows.ts
|
|
186
|
+
function validateLabelCharacters(label, lineNumber) {
|
|
187
|
+
const out = [];
|
|
188
|
+
if (label.includes("->") || label.includes("~>")) {
|
|
189
|
+
out.push(
|
|
190
|
+
makeDgmoError(
|
|
191
|
+
lineNumber,
|
|
192
|
+
'Arrow symbols (-> or ~>) are not allowed inside a label. Move the label after the arrow: "A -> B: uses -> to chain". See "In-Arrow Message Labels" \u2192 Forbidden.',
|
|
193
|
+
"error",
|
|
194
|
+
ARROW_DIAGNOSTIC_CODES.ARROW_SUBSTRING_IN_LABEL
|
|
195
|
+
)
|
|
196
|
+
);
|
|
120
197
|
}
|
|
121
|
-
|
|
122
|
-
const
|
|
123
|
-
const
|
|
124
|
-
const
|
|
125
|
-
if (
|
|
126
|
-
const
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
198
|
+
for (const ch of label) {
|
|
199
|
+
const cp = ch.codePointAt(0);
|
|
200
|
+
const isC0 = cp >= 0 && cp <= 31 && cp !== 9;
|
|
201
|
+
const isDel = cp === 127;
|
|
202
|
+
if (isC0 || isDel) {
|
|
203
|
+
const hex = cp.toString(16).toUpperCase().padStart(4, "0");
|
|
204
|
+
out.push(
|
|
205
|
+
makeDgmoError(
|
|
206
|
+
lineNumber,
|
|
207
|
+
`Label contains a control character (U+${hex}). Remove it and use plain text.`,
|
|
208
|
+
"error",
|
|
209
|
+
ARROW_DIAGNOSTIC_CODES.CONTROL_CHAR_IN_LABEL
|
|
210
|
+
)
|
|
132
211
|
);
|
|
133
|
-
|
|
134
|
-
return result;
|
|
212
|
+
break;
|
|
135
213
|
}
|
|
136
214
|
}
|
|
137
|
-
return
|
|
215
|
+
return out;
|
|
216
|
+
}
|
|
217
|
+
function parseInArrowLabel(rawLabel, lineNumber) {
|
|
218
|
+
const trimmed = rawLabel.trim();
|
|
219
|
+
if (trimmed.length === 0) {
|
|
220
|
+
return { label: void 0, diagnostics: [] };
|
|
221
|
+
}
|
|
222
|
+
const diagnostics = validateLabelCharacters(trimmed, lineNumber);
|
|
223
|
+
return { label: trimmed, diagnostics };
|
|
224
|
+
}
|
|
225
|
+
function matchColorParens(content) {
|
|
226
|
+
const m = content.match(/^\(([A-Za-z]+)\)$/);
|
|
227
|
+
if (!m) return null;
|
|
228
|
+
const candidate = m[1].toLowerCase();
|
|
229
|
+
if (RECOGNIZED_COLOR_NAMES.includes(candidate)) {
|
|
230
|
+
return candidate;
|
|
231
|
+
}
|
|
232
|
+
return null;
|
|
233
|
+
}
|
|
234
|
+
function parseArrow(line10) {
|
|
235
|
+
if (BIDI_SYNC_RE.test(line10) || BIDI_ASYNC_RE.test(line10)) {
|
|
236
|
+
return {
|
|
237
|
+
error: "Bidirectional arrows are no longer supported. Use two separate lines: 'A -msg-> B' and 'B -msg-> A'"
|
|
238
|
+
};
|
|
239
|
+
}
|
|
240
|
+
if (RETURN_SYNC_LABELED_RE.test(line10) || RETURN_ASYNC_LABELED_RE.test(line10)) {
|
|
241
|
+
const m = line10.match(RETURN_SYNC_LABELED_RE) ?? line10.match(RETURN_ASYNC_LABELED_RE);
|
|
242
|
+
const from = m[3];
|
|
243
|
+
const to = m[1];
|
|
244
|
+
const label = m[2].trim();
|
|
245
|
+
return {
|
|
246
|
+
error: `Left-pointing arrows are no longer supported. Write '${from} -${label}-> ${to}' instead`
|
|
247
|
+
};
|
|
248
|
+
}
|
|
249
|
+
const patterns = [
|
|
250
|
+
{ re: SYNC_LABELED_RE, async: false },
|
|
251
|
+
{ re: ASYNC_LABELED_RE, async: true }
|
|
252
|
+
];
|
|
253
|
+
for (const { re, async: isAsync } of patterns) {
|
|
254
|
+
const m = line10.match(re);
|
|
255
|
+
if (!m) continue;
|
|
256
|
+
const label = m[2].trim();
|
|
257
|
+
if (!label) return null;
|
|
258
|
+
return {
|
|
259
|
+
from: m[1],
|
|
260
|
+
to: m[3],
|
|
261
|
+
label,
|
|
262
|
+
async: isAsync
|
|
263
|
+
};
|
|
264
|
+
}
|
|
265
|
+
return null;
|
|
138
266
|
}
|
|
139
|
-
var
|
|
140
|
-
var
|
|
141
|
-
"src/
|
|
267
|
+
var ARROW_DIAGNOSTIC_CODES, SYNC_LABELED_RE, ASYNC_LABELED_RE, RETURN_SYNC_LABELED_RE, RETURN_ASYNC_LABELED_RE, BIDI_SYNC_RE, BIDI_ASYNC_RE;
|
|
268
|
+
var init_arrows = __esm({
|
|
269
|
+
"src/utils/arrows.ts"() {
|
|
142
270
|
"use strict";
|
|
143
|
-
|
|
144
|
-
|
|
271
|
+
init_diagnostics();
|
|
272
|
+
init_colors();
|
|
273
|
+
ARROW_DIAGNOSTIC_CODES = {
|
|
274
|
+
/** Active: label contains `->` or `~>` substring (TD-13). */
|
|
275
|
+
ARROW_SUBSTRING_IN_LABEL: "E_ARROW_SUBSTRING_IN_LABEL",
|
|
276
|
+
/** Active: label contains a forbidden control character (TD-14). */
|
|
277
|
+
CONTROL_CHAR_IN_LABEL: "E_CONTROL_CHAR_IN_LABEL",
|
|
278
|
+
/** Reserved: not currently emitted by any parser. See JSDoc above. */
|
|
279
|
+
TRAILING_ARROW_TEXT: "E_TRAILING_ARROW_TEXT",
|
|
280
|
+
/** Reserved: not currently emitted by any parser. See JSDoc above. */
|
|
281
|
+
MIXED_ARROW_DELIMITERS: "E_MIXED_ARROW_DELIMITERS"
|
|
282
|
+
};
|
|
283
|
+
SYNC_LABELED_RE = /^(.+?)\s*-(.+)->\s*(.+)$/;
|
|
284
|
+
ASYNC_LABELED_RE = /^(.+?)\s*~(.+)~>\s*(.+)$/;
|
|
285
|
+
RETURN_SYNC_LABELED_RE = /^(.+?)\s*<-(.+)-\s*(.+)$/;
|
|
286
|
+
RETURN_ASYNC_LABELED_RE = /^(.+?)\s*<~(.+)~\s*(.+)$/;
|
|
287
|
+
BIDI_SYNC_RE = /^(.+?)\s*<-(.+)->\s*(.+)$/;
|
|
288
|
+
BIDI_ASYNC_RE = /^(.+?)\s*<~(.+)~>\s*(.+)$/;
|
|
289
|
+
}
|
|
290
|
+
});
|
|
291
|
+
|
|
292
|
+
// src/fonts.ts
|
|
293
|
+
var FONT_FAMILY;
|
|
294
|
+
var init_fonts = __esm({
|
|
295
|
+
"src/fonts.ts"() {
|
|
296
|
+
"use strict";
|
|
297
|
+
FONT_FAMILY = "Inter, system-ui, Avenir, Helvetica, Arial, sans-serif";
|
|
145
298
|
}
|
|
146
299
|
});
|
|
147
300
|
|
|
@@ -322,110 +475,158 @@ var init_label_layout = __esm({
|
|
|
322
475
|
}
|
|
323
476
|
});
|
|
324
477
|
|
|
325
|
-
// src/
|
|
326
|
-
function
|
|
327
|
-
|
|
478
|
+
// src/utils/time-ticks.ts
|
|
479
|
+
function fractionalYearToDate(frac) {
|
|
480
|
+
const year = Math.floor(frac);
|
|
481
|
+
const remainder = frac - year;
|
|
482
|
+
const monthFrac = remainder * 12;
|
|
483
|
+
const month = Math.floor(monthFrac);
|
|
484
|
+
const monthRemainder = remainder - month / 12;
|
|
485
|
+
const dayFrac = monthRemainder * 365;
|
|
486
|
+
const day = Math.floor(dayFrac) + 1;
|
|
487
|
+
const dayRemainder = dayFrac - Math.floor(dayFrac);
|
|
488
|
+
const hourFrac = dayRemainder * 24;
|
|
489
|
+
const hour = Math.floor(hourFrac);
|
|
490
|
+
const minute = Math.round((hourFrac - hour) * 60);
|
|
491
|
+
return new Date(year, month, day, hour, minute);
|
|
328
492
|
}
|
|
329
|
-
function
|
|
330
|
-
|
|
331
|
-
if (color.startsWith("#")) return null;
|
|
332
|
-
const lower = color.toLowerCase();
|
|
333
|
-
if (!isRecognizedColorName(lower)) return null;
|
|
334
|
-
if (palette) {
|
|
335
|
-
const named = palette.colors[lower];
|
|
336
|
-
if (named) return named;
|
|
337
|
-
}
|
|
338
|
-
return colorNames[lower];
|
|
493
|
+
function dateToFractionalYear(d) {
|
|
494
|
+
return d.getFullYear() + d.getMonth() / 12 + (d.getDate() - 1) / 365 + d.getHours() / 8760 + d.getMinutes() / 525600;
|
|
339
495
|
}
|
|
340
|
-
function
|
|
341
|
-
const
|
|
342
|
-
|
|
343
|
-
const
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
)
|
|
351
|
-
|
|
352
|
-
|
|
496
|
+
function computeTimeTicks(domainMin, domainMax, scale, boundaryStart, boundaryEnd, boundaryStartLabel, boundaryEndLabel) {
|
|
497
|
+
const minYear = Math.floor(domainMin);
|
|
498
|
+
const maxYear = Math.floor(domainMax);
|
|
499
|
+
const span = domainMax - domainMin;
|
|
500
|
+
let ticks = [];
|
|
501
|
+
const firstYear = Math.ceil(domainMin);
|
|
502
|
+
const lastYear = Math.floor(domainMax);
|
|
503
|
+
if (lastYear >= firstYear + 1) {
|
|
504
|
+
const yearSpan = lastYear - firstYear;
|
|
505
|
+
let step = 1;
|
|
506
|
+
if (yearSpan > 80) step = 20;
|
|
507
|
+
else if (yearSpan > 40) step = 10;
|
|
508
|
+
else if (yearSpan > 20) step = 5;
|
|
509
|
+
else if (yearSpan > 10) step = 2;
|
|
510
|
+
const alignedFirst = Math.ceil(firstYear / step) * step;
|
|
511
|
+
for (let y = alignedFirst; y <= lastYear; y += step) {
|
|
512
|
+
ticks.push({ pos: scale(y), label: String(y) });
|
|
513
|
+
}
|
|
514
|
+
} else if (span > 0.25) {
|
|
515
|
+
const crossesYear = maxYear > minYear;
|
|
516
|
+
for (let y = minYear; y <= maxYear + 1; y++) {
|
|
517
|
+
for (let m = 1; m <= 12; m++) {
|
|
518
|
+
const val = y + (m - 1) / 12;
|
|
519
|
+
if (val > domainMax) break;
|
|
520
|
+
if (val >= domainMin) {
|
|
521
|
+
ticks.push({
|
|
522
|
+
pos: scale(val),
|
|
523
|
+
label: crossesYear ? `${MONTH_ABBR[m - 1]} '${String(y).slice(-2)}` : MONTH_ABBR[m - 1]
|
|
524
|
+
});
|
|
525
|
+
}
|
|
526
|
+
}
|
|
527
|
+
}
|
|
528
|
+
} else if (span <= 685e-6) {
|
|
529
|
+
let stepMin = 5;
|
|
530
|
+
const spanHours = span * 8760;
|
|
531
|
+
if (spanHours > 3) stepMin = 30;
|
|
532
|
+
else if (spanHours > 1) stepMin = 15;
|
|
533
|
+
else if (spanHours > 0.5) stepMin = 10;
|
|
534
|
+
const startDate = fractionalYearToDate(domainMin);
|
|
535
|
+
startDate.setMinutes(
|
|
536
|
+
Math.floor(startDate.getMinutes() / stepMin) * stepMin,
|
|
537
|
+
0,
|
|
538
|
+
0
|
|
539
|
+
);
|
|
540
|
+
while (true) {
|
|
541
|
+
const val = dateToFractionalYear(startDate);
|
|
542
|
+
if (val > domainMax) break;
|
|
543
|
+
if (val >= domainMin) {
|
|
544
|
+
const hh = String(startDate.getHours()).padStart(2, "0");
|
|
545
|
+
const mm = String(startDate.getMinutes()).padStart(2, "0");
|
|
546
|
+
ticks.push({ pos: scale(val), label: `${hh}:${mm}` });
|
|
547
|
+
}
|
|
548
|
+
startDate.setMinutes(startDate.getMinutes() + stepMin);
|
|
549
|
+
}
|
|
550
|
+
} else if (span <= 822e-5) {
|
|
551
|
+
let stepHour = 1;
|
|
552
|
+
const spanHours = span * 8760;
|
|
553
|
+
if (spanHours > 48) stepHour = 6;
|
|
554
|
+
else if (spanHours > 24) stepHour = 3;
|
|
555
|
+
else if (spanHours > 12) stepHour = 2;
|
|
556
|
+
const singleDay = spanHours <= 24;
|
|
557
|
+
const startDate = fractionalYearToDate(domainMin);
|
|
558
|
+
startDate.setHours(
|
|
559
|
+
Math.floor(startDate.getHours() / stepHour) * stepHour,
|
|
560
|
+
0,
|
|
561
|
+
0,
|
|
562
|
+
0
|
|
563
|
+
);
|
|
564
|
+
while (true) {
|
|
565
|
+
const val = dateToFractionalYear(startDate);
|
|
566
|
+
if (val > domainMax) break;
|
|
567
|
+
if (val >= domainMin) {
|
|
568
|
+
const hh = String(startDate.getHours()).padStart(2, "0");
|
|
569
|
+
const mm = String(startDate.getMinutes()).padStart(2, "0");
|
|
570
|
+
if (singleDay) {
|
|
571
|
+
ticks.push({ pos: scale(val), label: `${hh}:${mm}` });
|
|
572
|
+
} else {
|
|
573
|
+
const mon = MONTH_ABBR[startDate.getMonth()];
|
|
574
|
+
const d = startDate.getDate();
|
|
575
|
+
ticks.push({ pos: scale(val), label: `${mon} ${d} ${hh}:${mm}` });
|
|
576
|
+
}
|
|
577
|
+
}
|
|
578
|
+
startDate.setHours(startDate.getHours() + stepHour);
|
|
579
|
+
}
|
|
580
|
+
} else {
|
|
581
|
+
for (let y = minYear; y <= maxYear + 1; y++) {
|
|
582
|
+
for (let m = 1; m <= 12; m++) {
|
|
583
|
+
for (const d of [1, 8, 15, 22]) {
|
|
584
|
+
const val = y + (m - 1) / 12 + (d - 1) / 365;
|
|
585
|
+
if (val > domainMax) break;
|
|
586
|
+
if (val >= domainMin) {
|
|
587
|
+
ticks.push({
|
|
588
|
+
pos: scale(val),
|
|
589
|
+
label: `${MONTH_ABBR[m - 1]} ${d}`
|
|
590
|
+
});
|
|
591
|
+
}
|
|
592
|
+
}
|
|
593
|
+
}
|
|
594
|
+
}
|
|
595
|
+
}
|
|
596
|
+
const collisionThreshold = 40;
|
|
597
|
+
if (boundaryStart !== void 0 && boundaryStartLabel) {
|
|
598
|
+
const boundaryPos = scale(boundaryStart);
|
|
599
|
+
ticks = ticks.filter(
|
|
600
|
+
(t) => Math.abs(t.pos - boundaryPos) >= collisionThreshold
|
|
601
|
+
);
|
|
602
|
+
ticks.unshift({ pos: boundaryPos, label: boundaryStartLabel });
|
|
603
|
+
}
|
|
604
|
+
if (boundaryEnd !== void 0 && boundaryEndLabel) {
|
|
605
|
+
const boundaryPos = scale(boundaryEnd);
|
|
606
|
+
ticks = ticks.filter(
|
|
607
|
+
(t) => Math.abs(t.pos - boundaryPos) >= collisionThreshold
|
|
608
|
+
);
|
|
609
|
+
ticks.push({ pos: boundaryPos, label: boundaryEndLabel });
|
|
610
|
+
}
|
|
611
|
+
return ticks;
|
|
353
612
|
}
|
|
354
|
-
var
|
|
355
|
-
var
|
|
356
|
-
"src/
|
|
613
|
+
var MONTH_ABBR;
|
|
614
|
+
var init_time_ticks = __esm({
|
|
615
|
+
"src/utils/time-ticks.ts"() {
|
|
357
616
|
"use strict";
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
nord8: "#88c0d0",
|
|
372
|
-
nord9: "#81a1c1",
|
|
373
|
-
nord10: "#5e81ac",
|
|
374
|
-
// Aurora (colors)
|
|
375
|
-
nord11: "#bf616a",
|
|
376
|
-
// red
|
|
377
|
-
nord12: "#d08770",
|
|
378
|
-
// orange
|
|
379
|
-
nord13: "#ebcb8b",
|
|
380
|
-
// yellow
|
|
381
|
-
nord14: "#a3be8c",
|
|
382
|
-
// green
|
|
383
|
-
nord15: "#b48ead"
|
|
384
|
-
// purple
|
|
385
|
-
};
|
|
386
|
-
colorNames = {
|
|
387
|
-
red: nord.nord11,
|
|
388
|
-
orange: nord.nord12,
|
|
389
|
-
yellow: nord.nord13,
|
|
390
|
-
green: nord.nord14,
|
|
391
|
-
blue: nord.nord10,
|
|
392
|
-
purple: nord.nord15,
|
|
393
|
-
teal: nord.nord7,
|
|
394
|
-
cyan: nord.nord8,
|
|
395
|
-
gray: nord.nord3,
|
|
396
|
-
black: nord.nord0,
|
|
397
|
-
white: nord.nord6
|
|
398
|
-
};
|
|
399
|
-
RECOGNIZED_COLOR_NAMES = Object.freeze([
|
|
400
|
-
"red",
|
|
401
|
-
"orange",
|
|
402
|
-
"yellow",
|
|
403
|
-
"green",
|
|
404
|
-
"blue",
|
|
405
|
-
"purple",
|
|
406
|
-
"teal",
|
|
407
|
-
"cyan",
|
|
408
|
-
"gray",
|
|
409
|
-
"black",
|
|
410
|
-
"white"
|
|
411
|
-
]);
|
|
412
|
-
seriesColors = [
|
|
413
|
-
nord.nord10,
|
|
414
|
-
// blue
|
|
415
|
-
nord.nord14,
|
|
416
|
-
// green
|
|
417
|
-
nord.nord13,
|
|
418
|
-
// yellow
|
|
419
|
-
nord.nord12,
|
|
420
|
-
// orange
|
|
421
|
-
nord.nord15,
|
|
422
|
-
// purple
|
|
423
|
-
nord.nord11,
|
|
424
|
-
// red
|
|
425
|
-
nord.nord7,
|
|
426
|
-
// teal
|
|
427
|
-
nord.nord8
|
|
428
|
-
// light blue
|
|
617
|
+
MONTH_ABBR = [
|
|
618
|
+
"Jan",
|
|
619
|
+
"Feb",
|
|
620
|
+
"Mar",
|
|
621
|
+
"Apr",
|
|
622
|
+
"May",
|
|
623
|
+
"Jun",
|
|
624
|
+
"Jul",
|
|
625
|
+
"Aug",
|
|
626
|
+
"Sep",
|
|
627
|
+
"Oct",
|
|
628
|
+
"Nov",
|
|
629
|
+
"Dec"
|
|
429
630
|
];
|
|
430
631
|
}
|
|
431
632
|
});
|
|
@@ -554,10 +755,6 @@ function hexToHSLString(hex) {
|
|
|
554
755
|
const { h, s, l } = hexToHSL(hex);
|
|
555
756
|
return `${h} ${s}% ${l}%`;
|
|
556
757
|
}
|
|
557
|
-
function mute(hex) {
|
|
558
|
-
const { h, s, l } = hexToHSL(hex);
|
|
559
|
-
return hslToHex(h, Math.min(s, 35), Math.min(l, 36));
|
|
560
|
-
}
|
|
561
758
|
function tint(hex, amount) {
|
|
562
759
|
const raw = hex.replace("#", "");
|
|
563
760
|
const full = raw.length === 3 ? raw[0] + raw[0] + raw[1] + raw[1] + raw[2] + raw[2] : raw;
|
|
@@ -1499,177 +1696,10 @@ var init_monokai = __esm({
|
|
|
1499
1696
|
}
|
|
1500
1697
|
});
|
|
1501
1698
|
|
|
1502
|
-
// src/palettes/mermaid-bridge.ts
|
|
1503
|
-
function buildMermaidThemeVars(colors, isDark) {
|
|
1504
|
-
const c = colors.colors;
|
|
1505
|
-
const accentOrder = [
|
|
1506
|
-
c.blue,
|
|
1507
|
-
c.red,
|
|
1508
|
-
c.green,
|
|
1509
|
-
c.yellow,
|
|
1510
|
-
c.purple,
|
|
1511
|
-
c.orange,
|
|
1512
|
-
c.teal,
|
|
1513
|
-
c.cyan,
|
|
1514
|
-
colors.secondary
|
|
1515
|
-
];
|
|
1516
|
-
const fills = isDark ? accentOrder.map(mute) : accentOrder;
|
|
1517
|
-
return {
|
|
1518
|
-
// ── Backgrounds ──
|
|
1519
|
-
background: isDark ? colors.overlay : colors.border,
|
|
1520
|
-
mainBkg: colors.surface,
|
|
1521
|
-
// ── Primary/Secondary/Tertiary nodes ──
|
|
1522
|
-
primaryColor: isDark ? colors.primary : colors.surface,
|
|
1523
|
-
primaryTextColor: colors.text,
|
|
1524
|
-
primaryBorderColor: isDark ? colors.secondary : colors.border,
|
|
1525
|
-
secondaryColor: colors.secondary,
|
|
1526
|
-
secondaryTextColor: contrastText(colors.secondary, colors.text, colors.bg),
|
|
1527
|
-
secondaryBorderColor: colors.primary,
|
|
1528
|
-
tertiaryColor: colors.accent,
|
|
1529
|
-
tertiaryTextColor: contrastText(colors.accent, colors.text, colors.bg),
|
|
1530
|
-
tertiaryBorderColor: colors.border,
|
|
1531
|
-
// ── Lines & text ──
|
|
1532
|
-
lineColor: colors.textMuted,
|
|
1533
|
-
textColor: colors.text,
|
|
1534
|
-
// ── Clusters ──
|
|
1535
|
-
clusterBkg: colors.bg,
|
|
1536
|
-
clusterBorder: isDark ? colors.border : colors.textMuted,
|
|
1537
|
-
titleColor: colors.text,
|
|
1538
|
-
// ── Labels ──
|
|
1539
|
-
edgeLabelBackground: "transparent",
|
|
1540
|
-
// ── Notes (sequence diagrams) ──
|
|
1541
|
-
noteBkgColor: colors.bg,
|
|
1542
|
-
noteTextColor: colors.text,
|
|
1543
|
-
noteBorderColor: isDark ? colors.border : colors.textMuted,
|
|
1544
|
-
// ── Actors (sequence diagrams) ──
|
|
1545
|
-
actorBkg: colors.surface,
|
|
1546
|
-
actorTextColor: colors.text,
|
|
1547
|
-
actorBorder: isDark ? colors.border : colors.textMuted,
|
|
1548
|
-
actorLineColor: colors.textMuted,
|
|
1549
|
-
// ── Signals (sequence diagrams) ──
|
|
1550
|
-
signalColor: colors.textMuted,
|
|
1551
|
-
signalTextColor: colors.text,
|
|
1552
|
-
// ── Labels ──
|
|
1553
|
-
labelColor: colors.text,
|
|
1554
|
-
labelTextColor: colors.text,
|
|
1555
|
-
labelBoxBkgColor: colors.surface,
|
|
1556
|
-
labelBoxBorderColor: isDark ? colors.border : colors.textMuted,
|
|
1557
|
-
// ── Loop boxes ──
|
|
1558
|
-
loopTextColor: colors.text,
|
|
1559
|
-
// ── Activation (sequence diagrams) ──
|
|
1560
|
-
activationBkgColor: isDark ? colors.overlay : colors.border,
|
|
1561
|
-
activationBorderColor: isDark ? colors.border : colors.textMuted,
|
|
1562
|
-
// ── Sequence numbers ──
|
|
1563
|
-
sequenceNumberColor: isDark ? colors.text : colors.bg,
|
|
1564
|
-
// ── State diagrams ──
|
|
1565
|
-
labelBackgroundColor: colors.surface,
|
|
1566
|
-
// ── Pie chart (9 slices) ──
|
|
1567
|
-
// Dark mode: use muted fills so light pieSectionTextColor stays readable
|
|
1568
|
-
...Object.fromEntries(
|
|
1569
|
-
(isDark ? fills : accentOrder).map((col, i) => [`pie${i + 1}`, col])
|
|
1570
|
-
),
|
|
1571
|
-
pieTitleTextColor: colors.text,
|
|
1572
|
-
pieSectionTextColor: isDark ? colors.text : colors.bg,
|
|
1573
|
-
pieLegendTextColor: colors.text,
|
|
1574
|
-
pieStrokeColor: "transparent",
|
|
1575
|
-
pieOuterStrokeWidth: "0px",
|
|
1576
|
-
pieOuterStrokeColor: "transparent",
|
|
1577
|
-
// ── cScale (9 tiers) — muted in dark mode ──
|
|
1578
|
-
...Object.fromEntries(fills.map((f, i) => [`cScale${i}`, f])),
|
|
1579
|
-
...Object.fromEntries(
|
|
1580
|
-
fills.map((_, i) => [
|
|
1581
|
-
`cScaleLabel${i}`,
|
|
1582
|
-
isDark ? colors.text : i < 2 || i > 6 ? colors.bg : colors.text
|
|
1583
|
-
])
|
|
1584
|
-
),
|
|
1585
|
-
// ── fillType (8 slots) ──
|
|
1586
|
-
...Object.fromEntries(
|
|
1587
|
-
[0, 1, 2, 3, 4, 5, 6, 7].map((i) => [
|
|
1588
|
-
`fillType${i}`,
|
|
1589
|
-
fills[i % fills.length]
|
|
1590
|
-
])
|
|
1591
|
-
),
|
|
1592
|
-
// ── Journey actors (6 slots) ──
|
|
1593
|
-
...Object.fromEntries(
|
|
1594
|
-
[c.red, c.green, c.yellow, c.purple, c.orange, c.teal].map((color, i) => [
|
|
1595
|
-
`actor${i}`,
|
|
1596
|
-
color
|
|
1597
|
-
])
|
|
1598
|
-
),
|
|
1599
|
-
// ── Flowchart ──
|
|
1600
|
-
nodeBorder: isDark ? colors.border : colors.textMuted,
|
|
1601
|
-
nodeTextColor: colors.text,
|
|
1602
|
-
// ── Gantt ──
|
|
1603
|
-
gridColor: isDark ? colors.textMuted : colors.border,
|
|
1604
|
-
doneTaskBkgColor: c.green,
|
|
1605
|
-
doneTaskBorderColor: isDark ? colors.border : colors.textMuted,
|
|
1606
|
-
activeTaskBkgColor: colors.secondary,
|
|
1607
|
-
activeTaskBorderColor: colors.primary,
|
|
1608
|
-
critBkgColor: c.orange,
|
|
1609
|
-
critBorderColor: c.red,
|
|
1610
|
-
taskBkgColor: colors.surface,
|
|
1611
|
-
taskBorderColor: isDark ? colors.border : colors.textMuted,
|
|
1612
|
-
taskTextColor: contrastText(colors.surface, colors.text, colors.bg),
|
|
1613
|
-
taskTextDarkColor: colors.bg,
|
|
1614
|
-
taskTextLightColor: colors.text,
|
|
1615
|
-
taskTextOutsideColor: colors.text,
|
|
1616
|
-
doneTaskTextColor: contrastText(c.green, colors.text, colors.bg),
|
|
1617
|
-
activeTaskTextColor: contrastText(colors.secondary, colors.text, colors.bg),
|
|
1618
|
-
critTaskTextColor: contrastText(c.orange, colors.text, colors.bg),
|
|
1619
|
-
sectionBkgColor: isDark ? shade(colors.primary, colors.bg, 0.6) : tint(colors.primary, 0.6),
|
|
1620
|
-
altSectionBkgColor: colors.bg,
|
|
1621
|
-
sectionBkgColor2: isDark ? shade(colors.primary, colors.bg, 0.6) : tint(colors.primary, 0.6),
|
|
1622
|
-
todayLineColor: c.yellow,
|
|
1623
|
-
// ── Quadrant ──
|
|
1624
|
-
quadrant1Fill: isDark ? shade(c.green, colors.bg, 0.75) : tint(c.green, 0.75),
|
|
1625
|
-
quadrant2Fill: isDark ? shade(c.blue, colors.bg, 0.75) : tint(c.blue, 0.75),
|
|
1626
|
-
quadrant3Fill: isDark ? shade(c.red, colors.bg, 0.75) : tint(c.red, 0.75),
|
|
1627
|
-
quadrant4Fill: isDark ? shade(c.yellow, colors.bg, 0.75) : tint(c.yellow, 0.75),
|
|
1628
|
-
quadrant1TextFill: colors.text,
|
|
1629
|
-
quadrant2TextFill: colors.text,
|
|
1630
|
-
quadrant3TextFill: colors.text,
|
|
1631
|
-
quadrant4TextFill: colors.text,
|
|
1632
|
-
quadrantPointFill: isDark ? c.cyan : c.blue,
|
|
1633
|
-
quadrantPointTextFill: colors.text,
|
|
1634
|
-
quadrantXAxisTextFill: colors.text,
|
|
1635
|
-
quadrantYAxisTextFill: colors.text,
|
|
1636
|
-
quadrantTitleFill: colors.text,
|
|
1637
|
-
quadrantInternalBorderStrokeFill: colors.border,
|
|
1638
|
-
quadrantExternalBorderStrokeFill: colors.border
|
|
1639
|
-
};
|
|
1640
|
-
}
|
|
1641
|
-
function buildThemeCSS(palette, isDark) {
|
|
1642
|
-
const base = `
|
|
1643
|
-
.branchLabelBkg { fill: transparent !important; stroke: transparent !important; }
|
|
1644
|
-
.commit-label-bkg { fill: transparent !important; stroke: transparent !important; }
|
|
1645
|
-
.tag-label-bkg { fill: transparent !important; stroke: transparent !important; }
|
|
1646
|
-
|
|
1647
|
-
/* GitGraph: ensure commit and branch label text matches palette */
|
|
1648
|
-
.commit-label { fill: ${palette.text} !important; }
|
|
1649
|
-
.branch-label { fill: ${palette.text} !important; }
|
|
1650
|
-
.tag-label { fill: ${palette.text} !important; }
|
|
1651
|
-
`;
|
|
1652
|
-
if (!isDark) return base;
|
|
1653
|
-
return base + `
|
|
1654
|
-
/* Flowchart: ensure node and edge label text is readable */
|
|
1655
|
-
.nodeLabel, .label { color: ${palette.text} !important; fill: ${palette.text} !important; }
|
|
1656
|
-
.edgeLabel { color: ${palette.text} !important; fill: ${palette.text} !important; }
|
|
1657
|
-
.edgeLabel .label { color: ${palette.text} !important; fill: ${palette.text} !important; }
|
|
1658
|
-
`;
|
|
1659
|
-
}
|
|
1660
|
-
var init_mermaid_bridge = __esm({
|
|
1661
|
-
"src/palettes/mermaid-bridge.ts"() {
|
|
1662
|
-
"use strict";
|
|
1663
|
-
init_color_utils();
|
|
1664
|
-
}
|
|
1665
|
-
});
|
|
1666
|
-
|
|
1667
1699
|
// src/palettes/index.ts
|
|
1668
1700
|
var palettes_exports = {};
|
|
1669
1701
|
__export(palettes_exports, {
|
|
1670
1702
|
boldPalette: () => boldPalette,
|
|
1671
|
-
buildMermaidThemeVars: () => buildMermaidThemeVars,
|
|
1672
|
-
buildThemeCSS: () => buildThemeCSS,
|
|
1673
1703
|
catppuccinPalette: () => catppuccinPalette,
|
|
1674
1704
|
contrastText: () => contrastText,
|
|
1675
1705
|
draculaPalette: () => draculaPalette,
|
|
@@ -1683,7 +1713,6 @@ __export(palettes_exports, {
|
|
|
1683
1713
|
hslToHex: () => hslToHex,
|
|
1684
1714
|
isValidHex: () => isValidHex,
|
|
1685
1715
|
monokaiPalette: () => monokaiPalette,
|
|
1686
|
-
mute: () => mute,
|
|
1687
1716
|
nordPalette: () => nordPalette,
|
|
1688
1717
|
oneDarkPalette: () => oneDarkPalette,
|
|
1689
1718
|
registerPalette: () => registerPalette,
|
|
@@ -1708,7 +1737,6 @@ var init_palettes = __esm({
|
|
|
1708
1737
|
init_tokyo_night();
|
|
1709
1738
|
init_dracula();
|
|
1710
1739
|
init_monokai();
|
|
1711
|
-
init_mermaid_bridge();
|
|
1712
1740
|
}
|
|
1713
1741
|
});
|
|
1714
1742
|
|
|
@@ -2100,7 +2128,7 @@ function measureLegendText(text, fontSize) {
|
|
|
2100
2128
|
}
|
|
2101
2129
|
return w;
|
|
2102
2130
|
}
|
|
2103
|
-
var LEGEND_HEIGHT, LEGEND_PILL_PAD, LEGEND_PILL_FONT_SIZE, LEGEND_CAPSULE_PAD, LEGEND_DOT_R, LEGEND_ENTRY_FONT_SIZE, LEGEND_ENTRY_DOT_GAP, LEGEND_ENTRY_TRAIL, LEGEND_GROUP_GAP, LEGEND_EYE_SIZE, LEGEND_EYE_GAP, LEGEND_ICON_W, LEGEND_MAX_ENTRY_ROWS, CHAR_W, DEFAULT_W, EYE_OPEN_PATH, EYE_CLOSED_PATH;
|
|
2131
|
+
var LEGEND_HEIGHT, LEGEND_PILL_PAD, LEGEND_PILL_FONT_SIZE, LEGEND_CAPSULE_PAD, LEGEND_DOT_R, LEGEND_ENTRY_FONT_SIZE, LEGEND_ENTRY_DOT_GAP, LEGEND_ENTRY_TRAIL, LEGEND_GROUP_GAP, LEGEND_EYE_SIZE, LEGEND_EYE_GAP, LEGEND_ICON_W, LEGEND_MAX_ENTRY_ROWS, CHAR_W, DEFAULT_W, EYE_OPEN_PATH, EYE_CLOSED_PATH, CONTROLS_ICON_PATH, LEGEND_TOGGLE_DOT_R, LEGEND_TOGGLE_OFF_OPACITY, LEGEND_GEAR_PILL_W;
|
|
2104
2132
|
var init_legend_constants = __esm({
|
|
2105
2133
|
"src/utils/legend-constants.ts"() {
|
|
2106
2134
|
"use strict";
|
|
@@ -2207,6 +2235,10 @@ var init_legend_constants = __esm({
|
|
|
2207
2235
|
DEFAULT_W = 0.56;
|
|
2208
2236
|
EYE_OPEN_PATH = "M1 7s2.5-5 6-5 6 5 6 5-2.5 5-6 5-6-5-6-5z M7 9.5a2.5 2.5 0 1 0 0-5 2.5 2.5 0 0 0 0 5z";
|
|
2209
2237
|
EYE_CLOSED_PATH = "M2.5 2.5l9 9 M1.5 7s2.2-4 5.5-4c1.2 0 2.2.5 3 1.1 M12.5 7s-2.2 4-5.5 4c-1.2 0-2.2-.5-3-1.1";
|
|
2238
|
+
CONTROLS_ICON_PATH = "M5.6 1.7L8.4 1.7L7.9 3.6L9.5 4.5L10.9 3.1L12.3 5.6L10.4 6.1L10.4 7.9L12.3 8.4L10.9 10.9L9.5 9.5L7.9 10.4L8.4 12.3L5.6 12.3L6.1 10.4L4.5 9.5L3.1 10.9L1.7 8.4L3.6 7.9L3.6 6.1L1.7 5.6L3.1 3.1L4.5 4.5L6.1 3.6ZM5 7a2 2 0 1 0 4 0a2 2 0 1 0-4 0Z";
|
|
2239
|
+
LEGEND_TOGGLE_DOT_R = LEGEND_DOT_R;
|
|
2240
|
+
LEGEND_TOGGLE_OFF_OPACITY = 0.4;
|
|
2241
|
+
LEGEND_GEAR_PILL_W = 14 + LEGEND_PILL_PAD;
|
|
2210
2242
|
}
|
|
2211
2243
|
});
|
|
2212
2244
|
|
|
@@ -2280,6 +2312,63 @@ function capsuleWidth(name, entries, containerWidth, addonWidth = 0) {
|
|
|
2280
2312
|
visibleEntries: entries.length
|
|
2281
2313
|
};
|
|
2282
2314
|
}
|
|
2315
|
+
function controlsGroupCapsuleWidth(toggles) {
|
|
2316
|
+
let w = LEGEND_CAPSULE_PAD * 2 + LEGEND_GEAR_PILL_W + 4;
|
|
2317
|
+
for (const t of toggles) {
|
|
2318
|
+
w += LEGEND_TOGGLE_DOT_R * 2 + LEGEND_ENTRY_DOT_GAP + measureLegendText(t.label, LEGEND_ENTRY_FONT_SIZE) + LEGEND_ENTRY_TRAIL;
|
|
2319
|
+
}
|
|
2320
|
+
return w;
|
|
2321
|
+
}
|
|
2322
|
+
function buildControlsGroupLayout(config, state) {
|
|
2323
|
+
const cg = config.controlsGroup;
|
|
2324
|
+
if (!cg || cg.toggles.length === 0) return void 0;
|
|
2325
|
+
const expanded = !!state.controlsExpanded;
|
|
2326
|
+
const pillH = LEGEND_HEIGHT - LEGEND_CAPSULE_PAD * 2;
|
|
2327
|
+
if (!expanded) {
|
|
2328
|
+
return {
|
|
2329
|
+
x: 0,
|
|
2330
|
+
y: 0,
|
|
2331
|
+
width: LEGEND_GEAR_PILL_W,
|
|
2332
|
+
height: LEGEND_HEIGHT,
|
|
2333
|
+
expanded: false,
|
|
2334
|
+
pill: { x: 0, y: 0, width: LEGEND_GEAR_PILL_W, height: LEGEND_HEIGHT },
|
|
2335
|
+
toggles: []
|
|
2336
|
+
};
|
|
2337
|
+
}
|
|
2338
|
+
const capsuleW = controlsGroupCapsuleWidth(cg.toggles);
|
|
2339
|
+
const toggleLayouts = [];
|
|
2340
|
+
let tx = LEGEND_CAPSULE_PAD + LEGEND_GEAR_PILL_W + 4;
|
|
2341
|
+
for (const toggle of cg.toggles) {
|
|
2342
|
+
const dotCx = tx + LEGEND_TOGGLE_DOT_R;
|
|
2343
|
+
const dotCy = LEGEND_HEIGHT / 2;
|
|
2344
|
+
const textX = tx + LEGEND_TOGGLE_DOT_R * 2 + LEGEND_ENTRY_DOT_GAP;
|
|
2345
|
+
const textY = LEGEND_HEIGHT / 2;
|
|
2346
|
+
toggleLayouts.push({
|
|
2347
|
+
id: toggle.id,
|
|
2348
|
+
label: toggle.label,
|
|
2349
|
+
active: toggle.active,
|
|
2350
|
+
dotCx,
|
|
2351
|
+
dotCy,
|
|
2352
|
+
textX,
|
|
2353
|
+
textY
|
|
2354
|
+
});
|
|
2355
|
+
tx += LEGEND_TOGGLE_DOT_R * 2 + LEGEND_ENTRY_DOT_GAP + measureLegendText(toggle.label, LEGEND_ENTRY_FONT_SIZE) + LEGEND_ENTRY_TRAIL;
|
|
2356
|
+
}
|
|
2357
|
+
return {
|
|
2358
|
+
x: 0,
|
|
2359
|
+
y: 0,
|
|
2360
|
+
width: capsuleW,
|
|
2361
|
+
height: LEGEND_HEIGHT,
|
|
2362
|
+
expanded: true,
|
|
2363
|
+
pill: {
|
|
2364
|
+
x: LEGEND_CAPSULE_PAD,
|
|
2365
|
+
y: LEGEND_CAPSULE_PAD,
|
|
2366
|
+
width: LEGEND_GEAR_PILL_W - LEGEND_CAPSULE_PAD * 2,
|
|
2367
|
+
height: pillH
|
|
2368
|
+
},
|
|
2369
|
+
toggles: toggleLayouts
|
|
2370
|
+
};
|
|
2371
|
+
}
|
|
2283
2372
|
function computeLegendLayout(config, state, containerWidth) {
|
|
2284
2373
|
const { groups, controls: configControls, mode } = config;
|
|
2285
2374
|
const isExport = mode === "inline";
|
|
@@ -2294,8 +2383,9 @@ function computeLegendLayout(config, state, containerWidth) {
|
|
|
2294
2383
|
activeCapsule: void 0
|
|
2295
2384
|
};
|
|
2296
2385
|
}
|
|
2386
|
+
const controlsGroupLayout = isExport ? void 0 : buildControlsGroupLayout(config, state);
|
|
2297
2387
|
const visibleGroups = config.showEmptyGroups ? groups : groups.filter((g) => g.entries.length > 0);
|
|
2298
|
-
if (visibleGroups.length === 0 && (!configControls || configControls.length === 0)) {
|
|
2388
|
+
if (visibleGroups.length === 0 && (!configControls || configControls.length === 0) && !controlsGroupLayout) {
|
|
2299
2389
|
return {
|
|
2300
2390
|
height: 0,
|
|
2301
2391
|
width: 0,
|
|
@@ -2359,7 +2449,8 @@ function computeLegendLayout(config, state, containerWidth) {
|
|
|
2359
2449
|
if (totalControlsW > 0) totalControlsW -= CONTROL_GAP;
|
|
2360
2450
|
}
|
|
2361
2451
|
const controlsSpace = totalControlsW > 0 ? totalControlsW + LEGEND_GROUP_GAP * 2 : 0;
|
|
2362
|
-
const
|
|
2452
|
+
const gearSpace = controlsGroupLayout ? controlsGroupLayout.width + LEGEND_GROUP_GAP : 0;
|
|
2453
|
+
const groupAvailW = containerWidth - controlsSpace - gearSpace;
|
|
2363
2454
|
const pills = [];
|
|
2364
2455
|
let activeCapsule;
|
|
2365
2456
|
for (const g of visibleGroups) {
|
|
@@ -2368,7 +2459,7 @@ function computeLegendLayout(config, state, containerWidth) {
|
|
|
2368
2459
|
if (isActive) {
|
|
2369
2460
|
activeCapsule = buildCapsuleLayout(
|
|
2370
2461
|
g,
|
|
2371
|
-
|
|
2462
|
+
groupAvailW,
|
|
2372
2463
|
config.capsulePillAddonWidth ?? 0
|
|
2373
2464
|
);
|
|
2374
2465
|
} else {
|
|
@@ -2391,7 +2482,8 @@ function computeLegendLayout(config, state, containerWidth) {
|
|
|
2391
2482
|
groupAvailW,
|
|
2392
2483
|
containerWidth,
|
|
2393
2484
|
totalControlsW,
|
|
2394
|
-
alignLeft
|
|
2485
|
+
alignLeft,
|
|
2486
|
+
controlsGroupLayout
|
|
2395
2487
|
);
|
|
2396
2488
|
const height = rows.length * LEGEND_HEIGHT;
|
|
2397
2489
|
const width = containerWidth;
|
|
@@ -2401,7 +2493,8 @@ function computeLegendLayout(config, state, containerWidth) {
|
|
|
2401
2493
|
rows,
|
|
2402
2494
|
activeCapsule,
|
|
2403
2495
|
controls: controlLayouts,
|
|
2404
|
-
pills
|
|
2496
|
+
pills,
|
|
2497
|
+
controlsGroup: controlsGroupLayout
|
|
2405
2498
|
};
|
|
2406
2499
|
}
|
|
2407
2500
|
function buildCapsuleLayout(group, containerWidth, addonWidth = 0) {
|
|
@@ -2465,19 +2558,27 @@ function buildCapsuleLayout(group, containerWidth, addonWidth = 0) {
|
|
|
2465
2558
|
addonX: addonWidth > 0 ? LEGEND_CAPSULE_PAD + pw + 4 : void 0
|
|
2466
2559
|
};
|
|
2467
2560
|
}
|
|
2468
|
-
function layoutRows(activeCapsule, pills, controls, groupAvailW, containerWidth, totalControlsW, alignLeft = false) {
|
|
2561
|
+
function layoutRows(activeCapsule, pills, controls, groupAvailW, containerWidth, totalControlsW, alignLeft = false, controlsGroup) {
|
|
2469
2562
|
const rows = [];
|
|
2470
2563
|
const groupItems = [];
|
|
2471
2564
|
if (activeCapsule) groupItems.push(activeCapsule);
|
|
2472
2565
|
groupItems.push(...pills);
|
|
2566
|
+
const gearW = controlsGroup ? controlsGroup.width + LEGEND_GROUP_GAP : 0;
|
|
2473
2567
|
let currentRowItems = [];
|
|
2474
2568
|
let currentRowW = 0;
|
|
2475
2569
|
let rowY = 0;
|
|
2476
2570
|
for (const item of groupItems) {
|
|
2477
2571
|
const itemW = item.width + LEGEND_GROUP_GAP;
|
|
2478
2572
|
if (currentRowW + item.width > groupAvailW && currentRowItems.length > 0) {
|
|
2479
|
-
if (!alignLeft)
|
|
2480
|
-
|
|
2573
|
+
if (!alignLeft) {
|
|
2574
|
+
const rowGearW = rows.length === 0 ? gearW : 0;
|
|
2575
|
+
centerRowItems(
|
|
2576
|
+
currentRowItems,
|
|
2577
|
+
containerWidth,
|
|
2578
|
+
totalControlsW,
|
|
2579
|
+
rowGearW
|
|
2580
|
+
);
|
|
2581
|
+
}
|
|
2481
2582
|
rows.push({ y: rowY, items: currentRowItems });
|
|
2482
2583
|
rowY += LEGEND_HEIGHT;
|
|
2483
2584
|
currentRowItems = [];
|
|
@@ -2505,19 +2606,32 @@ function layoutRows(activeCapsule, pills, controls, groupAvailW, containerWidth,
|
|
|
2505
2606
|
}
|
|
2506
2607
|
}
|
|
2507
2608
|
if (currentRowItems.length > 0) {
|
|
2508
|
-
centerRowItems(currentRowItems, containerWidth, totalControlsW);
|
|
2609
|
+
centerRowItems(currentRowItems, containerWidth, totalControlsW, gearW);
|
|
2509
2610
|
rows.push({ y: rowY, items: currentRowItems });
|
|
2510
2611
|
}
|
|
2612
|
+
if (controlsGroup) {
|
|
2613
|
+
const row0Items = rows[0]?.items ?? [];
|
|
2614
|
+
const groupItemsInRow0 = row0Items.filter(
|
|
2615
|
+
(it) => "groupName" in it
|
|
2616
|
+
);
|
|
2617
|
+
if (groupItemsInRow0.length > 0) {
|
|
2618
|
+
const last = groupItemsInRow0[groupItemsInRow0.length - 1];
|
|
2619
|
+
controlsGroup.x = last.x + last.width + LEGEND_GROUP_GAP;
|
|
2620
|
+
} else {
|
|
2621
|
+
controlsGroup.x = 0;
|
|
2622
|
+
}
|
|
2623
|
+
controlsGroup.y = 0;
|
|
2624
|
+
}
|
|
2511
2625
|
if (rows.length === 0) {
|
|
2512
2626
|
rows.push({ y: 0, items: [] });
|
|
2513
2627
|
}
|
|
2514
2628
|
return rows;
|
|
2515
2629
|
}
|
|
2516
|
-
function centerRowItems(items, containerWidth, totalControlsW) {
|
|
2630
|
+
function centerRowItems(items, containerWidth, totalControlsW, controlsGroupW = 0) {
|
|
2517
2631
|
const groupItems = items.filter((it) => "groupName" in it);
|
|
2518
2632
|
if (groupItems.length === 0) return;
|
|
2519
2633
|
const totalGroupW = groupItems.reduce((s, it) => s + it.width, 0) + (groupItems.length - 1) * LEGEND_GROUP_GAP;
|
|
2520
|
-
const availW = containerWidth - (totalControlsW > 0 ? totalControlsW + LEGEND_GROUP_GAP * 2 : 0);
|
|
2634
|
+
const availW = containerWidth - (totalControlsW > 0 ? totalControlsW + LEGEND_GROUP_GAP * 2 : 0) - controlsGroupW;
|
|
2521
2635
|
const offset = Math.max(0, (availW - totalGroupW) / 2);
|
|
2522
2636
|
let x = offset;
|
|
2523
2637
|
for (const item of groupItems) {
|
|
@@ -2575,6 +2689,17 @@ function renderLegendD3(container, config, state, palette, isDark, callbacks, co
|
|
|
2575
2689
|
for (const pill of currentLayout.pills) {
|
|
2576
2690
|
renderPill(legendG, pill, palette, groupBg, callbacks);
|
|
2577
2691
|
}
|
|
2692
|
+
if (currentLayout.controlsGroup) {
|
|
2693
|
+
renderControlsGroup(
|
|
2694
|
+
legendG,
|
|
2695
|
+
currentLayout.controlsGroup,
|
|
2696
|
+
palette,
|
|
2697
|
+
groupBg,
|
|
2698
|
+
pillBorder,
|
|
2699
|
+
callbacks,
|
|
2700
|
+
config
|
|
2701
|
+
);
|
|
2702
|
+
}
|
|
2578
2703
|
for (const ctrl of currentLayout.controls) {
|
|
2579
2704
|
renderControl(
|
|
2580
2705
|
legendG,
|
|
@@ -2689,6 +2814,57 @@ function renderControl(parent, ctrl, palette, _groupBg, pillBorder, _isDark, con
|
|
|
2689
2814
|
g.on("click", () => onClick());
|
|
2690
2815
|
}
|
|
2691
2816
|
}
|
|
2817
|
+
function renderControlsGroup(parent, layout, palette, groupBg, pillBorder, callbacks, config) {
|
|
2818
|
+
const g = parent.append("g").attr("transform", `translate(${layout.x},${layout.y})`).attr("data-legend-controls", layout.expanded ? "expanded" : "collapsed").attr("data-export-ignore", "true").style("cursor", "pointer");
|
|
2819
|
+
if (!layout.expanded) {
|
|
2820
|
+
g.append("rect").attr("width", layout.width).attr("height", layout.height).attr("rx", layout.height / 2).attr("fill", groupBg);
|
|
2821
|
+
const iconSize = 14;
|
|
2822
|
+
const iconX = (layout.width - iconSize) / 2;
|
|
2823
|
+
const iconY = (layout.height - iconSize) / 2;
|
|
2824
|
+
g.append("path").attr("d", CONTROLS_ICON_PATH).attr("transform", `translate(${iconX},${iconY})`).attr("fill", palette.textMuted).attr("fill-rule", "evenodd").attr("pointer-events", "none");
|
|
2825
|
+
if (callbacks?.onControlsExpand) {
|
|
2826
|
+
const cb = callbacks.onControlsExpand;
|
|
2827
|
+
g.on("click", () => cb());
|
|
2828
|
+
}
|
|
2829
|
+
} else {
|
|
2830
|
+
const pill = layout.pill;
|
|
2831
|
+
g.append("rect").attr("width", layout.width).attr("height", layout.height).attr("rx", LEGEND_HEIGHT / 2).attr("fill", groupBg);
|
|
2832
|
+
const pillG = g.append("g").attr("class", "controls-gear-pill").style("cursor", "pointer");
|
|
2833
|
+
pillG.append("rect").attr("x", pill.x).attr("y", pill.y).attr("width", pill.width).attr("height", pill.height).attr("rx", pill.height / 2).attr("fill", palette.bg);
|
|
2834
|
+
pillG.append("rect").attr("x", pill.x).attr("y", pill.y).attr("width", pill.width).attr("height", pill.height).attr("rx", pill.height / 2).attr("fill", "none").attr("stroke", pillBorder).attr("stroke-width", 0.75);
|
|
2835
|
+
const iconSize = 14;
|
|
2836
|
+
const iconX = pill.x + (pill.width - iconSize) / 2;
|
|
2837
|
+
const iconY = pill.y + (pill.height - iconSize) / 2;
|
|
2838
|
+
pillG.append("path").attr("d", CONTROLS_ICON_PATH).attr("transform", `translate(${iconX},${iconY})`).attr("fill", palette.text).attr("fill-rule", "evenodd").attr("pointer-events", "none");
|
|
2839
|
+
if (callbacks?.onControlsExpand) {
|
|
2840
|
+
const cb = callbacks.onControlsExpand;
|
|
2841
|
+
pillG.on("click", (event) => {
|
|
2842
|
+
event.stopPropagation();
|
|
2843
|
+
cb();
|
|
2844
|
+
});
|
|
2845
|
+
}
|
|
2846
|
+
const toggles = config?.controlsGroup?.toggles ?? [];
|
|
2847
|
+
for (const tl of layout.toggles) {
|
|
2848
|
+
const toggle = toggles.find((t) => t.id === tl.id);
|
|
2849
|
+
const entryG = g.append("g").attr("data-controls-toggle", tl.id).style("cursor", "pointer");
|
|
2850
|
+
if (tl.active) {
|
|
2851
|
+
entryG.append("circle").attr("cx", tl.dotCx).attr("cy", tl.dotCy).attr("r", LEGEND_TOGGLE_DOT_R).attr("fill", palette.primary ?? palette.text);
|
|
2852
|
+
} else {
|
|
2853
|
+
entryG.append("circle").attr("cx", tl.dotCx).attr("cy", tl.dotCy).attr("r", LEGEND_TOGGLE_DOT_R).attr("fill", "none").attr("stroke", palette.textMuted).attr("stroke-width", 1);
|
|
2854
|
+
}
|
|
2855
|
+
entryG.append("text").attr("x", tl.textX).attr("y", tl.textY).attr("dominant-baseline", "central").attr("font-size", LEGEND_ENTRY_FONT_SIZE).attr("fill", palette.textMuted).attr("opacity", tl.active ? 1 : LEGEND_TOGGLE_OFF_OPACITY).attr("font-family", FONT_FAMILY).text(tl.label);
|
|
2856
|
+
if (callbacks?.onControlsToggle && toggle) {
|
|
2857
|
+
const cb = callbacks.onControlsToggle;
|
|
2858
|
+
const id = tl.id;
|
|
2859
|
+
const newActive = !tl.active;
|
|
2860
|
+
entryG.on("click", (event) => {
|
|
2861
|
+
event.stopPropagation();
|
|
2862
|
+
cb(id, newActive);
|
|
2863
|
+
});
|
|
2864
|
+
}
|
|
2865
|
+
}
|
|
2866
|
+
}
|
|
2867
|
+
}
|
|
2692
2868
|
var init_legend_d3 = __esm({
|
|
2693
2869
|
"src/utils/legend-d3.ts"() {
|
|
2694
2870
|
"use strict";
|
|
@@ -2985,61 +3161,6 @@ var init_participant_inference = __esm({
|
|
|
2985
3161
|
}
|
|
2986
3162
|
});
|
|
2987
3163
|
|
|
2988
|
-
// src/utils/arrows.ts
|
|
2989
|
-
function parseArrow(line10) {
|
|
2990
|
-
if (BIDI_SYNC_RE.test(line10) || BIDI_ASYNC_RE.test(line10)) {
|
|
2991
|
-
return {
|
|
2992
|
-
error: "Bidirectional arrows are no longer supported. Use two separate lines: 'A -msg-> B' and 'B -msg-> A'"
|
|
2993
|
-
};
|
|
2994
|
-
}
|
|
2995
|
-
if (RETURN_SYNC_LABELED_RE.test(line10) || RETURN_ASYNC_LABELED_RE.test(line10)) {
|
|
2996
|
-
const m = line10.match(RETURN_SYNC_LABELED_RE) ?? line10.match(RETURN_ASYNC_LABELED_RE);
|
|
2997
|
-
const from = m[3];
|
|
2998
|
-
const to = m[1];
|
|
2999
|
-
const label = m[2].trim();
|
|
3000
|
-
return {
|
|
3001
|
-
error: `Left-pointing arrows are no longer supported. Write '${from} -${label}-> ${to}' instead`
|
|
3002
|
-
};
|
|
3003
|
-
}
|
|
3004
|
-
const patterns = [
|
|
3005
|
-
{ re: SYNC_LABELED_RE, async: false },
|
|
3006
|
-
{ re: ASYNC_LABELED_RE, async: true }
|
|
3007
|
-
];
|
|
3008
|
-
for (const { re, async: isAsync } of patterns) {
|
|
3009
|
-
const m = line10.match(re);
|
|
3010
|
-
if (!m) continue;
|
|
3011
|
-
const label = m[2].trim();
|
|
3012
|
-
if (!label) return null;
|
|
3013
|
-
for (const arrow of ARROW_CHARS) {
|
|
3014
|
-
if (label.includes(arrow)) {
|
|
3015
|
-
return {
|
|
3016
|
-
error: "Arrow characters (->, ~>) are not allowed inside labels"
|
|
3017
|
-
};
|
|
3018
|
-
}
|
|
3019
|
-
}
|
|
3020
|
-
return {
|
|
3021
|
-
from: m[1],
|
|
3022
|
-
to: m[3],
|
|
3023
|
-
label,
|
|
3024
|
-
async: isAsync
|
|
3025
|
-
};
|
|
3026
|
-
}
|
|
3027
|
-
return null;
|
|
3028
|
-
}
|
|
3029
|
-
var SYNC_LABELED_RE, ASYNC_LABELED_RE, RETURN_SYNC_LABELED_RE, RETURN_ASYNC_LABELED_RE, BIDI_SYNC_RE, BIDI_ASYNC_RE, ARROW_CHARS;
|
|
3030
|
-
var init_arrows = __esm({
|
|
3031
|
-
"src/utils/arrows.ts"() {
|
|
3032
|
-
"use strict";
|
|
3033
|
-
SYNC_LABELED_RE = /^(.+?)\s*-(.+)->\s*(.+)$/;
|
|
3034
|
-
ASYNC_LABELED_RE = /^(.+?)\s*~(.+)~>\s*(.+)$/;
|
|
3035
|
-
RETURN_SYNC_LABELED_RE = /^(.+?)\s*<-(.+)-\s*(.+)$/;
|
|
3036
|
-
RETURN_ASYNC_LABELED_RE = /^(.+?)\s*<~(.+)~\s*(.+)$/;
|
|
3037
|
-
BIDI_SYNC_RE = /^(.+?)\s*<-(.+)->\s*(.+)$/;
|
|
3038
|
-
BIDI_ASYNC_RE = /^(.+?)\s*<~(.+)~>\s*(.+)$/;
|
|
3039
|
-
ARROW_CHARS = ["->", "~>"];
|
|
3040
|
-
}
|
|
3041
|
-
});
|
|
3042
|
-
|
|
3043
3164
|
// src/sequence/parser.ts
|
|
3044
3165
|
var parser_exports = {};
|
|
3045
3166
|
__export(parser_exports, {
|
|
@@ -3242,7 +3363,13 @@ function parseSequenceDgmo(content) {
|
|
|
3242
3363
|
const groupName = groupMatch[1].trim();
|
|
3243
3364
|
const groupColor = groupMatch[2]?.trim();
|
|
3244
3365
|
let groupMeta;
|
|
3245
|
-
|
|
3366
|
+
let afterBracket = groupMatch[3]?.trim() || "";
|
|
3367
|
+
let isCollapsed = false;
|
|
3368
|
+
const collapseMatch = afterBracket.match(/^collapse\b/i);
|
|
3369
|
+
if (collapseMatch) {
|
|
3370
|
+
isCollapsed = true;
|
|
3371
|
+
afterBracket = afterBracket.slice(collapseMatch[0].length).trim();
|
|
3372
|
+
}
|
|
3246
3373
|
if (afterBracket.startsWith("|")) {
|
|
3247
3374
|
const segments = afterBracket.split("|");
|
|
3248
3375
|
const meta = parsePipeMetadata(
|
|
@@ -3263,7 +3390,8 @@ function parseSequenceDgmo(content) {
|
|
|
3263
3390
|
name: groupName,
|
|
3264
3391
|
participantIds: [],
|
|
3265
3392
|
lineNumber,
|
|
3266
|
-
...groupMeta ? { metadata: groupMeta } : {}
|
|
3393
|
+
...groupMeta ? { metadata: groupMeta } : {},
|
|
3394
|
+
...isCollapsed ? { collapsed: true } : {}
|
|
3267
3395
|
};
|
|
3268
3396
|
result.groups.push(activeGroup);
|
|
3269
3397
|
continue;
|
|
@@ -3585,8 +3713,11 @@ function parseSequenceDgmo(content) {
|
|
|
3585
3713
|
}
|
|
3586
3714
|
if (labeledArrow) {
|
|
3587
3715
|
contentStarted = true;
|
|
3588
|
-
const { from, to, label, async: isAsync } = labeledArrow;
|
|
3716
|
+
const { from, to, label: rawLabel, async: isAsync } = labeledArrow;
|
|
3589
3717
|
lastMsgFrom = from;
|
|
3718
|
+
const labelResult = parseInArrowLabel(rawLabel, lineNumber);
|
|
3719
|
+
labelResult.diagnostics.forEach((d) => result.diagnostics.push(d));
|
|
3720
|
+
const label = labelResult.label ?? rawLabel;
|
|
3590
3721
|
const msg = {
|
|
3591
3722
|
from,
|
|
3592
3723
|
to,
|
|
@@ -3986,42 +4117,52 @@ function parseNodeRef(text, palette) {
|
|
|
3986
4117
|
}
|
|
3987
4118
|
function splitArrows(line10) {
|
|
3988
4119
|
const segments = [];
|
|
3989
|
-
let lastIndex = 0;
|
|
3990
4120
|
const arrowPositions = [];
|
|
3991
4121
|
let searchFrom = 0;
|
|
4122
|
+
let scanFloor = 0;
|
|
3992
4123
|
while (searchFrom < line10.length) {
|
|
3993
4124
|
const idx = line10.indexOf("->", searchFrom);
|
|
3994
4125
|
if (idx === -1) break;
|
|
3995
|
-
let
|
|
4126
|
+
let runStart = idx;
|
|
4127
|
+
while (runStart > scanFloor && line10[runStart - 1] === "-") runStart--;
|
|
4128
|
+
const arrowEnd = idx + 2;
|
|
4129
|
+
let arrowStart;
|
|
3996
4130
|
let label;
|
|
3997
4131
|
let color;
|
|
3998
|
-
|
|
3999
|
-
|
|
4000
|
-
|
|
4001
|
-
|
|
4002
|
-
|
|
4003
|
-
|
|
4004
|
-
|
|
4005
|
-
if (arrowContent.endsWith("-"))
|
|
4006
|
-
arrowContent = arrowContent.slice(0, -1);
|
|
4007
|
-
const colorMatch = arrowContent.match(/\(([^)]+)\)\s*$/);
|
|
4008
|
-
if (colorMatch) {
|
|
4009
|
-
color = colorMatch[1].trim();
|
|
4010
|
-
const labelPart = arrowContent.substring(0, colorMatch.index).trim();
|
|
4011
|
-
if (labelPart) label = labelPart;
|
|
4012
|
-
} else {
|
|
4013
|
-
const labelPart = arrowContent.trim();
|
|
4014
|
-
if (labelPart) label = labelPart;
|
|
4015
|
-
}
|
|
4016
|
-
arrowStart = scanBack;
|
|
4132
|
+
let openingStart = -1;
|
|
4133
|
+
for (let i = scanFloor; i < runStart; i++) {
|
|
4134
|
+
if (line10[i] !== "-") continue;
|
|
4135
|
+
const prevIsWsOrFloor = i === 0 || i === scanFloor || /\s/.test(line10[i - 1]);
|
|
4136
|
+
if (prevIsWsOrFloor) {
|
|
4137
|
+
openingStart = i;
|
|
4138
|
+
break;
|
|
4017
4139
|
}
|
|
4018
4140
|
}
|
|
4019
|
-
|
|
4020
|
-
|
|
4141
|
+
if (openingStart !== -1) {
|
|
4142
|
+
let openingEnd = openingStart;
|
|
4143
|
+
while (openingEnd < runStart && line10[openingEnd] === "-") openingEnd++;
|
|
4144
|
+
const arrowContent = line10.substring(openingEnd, runStart);
|
|
4145
|
+
const colorMatch = arrowContent.match(/\(([^)]+)\)\s*$/);
|
|
4146
|
+
if (colorMatch) {
|
|
4147
|
+
color = colorMatch[1].trim();
|
|
4148
|
+
const labelPart = arrowContent.substring(0, colorMatch.index).trim();
|
|
4149
|
+
if (labelPart) label = labelPart;
|
|
4150
|
+
} else {
|
|
4151
|
+
const labelPart = arrowContent.trim();
|
|
4152
|
+
if (labelPart) label = labelPart;
|
|
4153
|
+
}
|
|
4154
|
+
arrowStart = openingStart;
|
|
4155
|
+
} else {
|
|
4156
|
+
arrowStart = runStart;
|
|
4157
|
+
}
|
|
4158
|
+
arrowPositions.push({ start: arrowStart, end: arrowEnd, label, color });
|
|
4159
|
+
searchFrom = arrowEnd;
|
|
4160
|
+
scanFloor = arrowEnd;
|
|
4021
4161
|
}
|
|
4022
4162
|
if (arrowPositions.length === 0) {
|
|
4023
4163
|
return [line10];
|
|
4024
4164
|
}
|
|
4165
|
+
let lastIndex = 0;
|
|
4025
4166
|
for (let i = 0; i < arrowPositions.length; i++) {
|
|
4026
4167
|
const arrow = arrowPositions[i];
|
|
4027
4168
|
const beforeText = line10.substring(lastIndex, arrow.start).trim();
|
|
@@ -4044,20 +4185,26 @@ function splitArrows(line10) {
|
|
|
4044
4185
|
}
|
|
4045
4186
|
function parseArrowToken(token, palette, lineNumber, diagnostics) {
|
|
4046
4187
|
if (token === "->") return {};
|
|
4047
|
-
const
|
|
4048
|
-
if (
|
|
4049
|
-
|
|
4050
|
-
|
|
4051
|
-
|
|
4052
|
-
|
|
4053
|
-
|
|
4054
|
-
|
|
4055
|
-
|
|
4056
|
-
|
|
4188
|
+
const bareParen = token.match(/^-(\([A-Za-z]+\))->$/);
|
|
4189
|
+
if (bareParen) {
|
|
4190
|
+
const colorName = matchColorParens(bareParen[1]);
|
|
4191
|
+
if (colorName) {
|
|
4192
|
+
return {
|
|
4193
|
+
color: resolveColorWithDiagnostic(
|
|
4194
|
+
colorName,
|
|
4195
|
+
lineNumber,
|
|
4196
|
+
diagnostics,
|
|
4197
|
+
palette
|
|
4198
|
+
)
|
|
4199
|
+
};
|
|
4200
|
+
}
|
|
4057
4201
|
}
|
|
4058
4202
|
const m = token.match(/^-(.+?)(?:\(([^)]+)\))?->$/);
|
|
4059
4203
|
if (m) {
|
|
4060
|
-
const
|
|
4204
|
+
const rawLabel = m[1] ?? "";
|
|
4205
|
+
const labelResult = parseInArrowLabel(rawLabel, lineNumber);
|
|
4206
|
+
diagnostics.push(...labelResult.diagnostics);
|
|
4207
|
+
const label = labelResult.label;
|
|
4061
4208
|
let color = m[2] ? resolveColorWithDiagnostic(
|
|
4062
4209
|
m[2].trim(),
|
|
4063
4210
|
lineNumber,
|
|
@@ -4285,6 +4432,7 @@ var init_flowchart_parser = __esm({
|
|
|
4285
4432
|
"use strict";
|
|
4286
4433
|
init_colors();
|
|
4287
4434
|
init_diagnostics();
|
|
4435
|
+
init_arrows();
|
|
4288
4436
|
init_parsing();
|
|
4289
4437
|
NODE_ID_RE = /^([a-zA-Z_][\w-]*)[\s([</{]/;
|
|
4290
4438
|
}
|
|
@@ -4300,35 +4448,45 @@ function splitArrows2(line10) {
|
|
|
4300
4448
|
const segments = [];
|
|
4301
4449
|
const arrowPositions = [];
|
|
4302
4450
|
let searchFrom = 0;
|
|
4451
|
+
let scanFloor = 0;
|
|
4303
4452
|
while (searchFrom < line10.length) {
|
|
4304
4453
|
const idx = line10.indexOf("->", searchFrom);
|
|
4305
4454
|
if (idx === -1) break;
|
|
4306
|
-
let
|
|
4455
|
+
let runStart = idx;
|
|
4456
|
+
while (runStart > scanFloor && line10[runStart - 1] === "-") runStart--;
|
|
4457
|
+
const arrowEnd = idx + 2;
|
|
4458
|
+
let arrowStart;
|
|
4307
4459
|
let label;
|
|
4308
4460
|
let color;
|
|
4309
|
-
|
|
4310
|
-
|
|
4311
|
-
|
|
4312
|
-
|
|
4313
|
-
|
|
4314
|
-
|
|
4315
|
-
|
|
4316
|
-
if (arrowContent.endsWith("-"))
|
|
4317
|
-
arrowContent = arrowContent.slice(0, -1);
|
|
4318
|
-
const colorMatch = arrowContent.match(/\(([^)]+)\)\s*$/);
|
|
4319
|
-
if (colorMatch) {
|
|
4320
|
-
color = colorMatch[1].trim();
|
|
4321
|
-
const labelPart = arrowContent.substring(0, colorMatch.index).trim();
|
|
4322
|
-
if (labelPart) label = labelPart;
|
|
4323
|
-
} else {
|
|
4324
|
-
const labelPart = arrowContent.trim();
|
|
4325
|
-
if (labelPart) label = labelPart;
|
|
4326
|
-
}
|
|
4327
|
-
arrowStart = scanBack;
|
|
4461
|
+
let openingStart = -1;
|
|
4462
|
+
for (let i = scanFloor; i < runStart; i++) {
|
|
4463
|
+
if (line10[i] !== "-") continue;
|
|
4464
|
+
const prevIsWsOrFloor = i === 0 || i === scanFloor || /\s/.test(line10[i - 1]);
|
|
4465
|
+
if (prevIsWsOrFloor) {
|
|
4466
|
+
openingStart = i;
|
|
4467
|
+
break;
|
|
4328
4468
|
}
|
|
4329
4469
|
}
|
|
4330
|
-
|
|
4331
|
-
|
|
4470
|
+
if (openingStart !== -1) {
|
|
4471
|
+
let openingEnd = openingStart;
|
|
4472
|
+
while (openingEnd < runStart && line10[openingEnd] === "-") openingEnd++;
|
|
4473
|
+
const arrowContent = line10.substring(openingEnd, runStart);
|
|
4474
|
+
const colorMatch = arrowContent.match(/\(([^)]+)\)\s*$/);
|
|
4475
|
+
if (colorMatch) {
|
|
4476
|
+
color = colorMatch[1].trim();
|
|
4477
|
+
const labelPart = arrowContent.substring(0, colorMatch.index).trim();
|
|
4478
|
+
if (labelPart) label = labelPart;
|
|
4479
|
+
} else {
|
|
4480
|
+
const labelPart = arrowContent.trim();
|
|
4481
|
+
if (labelPart) label = labelPart;
|
|
4482
|
+
}
|
|
4483
|
+
arrowStart = openingStart;
|
|
4484
|
+
} else {
|
|
4485
|
+
arrowStart = runStart;
|
|
4486
|
+
}
|
|
4487
|
+
arrowPositions.push({ start: arrowStart, end: arrowEnd, label, color });
|
|
4488
|
+
searchFrom = arrowEnd;
|
|
4489
|
+
scanFloor = arrowEnd;
|
|
4332
4490
|
}
|
|
4333
4491
|
if (arrowPositions.length === 0) return [line10];
|
|
4334
4492
|
let lastIndex = 0;
|
|
@@ -4350,19 +4508,26 @@ function splitArrows2(line10) {
|
|
|
4350
4508
|
}
|
|
4351
4509
|
function parseArrowToken2(token, palette, lineNumber, diagnostics) {
|
|
4352
4510
|
if (token === "->") return {};
|
|
4353
|
-
const
|
|
4354
|
-
if (
|
|
4355
|
-
|
|
4356
|
-
|
|
4357
|
-
|
|
4358
|
-
|
|
4359
|
-
|
|
4360
|
-
|
|
4361
|
-
|
|
4362
|
-
|
|
4511
|
+
const bareParen = token.match(/^-(\([A-Za-z]+\))->$/);
|
|
4512
|
+
if (bareParen) {
|
|
4513
|
+
const colorName = matchColorParens(bareParen[1]);
|
|
4514
|
+
if (colorName) {
|
|
4515
|
+
return {
|
|
4516
|
+
color: resolveColorWithDiagnostic(
|
|
4517
|
+
colorName,
|
|
4518
|
+
lineNumber,
|
|
4519
|
+
diagnostics,
|
|
4520
|
+
palette
|
|
4521
|
+
)
|
|
4522
|
+
};
|
|
4523
|
+
}
|
|
4524
|
+
}
|
|
4363
4525
|
const m = token.match(/^-(.+?)(?:\(([^)]+)\))?->$/);
|
|
4364
4526
|
if (m) {
|
|
4365
|
-
const
|
|
4527
|
+
const rawLabel = m[1] ?? "";
|
|
4528
|
+
const labelResult = parseInArrowLabel(rawLabel, lineNumber);
|
|
4529
|
+
diagnostics.push(...labelResult.diagnostics);
|
|
4530
|
+
const label = labelResult.label;
|
|
4366
4531
|
const color = m[2] ? resolveColorWithDiagnostic(
|
|
4367
4532
|
m[2].trim(),
|
|
4368
4533
|
lineNumber,
|
|
@@ -4603,6 +4768,7 @@ var init_state_parser = __esm({
|
|
|
4603
4768
|
"use strict";
|
|
4604
4769
|
init_colors();
|
|
4605
4770
|
init_diagnostics();
|
|
4771
|
+
init_arrows();
|
|
4606
4772
|
init_parsing();
|
|
4607
4773
|
PSEUDOSTATE_ID = "pseudostate:[*]";
|
|
4608
4774
|
PSEUDOSTATE_LABEL = "[*]";
|
|
@@ -4759,6 +4925,11 @@ function parseClassDiagram(content, palette) {
|
|
|
4759
4925
|
const targetName = indentRel[2];
|
|
4760
4926
|
const label = indentRel[3]?.trim();
|
|
4761
4927
|
getOrCreateClass(targetName, lineNumber);
|
|
4928
|
+
if (label) {
|
|
4929
|
+
result.diagnostics.push(
|
|
4930
|
+
...validateLabelCharacters(label, lineNumber)
|
|
4931
|
+
);
|
|
4932
|
+
}
|
|
4762
4933
|
result.relationships.push({
|
|
4763
4934
|
source: currentClass.id,
|
|
4764
4935
|
target: classId(targetName),
|
|
@@ -4933,6 +5104,7 @@ var init_parser2 = __esm({
|
|
|
4933
5104
|
"use strict";
|
|
4934
5105
|
init_colors();
|
|
4935
5106
|
init_diagnostics();
|
|
5107
|
+
init_arrows();
|
|
4936
5108
|
init_parsing();
|
|
4937
5109
|
CLASS_DECL_RE = /^(?:(abstract|interface|enum)\s+)?([A-Z][A-Za-z0-9_]*)(?:\s+(extends|implements)\s+([A-Z][A-Za-z0-9_]*))?(?:\s+\[(abstract|interface|enum)\])?(?:\s+\(([^)]+)\))?\s*$/;
|
|
4938
5110
|
INDENT_REL_ARROW_RE = /^(--\|>|\.\.\|>|\*--|o--|\.\.>|->)\s*([A-Z][A-Za-z0-9_]*)(?:\s+:?\s*(.+))?$/;
|
|
@@ -4972,12 +5144,18 @@ function parseRelationship(trimmed, lineNumber, pushError) {
|
|
|
4972
5144
|
const fromCard = parseCardSide(sym[2]);
|
|
4973
5145
|
const toCard = parseCardSide(sym[3]);
|
|
4974
5146
|
if (fromCard && toCard) {
|
|
5147
|
+
const label = sym[5]?.trim();
|
|
5148
|
+
if (label) {
|
|
5149
|
+
validateLabelCharacters(label, lineNumber).forEach(
|
|
5150
|
+
(d) => pushError(d.line, d.message)
|
|
5151
|
+
);
|
|
5152
|
+
}
|
|
4975
5153
|
return {
|
|
4976
5154
|
source: sym[1],
|
|
4977
5155
|
target: sym[4],
|
|
4978
5156
|
from: fromCard,
|
|
4979
5157
|
to: toCard,
|
|
4980
|
-
label
|
|
5158
|
+
label
|
|
4981
5159
|
};
|
|
4982
5160
|
}
|
|
4983
5161
|
}
|
|
@@ -5140,11 +5318,17 @@ function parseERDiagram(content, palette) {
|
|
|
5140
5318
|
if (fromCard && toCard) {
|
|
5141
5319
|
const targetName = indentRel[4];
|
|
5142
5320
|
getOrCreateTable(targetName, lineNumber);
|
|
5321
|
+
const rawLabel = indentRel[2]?.trim();
|
|
5322
|
+
if (rawLabel) {
|
|
5323
|
+
result.diagnostics.push(
|
|
5324
|
+
...validateLabelCharacters(rawLabel, lineNumber)
|
|
5325
|
+
);
|
|
5326
|
+
}
|
|
5143
5327
|
result.relationships.push({
|
|
5144
5328
|
source: currentTable.id,
|
|
5145
5329
|
target: tableId(targetName),
|
|
5146
5330
|
cardinality: { from: fromCard, to: toCard },
|
|
5147
|
-
...
|
|
5331
|
+
...rawLabel && { label: rawLabel },
|
|
5148
5332
|
lineNumber
|
|
5149
5333
|
});
|
|
5150
5334
|
}
|
|
@@ -5308,6 +5492,7 @@ var init_parser3 = __esm({
|
|
|
5308
5492
|
"use strict";
|
|
5309
5493
|
init_colors();
|
|
5310
5494
|
init_diagnostics();
|
|
5495
|
+
init_arrows();
|
|
5311
5496
|
init_parsing();
|
|
5312
5497
|
init_tag_groups();
|
|
5313
5498
|
TABLE_DECL_RE = /^([a-zA-Z_]\w*)(?:\s*\(([^)]+)\))?(?:\s*\|(.+))?$/;
|
|
@@ -5810,7 +5995,28 @@ var init_legend_svg = __esm({
|
|
|
5810
5995
|
});
|
|
5811
5996
|
|
|
5812
5997
|
// src/echarts.ts
|
|
5813
|
-
import * as echarts from "echarts";
|
|
5998
|
+
import * as echarts from "echarts/core";
|
|
5999
|
+
import {
|
|
6000
|
+
BarChart,
|
|
6001
|
+
LineChart,
|
|
6002
|
+
PieChart,
|
|
6003
|
+
ScatterChart,
|
|
6004
|
+
RadarChart,
|
|
6005
|
+
SankeyChart,
|
|
6006
|
+
GraphChart,
|
|
6007
|
+
HeatmapChart,
|
|
6008
|
+
FunnelChart
|
|
6009
|
+
} from "echarts/charts";
|
|
6010
|
+
import {
|
|
6011
|
+
GridComponent,
|
|
6012
|
+
TitleComponent,
|
|
6013
|
+
TooltipComponent,
|
|
6014
|
+
LegendComponent,
|
|
6015
|
+
RadarComponent,
|
|
6016
|
+
VisualMapComponent,
|
|
6017
|
+
GraphicComponent
|
|
6018
|
+
} from "echarts/components";
|
|
6019
|
+
import { SVGRenderer } from "echarts/renderers";
|
|
5814
6020
|
function parseScatterRow(line10, palette, currentCategory, lineNumber) {
|
|
5815
6021
|
const dataRow = parseDataRowValues(line10, { multiValue: true });
|
|
5816
6022
|
if (!dataRow || dataRow.values.length < 2) return null;
|
|
@@ -7829,7 +8035,7 @@ function buildBarStackedOption(parsed, textColor, axisLineColor, splitLineColor,
|
|
|
7829
8035
|
series
|
|
7830
8036
|
};
|
|
7831
8037
|
}
|
|
7832
|
-
async function renderExtendedChartForExport(content, theme, palette
|
|
8038
|
+
async function renderExtendedChartForExport(content, theme, palette) {
|
|
7833
8039
|
const isDark = theme === "dark";
|
|
7834
8040
|
const { getPalette: getPalette2 } = await Promise.resolve().then(() => (init_palettes(), palettes_exports));
|
|
7835
8041
|
const effectivePalette = palette ?? (isDark ? getPalette2("nord").dark : getPalette2("nord").light);
|
|
@@ -7900,10 +8106,6 @@ async function renderExtendedChartForExport(content, theme, palette, options) {
|
|
|
7900
8106
|
`$1<g transform="translate(0,${legendY})">${legendSvgStr}</g>`
|
|
7901
8107
|
);
|
|
7902
8108
|
}
|
|
7903
|
-
if (options?.branding !== false) {
|
|
7904
|
-
const brandColor = theme === "transparent" ? "#888" : effectivePalette.textMuted;
|
|
7905
|
-
result = injectBranding(result, brandColor);
|
|
7906
|
-
}
|
|
7907
8109
|
return result;
|
|
7908
8110
|
} finally {
|
|
7909
8111
|
chart.dispose();
|
|
@@ -7914,7 +8116,6 @@ var init_echarts = __esm({
|
|
|
7914
8116
|
"src/echarts.ts"() {
|
|
7915
8117
|
"use strict";
|
|
7916
8118
|
init_fonts();
|
|
7917
|
-
init_branding();
|
|
7918
8119
|
init_legend_svg();
|
|
7919
8120
|
init_label_layout();
|
|
7920
8121
|
init_palettes();
|
|
@@ -7924,6 +8125,25 @@ var init_echarts = __esm({
|
|
|
7924
8125
|
init_colors();
|
|
7925
8126
|
init_parsing();
|
|
7926
8127
|
init_chart();
|
|
8128
|
+
echarts.use([
|
|
8129
|
+
BarChart,
|
|
8130
|
+
LineChart,
|
|
8131
|
+
PieChart,
|
|
8132
|
+
ScatterChart,
|
|
8133
|
+
RadarChart,
|
|
8134
|
+
SankeyChart,
|
|
8135
|
+
GraphChart,
|
|
8136
|
+
HeatmapChart,
|
|
8137
|
+
FunnelChart,
|
|
8138
|
+
GridComponent,
|
|
8139
|
+
TitleComponent,
|
|
8140
|
+
TooltipComponent,
|
|
8141
|
+
LegendComponent,
|
|
8142
|
+
RadarComponent,
|
|
8143
|
+
VisualMapComponent,
|
|
8144
|
+
GraphicComponent,
|
|
8145
|
+
SVGRenderer
|
|
8146
|
+
]);
|
|
7927
8147
|
EMPHASIS_SELF = {
|
|
7928
8148
|
focus: "self",
|
|
7929
8149
|
blurScope: "global",
|
|
@@ -8886,13 +9106,10 @@ function parseC4(content, palette) {
|
|
|
8886
9106
|
labeledHandled = true;
|
|
8887
9107
|
break;
|
|
8888
9108
|
}
|
|
8889
|
-
|
|
9109
|
+
const labelResult = parseInArrowLabel(rawLabel, lineNumber);
|
|
9110
|
+
labelResult.diagnostics.forEach((d) => result.diagnostics.push(d));
|
|
9111
|
+
const label = labelResult.label;
|
|
8890
9112
|
let technology;
|
|
8891
|
-
const techMatch = rawLabel.match(/\[([^\]]+)\]\s*$/);
|
|
8892
|
-
if (techMatch) {
|
|
8893
|
-
label = rawLabel.substring(0, techMatch.index).trim() || void 0;
|
|
8894
|
-
technology = techMatch[1].trim();
|
|
8895
|
-
}
|
|
8896
9113
|
let target = targetBody;
|
|
8897
9114
|
const pipeIdx = targetBody.indexOf("|");
|
|
8898
9115
|
if (pipeIdx !== -1) {
|
|
@@ -9228,6 +9445,7 @@ var init_parser6 = __esm({
|
|
|
9228
9445
|
"src/c4/parser.ts"() {
|
|
9229
9446
|
"use strict";
|
|
9230
9447
|
init_diagnostics();
|
|
9448
|
+
init_arrows();
|
|
9231
9449
|
init_tag_groups();
|
|
9232
9450
|
init_participant_inference();
|
|
9233
9451
|
init_parsing();
|
|
@@ -10028,7 +10246,10 @@ function parseInfra(content) {
|
|
|
10028
10246
|
}
|
|
10029
10247
|
const asyncConnMatch = trimmed.match(ASYNC_CONNECTION_RE);
|
|
10030
10248
|
if (asyncConnMatch) {
|
|
10031
|
-
const
|
|
10249
|
+
const rawLabel = asyncConnMatch[1] ?? "";
|
|
10250
|
+
const labelResult = parseInArrowLabel(rawLabel, lineNumber);
|
|
10251
|
+
result.diagnostics.push(...labelResult.diagnostics);
|
|
10252
|
+
const label = labelResult.label ?? "";
|
|
10032
10253
|
const targetRaw = asyncConnMatch[2].trim();
|
|
10033
10254
|
const pipeMeta = extractPipeMetadata(targetRaw);
|
|
10034
10255
|
const targetName = pipeMeta.clean || targetRaw;
|
|
@@ -10088,7 +10309,10 @@ function parseInfra(content) {
|
|
|
10088
10309
|
}
|
|
10089
10310
|
const connMatch = trimmed.match(CONNECTION_RE);
|
|
10090
10311
|
if (connMatch) {
|
|
10091
|
-
const
|
|
10312
|
+
const rawLabel = connMatch[1] ?? "";
|
|
10313
|
+
const labelResult = parseInArrowLabel(rawLabel, lineNumber);
|
|
10314
|
+
result.diagnostics.push(...labelResult.diagnostics);
|
|
10315
|
+
const label = labelResult.label ?? "";
|
|
10092
10316
|
const targetRaw = connMatch[2].trim();
|
|
10093
10317
|
const pipeMeta = extractPipeMetadata(targetRaw);
|
|
10094
10318
|
const targetName = pipeMeta.clean || targetRaw;
|
|
@@ -10287,6 +10511,7 @@ var init_parser8 = __esm({
|
|
|
10287
10511
|
"use strict";
|
|
10288
10512
|
init_diagnostics();
|
|
10289
10513
|
init_colors();
|
|
10514
|
+
init_arrows();
|
|
10290
10515
|
init_parsing();
|
|
10291
10516
|
init_tag_groups();
|
|
10292
10517
|
init_types();
|
|
@@ -11818,7 +12043,9 @@ function parseEdgeLine(trimmed, lineNum, aliasMap, diagnostics) {
|
|
|
11818
12043
|
const biLabeledMatch = trimmed.match(/^(.+?)\s*<-(.+)->\s*(.+)$/);
|
|
11819
12044
|
if (biLabeledMatch) {
|
|
11820
12045
|
const source2 = resolveEndpoint(biLabeledMatch[1].trim());
|
|
11821
|
-
const
|
|
12046
|
+
const labelResult = parseInArrowLabel(biLabeledMatch[2], lineNum);
|
|
12047
|
+
diagnostics.push(...labelResult.diagnostics);
|
|
12048
|
+
const label = labelResult.label;
|
|
11822
12049
|
let rest2 = biLabeledMatch[3].trim();
|
|
11823
12050
|
let metadata2 = {};
|
|
11824
12051
|
const pipeIdx2 = rest2.indexOf("|");
|
|
@@ -11839,7 +12066,7 @@ function parseEdgeLine(trimmed, lineNum, aliasMap, diagnostics) {
|
|
|
11839
12066
|
return {
|
|
11840
12067
|
source: source2,
|
|
11841
12068
|
target: resolveEndpoint(rest2),
|
|
11842
|
-
label
|
|
12069
|
+
label,
|
|
11843
12070
|
bidirectional: true,
|
|
11844
12071
|
lineNumber: lineNum,
|
|
11845
12072
|
metadata: metadata2
|
|
@@ -11876,7 +12103,9 @@ function parseEdgeLine(trimmed, lineNum, aliasMap, diagnostics) {
|
|
|
11876
12103
|
const labeledMatch = trimmed.match(/^(.+?)\s+-(.+)->\s*(.+)$/);
|
|
11877
12104
|
if (labeledMatch) {
|
|
11878
12105
|
const source2 = resolveEndpoint(labeledMatch[1].trim());
|
|
11879
|
-
const
|
|
12106
|
+
const labelResult = parseInArrowLabel(labeledMatch[2], lineNum);
|
|
12107
|
+
diagnostics.push(...labelResult.diagnostics);
|
|
12108
|
+
const label = labelResult.label;
|
|
11880
12109
|
let rest2 = labeledMatch[3].trim();
|
|
11881
12110
|
if (label) {
|
|
11882
12111
|
let metadata2 = {};
|
|
@@ -11939,6 +12168,7 @@ var init_parser10 = __esm({
|
|
|
11939
12168
|
"src/boxes-and-lines/parser.ts"() {
|
|
11940
12169
|
"use strict";
|
|
11941
12170
|
init_diagnostics();
|
|
12171
|
+
init_arrows();
|
|
11942
12172
|
init_tag_groups();
|
|
11943
12173
|
init_parsing();
|
|
11944
12174
|
MAX_GROUP_DEPTH = 1;
|
|
@@ -12014,19 +12244,78 @@ function getAllChartTypes() {
|
|
|
12014
12244
|
function parseDgmo(content) {
|
|
12015
12245
|
const chartType = parseDgmoChartType(content);
|
|
12016
12246
|
if (!chartType) {
|
|
12247
|
+
const colonDiag = detectColonChartType(content);
|
|
12248
|
+
if (colonDiag) {
|
|
12249
|
+
const fallback = parseVisualization(content).diagnostics;
|
|
12250
|
+
return { diagnostics: [colonDiag, ...fallback] };
|
|
12251
|
+
}
|
|
12017
12252
|
return { diagnostics: parseVisualization(content).diagnostics };
|
|
12018
12253
|
}
|
|
12019
12254
|
const directParser = PARSE_DISPATCH.get(chartType);
|
|
12020
|
-
if (directParser)
|
|
12255
|
+
if (directParser) {
|
|
12256
|
+
const result2 = directParser(content);
|
|
12257
|
+
return {
|
|
12258
|
+
diagnostics: [...result2.diagnostics, ...detectEmptyContent(content)]
|
|
12259
|
+
};
|
|
12260
|
+
}
|
|
12021
12261
|
if (STANDARD_CHART_TYPES2.has(chartType)) {
|
|
12022
|
-
|
|
12262
|
+
const result2 = parseChart(content);
|
|
12263
|
+
return {
|
|
12264
|
+
diagnostics: [...result2.diagnostics, ...detectEmptyContent(content)]
|
|
12265
|
+
};
|
|
12023
12266
|
}
|
|
12024
12267
|
if (ECHART_TYPES.has(chartType)) {
|
|
12025
|
-
|
|
12268
|
+
const result2 = parseExtendedChart(content);
|
|
12269
|
+
return {
|
|
12270
|
+
diagnostics: [...result2.diagnostics, ...detectEmptyContent(content)]
|
|
12271
|
+
};
|
|
12272
|
+
}
|
|
12273
|
+
const result = parseVisualization(content);
|
|
12274
|
+
return {
|
|
12275
|
+
diagnostics: [...result.diagnostics, ...detectEmptyContent(content)]
|
|
12276
|
+
};
|
|
12277
|
+
}
|
|
12278
|
+
function detectColonChartType(content) {
|
|
12279
|
+
const lines = content.split("\n");
|
|
12280
|
+
for (let i = 0; i < lines.length; i++) {
|
|
12281
|
+
const trimmed = lines[i].trim();
|
|
12282
|
+
if (!trimmed || trimmed.startsWith("#") || trimmed.startsWith("//"))
|
|
12283
|
+
continue;
|
|
12284
|
+
const match = trimmed.match(/^(\w[\w-]*)\s*:\s*(.*)$/);
|
|
12285
|
+
if (!match) return null;
|
|
12286
|
+
const word = match[1].toLowerCase();
|
|
12287
|
+
const rest = match[2].trim();
|
|
12288
|
+
if (ALL_KNOWN_TYPES.has(word)) {
|
|
12289
|
+
const example = rest ? `${word} ${rest}` : word;
|
|
12290
|
+
return makeDgmoError(
|
|
12291
|
+
i + 1,
|
|
12292
|
+
`Remove the colon \u2014 use '${example}' instead of '${trimmed}'. DGMO chart types don't use colons.`
|
|
12293
|
+
);
|
|
12294
|
+
}
|
|
12295
|
+
const hint = suggest(word, [...ALL_KNOWN_TYPES]);
|
|
12296
|
+
if (hint) {
|
|
12297
|
+
return makeDgmoError(
|
|
12298
|
+
i + 1,
|
|
12299
|
+
`Unknown chart type: ${word}. ${hint} Also, DGMO chart types don't use colons.`
|
|
12300
|
+
);
|
|
12301
|
+
}
|
|
12302
|
+
return null;
|
|
12303
|
+
}
|
|
12304
|
+
return null;
|
|
12305
|
+
}
|
|
12306
|
+
function detectEmptyContent(content) {
|
|
12307
|
+
const lines = content.split("\n");
|
|
12308
|
+
const nonEmpty = lines.filter(
|
|
12309
|
+
(l) => l.trim() && !l.trim().startsWith("#") && !l.trim().startsWith("//")
|
|
12310
|
+
);
|
|
12311
|
+
if (nonEmpty.length <= 1) {
|
|
12312
|
+
return [
|
|
12313
|
+
makeDgmoError(1, "No content after chart type declaration.", "warning")
|
|
12314
|
+
];
|
|
12026
12315
|
}
|
|
12027
|
-
return
|
|
12316
|
+
return [];
|
|
12028
12317
|
}
|
|
12029
|
-
var GANTT_DURATION_RE, GANTT_DATE_RE, C4_TYPE_RE, DATA_CHART_TYPES, VISUALIZATION_TYPES, DIAGRAM_TYPES, EXTENDED_CHART_TYPES, STANDARD_CHART_TYPES2, ECHART_TYPES, PARSE_DISPATCH;
|
|
12318
|
+
var GANTT_DURATION_RE, GANTT_DATE_RE, C4_TYPE_RE, DATA_CHART_TYPES, VISUALIZATION_TYPES, DIAGRAM_TYPES, EXTENDED_CHART_TYPES, STANDARD_CHART_TYPES2, ECHART_TYPES, PARSE_DISPATCH, ALL_KNOWN_TYPES;
|
|
12030
12319
|
var init_dgmo_router = __esm({
|
|
12031
12320
|
"src/dgmo-router.ts"() {
|
|
12032
12321
|
"use strict";
|
|
@@ -12046,6 +12335,7 @@ var init_dgmo_router = __esm({
|
|
|
12046
12335
|
init_parser9();
|
|
12047
12336
|
init_parser10();
|
|
12048
12337
|
init_parsing();
|
|
12338
|
+
init_diagnostics();
|
|
12049
12339
|
GANTT_DURATION_RE = /^\d+(?:\.\d+)?(?:min|bd|d|w|m|q|y|h)(?:\?)?\s+/;
|
|
12050
12340
|
GANTT_DATE_RE = /^\d{4}-\d{2}-\d{2}(?:\s\d{2}:\d{2})?\s+/;
|
|
12051
12341
|
C4_TYPE_RE = /\bis\s+an?\s+(person|system|container|component)\b/i;
|
|
@@ -12129,6 +12419,11 @@ var init_dgmo_router = __esm({
|
|
|
12129
12419
|
["gantt", (c) => parseGantt(c)],
|
|
12130
12420
|
["boxes-and-lines", (c) => parseBoxesAndLines(c)]
|
|
12131
12421
|
]);
|
|
12422
|
+
ALL_KNOWN_TYPES = /* @__PURE__ */ new Set([
|
|
12423
|
+
...DATA_CHART_TYPES,
|
|
12424
|
+
...VISUALIZATION_TYPES,
|
|
12425
|
+
...DIAGRAM_TYPES
|
|
12426
|
+
]);
|
|
12132
12427
|
}
|
|
12133
12428
|
});
|
|
12134
12429
|
|
|
@@ -14303,7 +14598,6 @@ async function renderSitemapForExport(content, theme, palette) {
|
|
|
14303
14598
|
const { parseSitemap: parseSitemap2 } = await Promise.resolve().then(() => (init_parser7(), parser_exports7));
|
|
14304
14599
|
const { layoutSitemap: layoutSitemap2 } = await Promise.resolve().then(() => (init_layout2(), layout_exports2));
|
|
14305
14600
|
const { getPalette: getPalette2 } = await Promise.resolve().then(() => (init_palettes(), palettes_exports));
|
|
14306
|
-
const { injectBranding: injectBranding2 } = await Promise.resolve().then(() => (init_branding(), branding_exports));
|
|
14307
14601
|
const isDark = theme === "dark";
|
|
14308
14602
|
const effectivePalette = palette ?? (isDark ? getPalette2("nord").dark : getPalette2("nord").light);
|
|
14309
14603
|
const parsed = parseSitemap2(content, effectivePalette);
|
|
@@ -14345,8 +14639,7 @@ async function renderSitemapForExport(content, theme, palette) {
|
|
|
14345
14639
|
svgEl.style.fontFamily = FONT_FAMILY;
|
|
14346
14640
|
const svgHtml = svgEl.outerHTML;
|
|
14347
14641
|
document.body.removeChild(container);
|
|
14348
|
-
|
|
14349
|
-
return injectBranding2(svgHtml, brandColor);
|
|
14642
|
+
return svgHtml;
|
|
14350
14643
|
}
|
|
14351
14644
|
var DIAGRAM_PADDING2, MAX_SCALE2, TITLE_HEIGHT2, LABEL_FONT_SIZE2, META_FONT_SIZE2, META_LINE_HEIGHT4, HEADER_HEIGHT4, SEPARATOR_GAP4, EDGE_STROKE_WIDTH2, NODE_STROKE_WIDTH2, CARD_RADIUS2, CONTAINER_RADIUS2, CONTAINER_LABEL_FONT_SIZE2, CONTAINER_META_FONT_SIZE2, CONTAINER_META_LINE_HEIGHT4, CONTAINER_HEADER_HEIGHT2, ARROWHEAD_W, ARROWHEAD_H, EDGE_LABEL_FONT_SIZE, COLLAPSE_BAR_HEIGHT2, LEGEND_FIXED_GAP2, lineGenerator, lineGeneratorLinear;
|
|
14352
14645
|
var init_renderer2 = __esm({
|
|
@@ -14550,7 +14843,6 @@ var init_mutations = __esm({
|
|
|
14550
14843
|
// src/kanban/renderer.ts
|
|
14551
14844
|
var renderer_exports3 = {};
|
|
14552
14845
|
__export(renderer_exports3, {
|
|
14553
|
-
bucketCardsBySwimlane: () => bucketCardsBySwimlane,
|
|
14554
14846
|
renderKanban: () => renderKanban,
|
|
14555
14847
|
renderKanbanForExport: () => renderKanbanForExport
|
|
14556
14848
|
});
|
|
@@ -23449,6 +23741,8 @@ function renderGantt(container, resolved, palette, isDark, options, exportDims)
|
|
|
23449
23741
|
options?.currentActiveGroup
|
|
23450
23742
|
);
|
|
23451
23743
|
let criticalPathActive = false;
|
|
23744
|
+
let dependenciesActive = !!resolved.options.dependencies;
|
|
23745
|
+
let controlsExpanded = false;
|
|
23452
23746
|
const tagRows = currentSwimlaneGroup ? buildTagLaneRowList(resolved, currentSwimlaneGroup, collapsedLanes) : null;
|
|
23453
23747
|
const rows = tagRows ?? buildRowList(resolved, collapsedGroups);
|
|
23454
23748
|
const isTagMode = tagRows !== null;
|
|
@@ -23465,9 +23759,11 @@ function renderGantt(container, resolved, palette, isDark, options, exportDims)
|
|
|
23465
23759
|
const maxLabelLen = Math.max(...allLabels.map((l) => l.length), 10);
|
|
23466
23760
|
const leftMargin = Math.max(MIN_LEFT_MARGIN, maxLabelLen * 7 + 30);
|
|
23467
23761
|
const totalRows = rows.length;
|
|
23762
|
+
const hasCriticalPath = resolved.options.criticalPath && resolved.tasks.some((t) => t.isCriticalPath);
|
|
23763
|
+
const hasDependencies = resolved.options.dependencies && resolved.tasks.some((t) => t.task.dependencies.length > 0);
|
|
23468
23764
|
const title = resolved.options.title;
|
|
23469
23765
|
const titleHeight = title ? 50 : 20;
|
|
23470
|
-
const tagLegendReserve = resolved.tagGroups.length > 0 ? LEGEND_HEIGHT + 8 : 0;
|
|
23766
|
+
const tagLegendReserve = resolved.tagGroups.length > 0 || hasCriticalPath || hasDependencies ? LEGEND_HEIGHT + 8 : 0;
|
|
23471
23767
|
const topDateLabelReserve = 22;
|
|
23472
23768
|
const hasOverheadLabels = resolved.markers.length > 0 || resolved.eras.length > 0;
|
|
23473
23769
|
const markerLabelReserve = hasOverheadLabels ? 28 : 0;
|
|
@@ -23485,10 +23781,9 @@ function renderGantt(container, resolved, palette, isDark, options, exportDims)
|
|
|
23485
23781
|
if (title) {
|
|
23486
23782
|
svg.append("text").attr("x", containerWidth / 2).attr("y", TITLE_Y).attr("text-anchor", "middle").attr("font-size", TITLE_FONT_SIZE).attr("font-weight", TITLE_FONT_WEIGHT).attr("fill", palette.text).text(title);
|
|
23487
23783
|
}
|
|
23488
|
-
const hasCriticalPath = resolved.options.criticalPath && resolved.tasks.some((t) => t.isCriticalPath);
|
|
23489
23784
|
function drawLegend() {
|
|
23490
23785
|
svg.selectAll(".gantt-tag-legend-container").remove();
|
|
23491
|
-
if (resolved.tagGroups.length > 0 || hasCriticalPath) {
|
|
23786
|
+
if (resolved.tagGroups.length > 0 || hasCriticalPath || hasDependencies) {
|
|
23492
23787
|
const legendY = titleHeight;
|
|
23493
23788
|
renderTagLegend(
|
|
23494
23789
|
svg,
|
|
@@ -23510,16 +23805,38 @@ function renderGantt(container, resolved, palette, isDark, options, exportDims)
|
|
|
23510
23805
|
recolorBars();
|
|
23511
23806
|
},
|
|
23512
23807
|
() => {
|
|
23513
|
-
|
|
23808
|
+
controlsExpanded = !controlsExpanded;
|
|
23514
23809
|
drawLegend();
|
|
23515
23810
|
},
|
|
23516
23811
|
currentSwimlaneGroup,
|
|
23517
23812
|
onSwimlaneChange,
|
|
23518
23813
|
viewMode,
|
|
23519
|
-
resolved.tasks
|
|
23814
|
+
resolved.tasks,
|
|
23815
|
+
controlsExpanded,
|
|
23816
|
+
hasDependencies,
|
|
23817
|
+
dependenciesActive,
|
|
23818
|
+
(toggleId, active) => {
|
|
23819
|
+
if (toggleId === "critical-path") {
|
|
23820
|
+
criticalPathActive = active;
|
|
23821
|
+
} else if (toggleId === "dependencies") {
|
|
23822
|
+
dependenciesActive = active;
|
|
23823
|
+
g.selectAll(
|
|
23824
|
+
".gantt-dep-arrow, .gantt-dep-arrowhead, .gantt-dep-label"
|
|
23825
|
+
).attr("display", active ? null : "none");
|
|
23826
|
+
}
|
|
23827
|
+
drawLegend();
|
|
23828
|
+
}
|
|
23520
23829
|
);
|
|
23521
23830
|
}
|
|
23522
23831
|
}
|
|
23832
|
+
function restoreHighlight() {
|
|
23833
|
+
if (criticalPathActive) {
|
|
23834
|
+
applyCriticalPathHighlight(svg, g);
|
|
23835
|
+
} else {
|
|
23836
|
+
svg.attr("data-critical-path-active", null);
|
|
23837
|
+
resetHighlight(g, svg);
|
|
23838
|
+
}
|
|
23839
|
+
}
|
|
23523
23840
|
function recolorBars() {
|
|
23524
23841
|
g.selectAll(".gantt-task").each(function() {
|
|
23525
23842
|
const el = d3Selection10.select(this);
|
|
@@ -23538,8 +23855,8 @@ function renderGantt(container, resolved, palette, isDark, options, exportDims)
|
|
|
23538
23855
|
});
|
|
23539
23856
|
}
|
|
23540
23857
|
drawLegend();
|
|
23541
|
-
const startTime =
|
|
23542
|
-
const endTime =
|
|
23858
|
+
const startTime = dateToFractionalYear2(resolved.startDate);
|
|
23859
|
+
const endTime = dateToFractionalYear2(resolved.endDate);
|
|
23543
23860
|
const domainPad = Math.max((endTime - startTime) * 0.02, 0.01);
|
|
23544
23861
|
const domainMin = startTime - domainPad;
|
|
23545
23862
|
const domainMax = endTime + domainPad;
|
|
@@ -23570,7 +23887,7 @@ function renderGantt(container, resolved, palette, isDark, options, exportDims)
|
|
|
23570
23887
|
} else {
|
|
23571
23888
|
todayDate = /* @__PURE__ */ new Date(resolved.options.todayMarker + "T00:00:00");
|
|
23572
23889
|
}
|
|
23573
|
-
todayX = xScale(
|
|
23890
|
+
todayX = xScale(dateToFractionalYear2(todayDate));
|
|
23574
23891
|
if (todayX >= 0 && todayX <= innerWidth) {
|
|
23575
23892
|
const todayLine = g.append("line").attr("class", "gantt-today").attr("x1", todayX).attr("y1", 0).attr("x2", todayX).attr("y2", innerHeight + 10).attr("stroke", todayColor).attr("stroke-width", 2).attr("stroke-dasharray", "6 4").attr("opacity", 0.7).attr("pointer-events", "none");
|
|
23576
23893
|
if (todayMarkerLineNum)
|
|
@@ -23612,8 +23929,8 @@ function renderGantt(container, resolved, palette, isDark, options, exportDims)
|
|
|
23612
23929
|
let lx2 = innerWidth;
|
|
23613
23930
|
let laneBarWidth = innerWidth;
|
|
23614
23931
|
if (row.laneStartDate && row.laneEndDate) {
|
|
23615
|
-
lx1 = xScale(
|
|
23616
|
-
lx2 = xScale(
|
|
23932
|
+
lx1 = xScale(dateToFractionalYear2(row.laneStartDate));
|
|
23933
|
+
lx2 = xScale(dateToFractionalYear2(row.laneEndDate));
|
|
23617
23934
|
laneBarWidth = Math.max(lx2 - lx1, 2);
|
|
23618
23935
|
}
|
|
23619
23936
|
lanePositions.set(row.laneName, {
|
|
@@ -23645,7 +23962,7 @@ function renderGantt(container, resolved, palette, isDark, options, exportDims)
|
|
|
23645
23962
|
);
|
|
23646
23963
|
}
|
|
23647
23964
|
}).on("mouseleave", () => {
|
|
23648
|
-
|
|
23965
|
+
restoreHighlight();
|
|
23649
23966
|
hideGanttDateIndicators(g);
|
|
23650
23967
|
});
|
|
23651
23968
|
labelG.append("text").attr("x", labelX).attr("y", marginTop + yOffset + BAR_H / 2).attr("dy", "0.35em").attr("text-anchor", "start").attr("font-size", "11px").attr("font-weight", "bold").attr("fill", laneColor).text(
|
|
@@ -23719,8 +24036,8 @@ function renderGantt(container, resolved, palette, isDark, options, exportDims)
|
|
|
23719
24036
|
labelG.append("text").attr("x", labelX).attr("y", marginTop + yOffset + BAR_H / 2).attr("dy", "0.35em").attr("text-anchor", "start").attr("font-size", "11px").attr("font-weight", "bold").attr("fill", palette.text).text(
|
|
23720
24037
|
toggleIcon + " " + group.name + (group.progress !== null ? ` ${Math.round(group.progress)}%` : "")
|
|
23721
24038
|
);
|
|
23722
|
-
const gStart =
|
|
23723
|
-
const gEnd =
|
|
24039
|
+
const gStart = dateToFractionalYear2(group.startDate);
|
|
24040
|
+
const gEnd = dateToFractionalYear2(group.endDate);
|
|
23724
24041
|
const gx1 = xScale(gStart);
|
|
23725
24042
|
const gx2 = xScale(gEnd);
|
|
23726
24043
|
if (gx2 > gx1) {
|
|
@@ -23834,7 +24151,7 @@ function renderGantt(container, resolved, palette, isDark, options, exportDims)
|
|
|
23834
24151
|
taskLabel.attr("data-critical-path", "true");
|
|
23835
24152
|
}
|
|
23836
24153
|
if (rt.isMilestone) {
|
|
23837
|
-
const mx = xScale(
|
|
24154
|
+
const mx = xScale(dateToFractionalYear2(rt.startDate));
|
|
23838
24155
|
const my = yOffset + BAR_H / 2;
|
|
23839
24156
|
g.append("polygon").attr("class", "gantt-milestone").attr("points", diamondPoints(mx, my, MILESTONE_SIZE)).attr("fill", barColor).attr("stroke", barColor).attr("stroke-width", 1.5).attr("data-line-number", String(task.lineNumber)).attr("data-task-name", task.label).attr("data-task-id", task.id).attr("data-group", topGroup).style("cursor", onClickItem ? "pointer" : "default").on("click", () => {
|
|
23840
24157
|
if (onClickItem) onClickItem(task.lineNumber);
|
|
@@ -23850,14 +24167,14 @@ function renderGantt(container, resolved, palette, isDark, options, exportDims)
|
|
|
23850
24167
|
);
|
|
23851
24168
|
g.append("text").attr("class", "gantt-milestone-hover-label").attr("x", mx - MILESTONE_SIZE - 4).attr("y", my).attr("dy", "0.35em").attr("text-anchor", "end").attr("font-size", "10px").attr("fill", barColor).attr("font-weight", "600").text(task.label);
|
|
23852
24169
|
}).on("mouseleave", () => {
|
|
23853
|
-
|
|
24170
|
+
restoreHighlight();
|
|
23854
24171
|
hideGanttDateIndicators(g);
|
|
23855
24172
|
g.selectAll(".gantt-milestone-hover-label").remove();
|
|
23856
24173
|
});
|
|
23857
24174
|
taskPositions.set(task.id, { x1: mx, x2: mx, y: my });
|
|
23858
24175
|
} else {
|
|
23859
|
-
const tStart =
|
|
23860
|
-
const tEnd =
|
|
24176
|
+
const tStart = dateToFractionalYear2(rt.startDate);
|
|
24177
|
+
const tEnd = dateToFractionalYear2(rt.endDate);
|
|
23861
24178
|
const x1 = xScale(tStart);
|
|
23862
24179
|
const x2 = xScale(tEnd);
|
|
23863
24180
|
const barWidth = Math.max(x2 - x1, 2);
|
|
@@ -23879,11 +24196,7 @@ function renderGantt(container, resolved, palette, isDark, options, exportDims)
|
|
|
23879
24196
|
);
|
|
23880
24197
|
}).on("mouseleave", () => {
|
|
23881
24198
|
if (resolved.options.dependencies) {
|
|
23882
|
-
|
|
23883
|
-
applyCriticalPathHighlight(svg, g);
|
|
23884
|
-
} else {
|
|
23885
|
-
resetHighlight(g, svg);
|
|
23886
|
-
}
|
|
24199
|
+
restoreHighlight();
|
|
23887
24200
|
}
|
|
23888
24201
|
resetTaskLabels(svg);
|
|
23889
24202
|
hideGanttDateIndicators(g);
|
|
@@ -24096,14 +24409,14 @@ function renderHolidayBands(g, svg, resolved, xScale, innerHeight, palette, isDa
|
|
|
24096
24409
|
}
|
|
24097
24410
|
}
|
|
24098
24411
|
function drawBand(g, xScale, start, end, height, palette, _isDark, className, opacity) {
|
|
24099
|
-
const x1 = xScale(
|
|
24100
|
-
const x2 = xScale(
|
|
24412
|
+
const x1 = xScale(dateToFractionalYear2(start));
|
|
24413
|
+
const x2 = xScale(dateToFractionalYear2(end));
|
|
24101
24414
|
if (x2 <= x1) return;
|
|
24102
24415
|
g.append("rect").attr("class", className).attr("x", x1).attr("y", 0).attr("width", x2 - x1).attr("height", height).attr("fill", palette.text).attr("opacity", opacity).attr("pointer-events", "none");
|
|
24103
24416
|
}
|
|
24104
24417
|
function drawHolidayBand(g, svg, xScale, start, end, height, palette, _isDark, label, lineNumber, headerY, chartLeftMargin, onClickItem) {
|
|
24105
|
-
const x1 = xScale(
|
|
24106
|
-
const x2 = xScale(
|
|
24418
|
+
const x1 = xScale(dateToFractionalYear2(start));
|
|
24419
|
+
const x2 = xScale(dateToFractionalYear2(end));
|
|
24107
24420
|
if (x2 <= x1) return;
|
|
24108
24421
|
const bandW = Math.max(x2 - x1, 4);
|
|
24109
24422
|
const baseOpacity = 0.08;
|
|
@@ -24198,6 +24511,7 @@ function arrowheadPoints(x, y, size, angle) {
|
|
|
24198
24511
|
return `${x},${y} ${x + size * Math.cos(a1)},${y + size * Math.sin(a1)} ${x + size * Math.cos(a2)},${y + size * Math.sin(a2)}`;
|
|
24199
24512
|
}
|
|
24200
24513
|
function applyCriticalPathHighlight(svg, chartG) {
|
|
24514
|
+
svg.attr("data-critical-path-active", "true");
|
|
24201
24515
|
chartG.selectAll(".gantt-task").each(function() {
|
|
24202
24516
|
const el = d3Selection10.select(this);
|
|
24203
24517
|
el.attr(
|
|
@@ -24250,8 +24564,31 @@ function drawSwimlaneIcon2(parent, x, y, isActive, palette) {
|
|
|
24250
24564
|
}
|
|
24251
24565
|
return iconG;
|
|
24252
24566
|
}
|
|
24253
|
-
function
|
|
24254
|
-
const
|
|
24567
|
+
function buildControlsToggles(hasCriticalPath, criticalPathActive, hasDependencies, dependenciesActive) {
|
|
24568
|
+
const toggles = [];
|
|
24569
|
+
if (hasCriticalPath) {
|
|
24570
|
+
toggles.push({
|
|
24571
|
+
id: "critical-path",
|
|
24572
|
+
type: "toggle",
|
|
24573
|
+
label: "Critical Path",
|
|
24574
|
+
active: criticalPathActive,
|
|
24575
|
+
onToggle: () => {
|
|
24576
|
+
}
|
|
24577
|
+
});
|
|
24578
|
+
}
|
|
24579
|
+
if (hasDependencies) {
|
|
24580
|
+
toggles.push({
|
|
24581
|
+
id: "dependencies",
|
|
24582
|
+
type: "toggle",
|
|
24583
|
+
label: "Dependencies",
|
|
24584
|
+
active: dependenciesActive,
|
|
24585
|
+
onToggle: () => {
|
|
24586
|
+
}
|
|
24587
|
+
});
|
|
24588
|
+
}
|
|
24589
|
+
return toggles;
|
|
24590
|
+
}
|
|
24591
|
+
function renderTagLegend(svg, chartG, tagGroups, activeGroupName, chartLeftMargin, chartInnerWidth, legendY, palette, isDark, hasCriticalPath, criticalPathActive, optionLineNumbers, onToggle, onToggleControlsExpand, currentSwimlaneGroup, onSwimlaneChange, legendViewMode, resolvedTasks, controlsExpanded = false, hasDependencies = false, dependenciesActive = false, onControlsToggle) {
|
|
24255
24592
|
let visibleGroups;
|
|
24256
24593
|
if (activeGroupName) {
|
|
24257
24594
|
const activeGroup = tagGroups.filter(
|
|
@@ -24312,16 +24649,17 @@ function renderTagLegend(svg, chartG, tagGroups, activeGroupName, chartLeftMargi
|
|
|
24312
24649
|
totalW += groupW;
|
|
24313
24650
|
}
|
|
24314
24651
|
totalW += Math.max(0, (visibleGroups.length - 1) * LEGEND_GROUP_GAP);
|
|
24315
|
-
const
|
|
24316
|
-
const
|
|
24317
|
-
if (hasCriticalPath) {
|
|
24652
|
+
const hasControls = hasCriticalPath || hasDependencies;
|
|
24653
|
+
const controlsToggleLabels = [];
|
|
24654
|
+
if (hasCriticalPath) controlsToggleLabels.push({ label: "Critical Path" });
|
|
24655
|
+
if (hasDependencies) controlsToggleLabels.push({ label: "Dependencies" });
|
|
24656
|
+
if (hasControls) {
|
|
24318
24657
|
if (visibleGroups.length > 0) totalW += LEGEND_GROUP_GAP;
|
|
24319
|
-
totalW +=
|
|
24658
|
+
totalW += controlsExpanded ? controlsGroupCapsuleWidth(controlsToggleLabels) : LEGEND_GEAR_PILL_W;
|
|
24320
24659
|
}
|
|
24321
24660
|
const containerWidth = chartLeftMargin + chartInnerWidth + RIGHT_MARGIN;
|
|
24322
24661
|
const legendX = (containerWidth - totalW) / 2;
|
|
24323
24662
|
const legendRow = svg.append("g").attr("class", "gantt-tag-legend-container").attr("transform", `translate(${legendX}, ${legendY})`);
|
|
24324
|
-
let cursorX = 0;
|
|
24325
24663
|
if (visibleGroups.length > 0) {
|
|
24326
24664
|
const showIcon = !legendViewMode && tagGroups.length > 0;
|
|
24327
24665
|
const iconReserve = showIcon ? LEGEND_ICON_W : 0;
|
|
@@ -24333,6 +24671,12 @@ function renderTagLegend(svg, chartG, tagGroups, activeGroupName, chartLeftMargi
|
|
|
24333
24671
|
entries: entries.map((e) => ({ value: e.value, color: e.color }))
|
|
24334
24672
|
};
|
|
24335
24673
|
});
|
|
24674
|
+
const controlsToggles = buildControlsToggles(
|
|
24675
|
+
hasCriticalPath,
|
|
24676
|
+
criticalPathActive,
|
|
24677
|
+
hasDependencies,
|
|
24678
|
+
dependenciesActive
|
|
24679
|
+
);
|
|
24336
24680
|
const legendConfig = {
|
|
24337
24681
|
groups: legendGroups,
|
|
24338
24682
|
position: {
|
|
@@ -24340,13 +24684,23 @@ function renderTagLegend(svg, chartG, tagGroups, activeGroupName, chartLeftMargi
|
|
|
24340
24684
|
titleRelation: "below-title"
|
|
24341
24685
|
},
|
|
24342
24686
|
mode: "fixed",
|
|
24343
|
-
capsulePillAddonWidth: iconReserve
|
|
24687
|
+
capsulePillAddonWidth: iconReserve,
|
|
24688
|
+
controlsGroup: controlsToggles.length > 0 ? { toggles: controlsToggles } : void 0
|
|
24689
|
+
};
|
|
24690
|
+
const legendState = {
|
|
24691
|
+
activeGroup: activeGroupName,
|
|
24692
|
+
controlsExpanded
|
|
24344
24693
|
};
|
|
24345
|
-
|
|
24346
|
-
|
|
24694
|
+
let tagGroupsW = visibleGroups.reduce((s, _, i) => s + groupWidths[i], 0) + Math.max(0, (visibleGroups.length - 1) * LEGEND_GROUP_GAP);
|
|
24695
|
+
if (hasControls) {
|
|
24696
|
+
if (visibleGroups.length > 0) tagGroupsW += LEGEND_GROUP_GAP;
|
|
24697
|
+
tagGroupsW += controlsExpanded ? controlsGroupCapsuleWidth(controlsToggleLabels) : LEGEND_GEAR_PILL_W;
|
|
24698
|
+
}
|
|
24347
24699
|
const tagGroupG = legendRow.append("g");
|
|
24348
24700
|
const legendCallbacks = {
|
|
24349
24701
|
onGroupToggle: onToggle,
|
|
24702
|
+
onControlsExpand: onToggleControlsExpand,
|
|
24703
|
+
onControlsToggle,
|
|
24350
24704
|
onEntryHover: (groupName, entryValue) => {
|
|
24351
24705
|
const tagKey = groupName.toLowerCase();
|
|
24352
24706
|
if (entryValue) {
|
|
@@ -24423,31 +24777,38 @@ function renderTagLegend(svg, chartG, tagGroups, activeGroupName, chartLeftMargi
|
|
|
24423
24777
|
legendCallbacks,
|
|
24424
24778
|
tagGroupsW
|
|
24425
24779
|
);
|
|
24426
|
-
|
|
24427
|
-
|
|
24428
|
-
|
|
24780
|
+
} else if (hasControls) {
|
|
24781
|
+
const controlsToggles = buildControlsToggles(
|
|
24782
|
+
hasCriticalPath,
|
|
24783
|
+
criticalPathActive,
|
|
24784
|
+
hasDependencies,
|
|
24785
|
+
dependenciesActive
|
|
24786
|
+
);
|
|
24787
|
+
const legendConfig = {
|
|
24788
|
+
groups: [],
|
|
24789
|
+
position: {
|
|
24790
|
+
placement: "top-center",
|
|
24791
|
+
titleRelation: "below-title"
|
|
24792
|
+
},
|
|
24793
|
+
mode: "fixed",
|
|
24794
|
+
controlsGroup: { toggles: controlsToggles }
|
|
24795
|
+
};
|
|
24796
|
+
const tagGroupG = legendRow.append("g");
|
|
24797
|
+
renderLegendD3(
|
|
24798
|
+
tagGroupG,
|
|
24799
|
+
legendConfig,
|
|
24800
|
+
{ activeGroup: null, controlsExpanded },
|
|
24801
|
+
palette,
|
|
24802
|
+
isDark,
|
|
24803
|
+
{
|
|
24804
|
+
onControlsExpand: onToggleControlsExpand,
|
|
24805
|
+
onControlsToggle
|
|
24806
|
+
},
|
|
24807
|
+
totalW
|
|
24808
|
+
);
|
|
24429
24809
|
}
|
|
24430
|
-
if (
|
|
24431
|
-
|
|
24432
|
-
const cpG = legendRow.append("g").attr("transform", `translate(${cursorX}, 0)`).attr("class", "gantt-legend-critical-path").style("cursor", "pointer").on("click", () => {
|
|
24433
|
-
if (onToggleCriticalPath) onToggleCriticalPath();
|
|
24434
|
-
});
|
|
24435
|
-
if (cpLineNum) cpG.attr("data-line-number", String(cpLineNum));
|
|
24436
|
-
cpG.append("rect").attr("width", cpPillW).attr("height", LEGEND_HEIGHT).attr("rx", LEGEND_HEIGHT / 2).attr("fill", criticalPathActive ? palette.bg : groupBg);
|
|
24437
|
-
if (criticalPathActive) {
|
|
24438
|
-
cpG.append("rect").attr("width", cpPillW).attr("height", LEGEND_HEIGHT).attr("rx", LEGEND_HEIGHT / 2).attr("fill", "none").attr("stroke", mix(palette.textMuted, palette.bg, 50)).attr("stroke-width", 0.75);
|
|
24439
|
-
}
|
|
24440
|
-
cpG.append("text").attr("x", cpPillW / 2).attr("y", LEGEND_HEIGHT / 2 + LEGEND_PILL_FONT_SIZE / 2 - 2).attr("text-anchor", "middle").attr("font-size", `${LEGEND_PILL_FONT_SIZE}px`).attr("font-weight", "500").attr("fill", criticalPathActive ? palette.text : palette.textMuted).text(cpLabel);
|
|
24441
|
-
if (criticalPathActive) {
|
|
24442
|
-
applyCriticalPathHighlight(svg, chartG);
|
|
24443
|
-
}
|
|
24444
|
-
cpG.on("mouseenter", () => {
|
|
24445
|
-
applyCriticalPathHighlight(svg, chartG);
|
|
24446
|
-
}).on("mouseleave", () => {
|
|
24447
|
-
if (!criticalPathActive) {
|
|
24448
|
-
resetHighlightAll(svg, chartG);
|
|
24449
|
-
}
|
|
24450
|
-
});
|
|
24810
|
+
if (criticalPathActive) {
|
|
24811
|
+
applyCriticalPathHighlight(svg, chartG);
|
|
24451
24812
|
}
|
|
24452
24813
|
}
|
|
24453
24814
|
function renderErasAndMarkers(g, svg, resolved, xScale, innerHeight, palette) {
|
|
@@ -24577,8 +24938,8 @@ function renderSprintBands(g, svg, resolved, xScale, innerHeight, palette) {
|
|
|
24577
24938
|
const chartMinX = 0;
|
|
24578
24939
|
for (let i = 0; i < resolved.sprints.length; i++) {
|
|
24579
24940
|
const sprint = resolved.sprints[i];
|
|
24580
|
-
const rawSx = xScale(
|
|
24581
|
-
const rawEx = xScale(
|
|
24941
|
+
const rawSx = xScale(dateToFractionalYear2(sprint.startDate));
|
|
24942
|
+
const rawEx = xScale(dateToFractionalYear2(sprint.endDate));
|
|
24582
24943
|
if (rawEx <= rawSx) continue;
|
|
24583
24944
|
const sx = Math.max(rawSx, chartMinX);
|
|
24584
24945
|
const ex = rawEx;
|
|
@@ -24700,7 +25061,7 @@ function renderSprintBands(g, svg, resolved, xScale, innerHeight, palette) {
|
|
|
24700
25061
|
});
|
|
24701
25062
|
}
|
|
24702
25063
|
const lastSprint = resolved.sprints[resolved.sprints.length - 1];
|
|
24703
|
-
const lastEx = xScale(
|
|
25064
|
+
const lastEx = xScale(dateToFractionalYear2(lastSprint.endDate));
|
|
24704
25065
|
g.append("line").attr("class", "gantt-sprint-boundary").attr("x1", lastEx).attr("y1", -6).attr("x2", lastEx).attr("y2", innerHeight).attr("stroke", bandColor).attr("stroke-width", 1).attr("stroke-dasharray", "3 3").attr("opacity", SPRINT_BOUNDARY_OPACITY);
|
|
24705
25066
|
}
|
|
24706
25067
|
function parseDateStringToDate(s) {
|
|
@@ -24711,7 +25072,7 @@ function parseDateStringToDate(s) {
|
|
|
24711
25072
|
return new Date(year, month, day);
|
|
24712
25073
|
}
|
|
24713
25074
|
function parseDateToFractionalYear(s) {
|
|
24714
|
-
return
|
|
25075
|
+
return dateToFractionalYear2(parseDateStringToDate(s));
|
|
24715
25076
|
}
|
|
24716
25077
|
function highlightDeps(g, svg, taskId, resolved) {
|
|
24717
25078
|
const related = /* @__PURE__ */ new Set([taskId]);
|
|
@@ -24915,6 +25276,10 @@ function resetTaskLabels(svg) {
|
|
|
24915
25276
|
svg.selectAll(".gantt-task-label").attr("opacity", 1);
|
|
24916
25277
|
}
|
|
24917
25278
|
function resetHighlight(g, svg) {
|
|
25279
|
+
if (svg.attr("data-critical-path-active") === "true") {
|
|
25280
|
+
applyCriticalPathHighlight(svg, g);
|
|
25281
|
+
return;
|
|
25282
|
+
}
|
|
24918
25283
|
g.selectAll(".gantt-task, .gantt-milestone").attr(
|
|
24919
25284
|
"opacity",
|
|
24920
25285
|
1
|
|
@@ -25074,7 +25439,7 @@ function durationWeightedProgress(tasks) {
|
|
|
25074
25439
|
}
|
|
25075
25440
|
return hasProgress && totalDuration > 0 ? totalProgress / totalDuration : null;
|
|
25076
25441
|
}
|
|
25077
|
-
function
|
|
25442
|
+
function dateToFractionalYear2(d) {
|
|
25078
25443
|
const y = d.getFullYear();
|
|
25079
25444
|
const startOfYear = new Date(y, 0, 1);
|
|
25080
25445
|
const endOfYear = new Date(y + 1, 0, 1);
|
|
@@ -25086,7 +25451,7 @@ function diamondPoints(cx, cy, size) {
|
|
|
25086
25451
|
return `${cx},${cy - half} ${cx + half},${cy} ${cx},${cy + half} ${cx - half},${cy}`;
|
|
25087
25452
|
}
|
|
25088
25453
|
function formatGanttDate(d) {
|
|
25089
|
-
const base = `${
|
|
25454
|
+
const base = `${MONTH_ABBR2[d.getMonth()]} ${d.getDate()}, ${d.getFullYear()}`;
|
|
25090
25455
|
if (d.getHours() === 0 && d.getMinutes() === 0) return base;
|
|
25091
25456
|
const hh = String(d.getHours()).padStart(2, "0");
|
|
25092
25457
|
const mm = String(d.getMinutes()).padStart(2, "0");
|
|
@@ -25097,7 +25462,7 @@ function showGanttDateIndicators(g, xScale, startDate, endDate, innerHeight, col
|
|
|
25097
25462
|
g.selectAll(".gantt-today").attr("opacity", 0.05);
|
|
25098
25463
|
const hg = g.append("g").attr("class", "gantt-hover-date").attr("pointer-events", "none");
|
|
25099
25464
|
const tickLen = 6;
|
|
25100
|
-
const startPos = xScale(
|
|
25465
|
+
const startPos = xScale(dateToFractionalYear2(startDate));
|
|
25101
25466
|
const startLabel = formatGanttDate(startDate);
|
|
25102
25467
|
if (!options?.skipStartLine) {
|
|
25103
25468
|
hg.append("line").attr("class", "gantt-hover-date").attr("x1", startPos).attr("y1", -tickLen).attr("x2", startPos).attr("y2", innerHeight).attr("stroke", color).attr("stroke-width", 1.5).attr("stroke-dasharray", "4 4").attr("opacity", 0.6);
|
|
@@ -25105,7 +25470,7 @@ function showGanttDateIndicators(g, xScale, startDate, endDate, innerHeight, col
|
|
|
25105
25470
|
hg.append("text").attr("class", "gantt-hover-date").attr("x", startPos).attr("y", -tickLen - 4).attr("text-anchor", "middle").attr("fill", color).attr("font-size", "10px").attr("font-weight", "600").text(startLabel);
|
|
25106
25471
|
hg.append("text").attr("class", "gantt-hover-date").attr("x", startPos).attr("y", innerHeight + tickLen + 12).attr("text-anchor", "middle").attr("fill", color).attr("font-size", "10px").attr("font-weight", "600").text(startLabel);
|
|
25107
25472
|
if (endDate && endDate.getTime() !== startDate.getTime()) {
|
|
25108
|
-
const endPos = xScale(
|
|
25473
|
+
const endPos = xScale(dateToFractionalYear2(endDate));
|
|
25109
25474
|
const endLabel = formatGanttDate(endDate);
|
|
25110
25475
|
const minLabelGap = 90;
|
|
25111
25476
|
const gap = endPos - startPos;
|
|
@@ -25175,7 +25540,7 @@ function renderTimeScaleHorizontal(g, scale, innerWidth, innerHeight, textColor)
|
|
|
25175
25540
|
g.append("text").attr("class", "gantt-scale-tick").attr("x", tick.pos).attr("y", innerHeight + tickLen + 12).attr("text-anchor", "middle").attr("font-size", "10px").attr("fill", textColor).attr("opacity", opacity).text(tick.label);
|
|
25176
25541
|
}
|
|
25177
25542
|
}
|
|
25178
|
-
var BAR_H, ROW_GAP, GROUP_GAP2, MILESTONE_SIZE, MIN_LEFT_MARGIN, BOTTOM_MARGIN, RIGHT_MARGIN, CHAR_W2, LABEL_PAD, LABEL_GAP, BAND_ACCENT_W, BAND_RADIUS, bandClipCounter, JS_DAY_TO_WEEKDAY2, ERA_COLORS, SPRINT_BAND_OPACITY, SPRINT_HOVER_OPACITY, SPRINT_BOUNDARY_OPACITY, FADE_OPACITY,
|
|
25543
|
+
var BAR_H, ROW_GAP, GROUP_GAP2, MILESTONE_SIZE, MIN_LEFT_MARGIN, BOTTOM_MARGIN, RIGHT_MARGIN, CHAR_W2, LABEL_PAD, LABEL_GAP, BAND_ACCENT_W, BAND_RADIUS, bandClipCounter, JS_DAY_TO_WEEKDAY2, ERA_COLORS, SPRINT_BAND_OPACITY, SPRINT_HOVER_OPACITY, SPRINT_BOUNDARY_OPACITY, FADE_OPACITY, MONTH_ABBR2;
|
|
25179
25544
|
var init_renderer9 = __esm({
|
|
25180
25545
|
"src/gantt/renderer.ts"() {
|
|
25181
25546
|
"use strict";
|
|
@@ -25183,9 +25548,10 @@ var init_renderer9 = __esm({
|
|
|
25183
25548
|
init_palettes();
|
|
25184
25549
|
init_color_utils();
|
|
25185
25550
|
init_tag_groups();
|
|
25186
|
-
|
|
25551
|
+
init_time_ticks();
|
|
25187
25552
|
init_legend_constants();
|
|
25188
25553
|
init_legend_d3();
|
|
25554
|
+
init_legend_layout();
|
|
25189
25555
|
init_title_constants();
|
|
25190
25556
|
BAR_H = 22;
|
|
25191
25557
|
ROW_GAP = 6;
|
|
@@ -25214,7 +25580,7 @@ var init_renderer9 = __esm({
|
|
|
25214
25580
|
SPRINT_HOVER_OPACITY = 0.12;
|
|
25215
25581
|
SPRINT_BOUNDARY_OPACITY = 0.3;
|
|
25216
25582
|
FADE_OPACITY = 0.1;
|
|
25217
|
-
|
|
25583
|
+
MONTH_ABBR2 = [
|
|
25218
25584
|
"Jan",
|
|
25219
25585
|
"Feb",
|
|
25220
25586
|
"Mar",
|
|
@@ -25479,6 +25845,109 @@ var init_state_renderer = __esm({
|
|
|
25479
25845
|
}
|
|
25480
25846
|
});
|
|
25481
25847
|
|
|
25848
|
+
// src/sequence/collapse.ts
|
|
25849
|
+
function applyCollapseProjection(parsed, collapsedGroups) {
|
|
25850
|
+
if (collapsedGroups.size === 0) {
|
|
25851
|
+
return {
|
|
25852
|
+
participants: parsed.participants,
|
|
25853
|
+
messages: parsed.messages,
|
|
25854
|
+
elements: parsed.elements,
|
|
25855
|
+
groups: parsed.groups,
|
|
25856
|
+
collapsedGroupIds: /* @__PURE__ */ new Map()
|
|
25857
|
+
};
|
|
25858
|
+
}
|
|
25859
|
+
const memberToGroup = /* @__PURE__ */ new Map();
|
|
25860
|
+
const collapsedGroupNames = /* @__PURE__ */ new Set();
|
|
25861
|
+
for (const group of parsed.groups) {
|
|
25862
|
+
if (collapsedGroups.has(group.lineNumber)) {
|
|
25863
|
+
collapsedGroupNames.add(group.name);
|
|
25864
|
+
for (const memberId of group.participantIds) {
|
|
25865
|
+
memberToGroup.set(memberId, group.name);
|
|
25866
|
+
}
|
|
25867
|
+
}
|
|
25868
|
+
}
|
|
25869
|
+
const participants = [];
|
|
25870
|
+
const insertedGroups = /* @__PURE__ */ new Set();
|
|
25871
|
+
for (const p of parsed.participants) {
|
|
25872
|
+
const groupName = memberToGroup.get(p.id);
|
|
25873
|
+
if (groupName) {
|
|
25874
|
+
if (!insertedGroups.has(groupName)) {
|
|
25875
|
+
insertedGroups.add(groupName);
|
|
25876
|
+
const group = parsed.groups.find(
|
|
25877
|
+
(g) => g.name === groupName && collapsedGroups.has(g.lineNumber)
|
|
25878
|
+
);
|
|
25879
|
+
participants.push({
|
|
25880
|
+
id: groupName,
|
|
25881
|
+
label: groupName,
|
|
25882
|
+
type: "default",
|
|
25883
|
+
lineNumber: group.lineNumber
|
|
25884
|
+
});
|
|
25885
|
+
}
|
|
25886
|
+
} else if (collapsedGroupNames.has(p.id)) {
|
|
25887
|
+
} else {
|
|
25888
|
+
participants.push(p);
|
|
25889
|
+
}
|
|
25890
|
+
}
|
|
25891
|
+
const remap = (id) => memberToGroup.get(id) ?? id;
|
|
25892
|
+
const messages = parsed.messages.map((msg) => ({
|
|
25893
|
+
...msg,
|
|
25894
|
+
from: remap(msg.from),
|
|
25895
|
+
to: remap(msg.to)
|
|
25896
|
+
}));
|
|
25897
|
+
const elements = remapElements(parsed.elements, memberToGroup);
|
|
25898
|
+
const groups = parsed.groups.filter(
|
|
25899
|
+
(g) => !collapsedGroups.has(g.lineNumber)
|
|
25900
|
+
);
|
|
25901
|
+
return {
|
|
25902
|
+
participants,
|
|
25903
|
+
messages,
|
|
25904
|
+
elements,
|
|
25905
|
+
groups,
|
|
25906
|
+
collapsedGroupIds: memberToGroup
|
|
25907
|
+
};
|
|
25908
|
+
}
|
|
25909
|
+
function remapElements(elements, memberToGroup) {
|
|
25910
|
+
const remap = (id) => memberToGroup.get(id) ?? id;
|
|
25911
|
+
const result = [];
|
|
25912
|
+
for (const el of elements) {
|
|
25913
|
+
if (isSequenceSection(el)) {
|
|
25914
|
+
result.push(el);
|
|
25915
|
+
} else if (isSequenceNote(el)) {
|
|
25916
|
+
result.push({
|
|
25917
|
+
...el,
|
|
25918
|
+
participantId: remap(el.participantId)
|
|
25919
|
+
});
|
|
25920
|
+
} else if (isSequenceBlock(el)) {
|
|
25921
|
+
result.push({
|
|
25922
|
+
...el,
|
|
25923
|
+
children: remapElements(el.children, memberToGroup),
|
|
25924
|
+
elseChildren: remapElements(el.elseChildren, memberToGroup),
|
|
25925
|
+
...el.elseIfBranches ? {
|
|
25926
|
+
elseIfBranches: el.elseIfBranches.map((branch) => ({
|
|
25927
|
+
...branch,
|
|
25928
|
+
children: remapElements(branch.children, memberToGroup)
|
|
25929
|
+
}))
|
|
25930
|
+
} : {}
|
|
25931
|
+
});
|
|
25932
|
+
} else {
|
|
25933
|
+
const msg = el;
|
|
25934
|
+
const from = remap(msg.from);
|
|
25935
|
+
const to = remap(msg.to);
|
|
25936
|
+
if (from === to && from !== msg.from && !msg.label) {
|
|
25937
|
+
continue;
|
|
25938
|
+
}
|
|
25939
|
+
result.push({ ...msg, from, to });
|
|
25940
|
+
}
|
|
25941
|
+
}
|
|
25942
|
+
return result;
|
|
25943
|
+
}
|
|
25944
|
+
var init_collapse3 = __esm({
|
|
25945
|
+
"src/sequence/collapse.ts"() {
|
|
25946
|
+
"use strict";
|
|
25947
|
+
init_parser();
|
|
25948
|
+
}
|
|
25949
|
+
});
|
|
25950
|
+
|
|
25482
25951
|
// src/sequence/tag-resolution.ts
|
|
25483
25952
|
function propagateGroupTags(participantMeta, groups) {
|
|
25484
25953
|
for (const group of groups) {
|
|
@@ -25934,13 +26403,32 @@ function applyGroupOrdering(participants, groups, messages = []) {
|
|
|
25934
26403
|
}
|
|
25935
26404
|
function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateToLine, options) {
|
|
25936
26405
|
d3Selection12.select(container).selectAll("*").remove();
|
|
25937
|
-
const { title,
|
|
26406
|
+
const { title, options: parsedOptions } = parsed;
|
|
26407
|
+
const effectiveCollapsedGroups = /* @__PURE__ */ new Set();
|
|
26408
|
+
for (const group of parsed.groups) {
|
|
26409
|
+
if (group.collapsed) effectiveCollapsedGroups.add(group.lineNumber);
|
|
26410
|
+
}
|
|
26411
|
+
if (options?.collapsedGroups) {
|
|
26412
|
+
for (const ln of options.collapsedGroups) {
|
|
26413
|
+
if (effectiveCollapsedGroups.has(ln)) {
|
|
26414
|
+
effectiveCollapsedGroups.delete(ln);
|
|
26415
|
+
} else {
|
|
26416
|
+
effectiveCollapsedGroups.add(ln);
|
|
26417
|
+
}
|
|
26418
|
+
}
|
|
26419
|
+
}
|
|
26420
|
+
const collapsed = effectiveCollapsedGroups.size > 0 ? applyCollapseProjection(parsed, effectiveCollapsedGroups) : null;
|
|
26421
|
+
const messages = collapsed ? collapsed.messages : parsed.messages;
|
|
26422
|
+
const elements = collapsed ? collapsed.elements : parsed.elements;
|
|
26423
|
+
const groups = collapsed ? collapsed.groups : parsed.groups;
|
|
26424
|
+
const collapsedGroupIds = collapsed?.collapsedGroupIds ?? /* @__PURE__ */ new Map();
|
|
25938
26425
|
const collapsedSections = options?.collapsedSections;
|
|
25939
26426
|
const expandedNoteLines = options?.expandedNoteLines;
|
|
25940
26427
|
const collapseNotesDisabled = parsedOptions["collapse-notes"]?.toLowerCase() === "no";
|
|
25941
26428
|
const isNoteExpanded = (note) => expandedNoteLines === void 0 || collapseNotesDisabled || expandedNoteLines.has(note.lineNumber);
|
|
26429
|
+
const sourceParticipants = collapsed ? collapsed.participants : parsed.participants;
|
|
25942
26430
|
const participants = applyPositionOverrides(
|
|
25943
|
-
applyGroupOrdering(
|
|
26431
|
+
applyGroupOrdering(sourceParticipants, groups, messages)
|
|
25944
26432
|
);
|
|
25945
26433
|
if (participants.length === 0) return;
|
|
25946
26434
|
const activationsOff = parsedOptions.activations?.toLowerCase() === "off";
|
|
@@ -26111,13 +26599,16 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
|
|
|
26111
26599
|
const preSectionMsgIndices = [];
|
|
26112
26600
|
const sectionRegions = [];
|
|
26113
26601
|
{
|
|
26602
|
+
const msgLineToIndex = /* @__PURE__ */ new Map();
|
|
26603
|
+
messages.forEach((m, i) => msgLineToIndex.set(m.lineNumber, i));
|
|
26604
|
+
const findMsgIndex = (child) => msgLineToIndex.get(child.lineNumber) ?? -1;
|
|
26114
26605
|
const collectMsgIndicesFromBlock = (block) => {
|
|
26115
26606
|
const indices = [];
|
|
26116
26607
|
for (const child of block.children) {
|
|
26117
26608
|
if (isSequenceBlock(child)) {
|
|
26118
26609
|
indices.push(...collectMsgIndicesFromBlock(child));
|
|
26119
26610
|
} else if (!isSequenceSection(child) && !isSequenceNote(child)) {
|
|
26120
|
-
const idx =
|
|
26611
|
+
const idx = findMsgIndex(child);
|
|
26121
26612
|
if (idx >= 0) indices.push(idx);
|
|
26122
26613
|
}
|
|
26123
26614
|
}
|
|
@@ -26127,7 +26618,7 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
|
|
|
26127
26618
|
if (isSequenceBlock(child)) {
|
|
26128
26619
|
indices.push(...collectMsgIndicesFromBlock(child));
|
|
26129
26620
|
} else if (!isSequenceSection(child) && !isSequenceNote(child)) {
|
|
26130
|
-
const idx =
|
|
26621
|
+
const idx = findMsgIndex(child);
|
|
26131
26622
|
if (idx >= 0) indices.push(idx);
|
|
26132
26623
|
}
|
|
26133
26624
|
}
|
|
@@ -26137,7 +26628,7 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
|
|
|
26137
26628
|
if (isSequenceBlock(child)) {
|
|
26138
26629
|
indices.push(...collectMsgIndicesFromBlock(child));
|
|
26139
26630
|
} else if (!isSequenceSection(child) && !isSequenceNote(child)) {
|
|
26140
|
-
const idx =
|
|
26631
|
+
const idx = findMsgIndex(child);
|
|
26141
26632
|
if (idx >= 0) indices.push(idx);
|
|
26142
26633
|
}
|
|
26143
26634
|
}
|
|
@@ -26152,7 +26643,7 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
|
|
|
26152
26643
|
} else if (isSequenceBlock(el)) {
|
|
26153
26644
|
currentTarget.push(...collectMsgIndicesFromBlock(el));
|
|
26154
26645
|
} else {
|
|
26155
|
-
const idx =
|
|
26646
|
+
const idx = findMsgIndex(el);
|
|
26156
26647
|
if (idx >= 0) currentTarget.push(idx);
|
|
26157
26648
|
}
|
|
26158
26649
|
}
|
|
@@ -26214,7 +26705,7 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
|
|
|
26214
26705
|
const titleOffset = title ? TITLE_HEIGHT5 : 0;
|
|
26215
26706
|
const LEGEND_FIXED_GAP4 = 8;
|
|
26216
26707
|
const legendTopSpace = parsed.tagGroups.length > 0 ? LEGEND_HEIGHT + LEGEND_FIXED_GAP4 : 0;
|
|
26217
|
-
const groupOffset = groups.length > 0 ? GROUP_PADDING_TOP + GROUP_LABEL_SIZE : 0;
|
|
26708
|
+
const groupOffset = parsed.groups.length > 0 ? GROUP_PADDING_TOP + GROUP_LABEL_SIZE : 0;
|
|
26218
26709
|
const participantStartY = TOP_MARGIN + titleOffset + legendTopSpace + PARTICIPANT_Y_OFFSET + groupOffset;
|
|
26219
26710
|
const lifelineStartY0 = participantStartY + PARTICIPANT_BOX_HEIGHT;
|
|
26220
26711
|
const hasActors = participants.some((p) => p.type === "actor");
|
|
@@ -26384,6 +26875,17 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
|
|
|
26384
26875
|
svgWidth
|
|
26385
26876
|
);
|
|
26386
26877
|
}
|
|
26878
|
+
const collapsedGroupNames = /* @__PURE__ */ new Set();
|
|
26879
|
+
const collapsedGroupMeta = /* @__PURE__ */ new Map();
|
|
26880
|
+
for (const group of parsed.groups) {
|
|
26881
|
+
if (effectiveCollapsedGroups.has(group.lineNumber)) {
|
|
26882
|
+
collapsedGroupNames.add(group.name);
|
|
26883
|
+
collapsedGroupMeta.set(group.name, {
|
|
26884
|
+
lineNumber: group.lineNumber,
|
|
26885
|
+
metadata: group.metadata
|
|
26886
|
+
});
|
|
26887
|
+
}
|
|
26888
|
+
}
|
|
26387
26889
|
for (const group of groups) {
|
|
26388
26890
|
if (group.participantIds.length === 0) continue;
|
|
26389
26891
|
const memberXs = group.participantIds.map((id) => participantX.get(id)).filter((x) => x !== void 0);
|
|
@@ -26400,8 +26902,10 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
|
|
|
26400
26902
|
isDark ? 15 : 20
|
|
26401
26903
|
) : isDark ? palette.surface : palette.bg;
|
|
26402
26904
|
const strokeColor = groupTagColor || palette.textMuted;
|
|
26403
|
-
svg.append("
|
|
26404
|
-
|
|
26905
|
+
const groupG = svg.append("g").attr("class", "group-box-wrapper").attr("data-group-toggle", "").attr("data-group-line", String(group.lineNumber)).attr("cursor", "pointer");
|
|
26906
|
+
groupG.append("title").text("Click to collapse");
|
|
26907
|
+
groupG.append("rect").attr("x", minX).attr("y", boxY).attr("width", maxX - minX).attr("height", boxH).attr("rx", 6).attr("fill", fillColor).attr("stroke", strokeColor).attr("stroke-width", 1).attr("stroke-opacity", 0.5).attr("class", "group-box");
|
|
26908
|
+
groupG.append("text").attr("x", minX + 8).attr("y", boxY + GROUP_LABEL_SIZE + 4).attr("fill", strokeColor).attr("font-size", GROUP_LABEL_SIZE).attr("font-weight", "bold").attr("opacity", 0.7).attr("class", "group-label").text(group.name);
|
|
26405
26909
|
}
|
|
26406
26910
|
const lifelineStartY = lifelineStartY0;
|
|
26407
26911
|
participants.forEach((participant, index) => {
|
|
@@ -26410,6 +26914,14 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
|
|
|
26410
26914
|
const pTagValue = tagMap?.participants.get(participant.id);
|
|
26411
26915
|
const pTagColor = getTagColor(pTagValue);
|
|
26412
26916
|
const pTagAttr = tagKey && pTagValue ? { key: tagKey, value: pTagValue.toLowerCase() } : void 0;
|
|
26917
|
+
const isCollapsedGroup = collapsedGroupNames.has(participant.id);
|
|
26918
|
+
let effectiveTagColor = pTagColor;
|
|
26919
|
+
if (isCollapsedGroup && !effectiveTagColor) {
|
|
26920
|
+
const meta = collapsedGroupMeta.get(participant.id);
|
|
26921
|
+
if (meta?.metadata && tagKey) {
|
|
26922
|
+
effectiveTagColor = getTagColor(meta.metadata[tagKey]);
|
|
26923
|
+
}
|
|
26924
|
+
}
|
|
26413
26925
|
renderParticipant(
|
|
26414
26926
|
svg,
|
|
26415
26927
|
participant,
|
|
@@ -26417,10 +26929,35 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
|
|
|
26417
26929
|
cy,
|
|
26418
26930
|
palette,
|
|
26419
26931
|
isDark,
|
|
26420
|
-
|
|
26932
|
+
effectiveTagColor,
|
|
26421
26933
|
pTagAttr
|
|
26422
26934
|
);
|
|
26423
|
-
|
|
26935
|
+
if (isCollapsedGroup) {
|
|
26936
|
+
const meta = collapsedGroupMeta.get(participant.id);
|
|
26937
|
+
const drillColor = effectiveTagColor || palette.textMuted;
|
|
26938
|
+
const drillBarH = 6;
|
|
26939
|
+
const boxW = PARTICIPANT_BOX_WIDTH;
|
|
26940
|
+
const fullH = PARTICIPANT_BOX_HEIGHT + GROUP_PADDING_TOP + GROUP_PADDING_BOTTOM;
|
|
26941
|
+
const clipId = `clip-drill-group-${participant.id.replace(/[^a-zA-Z0-9-]/g, "-")}`;
|
|
26942
|
+
const participantG = svg.select(
|
|
26943
|
+
`.participant[data-participant-id="${participant.id}"]`
|
|
26944
|
+
);
|
|
26945
|
+
participantG.attr("data-group-toggle", "").attr("data-group-line", String(meta.lineNumber)).attr("cursor", "pointer");
|
|
26946
|
+
participantG.append("title").text("Click to expand");
|
|
26947
|
+
const pFill = effectiveTagColor ? mix(
|
|
26948
|
+
effectiveTagColor,
|
|
26949
|
+
isDark ? palette.surface : palette.bg,
|
|
26950
|
+
isDark ? 30 : 40
|
|
26951
|
+
) : isDark ? mix(palette.overlay, palette.surface, 50) : mix(palette.bg, palette.surface, 50);
|
|
26952
|
+
const pStroke = effectiveTagColor || palette.border;
|
|
26953
|
+
participantG.append("rect").attr("x", -boxW / 2).attr("y", -GROUP_PADDING_TOP).attr("width", boxW).attr("height", fullH).attr("rx", 6).attr("fill", pFill).attr("stroke", pStroke).attr("stroke-width", 1.5);
|
|
26954
|
+
participantG.append("text").attr("x", 0).attr("y", -GROUP_PADDING_TOP + fullH / 2).attr("text-anchor", "middle").attr("dominant-baseline", "central").attr("fill", palette.text).attr("font-size", 13).attr("font-weight", 500).text(participant.label);
|
|
26955
|
+
participantG.append("clipPath").attr("id", clipId).append("rect").attr("x", -boxW / 2).attr("y", -GROUP_PADDING_TOP).attr("width", boxW).attr("height", fullH).attr("rx", 6);
|
|
26956
|
+
participantG.append("rect").attr("class", "sequence-drill-bar").attr("x", -boxW / 2).attr("y", -GROUP_PADDING_TOP + fullH - drillBarH).attr("width", boxW).attr("height", drillBarH).attr("fill", drillColor).attr("clip-path", `url(#${clipId})`);
|
|
26957
|
+
}
|
|
26958
|
+
const llY = isCollapsedGroup ? lifelineStartY + GROUP_PADDING_BOTTOM : lifelineStartY;
|
|
26959
|
+
const llColor = isCollapsedGroup ? effectiveTagColor || palette.textMuted : pTagColor || palette.textMuted;
|
|
26960
|
+
const lifelineEl = svg.append("line").attr("x1", cx).attr("y1", llY).attr("x2", cx).attr("y2", lifelineStartY + lifelineLength).attr("stroke", llColor).attr("stroke-width", 1).attr("stroke-dasharray", "6 4").attr("class", "lifeline").attr("data-participant-id", participant.id);
|
|
26424
26961
|
if (tagKey && pTagValue) {
|
|
26425
26962
|
lifelineEl.attr(`data-tag-${tagKey}`, pTagValue.toLowerCase());
|
|
26426
26963
|
}
|
|
@@ -26648,23 +27185,8 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
|
|
|
26648
27185
|
sectionG.append("rect").attr("x", bandX).attr("y", secY - BAND_HEIGHT / 2).attr("width", bandWidth).attr("height", BAND_HEIGHT).attr("fill", lineColor).attr("opacity", bandOpacity).attr("rx", 2).attr("class", "section-divider");
|
|
26649
27186
|
const msgCount = sectionMsgCounts.get(sec.lineNumber) ?? 0;
|
|
26650
27187
|
const labelText = isCollapsed ? `${sec.label} (${msgCount} ${msgCount === 1 ? "message" : "messages"})` : sec.label;
|
|
26651
|
-
const labelColor = isCollapsed ? "#ffffff" : lineColor;
|
|
26652
|
-
const chevronSpace = 14;
|
|
26653
27188
|
const labelX = (sectionLineX1 + sectionLineX2) / 2;
|
|
26654
|
-
|
|
26655
|
-
const chevronY = secY;
|
|
26656
|
-
if (isCollapsed) {
|
|
26657
|
-
sectionG.append("path").attr(
|
|
26658
|
-
"d",
|
|
26659
|
-
`M ${chevronX} ${chevronY - 4} L ${chevronX + 6} ${chevronY} L ${chevronX} ${chevronY + 4} Z`
|
|
26660
|
-
).attr("fill", labelColor).attr("class", "section-chevron");
|
|
26661
|
-
} else {
|
|
26662
|
-
sectionG.append("path").attr(
|
|
26663
|
-
"d",
|
|
26664
|
-
`M ${chevronX - 1} ${chevronY - 3} L ${chevronX + 7} ${chevronY - 3} L ${chevronX + 3} ${chevronY + 3} Z`
|
|
26665
|
-
).attr("fill", labelColor).attr("class", "section-chevron");
|
|
26666
|
-
}
|
|
26667
|
-
sectionG.append("text").attr("x", labelX + chevronSpace / 2).attr("y", secY + 4).attr("text-anchor", "middle").attr("fill", labelColor).attr("font-size", 11).attr("font-weight", "bold").attr("class", "section-label").text(labelText);
|
|
27189
|
+
sectionG.append("text").attr("x", labelX).attr("y", secY + 4).attr("text-anchor", "middle").attr("fill", lineColor).attr("font-size", 11).attr("font-weight", "bold").attr("class", "section-label").text(labelText);
|
|
26668
27190
|
}
|
|
26669
27191
|
const SELF_CALL_WIDTH = 30;
|
|
26670
27192
|
const SELF_CALL_HEIGHT = 25;
|
|
@@ -26703,7 +27225,7 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
|
|
|
26703
27225
|
if (tagKey && msgTagValue) {
|
|
26704
27226
|
labelEl.attr(`data-tag-${tagKey}`, msgTagValue.toLowerCase());
|
|
26705
27227
|
}
|
|
26706
|
-
|
|
27228
|
+
labelEl.text(step.label);
|
|
26707
27229
|
}
|
|
26708
27230
|
} else {
|
|
26709
27231
|
const goingRight = fromX < toX;
|
|
@@ -26730,7 +27252,7 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
|
|
|
26730
27252
|
if (tagKey && msgTagValue) {
|
|
26731
27253
|
labelEl.attr(`data-tag-${tagKey}`, msgTagValue.toLowerCase());
|
|
26732
27254
|
}
|
|
26733
|
-
|
|
27255
|
+
labelEl.text(step.label);
|
|
26734
27256
|
}
|
|
26735
27257
|
}
|
|
26736
27258
|
} else {
|
|
@@ -26761,7 +27283,7 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
|
|
|
26761
27283
|
if (tagKey && msgTagValue) {
|
|
26762
27284
|
labelEl.attr(`data-tag-${tagKey}`, msgTagValue.toLowerCase());
|
|
26763
27285
|
}
|
|
26764
|
-
|
|
27286
|
+
labelEl.text(step.label);
|
|
26765
27287
|
}
|
|
26766
27288
|
}
|
|
26767
27289
|
});
|
|
@@ -26945,6 +27467,7 @@ var init_renderer10 = __esm({
|
|
|
26945
27467
|
init_inline_markdown();
|
|
26946
27468
|
init_fonts();
|
|
26947
27469
|
init_parser();
|
|
27470
|
+
init_collapse3();
|
|
26948
27471
|
init_tag_resolution();
|
|
26949
27472
|
init_tag_groups();
|
|
26950
27473
|
init_legend_constants();
|
|
@@ -27037,23 +27560,6 @@ function parseTimelineDate(s) {
|
|
|
27037
27560
|
const day = parts.length >= 3 ? parts[2] : 1;
|
|
27038
27561
|
return year + (month - 1) / 12 + (day - 1) / 365 + hour / 8760 + minute / 525600;
|
|
27039
27562
|
}
|
|
27040
|
-
function fractionalYearToDate(frac) {
|
|
27041
|
-
const year = Math.floor(frac);
|
|
27042
|
-
const remainder = frac - year;
|
|
27043
|
-
const monthFrac = remainder * 12;
|
|
27044
|
-
const month = Math.floor(monthFrac);
|
|
27045
|
-
const monthRemainder = remainder - month / 12;
|
|
27046
|
-
const dayFrac = monthRemainder * 365;
|
|
27047
|
-
const day = Math.floor(dayFrac) + 1;
|
|
27048
|
-
const dayRemainder = dayFrac - Math.floor(dayFrac);
|
|
27049
|
-
const hourFrac = dayRemainder * 24;
|
|
27050
|
-
const hour = Math.floor(hourFrac);
|
|
27051
|
-
const minute = Math.round((hourFrac - hour) * 60);
|
|
27052
|
-
return new Date(year, month, day, hour, minute);
|
|
27053
|
-
}
|
|
27054
|
-
function dateToFractionalYear2(d) {
|
|
27055
|
-
return d.getFullYear() + d.getMonth() / 12 + (d.getDate() - 1) / 365 + d.getHours() / 8760 + d.getMinutes() / 525600;
|
|
27056
|
-
}
|
|
27057
27563
|
function addDurationToDate(startDate, amount, unit) {
|
|
27058
27564
|
const spaceIdx = startDate.indexOf(" ");
|
|
27059
27565
|
let datePart = startDate;
|
|
@@ -28608,7 +29114,7 @@ function formatDateLabel(dateStr) {
|
|
|
28608
29114
|
const parts = datePart.split("-");
|
|
28609
29115
|
const year = parts[0];
|
|
28610
29116
|
if (parts.length === 1) return year + timeSuffix;
|
|
28611
|
-
const month =
|
|
29117
|
+
const month = MONTH_ABBR[parseInt(parts[1], 10) - 1];
|
|
28612
29118
|
if (parts.length === 2) return `${month} ${year}${timeSuffix}`;
|
|
28613
29119
|
const day = parseInt(parts[2], 10);
|
|
28614
29120
|
return `${month} ${day}, ${year}${timeSuffix}`;
|
|
@@ -28625,123 +29131,6 @@ function formatBoundaryLabel(dateStr, otherDateStr) {
|
|
|
28625
29131
|
}
|
|
28626
29132
|
return formatDateLabel(dateStr);
|
|
28627
29133
|
}
|
|
28628
|
-
function computeTimeTicks(domainMin, domainMax, scale, boundaryStart, boundaryEnd, boundaryStartLabel, boundaryEndLabel) {
|
|
28629
|
-
const minYear = Math.floor(domainMin);
|
|
28630
|
-
const maxYear = Math.floor(domainMax);
|
|
28631
|
-
const span = domainMax - domainMin;
|
|
28632
|
-
let ticks = [];
|
|
28633
|
-
const firstYear = Math.ceil(domainMin);
|
|
28634
|
-
const lastYear = Math.floor(domainMax);
|
|
28635
|
-
if (lastYear >= firstYear + 1) {
|
|
28636
|
-
const yearSpan = lastYear - firstYear;
|
|
28637
|
-
let step = 1;
|
|
28638
|
-
if (yearSpan > 80) step = 20;
|
|
28639
|
-
else if (yearSpan > 40) step = 10;
|
|
28640
|
-
else if (yearSpan > 20) step = 5;
|
|
28641
|
-
else if (yearSpan > 10) step = 2;
|
|
28642
|
-
const alignedFirst = Math.ceil(firstYear / step) * step;
|
|
28643
|
-
for (let y = alignedFirst; y <= lastYear; y += step) {
|
|
28644
|
-
ticks.push({ pos: scale(y), label: String(y) });
|
|
28645
|
-
}
|
|
28646
|
-
} else if (span > 0.25) {
|
|
28647
|
-
const crossesYear = maxYear > minYear;
|
|
28648
|
-
for (let y = minYear; y <= maxYear + 1; y++) {
|
|
28649
|
-
for (let m = 1; m <= 12; m++) {
|
|
28650
|
-
const val = y + (m - 1) / 12;
|
|
28651
|
-
if (val > domainMax) break;
|
|
28652
|
-
if (val >= domainMin) {
|
|
28653
|
-
ticks.push({
|
|
28654
|
-
pos: scale(val),
|
|
28655
|
-
label: crossesYear ? `${MONTH_ABBR2[m - 1]} '${String(y).slice(-2)}` : MONTH_ABBR2[m - 1]
|
|
28656
|
-
});
|
|
28657
|
-
}
|
|
28658
|
-
}
|
|
28659
|
-
}
|
|
28660
|
-
} else if (span <= 685e-6) {
|
|
28661
|
-
let stepMin = 5;
|
|
28662
|
-
const spanHours = span * 8760;
|
|
28663
|
-
if (spanHours > 3) stepMin = 30;
|
|
28664
|
-
else if (spanHours > 1) stepMin = 15;
|
|
28665
|
-
else if (spanHours > 0.5) stepMin = 10;
|
|
28666
|
-
const startDate = fractionalYearToDate(domainMin);
|
|
28667
|
-
startDate.setMinutes(
|
|
28668
|
-
Math.floor(startDate.getMinutes() / stepMin) * stepMin,
|
|
28669
|
-
0,
|
|
28670
|
-
0
|
|
28671
|
-
);
|
|
28672
|
-
while (true) {
|
|
28673
|
-
const val = dateToFractionalYear2(startDate);
|
|
28674
|
-
if (val > domainMax) break;
|
|
28675
|
-
if (val >= domainMin) {
|
|
28676
|
-
const hh = String(startDate.getHours()).padStart(2, "0");
|
|
28677
|
-
const mm = String(startDate.getMinutes()).padStart(2, "0");
|
|
28678
|
-
ticks.push({ pos: scale(val), label: `${hh}:${mm}` });
|
|
28679
|
-
}
|
|
28680
|
-
startDate.setMinutes(startDate.getMinutes() + stepMin);
|
|
28681
|
-
}
|
|
28682
|
-
} else if (span <= 822e-5) {
|
|
28683
|
-
let stepHour = 1;
|
|
28684
|
-
const spanHours = span * 8760;
|
|
28685
|
-
if (spanHours > 48) stepHour = 6;
|
|
28686
|
-
else if (spanHours > 24) stepHour = 3;
|
|
28687
|
-
else if (spanHours > 12) stepHour = 2;
|
|
28688
|
-
const singleDay = spanHours <= 24;
|
|
28689
|
-
const startDate = fractionalYearToDate(domainMin);
|
|
28690
|
-
startDate.setHours(
|
|
28691
|
-
Math.floor(startDate.getHours() / stepHour) * stepHour,
|
|
28692
|
-
0,
|
|
28693
|
-
0,
|
|
28694
|
-
0
|
|
28695
|
-
);
|
|
28696
|
-
while (true) {
|
|
28697
|
-
const val = dateToFractionalYear2(startDate);
|
|
28698
|
-
if (val > domainMax) break;
|
|
28699
|
-
if (val >= domainMin) {
|
|
28700
|
-
const hh = String(startDate.getHours()).padStart(2, "0");
|
|
28701
|
-
const mm = String(startDate.getMinutes()).padStart(2, "0");
|
|
28702
|
-
if (singleDay) {
|
|
28703
|
-
ticks.push({ pos: scale(val), label: `${hh}:${mm}` });
|
|
28704
|
-
} else {
|
|
28705
|
-
const mon = MONTH_ABBR2[startDate.getMonth()];
|
|
28706
|
-
const d = startDate.getDate();
|
|
28707
|
-
ticks.push({ pos: scale(val), label: `${mon} ${d} ${hh}:${mm}` });
|
|
28708
|
-
}
|
|
28709
|
-
}
|
|
28710
|
-
startDate.setHours(startDate.getHours() + stepHour);
|
|
28711
|
-
}
|
|
28712
|
-
} else {
|
|
28713
|
-
for (let y = minYear; y <= maxYear + 1; y++) {
|
|
28714
|
-
for (let m = 1; m <= 12; m++) {
|
|
28715
|
-
for (const d of [1, 8, 15, 22]) {
|
|
28716
|
-
const val = y + (m - 1) / 12 + (d - 1) / 365;
|
|
28717
|
-
if (val > domainMax) break;
|
|
28718
|
-
if (val >= domainMin) {
|
|
28719
|
-
ticks.push({
|
|
28720
|
-
pos: scale(val),
|
|
28721
|
-
label: `${MONTH_ABBR2[m - 1]} ${d}`
|
|
28722
|
-
});
|
|
28723
|
-
}
|
|
28724
|
-
}
|
|
28725
|
-
}
|
|
28726
|
-
}
|
|
28727
|
-
}
|
|
28728
|
-
const collisionThreshold = 40;
|
|
28729
|
-
if (boundaryStart !== void 0 && boundaryStartLabel) {
|
|
28730
|
-
const boundaryPos = scale(boundaryStart);
|
|
28731
|
-
ticks = ticks.filter(
|
|
28732
|
-
(t) => Math.abs(t.pos - boundaryPos) >= collisionThreshold
|
|
28733
|
-
);
|
|
28734
|
-
ticks.unshift({ pos: boundaryPos, label: boundaryStartLabel });
|
|
28735
|
-
}
|
|
28736
|
-
if (boundaryEnd !== void 0 && boundaryEndLabel) {
|
|
28737
|
-
const boundaryPos = scale(boundaryEnd);
|
|
28738
|
-
ticks = ticks.filter(
|
|
28739
|
-
(t) => Math.abs(t.pos - boundaryPos) >= collisionThreshold
|
|
28740
|
-
);
|
|
28741
|
-
ticks.push({ pos: boundaryPos, label: boundaryEndLabel });
|
|
28742
|
-
}
|
|
28743
|
-
return ticks;
|
|
28744
|
-
}
|
|
28745
29134
|
function renderTimeScale(g, scale, isVertical, innerWidth, innerHeight, textColor, boundaryStart, boundaryEnd, boundaryStartLabel, boundaryEndLabel) {
|
|
28746
29135
|
const [domainMin, domainMax] = scale.domain();
|
|
28747
29136
|
const ticks = computeTimeTicks(
|
|
@@ -30669,7 +31058,7 @@ function createExportContainer(width, height) {
|
|
|
30669
31058
|
document.body.appendChild(container);
|
|
30670
31059
|
return container;
|
|
30671
31060
|
}
|
|
30672
|
-
function finalizeSvgExport(container, theme, palette
|
|
31061
|
+
function finalizeSvgExport(container, theme, palette) {
|
|
30673
31062
|
const svgEl = container.querySelector("svg");
|
|
30674
31063
|
if (!svgEl) return "";
|
|
30675
31064
|
if (theme === "transparent") {
|
|
@@ -30682,10 +31071,6 @@ function finalizeSvgExport(container, theme, palette, options) {
|
|
|
30682
31071
|
svgEl.querySelectorAll("[data-export-ignore]").forEach((el) => el.remove());
|
|
30683
31072
|
const svgHtml = svgEl.outerHTML;
|
|
30684
31073
|
document.body.removeChild(container);
|
|
30685
|
-
if (options?.branding !== false) {
|
|
30686
|
-
const brandColor = theme === "transparent" ? "#888" : palette.textMuted;
|
|
30687
|
-
return injectBranding(svgHtml, brandColor);
|
|
30688
|
-
}
|
|
30689
31074
|
return svgHtml;
|
|
30690
31075
|
}
|
|
30691
31076
|
async function renderForExport(content, theme, palette, orgExportState, options) {
|
|
@@ -30732,7 +31117,7 @@ async function renderForExport(content, theme, palette, orgExportState, options)
|
|
|
30732
31117
|
activeTagGroup,
|
|
30733
31118
|
hiddenAttributes
|
|
30734
31119
|
);
|
|
30735
|
-
return finalizeSvgExport(container2, theme, effectivePalette2
|
|
31120
|
+
return finalizeSvgExport(container2, theme, effectivePalette2);
|
|
30736
31121
|
}
|
|
30737
31122
|
if (detectedType === "sitemap") {
|
|
30738
31123
|
const { parseSitemap: parseSitemap2 } = await Promise.resolve().then(() => (init_parser7(), parser_exports7));
|
|
@@ -30774,7 +31159,7 @@ async function renderForExport(content, theme, palette, orgExportState, options)
|
|
|
30774
31159
|
activeTagGroup,
|
|
30775
31160
|
hiddenAttributes
|
|
30776
31161
|
);
|
|
30777
|
-
return finalizeSvgExport(container2, theme, effectivePalette2
|
|
31162
|
+
return finalizeSvgExport(container2, theme, effectivePalette2);
|
|
30778
31163
|
}
|
|
30779
31164
|
if (detectedType === "kanban") {
|
|
30780
31165
|
const { parseKanban: parseKanban2 } = await Promise.resolve().then(() => (init_parser5(), parser_exports5));
|
|
@@ -30793,7 +31178,7 @@ async function renderForExport(content, theme, palette, orgExportState, options)
|
|
|
30793
31178
|
options?.tagGroup
|
|
30794
31179
|
)
|
|
30795
31180
|
});
|
|
30796
|
-
return finalizeSvgExport(container2, theme, effectivePalette2
|
|
31181
|
+
return finalizeSvgExport(container2, theme, effectivePalette2);
|
|
30797
31182
|
}
|
|
30798
31183
|
if (detectedType === "class") {
|
|
30799
31184
|
const { parseClassDiagram: parseClassDiagram2 } = await Promise.resolve().then(() => (init_parser2(), parser_exports2));
|
|
@@ -30817,7 +31202,7 @@ async function renderForExport(content, theme, palette, orgExportState, options)
|
|
|
30817
31202
|
void 0,
|
|
30818
31203
|
{ width: exportWidth, height: exportHeight }
|
|
30819
31204
|
);
|
|
30820
|
-
return finalizeSvgExport(container2, theme, effectivePalette2
|
|
31205
|
+
return finalizeSvgExport(container2, theme, effectivePalette2);
|
|
30821
31206
|
}
|
|
30822
31207
|
if (detectedType === "er") {
|
|
30823
31208
|
const { parseERDiagram: parseERDiagram2 } = await Promise.resolve().then(() => (init_parser3(), parser_exports3));
|
|
@@ -30846,7 +31231,7 @@ async function renderForExport(content, theme, palette, orgExportState, options)
|
|
|
30846
31231
|
options?.tagGroup
|
|
30847
31232
|
)
|
|
30848
31233
|
);
|
|
30849
|
-
return finalizeSvgExport(container2, theme, effectivePalette2
|
|
31234
|
+
return finalizeSvgExport(container2, theme, effectivePalette2);
|
|
30850
31235
|
}
|
|
30851
31236
|
if (detectedType === "boxes-and-lines") {
|
|
30852
31237
|
const { parseBoxesAndLines: parseBoxesAndLines2 } = await Promise.resolve().then(() => (init_parser10(), parser_exports10));
|
|
@@ -30872,7 +31257,7 @@ async function renderForExport(content, theme, palette, orgExportState, options)
|
|
|
30872
31257
|
activeTagGroup: options?.tagGroup
|
|
30873
31258
|
}
|
|
30874
31259
|
);
|
|
30875
|
-
return finalizeSvgExport(container2, theme, effectivePalette2
|
|
31260
|
+
return finalizeSvgExport(container2, theme, effectivePalette2);
|
|
30876
31261
|
}
|
|
30877
31262
|
if (detectedType === "c4") {
|
|
30878
31263
|
const { parseC4: parseC42 } = await Promise.resolve().then(() => (init_parser6(), parser_exports6));
|
|
@@ -30911,7 +31296,7 @@ async function renderForExport(content, theme, palette, orgExportState, options)
|
|
|
30911
31296
|
options?.tagGroup
|
|
30912
31297
|
)
|
|
30913
31298
|
);
|
|
30914
|
-
return finalizeSvgExport(container2, theme, effectivePalette2
|
|
31299
|
+
return finalizeSvgExport(container2, theme, effectivePalette2);
|
|
30915
31300
|
}
|
|
30916
31301
|
if (detectedType === "flowchart") {
|
|
30917
31302
|
const { parseFlowchart: parseFlowchart2 } = await Promise.resolve().then(() => (init_flowchart_parser(), flowchart_parser_exports));
|
|
@@ -30931,7 +31316,7 @@ async function renderForExport(content, theme, palette, orgExportState, options)
|
|
|
30931
31316
|
void 0,
|
|
30932
31317
|
{ width: EXPORT_WIDTH, height: EXPORT_HEIGHT }
|
|
30933
31318
|
);
|
|
30934
|
-
return finalizeSvgExport(container2, theme, effectivePalette2
|
|
31319
|
+
return finalizeSvgExport(container2, theme, effectivePalette2);
|
|
30935
31320
|
}
|
|
30936
31321
|
if (detectedType === "infra") {
|
|
30937
31322
|
const { parseInfra: parseInfra2 } = await Promise.resolve().then(() => (init_parser8(), parser_exports8));
|
|
@@ -30977,7 +31362,7 @@ async function renderForExport(content, theme, palette, orgExportState, options)
|
|
|
30977
31362
|
infraSvg.setAttribute("width", String(exportWidth));
|
|
30978
31363
|
infraSvg.setAttribute("height", String(exportHeight));
|
|
30979
31364
|
}
|
|
30980
|
-
return finalizeSvgExport(container2, theme, effectivePalette2
|
|
31365
|
+
return finalizeSvgExport(container2, theme, effectivePalette2);
|
|
30981
31366
|
}
|
|
30982
31367
|
if (detectedType === "gantt") {
|
|
30983
31368
|
const { parseGantt: parseGantt2 } = await Promise.resolve().then(() => (init_parser9(), parser_exports9));
|
|
@@ -30998,7 +31383,7 @@ async function renderForExport(content, theme, palette, orgExportState, options)
|
|
|
30998
31383
|
void 0,
|
|
30999
31384
|
{ width: EXPORT_W, height: EXPORT_H }
|
|
31000
31385
|
);
|
|
31001
|
-
return finalizeSvgExport(container2, theme, effectivePalette2
|
|
31386
|
+
return finalizeSvgExport(container2, theme, effectivePalette2);
|
|
31002
31387
|
}
|
|
31003
31388
|
if (detectedType === "state") {
|
|
31004
31389
|
const { parseState: parseState2 } = await Promise.resolve().then(() => (init_state_parser(), state_parser_exports));
|
|
@@ -31018,7 +31403,7 @@ async function renderForExport(content, theme, palette, orgExportState, options)
|
|
|
31018
31403
|
void 0,
|
|
31019
31404
|
{ width: EXPORT_WIDTH, height: EXPORT_HEIGHT }
|
|
31020
31405
|
);
|
|
31021
|
-
return finalizeSvgExport(container2, theme, effectivePalette2
|
|
31406
|
+
return finalizeSvgExport(container2, theme, effectivePalette2);
|
|
31022
31407
|
}
|
|
31023
31408
|
const parsed = parseVisualization(content, palette);
|
|
31024
31409
|
if (parsed.error && parsed.type !== "sequence") {
|
|
@@ -31110,15 +31495,15 @@ async function renderForExport(content, theme, palette, orgExportState, options)
|
|
|
31110
31495
|
dims
|
|
31111
31496
|
);
|
|
31112
31497
|
}
|
|
31113
|
-
return finalizeSvgExport(container, theme, effectivePalette
|
|
31498
|
+
return finalizeSvgExport(container, theme, effectivePalette);
|
|
31114
31499
|
}
|
|
31115
|
-
var DEFAULT_CLOUD_OPTIONS, STOP_WORDS, SLOPE_MARGIN, SLOPE_LABEL_FONT_SIZE, SLOPE_CHAR_WIDTH, ARC_MARGIN,
|
|
31500
|
+
var DEFAULT_CLOUD_OPTIONS, STOP_WORDS, SLOPE_MARGIN, SLOPE_LABEL_FONT_SIZE, SLOPE_CHAR_WIDTH, ARC_MARGIN, EXPORT_WIDTH, EXPORT_HEIGHT;
|
|
31116
31501
|
var init_d3 = __esm({
|
|
31117
31502
|
"src/d3.ts"() {
|
|
31118
31503
|
"use strict";
|
|
31119
31504
|
init_fonts();
|
|
31120
|
-
init_branding();
|
|
31121
31505
|
init_label_layout();
|
|
31506
|
+
init_time_ticks();
|
|
31122
31507
|
init_colors();
|
|
31123
31508
|
init_palettes();
|
|
31124
31509
|
init_color_utils();
|
|
@@ -31249,20 +31634,6 @@ var init_d3 = __esm({
|
|
|
31249
31634
|
SLOPE_LABEL_FONT_SIZE = 14;
|
|
31250
31635
|
SLOPE_CHAR_WIDTH = 8;
|
|
31251
31636
|
ARC_MARGIN = { top: 60, right: 40, bottom: 60, left: 40 };
|
|
31252
|
-
MONTH_ABBR2 = [
|
|
31253
|
-
"Jan",
|
|
31254
|
-
"Feb",
|
|
31255
|
-
"Mar",
|
|
31256
|
-
"Apr",
|
|
31257
|
-
"May",
|
|
31258
|
-
"Jun",
|
|
31259
|
-
"Jul",
|
|
31260
|
-
"Aug",
|
|
31261
|
-
"Sep",
|
|
31262
|
-
"Oct",
|
|
31263
|
-
"Nov",
|
|
31264
|
-
"Dec"
|
|
31265
|
-
];
|
|
31266
31637
|
EXPORT_WIDTH = 1200;
|
|
31267
31638
|
EXPORT_HEIGHT = 800;
|
|
31268
31639
|
}
|
|
@@ -31727,6 +32098,7 @@ var require_lz_string = __commonJS({
|
|
|
31727
32098
|
|
|
31728
32099
|
// src/index.ts
|
|
31729
32100
|
init_diagnostics();
|
|
32101
|
+
init_arrows();
|
|
31730
32102
|
|
|
31731
32103
|
// src/render.ts
|
|
31732
32104
|
init_d3();
|
|
@@ -31762,8 +32134,8 @@ async function ensureDom() {
|
|
|
31762
32134
|
async function render(content, options) {
|
|
31763
32135
|
const theme = options?.theme ?? "light";
|
|
31764
32136
|
const paletteName = options?.palette ?? "nord";
|
|
31765
|
-
const branding = options?.branding ?? false;
|
|
31766
32137
|
const paletteColors = getPalette(paletteName)[theme === "dark" ? "dark" : "light"];
|
|
32138
|
+
const { diagnostics } = parseDgmo(content);
|
|
31767
32139
|
const chartType = parseDgmoChartType(content);
|
|
31768
32140
|
const category = chartType ? getRenderCategory(chartType) : null;
|
|
31769
32141
|
const legendExportState = options?.legendState ? {
|
|
@@ -31771,18 +32143,27 @@ async function render(content, options) {
|
|
|
31771
32143
|
hiddenAttributes: options.legendState.hiddenAttributes ? new Set(options.legendState.hiddenAttributes) : void 0
|
|
31772
32144
|
} : void 0;
|
|
31773
32145
|
if (category === "data-chart") {
|
|
31774
|
-
|
|
31775
|
-
|
|
31776
|
-
|
|
32146
|
+
const svg2 = await renderExtendedChartForExport(
|
|
32147
|
+
content,
|
|
32148
|
+
theme,
|
|
32149
|
+
paletteColors
|
|
32150
|
+
);
|
|
32151
|
+
return { svg: svg2, diagnostics };
|
|
31777
32152
|
}
|
|
31778
32153
|
await ensureDom();
|
|
31779
|
-
|
|
31780
|
-
|
|
31781
|
-
|
|
31782
|
-
|
|
31783
|
-
|
|
31784
|
-
|
|
31785
|
-
|
|
32154
|
+
const svg = await renderForExport(
|
|
32155
|
+
content,
|
|
32156
|
+
theme,
|
|
32157
|
+
paletteColors,
|
|
32158
|
+
legendExportState,
|
|
32159
|
+
{
|
|
32160
|
+
c4Level: options?.c4Level,
|
|
32161
|
+
c4System: options?.c4System,
|
|
32162
|
+
c4Container: options?.c4Container,
|
|
32163
|
+
tagGroup: options?.tagGroup
|
|
32164
|
+
}
|
|
32165
|
+
);
|
|
32166
|
+
return { svg, diagnostics };
|
|
31786
32167
|
}
|
|
31787
32168
|
|
|
31788
32169
|
// src/index.ts
|
|
@@ -31790,172 +32171,9 @@ init_dgmo_router();
|
|
|
31790
32171
|
init_chart();
|
|
31791
32172
|
init_echarts();
|
|
31792
32173
|
init_d3();
|
|
32174
|
+
init_time_ticks();
|
|
31793
32175
|
init_parser();
|
|
31794
32176
|
init_participant_inference();
|
|
31795
|
-
|
|
31796
|
-
// src/dgmo-mermaid.ts
|
|
31797
|
-
init_colors();
|
|
31798
|
-
init_diagnostics();
|
|
31799
|
-
var QUADRANT_LABEL_RE = /^(.+?)(?:\s*\(([^)]+)\))?\s*$/;
|
|
31800
|
-
var DATA_POINT_RE = /^(.+?)\s+([0-9]*\.?[0-9]+)\s*,\s*([0-9]*\.?[0-9]+)\s*$/;
|
|
31801
|
-
var QUADRANT_POSITIONS = /* @__PURE__ */ new Set([
|
|
31802
|
-
"top-right",
|
|
31803
|
-
"top-left",
|
|
31804
|
-
"bottom-left",
|
|
31805
|
-
"bottom-right"
|
|
31806
|
-
]);
|
|
31807
|
-
function parseQuadrant(content) {
|
|
31808
|
-
const result = {
|
|
31809
|
-
title: null,
|
|
31810
|
-
titleLineNumber: null,
|
|
31811
|
-
xAxis: null,
|
|
31812
|
-
xAxisLineNumber: null,
|
|
31813
|
-
yAxis: null,
|
|
31814
|
-
yAxisLineNumber: null,
|
|
31815
|
-
quadrants: {
|
|
31816
|
-
topRight: null,
|
|
31817
|
-
topLeft: null,
|
|
31818
|
-
bottomLeft: null,
|
|
31819
|
-
bottomRight: null
|
|
31820
|
-
},
|
|
31821
|
-
points: [],
|
|
31822
|
-
diagnostics: [],
|
|
31823
|
-
error: null
|
|
31824
|
-
};
|
|
31825
|
-
const lines = content.split("\n");
|
|
31826
|
-
for (let i = 0; i < lines.length; i++) {
|
|
31827
|
-
const line10 = lines[i].trim();
|
|
31828
|
-
const lineNumber = i + 1;
|
|
31829
|
-
if (!line10 || line10.startsWith("//")) continue;
|
|
31830
|
-
if (/^chart\s*:/i.test(line10)) continue;
|
|
31831
|
-
const titleMatch = line10.match(/^title\s+(.+)/i);
|
|
31832
|
-
if (titleMatch) {
|
|
31833
|
-
result.title = titleMatch[1].trim();
|
|
31834
|
-
result.titleLineNumber = lineNumber;
|
|
31835
|
-
continue;
|
|
31836
|
-
}
|
|
31837
|
-
const xMatch = line10.match(/^x-label\s+(.+)/i);
|
|
31838
|
-
if (xMatch) {
|
|
31839
|
-
const parts = xMatch[1].split(",").map((s) => s.trim());
|
|
31840
|
-
if (parts.length >= 2) {
|
|
31841
|
-
result.xAxis = [parts[0], parts[1]];
|
|
31842
|
-
result.xAxisLineNumber = lineNumber;
|
|
31843
|
-
}
|
|
31844
|
-
continue;
|
|
31845
|
-
}
|
|
31846
|
-
const yMatch = line10.match(/^y-label\s+(.+)/i);
|
|
31847
|
-
if (yMatch) {
|
|
31848
|
-
const parts = yMatch[1].split(",").map((s) => s.trim());
|
|
31849
|
-
if (parts.length >= 2) {
|
|
31850
|
-
result.yAxis = [parts[0], parts[1]];
|
|
31851
|
-
result.yAxisLineNumber = lineNumber;
|
|
31852
|
-
}
|
|
31853
|
-
continue;
|
|
31854
|
-
}
|
|
31855
|
-
const posMatch = line10.match(
|
|
31856
|
-
/^(top-right|top-left|bottom-left|bottom-right)\s+(.+)/i
|
|
31857
|
-
);
|
|
31858
|
-
if (posMatch) {
|
|
31859
|
-
const position = posMatch[1].toLowerCase();
|
|
31860
|
-
const labelMatch = posMatch[2].match(QUADRANT_LABEL_RE);
|
|
31861
|
-
if (labelMatch) {
|
|
31862
|
-
const label = {
|
|
31863
|
-
text: labelMatch[1].trim(),
|
|
31864
|
-
color: labelMatch[2] ? resolveColorWithDiagnostic(
|
|
31865
|
-
labelMatch[2].trim(),
|
|
31866
|
-
lineNumber,
|
|
31867
|
-
result.diagnostics
|
|
31868
|
-
) ?? null : null,
|
|
31869
|
-
lineNumber
|
|
31870
|
-
};
|
|
31871
|
-
if (position === "top-right") result.quadrants.topRight = label;
|
|
31872
|
-
else if (position === "top-left") result.quadrants.topLeft = label;
|
|
31873
|
-
else if (position === "bottom-left")
|
|
31874
|
-
result.quadrants.bottomLeft = label;
|
|
31875
|
-
else if (position === "bottom-right")
|
|
31876
|
-
result.quadrants.bottomRight = label;
|
|
31877
|
-
}
|
|
31878
|
-
continue;
|
|
31879
|
-
}
|
|
31880
|
-
const pointMatch = line10.match(DATA_POINT_RE);
|
|
31881
|
-
if (pointMatch) {
|
|
31882
|
-
const key = pointMatch[1].trim().toLowerCase();
|
|
31883
|
-
if (!QUADRANT_POSITIONS.has(key)) {
|
|
31884
|
-
result.points.push({
|
|
31885
|
-
label: pointMatch[1].trim(),
|
|
31886
|
-
x: parseFloat(pointMatch[2]),
|
|
31887
|
-
y: parseFloat(pointMatch[3]),
|
|
31888
|
-
lineNumber
|
|
31889
|
-
});
|
|
31890
|
-
}
|
|
31891
|
-
continue;
|
|
31892
|
-
}
|
|
31893
|
-
}
|
|
31894
|
-
if (result.points.length === 0) {
|
|
31895
|
-
const diag = makeDgmoError(
|
|
31896
|
-
1,
|
|
31897
|
-
"No data points found. Add lines like: Label 0.5, 0.7"
|
|
31898
|
-
);
|
|
31899
|
-
result.diagnostics.push(diag);
|
|
31900
|
-
result.error = formatDgmoError(diag);
|
|
31901
|
-
}
|
|
31902
|
-
return result;
|
|
31903
|
-
}
|
|
31904
|
-
function buildMermaidQuadrant(parsed, options = {}) {
|
|
31905
|
-
const { isDark = false, textColor, mutedTextColor } = options;
|
|
31906
|
-
const lines = [];
|
|
31907
|
-
const fillAlpha = isDark ? "30" : "55";
|
|
31908
|
-
const primaryText = textColor ?? (isDark ? "#d0d0d0" : "#333333");
|
|
31909
|
-
const quadrantLabelText = mutedTextColor ?? (isDark ? "#888888" : "#666666");
|
|
31910
|
-
const colorMap = {};
|
|
31911
|
-
if (parsed.quadrants.topRight?.color)
|
|
31912
|
-
colorMap.quadrant1Fill = parsed.quadrants.topRight.color + fillAlpha;
|
|
31913
|
-
if (parsed.quadrants.topLeft?.color)
|
|
31914
|
-
colorMap.quadrant2Fill = parsed.quadrants.topLeft.color + fillAlpha;
|
|
31915
|
-
if (parsed.quadrants.bottomLeft?.color)
|
|
31916
|
-
colorMap.quadrant3Fill = parsed.quadrants.bottomLeft.color + fillAlpha;
|
|
31917
|
-
if (parsed.quadrants.bottomRight?.color)
|
|
31918
|
-
colorMap.quadrant4Fill = parsed.quadrants.bottomRight.color + fillAlpha;
|
|
31919
|
-
colorMap.quadrant1TextFill = quadrantLabelText;
|
|
31920
|
-
colorMap.quadrant2TextFill = quadrantLabelText;
|
|
31921
|
-
colorMap.quadrant3TextFill = quadrantLabelText;
|
|
31922
|
-
colorMap.quadrant4TextFill = quadrantLabelText;
|
|
31923
|
-
colorMap.quadrantPointTextFill = primaryText;
|
|
31924
|
-
colorMap.quadrantXAxisTextFill = primaryText;
|
|
31925
|
-
colorMap.quadrantYAxisTextFill = primaryText;
|
|
31926
|
-
colorMap.quadrantTitleFill = primaryText;
|
|
31927
|
-
const vars = JSON.stringify(colorMap);
|
|
31928
|
-
lines.push(`%%{init: {"themeVariables": ${vars}}}%%`);
|
|
31929
|
-
lines.push("quadrantChart");
|
|
31930
|
-
if (parsed.title) {
|
|
31931
|
-
lines.push(` title ${parsed.title}`);
|
|
31932
|
-
}
|
|
31933
|
-
if (parsed.xAxis) {
|
|
31934
|
-
lines.push(` x-axis ${parsed.xAxis[0]} --> ${parsed.xAxis[1]}`);
|
|
31935
|
-
}
|
|
31936
|
-
if (parsed.yAxis) {
|
|
31937
|
-
lines.push(` y-axis ${parsed.yAxis[0]} --> ${parsed.yAxis[1]}`);
|
|
31938
|
-
}
|
|
31939
|
-
const quote = (s) => /[\s,:[\]]/.test(s) ? `"${s}"` : s;
|
|
31940
|
-
if (parsed.quadrants.topRight) {
|
|
31941
|
-
lines.push(` quadrant-1 ${quote(parsed.quadrants.topRight.text)}`);
|
|
31942
|
-
}
|
|
31943
|
-
if (parsed.quadrants.topLeft) {
|
|
31944
|
-
lines.push(` quadrant-2 ${quote(parsed.quadrants.topLeft.text)}`);
|
|
31945
|
-
}
|
|
31946
|
-
if (parsed.quadrants.bottomLeft) {
|
|
31947
|
-
lines.push(` quadrant-3 ${quote(parsed.quadrants.bottomLeft.text)}`);
|
|
31948
|
-
}
|
|
31949
|
-
if (parsed.quadrants.bottomRight) {
|
|
31950
|
-
lines.push(` quadrant-4 ${quote(parsed.quadrants.bottomRight.text)}`);
|
|
31951
|
-
}
|
|
31952
|
-
for (const point of parsed.points) {
|
|
31953
|
-
lines.push(` ${quote(point.label)}: [${point.x}, ${point.y}]`);
|
|
31954
|
-
}
|
|
31955
|
-
return lines.join("\n");
|
|
31956
|
-
}
|
|
31957
|
-
|
|
31958
|
-
// src/index.ts
|
|
31959
32177
|
init_flowchart_parser();
|
|
31960
32178
|
init_state_parser();
|
|
31961
32179
|
init_state_renderer();
|
|
@@ -32507,6 +32725,7 @@ init_legend_d3();
|
|
|
32507
32725
|
init_legend_layout();
|
|
32508
32726
|
init_d3();
|
|
32509
32727
|
init_renderer10();
|
|
32728
|
+
init_collapse3();
|
|
32510
32729
|
init_colors();
|
|
32511
32730
|
init_palettes();
|
|
32512
32731
|
|
|
@@ -32514,6 +32733,24 @@ init_palettes();
|
|
|
32514
32733
|
var import_lz_string = __toESM(require_lz_string(), 1);
|
|
32515
32734
|
var DEFAULT_BASE_URL = "https://online.diagrammo.app";
|
|
32516
32735
|
var COMPRESSED_SIZE_LIMIT = 8192;
|
|
32736
|
+
function encodeViewState(state) {
|
|
32737
|
+
const keys = Object.keys(state);
|
|
32738
|
+
if (keys.length === 0) return "";
|
|
32739
|
+
return (0, import_lz_string.compressToEncodedURIComponent)(JSON.stringify(state));
|
|
32740
|
+
}
|
|
32741
|
+
function decodeViewState(encoded) {
|
|
32742
|
+
if (!encoded) return {};
|
|
32743
|
+
try {
|
|
32744
|
+
const json = (0, import_lz_string.decompressFromEncodedURIComponent)(encoded);
|
|
32745
|
+
if (!json) return {};
|
|
32746
|
+
const parsed = JSON.parse(json);
|
|
32747
|
+
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed))
|
|
32748
|
+
return {};
|
|
32749
|
+
return parsed;
|
|
32750
|
+
} catch {
|
|
32751
|
+
return {};
|
|
32752
|
+
}
|
|
32753
|
+
}
|
|
32517
32754
|
function encodeDiagramUrl(dsl, options) {
|
|
32518
32755
|
const baseUrl = options?.baseUrl ?? DEFAULT_BASE_URL;
|
|
32519
32756
|
const compressed = (0, import_lz_string.compressToEncodedURIComponent)(dsl);
|
|
@@ -32526,23 +32763,17 @@ function encodeDiagramUrl(dsl, options) {
|
|
|
32526
32763
|
};
|
|
32527
32764
|
}
|
|
32528
32765
|
let hash = `dgmo=${compressed}`;
|
|
32529
|
-
if (options?.viewState
|
|
32530
|
-
|
|
32531
|
-
|
|
32532
|
-
|
|
32533
|
-
|
|
32534
|
-
}
|
|
32535
|
-
if (options?.viewState?.swimlaneTagGroup) {
|
|
32536
|
-
hash += `&swim=${encodeURIComponent(options.viewState.swimlaneTagGroup)}`;
|
|
32537
|
-
}
|
|
32538
|
-
if (options?.viewState?.collapsedLanes?.length) {
|
|
32539
|
-
hash += `&cl=${encodeURIComponent(options.viewState.collapsedLanes.join(","))}`;
|
|
32766
|
+
if (options?.viewState) {
|
|
32767
|
+
const vsEncoded = encodeViewState(options.viewState);
|
|
32768
|
+
if (vsEncoded) {
|
|
32769
|
+
hash += `&vs=${vsEncoded}`;
|
|
32770
|
+
}
|
|
32540
32771
|
}
|
|
32541
|
-
if (options?.
|
|
32542
|
-
hash += `&pal=${encodeURIComponent(options.
|
|
32772
|
+
if (options?.palette && options.palette !== "nord") {
|
|
32773
|
+
hash += `&pal=${encodeURIComponent(options.palette)}`;
|
|
32543
32774
|
}
|
|
32544
|
-
if (options?.
|
|
32545
|
-
hash += `&th=${encodeURIComponent(options.
|
|
32775
|
+
if (options?.theme && options.theme !== "dark") {
|
|
32776
|
+
hash += `&th=${encodeURIComponent(options.theme)}`;
|
|
32546
32777
|
}
|
|
32547
32778
|
if (options?.filename) {
|
|
32548
32779
|
hash += `&fn=${encodeURIComponent(options.filename)}`;
|
|
@@ -32552,6 +32783,8 @@ function encodeDiagramUrl(dsl, options) {
|
|
|
32552
32783
|
function decodeDiagramUrl(hash) {
|
|
32553
32784
|
const empty = { dsl: "", viewState: {} };
|
|
32554
32785
|
let filename;
|
|
32786
|
+
let palette;
|
|
32787
|
+
let theme;
|
|
32555
32788
|
if (!hash) return empty;
|
|
32556
32789
|
let raw = hash;
|
|
32557
32790
|
if (raw.startsWith("#") || raw.startsWith("?")) {
|
|
@@ -32559,38 +32792,31 @@ function decodeDiagramUrl(hash) {
|
|
|
32559
32792
|
}
|
|
32560
32793
|
const parts = raw.split("&");
|
|
32561
32794
|
let payload = parts[0];
|
|
32562
|
-
|
|
32795
|
+
let viewState = {};
|
|
32563
32796
|
for (let i = 1; i < parts.length; i++) {
|
|
32564
32797
|
const eq = parts[i].indexOf("=");
|
|
32565
32798
|
if (eq === -1) continue;
|
|
32566
32799
|
const key = parts[i].slice(0, eq);
|
|
32567
|
-
const val =
|
|
32568
|
-
if (key === "
|
|
32569
|
-
viewState
|
|
32570
|
-
}
|
|
32571
|
-
if (key === "cg" && val) {
|
|
32572
|
-
viewState.collapsedGroups = val.split(",").filter(Boolean);
|
|
32573
|
-
}
|
|
32574
|
-
if (key === "swim" && val) {
|
|
32575
|
-
viewState.swimlaneTagGroup = val;
|
|
32800
|
+
const val = parts[i].slice(eq + 1);
|
|
32801
|
+
if (key === "vs" && val) {
|
|
32802
|
+
viewState = decodeViewState(val);
|
|
32576
32803
|
}
|
|
32577
|
-
if (key === "
|
|
32578
|
-
|
|
32804
|
+
if (key === "pal" && val) palette = decodeURIComponent(val);
|
|
32805
|
+
if (key === "th") {
|
|
32806
|
+
const decoded = decodeURIComponent(val);
|
|
32807
|
+
if (decoded === "light" || decoded === "dark") theme = decoded;
|
|
32579
32808
|
}
|
|
32580
|
-
if (key === "
|
|
32581
|
-
if (key === "th" && (val === "light" || val === "dark"))
|
|
32582
|
-
viewState.theme = val;
|
|
32583
|
-
if (key === "fn" && val) filename = val;
|
|
32809
|
+
if (key === "fn" && val) filename = decodeURIComponent(val);
|
|
32584
32810
|
}
|
|
32585
32811
|
if (payload.startsWith("dgmo=")) {
|
|
32586
32812
|
payload = payload.slice(5);
|
|
32587
32813
|
}
|
|
32588
|
-
if (!payload) return { dsl: "", viewState, filename };
|
|
32814
|
+
if (!payload) return { dsl: "", viewState, palette, theme, filename };
|
|
32589
32815
|
try {
|
|
32590
32816
|
const result = (0, import_lz_string.decompressFromEncodedURIComponent)(payload);
|
|
32591
|
-
return { dsl: result ?? "", viewState, filename };
|
|
32817
|
+
return { dsl: result ?? "", viewState, palette, theme, filename };
|
|
32592
32818
|
} catch {
|
|
32593
|
-
return { dsl: "", viewState, filename };
|
|
32819
|
+
return { dsl: "", viewState, palette, theme, filename };
|
|
32594
32820
|
}
|
|
32595
32821
|
}
|
|
32596
32822
|
|
|
@@ -33337,9 +33563,9 @@ registerExtractor("boxes-and-lines", extractBoxesAndLinesSymbols);
|
|
|
33337
33563
|
|
|
33338
33564
|
// src/index.ts
|
|
33339
33565
|
init_parsing();
|
|
33340
|
-
init_branding();
|
|
33341
33566
|
export {
|
|
33342
33567
|
ALL_CHART_TYPES,
|
|
33568
|
+
ARROW_DIAGNOSTIC_CODES,
|
|
33343
33569
|
CHART_TYPES,
|
|
33344
33570
|
COMPLETION_REGISTRY,
|
|
33345
33571
|
ENTITY_TYPES,
|
|
@@ -33350,17 +33576,15 @@ export {
|
|
|
33350
33576
|
RECOGNIZED_COLOR_NAMES,
|
|
33351
33577
|
RULE_COUNT,
|
|
33352
33578
|
addDurationToDate,
|
|
33579
|
+
applyCollapseProjection,
|
|
33353
33580
|
applyGroupOrdering,
|
|
33354
33581
|
applyPositionOverrides,
|
|
33355
33582
|
boldPalette,
|
|
33356
33583
|
buildExtendedChartOption,
|
|
33357
|
-
buildMermaidQuadrant,
|
|
33358
|
-
buildMermaidThemeVars,
|
|
33359
33584
|
buildNoteMessageMap,
|
|
33360
33585
|
buildRenderSequence,
|
|
33361
33586
|
buildSimpleChartOption,
|
|
33362
33587
|
buildTagLaneRowList,
|
|
33363
|
-
buildThemeCSS,
|
|
33364
33588
|
calculateSchedule,
|
|
33365
33589
|
catppuccinPalette,
|
|
33366
33590
|
collapseBoxesAndLines,
|
|
@@ -33379,8 +33603,10 @@ export {
|
|
|
33379
33603
|
computeTimeTicks,
|
|
33380
33604
|
contrastText,
|
|
33381
33605
|
decodeDiagramUrl,
|
|
33606
|
+
decodeViewState,
|
|
33382
33607
|
draculaPalette,
|
|
33383
33608
|
encodeDiagramUrl,
|
|
33609
|
+
encodeViewState,
|
|
33384
33610
|
extractDiagramSymbols,
|
|
33385
33611
|
extractTagDeclarations,
|
|
33386
33612
|
formatDateLabel,
|
|
@@ -33399,7 +33625,6 @@ export {
|
|
|
33399
33625
|
hslToHex,
|
|
33400
33626
|
inferParticipantType,
|
|
33401
33627
|
inferRoles,
|
|
33402
|
-
injectBranding,
|
|
33403
33628
|
isArchiveColumn,
|
|
33404
33629
|
isExtendedChartType,
|
|
33405
33630
|
isRecognizedColorName,
|
|
@@ -33424,8 +33649,8 @@ export {
|
|
|
33424
33649
|
looksLikeSitemap,
|
|
33425
33650
|
looksLikeState,
|
|
33426
33651
|
makeDgmoError,
|
|
33652
|
+
matchColorParens,
|
|
33427
33653
|
monokaiPalette,
|
|
33428
|
-
mute,
|
|
33429
33654
|
nord,
|
|
33430
33655
|
nordPalette,
|
|
33431
33656
|
oneDarkPalette,
|
|
@@ -33443,11 +33668,11 @@ export {
|
|
|
33443
33668
|
parseFirstLine,
|
|
33444
33669
|
parseFlowchart,
|
|
33445
33670
|
parseGantt,
|
|
33671
|
+
parseInArrowLabel,
|
|
33446
33672
|
parseInfra,
|
|
33447
33673
|
parseInlineMarkdown,
|
|
33448
33674
|
parseKanban,
|
|
33449
33675
|
parseOrg,
|
|
33450
|
-
parseQuadrant,
|
|
33451
33676
|
parseSequenceDgmo,
|
|
33452
33677
|
parseSitemap,
|
|
33453
33678
|
parseState,
|
|
@@ -33506,6 +33731,7 @@ export {
|
|
|
33506
33731
|
tokyoNightPalette,
|
|
33507
33732
|
truncateBareUrl,
|
|
33508
33733
|
validateComputed,
|
|
33509
|
-
validateInfra
|
|
33734
|
+
validateInfra,
|
|
33735
|
+
validateLabelCharacters
|
|
33510
33736
|
};
|
|
33511
33737
|
//# sourceMappingURL=index.js.map
|