@diagrammo/dgmo 0.15.1 → 0.17.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (122) hide show
  1. package/README.md +9 -9
  2. package/dist/advanced.cjs +612 -734
  3. package/dist/advanced.d.cts +42 -36
  4. package/dist/advanced.d.ts +42 -36
  5. package/dist/advanced.js +612 -733
  6. package/dist/auto.cjs +508 -620
  7. package/dist/auto.js +105 -105
  8. package/dist/auto.mjs +508 -620
  9. package/dist/cli.cjs +144 -144
  10. package/dist/editor.cjs +8 -9
  11. package/dist/editor.js +8 -9
  12. package/dist/highlight.cjs +8 -9
  13. package/dist/highlight.js +8 -9
  14. package/dist/index.cjs +497 -608
  15. package/dist/index.js +497 -608
  16. package/dist/internal.cjs +612 -734
  17. package/dist/internal.d.cts +42 -36
  18. package/dist/internal.d.ts +42 -36
  19. package/dist/internal.js +612 -733
  20. package/dist/pert.d.cts +2 -2
  21. package/dist/pert.d.ts +2 -2
  22. package/docs/language-reference.md +97 -84
  23. package/docs/migration-sequence-color-to-tags.md +1 -1
  24. package/gallery/fixtures/area.dgmo +3 -3
  25. package/gallery/fixtures/bar-stacked.dgmo +5 -5
  26. package/gallery/fixtures/boxes-and-lines.dgmo +2 -2
  27. package/gallery/fixtures/c4-full.dgmo +8 -8
  28. package/gallery/fixtures/class-full.dgmo +2 -2
  29. package/gallery/fixtures/doughnut.dgmo +6 -6
  30. package/gallery/fixtures/flowchart-colors.dgmo +3 -3
  31. package/gallery/fixtures/function.dgmo +3 -3
  32. package/gallery/fixtures/gantt-full.dgmo +9 -9
  33. package/gallery/fixtures/gantt.dgmo +7 -7
  34. package/gallery/fixtures/infra-full.dgmo +6 -6
  35. package/gallery/fixtures/infra.dgmo +2 -2
  36. package/gallery/fixtures/kanban.dgmo +9 -9
  37. package/gallery/fixtures/line.dgmo +2 -2
  38. package/gallery/fixtures/multi-line.dgmo +3 -3
  39. package/gallery/fixtures/org-full.dgmo +6 -6
  40. package/gallery/fixtures/quadrant.dgmo +2 -2
  41. package/gallery/fixtures/sankey.dgmo +9 -9
  42. package/gallery/fixtures/scatter.dgmo +3 -3
  43. package/gallery/fixtures/sequence-tags-protocols.dgmo +11 -11
  44. package/gallery/fixtures/sequence-tags.dgmo +10 -10
  45. package/gallery/fixtures/sequence.dgmo +4 -4
  46. package/gallery/fixtures/sitemap-full.dgmo +7 -7
  47. package/gallery/fixtures/slope.dgmo +5 -5
  48. package/gallery/fixtures/spr-eras.dgmo +9 -9
  49. package/gallery/fixtures/timeline.dgmo +3 -3
  50. package/gallery/fixtures/venn.dgmo +3 -3
  51. package/package.json +7 -3
  52. package/src/advanced.ts +0 -1
  53. package/src/auto/index.ts +2 -2
  54. package/src/boxes-and-lines/layout.ts +1 -2
  55. package/src/boxes-and-lines/renderer.ts +5 -1
  56. package/src/c4/parser.ts +2 -2
  57. package/src/c4/renderer.ts +15 -8
  58. package/src/chart.ts +18 -9
  59. package/src/class/parser.ts +8 -7
  60. package/src/class/renderer.ts +17 -6
  61. package/src/cli.ts +8 -8
  62. package/src/completion.ts +14 -17
  63. package/src/cycle/parser.ts +15 -1
  64. package/src/cycle/renderer.ts +6 -3
  65. package/src/d3.ts +88 -49
  66. package/src/diagnostics.ts +20 -0
  67. package/src/echarts.ts +28 -11
  68. package/src/editor/dgmo.grammar +1 -3
  69. package/src/editor/dgmo.grammar.d.ts +1 -1
  70. package/src/editor/dgmo.grammar.js +8 -8
  71. package/src/editor/dgmo.grammar.terms.js +11 -12
  72. package/src/editor/highlight-api.ts +0 -1
  73. package/src/editor/highlight.ts +0 -1
  74. package/src/er/parser.ts +19 -12
  75. package/src/er/renderer.ts +19 -7
  76. package/src/gantt/parser.ts +1 -1
  77. package/src/gantt/renderer.ts +7 -4
  78. package/src/graph/flowchart-parser.ts +18 -84
  79. package/src/graph/flowchart-renderer.ts +6 -8
  80. package/src/graph/layout.ts +0 -2
  81. package/src/graph/state-parser.ts +17 -62
  82. package/src/graph/state-renderer.ts +3 -8
  83. package/src/infra/parser.ts +21 -11
  84. package/src/infra/renderer.ts +8 -6
  85. package/src/journey-map/parser.ts +11 -4
  86. package/src/journey-map/renderer.ts +3 -1
  87. package/src/kanban/parser.ts +11 -7
  88. package/src/kanban/renderer.ts +3 -1
  89. package/src/mindmap/parser.ts +4 -5
  90. package/src/mindmap/renderer.ts +2 -1
  91. package/src/org/parser.ts +3 -3
  92. package/src/org/renderer.ts +4 -3
  93. package/src/pert/analyzer.ts +10 -10
  94. package/src/pert/layout.ts +1 -1
  95. package/src/pert/parser.ts +8 -8
  96. package/src/pert/renderer.ts +7 -2
  97. package/src/pert/types.ts +1 -1
  98. package/src/pyramid/parser.ts +13 -1
  99. package/src/raci/parser.ts +42 -12
  100. package/src/raci/renderer.ts +2 -1
  101. package/src/raci/types.ts +4 -3
  102. package/src/ring/parser.ts +13 -1
  103. package/src/sequence/parser.ts +81 -23
  104. package/src/sequence/participant-inference.ts +18 -181
  105. package/src/sequence/renderer.ts +48 -137
  106. package/src/sitemap/layout.ts +0 -2
  107. package/src/sitemap/parser.ts +12 -38
  108. package/src/sitemap/renderer.ts +13 -13
  109. package/src/sitemap/types.ts +0 -1
  110. package/src/tech-radar/parser.ts +2 -2
  111. package/src/tech-radar/renderer.ts +5 -3
  112. package/src/tech-radar/types.ts +2 -0
  113. package/src/utils/arrows.ts +3 -28
  114. package/src/utils/extract-alias.ts +1 -1
  115. package/src/utils/inline-markdown.ts +1 -1
  116. package/src/utils/legend-d3.ts +12 -6
  117. package/src/utils/legend-layout.ts +1 -1
  118. package/src/utils/legend-types.ts +1 -1
  119. package/src/utils/parsing.ts +64 -35
  120. package/src/utils/tag-groups.ts +98 -18
  121. package/src/utils/time-ticks.ts +1 -1
  122. package/src/wireframe/parser.ts +3 -3
