schematex 0.5.0 → 0.5.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +15 -7
- package/dist/ai/ai-sdk.cjs +18 -12
- package/dist/ai/ai-sdk.cjs.map +1 -1
- package/dist/ai/ai-sdk.d.cts +4 -3
- package/dist/ai/ai-sdk.d.ts +4 -3
- package/dist/ai/ai-sdk.js +14 -8
- package/dist/ai/ai-sdk.js.map +1 -1
- package/dist/ai/index.cjs +15 -11
- package/dist/ai/index.d.cts +20 -153
- package/dist/ai/index.d.ts +20 -153
- package/dist/ai/index.js +3 -3
- package/dist/api-C5SECOxZ.d.cts +69 -0
- package/dist/api-Cr_MxttI.d.ts +69 -0
- package/dist/browser.cjs +23 -5
- package/dist/browser.cjs.map +1 -1
- package/dist/browser.d.cts +12 -3
- package/dist/browser.d.ts +12 -3
- package/dist/browser.js +13 -5
- package/dist/browser.js.map +1 -1
- package/dist/{chunk-3YUUC6RN.cjs → chunk-4QPDZJAL.cjs} +1421 -37
- package/dist/chunk-4QPDZJAL.cjs.map +1 -0
- package/dist/{chunk-NWPCY65Z.cjs → chunk-HK56GQQP.cjs} +544 -61
- package/dist/chunk-HK56GQQP.cjs.map +1 -0
- package/dist/{chunk-GTDQAN2Z.js → chunk-OK5ZS3LU.js} +1419 -38
- package/dist/chunk-OK5ZS3LU.js.map +1 -0
- package/dist/{chunk-XRCY75UV.cjs → chunk-QMTWG6JL.cjs} +947 -916
- package/dist/chunk-QMTWG6JL.cjs.map +1 -0
- package/dist/{chunk-HUPDIRBX.js → chunk-VCH7RI5H.js} +947 -916
- package/dist/chunk-VCH7RI5H.js.map +1 -0
- package/dist/{chunk-IM4RCUHA.js → chunk-VKPCR7BG.js} +544 -62
- package/dist/chunk-VKPCR7BG.js.map +1 -0
- package/dist/diagrams/blockdiagram/index.d.cts +1 -1
- package/dist/diagrams/blockdiagram/index.d.ts +1 -1
- package/dist/diagrams/circuit/index.cjs +7 -7
- package/dist/diagrams/circuit/index.d.cts +1 -1
- package/dist/diagrams/circuit/index.d.ts +1 -1
- package/dist/diagrams/circuit/index.js +1 -1
- package/dist/diagrams/ecomap/index.d.cts +1 -1
- package/dist/diagrams/ecomap/index.d.ts +1 -1
- package/dist/diagrams/entity/index.d.cts +1 -1
- package/dist/diagrams/entity/index.d.ts +1 -1
- package/dist/diagrams/fishbone/index.d.cts +1 -1
- package/dist/diagrams/fishbone/index.d.ts +1 -1
- package/dist/diagrams/flowchart/index.d.cts +2 -2
- package/dist/diagrams/flowchart/index.d.ts +2 -2
- package/dist/diagrams/genogram/index.d.cts +1 -1
- package/dist/diagrams/genogram/index.d.ts +1 -1
- package/dist/diagrams/ladder/index.d.cts +1 -1
- package/dist/diagrams/ladder/index.d.ts +1 -1
- package/dist/diagrams/logic/index.d.cts +1 -1
- package/dist/diagrams/logic/index.d.ts +1 -1
- package/dist/diagrams/orgchart/index.d.cts +1 -1
- package/dist/diagrams/orgchart/index.d.ts +1 -1
- package/dist/diagrams/pedigree/index.d.cts +1 -1
- package/dist/diagrams/pedigree/index.d.ts +1 -1
- package/dist/diagrams/phylo/index.d.cts +1 -1
- package/dist/diagrams/phylo/index.d.ts +1 -1
- package/dist/diagrams/sld/index.d.cts +1 -1
- package/dist/diagrams/sld/index.d.ts +1 -1
- package/dist/diagrams/sociogram/index.d.cts +1 -1
- package/dist/diagrams/sociogram/index.d.ts +1 -1
- package/dist/diagrams/timing/index.d.cts +1 -1
- package/dist/diagrams/timing/index.d.ts +1 -1
- package/dist/diagrams/venn/index.d.cts +1 -1
- package/dist/diagrams/venn/index.d.ts +1 -1
- package/dist/{index-C9A0h-CB.d.cts → index-BD2yDfQM.d.cts} +1 -1
- package/dist/{index-CJai_TEZ.d.ts → index-C30zQWZI.d.ts} +1 -1
- package/dist/index.cjs +24 -12
- package/dist/index.d.cts +3 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.js +2 -2
- package/dist/react.cjs +7 -9
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.cts +3 -2
- package/dist/react.d.ts +3 -2
- package/dist/react.js +7 -9
- package/dist/react.js.map +1 -1
- package/dist/tools-BHWaJPOl.d.ts +153 -0
- package/dist/tools-DlpuE76u.d.cts +153 -0
- package/dist/{types-BOAsqHoU.d.cts → types-WTr9W5Ud.d.cts} +2 -2
- package/dist/{types-BOAsqHoU.d.ts → types-WTr9W5Ud.d.ts} +2 -2
- package/package.json +2 -2
- package/dist/api-C5UcmT7n.d.cts +0 -22
- package/dist/api-C5UcmT7n.d.ts +0 -22
- package/dist/chunk-3YUUC6RN.cjs.map +0 -1
- package/dist/chunk-GTDQAN2Z.js.map +0 -1
- package/dist/chunk-HUPDIRBX.js.map +0 -1
- package/dist/chunk-IM4RCUHA.js.map +0 -1
- package/dist/chunk-NWPCY65Z.cjs.map +0 -1
- package/dist/chunk-XRCY75UV.cjs.map +0 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var chunkQUKVGHN4_cjs = require('./chunk-QUKVGHN4.cjs');
|
|
4
|
-
var
|
|
4
|
+
var chunkQMTWG6JL_cjs = require('./chunk-QMTWG6JL.cjs');
|
|
5
5
|
var chunkSUIDD2C5_cjs = require('./chunk-SUIDD2C5.cjs');
|
|
6
6
|
var chunkN7W5KZK7_cjs = require('./chunk-N7W5KZK7.cjs');
|
|
7
7
|
var chunk3M6WB62Y_cjs = require('./chunk-3M6WB62Y.cjs');
|
|
@@ -3937,7 +3937,7 @@ function renderLayout(layout) {
|
|
|
3937
3937
|
var state = {
|
|
3938
3938
|
type: "state",
|
|
3939
3939
|
detect(text2) {
|
|
3940
|
-
return /^\s*state\b/i.test(text2);
|
|
3940
|
+
return /^\s*(?:state\b|stateDiagram(?:-v2)?\b)/i.test(text2);
|
|
3941
3941
|
},
|
|
3942
3942
|
parse: parseStateDiagram,
|
|
3943
3943
|
render(text2, config) {
|
|
@@ -7186,7 +7186,7 @@ function parseHeader(state2) {
|
|
|
7186
7186
|
if (!m) break;
|
|
7187
7187
|
const key = m[1].toLowerCase();
|
|
7188
7188
|
const valueRaw = m[2].trim();
|
|
7189
|
-
const value =
|
|
7189
|
+
const value = stripQuotes2(valueRaw);
|
|
7190
7190
|
if (key === "title") state2.ast.title = value;
|
|
7191
7191
|
else if (key === "system") state2.ast.system = value;
|
|
7192
7192
|
else if (key === "direction") {
|
|
@@ -7204,7 +7204,7 @@ function parseHeader(state2) {
|
|
|
7204
7204
|
state2.i++;
|
|
7205
7205
|
}
|
|
7206
7206
|
}
|
|
7207
|
-
function
|
|
7207
|
+
function stripQuotes2(s) {
|
|
7208
7208
|
const t = s.trim();
|
|
7209
7209
|
if (t.startsWith('"') && t.endsWith('"') && t.length >= 2) return t.slice(1, -1);
|
|
7210
7210
|
return t;
|
|
@@ -7241,7 +7241,7 @@ function parseActorDecl(ln, state2) {
|
|
|
7241
7241
|
id = asMatch[1];
|
|
7242
7242
|
rest = rest.slice(0, asMatch.index).trim();
|
|
7243
7243
|
}
|
|
7244
|
-
const name =
|
|
7244
|
+
const name = stripQuotes2(rest);
|
|
7245
7245
|
if (!name) throw new UsecaseParseError(`actor declaration missing name`, ln.line);
|
|
7246
7246
|
const actorId = id ?? defaultIdFor(name);
|
|
7247
7247
|
declareId(state2, actorId, "actor", ln.line);
|
|
@@ -7277,7 +7277,7 @@ function parseUsecaseDecl(ln, state2) {
|
|
|
7277
7277
|
id = asMatch[1];
|
|
7278
7278
|
rest = rest.slice(0, asMatch.index).trim();
|
|
7279
7279
|
}
|
|
7280
|
-
const name =
|
|
7280
|
+
const name = stripQuotes2(rest);
|
|
7281
7281
|
if (!name) throw new UsecaseParseError(`usecase declaration missing name`, ln.line);
|
|
7282
7282
|
const ucId = id ?? defaultIdFor(name);
|
|
7283
7283
|
declareId(state2, ucId, "usecase", ln.line);
|
|
@@ -8032,13 +8032,13 @@ function layoutUsecase(ast) {
|
|
|
8032
8032
|
pb = perimeter(r.target, a.cx, a.cy);
|
|
8033
8033
|
}
|
|
8034
8034
|
const dashed = r.kind === "include" || r.kind === "extend";
|
|
8035
|
-
let
|
|
8036
|
-
if (r.kind === "directed" || r.kind === "include" || r.kind === "extend")
|
|
8037
|
-
else if (r.kind === "generalization")
|
|
8035
|
+
let arrowKind2 = "none";
|
|
8036
|
+
if (r.kind === "directed" || r.kind === "include" || r.kind === "extend") arrowKind2 = "open";
|
|
8037
|
+
else if (r.kind === "generalization") arrowKind2 = "hollow";
|
|
8038
8038
|
const edge = {
|
|
8039
8039
|
relation: r,
|
|
8040
8040
|
d: `M ${round(pa.x)} ${round(pa.y)} L ${round(pb.x)} ${round(pb.y)}`,
|
|
8041
|
-
arrowKind,
|
|
8041
|
+
arrowKind: arrowKind2,
|
|
8042
8042
|
dashed
|
|
8043
8043
|
};
|
|
8044
8044
|
if (r.kind === "include" || r.kind === "extend") {
|
|
@@ -8521,7 +8521,7 @@ function preprocess7(src) {
|
|
|
8521
8521
|
}
|
|
8522
8522
|
return out;
|
|
8523
8523
|
}
|
|
8524
|
-
function
|
|
8524
|
+
function stripQuotes3(s) {
|
|
8525
8525
|
const t = s.trim();
|
|
8526
8526
|
if (t.length >= 2 && (t.startsWith('"') && t.endsWith('"') || t.startsWith("'") && t.endsWith("'"))) {
|
|
8527
8527
|
return t.slice(1, -1);
|
|
@@ -8539,7 +8539,7 @@ function parseHeaderLine(ln, ast) {
|
|
|
8539
8539
|
if (!m) return false;
|
|
8540
8540
|
const key = m[1].toLowerCase();
|
|
8541
8541
|
const valueRaw = m[2].trim();
|
|
8542
|
-
const value =
|
|
8542
|
+
const value = stripQuotes3(valueRaw);
|
|
8543
8543
|
switch (key) {
|
|
8544
8544
|
case "title":
|
|
8545
8545
|
ast.title = value;
|
|
@@ -8668,23 +8668,23 @@ function parseTaskLine(ln, ast) {
|
|
|
8668
8668
|
milestone = true;
|
|
8669
8669
|
return "";
|
|
8670
8670
|
}).trim();
|
|
8671
|
-
const
|
|
8671
|
+
const markers4 = [];
|
|
8672
8672
|
KEY_RE.lastIndex = 0;
|
|
8673
8673
|
let mm;
|
|
8674
8674
|
while ((mm = KEY_RE.exec(rest)) !== null) {
|
|
8675
|
-
|
|
8675
|
+
markers4.push({ key: mm[1].toLowerCase(), start: mm.index, valStart: mm.index + mm[0].length });
|
|
8676
8676
|
}
|
|
8677
8677
|
const values = {};
|
|
8678
|
-
for (let i = 0; i <
|
|
8679
|
-
const cur =
|
|
8680
|
-
const nextStart = i + 1 <
|
|
8678
|
+
for (let i = 0; i < markers4.length; i++) {
|
|
8679
|
+
const cur = markers4[i];
|
|
8680
|
+
const nextStart = i + 1 < markers4.length ? markers4[i + 1].start : rest.length;
|
|
8681
8681
|
const val = rest.slice(cur.valStart, nextStart).trim();
|
|
8682
8682
|
if (cur.key in values) {
|
|
8683
8683
|
throw new PertParseError(`duplicate '${cur.key}:' on task '${id}'`, ln.line);
|
|
8684
8684
|
}
|
|
8685
8685
|
values[cur.key] = val;
|
|
8686
8686
|
}
|
|
8687
|
-
const preamble = (
|
|
8687
|
+
const preamble = (markers4.length ? rest.slice(0, markers4[0].start) : rest).trim();
|
|
8688
8688
|
if (preamble) {
|
|
8689
8689
|
throw new PertParseError(`unexpected text '${preamble}' in task '${id}'`, ln.line);
|
|
8690
8690
|
}
|
|
@@ -8712,7 +8712,7 @@ function parseTaskLine(ln, ast) {
|
|
|
8712
8712
|
}
|
|
8713
8713
|
const tags = values.tags ? values.tags.split(",").map((t) => t.trim()).filter(Boolean) : [];
|
|
8714
8714
|
const className = values.class ? values.class.trim() : void 0;
|
|
8715
|
-
const lane = values.lane ?
|
|
8715
|
+
const lane = values.lane ? stripQuotes3(values.lane) : void 0;
|
|
8716
8716
|
const task = {
|
|
8717
8717
|
id,
|
|
8718
8718
|
label,
|
|
@@ -10267,6 +10267,155 @@ var pert = {
|
|
|
10267
10267
|
}
|
|
10268
10268
|
};
|
|
10269
10269
|
|
|
10270
|
+
// src/core/diagnostics.ts
|
|
10271
|
+
var ENGINE_BUG_NAMES = /* @__PURE__ */ new Set([
|
|
10272
|
+
"ReferenceError",
|
|
10273
|
+
"TypeError",
|
|
10274
|
+
"RangeError"
|
|
10275
|
+
]);
|
|
10276
|
+
function diagnosticFromError(err) {
|
|
10277
|
+
if (err instanceof Error) {
|
|
10278
|
+
const anyErr = err;
|
|
10279
|
+
const hasParseFields = typeof anyErr.line === "number";
|
|
10280
|
+
const isEngineBug = !hasParseFields && ENGINE_BUG_NAMES.has(err.name);
|
|
10281
|
+
const source = typeof anyErr.source === "string" ? anyErr.source : isEngineBug ? firstStackFrame(err.stack) : void 0;
|
|
10282
|
+
return {
|
|
10283
|
+
severity: "error",
|
|
10284
|
+
code: isEngineBug ? "ENGINE_BUG" : "DSL_INVALID",
|
|
10285
|
+
line: typeof anyErr.line === "number" ? anyErr.line : void 0,
|
|
10286
|
+
column: typeof anyErr.column === "number" ? anyErr.column : void 0,
|
|
10287
|
+
source,
|
|
10288
|
+
message: isEngineBug ? `[engine bug: ${err.name}] ${err.message}` : err.message,
|
|
10289
|
+
hint: typeof anyErr.hint === "string" ? anyErr.hint : isEngineBug ? "This looks like a Schematex internal error rather than a DSL syntax problem. Keep the failing DSL and file an issue." : void 0,
|
|
10290
|
+
fatal: true
|
|
10291
|
+
};
|
|
10292
|
+
}
|
|
10293
|
+
return {
|
|
10294
|
+
severity: "error",
|
|
10295
|
+
code: "UNKNOWN_THROW",
|
|
10296
|
+
message: String(err),
|
|
10297
|
+
fatal: true
|
|
10298
|
+
};
|
|
10299
|
+
}
|
|
10300
|
+
function renderDiagnosticSvg(diagnostics, type, config = {}) {
|
|
10301
|
+
const headline = type ? `${type} preview could not be rendered` : "Diagram preview could not be rendered";
|
|
10302
|
+
const detail = diagnostics[0]?.message ?? "Schematex could not parse this DSL.";
|
|
10303
|
+
const lines = wrapText3(detail, 88).slice(0, 5);
|
|
10304
|
+
const source = diagnostics[0]?.source ? wrapText3(`Source: ${diagnostics[0].source}`, 88).slice(0, 2) : [];
|
|
10305
|
+
const foot = "Strict validation failed before a diagram could be drawn.";
|
|
10306
|
+
const width = 760;
|
|
10307
|
+
const lineHeight = 20;
|
|
10308
|
+
const height = 174 + (lines.length + source.length) * lineHeight;
|
|
10309
|
+
const fontFamily = config.fontFamily ?? "system-ui, -apple-system, sans-serif";
|
|
10310
|
+
const children = [
|
|
10311
|
+
chunk3WNW5Y7P_cjs.title(headline),
|
|
10312
|
+
chunk3WNW5Y7P_cjs.desc(`${headline}. ${detail}`),
|
|
10313
|
+
chunk3WNW5Y7P_cjs.el(
|
|
10314
|
+
"style",
|
|
10315
|
+
{},
|
|
10316
|
+
`
|
|
10317
|
+
.schematex-preview-error { font-family: ${chunk3WNW5Y7P_cjs.escapeXml(fontFamily)}; }
|
|
10318
|
+
.schematex-preview-error-frame { fill: #fff7ed; stroke: #c2410c; stroke-width: 1.5; }
|
|
10319
|
+
.schematex-preview-error-mark { fill: #c2410c; }
|
|
10320
|
+
.schematex-preview-error-title { fill: #7c2d12; font-size: 18px; font-weight: 600; }
|
|
10321
|
+
.schematex-preview-error-copy { fill: #431407; font-size: 13px; }
|
|
10322
|
+
.schematex-preview-error-muted { fill: #9a3412; font-size: 12px; }
|
|
10323
|
+
`
|
|
10324
|
+
),
|
|
10325
|
+
chunk3WNW5Y7P_cjs.el("g", { class: "schematex-preview-error" }, [
|
|
10326
|
+
chunk3WNW5Y7P_cjs.rect({
|
|
10327
|
+
x: 1,
|
|
10328
|
+
y: 1,
|
|
10329
|
+
width: width - 2,
|
|
10330
|
+
height: height - 2,
|
|
10331
|
+
rx: 6,
|
|
10332
|
+
class: "schematex-preview-error-frame"
|
|
10333
|
+
}),
|
|
10334
|
+
chunk3WNW5Y7P_cjs.rect({
|
|
10335
|
+
x: 28,
|
|
10336
|
+
y: 30,
|
|
10337
|
+
width: 8,
|
|
10338
|
+
height: 34,
|
|
10339
|
+
rx: 4,
|
|
10340
|
+
class: "schematex-preview-error-mark"
|
|
10341
|
+
}),
|
|
10342
|
+
chunk3WNW5Y7P_cjs.rect({
|
|
10343
|
+
x: 28,
|
|
10344
|
+
y: 72,
|
|
10345
|
+
width: 8,
|
|
10346
|
+
height: 8,
|
|
10347
|
+
rx: 4,
|
|
10348
|
+
class: "schematex-preview-error-mark"
|
|
10349
|
+
}),
|
|
10350
|
+
chunk3WNW5Y7P_cjs.text(
|
|
10351
|
+
{ x: 58, y: 49, class: "schematex-preview-error-title" },
|
|
10352
|
+
headline
|
|
10353
|
+
),
|
|
10354
|
+
chunk3WNW5Y7P_cjs.text(
|
|
10355
|
+
{ x: 58, y: 76, class: "schematex-preview-error-muted" },
|
|
10356
|
+
"The DSL is still available to repair or retry."
|
|
10357
|
+
),
|
|
10358
|
+
...renderRows(lines, 58, 112, lineHeight, "schematex-preview-error-copy"),
|
|
10359
|
+
...renderRows(
|
|
10360
|
+
source,
|
|
10361
|
+
58,
|
|
10362
|
+
112 + lines.length * lineHeight + 10,
|
|
10363
|
+
lineHeight,
|
|
10364
|
+
"schematex-preview-error-muted"
|
|
10365
|
+
),
|
|
10366
|
+
chunk3WNW5Y7P_cjs.text(
|
|
10367
|
+
{ x: 58, y: height - 28, class: "schematex-preview-error-muted" },
|
|
10368
|
+
foot
|
|
10369
|
+
)
|
|
10370
|
+
])
|
|
10371
|
+
];
|
|
10372
|
+
return chunk3WNW5Y7P_cjs.svgRoot(
|
|
10373
|
+
{
|
|
10374
|
+
width,
|
|
10375
|
+
height,
|
|
10376
|
+
viewBox: `0 0 ${width} ${height}`,
|
|
10377
|
+
role: "img",
|
|
10378
|
+
"aria-label": headline,
|
|
10379
|
+
"data-schematex-status": "invalid"
|
|
10380
|
+
},
|
|
10381
|
+
children
|
|
10382
|
+
);
|
|
10383
|
+
}
|
|
10384
|
+
function renderRows(rows, x, y, lineHeight, className) {
|
|
10385
|
+
return rows.map(
|
|
10386
|
+
(row, idx) => chunk3WNW5Y7P_cjs.text({ x, y: y + idx * lineHeight, class: className }, row)
|
|
10387
|
+
);
|
|
10388
|
+
}
|
|
10389
|
+
function wrapText3(value, max) {
|
|
10390
|
+
const words = value.replace(/\s+/g, " ").trim().split(" ");
|
|
10391
|
+
const rows = [];
|
|
10392
|
+
let current = "";
|
|
10393
|
+
for (const word of words) {
|
|
10394
|
+
if (!current) {
|
|
10395
|
+
current = word;
|
|
10396
|
+
continue;
|
|
10397
|
+
}
|
|
10398
|
+
if (current.length + word.length + 1 <= max) {
|
|
10399
|
+
current += ` ${word}`;
|
|
10400
|
+
continue;
|
|
10401
|
+
}
|
|
10402
|
+
rows.push(current);
|
|
10403
|
+
current = word;
|
|
10404
|
+
}
|
|
10405
|
+
if (current) rows.push(current);
|
|
10406
|
+
return rows.length > 0 ? rows : [value];
|
|
10407
|
+
}
|
|
10408
|
+
function firstStackFrame(stack) {
|
|
10409
|
+
if (!stack) return void 0;
|
|
10410
|
+
for (const line2 of stack.split("\n")) {
|
|
10411
|
+
const trimmed = line2.trim();
|
|
10412
|
+
if (trimmed.startsWith("at ")) {
|
|
10413
|
+
return trimmed.replace(/\((?:.*\/)?([^/]+)\)/, "($1)");
|
|
10414
|
+
}
|
|
10415
|
+
}
|
|
10416
|
+
return void 0;
|
|
10417
|
+
}
|
|
10418
|
+
|
|
10270
10419
|
// src/diagrams/mindmap/inline.ts
|
|
10271
10420
|
var RE_TASK = /^\[( |x|X)\]\s+(.*)$/;
|
|
10272
10421
|
function tokenizeInline(raw) {
|
|
@@ -11236,7 +11385,7 @@ function newAST() {
|
|
|
11236
11385
|
config: { ...DEFAULT_CONFIG }
|
|
11237
11386
|
};
|
|
11238
11387
|
}
|
|
11239
|
-
function
|
|
11388
|
+
function stripQuotes4(s) {
|
|
11240
11389
|
const t = s.trim();
|
|
11241
11390
|
if (t.startsWith('"') && t.endsWith('"') || t.startsWith("'") && t.endsWith("'")) {
|
|
11242
11391
|
return t.slice(1, -1);
|
|
@@ -11272,7 +11421,7 @@ function parseAxis(raw) {
|
|
|
11272
11421
|
function parseNumberList2(raw) {
|
|
11273
11422
|
const t = raw.trim();
|
|
11274
11423
|
const inner = t.startsWith("[") && t.endsWith("]") ? t.slice(1, -1) : t;
|
|
11275
|
-
return inner.split(",").map((s) =>
|
|
11424
|
+
return inner.split(",").map((s) => stripQuotes4(s.trim())).filter((s) => s.length > 0);
|
|
11276
11425
|
}
|
|
11277
11426
|
function parseProperties2(raw, point) {
|
|
11278
11427
|
let i = 0;
|
|
@@ -11387,7 +11536,7 @@ function parseHeader2(line2, ast) {
|
|
|
11387
11536
|
ast.cols = Number(heatMatch[1]);
|
|
11388
11537
|
ast.rows = Number(heatMatch[2]);
|
|
11389
11538
|
const title2 = heatMatch[3].trim();
|
|
11390
|
-
if (title2) ast.title =
|
|
11539
|
+
if (title2) ast.title = stripQuotes4(title2);
|
|
11391
11540
|
return void 0;
|
|
11392
11541
|
}
|
|
11393
11542
|
const corrMatch = rest.match(/^correlation\s*(?:(\d+)\s*x\s*(\d+))?\s*(.*)$/i);
|
|
@@ -11399,7 +11548,7 @@ function parseHeader2(line2, ast) {
|
|
|
11399
11548
|
ast.rows = Number(corrMatch[2]);
|
|
11400
11549
|
}
|
|
11401
11550
|
const title2 = corrMatch[3].trim();
|
|
11402
|
-
if (title2) ast.title =
|
|
11551
|
+
if (title2) ast.title = stripQuotes4(title2);
|
|
11403
11552
|
return void 0;
|
|
11404
11553
|
}
|
|
11405
11554
|
const tokenMatch = rest.match(/^([a-zA-Z0-9_-]+)\s*(.*)$/);
|
|
@@ -11407,13 +11556,13 @@ function parseHeader2(line2, ast) {
|
|
|
11407
11556
|
const tok = tokenMatch[1].toLowerCase();
|
|
11408
11557
|
const remainder = tokenMatch[2].trim();
|
|
11409
11558
|
if (TEMPLATE_NAMES.has(tok)) {
|
|
11410
|
-
if (remainder) ast.title =
|
|
11559
|
+
if (remainder) ast.title = stripQuotes4(remainder);
|
|
11411
11560
|
return tok;
|
|
11412
11561
|
}
|
|
11413
11562
|
if (rest.startsWith('"') || rest.startsWith("'")) {
|
|
11414
|
-
ast.title =
|
|
11563
|
+
ast.title = stripQuotes4(rest);
|
|
11415
11564
|
} else if (rest.length > 0) {
|
|
11416
|
-
ast.title =
|
|
11565
|
+
ast.title = stripQuotes4(rest);
|
|
11417
11566
|
}
|
|
11418
11567
|
}
|
|
11419
11568
|
return void 0;
|
|
@@ -11449,7 +11598,7 @@ function parseMatrix(text2) {
|
|
|
11449
11598
|
inConfig = false;
|
|
11450
11599
|
}
|
|
11451
11600
|
if (/^title\s*:/i.test(line2)) {
|
|
11452
|
-
st.ast.title =
|
|
11601
|
+
st.ast.title = stripQuotes4(line2.replace(/^title\s*:\s*/i, ""));
|
|
11453
11602
|
continue;
|
|
11454
11603
|
}
|
|
11455
11604
|
if (/^x-axis\s*:/i.test(line2)) {
|
|
@@ -11534,7 +11683,7 @@ function parseMatrix(text2) {
|
|
|
11534
11683
|
if (qShort) {
|
|
11535
11684
|
const q = Number(qShort[1]);
|
|
11536
11685
|
const labelRaw = qShort[2].trim();
|
|
11537
|
-
const label =
|
|
11686
|
+
const label = stripQuotes4(labelRaw);
|
|
11538
11687
|
const cell = quadrantToCell(q);
|
|
11539
11688
|
st.ast.cellLabels.push({ col: cell.col, row: cell.row, label });
|
|
11540
11689
|
continue;
|
|
@@ -13422,10 +13571,10 @@ function renderEntity(e) {
|
|
|
13422
13571
|
a.name
|
|
13423
13572
|
)
|
|
13424
13573
|
);
|
|
13425
|
-
const
|
|
13574
|
+
const markers4 = attrMarkers(a);
|
|
13426
13575
|
const markerW = 26;
|
|
13427
13576
|
const markerGap = 4;
|
|
13428
|
-
const markersBlockW =
|
|
13577
|
+
const markersBlockW = markers4.length * markerW + (markers4.length - 1) * markerGap;
|
|
13429
13578
|
const markersStartX = e.x + e.width - C2.ENTITY_PADDING_X - markersBlockW;
|
|
13430
13579
|
if (a.type) {
|
|
13431
13580
|
body.push(
|
|
@@ -13440,8 +13589,8 @@ function renderEntity(e) {
|
|
|
13440
13589
|
)
|
|
13441
13590
|
);
|
|
13442
13591
|
}
|
|
13443
|
-
for (let j = 0; j <
|
|
13444
|
-
const m =
|
|
13592
|
+
for (let j = 0; j < markers4.length; j++) {
|
|
13593
|
+
const m = markers4[j];
|
|
13445
13594
|
const px = markersStartX + j * (markerW + markerGap);
|
|
13446
13595
|
body.push(
|
|
13447
13596
|
chunk3WNW5Y7P_cjs.rect({
|
|
@@ -18615,6 +18764,1178 @@ var sfc = {
|
|
|
18615
18764
|
}
|
|
18616
18765
|
};
|
|
18617
18766
|
|
|
18767
|
+
// src/diagrams/sequence/parser.ts
|
|
18768
|
+
var SequenceParseError = class extends Error {
|
|
18769
|
+
line;
|
|
18770
|
+
constructor(message, line2) {
|
|
18771
|
+
super(line2 ? `${message} (line ${line2})` : message);
|
|
18772
|
+
this.name = "SequenceParseError";
|
|
18773
|
+
this.line = line2;
|
|
18774
|
+
}
|
|
18775
|
+
};
|
|
18776
|
+
var KINDS = /* @__PURE__ */ new Set([
|
|
18777
|
+
"participant",
|
|
18778
|
+
"actor",
|
|
18779
|
+
"boundary",
|
|
18780
|
+
"control",
|
|
18781
|
+
"entity",
|
|
18782
|
+
"database",
|
|
18783
|
+
"collections",
|
|
18784
|
+
"queue"
|
|
18785
|
+
]);
|
|
18786
|
+
var SIMPLE_FRAG = /* @__PURE__ */ new Set([
|
|
18787
|
+
"opt",
|
|
18788
|
+
"loop",
|
|
18789
|
+
"break",
|
|
18790
|
+
"critical",
|
|
18791
|
+
"neg",
|
|
18792
|
+
"ignore",
|
|
18793
|
+
"consider",
|
|
18794
|
+
"assert"
|
|
18795
|
+
]);
|
|
18796
|
+
var MULTI_FRAG = /* @__PURE__ */ new Set(["par", "seq", "strict"]);
|
|
18797
|
+
var MSGSET_FRAG = /* @__PURE__ */ new Set(["ignore", "consider"]);
|
|
18798
|
+
var ALL_FRAG = /* @__PURE__ */ new Set([
|
|
18799
|
+
"alt",
|
|
18800
|
+
...SIMPLE_FRAG,
|
|
18801
|
+
...MULTI_FRAG
|
|
18802
|
+
]);
|
|
18803
|
+
var ARROW_RE = /(-->|->>|o->|-x|->)/;
|
|
18804
|
+
function arrowKind(token) {
|
|
18805
|
+
switch (token) {
|
|
18806
|
+
case "-->":
|
|
18807
|
+
return "reply";
|
|
18808
|
+
case "->>":
|
|
18809
|
+
return "async";
|
|
18810
|
+
case "o->":
|
|
18811
|
+
return "found";
|
|
18812
|
+
case "-x":
|
|
18813
|
+
return "lost";
|
|
18814
|
+
default:
|
|
18815
|
+
return "sync";
|
|
18816
|
+
}
|
|
18817
|
+
}
|
|
18818
|
+
function firstWord(s) {
|
|
18819
|
+
const m = /^(\S+)/.exec(s);
|
|
18820
|
+
return m ? m[1] : "";
|
|
18821
|
+
}
|
|
18822
|
+
function extractGuard(rest) {
|
|
18823
|
+
const t = rest.trim();
|
|
18824
|
+
if (!t) return void 0;
|
|
18825
|
+
if (t.startsWith("[") && t.endsWith("]")) return t.slice(1, -1).trim();
|
|
18826
|
+
if (t.startsWith("(") && t.endsWith(")")) return t.slice(1, -1).trim();
|
|
18827
|
+
return t;
|
|
18828
|
+
}
|
|
18829
|
+
var SequenceParser = class {
|
|
18830
|
+
lines;
|
|
18831
|
+
i = 0;
|
|
18832
|
+
order = [];
|
|
18833
|
+
byId = /* @__PURE__ */ new Map();
|
|
18834
|
+
warnings = [];
|
|
18835
|
+
constructor(source) {
|
|
18836
|
+
this.lines = source.split(/\r?\n/).map((raw, idx) => ({
|
|
18837
|
+
text: raw.trim(),
|
|
18838
|
+
n: idx + 1
|
|
18839
|
+
}));
|
|
18840
|
+
}
|
|
18841
|
+
parse() {
|
|
18842
|
+
const header = this.consumeHeader();
|
|
18843
|
+
const ast = {
|
|
18844
|
+
type: "sequence",
|
|
18845
|
+
participants: [],
|
|
18846
|
+
statements: [],
|
|
18847
|
+
warnings: this.warnings
|
|
18848
|
+
};
|
|
18849
|
+
if (header.title) ast.title = header.title;
|
|
18850
|
+
const statements = this.parseBlock();
|
|
18851
|
+
const leftover = this.peek();
|
|
18852
|
+
if (leftover) {
|
|
18853
|
+
const fw = firstWord(leftover.text).toLowerCase();
|
|
18854
|
+
throw new SequenceParseError(
|
|
18855
|
+
`'${fw}' without a matching combined fragment`,
|
|
18856
|
+
leftover.n
|
|
18857
|
+
);
|
|
18858
|
+
}
|
|
18859
|
+
if (this.autonumberSpec) ast.autonumber = this.autonumberSpec;
|
|
18860
|
+
ast.statements = statements;
|
|
18861
|
+
ast.participants = this.order.map((id) => this.byId.get(id));
|
|
18862
|
+
return ast;
|
|
18863
|
+
}
|
|
18864
|
+
autonumberSpec;
|
|
18865
|
+
// ── line cursor ──────────────────────────────────────────────
|
|
18866
|
+
peek() {
|
|
18867
|
+
while (this.i < this.lines.length) {
|
|
18868
|
+
const ln = this.lines[this.i];
|
|
18869
|
+
if (ln.text === "" || ln.text.startsWith("#") || ln.text.startsWith("//")) {
|
|
18870
|
+
this.i++;
|
|
18871
|
+
continue;
|
|
18872
|
+
}
|
|
18873
|
+
return ln;
|
|
18874
|
+
}
|
|
18875
|
+
return null;
|
|
18876
|
+
}
|
|
18877
|
+
next() {
|
|
18878
|
+
const ln = this.peek();
|
|
18879
|
+
if (ln) this.i++;
|
|
18880
|
+
return ln;
|
|
18881
|
+
}
|
|
18882
|
+
// ── header ───────────────────────────────────────────────────
|
|
18883
|
+
consumeHeader() {
|
|
18884
|
+
const ln = this.next();
|
|
18885
|
+
if (!ln || !/^sequence\b/i.test(ln.text)) {
|
|
18886
|
+
throw new SequenceParseError(
|
|
18887
|
+
"A sequence diagram must start with the keyword 'sequence'",
|
|
18888
|
+
ln?.n
|
|
18889
|
+
);
|
|
18890
|
+
}
|
|
18891
|
+
const title2 = chunkNAGUZFXX_cjs.matchQuotedTitle(ln.text);
|
|
18892
|
+
return title2 ? { title: title2 } : {};
|
|
18893
|
+
}
|
|
18894
|
+
// ── participants ─────────────────────────────────────────────
|
|
18895
|
+
ensure(id, kind = "participant", line2) {
|
|
18896
|
+
let p = this.byId.get(id);
|
|
18897
|
+
if (!p) {
|
|
18898
|
+
p = { id, name: id, kind, line: line2 };
|
|
18899
|
+
this.byId.set(id, p);
|
|
18900
|
+
this.order.push(id);
|
|
18901
|
+
}
|
|
18902
|
+
return p;
|
|
18903
|
+
}
|
|
18904
|
+
declare(line2) {
|
|
18905
|
+
const fw = firstWord(line2.text);
|
|
18906
|
+
const kind = fw.toLowerCase();
|
|
18907
|
+
let rest = line2.text.slice(fw.length).trim();
|
|
18908
|
+
let stereotype;
|
|
18909
|
+
const stereoMatch = /«([^»]*)»|<<([^>]*)>>/.exec(rest);
|
|
18910
|
+
if (stereoMatch) {
|
|
18911
|
+
stereotype = (stereoMatch[1] ?? stereoMatch[2] ?? "").trim();
|
|
18912
|
+
rest = (rest.slice(0, stereoMatch.index) + rest.slice(stereoMatch.index + stereoMatch[0].length)).trim();
|
|
18913
|
+
}
|
|
18914
|
+
let id;
|
|
18915
|
+
let name;
|
|
18916
|
+
const asMatch = /\sas\s/i.exec(rest);
|
|
18917
|
+
if (asMatch) {
|
|
18918
|
+
id = chunkNAGUZFXX_cjs.stripQuotes(rest.slice(0, asMatch.index).trim());
|
|
18919
|
+
name = chunkNAGUZFXX_cjs.stripQuotes(rest.slice(asMatch.index + asMatch[0].length).trim());
|
|
18920
|
+
} else {
|
|
18921
|
+
id = chunkNAGUZFXX_cjs.stripQuotes(rest);
|
|
18922
|
+
name = id;
|
|
18923
|
+
}
|
|
18924
|
+
if (!id) {
|
|
18925
|
+
throw new SequenceParseError(`'${fw}' declaration needs a name`, line2.n);
|
|
18926
|
+
}
|
|
18927
|
+
const existing = this.byId.get(id);
|
|
18928
|
+
if (existing) {
|
|
18929
|
+
existing.kind = kind;
|
|
18930
|
+
existing.name = name;
|
|
18931
|
+
if (stereotype) existing.stereotype = stereotype;
|
|
18932
|
+
} else {
|
|
18933
|
+
const p = { id, name, kind, line: line2.n };
|
|
18934
|
+
if (stereotype) p.stereotype = stereotype;
|
|
18935
|
+
this.byId.set(id, p);
|
|
18936
|
+
this.order.push(id);
|
|
18937
|
+
}
|
|
18938
|
+
}
|
|
18939
|
+
// ── block / statement dispatch ───────────────────────────────
|
|
18940
|
+
/** Parse statements until a terminator (`end`/`else`/`and`) or EOF. Terminators are left unconsumed. */
|
|
18941
|
+
parseBlock() {
|
|
18942
|
+
const out = [];
|
|
18943
|
+
for (; ; ) {
|
|
18944
|
+
const ln = this.peek();
|
|
18945
|
+
if (!ln) break;
|
|
18946
|
+
const fw = firstWord(ln.text).toLowerCase();
|
|
18947
|
+
if (fw === "end" || fw === "else" || fw === "and") break;
|
|
18948
|
+
if (KINDS.has(fw)) {
|
|
18949
|
+
this.i++;
|
|
18950
|
+
this.declare(ln);
|
|
18951
|
+
continue;
|
|
18952
|
+
}
|
|
18953
|
+
if (ALL_FRAG.has(fw)) {
|
|
18954
|
+
out.push(this.parseFragment(ln));
|
|
18955
|
+
continue;
|
|
18956
|
+
}
|
|
18957
|
+
this.i++;
|
|
18958
|
+
const stmt = this.parseSimpleStatement(ln);
|
|
18959
|
+
if (stmt) out.push(stmt);
|
|
18960
|
+
}
|
|
18961
|
+
return out;
|
|
18962
|
+
}
|
|
18963
|
+
parseFragment(open) {
|
|
18964
|
+
const fw = firstWord(open.text).toLowerCase();
|
|
18965
|
+
this.i++;
|
|
18966
|
+
let rest = open.text.slice(fw.length);
|
|
18967
|
+
let messageSet;
|
|
18968
|
+
if (MSGSET_FRAG.has(fw)) {
|
|
18969
|
+
const bm = /\{([^}]*)\}/.exec(rest);
|
|
18970
|
+
if (bm) {
|
|
18971
|
+
messageSet = bm[1].split(",").map((s) => s.trim()).filter(Boolean);
|
|
18972
|
+
rest = rest.slice(0, bm.index) + rest.slice(bm.index + bm[0].length);
|
|
18973
|
+
}
|
|
18974
|
+
}
|
|
18975
|
+
const firstGuard = extractGuard(rest);
|
|
18976
|
+
const operands = [
|
|
18977
|
+
{ guard: firstGuard, statements: this.parseBlock() }
|
|
18978
|
+
];
|
|
18979
|
+
for (; ; ) {
|
|
18980
|
+
const ln = this.peek();
|
|
18981
|
+
if (!ln) {
|
|
18982
|
+
throw new SequenceParseError(`Unterminated '${fw}' fragment`, open.n);
|
|
18983
|
+
}
|
|
18984
|
+
const term = firstWord(ln.text).toLowerCase();
|
|
18985
|
+
if (term === "end") {
|
|
18986
|
+
this.i++;
|
|
18987
|
+
break;
|
|
18988
|
+
}
|
|
18989
|
+
if (term === "else") {
|
|
18990
|
+
if (fw !== "alt") {
|
|
18991
|
+
throw new SequenceParseError(
|
|
18992
|
+
`'else' is only valid inside an 'alt' fragment, not '${fw}'`,
|
|
18993
|
+
ln.n
|
|
18994
|
+
);
|
|
18995
|
+
}
|
|
18996
|
+
this.i++;
|
|
18997
|
+
operands.push({
|
|
18998
|
+
guard: extractGuard(ln.text.slice(4)),
|
|
18999
|
+
statements: this.parseBlock()
|
|
19000
|
+
});
|
|
19001
|
+
continue;
|
|
19002
|
+
}
|
|
19003
|
+
if (term === "and") {
|
|
19004
|
+
if (!MULTI_FRAG.has(fw)) {
|
|
19005
|
+
throw new SequenceParseError(
|
|
19006
|
+
`'and' is only valid inside par/seq/strict, not '${fw}'`,
|
|
19007
|
+
ln.n
|
|
19008
|
+
);
|
|
19009
|
+
}
|
|
19010
|
+
this.i++;
|
|
19011
|
+
const label = ln.text.slice(3).trim();
|
|
19012
|
+
operands.push({
|
|
19013
|
+
guard: label ? extractGuard(label) : void 0,
|
|
19014
|
+
statements: this.parseBlock()
|
|
19015
|
+
});
|
|
19016
|
+
continue;
|
|
19017
|
+
}
|
|
19018
|
+
throw new SequenceParseError(`Unexpected '${term}' in '${fw}'`, ln.n);
|
|
19019
|
+
}
|
|
19020
|
+
const frag = { kind: "fragment", op: fw, operands, line: open.n };
|
|
19021
|
+
if (messageSet && messageSet.length) frag.messageSet = messageSet;
|
|
19022
|
+
return frag;
|
|
19023
|
+
}
|
|
19024
|
+
/** Non-fragment, non-participant statements. */
|
|
19025
|
+
parseSimpleStatement(ln) {
|
|
19026
|
+
const text2 = ln.text;
|
|
19027
|
+
const fw = firstWord(text2).toLowerCase();
|
|
19028
|
+
if (fw === "activate" || fw === "deactivate") {
|
|
19029
|
+
const m = /^(?:de)?activate\s+(\S+)$/i.exec(text2);
|
|
19030
|
+
if (!m) throw new SequenceParseError(`Malformed ${fw} statement`, ln.n);
|
|
19031
|
+
this.ensure(m[1], "participant", ln.n);
|
|
19032
|
+
return { kind: fw, id: m[1], line: ln.n };
|
|
19033
|
+
}
|
|
19034
|
+
if (fw === "note") {
|
|
19035
|
+
return this.parseNote(ln);
|
|
19036
|
+
}
|
|
19037
|
+
if (fw === "ref") {
|
|
19038
|
+
const m = /^ref\s+over\s+(.+?)\s*:\s*(.*)$/i.exec(text2);
|
|
19039
|
+
if (!m) throw new SequenceParseError("Malformed ref (expected: ref over A, B : text)", ln.n);
|
|
19040
|
+
const ids = m[1].split(",").map((s) => chunkNAGUZFXX_cjs.stripQuotes(s.trim())).filter(Boolean);
|
|
19041
|
+
ids.forEach((id) => this.ensure(id, "participant", ln.n));
|
|
19042
|
+
return { kind: "ref", ids, text: m[2].trim(), line: ln.n };
|
|
19043
|
+
}
|
|
19044
|
+
if (text2.startsWith("==")) {
|
|
19045
|
+
const m = /^==\s*(.*?)\s*==\s*$/.exec(text2);
|
|
19046
|
+
return { kind: "divider", text: m ? m[1].trim() : "", line: ln.n };
|
|
19047
|
+
}
|
|
19048
|
+
if (fw === "state") {
|
|
19049
|
+
const m = /^state\s+(\S+)\s*:\s*(.*)$/i.exec(text2);
|
|
19050
|
+
if (!m) throw new SequenceParseError("Malformed state invariant (expected: state A : text)", ln.n);
|
|
19051
|
+
this.ensure(m[1], "participant", ln.n);
|
|
19052
|
+
return { kind: "invariant", id: m[1], text: m[2].trim(), line: ln.n };
|
|
19053
|
+
}
|
|
19054
|
+
if (fw === "destroy") {
|
|
19055
|
+
const m = /^destroy\s+(\S+)$/i.exec(text2);
|
|
19056
|
+
if (!m) throw new SequenceParseError("Malformed destroy statement", ln.n);
|
|
19057
|
+
this.ensure(m[1], "participant", ln.n);
|
|
19058
|
+
return { kind: "destroy", id: m[1], line: ln.n };
|
|
19059
|
+
}
|
|
19060
|
+
if (fw === "autonumber") {
|
|
19061
|
+
const m = /^autonumber(?:\s+(\d+))?(?:\s+(\d+))?$/i.exec(text2);
|
|
19062
|
+
const start = m && m[1] ? parseInt(m[1], 10) : 1;
|
|
19063
|
+
const step = m && m[2] ? parseInt(m[2], 10) : 1;
|
|
19064
|
+
this.autonumberSpec = { start, step };
|
|
19065
|
+
return null;
|
|
19066
|
+
}
|
|
19067
|
+
return this.parseMessage(ln);
|
|
19068
|
+
}
|
|
19069
|
+
parseNote(ln) {
|
|
19070
|
+
const m = /^note\s+(over|left of|right of)\s+(.+?)\s*:\s*(.*)$/i.exec(ln.text);
|
|
19071
|
+
if (!m) {
|
|
19072
|
+
throw new SequenceParseError(
|
|
19073
|
+
"Malformed note (expected: note over|left of|right of A[, B] : text)",
|
|
19074
|
+
ln.n
|
|
19075
|
+
);
|
|
19076
|
+
}
|
|
19077
|
+
const placementRaw = m[1].toLowerCase();
|
|
19078
|
+
const placement = placementRaw === "over" ? "over" : placementRaw.startsWith("left") ? "left" : "right";
|
|
19079
|
+
const ids = m[2].split(",").map((s) => chunkNAGUZFXX_cjs.stripQuotes(s.trim())).filter(Boolean);
|
|
19080
|
+
ids.forEach((id) => this.ensure(id, "participant", ln.n));
|
|
19081
|
+
return { kind: "note", placement, ids, text: m[3].trim(), line: ln.n };
|
|
19082
|
+
}
|
|
19083
|
+
parseMessage(ln) {
|
|
19084
|
+
const text2 = ln.text;
|
|
19085
|
+
const arrowMatch = ARROW_RE.exec(text2);
|
|
19086
|
+
if (!arrowMatch) {
|
|
19087
|
+
throw new SequenceParseError(`Cannot parse statement: "${text2}"`, ln.n);
|
|
19088
|
+
}
|
|
19089
|
+
const token = arrowMatch[1];
|
|
19090
|
+
const at = arrowMatch.index;
|
|
19091
|
+
const leftRaw = text2.slice(0, at);
|
|
19092
|
+
let rightRaw = text2.slice(at + token.length);
|
|
19093
|
+
let label;
|
|
19094
|
+
const colon = rightRaw.indexOf(":");
|
|
19095
|
+
if (colon >= 0) {
|
|
19096
|
+
label = rightRaw.slice(colon + 1).trim();
|
|
19097
|
+
rightRaw = rightRaw.slice(0, colon);
|
|
19098
|
+
}
|
|
19099
|
+
let activateTarget = false;
|
|
19100
|
+
let deactivateSource = false;
|
|
19101
|
+
let left = leftRaw.trim();
|
|
19102
|
+
if (left.endsWith("+")) {
|
|
19103
|
+
activateTarget = true;
|
|
19104
|
+
left = left.slice(0, -1).trim();
|
|
19105
|
+
} else if (left.endsWith("-")) {
|
|
19106
|
+
deactivateSource = true;
|
|
19107
|
+
left = left.slice(0, -1).trim();
|
|
19108
|
+
}
|
|
19109
|
+
let right = rightRaw.trim();
|
|
19110
|
+
if (right.startsWith("+")) {
|
|
19111
|
+
activateTarget = true;
|
|
19112
|
+
right = right.slice(1).trim();
|
|
19113
|
+
} else if (right.startsWith("-")) {
|
|
19114
|
+
deactivateSource = true;
|
|
19115
|
+
right = right.slice(1).trim();
|
|
19116
|
+
}
|
|
19117
|
+
const arrow = arrowKind(token);
|
|
19118
|
+
let create = false;
|
|
19119
|
+
if (right.startsWith("*")) {
|
|
19120
|
+
create = true;
|
|
19121
|
+
right = right.slice(1).trim();
|
|
19122
|
+
}
|
|
19123
|
+
const from = arrow === "found" ? "" : chunkNAGUZFXX_cjs.stripQuotes(left);
|
|
19124
|
+
const to = arrow === "lost" ? "" : chunkNAGUZFXX_cjs.stripQuotes(right);
|
|
19125
|
+
if (from) this.ensure(from, "participant", ln.n);
|
|
19126
|
+
if (to) {
|
|
19127
|
+
const p = this.ensure(to, "participant", ln.n);
|
|
19128
|
+
if (create) p.createdInline = true;
|
|
19129
|
+
}
|
|
19130
|
+
const msg = {
|
|
19131
|
+
kind: "message",
|
|
19132
|
+
from,
|
|
19133
|
+
to,
|
|
19134
|
+
arrow,
|
|
19135
|
+
line: ln.n
|
|
19136
|
+
};
|
|
19137
|
+
if (label) msg.label = label;
|
|
19138
|
+
if (activateTarget) msg.activateTarget = true;
|
|
19139
|
+
if (deactivateSource) msg.deactivateSource = true;
|
|
19140
|
+
if (create) msg.create = true;
|
|
19141
|
+
return msg;
|
|
19142
|
+
}
|
|
19143
|
+
};
|
|
19144
|
+
function parseSequence(text2) {
|
|
19145
|
+
return new SequenceParser(text2).parse();
|
|
19146
|
+
}
|
|
19147
|
+
|
|
19148
|
+
// src/diagrams/sequence/layout.ts
|
|
19149
|
+
var SEQ_CONST = {
|
|
19150
|
+
HEAD_W_MIN: 90,
|
|
19151
|
+
HEAD_H: 38,
|
|
19152
|
+
HEAD_PAD_X: 14,
|
|
19153
|
+
LIFELINE_GAP: 140,
|
|
19154
|
+
LEFT_MARGIN: 24,
|
|
19155
|
+
RIGHT_PAD: 28,
|
|
19156
|
+
TOP_PAD: 16,
|
|
19157
|
+
HEAD_TO_FIRST: 30,
|
|
19158
|
+
EVENT_GAP: 38,
|
|
19159
|
+
BOTTOM_PAD: 30,
|
|
19160
|
+
SELF_GAP: 30,
|
|
19161
|
+
SELF_LOOP_W: 48,
|
|
19162
|
+
ACT_W: 10,
|
|
19163
|
+
ACT_NEST_DX: 6,
|
|
19164
|
+
ACT_STEP: 30,
|
|
19165
|
+
FRAG_PAD_X: 10,
|
|
19166
|
+
FRAG_LABEL_H: 18,
|
|
19167
|
+
FRAG_PAD_TOP: 16,
|
|
19168
|
+
FRAG_PAD_BOTTOM: 12,
|
|
19169
|
+
FRAG_GAP_BEFORE: 12,
|
|
19170
|
+
FRAG_OPERAND_GAP: 18,
|
|
19171
|
+
FRAG_NEST_INSET: 8,
|
|
19172
|
+
REF_H: 40,
|
|
19173
|
+
REF_GAP_BEFORE: 12,
|
|
19174
|
+
NOTE_GAP_BEFORE: 10,
|
|
19175
|
+
NOTE_PAD: 8,
|
|
19176
|
+
NOTE_MIN_W: 70,
|
|
19177
|
+
NOTE_LINE_H: 15,
|
|
19178
|
+
NOTE_SIDE_GAP: 16,
|
|
19179
|
+
DIV_H: 26,
|
|
19180
|
+
DIV_GAP_BEFORE: 8,
|
|
19181
|
+
INV_GAP_BEFORE: 10,
|
|
19182
|
+
INV_PAD: 10,
|
|
19183
|
+
INV_H: 24,
|
|
19184
|
+
LABEL_GAP_PAD: 26,
|
|
19185
|
+
LOST_LEN: 72
|
|
19186
|
+
};
|
|
19187
|
+
var LABEL_SIZE = 11;
|
|
19188
|
+
var HEAD_TEXT_SIZE = 12.5;
|
|
19189
|
+
function textWidth(s, size) {
|
|
19190
|
+
let w = 0;
|
|
19191
|
+
for (const ch of s) {
|
|
19192
|
+
w += /[⺀-]/.test(ch) ? size : size * 0.55;
|
|
19193
|
+
}
|
|
19194
|
+
return w;
|
|
19195
|
+
}
|
|
19196
|
+
var SequenceLayout = class {
|
|
19197
|
+
ast;
|
|
19198
|
+
lifelines = [];
|
|
19199
|
+
colOf = /* @__PURE__ */ new Map();
|
|
19200
|
+
llById = /* @__PURE__ */ new Map();
|
|
19201
|
+
x = [];
|
|
19202
|
+
headW = [];
|
|
19203
|
+
y = 0;
|
|
19204
|
+
open = /* @__PURE__ */ new Map();
|
|
19205
|
+
colAccStack = [];
|
|
19206
|
+
messages = [];
|
|
19207
|
+
activations = [];
|
|
19208
|
+
fragments = [];
|
|
19209
|
+
refs = [];
|
|
19210
|
+
notes = [];
|
|
19211
|
+
dividers = [];
|
|
19212
|
+
invariants = [];
|
|
19213
|
+
destroys = [];
|
|
19214
|
+
warnings = [];
|
|
19215
|
+
autoCounter = null;
|
|
19216
|
+
contentRight = 0;
|
|
19217
|
+
constructor(ast) {
|
|
19218
|
+
this.ast = ast;
|
|
19219
|
+
}
|
|
19220
|
+
run() {
|
|
19221
|
+
this.buildColumns();
|
|
19222
|
+
if (this.ast.autonumber) this.autoCounter = this.ast.autonumber.start;
|
|
19223
|
+
const headBottom = SEQ_CONST.TOP_PAD + SEQ_CONST.HEAD_H;
|
|
19224
|
+
this.y = headBottom + SEQ_CONST.HEAD_TO_FIRST - SEQ_CONST.EVENT_GAP;
|
|
19225
|
+
this.walk(this.ast.statements, 0);
|
|
19226
|
+
const bottomY = this.y + SEQ_CONST.EVENT_GAP;
|
|
19227
|
+
for (const [id, stack] of this.open) {
|
|
19228
|
+
while (stack.length) {
|
|
19229
|
+
const b = stack.pop();
|
|
19230
|
+
this.activations.push({ id, x: b.x, yTop: b.yTop, yBottom: bottomY, level: b.level });
|
|
19231
|
+
}
|
|
19232
|
+
}
|
|
19233
|
+
const bodyBottom = bottomY + SEQ_CONST.BOTTOM_PAD;
|
|
19234
|
+
for (const ll of this.lifelines) {
|
|
19235
|
+
if (!ll.destroyed) ll.axisBottom = bodyBottom;
|
|
19236
|
+
}
|
|
19237
|
+
const lastCenter = this.x[this.x.length - 1] ?? SEQ_CONST.LEFT_MARGIN;
|
|
19238
|
+
const lastHalf = (this.headW[this.headW.length - 1] ?? SEQ_CONST.HEAD_W_MIN) / 2;
|
|
19239
|
+
this.contentRight = Math.max(this.contentRight, lastCenter + lastHalf);
|
|
19240
|
+
const width = Math.round(this.contentRight + SEQ_CONST.RIGHT_PAD);
|
|
19241
|
+
const height = Math.round(bodyBottom);
|
|
19242
|
+
for (const d of this.dividers) d.width = width;
|
|
19243
|
+
const result = {
|
|
19244
|
+
width,
|
|
19245
|
+
height,
|
|
19246
|
+
lifelines: this.lifelines,
|
|
19247
|
+
messages: this.messages,
|
|
19248
|
+
activations: this.activations,
|
|
19249
|
+
fragments: this.fragments,
|
|
19250
|
+
refs: this.refs,
|
|
19251
|
+
notes: this.notes,
|
|
19252
|
+
dividers: this.dividers,
|
|
19253
|
+
invariants: this.invariants,
|
|
19254
|
+
destroys: this.destroys,
|
|
19255
|
+
warnings: this.warnings.concat(this.ast.warnings),
|
|
19256
|
+
ast: this.ast
|
|
19257
|
+
};
|
|
19258
|
+
if (this.ast.title) result.title = this.ast.title;
|
|
19259
|
+
return result;
|
|
19260
|
+
}
|
|
19261
|
+
// ── horizontal pass ──────────────────────────────────────────
|
|
19262
|
+
buildColumns() {
|
|
19263
|
+
const ps = this.ast.participants;
|
|
19264
|
+
this.headW = ps.map(
|
|
19265
|
+
(p) => Math.max(SEQ_CONST.HEAD_W_MIN, Math.ceil(textWidth(p.name, HEAD_TEXT_SIZE)) + SEQ_CONST.HEAD_PAD_X * 2)
|
|
19266
|
+
);
|
|
19267
|
+
ps.forEach((p, i) => this.colOf.set(p.id, i));
|
|
19268
|
+
const n = ps.length;
|
|
19269
|
+
const gaps = new Array(Math.max(0, n - 1)).fill(SEQ_CONST.LIFELINE_GAP);
|
|
19270
|
+
for (let k = 0; k < gaps.length; k++) {
|
|
19271
|
+
gaps[k] = Math.max(gaps[k], this.headW[k] / 2 + this.headW[k + 1] / 2 + 28);
|
|
19272
|
+
}
|
|
19273
|
+
const msgs = collectMessages(this.ast.statements);
|
|
19274
|
+
for (const m of msgs) {
|
|
19275
|
+
const label = m.label ?? "";
|
|
19276
|
+
const w = textWidth(label, LABEL_SIZE) + SEQ_CONST.LABEL_GAP_PAD;
|
|
19277
|
+
const cf = this.colOf.get(m.from);
|
|
19278
|
+
const ct = this.colOf.get(m.to);
|
|
19279
|
+
if (cf === void 0 && ct === void 0) continue;
|
|
19280
|
+
if (cf === void 0 || ct === void 0) continue;
|
|
19281
|
+
if (cf === ct) {
|
|
19282
|
+
if (cf < gaps.length) gaps[cf] = Math.max(gaps[cf], SEQ_CONST.SELF_LOOP_W + w);
|
|
19283
|
+
continue;
|
|
19284
|
+
}
|
|
19285
|
+
const i = Math.min(cf, ct);
|
|
19286
|
+
const j = Math.max(cf, ct);
|
|
19287
|
+
if (j === i + 1) {
|
|
19288
|
+
gaps[i] = Math.max(gaps[i], w);
|
|
19289
|
+
} else {
|
|
19290
|
+
let span = 0;
|
|
19291
|
+
for (let k = i; k < j; k++) span += gaps[k];
|
|
19292
|
+
if (span < w) {
|
|
19293
|
+
const add = (w - span) / (j - i);
|
|
19294
|
+
for (let k = i; k < j; k++) gaps[k] += add;
|
|
19295
|
+
}
|
|
19296
|
+
}
|
|
19297
|
+
}
|
|
19298
|
+
this.x = new Array(n);
|
|
19299
|
+
let cx = SEQ_CONST.LEFT_MARGIN + (this.headW[0] ?? SEQ_CONST.HEAD_W_MIN) / 2;
|
|
19300
|
+
for (let i = 0; i < n; i++) {
|
|
19301
|
+
this.x[i] = cx;
|
|
19302
|
+
if (i < gaps.length) cx += gaps[i];
|
|
19303
|
+
}
|
|
19304
|
+
ps.forEach((p, i) => {
|
|
19305
|
+
const created = p.createdInline === true;
|
|
19306
|
+
const headY = created ? -1 : SEQ_CONST.TOP_PAD;
|
|
19307
|
+
const ll = {
|
|
19308
|
+
participant: p,
|
|
19309
|
+
index: i,
|
|
19310
|
+
x: this.x[i],
|
|
19311
|
+
headX: this.x[i] - this.headW[i] / 2,
|
|
19312
|
+
headY,
|
|
19313
|
+
headW: this.headW[i],
|
|
19314
|
+
headH: SEQ_CONST.HEAD_H,
|
|
19315
|
+
axisTop: created ? -1 : SEQ_CONST.TOP_PAD + SEQ_CONST.HEAD_H,
|
|
19316
|
+
axisBottom: 0,
|
|
19317
|
+
destroyed: false
|
|
19318
|
+
};
|
|
19319
|
+
this.lifelines.push(ll);
|
|
19320
|
+
this.llById.set(p.id, ll);
|
|
19321
|
+
});
|
|
19322
|
+
}
|
|
19323
|
+
// ── column accounting (for fragment extents) ─────────────────
|
|
19324
|
+
touch(col) {
|
|
19325
|
+
if (col === void 0) return;
|
|
19326
|
+
for (const acc of this.colAccStack) {
|
|
19327
|
+
if (col < acc.min) acc.min = col;
|
|
19328
|
+
if (col > acc.max) acc.max = col;
|
|
19329
|
+
}
|
|
19330
|
+
}
|
|
19331
|
+
noteRight(x, w) {
|
|
19332
|
+
this.contentRight = Math.max(this.contentRight, x + w);
|
|
19333
|
+
}
|
|
19334
|
+
// ── activation bars ──────────────────────────────────────────
|
|
19335
|
+
openBar(id) {
|
|
19336
|
+
const col = this.colOf.get(id);
|
|
19337
|
+
if (col === void 0) return;
|
|
19338
|
+
const stack = this.open.get(id) ?? [];
|
|
19339
|
+
const level = stack.length;
|
|
19340
|
+
const x = this.x[col] - SEQ_CONST.ACT_W / 2 + level * SEQ_CONST.ACT_NEST_DX;
|
|
19341
|
+
stack.push({ x, yTop: this.y, level });
|
|
19342
|
+
this.open.set(id, stack);
|
|
19343
|
+
}
|
|
19344
|
+
closeBar(id) {
|
|
19345
|
+
const stack = this.open.get(id);
|
|
19346
|
+
if (!stack || stack.length === 0) {
|
|
19347
|
+
this.warnings.push(`deactivate '${id}' with no matching activation`);
|
|
19348
|
+
return;
|
|
19349
|
+
}
|
|
19350
|
+
const b = stack.pop();
|
|
19351
|
+
this.activations.push({ id, x: b.x, yTop: b.yTop, yBottom: this.y, level: b.level });
|
|
19352
|
+
}
|
|
19353
|
+
faceEdge(id, col, towardRight, extraLevel = 0) {
|
|
19354
|
+
const stack = this.open.get(id) ?? [];
|
|
19355
|
+
const levels = stack.length + extraLevel;
|
|
19356
|
+
if (levels <= 0) return this.x[col];
|
|
19357
|
+
if (!towardRight) return this.x[col] - SEQ_CONST.ACT_W / 2;
|
|
19358
|
+
return this.x[col] + SEQ_CONST.ACT_W / 2 + (levels - 1) * SEQ_CONST.ACT_NEST_DX;
|
|
19359
|
+
}
|
|
19360
|
+
// ── vertical walk ────────────────────────────────────────────
|
|
19361
|
+
walk(stmts, depth) {
|
|
19362
|
+
for (const s of stmts) {
|
|
19363
|
+
switch (s.kind) {
|
|
19364
|
+
case "message":
|
|
19365
|
+
this.placeMessage(s);
|
|
19366
|
+
break;
|
|
19367
|
+
case "activate":
|
|
19368
|
+
this.y += SEQ_CONST.ACT_STEP;
|
|
19369
|
+
this.openBar(s.id);
|
|
19370
|
+
this.touch(this.colOf.get(s.id));
|
|
19371
|
+
break;
|
|
19372
|
+
case "deactivate":
|
|
19373
|
+
this.y += SEQ_CONST.ACT_STEP;
|
|
19374
|
+
this.closeBar(s.id);
|
|
19375
|
+
this.touch(this.colOf.get(s.id));
|
|
19376
|
+
break;
|
|
19377
|
+
case "note":
|
|
19378
|
+
this.placeNote(s);
|
|
19379
|
+
break;
|
|
19380
|
+
case "ref":
|
|
19381
|
+
this.placeRef(s.ids, s.text);
|
|
19382
|
+
break;
|
|
19383
|
+
case "divider":
|
|
19384
|
+
this.y += SEQ_CONST.DIV_GAP_BEFORE;
|
|
19385
|
+
this.dividers.push({ text: s.text, y: this.y + SEQ_CONST.DIV_H / 2, width: 0 });
|
|
19386
|
+
this.y += SEQ_CONST.DIV_H;
|
|
19387
|
+
break;
|
|
19388
|
+
case "invariant":
|
|
19389
|
+
this.placeInvariant(s.id, s.text);
|
|
19390
|
+
break;
|
|
19391
|
+
case "destroy":
|
|
19392
|
+
this.placeDestroy(s.id);
|
|
19393
|
+
break;
|
|
19394
|
+
case "fragment":
|
|
19395
|
+
this.placeFragment(s.op, s.operands, depth, s.messageSet);
|
|
19396
|
+
break;
|
|
19397
|
+
}
|
|
19398
|
+
}
|
|
19399
|
+
}
|
|
19400
|
+
nextNumber() {
|
|
19401
|
+
if (this.autoCounter === null || !this.ast.autonumber) return void 0;
|
|
19402
|
+
const n = this.autoCounter;
|
|
19403
|
+
this.autoCounter += this.ast.autonumber.step;
|
|
19404
|
+
return n;
|
|
19405
|
+
}
|
|
19406
|
+
placeMessage(m) {
|
|
19407
|
+
this.y += SEQ_CONST.EVENT_GAP;
|
|
19408
|
+
const y = this.y;
|
|
19409
|
+
const cf = this.colOf.get(m.from);
|
|
19410
|
+
const ct = this.colOf.get(m.to);
|
|
19411
|
+
const self = m.from !== "" && m.from === m.to;
|
|
19412
|
+
let x1;
|
|
19413
|
+
let x2;
|
|
19414
|
+
if (m.arrow === "found") {
|
|
19415
|
+
const c = ct;
|
|
19416
|
+
x2 = this.faceEdge(m.to, c, false);
|
|
19417
|
+
x1 = x2 - SEQ_CONST.LOST_LEN;
|
|
19418
|
+
} else if (m.arrow === "lost") {
|
|
19419
|
+
const c = cf;
|
|
19420
|
+
x1 = this.faceEdge(m.from, c, true);
|
|
19421
|
+
x2 = x1 + SEQ_CONST.LOST_LEN;
|
|
19422
|
+
} else if (self) {
|
|
19423
|
+
const c = cf;
|
|
19424
|
+
x1 = this.faceEdge(m.from, c, true);
|
|
19425
|
+
x2 = x1 + SEQ_CONST.SELF_LOOP_W;
|
|
19426
|
+
} else {
|
|
19427
|
+
const fromRight = (ct ?? 0) > (cf ?? 0);
|
|
19428
|
+
x1 = this.faceEdge(m.from, cf, fromRight);
|
|
19429
|
+
if (m.create) {
|
|
19430
|
+
const halfW = this.headW[ct] / 2;
|
|
19431
|
+
x2 = fromRight ? this.x[ct] - halfW : this.x[ct] + halfW;
|
|
19432
|
+
} else {
|
|
19433
|
+
x2 = this.faceEdge(m.to, ct, !fromRight, m.activateTarget ? 1 : 0);
|
|
19434
|
+
}
|
|
19435
|
+
}
|
|
19436
|
+
const row = { message: m, y, x1, x2, self };
|
|
19437
|
+
const num = this.nextNumber();
|
|
19438
|
+
if (num !== void 0) row.number = num;
|
|
19439
|
+
if (self) {
|
|
19440
|
+
row.selfBottomY = y + SEQ_CONST.SELF_GAP;
|
|
19441
|
+
this.y = row.selfBottomY;
|
|
19442
|
+
}
|
|
19443
|
+
this.messages.push(row);
|
|
19444
|
+
this.contentRight = Math.max(this.contentRight, x1, x2);
|
|
19445
|
+
this.touch(cf);
|
|
19446
|
+
this.touch(ct);
|
|
19447
|
+
if (m.create && ct !== void 0) {
|
|
19448
|
+
const ll = this.llById.get(m.to);
|
|
19449
|
+
ll.headY = y - SEQ_CONST.HEAD_H / 2;
|
|
19450
|
+
ll.axisTop = ll.headY + SEQ_CONST.HEAD_H;
|
|
19451
|
+
}
|
|
19452
|
+
if (m.activateTarget && ct !== void 0) this.openBar(m.to);
|
|
19453
|
+
if (m.deactivateSource && cf !== void 0) this.closeBar(m.from);
|
|
19454
|
+
}
|
|
19455
|
+
placeNote(note) {
|
|
19456
|
+
this.y += SEQ_CONST.NOTE_GAP_BEFORE;
|
|
19457
|
+
const lines = note.text.split(/<br\s*\/?>|\\n/);
|
|
19458
|
+
const textW = lines.reduce((mx, l) => Math.max(mx, textWidth(l, LABEL_SIZE)), 0);
|
|
19459
|
+
const w = Math.max(SEQ_CONST.NOTE_MIN_W, Math.ceil(textW) + SEQ_CONST.NOTE_PAD * 2);
|
|
19460
|
+
const h = lines.length * SEQ_CONST.NOTE_LINE_H + SEQ_CONST.NOTE_PAD * 2;
|
|
19461
|
+
const top = this.y;
|
|
19462
|
+
const cols = note.ids.map((id) => this.colOf.get(id)).filter((c) => c !== void 0);
|
|
19463
|
+
cols.forEach((c) => this.touch(c));
|
|
19464
|
+
let x;
|
|
19465
|
+
let boxW = w;
|
|
19466
|
+
if (note.placement === "over" && cols.length >= 2) {
|
|
19467
|
+
const a = this.x[Math.min(...cols)];
|
|
19468
|
+
const b = this.x[Math.max(...cols)];
|
|
19469
|
+
const span = b - a + this.headW[Math.min(...cols)] / 2 + this.headW[Math.max(...cols)] / 2;
|
|
19470
|
+
boxW = Math.max(w, span);
|
|
19471
|
+
x = (a + b) / 2 - boxW / 2;
|
|
19472
|
+
} else if (note.placement === "left" && cols.length) {
|
|
19473
|
+
x = this.x[cols[0]] - SEQ_CONST.NOTE_SIDE_GAP - w;
|
|
19474
|
+
} else if (note.placement === "right" && cols.length) {
|
|
19475
|
+
x = this.x[cols[0]] + SEQ_CONST.NOTE_SIDE_GAP;
|
|
19476
|
+
} else {
|
|
19477
|
+
const c = cols[0] ?? 0;
|
|
19478
|
+
x = this.x[c] - w / 2;
|
|
19479
|
+
}
|
|
19480
|
+
this.notes.push({ note, x, y: top, width: boxW, height: h });
|
|
19481
|
+
this.noteRight(x, boxW);
|
|
19482
|
+
this.y = top + h;
|
|
19483
|
+
}
|
|
19484
|
+
placeRef(ids, text2) {
|
|
19485
|
+
this.y += SEQ_CONST.REF_GAP_BEFORE;
|
|
19486
|
+
const cols = ids.map((id) => this.colOf.get(id)).filter((c) => c !== void 0);
|
|
19487
|
+
cols.forEach((c) => this.touch(c));
|
|
19488
|
+
const minC = cols.length ? Math.min(...cols) : 0;
|
|
19489
|
+
const maxC = cols.length ? Math.max(...cols) : 0;
|
|
19490
|
+
const left = this.x[minC] - SEQ_CONST.FRAG_PAD_X;
|
|
19491
|
+
const right = this.x[maxC] + SEQ_CONST.FRAG_PAD_X;
|
|
19492
|
+
const top = this.y;
|
|
19493
|
+
this.refs.push({ text: text2, x: left, y: top, width: right - left, height: SEQ_CONST.REF_H });
|
|
19494
|
+
this.noteRight(left, right - left);
|
|
19495
|
+
this.y = top + SEQ_CONST.REF_H;
|
|
19496
|
+
}
|
|
19497
|
+
placeInvariant(id, text2) {
|
|
19498
|
+
this.y += SEQ_CONST.INV_GAP_BEFORE;
|
|
19499
|
+
const col = this.colOf.get(id);
|
|
19500
|
+
this.touch(col);
|
|
19501
|
+
const w = Math.ceil(textWidth(text2, LABEL_SIZE)) + SEQ_CONST.INV_PAD * 2;
|
|
19502
|
+
const cx = col !== void 0 ? this.x[col] : SEQ_CONST.LEFT_MARGIN;
|
|
19503
|
+
const top = this.y;
|
|
19504
|
+
this.invariants.push({ text: text2, cx, y: top, width: w, height: SEQ_CONST.INV_H });
|
|
19505
|
+
this.noteRight(cx - w / 2, w);
|
|
19506
|
+
this.y = top + SEQ_CONST.INV_H;
|
|
19507
|
+
}
|
|
19508
|
+
placeDestroy(id) {
|
|
19509
|
+
this.y += SEQ_CONST.EVENT_GAP / 2;
|
|
19510
|
+
const ll = this.llById.get(id);
|
|
19511
|
+
const col = this.colOf.get(id);
|
|
19512
|
+
if (ll && col !== void 0) {
|
|
19513
|
+
ll.destroyed = true;
|
|
19514
|
+
ll.axisBottom = this.y;
|
|
19515
|
+
this.destroys.push({ x: this.x[col], y: this.y });
|
|
19516
|
+
this.touch(col);
|
|
19517
|
+
}
|
|
19518
|
+
}
|
|
19519
|
+
placeFragment(op, operands, depth, messageSet) {
|
|
19520
|
+
const frameTop = this.y + SEQ_CONST.FRAG_GAP_BEFORE;
|
|
19521
|
+
const acc = { min: Number.POSITIVE_INFINITY, max: Number.NEGATIVE_INFINITY };
|
|
19522
|
+
this.colAccStack.push(acc);
|
|
19523
|
+
const operandGeom = [];
|
|
19524
|
+
this.y = frameTop + SEQ_CONST.FRAG_LABEL_H + SEQ_CONST.FRAG_PAD_TOP - SEQ_CONST.EVENT_GAP;
|
|
19525
|
+
const firstGeom = {};
|
|
19526
|
+
if (operands[0]?.guard) firstGeom.guard = operands[0].guard;
|
|
19527
|
+
operandGeom.push(firstGeom);
|
|
19528
|
+
this.walk(operands[0]?.statements ?? [], depth + 1);
|
|
19529
|
+
for (let oi = 1; oi < operands.length; oi++) {
|
|
19530
|
+
const sepY = this.y + SEQ_CONST.FRAG_OPERAND_GAP;
|
|
19531
|
+
const geom = { sepY };
|
|
19532
|
+
if (operands[oi].guard) geom.guard = operands[oi].guard;
|
|
19533
|
+
operandGeom.push(geom);
|
|
19534
|
+
this.y = sepY + SEQ_CONST.FRAG_PAD_TOP - SEQ_CONST.EVENT_GAP;
|
|
19535
|
+
this.walk(operands[oi].statements, depth + 1);
|
|
19536
|
+
}
|
|
19537
|
+
const frameBottom = this.y + SEQ_CONST.FRAG_PAD_BOTTOM;
|
|
19538
|
+
this.colAccStack.pop();
|
|
19539
|
+
let minC = acc.min;
|
|
19540
|
+
let maxC = acc.max;
|
|
19541
|
+
if (!isFinite(minC)) {
|
|
19542
|
+
minC = 0;
|
|
19543
|
+
maxC = Math.max(0, this.lifelines.length - 1);
|
|
19544
|
+
}
|
|
19545
|
+
const inset = depth * SEQ_CONST.FRAG_NEST_INSET;
|
|
19546
|
+
let left = this.x[minC] - SEQ_CONST.FRAG_PAD_X + inset;
|
|
19547
|
+
let right = this.x[maxC] + SEQ_CONST.FRAG_PAD_X - inset;
|
|
19548
|
+
if (right - left < 40) {
|
|
19549
|
+
const mid = (left + right) / 2;
|
|
19550
|
+
left = mid - 20;
|
|
19551
|
+
right = mid + 20;
|
|
19552
|
+
}
|
|
19553
|
+
const frame = {
|
|
19554
|
+
op,
|
|
19555
|
+
x: left,
|
|
19556
|
+
y: frameTop,
|
|
19557
|
+
width: right - left,
|
|
19558
|
+
height: frameBottom - frameTop,
|
|
19559
|
+
operands: operandGeom
|
|
19560
|
+
};
|
|
19561
|
+
if (messageSet && messageSet.length) frame.messageSet = messageSet;
|
|
19562
|
+
this.fragments.push(frame);
|
|
19563
|
+
this.noteRight(left, right - left);
|
|
19564
|
+
this.y = frameBottom;
|
|
19565
|
+
}
|
|
19566
|
+
};
|
|
19567
|
+
function collectMessages(stmts) {
|
|
19568
|
+
const out = [];
|
|
19569
|
+
for (const s of stmts) {
|
|
19570
|
+
if (s.kind === "message") out.push(s);
|
|
19571
|
+
else if (s.kind === "fragment") {
|
|
19572
|
+
for (const op of s.operands) out.push(...collectMessages(op.statements));
|
|
19573
|
+
}
|
|
19574
|
+
}
|
|
19575
|
+
return out;
|
|
19576
|
+
}
|
|
19577
|
+
function layoutSequence(ast) {
|
|
19578
|
+
return new SequenceLayout(ast).run();
|
|
19579
|
+
}
|
|
19580
|
+
|
|
19581
|
+
// src/diagrams/sequence/renderer.ts
|
|
19582
|
+
var HEAD = "#e8f0fb";
|
|
19583
|
+
var HEAD_STROKE = "#5b85c0";
|
|
19584
|
+
function buildCss7(t) {
|
|
19585
|
+
return `
|
|
19586
|
+
.sx-seq { font-family: system-ui, -apple-system, sans-serif; }
|
|
19587
|
+
.sx-seq-axis { stroke: ${t.neutral}; stroke-width: 1; stroke-dasharray: 4 4; }
|
|
19588
|
+
.sx-seq-head rect, .sx-seq-head path { fill: ${HEAD}; stroke: ${HEAD_STROKE}; stroke-width: 1.4; }
|
|
19589
|
+
.sx-seq-head-name { font: 600 12.5px sans-serif; fill: ${t.text}; }
|
|
19590
|
+
.sx-seq-head-stereo { font: italic 10px sans-serif; fill: ${t.textMuted}; }
|
|
19591
|
+
.sx-seq-actor line, .sx-seq-actor circle { stroke: ${t.stroke}; stroke-width: 1.6; fill: none; stroke-linecap: round; }
|
|
19592
|
+
.sx-seq-actor-head { fill: ${t.bg}; }
|
|
19593
|
+
.sx-seq-icon { fill: ${t.bg}; stroke: ${HEAD_STROKE}; stroke-width: 1.6; }
|
|
19594
|
+
.sx-seq-icon-line { stroke: ${HEAD_STROKE}; stroke-width: 1.6; fill: none; stroke-linecap: round; }
|
|
19595
|
+
.sx-seq-icon-fill { fill: ${HEAD_STROKE}; stroke: none; }
|
|
19596
|
+
.sx-seq-act { fill: ${t.bg}; stroke: ${HEAD_STROKE}; stroke-width: 1.2; }
|
|
19597
|
+
.sx-seq-msg { stroke: ${t.stroke}; stroke-width: 1.5; fill: none; }
|
|
19598
|
+
.sx-seq-msg-reply { stroke: ${t.stroke}; stroke-width: 1.4; fill: none; stroke-dasharray: 6 4; }
|
|
19599
|
+
.sx-seq-msg-label { font: 11px sans-serif; fill: ${t.text}; }
|
|
19600
|
+
.sx-seq-msg-num { font: 600 10px sans-serif; fill: ${t.textMuted}; }
|
|
19601
|
+
.sx-seq-endpoint { fill: ${t.stroke}; }
|
|
19602
|
+
.sx-seq-frame { fill: none; stroke: ${t.neutral}; stroke-width: 1.2; }
|
|
19603
|
+
.sx-seq-frame-neg { fill: ${t.negative}; fill-opacity: 0.06; }
|
|
19604
|
+
.sx-seq-frame-sep { stroke: ${t.neutral}; stroke-width: 1; stroke-dasharray: 5 4; }
|
|
19605
|
+
.sx-seq-frame-tab { fill: ${t.fillMuted}; stroke: ${t.neutral}; stroke-width: 1.2; }
|
|
19606
|
+
.sx-seq-frame-op { font: 700 11px sans-serif; fill: ${t.text}; }
|
|
19607
|
+
.sx-seq-guard { font: italic 10.5px sans-serif; fill: ${t.textMuted}; }
|
|
19608
|
+
.sx-seq-ref-name { font: 600 12px sans-serif; fill: ${t.text}; }
|
|
19609
|
+
.sx-seq-note rect { fill: #fdf6da; stroke: #d9c97e; stroke-width: 1.1; }
|
|
19610
|
+
.sx-seq-note path { fill: #efe2a6; stroke: #d9c97e; stroke-width: 1.1; }
|
|
19611
|
+
.sx-seq-note-text { font: 11px sans-serif; fill: ${t.text}; }
|
|
19612
|
+
.sx-seq-div line { stroke: ${t.neutral}; stroke-width: 1; }
|
|
19613
|
+
.sx-seq-div rect { fill: ${t.fillMuted}; stroke: ${t.neutral}; stroke-width: 1; }
|
|
19614
|
+
.sx-seq-div-text { font: 600 11px sans-serif; fill: ${t.textMuted}; }
|
|
19615
|
+
.sx-seq-inv rect { fill: ${t.bg}; stroke: ${t.neutral}; stroke-width: 1.1; }
|
|
19616
|
+
.sx-seq-inv-text { font: italic 10.5px sans-serif; fill: ${t.textMuted}; }
|
|
19617
|
+
.sx-seq-destroy { stroke: ${t.negative}; stroke-width: 2; }
|
|
19618
|
+
.sx-seq-title { font: 700 16px sans-serif; fill: ${t.text}; }
|
|
19619
|
+
`.trim();
|
|
19620
|
+
}
|
|
19621
|
+
function markers3(t) {
|
|
19622
|
+
return chunk3WNW5Y7P_cjs.defs([
|
|
19623
|
+
chunk3WNW5Y7P_cjs.el(
|
|
19624
|
+
"marker",
|
|
19625
|
+
{ id: "sx-seq-filled", viewBox: "0 0 12 10", refX: 10, refY: 5, markerWidth: 11, markerHeight: 9, orient: "auto" },
|
|
19626
|
+
[chunk3WNW5Y7P_cjs.el("polygon", { points: "0,0 11,5 0,10", fill: t.stroke })]
|
|
19627
|
+
),
|
|
19628
|
+
chunk3WNW5Y7P_cjs.el(
|
|
19629
|
+
"marker",
|
|
19630
|
+
{ id: "sx-seq-open", viewBox: "0 0 12 10", refX: 10, refY: 5, markerWidth: 12, markerHeight: 10, orient: "auto" },
|
|
19631
|
+
[chunk3WNW5Y7P_cjs.el("polyline", { points: "0,0 10,5 0,10", fill: "none", stroke: t.stroke, "stroke-width": 1.5 })]
|
|
19632
|
+
)
|
|
19633
|
+
]);
|
|
19634
|
+
}
|
|
19635
|
+
var CHAR_W2 = 6;
|
|
19636
|
+
function renderLifeline(ll) {
|
|
19637
|
+
const parts = [];
|
|
19638
|
+
parts.push(chunk3WNW5Y7P_cjs.line({ class: "sx-seq-axis", x1: ll.x, y1: ll.axisTop, x2: ll.x, y2: ll.axisBottom }));
|
|
19639
|
+
parts.push(renderHead(ll));
|
|
19640
|
+
return chunk3WNW5Y7P_cjs.group({ class: "sx-seq-lifeline", "data-id": ll.participant.id, "data-kind": ll.participant.kind }, parts);
|
|
19641
|
+
}
|
|
19642
|
+
function renderHead(ll) {
|
|
19643
|
+
const p = ll.participant;
|
|
19644
|
+
const cx = ll.x;
|
|
19645
|
+
const stereo = p.stereotype ? `\xAB${p.stereotype}\xBB` : null;
|
|
19646
|
+
if (p.kind === "actor") {
|
|
19647
|
+
const topY = ll.headY;
|
|
19648
|
+
const fig = [];
|
|
19649
|
+
if (stereo) {
|
|
19650
|
+
fig.push(chunk3WNW5Y7P_cjs.text({ class: "sx-seq-head-stereo", x: cx, y: topY - 4, "text-anchor": "middle" }, stereo));
|
|
19651
|
+
}
|
|
19652
|
+
fig.push(
|
|
19653
|
+
chunk3WNW5Y7P_cjs.circle({ class: "sx-seq-actor-head", cx, cy: topY + 6, r: 4.5 }),
|
|
19654
|
+
chunk3WNW5Y7P_cjs.line({ x1: cx, y1: topY + 10, x2: cx, y2: topY + 22 }),
|
|
19655
|
+
chunk3WNW5Y7P_cjs.line({ x1: cx - 8, y1: topY + 14, x2: cx + 8, y2: topY + 14 }),
|
|
19656
|
+
chunk3WNW5Y7P_cjs.line({ x1: cx, y1: topY + 22, x2: cx - 7, y2: topY + 32 }),
|
|
19657
|
+
chunk3WNW5Y7P_cjs.line({ x1: cx, y1: topY + 22, x2: cx + 7, y2: topY + 32 }),
|
|
19658
|
+
chunk3WNW5Y7P_cjs.text({ class: "sx-seq-head-name", x: cx, y: topY + 44, "text-anchor": "middle" }, p.name)
|
|
19659
|
+
);
|
|
19660
|
+
return chunk3WNW5Y7P_cjs.group({ class: "sx-seq-actor sx-seq-head" }, fig);
|
|
19661
|
+
}
|
|
19662
|
+
if (p.kind === "boundary" || p.kind === "control" || p.kind === "entity") {
|
|
19663
|
+
return renderRobustnessIcon(ll, stereo);
|
|
19664
|
+
}
|
|
19665
|
+
if (p.kind === "database") {
|
|
19666
|
+
const w = ll.headW;
|
|
19667
|
+
const h = ll.headH;
|
|
19668
|
+
const x = ll.headX;
|
|
19669
|
+
const y = ll.headY;
|
|
19670
|
+
const ry = 5;
|
|
19671
|
+
const d = `M ${x} ${y + ry} a ${w / 2} ${ry} 0 0 1 ${w} 0 v ${h - 2 * ry} a ${w / 2} ${ry} 0 0 1 ${-w} 0 Z M ${x} ${y + ry} a ${w / 2} ${ry} 0 0 0 ${w} 0`;
|
|
19672
|
+
return chunk3WNW5Y7P_cjs.group({ class: "sx-seq-head" }, [
|
|
19673
|
+
chunk3WNW5Y7P_cjs.path({ d }),
|
|
19674
|
+
chunk3WNW5Y7P_cjs.text({ class: "sx-seq-head-name", x: cx, y: y + h / 2 + 6, "text-anchor": "middle" }, p.name)
|
|
19675
|
+
]);
|
|
19676
|
+
}
|
|
19677
|
+
const parts = [
|
|
19678
|
+
chunk3WNW5Y7P_cjs.rect({ x: ll.headX, y: ll.headY, width: ll.headW, height: ll.headH, rx: 3, ry: 3 })
|
|
19679
|
+
];
|
|
19680
|
+
const stereoText = stereo ?? (p.kind === "collections" || p.kind === "queue" ? `\xAB${p.kind}\xBB` : null);
|
|
19681
|
+
if (stereoText) {
|
|
19682
|
+
parts.push(
|
|
19683
|
+
chunk3WNW5Y7P_cjs.text({ class: "sx-seq-head-stereo", x: cx, y: ll.headY + 14, "text-anchor": "middle" }, stereoText)
|
|
19684
|
+
);
|
|
19685
|
+
parts.push(
|
|
19686
|
+
chunk3WNW5Y7P_cjs.text({ class: "sx-seq-head-name", x: cx, y: ll.headY + 28, "text-anchor": "middle" }, p.name)
|
|
19687
|
+
);
|
|
19688
|
+
} else {
|
|
19689
|
+
parts.push(
|
|
19690
|
+
chunk3WNW5Y7P_cjs.text({ class: "sx-seq-head-name", x: cx, y: ll.headY + ll.headH / 2 + 5, "text-anchor": "middle" }, p.name)
|
|
19691
|
+
);
|
|
19692
|
+
}
|
|
19693
|
+
return chunk3WNW5Y7P_cjs.group({ class: "sx-seq-head" }, parts);
|
|
19694
|
+
}
|
|
19695
|
+
function renderRobustnessIcon(ll, stereo) {
|
|
19696
|
+
const p = ll.participant;
|
|
19697
|
+
const cx = ll.x;
|
|
19698
|
+
const R = 11;
|
|
19699
|
+
const cy = ll.headY + 14;
|
|
19700
|
+
const parts = [];
|
|
19701
|
+
if (stereo) {
|
|
19702
|
+
parts.push(chunk3WNW5Y7P_cjs.text({ class: "sx-seq-head-stereo", x: cx, y: ll.headY - 2, "text-anchor": "middle" }, stereo));
|
|
19703
|
+
}
|
|
19704
|
+
parts.push(chunk3WNW5Y7P_cjs.circle({ class: "sx-seq-icon", cx, cy, r: R }));
|
|
19705
|
+
if (p.kind === "boundary") {
|
|
19706
|
+
const bx = cx - R - 9;
|
|
19707
|
+
parts.push(chunk3WNW5Y7P_cjs.line({ class: "sx-seq-icon-line", x1: bx, y1: cy - R, x2: bx, y2: cy + R }));
|
|
19708
|
+
parts.push(chunk3WNW5Y7P_cjs.line({ class: "sx-seq-icon-line", x1: bx, y1: cy, x2: cx - R, y2: cy }));
|
|
19709
|
+
} else if (p.kind === "entity") {
|
|
19710
|
+
parts.push(chunk3WNW5Y7P_cjs.line({ class: "sx-seq-icon-line", x1: cx - R - 2, y1: cy + R + 1, x2: cx + R + 2, y2: cy + R + 1 }));
|
|
19711
|
+
} else {
|
|
19712
|
+
parts.push(
|
|
19713
|
+
chunk3WNW5Y7P_cjs.polygon({ class: "sx-seq-icon-fill", points: `${cx - 2},${cy - R - 6} ${cx + 5},${cy - R - 1} ${cx - 3},${cy - R + 2}` })
|
|
19714
|
+
);
|
|
19715
|
+
}
|
|
19716
|
+
parts.push(chunk3WNW5Y7P_cjs.text({ class: "sx-seq-head-name", x: cx, y: ll.headY + 44, "text-anchor": "middle" }, p.name));
|
|
19717
|
+
return chunk3WNW5Y7P_cjs.group({ class: "sx-seq-head sx-seq-icon-head", "data-icon": p.kind }, parts);
|
|
19718
|
+
}
|
|
19719
|
+
function renderActivation(a) {
|
|
19720
|
+
const h = Math.max(6, a.yBottom - a.yTop);
|
|
19721
|
+
return chunk3WNW5Y7P_cjs.rect({
|
|
19722
|
+
class: "sx-seq-act",
|
|
19723
|
+
"data-id": a.id,
|
|
19724
|
+
x: a.x,
|
|
19725
|
+
y: a.yTop,
|
|
19726
|
+
width: 10,
|
|
19727
|
+
height: h
|
|
19728
|
+
});
|
|
19729
|
+
}
|
|
19730
|
+
function renderMessage(m) {
|
|
19731
|
+
const k = m.message.arrow;
|
|
19732
|
+
const lineClass2 = k === "reply" ? "sx-seq-msg-reply" : "sx-seq-msg";
|
|
19733
|
+
const markerEnd = k === "async" || k === "reply" ? "url(#sx-seq-open)" : "url(#sx-seq-filled)";
|
|
19734
|
+
const parts = [];
|
|
19735
|
+
if (m.self) {
|
|
19736
|
+
const bottom = m.selfBottomY ?? m.y + 28;
|
|
19737
|
+
const right = m.x2;
|
|
19738
|
+
const d = `M ${m.x1} ${m.y} H ${right} V ${bottom} H ${m.x1}`;
|
|
19739
|
+
parts.push(chunk3WNW5Y7P_cjs.path({ class: lineClass2, d, "marker-end": markerEnd }));
|
|
19740
|
+
if (m.message.label) {
|
|
19741
|
+
parts.push(
|
|
19742
|
+
chunk3WNW5Y7P_cjs.text(
|
|
19743
|
+
{ class: "sx-seq-msg-label", x: right + 6, y: (m.y + bottom) / 2 + 3 },
|
|
19744
|
+
numbered(m, m.message.label)
|
|
19745
|
+
)
|
|
19746
|
+
);
|
|
19747
|
+
}
|
|
19748
|
+
} else {
|
|
19749
|
+
parts.push(chunk3WNW5Y7P_cjs.line({ class: lineClass2, x1: m.x1, y1: m.y, x2: m.x2, y2: m.y, "marker-end": markerEnd }));
|
|
19750
|
+
if (k === "lost") parts.push(chunk3WNW5Y7P_cjs.circle({ class: "sx-seq-endpoint", cx: m.x2, cy: m.y, r: 4 }));
|
|
19751
|
+
if (k === "found") parts.push(chunk3WNW5Y7P_cjs.circle({ class: "sx-seq-endpoint", cx: m.x1, cy: m.y, r: 4 }));
|
|
19752
|
+
if (m.message.label) {
|
|
19753
|
+
const mid = (m.x1 + m.x2) / 2;
|
|
19754
|
+
parts.push(
|
|
19755
|
+
chunk3WNW5Y7P_cjs.text(
|
|
19756
|
+
{ class: "sx-seq-msg-label", x: mid, y: m.y - 6, "text-anchor": "middle" },
|
|
19757
|
+
numbered(m, m.message.label)
|
|
19758
|
+
)
|
|
19759
|
+
);
|
|
19760
|
+
}
|
|
19761
|
+
}
|
|
19762
|
+
return chunk3WNW5Y7P_cjs.group(
|
|
19763
|
+
{
|
|
19764
|
+
class: "sx-seq-message",
|
|
19765
|
+
"data-kind": k,
|
|
19766
|
+
"data-from": m.message.from,
|
|
19767
|
+
"data-to": m.message.to
|
|
19768
|
+
},
|
|
19769
|
+
parts
|
|
19770
|
+
);
|
|
19771
|
+
}
|
|
19772
|
+
function numbered(m, label) {
|
|
19773
|
+
return m.number !== void 0 ? `${m.number}. ${label}` : label;
|
|
19774
|
+
}
|
|
19775
|
+
function tabWidth(f) {
|
|
19776
|
+
return Math.max(40, f.op.length * 8 + 22);
|
|
19777
|
+
}
|
|
19778
|
+
function renderFragmentBox(f) {
|
|
19779
|
+
const frameClass = f.op === "neg" ? "sx-seq-frame sx-seq-frame-neg" : "sx-seq-frame";
|
|
19780
|
+
const parts = [
|
|
19781
|
+
chunk3WNW5Y7P_cjs.rect({ class: frameClass, x: f.x, y: f.y, width: f.width, height: f.height, rx: 2, ry: 2 })
|
|
19782
|
+
];
|
|
19783
|
+
for (const op of f.operands) {
|
|
19784
|
+
if (op.sepY !== void 0) {
|
|
19785
|
+
parts.push(chunk3WNW5Y7P_cjs.line({ class: "sx-seq-frame-sep", x1: f.x, y1: op.sepY, x2: f.x + f.width, y2: op.sepY }));
|
|
19786
|
+
}
|
|
19787
|
+
}
|
|
19788
|
+
return chunk3WNW5Y7P_cjs.group({ class: "sx-seq-fragment", "data-op": f.op }, parts);
|
|
19789
|
+
}
|
|
19790
|
+
function renderFragmentTab(f) {
|
|
19791
|
+
const tabW = tabWidth(f);
|
|
19792
|
+
const tabH = 18;
|
|
19793
|
+
const fold = 6;
|
|
19794
|
+
const tx = f.x;
|
|
19795
|
+
const ty = f.y;
|
|
19796
|
+
const tab = `M ${tx} ${ty} H ${tx + tabW} V ${ty + tabH - fold} L ${tx + tabW - fold} ${ty + tabH} H ${tx} Z`;
|
|
19797
|
+
const parts = [
|
|
19798
|
+
chunk3WNW5Y7P_cjs.path({ class: "sx-seq-frame-tab", d: tab }),
|
|
19799
|
+
chunk3WNW5Y7P_cjs.text({ class: "sx-seq-frame-op", x: tx + 8, y: ty + 13 }, f.op)
|
|
19800
|
+
];
|
|
19801
|
+
if (f.messageSet && f.messageSet.length) {
|
|
19802
|
+
parts.push(
|
|
19803
|
+
chunk3WNW5Y7P_cjs.text({ class: "sx-seq-guard", x: tx + tabW + 8, y: ty + 13 }, `{${f.messageSet.join(", ")}}`)
|
|
19804
|
+
);
|
|
19805
|
+
}
|
|
19806
|
+
f.operands.forEach((op, i) => {
|
|
19807
|
+
if (!op.guard) return;
|
|
19808
|
+
const gx = i === 0 ? f.x + tabW + 8 : f.x + 8;
|
|
19809
|
+
const gy = i === 0 ? f.y + 13 : (op.sepY ?? f.y) + 14;
|
|
19810
|
+
parts.push(chunk3WNW5Y7P_cjs.text({ class: "sx-seq-guard", x: gx, y: gy }, `[${op.guard}]`));
|
|
19811
|
+
});
|
|
19812
|
+
return chunk3WNW5Y7P_cjs.group({ class: "sx-seq-fragment-tab-g", "data-op": f.op }, parts);
|
|
19813
|
+
}
|
|
19814
|
+
function renderRef(r) {
|
|
19815
|
+
const tabW = 40;
|
|
19816
|
+
const tabH = 18;
|
|
19817
|
+
const fold = 6;
|
|
19818
|
+
const tab = `M ${r.x} ${r.y} H ${r.x + tabW} V ${r.y + tabH - fold} L ${r.x + tabW - fold} ${r.y + tabH} H ${r.x} Z`;
|
|
19819
|
+
return chunk3WNW5Y7P_cjs.group({ class: "sx-seq-fragment", "data-op": "ref" }, [
|
|
19820
|
+
chunk3WNW5Y7P_cjs.rect({ class: "sx-seq-frame", x: r.x, y: r.y, width: r.width, height: r.height, rx: 2, ry: 2 }),
|
|
19821
|
+
chunk3WNW5Y7P_cjs.path({ class: "sx-seq-frame-tab", d: tab }),
|
|
19822
|
+
chunk3WNW5Y7P_cjs.text({ class: "sx-seq-frame-op", x: r.x + 8, y: r.y + 13 }, "ref"),
|
|
19823
|
+
chunk3WNW5Y7P_cjs.text(
|
|
19824
|
+
{ class: "sx-seq-ref-name", x: r.x + r.width / 2, y: r.y + r.height / 2 + 8, "text-anchor": "middle" },
|
|
19825
|
+
r.text
|
|
19826
|
+
)
|
|
19827
|
+
]);
|
|
19828
|
+
}
|
|
19829
|
+
function renderNote2(nb) {
|
|
19830
|
+
const fold = 8;
|
|
19831
|
+
const x = nb.x;
|
|
19832
|
+
const y = nb.y;
|
|
19833
|
+
const w = nb.width;
|
|
19834
|
+
const h = nb.height;
|
|
19835
|
+
const body = `M ${x} ${y} H ${x + w - fold} L ${x + w} ${y + fold} V ${y + h} H ${x} Z`;
|
|
19836
|
+
const corner = `M ${x + w - fold} ${y} V ${y + fold} H ${x + w} Z`;
|
|
19837
|
+
const lines = nb.note.text.split(/<br\s*\/?>|\\n/);
|
|
19838
|
+
const startY = y + h / 2 - (lines.length - 1) * 15 / 2 + 4;
|
|
19839
|
+
const texts = lines.map(
|
|
19840
|
+
(l, i) => chunk3WNW5Y7P_cjs.text({ class: "sx-seq-note-text", x: x + w / 2, y: startY + i * 15, "text-anchor": "middle" }, l)
|
|
19841
|
+
);
|
|
19842
|
+
return chunk3WNW5Y7P_cjs.group({ class: "sx-seq-note" }, [chunk3WNW5Y7P_cjs.path({ d: body }), chunk3WNW5Y7P_cjs.path({ d: corner }), ...texts]);
|
|
19843
|
+
}
|
|
19844
|
+
function renderDivider(d) {
|
|
19845
|
+
const labelW = Math.max(60, d.text.length * CHAR_W2 + 24);
|
|
19846
|
+
const cx = d.width / 2;
|
|
19847
|
+
const parts = [
|
|
19848
|
+
chunk3WNW5Y7P_cjs.line({ x1: 8, y1: d.y, x2: cx - labelW / 2, y2: d.y }),
|
|
19849
|
+
chunk3WNW5Y7P_cjs.line({ x1: cx + labelW / 2, y1: d.y, x2: d.width - 8, y2: d.y }),
|
|
19850
|
+
chunk3WNW5Y7P_cjs.rect({ x: cx - labelW / 2, y: d.y - 11, width: labelW, height: 22, rx: 4, ry: 4 }),
|
|
19851
|
+
chunk3WNW5Y7P_cjs.text({ class: "sx-seq-div-text", x: cx, y: d.y + 4, "text-anchor": "middle" }, d.text)
|
|
19852
|
+
];
|
|
19853
|
+
return chunk3WNW5Y7P_cjs.group({ class: "sx-seq-div" }, parts);
|
|
19854
|
+
}
|
|
19855
|
+
function renderInvariant(iv) {
|
|
19856
|
+
return chunk3WNW5Y7P_cjs.group({ class: "sx-seq-inv" }, [
|
|
19857
|
+
chunk3WNW5Y7P_cjs.rect({ x: iv.cx - iv.width / 2, y: iv.y, width: iv.width, height: iv.height, rx: iv.height / 2, ry: iv.height / 2 }),
|
|
19858
|
+
chunk3WNW5Y7P_cjs.text({ class: "sx-seq-inv-text", x: iv.cx, y: iv.y + iv.height / 2 + 4, "text-anchor": "middle" }, `{${iv.text}}`)
|
|
19859
|
+
]);
|
|
19860
|
+
}
|
|
19861
|
+
function renderDestroy(d) {
|
|
19862
|
+
const r = 7;
|
|
19863
|
+
return chunk3WNW5Y7P_cjs.group({ class: "sx-seq-destroy-g" }, [
|
|
19864
|
+
chunk3WNW5Y7P_cjs.line({ class: "sx-seq-destroy", x1: d.x - r, y1: d.y - r, x2: d.x + r, y2: d.y + r }),
|
|
19865
|
+
chunk3WNW5Y7P_cjs.line({ class: "sx-seq-destroy", x1: d.x - r, y1: d.y + r, x2: d.x + r, y2: d.y - r })
|
|
19866
|
+
]);
|
|
19867
|
+
}
|
|
19868
|
+
function renderSequenceLayout(layout, config) {
|
|
19869
|
+
const t = chunkD7EHZFK4_cjs.resolveBaseTheme(config?.theme ?? "default");
|
|
19870
|
+
const children = [];
|
|
19871
|
+
const nMsg = layout.messages.length;
|
|
19872
|
+
const nFrag = layout.fragments.length;
|
|
19873
|
+
children.push(chunk3WNW5Y7P_cjs.title(`Sequence Diagram${layout.title ? " \u2014 " + layout.title : ""}`));
|
|
19874
|
+
children.push(
|
|
19875
|
+
chunk3WNW5Y7P_cjs.desc(
|
|
19876
|
+
`${layout.lifelines.length} participants, ${nMsg} messages, ${nFrag} combined fragments.`
|
|
19877
|
+
)
|
|
19878
|
+
);
|
|
19879
|
+
children.push(chunk3WNW5Y7P_cjs.el("style", {}, buildCss7(t)));
|
|
19880
|
+
children.push(markers3(t));
|
|
19881
|
+
const titleBand = layout.title ? 32 : 0;
|
|
19882
|
+
if (layout.title) {
|
|
19883
|
+
children.push(
|
|
19884
|
+
chunk3WNW5Y7P_cjs.text({ x: layout.width / 2, y: 22, class: "sx-seq-title", "text-anchor": "middle" }, layout.title)
|
|
19885
|
+
);
|
|
19886
|
+
}
|
|
19887
|
+
const body = [];
|
|
19888
|
+
body.push(chunk3WNW5Y7P_cjs.group({ class: "sx-seq-lifelines" }, layout.lifelines.map(renderLifeline)));
|
|
19889
|
+
body.push(chunk3WNW5Y7P_cjs.group({ class: "sx-seq-frames" }, layout.fragments.map(renderFragmentBox)));
|
|
19890
|
+
body.push(chunk3WNW5Y7P_cjs.group({ class: "sx-seq-acts" }, layout.activations.map(renderActivation)));
|
|
19891
|
+
body.push(chunk3WNW5Y7P_cjs.group({ class: "sx-seq-frame-tabs" }, layout.fragments.map(renderFragmentTab)));
|
|
19892
|
+
body.push(chunk3WNW5Y7P_cjs.group({ class: "sx-seq-refs" }, layout.refs.map(renderRef)));
|
|
19893
|
+
body.push(chunk3WNW5Y7P_cjs.group({ class: "sx-seq-messages" }, layout.messages.map(renderMessage)));
|
|
19894
|
+
body.push(chunk3WNW5Y7P_cjs.group({ class: "sx-seq-notes" }, layout.notes.map(renderNote2)));
|
|
19895
|
+
body.push(chunk3WNW5Y7P_cjs.group({ class: "sx-seq-divs" }, layout.dividers.map(renderDivider)));
|
|
19896
|
+
body.push(chunk3WNW5Y7P_cjs.group({ class: "sx-seq-invs" }, layout.invariants.map(renderInvariant)));
|
|
19897
|
+
body.push(chunk3WNW5Y7P_cjs.group({ class: "sx-seq-destroys" }, layout.destroys.map(renderDestroy)));
|
|
19898
|
+
children.push(
|
|
19899
|
+
titleBand ? chunk3WNW5Y7P_cjs.group({ transform: `translate(0, ${titleBand})` }, body) : chunk3WNW5Y7P_cjs.group({}, body)
|
|
19900
|
+
);
|
|
19901
|
+
const height = layout.height + titleBand;
|
|
19902
|
+
return chunk3WNW5Y7P_cjs.svgRoot(
|
|
19903
|
+
{
|
|
19904
|
+
class: "sx-seq",
|
|
19905
|
+
role: "img",
|
|
19906
|
+
"aria-label": chunk3WNW5Y7P_cjs.escapeXml(layout.title ?? "UML sequence diagram"),
|
|
19907
|
+
width: layout.width,
|
|
19908
|
+
height,
|
|
19909
|
+
viewBox: `0 0 ${layout.width} ${height}`,
|
|
19910
|
+
"data-diagram-type": "sequence"
|
|
19911
|
+
},
|
|
19912
|
+
children
|
|
19913
|
+
);
|
|
19914
|
+
}
|
|
19915
|
+
function renderSequence(textOrAst, config) {
|
|
19916
|
+
const ast = typeof textOrAst === "string" ? parseSequence(textOrAst) : textOrAst;
|
|
19917
|
+
const layout = layoutSequence(ast);
|
|
19918
|
+
return renderSequenceLayout(layout, config);
|
|
19919
|
+
}
|
|
19920
|
+
|
|
19921
|
+
// src/diagrams/sequence/index.ts
|
|
19922
|
+
var sequence = {
|
|
19923
|
+
type: "sequence",
|
|
19924
|
+
detect(text2) {
|
|
19925
|
+
for (const raw of text2.split(/\r?\n/)) {
|
|
19926
|
+
const t = raw.trim();
|
|
19927
|
+
if (!t) continue;
|
|
19928
|
+
if (t.startsWith("#") || t.startsWith("//")) continue;
|
|
19929
|
+
return /^sequence\b/i.test(t);
|
|
19930
|
+
}
|
|
19931
|
+
return false;
|
|
19932
|
+
},
|
|
19933
|
+
parse: parseSequence,
|
|
19934
|
+
render(text2, config) {
|
|
19935
|
+
return renderSequence(text2, config);
|
|
19936
|
+
}
|
|
19937
|
+
};
|
|
19938
|
+
|
|
18618
19939
|
// src/core/api.ts
|
|
18619
19940
|
var plugins = [
|
|
18620
19941
|
chunkTZTCIAYW_cjs.genogram,
|
|
@@ -18624,7 +19945,7 @@ var plugins = [
|
|
|
18624
19945
|
chunkUUBNQV2T_cjs.sociogram,
|
|
18625
19946
|
chunkST5YRTTV_cjs.timing,
|
|
18626
19947
|
chunkYLEVMOK2_cjs.logic,
|
|
18627
|
-
|
|
19948
|
+
chunkQMTWG6JL_cjs.circuit,
|
|
18628
19949
|
chunkSUIDD2C5_cjs.blockdiagram,
|
|
18629
19950
|
chunkN7W5KZK7_cjs.ladder,
|
|
18630
19951
|
chunk3M6WB62Y_cjs.sld,
|
|
@@ -18646,7 +19967,8 @@ var plugins = [
|
|
|
18646
19967
|
sfc,
|
|
18647
19968
|
prisma,
|
|
18648
19969
|
usecase,
|
|
18649
|
-
pert
|
|
19970
|
+
pert,
|
|
19971
|
+
sequence
|
|
18650
19972
|
];
|
|
18651
19973
|
function detectPlugin(text2, config) {
|
|
18652
19974
|
if (config?.type) {
|
|
@@ -18657,7 +19979,7 @@ function detectPlugin(text2, config) {
|
|
|
18657
19979
|
if (plugin.detect(text2)) return plugin;
|
|
18658
19980
|
}
|
|
18659
19981
|
throw new Error(
|
|
18660
|
-
"Cannot detect diagram type. Start your text with 'genogram', 'ecomap', 'pedigree', 'phylo', 'sociogram', 'timing', 'logic', 'circuit', 'blockdiagram', 'ladder', 'sld', 'entity-structure', 'fishbone', 'venn', 'flowchart', 'mindmap', 'matrix', 'orgchart', 'state', 'pid', 'erd', 'breadboard', 'bpmn', 'fbd', 'sfc', 'prisma', 'usecase', or '
|
|
19982
|
+
"Cannot detect diagram type. Start your text with 'genogram', 'ecomap', 'pedigree', 'phylo', 'sociogram', 'timing', 'logic', 'circuit', 'blockdiagram', 'ladder', 'sld', 'entity-structure', 'fishbone', 'venn', 'flowchart', 'mindmap', 'matrix', 'orgchart', 'state', 'pid', 'erd', 'breadboard', 'bpmn', 'fbd', 'sfc', 'prisma', 'usecase', 'pert', or 'sequence'."
|
|
18661
19983
|
);
|
|
18662
19984
|
}
|
|
18663
19985
|
function preprocess8(text2) {
|
|
@@ -18682,9 +20004,68 @@ function parse(text2, config) {
|
|
|
18682
20004
|
`Diagram type '${plugin.type}' does not yet expose a parse() method.`
|
|
18683
20005
|
);
|
|
18684
20006
|
}
|
|
20007
|
+
function parseResult(text2, config) {
|
|
20008
|
+
let plugin;
|
|
20009
|
+
try {
|
|
20010
|
+
const prepared = preprocess8(text2);
|
|
20011
|
+
plugin = detectPlugin(prepared, config);
|
|
20012
|
+
if (!plugin.parse) {
|
|
20013
|
+
throw new Error(
|
|
20014
|
+
`Diagram type '${plugin.type}' does not yet expose a parse() method.`
|
|
20015
|
+
);
|
|
20016
|
+
}
|
|
20017
|
+
return {
|
|
20018
|
+
ok: true,
|
|
20019
|
+
status: "valid",
|
|
20020
|
+
type: plugin.type,
|
|
20021
|
+
ast: plugin.parse(prepared),
|
|
20022
|
+
diagnostics: []
|
|
20023
|
+
};
|
|
20024
|
+
} catch (err) {
|
|
20025
|
+
return {
|
|
20026
|
+
ok: false,
|
|
20027
|
+
status: "invalid",
|
|
20028
|
+
type: plugin?.type ?? config?.type ?? null,
|
|
20029
|
+
diagnostics: [diagnosticFromError(err)]
|
|
20030
|
+
};
|
|
20031
|
+
}
|
|
20032
|
+
}
|
|
18685
20033
|
function render(text2, config) {
|
|
20034
|
+
if (config?.mode === "preview") return renderResult(text2, config).svg;
|
|
18686
20035
|
const prepared = preprocess8(text2);
|
|
18687
20036
|
const plugin = detectPlugin(prepared, config);
|
|
20037
|
+
return renderWithPlugin(prepared, plugin, config);
|
|
20038
|
+
}
|
|
20039
|
+
function renderResult(text2, config) {
|
|
20040
|
+
let plugin;
|
|
20041
|
+
try {
|
|
20042
|
+
const prepared = preprocess8(text2);
|
|
20043
|
+
plugin = detectPlugin(prepared, config);
|
|
20044
|
+
return {
|
|
20045
|
+
ok: true,
|
|
20046
|
+
status: "valid",
|
|
20047
|
+
type: plugin.type,
|
|
20048
|
+
svg: renderWithPlugin(prepared, plugin, config),
|
|
20049
|
+
diagnostics: []
|
|
20050
|
+
};
|
|
20051
|
+
} catch (err) {
|
|
20052
|
+
const type = plugin?.type ?? config?.type ?? null;
|
|
20053
|
+
const diagnostics = [diagnosticFromError(err)];
|
|
20054
|
+
return {
|
|
20055
|
+
ok: false,
|
|
20056
|
+
status: "invalid",
|
|
20057
|
+
type,
|
|
20058
|
+
svg: renderDiagnosticSvg(diagnostics, type, {
|
|
20059
|
+
fontFamily: config?.fontFamily
|
|
20060
|
+
}),
|
|
20061
|
+
diagnostics
|
|
20062
|
+
};
|
|
20063
|
+
}
|
|
20064
|
+
}
|
|
20065
|
+
function renderPreview(text2, config) {
|
|
20066
|
+
return renderResult(text2, config).svg;
|
|
20067
|
+
}
|
|
20068
|
+
function renderWithPlugin(prepared, plugin, config) {
|
|
18688
20069
|
const renderConfig = {
|
|
18689
20070
|
fontFamily: config?.fontFamily ?? "system-ui, -apple-system, sans-serif",
|
|
18690
20071
|
fontSize: 12,
|
|
@@ -18696,12 +20077,15 @@ function render(text2, config) {
|
|
|
18696
20077
|
|
|
18697
20078
|
exports.decisiontree = decisiontree;
|
|
18698
20079
|
exports.parse = parse;
|
|
20080
|
+
exports.parseResult = parseResult;
|
|
18699
20081
|
exports.pert = pert;
|
|
18700
20082
|
exports.pid = pid;
|
|
18701
20083
|
exports.prisma = prisma;
|
|
18702
20084
|
exports.render = render;
|
|
20085
|
+
exports.renderPreview = renderPreview;
|
|
20086
|
+
exports.renderResult = renderResult;
|
|
18703
20087
|
exports.state = state;
|
|
18704
20088
|
exports.timeline = timeline;
|
|
18705
20089
|
exports.usecase = usecase;
|
|
18706
|
-
//# sourceMappingURL=chunk-
|
|
18707
|
-
//# sourceMappingURL=chunk-
|
|
20090
|
+
//# sourceMappingURL=chunk-4QPDZJAL.cjs.map
|
|
20091
|
+
//# sourceMappingURL=chunk-4QPDZJAL.cjs.map
|