schematex 0.8.0 → 0.8.2

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 (89) hide show
  1. package/dist/ai/ai-sdk.cjs +9 -9
  2. package/dist/ai/ai-sdk.d.cts +3 -3
  3. package/dist/ai/ai-sdk.d.ts +3 -3
  4. package/dist/ai/ai-sdk.js +4 -4
  5. package/dist/ai/index.cjs +15 -15
  6. package/dist/ai/index.d.cts +3 -3
  7. package/dist/ai/index.d.ts +3 -3
  8. package/dist/ai/index.js +4 -4
  9. package/dist/{api-BnJAPCwC.d.cts → api-BDMaX1cT.d.cts} +1 -1
  10. package/dist/{api-DAZJGq9r.d.ts → api-OED2jUVj.d.ts} +1 -1
  11. package/dist/browser.cjs +10 -10
  12. package/dist/browser.d.cts +3 -3
  13. package/dist/browser.d.ts +3 -3
  14. package/dist/browser.js +4 -4
  15. package/dist/{chunk-2YBBDPOW.cjs → chunk-AJJYWXZB.cjs} +2 -2
  16. package/dist/chunk-AJJYWXZB.cjs.map +1 -0
  17. package/dist/{chunk-TXMT4XLE.js → chunk-FLDHD4RM.js} +141 -7
  18. package/dist/chunk-FLDHD4RM.js.map +1 -0
  19. package/dist/{chunk-WNGOG4CI.js → chunk-GDZNTILD.js} +5 -3
  20. package/dist/chunk-GDZNTILD.js.map +1 -0
  21. package/dist/{chunk-RKN6QJ7K.cjs → chunk-HWNVSNDJ.cjs} +143 -9
  22. package/dist/chunk-HWNVSNDJ.cjs.map +1 -0
  23. package/dist/{chunk-6DVK5M2J.js → chunk-KF3DFASA.js} +2 -2
  24. package/dist/chunk-KF3DFASA.js.map +1 -0
  25. package/dist/{chunk-KUITLG4N.cjs → chunk-LENRV7ZJ.cjs} +5 -3
  26. package/dist/chunk-LENRV7ZJ.cjs.map +1 -0
  27. package/dist/{chunk-XI5QP7LM.js → chunk-LM5X7ZNR.js} +973 -95
  28. package/dist/chunk-LM5X7ZNR.js.map +1 -0
  29. package/dist/{chunk-3CSST5GZ.cjs → chunk-UGB42BGK.cjs} +975 -96
  30. package/dist/chunk-UGB42BGK.cjs.map +1 -0
  31. package/dist/{diagnostics-B-jOt6Ua.d.cts → diagnostics-hObcaaFC.d.cts} +1 -1
  32. package/dist/{diagnostics-B-jOt6Ua.d.ts → diagnostics-hObcaaFC.d.ts} +1 -1
  33. package/dist/diagrams/blockdiagram/index.d.cts +1 -1
  34. package/dist/diagrams/blockdiagram/index.d.ts +1 -1
  35. package/dist/diagrams/circuit/index.d.cts +1 -1
  36. package/dist/diagrams/circuit/index.d.ts +1 -1
  37. package/dist/diagrams/ecomap/index.d.cts +1 -1
  38. package/dist/diagrams/ecomap/index.d.ts +1 -1
  39. package/dist/diagrams/entity/index.cjs +5 -5
  40. package/dist/diagrams/entity/index.d.cts +1 -1
  41. package/dist/diagrams/entity/index.d.ts +1 -1
  42. package/dist/diagrams/entity/index.js +1 -1
  43. package/dist/diagrams/fishbone/index.d.cts +1 -1
  44. package/dist/diagrams/fishbone/index.d.ts +1 -1
  45. package/dist/diagrams/flowchart/index.d.cts +2 -2
  46. package/dist/diagrams/flowchart/index.d.ts +2 -2
  47. package/dist/diagrams/genogram/index.d.cts +1 -1
  48. package/dist/diagrams/genogram/index.d.ts +1 -1
  49. package/dist/diagrams/ladder/index.d.cts +1 -1
  50. package/dist/diagrams/ladder/index.d.ts +1 -1
  51. package/dist/diagrams/logic/index.d.cts +1 -1
  52. package/dist/diagrams/logic/index.d.ts +1 -1
  53. package/dist/diagrams/orgchart/index.d.cts +1 -1
  54. package/dist/diagrams/orgchart/index.d.ts +1 -1
  55. package/dist/diagrams/pedigree/index.d.cts +1 -1
  56. package/dist/diagrams/pedigree/index.d.ts +1 -1
  57. package/dist/diagrams/phylo/index.d.cts +1 -1
  58. package/dist/diagrams/phylo/index.d.ts +1 -1
  59. package/dist/diagrams/sld/index.cjs +7 -7
  60. package/dist/diagrams/sld/index.d.cts +1 -1
  61. package/dist/diagrams/sld/index.d.ts +1 -1
  62. package/dist/diagrams/sld/index.js +1 -1
  63. package/dist/diagrams/sociogram/index.d.cts +1 -1
  64. package/dist/diagrams/sociogram/index.d.ts +1 -1
  65. package/dist/diagrams/timing/index.d.cts +1 -1
  66. package/dist/diagrams/timing/index.d.ts +1 -1
  67. package/dist/diagrams/venn/index.d.cts +1 -1
  68. package/dist/diagrams/venn/index.d.ts +1 -1
  69. package/dist/{index-D-MAB6CH.d.cts → index-B0YO7rx8.d.cts} +1 -1
  70. package/dist/{index-8MaUFTMN.d.ts → index-u3KZBdas.d.ts} +1 -1
  71. package/dist/index.cjs +41 -37
  72. package/dist/index.d.cts +7 -5
  73. package/dist/index.d.ts +7 -5
  74. package/dist/index.js +5 -5
  75. package/dist/react.cjs +4 -4
  76. package/dist/react.d.cts +2 -2
  77. package/dist/react.d.ts +2 -2
  78. package/dist/react.js +3 -3
  79. package/dist/{tools-CV1JZ75-.d.cts → tools-CVgUmiGP.d.cts} +2 -2
  80. package/dist/{tools-CcPysgAD.d.ts → tools-CbBjmZVr.d.ts} +2 -2
  81. package/package.json +1 -1
  82. package/dist/chunk-2YBBDPOW.cjs.map +0 -1
  83. package/dist/chunk-3CSST5GZ.cjs.map +0 -1
  84. package/dist/chunk-6DVK5M2J.js.map +0 -1
  85. package/dist/chunk-KUITLG4N.cjs.map +0 -1
  86. package/dist/chunk-RKN6QJ7K.cjs.map +0 -1
  87. package/dist/chunk-TXMT4XLE.js.map +0 -1
  88. package/dist/chunk-WNGOG4CI.js.map +0 -1
  89. package/dist/chunk-XI5QP7LM.js.map +0 -1
@@ -1,4 +1,4 @@
1
- import { parseResult, renderResult } from './chunk-XI5QP7LM.js';
1
+ import { parseResult, renderResult } from './chunk-LM5X7ZNR.js';
2
2
 
3
3
  // src/ai/registry.ts
4
4
  var DIAGRAM_REGISTRY = [
@@ -413,6 +413,15 @@ var DIAGRAM_REGISTRY = [
413
413
  cluster: "network-infrastructure",
414
414
  standard: "Shostack, Threat Modeling (2014) STRIDE-per-element \xB7 Microsoft SDL \xB7 base DFD DeMarco/Yourdon; see 46-THREAT-MODEL-STRIDE-STANDARD.md + 31-DFD-STANDARD.md",
415
415
  syntaxKey: "threatmodel"
416
+ },
417
+ {
418
+ type: "welding",
419
+ name: "Welding symbols",
420
+ tagline: "AWS A2.4 / ISO 2553 welding callouts \u2014 the reference-line skeleton with weld glyphs, dimensions, and supplementary symbols placed correct-by-construction.",
421
+ useWhen: 'Use to annotate a welded joint on an engineering drawing: a horizontal reference line, a leader arrow to the joint, and a weld-symbol glyph above (other side) / below (arrow side) with size, length-pitch, groove angle, root opening, contour + finish. Header `welding [standard: aws|iso-a|iso-b]`; one `joint "label" { arrow: \u2026 other: \u2026 around field tail: \u2026 }` block per joint. Full glyph catalog (fillet, all groove types, plug/slot, spot/seam, back/backing, surfacing, edge) + weld-all-around, field flag, and tail process note. Validates illegal type/side/dimension combinations.',
422
+ cluster: "electrical-industrial",
423
+ standard: "AWS A2.4:2020 \xB7 ISO 2553:2019; see 47-WELDING-SYMBOL-STANDARD.md",
424
+ syntaxKey: "welding"
416
425
  }
417
426
  ];
