@descent-vtt/spec-graph 0.2.0 → 0.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md ADDED
@@ -0,0 +1,105 @@
1
+ # Changelog
2
+
3
+ Notable changes, newest first. Versions follow [semver](https://semver.org):
4
+ a patch fixes behaviour without asking anything of a repository that upgrades.
5
+
6
+ ## 0.2.2
7
+
8
+ ### Fixed
9
+
10
+ **A link to a file holding a register resolved to one of its rows.** Both halves
11
+ of this needed no flag to trigger and no configuration to fix: a repository that
12
+ keeps no registers is unaffected, and one that does needs no change beyond the
13
+ upgrade.
14
+
15
+ Since 0.1.3 a register has yielded one specification per row or per section
16
+ ([ADR-0009](docs/adr/0009-a-specification-is-a-region.md)), and every one of
17
+ those carried the file's path into the resolver's path index. That index keeps
18
+ whichever entry was written last, so the file's own entry was overwritten by its
19
+ final region, and:
20
+
21
+ - **A plain path link bound to the wrong node, silently.** `[A](docs/A.md)`
22
+ pointing at a file whose last table row is `FR-2` produced an edge to `FR-2`.
23
+ No diagnostic said so, and where the link carried a load-bearing relation -
24
+ `depends on`, `assumes` - the graph asserted a dependency nobody wrote. This
25
+ is the more serious half, because a wrong edge is invisible in a report that
26
+ says everything is consistent.
27
+ - **An anchored link reported a broken reference that was not broken.**
28
+ `[x](docs/A.md#how-to-read-this-document)` resolved to a row, and a row's
29
+ anchor set holds only the headings inside its own span - none, for a table
30
+ row - so a heading plainly present in the file was reported missing.
31
+
32
+ Both forms of register were affected, the table form and the heading form.
33
+
34
+ A region now stays out of the path index; only the file it lives in answers to
35
+ its path. The region keeps `path` on its node, so findings still name the file
36
+ it is written in and `document[path=docs/A.md]` still lists the file together
37
+ with its regions.
38
+
39
+ Found while adopting spec-graph in
40
+ [VirtualCortex](https://github.com/DescentVTT/VirtualCortex), where a
41
+ requirements table headed `Status` was enough to trigger it.
42
+
43
+ ## 0.2.1
44
+
45
+ ### Fixed
46
+
47
+ - One written citation is one reference. `Superseded by ADR-0009` in a status
48
+ section was read twice - once by the status reader, which reports the whole
49
+ line, and once by prose scanning, which reports the identifier inside it.
50
+ Invisible while the target resolved, because two identical edges collapse into
51
+ one; two findings on one line the moment it did not.
52
+
53
+ ## 0.2.0
54
+
55
+ ### Added
56
+
57
+ - **Historical records.** A journal, changelog or set of minutes is a log of
58
+ what was decided, not a decision. `record` is a lifecycle phase, declared by
59
+ `historyPatterns` in the configuration or by `<!-- @spec-history -->`, and
60
+ never guessed from a filename. Its links are still checked and work handed
61
+ *into* it is still a ghost handover; its own obligations and lifecycle are
62
+ not. See [ADR-0011](docs/adr/0011-a-record-is-not-a-specification.md).
63
+ - **Baselines.** `--record-baseline` writes today's findings as accepted debt;
64
+ `--baseline` reports only what is new since. Keyed on the specification and
65
+ the citation rather than on a line number, so it survives edits, reordering
66
+ and renames. Paid debt is reported, not failed. See
67
+ [ADR-0012](docs/adr/0012-a-baseline-is-a-ratchet.md).
68
+
69
+ ### Fixed
70
+
71
+ - The published tarball shipped source maps pointing at `../src/*.ts`, which was
72
+ not in the package. They are self-contained now, and the declaration maps that
73
+ could never resolve are gone.
74
+
75
+ ## 0.1.3
76
+
77
+ ### Added
78
+
79
+ - **A specification is a region of a file, not a file.** A register kept as
80
+ headings or as a table yields one specification per decision, each with its
81
+ own lifecycle, obligations and relations. See
82
+ [ADR-0009](docs/adr/0009-a-specification-is-a-region.md).
83
+ - **Repository configuration.** `.spec-graph.json`, `spec-graph.config.json`, or
84
+ a `"spec-graph"` key in `package.json`, with family allow and deny rules. See
85
+ [ADR-0010](docs/adr/0010-configuration-belongs-to-the-repository.md).
86
+
87
+ ## 0.1.2
88
+
89
+ ### Added
90
+
91
+ - `--ignore-ref`, for repositories where `[[...]]` tags a concept rather than
92
+ naming a file. See
93
+ [ADR-0008](docs/adr/0008-wiki-links-carry-no-path.md).
94
+
95
+ ## 0.1.1
96
+
97
+ ### Added
98
+
99
+ - `--strict`, raising every warning to an error. An explicit `--rule` still
100
+ wins, so `--strict --rule x=warn` exempts one rule rather than forcing a
101
+ choice between all of it and none.
102
+
103
+ ## 0.1.0
104
+
105
+ First release.
package/dist/extract.js CHANGED
@@ -843,8 +843,56 @@ function extractReferences(context) {
843
843
  opportunistic: true,
844
844
  });
845
845
  }
846
+ return withoutOverlaps(out);
847
+ }
848
+ /**
849
+ * Collapses candidates that describe the same written citation.
850
+ *
851
+ * `Superseded by ADR-0009` in a status section is read twice: the status
852
+ * reader reports the whole line, and prose scanning reports the identifier
853
+ * inside it. One written citation is one reference - so when the target
854
+ * resolves it must not become two edges, and when it does not it must not
855
+ * become two findings on one line a reader can only fix once.
856
+ *
857
+ * The narrower span wins, because it points at the text that has to change.
858
+ *
859
+ * Only overlapping spans collapse. Two sentences citing the same missing
860
+ * document are two citations, and silently reporting one of them would leave
861
+ * the other to be discovered on the next run.
862
+ */
863
+ function withoutOverlaps(candidates) {
864
+ const out = [];
865
+ for (const candidate of candidates) {
866
+ const index = out.findIndex((other) => other.kind === candidate.kind &&
867
+ other.from === candidate.from &&
868
+ other.inverted === candidate.inverted &&
869
+ normaliseRef(other.target) === normaliseRef(candidate.target) &&
870
+ overlapping(other.declaredAt, candidate.declaredAt));
871
+ if (index === -1) {
872
+ out.push(candidate);
873
+ continue;
874
+ }
875
+ const held = out[index];
876
+ // The status reader runs before prose scanning, so today the wider span is
877
+ // always the one already held and this comparison always replaces it. It is
878
+ // written as a comparison rather than an unconditional swap because which
879
+ // reader runs first is not a property worth depending on, and a mutant that
880
+ // makes it unconditional is equivalent only by that accident.
881
+ if (width(candidate.declaredAt) < width(held.declaredAt))
882
+ out[index] = candidate;
883
+ }
846
884
  return out;
847
885
  }
886
+ const width = (ref) => ref.span.end.offset - ref.span.start.offset;
887
+ /**
888
+ * Whether two spans cover any of the same text.
889
+ *
890
+ * Offsets alone, with no file comparison: every candidate here was built from
891
+ * one scan of one file, so there is no second file for them to be offsets into.
892
+ */
893
+ function overlapping(a, b) {
894
+ return a.span.start.offset < b.span.end.offset && b.span.start.offset < a.span.end.offset;
895
+ }
848
896
  /** The item whose block contains an offset, if any. */
