@diagrammo/dgmo 0.8.23 → 0.8.26

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (78) hide show
  1. package/.claude/commands/dgmo.md +43 -431
  2. package/.cursorrules +2 -2
  3. package/.windsurfrules +2 -2
  4. package/AGENTS.md +8 -5
  5. package/dist/cli.cjs +119 -114
  6. package/dist/editor.cjs +0 -2
  7. package/dist/editor.cjs.map +1 -1
  8. package/dist/editor.js +0 -2
  9. package/dist/editor.js.map +1 -1
  10. package/dist/highlight.cjs +0 -2
  11. package/dist/highlight.cjs.map +1 -1
  12. package/dist/highlight.js +0 -2
  13. package/dist/highlight.js.map +1 -1
  14. package/dist/index.cjs +719 -281
  15. package/dist/index.cjs.map +1 -1
  16. package/dist/index.d.cts +105 -18
  17. package/dist/index.d.ts +105 -18
  18. package/dist/index.js +709 -280
  19. package/dist/index.js.map +1 -1
  20. package/dist/internal.cjs +348 -51
  21. package/dist/internal.cjs.map +1 -1
  22. package/dist/internal.d.cts +93 -5
  23. package/dist/internal.d.ts +93 -5
  24. package/dist/internal.js +334 -38
  25. package/dist/internal.js.map +1 -1
  26. package/docs/guide/chart-area.md +17 -17
  27. package/docs/guide/chart-bar-stacked.md +12 -12
  28. package/docs/guide/chart-doughnut.md +10 -10
  29. package/docs/guide/chart-funnel.md +9 -9
  30. package/docs/guide/chart-heatmap.md +10 -10
  31. package/docs/guide/chart-kanban.md +2 -0
  32. package/docs/guide/chart-line.md +19 -19
  33. package/docs/guide/chart-multi-line.md +16 -16
  34. package/docs/guide/chart-pie.md +11 -11
  35. package/docs/guide/chart-polar-area.md +10 -10
  36. package/docs/guide/chart-radar.md +9 -9
  37. package/docs/guide/chart-scatter.md +24 -27
  38. package/docs/guide/index.md +3 -3
  39. package/docs/language-reference.md +46 -25
  40. package/fonts/Inter-Bold.ttf +0 -0
  41. package/fonts/Inter-Regular.ttf +0 -0
  42. package/fonts/LICENSE-Inter.txt +92 -0
  43. package/gallery/fixtures/bar-stacked.dgmo +12 -6
  44. package/gallery/fixtures/heatmap.dgmo +12 -6
  45. package/gallery/fixtures/multi-line.dgmo +11 -7
  46. package/gallery/fixtures/quadrant.dgmo +8 -8
  47. package/gallery/fixtures/scatter.dgmo +12 -12
  48. package/package.json +10 -3
  49. package/src/boxes-and-lines/parser.ts +13 -2
  50. package/src/boxes-and-lines/renderer.ts +22 -13
  51. package/src/chart-type-scoring.ts +162 -0
  52. package/src/chart-types.ts +437 -0
  53. package/src/cli.ts +147 -66
  54. package/src/completion.ts +0 -4
  55. package/src/d3.ts +40 -2
  56. package/src/dgmo-router.ts +85 -130
  57. package/src/editor/keywords.ts +0 -2
  58. package/src/fonts.ts +3 -2
  59. package/src/gantt/parser.ts +5 -1
  60. package/src/index.ts +24 -1
  61. package/src/infra/parser.ts +1 -1
  62. package/src/internal.ts +6 -2
  63. package/src/journey-map/layout.ts +8 -6
  64. package/src/journey-map/parser.ts +5 -1
  65. package/src/kanban/parser.ts +5 -1
  66. package/src/org/collapse.ts +1 -4
  67. package/src/org/parser.ts +1 -1
  68. package/src/org/renderer.ts +26 -17
  69. package/src/sequence/parser.ts +2 -2
  70. package/src/sequence/participant-inference.ts +0 -1
  71. package/src/sequence/renderer.ts +95 -263
  72. package/src/sharing.ts +0 -1
  73. package/src/sitemap/parser.ts +1 -1
  74. package/src/tech-radar/layout.ts +1 -2
  75. package/src/tech-radar/shared.ts +1 -37
  76. package/src/utils/tag-groups.ts +35 -5
  77. package/src/wireframe/parser.ts +3 -1
  78. package/src/tech-radar/index.ts +0 -14
package/dist/index.js CHANGED
@@ -2084,7 +2084,8 @@ function validateTagValues(entities, tagGroups, pushWarning, suggestFn) {
2084
2084
  }
2085
2085
  }
2086
2086
  }
