@diagrammo/dgmo 0.6.2 → 0.6.3

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 (44) hide show
  1. package/.claude/commands/dgmo.md +231 -13
  2. package/AGENTS.md +148 -0
  3. package/dist/cli.cjs +327 -153
  4. package/dist/index.cjs +305 -177
  5. package/dist/index.cjs.map +1 -1
  6. package/dist/index.d.cts +24 -3
  7. package/dist/index.d.ts +24 -3
  8. package/dist/index.js +303 -177
  9. package/dist/index.js.map +1 -1
  10. package/package.json +5 -3
  11. package/src/c4/layout.ts +0 -5
  12. package/src/c4/parser.ts +0 -16
  13. package/src/c4/renderer.ts +1 -5
  14. package/src/class/layout.ts +0 -1
  15. package/src/class/parser.ts +28 -0
  16. package/src/class/renderer.ts +5 -26
  17. package/src/cli.ts +563 -14
  18. package/src/completion.ts +58 -0
  19. package/src/d3.ts +58 -106
  20. package/src/dgmo-router.ts +0 -57
  21. package/src/echarts.ts +96 -55
  22. package/src/er/parser.ts +30 -1
  23. package/src/er/renderer.ts +1 -2
  24. package/src/graph/flowchart-parser.ts +27 -4
  25. package/src/graph/flowchart-renderer.ts +1 -2
  26. package/src/graph/state-parser.ts +0 -1
  27. package/src/graph/state-renderer.ts +1 -3
  28. package/src/index.ts +10 -0
  29. package/src/infra/compute.ts +0 -7
  30. package/src/infra/layout.ts +0 -2
  31. package/src/infra/parser.ts +46 -4
  32. package/src/infra/renderer.ts +1 -15
  33. package/src/initiative-status/renderer.ts +5 -25
  34. package/src/kanban/parser.ts +0 -2
  35. package/src/org/layout.ts +0 -4
  36. package/src/org/renderer.ts +7 -28
  37. package/src/sequence/parser.ts +14 -11
  38. package/src/sequence/renderer.ts +0 -2
  39. package/src/sequence/tag-resolution.ts +0 -1
  40. package/src/sitemap/layout.ts +1 -14
  41. package/src/sitemap/parser.ts +1 -2
  42. package/src/sitemap/renderer.ts +0 -3
  43. package/src/utils/arrows.ts +7 -7
  44. package/src/utils/export-container.ts +40 -0
package/dist/index.cjs CHANGED
@@ -1809,12 +1809,12 @@ var SYNC_LABELED_RE, ASYNC_LABELED_RE, RETURN_SYNC_LABELED_RE, RETURN_ASYNC_LABE
1809
1809
  var init_arrows = __esm({
1810
1810
  "src/utils/arrows.ts"() {
1811
1811
  "use strict";
1812
- SYNC_LABELED_RE = /^(\S+)\s+-(.+)->\s+(\S+)$/;
1813
- ASYNC_LABELED_RE = /^(\S+)\s+~(.+)~>\s+(\S+)$/;
1814
- RETURN_SYNC_LABELED_RE = /^(\S+)\s+<-(.+)-\s+(\S+)$/;
1815
- RETURN_ASYNC_LABELED_RE = /^(\S+)\s+<~(.+)~\s+(\S+)$/;
1816
- BIDI_SYNC_RE = /^(\S+)\s+<-(.+)->\s+(\S+)$/;
1817
- BIDI_ASYNC_RE = /^(\S+)\s+<~(.+)~>\s+(\S+)$/;
1812
+ SYNC_LABELED_RE = /^(.+?)\s+-(.+)->\s+(.+)$/;
1813
+ ASYNC_LABELED_RE = /^(.+?)\s+~(.+)~>\s+(.+)$/;
1814
+ RETURN_SYNC_LABELED_RE = /^(.+?)\s+<-(.+)-\s+(.+)$/;
1815
+ RETURN_ASYNC_LABELED_RE = /^(.+?)\s+<~(.+)~\s+(.+)$/;
1816
+ BIDI_SYNC_RE = /^(.+?)\s+<-(.+)->\s+(.+)$/;
1817
+ BIDI_ASYNC_RE = /^(.+?)\s+<~(.+)~>\s+(.+)$/;
1818
1818
  ARROW_CHARS = ["->", "~>"];
1819
1819
  }
1820
1820
  });
@@ -2223,7 +2223,7 @@ function parseSequenceDgmo(content) {
2223
2223
  continue;
2224
2224
  }
2225
2225
  const bidiPlainMatch = arrowCore.match(
2226
- /^(\S+)\s*(?:<->|<~>)\s*(\S+)/
2226
+ /^(.+?)\s*(?:<->|<~>)\s*(.+)/
2227
2227
  );
2228
2228
  if (bidiPlainMatch) {
2229
2229
  pushError(
@@ -2232,8 +2232,8 @@ function parseSequenceDgmo(content) {
2232
2232
  );
2233
2233
  continue;
2234
2234
  }
2235
- const bareReturnSync = arrowCore.match(/^(\S+)\s+<-\s+(\S+)$/);
2236
- const bareReturnAsync = arrowCore.match(/^(\S+)\s+<~\s+(\S+)$/);
2235
+ const bareReturnSync = arrowCore.match(/^(.+?)\s+<-\s+(.+)$/);
2236
+ const bareReturnAsync = arrowCore.match(/^(.+?)\s+<~\s+(.+)$/);
2237
2237
  const bareReturn = bareReturnSync || bareReturnAsync;
2238
2238
  if (bareReturn) {
2239
2239
  const to = bareReturn[1];
@@ -2244,8 +2244,8 @@ function parseSequenceDgmo(content) {
2244
2244
  );
2245
2245
  continue;
2246
2246
  }
2247
- const bareCallSync = arrowCore.match(/^(\S+)\s*->\s*(\S+)$/);
2248
- const bareCallAsync = arrowCore.match(/^(\S+)\s*~>\s*(\S+)$/);
2247
+ const bareCallSync = arrowCore.match(/^(.+?)\s*->\s*(.+)$/);
2248
+ const bareCallAsync = arrowCore.match(/^(.+?)\s*~>\s*(.+)$/);
2249
2249
  const bareCall = bareCallSync || bareCallAsync;
2250
2250
  if (bareCall) {
2251
2251
  contentStarted = true;
@@ -2497,21 +2497,22 @@ var init_parser = __esm({
2497
2497
  "networking",
2498
2498
  "frontend"
2499
2499
  ]);
2500
- IS_A_PATTERN = /^(\S+)\s+is\s+an?\s+(\w+)(?:\s+(.+))?$/i;
2501
- POSITION_ONLY_PATTERN = /^(\S+)\s+position\s+(-?\d+)$/i;
2500
+ IS_A_PATTERN = /^([^:]+?)\s+is\s+an?\s+(\w+)(?:\s+(.+))?$/i;
2501
+ POSITION_ONLY_PATTERN = /^([^:]+?)\s+position\s+(-?\d+)$/i;
2502
2502
  COLORED_PARTICIPANT_PATTERN = /^(\S+?)\(([^)]+)\)\s*$/;
2503
2503
  GROUP_HEADING_PATTERN = /^\[(.+?)(?:\(([^)]+)\))?\]\s*$/;
2504
2504
  LEGACY_GROUP_PATTERN = /^##\s+(.+?)(?:\(([^)]+)\))?\s*$/;
2505
2505
  SECTION_PATTERN = /^==\s+(.+?)(?:\s*==)?\s*$/;
2506
2506
  ARROW_PATTERN = /\S+\s*(?:<-\S+-|<~\S+~|-\S+->|~\S+~>|->|~>|<-|<~)\s*\S+/;
2507
- NOTE_SINGLE = /^note(?:\s+(right|left)\s+of\s+(\S+))?\s*:\s*(.+)$/i;
2508
- NOTE_MULTI = /^note(?:\s+(right|left)\s+of\s+([^\s:]+))?\s*:?\s*$/i;
2507
+ NOTE_SINGLE = /^note(?:\s+(right|left)\s+of\s+(.+?))?\s*:\s*(.+)$/i;
2508
+ NOTE_MULTI = /^note(?:\s+(right|left)\s+of\s+(.+?))?\s*:?\s*$/i;
2509
2509
  }
2510
2510
  });
2511
2511
 
2512
2512
  // src/graph/flowchart-parser.ts
2513
2513
  var flowchart_parser_exports = {};
2514
2514
  __export(flowchart_parser_exports, {
2515
+ extractSymbols: () => extractSymbols,
2515
2516
  looksLikeFlowchart: () => looksLikeFlowchart,
2516
2517
  parseFlowchart: () => parseFlowchart
2517
2518
  });
@@ -2555,7 +2556,6 @@ function parseNodeRef(text, palette) {
2555
2556
  }
