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.
Files changed (90) hide show
  1. package/README.md +15 -7
  2. package/dist/ai/ai-sdk.cjs +18 -12
  3. package/dist/ai/ai-sdk.cjs.map +1 -1
  4. package/dist/ai/ai-sdk.d.cts +4 -3
  5. package/dist/ai/ai-sdk.d.ts +4 -3
  6. package/dist/ai/ai-sdk.js +14 -8
  7. package/dist/ai/ai-sdk.js.map +1 -1
  8. package/dist/ai/index.cjs +15 -11
  9. package/dist/ai/index.d.cts +20 -153
  10. package/dist/ai/index.d.ts +20 -153
  11. package/dist/ai/index.js +3 -3
  12. package/dist/api-C5SECOxZ.d.cts +69 -0
  13. package/dist/api-Cr_MxttI.d.ts +69 -0
  14. package/dist/browser.cjs +23 -5
  15. package/dist/browser.cjs.map +1 -1
  16. package/dist/browser.d.cts +12 -3
  17. package/dist/browser.d.ts +12 -3
  18. package/dist/browser.js +13 -5
  19. package/dist/browser.js.map +1 -1
  20. package/dist/{chunk-3YUUC6RN.cjs → chunk-4QPDZJAL.cjs} +1421 -37
  21. package/dist/chunk-4QPDZJAL.cjs.map +1 -0
  22. package/dist/{chunk-NWPCY65Z.cjs → chunk-HK56GQQP.cjs} +544 -61
  23. package/dist/chunk-HK56GQQP.cjs.map +1 -0
  24. package/dist/{chunk-GTDQAN2Z.js → chunk-OK5ZS3LU.js} +1419 -38
  25. package/dist/chunk-OK5ZS3LU.js.map +1 -0
  26. package/dist/{chunk-XRCY75UV.cjs → chunk-QMTWG6JL.cjs} +947 -916
  27. package/dist/chunk-QMTWG6JL.cjs.map +1 -0
  28. package/dist/{chunk-HUPDIRBX.js → chunk-VCH7RI5H.js} +947 -916
  29. package/dist/chunk-VCH7RI5H.js.map +1 -0
  30. package/dist/{chunk-IM4RCUHA.js → chunk-VKPCR7BG.js} +544 -62
  31. package/dist/chunk-VKPCR7BG.js.map +1 -0
  32. package/dist/diagrams/blockdiagram/index.d.cts +1 -1
  33. package/dist/diagrams/blockdiagram/index.d.ts +1 -1
  34. package/dist/diagrams/circuit/index.cjs +7 -7
  35. package/dist/diagrams/circuit/index.d.cts +1 -1
  36. package/dist/diagrams/circuit/index.d.ts +1 -1
  37. package/dist/diagrams/circuit/index.js +1 -1
  38. package/dist/diagrams/ecomap/index.d.cts +1 -1
  39. package/dist/diagrams/ecomap/index.d.ts +1 -1
  40. package/dist/diagrams/entity/index.d.cts +1 -1
  41. package/dist/diagrams/entity/index.d.ts +1 -1
  42. package/dist/diagrams/fishbone/index.d.cts +1 -1
  43. package/dist/diagrams/fishbone/index.d.ts +1 -1
  44. package/dist/diagrams/flowchart/index.d.cts +2 -2
  45. package/dist/diagrams/flowchart/index.d.ts +2 -2
  46. package/dist/diagrams/genogram/index.d.cts +1 -1
  47. package/dist/diagrams/genogram/index.d.ts +1 -1
  48. package/dist/diagrams/ladder/index.d.cts +1 -1
  49. package/dist/diagrams/ladder/index.d.ts +1 -1
  50. package/dist/diagrams/logic/index.d.cts +1 -1
  51. package/dist/diagrams/logic/index.d.ts +1 -1
  52. package/dist/diagrams/orgchart/index.d.cts +1 -1
  53. package/dist/diagrams/orgchart/index.d.ts +1 -1
  54. package/dist/diagrams/pedigree/index.d.cts +1 -1
  55. package/dist/diagrams/pedigree/index.d.ts +1 -1
  56. package/dist/diagrams/phylo/index.d.cts +1 -1
  57. package/dist/diagrams/phylo/index.d.ts +1 -1
  58. package/dist/diagrams/sld/index.d.cts +1 -1
  59. package/dist/diagrams/sld/index.d.ts +1 -1
  60. package/dist/diagrams/sociogram/index.d.cts +1 -1
  61. package/dist/diagrams/sociogram/index.d.ts +1 -1
  62. package/dist/diagrams/timing/index.d.cts +1 -1
  63. package/dist/diagrams/timing/index.d.ts +1 -1
  64. package/dist/diagrams/venn/index.d.cts +1 -1
  65. package/dist/diagrams/venn/index.d.ts +1 -1
  66. package/dist/{index-C9A0h-CB.d.cts → index-BD2yDfQM.d.cts} +1 -1
  67. package/dist/{index-CJai_TEZ.d.ts → index-C30zQWZI.d.ts} +1 -1
  68. package/dist/index.cjs +24 -12
  69. package/dist/index.d.cts +3 -3
  70. package/dist/index.d.ts +3 -3
  71. package/dist/index.js +2 -2
  72. package/dist/react.cjs +7 -9
  73. package/dist/react.cjs.map +1 -1
  74. package/dist/react.d.cts +3 -2
  75. package/dist/react.d.ts +3 -2
  76. package/dist/react.js +7 -9
  77. package/dist/react.js.map +1 -1
  78. package/dist/tools-BHWaJPOl.d.ts +153 -0
  79. package/dist/tools-DlpuE76u.d.cts +153 -0
  80. package/dist/{types-BOAsqHoU.d.cts → types-WTr9W5Ud.d.cts} +2 -2
  81. package/dist/{types-BOAsqHoU.d.ts → types-WTr9W5Ud.d.ts} +2 -2
  82. package/package.json +2 -2
  83. package/dist/api-C5UcmT7n.d.cts +0 -22
  84. package/dist/api-C5UcmT7n.d.ts +0 -22
  85. package/dist/chunk-3YUUC6RN.cjs.map +0 -1
  86. package/dist/chunk-GTDQAN2Z.js.map +0 -1
  87. package/dist/chunk-HUPDIRBX.js.map +0 -1
  88. package/dist/chunk-IM4RCUHA.js.map +0 -1
  89. package/dist/chunk-NWPCY65Z.cjs.map +0 -1
  90. 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 chunkXRCY75UV_cjs = require('./chunk-XRCY75UV.cjs');
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 = stripQuotes(valueRaw);
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 stripQuotes(s) {
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 = stripQuotes(rest);
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 = stripQuotes(rest);
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 arrowKind = "none";
8036
- if (r.kind === "directed" || r.kind === "include" || r.kind === "extend") arrowKind = "open";
8037
- else if (r.kind === "generalization") arrowKind = "hollow";
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 stripQuotes2(s) {
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 = stripQuotes2(valueRaw);
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 markers3 = [];
8671
+ const markers4 = [];
8672
8672
  KEY_RE.lastIndex = 0;
8673
8673
  let mm;
8674
8674
  while ((mm = KEY_RE.exec(rest)) !== null) {
8675
- markers3.push({ key: mm[1].toLowerCase(), start: mm.index, valStart: mm.index + mm[0].length });
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 < markers3.length; i++) {
8679
- const cur = markers3[i];
8680
- const nextStart = i + 1 < markers3.length ? markers3[i + 1].start : rest.length;
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 = (markers3.length ? rest.slice(0, markers3[0].start) : rest).trim();
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 ? stripQuotes2(values.lane) : void 0;
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 stripQuotes3(s) {
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) => stripQuotes3(s.trim())).filter((s) => s.length > 0);
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 = stripQuotes3(title2);
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 = stripQuotes3(title2);
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 = stripQuotes3(remainder);
11559
+ if (remainder) ast.title = stripQuotes4(remainder);
11411
11560
  return tok;
11412
11561
  }
11413
11562
  if (rest.startsWith('"') || rest.startsWith("'")) {
11414
- ast.title = stripQuotes3(rest);
11563
+ ast.title = stripQuotes4(rest);
11415
11564
  } else if (rest.length > 0) {
11416
- ast.title = stripQuotes3(rest);
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 = stripQuotes3(line2.replace(/^title\s*:\s*/i, ""));
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 = stripQuotes3(labelRaw);
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 markers3 = attrMarkers(a);
13574
+ const markers4 = attrMarkers(a);
13426
13575
  const markerW = 26;
13427
13576
  const markerGap = 4;
13428
- const markersBlockW = markers3.length * markerW + (markers3.length - 1) * markerGap;
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 < markers3.length; j++) {
13444
- const m = markers3[j];
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
- chunkXRCY75UV_cjs.circuit,
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 'pert'."
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-3YUUC6RN.cjs.map
18707
- //# sourceMappingURL=chunk-3YUUC6RN.cjs.map
20090
+ //# sourceMappingURL=chunk-4QPDZJAL.cjs.map
20091
+ //# sourceMappingURL=chunk-4QPDZJAL.cjs.map