schematex 0.6.2 → 0.6.6
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 +23 -23
- package/dist/ai/ai-sdk.d.cts +4 -4
- package/dist/ai/ai-sdk.d.ts +4 -4
- package/dist/ai/ai-sdk.js +18 -18
- package/dist/ai/index.cjs +29 -29
- package/dist/ai/index.d.cts +3 -3
- package/dist/ai/index.d.ts +3 -3
- package/dist/ai/index.js +18 -18
- package/dist/{api-qVDutqXH.d.cts → api-DA4-U-jn.d.cts} +2 -2
- package/dist/{api-XWHHAhQI.d.ts → api-QFMTlIi7.d.ts} +2 -2
- package/dist/browser.cjs +24 -24
- package/dist/browser.d.cts +3 -3
- package/dist/browser.d.ts +3 -3
- package/dist/browser.js +18 -18
- package/dist/{chunk-VTSH4YPT.cjs → chunk-2SZJQVPN.cjs} +12 -12
- package/dist/{chunk-VTSH4YPT.cjs.map → chunk-2SZJQVPN.cjs.map} +1 -1
- package/dist/{chunk-3IE7KZY4.js → chunk-3GAPHXCE.js} +96 -10
- package/dist/chunk-3GAPHXCE.js.map +1 -0
- package/dist/{chunk-ITUPR7G5.js → chunk-3HZW6K5I.js} +429 -14
- package/dist/chunk-3HZW6K5I.js.map +1 -0
- package/dist/{chunk-WQDIZH2Z.cjs → chunk-5FYPSIGD.cjs} +12 -12
- package/dist/{chunk-WQDIZH2Z.cjs.map → chunk-5FYPSIGD.cjs.map} +1 -1
- package/dist/{chunk-DOK7LKLO.js → chunk-6NUAGU6O.js} +3 -3
- package/dist/{chunk-DOK7LKLO.js.map → chunk-6NUAGU6O.js.map} +1 -1
- package/dist/{chunk-V4GILQR6.cjs → chunk-77GPD4YQ.cjs} +4 -4
- package/dist/{chunk-V4GILQR6.cjs.map → chunk-77GPD4YQ.cjs.map} +1 -1
- package/dist/{chunk-RJMCWT7Z.js → chunk-7DAIEDQP.js} +3 -3
- package/dist/{chunk-RJMCWT7Z.js.map → chunk-7DAIEDQP.js.map} +1 -1
- package/dist/{chunk-4UFR2LB6.cjs → chunk-BL57NQKN.cjs} +13 -13
- package/dist/{chunk-4UFR2LB6.cjs.map → chunk-BL57NQKN.cjs.map} +1 -1
- package/dist/{chunk-SD6VDTQR.cjs → chunk-CMZKAASF.cjs} +431 -16
- package/dist/chunk-CMZKAASF.cjs.map +1 -0
- package/dist/{chunk-3JAI3OVG.cjs → chunk-DO2DDHTQ.cjs} +4 -4
- package/dist/{chunk-3JAI3OVG.cjs.map → chunk-DO2DDHTQ.cjs.map} +1 -1
- package/dist/{chunk-6JI6FWLZ.cjs → chunk-DR3DDDQY.cjs} +4 -4
- package/dist/{chunk-6JI6FWLZ.cjs.map → chunk-DR3DDDQY.cjs.map} +1 -1
- package/dist/{chunk-ECD5XHBM.cjs → chunk-EUVUO3CL.cjs} +100 -25
- package/dist/chunk-EUVUO3CL.cjs.map +1 -0
- package/dist/{chunk-IZWKJVIC.js → chunk-FOPOOV2P.js} +4344 -339
- package/dist/chunk-FOPOOV2P.js.map +1 -0
- package/dist/{chunk-MVIEIKOI.js → chunk-HL5PS6MG.js} +3 -3
- package/dist/{chunk-MVIEIKOI.js.map → chunk-HL5PS6MG.js.map} +1 -1
- package/dist/{chunk-7F76AWOI.js → chunk-HPEAE3JM.js} +3 -3
- package/dist/{chunk-7F76AWOI.js.map → chunk-HPEAE3JM.js.map} +1 -1
- package/dist/{chunk-N5B242WY.js → chunk-JN6FHUC6.js} +3 -3
- package/dist/{chunk-N5B242WY.js.map → chunk-JN6FHUC6.js.map} +1 -1
- package/dist/{chunk-YS6CGUNH.js → chunk-K2D6VFLP.js} +3 -3
- package/dist/{chunk-YS6CGUNH.js.map → chunk-K2D6VFLP.js.map} +1 -1
- package/dist/{chunk-LGABFD3L.js → chunk-KCHUQXS3.js} +100 -25
- package/dist/chunk-KCHUQXS3.js.map +1 -0
- package/dist/{chunk-YB4XJY5L.cjs → chunk-KGOZBABH.cjs} +12 -12
- package/dist/{chunk-YB4XJY5L.cjs.map → chunk-KGOZBABH.cjs.map} +1 -1
- package/dist/{chunk-JVAJ6ZLO.js → chunk-KJZCRHNR.js} +3 -3
- package/dist/{chunk-JVAJ6ZLO.js.map → chunk-KJZCRHNR.js.map} +1 -1
- package/dist/{chunk-C5C5EF3W.cjs → chunk-LPAWZYDU.cjs} +4 -4
- package/dist/{chunk-C5C5EF3W.cjs.map → chunk-LPAWZYDU.cjs.map} +1 -1
- package/dist/{chunk-KSNUMQGS.cjs → chunk-MLLARXOI.cjs} +4373 -365
- package/dist/chunk-MLLARXOI.cjs.map +1 -0
- package/dist/{chunk-S3RMAXH5.cjs → chunk-NFZMNKOR.cjs} +15 -15
- package/dist/{chunk-S3RMAXH5.cjs.map → chunk-NFZMNKOR.cjs.map} +1 -1
- package/dist/{chunk-L7POWM5B.cjs → chunk-NZT5P2XZ.cjs} +200 -2
- package/dist/chunk-NZT5P2XZ.cjs.map +1 -0
- package/dist/{chunk-3VB5AT4R.js → chunk-OFKRELZK.js} +3 -3
- package/dist/{chunk-3VB5AT4R.js.map → chunk-OFKRELZK.js.map} +1 -1
- package/dist/{chunk-FBS3PACU.js → chunk-T3FV73LM.js} +3 -3
- package/dist/{chunk-FBS3PACU.js.map → chunk-T3FV73LM.js.map} +1 -1
- package/dist/{chunk-HWVBHU3O.cjs → chunk-T5KHNJ67.cjs} +5 -5
- package/dist/{chunk-HWVBHU3O.cjs.map → chunk-T5KHNJ67.cjs.map} +1 -1
- package/dist/{chunk-2L4YXZAZ.cjs → chunk-TACTEF2N.cjs} +5 -5
- package/dist/{chunk-2L4YXZAZ.cjs.map → chunk-TACTEF2N.cjs.map} +1 -1
- package/dist/{chunk-LRI4RH2N.js → chunk-UK6HF6PE.js} +197 -3
- package/dist/chunk-UK6HF6PE.js.map +1 -0
- package/dist/{chunk-TWLKXV2O.js → chunk-WU2N6ZVM.js} +4 -4
- package/dist/{chunk-TWLKXV2O.js.map → chunk-WU2N6ZVM.js.map} +1 -1
- package/dist/{chunk-FKJBXGWP.cjs → chunk-XYHCAJMI.cjs} +4 -4
- package/dist/{chunk-FKJBXGWP.cjs.map → chunk-XYHCAJMI.cjs.map} +1 -1
- package/dist/{chunk-H4MT5TJP.js → chunk-YMZTXOUG.js} +3 -3
- package/dist/{chunk-H4MT5TJP.js.map → chunk-YMZTXOUG.js.map} +1 -1
- package/dist/{chunk-HAZALB7U.js → chunk-YTGOLTLJ.js} +3 -3
- package/dist/{chunk-HAZALB7U.js.map → chunk-YTGOLTLJ.js.map} +1 -1
- package/dist/{chunk-R66QG3XT.cjs → chunk-Z3A2UNK2.cjs} +98 -10
- package/dist/chunk-Z3A2UNK2.cjs.map +1 -0
- package/dist/{diagnostics-DRxhodP6.d.ts → diagnostics-CSznf_sl.d.cts} +7 -3
- package/dist/{diagnostics-DRxhodP6.d.cts → diagnostics-CSznf_sl.d.ts} +7 -3
- package/dist/diagrams/blockdiagram/index.d.cts +1 -1
- package/dist/diagrams/blockdiagram/index.d.ts +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.d.cts +1 -1
- package/dist/diagrams/timing/index.d.ts +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-BRIkOPnd.d.cts → index-CDpYuU7l.d.cts} +1 -1
- package/dist/{index-C7SN-FB3.d.ts → index-jTwjudTW.d.ts} +1 -1
- package/dist/index.cjs +84 -72
- package/dist/index.d.cts +11 -5
- package/dist/index.d.ts +11 -5
- package/dist/index.js +22 -22
- package/dist/react.cjs +18 -18
- package/dist/react.d.cts +2 -2
- package/dist/react.d.ts +2 -2
- package/dist/react.js +17 -17
- package/dist/{tools-DdhP1kWY.d.cts → tools-CbuSbW6B.d.cts} +3 -3
- package/dist/{tools-BVeUNdsU.d.ts → tools-D344vOzR.d.ts} +3 -3
- package/package.json +1 -1
- package/dist/chunk-3IE7KZY4.js.map +0 -1
- package/dist/chunk-ECD5XHBM.cjs.map +0 -1
- package/dist/chunk-ITUPR7G5.js.map +0 -1
- package/dist/chunk-IZWKJVIC.js.map +0 -1
- package/dist/chunk-KSNUMQGS.cjs.map +0 -1
- package/dist/chunk-L7POWM5B.cjs.map +0 -1
- package/dist/chunk-LGABFD3L.js.map +0 -1
- package/dist/chunk-LRI4RH2N.js.map +0 -1
- package/dist/chunk-R66QG3XT.cjs.map +0 -1
- package/dist/chunk-SD6VDTQR.cjs.map +0 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var chunkMLLARXOI_cjs = require('./chunk-MLLARXOI.cjs');
|
|
4
4
|
|
|
5
5
|
// src/ai/registry.ts
|
|
6
6
|
var DIAGRAM_REGISTRY = [
|
|
@@ -265,6 +265,34 @@ 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
|
+
},
|
|
287
|
+
{
|
|
288
|
+
type: "bowtie",
|
|
289
|
+
name: "Bowtie risk diagram",
|
|
290
|
+
tagline: "Barrier-based risk management \u2014 one hazard's top event (the knot) with threats fanning in through preventative barriers on the left and consequences fanning out through mitigative barriers on the right, the whole shaped like a bow tie.",
|
|
291
|
+
useWhen: 'Use for process-safety / barrier risk analysis (oil & gas, aviation SMS, chemical, rail): one hazard, one top event, the threats that could cause it and the consequences if it happens, with the controls (barriers) in between. Indentation-structured DSL mirrors the CCPS 7-step build: `hazard "\u2026"`, `topevent "\u2026"`, then each `threat "\u2026"` with indented `prevent "\u2026"` barrier chain, each `consequence "\u2026"` with indented `mitigate "\u2026"` chain; `escalation "\u2026"` nests under a barrier it degrades, `barrier "\u2026"` nests under an escalation. Correct-by-construction: the engine *rejects* a threat/consequence with no barrier and an escalation not attached to a barrier (CCPS/EI barrier rule set). Qualitative \u2014 no probability rollup (that is `faulttree`\'s job; a bowtie\'s left wing read backwards IS a fault tree). Distinct from `fishbone` (one-sided causes, no barriers) and `faulttree` (Boolean gates + cut sets, left wing only).',
|
|
292
|
+
cluster: "risk-reliability",
|
|
293
|
+
standard: "CCPS / Energy Institute 2018 (Bow Ties in Risk Management) + IEC 31010:2019 \xA7B.4.6 + ICAO Doc 9859; Swiss-cheese lineage (Reason 1990); see 38-BOWTIE-STANDARD.md",
|
|
294
|
+
syntaxKey: "bowtie"
|
|
295
|
+
},
|
|
268
296
|
// ── Generic process / flow ───────────────────────────────────
|
|
269
297
|
{
|
|
270
298
|
type: "flowchart",
|
|
@@ -356,7 +384,13 @@ var DIAGRAM_SINCE = {
|
|
|
356
384
|
// 0.6.0 — upcoming (committed post-0.5.2, not yet released)
|
|
357
385
|
pert: "0.6.0",
|
|
358
386
|
petri: "0.6.0",
|
|
359
|
-
network: "0.6.0"
|
|
387
|
+
network: "0.6.0",
|
|
388
|
+
// 0.6.4
|
|
389
|
+
umlclass: "0.6.4",
|
|
390
|
+
// 0.6.5
|
|
391
|
+
faulttree: "0.6.5",
|
|
392
|
+
// 0.6.6
|
|
393
|
+
bowtie: "0.6.6"
|
|
360
394
|
};
|
|
361
395
|
function getDiagramSince(type) {
|
|
362
396
|
const resolved = resolveDiagramType(type);
|
|
@@ -421,6 +455,82 @@ var EXAMPLES = [
|
|
|
421
455
|
"dsl": 'blockdiagram "PID control loop"\nC = block("PID C(s)") [role: controller]\nG = block("Plant G(s)") [role: plant]\nerr = sum(+r, -y)\nr = signal("r (setpoint)")\ny = signal("y (output)")\nin -> r\nr -> err\nerr -> C\nC -> G\nG -> y\nG -> err',
|
|
422
456
|
"notes": '## Scenario\n\nThe standard closed-loop PID block diagram appears in every control systems textbook (Ogata, Franklin, \xC5str\xF6m) and every control system design spec sheet. Schematex renders it from a signal-flow description \u2014 not a generic flowchart \u2014 using proper summing junction symbols and automatic feedback routing.\n\n## Annotation key\n\n- `block("label") [role: ...]` \u2014 transfer function block; `role: controller` and `role: plant` affect visual styling\n- `sum(+r, -y)` \u2014 summing junction: adds the `+r` (reference) signal and subtracts the `-y` (output feedback)\n- `signal("label")` \u2014 named signal node\n- `G -> err` \u2014 the feedback path: plant output `y` routes back to the summing junction\n\n## How to read\n\nThe setpoint `r` enters the summing junction `err`, which subtracts the plant output `y` to compute the error signal. The PID controller `C(s)` processes the error and drives the plant `G(s)`. The plant output `y` is both the system output and the feedback signal. The loop is closed when `G -> err` feeds `y` back to the summing junction.'
|
|
423
457
|
},
|
|
458
|
+
{
|
|
459
|
+
"slug": "bowtie-hot-work-fire",
|
|
460
|
+
"diagram": "bowtie",
|
|
461
|
+
"title": "Hot work \u2014 ignition of flammable atmosphere",
|
|
462
|
+
"description": "A bowtie with escalation factors on both wings \u2014 a preventative and a mitigative barrier are each degraded by a named condition with its own escalation-factor barrier, exercising the full element vocabulary.",
|
|
463
|
+
"standard": "CCPS / Energy Institute 2018",
|
|
464
|
+
"tags": [
|
|
465
|
+
"bowtie",
|
|
466
|
+
"risk",
|
|
467
|
+
"escalation-factor",
|
|
468
|
+
"hot-work",
|
|
469
|
+
"fire",
|
|
470
|
+
"barrier"
|
|
471
|
+
],
|
|
472
|
+
"complexity": 3,
|
|
473
|
+
"featured": false,
|
|
474
|
+
"dsl": 'bowtie "Hot work \u2014 fire bowtie"\nhazard "Hot work near flammable materials"\ntopevent "Ignition of flammable atmosphere"\nthreat "Sparks / hot slag"\n prevent "Hot-work permit"\n prevent "Fire watch"\n escalation "Fire watch leaves post early"\n barrier "Post-work monitoring period (60 min)"\nthreat "Static discharge"\n prevent "Bonding + grounding"\n prevent "Antistatic PPE"\nconsequence "Flash fire"\n mitigate "Fixed fire suppression"\n escalation "Suppression isolated for maintenance"\n barrier "Impairment register + MoC"\nconsequence "Asset loss"\n mitigate "Fire-rated separation"\n mitigate "Business-continuity plan"',
|
|
475
|
+
"notes": '## What this shows\n\nThe complete element vocabulary, with **escalation factors on both wings** \u2014 because a mitigative barrier can be degraded just as a preventative one can. On the left, the "Fire watch" barrier is defeated if the watch leaves early, controlled by a mandatory post-work monitoring period. On the right, the "Fixed fire suppression" barrier is defeated when isolated for maintenance, controlled by an impairment register and management-of-change.\n\nThe left wing is taller than the right (its escalation drops deeper), so it sets the diagram height while the right wing stays centred about the knot. Each escalation hangs into the whitespace between bands on a muted *degrades* connector, never colliding with the next line.'
|
|
476
|
+
},
|
|
477
|
+
{
|
|
478
|
+
"slug": "bowtie-lpg-loss-of-containment",
|
|
479
|
+
"diagram": "bowtie",
|
|
480
|
+
"title": "LPG storage \u2014 loss of containment",
|
|
481
|
+
"description": "The canonical process-safety bowtie \u2014 three threats fan in through preventative barrier chains, three consequences fan out through mitigative chains, around the central loss-of-containment top event.",
|
|
482
|
+
"standard": "CCPS / Energy Institute 2018",
|
|
483
|
+
"tags": [
|
|
484
|
+
"bowtie",
|
|
485
|
+
"risk",
|
|
486
|
+
"process-safety",
|
|
487
|
+
"barrier",
|
|
488
|
+
"hazard",
|
|
489
|
+
"loss-of-containment"
|
|
490
|
+
],
|
|
491
|
+
"complexity": 3,
|
|
492
|
+
"featured": true,
|
|
493
|
+
"dsl": 'bowtie "LPG storage \u2014 loss of containment"\nhazard "LPG stored under pressure"\ntopevent "Loss of containment"\nthreat "Corrosion of vessel wall"\n prevent "Corrosion-resistant coating"\n prevent "UT thickness inspection"\nthreat "Overpressure during filling"\n prevent "High-pressure trip (SIL 2)"\n prevent "Pressure relief valve"\nthreat "Mechanical impact (vehicle)"\n prevent "Bollards / vehicle barriers"\n prevent "Site speed limit + banksman"\nconsequence "Jet fire"\n mitigate "Gas detection + ESD"\n mitigate "Deluge / water spray"\nconsequence "Vapour cloud explosion"\n mitigate "Ignition-source control (ATEX)"\n mitigate "Blast-resistant control room"\nconsequence "Toxic / asphyxiation exposure"\n mitigate "Personal gas monitors"\n mitigate "Emergency evacuation plan"',
|
|
494
|
+
"notes": '## What this shows\n\nThe integrating picture of barrier-based risk management for one major-accident scenario. The **hazard** ("LPG stored under pressure") sits above the central **top event** \u2014 the moment control is lost. To the **left**, three credible **threats** each fan in through a chain of **preventative barriers** (grey, on the line) that stop them reaching the knot. To the **right**, three **consequences** each fan out through a chain of **mitigative barriers** that limit the damage if the top event occurs.\n\nThis is the shape a process-safety reviewer expects on an A3: defence-in-depth depth on both wings, the knot in the middle, the hazard above. **Correct by construction** \u2014 the engine would reject any threat or consequence drawn with no barrier (a Swiss-cheese cartoon), so every line you see genuinely passes through a control.'
|
|
495
|
+
},
|
|
496
|
+
{
|
|
497
|
+
"slug": "bowtie-runway-excursion",
|
|
498
|
+
"diagram": "bowtie",
|
|
499
|
+
"title": "Runway excursion (aviation SMS)",
|
|
500
|
+
"description": "A non-process-industry bowtie \u2014 the same threat / barrier / consequence grammar applied to an aviation safety-management scenario, showing the vocabulary travels across domains.",
|
|
501
|
+
"standard": "ICAO Doc 9859 + CCPS / EI 2018",
|
|
502
|
+
"tags": [
|
|
503
|
+
"bowtie",
|
|
504
|
+
"risk",
|
|
505
|
+
"aviation",
|
|
506
|
+
"SMS",
|
|
507
|
+
"ICAO",
|
|
508
|
+
"barrier"
|
|
509
|
+
],
|
|
510
|
+
"complexity": 3,
|
|
511
|
+
"featured": false,
|
|
512
|
+
"dsl": 'bowtie "Runway excursion"\nhazard "Aircraft landing in adverse conditions"\ntopevent "Runway excursion on landing"\nthreat "Unstable approach"\n prevent "Stabilised-approach gate (go-around policy)"\n prevent "Approach monitoring + callouts"\nthreat "Contaminated runway"\n prevent "Runway condition reporting (RCR)"\n prevent "Landing performance assessment"\nthreat "Excessive landing speed"\n prevent "Speed / energy management SOP"\n prevent "Autobrake selection"\nconsequence "Hull damage"\n mitigate "Runway end safety area (RESA)"\n mitigate "Arrestor bed (EMAS)"\nconsequence "Injuries / fatalities"\n mitigate "Cabin-crew brace + evacuation"\n mitigate "Airport emergency response"',
|
|
513
|
+
"notes": "## What this shows\n\nThe bowtie is mandated well beyond process industries \u2014 ICAO's Safety Management Manual (Doc 9859) makes it a primary hazard-analysis tool for airlines. The grammar is identical: a **hazard** (landing in adverse conditions), a **top event** (the runway excursion), **threats** that could cause it through preventative barrier chains, and **consequences** limited by mitigative chains.\n\nIt reads the same to a non-specialist as a chemical-plant bowtie, which is exactly the point: one A3 puts the entire defence-in-depth story for a single scenario in front of a board or a regulator, regardless of industry."
|
|
514
|
+
},
|
|
515
|
+
{
|
|
516
|
+
"slug": "bowtie-working-at-height",
|
|
517
|
+
"diagram": "bowtie",
|
|
518
|
+
"title": "Working at height \u2014 fall from height",
|
|
519
|
+
"description": "A defence-in-depth bowtie with an escalation factor \u2014 a preventative barrier is degraded by a named condition, which is itself controlled by an escalation-factor barrier dropping below the line.",
|
|
520
|
+
"standard": "CCPS / Energy Institute 2018",
|
|
521
|
+
"tags": [
|
|
522
|
+
"bowtie",
|
|
523
|
+
"risk",
|
|
524
|
+
"escalation-factor",
|
|
525
|
+
"defence-in-depth",
|
|
526
|
+
"construction",
|
|
527
|
+
"safety"
|
|
528
|
+
],
|
|
529
|
+
"complexity": 2,
|
|
530
|
+
"featured": true,
|
|
531
|
+
"dsl": 'bowtie "Working at height"\nhazard "Working at height"\ntopevent "Person falls from height"\nthreat "Guardrail removed for access"\n prevent "Permit-to-work system"\n prevent "Temporary edge protection"\n escalation "Edge protection not inspected"\n barrier "Pre-use inspection regime"\n prevent "Spotter / banksman"\nthreat "Fragile roof surface"\n prevent "Crawling boards + signage"\n prevent "Roof-access risk assessment"\nconsequence "Fatality"\n mitigate "Fall-arrest harness + lanyard"\n mitigate "Rescue plan + first aid"\nconsequence "Serious injury"\n mitigate "Safety netting below"\n mitigate "On-site medic + evacuation"',
|
|
532
|
+
"notes": '## What this shows\n\nTwo threats, two consequences, multi-barrier chains \u2014 and an **escalation factor**, the element that makes a bowtie an honest defence-in-depth model rather than a wish list. The "Temporary edge protection" barrier is degraded by a specific named condition ("Edge protection not inspected", amber), which drops vertically below the barrier on a muted *degrades* connector. That escalation factor is itself controlled by an **escalation-factor barrier** ("Pre-use inspection regime") one level deeper.\n\nReading order along each line is declaration order: the first barrier is the **outermost** (first line of defence, nearest the threat); the last is the **innermost** (nearest the knot). The escalation hangs into the whitespace below without disturbing the symmetry of the two threat lines.'
|
|
533
|
+
},
|
|
424
534
|
{
|
|
425
535
|
"slug": "bpmn-incident-response",
|
|
426
536
|
"diagram": "bpmn",
|
|
@@ -887,6 +997,83 @@ If the LED doesn't light up, three things to check, in order: LED polarity (the
|
|
|
887
997
|
"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',
|
|
888
998
|
"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)."
|
|
889
999
|
},
|
|
1000
|
+
{
|
|
1001
|
+
"slug": "faulttree-pump-redundancy",
|
|
1002
|
+
"diagram": "faulttree",
|
|
1003
|
+
"title": "Redundant pump failure (AND gate)",
|
|
1004
|
+
"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.",
|
|
1005
|
+
"standard": "NUREG-0492 / IEC 61025",
|
|
1006
|
+
"tags": [
|
|
1007
|
+
"faulttree",
|
|
1008
|
+
"fta",
|
|
1009
|
+
"reliability",
|
|
1010
|
+
"and-gate",
|
|
1011
|
+
"cut-sets",
|
|
1012
|
+
"probability"
|
|
1013
|
+
],
|
|
1014
|
+
"complexity": 1,
|
|
1015
|
+
"featured": true,
|
|
1016
|
+
"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',
|
|
1017
|
+
"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."
|
|
1018
|
+
},
|
|
1019
|
+
{
|
|
1020
|
+
"slug": "faulttree-repeated-event",
|
|
1021
|
+
"diagram": "faulttree",
|
|
1022
|
+
"title": "Repeated event with cut-set absorption",
|
|
1023
|
+
"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.",
|
|
1024
|
+
"standard": "NUREG-0492 / MOCUS (Fussell-Vesely 1972)",
|
|
1025
|
+
"tags": [
|
|
1026
|
+
"faulttree",
|
|
1027
|
+
"fta",
|
|
1028
|
+
"cut-sets",
|
|
1029
|
+
"repeated-event",
|
|
1030
|
+
"absorption",
|
|
1031
|
+
"spof"
|
|
1032
|
+
],
|
|
1033
|
+
"complexity": 2,
|
|
1034
|
+
"featured": true,
|
|
1035
|
+
"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',
|
|
1036
|
+
"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`."
|
|
1037
|
+
},
|
|
1038
|
+
{
|
|
1039
|
+
"slug": "faulttree-vessel-rupture",
|
|
1040
|
+
"diagram": "faulttree",
|
|
1041
|
+
"title": "Pressure vessel rupture (full vocabulary)",
|
|
1042
|
+
"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.",
|
|
1043
|
+
"standard": "NUREG-0492 / IEC 61025",
|
|
1044
|
+
"tags": [
|
|
1045
|
+
"faulttree",
|
|
1046
|
+
"fta",
|
|
1047
|
+
"voting",
|
|
1048
|
+
"inhibit",
|
|
1049
|
+
"house-event",
|
|
1050
|
+
"undeveloped",
|
|
1051
|
+
"mcub"
|
|
1052
|
+
],
|
|
1053
|
+
"complexity": 3,
|
|
1054
|
+
"featured": false,
|
|
1055
|
+
"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)"',
|
|
1056
|
+
"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."
|
|
1057
|
+
},
|
|
1058
|
+
{
|
|
1059
|
+
"slug": "faulttree-water-overheating",
|
|
1060
|
+
"diagram": "faulttree",
|
|
1061
|
+
"title": "Water overheating (classic textbook tree)",
|
|
1062
|
+
"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.",
|
|
1063
|
+
"standard": "NUREG-0492 / IEC 61025",
|
|
1064
|
+
"tags": [
|
|
1065
|
+
"faulttree",
|
|
1066
|
+
"fta",
|
|
1067
|
+
"and-or",
|
|
1068
|
+
"cut-sets",
|
|
1069
|
+
"probability",
|
|
1070
|
+
"textbook"
|
|
1071
|
+
],
|
|
1072
|
+
"complexity": 2,
|
|
1073
|
+
"featured": false,
|
|
1074
|
+
"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',
|
|
1075
|
+
"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."
|
|
1076
|
+
},
|
|
890
1077
|
{
|
|
891
1078
|
"slug": "fbd-bottle-counter",
|
|
892
1079
|
"diagram": "fbd",
|
|
@@ -2488,6 +2675,104 @@ If the LED doesn't light up, three things to check, in order: LED polarity (the
|
|
|
2488
2675
|
"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"]',
|
|
2489
2676
|
"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."
|
|
2490
2677
|
},
|
|
2678
|
+
{
|
|
2679
|
+
"slug": "umlclass-generics-mermaid",
|
|
2680
|
+
"diagram": "umlclass",
|
|
2681
|
+
"title": "Generics and Mermaid-compatible syntax",
|
|
2682
|
+
"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.",
|
|
2683
|
+
"standard": "OMG UML 2.5.1 \xA79\u2013\xA711",
|
|
2684
|
+
"tags": [
|
|
2685
|
+
"umlclass",
|
|
2686
|
+
"uml",
|
|
2687
|
+
"mermaid",
|
|
2688
|
+
"generics",
|
|
2689
|
+
"interface",
|
|
2690
|
+
"realization"
|
|
2691
|
+
],
|
|
2692
|
+
"complexity": 2,
|
|
2693
|
+
"featured": false,
|
|
2694
|
+
"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",
|
|
2695
|
+
"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."
|
|
2696
|
+
},
|
|
2697
|
+
{
|
|
2698
|
+
"slug": "umlclass-namespaces",
|
|
2699
|
+
"diagram": "umlclass",
|
|
2700
|
+
"title": "Packages and namespaces",
|
|
2701
|
+
"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.",
|
|
2702
|
+
"standard": "OMG UML 2.5.1 \xA79\u2013\xA711",
|
|
2703
|
+
"tags": [
|
|
2704
|
+
"umlclass",
|
|
2705
|
+
"uml",
|
|
2706
|
+
"namespace",
|
|
2707
|
+
"package",
|
|
2708
|
+
"architecture",
|
|
2709
|
+
"mermaid"
|
|
2710
|
+
],
|
|
2711
|
+
"complexity": 2,
|
|
2712
|
+
"featured": false,
|
|
2713
|
+
"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',
|
|
2714
|
+
"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 }`.'
|
|
2715
|
+
},
|
|
2716
|
+
{
|
|
2717
|
+
"slug": "umlclass-order-model",
|
|
2718
|
+
"diagram": "umlclass",
|
|
2719
|
+
"title": "Order model \u2014 aggregation, composition, and dependency",
|
|
2720
|
+
"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.",
|
|
2721
|
+
"standard": "OMG UML 2.5.1 \xA711.5 (Associations)",
|
|
2722
|
+
"tags": [
|
|
2723
|
+
"umlclass",
|
|
2724
|
+
"uml",
|
|
2725
|
+
"composition",
|
|
2726
|
+
"aggregation",
|
|
2727
|
+
"dependency",
|
|
2728
|
+
"multiplicity",
|
|
2729
|
+
"static",
|
|
2730
|
+
"derived"
|
|
2731
|
+
],
|
|
2732
|
+
"complexity": 2,
|
|
2733
|
+
"featured": true,
|
|
2734
|
+
"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',
|
|
2735
|
+
"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."
|
|
2736
|
+
},
|
|
2737
|
+
{
|
|
2738
|
+
"slug": "umlclass-payment-strategy",
|
|
2739
|
+
"diagram": "umlclass",
|
|
2740
|
+
"title": "Payment strategy pattern with enum + custom stereotype",
|
|
2741
|
+
"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.",
|
|
2742
|
+
"standard": "OMG UML 2.5.1 \xA79\u2013\xA711",
|
|
2743
|
+
"tags": [
|
|
2744
|
+
"umlclass",
|
|
2745
|
+
"uml",
|
|
2746
|
+
"strategy-pattern",
|
|
2747
|
+
"interface",
|
|
2748
|
+
"enum",
|
|
2749
|
+
"stereotype",
|
|
2750
|
+
"dependency"
|
|
2751
|
+
],
|
|
2752
|
+
"complexity": 2,
|
|
2753
|
+
"featured": false,
|
|
2754
|
+
"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',
|
|
2755
|
+
"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."
|
|
2756
|
+
},
|
|
2757
|
+
{
|
|
2758
|
+
"slug": "umlclass-shape-hierarchy",
|
|
2759
|
+
"diagram": "umlclass",
|
|
2760
|
+
"title": "Shape class hierarchy with an interface",
|
|
2761
|
+
"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.",
|
|
2762
|
+
"standard": "OMG UML 2.5.1 \xA79\u2013\xA711",
|
|
2763
|
+
"tags": [
|
|
2764
|
+
"umlclass",
|
|
2765
|
+
"uml",
|
|
2766
|
+
"generalization",
|
|
2767
|
+
"realization",
|
|
2768
|
+
"interface",
|
|
2769
|
+
"abstract-class"
|
|
2770
|
+
],
|
|
2771
|
+
"complexity": 1,
|
|
2772
|
+
"featured": true,
|
|
2773
|
+
"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',
|
|
2774
|
+
"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."
|
|
2775
|
+
},
|
|
2491
2776
|
{
|
|
2492
2777
|
"slug": "usecase-atm",
|
|
2493
2778
|
"diagram": "usecase",
|
|
@@ -2694,6 +2979,18 @@ var SYNTAX = {
|
|
|
2694
2979
|
"network": {
|
|
2695
2980
|
"title": "Network Topology",
|
|
2696
2981
|
"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---'
|
|
2982
|
+
},
|
|
2983
|
+
"umlclass": {
|
|
2984
|
+
"title": "UML Class Diagram",
|
|
2985
|
+
"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.'
|
|
2986
|
+
},
|
|
2987
|
+
"faulttree": {
|
|
2988
|
+
"title": "Fault Tree Analysis",
|
|
2989
|
+
"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.'
|
|
2990
|
+
},
|
|
2991
|
+
"bowtie": {
|
|
2992
|
+
"title": "Bowtie Risk Diagram",
|
|
2993
|
+
"content": '## 1. Your first diagram\n\nEvery document starts with the `bowtie` keyword, an optional title, then the hazard, the top event, and the two wings:\n\n```\nbowtie\ntopevent "Loss of containment"\nthreat "Corrosion"\n prevent "Inspection programme"\nconsequence "Release to atmosphere"\n mitigate "Gas detection + ESD"\n```\n\n`topevent` declares the single knot at the centre (mandatory, exactly one). Each `threat` starts a left-wing line; each `consequence` ends a right-wing line. A barrier under a `threat` is **preventative** (`prevent`); under a `consequence` it is **mitigative** (`mitigate`). The diagram is laid out symmetrically about the knot \u2014 threats fan in from the left, consequences fan out to the right.\n\nThe DSL is **indentation-structured** and mirrors the CCPS 7-step build methodology: identify the hazard \u2192 the top event \u2192 the threats \u2192 the consequences \u2192 the preventative barriers \u2192 the mitigative barriers \u2192 the escalation factors.\n\nHeader directives (any order):\n\n- `layout: symmetric | compact` \u2014 band model (default `symmetric`).\n- `legend: on | off | bottom | top` \u2014 the auto-derived colour legend (default on).\n\n---\n\n## 2. Hazard and top event\n\n```\nhazard "Working at height"\ntopevent "Person falls from height"\n```\n\n- **`hazard`** \u2014 the operation or material with the potential to cause harm: the *context* the bowtie is about (e.g. "Working at height", "Hydrocarbon under pressure"). Optional; renders as a header box above the knot with a tie-line down to it. At most one.\n- **`topevent`** \u2014 the moment control of the hazard is **lost** (e.g. "Loss of containment", "Person falls from height"). The knot of the bowtie, drawn as a green circle. **Mandatory, exactly one.**\n\nA hazard is a *thing/activity*, not a failure; the top event is the precise moment of *loss of control* \u2014 not a cause, and not yet a consequence.\n\n---\n\n## 3. Threats and consequences\n\n```\nthreat "Guardrail removed for access"\n prevent "Permit-to-work system"\n\nconsequence "Fatality"\n mitigate "Fall-arrest harness + lanyard"\n```\n\n- A **threat** is a credible cause that, *on its own*, could trigger the top event. Each threat is the start of one left-wing line, drawn as an orange box on the left edge.\n- A **consequence** is a credible outcome *of the top event* (not of the threat), drawn as a red box on the right edge.\n\nThreats and consequences may be declared in any interleaved order \u2014 the parser groups all left-wing blocks and all right-wing blocks regardless of sequence. A bowtie needs **at least one of each**: a one-wing diagram is a fault tree (see `faulttree`) or an event tree, not a bowtie.\n\n---\n\n## 4. Barriers (the controls in between)\n\n```\nthreat "Guardrail removed for access"\n prevent "Permit-to-work system"\n prevent "Temporary edge protection"\n prevent "Spotter / banksman"\n```\n\nA **barrier** is a control that interrupts the threat \u2192 top-event path (preventative) or reduces the consequence after the top event (mitigative). Each is a grey box *on the line*. Chains are free length (1..n) \u2014 the wing simply extends.\n\n**Barrier order is declaration order**: the first declared is the **outermost** (closest to the threat/consequence, the first line of defence); the last declared is the **innermost** (closest to the knot). This matches the left-to-right reading of a real bowtie. Each barrier carries `data-order` (0 = outermost) and `data-side` (`prevent` / `mitigate`) for downstream interactivity.\n\nWhen chains differ in length, barriers are **centre-anchored**: the innermost barriers align in a neat column near the knot, and the threat/consequence boxes are ragged by chain depth \u2014 reading as defence-in-depth.\n\n---\n\n## 5. Escalation factors\n\n```\nthreat "Corrosion"\n prevent "UT thickness inspection"\n escalation "Inspection interval too long"\n barrier "Risk-based inspection scheme"\n```\n\nAn **escalation factor** (or degradation factor) is a condition that *degrades a specific barrier\'s effectiveness* \u2014 e.g. "Edge protection not inspected", "Operator fatigue". It attaches to **one** barrier (not to the line) and drops vertically below it as an amber box, joined by a muted "degrades" connector.\n\nAn **escalation-factor barrier** is a control placed on the escalation factor itself \u2014 it protects the barrier from being degraded (e.g. a pre-use inspection regime). It nests one level deeper, under the escalation factor, and renders as a grey box below it.\n\nIndentation binds the nesting: `prevent`/`mitigate` at 2 spaces, `escalation` at 4, `barrier` at 6.\n\n---\n\n## 6. Correct by construction (the barrier rule set)\n\nBefore it draws a single shape, the engine validates the structural half of the CCPS/EI barrier rule set and **refuses to render** on failure \u2014 exactly as `prisma` refuses missing counts:\n\n- **Exactly one top event** \u2014 zero or several is an error.\n- **Every threat has \u2265 1 preventative barrier** \u2014 a bare threat is a Swiss-cheese cartoon, not a bowtie.\n- **Every consequence has \u2265 1 mitigative barrier** \u2014 the mirror rule.\n- **Every escalation factor is attached to a barrier** \u2014 it cannot float on a line or on the top event.\n- **At least one threat and one consequence** \u2014 a one-wing diagram is an FTA or an ETA.\n\nMessages name the offending element and the rule in plain English, e.g. *"Threat \'Corrosion\' has no preventative barrier \u2014 every threat must reach the top event through at least one barrier (CCPS/EI barrier rule). Add a `prevent` line under it."* This is what separates a real bowtie from a doodle. The engine does **not** judge whether a barrier is truly *effective* or *independent* \u2014 that is the analyst\'s qualitative judgement.\n\n---\n\n## 7. Bowtie vs fault tree\n\nA fully-developed bowtie *is* a fault tree glued to an event tree at the top event: the left wing read backwards is the fault tree whose top event is the bowtie\'s knot, and the right wing is the event tree that propagates it into consequences. Schematex keeps them as two engines because their use differs:\n\n- **`bowtie`** is qualitative and symmetric \u2014 the barrier inventory and the at-a-glance defence-in-depth story; no probability arithmetic.\n- **`faulttree`** is quantitative and Boolean \u2014 AND/OR gates, basic-event probabilities, minimal cut sets, a probability rollup.\n\nWhere you want the gate-level detail behind a single threat, draw a separate `faulttree`.\n\n---\n\n## 8. Theming\n\n`default` uses the recognised BowTieXP / bowtiemaster palette \u2014 **orange threats** (left), **grey barriers** on the line, a **green top-event disc** (centre knot), **red consequences** (right), **amber escalation factors** dropping below \u2014 mapped onto Schematex\'s semantic slots so it stays coherent with `prisma` / `pert` / `petri`. `monochrome` reproduces the regulator-print black-and-white look, where element distinction rides on shape/border + position (escalation factors get a dashed border, the knot a doubled ring) rather than colour. `dark` follows Catppuccin Mocha. All strokes/fills come from `BowtieTokens`; every element carries `data-*` (`data-role`, `data-side`, `data-line`, `data-order`, `data-barrier`) so the structure is inspectable downstream.'
|
|
2697
2994
|
}
|
|
2698
2995
|
};
|
|
2699
2996
|
|
|
@@ -2817,9 +3114,12 @@ var PROFILES = {
|
|
|
2817
3114
|
header: 'logic "Title"',
|
|
2818
3115
|
mode: "logic netlist",
|
|
2819
3116
|
forms: ["INPUT A, B", "G1 = AND(A, B)", "OUTPUT Y = G1"],
|
|
2820
|
-
prefer: [
|
|
2821
|
-
|
|
2822
|
-
|
|
3117
|
+
prefer: [
|
|
3118
|
+
"Gate form is `id = TYPE(in1, in2, \u2026)`; declare `INPUT`/`OUTPUT` ports explicitly. Prefix a signal with `~` for active-low.",
|
|
3119
|
+
"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."
|
|
3120
|
+
],
|
|
3121
|
+
avoid: ["Avoid circuit component names (R, C, transistors) inside logic diagrams."],
|
|
3122
|
+
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)."]
|
|
2823
3123
|
},
|
|
2824
3124
|
circuit: {
|
|
2825
3125
|
type: "circuit",
|
|
@@ -2864,10 +3164,14 @@ var PROFILES = {
|
|
|
2864
3164
|
type: "sld",
|
|
2865
3165
|
header: 'sld "Title"',
|
|
2866
3166
|
mode: "equipment assignments + power-flow edges",
|
|
2867
|
-
forms: ['util = utility [label: "Grid"]', 'xfmr = transformer [rating: "500 kVA"]', "util -> xfmr
|
|
2868
|
-
prefer: [
|
|
3167
|
+
forms: ['util = utility [label: "Grid"]', 'xfmr = transformer [rating: "500 kVA"]', "util -> xfmr (one edge per line, no chaining)"],
|
|
3168
|
+
prefer: [
|
|
3169
|
+
"Declare equipment as `id = nodeType [attrs]`, one `from -> to` connection per line.",
|
|
3170
|
+
"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.",
|
|
3171
|
+
"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."
|
|
3172
|
+
],
|
|
2869
3173
|
avoid: ["Avoid generic flowchart node syntax."],
|
|
2870
|
-
repair: ["
|
|
3174
|
+
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)."]
|
|
2871
3175
|
},
|
|
2872
3176
|
entity: {
|
|
2873
3177
|
type: "entity",
|
|
@@ -2977,10 +3281,19 @@ var PROFILES = {
|
|
|
2977
3281
|
type: "pid",
|
|
2978
3282
|
header: 'pid "Title"',
|
|
2979
3283
|
mode: "equipment + process lines",
|
|
2980
|
-
forms: [
|
|
2981
|
-
|
|
2982
|
-
|
|
2983
|
-
|
|
3284
|
+
forms: [
|
|
3285
|
+
"equip T-101 : tank_atm",
|
|
3286
|
+
"equip P-101 : pump_centrifugal",
|
|
3287
|
+
"line L1 from T-101.bottom to P-101.in",
|
|
3288
|
+
"inst FIC-201 : cr_shared"
|
|
3289
|
+
],
|
|
3290
|
+
prefer: [
|
|
3291
|
+
"Declare equipment first (`equip ID : type [attrs]`), then process/signal lines, then instruments (`inst TAG : category`).",
|
|
3292
|
+
"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.",
|
|
3293
|
+
"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."
|
|
3294
|
+
],
|
|
3295
|
+
avoid: ["Avoid SLD electrical nodes (transformer, breaker) in a P&ID."],
|
|
3296
|
+
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)."]
|
|
2984
3297
|
},
|
|
2985
3298
|
erd: {
|
|
2986
3299
|
type: "erd",
|
|
@@ -3141,6 +3454,108 @@ var PROFILES = {
|
|
|
3141
3454
|
"An 'undeclared device' error means a link references an id with no `kind id` declaration \u2014 declare it first.",
|
|
3142
3455
|
"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."
|
|
3143
3456
|
]
|
|
3457
|
+
},
|
|
3458
|
+
umlclass: {
|
|
3459
|
+
type: "umlclass",
|
|
3460
|
+
header: "umlclass",
|
|
3461
|
+
mode: "classifier declarations + relationship lines (PlantUML-flavoured, Mermaid aliases accepted)",
|
|
3462
|
+
forms: [
|
|
3463
|
+
"class Order { + id : String + place() : void } (visibility: + - # ~)",
|
|
3464
|
+
"\xABinterface\xBB Shape { + area() : double } (stereotype above name)",
|
|
3465
|
+
"abstract class AbstractShape { + area() : double {abstract} }",
|
|
3466
|
+
"\xABenumeration\xBB Suit { HEARTS DIAMONDS CLUBS SPADES } (literals in attr compartment)",
|
|
3467
|
+
"Animal <|-- Dog (generalization \u2014 hollow triangle to parent)",
|
|
3468
|
+
"Shape <|.. Circle (realization \u2014 dashed + hollow triangle)",
|
|
3469
|
+
'Order *-- "1..*" LineItem : contains (composition \u2014 filled diamond at whole)',
|
|
3470
|
+
'Customer o-- "0..*" Address (aggregation \u2014 hollow diamond at whole)',
|
|
3471
|
+
'A "1" --> "*" B : owns (directed association \u2014 open arrow to target)',
|
|
3472
|
+
"X ..> Y (dependency \u2014 dashed + open arrow)"
|
|
3473
|
+
],
|
|
3474
|
+
prefer: [
|
|
3475
|
+
"Single-word keyword is `umlclass` (also accepts `class-diagram` and Mermaid's `classDiagram`).",
|
|
3476
|
+
"Use `class`, `abstract class`, `\xABinterface\xBB`, `\xABenumeration\xBB`, or any custom `\xABstereotype\xBB` above the name.",
|
|
3477
|
+
"Members go in `{ \u2026 }`; visibility glyphs are `+ - # ~`; `{static}` underlines, `{abstract}` italicises, `/name` marks a derived attribute.",
|
|
3478
|
+
'Multiplicity is the quoted token next to an endpoint: `"1"`, `"0..*"`, `"1..*"`. The line midpoint label after `:` is the association name.',
|
|
3479
|
+
"PlantUML connectors are primary; the Mermaid reversed forms `--|>`, `..|>`, `--*`, `--o` are accepted and normalised."
|
|
3480
|
+
],
|
|
3481
|
+
avoid: [
|
|
3482
|
+
"Don't use bare `class` as the diagram keyword \u2014 that's a reserved programming-language word, and the engine keyword is `umlclass`.",
|
|
3483
|
+
"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).",
|
|
3484
|
+
"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."
|
|
3485
|
+
],
|
|
3486
|
+
repair: [
|
|
3487
|
+
"A 'malformed relationship' error means no connector glyph was found between two ids \u2014 check the line uses one of `<|--` `<|..` `*--` `o--` `-->` `..>` `--` `..`.",
|
|
3488
|
+
"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.",
|
|
3489
|
+
"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."
|
|
3490
|
+
]
|
|
3491
|
+
},
|
|
3492
|
+
faulttree: {
|
|
3493
|
+
type: "faulttree",
|
|
3494
|
+
header: 'faulttree "Title"',
|
|
3495
|
+
mode: "flat event/gate declarations wired by id (top + gates + leaves)",
|
|
3496
|
+
forms: [
|
|
3497
|
+
"analysis: cutsets, probability",
|
|
3498
|
+
'top T "System fails" = OR(G1, G2)',
|
|
3499
|
+
'gate G1 "Sub-fault" = AND(A, B)',
|
|
3500
|
+
'basic A "Component A fails" p: 0.01',
|
|
3501
|
+
'undeveloped EXT "External cause"',
|
|
3502
|
+
'house HX "Power on" state: 1',
|
|
3503
|
+
"RELIEF = VOTING(2/3; PRV_A, PRV_B, PRV_C)",
|
|
3504
|
+
"OVP = INHIBIT(PUMP) if HEATER"
|
|
3505
|
+
],
|
|
3506
|
+
prefer: [
|
|
3507
|
+
"Single-word keyword is `faulttree` (alias `fta`). Declare exactly one `top` event.",
|
|
3508
|
+
"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).",
|
|
3509
|
+
"Gate expressions: AND/OR/XOR(a, b, \u2026), VOTING(k/n; \u2026), INHIBIT(x) if cond, PAND(a, b) order: a, b.",
|
|
3510
|
+
"Put `p: 0.001` (or scientific `1e-3`) on basic/undeveloped events; the engine computes minimal cut sets and P(top).",
|
|
3511
|
+
"Use `prob: rare` (default), `mcub`, or `exact`; `house \u2026 state: 0|1` switches branches on/off."
|
|
3512
|
+
],
|
|
3513
|
+
avoid: [
|
|
3514
|
+
"Don't nest by indentation \u2014 fault tree is flat declaration + id reference (so repeated/shared events are unambiguous).",
|
|
3515
|
+
"Don't attach `if <cond>` to anything but INHIBIT (or `order:` to anything but PAND).",
|
|
3516
|
+
"Don't declare more than one `top`, and don't create cycles (a gate may not transitively reference itself)."
|
|
3517
|
+
],
|
|
3518
|
+
repair: [
|
|
3519
|
+
"'references undefined event' means a gate input id was never declared \u2014 add the `basic`/`gate`/\u2026 line.",
|
|
3520
|
+
"'must have exactly one top' \u2014 keep a single `top`; downgrade the others to `gate`.",
|
|
3521
|
+
"'VOTING k/n: n must equal the number of inputs' \u2014 make n match the listed inputs.",
|
|
3522
|
+
"If P(top) shows 'n/a', a basic event in a cut set is missing its `p:`."
|
|
3523
|
+
]
|
|
3524
|
+
},
|
|
3525
|
+
bowtie: {
|
|
3526
|
+
type: "bowtie",
|
|
3527
|
+
header: 'bowtie "Title"',
|
|
3528
|
+
mode: "indentation-structured: hazard + topevent, then threat/consequence blocks with indented barrier chains",
|
|
3529
|
+
forms: [
|
|
3530
|
+
'hazard "Working at height"',
|
|
3531
|
+
'topevent "Person falls from height"',
|
|
3532
|
+
'threat "Guardrail removed for access"',
|
|
3533
|
+
' prevent "Permit-to-work system"',
|
|
3534
|
+
' prevent "Temporary edge protection"',
|
|
3535
|
+
' escalation "Edge protection not inspected"',
|
|
3536
|
+
' barrier "Pre-use inspection regime"',
|
|
3537
|
+
'consequence "Fatality"',
|
|
3538
|
+
' mitigate "Fall-arrest harness"'
|
|
3539
|
+
],
|
|
3540
|
+
prefer: [
|
|
3541
|
+
"Single-word keyword is `bowtie`. Declare exactly one `topevent` (the knot) and an optional `hazard` header.",
|
|
3542
|
+
"Each `threat` needs \u2265 1 indented `prevent` barrier; each `consequence` needs \u2265 1 indented `mitigate` barrier (the engine rejects a bare threat/consequence).",
|
|
3543
|
+
"Barrier order = declaration order (first = outermost, nearest the threat/consequence; last = innermost, nearest the knot).",
|
|
3544
|
+
"`escalation` nests (4 spaces) under the `prevent`/`mitigate` barrier it degrades; an escalation-factor `barrier` nests (6 spaces) under the escalation.",
|
|
3545
|
+
"Bowtie is qualitative \u2014 no probabilities. For Boolean gates + cut sets behind one threat, use a separate `faulttree`."
|
|
3546
|
+
],
|
|
3547
|
+
avoid: [
|
|
3548
|
+
"Don't put a `prevent` before any `threat`, or a `mitigate` before any `consequence` \u2014 they bind to the most recent one.",
|
|
3549
|
+
"Don't leave a threat or consequence with no barrier \u2014 that is a Swiss-cheese cartoon, not a bowtie (it is rejected).",
|
|
3550
|
+
"Don't float an `escalation` on its own \u2014 it must follow a barrier line.",
|
|
3551
|
+
"Don't declare more than one `topevent` or more than one `hazard`."
|
|
3552
|
+
],
|
|
3553
|
+
repair: [
|
|
3554
|
+
"'has no preventative barrier' / 'no mitigative barrier' \u2014 add a `prevent`/`mitigate` line under the threat/consequence.",
|
|
3555
|
+
"'not attached to a barrier' \u2014 move the `escalation` so it follows a `prevent`/`mitigate` line.",
|
|
3556
|
+
"'needs at least one threat/consequence' \u2014 a one-wing diagram is a fault tree or event tree; add the missing wing.",
|
|
3557
|
+
"'exactly one top event' \u2014 keep a single `topevent` line."
|
|
3558
|
+
]
|
|
3144
3559
|
}
|
|
3145
3560
|
};
|
|
3146
3561
|
function getGenerationProfile(type) {
|
|
@@ -3224,7 +3639,7 @@ function getExamples(type, opts = {}) {
|
|
|
3224
3639
|
function validateDsl(type, dsl) {
|
|
3225
3640
|
const resolvedType = type ? resolveDiagramType(type) : void 0;
|
|
3226
3641
|
const config = type ? { type: resolvedType ?? type } : void 0;
|
|
3227
|
-
const result =
|
|
3642
|
+
const result = chunkMLLARXOI_cjs.parseResult(dsl, config);
|
|
3228
3643
|
if (result.ok) {
|
|
3229
3644
|
return { ok: true, type: result.type };
|
|
3230
3645
|
}
|
|
@@ -3242,7 +3657,7 @@ function renderDsl(type, dsl, options = {}) {
|
|
|
3242
3657
|
...options,
|
|
3243
3658
|
...type ? { type: resolvedType ?? type } : {}
|
|
3244
3659
|
};
|
|
3245
|
-
const result =
|
|
3660
|
+
const result = chunkMLLARXOI_cjs.renderResult(dsl, config);
|
|
3246
3661
|
if (result.ok) {
|
|
3247
3662
|
return {
|
|
3248
3663
|
ok: true,
|
|
@@ -3295,5 +3710,5 @@ exports.listDiagrams = listDiagrams;
|
|
|
3295
3710
|
exports.renderDsl = renderDsl;
|
|
3296
3711
|
exports.resolveDiagramType = resolveDiagramType;
|
|
3297
3712
|
exports.validateDsl = validateDsl;
|
|
3298
|
-
//# sourceMappingURL=chunk-
|
|
3299
|
-
//# sourceMappingURL=chunk-
|
|
3713
|
+
//# sourceMappingURL=chunk-CMZKAASF.cjs.map
|
|
3714
|
+
//# sourceMappingURL=chunk-CMZKAASF.cjs.map
|