@diagrammo/dgmo 0.2.20 → 0.2.22

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -3956,16 +3956,15 @@ function buildFunnelOption(parsed, textColor, colors, titleConfig, tooltipTheme)
3956
3956
  const val = p.value;
3957
3957
  const prev = prevValueMap.get(p.name) ?? val;
3958
3958
  const isFirst = p.dataIndex === 0;
3959
- let html = `<strong>${p.name}</strong>: ${val}`;
3960
- if (!isFirst) {
3961
- const stepDrop = ((1 - val / prev) * 100).toFixed(1);
3962
- html += `<br/>Step drop-off: ${stepDrop}%`;
3963
- }
3964
- if (!isFirst && topValue > 0) {
3959
+ if (isFirst) return "";
3960
+ const parts = [];
3961
+ const stepDrop = ((1 - val / prev) * 100).toFixed(1);
3962
+ parts.push(`Step drop-off: ${stepDrop}%`);
3963
+ if (topValue > 0) {
3965
3964
  const totalDrop = ((1 - val / topValue) * 100).toFixed(1);
3966
- html += `<br/>Overall drop-off: ${totalDrop}%`;
3965
+ parts.push(`Overall drop-off: ${totalDrop}%`);
3967
3966
  }
3968
- return html;
3967
+ return parts.join("<br/>");
3969
3968
  }
3970
3969
  },
