@diagrammo/dgmo 0.2.20 → 0.2.21

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
@@ -4521,6 +4521,7 @@ var init_echarts = __esm({
4521
4521
  // src/org/parser.ts
4522
4522
  var parser_exports4 = {};
4523
4523
  __export(parser_exports4, {
4524
+ looksLikeOrg: () => looksLikeOrg,
4524
4525
  parseOrg: () => parseOrg
4525
4526
  });
4526
4527
  function measureIndent5(line5) {
@@ -4541,6 +4542,14 @@ function extractColor2(label, palette) {
4541
4542
  color: resolveColor(colorName, palette)
4542
4543
  };
4543
4544
  }
4545
+ function looksLikeOrg(content) {
4546
+ for (const line5 of content.split("\n")) {
4547
+ const trimmed = line5.trim();
4548
+ if (!trimmed || trimmed.startsWith("//")) continue;
4549
+ if (GROUP_HEADING_RE2.test(trimmed)) return true;
4550
+ }
4551
+ return false;
4552
+ }
4544
4553
  function parseOrg(content, palette) {
4545
4554
  const result = {
4546
4555
  title: null,
@@ -4699,7 +4708,7 @@ function parseOrg(content, palette) {
4699
4708
  attachNode(node, indent, indentStack, result);
4700
4709
  }
4701
4710
  }
4702
- if (result.roots.length === 0 && !result.error) {
4711
+ if (result.roots.length === 0 && result.tagGroups.length === 0 && !result.error) {
4703
4712
  const diag = makeDgmoError(1, "No nodes found in org chart");
4704
4713
  result.diagnostics.push(diag);
4705
4714
  result.error = formatDgmoError(diag);
@@ -4780,6 +4789,289 @@ var init_parser4 = __esm({
4780
4789
  }
4781
4790
  });
4782
4791
 
4792
+ // src/kanban/parser.ts
4793
+ var parser_exports5 = {};
4794
+ __export(parser_exports5, {
4795
+ parseKanban: () => parseKanban
4796
+ });
4797
+ function measureIndent6(line5) {
4798
+ let indent = 0;
4799
+ for (const ch of line5) {
4800
+ if (ch === " ") indent++;
4801
+ else if (ch === " ") indent += 4;
4802
+ else break;
4803
+ }
4804
+ return indent;
4805
+ }
4806
+ function extractColor3(label, palette) {
4807
+ const m = label.match(COLOR_SUFFIX_RE3);
4808
+ if (!m) return { label };
4809
+ const colorName = m[1].trim();
4810
+ return {
4811
+ label: label.substring(0, m.index).trim(),
4812
+ color: resolveColor(colorName, palette)
4813
+ };
4814
+ }
4815
+ function parseKanban(content, palette) {
4816
+ const result = {
4817
+ type: "kanban",
4818
+ columns: [],
4819
+ tagGroups: [],
4820
+ options: {},
4821
+ diagnostics: []
4822
+ };
4823
+ const fail = (line5, message) => {
4824
+ const diag = makeDgmoError(line5, message);
4825
+ result.diagnostics.push(diag);
4826
+ result.error = formatDgmoError(diag);
4827
+ return result;
4828
+ };
4829
+ const warn = (line5, message) => {
4830
+ result.diagnostics.push(makeDgmoError(line5, message, "warning"));
4831
+ };
4832
+ if (!content || !content.trim()) {
4833
+ return fail(0, "No content provided");
4834
+ }
4835
+ const lines = content.split("\n");
4836
+ let contentStarted = false;
4837
+ let currentTagGroup = null;
4838
+ let currentColumn = null;
4839
+ let currentCard = null;
4840
+ let columnCounter = 0;
4841
+ let cardCounter = 0;
4842
+ const aliasMap = /* @__PURE__ */ new Map();
4843
+ const tagValueSets = /* @__PURE__ */ new Map();
4844
+ for (let i = 0; i < lines.length; i++) {
4845
+ const line5 = lines[i];
4846
+ const lineNumber = i + 1;
4847
+ const trimmed = line5.trim();
4848
+ if (!trimmed) {
4849
+ if (currentTagGroup) currentTagGroup = null;
4850
+ continue;
4851
+ }
4852
+ if (trimmed.startsWith("//")) continue;
4853
+ if (!contentStarted && !currentTagGroup) {
4854
+ const chartMatch = trimmed.match(CHART_TYPE_RE2);
4855
+ if (chartMatch) {
4856
+ const chartType = chartMatch[1].trim().toLowerCase();
4857
+ if (chartType !== "kanban") {
4858
+ const allTypes = [
4859
+ "kanban",
4860
+ "org",
4861
+ "class",
4862
+ "flowchart",
4863
+ "sequence",
4864
+ "er",
4865
+ "bar",
4866
+ "line",
4867
+ "pie"
4868
+ ];
4869
+ let msg = `Expected chart type "kanban", got "${chartType}"`;
4870
+ const hint = suggest(chartType, allTypes);
4871
+ if (hint) msg += `. ${hint}`;
4872
+ return fail(lineNumber, msg);
4873
+ }
4874
+ continue;
4875
+ }
4876
+ }
4877
+ if (!contentStarted && !currentTagGroup) {
4878
+ const titleMatch = trimmed.match(TITLE_RE2);
4879
+ if (titleMatch) {
4880
+ result.title = titleMatch[1].trim();
4881
+ result.titleLineNumber = lineNumber;
4882
+ continue;
4883
+ }
4884
+ }
4885
+ if (!contentStarted && !currentTagGroup && measureIndent6(line5) === 0) {
4886
+ const optMatch = trimmed.match(OPTION_RE2);
4887
+ if (optMatch && !trimmed.startsWith("##") && !COLUMN_RE2.test(trimmed)) {
4888
+ const key = optMatch[1].trim().toLowerCase();
4889
+ if (key !== "chart" && key !== "title") {
4890
+ result.options[key] = optMatch[2].trim();
4891
+ continue;
4892
+ }
4893
+ }
4894
+ }
4895
+ const groupMatch = trimmed.match(GROUP_HEADING_RE3);
4896
+ if (groupMatch && !contentStarted) {
4897
+ const groupName = groupMatch[1].trim();
4898
+ const alias = groupMatch[2] || void 0;
4899
+ currentTagGroup = {
4900
+ name: groupName,
4901
+ alias,
4902
+ entries: [],
4903
+ lineNumber
4904
+ };
4905
+ if (alias) {
4906
+ aliasMap.set(alias.toLowerCase(), groupName.toLowerCase());
4907
+ }
4908
+ result.tagGroups.push(currentTagGroup);
4909
+ continue;
4910
+ }
4911
+ if (currentTagGroup && !contentStarted) {
4912
+ const indent2 = measureIndent6(line5);
4913
+ if (indent2 > 0) {
4914
+ const isDefault = /\bdefault\s*$/.test(trimmed);
4915
+ const entryText = isDefault ? trimmed.replace(/\s+default\s*$/, "").trim() : trimmed;
4916
+ const { label, color } = extractColor3(entryText, palette);
4917
+ if (!color) {
4918
+ warn(
4919
+ lineNumber,
4920
+ `Expected 'Value(color)' in tag group '${currentTagGroup.name}'`
4921
+ );
4922
+ continue;
4923
+ }
4924
+ if (isDefault) {
4925
+ currentTagGroup.defaultValue = label;
4926
+ }
4927
+ currentTagGroup.entries.push({
4928
+ value: label,
4929
+ color,
4930
+ lineNumber
4931
+ });
4932
+ continue;
4933
+ }
4934
+ currentTagGroup = null;
4935
+ }
4936
+ const columnMatch = trimmed.match(COLUMN_RE2);
4937
+ if (columnMatch) {
4938
+ contentStarted = true;
4939
+ currentTagGroup = null;
4940
+ if (currentCard) {
4941
+ currentCard.endLineNumber = lineNumber - 1;
4942
+ while (currentCard.endLineNumber > currentCard.lineNumber && !lines[currentCard.endLineNumber - 1].trim()) {
4943
+ currentCard.endLineNumber--;
4944
+ }
4945
+ }
4946
+ currentCard = null;
4947
+ columnCounter++;
4948
+ const rawColName = columnMatch[1].trim();
4949
+ const wipStr = columnMatch[2];
4950
+ const { label: colName, color: colColor } = extractColor3(
4951
+ rawColName,
4952
+ palette
4953
+ );
4954
+ currentColumn = {
4955
+ id: `col-${columnCounter}`,
4956
+ name: colName,
4957
+ wipLimit: wipStr ? parseInt(wipStr, 10) : void 0,
4958
+ color: colColor,
4959
+ cards: [],
4960
+ lineNumber
4961
+ };
4962
+ result.columns.push(currentColumn);
4963
+ continue;
4964
+ }
4965
+ if (!contentStarted) {
4966
+ continue;
4967
+ }
4968
+ if (!currentColumn) {
4969
+ warn(lineNumber, "Card line found before any column");
4970
+ continue;
4971
+ }
4972
+ const indent = measureIndent6(line5);
4973
+ if (indent > 0 && currentCard) {
4974
+ currentCard.details.push(trimmed);
4975
+ currentCard.endLineNumber = lineNumber;
4976
+ continue;
4977
+ }
4978
+ if (currentCard) {
4979
+ }
4980
+ cardCounter++;
4981
+ const card = parseCardLine(
4982
+ trimmed,
4983
+ lineNumber,
4984
+ cardCounter,
4985
+ aliasMap,
4986
+ palette
4987
+ );
4988
+ currentCard = card;
4989
+ currentColumn.cards.push(card);
4990
+ }
4991
+ if (currentCard) {
4992
+ }
4993
+ for (const group of result.tagGroups) {
4994
+ const values = new Set(group.entries.map((e) => e.value.toLowerCase()));
4995
+ tagValueSets.set(group.name.toLowerCase(), values);
4996
+ }
4997
+ for (const col of result.columns) {
4998
+ if (col.wipLimit != null && col.cards.length > col.wipLimit) {
4999
+ warn(
5000
+ col.lineNumber,
5001
+ `Column "${col.name}" has ${col.cards.length} cards but WIP limit is ${col.wipLimit}`
5002
+ );
5003
+ }
5004
+ }
5005
+ for (const col of result.columns) {
5006
+ for (const card of col.cards) {
5007
+ for (const [tagKey, tagValue] of Object.entries(card.tags)) {
5008
+ const groupKey = aliasMap.get(tagKey.toLowerCase()) ?? tagKey.toLowerCase();
5009
+ const validValues = tagValueSets.get(groupKey);
5010
+ if (validValues && !validValues.has(tagValue.toLowerCase())) {
5011
+ const entries = result.tagGroups.find((g) => g.name.toLowerCase() === groupKey)?.entries.map((e) => e.value);
5012
+ let msg = `Unknown tag value "${tagValue}" for group "${groupKey}"`;
5013
+ if (entries) {
5014
+ const hint = suggest(tagValue, entries);
5015
+ if (hint) msg += `. ${hint}`;
5016
+ }
5017
+ warn(card.lineNumber, msg);
5018
+ }
5019
+ }
5020
+ }
5021
+ }
5022
+ if (result.columns.length === 0 && !result.error) {
5023
+ return fail(1, "No columns found. Use == Column Name == to define columns");
5024
+ }
5025
+ return result;
5026
+ }
5027
+ function parseCardLine(trimmed, lineNumber, counter, aliasMap, palette) {
5028
+ const pipeIdx = trimmed.indexOf("|");
5029
+ let rawTitle;
5030
+ let tagsStr = null;
5031
+ if (pipeIdx >= 0) {
5032
+ rawTitle = trimmed.substring(0, pipeIdx).trim();
5033
+ tagsStr = trimmed.substring(pipeIdx + 1).trim();
5034
+ } else {
5035
+ rawTitle = trimmed;
5036
+ }
5037
+ const { label: title, color } = extractColor3(rawTitle, palette);
5038
+ const tags = {};
5039
+ if (tagsStr) {
5040
+ for (const part of tagsStr.split(",")) {
5041
+ const colonIdx = part.indexOf(":");
5042
+ if (colonIdx > 0) {
5043
+ const rawKey = part.substring(0, colonIdx).trim().toLowerCase();
5044
+ const key = aliasMap.get(rawKey) ?? rawKey;
5045
+ const value = part.substring(colonIdx + 1).trim();
5046
+ tags[key] = value;
5047
+ }
5048
+ }
5049
+ }
5050
+ return {
5051
+ id: `card-${counter}`,
5052
+ title,
5053
+ tags,
5054
+ details: [],
5055
+ lineNumber,
5056
+ endLineNumber: lineNumber,
5057
+ color
5058
+ };
5059
+ }
5060
+ var CHART_TYPE_RE2, TITLE_RE2, OPTION_RE2, GROUP_HEADING_RE3, COLUMN_RE2, COLOR_SUFFIX_RE3;
5061
+ var init_parser5 = __esm({
5062
+ "src/kanban/parser.ts"() {
5063
+ "use strict";
5064
+ init_colors();
5065
+ init_diagnostics();
5066
+ CHART_TYPE_RE2 = /^chart\s*:\s*(.+)/i;
5067
+ TITLE_RE2 = /^title\s*:\s*(.+)/i;
5068
+ OPTION_RE2 = /^([a-z][a-z0-9-]*)\s*:\s*(.+)$/i;
5069
+ GROUP_HEADING_RE3 = /^##\s+(.+?)(?:\s+alias\s+(\w+))?(?:\s*\(([^)]+)\))?\s*$/;
5070
+ COLUMN_RE2 = /^==\s+(.+?)\s*(?:\[wip:\s*(\d+)\])?\s*==$/;
5071
+ COLOR_SUFFIX_RE3 = /\(([^)]+)\)\s*$/;
5072
+ }
5073
+ });
5074
+
4783
5075
  // src/dgmo-router.ts
4784
5076
  var dgmo_router_exports = {};
4785
5077
  __export(dgmo_router_exports, {
@@ -4804,6 +5096,7 @@ function parseDgmoChartType(content) {
4804
5096
  if (looksLikeFlowchart(content)) return "flowchart";
4805
5097
  if (looksLikeClassDiagram(content)) return "class";
4806
5098
  if (looksLikeERDiagram(content)) return "er";
5099
+ if (looksLikeOrg(content)) return "org";
4807
5100
  return null;
4808
5101
  }
4809
5102
  function parseDgmo(content) {
@@ -4832,6 +5125,10 @@ function parseDgmo(content) {
4832
5125
  const parsed2 = parseOrg(content);
4833
5126
  return { diagnostics: parsed2.diagnostics };
4834
5127
  }
5128
+ if (chartType === "kanban") {
5129
+ const parsed2 = parseKanban(content);
5130
+ return { diagnostics: parsed2.diagnostics };
5131
+ }
4835
5132
  if (STANDARD_CHART_TYPES2.has(chartType)) {
4836
5133
  const parsed2 = parseChart(content);
4837
5134
  return { diagnostics: parsed2.diagnostics };
@@ -4855,6 +5152,7 @@ var init_dgmo_router = __esm({
4855
5152
  init_echarts();
4856
5153
  init_d3();
4857
5154
  init_parser4();
5155
+ init_parser5();
4858
5156
  DGMO_CHART_TYPE_MAP = {
4859
5157
  // Standard charts (via ECharts)
4860
5158
  bar: "echart",
@@ -4884,7 +5182,8 @@ var init_dgmo_router = __esm({
4884
5182
  flowchart: "d3",
4885
5183
  class: "d3",
4886
5184
  er: "d3",
4887
- org: "d3"
5185
+ org: "d3",
5186
+ kanban: "d3"
4888
5187
  };
4889
5188
  STANDARD_CHART_TYPES2 = /* @__PURE__ */ new Set([
4890
5189
  "bar",
@@ -5007,39 +5306,25 @@ function centerHeavyChildren(node) {
5007
5306
  }
5008
5307
  node.children = result;
5009
5308
  }
5010
- function computeLegendGroups(tagGroups, showEyeIcons) {
5309
+ function computeLegendGroups(tagGroups, _showEyeIcons) {
5011
5310
  const groups = [];
5012
5311
  for (const group of tagGroups) {
5013
5312
  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;
5313
+ const pillWidth = group.name.length * LEGEND_PILL_FONT_W + LEGEND_PILL_PAD;
5314
+ let entriesWidth = 0;
5315
+ for (const entry of group.entries) {
5316
+ entriesWidth += LEGEND_DOT_R * 2 + LEGEND_ENTRY_DOT_GAP + entry.value.length * LEGEND_ENTRY_FONT_W + LEGEND_ENTRY_TRAIL;
5317
+ }
5318
+ const capsuleWidth = LEGEND_CAPSULE_PAD * 2 + pillWidth + 4 + entriesWidth;
5034
5319
  groups.push({
5035
5320
  name: group.name,
5036
5321
  entries: group.entries.map((e) => ({ value: e.value, color: e.color })),
5037
5322
  x: 0,
5038
5323
  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
5324
+ width: capsuleWidth,
5325
+ height: LEGEND_HEIGHT,
5326
+ minifiedWidth: pillWidth,
5327
+ minifiedHeight: LEGEND_HEIGHT
5043
5328
  });
5044
5329
  }
5045
5330
  return groups;
@@ -5066,7 +5351,25 @@ function injectDefaultMetadata(roots, tagGroups) {
5066
5351
  }
5067
5352
  function layoutOrg(parsed, hiddenCounts, activeTagGroup, hiddenAttributes) {
5068
5353
  if (parsed.roots.length === 0) {
5069
- return { nodes: [], edges: [], containers: [], legend: [], width: 0, height: 0 };
5354
+ const showEyeIcons2 = hiddenAttributes !== void 0;
5355
+ const legendGroups2 = computeLegendGroups(parsed.tagGroups, showEyeIcons2);
5356
+ if (legendGroups2.length === 0) {
5357
+ return { nodes: [], edges: [], containers: [], legend: [], width: 0, height: 0 };
5358
+ }
5359
+ let cx = MARGIN;
5360
+ for (const g of legendGroups2) {
5361
+ g.x = cx;
5362
+ g.y = MARGIN;
5363
+ cx += g.minifiedWidth + LEGEND_GROUP_GAP;
5364
+ }
5365
+ return {
5366
+ nodes: [],
5367
+ edges: [],
5368
+ containers: [],
5369
+ legend: legendGroups2,
5370
+ width: cx - LEGEND_GROUP_GAP + MARGIN,
5371
+ height: LEGEND_HEIGHT + MARGIN * 2
5372
+ };
5070
5373
  }
5071
5374
  injectDefaultMetadata(parsed.roots, parsed.tagGroups);
5072
5375
  const subNodeLabel = parsed.options["sub-node-label"] ?? void 0;
@@ -5580,7 +5883,7 @@ function layoutOrg(parsed, hiddenCounts, activeTagGroup, hiddenAttributes) {
5580
5883
  const effectiveH = (g) => activeTagGroup != null ? g.height : g.minifiedHeight;
5581
5884
  if (visibleGroups.length > 0) {
5582
5885
  if (legendPosition === "bottom") {
5583
- const totalGroupsWidth = visibleGroups.reduce((s, g) => s + effectiveW(g), 0) + (visibleGroups.length - 1) * H_GAP;
5886
+ const totalGroupsWidth = visibleGroups.reduce((s, g) => s + effectiveW(g), 0) + (visibleGroups.length - 1) * LEGEND_GROUP_GAP;
5584
5887
  const neededWidth = totalGroupsWidth + MARGIN * 2;
5585
5888
  if (neededWidth > totalWidth) {
5586
5889
  finalWidth = neededWidth;
@@ -5595,29 +5898,27 @@ function layoutOrg(parsed, hiddenCounts, activeTagGroup, hiddenAttributes) {
5595
5898
  const legendY = contentBottom + LEGEND_GAP;
5596
5899
  const startX = (finalWidth - totalGroupsWidth) / 2;
5597
5900
  let cx = startX;
5598
- let maxH = 0;
5599
5901
  for (const g of visibleGroups) {
5600
5902
  g.x = cx;
5601
5903
  g.y = legendY;
5602
- cx += effectiveW(g) + H_GAP;
5603
- const h2 = effectiveH(g);
5604
- if (h2 > maxH) maxH = h2;
5904
+ cx += effectiveW(g) + LEGEND_GROUP_GAP;
5605
5905
  }
5606
- finalHeight = totalHeight + LEGEND_GAP + maxH;
5906
+ finalHeight = totalHeight + LEGEND_GAP + LEGEND_HEIGHT;
5607
5907
  } else {
5608
- const maxLegendWidth = Math.max(...visibleGroups.map((g) => effectiveW(g)));
5908
+ const totalGroupsWidth = visibleGroups.reduce((s, g) => s + effectiveW(g), 0) + (visibleGroups.length - 1) * LEGEND_GROUP_GAP;
5609
5909
  const legendStartX = totalWidth - MARGIN + LEGEND_GAP;
5610
- let legendY = MARGIN;
5910
+ const legendY = MARGIN;
5911
+ let cx = legendStartX;
5611
5912
  for (const g of visibleGroups) {
5612
- g.x = legendStartX;
5913
+ g.x = cx;
5613
5914
  g.y = legendY;
5614
- legendY += effectiveH(g) + LEGEND_V_GAP;
5915
+ cx += effectiveW(g) + LEGEND_GROUP_GAP;
5615
5916
  }
5616
- const legendRight = legendStartX + maxLegendWidth + MARGIN;
5917
+ const legendRight = legendStartX + totalGroupsWidth + MARGIN;
5617
5918
  if (legendRight > finalWidth) {
5618
5919
  finalWidth = legendRight;
5619
5920
  }
5620
- const legendBottom = legendY - LEGEND_V_GAP + MARGIN;
5921
+ const legendBottom = legendY + LEGEND_HEIGHT + MARGIN;
5621
5922
  if (legendBottom > finalHeight) {
5622
5923
  finalHeight = legendBottom;
5623
5924
  }
@@ -5632,7 +5933,7 @@ function layoutOrg(parsed, hiddenCounts, activeTagGroup, hiddenAttributes) {
5632
5933
  height: finalHeight
5633
5934
  };
5634
5935
  }
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;
5936
+ 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
5937
  var init_layout = __esm({
5637
5938
  "src/org/layout.ts"() {
5638
5939
  "use strict";
@@ -5652,16 +5953,15 @@ var init_layout = __esm({
5652
5953
  CONTAINER_META_LINE_HEIGHT = 16;
5653
5954
  STACK_V_GAP = 20;
5654
5955
  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;
5956
+ LEGEND_HEIGHT = 28;
5957
+ LEGEND_PILL_PAD = 16;
5958
+ LEGEND_PILL_FONT_W = 11 * 0.6;
5959
+ LEGEND_CAPSULE_PAD = 4;
5960
+ LEGEND_DOT_R = 4;
5961
+ LEGEND_ENTRY_FONT_W = 10 * 0.6;
5962
+ LEGEND_ENTRY_DOT_GAP = 4;
5963
+ LEGEND_ENTRY_TRAIL = 8;
5964
+ LEGEND_GROUP_GAP = 12;
5665
5965
  }
5666
5966
  });
5667
5967
 
@@ -5896,69 +6196,37 @@ function renderOrg(container, parsed, layout, palette, isDark, onClickItem, expo
5896
6196
  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
6197
  }
5898
6198
  }
5899
- if (!exportDims) for (const group of layout.legend) {
6199
+ if (!exportDims || layout.nodes.length === 0) for (const group of layout.legend) {
5900
6200
  const isActive = activeTagGroup != null && group.name.toLowerCase() === activeTagGroup.toLowerCase();
5901
6201
  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;
6202
+ const groupBg = mix(palette.surface, palette.bg, isDark ? 35 : 20);
6203
+ const pillWidth = group.name.length * LEGEND_PILL_FONT_W2 + LEGEND_PILL_PAD2;
5905
6204
  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);
5908
6205
  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
- }
5928
- }
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);
6206
+ gEl.append("rect").attr("width", group.width).attr("height", LEGEND_HEIGHT2).attr("rx", LEGEND_HEIGHT2 / 2).attr("fill", groupBg);
5943
6207
  }
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);
6208
+ const pillX = isActive ? LEGEND_CAPSULE_PAD2 : 0;
6209
+ const pillY = isActive ? LEGEND_CAPSULE_PAD2 : 0;
6210
+ const pillH = LEGEND_HEIGHT2 - (isActive ? LEGEND_CAPSULE_PAD2 * 2 : 0);
6211
+ 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);
6212
+ if (isActive) {
6213
+ 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
6214
  }
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);
6215
+ 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(group.name);
6216
+ if (isActive) {
6217
+ let entryX = pillX + pillWidth + 4;
6218
+ for (const entry of group.entries) {
6219
+ gEl.append("circle").attr("cx", entryX + LEGEND_DOT_R2).attr("cy", LEGEND_HEIGHT2 / 2).attr("r", LEGEND_DOT_R2).attr("fill", entry.color);
6220
+ const textX = entryX + LEGEND_DOT_R2 * 2 + LEGEND_ENTRY_DOT_GAP2;
6221
+ 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(entry.value);
6222
+ entryX = textX + entry.value.length * LEGEND_ENTRY_FONT_W2 + LEGEND_ENTRY_TRAIL2;
6223
+ }
5956
6224
  }
5957
6225
  }
5958
6226
  }
5959
6227
  function renderOrgForExport(content, theme, palette) {
5960
6228
  const parsed = parseOrg(content, palette);
5961
- if (parsed.error || parsed.roots.length === 0) return "";
6229
+ if (parsed.error) return "";
5962
6230
  const hideOption = parsed.options?.["hide"];
5963
6231
  const exportHidden = hideOption ? new Set(hideOption.split(",").map((s) => s.trim().toLowerCase())) : void 0;
5964
6232
  const layout = layoutOrg(parsed, void 0, void 0, exportHidden);
@@ -5989,7 +6257,7 @@ function renderOrgForExport(content, theme, palette) {
5989
6257
  document.body.removeChild(container);
5990
6258
  }
5991
6259
  }
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;
6260
+ 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
6261
  var init_renderer = __esm({
5994
6262
  "src/org/renderer.ts"() {
5995
6263
  "use strict";
@@ -6015,22 +6283,393 @@ var init_renderer = __esm({
6015
6283
  CONTAINER_HEADER_HEIGHT = 28;
6016
6284
  COLLAPSE_BAR_HEIGHT = 6;
6017
6285
  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;
6286
+ LEGEND_HEIGHT2 = 28;
6287
+ LEGEND_PILL_PAD2 = 16;
6288
+ LEGEND_PILL_FONT_SIZE = 11;
6289
+ LEGEND_PILL_FONT_W2 = LEGEND_PILL_FONT_SIZE * 0.6;
6290
+ LEGEND_CAPSULE_PAD2 = 4;
6291
+ LEGEND_DOT_R2 = 4;
6292
+ LEGEND_ENTRY_FONT_SIZE = 10;
6293
+ LEGEND_ENTRY_FONT_W2 = LEGEND_ENTRY_FONT_SIZE * 0.6;
6294
+ LEGEND_ENTRY_DOT_GAP2 = 4;
6295
+ LEGEND_ENTRY_TRAIL2 = 8;
6296
+ }
6297
+ });
6298
+
6299
+ // src/kanban/mutations.ts
6300
+ function computeCardMove(content, parsed, cardId, targetColumnId, targetIndex) {
6301
+ let sourceCard = null;
6302
+ let sourceColumn = null;
6303
+ for (const col of parsed.columns) {
6304
+ for (const card of col.cards) {
6305
+ if (card.id === cardId) {
6306
+ sourceCard = card;
6307
+ sourceColumn = col;
6308
+ break;
6309
+ }
6310
+ }
6311
+ if (sourceCard) break;
6312
+ }
6313
+ if (!sourceCard || !sourceColumn) return null;
6314
+ const targetColumn = parsed.columns.find((c) => c.id === targetColumnId);
6315
+ if (!targetColumn) return null;
6316
+ const lines = content.split("\n");
6317
+ const startIdx = sourceCard.lineNumber - 1;
6318
+ const endIdx = sourceCard.endLineNumber - 1;
6319
+ const cardLines = lines.slice(startIdx, endIdx + 1);
6320
+ const withoutCard = [
6321
+ ...lines.slice(0, startIdx),
6322
+ ...lines.slice(endIdx + 1)
6323
+ ];
6324
+ let insertIdx;
6325
+ const removedCount = endIdx - startIdx + 1;
6326
+ const adjustLine = (ln) => {
6327
+ if (ln > endIdx + 1) return ln - removedCount;
6328
+ return ln;
6329
+ };
6330
+ if (targetIndex === 0) {
6331
+ const adjColLine = adjustLine(targetColumn.lineNumber);
6332
+ insertIdx = adjColLine;
6333
+ } else {
6334
+ const targetCards = targetColumn.cards.filter((c) => c.id !== cardId);
6335
+ const clampedIdx = Math.min(targetIndex, targetCards.length);
6336
+ const precedingCard = targetCards[clampedIdx - 1];
6337
+ if (!precedingCard) {
6338
+ const adjColLine = adjustLine(targetColumn.lineNumber);
6339
+ insertIdx = adjColLine;
6340
+ } else {
6341
+ const adjEndLine = adjustLine(precedingCard.endLineNumber);
6342
+ insertIdx = adjEndLine;
6343
+ }
6344
+ }
6345
+ const result = [
6346
+ ...withoutCard.slice(0, insertIdx),
6347
+ ...cardLines,
6348
+ ...withoutCard.slice(insertIdx)
6349
+ ];
6350
+ return result.join("\n");
6351
+ }
6352
+ function computeCardArchive(content, parsed, cardId) {
6353
+ let sourceCard = null;
6354
+ for (const col of parsed.columns) {
6355
+ for (const card of col.cards) {
6356
+ if (card.id === cardId) {
6357
+ sourceCard = card;
6358
+ break;
6359
+ }
6360
+ }
6361
+ if (sourceCard) break;
6362
+ }
6363
+ if (!sourceCard) return null;
6364
+ const lines = content.split("\n");
6365
+ const startIdx = sourceCard.lineNumber - 1;
6366
+ const endIdx = sourceCard.endLineNumber - 1;
6367
+ const cardLines = lines.slice(startIdx, endIdx + 1);
6368
+ const withoutCard = [
6369
+ ...lines.slice(0, startIdx),
6370
+ ...lines.slice(endIdx + 1)
6371
+ ];
6372
+ const archiveCol = parsed.columns.find(
6373
+ (c) => c.name.toLowerCase() === ARCHIVE_COLUMN_NAME
6374
+ );
6375
+ if (archiveCol) {
6376
+ const removedCount = endIdx - startIdx + 1;
6377
+ let archiveEndLine = archiveCol.lineNumber;
6378
+ if (archiveCol.cards.length > 0) {
6379
+ const lastCard = archiveCol.cards[archiveCol.cards.length - 1];
6380
+ archiveEndLine = lastCard.endLineNumber;
6381
+ }
6382
+ if (archiveEndLine > endIdx + 1) {
6383
+ archiveEndLine -= removedCount;
6384
+ }
6385
+ const insertIdx = archiveEndLine;
6386
+ return [
6387
+ ...withoutCard.slice(0, insertIdx),
6388
+ ...cardLines,
6389
+ ...withoutCard.slice(insertIdx)
6390
+ ].join("\n");
6391
+ } else {
6392
+ const trimmedEnd = withoutCard.length > 0 && withoutCard[withoutCard.length - 1].trim() === "" ? withoutCard : [...withoutCard, ""];
6393
+ return [
6394
+ ...trimmedEnd,
6395
+ "== Archive ==",
6396
+ ...cardLines
6397
+ ].join("\n");
6398
+ }
6399
+ }
6400
+ function isArchiveColumn(name) {
6401
+ return name.toLowerCase() === ARCHIVE_COLUMN_NAME;
6402
+ }
6403
+ var ARCHIVE_COLUMN_NAME;
6404
+ var init_mutations = __esm({
6405
+ "src/kanban/mutations.ts"() {
6406
+ "use strict";
6407
+ ARCHIVE_COLUMN_NAME = "archive";
6408
+ }
6409
+ });
6410
+
6411
+ // src/kanban/renderer.ts
6412
+ var renderer_exports2 = {};
6413
+ __export(renderer_exports2, {
6414
+ renderKanban: () => renderKanban,
6415
+ renderKanbanForExport: () => renderKanbanForExport
6416
+ });
6417
+ import * as d3Selection2 from "d3-selection";
6418
+ function mix2(a, b, pct) {
6419
+ const parse = (h) => {
6420
+ const r = h.replace("#", "");
6421
+ const f = r.length === 3 ? r[0] + r[0] + r[1] + r[1] + r[2] + r[2] : r;
6422
+ return [
6423
+ parseInt(f.substring(0, 2), 16),
6424
+ parseInt(f.substring(2, 4), 16),
6425
+ parseInt(f.substring(4, 6), 16)
6426
+ ];
6427
+ };
6428
+ const [ar, ag, ab] = parse(a);
6429
+ const [br, bg, bb] = parse(b);
6430
+ const t = pct / 100;
6431
+ const c = (x, y) => Math.round(x * t + y * (1 - t)).toString(16).padStart(2, "0");
6432
+ return `#${c(ar, br)}${c(ag, bg)}${c(ab, bb)}`;
6433
+ }
6434
+ function resolveCardTagMeta(card, tagGroups) {
6435
+ const meta = [];
6436
+ for (const group of tagGroups) {
6437
+ const tagValue = card.tags[group.name.toLowerCase()];
6438
+ const value = tagValue ?? group.defaultValue;
6439
+ if (!value) continue;
6440
+ const entry = group.entries.find(
6441
+ (e) => e.value.toLowerCase() === value.toLowerCase()
6442
+ );
6443
+ meta.push({ label: group.name, value, color: entry?.color });
6444
+ }
6445
+ return meta;
6446
+ }
6447
+ function resolveCardTagColor(card, tagGroups, activeTagGroup) {
6448
+ if (!activeTagGroup) return card.color;
6449
+ const group = tagGroups.find(
6450
+ (g) => g.name.toLowerCase() === activeTagGroup.toLowerCase()
6451
+ );
6452
+ if (!group) return card.color;
6453
+ const tagValue = card.tags[group.name.toLowerCase()];
6454
+ const value = tagValue ?? group.defaultValue;
6455
+ if (!value) return void 0;
6456
+ const entry = group.entries.find(
6457
+ (e) => e.value.toLowerCase() === value.toLowerCase()
6458
+ );
6459
+ return entry?.color;
6460
+ }
6461
+ function computeLayout(parsed, _palette) {
6462
+ const hasHeader = !!parsed.title || parsed.tagGroups.length > 0;
6463
+ const headerHeight = hasHeader ? Math.max(TITLE_HEIGHT2, LEGEND_HEIGHT3) + 8 : 0;
6464
+ const startY = DIAGRAM_PADDING2 + headerHeight;
6465
+ const charWidth = CARD_TITLE_FONT_SIZE * 0.6;
6466
+ const columnLayouts = [];
6467
+ let maxColumnHeight = 0;
6468
+ const visibleColumns = parsed.columns.filter((c) => !isArchiveColumn(c.name));
6469
+ for (const col of visibleColumns) {
6470
+ let maxCardTextWidth = col.name.length * (COLUMN_HEADER_FONT_SIZE * 0.65);
6471
+ const cardLayouts = [];
6472
+ let cardY = COLUMN_HEADER_HEIGHT + COLUMN_PADDING;
6473
+ for (const card of col.cards) {
6474
+ const titleWidth = card.title.length * charWidth;
6475
+ maxCardTextWidth = Math.max(
6476
+ maxCardTextWidth,
6477
+ titleWidth + CARD_PADDING_X * 2
6478
+ );
6479
+ const tagMeta = resolveCardTagMeta(card, parsed.tagGroups);
6480
+ const metaCount = tagMeta.length + card.details.length;
6481
+ const metaHeight = metaCount > 0 ? CARD_SEPARATOR_GAP + 1 + CARD_PADDING_Y + metaCount * CARD_META_LINE_HEIGHT : 0;
6482
+ const cardHeight = CARD_HEADER_HEIGHT + CARD_PADDING_Y + metaHeight;
6483
+ for (const m of tagMeta) {
6484
+ const metaW = (m.label.length + 2 + m.value.length) * CARD_META_FONT_SIZE * 0.6 + CARD_PADDING_X * 2;
6485
+ maxCardTextWidth = Math.max(maxCardTextWidth, metaW);
6486
+ }
6487
+ cardLayouts.push({
6488
+ x: COLUMN_PADDING,
6489
+ y: cardY,
6490
+ width: 0,
6491
+ // set after column width computed
6492
+ height: cardHeight,
6493
+ card
6494
+ });
6495
+ cardY += cardHeight + CARD_GAP;
6496
+ }
6497
+ const colWidth = Math.max(COLUMN_MIN_WIDTH, maxCardTextWidth + COLUMN_PADDING * 2);
6498
+ for (const cl of cardLayouts) {
6499
+ cl.width = colWidth - COLUMN_PADDING * 2;
6500
+ }
6501
+ const colHeight = cardY + COLUMN_PADDING;
6502
+ maxColumnHeight = Math.max(maxColumnHeight, colHeight);
6503
+ columnLayouts.push({
6504
+ x: 0,
6505
+ // set below
6506
+ y: startY,
6507
+ width: colWidth,
6508
+ height: colHeight,
6509
+ column: col,
6510
+ cardLayouts
6511
+ });
6512
+ }
6513
+ let currentX = DIAGRAM_PADDING2;
6514
+ for (const cl of columnLayouts) {
6515
+ cl.x = currentX;
6516
+ cl.height = maxColumnHeight;
6517
+ currentX += cl.width + COLUMN_GAP;
6518
+ }
6519
+ const totalWidth = currentX - COLUMN_GAP + DIAGRAM_PADDING2;
6520
+ const totalHeight = startY + maxColumnHeight + DIAGRAM_PADDING2;
6521
+ return { columns: columnLayouts, totalWidth, totalHeight };
6522
+ }
6523
+ function renderKanban(container, parsed, palette, isDark, _onNavigateToLine, exportDims, activeTagGroup) {
6524
+ const layout = computeLayout(parsed, palette);
6525
+ const width = exportDims?.width ?? layout.totalWidth;
6526
+ const height = exportDims?.height ?? layout.totalHeight;
6527
+ container.innerHTML = "";
6528
+ 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);
6529
+ if (parsed.title) {
6530
+ 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);
6531
+ }
6532
+ if (parsed.tagGroups.length > 0) {
6533
+ const legendY = DIAGRAM_PADDING2;
6534
+ const titleTextWidth = parsed.title ? parsed.title.length * TITLE_FONT_SIZE2 * 0.6 + 16 : 0;
6535
+ let legendX = DIAGRAM_PADDING2 + titleTextWidth;
6536
+ const groupBg = mix2(palette.surface, palette.bg, isDark ? 35 : 20);
6537
+ const capsulePad = 4;
6538
+ for (const group of parsed.tagGroups) {
6539
+ const isActive = activeTagGroup?.toLowerCase() === group.name.toLowerCase();
6540
+ if (activeTagGroup != null && !isActive) continue;
6541
+ const pillTextWidth = group.name.length * LEGEND_FONT_SIZE * 0.6;
6542
+ const pillWidth = pillTextWidth + 16;
6543
+ let capsuleContentWidth = pillWidth;
6544
+ if (isActive) {
6545
+ capsuleContentWidth += 4;
6546
+ for (const entry of group.entries) {
6547
+ capsuleContentWidth += LEGEND_DOT_R3 * 2 + 4 + entry.value.length * LEGEND_ENTRY_FONT_SIZE2 * 0.6 + 8;
6548
+ }
6549
+ }
6550
+ const capsuleWidth = capsuleContentWidth + capsulePad * 2;
6551
+ if (isActive) {
6552
+ svg.append("rect").attr("x", legendX).attr("y", legendY).attr("width", capsuleWidth).attr("height", LEGEND_HEIGHT3).attr("rx", LEGEND_HEIGHT3 / 2).attr("fill", groupBg);
6553
+ }
6554
+ const pillX = legendX + (isActive ? capsulePad : 0);
6555
+ const pillBg = isActive ? palette.bg : groupBg;
6556
+ 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());
6557
+ if (isActive) {
6558
+ 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);
6559
+ }
6560
+ 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);
6561
+ if (isActive) {
6562
+ let entryX = pillX + pillWidth + 4;
6563
+ for (const entry of group.entries) {
6564
+ svg.append("circle").attr("cx", entryX + LEGEND_DOT_R3).attr("cy", legendY + LEGEND_HEIGHT3 / 2).attr("r", LEGEND_DOT_R3).attr("fill", entry.color);
6565
+ const entryTextX = entryX + LEGEND_DOT_R3 * 2 + 4;
6566
+ 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);
6567
+ entryX = entryTextX + entry.value.length * LEGEND_ENTRY_FONT_SIZE2 * 0.6 + 8;
6568
+ }
6569
+ legendX += capsuleWidth + 12;
6570
+ } else {
6571
+ legendX += pillWidth + 12;
6572
+ }
6573
+ }
6574
+ }
6575
+ const defaultColBg = isDark ? mix2(palette.surface, palette.bg, 50) : mix2(palette.surface, palette.bg, 30);
6576
+ const defaultColHeaderBg = isDark ? mix2(palette.surface, palette.bg, 70) : mix2(palette.surface, palette.bg, 50);
6577
+ const cardBaseBg = isDark ? palette.surface : palette.bg;
6578
+ for (const colLayout of layout.columns) {
6579
+ const col = colLayout.column;
6580
+ const g = svg.append("g").attr("class", "kanban-column").attr("data-column-id", col.id).attr("data-line-number", col.lineNumber);
6581
+ const thisColBg = defaultColBg;
6582
+ const thisColHeaderBg = col.color ? mix2(col.color, palette.bg, 25) : defaultColHeaderBg;
6583
+ 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);
6584
+ 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);
6585
+ g.append("text").attr("x", colLayout.x + COLUMN_PADDING).attr(
6586
+ "y",
6587
+ colLayout.y + COLUMN_HEADER_HEIGHT / 2 + COLUMN_HEADER_FONT_SIZE / 2 - 2
6588
+ ).attr("font-size", COLUMN_HEADER_FONT_SIZE).attr("font-weight", "bold").attr("fill", palette.text).text(col.name);
6589
+ if (col.wipLimit != null) {
6590
+ const wipExceeded = col.cards.length > col.wipLimit;
6591
+ const badgeText = `${col.cards.length}/${col.wipLimit}`;
6592
+ const nameWidth = col.name.length * COLUMN_HEADER_FONT_SIZE * 0.65;
6593
+ g.append("text").attr("x", colLayout.x + COLUMN_PADDING + nameWidth + 8).attr(
6594
+ "y",
6595
+ colLayout.y + COLUMN_HEADER_HEIGHT / 2 + WIP_FONT_SIZE / 2 - 1
6596
+ ).attr("font-size", WIP_FONT_SIZE).attr("fill", wipExceeded ? palette.colors.red : palette.textMuted).attr("font-weight", wipExceeded ? "bold" : "normal").text(badgeText);
6597
+ }
6598
+ for (const cardLayout of colLayout.cardLayouts) {
6599
+ const card = cardLayout.card;
6600
+ const resolvedColor = resolveCardTagColor(card, parsed.tagGroups, activeTagGroup ?? null);
6601
+ const tagMeta = resolveCardTagMeta(card, parsed.tagGroups);
6602
+ const hasMeta = tagMeta.length > 0 || card.details.length > 0;
6603
+ const cardFill = resolvedColor ? mix2(resolvedColor, cardBaseBg, 15) : mix2(palette.primary, cardBaseBg, 15);
6604
+ const cardStroke = resolvedColor ?? palette.textMuted;
6605
+ const cg = g.append("g").attr("class", "kanban-card").attr("data-card-id", card.id).attr("data-line-number", card.lineNumber);
6606
+ const cx = colLayout.x + cardLayout.x;
6607
+ const cy = colLayout.y + cardLayout.y;
6608
+ 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);
6609
+ 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);
6610
+ if (hasMeta) {
6611
+ const separatorY = cy + CARD_HEADER_HEIGHT;
6612
+ 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);
6613
+ let metaY = separatorY + CARD_SEPARATOR_GAP + CARD_META_FONT_SIZE;
6614
+ for (const meta of tagMeta) {
6615
+ 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}: `);
6616
+ const labelWidth = (meta.label.length + 2) * CARD_META_FONT_SIZE * 0.6;
6617
+ 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);
6618
+ metaY += CARD_META_LINE_HEIGHT;
6619
+ }
6620
+ for (const detail of card.details) {
6621
+ 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);
6622
+ metaY += CARD_META_LINE_HEIGHT;
6623
+ }
6624
+ }
6625
+ }
6626
+ }
6627
+ }
6628
+ function renderKanbanForExport(content, theme, palette) {
6629
+ const parsed = parseKanban(content, palette);
6630
+ if (parsed.error || parsed.columns.length === 0) return "";
6631
+ const isDark = theme === "dark";
6632
+ const layout = computeLayout(parsed, palette);
6633
+ const container = document.createElement("div");
6634
+ renderKanban(container, parsed, palette, isDark, void 0, {
6635
+ width: layout.totalWidth,
6636
+ height: layout.totalHeight
6637
+ });
6638
+ const svgEl = container.querySelector("svg");
6639
+ return svgEl?.outerHTML ?? "";
6640
+ }
6641
+ 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;
6642
+ var init_renderer2 = __esm({
6643
+ "src/kanban/renderer.ts"() {
6644
+ "use strict";
6645
+ init_fonts();
6646
+ init_parser5();
6647
+ init_mutations();
6648
+ DIAGRAM_PADDING2 = 20;
6649
+ COLUMN_GAP = 16;
6650
+ COLUMN_HEADER_HEIGHT = 36;
6651
+ COLUMN_PADDING = 12;
6652
+ COLUMN_MIN_WIDTH = 200;
6653
+ CARD_HEADER_HEIGHT = 24;
6654
+ CARD_META_LINE_HEIGHT = 14;
6655
+ CARD_SEPARATOR_GAP = 4;
6656
+ CARD_GAP = 8;
6657
+ CARD_RADIUS2 = 6;
6658
+ CARD_PADDING_X = 10;
6659
+ CARD_PADDING_Y = 6;
6660
+ CARD_STROKE_WIDTH = 1.5;
6661
+ TITLE_HEIGHT2 = 30;
6662
+ TITLE_FONT_SIZE2 = 18;
6663
+ COLUMN_HEADER_FONT_SIZE = 13;
6664
+ CARD_TITLE_FONT_SIZE = 12;
6665
+ CARD_META_FONT_SIZE = 10;
6666
+ WIP_FONT_SIZE = 10;
6667
+ COLUMN_RADIUS = 8;
6668
+ COLUMN_HEADER_RADIUS = 8;
6669
+ LEGEND_HEIGHT3 = 28;
6025
6670
  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;
6671
+ LEGEND_DOT_R3 = 4;
6672
+ LEGEND_ENTRY_FONT_SIZE2 = 10;
6034
6673
  }
6035
6674
  });
6036
6675
 
@@ -6163,14 +6802,14 @@ var init_layout2 = __esm({
6163
6802
  });
6164
6803
 
6165
6804
  // src/class/renderer.ts
6166
- var renderer_exports2 = {};
6167
- __export(renderer_exports2, {
6805
+ var renderer_exports3 = {};
6806
+ __export(renderer_exports3, {
6168
6807
  renderClassDiagram: () => renderClassDiagram,
6169
6808
  renderClassDiagramForExport: () => renderClassDiagramForExport
6170
6809
  });
6171
- import * as d3Selection2 from "d3-selection";
6810
+ import * as d3Selection3 from "d3-selection";
6172
6811
  import * as d3Shape from "d3-shape";
6173
- function mix2(a, b, pct) {
6812
+ function mix3(a, b, pct) {
6174
6813
  const parse = (h) => {
6175
6814
  const r = h.replace("#", "");
6176
6815
  const f = r.length === 3 ? r[0] + r[0] + r[1] + r[1] + r[2] + r[2] : r;
@@ -6195,7 +6834,7 @@ function modifierColor(modifier, palette, colorOff) {
6195
6834
  }
6196
6835
  function nodeFill2(palette, isDark, modifier, nodeColor, colorOff) {
6197
6836
  const color = nodeColor ?? modifierColor(modifier, palette, colorOff);
6198
- return mix2(color, isDark ? palette.surface : palette.bg, 20);
6837
+ return mix3(color, isDark ? palette.surface : palette.bg, 20);
6199
6838
  }
6200
6839
  function nodeStroke2(palette, modifier, nodeColor, colorOff) {
6201
6840
  return nodeColor ?? modifierColor(modifier, palette, colorOff);
@@ -6233,7 +6872,7 @@ function isSourceMarker(type) {
6233
6872
  return type === "composes" || type === "aggregates";
6234
6873
  }
6235
6874
  function renderClassDiagram(container, parsed, layout, palette, isDark, onClickItem, exportDims) {
6236
- d3Selection2.select(container).selectAll(":not([data-d3-tooltip])").remove();
6875
+ d3Selection3.select(container).selectAll(":not([data-d3-tooltip])").remove();
6237
6876
  const width = exportDims?.width ?? container.clientWidth;
6238
6877
  const height = exportDims?.height ?? container.clientHeight;
6239
6878
  if (width <= 0 || height <= 0) return;
@@ -6241,14 +6880,14 @@ function renderClassDiagram(container, parsed, layout, palette, isDark, onClickI
6241
6880
  const diagramW = layout.width;
6242
6881
  const diagramH = layout.height;
6243
6882
  const availH = height - titleHeight;
6244
- const scaleX = (width - DIAGRAM_PADDING2 * 2) / diagramW;
6245
- const scaleY = (availH - DIAGRAM_PADDING2 * 2) / diagramH;
6883
+ const scaleX = (width - DIAGRAM_PADDING3 * 2) / diagramW;
6884
+ const scaleY = (availH - DIAGRAM_PADDING3 * 2) / diagramH;
6246
6885
  const scale = Math.min(MAX_SCALE2, scaleX, scaleY);
6247
6886
  const scaledW = diagramW * scale;
6248
6887
  const scaledH = diagramH * scale;
6249
6888
  const offsetX = (width - scaledW) / 2;
6250
6889
  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);
6890
+ const svg = d3Selection3.select(container).append("svg").attr("width", width).attr("height", height).style("font-family", FONT_FAMILY);
6252
6891
  const defs = svg.append("defs");
6253
6892
  const AW = 12;
6254
6893
  const AH = 8;
@@ -6266,9 +6905,9 @@ function renderClassDiagram(container, parsed, layout, palette, isDark, onClickI
6266
6905
  titleEl.attr("data-line-number", parsed.titleLineNumber);
6267
6906
  if (onClickItem) {
6268
6907
  titleEl.on("click", () => onClickItem(parsed.titleLineNumber)).on("mouseenter", function() {
6269
- d3Selection2.select(this).attr("opacity", 0.7);
6908
+ d3Selection3.select(this).attr("opacity", 0.7);
6270
6909
  }).on("mouseleave", function() {
6271
- d3Selection2.select(this).attr("opacity", 1);
6910
+ d3Selection3.select(this).attr("opacity", 1);
6272
6911
  });
6273
6912
  }
6274
6913
  }
@@ -6379,8 +7018,8 @@ function renderClassDiagramForExport(content, theme, palette) {
6379
7018
  const layout = layoutClassDiagram(parsed);
6380
7019
  const isDark = theme === "dark";
6381
7020
  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);
7021
+ const exportWidth = layout.width + DIAGRAM_PADDING3 * 2;
7022
+ const exportHeight = layout.height + DIAGRAM_PADDING3 * 2 + (parsed.title ? 40 : 0);
6384
7023
  container.style.width = `${exportWidth}px`;
6385
7024
  container.style.height = `${exportHeight}px`;
6386
7025
  container.style.position = "absolute";
@@ -6408,14 +7047,14 @@ function renderClassDiagramForExport(content, theme, palette) {
6408
7047
  document.body.removeChild(container);
6409
7048
  }
6410
7049
  }
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({
7050
+ 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;
7051
+ var init_renderer3 = __esm({
6413
7052
  "src/class/renderer.ts"() {
6414
7053
  "use strict";
6415
7054
  init_fonts();
6416
7055
  init_parser2();
6417
7056
  init_layout2();
6418
- DIAGRAM_PADDING2 = 20;
7057
+ DIAGRAM_PADDING3 = 20;
6419
7058
  MAX_SCALE2 = 3;
6420
7059
  CLASS_FONT_SIZE = 13;
6421
7060
  MEMBER_FONT_SIZE = 11;
@@ -6570,14 +7209,14 @@ var init_layout3 = __esm({
6570
7209
  });
6571
7210
 
6572
7211
  // src/er/renderer.ts
6573
- var renderer_exports3 = {};
6574
- __export(renderer_exports3, {
7212
+ var renderer_exports4 = {};
7213
+ __export(renderer_exports4, {
6575
7214
  renderERDiagram: () => renderERDiagram,
6576
7215
  renderERDiagramForExport: () => renderERDiagramForExport
6577
7216
  });
6578
- import * as d3Selection3 from "d3-selection";
7217
+ import * as d3Selection4 from "d3-selection";
6579
7218
  import * as d3Shape2 from "d3-shape";
6580
- function mix3(a, b, pct) {
7219
+ function mix4(a, b, pct) {
6581
7220
  const parse = (h) => {
6582
7221
  const r = h.replace("#", "");
6583
7222
  const f = r.length === 3 ? r[0] + r[0] + r[1] + r[1] + r[2] + r[2] : r;
@@ -6648,7 +7287,7 @@ function drawCardinality(g, point, prevPoint, cardinality, color, useLabels) {
6648
7287
  }
6649
7288
  }
6650
7289
  function renderERDiagram(container, parsed, layout, palette, isDark, onClickItem, exportDims) {
6651
- d3Selection3.select(container).selectAll(":not([data-d3-tooltip])").remove();
7290
+ d3Selection4.select(container).selectAll(":not([data-d3-tooltip])").remove();
6652
7291
  const width = exportDims?.width ?? container.clientWidth;
6653
7292
  const height = exportDims?.height ?? container.clientHeight;
6654
7293
  if (width <= 0 || height <= 0) return;
@@ -6656,23 +7295,23 @@ function renderERDiagram(container, parsed, layout, palette, isDark, onClickItem
6656
7295
  const diagramW = layout.width;
6657
7296
  const diagramH = layout.height;
6658
7297
  const availH = height - titleHeight;
6659
- const scaleX = (width - DIAGRAM_PADDING3 * 2) / diagramW;
6660
- const scaleY = (availH - DIAGRAM_PADDING3 * 2) / diagramH;
7298
+ const scaleX = (width - DIAGRAM_PADDING4 * 2) / diagramW;
7299
+ const scaleY = (availH - DIAGRAM_PADDING4 * 2) / diagramH;
6661
7300
  const scale = Math.min(MAX_SCALE3, scaleX, scaleY);
6662
7301
  const scaledW = diagramW * scale;
6663
7302
  const scaledH = diagramH * scale;
6664
7303
  const offsetX = (width - scaledW) / 2;
6665
7304
  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);
7305
+ const svg = d3Selection4.select(container).append("svg").attr("width", width).attr("height", height).style("font-family", FONT_FAMILY);
6667
7306
  if (parsed.title) {
6668
7307
  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
7308
  if (parsed.titleLineNumber) {
6670
7309
  titleEl.attr("data-line-number", parsed.titleLineNumber);
6671
7310
  if (onClickItem) {
6672
7311
  titleEl.on("click", () => onClickItem(parsed.titleLineNumber)).on("mouseenter", function() {
6673
- d3Selection3.select(this).attr("opacity", 0.7);
7312
+ d3Selection4.select(this).attr("opacity", 0.7);
6674
7313
  }).on("mouseleave", function() {
6675
- d3Selection3.select(this).attr("opacity", 1);
7314
+ d3Selection4.select(this).attr("opacity", 1);
6676
7315
  });
6677
7316
  }
6678
7317
  }
@@ -6726,7 +7365,7 @@ function renderERDiagram(container, parsed, layout, palette, isDark, onClickItem
6726
7365
  }
6727
7366
  const w = node.width;
6728
7367
  const h = node.height;
6729
- const fill2 = mix3(nodeColor, isDark ? palette.surface : palette.bg, 20);
7368
+ const fill2 = mix4(nodeColor, isDark ? palette.surface : palette.bg, 20);
6730
7369
  const stroke2 = nodeColor;
6731
7370
  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
7371
  let yPos = -h / 2;
@@ -6757,8 +7396,8 @@ function renderERDiagramForExport(content, theme, palette) {
6757
7396
  const layout = layoutERDiagram(parsed);
6758
7397
  const isDark = theme === "dark";
6759
7398
  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);
7399
+ const exportWidth = layout.width + DIAGRAM_PADDING4 * 2;
7400
+ const exportHeight = layout.height + DIAGRAM_PADDING4 * 2 + (parsed.title ? 40 : 0);
6762
7401
  container.style.width = `${exportWidth}px`;
6763
7402
  container.style.height = `${exportHeight}px`;
6764
7403
  container.style.position = "absolute";
@@ -6786,15 +7425,15 @@ function renderERDiagramForExport(content, theme, palette) {
6786
7425
  document.body.removeChild(container);
6787
7426
  }
6788
7427
  }
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({
7428
+ 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;
7429
+ var init_renderer4 = __esm({
6791
7430
  "src/er/renderer.ts"() {
6792
7431
  "use strict";
6793
7432
  init_fonts();
6794
7433
  init_palettes();
6795
7434
  init_parser3();
6796
7435
  init_layout3();
6797
- DIAGRAM_PADDING3 = 20;
7436
+ DIAGRAM_PADDING4 = 20;
6798
7437
  MAX_SCALE3 = 3;
6799
7438
  TABLE_FONT_SIZE = 13;
6800
7439
  COLUMN_FONT_SIZE = 11;
@@ -6969,9 +7608,9 @@ __export(flowchart_renderer_exports, {
6969
7608
  renderFlowchart: () => renderFlowchart,
6970
7609
  renderFlowchartForExport: () => renderFlowchartForExport
6971
7610
  });
6972
- import * as d3Selection4 from "d3-selection";
7611
+ import * as d3Selection5 from "d3-selection";
6973
7612
  import * as d3Shape3 from "d3-shape";
6974
- function mix4(a, b, pct) {
7613
+ function mix5(a, b, pct) {
6975
7614
  const parse = (h) => {
6976
7615
  const r = h.replace("#", "");
6977
7616
  const f = r.length === 3 ? r[0] + r[0] + r[1] + r[1] + r[2] + r[2] : r;
@@ -7000,7 +7639,7 @@ function shapeDefaultColor(shape, palette, isEndTerminal, colorOff) {
7000
7639
  }
7001
7640
  function nodeFill3(palette, isDark, shape, nodeColor, isEndTerminal, colorOff) {
7002
7641
  const color = nodeColor ?? shapeDefaultColor(shape, palette, isEndTerminal, colorOff);
7003
- return mix4(color, isDark ? palette.surface : palette.bg, 25);
7642
+ return mix5(color, isDark ? palette.surface : palette.bg, 25);
7004
7643
  }
7005
7644
  function nodeStroke3(palette, shape, nodeColor, isEndTerminal, colorOff) {
7006
7645
  return nodeColor ?? shapeDefaultColor(shape, palette, isEndTerminal, colorOff);
@@ -7095,7 +7734,7 @@ function renderNodeShape(g, node, palette, isDark, endTerminalIds, colorOff) {
7095
7734
  }
7096
7735
  }
7097
7736
  function renderFlowchart(container, graph, layout, palette, isDark, onClickItem, exportDims) {
7098
- d3Selection4.select(container).selectAll(":not([data-d3-tooltip])").remove();
7737
+ d3Selection5.select(container).selectAll(":not([data-d3-tooltip])").remove();
7099
7738
  const width = exportDims?.width ?? container.clientWidth;
7100
7739
  const height = exportDims?.height ?? container.clientHeight;
7101
7740
  if (width <= 0 || height <= 0) return;
@@ -7103,14 +7742,14 @@ function renderFlowchart(container, graph, layout, palette, isDark, onClickItem,
7103
7742
  const diagramW = layout.width;
7104
7743
  const diagramH = layout.height;
7105
7744
  const availH = height - titleHeight;
7106
- const scaleX = (width - DIAGRAM_PADDING4 * 2) / diagramW;
7107
- const scaleY = (availH - DIAGRAM_PADDING4 * 2) / diagramH;
7745
+ const scaleX = (width - DIAGRAM_PADDING5 * 2) / diagramW;
7746
+ const scaleY = (availH - DIAGRAM_PADDING5 * 2) / diagramH;
7108
7747
  const scale = Math.min(MAX_SCALE4, scaleX, scaleY);
7109
7748
  const scaledW = diagramW * scale;
7110
7749
  const scaledH = diagramH * scale;
7111
7750
  const offsetX = (width - scaledW) / 2;
7112
7751
  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);
7752
+ const svg = d3Selection5.select(container).append("svg").attr("width", width).attr("height", height).style("font-family", FONT_FAMILY);
7114
7753
  const defs = svg.append("defs");
7115
7754
  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
7755
  const edgeColors = /* @__PURE__ */ new Set();
@@ -7127,9 +7766,9 @@ function renderFlowchart(container, graph, layout, palette, isDark, onClickItem,
7127
7766
  titleEl.attr("data-line-number", graph.titleLineNumber);
7128
7767
  if (onClickItem) {
7129
7768
  titleEl.on("click", () => onClickItem(graph.titleLineNumber)).on("mouseenter", function() {
7130
- d3Selection4.select(this).attr("opacity", 0.7);
7769
+ d3Selection5.select(this).attr("opacity", 0.7);
7131
7770
  }).on("mouseleave", function() {
7132
- d3Selection4.select(this).attr("opacity", 1);
7771
+ d3Selection5.select(this).attr("opacity", 1);
7133
7772
  });
7134
7773
  }
7135
7774
  }
@@ -7141,7 +7780,7 @@ function renderFlowchart(container, graph, layout, palette, isDark, onClickItem,
7141
7780
  const gy = group.y - GROUP_EXTRA_PADDING - GROUP_LABEL_FONT_SIZE - 4;
7142
7781
  const gw = group.width + GROUP_EXTRA_PADDING * 2;
7143
7782
  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);
7783
+ const fillColor = group.color ? mix5(group.color, isDark ? palette.surface : palette.bg, 10) : isDark ? palette.surface : mix5(palette.border, palette.bg, 30);
7145
7784
  const strokeColor = group.color ?? palette.textMuted;
7146
7785
  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
7786
  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 +7830,13 @@ function renderFlowchartForExport(content, theme, palette) {
7191
7830
  const layout = layoutGraph(parsed);
7192
7831
  const isDark = theme === "dark";
7193
7832
  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`;
7833
+ container.style.width = `${layout.width + DIAGRAM_PADDING5 * 2}px`;
7834
+ container.style.height = `${layout.height + DIAGRAM_PADDING5 * 2 + (parsed.title ? 40 : 0)}px`;
7196
7835
  container.style.position = "absolute";
7197
7836
  container.style.left = "-9999px";
7198
7837
  document.body.appendChild(container);
7199
- const exportWidth = layout.width + DIAGRAM_PADDING4 * 2;
7200
- const exportHeight = layout.height + DIAGRAM_PADDING4 * 2 + (parsed.title ? 40 : 0);
7838
+ const exportWidth = layout.width + DIAGRAM_PADDING5 * 2;
7839
+ const exportHeight = layout.height + DIAGRAM_PADDING5 * 2 + (parsed.title ? 40 : 0);
7201
7840
  try {
7202
7841
  renderFlowchart(
7203
7842
  container,
@@ -7220,14 +7859,14 @@ function renderFlowchartForExport(content, theme, palette) {
7220
7859
  document.body.removeChild(container);
7221
7860
  }
7222
7861
  }
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;
7862
+ 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
7863
  var init_flowchart_renderer = __esm({
7225
7864
  "src/graph/flowchart-renderer.ts"() {
7226
7865
  "use strict";
7227
7866
  init_fonts();
7228
7867
  init_flowchart_parser();
7229
7868
  init_layout4();
7230
- DIAGRAM_PADDING4 = 20;
7869
+ DIAGRAM_PADDING5 = 20;
7231
7870
  MAX_SCALE4 = 3;
7232
7871
  NODE_FONT_SIZE = 13;
7233
7872
  EDGE_LABEL_FONT_SIZE3 = 11;
@@ -7245,8 +7884,8 @@ var init_flowchart_renderer = __esm({
7245
7884
  });
7246
7885
 
7247
7886
  // src/sequence/renderer.ts
7248
- var renderer_exports4 = {};
7249
- __export(renderer_exports4, {
7887
+ var renderer_exports5 = {};
7888
+ __export(renderer_exports5, {
7250
7889
  applyGroupOrdering: () => applyGroupOrdering,
7251
7890
  applyPositionOverrides: () => applyPositionOverrides,
7252
7891
  buildNoteMessageMap: () => buildNoteMessageMap,
@@ -7257,7 +7896,7 @@ __export(renderer_exports4, {
7257
7896
  renderSequenceDiagram: () => renderSequenceDiagram,
7258
7897
  truncateBareUrl: () => truncateBareUrl
7259
7898
  });
7260
- import * as d3Selection5 from "d3-selection";
7899
+ import * as d3Selection6 from "d3-selection";
7261
7900
  function parseInlineMarkdown(text) {
7262
7901
  const spans = [];
7263
7902
  const regex = /\*\*(.+?)\*\*|__(.+?)__|\*(.+?)\*|_(.+?)_|`(.+?)`|\[(.+?)\]\((.+?)\)|(https?:\/\/[^\s)>\]]+|www\.[^\s)>\]]+)|([^*_`[]+?(?=https?:\/\/|www\.|$)|[^*_`[]+)/g;
@@ -7323,7 +7962,7 @@ function wrapTextLines(text, maxChars) {
7323
7962
  }
7324
7963
  return wrapped;
7325
7964
  }
7326
- function mix5(a, b, pct) {
7965
+ function mix6(a, b, pct) {
7327
7966
  const parse = (h) => {
7328
7967
  const r = h.replace("#", "");
7329
7968
  const f = r.length === 3 ? r[0] + r[0] + r[1] + r[1] + r[2] + r[2] : r;
@@ -7607,7 +8246,7 @@ function applyGroupOrdering(participants, groups) {
7607
8246
  return result;
7608
8247
  }
7609
8248
  function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateToLine, options) {
7610
- d3Selection5.select(container).selectAll("*").remove();
8249
+ d3Selection6.select(container).selectAll("*").remove();
7611
8250
  const { title, messages, elements, groups, options: parsedOptions } = parsed;
7612
8251
  const collapsedSections = options?.collapsedSections;
7613
8252
  const expandedNoteLines = options?.expandedNoteLines;
@@ -7647,7 +8286,7 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
7647
8286
  }
7648
8287
  msgToLastStep.set(step.messageIndex, si);
7649
8288
  });
7650
- const findAssociatedFirstStep = (note) => {
8289
+ const findAssociatedLastStep = (note) => {
7651
8290
  let closestMsgIndex = -1;
7652
8291
  let closestLine = -1;
7653
8292
  for (let mi = 0; mi < messages.length; mi++) {
@@ -7660,7 +8299,7 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
7660
8299
  return -1;
7661
8300
  }
7662
8301
  if (closestMsgIndex < 0) return -1;
7663
- return msgToFirstStep.get(closestMsgIndex) ?? -1;
8302
+ return msgToLastStep.get(closestMsgIndex) ?? -1;
7664
8303
  };
7665
8304
  const findFirstMsgIndex = (els) => {
7666
8305
  for (const el of els) {
@@ -7867,7 +8506,7 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
7867
8506
  const GROUP_PADDING_TOP = 22;
7868
8507
  const GROUP_PADDING_BOTTOM = 8;
7869
8508
  const GROUP_LABEL_SIZE = 11;
7870
- const titleOffset = title ? TITLE_HEIGHT2 : 0;
8509
+ const titleOffset = title ? TITLE_HEIGHT3 : 0;
7871
8510
  const groupOffset = groups.length > 0 ? GROUP_PADDING_TOP + GROUP_LABEL_SIZE : 0;
7872
8511
  const participantStartY = TOP_MARGIN + titleOffset + PARTICIPANT_Y_OFFSET + groupOffset;
7873
8512
  const lifelineStartY0 = participantStartY + PARTICIPANT_BOX_HEIGHT;
@@ -7910,7 +8549,7 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
7910
8549
  for (let i = 0; i < els.length; i++) {
7911
8550
  const el = els[i];
7912
8551
  if (isSequenceNote(el)) {
7913
- const si = findAssociatedFirstStep(el);
8552
+ const si = findAssociatedLastStep(el);
7914
8553
  if (si < 0) continue;
7915
8554
  const prevNote = i > 0 && isSequenceNote(els[i - 1]) ? els[i - 1] : null;
7916
8555
  const prevNoteY = prevNote ? noteYMap.get(prevNote) : void 0;
@@ -7960,7 +8599,7 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
7960
8599
  participants.forEach((p, i) => {
7961
8600
  participantX.set(p.id, offsetX + i * PARTICIPANT_GAP);
7962
8601
  });
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);
8602
+ 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
8603
  const defs = svg.append("defs");
7965
8604
  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
8605
  "points",
@@ -7989,7 +8628,7 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
7989
8628
  const boxY = participantStartY - GROUP_PADDING_TOP;
7990
8629
  const boxH = PARTICIPANT_BOX_HEIGHT + GROUP_PADDING_TOP + GROUP_PADDING_BOTTOM;
7991
8630
  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;
8631
+ const fillColor = resolvedGroupColor ? mix6(resolvedGroupColor, isDark ? palette.surface : palette.bg, 10) : isDark ? palette.surface : palette.bg;
7993
8632
  const strokeColor = resolvedGroupColor || palette.textMuted;
7994
8633
  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
8634
  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 +8798,7 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
8159
8798
  if (msg) coveredLines.push(msg.lineNumber);
8160
8799
  }
8161
8800
  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);
8801
+ const actFill = mix6(palette.primary, isDark ? palette.surface : palette.bg, isDark ? 15 : 30);
8163
8802
  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
8803
  });
8165
8804
  for (const ln of deferredLines) {
@@ -8288,8 +8927,8 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
8288
8927
  }
8289
8928
  }
8290
8929
  });
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);
8930
+ const noteFill = isDark ? mix6(palette.surface, palette.bg, 50) : mix6(palette.bg, palette.surface, 15);
8931
+ const collapsedNoteFill = mix6(palette.textMuted, palette.bg, 15);
8293
8932
  const renderNoteElements = (els) => {
8294
8933
  for (const el of els) {
8295
8934
  if (isSequenceNote(el)) {
@@ -8445,8 +9084,8 @@ function renderParticipant(svg, participant, cx, cy, palette, isDark) {
8445
9084
  isActor ? PARTICIPANT_BOX_HEIGHT + 14 : PARTICIPANT_BOX_HEIGHT / 2 + 5
8446
9085
  ).attr("text-anchor", "middle").attr("fill", palette.text).attr("font-size", 13).attr("font-weight", 500).text(participant.label);
8447
9086
  }
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({
9087
+ 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;
9088
+ var init_renderer5 = __esm({
8450
9089
  "src/sequence/renderer.ts"() {
8451
9090
  "use strict";
8452
9091
  init_colors();
@@ -8456,7 +9095,7 @@ var init_renderer4 = __esm({
8456
9095
  PARTICIPANT_BOX_WIDTH = 120;
8457
9096
  PARTICIPANT_BOX_HEIGHT = 50;
8458
9097
  TOP_MARGIN = 20;
8459
- TITLE_HEIGHT2 = 30;
9098
+ TITLE_HEIGHT3 = 30;
8460
9099
  PARTICIPANT_Y_OFFSET = 10;
8461
9100
  SERVICE_BORDER_RADIUS = 10;
8462
9101
  MESSAGE_START_OFFSET = 30;
@@ -8474,7 +9113,7 @@ var init_renderer4 = __esm({
8474
9113
  COLLAPSED_NOTE_H = 20;
8475
9114
  COLLAPSED_NOTE_W = 40;
8476
9115
  BARE_URL_MAX_DISPLAY = 35;
8477
- fill = (palette, isDark) => mix5(palette.primary, isDark ? palette.surface : palette.bg, isDark ? 15 : 30);
9116
+ fill = (palette, isDark) => mix6(palette.primary, isDark ? palette.surface : palette.bg, isDark ? 15 : 30);
8478
9117
  stroke = (palette) => palette.textMuted;
8479
9118
  SW = 1.5;
8480
9119
  W = PARTICIPANT_BOX_WIDTH;
@@ -8484,7 +9123,7 @@ var init_renderer4 = __esm({
8484
9123
 
8485
9124
  // src/d3.ts
8486
9125
  import * as d3Scale from "d3-scale";
8487
- import * as d3Selection6 from "d3-selection";
9126
+ import * as d3Selection7 from "d3-selection";
8488
9127
  import * as d3Shape4 from "d3-shape";
8489
9128
  import * as d3Array from "d3-array";
8490
9129
  import cloud from "d3-cloud";
@@ -9035,7 +9674,7 @@ function tokenizeFreeformText(text) {
9035
9674
  return Array.from(counts.entries()).map(([text2, count]) => ({ text: text2, weight: count, lineNumber: 0 })).sort((a, b) => b.weight - a.weight);
9036
9675
  }
9037
9676
  function renderSlopeChart(container, parsed, palette, isDark, onClickItem, exportDims) {
9038
- d3Selection6.select(container).selectAll(":not([data-d3-tooltip])").remove();
9677
+ d3Selection7.select(container).selectAll(":not([data-d3-tooltip])").remove();
9039
9678
  const { periods, data, title } = parsed;
9040
9679
  if (data.length === 0 || periods.length < 2) return;
9041
9680
  const width = exportDims?.width ?? container.clientWidth;
@@ -9062,7 +9701,7 @@ function renderSlopeChart(container, parsed, palette, isDark, onClickItem, expor
9062
9701
  const valuePadding = (maxVal - minVal) * 0.1 || 1;
9063
9702
  const yScale = d3Scale.scaleLinear().domain([minVal - valuePadding, maxVal + valuePadding]).range([innerHeight, 0]);
9064
9703
  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);
9704
+ const svg = d3Selection7.select(container).append("svg").attr("width", width).attr("height", height).style("background", bgColor);
9066
9705
  const g = svg.append("g").attr("transform", `translate(${SLOPE_MARGIN.left},${SLOPE_MARGIN.top})`);
9067
9706
  const tooltip = createTooltip(container, palette, isDark);
9068
9707
  if (title) {
@@ -9071,9 +9710,9 @@ function renderSlopeChart(container, parsed, palette, isDark, onClickItem, expor
9071
9710
  titleEl.attr("data-line-number", parsed.titleLineNumber);
9072
9711
  if (onClickItem) {
9073
9712
  titleEl.on("click", () => onClickItem(parsed.titleLineNumber)).on("mouseenter", function() {
9074
- d3Selection6.select(this).attr("opacity", 0.7);
9713
+ d3Selection7.select(this).attr("opacity", 0.7);
9075
9714
  }).on("mouseleave", function() {
9076
- d3Selection6.select(this).attr("opacity", 1);
9715
+ d3Selection7.select(this).attr("opacity", 1);
9077
9716
  });
9078
9717
  }
9079
9718
  }
@@ -9247,7 +9886,7 @@ function orderArcNodes(links, order, groups) {
9247
9886
  return allNodes;
9248
9887
  }
9249
9888
  function renderArcDiagram(container, parsed, palette, _isDark, onClickItem, exportDims) {
9250
- d3Selection6.select(container).selectAll(":not([data-d3-tooltip])").remove();
9889
+ d3Selection7.select(container).selectAll(":not([data-d3-tooltip])").remove();
9251
9890
  const { links, title, orientation, arcOrder, arcNodeGroups } = parsed;
9252
9891
  if (links.length === 0) return;
9253
9892
  const width = exportDims?.width ?? container.clientWidth;
@@ -9284,7 +9923,7 @@ function renderArcDiagram(container, parsed, palette, _isDark, onClickItem, expo
9284
9923
  const values = links.map((l) => l.value);
9285
9924
  const [minVal, maxVal] = d3Array.extent(values);
9286
9925
  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);
9926
+ const svg = d3Selection7.select(container).append("svg").attr("width", width).attr("height", height).style("background", bgColor);
9288
9927
  const g = svg.append("g").attr("transform", `translate(${margin.left},${margin.top})`);
9289
9928
  if (title) {
9290
9929
  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 +9931,9 @@ function renderArcDiagram(container, parsed, palette, _isDark, onClickItem, expo
9292
9931
  titleEl.attr("data-line-number", parsed.titleLineNumber);
9293
9932
  if (onClickItem) {
9294
9933
  titleEl.on("click", () => onClickItem(parsed.titleLineNumber)).on("mouseenter", function() {
9295
- d3Selection6.select(this).attr("opacity", 0.7);
9934
+ d3Selection7.select(this).attr("opacity", 0.7);
9296
9935
  }).on("mouseleave", function() {
9297
- d3Selection6.select(this).attr("opacity", 1);
9936
+ d3Selection7.select(this).attr("opacity", 1);
9298
9937
  });
9299
9938
  }
9300
9939
  }
@@ -9309,14 +9948,14 @@ function renderArcDiagram(container, parsed, palette, _isDark, onClickItem, expo
9309
9948
  function handleMouseEnter(hovered) {
9310
9949
  const connected = neighbors.get(hovered);
9311
9950
  g.selectAll(".arc-link").each(function() {
9312
- const el = d3Selection6.select(this);
9951
+ const el = d3Selection7.select(this);
9313
9952
  const src = el.attr("data-source");
9314
9953
  const tgt = el.attr("data-target");
9315
9954
  const isRelated = src === hovered || tgt === hovered;
9316
9955
  el.attr("stroke-opacity", isRelated ? 0.85 : FADE_OPACITY);
9317
9956
  });
9318
9957
  g.selectAll(".arc-node").each(function() {
9319
- const el = d3Selection6.select(this);
9958
+ const el = d3Selection7.select(this);
9320
9959
  const name = el.attr("data-node");
9321
9960
  const isRelated = name === hovered || connected.has(name);
9322
9961
  el.attr("opacity", isRelated ? 1 : FADE_OPACITY);
@@ -9341,23 +9980,23 @@ function renderArcDiagram(container, parsed, palette, _isDark, onClickItem, expo
9341
9980
  const members = groupNodeSets.get(groupName);
9342
9981
  if (!members) return;
9343
9982
  g.selectAll(".arc-link").each(function() {
9344
- const el = d3Selection6.select(this);
9983
+ const el = d3Selection7.select(this);
9345
9984
  const isRelated = members.has(el.attr("data-source")) || members.has(el.attr("data-target"));
9346
9985
  el.attr("stroke-opacity", isRelated ? 0.85 : FADE_OPACITY);
9347
9986
  });
9348
9987
  g.selectAll(".arc-node").each(function() {
9349
- const el = d3Selection6.select(this);
9988
+ const el = d3Selection7.select(this);
9350
9989
  el.attr("opacity", members.has(el.attr("data-node")) ? 1 : FADE_OPACITY);
9351
9990
  });
9352
9991
  g.selectAll(".arc-group-band").each(function() {
9353
- const el = d3Selection6.select(this);
9992
+ const el = d3Selection7.select(this);
9354
9993
  el.attr(
9355
9994
  "fill-opacity",
9356
9995
  el.attr("data-group") === groupName ? 0.18 : 0.03
9357
9996
  );
9358
9997
  });
9359
9998
  g.selectAll(".arc-group-label").each(function() {
9360
- const el = d3Selection6.select(this);
9999
+ const el = d3Selection7.select(this);
9361
10000
  el.attr("fill-opacity", el.attr("data-group") === groupName ? 1 : 0.2);
9362
10001
  });
9363
10002
  }
@@ -9653,7 +10292,7 @@ function showEventDatesOnScale(g, scale, startDate, endDate, innerHeight, accent
9653
10292
  function hideEventDatesOnScale(g) {
9654
10293
  g.selectAll(".tl-event-date").remove();
9655
10294
  g.selectAll(".tl-scale-tick").each(function() {
9656
- const el = d3Selection6.select(this);
10295
+ const el = d3Selection7.select(this);
9657
10296
  const isDashed = el.attr("stroke-dasharray");
9658
10297
  el.attr("opacity", isDashed ? 0.15 : 0.4);
9659
10298
  });
@@ -9711,7 +10350,7 @@ function buildEraTooltipHtml(era) {
9711
10350
  return `<strong>${era.label}</strong><br>${formatDateLabel(era.startDate)} \u2192 ${formatDateLabel(era.endDate)}`;
9712
10351
  }
9713
10352
  function renderTimeline(container, parsed, palette, isDark, onClickItem, exportDims) {
9714
- d3Selection6.select(container).selectAll(":not([data-d3-tooltip])").remove();
10353
+ d3Selection7.select(container).selectAll(":not([data-d3-tooltip])").remove();
9715
10354
  const {
9716
10355
  timelineEvents,
9717
10356
  timelineGroups,
@@ -9763,13 +10402,13 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
9763
10402
  const FADE_OPACITY = 0.1;
9764
10403
  function fadeToGroup(g, groupName) {
9765
10404
  g.selectAll(".tl-event").each(function() {
9766
- const el = d3Selection6.select(this);
10405
+ const el = d3Selection7.select(this);
9767
10406
  const evGroup = el.attr("data-group");
9768
10407
  el.attr("opacity", evGroup === groupName ? 1 : FADE_OPACITY);
9769
10408
  });
9770
10409
  g.selectAll(".tl-legend-item, .tl-lane-header").each(
9771
10410
  function() {
9772
- const el = d3Selection6.select(this);
10411
+ const el = d3Selection7.select(this);
9773
10412
  const name = el.attr("data-group");
9774
10413
  el.attr("opacity", name === groupName ? 1 : FADE_OPACITY);
9775
10414
  }
@@ -9781,7 +10420,7 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
9781
10420
  }
9782
10421
  function fadeToEra(g, eraStart, eraEnd) {
9783
10422
  g.selectAll(".tl-event").each(function() {
9784
- const el = d3Selection6.select(this);
10423
+ const el = d3Selection7.select(this);
9785
10424
  const date = parseFloat(el.attr("data-date"));
9786
10425
  const endDate = el.attr("data-end-date");
9787
10426
  const evEnd = endDate ? parseFloat(endDate) : date;
@@ -9793,14 +10432,14 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
9793
10432
  FADE_OPACITY
9794
10433
  );
9795
10434
  g.selectAll(".tl-era").each(function() {
9796
- const el = d3Selection6.select(this);
10435
+ const el = d3Selection7.select(this);
9797
10436
  const s = parseFloat(el.attr("data-era-start"));
9798
10437
  const e = parseFloat(el.attr("data-era-end"));
9799
10438
  const isSelf = s === eraStart && e === eraEnd;
9800
10439
  el.attr("opacity", isSelf ? 1 : FADE_OPACITY);
9801
10440
  });
9802
10441
  g.selectAll(".tl-marker").each(function() {
9803
- const el = d3Selection6.select(this);
10442
+ const el = d3Selection7.select(this);
9804
10443
  const date = parseFloat(el.attr("data-marker-date"));
9805
10444
  const inside = date >= eraStart && date <= eraEnd;
9806
10445
  el.attr("opacity", inside ? 1 : FADE_OPACITY);
@@ -9832,7 +10471,7 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
9832
10471
  const innerHeight = height - margin.top - margin.bottom;
9833
10472
  const laneWidth = innerWidth / laneCount;
9834
10473
  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);
10474
+ const svg = d3Selection7.select(container).append("svg").attr("width", width).attr("height", height).style("background", bgColor);
9836
10475
  const g = svg.append("g").attr("transform", `translate(${margin.left},${margin.top})`);
9837
10476
  if (title) {
9838
10477
  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 +10479,9 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
9840
10479
  titleEl.attr("data-line-number", parsed.titleLineNumber);
9841
10480
  if (onClickItem) {
9842
10481
  titleEl.on("click", () => onClickItem(parsed.titleLineNumber)).on("mouseenter", function() {
9843
- d3Selection6.select(this).attr("opacity", 0.7);
10482
+ d3Selection7.select(this).attr("opacity", 0.7);
9844
10483
  }).on("mouseleave", function() {
9845
- d3Selection6.select(this).attr("opacity", 1);
10484
+ d3Selection7.select(this).attr("opacity", 1);
9846
10485
  });
9847
10486
  }
9848
10487
  }
@@ -9918,7 +10557,7 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
9918
10557
  if (ev.uncertain) {
9919
10558
  const gradientId = `uncertain-vg-${ev.lineNumber}`;
9920
10559
  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([
10560
+ d3Selection7.select(defs).append("linearGradient").attr("id", gradientId).attr("x1", "0%").attr("y1", "0%").attr("x2", "0%").attr("y2", "100%").selectAll("stop").data([
9922
10561
  { offset: "0%", opacity: 1 },
9923
10562
  { offset: "80%", opacity: 1 },
9924
10563
  { offset: "100%", opacity: 0 }
@@ -9947,7 +10586,7 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
9947
10586
  const axisX = 20;
9948
10587
  const yScale = d3Scale.scaleLinear().domain([minDate - datePadding, maxDate + datePadding]).range([0, innerHeight]);
9949
10588
  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);
10589
+ const svg = d3Selection7.select(container).append("svg").attr("width", width).attr("height", height).style("background", bgColor);
9951
10590
  const g = svg.append("g").attr("transform", `translate(${margin.left},${margin.top})`);
9952
10591
  if (title) {
9953
10592
  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 +10594,9 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
9955
10594
  titleEl.attr("data-line-number", parsed.titleLineNumber);
9956
10595
  if (onClickItem) {
9957
10596
  titleEl.on("click", () => onClickItem(parsed.titleLineNumber)).on("mouseenter", function() {
9958
- d3Selection6.select(this).attr("opacity", 0.7);
10597
+ d3Selection7.select(this).attr("opacity", 0.7);
9959
10598
  }).on("mouseleave", function() {
9960
- d3Selection6.select(this).attr("opacity", 1);
10599
+ d3Selection7.select(this).attr("opacity", 1);
9961
10600
  });
9962
10601
  }
9963
10602
  }
@@ -10036,7 +10675,7 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
10036
10675
  if (ev.uncertain) {
10037
10676
  const gradientId = `uncertain-v-${ev.lineNumber}`;
10038
10677
  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([
10678
+ d3Selection7.select(defs).append("linearGradient").attr("id", gradientId).attr("x1", "0%").attr("y1", "0%").attr("x2", "0%").attr("y2", "100%").selectAll("stop").data([
10040
10679
  { offset: "0%", opacity: 1 },
10041
10680
  { offset: "80%", opacity: 1 },
10042
10681
  { offset: "100%", opacity: 0 }
@@ -10091,7 +10730,7 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
10091
10730
  const totalGaps = (lanes.length - 1) * GROUP_GAP;
10092
10731
  const rowH = Math.min(28, (innerHeight - totalGaps) / totalEventRows);
10093
10732
  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);
10733
+ const svg = d3Selection7.select(container).append("svg").attr("width", width).attr("height", height).style("background", bgColor);
10095
10734
  const g = svg.append("g").attr("transform", `translate(${margin.left},${margin.top})`);
10096
10735
  if (title) {
10097
10736
  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 +10738,9 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
10099
10738
  titleEl.attr("data-line-number", parsed.titleLineNumber);
10100
10739
  if (onClickItem) {
10101
10740
  titleEl.on("click", () => onClickItem(parsed.titleLineNumber)).on("mouseenter", function() {
10102
- d3Selection6.select(this).attr("opacity", 0.7);
10741
+ d3Selection7.select(this).attr("opacity", 0.7);
10103
10742
  }).on("mouseleave", function() {
10104
- d3Selection6.select(this).attr("opacity", 1);
10743
+ d3Selection7.select(this).attr("opacity", 1);
10105
10744
  });
10106
10745
  }
10107
10746
  }
@@ -10205,7 +10844,7 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
10205
10844
  if (ev.uncertain) {
10206
10845
  const gradientId = `uncertain-${ev.lineNumber}`;
10207
10846
  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([
10847
+ d3Selection7.select(defs).append("linearGradient").attr("id", gradientId).attr("x1", "0%").attr("y1", "0%").attr("x2", "100%").attr("y2", "0%").selectAll("stop").data([
10209
10848
  { offset: "0%", opacity: 1 },
10210
10849
  { offset: "80%", opacity: 1 },
10211
10850
  { offset: "100%", opacity: 0 }
@@ -10246,7 +10885,7 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
10246
10885
  const innerHeight = height - margin.top - margin.bottom;
10247
10886
  const rowH = Math.min(28, innerHeight / sorted.length);
10248
10887
  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);
10888
+ const svg = d3Selection7.select(container).append("svg").attr("width", width).attr("height", height).style("background", bgColor);
10250
10889
  const g = svg.append("g").attr("transform", `translate(${margin.left},${margin.top})`);
10251
10890
  if (title) {
10252
10891
  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 +10893,9 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
10254
10893
  titleEl.attr("data-line-number", parsed.titleLineNumber);
10255
10894
  if (onClickItem) {
10256
10895
  titleEl.on("click", () => onClickItem(parsed.titleLineNumber)).on("mouseenter", function() {
10257
- d3Selection6.select(this).attr("opacity", 0.7);
10896
+ d3Selection7.select(this).attr("opacity", 0.7);
10258
10897
  }).on("mouseleave", function() {
10259
- d3Selection6.select(this).attr("opacity", 1);
10898
+ d3Selection7.select(this).attr("opacity", 1);
10260
10899
  });
10261
10900
  }
10262
10901
  }
@@ -10354,7 +10993,7 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
10354
10993
  if (ev.uncertain) {
10355
10994
  const gradientId = `uncertain-ts-${ev.lineNumber}`;
10356
10995
  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([
10996
+ d3Selection7.select(defs).append("linearGradient").attr("id", gradientId).attr("x1", "0%").attr("y1", "0%").attr("x2", "100%").attr("y2", "0%").selectAll("stop").data([
10358
10997
  { offset: "0%", opacity: 1 },
10359
10998
  { offset: "80%", opacity: 1 },
10360
10999
  { offset: "100%", opacity: 0 }
@@ -10387,7 +11026,7 @@ function getRotateFn(mode) {
10387
11026
  return () => 0;
10388
11027
  }
10389
11028
  function renderWordCloud(container, parsed, palette, _isDark, onClickItem, exportDims) {
10390
- d3Selection6.select(container).selectAll(":not([data-d3-tooltip])").remove();
11029
+ d3Selection7.select(container).selectAll(":not([data-d3-tooltip])").remove();
10391
11030
  const { words, title, cloudOptions } = parsed;
10392
11031
  if (words.length === 0) return;
10393
11032
  const width = exportDims?.width ?? container.clientWidth;
@@ -10408,16 +11047,16 @@ function renderWordCloud(container, parsed, palette, _isDark, onClickItem, expor
10408
11047
  return minSize + t * (maxSize - minSize);
10409
11048
  };
10410
11049
  const rotateFn = getRotateFn(cloudOptions.rotate);
10411
- const svg = d3Selection6.select(container).append("svg").attr("width", width).attr("height", height).style("background", bgColor);
11050
+ const svg = d3Selection7.select(container).append("svg").attr("width", width).attr("height", height).style("background", bgColor);
10412
11051
  if (title) {
10413
11052
  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
11053
  if (parsed.titleLineNumber) {
10415
11054
  titleEl.attr("data-line-number", parsed.titleLineNumber);
10416
11055
  if (onClickItem) {
10417
11056
  titleEl.on("click", () => onClickItem(parsed.titleLineNumber)).on("mouseenter", function() {
10418
- d3Selection6.select(this).attr("opacity", 0.7);
11057
+ d3Selection7.select(this).attr("opacity", 0.7);
10419
11058
  }).on("mouseleave", function() {
10420
- d3Selection6.select(this).attr("opacity", 1);
11059
+ d3Selection7.select(this).attr("opacity", 1);
10421
11060
  });
10422
11061
  }
10423
11062
  }
@@ -10444,7 +11083,7 @@ function renderWordCloud(container, parsed, palette, _isDark, onClickItem, expor
10444
11083
  }
10445
11084
  function renderWordCloudAsync(container, parsed, palette, _isDark, exportDims) {
10446
11085
  return new Promise((resolve) => {
10447
- d3Selection6.select(container).selectAll(":not([data-d3-tooltip])").remove();
11086
+ d3Selection7.select(container).selectAll(":not([data-d3-tooltip])").remove();
10448
11087
  const { words, title, cloudOptions } = parsed;
10449
11088
  if (words.length === 0) {
10450
11089
  resolve();
@@ -10471,7 +11110,7 @@ function renderWordCloudAsync(container, parsed, palette, _isDark, exportDims) {
10471
11110
  return minSize + t * (maxSize - minSize);
10472
11111
  };
10473
11112
  const rotateFn = getRotateFn(cloudOptions.rotate);
10474
- const svg = d3Selection6.select(container).append("svg").attr("width", width).attr("height", height).style("background", bgColor);
11113
+ const svg = d3Selection7.select(container).append("svg").attr("width", width).attr("height", height).style("background", bgColor);
10475
11114
  if (title) {
10476
11115
  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
11116
  if (parsed.titleLineNumber) {
@@ -10608,7 +11247,7 @@ function regionCentroid(circles, inside) {
10608
11247
  return { x: sx / count, y: sy / count };
10609
11248
  }
10610
11249
  function renderVenn(container, parsed, palette, isDark, onClickItem, exportDims) {
10611
- d3Selection6.select(container).selectAll(":not([data-d3-tooltip])").remove();
11250
+ d3Selection7.select(container).selectAll(":not([data-d3-tooltip])").remove();
10612
11251
  const { vennSets, vennOverlaps, vennShowValues, title } = parsed;
10613
11252
  if (vennSets.length < 2) return;
10614
11253
  const width = exportDims?.width ?? container.clientWidth;
@@ -10695,7 +11334,7 @@ function renderVenn(container, parsed, palette, isDark, onClickItem, exportDims)
10695
11334
  marginTop,
10696
11335
  marginBottom
10697
11336
  ).map((c) => ({ ...c, y: c.y + titleHeight }));
10698
- const svg = d3Selection6.select(container).append("svg").attr("width", width).attr("height", height).style("background", bgColor);
11337
+ const svg = d3Selection7.select(container).append("svg").attr("width", width).attr("height", height).style("background", bgColor);
10699
11338
  const tooltip = createTooltip(container, palette, isDark);
10700
11339
  if (title) {
10701
11340
  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 +11342,9 @@ function renderVenn(container, parsed, palette, isDark, onClickItem, exportDims)
10703
11342
  titleEl.attr("data-line-number", parsed.titleLineNumber);
10704
11343
  if (onClickItem) {
10705
11344
  titleEl.on("click", () => onClickItem(parsed.titleLineNumber)).on("mouseenter", function() {
10706
- d3Selection6.select(this).attr("opacity", 0.7);
11345
+ d3Selection7.select(this).attr("opacity", 0.7);
10707
11346
  }).on("mouseleave", function() {
10708
- d3Selection6.select(this).attr("opacity", 1);
11347
+ d3Selection7.select(this).attr("opacity", 1);
10709
11348
  });
10710
11349
  }
10711
11350
  }
@@ -10853,7 +11492,7 @@ function renderVenn(container, parsed, palette, isDark, onClickItem, exportDims)
10853
11492
  });
10854
11493
  }
10855
11494
  function renderQuadrant(container, parsed, palette, isDark, onClickItem, exportDims) {
10856
- d3Selection6.select(container).selectAll(":not([data-d3-tooltip])").remove();
11495
+ d3Selection7.select(container).selectAll(":not([data-d3-tooltip])").remove();
10857
11496
  const {
10858
11497
  title,
10859
11498
  quadrantLabels,
@@ -10885,7 +11524,7 @@ function renderQuadrant(container, parsed, palette, isDark, onClickItem, exportD
10885
11524
  const chartHeight = height - margin.top - margin.bottom;
10886
11525
  const xScale = d3Scale.scaleLinear().domain([0, 1]).range([0, chartWidth]);
10887
11526
  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);
11527
+ const svg = d3Selection7.select(container).append("svg").attr("width", width).attr("height", height).style("background", bgColor);
10889
11528
  const tooltip = createTooltip(container, palette, isDark);
10890
11529
  if (title) {
10891
11530
  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 +11536,9 @@ function renderQuadrant(container, parsed, palette, isDark, onClickItem, exportD
10897
11536
  }
10898
11537
  if (onClickItem && quadrantTitleLineNumber) {
10899
11538
  titleText.on("click", () => onClickItem(quadrantTitleLineNumber)).on("mouseenter", function() {
10900
- d3Selection6.select(this).attr("opacity", 0.7);
11539
+ d3Selection7.select(this).attr("opacity", 0.7);
10901
11540
  }).on("mouseleave", function() {
10902
- d3Selection6.select(this).attr("opacity", 1);
11541
+ d3Selection7.select(this).attr("opacity", 1);
10903
11542
  });
10904
11543
  }
10905
11544
  }
@@ -11035,7 +11674,7 @@ function renderQuadrant(container, parsed, palette, isDark, onClickItem, exportD
11035
11674
  (d) => onClickItem && d.label?.lineNumber ? "pointer" : "default"
11036
11675
  ).each(function(d) {
11037
11676
  const layout = labelLayouts.get(d.label.text);
11038
- const el = d3Selection6.select(this);
11677
+ const el = d3Selection7.select(this);
11039
11678
  if (layout.lines.length === 1) {
11040
11679
  el.text(layout.lines[0]);
11041
11680
  } else {
@@ -11051,9 +11690,9 @@ function renderQuadrant(container, parsed, palette, isDark, onClickItem, exportD
11051
11690
  quadrantLabelTexts.on("click", (_, d) => {
11052
11691
  if (d.label?.lineNumber) onClickItem(d.label.lineNumber);
11053
11692
  }).on("mouseenter", function() {
11054
- d3Selection6.select(this).attr("opacity", 0.7);
11693
+ d3Selection7.select(this).attr("opacity", 0.7);
11055
11694
  }).on("mouseleave", function() {
11056
- d3Selection6.select(this).attr("opacity", 1);
11695
+ d3Selection7.select(this).attr("opacity", 1);
11057
11696
  });
11058
11697
  }
11059
11698
  if (quadrantXAxis) {
@@ -11068,9 +11707,9 @@ function renderQuadrant(container, parsed, palette, isDark, onClickItem, exportD
11068
11707
  if (onClickItem && quadrantXAxisLineNumber) {
11069
11708
  [xLowLabel, xHighLabel].forEach((label) => {
11070
11709
  label.on("click", () => onClickItem(quadrantXAxisLineNumber)).on("mouseenter", function() {
11071
- d3Selection6.select(this).attr("opacity", 0.7);
11710
+ d3Selection7.select(this).attr("opacity", 0.7);
11072
11711
  }).on("mouseleave", function() {
11073
- d3Selection6.select(this).attr("opacity", 1);
11712
+ d3Selection7.select(this).attr("opacity", 1);
11074
11713
  });
11075
11714
  });
11076
11715
  }
@@ -11089,9 +11728,9 @@ function renderQuadrant(container, parsed, palette, isDark, onClickItem, exportD
11089
11728
  if (onClickItem && quadrantYAxisLineNumber) {
11090
11729
  [yLowLabel, yHighLabel].forEach((label) => {
11091
11730
  label.on("click", () => onClickItem(quadrantYAxisLineNumber)).on("mouseenter", function() {
11092
- d3Selection6.select(this).attr("opacity", 0.7);
11731
+ d3Selection7.select(this).attr("opacity", 0.7);
11093
11732
  }).on("mouseleave", function() {
11094
- d3Selection6.select(this).attr("opacity", 1);
11733
+ d3Selection7.select(this).attr("opacity", 1);
11095
11734
  });
11096
11735
  });
11097
11736
  }
@@ -11139,7 +11778,7 @@ function renderQuadrant(container, parsed, palette, isDark, onClickItem, exportD
11139
11778
  pointsG.selectAll("g.point-group").each(function(_2, i) {
11140
11779
  const pt = quadrantPoints[i];
11141
11780
  const ptQuad = getPointQuadrant(pt.x, pt.y);
11142
- d3Selection6.select(this).attr("opacity", ptQuad === d.position ? 1 : 0.2);
11781
+ d3Selection7.select(this).attr("opacity", ptQuad === d.position ? 1 : 0.2);
11143
11782
  });
11144
11783
  }).on("mouseleave", () => {
11145
11784
  quadrantRects.attr("opacity", 1);
@@ -11163,7 +11802,7 @@ async function renderD3ForExport(content, theme, palette, orgExportState, option
11163
11802
  const { getPalette: getPalette3 } = await Promise.resolve().then(() => (init_palettes(), palettes_exports));
11164
11803
  const effectivePalette2 = palette ?? (isDark2 ? getPalette3("nord").dark : getPalette3("nord").light);
11165
11804
  const orgParsed = parseOrg2(content, effectivePalette2);
11166
- if (orgParsed.error || orgParsed.roots.length === 0) return "";
11805
+ if (orgParsed.error) return "";
11167
11806
  const collapsedNodes = orgExportState?.collapsedNodes;
11168
11807
  const activeTagGroup = orgExportState?.activeTagGroup ?? null;
11169
11808
  const hiddenAttributes = orgExportState?.hiddenAttributes;
@@ -11215,10 +11854,43 @@ async function renderD3ForExport(content, theme, palette, orgExportState, option
11215
11854
  document.body.removeChild(container2);
11216
11855
  }
11217
11856
  }
11857
+ if (detectedType === "kanban") {
11858
+ const { parseKanban: parseKanban2 } = await Promise.resolve().then(() => (init_parser5(), parser_exports5));
11859
+ const { renderKanban: renderKanban2 } = await Promise.resolve().then(() => (init_renderer2(), renderer_exports2));
11860
+ const isDark2 = theme === "dark";
11861
+ const { getPalette: getPalette3 } = await Promise.resolve().then(() => (init_palettes(), palettes_exports));
11862
+ const effectivePalette2 = palette ?? (isDark2 ? getPalette3("nord").dark : getPalette3("nord").light);
11863
+ const kanbanParsed = parseKanban2(content, effectivePalette2);
11864
+ if (kanbanParsed.error || kanbanParsed.columns.length === 0) return "";
11865
+ const container2 = document.createElement("div");
11866
+ container2.style.position = "absolute";
11867
+ container2.style.left = "-9999px";
11868
+ document.body.appendChild(container2);
11869
+ try {
11870
+ renderKanban2(container2, kanbanParsed, effectivePalette2, isDark2);
11871
+ const svgEl = container2.querySelector("svg");
11872
+ if (!svgEl) return "";
11873
+ if (theme === "transparent") {
11874
+ svgEl.style.background = "none";
11875
+ } else if (!svgEl.style.background) {
11876
+ svgEl.style.background = effectivePalette2.bg;
11877
+ }
11878
+ svgEl.setAttribute("xmlns", "http://www.w3.org/2000/svg");
11879
+ svgEl.style.fontFamily = FONT_FAMILY;
11880
+ const svgHtml = svgEl.outerHTML;
11881
+ if (options?.branding !== false) {
11882
+ const brandColor = theme === "transparent" ? "#888" : effectivePalette2.textMuted;
11883
+ return injectBranding(svgHtml, brandColor);
11884
+ }
11885
+ return svgHtml;
11886
+ } finally {
11887
+ document.body.removeChild(container2);
11888
+ }
11889
+ }
11218
11890
  if (detectedType === "class") {
11219
11891
  const { parseClassDiagram: parseClassDiagram2 } = await Promise.resolve().then(() => (init_parser2(), parser_exports2));
11220
11892
  const { layoutClassDiagram: layoutClassDiagram2 } = await Promise.resolve().then(() => (init_layout2(), layout_exports2));
11221
- const { renderClassDiagram: renderClassDiagram2 } = await Promise.resolve().then(() => (init_renderer2(), renderer_exports2));
11893
+ const { renderClassDiagram: renderClassDiagram2 } = await Promise.resolve().then(() => (init_renderer3(), renderer_exports3));
11222
11894
  const isDark2 = theme === "dark";
11223
11895
  const { getPalette: getPalette3 } = await Promise.resolve().then(() => (init_palettes(), palettes_exports));
11224
11896
  const effectivePalette2 = palette ?? (isDark2 ? getPalette3("nord").dark : getPalette3("nord").light);
@@ -11267,7 +11939,7 @@ async function renderD3ForExport(content, theme, palette, orgExportState, option
11267
11939
  if (detectedType === "er") {
11268
11940
  const { parseERDiagram: parseERDiagram2 } = await Promise.resolve().then(() => (init_parser3(), parser_exports3));
11269
11941
  const { layoutERDiagram: layoutERDiagram2 } = await Promise.resolve().then(() => (init_layout3(), layout_exports3));
11270
- const { renderERDiagram: renderERDiagram2 } = await Promise.resolve().then(() => (init_renderer3(), renderer_exports3));
11942
+ const { renderERDiagram: renderERDiagram2 } = await Promise.resolve().then(() => (init_renderer4(), renderer_exports4));
11271
11943
  const isDark2 = theme === "dark";
11272
11944
  const { getPalette: getPalette3 } = await Promise.resolve().then(() => (init_palettes(), palettes_exports));
11273
11945
  const effectivePalette2 = palette ?? (isDark2 ? getPalette3("nord").dark : getPalette3("nord").light);
@@ -11380,7 +12052,7 @@ async function renderD3ForExport(content, theme, palette, orgExportState, option
11380
12052
  try {
11381
12053
  if (parsed.type === "sequence") {
11382
12054
  const { parseSequenceDgmo: parseSequenceDgmo2 } = await Promise.resolve().then(() => (init_parser(), parser_exports));
11383
- const { renderSequenceDiagram: renderSequenceDiagram2 } = await Promise.resolve().then(() => (init_renderer4(), renderer_exports4));
12055
+ const { renderSequenceDiagram: renderSequenceDiagram2 } = await Promise.resolve().then(() => (init_renderer5(), renderer_exports5));
11384
12056
  const seqParsed = parseSequenceDgmo2(content);
11385
12057
  if (seqParsed.error || seqParsed.participants.length === 0) return "";
11386
12058
  renderSequenceDiagram2(container, seqParsed, effectivePalette, isDark, void 0, {
@@ -11767,13 +12439,16 @@ function buildMermaidQuadrant(parsed, options = {}) {
11767
12439
  init_flowchart_parser();
11768
12440
  init_parser2();
11769
12441
  init_layout2();
11770
- init_renderer2();
12442
+ init_renderer3();
11771
12443
  init_parser3();
11772
12444
  init_layout3();
11773
- init_renderer3();
12445
+ init_renderer4();
11774
12446
  init_parser4();
11775
12447
  init_layout();
11776
12448
  init_renderer();
12449
+ init_parser5();
12450
+ init_mutations();
12451
+ init_renderer2();
11777
12452
  init_collapse();
11778
12453
 
11779
12454
  // src/org/resolver.ts
@@ -11782,8 +12457,8 @@ var MAX_DEPTH = 10;
11782
12457
  var IMPORT_RE = /^(\s+)import:\s+(.+\.dgmo)\s*$/i;
11783
12458
  var TAGS_RE = /^tags:\s+(.+\.dgmo)\s*$/i;
11784
12459
  var HEADER_RE = /^(chart|title)\s*:/i;
11785
- var OPTION_RE2 = /^[a-z][a-z0-9-]*\s*:/i;
11786
- var GROUP_HEADING_RE3 = /^##\s+/;
12460
+ var OPTION_RE3 = /^[a-z][a-z0-9-]*\s*:/i;
12461
+ var GROUP_HEADING_RE4 = /^##\s+/;
11787
12462
  function dirname(filePath) {
11788
12463
  const last = filePath.lastIndexOf("/");
11789
12464
  return last > 0 ? filePath.substring(0, last) : "/";
@@ -11804,7 +12479,7 @@ function extractTagGroups(lines) {
11804
12479
  let current = null;
11805
12480
  for (const line5 of lines) {
11806
12481
  const trimmed = line5.trim();
11807
- if (GROUP_HEADING_RE3.test(trimmed)) {
12482
+ if (GROUP_HEADING_RE4.test(trimmed)) {
11808
12483
  const nameMatch = trimmed.match(/^##\s+(.+?)(?:\s+alias\s+\w+)?(?:\s*\([^)]+\))?\s*$/);
11809
12484
  const name = nameMatch ? nameMatch[1].trim().toLowerCase() : trimmed.substring(3).trim().toLowerCase();
11810
12485
  current = { name, lines: [line5] };
@@ -11848,7 +12523,7 @@ function parseFileHeader(lines) {
11848
12523
  tagsDirective = tagsMatch[1].trim();
11849
12524
  continue;
11850
12525
  }
11851
- if (OPTION_RE2.test(trimmed) && !trimmed.startsWith("##") && !lines[i].match(/^\s/)) {
12526
+ if (OPTION_RE3.test(trimmed) && !trimmed.startsWith("##") && !lines[i].match(/^\s/)) {
11852
12527
  const key = trimmed.split(":")[0].trim().toLowerCase();
11853
12528
  if (key !== "chart" && key !== "title" && !trimmed.includes("|")) {
11854
12529
  continue;
@@ -11877,7 +12552,7 @@ async function resolveFile(content, filePath, readFileFn, diagnostics, ancestorC
11877
12552
  headerLines.push(lines[i]);
11878
12553
  continue;
11879
12554
  }
11880
- if (GROUP_HEADING_RE3.test(trimmed)) continue;
12555
+ if (GROUP_HEADING_RE4.test(trimmed)) continue;
11881
12556
  if (lines[i] !== trimmed) continue;
11882
12557
  const tagsMatch = trimmed.match(TAGS_RE);
11883
12558
  if (tagsMatch) {
@@ -11908,7 +12583,7 @@ async function resolveFile(content, filePath, readFileFn, diagnostics, ancestorC
11908
12583
  const importMatch = line5.match(IMPORT_RE);
11909
12584
  if (!importMatch) {
11910
12585
  const trimmed = line5.trim();
11911
- if (GROUP_HEADING_RE3.test(trimmed) || inlineTagGroups.length > 0 && isTagGroupEntry(line5, bodyLines, i)) {
12586
+ if (GROUP_HEADING_RE4.test(trimmed) || inlineTagGroups.length > 0 && isTagGroupEntry(line5, bodyLines, i)) {
11912
12587
  continue;
11913
12588
  }
11914
12589
  resolvedBodyLines.push(line5);
@@ -12003,7 +12678,7 @@ function findBodyStart(lines) {
12003
12678
  if (inTagGroup) inTagGroup = false;
12004
12679
  continue;
12005
12680
  }
12006
- if (GROUP_HEADING_RE3.test(trimmed)) {
12681
+ if (GROUP_HEADING_RE4.test(trimmed)) {
12007
12682
  inTagGroup = true;
12008
12683
  continue;
12009
12684
  }
@@ -12015,7 +12690,7 @@ function findBodyStart(lines) {
12015
12690
  }
12016
12691
  if (HEADER_RE.test(trimmed)) continue;
12017
12692
  if (TAGS_RE.test(trimmed)) continue;
12018
- if (OPTION_RE2.test(trimmed) && !lines[i].match(/^\s/) && !trimmed.includes("|")) {
12693
+ if (OPTION_RE3.test(trimmed) && !lines[i].match(/^\s/) && !trimmed.includes("|")) {
12019
12694
  const key = trimmed.split(":")[0].trim().toLowerCase();
12020
12695
  if (key !== "chart" && key !== "title") {
12021
12696
  continue;
@@ -12030,7 +12705,7 @@ function isTagGroupEntry(line5, allLines, index) {
12030
12705
  for (let i = index - 1; i >= 0; i--) {
12031
12706
  const prev = allLines[i].trim();
12032
12707
  if (prev === "" || prev.startsWith("//")) continue;
12033
- if (GROUP_HEADING_RE3.test(prev)) return true;
12708
+ if (GROUP_HEADING_RE4.test(prev)) return true;
12034
12709
  if (allLines[i].match(/^\s+/)) continue;
12035
12710
  return false;
12036
12711
  }
@@ -12059,7 +12734,7 @@ init_layout4();
12059
12734
  init_flowchart_renderer();
12060
12735
  init_echarts();
12061
12736
  init_d3();
12062
- init_renderer4();
12737
+ init_renderer5();
12063
12738
  init_colors();
12064
12739
  init_palettes();
12065
12740
 
@@ -12134,6 +12809,8 @@ export {
12134
12809
  collapseOrgTree,
12135
12810
  colorNames,
12136
12811
  computeActivations,
12812
+ computeCardArchive,
12813
+ computeCardMove,
12137
12814
  computeTimeTicks,
12138
12815
  contrastText,
12139
12816
  decodeDiagramUrl,
@@ -12151,6 +12828,7 @@ export {
12151
12828
  hslToHex,
12152
12829
  inferParticipantType,
12153
12830
  injectBranding,
12831
+ isArchiveColumn,
12154
12832
  isSequenceBlock,
12155
12833
  isSequenceNote,
12156
12834
  isValidHex,
@@ -12176,6 +12854,7 @@ export {
12176
12854
  parseEChart,
12177
12855
  parseERDiagram,
12178
12856
  parseFlowchart,
12857
+ parseKanban,
12179
12858
  parseOrg,
12180
12859
  parseQuadrant,
12181
12860
  parseSequenceDgmo,
@@ -12191,6 +12870,8 @@ export {
12191
12870
  renderERDiagramForExport,
12192
12871
  renderFlowchart,
12193
12872
  renderFlowchartForExport,
12873
+ renderKanban,
12874
+ renderKanbanForExport,
12194
12875
  renderOrg,
12195
12876
  renderOrgForExport,
12196
12877
  renderQuadrant,