@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.js CHANGED
@@ -1787,12 +1787,12 @@ var SYNC_LABELED_RE, ASYNC_LABELED_RE, RETURN_SYNC_LABELED_RE, RETURN_ASYNC_LABE
1787
1787
  var init_arrows = __esm({
1788
1788
  "src/utils/arrows.ts"() {
1789
1789
  "use strict";
1790
- SYNC_LABELED_RE = /^(\S+)\s+-(.+)->\s+(\S+)$/;
1791
- ASYNC_LABELED_RE = /^(\S+)\s+~(.+)~>\s+(\S+)$/;
1792
- RETURN_SYNC_LABELED_RE = /^(\S+)\s+<-(.+)-\s+(\S+)$/;
1793
- RETURN_ASYNC_LABELED_RE = /^(\S+)\s+<~(.+)~\s+(\S+)$/;
1794
- BIDI_SYNC_RE = /^(\S+)\s+<-(.+)->\s+(\S+)$/;
1795
- BIDI_ASYNC_RE = /^(\S+)\s+<~(.+)~>\s+(\S+)$/;
1790
+ SYNC_LABELED_RE = /^(.+?)\s+-(.+)->\s+(.+)$/;
1791
+ ASYNC_LABELED_RE = /^(.+?)\s+~(.+)~>\s+(.+)$/;
1792
+ RETURN_SYNC_LABELED_RE = /^(.+?)\s+<-(.+)-\s+(.+)$/;
1793
+ RETURN_ASYNC_LABELED_RE = /^(.+?)\s+<~(.+)~\s+(.+)$/;
1794
+ BIDI_SYNC_RE = /^(.+?)\s+<-(.+)->\s+(.+)$/;
1795
+ BIDI_ASYNC_RE = /^(.+?)\s+<~(.+)~>\s+(.+)$/;
1796
1796
  ARROW_CHARS = ["->", "~>"];
1797
1797
  }
1798
1798
  });
@@ -2201,7 +2201,7 @@ function parseSequenceDgmo(content) {
2201
2201
  continue;
2202
2202
  }
2203
2203
  const bidiPlainMatch = arrowCore.match(
2204
- /^(\S+)\s*(?:<->|<~>)\s*(\S+)/
2204
+ /^(.+?)\s*(?:<->|<~>)\s*(.+)/
2205
2205
  );
2206
2206
  if (bidiPlainMatch) {
2207
2207
  pushError(
@@ -2210,8 +2210,8 @@ function parseSequenceDgmo(content) {
2210
2210
  );
2211
2211
  continue;
2212
2212
  }
2213
- const bareReturnSync = arrowCore.match(/^(\S+)\s+<-\s+(\S+)$/);
2214
- const bareReturnAsync = arrowCore.match(/^(\S+)\s+<~\s+(\S+)$/);
2213
+ const bareReturnSync = arrowCore.match(/^(.+?)\s+<-\s+(.+)$/);
2214
+ const bareReturnAsync = arrowCore.match(/^(.+?)\s+<~\s+(.+)$/);
2215
2215
  const bareReturn = bareReturnSync || bareReturnAsync;
2216
2216
  if (bareReturn) {
2217
2217
  const to = bareReturn[1];
@@ -2222,8 +2222,8 @@ function parseSequenceDgmo(content) {
2222
2222
  );
2223
2223
  continue;
2224
2224
  }
2225
- const bareCallSync = arrowCore.match(/^(\S+)\s*->\s*(\S+)$/);
2226
- const bareCallAsync = arrowCore.match(/^(\S+)\s*~>\s*(\S+)$/);
2225
+ const bareCallSync = arrowCore.match(/^(.+?)\s*->\s*(.+)$/);
2226
+ const bareCallAsync = arrowCore.match(/^(.+?)\s*~>\s*(.+)$/);
2227
2227
  const bareCall = bareCallSync || bareCallAsync;
2228
2228
  if (bareCall) {
2229
2229
  contentStarted = true;
@@ -2475,21 +2475,22 @@ var init_parser = __esm({
2475
2475
  "networking",
2476
2476
  "frontend"
2477
2477
  ]);
2478
- IS_A_PATTERN = /^(\S+)\s+is\s+an?\s+(\w+)(?:\s+(.+))?$/i;
2479
- POSITION_ONLY_PATTERN = /^(\S+)\s+position\s+(-?\d+)$/i;
2478
+ IS_A_PATTERN = /^([^:]+?)\s+is\s+an?\s+(\w+)(?:\s+(.+))?$/i;
2479
+ POSITION_ONLY_PATTERN = /^([^:]+?)\s+position\s+(-?\d+)$/i;
2480
2480
  COLORED_PARTICIPANT_PATTERN = /^(\S+?)\(([^)]+)\)\s*$/;
2481
2481
  GROUP_HEADING_PATTERN = /^\[(.+?)(?:\(([^)]+)\))?\]\s*$/;
2482
2482
  LEGACY_GROUP_PATTERN = /^##\s+(.+?)(?:\(([^)]+)\))?\s*$/;
2483
2483
  SECTION_PATTERN = /^==\s+(.+?)(?:\s*==)?\s*$/;
2484
2484
  ARROW_PATTERN = /\S+\s*(?:<-\S+-|<~\S+~|-\S+->|~\S+~>|->|~>|<-|<~)\s*\S+/;
2485
- NOTE_SINGLE = /^note(?:\s+(right|left)\s+of\s+(\S+))?\s*:\s*(.+)$/i;
2486
- NOTE_MULTI = /^note(?:\s+(right|left)\s+of\s+([^\s:]+))?\s*:?\s*$/i;
2485
+ NOTE_SINGLE = /^note(?:\s+(right|left)\s+of\s+(.+?))?\s*:\s*(.+)$/i;
2486
+ NOTE_MULTI = /^note(?:\s+(right|left)\s+of\s+(.+?))?\s*:?\s*$/i;
2487
2487
  }
2488
2488
  });
2489
2489
 
2490
2490
  // src/graph/flowchart-parser.ts
2491
2491
  var flowchart_parser_exports = {};
2492
2492
  __export(flowchart_parser_exports, {
2493
+ extractSymbols: () => extractSymbols,
2493
2494
  looksLikeFlowchart: () => looksLikeFlowchart,
2494
2495
  parseFlowchart: () => parseFlowchart
2495
2496
  });
@@ -2533,7 +2534,6 @@ function parseNodeRef(text, palette) {
2533
2534
  }