849
897
  function ownerOf(items, offset) {
850
898
  let best = null;
@@ -1 +1 @@
1
- {"version":3,"file":"extract.js","sourceRoot":"","sources":["../src/extract.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,YAAY,EAAE,eAAe,EAAkB,MAAM,iBAAiB,CAAC;AAChG,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,YAAY,EAAyB,OAAO,EAAE,MAAM,eAAe,CAAC;AACnG,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,OAAO,EAAE,WAAW,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AAC7G,OAAO,EAAE,YAAY,EAAE,OAAO,EAAkD,MAAM,eAAe,CAAC;AACtG,OAAO,EAAE,wBAAwB,EAAE,QAAQ,EAA4B,MAAM,eAAe,CAAC;AAC7F,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAC9C,OAAO,EAAE,KAAK,EAAkB,MAAM,aAAa,CAAC;AAUpD,OAAO,EAAE,gBAAgB,EAAE,QAAQ,EAAE,QAAQ,EAAkB,MAAM,WAAW,CAAC;AA6DjF,gFAAgF;AAChF,gFAAgF;AAChF,gFAAgF;AAEhF,qEAAqE;AACrE,MAAM,aAAa,GAAoE;IACrF,UAAU,EAAE,EAAE,IAAI,EAAE,YAAY,EAAE,QAAQ,EAAE,KAAK,EAAE;IACnD,UAAU,EAAE,EAAE,IAAI,EAAE,YAAY,EAAE,QAAQ,EAAE,KAAK,EAAE;IACnD,QAAQ,EAAE,EAAE,IAAI,EAAE,YAAY,EAAE,QAAQ,EAAE,KAAK,EAAE;IACjD,SAAS,EAAE,EAAE,IAAI,EAAE,YAAY,EAAE,QAAQ,EAAE,KAAK,EAAE;IAClD,eAAe,EAAE,EAAE,IAAI,EAAE,YAAY,EAAE,QAAQ,EAAE,IAAI,EAAE;IACvD,eAAe,EAAE,EAAE,IAAI,EAAE,YAAY,EAAE,QAAQ,EAAE,IAAI,EAAE;IACvD,aAAa,EAAE,EAAE,IAAI,EAAE,YAAY,EAAE,QAAQ,EAAE,IAAI,EAAE;IACrD,cAAc,EAAE,EAAE,IAAI,EAAE,YAAY,EAAE,QAAQ,EAAE,IAAI,EAAE;IACtD,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE;IAC3C,OAAO,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE;IAC5C,YAAY,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE;IAChD,YAAY,EAAE,EAAE,IAAI,EAAE,YAAY,EAAE,QAAQ,EAAE,KAAK,EAAE;IACrD,YAAY,EAAE,EAAE,IAAI,EAAE,YAAY,EAAE,QAAQ,EAAE,KAAK,EAAE;IACrD,QAAQ,EAAE,EAAE,IAAI,EAAE,YAAY,EAAE,QAAQ,EAAE,KAAK,EAAE;IACjD,OAAO,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,KAAK,EAAE;IAC7C,YAAY,EAAE,EAAE,IAAI,EAAE,YAAY,EAAE,QAAQ,EAAE,KAAK,EAAE;IACrD,MAAM,EAAE,EAAE,IAAI,EAAE,YAAY,EAAE,QAAQ,EAAE,IAAI,EAAE;IAC9C,cAAc,EAAE,EAAE,IAAI,EAAE,cAAc,EAAE,QAAQ,EAAE,KAAK,EAAE;IACzD,cAAc,EAAE,EAAE,IAAI,EAAE,cAAc,EAAE,QAAQ,EAAE,KAAK,EAAE;IACzD,YAAY,EAAE,EAAE,IAAI,EAAE,cAAc,EAAE,QAAQ,EAAE,KAAK,EAAE;IACvD,OAAO,EAAE,EAAE,IAAI,EAAE,YAAY,EAAE,QAAQ,EAAE,KAAK,EAAE;IAChD,YAAY,EAAE,EAAE,IAAI,EAAE,YAAY,EAAE,QAAQ,EAAE,KAAK,EAAE;IACrD,UAAU,EAAE,EAAE,IAAI,EAAE,YAAY,EAAE,QAAQ,EAAE,KAAK,EAAE;IACnD,UAAU,EAAE,EAAE,IAAI,EAAE,YAAY,EAAE,QAAQ,EAAE,KAAK,EAAE;IACnD,IAAI,EAAE,EAAE,IAAI,EAAE,YAAY,EAAE,QAAQ,EAAE,KAAK,EAAE;CAC9C,CAAC;AAEF;;;;;;;GAOG;AACH,MAAM,UAAU,GAAiF;IAC/F;QACE,IAAI,EAAE,YAAY;QAClB,QAAQ,EAAE,IAAI;QACd,OAAO,EAAE,CAAC,eAAe,EAAE,eAAe,EAAE,aAAa,EAAE,cAAc,EAAE,eAAe,EAAE,aAAa,CAAC;KAC3G;IACD,EAAE,IAAI,EAAE,YAAY,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,YAAY,EAAE,YAAY,EAAE,UAAU,EAAE,WAAW,EAAE,YAAY,CAAC,EAAE;IACrH,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,YAAY,EAAE,YAAY,EAAE,cAAc,EAAE,YAAY,CAAC,EAAE;IACvG,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,QAAQ,EAAE,SAAS,EAAE,WAAW,EAAE,SAAS,CAAC,EAAE;IAC3F;QACE,IAAI,EAAE,cAAc;QACpB,QAAQ,EAAE,KAAK;QACf,OAAO,EAAE;YACP,cAAc;YACd,aAAa;YACb,aAAa;YACb,UAAU;YACV,UAAU;YACV,SAAS;YACT,YAAY;YACZ,YAAY;YACZ,eAAe;YACf,WAAW;YACX,aAAa;YACb,cAAc;YACd,cAAc;YACd,aAAa;YACb,cAAc;YACd,cAAc;YACd,WAAW;YACX,SAAS;YACT,YAAY;YACZ,UAAU;YACV,oBAAoB;YACpB,qBAAqB;YACrB,oBAAoB;YACpB,oBAAoB;YACpB,qBAAqB;YACrB,kBAAkB;YAClB,mBAAmB;YACnB,kBAAkB;YAClB,mBAAmB;SACpB;KACF;IACD;QACE,IAAI,EAAE,YAAY;QAClB,QAAQ,EAAE,KAAK;QACf,OAAO,EAAE,CAAC,YAAY,EAAE,YAAY,EAAE,YAAY,EAAE,aAAa,EAAE,UAAU,EAAE,UAAU,EAAE,cAAc,CAAC;KAC3G;IACD,EAAE,IAAI,EAAE,YAAY,EAAE,QAAQ,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,QAAQ,EAAE,UAAU,CAAC,EAAE;IACvE;QACE,IAAI,EAAE,YAAY;QAClB,QAAQ,EAAE,KAAK;QACf,OAAO,EAAE,CAAC,YAAY,EAAE,WAAW,EAAE,cAAc,EAAE,UAAU,EAAE,WAAW,EAAE,UAAU,EAAE,WAAW,CAAC;KACvG;IACD,EAAE,IAAI,EAAE,YAAY,EAAE,QAAQ,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,gBAAgB,CAAC,EAAE;IACnE;QACE,IAAI,EAAE,SAAS;QACf,QAAQ,EAAE,KAAK;QACf,OAAO,EAAE;YACP,SAAS;YACT,UAAU;YACV,sBAAsB;YACtB,eAAe;YACf,mBAAmB;YACnB,mBAAmB;YACnB,cAAc;YACd,iBAAiB;YACjB,gBAAgB;YAChB,gBAAgB;YAChB,oBAAoB;YACpB,gBAAgB;YAChB,aAAa;YACb,aAAa;YACb,eAAe;YACf,UAAU;YACV,cAAc;YACd,cAAc;YACd,0EAA0E;YAC1E,0EAA0E;YAC1E,qEAAqE;YACrE,YAAY;YACZ,aAAa;YACb,aAAa;YACb,eAAe;YACf,YAAY;YACZ,WAAW;YACX,YAAY;YACZ,YAAY;YACZ,YAAY;YACZ,cAAc;YACd,QAAQ;YACR,KAAK;YACL,SAAS;YACT,OAAO;SACR;KACF;CACF,CAAC;AAEF;;;;;;;;;GASG;AACH,MAAM,QAAQ,GAAG,0EAA0E,CAAC;AAE5F,yEAAyE;AACzE,MAAM,WAAW,GAAG,EAAE,CAAC;AAEvB;;;;;;;;;GASG;AACH,MAAM,WAAW,GAAwC,IAAI,GAAG,CAC9D,UAAU,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE,CAC1B,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,CAAU,CAAC,CAC9F,CACF,CAAC;AAEF,MAAM,YAAY,GAAG,IAAI,MAAM,CAC7B,yBAAyB,CAAC,GAAG,WAAW,CAAC,IAAI,EAAE,CAAC;KAC7C,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,MAAM,CAAC;KACnC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,qBAAqB,EAAE,MAAM,CAAC,CAAC;KAC9D,IAAI,CAAC,GAAG,CAAC,qBAAqB,EACjC,IAAI,CACL,CAAC;AAEF,2EAA2E;AAC3E,MAAM,aAAa,GAAwB,IAAI,GAAG,CAAC;IACjD,UAAU;IACV,YAAY;IACZ,WAAW;IACX,SAAS;IACT,cAAc;IACd,mBAAmB;IACnB,mBAAmB;IACnB,OAAO;IACP,iBAAiB;IACjB,WAAW;IACX,SAAS;IACT,WAAW;IACX,YAAY;IACZ,kBAAkB;IAClB,cAAc;IACd,SAAS;IACT,UAAU;IACV,kBAAkB;IAClB,WAAW;IACX,OAAO;CACR,CAAC,CAAC;AAEH,sEAAsE;AACtE,MAAM,mBAAmB,GAAwB,IAAI,GAAG,CAAC;IACvD,gBAAgB;IAChB,eAAe;IACf,sBAAsB;IACtB,sBAAsB;IACtB,WAAW;IACX,aAAa;IACb,cAAc;IACd,SAAS;IACT,MAAM;IACN,OAAO;IACP,OAAO;IACP,OAAO;IACP,YAAY;IACZ,YAAY;IACZ,YAAY;IACZ,WAAW;IACX,WAAW;IACX,WAAW;IACX,YAAY;IACZ,aAAa;IACb,uBAAuB;IACvB,OAAO;IACP,WAAW;IACX,YAAY;IACZ,gBAAgB;IAChB,kBAAkB;IAClB,UAAU;IACV,aAAa;IACb,aAAa;IACb,UAAU;CACX,CAAC,CAAC;AAEH;;;;;GAKG;AACH,MAAM,YAAY,GAAwB,IAAI,GAAG,CAAC;IAChD,GAAG;IACH,KAAK;IACL,SAAS;IACT,GAAG;IACH,IAAI;IACJ,KAAK;IACL,QAAQ;IACR,OAAO;IACP,KAAK;IACL,SAAS;IACT,MAAM;IACN,KAAK;IACL,MAAM;IACN,MAAM;IACN,IAAI;IACJ,KAAK;IACL,MAAM;IACN,IAAI;IACJ,KAAK;IACL,MAAM;IACN,IAAI;IACJ,OAAO;IACP,IAAI;IACJ,KAAK;IACL,OAAO;IACP,KAAK;IACL,IAAI;IACJ,MAAM;IACN,OAAO;IACP,KAAK;IACL,KAAK;IACL,KAAK;IACL,IAAI;IACJ,MAAM;IACN,GAAG;IACH,GAAG;IACH,KAAK;IACL,MAAM;IACN,KAAK;IACL,MAAM;IACN,MAAM;IACN,KAAK;IACL,KAAK;IACL,KAAK;IACL,MAAM;IACN,QAAQ;IACR,MAAM;IACN,IAAI;IACJ,GAAG;IACH,KAAK;CACN,CAAC,CAAC;AAEH,MAAM,QAAQ,GAAG,mDAAmD,CAAC;AAmBrE;;;;;;;GAOG;AACH,MAAM,UAAU,qBAAqB,CAAC,KAAmB;IACvD,MAAM,KAAK,GAAG,eAAe,CAAC,KAAK,CAAC,CAAC;IACrC,OAAO,KAAK,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,GAAI,KAAK,CAAC,iBAAyC,CAAC,CAAC;AAC5F,CAAC;AAED,yEAAyE;AACzE,MAAM,UAAU,eAAe,CAAC,KAAmB;IACjD,MAAM,OAAO,GAAG,YAAY,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACzC,MAAM,UAAU,GAAG,eAAe,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IACrD,IAAI,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,aAAa,CAAC;QAAE,OAAO,IAAI,CAAC;IAElE,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC;IAC5B,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC;IACxB,MAAM,QAAQ,GAAmB,EAAE,CAAC;IACpC,MAAM,EAAE,GAAG,CAAC,KAAa,EAAE,GAAW,EAAa,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,CAAC,CAAC;IAErF,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;QACnC,KAAK,MAAM,OAAO,IAAI,SAAS,CAAC,iBAAiB,EAAE,CAAC;YAClD,QAAQ,CAAC,IAAI,CAAC;gBACZ,OAAO,EAAE,sBAAsB,OAAO,SAAS,SAAS,CAAC,IAAI,EAAE;gBAC/D,EAAE,EAAE,EAAE,CAAC,SAAS,CAAC,KAAK,EAAE,SAAS,CAAC,GAAG,CAAC;aACvC,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,MAAM,OAAO,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,gBAAgB,CAAC,OAAO,CAAC,WAAW,CAAC,GAAG,EAAE,OAAO,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAChH,MAAM,KAAK,GAAG,IAAI,GAAG,EAAqB,CAAC;IAC3C,KAAK,MAAM,KAAK,IAAI,OAAO;QAAE,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IAEzD,MAAM,EAAE,GAAG,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,IAAI,IAAI,CAAC;IAC/D,MAAM,aAAa,GAAG,UAAU,CAAC,KAAK,EAAE,OAAO,CAAC,IAAI,IAAI,CAAC;IAEzD,MAAM,UAAU,GAAG,CAAC,UAAyB,EAAE,SAA2B,EAAoB,EAAE,CAC9F,QAAQ,CAAC;QACP,IAAI,EAAE,KAAK,CAAC,IAAI;QAChB,UAAU;QACV,eAAe,EAAE;YACf,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YACpD,GAAG,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;YACjC,GAAG,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;SAChC;QACD,OAAO,EAAE,EAAE,EAAE,IAAI,IAAI,IAAI;KAC1B,CAAC,CAAC;IAEL,8EAA8E;IAC9E,2EAA2E;IAC3E,6EAA6E;IAC7E,0EAA0E;IAC1E,MAAM,WAAW,GAAG,UAAU,CAAC,aAAa,EAAE,IAAI,CAAC,CAAC;IACpD,MAAM,kBAAkB,GAAG,wBAAwB,CAAC,OAAO,EAAE,UAAU,EAAE,WAAW,CAAC,EAAE,CAAC,CAAC;IACzF,MAAM,aAAa,GACjB,UAAU,CAAC,IAAI,CACb,CAAC,SAAS,EAAE,EAAE,CACZ,SAAS,CAAC,IAAI,KAAK,WAAW;QAC9B,CAAC,kBAAkB,CAAC,IAAI,CACtB,CAAC,MAAM,EAAE,EAAE,CACT,CAAC,MAAM,CAAC,OAAO,KAAK,IAAI,IAAI,MAAM,CAAC,GAAG,KAAK,IAAI,CAAC;YAChD,SAAS,CAAC,KAAK,IAAI,MAAM,CAAC,KAAK;YAC/B,SAAS,CAAC,GAAG,IAAI,MAAM,CAAC,GAAG,CAC9B,CACJ,IAAI,IAAI,CAAC;IAEZ,MAAM,UAAU,GAAG,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,EAAE,IAAI,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,aAAa,CAAC;IAC9F,MAAM,QAAQ,GAAG,UAAU,KAAK,aAAa,IAAI,aAAa,KAAK,IAAI;QACrE,CAAC,CAAC,WAAW;QACb,CAAC,CAAC,UAAU,CAAC,UAAU,EAAE,aAAa,CAAC,CAAC;IAE1C,MAAM,MAAM,GAAG,UAAU,CAAC,OAAO,EAAE,KAAK,EAAE,aAAa,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;IACtE,MAAM,SAAS,GAAG,aAAa,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC5C,wEAAwE;IACxE,0EAA0E;IAC1E,yCAAyC;IACzC,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,KAAK,IAAI,IAAI,UAAU,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,IAAI,KAAK,cAAc,CAAC,CAAC;IAC1G,MAAM,KAAK,GAAU,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;IAE/F,MAAM,KAAK,GACT,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,EAAE,OAAO,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;QAC5D,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QAC5B,EAAE,EAAE,IAAI;QACR,QAAQ,CAAC,EAAE,CAAC;IAEd,MAAM,QAAQ,GAAiB;QAC7B,EAAE,EAAE,QAAQ,CAAC,EAAE;QACf,IAAI,EAAE,UAAU;QAChB,KAAK;QACL,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;QAC1D,IAAI,EAAE,KAAK,CAAC,IAAI;QAChB,OAAO,EAAE,QAAQ,CAAC,OAAO;QACzB,KAAK;QACL,SAAS,EAAE,MAAM,CAAC,GAAG;QACrB,QAAQ,EAAE,MAAM,CAAC,EAAE;QACnB,WAAW,EAAE,QAAQ,CAAC,OAAO,CAAC;KAC/B,CAAC;IAEF,6EAA6E;IAC7E,mEAAmE;IACnE,MAAM,OAAO,GACX,QAAQ,CAAC,EAAE,KAAK,WAAW,CAAC,EAAE,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,wBAAwB,CAAC,OAAO,EAAE,UAAU,EAAE,QAAQ,CAAC,EAAE,CAAC,CAAC;IACnH,6EAA6E;IAC7E,cAAc;IACd,MAAM,iBAAiB,GAAG,OAAO;SAC9B,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,OAAO,KAAK,IAAI,IAAI,MAAM,CAAC,GAAG,KAAK,IAAI,CAAC;SAClE,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CACd,WAAW,CAAC;QACV,MAAM;QACN,WAAW,EAAE,QAAQ,CAAC,EAAE;QACxB,KAAK;QACL,OAAO;QACP,UAAU;QACV,KAAK;QACL,IAAI;QACJ,SAAS;QACT,MAAM;KACP,CAAC,CACH,CAAC;IAEJ,MAAM,OAAO,GAAG,CAAC,MAAc,EAAU,EAAE;QACzC,MAAM,MAAM,GAAG,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QACzC,IAAI,MAAM,KAAK,IAAI;YAAE,OAAO,QAAQ,CAAC,EAAE,CAAC;QACxC,MAAM,KAAK,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC;QACvE,OAAO,KAAK,EAAE,QAAQ,CAAC,EAAE,IAAI,QAAQ,CAAC,EAAE,CAAC;IAC3C,CAAC,CAAC;IAEF,MAAM,QAAQ,GAAG,YAAY,CAAC,EAAE,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IAC7E,MAAM,UAAU,GAAG,CAAC,MAAc,EAAgB,EAAE;QAClD,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;QAC3B,IAAI,EAAE,KAAK,QAAQ,CAAC,EAAE;YAAE,OAAO,QAAQ,CAAC;QACxC,OAAO,iBAAiB,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,IAAI,QAAQ,CAAC;IACzF,CAAC,CAAC;IAEF,MAAM,aAAa,GAAG,iBAAiB,CAAC;QACtC,OAAO;QACP,UAAU;QACV,QAAQ;QACR,UAAU;QACV,KAAK,EAAE,QAAQ;QACf,KAAK;QACL,MAAM;QACN,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC;QACzD,IAAI;QACJ,KAAK;KACN,CAAC,CAAC;IAEH,iEAAiE;IACjE,MAAM,QAAQ,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,KAAK,QAAQ,CAAC,EAAE,CAAC,CAAC;IAC1E,MAAM,aAAa,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,SAAS,EAAE,QAAQ,CAAC,EAAE,EAAE,QAAQ,CAAC,CAAC,CAAC;IACvG,MAAM,OAAO,GAAG,IAAI,GAAG,CAAS,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IAErE,MAAM,MAAM,GAAG,iBAAiB,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QAC9C,GAAG,IAAI,CAAC,SAAS;QACjB,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,KAAK,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;QACpE,UAAU,EAAE;YACV,uEAAuE;YACvE,2BAA2B;YAC3B,GAAG,IAAI,CAAC,SAAS,CAAC,UAAU;YAC5B,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,SAAS,EAAE,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,QAAQ,CAAC,CAAC;SACzF;KACF,CAAC,CAAC,CAAC;IAEJ,OAAO;QACL,QAAQ;QACR,KAAK,EAAE,QAAQ;QACf,UAAU,EAAE,aAAa;QACzB,QAAQ;QACR,OAAO;QACP,QAAQ;QACR,OAAO;QACP,iBAAiB,EAAE,MAAM;QACzB,WAAW,EAAE,IAAI;KAClB,CAAC;AACJ,CAAC;AAED,8EAA8E;AAC9E,SAAS,SAAS,CAAC,SAA6B,EAAE,UAAkB,EAAE,KAA0B;IAC9F,IAAI,SAAS,CAAC,IAAI,KAAK,UAAU;QAAE,OAAO,IAAI,CAAC;IAC/C,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,KAAK,SAAS,CAAC,IAAI,CAAC,CAAC;IAC/D,OAAO,KAAK,EAAE,QAAQ,KAAK,UAAU,CAAC;AACxC,CAAC;AAqBD;;;;;;;;;GASG;AACH,SAAS,WAAW,CAAC,OAAoB;IACvC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC;IAC3E,MAAM,EAAE,GAAG,CAAC,KAAa,EAAE,GAAW,EAAa,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,CAAC,CAAC;IAErF,MAAM,QAAQ,GAAG,QAAQ,CAAC;QACxB,IAAI,EAAE,KAAK,CAAC,IAAI;QAChB,UAAU,EAAE,MAAM,CAAC,UAAU;QAC7B,eAAe,EAAE,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,EAAE;QAC9E,OAAO,EAAE,MAAM,CAAC,KAAK;QACrB,kBAAkB,EAAE,KAAK;KAC1B,CAAC,CAAC;IAEH,MAAM,cAAc,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAClF,MAAM,SAAS,GAAG,cAAc,EAAE,KAAK,IAAI,MAAM,CAAC,MAAM,EAAE,IAAI,IAAI,IAAI,CAAC;IACvE,MAAM,QAAQ,GAAG,cAAc;QAC7B,CAAC,CAAC,EAAE,CAAC,cAAc,CAAC,KAAK,EAAE,cAAc,CAAC,GAAG,CAAC;QAC9C,CAAC,CAAC,MAAM,CAAC,MAAM;YACb,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC;YAC5C,CAAC,CAAC,IAAI,CAAC;IACX,MAAM,aAAa,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;IAEzC,MAAM,QAAQ,GAAiB;QAC7B,EAAE,EAAE,QAAQ,CAAC,EAAE;QACf,IAAI,EAAE,UAAU;QAChB,KAAK,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,OAAO,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,MAAM,CAAC,KAAK,IAAI,QAAQ,CAAC,EAAE;QACxG,uEAAuE;QACvE,EAAE,EAAE,EAAE,CAAC,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,OAAO,EAAE,GAAG,IAAI,MAAM,CAAC,GAAG,EAAE,GAAG,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC;QAChG,IAAI,EAAE,KAAK,CAAC,IAAI;QAChB,OAAO,EAAE,QAAQ,CAAC,OAAO;QACzB,yEAAyE;QACzE,2EAA2E;QAC3E,iDAAiD;QACjD,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,aAAa,KAAK,SAAS,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,SAAS;QAClF,SAAS;QACT,QAAQ;QACR,WAAW,EAAE,EAAE;KAChB,CAAC;IAEF,MAAM,OAAO,GAAG,IAAI,GAAG,CACrB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,IAAI,MAAM,CAAC,KAAK,IAAI,CAAC,CAAC,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CACnG,CAAC;IAEF,8EAA8E;IAC9E,MAAM,UAAU,GAAyB,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;QAC3E,IAAI,EAAE,QAAQ,CAAC,IAAI;QACnB,IAAI,EAAE,QAAQ,CAAC,EAAE;QACjB,MAAM,EAAE,QAAQ,CAAC,MAAM;QACvB,MAAM,EAAE,cAAuB;QAC/B,UAAU,EAAE,EAAE,CAAC,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,CAAC;QAC5C,GAAG,EAAE,GAAG,QAAQ,CAAC,MAAM,KAAK,QAAQ,CAAC,MAAM,EAAE;QAC7C,QAAQ,EAAE,QAAQ,CAAC,QAAQ;QAC3B,aAAa,EAAE,KAAK;KACrB,CAAC,CAAC,CAAC;IAEJ,OAAO;QACL,MAAM;QACN,QAAQ;QACR,SAAS,EAAE;YACT,QAAQ;YACR,KAAK,EAAE,EAAE;YACT,UAAU;YACV,QAAQ,EAAE,EAAE;YACZ,OAAO;YACP,QAAQ;YACR,OAAO;YACP,iBAAiB,EAAE,EAAE;YACrB,WAAW,EAAE,OAAO,CAAC,WAAW;SACjC;KACF,CAAC;AACJ,CAAC;AAYD;;;;;;;GAOG;AACH,SAAS,UAAU,CACjB,OAAwB,EACxB,KAAqC,EACrC,aAA+B,EAC/B,KAAgB,EAChB,IAAY;IAEZ,IAAI,aAAa,EAAE,CAAC;QAClB,MAAM,QAAQ,GAAG,IAAI,CAAC,aAAa,EAAE,QAAQ,CAAC,CAAC;QAC/C,IAAI,QAAQ,EAAE,CAAC;YACb,OAAO;gBACL,GAAG,EAAE,QAAQ,CAAC,KAAK;gBACnB,EAAE,EAAE,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,CAAC;gBACpD,KAAK,EAAE,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC;aAC/B,CAAC;QACJ,CAAC;IACH,CAAC;IAED,KAAK,MAAM,GAAG,IAAI,WAAW,EAAE,CAAC;QAC9B,MAAM,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAC7B,IAAI,CAAC,KAAK;YAAE,SAAS;QACrB,MAAM,GAAG,GAAG,OAAO,KAAK,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACnF,IAAI,GAAG,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC;YAAE,SAAS;QACtC,OAAO;YACL,GAAG;YACH,EAAE,EAAE,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,KAAK,CAAC,UAAU,EAAE,KAAK,CAAC,GAAG,CAAC;YACnD,KAAK,EAAE,OAAO,CAAC,GAAG,CAAC;SACpB,CAAC;IACJ,CAAC;IAED,MAAM,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,eAAe,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IACtE,IAAI,OAAO,EAAE,CAAC;QACZ,MAAM,IAAI,GAAG,iBAAiB,CAAC,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;QACtD,IAAI,IAAI,EAAE,CAAC;YACT,OAAO;gBACL,GAAG,EAAE,IAAI,CAAC,IAAI;gBACd,EAAE,EAAE,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,GAAG,CAAC;gBAC5C,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC;aAC1B,CAAC;QACJ,CAAC;IACH,CAAC;IAED,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC;AACnD,CAAC;AAED,4DAA4D;AAC5D,SAAS,iBAAiB,CACxB,OAAwB,EACxB,WAAmB;IAEnB,KAAK,MAAM,IAAI,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;QACjC,IAAI,IAAI,CAAC,IAAI,IAAI,WAAW;YAAE,SAAS;QACvC,IAAI,IAAI,CAAC,KAAK;YAAE,SAAS;QACzB,IAAI,IAAI,CAAC,IAAI;YAAE,OAAO,IAAI,CAAC;QAC3B,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;QACpC,0DAA0D;QAC1D,IAAI,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,OAAO,IAAI,CAAC;QACzC,MAAM,MAAM,GAAG,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QACjE,wEAAwE;QACxE,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;QACjD,MAAM,KAAK,GAAG,MAAM,GAAG,CAAC,OAAO,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;QACzD,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAC/D,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAeD,SAAS,YAAY,CAAC,OAAoB;IACxC,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,OAAO,CAAC;IAC9D,MAAM,GAAG,GAAe,EAAE,CAAC;IAC3B,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAkB,CAAC;IAE3C,KAAK,MAAM,IAAI,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC;QACrC,MAAM,OAAO,GAAG,aAAa,CAAC,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;QACnD,MAAM,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,mBAAmB,CAAC,GAAG,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;QAC1G,MAAM,SAAS,GAAG,YAAY,CAAC,UAAU,EAAE,WAAW,EAAE,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,GAAG,CAAC,CAAC;QAEnG,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE,mBAAmB,EAAE,SAAS,CAAC;YAAE,SAAS;QAElE,MAAM,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACvC,MAAM,IAAI,GAAG,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAW,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;QAC1F,0EAA0E;QAC1E,yEAAyE;QACzE,MAAM,GAAG,GAAG,GAAG,UAAU,IAAI,IAAI,EAAE,CAAC;QACpC,MAAM,OAAO,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;QAC7C,QAAQ,CAAC,GAAG,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;QAE3B,MAAM,UAAU,GAAG,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;QACnE,MAAM,EAAE,GAAG,GAAG,UAAU,IAAI,UAAU,IAAI,GAAG,IAAI,IAAI,OAAO,EAAE,EAAE,CAAC;QAEjE,MAAM,KAAK,GAAG,gBAAgB,CAAC;YAC7B,IAAI;YACJ,KAAK;YACL,IAAI;YACJ,OAAO;YACP,SAAS;YACT,mBAAmB;SACpB,CAAC,CAAC;QAEH,GAAG,CAAC,IAAI,CAAC;YACP,EAAE;YACF,IAAI,EAAE,MAAM;YACZ,KAAK,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,EAAE,OAAO,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,SAAS,CAAC,IAAI,CAAC,SAAS,CAAC;YACxF,EAAE,EAAE,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,GAAG,CAAC;YAC5C,QAAQ,EAAE,UAAU;YACpB,OAAO;YACP,IAAI,EAAE,SAAS,CAAC,IAAI,CAAC,SAAS,CAAC;YAC/B,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,WAAW,EAAE,KAAK,CAAC,WAAW;YAC9B,QAAQ,EAAE,KAAK,CAAC,QAAQ;YACxB,QAAQ,EAAE,KAAK,CAAC,QAAQ;YACxB,SAAS,EAAE,KAAK,CAAC,SAAS;SAC3B,CAAC,CAAC;IACL,CAAC;IAED,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;;;;;GAOG;AACH,SAAS,YAAY,CAAC,IAAc,EAAE,mBAA4B,EAAE,SAA2B;IAC7F,IAAI,SAAS,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IACpC,IAAI,IAAI,CAAC,QAAQ,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IACxC,OAAO,mBAAmB,IAAI,IAAI,CAAC,KAAK,KAAK,CAAC,CAAC;AACjD,CAAC;AAED,6DAA6D;AAC7D,SAAS,aAAa,CAAC,OAAwB,EAAE,MAAc;IAC7D,MAAM,IAAI,GAAsC,EAAE,CAAC;IACnD,KAAK,MAAM,OAAO,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;QACvC,IAAI,OAAO,CAAC,KAAK,GAAG,MAAM;YAAE,MAAM;QAClC,OAAO,IAAI,CAAC,MAAM,GAAG,CAAC,IAAK,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAuB,CAAC,KAAK,IAAI,OAAO,CAAC,KAAK;YAAE,IAAI,CAAC,GAAG,EAAE,CAAC;QAC1G,IAAI,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;IAC1D,CAAC;IACD,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;AACzC,CAAC;AAED;;;;GAIG;AACH,MAAM,YAAY,GAAG,IAAI,GAAG,EAAkB,CAAC;AAE/C,SAAS,gBAAgB,CAAC,IAAY;IACpC,MAAM,MAAM,GAAG,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IACtC,IAAI,MAAM,KAAK,SAAS;QAAE,OAAO,MAAM,CAAC;IACxC,MAAM,UAAU,GAAG,IAAI;SACpB,WAAW,EAAE;SACb,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC;SACtB,OAAO,CAAC,oBAAoB,EAAE,EAAE,CAAC;SACjC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC;SACpB,IAAI,EAAE,CAAC;IACV,8EAA8E;IAC9E,IAAI,YAAY,CAAC,IAAI,GAAG,IAAI;QAAE,YAAY,CAAC,GAAG,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;IACjE,OAAO,UAAU,CAAC;AACpB,CAAC;AAED;;;;;;GAMG;AACH,SAAS,SAAS,CAAC,IAAY;IAC7B,MAAM,IAAI,GAAG,IAAI;SACd,OAAO,CAAC,0BAA0B,EAAE,IAAI,CAAC;QAC1C,yEAAyE;QACzE,0CAA0C;SACzC,OAAO,CAAC,iCAAiC,EAAE,IAAI,CAAC;SAChD,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC;SACpB,IAAI,EAAE,CAAC;IACV,OAAO,IAAI,CAAC,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,KAAK,CAAC;AAChE,CAAC;AAqBD,iFAAiF;AACjF,SAAS,SAAS,CAAC,OAAkD,EAAE,MAAc;IACnF,OAAO,OAAO,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,MAAM,IAAI,KAAK,CAAC,KAAK,IAAI,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC;AAC9E,CAAC;AAED,SAAS,iBAAiB,CAAC,OAAyB;IAClD,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,UAAU,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,OAAO,CAAC;IAC1G,MAAM,GAAG,GAAyB,EAAE,CAAC;IACrC,MAAM,EAAE,GAAG,CAAC,KAAa,EAAE,GAAW,EAAa,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,CAAC,CAAC;IAErF,gBAAgB;IAChB,KAAK,MAAM,CAAC,GAAG,EAAE,QAAQ,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,aAAa,CAAC,EAAE,CAAC;QAC5D,MAAM,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC;QAClE,IAAI,CAAC,KAAK;YAAE,SAAS;QACrB,KAAK,MAAM,KAAK,IAAI,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;YACpC,MAAM,MAAM,GAAG,WAAW,CAAC,KAAK,CAAC,CAAC;YAClC,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;gBAAE,SAAS;YAClC,GAAG,CAAC,IAAI,CAAC;gBACP,IAAI,EAAE,QAAQ,CAAC,IAAI;gBACnB,IAAI,EAAE,QAAQ,CAAC,EAAE;gBACjB,MAAM;gBACN,MAAM,EAAE,cAAc;gBACtB,UAAU,EAAE,EAAE,CAAC,KAAK,CAAC,UAAU,EAAE,KAAK,CAAC,GAAG,CAAC;gBAC3C,GAAG,EAAE,GAAG,GAAG,KAAK,KAAK,EAAE;gBACvB,QAAQ,EAAE,QAAQ,CAAC,QAAQ;gBAC3B,aAAa,EAAE,KAAK;aACrB,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,6EAA6E;IAC7E,mDAAmD;IACnD,IAAI,MAAM,CAAC,GAAG,IAAI,MAAM,CAAC,EAAE,EAAE,CAAC;QAC5B,KAAK,MAAM,MAAM,IAAI,qBAAqB,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;YACvD,MAAM,OAAO,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC;YACpC,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;gBAAE,SAAS;YACnC,GAAG,CAAC,IAAI,CAAC;gBACP,IAAI,EAAE,YAAY;gBAClB,IAAI,EAAE,QAAQ,CAAC,EAAE;gBACjB,MAAM,EAAE,OAAO;gBACf,MAAM,EAAE,cAAc;gBACtB,UAAU,EAAE,MAAM,CAAC,EAAE;gBACrB,GAAG,EAAE,MAAM,CAAC,GAAG;gBACf,QAAQ,EAAE,IAAI;gBACd,aAAa,EAAE,IAAI;aACpB,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,4BAA4B;IAC5B,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;QACnC,IAAI,SAAS,CAAC,IAAI,KAAK,WAAW;YAAE,SAAS;QAC7C,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,EAAE,MAAM,CAAC,EAAE,KAA6B,CAAC;QACpE,MAAM,EAAE,GAAG,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;QACjC,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;QACrC,IAAI,CAAC,IAAI;YAAE,SAAS;QACpB,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,EAAE,SAAS,CAAC,KAAK,CAAC,IAAI,UAAU,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;QAChF,IAAI,EAAE,EAAE,CAAC;YACP,GAAG,CAAC,IAAI,CAAC;gBACP,IAAI;gBACJ,IAAI,EAAE,KAAK;gBACX,MAAM,EAAE,EAAE,CAAC,KAAK;gBAChB,MAAM,EAAE,WAAW;gBACnB,UAAU,EAAE,EAAE,CAAC,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,GAAG,CAAC;gBAChC,GAAG,EAAE,oBAAoB,IAAI,SAAS,EAAE,CAAC,KAAK,GAAG;gBACjD,QAAQ,EAAE,KAAK;gBACf,aAAa,EAAE,KAAK;aACrB,CAAC,CAAC;QACL,CAAC;QACD,IAAI,IAAI,EAAE,CAAC;YACT,GAAG,CAAC,IAAI,CAAC;gBACP,IAAI;gBACJ,IAAI,EAAE,KAAK;gBACX,MAAM,EAAE,IAAI,CAAC,KAAK;gBAClB,MAAM,EAAE,WAAW;gBACnB,UAAU,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,GAAG,CAAC;gBACpC,GAAG,EAAE,oBAAoB,IAAI,WAAW,IAAI,CAAC,KAAK,GAAG;gBACrD,QAAQ,EAAE,IAAI;gBACd,aAAa,EAAE,KAAK;aACrB,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,6EAA6E;IAC7E,6EAA6E;IAC7E,sDAAsD;IACtD,MAAM,MAAM,GAAG,IAAI,GAAG,EAAU,CAAC;IACjC,KAAK,MAAM,IAAI,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;QACjC,IAAI,IAAI,CAAC,IAAI,KAAK,YAAY;YAAE,SAAS;QACzC,IAAI,SAAS,CAAC,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC;YAAE,SAAS;QAC7C,MAAM,MAAM,GAAG,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACxC,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;YAAE,SAAS;QAClC,IAAI,UAAU,CAAC,MAAM,CAAC;YAAE,SAAS;QAEjC,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;QACtE,MAAM,OAAO,GAAG,aAAa,CAAC,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;QACnD,MAAM,UAAU,GAAG,iBAAiB,CAAC,OAAO,CAAC,MAAM,EAAE,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;QAEpF,MAAM,CAAC,GAAG,CAAC,YAAY,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;QAC9C,GAAG,CAAC,IAAI,CAAC;YACP,IAAI,EAAE,UAAU,CAAC,IAAI;YACrB,IAAI,EAAE,KAAK;YACX,MAAM;YACN,MAAM,EAAE,MAAM;YACd,UAAU,EAAE,EAAE,CAAC,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC;YACvE,GAAG,EAAE,UAAU,CAAC,IAAI,CAAC;YACrB,QAAQ,EAAE,UAAU,CAAC,QAAQ;YAC7B,aAAa,EAAE,KAAK;SACrB,CAAC,CAAC;IACL,CAAC;IAED,6EAA6E;IAC7E,oEAAoE;IACpE,KAAK,MAAM,IAAI,IAAI,kBAAkB,CAAC,OAAO,CAAC,EAAE,CAAC;QAC/C,MAAM,GAAG,GAAG,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACpC,IAAI,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC;YAAE,SAAS;QAC9B,IAAI,SAAS,CAAC,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC;YAAE,SAAS;QAC7C,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;QACtE,MAAM,OAAO,GAAG,aAAa,CAAC,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;QACnD,MAAM,UAAU,GAAG,iBAAiB,CAAC,OAAO,CAAC,MAAM,EAAE,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;QACpF,GAAG,CAAC,IAAI,CAAC;YACP,IAAI,EAAE,UAAU,CAAC,IAAI;YACrB,IAAI,EAAE,KAAK;YACX,MAAM,EAAE,IAAI,CAAC,IAAI;YACjB,MAAM,EAAE,MAAM;YACd,UAAU,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,GAAG,CAAC;YACpC,GAAG,EAAE,IAAI,CAAC,IAAI;YACd,QAAQ,EAAE,UAAU,CAAC,QAAQ;YAC7B,aAAa,EAAE,IAAI;SACpB,CAAC,CAAC;IACL,CAAC;IAED,OAAO,GAAG,CAAC;AACb,CAAC;AAED,uDAAuD;AACvD,SAAS,OAAO,CAAC,KAA0B,EAAE,MAAc;IACzD,IAAI,IAAI,GAAoB,IAAI,CAAC;IACjC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,IAAI,GAAG,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC;QAC1B,IAAI,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,IAAI,MAAM,IAAI,IAAI,CAAC,GAAG,CAAC,MAAM;YAAE,SAAS;QACtE,kCAAkC;QAClC,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM;YAAE,IAAI,GAAG,IAAI,CAAC;IAClF,CAAC;IACD,OAAO,IAAI,EAAE,EAAE,IAAI,IAAI,CAAC;AAC1B,CAAC;AAOD;;;;;;;GAOG;AACH,MAAM,UAAU,iBAAiB,CAC/B,IAAY,EACZ,KAAa,EACb,GAAW,EACX,OAA0B;IAE1B,MAAM,MAAM,GAAG,cAAc,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IAE3C,8EAA8E;IAC9E,wDAAwD;IACxD,IAAI,IAAI,GAA0B,IAAI,CAAC;IACvC,YAAY,CAAC,SAAS,GAAG,CAAC,CAAC;IAC3B,KAAK,IAAI,CAAC,GAAG,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,KAAK,IAAI,EAAE,CAAC,GAAG,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;QAClF,MAAM,MAAM,GAAG,CAAC,CAAC,CAAC,CAAW,CAAC;QAC9B,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC;QAC3C,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,GAAG,GAAG,CAAC;QACrC,IAAI,QAAQ,GAAG,WAAW;YAAE,SAAS;QACrC,yEAAyE;QACzE,wEAAwE;QACxE,IAAI,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YAAE,SAAS;QAC/C,MAAM,IAAI,GAAG,WAAW,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACrC,IAAI,IAAI;YAAE,IAAI,GAAG,IAAI,CAAC;IACxB,CAAC;IAED,IAAI,IAAI;QAAE,OAAO,IAAI,CAAC;IAEtB,8EAA8E;IAC9E,+BAA+B;IAC/B,MAAM,KAAK,GAAG,aAAa,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;IACvC,KAAK,MAAM,IAAI,IAAI,UAAU,EAAE,CAAC;QAC9B,IAAI,IAAI,CAAC,QAAQ;YAAE,SAAS;QAC5B,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YAClC,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,MAAM,CAAC;gBAAE,SAAS;YACxC,IAAI,IAAI,CAAC,IAAI,KAAK,SAAS,IAAI,IAAI,CAAC,IAAI,KAAK,YAAY;gBAAE,SAAS;YACpE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;QAC7C,CAAC;IACH,CAAC;IAED,MAAM,SAAS,GAAG,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,gBAAgB,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAW,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IACpG,IAAI,aAAa,CAAC,GAAG,CAAC,SAAS,CAAC;QAAE,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC;IACjF,KAAK,MAAM,OAAO,IAAI,OAAO,EAAE,CAAC;QAC9B,IAAI,aAAa,CAAC,GAAG,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC;YAAE,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC;IACnG,CAAC;IAED,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC;AACjD,CAAC;AAED,4EAA4E;AAC5E;;;;;;;;;GASG;AACH,MAAM,eAAe,GAAG,mCAAmC,CAAC;AAE5D;;;;;;GAMG;AACH,SAAS,cAAc,CAAC,IAAY,EAAE,KAAa;IACjD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,GAAG,GAAG,CAAC,EAAE,KAAK,CAAC,CAAC;IAC3D,IAAI,GAAG,GAAG,CAAC,CAAC;IACZ,eAAe,CAAC,SAAS,GAAG,CAAC,CAAC;IAC9B,KAAK,IAAI,CAAC,GAAG,eAAe,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,KAAK,IAAI,EAAE,CAAC,GAAG,eAAe,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;QACxF,GAAG,GAAG,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,GAAI,CAAC,CAAC,CAAC,CAAY,CAAC,MAAM,CAAC;IACjD,CAAC;IACD,OAAO,MAAM;SACV,KAAK,CAAC,GAAG,CAAC;SACV,WAAW,EAAE;SACb,OAAO,CAAC,kBAAkB,EAAE,GAAG,CAAC;SAChC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;AAC1B,CAAC;AAED,SAAS,aAAa,CAAC,IAAY,EAAE,GAAW;IAC9C,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,GAAG,EAAE,CAAC,CAAC,CAAC;IAChE,MAAM,IAAI,GAAG,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACtC,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;IACxD,OAAO,GAAG,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,kBAAkB,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;AACxF,CAAC;AAQD;;;;;;;GAOG;AACH,SAAS,kBAAkB,CAAC,OAAwB;IAClD,2EAA2E;IAC3E,4EAA4E;IAC5E,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAC9B,IAAI,IAAI,GAAG,EAAE,CAAC;IACd,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,KAAK,MAAM,IAAI,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;QACjC,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;QAC3C,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;QAC9C,IAAI,GAAG,IAAI,KAAK;YAAE,SAAS;QAC3B,IAAI,IAAI,MAAM,CAAC,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;QACpC,IAAI,IAAI,MAAM,CAAC,KAAK,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,UAAU,EAAE,GAAG,CAAC,CAAC;QAC1D,MAAM,GAAG,GAAG,CAAC;IACf,CAAC;IACD,IAAI,IAAI,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IAE7B,MAAM,GAAG,GAAoB,EAAE,CAAC;IAChC,QAAQ,CAAC,SAAS,GAAG,CAAC,CAAC;IACvB,KAAK,IAAI,CAAC,GAAG,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,IAAI,EAAE,CAAC,GAAG,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QACtE,MAAM,MAAM,GAAI,CAAC,CAAC,CAAC,CAAY,CAAC,WAAW,EAAE,CAAC;QAC9C,IAAI,YAAY,CAAC,GAAG,CAAC,MAAM,CAAC;YAAE,SAAS;QACvC,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC;YAAE,SAAS;QAChC,MAAM,KAAK,GAAG,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC;QAC3B,uEAAuE;QACvE,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC,IAAI,GAAG,CAAC;QACtC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,GAAI,CAAC,CAAC,CAAC,CAAY,CAAC,MAAM,CAAC,IAAI,GAAG,CAAC;QAC3D,IAAI,MAAM,KAAK,GAAG,IAAI,MAAM,KAAK,GAAG,IAAI,KAAK,KAAK,GAAG;YAAE,SAAS;QAChE,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAW,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,GAAI,CAAC,CAAC,CAAC,CAAY,CAAC,MAAM,EAAE,CAAC,CAAC;IAClF,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,gFAAgF;AAChF,gFAAgF;AAChF,gFAAgF;AAEhF,SAAS,UAAU,CAAC,KAAqC,EAAE,IAAuB;IAChF,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,MAAM,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAC7B,IAAI,CAAC,KAAK;YAAE,SAAS;QACrB,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;QAC9B,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC;YAAE,OAAO,KAAK,CAAC;IACvD,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,QAAQ,CAAC,KAA4B;IAC5C,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAC;IACxB,IAAI,OAAO,KAAK,CAAC,KAAK,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;IACtG,OAAO,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAE,KAAK,CAAC,KAAK,CAAC,CAAC,CAAY,CAAC,CAAC,CAAC,IAAI,CAAC;AACpE,CAAC;AAED,gEAAgE;AAChE,SAAS,WAAW,CAAC,KAAa;IAChC,OAAO,KAAK;SACT,IAAI,EAAE;SACN,OAAO,CAAC,aAAa,EAAE,EAAE,CAAC;SAC1B,OAAO,CAAC,aAAa,EAAE,EAAE,CAAC;SAC1B,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC;SACtB,IAAI,EAAE,CAAC;AACZ,CAAC;AAED,SAAS,WAAW,CAAC,MAAc;IACjC,MAAM,IAAI,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IACjC,OAAO,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;AACpD,CAAC;AAED,SAAS,UAAU,CAAC,IAAU;IAC5B,QAAQ,IAAI,CAAC,IAAI,EAAE,CAAC;QAClB,KAAK,MAAM;YACT,OAAO,KAAK,IAAI,CAAC,MAAM,IAAI,CAAC;QAC9B,KAAK,UAAU;YACb,OAAO,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC;QAC5B,KAAK,WAAW,CAAC;QACjB,KAAK,UAAU;YACb,OAAO,IAAI,IAAI,CAAC,IAAI,KAAK,IAAI,CAAC,MAAM,GAAG,CAAC;QAC1C;YACE,OAAO,IAAI,IAAI,CAAC,IAAI,KAAK,IAAI,CAAC,MAAM,GAAG,CAAC;IAC5C,CAAC;AACH,CAAC;AAED,0EAA0E;AAC1E,OAAO,EAAE,mBAAmB,EAAE,aAAa,EAAE,aAAa,EAAE,CAAC","sourcesContent":["/**\n * Document extraction: Markdown in, graph fragments out.\n *\n * This module is where domain-agnosticism is won or lost. It never requires a\n * repository to adopt a syntax. It reads what teams already write - front\n * matter, a `## Status` section, a checklist under `## Open Questions`, a link\n * that says \"deferred to ADR-0011\" - and turns each into a typed relation with a\n * source position.\n *\n * The one rule it holds to everywhere: **an inference that cannot be justified\n * is not made.** An unrecognised status becomes `unknown`, not a guess. A link\n * with no governing verb becomes a neutral `references`, not a dependency. Bare\n * identifiers found in prose are opportunistic and are dropped silently when\n * they do not resolve, because the alternative is reporting `SHA-256` as a\n * broken reference to specification 256.\n */\n\nimport { attr, attrList, directiveFor, parseDirectives, type Directive } from './directives.js';\nimport { identify, isExternal, normaliseRef, type DocumentIdentity, ID_KEYS } from './identity.js';\nimport { isStatusHeading, phaseFromPath, phaseOf, STATUS_KEYS, supersessionTargetsIn } from './lifecycle.js';\nimport { scanMarkdown, slugify, type Link, type ListItem, type ScannedDocument } from './markdown.js';\nimport { findSpecificationRegions, regionAt, type SpecificationRegion } from './sections.js';\nimport { resolveItemState } from './state.js';\nimport { refOf, type LineIndex } from './source.js';\nimport type {\n DocumentNode,\n EdgeKind,\n EdgeOrigin,\n ItemNode,\n ParseProblem,\n Phase,\n SourceRef,\n} from './types.js';\nimport { parseFrontMatter, toRecord, valuesOf, type YamlEntry } from './yaml.js';\n\n/* -------------------------------------------------------------------------- */\n/* Output */\n/* -------------------------------------------------------------------------- */\n\n/**\n * A relation that has been read but not yet resolved to a target node.\n *\n * Resolution needs the whole corpus, so extraction stops at the raw target text.\n */\nexport interface ReferenceCandidate {\n readonly kind: EdgeKind;\n /** Id of the node the relation was written on. */\n readonly from: string;\n /** The target exactly as written: a path, an identifier, or a URL. */\n readonly target: string;\n readonly origin: EdgeOrigin;\n readonly declaredAt: SourceRef;\n readonly raw: string;\n /**\n * When true the relation runs `target -> from`.\n *\n * `superseded-by: ADR-0009` written in ADR-0003 declares that *ADR-0009*\n * supersedes ADR-0003. The edge belongs to ADR-0009; the line a human must go\n * and fix is in ADR-0003, which is why `declaredAt` is tracked separately.\n */\n readonly inverted: boolean;\n /**\n * Opportunistic references are dropped in silence when they do not resolve.\n * Only deliberate ones - links, front matter, directives - are reported.\n */\n readonly opportunistic: boolean;\n}\n\nexport interface ExtractedDocument {\n readonly document: DocumentNode;\n readonly items: readonly ItemNode[];\n readonly references: readonly ReferenceCandidate[];\n readonly problems: readonly ParseProblem[];\n /** Heading slugs, for resolving `#anchor` references into this document. */\n readonly anchors: ReadonlySet<string>;\n readonly identity: DocumentIdentity;\n readonly scanned: ScannedDocument;\n /**\n * Specifications declared inside this file, each a document in its own right.\n *\n * Empty for the ordinary one-file-per-decision layout, which is why nothing\n * downstream had to change to support registers.\n */\n readonly subSpecifications: readonly ExtractedDocument[];\n /**\n * The file-level specification this one is a region of, if any.\n *\n * Recorded so the register's structure is a relation in the graph rather than\n * an accident of which offsets fall inside which: \"what decisions does this\n * register hold\" is a question worth being able to ask.\n */\n readonly containerId: string | null;\n}\n\n/* -------------------------------------------------------------------------- */\n/* Vocabulary */\n/* -------------------------------------------------------------------------- */\n\n/** Front-matter keys that declare a relation, and what they mean. */\nconst RELATION_KEYS: Readonly<Record<string, { kind: EdgeKind; inverted: boolean }>> = {\n supersedes: { kind: 'supersedes', inverted: false },\n supercedes: { kind: 'supersedes', inverted: false },\n replaces: { kind: 'supersedes', inverted: false },\n obsoletes: { kind: 'supersedes', inverted: false },\n 'superseded-by': { kind: 'supersedes', inverted: true },\n 'superceded-by': { kind: 'supersedes', inverted: true },\n 'replaced-by': { kind: 'supersedes', inverted: true },\n 'obsoleted-by': { kind: 'supersedes', inverted: true },\n amends: { kind: 'amends', inverted: false },\n extends: { kind: 'amends', inverted: false },\n 'amended-by': { kind: 'amends', inverted: true },\n 'depends-on': { kind: 'depends-on', inverted: false },\n dependencies: { kind: 'depends-on', inverted: false },\n requires: { kind: 'depends-on', inverted: false },\n assumes: { kind: 'assumes', inverted: false },\n 'blocked-by': { kind: 'blocked-by', inverted: false },\n blocks: { kind: 'blocked-by', inverted: true },\n 'delegates-to': { kind: 'delegates-to', inverted: false },\n 'delegated-to': { kind: 'delegates-to', inverted: false },\n 'tracked-in': { kind: 'delegates-to', inverted: false },\n related: { kind: 'relates-to', inverted: false },\n 'relates-to': { kind: 'relates-to', inverted: false },\n 'see-also': { kind: 'relates-to', inverted: false },\n references: { kind: 'references', inverted: false },\n refs: { kind: 'references', inverted: false },\n};\n\n/**\n * Phrases that give a link its meaning, longest-matching-nearest wins.\n *\n * Only phrases that genuinely commit the citing document are here. Vague ones\n * (\"see\", \"covered by\") stay out: a `references` edge is harmless, whereas a\n * wrongly inferred `assumes` edge produces a confident stale-premise finding\n * about a document that never depended on anything.\n */\nconst VERB_RULES: readonly { kind: EdgeKind; inverted: boolean; phrases: readonly string[] }[] = [\n {\n kind: 'supersedes',\n inverted: true,\n phrases: ['superseded by', 'superceded by', 'replaced by', 'obsoleted by', 'deprecated by', 'rolled into'],\n },\n { kind: 'supersedes', inverted: false, phrases: ['supersedes', 'supercedes', 'replaces', 'obsoletes', 'deprecates'] },\n { kind: 'amends', inverted: true, phrases: ['amended by', 'refined by', 'clarified by', 'revised by'] },\n { kind: 'amends', inverted: false, phrases: ['amends', 'refines', 'clarifies', 'revises'] },\n {\n kind: 'delegates-to',\n inverted: false,\n phrases: [\n 'delegated to',\n 'delegate to',\n 'deferred to',\n 'defer to',\n 'moved to',\n 'move to',\n 'tracked in',\n 'tracked by',\n 'handed off to',\n 'handed to',\n 'hand off to',\n 'follow up in',\n 'follow-up in',\n 'followup in',\n 'continued in',\n 'continues in',\n 'punted to',\n 'left to',\n 'belongs in',\n 'owned by',\n 'will be decided in',\n 'will be resolved in',\n 'will be handled in',\n 'will be handled by',\n 'will be answered in',\n 'to be decided in',\n 'to be resolved in',\n 'to be handled in',\n 'to be answered in',\n ],\n },\n {\n kind: 'blocked-by',\n inverted: false,\n phrases: ['blocked by', 'blocked on', 'waiting on', 'waiting for', 'gated on', 'gated by', 'unblocked by'],\n },\n { kind: 'blocked-by', inverted: true, phrases: ['blocks', 'blocking'] },\n {\n kind: 'depends-on',\n inverted: false,\n phrases: ['depends on', 'depend on', 'dependent on', 'requires', 'builds on', 'built on', 'relies on'],\n },\n { kind: 'depends-on', inverted: true, phrases: ['depended on by'] },\n {\n kind: 'assumes',\n inverted: false,\n phrases: [\n 'assumes',\n 'assuming',\n 'on the assumption of',\n 'as decided in',\n 'as established in',\n 'as established by',\n 'as stated in',\n 'as specified in',\n 'as required by',\n 'as mandated by',\n 'in accordance with',\n 'constrained by',\n 'mandated by',\n 'governed by',\n 'predicated on',\n 'rests on',\n 'follows from',\n 'justified by',\n // A constraint the citing document designs around. \"the row limit imposed\n // by ADR-0002\" is the archetypal stale premise: when ADR-0002 is retired,\n // this document is still working around a cap that no longer exists.\n 'imposed by',\n 'required by',\n 'dictated by',\n 'determined by',\n 'limited by',\n 'capped by',\n 'bounded by',\n 'defined by',\n 'defined in',\n 'specified by',\n 'set by',\n 'per',\n 'because',\n 'since',\n ],\n },\n];\n\n/**\n * Words that cancel a governing phrase standing before them.\n *\n * The window allows a short noun phrase between a verb and the reference it\n * governs - \"deferred to the sharding decision in [ADR-7]\" is one statement.\n * It cannot allow a negation. A table entry reading \"Owned by nobody today and\n * disclaimed by [138]\" was being read as a delegation *to* 138, which is the\n * opposite of what the sentence says, and an inference that inverts its source\n * is worse than no inference at all.\n */\nconst NEGATION = /(?:^|\\s)(?:no|not|nobody|none|never|neither|nor|nothing|without)(?:\\s|$)/;\n\n/** How close a governing phrase must sit to the reference it governs. */\nconst VERB_WINDOW = 40;\n\n/**\n * Every governing phrase compiled into one alternation, plus a lookup table.\n *\n * Classification runs on every reference in the corpus, and testing a hundred\n * phrases one at a time made it the most expensive thing extraction did. The\n * alternation is sorted longest-first so that at any given position the regex\n * prefers `partially resolved` over `resolved`, matching the precedence the\n * per-phrase search had. Lookarounds rather than `\\b`, because phrases contain\n * hyphens and `\\b` does the wrong thing around them.\n */\nconst VERB_LOOKUP: ReadonlyMap<string, Classification> = new Map(\n VERB_RULES.flatMap((rule) =>\n rule.phrases.map((phrase) => [phrase, { kind: rule.kind, inverted: rule.inverted }] as const),\n ),\n);\n\nconst VERB_PATTERN = new RegExp(\n `(?<![\\\\p{L}\\\\p{N}])(?:${[...VERB_LOOKUP.keys()]\n .sort((a, b) => b.length - a.length)\n .map((phrase) => phrase.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&'))\n .join('|')})(?![\\\\p{L}\\\\p{N}])`,\n 'gu',\n);\n\n/** Headings under which a link is bookkeeping rather than a commitment. */\nconst WEAK_SECTIONS: ReadonlySet<string> = new Set([\n 'see also',\n 'references',\n 'reference',\n 'related',\n 'related work',\n 'related decisions',\n 'related documents',\n 'links',\n 'further reading',\n 'prior art',\n 'history',\n 'changelog',\n 'change log',\n 'revision history',\n 'bibliography',\n 'sources',\n 'appendix',\n 'more information',\n 'resources',\n 'index',\n]);\n\n/** Headings whose bullets are obligations even without a checkbox. */\nconst OBLIGATION_SECTIONS: ReadonlySet<string> = new Set([\n 'open questions',\n 'open question',\n 'unresolved questions',\n 'unanswered questions',\n 'questions',\n 'open issues',\n 'action items',\n 'actions',\n 'todo',\n 'to do',\n 'to-do',\n 'todos',\n 'next steps',\n 'follow ups',\n 'follow-ups',\n 'followups',\n 'follow up',\n 'follow-up',\n 'unresolved',\n 'outstanding',\n 'outstanding questions',\n 'tasks',\n 'task list',\n 'work items',\n 'remaining work',\n 'decisions needed',\n 'blockers',\n 'parking lot',\n 'future work',\n 'deferred',\n]);\n\n/**\n * Prefixes that look like specification identifiers but never are.\n *\n * The corpus filter in `resolve.ts` is the real defence; this list only keeps\n * the obvious noise out of the candidate set.\n */\nconst NOT_A_FAMILY: ReadonlySet<string> = new Set([\n 'v',\n 'ver',\n 'version',\n 'p',\n 'pp',\n 'fig',\n 'figure',\n 'table',\n 'tbl',\n 'section',\n 'sect',\n 'sec',\n 'step',\n 'item',\n 'no',\n 'num',\n 'line',\n 'ln',\n 'col',\n 'port',\n 'pr',\n 'issue',\n 'gh',\n 'utf',\n 'ascii',\n 'sha',\n 'md',\n 'http',\n 'https',\n 'ipv',\n 'tls',\n 'ssl',\n 'es',\n 'ecma',\n 'x',\n 'h',\n 'p99',\n 'base',\n 'sql',\n 'ipv4',\n 'ipv6',\n 'arm',\n 'x86',\n 'win',\n 'node',\n 'python',\n 'java',\n 'go',\n 'c',\n 'cpp',\n]);\n\nconst BARE_REF = /\\b([A-Za-z][A-Za-z0-9]{0,14})[\\s._-]?(\\d{1,6})\\b/g;\n\n/* -------------------------------------------------------------------------- */\n/* Extraction */\n/* -------------------------------------------------------------------------- */\n\nexport interface ExtractInput {\n /** Repository-relative POSIX path. */\n readonly path: string;\n readonly text: string;\n /**\n * This file is a historical record: a log of what was decided, not a\n * decision. Matched against the caller's history patterns, because deciding\n * which files those are is a repository's business and not a guess this\n * layer could justify making. See ADR-0011.\n */\n readonly record?: boolean | undefined;\n}\n\n/**\n * Reads one file into graph fragments, one entry per specification in it.\n *\n * A file yields at least itself. It yields more when it is a register: a\n * heading that carries an identifier *and* declares a status is a specification\n * in its own right, with its own lifecycle, its own obligations and its own\n * relations. See ADR-0009.\n */\nexport function extractSpecifications(input: ExtractInput): ExtractedDocument[] {\n const first = extractDocument(input);\n return first === null ? [] : [first, ...(first.subSpecifications as ExtractedDocument[])];\n}\n\n/** Reads a file's own specification. Returns `null` when it opts out. */\nexport function extractDocument(input: ExtractInput): ExtractedDocument | null {\n const scanned = scanMarkdown(input.text);\n const directives = parseDirectives(scanned.comments);\n if (directives.some((d) => d.name === 'spec-ignore')) return null;\n\n const index = scanned.index;\n const file = input.path;\n const problems: ParseProblem[] = [];\n const at = (start: number, end: number): SourceRef => refOf(file, index, start, end);\n\n for (const directive of directives) {\n for (const unknown of directive.unknownAttributes) {\n problems.push({\n message: `unknown attribute \"${unknown}\" on @${directive.name}`,\n at: at(directive.start, directive.end),\n });\n }\n }\n\n const entries = scanned.frontMatter ? parseFrontMatter(scanned.frontMatter.raw, scanned.frontMatter.start) : [];\n const byKey = new Map<string, YamlEntry>();\n for (const entry of entries) byKey.set(entry.key, entry);\n\n const h1 = scanned.headings.find((h) => h.level === 1) ?? null;\n const frontMatterId = firstValue(byKey, ID_KEYS) ?? null;\n\n const identityOf = (declaredId: string | null, directive: Directive | null): DocumentIdentity =>\n identify({\n path: input.path,\n declaredId,\n declaredAliases: [\n ...(directive ? attrList(directive, 'aliases') : []),\n ...valuesOf(byKey.get('aliases')),\n ...valuesOf(byKey.get('alias')),\n ],\n heading: h1?.text ?? null,\n });\n\n // A `@spec-node` written inside a register's section belongs to that section,\n // not to the file. Finding the file's own therefore needs the regions, and\n // finding the regions needs the file's identity - so the identity is settled\n // provisionally first, then again once the file's own directive is known.\n const provisional = identityOf(frontMatterId, null);\n const provisionalRegions = findSpecificationRegions(scanned, directives, provisional.id);\n const nodeDirective =\n directives.find(\n (directive) =>\n directive.name === 'spec-node' &&\n !provisionalRegions.some(\n (region) =>\n (region.heading !== null || region.row !== null) &&\n directive.start >= region.start &&\n directive.end <= region.end,\n ),\n ) ?? null;\n\n const declaredId = (nodeDirective ? attr(nodeDirective, 'id')?.value : null) ?? frontMatterId;\n const identity = declaredId === frontMatterId && nodeDirective === null\n ? provisional\n : identityOf(declaredId, nodeDirective);\n\n const status = readStatus(scanned, byKey, nodeDirective, index, file);\n const pathPhase = phaseFromPath(input.path);\n // A record is a categorical statement about what the file *is*, made by\n // configuration or by an explicit directive, so it outranks a status word\n // that happened to be written inside it.\n const record = input.record === true || directives.some((directive) => directive.name === 'spec-history');\n const phase: Phase = record ? 'record' : status.phase !== 'unknown' ? status.phase : pathPhase;\n\n const title =\n (nodeDirective ? attr(nodeDirective, 'title')?.value : null) ??\n asString(byKey.get('title')) ??\n h1?.text ??\n identity.id;\n\n const document: DocumentNode = {\n id: identity.id,\n kind: 'document',\n title,\n at: at(0, Math.min(scanned.text.length, index.lineEnd(1))),\n path: input.path,\n aliases: identity.aliases,\n phase,\n rawStatus: status.raw,\n statusAt: status.at,\n frontMatter: toRecord(entries),\n };\n\n // A register's sections are specifications too. The file is always the first\n // region, so a one-decision file behaves exactly as it did before.\n const regions =\n identity.id === provisional.id ? provisionalRegions : findSpecificationRegions(scanned, directives, identity.id);\n // Every region but the first: a heading section, or a row of a register kept\n // as a table.\n const subSpecifications = regions\n .filter((region) => region.heading !== null || region.row !== null)\n .map((region) =>\n buildRegion({\n region,\n containerId: identity.id,\n input,\n scanned,\n directives,\n index,\n file,\n pathPhase,\n record,\n }),\n );\n\n const ownerAt = (offset: number): string => {\n const region = regionAt(regions, offset);\n if (region === null) return identity.id;\n const owner = subSpecifications.find((spec) => spec.region === region);\n return owner?.document.id ?? identity.id;\n };\n\n const allItems = extractItems({ scanned, directives, ownerAt, file, index });\n const documentAt = (offset: number): DocumentNode => {\n const id = ownerAt(offset);\n if (id === identity.id) return document;\n return subSpecifications.find((spec) => spec.document.id === id)?.document ?? document;\n };\n\n const allReferences = extractReferences({\n scanned,\n directives,\n document,\n documentAt,\n items: allItems,\n byKey,\n status,\n claimed: regions.flatMap((region) => [...region.claimed]),\n file,\n index,\n });\n\n // Hand each region the items and references that fall inside it.\n const ownItems = allItems.filter((item) => item.document === identity.id);\n const ownReferences = allReferences.filter((reference) => belongsTo(reference, identity.id, allItems));\n const anchors = new Set<string>(scanned.headings.map((h) => h.slug));\n\n const filled = subSpecifications.map((spec) => ({\n ...spec.extracted,\n items: allItems.filter((item) => item.document === spec.document.id),\n references: [\n // Column-declared relations first: they are typed by the header rather\n // than guessed from prose.\n ...spec.extracted.references,\n ...allReferences.filter((reference) => belongsTo(reference, spec.document.id, allItems)),\n ],\n }));\n\n return {\n document,\n items: ownItems,\n references: ownReferences,\n problems,\n anchors,\n identity,\n scanned,\n subSpecifications: filled,\n containerId: null,\n };\n}\n\n/** True when a reference was written on a document or on one of its items. */\nfunction belongsTo(reference: ReferenceCandidate, documentId: string, items: readonly ItemNode[]): boolean {\n if (reference.from === documentId) return true;\n const owner = items.find((item) => item.id === reference.from);\n return owner?.document === documentId;\n}\n\ninterface RegionInput {\n readonly region: SpecificationRegion;\n readonly containerId: string;\n readonly input: ExtractInput;\n readonly scanned: ScannedDocument;\n readonly directives: readonly Directive[];\n readonly index: LineIndex;\n readonly file: string;\n readonly pathPhase: Phase;\n /** The whole file is a historical record, so every part of it is one too. */\n readonly record: boolean;\n}\n\ninterface BuiltRegion {\n readonly region: SpecificationRegion;\n readonly document: DocumentNode;\n readonly extracted: ExtractedDocument;\n}\n\n/**\n * Turns one region into a specification.\n *\n * It produces exactly the `DocumentNode` a whole file produces, which is the\n * reason every rule, query and reporter works on registers without knowing they\n * exist. The only deliberate differences: the node is anchored at its heading\n * rather than at line one, it carries no front matter of its own, and it does\n * not claim the file's path as an alias - the file already does, and two nodes\n * answering to one path would make every link to that file ambiguous.\n */\nfunction buildRegion(context: RegionInput): BuiltRegion {\n const { region, input, scanned, index, file, pathPhase, record } = context;\n const at = (start: number, end: number): SourceRef => refOf(file, index, start, end);\n\n const identity = identify({\n path: input.path,\n declaredId: region.declaredId,\n declaredAliases: region.directive ? attrList(region.directive, 'aliases') : [],\n heading: region.title,\n includePathAliases: false,\n });\n\n const declaredStatus = region.directive ? attr(region.directive, 'status') : null;\n const rawStatus = declaredStatus?.value ?? region.status?.text ?? null;\n const statusAt = declaredStatus\n ? at(declaredStatus.start, declaredStatus.end)\n : region.status\n ? at(region.status.start, region.status.end)\n : null;\n const declaredPhase = phaseOf(rawStatus);\n\n const document: DocumentNode = {\n id: identity.id,\n kind: 'document',\n title: (region.directive ? attr(region.directive, 'title')?.value : null) ?? region.title ?? identity.id,\n // Anchored at its heading, or at the row when the register is a table.\n at: at(region.start, Math.min(region.end, region.heading?.end ?? region.row?.end ?? region.end)),\n path: input.path,\n aliases: identity.aliases,\n // A section of a journal is part of the journal, whatever status word it\n // wrote for itself. Being a record is a statement about the file made from\n // outside it, and it does not stop at a heading.\n phase: record ? 'record' : declaredPhase !== 'unknown' ? declaredPhase : pathPhase,\n rawStatus,\n statusAt,\n frontMatter: {},\n };\n\n const anchors = new Set<string>(\n scanned.headings.filter((h) => h.start >= region.start && h.start < region.end).map((h) => h.slug),\n );\n\n // Relations a table declares by column, typed by the header the author wrote.\n const references: ReferenceCandidate[] = region.relations.map((relation) => ({\n kind: relation.kind,\n from: document.id,\n target: relation.target,\n origin: 'front-matter' as const,\n declaredAt: at(relation.start, relation.end),\n raw: `${relation.column}: ${relation.target}`,\n inverted: relation.inverted,\n opportunistic: false,\n }));\n\n return {\n region,\n document,\n extracted: {\n document,\n items: [],\n references,\n problems: [],\n anchors,\n identity,\n scanned,\n subSpecifications: [],\n containerId: context.containerId,\n },\n };\n}\n\n/* -------------------------------------------------------------------------- */\n/* Status */\n/* -------------------------------------------------------------------------- */\n\ninterface StatusReading {\n readonly raw: string | null;\n readonly at: SourceRef | null;\n readonly phase: Phase;\n}\n\n/**\n * Finds the document status.\n *\n * Looks in the three places teams actually put it, in descending order of how\n * deliberate each is: a directive, a front-matter field, then the body of a\n * `## Status` section. A repository using none of them still gets a phase from\n * its directory layout, which is handled by the caller.\n */\nfunction readStatus(\n scanned: ScannedDocument,\n byKey: ReadonlyMap<string, YamlEntry>,\n nodeDirective: Directive | null,\n index: LineIndex,\n file: string,\n): StatusReading {\n if (nodeDirective) {\n const declared = attr(nodeDirective, 'status');\n if (declared) {\n return {\n raw: declared.value,\n at: refOf(file, index, declared.start, declared.end),\n phase: phaseOf(declared.value),\n };\n }\n }\n\n for (const key of STATUS_KEYS) {\n const entry = byKey.get(key);\n if (!entry) continue;\n const raw = typeof entry.value === 'string' ? entry.value : entry.value.join(', ');\n if (raw.trim().length === 0) continue;\n return {\n raw,\n at: refOf(file, index, entry.valueStart, entry.end),\n phase: phaseOf(raw),\n };\n }\n\n const heading = scanned.headings.find((h) => isStatusHeading(h.text));\n if (heading) {\n const body = statusSectionBody(scanned, heading.line);\n if (body) {\n return {\n raw: body.text,\n at: refOf(file, index, body.start, body.end),\n phase: phaseOf(body.text),\n };\n }\n }\n\n return { raw: null, at: null, phase: 'unknown' };\n}\n\n/** The first non-blank line under a `## Status` heading. */\nfunction statusSectionBody(\n scanned: ScannedDocument,\n headingLine: number,\n): { text: string; start: number; end: number } | null {\n for (const line of scanned.lines) {\n if (line.line <= headingLine) continue;\n if (line.blank) continue;\n if (line.code) return null;\n const trimmed = line.content.trim();\n // A heading immediately after means the section is empty.\n if (trimmed.startsWith('#')) return null;\n const offset = line.contentStart + line.content.indexOf(trimmed);\n // Bullet lists under Status are a status history; take the first entry.\n const cleaned = trimmed.replace(/^[-*+]\\s+/, '');\n const start = offset + (trimmed.length - cleaned.length);\n return { text: cleaned, start, end: start + cleaned.length };\n }\n return null;\n}\n\n/* -------------------------------------------------------------------------- */\n/* Items */\n/* -------------------------------------------------------------------------- */\n\ninterface ItemContext {\n readonly scanned: ScannedDocument;\n readonly directives: readonly Directive[];\n /** The specification that owns an offset, which in a register is a section. */\n readonly ownerAt: (offset: number) => string;\n readonly file: string;\n readonly index: LineIndex;\n}\n\nfunction extractItems(context: ItemContext): ItemNode[] {\n const { scanned, directives, ownerAt, file, index } = context;\n const out: ItemNode[] = [];\n const ordinals = new Map<string, number>();\n\n for (const item of scanned.listItems) {\n const section = sectionPathAt(scanned, item.start);\n const inObligationSection = section.some((heading) => OBLIGATION_SECTIONS.has(normaliseHeading(heading)));\n const directive = directiveFor(directives, 'spec-item', { start: item.start, end: item.end }, 200);\n\n if (!isObligation(item, inObligationSection, directive)) continue;\n\n const documentId = ownerAt(item.start);\n const slug = section.length > 0 ? slugify(section[section.length - 1] as string) : 'item';\n // Ordinals count within a specification, so two decisions in one register\n // each get their own `#open-questions.1` rather than sharing a sequence.\n const key = `${documentId}#${slug}`;\n const ordinal = (ordinals.get(key) ?? 0) + 1;\n ordinals.set(key, ordinal);\n\n const declaredId = directive ? attr(directive, 'id')?.value : null;\n const id = `${documentId}#${declaredId ?? `${slug}.${ordinal}`}`;\n\n const state = resolveItemState({\n file,\n index,\n item,\n section,\n directive,\n inObligationSection,\n });\n\n out.push({\n id,\n kind: 'item',\n title: (directive ? attr(directive, 'title')?.value : null) ?? summarise(item.firstLine),\n at: refOf(file, index, item.start, item.end),\n document: documentId,\n section,\n text: summarise(item.firstLine),\n body: item.body,\n disposition: state.disposition,\n openness: state.openness,\n evidence: state.evidence,\n conflicts: state.conflicts,\n });\n }\n\n return out;\n}\n\n/**\n * Decides whether a bullet is an obligation.\n *\n * A checkbox or an explicit directive always makes one. Otherwise only\n * top-level bullets under a heading like \"Open Questions\" count: promoting\n * every bullet in a specification would bury the real obligations under the\n * document's own prose.\n */\nfunction isObligation(item: ListItem, inObligationSection: boolean, directive: Directive | null): boolean {\n if (directive !== null) return true;\n if (item.checkbox !== null) return true;\n return inObligationSection && item.depth === 0;\n}\n\n/** The heading path enclosing an offset, outermost first. */\nfunction sectionPathAt(scanned: ScannedDocument, offset: number): string[] {\n const path: { level: number; text: string }[] = [];\n for (const heading of scanned.headings) {\n if (heading.start > offset) break;\n while (path.length > 0 && (path[path.length - 1] as { level: number }).level >= heading.level) path.pop();\n path.push({ level: heading.level, text: heading.text });\n }\n return path.map((entry) => entry.text);\n}\n\n/**\n * Memoised because it is called for every heading above every reference and\n * every item, and a corpus has only a handful of distinct headings - `Context`,\n * `Decision`, `Open Questions`, `See also` - repeated thousands of times.\n */\nconst headingCache = new Map<string, string>();\n\nfunction normaliseHeading(text: string): string {\n const cached = headingCache.get(text);\n if (cached !== undefined) return cached;\n const normalised = text\n .toLowerCase()\n .replace(/[`*_~]/g, '')\n .replace(/[^\\p{L}\\p{N}\\s-]/gu, '')\n .replace(/\\s+/g, ' ')\n .trim();\n // Bounded so a pathological corpus of unique headings cannot grow it forever.\n if (headingCache.size < 4096) headingCache.set(text, normalised);\n return normalised;\n}\n\n/**\n * One-line form of an item for reports.\n *\n * Link syntax is flattened to its label. A finding that quotes the obligation\n * back at the reader should read like the sentence they wrote, not like the\n * Markdown source of it.\n */\nfunction summarise(text: string): string {\n const flat = text\n .replace(/!?\\[([^\\]]*)\\]\\([^)]*\\)/g, '$1')\n // `[[target|display]]` keeps the display half: that is the text a reader\n // of the rendered document actually sees.\n .replace(/\\[\\[(?:[^\\]|]*\\|)?([^\\]]*)\\]\\]/g, '$1')\n .replace(/\\s+/g, ' ')\n .trim();\n return flat.length <= 120 ? flat : `${flat.slice(0, 117)}...`;\n}\n\n/* -------------------------------------------------------------------------- */\n/* References */\n/* -------------------------------------------------------------------------- */\n\ninterface ReferenceContext {\n readonly scanned: ScannedDocument;\n readonly directives: readonly Directive[];\n readonly document: DocumentNode;\n /** The specification that owns an offset, for a reference outside any item. */\n readonly documentAt: (offset: number) => DocumentNode;\n readonly items: readonly ItemNode[];\n readonly byKey: ReadonlyMap<string, YamlEntry>;\n readonly status: StatusReading;\n /** Cell ranges already typed by a table column header. */\n readonly claimed: readonly { start: number; end: number }[];\n readonly file: string;\n readonly index: LineIndex;\n}\n\n/** True when an offset falls in a cell a column header already accounted for. */\nfunction isClaimed(claimed: readonly { start: number; end: number }[], offset: number): boolean {\n return claimed.some((range) => offset >= range.start && offset < range.end);\n}\n\nfunction extractReferences(context: ReferenceContext): ReferenceCandidate[] {\n const { scanned, directives, document, documentAt, items, byKey, status, claimed, file, index } = context;\n const out: ReferenceCandidate[] = [];\n const at = (start: number, end: number): SourceRef => refOf(file, index, start, end);\n\n // Front matter.\n for (const [key, relation] of Object.entries(RELATION_KEYS)) {\n const entry = byKey.get(key) ?? byKey.get(key.replace(/-/g, '_'));\n if (!entry) continue;\n for (const value of valuesOf(entry)) {\n const target = cleanTarget(value);\n if (target.length === 0) continue;\n out.push({\n kind: relation.kind,\n from: document.id,\n target,\n origin: 'front-matter',\n declaredAt: at(entry.valueStart, entry.end),\n raw: `${key}: ${value}`,\n inverted: relation.inverted,\n opportunistic: false,\n });\n }\n }\n\n // `status: Superseded by ADR-0009` is the most common supersession record of\n // all, and it never appears as a field of its own.\n if (status.raw && status.at) {\n for (const target of supersessionTargetsIn(status.raw)) {\n const cleaned = cleanTarget(target);\n if (cleaned.length === 0) continue;\n out.push({\n kind: 'supersedes',\n from: document.id,\n target: cleaned,\n origin: 'front-matter',\n declaredAt: status.at,\n raw: status.raw,\n inverted: true,\n opportunistic: true,\n });\n }\n }\n\n // Explicit edge directives.\n for (const directive of directives) {\n if (directive.name !== 'spec-edge') continue;\n const kind = attr(directive, 'kind')?.value as EdgeKind | undefined;\n const to = attr(directive, 'to');\n const from = attr(directive, 'from');\n if (!kind) continue;\n const owner = ownerOf(items, directive.start) ?? documentAt(directive.start).id;\n if (to) {\n out.push({\n kind,\n from: owner,\n target: to.value,\n origin: 'directive',\n declaredAt: at(to.start, to.end),\n raw: `@spec-edge kind=\"${kind}\" to=\"${to.value}\"`,\n inverted: false,\n opportunistic: false,\n });\n }\n if (from) {\n out.push({\n kind,\n from: owner,\n target: from.value,\n origin: 'directive',\n declaredAt: at(from.start, from.end),\n raw: `@spec-edge kind=\"${kind}\" from=\"${from.value}\"`,\n inverted: true,\n opportunistic: false,\n });\n }\n }\n\n // Prose links. A cell whose meaning a column header already gave is skipped,\n // so `| ADR-0002 | ... | [ADR-0001](0001.md) |` yields one typed edge rather\n // than a typed edge and a neutral citation beside it.\n const linked = new Set<string>();\n for (const link of scanned.links) {\n if (link.form === 'definition') continue;\n if (isClaimed(claimed, link.start)) continue;\n const target = cleanTarget(link.target);\n if (target.length === 0) continue;\n if (isExternal(target)) continue;\n\n const owner = ownerOf(items, link.start) ?? documentAt(link.start).id;\n const section = sectionPathAt(scanned, link.start);\n const classified = classifyReference(scanned.masked, link.start, link.end, section);\n\n linked.add(normaliseRef(stripAnchor(target)));\n out.push({\n kind: classified.kind,\n from: owner,\n target,\n origin: 'link',\n declaredAt: at(link.targetStart, link.targetStart + link.target.length),\n raw: renderLink(link),\n inverted: classified.inverted,\n opportunistic: false,\n });\n }\n\n // Bare identifiers in prose. Everything already covered by a link is skipped\n // so a citation written as `[ADR-7](0007.md)` is not counted twice.\n for (const bare of findBareReferences(scanned)) {\n const key = normaliseRef(bare.text);\n if (linked.has(key)) continue;\n if (isClaimed(claimed, bare.start)) continue;\n const owner = ownerOf(items, bare.start) ?? documentAt(bare.start).id;\n const section = sectionPathAt(scanned, bare.start);\n const classified = classifyReference(scanned.masked, bare.start, bare.end, section);\n out.push({\n kind: classified.kind,\n from: owner,\n target: bare.text,\n origin: 'text',\n declaredAt: at(bare.start, bare.end),\n raw: bare.text,\n inverted: classified.inverted,\n opportunistic: true,\n });\n }\n\n return out;\n}\n\n/** The item whose block contains an offset, if any. */\nfunction ownerOf(items: readonly ItemNode[], offset: number): string | null {\n let best: ItemNode | null = null;\n for (const item of items) {\n const span = item.at.span;\n if (offset < span.start.offset || offset >= span.end.offset) continue;\n // Innermost wins when items nest.\n if (best === null || span.start.offset > best.at.span.start.offset) best = item;\n }\n return best?.id ?? null;\n}\n\nexport interface Classification {\n readonly kind: EdgeKind;\n readonly inverted: boolean;\n}\n\n/**\n * Decides what a reference means from the words around it.\n *\n * The nearest governing phrase within {@link VERB_WINDOW} characters wins, and\n * the search never crosses a sentence boundary. With nothing to go on, a\n * reference under a \"See also\" heading is bookkeeping and everything else is a\n * neutral citation.\n */\nexport function classifyReference(\n text: string,\n start: number,\n end: number,\n section: readonly string[],\n): Classification {\n const before = sentenceBefore(text, start);\n\n // Left to right, so the last match within the window is the nearest one - and\n // the nearest governing phrase is the one that governs.\n let best: Classification | null = null;\n VERB_PATTERN.lastIndex = 0;\n for (let m = VERB_PATTERN.exec(before); m !== null; m = VERB_PATTERN.exec(before)) {\n const phrase = m[0] as string;\n const end = (m.index ?? 0) + phrase.length;\n const distance = before.length - end;\n if (distance > VERB_WINDOW) continue;\n // What sits between the phrase and the reference has to be connective. A\n // negation in there reverses the claim the phrase would otherwise make.\n if (NEGATION.test(before.slice(end))) continue;\n const rule = VERB_LOOKUP.get(phrase);\n if (rule) best = rule;\n }\n\n if (best) return best;\n\n // \"[ADR-0009] supersedes this decision\": the reference is the subject, so the\n // relation runs the other way.\n const after = sentenceAfter(text, end);\n for (const rule of VERB_RULES) {\n if (rule.inverted) continue;\n for (const phrase of rule.phrases) {\n if (!after.startsWith(phrase)) continue;\n if (rule.kind === 'assumes' || rule.kind === 'depends-on') continue;\n return { kind: rule.kind, inverted: true };\n }\n }\n\n const innermost = section.length > 0 ? normaliseHeading(section[section.length - 1] as string) : '';\n if (WEAK_SECTIONS.has(innermost)) return { kind: 'relates-to', inverted: false };\n for (const heading of section) {\n if (WEAK_SECTIONS.has(normaliseHeading(heading))) return { kind: 'relates-to', inverted: false };\n }\n\n return { kind: 'references', inverted: false };\n}\n\n/** A sentence end, a blank line, or the start of a new block-level item. */\n/**\n * A table cell edge ends a statement too.\n *\n * The pipe matters more than it looks. A table row is a list of independent\n * fields, and without it the look-behind window reaches back across the row\n * boundary into the previous row's prose. An index of archived documents whose\n * last column ended \"...before assuming the drift was fixed\" turned every\n * following row's link into an `assumes` edge, and so turned every archived\n * document it listed into a stale premise.\n */\nconst STATEMENT_BREAK = /[.?!;]\\s|\\n\\s*\\n|\\n\\s*[-*+>#]|\\|/g;\n\n/**\n * Lower-cased, whitespace-collapsed text back to the start of the statement.\n *\n * The search stops at the last boundary: a governing phrase in the *previous*\n * sentence does not govern this reference. \"We deferred that to ADR-3. See also\n * [ADR-9].\" must not read as a delegation to ADR-9.\n */\nfunction sentenceBefore(text: string, start: number): string {\n const window = text.slice(Math.max(0, start - 160), start);\n let cut = 0;\n STATEMENT_BREAK.lastIndex = 0;\n for (let m = STATEMENT_BREAK.exec(window); m !== null; m = STATEMENT_BREAK.exec(window)) {\n cut = (m.index ?? 0) + (m[0] as string).length;\n }\n return window\n .slice(cut)\n .toLowerCase()\n .replace(/[`*_~\"'()\\[\\],]/g, ' ')\n .replace(/\\s+/g, ' ');\n}\n\nfunction sentenceAfter(text: string, end: number): string {\n const window = text.slice(end, Math.min(text.length, end + 80));\n const stop = /[.?!;\\n|]/.exec(window);\n const cut = stop ? window.slice(0, stop.index) : window;\n return cut.toLowerCase().replace(/[`*_~\"'()\\[\\],]/g, ' ').replace(/\\s+/g, ' ').trim();\n}\n\ninterface BareReference {\n readonly text: string;\n readonly start: number;\n readonly end: number;\n}\n\n/**\n * Finds identifiers written as plain prose, such as \"as decided in ADR-0007\".\n *\n * Link constructs are blanked first. Without that, `[ADR-7](https://x/adr-7)`\n * would yield three references to the same thing - one real and two harvested\n * out of a URL - which is precisely the mis-match that makes hand-rolled regex\n * checks untrustworthy.\n */\nfunction findBareReferences(scanned: ScannedDocument): BareReference[] {\n // Slice-based for the same reason as the scanner's masking: this runs over\n // every document, and a per-character array is the wrong shape for the job.\n const source = scanned.masked;\n let text = '';\n let cursor = 0;\n for (const link of scanned.links) {\n const start = Math.max(link.start, cursor);\n const end = Math.min(link.end, source.length);\n if (end <= start) continue;\n text += source.slice(cursor, start);\n text += source.slice(start, end).replace(/[^\\n\\r]/g, ' ');\n cursor = end;\n }\n text += source.slice(cursor);\n\n const out: BareReference[] = [];\n BARE_REF.lastIndex = 0;\n for (let m = BARE_REF.exec(text); m !== null; m = BARE_REF.exec(text)) {\n const prefix = (m[1] as string).toLowerCase();\n if (NOT_A_FAMILY.has(prefix)) continue;\n if (prefix.length < 2) continue;\n const start = m.index ?? 0;\n // A token glued to a path separator or an extension is not a citation.\n const before = text[start - 1] ?? ' ';\n const after = text[start + (m[0] as string).length] ?? ' ';\n if (before === '/' || before === '.' || after === '/') continue;\n out.push({ text: m[0] as string, start, end: start + (m[0] as string).length });\n }\n return out;\n}\n\n/* -------------------------------------------------------------------------- */\n/* Helpers */\n/* -------------------------------------------------------------------------- */\n\nfunction firstValue(byKey: ReadonlyMap<string, YamlEntry>, keys: readonly string[]): string | null {\n for (const key of keys) {\n const entry = byKey.get(key);\n if (!entry) continue;\n const value = asString(entry);\n if (value !== null && value.length > 0) return value;\n }\n return null;\n}\n\nfunction asString(entry: YamlEntry | undefined): string | null {\n if (!entry) return null;\n if (typeof entry.value === 'string') return entry.value.trim().length > 0 ? entry.value.trim() : null;\n return entry.value.length > 0 ? (entry.value[0] as string) : null;\n}\n\n/** Strips Markdown decoration a target may still be wearing. */\nfunction cleanTarget(value: string): string {\n return value\n .trim()\n .replace(/^[`'\"<(\\[]+/, '')\n .replace(/[`'\">)\\]]+$/, '')\n .replace(/[.,;]+$/, '')\n .trim();\n}\n\nfunction stripAnchor(target: string): string {\n const hash = target.indexOf('#');\n return hash <= 0 ? target : target.slice(0, hash);\n}\n\nfunction renderLink(link: Link): string {\n switch (link.form) {\n case 'wiki':\n return `[[${link.target}]]`;\n case 'autolink':\n return `<${link.target}>`;\n case 'reference':\n case 'shortcut':\n return `[${link.text}][${link.target}]`;\n default:\n return `[${link.text}](${link.target})`;\n }\n}\n\n/** Exposed for tests and for callers that classify their own sections. */\nexport { OBLIGATION_SECTIONS, sectionPathAt, WEAK_SECTIONS };\n"]}
1
+ {"version":3,"file":"extract.js","sourceRoot":"","sources":["../src/extract.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Document extraction: Markdown in, graph fragments out.\n *\n * This module is where domain-agnosticism is won or lost. It never requires a\n * repository to adopt a syntax. It reads what teams already write - front\n * matter, a `## Status` section, a checklist under `## Open Questions`, a link\n * that says \"deferred to ADR-0011\" - and turns each into a typed relation with a\n * source position.\n *\n * The one rule it holds to everywhere: **an inference that cannot be justified\n * is not made.** An unrecognised status becomes `unknown`, not a guess. A link\n * with no governing verb becomes a neutral `references`, not a dependency. Bare\n * identifiers found in prose are opportunistic and are dropped silently when\n * they do not resolve, because the alternative is reporting `SHA-256` as a\n * broken reference to specification 256.\n */\n\nimport { attr, attrList, directiveFor, parseDirectives, type Directive } from './directives.js';\nimport { identify, isExternal, normaliseRef, type DocumentIdentity, ID_KEYS } from './identity.js';\nimport { isStatusHeading, phaseFromPath, phaseOf, STATUS_KEYS, supersessionTargetsIn } from './lifecycle.js';\nimport { scanMarkdown, slugify, type Link, type ListItem, type ScannedDocument } from './markdown.js';\nimport { findSpecificationRegions, regionAt, type SpecificationRegion } from './sections.js';\nimport { resolveItemState } from './state.js';\nimport { refOf, type LineIndex } from './source.js';\nimport type {\n DocumentNode,\n EdgeKind,\n EdgeOrigin,\n ItemNode,\n ParseProblem,\n Phase,\n SourceRef,\n} from './types.js';\nimport { parseFrontMatter, toRecord, valuesOf, type YamlEntry } from './yaml.js';\n\n/* -------------------------------------------------------------------------- */\n/* Output */\n/* -------------------------------------------------------------------------- */\n\n/**\n * A relation that has been read but not yet resolved to a target node.\n *\n * Resolution needs the whole corpus, so extraction stops at the raw target text.\n */\nexport interface ReferenceCandidate {\n readonly kind: EdgeKind;\n /** Id of the node the relation was written on. */\n readonly from: string;\n /** The target exactly as written: a path, an identifier, or a URL. */\n readonly target: string;\n readonly origin: EdgeOrigin;\n readonly declaredAt: SourceRef;\n readonly raw: string;\n /**\n * When true the relation runs `target -> from`.\n *\n * `superseded-by: ADR-0009` written in ADR-0003 declares that *ADR-0009*\n * supersedes ADR-0003. The edge belongs to ADR-0009; the line a human must go\n * and fix is in ADR-0003, which is why `declaredAt` is tracked separately.\n */\n readonly inverted: boolean;\n /**\n * Opportunistic references are dropped in silence when they do not resolve.\n * Only deliberate ones - links, front matter, directives - are reported.\n */\n readonly opportunistic: boolean;\n}\n\nexport interface ExtractedDocument {\n readonly document: DocumentNode;\n readonly items: readonly ItemNode[];\n readonly references: readonly ReferenceCandidate[];\n readonly problems: readonly ParseProblem[];\n /** Heading slugs, for resolving `#anchor` references into this document. */\n readonly anchors: ReadonlySet<string>;\n readonly identity: DocumentIdentity;\n readonly scanned: ScannedDocument;\n /**\n * Specifications declared inside this file, each a document in its own right.\n *\n * Empty for the ordinary one-file-per-decision layout, which is why nothing\n * downstream had to change to support registers.\n */\n readonly subSpecifications: readonly ExtractedDocument[];\n /**\n * The file-level specification this one is a region of, if any.\n *\n * Recorded so the register's structure is a relation in the graph rather than\n * an accident of which offsets fall inside which: \"what decisions does this\n * register hold\" is a question worth being able to ask.\n */\n readonly containerId: string | null;\n}\n\n/* -------------------------------------------------------------------------- */\n/* Vocabulary */\n/* -------------------------------------------------------------------------- */\n\n/** Front-matter keys that declare a relation, and what they mean. */\nconst RELATION_KEYS: Readonly<Record<string, { kind: EdgeKind; inverted: boolean }>> = {\n supersedes: { kind: 'supersedes', inverted: false },\n supercedes: { kind: 'supersedes', inverted: false },\n replaces: { kind: 'supersedes', inverted: false },\n obsoletes: { kind: 'supersedes', inverted: false },\n 'superseded-by': { kind: 'supersedes', inverted: true },\n 'superceded-by': { kind: 'supersedes', inverted: true },\n 'replaced-by': { kind: 'supersedes', inverted: true },\n 'obsoleted-by': { kind: 'supersedes', inverted: true },\n amends: { kind: 'amends', inverted: false },\n extends: { kind: 'amends', inverted: false },\n 'amended-by': { kind: 'amends', inverted: true },\n 'depends-on': { kind: 'depends-on', inverted: false },\n dependencies: { kind: 'depends-on', inverted: false },\n requires: { kind: 'depends-on', inverted: false },\n assumes: { kind: 'assumes', inverted: false },\n 'blocked-by': { kind: 'blocked-by', inverted: false },\n blocks: { kind: 'blocked-by', inverted: true },\n 'delegates-to': { kind: 'delegates-to', inverted: false },\n 'delegated-to': { kind: 'delegates-to', inverted: false },\n 'tracked-in': { kind: 'delegates-to', inverted: false },\n related: { kind: 'relates-to', inverted: false },\n 'relates-to': { kind: 'relates-to', inverted: false },\n 'see-also': { kind: 'relates-to', inverted: false },\n references: { kind: 'references', inverted: false },\n refs: { kind: 'references', inverted: false },\n};\n\n/**\n * Phrases that give a link its meaning, longest-matching-nearest wins.\n *\n * Only phrases that genuinely commit the citing document are here. Vague ones\n * (\"see\", \"covered by\") stay out: a `references` edge is harmless, whereas a\n * wrongly inferred `assumes` edge produces a confident stale-premise finding\n * about a document that never depended on anything.\n */\nconst VERB_RULES: readonly { kind: EdgeKind; inverted: boolean; phrases: readonly string[] }[] = [\n {\n kind: 'supersedes',\n inverted: true,\n phrases: ['superseded by', 'superceded by', 'replaced by', 'obsoleted by', 'deprecated by', 'rolled into'],\n },\n { kind: 'supersedes', inverted: false, phrases: ['supersedes', 'supercedes', 'replaces', 'obsoletes', 'deprecates'] },\n { kind: 'amends', inverted: true, phrases: ['amended by', 'refined by', 'clarified by', 'revised by'] },\n { kind: 'amends', inverted: false, phrases: ['amends', 'refines', 'clarifies', 'revises'] },\n {\n kind: 'delegates-to',\n inverted: false,\n phrases: [\n 'delegated to',\n 'delegate to',\n 'deferred to',\n 'defer to',\n 'moved to',\n 'move to',\n 'tracked in',\n 'tracked by',\n 'handed off to',\n 'handed to',\n 'hand off to',\n 'follow up in',\n 'follow-up in',\n 'followup in',\n 'continued in',\n 'continues in',\n 'punted to',\n 'left to',\n 'belongs in',\n 'owned by',\n 'will be decided in',\n 'will be resolved in',\n 'will be handled in',\n 'will be handled by',\n 'will be answered in',\n 'to be decided in',\n 'to be resolved in',\n 'to be handled in',\n 'to be answered in',\n ],\n },\n {\n kind: 'blocked-by',\n inverted: false,\n phrases: ['blocked by', 'blocked on', 'waiting on', 'waiting for', 'gated on', 'gated by', 'unblocked by'],\n },\n { kind: 'blocked-by', inverted: true, phrases: ['blocks', 'blocking'] },\n {\n kind: 'depends-on',\n inverted: false,\n phrases: ['depends on', 'depend on', 'dependent on', 'requires', 'builds on', 'built on', 'relies on'],\n },\n { kind: 'depends-on', inverted: true, phrases: ['depended on by'] },\n {\n kind: 'assumes',\n inverted: false,\n phrases: [\n 'assumes',\n 'assuming',\n 'on the assumption of',\n 'as decided in',\n 'as established in',\n 'as established by',\n 'as stated in',\n 'as specified in',\n 'as required by',\n 'as mandated by',\n 'in accordance with',\n 'constrained by',\n 'mandated by',\n 'governed by',\n 'predicated on',\n 'rests on',\n 'follows from',\n 'justified by',\n // A constraint the citing document designs around. \"the row limit imposed\n // by ADR-0002\" is the archetypal stale premise: when ADR-0002 is retired,\n // this document is still working around a cap that no longer exists.\n 'imposed by',\n 'required by',\n 'dictated by',\n 'determined by',\n 'limited by',\n 'capped by',\n 'bounded by',\n 'defined by',\n 'defined in',\n 'specified by',\n 'set by',\n 'per',\n 'because',\n 'since',\n ],\n },\n];\n\n/**\n * Words that cancel a governing phrase standing before them.\n *\n * The window allows a short noun phrase between a verb and the reference it\n * governs - \"deferred to the sharding decision in [ADR-7]\" is one statement.\n * It cannot allow a negation. A table entry reading \"Owned by nobody today and\n * disclaimed by [138]\" was being read as a delegation *to* 138, which is the\n * opposite of what the sentence says, and an inference that inverts its source\n * is worse than no inference at all.\n */\nconst NEGATION = /(?:^|\\s)(?:no|not|nobody|none|never|neither|nor|nothing|without)(?:\\s|$)/;\n\n/** How close a governing phrase must sit to the reference it governs. */\nconst VERB_WINDOW = 40;\n\n/**\n * Every governing phrase compiled into one alternation, plus a lookup table.\n *\n * Classification runs on every reference in the corpus, and testing a hundred\n * phrases one at a time made it the most expensive thing extraction did. The\n * alternation is sorted longest-first so that at any given position the regex\n * prefers `partially resolved` over `resolved`, matching the precedence the\n * per-phrase search had. Lookarounds rather than `\\b`, because phrases contain\n * hyphens and `\\b` does the wrong thing around them.\n */\nconst VERB_LOOKUP: ReadonlyMap<string, Classification> = new Map(\n VERB_RULES.flatMap((rule) =>\n rule.phrases.map((phrase) => [phrase, { kind: rule.kind, inverted: rule.inverted }] as const),\n ),\n);\n\nconst VERB_PATTERN = new RegExp(\n `(?<![\\\\p{L}\\\\p{N}])(?:${[...VERB_LOOKUP.keys()]\n .sort((a, b) => b.length - a.length)\n .map((phrase) => phrase.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&'))\n .join('|')})(?![\\\\p{L}\\\\p{N}])`,\n 'gu',\n);\n\n/** Headings under which a link is bookkeeping rather than a commitment. */\nconst WEAK_SECTIONS: ReadonlySet<string> = new Set([\n 'see also',\n 'references',\n 'reference',\n 'related',\n 'related work',\n 'related decisions',\n 'related documents',\n 'links',\n 'further reading',\n 'prior art',\n 'history',\n 'changelog',\n 'change log',\n 'revision history',\n 'bibliography',\n 'sources',\n 'appendix',\n 'more information',\n 'resources',\n 'index',\n]);\n\n/** Headings whose bullets are obligations even without a checkbox. */\nconst OBLIGATION_SECTIONS: ReadonlySet<string> = new Set([\n 'open questions',\n 'open question',\n 'unresolved questions',\n 'unanswered questions',\n 'questions',\n 'open issues',\n 'action items',\n 'actions',\n 'todo',\n 'to do',\n 'to-do',\n 'todos',\n 'next steps',\n 'follow ups',\n 'follow-ups',\n 'followups',\n 'follow up',\n 'follow-up',\n 'unresolved',\n 'outstanding',\n 'outstanding questions',\n 'tasks',\n 'task list',\n 'work items',\n 'remaining work',\n 'decisions needed',\n 'blockers',\n 'parking lot',\n 'future work',\n 'deferred',\n]);\n\n/**\n * Prefixes that look like specification identifiers but never are.\n *\n * The corpus filter in `resolve.ts` is the real defence; this list only keeps\n * the obvious noise out of the candidate set.\n */\nconst NOT_A_FAMILY: ReadonlySet<string> = new Set([\n 'v',\n 'ver',\n 'version',\n 'p',\n 'pp',\n 'fig',\n 'figure',\n 'table',\n 'tbl',\n 'section',\n 'sect',\n 'sec',\n 'step',\n 'item',\n 'no',\n 'num',\n 'line',\n 'ln',\n 'col',\n 'port',\n 'pr',\n 'issue',\n 'gh',\n 'utf',\n 'ascii',\n 'sha',\n 'md',\n 'http',\n 'https',\n 'ipv',\n 'tls',\n 'ssl',\n 'es',\n 'ecma',\n 'x',\n 'h',\n 'p99',\n 'base',\n 'sql',\n 'ipv4',\n 'ipv6',\n 'arm',\n 'x86',\n 'win',\n 'node',\n 'python',\n 'java',\n 'go',\n 'c',\n 'cpp',\n]);\n\nconst BARE_REF = /\\b([A-Za-z][A-Za-z0-9]{0,14})[\\s._-]?(\\d{1,6})\\b/g;\n\n/* -------------------------------------------------------------------------- */\n/* Extraction */\n/* -------------------------------------------------------------------------- */\n\nexport interface ExtractInput {\n /** Repository-relative POSIX path. */\n readonly path: string;\n readonly text: string;\n /**\n * This file is a historical record: a log of what was decided, not a\n * decision. Matched against the caller's history patterns, because deciding\n * which files those are is a repository's business and not a guess this\n * layer could justify making. See ADR-0011.\n */\n readonly record?: boolean | undefined;\n}\n\n/**\n * Reads one file into graph fragments, one entry per specification in it.\n *\n * A file yields at least itself. It yields more when it is a register: a\n * heading that carries an identifier *and* declares a status is a specification\n * in its own right, with its own lifecycle, its own obligations and its own\n * relations. See ADR-0009.\n */\nexport function extractSpecifications(input: ExtractInput): ExtractedDocument[] {\n const first = extractDocument(input);\n return first === null ? [] : [first, ...(first.subSpecifications as ExtractedDocument[])];\n}\n\n/** Reads a file's own specification. Returns `null` when it opts out. */\nexport function extractDocument(input: ExtractInput): ExtractedDocument | null {\n const scanned = scanMarkdown(input.text);\n const directives = parseDirectives(scanned.comments);\n if (directives.some((d) => d.name === 'spec-ignore')) return null;\n\n const index = scanned.index;\n const file = input.path;\n const problems: ParseProblem[] = [];\n const at = (start: number, end: number): SourceRef => refOf(file, index, start, end);\n\n for (const directive of directives) {\n for (const unknown of directive.unknownAttributes) {\n problems.push({\n message: `unknown attribute \"${unknown}\" on @${directive.name}`,\n at: at(directive.start, directive.end),\n });\n }\n }\n\n const entries = scanned.frontMatter ? parseFrontMatter(scanned.frontMatter.raw, scanned.frontMatter.start) : [];\n const byKey = new Map<string, YamlEntry>();\n for (const entry of entries) byKey.set(entry.key, entry);\n\n const h1 = scanned.headings.find((h) => h.level === 1) ?? null;\n const frontMatterId = firstValue(byKey, ID_KEYS) ?? null;\n\n const identityOf = (declaredId: string | null, directive: Directive | null): DocumentIdentity =>\n identify({\n path: input.path,\n declaredId,\n declaredAliases: [\n ...(directive ? attrList(directive, 'aliases') : []),\n ...valuesOf(byKey.get('aliases')),\n ...valuesOf(byKey.get('alias')),\n ],\n heading: h1?.text ?? null,\n });\n\n // A `@spec-node` written inside a register's section belongs to that section,\n // not to the file. Finding the file's own therefore needs the regions, and\n // finding the regions needs the file's identity - so the identity is settled\n // provisionally first, then again once the file's own directive is known.\n const provisional = identityOf(frontMatterId, null);\n const provisionalRegions = findSpecificationRegions(scanned, directives, provisional.id);\n const nodeDirective =\n directives.find(\n (directive) =>\n directive.name === 'spec-node' &&\n !provisionalRegions.some(\n (region) =>\n (region.heading !== null || region.row !== null) &&\n directive.start >= region.start &&\n directive.end <= region.end,\n ),\n ) ?? null;\n\n const declaredId = (nodeDirective ? attr(nodeDirective, 'id')?.value : null) ?? frontMatterId;\n const identity = declaredId === frontMatterId && nodeDirective === null\n ? provisional\n : identityOf(declaredId, nodeDirective);\n\n const status = readStatus(scanned, byKey, nodeDirective, index, file);\n const pathPhase = phaseFromPath(input.path);\n // A record is a categorical statement about what the file *is*, made by\n // configuration or by an explicit directive, so it outranks a status word\n // that happened to be written inside it.\n const record = input.record === true || directives.some((directive) => directive.name === 'spec-history');\n const phase: Phase = record ? 'record' : status.phase !== 'unknown' ? status.phase : pathPhase;\n\n const title =\n (nodeDirective ? attr(nodeDirective, 'title')?.value : null) ??\n asString(byKey.get('title')) ??\n h1?.text ??\n identity.id;\n\n const document: DocumentNode = {\n id: identity.id,\n kind: 'document',\n title,\n at: at(0, Math.min(scanned.text.length, index.lineEnd(1))),\n path: input.path,\n aliases: identity.aliases,\n phase,\n rawStatus: status.raw,\n statusAt: status.at,\n frontMatter: toRecord(entries),\n };\n\n // A register's sections are specifications too. The file is always the first\n // region, so a one-decision file behaves exactly as it did before.\n const regions =\n identity.id === provisional.id ? provisionalRegions : findSpecificationRegions(scanned, directives, identity.id);\n // Every region but the first: a heading section, or a row of a register kept\n // as a table.\n const subSpecifications = regions\n .filter((region) => region.heading !== null || region.row !== null)\n .map((region) =>\n buildRegion({\n region,\n containerId: identity.id,\n input,\n scanned,\n directives,\n index,\n file,\n pathPhase,\n record,\n }),\n );\n\n const ownerAt = (offset: number): string => {\n const region = regionAt(regions, offset);\n if (region === null) return identity.id;\n const owner = subSpecifications.find((spec) => spec.region === region);\n return owner?.document.id ?? identity.id;\n };\n\n const allItems = extractItems({ scanned, directives, ownerAt, file, index });\n const documentAt = (offset: number): DocumentNode => {\n const id = ownerAt(offset);\n if (id === identity.id) return document;\n return subSpecifications.find((spec) => spec.document.id === id)?.document ?? document;\n };\n\n const allReferences = extractReferences({\n scanned,\n directives,\n document,\n documentAt,\n items: allItems,\n byKey,\n status,\n claimed: regions.flatMap((region) => [...region.claimed]),\n file,\n index,\n });\n\n // Hand each region the items and references that fall inside it.\n const ownItems = allItems.filter((item) => item.document === identity.id);\n const ownReferences = allReferences.filter((reference) => belongsTo(reference, identity.id, allItems));\n const anchors = new Set<string>(scanned.headings.map((h) => h.slug));\n\n const filled = subSpecifications.map((spec) => ({\n ...spec.extracted,\n items: allItems.filter((item) => item.document === spec.document.id),\n references: [\n // Column-declared relations first: they are typed by the header rather\n // than guessed from prose.\n ...spec.extracted.references,\n ...allReferences.filter((reference) => belongsTo(reference, spec.document.id, allItems)),\n ],\n }));\n\n return {\n document,\n items: ownItems,\n references: ownReferences,\n problems,\n anchors,\n identity,\n scanned,\n subSpecifications: filled,\n containerId: null,\n };\n}\n\n/** True when a reference was written on a document or on one of its items. */\nfunction belongsTo(reference: ReferenceCandidate, documentId: string, items: readonly ItemNode[]): boolean {\n if (reference.from === documentId) return true;\n const owner = items.find((item) => item.id === reference.from);\n return owner?.document === documentId;\n}\n\ninterface RegionInput {\n readonly region: SpecificationRegion;\n readonly containerId: string;\n readonly input: ExtractInput;\n readonly scanned: ScannedDocument;\n readonly directives: readonly Directive[];\n readonly index: LineIndex;\n readonly file: string;\n readonly pathPhase: Phase;\n /** The whole file is a historical record, so every part of it is one too. */\n readonly record: boolean;\n}\n\ninterface BuiltRegion {\n readonly region: SpecificationRegion;\n readonly document: DocumentNode;\n readonly extracted: ExtractedDocument;\n}\n\n/**\n * Turns one region into a specification.\n *\n * It produces exactly the `DocumentNode` a whole file produces, which is the\n * reason every rule, query and reporter works on registers without knowing they\n * exist. The only deliberate differences: the node is anchored at its heading\n * rather than at line one, it carries no front matter of its own, and it does\n * not claim the file's path as an alias - the file already does, and two nodes\n * answering to one path would make every link to that file ambiguous.\n */\nfunction buildRegion(context: RegionInput): BuiltRegion {\n const { region, input, scanned, index, file, pathPhase, record } = context;\n const at = (start: number, end: number): SourceRef => refOf(file, index, start, end);\n\n const identity = identify({\n path: input.path,\n declaredId: region.declaredId,\n declaredAliases: region.directive ? attrList(region.directive, 'aliases') : [],\n heading: region.title,\n includePathAliases: false,\n });\n\n const declaredStatus = region.directive ? attr(region.directive, 'status') : null;\n const rawStatus = declaredStatus?.value ?? region.status?.text ?? null;\n const statusAt = declaredStatus\n ? at(declaredStatus.start, declaredStatus.end)\n : region.status\n ? at(region.status.start, region.status.end)\n : null;\n const declaredPhase = phaseOf(rawStatus);\n\n const document: DocumentNode = {\n id: identity.id,\n kind: 'document',\n title: (region.directive ? attr(region.directive, 'title')?.value : null) ?? region.title ?? identity.id,\n // Anchored at its heading, or at the row when the register is a table.\n at: at(region.start, Math.min(region.end, region.heading?.end ?? region.row?.end ?? region.end)),\n path: input.path,\n aliases: identity.aliases,\n // A section of a journal is part of the journal, whatever status word it\n // wrote for itself. Being a record is a statement about the file made from\n // outside it, and it does not stop at a heading.\n phase: record ? 'record' : declaredPhase !== 'unknown' ? declaredPhase : pathPhase,\n rawStatus,\n statusAt,\n frontMatter: {},\n };\n\n const anchors = new Set<string>(\n scanned.headings.filter((h) => h.start >= region.start && h.start < region.end).map((h) => h.slug),\n );\n\n // Relations a table declares by column, typed by the header the author wrote.\n const references: ReferenceCandidate[] = region.relations.map((relation) => ({\n kind: relation.kind,\n from: document.id,\n target: relation.target,\n origin: 'front-matter' as const,\n declaredAt: at(relation.start, relation.end),\n raw: `${relation.column}: ${relation.target}`,\n inverted: relation.inverted,\n opportunistic: false,\n }));\n\n return {\n region,\n document,\n extracted: {\n document,\n items: [],\n references,\n problems: [],\n anchors,\n identity,\n scanned,\n subSpecifications: [],\n containerId: context.containerId,\n },\n };\n}\n\n/* -------------------------------------------------------------------------- */\n/* Status */\n/* -------------------------------------------------------------------------- */\n\ninterface StatusReading {\n readonly raw: string | null;\n readonly at: SourceRef | null;\n readonly phase: Phase;\n}\n\n/**\n * Finds the document status.\n *\n * Looks in the three places teams actually put it, in descending order of how\n * deliberate each is: a directive, a front-matter field, then the body of a\n * `## Status` section. A repository using none of them still gets a phase from\n * its directory layout, which is handled by the caller.\n */\nfunction readStatus(\n scanned: ScannedDocument,\n byKey: ReadonlyMap<string, YamlEntry>,\n nodeDirective: Directive | null,\n index: LineIndex,\n file: string,\n): StatusReading {\n if (nodeDirective) {\n const declared = attr(nodeDirective, 'status');\n if (declared) {\n return {\n raw: declared.value,\n at: refOf(file, index, declared.start, declared.end),\n phase: phaseOf(declared.value),\n };\n }\n }\n\n for (const key of STATUS_KEYS) {\n const entry = byKey.get(key);\n if (!entry) continue;\n const raw = typeof entry.value === 'string' ? entry.value : entry.value.join(', ');\n if (raw.trim().length === 0) continue;\n return {\n raw,\n at: refOf(file, index, entry.valueStart, entry.end),\n phase: phaseOf(raw),\n };\n }\n\n const heading = scanned.headings.find((h) => isStatusHeading(h.text));\n if (heading) {\n const body = statusSectionBody(scanned, heading.line);\n if (body) {\n return {\n raw: body.text,\n at: refOf(file, index, body.start, body.end),\n phase: phaseOf(body.text),\n };\n }\n }\n\n return { raw: null, at: null, phase: 'unknown' };\n}\n\n/** The first non-blank line under a `## Status` heading. */\nfunction statusSectionBody(\n scanned: ScannedDocument,\n headingLine: number,\n): { text: string; start: number; end: number } | null {\n for (const line of scanned.lines) {\n if (line.line <= headingLine) continue;\n if (line.blank) continue;\n if (line.code) return null;\n const trimmed = line.content.trim();\n // A heading immediately after means the section is empty.\n if (trimmed.startsWith('#')) return null;\n const offset = line.contentStart + line.content.indexOf(trimmed);\n // Bullet lists under Status are a status history; take the first entry.\n const cleaned = trimmed.replace(/^[-*+]\\s+/, '');\n const start = offset + (trimmed.length - cleaned.length);\n return { text: cleaned, start, end: start + cleaned.length };\n }\n return null;\n}\n\n/* -------------------------------------------------------------------------- */\n/* Items */\n/* -------------------------------------------------------------------------- */\n\ninterface ItemContext {\n readonly scanned: ScannedDocument;\n readonly directives: readonly Directive[];\n /** The specification that owns an offset, which in a register is a section. */\n readonly ownerAt: (offset: number) => string;\n readonly file: string;\n readonly index: LineIndex;\n}\n\nfunction extractItems(context: ItemContext): ItemNode[] {\n const { scanned, directives, ownerAt, file, index } = context;\n const out: ItemNode[] = [];\n const ordinals = new Map<string, number>();\n\n for (const item of scanned.listItems) {\n const section = sectionPathAt(scanned, item.start);\n const inObligationSection = section.some((heading) => OBLIGATION_SECTIONS.has(normaliseHeading(heading)));\n const directive = directiveFor(directives, 'spec-item', { start: item.start, end: item.end }, 200);\n\n if (!isObligation(item, inObligationSection, directive)) continue;\n\n const documentId = ownerAt(item.start);\n const slug = section.length > 0 ? slugify(section[section.length - 1] as string) : 'item';\n // Ordinals count within a specification, so two decisions in one register\n // each get their own `#open-questions.1` rather than sharing a sequence.\n const key = `${documentId}#${slug}`;\n const ordinal = (ordinals.get(key) ?? 0) + 1;\n ordinals.set(key, ordinal);\n\n const declaredId = directive ? attr(directive, 'id')?.value : null;\n const id = `${documentId}#${declaredId ?? `${slug}.${ordinal}`}`;\n\n const state = resolveItemState({\n file,\n index,\n item,\n section,\n directive,\n inObligationSection,\n });\n\n out.push({\n id,\n kind: 'item',\n title: (directive ? attr(directive, 'title')?.value : null) ?? summarise(item.firstLine),\n at: refOf(file, index, item.start, item.end),\n document: documentId,\n section,\n text: summarise(item.firstLine),\n body: item.body,\n disposition: state.disposition,\n openness: state.openness,\n evidence: state.evidence,\n conflicts: state.conflicts,\n });\n }\n\n return out;\n}\n\n/**\n * Decides whether a bullet is an obligation.\n *\n * A checkbox or an explicit directive always makes one. Otherwise only\n * top-level bullets under a heading like \"Open Questions\" count: promoting\n * every bullet in a specification would bury the real obligations under the\n * document's own prose.\n */\nfunction isObligation(item: ListItem, inObligationSection: boolean, directive: Directive | null): boolean {\n if (directive !== null) return true;\n if (item.checkbox !== null) return true;\n return inObligationSection && item.depth === 0;\n}\n\n/** The heading path enclosing an offset, outermost first. */\nfunction sectionPathAt(scanned: ScannedDocument, offset: number): string[] {\n const path: { level: number; text: string }[] = [];\n for (const heading of scanned.headings) {\n if (heading.start > offset) break;\n while (path.length > 0 && (path[path.length - 1] as { level: number }).level >= heading.level) path.pop();\n path.push({ level: heading.level, text: heading.text });\n }\n return path.map((entry) => entry.text);\n}\n\n/**\n * Memoised because it is called for every heading above every reference and\n * every item, and a corpus has only a handful of distinct headings - `Context`,\n * `Decision`, `Open Questions`, `See also` - repeated thousands of times.\n */\nconst headingCache = new Map<string, string>();\n\nfunction normaliseHeading(text: string): string {\n const cached = headingCache.get(text);\n if (cached !== undefined) return cached;\n const normalised = text\n .toLowerCase()\n .replace(/[`*_~]/g, '')\n .replace(/[^\\p{L}\\p{N}\\s-]/gu, '')\n .replace(/\\s+/g, ' ')\n .trim();\n // Bounded so a pathological corpus of unique headings cannot grow it forever.\n if (headingCache.size < 4096) headingCache.set(text, normalised);\n return normalised;\n}\n\n/**\n * One-line form of an item for reports.\n *\n * Link syntax is flattened to its label. A finding that quotes the obligation\n * back at the reader should read like the sentence they wrote, not like the\n * Markdown source of it.\n */\nfunction summarise(text: string): string {\n const flat = text\n .replace(/!?\\[([^\\]]*)\\]\\([^)]*\\)/g, '$1')\n // `[[target|display]]` keeps the display half: that is the text a reader\n // of the rendered document actually sees.\n .replace(/\\[\\[(?:[^\\]|]*\\|)?([^\\]]*)\\]\\]/g, '$1')\n .replace(/\\s+/g, ' ')\n .trim();\n return flat.length <= 120 ? flat : `${flat.slice(0, 117)}...`;\n}\n\n/* -------------------------------------------------------------------------- */\n/* References */\n/* -------------------------------------------------------------------------- */\n\ninterface ReferenceContext {\n readonly scanned: ScannedDocument;\n readonly directives: readonly Directive[];\n readonly document: DocumentNode;\n /** The specification that owns an offset, for a reference outside any item. */\n readonly documentAt: (offset: number) => DocumentNode;\n readonly items: readonly ItemNode[];\n readonly byKey: ReadonlyMap<string, YamlEntry>;\n readonly status: StatusReading;\n /** Cell ranges already typed by a table column header. */\n readonly claimed: readonly { start: number; end: number }[];\n readonly file: string;\n readonly index: LineIndex;\n}\n\n/** True when an offset falls in a cell a column header already accounted for. */\nfunction isClaimed(claimed: readonly { start: number; end: number }[], offset: number): boolean {\n return claimed.some((range) => offset >= range.start && offset < range.end);\n}\n\nfunction extractReferences(context: ReferenceContext): ReferenceCandidate[] {\n const { scanned, directives, document, documentAt, items, byKey, status, claimed, file, index } = context;\n const out: ReferenceCandidate[] = [];\n const at = (start: number, end: number): SourceRef => refOf(file, index, start, end);\n\n // Front matter.\n for (const [key, relation] of Object.entries(RELATION_KEYS)) {\n const entry = byKey.get(key) ?? byKey.get(key.replace(/-/g, '_'));\n if (!entry) continue;\n for (const value of valuesOf(entry)) {\n const target = cleanTarget(value);\n if (target.length === 0) continue;\n out.push({\n kind: relation.kind,\n from: document.id,\n target,\n origin: 'front-matter',\n declaredAt: at(entry.valueStart, entry.end),\n raw: `${key}: ${value}`,\n inverted: relation.inverted,\n opportunistic: false,\n });\n }\n }\n\n // `status: Superseded by ADR-0009` is the most common supersession record of\n // all, and it never appears as a field of its own.\n if (status.raw && status.at) {\n for (const target of supersessionTargetsIn(status.raw)) {\n const cleaned = cleanTarget(target);\n if (cleaned.length === 0) continue;\n out.push({\n kind: 'supersedes',\n from: document.id,\n target: cleaned,\n origin: 'front-matter',\n declaredAt: status.at,\n raw: status.raw,\n inverted: true,\n opportunistic: true,\n });\n }\n }\n\n // Explicit edge directives.\n for (const directive of directives) {\n if (directive.name !== 'spec-edge') continue;\n const kind = attr(directive, 'kind')?.value as EdgeKind | undefined;\n const to = attr(directive, 'to');\n const from = attr(directive, 'from');\n if (!kind) continue;\n const owner = ownerOf(items, directive.start) ?? documentAt(directive.start).id;\n if (to) {\n out.push({\n kind,\n from: owner,\n target: to.value,\n origin: 'directive',\n declaredAt: at(to.start, to.end),\n raw: `@spec-edge kind=\"${kind}\" to=\"${to.value}\"`,\n inverted: false,\n opportunistic: false,\n });\n }\n if (from) {\n out.push({\n kind,\n from: owner,\n target: from.value,\n origin: 'directive',\n declaredAt: at(from.start, from.end),\n raw: `@spec-edge kind=\"${kind}\" from=\"${from.value}\"`,\n inverted: true,\n opportunistic: false,\n });\n }\n }\n\n // Prose links. A cell whose meaning a column header already gave is skipped,\n // so `| ADR-0002 | ... | [ADR-0001](0001.md) |` yields one typed edge rather\n // than a typed edge and a neutral citation beside it.\n const linked = new Set<string>();\n for (const link of scanned.links) {\n if (link.form === 'definition') continue;\n if (isClaimed(claimed, link.start)) continue;\n const target = cleanTarget(link.target);\n if (target.length === 0) continue;\n if (isExternal(target)) continue;\n\n const owner = ownerOf(items, link.start) ?? documentAt(link.start).id;\n const section = sectionPathAt(scanned, link.start);\n const classified = classifyReference(scanned.masked, link.start, link.end, section);\n\n linked.add(normaliseRef(stripAnchor(target)));\n out.push({\n kind: classified.kind,\n from: owner,\n target,\n origin: 'link',\n declaredAt: at(link.targetStart, link.targetStart + link.target.length),\n raw: renderLink(link),\n inverted: classified.inverted,\n opportunistic: false,\n });\n }\n\n // Bare identifiers in prose. Everything already covered by a link is skipped\n // so a citation written as `[ADR-7](0007.md)` is not counted twice.\n for (const bare of findBareReferences(scanned)) {\n const key = normaliseRef(bare.text);\n if (linked.has(key)) continue;\n if (isClaimed(claimed, bare.start)) continue;\n const owner = ownerOf(items, bare.start) ?? documentAt(bare.start).id;\n const section = sectionPathAt(scanned, bare.start);\n const classified = classifyReference(scanned.masked, bare.start, bare.end, section);\n out.push({\n kind: classified.kind,\n from: owner,\n target: bare.text,\n origin: 'text',\n declaredAt: at(bare.start, bare.end),\n raw: bare.text,\n inverted: classified.inverted,\n opportunistic: true,\n });\n }\n\n return withoutOverlaps(out);\n}\n\n/**\n * Collapses candidates that describe the same written citation.\n *\n * `Superseded by ADR-0009` in a status section is read twice: the status\n * reader reports the whole line, and prose scanning reports the identifier\n * inside it. One written citation is one reference - so when the target\n * resolves it must not become two edges, and when it does not it must not\n * become two findings on one line a reader can only fix once.\n *\n * The narrower span wins, because it points at the text that has to change.\n *\n * Only overlapping spans collapse. Two sentences citing the same missing\n * document are two citations, and silently reporting one of them would leave\n * the other to be discovered on the next run.\n */\nfunction withoutOverlaps(candidates: readonly ReferenceCandidate[]): ReferenceCandidate[] {\n const out: ReferenceCandidate[] = [];\n for (const candidate of candidates) {\n const index = out.findIndex(\n (other) =>\n other.kind === candidate.kind &&\n other.from === candidate.from &&\n other.inverted === candidate.inverted &&\n normaliseRef(other.target) === normaliseRef(candidate.target) &&\n overlapping(other.declaredAt, candidate.declaredAt),\n );\n if (index === -1) {\n out.push(candidate);\n continue;\n }\n const held = out[index] as ReferenceCandidate;\n // The status reader runs before prose scanning, so today the wider span is\n // always the one already held and this comparison always replaces it. It is\n // written as a comparison rather than an unconditional swap because which\n // reader runs first is not a property worth depending on, and a mutant that\n // makes it unconditional is equivalent only by that accident.\n if (width(candidate.declaredAt) < width(held.declaredAt)) out[index] = candidate;\n }\n return out;\n}\n\nconst width = (ref: SourceRef): number => ref.span.end.offset - ref.span.start.offset;\n\n/**\n * Whether two spans cover any of the same text.\n *\n * Offsets alone, with no file comparison: every candidate here was built from\n * one scan of one file, so there is no second file for them to be offsets into.\n */\nfunction overlapping(a: SourceRef, b: SourceRef): boolean {\n return a.span.start.offset < b.span.end.offset && b.span.start.offset < a.span.end.offset;\n}\n\n/** The item whose block contains an offset, if any. */\nfunction ownerOf(items: readonly ItemNode[], offset: number): string | null {\n let best: ItemNode | null = null;\n for (const item of items) {\n const span = item.at.span;\n if (offset < span.start.offset || offset >= span.end.offset) continue;\n // Innermost wins when items nest.\n if (best === null || span.start.offset > best.at.span.start.offset) best = item;\n }\n return best?.id ?? null;\n}\n\nexport interface Classification {\n readonly kind: EdgeKind;\n readonly inverted: boolean;\n}\n\n/**\n * Decides what a reference means from the words around it.\n *\n * The nearest governing phrase within {@link VERB_WINDOW} characters wins, and\n * the search never crosses a sentence boundary. With nothing to go on, a\n * reference under a \"See also\" heading is bookkeeping and everything else is a\n * neutral citation.\n */\nexport function classifyReference(\n text: string,\n start: number,\n end: number,\n section: readonly string[],\n): Classification {\n const before = sentenceBefore(text, start);\n\n // Left to right, so the last match within the window is the nearest one - and\n // the nearest governing phrase is the one that governs.\n let best: Classification | null = null;\n VERB_PATTERN.lastIndex = 0;\n for (let m = VERB_PATTERN.exec(before); m !== null; m = VERB_PATTERN.exec(before)) {\n const phrase = m[0] as string;\n const end = (m.index ?? 0) + phrase.length;\n const distance = before.length - end;\n if (distance > VERB_WINDOW) continue;\n // What sits between the phrase and the reference has to be connective. A\n // negation in there reverses the claim the phrase would otherwise make.\n if (NEGATION.test(before.slice(end))) continue;\n const rule = VERB_LOOKUP.get(phrase);\n if (rule) best = rule;\n }\n\n if (best) return best;\n\n // \"[ADR-0009] supersedes this decision\": the reference is the subject, so the\n // relation runs the other way.\n const after = sentenceAfter(text, end);\n for (const rule of VERB_RULES) {\n if (rule.inverted) continue;\n for (const phrase of rule.phrases) {\n if (!after.startsWith(phrase)) continue;\n if (rule.kind === 'assumes' || rule.kind === 'depends-on') continue;\n return { kind: rule.kind, inverted: true };\n }\n }\n\n const innermost = section.length > 0 ? normaliseHeading(section[section.length - 1] as string) : '';\n if (WEAK_SECTIONS.has(innermost)) return { kind: 'relates-to', inverted: false };\n for (const heading of section) {\n if (WEAK_SECTIONS.has(normaliseHeading(heading))) return { kind: 'relates-to', inverted: false };\n }\n\n return { kind: 'references', inverted: false };\n}\n\n/** A sentence end, a blank line, or the start of a new block-level item. */\n/**\n * A table cell edge ends a statement too.\n *\n * The pipe matters more than it looks. A table row is a list of independent\n * fields, and without it the look-behind window reaches back across the row\n * boundary into the previous row's prose. An index of archived documents whose\n * last column ended \"...before assuming the drift was fixed\" turned every\n * following row's link into an `assumes` edge, and so turned every archived\n * document it listed into a stale premise.\n */\nconst STATEMENT_BREAK = /[.?!;]\\s|\\n\\s*\\n|\\n\\s*[-*+>#]|\\|/g;\n\n/**\n * Lower-cased, whitespace-collapsed text back to the start of the statement.\n *\n * The search stops at the last boundary: a governing phrase in the *previous*\n * sentence does not govern this reference. \"We deferred that to ADR-3. See also\n * [ADR-9].\" must not read as a delegation to ADR-9.\n */\nfunction sentenceBefore(text: string, start: number): string {\n const window = text.slice(Math.max(0, start - 160), start);\n let cut = 0;\n STATEMENT_BREAK.lastIndex = 0;\n for (let m = STATEMENT_BREAK.exec(window); m !== null; m = STATEMENT_BREAK.exec(window)) {\n cut = (m.index ?? 0) + (m[0] as string).length;\n }\n return window\n .slice(cut)\n .toLowerCase()\n .replace(/[`*_~\"'()\\[\\],]/g, ' ')\n .replace(/\\s+/g, ' ');\n}\n\nfunction sentenceAfter(text: string, end: number): string {\n const window = text.slice(end, Math.min(text.length, end + 80));\n const stop = /[.?!;\\n|]/.exec(window);\n const cut = stop ? window.slice(0, stop.index) : window;\n return cut.toLowerCase().replace(/[`*_~\"'()\\[\\],]/g, ' ').replace(/\\s+/g, ' ').trim();\n}\n\ninterface BareReference {\n readonly text: string;\n readonly start: number;\n readonly end: number;\n}\n\n/**\n * Finds identifiers written as plain prose, such as \"as decided in ADR-0007\".\n *\n * Link constructs are blanked first. Without that, `[ADR-7](https://x/adr-7)`\n * would yield three references to the same thing - one real and two harvested\n * out of a URL - which is precisely the mis-match that makes hand-rolled regex\n * checks untrustworthy.\n */\nfunction findBareReferences(scanned: ScannedDocument): BareReference[] {\n // Slice-based for the same reason as the scanner's masking: this runs over\n // every document, and a per-character array is the wrong shape for the job.\n const source = scanned.masked;\n let text = '';\n let cursor = 0;\n for (const link of scanned.links) {\n const start = Math.max(link.start, cursor);\n const end = Math.min(link.end, source.length);\n if (end <= start) continue;\n text += source.slice(cursor, start);\n text += source.slice(start, end).replace(/[^\\n\\r]/g, ' ');\n cursor = end;\n }\n text += source.slice(cursor);\n\n const out: BareReference[] = [];\n BARE_REF.lastIndex = 0;\n for (let m = BARE_REF.exec(text); m !== null; m = BARE_REF.exec(text)) {\n const prefix = (m[1] as string).toLowerCase();\n if (NOT_A_FAMILY.has(prefix)) continue;\n if (prefix.length < 2) continue;\n const start = m.index ?? 0;\n // A token glued to a path separator or an extension is not a citation.\n const before = text[start - 1] ?? ' ';\n const after = text[start + (m[0] as string).length] ?? ' ';\n if (before === '/' || before === '.' || after === '/') continue;\n out.push({ text: m[0] as string, start, end: start + (m[0] as string).length });\n }\n return out;\n}\n\n/* -------------------------------------------------------------------------- */\n/* Helpers */\n/* -------------------------------------------------------------------------- */\n\nfunction firstValue(byKey: ReadonlyMap<string, YamlEntry>, keys: readonly string[]): string | null {\n for (const key of keys) {\n const entry = byKey.get(key);\n if (!entry) continue;\n const value = asString(entry);\n if (value !== null && value.length > 0) return value;\n }\n return null;\n}\n\nfunction asString(entry: YamlEntry | undefined): string | null {\n if (!entry) return null;\n if (typeof entry.value === 'string') return entry.value.trim().length > 0 ? entry.value.trim() : null;\n return entry.value.length > 0 ? (entry.value[0] as string) : null;\n}\n\n/** Strips Markdown decoration a target may still be wearing. */\nfunction cleanTarget(value: string): string {\n return value\n .trim()\n .replace(/^[`'\"<(\\[]+/, '')\n .replace(/[`'\">)\\]]+$/, '')\n .replace(/[.,;]+$/, '')\n .trim();\n}\n\nfunction stripAnchor(target: string): string {\n const hash = target.indexOf('#');\n return hash <= 0 ? target : target.slice(0, hash);\n}\n\nfunction renderLink(link: Link): string {\n switch (link.form) {\n case 'wiki':\n return `[[${link.target}]]`;\n case 'autolink':\n return `<${link.target}>`;\n case 'reference':\n case 'shortcut':\n return `[${link.text}][${link.target}]`;\n default:\n return `[${link.text}](${link.target})`;\n }\n}\n\n/** Exposed for tests and for callers that classify their own sections. */\nexport { OBLIGATION_SECTIONS, sectionPathAt, WEAK_SECTIONS };\n"]}
package/dist/resolve.js CHANGED
@@ -129,8 +129,19 @@ function buildIndex(extracted) {
129
129
  set.add(id);
130
130
  index.byAlias.set(alias, set);
131
131
  }
132
- for (const path of pathKeys(entry.document.path))
133
- index.byPath.set(path, id);
132
+ // Only a file answers to its path. A region keeps the path on its node, so a
133
+ // finding can say where it lives and `document[path=...]` can select it, but
134
+ // it must not be reachable *by* that path: two nodes answering to one path
135
+ // makes every link to the file ambiguous, and this index resolves a
136
+ // collision by keeping whichever was written last. A link to a file holding
137
+ // a register bound to its final row, quietly and with no diagnostic, and
138
+ // anchors were then checked against that row's span rather than the file's.
139
+ // ADR-0009 said a region does not claim the file's path; this is the index
140
+ // where that had to be true.
141
+ if (entry.containerId === null) {
142
+ for (const path of pathKeys(entry.document.path))
143
+ index.byPath.set(path, id);
144
+ }
134
145
  if (entry.identity.family !== null && entry.identity.number !== null) {
135
146
  index.families.add(entry.identity.family);
136
147
  const key = `${entry.identity.family}:${entry.identity.number}`;
@@ -1 +1 @@
1
- {"version":3,"file":"resolve.js","sourceRoot":"","sources":["../src/resolve.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Corpus-level reference resolution - the foreign-key check.\n *\n * Extraction produces relations whose targets are still just text. This module\n * turns each into an edge or into an explicit, reportable failure. The whole\n * value of the exercise is in refusing to do either job carelessly:\n *\n * - **A deliberate reference that does not resolve is an error.** A link, a\n * front-matter field or a directive naming a document that does not exist is\n * a broken foreign key, and silence about it is how reference graphs rot.\n * - **An opportunistic reference that does not resolve is nothing.** `ADR-0007`\n * written in prose is a citation; `SHA-256` is not. Since the two are\n * indistinguishable in isolation, bare identifiers are only reported when\n * their family already exists in the corpus - so `ADR-0099` in a repository\n * full of ADRs is a finding, and `T-1000` in the same repository is not.\n * - **Two candidates is worse than none.** A reference that matches several\n * documents is reported as ambiguous rather than silently bound to whichever\n * one happened to be indexed first.\n */\n\nimport type { ExtractedDocument, ReferenceCandidate } from './extract.js';\nimport {\n isDocumentTarget,\n isExternal,\n looksLikePath,\n normaliseRef,\n parseBareRef,\n parsePrefixedRef,\n splitAnchor,\n} from './identity.js';\nimport { basenamePosix, extnamePosix, resolveFrom } from './paths.js';\nimport type { DanglingRef, DocumentNode, Edge, ItemNode, ParseProblem, SpecNode } from './types.js';\n\nexport interface ResolveOptions {\n /**\n * Whether a repository-relative path exists on disk.\n *\n * Used only to tell \"you linked to a file that is not a specification\" apart\n * from \"you linked to nothing at all\", which are different mistakes with\n * different fixes.\n */\n readonly fileExists?: ((path: string) => boolean) | undefined;\n /**\n * Targets whose failure to resolve should not be reported.\n *\n * This is a *suppression* filter, not a resolution one: it is consulted only\n * when a reference has already failed to resolve. A reference that resolves\n * still becomes an edge no matter what this says, so no amount of\n * configuration can silently delete a relation from the graph.\n */\n readonly isIgnoredReference?: ((target: string) => boolean) | undefined;\n /**\n * Families that are never citations in this repository.\n *\n * `RFC 2119` is the canonical case: every specification cites it, and a\n * repository that keeps its own `RFC-*` documents will otherwise read that\n * sentence as a dangling reference to a local RFC 2119 it does not have.\n * Consulted only after resolution has failed, like every other filter here.\n */\n readonly isIgnoredFamily?: ((family: string) => boolean) | undefined;\n}\n\nexport interface ResolvedCorpus {\n readonly nodes: ReadonlyMap<string, SpecNode>;\n readonly documents: readonly DocumentNode[];\n readonly items: readonly ItemNode[];\n readonly edges: readonly Edge[];\n readonly dangling: readonly DanglingRef[];\n readonly problems: readonly ParseProblem[];\n}\n\ninterface Index {\n readonly byId: Map<string, string>;\n readonly byAlias: Map<string, Set<string>>;\n readonly byPath: Map<string, string>;\n readonly byFamilyNumber: Map<string, Set<string>>;\n readonly families: Set<string>;\n readonly anchors: Map<string, ReadonlySet<string>>;\n readonly itemIds: Set<string>;\n readonly familyOf: Map<string, string | null>;\n}\n\n/** Resolves every extracted reference against the whole corpus. */\nexport function resolveCorpus(\n extracted: readonly ExtractedDocument[],\n options: ResolveOptions = {},\n): ResolvedCorpus {\n const index = buildIndex(extracted);\n const nodes = new Map<string, SpecNode>();\n const documents: DocumentNode[] = [];\n const items: ItemNode[] = [];\n const problems: ParseProblem[] = [];\n\n for (const entry of extracted) {\n const existing = nodes.get(entry.document.id);\n if (existing && existing.kind === 'document') {\n problems.push({\n message: `duplicate document id \"${entry.document.id}\", already declared by ${existing.path}`,\n at: entry.document.at,\n });\n continue;\n }\n nodes.set(entry.document.id, entry.document);\n documents.push(entry.document);\n for (const item of entry.items) {\n nodes.set(item.id, item);\n items.push(item);\n }\n problems.push(...entry.problems);\n }\n\n const edges: Edge[] = [];\n const dangling: DanglingRef[] = [];\n const byKey = new Map<string, number>();\n\n // Structural edges: a register contains the specifications written inside it.\n for (const entry of extracted) {\n if (entry.containerId === null) continue;\n if (!nodes.has(entry.containerId) || !nodes.has(entry.document.id)) continue;\n edges.push({\n kind: 'contains',\n from: entry.containerId,\n to: entry.document.id,\n origin: 'structural',\n declaredAt: entry.document.at,\n raw: entry.document.title,\n declaredIn: [entry.document.at.file],\n reflexive: false,\n });\n }\n\n // Structural edges: a document contains its items.\n for (const item of items) {\n edges.push({\n kind: 'contains',\n from: item.document,\n to: item.id,\n origin: 'structural',\n declaredAt: item.at,\n raw: item.text,\n declaredIn: [item.at.file],\n reflexive: false,\n });\n }\n\n for (const entry of extracted) {\n for (const candidate of entry.references) {\n if (!nodes.has(candidate.from)) continue;\n const outcome = resolveOne(candidate, entry, index, nodes, options);\n if (outcome === null) continue;\n if ('reason' in outcome) {\n dangling.push(outcome);\n continue;\n }\n // Collapse duplicates: the same relation stated twice is one edge - but\n // every declaration site is kept, because a supersession recorded in only\n // one of the two documents is itself a finding.\n const key = `${outcome.kind} ${outcome.from} ${outcome.to}`;\n const existing = byKey.get(key);\n if (existing !== undefined) {\n const previous = edges[existing] as Edge;\n if (!previous.declaredIn.includes(outcome.declaredAt.file)) {\n edges[existing] = { ...previous, declaredIn: [...previous.declaredIn, outcome.declaredAt.file] };\n }\n continue;\n }\n byKey.set(key, edges.length);\n edges.push(outcome);\n }\n }\n\n return { nodes, documents, items, edges, dangling, problems };\n}\n\n/* -------------------------------------------------------------------------- */\n/* Indexing */\n/* -------------------------------------------------------------------------- */\n\nfunction buildIndex(extracted: readonly ExtractedDocument[]): Index {\n const index: Index = {\n byId: new Map(),\n byAlias: new Map(),\n byPath: new Map(),\n byFamilyNumber: new Map(),\n families: new Set(),\n anchors: new Map(),\n itemIds: new Set(),\n familyOf: new Map(),\n };\n\n for (const entry of extracted) {\n const id = entry.document.id;\n index.byId.set(normaliseRef(id), id);\n index.anchors.set(id, entry.anchors);\n index.familyOf.set(id, entry.identity.family);\n\n for (const alias of entry.document.aliases) {\n const set = index.byAlias.get(alias) ?? new Set<string>();\n set.add(id);\n index.byAlias.set(alias, set);\n }\n\n for (const path of pathKeys(entry.document.path)) index.byPath.set(path, id);\n\n if (entry.identity.family !== null && entry.identity.number !== null) {\n index.families.add(entry.identity.family);\n const key = `${entry.identity.family}:${entry.identity.number}`;\n const set = index.byFamilyNumber.get(key) ?? new Set<string>();\n set.add(id);\n index.byFamilyNumber.set(key, set);\n }\n\n for (const item of entry.items) index.itemIds.add(item.id);\n }\n\n return index;\n}\n\n/** Every spelling of a path that a link might use. */\nfunction pathKeys(path: string): string[] {\n const keys = new Set<string>([path.toLowerCase()]);\n const extension = extnamePosix(path);\n if (extension.length > 0) keys.add(path.slice(0, path.length - extension.length).toLowerCase());\n // `docs/adr/0007/README.md` is also addressed as `docs/adr/0007`.\n const base = basenamePosix(path);\n if (/^(readme|index)\\./i.test(base)) {\n const parent = path.slice(0, path.length - base.length - 1);\n if (parent.length > 0) keys.add(parent.toLowerCase());\n }\n return [...keys];\n}\n\n/* -------------------------------------------------------------------------- */\n/* Resolution */\n/* -------------------------------------------------------------------------- */\n\nfunction resolveOne(\n candidate: ReferenceCandidate,\n entry: ExtractedDocument,\n index: Index,\n nodes: ReadonlyMap<string, SpecNode>,\n options: ResolveOptions,\n): Edge | DanglingRef | null {\n const { target: bare, anchor } = splitAnchor(candidate.target);\n\n // A pure `#anchor` points inside the citing document.\n if (bare.length === 0 && anchor !== null) {\n return bindAnchor(candidate, entry.document.id, anchor, index, nodes, options);\n }\n\n if (isExternal(bare)) return null;\n // A link to source code, an image or a config file is not a specification\n // reference. Validating it would report an error on the most ordinary thing a\n // design document does.\n if (!isDocumentTarget(bare)) return null;\n\n const found = lookup(bare, entry, index);\n\n if (found.ids.length === 0) {\n if (candidate.opportunistic && !worthReporting(bare, index)) return null;\n if (isFiltered(candidate.target, bare, options)) return null;\n // A trailing slash names a directory. Linking to one is ordinary - \"the\n // decisions live in [archive/](archive/)\" - and is not a citation of any\n // document. Resolution is still attempted first, so a directory-style\n // document written as `0007-sharding/` continues to resolve.\n if (bare.endsWith('/')) return null;\n const reason = pathMissingReason(bare, entry, options);\n return dangle(candidate, reason, found.near);\n }\n\n if (found.ids.length > 1) {\n if (candidate.opportunistic) return null;\n if (isFiltered(candidate.target, bare, options)) return null;\n return dangle(candidate, 'ambiguous', found.ids);\n }\n\n const documentId = found.ids[0] as string;\n\n // A document naming itself in prose - almost always its own H1, `# ADR-0007:\n // Sharding` - is not a citation. Deliberate self-links are kept, because a\n // link that points at its own document is a real mistake worth reporting.\n if (candidate.opportunistic && documentId === entry.document.id) return null;\n\n if (anchor !== null) return bindAnchor(candidate, documentId, anchor, index, nodes, options);\n\n return makeEdge(candidate, documentId);\n}\n\ninterface Lookup {\n readonly ids: readonly string[];\n /** Near-misses worth suggesting in the report. */\n readonly near: readonly string[];\n}\n\nfunction lookup(target: string, entry: ExtractedDocument, index: Index): Lookup {\n if (looksLikePath(target)) {\n const resolved = resolveFrom(entry.document.path, target).toLowerCase();\n const byPath = index.byPath.get(resolved);\n if (byPath) return { ids: [byPath], near: [] };\n // A path may still be spelled as an identifier in a nested folder layout.\n const stem = basenamePosix(resolved);\n const byStem = index.byAlias.get(normaliseRef(stem.replace(/\\.[^.]+$/, '')));\n if (byStem && byStem.size > 0) return { ids: [...byStem], near: [] };\n return { ids: [], near: [] };\n }\n\n const key = normaliseRef(target);\n if (key.length === 0) return { ids: [], near: [] };\n\n const byId = index.byId.get(key);\n if (byId) return { ids: [byId], near: [] };\n\n const byAlias = index.byAlias.get(key);\n if (byAlias && byAlias.size > 0) return { ids: [...byAlias], near: [] };\n\n const prefixed = parsePrefixedRef(target);\n if (prefixed) {\n const byFamily = index.byFamilyNumber.get(`${prefixed.family}:${prefixed.number}`);\n if (byFamily && byFamily.size > 0) return { ids: [...byFamily], near: [] };\n return { ids: [], near: [] };\n }\n\n // A bare number resolves only inside the citing document's own family. A\n // repository with both `adr/0007` and `rfc/0007` is ordinary, and guessing\n // between them would be worse than reporting nothing.\n const number = parseBareRef(target);\n if (number !== null) {\n const family = index.familyOf.get(entry.document.id) ?? null;\n if (family === null) return { ids: [], near: [] };\n const byFamily = index.byFamilyNumber.get(`${family}:${number}`);\n if (byFamily && byFamily.size > 0) return { ids: [...byFamily], near: [] };\n }\n\n return { ids: [], near: [] };\n}\n\n/** Whether a repository has declared this reference none of its business. */\nfunction isFiltered(target: string, bare: string, options: ResolveOptions): boolean {\n if (options.isIgnoredReference?.(target)) return true;\n const prefixed = parsePrefixedRef(bare);\n return prefixed !== null && options.isIgnoredFamily?.(prefixed.family) === true;\n}\n\n/**\n * Whether an unresolved bare identifier deserves a report.\n *\n * Only when the corpus already contains that family. `ADR-0099` in a repository\n * of ADRs is a real dangling citation; `T-1000` in the same repository is a\n * sentence about a robot.\n */\nfunction worthReporting(target: string, index: Index): boolean {\n const prefixed = parsePrefixedRef(target);\n return prefixed !== null && index.families.has(prefixed.family);\n}\n\nfunction pathMissingReason(\n target: string,\n entry: ExtractedDocument,\n options: ResolveOptions,\n): DanglingRef['reason'] {\n if (!looksLikePath(target) || !options.fileExists) return 'unknown-target';\n const resolved = resolveFrom(entry.document.path, target);\n return options.fileExists(resolved) ? 'not-a-spec' : 'unknown-target';\n}\n\n/**\n * Binds a `#anchor` to an item or a section.\n *\n * Anchors are how a delegation names a specific obligation rather than a whole\n * document, so resolving them precisely is what lets a ghost-handover finding\n * say *which* question was handed into the archive.\n */\nfunction bindAnchor(\n candidate: ReferenceCandidate,\n documentId: string,\n anchor: string,\n index: Index,\n nodes: ReadonlyMap<string, SpecNode>,\n options: ResolveOptions,\n): Edge | DanglingRef | null {\n const itemId = `${documentId}#${anchor}`;\n if (index.itemIds.has(itemId)) return makeEdge(candidate, itemId);\n\n const anchors = index.anchors.get(documentId);\n if (anchors?.has(anchor.toLowerCase())) return makeEdge(candidate, documentId);\n\n // Some renderers slugify differently; try the loosest reasonable match before\n // calling it broken.\n const loose = anchor.toLowerCase().replace(/[^\\p{L}\\p{N}]+/gu, '-').replace(/^-|-$/g, '');\n if (anchors?.has(loose)) return makeEdge(candidate, documentId);\n\n if (isFiltered(candidate.target, splitAnchor(candidate.target).target, options)) return null;\n\n const candidates = [...(nodes.keys() as Iterable<string>)].filter(\n (id) => id.startsWith(`${documentId}#`) && id.toLowerCase().includes(loose),\n );\n return {\n kind: candidate.kind,\n from: candidate.from,\n target: candidate.target,\n reason: 'unknown-anchor',\n origin: candidate.origin,\n declaredAt: candidate.declaredAt,\n raw: candidate.raw,\n candidates,\n };\n}\n\nfunction makeEdge(candidate: ReferenceCandidate, resolved: string): Edge {\n const from = candidate.inverted ? resolved : candidate.from;\n const to = candidate.inverted ? candidate.from : resolved;\n return {\n kind: candidate.kind,\n from,\n to,\n origin: candidate.origin,\n declaredAt: candidate.declaredAt,\n raw: candidate.raw,\n declaredIn: [candidate.declaredAt.file],\n reflexive: documentOf(from) === documentOf(to),\n };\n}\n\nfunction dangle(\n candidate: ReferenceCandidate,\n reason: DanglingRef['reason'],\n candidates: readonly string[],\n): DanglingRef {\n return {\n kind: candidate.kind,\n from: candidate.from,\n target: candidate.target,\n reason,\n origin: candidate.origin,\n declaredAt: candidate.declaredAt,\n raw: candidate.raw,\n candidates,\n };\n}\n\n/** The document part of a node id: `ADR-7#q.1` -> `ADR-7`. */\nexport function documentOf(nodeId: string): string {\n const hash = nodeId.indexOf('#');\n return hash === -1 ? nodeId : nodeId.slice(0, hash);\n}\n"]}
1
+ {"version":3,"file":"resolve.js","sourceRoot":"","sources":["../src/resolve.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Corpus-level reference resolution - the foreign-key check.\n *\n * Extraction produces relations whose targets are still just text. This module\n * turns each into an edge or into an explicit, reportable failure. The whole\n * value of the exercise is in refusing to do either job carelessly:\n *\n * - **A deliberate reference that does not resolve is an error.** A link, a\n * front-matter field or a directive naming a document that does not exist is\n * a broken foreign key, and silence about it is how reference graphs rot.\n * - **An opportunistic reference that does not resolve is nothing.** `ADR-0007`\n * written in prose is a citation; `SHA-256` is not. Since the two are\n * indistinguishable in isolation, bare identifiers are only reported when\n * their family already exists in the corpus - so `ADR-0099` in a repository\n * full of ADRs is a finding, and `T-1000` in the same repository is not.\n * - **Two candidates is worse than none.** A reference that matches several\n * documents is reported as ambiguous rather than silently bound to whichever\n * one happened to be indexed first.\n */\n\nimport type { ExtractedDocument, ReferenceCandidate } from './extract.js';\nimport {\n isDocumentTarget,\n isExternal,\n looksLikePath,\n normaliseRef,\n parseBareRef,\n parsePrefixedRef,\n splitAnchor,\n} from './identity.js';\nimport { basenamePosix, extnamePosix, resolveFrom } from './paths.js';\nimport type { DanglingRef, DocumentNode, Edge, ItemNode, ParseProblem, SpecNode } from './types.js';\n\nexport interface ResolveOptions {\n /**\n * Whether a repository-relative path exists on disk.\n *\n * Used only to tell \"you linked to a file that is not a specification\" apart\n * from \"you linked to nothing at all\", which are different mistakes with\n * different fixes.\n */\n readonly fileExists?: ((path: string) => boolean) | undefined;\n /**\n * Targets whose failure to resolve should not be reported.\n *\n * This is a *suppression* filter, not a resolution one: it is consulted only\n * when a reference has already failed to resolve. A reference that resolves\n * still becomes an edge no matter what this says, so no amount of\n * configuration can silently delete a relation from the graph.\n */\n readonly isIgnoredReference?: ((target: string) => boolean) | undefined;\n /**\n * Families that are never citations in this repository.\n *\n * `RFC 2119` is the canonical case: every specification cites it, and a\n * repository that keeps its own `RFC-*` documents will otherwise read that\n * sentence as a dangling reference to a local RFC 2119 it does not have.\n * Consulted only after resolution has failed, like every other filter here.\n */\n readonly isIgnoredFamily?: ((family: string) => boolean) | undefined;\n}\n\nexport interface ResolvedCorpus {\n readonly nodes: ReadonlyMap<string, SpecNode>;\n readonly documents: readonly DocumentNode[];\n readonly items: readonly ItemNode[];\n readonly edges: readonly Edge[];\n readonly dangling: readonly DanglingRef[];\n readonly problems: readonly ParseProblem[];\n}\n\ninterface Index {\n readonly byId: Map<string, string>;\n readonly byAlias: Map<string, Set<string>>;\n readonly byPath: Map<string, string>;\n readonly byFamilyNumber: Map<string, Set<string>>;\n readonly families: Set<string>;\n readonly anchors: Map<string, ReadonlySet<string>>;\n readonly itemIds: Set<string>;\n readonly familyOf: Map<string, string | null>;\n}\n\n/** Resolves every extracted reference against the whole corpus. */\nexport function resolveCorpus(\n extracted: readonly ExtractedDocument[],\n options: ResolveOptions = {},\n): ResolvedCorpus {\n const index = buildIndex(extracted);\n const nodes = new Map<string, SpecNode>();\n const documents: DocumentNode[] = [];\n const items: ItemNode[] = [];\n const problems: ParseProblem[] = [];\n\n for (const entry of extracted) {\n const existing = nodes.get(entry.document.id);\n if (existing && existing.kind === 'document') {\n problems.push({\n message: `duplicate document id \"${entry.document.id}\", already declared by ${existing.path}`,\n at: entry.document.at,\n });\n continue;\n }\n nodes.set(entry.document.id, entry.document);\n documents.push(entry.document);\n for (const item of entry.items) {\n nodes.set(item.id, item);\n items.push(item);\n }\n problems.push(...entry.problems);\n }\n\n const edges: Edge[] = [];\n const dangling: DanglingRef[] = [];\n const byKey = new Map<string, number>();\n\n // Structural edges: a register contains the specifications written inside it.\n for (const entry of extracted) {\n if (entry.containerId === null) continue;\n if (!nodes.has(entry.containerId) || !nodes.has(entry.document.id)) continue;\n edges.push({\n kind: 'contains',\n from: entry.containerId,\n to: entry.document.id,\n origin: 'structural',\n declaredAt: entry.document.at,\n raw: entry.document.title,\n declaredIn: [entry.document.at.file],\n reflexive: false,\n });\n }\n\n // Structural edges: a document contains its items.\n for (const item of items) {\n edges.push({\n kind: 'contains',\n from: item.document,\n to: item.id,\n origin: 'structural',\n declaredAt: item.at,\n raw: item.text,\n declaredIn: [item.at.file],\n reflexive: false,\n });\n }\n\n for (const entry of extracted) {\n for (const candidate of entry.references) {\n if (!nodes.has(candidate.from)) continue;\n const outcome = resolveOne(candidate, entry, index, nodes, options);\n if (outcome === null) continue;\n if ('reason' in outcome) {\n dangling.push(outcome);\n continue;\n }\n // Collapse duplicates: the same relation stated twice is one edge - but\n // every declaration site is kept, because a supersession recorded in only\n // one of the two documents is itself a finding.\n const key = `${outcome.kind} ${outcome.from} ${outcome.to}`;\n const existing = byKey.get(key);\n if (existing !== undefined) {\n const previous = edges[existing] as Edge;\n if (!previous.declaredIn.includes(outcome.declaredAt.file)) {\n edges[existing] = { ...previous, declaredIn: [...previous.declaredIn, outcome.declaredAt.file] };\n }\n continue;\n }\n byKey.set(key, edges.length);\n edges.push(outcome);\n }\n }\n\n return { nodes, documents, items, edges, dangling, problems };\n}\n\n/* -------------------------------------------------------------------------- */\n/* Indexing */\n/* -------------------------------------------------------------------------- */\n\nfunction buildIndex(extracted: readonly ExtractedDocument[]): Index {\n const index: Index = {\n byId: new Map(),\n byAlias: new Map(),\n byPath: new Map(),\n byFamilyNumber: new Map(),\n families: new Set(),\n anchors: new Map(),\n itemIds: new Set(),\n familyOf: new Map(),\n };\n\n for (const entry of extracted) {\n const id = entry.document.id;\n index.byId.set(normaliseRef(id), id);\n index.anchors.set(id, entry.anchors);\n index.familyOf.set(id, entry.identity.family);\n\n for (const alias of entry.document.aliases) {\n const set = index.byAlias.get(alias) ?? new Set<string>();\n set.add(id);\n index.byAlias.set(alias, set);\n }\n\n // Only a file answers to its path. A region keeps the path on its node, so a\n // finding can say where it lives and `document[path=...]` can select it, but\n // it must not be reachable *by* that path: two nodes answering to one path\n // makes every link to the file ambiguous, and this index resolves a\n // collision by keeping whichever was written last. A link to a file holding\n // a register bound to its final row, quietly and with no diagnostic, and\n // anchors were then checked against that row's span rather than the file's.\n // ADR-0009 said a region does not claim the file's path; this is the index\n // where that had to be true.\n if (entry.containerId === null) {\n for (const path of pathKeys(entry.document.path)) index.byPath.set(path, id);\n }\n\n if (entry.identity.family !== null && entry.identity.number !== null) {\n index.families.add(entry.identity.family);\n const key = `${entry.identity.family}:${entry.identity.number}`;\n const set = index.byFamilyNumber.get(key) ?? new Set<string>();\n set.add(id);\n index.byFamilyNumber.set(key, set);\n }\n\n for (const item of entry.items) index.itemIds.add(item.id);\n }\n\n return index;\n}\n\n/** Every spelling of a path that a link might use. */\nfunction pathKeys(path: string): string[] {\n const keys = new Set<string>([path.toLowerCase()]);\n const extension = extnamePosix(path);\n if (extension.length > 0) keys.add(path.slice(0, path.length - extension.length).toLowerCase());\n // `docs/adr/0007/README.md` is also addressed as `docs/adr/0007`.\n const base = basenamePosix(path);\n if (/^(readme|index)\\./i.test(base)) {\n const parent = path.slice(0, path.length - base.length - 1);\n if (parent.length > 0) keys.add(parent.toLowerCase());\n }\n return [...keys];\n}\n\n/* -------------------------------------------------------------------------- */\n/* Resolution */\n/* -------------------------------------------------------------------------- */\n\nfunction resolveOne(\n candidate: ReferenceCandidate,\n entry: ExtractedDocument,\n index: Index,\n nodes: ReadonlyMap<string, SpecNode>,\n options: ResolveOptions,\n): Edge | DanglingRef | null {\n const { target: bare, anchor } = splitAnchor(candidate.target);\n\n // A pure `#anchor` points inside the citing document.\n if (bare.length === 0 && anchor !== null) {\n return bindAnchor(candidate, entry.document.id, anchor, index, nodes, options);\n }\n\n if (isExternal(bare)) return null;\n // A link to source code, an image or a config file is not a specification\n // reference. Validating it would report an error on the most ordinary thing a\n // design document does.\n if (!isDocumentTarget(bare)) return null;\n\n const found = lookup(bare, entry, index);\n\n if (found.ids.length === 0) {\n if (candidate.opportunistic && !worthReporting(bare, index)) return null;\n if (isFiltered(candidate.target, bare, options)) return null;\n // A trailing slash names a directory. Linking to one is ordinary - \"the\n // decisions live in [archive/](archive/)\" - and is not a citation of any\n // document. Resolution is still attempted first, so a directory-style\n // document written as `0007-sharding/` continues to resolve.\n if (bare.endsWith('/')) return null;\n const reason = pathMissingReason(bare, entry, options);\n return dangle(candidate, reason, found.near);\n }\n\n if (found.ids.length > 1) {\n if (candidate.opportunistic) return null;\n if (isFiltered(candidate.target, bare, options)) return null;\n return dangle(candidate, 'ambiguous', found.ids);\n }\n\n const documentId = found.ids[0] as string;\n\n // A document naming itself in prose - almost always its own H1, `# ADR-0007:\n // Sharding` - is not a citation. Deliberate self-links are kept, because a\n // link that points at its own document is a real mistake worth reporting.\n if (candidate.opportunistic && documentId === entry.document.id) return null;\n\n if (anchor !== null) return bindAnchor(candidate, documentId, anchor, index, nodes, options);\n\n return makeEdge(candidate, documentId);\n}\n\ninterface Lookup {\n readonly ids: readonly string[];\n /** Near-misses worth suggesting in the report. */\n readonly near: readonly string[];\n}\n\nfunction lookup(target: string, entry: ExtractedDocument, index: Index): Lookup {\n if (looksLikePath(target)) {\n const resolved = resolveFrom(entry.document.path, target).toLowerCase();\n const byPath = index.byPath.get(resolved);\n if (byPath) return { ids: [byPath], near: [] };\n // A path may still be spelled as an identifier in a nested folder layout.\n const stem = basenamePosix(resolved);\n const byStem = index.byAlias.get(normaliseRef(stem.replace(/\\.[^.]+$/, '')));\n if (byStem && byStem.size > 0) return { ids: [...byStem], near: [] };\n return { ids: [], near: [] };\n }\n\n const key = normaliseRef(target);\n if (key.length === 0) return { ids: [], near: [] };\n\n const byId = index.byId.get(key);\n if (byId) return { ids: [byId], near: [] };\n\n const byAlias = index.byAlias.get(key);\n if (byAlias && byAlias.size > 0) return { ids: [...byAlias], near: [] };\n\n const prefixed = parsePrefixedRef(target);\n if (prefixed) {\n const byFamily = index.byFamilyNumber.get(`${prefixed.family}:${prefixed.number}`);\n if (byFamily && byFamily.size > 0) return { ids: [...byFamily], near: [] };\n return { ids: [], near: [] };\n }\n\n // A bare number resolves only inside the citing document's own family. A\n // repository with both `adr/0007` and `rfc/0007` is ordinary, and guessing\n // between them would be worse than reporting nothing.\n const number = parseBareRef(target);\n if (number !== null) {\n const family = index.familyOf.get(entry.document.id) ?? null;\n if (family === null) return { ids: [], near: [] };\n const byFamily = index.byFamilyNumber.get(`${family}:${number}`);\n if (byFamily && byFamily.size > 0) return { ids: [...byFamily], near: [] };\n }\n\n return { ids: [], near: [] };\n}\n\n/** Whether a repository has declared this reference none of its business. */\nfunction isFiltered(target: string, bare: string, options: ResolveOptions): boolean {\n if (options.isIgnoredReference?.(target)) return true;\n const prefixed = parsePrefixedRef(bare);\n return prefixed !== null && options.isIgnoredFamily?.(prefixed.family) === true;\n}\n\n/**\n * Whether an unresolved bare identifier deserves a report.\n *\n * Only when the corpus already contains that family. `ADR-0099` in a repository\n * of ADRs is a real dangling citation; `T-1000` in the same repository is a\n * sentence about a robot.\n */\nfunction worthReporting(target: string, index: Index): boolean {\n const prefixed = parsePrefixedRef(target);\n return prefixed !== null && index.families.has(prefixed.family);\n}\n\nfunction pathMissingReason(\n target: string,\n entry: ExtractedDocument,\n options: ResolveOptions,\n): DanglingRef['reason'] {\n if (!looksLikePath(target) || !options.fileExists) return 'unknown-target';\n const resolved = resolveFrom(entry.document.path, target);\n return options.fileExists(resolved) ? 'not-a-spec' : 'unknown-target';\n}\n\n/**\n * Binds a `#anchor` to an item or a section.\n *\n * Anchors are how a delegation names a specific obligation rather than a whole\n * document, so resolving them precisely is what lets a ghost-handover finding\n * say *which* question was handed into the archive.\n */\nfunction bindAnchor(\n candidate: ReferenceCandidate,\n documentId: string,\n anchor: string,\n index: Index,\n nodes: ReadonlyMap<string, SpecNode>,\n options: ResolveOptions,\n): Edge | DanglingRef | null {\n const itemId = `${documentId}#${anchor}`;\n if (index.itemIds.has(itemId)) return makeEdge(candidate, itemId);\n\n const anchors = index.anchors.get(documentId);\n if (anchors?.has(anchor.toLowerCase())) return makeEdge(candidate, documentId);\n\n // Some renderers slugify differently; try the loosest reasonable match before\n // calling it broken.\n const loose = anchor.toLowerCase().replace(/[^\\p{L}\\p{N}]+/gu, '-').replace(/^-|-$/g, '');\n if (anchors?.has(loose)) return makeEdge(candidate, documentId);\n\n if (isFiltered(candidate.target, splitAnchor(candidate.target).target, options)) return null;\n\n const candidates = [...(nodes.keys() as Iterable<string>)].filter(\n (id) => id.startsWith(`${documentId}#`) && id.toLowerCase().includes(loose),\n );\n return {\n kind: candidate.kind,\n from: candidate.from,\n target: candidate.target,\n reason: 'unknown-anchor',\n origin: candidate.origin,\n declaredAt: candidate.declaredAt,\n raw: candidate.raw,\n candidates,\n };\n}\n\nfunction makeEdge(candidate: ReferenceCandidate, resolved: string): Edge {\n const from = candidate.inverted ? resolved : candidate.from;\n const to = candidate.inverted ? candidate.from : resolved;\n return {\n kind: candidate.kind,\n from,\n to,\n origin: candidate.origin,\n declaredAt: candidate.declaredAt,\n raw: candidate.raw,\n declaredIn: [candidate.declaredAt.file],\n reflexive: documentOf(from) === documentOf(to),\n };\n}\n\nfunction dangle(\n candidate: ReferenceCandidate,\n reason: DanglingRef['reason'],\n candidates: readonly string[],\n): DanglingRef {\n return {\n kind: candidate.kind,\n from: candidate.from,\n target: candidate.target,\n reason,\n origin: candidate.origin,\n declaredAt: candidate.declaredAt,\n raw: candidate.raw,\n candidates,\n };\n}\n\n/** The document part of a node id: `ADR-7#q.1` -> `ADR-7`. */\nexport function documentOf(nodeId: string): string {\n const hash = nodeId.indexOf('#');\n return hash === -1 ? nodeId : nodeId.slice(0, hash);\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@descent-vtt/spec-graph",
3
- "version": "0.2.0",
3
+ "version": "0.2.2",
4
4
  "description": "Turn Markdown specs into a verifiable relational graph. Catches ghost handovers, stale premises and broken references in CI.",
5
5
  "keywords": [
6
6
  "adr",
@@ -33,6 +33,7 @@
33
33
  "./package.json": "./package.json"
34
34
  },
35
35
  "files": [
36
+ "CHANGELOG.md",
36
37
  "LICENSE",
37
38
  "README.md",
38
39
  "bin",