package/dist/index.cjs CHANGED
@@ -418,6 +418,9 @@ function nameMergedMessage(args) {
418
418
  function akaRemovedMessage() {
419
419
  return `'aka' is no longer supported \u2014 use the participant name directly`;
420
420
  }
421
+ function participantTypeRemovedMessage(type) {
422
+ return `'${type}' is no longer supported \u2014 drop 'is a ${type}'; the participant renders as the default rectangle`;
423
+ }
421
424
  function tagShorthandRemovedMessage(args) {
422
425
  return `Bare tag shorthand 'tag ${args.name} ${args.alias}' was removed. Use 'tag ${args.name} as ${args.alias}' instead.`;
423
426
  }
@@ -451,7 +454,15 @@ var init_diagnostics = __esm({
451
454
  * participant declaration. Forgiving normalization makes aliasing
452
455
  * unnecessary; the diagnostic directs users to the new syntax.
453
456
  */
454
- AKA_REMOVED: "E_AKA_REMOVED"
457
+ AKA_REMOVED: "E_AKA_REMOVED",
458
+ /**
459
+ * Error: a removed sequence participant-type keyword was used in
460
+ * an `is a X` declaration. The 0.16.0 trim retained only
461
+ * `actor`/`database`/`cache`/`queue`; `service`/`frontend`/
462
+ * `networking`/`gateway`/`external` no longer carry semantic
463
+ * weight and emit this error so users drop the override.
464
+ */
465
+ PARTICIPANT_TYPE_REMOVED: "E_PARTICIPANT_TYPE_REMOVED"
455
466
  };
456
467
  ALIAS_DIAGNOSTIC_CODES = {
457
468
  /** Alias token used before its declaration (strict-ordering rule). */
@@ -1822,17 +1833,21 @@ function measureIndent(line12) {
1822
1833
  return indent;
1823
1834
  }
1824
1835
  function extractColor(label, palette, diagnostics, line12) {
1825
- const m = label.match(COLOR_SUFFIX_RE);
1826
- if (!m) return { label };
1827
- const colorName = m[1].trim();
1836
+ const lastSpaceIdx = Math.max(
1837
+ label.lastIndexOf(" "),
1838
+ label.lastIndexOf(" ")
1839
+ );
1840
+ if (lastSpaceIdx < 0) return { label };
1841
+ const trailing = label.substring(lastSpaceIdx + 1);
1842
+ if (!RECOGNIZED_COLOR_SET.has(trailing)) return { label };
1828
1843
  let color;
1829
1844
  if (diagnostics && line12 !== void 0) {
1830
- color = resolveColorWithDiagnostic(colorName, line12, diagnostics, palette);
1845
+ color = resolveColorWithDiagnostic(trailing, line12, diagnostics, palette);
1831
1846
  } else {
1832
- color = resolveColor(colorName, palette) ?? void 0;
1847
+ color = resolveColor(trailing, palette) ?? void 0;
1833
1848
  }
1834
1849
  return {
1835
- label: label.substring(0, m.index).trim(),
1850
+ label: label.substring(0, lastSpaceIdx).trimEnd(),
1836
1851
  color
1837
1852
  };
1838
1853
  }
@@ -1965,14 +1980,18 @@ function parseSeriesNames(value, lines, lineIndex, palette, diagnostics) {
1965
1980
  }
1966
1981
  return { series, names, nameColors, nameLineNumbers, newIndex };
1967
1982
  }
1968
- function inferArrowColor(label) {
1969
- const lower = label.toLowerCase();
1970
- if (lower === "yes" || lower === "success" || lower === "ok" || lower === "true")
1971
- return "green";
1972
- if (lower === "no" || lower === "fail" || lower === "error" || lower === "false")
1973
- return "red";
1974
- if (lower === "maybe" || lower === "warning") return "orange";
1975
- return void 0;
1983
+ function peelTrailingColorName(label) {
1984
+ const lastSpaceIdx = Math.max(
1985
+ label.lastIndexOf(" "),
1986
+ label.lastIndexOf(" ")
1987
+ );
1988
+ if (lastSpaceIdx < 0) return { label };
1989
+ const trailing = label.substring(lastSpaceIdx + 1);
1990
+ if (!RECOGNIZED_COLOR_SET.has(trailing)) return { label };
1991
+ return {
1992
+ label: label.substring(0, lastSpaceIdx).trimEnd(),
1993
+ colorName: trailing
1994
+ };
1976
1995
  }
1977
1996
  function parsePipeMetadata(segments, aliasMap = /* @__PURE__ */ new Map(), errorMultiplePipes) {
1978
1997
  if (segments.length > 2) {
@@ -1994,11 +2013,14 @@ function parsePipeMetadata(segments, aliasMap = /* @__PURE__ */ new Map(), error
1994
2013
  }
1995
2014
  return metadata;
1996
2015
  }
1997
- var ALL_CHART_TYPES, PIPE_KEY_VALUE_PREFIX_RE, PIPE_LIKELY_STRUCTURED_TAIL_RE, COLOR_SUFFIX_RE, OPTION_NOCOLON_RE, GLOBAL_BOOLEANS, MULTIPLE_PIPE_ERROR;
2016
+ var RECOGNIZED_COLOR_SET, ALL_CHART_TYPES, PIPE_KEY_VALUE_PREFIX_RE, PIPE_LIKELY_STRUCTURED_TAIL_RE, OPTION_NOCOLON_RE, GLOBAL_BOOLEANS, MULTIPLE_PIPE_ERROR;
1998
2017
  var init_parsing = __esm({
1999
2018
  "src/utils/parsing.ts"() {
2000
2019
  "use strict";
2001
2020
  init_colors();
2021
+ RECOGNIZED_COLOR_SET = new Set(
2022
+ RECOGNIZED_COLOR_NAMES
2023
+ );
2002
2024
  ALL_CHART_TYPES = /* @__PURE__ */ new Set([
2003
2025
  // data charts
2004
2026
  "bar",
@@ -2050,7 +2072,6 @@ var init_parsing = __esm({
2050
2072
  ]);
2051
2073
  PIPE_KEY_VALUE_PREFIX_RE = /^\s*[A-Za-z][A-Za-z0-9_-]*\s*:/;
2052
2074
  PIPE_LIKELY_STRUCTURED_TAIL_RE = /,\s*[A-Za-z][A-Za-z0-9_-]*\s*:/;
2053
- COLOR_SUFFIX_RE = /\(([^)]+)\)\s*$/;
2054
2075
  OPTION_NOCOLON_RE = /^([a-z][a-z0-9-]*)\s+(.+)$/i;
2055
2076
  GLOBAL_BOOLEANS = /* @__PURE__ */ new Set([
2056
2077
  "solid-fill",
@@ -2087,7 +2108,7 @@ function parseTagDeclaration(line12) {
2087
2108
  let restStartIdx = 1;
2088
2109
  let valueStart = tokens.length;
2089
2110
  for (let i = 1; i < tokens.length; i++) {
2090
- if (tokens[i].includes("(")) {
2111
+ if (tokens[i].includes(",")) {
2091
2112
  valueStart = i;
2092
2113
  break;
2093
2114
  }
@@ -2119,13 +2140,29 @@ function parseTagDeclaration(line12) {
2119
2140
  restStartIdx = valueStart;
2120
2141
  }
2121
2142
  } else {
2122
- if (tokens[0][0] === '"' || tokens[0][0] === "'") {
2123
- if (tokens.length > 1 && isAliasToken(tokens[1]) && valueStart > 1) {
2143
+ const isColorWord = (s) => RECOGNIZED_COLOR_NAMES.includes(s);
2144
+ if (valueStart < tokens.length) {
2145
+ const commaTokenIdx = valueStart;
2146
+ const lastBeforeComma = tokens[commaTokenIdx].replace(/,$/, "");
2147
+ const firstValueStart = isColorWord(lastBeforeComma) ? commaTokenIdx - 1 : commaTokenIdx;
2148
+ const prefixEnd = firstValueStart;
2149
+ const aliasCandidate = prefixEnd > 1 ? tokens[prefixEnd - 1] : void 0;
2150
+ if (aliasCandidate && isAliasToken(aliasCandidate) && !isColorWord(aliasCandidate)) {
2151
+ alias = aliasCandidate;
2152
+ legacyForm = "bare-shorthand";
2153
+ name = tokens.slice(0, prefixEnd - 1).map((t) => stripQuotes(t)).join(" ");
2154
+ restStartIdx = prefixEnd;
2155
+ } else {
2156
+ name = tokens.slice(0, prefixEnd).map((t) => stripQuotes(t)).join(" ");
2157
+ restStartIdx = prefixEnd;
2158
+ }
2159
+ } else if (tokens[0][0] === '"' || tokens[0][0] === "'") {
2160
+ if (tokens.length > 1 && isAliasToken(tokens[1]) && !isColorWord(tokens[1])) {
2124
2161
  alias = tokens[1];
2125
2162
  legacyForm = "bare-shorthand";
2126
2163
  restStartIdx = 2;
2127
2164
  }
2128
- } else if (valueStart > 1 && isAliasToken(tokens[valueStart - 1])) {
2165
+ } else if (valueStart > 1 && isAliasToken(tokens[valueStart - 1]) && !isColorWord(tokens[valueStart - 1])) {
2129
2166
  alias = tokens[valueStart - 1];
2130
2167
  legacyForm = "bare-shorthand";
2131
2168
  name = tokens.slice(0, valueStart - 1).map((t) => stripQuotes(t)).join(" ");
@@ -2140,10 +2177,13 @@ function parseTagDeclaration(line12) {
2140
2177
  inlineValues = valueStr.split(",").map((v) => v.trim()).filter(Boolean);
2141
2178
  }
2142
2179
  if (!inlineValues || inlineValues.length === 0) {
2143
- const colorMatch = name.match(/\(([^)]+)\)\s*$/);
2144
- if (colorMatch) {
2145
- colorHint = colorMatch[1];
2146
- name = name.substring(0, colorMatch.index).trim();
2180
+ const lastSpaceIdx = name.lastIndexOf(" ");
2181
+ if (lastSpaceIdx > 0) {
2182
+ const trailing = name.substring(lastSpaceIdx + 1);
2183
+ if (RECOGNIZED_COLOR_NAMES.includes(trailing)) {
2184
+ colorHint = trailing;
2185
+ name = name.substring(0, lastSpaceIdx).trimEnd();
2186
+ }
2147
2187
  }
2148
2188
  }
2149
2189
  return {
@@ -2271,6 +2311,7 @@ var init_tag_groups = __esm({
2271
2311
  "use strict";
2272
2312
  init_parsing();
2273
2313
  init_diagnostics();
2314
+ init_colors();
2274
2315
  TAG_BLOCK_NOCOLON_RE = /^tag\s+/i;
2275
2316
  VALID_TAG_IDENT_RE = /^[A-Za-z_][A-Za-z0-9_-]*$/;
2276
2317
  }
@@ -2544,7 +2585,7 @@ function buildControlsGroupLayout(config, state) {
2544
2585
  }
2545
2586
  function computeLegendLayout(config, state, containerWidth) {
2546
2587
  const { groups, controls: configControls, mode } = config;
2547
- const isExport = mode === "inline";
2588
+ const isExport = mode === "export";
2548
2589
  const activeGroupName = state.activeGroup?.toLowerCase() ?? null;
2549
2590
  if (isExport && !activeGroupName) {
2550
2591
  return {
@@ -2830,7 +2871,10 @@ function renderLegendD3(container, config, state, palette, isDark, callbacks, co
2830
2871
  const width = containerWidth ?? parseFloat(container.attr("width") || "800");
2831
2872
  let currentState = { ...state };
2832
2873
  let currentLayout;
2833
- const legendG = container.append("g").attr("class", "dgmo-legend");
2874
+ const legendG = container.append("g").attr("class", "dgmo-legend").attr("data-legend-title-relation", config.position.titleRelation).attr(
2875
+ "data-legend-capsule-addon-width",
2876
+ String(config.capsulePillAddonWidth ?? 0)
2877
+ );
2834
2878
  function render3() {
2835
2879
  currentLayout = computeLegendLayout(config, currentState, width);
2836
2880
  legendG.selectAll("*").remove();
@@ -3081,81 +3125,7 @@ var init_participant_inference = __esm({
3081
3125
  // Names that would incorrectly match general patterns in later groups
3082
3126
  { pattern: /^KeyDB$/i, type: "cache" },
3083
3127
  // not database (DB$ suffix)
3084
- { pattern: /Webhook/i, type: "external" },
3085
- // not frontend (Web contains)
3086
- { pattern: /^Upstream$/i, type: "external" },
3087
- // not queue (Stream$ suffix)
3088
- { pattern: /^Downstream$/i, type: "external" },
3089
- // not queue (Stream$ suffix)
3090
- // ── 1. Infrastructure overrides ─────────────────────────
3091
- // These names end in -er/-or but are NOT actors
3092
- { pattern: /^.*Router$/i, type: "networking" },
3093
- { pattern: /^.*Scheduler$/i, type: "service" },
3094
- { pattern: /^.*Dispatcher$/i, type: "service" },
3095
- { pattern: /^.*Balancer$/i, type: "networking" },
3096
- { pattern: /^.*Controller$/i, type: "service" },
3097
- { pattern: /^.*Handler$/i, type: "service" },
3098
- { pattern: /^.*Processor$/i, type: "service" },
3099
- { pattern: /^.*Connector$/i, type: "service" },
3100
- { pattern: /^.*Adapter$/i, type: "service" },
3101
- { pattern: /^.*Provider$/i, type: "service" },
3102
- { pattern: /^.*Manager$/i, type: "service" },
3103
- { pattern: /^.*Orchestrator$/i, type: "service" },
3104
- { pattern: /^.*Monitor$/i, type: "service" },
3105
- { pattern: /^.*Resolver$/i, type: "service" },
3106
- { pattern: /^.*Logger$/i, type: "service" },
3107
- { pattern: /^.*Server$/i, type: "service" },
3108
- { pattern: /^.*Broker$/i, type: "queue" },
3109
- { pattern: /^.*Worker$/i, type: "service" },
3110
- { pattern: /^.*Consumer$/i, type: "service" },
3111
- { pattern: /^.*Producer$/i, type: "service" },
3112
- { pattern: /^.*Publisher$/i, type: "service" },
3113
- { pattern: /^.*Subscriber$/i, type: "service" },
3114
- { pattern: /^.*Listener$/i, type: "service" },
3115
- // New -er/-or suffixes that are services, not actors
3116
- { pattern: /^.*Watcher$/i, type: "service" },
3117
- { pattern: /^.*Executor$/i, type: "service" },
3118
- { pattern: /^.*Aggregator$/i, type: "service" },
3119
- { pattern: /^.*Collector$/i, type: "service" },
3120
- { pattern: /^.*Transformer$/i, type: "service" },
3121
- { pattern: /^.*Validator$/i, type: "service" },
3122
- { pattern: /^.*Generator$/i, type: "service" },
3123
- { pattern: /^.*Indexer$/i, type: "service" },
3124
- { pattern: /^.*Crawler$/i, type: "service" },
3125
- { pattern: /^.*Scanner$/i, type: "service" },
3126
- { pattern: /^.*Parser$/i, type: "service" },
3127
- { pattern: /^.*Emitter$/i, type: "service" },
3128
- { pattern: /^.*Exporter$/i, type: "service" },
3129
- { pattern: /^.*Importer$/i, type: "service" },
3130
- { pattern: /^.*Loader$/i, type: "service" },
3131
- { pattern: /^.*Renderer$/i, type: "service" },
3132
- { pattern: /^.*Checker$/i, type: "service" },
3133
- { pattern: /^.*Inspector$/i, type: "service" },
3134
- { pattern: /^.*Encoder$/i, type: "service" },
3135
- { pattern: /^.*Decoder$/i, type: "service" },
3136
- { pattern: /^.*Notifier$/i, type: "service" },
3137
- // ── 2. Networking patterns ──────────────────────────────
3138
- { pattern: /Gateway/i, type: "networking" },
3139
- { pattern: /GW$/i, type: "networking" },
3140
- { pattern: /Proxy/i, type: "networking" },
3141
- { pattern: /LB$/i, type: "networking" },
3142
- { pattern: /LoadBalancer/i, type: "networking" },
3143
- { pattern: /CDN/i, type: "networking" },
3144
- { pattern: /Firewall/i, type: "networking" },
3145
- { pattern: /WAF$/i, type: "networking" },
3146
- { pattern: /DNS/i, type: "networking" },
3147
- { pattern: /Ingress/i, type: "networking" },
3148
- // Named products & patterns
3149
- { pattern: /Nginx/i, type: "networking" },
3150
- { pattern: /Traefik/i, type: "networking" },
3151
- { pattern: /Envoy/i, type: "networking" },
3152
- { pattern: /Istio/i, type: "networking" },
3153
- { pattern: /Kong/i, type: "networking" },
3154
- { pattern: /Akamai/i, type: "networking" },
3155
- { pattern: /Cloudflare/i, type: "networking" },
3156
- { pattern: /Mesh$/i, type: "networking" },
3157
- { pattern: /ServiceMesh/i, type: "networking" },
3158
- // ── 3. Database patterns ────────────────────────────────
3128
+ // ── 1. Database patterns ────────────────────────────────
3159
3129
  { pattern: /DB$/i, type: "database" },
3160
3130
  { pattern: /Database/i, type: "database" },
3161
3131
  { pattern: /Datastore/i, type: "database" },
@@ -3189,16 +3159,15 @@ var init_participant_inference = __esm({
3189
3159
  { pattern: /Milvus/i, type: "database" },
3190
3160
  { pattern: /Presto/i, type: "database" },
3191
3161
  { pattern: /Table$/i, type: "database" },
3192
- // ── 4. Cache patterns ──────────────────────────────────
3162
+ // ── 2. Cache patterns ──────────────────────────────────
3193
3163
  { pattern: /Cache/i, type: "cache" },
3194
3164
  { pattern: /Redis/i, type: "cache" },
3195
3165
  { pattern: /Memcache/i, type: "cache" },
3196
- // CDN already matched by networking above
3197
3166
  // Named products
3198
3167
  { pattern: /Dragonfly/i, type: "cache" },
3199
3168
  { pattern: /Hazelcast/i, type: "cache" },
3200
3169
  { pattern: /Valkey/i, type: "cache" },
3201
- // ── 5. Queue/Messaging patterns ─────────────────────────
3170
+ // ── 3. Queue/Messaging patterns ─────────────────────────
3202
3171
  { pattern: /Queue/i, type: "queue" },
3203
3172
  { pattern: /MQ$/i, type: "queue" },
3204
3173
  { pattern: /SQS/i, type: "queue" },
@@ -3211,6 +3180,7 @@ var init_participant_inference = __esm({
3211
3180
  { pattern: /Stream$/i, type: "queue" },
3212
3181
  { pattern: /SNS/i, type: "queue" },
3213
3182
  { pattern: /PubSub/i, type: "queue" },
3183
+ { pattern: /Broker$/i, type: "queue" },
3214
3184
  // Named products & patterns
3215
3185
  { pattern: /NATS/i, type: "queue" },
3216
3186
  { pattern: /Pulsar/i, type: "queue" },
@@ -3221,7 +3191,7 @@ var init_participant_inference = __esm({
3221
3191
  { pattern: /Sidekiq/i, type: "queue" },
3222
3192
  { pattern: /EventHub/i, type: "queue" },
3223
3193
  { pattern: /Channel$/i, type: "queue" },
3224
- // ── 6. Actor patterns ──────────────────────────────────
3194
+ // ── 4. Actor patterns ──────────────────────────────────
3225
3195
  // Exact matches first
3226
3196
  { pattern: /^Admin$/i, type: "actor" },
3227
3197
  { pattern: /^User$/i, type: "actor" },
@@ -3240,98 +3210,11 @@ var init_participant_inference = __esm({
3240
3210
  { pattern: /^Fan$/i, type: "actor" },
3241
3211
  { pattern: /^Purchaser$/i, type: "actor" },
3242
3212
  { pattern: /^Reviewer$/i, type: "actor" },
3243
- // Suffix rules (after infrastructure overrides filtered above)
3213
+ // Suffix rules
3244
3214
  { pattern: /User$/i, type: "actor" },
3245
3215
  { pattern: /Actor$/i, type: "actor" },
3246
3216
  { pattern: /Analyst$/i, type: "actor" },
3247
- { pattern: /Staff$/i, type: "actor" },
3248
- // ── 7. Frontend patterns ────────────────────────────────
3249
- { pattern: /App$/i, type: "frontend" },
3250
- { pattern: /Application/i, type: "frontend" },
3251
- { pattern: /Mobile/i, type: "frontend" },
3252
- { pattern: /iOS/i, type: "frontend" },
3253
- { pattern: /Android/i, type: "frontend" },
3254
- { pattern: /Web/i, type: "frontend" },
3255
- { pattern: /Browser/i, type: "frontend" },
3256
- { pattern: /Frontend/i, type: "frontend" },
3257
- { pattern: /UI$/i, type: "frontend" },
3258
- { pattern: /Dashboard/i, type: "frontend" },
3259
- { pattern: /CLI$/i, type: "frontend" },
3260
- { pattern: /Terminal/i, type: "frontend" },
3261
- // Frameworks & patterns
3262
- { pattern: /React/i, type: "frontend" },
3263
- { pattern: /^Vue$/i, type: "frontend" },
3264
- { pattern: /Angular/i, type: "frontend" },
3265
- { pattern: /Svelte/i, type: "frontend" },
3266
- { pattern: /NextJS/i, type: "frontend" },
3267
- { pattern: /Nuxt/i, type: "frontend" },
3268
- { pattern: /Remix/i, type: "frontend" },
3269
- { pattern: /Electron/i, type: "frontend" },
3270
- { pattern: /Tauri/i, type: "frontend" },
3271
- { pattern: /Widget$/i, type: "frontend" },
3272
- { pattern: /Portal/i, type: "frontend" },
3273
- { pattern: /Console$/i, type: "frontend" },
3274
- { pattern: /^SPA$/i, type: "frontend" },
3275
- { pattern: /^PWA$/i, type: "frontend" },
3276
- // ── 8. Service patterns ─────────────────────────────────
3277
- { pattern: /Service/i, type: "service" },
3278
- { pattern: /Svc$/i, type: "service" },
3279
- { pattern: /API$/i, type: "service" },
3280
- { pattern: /Lambda/i, type: "service" },
3281
- { pattern: /Function$/i, type: "service" },
3282
- { pattern: /Fn$/i, type: "service" },
3283
- { pattern: /Job$/i, type: "service" },
3284
- { pattern: /Cron/i, type: "service" },
3285
- { pattern: /Microservice/i, type: "service" },
3286
- // Auth
3287
- { pattern: /^Auth$/i, type: "service" },
3288
- { pattern: /^AuthN$/i, type: "service" },
3289
- { pattern: /^AuthZ$/i, type: "service" },
3290
- { pattern: /^SSO$/i, type: "service" },
3291
- { pattern: /OAuth/i, type: "service" },
3292
- { pattern: /^OIDC$/i, type: "service" },
3293
- // SaaS
3294
- { pattern: /Stripe/i, type: "service" },
3295
- { pattern: /Twilio/i, type: "service" },
3296
- { pattern: /SendGrid/i, type: "service" },
3297
- { pattern: /Mailgun/i, type: "service" },
3298
- // Cloud/infra
3299
- { pattern: /^S3$/i, type: "service" },
3300
- { pattern: /^Blob$/i, type: "service" },
3301
- { pattern: /Vercel/i, type: "service" },
3302
- { pattern: /Netlify/i, type: "service" },
3303
- { pattern: /Heroku/i, type: "service" },
3304
- { pattern: /Docker/i, type: "service" },
3305
- { pattern: /Kubernetes/i, type: "service" },
3306
- { pattern: /K8s/i, type: "service" },
3307
- { pattern: /Terraform/i, type: "service" },
3308
- // Security
3309
- { pattern: /Vault/i, type: "service" },
3310
- { pattern: /^HSM$/i, type: "service" },
3311
- { pattern: /KMS/i, type: "service" },
3312
- { pattern: /^IAM$/i, type: "service" },
3313
- // AI/ML
3314
- { pattern: /^LLM$/i, type: "service" },
3315
- { pattern: /GPT/i, type: "service" },
3316
- { pattern: /^Claude$/i, type: "service" },
3317
- { pattern: /Embedding/i, type: "service" },
3318
- { pattern: /Inference/i, type: "service" },
3319
- // Suffixes & patterns
3320
- { pattern: /Pipeline$/i, type: "service" },
3321
- { pattern: /Registry/i, type: "service" },
3322
- { pattern: /Engine$/i, type: "service" },
3323
- { pattern: /Daemon/i, type: "service" },
3324
- // ── 9. External patterns ────────────────────────────────
3325
- { pattern: /External/i, type: "external" },
3326
- { pattern: /Ext$/i, type: "external" },
3327
- { pattern: /ThirdParty/i, type: "external" },
3328
- { pattern: /3P$/i, type: "external" },
3329
- { pattern: /Vendor/i, type: "external" },
3330
- // Named products & patterns
3331
- { pattern: /Callback/i, type: "external" },
3332
- { pattern: /^AWS$/i, type: "external" },
3333
- { pattern: /^GCP$/i, type: "external" },
3334
- { pattern: /Azure/i, type: "external" }
3217
+ { pattern: /Staff$/i, type: "actor" }
3335
3218
  ];
3336
3219
  RULE_COUNT = PARTICIPANT_RULES.length;
3337
3220
  }
@@ -3392,15 +3275,6 @@ function parseInArrowLabel(rawLabel, lineNumber) {
3392
3275
  const diagnostics = validateLabelCharacters(trimmed, lineNumber);
3393
3276
  return { label: trimmed, diagnostics };
3394
3277
  }
3395
- function matchColorParens(content) {
3396
- const m = content.match(/^\(([A-Za-z]+)\)$/);
3397
- if (!m) return null;
3398
- const candidate = m[1].toLowerCase();
3399
- if (RECOGNIZED_COLOR_NAMES.includes(candidate)) {
3400
- return candidate;
3401
- }
3402
- return null;
3403
- }
3404
3278
  function parseArrow(line12) {
3405
3279
  if (BIDI_SYNC_RE.test(line12) || BIDI_ASYNC_RE.test(line12)) {
3406
3280
  return {
@@ -3439,7 +3313,6 @@ var init_arrows = __esm({
3439
3313
  "src/utils/arrows.ts"() {
3440
3314
  "use strict";
3441
3315
  init_diagnostics();
3442
- init_colors();
3443
3316
  ARROW_DIAGNOSTIC_CODES = {
3444
3317
  /** Active: label contains `->` or `~>` substring (TD-13). */
3445
3318
  ARROW_SUBSTRING_IN_LABEL: "E_ARROW_SUBSTRING_IN_LABEL",
@@ -3634,7 +3507,7 @@ function parseSequenceDgmo(content) {
3634
3507
  const pushWarning = (line12, message) => {
3635
3508
  result.diagnostics.push(makeDgmoError(line12, message, "warning"));
3636
3509
  };
3637
- if (!content || !content.trim()) {
3510
+ if (!content?.trim()) {
3638
3511
  return fail(0, "Empty content");
3639
3512
  }
3640
3513
  const lines = content.split("\n");
@@ -3645,7 +3518,7 @@ function parseSequenceDgmo(content) {
3645
3518
  const fl = lines[fi].trim();
3646
3519
  if (!fl || fl.startsWith("//")) continue;
3647
3520
  const parsed = parseFirstLine(fl);
3648
- if (parsed && parsed.chartType === "sequence") {
3521
+ if (parsed?.chartType === "sequence") {
3649
3522
  hasExplicitChart = true;
3650
3523
  firstLineIndex = fi;
3651
3524
  if (parsed.title) {
@@ -3764,7 +3637,7 @@ function parseSequenceDgmo(content) {
3764
3637
  if (groupColor) {
3765
3638
  pushWarning(
3766
3639
  lineNumber,
3767
- `(${groupColor}) color syntax removed from sequence diagrams \u2014 use 'tag:' groups for coloring`
3640
+ `'(${groupColor})' parens-color syntax removed from sequence diagrams \u2014 use 'tag:' groups for coloring`
3768
3641
  );
3769
3642
  }
3770
3643
  contentStarted = true;
@@ -3844,7 +3717,7 @@ function parseSequenceDgmo(content) {
3844
3717
  if (!color) {
3845
3718
  pushError(
3846
3719
  lineNumber,
3847
- `Expected 'Value(color)' in tag group '${currentTagGroup.name}'`
3720
+ `Expected 'Value color' in tag group '${currentTagGroup.name}'`
3848
3721
  );
3849
3722
  continue;
3850
3723
  }
@@ -3868,11 +3741,13 @@ function parseSequenceDgmo(content) {
3868
3741
  blockStack.pop();
3869
3742
  }
3870
3743
  const labelRaw = sectionMatch[1].trim();
3871
- const colorMatch = labelRaw.match(/^(.+?)\(([^)]+)\)$/);
3744
+ const colorMatch = labelRaw.match(
3745
+ /^(.+?)\((red|orange|yellow|green|blue|purple|teal|cyan|gray|black|white)\)$/
3746
+ );
3872
3747
  if (colorMatch) {
3873
3748
  pushWarning(
3874
3749
  lineNumber,
3875
- `(${colorMatch[2].trim()}) color syntax removed from sequence diagrams \u2014 use 'tag:' groups for coloring`
3750
+ `'(${colorMatch[2]})' parens-color syntax removed from sequence diagrams \u2014 use 'tag:' groups for coloring`
3876
3751
  );
3877
3752
  }
3878
3753
  contentStarted = true;
@@ -3958,6 +3833,17 @@ function parseSequenceDgmo(content) {
3958
3833
  const id = isAMatch[1];
3959
3834
  const typeStr = isAMatch[2].toLowerCase();
3960
3835
  let remainder = isAMatch[3]?.trim() || "";
3836
+ if (REMOVED_PARTICIPANT_TYPES.has(typeStr)) {
3837
+ result.diagnostics.push(
3838
+ makeDgmoError(
3839
+ lineNumber,
3840
+ participantTypeRemovedMessage(typeStr),
3841
+ "error",
3842
+ NAME_DIAGNOSTIC_CODES.PARTICIPANT_TYPE_REMOVED
3843
+ )
3844
+ );
3845
+ continue;
3846
+ }
3961
3847
  const participantType = VALID_PARTICIPANT_TYPES.has(
3962
3848
  typeStr
3963
3849
  ) ? typeStr : "default";
@@ -4027,7 +3913,7 @@ function parseSequenceDgmo(content) {
4027
3913
  const color = coloredMatch[2].trim();
4028
3914
  pushError(
4029
3915
  lineNumber,
4030
- `'${id}(${color})' syntax is no longer supported \u2014 use 'tag:' groups for coloring`
3916
+ `'${id}(${color})' parens-color syntax is no longer supported \u2014 use 'tag:' groups for coloring`
4031
3917
  );
4032
3918
  contentStarted = true;
4033
3919
  const key = addParticipant(id, lineNumber, { metadata: colorMeta });
@@ -4258,6 +4144,25 @@ function parseSequenceDgmo(content) {
4258
4144
  }
4259
4145
  continue;
4260
4146
  }
4147
+ const elifMatch = trimmed.match(/^elif\b\s*(.*)$/i);
4148
+ if (elifMatch) {
4149
+ const tailRaw = elifMatch[1].trim();
4150
+ const tail = tailRaw ? " " + tailRaw : "";
4151
+ pushError(
4152
+ lineNumber,
4153
+ `'elif' is not a keyword. Did you mean 'else if${tail}'?`
4154
+ );
4155
+ continue;
4156
+ }
4157
+ const elseLabelMatch = trimmed.match(/^else\s+(.+)$/i);
4158
+ if (elseLabelMatch) {
4159
+ const tail = elseLabelMatch[1].trim();
4160
+ pushError(
4161
+ lineNumber,
4162
+ `'else' does not take a label. Did you mean 'else if ${tail}'?`
4163
+ );
4164
+ continue;
4165
+ }
4261
4166
  {
4262
4167
  const noteParsed = parseNoteLine(
4263
4168
  trimmed,
@@ -4381,7 +4286,7 @@ function looksLikeSequence(content) {
4381
4286
  return ARROW_PATTERN.test(trimmed);
4382
4287
  });
4383
4288
  }
4384
- var KNOWN_SEQ_OPTIONS, KNOWN_SEQ_BOOLEANS, VALID_PARTICIPANT_TYPES, IS_A_PATTERN, POSITION_ONLY_PATTERN, COLORED_PARTICIPANT_PATTERN, GROUP_HEADING_PATTERN, GROUP_HEADING_FALLBACK, LEGACY_GROUP_PATTERN, SECTION_PATTERN, ARROW_PATTERN, NOTE_BARE, NOTE_MULTI;
4289
+ var KNOWN_SEQ_OPTIONS, KNOWN_SEQ_BOOLEANS, VALID_PARTICIPANT_TYPES, REMOVED_PARTICIPANT_TYPES, IS_A_PATTERN, POSITION_ONLY_PATTERN, COLORED_PARTICIPANT_PATTERN, GROUP_HEADING_PATTERN, GROUP_HEADING_FALLBACK, LEGACY_GROUP_PATTERN, SECTION_PATTERN, ARROW_PATTERN, NOTE_BARE, NOTE_MULTI;
4385
4290
  var init_parser = __esm({
4386
4291
  "src/sequence/parser.ts"() {
4387
4292
  "use strict";
@@ -4394,19 +4299,21 @@ var init_parser = __esm({
4394
4299
  KNOWN_SEQ_OPTIONS = /* @__PURE__ */ new Set(["active-tag"]);
4395
4300
  KNOWN_SEQ_BOOLEANS = /* @__PURE__ */ new Set(["activations", "solid-fill", "no-title"]);
4396
4301
  VALID_PARTICIPANT_TYPES = /* @__PURE__ */ new Set([
4397
- "service",
4398
4302
  "database",
4399
4303
  "actor",
4400
4304
  "queue",
4401
- "cache",
4402
- "gateway",
4403
- "external",
4305
+ "cache"
4306
+ ]);
4307
+ REMOVED_PARTICIPANT_TYPES = /* @__PURE__ */ new Set([
4308
+ "service",
4309
+ "frontend",
4404
4310
  "networking",
4405
- "frontend"
4311
+ "gateway",
4312
+ "external"
4406
4313
  ]);
4407
4314
  IS_A_PATTERN = /^([^:]+?)\s+is\s+an?\s+(\w+)(?:\s+(.+))?$/i;
4408
4315
  POSITION_ONLY_PATTERN = /^([^:]+?)\s+position\s+(-?\d+)$/i;
4409
- COLORED_PARTICIPANT_PATTERN = /^(\S+?)\(([^)]+)\)\s*$/;
4316
+ COLORED_PARTICIPANT_PATTERN = /^(\S+?)\((red|orange|yellow|green|blue|purple|teal|cyan|gray|black|white)\)\s*$/;
4410
4317
  GROUP_HEADING_PATTERN = /^\[([^\]|]+?)(?:\(([^)]+)\))?\]\s*(.*)$/;
4411
4318
  GROUP_HEADING_FALLBACK = /^\[([^\]]+)\]\s*(.*)$/;
4412
4319
  LEGACY_GROUP_PATTERN = /^##\s+(.+?)(?:\(([^)]+)\))?\s*$/;
@@ -4475,7 +4382,6 @@ function splitArrows(line12) {
4475
4382
  const arrowEnd = idx + 2;
4476
4383
  let arrowStart;
4477
4384
  let label;
4478
- let color;
4479
4385
  let openingStart = -1;
4480
4386
  for (let i = scanFloor; i < runStart; i++) {
4481
4387
  if (line12[i] !== "-") continue;
@@ -4488,21 +4394,13 @@ function splitArrows(line12) {
4488
4394
  if (openingStart !== -1) {
4489
4395
  let openingEnd = openingStart;
4490
4396
  while (openingEnd < runStart && line12[openingEnd] === "-") openingEnd++;
4491
- const arrowContent = line12.substring(openingEnd, runStart);
4492
- const colorMatch = arrowContent.match(/\(([^)]+)\)\s*$/);
4493
- if (colorMatch) {
4494
- color = colorMatch[1].trim();
4495
- const labelPart = arrowContent.substring(0, colorMatch.index).trim();
4496
- if (labelPart) label = labelPart;
4497
- } else {
4498
- const labelPart = arrowContent.trim();
4499
- if (labelPart) label = labelPart;
4500
- }
4397
+ const labelPart = line12.substring(openingEnd, runStart).trim();
4398
+ if (labelPart) label = labelPart;
4501
4399
  arrowStart = openingStart;
4502
4400
  } else {
4503
4401
  arrowStart = runStart;
4504
4402
  }
4505
- arrowPositions.push({ start: arrowStart, end: arrowEnd, label, color });
4403
+ arrowPositions.push({ start: arrowStart, end: arrowEnd, label });
4506
4404
  searchFrom = arrowEnd;
4507
4405
  scanFloor = arrowEnd;
4508
4406
  }
@@ -4516,11 +4414,7 @@ function splitArrows(line12) {
4516
4414
  if (beforeText || i === 0) {
4517
4415
  segments.push(beforeText);
4518
4416
  }
4519
- let arrowToken = "->";
4520
- if (arrow.label && arrow.color)
4521
- arrowToken = `-${arrow.label}(${arrow.color})->`;
4522
- else if (arrow.label) arrowToken = `-${arrow.label}->`;
4523
- else if (arrow.color) arrowToken = `-(${arrow.color})->`;
4417
+ const arrowToken = arrow.label ? `-${arrow.label}->` : "->";
4524
4418
  segments.push(arrowToken);
4525
4419
  lastIndex = arrow.end;
4526
4420
  }
@@ -4530,45 +4424,14 @@ function splitArrows(line12) {
4530
4424
  }
4531
4425
  return segments;
4532
4426
  }
4533
- function parseArrowToken(token, palette, lineNumber, diagnostics) {
4427
+ function parseArrowToken(token, _palette, lineNumber, diagnostics) {
4534
4428
  if (token === "->") return {};
4535
- const bareParen = token.match(/^-(\([A-Za-z]+\))->$/);
4536
- if (bareParen) {
4537
- const colorName = matchColorParens(bareParen[1]);
4538
- if (colorName) {
4539
- return {
4540
- color: resolveColorWithDiagnostic(
4541
- colorName,
4542
- lineNumber,
4543
- diagnostics,
4544
- palette
4545
- )
4546
- };
4547
- }
4548
- }
4549
- const m = token.match(/^-(.+?)(?:\(([^)]+)\))?->$/);
4429
+ const m = token.match(/^-(.+?)->$/);
4550
4430
  if (m) {
4551
4431
  const rawLabel = m[1] ?? "";
4552
4432
  const labelResult = parseInArrowLabel(rawLabel, lineNumber);
4553
4433
  diagnostics.push(...labelResult.diagnostics);
4554
- const label = labelResult.label;
4555
- let color = m[2] ? resolveColorWithDiagnostic(
4556
- m[2].trim(),
4557
- lineNumber,
4558
- diagnostics,
4559
- palette
4560
- ) : void 0;
4561
- if (label && !color) {
4562
- const inferred = inferArrowColor(label);
4563
- if (inferred)
4564
- color = resolveColorWithDiagnostic(
4565
- inferred,
4566
- lineNumber,
4567
- diagnostics,
4568
- palette
4569
- );
4570
- }
4571
- return { label, color };
4434
+ return { label: labelResult.label };
4572
4435
  }
4573
4436
  return {};
4574
4437
  }
@@ -4634,13 +4497,12 @@ function parseFlowchart(content, palette) {
4634
4497
  result.nodes.push(node);
4635
4498
  return node;
4636
4499
  }
4637
- function addEdge(sourceId, targetId, lineNumber, label, color) {
4500
+ function addEdge(sourceId, targetId, lineNumber, label) {
4638
4501
  const edge = {
4639
4502
  source: sourceId,
4640
4503
  target: targetId,
4641
4504
  lineNumber,
4642
- ...label && { label },
4643
- ...color && { color }
4505
+ ...label && { label }
4644
4506
  };
4645
4507
  result.edges.push(edge);
4646
4508
  }
@@ -4706,13 +4568,7 @@ function parseFlowchart(content, palette) {
4706
4568
  if (pendingArrow !== null) {
4707
4569
  const sourceId = lastNodeId ?? implicitSourceId;
4708
4570
  if (sourceId) {
4709
- addEdge(
4710
- sourceId,
4711
- node.id,
4712
- lineNumber,
4713
- pendingArrow.label,
4714
- pendingArrow.color
4715
- );
4571
+ addEdge(sourceId, node.id, lineNumber, pendingArrow.label);
4716
4572
  }
4717
4573
  pendingArrow = null;
4718
4574
  } else if (lastNodeId === null && implicitSourceId === null) {
@@ -4837,7 +4693,6 @@ var NODE_ID_RE;
4837
4693
  var init_flowchart_parser = __esm({
4838
4694
  "src/graph/flowchart-parser.ts"() {
4839
4695
  "use strict";
4840
- init_colors();
4841
4696
  init_diagnostics();
4842
4697
  init_arrows();
4843
4698
  init_parsing();
@@ -4865,7 +4720,6 @@ function splitArrows2(line12) {
4865
4720
  const arrowEnd = idx + 2;
4866
4721
  let arrowStart;
4867
4722
  let label;
4868
- let color;
4869
4723
  let openingStart = -1;
4870
4724
  for (let i = scanFloor; i < runStart; i++) {
4871
4725
  if (line12[i] !== "-") continue;
@@ -4878,21 +4732,13 @@ function splitArrows2(line12) {
4878
4732
  if (openingStart !== -1) {
4879
4733
  let openingEnd = openingStart;
4880
4734
  while (openingEnd < runStart && line12[openingEnd] === "-") openingEnd++;
4881
- const arrowContent = line12.substring(openingEnd, runStart);
4882
- const colorMatch = arrowContent.match(/\(([^)]+)\)\s*$/);
4883
- if (colorMatch) {
4884
- color = colorMatch[1].trim();
4885
- const labelPart = arrowContent.substring(0, colorMatch.index).trim();
4886
- if (labelPart) label = labelPart;
4887
- } else {
4888
- const labelPart = arrowContent.trim();
4889
- if (labelPart) label = labelPart;
4890
- }
4735
+ const labelPart = line12.substring(openingEnd, runStart).trim();
4736
+ if (labelPart) label = labelPart;
4891
4737
  arrowStart = openingStart;
4892
4738
  } else {
4893
4739
  arrowStart = runStart;
4894
4740
  }
4895
- arrowPositions.push({ start: arrowStart, end: arrowEnd, label, color });
4741
+ arrowPositions.push({ start: arrowStart, end: arrowEnd, label });
4896
4742
  searchFrom = arrowEnd;
4897
4743
  scanFloor = arrowEnd;
4898
4744
  }
@@ -4902,11 +4748,7 @@ function splitArrows2(line12) {
4902
4748
  const arrow = arrowPositions[i];
4903
4749
  const beforeText = line12.substring(lastIndex, arrow.start).trim();
4904
4750
  if (beforeText || i === 0) segments.push(beforeText);
4905
- let arrowToken = "->";
4906
- if (arrow.label && arrow.color)
4907
- arrowToken = `-${arrow.label}(${arrow.color})->`;
4908
- else if (arrow.label) arrowToken = `-${arrow.label}->`;
4909
- else if (arrow.color) arrowToken = `-(${arrow.color})->`;
4751
+ const arrowToken = arrow.label ? `-${arrow.label}->` : "->";
4910
4752
  segments.push(arrowToken);
4911
4753
  lastIndex = arrow.end;
4912
4754
  }
@@ -4914,35 +4756,14 @@ function splitArrows2(line12) {
4914
4756
  if (remaining) segments.push(remaining);
4915
4757
  return segments;
4916
4758
  }
4917
- function parseArrowToken2(token, palette, lineNumber, diagnostics) {
4759
+ function parseArrowToken2(token, _palette, lineNumber, diagnostics) {
4918
4760
  if (token === "->") return {};
4919
- const bareParen = token.match(/^-(\([A-Za-z]+\))->$/);
4920
- if (bareParen) {
4921
- const colorName = matchColorParens(bareParen[1]);
4922
- if (colorName) {
4923
- return {
4924
- color: resolveColorWithDiagnostic(
4925
- colorName,
4926
- lineNumber,
4927
- diagnostics,
4928
- palette
4929
- )
4930
- };
4931
- }
4932
- }
4933
- const m = token.match(/^-(.+?)(?:\(([^)]+)\))?->$/);
4761
+ const m = token.match(/^-(.+?)->$/);
4934
4762
  if (m) {
4935
4763
  const rawLabel = m[1] ?? "";
4936
4764
  const labelResult = parseInArrowLabel(rawLabel, lineNumber);
4937
4765
  diagnostics.push(...labelResult.diagnostics);
4938
- const label = labelResult.label;
4939
- const color = m[2] ? resolveColorWithDiagnostic(
4940
- m[2].trim(),
4941
- lineNumber,
4942
- diagnostics,
4943
- palette
4944
- ) : void 0;
4945
- return { label, color };
4766
+ return { label: labelResult.label };
4946
4767
  }
4947
4768
  return {};
4948
4769
  }
@@ -5033,13 +4854,12 @@ function parseState(content, palette) {
5033
4854
  }
5034
4855
  return node;
5035
4856
  }
5036
- function addEdge(sourceId, targetId, lineNumber, label, color) {
4857
+ function addEdge(sourceId, targetId, lineNumber, label) {
5037
4858
  result.edges.push({
5038
4859
  source: sourceId,
5039
4860
  target: targetId,
5040
4861
  lineNumber,
5041
- ...label && { label },
5042
- ...color && { color }
4862
+ ...label && { label }
5043
4863
  });
5044
4864
  }
5045
4865
  for (let i = 0; i < lines.length; i++) {
@@ -5182,13 +5002,7 @@ function parseState(content, palette) {
5182
5002
  if (pendingArrow !== null) {
5183
5003
  const sourceId = lastNodeId ?? implicitSourceId;
5184
5004
  if (sourceId) {
5185
- addEdge(
5186
- sourceId,
5187
- node.id,
5188
- lineNumber,
5189
- pendingArrow.label,
5190
- pendingArrow.color
5191
- );
5005
+ addEdge(sourceId, node.id, lineNumber, pendingArrow.label);
5192
5006
  }
5193
5007
  pendingArrow = null;
5194
5008
  }
@@ -5241,7 +5055,7 @@ var init_state_parser = __esm({
5241
5055
  init_name_normalize();
5242
5056
  PSEUDOSTATE_ID = "pseudostate:[*]";
5243
5057
  PSEUDOSTATE_LABEL = "[*]";
5244
- GROUP_BRACKET_RE = /^\[([^\]]+)\](?:\(([^)]+)\))?\s*$/;
5058
+ GROUP_BRACKET_RE = /^\[([^\]]+)\](?:\s+(red|orange|yellow|green|blue|purple|teal|cyan|gray|black|white))?\s*$/;
5245
5059
  }
5246
5060
  });
5247
5061
 
@@ -5389,7 +5203,7 @@ function parseClassDiagram(content, palette) {
5389
5203
  if (trimmed.startsWith("//")) continue;
5390
5204
  if (!contentStarted && indent === 0 && i === 0) {
5391
5205
  const firstLine = parseFirstLine(trimmed);
5392
- if (firstLine && firstLine.chartType === "class") {
5206
+ if (firstLine?.chartType === "class") {
5393
5207
  if (firstLine.title) {
5394
5208
  result.title = firstLine.title;
5395
5209
  result.titleLineNumber = lineNumber;
@@ -5620,7 +5434,7 @@ var init_parser2 = __esm({
5620
5434
  init_arrows();
5621
5435
  init_parsing();
5622
5436
  init_name_normalize();
5623
- CLASS_DECL_RE = /^(?:(abstract|interface|enum)\s+)?(?:"([^"]+)"|([A-Z][^":]*?))(?:\s+extends\s+(?:"([^"]+)"|([A-Z][^":]*?)))?(?:\s+implements\s+(?:"([^"]+)"|([A-Z][^":]*?)))?(?:\s+\[(abstract|interface|enum)\])?(?:\s+\(([^)]+)\))?(?:\s+as\s+([A-Za-z][A-Za-z0-9_]{0,11}))?\s*$/;
5437
+ CLASS_DECL_RE = /^(?:(abstract|interface|enum)\s+)?(?:"([^"]+)"|([A-Z][^":]*?))(?:\s+extends\s+(?:"([^"]+)"|([A-Z][^":]*?)))?(?:\s+implements\s+(?:"([^"]+)"|([A-Z][^":]*?)))?(?:\s+\[(abstract|interface|enum)\])?(?:\s+(red|orange|yellow|green|blue|purple|teal|cyan|gray|black|white))?(?:\s+as\s+([A-Za-z][A-Za-z0-9_]{0,11}))?\s*$/;
5624
5438
  INDENT_REL_ARROW_RE = /^(--\|>|\.\.\|>|\*--|o--|\.\.>|->)\s*(?:"([^"]+)"|([A-Za-z][^":]*?))(?:\s+:?\s*(.+))?$/;
5625
5439
  REL_ARROW_RE = /^(?:"([^"]+)"|([A-Z][^":]*?))\s*(--\|>|\.\.\|>|\*--|o--|\.\.>|->)\s*(?:"([^"]+)"|([A-Z][^":]*?))(?:\s+:?\s*(.+))?$/;
5626
5440
  VISIBILITY_RE = /^([+\-#])\s*/;
@@ -5790,7 +5604,7 @@ function parseERDiagram(content, palette) {
5790
5604
  if (trimmed.startsWith("//")) continue;
5791
5605
  if (!firstLineParsed && indent === 0) {
5792
5606
  const firstLineResult = parseFirstLine(trimmed);
5793
- if (firstLineResult && firstLineResult.chartType === "er") {
5607
+ if (firstLineResult?.chartType === "er") {
5794
5608
  firstLineParsed = true;
5795
5609
  if (firstLineResult.title) {
5796
5610
  result.title = firstLineResult.title;
@@ -5827,7 +5641,7 @@ function parseERDiagram(content, palette) {
5827
5641
  result.diagnostics.push(
5828
5642
  makeDgmoError(
5829
5643
  lineNumber,
5830
- `Expected 'Value(color)' in tag group '${currentTagGroup.name}'`,
5644
+ `Expected 'Value color' in tag group '${currentTagGroup.name}'`,
5831
5645
  "warning"
5832
5646
  )
5833
5647
  );
@@ -5939,7 +5753,7 @@ function parseERDiagram(content, palette) {
5939
5753
  if (result.tables.length === 0 && !result.error) {
5940
5754
  const diag = makeDgmoError(
5941
5755
  1,
5942
- 'No tables found. Add table declarations like "users" or "orders (blue)".'
5756
+ 'No tables found. Add table declarations like "users" or "orders blue".'
5943
5757
  );
5944
5758
  result.diagnostics.push(diag);
5945
5759
  result.error = formatDgmoError(diag);
@@ -6025,15 +5839,19 @@ function extractSymbols3(docText) {
6025
5839
  for (const rawLine of docText.split("\n")) {
6026
5840
  const line12 = rawLine.trim();
6027
5841
  if (inMetadata && /^er(\s|$)/i.test(line12)) continue;
6028
- if (inMetadata && OPTION_NOCOLON_RE.test(line12)) continue;
6029
- inMetadata = false;
6030
- if (line12.length === 0) continue;
6031
5842
  if (/^\s/.test(rawLine)) continue;
5843
+ if (line12.length === 0) continue;
6032
5844
  const m = TABLE_DECL_RE.exec(line12);
6033
5845
  if (m) {
6034
5846
  const name = (m[1] ?? m[2] ?? "").trim();
6035
- if (name) entities.push(name);
5847
+ if (name) {
5848
+ inMetadata = false;
5849
+ entities.push(name);
5850
+ continue;
5851
+ }
6036
5852
  }
5853
+ if (inMetadata && OPTION_NOCOLON_RE.test(line12)) continue;
5854
+ inMetadata = false;
6037
5855
  }
6038
5856
  return {
6039
5857
  kind: "er",
@@ -6051,7 +5869,7 @@ var init_parser3 = __esm({
6051
5869
  init_name_normalize();
6052
5870
  init_parsing();
6053
5871
  init_tag_groups();
6054
- TABLE_DECL_RE = /^(?:"([^"]+)"|([a-zA-Z_][^|":(]*?))(?:\s*\(([^)]+)\))?(?:\s*\|(.+))?$/;
5872
+ TABLE_DECL_RE = /^(?:"([^"]+)"|([a-zA-Z_][^|":(]*?))(?:\s+(red|orange|yellow|green|blue|purple|teal|cyan|gray|black|white))?(?:\s*\|(.+))?$/;
6055
5873
  INDENT_REL_RE = /^([1*?])-{1,2}(?:(.+?)-{1,2})?([1*?])\s+(?:"([^"]+)"|([a-zA-Z_][^":]*?))\s*$/;
6056
5874
  CONSTRAINT_MAP = {
6057
5875
  pk: "pk",
@@ -6131,18 +5949,22 @@ function parseChart(content, palette) {
6131
5949
  return fail(lineNumber, msg2);
6132
5950
  }
6133
5951
  }
6134
- const eraMatch = trimmed.match(
6135
- /^era\s+(.+?)\s*->\s*(.+?)(?:\s*\(([^)]+)\))?\s*$/
6136
- );
5952
+ const eraMatch = trimmed.match(/^era\s+(.+?)\s*->\s*(.+?)\s*$/);
6137
5953
  if (eraMatch) {
6138
5954
  const afterArrow = eraMatch[2].trim();
6139
5955
  const spaceIdx2 = afterArrow.indexOf(" ");
6140
5956
  if (spaceIdx2 >= 0) {
5957
+ const lastSpaceIdx = afterArrow.lastIndexOf(" ");
5958
+ const trailing = afterArrow.substring(lastSpaceIdx + 1);
5959
+ const hasColor = RECOGNIZED_COLOR_NAMES.includes(
5960
+ trailing
5961
+ );
5962
+ const labelPart = hasColor ? afterArrow.substring(0, lastSpaceIdx).trimEnd() : afterArrow;
6141
5963
  rawEras.push({
6142
5964
  start: eraMatch[1].trim(),
6143
- afterArrow,
6144
- color: eraMatch[3] ? resolveColorWithDiagnostic(
6145
- eraMatch[3].trim(),
5965
+ afterArrow: labelPart,
5966
+ color: hasColor ? resolveColorWithDiagnostic(
5967
+ trailing,
6146
5968
  lineNumber,
6147
5969
  result.diagnostics,
6148
5970
  palette
@@ -6642,11 +6464,12 @@ function parseExtendedChart(content, palette) {
6642
6464
  return result;
6643
6465
  }
6644
6466
  }
6645
- const categoryMatch = trimmed.match(/^\[(.+?)\](?:\s*\(([^)]+)\))?\s*$/);
6467
+ const categoryMatch = trimmed.match(/^\[(.+?)\](?:\s+(\S+))?\s*$/);
6646
6468
  if (categoryMatch) {
6647
6469
  const catName = categoryMatch[1].trim();
6648
- const catColor = categoryMatch[2] ? resolveColorWithDiagnostic(
6649
- categoryMatch[2].trim(),
6470
+ const rawCatColor = categoryMatch[2]?.trim();
6471
+ const catColor = rawCatColor ? resolveColorWithDiagnostic(
6472
+ rawCatColor,
6650
6473
  lineNumber,
6651
6474
  result.diagnostics,
6652
6475
  palette
@@ -6661,7 +6484,7 @@ function parseExtendedChart(content, palette) {
6661
6484
  continue;
6662
6485
  }
6663
6486
  const arrowMatch = trimmed.match(
6664
- /^(.+?)\s*(->|--)\s*(.+?)\s+(-?[\d,_]+(?:\.[\d]+)?)\s*(?:\(([^)]+)\))?\s*$/
6487
+ /^(.+?)\s*(->|--)\s*(.+?)\s+(-?[\d,_]+(?:\.[\d]+)?)(?:\s+(red|orange|yellow|green|blue|purple|teal|cyan|gray|black|white))?\s*$/
6665
6488
  );
6666
6489
  if (arrowMatch) {
6667
6490
  const [, rawSource, arrow, rawTarget, rawVal, rawLinkColor] = arrowMatch;
@@ -6706,11 +6529,14 @@ function parseExtendedChart(content, palette) {
6706
6529
  }
6707
6530
  if (sankeyStack.length > 0) {
6708
6531
  const valColorMatch = trimmed.match(
6709
- /(-?[\d,_]+(?:\.[\d]+)?)\s*\(([^)]+)\)\s*$/
6532
+ /(-?[\d,_]+(?:\.[\d]+)?)\s+(red|orange|yellow|green|blue|purple|teal|cyan|gray|black|white)\s*$/
6710
6533
  );
6711
- const strippedLine = valColorMatch ? trimmed.replace(/\s*\([^)]+\)\s*$/, "") : trimmed;
6534
+ const strippedLine = valColorMatch ? trimmed.replace(
6535
+ /\s+(red|orange|yellow|green|blue|purple|teal|cyan|gray|black|white)\s*$/,
6536
+ ""
6537
+ ) : trimmed;
6712
6538
  const dataRow2 = parseDataRowValues(strippedLine);
6713
- if (dataRow2 && dataRow2.values.length === 1) {
6539
+ if (dataRow2?.values.length === 1) {
6714
6540
  const source = sankeyStack.at(-1).name;
6715
6541
  const linkColor = valColorMatch?.[2] ? resolveColorWithDiagnostic(
6716
6542
  valColorMatch[2].trim(),
@@ -6942,7 +6768,7 @@ function parseExtendedChart(content, palette) {
6942
6768
  }
6943
6769
  }
6944
6770
  const dataRow = parseDataRowValues(trimmed);
6945
- if (dataRow && dataRow.values.length === 1) {
6771
+ if (dataRow?.values.length === 1) {
6946
6772
  const { label: rawLabel, color: pointColor } = extractColor(
6947
6773
  dataRow.label,
6948
6774
  palette
@@ -8990,7 +8816,7 @@ function parseOrg(content, palette) {
8990
8816
  const pushWarning = (line12, message) => {
8991
8817
  result.diagnostics.push(makeDgmoError(line12, message, "warning"));
8992
8818
  };
8993
- if (!content || !content.trim()) {
8819
+ if (!content?.trim()) {
8994
8820
  return fail(0, "No content provided");
8995
8821
  }
8996
8822
  const lines = content.split("\n");
@@ -9088,7 +8914,7 @@ function parseOrg(content, palette) {
9088
8914
  if (!color) {
9089
8915
  pushError(
9090
8916
  lineNumber,
9091
- `Expected 'Value(color)' in tag group '${currentTagGroup.name}'`
8917
+ `Expected 'Value color' in tag group '${currentTagGroup.name}'`
9092
8918
  );
9093
8919
  continue;
9094
8920
  }
@@ -9287,7 +9113,7 @@ function parseKanban(content, palette) {
9287
9113
  const warn = (line12, message) => {
9288
9114
  result.diagnostics.push(makeDgmoError(line12, message, "warning"));
9289
9115
  };
9290
- if (!content || !content.trim()) {
9116
+ if (!content?.trim()) {
9291
9117
  return fail(0, "No content provided");
9292
9118
  }
9293
9119
  const lines = content.split("\n");
@@ -9379,7 +9205,7 @@ function parseKanban(content, palette) {
9379
9205
  if (!color) {
9380
9206
  warn(
9381
9207
  lineNumber,
9382
- `Expected 'Value(color)' in tag group '${currentTagGroup.name}'`
9208
+ `Expected 'Value color' in tag group '${currentTagGroup.name}'`
9383
9209
  );
9384
9210
  continue;
9385
9211
  }
@@ -9422,8 +9248,9 @@ function parseKanban(content, palette) {
9422
9248
  currentCard = null;
9423
9249
  columnCounter++;
9424
9250
  const colName = columnMatch[1].trim();
9425
- const colColor = columnMatch[2] ? resolveColorWithDiagnostic(
9426
- columnMatch[2].trim(),
9251
+ const rawTrailing = columnMatch[2]?.trim();
9252
+ const colColor = rawTrailing ? resolveColorWithDiagnostic(
9253
+ rawTrailing,
9427
9254
  lineNumber,
9428
9255
  result.diagnostics,
9429
9256
  palette
@@ -9578,7 +9405,7 @@ var init_parser5 = __esm({
9578
9405
  init_tag_groups();
9579
9406
  init_parsing();
9580
9407
  init_name_normalize();
9581
- COLUMN_RE = /^\[(.+?)\](?:\s*\(([^)]+)\))?(?:\s+as\s+([A-Za-z][A-Za-z0-9_]{0,11}))?\s*(?:\|\s*(.+))?$/;
9408
+ COLUMN_RE = /^\[(.+?)\](?:\s+(\S+))?(?:\s+as\s+([A-Za-z][A-Za-z0-9_]{0,11}))?\s*(?:\|\s*(.+))?$/;
9582
9409
  LEGACY_COLUMN_RE = /^==\s+(.+?)\s*(?:\[wip:\s*(\d+)\])?\s*==$/;
9583
9410
  KNOWN_OPTIONS4 = /* @__PURE__ */ new Set(["hide", "active-tag"]);
9584
9411
  KNOWN_BOOLEANS3 = /* @__PURE__ */ new Set([
@@ -9675,7 +9502,7 @@ function parseC4(content, palette) {
9675
9502
  result.error = formatDgmoError(diag);
9676
9503
  return result;
9677
9504
  };
9678
- if (!content || !content.trim()) {
9505
+ if (!content?.trim()) {
9679
9506
  return fail(0, "No content provided");
9680
9507
  }
9681
9508
  const lines = content.split("\n");
@@ -9761,7 +9588,7 @@ function parseC4(content, palette) {
9761
9588
  if (!color) {
9762
9589
  pushError(
9763
9590
  lineNumber,
9764
- `Expected 'Value(color)' in tag group '${currentTagGroup.name}'`
9591
+ `Expected 'Value color' in tag group '${currentTagGroup.name}'`
9765
9592
  );
9766
9593
  continue;
9767
9594
  }
@@ -10357,7 +10184,7 @@ __export(parser_exports7, {
10357
10184
  looksLikeSitemap: () => looksLikeSitemap,
10358
10185
  parseSitemap: () => parseSitemap
10359
10186
  });
10360
- function parseArrowLine(trimmed, palette, lineNumber, diagnostics) {
10187
+ function parseArrowLine(trimmed, _palette, _lineNumber, _diagnostics) {
10361
10188
  const bareMatch = trimmed.match(BARE_ARROW_RE);
10362
10189
  if (bareMatch) {
10363
10190
  const rawTarget = bareMatch[1].trim();
@@ -10370,27 +10197,10 @@ function parseArrowLine(trimmed, palette, lineNumber, diagnostics) {
10370
10197
  const arrowMatch = trimmed.match(ARROW_RE);
10371
10198
  if (arrowMatch) {
10372
10199
  const label = arrowMatch[1]?.trim() || void 0;
10373
- let color = arrowMatch[2] ? resolveColorWithDiagnostic(
10374
- arrowMatch[2].trim(),
10375
- lineNumber,
10376
- diagnostics,
10377
- palette
10378
- ) : void 0;
10379
- if (label && !color) {
10380
- const inferred = inferArrowColor(label);
10381
- if (inferred)
10382
- color = resolveColorWithDiagnostic(
10383
- inferred,
10384
- lineNumber,
10385
- diagnostics,
10386
- palette
10387
- );
10388
- }
10389
- const rawTarget = arrowMatch[3].trim();
10200
+ const rawTarget = arrowMatch[2].trim();
10390
10201
  const groupMatch = rawTarget.match(/^\[(.+)\]$/);
10391
10202
  return {
10392
10203
  label,
10393
- color,
10394
10204
  target: groupMatch ? groupMatch[1].trim() : rawTarget,
10395
10205
  targetIsGroup: !!groupMatch
10396
10206
  };
@@ -10443,7 +10253,7 @@ function parseSitemap(content, palette) {
10443
10253
  const pushWarning = (line12, message) => {
10444
10254
  result.diagnostics.push(makeDgmoError(line12, message, "warning"));
10445
10255
  };
10446
- if (!content || !content.trim()) {
10256
+ if (!content?.trim()) {
10447
10257
  return fail(0, "No content provided");
10448
10258
  }
10449
10259
  const lines = content.split("\n");
@@ -10532,7 +10342,7 @@ function parseSitemap(content, palette) {
10532
10342
  if (!color) {
10533
10343
  pushError(
10534
10344
  lineNumber,
10535
- `Expected 'Value(color)' in tag group '${currentTagGroup.name}'`
10345
+ `Expected 'Value color' in tag group '${currentTagGroup.name}'`
10536
10346
  );
10537
10347
  continue;
10538
10348
  }
@@ -10569,7 +10379,6 @@ function parseSitemap(content, palette) {
10569
10379
  targetLabel: arrowInfo.target,
10570
10380
  targetIsGroup: arrowInfo.targetIsGroup,
10571
10381
  label: arrowInfo.label,
10572
- color: arrowInfo.color,
10573
10382
  lineNumber
10574
10383
  });
10575
10384
  }
@@ -10667,7 +10476,6 @@ function parseSitemap(content, palette) {
10667
10476
  sourceId: arrow.sourceNode.id,
10668
10477
  targetId: aliasHit,
10669
10478
  label: arrow.label,
10670
- color: arrow.color,
10671
10479
  lineNumber: arrow.lineNumber
10672
10480
  });
10673
10481
  continue;
@@ -10687,7 +10495,6 @@ function parseSitemap(content, palette) {
10687
10495
  sourceId: arrow.sourceNode.id,
10688
10496
  targetId: targetContainer.id,
10689
10497
  label: arrow.label,
10690
- color: arrow.color,
10691
10498
  lineNumber: arrow.lineNumber
10692
10499
  });
10693
10500
  } else {
@@ -10704,7 +10511,6 @@ function parseSitemap(content, palette) {
10704
10511
  sourceId: arrow.sourceNode.id,
10705
10512
  targetId: targetNode.id,
10706
10513
  label: arrow.label,
10707
- color: arrow.color,
10708
10514
  lineNumber: arrow.lineNumber
10709
10515
  });
10710
10516
  }
@@ -10794,7 +10600,6 @@ var CONTAINER_RE3, METADATA_RE3, ARROW_RE, BARE_ARROW_RE;
10794
10600
  var init_parser7 = __esm({
10795
10601
  "src/sitemap/parser.ts"() {
10796
10602
  "use strict";
10797
- init_colors();
10798
10603
  init_diagnostics();
10799
10604
  init_name_normalize();
10800
10605
  init_tag_groups();
@@ -10802,7 +10607,7 @@ var init_parser7 = __esm({
10802
10607
  init_description_helpers();
10803
10608
  CONTAINER_RE3 = /^\[([^\]]+)\]\s*(?:\|\s*(.+))?$/;
10804
10609
  METADATA_RE3 = /^([^:]+):\s*(.+)$/;
10805
- ARROW_RE = /^-([^(>][^(>]*?)?\s*(?:\(([^)]+)\))?\s*->\s*(.+)$/;
10610
+ ARROW_RE = /^-([^>][^>]*?)?\s*->\s*(.+)$/;
10806
10611
  BARE_ARROW_RE = /^->\s*(.+)$/;
10807
10612
  }
10808
10613
  });
@@ -11093,13 +10898,18 @@ function parseInfra(content) {
11093
10898
  }
11094
10899
  if (currentTagGroup && indent > 0) {
11095
10900
  const { text: cleanEntry, isDefault } = stripDefaultModifier(trimmed);
11096
- const tvMatch = cleanEntry.match(TAG_VALUE_RE);
11097
- if (tvMatch) {
11098
- const valueName = tvMatch[1].trim();
11099
- const rawColor = tvMatch[2]?.trim();
11100
- if (rawColor) {
11101
- resolveColorWithDiagnostic(rawColor, lineNumber, result.diagnostics);
11102
- }
10901
+ const lastSpaceIdx = cleanEntry.lastIndexOf(" ");
10902
+ let valueName = cleanEntry;
10903
+ let rawColor;
10904
+ if (lastSpaceIdx > 0) {
10905
+ const trailing = cleanEntry.substring(lastSpaceIdx + 1);
10906
+ if (isRecognizedColorName(trailing)) {
10907
+ rawColor = trailing;
10908
+ valueName = cleanEntry.substring(0, lastSpaceIdx).trimEnd();
10909
+ }
10910
+ }
10911
+ const tvMatch = valueName.match(TAG_VALUE_RE);
10912
+ if (tvMatch || /^\w+$/.test(valueName)) {
11103
10913
  currentTagGroup.values.push({
11104
10914
  name: valueName,
11105
10915
  color: rawColor
@@ -11511,9 +11321,9 @@ var init_parser8 = __esm({
11511
11321
  "use strict";
11512
11322
  init_diagnostics();
11513
11323
  init_description_helpers();
11514
- init_colors();
11515
11324
  init_arrows();
11516
11325
  init_parsing();
11326
+ init_colors();
11517
11327
  init_name_normalize();
11518
11328
  init_tag_groups();
11519
11329
  init_types();
@@ -11523,7 +11333,7 @@ var init_parser8 = __esm({
11523
11333
  ASYNC_SIMPLE_CONNECTION_RE = /^~>\s*(.+?)\s*$/;
11524
11334
  DEPRECATED_FANOUT_RE = /\bx(\d+)\s*$/;
11525
11335
  GROUP_RE = /^\[([^\]]+)\]\s*(?:as\s+([A-Za-z][A-Za-z0-9_]{0,11})\s*)?(?:\|\s*(.+))?$/;
11526
- TAG_VALUE_RE = /^(\w[\w\s]*?)(?:\(([^)]+)\))?\s*$/;
11336
+ TAG_VALUE_RE = /^(\w[\w\s]+?)\s*$/;
11527
11337
  COMPONENT_RE = /^(?:"([^"]+)"|([a-zA-Z_][^|":]*?))\s*(\|.*)?$/;
11528
11338
  PIPE_META_RE = /[|,]\s*(\w+)\s*:\s*([^|,]+)/g;
11529
11339
  PROPERTY_RE = /^([\w-]+)\s+(.+)$/;
@@ -12960,7 +12770,7 @@ function parsePert(content, parseOpts = {}) {
12960
12770
  if (!color) {
12961
12771
  warn(
12962
12772
  lineNumber,
12963
- `Expected 'Value(color)' in tag group '${currentTagGroup.name}'`
12773
+ `Expected 'Value color' in tag group '${currentTagGroup.name}'`
12964
12774
  );
12965
12775
  continue;
12966
12776
  }
@@ -12983,7 +12793,7 @@ function parsePert(content, parseOpts = {}) {
12983
12793
  if (!color) {
12984
12794
  warn(
12985
12795
  lineNumber,
12986
- `Expected 'Value(color)' in tag group '${currentTagGroup.name}'`
12796
+ `Expected 'Value color' in tag group '${currentTagGroup.name}'`
12987
12797
  );
12988
12798
  continue;
12989
12799
  }
@@ -13127,7 +12937,7 @@ function parsePert(content, parseOpts = {}) {
13127
12937
  const head = trimmed.slice(0, firstSpace).toLowerCase();
13128
12938
  const value = trimmed.slice(firstSpace + 1).trim();
13129
12939
  const hint = NEAR_DIRECTIVE_HINTS.find((h) => h.stem === head);
13130
- if (hint && hint.matches.test(value)) {
12940
+ if (hint?.matches.test(value)) {
13131
12941
  error(
13132
12942
  lineNumber,
13133
12943
  `Unknown directive '${head}'. Did you mean '${hint.canonical}'?`,
@@ -14434,7 +14244,7 @@ function parseMindmap(content, palette) {
14434
14244
  const pushWarning = (line12, message) => {
14435
14245
  result.diagnostics.push(makeDgmoError(line12, message, "warning"));
14436
14246
  };
14437
- if (!content || !content.trim()) {
14247
+ if (!content?.trim()) {
14438
14248
  return fail(0, "No content provided");
14439
14249
  }
14440
14250
  const lines = content.split("\n");
@@ -14532,7 +14342,7 @@ function parseMindmap(content, palette) {
14532
14342
  if (!color) {
14533
14343
  pushError(
14534
14344
  lineNumber,
14535
- `Expected 'Value(color)' in tag group '${currentTagGroup.name}'`
14345
+ `Expected 'Value color' in tag group '${currentTagGroup.name}'`
14536
14346
  );
14537
14347
  continue;
14538
14348
  }
@@ -14605,7 +14415,7 @@ function parseMindmap(content, palette) {
14605
14415
  const diag = makeDgmoError(1, "No nodes found in mindmap");
14606
14416
  result.diagnostics.push(diag);
14607
14417
  result.error = formatDgmoError(diag);
14608
- } else if (titleRoot && titleRoot.children.length === 0 && result.roots.length === 1 && !result.error) {
14418
+ } else if (titleRoot?.children.length === 0 && result.roots.length === 1 && !result.error) {
14609
14419
  }
14610
14420
  return result;
14611
14421
  }
@@ -15064,7 +14874,7 @@ function parseWireframe(content) {
15064
14874
  const indent = measureIndent(line12);
15065
14875
  if (phase === "header") {
15066
14876
  const firstLineResult = parseFirstLine(trimmed);
15067
- if (firstLineResult && firstLineResult.chartType === "wireframe") {
14877
+ if (firstLineResult?.chartType === "wireframe") {
15068
14878
  title = firstLineResult.title || null;
15069
14879
  titleLineNumber = lineNumber;
15070
14880
  continue;
@@ -15118,7 +14928,7 @@ function parseWireframe(content) {
15118
14928
  } else {
15119
14929
  pushWarning(
15120
14930
  lineNumber,
15121
- `Expected 'Value(color)' in tag group '${currentTagGroup.name}'`
14931
+ `Expected 'Value color' in tag group '${currentTagGroup.name}'`
15122
14932
  );
15123
14933
  }
15124
14934
  continue;
@@ -15359,7 +15169,7 @@ function parseTechRadar(content) {
15359
15169
  const warn = (line12, message) => {
15360
15170
  result.diagnostics.push(makeDgmoError(line12, message, "warning"));
15361
15171
  };
15362
- if (!content || !content.trim()) {
15172
+ if (!content?.trim()) {
15363
15173
  return fail(0, "No content provided");
15364
15174
  }
15365
15175
  function isRingName(name) {
@@ -15396,7 +15206,7 @@ function parseTechRadar(content) {
15396
15206
  if (trimmed.startsWith("//")) continue;
15397
15207
  if (!headerParsed) {
15398
15208
  const firstLine = parseFirstLine(trimmed);
15399
- if (firstLine && firstLine.chartType === "tech-radar") {
15209
+ if (firstLine?.chartType === "tech-radar") {
15400
15210
  result.title = firstLine.title ?? "";
15401
15211
  result.titleLineNumber = lineNumber;
15402
15212
  headerParsed = true;
@@ -15688,7 +15498,7 @@ function parseCycle(content) {
15688
15498
  const indent = measureIndent(raw);
15689
15499
  if (!headerParsed) {
15690
15500
  const firstLineResult = parseFirstLine(trimmed);
15691
- if (firstLineResult && firstLineResult.chartType === "cycle") {
15501
+ if (firstLineResult?.chartType === "cycle") {
15692
15502
  result.title = firstLineResult.title ?? "";
15693
15503
  result.titleLineNumber = lineNum;
15694
15504
  headerParsed = true;
@@ -15735,6 +15545,13 @@ function parseCycle(content) {
15735
15545
  warn(lineNum, "Empty node label.");
15736
15546
  continue;
15737
15547
  }
15548
+ if (!metadata["color"]) {
15549
+ const { label: stripped, colorName: shortcutColor } = peelTrailingColorName(label);
15550
+ if (shortcutColor) {
15551
+ metadata["color"] = shortcutColor;
15552
+ label = stripped;
15553
+ }
15554
+ }
15738
15555
  const color = metadata["color"];
15739
15556
  const spanStr = metadata["span"];
15740
15557
  let span = 1;
@@ -15905,7 +15722,7 @@ function parseJourneyMap(content, palette) {
15905
15722
  const warn = (line12, message) => {
15906
15723
  result.diagnostics.push(makeDgmoError(line12, message, "warning"));
15907
15724
  };
15908
- if (!content || !content.trim()) {
15725
+ if (!content?.trim()) {
15909
15726
  return fail(0, "No content provided");
15910
15727
  }
15911
15728
  const lines = content.split("\n");
@@ -15964,8 +15781,12 @@ function parseJourneyMap(content, palette) {
15964
15781
  const key = part.substring(0, colonIdx).trim().toLowerCase();
15965
15782
  const value = part.substring(colonIdx + 1).trim();
15966
15783
  if (key === "color") {
15967
- const resolved = extractColor(`x(${value})`, palette);
15968
- personaColor = resolved.color;
15784
+ personaColor = resolveColorWithDiagnostic(
15785
+ value,
15786
+ lineNumber,
15787
+ result.diagnostics,
15788
+ palette
15789
+ ) ?? void 0;
15969
15790
  }
15970
15791
  }
15971
15792
  }
@@ -16023,7 +15844,7 @@ function parseJourneyMap(content, palette) {
16023
15844
  if (!color) {
16024
15845
  warn(
16025
15846
  lineNumber,
16026
- `Expected 'Value(color)' in tag group '${currentTagGroup.name}'`
15847
+ `Expected 'Value color' in tag group '${currentTagGroup.name}'`
16027
15848
  );
16028
15849
  continue;
16029
15850
  }
@@ -16266,6 +16087,7 @@ var PHASE_RE, SCORE_RE, ANNOTATION_RE, KNOWN_OPTIONS9, KNOWN_BOOLEANS6;
16266
16087
  var init_parser16 = __esm({
16267
16088
  "src/journey-map/parser.ts"() {
16268
16089
  "use strict";
16090
+ init_colors();
16269
16091
  init_diagnostics();
16270
16092
  init_tag_groups();
16271
16093
  init_parsing();
@@ -16320,7 +16142,7 @@ function parsePyramid(content) {
16320
16142
  const indent = measureIndent(raw);
16321
16143
  if (!headerParsed) {
16322
16144
  const firstLineResult = parseFirstLine(trimmed);
16323
- if (firstLineResult && firstLineResult.chartType === "pyramid") {
16145
+ if (firstLineResult?.chartType === "pyramid") {
16324
16146
  result.title = firstLineResult.title ?? "";
16325
16147
  result.titleLineNumber = lineNum;
16326
16148
  headerParsed = true;
@@ -16364,6 +16186,13 @@ function parsePyramid(content) {
16364
16186
  warn(lineNum, "Empty layer label.");
16365
16187
  continue;
16366
16188
  }
16189
+ if (!color) {
16190
+ const { label: stripped, colorName: shortcutColor } = peelTrailingColorName(label);
16191
+ if (shortcutColor) {
16192
+ color = shortcutColor;
16193
+ label = stripped;
16194
+ }
16195
+ }
16367
16196
  currentLayer = {
16368
16197
  label,
16369
16198
  lineNumber: lineNum,
@@ -16447,7 +16276,7 @@ function parseRing(content) {
16447
16276
  const indent = measureIndent(raw);
16448
16277
  if (!headerParsed) {
16449
16278
  const firstLineResult = parseFirstLine(trimmed);
16450
- if (firstLineResult && firstLineResult.chartType === "ring") {
16279
+ if (firstLineResult?.chartType === "ring") {
16451
16280
  result.title = firstLineResult.title ?? "";
16452
16281
  result.titleLineNumber = lineNum;
16453
16282
  headerParsed = true;
@@ -16527,6 +16356,13 @@ function parseRing(content) {
16527
16356
  warn(lineNum, "Empty layer label.");
16528
16357
  continue;
16529
16358
  }
16359
+ if (!color) {
16360
+ const { label: stripped, colorName: shortcutColor } = peelTrailingColorName(label);
16361
+ if (shortcutColor) {
16362
+ color = shortcutColor;
16363
+ label = stripped;
16364
+ }
16365
+ }
16530
16366
  currentLayer = {
16531
16367
  label,
16532
16368
  lineNumber: lineNum,
@@ -16887,7 +16723,7 @@ function parseRaci(content, palette) {
16887
16723
  const errorAt = (line12, message, code) => {
16888
16724
  result.diagnostics.push(makeDgmoError(line12, message, "error", code));
16889
16725
  };
16890
- if (!content || !content.trim()) {
16726
+ if (!content?.trim()) {
16891
16727
  return fail(0, "No content provided");
16892
16728
  }
16893
16729
  const lines = content.split("\n");
@@ -17021,7 +16857,7 @@ function parseRaci(content, palette) {
17021
16857
  if (next.length > 0 && next[0] !== " " && next[0] !== " ") break;
17022
16858
  const stripped = nextTrim.replace(/,\s*$/, "");
17023
16859
  const segments = stripped.split("|").map((s) => s.trim());
17024
- const roleLabel = segments[0] ?? "";
16860
+ let roleLabel = segments[0] ?? "";
17025
16861
  let roleColor;
17026
16862
  if (segments.length > 1) {
17027
16863
  const meta = parsePipeMetadata(segments);
@@ -17034,6 +16870,18 @@ function parseRaci(content, palette) {
17034
16870
  );
17035
16871
  }
17036
16872
  }
16873
+ if (!roleColor) {
16874
+ const { label: stripLabel, colorName: shortcutColor } = peelTrailingColorName(roleLabel);
16875
+ if (shortcutColor) {
16876
+ roleColor = resolveColorWithDiagnostic(
16877
+ shortcutColor,
16878
+ j + 1,
16879
+ result.diagnostics,
16880
+ palette
16881
+ );
16882
+ roleLabel = stripLabel;
16883
+ }
16884
+ }
17037
16885
  if (roleLabel) getOrAddRole(roleLabel, j + 1, roleColor);
17038
16886
  }
17039
16887
  i = j - 1;
@@ -17092,8 +16940,10 @@ function parseRaci(content, palette) {
17092
16940
  continue;
17093
16941
  }
17094
16942
  let phaseColor;
17095
- if (phaseMatch[2]) {
17096
- const meta = parsePipeMetadata(["", phaseMatch[2]]);
16943
+ const trailingToken = phaseMatch[2];
16944
+ const pipeMeta = phaseMatch[3];
16945
+ if (pipeMeta) {
16946
+ const meta = parsePipeMetadata(["", pipeMeta]);
17097
16947
  if (meta["color"]) {
17098
16948
  phaseColor = resolveColorWithDiagnostic(
17099
16949
  meta["color"],
@@ -17103,6 +16953,17 @@ function parseRaci(content, palette) {
17103
16953
  );
17104
16954
  }
17105
16955
  }
16956
+ if (!phaseColor && trailingToken) {
16957
+ const { colorName } = peelTrailingColorName(`x ${trailingToken}`);
16958
+ if (colorName) {
16959
+ phaseColor = resolveColorWithDiagnostic(
16960
+ colorName,
16961
+ lineNumber,
16962
+ result.diagnostics,
16963
+ palette
16964
+ );
16965
+ }
16966
+ }
17106
16967
  currentPhase = {
17107
16968
  id: normalizeName(display),
17108
16969
  displayName: display,
@@ -17183,7 +17044,7 @@ function parseRaci(content, palette) {
17183
17044
  if (roleId === null) continue;
17184
17045
  if (rolesExplicit) {
17185
17046
  const entry = roleStore.get(roleId);
17186
- if (entry && entry.declaredLine === lineNumber) {
17047
+ if (entry?.declaredLine === lineNumber) {
17187
17048
  const candidates = result.roleDisplayNames.filter(
17188
17049
  (n) => n !== entry.displayName
17189
17050
  );
@@ -17333,7 +17194,7 @@ var init_parser19 = __esm({
17333
17194
  "no-title",
17334
17195
  ...Object.keys(VARIANT_LOCK_DIRECTIVES)
17335
17196
  ]);
17336
- PHASE_RE2 = /^\[(.+?)\]\s*(?:\|\s*(.+))?\s*$/;
17197
+ PHASE_RE2 = /^\[(.+?)\](?:\s+(\S+))?(?:\s*\|\s*(.+))?\s*$/;
17337
17198
  ROLE_ASSIGNMENT_RE = /^([^:]+):\s*(.*)$/;
17338
17199
  }
17339
17200
  });
@@ -19049,7 +18910,7 @@ function containerFill(palette, isDark, nodeColor2) {
19049
18910
  function containerStroke(palette, nodeColor2) {
19050
18911
  return nodeColor2 ?? palette.textMuted;
19051
18912
  }
19052
- function renderOrg(container, parsed, layout, palette, isDark, onClickItem, exportDims, activeTagGroup, hiddenAttributes, ancestorPath) {
18913
+ function renderOrg(container, parsed, layout, palette, isDark, onClickItem, exportDims, activeTagGroup, hiddenAttributes, ancestorPath, exportMode) {
19053
18914
  d3Selection.select(container).selectAll(":not([data-d3-tooltip])").remove();
19054
18915
  const width = exportDims?.width ?? container.clientWidth;
19055
18916
  const height = exportDims?.height ?? container.clientHeight;
@@ -19309,7 +19170,7 @@ function renderOrg(container, parsed, layout, palette, isDark, onClickItem, expo
19309
19170
  }
19310
19171
  ],
19311
19172
  position: { placement: "top-center", titleRelation: "below-title" },
19312
- mode: "fixed"
19173
+ mode: exportMode ? "export" : "preview"
19313
19174
  };
19314
19175
  const singleState = { activeGroup: lg.name };
19315
19176
  const groupG = legendParentBase.append("g").attr("transform", `translate(${lg.x}, ${lg.y})`);
@@ -19329,7 +19190,7 @@ function renderOrg(container, parsed, layout, palette, isDark, onClickItem, expo
19329
19190
  const legendConfig = {
19330
19191
  groups,
19331
19192
  position: { placement: "top-center", titleRelation: "below-title" },
19332
- mode: "fixed",
19193
+ mode: exportMode ? "export" : "preview",
19333
19194
  capsulePillAddonWidth: eyeAddonWidth
19334
19195
  };
19335
19196
  const legendState = { activeGroup: activeTagGroup ?? null };
@@ -19796,7 +19657,6 @@ function layoutSitemap(parsed, hiddenCounts, activeTagGroup, hiddenAttributes, e
19796
19657
  targetId: edge.targetId,
19797
19658
  points,
19798
19659
  label: edge.label,
19799
- color: edge.color,
19800
19660
  lineNumber: edge.lineNumber,
19801
19661
  deferred: deferredSet.has(i) || void 0
19802
19662
  });
@@ -20252,7 +20112,7 @@ function containerFill2(palette, isDark, nodeColor2) {
20252
20112
  function containerStroke2(palette, nodeColor2) {
20253
20113
  return nodeColor2 ?? palette.textMuted;
20254
20114
  }
20255
- function renderSitemap(container, parsed, layout, palette, isDark, onClickItem, exportDims, activeTagGroup, hiddenAttributes) {
20115
+ function renderSitemap(container, parsed, layout, palette, isDark, onClickItem, exportDims, activeTagGroup, hiddenAttributes, exportMode) {
20256
20116
  d3Selection2.select(container).selectAll(":not([data-d3-tooltip])").remove();
20257
20117
  const width = exportDims?.width ?? container.clientWidth;
20258
20118
  const height = exportDims?.height ?? container.clientHeight;
@@ -20283,9 +20143,6 @@ function renderSitemap(container, parsed, layout, palette, isDark, onClickItem,
20283
20143
  const defs = svg.append("defs");
20284
20144
  defs.append("marker").attr("id", "sm-arrow").attr("viewBox", `0 0 ${ARROWHEAD_W} ${ARROWHEAD_H}`).attr("refX", ARROWHEAD_W).attr("refY", ARROWHEAD_H / 2).attr("markerWidth", ARROWHEAD_W).attr("markerHeight", ARROWHEAD_H).attr("orient", "auto").append("polygon").attr("points", `0,0 ${ARROWHEAD_W},${ARROWHEAD_H / 2} 0,${ARROWHEAD_H}`).attr("fill", palette.textMuted);
20285
20145
  const edgeColors = /* @__PURE__ */ new Set();
20286
- for (const edge of layout.edges) {
20287
- if (edge.color) edgeColors.add(edge.color);
20288
- }
20289
20146
  for (const color of edgeColors) {
20290
20147
  const id = `sm-arrow-${color.replace("#", "")}`;
20291
20148
  defs.append("marker").attr("id", id).attr("viewBox", `0 0 ${ARROWHEAD_W} ${ARROWHEAD_H}`).attr("refX", ARROWHEAD_W).attr("refY", ARROWHEAD_H / 2).attr("markerWidth", ARROWHEAD_W).attr("markerHeight", ARROWHEAD_H).attr("orient", "auto").append("polygon").attr("points", `0,0 ${ARROWHEAD_W},${ARROWHEAD_H / 2} 0,${ARROWHEAD_H}`).attr("fill", color);
@@ -20364,8 +20221,8 @@ function renderSitemap(container, parsed, layout, palette, isDark, onClickItem,
20364
20221
  for (const edge of layout.edges) {
20365
20222
  if (edge.points.length < 2) continue;
20366
20223
  const edgeG = contentG.append("g").attr("class", "sitemap-edge-group").attr("data-line-number", String(edge.lineNumber));
20367
- const edgeColor3 = edge.color ?? palette.textMuted;
20368
- const markerId = edge.color ? `sm-arrow-${edge.color.replace("#", "")}` : "sm-arrow";
20224
+ const edgeColor3 = palette.textMuted;
20225
+ const markerId = "sm-arrow";
20369
20226
  const gen = edge.deferred ? lineGeneratorLinear : lineGenerator;
20370
20227
  const pathD = gen(edge.points);
20371
20228
  if (pathD) {
@@ -20446,7 +20303,8 @@ function renderSitemap(container, parsed, layout, palette, isDark, onClickItem,
20446
20303
  isDark,
20447
20304
  activeTagGroup,
20448
20305
  void 0,
20449
- hiddenAttributes
20306
+ hiddenAttributes,
20307
+ exportMode
20450
20308
  );
20451
20309
  }
20452
20310
  if (fixedTitle) {
@@ -20471,11 +20329,12 @@ function renderSitemap(container, parsed, layout, palette, isDark, onClickItem,
20471
20329
  isDark,
20472
20330
  activeTagGroup,
20473
20331
  width,
20474
- hiddenAttributes
20332
+ hiddenAttributes,
20333
+ exportMode
20475
20334
  );
20476
20335
  }
20477
20336
  }
20478
- function renderLegend(parent, legendGroups, palette, isDark, activeTagGroup, fixedWidth, hiddenAttributes) {
20337
+ function renderLegend(parent, legendGroups, palette, isDark, activeTagGroup, fixedWidth, hiddenAttributes, exportMode) {
20479
20338
  if (legendGroups.length === 0) return;
20480
20339
  const groups = legendGroups.map((g) => ({
20481
20340
  name: g.name,
@@ -20486,7 +20345,7 @@ function renderLegend(parent, legendGroups, palette, isDark, activeTagGroup, fix
20486
20345
  const legendConfig = {
20487
20346
  groups,
20488
20347
  position: { placement: "top-center", titleRelation: "below-title" },
20489
- mode: "fixed",
20348
+ mode: exportMode ? "export" : "preview",
20490
20349
  capsulePillAddonWidth: eyeAddonWidth
20491
20350
  };
20492
20351
  const legendState = { activeGroup: activeTagGroup ?? null };
@@ -20772,7 +20631,7 @@ function renderKanban(container, parsed, palette, isDark, options) {
20772
20631
  const legendConfig = {
20773
20632
  groups: parsed.tagGroups,
20774
20633
  position: { placement: "top-center", titleRelation: "inline-with-title" },
20775
- mode: exportDims ? "inline" : "fixed"
20634
+ mode: options?.exportMode ? "export" : "preview"
20776
20635
  };
20777
20636
  const legendState = { activeGroup: activeTagGroup ?? null };
20778
20637
  const legendG = svg.append("g").attr("class", "kanban-legend").attr("transform", `translate(${legendX},${legendY})`);
@@ -20930,7 +20789,8 @@ function renderKanbanForExport(content, theme, palette) {
20930
20789
  const layout = computeLayout(parsed, palette);
20931
20790
  const container = document.createElement("div");
20932
20791
  renderKanban(container, parsed, palette, isDark, {
20933
- exportDims: { width: layout.totalWidth, height: layout.totalHeight }
20792
+ exportDims: { width: layout.totalWidth, height: layout.totalHeight },
20793
+ exportMode: true
20934
20794
  });
20935
20795
  const svgEl = container.querySelector("svg");
20936
20796
  return svgEl?.outerHTML ?? "";
@@ -21468,7 +21328,7 @@ function markerIdForType(type) {
21468
21328
  function isSourceMarker(type) {
21469
21329
  return type === "composes" || type === "aggregates";
21470
21330
  }
21471
- function renderClassDiagram(container, parsed, layout, palette, isDark, onClickItem, exportDims, legendActive) {
21331
+ function renderClassDiagram(container, parsed, layout, palette, isDark, onClickItem, exportDims, legendActive, exportMode) {
21472
21332
  d3Selection4.select(container).selectAll(":not([data-d3-tooltip])").remove();
21473
21333
  const width = exportDims?.width ?? container.clientWidth;
21474
21334
  const height = exportDims?.height ?? container.clientHeight;
@@ -21530,7 +21390,7 @@ function renderClassDiagram(container, parsed, layout, palette, isDark, onClickI
21530
21390
  const legendConfig = {
21531
21391
  groups: legendGroups,
21532
21392
  position: { placement: "top-center", titleRelation: "below-title" },
21533
- mode: "fixed"
21393
+ mode: exportMode ? "export" : "preview"
21534
21394
  };
21535
21395
  const legendState = {
21536
21396
  activeGroup: isLegendExpanded ? LEGEND_GROUP_NAME : null
@@ -21670,10 +21530,22 @@ function renderClassDiagramForExport(content, theme, palette) {
21670
21530
  const exportWidth = layout.width + DIAGRAM_PADDING4 * 2;
21671
21531
  const exportHeight = layout.height + DIAGRAM_PADDING4 * 2 + (parsed.title ? 40 : 0) + legendReserve;
21672
21532
  return runInExportContainer(exportWidth, exportHeight, (container) => {
21673
- renderClassDiagram(container, parsed, layout, palette, isDark, void 0, {
21674
- width: exportWidth,
21675
- height: exportHeight
21676
- });
21533
+ renderClassDiagram(
21534
+ container,
21535
+ parsed,
21536
+ layout,
21537
+ palette,
21538
+ isDark,
21539
+ void 0,
21540
+ {
21541
+ width: exportWidth,
21542
+ height: exportHeight
21543
+ },
21544
+ true,
21545
+ // legendActive for export
21546
+ true
21547
+ // exportMode
21548
+ );
21677
21549
  return extractExportSvg(container, theme);
21678
21550
  });
21679
21551
  }
@@ -22149,7 +22021,7 @@ function drawCardinality(g, point, prevPoint, cardinality, color, useLabels) {
22149
22021
  g.append("line").attr("x1", bx + px * spread).attr("y1", by + py * spread).attr("x2", bx - px * spread).attr("y2", by - py * spread).attr("stroke", color).attr("stroke-width", sw);
22150
22022
  }
22151
22023
  }
22152
- function renderERDiagram(container, parsed, layout, palette, isDark, onClickItem, exportDims, activeTagGroup, semanticColorsActive) {
22024
+ function renderERDiagram(container, parsed, layout, palette, isDark, onClickItem, exportDims, activeTagGroup, semanticColorsActive, exportMode) {
22153
22025
  d3Selection5.select(container).selectAll(":not([data-d3-tooltip])").remove();
22154
22026
  const useSemanticColors = parsed.tagGroups.length === 0 && layout.nodes.every((n) => !n.color);
22155
22027
  const LEGEND_FIXED_GAP4 = 8;
@@ -22305,7 +22177,7 @@ function renderERDiagram(container, parsed, layout, palette, isDark, onClickItem
22305
22177
  const legendConfig = {
22306
22178
  groups: parsed.tagGroups,
22307
22179
  position: { placement: "top-center", titleRelation: "below-title" },
22308
- mode: "fixed"
22180
+ mode: exportMode ? "export" : "preview"
22309
22181
  };
22310
22182
  const legendState = { activeGroup: activeTagGroup ?? null };
22311
22183
  const legendG = svg.append("g").attr("class", "er-tag-legend").attr("transform", `translate(0,${legendY})`);
@@ -22341,7 +22213,7 @@ function renderERDiagram(container, parsed, layout, palette, isDark, onClickItem
22341
22213
  const legendConfig = {
22342
22214
  groups: semanticGroups,
22343
22215
  position: { placement: "top-center", titleRelation: "below-title" },
22344
- mode: "fixed"
22216
+ mode: exportMode ? "export" : "preview"
22345
22217
  };
22346
22218
  const legendState = {
22347
22219
  activeGroup: semanticActive ? "Role" : null
@@ -22374,10 +22246,21 @@ function renderERDiagramForExport(content, theme, palette) {
22374
22246
  container.style.left = "-9999px";
22375
22247
  document.body.appendChild(container);
22376
22248
  try {
22377
- renderERDiagram(container, parsed, layout, palette, isDark, void 0, {
22378
- width: exportWidth,
22379
- height: exportHeight
22380
- });
22249
+ renderERDiagram(
22250
+ container,
22251
+ parsed,
22252
+ layout,
22253
+ palette,
22254
+ isDark,
22255
+ void 0,
22256
+ {
22257
+ width: exportWidth,
22258
+ height: exportHeight
22259
+ },
22260
+ void 0,
22261
+ void 0,
22262
+ true
22263
+ );
22381
22264
  const svgEl = container.querySelector("svg");
22382
22265
  if (!svgEl) return "";
22383
22266
  if (theme === "transparent") {
@@ -22612,7 +22495,8 @@ function renderBoxesAndLines(container, parsed, layout, palette, isDark, options
22612
22495
  hideDescriptions,
22613
22496
  controlsExpanded,
22614
22497
  onToggleDescriptions,
22615
- onToggleControlsExpand
22498
+ onToggleControlsExpand,
22499
+ exportMode = false
22616
22500
  } = options ?? {};
22617
22501
  d3Selection6.select(container).selectAll(":not([data-d3-tooltip])").remove();
22618
22502
  const width = exportDims?.width ?? container.clientWidth;
@@ -22948,7 +22832,7 @@ function renderBoxesAndLines(container, parsed, layout, palette, isDark, options
22948
22832
  const legendConfig = {
22949
22833
  groups: parsed.tagGroups,
22950
22834
  position: { placement: "top-center", titleRelation: "below-title" },
22951
- mode: "fixed",
22835
+ mode: exportMode ? "export" : "preview",
22952
22836
  controlsGroup
22953
22837
  };
22954
22838
  const legendState = {
@@ -22980,7 +22864,8 @@ function renderBoxesAndLinesForExport(container, parsed, layout, palette, isDark
22980
22864
  renderBoxesAndLines(container, parsed, layout, palette, isDark, {
22981
22865
  exportDims: options?.exportDims,
22982
22866
  activeTagGroup: options?.activeTagGroup,
22983
- hiddenTagValues: options?.hiddenTagValues
22867
+ hiddenTagValues: options?.hiddenTagValues,
22868
+ exportMode: options?.exportMode
22984
22869
  });
22985
22870
  }
22986
22871
  var d3Selection6, d3Shape4, DIAGRAM_PADDING6, NODE_FONT_SIZE, MIN_NODE_FONT_SIZE, EDGE_LABEL_FONT_SIZE4, EDGE_STROKE_WIDTH5, NODE_STROKE_WIDTH5, NODE_RX, COLLAPSE_BAR_HEIGHT3, ARROWHEAD_W2, ARROWHEAD_H2, DESC_FONT_SIZE, DESC_LINE_HEIGHT, MAX_DESC_LINES, CHAR_WIDTH_RATIO2, NODE_TEXT_PADDING, GROUP_RX, GROUP_LABEL_FONT_SIZE, GROUP_LABEL_ZONE, lineGeneratorLR, lineGeneratorTB;
@@ -23440,8 +23325,7 @@ async function layoutBoxesAndLines(parsed, collapseInfo, layoutOptions) {
23440
23325
  const edge = parsed.edges[i];
23441
23326
  if (edgeParallelCounts[i] === 0) continue;
23442
23327
  const elkEdge = edgeById.get(`e${i}`);
23443
- if (!elkEdge || !elkEdge.sections || elkEdge.sections.length === 0)
23444
- continue;
23328
+ if (!elkEdge?.sections || elkEdge.sections.length === 0) continue;
23445
23329
  const container = elkEdge.container ?? "root";
23446
23330
  const off = containerAbs.get(container) ?? { x: 0, y: 0 };
23447
23331
  const s = elkEdge.sections[0];
@@ -24218,7 +24102,7 @@ function renderMindmap(container, parsed, layout, palette, isDark, onClickItem,
24218
24102
  };
24219
24103
  }),
24220
24104
  position: { placement: "top-center", titleRelation: "below-title" },
24221
- mode: "fixed",
24105
+ mode: options?.exportMode ? "export" : "preview",
24222
24106
  controlsGroup: controlsToggles
24223
24107
  };
24224
24108
  const legendState = {
@@ -27020,7 +26904,7 @@ function drawPersonIcon(g, cx, cy, color) {
27020
26904
  g.append("line").attr("x1", cx).attr("y1", bodyBottomY).attr("x2", cx - PERSON_LEG_SPAN).attr("y2", legY).attr("stroke", color).attr("stroke-width", PERSON_SW);
27021
26905
  g.append("line").attr("x1", cx).attr("y1", bodyBottomY).attr("x2", cx + PERSON_LEG_SPAN).attr("y2", legY).attr("stroke", color).attr("stroke-width", PERSON_SW);
27022
26906
  }
27023
- function renderC4Context(container, parsed, layout, palette, isDark, onClickItem, exportDims, activeTagGroup) {
26907
+ function renderC4Context(container, parsed, layout, palette, isDark, onClickItem, exportDims, activeTagGroup, exportMode) {
27024
26908
  d3Selection9.select(container).selectAll(":not([data-d3-tooltip])").remove();
27025
26909
  const width = exportDims?.width ?? container.clientWidth;
27026
26910
  const height = exportDims?.height ?? container.clientHeight;
@@ -27196,7 +27080,8 @@ function renderC4Context(container, parsed, layout, palette, isDark, onClickItem
27196
27080
  palette,
27197
27081
  isDark,
27198
27082
  activeTagGroup,
27199
- fixedLegend ? width : null
27083
+ fixedLegend ? width : null,
27084
+ exportMode
27200
27085
  );
27201
27086
  }
27202
27087
  }
@@ -27551,7 +27436,7 @@ function placeEdgeLabels(labels, edges, obstacleRects) {
27551
27436
  placedRects.push({ x: lbl.x, y: lbl.y, w: lbl.bgW, h: lbl.bgH });
27552
27437
  }
27553
27438
  }
27554
- function renderLegend2(parent, layout, palette, isDark, activeTagGroup, fixedWidth) {
27439
+ function renderLegend2(parent, layout, palette, isDark, activeTagGroup, fixedWidth, exportMode) {
27555
27440
  const groups = layout.legend.map((g) => ({
27556
27441
  name: g.name,
27557
27442
  entries: g.entries.map((e) => ({ value: e.value, color: e.color }))
@@ -27559,7 +27444,7 @@ function renderLegend2(parent, layout, palette, isDark, activeTagGroup, fixedWid
27559
27444
  const legendConfig = {
27560
27445
  groups,
27561
27446
  position: { placement: "top-center", titleRelation: "below-title" },
27562
- mode: "fixed"
27447
+ mode: exportMode ? "export" : "preview"
27563
27448
  };
27564
27449
  const legendState = { activeGroup: activeTagGroup ?? null };
27565
27450
  const containerWidth = fixedWidth ?? layout.width;
@@ -27574,7 +27459,7 @@ function renderLegend2(parent, layout, palette, isDark, activeTagGroup, fixedWid
27574
27459
  );
27575
27460
  parent.selectAll("[data-legend-group]").classed("c4-legend-group", true);
27576
27461
  }
27577
- function renderC4Containers(container, parsed, layout, palette, isDark, onClickItem, exportDims, activeTagGroup) {
27462
+ function renderC4Containers(container, parsed, layout, palette, isDark, onClickItem, exportDims, activeTagGroup, exportMode) {
27578
27463
  d3Selection9.select(container).selectAll(":not([data-d3-tooltip])").remove();
27579
27464
  const width = exportDims?.width ?? container.clientWidth;
27580
27465
  const height = exportDims?.height ?? container.clientHeight;
@@ -27805,7 +27690,8 @@ function renderC4Containers(container, parsed, layout, palette, isDark, onClickI
27805
27690
  palette,
27806
27691
  isDark,
27807
27692
  activeTagGroup,
27808
- fixedLegend ? width : null
27693
+ fixedLegend ? width : null,
27694
+ exportMode
27809
27695
  );
27810
27696
  }
27811
27697
  }
@@ -27873,7 +27759,7 @@ function renderC4ComponentsForExport(content, systemName, containerName, theme,
27873
27759
  document.body.removeChild(el);
27874
27760
  }
27875
27761
  }
27876
- function renderC4Deployment(container, parsed, layout, palette, isDark, onClickItem, exportDims, activeTagGroup) {
27762
+ function renderC4Deployment(container, parsed, layout, palette, isDark, onClickItem, exportDims, activeTagGroup, exportMode) {
27877
27763
  renderC4Containers(
27878
27764
  container,
27879
27765
  parsed,
@@ -27882,7 +27768,8 @@ function renderC4Deployment(container, parsed, layout, palette, isDark, onClickI
27882
27768
  isDark,
27883
27769
  onClickItem,
27884
27770
  exportDims,
27885
- activeTagGroup
27771
+ activeTagGroup,
27772
+ exportMode
27886
27773
  );
27887
27774
  }
27888
27775
  function renderC4DeploymentForExport(content, theme, palette) {
@@ -28064,7 +27951,6 @@ function layoutGraph(graph, options) {
28064
27951
  target: edge.target,
28065
27952
  points: edgeData?.points ?? [],
28066
27953
  label: edge.label,
28067
- color: edge.color,
28068
27954
  lineNumber: edge.lineNumber
28069
27955
  };
28070
27956
  });
@@ -28365,6 +28251,8 @@ function renderNodeShape(g, node, palette, isDark, endTerminalIds, colorOff, sol
28365
28251
  case "document":
28366
28252
  renderDocument(g, node, palette, isDark, colorOff, solid);
28367
28253
  break;
28254
+ default:
28255
+ break;
28368
28256
  }
28369
28257
  }
28370
28258
  function renderFlowchart(container, graph, layout, palette, isDark, onClickItem, exportDims) {
@@ -28387,9 +28275,6 @@ function renderFlowchart(container, graph, layout, palette, isDark, onClickItem,
28387
28275
  const defs = svg.append("defs");
28388
28276
  defs.append("marker").attr("id", "fc-arrow").attr("viewBox", `0 0 ${ARROWHEAD_W3} ${ARROWHEAD_H3}`).attr("refX", ARROWHEAD_W3).attr("refY", ARROWHEAD_H3 / 2).attr("markerWidth", ARROWHEAD_W3).attr("markerHeight", ARROWHEAD_H3).attr("orient", "auto").append("polygon").attr("points", `0,0 ${ARROWHEAD_W3},${ARROWHEAD_H3 / 2} 0,${ARROWHEAD_H3}`).attr("fill", palette.textMuted);
28389
28277
  const edgeColors = /* @__PURE__ */ new Set();
28390
- for (const edge of layout.edges) {
28391
- if (edge.color) edgeColors.add(edge.color);
28392
- }
28393
28278
  for (const color of edgeColors) {
28394
28279
  const id = `fc-arrow-${color.replace("#", "")}`;
28395
28280
  defs.append("marker").attr("id", id).attr("viewBox", `0 0 ${ARROWHEAD_W3} ${ARROWHEAD_H3}`).attr("refX", ARROWHEAD_W3).attr("refY", ARROWHEAD_H3 / 2).attr("markerWidth", ARROWHEAD_W3).attr("markerHeight", ARROWHEAD_H3).attr("orient", "auto").append("polygon").attr("points", `0,0 ${ARROWHEAD_W3},${ARROWHEAD_H3 / 2} 0,${ARROWHEAD_H3}`).attr("fill", color);
@@ -28453,8 +28338,8 @@ function renderFlowchart(container, graph, layout, palette, isDark, onClickItem,
28453
28338
  const edge = layout.edges[ei];
28454
28339
  if (edge.points.length < 2) continue;
28455
28340
  const edgeG = contentG.append("g").attr("class", "fc-edge-group").attr("data-line-number", String(edge.lineNumber));
28456
- const edgeColor3 = edge.color ?? palette.textMuted;
28457
- const markerId = edge.color ? `fc-arrow-${edge.color.replace("#", "")}` : "fc-arrow";
28341
+ const edgeColor3 = palette.textMuted;
28342
+ const markerId = "fc-arrow";
28458
28343
  const pathD = lineGenerator5(edge.points);
28459
28344
  if (pathD) {
28460
28345
  edgeG.append("path").attr("d", pathD).attr("fill", "none").attr("stroke", edgeColor3).attr("stroke-width", EDGE_STROKE_WIDTH8).attr("marker-end", `url(#${markerId})`).attr("class", "fc-edge");
@@ -30938,7 +30823,7 @@ function renderNodes(svg, nodes, palette, isDark, animate, expandedNodeIds, acti
30938
30823
  const badgeText = `${node.computedInstances}x`;
30939
30824
  g.append("text").attr("x", x + node.width - 6).attr("y", y + NODE_HEADER_HEIGHT2 / 2 + META_FONT_SIZE4 * 0.35).attr("text-anchor", "end").attr("font-family", FONT_FAMILY).attr("font-size", META_FONT_SIZE4).attr("fill", textFill).attr("data-instance-node", node.id).style("cursor", "pointer").text(badgeText);
30940
30825
  }
30941
- const showDots = activeGroup != null && activeGroup.toLowerCase() === "capabilities";
30826
+ const showDots = activeGroup?.toLowerCase() === "capabilities";
30942
30827
  const roles = showDots && !node.isEdge ? inferRoles(node.properties) : [];
30943
30828
  if (roles.length > 0) {
30944
30829
  const dotY = isCollapsedGroup ? y + node.height - COLLAPSE_BAR_HEIGHT6 - NODE_PAD_BOTTOM2 / 2 : y + node.height - NODE_PAD_BOTTOM2 / 2;
@@ -31078,7 +30963,7 @@ function computeInfraLegendGroups(nodes, tagGroups, palette, edges) {
31078
30963
  }
31079
30964
  return groups;
31080
30965
  }
31081
- function renderLegend3(rootSvg, legendGroups, totalWidth, legendY, palette, isDark, activeGroup, playback) {
30966
+ function renderLegend3(rootSvg, legendGroups, totalWidth, legendY, palette, isDark, activeGroup, playback, exportMode = false) {
31082
30967
  if (legendGroups.length === 0 && !playback) return;
31083
30968
  const legendG = rootSvg.append("g").attr("transform", `translate(0, ${legendY})`);
31084
30969
  if (activeGroup) {
@@ -31094,7 +30979,7 @@ function renderLegend3(rootSvg, legendGroups, totalWidth, legendY, palette, isDa
31094
30979
  const legendConfig = {
31095
30980
  groups: allGroups,
31096
30981
  position: { placement: "top-center", titleRelation: "below-title" },
31097
- mode: "fixed",
30982
+ mode: exportMode ? "export" : "preview",
31098
30983
  showEmptyGroups: true
31099
30984
  };
31100
30985
  const legendState = { activeGroup };
@@ -31282,7 +31167,8 @@ function renderInfra(container, layout, palette, isDark, title, titleLineNumber,
31282
31167
  palette,
31283
31168
  isDark,
31284
31169
  activeGroup ?? null,
31285
- playback ?? void 0
31170
+ playback ?? void 0,
31171
+ exportMode
31286
31172
  );
31287
31173
  legendSvg.selectAll(".infra-legend-group").style("pointer-events", "auto");
31288
31174
  } else {
@@ -31294,7 +31180,8 @@ function renderInfra(container, layout, palette, isDark, title, titleLineNumber,
31294
31180
  palette,
31295
31181
  isDark,
31296
31182
  activeGroup ?? null,
31297
- playback ?? void 0
31183
+ playback ?? void 0,
31184
+ exportMode
31298
31185
  );
31299
31186
  }
31300
31187
  }
@@ -31735,7 +31622,7 @@ function analyzePert(parsed) {
31735
31622
  for (const e of edges) {
31736
31623
  if (!e.lag || e.lag.amount >= 0) continue;
31737
31624
  const src = activities.find((a) => a.id === e.source);
31738
- if (!src || !src.duration) continue;
31625
+ if (!src?.duration) continue;
31739
31626
  const leadDays = -toDays(e.lag, sprintDays);
31740
31627
  const srcDurDays = toDays(src.duration.m, sprintDays);
31741
31628
  if (e.type === "FS" && leadDays > srcDurDays) {
@@ -32241,7 +32128,7 @@ function buildSummary(input) {
32241
32128
  const anchor = input.anchor ?? null;
32242
32129
  if (parsedActivities.length === 0) return null;
32243
32130
  if (projectMu === null) {
32244
- if (anchor && anchor.kind === "backward") {
32131
+ if (anchor?.kind === "backward") {
32245
32132
  return [
32246
32133
  { text: "Expected duration: ?", level: 0 },
32247
32134
  { text: "P50 latest-safe start: ?", level: 0 },
@@ -32264,13 +32151,13 @@ function buildSummary(input) {
32264
32151
  const sigmaPositive = projectSigma !== null && projectSigma > 0;
32265
32152
  const showMcDetail = mc && sigmaPositive;
32266
32153
  const sigmaParen = showMcDetail ? ` (\xB1 ${roundForCaption(projectSigma)} ${pluralizeUnit(projectSigma, unit)})` : "";
32267
- if (anchor && anchor.kind === "forward") {
32154
+ if (anchor?.kind === "forward") {
32268
32155
  const projectMuDays = projectMu * unitToDays(unit);
32269
32156
  rows.push({
32270
32157
  text: `Expected finish: ${addCalendarDays(anchor.date, projectMuDays)}${sigmaParen}.`,
32271
32158
  level: 0
32272
32159
  });
32273
- } else if (anchor && anchor.kind === "backward") {
32160
+ } else if (anchor?.kind === "backward") {
32274
32161
  const projectMuDays = projectMu * unitToDays(unit);
32275
32162
  rows.push({
32276
32163
  text: `Expected start: ${addCalendarDays(anchor.date, -projectMuDays)}${sigmaParen}.`,
@@ -32289,13 +32176,13 @@ function buildSummary(input) {
32289
32176
  { pct: 80, days: monteCarloResult.p80 },
32290
32177
  { pct: 95, days: monteCarloResult.p95 }
32291
32178
  ];
32292
- if (anchor && anchor.kind === "forward") {
32179
+ if (anchor?.kind === "forward") {
32293
32180
  for (const { pct, days } of percentiles) {
32294
32181
  const offsetDays = roundConservative(days, "forward");
32295
32182
  const date = addCalendarDays(anchor.date, offsetDays);
32296
32183
  rows.push({ text: `P${pct} finish: ${date}.`, level: 1 });
32297
32184
  }
32298
- } else if (anchor && anchor.kind === "backward") {
32185
+ } else if (anchor?.kind === "backward") {
32299
32186
  for (const { pct, days } of percentiles) {
32300
32187
  const offsetDays = roundConservative(days, "backward");
32301
32188
  const date = addCalendarDays(anchor.date, -offsetDays);
@@ -32339,20 +32226,20 @@ function buildProjectSubtitle(input) {
32339
32226
  const sigmaPositive = projectSigma !== null && projectSigma > 0;
32340
32227
  const sigmaParen = sigmaPositive ? ` (\xB1 ${roundForCaption(projectSigma)})` : "";
32341
32228
  if (projectMu === null) {
32342
- if (anchor && anchor.kind === "forward") {
32229
+ if (anchor?.kind === "forward") {
32343
32230
  return `Expected finish: ? \xB7 \u2248 ? ${pluralizeUnit(2, unit)} of work`;
32344
32231
  }
32345
- if (anchor && anchor.kind === "backward") {
32232
+ if (anchor?.kind === "backward") {
32346
32233
  return `Expected start: ? \xB7 \u2248 ? ${pluralizeUnit(2, unit)} lead time`;
32347
32234
  }
32348
32235
  return `\u2248 ? ${pluralizeUnit(2, unit)}`;
32349
32236
  }
32350
32237
  const muStr = `${roundForCaption(projectMu)} ${pluralizeUnit(projectMu, unit)}`;
32351
- if (anchor && anchor.kind === "forward") {
32238
+ if (anchor?.kind === "forward") {
32352
32239
  const projectMuDays = projectMu * unitToDays(unit);
32353
32240
  return `Expected finish: ${addCalendarDays(anchor.date, projectMuDays)} \xB7 \u2248 ${muStr} of work${sigmaParen}`;
32354
32241
  }
32355
- if (anchor && anchor.kind === "backward") {
32242
+ if (anchor?.kind === "backward") {
32356
32243
  const projectMuDays = projectMu * unitToDays(unit);
32357
32244
  return `Expected start: ${addCalendarDays(anchor.date, -projectMuDays)} \xB7 \u2248 ${muStr} lead time${sigmaParen}`;
32358
32245
  }
@@ -32542,7 +32429,7 @@ function computeNodeSizing(resolved) {
32542
32429
  return { activityWidth, milestoneWidth, outerColW, midColW };
32543
32430
  }
32544
32431
  function nodeDimensions(resolved, id, sizing, overrides) {
32545
- if (overrides && overrides[id]) {
32432
+ if (overrides?.[id]) {
32546
32433
  return { width: overrides[id].width, height: overrides[id].height };
32547
32434
  }
32548
32435
  const r = resolved.activities.find((a) => a.activity.id === id);
@@ -33193,7 +33080,8 @@ function renderPert(container, resolved, layout, palette, isDark, options = {})
33193
33080
  x: 0,
33194
33081
  y: tagLegendY,
33195
33082
  width: exportWidth,
33196
- activeGroup: tagLegendActive
33083
+ activeGroup: tagLegendActive,
33084
+ exportMode: options.exportMode
33197
33085
  });
33198
33086
  }
33199
33087
  const root = svg.append("g").attr("transform", `translate(${offsetX}, ${offsetY})`);
@@ -33254,7 +33142,8 @@ function renderPertForExport(content, theme, palette, now) {
33254
33142
  renderPert(container, resolved, layout, palette, isDark, {
33255
33143
  title: hasTitle ? parsed.title : null,
33256
33144
  subtitle: resolved.projectSubtitle,
33257
- exportDims: { width: exportWidth, height: exportHeight }
33145
+ exportDims: { width: exportWidth, height: exportHeight },
33146
+ exportMode: true
33258
33147
  });
33259
33148
  const svgEl = container.querySelector("svg");
33260
33149
  if (!svgEl) return "";
@@ -34341,7 +34230,7 @@ function renderLegendBlock(svg, entries, args) {
34341
34230
  }
34342
34231
  function renderTagLegendRow(svg, resolved, palette, isDark, args) {
34343
34232
  if (resolved.tagGroups.length === 0) return;
34344
- const { x, y, width, activeGroup } = args;
34233
+ const { x, y, width, activeGroup, exportMode } = args;
34345
34234
  const groups = resolved.tagGroups.map((g) => ({
34346
34235
  name: g.name,
34347
34236
  entries: g.entries.map((e) => ({ value: e.value, color: e.color }))
@@ -34352,7 +34241,7 @@ function renderTagLegendRow(svg, resolved, palette, isDark, args) {
34352
34241
  {
34353
34242
  groups,
34354
34243
  position: { placement: "top-center", titleRelation: "below-title" },
34355
- mode: "fixed"
34244
+ mode: exportMode ? "export" : "preview"
34356
34245
  },
34357
34246
  { activeGroup },
34358
34247
  palette,
@@ -35792,7 +35681,8 @@ function renderGantt(container, resolved, palette, isDark, options, exportDims)
35792
35681
  ).attr("display", active ? null : "none");
35793
35682
  }
35794
35683
  drawLegend();
35795
- }
35684
+ },
35685
+ options?.exportMode ?? false
35796
35686
  );
35797
35687
  }
35798
35688
  }
@@ -36581,7 +36471,7 @@ function buildControlsToggles(hasCriticalPath, criticalPathActive, hasDependenci
36581
36471
  }
36582
36472
  return toggles;
36583
36473
  }
36584
- function renderTagLegend(svg, chartG, tagGroups, activeGroupName, chartLeftMargin, chartInnerWidth, legendY, palette, isDark, hasCriticalPath, criticalPathActive, _optionLineNumbers, onToggle, onToggleControlsExpand, currentSwimlaneGroup, onSwimlaneChange, legendViewMode, resolvedTasks, controlsExpanded = false, hasDependencies = false, dependenciesActive = false, onControlsToggle) {
36474
+ function renderTagLegend(svg, chartG, tagGroups, activeGroupName, chartLeftMargin, chartInnerWidth, legendY, palette, isDark, hasCriticalPath, criticalPathActive, _optionLineNumbers, onToggle, onToggleControlsExpand, currentSwimlaneGroup, onSwimlaneChange, legendViewMode, resolvedTasks, controlsExpanded = false, hasDependencies = false, dependenciesActive = false, onControlsToggle, exportMode = false) {
36585
36475
  let visibleGroups;
36586
36476
  if (activeGroupName) {
36587
36477
  const activeGroup = tagGroups.filter(
@@ -36676,7 +36566,7 @@ function renderTagLegend(svg, chartG, tagGroups, activeGroupName, chartLeftMargi
36676
36566
  placement: "top-center",
36677
36567
  titleRelation: "below-title"
36678
36568
  },
36679
- mode: "fixed",
36569
+ mode: exportMode ? "export" : "preview",
36680
36570
  capsulePillAddonWidth: iconReserve,
36681
36571
  controlsGroup: controlsToggles.length > 0 ? { toggles: controlsToggles } : void 0
36682
36572
  };
@@ -36783,7 +36673,7 @@ function renderTagLegend(svg, chartG, tagGroups, activeGroupName, chartLeftMargi
36783
36673
  placement: "top-center",
36784
36674
  titleRelation: "below-title"
36785
36675
  },
36786
- mode: "fixed",
36676
+ mode: exportMode ? "export" : "preview",
36787
36677
  controlsGroup: { toggles: controlsToggles }
36788
36678
  };
36789
36679
  const tagGroupG = legendRow.append("g");
@@ -37666,9 +37556,6 @@ function renderState(container, graph, layout, palette, isDark, onClickItem, exp
37666
37556
  const defs = svg.append("defs");
37667
37557
  defs.append("marker").attr("id", "st-arrow").attr("viewBox", `0 0 ${ARROWHEAD_W5} ${ARROWHEAD_H5}`).attr("refX", ARROWHEAD_W5).attr("refY", ARROWHEAD_H5 / 2).attr("markerWidth", ARROWHEAD_W5).attr("markerHeight", ARROWHEAD_H5).attr("orient", "auto").append("polygon").attr("points", `0,0 ${ARROWHEAD_W5},${ARROWHEAD_H5 / 2} 0,${ARROWHEAD_H5}`).attr("fill", palette.textMuted);
37668
37558
  const edgeColors = /* @__PURE__ */ new Set();
37669
- for (const edge of layout.edges) {
37670
- if (edge.color) edgeColors.add(edge.color);
37671
- }
37672
37559
  for (const color of edgeColors) {
37673
37560
  const id = `st-arrow-${color.replace("#", "")}`;
37674
37561
  defs.append("marker").attr("id", id).attr("viewBox", `0 0 ${ARROWHEAD_W5} ${ARROWHEAD_H5}`).attr("refX", ARROWHEAD_W5).attr("refY", ARROWHEAD_H5 / 2).attr("markerWidth", ARROWHEAD_W5).attr("markerHeight", ARROWHEAD_H5).attr("orient", "auto").append("polygon").attr("points", `0,0 ${ARROWHEAD_W5},${ARROWHEAD_H5 / 2} 0,${ARROWHEAD_H5}`).attr("fill", color);
@@ -37763,8 +37650,8 @@ function renderState(container, graph, layout, palette, isDark, onClickItem, exp
37763
37650
  for (let ei = 0; ei < layout.edges.length; ei++) {
37764
37651
  const edge = layout.edges[ei];
37765
37652
  const edgeG = contentG.append("g").attr("class", "st-edge-group").attr("data-line-number", String(edge.lineNumber));
37766
- const edgeColor3 = edge.color ?? palette.textMuted;
37767
- const markerId = edge.color ? `st-arrow-${edge.color.replace("#", "")}` : "st-arrow";
37653
+ const edgeColor3 = palette.textMuted;
37654
+ const markerId = "st-arrow";
37768
37655
  if (edge.source === edge.target) {
37769
37656
  const node = nodePositionMap.get(edge.source);
37770
37657
  if (node) {
@@ -38634,7 +38521,7 @@ function renderTechRadar(container, parsed, palette, isDark, onClickItem, export
38634
38521
  }
38635
38522
  ],
38636
38523
  position: { placement: "top-center", titleRelation: "below-title" },
38637
- mode: "fixed",
38524
+ mode: options?.exportMode ? "export" : "preview",
38638
38525
  controlsGroup: {
38639
38526
  toggles: [
38640
38527
  {
@@ -39237,7 +39124,7 @@ function getQuadrantLabelPosition(position, cx, cy, maxRadius) {
39237
39124
  };
39238
39125
  }
39239
39126
  }
39240
- function renderTechRadarForExport(container, parsed, palette, isDark, exportDims, viewState) {
39127
+ function renderTechRadarForExport(container, parsed, palette, isDark, exportDims, viewState, exportMode) {
39241
39128
  renderTechRadar(
39242
39129
  container,
39243
39130
  parsed,
@@ -39245,7 +39132,8 @@ function renderTechRadarForExport(container, parsed, palette, isDark, exportDims
39245
39132
  isDark,
39246
39133
  void 0,
39247
39134
  exportDims,
39248
- viewState
39135
+ viewState,
39136
+ { exportMode }
39249
39137
  );
39250
39138
  }
39251
39139
  var d3Selection16, BLIP_RADIUS2, BLIP_FONT_SIZE2, RING_LABEL_FONT_SIZE, QUADRANT_LABEL_FONT_SIZE, TITLE_FONT_SIZE3, LISTING_FONT_SIZE, LISTING_HEADER_FONT_SIZE, LISTING_TOP_MARGIN, LISTING_COL_GAP, LISTING_LINE_HEIGHT, LISTING_BLIP_R;
@@ -39624,7 +39512,7 @@ function renderJourneyMap(container, parsed, palette, isDark, options) {
39624
39512
  titleRelation: "inline-with-title"
39625
39513
  },
39626
39514
  titleWidth: 0,
39627
- mode: exportDims ? "inline" : "fixed"
39515
+ mode: options?.exportMode ? "export" : "preview"
39628
39516
  };
39629
39517
  const legendState = { activeGroup: effectiveActiveGroup };
39630
39518
  const legendCallbacks = {
@@ -40337,7 +40225,8 @@ function renderJourneyMapForExport(content, theme, palette) {
40337
40225
  const layout = layoutJourneyMap(parsed, palette, { isDark });
40338
40226
  const container = document.createElement("div");
40339
40227
  renderJourneyMap(container, parsed, palette, isDark, {
40340
- exportDims: { width: layout.totalWidth, height: layout.totalHeight }
40228
+ exportDims: { width: layout.totalWidth, height: layout.totalHeight },
40229
+ exportMode: true
40341
40230
  });
40342
40231
  const svgEl = container.querySelector("svg");
40343
40232
  if (!svgEl) return "";
@@ -41103,7 +40992,7 @@ function renderCycle(container, parsed, palette, isDark, onClickItem, exportDims
41103
40992
  const legendConfig = {
41104
40993
  groups: [],
41105
40994
  position: { placement: "top-center", titleRelation: "below-title" },
41106
- mode: "fixed",
40995
+ mode: renderOptions?.exportMode ? "export" : "preview",
41107
40996
  controlsGroup
41108
40997
  };
41109
40998
  const legendState = {
@@ -41287,7 +41176,7 @@ function renderCycle(container, parsed, palette, isDark, onClickItem, exportDims
41287
41176
  }
41288
41177
  }
41289
41178
  }
41290
- function renderCycleForExport(container, parsed, palette, isDark, exportDims, viewState) {
41179
+ function renderCycleForExport(container, parsed, palette, isDark, exportDims, viewState, exportMode) {
41291
41180
  renderCycle(
41292
41181
  container,
41293
41182
  parsed,
@@ -41295,7 +41184,8 @@ function renderCycleForExport(container, parsed, palette, isDark, exportDims, vi
41295
41184
  isDark,
41296
41185
  void 0,
41297
41186
  exportDims,
41298
- viewState
41187
+ viewState,
41188
+ { exportMode }
41299
41189
  );
41300
41190
  }
41301
41191
  function resolveNodeColor5(color, palette, defaultColor) {
@@ -42925,9 +42815,6 @@ function wrapLabelWords(words) {
42925
42815
  function renderRectParticipant(g, palette, isDark, color, solid) {
42926
42816
  g.append("rect").attr("x", -W / 2).attr("y", 0).attr("width", W).attr("height", H).attr("rx", 2).attr("ry", 2).attr("fill", fill(palette, isDark, color, solid)).attr("stroke", stroke(palette, color)).attr("stroke-width", SW);
42927
42817
  }
42928
- function renderServiceParticipant(g, palette, isDark, color, solid) {
42929
- g.append("rect").attr("x", -W / 2).attr("y", 0).attr("width", W).attr("height", H).attr("rx", SERVICE_BORDER_RADIUS).attr("ry", SERVICE_BORDER_RADIUS).attr("fill", fill(palette, isDark, color, solid)).attr("stroke", stroke(palette, color)).attr("stroke-width", SW);
42930
- }
42931
42818
  function renderActorParticipant(g, palette, color) {
42932
42819
  const headR = 8;
42933
42820
  const cx = 0;
@@ -42982,31 +42869,6 @@ function renderCacheParticipant(g, palette, isDark, color, solid) {
42982
42869
  g.append("line").attr("x1", W / 2).attr("y1", topY).attr("x2", W / 2).attr("y2", topY + bodyH).attr("stroke", s).attr("stroke-width", SW).attr("stroke-dasharray", dash);
42983
42870
  g.append("ellipse").attr("cx", 0).attr("cy", topY).attr("rx", W / 2).attr("ry", ry).attr("fill", f).attr("stroke", s).attr("stroke-width", SW).attr("stroke-dasharray", dash);
42984
42871
  }
42985
- function renderNetworkingParticipant(g, palette, isDark, color, solid) {
42986
- const inset = 16;
42987
- const points = [
42988
- `${-W / 2 + inset},0`,
42989
- `${W / 2 - inset},0`,
42990
- `${W / 2},${H / 2}`,
42991
- `${W / 2 - inset},${H}`,
42992
- `${-W / 2 + inset},${H}`,
42993
- `${-W / 2},${H / 2}`
42994
- ].join(" ");
42995
- g.append("polygon").attr("points", points).attr("fill", fill(palette, isDark, color, solid)).attr("stroke", stroke(palette, color)).attr("stroke-width", SW);
42996
- }
42997
- function renderFrontendParticipant(g, palette, isDark, color, solid) {
42998
- const screenH = H - 10;
42999
- const s = stroke(palette, color);
43000
- g.append("rect").attr("x", -W / 2).attr("y", 0).attr("width", W).attr("height", screenH).attr("rx", 3).attr("ry", 3).attr("fill", fill(palette, isDark, color, solid)).attr("stroke", s).attr("stroke-width", SW);
43001
- g.append("line").attr("x1", 0).attr("y1", screenH).attr("x2", 0).attr("y2", H - 2).attr("stroke", s).attr("stroke-width", SW);
43002
- g.append("line").attr("x1", -14).attr("y1", H - 2).attr("x2", 14).attr("y2", H - 2).attr("stroke", s).attr("stroke-width", SW);
43003
- }
43004
- function renderExternalParticipant(g, palette, isDark, color, solid) {
43005
- g.append("rect").attr("x", -W / 2).attr("y", 0).attr("width", W).attr("height", H).attr("rx", 2).attr("ry", 2).attr("fill", fill(palette, isDark, color, solid)).attr("stroke", stroke(palette, color)).attr("stroke-width", SW).attr("stroke-dasharray", "6 3");
43006
- }
43007
- function renderGatewayParticipant(g, palette, isDark, color, _solid) {
43008
- renderRectParticipant(g, palette, isDark, color);
43009
- }
43010
42872
  function groupMessagesBySection(elements, messages) {
43011
42873
  const groups = [];
43012
42874
  let currentGroup = null;
@@ -43645,7 +43507,7 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
43645
43507
  }
43646
43508
  }
43647
43509
  const lastStep = renderSteps[renderSteps.length - 1];
43648
- const lastIsSelfCall = lastStep && lastStep.type === "call" && lastStep.from === lastStep.to;
43510
+ const lastIsSelfCall = lastStep?.type === "call" && lastStep.from === lastStep.to;
43649
43511
  const lastStepTrailing = lastIsSelfCall ? SELF_CALL_HEIGHT + 25 : stepSpacing;
43650
43512
  let contentBottomY = renderSteps.length > 0 ? Math.max(
43651
43513
  stepYPositions[stepYPositions.length - 1] + lastStepTrailing,
@@ -43819,6 +43681,9 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
43819
43681
  const FRAME_PADDING_X = 30;
43820
43682
  const FRAME_PADDING_BOTTOM = 15;
43821
43683
  const FRAME_LABEL_HEIGHT = 18;
43684
+ const SELF_ARROW_PROJECTION = ACTIVATION_WIDTH / 2 + SELF_CALL_WIDTH;
43685
+ const SELF_ARROW_FRAME_PAD = 10;
43686
+ const frameRightmostX = Math.max(...Array.from(participantX.values()));
43822
43687
  const collectMsgIndices = (els) => {
43823
43688
  const indices = [];
43824
43689
  for (const el of els) {
@@ -43885,16 +43750,40 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
43885
43750
  maxPX = Math.max(maxPX, px);
43886
43751
  }
43887
43752
  }
43888
- const frameX = minPX - FRAME_PADDING_X;
43753
+ let extraLeft = 0;
43754
+ let extraRight = 0;
43755
+ let maxStepIsSelfCall = false;
43756
+ for (const mi of allIndices) {
43757
+ const m = messages[mi];
43758
+ if (m.from === m.to) {
43759
+ const px = participantX.get(m.from);
43760
+ if (px !== void 0) {
43761
+ const flipLeft = px === frameRightmostX;
43762
+ if (flipLeft) {
43763
+ const loopMin = px - SELF_ARROW_PROJECTION;
43764
+ const need = minPX - FRAME_PADDING_X - loopMin + SELF_ARROW_FRAME_PAD;
43765
+ if (need > 0) extraLeft = Math.max(extraLeft, need);
43766
+ } else {
43767
+ const loopMax = px + SELF_ARROW_PROJECTION;
43768
+ const need = loopMax - (maxPX + FRAME_PADDING_X) + SELF_ARROW_FRAME_PAD;
43769
+ if (need > 0) extraRight = Math.max(extraRight, need);
43770
+ }
43771
+ }
43772
+ if (msgToLastStep.get(mi) === maxStep) {
43773
+ maxStepIsSelfCall = true;
43774
+ }
43775
+ }
43776
+ }
43777
+ const frameX = minPX - FRAME_PADDING_X - extraLeft;
43889
43778
  const frameY = stepY(minStep) - FRAME_PADDING_TOP;
43890
- const frameW = maxPX - minPX + FRAME_PADDING_X * 2;
43891
- const frameH = stepY(maxStep) - stepY(minStep) + FRAME_PADDING_TOP + FRAME_PADDING_BOTTOM;
43779
+ const frameW = maxPX - minPX + FRAME_PADDING_X * 2 + extraLeft + extraRight;
43780
+ const frameH = stepY(maxStep) - stepY(minStep) + FRAME_PADDING_TOP + FRAME_PADDING_BOTTOM + (maxStepIsSelfCall ? SELF_CALL_HEIGHT : 0);
43892
43781
  svg.append("rect").attr("x", frameX).attr("y", frameY).attr("width", frameW).attr("height", frameH).attr("fill", "none").attr("stroke", palette.textMuted).attr("stroke-width", 1).attr("stroke-dasharray", "2 3").attr("rx", 3).attr("ry", 3).attr("class", "block-frame").attr("data-block-line", String(el.lineNumber));
43893
43782
  deferredLabels.push({
43894
43783
  x: frameX + 6,
43895
43784
  y: frameY + FRAME_LABEL_HEIGHT - 4,
43896
43785
  text: `${el.type} ${el.label}`,
43897
- bold: true,
43786
+ bold: false,
43898
43787
  italic: false,
43899
43788
  blockLine: el.lineNumber
43900
43789
  });
@@ -43920,7 +43809,7 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
43920
43809
  y: dividerY + 14,
43921
43810
  text: `else if ${branchData.label}`,
43922
43811
  bold: false,
43923
- italic: true,
43812
+ italic: false,
43924
43813
  blockLine: branchData.lineNumber
43925
43814
  });
43926
43815
  }
@@ -43947,7 +43836,7 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
43947
43836
  y: dividerY + 14,
43948
43837
  text: "else",
43949
43838
  bold: false,
43950
- italic: true,
43839
+ italic: false,
43951
43840
  blockLine: el.elseLineNumber
43952
43841
  });
43953
43842
  }
@@ -44017,7 +43906,7 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
44017
43906
  return side === "right" ? px + ACTIVATION_WIDTH / 2 + offset : px - ACTIVATION_WIDTH / 2 + offset;
44018
43907
  };
44019
43908
  const leftmostX = Math.min(...Array.from(participantX.values()));
44020
- const rightmostX = Math.max(...Array.from(participantX.values()));
43909
+ const rightmostX = frameRightmostX;
44021
43910
  const sectionLineX1 = leftmostX - PARTICIPANT_BOX_WIDTH / 2 - 10;
44022
43911
  const sectionLineX2 = rightmostX + PARTICIPANT_BOX_WIDTH / 2 + 10;
44023
43912
  for (const region of sectionRegions) {
@@ -44219,7 +44108,7 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
44219
44108
  const legendConfig = {
44220
44109
  groups: resolvedGroups,
44221
44110
  position: { placement: "top-center", titleRelation: "below-title" },
44222
- mode: "fixed"
44111
+ mode: "preview"
44223
44112
  };
44224
44113
  const legendState = {
44225
44114
  activeGroup: activeTagGroup ?? null,
@@ -44276,27 +44165,12 @@ function renderParticipant(svg, participant, cx, cy, palette, isDark, color, tag
44276
44165
  case "database":
44277
44166
  renderDatabaseParticipant(g, palette, isDark, color, solid);
44278
44167
  break;
44279
- case "service":
44280
- renderServiceParticipant(g, palette, isDark, color, solid);
44281
- break;
44282
44168
  case "queue":
44283
44169
  renderQueueParticipant(g, palette, isDark, color, solid);
44284
44170
  break;
44285
44171
  case "cache":
44286
44172
  renderCacheParticipant(g, palette, isDark, color, solid);
44287
44173
  break;
44288
- case "networking":
44289
- renderNetworkingParticipant(g, palette, isDark, color, solid);
44290
- break;
44291
- case "frontend":
44292
- renderFrontendParticipant(g, palette, isDark, color, solid);
44293
- break;
44294
- case "external":
44295
- renderExternalParticipant(g, palette, isDark, color, solid);
44296
- break;
44297
- case "gateway":
44298
- renderGatewayParticipant(g, palette, isDark, color, solid);
44299
- break;
44300
44174
  default:
44301
44175
  renderRectParticipant(g, palette, isDark, color, solid);
44302
44176
  break;
@@ -44324,7 +44198,7 @@ function renderParticipant(svg, participant, cx, cy, palette, isDark, color, tag
44324
44198
  });
44325
44199
  }
44326
44200
  }
44327
- var d3Selection21, PARTICIPANT_GAP, PARTICIPANT_BOX_WIDTH, PARTICIPANT_BOX_HEIGHT, TOP_MARGIN, TITLE_HEIGHT8, PARTICIPANT_Y_OFFSET, SERVICE_BORDER_RADIUS, MESSAGE_START_OFFSET, LIFELINE_TAIL, ARROWHEAD_SIZE, NOTE_MAX_W, NOTE_FOLD, NOTE_PAD_H, NOTE_PAD_V, NOTE_FONT_SIZE, NOTE_LINE_H, NOTE_GAP, NOTE_CHAR_W, NOTE_CHARS_PER_LINE, ACTIVATION_WIDTH, SELF_CALL_HEIGHT, SELF_CALL_WIDTH, NOTE_LANE_MAX, LABEL_CHAR_WIDTH, LABEL_MAX_CHARS, fill, stroke, SW, W, H;
44201
+ var d3Selection21, PARTICIPANT_GAP, PARTICIPANT_BOX_WIDTH, PARTICIPANT_BOX_HEIGHT, TOP_MARGIN, TITLE_HEIGHT8, PARTICIPANT_Y_OFFSET, MESSAGE_START_OFFSET, LIFELINE_TAIL, ARROWHEAD_SIZE, NOTE_MAX_W, NOTE_FOLD, NOTE_PAD_H, NOTE_PAD_V, NOTE_FONT_SIZE, NOTE_LINE_H, NOTE_GAP, NOTE_CHAR_W, NOTE_CHARS_PER_LINE, ACTIVATION_WIDTH, SELF_CALL_HEIGHT, SELF_CALL_WIDTH, NOTE_LANE_MAX, LABEL_CHAR_WIDTH, LABEL_MAX_CHARS, fill, stroke, SW, W, H;
44328
44202
  var init_renderer19 = __esm({
44329
44203
  "src/sequence/renderer.ts"() {
44330
44204
  "use strict";
@@ -44346,7 +44220,6 @@ var init_renderer19 = __esm({
44346
44220
  TOP_MARGIN = 20;
44347
44221
  TITLE_HEIGHT8 = 30;
44348
44222
  PARTICIPANT_Y_OFFSET = 10;
44349
- SERVICE_BORDER_RADIUS = 10;
44350
44223
  MESSAGE_START_OFFSET = 30;
44351
44224
  LIFELINE_TAIL = 30;
44352
44225
  ARROWHEAD_SIZE = 8;
@@ -44538,7 +44411,7 @@ function parseVisualization(content, palette) {
44538
44411
  const warn = (line12, message) => {
44539
44412
  result.diagnostics.push(makeDgmoError(line12, message, "warning"));
44540
44413
  };
44541
- if (!content || !content.trim()) {
44414
+ if (!content?.trim()) {
44542
44415
  return fail(0, "Empty content");
44543
44416
  }
44544
44417
  const lines = content.split("\n");
@@ -44620,7 +44493,9 @@ function parseVisualization(content, palette) {
44620
44493
  if (currentTimelineTagGroup && indent === 0) {
44621
44494
  currentTimelineTagGroup = null;
44622
44495
  }
44623
- const groupMatch = line12.match(/^\[(.+?)\](?:\s*\(([^)]+)\))?\s*$/);
44496
+ const groupMatch = line12.match(
44497
+ /^\[(.+?)\](?:\s+(red|orange|yellow|green|blue|purple|teal|cyan|gray|black|white))?\s*$/
44498
+ );
44624
44499
  if (groupMatch) {
44625
44500
  if (result.type === "arc") {
44626
44501
  const name = groupMatch[1].trim();
@@ -44662,7 +44537,7 @@ function parseVisualization(content, palette) {
44662
44537
  }
44663
44538
  if (result.type === "arc") {
44664
44539
  const linkMatch = line12.match(
44665
- /^(.+?)\s*->\s*(.+?)(?:\(([^)]+)\))?\s*(?:\s+(-?[\d,_]+(?:\.[\d]+)?))?$/
44540
+ /^(.+?)\s*->\s*(.+?)(?:\s+(red|orange|yellow|green|blue|purple|teal|cyan|gray|black|white))?(?:\s+(-?[\d,_]+(?:\.[\d]+)?))?$/
44666
44541
  );
44667
44542
  if (linkMatch) {
44668
44543
  const source = linkMatch[1].trim();
@@ -44701,7 +44576,7 @@ function parseVisualization(content, palette) {
44701
44576
  } else {
44702
44577
  if (line12.startsWith("//")) continue;
44703
44578
  const eraEntryMatch = line12.match(
44704
- /^(\d{4}(?:-\d{2})?(?:-\d{2}(?: \d{2}:\d{2})?)?)\s*(?:->|\u2013>)\s*(\d{4}(?:-\d{2})?(?:-\d{2}(?: \d{2}:\d{2})?)?)\s+(.+?)(?:\s*\(([^)]+)\))?\s*$/
44579
+ /^(\d{4}(?:-\d{2})?(?:-\d{2}(?: \d{2}:\d{2})?)?)\s*(?:->|\u2013>)\s*(\d{4}(?:-\d{2})?(?:-\d{2}(?: \d{2}:\d{2})?)?)\s+(.+?)(?:\s+(red|orange|yellow|green|blue|purple|teal|cyan|gray|black|white))?\s*$/
44705
44580
  );
44706
44581
  if (eraEntryMatch) {
44707
44582
  const colorAnnotation = eraEntryMatch[4]?.trim() || null;
@@ -44729,7 +44604,7 @@ function parseVisualization(content, palette) {
44729
44604
  } else {
44730
44605
  if (line12.startsWith("//")) continue;
44731
44606
  const markerEntryMatch = line12.match(
44732
- /^(\d{4}(?:-\d{2})?(?:-\d{2}(?: \d{2}:\d{2})?)?)\s+(.+?)(?:\s*\(([^)]+)\))?\s*$/
44607
+ /^(\d{4}(?:-\d{2})?(?:-\d{2}(?: \d{2}:\d{2})?)?)\s+(.+?)(?:\s+(red|orange|yellow|green|blue|purple|teal|cyan|gray|black|white))?\s*$/
44733
44608
  );
44734
44609
  if (markerEntryMatch) {
44735
44610
  const colorAnnotation = markerEntryMatch[3]?.trim() || null;
@@ -44762,7 +44637,7 @@ function parseVisualization(content, palette) {
44762
44637
  continue;
44763
44638
  }
44764
44639
  const eraMatch = line12.match(
44765
- /^era\s+(\d{4}(?:-\d{2})?(?:-\d{2}(?: \d{2}:\d{2})?)?)\s*(?:->|\u2013>)\s*(\d{4}(?:-\d{2})?(?:-\d{2}(?: \d{2}:\d{2})?)?)\s+(.+?)(?:\s*\(([^)]+)\))?\s*$/
44640
+ /^era\s+(\d{4}(?:-\d{2})?(?:-\d{2}(?: \d{2}:\d{2})?)?)\s*(?:->|\u2013>)\s*(\d{4}(?:-\d{2})?(?:-\d{2}(?: \d{2}:\d{2})?)?)\s+(.+?)(?:\s+(red|orange|yellow|green|blue|purple|teal|cyan|gray|black|white))?\s*$/
44766
44641
  );
44767
44642
  if (eraMatch) {
44768
44643
  const colorAnnotation = eraMatch[4]?.trim() || null;
@@ -44781,7 +44656,7 @@ function parseVisualization(content, palette) {
44781
44656
  continue;
44782
44657
  }
44783
44658
  const markerMatch = line12.match(
44784
- /^marker\s+(\d{4}(?:-\d{2})?(?:-\d{2}(?: \d{2}:\d{2})?)?)\s+(.+?)(?:\s*\(([^)]+)\))?\s*$/
44659
+ /^marker\s+(\d{4}(?:-\d{2})?(?:-\d{2}(?: \d{2}:\d{2})?)?)\s+(.+?)(?:\s+(red|orange|yellow|green|blue|purple|teal|cyan|gray|black|white))?\s*$/
44785
44660
  );
44786
44661
  if (markerMatch) {
44787
44662
  const colorAnnotation = markerMatch[3]?.trim() || null;
@@ -44902,13 +44777,11 @@ function parseVisualization(content, palette) {
44902
44777
  }
44903
44778
  }
44904
44779
  if (!/^(solid-fill|no-name|no-value|no-percent|no-title)$/i.test(line12)) {
44905
- const legacyAliasMatch = line12.match(
44906
- /^([^(:]+?)(?:\(([^)]+)\))?\s+alias\s+(\S+)\s*$/i
44907
- );
44780
+ const legacyAliasMatch = line12.match(/^(.+?)\s+alias\s+(\S+)\s*$/i);
44908
44781
  if (legacyAliasMatch) {
44909
- const name = legacyAliasMatch[1].trim();
44910
- const colorName = legacyAliasMatch[2]?.trim() ?? null;
44911
- const aliasToken = legacyAliasMatch[3].trim();
44782
+ const nameWithMaybeColor = legacyAliasMatch[1].trim();
44783
+ const aliasToken = legacyAliasMatch[2].trim();
44784
+ const { label: name, colorName } = peelTrailingColorName(nameWithMaybeColor);
44912
44785
  let color = null;
44913
44786
  if (colorName) {
44914
44787
  color = resolveColorWithDiagnostic(
@@ -44930,11 +44803,12 @@ function parseVisualization(content, palette) {
44930
44803
  continue;
44931
44804
  }
44932
44805
  const setDeclMatch = line12.match(
44933
- /^([^(:]+?)(?:\(([^)]+)\))?(?:\s+as\s+([A-Za-z][A-Za-z0-9_]{0,11}))?\s*$/i
44806
+ /^(.+?)(?:\s+as\s+([A-Za-z][A-Za-z0-9_]{0,11}))?\s*$/i
44934
44807
  );
44935
44808
  if (setDeclMatch) {
44936
- const name = setDeclMatch[1].trim();
44937
- const colorName = setDeclMatch[2]?.trim() ?? null;
44809
+ const nameWithMaybeColor = setDeclMatch[1].trim();
44810
+ const alias = setDeclMatch[2]?.trim() ?? null;
44811
+ const { label: name, colorName } = peelTrailingColorName(nameWithMaybeColor);
44938
44812
  let color = null;
44939
44813
  if (colorName) {
44940
44814
  color = resolveColorWithDiagnostic(
@@ -44944,7 +44818,6 @@ function parseVisualization(content, palette) {
44944
44818
  palette
44945
44819
  ) ?? null;
44946
44820
  }
44947
- const alias = setDeclMatch[3]?.trim() ?? null;
44948
44821
  result.vennSets.push({ name, alias, color, lineNumber });
44949
44822
  continue;
44950
44823
  }
@@ -44990,10 +44863,9 @@ function parseVisualization(content, palette) {
44990
44863
  if (quadrantMatch) {
44991
44864
  const position = quadrantMatch[1].toLowerCase();
44992
44865
  const labelPart = quadrantMatch[2].trim();
44993
- const labelColorMatch = labelPart.match(/^(.+?)\s*\(([^)]+)\)\s*$/);
44994
- const text = labelColorMatch ? labelColorMatch[1].trim() : labelPart;
44995
- const color = labelColorMatch ? resolveColorWithDiagnostic(
44996
- labelColorMatch[2].trim(),
44866
+ const { label: text, colorName } = peelTrailingColorName(labelPart);
44867
+ const color = colorName ? resolveColorWithDiagnostic(
44868
+ colorName,
44997
44869
  lineNumber,
44998
44870
  result.diagnostics,
44999
44871
  palette
@@ -45183,10 +45055,9 @@ function parseVisualization(content, palette) {
45183
45055
  );
45184
45056
  continue;
45185
45057
  }
45186
- const colorMatch = joinedLabel.match(/^(.+?)\(([^)]+)\)\s*$/);
45187
- const labelPart = colorMatch ? colorMatch[1].trim() : joinedLabel;
45188
- const colorPart = colorMatch ? resolveColorWithDiagnostic(
45189
- colorMatch[2].trim(),
45058
+ const { label: labelPart, colorName: colorWord } = peelTrailingColorName(joinedLabel);
45059
+ const colorPart = colorWord ? resolveColorWithDiagnostic(
45060
+ colorWord,
45190
45061
  lineNumber,
45191
45062
  result.diagnostics,
45192
45063
  palette
@@ -46475,7 +46346,7 @@ function makeTimelineHoverHelpers() {
46475
46346
  setTagAttrs
46476
46347
  };
46477
46348
  }
46478
- function renderTimelineTagLegendOverlay(container, parsed, palette, isDark, setup, hovers, onClickItem, exportDims, swimlaneTagGroup, activeTagGroup, onTagStateChange, viewMode) {
46349
+ function renderTimelineTagLegendOverlay(container, parsed, palette, isDark, setup, hovers, onClickItem, exportDims, swimlaneTagGroup, activeTagGroup, onTagStateChange, viewMode, exportMode) {
46479
46350
  if (parsed.timelineTagGroups.length === 0) return;
46480
46351
  const { width, textColor, groupColorMap, solid } = setup;
46481
46352
  const { FADE_OPACITY: FADE_OPACITY3, fadeReset, fadeToTagValue } = hovers;
@@ -46546,7 +46417,7 @@ function renderTimelineTagLegendOverlay(container, parsed, palette, isDark, setu
46546
46417
  const centralConfig = {
46547
46418
  groups: centralGroups,
46548
46419
  position: { placement: "top-center", titleRelation: "below-title" },
46549
- mode: "fixed",
46420
+ mode: exportMode ? "export" : "preview",
46550
46421
  capsulePillAddonWidth: iconAddon
46551
46422
  };
46552
46423
  const centralState = { activeGroup: centralActive };
@@ -46580,7 +46451,7 @@ function renderTimelineTagLegendOverlay(container, parsed, palette, isDark, setu
46580
46451
  const groupKey = groupName.toLowerCase();
46581
46452
  groupEl.attr("data-tag-group", groupKey);
46582
46453
  if (isActive && !viewMode) {
46583
- const isSwimActive = currentSwimlaneGroup != null && currentSwimlaneGroup.toLowerCase() === groupKey;
46454
+ const isSwimActive = currentSwimlaneGroup?.toLowerCase() === groupKey;
46584
46455
  const pillWidth3 = measureLegendText(groupName, LG_PILL_FONT_SIZE) + LG_PILL_PAD;
46585
46456
  const pillXOff = LG_CAPSULE_PAD;
46586
46457
  const iconX = pillXOff + pillWidth3 + 5;
@@ -47390,7 +47261,7 @@ function renderTimelineVertical(container, parsed, palette, isDark, setup, hover
47390
47261
  }
47391
47262
  }
47392
47263
  }
47393
- function renderTimeline(container, parsed, palette, isDark, onClickItem, exportDims, activeTagGroup, swimlaneTagGroup, onTagStateChange, viewMode) {
47264
+ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportDims, activeTagGroup, swimlaneTagGroup, onTagStateChange, viewMode, exportMode) {
47394
47265
  const setup = setupTimeline(
47395
47266
  container,
47396
47267
  parsed,
@@ -47465,7 +47336,8 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
47465
47336
  swimlaneTagGroup,
47466
47337
  activeTagGroup,
47467
47338
  onTagStateChange,
47468
- viewMode
47339
+ viewMode,
47340
+ exportMode
47469
47341
  );
47470
47342
  }
47471
47343
  function getRotateFn(mode) {
@@ -48562,6 +48434,7 @@ function finalizeSvgExport(container, theme, palette) {
48562
48434
  return svgHtml;
48563
48435
  }
48564
48436
  async function renderForExport(content, theme, palette, viewState, options) {
48437
+ const exportMode = options?.exportMode ?? false;
48565
48438
  const { parseDgmoChartType: parseDgmoChartType2 } = await Promise.resolve().then(() => (init_dgmo_router(), dgmo_router_exports));
48566
48439
  const detectedType = parseDgmoChartType2(content);
48567
48440
  if (detectedType === "org") {
@@ -48603,7 +48476,9 @@ async function renderForExport(content, theme, palette, viewState, options) {
48603
48476
  void 0,
48604
48477
  { width: exportWidth, height: exportHeight },
48605
48478
  activeTagGroup,
48606
- hiddenAttributes
48479
+ hiddenAttributes,
48480
+ void 0,
48481
+ exportMode
48607
48482
  );
48608
48483
  return finalizeSvgExport(container2, theme, effectivePalette2);
48609
48484
  }
@@ -48645,7 +48520,8 @@ async function renderForExport(content, theme, palette, viewState, options) {
48645
48520
  void 0,
48646
48521
  { width: exportWidth, height: exportHeight },
48647
48522
  activeTagGroup,
48648
- hiddenAttributes
48523
+ hiddenAttributes,
48524
+ exportMode
48649
48525
  );
48650
48526
  return finalizeSvgExport(container2, theme, effectivePalette2);
48651
48527
  }
@@ -48668,7 +48544,8 @@ async function renderForExport(content, theme, palette, viewState, options) {
48668
48544
  currentSwimlaneGroup: viewState?.swim ?? null,
48669
48545
  collapsedLanes: viewState?.cl ? new Set(viewState.cl) : void 0,
48670
48546
  collapsedColumns: viewState?.cc ? new Set(viewState.cc) : void 0,
48671
- compactMeta: viewState?.cm
48547
+ compactMeta: viewState?.cm,
48548
+ exportMode
48672
48549
  });
48673
48550
  return finalizeSvgExport(container2, theme, effectivePalette2);
48674
48551
  }
@@ -48692,7 +48569,9 @@ async function renderForExport(content, theme, palette, viewState, options) {
48692
48569
  effectivePalette2,
48693
48570
  theme === "dark",
48694
48571
  void 0,
48695
- { width: exportWidth, height: exportHeight }
48572
+ { width: exportWidth, height: exportHeight },
48573
+ void 0,
48574
+ exportMode
48696
48575
  );
48697
48576
  return finalizeSvgExport(container2, theme, effectivePalette2);
48698
48577
  }
@@ -48722,7 +48601,8 @@ async function renderForExport(content, theme, palette, viewState, options) {
48722
48601
  erParsed.options["active-tag"],
48723
48602
  viewState?.tag ?? options?.tagGroup
48724
48603
  ),
48725
- viewState?.sem
48604
+ viewState?.sem,
48605
+ exportMode
48726
48606
  );
48727
48607
  return finalizeSvgExport(container2, theme, effectivePalette2);
48728
48608
  }
@@ -48755,7 +48635,8 @@ async function renderForExport(content, theme, palette, viewState, options) {
48755
48635
  {
48756
48636
  exportDims: { width: exportWidth, height: exportHeight },
48757
48637
  activeTagGroup: viewState?.tag ?? options?.tagGroup,
48758
- hiddenTagValues: blHiddenTagValues
48638
+ hiddenTagValues: blHiddenTagValues,
48639
+ exportMode
48759
48640
  }
48760
48641
  );
48761
48642
  return finalizeSvgExport(container2, theme, effectivePalette2);
@@ -48801,7 +48682,7 @@ async function renderForExport(content, theme, palette, viewState, options) {
48801
48682
  void 0,
48802
48683
  hideDescriptions,
48803
48684
  colorByDepth ? null : activeTagGroup,
48804
- colorByDepth ? { colorByDepth: true } : void 0
48685
+ colorByDepth ? { colorByDepth: true, exportMode } : { exportMode }
48805
48686
  );
48806
48687
  return finalizeSvgExport(container2, theme, effectivePalette2);
48807
48688
  }
@@ -48864,7 +48745,8 @@ async function renderForExport(content, theme, palette, viewState, options) {
48864
48745
  c4Parsed.tagGroups,
48865
48746
  c4Parsed.options["active-tag"],
48866
48747
  viewState?.tag ?? options?.tagGroup
48867
- )
48748
+ ),
48749
+ exportMode
48868
48750
  );
48869
48751
  return finalizeSvgExport(container2, theme, effectivePalette2);
48870
48752
  }
@@ -49000,7 +48882,8 @@ async function renderForExport(content, theme, palette, viewState, options) {
49000
48882
  resolved.tagGroups,
49001
48883
  resolved.options.activeTag ?? void 0,
49002
48884
  viewState?.tag ?? options?.tagGroup
49003
- )
48885
+ ),
48886
+ exportMode
49004
48887
  },
49005
48888
  { width: EXPORT_W, height: EXPORT_H }
49006
48889
  );
@@ -49041,7 +48924,8 @@ async function renderForExport(content, theme, palette, viewState, options) {
49041
48924
  effectivePalette2,
49042
48925
  theme === "dark",
49043
48926
  { width: RADAR_EXPORT_W, height: RADAR_EXPORT_H },
49044
- viewState
48927
+ viewState,
48928
+ exportMode
49045
48929
  );
49046
48930
  return finalizeSvgExport(container2, theme, effectivePalette2);
49047
48931
  }
@@ -49061,7 +48945,8 @@ async function renderForExport(content, theme, palette, viewState, options) {
49061
48945
  jmLayout.totalHeight
49062
48946
  );
49063
48947
  renderJourneyMap2(container2, jmParsed, effectivePalette2, theme === "dark", {
49064
- exportDims: { width: jmLayout.totalWidth, height: jmLayout.totalHeight }
48948
+ exportDims: { width: jmLayout.totalWidth, height: jmLayout.totalHeight },
48949
+ exportMode
49065
48950
  });
49066
48951
  return finalizeSvgExport(container2, theme, effectivePalette2);
49067
48952
  }
@@ -49078,7 +48963,8 @@ async function renderForExport(content, theme, palette, viewState, options) {
49078
48963
  effectivePalette2,
49079
48964
  theme === "dark",
49080
48965
  { width: EXPORT_WIDTH, height: EXPORT_HEIGHT },
49081
- viewState
48966
+ viewState,
48967
+ exportMode
49082
48968
  );
49083
48969
  return finalizeSvgExport(container2, theme, effectivePalette2);
49084
48970
  }
@@ -49197,7 +49083,10 @@ async function renderForExport(content, theme, palette, viewState, options) {
49197
49083
  void 0,
49198
49084
  viewState?.tag ?? options?.tagGroup
49199
49085
  ),
49200
- viewState?.swim
49086
+ viewState?.swim,
49087
+ void 0,
49088
+ void 0,
49089
+ exportMode
49201
49090
  );
49202
49091
  } else if (parsed.type === "venn") {
49203
49092
  renderVenn(container, parsed, effectivePalette, isDark, void 0, dims);