2534
2535
  function splitArrows(line10) {
2535
2536
  const segments = [];
2536
- const arrowRe = /(?:^|\s)-([^>\s(][^(>]*?)?\s*(?:\(([^)]+)\))?\s*->|(?:^|\s)->/g;
2537
2537
  let lastIndex = 0;
2538
2538
  const arrowPositions = [];
2539
2539
  let searchFrom = 0;
@@ -2774,7 +2774,20 @@ function looksLikeFlowchart(content) {
2774
2774
  /->[ \t]*[\[(<\/]/.test(content);
2775
2775
  return shapeNearArrow;
2776
2776
  }
2777
- var LEGACY_GROUP_RE;
2777
+ function extractSymbols(docText) {
2778
+ const entities = [];
2779
+ let inMetadata = true;
2780
+ for (const rawLine of docText.split("\n")) {
2781
+ const line10 = rawLine.trim();
2782
+ if (inMetadata && /^[a-z-]+\s*:/i.test(line10)) continue;
2783
+ inMetadata = false;
2784
+ if (line10.length === 0 || /^\s/.test(rawLine)) continue;
2785
+ const m = NODE_ID_RE.exec(line10);
2786
+ if (m && !entities.includes(m[1])) entities.push(m[1]);
2787
+ }
2788
+ return { kind: "flowchart", entities, keywords: [] };
2789
+ }
2790
+ var LEGACY_GROUP_RE, NODE_ID_RE;
2778
2791
  var init_flowchart_parser = __esm({
2779
2792
  "src/graph/flowchart-parser.ts"() {
2780
2793
  "use strict";
@@ -2782,6 +2795,7 @@ var init_flowchart_parser = __esm({
2782
2795
  init_diagnostics();
2783
2796
  init_parsing();
2784
2797
  LEGACY_GROUP_RE = /^##\s+/;
2798
+ NODE_ID_RE = /^([a-zA-Z_][\w-]*)[\s([</{]/;
2785
2799
  }
2786
2800
  });
2787
2801
 
@@ -3057,6 +3071,7 @@ var init_state_parser = __esm({
3057
3071
  // src/class/parser.ts
3058
3072
  var parser_exports2 = {};
3059
3073
  __export(parser_exports2, {
3074
+ extractSymbols: () => extractSymbols2,
3060
3075
  looksLikeClassDiagram: () => looksLikeClassDiagram,
3061
3076
  parseClassDiagram: () => parseClassDiagram
3062
3077
  });
@@ -3304,6 +3319,23 @@ function looksLikeClassDiagram(content) {
3304
3319
  if (hasRelationship && hasClassDecl && hasIndentedMember) return true;
3305
3320
  return false;
3306
3321
  }
3322
+ function extractSymbols2(docText) {
3323
+ const entities = [];
3324
+ let inMetadata = true;
3325
+ for (const rawLine of docText.split("\n")) {
3326
+ const line10 = rawLine.trim();
3327
+ if (inMetadata && /^[a-z-]+\s*:/i.test(line10)) continue;
3328
+ inMetadata = false;
3329
+ if (line10.length === 0 || /^\s/.test(rawLine)) continue;
3330
+ const m = CLASS_DECL_RE.exec(line10);
3331
+ if (m && !entities.includes(m[1])) entities.push(m[1]);
3332
+ }
3333
+ return {
3334
+ kind: "class",
3335
+ entities,
3336
+ keywords: ["extends", "implements", "abstract", "interface", "enum"]
3337
+ };
3338
+ }
3307
3339
  var CLASS_DECL_RE, REL_ARROW_RE, VISIBILITY_RE, STATIC_SUFFIX_RE, METHOD_RE, FIELD_RE, ARROW_TO_TYPE;
3308
3340
  var init_parser2 = __esm({
3309
3341
  "src/class/parser.ts"() {
@@ -3331,6 +3363,7 @@ var init_parser2 = __esm({
3331
3363
  // src/er/parser.ts
3332
3364
  var parser_exports3 = {};
3333
3365
  __export(parser_exports3, {
3366
+ extractSymbols: () => extractSymbols3,
3334
3367
  looksLikeERDiagram: () => looksLikeERDiagram,
3335
3368
  parseERDiagram: () => parseERDiagram
3336
3369
  });
@@ -3633,6 +3666,25 @@ function looksLikeERDiagram(content) {
3633
3666
  if (hasRelationship && hasTableDecl) return true;
3634
3667
  return false;
3635
3668
  }
3669
+ function extractSymbols3(docText) {
3670
+ const entities = [];
3671
+ let inMetadata = true;
3672
+ for (const rawLine of docText.split("\n")) {
3673
+ const line10 = rawLine.trim();
3674
+ if (inMetadata && /^chart\s*:/i.test(line10)) continue;
3675
+ if (inMetadata && /^[a-z-]+\s*:/i.test(line10)) continue;
3676
+ inMetadata = false;
3677
+ if (line10.length === 0) continue;
3678
+ if (/^\s/.test(rawLine)) continue;
3679
+ const m = TABLE_DECL_RE.exec(line10);
3680
+ if (m) entities.push(m[1]);
3681
+ }
3682
+ return {
3683
+ kind: "er",
3684
+ entities,
3685
+ keywords: ["pk", "fk", "unique", "nullable", "1", "*", "?"]
3686
+ };
3687
+ }
3636
3688
  var TABLE_DECL_RE, COLUMN_RE, INDENT_REL_RE, CONSTRAINT_MAP, REL_SYMBOLIC_RE, REL_KEYWORD_RE, KEYWORD_TO_SYMBOL;
3637
3689
  var init_parser3 = __esm({
3638
3690
  "src/er/parser.ts"() {
@@ -4115,10 +4167,12 @@ function buildExtendedChartOption(parsed, palette, isDark) {
4115
4167
  );
4116
4168
  }
4117
4169
  if (parsed.type === "chord") {
4170
+ const bg = isDark ? palette.surface : palette.bg;
4118
4171
  return buildChordOption(
4119
4172
  parsed,
4120
4173
  textColor,
4121
4174
  colors,
4175
+ bg,
4122
4176
  titleConfig,
4123
4177
  tooltipTheme
4124
4178
  );
@@ -4136,6 +4190,7 @@ function buildExtendedChartOption(parsed, palette, isDark) {
4136
4190
  );
4137
4191
  }
4138
4192
  if (parsed.type === "scatter") {
4193
+ const bg = isDark ? palette.surface : palette.bg;
4139
4194
  return buildScatterOption(
4140
4195
  parsed,
4141
4196
  palette,
@@ -4143,15 +4198,18 @@ function buildExtendedChartOption(parsed, palette, isDark) {
4143
4198
  axisLineColor,
4144
4199
  gridOpacity,
4145
4200
  colors,
4201
+ bg,
4146
4202
  titleConfig,
4147
4203
  tooltipTheme
4148
4204
  );
4149
4205
  }
4150
4206
  if (parsed.type === "funnel") {
4207
+ const bg = isDark ? palette.surface : palette.bg;
4151
4208
  return buildFunnelOption(
4152
4209
  parsed,
4153
4210
  textColor,
4154
4211
  colors,
4212
+ bg,
4155
4213
  titleConfig,
4156
4214
  tooltipTheme
4157
4215
  );
@@ -4159,6 +4217,7 @@ function buildExtendedChartOption(parsed, palette, isDark) {
4159
4217
  return buildHeatmapOption(
4160
4218
  parsed,
4161
4219
  palette,
4220
+ isDark,
4162
4221
  textColor,
4163
4222
  axisLineColor,
4164
4223
  titleConfig,
@@ -4215,7 +4274,7 @@ function buildSankeyOption(parsed, textColor, colors, titleConfig, tooltipTheme)
4215
4274
  ]
4216
4275
  };
4217
4276
  }
4218
- function buildChordOption(parsed, textColor, colors, titleConfig, tooltipTheme) {
4277
+ function buildChordOption(parsed, textColor, colors, bg, titleConfig, tooltipTheme) {
4219
4278
  const nodeSet = /* @__PURE__ */ new Set();
4220
4279
  if (parsed.links) {
4221
4280
  for (const link of parsed.links) {
@@ -4235,12 +4294,13 @@ function buildChordOption(parsed, textColor, colors, titleConfig, tooltipTheme)
4235
4294
  }
4236
4295
  }
4237
4296
  }
4238
- const categories = nodeNames.map((name, index) => ({
4239
- name,
4240
- itemStyle: {
4241
- color: colors[index % colors.length]
4242
- }
4243
- }));
4297
+ const categories = nodeNames.map((name, index) => {
4298
+ const stroke2 = colors[index % colors.length];
4299
+ return {
4300
+ name,
4301
+ itemStyle: { color: mix(stroke2, bg, 30), borderColor: stroke2, borderWidth: CHART_BORDER_WIDTH }
4302
+ };
4303
+ });
4244
4304
  return {
4245
4305
  ...CHART_BASE,
4246
4306
  title: titleConfig,
@@ -4408,7 +4468,7 @@ function buildFunctionOption(parsed, palette, textColor, axisLineColor, gridOpac
4408
4468
  series
4409
4469
  };
4410
4470
  }
4411
- function buildScatterOption(parsed, palette, textColor, axisLineColor, gridOpacity, colors, titleConfig, tooltipTheme) {
4471
+ function buildScatterOption(parsed, palette, textColor, axisLineColor, gridOpacity, colors, bg, titleConfig, tooltipTheme) {
4412
4472
  const points = parsed.scatterPoints ?? [];
4413
4473
  const defaultSize = 15;
4414
4474
  const hasCategories = points.some((p) => p.category !== void 0);
@@ -4440,27 +4500,30 @@ function buildScatterOption(parsed, palette, textColor, axisLineColor, gridOpaci
4440
4500
  const data = categoryPoints.map((p) => ({
4441
4501
  name: p.name,
4442
4502
  value: hasSize ? [p.x, p.y, p.size ?? 0] : [p.x, p.y],
4443
- ...p.color && { itemStyle: { color: p.color } }
4503
+ ...p.color && {
4504
+ itemStyle: { color: mix(p.color, bg, 30), borderColor: p.color, borderWidth: CHART_BORDER_WIDTH }
4505
+ }
4444
4506
  }));
4445
4507
  return {
4446
4508
  name: category,
4447
4509
  type: "scatter",
4448
4510
  data,
4449
4511
  ...hasSize ? { symbolSize: (val) => val[2] } : { symbolSize: defaultSize },
4450
- itemStyle: { color: catColor },
4512
+ itemStyle: { color: mix(catColor, bg, 30), borderColor: catColor, borderWidth: CHART_BORDER_WIDTH },
4451
4513
  label: labelConfig,
4452
4514
  emphasis: emphasisConfig
4453
4515
  };
4454
4516
  });
4455
4517
  } else {
4456
- const data = points.map((p, index) => ({
4457
- name: p.name,
4458
- value: hasSize ? [p.x, p.y, p.size ?? 0] : [p.x, p.y],
4459
- ...hasSize ? { symbolSize: p.size ?? defaultSize } : { symbolSize: defaultSize },
4460
- itemStyle: {
4461
- color: p.color ?? colors[index % colors.length]
4462
- }
4463
- }));
4518
+ const data = points.map((p, index) => {
4519
+ const stroke2 = p.color ?? colors[index % colors.length];
4520
+ return {
4521
+ name: p.name,
4522
+ value: hasSize ? [p.x, p.y, p.size ?? 0] : [p.x, p.y],
4523
+ ...hasSize ? { symbolSize: p.size ?? defaultSize } : { symbolSize: defaultSize },
4524
+ itemStyle: { color: mix(stroke2, bg, 30), borderColor: stroke2, borderWidth: CHART_BORDER_WIDTH }
4525
+ };
4526
+ });
4464
4527
  series = [
4465
4528
  {
4466
4529
  type: "scatter",
@@ -4563,7 +4626,8 @@ function buildScatterOption(parsed, palette, textColor, axisLineColor, gridOpaci
4563
4626
  series
4564
4627
  };
4565
4628
  }
4566
- function buildHeatmapOption(parsed, palette, textColor, axisLineColor, titleConfig, tooltipTheme) {
4629
+ function buildHeatmapOption(parsed, palette, isDark, textColor, axisLineColor, titleConfig, tooltipTheme) {
4630
+ const bg = isDark ? palette.surface : palette.bg;
4567
4631
  const heatmapRows = parsed.heatmapRows ?? [];
4568
4632
  const columns = parsed.columns ?? [];
4569
4633
  const rowLabels = heatmapRows.map((r) => r.label);
@@ -4634,10 +4698,10 @@ function buildHeatmapOption(parsed, palette, textColor, axisLineColor, titleConf
4634
4698
  top: "center",
4635
4699
  inRange: {
4636
4700
  color: [
4637
- palette.primary,
4638
- palette.colors.cyan,
4639
- palette.colors.yellow,
4640
- palette.colors.orange
4701
+ mix(palette.primary, bg, 30),
4702
+ mix(palette.colors.cyan, bg, 30),
4703
+ mix(palette.colors.yellow, bg, 30),
4704
+ mix(palette.colors.orange, bg, 30)
4641
4705
  ]
4642
4706
  },
4643
4707
  textStyle: {
@@ -4648,9 +4712,13 @@ function buildHeatmapOption(parsed, palette, textColor, axisLineColor, titleConf
4648
4712
  {
4649
4713
  type: "heatmap",
4650
4714
  data,
4715
+ itemStyle: {
4716
+ borderWidth: 2,
4717
+ borderColor: bg
4718
+ },
4651
4719
  label: {
4652
4720
  show: true,
4653
- color: "#ffffff",
4721
+ color: textColor,
4654
4722
  fontSize: 14,
4655
4723
  fontWeight: "bold"
4656
4724
  },
@@ -4665,17 +4733,21 @@ function buildHeatmapOption(parsed, palette, textColor, axisLineColor, titleConf
4665
4733
  ]
4666
4734
  };
4667
4735
  }
4668
- function buildFunnelOption(parsed, textColor, colors, titleConfig, tooltipTheme) {
4736
+ function buildFunnelOption(parsed, textColor, colors, bg, titleConfig, tooltipTheme) {
4669
4737
  const sorted = [...parsed.data].sort((a, b) => b.value - a.value);
4670
4738
  const topValue = sorted.length > 0 ? sorted[0].value : 1;
4671
- const data = sorted.map((d) => ({
4672
- name: d.label,
4673
- value: d.value,
4674
- itemStyle: {
4675
- color: d.color ?? colors[parsed.data.indexOf(d) % colors.length],
4676
- borderWidth: 0
4677
- }
4678
- }));
4739
+ const data = sorted.map((d) => {
4740
+ const stroke2 = d.color ?? colors[parsed.data.indexOf(d) % colors.length];
4741
+ return {
4742
+ name: d.label,
4743
+ value: d.value,
4744
+ itemStyle: {
4745
+ color: mix(stroke2, bg, 30),
4746
+ borderColor: stroke2,
4747
+ borderWidth: CHART_BORDER_WIDTH
4748
+ }
4749
+ };
4750
+ });
4679
4751
  const prevValueMap = /* @__PURE__ */ new Map();
4680
4752
  for (let i = 0; i < sorted.length; i++) {
4681
4753
  prevValueMap.set(
@@ -4821,23 +4893,24 @@ function makeGridAxis(type, textColor, axisLineColor, splitLineColor, gridOpacit
4821
4893
  function buildSimpleChartOption(parsed, palette, isDark, chartWidth) {
4822
4894
  if (parsed.error) return {};
4823
4895
  const { textColor, axisLineColor, splitLineColor, gridOpacity, colors, titleConfig, tooltipTheme } = buildChartCommons(parsed, palette, isDark);
4896
+ const bg = isDark ? palette.surface : palette.bg;
4824
4897
  switch (parsed.type) {
4825
4898
  case "bar":
4826
- return buildBarOption(parsed, textColor, axisLineColor, splitLineColor, gridOpacity, colors, titleConfig, tooltipTheme, chartWidth);
4899
+ return buildBarOption(parsed, textColor, axisLineColor, splitLineColor, gridOpacity, colors, bg, titleConfig, tooltipTheme, chartWidth);
4827
4900
  case "bar-stacked":
4828
- return buildBarStackedOption(parsed, textColor, axisLineColor, splitLineColor, gridOpacity, colors, titleConfig, tooltipTheme, chartWidth);
4901
+ return buildBarStackedOption(parsed, textColor, axisLineColor, splitLineColor, gridOpacity, colors, bg, titleConfig, tooltipTheme, chartWidth);
4829
4902
  case "line":
4830
4903
  return parsed.seriesNames ? buildMultiLineOption(parsed, palette, textColor, axisLineColor, splitLineColor, gridOpacity, colors, titleConfig, tooltipTheme, chartWidth) : buildLineOption(parsed, palette, textColor, axisLineColor, splitLineColor, gridOpacity, titleConfig, tooltipTheme, chartWidth);
4831
4904
  case "area":
4832
4905
  return buildAreaOption(parsed, palette, textColor, axisLineColor, splitLineColor, gridOpacity, titleConfig, tooltipTheme, chartWidth);
4833
4906
  case "pie":
4834
- return buildPieOption(parsed, textColor, getSegmentColors(palette, parsed.data.length), titleConfig, tooltipTheme, false);
4907
+ return buildPieOption(parsed, textColor, getSegmentColors(palette, parsed.data.length), bg, titleConfig, tooltipTheme, false);
4835
4908
  case "doughnut":
4836
- return buildPieOption(parsed, textColor, getSegmentColors(palette, parsed.data.length), titleConfig, tooltipTheme, true);
4909
+ return buildPieOption(parsed, textColor, getSegmentColors(palette, parsed.data.length), bg, titleConfig, tooltipTheme, true);
4837
4910
  case "radar":
4838
- return buildRadarOption(parsed, palette, textColor, gridOpacity, colors, titleConfig, tooltipTheme);
4911
+ return buildRadarOption(parsed, palette, isDark, textColor, gridOpacity, titleConfig, tooltipTheme);
4839
4912
  case "polar-area":
4840
- return buildPolarAreaOption(parsed, textColor, getSegmentColors(palette, parsed.data.length), titleConfig, tooltipTheme);
4913
+ return buildPolarAreaOption(parsed, textColor, getSegmentColors(palette, parsed.data.length), bg, titleConfig, tooltipTheme);
4841
4914
  }
4842
4915
  }
4843
4916
  function makeChartGrid(options) {
@@ -4849,14 +4922,17 @@ function makeChartGrid(options) {
4849
4922
  containLabel: true
4850
4923
  };
4851
4924
  }
4852
- function buildBarOption(parsed, textColor, axisLineColor, splitLineColor, gridOpacity, colors, titleConfig, tooltipTheme, chartWidth) {
4925
+ function buildBarOption(parsed, textColor, axisLineColor, splitLineColor, gridOpacity, colors, bg, titleConfig, tooltipTheme, chartWidth) {
4853
4926
  const { xLabel, yLabel } = resolveAxisLabels(parsed);
4854
4927
  const isHorizontal = parsed.orientation === "horizontal";
4855
4928
  const labels = parsed.data.map((d) => d.label);
4856
- const data = parsed.data.map((d, i) => ({
4857
- value: d.value,
4858
- itemStyle: { color: d.color ?? colors[i % colors.length] }
4859
- }));
4929
+ const data = parsed.data.map((d, i) => {
4930
+ const stroke2 = d.color ?? colors[i % colors.length];
4931
+ return {
4932
+ value: d.value,
4933
+ itemStyle: { color: mix(stroke2, bg, 30), borderColor: stroke2, borderWidth: CHART_BORDER_WIDTH }
4934
+ };
4935
+ });
4860
4936
  const hCatGap = isHorizontal && yLabel ? Math.max(40, Math.max(...labels.map((l) => l.length)) * 8 + 16) : void 0;
4861
4937
  const categoryAxis = makeGridAxis("category", textColor, axisLineColor, splitLineColor, gridOpacity, isHorizontal ? yLabel : xLabel, labels, hCatGap, !isHorizontal ? chartWidth : void 0);
4862
4938
  const valueAxis = makeGridAxis("value", textColor, axisLineColor, splitLineColor, gridOpacity, isHorizontal ? xLabel : yLabel);
@@ -5037,12 +5113,15 @@ function segmentLabelFormatter(mode) {
5037
5113
  return "{b} \u2014 {c} ({d}%)";
5038
5114
  }
5039
5115
  }
5040
- function buildPieOption(parsed, textColor, colors, titleConfig, tooltipTheme, isDoughnut) {
5041
- const data = parsed.data.map((d, i) => ({
5042
- name: d.label,
5043
- value: d.value,
5044
- itemStyle: { color: d.color ?? colors[i % colors.length] }
5045
- }));
5116
+ function buildPieOption(parsed, textColor, colors, bg, titleConfig, tooltipTheme, isDoughnut) {
5117
+ const data = parsed.data.map((d, i) => {
5118
+ const stroke2 = d.color ?? colors[i % colors.length];
5119
+ return {
5120
+ name: d.label,
5121
+ value: d.value,
5122
+ itemStyle: { color: mix(stroke2, bg, 30), borderColor: stroke2, borderWidth: CHART_BORDER_WIDTH }
5123
+ };
5124
+ });
5046
5125
  return {
5047
5126
  ...CHART_BASE,
5048
5127
  title: titleConfig,
@@ -5067,7 +5146,8 @@ function buildPieOption(parsed, textColor, colors, titleConfig, tooltipTheme, is
5067
5146
  ]
5068
5147
  };
5069
5148
  }
5070
- function buildRadarOption(parsed, palette, textColor, gridOpacity, colors, titleConfig, tooltipTheme) {
5149
+ function buildRadarOption(parsed, palette, isDark, textColor, gridOpacity, titleConfig, tooltipTheme) {
5150
+ const bg = isDark ? palette.surface : palette.bg;
5071
5151
  const radarColor = parsed.color ?? parsed.seriesNameColors?.[0] ?? palette.primary;
5072
5152
  const values = parsed.data.map((d) => d.value);
5073
5153
  const maxValue = Math.max(...values) * 1.15;
@@ -5104,7 +5184,7 @@ function buildRadarOption(parsed, palette, textColor, gridOpacity, colors, title
5104
5184
  {
5105
5185
  value: values,
5106
5186
  name: parsed.series ?? "Value",
5107
- areaStyle: { color: radarColor, opacity: 0.25 },
5187
+ areaStyle: { color: mix(radarColor, bg, 30) },
5108
5188
  lineStyle: { color: radarColor },
5109
5189
  itemStyle: { color: radarColor },
5110
5190
  symbol: "circle",
@@ -5123,12 +5203,15 @@ function buildRadarOption(parsed, palette, textColor, gridOpacity, colors, title
5123
5203
  ]
5124
5204
  };
5125
5205
  }
5126
- function buildPolarAreaOption(parsed, textColor, colors, titleConfig, tooltipTheme) {
5127
- const data = parsed.data.map((d, i) => ({
5128
- name: d.label,
5129
- value: d.value,
5130
- itemStyle: { color: d.color ?? colors[i % colors.length] }
5131
- }));
5206
+ function buildPolarAreaOption(parsed, textColor, colors, bg, titleConfig, tooltipTheme) {
5207
+ const data = parsed.data.map((d, i) => {
5208
+ const stroke2 = d.color ?? colors[i % colors.length];
5209
+ return {
5210
+ name: d.label,
5211
+ value: d.value,
5212
+ itemStyle: { color: mix(stroke2, bg, 30), borderColor: stroke2, borderWidth: CHART_BORDER_WIDTH }
5213
+ };
5214
+ });
5132
5215
  return {
5133
5216
  ...CHART_BASE,
5134
5217
  title: titleConfig,
@@ -5154,7 +5237,7 @@ function buildPolarAreaOption(parsed, textColor, colors, titleConfig, tooltipThe
5154
5237
  ]
5155
5238
  };
5156
5239
  }
5157
- function buildBarStackedOption(parsed, textColor, axisLineColor, splitLineColor, gridOpacity, colors, titleConfig, tooltipTheme, chartWidth) {
5240
+ function buildBarStackedOption(parsed, textColor, axisLineColor, splitLineColor, gridOpacity, colors, bg, titleConfig, tooltipTheme, chartWidth) {
5158
5241
  const { xLabel, yLabel } = resolveAxisLabels(parsed);
5159
5242
  const isHorizontal = parsed.orientation === "horizontal";
5160
5243
  const seriesNames = parsed.seriesNames ?? [];
@@ -5169,12 +5252,12 @@ function buildBarStackedOption(parsed, textColor, axisLineColor, splitLineColor,
5169
5252
  type: "bar",
5170
5253
  stack: "total",
5171
5254
  data,
5172
- itemStyle: { color },
5255
+ itemStyle: { color: mix(color, bg, 30), borderColor: color, borderWidth: CHART_BORDER_WIDTH },
5173
5256
  label: {
5174
5257
  show: true,
5175
5258
  position: "inside",
5176
5259
  formatter: "{c}",
5177
- color: "#ffffff",
5260
+ color: textColor,
5178
5261
  fontSize: 14,
5179
5262
  fontWeight: "bold",
5180
5263
  fontFamily: FONT_FAMILY
@@ -5246,19 +5329,21 @@ async function renderExtendedChartForExport(content, theme, palette, options) {
5246
5329
  chart.dispose();
5247
5330
  }
5248
5331
  }
5249
- var EMPHASIS_SELF, CHART_BASE, ECHART_EXPORT_WIDTH, ECHART_EXPORT_HEIGHT, STANDARD_CHART_TYPES;
5332
+ var EMPHASIS_SELF, CHART_BASE, CHART_BORDER_WIDTH, ECHART_EXPORT_WIDTH, ECHART_EXPORT_HEIGHT, STANDARD_CHART_TYPES;
5250
5333
  var init_echarts = __esm({
5251
5334
  "src/echarts.ts"() {
5252
5335
  "use strict";
5253
5336
  init_fonts();
5254
5337
  init_branding();
5255
5338
  init_palettes();
5339
+ init_color_utils();
5256
5340
  init_chart();
5257
5341
  init_diagnostics();
5258
5342
  init_colors();
5259
5343
  init_parsing();
5260
5344
  EMPHASIS_SELF = { focus: "self", blurScope: "global" };
5261
5345
  CHART_BASE = { backgroundColor: "transparent", animation: false };
5346
+ CHART_BORDER_WIDTH = 2;
5262
5347
  ECHART_EXPORT_WIDTH = 1200;
5263
5348
  ECHART_EXPORT_HEIGHT = 800;
5264
5349
  STANDARD_CHART_TYPES = /* @__PURE__ */ new Set([
@@ -6973,6 +7058,7 @@ var init_types2 = __esm({
6973
7058
  // src/infra/parser.ts
6974
7059
  var parser_exports9 = {};
6975
7060
  __export(parser_exports9, {
7061
+ extractSymbols: () => extractSymbols4,
6976
7062
  parseInfra: () => parseInfra
6977
7063
  });
6978
7064
  function nodeId2(name) {
@@ -7015,7 +7101,6 @@ function parseInfra(content) {
7015
7101
  error: null
7016
7102
  };
7017
7103
  const nodeMap = /* @__PURE__ */ new Map();
7018
- const edgeNodeId = "edge";
7019
7104
  const setError = (line10, message) => {
7020
7105
  const diag = makeDgmoError(line10, message);
7021
7106
  result.diagnostics.push(diag);
@@ -7381,6 +7466,38 @@ function parseInfra(content) {
7381
7466
  }
7382
7467
  return result;
7383
7468
  }
7469
+ function extractSymbols4(docText) {
7470
+ const entities = [];
7471
+ let inMetadata = true;
7472
+ let inTagGroup = false;
7473
+ for (const rawLine of docText.split("\n")) {
7474
+ const line10 = rawLine.trim();
7475
+ if (line10.length === 0) continue;
7476
+ const indented = /^\s/.test(rawLine);
7477
+ if (inMetadata) {
7478
+ if (!indented && !/^[a-z-]+\s*:/i.test(line10)) inMetadata = false;
7479
+ else continue;
7480
+ }
7481
+ if (!indented) {
7482
+ if (/^tag\s*:/i.test(line10)) {
7483
+ inTagGroup = true;
7484
+ continue;
7485
+ }
7486
+ inTagGroup = false;
7487
+ if (/^\[/.test(line10)) continue;
7488
+ const m = COMPONENT_RE.exec(line10);
7489
+ if (m && !entities.includes(m[1])) entities.push(m[1]);
7490
+ } else {
7491
+ if (inTagGroup) continue;
7492
+ if (/^->/.test(line10)) continue;
7493
+ if (/^-[^>]+-?>/.test(line10)) continue;
7494
+ if (/^\w[\w-]*\s*:/.test(line10)) continue;
7495
+ const m = COMPONENT_RE.exec(line10);
7496
+ if (m && !entities.includes(m[1])) entities.push(m[1]);
7497
+ }
7498
+ }
7499
+ return { kind: "infra", entities, keywords: [] };
7500
+ }
7384
7501
  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;
7385
7502
  var init_parser9 = __esm({
7386
7503
  "src/infra/parser.ts"() {
@@ -8244,7 +8361,6 @@ function layoutOrg(parsed, hiddenCounts, activeTagGroup, hiddenAttributes, expan
8244
8361
  const visibleGroups = activeTagGroup != null ? legendGroups.filter((g) => g.name.toLowerCase() === activeTagGroup.toLowerCase()) : legendGroups;
8245
8362
  const allExpanded = expandAllLegend && activeTagGroup == null;
8246
8363
  const effectiveW = (g) => activeTagGroup != null || allExpanded ? g.width : g.minifiedWidth;
8247
- const effectiveH = (g) => activeTagGroup != null || allExpanded ? g.height : g.minifiedHeight;
8248
8364
  if (visibleGroups.length > 0) {
8249
8365
  if (legendPosition === "bottom") {
8250
8366
  const totalGroupsWidth = visibleGroups.reduce((s, g) => s + effectiveW(g), 0) + (visibleGroups.length - 1) * LEGEND_GROUP_GAP2;
@@ -8397,6 +8513,35 @@ var init_collapse = __esm({
8397
8513
  }
8398
8514
  });
8399
8515
 
8516
+ // src/utils/export-container.ts
8517
+ function runInExportContainer(width, height, fn) {
8518
+ const container = document.createElement("div");
8519
+ container.style.width = `${width}px`;
8520
+ container.style.height = `${height}px`;
8521
+ container.style.position = "absolute";
8522
+ container.style.left = "-9999px";
8523
+ document.body.appendChild(container);
8524
+ try {
8525
+ return fn(container);
8526
+ } finally {
8527
+ document.body.removeChild(container);
8528
+ }
8529
+ }
8530
+ function extractExportSvg(container, theme) {
8531
+ const svgEl = container.querySelector("svg");
8532
+ if (!svgEl) return "";
8533
+ if (theme === "transparent") svgEl.style.background = "none";
8534
+ svgEl.setAttribute("xmlns", "http://www.w3.org/2000/svg");
8535
+ svgEl.style.fontFamily = FONT_FAMILY;
8536
+ return svgEl.outerHTML;
8537
+ }
8538
+ var init_export_container = __esm({
8539
+ "src/utils/export-container.ts"() {
8540
+ "use strict";
8541
+ init_fonts();
8542
+ }
8543
+ });
8544
+
8400
8545
  // src/org/renderer.ts
8401
8546
  var renderer_exports = {};
8402
8547
  __export(renderer_exports, {
@@ -8652,37 +8797,23 @@ function renderOrgForExport(content, theme, palette) {
8652
8797
  const exportHidden = hideOption ? new Set(hideOption.split(",").map((s) => s.trim().toLowerCase())) : void 0;
8653
8798
  const layout = layoutOrg(parsed, void 0, void 0, exportHidden);
8654
8799
  const isDark = theme === "dark";
8655
- const container = document.createElement("div");
8656
8800
  const titleOffset = parsed.title ? TITLE_HEIGHT : 0;
8657
8801
  const exportWidth = layout.width + DIAGRAM_PADDING * 2;
8658
8802
  const exportHeight = layout.height + DIAGRAM_PADDING * 2 + titleOffset;
8659
- container.style.width = `${exportWidth}px`;
8660
- container.style.height = `${exportHeight}px`;
8661
- container.style.position = "absolute";
8662
- container.style.left = "-9999px";
8663
- document.body.appendChild(container);
8664
- try {
8803
+ return runInExportContainer(exportWidth, exportHeight, (container) => {
8665
8804
  renderOrg(container, parsed, layout, palette, isDark, void 0, {
8666
8805
  width: exportWidth,
8667
8806
  height: exportHeight
8668
8807
  });
8669
- const svgEl = container.querySelector("svg");
8670
- if (!svgEl) return "";
8671
- if (theme === "transparent") {
8672
- svgEl.style.background = "none";
8673
- }
8674
- svgEl.setAttribute("xmlns", "http://www.w3.org/2000/svg");
8675
- svgEl.style.fontFamily = FONT_FAMILY;
8676
- return svgEl.outerHTML;
8677
- } finally {
8678
- document.body.removeChild(container);
8679
- }
8808
+ return extractExportSvg(container, theme);
8809
+ });
8680
8810
  }
8681
8811
  var 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;
8682
8812
  var init_renderer = __esm({
8683
8813
  "src/org/renderer.ts"() {
8684
8814
  "use strict";
8685
8815
  init_fonts();
8816
+ init_export_container();
8686
8817
  init_color_utils();
8687
8818
  init_parser4();
8688
8819
  init_layout();
@@ -10270,7 +10401,6 @@ function renderClassDiagram(container, parsed, layout, palette, isDark, onClickI
10270
10401
  const scaleY = (availH - DIAGRAM_PADDING4 * 2) / diagramH;
10271
10402
  const scale = Math.min(MAX_SCALE3, scaleX, scaleY);
10272
10403
  const scaledW = diagramW * scale;
10273
- const scaledH = diagramH * scale;
10274
10404
  const offsetX = (width - scaledW) / 2;
10275
10405
  const offsetY = titleHeight + DIAGRAM_PADDING4;
10276
10406
  const svg = d3Selection4.select(container).append("svg").attr("width", width).attr("height", height).style("font-family", FONT_FAMILY);
@@ -10401,15 +10531,9 @@ function renderClassDiagramForExport(content, theme, palette) {
10401
10531
  if (parsed.error || parsed.classes.length === 0) return "";
10402
10532
  const layout = layoutClassDiagram(parsed);
10403
10533
  const isDark = theme === "dark";
10404
- const container = document.createElement("div");
10405
10534
  const exportWidth = layout.width + DIAGRAM_PADDING4 * 2;
10406
10535
  const exportHeight = layout.height + DIAGRAM_PADDING4 * 2 + (parsed.title ? 40 : 0);
10407
- container.style.width = `${exportWidth}px`;
10408
- container.style.height = `${exportHeight}px`;
10409
- container.style.position = "absolute";
10410
- container.style.left = "-9999px";
10411
- document.body.appendChild(container);
10412
- try {
10536
+ return runInExportContainer(exportWidth, exportHeight, (container) => {
10413
10537
  renderClassDiagram(
10414
10538
  container,
10415
10539
  parsed,
@@ -10419,23 +10543,15 @@ function renderClassDiagramForExport(content, theme, palette) {
10419
10543
  void 0,
10420
10544
  { width: exportWidth, height: exportHeight }
10421
10545
  );
10422
- const svgEl = container.querySelector("svg");
10423
- if (!svgEl) return "";
10424
- if (theme === "transparent") {
10425
- svgEl.style.background = "none";
10426
- }
10427
- svgEl.setAttribute("xmlns", "http://www.w3.org/2000/svg");
10428
- svgEl.style.fontFamily = FONT_FAMILY;
10429
- return svgEl.outerHTML;
10430
- } finally {
10431
- document.body.removeChild(container);
10432
- }
10546
+ return extractExportSvg(container, theme);
10547
+ });
10433
10548
  }
10434
10549
  var 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;
10435
10550
  var init_renderer4 = __esm({
10436
10551
  "src/class/renderer.ts"() {
10437
10552
  "use strict";
10438
10553
  init_fonts();
10554
+ init_export_container();
10439
10555
  init_color_utils();
10440
10556
  init_parser2();
10441
10557
  init_layout3();
@@ -11697,7 +11813,6 @@ function renderInitiativeStatus(container, parsed, layout, palette, isDark, onCl
11697
11813
  const scaleY = (availH - DIAGRAM_PADDING6 * 2) / diagramH;
11698
11814
  const scale = Math.min(MAX_SCALE5, scaleX, scaleY);
11699
11815
  const scaledW = diagramW * scale;
11700
- const scaledH = diagramH * scale;
11701
11816
  const offsetX = (width - scaledW) / 2;
11702
11817
  const offsetY = titleHeight + DIAGRAM_PADDING6;
11703
11818
  const svg = d3Selection6.select(container).append("svg").attr("width", width).attr("height", height).style("font-family", FONT_FAMILY);
@@ -11880,13 +11995,7 @@ function renderInitiativeStatusForExport(content, theme, palette) {
11880
11995
  const titleOffset = parsed.title ? 40 : 0;
11881
11996
  const exportWidth = layout.width + DIAGRAM_PADDING6 * 2;
11882
11997
  const exportHeight = layout.height + DIAGRAM_PADDING6 * 2 + titleOffset;
11883
- const container = document.createElement("div");
11884
- container.style.width = `${exportWidth}px`;
11885
- container.style.height = `${exportHeight}px`;
11886
- container.style.position = "absolute";
11887
- container.style.left = "-9999px";
11888
- document.body.appendChild(container);
11889
- try {
11998
+ return runInExportContainer(exportWidth, exportHeight, (container) => {
11890
11999
  renderInitiativeStatus(
11891
12000
  container,
11892
12001
  parsed,
@@ -11896,23 +12005,15 @@ function renderInitiativeStatusForExport(content, theme, palette) {
11896
12005
  void 0,
11897
12006
  { width: exportWidth, height: exportHeight }
11898
12007
  );
11899
- const svgEl = container.querySelector("svg");
11900
- if (!svgEl) return "";
11901
- if (theme === "transparent") {
11902
- svgEl.style.background = "none";
11903
- }
11904
- svgEl.setAttribute("xmlns", "http://www.w3.org/2000/svg");
11905
- svgEl.style.fontFamily = FONT_FAMILY;
11906
- return svgEl.outerHTML;
11907
- } finally {
11908
- document.body.removeChild(container);
11909
- }
12008
+ return extractExportSvg(container, theme);
12009
+ });
11910
12010
  }
11911
12011
  var 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;
11912
12012
  var init_renderer6 = __esm({
11913
12013
  "src/initiative-status/renderer.ts"() {
11914
12014
  "use strict";
11915
12015
  init_fonts();
12016
+ init_export_container();
11916
12017
  init_color_utils();
11917
12018
  init_parser7();
11918
12019
  init_layout5();
@@ -12181,8 +12282,6 @@ function collectAllRelationships(elements, ownerMap) {
12181
12282
  function rollUpContextRelationships(parsed) {
12182
12283
  const ownerMap = buildOwnershipMap(parsed.elements);
12183
12284
  const allRels = collectAllRelationships(parsed.elements, ownerMap);
12184
- for (const rel of parsed.relationships) {
12185
- }
12186
12285
  const topLevelNames = new Set(parsed.elements.map((e) => e.name));
12187
12286
  const explicitKeys = /* @__PURE__ */ new Set();
12188
12287
  const explicit = [];
@@ -12313,7 +12412,7 @@ function computeLegendGroups3(tagGroups) {
12313
12412
  const nameW = group.name.length * LEGEND_PILL_FONT_W4 + LEGEND_PILL_PAD4 * 2;
12314
12413
  let capsuleW = LEGEND_CAPSULE_PAD4;
12315
12414
  for (const e of entries) {
12316
- capsuleW += LEGEND_DOT_R4 * 2 + LEGEND_ENTRY_DOT_GAP4 + e.value.length * LEGEND_ENTRY_FONT_W5 + LEGEND_ENTRY_TRAIL4;
12415
+ capsuleW += LEGEND_DOT_R4 * 2 + LEGEND_ENTRY_DOT_GAP4 + e.value.length * LEGEND_ENTRY_FONT_W4 + LEGEND_ENTRY_TRAIL4;
12317
12416
  }
12318
12417
  capsuleW += LEGEND_CAPSULE_PAD4;
12319
12418
  result.push({
@@ -13394,7 +13493,7 @@ function layoutC4Deployment(parsed, activeTagGroup) {
13394
13493
  }
13395
13494
  return { nodes, edges, legend: legendGroups, groupBoundaries, width: totalWidth, height: totalHeight };
13396
13495
  }
13397
- var 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;
13496
+ var 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;
13398
13497
  var init_layout6 = __esm({
13399
13498
  "src/c4/layout.ts"() {
13400
13499
  "use strict";
@@ -13419,7 +13518,7 @@ var init_layout6 = __esm({
13419
13518
  LEGEND_PILL_PAD4 = 16;
13420
13519
  LEGEND_DOT_R4 = 4;
13421
13520
  LEGEND_ENTRY_FONT_SIZE2 = 10;
13422
- LEGEND_ENTRY_FONT_W5 = LEGEND_ENTRY_FONT_SIZE2 * 0.6;
13521
+ LEGEND_ENTRY_FONT_W4 = LEGEND_ENTRY_FONT_SIZE2 * 0.6;
13423
13522
  LEGEND_ENTRY_DOT_GAP4 = 4;
13424
13523
  LEGEND_ENTRY_TRAIL4 = 8;
13425
13524
  LEGEND_CAPSULE_PAD4 = 4;
@@ -13513,7 +13612,6 @@ function renderC4Context(container, parsed, layout, palette, isDark, onClickItem
13513
13612
  const scaleY = (availH - DIAGRAM_PADDING7 * 2) / diagramH;
13514
13613
  const scale = Math.min(MAX_SCALE6, scaleX, scaleY);
13515
13614
  const scaledW = diagramW * scale;
13516
- const scaledH = diagramH * scale;
13517
13615
  const offsetX = (width - scaledW) / 2;
13518
13616
  const offsetY = titleHeight + DIAGRAM_PADDING7;
13519
13617
  const svg = d3Selection7.select(container).append("svg").attr("width", width).attr("height", height).style("font-family", FONT_FAMILY);
@@ -14003,7 +14101,6 @@ function renderC4Containers(container, parsed, layout, palette, isDark, onClickI
14003
14101
  const scaleY = (availH - DIAGRAM_PADDING7 * 2) / diagramH;
14004
14102
  const scale = Math.min(MAX_SCALE6, scaleX, scaleY);
14005
14103
  const scaledW = diagramW * scale;
14006
- const scaledH = diagramH * scale;
14007
14104
  const offsetX = (width - scaledW) / 2;
14008
14105
  const offsetY = titleHeight + DIAGRAM_PADDING7;
14009
14106
  const svg = d3Selection7.select(container).append("svg").attr("width", width).attr("height", height).style("font-family", FONT_FAMILY);
@@ -14616,7 +14713,6 @@ function renderFlowchart(container, graph, layout, palette, isDark, onClickItem,
14616
14713
  const scaleY = (availH - DIAGRAM_PADDING8 * 2) / diagramH;
14617
14714
  const scale = Math.min(MAX_SCALE7, scaleX, scaleY);
14618
14715
  const scaledW = diagramW * scale;
14619
- const scaledH = diagramH * scale;
14620
14716
  const offsetX = (width - scaledW) / 2;
14621
14717
  const offsetY = titleHeight + DIAGRAM_PADDING8;
14622
14718
  const svg = d3Selection8.select(container).append("svg").attr("width", width).attr("height", height).style("font-family", FONT_FAMILY);
@@ -18690,7 +18786,6 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
18690
18786
  if (secY === void 0) continue;
18691
18787
  const isCollapsed = collapsedSections?.has(sec.lineNumber) ?? false;
18692
18788
  const lineColor = palette.textMuted;
18693
- const HIT_AREA_HEIGHT = 36;
18694
18789
  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));
18695
18790
  const BAND_HEIGHT = 22;
18696
18791
  const bandX = sectionLineX1 - 10;
@@ -20083,7 +20178,6 @@ function renderArcDiagram(container, parsed, palette, _isDark, onClickItem, expo
20083
20178
  const positions = groupNodes.map((n) => yScale(n));
20084
20179
  const minY = Math.min(...positions) - bandPad;
20085
20180
  const maxY = Math.max(...positions) + bandPad;
20086
- const bandColor = group.color ?? mutedColor;
20087
20181
  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", () => {
20088
20182
  if (onClickItem) onClickItem(group.lineNumber);
20089
20183
  });
@@ -20127,7 +20221,6 @@ function renderArcDiagram(container, parsed, palette, _isDark, onClickItem, expo
20127
20221
  const positions = groupNodes.map((n) => xScale(n));
20128
20222
  const minX = Math.min(...positions) - bandPad;
20129
20223
  const maxX = Math.max(...positions) + bandPad;
20130
- const bandColor = group.color ?? mutedColor;
20131
20224
  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", () => {
20132
20225
  if (onClickItem) onClickItem(group.lineNumber);
20133
20226
  });
@@ -20445,6 +20538,7 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
20445
20538
  const textColor = palette.text;
20446
20539
  const mutedColor = palette.border;
20447
20540
  const bgColor = palette.bg;
20541
+ const bg = isDark ? palette.surface : palette.bg;
20448
20542
  const colors = getSeriesColors(palette);
20449
20543
  const groupColorMap = /* @__PURE__ */ new Map();
20450
20544
  timelineGroups.forEach((grp, i) => {
@@ -20706,7 +20800,7 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
20706
20800
  if (ev.endDate) {
20707
20801
  const y2 = yScale(parseTimelineDate(ev.endDate));
20708
20802
  const rectH = Math.max(y2 - y, 4);
20709
- let fill2 = evColor;
20803
+ let fill2 = mix(evColor, bg, 30);
20710
20804
  if (ev.uncertain) {
20711
20805
  const gradientId = `uncertain-vg-${ev.lineNumber}`;
20712
20806
  const defs = svg.select("defs").node() || svg.append("defs").node();
@@ -20714,13 +20808,13 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
20714
20808
  { offset: "0%", opacity: 1 },
20715
20809
  { offset: "80%", opacity: 1 },
20716
20810
  { offset: "100%", opacity: 0 }
20717
- ]).enter().append("stop").attr("offset", (d) => d.offset).attr("stop-color", laneColor).attr("stop-opacity", (d) => d.opacity);
20811
+ ]).enter().append("stop").attr("offset", (d) => d.offset).attr("stop-color", mix(laneColor, bg, 30)).attr("stop-opacity", (d) => d.opacity);
20718
20812
  fill2 = `url(#${gradientId})`;
20719
20813
  }
20720
- evG.append("rect").attr("x", laneCenter - 6).attr("y", y).attr("width", 12).attr("height", rectH).attr("rx", 4).attr("fill", fill2);
20814
+ 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);
20721
20815
  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);
20722
20816
  } else {
20723
- evG.append("circle").attr("cx", laneCenter).attr("cy", y).attr("r", 4).attr("fill", evColor).attr("stroke", bgColor).attr("stroke-width", 1.5);
20817
+ 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);
20724
20818
  evG.append("text").attr("x", laneCenter + 10).attr("y", y).attr("dy", "0.35em").attr("fill", textColor).attr("font-size", "10px").text(ev.label);
20725
20819
  }
20726
20820
  }
@@ -20813,7 +20907,7 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
20813
20907
  if (ev.endDate) {
20814
20908
  const y2 = yScale(parseTimelineDate(ev.endDate));
20815
20909
  const rectH = Math.max(y2 - y, 4);
20816
- let fill2 = color;
20910
+ let fill2 = mix(color, bg, 30);
20817
20911
  if (ev.uncertain) {
20818
20912
  const gradientId = `uncertain-v-${ev.lineNumber}`;
20819
20913
  const defs = svg.select("defs").node() || svg.append("defs").node();
@@ -20821,13 +20915,13 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
20821
20915
  { offset: "0%", opacity: 1 },
20822
20916
  { offset: "80%", opacity: 1 },
20823
20917
  { offset: "100%", opacity: 0 }
20824
- ]).enter().append("stop").attr("offset", (d) => d.offset).attr("stop-color", color).attr("stop-opacity", (d) => d.opacity);
20918
+ ]).enter().append("stop").attr("offset", (d) => d.offset).attr("stop-color", mix(color, bg, 30)).attr("stop-opacity", (d) => d.opacity);
20825
20919
  fill2 = `url(#${gradientId})`;
20826
20920
  }
20827
- evG.append("rect").attr("x", axisX - 6).attr("y", y).attr("width", 12).attr("height", rectH).attr("rx", 4).attr("fill", fill2);
20921
+ 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);
20828
20922
  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);
20829
20923
  } else {
20830
- evG.append("circle").attr("cx", axisX).attr("cy", y).attr("r", 4).attr("fill", color).attr("stroke", bgColor).attr("stroke-width", 1.5);
20924
+ 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);
20831
20925
  evG.append("text").attr("x", axisX + 16).attr("y", y).attr("dy", "0.35em").attr("fill", textColor).attr("font-size", "11px").text(ev.label);
20832
20926
  }
20833
20927
  evG.append("text").attr("x", axisX - 14).attr(
@@ -20978,7 +21072,7 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
20978
21072
  const rectW = Math.max(x2 - x, 4);
20979
21073
  const estLabelWidth = ev.label.length * 7 + 16;
20980
21074
  const labelFitsInside = rectW >= estLabelWidth;
20981
- let fill2 = evColor;
21075
+ let fill2 = mix(evColor, bg, 30);
20982
21076
  if (ev.uncertain) {
20983
21077
  const gradientId = `uncertain-${ev.lineNumber}`;
20984
21078
  const defs = svg.select("defs").node() || svg.append("defs").node();
@@ -20986,12 +21080,12 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
20986
21080
  { offset: "0%", opacity: 1 },
20987
21081
  { offset: "80%", opacity: 1 },
20988
21082
  { offset: "100%", opacity: 0 }
20989
- ]).enter().append("stop").attr("offset", (d) => d.offset).attr("stop-color", evColor).attr("stop-opacity", (d) => d.opacity);
21083
+ ]).enter().append("stop").attr("offset", (d) => d.offset).attr("stop-color", mix(evColor, bg, 30)).attr("stop-opacity", (d) => d.opacity);
20990
21084
  fill2 = `url(#${gradientId})`;
20991
21085
  }
20992
- 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);
21086
+ 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);
20993
21087
  if (labelFitsInside) {
20994
- 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);
21088
+ 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);
20995
21089
  } else {
20996
21090
  const wouldFlipLeft = x + rectW > innerWidth * 0.6;
20997
21091
  const labelFitsLeft = x - 6 - estLabelWidth > 0;
@@ -21003,7 +21097,7 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
21003
21097
  const wouldFlipLeft = x > innerWidth * 0.6;
21004
21098
  const labelFitsLeft = x - 10 - estLabelWidth > 0;
21005
21099
  const flipLeft = wouldFlipLeft && labelFitsLeft;
21006
- evG.append("circle").attr("cx", x).attr("cy", y).attr("r", 5).attr("fill", evColor).attr("stroke", bgColor).attr("stroke-width", 1.5);
21100
+ 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);
21007
21101
  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);
21008
21102
  }
21009
21103
  });
@@ -21116,7 +21210,7 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
21116
21210
  const rectW = Math.max(x2 - x, 4);
21117
21211
  const estLabelWidth = ev.label.length * 7 + 16;
21118
21212
  const labelFitsInside = rectW >= estLabelWidth;
21119
- let fill2 = color;
21213
+ let fill2 = mix(color, bg, 30);
21120
21214
  if (ev.uncertain) {
21121
21215
  const gradientId = `uncertain-ts-${ev.lineNumber}`;
21122
21216
  const defs = svg.select("defs").node() || svg.append("defs").node();
@@ -21124,12 +21218,12 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
21124
21218
  { offset: "0%", opacity: 1 },
21125
21219
  { offset: "80%", opacity: 1 },
21126
21220
  { offset: "100%", opacity: 0 }
21127
- ]).enter().append("stop").attr("offset", (d) => d.offset).attr("stop-color", color).attr("stop-opacity", (d) => d.opacity);
21221
+ ]).enter().append("stop").attr("offset", (d) => d.offset).attr("stop-color", mix(color, bg, 30)).attr("stop-opacity", (d) => d.opacity);
21128
21222
  fill2 = `url(#${gradientId})`;
21129
21223
  }
21130
- 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);
21224
+ 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);
21131
21225
  if (labelFitsInside) {
21132
- 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);
21226
+ 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);
21133
21227
  } else {
21134
21228
  const wouldFlipLeft = x + rectW > innerWidth * 0.6;
21135
21229
  const labelFitsLeft = x - 6 - estLabelWidth > 0;
@@ -21141,7 +21235,7 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
21141
21235
  const wouldFlipLeft = x > innerWidth * 0.6;
21142
21236
  const labelFitsLeft = x - 10 - estLabelWidth > 0;
21143
21237
  const flipLeft = wouldFlipLeft && labelFitsLeft;
21144
- evG.append("circle").attr("cx", x).attr("cy", y).attr("r", 5).attr("fill", color).attr("stroke", bgColor).attr("stroke-width", 1.5);
21238
+ 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);
21145
21239
  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);
21146
21240
  }
21147
21241
  });
@@ -21296,8 +21390,8 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
21296
21390
  } else {
21297
21391
  color = ev.group && groupColorMap.has(ev.group) ? groupColorMap.get(ev.group) : textColor;
21298
21392
  }
21299
- el.selectAll("rect").attr("fill", color);
21300
- el.selectAll("circle:not(.tl-event-point-outline)").attr("fill", color);
21393
+ el.selectAll("rect").attr("fill", mix(color, bg, 30)).attr("stroke", color);
21394
+ el.selectAll("circle:not(.tl-event-point-outline)").attr("fill", mix(color, bg, 30)).attr("stroke", color);
21301
21395
  });
21302
21396
  };
21303
21397
  var drawSwimlaneIcon = drawSwimlaneIcon2, relayout = relayout2, drawLegend = drawLegend2, recolorEvents = recolorEvents2;
@@ -21762,7 +21856,6 @@ function renderQuadrant(container, parsed, palette, isDark, onClickItem, exportD
21762
21856
  const init2 = initD3Chart(container, palette, exportDims);
21763
21857
  if (!init2) return;
21764
21858
  const { svg, width, height, textColor } = init2;
21765
- const mutedColor = palette.textMuted;
21766
21859
  const borderColor = palette.border;
21767
21860
  const defaultColors = [
21768
21861
  palette.colors.blue,
@@ -21786,13 +21879,17 @@ function renderQuadrant(container, parsed, palette, isDark, onClickItem, exportD
21786
21879
  const f = r.length === 3 ? r[0] + r[0] + r[1] + r[1] + r[2] + r[2] : r;
21787
21880
  return [parseInt(f.substring(0, 2), 16), parseInt(f.substring(2, 4), 16), parseInt(f.substring(4, 6), 16)];
21788
21881
  };
21789
- const [ar, ag, ab] = parse(a), [br, bg, bb] = parse(b), t = pct / 100;
21882
+ const [ar, ag, ab] = parse(a), [br, bg2, bb] = parse(b), t = pct / 100;
21790
21883
  const c = (x, y) => Math.round(x * t + y * (1 - t)).toString(16).padStart(2, "0");
21791
- return `#${c(ar, br)}${c(ag, bg)}${c(ab, bb)}`;
21884
+ return `#${c(ar, br)}${c(ag, bg2)}${c(ab, bb)}`;
21792
21885
  };
21793
- const getQuadrantFill = (label, defaultIdx) => {
21886
+ const bg = isDark ? palette.surface : palette.bg;
21887
+ const getQuadrantColor = (label, defaultIdx) => {
21794
21888
  return label?.color ?? defaultColors[defaultIdx % defaultColors.length];
21795
21889
  };
21890
+ const getQuadrantFill = (label, defaultIdx) => {
21891
+ return mixHex(getQuadrantColor(label, defaultIdx), bg, 30);
21892
+ };
21796
21893
  const quadrantDefs = [
21797
21894
  {
21798
21895
  position: "top-left",
@@ -21843,12 +21940,11 @@ function renderQuadrant(container, parsed, palette, isDark, onClickItem, exportD
21843
21940
  // purple
21844
21941
  }
21845
21942
  ];
21846
- 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);
21847
- const contrastColor = "#ffffff";
21943
+ 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);
21848
21944
  const shadowColor = "rgba(0,0,0,0.4)";
21849
21945
  const getQuadrantLabelColor = (d) => {
21850
- const fill2 = getQuadrantFill(d.label, d.colorIdx);
21851
- return mixHex("#000000", fill2, 40);
21946
+ const color = getQuadrantColor(d.label, d.colorIdx);
21947
+ return mixHex("#000000", color, 40);
21852
21948
  };
21853
21949
  const LABEL_MAX_FONT = 48;
21854
21950
  const LABEL_MIN_FONT = 14;
@@ -21989,7 +22085,7 @@ function renderQuadrant(container, parsed, palette, isDark, onClickItem, exportD
21989
22085
  const pointColor = quadDef?.label?.color ?? defaultColors[quadDef?.colorIdx ?? 0];
21990
22086
  const pointG = pointsG.append("g").attr("class", "point-group").attr("data-line-number", String(point.lineNumber));
21991
22087
  pointG.append("circle").attr("cx", cx).attr("cy", cy).attr("r", 6).attr("fill", "#ffffff").attr("stroke", pointColor).attr("stroke-width", 2);
21992
- 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);
22088
+ 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);
21993
22089
  const tipHtml = `<strong>${point.label}</strong><br>x: ${point.x.toFixed(2)}, y: ${point.y.toFixed(2)}`;
21994
22090
  pointG.style("cursor", onClickItem ? "pointer" : "default").on("mouseenter", (event) => {
21995
22091
  showTooltip(tooltip, tipHtml, event);
@@ -23262,6 +23358,34 @@ function decodeDiagramUrl(hash) {
23262
23358
  }
23263
23359
  }
23264
23360
 
23361
+ // src/completion.ts
23362
+ init_parser3();
23363
+ init_flowchart_parser();
23364
+ init_parser9();
23365
+ init_parser2();
23366
+ var registry = /* @__PURE__ */ new Map();
23367
+ function registerExtractor(kind, fn) {
23368
+ registry.set(kind, fn);
23369
+ }
23370
+ function extractDiagramSymbols(docText) {
23371
+ let chartType = null;
23372
+ for (const line10 of docText.split("\n")) {
23373
+ const m = line10.match(/^\s*chart\s*:\s*(.+)/i);
23374
+ if (m) {
23375
+ chartType = m[1].trim().toLowerCase();
23376
+ break;
23377
+ }
23378
+ }
23379
+ if (!chartType) return null;
23380
+ const fn = registry.get(chartType);
23381
+ if (!fn) return null;
23382
+ return fn(docText);
23383
+ }
23384
+ registerExtractor("er", extractSymbols3);
23385
+ registerExtractor("flowchart", extractSymbols);
23386
+ registerExtractor("infra", extractSymbols4);
23387
+ registerExtractor("class", extractSymbols2);
23388
+
23265
23389
  // src/index.ts
23266
23390
  init_branding();
23267
23391
  export {
@@ -23293,6 +23417,7 @@ export {
23293
23417
  contrastText,
23294
23418
  decodeDiagramUrl,
23295
23419
  encodeDiagramUrl,
23420
+ extractDiagramSymbols,
23296
23421
  formatDateLabel,
23297
23422
  formatDgmoError,
23298
23423
  getAvailablePalettes,
@@ -23356,6 +23481,7 @@ export {
23356
23481
  parseState,
23357
23482
  parseTimelineDate,
23358
23483
  parseVisualization,
23484
+ registerExtractor,
23359
23485
  registerPalette,
23360
23486
  render,
23361
23487
  renderArcDiagram,