418
427
  var DIAGRAM_SINCE = {
@@ -472,7 +481,9 @@ var DIAGRAM_SINCE = {
472
481
  gitgraph: "0.8.0",
473
482
  epc: "0.8.0",
474
483
  idef0: "0.8.0",
475
- threatmodel: "0.8.0"
484
+ threatmodel: "0.8.0",
485
+ // 0.8.1 — welding symbols (AWS A2.4 / ISO 2553)
486
+ welding: "0.8.1"
476
487
  };
477
488
  function getDiagramSince(type) {
478
489
  const resolved = resolveDiagramType(type);
@@ -1859,6 +1870,63 @@ If the LED doesn't light up, three things to check, in order: LED polarity (the
1859
1870
  "dsl": 'matrix johari "Self vs. Team \u2014 Q2 Reflection"\nstyle: table\nQ2: "Strong technical instincts"\nQ2: "Direct in code review"\nQ2: "Patient with juniors"\nQ1: "Interrupts in meetings"\nQ1: "Hard to read when stressed"\nQ3: "Imposter syndrome about leadership"\nQ3: "Anxiety about cross-team politics"\nQ4: "Capacity for difficult conversations under pressure"',
1860
1871
  "notes": "## Scenario\n\nA newly-promoted engineering manager runs a Johari exercise with her team during a 1:1 retro. She populates the **Open** cell (things both she and the team see); the team adds to **Blind** (things they see that she doesn't); she fills **Hidden** privately; **Unknown** is the open hypothesis space \u2014 capabilities and limitations that haven't surfaced yet.\n\nThe table form is the canonical Johari output. Coaches print it on a single page and walk through it with the coachee \u2014 a scatter plot of dots would defeat the entire purpose.\n\n## Annotation key\n\n- `matrix johari` \u2014 preset axes (Known to Self \xD7 Known to Others) with the four window panes\n- `style: table` \u2014 flips off axes/grid, places each pane title as a cell header, lists items as bullets\n- `Q1` = Blind (top-right: not known to self, known to others)\n- `Q2` = Open / Arena (top-left: known to self + others)\n- `Q3` = Hidden / Fa\xE7ade (bottom-left: known to self, not to others)\n- `Q4` = Unknown (bottom-right: not known to either \u2014 the growth hypothesis space)\n\n## How to read\n\nThe classic Johari coaching prompt: **how do you move items from Hidden \u2192 Open** (vulnerability work) **and from Blind \u2192 Open** (feedback-acceptance work)? An overstuffed Hidden pane signals psychological-safety debt; an empty Blind pane usually means the team hasn't been asked."
1861
1872
  },
1873
+ {
1874
+ "slug": "matrix-punnett-dihybrid",
1875
+ "diagram": "matrix",
1876
+ "title": "Dihybrid cross Punnett square (9:3:3:1)",
1877
+ "description": "A two-gene Punnett square where the engine computes the gametes, the 4\xD74 offspring grid, and the canonical 9:3:3:1 phenotype ratio \u2014 Mendel's pea seed shape \xD7 colour cross \u2014 with each phenotype class auto-tinted.",
1878
+ "standard": "Mendelian genetics (Punnett square)",
1879
+ "tags": [
1880
+ "matrix",
1881
+ "punnett",
1882
+ "genetics",
1883
+ "mendel",
1884
+ "dihybrid",
1885
+ "biology"
1886
+ ],
1887
+ "complexity": 3,
1888
+ "featured": false,
1889
+ "dsl": 'matrix punnett "Seed shape & colour (RrYy \xD7 RrYy)"\ncross: RrYy x RrYy\ntrait R: "Round" / "Wrinkled"\ntrait Y: "Yellow" / "Green"',
1890
+ "notes": "## What this shows\n\nA **Punnett square** predicts the offspring of a genetic cross. You write only the two parental genotypes \u2014 the engine does the Mendelian bookkeeping: it enumerates each parent's **gametes** (one allele per gene locus), fills the grid with every gamete combination, and counts the resulting **genotype and phenotype ratios**.\n\nThis is a **dihybrid** cross (two genes at once) \u2014 Mendel's classic pea experiment crossing seed shape (`R` round dominant / `r` wrinkled) with seed colour (`Y` yellow dominant / `y` green). Two heterozygous parents each produce four gametes (RY, Ry, rY, ry), so the grid is 4\xD74 = 16 boxes. The engine computes the famous **9:3:3:1** phenotype ratio \u2014 9 round-yellow : 3 wrinkled-yellow : 3 round-green : 1 wrinkled-green \u2014 and tints each box by its phenotype class so the ratio is visible at a glance. Case sets dominance (uppercase = dominant), and the optional `trait` lines name each phenotype so the legend reads in plain English."
1891
+ },
1892
+ {
1893
+ "slug": "matrix-punnett-monohybrid",
1894
+ "diagram": "matrix",
1895
+ "title": "Monohybrid cross Punnett square (3:1)",
1896
+ "description": "The classic single-gene Punnett square \u2014 two heterozygous parents (Bb \xD7 Bb) crossed for eye colour. The engine computes the gametes, the 2\xD72 grid, and the canonical 3:1 dominant-to-recessive phenotype ratio with a 1:2:1 genotype ratio.",
1897
+ "standard": "Mendelian genetics (Punnett square)",
1898
+ "tags": [
1899
+ "matrix",
1900
+ "punnett",
1901
+ "genetics",
1902
+ "mendel",
1903
+ "monohybrid",
1904
+ "biology"
1905
+ ],
1906
+ "complexity": 1,
1907
+ "featured": false,
1908
+ "dsl": 'matrix punnett "Eye color (Bb \xD7 Bb)"\ncross: Bb x Bb\ntrait B: "Brown eyes" / "Blue eyes"',
1909
+ "notes": "## What this shows\n\nThe **monohybrid cross** is where every genetics course starts: one gene, two heterozygous parents. Here both parents are `Bb` for eye colour \u2014 `B` (brown) is dominant, `b` (blue) recessive. You write only the cross; the engine does the Mendelian bookkeeping.\n\nEach `Bb` parent makes two gametes, `B` and `b`, so the grid is 2\xD72. The engine fills it \u2014 `BB`, `Bb`, `Bb`, `bb` \u2014 and computes the two ratios every student memorises: a **3:1 phenotype ratio** (3 brown-eyed : 1 blue-eyed) and a **1:2:1 genotype ratio** (1 `BB` : 2 `Bb` : 1 `bb`). The single recessive `bb` box is tinted apart from the three dominant boxes, and the `trait` line names the phenotypes so the legend reads in plain English. Allele case sets dominance \u2014 uppercase is dominant \u2014 so the notation is exactly what a textbook uses."
1910
+ },
1911
+ {
1912
+ "slug": "matrix-punnett-testcross",
1913
+ "diagram": "matrix",
1914
+ "title": "Test cross Punnett square (1:1)",
1915
+ "description": "A genetic test cross \u2014 crossing an organism of unknown genotype against a homozygous-recessive parent (Bb \xD7 bb) to reveal whether it is heterozygous. The engine computes the 1:1 phenotype ratio that signals a heterozygous parent.",
1916
+ "standard": "Mendelian genetics (Punnett square)",
1917
+ "tags": [
1918
+ "matrix",
1919
+ "punnett",
1920
+ "genetics",
1921
+ "mendel",
1922
+ "test-cross",
1923
+ "biology"
1924
+ ],
1925
+ "complexity": 2,
1926
+ "featured": false,
1927
+ "dsl": 'matrix punnett "Test cross (Bb \xD7 bb)"\ncross: Bb x bb\ntrait B: "Brown" / "Blue"',
1928
+ "notes": "## What this shows\n\nA **test cross** answers a practical genetics question: an organism shows the dominant trait, but is it `BB` or `Bb`? Cross it against a **homozygous-recessive** partner (`bb`) and read the offspring. You write only the cross; the engine computes the outcome that gives the answer.\n\nThe recessive `bb` parent contributes only `b` gametes, so the offspring genotypes come straight from the unknown parent's gametes. Crossing `Bb \xD7 bb` yields a **1:1 phenotype ratio** \u2014 half `Bb` (dominant phenotype), half `bb` (recessive) \u2014 the tell-tale signature of a heterozygous parent. (A `BB` parent would instead give all dominant offspring.) The engine fills the 2\xD71 grid, tints the two phenotype classes apart, and reports the 1:1 ratio, so the diagnostic result is immediate."
1929
+ },
1862
1930
  {
1863
1931
  "slug": "matrix-qfd-coffee-maker",
1864
1932
  "diagram": "matrix",
@@ -3316,6 +3384,25 @@ If the LED doesn't light up, three things to check, in order: LED polarity (the
3316
3384
  "featured": false,
3317
3385
  "dsl": 'venn "Programming Paradigms"\nset oop "Object-Oriented" [color: "#1E88E5"]\nset fp "Functional" [color: "#E53935"]\nset logic "Logic" [color: "#43A047"]\noop & fp : 180\noop & logic : 45\nfp & logic : 90\noop & fp & logic : 12\noop only : 620\nfp only : 340\nlogic only : 95',
3318
3386
  "notes": '## Scenario\n\nA CS instructor opens a lecture on programming paradigms with this Venn. Counts come from a language survey \u2014 how many languages offer strong OOP, FP, and logic support. The tiny triple-overlap (12) tells students that languages supporting all three well are rare; the large OOP-only region shows industry gravity; the FP \u2229 logic overlap (90) is where languages like Prolog-with-lambdas sit.\n\n## Annotation key\n\n- `set ID "Label"` \u2014 paradigm circle\n- `A & B : n` \u2014 number of languages supporting both paradigms strongly\n- `A only : n` \u2014 languages committed to a single paradigm\n\n## How to read\n\nEach circle represents a paradigm. Overlapping regions count multi-paradigm languages. The `oop & fp` intersection (180) is where modern mainstream languages \u2014 Scala, Kotlin, Swift, TypeScript \u2014 sit. The tiny triple intersection (12) is a reminder that truly multi-paradigm language design is expensive; the larger exclusive regions show how few languages commit to logic programming at all.'
3387
+ },
3388
+ {
3389
+ "slug": "welding-bracket-fillet",
3390
+ "diagram": "welding",
3391
+ "title": "Welded bracket \u2014 fillet + V-groove callouts",
3392
+ "description": "AWS A2.4 welding callouts on a fabrication drawing \u2014 an intermittent double-fillet bracket with a weld-all-around flag, and a full-penetration V-groove butt weld with backing, root opening, and the welding process in the tail.",
3393
+ "standard": "AWS A2.4 / ISO 2553 welding symbols",
3394
+ "tags": [
3395
+ "welding",
3396
+ "aws-a2.4",
3397
+ "iso-2553",
3398
+ "fillet",
3399
+ "groove",
3400
+ "fabrication"
3401
+ ],
3402
+ "complexity": 3,
3403
+ "featured": false,
3404
+ "dsl": 'welding "Bracket assembly"\njoint "gusset to column" {\n arrow: fillet size=8 len=50 pitch=150\n other: fillet size=6\n around\n field\n tail: "GMAW"\n}\njoint "splice plate (butt)" {\n arrow: vgroove angle=60 root=3 throat=12 contour=flush finish=G\n other: backing\n tail: "SMAW; E7018"\n}',
3405
+ "notes": "## What this shows\n\nA **welding symbol** is the standard way a drawing tells a fabricator how to weld a joint \u2014 codified by **AWS A2.4** (US) and **ISO 2553** (international). It is a *reference-line skeleton*: a horizontal line, a leader arrow to the joint, and a weld glyph snapped above (other side) or below (arrow side) the line, with dimensions in fixed slots.\n\nThe first joint is an **intermittent double fillet** \u2014 a `size=8` arrow-side fillet welded `50` long on a `150` pitch, a `size=6` fillet on the other side \u2014 carried **all around** the gusset (the open circle at the leader junction) as a **field weld** (the flag), with the **GMAW** process noted in the tail. The second joint is a full-penetration **V-groove butt weld**: a `60\xB0` included angle with a `3 mm` root opening and a `12 mm` effective throat, a **backing** weld on the far side, ground **flush**, welded **SMAW** with **E7018** electrode. Each callout is placed correct-by-construction \u2014 the engine owns the skeleton, you describe the weld."
3319
3406
  }
3320
3407
  ];