2087
- function validateTagGroupNames(tagGroups, pushWarning) {
2087
+ function validateTagGroupNames(tagGroups, pushWarning, pushError) {
2088
+ const report = pushError ?? pushWarning;
2088
2089
  for (const group of tagGroups) {
2089
2090
  if (group.name.toLowerCase() === "none") {
2090
2091
  pushWarning(
@@ -2092,6 +2093,18 @@ function validateTagGroupNames(tagGroups, pushWarning) {
2092
2093
  `'none' is a reserved keyword and cannot be used as a tag group name`
2093
2094
  );
2094
2095
  }
2096
+ if (!VALID_TAG_IDENT_RE.test(group.name)) {
2097
+ report(
2098
+ group.lineNumber,
2099
+ `Tag group name "${group.name}" contains invalid characters \u2014 use a single identifier (letters, digits, underscore, hyphen)`
2100
+ );
2101
+ }
2102
+ if (group.alias != null && !VALID_TAG_IDENT_RE.test(group.alias)) {
2103
+ report(
2104
+ group.lineNumber,
2105
+ `Tag group alias "${group.alias}" contains invalid characters \u2014 use a single identifier (letters, digits, underscore, hyphen)`
2106
+ );
2107
+ }
2095
2108
  }
2096
2109
  }
2097
2110
  function injectDefaultTagMetadata(entities, tagGroups, skip) {
@@ -2130,12 +2143,13 @@ function resolveActiveTagGroup(tagGroups, explicitActiveTag, programmaticOverrid
2130
2143
  function matchTagBlockHeading(trimmed) {
2131
2144
  return parseTagDeclaration(trimmed);
2132
2145
  }
2133
- var TAG_BLOCK_NOCOLON_RE;
2146
+ var TAG_BLOCK_NOCOLON_RE, VALID_TAG_IDENT_RE;
2134
2147
  var init_tag_groups = __esm({
2135
2148
  "src/utils/tag-groups.ts"() {
2136
2149
  "use strict";
2137
2150
  init_parsing();
2138
2151
  TAG_BLOCK_NOCOLON_RE = /^tag\s+/i;
2152
+ VALID_TAG_IDENT_RE = /^[A-Za-z_][A-Za-z0-9_-]*$/;
2139
2153
  }
2140
2154
  });
2141
2155
 
@@ -3071,7 +3085,6 @@ var init_participant_inference = __esm({
3071
3085
  { pattern: /^Admin$/i, type: "actor" },
3072
3086
  { pattern: /^User$/i, type: "actor" },
3073
3087
  { pattern: /^Customer$/i, type: "actor" },
3074
- { pattern: /^Client$/i, type: "actor" },
3075
3088
  { pattern: /^Agent$/i, type: "actor" },
3076
3089
  { pattern: /^Person$/i, type: "actor" },
3077
3090
  { pattern: /^Buyer$/i, type: "actor" },
@@ -4069,7 +4082,7 @@ function parseSequenceDgmo(content) {
4069
4082
  entities.push({ metadata: g.metadata, lineNumber: g.lineNumber });
4070
4083
  }
4071
4084
  validateTagValues(entities, result.tagGroups, pushWarning, suggest);
4072
- validateTagGroupNames(result.tagGroups, pushWarning);
4085
+ validateTagGroupNames(result.tagGroups, pushWarning, pushError);
4073
4086
  }
4074
4087
  return result;
4075
4088
  }
@@ -4092,7 +4105,7 @@ var init_parser = __esm({
4092
4105
  init_parsing();
4093
4106
  init_tag_groups();
4094
4107
  KNOWN_SEQ_OPTIONS = /* @__PURE__ */ new Set(["active-tag"]);
4095
- KNOWN_SEQ_BOOLEANS = /* @__PURE__ */ new Set(["activations", "collapse-notes"]);
4108
+ KNOWN_SEQ_BOOLEANS = /* @__PURE__ */ new Set(["activations"]);
4096
4109
  VALID_PARTICIPANT_TYPES = /* @__PURE__ */ new Set([
4097
4110
  "service",
4098
4111
  "database",
@@ -8468,7 +8481,7 @@ function parseOrg(content, palette) {
8468
8481
  };
8469
8482
  collectAll(result.roots);
8470
8483
  validateTagValues(allNodes, result.tagGroups, pushWarning, suggest);
8471
- validateTagGroupNames(result.tagGroups, pushWarning);
8484
+ validateTagGroupNames(result.tagGroups, pushWarning, pushError);
8472
8485
  }
8473
8486
  if (result.roots.length === 0 && result.tagGroups.length === 0 && !result.error) {
8474
8487
  const diag = makeDgmoError(1, "No nodes found in org chart");
@@ -8801,7 +8814,11 @@ function parseKanban(content, palette) {
8801
8814
  if (result.columns.length === 0 && !result.error) {
8802
8815
  return fail(1, "No columns found. Use [Column Name] to define columns");
8803
8816
  }
8804
- validateTagGroupNames(result.tagGroups, warn);
8817
+ validateTagGroupNames(result.tagGroups, warn, (line11, msg) => {
8818
+ const diag = makeDgmoError(line11, msg);
8819
+ result.diagnostics.push(diag);
8820
+ if (!result.error) result.error = formatDgmoError(diag);
8821
+ });
8805
8822
  return result;
8806
8823
  }
8807
8824
  function parseCardLine(trimmed, lineNumber, counter, aliasMap, _palette, _diagnostics) {
@@ -9927,7 +9944,7 @@ function parseSitemap(content, palette) {
9927
9944
  };
9928
9945
  collectAll(result.roots);
9929
9946
  validateTagValues(allNodes, result.tagGroups, pushWarning, suggest);
9930
- validateTagGroupNames(result.tagGroups, pushWarning);
9947
+ validateTagGroupNames(result.tagGroups, pushWarning, pushError);
9931
9948
  }
9932
9949
  if (result.roots.length === 0 && result.tagGroups.length === 0 && !result.error) {
9933
9950
  const diag = makeDgmoError(1, "No pages found in sitemap");
@@ -10564,7 +10581,7 @@ function parseInfra(content) {
10564
10581
  }
10565
10582
  }
10566
10583
  }
10567
- validateTagGroupNames(result.tagGroups, warn);
10584
+ validateTagGroupNames(result.tagGroups, warn, setError);
10568
10585
  return result;
10569
10586
  }
10570
10587
  function extractSymbols4(docText) {
@@ -11505,7 +11522,11 @@ function parseGantt(content, palette) {
11505
11522
  warn(0, "sort tag has no effect \u2014 no tag groups defined.");
11506
11523
  result.options.sort = "default";
11507
11524
  }
11508
- validateTagGroupNames(result.tagGroups, warn);
11525
+ validateTagGroupNames(result.tagGroups, warn, (line11, msg) => {
11526
+ const diag = makeDgmoError(line11, msg);
11527
+ diagnostics.push(diag);
11528
+ if (!result.error) result.error = formatDgmoError(diag);
11529
+ });
11509
11530
  const hasSprintOption = result.options.sprintLength !== null || result.options.sprintNumber !== null || result.options.sprintStart !== null;
11510
11531
  const hasSprintUnit = hasSprintDurationUnit(result.nodes);
11511
11532
  if (hasSprintOption) {
@@ -11769,6 +11790,7 @@ function parseBoxesAndLines(content) {
11769
11790
  const groupLabels = /* @__PURE__ */ new Set();
11770
11791
  let lastNodeLabel = null;
11771
11792
  let lastSourceIsGroup = false;
11793
+ let lastNodeIndent = 0;
11772
11794
  let descState = null;
11773
11795
  function flushDescription() {
11774
11796
  if (descState && descState.lines.length > 0) {
@@ -12066,7 +12088,8 @@ function parseBoxesAndLines(content) {
12066
12088
  if (trimmed.startsWith("->") || /^-[^>].*->/.test(trimmed)) {
12067
12089
  const gs2 = currentGroupState();
12068
12090
  const inGroup = gs2 && indent > gs2.indent;
12069
- if (inGroup) {
12091
+ const indentedUnderNode = lastNodeLabel && !lastSourceIsGroup && indent > lastNodeIndent;
12092
+ if (inGroup && !indentedUnderNode) {
12070
12093
  const sourcePrefix = `[${gs2.group.label}]`;
12071
12094
  edgeText = `${sourcePrefix} ${trimmed}`;
12072
12095
  } else if (lastNodeLabel) {
@@ -12106,6 +12129,7 @@ function parseBoxesAndLines(content) {
12106
12129
  }
12107
12130
  lastNodeLabel = node.label;
12108
12131
  lastSourceIsGroup = false;
12132
+ lastNodeIndent = indent;
12109
12133
  const gs = currentGroupState();
12110
12134
  const isGroupChild = gs && indent > gs.indent;
12111
12135
  if (nodeLabels.has(node.label)) {
@@ -12174,7 +12198,11 @@ function parseBoxesAndLines(content) {
12174
12198
  if (result.tagGroups.length > 0) {
12175
12199
  injectDefaultTagMetadata(result.nodes, result.tagGroups);
12176
12200
  validateTagValues(result.nodes, result.tagGroups, pushWarning, suggest);
12177
- validateTagGroupNames(result.tagGroups, pushWarning);
12201
+ validateTagGroupNames(result.tagGroups, pushWarning, (line11, msg) => {
12202
+ const diag = makeDgmoError(line11, msg);
12203
+ result.diagnostics.push(diag);
12204
+ if (!result.error) result.error = diag.message;
12205
+ });
12178
12206
  }
12179
12207
  return result;
12180
12208
  }
@@ -13150,7 +13178,9 @@ function parseWireframe(content) {
13150
13178
  }
13151
13179
  }
13152
13180
  }
13153
- validateTagGroupNames(tagGroups, pushWarning);
13181
+ validateTagGroupNames(tagGroups, pushWarning, (line11, msg) => {
13182
+ diagnostics.push(makeDgmoError(line11, msg));
13183
+ });
13154
13184
  const error = diagnostics.find((d) => d.severity === "error") ? formatDgmoError(diagnostics.find((d) => d.severity === "error")) : null;
13155
13185
  return {
13156
13186
  title,
@@ -14078,7 +14108,11 @@ function parseJourneyMap(content, palette) {
14078
14108
  if (result.phases.length === 0 && result.steps.length === 0 && !result.error) {
14079
14109
  return fail(1, "No phases or steps found");
14080
14110
  }
14081
- validateTagGroupNames(result.tagGroups, warn);
14111
+ validateTagGroupNames(result.tagGroups, warn, (line11, msg) => {
14112
+ const diag = makeDgmoError(line11, msg);
14113
+ result.diagnostics.push(diag);
14114
+ if (!result.error) result.error = formatDgmoError(diag);
14115
+ });
14082
14116
  return result;
14083
14117
  }
14084
14118
  function parseStepLine(trimmed, lineNumber, counter, aliasMap, warn) {
@@ -14308,13 +14342,425 @@ var init_parser16 = __esm({
14308
14342
  }
14309
14343
  });
14310
14344
 
14345
+ // src/chart-types.ts
14346
+ var chartTypes;
14347
+ var init_chart_types = __esm({
14348
+ "src/chart-types.ts"() {
14349
+ "use strict";
14350
+ chartTypes = [
14351
+ // ── Tier 1 — Narrative / architecture diagrams ────────────
14352
+ {
14353
+ id: "journey-map",
14354
+ description: "User experience flow with emotion scores, phases, and annotations",
14355
+ triggers: [
14356
+ "user journey",
14357
+ "customer journey",
14358
+ "customer experience",
14359
+ "customer goes through",
14360
+ "user goes through",
14361
+ "customer path",
14362
+ "customer touchpoints",
14363
+ "cx flow",
14364
+ "ux journey",
14365
+ "onboarding flow",
14366
+ "persona journey",
14367
+ "empathy map",
14368
+ "service blueprint"
14369
+ ]
14370
+ },
14371
+ {
14372
+ id: "c4",
14373
+ description: "System architecture (context, container, component, deployment)",
14374
+ triggers: [
14375
+ "c4 diagram",
14376
+ "system context",
14377
+ "container diagram",
14378
+ "component diagram",
14379
+ "architecture overview",
14380
+ "software architecture"
14381
+ ]
14382
+ },
14383
+ {
14384
+ id: "er",
14385
+ description: "Database schemas and relationships",
14386
+ triggers: [
14387
+ "database schema",
14388
+ "er diagram",
14389
+ "entity relationship",
14390
+ "data model",
14391
+ "tables and relationships",
14392
+ "foreign keys"
14393
+ ]
14394
+ },
14395
+ {
14396
+ id: "class",
14397
+ description: "UML class hierarchies",
14398
+ triggers: [
14399
+ "uml class",
14400
+ "class hierarchy",
14401
+ "class diagram",
14402
+ "inheritance tree",
14403
+ "oop structure"
14404
+ ]
14405
+ },
14406
+ {
14407
+ id: "sequence",
14408
+ description: "Message / interaction flows",
14409
+ triggers: [
14410
+ "sequence diagram",
14411
+ "message flow",
14412
+ "api call flow",
14413
+ "request lifecycle",
14414
+ "interaction diagram",
14415
+ "call sequence"
14416
+ ],
14417
+ fallback: true
14418
+ },
14419
+ {
14420
+ id: "state",
14421
+ description: "State machine / lifecycle transitions",
14422
+ triggers: [
14423
+ "state diagram",
14424
+ "state machine",
14425
+ "state transitions",
14426
+ "lifecycle diagram",
14427
+ "status transitions"
14428
+ ]
14429
+ },
14430
+ {
14431
+ id: "infra",
14432
+ description: "Infrastructure traffic flow with RPS computation",
14433
+ triggers: [
14434
+ "infrastructure diagram",
14435
+ "traffic flow",
14436
+ "request path",
14437
+ "rps",
14438
+ "capacity planning",
14439
+ "network topology"
14440
+ ]
14441
+ },
14442
+ {
14443
+ id: "gantt",
14444
+ description: "Project scheduling with task dependencies and milestones",
14445
+ triggers: [
14446
+ "gantt chart",
14447
+ "project schedule",
14448
+ "sprint plan",
14449
+ "project timeline",
14450
+ "task dependencies",
14451
+ "project milestones"
14452
+ ]
14453
+ },
14454
+ // ── Tier 2 — Specialized structural diagrams ──────────────
14455
+ {
14456
+ id: "timeline",
14457
+ description: "Events, eras, and date ranges",
14458
+ triggers: [
14459
+ "event timeline",
14460
+ "historical timeline",
14461
+ "era chart",
14462
+ "period chart",
14463
+ "project history"
14464
+ ]
14465
+ },
14466
+ {
14467
+ id: "org",
14468
+ description: "Reporting hierarchy",
14469
+ triggers: [
14470
+ "org chart",
14471
+ "organization chart",
14472
+ "reporting structure",
14473
+ "hierarchy chart",
14474
+ "team structure"
14475
+ ]
14476
+ },
14477
+ {
14478
+ id: "sitemap",
14479
+ description: "Site / app navigation structure",
14480
+ triggers: [
14481
+ "sitemap",
14482
+ "site structure",
14483
+ "page hierarchy",
14484
+ "navigation structure",
14485
+ "app navigation"
14486
+ ]
14487
+ },
14488
+ {
14489
+ id: "kanban",
14490
+ description: "Task board columns",
14491
+ triggers: [
14492
+ "kanban board",
14493
+ "task board",
14494
+ "workflow columns",
14495
+ "todo doing done",
14496
+ "agile board"
14497
+ ]
14498
+ },
14499
+ {
14500
+ id: "tech-radar",
14501
+ description: "Technology adoption quadrants (adopt/trial/assess/hold)",
14502
+ triggers: [
14503
+ "tech radar",
14504
+ "technology radar",
14505
+ "tech adoption",
14506
+ "adopt trial assess hold",
14507
+ "tech choices"
14508
+ ]
14509
+ },
14510
+ {
14511
+ id: "mindmap",
14512
+ description: "Radial hierarchy of ideas branching from a central topic",
14513
+ triggers: [
14514
+ "mind map",
14515
+ "brainstorm diagram",
14516
+ "concept map",
14517
+ "idea tree",
14518
+ "radial ideas"
14519
+ ]
14520
+ },
14521
+ {
14522
+ id: "wireframe",
14523
+ description: "Low-fidelity UI layout with panels, controls, and annotations",
14524
+ triggers: [
14525
+ "wireframe",
14526
+ "ui mockup",
14527
+ "screen layout",
14528
+ "page layout",
14529
+ "low-fidelity mockup"
14530
+ ]
14531
+ },
14532
+ {
14533
+ id: "cycle",
14534
+ description: "Cyclical process visualization (PDCA, OODA, DevOps loops)",
14535
+ triggers: [
14536
+ "pdca cycle",
14537
+ "ooda loop",
14538
+ "feedback loop",
14539
+ "cyclical process",
14540
+ "devops loop",
14541
+ "continuous loop"
14542
+ ]
14543
+ },
14544
+ {
14545
+ id: "pyramid",
14546
+ description: "Stacked hierarchy of layers with descriptions (Maslow, DIKW)",
14547
+ triggers: [
14548
+ "pyramid diagram",
14549
+ "layered hierarchy",
14550
+ "maslow hierarchy",
14551
+ "dikw pyramid",
14552
+ "layered model"
14553
+ ]
14554
+ },
14555
+ // ── Tier 3 — Specialized analytical charts ────────────────
14556
+ {
14557
+ id: "quadrant",
14558
+ description: "2x2 positioning matrix",
14559
+ triggers: [
14560
+ "2x2 matrix",
14561
+ "priority matrix",
14562
+ "quadrant chart",
14563
+ "impact effort matrix",
14564
+ "positioning matrix"
14565
+ ]
14566
+ },
14567
+ {
14568
+ id: "venn",
14569
+ description: "Set overlaps",
14570
+ triggers: [
14571
+ "venn diagram",
14572
+ "set overlap",
14573
+ "intersection of",
14574
+ "shared traits",
14575
+ "overlapping circles"
14576
+ ]
14577
+ },
14578
+ {
14579
+ id: "funnel",
14580
+ description: "Conversion pipeline",
14581
+ triggers: [
14582
+ "conversion funnel",
14583
+ "sales funnel",
14584
+ "user funnel",
14585
+ "pipeline stages",
14586
+ "drop-off funnel"
14587
+ ]
14588
+ },
14589
+ {
14590
+ id: "slope",
14591
+ description: "Change between two periods",
14592
+ triggers: [
14593
+ "slope chart",
14594
+ "before and after",
14595
+ "two-period change",
14596
+ "delta chart",
14597
+ "shift comparison"
14598
+ ]
14599
+ },
14600
+ {
14601
+ id: "sankey",
14602
+ description: "Flow / allocation visualization",
14603
+ triggers: [
14604
+ "sankey diagram",
14605
+ "flow allocation",
14606
+ "budget flow",
14607
+ "energy flow",
14608
+ "traffic allocation"
14609
+ ]
14610
+ },
14611
+ {
14612
+ id: "chord",
14613
+ description: "Circular flow relationships",
14614
+ triggers: [
14615
+ "chord diagram",
14616
+ "circular flow",
14617
+ "relationship wheel",
14618
+ "team connections"
14619
+ ]
14620
+ },
14621
+ {
14622
+ id: "arc",
14623
+ description: "Network relationships",
14624
+ triggers: [
14625
+ "arc diagram",
14626
+ "relationship chart",
14627
+ "connection arcs",
14628
+ "network arcs"
14629
+ ]
14630
+ },
14631
+ {
14632
+ id: "wordcloud",
14633
+ description: "Term frequency visualization",
14634
+ triggers: [
14635
+ "word cloud",
14636
+ "tag cloud",
14637
+ "term frequency",
14638
+ "keyword frequency"
14639
+ ]
14640
+ },
14641
+ {
14642
+ id: "heatmap",
14643
+ description: "Matrix intensity visualization",
14644
+ triggers: [
14645
+ "heatmap",
14646
+ "intensity matrix",
14647
+ "activity heatmap",
14648
+ "correlation matrix"
14649
+ ]
14650
+ },
14651
+ {
14652
+ id: "function",
14653
+ description: "Mathematical expressions",
14654
+ triggers: [
14655
+ "function plot",
14656
+ "mathematical plot",
14657
+ "equation chart",
14658
+ "graph y=f(x)"
14659
+ ]
14660
+ },
14661
+ // ── Tier 4 — General-purpose data charts ──────────────────
14662
+ {
14663
+ id: "bar",
14664
+ description: "Categorical comparisons",
14665
+ triggers: ["bar chart", "categorical comparison", "bar graph"],
14666
+ fallback: true
14667
+ },
14668
+ {
14669
+ id: "line",
14670
+ description: "Trends over time",
14671
+ triggers: ["line chart", "trend over time", "time series"],
14672
+ fallback: true
14673
+ },
14674
+ {
14675
+ id: "multi-line",
14676
+ description: "Multiple series trends over time",
14677
+ triggers: [
14678
+ "multi-line chart",
14679
+ "multiple trends",
14680
+ "multiple series over time"
14681
+ ]
14682
+ },
14683
+ {
14684
+ id: "area",
14685
+ description: "Filled line chart",
14686
+ triggers: ["area chart", "filled line", "cumulative trend"]
14687
+ },
14688
+ {
14689
+ id: "pie",
14690
+ description: "Part-to-whole proportions",
14691
+ triggers: ["pie chart", "part to whole", "percentage breakdown"]
14692
+ },
14693
+ {
14694
+ id: "doughnut",
14695
+ description: "Ring-style pie chart",
14696
+ triggers: ["doughnut chart", "donut chart", "ring chart"]
14697
+ },
14698
+ {
14699
+ id: "radar",
14700
+ description: "Multi-dimensional metrics",
14701
+ triggers: ["radar chart", "spider chart", "multi-dimensional metrics"]
14702
+ },
14703
+ {
14704
+ id: "polar-area",
14705
+ description: "Radial bar chart",
14706
+ triggers: ["polar area", "radial bar chart"]
14707
+ },
14708
+ {
14709
+ id: "bar-stacked",
14710
+ description: "Multi-series categorical",
14711
+ triggers: [
14712
+ "stacked bar",
14713
+ "stacked bar chart",
14714
+ "multi-series bar",
14715
+ "composite bar"
14716
+ ]
14717
+ },
14718
+ {
14719
+ id: "scatter",
14720
+ description: "2D data points or bubble chart",
14721
+ triggers: [
14722
+ "scatter plot",
14723
+ "correlation plot",
14724
+ "bubble chart",
14725
+ "2d data points"
14726
+ ]
14727
+ },
14728
+ // ── Tier 5 — Generic catch-alls (listed last on purpose) ──
14729
+ {
14730
+ id: "flowchart",
14731
+ description: "Decision trees and process flows",
14732
+ triggers: [
14733
+ "flowchart",
14734
+ "decision tree",
14735
+ "if-then diagram",
14736
+ "process flow with decisions"
14737
+ ],
14738
+ fallback: true
14739
+ },
14740
+ {
14741
+ id: "boxes-and-lines",
14742
+ description: "General-purpose node-edge diagrams with groups and tags",
14743
+ triggers: [
14744
+ "boxes and lines",
14745
+ "nodes and edges",
14746
+ "generic diagram",
14747
+ "general-purpose network"
14748
+ ],
14749
+ fallback: true
14750
+ }
14751
+ ];
14752
+ }
14753
+ });
14754
+
14311
14755
  // src/dgmo-router.ts
14312
14756
  var dgmo_router_exports = {};
14313
14757
  __export(dgmo_router_exports, {
14314
14758
  CHART_TYPE_DESCRIPTIONS: () => CHART_TYPE_DESCRIPTIONS,
14759
+ chartTypeParsers: () => chartTypeParsers,
14315
14760
  getAllChartTypes: () => getAllChartTypes,
14316
14761
  getRenderCategory: () => getRenderCategory,
14317
14762
  isExtendedChartType: () => isExtendedChartType,
14763
+ knownChartTypeIds: () => knownChartTypeIds,
14318
14764
  looksLikeC4: () => looksLikeC4,
14319
14765
  looksLikeGantt: () => looksLikeGantt,
14320
14766
  parseDgmo: () => parseDgmo,
@@ -14373,7 +14819,7 @@ function isExtendedChartType(chartType) {
14373
14819
  return EXTENDED_CHART_TYPES.has(chartType.toLowerCase());
14374
14820
  }
14375
14821
  function getAllChartTypes() {
14376
- return [...DATA_CHART_TYPES, ...VISUALIZATION_TYPES, ...DIAGRAM_TYPES];
14822
+ return chartTypes.map((c) => c.id);
14377
14823
  }
14378
14824
  function parseDgmo(content) {
14379
14825
  const chartType = parseDgmoChartType(content);
@@ -14388,23 +14834,9 @@ function parseDgmo(content) {
14388
14834
  chartType: null
14389
14835
  };
14390
14836
  }
14391
- const directParser = PARSE_DISPATCH.get(chartType);
14392
- if (directParser) {
14393
- const result2 = directParser(content);
14394
- return {
14395
- diagnostics: [...result2.diagnostics, ...detectEmptyContent(content)],
14396
- chartType
14397
- };
14398
- }
14399
- if (STANDARD_CHART_TYPES2.has(chartType)) {
14400
- const result2 = parseChart(content);
14401
- return {
14402
- diagnostics: [...result2.diagnostics, ...detectEmptyContent(content)],
14403
- chartType
14404
- };
14405
- }
14406
- if (ECHART_TYPES.has(chartType)) {
14407
- const result2 = parseExtendedChart(content);
14837
+ const parser = PARSER_BY_ID.get(chartType);
14838
+ if (parser) {
14839
+ const result2 = parser(content);
14408
14840
  return {
14409
14841
  diagnostics: [...result2.diagnostics, ...detectEmptyContent(content)],
14410
14842
  chartType
@@ -14456,7 +14888,7 @@ function detectEmptyContent(content) {
14456
14888
  }
14457
14889
  return [];
14458
14890
  }
14459
- var GANTT_DURATION_RE, GANTT_DATE_RE, C4_TYPE_RE, DATA_CHART_TYPES, VISUALIZATION_TYPES, DIAGRAM_TYPES, EXTENDED_CHART_TYPES, STANDARD_CHART_TYPES2, CHART_TYPE_DESCRIPTIONS, ECHART_TYPES, PARSE_DISPATCH, ALL_KNOWN_TYPES;
14891
+ var GANTT_DURATION_RE, GANTT_DATE_RE, C4_TYPE_RE, DATA_CHART_TYPES, VISUALIZATION_TYPES, DIAGRAM_TYPES, EXTENDED_CHART_TYPES, CHART_TYPE_DESCRIPTIONS, chartTypeParsers, knownChartTypeIds, PARSER_BY_ID, ALL_KNOWN_TYPES;
14460
14892
  var init_dgmo_router = __esm({
14461
14893
  "src/dgmo-router.ts"() {
14462
14894
  "use strict";
@@ -14483,6 +14915,7 @@ var init_dgmo_router = __esm({
14483
14915
  init_parser16();
14484
14916
  init_parsing();
14485
14917
  init_diagnostics();
14918
+ init_chart_types();
14486
14919
  GANTT_DURATION_RE = /^\d+(?:\.\d+)?(?:min|bd|d|w|m|q|y|h)(?:\?)?\s+/;
14487
14920
  GANTT_DATE_RE = /^\d{4}-\d{2}-\d{2}(?:\s\d{2}:\d{2})?\s+/;
14488
14921
  C4_TYPE_RE = /\bis\s+an?\s+(person|system|container|component)\b/i;
@@ -14539,91 +14972,57 @@ var init_dgmo_router = __esm({
14539
14972
  "heatmap",
14540
14973
  "funnel"
14541
14974
  ]);
14542
- STANDARD_CHART_TYPES2 = /* @__PURE__ */ new Set([
14543
- "bar",
14544
- "line",
14545
- "multi-line",
14546
- "area",
14547
- "pie",
14548
- "doughnut",
14549
- "radar",
14550
- "polar-area",
14551
- "bar-stacked"
14552
- ]);
14553
- CHART_TYPE_DESCRIPTIONS = {
14554
- bar: "Bar chart \u2014 categorical comparisons",
14555
- line: "Line chart \u2014 trends over time; supports era bands (era start -> end Label (color)) for annotating named periods",
14556
- "multi-line": "Multi-line chart \u2014 multiple series trends over time; supports era bands",
14557
- area: "Area chart \u2014 filled line chart; supports era bands",
14558
- pie: "Pie chart \u2014 part-to-whole proportions",
14559
- doughnut: "Doughnut chart \u2014 ring-style pie chart",
14560
- radar: "Radar chart \u2014 multi-dimensional metrics",
14561
- "polar-area": "Polar area chart \u2014 radial bar chart",
14562
- "bar-stacked": "Stacked bar chart \u2014 multi-series categorical",
14563
- scatter: "Scatter plot \u2014 2D data points or bubble chart",
14564
- sankey: "Sankey diagram \u2014 flow/allocation visualization",
14565
- chord: "Chord diagram \u2014 circular flow relationships",
14566
- function: "Function plot \u2014 mathematical expressions",
14567
- heatmap: "Heatmap \u2014 matrix intensity visualization",
14568
- funnel: "Funnel chart \u2014 conversion pipeline",
14569
- slope: "Slope chart \u2014 change between two periods",
14570
- wordcloud: "Word cloud \u2014 term frequency visualization",
14571
- arc: "Arc diagram \u2014 network relationships",
14572
- timeline: "Timeline \u2014 events, eras, and date ranges",
14573
- venn: "Venn diagram \u2014 set overlaps",
14574
- quadrant: "Quadrant chart \u2014 2x2 positioning matrix",
14575
- "tech-radar": "Tech radar \u2014 technology adoption quadrants (adopt/trial/assess/hold)",
14576
- cycle: "Cycle diagram \u2014 cyclical process visualization (PDCA, OODA, DevOps loops)",
14577
- sequence: "Sequence diagram \u2014 message/interaction flows",
14578
- flowchart: "Flowchart \u2014 decision trees and process flows",
14579
- class: "Class diagram \u2014 UML class hierarchies",
14580
- er: "ER diagram \u2014 database schemas and relationships",
14581
- org: "Org chart \u2014 hierarchical tree structures",
14582
- kanban: "Kanban board \u2014 task/workflow columns",
14583
- c4: "C4 diagram \u2014 system architecture (context, container, component, deployment)",
14584
- state: "State diagram \u2014 state machine / lifecycle transitions",
14585
- sitemap: "Sitemap \u2014 navigable UI structure with pages, groups, and cross-link arrows",
14586
- infra: "Infrastructure diagram \u2014 traffic flow with RPS computation, capacity modeling, and latency analysis",
14587
- gantt: "Gantt chart \u2014 project scheduling with task dependencies and milestones",
14588
- "boxes-and-lines": "Boxes and lines \u2014 general-purpose node-edge diagrams with nested groups, tags, and shape inference",
14589
- mindmap: "Mindmap \u2014 radial hierarchy of ideas branching from a central topic",
14590
- wireframe: "Wireframe \u2014 low-fidelity UI layout with panels, controls, and annotations",
14591
- "journey-map": "Journey map \u2014 user experience flow with emotion scores, phases, and annotations",
14592
- pyramid: "Pyramid \u2014 hierarchical layered pyramid (Maslow, DIKW, learning pyramid); inverted for funnel-of-learning style"
14593
- };
14594
- ECHART_TYPES = /* @__PURE__ */ new Set([
14595
- "scatter",
14596
- "sankey",
14597
- "chord",
14598
- "function",
14599
- "heatmap",
14600
- "funnel"
14601
- ]);
14602
- PARSE_DISPATCH = /* @__PURE__ */ new Map([
14603
- ["sequence", (c) => parseSequenceDgmo(c)],
14604
- ["flowchart", (c) => parseFlowchart(c)],
14605
- ["class", (c) => parseClassDiagram(c)],
14606
- ["er", (c) => parseERDiagram(c)],
14607
- ["org", (c) => parseOrg(c)],
14608
- ["kanban", (c) => parseKanban(c)],
14609
- ["c4", (c) => parseC4(c)],
14610
- ["state", (c) => parseState(c)],
14611
- ["sitemap", (c) => parseSitemap(c)],
14612
- ["infra", (c) => parseInfra(c)],
14613
- ["gantt", (c) => parseGantt(c)],
14614
- ["boxes-and-lines", (c) => parseBoxesAndLines(c)],
14615
- ["mindmap", (c) => parseMindmap(c)],
14616
- ["wireframe", (c) => parseWireframe(c)],
14617
- ["tech-radar", (c) => parseTechRadar(c)],
14618
- ["cycle", (c) => parseCycle(c)],
14619
- ["journey-map", (c) => parseJourneyMap(c)],
14620
- ["pyramid", (c) => parsePyramid(c)]
14621
- ]);
14622
- ALL_KNOWN_TYPES = /* @__PURE__ */ new Set([
14623
- ...DATA_CHART_TYPES,
14624
- ...VISUALIZATION_TYPES,
14625
- ...DIAGRAM_TYPES
14626
- ]);
14975
+ CHART_TYPE_DESCRIPTIONS = Object.fromEntries(chartTypes.map((c) => [c.id, c.description]));
14976
+ chartTypeParsers = [
14977
+ // Structured diagrams (direct parsers)
14978
+ ["sequence", parseSequenceDgmo],
14979
+ ["flowchart", parseFlowchart],
14980
+ ["class", parseClassDiagram],
14981
+ ["er", parseERDiagram],
14982
+ ["state", parseState],
14983
+ ["org", parseOrg],
14984
+ ["kanban", parseKanban],
14985
+ ["c4", parseC4],
14986
+ ["sitemap", parseSitemap],
14987
+ ["infra", parseInfra],
14988
+ ["gantt", parseGantt],
14989
+ ["boxes-and-lines", parseBoxesAndLines],
14990
+ ["mindmap", parseMindmap],
14991
+ ["wireframe", parseWireframe],
14992
+ ["tech-radar", parseTechRadar],
14993
+ ["cycle", parseCycle],
14994
+ ["journey-map", parseJourneyMap],
14995
+ ["pyramid", parsePyramid],
14996
+ // Standard ECharts charts (parseChart)
14997
+ ["bar", parseChart],
14998
+ ["line", parseChart],
14999
+ ["multi-line", parseChart],
15000
+ ["area", parseChart],
15001
+ ["pie", parseChart],
15002
+ ["doughnut", parseChart],
15003
+ ["radar", parseChart],
15004
+ ["polar-area", parseChart],
15005
+ ["bar-stacked", parseChart],
15006
+ // Extended ECharts charts (parseExtendedChart)
15007
+ ["scatter", parseExtendedChart],
15008
+ ["sankey", parseExtendedChart],
15009
+ ["chord", parseExtendedChart],
15010
+ ["function", parseExtendedChart],
15011
+ ["heatmap", parseExtendedChart],
15012
+ ["funnel", parseExtendedChart],
15013
+ // D3 visualizations (parseVisualization)
15014
+ ["slope", parseVisualization],
15015
+ ["wordcloud", parseVisualization],
15016
+ ["arc", parseVisualization],
15017
+ ["timeline", parseVisualization],
15018
+ ["venn", parseVisualization],
15019
+ ["quadrant", parseVisualization]
15020
+ ];
15021
+ knownChartTypeIds = chartTypeParsers.map(
15022
+ ([id]) => id
15023
+ );
15024
+ PARSER_BY_ID = new Map(chartTypeParsers);
15025
+ ALL_KNOWN_TYPES = new Set(knownChartTypeIds);
14627
15026
  }
14628
15027
  });
14629
15028
 
@@ -19661,7 +20060,16 @@ function renderBoxesAndLines(container, parsed, layout, palette, isDark, options
19661
20060
  const clipId = `bl-clip-${group.label.replace(/[[\]\s]/g, "")}`;
19662
20061
  groupG.append("clipPath").attr("id", clipId).append("rect").attr("x", gx).attr("y", gy).attr("width", group.width).attr("height", group.height).attr("rx", NODE_RX);
19663
20062
  groupG.append("rect").attr("x", gx).attr("y", gy + group.height - COLLAPSE_BAR_HEIGHT3).attr("width", group.width).attr("height", COLLAPSE_BAR_HEIGHT3).attr("fill", strokeColor).attr("clip-path", `url(#${clipId})`).attr("class", "bl-collapse-bar");
19664
- groupG.append("text").attr("class", "bl-group-label").attr("x", group.x).attr("y", group.y).attr("text-anchor", "middle").attr("dominant-baseline", "central").attr("font-family", FONT_FAMILY).attr("font-size", GROUP_LABEL_FONT_SIZE).attr("font-weight", "600").attr("fill", palette.text).text(group.label);
20063
+ const maxLabelLines = Math.max(
20064
+ 2,
20065
+ Math.floor((group.height - 16) / (MIN_NODE_FONT_SIZE * 1.3))
20066
+ );
20067
+ const fitted = fitLabelToHeader(group.label, group.width, maxLabelLines);
20068
+ const lineH = fitted.fontSize * 1.3;
20069
+ const totalH = fitted.lines.length * lineH;
20070
+ for (let li = 0; li < fitted.lines.length; li++) {
20071
+ groupG.append("text").attr("class", "bl-group-label").attr("x", group.x).attr("y", group.y - totalH / 2 + lineH / 2 + li * lineH).attr("text-anchor", "middle").attr("dominant-baseline", "central").attr("font-family", FONT_FAMILY).attr("font-size", fitted.fontSize).attr("font-weight", "600").attr("fill", palette.text).text(fitted.lines[li]);
20072
+ }
19665
20073
  } else {
19666
20074
  groupG.append("rect").attr("x", gx).attr("y", gy).attr("width", group.width).attr("height", groupHeight).attr("rx", GROUP_RX).attr("ry", GROUP_RX).attr("fill", mix(palette.surface, palette.bg, 40)).attr("stroke", palette.textMuted).attr("stroke-width", 1).attr("stroke-opacity", 0.35);
19667
20075
  groupG.append("text").attr("class", "bl-group-label").attr("x", gx + group.width / 2).attr("y", gy + 18).attr("text-anchor", "middle").attr("font-family", FONT_FAMILY).attr("font-size", GROUP_LABEL_FONT_SIZE).attr("font-weight", "600").attr("fill", palette.text).text(group.label);
@@ -32144,7 +32552,6 @@ var init_renderer12 = __esm({
32144
32552
  // src/journey-map/layout.ts
32145
32553
  var layout_exports11 = {};
32146
32554
  __export(layout_exports11, {
32147
- COLLAPSED_PHASE_WIDTH: () => COLLAPSED_PHASE_WIDTH,
32148
32555
  TAG_STRIP_HEIGHT: () => TAG_STRIP_HEIGHT,
32149
32556
  layoutJourneyMap: () => layoutJourneyMap,
32150
32557
  scoreToColor: () => scoreToColor
@@ -32170,7 +32577,8 @@ function layoutJourneyMap(parsed, palette, options) {
32170
32577
  const annoIconIndent = ANNO_ICON_SIZE + ANNO_ICON_GAP;
32171
32578
  const annoTextW = STEP_CARD_WIDTH - CARD_PADDING_X2 * 2 - annoIconIndent;
32172
32579
  const descTextWidth = STEP_CARD_WIDTH - CARD_PADDING_X2 * 2;
32173
- const charWidth = 4.8;
32580
+ const FONT_SIZE_META2 = 10;
32581
+ const charWidth = FONT_SIZE_META2 * 0.6;
32174
32582
  const titleTextWidth = STEP_CARD_WIDTH - CARD_PADDING_X2 * 2;
32175
32583
  const titleCharWidth = 6.5;
32176
32584
  const TITLE_LINE_HEIGHT2 = 16;
@@ -32337,7 +32745,7 @@ function wrapLineCount(text, maxWidth, charWidth) {
32337
32745
  }
32338
32746
  return lines;
32339
32747
  }
32340
- var PADDING, TITLE_HEIGHT7, PERSONA_HEIGHT, CURVE_AREA_HEIGHT, CARD_GAP2, STEP_CARD_WIDTH, CARD_HEADER_HEIGHT2, CARD_META_LINE_HEIGHT2, PHASE_HEADER_HEIGHT, CARD_PADDING_X2, CARD_PADDING_Y2, ANNO_ICON_SIZE, ANNO_ICON_GAP, TAG_STRIP_HEIGHT, PHASE_GAP, COLUMN_PADDING2, FACE_ICON_SIZE, COLLAPSED_PHASE_WIDTH;
32748
+ var PADDING, TITLE_HEIGHT7, PERSONA_HEIGHT, CURVE_AREA_HEIGHT, CARD_GAP2, STEP_CARD_WIDTH, CARD_HEADER_HEIGHT2, CARD_META_LINE_HEIGHT2, PHASE_HEADER_HEIGHT, CARD_PADDING_X2, CARD_PADDING_Y2, ANNO_ICON_SIZE, ANNO_ICON_GAP, TAG_STRIP_HEIGHT, PHASE_GAP, COLUMN_PADDING2, FACE_ICON_SIZE;
32341
32749
  var init_layout12 = __esm({
32342
32750
  "src/journey-map/layout.ts"() {
32343
32751
  "use strict";
@@ -32359,7 +32767,6 @@ var init_layout12 = __esm({
32359
32767
  PHASE_GAP = 16;
32360
32768
  COLUMN_PADDING2 = 12;
32361
32769
  FACE_ICON_SIZE = 20;
32362
- COLLAPSED_PHASE_WIDTH = 60;
32363
32770
  }
32364
32771
  });
32365
32772
 
@@ -34553,7 +34960,6 @@ __export(renderer_exports16, {
34553
34960
  applyPositionOverrides: () => applyPositionOverrides,
34554
34961
  buildNoteMessageMap: () => buildNoteMessageMap,
34555
34962
  buildRenderSequence: () => buildRenderSequence,
34556
- collectNoteLineNumbers: () => collectNoteLineNumbers,
34557
34963
  computeActivations: () => computeActivations,
34558
34964
  groupMessagesBySection: () => groupMessagesBySection,
34559
34965
  parseInlineMarkdown: () => parseInlineMarkdown,
@@ -34937,9 +35343,6 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
34937
35343
  const groups = collapsed ? collapsed.groups : parsed.groups;
34938
35344
  const collapsedGroupIds = collapsed?.collapsedGroupIds ?? /* @__PURE__ */ new Map();
34939
35345
  const collapsedSections = options?.collapsedSections;
34940
- const expandedNoteLines = options?.expandedNoteLines;
34941
- const collapseNotesDisabled = parsedOptions["collapse-notes"]?.toLowerCase() === "no";
34942
- const isNoteExpanded = (note) => expandedNoteLines === void 0 || collapseNotesDisabled || expandedNoteLines.has(note.lineNumber);
34943
35346
  const sourceParticipants = collapsed ? collapsed.participants : parsed.participants;
34944
35347
  const participants = applyPositionOverrides(
34945
35348
  applyGroupOrdering(sourceParticipants, groups, messages)
@@ -35108,7 +35511,7 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
35108
35511
  const note = els[j];
35109
35512
  const sc = isNoteAfterSelfCall(note);
35110
35513
  const maxW = noteEffectiveMaxW(note.participantId, note.position, sc);
35111
- const noteH = isNoteExpanded(note) ? computeNoteHeight(note.text, charsForWidth(maxW)) : COLLAPSED_NOTE_H;
35514
+ const noteH = computeNoteHeight(note.text, charsForWidth(maxW));
35112
35515
  totalExtent += noteH + NOTE_OFFSET_BELOW;
35113
35516
  j++;
35114
35517
  }
@@ -35304,7 +35707,10 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
35304
35707
  prevNote.position,
35305
35708
  isNoteAfterSelfCall(prevNote)
35306
35709
  );
35307
- const prevNoteH = isNoteExpanded(prevNote) ? computeNoteHeight(prevNote.text, charsForWidth(prevMaxW)) : COLLAPSED_NOTE_H;
35710
+ const prevNoteH = computeNoteHeight(
35711
+ prevNote.text,
35712
+ charsForWidth(prevMaxW)
35713
+ );
35308
35714
  noteTopY = prevNoteY + prevNoteH + NOTE_OFFSET_BELOW;
35309
35715
  } else {
35310
35716
  noteTopY = stepY(si) + noteOffsetBelow(el);
@@ -35335,7 +35741,7 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
35335
35741
  note.position,
35336
35742
  isNoteAfterSelfCall(note)
35337
35743
  );
35338
- const noteH = isNoteExpanded(note) ? computeNoteHeight(note.text, charsForWidth(maxW)) : COLLAPSED_NOTE_H;
35744
+ const noteH = computeNoteHeight(note.text, charsForWidth(maxW));
35339
35745
  contentBottomY = Math.max(
35340
35746
  contentBottomY,
35341
35747
  noteTopY + noteH + NOTE_TRAILING_GAP
@@ -35405,24 +35811,6 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
35405
35811
  titleEl.attr("data-line-number", parsed.titleLineNumber);
35406
35812
  }
35407
35813
  }
35408
- const allNoteLineNumbers = [];
35409
- const collectNoteLines = (els) => {
35410
- for (const el of els) {
35411
- if (isSequenceNote(el)) {
35412
- allNoteLineNumbers.push(el.lineNumber);
35413
- } else if (isSequenceBlock(el)) {
35414
- collectNoteLines(el.children);
35415
- if ("elseChildren" in el) collectNoteLines(el.elseChildren);
35416
- if ("branches" in el && Array.isArray(el.branches)) {
35417
- for (const branch of el.branches) {
35418
- collectNoteLines(branch.children);
35419
- }
35420
- }
35421
- }
35422
- }
35423
- };
35424
- collectNoteLines(elements);
35425
- const showNotesControl = allNoteLineNumbers.length > 0 && !collapseNotesDisabled && expandedNoteLines !== void 0;
35426
35814
  const hasTagGroups = parsed.tagGroups.length > 0;
35427
35815
  const collapsedGroupNames = /* @__PURE__ */ new Set();
35428
35816
  const collapsedGroupMeta = /* @__PURE__ */ new Map();
@@ -35834,7 +36222,6 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
35834
36222
  }
35835
36223
  });
35836
36224
  const noteFill = isDark ? mix(palette.surface, palette.bg, 50) : mix(palette.bg, palette.surface, 15);
35837
- const collapsedNoteFill = mix(palette.textMuted, palette.bg, 15);
35838
36225
  const renderNoteElements = (els) => {
35839
36226
  for (const el of els) {
35840
36227
  if (isSequenceNote(el)) {
@@ -35842,83 +36229,54 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
35842
36229
  if (px === void 0) continue;
35843
36230
  const noteTopY = noteYMap.get(el);
35844
36231
  if (noteTopY === void 0) continue;
35845
- const expanded = isNoteExpanded(el);
35846
36232
  const isRight = el.position === "right";
35847
- if (expanded) {
35848
- const afterSelfCall = isNoteAfterSelfCall(el);
35849
- const maxW = noteEffectiveMaxW(
35850
- el.participantId,
35851
- el.position,
35852
- afterSelfCall
35853
- );
35854
- const maxChars = charsForWidth(maxW);
35855
- const wrappedLines = wrapTextLines(el.text, maxChars);
35856
- const noteH = wrappedLines.length * NOTE_LINE_H + NOTE_PAD_V * 2;
35857
- const maxLineLen = Math.max(...wrappedLines.map((l) => l.length));
35858
- const noteW = Math.min(
35859
- maxW,
35860
- Math.max(80, maxLineLen * NOTE_CHAR_W + NOTE_PAD_H * 2 + NOTE_FOLD)
35861
- );
35862
- const rightOffset = afterSelfCall && isRight ? ACTIVATION_WIDTH / 2 + SELF_CALL_WIDTH + NOTE_GAP : ACTIVATION_WIDTH + NOTE_GAP;
35863
- const noteX = isRight ? px + rightOffset : px - ACTIVATION_WIDTH - NOTE_GAP - noteW;
35864
- const noteG = svg.append("g").attr("class", "note").attr("data-note-toggle", "").attr("data-line-number", String(el.lineNumber)).attr("data-line-end", String(el.endLineNumber));
35865
- noteG.append("path").attr(
35866
- "d",
35867
- [
35868
- `M ${noteX} ${noteTopY}`,
35869
- `L ${noteX + noteW - NOTE_FOLD} ${noteTopY}`,
35870
- `L ${noteX + noteW} ${noteTopY + NOTE_FOLD}`,
35871
- `L ${noteX + noteW} ${noteTopY + noteH}`,
35872
- `L ${noteX} ${noteTopY + noteH}`,
35873
- "Z"
35874
- ].join(" ")
35875
- ).attr("fill", noteFill).attr("stroke", palette.textMuted).attr("stroke-width", 0.75).attr("class", "note-box");
35876
- noteG.append("path").attr(
35877
- "d",
35878
- [
35879
- `M ${noteX + noteW - NOTE_FOLD} ${noteTopY}`,
35880
- `L ${noteX + noteW - NOTE_FOLD} ${noteTopY + NOTE_FOLD}`,
35881
- `L ${noteX + noteW} ${noteTopY + NOTE_FOLD}`
35882
- ].join(" ")
35883
- ).attr("fill", "none").attr("stroke", palette.textMuted).attr("stroke-width", 0.75).attr("class", "note-fold");
35884
- wrappedLines.forEach((line11, li) => {
35885
- const textY = noteTopY + NOTE_PAD_V + (li + 1) * NOTE_LINE_H - 3;
35886
- const isBullet = line11.startsWith("- ");
35887
- const bulletIndent = isBullet ? 10 : 0;
35888
- const displayLine = isBullet ? line11.slice(2) : line11;
35889
- const textEl = noteG.append("text").attr("x", noteX + NOTE_PAD_H + bulletIndent).attr("y", textY).attr("fill", palette.text).attr("font-size", NOTE_FONT_SIZE).attr("class", "note-text");
35890
- if (isBullet) {
35891
- noteG.append("text").attr("x", noteX + NOTE_PAD_H).attr("y", textY).attr("fill", palette.text).attr("font-size", NOTE_FONT_SIZE).text("\u2022");
35892
- }
35893
- renderInlineText(textEl, displayLine, palette, NOTE_FONT_SIZE);
35894
- });
35895
- } else {
35896
- const cFold = 6;
35897
- const afterSelfCallC = isNoteAfterSelfCall(el);
35898
- const rightOffsetC = afterSelfCallC && isRight ? ACTIVATION_WIDTH / 2 + SELF_CALL_WIDTH + NOTE_GAP : ACTIVATION_WIDTH + NOTE_GAP;
35899
- const noteX = isRight ? px + rightOffsetC : px - ACTIVATION_WIDTH - NOTE_GAP - COLLAPSED_NOTE_W;
35900
- const noteG = svg.append("g").attr("class", "note note-collapsed").attr("data-note-toggle", "").attr("data-line-number", String(el.lineNumber)).attr("data-line-end", String(el.endLineNumber)).style("cursor", "pointer");
35901
- noteG.append("path").attr(
35902
- "d",
35903
- [
35904
- `M ${noteX} ${noteTopY}`,
35905
- `L ${noteX + COLLAPSED_NOTE_W - cFold} ${noteTopY}`,
35906
- `L ${noteX + COLLAPSED_NOTE_W} ${noteTopY + cFold}`,
35907
- `L ${noteX + COLLAPSED_NOTE_W} ${noteTopY + COLLAPSED_NOTE_H}`,
35908
- `L ${noteX} ${noteTopY + COLLAPSED_NOTE_H}`,
35909
- "Z"
35910
- ].join(" ")
35911
- ).attr("fill", collapsedNoteFill).attr("stroke", palette.border).attr("stroke-width", 0.75).attr("class", "note-box");
35912
- noteG.append("path").attr(
35913
- "d",
35914
- [
35915
- `M ${noteX + COLLAPSED_NOTE_W - cFold} ${noteTopY}`,
35916
- `L ${noteX + COLLAPSED_NOTE_W - cFold} ${noteTopY + cFold}`,
35917
- `L ${noteX + COLLAPSED_NOTE_W} ${noteTopY + cFold}`
35918
- ].join(" ")
35919
- ).attr("fill", "none").attr("stroke", palette.border).attr("stroke-width", 0.75).attr("class", "note-fold");
35920
- noteG.append("text").attr("x", noteX + COLLAPSED_NOTE_W / 2).attr("y", noteTopY + COLLAPSED_NOTE_H / 2 + 3).attr("text-anchor", "middle").attr("fill", palette.textMuted).attr("font-size", 9).attr("class", "note-text").text("\u2026");
35921
- }
36233
+ const afterSelfCall = isNoteAfterSelfCall(el);
36234
+ const maxW = noteEffectiveMaxW(
36235
+ el.participantId,
36236
+ el.position,
36237
+ afterSelfCall
36238
+ );
36239
+ const maxChars = charsForWidth(maxW);
36240
+ const wrappedLines = wrapTextLines(el.text, maxChars);
36241
+ const noteH = wrappedLines.length * NOTE_LINE_H + NOTE_PAD_V * 2;
36242
+ const maxLineLen = Math.max(...wrappedLines.map((l) => l.length));
36243
+ const noteW = Math.min(
36244
+ maxW,
36245
+ Math.max(80, maxLineLen * NOTE_CHAR_W + NOTE_PAD_H * 2 + NOTE_FOLD)
36246
+ );
36247
+ const rightOffset = afterSelfCall && isRight ? ACTIVATION_WIDTH / 2 + SELF_CALL_WIDTH + NOTE_GAP : ACTIVATION_WIDTH + NOTE_GAP;
36248
+ const noteX = isRight ? px + rightOffset : px - ACTIVATION_WIDTH - NOTE_GAP - noteW;
36249
+ const noteG = svg.append("g").attr("class", "note").attr("data-note-toggle", "").attr("data-line-number", String(el.lineNumber)).attr("data-line-end", String(el.endLineNumber));
36250
+ noteG.append("path").attr(
36251
+ "d",
36252
+ [
36253
+ `M ${noteX} ${noteTopY}`,
36254
+ `L ${noteX + noteW - NOTE_FOLD} ${noteTopY}`,
36255
+ `L ${noteX + noteW} ${noteTopY + NOTE_FOLD}`,
36256
+ `L ${noteX + noteW} ${noteTopY + noteH}`,
36257
+ `L ${noteX} ${noteTopY + noteH}`,
36258
+ "Z"
36259
+ ].join(" ")
36260
+ ).attr("fill", noteFill).attr("stroke", palette.textMuted).attr("stroke-width", 0.75).attr("class", "note-box");
36261
+ noteG.append("path").attr(
36262
+ "d",
36263
+ [
36264
+ `M ${noteX + noteW - NOTE_FOLD} ${noteTopY}`,
36265
+ `L ${noteX + noteW - NOTE_FOLD} ${noteTopY + NOTE_FOLD}`,
36266
+ `L ${noteX + noteW} ${noteTopY + NOTE_FOLD}`
36267
+ ].join(" ")
36268
+ ).attr("fill", "none").attr("stroke", palette.textMuted).attr("stroke-width", 0.75).attr("class", "note-fold");
36269
+ wrappedLines.forEach((line11, li) => {
36270
+ const textY = noteTopY + NOTE_PAD_V + (li + 1) * NOTE_LINE_H - 3;
36271
+ const isBullet = line11.startsWith("- ");
36272
+ const bulletIndent = isBullet ? 10 : 0;
36273
+ const displayLine = isBullet ? line11.slice(2) : line11;
36274
+ const textEl = noteG.append("text").attr("x", noteX + NOTE_PAD_H + bulletIndent).attr("y", textY).attr("fill", palette.text).attr("font-size", NOTE_FONT_SIZE).attr("class", "note-text");
36275
+ if (isBullet) {
36276
+ noteG.append("text").attr("x", noteX + NOTE_PAD_H).attr("y", textY).attr("fill", palette.text).attr("font-size", NOTE_FONT_SIZE).text("\u2022");
36277
+ }
36278
+ renderInlineText(textEl, displayLine, palette, NOTE_FONT_SIZE);
36279
+ });
35922
36280
  } else if (isSequenceBlock(el)) {
35923
36281
  renderNoteElements(el.children);
35924
36282
  if (el.elseIfBranches) {
@@ -35933,8 +36291,7 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
35933
36291
  if (elements && elements.length > 0) {
35934
36292
  renderNoteElements(elements);
35935
36293
  }
35936
- if (hasTagGroups || showNotesControl) {
35937
- const controlsExpanded = options?.controlsExpanded ?? false;
36294
+ if (hasTagGroups) {
35938
36295
  const legendY = TOP_MARGIN + titleOffset;
35939
36296
  const resolvedGroups = parsed.tagGroups.filter((tg) => tg.entries.length > 0).map((tg) => ({
35940
36297
  name: tg.name,
@@ -35943,37 +36300,16 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
35943
36300
  color: e.color
35944
36301
  }))
35945
36302
  }));
35946
- const allExpanded = showNotesControl && (options?.expandAllNotes ?? false);
35947
- const controlsGroup = showNotesControl ? {
35948
- toggles: [
35949
- {
35950
- id: "expand-all-notes",
35951
- type: "toggle",
35952
- label: "Expand Notes",
35953
- active: allExpanded,
35954
- onToggle: () => {
35955
- }
35956
- }
35957
- ]
35958
- } : void 0;
35959
36303
  const legendConfig = {
35960
36304
  groups: resolvedGroups,
35961
36305
  position: { placement: "top-center", titleRelation: "below-title" },
35962
- mode: "fixed",
35963
- controlsGroup
36306
+ mode: "fixed"
35964
36307
  };
35965
36308
  const legendState = {
35966
36309
  activeGroup: activeTagGroup ?? null,
35967
- controlsExpanded
35968
- };
35969
- const legendCallbacks = {
35970
- onControlsExpand: () => {
35971
- options?.onToggleControlsExpand?.();
35972
- },
35973
- onControlsToggle: (_toggleId, active) => {
35974
- options?.onExpandAllNotes?.(active);
35975
- }
36310
+ controlsExpanded: false
35976
36311
  };
36312
+ const legendCallbacks = {};
35977
36313
  const legendG = svg.append("g").attr("class", "sequence-legend").attr("transform", `translate(0,${legendY})`);
35978
36314
  renderLegendD3(
35979
36315
  legendG,
@@ -36012,26 +36348,6 @@ function buildNoteMessageMap(elements) {
36012
36348
  walk(elements);
36013
36349
  return map;
36014
36350
  }
36015
- function collectNoteLineNumbers(elements) {
36016
- const result = [];
36017
- const walk = (els) => {
36018
- for (const el of els) {
36019
- if (isSequenceNote(el)) {
36020
- result.push(el.lineNumber);
36021
- } else if (isSequenceBlock(el)) {
36022
- walk(el.children);
36023
- if (el.elseIfBranches) {
36024
- for (const branch of el.elseIfBranches) {
36025
- walk(branch.children);
36026
- }
36027
- }
36028
- walk(el.elseChildren);
36029
- }
36030
- }
36031
- };
36032
- walk(elements);
36033
- return result;
36034
- }
36035
36351
  function renderParticipant(svg, participant, cx, cy, palette, isDark, color, tagAttr) {
36036
36352
  const g = svg.append("g").attr("transform", `translate(${cx}, ${cy})`).attr("class", "participant").attr("data-participant-id", participant.id);
36037
36353
  if (tagAttr) {
@@ -36087,7 +36403,7 @@ function renderParticipant(svg, participant, cx, cy, palette, isDark, color, tag
36087
36403
  });
36088
36404
  }
36089
36405
  }
36090
- var PARTICIPANT_GAP, PARTICIPANT_BOX_WIDTH, PARTICIPANT_BOX_HEIGHT, TOP_MARGIN, TITLE_HEIGHT8, PARTICIPANT_Y_OFFSET, SERVICE_BORDER_RADIUS, MESSAGE_START_OFFSET, LIFELINE_TAIL, ARROWHEAD_SIZE, NOTE_MAX_W, NOTE_FOLD, NOTE_PAD_H, NOTE_PAD_V, NOTE_FONT_SIZE, NOTE_LINE_H, NOTE_GAP, NOTE_CHAR_W, NOTE_CHARS_PER_LINE, COLLAPSED_NOTE_H, COLLAPSED_NOTE_W, ACTIVATION_WIDTH, SELF_CALL_HEIGHT, SELF_CALL_WIDTH, NOTE_LANE_MAX, LABEL_CHAR_WIDTH, LABEL_MAX_CHARS, fill, stroke, SW, W, H;
36406
+ var PARTICIPANT_GAP, PARTICIPANT_BOX_WIDTH, PARTICIPANT_BOX_HEIGHT, TOP_MARGIN, TITLE_HEIGHT8, PARTICIPANT_Y_OFFSET, SERVICE_BORDER_RADIUS, MESSAGE_START_OFFSET, LIFELINE_TAIL, ARROWHEAD_SIZE, NOTE_MAX_W, NOTE_FOLD, NOTE_PAD_H, NOTE_PAD_V, NOTE_FONT_SIZE, NOTE_LINE_H, NOTE_GAP, NOTE_CHAR_W, NOTE_CHARS_PER_LINE, ACTIVATION_WIDTH, SELF_CALL_HEIGHT, SELF_CALL_WIDTH, NOTE_LANE_MAX, LABEL_CHAR_WIDTH, LABEL_MAX_CHARS, fill, stroke, SW, W, H;
36091
36407
  var init_renderer16 = __esm({
36092
36408
  "src/sequence/renderer.ts"() {
36093
36409
  "use strict";
@@ -36122,8 +36438,6 @@ var init_renderer16 = __esm({
36122
36438
  NOTE_CHARS_PER_LINE = Math.floor(
36123
36439
  (NOTE_MAX_W - NOTE_PAD_H * 2 - NOTE_FOLD) / NOTE_CHAR_W
36124
36440
  );
36125
- COLLAPSED_NOTE_H = 20;
36126
- COLLAPSED_NOTE_W = 40;
36127
36441
  ACTIVATION_WIDTH = 10;
36128
36442
  SELF_CALL_HEIGHT = 25;
36129
36443
  SELF_CALL_WIDTH = 30;
@@ -37094,7 +37408,12 @@ function parseVisualization(content, palette) {
37094
37408
  );
37095
37409
  validateTagGroupNames(
37096
37410
  result.timelineTagGroups,
37097
- (line11, msg) => result.diagnostics.push(makeDgmoError(line11, msg, "warning"))
37411
+ (line11, msg) => result.diagnostics.push(makeDgmoError(line11, msg, "warning")),
37412
+ (line11, msg) => {
37413
+ const diag = makeDgmoError(line11, msg);
37414
+ result.diagnostics.push(diag);
37415
+ if (!result.error) result.error = formatDgmoError(diag);
37416
+ }
37098
37417
  );
37099
37418
  for (const group of result.timelineTagGroups) {
37100
37419
  if (!group.defaultValue) continue;
@@ -37676,8 +37995,10 @@ function renderEras(g, eras, scale, isVertical, innerWidth, innerHeight, onEnter
37676
37995
  eras.forEach((era, i) => {
37677
37996
  const startVal = parseTimelineDate(era.startDate);
37678
37997
  const endVal = parseTimelineDate(era.endDate);
37998
+ if (!Number.isFinite(startVal) || !Number.isFinite(endVal)) return;
37679
37999
  const start = scale(startVal);
37680
38000
  const end = scale(endVal);
38001
+ if (!Number.isFinite(start) || !Number.isFinite(end)) return;
37681
38002
  const color = era.color || eraColors[i % eraColors.length];
37682
38003
  const eraG = g.append("g").attr("class", "tl-era").attr("data-line-number", String(era.lineNumber)).attr("data-era-start", String(startVal)).attr("data-era-end", String(endVal)).style("cursor", "pointer").on("mouseenter", function(event) {
37683
38004
  onEnter(startVal, endVal);
@@ -37706,7 +38027,9 @@ function renderMarkers(g, markers, scale, isVertical, innerWidth, innerHeight, _
37706
38027
  const defaultColor = palette?.accent || "#d08770";
37707
38028
  markers.forEach((marker) => {
37708
38029
  const dateVal = parseTimelineDate(marker.date);
38030
+ if (!Number.isFinite(dateVal)) return;
37709
38031
  const pos = scale(dateVal);
38032
+ if (!Number.isFinite(pos)) return;
37710
38033
  const color = marker.color || defaultColor;
37711
38034
  const lineOpacity = 0.5;
37712
38035
  const diamondSize = 5;
@@ -37990,6 +38313,30 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
37990
38313
  latestEndDateStr = ev.endDate ?? ev.date;
37991
38314
  }
37992
38315
  }
38316
+ for (const era of timelineEras) {
38317
+ const eraStartNum = parseTimelineDate(era.startDate);
38318
+ const eraEndNum = parseTimelineDate(era.endDate);
38319
+ if (Number.isFinite(eraStartNum) && eraStartNum < minDate) {
38320
+ minDate = eraStartNum;
38321
+ earliestStartDateStr = era.startDate;
38322
+ }
38323
+ if (Number.isFinite(eraEndNum) && eraEndNum > maxDate) {
38324
+ maxDate = eraEndNum;
38325
+ latestEndDateStr = era.endDate;
38326
+ }
38327
+ }
38328
+ for (const marker of timelineMarkers) {
38329
+ const markerNum = parseTimelineDate(marker.date);
38330
+ if (!Number.isFinite(markerNum)) continue;
38331
+ if (markerNum < minDate) {
38332
+ minDate = markerNum;
38333
+ earliestStartDateStr = marker.date;
38334
+ }
38335
+ if (markerNum > maxDate) {
38336
+ maxDate = markerNum;
38337
+ latestEndDateStr = marker.date;
38338
+ }
38339
+ }
37993
38340
  const datePadding = (maxDate - minDate) * 0.05 || 0.5;
37994
38341
  const FADE_OPACITY2 = 0.1;
37995
38342
  function fadeToGroup(g, groupName) {
@@ -40958,6 +41305,83 @@ async function render(content, options) {
40958
41305
  return { svg, diagnostics };
40959
41306
  }
40960
41307
 
41308
+ // src/index.ts
41309
+ init_chart_types();
41310
+
41311
+ // src/chart-type-scoring.ts
41312
+ init_chart_types();
41313
+ var TYPOGRAPHIC_REPLACEMENTS = [
41314
+ [/[‘’]/g, "'"],
41315
+ // curly single quotes
41316
+ [/[“”]/g, '"'],
41317
+ // curly double quotes
41318
+ [/[–—]/g, "-"],
41319
+ // en/em dash
41320
+ [/×/g, "x"]
41321
+ // unicode multiplication → ASCII (for "2×2" vs "2x2")
41322
+ ];
41323
+ function normalize(s) {
41324
+ let out = s.normalize("NFKD").toLowerCase();
41325
+ for (const [re, repl] of TYPOGRAPHIC_REPLACEMENTS)
41326
+ out = out.replace(re, repl);
41327
+ return out.split(/[^a-z0-9]+/).filter(Boolean);
41328
+ }
41329
+ function matchesContiguously(promptTokens, triggerTokens) {
41330
+ if (triggerTokens.length === 0 || triggerTokens.length > promptTokens.length)
41331
+ return false;
41332
+ outer: for (let i = 0; i <= promptTokens.length - triggerTokens.length; i++) {
41333
+ for (let j = 0; j < triggerTokens.length; j++) {
41334
+ if (promptTokens[i + j] !== triggerTokens[j]) continue outer;
41335
+ }
41336
+ return true;
41337
+ }
41338
+ return false;
41339
+ }
41340
+ function scoreChartType(prompt, type) {
41341
+ const promptTokens = normalize(prompt);
41342
+ const matched = [];
41343
+ let score = 0;
41344
+ for (const trigger of type.triggers) {
41345
+ const triggerTokens = normalize(trigger);
41346
+ if (matchesContiguously(promptTokens, triggerTokens)) {
41347
+ matched.push(trigger);
41348
+ score += triggerTokens.length;
41349
+ }
41350
+ }
41351
+ const descTokens = new Set(normalize(type.description));
41352
+ let descHits = 0;
41353
+ for (const t of promptTokens) if (descTokens.has(t)) descHits++;
41354
+ score += descHits * 0.25;
41355
+ return { score, matched };
41356
+ }
41357
+ var MIN_PRIMARY_SCORE = 1;
41358
+ var AMBIGUITY_THRESHOLD = 0.5;
41359
+ function confidence(top, second) {
41360
+ if (top < MIN_PRIMARY_SCORE) return "ambiguous";
41361
+ if (second === 0) return "high";
41362
+ if (top >= second * 2) return "high";
41363
+ if (top - second < AMBIGUITY_THRESHOLD) return "ambiguous";
41364
+ return "medium";
41365
+ }
41366
+ function suggestChartTypes(prompt) {
41367
+ const scored = [];
41368
+ for (const type of chartTypes) {
41369
+ const { score, matched } = scoreChartType(prompt, type);
41370
+ if (score > 0) scored.push({ type, score, matched });
41371
+ }
41372
+ scored.sort((a, b) => b.score - a.score);
41373
+ const fallback = chartTypes.filter((c) => c.fallback);
41374
+ const topScore = scored[0]?.score ?? 0;
41375
+ const secondScore = scored[1]?.score ?? 0;
41376
+ const fellBack = topScore < MIN_PRIMARY_SCORE;
41377
+ return {
41378
+ ranked: scored,
41379
+ fallback,
41380
+ confidence: confidence(topScore, secondScore),
41381
+ fellBack
41382
+ };
41383
+ }
41384
+
40961
41385
  // src/index.ts
40962
41386
  init_dgmo_router();
40963
41387
  init_chart();
@@ -41869,10 +42293,6 @@ var COMPLETION_REGISTRY = /* @__PURE__ */ new Map([
41869
42293
  description: "Show activation bars",
41870
42294
  values: ["on", "off"]
41871
42295
  },
41872
- "collapse-notes": {
41873
- description: "Collapse note blocks",
41874
- values: ["yes", "no"]
41875
- },
41876
42296
  "active-tag": { description: "Active tag group name" }
41877
42297
  })
41878
42298
  ],
@@ -42609,6 +43029,7 @@ function extractJourneyMapSymbols(docText) {
42609
43029
  init_parsing();
42610
43030
  export {
42611
43031
  ALL_CHART_TYPES,
43032
+ AMBIGUITY_THRESHOLD,
42612
43033
  ARROW_DIAGNOSTIC_CODES,
42613
43034
  CHART_TYPES,
42614
43035
  CHART_TYPE_DESCRIPTIONS,
@@ -42617,6 +43038,7 @@ export {
42617
43038
  INFRA_BEHAVIOR_KEYS,
42618
43039
  LEGEND_HEIGHT,
42619
43040
  METADATA_KEY_SET,
43041
+ MIN_PRIMARY_SCORE,
42620
43042
  PIPE_METADATA,
42621
43043
  RECOGNIZED_COLOR_NAMES,
42622
43044
  RULE_COUNT,
@@ -42632,13 +43054,15 @@ export {
42632
43054
  buildTagLaneRowList,
42633
43055
  calculateSchedule,
42634
43056
  catppuccinPalette,
43057
+ confidence as chartTypeConfidence,
43058
+ chartTypeParsers,
43059
+ chartTypes,
42635
43060
  collapseBoxesAndLines,
42636
43061
  collapseMindmapTree,
42637
43062
  collapseOrgTree,
42638
43063
  collapseSitemapTree,
42639
43064
  collapseStateGroups,
42640
43065
  collectDiagramRoles,
42641
- collectNoteLineNumbers,
42642
43066
  collectTasks,
42643
43067
  colorNames,
42644
43068
  computeActivations,
@@ -42684,6 +43108,7 @@ export {
42684
43108
  isSequenceBlock,
42685
43109
  isSequenceNote,
42686
43110
  isValidHex,
43111
+ knownChartTypeIds,
42687
43112
  layoutBoxesAndLines,
42688
43113
  layoutC4Components,
42689
43114
  layoutC4Containers,
@@ -42706,10 +43131,12 @@ export {
42706
43131
  looksLikeState,
42707
43132
  makeDgmoError,
42708
43133
  matchColorParens,
43134
+ matchesContiguously,
42709
43135
  mix,
42710
43136
  monokaiPalette,
42711
43137
  nord,
42712
43138
  nordPalette,
43139
+ normalize as normalizeChartTypePrompt,
42713
43140
  oneDarkPalette,
42714
43141
  orderArcNodes,
42715
43142
  parseAndLayoutInfra,
@@ -42801,9 +43228,11 @@ export {
42801
43228
  resolveTaskName,
42802
43229
  rollUpContextRelationships,
42803
43230
  rosePinePalette,
43231
+ scoreChartType,
42804
43232
  seriesColors,
42805
43233
  shade,
42806
43234
  solarizedPalette,
43235
+ suggestChartTypes,
42807
43236
  tint,
42808
43237
  tokyoNightPalette,
42809
43238
  truncateBareUrl,