@am_shork/attest 0.2.1 → 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 +63 -19
- package/README.md +12 -1
- package/dist/cli/report.d.ts +17 -0
- package/dist/cli/report.d.ts.map +1 -1
- package/dist/cli/report.js +48 -1
- package/dist/cli/report.js.map +1 -1
- package/dist/core/gate.d.ts +9 -9
- package/dist/core/gate.d.ts.map +1 -1
- package/dist/core/gate.js +11 -11
- package/dist/core/gate.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -15,24 +15,67 @@ not API.
|
|
|
15
15
|
|
|
16
16
|
## [Unreleased]
|
|
17
17
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
18
|
+
## [0.2.2] - 2026-07-26
|
|
19
|
+
|
|
20
|
+
A wall of identical diagnostics now says once that it is one cause, and the
|
|
21
|
+
per-issue lines it summarises are unchanged.
|
|
22
|
+
|
|
23
|
+
### Added
|
|
24
|
+
|
|
25
|
+
- **A report of N issues sharing one `code` now says so once.** The 0.1.1 → 0.2.0
|
|
26
|
+
upgrade printed six `registry-not-static` ERRORs in a row — one per registry
|
|
27
|
+
file, every one caused by the same prose written as `'…' + '…'` — and left the
|
|
28
|
+
reader to work out that they were one cause and one mechanical fix. Every
|
|
29
|
+
command that prints issues (`check`, `verify`, `cover`, `render`, `archive`)
|
|
30
|
+
now adds one line above the counts when a code repeats:
|
|
31
|
+
|
|
32
|
+
```
|
|
33
|
+
Repeated: 6 × ERROR registry-not-static, 4 × WARNING rationale-placeholder
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
The per-issue lines are untouched — they are what makes a diagnostic
|
|
37
|
+
clickable — and this is the last entry from the skills-manager adoption report
|
|
38
|
+
(0.2.0, 41 requirements / 106 scenarios, plain-TS), so the
|
|
39
|
+
`Under consideration` section is now empty and gone. Five decisions, with the
|
|
40
|
+
reasoning, because each of them could plausibly have gone the other way:
|
|
41
|
+
|
|
42
|
+
**The `code` names the shared cause, and there is no table.** The obvious
|
|
43
|
+
reading of "name the cause" is a `code` → prose map: `registry-not-static` →
|
|
44
|
+
"a registry was built by concatenation". That map would have to be extended
|
|
45
|
+
with every new code, and the failure mode of forgetting is silent — the line
|
|
46
|
+
keeps printing, just vaguer. So the summary states structure only, how many
|
|
47
|
+
issues carry the same code, and leaves the explaining to the per-issue
|
|
48
|
+
`message`s directly above it. A `code` already *is* the stable name of the
|
|
49
|
+
shared rule; `message` is prose and not API, which is exactly why the summary
|
|
50
|
+
quotes neither.
|
|
51
|
+
|
|
52
|
+
**Three, not two.** Two adjacent lines with the same code are not a wall — the
|
|
53
|
+
repetition is visible at a glance, and summarising it would charge every
|
|
54
|
+
ordinary double error a line to state what the reader can already see.
|
|
55
|
+
|
|
56
|
+
**Below the issues, beside the counts, not merged into them.** The clickable
|
|
57
|
+
lines land first and the aggregate reads as a conclusion about them rather than
|
|
58
|
+
a preamble to issues not yet seen. It stays a separate line because
|
|
59
|
+
`— N error, M warning, K info` is a fixed shape and the only stable thing to
|
|
60
|
+
`grep` at the end of a report; a conditional clause inside it would make it
|
|
61
|
+
variable-length.
|
|
62
|
+
|
|
63
|
+
**Every level, grouped by level *and* code.** A pile of `rationale-placeholder`
|
|
64
|
+
WARNINGs is the same reading problem as a pile of ERRORs. The grouping key is
|
|
65
|
+
the pair because a count that silently spanned two levels would give one number
|
|
66
|
+
for two different dispositions — in practice every issue site writes a literal
|
|
67
|
+
level, and the composite key is what makes that not need to be true.
|
|
68
|
+
|
|
69
|
+
**Presentation, not a report change.** `SCHEMA_VERSION` is untouched and
|
|
70
|
+
`--json` is byte-identical: the summary is not an `Issue`, so it carries no
|
|
71
|
+
`code` into `issues[]`, adds nothing to `summary`, and cannot move `ok`. Split
|
|
72
|
+
across two self-requirements (ATX-23, ATX-24) rather than one, because the
|
|
73
|
+
cheapest implementation — push one more `Issue` — satisfies the human half
|
|
74
|
+
completely while breaking the contract half, and at ERROR level would flip the
|
|
75
|
+
verdict of a report that found nothing new. That needs a scenario that fails,
|
|
76
|
+
not a clause in a sentence. `docs/en/attest-design.md` §5.3 is deliberately
|
|
77
|
+
unchanged: it specifies the `Issue` contract and the grading, and documenting a
|
|
78
|
+
terminal nicety there would imply this is part of it.
|
|
36
79
|
|
|
37
80
|
## [0.2.1] - 2026-07-26
|
|
38
81
|
|
|
@@ -698,7 +741,8 @@ Initial release.
|
|
|
698
741
|
(MIT), whose four-stage engine and diff-first change model Attest's
|
|
699
742
|
architecture is adapted from (re-implemented from scratch, no source copied).
|
|
700
743
|
|
|
701
|
-
[Unreleased]: https://gitlab.com/Pseudorca/attest/-/compare/v0.2.
|
|
744
|
+
[Unreleased]: https://gitlab.com/Pseudorca/attest/-/compare/v0.2.2...main
|
|
745
|
+
[0.2.2]: https://gitlab.com/Pseudorca/attest/-/tags/v0.2.2
|
|
702
746
|
[0.2.1]: https://gitlab.com/Pseudorca/attest/-/tags/v0.2.1
|
|
703
747
|
[0.2.0]: https://gitlab.com/Pseudorca/attest/-/tags/v0.2.0
|
|
704
748
|
[0.1.7]: https://gitlab.com/Pseudorca/attest/-/tags/v0.1.7
|
package/README.md
CHANGED
|
@@ -185,6 +185,17 @@ The gap between the two numbers is worth watching: a spec file whose
|
|
|
185
185
|
`requirement()` call Attest cannot see statically is skipped rather than failed,
|
|
186
186
|
and that is where it shows. The same four numbers are in `--json` under `counts`.
|
|
187
187
|
|
|
188
|
+
When three or more issues in one report share a level and a code, one line above
|
|
189
|
+
the counts says so, because a wall of identical codes is one rule and many sites:
|
|
190
|
+
|
|
191
|
+
```
|
|
192
|
+
Repeated: 6 × ERROR registry-not-static, 4 × WARNING rationale-placeholder
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
Every per-issue line stays exactly as it is — they are what makes a diagnostic
|
|
196
|
+
clickable — and the summary is terminal output only: it is not an issue, so it
|
|
197
|
+
appears nowhere in `--json`, changes no count, and never moves a verdict.
|
|
198
|
+
|
|
188
199
|
A run with **no requirements** under the root is an `empty-spec` ERROR, not a
|
|
189
200
|
pass. "No failing tests" is not the same claim as "the requirements hold", and
|
|
190
201
|
the case that matters is not the empty directory — it is the repo whose registry
|
|
@@ -221,7 +232,7 @@ attest check --json
|
|
|
221
232
|
{
|
|
222
233
|
"tool": "attest",
|
|
223
234
|
"schemaVersion": 1,
|
|
224
|
-
"version": "0.2.
|
|
235
|
+
"version": "0.2.2",
|
|
225
236
|
"command": "check",
|
|
226
237
|
"ok": false,
|
|
227
238
|
"summary": { "error": 1, "warning": 0, "info": 0 },
|
package/dist/cli/report.d.ts
CHANGED
|
@@ -1,6 +1,23 @@
|
|
|
1
1
|
import type { CoverageRow, VerifyCounts } from '../core/pipeline.js';
|
|
2
2
|
import type { Issue } from '../core/types.js';
|
|
3
3
|
export declare function formatIssues(issues: Issue[]): string;
|
|
4
|
+
/**
|
|
5
|
+
* A code repeating across files is one rule and many sites, and a reader looking
|
|
6
|
+
* at the wall has to diff the lines to learn that. This says it once.
|
|
7
|
+
*
|
|
8
|
+
* There is deliberately no code → prose table naming the "cause": the `code`
|
|
9
|
+
* already *is* the name of the shared rule, and each site's `message` states the
|
|
10
|
+
* rule in full. A table would also have to be extended with every new code, and
|
|
11
|
+
* forgetting to would degrade this line in silence. So the line states structure
|
|
12
|
+
* only — how many issues carry the same code — and leaves the explaining to the
|
|
13
|
+
* per-site lines above it, which are what makes a diagnostic clickable.
|
|
14
|
+
*
|
|
15
|
+
* Grouped by level *and* code, not code alone: a count that silently spanned two
|
|
16
|
+
* levels would name one number for two different dispositions. Every issue site
|
|
17
|
+
* writes a literal level, so in practice the two groupings agree — the composite
|
|
18
|
+
* key is what makes that not need to be true.
|
|
19
|
+
*/
|
|
20
|
+
export declare function formatRepeats(issues: Issue[]): string;
|
|
4
21
|
export declare function summarize(issues: Issue[], scope?: VerifyCounts): string;
|
|
5
22
|
/**
|
|
6
23
|
* The pre-run line for `verify`: how many spec files were located, and how many
|
package/dist/cli/report.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"report.d.ts","sourceRoot":"","sources":["../../src/cli/report.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"report.d.ts","sourceRoot":"","sources":["../../src/cli/report.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACrE,OAAO,KAAK,EAAE,KAAK,EAAS,MAAM,kBAAkB,CAAC;AAUrD,wBAAgB,YAAY,CAAC,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,CAYpD;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,CAkBrD;AAUD,wBAAgB,SAAS,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,KAAK,CAAC,EAAE,YAAY,GAAG,MAAM,CASvE;AAID;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,YAAY,GAAG,MAAM,CAIvD;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,WAAW,EAAE,GAAG,MAAM,CAW1D"}
|
package/dist/cli/report.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// Terminal rendering of graded issues (design §5.3 levels). Pure formatting —
|
|
2
2
|
// no process side effects — so it stays testable and the CLI stays thin.
|
|
3
3
|
import chalk from 'chalk';
|
|
4
|
+
import { byCodeUnit } from '../core/order.js';
|
|
4
5
|
const LEVEL_TAG = {
|
|
5
6
|
ERROR: (s) => chalk.red.bold(s),
|
|
6
7
|
WARNING: (s) => chalk.yellow.bold(s),
|
|
@@ -18,8 +19,54 @@ export function formatIssues(issues) {
|
|
|
18
19
|
lines.push(`${LEVEL_TAG[level](level.padEnd(7))} ${chalk.cyan(i.code)}${loc}\n ${i.message}`);
|
|
19
20
|
}
|
|
20
21
|
}
|
|
21
|
-
|
|
22
|
+
const repeats = formatRepeats(issues);
|
|
23
|
+
return repeats ? `${lines.join('\n')}\n${repeats}` : lines.join('\n');
|
|
22
24
|
}
|
|
25
|
+
/**
|
|
26
|
+
* A code repeating across files is one rule and many sites, and a reader looking
|
|
27
|
+
* at the wall has to diff the lines to learn that. This says it once.
|
|
28
|
+
*
|
|
29
|
+
* There is deliberately no code → prose table naming the "cause": the `code`
|
|
30
|
+
* already *is* the name of the shared rule, and each site's `message` states the
|
|
31
|
+
* rule in full. A table would also have to be extended with every new code, and
|
|
32
|
+
* forgetting to would degrade this line in silence. So the line states structure
|
|
33
|
+
* only — how many issues carry the same code — and leaves the explaining to the
|
|
34
|
+
* per-site lines above it, which are what makes a diagnostic clickable.
|
|
35
|
+
*
|
|
36
|
+
* Grouped by level *and* code, not code alone: a count that silently spanned two
|
|
37
|
+
* levels would name one number for two different dispositions. Every issue site
|
|
38
|
+
* writes a literal level, so in practice the two groupings agree — the composite
|
|
39
|
+
* key is what makes that not need to be true.
|
|
40
|
+
*/
|
|
41
|
+
export function formatRepeats(issues) {
|
|
42
|
+
/** `${level} ${code}` -> how many issues carry that pair, and its parts. */
|
|
43
|
+
const groups = new Map();
|
|
44
|
+
for (const i of issues) {
|
|
45
|
+
const key = `${i.level} ${i.code}`;
|
|
46
|
+
const seen = groups.get(key);
|
|
47
|
+
if (seen)
|
|
48
|
+
seen.count++;
|
|
49
|
+
else
|
|
50
|
+
groups.set(key, { level: i.level, code: i.code, count: 1 });
|
|
51
|
+
}
|
|
52
|
+
const repeated = [...groups]
|
|
53
|
+
.filter(([, g]) => g.count >= REPEAT_THRESHOLD)
|
|
54
|
+
// Count first, then the key — by code unit, so the line a reader compares
|
|
55
|
+
// between two runs does not depend on the machine's collation.
|
|
56
|
+
.sort(([aKey, a], [bKey, b]) => b.count - a.count || byCodeUnit(aKey, bKey))
|
|
57
|
+
.map(([, g]) => `${g.count} × ${g.level} ${g.code}`);
|
|
58
|
+
if (repeated.length === 0)
|
|
59
|
+
return '';
|
|
60
|
+
// One line however many codes repeat: the point is to shorten the report.
|
|
61
|
+
return chalk.dim(`Repeated: ${repeated.join(', ')}`);
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Two adjacent lines with the same code are not a wall — the repetition is
|
|
65
|
+
* visible at a glance, and summarising it would charge every ordinary double
|
|
66
|
+
* error an extra line to say what the reader already knows. Three is where the
|
|
67
|
+
* repetition stops being obvious.
|
|
68
|
+
*/
|
|
69
|
+
const REPEAT_THRESHOLD = 3;
|
|
23
70
|
export function summarize(issues, scope) {
|
|
24
71
|
const counts = { ERROR: 0, WARNING: 0, INFO: 0 };
|
|
25
72
|
for (const i of issues)
|
package/dist/cli/report.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"report.js","sourceRoot":"","sources":["../../src/cli/report.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,yEAAyE;AAEzE,OAAO,KAAK,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"report.js","sourceRoot":"","sources":["../../src/cli/report.ts"],"names":[],"mappings":"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"}
|
package/dist/core/gate.d.ts
CHANGED
|
@@ -7,6 +7,15 @@ export interface GateInputs {
|
|
|
7
7
|
/** Executable verification result (design §5.4). */
|
|
8
8
|
run: RunResult;
|
|
9
9
|
}
|
|
10
|
+
/**
|
|
11
|
+
* Declared-not-run: a scenario the static plan claims attests a requirement,
|
|
12
|
+
* which the runtime never executed (skipped, or excluded by an `.only`).
|
|
13
|
+
*
|
|
14
|
+
* Exported because `verify` and `archive` both make this call. While each owned
|
|
15
|
+
* a copy, the two verdicts agreed only by transcription — and the whole point of
|
|
16
|
+
* this framework is that agreement should be structural, not clerical.
|
|
17
|
+
*/
|
|
18
|
+
export declare function declaredNotRunIssues(plan: AttestPlan, run: RunResult): Issue[];
|
|
10
19
|
/**
|
|
11
20
|
* Decide whether a change may be archived. Returns the blocking issues; an
|
|
12
21
|
* empty array means the gate passes (design §8). Checks, in order:
|
|
@@ -18,14 +27,5 @@ export interface GateInputs {
|
|
|
18
27
|
* 3. Static coverage vs runtime coverage: every declared scenario actually
|
|
19
28
|
* ran (catches skip/only false coverage).
|
|
20
29
|
*/
|
|
21
|
-
/**
|
|
22
|
-
* Declared-not-run: a scenario the static plan claims attests a requirement,
|
|
23
|
-
* which the runtime never executed (skipped, or excluded by an `.only`).
|
|
24
|
-
*
|
|
25
|
-
* Exported because `verify` and `archive` both make this call. While each owned
|
|
26
|
-
* a copy, the two verdicts agreed only by transcription — and the whole point of
|
|
27
|
-
* this framework is that agreement should be structural, not clerical.
|
|
28
|
-
*/
|
|
29
|
-
export declare function declaredNotRunIssues(plan: AttestPlan, run: RunResult): Issue[];
|
|
30
30
|
export declare function evaluateGate({ registry, plan, run }: GateInputs): Issue[];
|
|
31
31
|
//# sourceMappingURL=gate.d.ts.map
|
package/dist/core/gate.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gate.d.ts","sourceRoot":"","sources":["../../src/core/gate.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAEzE,MAAM,WAAW,UAAU;IACzB,yEAAyE;IACzE,QAAQ,EAAE,QAAQ,CAAC;IACnB,8CAA8C;IAC9C,IAAI,EAAE,UAAU,CAAC;IACjB,oDAAoD;IACpD,GAAG,EAAE,SAAS,CAAC;CAChB;AAED
|
|
1
|
+
{"version":3,"file":"gate.d.ts","sourceRoot":"","sources":["../../src/core/gate.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAEzE,MAAM,WAAW,UAAU;IACzB,yEAAyE;IACzE,QAAQ,EAAE,QAAQ,CAAC;IACnB,8CAA8C;IAC9C,IAAI,EAAE,UAAU,CAAC;IACjB,oDAAoD;IACpD,GAAG,EAAE,SAAS,CAAC;CAChB;AAED;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,UAAU,EAAE,GAAG,EAAE,SAAS,GAAG,KAAK,EAAE,CAe9E;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,YAAY,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE,UAAU,GAAG,KAAK,EAAE,CAqBzE"}
|
package/dist/core/gate.js
CHANGED
|
@@ -4,17 +4,6 @@
|
|
|
4
4
|
// inputs; the file orchestration (load registry+delta, parse all specs, run)
|
|
5
5
|
// is wired in the Locate layer / CLI (see pipeline.ts).
|
|
6
6
|
import { validateStructure } from './validator.js';
|
|
7
|
-
/**
|
|
8
|
-
* Decide whether a change may be archived. Returns the blocking issues; an
|
|
9
|
-
* empty array means the gate passes (design §8). Checks, in order:
|
|
10
|
-
* 1. Structural ERRORs on the end-state registry (no orphan / uncovered /
|
|
11
|
-
* unbound-param). This is also the design's step-4 final re-validation:
|
|
12
|
-
* the registry+plan here are already the applied result, so one pass
|
|
13
|
-
* validates the end state.
|
|
14
|
-
* 2. Executable: all tests green.
|
|
15
|
-
* 3. Static coverage vs runtime coverage: every declared scenario actually
|
|
16
|
-
* ran (catches skip/only false coverage).
|
|
17
|
-
*/
|
|
18
7
|
/**
|
|
19
8
|
* Declared-not-run: a scenario the static plan claims attests a requirement,
|
|
20
9
|
* which the runtime never executed (skipped, or excluded by an `.only`).
|
|
@@ -39,6 +28,17 @@ export function declaredNotRunIssues(plan, run) {
|
|
|
39
28
|
}
|
|
40
29
|
return issues;
|
|
41
30
|
}
|
|
31
|
+
/**
|
|
32
|
+
* Decide whether a change may be archived. Returns the blocking issues; an
|
|
33
|
+
* empty array means the gate passes (design §8). Checks, in order:
|
|
34
|
+
* 1. Structural ERRORs on the end-state registry (no orphan / uncovered /
|
|
35
|
+
* unbound-param). This is also the design's step-4 final re-validation:
|
|
36
|
+
* the registry+plan here are already the applied result, so one pass
|
|
37
|
+
* validates the end state.
|
|
38
|
+
* 2. Executable: all tests green.
|
|
39
|
+
* 3. Static coverage vs runtime coverage: every declared scenario actually
|
|
40
|
+
* ran (catches skip/only false coverage).
|
|
41
|
+
*/
|
|
42
42
|
export function evaluateGate({ registry, plan, run }) {
|
|
43
43
|
const blocking = [];
|
|
44
44
|
// 1) Structure (end-state re-validation).
|
package/dist/core/gate.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gate.js","sourceRoot":"","sources":["../../src/core/gate.ts"],"names":[],"mappings":"AAAA,yEAAyE;AACzE,iFAAiF;AACjF,4EAA4E;AAC5E,6EAA6E;AAC7E,wDAAwD;AAExD,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAYnD
|
|
1
|
+
{"version":3,"file":"gate.js","sourceRoot":"","sources":["../../src/core/gate.ts"],"names":[],"mappings":"AAAA,yEAAyE;AACzE,iFAAiF;AACjF,4EAA4E;AAC5E,6EAA6E;AAC7E,wDAAwD;AAExD,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAYnD;;;;;;;GAOG;AACH,MAAM,UAAU,oBAAoB,CAAC,IAAgB,EAAE,GAAc;IACnE,MAAM,MAAM,GAAY,EAAE,CAAC;IAC3B,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;QAC/B,IAAI,CAAC,GAAG,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC;YACnD,MAAM,CAAC,IAAI,CAAC;gBACV,KAAK,EAAE,OAAO;gBACd,IAAI,EAAE,kBAAkB;gBACxB,KAAK,EAAE,CAAC,CAAC,KAAK;gBACd,IAAI,EAAE,CAAC,CAAC,IAAI;gBACZ,IAAI,EAAE,CAAC,CAAC,IAAI;gBACZ,OAAO,EAAE,aAAa,CAAC,CAAC,IAAI,oCAAoC,CAAC,CAAC,KAAK,2DAA2D;aACnI,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,YAAY,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,GAAG,EAAc;IAC9D,MAAM,QAAQ,GAAY,EAAE,CAAC;IAE7B,0CAA0C;IAC1C,QAAQ,CAAC,IAAI,CACX,GAAG,iBAAiB,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,OAAO,CAAC,CACxE,CAAC;IAEF,4BAA4B;IAC5B,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC;QAChB,QAAQ,CAAC,IAAI,CAAC;YACZ,KAAK,EAAE,OAAO;YACd,IAAI,EAAE,WAAW;YACjB,OAAO,EAAE,wDAAwD;SAClE,CAAC,CAAC;IACL,CAAC;IAED,2EAA2E;IAC3E,QAAQ,CAAC,IAAI,CAAC,GAAG,oBAAoB,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC;IAElD,OAAO,QAAQ,CAAC;AAClB,CAAC"}
|
package/package.json
CHANGED