@nielspeter/eess-md 0.3.0 → 0.6.0
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/README.md +57 -8
- package/dist/builders/links.d.ts.map +1 -1
- package/dist/builders/links.js +2 -3
- package/dist/builders/links.js.map +1 -1
- package/dist/builders/pointers.d.ts.map +1 -1
- package/dist/builders/pointers.js +2 -3
- package/dist/builders/pointers.js.map +1 -1
- package/dist/builders/task-items.d.ts.map +1 -1
- package/dist/builders/task-items.js +2 -3
- package/dist/builders/task-items.js.map +1 -1
- package/dist/conditions/pointer-resolve.d.ts +8 -3
- package/dist/conditions/pointer-resolve.d.ts.map +1 -1
- package/dist/conditions/pointer-resolve.js +80 -35
- package/dist/conditions/pointer-resolve.js.map +1 -1
- package/dist/corpus.d.ts +10 -3
- package/dist/corpus.d.ts.map +1 -1
- package/dist/corpus.js +5 -27
- package/dist/corpus.js.map +1 -1
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +23 -0
- package/dist/index.js.map +1 -1
- package/dist/model/by-document.d.ts +21 -0
- package/dist/model/by-document.d.ts.map +1 -0
- package/dist/model/by-document.js +19 -0
- package/dist/model/by-document.js.map +1 -0
- package/dist/model/document.d.ts +1 -1
- package/dist/model/document.d.ts.map +1 -1
- package/dist/model/links.d.ts.map +1 -1
- package/dist/model/links.js +1 -7
- package/dist/model/links.js.map +1 -1
- package/dist/model/task-items.d.ts.map +1 -1
- package/dist/model/task-items.js +1 -7
- package/dist/model/task-items.js.map +1 -1
- package/dist/model/text-of.d.ts +14 -0
- package/dist/model/text-of.d.ts.map +1 -0
- package/dist/model/text-of.js +19 -0
- package/dist/model/text-of.js.map +1 -0
- package/dist/rules/adr.d.ts +8 -0
- package/dist/rules/adr.d.ts.map +1 -1
- package/dist/rules/adr.js +18 -6
- package/dist/rules/adr.js.map +1 -1
- package/dist/rules/ledger.d.ts +120 -0
- package/dist/rules/ledger.d.ts.map +1 -1
- package/dist/rules/ledger.js +255 -41
- package/dist/rules/ledger.js.map +1 -1
- package/package.json +3 -2
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { Corpus } from '../corpus.js';
|
|
2
|
+
import type { MdDocument } from './document.js';
|
|
3
|
+
/**
|
|
4
|
+
* Every reference in the corpus, each stamped with the document it came from.
|
|
5
|
+
*
|
|
6
|
+
* `links`, `pointers` and `task-items` each walked the corpus and re-attached
|
|
7
|
+
* `doc` to what their collector returned — `no-copy-paste` reported the first
|
|
8
|
+
* two at 100%. The collector is the parameter, which is all that ever differed;
|
|
9
|
+
* even its argument order did (`collectLinks(root, text)` against
|
|
10
|
+
* `extractPointers(text, root)`), which is why this takes a callback rather
|
|
11
|
+
* than a `(root, text)` pair.
|
|
12
|
+
*
|
|
13
|
+
* The stamp is not decoration. An md element's violation is reported at
|
|
14
|
+
* `doc.relPath`, so a reference that loses its document is a finding with no
|
|
15
|
+
* file — unactionable, and ADR-009 rule 2's whole subject. One place to attach
|
|
16
|
+
* it is one place for that to be true.
|
|
17
|
+
*/
|
|
18
|
+
export declare function stampedByDocument<Ref extends object>(corpus: Corpus, collect: (doc: MdDocument) => readonly Ref[]): (Ref & {
|
|
19
|
+
doc: MdDocument;
|
|
20
|
+
})[];
|
|
21
|
+
//# sourceMappingURL=by-document.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"by-document.d.ts","sourceRoot":"","sources":["../../src/model/by-document.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAA;AAC1C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAA;AAE/C;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,SAAS,MAAM,EAClD,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,CAAC,GAAG,EAAE,UAAU,KAAK,SAAS,GAAG,EAAE,GAC3C,CAAC,GAAG,GAAG;IAAE,GAAG,EAAE,UAAU,CAAA;CAAE,CAAC,EAAE,CAE/B"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Every reference in the corpus, each stamped with the document it came from.
|
|
3
|
+
*
|
|
4
|
+
* `links`, `pointers` and `task-items` each walked the corpus and re-attached
|
|
5
|
+
* `doc` to what their collector returned — `no-copy-paste` reported the first
|
|
6
|
+
* two at 100%. The collector is the parameter, which is all that ever differed;
|
|
7
|
+
* even its argument order did (`collectLinks(root, text)` against
|
|
8
|
+
* `extractPointers(text, root)`), which is why this takes a callback rather
|
|
9
|
+
* than a `(root, text)` pair.
|
|
10
|
+
*
|
|
11
|
+
* The stamp is not decoration. An md element's violation is reported at
|
|
12
|
+
* `doc.relPath`, so a reference that loses its document is a finding with no
|
|
13
|
+
* file — unactionable, and ADR-009 rule 2's whole subject. One place to attach
|
|
14
|
+
* it is one place for that to be true.
|
|
15
|
+
*/
|
|
16
|
+
export function stampedByDocument(corpus, collect) {
|
|
17
|
+
return corpus.documents().flatMap((doc) => collect(doc).map((ref) => ({ ...ref, doc })));
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=by-document.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"by-document.js","sourceRoot":"","sources":["../../src/model/by-document.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,iBAAiB,CAC/B,MAAc,EACd,OAA4C;IAE5C,OAAO,MAAM,CAAC,SAAS,EAAE,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,CAAA;AAC1F,CAAC"}
|
package/dist/model/document.d.ts
CHANGED
|
@@ -50,7 +50,7 @@ export interface MdDocument {
|
|
|
50
50
|
readonly file: string;
|
|
51
51
|
/** Repo-relative path (POSIX separators), e.g. `docs/adr/0001-x.md` */
|
|
52
52
|
readonly relPath: string;
|
|
53
|
-
/** In a frozen folder — historical record;
|
|
53
|
+
/** In a frozen folder — historical record; links still checked, pointers not examined (bug 0253) */
|
|
54
54
|
readonly frozen: boolean;
|
|
55
55
|
/** Raw source text */
|
|
56
56
|
readonly text: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"document.d.ts","sourceRoot":"","sources":["../../src/model/document.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAe,MAAM,OAAO,CAAA;AAE9C;;GAEG;AACH,MAAM,WAAW,SAAS;IACxB,uCAAuC;IACvC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,2CAA2C;IAC3C,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,4CAA4C;IAC5C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CACtB;AAED;;GAEG;AACH,MAAM,WAAW,OAAO;IACtB,iCAAiC;IACjC,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAA;IAClC,qDAAqD;IACrD,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC,SAAS,MAAM,EAAE,CAAC,EAAE,CAAA;IAC7C;;;;OAIG;IACH,QAAQ,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAA;IACpC,0CAA0C;IAC1C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,iFAAiF;IACjF,QAAQ,CAAC,WAAW,EAAE,SAAS,MAAM,EAAE,CAAA;CACxC;AAED,kDAAkD;AAClD,MAAM,WAAW,WAAW;IAC1B,yEAAyE;IACzE,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;IAC5B,4BAA4B;IAC5B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,2CAA2C;IAC3C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CACtB;AAED;;;;;;GAMG;AACH,MAAM,WAAW,UAAU;IACzB,yBAAyB;IACzB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,uEAAuE;IACvE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,
|
|
1
|
+
{"version":3,"file":"document.d.ts","sourceRoot":"","sources":["../../src/model/document.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAe,MAAM,OAAO,CAAA;AAE9C;;GAEG;AACH,MAAM,WAAW,SAAS;IACxB,uCAAuC;IACvC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,2CAA2C;IAC3C,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,4CAA4C;IAC5C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CACtB;AAED;;GAEG;AACH,MAAM,WAAW,OAAO;IACtB,iCAAiC;IACjC,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAA;IAClC,qDAAqD;IACrD,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC,SAAS,MAAM,EAAE,CAAC,EAAE,CAAA;IAC7C;;;;OAIG;IACH,QAAQ,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAA;IACpC,0CAA0C;IAC1C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,iFAAiF;IACjF,QAAQ,CAAC,WAAW,EAAE,SAAS,MAAM,EAAE,CAAA;CACxC;AAED,kDAAkD;AAClD,MAAM,WAAW,WAAW;IAC1B,yEAAyE;IACzE,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;IAC5B,4BAA4B;IAC5B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,2CAA2C;IAC3C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CACtB;AAED;;;;;;GAMG;AACH,MAAM,WAAW,UAAU;IACzB,yBAAyB;IACzB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,uEAAuE;IACvE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,oGAAoG;IACpG,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAA;IACxB,sBAAsB;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,QAAQ,EAAE,SAAS,SAAS,EAAE,CAAA;IACvC,QAAQ,CAAC,MAAM,EAAE,SAAS,OAAO,EAAE,CAAA;IACnC,6DAA6D;IAC7D,QAAQ,CAAC,UAAU,EAAE,SAAS,WAAW,EAAE,CAAA;IAC3C,uCAAuC;IACvC,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAA;CACpB;AAsBD;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE;IAClC,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,CAAA;IACf,MAAM,EAAE,OAAO,CAAA;IACf,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,IAAI,CAAA;CACX,GAAG,UAAU,CAwCb"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"links.d.ts","sourceRoot":"","sources":["../../src/model/links.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAS,MAAM,OAAO,CAAA;
|
|
1
|
+
{"version":3,"file":"links.d.ts","sourceRoot":"","sources":["../../src/model/links.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAS,MAAM,OAAO,CAAA;AAExC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAA;AAE/C,gFAAgF;AAChF,MAAM,WAAW,SAAS;IACxB,8EAA8E;IAC9E,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB,iBAAiB;IACjB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,2CAA2C;IAC3C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,8EAA8E;IAC9E,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAA;IAC1B;;;;;OAKG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CACzB;AAKD;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,EAAE,CAoCrE;AAED,qGAAqG;AACrG,MAAM,WAAW,MAAO,SAAQ,SAAS;IACvC,QAAQ,CAAC,GAAG,EAAE,UAAU,CAAA;CACzB"}
|
package/dist/model/links.js
CHANGED
|
@@ -1,12 +1,6 @@
|
|
|
1
|
+
import { textOf } from './text-of.js';
|
|
1
2
|
// A URL is external if it has a scheme (`https:`, `mailto:`) or is protocol-relative.
|
|
2
3
|
const EXTERNAL_RE = /^([a-z][a-z0-9+.-]*:|\/\/)/i;
|
|
3
|
-
function textOf(node) {
|
|
4
|
-
if ('value' in node && typeof node.value === 'string')
|
|
5
|
-
return node.value;
|
|
6
|
-
if ('children' in node)
|
|
7
|
-
return node.children.map((c) => textOf(c)).join('');
|
|
8
|
-
return '';
|
|
9
|
-
}
|
|
10
4
|
/**
|
|
11
5
|
* Collect inline markdown links (`[text](url)`) from a document tree. Links
|
|
12
6
|
* inside fenced code are not parsed as `link` nodes by mdast, so they are
|
package/dist/model/links.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"links.js","sourceRoot":"","sources":["../../src/model/links.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"links.js","sourceRoot":"","sources":["../../src/model/links.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAA;AAuBrC,sFAAsF;AACtF,MAAM,WAAW,GAAG,6BAA6B,CAAA;AAEjD;;;;GAIG;AACH,MAAM,UAAU,YAAY,CAAC,IAAU,EAAE,MAAe;IACtD,MAAM,GAAG,GAAgB,EAAE,CAAA;IAC3B,MAAM,KAAK,GAAG,CAAC,IAAW,EAAQ,EAAE;QAClC,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;YACzB,yEAAyE;YACzE,wEAAwE;YACxE,2EAA2E;YAC3E,2EAA2E;YAC3E,2CAA2C;YAC3C,IAAI,QAA4B,CAAA;YAChC,IAAI,MAA0B,CAAA;YAC9B,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,EAAE,KAAK,CAAC,MAAM,CAAA;YAC5C,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,EAAE,GAAG,CAAC,MAAM,CAAA;YACxC,IAAI,MAAM,KAAK,SAAS,IAAI,QAAQ,KAAK,SAAS,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;gBAC3E,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAA;gBAC1C,MAAM,GAAG,GAAG,GAAG,CAAC,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;gBACrC,IAAI,GAAG,IAAI,CAAC,EAAE,CAAC;oBACb,QAAQ,GAAG,QAAQ,GAAG,GAAG,CAAA;oBACzB,MAAM,GAAG,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,CAAA;gBACrC,CAAC;YACH,CAAC;YACD,GAAG,CAAC,IAAI,CAAC;gBACP,GAAG,EAAE,IAAI,CAAC,GAAG;gBACb,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC;gBAClB,IAAI,EAAE,IAAI,CAAC,QAAQ,EAAE,KAAK,CAAC,IAAI,IAAI,CAAC;gBACpC,QAAQ,EAAE,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC;gBACpC,QAAQ;gBACR,MAAM;aACP,CAAC,CAAA;QACJ,CAAC;QACD,IAAI,UAAU,IAAI,IAAI,EAAE,CAAC;YACvB,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,QAAQ;gBAAE,KAAK,CAAC,KAAK,CAAC,CAAA;QACjD,CAAC;IACH,CAAC,CAAA;IACD,KAAK,CAAC,IAAI,CAAC,CAAA;IACX,OAAO,GAAG,CAAA;AACZ,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"task-items.d.ts","sourceRoot":"","sources":["../../src/model/task-items.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAS,MAAM,OAAO,CAAA;
|
|
1
|
+
{"version":3,"file":"task-items.d.ts","sourceRoot":"","sources":["../../src/model/task-items.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAS,MAAM,OAAO,CAAA;AAGxC,kEAAkE;AAClE,MAAM,WAAW,aAAa;IAC5B,yEAAyE;IACzE,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAA;IACzB,qFAAqF;IACrF,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,0DAA0D;IAC1D,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CACtB;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,IAAI,GAAG,aAAa,EAAE,CAoB5D"}
|
package/dist/model/task-items.js
CHANGED
|
@@ -1,10 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
if ('value' in node && typeof node.value === 'string')
|
|
3
|
-
return node.value;
|
|
4
|
-
if ('children' in node)
|
|
5
|
-
return node.children.map((c) => textOf(c)).join('');
|
|
6
|
-
return '';
|
|
7
|
-
}
|
|
1
|
+
import { textOf } from './text-of.js';
|
|
8
2
|
/**
|
|
9
3
|
* Collect GFM task-list items from a document tree.
|
|
10
4
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"task-items.js","sourceRoot":"","sources":["../../src/model/task-items.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"task-items.js","sourceRoot":"","sources":["../../src/model/task-items.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAA;AAYrC;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,gBAAgB,CAAC,IAAU;IACzC,MAAM,GAAG,GAAoB,EAAE,CAAA;IAC/B,MAAM,KAAK,GAAG,CAAC,IAAW,EAAE,YAAqB,EAAQ,EAAE;QACzD,IAAI,IAAI,CAAC,IAAI,KAAK,YAAY,EAAE,CAAC;YAC/B,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,QAAQ;gBAAE,KAAK,CAAC,KAAK,EAAE,IAAI,CAAC,CAAA;YACrD,OAAM;QACR,CAAC;QACD,IAAI,IAAI,CAAC,IAAI,KAAK,UAAU,IAAI,OAAO,IAAI,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;YAClE,IAAI,CAAC,YAAY,EAAE,CAAC;gBAClB,MAAM,cAAc,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,WAAW,CAAC,CAAA;gBACxE,MAAM,IAAI,GAAG,CAAC,cAAc,CAAC,CAAC,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,CAAA;gBAC5E,GAAG,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,QAAQ,EAAE,KAAK,CAAC,IAAI,IAAI,CAAC,EAAE,CAAC,CAAA;YACjF,CAAC;QACH,CAAC;QACD,IAAI,UAAU,IAAI,IAAI,EAAE,CAAC;YACvB,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,QAAQ;gBAAE,KAAK,CAAC,KAAK,EAAE,YAAY,CAAC,CAAA;QAC/D,CAAC;IACH,CAAC,CAAA;IACD,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,CAAA;IAClB,OAAO,GAAG,CAAA;AACZ,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { Nodes } from 'mdast';
|
|
2
|
+
/**
|
|
3
|
+
* The visible text of an mdast node, with formatting flattened.
|
|
4
|
+
*
|
|
5
|
+
* `[**bold** link](url)` is three nodes; a rule that reads a link's text wants
|
|
6
|
+
* `bold link`. Recursing over `children` and concatenating leaf `value`s is what
|
|
7
|
+
* produces that, and returning `''` for a node with neither — an image, a
|
|
8
|
+
* thematic break — is deliberate: it contributes nothing to the reader's text.
|
|
9
|
+
*
|
|
10
|
+
* Extracted because `links.ts` and `task-items.ts` each carried a byte-identical
|
|
11
|
+
* copy, which `no-copy-paste` reported at 100%.
|
|
12
|
+
*/
|
|
13
|
+
export declare function textOf(node: Nodes): string;
|
|
14
|
+
//# sourceMappingURL=text-of.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"text-of.d.ts","sourceRoot":"","sources":["../../src/model/text-of.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,OAAO,CAAA;AAElC;;;;;;;;;;GAUG;AACH,wBAAgB,MAAM,CAAC,IAAI,EAAE,KAAK,GAAG,MAAM,CAI1C"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The visible text of an mdast node, with formatting flattened.
|
|
3
|
+
*
|
|
4
|
+
* `[**bold** link](url)` is three nodes; a rule that reads a link's text wants
|
|
5
|
+
* `bold link`. Recursing over `children` and concatenating leaf `value`s is what
|
|
6
|
+
* produces that, and returning `''` for a node with neither — an image, a
|
|
7
|
+
* thematic break — is deliberate: it contributes nothing to the reader's text.
|
|
8
|
+
*
|
|
9
|
+
* Extracted because `links.ts` and `task-items.ts` each carried a byte-identical
|
|
10
|
+
* copy, which `no-copy-paste` reported at 100%.
|
|
11
|
+
*/
|
|
12
|
+
export function textOf(node) {
|
|
13
|
+
if ('value' in node && typeof node.value === 'string')
|
|
14
|
+
return node.value;
|
|
15
|
+
if ('children' in node)
|
|
16
|
+
return node.children.map((c) => textOf(c)).join('');
|
|
17
|
+
return '';
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=text-of.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"text-of.js","sourceRoot":"","sources":["../../src/model/text-of.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;GAUG;AACH,MAAM,UAAU,MAAM,CAAC,IAAW;IAChC,IAAI,OAAO,IAAI,IAAI,IAAI,OAAO,IAAI,CAAC,KAAK,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC,KAAK,CAAA;IACxE,IAAI,UAAU,IAAI,IAAI;QAAE,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;IAC3E,OAAO,EAAE,CAAA;AACX,CAAC"}
|
package/dist/rules/adr.d.ts
CHANGED
|
@@ -29,6 +29,14 @@ export interface AdrEnforcementOptions extends PresetBaseOptions {
|
|
|
29
29
|
* resolve; a soft-tier clause declared as such passes.
|
|
30
30
|
*
|
|
31
31
|
* Emits per-rule ids so `overrides` can downgrade/disable individual checks.
|
|
32
|
+
*
|
|
33
|
+
* The citation check resolves two forms — a backticked file path and an
|
|
34
|
+
* `it('…')` title. A Mechanism cell that cites something else (a rule id in
|
|
35
|
+
* your own architecture tool, a CI job) is not resolved here, and this preset
|
|
36
|
+
* takes no plugin for it: what counts as a live id is your fact, not the
|
|
37
|
+
* corpus's. Compose that check from `rows()` + `correspondence()` against the
|
|
38
|
+
* set you hold — the worked recipe is "Citing something that is not a file or
|
|
39
|
+
* a test" on the `eess-md` docs page.
|
|
32
40
|
*/
|
|
33
41
|
export declare function adrEnforcement(corpus: Corpus, options?: AdrEnforcementOptions): ArchViolation[];
|
|
34
42
|
//# sourceMappingURL=adr.d.ts.map
|
package/dist/rules/adr.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"adr.d.ts","sourceRoot":"","sources":["../../src/rules/adr.ts"],"names":[],"mappings":"AAEA,OAAO,EAKL,KAAK,aAAa,EAClB,KAAK,iBAAiB,
|
|
1
|
+
{"version":3,"file":"adr.d.ts","sourceRoot":"","sources":["../../src/rules/adr.ts"],"names":[],"mappings":"AAEA,OAAO,EAKL,KAAK,aAAa,EAClB,KAAK,iBAAiB,EAEvB,MAAM,kBAAkB,CAAA;AACzB,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAA;AAW1C;;;;;GAKG;AACH,MAAM,WAAW,qBAAsB,SAAQ,iBAAiB;IAC9D,uDAAuD;IACvD,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAA;IACrB,sEAAsE;IACtE,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;IAClC,kEAAkE;IAClE,QAAQ,CAAC,OAAO,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAA;IACtE,iDAAiD;IACjD,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;IAClC,wFAAwF;IACxF,QAAQ,CAAC,eAAe,CAAC,EAAE,OAAO,CAAA;CACnC;AAuDD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,cAAc,CAC5B,MAAM,EAAE,MAAM,EACd,OAAO,GAAE,qBAA0B,GAClC,aAAa,EAAE,CAgDjB"}
|
package/dist/rules/adr.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { existsSync, readFileSync } from 'node:fs';
|
|
2
2
|
import { join } from 'node:path';
|
|
3
|
-
import { dispatchRule, finishPreset, validateOverrides, not, } from '@nielspeter/eess';
|
|
3
|
+
import { dispatchRule, finishPreset, validateOverrides, not, mergeCollectResults, } from '@nielspeter/eess';
|
|
4
4
|
import { docs } from '../builders/docs.js';
|
|
5
5
|
import { haveNameMatching } from '../predicates/document.js';
|
|
6
6
|
import { haveTableRowsSatisfying } from '../conditions/table-rows.js';
|
|
@@ -61,6 +61,14 @@ function validateCitations(ctx, corpus) {
|
|
|
61
61
|
* resolve; a soft-tier clause declared as such passes.
|
|
62
62
|
*
|
|
63
63
|
* Emits per-rule ids so `overrides` can downgrade/disable individual checks.
|
|
64
|
+
*
|
|
65
|
+
* The citation check resolves two forms — a backticked file path and an
|
|
66
|
+
* `it('…')` title. A Mechanism cell that cites something else (a rule id in
|
|
67
|
+
* your own architecture tool, a CI job) is not resolved here, and this preset
|
|
68
|
+
* takes no plugin for it: what counts as a live id is your fact, not the
|
|
69
|
+
* corpus's. Compose that check from `rows()` + `correspondence()` against the
|
|
70
|
+
* set you hold — the worked recipe is "Citing something that is not a file or
|
|
71
|
+
* a test" on the `eess-md` docs page.
|
|
64
72
|
*/
|
|
65
73
|
export function adrEnforcement(corpus, options = {}) {
|
|
66
74
|
const dir = options.dir ?? 'docs/adr/**';
|
|
@@ -85,9 +93,13 @@ export function adrEnforcement(corpus, options = {}) {
|
|
|
85
93
|
.satisfy(notIndexDoc)
|
|
86
94
|
.should()
|
|
87
95
|
.satisfy(haveTableRowsSatisfying({ section, columns, row: (ctx) => validateTier(ctx, tiers) }));
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
96
|
+
// The kernel merge, not a spread: a spread drops each receipt's evidence, and
|
|
97
|
+
// this preset's own all-off case (every rule id overridden `'off'`) is then
|
|
98
|
+
// indistinguishable from a healthy run that found nothing — bug 0261, measured
|
|
99
|
+
// in this very function.
|
|
100
|
+
const parts = [
|
|
101
|
+
dispatchRule(declared, 'adr/enforcement-declared', 'error', options.overrides),
|
|
102
|
+
dispatchRule(validTiers, 'adr/valid-tiers', 'error', options.overrides),
|
|
91
103
|
];
|
|
92
104
|
if (verify) {
|
|
93
105
|
const citations = docs(corpus)
|
|
@@ -96,8 +108,8 @@ export function adrEnforcement(corpus, options = {}) {
|
|
|
96
108
|
.satisfy(notIndexDoc)
|
|
97
109
|
.should()
|
|
98
110
|
.satisfy(haveTableRowsSatisfying({ section, columns, row: (ctx) => validateCitations(ctx, corpus) }));
|
|
99
|
-
|
|
111
|
+
parts.push(dispatchRule(citations, 'adr/citations-resolve', 'error', options.overrides));
|
|
100
112
|
}
|
|
101
|
-
return finishPreset(
|
|
113
|
+
return finishPreset(mergeCollectResults(parts), options);
|
|
102
114
|
}
|
|
103
115
|
//# sourceMappingURL=adr.js.map
|
package/dist/rules/adr.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"adr.js","sourceRoot":"","sources":["../../src/rules/adr.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AAClD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAChC,OAAO,EACL,YAAY,EACZ,YAAY,EACZ,iBAAiB,EACjB,GAAG,
|
|
1
|
+
{"version":3,"file":"adr.js","sourceRoot":"","sources":["../../src/rules/adr.ts"],"names":[],"mappings":"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"}
|
package/dist/rules/ledger.d.ts
CHANGED
|
@@ -19,6 +19,17 @@ import type { ArchViolation } from '../model/violation.js';
|
|
|
19
19
|
* `collectTaskItems`), so a `- [ ]` in fenced code or a blockquote is excluded
|
|
20
20
|
* for free — no hand-rolled stripping. `deferred: none` summaries and the
|
|
21
21
|
* `State:` header token are unambiguous prose lines, scanned from the source.
|
|
22
|
+
*
|
|
23
|
+
* **Expressed through the builder DSL** (bug 0131, closed by plan 0101 Phase 1):
|
|
24
|
+
* previously this preset hand-iterated `corpus.documents()` directly, calling
|
|
25
|
+
* no `RuleBuilder`/`TerminalBuilder` at all — invisible to every kernel-level
|
|
26
|
+
* guarantee, including the ADR-010 evidence gate the fold (plan 0088) landed.
|
|
27
|
+
* `docs(corpus)` and `taskItems(corpus)` already existed and already
|
|
28
|
+
* `extends RuleBuilder<T, Corpus>` — the detection logic below is unchanged
|
|
29
|
+
* from the pre-fold version (same regexes, same `findState`/`isDoneItem`
|
|
30
|
+
* helpers, same messages), only its *iteration* now goes through the DSL, so
|
|
31
|
+
* this preset inherits the fold's fail-closed floor like every sibling
|
|
32
|
+
* builder-based rule already does.
|
|
22
33
|
*/
|
|
23
34
|
export interface HonestyAtCloseOptions extends PresetReportOptions {
|
|
24
35
|
/**
|
|
@@ -47,11 +58,118 @@ export interface HonestyAtCloseOptions extends PresetReportOptions {
|
|
|
47
58
|
* whether or not they also appear in {@link states}.
|
|
48
59
|
*/
|
|
49
60
|
readonly terminalStates?: readonly string[];
|
|
61
|
+
/**
|
|
62
|
+
* Declare that this corpus may legitimately hold zero non-board documents
|
|
63
|
+
* right now — a freshly-bootstrapped lane before its first real item is
|
|
64
|
+
* authored (e.g. a `kit/`-seeded `work/plans/` containing only
|
|
65
|
+
* `ROADMAP.md`). Default `false`: an empty non-board selection is treated
|
|
66
|
+
* as a dead selector (wrong glob, broken `boardFiles`) and reported.
|
|
67
|
+
*
|
|
68
|
+
* This is a genuine, caller-declared claim, not something `honestyAtClose`
|
|
69
|
+
* can infer — nothing else in the corpus distinguishes "nothing authored
|
|
70
|
+
* yet" from "the selector broke." Per ADR-010 it **expires**: the day a
|
|
71
|
+
* real document appears, `examined > 0` while this is still declared `true`
|
|
72
|
+
* is itself reported ("the declaration has expired"), so remove it once
|
|
73
|
+
* the lane has real content.
|
|
74
|
+
*/
|
|
75
|
+
readonly expectEmptyHeaders?: boolean;
|
|
50
76
|
}
|
|
77
|
+
/**
|
|
78
|
+
* The `State:` token in the header region, with its line — one scan, shared by
|
|
79
|
+
* the done-item test and the placement check so the two cannot disagree about
|
|
80
|
+
* what a document says it is.
|
|
81
|
+
*/
|
|
82
|
+
export declare function findState(text: string, vocabulary: readonly string[]): {
|
|
83
|
+
state?: string;
|
|
84
|
+
raw: string;
|
|
85
|
+
line: number;
|
|
86
|
+
} | null;
|
|
51
87
|
/**
|
|
52
88
|
* Run the honesty-at-close gate over a corpus. Throws `ArchRuleError` on any
|
|
53
89
|
* finding. Placement is checked on every item; ledger reconciliation only on
|
|
54
90
|
* done-items (the inverse of the frozen-folder exemption).
|
|
91
|
+
*
|
|
92
|
+
* Three builder-based rules, merged: header state↔folder (`docs()`), silent
|
|
93
|
+
* open boxes (`taskItems()`, filtered to done-items), and the deferred-none
|
|
94
|
+
* lie (`docs()`, filtered to done-items carrying a deferred-disposed box).
|
|
95
|
+
*
|
|
96
|
+
* **Emptiness declarations, and why each is shaped the way it is** (bug 0131
|
|
97
|
+
* follow-up, six-persona review before this landed): `.expectEmpty()` is only
|
|
98
|
+
* a sound fail-closed gate when the thing that decides *whether* to declare
|
|
99
|
+
* it is independent of the predicate the declaration would otherwise let
|
|
100
|
+
* pass silently. Two designs were tried and rejected for this reason:
|
|
101
|
+
*
|
|
102
|
+
* 1. Peeking the exact same selection each rule gates (`.select()` on
|
|
103
|
+
* `openBoxesOnDoneItems`/`doneItemsWithDeferredBox` themselves) before
|
|
104
|
+
* conditionally declaring `.expectEmpty()`. This *reads* as a live check
|
|
105
|
+
* but is circular: the peek and the real run filter the identical
|
|
106
|
+
* elements through the identical predicates with nothing in between, so
|
|
107
|
+
* the declaration is always self-consistent and can never expire — it
|
|
108
|
+
* provides zero protection against exactly the corruption class ADR-010
|
|
109
|
+
* exists to catch, for either rule.
|
|
110
|
+
* 2. Gating on `terminalStates.length === 0` alone. Correct for the
|
|
111
|
+
* always-structurally-empty `proposals` lane, but too narrow: it doesn't
|
|
112
|
+
* cover a plan/bug lane's own test fixtures that legitimately have zero
|
|
113
|
+
* done-items in a given run (e.g. a single-document fixture testing an
|
|
114
|
+
* unrelated placement rule).
|
|
115
|
+
* 3. Gating both rules on one coarse "any done item exists in this corpus"
|
|
116
|
+
* signal. Independent of the right predicate, but the wrong *scope*: most
|
|
117
|
+
* done items carry zero open boxes and zero deferred boxes — that's the
|
|
118
|
+
* normal, healthy, permanent state for a reconciled item, not a corner
|
|
119
|
+
* case — so "a done item exists" routinely holds while the real selection
|
|
120
|
+
* (open boxes on it, or a deferred box on it) is legitimately empty. That
|
|
121
|
+
* false-positived on the project's own `fixed/green-bug-closed.md` fixture
|
|
122
|
+
* (a done item with one already-checked box, no open boxes at all).
|
|
123
|
+
*
|
|
124
|
+
* The fix: peek `openTaskItems` once (`taskItems(corpus).that().areOpen()`,
|
|
125
|
+
* a purely structural filter, no done-item check), then derive each rule's
|
|
126
|
+
* own emptiness signal from *that*, narrowed to what the rule actually
|
|
127
|
+
* selects, while staying independent of the specific predicate/function
|
|
128
|
+
* being protected:
|
|
129
|
+
*
|
|
130
|
+
* - `silentOpenBoxViolations` is gated by `belongsToADoneItem`. Its peek
|
|
131
|
+
* (`anyOpenBoxOnADoneItem`) calls `isDoneItem` on `openTaskItems` directly
|
|
132
|
+
* — not through `belongsToADoneItem` — so a corruption of that predicate
|
|
133
|
+
* specifically doesn't also blind the peek.
|
|
134
|
+
* - `deferredLieViolations`'s selection adds `hasDeferredDisposedBox` (which
|
|
135
|
+
* walks each done document's own mdast via a separate
|
|
136
|
+
* `collectTaskItems(doc.root)` call) on top of `isDoneItemPredicate`. Its
|
|
137
|
+
* peek (`anyDeferredDisposedBoxOnADoneItem`) instead re-tests
|
|
138
|
+
* `openTaskItems` (a different traversal) against the same
|
|
139
|
+
* `DEFERRED_DISPOSITION_RE` constant `hasDeferredDisposedBox` uses — so a
|
|
140
|
+
* corruption of `hasDeferredDisposedBox`'s own body doesn't blind this
|
|
141
|
+
* peek either.
|
|
142
|
+
*
|
|
143
|
+
* Both peeks share `isDoneItem` and the underlying `collectTaskItems` box
|
|
144
|
+
* collection with the very selections they protect — a corruption isolated to
|
|
145
|
+
* either would defeat both peek and real selection identically, uniformly,
|
|
146
|
+
* for every lane. This is a real residual gap, not a narrow one: verified by
|
|
147
|
+
* sabotaging `isDoneItem` against this repo's own real corpus during bug
|
|
148
|
+
* 0131's round-2 review, which produced **zero violations, exit 0** — not a
|
|
149
|
+
* partial miss. `headerStateCondition` does **not** independently backstop
|
|
150
|
+
* this (an earlier draft of this comment claimed it "would likely also
|
|
151
|
+
* surface through `headerViolations`" — false: `headerStateCondition` never
|
|
152
|
+
* calls `isDoneItem`, it recomputes the folder half of the same determination
|
|
153
|
+
* inline, so it only catches a corruption if a live state/folder mismatch
|
|
154
|
+
* already exists in the scanned corpus, which it usually doesn't).
|
|
155
|
+
*
|
|
156
|
+
* `honestyAtClose` itself can't close this gap generically — a corpus with
|
|
157
|
+
* zero done-items is legitimate on a freshly-bootstrapped lane's first day,
|
|
158
|
+
* so a library-level "zero done-items across the whole call is always wrong"
|
|
159
|
+
* assertion would be exactly the false-positive class `expectEmptyHeaders`
|
|
160
|
+
* exists to avoid. What closes it is caller knowledge: **a corpus with an
|
|
161
|
+
* established history should assert its own "zero done-items is never
|
|
162
|
+
* legitimate here" claim on top.** `scripts/check-ledger.mjs` (this repo's
|
|
163
|
+
* own wiring) does exactly that — 0 done-items summed across every lane fails
|
|
164
|
+
* the build, because this repo has carried done-items in every
|
|
165
|
+
* terminal-states lane for its entire history. A `kit/`-seeded caller with no
|
|
166
|
+
* history yet should not copy that assertion verbatim; it becomes true, and
|
|
167
|
+
* worth adding, once the corpus has one.
|
|
168
|
+
*
|
|
169
|
+
* `headerViolations` gets no computed declaration — nothing in the corpus
|
|
170
|
+
* can tell "no non-board documents authored yet" apart from "the selector
|
|
171
|
+
* broke." Callers who know the former is legitimate (a freshly-bootstrapped
|
|
172
|
+
* lane) opt in explicitly via {@link HonestyAtCloseOptions.expectEmptyHeaders}.
|
|
55
173
|
*/
|
|
56
174
|
export declare function honestyAtClose(corpus: Corpus, options?: HonestyAtCloseOptions): ArchViolation[];
|
|
57
175
|
/** What a {@link honestyAtClose} run actually examined. */
|
|
@@ -77,6 +195,8 @@ export interface LedgerStats {
|
|
|
77
195
|
* Callers must not re-derive it. `check-ledger.mjs` did, with a copy of the very
|
|
78
196
|
* expression 0119 removed, and its copy disagreed with the preset on 56 of 56
|
|
79
197
|
* records while heading a section captioned "so a green is provably non-vacuous".
|
|
198
|
+
*
|
|
199
|
+
* Pure read-only counting, not a rule — no evidence gate applies here.
|
|
80
200
|
*/
|
|
81
201
|
export declare function ledgerStats(corpus: Corpus, options?: HonestyAtCloseOptions): LedgerStats;
|
|
82
202
|
//# sourceMappingURL=ledger.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ledger.d.ts","sourceRoot":"","sources":["../../src/rules/ledger.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,KAAK,mBAAmB,
|
|
1
|
+
{"version":3,"file":"ledger.d.ts","sourceRoot":"","sources":["../../src/rules/ledger.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,KAAK,mBAAmB,EAAuB,MAAM,kBAAkB,CAAA;AAE9F,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAA;AAE1C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAA;AAK1D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,MAAM,WAAW,qBAAsB,SAAQ,mBAAmB;IAChE;;;OAGG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;IACxC,sEAAsE;IACtE,QAAQ,CAAC,UAAU,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;IACvC;;;;OAIG;IACH,QAAQ,CAAC,YAAY,CAAC,EAAE,OAAO,CAAA;IAC/B;;;;;OAKG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;IACnC;;;;OAIG;IACH,QAAQ,CAAC,cAAc,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;IAC3C;;;;;;;;;;;;;OAaG;IACH,QAAQ,CAAC,kBAAkB,CAAC,EAAE,OAAO,CAAA;CACtC;AA+ED;;;;GAIG;AACH,wBAAgB,SAAS,CACvB,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,SAAS,MAAM,EAAE,GAC5B;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CA6BtD;AA+ND;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsFG;AACH,wBAAgB,cAAc,CAC5B,MAAM,EAAE,MAAM,EACd,OAAO,GAAE,qBAA0B,GAClC,aAAa,EAAE,CA2EjB;AAED,2DAA2D;AAC3D,MAAM,WAAW,WAAW;IAC1B,mDAAmD;IACnD,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,wEAAwE;IACxE,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAA;IAClC,4EAA4E;IAC5E,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAA;IAChC,qFAAqF;IACrF,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;CAC3B;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,GAAE,qBAA0B,GAAG,WAAW,CAqB5F"}
|