3321
3408
  var SYNTAX = {
@@ -3385,7 +3472,7 @@ var SYNTAX = {
3385
3472
  },
3386
3473
  "matrix": {
3387
3474
  "title": "Matrix / Quadrant diagram",
3388
- "content": '## 1. Your first matrix\n\nThe smallest useful matrix: a custom 2\xD72 with two labeled axes and three points.\n\n```\nmatrix "Feature Prioritization"\nx-axis: Low Effort \u2192 High Effort\ny-axis: Low Value \u2192 High Value\n\n"Add search" at (0.3, 0.8)\n"Rebuild pipeline" at (0.85, 0.7)\n"Update footer" at (0.2, 0.2)\n```\n\nFour rules cover 80% of usage:\n\n1. Start with the keyword `matrix`, optionally followed by a template name or a quoted title.\n2. Set the axes with `x-axis:` and `y-axis:` \u2014 or use a built-in template and skip this step entirely.\n3. Each point is `"Label" at (x, y)` where `x` and `y` are decimal fractions from 0.0 (low/left/bottom) to 1.0 (high/right/top).\n4. Add optional properties \u2014 `size:`, `category:`, `color:`, `shape:`, `highlight:` \u2014 after the coordinates.\n\n> Comments must start with `#` anywhere on a line (outside quoted strings).\n\n---\n\n## 2. Built-in templates\n\nA template pre-configures axes, quadrant labels, and grid size. Just use the template name as the second token on the header line.\n\n| Template | Grid | Use case |\n|---|---|---|\n| `eisenhower` | 2\xD72 | Urgency / Importance task prioritization |\n| `impact-effort` | 2\xD72 | Feature prioritization by impact vs. effort |\n| `rice` | 2\xD72 | RICE scoring \u2014 Reach \xD7 Impact vs. Effort |\n| `bcg` | 2\xD72 | Portfolio \u2014 Market Share vs. Growth rate |\n| `ansoff` | 2\xD72 | Product/market growth strategy |\n| `johari` | 2\xD72 | Self-awareness \u2014 known-to-self vs. known-to-others |\n| `9-box` | 3\xD73 | HR talent review \u2014 Performance vs. Potential |\n| `risk-matrix` | 5\xD75 | Risk assessment \u2014 Likelihood vs. Severity (heatmap) |\n\n```\nmatrix eisenhower "This Week"\n"Ship hotfix" at (0.1, 0.9) size: 5 highlight: true\n"Team 1:1s" at (0.1, 0.7) size: 3\n"Write Q3 OKRs" at (0.8, 0.85) size: 4\n"Inbox zero" at (0.1, 0.3) size: 2\n"Refactor auth" at (0.75, 0.4) size: 3\n```\n\nAxes and quadrant labels from a template can be overridden with explicit `x-axis:` / `y-axis:` / `quadrant` directives.\n\n---\n\n## 3. Axes\n\nAxis lines declare the semantic poles of each dimension.\n\n```\nx-axis: Low Effort \u2192 High Effort\ny-axis: Low Value \u2192 High Value\n```\n\nThe arrow separates the low label (left / bottom) from the high label (right / top). All of these separators are equivalent:\n\n| Separator | Example |\n|---|---|\n| `\u2192` (Unicode) | `x-axis: Rare \u2192 Certain` |\n| `->` (ASCII) | `x-axis: Rare -> Certain` |\n| `\u2191` | `y-axis: Cheap \u2191 Expensive` |\n| `\u2190` / `<-` / `<` | Reversed axis \u2014 high label is on the left |\n\nA **reversed axis** is for conventions where the "high" value sits at the left or bottom:\n\n```\nx-axis: High Market Share \u2190 Low Market Share\n```\n\n```\nmatrix "Product Portfolio"\nx-axis: High Market Share \u2190 Low Market Share\ny-axis: Low Growth \u2192 High Growth\n\nquadrant Q1 "Question Marks"\nquadrant Q2 "Stars"\nquadrant Q3 "Cash Cows"\nquadrant Q4 "Dogs"\n\n"Analytics Suite" at (0.25, 0.35) size: 5\n"ChatBot Pro" at (0.2, 0.8) size: 4 highlight: true\n"Legacy CRM" at (0.75, 0.25) size: 6\n"Mobile App" at (0.65, 0.75) size: 3\n```\n\n---\n\n## 4. Points\n\nEach point is a bubble positioned by a normalized (x, y) coordinate pair.\n\n```\n"Label" at (x, y)\n"Label" at (x, y) size: 4 category: design color: #7B1FA2 highlight: true note: "clarify spec"\n```\n\n| Property | Values | Meaning |\n|---|---|---|\n| `size:` | positive number | Bubble area weight (default: 3) |\n| `category:` | bareword | Color group; drives the legend |\n| `color:` | hex string | Override bubble color for this point |\n| `shape:` | `circle` \\| `square` \\| `triangle` \\| `diamond` | Bubble shape (default: `circle`) |\n| `highlight:` | `true` | Draws an emphasis ring around the bubble |\n| `note:` | quoted string | Tooltip annotation |\n| `label:` | quoted string | Replaces the display label (different from the ID) |\n\nCoordinates outside `[0, 1]` are clamped to the chart boundary and flagged with a badge \u2014 the original value is stored for tooltip display.\n\n```\nmatrix "Risk Register"\nx-axis: Low Impact \u2192 High Impact\ny-axis: Rare \u2192 Certain\n\n"Vendor delay" at (0.45, 0.7) size: 4 category: schedule highlight: true\n"Security breach" at (0.9, 0.3) size: 5 category: security shape: diamond\n"Budget overrun" at (0.5, 0.65) size: 3 category: finance\n"Key hire falls through" at (0.6, 0.55) size: 3 category: people\n"Scope creep" at (0.4, 0.8) size: 4 category: schedule\n```\n\n---\n\n## 5. Quadrant labels\n\nLabel each quadrant with a name and an optional subtitle.\n\n```\nquadrant Q1 "Do First"\nquadrant Q2 "Schedule"\nquadrant Q3 "Delete"\nquadrant Q4 "Delegate"\n\n# With an optional subtitle:\nquadrant Q1 "Do First" description: "High urgency, high importance"\n```\n\nQuadrant numbering follows the standard mathematical convention: **Q1 = top-right, Q2 = top-left, Q3 = bottom-left, Q4 = bottom-right**. The `Q` prefix is optional \u2014 `quadrant 1 "Label"` is equally valid.\n\n---\n\n## 6. Heatmap mode\n\nHeatmap mode fills N\xD7M cells with color intensity instead of plotting bubble positions.\n\n```\nmatrix heatmap 4x3 "Skill Matrix"\nrows: [Strategy, Execution, Communication, Technical]\ncols: [Junior, Mid, Senior]\n\ncell (0,0) level: weak\ncell (1,0) level: medium\ncell (2,0) level: strong\ncell (0,1) value: 7\ncell (1,2) label: "Top 10%"\n```\n\n- `matrix heatmap COLxROW` \u2014 header sets the grid dimensions.\n- `rows:` and `cols:` \u2014 comma-separated or bracket-list of axis labels.\n- `cell (col, row)` \u2014 zero-indexed, column first, row second (row 0 = bottom).\n- `level:` \u2014 `strong` (3), `medium` (2), or `weak` (1) \u2014 shorthand for heat intensity.\n- `value:` \u2014 explicit numeric value (overrides `level:`).\n- `label:` \u2014 quoted text placed inside the cell.\n\n```\nmatrix heatmap 4x4 "Competency Heat Map"\nrows: [Leadership, Execution, Communication, Technical]\ncols: [Junior, Mid, Senior, Staff]\n\ncell (0,0) level: weak\ncell (1,0) level: medium\ncell (2,0) level: strong\ncell (3,0) level: strong\ncell (0,1) level: medium\ncell (1,1) level: medium\ncell (2,1) level: strong\ncell (3,1) level: strong\ncell (0,2) level: weak\ncell (1,2) level: medium\ncell (2,2) level: medium\ncell (3,2) level: strong\ncell (0,3) level: weak\ncell (1,3) level: weak\ncell (2,3) level: medium\ncell (3,3) level: strong\n```\n\n---\n\n## 7. Correlation mode\n\nCorrelation mode renders an N\xD7M dot matrix where intensity represents the relationship strength between row and column variables.\n\n```\nmatrix correlation 4x4 "Product Metrics"\nrows: [DAU, Retention, Revenue, NPS]\ncols: [DAU, Retention, Revenue, NPS]\n\ncell (0,0) value: 1\ncell (1,0) value: 0.82\ncell (2,0) value: 0.54\ncell (3,0) value: 0.71\n```\n\nThe same `cell` syntax applies. `level: strong | medium | weak` is also accepted in correlation mode.\n\n---\n\n## 8. SIPOC mode\n\nA **SIPOC** is the one-page scoping table that opens the *Define* phase of a Six Sigma DMAIC project. It names, in five fixed columns left to right, everyone and everything the process touches: **S**uppliers \xB7 **I**nputs \xB7 **P**rocess \xB7 **O**utputs \xB7 **C**ustomers. Before a team measures or improves anything, SIPOC pins down the boundary \u2014 "where does this process start, where does it end, and who hands work in and out of it."\n\n```\nmatrix sipoc "Order fulfilment"\nsuppliers: "Vendor", "Warehouse"\ninputs: "PO", "Stock levels"\nprocess: "Receive order", "Pick", "Pack", "Ship"\noutputs: "Shipped package", "Invoice"\ncustomers: "End customer", "Finance"\n```\n\n- Start with `matrix sipoc`, optionally followed by a quoted title.\n- Each of the five columns is its own directive: `suppliers:`, `inputs:`, `process:`, `outputs:`, `customers:`.\n- After the colon, list the entries as **comma-separated quoted strings**. A column may have any number of entries; the rows simply stack top-down inside that column.\n- The `process:` column is the high-level step sequence (typically 4\u20137 steps) \u2014 keep it to the major stages, not a detailed flowchart.\n\nThe five columns always render in the canonical S-I-P-O-C order regardless of the order you declare them, so the diagram reads correctly even if an LLM emits the blocks out of sequence.\n\n```\nmatrix sipoc "Order fulfilment"\nsuppliers: "Vendor", "Warehouse"\ninputs: "PO", "Stock levels"\nprocess: "Receive order", "Pick", "Pack", "Ship"\noutputs: "Shipped package", "Invoice"\ncustomers: "End customer", "Finance"\n```\n\n---\n\n## 9. QFD mode (House of Quality)\n\n**Quality Function Deployment (QFD)** \u2014 the *House of Quality*, introduced by Yoji Akao \u2014 translates what customers want into the engineering characteristics that deliver it. Rows are the **WHATs** (customer requirements, each with an importance weight); columns are the **HOWs** (the measurable engineering characteristics the team controls). The body of the grid records how strongly each HOW serves each WHAT.\n\nThe differentiator: the engine **computes** the bottom row for you. Each HOW\'s *technical importance* is the sum down its column of `weight \xD7 relationship strength` \u2014 a ranked answer to "which engineering characteristic moves the most customer value, and is therefore worth the most effort." And the roof of the house \u2014 a half-matrix of diamond cells above the columns \u2014 records whether two HOWs help or fight each other.\n\n```\nmatrix qfd "Coffee maker"\nwhat: "Quiet operation" weight: 5\nwhat: "Brews fast" weight: 3\nwhat: "Energy efficient" weight: 4\nhow: "Fan RPM" dir: down\nhow: "Heater watts" dir: up\nhow: "Insulation" dir: up\nrel (0,0): 9\nrel (0,2): 3\nrel (1,1): 9\nrel (2,1): 3\nrel (2,2): 9\nroof (0,1): --\nroof (1,2): +\n```\n\n### WHATs and HOWs\n\n| Directive | Form | Meaning |\n|---|---|---|\n| `what:` | `what: "Label" weight: N` | A customer requirement (one row). `weight:` is its importance, conventionally 1\u20135. Declaration order is the row order, indexed from 0. |\n| `how:` | `how: "Label" dir: up\\|down` | An engineering characteristic (one column). Declaration order is the column order, indexed from 0. `dir:` is the optimization target \u2014 `up` = more is better, `down` = less is better. |\n\n### Relationship cells\n\n`rel (i, j): strength` records how strongly column-`j` HOW serves row-`i` WHAT. The index is **(row, column)**, both zero-based.\n\n| Strength | Meaning |\n|---|---|\n| `9` | Strong relationship |\n| `3` | Medium relationship |\n| `1` | Weak relationship |\n| *(omitted)* | No relationship \u2014 leave the cell out |\n\nThis 9 / 3 / 1 scale is the QFD convention: it is deliberately non-linear so that one strong link outweighs several weak ones when the importance row is summed.\n\n### Computed technical-importance row\n\nThe engine sums each column to produce the technical-importance row at the foot of the house:\n\n```\nimportance(j) = \u03A3 over rows i ( weight(i) \xD7 strength(i, j) )\n```\n\nFor the coffee-maker example above the row computes to **45 / 39 / 51** \u2014 Insulation (51) is the highest-leverage characteristic, Heater watts (39) the lowest. This ranking is the deliverable: it tells the team where to spend engineering effort.\n\nAdd `normalize: true` (its own line, anywhere in the block) to show each column as a **percentage of the total** instead of a raw sum \u2014 for this example, **33% / 29% / 38%**. Percentages make the relative priorities easier to read across very different weight scales.\n\n### The roof \u2014 HOW \xD7 HOW correlations\n\nThe **roof** is the triangular half-matrix sitting above the columns. `roof (i, j): glyph` records whether HOW `i` and HOW `j` reinforce or conflict with each other \u2014 the synergies and trade-offs a team must reconcile.\n\n| Glyph | Correlation |\n|---|---|\n| `++` | Strong positive \u2014 improving one strongly helps the other |\n| `+` | Positive |\n| `-` | Negative |\n| `--` | Strong negative \u2014 improving one hurts the other (a trade-off) |\n| *(omitted)* | No correlation \u2014 leave the cell out |\n\nEach roof entry renders as a diamond cell in the standard QFD pitched-roof grid. In the example, `roof (0,1): --` flags that pushing Fan RPM down while pushing Heater watts up is a trade-off, and `roof (1,2): +` flags that Heater watts and Insulation reinforce each other.\n\n```\nmatrix qfd "Coffee maker"\nwhat: "Quiet operation" weight: 5\nwhat: "Brews fast" weight: 3\nwhat: "Energy efficient" weight: 4\nhow: "Fan RPM" dir: down\nhow: "Heater watts" dir: up\nhow: "Insulation" dir: up\nrel (0,0): 9\nrel (0,2): 3\nrel (1,1): 9\nrel (2,1): 3\nrel (2,2): 9\nroof (0,1): --\nroof (1,2): +\n```\n\n---\n\n## 10. Config options\n\nA `config:` block tunes visual rendering. Each option goes on its own indented line below the `config:` header.\n\n```\nconfig:\n quadrantBg: true\n gridLines: true\n axisArrows: true\n bubbleScale: area\n legendPosition: bottom-right\n```\n\n| Key | Values | Default | Effect |\n|---|---|---|---|\n| `quadrantBg` | `true` \\| `false` | `true` | Colored quadrant background fills |\n| `gridLines` | `true` \\| `false` | `true` | Grid lines overlay |\n| `axisArrows` | `true` \\| `false` | `true` | Arrows at axis ends |\n| `bubbleScale` | `area` \\| `radius` | `area` | Whether `size:` scales bubble area or radius |\n| `quadrantAnnotations` | `true` \\| `false` | `true` | Show quadrant label text in corners |\n| `legendPosition` | `bottom-right` \\| `right` \\| `bottom-center` \\| `none` | `bottom-right` | Category legend placement |\n| `labelCollision` | `auto` \\| `offset-only` \\| `leader-only` \\| `off` | `auto` | Overlap avoidance strategy for point labels |\n| `offChartPolicy` | `clamp-badge` \\| `drop` | `clamp-badge` | What to do with points outside [0,1] |\n\nTwo shorthand directives also work at the top level (not inside the `config:` block):\n\n```\naxis: off # off | on | auto \u2014 show or hide the axis lines\nmargins: true # true | false \u2014 show Score + Rank margins (correlation mode)\n```\n\n---\n\n## 11. Labels & comments\n\n- **Title:** `matrix "My Title"` or `title: My Title` as a standalone line.\n- **Point label:** the quoted string before `at (\u2026)`.\n- **Axis labels:** `x-axis:` and `y-axis:` directives.\n- **Quadrant labels:** `quadrant Q1 "Name"` directive.\n- **Comments:** `#` anywhere on a line, outside quoted strings.\n\n```\nmatrix "Prioritization"\n# This is a comment\nx-axis: Low Cost \u2192 High Cost # inline comment after a directive\n"Fix bug" at (0.1, 0.9) size: 3 # comment after a point\n```\n\n---\n\n## 12. Table mode (`style: table`)\n\nThe default matrix rendering is a **scatter / bubble chart** \u2014 points float at (x, y) coordinates. For frameworks where the output is a list of items grouped by quadrant (Eisenhower, Johari, Impact-Effort, 9-box), use `style: table` to switch to a **text-in-cell layout** instead.\n\n```\nmatrix eisenhower "This Week"\nstyle: table\nQ2: "Ship hotfix"\nQ2: "Customer demo prep"\nQ1: "Write Q3 OKRs"\nQ1: "Refactor auth layer"\nQ4: "LinkedIn updates"\nQ3: "Reorganize Slack channels"\n```\n\n`style: table` applies these changes automatically:\n\n| Effect | Detail |\n|---|---|\n| Axes and arrows hidden | No axis lines, labels, or arrowheads |\n| Grid lines hidden | Only the outer border and cell dividers remain |\n| Quadrant titles move inside cells | Each title becomes a cell header instead of a corner overlay |\n| Items stack as a bullet list | Multiple entries for the same quadrant stack top-down |\n\n### `Q1` \u2026 `Q4` shorthand (2\xD72 only)\n\nFor 2\xD72 templates, use `Qn: "item"` instead of the longer `cell (col, row) label: "item"` form. Mapping:\n\n| Shorthand | Cell | Eisenhower | Johari |\n|---|---|---|---|\n| `Q1:` | top-right | Schedule | Blind |\n| `Q2:` | top-left | Do First | Open / Arena |\n| `Q3:` | bottom-left | Delete | Hidden / Fa\xE7ade |\n| `Q4:` | bottom-right | Delegate | Unknown |\n\nRepeat a shorthand key to add multiple items to the same cell:\n\n```\nQ2: "Ship hotfix"\nQ2: "Customer demo prep"\n```\n\nFor 3\xD73 grids (9-box), use `cell (col, row) label: "\u2026"` directly \u2014 the `Q` shorthand is 2\xD72 only.\n\n### When to use table vs scatter\n\n| Use `style: table` for | Use scatter (default) for |\n|---|---|\n| Eisenhower with task lists | Eisenhower with `size:` effort weights |\n| Johari window coaching | Impact-Effort with bubble = revenue |\n| Backlog grouping (no numeric third dimension) | RICE / BCG portfolio (third dimension IS the bubble size) |\n| 9-box talent review | Risk heatmap (5\xD75 with numeric severity) |\n\n```\nmatrix eisenhower "This Week"\nstyle: table\nQ2: "Ship hotfix"\nQ2: "Customer demo prep"\nQ1: "Write Q3 OKRs"\nQ1: "Refactor auth layer"\nQ4: "LinkedIn updates"\nQ3: "Reorganize Slack channels"\n```\n\n---\n\n## 13. Reserved words & escaping\n\n**Reserved at line start:** `matrix` (header), `x-axis:`, `y-axis:`, `quadrant`, `config:`, `title:`, `rows:`, `cols:`, `grid:`, `axis:`, `margins:`, `cell`. In **SIPOC** mode: `suppliers:`, `inputs:`, `process:`, `outputs:`, `customers:`. In **QFD** mode: `what:`, `how:`, `rel`, `roof`, `normalize:`.\n\n**Point lines must start with a quote character** (`"` or `\'`). A line that does not start with a quote is not treated as a point.\n\n**Strings with spaces** in axis labels do not need quoting \u2014 the text after the colon (and after the arrow) is taken verbatim. In `note:` and `label:` point properties, use double quotes.\n\n---\n\n## 14. Common mistakes\n\n| You wrote | Parser says | Fix |\n|---|---|---|\n| `"Fix bug" at (1, 2)` | Point parsed; x=1 clamped, y=1 clamped; off-chart badge shown | Keep coordinates in [0.0, 1.0] or accept the clamp-badge |\n| `quadrant 1 "Quick Wins"` (no Q prefix) | Accepted \u2014 `Q` prefix is optional | Both `quadrant 1` and `quadrant Q1` work |\n| `config: gridLines: false` (on same line) | Only `config:` keyword recognized; `gridLines: false` silently ignored | Put options on their own indented lines below `config:` |\n| `x-axis: "Low" \u2192 "High"` (quoted labels) | Arrow not found inside quotes \u2014 treated as plain text | Remove quotes: `x-axis: Low \u2192 High` |\n| `matrix heatmap` without dimensions | Defaults to 2\xD72; rows/cols directives set actual size | Specify dimensions on the header: `matrix heatmap 4x4` |\n| `cell (0, 0) level: Strong` (capital S) | `level` match is case-insensitive \u2014 accepted | Both `strong` and `Strong` work |\n| `shape: oval` | Unknown shape value \u2014 silently ignored | Use `circle`, `square`, `triangle`, or `diamond` |\n| `"Fix bug" at (0.1, 0.9)` on an Eisenhower with a task list | Valid scatter point \u2014 but you probably wanted a list in a cell | Add `style: table` and use `Q2: "Fix bug"` instead |\n| `Q1: "item"` on a 3\xD73 template | `Q` shorthand is parsed as a point line \u2014 silently dropped | Use `cell (col, row) label: "item"` for 3\xD73 grids |\n\n---\n\n## 15. Grammar (EBNF)\n\n```text\ndocument = header directive*\n\nheader = "matrix" ( template-name | mode-header | title )? NEWLINE\ntemplate-name = "eisenhower"|"impact-effort"|"rice"|"bcg"|"ansoff"|"johari"|"9-box"|"risk-matrix"\nmode-header = ( "heatmap" | "correlation" ) ( number "x" number )? title?\n | ( "sipoc" | "qfd" ) title?\ntitle = quoted-string | bare-text\n\ndirective = x-axis | y-axis | quadrant-dir | config-block\n | point | cell | q-short | rows-dir | cols-dir | grid-dir\n | style-dir | title-dir | axis-dir | margins-dir\n | sipoc-col | qfd-what | qfd-how | qfd-rel | qfd-roof | normalize-dir\n | comment | blank\n\n# SIPOC mode\nsipoc-col = ( "suppliers:" | "inputs:" | "process:" | "outputs:" | "customers:" )\n WS quoted-string ( "," quoted-string )* NEWLINE\n\n# QFD / House of Quality mode\nqfd-what = "what:" WS quoted-string WS "weight:" number NEWLINE\nqfd-how = "how:" WS quoted-string ( WS "dir:" ( "up" | "down" ) )? NEWLINE\nqfd-rel = "rel" WS "(" number "," number ")" ":" WS ( "9" | "3" | "1" ) NEWLINE # (row, col)\nqfd-roof = "roof" WS "(" number "," number ")" ":" WS ( "++" | "+" | "-" | "--" ) NEWLINE # (how, how)\nnormalize-dir = "normalize:" WS "true" NEWLINE\n\nx-axis = "x-axis:" WS axis-spec NEWLINE\ny-axis = "y-axis:" WS axis-spec NEWLINE\naxis-spec = text arrow text | text # plain text \u2192 high label only\narrow = "\u2192" | "->" | "\u2191" | "\u2190" | "<-" | "<" | "\u2193"\n\nquadrant-dir = "quadrant" WS "Q"? digit WS quoted-string ( WS "description:" quoted-string )? NEWLINE\n\nconfig-block = "config:" NEWLINE ( INDENT key ":" WS value NEWLINE )*\n\npoint = quoted-string WS "at" WS "(" number "," number ")" ( WS point-prop )* NEWLINE\npoint-prop = "size:" number\n | "category:" bareword\n | "color:" hex-color\n | "shape:" ( "circle"|"square"|"triangle"|"diamond" )\n | "highlight:" "true"\n | "note:" quoted-string\n | "label:" quoted-string\n\ncell = "cell" WS "(" digit "," digit ")" ( WS cell-prop )* NEWLINE\ncell-prop = "value:" number\n | "label:" quoted-string\n | "level:" ( "strong" | "medium" | "weak" )\n\nstyle-dir = "style:" WS "table" NEWLINE\nq-short = "Q" ( "1" | "2" | "3" | "4" ) ":" WS quoted-string NEWLINE # 2\xD72 only\n\nrows-dir = "rows:" WS label-list NEWLINE\ncols-dir = "cols:" WS label-list NEWLINE\ngrid-dir = "grid:" WS number "x" number NEWLINE\naxis-dir = "axis:" WS ( "off" | "on" | "auto" ) NEWLINE\nmargins-dir = "margins:" WS ( "true" | "false" | "on" | "1" ) NEWLINE\n\nlabel-list = "[" text ("," text)* "]" | text ("," text)*\nquoted-string = \'"\' any-char-but-quote* \'"\' | "\'" any-char-but-quote* "\'"\ncomment = "#" any NEWLINE\n```\n\nAuthoritative source: `src/diagrams/matrix/parser.ts`. If this diverges from the parser, the parser wins \u2014 please open an issue.\n\n---'
3475
+ "content": '## 1. Your first matrix\n\nThe smallest useful matrix: a custom 2\xD72 with two labeled axes and three points.\n\n```\nmatrix "Feature Prioritization"\nx-axis: Low Effort \u2192 High Effort\ny-axis: Low Value \u2192 High Value\n\n"Add search" at (0.3, 0.8)\n"Rebuild pipeline" at (0.85, 0.7)\n"Update footer" at (0.2, 0.2)\n```\n\nFour rules cover 80% of usage:\n\n1. Start with the keyword `matrix`, optionally followed by a template name or a quoted title.\n2. Set the axes with `x-axis:` and `y-axis:` \u2014 or use a built-in template and skip this step entirely.\n3. Each point is `"Label" at (x, y)` where `x` and `y` are decimal fractions from 0.0 (low/left/bottom) to 1.0 (high/right/top).\n4. Add optional properties \u2014 `size:`, `category:`, `color:`, `shape:`, `highlight:` \u2014 after the coordinates.\n\n> Comments must start with `#` anywhere on a line (outside quoted strings).\n\n---\n\n## 2. Built-in templates\n\nA template pre-configures axes, quadrant labels, and grid size. Just use the template name as the second token on the header line.\n\n| Template | Grid | Use case |\n|---|---|---|\n| `eisenhower` | 2\xD72 | Urgency / Importance task prioritization |\n| `impact-effort` | 2\xD72 | Feature prioritization by impact vs. effort |\n| `rice` | 2\xD72 | RICE scoring \u2014 Reach \xD7 Impact vs. Effort |\n| `bcg` | 2\xD72 | Portfolio \u2014 Market Share vs. Growth rate |\n| `ansoff` | 2\xD72 | Product/market growth strategy |\n| `johari` | 2\xD72 | Self-awareness \u2014 known-to-self vs. known-to-others |\n| `9-box` | 3\xD73 | HR talent review \u2014 Performance vs. Potential |\n| `risk-matrix` | 5\xD75 | Risk assessment \u2014 Likelihood vs. Severity (heatmap) |\n\n```\nmatrix eisenhower "This Week"\n"Ship hotfix" at (0.1, 0.9) size: 5 highlight: true\n"Team 1:1s" at (0.1, 0.7) size: 3\n"Write Q3 OKRs" at (0.8, 0.85) size: 4\n"Inbox zero" at (0.1, 0.3) size: 2\n"Refactor auth" at (0.75, 0.4) size: 3\n```\n\nAxes and quadrant labels from a template can be overridden with explicit `x-axis:` / `y-axis:` / `quadrant` directives.\n\n---\n\n## 3. Axes\n\nAxis lines declare the semantic poles of each dimension.\n\n```\nx-axis: Low Effort \u2192 High Effort\ny-axis: Low Value \u2192 High Value\n```\n\nThe arrow separates the low label (left / bottom) from the high label (right / top). All of these separators are equivalent:\n\n| Separator | Example |\n|---|---|\n| `\u2192` (Unicode) | `x-axis: Rare \u2192 Certain` |\n| `->` (ASCII) | `x-axis: Rare -> Certain` |\n| `\u2191` | `y-axis: Cheap \u2191 Expensive` |\n| `\u2190` / `<-` / `<` | Reversed axis \u2014 high label is on the left |\n\nA **reversed axis** is for conventions where the "high" value sits at the left or bottom:\n\n```\nx-axis: High Market Share \u2190 Low Market Share\n```\n\n```\nmatrix "Product Portfolio"\nx-axis: High Market Share \u2190 Low Market Share\ny-axis: Low Growth \u2192 High Growth\n\nquadrant Q1 "Question Marks"\nquadrant Q2 "Stars"\nquadrant Q3 "Cash Cows"\nquadrant Q4 "Dogs"\n\n"Analytics Suite" at (0.25, 0.35) size: 5\n"ChatBot Pro" at (0.2, 0.8) size: 4 highlight: true\n"Legacy CRM" at (0.75, 0.25) size: 6\n"Mobile App" at (0.65, 0.75) size: 3\n```\n\n---\n\n## 4. Points\n\nEach point is a bubble positioned by a normalized (x, y) coordinate pair.\n\n```\n"Label" at (x, y)\n"Label" at (x, y) size: 4 category: design color: #7B1FA2 highlight: true note: "clarify spec"\n```\n\n| Property | Values | Meaning |\n|---|---|---|\n| `size:` | positive number | Bubble area weight (default: 3) |\n| `category:` | bareword | Color group; drives the legend |\n| `color:` | hex string | Override bubble color for this point |\n| `shape:` | `circle` \\| `square` \\| `triangle` \\| `diamond` | Bubble shape (default: `circle`) |\n| `highlight:` | `true` | Draws an emphasis ring around the bubble |\n| `note:` | quoted string | Tooltip annotation |\n| `label:` | quoted string | Replaces the display label (different from the ID) |\n\nCoordinates outside `[0, 1]` are clamped to the chart boundary and flagged with a badge \u2014 the original value is stored for tooltip display.\n\n```\nmatrix "Risk Register"\nx-axis: Low Impact \u2192 High Impact\ny-axis: Rare \u2192 Certain\n\n"Vendor delay" at (0.45, 0.7) size: 4 category: schedule highlight: true\n"Security breach" at (0.9, 0.3) size: 5 category: security shape: diamond\n"Budget overrun" at (0.5, 0.65) size: 3 category: finance\n"Key hire falls through" at (0.6, 0.55) size: 3 category: people\n"Scope creep" at (0.4, 0.8) size: 4 category: schedule\n```\n\n---\n\n## 5. Quadrant labels\n\nLabel each quadrant with a name and an optional subtitle.\n\n```\nquadrant Q1 "Do First"\nquadrant Q2 "Schedule"\nquadrant Q3 "Delete"\nquadrant Q4 "Delegate"\n\n# With an optional subtitle:\nquadrant Q1 "Do First" description: "High urgency, high importance"\n```\n\nQuadrant numbering follows the standard mathematical convention: **Q1 = top-right, Q2 = top-left, Q3 = bottom-left, Q4 = bottom-right**. The `Q` prefix is optional \u2014 `quadrant 1 "Label"` is equally valid.\n\n---\n\n## 6. Heatmap mode\n\nHeatmap mode fills N\xD7M cells with color intensity instead of plotting bubble positions.\n\n```\nmatrix heatmap 4x3 "Skill Matrix"\nrows: [Strategy, Execution, Communication, Technical]\ncols: [Junior, Mid, Senior]\n\ncell (0,0) level: weak\ncell (1,0) level: medium\ncell (2,0) level: strong\ncell (0,1) value: 7\ncell (1,2) label: "Top 10%"\n```\n\n- `matrix heatmap COLxROW` \u2014 header sets the grid dimensions.\n- `rows:` and `cols:` \u2014 comma-separated or bracket-list of axis labels.\n- `cell (col, row)` \u2014 zero-indexed, column first, row second (row 0 = bottom).\n- `level:` \u2014 `strong` (3), `medium` (2), or `weak` (1) \u2014 shorthand for heat intensity.\n- `value:` \u2014 explicit numeric value (overrides `level:`).\n- `label:` \u2014 quoted text placed inside the cell.\n\n```\nmatrix heatmap 4x4 "Competency Heat Map"\nrows: [Leadership, Execution, Communication, Technical]\ncols: [Junior, Mid, Senior, Staff]\n\ncell (0,0) level: weak\ncell (1,0) level: medium\ncell (2,0) level: strong\ncell (3,0) level: strong\ncell (0,1) level: medium\ncell (1,1) level: medium\ncell (2,1) level: strong\ncell (3,1) level: strong\ncell (0,2) level: weak\ncell (1,2) level: medium\ncell (2,2) level: medium\ncell (3,2) level: strong\ncell (0,3) level: weak\ncell (1,3) level: weak\ncell (2,3) level: medium\ncell (3,3) level: strong\n```\n\n---\n\n## 7. Correlation mode\n\nCorrelation mode renders an N\xD7M dot matrix where intensity represents the relationship strength between row and column variables.\n\n```\nmatrix correlation 4x4 "Product Metrics"\nrows: [DAU, Retention, Revenue, NPS]\ncols: [DAU, Retention, Revenue, NPS]\n\ncell (0,0) value: 1\ncell (1,0) value: 0.82\ncell (2,0) value: 0.54\ncell (3,0) value: 0.71\n```\n\nThe same `cell` syntax applies. `level: strong | medium | weak` is also accepted in correlation mode.\n\n---\n\n## 8. SIPOC mode\n\nA **SIPOC** is the one-page scoping table that opens the *Define* phase of a Six Sigma DMAIC project. It names, in five fixed columns left to right, everyone and everything the process touches: **S**uppliers \xB7 **I**nputs \xB7 **P**rocess \xB7 **O**utputs \xB7 **C**ustomers. Before a team measures or improves anything, SIPOC pins down the boundary \u2014 "where does this process start, where does it end, and who hands work in and out of it."\n\n```\nmatrix sipoc "Order fulfilment"\nsuppliers: "Vendor", "Warehouse"\ninputs: "PO", "Stock levels"\nprocess: "Receive order", "Pick", "Pack", "Ship"\noutputs: "Shipped package", "Invoice"\ncustomers: "End customer", "Finance"\n```\n\n- Start with `matrix sipoc`, optionally followed by a quoted title.\n- Each of the five columns is its own directive: `suppliers:`, `inputs:`, `process:`, `outputs:`, `customers:`.\n- After the colon, list the entries as **comma-separated quoted strings**. A column may have any number of entries; the rows simply stack top-down inside that column.\n- The `process:` column is the high-level step sequence (typically 4\u20137 steps) \u2014 keep it to the major stages, not a detailed flowchart.\n\nThe five columns always render in the canonical S-I-P-O-C order regardless of the order you declare them, so the diagram reads correctly even if an LLM emits the blocks out of sequence.\n\n```\nmatrix sipoc "Order fulfilment"\nsuppliers: "Vendor", "Warehouse"\ninputs: "PO", "Stock levels"\nprocess: "Receive order", "Pick", "Pack", "Ship"\noutputs: "Shipped package", "Invoice"\ncustomers: "End customer", "Finance"\n```\n\n---\n\n## 9. QFD mode (House of Quality)\n\n**Quality Function Deployment (QFD)** \u2014 the *House of Quality*, introduced by Yoji Akao \u2014 translates what customers want into the engineering characteristics that deliver it. Rows are the **WHATs** (customer requirements, each with an importance weight); columns are the **HOWs** (the measurable engineering characteristics the team controls). The body of the grid records how strongly each HOW serves each WHAT.\n\nThe differentiator: the engine **computes** the bottom row for you. Each HOW\'s *technical importance* is the sum down its column of `weight \xD7 relationship strength` \u2014 a ranked answer to "which engineering characteristic moves the most customer value, and is therefore worth the most effort." And the roof of the house \u2014 a half-matrix of diamond cells above the columns \u2014 records whether two HOWs help or fight each other.\n\n```\nmatrix qfd "Coffee maker"\nwhat: "Quiet operation" weight: 5\nwhat: "Brews fast" weight: 3\nwhat: "Energy efficient" weight: 4\nhow: "Fan RPM" dir: down\nhow: "Heater watts" dir: up\nhow: "Insulation" dir: up\nrel (0,0): 9\nrel (0,2): 3\nrel (1,1): 9\nrel (2,1): 3\nrel (2,2): 9\nroof (0,1): --\nroof (1,2): +\n```\n\n### WHATs and HOWs\n\n| Directive | Form | Meaning |\n|---|---|---|\n| `what:` | `what: "Label" weight: N` | A customer requirement (one row). `weight:` is its importance, conventionally 1\u20135. Declaration order is the row order, indexed from 0. |\n| `how:` | `how: "Label" dir: up\\|down` | An engineering characteristic (one column). Declaration order is the column order, indexed from 0. `dir:` is the optimization target \u2014 `up` = more is better, `down` = less is better. |\n\n### Relationship cells\n\n`rel (i, j): strength` records how strongly column-`j` HOW serves row-`i` WHAT. The index is **(row, column)**, both zero-based.\n\n| Strength | Meaning |\n|---|---|\n| `9` | Strong relationship |\n| `3` | Medium relationship |\n| `1` | Weak relationship |\n| *(omitted)* | No relationship \u2014 leave the cell out |\n\nThis 9 / 3 / 1 scale is the QFD convention: it is deliberately non-linear so that one strong link outweighs several weak ones when the importance row is summed.\n\n### Computed technical-importance row\n\nThe engine sums each column to produce the technical-importance row at the foot of the house:\n\n```\nimportance(j) = \u03A3 over rows i ( weight(i) \xD7 strength(i, j) )\n```\n\nFor the coffee-maker example above the row computes to **45 / 39 / 51** \u2014 Insulation (51) is the highest-leverage characteristic, Heater watts (39) the lowest. This ranking is the deliverable: it tells the team where to spend engineering effort.\n\nAdd `normalize: true` (its own line, anywhere in the block) to show each column as a **percentage of the total** instead of a raw sum \u2014 for this example, **33% / 29% / 38%**. Percentages make the relative priorities easier to read across very different weight scales.\n\n### The roof \u2014 HOW \xD7 HOW correlations\n\nThe **roof** is the triangular half-matrix sitting above the columns. `roof (i, j): glyph` records whether HOW `i` and HOW `j` reinforce or conflict with each other \u2014 the synergies and trade-offs a team must reconcile.\n\n| Glyph | Correlation |\n|---|---|\n| `++` | Strong positive \u2014 improving one strongly helps the other |\n| `+` | Positive |\n| `-` | Negative |\n| `--` | Strong negative \u2014 improving one hurts the other (a trade-off) |\n| *(omitted)* | No correlation \u2014 leave the cell out |\n\nEach roof entry renders as a diamond cell in the standard QFD pitched-roof grid. In the example, `roof (0,1): --` flags that pushing Fan RPM down while pushing Heater watts up is a trade-off, and `roof (1,2): +` flags that Heater watts and Insulation reinforce each other.\n\n```\nmatrix qfd "Coffee maker"\nwhat: "Quiet operation" weight: 5\nwhat: "Brews fast" weight: 3\nwhat: "Energy efficient" weight: 4\nhow: "Fan RPM" dir: down\nhow: "Heater watts" dir: up\nhow: "Insulation" dir: up\nrel (0,0): 9\nrel (0,2): 3\nrel (1,1): 9\nrel (2,1): 3\nrel (2,2): 9\nroof (0,1): --\nroof (1,2): +\n```\n\n---\n\n## 10. Punnett mode (Mendelian genetics)\n\nA **Punnett square** predicts the offspring of a genetic cross. You write only the two parental genotypes; the engine does the Mendelian bookkeeping \u2014 it enumerates each parent\'s **gametes** (one allele per gene locus), fills the grid with every gamete combination, and **computes the genotype and phenotype ratios**. The user never fills the grid.\n\n```\nmatrix punnett "Eye color (Bb \xD7 Bb)"\ncross: Bb x Bb\ntrait B: "Brown eyes" / "Blue eyes"\n```\n\n### The cross\n\n| Directive | Form | Meaning |\n|---|---|---|\n| `cross:` | `cross: Bb x Bb` | The two parental genotypes, separated by `x`, `\xD7`, or `*`. `parents:` is an accepted alias. |\n| `trait:` | `trait B: "Dominant" / "Recessive"` | *(optional)* Names the two phenotypes for gene `B`, so the legend reads in plain English instead of `B_` / `bb`. |\n\n**Allele case sets dominance** \u2014 this is the standard genetics convention. An uppercase letter is the **dominant** allele, the matching lowercase letter is **recessive**. A genotype groups alleles by letter: `RrYy` is two loci, `R/r` (round/wrinkled) and `Y/y` (yellow/green). One gene is a **monohybrid** cross (2\xD72 grid), two genes a **dihybrid** (4\xD74), three a trihybrid (8\xD78).\n\n### Computed ratios (the differentiator)\n\nThe engine derives, from the genotypes alone:\n\n- the **gametes** of each parent \u2014 the column and row headers \u2014 by taking one allele per locus (so a heterozygote `Bb` yields `B` and `b`);\n- the **offspring grid** \u2014 every gamete pairing, written dominant-allele-first (`Bb`, never `bB`);\n- the **phenotype ratio** \u2014 boxes grouped by which phenotype they express, reduced to lowest terms. A monohybrid `Bb \xD7 Bb` gives the classic **3:1**; a dihybrid `RrYy \xD7 RrYy` gives the famous **9:3:3:1**;\n- the **genotype ratio** \u2014 e.g. `1:2:1` (1 BB, 2 Bb, 1 bb) for the monohybrid.\n\nEach box is tinted by its phenotype class, and the footer lists the phenotype ratio with a legend plus the genotype ratio.\n\n```\nmatrix punnett "Seed shape & colour (RrYy \xD7 RrYy)"\ncross: RrYy x RrYy\ntrait R: "Round" / "Wrinkled"\ntrait Y: "Yellow" / "Green"\n```\n\n---\n\n## 11. Config options\n\nA `config:` block tunes visual rendering. Each option goes on its own indented line below the `config:` header.\n\n```\nconfig:\n quadrantBg: true\n gridLines: true\n axisArrows: true\n bubbleScale: area\n legendPosition: bottom-right\n```\n\n| Key | Values | Default | Effect |\n|---|---|---|---|\n| `quadrantBg` | `true` \\| `false` | `true` | Colored quadrant background fills |\n| `gridLines` | `true` \\| `false` | `true` | Grid lines overlay |\n| `axisArrows` | `true` \\| `false` | `true` | Arrows at axis ends |\n| `bubbleScale` | `area` \\| `radius` | `area` | Whether `size:` scales bubble area or radius |\n| `quadrantAnnotations` | `true` \\| `false` | `true` | Show quadrant label text in corners |\n| `legendPosition` | `bottom-right` \\| `right` \\| `bottom-center` \\| `none` | `bottom-right` | Category legend placement |\n| `labelCollision` | `auto` \\| `offset-only` \\| `leader-only` \\| `off` | `auto` | Overlap avoidance strategy for point labels |\n| `offChartPolicy` | `clamp-badge` \\| `drop` | `clamp-badge` | What to do with points outside [0,1] |\n\nTwo shorthand directives also work at the top level (not inside the `config:` block):\n\n```\naxis: off # off | on | auto \u2014 show or hide the axis lines\nmargins: true # true | false \u2014 show Score + Rank margins (correlation mode)\n```\n\n---\n\n## 12. Labels & comments\n\n- **Title:** `matrix "My Title"` or `title: My Title` as a standalone line.\n- **Point label:** the quoted string before `at (\u2026)`.\n- **Axis labels:** `x-axis:` and `y-axis:` directives.\n- **Quadrant labels:** `quadrant Q1 "Name"` directive.\n- **Comments:** `#` anywhere on a line, outside quoted strings.\n\n```\nmatrix "Prioritization"\n# This is a comment\nx-axis: Low Cost \u2192 High Cost # inline comment after a directive\n"Fix bug" at (0.1, 0.9) size: 3 # comment after a point\n```\n\n---\n\n## 13. Table mode (`style: table`)\n\nThe default matrix rendering is a **scatter / bubble chart** \u2014 points float at (x, y) coordinates. For frameworks where the output is a list of items grouped by quadrant (Eisenhower, Johari, Impact-Effort, 9-box), use `style: table` to switch to a **text-in-cell layout** instead.\n\n```\nmatrix eisenhower "This Week"\nstyle: table\nQ2: "Ship hotfix"\nQ2: "Customer demo prep"\nQ1: "Write Q3 OKRs"\nQ1: "Refactor auth layer"\nQ4: "LinkedIn updates"\nQ3: "Reorganize Slack channels"\n```\n\n`style: table` applies these changes automatically:\n\n| Effect | Detail |\n|---|---|\n| Axes and arrows hidden | No axis lines, labels, or arrowheads |\n| Grid lines hidden | Only the outer border and cell dividers remain |\n| Quadrant titles move inside cells | Each title becomes a cell header instead of a corner overlay |\n| Items stack as a bullet list | Multiple entries for the same quadrant stack top-down |\n\n### `Q1` \u2026 `Q4` shorthand (2\xD72 only)\n\nFor 2\xD72 templates, use `Qn: "item"` instead of the longer `cell (col, row) label: "item"` form. Mapping:\n\n| Shorthand | Cell | Eisenhower | Johari |\n|---|---|---|---|\n| `Q1:` | top-right | Schedule | Blind |\n| `Q2:` | top-left | Do First | Open / Arena |\n| `Q3:` | bottom-left | Delete | Hidden / Fa\xE7ade |\n| `Q4:` | bottom-right | Delegate | Unknown |\n\nRepeat a shorthand key to add multiple items to the same cell:\n\n```\nQ2: "Ship hotfix"\nQ2: "Customer demo prep"\n```\n\nFor 3\xD73 grids (9-box), use `cell (col, row) label: "\u2026"` directly \u2014 the `Q` shorthand is 2\xD72 only.\n\n### When to use table vs scatter\n\n| Use `style: table` for | Use scatter (default) for |\n|---|---|\n| Eisenhower with task lists | Eisenhower with `size:` effort weights |\n| Johari window coaching | Impact-Effort with bubble = revenue |\n| Backlog grouping (no numeric third dimension) | RICE / BCG portfolio (third dimension IS the bubble size) |\n| 9-box talent review | Risk heatmap (5\xD75 with numeric severity) |\n\n```\nmatrix eisenhower "This Week"\nstyle: table\nQ2: "Ship hotfix"\nQ2: "Customer demo prep"\nQ1: "Write Q3 OKRs"\nQ1: "Refactor auth layer"\nQ4: "LinkedIn updates"\nQ3: "Reorganize Slack channels"\n```\n\n---\n\n## 14. Reserved words & escaping\n\n**Reserved at line start:** `matrix` (header), `x-axis:`, `y-axis:`, `quadrant`, `config:`, `title:`, `rows:`, `cols:`, `grid:`, `axis:`, `margins:`, `cell`. In **SIPOC** mode: `suppliers:`, `inputs:`, `process:`, `outputs:`, `customers:`. In **QFD** mode: `what:`, `how:`, `rel`, `roof`, `normalize:`.\n\n**Point lines must start with a quote character** (`"` or `\'`). A line that does not start with a quote is not treated as a point.\n\n**Strings with spaces** in axis labels do not need quoting \u2014 the text after the colon (and after the arrow) is taken verbatim. In `note:` and `label:` point properties, use double quotes.\n\n---\n\n## 15. Common mistakes\n\n| You wrote | Parser says | Fix |\n|---|---|---|\n| `"Fix bug" at (1, 2)` | Point parsed; x=1 clamped, y=1 clamped; off-chart badge shown | Keep coordinates in [0.0, 1.0] or accept the clamp-badge |\n| `quadrant 1 "Quick Wins"` (no Q prefix) | Accepted \u2014 `Q` prefix is optional | Both `quadrant 1` and `quadrant Q1` work |\n| `config: gridLines: false` (on same line) | Only `config:` keyword recognized; `gridLines: false` silently ignored | Put options on their own indented lines below `config:` |\n| `x-axis: "Low" \u2192 "High"` (quoted labels) | Arrow not found inside quotes \u2014 treated as plain text | Remove quotes: `x-axis: Low \u2192 High` |\n| `matrix heatmap` without dimensions | Defaults to 2\xD72; rows/cols directives set actual size | Specify dimensions on the header: `matrix heatmap 4x4` |\n| `cell (0, 0) level: Strong` (capital S) | `level` match is case-insensitive \u2014 accepted | Both `strong` and `Strong` work |\n| `shape: oval` | Unknown shape value \u2014 silently ignored | Use `circle`, `square`, `triangle`, or `diamond` |\n| `"Fix bug" at (0.1, 0.9)` on an Eisenhower with a task list | Valid scatter point \u2014 but you probably wanted a list in a cell | Add `style: table` and use `Q2: "Fix bug"` instead |\n| `Q1: "item"` on a 3\xD73 template | `Q` shorthand is parsed as a point line \u2014 silently dropped | Use `cell (col, row) label: "item"` for 3\xD73 grids |\n\n---\n\n## 16. Grammar (EBNF)\n\n```text\ndocument = header directive*\n\nheader = "matrix" ( template-name | mode-header | title )? NEWLINE\ntemplate-name = "eisenhower"|"impact-effort"|"rice"|"bcg"|"ansoff"|"johari"|"9-box"|"risk-matrix"\nmode-header = ( "heatmap" | "correlation" ) ( number "x" number )? title?\n | ( "sipoc" | "qfd" | "punnett" ) title?\ntitle = quoted-string | bare-text\n\ndirective = x-axis | y-axis | quadrant-dir | config-block\n | point | cell | q-short | rows-dir | cols-dir | grid-dir\n | style-dir | title-dir | axis-dir | margins-dir\n | sipoc-col | qfd-what | qfd-how | qfd-rel | qfd-roof | normalize-dir\n | punnett-cross | punnett-trait\n | comment | blank\n\n# SIPOC mode\nsipoc-col = ( "suppliers:" | "inputs:" | "process:" | "outputs:" | "customers:" )\n WS quoted-string ( "," quoted-string )* NEWLINE\n\n# QFD / House of Quality mode\nqfd-what = "what:" WS quoted-string WS "weight:" number NEWLINE\nqfd-how = "how:" WS quoted-string ( WS "dir:" ( "up" | "down" ) )? NEWLINE\nqfd-rel = "rel" WS "(" number "," number ")" ":" WS ( "9" | "3" | "1" ) NEWLINE # (row, col)\nqfd-roof = "roof" WS "(" number "," number ")" ":" WS ( "++" | "+" | "-" | "--" ) NEWLINE # (how, how)\nnormalize-dir = "normalize:" WS "true" NEWLINE\n\n# Punnett (Mendelian genetics) mode\npunnett-cross = ( "cross:" | "parents:" ) WS genotype WS ( "x" | "\xD7" | "*" ) WS genotype NEWLINE\npunnett-trait = "trait" WS letter ":" WS quoted-string WS "/" WS quoted-string NEWLINE # dominant / recessive\ngenotype = ( letter letter )+ # allele pairs grouped by letter; case = dominance, e.g. "RrYy"\n\nx-axis = "x-axis:" WS axis-spec NEWLINE\ny-axis = "y-axis:" WS axis-spec NEWLINE\naxis-spec = text arrow text | text # plain text \u2192 high label only\narrow = "\u2192" | "->" | "\u2191" | "\u2190" | "<-" | "<" | "\u2193"\n\nquadrant-dir = "quadrant" WS "Q"? digit WS quoted-string ( WS "description:" quoted-string )? NEWLINE\n\nconfig-block = "config:" NEWLINE ( INDENT key ":" WS value NEWLINE )*\n\npoint = quoted-string WS "at" WS "(" number "," number ")" ( WS point-prop )* NEWLINE\npoint-prop = "size:" number\n | "category:" bareword\n | "color:" hex-color\n | "shape:" ( "circle"|"square"|"triangle"|"diamond" )\n | "highlight:" "true"\n | "note:" quoted-string\n | "label:" quoted-string\n\ncell = "cell" WS "(" digit "," digit ")" ( WS cell-prop )* NEWLINE\ncell-prop = "value:" number\n | "label:" quoted-string\n | "level:" ( "strong" | "medium" | "weak" )\n\nstyle-dir = "style:" WS "table" NEWLINE\nq-short = "Q" ( "1" | "2" | "3" | "4" ) ":" WS quoted-string NEWLINE # 2\xD72 only\n\nrows-dir = "rows:" WS label-list NEWLINE\ncols-dir = "cols:" WS label-list NEWLINE\ngrid-dir = "grid:" WS number "x" number NEWLINE\naxis-dir = "axis:" WS ( "off" | "on" | "auto" ) NEWLINE\nmargins-dir = "margins:" WS ( "true" | "false" | "on" | "1" ) NEWLINE\n\nlabel-list = "[" text ("," text)* "]" | text ("," text)*\nquoted-string = \'"\' any-char-but-quote* \'"\' | "\'" any-char-but-quote* "\'"\ncomment = "#" any NEWLINE\n```\n\nAuthoritative source: `src/diagrams/matrix/parser.ts`. If this diverges from the parser, the parser wins \u2014 please open an issue.\n\n---'
3389
3476
  },
3390
3477
  "orgchart": {
3391
3478
  "title": "Org chart",
@@ -3494,6 +3581,10 @@ var SYNTAX = {
3494
3581
  "threatmodel": {
3495
3582
  "title": "Threat Model (STRIDE DFD)",
3496
3583
  "content": '## 1. Your first threat model\n\nStart with the `threatmodel` keyword (alias `stride`), an optional title, then **declare elements** and **wire flows**:\n\n```\nthreatmodel "Login flow"\nexternal: User\nprocess 1.1: Web Server\ndatastore D1: User DB\nUser -> 1.1 : "Login request"\n1.1 -> D1 : Lookup\n```\n\nEach element is `kind: ID: Label` (or `kind: Label`, where the id is slugged from the label \u2014 `external: Mobile App` becomes id `Mobile_App`). A flow is `SOURCE -> TARGET : label`, and the **label is mandatory** (it names the data crossing).\n\n---\n\n## 2. Element kinds and flows\n\n```\nexternal: User # external entity (the attacker\'s side)\nprocess 1.1: Web Server # a process / service\ndatastore D1: User DB # a data store\ndatastore D2: Audit log # a log/audit store (gets conditional Repudiation)\nUser -> 1.1 : "HTTPS Request" # directed flow, quoted or bare label\n1.1 <-> D1 : Read/Write # <-> expands into two directed flows\n```\n\n- Process ids are often dotted DFD numbers (`1.1`, `2.3`); external/store ids are usually short slugs (`User`, `D1`).\n- A `<->` flow expands into **two** directed flows.\n- A store whose name/id matches `log|audit|journal` (or carries an explicit hint) is treated as a log store.\n\n**Flow rules** the engine enforces: no store\u2192store flows (data stores are passive), no external\u2192external flows, and every endpoint must be a declared element.\n\n---\n\n## 3. Trust boundaries\n\n```\nboundary "Internet" { User }\nboundary "DMZ" { 1.1 }\nboundary "Internal" { D1, D2 }\n```\n\n`boundary "name" { id, id, \u2026 }` groups elements into a trust zone. An element may belong to **at most one** boundary; members must be declared. Elements in no boundary share an implicit untrusted zone.\n\n---\n\n## 4. Computed STRIDE analysis\n\nThis is the differentiator. The engine applies the **STRIDE-per-element** mapping:\n\n| DFD element | Threats applied |\n|-----------------|------------------------|\n| External entity | S, R |\n| Process | S, T, R, I, D, E |\n| Data store | T, I, D (+ R if log) |\n| Data flow | T, I, D |\n\n- The data-store **Repudiation** is conditional \u2014 added for log / audit / journal stores (the Shostack green "?").\n- **Boundary crossing**: a flow whose endpoints sit in different trust zones is flagged, because that is where Spoofing / Tampering / Information-disclosure concentrate. Two elements in the same (or implicit) zone do not cross.\n\nEach element and flow carries its applicable STRIDE categories in `data-*` so the analysis is inspectable.\n\n---\n\n## 5. Common mistakes\n\n```\n# WRONG \u2014 flow with no label\nUser -> 1.1\n\n# WRONG \u2014 store to store (data stores are passive)\nD1 -> D2 : x\n\n# WRONG \u2014 external to external\nA -> B : x\n\n# WRONG \u2014 unknown flow endpoint\nP -> Ghost : x\n\n# WRONG \u2014 an element in two boundaries\nboundary "A" { P }\nboundary "B" { P }\n```\n\nEvery flow needs a label; stores and externals cannot be flow partners with their own kind; endpoints must be declared; an element belongs to at most one trust boundary. Duplicate ids are rejected.\n\n---'
3584
+ },
3585
+ "welding": {
3586
+ "title": "Welding symbol diagram",
3587
+ "content": '## 1. Your first weld\n\nThe smallest useful callout: a header, one joint, one arrow-side weld.\n\n```\nwelding "Bracket"\njoint "bracket to plate" {\n arrow: fillet size=8\n}\n```\n\nThree rules cover most usage:\n\n1. Start with `welding`, optionally `standard: aws | iso-a | iso-b` (default `aws`) and a quoted title.\n2. Each joint is a `joint "label" { \u2026 }` block. Put a weld on `arrow:` (arrow side) and/or `other:` (other side).\n3. A weld spec is a type followed by `key=value` dimensions \u2014 `fillet size=8`, `vgroove angle=60 root=3`.\n\n---\n\n## 2. Sides \u2014 arrow, other, both\n\nA joint is welded on the arrow side, the other side, or both.\n\n```\njoint "double fillet" {\n both: fillet size=6 # same weld on both sides\n}\njoint "asymmetric" {\n arrow: fillet size=8 # arrow side only\n other: vgroove angle=60 # different weld on the other side\n}\n```\n\n- **AWS** (default): the arrow-side glyph draws **below** the reference line, the other-side glyph **above**.\n- **ISO-A** (`standard: iso-a`): a **dashed companion line** appears; the arrow-side weld attaches to the solid line, the other-side weld to the dashed line. A symmetric `both:` weld suppresses the dashed line.\n\n---\n\n## 3. Weld types\n\n| Type | Glyph | Type | Glyph |\n|---|---|---|---|\n| `fillet` | triangle | `plug` / `slot` | rectangle |\n| `square` | parallel verticals | `spot` | circle on the line |\n| `vgroove` | V | `seam` | circle + line |\n| `bevel` | half-V | `back` / `backing` | semicircle |\n| `ugroove` | U | `surfacing` | build-up bumps |\n| `jgroove` | half-U | `edge` | tall verticals |\n| `flarev` / `flarebevel` | curved groove | | |\n\nAliases: `v`\u2192`vgroove`, `u`\u2192`ugroove`, `j`\u2192`jgroove`, `flare-v`\u2192`flarev`.\n\n---\n\n## 4. Dimensions\n\nDimensions read along the reference line in fixed slots.\n\n```\njoint "groove" {\n arrow: vgroove angle=60 root=3 throat=12 len=50 pitch=150\n}\n```\n\n| Key | Slot | Meaning |\n|---|---|---|\n| `size=` | left of symbol | fillet leg / groove depth / plug diameter |\n| `throat=` | left, in parentheses | effective throat `(E)` |\n| `len=` | right of symbol | weld length |\n| `pitch=` | right (with `len`) | intermittent centre-to-centre pitch \u2192 `len-pitch` |\n| `count=` | right (ISO) | number of increments \u2192 `count\xD7len (pitch)` |\n| `angle=` | at the opening | groove included angle (groove types only) |\n| `root=` | between symbol and line | root opening / gap |\n| `contour=` | above the symbol | `flush` (bar), `convex`, `concave` (arc) |\n| `finish=` | above the contour | finish method letter `G`/`M`/`C`/`R`/`H`/`U` |\n\n---\n\n## 5. Supplementary symbols\n\n```\njoint "post base" {\n arrow: fillet size=10\n around # weld-all-around \u2014 open circle at the junction\n field # field / site weld \u2014 filled flag pointing to the tail\n tail: "GTAW; WPS-12" # process / spec / NDE method\n}\n```\n\n```\nwelding\njoint "butt weld" {\n arrow: vgroove angle=60 root=3 throat=12\n other: backing\n tail: "SMAW; E7018"\n}\n```\n\n---'
3497
3588
  }
3498
3589
  };
3499
3590
 
@@ -3680,8 +3771,17 @@ var PROFILES = {
3680
3771
  type: "entity",
3681
3772
  header: 'entity-structure "Title"',
3682
3773
  mode: "legal entities + ownership edges",
3683
- forms: ['entity holdco "HoldCo" corp@US', 'entity opco "OpCo" llc@DE', "holdco -> opco : 100%"],
3684
- prefer: ["Use `entity` declarations before ownership edges.", "Keep legal form and jurisdiction explicit when known."],
3774
+ forms: [
3775
+ 'entity holdco "HoldCo" corp@US',
3776
+ 'entity opco "OpCo" llc@DE',
3777
+ "holdco -> opco : 100%",
3778
+ 'cluster "Group Name" [members: [holdco, opco]]'
3779
+ ],
3780
+ prefer: [
3781
+ "Use `entity` declarations before ownership edges.",
3782
+ "Keep legal form and jurisdiction explicit when known.",
3783
+ 'Group entities with `cluster "Name" [members: [id1, id2]]` \u2014 the members value MUST be a bracketed list.'
3784
+ ],
3685
3785
  avoid: ["Avoid database schema terminology; use `erd` for tables and FKs."],
3686
3786
  repair: ["Unknown ownership endpoints need entity declarations."]
3687
3787
  },
@@ -4277,6 +4377,40 @@ var PROFILES = {
4277
4377
  "'unknown element' \u2014 declare the external/process/datastore before referencing it.",
4278
4378
  "'flow needs a label' \u2014 add `: \"\u2026\"` to the flow."
4279
4379
  ]
4380
+ },
4381
+ welding: {
4382
+ type: "welding",
4383
+ header: "welding [standard: aws|iso-a|iso-b]",
4384
+ mode: "reference-line callouts; one joint block per joint, weld glyphs above/below the line",
4385
+ forms: [
4386
+ 'welding "Bracket welds"',
4387
+ 'joint "bracket to plate" {',
4388
+ " arrow: fillet size=8 len=50 pitch=150",
4389
+ " other: fillet size=6",
4390
+ " around",
4391
+ " field",
4392
+ ' tail: "GTAW"',
4393
+ "}",
4394
+ 'joint "butt weld" {',
4395
+ " arrow: vgroove angle=60 root=3 throat=12",
4396
+ " other: backing",
4397
+ "}"
4398
+ ],
4399
+ prefer: [
4400
+ 'Keyword `welding`; one `joint "label" { \u2026 }` block per joint. Put a weld on `arrow:` (arrow side) and/or `other:` (other side); `both:` is shorthand for the same weld on both sides.',
4401
+ "A weldspec is `<type> key=value \u2026`: `size=` (left of symbol), `len=`/`pitch=` (length-pitch, right), `angle=`/`root=` (groove only), `throat=`, `contour=flush|convex|concave`, `finish=G|M|C|R|H|U`.",
4402
+ 'Flags on their own line: `around` (weld-all-around), `field` (site weld). Process/spec/NDE goes in `tail: "GTAW; WPS-12"`.',
4403
+ "Types: fillet \xB7 square \xB7 vgroove \xB7 bevel \xB7 ugroove \xB7 jgroove \xB7 flarev \xB7 flarebevel \xB7 plug \xB7 slot \xB7 spot \xB7 seam \xB7 back \xB7 backing \xB7 surfacing \xB7 edge."
4404
+ ],
4405
+ avoid: [
4406
+ "Don't put `angle=` on a fillet/plug/spot \u2014 angle is groove-only (the engine warns).",
4407
+ "Don't use `both:` for plug/slot/surfacing \u2014 they are single-side; surfacing is arrow-side only.",
4408
+ "Don't give a fillet without `size=`, or a `pitch=` without `len=`."
4409
+ ],
4410
+ repair: [
4411
+ "'a fillet weld needs a leg size' \u2014 add `size=\u2026` to the fillet spec.",
4412
+ "'angle= only applies to groove welds' \u2014 drop `angle=`, or change the type to a groove."
4413
+ ]
4280
4414
  }
4281
4415
  };
4282
4416
  function getGenerationProfile(type) {
@@ -4429,5 +4563,5 @@ function repairHint(type) {
4429
4563
  }
4430
4564
 
4431
4565
  export { DIAGRAM_REGISTRY, DIAGRAM_SINCE, getAllDiagramTypes, getDiagramMeta, getDiagramSince, getExamples, getSyntax, listDiagrams, renderDsl, resolveDiagramType, validateDsl };
4432
- //# sourceMappingURL=chunk-TXMT4XLE.js.map
4433
- //# sourceMappingURL=chunk-TXMT4XLE.js.map
4566
+ //# sourceMappingURL=chunk-FLDHD4RM.js.map
4567
+ //# sourceMappingURL=chunk-FLDHD4RM.js.map