3971
3970
  series: [
@@ -4521,6 +4520,7 @@ var init_echarts = __esm({
4521
4520
  // src/org/parser.ts
4522
4521
  var parser_exports4 = {};
4523
4522
  __export(parser_exports4, {
4523
+ looksLikeOrg: () => looksLikeOrg,
4524
4524
  parseOrg: () => parseOrg
4525
4525
  });
4526
4526
  function measureIndent5(line5) {
@@ -4541,6 +4541,14 @@ function extractColor2(label, palette) {
4541
4541
  color: resolveColor(colorName, palette)
4542
4542
  };
4543
4543
  }
4544
+ function looksLikeOrg(content) {
4545
+ for (const line5 of content.split("\n")) {
4546
+ const trimmed = line5.trim();
4547
+ if (!trimmed || trimmed.startsWith("//")) continue;
4548
+ if (GROUP_HEADING_RE2.test(trimmed)) return true;
4549
+ }
4550
+ return false;
4551
+ }
4544
4552
  function parseOrg(content, palette) {
4545
4553
  const result = {
4546
4554
  title: null,
@@ -4699,7 +4707,7 @@ function parseOrg(content, palette) {
4699
4707
  attachNode(node, indent, indentStack, result);
4700
4708
  }
4701
4709
  }
4702
- if (result.roots.length === 0 && !result.error) {
4710
+ if (result.roots.length === 0 && result.tagGroups.length === 0 && !result.error) {
4703
4711
  const diag = makeDgmoError(1, "No nodes found in org chart");
4704
4712
  result.diagnostics.push(diag);
4705
4713
  result.error = formatDgmoError(diag);
@@ -4780,6 +4788,289 @@ var init_parser4 = __esm({
4780
4788
  }
4781
4789
  });
4782
4790
 
4791
+ // src/kanban/parser.ts
4792
+ var parser_exports5 = {};
4793
+ __export(parser_exports5, {
4794
+ parseKanban: () => parseKanban
4795
+ });
4796
+ function measureIndent6(line5) {
4797
+ let indent = 0;
4798
+ for (const ch of line5) {
4799
+ if (ch === " ") indent++;
4800
+ else if (ch === " ") indent += 4;
4801
+ else break;
4802
+ }
4803
+ return indent;
4804
+ }
4805
+ function extractColor3(label, palette) {
4806
+ const m = label.match(COLOR_SUFFIX_RE3);
4807
+ if (!m) return { label };
4808
+ const colorName = m[1].trim();
4809
+ return {
4810
+ label: label.substring(0, m.index).trim(),
4811
+ color: resolveColor(colorName, palette)
4812
+ };
4813
+ }
4814
+ function parseKanban(content, palette) {
4815
+ const result = {
4816
+ type: "kanban",
4817
+ columns: [],
4818
+ tagGroups: [],
4819
+ options: {},
4820
+ diagnostics: []
4821
+ };
4822
+ const fail = (line5, message) => {
4823
+ const diag = makeDgmoError(line5, message);
4824
+ result.diagnostics.push(diag);
4825
+ result.error = formatDgmoError(diag);
4826
+ return result;
4827
+ };
4828
+ const warn = (line5, message) => {
4829
+ result.diagnostics.push(makeDgmoError(line5, message, "warning"));
4830
+ };
4831
+ if (!content || !content.trim()) {
4832
+ return fail(0, "No content provided");
4833
+ }
4834
+ const lines = content.split("\n");
4835
+ let contentStarted = false;
4836
+ let currentTagGroup = null;
4837
+ let currentColumn = null;
4838
+ let currentCard = null;
4839
+ let columnCounter = 0;
4840
+ let cardCounter = 0;
4841
+ const aliasMap = /* @__PURE__ */ new Map();
4842
+ const tagValueSets = /* @__PURE__ */ new Map();
4843
+ for (let i = 0; i < lines.length; i++) {
4844
+ const line5 = lines[i];
4845
+ const lineNumber = i + 1;
4846
+ const trimmed = line5.trim();
4847
+ if (!trimmed) {
4848
+ if (currentTagGroup) currentTagGroup = null;
4849
+ continue;
4850
+ }
4851
+ if (trimmed.startsWith("//")) continue;
4852
+ if (!contentStarted && !currentTagGroup) {
4853
+ const chartMatch = trimmed.match(CHART_TYPE_RE2);
4854
+ if (chartMatch) {
4855
+ const chartType = chartMatch[1].trim().toLowerCase();
4856
+ if (chartType !== "kanban") {
4857
+ const allTypes = [
4858
+ "kanban",
4859
+ "org",
4860
+ "class",
4861
+ "flowchart",
4862
+ "sequence",
4863
+ "er",
4864
+ "bar",
4865
+ "line",
4866
+ "pie"
4867
+ ];
4868
+ let msg = `Expected chart type "kanban", got "${chartType}"`;
4869
+ const hint = suggest(chartType, allTypes);
4870
+ if (hint) msg += `. ${hint}`;
4871
+ return fail(lineNumber, msg);
4872
+ }
4873
+ continue;
4874
+ }
4875
+ }
4876
+ if (!contentStarted && !currentTagGroup) {
4877
+ const titleMatch = trimmed.match(TITLE_RE2);
4878
+ if (titleMatch) {
4879
+ result.title = titleMatch[1].trim();
4880
+ result.titleLineNumber = lineNumber;
4881
+ continue;
4882
+ }
4883
+ }
4884
+ if (!contentStarted && !currentTagGroup && measureIndent6(line5) === 0) {
4885
+ const optMatch = trimmed.match(OPTION_RE2);
4886
+ if (optMatch && !trimmed.startsWith("##") && !COLUMN_RE2.test(trimmed)) {
4887
+ const key = optMatch[1].trim().toLowerCase();
4888
+ if (key !== "chart" && key !== "title") {
4889
+ result.options[key] = optMatch[2].trim();
4890
+ continue;
4891
+ }
4892
+ }
4893
+ }
4894
+ const groupMatch = trimmed.match(GROUP_HEADING_RE3);
4895
+ if (groupMatch && !contentStarted) {
4896
+ const groupName = groupMatch[1].trim();
4897
+ const alias = groupMatch[2] || void 0;
4898
+ currentTagGroup = {
4899
+ name: groupName,
4900
+ alias,
4901
+ entries: [],
4902
+ lineNumber
4903
+ };
4904
+ if (alias) {
4905
+ aliasMap.set(alias.toLowerCase(), groupName.toLowerCase());
4906
+ }
4907
+ result.tagGroups.push(currentTagGroup);
4908
+ continue;
4909
+ }
4910
+ if (currentTagGroup && !contentStarted) {
4911
+ const indent2 = measureIndent6(line5);
4912
+ if (indent2 > 0) {
4913
+ const isDefault = /\bdefault\s*$/.test(trimmed);
4914
+ const entryText = isDefault ? trimmed.replace(/\s+default\s*$/, "").trim() : trimmed;
4915
+ const { label, color } = extractColor3(entryText, palette);
4916
+ if (!color) {
4917
+ warn(
4918
+ lineNumber,
4919
+ `Expected 'Value(color)' in tag group '${currentTagGroup.name}'`
4920
+ );
4921
+ continue;
4922
+ }
4923
+ if (isDefault) {
4924
+ currentTagGroup.defaultValue = label;
4925
+ }
4926
+ currentTagGroup.entries.push({
4927
+ value: label,
4928
+ color,
4929
+ lineNumber
4930
+ });
4931
+ continue;
4932
+ }
4933
+ currentTagGroup = null;
4934
+ }
4935
+ const columnMatch = trimmed.match(COLUMN_RE2);
4936
+ if (columnMatch) {
4937
+ contentStarted = true;
4938
+ currentTagGroup = null;
4939
+ if (currentCard) {
4940
+ currentCard.endLineNumber = lineNumber - 1;
4941
+ while (currentCard.endLineNumber > currentCard.lineNumber && !lines[currentCard.endLineNumber - 1].trim()) {
4942
+ currentCard.endLineNumber--;
4943
+ }
4944
+ }
4945
+ currentCard = null;
4946
+ columnCounter++;
4947
+ const rawColName = columnMatch[1].trim();
4948
+ const wipStr = columnMatch[2];
4949
+ const { label: colName, color: colColor } = extractColor3(
4950
+ rawColName,
4951
+ palette
4952
+ );
4953
+ currentColumn = {
4954
+ id: `col-${columnCounter}`,
4955
+ name: colName,
4956
+ wipLimit: wipStr ? parseInt(wipStr, 10) : void 0,
4957
+ color: colColor,
4958
+ cards: [],
4959
+ lineNumber
4960
+ };
4961
+ result.columns.push(currentColumn);
4962
+ continue;
4963
+ }
4964
+ if (!contentStarted) {
4965
+ continue;
4966
+ }
4967
+ if (!currentColumn) {
4968
+ warn(lineNumber, "Card line found before any column");
4969
+ continue;
4970
+ }
4971
+ const indent = measureIndent6(line5);
4972
+ if (indent > 0 && currentCard) {
4973
+ currentCard.details.push(trimmed);
4974
+ currentCard.endLineNumber = lineNumber;
4975
+ continue;
4976
+ }
4977
+ if (currentCard) {
4978
+ }
4979
+ cardCounter++;
4980
+ const card = parseCardLine(
4981
+ trimmed,
4982
+ lineNumber,
4983
+ cardCounter,
4984
+ aliasMap,
4985
+ palette
4986
+ );
4987
+ currentCard = card;
4988
+ currentColumn.cards.push(card);
4989
+ }
4990
+ if (currentCard) {
4991
+ }
4992
+ for (const group of result.tagGroups) {
4993
+ const values = new Set(group.entries.map((e) => e.value.toLowerCase()));
4994
+ tagValueSets.set(group.name.toLowerCase(), values);
4995
+ }
4996
+ for (const col of result.columns) {
4997
+ if (col.wipLimit != null && col.cards.length > col.wipLimit) {
4998
+ warn(
4999
+ col.lineNumber,
5000
+ `Column "${col.name}" has ${col.cards.length} cards but WIP limit is ${col.wipLimit}`
5001
+ );
5002
+ }
5003
+ }
5004
+ for (const col of result.columns) {
5005
+ for (const card of col.cards) {
5006
+ for (const [tagKey, tagValue] of Object.entries(card.tags)) {
5007
+ const groupKey = aliasMap.get(tagKey.toLowerCase()) ?? tagKey.toLowerCase();
5008
+ const validValues = tagValueSets.get(groupKey);
5009
+ if (validValues && !validValues.has(tagValue.toLowerCase())) {
5010
+ const entries = result.tagGroups.find((g) => g.name.toLowerCase() === groupKey)?.entries.map((e) => e.value);
5011
+ let msg = `Unknown tag value "${tagValue}" for group "${groupKey}"`;
5012
+ if (entries) {
5013
+ const hint = suggest(tagValue, entries);
5014
+ if (hint) msg += `. ${hint}`;
5015
+ }
5016
+ warn(card.lineNumber, msg);
5017
+ }
5018
+ }
5019
+ }
5020
+ }
5021
+ if (result.columns.length === 0 && !result.error) {
5022
+ return fail(1, "No columns found. Use == Column Name == to define columns");
5023
+ }
5024
+ return result;
5025
+ }
5026
+ function parseCardLine(trimmed, lineNumber, counter, aliasMap, palette) {
5027
+ const pipeIdx = trimmed.indexOf("|");
5028
+ let rawTitle;
5029
+ let tagsStr = null;
5030
+ if (pipeIdx >= 0) {
5031
+ rawTitle = trimmed.substring(0, pipeIdx).trim();
5032
+ tagsStr = trimmed.substring(pipeIdx + 1).trim();
5033
+ } else {
5034
+ rawTitle = trimmed;
5035
+ }
5036
+ const { label: title, color } = extractColor3(rawTitle, palette);
5037
+ const tags = {};
5038
+ if (tagsStr) {
5039
+ for (const part of tagsStr.split(",")) {
5040
+ const colonIdx = part.indexOf(":");
5041
+ if (colonIdx > 0) {
5042
+ const rawKey = part.substring(0, colonIdx).trim().toLowerCase();
5043
+ const key = aliasMap.get(rawKey) ?? rawKey;
5044
+ const value = part.substring(colonIdx + 1).trim();
5045
+ tags[key] = value;
5046
+ }
5047
+ }
5048
+ }
5049
+ return {
5050
+ id: `card-${counter}`,
5051
+ title,
5052
+ tags,
5053
+ details: [],
5054
+ lineNumber,
5055
+ endLineNumber: lineNumber,
5056
+ color
5057
+ };
5058
+ }
5059
+ var CHART_TYPE_RE2, TITLE_RE2, OPTION_RE2, GROUP_HEADING_RE3, COLUMN_RE2, COLOR_SUFFIX_RE3;
5060
+ var init_parser5 = __esm({
5061
+ "src/kanban/parser.ts"() {
5062
+ "use strict";
5063
+ init_colors();
5064
+ init_diagnostics();
5065
+ CHART_TYPE_RE2 = /^chart\s*:\s*(.+)/i;
5066
+ TITLE_RE2 = /^title\s*:\s*(.+)/i;
5067
+ OPTION_RE2 = /^([a-z][a-z0-9-]*)\s*:\s*(.+)$/i;
5068
+ GROUP_HEADING_RE3 = /^##\s+(.+?)(?:\s+alias\s+(\w+))?(?:\s*\(([^)]+)\))?\s*$/;
5069
+ COLUMN_RE2 = /^==\s+(.+?)\s*(?:\[wip:\s*(\d+)\])?\s*==$/;
5070
+ COLOR_SUFFIX_RE3 = /\(([^)]+)\)\s*$/;
5071
+ }
5072
+ });
5073
+
4783
5074
  // src/dgmo-router.ts
4784
5075
  var dgmo_router_exports = {};
4785
5076
  __export(dgmo_router_exports, {
@@ -4804,6 +5095,7 @@ function parseDgmoChartType(content) {
4804
5095
  if (looksLikeFlowchart(content)) return "flowchart";
4805
5096
  if (looksLikeClassDiagram(content)) return "class";
4806
5097
  if (looksLikeERDiagram(content)) return "er";
5098
+ if (looksLikeOrg(content)) return "org";
4807
5099
  return null;
4808
5100
  }
4809
5101
  function parseDgmo(content) {
@@ -4832,6 +5124,10 @@ function parseDgmo(content) {
4832
5124
  const parsed2 = parseOrg(content);
4833
5125
  return { diagnostics: parsed2.diagnostics };
4834
5126
  }
5127
+ if (chartType === "kanban") {
5128
+ const parsed2 = parseKanban(content);
5129
+ return { diagnostics: parsed2.diagnostics };
5130
+ }
4835
5131
  if (STANDARD_CHART_TYPES2.has(chartType)) {
4836
5132
  const parsed2 = parseChart(content);
4837
5133
  return { diagnostics: parsed2.diagnostics };
@@ -4855,6 +5151,7 @@ var init_dgmo_router = __esm({
4855
5151
  init_echarts();
4856
5152
  init_d3();
4857
5153
  init_parser4();
5154
+ init_parser5();
4858
5155
  DGMO_CHART_TYPE_MAP = {
4859
5156
  // Standard charts (via ECharts)
4860
5157
  bar: "echart",
@@ -4884,7 +5181,8 @@ var init_dgmo_router = __esm({
4884
5181
  flowchart: "d3",
4885
5182
  class: "d3",
4886
5183
  er: "d3",
4887
- org: "d3"
5184
+ org: "d3",
5185
+ kanban: "d3"
4888
5186
  };
4889
5187
  STANDARD_CHART_TYPES2 = /* @__PURE__ */ new Set([
4890
5188
  "bar",
@@ -5007,39 +5305,34 @@ function centerHeavyChildren(node) {
5007
5305
  }
5008
5306
  node.children = result;
5009
5307
  }
5010
- function computeLegendGroups(tagGroups, showEyeIcons) {
5308
+ function computeLegendGroups(tagGroups, _showEyeIcons) {
5011
5309
  const groups = [];
5012
5310
  for (const group of tagGroups) {
5013
5311
  if (group.entries.length === 0) continue;
5014
- const entryWidths = group.entries.map(
5015
- (e) => LEGEND_DOT_R * 2 + LEGEND_DOT_TEXT_GAP + e.value.length * CHAR_WIDTH
5016
- );
5017
- const numRows = Math.ceil(entryWidths.length / LEGEND_MAX_PER_ROW);
5018
- const colWidths = [];
5019
- for (let col = 0; col < LEGEND_MAX_PER_ROW; col++) {
5020
- let maxW = 0;
5021
- for (let row = 0; row < numRows; row++) {
5022
- const idx = row * LEGEND_MAX_PER_ROW + col;
5023
- if (idx < entryWidths.length && entryWidths[idx] > maxW) {
5024
- maxW = entryWidths[idx];
5025
- }
5026
- }
5027
- if (maxW > 0) colWidths.push(maxW);
5028
- }
5029
- const eyeExtra = showEyeIcons ? EYE_ICON_GAP + EYE_ICON_WIDTH : 0;
5030
- const headerWidth = group.name.length * CHAR_WIDTH + eyeExtra;
5031
- const totalColumnsWidth = colWidths.reduce((s, w) => s + w, 0) + (colWidths.length - 1) * LEGEND_ENTRY_GAP;
5032
- const maxRowWidth = Math.max(headerWidth, totalColumnsWidth);
5033
- const minifiedWidth = group.name.length * CHAR_WIDTH + LEGEND_PAD * 2;
5312
+ const pillLabel = group.alias ? `${group.name} (${group.alias})` : group.name;
5313
+ const pillWidth = pillLabel.length * LEGEND_PILL_FONT_W + LEGEND_PILL_PAD;
5314
+ const minPillWidth = group.name.length * LEGEND_PILL_FONT_W + LEGEND_PILL_PAD;
5315
+ const isDefaultValue = group.defaultValue?.toLowerCase();
5316
+ let entriesWidth = 0;
5317
+ for (const entry of group.entries) {
5318
+ const entryLabel = isDefaultValue === entry.value.toLowerCase() ? `${entry.value} (default)` : entry.value;
5319
+ entriesWidth += LEGEND_DOT_R * 2 + LEGEND_ENTRY_DOT_GAP + entryLabel.length * LEGEND_ENTRY_FONT_W + LEGEND_ENTRY_TRAIL;
5320
+ }
5321
+ const capsuleWidth = LEGEND_CAPSULE_PAD * 2 + pillWidth + 4 + entriesWidth;
5034
5322
  groups.push({
5035
5323
  name: group.name,
5036
- entries: group.entries.map((e) => ({ value: e.value, color: e.color })),
5324
+ alias: group.alias,
5325
+ entries: group.entries.map((e) => ({
5326
+ value: e.value,
5327
+ color: e.color,
5328
+ isDefault: group.defaultValue?.toLowerCase() === e.value.toLowerCase() || void 0
5329
+ })),
5037
5330
  x: 0,
5038
5331
  y: 0,
5039
- width: maxRowWidth + LEGEND_PAD * 2,
5040
- height: LEGEND_HEADER_H + numRows * LEGEND_ENTRY_H + LEGEND_PAD,
5041
- minifiedWidth,
5042
- minifiedHeight: LEGEND_HEADER_H + LEGEND_PAD
5332
+ width: capsuleWidth,
5333
+ height: LEGEND_HEIGHT,
5334
+ minifiedWidth: minPillWidth,
5335
+ minifiedHeight: LEGEND_HEIGHT
5043
5336
  });
5044
5337
  }
5045
5338
  return groups;
@@ -5066,7 +5359,27 @@ function injectDefaultMetadata(roots, tagGroups) {
5066
5359
  }
5067
5360
  function layoutOrg(parsed, hiddenCounts, activeTagGroup, hiddenAttributes) {
5068
5361
  if (parsed.roots.length === 0) {
5069
- return { nodes: [], edges: [], containers: [], legend: [], width: 0, height: 0 };
5362
+ const showEyeIcons2 = hiddenAttributes !== void 0;
5363
+ const legendGroups2 = computeLegendGroups(parsed.tagGroups, showEyeIcons2);
5364
+ if (legendGroups2.length === 0) {
5365
+ return { nodes: [], edges: [], containers: [], legend: [], width: 0, height: 0 };
5366
+ }
5367
+ let cy = MARGIN;
5368
+ let maxWidth2 = 0;
5369
+ for (const g of legendGroups2) {
5370
+ g.x = MARGIN;
5371
+ g.y = cy;
5372
+ cy += LEGEND_HEIGHT + LEGEND_GROUP_GAP;
5373
+ if (g.width > maxWidth2) maxWidth2 = g.width;
5374
+ }
5375
+ return {
5376
+ nodes: [],
5377
+ edges: [],
5378
+ containers: [],
5379
+ legend: legendGroups2,
5380
+ width: maxWidth2 + MARGIN * 2,
5381
+ height: cy - LEGEND_GROUP_GAP + MARGIN
5382
+ };
5070
5383
  }
5071
5384
  injectDefaultMetadata(parsed.roots, parsed.tagGroups);
5072
5385
  const subNodeLabel = parsed.options["sub-node-label"] ?? void 0;
@@ -5574,13 +5887,13 @@ function layoutOrg(parsed, hiddenCounts, activeTagGroup, hiddenAttributes) {
5574
5887
  const legendGroups = computeLegendGroups(parsed.tagGroups, showEyeIcons);
5575
5888
  let finalWidth = totalWidth;
5576
5889
  let finalHeight = totalHeight;
5577
- const legendPosition = parsed.options?.["legend-position"] ?? "bottom";
5890
+ const legendPosition = parsed.options?.["legend-position"] ?? "top";
5578
5891
  const visibleGroups = activeTagGroup != null ? legendGroups.filter((g) => g.name.toLowerCase() === activeTagGroup.toLowerCase()) : legendGroups;
5579
5892
  const effectiveW = (g) => activeTagGroup != null ? g.width : g.minifiedWidth;
5580
5893
  const effectiveH = (g) => activeTagGroup != null ? g.height : g.minifiedHeight;
5581
5894
  if (visibleGroups.length > 0) {
5582
5895
  if (legendPosition === "bottom") {
5583
- const totalGroupsWidth = visibleGroups.reduce((s, g) => s + effectiveW(g), 0) + (visibleGroups.length - 1) * H_GAP;
5896
+ const totalGroupsWidth = visibleGroups.reduce((s, g) => s + effectiveW(g), 0) + (visibleGroups.length - 1) * LEGEND_GROUP_GAP;
5584
5897
  const neededWidth = totalGroupsWidth + MARGIN * 2;
5585
5898
  if (neededWidth > totalWidth) {
5586
5899
  finalWidth = neededWidth;
@@ -5595,31 +5908,30 @@ function layoutOrg(parsed, hiddenCounts, activeTagGroup, hiddenAttributes) {
5595
5908
  const legendY = contentBottom + LEGEND_GAP;
5596
5909
  const startX = (finalWidth - totalGroupsWidth) / 2;
5597
5910
  let cx = startX;
5598
- let maxH = 0;
5599
5911
  for (const g of visibleGroups) {
5600
5912
  g.x = cx;
5601
5913
  g.y = legendY;
5602
- cx += effectiveW(g) + H_GAP;
5603
- const h2 = effectiveH(g);
5604
- if (h2 > maxH) maxH = h2;
5914
+ cx += effectiveW(g) + LEGEND_GROUP_GAP;
5605
5915
  }
5606
- finalHeight = totalHeight + LEGEND_GAP + maxH;
5916
+ finalHeight = totalHeight + LEGEND_GAP + LEGEND_HEIGHT;
5607
5917
  } else {
5608
- const maxLegendWidth = Math.max(...visibleGroups.map((g) => effectiveW(g)));
5609
- const legendStartX = totalWidth - MARGIN + LEGEND_GAP;
5610
- let legendY = MARGIN;
5918
+ const legendShift = LEGEND_HEIGHT + LEGEND_GROUP_GAP;
5919
+ for (const n of layoutNodes) n.y += legendShift;
5920
+ for (const c of containers) c.y += legendShift;
5921
+ for (const e of layoutEdges) {
5922
+ for (const p of e.points) p.y += legendShift;
5923
+ }
5924
+ const totalGroupsWidth = visibleGroups.reduce((s, g) => s + effectiveW(g), 0) + (visibleGroups.length - 1) * LEGEND_GROUP_GAP;
5925
+ let cx = MARGIN;
5611
5926
  for (const g of visibleGroups) {
5612
- g.x = legendStartX;
5613
- g.y = legendY;
5614
- legendY += effectiveH(g) + LEGEND_V_GAP;
5615
- }
5616
- const legendRight = legendStartX + maxLegendWidth + MARGIN;
5617
- if (legendRight > finalWidth) {
5618
- finalWidth = legendRight;
5927
+ g.x = cx;
5928
+ g.y = MARGIN;
5929
+ cx += effectiveW(g) + LEGEND_GROUP_GAP;
5619
5930
  }
5620
- const legendBottom = legendY - LEGEND_V_GAP + MARGIN;
5621
- if (legendBottom > finalHeight) {
5622
- finalHeight = legendBottom;
5931
+ finalHeight += legendShift;
5932
+ const neededWidth = totalGroupsWidth + MARGIN * 2;
5933
+ if (neededWidth > finalWidth) {
5934
+ finalWidth = neededWidth;
5623
5935
  }
5624
5936
  }
5625
5937
  }
@@ -5632,7 +5944,7 @@ function layoutOrg(parsed, hiddenCounts, activeTagGroup, hiddenAttributes) {
5632
5944
  height: finalHeight
5633
5945
  };
5634
5946
  }
5635
- var CHAR_WIDTH, META_LINE_HEIGHT, HEADER_HEIGHT, SEPARATOR_GAP, CARD_H_PAD, CARD_V_PAD, MIN_CARD_WIDTH, H_GAP, V_GAP, MARGIN, CONTAINER_PAD_X, CONTAINER_PAD_BOTTOM, CONTAINER_LABEL_HEIGHT, CONTAINER_META_LINE_HEIGHT, STACK_V_GAP, LEGEND_GAP, LEGEND_DOT_R, LEGEND_DOT_TEXT_GAP, LEGEND_ENTRY_GAP, LEGEND_PAD, LEGEND_HEADER_H, LEGEND_ENTRY_H, LEGEND_MAX_PER_ROW, LEGEND_V_GAP, EYE_ICON_WIDTH, EYE_ICON_GAP;
5947
+ var CHAR_WIDTH, META_LINE_HEIGHT, HEADER_HEIGHT, SEPARATOR_GAP, CARD_H_PAD, CARD_V_PAD, MIN_CARD_WIDTH, H_GAP, V_GAP, MARGIN, CONTAINER_PAD_X, CONTAINER_PAD_BOTTOM, CONTAINER_LABEL_HEIGHT, CONTAINER_META_LINE_HEIGHT, STACK_V_GAP, LEGEND_GAP, LEGEND_HEIGHT, LEGEND_PILL_PAD, LEGEND_PILL_FONT_W, LEGEND_CAPSULE_PAD, LEGEND_DOT_R, LEGEND_ENTRY_FONT_W, LEGEND_ENTRY_DOT_GAP, LEGEND_ENTRY_TRAIL, LEGEND_GROUP_GAP;
5636
5948
  var init_layout = __esm({
5637
5949
  "src/org/layout.ts"() {
5638
5950
  "use strict";
@@ -5652,16 +5964,15 @@ var init_layout = __esm({
5652
5964
  CONTAINER_META_LINE_HEIGHT = 16;
5653
5965
  STACK_V_GAP = 20;
5654
5966
  LEGEND_GAP = 30;
5655
- LEGEND_DOT_R = 5;
5656
- LEGEND_DOT_TEXT_GAP = 6;
5657
- LEGEND_ENTRY_GAP = 12;
5658
- LEGEND_PAD = 10;
5659
- LEGEND_HEADER_H = 20;
5660
- LEGEND_ENTRY_H = 18;
5661
- LEGEND_MAX_PER_ROW = 3;
5662
- LEGEND_V_GAP = 12;
5663
- EYE_ICON_WIDTH = 16;
5664
- EYE_ICON_GAP = 6;
5967
+ LEGEND_HEIGHT = 28;
5968
+ LEGEND_PILL_PAD = 16;
5969
+ LEGEND_PILL_FONT_W = 11 * 0.6;
5970
+ LEGEND_CAPSULE_PAD = 4;
5971
+ LEGEND_DOT_R = 4;
5972
+ LEGEND_ENTRY_FONT_W = 10 * 0.6;
5973
+ LEGEND_ENTRY_DOT_GAP = 4;
5974
+ LEGEND_ENTRY_TRAIL = 8;
5975
+ LEGEND_GROUP_GAP = 12;
5665
5976
  }
5666
5977
  });
5667
5978
 
@@ -5896,69 +6207,40 @@ function renderOrg(container, parsed, layout, palette, isDark, onClickItem, expo
5896
6207
  nodeG.append("rect").attr("x", COLLAPSE_BAR_INSET).attr("y", node.height - COLLAPSE_BAR_HEIGHT).attr("width", node.width - COLLAPSE_BAR_INSET * 2).attr("height", COLLAPSE_BAR_HEIGHT).attr("fill", nodeStroke(palette, colorOff ? void 0 : node.color)).attr("clip-path", `url(#${clipId})`).attr("class", "org-collapse-bar");
5897
6208
  }
5898
6209
  }
5899
- if (!exportDims) for (const group of layout.legend) {
5900
- const isActive = activeTagGroup != null && group.name.toLowerCase() === activeTagGroup.toLowerCase();
5901
- if (activeTagGroup != null && !isActive) continue;
5902
- const isMinified = activeTagGroup == null;
5903
- const renderW = isMinified ? group.minifiedWidth : group.width;
5904
- const renderH = isMinified ? group.minifiedHeight : group.height;
5905
- const gEl = contentG.append("g").attr("transform", `translate(${group.x}, ${group.y})`).attr("class", "org-legend-group").attr("data-legend-group", group.name.toLowerCase()).style("cursor", "pointer");
5906
- const legendFill = mix(palette.surface, palette.bg, 40);
5907
- const bgRect = gEl.append("rect").attr("x", 0).attr("y", 0).attr("width", renderW).attr("height", renderH).attr("rx", LEGEND_RADIUS).attr("fill", legendFill);
6210
+ const legendOnly = layout.nodes.length === 0;
6211
+ if (!exportDims || legendOnly) for (const group of layout.legend) {
6212
+ const isActive = legendOnly || activeTagGroup != null && group.name.toLowerCase() === activeTagGroup.toLowerCase();
6213
+ if (!legendOnly && activeTagGroup != null && !isActive) continue;
6214
+ const groupBg = isDark ? mix(palette.surface, palette.bg, 50) : mix(palette.surface, palette.bg, 30);
6215
+ const pillLabel = isActive && group.alias ? `${group.name} (${group.alias})` : group.name;
6216
+ const pillWidth = pillLabel.length * LEGEND_PILL_FONT_W2 + LEGEND_PILL_PAD2;
6217
+ const gEl = contentG.append("g").attr("transform", `translate(${group.x}, ${group.y})`).attr("class", "org-legend-group").attr("data-legend-group", group.name.toLowerCase()).style("cursor", legendOnly ? "default" : "pointer");
5908
6218
  if (isActive) {
5909
- bgRect.attr("stroke", palette.primary).attr("stroke-opacity", 0.8).attr("stroke-width", 2);
5910
- } else {
5911
- bgRect.attr("stroke", palette.textMuted).attr("stroke-opacity", 0.35).attr("stroke-width", NODE_STROKE_WIDTH);
5912
- }
5913
- gEl.append("text").attr("x", LEGEND_PAD2).attr("y", LEGEND_HEADER_H2 / 2 + LEGEND_FONT_SIZE / 2 - 2).attr("fill", isMinified ? palette.textMuted : palette.text).attr("font-size", LEGEND_FONT_SIZE).attr("font-weight", "bold").text(group.name);
5914
- if (isMinified) continue;
5915
- if (hiddenAttributes !== void 0 && !exportDims) {
5916
- const groupKey = group.name.toLowerCase();
5917
- const isHidden = hiddenAttributes.has(groupKey);
5918
- const eyeX = LEGEND_PAD2 + group.name.length * LEGEND_CHAR_WIDTH + EYE_ICON_GAP2;
5919
- const eyeY = (LEGEND_HEADER_H2 - EYE_ICON_SIZE) / 2;
5920
- const eyeG = gEl.append("g").attr("class", "org-legend-eye").attr("data-legend-visibility", groupKey).attr("transform", `translate(${eyeX}, ${eyeY})`);
5921
- eyeG.append("rect").attr("x", -4).attr("y", -4).attr("width", EYE_ICON_SIZE + 8).attr("height", EYE_ICON_SIZE + 8).attr("fill", "transparent");
5922
- eyeG.append("path").attr("d", EYE_OPEN_PATH).attr("fill", isHidden ? "none" : palette.textMuted).attr("fill-opacity", isHidden ? 0 : 0.15).attr("stroke", palette.textMuted).attr("stroke-width", 1.2).attr("opacity", isHidden ? 0.5 : 0.7);
5923
- if (!isHidden) {
5924
- eyeG.append("circle").attr("cx", EYE_PUPIL_CX).attr("cy", EYE_PUPIL_CY).attr("r", EYE_PUPIL_R).attr("fill", palette.textMuted).attr("opacity", 0.7);
5925
- } else {
5926
- eyeG.append("line").attr("x1", 2).attr("y1", 2).attr("x2", 10).attr("y2", 10).attr("stroke", palette.textMuted).attr("stroke-width", 1.5).attr("opacity", 0.5);
5927
- }
6219
+ gEl.append("rect").attr("width", group.width).attr("height", LEGEND_HEIGHT2).attr("rx", LEGEND_HEIGHT2 / 2).attr("fill", groupBg);
5928
6220
  }
5929
- const entryWidths = group.entries.map(
5930
- (e) => LEGEND_DOT_R2 * 2 + LEGEND_DOT_TEXT_GAP2 + e.value.length * LEGEND_CHAR_WIDTH
5931
- );
5932
- const numRows = Math.ceil(group.entries.length / LEGEND_MAX_PER_ROW2);
5933
- const colWidths = [];
5934
- for (let col = 0; col < LEGEND_MAX_PER_ROW2; col++) {
5935
- let maxW = 0;
5936
- for (let r = 0; r < numRows; r++) {
5937
- const idx = r * LEGEND_MAX_PER_ROW2 + col;
5938
- if (idx < entryWidths.length && entryWidths[idx] > maxW) {
5939
- maxW = entryWidths[idx];
5940
- }
5941
- }
5942
- if (maxW > 0) colWidths.push(maxW);
5943
- }
5944
- const colX = [LEGEND_PAD2];
5945
- for (let c = 1; c < colWidths.length; c++) {
5946
- colX.push(colX[c - 1] + colWidths[c - 1] + LEGEND_ENTRY_GAP2);
6221
+ const pillX = isActive ? LEGEND_CAPSULE_PAD2 : 0;
6222
+ const pillY = isActive ? LEGEND_CAPSULE_PAD2 : 0;
6223
+ const pillH = LEGEND_HEIGHT2 - (isActive ? LEGEND_CAPSULE_PAD2 * 2 : 0);
6224
+ gEl.append("rect").attr("x", pillX).attr("y", pillY).attr("width", pillWidth).attr("height", pillH).attr("rx", pillH / 2).attr("fill", isActive ? palette.bg : groupBg);
6225
+ if (isActive) {
6226
+ gEl.append("rect").attr("x", pillX).attr("y", pillY).attr("width", pillWidth).attr("height", pillH).attr("rx", pillH / 2).attr("fill", "none").attr("stroke", mix(palette.textMuted, palette.bg, 50)).attr("stroke-width", 0.75);
5947
6227
  }
5948
- for (let i = 0; i < group.entries.length; i++) {
5949
- const entry = group.entries[i];
5950
- const row = Math.floor(i / LEGEND_MAX_PER_ROW2);
5951
- const col = i % LEGEND_MAX_PER_ROW2;
5952
- const entryX = colX[col];
5953
- const entryY = LEGEND_HEADER_H2 + row * LEGEND_ENTRY_H2 + LEGEND_ENTRY_H2 / 2;
5954
- gEl.append("circle").attr("cx", entryX + LEGEND_DOT_R2).attr("cy", entryY).attr("r", LEGEND_DOT_R2).attr("fill", entry.color);
5955
- gEl.append("text").attr("x", entryX + LEGEND_DOT_R2 * 2 + LEGEND_DOT_TEXT_GAP2).attr("y", entryY + LEGEND_FONT_SIZE / 2 - 2).attr("fill", palette.text).attr("font-size", LEGEND_FONT_SIZE).text(entry.value);
6228
+ gEl.append("text").attr("x", pillX + pillWidth / 2).attr("y", LEGEND_HEIGHT2 / 2 + LEGEND_PILL_FONT_SIZE / 2 - 2).attr("font-size", LEGEND_PILL_FONT_SIZE).attr("font-weight", "500").attr("fill", isActive ? palette.text : palette.textMuted).attr("text-anchor", "middle").text(pillLabel);
6229
+ if (isActive) {
6230
+ let entryX = pillX + pillWidth + 4;
6231
+ for (const entry of group.entries) {
6232
+ gEl.append("circle").attr("cx", entryX + LEGEND_DOT_R2).attr("cy", LEGEND_HEIGHT2 / 2).attr("r", LEGEND_DOT_R2).attr("fill", entry.color);
6233
+ const textX = entryX + LEGEND_DOT_R2 * 2 + LEGEND_ENTRY_DOT_GAP2;
6234
+ const entryLabel = entry.isDefault ? `${entry.value} (default)` : entry.value;
6235
+ gEl.append("text").attr("x", textX).attr("y", LEGEND_HEIGHT2 / 2 + LEGEND_ENTRY_FONT_SIZE / 2 - 1).attr("font-size", LEGEND_ENTRY_FONT_SIZE).attr("fill", palette.textMuted).text(entryLabel);
6236
+ entryX = textX + entryLabel.length * LEGEND_ENTRY_FONT_W2 + LEGEND_ENTRY_TRAIL2;
6237
+ }
5956
6238
  }
5957
6239
  }
5958
6240
  }
5959
6241
  function renderOrgForExport(content, theme, palette) {
5960
6242
  const parsed = parseOrg(content, palette);
5961
- if (parsed.error || parsed.roots.length === 0) return "";
6243
+ if (parsed.error) return "";
5962
6244
  const hideOption = parsed.options?.["hide"];
5963
6245
  const exportHidden = hideOption ? new Set(hideOption.split(",").map((s) => s.trim().toLowerCase())) : void 0;
5964
6246
  const layout = layoutOrg(parsed, void 0, void 0, exportHidden);
@@ -5989,7 +6271,7 @@ function renderOrgForExport(content, theme, palette) {
5989
6271
  document.body.removeChild(container);
5990
6272
  }
5991
6273
  }
5992
- 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_RADIUS, LEGEND_DOT_R2, LEGEND_DOT_TEXT_GAP2, LEGEND_ENTRY_GAP2, LEGEND_PAD2, LEGEND_HEADER_H2, LEGEND_ENTRY_H2, LEGEND_FONT_SIZE, LEGEND_MAX_PER_ROW2, LEGEND_CHAR_WIDTH, EYE_ICON_SIZE, EYE_ICON_GAP2, EYE_OPEN_PATH, EYE_PUPIL_CX, EYE_PUPIL_CY, EYE_PUPIL_R;
6274
+ 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_HEIGHT2, LEGEND_PILL_PAD2, LEGEND_PILL_FONT_SIZE, LEGEND_PILL_FONT_W2, LEGEND_CAPSULE_PAD2, LEGEND_DOT_R2, LEGEND_ENTRY_FONT_SIZE, LEGEND_ENTRY_FONT_W2, LEGEND_ENTRY_DOT_GAP2, LEGEND_ENTRY_TRAIL2;
5993
6275
  var init_renderer = __esm({
5994
6276
  "src/org/renderer.ts"() {
5995
6277
  "use strict";
@@ -6015,22 +6297,393 @@ var init_renderer = __esm({
6015
6297
  CONTAINER_HEADER_HEIGHT = 28;
6016
6298
  COLLAPSE_BAR_HEIGHT = 6;
6017
6299
  COLLAPSE_BAR_INSET = 0;
6018
- LEGEND_RADIUS = 6;
6019
- LEGEND_DOT_R2 = 5;
6020
- LEGEND_DOT_TEXT_GAP2 = 6;
6021
- LEGEND_ENTRY_GAP2 = 12;
6022
- LEGEND_PAD2 = 10;
6023
- LEGEND_HEADER_H2 = 20;
6024
- LEGEND_ENTRY_H2 = 18;
6300
+ LEGEND_HEIGHT2 = 28;
6301
+ LEGEND_PILL_PAD2 = 16;
6302
+ LEGEND_PILL_FONT_SIZE = 11;
6303
+ LEGEND_PILL_FONT_W2 = LEGEND_PILL_FONT_SIZE * 0.6;
6304
+ LEGEND_CAPSULE_PAD2 = 4;
6305
+ LEGEND_DOT_R2 = 4;
6306
+ LEGEND_ENTRY_FONT_SIZE = 10;
6307
+ LEGEND_ENTRY_FONT_W2 = LEGEND_ENTRY_FONT_SIZE * 0.6;
6308
+ LEGEND_ENTRY_DOT_GAP2 = 4;
6309
+ LEGEND_ENTRY_TRAIL2 = 8;
6310
+ }
6311
+ });
6312
+
6313
+ // src/kanban/mutations.ts
6314
+ function computeCardMove(content, parsed, cardId, targetColumnId, targetIndex) {
6315
+ let sourceCard = null;
6316
+ let sourceColumn = null;
6317
+ for (const col of parsed.columns) {
6318
+ for (const card of col.cards) {
6319
+ if (card.id === cardId) {
6320
+ sourceCard = card;
6321
+ sourceColumn = col;
6322
+ break;
6323
+ }
6324
+ }
6325
+ if (sourceCard) break;
6326
+ }
6327
+ if (!sourceCard || !sourceColumn) return null;
6328
+ const targetColumn = parsed.columns.find((c) => c.id === targetColumnId);
6329
+ if (!targetColumn) return null;
6330
+ const lines = content.split("\n");
6331
+ const startIdx = sourceCard.lineNumber - 1;
6332
+ const endIdx = sourceCard.endLineNumber - 1;
6333
+ const cardLines = lines.slice(startIdx, endIdx + 1);
6334
+ const withoutCard = [
6335
+ ...lines.slice(0, startIdx),
6336
+ ...lines.slice(endIdx + 1)
6337
+ ];
6338
+ let insertIdx;
6339
+ const removedCount = endIdx - startIdx + 1;
6340
+ const adjustLine = (ln) => {
6341
+ if (ln > endIdx + 1) return ln - removedCount;
6342
+ return ln;
6343
+ };
6344
+ if (targetIndex === 0) {
6345
+ const adjColLine = adjustLine(targetColumn.lineNumber);
6346
+ insertIdx = adjColLine;
6347
+ } else {
6348
+ const targetCards = targetColumn.cards.filter((c) => c.id !== cardId);
6349
+ const clampedIdx = Math.min(targetIndex, targetCards.length);
6350
+ const precedingCard = targetCards[clampedIdx - 1];
6351
+ if (!precedingCard) {
6352
+ const adjColLine = adjustLine(targetColumn.lineNumber);
6353
+ insertIdx = adjColLine;
6354
+ } else {
6355
+ const adjEndLine = adjustLine(precedingCard.endLineNumber);
6356
+ insertIdx = adjEndLine;
6357
+ }
6358
+ }
6359
+ const result = [
6360
+ ...withoutCard.slice(0, insertIdx),
6361
+ ...cardLines,
6362
+ ...withoutCard.slice(insertIdx)
6363
+ ];
6364
+ return result.join("\n");
6365
+ }
6366
+ function computeCardArchive(content, parsed, cardId) {
6367
+ let sourceCard = null;
6368
+ for (const col of parsed.columns) {
6369
+ for (const card of col.cards) {
6370
+ if (card.id === cardId) {
6371
+ sourceCard = card;
6372
+ break;
6373
+ }
6374
+ }
6375
+ if (sourceCard) break;
6376
+ }
6377
+ if (!sourceCard) return null;
6378
+ const lines = content.split("\n");
6379
+ const startIdx = sourceCard.lineNumber - 1;
6380
+ const endIdx = sourceCard.endLineNumber - 1;
6381
+ const cardLines = lines.slice(startIdx, endIdx + 1);
6382
+ const withoutCard = [
6383
+ ...lines.slice(0, startIdx),
6384
+ ...lines.slice(endIdx + 1)
6385
+ ];
6386
+ const archiveCol = parsed.columns.find(
6387
+ (c) => c.name.toLowerCase() === ARCHIVE_COLUMN_NAME
6388
+ );
6389
+ if (archiveCol) {
6390
+ const removedCount = endIdx - startIdx + 1;
6391
+ let archiveEndLine = archiveCol.lineNumber;
6392
+ if (archiveCol.cards.length > 0) {
6393
+ const lastCard = archiveCol.cards[archiveCol.cards.length - 1];
6394
+ archiveEndLine = lastCard.endLineNumber;
6395
+ }
6396
+ if (archiveEndLine > endIdx + 1) {
6397
+ archiveEndLine -= removedCount;
6398
+ }
6399
+ const insertIdx = archiveEndLine;
6400
+ return [
6401
+ ...withoutCard.slice(0, insertIdx),
6402
+ ...cardLines,
6403
+ ...withoutCard.slice(insertIdx)
6404
+ ].join("\n");
6405
+ } else {
6406
+ const trimmedEnd = withoutCard.length > 0 && withoutCard[withoutCard.length - 1].trim() === "" ? withoutCard : [...withoutCard, ""];
6407
+ return [
6408
+ ...trimmedEnd,
6409
+ "== Archive ==",
6410
+ ...cardLines
6411
+ ].join("\n");
6412
+ }
6413
+ }
6414
+ function isArchiveColumn(name) {
6415
+ return name.toLowerCase() === ARCHIVE_COLUMN_NAME;
6416
+ }
6417
+ var ARCHIVE_COLUMN_NAME;
6418
+ var init_mutations = __esm({
6419
+ "src/kanban/mutations.ts"() {
6420
+ "use strict";
6421
+ ARCHIVE_COLUMN_NAME = "archive";
6422
+ }
6423
+ });
6424
+
6425
+ // src/kanban/renderer.ts
6426
+ var renderer_exports2 = {};
6427
+ __export(renderer_exports2, {
6428
+ renderKanban: () => renderKanban,
6429
+ renderKanbanForExport: () => renderKanbanForExport
6430
+ });
6431
+ import * as d3Selection2 from "d3-selection";
6432
+ function mix2(a, b, pct) {
6433
+ const parse = (h) => {
6434
+ const r = h.replace("#", "");
6435
+ const f = r.length === 3 ? r[0] + r[0] + r[1] + r[1] + r[2] + r[2] : r;
6436
+ return [
6437
+ parseInt(f.substring(0, 2), 16),
6438
+ parseInt(f.substring(2, 4), 16),
6439
+ parseInt(f.substring(4, 6), 16)
6440
+ ];
6441
+ };
6442
+ const [ar, ag, ab] = parse(a);
6443
+ const [br, bg, bb] = parse(b);
6444
+ const t = pct / 100;
6445
+ const c = (x, y) => Math.round(x * t + y * (1 - t)).toString(16).padStart(2, "0");
6446
+ return `#${c(ar, br)}${c(ag, bg)}${c(ab, bb)}`;
6447
+ }
6448
+ function resolveCardTagMeta(card, tagGroups) {
6449
+ const meta = [];
6450
+ for (const group of tagGroups) {
6451
+ const tagValue = card.tags[group.name.toLowerCase()];
6452
+ const value = tagValue ?? group.defaultValue;
6453
+ if (!value) continue;
6454
+ const entry = group.entries.find(
6455
+ (e) => e.value.toLowerCase() === value.toLowerCase()
6456
+ );
6457
+ meta.push({ label: group.name, value, color: entry?.color });
6458
+ }
6459
+ return meta;
6460
+ }
6461
+ function resolveCardTagColor(card, tagGroups, activeTagGroup) {
6462
+ if (!activeTagGroup) return card.color;
6463
+ const group = tagGroups.find(
6464
+ (g) => g.name.toLowerCase() === activeTagGroup.toLowerCase()
6465
+ );
6466
+ if (!group) return card.color;
6467
+ const tagValue = card.tags[group.name.toLowerCase()];
6468
+ const value = tagValue ?? group.defaultValue;
6469
+ if (!value) return void 0;
6470
+ const entry = group.entries.find(
6471
+ (e) => e.value.toLowerCase() === value.toLowerCase()
6472
+ );
6473
+ return entry?.color;
6474
+ }
6475
+ function computeLayout(parsed, _palette) {
6476
+ const hasHeader = !!parsed.title || parsed.tagGroups.length > 0;
6477
+ const headerHeight = hasHeader ? Math.max(TITLE_HEIGHT2, LEGEND_HEIGHT3) + 8 : 0;
6478
+ const startY = DIAGRAM_PADDING2 + headerHeight;
6479
+ const charWidth = CARD_TITLE_FONT_SIZE * 0.6;
6480
+ const columnLayouts = [];
6481
+ let maxColumnHeight = 0;
6482
+ const visibleColumns = parsed.columns.filter((c) => !isArchiveColumn(c.name));
6483
+ for (const col of visibleColumns) {
6484
+ let maxCardTextWidth = col.name.length * (COLUMN_HEADER_FONT_SIZE * 0.65);
6485
+ const cardLayouts = [];
6486
+ let cardY = COLUMN_HEADER_HEIGHT + COLUMN_PADDING;
6487
+ for (const card of col.cards) {
6488
+ const titleWidth = card.title.length * charWidth;
6489
+ maxCardTextWidth = Math.max(
6490
+ maxCardTextWidth,
6491
+ titleWidth + CARD_PADDING_X * 2
6492
+ );
6493
+ const tagMeta = resolveCardTagMeta(card, parsed.tagGroups);
6494
+ const metaCount = tagMeta.length + card.details.length;
6495
+ const metaHeight = metaCount > 0 ? CARD_SEPARATOR_GAP + 1 + CARD_PADDING_Y + metaCount * CARD_META_LINE_HEIGHT : 0;
6496
+ const cardHeight = CARD_HEADER_HEIGHT + CARD_PADDING_Y + metaHeight;
6497
+ for (const m of tagMeta) {
6498
+ const metaW = (m.label.length + 2 + m.value.length) * CARD_META_FONT_SIZE * 0.6 + CARD_PADDING_X * 2;
6499
+ maxCardTextWidth = Math.max(maxCardTextWidth, metaW);
6500
+ }
6501
+ cardLayouts.push({
6502
+ x: COLUMN_PADDING,
6503
+ y: cardY,
6504
+ width: 0,
6505
+ // set after column width computed
6506
+ height: cardHeight,
6507
+ card
6508
+ });
6509
+ cardY += cardHeight + CARD_GAP;
6510
+ }
6511
+ const colWidth = Math.max(COLUMN_MIN_WIDTH, maxCardTextWidth + COLUMN_PADDING * 2);
6512
+ for (const cl of cardLayouts) {
6513
+ cl.width = colWidth - COLUMN_PADDING * 2;
6514
+ }
6515
+ const colHeight = cardY + COLUMN_PADDING;
6516
+ maxColumnHeight = Math.max(maxColumnHeight, colHeight);
6517
+ columnLayouts.push({
6518
+ x: 0,
6519
+ // set below
6520
+ y: startY,
6521
+ width: colWidth,
6522
+ height: colHeight,
6523
+ column: col,
6524
+ cardLayouts
6525
+ });
6526
+ }
6527
+ let currentX = DIAGRAM_PADDING2;
6528
+ for (const cl of columnLayouts) {
6529
+ cl.x = currentX;
6530
+ cl.height = maxColumnHeight;
6531
+ currentX += cl.width + COLUMN_GAP;
6532
+ }
6533
+ const totalWidth = currentX - COLUMN_GAP + DIAGRAM_PADDING2;
6534
+ const totalHeight = startY + maxColumnHeight + DIAGRAM_PADDING2;
6535
+ return { columns: columnLayouts, totalWidth, totalHeight };
6536
+ }
6537
+ function renderKanban(container, parsed, palette, isDark, _onNavigateToLine, exportDims, activeTagGroup) {
6538
+ const layout = computeLayout(parsed, palette);
6539
+ const width = exportDims?.width ?? layout.totalWidth;
6540
+ const height = exportDims?.height ?? layout.totalHeight;
6541
+ container.innerHTML = "";
6542
+ const svg = d3Selection2.select(container).append("svg").attr("xmlns", "http://www.w3.org/2000/svg").attr("width", width).attr("height", height).attr("font-family", FONT_FAMILY).style("background", palette.bg);
6543
+ if (parsed.title) {
6544
+ svg.append("text").attr("class", "chart-title").attr("data-line-number", parsed.titleLineNumber ?? 0).attr("x", DIAGRAM_PADDING2).attr("y", DIAGRAM_PADDING2 + TITLE_FONT_SIZE2).attr("font-size", TITLE_FONT_SIZE2).attr("font-weight", "bold").attr("fill", palette.text).text(parsed.title);
6545
+ }
6546
+ if (parsed.tagGroups.length > 0) {
6547
+ const legendY = DIAGRAM_PADDING2;
6548
+ const titleTextWidth = parsed.title ? parsed.title.length * TITLE_FONT_SIZE2 * 0.6 + 16 : 0;
6549
+ let legendX = DIAGRAM_PADDING2 + titleTextWidth;
6550
+ const groupBg = isDark ? mix2(palette.surface, palette.bg, 50) : mix2(palette.surface, palette.bg, 30);
6551
+ const capsulePad = 4;
6552
+ for (const group of parsed.tagGroups) {
6553
+ const isActive = activeTagGroup?.toLowerCase() === group.name.toLowerCase();
6554
+ if (activeTagGroup != null && !isActive) continue;
6555
+ const pillTextWidth = group.name.length * LEGEND_FONT_SIZE * 0.6;
6556
+ const pillWidth = pillTextWidth + 16;
6557
+ let capsuleContentWidth = pillWidth;
6558
+ if (isActive) {
6559
+ capsuleContentWidth += 4;
6560
+ for (const entry of group.entries) {
6561
+ capsuleContentWidth += LEGEND_DOT_R3 * 2 + 4 + entry.value.length * LEGEND_ENTRY_FONT_SIZE2 * 0.6 + 8;
6562
+ }
6563
+ }
6564
+ const capsuleWidth = capsuleContentWidth + capsulePad * 2;
6565
+ if (isActive) {
6566
+ svg.append("rect").attr("x", legendX).attr("y", legendY).attr("width", capsuleWidth).attr("height", LEGEND_HEIGHT3).attr("rx", LEGEND_HEIGHT3 / 2).attr("fill", groupBg);
6567
+ }
6568
+ const pillX = legendX + (isActive ? capsulePad : 0);
6569
+ const pillBg = isActive ? palette.bg : groupBg;
6570
+ svg.append("rect").attr("x", pillX).attr("y", legendY + (isActive ? capsulePad : 0)).attr("width", pillWidth).attr("height", LEGEND_HEIGHT3 - (isActive ? capsulePad * 2 : 0)).attr("rx", (LEGEND_HEIGHT3 - (isActive ? capsulePad * 2 : 0)) / 2).attr("fill", pillBg).attr("class", "kanban-legend-group").attr("data-legend-group", group.name.toLowerCase());
6571
+ if (isActive) {
6572
+ svg.append("rect").attr("x", pillX).attr("y", legendY + capsulePad).attr("width", pillWidth).attr("height", LEGEND_HEIGHT3 - capsulePad * 2).attr("rx", (LEGEND_HEIGHT3 - capsulePad * 2) / 2).attr("fill", "none").attr("stroke", mix2(palette.textMuted, palette.bg, 50)).attr("stroke-width", 0.75);
6573
+ }
6574
+ svg.append("text").attr("x", pillX + pillWidth / 2).attr("y", legendY + LEGEND_HEIGHT3 / 2 + LEGEND_FONT_SIZE / 2 - 2).attr("font-size", LEGEND_FONT_SIZE).attr("font-weight", "500").attr("fill", isActive ? palette.text : palette.textMuted).attr("text-anchor", "middle").text(group.name);
6575
+ if (isActive) {
6576
+ let entryX = pillX + pillWidth + 4;
6577
+ for (const entry of group.entries) {
6578
+ svg.append("circle").attr("cx", entryX + LEGEND_DOT_R3).attr("cy", legendY + LEGEND_HEIGHT3 / 2).attr("r", LEGEND_DOT_R3).attr("fill", entry.color);
6579
+ const entryTextX = entryX + LEGEND_DOT_R3 * 2 + 4;
6580
+ svg.append("text").attr("x", entryTextX).attr("y", legendY + LEGEND_HEIGHT3 / 2 + LEGEND_ENTRY_FONT_SIZE2 / 2 - 1).attr("font-size", LEGEND_ENTRY_FONT_SIZE2).attr("fill", palette.textMuted).text(entry.value);
6581
+ entryX = entryTextX + entry.value.length * LEGEND_ENTRY_FONT_SIZE2 * 0.6 + 8;
6582
+ }
6583
+ legendX += capsuleWidth + 12;
6584
+ } else {
6585
+ legendX += pillWidth + 12;
6586
+ }
6587
+ }
6588
+ }
6589
+ const defaultColBg = isDark ? mix2(palette.surface, palette.bg, 50) : mix2(palette.surface, palette.bg, 30);
6590
+ const defaultColHeaderBg = isDark ? mix2(palette.surface, palette.bg, 70) : mix2(palette.surface, palette.bg, 50);
6591
+ const cardBaseBg = isDark ? palette.surface : palette.bg;
6592
+ for (const colLayout of layout.columns) {
6593
+ const col = colLayout.column;
6594
+ const g = svg.append("g").attr("class", "kanban-column").attr("data-column-id", col.id).attr("data-line-number", col.lineNumber);
6595
+ const thisColBg = defaultColBg;
6596
+ const thisColHeaderBg = col.color ? mix2(col.color, palette.bg, 25) : defaultColHeaderBg;
6597
+ g.append("rect").attr("x", colLayout.x).attr("y", colLayout.y).attr("width", colLayout.width).attr("height", colLayout.height).attr("rx", COLUMN_RADIUS).attr("fill", thisColBg);
6598
+ g.append("rect").attr("x", colLayout.x).attr("y", colLayout.y).attr("width", colLayout.width).attr("height", COLUMN_HEADER_HEIGHT).attr("rx", COLUMN_HEADER_RADIUS).attr("fill", thisColHeaderBg);
6599
+ g.append("text").attr("x", colLayout.x + COLUMN_PADDING).attr(
6600
+ "y",
6601
+ colLayout.y + COLUMN_HEADER_HEIGHT / 2 + COLUMN_HEADER_FONT_SIZE / 2 - 2
6602
+ ).attr("font-size", COLUMN_HEADER_FONT_SIZE).attr("font-weight", "bold").attr("fill", palette.text).text(col.name);
6603
+ if (col.wipLimit != null) {
6604
+ const wipExceeded = col.cards.length > col.wipLimit;
6605
+ const badgeText = `${col.cards.length}/${col.wipLimit}`;
6606
+ const nameWidth = col.name.length * COLUMN_HEADER_FONT_SIZE * 0.65;
6607
+ g.append("text").attr("x", colLayout.x + COLUMN_PADDING + nameWidth + 8).attr(
6608
+ "y",
6609
+ colLayout.y + COLUMN_HEADER_HEIGHT / 2 + WIP_FONT_SIZE / 2 - 1
6610
+ ).attr("font-size", WIP_FONT_SIZE).attr("fill", wipExceeded ? palette.colors.red : palette.textMuted).attr("font-weight", wipExceeded ? "bold" : "normal").text(badgeText);
6611
+ }
6612
+ for (const cardLayout of colLayout.cardLayouts) {
6613
+ const card = cardLayout.card;
6614
+ const resolvedColor = resolveCardTagColor(card, parsed.tagGroups, activeTagGroup ?? null);
6615
+ const tagMeta = resolveCardTagMeta(card, parsed.tagGroups);
6616
+ const hasMeta = tagMeta.length > 0 || card.details.length > 0;
6617
+ const cardFill = resolvedColor ? mix2(resolvedColor, cardBaseBg, 15) : mix2(palette.primary, cardBaseBg, 15);
6618
+ const cardStroke = resolvedColor ?? palette.textMuted;
6619
+ const cg = g.append("g").attr("class", "kanban-card").attr("data-card-id", card.id).attr("data-line-number", card.lineNumber);
6620
+ const cx = colLayout.x + cardLayout.x;
6621
+ const cy = colLayout.y + cardLayout.y;
6622
+ cg.append("rect").attr("x", cx).attr("y", cy).attr("width", cardLayout.width).attr("height", cardLayout.height).attr("rx", CARD_RADIUS2).attr("fill", cardFill).attr("stroke", cardStroke).attr("stroke-width", CARD_STROKE_WIDTH);
6623
+ cg.append("text").attr("x", cx + CARD_PADDING_X).attr("y", cy + CARD_PADDING_Y + CARD_TITLE_FONT_SIZE).attr("font-size", CARD_TITLE_FONT_SIZE).attr("font-weight", "500").attr("fill", palette.text).text(card.title);
6624
+ if (hasMeta) {
6625
+ const separatorY = cy + CARD_HEADER_HEIGHT;
6626
+ cg.append("line").attr("x1", cx).attr("y1", separatorY).attr("x2", cx + cardLayout.width).attr("y2", separatorY).attr("stroke", cardStroke).attr("stroke-opacity", 0.3).attr("stroke-width", 1);
6627
+ let metaY = separatorY + CARD_SEPARATOR_GAP + CARD_META_FONT_SIZE;
6628
+ for (const meta of tagMeta) {
6629
+ cg.append("text").attr("x", cx + CARD_PADDING_X).attr("y", metaY).attr("font-size", CARD_META_FONT_SIZE).attr("fill", palette.textMuted).text(`${meta.label}: `);
6630
+ const labelWidth = (meta.label.length + 2) * CARD_META_FONT_SIZE * 0.6;
6631
+ cg.append("text").attr("x", cx + CARD_PADDING_X + labelWidth).attr("y", metaY).attr("font-size", CARD_META_FONT_SIZE).attr("fill", palette.text).text(meta.value);
6632
+ metaY += CARD_META_LINE_HEIGHT;
6633
+ }
6634
+ for (const detail of card.details) {
6635
+ cg.append("text").attr("x", cx + CARD_PADDING_X).attr("y", metaY).attr("font-size", CARD_META_FONT_SIZE).attr("fill", palette.textMuted).text(detail);
6636
+ metaY += CARD_META_LINE_HEIGHT;
6637
+ }
6638
+ }
6639
+ }
6640
+ }
6641
+ }
6642
+ function renderKanbanForExport(content, theme, palette) {
6643
+ const parsed = parseKanban(content, palette);
6644
+ if (parsed.error || parsed.columns.length === 0) return "";
6645
+ const isDark = theme === "dark";
6646
+ const layout = computeLayout(parsed, palette);
6647
+ const container = document.createElement("div");
6648
+ renderKanban(container, parsed, palette, isDark, void 0, {
6649
+ width: layout.totalWidth,
6650
+ height: layout.totalHeight
6651
+ });
6652
+ const svgEl = container.querySelector("svg");
6653
+ return svgEl?.outerHTML ?? "";
6654
+ }
6655
+ var DIAGRAM_PADDING2, COLUMN_GAP, COLUMN_HEADER_HEIGHT, COLUMN_PADDING, COLUMN_MIN_WIDTH, CARD_HEADER_HEIGHT, CARD_META_LINE_HEIGHT, CARD_SEPARATOR_GAP, CARD_GAP, CARD_RADIUS2, CARD_PADDING_X, CARD_PADDING_Y, CARD_STROKE_WIDTH, TITLE_HEIGHT2, TITLE_FONT_SIZE2, COLUMN_HEADER_FONT_SIZE, CARD_TITLE_FONT_SIZE, CARD_META_FONT_SIZE, WIP_FONT_SIZE, COLUMN_RADIUS, COLUMN_HEADER_RADIUS, LEGEND_HEIGHT3, LEGEND_FONT_SIZE, LEGEND_DOT_R3, LEGEND_ENTRY_FONT_SIZE2;
6656
+ var init_renderer2 = __esm({
6657
+ "src/kanban/renderer.ts"() {
6658
+ "use strict";
6659
+ init_fonts();
6660
+ init_parser5();
6661
+ init_mutations();
6662
+ DIAGRAM_PADDING2 = 20;
6663
+ COLUMN_GAP = 16;
6664
+ COLUMN_HEADER_HEIGHT = 36;
6665
+ COLUMN_PADDING = 12;
6666
+ COLUMN_MIN_WIDTH = 200;
6667
+ CARD_HEADER_HEIGHT = 24;
6668
+ CARD_META_LINE_HEIGHT = 14;
6669
+ CARD_SEPARATOR_GAP = 4;
6670
+ CARD_GAP = 8;
6671
+ CARD_RADIUS2 = 6;
6672
+ CARD_PADDING_X = 10;
6673
+ CARD_PADDING_Y = 6;
6674
+ CARD_STROKE_WIDTH = 1.5;
6675
+ TITLE_HEIGHT2 = 30;
6676
+ TITLE_FONT_SIZE2 = 18;
6677
+ COLUMN_HEADER_FONT_SIZE = 13;
6678
+ CARD_TITLE_FONT_SIZE = 12;
6679
+ CARD_META_FONT_SIZE = 10;
6680
+ WIP_FONT_SIZE = 10;
6681
+ COLUMN_RADIUS = 8;
6682
+ COLUMN_HEADER_RADIUS = 8;
6683
+ LEGEND_HEIGHT3 = 28;
6025
6684
  LEGEND_FONT_SIZE = 11;
6026
- LEGEND_MAX_PER_ROW2 = 3;
6027
- LEGEND_CHAR_WIDTH = 7.5;
6028
- EYE_ICON_SIZE = 12;
6029
- EYE_ICON_GAP2 = 6;
6030
- EYE_OPEN_PATH = "M1 6C1 6 3 2 6 2C9 2 11 6 11 6C11 6 9 10 6 10C3 10 1 6 1 6Z";
6031
- EYE_PUPIL_CX = 6;
6032
- EYE_PUPIL_CY = 6;
6033
- EYE_PUPIL_R = 1.8;
6685
+ LEGEND_DOT_R3 = 4;
6686
+ LEGEND_ENTRY_FONT_SIZE2 = 10;
6034
6687
  }
6035
6688
  });
6036
6689
 
@@ -6163,14 +6816,14 @@ var init_layout2 = __esm({
6163
6816
  });
6164
6817
 
6165
6818
  // src/class/renderer.ts
6166
- var renderer_exports2 = {};
6167
- __export(renderer_exports2, {
6819
+ var renderer_exports3 = {};
6820
+ __export(renderer_exports3, {
6168
6821
  renderClassDiagram: () => renderClassDiagram,
6169
6822
  renderClassDiagramForExport: () => renderClassDiagramForExport
6170
6823
  });
6171
- import * as d3Selection2 from "d3-selection";
6824
+ import * as d3Selection3 from "d3-selection";
6172
6825
  import * as d3Shape from "d3-shape";
6173
- function mix2(a, b, pct) {
6826
+ function mix3(a, b, pct) {
6174
6827
  const parse = (h) => {
6175
6828
  const r = h.replace("#", "");
6176
6829
  const f = r.length === 3 ? r[0] + r[0] + r[1] + r[1] + r[2] + r[2] : r;
@@ -6195,7 +6848,7 @@ function modifierColor(modifier, palette, colorOff) {
6195
6848
  }
6196
6849
  function nodeFill2(palette, isDark, modifier, nodeColor, colorOff) {
6197
6850
  const color = nodeColor ?? modifierColor(modifier, palette, colorOff);
6198
- return mix2(color, isDark ? palette.surface : palette.bg, 20);
6851
+ return mix3(color, isDark ? palette.surface : palette.bg, 20);
6199
6852
  }
6200
6853
  function nodeStroke2(palette, modifier, nodeColor, colorOff) {
6201
6854
  return nodeColor ?? modifierColor(modifier, palette, colorOff);
@@ -6233,7 +6886,7 @@ function isSourceMarker(type) {
6233
6886
  return type === "composes" || type === "aggregates";
6234
6887
  }
6235
6888
  function renderClassDiagram(container, parsed, layout, palette, isDark, onClickItem, exportDims) {
6236
- d3Selection2.select(container).selectAll(":not([data-d3-tooltip])").remove();
6889
+ d3Selection3.select(container).selectAll(":not([data-d3-tooltip])").remove();
6237
6890
  const width = exportDims?.width ?? container.clientWidth;
6238
6891
  const height = exportDims?.height ?? container.clientHeight;
6239
6892
  if (width <= 0 || height <= 0) return;
@@ -6241,14 +6894,14 @@ function renderClassDiagram(container, parsed, layout, palette, isDark, onClickI
6241
6894
  const diagramW = layout.width;
6242
6895
  const diagramH = layout.height;
6243
6896
  const availH = height - titleHeight;
6244
- const scaleX = (width - DIAGRAM_PADDING2 * 2) / diagramW;
6245
- const scaleY = (availH - DIAGRAM_PADDING2 * 2) / diagramH;
6897
+ const scaleX = (width - DIAGRAM_PADDING3 * 2) / diagramW;
6898
+ const scaleY = (availH - DIAGRAM_PADDING3 * 2) / diagramH;
6246
6899
  const scale = Math.min(MAX_SCALE2, scaleX, scaleY);
6247
6900
  const scaledW = diagramW * scale;
6248
6901
  const scaledH = diagramH * scale;
6249
6902
  const offsetX = (width - scaledW) / 2;
6250
6903
  const offsetY = titleHeight + (availH - scaledH) / 2;
6251
- const svg = d3Selection2.select(container).append("svg").attr("width", width).attr("height", height).style("font-family", FONT_FAMILY);
6904
+ const svg = d3Selection3.select(container).append("svg").attr("width", width).attr("height", height).style("font-family", FONT_FAMILY);
6252
6905
  const defs = svg.append("defs");
6253
6906
  const AW = 12;
6254
6907
  const AH = 8;
@@ -6266,9 +6919,9 @@ function renderClassDiagram(container, parsed, layout, palette, isDark, onClickI
6266
6919
  titleEl.attr("data-line-number", parsed.titleLineNumber);
6267
6920
  if (onClickItem) {
6268
6921
  titleEl.on("click", () => onClickItem(parsed.titleLineNumber)).on("mouseenter", function() {
6269
- d3Selection2.select(this).attr("opacity", 0.7);
6922
+ d3Selection3.select(this).attr("opacity", 0.7);
6270
6923
  }).on("mouseleave", function() {
6271
- d3Selection2.select(this).attr("opacity", 1);
6924
+ d3Selection3.select(this).attr("opacity", 1);
6272
6925
  });
6273
6926
  }
6274
6927
  }
@@ -6379,8 +7032,8 @@ function renderClassDiagramForExport(content, theme, palette) {
6379
7032
  const layout = layoutClassDiagram(parsed);
6380
7033
  const isDark = theme === "dark";
6381
7034
  const container = document.createElement("div");
6382
- const exportWidth = layout.width + DIAGRAM_PADDING2 * 2;
6383
- const exportHeight = layout.height + DIAGRAM_PADDING2 * 2 + (parsed.title ? 40 : 0);
7035
+ const exportWidth = layout.width + DIAGRAM_PADDING3 * 2;
7036
+ const exportHeight = layout.height + DIAGRAM_PADDING3 * 2 + (parsed.title ? 40 : 0);
6384
7037
  container.style.width = `${exportWidth}px`;
6385
7038
  container.style.height = `${exportHeight}px`;
6386
7039
  container.style.position = "absolute";
@@ -6408,14 +7061,14 @@ function renderClassDiagramForExport(content, theme, palette) {
6408
7061
  document.body.removeChild(container);
6409
7062
  }
6410
7063
  }
6411
- var DIAGRAM_PADDING2, MAX_SCALE2, CLASS_FONT_SIZE, MEMBER_FONT_SIZE, EDGE_LABEL_FONT_SIZE, EDGE_STROKE_WIDTH2, NODE_STROKE_WIDTH2, MEMBER_LINE_HEIGHT2, COMPARTMENT_PADDING_Y2, MEMBER_PADDING_X, lineGenerator;
6412
- var init_renderer2 = __esm({
7064
+ var DIAGRAM_PADDING3, MAX_SCALE2, CLASS_FONT_SIZE, MEMBER_FONT_SIZE, EDGE_LABEL_FONT_SIZE, EDGE_STROKE_WIDTH2, NODE_STROKE_WIDTH2, MEMBER_LINE_HEIGHT2, COMPARTMENT_PADDING_Y2, MEMBER_PADDING_X, lineGenerator;
7065
+ var init_renderer3 = __esm({
6413
7066
  "src/class/renderer.ts"() {
6414
7067
  "use strict";
6415
7068
  init_fonts();
6416
7069
  init_parser2();
6417
7070
  init_layout2();
6418
- DIAGRAM_PADDING2 = 20;
7071
+ DIAGRAM_PADDING3 = 20;
6419
7072
  MAX_SCALE2 = 3;
6420
7073
  CLASS_FONT_SIZE = 13;
6421
7074
  MEMBER_FONT_SIZE = 11;
@@ -6570,14 +7223,14 @@ var init_layout3 = __esm({
6570
7223
  });
6571
7224
 
6572
7225
  // src/er/renderer.ts
6573
- var renderer_exports3 = {};
6574
- __export(renderer_exports3, {
7226
+ var renderer_exports4 = {};
7227
+ __export(renderer_exports4, {
6575
7228
  renderERDiagram: () => renderERDiagram,
6576
7229
  renderERDiagramForExport: () => renderERDiagramForExport
6577
7230
  });
6578
- import * as d3Selection3 from "d3-selection";
7231
+ import * as d3Selection4 from "d3-selection";
6579
7232
  import * as d3Shape2 from "d3-shape";
6580
- function mix3(a, b, pct) {
7233
+ function mix4(a, b, pct) {
6581
7234
  const parse = (h) => {
6582
7235
  const r = h.replace("#", "");
6583
7236
  const f = r.length === 3 ? r[0] + r[0] + r[1] + r[1] + r[2] + r[2] : r;
@@ -6648,7 +7301,7 @@ function drawCardinality(g, point, prevPoint, cardinality, color, useLabels) {
6648
7301
  }
6649
7302
  }
6650
7303
  function renderERDiagram(container, parsed, layout, palette, isDark, onClickItem, exportDims) {
6651
- d3Selection3.select(container).selectAll(":not([data-d3-tooltip])").remove();
7304
+ d3Selection4.select(container).selectAll(":not([data-d3-tooltip])").remove();
6652
7305
  const width = exportDims?.width ?? container.clientWidth;
6653
7306
  const height = exportDims?.height ?? container.clientHeight;
6654
7307
  if (width <= 0 || height <= 0) return;
@@ -6656,23 +7309,23 @@ function renderERDiagram(container, parsed, layout, palette, isDark, onClickItem
6656
7309
  const diagramW = layout.width;
6657
7310
  const diagramH = layout.height;
6658
7311
  const availH = height - titleHeight;
6659
- const scaleX = (width - DIAGRAM_PADDING3 * 2) / diagramW;
6660
- const scaleY = (availH - DIAGRAM_PADDING3 * 2) / diagramH;
7312
+ const scaleX = (width - DIAGRAM_PADDING4 * 2) / diagramW;
7313
+ const scaleY = (availH - DIAGRAM_PADDING4 * 2) / diagramH;
6661
7314
  const scale = Math.min(MAX_SCALE3, scaleX, scaleY);
6662
7315
  const scaledW = diagramW * scale;
6663
7316
  const scaledH = diagramH * scale;
6664
7317
  const offsetX = (width - scaledW) / 2;
6665
7318
  const offsetY = titleHeight + (availH - scaledH) / 2;
6666
- const svg = d3Selection3.select(container).append("svg").attr("width", width).attr("height", height).style("font-family", FONT_FAMILY);
7319
+ const svg = d3Selection4.select(container).append("svg").attr("width", width).attr("height", height).style("font-family", FONT_FAMILY);
6667
7320
  if (parsed.title) {
6668
7321
  const titleEl = svg.append("text").attr("class", "chart-title").attr("x", width / 2).attr("y", 30).attr("text-anchor", "middle").attr("fill", palette.text).attr("font-size", "20px").attr("font-weight", "700").style("cursor", onClickItem && parsed.titleLineNumber ? "pointer" : "default").text(parsed.title);
6669
7322
  if (parsed.titleLineNumber) {
6670
7323
  titleEl.attr("data-line-number", parsed.titleLineNumber);
6671
7324
  if (onClickItem) {
6672
7325
  titleEl.on("click", () => onClickItem(parsed.titleLineNumber)).on("mouseenter", function() {
6673
- d3Selection3.select(this).attr("opacity", 0.7);
7326
+ d3Selection4.select(this).attr("opacity", 0.7);
6674
7327
  }).on("mouseleave", function() {
6675
- d3Selection3.select(this).attr("opacity", 1);
7328
+ d3Selection4.select(this).attr("opacity", 1);
6676
7329
  });
6677
7330
  }
6678
7331
  }
@@ -6726,7 +7379,7 @@ function renderERDiagram(container, parsed, layout, palette, isDark, onClickItem
6726
7379
  }
6727
7380
  const w = node.width;
6728
7381
  const h = node.height;
6729
- const fill2 = mix3(nodeColor, isDark ? palette.surface : palette.bg, 20);
7382
+ const fill2 = mix4(nodeColor, isDark ? palette.surface : palette.bg, 20);
6730
7383
  const stroke2 = nodeColor;
6731
7384
  nodeG.append("rect").attr("x", -w / 2).attr("y", -h / 2).attr("width", w).attr("height", h).attr("rx", 3).attr("ry", 3).attr("fill", fill2).attr("stroke", stroke2).attr("stroke-width", NODE_STROKE_WIDTH3);
6732
7385
  let yPos = -h / 2;
@@ -6757,8 +7410,8 @@ function renderERDiagramForExport(content, theme, palette) {
6757
7410
  const layout = layoutERDiagram(parsed);
6758
7411
  const isDark = theme === "dark";
6759
7412
  const container = document.createElement("div");
6760
- const exportWidth = layout.width + DIAGRAM_PADDING3 * 2;
6761
- const exportHeight = layout.height + DIAGRAM_PADDING3 * 2 + (parsed.title ? 40 : 0);
7413
+ const exportWidth = layout.width + DIAGRAM_PADDING4 * 2;
7414
+ const exportHeight = layout.height + DIAGRAM_PADDING4 * 2 + (parsed.title ? 40 : 0);
6762
7415
  container.style.width = `${exportWidth}px`;
6763
7416
  container.style.height = `${exportHeight}px`;
6764
7417
  container.style.position = "absolute";
@@ -6786,15 +7439,15 @@ function renderERDiagramForExport(content, theme, palette) {
6786
7439
  document.body.removeChild(container);
6787
7440
  }
6788
7441
  }
6789
- var DIAGRAM_PADDING3, MAX_SCALE3, TABLE_FONT_SIZE, COLUMN_FONT_SIZE, EDGE_LABEL_FONT_SIZE2, EDGE_STROKE_WIDTH3, NODE_STROKE_WIDTH3, MEMBER_LINE_HEIGHT4, COMPARTMENT_PADDING_Y4, MEMBER_PADDING_X2, lineGenerator2;
6790
- var init_renderer3 = __esm({
7442
+ var DIAGRAM_PADDING4, MAX_SCALE3, TABLE_FONT_SIZE, COLUMN_FONT_SIZE, EDGE_LABEL_FONT_SIZE2, EDGE_STROKE_WIDTH3, NODE_STROKE_WIDTH3, MEMBER_LINE_HEIGHT4, COMPARTMENT_PADDING_Y4, MEMBER_PADDING_X2, lineGenerator2;
7443
+ var init_renderer4 = __esm({
6791
7444
  "src/er/renderer.ts"() {
6792
7445
  "use strict";
6793
7446
  init_fonts();
6794
7447
  init_palettes();
6795
7448
  init_parser3();
6796
7449
  init_layout3();
6797
- DIAGRAM_PADDING3 = 20;
7450
+ DIAGRAM_PADDING4 = 20;
6798
7451
  MAX_SCALE3 = 3;
6799
7452
  TABLE_FONT_SIZE = 13;
6800
7453
  COLUMN_FONT_SIZE = 11;
@@ -6969,9 +7622,9 @@ __export(flowchart_renderer_exports, {
6969
7622
  renderFlowchart: () => renderFlowchart,
6970
7623
  renderFlowchartForExport: () => renderFlowchartForExport
6971
7624
  });
6972
- import * as d3Selection4 from "d3-selection";
7625
+ import * as d3Selection5 from "d3-selection";
6973
7626
  import * as d3Shape3 from "d3-shape";
6974
- function mix4(a, b, pct) {
7627
+ function mix5(a, b, pct) {
6975
7628
  const parse = (h) => {
6976
7629
  const r = h.replace("#", "");
6977
7630
  const f = r.length === 3 ? r[0] + r[0] + r[1] + r[1] + r[2] + r[2] : r;
@@ -7000,7 +7653,7 @@ function shapeDefaultColor(shape, palette, isEndTerminal, colorOff) {
7000
7653
  }
7001
7654
  function nodeFill3(palette, isDark, shape, nodeColor, isEndTerminal, colorOff) {
7002
7655
  const color = nodeColor ?? shapeDefaultColor(shape, palette, isEndTerminal, colorOff);
7003
- return mix4(color, isDark ? palette.surface : palette.bg, 25);
7656
+ return mix5(color, isDark ? palette.surface : palette.bg, 25);
7004
7657
  }
7005
7658
  function nodeStroke3(palette, shape, nodeColor, isEndTerminal, colorOff) {
7006
7659
  return nodeColor ?? shapeDefaultColor(shape, palette, isEndTerminal, colorOff);
@@ -7095,7 +7748,7 @@ function renderNodeShape(g, node, palette, isDark, endTerminalIds, colorOff) {
7095
7748
  }
7096
7749
  }
7097
7750
  function renderFlowchart(container, graph, layout, palette, isDark, onClickItem, exportDims) {
7098
- d3Selection4.select(container).selectAll(":not([data-d3-tooltip])").remove();
7751
+ d3Selection5.select(container).selectAll(":not([data-d3-tooltip])").remove();
7099
7752
  const width = exportDims?.width ?? container.clientWidth;
7100
7753
  const height = exportDims?.height ?? container.clientHeight;
7101
7754
  if (width <= 0 || height <= 0) return;
@@ -7103,14 +7756,14 @@ function renderFlowchart(container, graph, layout, palette, isDark, onClickItem,
7103
7756
  const diagramW = layout.width;
7104
7757
  const diagramH = layout.height;
7105
7758
  const availH = height - titleHeight;
7106
- const scaleX = (width - DIAGRAM_PADDING4 * 2) / diagramW;
7107
- const scaleY = (availH - DIAGRAM_PADDING4 * 2) / diagramH;
7759
+ const scaleX = (width - DIAGRAM_PADDING5 * 2) / diagramW;
7760
+ const scaleY = (availH - DIAGRAM_PADDING5 * 2) / diagramH;
7108
7761
  const scale = Math.min(MAX_SCALE4, scaleX, scaleY);
7109
7762
  const scaledW = diagramW * scale;
7110
7763
  const scaledH = diagramH * scale;
7111
7764
  const offsetX = (width - scaledW) / 2;
7112
7765
  const offsetY = titleHeight + (availH - scaledH) / 2;
7113
- const svg = d3Selection4.select(container).append("svg").attr("width", width).attr("height", height).style("font-family", FONT_FAMILY);
7766
+ const svg = d3Selection5.select(container).append("svg").attr("width", width).attr("height", height).style("font-family", FONT_FAMILY);
7114
7767
  const defs = svg.append("defs");
7115
7768
  defs.append("marker").attr("id", "fc-arrow").attr("viewBox", `0 0 ${ARROWHEAD_W} ${ARROWHEAD_H}`).attr("refX", ARROWHEAD_W).attr("refY", ARROWHEAD_H / 2).attr("markerWidth", ARROWHEAD_W).attr("markerHeight", ARROWHEAD_H).attr("orient", "auto").append("polygon").attr("points", `0,0 ${ARROWHEAD_W},${ARROWHEAD_H / 2} 0,${ARROWHEAD_H}`).attr("fill", palette.textMuted);
7116
7769
  const edgeColors = /* @__PURE__ */ new Set();
@@ -7127,9 +7780,9 @@ function renderFlowchart(container, graph, layout, palette, isDark, onClickItem,
7127
7780
  titleEl.attr("data-line-number", graph.titleLineNumber);
7128
7781
  if (onClickItem) {
7129
7782
  titleEl.on("click", () => onClickItem(graph.titleLineNumber)).on("mouseenter", function() {
7130
- d3Selection4.select(this).attr("opacity", 0.7);
7783
+ d3Selection5.select(this).attr("opacity", 0.7);
7131
7784
  }).on("mouseleave", function() {
7132
- d3Selection4.select(this).attr("opacity", 1);
7785
+ d3Selection5.select(this).attr("opacity", 1);
7133
7786
  });
7134
7787
  }
7135
7788
  }
@@ -7141,7 +7794,7 @@ function renderFlowchart(container, graph, layout, palette, isDark, onClickItem,
7141
7794
  const gy = group.y - GROUP_EXTRA_PADDING - GROUP_LABEL_FONT_SIZE - 4;
7142
7795
  const gw = group.width + GROUP_EXTRA_PADDING * 2;
7143
7796
  const gh = group.height + GROUP_EXTRA_PADDING * 2 + GROUP_LABEL_FONT_SIZE + 4;
7144
- const fillColor = group.color ? mix4(group.color, isDark ? palette.surface : palette.bg, 10) : isDark ? palette.surface : mix4(palette.border, palette.bg, 30);
7797
+ const fillColor = group.color ? mix5(group.color, isDark ? palette.surface : palette.bg, 10) : isDark ? palette.surface : mix5(palette.border, palette.bg, 30);
7145
7798
  const strokeColor = group.color ?? palette.textMuted;
7146
7799
  contentG.append("rect").attr("x", gx).attr("y", gy).attr("width", gw).attr("height", gh).attr("rx", 6).attr("fill", fillColor).attr("stroke", strokeColor).attr("stroke-width", 1).attr("stroke-opacity", 0.5).attr("class", "fc-group");
7147
7800
  contentG.append("text").attr("x", gx + 8).attr("y", gy + GROUP_LABEL_FONT_SIZE + 4).attr("fill", strokeColor).attr("font-size", GROUP_LABEL_FONT_SIZE).attr("font-weight", "bold").attr("opacity", 0.7).attr("class", "fc-group-label").text(group.label);
@@ -7191,13 +7844,13 @@ function renderFlowchartForExport(content, theme, palette) {
7191
7844
  const layout = layoutGraph(parsed);
7192
7845
  const isDark = theme === "dark";
7193
7846
  const container = document.createElement("div");
7194
- container.style.width = `${layout.width + DIAGRAM_PADDING4 * 2}px`;
7195
- container.style.height = `${layout.height + DIAGRAM_PADDING4 * 2 + (parsed.title ? 40 : 0)}px`;
7847
+ container.style.width = `${layout.width + DIAGRAM_PADDING5 * 2}px`;
7848
+ container.style.height = `${layout.height + DIAGRAM_PADDING5 * 2 + (parsed.title ? 40 : 0)}px`;
7196
7849
  container.style.position = "absolute";
7197
7850
  container.style.left = "-9999px";
7198
7851
  document.body.appendChild(container);
7199
- const exportWidth = layout.width + DIAGRAM_PADDING4 * 2;
7200
- const exportHeight = layout.height + DIAGRAM_PADDING4 * 2 + (parsed.title ? 40 : 0);
7852
+ const exportWidth = layout.width + DIAGRAM_PADDING5 * 2;
7853
+ const exportHeight = layout.height + DIAGRAM_PADDING5 * 2 + (parsed.title ? 40 : 0);
7201
7854
  try {
7202
7855
  renderFlowchart(
7203
7856
  container,
@@ -7220,14 +7873,14 @@ function renderFlowchartForExport(content, theme, palette) {
7220
7873
  document.body.removeChild(container);
7221
7874
  }
7222
7875
  }
7223
- var DIAGRAM_PADDING4, MAX_SCALE4, NODE_FONT_SIZE, EDGE_LABEL_FONT_SIZE3, GROUP_LABEL_FONT_SIZE, EDGE_STROKE_WIDTH4, NODE_STROKE_WIDTH4, ARROWHEAD_W, ARROWHEAD_H, IO_SKEW, SUBROUTINE_INSET, DOC_WAVE_HEIGHT, GROUP_EXTRA_PADDING, lineGenerator3;
7876
+ var DIAGRAM_PADDING5, MAX_SCALE4, NODE_FONT_SIZE, EDGE_LABEL_FONT_SIZE3, GROUP_LABEL_FONT_SIZE, EDGE_STROKE_WIDTH4, NODE_STROKE_WIDTH4, ARROWHEAD_W, ARROWHEAD_H, IO_SKEW, SUBROUTINE_INSET, DOC_WAVE_HEIGHT, GROUP_EXTRA_PADDING, lineGenerator3;
7224
7877
  var init_flowchart_renderer = __esm({
7225
7878
  "src/graph/flowchart-renderer.ts"() {
7226
7879
  "use strict";
7227
7880
  init_fonts();
7228
7881
  init_flowchart_parser();
7229
7882
  init_layout4();
7230
- DIAGRAM_PADDING4 = 20;
7883
+ DIAGRAM_PADDING5 = 20;
7231
7884
  MAX_SCALE4 = 3;
7232
7885
  NODE_FONT_SIZE = 13;
7233
7886
  EDGE_LABEL_FONT_SIZE3 = 11;
@@ -7245,8 +7898,8 @@ var init_flowchart_renderer = __esm({
7245
7898
  });
7246
7899
 
7247
7900
  // src/sequence/renderer.ts
7248
- var renderer_exports4 = {};
7249
- __export(renderer_exports4, {
7901
+ var renderer_exports5 = {};
7902
+ __export(renderer_exports5, {
7250
7903
  applyGroupOrdering: () => applyGroupOrdering,
7251
7904
  applyPositionOverrides: () => applyPositionOverrides,
7252
7905
  buildNoteMessageMap: () => buildNoteMessageMap,
@@ -7257,7 +7910,7 @@ __export(renderer_exports4, {
7257
7910
  renderSequenceDiagram: () => renderSequenceDiagram,
7258
7911
  truncateBareUrl: () => truncateBareUrl
7259
7912
  });
7260
- import * as d3Selection5 from "d3-selection";
7913
+ import * as d3Selection6 from "d3-selection";
7261
7914
  function parseInlineMarkdown(text) {
7262
7915
  const spans = [];
7263
7916
  const regex = /\*\*(.+?)\*\*|__(.+?)__|\*(.+?)\*|_(.+?)_|`(.+?)`|\[(.+?)\]\((.+?)\)|(https?:\/\/[^\s)>\]]+|www\.[^\s)>\]]+)|([^*_`[]+?(?=https?:\/\/|www\.|$)|[^*_`[]+)/g;
@@ -7323,7 +7976,7 @@ function wrapTextLines(text, maxChars) {
7323
7976
  }
7324
7977
  return wrapped;
7325
7978
  }
7326
- function mix5(a, b, pct) {
7979
+ function mix6(a, b, pct) {
7327
7980
  const parse = (h) => {
7328
7981
  const r = h.replace("#", "");
7329
7982
  const f = r.length === 3 ? r[0] + r[0] + r[1] + r[1] + r[2] + r[2] : r;
@@ -7607,7 +8260,7 @@ function applyGroupOrdering(participants, groups) {
7607
8260
  return result;
7608
8261
  }
7609
8262
  function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateToLine, options) {
7610
- d3Selection5.select(container).selectAll("*").remove();
8263
+ d3Selection6.select(container).selectAll("*").remove();
7611
8264
  const { title, messages, elements, groups, options: parsedOptions } = parsed;
7612
8265
  const collapsedSections = options?.collapsedSections;
7613
8266
  const expandedNoteLines = options?.expandedNoteLines;
@@ -7647,7 +8300,7 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
7647
8300
  }
7648
8301
  msgToLastStep.set(step.messageIndex, si);
7649
8302
  });
7650
- const findAssociatedFirstStep = (note) => {
8303
+ const findAssociatedLastStep = (note) => {
7651
8304
  let closestMsgIndex = -1;
7652
8305
  let closestLine = -1;
7653
8306
  for (let mi = 0; mi < messages.length; mi++) {
@@ -7660,7 +8313,7 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
7660
8313
  return -1;
7661
8314
  }
7662
8315
  if (closestMsgIndex < 0) return -1;
7663
- return msgToFirstStep.get(closestMsgIndex) ?? -1;
8316
+ return msgToLastStep.get(closestMsgIndex) ?? -1;
7664
8317
  };
7665
8318
  const findFirstMsgIndex = (els) => {
7666
8319
  for (const el of els) {
@@ -7867,7 +8520,7 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
7867
8520
  const GROUP_PADDING_TOP = 22;
7868
8521
  const GROUP_PADDING_BOTTOM = 8;
7869
8522
  const GROUP_LABEL_SIZE = 11;
7870
- const titleOffset = title ? TITLE_HEIGHT2 : 0;
8523
+ const titleOffset = title ? TITLE_HEIGHT3 : 0;
7871
8524
  const groupOffset = groups.length > 0 ? GROUP_PADDING_TOP + GROUP_LABEL_SIZE : 0;
7872
8525
  const participantStartY = TOP_MARGIN + titleOffset + PARTICIPANT_Y_OFFSET + groupOffset;
7873
8526
  const lifelineStartY0 = participantStartY + PARTICIPANT_BOX_HEIGHT;
@@ -7910,7 +8563,7 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
7910
8563
  for (let i = 0; i < els.length; i++) {
7911
8564
  const el = els[i];
7912
8565
  if (isSequenceNote(el)) {
7913
- const si = findAssociatedFirstStep(el);
8566
+ const si = findAssociatedLastStep(el);
7914
8567
  if (si < 0) continue;
7915
8568
  const prevNote = i > 0 && isSequenceNote(els[i - 1]) ? els[i - 1] : null;
7916
8569
  const prevNoteY = prevNote ? noteYMap.get(prevNote) : void 0;
@@ -7960,7 +8613,7 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
7960
8613
  participants.forEach((p, i) => {
7961
8614
  participantX.set(p.id, offsetX + i * PARTICIPANT_GAP);
7962
8615
  });
7963
- const svg = d3Selection5.select(container).append("svg").attr("width", "100%").attr("height", totalHeight).attr("viewBox", `0 0 ${svgWidth} ${totalHeight}`).attr("preserveAspectRatio", "xMidYMin meet").attr("class", "sequence-diagram").style("font-family", FONT_FAMILY);
8616
+ const svg = d3Selection6.select(container).append("svg").attr("width", "100%").attr("height", totalHeight).attr("viewBox", `0 0 ${svgWidth} ${totalHeight}`).attr("preserveAspectRatio", "xMidYMin meet").attr("class", "sequence-diagram").style("font-family", FONT_FAMILY);
7964
8617
  const defs = svg.append("defs");
7965
8618
  defs.append("marker").attr("id", "seq-arrowhead").attr("viewBox", `0 0 ${ARROWHEAD_SIZE} ${ARROWHEAD_SIZE}`).attr("refX", ARROWHEAD_SIZE).attr("refY", ARROWHEAD_SIZE / 2).attr("markerWidth", ARROWHEAD_SIZE).attr("markerHeight", ARROWHEAD_SIZE).attr("orient", "auto").append("polygon").attr(
7966
8619
  "points",
@@ -7989,7 +8642,7 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
7989
8642
  const boxY = participantStartY - GROUP_PADDING_TOP;
7990
8643
  const boxH = PARTICIPANT_BOX_HEIGHT + GROUP_PADDING_TOP + GROUP_PADDING_BOTTOM;
7991
8644
  const resolvedGroupColor = group.color ? resolveColor(group.color, palette) : void 0;
7992
- const fillColor = resolvedGroupColor ? mix5(resolvedGroupColor, isDark ? palette.surface : palette.bg, 10) : isDark ? palette.surface : palette.bg;
8645
+ const fillColor = resolvedGroupColor ? mix6(resolvedGroupColor, isDark ? palette.surface : palette.bg, 10) : isDark ? palette.surface : palette.bg;
7993
8646
  const strokeColor = resolvedGroupColor || palette.textMuted;
7994
8647
  svg.append("rect").attr("x", minX).attr("y", boxY).attr("width", maxX - minX).attr("height", boxH).attr("rx", 6).attr("fill", fillColor).attr("stroke", strokeColor).attr("stroke-width", 1).attr("stroke-opacity", 0.5).attr("class", "group-box").attr("data-group-line", String(group.lineNumber));
7995
8648
  svg.append("text").attr("x", minX + 8).attr("y", boxY + GROUP_LABEL_SIZE + 4).attr("fill", strokeColor).attr("font-size", GROUP_LABEL_SIZE).attr("font-weight", "bold").attr("opacity", 0.7).attr("class", "group-label").attr("data-group-line", String(group.lineNumber)).text(group.name);
@@ -8159,7 +8812,7 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
8159
8812
  if (msg) coveredLines.push(msg.lineNumber);
8160
8813
  }
8161
8814
  svg.append("rect").attr("x", x).attr("y", y1).attr("width", ACTIVATION_WIDTH).attr("height", y2 - y1).attr("fill", isDark ? palette.surface : palette.bg);
8162
- const actFill = mix5(palette.primary, isDark ? palette.surface : palette.bg, isDark ? 15 : 30);
8815
+ const actFill = mix6(palette.primary, isDark ? palette.surface : palette.bg, isDark ? 15 : 30);
8163
8816
  svg.append("rect").attr("x", x).attr("y", y1).attr("width", ACTIVATION_WIDTH).attr("height", y2 - y1).attr("fill", actFill).attr("stroke", palette.primary).attr("stroke-width", 1).attr("stroke-opacity", 0.5).attr("data-participant-id", act.participantId).attr("data-msg-lines", coveredLines.join(",")).attr("data-line-number", coveredLines[0] ?? "").attr("class", "activation");
8164
8817
  });
8165
8818
  for (const ln of deferredLines) {
@@ -8288,8 +8941,8 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
8288
8941
  }
8289
8942
  }
8290
8943
  });
8291
- const noteFill = isDark ? mix5(palette.surface, palette.bg, 50) : mix5(palette.bg, palette.surface, 15);
8292
- const collapsedNoteFill = mix5(palette.textMuted, palette.bg, 15);
8944
+ const noteFill = isDark ? mix6(palette.surface, palette.bg, 50) : mix6(palette.bg, palette.surface, 15);
8945
+ const collapsedNoteFill = mix6(palette.textMuted, palette.bg, 15);
8293
8946
  const renderNoteElements = (els) => {
8294
8947
  for (const el of els) {
8295
8948
  if (isSequenceNote(el)) {
@@ -8445,8 +9098,8 @@ function renderParticipant(svg, participant, cx, cy, palette, isDark) {
8445
9098
  isActor ? PARTICIPANT_BOX_HEIGHT + 14 : PARTICIPANT_BOX_HEIGHT / 2 + 5
8446
9099
  ).attr("text-anchor", "middle").attr("fill", palette.text).attr("font-size", 13).attr("font-weight", 500).text(participant.label);
8447
9100
  }
8448
- var PARTICIPANT_GAP, PARTICIPANT_BOX_WIDTH, PARTICIPANT_BOX_HEIGHT, TOP_MARGIN, TITLE_HEIGHT2, PARTICIPANT_Y_OFFSET, SERVICE_BORDER_RADIUS, MESSAGE_START_OFFSET, LIFELINE_TAIL, ARROWHEAD_SIZE, NOTE_MAX_W, NOTE_FOLD, NOTE_PAD_H, NOTE_PAD_V, NOTE_FONT_SIZE, NOTE_LINE_H, NOTE_GAP, NOTE_CHAR_W, NOTE_CHARS_PER_LINE, COLLAPSED_NOTE_H, COLLAPSED_NOTE_W, BARE_URL_MAX_DISPLAY, fill, stroke, SW, W, H;
8449
- var init_renderer4 = __esm({
9101
+ var PARTICIPANT_GAP, PARTICIPANT_BOX_WIDTH, PARTICIPANT_BOX_HEIGHT, TOP_MARGIN, TITLE_HEIGHT3, PARTICIPANT_Y_OFFSET, SERVICE_BORDER_RADIUS, MESSAGE_START_OFFSET, LIFELINE_TAIL, ARROWHEAD_SIZE, NOTE_MAX_W, NOTE_FOLD, NOTE_PAD_H, NOTE_PAD_V, NOTE_FONT_SIZE, NOTE_LINE_H, NOTE_GAP, NOTE_CHAR_W, NOTE_CHARS_PER_LINE, COLLAPSED_NOTE_H, COLLAPSED_NOTE_W, BARE_URL_MAX_DISPLAY, fill, stroke, SW, W, H;
9102
+ var init_renderer5 = __esm({
8450
9103
  "src/sequence/renderer.ts"() {
8451
9104
  "use strict";
8452
9105
  init_colors();
@@ -8456,7 +9109,7 @@ var init_renderer4 = __esm({
8456
9109
  PARTICIPANT_BOX_WIDTH = 120;
8457
9110
  PARTICIPANT_BOX_HEIGHT = 50;
8458
9111
  TOP_MARGIN = 20;
8459
- TITLE_HEIGHT2 = 30;
9112
+ TITLE_HEIGHT3 = 30;
8460
9113
  PARTICIPANT_Y_OFFSET = 10;
8461
9114
  SERVICE_BORDER_RADIUS = 10;
8462
9115
  MESSAGE_START_OFFSET = 30;
@@ -8474,7 +9127,7 @@ var init_renderer4 = __esm({
8474
9127
  COLLAPSED_NOTE_H = 20;
8475
9128
  COLLAPSED_NOTE_W = 40;
8476
9129
  BARE_URL_MAX_DISPLAY = 35;
8477
- fill = (palette, isDark) => mix5(palette.primary, isDark ? palette.surface : palette.bg, isDark ? 15 : 30);
9130
+ fill = (palette, isDark) => mix6(palette.primary, isDark ? palette.surface : palette.bg, isDark ? 15 : 30);
8478
9131
  stroke = (palette) => palette.textMuted;
8479
9132
  SW = 1.5;
8480
9133
  W = PARTICIPANT_BOX_WIDTH;
@@ -8484,7 +9137,7 @@ var init_renderer4 = __esm({
8484
9137
 
8485
9138
  // src/d3.ts
8486
9139
  import * as d3Scale from "d3-scale";
8487
- import * as d3Selection6 from "d3-selection";
9140
+ import * as d3Selection7 from "d3-selection";
8488
9141
  import * as d3Shape4 from "d3-shape";
8489
9142
  import * as d3Array from "d3-array";
8490
9143
  import cloud from "d3-cloud";
@@ -9035,7 +9688,7 @@ function tokenizeFreeformText(text) {
9035
9688
  return Array.from(counts.entries()).map(([text2, count]) => ({ text: text2, weight: count, lineNumber: 0 })).sort((a, b) => b.weight - a.weight);
9036
9689
  }
9037
9690
  function renderSlopeChart(container, parsed, palette, isDark, onClickItem, exportDims) {
9038
- d3Selection6.select(container).selectAll(":not([data-d3-tooltip])").remove();
9691
+ d3Selection7.select(container).selectAll(":not([data-d3-tooltip])").remove();
9039
9692
  const { periods, data, title } = parsed;
9040
9693
  if (data.length === 0 || periods.length < 2) return;
9041
9694
  const width = exportDims?.width ?? container.clientWidth;
@@ -9062,7 +9715,7 @@ function renderSlopeChart(container, parsed, palette, isDark, onClickItem, expor
9062
9715
  const valuePadding = (maxVal - minVal) * 0.1 || 1;
9063
9716
  const yScale = d3Scale.scaleLinear().domain([minVal - valuePadding, maxVal + valuePadding]).range([innerHeight, 0]);
9064
9717
  const xScale = d3Scale.scalePoint().domain(periods).range([0, innerWidth]).padding(0);
9065
- const svg = d3Selection6.select(container).append("svg").attr("width", width).attr("height", height).style("background", bgColor);
9718
+ const svg = d3Selection7.select(container).append("svg").attr("width", width).attr("height", height).style("background", bgColor);
9066
9719
  const g = svg.append("g").attr("transform", `translate(${SLOPE_MARGIN.left},${SLOPE_MARGIN.top})`);
9067
9720
  const tooltip = createTooltip(container, palette, isDark);
9068
9721
  if (title) {
@@ -9071,9 +9724,9 @@ function renderSlopeChart(container, parsed, palette, isDark, onClickItem, expor
9071
9724
  titleEl.attr("data-line-number", parsed.titleLineNumber);
9072
9725
  if (onClickItem) {
9073
9726
  titleEl.on("click", () => onClickItem(parsed.titleLineNumber)).on("mouseenter", function() {
9074
- d3Selection6.select(this).attr("opacity", 0.7);
9727
+ d3Selection7.select(this).attr("opacity", 0.7);
9075
9728
  }).on("mouseleave", function() {
9076
- d3Selection6.select(this).attr("opacity", 1);
9729
+ d3Selection7.select(this).attr("opacity", 1);
9077
9730
  });
9078
9731
  }
9079
9732
  }
@@ -9247,7 +9900,7 @@ function orderArcNodes(links, order, groups) {
9247
9900
  return allNodes;
9248
9901
  }
9249
9902
  function renderArcDiagram(container, parsed, palette, _isDark, onClickItem, exportDims) {
9250
- d3Selection6.select(container).selectAll(":not([data-d3-tooltip])").remove();
9903
+ d3Selection7.select(container).selectAll(":not([data-d3-tooltip])").remove();
9251
9904
  const { links, title, orientation, arcOrder, arcNodeGroups } = parsed;
9252
9905
  if (links.length === 0) return;
9253
9906
  const width = exportDims?.width ?? container.clientWidth;
@@ -9284,7 +9937,7 @@ function renderArcDiagram(container, parsed, palette, _isDark, onClickItem, expo
9284
9937
  const values = links.map((l) => l.value);
9285
9938
  const [minVal, maxVal] = d3Array.extent(values);
9286
9939
  const strokeScale = d3Scale.scaleLinear().domain([minVal, maxVal]).range([1.5, 6]);
9287
- const svg = d3Selection6.select(container).append("svg").attr("width", width).attr("height", height).style("background", bgColor);
9940
+ const svg = d3Selection7.select(container).append("svg").attr("width", width).attr("height", height).style("background", bgColor);
9288
9941
  const g = svg.append("g").attr("transform", `translate(${margin.left},${margin.top})`);
9289
9942
  if (title) {
9290
9943
  const titleEl = svg.append("text").attr("class", "chart-title").attr("x", width / 2).attr("y", 30).attr("text-anchor", "middle").attr("fill", textColor).attr("font-size", "20px").attr("font-weight", "700").style("cursor", onClickItem && parsed.titleLineNumber ? "pointer" : "default").text(title);
@@ -9292,9 +9945,9 @@ function renderArcDiagram(container, parsed, palette, _isDark, onClickItem, expo
9292
9945
  titleEl.attr("data-line-number", parsed.titleLineNumber);
9293
9946
  if (onClickItem) {
9294
9947
  titleEl.on("click", () => onClickItem(parsed.titleLineNumber)).on("mouseenter", function() {
9295
- d3Selection6.select(this).attr("opacity", 0.7);
9948
+ d3Selection7.select(this).attr("opacity", 0.7);
9296
9949
  }).on("mouseleave", function() {
9297
- d3Selection6.select(this).attr("opacity", 1);
9950
+ d3Selection7.select(this).attr("opacity", 1);
9298
9951
  });
9299
9952
  }
9300
9953
  }
@@ -9309,14 +9962,14 @@ function renderArcDiagram(container, parsed, palette, _isDark, onClickItem, expo
9309
9962
  function handleMouseEnter(hovered) {
9310
9963
  const connected = neighbors.get(hovered);
9311
9964
  g.selectAll(".arc-link").each(function() {
9312
- const el = d3Selection6.select(this);
9965
+ const el = d3Selection7.select(this);
9313
9966
  const src = el.attr("data-source");
9314
9967
  const tgt = el.attr("data-target");
9315
9968
  const isRelated = src === hovered || tgt === hovered;
9316
9969
  el.attr("stroke-opacity", isRelated ? 0.85 : FADE_OPACITY);
9317
9970
  });
9318
9971
  g.selectAll(".arc-node").each(function() {
9319
- const el = d3Selection6.select(this);
9972
+ const el = d3Selection7.select(this);
9320
9973
  const name = el.attr("data-node");
9321
9974
  const isRelated = name === hovered || connected.has(name);
9322
9975
  el.attr("opacity", isRelated ? 1 : FADE_OPACITY);
@@ -9341,23 +9994,23 @@ function renderArcDiagram(container, parsed, palette, _isDark, onClickItem, expo
9341
9994
  const members = groupNodeSets.get(groupName);
9342
9995
  if (!members) return;
9343
9996
  g.selectAll(".arc-link").each(function() {
9344
- const el = d3Selection6.select(this);
9997
+ const el = d3Selection7.select(this);
9345
9998
  const isRelated = members.has(el.attr("data-source")) || members.has(el.attr("data-target"));
9346
9999
  el.attr("stroke-opacity", isRelated ? 0.85 : FADE_OPACITY);
9347
10000
  });
9348
10001
  g.selectAll(".arc-node").each(function() {
9349
- const el = d3Selection6.select(this);
10002
+ const el = d3Selection7.select(this);
9350
10003
  el.attr("opacity", members.has(el.attr("data-node")) ? 1 : FADE_OPACITY);
9351
10004
  });
9352
10005
  g.selectAll(".arc-group-band").each(function() {
9353
- const el = d3Selection6.select(this);
10006
+ const el = d3Selection7.select(this);
9354
10007
  el.attr(
9355
10008
  "fill-opacity",
9356
10009
  el.attr("data-group") === groupName ? 0.18 : 0.03
9357
10010
  );
9358
10011
  });
9359
10012
  g.selectAll(".arc-group-label").each(function() {
9360
- const el = d3Selection6.select(this);
10013
+ const el = d3Selection7.select(this);
9361
10014
  el.attr("fill-opacity", el.attr("data-group") === groupName ? 1 : 0.2);
9362
10015
  });
9363
10016
  }
@@ -9653,7 +10306,7 @@ function showEventDatesOnScale(g, scale, startDate, endDate, innerHeight, accent
9653
10306
  function hideEventDatesOnScale(g) {
9654
10307
  g.selectAll(".tl-event-date").remove();
9655
10308
  g.selectAll(".tl-scale-tick").each(function() {
9656
- const el = d3Selection6.select(this);
10309
+ const el = d3Selection7.select(this);
9657
10310
  const isDashed = el.attr("stroke-dasharray");
9658
10311
  el.attr("opacity", isDashed ? 0.15 : 0.4);
9659
10312
  });
@@ -9711,7 +10364,7 @@ function buildEraTooltipHtml(era) {
9711
10364
  return `<strong>${era.label}</strong><br>${formatDateLabel(era.startDate)} \u2192 ${formatDateLabel(era.endDate)}`;
9712
10365
  }
9713
10366
  function renderTimeline(container, parsed, palette, isDark, onClickItem, exportDims) {
9714
- d3Selection6.select(container).selectAll(":not([data-d3-tooltip])").remove();
10367
+ d3Selection7.select(container).selectAll(":not([data-d3-tooltip])").remove();
9715
10368
  const {
9716
10369
  timelineEvents,
9717
10370
  timelineGroups,
@@ -9763,13 +10416,13 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
9763
10416
  const FADE_OPACITY = 0.1;
9764
10417
  function fadeToGroup(g, groupName) {
9765
10418
  g.selectAll(".tl-event").each(function() {
9766
- const el = d3Selection6.select(this);
10419
+ const el = d3Selection7.select(this);
9767
10420
  const evGroup = el.attr("data-group");
9768
10421
  el.attr("opacity", evGroup === groupName ? 1 : FADE_OPACITY);
9769
10422
  });
9770
10423
  g.selectAll(".tl-legend-item, .tl-lane-header").each(
9771
10424
  function() {
9772
- const el = d3Selection6.select(this);
10425
+ const el = d3Selection7.select(this);
9773
10426
  const name = el.attr("data-group");
9774
10427
  el.attr("opacity", name === groupName ? 1 : FADE_OPACITY);
9775
10428
  }
@@ -9781,7 +10434,7 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
9781
10434
  }
9782
10435
  function fadeToEra(g, eraStart, eraEnd) {
9783
10436
  g.selectAll(".tl-event").each(function() {
9784
- const el = d3Selection6.select(this);
10437
+ const el = d3Selection7.select(this);
9785
10438
  const date = parseFloat(el.attr("data-date"));
9786
10439
  const endDate = el.attr("data-end-date");
9787
10440
  const evEnd = endDate ? parseFloat(endDate) : date;
@@ -9793,14 +10446,14 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
9793
10446
  FADE_OPACITY
9794
10447
  );
9795
10448
  g.selectAll(".tl-era").each(function() {
9796
- const el = d3Selection6.select(this);
10449
+ const el = d3Selection7.select(this);
9797
10450
  const s = parseFloat(el.attr("data-era-start"));
9798
10451
  const e = parseFloat(el.attr("data-era-end"));
9799
10452
  const isSelf = s === eraStart && e === eraEnd;
9800
10453
  el.attr("opacity", isSelf ? 1 : FADE_OPACITY);
9801
10454
  });
9802
10455
  g.selectAll(".tl-marker").each(function() {
9803
- const el = d3Selection6.select(this);
10456
+ const el = d3Selection7.select(this);
9804
10457
  const date = parseFloat(el.attr("data-marker-date"));
9805
10458
  const inside = date >= eraStart && date <= eraEnd;
9806
10459
  el.attr("opacity", inside ? 1 : FADE_OPACITY);
@@ -9832,7 +10485,7 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
9832
10485
  const innerHeight = height - margin.top - margin.bottom;
9833
10486
  const laneWidth = innerWidth / laneCount;
9834
10487
  const yScale = d3Scale.scaleLinear().domain([minDate - datePadding, maxDate + datePadding]).range([0, innerHeight]);
9835
- const svg = d3Selection6.select(container).append("svg").attr("width", width).attr("height", height).style("background", bgColor);
10488
+ const svg = d3Selection7.select(container).append("svg").attr("width", width).attr("height", height).style("background", bgColor);
9836
10489
  const g = svg.append("g").attr("transform", `translate(${margin.left},${margin.top})`);
9837
10490
  if (title) {
9838
10491
  const titleEl = svg.append("text").attr("class", "chart-title").attr("x", width / 2).attr("y", 30).attr("text-anchor", "middle").attr("fill", textColor).attr("font-size", "20px").attr("font-weight", "700").style("cursor", onClickItem && parsed.titleLineNumber ? "pointer" : "default").text(title);
@@ -9840,9 +10493,9 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
9840
10493
  titleEl.attr("data-line-number", parsed.titleLineNumber);
9841
10494
  if (onClickItem) {
9842
10495
  titleEl.on("click", () => onClickItem(parsed.titleLineNumber)).on("mouseenter", function() {
9843
- d3Selection6.select(this).attr("opacity", 0.7);
10496
+ d3Selection7.select(this).attr("opacity", 0.7);
9844
10497
  }).on("mouseleave", function() {
9845
- d3Selection6.select(this).attr("opacity", 1);
10498
+ d3Selection7.select(this).attr("opacity", 1);
9846
10499
  });
9847
10500
  }
9848
10501
  }
@@ -9918,7 +10571,7 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
9918
10571
  if (ev.uncertain) {
9919
10572
  const gradientId = `uncertain-vg-${ev.lineNumber}`;
9920
10573
  const defs = svg.select("defs").node() || svg.append("defs").node();
9921
- d3Selection6.select(defs).append("linearGradient").attr("id", gradientId).attr("x1", "0%").attr("y1", "0%").attr("x2", "0%").attr("y2", "100%").selectAll("stop").data([
10574
+ d3Selection7.select(defs).append("linearGradient").attr("id", gradientId).attr("x1", "0%").attr("y1", "0%").attr("x2", "0%").attr("y2", "100%").selectAll("stop").data([
9922
10575
  { offset: "0%", opacity: 1 },
9923
10576
  { offset: "80%", opacity: 1 },
9924
10577
  { offset: "100%", opacity: 0 }
@@ -9947,7 +10600,7 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
9947
10600
  const axisX = 20;
9948
10601
  const yScale = d3Scale.scaleLinear().domain([minDate - datePadding, maxDate + datePadding]).range([0, innerHeight]);
9949
10602
  const sorted = timelineEvents.slice().sort((a, b) => parseTimelineDate(a.date) - parseTimelineDate(b.date));
9950
- const svg = d3Selection6.select(container).append("svg").attr("width", width).attr("height", height).style("background", bgColor);
10603
+ const svg = d3Selection7.select(container).append("svg").attr("width", width).attr("height", height).style("background", bgColor);
9951
10604
  const g = svg.append("g").attr("transform", `translate(${margin.left},${margin.top})`);
9952
10605
  if (title) {
9953
10606
  const titleEl = svg.append("text").attr("class", "chart-title").attr("x", width / 2).attr("y", 30).attr("text-anchor", "middle").attr("fill", textColor).attr("font-size", "20px").attr("font-weight", "700").style("cursor", onClickItem && parsed.titleLineNumber ? "pointer" : "default").text(title);
@@ -9955,9 +10608,9 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
9955
10608
  titleEl.attr("data-line-number", parsed.titleLineNumber);
9956
10609
  if (onClickItem) {
9957
10610
  titleEl.on("click", () => onClickItem(parsed.titleLineNumber)).on("mouseenter", function() {
9958
- d3Selection6.select(this).attr("opacity", 0.7);
10611
+ d3Selection7.select(this).attr("opacity", 0.7);
9959
10612
  }).on("mouseleave", function() {
9960
- d3Selection6.select(this).attr("opacity", 1);
10613
+ d3Selection7.select(this).attr("opacity", 1);
9961
10614
  });
9962
10615
  }
9963
10616
  }
@@ -10036,7 +10689,7 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
10036
10689
  if (ev.uncertain) {
10037
10690
  const gradientId = `uncertain-v-${ev.lineNumber}`;
10038
10691
  const defs = svg.select("defs").node() || svg.append("defs").node();
10039
- d3Selection6.select(defs).append("linearGradient").attr("id", gradientId).attr("x1", "0%").attr("y1", "0%").attr("x2", "0%").attr("y2", "100%").selectAll("stop").data([
10692
+ d3Selection7.select(defs).append("linearGradient").attr("id", gradientId).attr("x1", "0%").attr("y1", "0%").attr("x2", "0%").attr("y2", "100%").selectAll("stop").data([
10040
10693
  { offset: "0%", opacity: 1 },
10041
10694
  { offset: "80%", opacity: 1 },
10042
10695
  { offset: "100%", opacity: 0 }
@@ -10091,7 +10744,7 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
10091
10744
  const totalGaps = (lanes.length - 1) * GROUP_GAP;
10092
10745
  const rowH = Math.min(28, (innerHeight - totalGaps) / totalEventRows);
10093
10746
  const xScale = d3Scale.scaleLinear().domain([minDate - datePadding, maxDate + datePadding]).range([0, innerWidth]);
10094
- const svg = d3Selection6.select(container).append("svg").attr("width", width).attr("height", height).style("background", bgColor);
10747
+ const svg = d3Selection7.select(container).append("svg").attr("width", width).attr("height", height).style("background", bgColor);
10095
10748
  const g = svg.append("g").attr("transform", `translate(${margin.left},${margin.top})`);
10096
10749
  if (title) {
10097
10750
  const titleEl = svg.append("text").attr("class", "chart-title").attr("x", width / 2).attr("y", 30).attr("text-anchor", "middle").attr("fill", textColor).attr("font-size", "20px").attr("font-weight", "700").style("cursor", onClickItem && parsed.titleLineNumber ? "pointer" : "default").text(title);
@@ -10099,9 +10752,9 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
10099
10752
  titleEl.attr("data-line-number", parsed.titleLineNumber);
10100
10753
  if (onClickItem) {
10101
10754
  titleEl.on("click", () => onClickItem(parsed.titleLineNumber)).on("mouseenter", function() {
10102
- d3Selection6.select(this).attr("opacity", 0.7);
10755
+ d3Selection7.select(this).attr("opacity", 0.7);
10103
10756
  }).on("mouseleave", function() {
10104
- d3Selection6.select(this).attr("opacity", 1);
10757
+ d3Selection7.select(this).attr("opacity", 1);
10105
10758
  });
10106
10759
  }
10107
10760
  }
@@ -10205,7 +10858,7 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
10205
10858
  if (ev.uncertain) {
10206
10859
  const gradientId = `uncertain-${ev.lineNumber}`;
10207
10860
  const defs = svg.select("defs").node() || svg.append("defs").node();
10208
- d3Selection6.select(defs).append("linearGradient").attr("id", gradientId).attr("x1", "0%").attr("y1", "0%").attr("x2", "100%").attr("y2", "0%").selectAll("stop").data([
10861
+ d3Selection7.select(defs).append("linearGradient").attr("id", gradientId).attr("x1", "0%").attr("y1", "0%").attr("x2", "100%").attr("y2", "0%").selectAll("stop").data([
10209
10862
  { offset: "0%", opacity: 1 },
10210
10863
  { offset: "80%", opacity: 1 },
10211
10864
  { offset: "100%", opacity: 0 }
@@ -10246,7 +10899,7 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
10246
10899
  const innerHeight = height - margin.top - margin.bottom;
10247
10900
  const rowH = Math.min(28, innerHeight / sorted.length);
10248
10901
  const xScale = d3Scale.scaleLinear().domain([minDate - datePadding, maxDate + datePadding]).range([0, innerWidth]);
10249
- const svg = d3Selection6.select(container).append("svg").attr("width", width).attr("height", height).style("background", bgColor);
10902
+ const svg = d3Selection7.select(container).append("svg").attr("width", width).attr("height", height).style("background", bgColor);
10250
10903
  const g = svg.append("g").attr("transform", `translate(${margin.left},${margin.top})`);
10251
10904
  if (title) {
10252
10905
  const titleEl = svg.append("text").attr("class", "chart-title").attr("x", width / 2).attr("y", 30).attr("text-anchor", "middle").attr("fill", textColor).attr("font-size", "20px").attr("font-weight", "700").style("cursor", onClickItem && parsed.titleLineNumber ? "pointer" : "default").text(title);
@@ -10254,9 +10907,9 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
10254
10907
  titleEl.attr("data-line-number", parsed.titleLineNumber);
10255
10908
  if (onClickItem) {
10256
10909
  titleEl.on("click", () => onClickItem(parsed.titleLineNumber)).on("mouseenter", function() {
10257
- d3Selection6.select(this).attr("opacity", 0.7);
10910
+ d3Selection7.select(this).attr("opacity", 0.7);
10258
10911
  }).on("mouseleave", function() {
10259
- d3Selection6.select(this).attr("opacity", 1);
10912
+ d3Selection7.select(this).attr("opacity", 1);
10260
10913
  });
10261
10914
  }
10262
10915
  }
@@ -10354,7 +11007,7 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
10354
11007
  if (ev.uncertain) {
10355
11008
  const gradientId = `uncertain-ts-${ev.lineNumber}`;
10356
11009
  const defs = svg.select("defs").node() || svg.append("defs").node();
10357
- d3Selection6.select(defs).append("linearGradient").attr("id", gradientId).attr("x1", "0%").attr("y1", "0%").attr("x2", "100%").attr("y2", "0%").selectAll("stop").data([
11010
+ d3Selection7.select(defs).append("linearGradient").attr("id", gradientId).attr("x1", "0%").attr("y1", "0%").attr("x2", "100%").attr("y2", "0%").selectAll("stop").data([
10358
11011
  { offset: "0%", opacity: 1 },
10359
11012
  { offset: "80%", opacity: 1 },
10360
11013
  { offset: "100%", opacity: 0 }
@@ -10387,7 +11040,7 @@ function getRotateFn(mode) {
10387
11040
  return () => 0;
10388
11041
  }
10389
11042
  function renderWordCloud(container, parsed, palette, _isDark, onClickItem, exportDims) {
10390
- d3Selection6.select(container).selectAll(":not([data-d3-tooltip])").remove();
11043
+ d3Selection7.select(container).selectAll(":not([data-d3-tooltip])").remove();
10391
11044
  const { words, title, cloudOptions } = parsed;
10392
11045
  if (words.length === 0) return;
10393
11046
  const width = exportDims?.width ?? container.clientWidth;
@@ -10408,16 +11061,16 @@ function renderWordCloud(container, parsed, palette, _isDark, onClickItem, expor
10408
11061
  return minSize + t * (maxSize - minSize);
10409
11062
  };
10410
11063
  const rotateFn = getRotateFn(cloudOptions.rotate);
10411
- const svg = d3Selection6.select(container).append("svg").attr("width", width).attr("height", height).style("background", bgColor);
11064
+ const svg = d3Selection7.select(container).append("svg").attr("width", width).attr("height", height).style("background", bgColor);
10412
11065
  if (title) {
10413
11066
  const titleEl = svg.append("text").attr("class", "chart-title").attr("x", width / 2).attr("y", 30).attr("text-anchor", "middle").attr("fill", textColor).attr("font-size", "20px").attr("font-weight", "700").style("cursor", onClickItem && parsed.titleLineNumber ? "pointer" : "default").text(title);
10414
11067
  if (parsed.titleLineNumber) {
10415
11068
  titleEl.attr("data-line-number", parsed.titleLineNumber);
10416
11069
  if (onClickItem) {
10417
11070
  titleEl.on("click", () => onClickItem(parsed.titleLineNumber)).on("mouseenter", function() {
10418
- d3Selection6.select(this).attr("opacity", 0.7);
11071
+ d3Selection7.select(this).attr("opacity", 0.7);
10419
11072
  }).on("mouseleave", function() {
10420
- d3Selection6.select(this).attr("opacity", 1);
11073
+ d3Selection7.select(this).attr("opacity", 1);
10421
11074
  });
10422
11075
  }
10423
11076
  }
@@ -10444,7 +11097,7 @@ function renderWordCloud(container, parsed, palette, _isDark, onClickItem, expor
10444
11097
  }
10445
11098
  function renderWordCloudAsync(container, parsed, palette, _isDark, exportDims) {
10446
11099
  return new Promise((resolve) => {
10447
- d3Selection6.select(container).selectAll(":not([data-d3-tooltip])").remove();
11100
+ d3Selection7.select(container).selectAll(":not([data-d3-tooltip])").remove();
10448
11101
  const { words, title, cloudOptions } = parsed;
10449
11102
  if (words.length === 0) {
10450
11103
  resolve();
@@ -10471,7 +11124,7 @@ function renderWordCloudAsync(container, parsed, palette, _isDark, exportDims) {
10471
11124
  return minSize + t * (maxSize - minSize);
10472
11125
  };
10473
11126
  const rotateFn = getRotateFn(cloudOptions.rotate);
10474
- const svg = d3Selection6.select(container).append("svg").attr("width", width).attr("height", height).style("background", bgColor);
11127
+ const svg = d3Selection7.select(container).append("svg").attr("width", width).attr("height", height).style("background", bgColor);
10475
11128
  if (title) {
10476
11129
  const titleEl = svg.append("text").attr("class", "chart-title").attr("x", width / 2).attr("y", 30).attr("text-anchor", "middle").attr("fill", textColor).attr("font-size", "20px").attr("font-weight", "700").text(title);
10477
11130
  if (parsed.titleLineNumber) {
@@ -10608,7 +11261,7 @@ function regionCentroid(circles, inside) {
10608
11261
  return { x: sx / count, y: sy / count };
10609
11262
  }
10610
11263
  function renderVenn(container, parsed, palette, isDark, onClickItem, exportDims) {
10611
- d3Selection6.select(container).selectAll(":not([data-d3-tooltip])").remove();
11264
+ d3Selection7.select(container).selectAll(":not([data-d3-tooltip])").remove();
10612
11265
  const { vennSets, vennOverlaps, vennShowValues, title } = parsed;
10613
11266
  if (vennSets.length < 2) return;
10614
11267
  const width = exportDims?.width ?? container.clientWidth;
@@ -10695,7 +11348,7 @@ function renderVenn(container, parsed, palette, isDark, onClickItem, exportDims)
10695
11348
  marginTop,
10696
11349
  marginBottom
10697
11350
  ).map((c) => ({ ...c, y: c.y + titleHeight }));
10698
- const svg = d3Selection6.select(container).append("svg").attr("width", width).attr("height", height).style("background", bgColor);
11351
+ const svg = d3Selection7.select(container).append("svg").attr("width", width).attr("height", height).style("background", bgColor);
10699
11352
  const tooltip = createTooltip(container, palette, isDark);
10700
11353
  if (title) {
10701
11354
  const titleEl = svg.append("text").attr("class", "chart-title").attr("x", width / 2).attr("y", 30).attr("text-anchor", "middle").attr("fill", textColor).attr("font-size", "20px").attr("font-weight", "700").style("cursor", onClickItem && parsed.titleLineNumber ? "pointer" : "default").text(title);
@@ -10703,9 +11356,9 @@ function renderVenn(container, parsed, palette, isDark, onClickItem, exportDims)
10703
11356
  titleEl.attr("data-line-number", parsed.titleLineNumber);
10704
11357
  if (onClickItem) {
10705
11358
  titleEl.on("click", () => onClickItem(parsed.titleLineNumber)).on("mouseenter", function() {
10706
- d3Selection6.select(this).attr("opacity", 0.7);
11359
+ d3Selection7.select(this).attr("opacity", 0.7);
10707
11360
  }).on("mouseleave", function() {
10708
- d3Selection6.select(this).attr("opacity", 1);
11361
+ d3Selection7.select(this).attr("opacity", 1);
10709
11362
  });
10710
11363
  }
10711
11364
  }
@@ -10853,7 +11506,7 @@ function renderVenn(container, parsed, palette, isDark, onClickItem, exportDims)
10853
11506
  });
10854
11507
  }
10855
11508
  function renderQuadrant(container, parsed, palette, isDark, onClickItem, exportDims) {
10856
- d3Selection6.select(container).selectAll(":not([data-d3-tooltip])").remove();
11509
+ d3Selection7.select(container).selectAll(":not([data-d3-tooltip])").remove();
10857
11510
  const {
10858
11511
  title,
10859
11512
  quadrantLabels,
@@ -10885,7 +11538,7 @@ function renderQuadrant(container, parsed, palette, isDark, onClickItem, exportD
10885
11538
  const chartHeight = height - margin.top - margin.bottom;
10886
11539
  const xScale = d3Scale.scaleLinear().domain([0, 1]).range([0, chartWidth]);
10887
11540
  const yScale = d3Scale.scaleLinear().domain([0, 1]).range([chartHeight, 0]);
10888
- const svg = d3Selection6.select(container).append("svg").attr("width", width).attr("height", height).style("background", bgColor);
11541
+ const svg = d3Selection7.select(container).append("svg").attr("width", width).attr("height", height).style("background", bgColor);
10889
11542
  const tooltip = createTooltip(container, palette, isDark);
10890
11543
  if (title) {
10891
11544
  const titleText = svg.append("text").attr("class", "chart-title").attr("x", width / 2).attr("y", 30).attr("text-anchor", "middle").attr("fill", textColor).attr("font-size", "20px").attr("font-weight", "700").style(
@@ -10897,9 +11550,9 @@ function renderQuadrant(container, parsed, palette, isDark, onClickItem, exportD
10897
11550
  }
10898
11551
  if (onClickItem && quadrantTitleLineNumber) {
10899
11552
  titleText.on("click", () => onClickItem(quadrantTitleLineNumber)).on("mouseenter", function() {
10900
- d3Selection6.select(this).attr("opacity", 0.7);
11553
+ d3Selection7.select(this).attr("opacity", 0.7);
10901
11554
  }).on("mouseleave", function() {
10902
- d3Selection6.select(this).attr("opacity", 1);
11555
+ d3Selection7.select(this).attr("opacity", 1);
10903
11556
  });
10904
11557
  }
10905
11558
  }
@@ -11035,7 +11688,7 @@ function renderQuadrant(container, parsed, palette, isDark, onClickItem, exportD
11035
11688
  (d) => onClickItem && d.label?.lineNumber ? "pointer" : "default"
11036
11689
  ).each(function(d) {
11037
11690
  const layout = labelLayouts.get(d.label.text);
11038
- const el = d3Selection6.select(this);
11691
+ const el = d3Selection7.select(this);
11039
11692
  if (layout.lines.length === 1) {
11040
11693
  el.text(layout.lines[0]);
11041
11694
  } else {
@@ -11051,9 +11704,9 @@ function renderQuadrant(container, parsed, palette, isDark, onClickItem, exportD
11051
11704
  quadrantLabelTexts.on("click", (_, d) => {
11052
11705
  if (d.label?.lineNumber) onClickItem(d.label.lineNumber);
11053
11706
  }).on("mouseenter", function() {
11054
- d3Selection6.select(this).attr("opacity", 0.7);
11707
+ d3Selection7.select(this).attr("opacity", 0.7);
11055
11708
  }).on("mouseleave", function() {
11056
- d3Selection6.select(this).attr("opacity", 1);
11709
+ d3Selection7.select(this).attr("opacity", 1);
11057
11710
  });
11058
11711
  }
11059
11712
  if (quadrantXAxis) {
@@ -11068,9 +11721,9 @@ function renderQuadrant(container, parsed, palette, isDark, onClickItem, exportD
11068
11721
  if (onClickItem && quadrantXAxisLineNumber) {
11069
11722
  [xLowLabel, xHighLabel].forEach((label) => {
11070
11723
  label.on("click", () => onClickItem(quadrantXAxisLineNumber)).on("mouseenter", function() {
11071
- d3Selection6.select(this).attr("opacity", 0.7);
11724
+ d3Selection7.select(this).attr("opacity", 0.7);
11072
11725
  }).on("mouseleave", function() {
11073
- d3Selection6.select(this).attr("opacity", 1);
11726
+ d3Selection7.select(this).attr("opacity", 1);
11074
11727
  });
11075
11728
  });
11076
11729
  }
@@ -11089,9 +11742,9 @@ function renderQuadrant(container, parsed, palette, isDark, onClickItem, exportD
11089
11742
  if (onClickItem && quadrantYAxisLineNumber) {
11090
11743
  [yLowLabel, yHighLabel].forEach((label) => {
11091
11744
  label.on("click", () => onClickItem(quadrantYAxisLineNumber)).on("mouseenter", function() {
11092
- d3Selection6.select(this).attr("opacity", 0.7);
11745
+ d3Selection7.select(this).attr("opacity", 0.7);
11093
11746
  }).on("mouseleave", function() {
11094
- d3Selection6.select(this).attr("opacity", 1);
11747
+ d3Selection7.select(this).attr("opacity", 1);
11095
11748
  });
11096
11749
  });
11097
11750
  }
@@ -11139,7 +11792,7 @@ function renderQuadrant(container, parsed, palette, isDark, onClickItem, exportD
11139
11792
  pointsG.selectAll("g.point-group").each(function(_2, i) {
11140
11793
  const pt = quadrantPoints[i];
11141
11794
  const ptQuad = getPointQuadrant(pt.x, pt.y);
11142
- d3Selection6.select(this).attr("opacity", ptQuad === d.position ? 1 : 0.2);
11795
+ d3Selection7.select(this).attr("opacity", ptQuad === d.position ? 1 : 0.2);
11143
11796
  });
11144
11797
  }).on("mouseleave", () => {
11145
11798
  quadrantRects.attr("opacity", 1);
@@ -11163,7 +11816,7 @@ async function renderD3ForExport(content, theme, palette, orgExportState, option
11163
11816
  const { getPalette: getPalette3 } = await Promise.resolve().then(() => (init_palettes(), palettes_exports));
11164
11817
  const effectivePalette2 = palette ?? (isDark2 ? getPalette3("nord").dark : getPalette3("nord").light);
11165
11818
  const orgParsed = parseOrg2(content, effectivePalette2);
11166
- if (orgParsed.error || orgParsed.roots.length === 0) return "";
11819
+ if (orgParsed.error) return "";
11167
11820
  const collapsedNodes = orgExportState?.collapsedNodes;
11168
11821
  const activeTagGroup = orgExportState?.activeTagGroup ?? null;
11169
11822
  const hiddenAttributes = orgExportState?.hiddenAttributes;
@@ -11215,10 +11868,43 @@ async function renderD3ForExport(content, theme, palette, orgExportState, option
11215
11868
  document.body.removeChild(container2);
11216
11869
  }
11217
11870
  }
11871
+ if (detectedType === "kanban") {
11872
+ const { parseKanban: parseKanban2 } = await Promise.resolve().then(() => (init_parser5(), parser_exports5));
11873
+ const { renderKanban: renderKanban2 } = await Promise.resolve().then(() => (init_renderer2(), renderer_exports2));
11874
+ const isDark2 = theme === "dark";
11875
+ const { getPalette: getPalette3 } = await Promise.resolve().then(() => (init_palettes(), palettes_exports));
11876
+ const effectivePalette2 = palette ?? (isDark2 ? getPalette3("nord").dark : getPalette3("nord").light);
11877
+ const kanbanParsed = parseKanban2(content, effectivePalette2);
11878
+ if (kanbanParsed.error || kanbanParsed.columns.length === 0) return "";
11879
+ const container2 = document.createElement("div");
11880
+ container2.style.position = "absolute";
11881
+ container2.style.left = "-9999px";
11882
+ document.body.appendChild(container2);
11883
+ try {
11884
+ renderKanban2(container2, kanbanParsed, effectivePalette2, isDark2);
11885
+ const svgEl = container2.querySelector("svg");
11886
+ if (!svgEl) return "";
11887
+ if (theme === "transparent") {
11888
+ svgEl.style.background = "none";
11889
+ } else if (!svgEl.style.background) {
11890
+ svgEl.style.background = effectivePalette2.bg;
11891
+ }
11892
+ svgEl.setAttribute("xmlns", "http://www.w3.org/2000/svg");
11893
+ svgEl.style.fontFamily = FONT_FAMILY;
11894
+ const svgHtml = svgEl.outerHTML;
11895
+ if (options?.branding !== false) {
11896
+ const brandColor = theme === "transparent" ? "#888" : effectivePalette2.textMuted;
11897
+ return injectBranding(svgHtml, brandColor);
11898
+ }
11899
+ return svgHtml;
11900
+ } finally {
11901
+ document.body.removeChild(container2);
11902
+ }
11903
+ }
11218
11904
  if (detectedType === "class") {
11219
11905
  const { parseClassDiagram: parseClassDiagram2 } = await Promise.resolve().then(() => (init_parser2(), parser_exports2));
11220
11906
  const { layoutClassDiagram: layoutClassDiagram2 } = await Promise.resolve().then(() => (init_layout2(), layout_exports2));
11221
- const { renderClassDiagram: renderClassDiagram2 } = await Promise.resolve().then(() => (init_renderer2(), renderer_exports2));
11907
+ const { renderClassDiagram: renderClassDiagram2 } = await Promise.resolve().then(() => (init_renderer3(), renderer_exports3));
11222
11908
  const isDark2 = theme === "dark";
11223
11909
  const { getPalette: getPalette3 } = await Promise.resolve().then(() => (init_palettes(), palettes_exports));
11224
11910
  const effectivePalette2 = palette ?? (isDark2 ? getPalette3("nord").dark : getPalette3("nord").light);
@@ -11267,7 +11953,7 @@ async function renderD3ForExport(content, theme, palette, orgExportState, option
11267
11953
  if (detectedType === "er") {
11268
11954
  const { parseERDiagram: parseERDiagram2 } = await Promise.resolve().then(() => (init_parser3(), parser_exports3));
11269
11955
  const { layoutERDiagram: layoutERDiagram2 } = await Promise.resolve().then(() => (init_layout3(), layout_exports3));
11270
- const { renderERDiagram: renderERDiagram2 } = await Promise.resolve().then(() => (init_renderer3(), renderer_exports3));
11956
+ const { renderERDiagram: renderERDiagram2 } = await Promise.resolve().then(() => (init_renderer4(), renderer_exports4));
11271
11957
  const isDark2 = theme === "dark";
11272
11958
  const { getPalette: getPalette3 } = await Promise.resolve().then(() => (init_palettes(), palettes_exports));
11273
11959
  const effectivePalette2 = palette ?? (isDark2 ? getPalette3("nord").dark : getPalette3("nord").light);
@@ -11380,7 +12066,7 @@ async function renderD3ForExport(content, theme, palette, orgExportState, option
11380
12066
  try {
11381
12067
  if (parsed.type === "sequence") {
11382
12068
  const { parseSequenceDgmo: parseSequenceDgmo2 } = await Promise.resolve().then(() => (init_parser(), parser_exports));
11383
- const { renderSequenceDiagram: renderSequenceDiagram2 } = await Promise.resolve().then(() => (init_renderer4(), renderer_exports4));
12069
+ const { renderSequenceDiagram: renderSequenceDiagram2 } = await Promise.resolve().then(() => (init_renderer5(), renderer_exports5));
11384
12070
  const seqParsed = parseSequenceDgmo2(content);
11385
12071
  if (seqParsed.error || seqParsed.participants.length === 0) return "";
11386
12072
  renderSequenceDiagram2(container, seqParsed, effectivePalette, isDark, void 0, {
@@ -11767,13 +12453,16 @@ function buildMermaidQuadrant(parsed, options = {}) {
11767
12453
  init_flowchart_parser();
11768
12454
  init_parser2();
11769
12455
  init_layout2();
11770
- init_renderer2();
12456
+ init_renderer3();
11771
12457
  init_parser3();
11772
12458
  init_layout3();
11773
- init_renderer3();
12459
+ init_renderer4();
11774
12460
  init_parser4();
11775
12461
  init_layout();
11776
12462
  init_renderer();
12463
+ init_parser5();
12464
+ init_mutations();
12465
+ init_renderer2();
11777
12466
  init_collapse();
11778
12467
 
11779
12468
  // src/org/resolver.ts
@@ -11782,8 +12471,8 @@ var MAX_DEPTH = 10;
11782
12471
  var IMPORT_RE = /^(\s+)import:\s+(.+\.dgmo)\s*$/i;
11783
12472
  var TAGS_RE = /^tags:\s+(.+\.dgmo)\s*$/i;
11784
12473
  var HEADER_RE = /^(chart|title)\s*:/i;
11785
- var OPTION_RE2 = /^[a-z][a-z0-9-]*\s*:/i;
11786
- var GROUP_HEADING_RE3 = /^##\s+/;
12474
+ var OPTION_RE3 = /^[a-z][a-z0-9-]*\s*:/i;
12475
+ var GROUP_HEADING_RE4 = /^##\s+/;
11787
12476
  function dirname(filePath) {
11788
12477
  const last = filePath.lastIndexOf("/");
11789
12478
  return last > 0 ? filePath.substring(0, last) : "/";
@@ -11804,7 +12493,7 @@ function extractTagGroups(lines) {
11804
12493
  let current = null;
11805
12494
  for (const line5 of lines) {
11806
12495
  const trimmed = line5.trim();
11807
- if (GROUP_HEADING_RE3.test(trimmed)) {
12496
+ if (GROUP_HEADING_RE4.test(trimmed)) {
11808
12497
  const nameMatch = trimmed.match(/^##\s+(.+?)(?:\s+alias\s+\w+)?(?:\s*\([^)]+\))?\s*$/);
11809
12498
  const name = nameMatch ? nameMatch[1].trim().toLowerCase() : trimmed.substring(3).trim().toLowerCase();
11810
12499
  current = { name, lines: [line5] };
@@ -11848,7 +12537,7 @@ function parseFileHeader(lines) {
11848
12537
  tagsDirective = tagsMatch[1].trim();
11849
12538
  continue;
11850
12539
  }
11851
- if (OPTION_RE2.test(trimmed) && !trimmed.startsWith("##") && !lines[i].match(/^\s/)) {
12540
+ if (OPTION_RE3.test(trimmed) && !trimmed.startsWith("##") && !lines[i].match(/^\s/)) {
11852
12541
  const key = trimmed.split(":")[0].trim().toLowerCase();
11853
12542
  if (key !== "chart" && key !== "title" && !trimmed.includes("|")) {
11854
12543
  continue;
@@ -11877,7 +12566,7 @@ async function resolveFile(content, filePath, readFileFn, diagnostics, ancestorC
11877
12566
  headerLines.push(lines[i]);
11878
12567
  continue;
11879
12568
  }
11880
- if (GROUP_HEADING_RE3.test(trimmed)) continue;
12569
+ if (GROUP_HEADING_RE4.test(trimmed)) continue;
11881
12570
  if (lines[i] !== trimmed) continue;
11882
12571
  const tagsMatch = trimmed.match(TAGS_RE);
11883
12572
  if (tagsMatch) {
@@ -11908,7 +12597,7 @@ async function resolveFile(content, filePath, readFileFn, diagnostics, ancestorC
11908
12597
  const importMatch = line5.match(IMPORT_RE);
11909
12598
  if (!importMatch) {
11910
12599
  const trimmed = line5.trim();
11911
- if (GROUP_HEADING_RE3.test(trimmed) || inlineTagGroups.length > 0 && isTagGroupEntry(line5, bodyLines, i)) {
12600
+ if (GROUP_HEADING_RE4.test(trimmed) || inlineTagGroups.length > 0 && isTagGroupEntry(line5, bodyLines, i)) {
11912
12601
  continue;
11913
12602
  }
11914
12603
  resolvedBodyLines.push(line5);
@@ -12003,7 +12692,7 @@ function findBodyStart(lines) {
12003
12692
  if (inTagGroup) inTagGroup = false;
12004
12693
  continue;
12005
12694
  }
12006
- if (GROUP_HEADING_RE3.test(trimmed)) {
12695
+ if (GROUP_HEADING_RE4.test(trimmed)) {
12007
12696
  inTagGroup = true;
12008
12697
  continue;
12009
12698
  }
@@ -12015,7 +12704,7 @@ function findBodyStart(lines) {
12015
12704
  }
12016
12705
  if (HEADER_RE.test(trimmed)) continue;
12017
12706
  if (TAGS_RE.test(trimmed)) continue;
12018
- if (OPTION_RE2.test(trimmed) && !lines[i].match(/^\s/) && !trimmed.includes("|")) {
12707
+ if (OPTION_RE3.test(trimmed) && !lines[i].match(/^\s/) && !trimmed.includes("|")) {
12019
12708
  const key = trimmed.split(":")[0].trim().toLowerCase();
12020
12709
  if (key !== "chart" && key !== "title") {
12021
12710
  continue;
@@ -12030,7 +12719,7 @@ function isTagGroupEntry(line5, allLines, index) {
12030
12719
  for (let i = index - 1; i >= 0; i--) {
12031
12720
  const prev = allLines[i].trim();
12032
12721
  if (prev === "" || prev.startsWith("//")) continue;
12033
- if (GROUP_HEADING_RE3.test(prev)) return true;
12722
+ if (GROUP_HEADING_RE4.test(prev)) return true;
12034
12723
  if (allLines[i].match(/^\s+/)) continue;
12035
12724
  return false;
12036
12725
  }
@@ -12059,7 +12748,7 @@ init_layout4();
12059
12748
  init_flowchart_renderer();
12060
12749
  init_echarts();
12061
12750
  init_d3();
12062
- init_renderer4();
12751
+ init_renderer5();
12063
12752
  init_colors();
12064
12753
  init_palettes();
12065
12754
 
@@ -12134,6 +12823,8 @@ export {
12134
12823
  collapseOrgTree,
12135
12824
  colorNames,
12136
12825
  computeActivations,
12826
+ computeCardArchive,
12827
+ computeCardMove,
12137
12828
  computeTimeTicks,
12138
12829
  contrastText,
12139
12830
  decodeDiagramUrl,
@@ -12151,6 +12842,7 @@ export {
12151
12842
  hslToHex,
12152
12843
  inferParticipantType,
12153
12844
  injectBranding,
12845
+ isArchiveColumn,
12154
12846
  isSequenceBlock,
12155
12847
  isSequenceNote,
12156
12848
  isValidHex,
@@ -12176,6 +12868,7 @@ export {
12176
12868
  parseEChart,
12177
12869
  parseERDiagram,
12178
12870
  parseFlowchart,
12871
+ parseKanban,
12179
12872
  parseOrg,
12180
12873
  parseQuadrant,
12181
12874
  parseSequenceDgmo,
@@ -12191,6 +12884,8 @@ export {
12191
12884
  renderERDiagramForExport,
12192
12885
  renderFlowchart,
12193
12886
  renderFlowchartForExport,
12887
+ renderKanban,
12888
+ renderKanbanForExport,
12194
12889
  renderOrg,
12195
12890
  renderOrgForExport,
12196
12891
  renderQuadrant,