schematex 0.6.1 → 0.6.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/ai/ai-sdk.cjs +25 -25
- package/dist/ai/ai-sdk.d.cts +4 -4
- package/dist/ai/ai-sdk.d.ts +4 -4
- package/dist/ai/ai-sdk.js +20 -20
- package/dist/ai/index.cjs +31 -31
- package/dist/ai/index.d.cts +3 -3
- package/dist/ai/index.d.ts +3 -3
- package/dist/ai/index.js +20 -20
- package/dist/{api-BEJTXyBA.d.cts → api-BIqZjEDf.d.ts} +2 -2
- package/dist/{api-DFrSR3lw.d.ts → api-BXkOT7GL.d.cts} +2 -2
- package/dist/browser.cjs +26 -26
- package/dist/browser.d.cts +3 -3
- package/dist/browser.d.ts +3 -3
- package/dist/browser.js +20 -20
- package/dist/{chunk-ST5YRTTV.cjs → chunk-2F45Y2ON.cjs} +44 -5
- package/dist/chunk-2F45Y2ON.cjs.map +1 -0
- package/dist/{chunk-UWA5MWCI.js → chunk-35XCP2E4.js} +82 -48
- package/dist/chunk-35XCP2E4.js.map +1 -0
- package/dist/{chunk-VTSH4YPT.cjs → chunk-3C5DKCBJ.cjs} +12 -12
- package/dist/{chunk-VTSH4YPT.cjs.map → chunk-3C5DKCBJ.cjs.map} +1 -1
- package/dist/{chunk-HWVBHU3O.cjs → chunk-4THUHX2D.cjs} +5 -5
- package/dist/{chunk-HWVBHU3O.cjs.map → chunk-4THUHX2D.cjs.map} +1 -1
- package/dist/{chunk-4XR7X7XW.cjs → chunk-624UQ5R6.cjs} +4073 -640
- package/dist/chunk-624UQ5R6.cjs.map +1 -0
- package/dist/{chunk-LRI4RH2N.js → chunk-AORGFBEH.js} +127 -3
- package/dist/chunk-AORGFBEH.js.map +1 -0
- package/dist/{chunk-DOK7LKLO.js → chunk-B7ATOBL7.js} +3 -3
- package/dist/{chunk-DOK7LKLO.js.map → chunk-B7ATOBL7.js.map} +1 -1
- package/dist/{chunk-FKJBXGWP.cjs → chunk-BXNOXOE4.cjs} +4 -4
- package/dist/{chunk-FKJBXGWP.cjs.map → chunk-BXNOXOE4.cjs.map} +1 -1
- package/dist/{chunk-MFAMNFPA.js → chunk-EPKIJEH7.js} +6 -63
- package/dist/chunk-EPKIJEH7.js.map +1 -0
- package/dist/{chunk-H4MT5TJP.js → chunk-FHZTWWI6.js} +3 -3
- package/dist/{chunk-H4MT5TJP.js.map → chunk-FHZTWWI6.js.map} +1 -1
- package/dist/{chunk-2L4YXZAZ.cjs → chunk-FXPOHPBE.cjs} +5 -5
- package/dist/{chunk-2L4YXZAZ.cjs.map → chunk-FXPOHPBE.cjs.map} +1 -1
- package/dist/{chunk-3VB5AT4R.js → chunk-GPC5BWLI.js} +3 -3
- package/dist/{chunk-3VB5AT4R.js.map → chunk-GPC5BWLI.js.map} +1 -1
- package/dist/{chunk-MVIEIKOI.js → chunk-GV5QLYTW.js} +3 -3
- package/dist/{chunk-MVIEIKOI.js.map → chunk-GV5QLYTW.js.map} +1 -1
- package/dist/{chunk-WQDIZH2Z.cjs → chunk-HCBXTBFA.cjs} +12 -12
- package/dist/{chunk-WQDIZH2Z.cjs.map → chunk-HCBXTBFA.cjs.map} +1 -1
- package/dist/{chunk-6JI6FWLZ.cjs → chunk-I6UJR4SG.cjs} +4 -4
- package/dist/{chunk-6JI6FWLZ.cjs.map → chunk-I6UJR4SG.cjs.map} +1 -1
- package/dist/{chunk-RJMCWT7Z.js → chunk-IPEHLRTI.js} +3 -3
- package/dist/{chunk-RJMCWT7Z.js.map → chunk-IPEHLRTI.js.map} +1 -1
- package/dist/{chunk-N5B242WY.js → chunk-KPKGMOTS.js} +3 -3
- package/dist/{chunk-N5B242WY.js.map → chunk-KPKGMOTS.js.map} +1 -1
- package/dist/{chunk-TWLKXV2O.js → chunk-LGFB4H5B.js} +4 -4
- package/dist/{chunk-TWLKXV2O.js.map → chunk-LGFB4H5B.js.map} +1 -1
- package/dist/{chunk-I2GQYOZ5.js → chunk-MI77LY6A.js} +4043 -612
- package/dist/chunk-MI77LY6A.js.map +1 -0
- package/dist/{chunk-7F76AWOI.js → chunk-MKECYIWN.js} +3 -3
- package/dist/{chunk-7F76AWOI.js.map → chunk-MKECYIWN.js.map} +1 -1
- package/dist/{chunk-522WB2EH.js → chunk-OANWVUBA.js} +100 -25
- package/dist/chunk-OANWVUBA.js.map +1 -0
- package/dist/{chunk-YS6CGUNH.js → chunk-OHLNH7IO.js} +3 -3
- package/dist/{chunk-YS6CGUNH.js.map → chunk-OHLNH7IO.js.map} +1 -1
- package/dist/{chunk-6URNSB6G.js → chunk-P26FCZP3.js} +44 -5
- package/dist/chunk-P26FCZP3.js.map +1 -0
- package/dist/{chunk-L7POWM5B.cjs → chunk-R5E2LSN2.cjs} +129 -2
- package/dist/chunk-R5E2LSN2.cjs.map +1 -0
- package/dist/{chunk-S3RMAXH5.cjs → chunk-ROX5KEZM.cjs} +15 -15
- package/dist/{chunk-S3RMAXH5.cjs.map → chunk-ROX5KEZM.cjs.map} +1 -1
- package/dist/{chunk-3IE7KZY4.js → chunk-RVHOCGHT.js} +96 -10
- package/dist/chunk-RVHOCGHT.js.map +1 -0
- package/dist/{chunk-4UFR2LB6.cjs → chunk-S2CHBZ4A.cjs} +13 -13
- package/dist/{chunk-4UFR2LB6.cjs.map → chunk-S2CHBZ4A.cjs.map} +1 -1
- package/dist/{chunk-XNCOSVNG.cjs → chunk-SUIDD2C5.cjs} +6 -63
- package/dist/chunk-SUIDD2C5.cjs.map +1 -0
- package/dist/{chunk-SSLNPHCL.cjs → chunk-T3ZN5P32.cjs} +452 -61
- package/dist/chunk-T3ZN5P32.cjs.map +1 -0
- package/dist/{chunk-R66QG3XT.cjs → chunk-VZO2SX6Q.cjs} +98 -10
- package/dist/chunk-VZO2SX6Q.cjs.map +1 -0
- package/dist/{chunk-R6VX5YTJ.cjs → chunk-W3IXH6BN.cjs} +100 -25
- package/dist/chunk-W3IXH6BN.cjs.map +1 -0
- package/dist/{chunk-V4GILQR6.cjs → chunk-WZ5QBGPZ.cjs} +4 -4
- package/dist/{chunk-V4GILQR6.cjs.map → chunk-WZ5QBGPZ.cjs.map} +1 -1
- package/dist/{chunk-FBS3PACU.js → chunk-XEIVA2CT.js} +3 -3
- package/dist/{chunk-FBS3PACU.js.map → chunk-XEIVA2CT.js.map} +1 -1
- package/dist/{chunk-V4RO5KYY.cjs → chunk-XJJUJ2EF.cjs} +83 -49
- package/dist/chunk-XJJUJ2EF.cjs.map +1 -0
- package/dist/{chunk-C5C5EF3W.cjs → chunk-XO7WW3I6.cjs} +4 -4
- package/dist/{chunk-C5C5EF3W.cjs.map → chunk-XO7WW3I6.cjs.map} +1 -1
- package/dist/{chunk-HAZALB7U.js → chunk-XSPENTEG.js} +3 -3
- package/dist/{chunk-HAZALB7U.js.map → chunk-XSPENTEG.js.map} +1 -1
- package/dist/{chunk-YB4XJY5L.cjs → chunk-ZZFPXCAK.cjs} +12 -12
- package/dist/{chunk-YB4XJY5L.cjs.map → chunk-ZZFPXCAK.cjs.map} +1 -1
- package/dist/{chunk-OTSVMKII.js → chunk-ZZHQBAC3.js} +450 -59
- package/dist/chunk-ZZHQBAC3.js.map +1 -0
- package/dist/{diagnostics-B-ffSEhl.d.ts → diagnostics-CzHW0RCo.d.cts} +7 -11
- package/dist/{diagnostics-B-ffSEhl.d.cts → diagnostics-CzHW0RCo.d.ts} +7 -11
- package/dist/diagrams/blockdiagram/index.cjs +5 -5
- package/dist/diagrams/blockdiagram/index.d.cts +1 -1
- package/dist/diagrams/blockdiagram/index.d.ts +1 -1
- package/dist/diagrams/blockdiagram/index.js +1 -1
- package/dist/diagrams/circuit/index.cjs +8 -8
- package/dist/diagrams/circuit/index.d.cts +1 -1
- package/dist/diagrams/circuit/index.d.ts +1 -1
- package/dist/diagrams/circuit/index.js +2 -2
- package/dist/diagrams/ecomap/index.cjs +7 -7
- package/dist/diagrams/ecomap/index.d.cts +1 -1
- package/dist/diagrams/ecomap/index.d.ts +1 -1
- package/dist/diagrams/ecomap/index.js +2 -2
- package/dist/diagrams/entity/index.cjs +6 -6
- package/dist/diagrams/entity/index.d.cts +1 -1
- package/dist/diagrams/entity/index.d.ts +1 -1
- package/dist/diagrams/entity/index.js +2 -2
- package/dist/diagrams/fishbone/index.cjs +8 -8
- package/dist/diagrams/fishbone/index.d.cts +1 -1
- package/dist/diagrams/fishbone/index.d.ts +1 -1
- package/dist/diagrams/fishbone/index.js +2 -2
- package/dist/diagrams/flowchart/index.cjs +8 -8
- package/dist/diagrams/flowchart/index.d.cts +2 -2
- package/dist/diagrams/flowchart/index.d.ts +2 -2
- package/dist/diagrams/flowchart/index.js +2 -2
- package/dist/diagrams/genogram/index.cjs +9 -9
- package/dist/diagrams/genogram/index.d.cts +1 -1
- package/dist/diagrams/genogram/index.d.ts +1 -1
- package/dist/diagrams/genogram/index.js +2 -2
- package/dist/diagrams/ladder/index.cjs +7 -7
- package/dist/diagrams/ladder/index.d.cts +1 -1
- package/dist/diagrams/ladder/index.d.ts +1 -1
- package/dist/diagrams/ladder/index.js +3 -3
- package/dist/diagrams/logic/index.cjs +15 -6
- package/dist/diagrams/logic/index.d.cts +7 -2
- package/dist/diagrams/logic/index.d.ts +7 -2
- package/dist/diagrams/logic/index.js +3 -2
- package/dist/diagrams/orgchart/index.cjs +7 -7
- package/dist/diagrams/orgchart/index.d.cts +1 -1
- package/dist/diagrams/orgchart/index.d.ts +1 -1
- package/dist/diagrams/orgchart/index.js +2 -2
- package/dist/diagrams/pedigree/index.cjs +7 -7
- package/dist/diagrams/pedigree/index.d.cts +1 -1
- package/dist/diagrams/pedigree/index.d.ts +1 -1
- package/dist/diagrams/pedigree/index.js +2 -2
- package/dist/diagrams/phylo/index.cjs +7 -7
- package/dist/diagrams/phylo/index.d.cts +1 -1
- package/dist/diagrams/phylo/index.d.ts +1 -1
- package/dist/diagrams/phylo/index.js +2 -2
- package/dist/diagrams/sld/index.cjs +9 -9
- package/dist/diagrams/sld/index.d.cts +1 -1
- package/dist/diagrams/sld/index.d.ts +1 -1
- package/dist/diagrams/sld/index.js +3 -3
- package/dist/diagrams/sociogram/index.cjs +6 -6
- package/dist/diagrams/sociogram/index.d.cts +1 -1
- package/dist/diagrams/sociogram/index.d.ts +1 -1
- package/dist/diagrams/sociogram/index.js +2 -2
- package/dist/diagrams/timing/index.cjs +4 -4
- package/dist/diagrams/timing/index.d.cts +1 -1
- package/dist/diagrams/timing/index.d.ts +1 -1
- package/dist/diagrams/timing/index.js +1 -1
- package/dist/diagrams/venn/index.cjs +9 -9
- package/dist/diagrams/venn/index.d.cts +1 -1
- package/dist/diagrams/venn/index.d.ts +1 -1
- package/dist/diagrams/venn/index.js +2 -2
- package/dist/{index-DPWdYfNx.d.ts → index-DdR1Auby.d.ts} +1 -1
- package/dist/{index-S0njakQ2.d.cts → index-R0IwpG20.d.cts} +1 -1
- package/dist/index.cjs +84 -76
- package/dist/index.d.cts +9 -5
- package/dist/index.d.ts +9 -5
- package/dist/index.js +24 -24
- package/dist/react.cjs +20 -20
- package/dist/react.d.cts +2 -2
- package/dist/react.d.ts +2 -2
- package/dist/react.js +19 -19
- package/dist/{tools-CeGGMCs7.d.cts → tools-B7EqXLgD.d.ts} +3 -3
- package/dist/{tools-kK_enDwb.d.ts → tools-DHSVXHM9.d.cts} +3 -3
- package/package.json +1 -1
- package/dist/chunk-3IE7KZY4.js.map +0 -1
- package/dist/chunk-4XR7X7XW.cjs.map +0 -1
- package/dist/chunk-522WB2EH.js.map +0 -1
- package/dist/chunk-6URNSB6G.js.map +0 -1
- package/dist/chunk-I2GQYOZ5.js.map +0 -1
- package/dist/chunk-L7POWM5B.cjs.map +0 -1
- package/dist/chunk-LRI4RH2N.js.map +0 -1
- package/dist/chunk-MFAMNFPA.js.map +0 -1
- package/dist/chunk-OTSVMKII.js.map +0 -1
- package/dist/chunk-R66QG3XT.cjs.map +0 -1
- package/dist/chunk-R6VX5YTJ.cjs.map +0 -1
- package/dist/chunk-SSLNPHCL.cjs.map +0 -1
- package/dist/chunk-ST5YRTTV.cjs.map +0 -1
- package/dist/chunk-UWA5MWCI.js.map +0 -1
- package/dist/chunk-V4RO5KYY.cjs.map +0 -1
- package/dist/chunk-XNCOSVNG.cjs.map +0 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var chunk624UQ5R6_cjs = require('./chunk-624UQ5R6.cjs');
|
|
4
4
|
|
|
5
5
|
// src/ai/registry.ts
|
|
6
6
|
var DIAGRAM_REGISTRY = [
|
|
@@ -265,6 +265,25 @@ var DIAGRAM_REGISTRY = [
|
|
|
265
265
|
standard: "PMI PMBOK 7 + Moder 1983 (AON/PDM); see 32-PERT-STANDARD.md",
|
|
266
266
|
syntaxKey: "pert"
|
|
267
267
|
},
|
|
268
|
+
// ── Structural UML ───────────────────────────────────────────
|
|
269
|
+
{
|
|
270
|
+
type: "umlclass",
|
|
271
|
+
name: "UML Class Diagram",
|
|
272
|
+
tagline: "OMG UML 2.5.1 class diagram \u2014 classifiers (class / abstract / interface / enum / datatype / primitive) joined by the six relationship kinds, with visibility, multiplicity, and stereotypes.",
|
|
273
|
+
useWhen: "Use for OO design \u2014 the static type structure of a software system. Declare `class X { + name: T }` / `\xABinterface\xBB Y { + op(): R }` / `\xABenumeration\xBB Z { A B C }`, then connect with PlantUML-flavoured glyphs: `<|--` generalization (hollow triangle to parent), `<|..` realization (dashed + hollow triangle to interface), `*--` composition (filled diamond at the whole), `o--` aggregation (hollow diamond at the whole), `-->` directed association (open arrow to target), `..>` dependency (dashed + open arrow), `--` plain association. Adornment placement is normalised regardless of which id is typed first (reversed forms accepted). Mermaid `classDiagram` glyphs work as aliases. Layout is generalization-driven (parents on top by default). Distinct from `erd` (data tables + crow's-foot \u2014 no visibility/methods/inheritance) and from `entity` (legal/corporate ownership). This is the C4 (\xA730) Code-level engine.",
|
|
274
|
+
cluster: "software-uml",
|
|
275
|
+
standard: "OMG UML 2.5.1 \xA79\u2013\xA711 (Classification / Classifiers / Associations) + ISO/IEC 19505-2:2012; see 36-UMLCLASS-STANDARD.md",
|
|
276
|
+
syntaxKey: "umlclass"
|
|
277
|
+
},
|
|
278
|
+
{
|
|
279
|
+
type: "faulttree",
|
|
280
|
+
name: "Fault Tree Analysis",
|
|
281
|
+
tagline: "Deductive top-down reliability analysis \u2014 decompose one undesired top event through Boolean AND/OR/voting gates to basic component failures; the engine computes the minimal cut sets and the top-event probability.",
|
|
282
|
+
useWhen: 'Use for safety / reliability analysis: start from one top event and decompose its causes through gates down to basic events with known failure probabilities. Flat declaration wired by id: `top T "\u2026" = OR(G1, G2)`, `gate G1 = AND(A, B)`, `basic A "\u2026" p: 0.01`. Gates: AND/OR/XOR(a,b,\u2026), VOTING(k/n; \u2026), INHIBIT(x) if cond, PAND(a,b). `house H state: 0|1` switches branches; `undeveloped` for unanalysed causes. The engine *computes* the minimal cut sets (MOCUS) and P(top) (`prob: rare|mcub|exact`) and highlights single points of failure \u2014 the differentiator over a shape stencil. Keyword `faulttree` (alias `fta`). Distinct from `logic` (left-right signal netlist), `decisiontree` (expected-value rollback), and `fishbone` (qualitative, unquantified).',
|
|
283
|
+
cluster: "risk-reliability",
|
|
284
|
+
standard: "NUREG-0492 Fault Tree Handbook + IEC 61025:2006 + NASA FT Handbook 2002; MOCUS cut sets (Fussell-Vesely 1972); see 37-FAULT-TREE-STANDARD.md",
|
|
285
|
+
syntaxKey: "faulttree"
|
|
286
|
+
},
|
|
268
287
|
// ── Generic process / flow ───────────────────────────────────
|
|
269
288
|
{
|
|
270
289
|
type: "flowchart",
|
|
@@ -356,7 +375,11 @@ var DIAGRAM_SINCE = {
|
|
|
356
375
|
// 0.6.0 — upcoming (committed post-0.5.2, not yet released)
|
|
357
376
|
pert: "0.6.0",
|
|
358
377
|
petri: "0.6.0",
|
|
359
|
-
network: "0.6.0"
|
|
378
|
+
network: "0.6.0",
|
|
379
|
+
// 0.6.4
|
|
380
|
+
umlclass: "0.6.4",
|
|
381
|
+
// 0.6.5
|
|
382
|
+
faulttree: "0.6.5"
|
|
360
383
|
};
|
|
361
384
|
function getDiagramSince(type) {
|
|
362
385
|
const resolved = resolveDiagramType(type);
|
|
@@ -616,6 +639,25 @@ If the LED doesn't light up, three things to check, in order: LED polarity (the
|
|
|
616
639
|
"dsl": 'circuit "Inverting Op-Amp (netlist)" netlist\nVin vin 0 AC1V\nRin vin inv 10k\nRf out inv 100k\nU1 noninv inv out type=opamp label="U1 TL072"\nRbias noninv 0 10k\nVp vcc 0 +12V\nVn vee 0 -12V',
|
|
617
640
|
"notes": "## Scenario\n\nAn analog engineer documents a standard inverting gain stage before moving to PCB layout. The two resistors make the gain visible in the schematic: `Rf / Rin = 10`, so the output is an inverted, amplified version of the input.\n\n## Annotation key\n\n- `type=opamp` selects the three-pin op-amp symbol in netlist mode.\n- `Rin` and `Rf` are ordinary SPICE-style resistor lines.\n- `noninv`, `inv`, and `out` are named nets, not pixel coordinates.\n\n## How to read\n\nThe input signal enters through `Rin` into the inverting input. `Rf` feeds the output back to the same node, closing the negative feedback loop. The non-inverting input is tied to ground through `Rbias`, giving the stage a stable reference."
|
|
618
641
|
},
|
|
642
|
+
{
|
|
643
|
+
"slug": "circuit-pullup-orientation-hint",
|
|
644
|
+
"diagram": "circuit",
|
|
645
|
+
"title": "Pull-up resistor circuit with dir= orientation hint",
|
|
646
|
+
"description": "A netlist-mode circuit that uses the optional dir= orientation hint to draw the pull-up resistor vertically, showing lightweight layout control on top of automatic placement.",
|
|
647
|
+
"standard": "IEEE 315 / IEC 60617",
|
|
648
|
+
"tags": [
|
|
649
|
+
"netlist",
|
|
650
|
+
"pull-up",
|
|
651
|
+
"dir",
|
|
652
|
+
"orientation",
|
|
653
|
+
"push-button",
|
|
654
|
+
"SPICE"
|
|
655
|
+
],
|
|
656
|
+
"complexity": 1,
|
|
657
|
+
"featured": false,
|
|
658
|
+
"dsl": 'circuit "Pull-up + push button" netlist\nV1 vcc 0 5V\nR1 vcc sig 10k dir=down\nSW1 sig 0 type=switch\nC1 sig 0 100n',
|
|
659
|
+
"notes": "## Scenario\n\nAn embedded engineer documents a classic active-low input: a pull-up resistor\nholds the signal high, a push button pulls it to ground, and a small capacitor\ndebounces it. The connectivity is written as a SPICE-style netlist \u2014 the engine\nplaces everything from the node names \u2014 and one optional hint refines the look.\n\n## Annotation key\n\n- **netlist line** \u2014 `id node-A node-B value`; components that share a node name\n are wired together. `0` is ground.\n- **`dir=down`** \u2014 the optional orientation hint. `R1` connects `vcc` to `sig`;\n by default the engine would lay it horizontally, but a pull-up reads best drawn\n vertically from the supply rail down to the signal node, so `dir=down` rotates\n just that symbol. Connectivity is unchanged \u2014 `dir=` only rotates the glyph.\n- **`type=switch`** \u2014 the `SW1` id prefix is ambiguous, so the component type is\n made explicit.\n\n## How to read\n\n`R1` ties `sig` up to `vcc` (drawn vertically thanks to `dir=down`). `SW1` and the\ndebounce cap `C1` both go from `sig` to ground, so the engine recognises them as\nshunt legs and drops them beneath the node. Pressing the button shorts `sig` to\nground, pulling the input low."
|
|
660
|
+
},
|
|
619
661
|
{
|
|
620
662
|
"slug": "decisiontree-investment-analysis",
|
|
621
663
|
"diagram": "decisiontree",
|
|
@@ -868,6 +910,83 @@ If the LED doesn't light up, three things to check, in order: LED polarity (the
|
|
|
868
910
|
"dsl": 'erd\ntitle: "University Schema"\n\ntable Student {\n student_id int PK\n name varchar\n email varchar UK\n major_id int FK -> Major.major_id\n}\n\ntable Major {\n major_id int PK\n name varchar\n}\n\ntable Course {\n course_id int PK\n title varchar\n credits int\n}\n\ntable Enrollment {\n student_id int PK FK -> Student.student_id\n course_id int PK FK -> Course.course_id\n grade char\n}\n\nref Student.major_id many-mandatory -- one-mandatory Major.major_id : "majors in"\nref Enrollment.student_id many-mandatory -- one-mandatory Student.student_id\nref Enrollment.course_id many-mandatory -- one-mandatory Course.course_id',
|
|
869
911
|
"notes": "The university schema is the canonical introduction to associative entities. The M:N relationship between Student and Course is resolved through Enrollment, which carries the relationship attribute `grade`. Both Student and Course join Enrollment via composite primary keys (each FK column doubles as part of the PK)."
|
|
870
912
|
},
|
|
913
|
+
{
|
|
914
|
+
"slug": "faulttree-pump-redundancy",
|
|
915
|
+
"diagram": "faulttree",
|
|
916
|
+
"title": "Redundant pump failure (AND gate)",
|
|
917
|
+
"description": "The smallest quantified fault tree \u2014 two redundant pumps in an AND gate, so the system fails only if both fail. One minimal cut set, no single point of failure, with a computed top-event probability.",
|
|
918
|
+
"standard": "NUREG-0492 / IEC 61025",
|
|
919
|
+
"tags": [
|
|
920
|
+
"faulttree",
|
|
921
|
+
"fta",
|
|
922
|
+
"reliability",
|
|
923
|
+
"and-gate",
|
|
924
|
+
"cut-sets",
|
|
925
|
+
"probability"
|
|
926
|
+
],
|
|
927
|
+
"complexity": 1,
|
|
928
|
+
"featured": true,
|
|
929
|
+
"dsl": 'faulttree "Both pumps fail"\n analysis: cutsets, probability\n top T "Both redundant pumps fail" = AND(PA, PB)\n basic PA "Pump A fails" p: 0.01\n basic PB "Pump B fails" p: 0.01',
|
|
930
|
+
"notes": "## What this shows\n\nThe canonical reliability argument for redundancy. The top event occurs only when **both** pumps fail, so the gate is an **AND** (drawn as the flat-bottomed dome). The engine computes the one **minimal cut set `{PA, PB}`** (order 2, boxed in red) and \u2014 because no single component alone causes the top event \u2014 reports **no single point of failure**.\n\n**P(top) is computed, not drawn.** With independent basic events, `P(top) \u2248 P(PA)\xB7P(PB) = 1.0e-4` (rare-event). Adding a second pump turned two 1-in-100 components into a 1-in-10,000 system \u2014 exactly the quantified payoff redundancy is meant to deliver."
|
|
931
|
+
},
|
|
932
|
+
{
|
|
933
|
+
"slug": "faulttree-repeated-event",
|
|
934
|
+
"diagram": "faulttree",
|
|
935
|
+
"title": "Repeated event with cut-set absorption",
|
|
936
|
+
"description": "A shared basic event feeds two gates \u2014 the case naive fault-tree tools get wrong. MOCUS applies absorption so the supersets collapse, leaving two single points of failure that a shape stencil would miss.",
|
|
937
|
+
"standard": "NUREG-0492 / MOCUS (Fussell-Vesely 1972)",
|
|
938
|
+
"tags": [
|
|
939
|
+
"faulttree",
|
|
940
|
+
"fta",
|
|
941
|
+
"cut-sets",
|
|
942
|
+
"repeated-event",
|
|
943
|
+
"absorption",
|
|
944
|
+
"spof"
|
|
945
|
+
],
|
|
946
|
+
"complexity": 2,
|
|
947
|
+
"featured": true,
|
|
948
|
+
"dsl": 'faulttree "Product not removed"\n analysis: cutsets, probability\n top T "Failure to remove product" = OR(G1, G2)\n gate G1 "Arm jams or collides" = AND(MSF, G3)\n gate G2 "Wrong slot commanded" = OR(CDM, MSF)\n gate G3 "Loss of position feedback" = OR(ESF, RCF)\n basic MSF "Manipulator system failure" p: 0.0035\n basic CDM "Controller command error" p: 0.0009\n basic ESF "Encoder sensor failure" p: 0.0021\n basic RCF "Resolver cable fault" p: 0.0012',
|
|
949
|
+
"notes": "## What this shows\n\n`MSF` feeds **both** `G1` and `G2` \u2014 a *repeated event*, the DAG case that separates a real engine from a shape stencil. It is drawn once per reference with the shared-event mark, but the cut-set engine treats every instance as the same Boolean variable.\n\n**Absorption is the point.** MOCUS first expands the tree to `{MSF, ESF}`, `{MSF, RCF}`, `{MSF}`, `{CDM}`. Because `{MSF}` is itself a cut set (via `G2`), the larger sets `{MSF, ESF}` and `{MSF, RCF}` are *absorbed* \u2014 a superset of a cut set is not minimal. The **two minimal cut sets are `{MSF}` and `{CDM}`**, both order-1 **single points of failure** (boxed in the strongest red). A naive expander that forgets absorption would wrongly report four. `P(top) \u2248 P(MSF) + P(CDM) = 0.0044`."
|
|
950
|
+
},
|
|
951
|
+
{
|
|
952
|
+
"slug": "faulttree-vessel-rupture",
|
|
953
|
+
"diagram": "faulttree",
|
|
954
|
+
"title": "Pressure vessel rupture (full vocabulary)",
|
|
955
|
+
"description": "Voting, inhibit, house and undeveloped events in one tree \u2014 a 2-of-2 relief group, an over-pressure inhibited by a heater condition, and an order-3 minimal cut set with the tighter MCUB probability.",
|
|
956
|
+
"standard": "NUREG-0492 / IEC 61025",
|
|
957
|
+
"tags": [
|
|
958
|
+
"faulttree",
|
|
959
|
+
"fta",
|
|
960
|
+
"voting",
|
|
961
|
+
"inhibit",
|
|
962
|
+
"house-event",
|
|
963
|
+
"undeveloped",
|
|
964
|
+
"mcub"
|
|
965
|
+
],
|
|
966
|
+
"complexity": 3,
|
|
967
|
+
"featured": false,
|
|
968
|
+
"dsl": 'faulttree "Vessel ruptures"\n analysis: cutsets, probability\n prob: mcub\n top TOP "Pressure vessel ruptures" = AND(OVP, RELIEF)\n gate OVP "Sustained over-pressure" = INHIBIT(PUMP) if HEATER\n gate RELIEF "Both reliefs fail" = VOTING(2/2; PRV_A, PRV_B)\n basic PUMP "Pump runaway" p: 0.004\n basic PRV_A "Relief A stuck" p: 0.02\n basic PRV_B "Relief B stuck" p: 0.02\n house HEATER "Heater energised" state: 1\n undeveloped EXT "External fire (not modelled)"',
|
|
969
|
+
"notes": "## What this shows\n\nThe full NUREG-0492 vocabulary in one tree. **INHIBIT** renders as a hexagon with the `HEATER` conditioning event as an ellipse on its side; because `HEATER` is a **house event** forced to `state: 1`, it is absorbed as a constant TRUE and `OVP` reduces to `{PUMP}`. **VOTING `2/2`** is a redundant relief group that fails only when both valves stick.\n\nThe single **minimal cut set is `{PUMP, PRV_A, PRV_B}`** (order 3), and `prob: mcub` reports the minimal-cut-set upper bound \u2014 tighter than the rare-event default. `EXT` is an **undeveloped event** (diamond) that is declared but referenced by no gate, so it is noted as unconnected in the diagram description. Switching the heater to `state: 0` would prune the over-pressure branch entirely and make the top event unsatisfiable."
|
|
970
|
+
},
|
|
971
|
+
{
|
|
972
|
+
"slug": "faulttree-water-overheating",
|
|
973
|
+
"diagram": "faulttree",
|
|
974
|
+
"title": "Water overheating (classic textbook tree)",
|
|
975
|
+
"description": "The canonical introductory fault tree \u2014 an OR top over an AND sub-fault and an OR no-voltage branch, with a probability on every basic event. A faithful, quantified reproduction of the standard worked example.",
|
|
976
|
+
"standard": "NUREG-0492 / IEC 61025",
|
|
977
|
+
"tags": [
|
|
978
|
+
"faulttree",
|
|
979
|
+
"fta",
|
|
980
|
+
"and-or",
|
|
981
|
+
"cut-sets",
|
|
982
|
+
"probability",
|
|
983
|
+
"textbook"
|
|
984
|
+
],
|
|
985
|
+
"complexity": 2,
|
|
986
|
+
"featured": false,
|
|
987
|
+
"dsl": 'faulttree "Water overheating"\n analysis: cutsets, probability\n top T "Water overheating" = OR(F, E, G)\n gate F "Circuit failure and no warning lamp" = AND(A, B)\n gate G "No voltage at input" = OR(C, D)\n basic E "Booster failure" p: 0.02\n basic A "Chip failure" p: 0.05\n basic B "Warning lamp burned" p: 0.03\n basic C "No burn in network" p: 0.12\n basic D "Fuse blown" p: 0.23',
|
|
988
|
+
"notes": "## What this shows\n\nThe fault tree every reliability course opens with, rendered with computed cut sets. The top event **OR**s three branches: an **AND** sub-fault `F` (a circuit failure *and* a dead warning lamp must coincide), a direct booster failure `E`, and an **OR** no-voltage branch `G`.\n\nThe minimal cut sets mix orders: `{E}`, `{C}`, `{D}` are order-1 **single points of failure** (any one trips the top event), while `{A, B}` is order-2 (both the chip and the lamp must fail together). Each is boxed in red, single points of failure in the strongest red, and the top-event probability is computed from the per-event values \u2014 the deductive, quantified reading a fault tree exists to give."
|
|
989
|
+
},
|
|
871
990
|
{
|
|
872
991
|
"slug": "fbd-bottle-counter",
|
|
873
992
|
"diagram": "fbd",
|
|
@@ -2412,6 +2531,25 @@ If the LED doesn't light up, three things to check, in order: LED polarity (the
|
|
|
2412
2531
|
"dsl": 'timeline "Platform v2 Launch"\nconfig: style = gantt\n\n2025-07-01 - 2025-08-15: "Engineering build" [category: "engineering"]\n2025-07-15 - 2025-08-31: "Design polish" [category: "design"]\n2025-08-01 - 2025-09-10: "Marketing collateral" [category: "marketing"]\n2025-08-20: milestone "Feature freeze" [color: #E53935]\n2025-08-20 - 2025-09-05: "QA hardening" [category: "engineering"]\n2025-09-01 - 2025-09-12: "Press embargo outreach" [category: "marketing"]\n2025-09-15: milestone "Public launch" [color: #2E7D32]',
|
|
2413
2532
|
"notes": '## Scenario\n\nThe launch PM shares this in weekly exec status. Overlapping bars show where workstreams parallelize (design polishing while engineering still builds) and the feature-freeze diamond makes the handoff between build and QA unmissable. The second milestone (public launch) anchors the entire timeline and is the reason every other bar exists.\n\n## Annotation key\n\n- `DATE - DATE: "Label"` \u2014 range (bar) event\n- `DATE: milestone "Label"` \u2014 point milestone (diamond)\n- `[category: \u2026]` \u2014 group colour in the gantt legend\n- `[color: #hex]` \u2014 explicit marker colour\n\n## How to read\n\nTime flows left to right. Horizontal bars are continuous work; diamonds are instantaneous events. Overlapping bars mean two teams are working simultaneously \u2014 fine, so long as they coordinate. The red *Feature freeze* marks the transition from net-new work to hardening; any engineering bar extending past it needs an exception. The green *Public launch* is the terminal milestone every other bar is serving.'
|
|
2414
2533
|
},
|
|
2534
|
+
{
|
|
2535
|
+
"slug": "timing-clock-rle-shorthand",
|
|
2536
|
+
"diagram": "timing",
|
|
2537
|
+
"title": "Timing diagram with clock and run-length shorthands",
|
|
2538
|
+
"description": "A synchronous bus-read timing diagram written with the clock and rle shorthands so signals stay aligned without hand-counting wave characters.",
|
|
2539
|
+
"standard": "WaveDrom / IEEE 1497",
|
|
2540
|
+
"tags": [
|
|
2541
|
+
"clock",
|
|
2542
|
+
"run-length",
|
|
2543
|
+
"rle",
|
|
2544
|
+
"WaveDrom",
|
|
2545
|
+
"synchronous",
|
|
2546
|
+
"bus-read"
|
|
2547
|
+
],
|
|
2548
|
+
"complexity": 1,
|
|
2549
|
+
"featured": false,
|
|
2550
|
+
"dsl": 'timing "Synchronous Bus Read"\nCLK: clock 8\nRST: rle 1*2 0*6\nEN: rle 0*2 1*4 0*2\nDATA: zz====zz data: ["D0","D1","D2","D3"]',
|
|
2551
|
+
"notes": "## Scenario\n\nA digital designer documents an 8-cycle synchronous read. Rather than typing\n`pppppppp` for the clock and counting `0`/`1` runs by hand for reset and enable \u2014\nthe most common source of misaligned waveforms \u2014 the diagram uses the two\nlength-explicit shorthands.\n\n## Annotation key\n\n- **`clock N`** \u2014 a clock generator with `N` periods. `CLK: clock 8` expands to\n `pppppppp`; add `neg` for a negedge clock. No character-counting.\n- **`rle <state>*<count> \u2026`** \u2014 run-length segments. `RST: rle 1*2 0*6` expands to\n `11000000`; `EN: rle 0*2 1*4 0*2` expands to `00111100`. Every signal's total\n cell count is explicit, so the waves line up.\n- **raw wave string** \u2014 `DATA: zz====zz` keeps per-cell control where it matters;\n `data: [...]` labels the four `=` bus segments.\n\n## How to read\n\nThe clock runs 8 cycles. Reset is asserted for the first 2 cycles, then drops.\nEnable rises for the middle 4 cycles. The data bus is high-impedance until enable,\nthen presents four stable bytes `D0\u2026D3`, returning to high-Z after. Because\n`clock` and `rle` make each signal exactly 8 cells, the edges align without manual\ncounting."
|
|
2552
|
+
},
|
|
2415
2553
|
{
|
|
2416
2554
|
"slug": "timing-i2c-read-burst",
|
|
2417
2555
|
"diagram": "timing",
|
|
@@ -2450,6 +2588,104 @@ If the LED doesn't light up, three things to check, in order: LED polarity (the
|
|
|
2450
2588
|
"dsl": 'timing "SPI Transaction"\nCLK: pppppppp\nCS_N: 10000001\nMOSI: x======= data: ["0xAB","0xCD","0xEF","0x01","0x02","0x03","0x04","0x05"]\nMISO: zzzz==== data: ["","","","","0xFF","0x12","0x34","0x56"]',
|
|
2451
2589
|
"notes": "## Scenario\n\nA firmware engineer or hardware designer documents an 8-byte SPI master-to-slave transaction for a device driver review or datasheet. The WaveDrom-compatible syntax means the same DSL can be pasted directly into WaveDrom's online editor or embedded in documentation pipelines.\n\n## Annotation key\n\n- `p` \u2014 clock pulse (high period followed by low); each `p` is one clock cycle\n- `1` / `0` \u2014 logic high / logic low\n- `=` \u2014 data bus: stable data (value unchanged from previous cycle)\n- `x` \u2014 don't-care or undefined state (transition state)\n- `z` \u2014 high-impedance (floating / tri-state)\n- `data: [...]` \u2014 optional data labels for each stable segment, rendered inside the bus bar\n- `CS_N` \u2014 active-low chip select; `1` = deselected, `0` = selected\n\n## How to read\n\nThe clock runs for 8 cycles. CS_N goes low at cycle 1 and returns high at cycle 8, framing the transaction. MOSI (master out) sends 8 bytes starting at cycle 1. MISO (slave in) is high-Z for the first 4 cycles (slave preparing the response) then transitions to stable data bytes 5\u20138. The transaction completes when CS_N de-asserts."
|
|
2452
2590
|
},
|
|
2591
|
+
{
|
|
2592
|
+
"slug": "umlclass-generics-mermaid",
|
|
2593
|
+
"diagram": "umlclass",
|
|
2594
|
+
"title": "Generics and Mermaid-compatible syntax",
|
|
2595
|
+
"description": "A generic repository written in Mermaid classDiagram shorthand \u2014 tilde-generics, single-line members, and member classifiers \u2014 all rendered with standard-correct adornments, so a Mermaid snippet migrates in one line.",
|
|
2596
|
+
"standard": "OMG UML 2.5.1 \xA79\u2013\xA711",
|
|
2597
|
+
"tags": [
|
|
2598
|
+
"umlclass",
|
|
2599
|
+
"uml",
|
|
2600
|
+
"mermaid",
|
|
2601
|
+
"generics",
|
|
2602
|
+
"interface",
|
|
2603
|
+
"realization"
|
|
2604
|
+
],
|
|
2605
|
+
"complexity": 2,
|
|
2606
|
+
"featured": false,
|
|
2607
|
+
"dsl": "classDiagram\nclass Repository~T~ {\n +findAll() List~T~\n +findById(id : ID) Optional~T~\n +cache : Map~String,List~int~~\n +count$\n +flush()*\n}\nclass CrudService\nCrudService : <<service>>\nCrudService : +repo : Repository~User~\nCrudService : +save(e : User) User\nRepository~T~ <|.. CrudService",
|
|
2608
|
+
"notes": "## What this shows\n\nThe same diagram a developer would paste from a Mermaid `classDiagram`, rendered with Schematex's standard-correct adornments and layered layout.\n\n**Tilde-generics** convert to angle brackets: `List~T~` \u2192 `List`, and they nest \u2014 `Map~String,List~int~~` \u2192 `Map>`. The generic also works on the class name itself (`class Repository~T~` \u2192 `Repository`).\n\n**Single-line members** append to a class: `CrudService : +repo : Repository~User~` adds an attribute, and `CrudService : <<service>>` sets the stereotype \u2014 no `{ \u2026 }` block required.\n\n**Member classifiers** are the Mermaid suffixes: `flush()*` marks an abstract operation (rendered italic) and `count$` a static member (rendered underlined). Return types may be space-separated (`findAll() List~T~`) the way Mermaid writes them. A lone leading `~` is still the package-visibility glyph, so the two never collide."
|
|
2609
|
+
},
|
|
2610
|
+
{
|
|
2611
|
+
"slug": "umlclass-namespaces",
|
|
2612
|
+
"diagram": "umlclass",
|
|
2613
|
+
"title": "Packages and namespaces",
|
|
2614
|
+
"description": "Group classifiers into labelled containment frames with namespace blocks \u2014 dot-notation auto-creates parent packages, and blocks nest, so a layered architecture reads as nested boxes the way an architect draws it.",
|
|
2615
|
+
"standard": "OMG UML 2.5.1 \xA79\u2013\xA711",
|
|
2616
|
+
"tags": [
|
|
2617
|
+
"umlclass",
|
|
2618
|
+
"uml",
|
|
2619
|
+
"namespace",
|
|
2620
|
+
"package",
|
|
2621
|
+
"architecture",
|
|
2622
|
+
"mermaid"
|
|
2623
|
+
],
|
|
2624
|
+
"complexity": 2,
|
|
2625
|
+
"featured": false,
|
|
2626
|
+
"dsl": 'umlclass\ntitle: "Layered packages"\n\nnamespace Platform {\nnamespace Auth {\nclass UserService {\n + login()\n + logout()\n}\n}\nnamespace Data {\nclass Repository {\n + find()\n + save()\n}\n}\n}\n\nclass Gateway {\n + route()\n}\n\nGateway --> UserService : delegates\nGateway --> Repository : delegates',
|
|
2627
|
+
"notes": '## What this shows\n\nA **`namespace` block** groups its classifiers into a labelled bounding frame. Frames are computed as the **union of their members plus any nested sub-packages**, padded, with a label band on top \u2014 the same C4-style containment Schematex uses for the `network` engine\'s site/zone boundaries. Here `Platform` contains `Auth` and `Data`, each holding one service; `Gateway` lives outside the package and delegates into both.\n\n**Frames never overlap and always enclose.** A package-clustering pass keeps same-package classifiers contiguous within each layout rank, so the frame stays a clean rectangle instead of a ragged shape that swallows unrelated boxes.\n\n**Dot-notation also works.** Writing `namespace Company.Engineering.Backend { \u2026 }` auto-creates `Company` and `Company.Engineering` as parent frames, so you can declare a deep package in one line. An explicit label is available too: `namespace plat["Platform Layer"] { \u2026 }`.'
|
|
2628
|
+
},
|
|
2629
|
+
{
|
|
2630
|
+
"slug": "umlclass-order-model",
|
|
2631
|
+
"diagram": "umlclass",
|
|
2632
|
+
"title": "Order model \u2014 aggregation, composition, and dependency",
|
|
2633
|
+
"description": "A small domain model that exercises every relationship-end adornment that confuses first-time UML readers \u2014 filled diamond for composition, hollow diamond for aggregation, plain association, and a dashed dependency.",
|
|
2634
|
+
"standard": "OMG UML 2.5.1 \xA711.5 (Associations)",
|
|
2635
|
+
"tags": [
|
|
2636
|
+
"umlclass",
|
|
2637
|
+
"uml",
|
|
2638
|
+
"composition",
|
|
2639
|
+
"aggregation",
|
|
2640
|
+
"dependency",
|
|
2641
|
+
"multiplicity",
|
|
2642
|
+
"static",
|
|
2643
|
+
"derived"
|
|
2644
|
+
],
|
|
2645
|
+
"complexity": 2,
|
|
2646
|
+
"featured": true,
|
|
2647
|
+
"dsl": 'umlclass\ntitle: "Order model"\n\nclass Order {\n - id : String\n + total : Money {readOnly}\n + place() : void\n + count : int {static}\n}\n\nclass LineItem {\n + qty : int\n + subtotal() : Money\n}\n\nclass Customer {\n + name : String\n}\n\nclass Address {\n + city : String\n}\n\nclass TaxPolicy {\n + rate(c : Country) : Percent\n}\n\nOrder *-- "1..*" LineItem : contains\nCustomer o-- "0..*" Address : has\nCustomer "1" -- "*" Order : places\nOrder ..> TaxPolicy : uses',
|
|
2648
|
+
"notes": "## Why the diamonds are not interchangeable\n\nUML's two diamond shapes encode genuinely different lifetime semantics, and they're the single most-confused pair on the notation.\n\n**Composition** (filled diamond) means *the part dies with the whole*: when an `Order` is deleted, its `LineItem`s are deleted with it \u2014 the line items have no independent existence. The filled diamond sits at the `Order` (whole) end of `*--`, regardless of which id the author typed first.\n\n**Aggregation** (hollow diamond) means *the part outlives the whole*: an `Address` exists in its own right and a `Customer` aggregating it is just a structural reference \u2014 deleting the customer should not delete the address.\n\n**Plain association** (no diamond) is just \"these two types are structurally linked\" \u2014 the line carries multiplicity (`1` \u2194 `*`) and a name (`places`) but makes no claim about ownership.\n\n**Dependency** (dashed + open arrow) says `Order` *uses* `TaxPolicy` without holding a reference to it \u2014 typically a method parameter or a transient call. The dashed line distinguishes a using-relationship from a structural one at a glance.\n\nThe `{readOnly}`, `{static}`, and `{abstract}` property strings render as the standard UML annotations; `count` is underlined to mark it as class-scope."
|
|
2649
|
+
},
|
|
2650
|
+
{
|
|
2651
|
+
"slug": "umlclass-payment-strategy",
|
|
2652
|
+
"diagram": "umlclass",
|
|
2653
|
+
"title": "Payment strategy pattern with enum + custom stereotype",
|
|
2654
|
+
"description": "The Strategy pattern as a UML class diagram \u2014 a payment service depending on an interface that three concrete strategies realize, plus an enumeration for the supported methods and a custom \xABservice\xBB stereotype.",
|
|
2655
|
+
"standard": "OMG UML 2.5.1 \xA79\u2013\xA711",
|
|
2656
|
+
"tags": [
|
|
2657
|
+
"umlclass",
|
|
2658
|
+
"uml",
|
|
2659
|
+
"strategy-pattern",
|
|
2660
|
+
"interface",
|
|
2661
|
+
"enum",
|
|
2662
|
+
"stereotype",
|
|
2663
|
+
"dependency"
|
|
2664
|
+
],
|
|
2665
|
+
"complexity": 2,
|
|
2666
|
+
"featured": false,
|
|
2667
|
+
"dsl": 'umlclass\ntitle: "Payment strategy"\n\n\xABenumeration\xBB PaymentMethod {\n CARD\n BANK_TRANSFER\n WALLET\n}\n\n\xABinterface\xBB PaymentStrategy {\n + authorize(amount : Money) : AuthResult\n + capture(auth : AuthResult) : Receipt\n}\n\n\xABservice\xBB class CheckoutService {\n - strategies : Map<PaymentMethod, PaymentStrategy>\n + pay(method : PaymentMethod, amount : Money) : Receipt\n}\n\nclass CardStrategy { + authorize(amount : Money) : AuthResult + capture(auth : AuthResult) : Receipt }\nclass BankStrategy { + authorize(amount : Money) : AuthResult + capture(auth : AuthResult) : Receipt }\nclass WalletStrategy { + authorize(amount : Money) : AuthResult + capture(auth : AuthResult) : Receipt }\n\nPaymentStrategy <|.. CardStrategy\nPaymentStrategy <|.. BankStrategy\nPaymentStrategy <|.. WalletStrategy\n\nCheckoutService ..> PaymentStrategy : delegates to\nCheckoutService ..> PaymentMethod : selects by',
|
|
2668
|
+
"notes": "## Reading the diagram\n\nThe Strategy pattern is one of the canonical Gang-of-Four examples and is almost always introduced as a UML class diagram for a reason: a single picture says exactly what an interface-based design buys you.\n\n**`\xABenumeration\xBB` and `\xABservice\xBB` are both stereotypes.** The enum keyword is a standard UML stereotype that swaps the rendering: literals sit in the attribute compartment without visibility glyphs, and there's no operations compartment populated. The `\xABservice\xBB` keyword on `CheckoutService` is a *custom* stereotype \u2014 any guillemet-wrapped word above a class name. Custom stereotypes are how teams tag classifiers with their architectural role (`\xABservice\xBB`, `\xABcontroller\xBB`, `\xABentity\xBB`, `\xABrepository\xBB`) without inventing new visual primitives.\n\n**Realization vs dependency at a glance.** The three concrete strategies *realize* the interface \u2014 dashed line, hollow triangle, drawn three times pointing at the same interface (a future render pass may merge the triangle heads into a single shared head). The `CheckoutService`'s relationship is a *dependency* \u2014 it uses both `PaymentStrategy` and `PaymentMethod` through its public API but does not commit to a structural containment. The dashed-line-with-open-arrow encoding makes the using-relationship visible without implying ownership.\n\nThe `Map` attribute type renders inline as text \u2014 generic type *names* are part of v0.1; parameterised classifier *boxes* (`List`) are deferred."
|
|
2669
|
+
},
|
|
2670
|
+
{
|
|
2671
|
+
"slug": "umlclass-shape-hierarchy",
|
|
2672
|
+
"diagram": "umlclass",
|
|
2673
|
+
"title": "Shape class hierarchy with an interface",
|
|
2674
|
+
"description": "The canonical UML 2.5.1 class diagram \u2014 an interface, an abstract base class, and two concrete leaves \u2014 showing generalization, realization, and a generalization-driven layered layout where parents float to the top.",
|
|
2675
|
+
"standard": "OMG UML 2.5.1 \xA79\u2013\xA711",
|
|
2676
|
+
"tags": [
|
|
2677
|
+
"umlclass",
|
|
2678
|
+
"uml",
|
|
2679
|
+
"generalization",
|
|
2680
|
+
"realization",
|
|
2681
|
+
"interface",
|
|
2682
|
+
"abstract-class"
|
|
2683
|
+
],
|
|
2684
|
+
"complexity": 1,
|
|
2685
|
+
"featured": true,
|
|
2686
|
+
"dsl": 'umlclass\ntitle: "Shape hierarchy"\n\n\xABinterface\xBB Shape {\n + area() : double\n + perimeter() : double\n}\n\nabstract class AbstractShape {\n # name : String\n + area() : double {abstract}\n + perimeter() : double {abstract}\n + describe() : String\n}\n\nclass Circle {\n + radius : double\n + area() : double\n + perimeter() : double\n}\n\nclass Square {\n + side : double\n + area() : double\n + perimeter() : double\n}\n\nShape <|.. AbstractShape\nAbstractShape <|-- Circle\nAbstractShape <|-- Square',
|
|
2687
|
+
"notes": "## What this shows\n\nThe smallest diagram that exercises the three notations every UML primer covers in the first hour: an **interface** (rendered with the `\xABinterface\xBB` keyword), an **abstract class** (rendered in *italics*, with an abstract `area()` operation also in italics), and two concrete leaves.\n\n**Layering is generalization-driven.** Inheritance edges (`<|--`) and realization edges (`<|..`) define the rank hierarchy, so the interface floats to the very top, the abstract base sits below it, and the two concrete classes anchor the bottom \u2014 without any author-side layout hints. This is the visual default a UML textbook expects, and it's why a class diagram should not ride a generic flowchart layout.\n\n**Adornments carry the semantics.** Realization is dashed + hollow triangle; generalization is solid + hollow triangle. The two distinctions render identically in `theme: monochrome` because the meaning is in the shape, not the colour \u2014 exactly the point of UML 2.5.1."
|
|
2688
|
+
},
|
|
2453
2689
|
{
|
|
2454
2690
|
"slug": "usecase-atm",
|
|
2455
2691
|
"diagram": "usecase",
|
|
@@ -2547,7 +2783,7 @@ var SYNTAX = {
|
|
|
2547
2783
|
},
|
|
2548
2784
|
"timing": {
|
|
2549
2785
|
"title": "Timing diagram",
|
|
2550
|
-
"content": '## 1. Your first timing diagram\n\nThe smallest useful timing diagram: a clock and one data signal
|
|
2786
|
+
"content": '## 1. Your first timing diagram\n\nThe smallest useful timing diagram: a clock and one data signal. The friendliest way to write it avoids counting characters entirely:\n\n```\ntiming\nCLK: clock 8\nRST: rle 1*2 0*6\nDATA: 0011==00 data: ["A","B"]\n```\n\nThree rules cover 80% of usage:\n\n1. Start with the keyword `timing`, optionally followed by a quoted title and `[hscale: N]`.\n2. Each signal is one line: `NAME: <wave>` \u2014 name, colon, then the waveform. The waveform can be:\n - **`clock N`** \u2014 a clock generator with `N` periods (add `neg` for a negedge clock). No character-counting.\n - **`rle <state>*<count> \u2026`** \u2014 run-length segments, e.g. `rle 1*2 0*6` = `11000000`. Auto-aligns length.\n - **a raw WaveDrom wave string** \u2014 a contiguous run of state characters (no internal spaces) for fine control.\n3. Add `data: ["val1", "val2"]` after a raw wave string to label bus segments.\n\n> **Tip for alignment:** the #1 cause of a broken timing diagram is signals of unequal length. `clock N` and `rle` make every signal\'s cell count explicit, so they line up. Use raw wave strings only when you need per-cell control.\n\n> Comments must start with `#` on their own line.\n\n---\n\n## 2. Wave characters\n\nThe wave string is a sequence of characters, one per time period. The parser accepts these:\n\n| Character | State | Meaning |\n|---|---|---|\n| `0` | Logic low | Signal at GND / VSS |\n| `1` | Logic high | Signal at VDD |\n| `x` | Unknown | Don\'t-care, undefined, or uninitialized |\n| `z` | High-Z | Tri-state / high-impedance |\n| `p` | Clock pulse (positive) | Rising-edge-active clock; one `p` = one full period (low\u2192high\u2192low) |\n| `P` | Clock pulse (positive, tall) | Same as `p`, visually taller |\n| `n` | Clock pulse (negative) | Falling-edge-active; one `n` = one full period (high\u2192low\u2192high) |\n| `N` | Clock pulse (negative, tall) | Same as `n`, visually taller |\n| `=` | Bus data | Parallel-bus segment; add labels via `data: [\u2026]` |\n| `2`\u2013`9` | Named bus segment | Same as `=`, indexed into `data: [\u2026]` by position |\n| `.` | Hold / continue | Extend the previous state for one more period |\n| `h` / `H` | Hold high | Force-high for this period |\n| `l` / `L` | Hold low | Force-low for this period |\n| `u` | Rising edge | Diagonal from low to high (transition only) |\n| `d` / `D` | Falling edge | Diagonal from high to low (transition only) |\n\n```\ntiming "Wave character reference"\nclk: pppppppppp\nhigh: 1111111111\nlow: 0000000000\nunkn: xxxxxxxxxx\nhiz: zzzzzzzzzz\nbus: x========x data: ["ADDR","DATA","","","","","",""]\nhold: 0..1..0..1\nrise: 0u1\nfall: 1d0\n```\n\n---\n\n## 3. Data labels\n\nWhen a signal carries a bus value, tag the wave with `data: ["label1", "label2", \u2026]`. Each non-empty quoted string is placed inside the corresponding `=` (or `2`\u2013`9`) segment.\n\n```\nMOSI: x======= data: ["0xAB","0xCD","0xEF","0x01","0x02","0x03","0x04","0x05"]\n```\n\nEmpty strings `""` leave a segment unlabeled (useful for segments that extend a previous value).\n\n```\nMISO: zzzz==== data: ["","","","","0xFF","0x12","0x34","0x56"]\n# first four z-periods have no label; four = segments get labels starting at 0xFF\n```\n\n```\ntiming "I2C read burst"\nSCL: ppppppppppp\nSDA: x1=======1x data: ["ADDR+R","ACK","D0","D1","D2","D3","D4","D5","NACK"]\n```\n\n---\n\n## 4. Grouping signals\n\nWrap related signals in a `[GroupName]` block. A `---` line closes the group and also acts as a visual separator between groups.\n\n```\n[Control]\nCLK: pppppppp\nCS_N: 10000001\n---\n[Data]\nMOSI: x======= data: ["0xAB","0xCD","0xEF","0x01","0x02","0x03","0x04","0x05"]\nMISO: zzzz==== data: ["","","","","0xFF","0x12","0x34","0x56"]\n```\n\nAlternative `group "name" { \u2026 }` syntax is also accepted (closing `}` closes the group).\n\n```\ntiming "UART frame"\n[Clock & control]\nCLK: pppppppppppp\nTX_EN: 0111111110\n---\n[Data lines]\nTX: 1========== data: ["START","D0","D1","D2","D3","D4","D5","D6","D7","STOP"]\nRX: zz1=======1 data: ["","","D0","D1","D2","D3","D4","D5","D6","D7"]\n```\n\n---\n\n## 5. Title and hscale\n\n**Title:** `timing "SPI Transaction"` \u2014 appears at the top of the diagram.\n\n**hscale:** `timing "title" [hscale: 2]` \u2014 scales the width of each time period. Default is 1. Use 2 for wider periods when data labels need more room.\n\n```\ntiming "Wide bus" [hscale: 2]\nCLK: pppp\nDATA: ==== data: ["long label here","another","third","fourth"]\n```\n\n---\n\n## 6. Labels & comments\n\n- **Signal name:** anything before the first `:` on a signal line. Names with spaces are fine \u2014 the colon is the delimiter.\n- **Data labels:** `data: ["a", "b"]` after the wave string.\n- **Title:** first token after `timing` keyword, quoted.\n- **Comments:** `#` at the start of a line (after leading whitespace).\n\n```\ntiming "Demo"\n# this is a comment\nCLK: pppp # \u2190 inline trailing comment is NOT supported\n```\n\n---\n\n## 7. Common mistakes\n\n| You wrote | Parser says | Fix |\n|---|---|---|\n| `CLK: p p p p` (spaces in wave) | Wave string parsed as `p` only; the rest is treated as data clause | Remove spaces: `CLK: pppp` |\n| `DATA: =====` with no `data:` | Segments render as unlabeled bus cells | Add `data: ["A","B","C","D","E"]` |\n| Wave character `s` or `r` | `TimingParseError: Invalid wave string` | Only the characters listed in \xA72 are valid |\n| `CLK pppp` (no colon) | Line does not match signal pattern; silently skipped | The colon after the signal name is required |\n| `data: [A, B, C]` (unquoted) | Values not recognized \u2014 parser looks for `"\u2026"` | Quote each value: `data: ["A","B","C"]` |\n| `[Group Name with spaces]` | Group label is `Group Name with spaces` \u2014 parsed fine | Supported |\n| `hscale: 2` on its own line | Not recognized (hscale goes on the header line) | `timing "title" [hscale: 2]` |\n\n---\n\n## 8. Grammar (EBNF)\n\n```text\ndocument = header (blank | comment | group-open | group-close | separator | signal)*\n\nheader = "timing" ( WS quoted-string )? ( WS "[" "hscale:" number "]" )? NEWLINE\nquoted-string = \'"\' any-char-but-quote* \'"\'\n\ngroup-open = "[" label "]" NEWLINE\n | "group" WS quoted-string WS "{"? NEWLINE\ngroup-close = "}" NEWLINE\nseparator = "---" NEWLINE\n\nsignal = name ":" WS wave-string ( WS data-clause )? NEWLINE\nname = any text before the first ":"\nwave-string = wave-char+\nwave-char = "0"|"1"|"x"|"z"\n | "p"|"P"|"n"|"N"\n | "h"|"H"|"l"|"L"\n | "u"|"d"|"D"\n | "="|"."|"2"|"3"|"4"|"5"|"6"|"7"|"8"|"9"\n\ndata-clause = "data:" WS ( "[" quoted-string ("," quoted-string)* "]"\n | quoted-string+ )\n\ncomment = "#" any NEWLINE\n```\n\nAuthoritative source: `src/diagrams/timing/parser.ts`. If this diverges from the parser, the parser wins \u2014 please open an issue.\n\n---'
|
|
2551
2787
|
},
|
|
2552
2788
|
"logic": {
|
|
2553
2789
|
"title": "Logic gate diagram",
|
|
@@ -2555,7 +2791,7 @@ var SYNTAX = {
|
|
|
2555
2791
|
},
|
|
2556
2792
|
"circuit": {
|
|
2557
2793
|
"title": "Circuit schematic",
|
|
2558
|
-
"content": '## 1. A minimal circuit\n\nThe smallest useful positional circuit: a voltage source, a resistor, and a ground.\n\n```\ncircuit "Voltage divider"\nV1: voltage_source down value="5V"\nwire right\nR1: resistor right value="10k"\nwire right\nground\n```\n\nFour rules cover 80% of positional-mode usage:\n\n1. Start with the keyword `circuit`, optionally followed by a quoted title.\n2. Each component is `id: type direction` \u2014 or just `type direction` for anonymous components.\n3. Each component\'s output end becomes the starting point for the next component (the "cursor").\n4. `at: id.end` (or `at: id.start`) jumps the cursor to any named anchor \u2014 use this to branch.\n\n> Comments must start with `#` on their own line.\n\n---\n\n## 2. Components\n\n### 2.1 Positional mode syntax\n\nA named component line has the form:\n\n```\nid: type direction [value="\u2026"] [label="\u2026"]\n```\n\nAn anonymous component omits the `id:` prefix \u2014 the parser assigns an auto ID.\n\n```\nR1: resistor right value="4.7k" label="R1"\ncapacitor down value="100n"\n```\n\n**Direction** is one of `right` (default), `left`, `up`, `down`. It controls which way the component extends from the current cursor position.\n\n### 2.2 Passive components\n\n| DSL type | Description |\n|---|---|\n| `resistor` | Zigzag (ANSI) or rectangle (IEC) |\n| `potentiometer` | Resistor + wiper arrow, 3-pin |\n| `rheostat` | 2-pin variable resistor |\n| `thermistor_ntc` | NTC thermistor (also: `therm`, `ntc`) |\n| `thermistor_ptc` | PTC thermistor (also: `ptc`) |\n| `ldr` | Light-dependent resistor |\n| `varistor` | Voltage-dependent resistor |\n| `fuse` | Standard fuse |\n| `fuse_slow` | Slow-blow fuse (`T` designation) |\n| `capacitor` | Non-polar capacitor |\n| `electrolytic_cap` | Polar/electrolytic capacitor (also: `ecap`) |\n| `variable_cap` | Variable capacitor |\n| `inductor` | Air-core inductor |\n| `inductor_iron` | Iron-core inductor |\n| `inductor_ferrite` | Ferrite-core inductor |\n| `variable_inductor` | Variable inductor |\n| `ferrite_bead` | EMI ferrite bead |\n| `crystal` | Quartz crystal oscillator (also: `xtal`) |\n| `transformer` | Coupled coils (also: `xfmr`) |\n\n```\ncircuit "Passive components gallery"\n# Row 1: resistor \u2192 capacitor \u2192 inductor\nR1: resistor right value="1k"\nwire right\nC1: capacitor right value="100n"\nwire right\nL1: inductor right value="10u"\n# Row 2: crystal and transformer, offset below\nat: R1.start\nwire down\nwire down\nX1: crystal right\nwire right\nwire right\nT1: transformer right\n```\n\n### 2.3 Sources and power\n\n| DSL type | Description |\n|---|---|\n| `voltage_source` | Circle + polarity (also: `vsource`) |\n| `current_source` | Circle + arrow (also: `isource`) |\n| `ac_source` | Circle + sine symbol (also: `acsource`) |\n| `battery` | Alternating long/short terminal lines |\n| `vcc` | Power rail arrow (pointing up) |\n| `ground` | Earth ground \u2014 3 decreasing lines (also: `gnd`) |\n| `gnd_signal` | Signal ground \u2014 solid triangle |\n| `gnd_chassis` | Chassis ground |\n| `gnd_digital` | Digital ground |\n\n```\ncircuit "Sources and power gallery"\n# voltage source with ground\nV1: voltage_source down value="5V"\nwire down\nground\nat: V1.start\nwire right\nwire right\n# battery\nB1: battery down value="9V"\nwire down\nground\nat: B1.start\nwire right\nwire right\n# ac source\nA1: ac_source down value="120V"\nwire down\nground\nat: A1.start\nwire right\nwire right\n# vcc rail\nvcc up\nwire down\ngnd_signal down\n```\n\n### 2.4 Semiconductors \u2014 diodes\n\n| DSL type | Description |\n|---|---|\n| `diode` | Triangle + cathode bar |\n| `zener` | Diode + bent cathode bar |\n| `schottky` | Diode + S-bar |\n| `led` | Diode + outward emission arrows |\n| `photodiode` | Diode + inward light arrows |\n| `varactor` | Diode + variable capacitor |\n| `tvs_diode` | Bidirectional TVS (two bent bars) |\n| `bridge_rectifier` | 4-diode bridge, 4-pin |\n\n```\ncircuit "Diode types gallery"\nD1: diode right\nwire right\nD2: zener right\nwire right\nD3: led right\nwire right\nD4: schottky right\nwire right\nD5: photodiode right\nwire right\nground\nat: D1.start\nwire left\nground\n```\n\n### 2.5 Semiconductors \u2014 transistors\n\n| DSL type | Description |\n|---|---|\n| `npn` | NPN BJT (also: `transistor`, `bjt_npn`) |\n| `pnp` | PNP BJT (also: `bjt_pnp`) |\n| `darlington_npn` | NPN Darlington pair |\n| `darlington_pnp` | PNP Darlington pair |\n| `nmos` | N-channel MOSFET enhancement (also: `mosfet_n`) |\n| `pmos` | P-channel MOSFET enhancement (also: `mosfet_p`) |\n| `nmos_depletion` | N-channel MOSFET depletion |\n| `jfet_n` | N-channel JFET |\n| `jfet_p` | P-channel JFET |\n| `igbt` | IGBT |\n| `scr` | SCR / thyristor |\n| `triac` | TRIAC |\n| `diac` | DIAC |\n| `phototransistor` | NPN with light arrows |\n| `optocoupler` | LED + phototransistor in isolation box |\n\n```\ncircuit "Transistor types gallery"\n# NPN BJT\nQ1: npn right\nwire right\nwire right\n# PNP BJT\nQ2: pnp right\nwire right\nwire right\n# N-channel MOSFET\nQ3: nmos right\nwire right\nwire right\n# P-channel MOSFET\nQ4: pmos right\n```\n\n### 2.6 Analog ICs and op-amps\n\n| DSL type | Description |\n|---|---|\n| `opamp` | Triangle: +/\u2212 inputs, output |\n| `comparator` | Same shape, open-collector output |\n| `schmitt_buffer` | Buffer + hysteresis symbol |\n| `tri_state_buffer` | Buffer + enable pin |\n| `instrumentation_amp` | Three-op-amp INA block |\n| `generic_ic` | Configurable rect with labeled pins (also: `ic`) |\n| `voltage_regulator` | 3-terminal block: IN/GND/OUT (also: `reg`) |\n| `dc_dc_converter` | 2-port block with DC/DC label |\n| `555_timer` | 8-pin 555 pinout block (also: `timer555`) |\n\n```\ncircuit "Analog IC gallery"\n# op-amp with input/output wires\nwire right\nU1: opamp right\nwire right\nwire right\nwire right\n# comparator\nU2: comparator right\nwire right\nwire right\nwire right\n# generic IC block\nU3: generic_ic right\n```\n\n### 2.7 Switches and relays\n\n| DSL type | Description |\n|---|---|\n| `switch_spst` | Single-pole single-throw |\n| `switch_spdt` | Single-pole double-throw |\n| `switch_dpdt` | Double-pole double-throw |\n| `push_no` | Push button normally-open |\n| `push_nc` | Push button normally-closed |\n| `relay_coil` | Relay coil (2-pin rect) |\n| `relay_no` | Relay contact normally-open |\n| `relay_nc` | Relay contact normally-closed |\n\n```\ncircuit "Switch and relay gallery"\n# SPST switch\nS1: switch_spst right\nwire right\nwire right\n# SPDT switch\nS2: switch_spdt right\nwire right\nwire right\n# normally-open push button\nS3: push_no right\nwire right\nwire right\n# relay coil + contact pair\nK1: relay_coil right\nwire right\nK2: relay_no right\n```\n\n### 2.8 Electromechanical and measurement\n\n| DSL type | Description |\n|---|---|\n| `motor` | Circle + M |\n| `speaker` | Cone + box |\n| `microphone` | Capsule symbol |\n| `buzzer` | Piezo buzzer |\n| `ammeter` | Circle + A |\n| `voltmeter` | Circle + V |\n| `wattmeter` | Circle + W |\n| `oscilloscope` | Circle + waveform |\n\n### 2.9 Connectors and annotations\n\n| DSL type | Description |\n|---|---|\n| `wire` | Plain wire segment |\n| `dot` | Junction dot (T-junction marker) |\n| `label` | Net label / flag |\n| `port` | Named port (hollow circle) |\n| `test_point` | TP marker |\n| `no_connect` | X \u2014 intentionally unconnected pin |\n| `antenna` | Antenna stub |\n\n```\ncircuit "Passive components"\nR1: resistor right value="1k" label="R1"\nwire right\nC1: capacitor down value="100n" label="C1"\nwire down\nground\nat: R1.start\nwire up\nbattery up label="9V"\n```\n\n---\n\n## 3. Wiring and branching\n\n### 3.1 Wire segments\n\n`wire direction [N]` draws a bare wire from the current cursor in the given direction. An optional number sets the length in pixels.\n\n```\nwire right\nwire down 40\nwire left 20\n```\n\n### 3.2 Jumping the cursor with `at:`\n\n`at: id.end` moves the cursor to a named anchor without drawing anything. Use it to branch from a previously placed component.\n\n```\nR1: resistor right value="10k"\nat: R1.end\nC1: capacitor down value="100n"\n```\n\nNamed anchor suffixes: `end`, `start`. Components retain their ID across the whole diagram, so you can jump back to any previously placed component.\n\n### 3.3 Junction dots\n\nPlace a `dot` (or use `net NAME: dot`) to mark a T-junction \u2014 a point where three or more wires meet. Without a dot, crossed wires are drawn as a crossover (no connection).\n\n```\nR1: resistor right\ndot\nwire right # continues from R1.end\nat: R1.end\nC1: capacitor down # branches down from the same point\n```\n\n### 3.4 Named nets\n\n`net NAME` declares a named net. `net NAME: dot` declares the net and places a junction dot at the current cursor, remembering that location. Later, `at: NAME` jumps back to that net\'s anchor.\n\n```\nnet VOUT: dot\nR2: resistor right value="10k"\nat: VOUT\nC1: capacitor down value="470n"\n```\n\n### 3.5 Net labels\n\n`label "text" direction?` places a text label at the current cursor position. Labels do not advance the cursor. They are useful for naming power rails or inter-sheet connections.\n\n```\nlabel "VCC" up\nlabel "GND" down\n```\n\n```\ncircuit "RC filter"\nV1: voltage_source down value="5V"\nwire right\nR1: resistor right value="1k" label="R1"\nnet OUT: dot\nwire right\nlabel "Vout" right\nat: OUT\nC1: capacitor down value="100n" label="C1"\nwire down\nground\n```\n\n---\n\n## 4. Netlist mode\n\nAdd `netlist` after the title on the header line to switch to SPICE-style netlist parsing. The auto-layout engine computes component positions from the net connectivity.\n\n```\ncircuit "Low-pass filter" netlist\n```\n\n### 4.1 Netlist line format\n\nEach line is: `ID net1 net2 [net3\u2026] [value] [key=value\u2026]`\n\n- **ID** \u2014 component identifier. The first letter determines the default type (SPICE prefix convention).\n- **net1, net2, \u2026** \u2014 net names the pins connect to. Net names matching `0`, `gnd`, `ground`, `earth`, `pe`, `agnd`, `dgnd`, `gnda`, `gndd`, `vss`, or `com` (case-insensitive, with optional `_<word>` or numeric suffix \u2014 e.g. `gnd_ref`, `AGND_DIG`, `EARTH1`) all canonicalize to the ground net.\n- **value** (optional bare token) \u2014 component value or model name.\n- **key=value** (optional) \u2014 `label=`, `value=`, `type=` overrides.\n\n### 4.2 SPICE prefix \u2192 component type\n\n| Prefix | Default type | Pin order |\n|---|---|---|\n| `R` | `resistor` | p1, p2 |\n| `C` | `capacitor` | p1, p2 |\n| `L` | `inductor` | p1, p2 |\n| `D` | `diode` | anode (start), cathode (end) |\n| `V` | `voltage_source` | plus, minus |\n| `I` | `current_source` | plus, minus |\n| `Q` | `npn` | c, b, e |\n| `M` | `nmos` | d, g, s |\n| `J` | `jfet_n` | d, g, s |\n| `S` | `switch_spst` | p1, p2 |\n| `F` | `fuse` | p1, p2 |\n| `B` | `battery` | plus, minus |\n| `K` | `relay_coil` | p1, p2 |\n| `U`, `X` | `generic_ic` | custom via `pins=` |\n| `W` | `wire` | start, end |\n| `T` | `terminal_block` | custom via `pins=` (also `type=junction_box`) |\n\n> **Scope:** schematex circuit covers **electrical schematics only** (IEEE 315 / IEC 60617). Hydraulic and pneumatic schematics (ISO 1219) use a fundamentally different visual grammar \u2014 directional valve envelopes, cylinder symbols, line styles for pressure/return/drain \u2014 and are not supported by this engine. Hydraulic prefixes such as `EV*` (electrovalve), `BOMBA*` (pump), `TANK*`, `DIPOSIT*` will be rejected with a "cannot infer type" error.\n\n### 4.3 Transistor model override\n\nFor `Q` lines, a trailing model name overrides the type:\n\n```\nQ1 c b e npn # NPN BJT\nQ2 c b e pnp # PNP BJT\nM1 d g s nmos # N-channel MOSFET\nM2 d g s pmos # P-channel MOSFET\n```\n\nFor `D` lines, similarly:\n\n```\nD1 anode cathode zener\nD2 anode cathode led\nD3 anode cathode schottky\nD4 anode cathode photodiode\n```\n\n### 4.4 Netlist example\n\n```\ncircuit "CE Amp (netlist)" netlist\nV1 vcc 0 9V\nRc vcc c 2.2k\nRb vcc b 100k\nQ1 c b e npn\nRe e 0 1k\n```\n\n---\n\n## 5. Attributes\n\nBoth positional and netlist modes accept these key=value attributes:\n\n| Attribute | Accepted by | Effect |\n|---|---|---|\n| `label="\u2026"` | all components | Display label (reference designator) |\n| `value="\u2026"` | all components | Value annotation (1k\u03A9, 100nF, 5V) |\n| `at=id.end` | positional components | Start this component at a named anchor |\n| `length=N` | `wire`, some passives | Length in pixels |\n\nIn positional mode, `at=` inside the component line is equivalent to a preceding `at:` line:\n\n```\nC1: capacitor down at=R1.end value="100n"\n```\n\n---\n\n## 6. Labels & comments\n\n- **Diagram title:** `circuit "RC Filter"` \u2014 first line only.\n- **Component label:** `label="R1"` attribute \u2014 reference designator shown beside the symbol.\n- **Value annotation:** `value="4.7k"` \u2014 shown beside or below the component.\n- **Net label:** `label "VOUT" right` \u2014 standalone net flag at the current cursor.\n- **Comments:** `#` at the start of a line (after leading whitespace).\n\n---\n\n## 7. Reserved words & escaping\n\n**Reserved at line start (positional):** `circuit` (header), `at:`, `net`, `wire`, `label`.\n\n**Reserved in netlist mode:** same header rules apply; all other lines are SPICE component lines.\n\n**Ground net aliases (netlist only):** `0`, `gnd`, `GND`, `Gnd`, `ground`, `Ground` \u2014 all treated as the same node.\n\n**Component IDs** must match `[a-zA-Z_][a-zA-Z0-9_]*`. Spaces in values must be quoted: `value="10 k\u03A9"`.\n\n---\n\n## 8. Common mistakes\n\n| You wrote | Parser says | Fix |\n|---|---|---|\n| `resistor right 1k` (bare value without `value=`) | `1k` is parsed as an unknown attribute flag and ignored | Use `value="1k"`: `resistor right value="1k"` |\n| `at: R1.center` | `center` is not a recognized anchor suffix \u2014 cursor stays at current position | Use `at: R1.end` or `at: R1.start` |\n| `wire 40` (no direction) | Direction defaults to `right`; length `40` is accepted | Explicit direction recommended: `wire right 40` |\n| `R1 vcc out 10k` in positional mode | Line matches the bare-type pattern; `R1` is read as a type name, fails lookup | In positional mode, use `R1: resistor right value="10k"` |\n| `Q1 c b e` (netlist, no model) | Type defaults to `npn` from `Q` prefix \u2014 correct | OK; add `npn` explicitly for clarity |\n| `net OUT` then `at: OUT` without `net OUT: dot` | `OUT` net exists but has no anchor; jump has no destination | Use `net OUT: dot` to register the cursor position |\n| `label VCC up` (unquoted label) | `VCC` is parsed as a direction token, then `up` \u2014 the label text is lost | Quote the text: `label "VCC" up` |\n\n---\n\n## 9. Grammar (EBNF)\n\n```text\ndocument = header statement*\n\n-- Positional mode --\nheader = "circuit" ( WS quoted-string )? NEWLINE\nstatement = blank | comment | component | wire | at | net-decl | label-stmt\n\ncomponent = ( id ":" WS )? type WS direction? attrs* NEWLINE\nwire = "wire" ( WS direction )? ( WS integer )? NEWLINE\nat = "at:" WS anchor NEWLINE\nanchor = id "." ( "start" | "end" )\n | id // net name anchor\n\nnet-decl = "net" WS id NEWLINE // declare net only\n | "net" WS id ":" WS "dot" NEWLINE // declare + place dot\n\nlabel-stmt = "label" WS quoted-string ( WS direction )? NEWLINE\n\ncomponent-attr = "value=" quoted-string\n | "label=" quoted-string\n | "at=" anchor\n | "length=" integer\n\ndirection = "right" | "left" | "up" | "down"\ntype = // any value from \xA72 component tables\n\n-- Netlist mode --\nnetlist-header = "circuit" ( WS quoted-string )? WS "netlist" NEWLINE\nnetlist-stmt = id WS net-ref+ ( WS kv-pair )* NEWLINE\n | comment\nnet-ref = id | "0" // net name or ground alias\nkv-pair = id "=" ( quoted-string | bare-value )\n\nid = [a-zA-Z_] [a-zA-Z0-9_]*\ninteger = [0-9]+\nquoted-string = \'"\' any-char-but-quote* \'"\'\ncomment = "#" any NEWLINE\n```\n\nAuthoritative source: `src/diagrams/circuit/parser.ts` and `src/diagrams/circuit/netlist.ts`. If this diverges from the parser, the parser wins \u2014 please open an issue.\n\n---'
|
|
2794
|
+
"content": '## 1. A minimal circuit (netlist mode \u2014 recommended)\n\nThe smallest useful circuit: a voltage source, a resistor, and a capacitor to ground \u2014 an RC low-pass filter.\n\n```\ncircuit "RC Low-Pass" netlist\nV1 in 0 5V\nR1 in out 1k\nC1 out 0 100n\n```\n\nThree rules cover ~90% of netlist usage:\n\n1. Start with `circuit "Title" netlist` (the `netlist` keyword switches on this mode).\n2. Each line is `componentId nodeA nodeB value` \u2014 one component, the two (or more) named nodes it connects to, then its value.\n3. **Two components that share a node name are wired together.** `0`, `gnd`, or `GND` is the ground net (a ground symbol is drawn automatically).\n\nThe component-id prefix sets the symbol: `R*`\u2192resistor, `C*`\u2192capacitor, `L*`\u2192inductor, `V*`\u2192voltage source, `D*`\u2192diode, `Q*`\u2192BJT. When the prefix is ambiguous, add `type=` (e.g. `X1 a b type=opamp`). You never compute coordinates \u2014 the engine derives placement from the connectivity.\n\n> Comments must start with `#` on their own line.\n\n---\n\n## 2. Components\n\n### 2.1 Netlist mode syntax\n\nA netlist line has the form:\n\n```\ncomponentId node... [value] [type=\u2026] [label="\u2026"]\n```\n\nThe positional nodes come first; a trailing token that doesn\'t look like a node becomes the value. Example \u2014 a transistor (4 nodes) and a resistor:\n\n```\nQ1 c b e npn # collector, base, emitter nodes + model\nRc vcc c 2.2k # two nodes + value\n```\n\n**Optional orientation hint.** The engine auto-orients symbols by role (sources up, ground down, the rest horizontal). To nudge a single symbol, add `dir=right|left|up|down` \u2014 connectivity is unchanged, only the symbol\'s facing rotates:\n\n```\nC1 out 0 100n dir=down # draw C1 as a shunt cap hanging to ground\n```\n\nThis is the lightweight layout-control layer (like Lcapy\'s per-component orientation): netlist connectivity does the heavy lifting, `dir=` only refines appearance. For full geometric control, use positional mode below.\n\n### 2.2 Positional mode syntax (hand-drawing)\n\n> Positional mode is for manually laying out a schematic geometrically. **Prefer netlist mode for generated output** \u2014 positional mode requires tracking a moving "cursor" across lines, which is error-prone for LLMs.\n\nA named component line has the form:\n\n```\nid: type direction [value="\u2026"] [label="\u2026"]\n```\n\nAn anonymous component omits the `id:` prefix \u2014 the parser assigns an auto ID.\n\n```\nR1: resistor right value="4.7k" label="R1"\ncapacitor down value="100n"\n```\n\n**Direction** is one of `right` (default), `left`, `up`, `down`. It controls which way the component extends from the current cursor position.\n\n### 2.3 Passive components\n\n| DSL type | Description |\n|---|---|\n| `resistor` | Zigzag (ANSI) or rectangle (IEC) |\n| `potentiometer` | Resistor + wiper arrow, 3-pin |\n| `rheostat` | 2-pin variable resistor |\n| `thermistor_ntc` | NTC thermistor (also: `therm`, `ntc`) |\n| `thermistor_ptc` | PTC thermistor (also: `ptc`) |\n| `ldr` | Light-dependent resistor |\n| `varistor` | Voltage-dependent resistor |\n| `fuse` | Standard fuse |\n| `fuse_slow` | Slow-blow fuse (`T` designation) |\n| `capacitor` | Non-polar capacitor |\n| `electrolytic_cap` | Polar/electrolytic capacitor (also: `ecap`) |\n| `variable_cap` | Variable capacitor |\n| `inductor` | Air-core inductor |\n| `inductor_iron` | Iron-core inductor |\n| `inductor_ferrite` | Ferrite-core inductor |\n| `variable_inductor` | Variable inductor |\n| `ferrite_bead` | EMI ferrite bead |\n| `crystal` | Quartz crystal oscillator (also: `xtal`) |\n| `transformer` | Coupled coils (also: `xfmr`) |\n\n```\ncircuit "Passive components gallery"\n# Row 1: resistor \u2192 capacitor \u2192 inductor\nR1: resistor right value="1k"\nwire right\nC1: capacitor right value="100n"\nwire right\nL1: inductor right value="10u"\n# Row 2: crystal and transformer, offset below\nat: R1.start\nwire down\nwire down\nX1: crystal right\nwire right\nwire right\nT1: transformer right\n```\n\n### 2.4 Sources and power\n\n| DSL type | Description |\n|---|---|\n| `voltage_source` | Circle + polarity (also: `vsource`) |\n| `current_source` | Circle + arrow (also: `isource`) |\n| `ac_source` | Circle + sine symbol (also: `acsource`) |\n| `battery` | Alternating long/short terminal lines |\n| `vcc` | Power rail arrow (pointing up) |\n| `ground` | Earth ground \u2014 3 decreasing lines (also: `gnd`) |\n| `gnd_signal` | Signal ground \u2014 solid triangle |\n| `gnd_chassis` | Chassis ground |\n| `gnd_digital` | Digital ground |\n\n```\ncircuit "Sources and power gallery"\n# voltage source with ground\nV1: voltage_source down value="5V"\nwire down\nground\nat: V1.start\nwire right\nwire right\n# battery\nB1: battery down value="9V"\nwire down\nground\nat: B1.start\nwire right\nwire right\n# ac source\nA1: ac_source down value="120V"\nwire down\nground\nat: A1.start\nwire right\nwire right\n# vcc rail\nvcc up\nwire down\ngnd_signal down\n```\n\n### 2.5 Semiconductors \u2014 diodes\n\n| DSL type | Description |\n|---|---|\n| `diode` | Triangle + cathode bar |\n| `zener` | Diode + bent cathode bar |\n| `schottky` | Diode + S-bar |\n| `led` | Diode + outward emission arrows |\n| `photodiode` | Diode + inward light arrows |\n| `varactor` | Diode + variable capacitor |\n| `tvs_diode` | Bidirectional TVS (two bent bars) |\n| `bridge_rectifier` | 4-diode bridge, 4-pin |\n\n```\ncircuit "Diode types gallery"\nD1: diode right\nwire right\nD2: zener right\nwire right\nD3: led right\nwire right\nD4: schottky right\nwire right\nD5: photodiode right\nwire right\nground\nat: D1.start\nwire left\nground\n```\n\n### 2.6 Semiconductors \u2014 transistors\n\n| DSL type | Description |\n|---|---|\n| `npn` | NPN BJT (also: `transistor`, `bjt_npn`) |\n| `pnp` | PNP BJT (also: `bjt_pnp`) |\n| `darlington_npn` | NPN Darlington pair |\n| `darlington_pnp` | PNP Darlington pair |\n| `nmos` | N-channel MOSFET enhancement (also: `mosfet_n`) |\n| `pmos` | P-channel MOSFET enhancement (also: `mosfet_p`) |\n| `nmos_depletion` | N-channel MOSFET depletion |\n| `jfet_n` | N-channel JFET |\n| `jfet_p` | P-channel JFET |\n| `igbt` | IGBT |\n| `scr` | SCR / thyristor |\n| `triac` | TRIAC |\n| `diac` | DIAC |\n| `phototransistor` | NPN with light arrows |\n| `optocoupler` | LED + phototransistor in isolation box |\n\n```\ncircuit "Transistor types gallery"\n# NPN BJT\nQ1: npn right\nwire right\nwire right\n# PNP BJT\nQ2: pnp right\nwire right\nwire right\n# N-channel MOSFET\nQ3: nmos right\nwire right\nwire right\n# P-channel MOSFET\nQ4: pmos right\n```\n\n### 2.7 Analog ICs and op-amps\n\n| DSL type | Description |\n|---|---|\n| `opamp` | Triangle: +/\u2212 inputs, output |\n| `comparator` | Same shape, open-collector output |\n| `schmitt_buffer` | Buffer + hysteresis symbol |\n| `tri_state_buffer` | Buffer + enable pin |\n| `instrumentation_amp` | Three-op-amp INA block |\n| `generic_ic` | Configurable rect with labeled pins (also: `ic`) |\n| `voltage_regulator` | 3-terminal block: IN/GND/OUT (also: `reg`) |\n| `dc_dc_converter` | 2-port block with DC/DC label |\n| `555_timer` | 8-pin 555 pinout block (also: `timer555`) |\n\n```\ncircuit "Analog IC gallery"\n# op-amp with input/output wires\nwire right\nU1: opamp right\nwire right\nwire right\nwire right\n# comparator\nU2: comparator right\nwire right\nwire right\nwire right\n# generic IC block\nU3: generic_ic right\n```\n\n### 2.8 Switches and relays\n\n| DSL type | Description |\n|---|---|\n| `switch_spst` | Single-pole single-throw |\n| `switch_spdt` | Single-pole double-throw |\n| `switch_dpdt` | Double-pole double-throw |\n| `push_no` | Push button normally-open |\n| `push_nc` | Push button normally-closed |\n| `relay_coil` | Relay coil (2-pin rect) |\n| `relay_no` | Relay contact normally-open |\n| `relay_nc` | Relay contact normally-closed |\n\n```\ncircuit "Switch and relay gallery"\n# SPST switch\nS1: switch_spst right\nwire right\nwire right\n# SPDT switch\nS2: switch_spdt right\nwire right\nwire right\n# normally-open push button\nS3: push_no right\nwire right\nwire right\n# relay coil + contact pair\nK1: relay_coil right\nwire right\nK2: relay_no right\n```\n\n### 2.9 Electromechanical and measurement\n\n| DSL type | Description |\n|---|---|\n| `motor` | Circle + M |\n| `speaker` | Cone + box |\n| `microphone` | Capsule symbol |\n| `buzzer` | Piezo buzzer |\n| `ammeter` | Circle + A |\n| `voltmeter` | Circle + V |\n| `wattmeter` | Circle + W |\n| `oscilloscope` | Circle + waveform |\n\n### 2.10 Connectors and annotations\n\n| DSL type | Description |\n|---|---|\n| `wire` | Plain wire segment |\n| `dot` | Junction dot (T-junction marker) |\n| `label` | Net label / flag |\n| `port` | Named port (hollow circle) |\n| `test_point` | TP marker |\n| `no_connect` | X \u2014 intentionally unconnected pin |\n| `antenna` | Antenna stub |\n\n```\ncircuit "Passive components"\nR1: resistor right value="1k" label="R1"\nwire right\nC1: capacitor down value="100n" label="C1"\nwire down\nground\nat: R1.start\nwire up\nbattery up label="9V"\n```\n\n---\n\n## 3. Wiring and branching\n\n### 3.1 Wire segments\n\n`wire direction [N]` draws a bare wire from the current cursor in the given direction. An optional number sets the length in pixels.\n\n```\nwire right\nwire down 40\nwire left 20\n```\n\n### 3.2 Jumping the cursor with `at:`\n\n`at: id.end` moves the cursor to a named anchor without drawing anything. Use it to branch from a previously placed component.\n\n```\nR1: resistor right value="10k"\nat: R1.end\nC1: capacitor down value="100n"\n```\n\nNamed anchor suffixes: `end`, `start`. Components retain their ID across the whole diagram, so you can jump back to any previously placed component.\n\n### 3.3 Junction dots\n\nPlace a `dot` (or use `net NAME: dot`) to mark a T-junction \u2014 a point where three or more wires meet. Without a dot, crossed wires are drawn as a crossover (no connection).\n\n```\nR1: resistor right\ndot\nwire right # continues from R1.end\nat: R1.end\nC1: capacitor down # branches down from the same point\n```\n\n### 3.4 Named nets\n\n`net NAME` declares a named net. `net NAME: dot` declares the net and places a junction dot at the current cursor, remembering that location. Later, `at: NAME` jumps back to that net\'s anchor.\n\n```\nnet VOUT: dot\nR2: resistor right value="10k"\nat: VOUT\nC1: capacitor down value="470n"\n```\n\n### 3.5 Net labels\n\n`label "text" direction?` places a text label at the current cursor position. Labels do not advance the cursor. They are useful for naming power rails or inter-sheet connections.\n\n```\nlabel "VCC" up\nlabel "GND" down\n```\n\n```\ncircuit "RC filter"\nV1: voltage_source down value="5V"\nwire right\nR1: resistor right value="1k" label="R1"\nnet OUT: dot\nwire right\nlabel "Vout" right\nat: OUT\nC1: capacitor down value="100n" label="C1"\nwire down\nground\n```\n\n---\n\n## 4. Netlist mode\n\nAdd `netlist` after the title on the header line to switch to SPICE-style netlist parsing. The auto-layout engine computes component positions from the net connectivity.\n\n```\ncircuit "Low-pass filter" netlist\n```\n\n### 4.1 Netlist line format\n\nEach line is: `ID net1 net2 [net3\u2026] [value] [key=value\u2026]`\n\n- **ID** \u2014 component identifier. The first letter determines the default type (SPICE prefix convention).\n- **net1, net2, \u2026** \u2014 net names the pins connect to. Net names matching `0`, `gnd`, `ground`, `earth`, `pe`, `agnd`, `dgnd`, `gnda`, `gndd`, `vss`, or `com` (case-insensitive, with optional `_<word>` or numeric suffix \u2014 e.g. `gnd_ref`, `AGND_DIG`, `EARTH1`) all canonicalize to the ground net.\n- **value** (optional bare token) \u2014 component value or model name.\n- **key=value** (optional) \u2014 `label=`, `value=`, `type=` overrides.\n\n### 4.2 SPICE prefix \u2192 component type\n\n| Prefix | Default type | Pin order |\n|---|---|---|\n| `R` | `resistor` | p1, p2 |\n| `C` | `capacitor` | p1, p2 |\n| `L` | `inductor` | p1, p2 |\n| `D` | `diode` | anode (start), cathode (end) |\n| `V` | `voltage_source` | plus, minus |\n| `I` | `current_source` | plus, minus |\n| `Q` | `npn` | c, b, e |\n| `M` | `nmos` | d, g, s |\n| `J` | `jfet_n` | d, g, s |\n| `S` | `switch_spst` | p1, p2 |\n| `F` | `fuse` | p1, p2 |\n| `B` | `battery` | plus, minus |\n| `K` | `relay_coil` | p1, p2 |\n| `U`, `X` | `generic_ic` | custom via `pins=` |\n| `W` | `wire` | start, end |\n| `T` | `terminal_block` | custom via `pins=` (also `type=junction_box`) |\n\n> **Scope:** schematex circuit covers **electrical schematics only** (IEEE 315 / IEC 60617). Hydraulic and pneumatic schematics (ISO 1219) use a fundamentally different visual grammar \u2014 directional valve envelopes, cylinder symbols, line styles for pressure/return/drain \u2014 and are not supported by this engine. Hydraulic prefixes such as `EV*` (electrovalve), `BOMBA*` (pump), `TANK*`, `DIPOSIT*` will be rejected with a "cannot infer type" error.\n\n### 4.3 Transistor model override\n\nFor `Q` lines, a trailing model name overrides the type:\n\n```\nQ1 c b e npn # NPN BJT\nQ2 c b e pnp # PNP BJT\nM1 d g s nmos # N-channel MOSFET\nM2 d g s pmos # P-channel MOSFET\n```\n\nFor `D` lines, similarly:\n\n```\nD1 anode cathode zener\nD2 anode cathode led\nD3 anode cathode schottky\nD4 anode cathode photodiode\n```\n\n### 4.4 Netlist example\n\n```\ncircuit "CE Amp (netlist)" netlist\nV1 vcc 0 9V\nRc vcc c 2.2k\nRb vcc b 100k\nQ1 c b e npn\nRe e 0 1k\n```\n\n---\n\n## 5. Attributes\n\nBoth positional and netlist modes accept these key=value attributes:\n\n| Attribute | Accepted by | Effect |\n|---|---|---|\n| `label="\u2026"` | all components | Display label (reference designator) |\n| `value="\u2026"` | all components | Value annotation (1k\u03A9, 100nF, 5V) |\n| `at=id.end` | positional components | Start this component at a named anchor |\n| `length=N` | `wire`, some passives | Length in pixels |\n\nIn positional mode, `at=` inside the component line is equivalent to a preceding `at:` line:\n\n```\nC1: capacitor down at=R1.end value="100n"\n```\n\n---\n\n## 6. Labels & comments\n\n- **Diagram title:** `circuit "RC Filter"` \u2014 first line only.\n- **Component label:** `label="R1"` attribute \u2014 reference designator shown beside the symbol.\n- **Value annotation:** `value="4.7k"` \u2014 shown beside or below the component.\n- **Net label:** `label "VOUT" right` \u2014 standalone net flag at the current cursor.\n- **Comments:** `#` at the start of a line (after leading whitespace).\n\n---\n\n## 7. Reserved words & escaping\n\n**Reserved at line start (positional):** `circuit` (header), `at:`, `net`, `wire`, `label`.\n\n**Reserved in netlist mode:** same header rules apply; all other lines are SPICE component lines.\n\n**Ground net aliases (netlist only):** `0`, `gnd`, `GND`, `Gnd`, `ground`, `Ground` \u2014 all treated as the same node.\n\n**Component IDs** must match `[a-zA-Z_][a-zA-Z0-9_]*`. Spaces in values must be quoted: `value="10 k\u03A9"`.\n\n---\n\n## 8. Common mistakes\n\n| You wrote | Parser says | Fix |\n|---|---|---|\n| `resistor right 1k` (bare value without `value=`) | `1k` is parsed as an unknown attribute flag and ignored | Use `value="1k"`: `resistor right value="1k"` |\n| `at: R1.center` | `center` is not a recognized anchor suffix \u2014 cursor stays at current position | Use `at: R1.end` or `at: R1.start` |\n| `wire 40` (no direction) | Direction defaults to `right`; length `40` is accepted | Explicit direction recommended: `wire right 40` |\n| `R1 vcc out 10k` in positional mode | Line matches the bare-type pattern; `R1` is read as a type name, fails lookup | In positional mode, use `R1: resistor right value="10k"` |\n| `Q1 c b e` (netlist, no model) | Type defaults to `npn` from `Q` prefix \u2014 correct | OK; add `npn` explicitly for clarity |\n| `net OUT` then `at: OUT` without `net OUT: dot` | `OUT` net exists but has no anchor; jump has no destination | Use `net OUT: dot` to register the cursor position |\n| `label VCC up` (unquoted label) | `VCC` is parsed as a direction token, then `up` \u2014 the label text is lost | Quote the text: `label "VCC" up` |\n\n---\n\n## 9. Grammar (EBNF)\n\n```text\ndocument = header statement*\n\n-- Positional mode --\nheader = "circuit" ( WS quoted-string )? NEWLINE\nstatement = blank | comment | component | wire | at | net-decl | label-stmt\n\ncomponent = ( id ":" WS )? type WS direction? attrs* NEWLINE\nwire = "wire" ( WS direction )? ( WS integer )? NEWLINE\nat = "at:" WS anchor NEWLINE\nanchor = id "." ( "start" | "end" )\n | id // net name anchor\n\nnet-decl = "net" WS id NEWLINE // declare net only\n | "net" WS id ":" WS "dot" NEWLINE // declare + place dot\n\nlabel-stmt = "label" WS quoted-string ( WS direction )? NEWLINE\n\ncomponent-attr = "value=" quoted-string\n | "label=" quoted-string\n | "at=" anchor\n | "length=" integer\n\ndirection = "right" | "left" | "up" | "down"\ntype = // any value from \xA72 component tables\n\n-- Netlist mode --\nnetlist-header = "circuit" ( WS quoted-string )? WS "netlist" NEWLINE\nnetlist-stmt = id WS net-ref+ ( WS kv-pair )* NEWLINE\n | comment\nnet-ref = id | "0" // net name or ground alias\nkv-pair = id "=" ( quoted-string | bare-value )\n\nid = [a-zA-Z_] [a-zA-Z0-9_]*\ninteger = [0-9]+\nquoted-string = \'"\' any-char-but-quote* \'"\'\ncomment = "#" any NEWLINE\n```\n\nAuthoritative source: `src/diagrams/circuit/parser.ts` and `src/diagrams/circuit/netlist.ts`. If this diverges from the parser, the parser wins \u2014 please open an issue.\n\n---'
|
|
2559
2795
|
},
|
|
2560
2796
|
"block": {
|
|
2561
2797
|
"title": "Block diagram",
|
|
@@ -2655,7 +2891,15 @@ var SYNTAX = {
|
|
|
2655
2891
|
},
|
|
2656
2892
|
"network": {
|
|
2657
2893
|
"title": "Network Topology",
|
|
2658
|
-
"content": '## 1. Your first diagram\n\
|
|
2894
|
+
"content": '## 1. Your first diagram\n\nA complete network diagram needs only two kinds of line: **device declarations** and **links**. Nothing else is required.\n\n```\nnetwork "Tiny LAN"\nrouter r1 "Edge Router"\nswitch sw1 "Core Switch"\npc pc1 "Workstation"\nr1 -- sw1\nsw1 -- pc1\n```\n\nThat\'s it \u2014 a valid, laid-out diagram. Just two rules:\n\n- `<kind> <id> ["label"]` \u2014 a typed device. The kind picks the icon.\n- `<a> -- <b>` \u2014 an undirected link between two declared devices.\n\n**Everything else is optional and additive \u2014 but not all of it is equal.** Two cheap, high-value structural hints are worth adding whenever hierarchy matters: `layout:` (tiered/tree/star/ring/bus/mesh/spine-leaf) and `tier:` (edge/core/distribution/access). They drive a readable top-down hierarchy at almost no syntax cost:\n\n```\nnetwork "Branch"\n layout: tiered\n router r1 "Edge Router" tier: edge\n l3switch core1 "Core SW" tier: core\n switch acc1 "Access SW" tier: access\n pc pc1 "Workstation"\n r1 -- core1\n core1 -- acc1\n acc1 -- pc1\n```\n\nBy contrast, the **per-link annotations** \u2014 link types (`fiber`/`wireless`/`poe`\u2026), speeds, `vlan:`, `port:`, `trunk`/`access`, and `subnet { }` boundaries \u2014 don\'t affect layout and are where generation most often breaks. Add them only when the request calls for them. Rule of thumb: keep the structural hints, drop the decorative annotations unless asked.\n\nDevices are **not** auto-declared from links \u2014 an undeclared id can\'t be safely typed, so a link to an unknown device is a readable error. Use `;` to put several statements on one line, and `a b c : kind` shorthand to declare several same-kind devices at once.\n\nOnce the skeleton works, you can layer on direction and annotations \u2014 `->` is a directed link, `==` is a LAG, and anything after `:` is the link spec:\n\n```\nnetwork "Home"\n layout: star\n router gw "Gateway"\n pc pc1\n laptop lt1\n gw -- pc1\n gw -- lt1 : wireless\n```\n\n---\n\n## 2. Device kinds\n\nPick the kind that matches the box; the icon follows the Cisco-convention silhouette.\n\n- **Infrastructure** \u2014 `router`, `switch`, `l3switch`, `firewall`, `loadbalancer`, `ap`, `wlc`, `gateway`, `modem`, `ids`, `proxy`, `vpngw`\n- **Endpoints** \u2014 `server`, `serverfarm` (`count: n`), `pc`, `laptop`, `mobile`, `ipphone`, `printer`, `storage`\n- **CCTV / security** \u2014 `camera` (with `type: fixed | bullet | dome | ptz | turret`), `nvr`, `dvr`, `poeswitch`, `encoder`, `monitor`\n- **Clouds** \u2014 `internet`, `wan`, `pstn`, `cloud`, plus `lan` (a bus bar)\n\nAliases are accepted: `multilayer`\u2192`l3switch`, `workstation`\u2192`pc`, `wifi`\u2192`ap`, `nas`/`san`\u2192`storage`, `voip`\u2192`ipphone`.\n\n```\ncamera cam1 type: dome ip: 192.168.20.11\nserverfarm farm "Server Farm" count: 4\nl3switch core1 tier: core model: "C9500"\n```\n\n---\n\n## 3. Links & annotations\n\nA link\'s appearance follows its type; everything after `:` is order-free.\n\n```\na -- b # copper / ethernet (default solid)\na -- b : fiber 10G # fiber \u2014 orange with slash ticks\na -- b : wireless # dashed\na -- b : serial # leased / WAN circuit\na -- b : poe # Power-over-Ethernet (green + tag)\na -- b : vpn "site-to-site" # dashed tunnel\na == b : lag 40G # aggregated / EtherChannel (double line)\na -- b : trunk vlan: 10,20 1G port: Gi0/1>Gi1/0/24\n```\n\n- `trunk` / `access` \u2014 port mode (a trunk should connect switch-class devices).\n- `vlan: 10` or `vlan: 10,20` \u2014 a single VLAN tints the link (skipping the reserved alarm-red).\n- `1G` / `10G` / `100M` / `40G` \u2014 speed, shown mid-link.\n- `port: near>far` \u2014 interface labels at each end.\n\n---\n\n## 4. Layout modes\n\n```\nlayout: tiered # default \u2014 band by tier: edge \u2192 core \u2192 distribution \u2192 access\nlayout: tree # hierarchical from the root\nlayout: star # hub at center, spokes on a ring\nlayout: ring # nodes on a circle\nlayout: bus # shared backbone\nlayout: mesh # full/partial mesh on a circle\nlayout: spine-leaf # two rows, every leaf auto-meshed to every spine\nlayout: manual # explicit at: x,y per device\ndirection: tb | lr # flow axis for tiered/tree\n```\n\nFor `tiered`, set `tier:` (`edge` / `core` / `distribution` / `access`) on infrastructure; untiered endpoints are placed below their switch. For `spine-leaf`, declare `spines:` and `leaves:` and the spine\u2194leaf links are generated for you.\n\n---\n\n## 5. Boundaries: sites, racks, subnets, VLANs\n\nA device can live inside nested boundary blocks. **Physical** containers (site/rack) draw a solid border; **logical** overlays (subnet/VLAN/zone/DMZ) draw a dashed tinted region.\n\n```\nnetwork "Branch"\n site hq "HQ Building" {\n rack mdf "MDF Rack" {\n firewall fw1 tier: edge\n l3switch core1 tier: core\n }\n }\n subnet lan "10.0.10.0/24" {\n switch a1 tier: access\n pc u1 "User PC" ip: 10.0.10.50\n }\n zone dmz "DMZ" {\n server web\n }\n fw1 -- core1 : 10G\n core1 -- a1 : trunk vlan: 10\n a1 -- u1\n```\n\nA device declared inside a `subnet` whose label is a CIDR has its `ip:` validated \u2014 an address outside the range is a readable error. A bare id on its own line inside a block adds an already-declared device to that group.\n\n---\n\n## 6. Validation & the no-drop guarantee\n\nThe engine guarantees every declared device and link renders \u2014 the dropped-device failure of generic tools is structurally impossible. It also checks:\n\n- **duplicate id** \u2192 error;\n- **unknown kind** \u2192 error with the nearest suggestion (`"swtich" \u2192 did you mean "switch"?`);\n- **link to an undeclared device** \u2192 error;\n- **VLAN id outside 1\u20134094** \u2192 warning (still renders);\n- **device IP outside its subnet CIDR** \u2192 error.\n\nThe SVG `<desc>` records device/link counts, the detected topology class (star / ring / bus / mesh / tree / hierarchical / spine-leaf), and any warnings.\n\n---\n\n## 7. Themes\n\n```\ntheme: default # house "network blue" Cisco-style bodies\ntheme: monochrome # clean line-art for print/audit (link meaning via line-style + tags)\ntheme: dark # Catppuccin Mocha\n```\n\nCJK labels and `\u300C\u2026\u300D` / `"\u2026"` quotes parse cleanly:\n\n```\nnetwork "\u529E\u516C\u5BA4"\n multilayer core1 \u300C\u6838\u5FC3\u4EA4\u6362\u673A\u300D\n poeswitch poe1\n camera cam1 type: dome\n core1 -- poe1 : trunk vlan: 10\n poe1 -- cam1 : poe\n```\n\n---'
|
|
2895
|
+
},
|
|
2896
|
+
"umlclass": {
|
|
2897
|
+
"title": "UML Class Diagram",
|
|
2898
|
+
"content": '## 1. Your first diagram\n\nEvery document starts with the `umlclass` keyword (the Mermaid `classDiagram` header is also accepted), then declarations and relationships:\n\n```\numlclass\nclass Account {\n + id : String\n - balance : Money\n + deposit(amount : Money) : void\n}\nclass Customer {\n + name : String\n}\nCustomer "1" o-- "*" Account : owns\n```\n\nA `class X { \u2026 }` block declares a classifier with a name compartment, an attributes compartment, and an operations compartment. Members on their own lines inside the braces; you can also write the body on a single line (`class Account { + id : String + deposit() }`). The header accepts:\n\n- `title: "\u2026"` \u2014 a heading drawn above the diagram.\n- `direction: tb | bt | lr | rl` \u2014 rank direction, default `tb` (parents on top).\n- `theme: \u2026` \u2014 a theme override.\n\n---\n\n## 2. Classifiers\n\n```\nclass Order\n\xABinterface\xBB Repository\n\xABenumeration\xBB Status\nabstract class Shape\ndatatype Money\nprimitive int\n```\n\nThe five classifier kinds are `class`, `interface`, `enum` (alias `enumeration`), `datatype`, and `primitive`. A `\xABstereotype\xBB` (or ASCII `<<stereotype>>`) renders above the name; `abstract class` (or the `{abstract}` annotation) renders the name in italics. Use `as` to give a display name that differs from the reference id: `class "Order Service" as OrderSvc`.\n\n---\n\n## 3. Members \u2014 attributes & operations\n\n```\nclass Account {\n + id : String\n - balance : Money = 0\n / available : Money\n # owner : Customer\n ~ region : String\n + count : int {static}\n + deposit(amount : Money) : void\n + transfer(to : Account, amount : Money) : boolean {query}\n}\n```\n\n- **Visibility** glyphs: `+` public, `-` private, `#` protected, `~` package.\n- `: Type` gives the attribute type or operation return type; `= value` a default; `[0..*]` a multiplicity; `/` a derived attribute.\n- `{\u2026}` annotations: `{static}` (renders underlined), `{abstract}` (italic operation), `{readOnly}`, `{query}`, `{ordered}`, \u2026\n- `name : Type`, `name: Type`, and Java-order `Type name` are all accepted and normalised to `name : Type`.\n\n**Enum literals** are bare names inside an `enum` body:\n\n```\n\xABenumeration\xBB Status {\n ACTIVE\n SUSPENDED\n CLOSED\n}\n```\n\n---\n\n## 4. Relationships\n\n```\nVehicle <|-- Car generalization (hollow triangle \u2192 parent)\nShape <|.. Circle realization (dashed + hollow triangle \u2192 interface)\nOrder *-- LineItem composition (filled diamond at the whole)\nCustomer o-- Address aggregation (hollow diamond at the whole)\nService --> Repository directed association (open arrow \u2192 target)\nService ..> Logger dependency (dashed + open arrow \u2192 supplier)\nA -- B plain association (no head)\n```\n\nReversed forms are accepted and normalised (`Car --|> Vehicle` \u2261 `Vehicle <|-- Car`). Whitespace around a connector is optional.\n\nWhen two or more children share one parent via generalization/realization, the heads are **tree-merged**: one trunk, one shared triangle, per-child legs.\n\n---\n\n## 5. Labels & multiplicity\n\n```\nCustomer "1" o-- "0..*" Order : places\n```\n\nA trailing `: label` names the association (drawn at the line midpoint). Quoted ends are multiplicities or role names: `"1"`, `"0..1"`, `"*"`, `"1..*"`. The source end is the left of the connector, the target end the right (after reversed-form normalisation).\n\n---\n\n## 6. Namespaces / packages\n\nGroup classifiers into a labelled containment frame:\n\n```\numlclass\nnamespace Platform {\n namespace Auth {\n class UserService {\n + login()\n }\n }\n namespace Data {\n class Repository {\n + find()\n }\n }\n}\nclass Gateway {\n + route()\n}\nGateway --> UserService : delegates\nGateway --> Repository : delegates\n```\n\n- Blocks **nest** syntactically. Dot-notation auto-creates parents: `namespace Company.Engineering.Backend { \u2026 }` creates `Company` and `Company.Engineering` too.\n- An explicit label: `namespace plat["Platform Layer"] { \u2026 }`.\n- Each package renders as a frame = the union of its members (and nested sub-frames) + padding + a top label. Namespace bodies must use newlines (one declaration per line).\n\n---\n\n## 7. Mermaid-compatibility forms\n\nFor one-line migration from Mermaid `classDiagram`:\n\n```\nclassDiagram\nclass Repository~T~ {\n + findAll() List~T~\n + cache : Map~String,List~int~~\n + count$\n + flush()*\n}\nRepository : <<service>>\nRepository : + save(e : T) T\n```\n\n- **Tilde-generics** `List~T~` \u2192 `List` (nesting supported: `Map~String,List~int~~` \u2192 `Map>`); also on class names (`class Box~T~`).\n- **Single-line member**: `ClassName : +member` appends a member; `ClassName : <<interface>>` sets the kind/stereotype.\n- **Member classifiers**: trailing `*` = abstract (italic), trailing `$` = static (underlined).\n- **Space-return-type**: `getId() String` needs no colon.\n\nA lone leading `~` is still the package-visibility glyph; tilde-generics only convert balanced `~\u2026~` pairs inside a type, so the two never collide.\n\n---\n\n## 8. Theming & accessibility\n\nAll strokes and fills come from theme tokens (no inline styles); CSS classes are prefixed `sx-umlclass-*`. Visibility renders as text glyphs (`+ - # ~`), never coloured icons \u2014 standard-faithful and monochrome-safe. Every diagram carries `<title>`/`<desc>` and `data-*` attributes (`data-id`, `data-kind`, `data-from`/`data-to`/`data-kind` on relationships, `data-package-id` on frames) for interactivity.'
|
|
2899
|
+
},
|
|
2900
|
+
"faulttree": {
|
|
2901
|
+
"title": "Fault Tree Analysis",
|
|
2902
|
+
"content": '## 1. Your first diagram\n\nEvery document starts with the `faulttree` keyword (alias `fta`), an optional title, then a flat list of declarations wired by id:\n\n```\nfaulttree "Both pumps fail"\n analysis: cutsets, probability\n top T "Both redundant pumps fail" = AND(PA, PB)\n basic PA "Pump A fails" p: 0.01\n basic PB "Pump B fails" p: 0.01\n```\n\n`top` declares the single root event and the gate that produces it; `basic` declares a leaf component failure with a probability. The engine computes the minimal cut set `{PA, PB}` and P(top) = 1.0e-4. The DSL is **flat declaration + reference** (not nested by indentation) \u2014 a fault tree is a DAG, so a shared event is just referenced by id from several gates.\n\nHeader directives:\n\n- `analysis: cutsets, probability` \u2014 what to compute (also `pathsets`, `none`).\n- `prob: rare | mcub | exact` \u2014 the probability method (default `rare`, a conservative upper bound).\n- `layout: tb | bt` \u2014 top-down (default) or bottom-up.\n\n---\n\n## 2. Events\n\n```\ntop T "System fails" = OR(A, B)\ngate G1 "Sub-fault" = AND(A, B)\nbasic A "Component A fails" p: 0.01\nundeveloped EXT "External fire (not modelled)"\nhouse HX "Power on" state: 1\n```\n\n- **`top`** \u2014 the one undesired event being analysed (rectangle, emphasised border). Exactly one is required.\n- **`gate`** \u2014 an intermediate event that is itself a gate output (rectangle).\n- **`basic`** \u2014 a primary component failure, the leaf that carries `p:` (circle).\n- **`undeveloped`** \u2014 an event not developed further (diamond); may carry `p:`.\n- **`house`** \u2014 a normally-expected event forced `state: 0` or `state: 1` (house glyph) \u2014 switches branches of the tree on/off.\n\nProbabilities accept decimals or scientific notation (`p: 0.004` or `p: 1e-6`); `p:` and `prob:` are interchangeable. An event with no probability is treated symbolically (cut sets still computed; P(top) reported as n/a).\n\n---\n\n## 3. Gates\n\n```\ntop T1 = AND(A, B, C) # all inputs occur\ntop T2 = OR(A, B) # at least one input occurs\ntop T3 = XOR(A, B) # exactly one (treated as OR for cut sets)\ntop T4 = VOTING(2/3; A, B, C) # at least k of n\ngate G1 = INHIBIT(A) if COND # A occurs AND the condition holds\ngate G2 = PAND(A, B) order: A, B # A then B (order rendered, AND for cut sets)\n```\n\nGates are drawn **output-up, inputs-down** (the mirror of a `logic` gate): AND is a flat-bottomed dome, OR/XOR/VOTING a shield, INHIBIT a hexagon. The conditioning event of an `INHIBIT`/`PAND` renders as an ellipse to the side. A gate may reference another gate or any event \u2014 and the same basic event may feed several gates (a repeated event).\n\n---\n\n## 4. Computed cut sets & probability\n\nThis is the differentiator. With `analysis: cutsets`, the engine runs **MOCUS**: AND gates grow the order of a cut set, OR gates multiply the number of cut sets, then idempotence (`A\u2227A=A`) and absorption (`X \u2286 Y \u21D2 drop Y`) minimise the result.\n\n- Each **minimal cut set** is boxed in red; an **order-1 cut set is a single point of failure** (strongest red, `data-spof`).\n- A **repeated event** (one basic event under several gates) is handled by absorption \u2014 the case a naive expander gets wrong.\n- **P(top)** is computed from per-event probabilities: `rare` (\u03A3 cut-set probs, default), `mcub` (1 \u2212 \u220F(1\u2212P)), or `exact` (inclusion-exclusion, which correctly de-duplicates a shared event). The method is shown next to the top event and noted in `<desc>`.\n- A `house state: 0` can make the top event unsatisfiable \u2014 reported as "no cut sets."\n\n---\n\n## 5. Repeated events\n\n```\nfaulttree "Safety function fails"\n analysis: cutsets, probability\n prob: exact\n top T "Safety function fails" = OR(C1, C2)\n gate C1 "Channel 1" = AND(S1, L1)\n gate C2 "Channel 2" = AND(S2, L1)\n basic S1 "Sensor 1 fails" p: 0.05\n basic S2 "Sensor 2 fails" p: 0.05\n basic L1 "Shared logic solver fails" p: 0.05\n```\n\n`L1` feeds both channels \u2014 it is drawn once per reference with a shared-event mark, but the cut-set engine treats every instance as one Boolean variable. Cut sets are `{S1, L1}` and `{S2, L1}`; `prob: exact` subtracts the overlap (L1 counted once over the union), giving 0.004875 rather than the rare-event 0.005.\n\n---\n\n## 6. Transfers\n\n```\ngate OVP "Sustained over-pressure" = INHIBIT(PUMP) if HEATER\ntransfer OVP -> "OVP-detail"\n```\n\nA `transfer ID -> "name"` draws the transfer-out triangle below an event whose development lives elsewhere; a matching `transfer "name" = gate_expr` defines that named subtree and is spliced in for cut-set computation. v0.1 resolves transfers in-document.\n\n---\n\n## 7. Validation\n\nThe parser fails fast with readable errors so the cut-set math is meaningful:\n\n- exactly one `top` is required (zero or several is an error);\n- a gate referencing an undeclared id reports the id by name;\n- cycles are rejected (a fault tree is a DAG);\n- a probability outside `[0, 1]`, a `VOTING k/n` with `k > n` or `n \u2260 input count`, or an `if` condition on a non-INHIBIT/PAND gate are all reported in plain English.\n\n---\n\n## 8. Theming\n\n`default` uses the house palette \u2014 soft slate-blue event boxes, **green gates** ("logic proceeds"), **red cut-set boxes** (the computed risk), blue probability numerals, a yellow house. `monochrome` reproduces the NUREG-0492 black-and-white textbook look, where the dome/shield shape (not colour) carries the gate type. All strokes/fills come from `ReliabilityTokens`; every element carries `data-*` (`data-cutset`, `data-spof`, `data-prob`, `data-gate`) so the computed analysis is inspectable downstream.'
|
|
2659
2903
|
}
|
|
2660
2904
|
};
|
|
2661
2905
|
|
|
@@ -2756,29 +3000,56 @@ var PROFILES = {
|
|
|
2756
3000
|
timing: {
|
|
2757
3001
|
type: "timing",
|
|
2758
3002
|
header: 'timing "Title"',
|
|
2759
|
-
mode: "WaveDrom-
|
|
2760
|
-
forms: [
|
|
2761
|
-
|
|
2762
|
-
|
|
2763
|
-
|
|
3003
|
+
mode: "WaveDrom signals, with clock/run-length shorthands",
|
|
3004
|
+
forms: [
|
|
3005
|
+
"CLK: clock 8 (clock generator, 8 periods \u2014 no char-counting)",
|
|
3006
|
+
"RST: rle 1*2 0*6 (run-length: two 1s then six 0s)",
|
|
3007
|
+
'DATA: x====x data: ["A","B"] (raw WaveDrom wave + bus labels)'
|
|
3008
|
+
],
|
|
3009
|
+
prefer: [
|
|
3010
|
+
"Use `clock N` for clocks instead of counting `p` characters.",
|
|
3011
|
+
"Use `rle <state>*<count> ...` for level/data signals instead of counting characters \u2014 it auto-aligns length.",
|
|
3012
|
+
"Drop to a raw wave string only for fine control; keep all signals the same total length so they align.",
|
|
3013
|
+
"Use `data:` labels for bus segments (`=` or digit states)."
|
|
3014
|
+
],
|
|
3015
|
+
avoid: ["Avoid hand-counting long runs of identical characters \u2014 that is the main source of misaligned waves."],
|
|
3016
|
+
repair: [
|
|
3017
|
+
"Wave-state errors name the offending character and list the valid states.",
|
|
3018
|
+
"If two signals don't line up, make their total cell counts equal (clock N and rle make this easy)."
|
|
3019
|
+
]
|
|
2764
3020
|
},
|
|
2765
3021
|
logic: {
|
|
2766
3022
|
type: "logic",
|
|
2767
3023
|
header: 'logic "Title"',
|
|
2768
3024
|
mode: "logic netlist",
|
|
2769
3025
|
forms: ["INPUT A, B", "G1 = AND(A, B)", "OUTPUT Y = G1"],
|
|
2770
|
-
prefer: [
|
|
2771
|
-
|
|
2772
|
-
|
|
3026
|
+
prefer: [
|
|
3027
|
+
"Gate form is `id = TYPE(in1, in2, \u2026)`; declare `INPUT`/`OUTPUT` ports explicitly. Prefix a signal with `~` for active-low.",
|
|
3028
|
+
"Use only these canonical gate TYPEs: combinational AND, OR, NOT, NAND, NOR, XOR, XNOR, BUF; output buffers TRISTATE_BUF, TRISTATE_INV, OPEN_DRAIN, SCHMITT; flip-flops DFF, JKFF, SRFF, TFF; latches LATCH_SR, LATCH_D; complex MUX, DEMUX, DECODER, ENCODER, COUNTER, SHIFT_REG."
|
|
3029
|
+
],
|
|
3030
|
+
avoid: ["Avoid circuit component names (R, C, transistors) inside logic diagrams."],
|
|
3031
|
+
repair: ["An unrecognised gate renders as a flagged `?` placeholder; replace it with the closest canonical gate from the list above (e.g. LOAD/REG \u2192 DFF, INV \u2192 NOT)."]
|
|
2773
3032
|
},
|
|
2774
3033
|
circuit: {
|
|
2775
3034
|
type: "circuit",
|
|
2776
3035
|
header: 'circuit "Title" netlist',
|
|
2777
|
-
mode: "SPICE-style netlist",
|
|
2778
|
-
forms: [
|
|
2779
|
-
|
|
2780
|
-
|
|
2781
|
-
|
|
3036
|
+
mode: "SPICE-style netlist (recommended for generation)",
|
|
3037
|
+
forms: [
|
|
3038
|
+
"V1 in 0 5V (component-id node-A node-B value)",
|
|
3039
|
+
"R1 in out 1k",
|
|
3040
|
+
"C1 out 0 100n"
|
|
3041
|
+
],
|
|
3042
|
+
prefer: [
|
|
3043
|
+
"Always use netlist mode (`... netlist` header). Each line is one component; no spatial state to track.",
|
|
3044
|
+
"Two components that share a node name are wired together. `0`, `gnd`, or `GND` is the ground net.",
|
|
3045
|
+
"The component-id prefix sets the type (R=resistor, C=capacitor, L=inductor, V=source, D=diode, Q=BJT). Add explicit `type=` only when the prefix is ambiguous.",
|
|
3046
|
+
"Optional orientation hint `dir=` (right|left|up|down) nudges a single symbol's facing, e.g. `C1 out 0 100n dir=down` for a shunt cap. Connectivity is unaffected; omit it unless layout readability needs it."
|
|
3047
|
+
],
|
|
3048
|
+
avoid: [
|
|
3049
|
+
"Avoid positional cursor routing (`wire`, `at:`) \u2014 that mode is for hand-drawing, not generation.",
|
|
3050
|
+
"Do not invent coordinates; the layout engine places components from the net connectivity. `dir=` only rotates a symbol, it does not set position."
|
|
3051
|
+
],
|
|
3052
|
+
repair: ["If a component type or pin count is ambiguous, make the symbol type explicit with `type=`."]
|
|
2782
3053
|
},
|
|
2783
3054
|
blockdiagram: {
|
|
2784
3055
|
type: "blockdiagram",
|
|
@@ -2802,10 +3073,14 @@ var PROFILES = {
|
|
|
2802
3073
|
type: "sld",
|
|
2803
3074
|
header: 'sld "Title"',
|
|
2804
3075
|
mode: "equipment assignments + power-flow edges",
|
|
2805
|
-
forms: ['util = utility [label: "Grid"]', 'xfmr = transformer [rating: "500 kVA"]', "util -> xfmr
|
|
2806
|
-
prefer: [
|
|
3076
|
+
forms: ['util = utility [label: "Grid"]', 'xfmr = transformer [rating: "500 kVA"]', "util -> xfmr (one edge per line, no chaining)"],
|
|
3077
|
+
prefer: [
|
|
3078
|
+
"Declare equipment as `id = nodeType [attrs]`, one `from -> to` connection per line.",
|
|
3079
|
+
"Use only these canonical nodeTypes: sources utility, generator, solar, wind, ups; transformers transformer, transformer_dy, transformer_yd, transformer_yy, transformer_dd, autotransformer, transformer_3winding; buses bus, bus_tie, hub; switching breaker, breaker_vacuum, switch, switch_load, ground_switch, ats, recloser, sectionalizer, fuse, fuse_cl; protection ct, pt, relay, surge_arrester, ground_fault; loads motor, load, capacitor_bank, harmonic_filter, vfd; metering watthour_meter, demand_meter.",
|
|
3080
|
+
"IEC/REBT residential aliases are also accepted: mcb/mccb\u2192breaker, rcd/rcbo/rccb\u2192ground_fault, isolator/disconnector\u2192switch_load, panel/consumer_unit/distribution_board\u2192bus."
|
|
3081
|
+
],
|
|
2807
3082
|
avoid: ["Avoid generic flowchart node syntax."],
|
|
2808
|
-
repair: ["
|
|
3083
|
+
repair: ["An unrecognised nodeType renders as a flagged `?` placeholder; pick the closest canonical type or alias from the list above (e.g. meter\u2192watthour_meter, inverter\u2192vfd)."]
|
|
2809
3084
|
},
|
|
2810
3085
|
entity: {
|
|
2811
3086
|
type: "entity",
|
|
@@ -2890,30 +3165,66 @@ var PROFILES = {
|
|
|
2890
3165
|
},
|
|
2891
3166
|
state: {
|
|
2892
3167
|
type: "state",
|
|
2893
|
-
header:
|
|
2894
|
-
mode: "
|
|
2895
|
-
forms: [
|
|
2896
|
-
|
|
2897
|
-
|
|
2898
|
-
|
|
3168
|
+
header: "stateDiagram-v2",
|
|
3169
|
+
mode: "Mermaid stateDiagram-v2 (recommended for generation)",
|
|
3170
|
+
forms: [
|
|
3171
|
+
"[*] --> Idle",
|
|
3172
|
+
"Idle --> Running : start",
|
|
3173
|
+
"Running --> Done : finish",
|
|
3174
|
+
"Done --> [*]"
|
|
3175
|
+
],
|
|
3176
|
+
prefer: [
|
|
3177
|
+
"Use Mermaid `stateDiagram-v2` syntax: `[*]` for the start/end pseudo-states, `-->` for transitions, `: label` for the event/guard.",
|
|
3178
|
+
'This matches the most common training data, so prefer it over the native `state "Title"` + `initial`/`final` form (which is also accepted).'
|
|
3179
|
+
],
|
|
3180
|
+
avoid: [
|
|
3181
|
+
"Avoid composite/concurrent-state syntax until the request needs it.",
|
|
3182
|
+
"Do not mix the two styles in one file (e.g. `[*]` together with `initial X`); pick `[*]`."
|
|
3183
|
+
],
|
|
3184
|
+
repair: [
|
|
3185
|
+
"Every transition uses `-->`; place at least one named state between a `[*]` start and a `[*]` end.",
|
|
3186
|
+
'If the header is rejected, use exactly `stateDiagram-v2` (or `state "Title"`).'
|
|
3187
|
+
]
|
|
2899
3188
|
},
|
|
2900
3189
|
pid: {
|
|
2901
3190
|
type: "pid",
|
|
2902
3191
|
header: 'pid "Title"',
|
|
2903
3192
|
mode: "equipment + process lines",
|
|
2904
|
-
forms: [
|
|
2905
|
-
|
|
2906
|
-
|
|
2907
|
-
|
|
3193
|
+
forms: [
|
|
3194
|
+
"equip T-101 : tank_atm",
|
|
3195
|
+
"equip P-101 : pump_centrifugal",
|
|
3196
|
+
"line L1 from T-101.bottom to P-101.in",
|
|
3197
|
+
"inst FIC-201 : cr_shared"
|
|
3198
|
+
],
|
|
3199
|
+
prefer: [
|
|
3200
|
+
"Declare equipment first (`equip ID : type [attrs]`), then process/signal lines, then instruments (`inst TAG : category`).",
|
|
3201
|
+
"Use only these canonical equipment types: tanks/vessels tank_atm, tank_cone_roof, vessel_v, vessel_h, sphere; columns column_tray, column_packed; heat transfer hx_shell_tube, hx_air_cooled, reboiler, condenser; rotating pump_centrifugal, pump_pd, compressor, blower; reactors reactor_cstr, reactor_pfr; misc filter, cyclone, flare, cooling_tower; valves valve_gate, valve_ball, valve_globe, valve_butterfly, valve_check, valve_control, valve_psv.",
|
|
3202
|
+
"Instrument categories: field_discrete, field_shared, field_computer, field_plc, cr_discrete, cr_shared, cr_computer, cr_plc, local_discrete, local_shared. Line types (`[type: \u2026]`): process, process_minor, pneumatic, electric, hydraulic, capillary, software, mechanical."
|
|
3203
|
+
],
|
|
3204
|
+
avoid: ["Avoid SLD electrical nodes (transformer, breaker) in a P&ID."],
|
|
3205
|
+
repair: ["An unrecognised equipment type renders as a flagged `?` placeholder; pick the closest canonical type from the list above (e.g. exchanger/heat_exchanger\u2192hx_shell_tube, vessel_horizontal\u2192vessel_h, cstr\u2192reactor_cstr)."]
|
|
2908
3206
|
},
|
|
2909
3207
|
erd: {
|
|
2910
3208
|
type: "erd",
|
|
2911
|
-
header: "
|
|
2912
|
-
mode: "
|
|
2913
|
-
forms: [
|
|
2914
|
-
|
|
2915
|
-
|
|
2916
|
-
|
|
3209
|
+
header: "erDiagram",
|
|
3210
|
+
mode: "Mermaid erDiagram (recommended for generation)",
|
|
3211
|
+
forms: [
|
|
3212
|
+
"CUSTOMER ||--o{ ORDER : places",
|
|
3213
|
+
"ORDER {",
|
|
3214
|
+
" int id PK",
|
|
3215
|
+
" string customerId FK",
|
|
3216
|
+
"}"
|
|
3217
|
+
],
|
|
3218
|
+
prefer: [
|
|
3219
|
+
"Use Mermaid `erDiagram` syntax: relationships `A <card>--<card> B : label` with crow's-foot glyphs (`||` one, `o{` zero-or-many, `|{` one-or-many, `|o` zero-or-one); entity blocks `NAME { type name KEY }` with attributes **type-first** and KEY \u2208 PK/FK/UK.",
|
|
3220
|
+
"Entities are auto-created from relationships; you only need a `{ \u2026 }` block to list attributes.",
|
|
3221
|
+
"This matches the dominant training-data prior. The native `erd` header with `table NAME { name type PK }` + `ref \u2026 many-mandatory -- one-mandatory \u2026` is also accepted."
|
|
3222
|
+
],
|
|
3223
|
+
avoid: ["Do not mix the two header styles; under `erDiagram`, attributes are type-first (`int id PK`), not name-first."],
|
|
3224
|
+
repair: [
|
|
3225
|
+
"Crow's-foot glyph pairs must be valid (`||`, `|o`, `}o`, `}|` on the left; `||`, `o|`, `o{`, `|{` on the right).",
|
|
3226
|
+
"If the header is rejected, use exactly `erDiagram` (or native `erd`)."
|
|
3227
|
+
]
|
|
2917
3228
|
},
|
|
2918
3229
|
breadboard: {
|
|
2919
3230
|
type: "breadboard",
|
|
@@ -2980,12 +3291,25 @@ var PROFILES = {
|
|
|
2980
3291
|
},
|
|
2981
3292
|
sequence: {
|
|
2982
3293
|
type: "sequence",
|
|
2983
|
-
header:
|
|
2984
|
-
mode: "
|
|
2985
|
-
forms: [
|
|
2986
|
-
|
|
2987
|
-
|
|
2988
|
-
|
|
3294
|
+
header: "sequenceDiagram",
|
|
3295
|
+
mode: "Mermaid sequenceDiagram (recommended for generation)",
|
|
3296
|
+
forms: [
|
|
3297
|
+
"participant Alice",
|
|
3298
|
+
"participant Bob",
|
|
3299
|
+
"Alice->>Bob: request",
|
|
3300
|
+
"Bob-->>Alice: response",
|
|
3301
|
+
"Note over Alice,Bob: handshake"
|
|
3302
|
+
],
|
|
3303
|
+
prefer: [
|
|
3304
|
+
"Use Mermaid `sequenceDiagram` syntax: `->>` is a sync call, `-->>` a reply/return, `-)` async; `participant`/`actor`, `Note over A,B:`, and `loop`/`alt`/`opt`/`par \u2026 end` all work.",
|
|
3305
|
+
'This matches the dominant training-data prior; the native `sequence "Title"` header (where `->>` means async) is also accepted.',
|
|
3306
|
+
"Add combined fragments only when control flow matters."
|
|
3307
|
+
],
|
|
3308
|
+
avoid: ["Do not mix the two header styles; pick `sequenceDiagram` and keep Mermaid arrow meanings throughout."],
|
|
3309
|
+
repair: [
|
|
3310
|
+
"Every fragment (`loop`/`alt`/`opt`/`par`/`break`/`critical`) needs a matching `end`; `else` only inside `alt`.",
|
|
3311
|
+
'If the header is rejected, use exactly `sequenceDiagram` (or `sequence "Title"`).'
|
|
3312
|
+
]
|
|
2989
3313
|
},
|
|
2990
3314
|
petri: {
|
|
2991
3315
|
type: "petri",
|
|
@@ -3015,29 +3339,96 @@ var PROFILES = {
|
|
|
3015
3339
|
network: {
|
|
3016
3340
|
type: "network",
|
|
3017
3341
|
header: 'network "Title"',
|
|
3018
|
-
mode: "
|
|
3342
|
+
mode: "device declarations + links (annotations are optional)",
|
|
3019
3343
|
forms: [
|
|
3020
|
-
"
|
|
3021
|
-
'
|
|
3022
|
-
|
|
3023
|
-
|
|
3024
|
-
"
|
|
3025
|
-
"
|
|
3026
|
-
|
|
3344
|
+
'router r1 "Edge Router" (kind id "label")',
|
|
3345
|
+
'l3switch core1 "Core" tier: core (optional structural hint)',
|
|
3346
|
+
'switch acc1 "Access" tier: access',
|
|
3347
|
+
'pc pc1 "Workstation"',
|
|
3348
|
+
"r1 -- core1 (link: id -- id)",
|
|
3349
|
+
"core1 -- acc1",
|
|
3350
|
+
"acc1 -- pc1"
|
|
3027
3351
|
],
|
|
3028
3352
|
prefer: [
|
|
3029
|
-
"
|
|
3030
|
-
"
|
|
3031
|
-
"
|
|
3032
|
-
"
|
|
3353
|
+
'Start from the skeleton: `kind id "label"` device lines plus `a -- b` links. That alone renders a complete, valid diagram.',
|
|
3354
|
+
"Declare every device before any link references it.",
|
|
3355
|
+
"Keep the cheap structural hints `layout:` (tiered/tree/star/ring/bus/mesh/spine-leaf) and `tier:` (edge/core/distribution/access) \u2014 they cost little and drive a readable hierarchy. They are recommended, not noise.",
|
|
3356
|
+
"Common kinds: router, switch, l3switch, firewall, ap, server, pc, laptop, camera, nvr, poeswitch, internet, cloud."
|
|
3033
3357
|
],
|
|
3034
3358
|
avoid: [
|
|
3035
3359
|
"Avoid linking to an undeclared device id.",
|
|
3036
|
-
|
|
3360
|
+
'Add the verbose per-link annotations \u2014 `vlan:`, `port:`, speeds (1G/10G), `trunk`/`access` \u2014 and `subnet "cidr" { ... }` boundaries ONLY when the request explicitly needs them. These don\'t affect the layout and are where generation most often breaks.'
|
|
3037
3361
|
],
|
|
3038
3362
|
repair: [
|
|
3039
3363
|
"An 'undeclared device' error means a link references an id with no `kind id` declaration \u2014 declare it first.",
|
|
3040
|
-
"
|
|
3364
|
+
"If the layout looks flat/messy, add `layout: tiered` + `tier:` on infrastructure; if unsure about per-link annotations, drop them \u2014 the skeleton always renders."
|
|
3365
|
+
]
|
|
3366
|
+
},
|
|
3367
|
+
umlclass: {
|
|
3368
|
+
type: "umlclass",
|
|
3369
|
+
header: "umlclass",
|
|
3370
|
+
mode: "classifier declarations + relationship lines (PlantUML-flavoured, Mermaid aliases accepted)",
|
|
3371
|
+
forms: [
|
|
3372
|
+
"class Order { + id : String + place() : void } (visibility: + - # ~)",
|
|
3373
|
+
"\xABinterface\xBB Shape { + area() : double } (stereotype above name)",
|
|
3374
|
+
"abstract class AbstractShape { + area() : double {abstract} }",
|
|
3375
|
+
"\xABenumeration\xBB Suit { HEARTS DIAMONDS CLUBS SPADES } (literals in attr compartment)",
|
|
3376
|
+
"Animal <|-- Dog (generalization \u2014 hollow triangle to parent)",
|
|
3377
|
+
"Shape <|.. Circle (realization \u2014 dashed + hollow triangle)",
|
|
3378
|
+
'Order *-- "1..*" LineItem : contains (composition \u2014 filled diamond at whole)',
|
|
3379
|
+
'Customer o-- "0..*" Address (aggregation \u2014 hollow diamond at whole)',
|
|
3380
|
+
'A "1" --> "*" B : owns (directed association \u2014 open arrow to target)',
|
|
3381
|
+
"X ..> Y (dependency \u2014 dashed + open arrow)"
|
|
3382
|
+
],
|
|
3383
|
+
prefer: [
|
|
3384
|
+
"Single-word keyword is `umlclass` (also accepts `class-diagram` and Mermaid's `classDiagram`).",
|
|
3385
|
+
"Use `class`, `abstract class`, `\xABinterface\xBB`, `\xABenumeration\xBB`, or any custom `\xABstereotype\xBB` above the name.",
|
|
3386
|
+
"Members go in `{ \u2026 }`; visibility glyphs are `+ - # ~`; `{static}` underlines, `{abstract}` italicises, `/name` marks a derived attribute.",
|
|
3387
|
+
'Multiplicity is the quoted token next to an endpoint: `"1"`, `"0..*"`, `"1..*"`. The line midpoint label after `:` is the association name.',
|
|
3388
|
+
"PlantUML connectors are primary; the Mermaid reversed forms `--|>`, `..|>`, `--*`, `--o` are accepted and normalised."
|
|
3389
|
+
],
|
|
3390
|
+
avoid: [
|
|
3391
|
+
"Don't use bare `class` as the diagram keyword \u2014 that's a reserved programming-language word, and the engine keyword is `umlclass`.",
|
|
3392
|
+
"Don't put `-->` for dependency: `-->` is *directed association*; dependency is the dashed `..>` (this is a deliberate deviation from PlantUML, matching Mermaid and the usual UML reading).",
|
|
3393
|
+
"Don't declare a classifier with an empty body and `{}` if you want a name-only sketch box \u2014 write `class Foo` on its own line."
|
|
3394
|
+
],
|
|
3395
|
+
repair: [
|
|
3396
|
+
"A 'malformed relationship' error means no connector glyph was found between two ids \u2014 check the line uses one of `<|--` `<|..` `*--` `o--` `-->` `..>` `--` `..`.",
|
|
3397
|
+
"A 'generalization cycle' error means inheritance edges form a loop \u2014 fix the parent/child direction of one of the edges named in the cycle.",
|
|
3398
|
+
"If a class appears as a one-line empty box you didn't expect, the parser auto-created it from an arc reference \u2014 declare it explicitly or fix the typo in the relationship id."
|
|
3399
|
+
]
|
|
3400
|
+
},
|
|
3401
|
+
faulttree: {
|
|
3402
|
+
type: "faulttree",
|
|
3403
|
+
header: 'faulttree "Title"',
|
|
3404
|
+
mode: "flat event/gate declarations wired by id (top + gates + leaves)",
|
|
3405
|
+
forms: [
|
|
3406
|
+
"analysis: cutsets, probability",
|
|
3407
|
+
'top T "System fails" = OR(G1, G2)',
|
|
3408
|
+
'gate G1 "Sub-fault" = AND(A, B)',
|
|
3409
|
+
'basic A "Component A fails" p: 0.01',
|
|
3410
|
+
'undeveloped EXT "External cause"',
|
|
3411
|
+
'house HX "Power on" state: 1',
|
|
3412
|
+
"RELIEF = VOTING(2/3; PRV_A, PRV_B, PRV_C)",
|
|
3413
|
+
"OVP = INHIBIT(PUMP) if HEATER"
|
|
3414
|
+
],
|
|
3415
|
+
prefer: [
|
|
3416
|
+
"Single-word keyword is `faulttree` (alias `fta`). Declare exactly one `top` event.",
|
|
3417
|
+
"Declare every referenced event before or after use; wire gates by id (the tree is a DAG \u2014 a basic event may feed several gates).",
|
|
3418
|
+
"Gate expressions: AND/OR/XOR(a, b, \u2026), VOTING(k/n; \u2026), INHIBIT(x) if cond, PAND(a, b) order: a, b.",
|
|
3419
|
+
"Put `p: 0.001` (or scientific `1e-3`) on basic/undeveloped events; the engine computes minimal cut sets and P(top).",
|
|
3420
|
+
"Use `prob: rare` (default), `mcub`, or `exact`; `house \u2026 state: 0|1` switches branches on/off."
|
|
3421
|
+
],
|
|
3422
|
+
avoid: [
|
|
3423
|
+
"Don't nest by indentation \u2014 fault tree is flat declaration + id reference (so repeated/shared events are unambiguous).",
|
|
3424
|
+
"Don't attach `if <cond>` to anything but INHIBIT (or `order:` to anything but PAND).",
|
|
3425
|
+
"Don't declare more than one `top`, and don't create cycles (a gate may not transitively reference itself)."
|
|
3426
|
+
],
|
|
3427
|
+
repair: [
|
|
3428
|
+
"'references undefined event' means a gate input id was never declared \u2014 add the `basic`/`gate`/\u2026 line.",
|
|
3429
|
+
"'must have exactly one top' \u2014 keep a single `top`; downgrade the others to `gate`.",
|
|
3430
|
+
"'VOTING k/n: n must equal the number of inputs' \u2014 make n match the listed inputs.",
|
|
3431
|
+
"If P(top) shows 'n/a', a basic event in a cut set is missing its `p:`."
|
|
3041
3432
|
]
|
|
3042
3433
|
}
|
|
3043
3434
|
};
|
|
@@ -3122,7 +3513,7 @@ function getExamples(type, opts = {}) {
|
|
|
3122
3513
|
function validateDsl(type, dsl) {
|
|
3123
3514
|
const resolvedType = type ? resolveDiagramType(type) : void 0;
|
|
3124
3515
|
const config = type ? { type: resolvedType ?? type } : void 0;
|
|
3125
|
-
const result =
|
|
3516
|
+
const result = chunk624UQ5R6_cjs.parseResult(dsl, config);
|
|
3126
3517
|
if (result.ok) {
|
|
3127
3518
|
return { ok: true, type: result.type };
|
|
3128
3519
|
}
|
|
@@ -3140,7 +3531,7 @@ function renderDsl(type, dsl, options = {}) {
|
|
|
3140
3531
|
...options,
|
|
3141
3532
|
...type ? { type: resolvedType ?? type } : {}
|
|
3142
3533
|
};
|
|
3143
|
-
const result =
|
|
3534
|
+
const result = chunk624UQ5R6_cjs.renderResult(dsl, config);
|
|
3144
3535
|
if (result.ok) {
|
|
3145
3536
|
return {
|
|
3146
3537
|
ok: true,
|
|
@@ -3193,5 +3584,5 @@ exports.listDiagrams = listDiagrams;
|
|
|
3193
3584
|
exports.renderDsl = renderDsl;
|
|
3194
3585
|
exports.resolveDiagramType = resolveDiagramType;
|
|
3195
3586
|
exports.validateDsl = validateDsl;
|
|
3196
|
-
//# sourceMappingURL=chunk-
|
|
3197
|
-
//# sourceMappingURL=chunk-
|
|
3587
|
+
//# sourceMappingURL=chunk-T3ZN5P32.cjs.map
|
|
3588
|
+
//# sourceMappingURL=chunk-T3ZN5P32.cjs.map
|