2556
2557
  function splitArrows(line10) {
2557
2558
  const segments = [];
2558
- const arrowRe = /(?:^|\s)-([^>\s(][^(>]*?)?\s*(?:\(([^)]+)\))?\s*->|(?:^|\s)->/g;
2559
2559
  let lastIndex = 0;
2560
2560
  const arrowPositions = [];
2561
2561
  let searchFrom = 0;
@@ -2796,7 +2796,20 @@ function looksLikeFlowchart(content) {
2796
2796
  /->[ \t]*[\[(<\/]/.test(content);
2797
2797
  return shapeNearArrow;
2798
2798
  }
2799
- var LEGACY_GROUP_RE;
2799
+ function extractSymbols(docText) {
2800
+ const entities = [];
2801
+ let inMetadata = true;
2802
+ for (const rawLine of docText.split("\n")) {
2803
+ const line10 = rawLine.trim();
2804
+ if (inMetadata && /^[a-z-]+\s*:/i.test(line10)) continue;
2805
+ inMetadata = false;
2806
+ if (line10.length === 0 || /^\s/.test(rawLine)) continue;
2807
+ const m = NODE_ID_RE.exec(line10);
2808
+ if (m && !entities.includes(m[1])) entities.push(m[1]);
2809
+ }
2810
+ return { kind: "flowchart", entities, keywords: [] };
2811
+ }
2812
+ var LEGACY_GROUP_RE, NODE_ID_RE;
2800
2813
  var init_flowchart_parser = __esm({
2801
2814
  "src/graph/flowchart-parser.ts"() {
2802
2815
  "use strict";
@@ -2804,6 +2817,7 @@ var init_flowchart_parser = __esm({
2804
2817
  init_diagnostics();
2805
2818
  init_parsing();
2806
2819
  LEGACY_GROUP_RE = /^##\s+/;
2820
+ NODE_ID_RE = /^([a-zA-Z_][\w-]*)[\s([</{]/;
2807
2821
  }
2808
2822
  });
2809
2823
 
@@ -3079,6 +3093,7 @@ var init_state_parser = __esm({
3079
3093
  // src/class/parser.ts
3080
3094
  var parser_exports2 = {};
3081
3095
  __export(parser_exports2, {
3096
+ extractSymbols: () => extractSymbols2,
3082
3097
  looksLikeClassDiagram: () => looksLikeClassDiagram,
3083
3098
  parseClassDiagram: () => parseClassDiagram
3084
3099
  });
@@ -3326,6 +3341,23 @@ function looksLikeClassDiagram(content) {
3326
3341
  if (hasRelationship && hasClassDecl && hasIndentedMember) return true;
3327
3342
  return false;
3328
3343
  }
3344
+ function extractSymbols2(docText) {
3345
+ const entities = [];
3346
+ let inMetadata = true;
3347
+ for (const rawLine of docText.split("\n")) {
3348
+ const line10 = rawLine.trim();
3349
+ if (inMetadata && /^[a-z-]+\s*:/i.test(line10)) continue;
3350
+ inMetadata = false;
3351
+ if (line10.length === 0 || /^\s/.test(rawLine)) continue;
3352
+ const m = CLASS_DECL_RE.exec(line10);
3353
+ if (m && !entities.includes(m[1])) entities.push(m[1]);
3354
+ }
3355
+ return {
3356
+ kind: "class",
3357
+ entities,
3358
+ keywords: ["extends", "implements", "abstract", "interface", "enum"]
3359
+ };
3360
+ }
3329
3361
  var CLASS_DECL_RE, REL_ARROW_RE, VISIBILITY_RE, STATIC_SUFFIX_RE, METHOD_RE, FIELD_RE, ARROW_TO_TYPE;
3330
3362
  var init_parser2 = __esm({
3331
3363
  "src/class/parser.ts"() {
@@ -3353,6 +3385,7 @@ var init_parser2 = __esm({
3353
3385
  // src/er/parser.ts
3354
3386
  var parser_exports3 = {};
3355
3387
  __export(parser_exports3, {
3388
+ extractSymbols: () => extractSymbols3,
3356
3389
  looksLikeERDiagram: () => looksLikeERDiagram,
3357
3390
  parseERDiagram: () => parseERDiagram
3358
3391
  });
@@ -3655,6 +3688,25 @@ function looksLikeERDiagram(content) {
3655
3688
  if (hasRelationship && hasTableDecl) return true;
3656
3689
  return false;
3657
3690
  }
3691
+ function extractSymbols3(docText) {
3692
+ const entities = [];
3693
+ let inMetadata = true;
3694
+ for (const rawLine of docText.split("\n")) {
3695
+ const line10 = rawLine.trim();
3696
+ if (inMetadata && /^chart\s*:/i.test(line10)) continue;
3697
+ if (inMetadata && /^[a-z-]+\s*:/i.test(line10)) continue;
3698
+ inMetadata = false;
3699
+ if (line10.length === 0) continue;
3700
+ if (/^\s/.test(rawLine)) continue;
3701
+ const m = TABLE_DECL_RE.exec(line10);
3702
+ if (m) entities.push(m[1]);
3703
+ }
3704
+ return {
3705
+ kind: "er",
3706
+ entities,
3707
+ keywords: ["pk", "fk", "unique", "nullable", "1", "*", "?"]
3708
+ };
3709
+ }
3658
3710
  var TABLE_DECL_RE, COLUMN_RE, INDENT_REL_RE, CONSTRAINT_MAP, REL_SYMBOLIC_RE, REL_KEYWORD_RE, KEYWORD_TO_SYMBOL;
3659
3711
  var init_parser3 = __esm({
3660
3712
  "src/er/parser.ts"() {
@@ -4136,10 +4188,12 @@ function buildExtendedChartOption(parsed, palette, isDark) {
4136
4188
  );
4137
4189
  }
4138
4190
  if (parsed.type === "chord") {
4191
+ const bg = isDark ? palette.surface : palette.bg;
4139
4192
  return buildChordOption(
4140
4193
  parsed,
4141
4194
  textColor,
4142
4195
  colors,
4196
+ bg,
4143
4197
  titleConfig,
4144
4198
  tooltipTheme
4145
4199
  );
@@ -4157,6 +4211,7 @@ function buildExtendedChartOption(parsed, palette, isDark) {
4157
4211
  );
4158
4212
  }
4159
4213
  if (parsed.type === "scatter") {
4214
+ const bg = isDark ? palette.surface : palette.bg;
4160
4215
  return buildScatterOption(
4161
4216
  parsed,
4162
4217
  palette,
@@ -4164,15 +4219,18 @@ function buildExtendedChartOption(parsed, palette, isDark) {
4164
4219
  axisLineColor,
4165
4220
  gridOpacity,
4166
4221
  colors,
4222
+ bg,
4167
4223
  titleConfig,
4168
4224
  tooltipTheme
4169
4225
  );
4170
4226
  }
4171
4227
  if (parsed.type === "funnel") {
4228
+ const bg = isDark ? palette.surface : palette.bg;
4172
4229
  return buildFunnelOption(
4173
4230
  parsed,
4174
4231
  textColor,
4175
4232
  colors,
4233
+ bg,
4176
4234
  titleConfig,
4177
4235
  tooltipTheme
4178
4236
  );
@@ -4180,6 +4238,7 @@ function buildExtendedChartOption(parsed, palette, isDark) {
4180
4238
  return buildHeatmapOption(
4181
4239
  parsed,
4182
4240
  palette,
4241
+ isDark,
4183
4242
  textColor,
4184
4243
  axisLineColor,
4185
4244
  titleConfig,
@@ -4236,7 +4295,7 @@ function buildSankeyOption(parsed, textColor, colors, titleConfig, tooltipTheme)
4236
4295
  ]
4237
4296
  };
4238
4297
  }
4239
- function buildChordOption(parsed, textColor, colors, titleConfig, tooltipTheme) {
4298
+ function buildChordOption(parsed, textColor, colors, bg, titleConfig, tooltipTheme) {
4240
4299
  const nodeSet = /* @__PURE__ */ new Set();
4241
4300
  if (parsed.links) {
4242
4301
  for (const link of parsed.links) {
@@ -4256,12 +4315,13 @@ function buildChordOption(parsed, textColor, colors, titleConfig, tooltipTheme)
4256
4315
  }
4257
4316
  }
4258
4317
  }
4259
- const categories = nodeNames.map((name, index) => ({
4260
- name,
4261
- itemStyle: {
4262
- color: colors[index % colors.length]
4263
- }
4264
- }));
4318
+ const categories = nodeNames.map((name, index) => {
4319
+ const stroke2 = colors[index % colors.length];
4320
+ return {
4321
+ name,
4322
+ itemStyle: { color: mix(stroke2, bg, 30), borderColor: stroke2, borderWidth: CHART_BORDER_WIDTH }
4323
+ };
4324
+ });
4265
4325
  return {
4266
4326
  ...CHART_BASE,
4267
4327
  title: titleConfig,
@@ -4429,7 +4489,7 @@ function buildFunctionOption(parsed, palette, textColor, axisLineColor, gridOpac
4429
4489
  series
4430
4490
  };
4431
4491
  }
4432
- function buildScatterOption(parsed, palette, textColor, axisLineColor, gridOpacity, colors, titleConfig, tooltipTheme) {
4492
+ function buildScatterOption(parsed, palette, textColor, axisLineColor, gridOpacity, colors, bg, titleConfig, tooltipTheme) {
4433
4493
  const points = parsed.scatterPoints ?? [];
4434
4494
  const defaultSize = 15;
4435
4495
  const hasCategories = points.some((p) => p.category !== void 0);
@@ -4461,27 +4521,30 @@ function buildScatterOption(parsed, palette, textColor, axisLineColor, gridOpaci
4461
4521
  const data = categoryPoints.map((p) => ({
4462
4522
  name: p.name,
4463
4523
  value: hasSize ? [p.x, p.y, p.size ?? 0] : [p.x, p.y],
4464
- ...p.color && { itemStyle: { color: p.color } }
4524
+ ...p.color && {
4525
+ itemStyle: { color: mix(p.color, bg, 30), borderColor: p.color, borderWidth: CHART_BORDER_WIDTH }
4526
+ }
4465
4527
  }));
4466
4528
  return {
4467
4529
  name: category,
4468
4530
  type: "scatter",
4469
4531
  data,
4470
4532
  ...hasSize ? { symbolSize: (val) => val[2] } : { symbolSize: defaultSize },
4471
- itemStyle: { color: catColor },
4533
+ itemStyle: { color: mix(catColor, bg, 30), borderColor: catColor, borderWidth: CHART_BORDER_WIDTH },
4472
4534
  label: labelConfig,
4473
4535
  emphasis: emphasisConfig
4474
4536
  };
4475
4537
  });
4476
4538
  } else {
4477
- const data = points.map((p, index) => ({
4478
- name: p.name,
4479
- value: hasSize ? [p.x, p.y, p.size ?? 0] : [p.x, p.y],
4480
- ...hasSize ? { symbolSize: p.size ?? defaultSize } : { symbolSize: defaultSize },
4481
- itemStyle: {
4482
- color: p.color ?? colors[index % colors.length]
4483
- }
4484
- }));
4539
+ const data = points.map((p, index) => {
4540
+ const stroke2 = p.color ?? colors[index % colors.length];
4541
+ return {
4542
+ name: p.name,
4543
+ value: hasSize ? [p.x, p.y, p.size ?? 0] : [p.x, p.y],
4544
+ ...hasSize ? { symbolSize: p.size ?? defaultSize } : { symbolSize: defaultSize },
4545
+ itemStyle: { color: mix(stroke2, bg, 30), borderColor: stroke2, borderWidth: CHART_BORDER_WIDTH }
4546
+ };
4547
+ });
4485
4548
  series = [
4486
4549
  {
4487
4550
  type: "scatter",
@@ -4584,7 +4647,8 @@ function buildScatterOption(parsed, palette, textColor, axisLineColor, gridOpaci
4584
4647
  series
4585
4648
  };
4586
4649
  }
4587
- function buildHeatmapOption(parsed, palette, textColor, axisLineColor, titleConfig, tooltipTheme) {
4650
+ function buildHeatmapOption(parsed, palette, isDark, textColor, axisLineColor, titleConfig, tooltipTheme) {
4651
+ const bg = isDark ? palette.surface : palette.bg;
4588
4652
  const heatmapRows = parsed.heatmapRows ?? [];
4589
4653
  const columns = parsed.columns ?? [];
4590
4654
  const rowLabels = heatmapRows.map((r) => r.label);
@@ -4655,10 +4719,10 @@ function buildHeatmapOption(parsed, palette, textColor, axisLineColor, titleConf
4655
4719
  top: "center",
4656
4720
  inRange: {
4657
4721
  color: [
4658
- palette.primary,
4659
- palette.colors.cyan,
4660
- palette.colors.yellow,
4661
- palette.colors.orange
4722
+ mix(palette.primary, bg, 30),
4723
+ mix(palette.colors.cyan, bg, 30),
4724
+ mix(palette.colors.yellow, bg, 30),
4725
+ mix(palette.colors.orange, bg, 30)
4662
4726
  ]
4663
4727
  },
4664
4728
  textStyle: {
@@ -4669,9 +4733,13 @@ function buildHeatmapOption(parsed, palette, textColor, axisLineColor, titleConf
4669
4733
  {
4670
4734
  type: "heatmap",
4671
4735
  data,
4736
+ itemStyle: {
4737
+ borderWidth: 2,
4738
+ borderColor: bg
4739
+ },
4672
4740
  label: {
4673
4741
  show: true,
4674
- color: "#ffffff",
4742
+ color: textColor,
4675
4743
  fontSize: 14,
4676
4744
  fontWeight: "bold"
4677
4745
  },
@@ -4686,17 +4754,21 @@ function buildHeatmapOption(parsed, palette, textColor, axisLineColor, titleConf
4686
4754
  ]
4687
4755
  };
4688
4756
  }
4689
- function buildFunnelOption(parsed, textColor, colors, titleConfig, tooltipTheme) {
4757
+ function buildFunnelOption(parsed, textColor, colors, bg, titleConfig, tooltipTheme) {
4690
4758
  const sorted = [...parsed.data].sort((a, b) => b.value - a.value);
4691
4759
  const topValue = sorted.length > 0 ? sorted[0].value : 1;
4692
- const data = sorted.map((d) => ({
4693
- name: d.label,
4694
- value: d.value,
4695
- itemStyle: {
4696
- color: d.color ?? colors[parsed.data.indexOf(d) % colors.length],
4697
- borderWidth: 0
4698
- }
4699
- }));
4760
+ const data = sorted.map((d) => {
4761
+ const stroke2 = d.color ?? colors[parsed.data.indexOf(d) % colors.length];
4762
+ return {
4763
+ name: d.label,
4764
+ value: d.value,
4765
+ itemStyle: {
4766
+ color: mix(stroke2, bg, 30),
4767
+ borderColor: stroke2,
4768
+ borderWidth: CHART_BORDER_WIDTH
4769
+ }
4770
+ };
4771
+ });
4700
4772
  const prevValueMap = /* @__PURE__ */ new Map();
4701
4773
  for (let i = 0; i < sorted.length; i++) {
4702
4774
  prevValueMap.set(
@@ -4842,23 +4914,24 @@ function makeGridAxis(type, textColor, axisLineColor, splitLineColor, gridOpacit
4842
4914
  function buildSimpleChartOption(parsed, palette, isDark, chartWidth) {
4843
4915
  if (parsed.error) return {};
4844
4916
  const { textColor, axisLineColor, splitLineColor, gridOpacity, colors, titleConfig, tooltipTheme } = buildChartCommons(parsed, palette, isDark);
4917
+ const bg = isDark ? palette.surface : palette.bg;
4845
4918
  switch (parsed.type) {
4846
4919
  case "bar":
4847
- return buildBarOption(parsed, textColor, axisLineColor, splitLineColor, gridOpacity, colors, titleConfig, tooltipTheme, chartWidth);
4920
+ return buildBarOption(parsed, textColor, axisLineColor, splitLineColor, gridOpacity, colors, bg, titleConfig, tooltipTheme, chartWidth);
4848
4921
  case "bar-stacked":
4849
- return buildBarStackedOption(parsed, textColor, axisLineColor, splitLineColor, gridOpacity, colors, titleConfig, tooltipTheme, chartWidth);
4922
+ return buildBarStackedOption(parsed, textColor, axisLineColor, splitLineColor, gridOpacity, colors, bg, titleConfig, tooltipTheme, chartWidth);
4850
4923
  case "line":
4851
4924
  return parsed.seriesNames ? buildMultiLineOption(parsed, palette, textColor, axisLineColor, splitLineColor, gridOpacity, colors, titleConfig, tooltipTheme, chartWidth) : buildLineOption(parsed, palette, textColor, axisLineColor, splitLineColor, gridOpacity, titleConfig, tooltipTheme, chartWidth);
4852
4925
  case "area":
4853
4926
  return buildAreaOption(parsed, palette, textColor, axisLineColor, splitLineColor, gridOpacity, titleConfig, tooltipTheme, chartWidth);
4854
4927
  case "pie":
4855
- return buildPieOption(parsed, textColor, getSegmentColors(palette, parsed.data.length), titleConfig, tooltipTheme, false);
4928
+ return buildPieOption(parsed, textColor, getSegmentColors(palette, parsed.data.length), bg, titleConfig, tooltipTheme, false);
4856
4929
  case "doughnut":
4857
- return buildPieOption(parsed, textColor, getSegmentColors(palette, parsed.data.length), titleConfig, tooltipTheme, true);
4930
+ return buildPieOption(parsed, textColor, getSegmentColors(palette, parsed.data.length), bg, titleConfig, tooltipTheme, true);
4858
4931
  case "radar":
4859
- return buildRadarOption(parsed, palette, textColor, gridOpacity, colors, titleConfig, tooltipTheme);
4932
+ return buildRadarOption(parsed, palette, isDark, textColor, gridOpacity, titleConfig, tooltipTheme);
4860
4933
  case "polar-area":
4861
- return buildPolarAreaOption(parsed, textColor, getSegmentColors(palette, parsed.data.length), titleConfig, tooltipTheme);
4934
+ return buildPolarAreaOption(parsed, textColor, getSegmentColors(palette, parsed.data.length), bg, titleConfig, tooltipTheme);
4862
4935
  }
4863
4936
  }
4864
4937
  function makeChartGrid(options) {
@@ -4870,14 +4943,17 @@ function makeChartGrid(options) {
4870
4943
  containLabel: true
4871
4944
  };
4872
4945
  }
4873
- function buildBarOption(parsed, textColor, axisLineColor, splitLineColor, gridOpacity, colors, titleConfig, tooltipTheme, chartWidth) {
4946
+ function buildBarOption(parsed, textColor, axisLineColor, splitLineColor, gridOpacity, colors, bg, titleConfig, tooltipTheme, chartWidth) {
4874
4947
  const { xLabel, yLabel } = resolveAxisLabels(parsed);
4875
4948
  const isHorizontal = parsed.orientation === "horizontal";
4876
4949
  const labels = parsed.data.map((d) => d.label);
4877
- const data = parsed.data.map((d, i) => ({
4878
- value: d.value,
4879
- itemStyle: { color: d.color ?? colors[i % colors.length] }
4880
- }));
4950
+ const data = parsed.data.map((d, i) => {
4951
+ const stroke2 = d.color ?? colors[i % colors.length];
4952
+ return {
4953
+ value: d.value,
4954
+ itemStyle: { color: mix(stroke2, bg, 30), borderColor: stroke2, borderWidth: CHART_BORDER_WIDTH }
4955
+ };
4956
+ });
4881
4957
  const hCatGap = isHorizontal && yLabel ? Math.max(40, Math.max(...labels.map((l) => l.length)) * 8 + 16) : void 0;
4882
4958
  const categoryAxis = makeGridAxis("category", textColor, axisLineColor, splitLineColor, gridOpacity, isHorizontal ? yLabel : xLabel, labels, hCatGap, !isHorizontal ? chartWidth : void 0);
4883
4959
  const valueAxis = makeGridAxis("value", textColor, axisLineColor, splitLineColor, gridOpacity, isHorizontal ? xLabel : yLabel);
@@ -5058,12 +5134,15 @@ function segmentLabelFormatter(mode) {
5058
5134
  return "{b} \u2014 {c} ({d}%)";
5059
5135
  }
5060
5136
  }
5061
- function buildPieOption(parsed, textColor, colors, titleConfig, tooltipTheme, isDoughnut) {
5062
- const data = parsed.data.map((d, i) => ({
5063
- name: d.label,
5064
- value: d.value,
5065
- itemStyle: { color: d.color ?? colors[i % colors.length] }
5066
- }));
5137
+ function buildPieOption(parsed, textColor, colors, bg, titleConfig, tooltipTheme, isDoughnut) {
5138
+ const data = parsed.data.map((d, i) => {
5139
+ const stroke2 = d.color ?? colors[i % colors.length];
5140
+ return {
5141
+ name: d.label,
5142
+ value: d.value,
5143
+ itemStyle: { color: mix(stroke2, bg, 30), borderColor: stroke2, borderWidth: CHART_BORDER_WIDTH }
5144
+ };
5145
+ });
5067
5146
  return {
5068
5147
  ...CHART_BASE,
5069
5148
  title: titleConfig,
@@ -5088,7 +5167,8 @@ function buildPieOption(parsed, textColor, colors, titleConfig, tooltipTheme, is
5088
5167
  ]
5089
5168
  };
5090
5169
  }
5091
- function buildRadarOption(parsed, palette, textColor, gridOpacity, colors, titleConfig, tooltipTheme) {
5170
+ function buildRadarOption(parsed, palette, isDark, textColor, gridOpacity, titleConfig, tooltipTheme) {
5171
+ const bg = isDark ? palette.surface : palette.bg;
5092
5172
  const radarColor = parsed.color ?? parsed.seriesNameColors?.[0] ?? palette.primary;
5093
5173
  const values = parsed.data.map((d) => d.value);
5094
5174
  const maxValue = Math.max(...values) * 1.15;
@@ -5125,7 +5205,7 @@ function buildRadarOption(parsed, palette, textColor, gridOpacity, colors, title
5125
5205
  {
5126
5206
  value: values,
5127
5207
  name: parsed.series ?? "Value",
5128
- areaStyle: { color: radarColor, opacity: 0.25 },
5208
+ areaStyle: { color: mix(radarColor, bg, 30) },
5129
5209
  lineStyle: { color: radarColor },
5130
5210
  itemStyle: { color: radarColor },
5131
5211
  symbol: "circle",
@@ -5144,12 +5224,15 @@ function buildRadarOption(parsed, palette, textColor, gridOpacity, colors, title
5144
5224
  ]
5145
5225
  };
5146
5226
  }
5147
- function buildPolarAreaOption(parsed, textColor, colors, titleConfig, tooltipTheme) {
5148
- const data = parsed.data.map((d, i) => ({
5149
- name: d.label,
5150
- value: d.value,
5151
- itemStyle: { color: d.color ?? colors[i % colors.length] }
5152
- }));
5227
+ function buildPolarAreaOption(parsed, textColor, colors, bg, titleConfig, tooltipTheme) {
5228
+ const data = parsed.data.map((d, i) => {
5229
+ const stroke2 = d.color ?? colors[i % colors.length];
5230
+ return {
5231
+ name: d.label,
5232
+ value: d.value,
5233
+ itemStyle: { color: mix(stroke2, bg, 30), borderColor: stroke2, borderWidth: CHART_BORDER_WIDTH }
5234
+ };
5235
+ });
5153
5236
  return {
5154
5237
  ...CHART_BASE,
5155
5238
  title: titleConfig,
@@ -5175,7 +5258,7 @@ function buildPolarAreaOption(parsed, textColor, colors, titleConfig, tooltipThe
5175
5258
  ]
5176
5259
  };
5177
5260
  }
5178
- function buildBarStackedOption(parsed, textColor, axisLineColor, splitLineColor, gridOpacity, colors, titleConfig, tooltipTheme, chartWidth) {
5261
+ function buildBarStackedOption(parsed, textColor, axisLineColor, splitLineColor, gridOpacity, colors, bg, titleConfig, tooltipTheme, chartWidth) {
5179
5262
  const { xLabel, yLabel } = resolveAxisLabels(parsed);
5180
5263
  const isHorizontal = parsed.orientation === "horizontal";
5181
5264
  const seriesNames = parsed.seriesNames ?? [];
@@ -5190,12 +5273,12 @@ function buildBarStackedOption(parsed, textColor, axisLineColor, splitLineColor,
5190
5273
  type: "bar",
5191
5274
  stack: "total",
5192
5275
  data,
5193
- itemStyle: { color },
5276
+ itemStyle: { color: mix(color, bg, 30), borderColor: color, borderWidth: CHART_BORDER_WIDTH },
5194
5277
  label: {
5195
5278
  show: true,
5196
5279
  position: "inside",
5197
5280
  formatter: "{c}",
5198
- color: "#ffffff",
5281
+ color: textColor,
5199
5282
  fontSize: 14,
5200
5283
  fontWeight: "bold",
5201
5284
  fontFamily: FONT_FAMILY
@@ -5267,7 +5350,7 @@ async function renderExtendedChartForExport(content, theme, palette, options) {
5267
5350
  chart.dispose();
5268
5351
  }
5269
5352
  }
5270
- var echarts, EMPHASIS_SELF, CHART_BASE, ECHART_EXPORT_WIDTH, ECHART_EXPORT_HEIGHT, STANDARD_CHART_TYPES;
5353
+ var echarts, EMPHASIS_SELF, CHART_BASE, CHART_BORDER_WIDTH, ECHART_EXPORT_WIDTH, ECHART_EXPORT_HEIGHT, STANDARD_CHART_TYPES;
5271
5354
  var init_echarts = __esm({
5272
5355
  "src/echarts.ts"() {
5273
5356
  "use strict";
@@ -5275,12 +5358,14 @@ var init_echarts = __esm({
5275
5358
  init_fonts();
5276
5359
  init_branding();
5277
5360
  init_palettes();
5361
+ init_color_utils();
5278
5362
  init_chart();
5279
5363
  init_diagnostics();
5280
5364
  init_colors();
5281
5365
  init_parsing();
5282
5366
  EMPHASIS_SELF = { focus: "self", blurScope: "global" };
5283
5367
  CHART_BASE = { backgroundColor: "transparent", animation: false };
5368
+ CHART_BORDER_WIDTH = 2;
5284
5369
  ECHART_EXPORT_WIDTH = 1200;
5285
5370
  ECHART_EXPORT_HEIGHT = 800;
5286
5371
  STANDARD_CHART_TYPES = /* @__PURE__ */ new Set([
@@ -6995,6 +7080,7 @@ var init_types2 = __esm({
6995
7080
  // src/infra/parser.ts
6996
7081
  var parser_exports9 = {};
6997
7082
  __export(parser_exports9, {
7083
+ extractSymbols: () => extractSymbols4,
6998
7084
  parseInfra: () => parseInfra
6999
7085
  });
7000
7086
  function nodeId2(name) {
@@ -7037,7 +7123,6 @@ function parseInfra(content) {
7037
7123
  error: null
7038
7124
  };
7039
7125
  const nodeMap = /* @__PURE__ */ new Map();
7040
- const edgeNodeId = "edge";
7041
7126
  const setError = (line10, message) => {
7042
7127
  const diag = makeDgmoError(line10, message);
7043
7128
  result.diagnostics.push(diag);
@@ -7403,6 +7488,38 @@ function parseInfra(content) {
7403
7488
  }
7404
7489
  return result;
7405
7490
  }
7491
+ function extractSymbols4(docText) {
7492
+ const entities = [];
7493
+ let inMetadata = true;
7494
+ let inTagGroup = false;
7495
+ for (const rawLine of docText.split("\n")) {
7496
+ const line10 = rawLine.trim();
7497
+ if (line10.length === 0) continue;
7498
+ const indented = /^\s/.test(rawLine);
7499
+ if (inMetadata) {
7500
+ if (!indented && !/^[a-z-]+\s*:/i.test(line10)) inMetadata = false;
7501
+ else continue;
7502
+ }
7503
+ if (!indented) {
7504
+ if (/^tag\s*:/i.test(line10)) {
7505
+ inTagGroup = true;
7506
+ continue;
7507
+ }
7508
+ inTagGroup = false;
7509
+ if (/^\[/.test(line10)) continue;
7510
+ const m = COMPONENT_RE.exec(line10);
7511
+ if (m && !entities.includes(m[1])) entities.push(m[1]);
7512
+ } else {
7513
+ if (inTagGroup) continue;
7514
+ if (/^->/.test(line10)) continue;
7515
+ if (/^-[^>]+-?>/.test(line10)) continue;
7516
+ if (/^\w[\w-]*\s*:/.test(line10)) continue;
7517
+ const m = COMPONENT_RE.exec(line10);
7518
+ if (m && !entities.includes(m[1])) entities.push(m[1]);
7519
+ }
7520
+ }
7521
+ return { kind: "infra", entities, keywords: [] };
7522
+ }
7406
7523
  var CONNECTION_RE, SIMPLE_CONNECTION_RE, GROUP_RE, TAG_GROUP_RE, TAG_VALUE_RE, COMPONENT_RE, PIPE_META_RE, PROPERTY_RE, PERCENT_RE, RANGE_RE, EDGE_NODE_NAMES;
7407
7524
  var init_parser9 = __esm({
7408
7525
  "src/infra/parser.ts"() {
@@ -8265,7 +8382,6 @@ function layoutOrg(parsed, hiddenCounts, activeTagGroup, hiddenAttributes, expan
8265
8382
  const visibleGroups = activeTagGroup != null ? legendGroups.filter((g) => g.name.toLowerCase() === activeTagGroup.toLowerCase()) : legendGroups;
8266
8383
  const allExpanded = expandAllLegend && activeTagGroup == null;
8267
8384
  const effectiveW = (g) => activeTagGroup != null || allExpanded ? g.width : g.minifiedWidth;
8268
- const effectiveH = (g) => activeTagGroup != null || allExpanded ? g.height : g.minifiedHeight;
8269
8385
  if (visibleGroups.length > 0) {
8270
8386
  if (legendPosition === "bottom") {
8271
8387
  const totalGroupsWidth = visibleGroups.reduce((s, g) => s + effectiveW(g), 0) + (visibleGroups.length - 1) * LEGEND_GROUP_GAP2;
@@ -8419,6 +8535,35 @@ var init_collapse = __esm({
8419
8535
  }
8420
8536
  });
8421
8537
 
8538
+ // src/utils/export-container.ts
8539
+ function runInExportContainer(width, height, fn) {
8540
+ const container = document.createElement("div");
8541
+ container.style.width = `${width}px`;
8542
+ container.style.height = `${height}px`;
8543
+ container.style.position = "absolute";
8544
+ container.style.left = "-9999px";
8545
+ document.body.appendChild(container);
8546
+ try {
8547
+ return fn(container);
8548
+ } finally {
8549
+ document.body.removeChild(container);
8550
+ }
8551
+ }
8552
+ function extractExportSvg(container, theme) {
8553
+ const svgEl = container.querySelector("svg");
8554
+ if (!svgEl) return "";
8555
+ if (theme === "transparent") svgEl.style.background = "none";
8556
+ svgEl.setAttribute("xmlns", "http://www.w3.org/2000/svg");
8557
+ svgEl.style.fontFamily = FONT_FAMILY;
8558
+ return svgEl.outerHTML;
8559
+ }
8560
+ var init_export_container = __esm({
8561
+ "src/utils/export-container.ts"() {
8562
+ "use strict";
8563
+ init_fonts();
8564
+ }
8565
+ });
8566
+
8422
8567
  // src/org/renderer.ts
8423
8568
  var renderer_exports = {};
8424
8569
  __export(renderer_exports, {
@@ -8673,31 +8818,16 @@ function renderOrgForExport(content, theme, palette) {
8673
8818
  const exportHidden = hideOption ? new Set(hideOption.split(",").map((s) => s.trim().toLowerCase())) : void 0;
8674
8819
  const layout = layoutOrg(parsed, void 0, void 0, exportHidden);
8675
8820
  const isDark = theme === "dark";
8676
- const container = document.createElement("div");
8677
8821
  const titleOffset = parsed.title ? TITLE_HEIGHT : 0;
8678
8822
  const exportWidth = layout.width + DIAGRAM_PADDING * 2;
8679
8823
  const exportHeight = layout.height + DIAGRAM_PADDING * 2 + titleOffset;
8680
- container.style.width = `${exportWidth}px`;
8681
- container.style.height = `${exportHeight}px`;
8682
- container.style.position = "absolute";
8683
- container.style.left = "-9999px";
8684
- document.body.appendChild(container);
8685
- try {
8824
+ return runInExportContainer(exportWidth, exportHeight, (container) => {
8686
8825
  renderOrg(container, parsed, layout, palette, isDark, void 0, {
8687
8826
  width: exportWidth,
8688
8827
  height: exportHeight
8689
8828
  });
8690
- const svgEl = container.querySelector("svg");
8691
- if (!svgEl) return "";
8692
- if (theme === "transparent") {
8693
- svgEl.style.background = "none";
8694
- }
8695
- svgEl.setAttribute("xmlns", "http://www.w3.org/2000/svg");
8696
- svgEl.style.fontFamily = FONT_FAMILY;
8697
- return svgEl.outerHTML;
8698
- } finally {
8699
- document.body.removeChild(container);
8700
- }
8829
+ return extractExportSvg(container, theme);
8830
+ });
8701
8831
  }
8702
8832
  var d3Selection, DIAGRAM_PADDING, MAX_SCALE, TITLE_HEIGHT, TITLE_FONT_SIZE, LABEL_FONT_SIZE, META_FONT_SIZE, META_LINE_HEIGHT2, HEADER_HEIGHT2, SEPARATOR_GAP2, EDGE_STROKE_WIDTH, NODE_STROKE_WIDTH, CARD_RADIUS, CONTAINER_RADIUS, CONTAINER_LABEL_FONT_SIZE, CONTAINER_META_FONT_SIZE, CONTAINER_META_LINE_HEIGHT2, CONTAINER_HEADER_HEIGHT, COLLAPSE_BAR_HEIGHT, COLLAPSE_BAR_INSET, LEGEND_FIXED_GAP;
8703
8833
  var init_renderer = __esm({
@@ -8705,6 +8835,7 @@ var init_renderer = __esm({
8705
8835
  "use strict";
8706
8836
  d3Selection = __toESM(require("d3-selection"), 1);
8707
8837
  init_fonts();
8838
+ init_export_container();
8708
8839
  init_color_utils();
8709
8840
  init_parser4();
8710
8841
  init_layout();
@@ -10290,7 +10421,6 @@ function renderClassDiagram(container, parsed, layout, palette, isDark, onClickI
10290
10421
  const scaleY = (availH - DIAGRAM_PADDING4 * 2) / diagramH;
10291
10422
  const scale = Math.min(MAX_SCALE3, scaleX, scaleY);
10292
10423
  const scaledW = diagramW * scale;
10293
- const scaledH = diagramH * scale;
10294
10424
  const offsetX = (width - scaledW) / 2;
10295
10425
  const offsetY = titleHeight + DIAGRAM_PADDING4;
10296
10426
  const svg = d3Selection4.select(container).append("svg").attr("width", width).attr("height", height).style("font-family", FONT_FAMILY);
@@ -10421,15 +10551,9 @@ function renderClassDiagramForExport(content, theme, palette) {
10421
10551
  if (parsed.error || parsed.classes.length === 0) return "";
10422
10552
  const layout = layoutClassDiagram(parsed);
10423
10553
  const isDark = theme === "dark";
10424
- const container = document.createElement("div");
10425
10554
  const exportWidth = layout.width + DIAGRAM_PADDING4 * 2;
10426
10555
  const exportHeight = layout.height + DIAGRAM_PADDING4 * 2 + (parsed.title ? 40 : 0);
10427
- container.style.width = `${exportWidth}px`;
10428
- container.style.height = `${exportHeight}px`;
10429
- container.style.position = "absolute";
10430
- container.style.left = "-9999px";
10431
- document.body.appendChild(container);
10432
- try {
10556
+ return runInExportContainer(exportWidth, exportHeight, (container) => {
10433
10557
  renderClassDiagram(
10434
10558
  container,
10435
10559
  parsed,
@@ -10439,17 +10563,8 @@ function renderClassDiagramForExport(content, theme, palette) {
10439
10563
  void 0,
10440
10564
  { width: exportWidth, height: exportHeight }
10441
10565
  );
10442
- const svgEl = container.querySelector("svg");
10443
- if (!svgEl) return "";
10444
- if (theme === "transparent") {
10445
- svgEl.style.background = "none";
10446
- }
10447
- svgEl.setAttribute("xmlns", "http://www.w3.org/2000/svg");
10448
- svgEl.style.fontFamily = FONT_FAMILY;
10449
- return svgEl.outerHTML;
10450
- } finally {
10451
- document.body.removeChild(container);
10452
- }
10566
+ return extractExportSvg(container, theme);
10567
+ });
10453
10568
  }
10454
10569
  var d3Selection4, d3Shape2, DIAGRAM_PADDING4, MAX_SCALE3, CLASS_FONT_SIZE, MEMBER_FONT_SIZE, EDGE_LABEL_FONT_SIZE2, EDGE_STROKE_WIDTH3, NODE_STROKE_WIDTH3, MEMBER_LINE_HEIGHT2, COMPARTMENT_PADDING_Y2, MEMBER_PADDING_X, lineGenerator2;
10455
10570
  var init_renderer4 = __esm({
@@ -10458,6 +10573,7 @@ var init_renderer4 = __esm({
10458
10573
  d3Selection4 = __toESM(require("d3-selection"), 1);
10459
10574
  d3Shape2 = __toESM(require("d3-shape"), 1);
10460
10575
  init_fonts();
10576
+ init_export_container();
10461
10577
  init_color_utils();
10462
10578
  init_parser2();
10463
10579
  init_layout3();
@@ -11717,7 +11833,6 @@ function renderInitiativeStatus(container, parsed, layout, palette, isDark, onCl
11717
11833
  const scaleY = (availH - DIAGRAM_PADDING6 * 2) / diagramH;
11718
11834
  const scale = Math.min(MAX_SCALE5, scaleX, scaleY);
11719
11835
  const scaledW = diagramW * scale;
11720
- const scaledH = diagramH * scale;
11721
11836
  const offsetX = (width - scaledW) / 2;
11722
11837
  const offsetY = titleHeight + DIAGRAM_PADDING6;
11723
11838
  const svg = d3Selection6.select(container).append("svg").attr("width", width).attr("height", height).style("font-family", FONT_FAMILY);
@@ -11900,13 +12015,7 @@ function renderInitiativeStatusForExport(content, theme, palette) {
11900
12015
  const titleOffset = parsed.title ? 40 : 0;
11901
12016
  const exportWidth = layout.width + DIAGRAM_PADDING6 * 2;
11902
12017
  const exportHeight = layout.height + DIAGRAM_PADDING6 * 2 + titleOffset;
11903
- const container = document.createElement("div");
11904
- container.style.width = `${exportWidth}px`;
11905
- container.style.height = `${exportHeight}px`;
11906
- container.style.position = "absolute";
11907
- container.style.left = "-9999px";
11908
- document.body.appendChild(container);
11909
- try {
12018
+ return runInExportContainer(exportWidth, exportHeight, (container) => {
11910
12019
  renderInitiativeStatus(
11911
12020
  container,
11912
12021
  parsed,
@@ -11916,17 +12025,8 @@ function renderInitiativeStatusForExport(content, theme, palette) {
11916
12025
  void 0,
11917
12026
  { width: exportWidth, height: exportHeight }
11918
12027
  );
11919
- const svgEl = container.querySelector("svg");
11920
- if (!svgEl) return "";
11921
- if (theme === "transparent") {
11922
- svgEl.style.background = "none";
11923
- }
11924
- svgEl.setAttribute("xmlns", "http://www.w3.org/2000/svg");
11925
- svgEl.style.fontFamily = FONT_FAMILY;
11926
- return svgEl.outerHTML;
11927
- } finally {
11928
- document.body.removeChild(container);
11929
- }
12028
+ return extractExportSvg(container, theme);
12029
+ });
11930
12030
  }
11931
12031
  var d3Selection6, d3Shape4, DIAGRAM_PADDING6, MAX_SCALE5, NODE_FONT_SIZE2, MIN_NODE_FONT_SIZE, EDGE_LABEL_FONT_SIZE4, EDGE_STROKE_WIDTH5, NODE_STROKE_WIDTH5, NODE_RX, ARROWHEAD_W2, ARROWHEAD_H2, CHAR_WIDTH_RATIO2, NODE_TEXT_PADDING2, SERVICE_RX, GROUP_EXTRA_PADDING, GROUP_LABEL_FONT_SIZE, COLLAPSE_BAR_HEIGHT3, lineGenerator4;
11932
12032
  var init_renderer6 = __esm({
@@ -11935,6 +12035,7 @@ var init_renderer6 = __esm({
11935
12035
  d3Selection6 = __toESM(require("d3-selection"), 1);
11936
12036
  d3Shape4 = __toESM(require("d3-shape"), 1);
11937
12037
  init_fonts();
12038
+ init_export_container();
11938
12039
  init_color_utils();
11939
12040
  init_parser7();
11940
12041
  init_layout5();
@@ -12202,8 +12303,6 @@ function collectAllRelationships(elements, ownerMap) {
12202
12303
  function rollUpContextRelationships(parsed) {
12203
12304
  const ownerMap = buildOwnershipMap(parsed.elements);
12204
12305
  const allRels = collectAllRelationships(parsed.elements, ownerMap);
12205
- for (const rel of parsed.relationships) {
12206
- }
12207
12306
  const topLevelNames = new Set(parsed.elements.map((e) => e.name));
12208
12307
  const explicitKeys = /* @__PURE__ */ new Set();
12209
12308
  const explicit = [];
@@ -12334,7 +12433,7 @@ function computeLegendGroups3(tagGroups) {
12334
12433
  const nameW = group.name.length * LEGEND_PILL_FONT_W4 + LEGEND_PILL_PAD4 * 2;
12335
12434
  let capsuleW = LEGEND_CAPSULE_PAD4;
12336
12435
  for (const e of entries) {
12337
- capsuleW += LEGEND_DOT_R4 * 2 + LEGEND_ENTRY_DOT_GAP4 + e.value.length * LEGEND_ENTRY_FONT_W5 + LEGEND_ENTRY_TRAIL4;
12436
+ capsuleW += LEGEND_DOT_R4 * 2 + LEGEND_ENTRY_DOT_GAP4 + e.value.length * LEGEND_ENTRY_FONT_W4 + LEGEND_ENTRY_TRAIL4;
12338
12437
  }
12339
12438
  capsuleW += LEGEND_CAPSULE_PAD4;
12340
12439
  result.push({
@@ -13415,7 +13514,7 @@ function layoutC4Deployment(parsed, activeTagGroup) {
13415
13514
  }
13416
13515
  return { nodes, edges, legend: legendGroups, groupBoundaries, width: totalWidth, height: totalHeight };
13417
13516
  }
13418
- var import_dagre5, CHAR_WIDTH5, MIN_NODE_WIDTH, MAX_NODE_WIDTH, TYPE_LABEL_HEIGHT, DIVIDER_GAP, NAME_HEIGHT, DESC_LINE_HEIGHT, DESC_CHAR_WIDTH, CARD_V_PAD3, CARD_H_PAD3, META_LINE_HEIGHT5, META_CHAR_WIDTH, MARGIN3, BOUNDARY_PAD, GROUP_BOUNDARY_PAD, LEGEND_HEIGHT4, LEGEND_PILL_FONT_SIZE2, LEGEND_PILL_FONT_W4, LEGEND_PILL_PAD4, LEGEND_DOT_R4, LEGEND_ENTRY_FONT_SIZE2, LEGEND_ENTRY_FONT_W5, LEGEND_ENTRY_DOT_GAP4, LEGEND_ENTRY_TRAIL4, LEGEND_CAPSULE_PAD4, EDGE_NODE_COLLISION_WEIGHT, META_EXCLUDE_KEYS;
13517
+ var import_dagre5, CHAR_WIDTH5, MIN_NODE_WIDTH, MAX_NODE_WIDTH, TYPE_LABEL_HEIGHT, DIVIDER_GAP, NAME_HEIGHT, DESC_LINE_HEIGHT, DESC_CHAR_WIDTH, CARD_V_PAD3, CARD_H_PAD3, META_LINE_HEIGHT5, META_CHAR_WIDTH, MARGIN3, BOUNDARY_PAD, GROUP_BOUNDARY_PAD, LEGEND_HEIGHT4, LEGEND_PILL_FONT_SIZE2, LEGEND_PILL_FONT_W4, LEGEND_PILL_PAD4, LEGEND_DOT_R4, LEGEND_ENTRY_FONT_SIZE2, LEGEND_ENTRY_FONT_W4, LEGEND_ENTRY_DOT_GAP4, LEGEND_ENTRY_TRAIL4, LEGEND_CAPSULE_PAD4, EDGE_NODE_COLLISION_WEIGHT, META_EXCLUDE_KEYS;
13419
13518
  var init_layout6 = __esm({
13420
13519
  "src/c4/layout.ts"() {
13421
13520
  "use strict";
@@ -13441,7 +13540,7 @@ var init_layout6 = __esm({
13441
13540
  LEGEND_PILL_PAD4 = 16;
13442
13541
  LEGEND_DOT_R4 = 4;
13443
13542
  LEGEND_ENTRY_FONT_SIZE2 = 10;
13444
- LEGEND_ENTRY_FONT_W5 = LEGEND_ENTRY_FONT_SIZE2 * 0.6;
13543
+ LEGEND_ENTRY_FONT_W4 = LEGEND_ENTRY_FONT_SIZE2 * 0.6;
13445
13544
  LEGEND_ENTRY_DOT_GAP4 = 4;
13446
13545
  LEGEND_ENTRY_TRAIL4 = 8;
13447
13546
  LEGEND_CAPSULE_PAD4 = 4;
@@ -13533,7 +13632,6 @@ function renderC4Context(container, parsed, layout, palette, isDark, onClickItem
13533
13632
  const scaleY = (availH - DIAGRAM_PADDING7 * 2) / diagramH;
13534
13633
  const scale = Math.min(MAX_SCALE6, scaleX, scaleY);
13535
13634
  const scaledW = diagramW * scale;
13536
- const scaledH = diagramH * scale;
13537
13635
  const offsetX = (width - scaledW) / 2;
13538
13636
  const offsetY = titleHeight + DIAGRAM_PADDING7;
13539
13637
  const svg = d3Selection7.select(container).append("svg").attr("width", width).attr("height", height).style("font-family", FONT_FAMILY);
@@ -14023,7 +14121,6 @@ function renderC4Containers(container, parsed, layout, palette, isDark, onClickI
14023
14121
  const scaleY = (availH - DIAGRAM_PADDING7 * 2) / diagramH;
14024
14122
  const scale = Math.min(MAX_SCALE6, scaleX, scaleY);
14025
14123
  const scaledW = diagramW * scale;
14026
- const scaledH = diagramH * scale;
14027
14124
  const offsetX = (width - scaledW) / 2;
14028
14125
  const offsetY = titleHeight + DIAGRAM_PADDING7;
14029
14126
  const svg = d3Selection7.select(container).append("svg").attr("width", width).attr("height", height).style("font-family", FONT_FAMILY);
@@ -14636,7 +14733,6 @@ function renderFlowchart(container, graph, layout, palette, isDark, onClickItem,
14636
14733
  const scaleY = (availH - DIAGRAM_PADDING8 * 2) / diagramH;
14637
14734
  const scale = Math.min(MAX_SCALE7, scaleX, scaleY);
14638
14735
  const scaledW = diagramW * scale;
14639
- const scaledH = diagramH * scale;
14640
14736
  const offsetX = (width - scaledW) / 2;
14641
14737
  const offsetY = titleHeight + DIAGRAM_PADDING8;
14642
14738
  const svg = d3Selection8.select(container).append("svg").attr("width", width).attr("height", height).style("font-family", FONT_FAMILY);
@@ -18711,7 +18807,6 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
18711
18807
  if (secY === void 0) continue;
18712
18808
  const isCollapsed = collapsedSections?.has(sec.lineNumber) ?? false;
18713
18809
  const lineColor = palette.textMuted;
18714
- const HIT_AREA_HEIGHT = 36;
18715
18810
  const sectionG = svg.append("g").attr("data-section-toggle", "").attr("data-line-number", String(sec.lineNumber)).attr("data-section", "").attr("tabindex", "0").attr("role", "button").attr("aria-expanded", String(!isCollapsed));
18716
18811
  const BAND_HEIGHT = 22;
18717
18812
  const bandX = sectionLineX1 - 10;
@@ -20100,7 +20195,6 @@ function renderArcDiagram(container, parsed, palette, _isDark, onClickItem, expo
20100
20195
  const positions = groupNodes.map((n) => yScale(n));
20101
20196
  const minY = Math.min(...positions) - bandPad;
20102
20197
  const maxY = Math.max(...positions) + bandPad;
20103
- const bandColor = group.color ?? mutedColor;
20104
20198
  g.append("rect").attr("class", "arc-group-band").attr("data-group", group.name).attr("data-line-number", String(group.lineNumber)).attr("x", baseX - bandHalfW).attr("y", minY).attr("width", bandHalfW * 2).attr("height", maxY - minY).attr("rx", 4).attr("fill", textColor).attr("fill-opacity", 0.06).style("cursor", "pointer").on("mouseenter", () => handleGroupEnter(group.name)).on("mouseleave", handleMouseLeave).on("click", () => {
20105
20199
  if (onClickItem) onClickItem(group.lineNumber);
20106
20200
  });
@@ -20144,7 +20238,6 @@ function renderArcDiagram(container, parsed, palette, _isDark, onClickItem, expo
20144
20238
  const positions = groupNodes.map((n) => xScale(n));
20145
20239
  const minX = Math.min(...positions) - bandPad;
20146
20240
  const maxX = Math.max(...positions) + bandPad;
20147
- const bandColor = group.color ?? mutedColor;
20148
20241
  g.append("rect").attr("class", "arc-group-band").attr("data-group", group.name).attr("data-line-number", String(group.lineNumber)).attr("x", minX).attr("y", baseY - bandHalfH).attr("width", maxX - minX).attr("height", bandHalfH * 2).attr("rx", 4).attr("fill", textColor).attr("fill-opacity", 0.06).style("cursor", "pointer").on("mouseenter", () => handleGroupEnter(group.name)).on("mouseleave", handleMouseLeave).on("click", () => {
20149
20242
  if (onClickItem) onClickItem(group.lineNumber);
20150
20243
  });
@@ -20462,6 +20555,7 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
20462
20555
  const textColor = palette.text;
20463
20556
  const mutedColor = palette.border;
20464
20557
  const bgColor = palette.bg;
20558
+ const bg = isDark ? palette.surface : palette.bg;
20465
20559
  const colors = getSeriesColors(palette);
20466
20560
  const groupColorMap = /* @__PURE__ */ new Map();
20467
20561
  timelineGroups.forEach((grp, i) => {
@@ -20723,7 +20817,7 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
20723
20817
  if (ev.endDate) {
20724
20818
  const y2 = yScale(parseTimelineDate(ev.endDate));
20725
20819
  const rectH = Math.max(y2 - y, 4);
20726
- let fill2 = evColor;
20820
+ let fill2 = mix(evColor, bg, 30);
20727
20821
  if (ev.uncertain) {
20728
20822
  const gradientId = `uncertain-vg-${ev.lineNumber}`;
20729
20823
  const defs = svg.select("defs").node() || svg.append("defs").node();
@@ -20731,13 +20825,13 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
20731
20825
  { offset: "0%", opacity: 1 },
20732
20826
  { offset: "80%", opacity: 1 },
20733
20827
  { offset: "100%", opacity: 0 }
20734
- ]).enter().append("stop").attr("offset", (d) => d.offset).attr("stop-color", laneColor).attr("stop-opacity", (d) => d.opacity);
20828
+ ]).enter().append("stop").attr("offset", (d) => d.offset).attr("stop-color", mix(laneColor, bg, 30)).attr("stop-opacity", (d) => d.opacity);
20735
20829
  fill2 = `url(#${gradientId})`;
20736
20830
  }
20737
- evG.append("rect").attr("x", laneCenter - 6).attr("y", y).attr("width", 12).attr("height", rectH).attr("rx", 4).attr("fill", fill2);
20831
+ evG.append("rect").attr("x", laneCenter - 6).attr("y", y).attr("width", 12).attr("height", rectH).attr("rx", 4).attr("fill", fill2).attr("stroke", evColor).attr("stroke-width", 2);
20738
20832
  evG.append("text").attr("x", laneCenter + 14).attr("y", y + rectH / 2).attr("dy", "0.35em").attr("fill", textColor).attr("font-size", "10px").text(ev.label);
20739
20833
  } else {
20740
- evG.append("circle").attr("cx", laneCenter).attr("cy", y).attr("r", 4).attr("fill", evColor).attr("stroke", bgColor).attr("stroke-width", 1.5);
20834
+ evG.append("circle").attr("cx", laneCenter).attr("cy", y).attr("r", 4).attr("fill", mix(evColor, bg, 30)).attr("stroke", evColor).attr("stroke-width", 2);
20741
20835
  evG.append("text").attr("x", laneCenter + 10).attr("y", y).attr("dy", "0.35em").attr("fill", textColor).attr("font-size", "10px").text(ev.label);
20742
20836
  }
20743
20837
  }
@@ -20830,7 +20924,7 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
20830
20924
  if (ev.endDate) {
20831
20925
  const y2 = yScale(parseTimelineDate(ev.endDate));
20832
20926
  const rectH = Math.max(y2 - y, 4);
20833
- let fill2 = color;
20927
+ let fill2 = mix(color, bg, 30);
20834
20928
  if (ev.uncertain) {
20835
20929
  const gradientId = `uncertain-v-${ev.lineNumber}`;
20836
20930
  const defs = svg.select("defs").node() || svg.append("defs").node();
@@ -20838,13 +20932,13 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
20838
20932
  { offset: "0%", opacity: 1 },
20839
20933
  { offset: "80%", opacity: 1 },
20840
20934
  { offset: "100%", opacity: 0 }
20841
- ]).enter().append("stop").attr("offset", (d) => d.offset).attr("stop-color", color).attr("stop-opacity", (d) => d.opacity);
20935
+ ]).enter().append("stop").attr("offset", (d) => d.offset).attr("stop-color", mix(color, bg, 30)).attr("stop-opacity", (d) => d.opacity);
20842
20936
  fill2 = `url(#${gradientId})`;
20843
20937
  }
20844
- evG.append("rect").attr("x", axisX - 6).attr("y", y).attr("width", 12).attr("height", rectH).attr("rx", 4).attr("fill", fill2);
20938
+ evG.append("rect").attr("x", axisX - 6).attr("y", y).attr("width", 12).attr("height", rectH).attr("rx", 4).attr("fill", fill2).attr("stroke", color).attr("stroke-width", 2);
20845
20939
  evG.append("text").attr("x", axisX + 16).attr("y", y + rectH / 2).attr("dy", "0.35em").attr("fill", textColor).attr("font-size", "11px").text(ev.label);
20846
20940
  } else {
20847
- evG.append("circle").attr("cx", axisX).attr("cy", y).attr("r", 4).attr("fill", color).attr("stroke", bgColor).attr("stroke-width", 1.5);
20941
+ evG.append("circle").attr("cx", axisX).attr("cy", y).attr("r", 4).attr("fill", mix(color, bg, 30)).attr("stroke", color).attr("stroke-width", 2);
20848
20942
  evG.append("text").attr("x", axisX + 16).attr("y", y).attr("dy", "0.35em").attr("fill", textColor).attr("font-size", "11px").text(ev.label);
20849
20943
  }
20850
20944
  evG.append("text").attr("x", axisX - 14).attr(
@@ -20995,7 +21089,7 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
20995
21089
  const rectW = Math.max(x2 - x, 4);
20996
21090
  const estLabelWidth = ev.label.length * 7 + 16;
20997
21091
  const labelFitsInside = rectW >= estLabelWidth;
20998
- let fill2 = evColor;
21092
+ let fill2 = mix(evColor, bg, 30);
20999
21093
  if (ev.uncertain) {
21000
21094
  const gradientId = `uncertain-${ev.lineNumber}`;
21001
21095
  const defs = svg.select("defs").node() || svg.append("defs").node();
@@ -21003,12 +21097,12 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
21003
21097
  { offset: "0%", opacity: 1 },
21004
21098
  { offset: "80%", opacity: 1 },
21005
21099
  { offset: "100%", opacity: 0 }
21006
- ]).enter().append("stop").attr("offset", (d) => d.offset).attr("stop-color", evColor).attr("stop-opacity", (d) => d.opacity);
21100
+ ]).enter().append("stop").attr("offset", (d) => d.offset).attr("stop-color", mix(evColor, bg, 30)).attr("stop-opacity", (d) => d.opacity);
21007
21101
  fill2 = `url(#${gradientId})`;
21008
21102
  }
21009
- evG.append("rect").attr("x", x).attr("y", y - BAR_H / 2).attr("width", rectW).attr("height", BAR_H).attr("rx", 4).attr("fill", fill2);
21103
+ evG.append("rect").attr("x", x).attr("y", y - BAR_H / 2).attr("width", rectW).attr("height", BAR_H).attr("rx", 4).attr("fill", fill2).attr("stroke", evColor).attr("stroke-width", 2);
21010
21104
  if (labelFitsInside) {
21011
- evG.append("text").attr("x", x + 8).attr("y", y).attr("dy", "0.35em").attr("text-anchor", "start").attr("fill", "#ffffff").attr("font-size", "14px").attr("font-weight", "700").text(ev.label);
21105
+ evG.append("text").attr("x", x + 8).attr("y", y).attr("dy", "0.35em").attr("text-anchor", "start").attr("fill", textColor).attr("font-size", "14px").attr("font-weight", "700").text(ev.label);
21012
21106
  } else {
21013
21107
  const wouldFlipLeft = x + rectW > innerWidth * 0.6;
21014
21108
  const labelFitsLeft = x - 6 - estLabelWidth > 0;
@@ -21020,7 +21114,7 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
21020
21114
  const wouldFlipLeft = x > innerWidth * 0.6;
21021
21115
  const labelFitsLeft = x - 10 - estLabelWidth > 0;
21022
21116
  const flipLeft = wouldFlipLeft && labelFitsLeft;
21023
- evG.append("circle").attr("cx", x).attr("cy", y).attr("r", 5).attr("fill", evColor).attr("stroke", bgColor).attr("stroke-width", 1.5);
21117
+ evG.append("circle").attr("cx", x).attr("cy", y).attr("r", 5).attr("fill", mix(evColor, bg, 30)).attr("stroke", evColor).attr("stroke-width", 2);
21024
21118
  evG.append("text").attr("x", flipLeft ? x - 10 : x + 10).attr("y", y).attr("dy", "0.35em").attr("text-anchor", flipLeft ? "end" : "start").attr("fill", textColor).attr("font-size", "12px").text(ev.label);
21025
21119
  }
21026
21120
  });
@@ -21133,7 +21227,7 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
21133
21227
  const rectW = Math.max(x2 - x, 4);
21134
21228
  const estLabelWidth = ev.label.length * 7 + 16;
21135
21229
  const labelFitsInside = rectW >= estLabelWidth;
21136
- let fill2 = color;
21230
+ let fill2 = mix(color, bg, 30);
21137
21231
  if (ev.uncertain) {
21138
21232
  const gradientId = `uncertain-ts-${ev.lineNumber}`;
21139
21233
  const defs = svg.select("defs").node() || svg.append("defs").node();
@@ -21141,12 +21235,12 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
21141
21235
  { offset: "0%", opacity: 1 },
21142
21236
  { offset: "80%", opacity: 1 },
21143
21237
  { offset: "100%", opacity: 0 }
21144
- ]).enter().append("stop").attr("offset", (d) => d.offset).attr("stop-color", color).attr("stop-opacity", (d) => d.opacity);
21238
+ ]).enter().append("stop").attr("offset", (d) => d.offset).attr("stop-color", mix(color, bg, 30)).attr("stop-opacity", (d) => d.opacity);
21145
21239
  fill2 = `url(#${gradientId})`;
21146
21240
  }
21147
- evG.append("rect").attr("x", x).attr("y", y - BAR_H / 2).attr("width", rectW).attr("height", BAR_H).attr("rx", 4).attr("fill", fill2);
21241
+ evG.append("rect").attr("x", x).attr("y", y - BAR_H / 2).attr("width", rectW).attr("height", BAR_H).attr("rx", 4).attr("fill", fill2).attr("stroke", color).attr("stroke-width", 2);
21148
21242
  if (labelFitsInside) {
21149
- evG.append("text").attr("x", x + 8).attr("y", y).attr("dy", "0.35em").attr("text-anchor", "start").attr("fill", "#ffffff").attr("font-size", "14px").attr("font-weight", "700").text(ev.label);
21243
+ evG.append("text").attr("x", x + 8).attr("y", y).attr("dy", "0.35em").attr("text-anchor", "start").attr("fill", textColor).attr("font-size", "14px").attr("font-weight", "700").text(ev.label);
21150
21244
  } else {
21151
21245
  const wouldFlipLeft = x + rectW > innerWidth * 0.6;
21152
21246
  const labelFitsLeft = x - 6 - estLabelWidth > 0;
@@ -21158,7 +21252,7 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
21158
21252
  const wouldFlipLeft = x > innerWidth * 0.6;
21159
21253
  const labelFitsLeft = x - 10 - estLabelWidth > 0;
21160
21254
  const flipLeft = wouldFlipLeft && labelFitsLeft;
21161
- evG.append("circle").attr("cx", x).attr("cy", y).attr("r", 5).attr("fill", color).attr("stroke", bgColor).attr("stroke-width", 1.5);
21255
+ evG.append("circle").attr("cx", x).attr("cy", y).attr("r", 5).attr("fill", mix(color, bg, 30)).attr("stroke", color).attr("stroke-width", 2);
21162
21256
  evG.append("text").attr("x", flipLeft ? x - 10 : x + 10).attr("y", y).attr("dy", "0.35em").attr("text-anchor", flipLeft ? "end" : "start").attr("fill", textColor).attr("font-size", "12px").text(ev.label);
21163
21257
  }
21164
21258
  });
@@ -21313,8 +21407,8 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
21313
21407
  } else {
21314
21408
  color = ev.group && groupColorMap.has(ev.group) ? groupColorMap.get(ev.group) : textColor;
21315
21409
  }
21316
- el.selectAll("rect").attr("fill", color);
21317
- el.selectAll("circle:not(.tl-event-point-outline)").attr("fill", color);
21410
+ el.selectAll("rect").attr("fill", mix(color, bg, 30)).attr("stroke", color);
21411
+ el.selectAll("circle:not(.tl-event-point-outline)").attr("fill", mix(color, bg, 30)).attr("stroke", color);
21318
21412
  });
21319
21413
  };
21320
21414
  var drawSwimlaneIcon = drawSwimlaneIcon2, relayout = relayout2, drawLegend = drawLegend2, recolorEvents = recolorEvents2;
@@ -21779,7 +21873,6 @@ function renderQuadrant(container, parsed, palette, isDark, onClickItem, exportD
21779
21873
  const init2 = initD3Chart(container, palette, exportDims);
21780
21874
  if (!init2) return;
21781
21875
  const { svg, width, height, textColor } = init2;
21782
- const mutedColor = palette.textMuted;
21783
21876
  const borderColor = palette.border;
21784
21877
  const defaultColors = [
21785
21878
  palette.colors.blue,
@@ -21803,13 +21896,17 @@ function renderQuadrant(container, parsed, palette, isDark, onClickItem, exportD
21803
21896
  const f = r.length === 3 ? r[0] + r[0] + r[1] + r[1] + r[2] + r[2] : r;
21804
21897
  return [parseInt(f.substring(0, 2), 16), parseInt(f.substring(2, 4), 16), parseInt(f.substring(4, 6), 16)];
21805
21898
  };
21806
- const [ar, ag, ab] = parse(a), [br, bg, bb] = parse(b), t = pct / 100;
21899
+ const [ar, ag, ab] = parse(a), [br, bg2, bb] = parse(b), t = pct / 100;
21807
21900
  const c = (x, y) => Math.round(x * t + y * (1 - t)).toString(16).padStart(2, "0");
21808
- return `#${c(ar, br)}${c(ag, bg)}${c(ab, bb)}`;
21901
+ return `#${c(ar, br)}${c(ag, bg2)}${c(ab, bb)}`;
21809
21902
  };
21810
- const getQuadrantFill = (label, defaultIdx) => {
21903
+ const bg = isDark ? palette.surface : palette.bg;
21904
+ const getQuadrantColor = (label, defaultIdx) => {
21811
21905
  return label?.color ?? defaultColors[defaultIdx % defaultColors.length];
21812
21906
  };
21907
+ const getQuadrantFill = (label, defaultIdx) => {
21908
+ return mixHex(getQuadrantColor(label, defaultIdx), bg, 30);
21909
+ };
21813
21910
  const quadrantDefs = [
21814
21911
  {
21815
21912
  position: "top-left",
@@ -21860,12 +21957,11 @@ function renderQuadrant(container, parsed, palette, isDark, onClickItem, exportD
21860
21957
  // purple
21861
21958
  }
21862
21959
  ];
21863
- const quadrantRects = chartG.selectAll("rect.quadrant").data(quadrantDefs).enter().append("rect").attr("class", "quadrant").attr("x", (d) => d.x).attr("y", (d) => d.y).attr("width", (d) => d.w).attr("height", (d) => d.h).attr("fill", (d) => getQuadrantFill(d.label, d.colorIdx)).attr("stroke", borderColor).attr("stroke-width", 0.5);
21864
- const contrastColor = "#ffffff";
21960
+ const quadrantRects = chartG.selectAll("rect.quadrant").data(quadrantDefs).enter().append("rect").attr("class", "quadrant").attr("x", (d) => d.x).attr("y", (d) => d.y).attr("width", (d) => d.w).attr("height", (d) => d.h).attr("fill", (d) => getQuadrantFill(d.label, d.colorIdx)).attr("stroke", (d) => getQuadrantColor(d.label, d.colorIdx)).attr("stroke-width", 2);
21865
21961
  const shadowColor = "rgba(0,0,0,0.4)";
21866
21962
  const getQuadrantLabelColor = (d) => {
21867
- const fill2 = getQuadrantFill(d.label, d.colorIdx);
21868
- return mixHex("#000000", fill2, 40);
21963
+ const color = getQuadrantColor(d.label, d.colorIdx);
21964
+ return mixHex("#000000", color, 40);
21869
21965
  };
21870
21966
  const LABEL_MAX_FONT = 48;
21871
21967
  const LABEL_MIN_FONT = 14;
@@ -22006,7 +22102,7 @@ function renderQuadrant(container, parsed, palette, isDark, onClickItem, exportD
22006
22102
  const pointColor = quadDef?.label?.color ?? defaultColors[quadDef?.colorIdx ?? 0];
22007
22103
  const pointG = pointsG.append("g").attr("class", "point-group").attr("data-line-number", String(point.lineNumber));
22008
22104
  pointG.append("circle").attr("cx", cx).attr("cy", cy).attr("r", 6).attr("fill", "#ffffff").attr("stroke", pointColor).attr("stroke-width", 2);
22009
- pointG.append("text").attr("x", cx).attr("y", cy - 10).attr("text-anchor", "middle").attr("fill", contrastColor).attr("font-size", "12px").attr("font-weight", "700").style("text-shadow", `0 1px 2px ${shadowColor}`).text(point.label);
22105
+ pointG.append("text").attr("x", cx).attr("y", cy - 10).attr("text-anchor", "middle").attr("fill", textColor).attr("font-size", "12px").attr("font-weight", "700").style("text-shadow", `0 1px 2px ${shadowColor}`).text(point.label);
22010
22106
  const tipHtml = `<strong>${point.label}</strong><br>x: ${point.x.toFixed(2)}, y: ${point.y.toFixed(2)}`;
22011
22107
  pointG.style("cursor", onClickItem ? "pointer" : "default").on("mouseenter", (event) => {
22012
22108
  showTooltip(tooltip, tipHtml, event);
@@ -22507,6 +22603,7 @@ __export(index_exports, {
22507
22603
  contrastText: () => contrastText,
22508
22604
  decodeDiagramUrl: () => decodeDiagramUrl,
22509
22605
  encodeDiagramUrl: () => encodeDiagramUrl,
22606
+ extractDiagramSymbols: () => extractDiagramSymbols,
22510
22607
  formatDateLabel: () => formatDateLabel,
22511
22608
  formatDgmoError: () => formatDgmoError,
22512
22609
  getAvailablePalettes: () => getAvailablePalettes,
@@ -22570,6 +22667,7 @@ __export(index_exports, {
22570
22667
  parseState: () => parseState,
22571
22668
  parseTimelineDate: () => parseTimelineDate,
22572
22669
  parseVisualization: () => parseVisualization,
22670
+ registerExtractor: () => registerExtractor,
22573
22671
  registerPalette: () => registerPalette,
22574
22672
  render: () => render,
22575
22673
  renderArcDiagram: () => renderArcDiagram,
@@ -23423,6 +23521,34 @@ function decodeDiagramUrl(hash) {
23423
23521
  }
23424
23522
  }
23425
23523
 
23524
+ // src/completion.ts
23525
+ init_parser3();
23526
+ init_flowchart_parser();
23527
+ init_parser9();
23528
+ init_parser2();
23529
+ var registry = /* @__PURE__ */ new Map();
23530
+ function registerExtractor(kind, fn) {
23531
+ registry.set(kind, fn);
23532
+ }
23533
+ function extractDiagramSymbols(docText) {
23534
+ let chartType = null;
23535
+ for (const line10 of docText.split("\n")) {
23536
+ const m = line10.match(/^\s*chart\s*:\s*(.+)/i);
23537
+ if (m) {
23538
+ chartType = m[1].trim().toLowerCase();
23539
+ break;
23540
+ }
23541
+ }
23542
+ if (!chartType) return null;
23543
+ const fn = registry.get(chartType);
23544
+ if (!fn) return null;
23545
+ return fn(docText);
23546
+ }
23547
+ registerExtractor("er", extractSymbols3);
23548
+ registerExtractor("flowchart", extractSymbols);
23549
+ registerExtractor("infra", extractSymbols4);
23550
+ registerExtractor("class", extractSymbols2);
23551
+
23426
23552
  // src/index.ts
23427
23553
  init_branding();
23428
23554
  // Annotate the CommonJS export names for ESM import in node:
@@ -23455,6 +23581,7 @@ init_branding();
23455
23581
  contrastText,
23456
23582
  decodeDiagramUrl,
23457
23583
  encodeDiagramUrl,
23584
+ extractDiagramSymbols,
23458
23585
  formatDateLabel,
23459
23586
  formatDgmoError,
23460
23587
  getAvailablePalettes,
@@ -23518,6 +23645,7 @@ init_branding();
23518
23645
  parseState,
23519
23646
  parseTimelineDate,
23520
23647
  parseVisualization,
23648
+ registerExtractor,
23521
23649
  registerPalette,
23522
23650
  render,
23523
23651
  renderArcDiagram,