@memberjunction/standards 0.0.0 → 6.1.0-edge.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/LICENSE +7 -0
- package/README.md +120 -28
- package/bin/run.js +92 -0
- package/dist/checks/ui-layers.d.ts +78 -0
- package/dist/checks/ui-layers.d.ts.map +1 -0
- package/dist/checks/ui-layers.js +408 -0
- package/dist/checks/ui-layers.js.map +1 -0
- package/dist/config.d.ts +26 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +98 -0
- package/dist/config.js.map +1 -0
- package/dist/index.d.ts +38 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +38 -0
- package/dist/index.js.map +1 -0
- package/dist/registry.d.ts +27 -0
- package/dist/registry.d.ts.map +1 -0
- package/dist/registry.js +31 -0
- package/dist/registry.js.map +1 -0
- package/dist/runner.d.ts +25 -0
- package/dist/runner.d.ts.map +1 -0
- package/dist/runner.js +110 -0
- package/dist/runner.js.map +1 -0
- package/dist/scaffold.d.ts +55 -0
- package/dist/scaffold.d.ts.map +1 -0
- package/dist/scaffold.js +179 -0
- package/dist/scaffold.js.map +1 -0
- package/dist/types.d.ts +134 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +10 -0
- package/dist/types.js.map +1 -0
- package/dist/version.d.ts +37 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +47 -0
- package/dist/version.js.map +1 -0
- package/package.json +35 -7
- package/schema/mj-standards.schema.json +50 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
ISC License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2023 MemberJunction
|
|
4
|
+
|
|
5
|
+
Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies.
|
|
6
|
+
|
|
7
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,45 +1,137 @@
|
|
|
1
1
|
# @memberjunction/standards
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
MemberJunction's engineering standards, as runnable checks — plus the scaffolding that gets a
|
|
4
|
+
repository actually enforcing them.
|
|
4
5
|
|
|
5
|
-
|
|
6
|
+
```bash
|
|
7
|
+
npx mj-standards adopt --ci github --declare-compliant # set a repo up
|
|
8
|
+
npx mj-standards check # run what it adopted
|
|
9
|
+
npx mj-standards list # what exists, and this repo's stance
|
|
10
|
+
```
|
|
6
11
|
|
|
7
|
-
|
|
12
|
+
Inside a repo that has the MJ CLI, the same commands are `mj standards adopt` / `check` / `list`.
|
|
8
13
|
|
|
9
|
-
|
|
14
|
+
---
|
|
10
15
|
|
|
11
|
-
|
|
12
|
-
1. Configure OIDC trusted publishing for the package name `@memberjunction/standards`
|
|
13
|
-
2. Enable secure, token-less publishing from CI/CD workflows
|
|
14
|
-
3. Establish provenance for packages published under this name
|
|
16
|
+
## Why this package exists
|
|
15
17
|
|
|
16
|
-
|
|
18
|
+
MJ has two kinds of standards and they need opposite distribution mechanisms.
|
|
17
19
|
|
|
18
|
-
|
|
20
|
+
**Judgment standards** are prose that has to be read — the guides in the MJ repo. They are
|
|
21
|
+
distributed as documentation.
|
|
19
22
|
|
|
20
|
-
|
|
23
|
+
**Executable standards** are the ones a machine can settle. Those are here, versioned like code,
|
|
24
|
+
because copy-pasting a check script into each repo stops scaling at about five repos and guarantees
|
|
25
|
+
that half of them are running a version from eight months ago.
|
|
21
26
|
|
|
22
|
-
|
|
27
|
+
## The property that makes it safe
|
|
23
28
|
|
|
24
|
-
|
|
25
|
-
2. Configure the trusted publisher (e.g., GitHub Actions)
|
|
26
|
-
3. Specify the repository and workflow that should be allowed to publish
|
|
27
|
-
4. Use the configured workflow to publish your actual package
|
|
29
|
+
> **Adding a standard to this package never changes an existing repository's result.**
|
|
28
30
|
|
|
29
|
-
|
|
31
|
+
Three mechanisms, together:
|
|
30
32
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
-
|
|
34
|
-
|
|
35
|
-
|
|
33
|
+
1. **Opt-in per check.** A check does nothing until a repo's `.mj-standards.json` names it.
|
|
34
|
+
Registration makes a check *available*, not active.
|
|
35
|
+
2. **Version-pinned adoption.** Each check declares the MJ version it was introduced in (`Since`).
|
|
36
|
+
Each repo records the version it adopted against (`StandardsVersion`). Checks newer than that
|
|
37
|
+
are reported as available and are **not run** — upgrading this package cannot activate them.
|
|
38
|
+
3. **Severity lives in the repo, not the package.** `DefaultSeverity` is what `adopt` writes for a
|
|
39
|
+
*new* adopter. Changing it here never changes a repo that has already adopted. Severity can
|
|
40
|
+
decay forward — `warn` → `error` on a major, by the repo's own choice — and never backward into
|
|
41
|
+
something already shipped.
|
|
36
42
|
|
|
37
|
-
|
|
43
|
+
The result: this package can ship new standards continuously, and a repo pinned on an older MJ
|
|
44
|
+
never wakes up to a red build it did not ask for. Adopting a new standard is always a visible,
|
|
45
|
+
reviewable commit.
|
|
38
46
|
|
|
39
|
-
|
|
40
|
-
- [npm Trusted Publishing Documentation](https://docs.npmjs.com/generating-provenance-statements)
|
|
41
|
-
- [GitHub Actions OIDC Documentation](https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/about-security-hardening-with-openid-connect)
|
|
47
|
+
## `.mj-standards.json`
|
|
42
48
|
|
|
43
|
-
|
|
49
|
+
```jsonc
|
|
50
|
+
{
|
|
51
|
+
"$schema": "./node_modules/@memberjunction/standards/schema/mj-standards.schema.json",
|
|
52
|
+
"StandardsVersion": "6.0.0", // what this repo adopted against
|
|
53
|
+
"Checks": {
|
|
54
|
+
"ui-layers": {
|
|
55
|
+
"Severity": "error", // off | warn | error
|
|
56
|
+
"Roots": ["packages"],
|
|
57
|
+
"Options": {
|
|
58
|
+
// Locked subtrees: an undeclared package HERE is a failure. Everywhere else it is
|
|
59
|
+
// skipped. This is the shape a real migration takes — one tree cleaned and held, the
|
|
60
|
+
// rest still being worked through.
|
|
61
|
+
"requireDeclaredIn": ["packages/Angular"]
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
A check absent from `Checks` does not run. A check present but `off` does not run and is not
|
|
69
|
+
nagged about — the repo has seen it and said no.
|
|
70
|
+
|
|
71
|
+
## Commands
|
|
72
|
+
|
|
73
|
+
### `adopt`
|
|
74
|
+
|
|
75
|
+
Writes the config, and optionally a CI workflow, an npm script, and the per-package declarations.
|
|
76
|
+
**Idempotent and additive**: it never lowers a severity you raised, never overwrites a CI file you
|
|
77
|
+
edited, and never bumps `StandardsVersion` without `--upgrade`.
|
|
78
|
+
|
|
79
|
+
| Flag | |
|
|
80
|
+
|---|---|
|
|
81
|
+
| `--ci github` | write `.github/workflows/mj-standards.yml` |
|
|
82
|
+
| `--declare-compliant` | declare `mjUILayer` on packages that already pass |
|
|
83
|
+
| `--upgrade` | enable standards newer than the recorded version, and bump it |
|
|
84
|
+
| `--dry-run` | report, write nothing |
|
|
85
|
+
|
|
86
|
+
**`--declare-compliant` matters more than it looks.** Without it, a fresh adoption produces a
|
|
87
|
+
config that enforces nothing: every package is undeclared, so every package is skipped, and the
|
|
88
|
+
repo gets a green check that means nothing.
|
|
89
|
+
|
|
90
|
+
It takes the **strictest** layer each package honestly qualifies for and **never assigns `shell`**.
|
|
91
|
+
`shell` checks nothing, so every package passes as `shell` — assigning it would hand a permanent
|
|
92
|
+
exemption to exactly the packages that need work. (An earlier version did assign it; a two-package
|
|
93
|
+
test repo caught it in the first run, with the deliberately-broken package coming back declared
|
|
94
|
+
`shell` and passing.) A package that qualifies for nothing is reported, not declared.
|
|
95
|
+
|
|
96
|
+
### `check`
|
|
97
|
+
|
|
98
|
+
Runs the adopted standards. Exit 1 on `error` violations only; `--strict` also fails on warnings —
|
|
99
|
+
the flag to turn on once a newly adopted check is clean.
|
|
100
|
+
|
|
101
|
+
### `list`
|
|
102
|
+
|
|
103
|
+
Every registered standard, when it was introduced, and what this repo does with it.
|
|
104
|
+
|
|
105
|
+
## The standards
|
|
106
|
+
|
|
107
|
+
| Id | Since | What it enforces |
|
|
108
|
+
|---|---|---|
|
|
109
|
+
| `ui-layers` | 6.0.0 | The four-layer UI architecture — [guide](https://github.com/MemberJunction/MJ/blob/next/guides/UI_LAYERING_GUIDE.md). Widgets may not import `@angular/router` or MJ Explorer, and may not construct a global-provider `RunView`/`Metadata`. Packages opt in with `"mjUILayer"` in their own `package.json`. |
|
|
110
|
+
|
|
111
|
+
## Adding a standard
|
|
44
112
|
|
|
45
|
-
|
|
113
|
+
1. Implement `StandardCheck` in `src/checks/`.
|
|
114
|
+
2. Set `Since` to the MJ version it will **ship in**. Never backdate it — that would silently
|
|
115
|
+
activate the check in repos that adopted before it existed.
|
|
116
|
+
3. Register it in `src/registry.ts`.
|
|
117
|
+
4. Give it a `DocsUrl`. Every failure prints it; a rule whose reasoning is one click away gets
|
|
118
|
+
followed, and one that just says "no" gets worked around.
|
|
119
|
+
5. Consider shipping it at `DefaultSeverity: 'warn'` first if it is likely to have a long tail.
|
|
120
|
+
|
|
121
|
+
## Design notes
|
|
122
|
+
|
|
123
|
+
**No runtime dependencies.** This gets installed into client repos and run in CI; every dependency
|
|
124
|
+
is one more thing that can conflict with their tree. The only non-trivial thing it needed was
|
|
125
|
+
semver comparison, which is twenty lines.
|
|
126
|
+
|
|
127
|
+
**Comments are stripped before matching.** MJ source documents itself heavily — a JSDoc block
|
|
128
|
+
explaining "this calls `new RunView()` on the global provider" is a comment about a violation, not
|
|
129
|
+
a violation. A gate that cannot tell the difference gets switched off.
|
|
130
|
+
|
|
131
|
+
**Only zero-argument constructors are flagged.** `new RunView(provider)` passes a provider
|
|
132
|
+
explicitly and is correct. An earlier, blunter pattern flagged it; false positives are how a gate
|
|
133
|
+
loses its authority.
|
|
134
|
+
|
|
135
|
+
**Reviewed exceptions** use a marker in a comment on the offending line, or the line directly
|
|
136
|
+
above it — one line, so a marker cannot drift away from what it excuses. For `ui-layers` the marker
|
|
137
|
+
is `mj-ui-layers-allow`.
|
package/bin/run.js
ADDED
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* `mj-standards` — the standards runner, without the MJ CLI.
|
|
4
|
+
*
|
|
5
|
+
* Client and external repos should not have to install the whole MemberJunction CLI to run four
|
|
6
|
+
* checks in CI. This binary is the same code the `mj standards` commands call, exposed directly:
|
|
7
|
+
*
|
|
8
|
+
* npx mj-standards check
|
|
9
|
+
* npx mj-standards adopt --ci github --declare-compliant
|
|
10
|
+
* npx mj-standards list
|
|
11
|
+
*
|
|
12
|
+
* Argument handling is deliberately minimal — anyone who wants rich flags can install the CLI.
|
|
13
|
+
*/
|
|
14
|
+
import { LoadConfig, HasConfig, RunStandards, FormatSummary, ExitCodeFor, Adopt, STANDARD_CHECKS, IsNewerThan } from '../dist/index.js';
|
|
15
|
+
import { readFileSync } from 'node:fs';
|
|
16
|
+
import { dirname, join } from 'node:path';
|
|
17
|
+
import { fileURLToPath } from 'node:url';
|
|
18
|
+
|
|
19
|
+
const argv = process.argv.slice(2);
|
|
20
|
+
const command = argv[0] ?? 'check';
|
|
21
|
+
const repoRoot = process.cwd();
|
|
22
|
+
const flag = (name) => argv.includes(`--${name}`);
|
|
23
|
+
const value = (name) => {
|
|
24
|
+
const i = argv.indexOf(`--${name}`);
|
|
25
|
+
return i !== -1 ? argv[i + 1] : undefined;
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
const ownVersion = JSON.parse(
|
|
29
|
+
readFileSync(join(dirname(fileURLToPath(import.meta.url)), '..', 'package.json'), 'utf8'),
|
|
30
|
+
).version;
|
|
31
|
+
|
|
32
|
+
function usage() {
|
|
33
|
+
console.log(`mj-standards <check|adopt|list> [options]
|
|
34
|
+
|
|
35
|
+
check run the standards this repo has adopted
|
|
36
|
+
--strict treat warnings as errors
|
|
37
|
+
--quiet summary line only
|
|
38
|
+
|
|
39
|
+
adopt write .mj-standards.json and optional scaffolding
|
|
40
|
+
--ci github also write a GitHub Actions workflow
|
|
41
|
+
--declare-compliant declare mjUILayer on packages that already pass
|
|
42
|
+
--upgrade enable standards newer than the repo's recorded version
|
|
43
|
+
--dry-run report, write nothing
|
|
44
|
+
|
|
45
|
+
list every standard, and this repo's stance on each`);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
if (flag('help') || command === 'help') {
|
|
49
|
+
usage();
|
|
50
|
+
process.exit(0);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
if (command === 'check') {
|
|
54
|
+
if (!HasConfig(repoRoot)) {
|
|
55
|
+
console.error('No .mj-standards.json here. Run `npx mj-standards adopt` first.');
|
|
56
|
+
process.exit(2);
|
|
57
|
+
}
|
|
58
|
+
const config = LoadConfig(repoRoot);
|
|
59
|
+
const summary = await RunStandards(repoRoot, config);
|
|
60
|
+
if (!flag('quiet')) console.log(FormatSummary(summary, config));
|
|
61
|
+
const failed = ExitCodeFor(summary) !== 0 || (flag('strict') && summary.WarningCount > 0);
|
|
62
|
+
process.exit(failed ? 1 : 0);
|
|
63
|
+
} else if (command === 'adopt') {
|
|
64
|
+
const result = Adopt({
|
|
65
|
+
RepoRoot: repoRoot,
|
|
66
|
+
Version: value('version') ?? ownVersion,
|
|
67
|
+
Upgrade: flag('upgrade'),
|
|
68
|
+
DryRun: flag('dry-run'),
|
|
69
|
+
Ci: value('ci') === 'github' ? 'github' : 'none',
|
|
70
|
+
AddNpmScript: !flag('no-npm-script'),
|
|
71
|
+
DeclareCompliant: flag('declare-compliant'),
|
|
72
|
+
});
|
|
73
|
+
const icon = { created: '+', updated: '~', skipped: '·' };
|
|
74
|
+
for (const a of result.Actions) console.log(`${icon[a.Kind]} ${a.What}${a.Detail ? ` — ${a.Detail}` : ''}`);
|
|
75
|
+
console.log(flag('dry-run') ? '\nDry run — nothing was written.' : `\nAdopted at StandardsVersion ${result.Config.StandardsVersion}.`);
|
|
76
|
+
} else if (command === 'list') {
|
|
77
|
+
const config = HasConfig(repoRoot) ? LoadConfig(repoRoot) : null;
|
|
78
|
+
for (const check of STANDARD_CHECKS) {
|
|
79
|
+
const entry = config?.Checks[check.Id];
|
|
80
|
+
const stance = !config
|
|
81
|
+
? 'not adopted'
|
|
82
|
+
: entry
|
|
83
|
+
? entry.Severity
|
|
84
|
+
: IsNewerThan(check.Since, config.StandardsVersion)
|
|
85
|
+
? `available (added in ${check.Since}, after this repo adopted)`
|
|
86
|
+
: 'available, not adopted';
|
|
87
|
+
console.log(`${check.Id} [${stance}] since ${check.Since}\n ${check.Title}\n`);
|
|
88
|
+
}
|
|
89
|
+
} else {
|
|
90
|
+
usage();
|
|
91
|
+
process.exit(2);
|
|
92
|
+
}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview The UI layering standard.
|
|
3
|
+
*
|
|
4
|
+
* Enforces the boundaries in the MJ repo's `guides/UI_LAYERING_GUIDE.md`:
|
|
5
|
+
*
|
|
6
|
+
* runtime (L0) pure TS — no Angular at all
|
|
7
|
+
* widgets (L1+L2) framework-clean Angular — no Router, no Explorer, no global provider
|
|
8
|
+
* surface (L3) Explorer surfaces — NavigationService only, never Router
|
|
9
|
+
* shell the navigation layer ITSELF — the documented Router exception
|
|
10
|
+
*
|
|
11
|
+
* A package opts in by declaring `"mjUILayer"` in its own package.json. A package without the
|
|
12
|
+
* field is skipped, unless `requireDeclared` is on — see the option's docs for why that matters.
|
|
13
|
+
*
|
|
14
|
+
* @module @memberjunction/standards
|
|
15
|
+
*/
|
|
16
|
+
import type { StandardCheck } from '../types.js';
|
|
17
|
+
/** The layers a package can declare. */
|
|
18
|
+
export type UILayer = 'runtime' | 'widgets' | 'surface' | 'shell';
|
|
19
|
+
/**
|
|
20
|
+
* Blank out `//` and block comments, preserving every newline so line numbers still line up.
|
|
21
|
+
*
|
|
22
|
+
* Necessary because MJ source documents itself heavily: a JSDoc block explaining "this calls
|
|
23
|
+
* `new RunView()` on the global provider" is a comment about a violation, not a violation, and a
|
|
24
|
+
* gate that cannot tell the difference gets switched off. String literals are left alone — the
|
|
25
|
+
* banned constructs do not plausibly appear in one.
|
|
26
|
+
*/
|
|
27
|
+
export declare function StripComments(source: string): string;
|
|
28
|
+
/** One import/export-from occurrence. */
|
|
29
|
+
export interface ImportRecord {
|
|
30
|
+
Specifier: string;
|
|
31
|
+
Names: string[];
|
|
32
|
+
Line: number;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Extract every import/export-from specifier with the names it binds and its 1-based line.
|
|
36
|
+
*
|
|
37
|
+
* Import-aware rather than grep-based: matching the bare word `Router` anywhere produces false
|
|
38
|
+
* positives on `RouterLikeThing`, on comments and on strings. What matters is whether the module
|
|
39
|
+
* *binds* the symbol.
|
|
40
|
+
*/
|
|
41
|
+
export declare function ParseImports(source: string): ImportRecord[];
|
|
42
|
+
/**
|
|
43
|
+
* Does the given 1-based line carry a reviewed-exception marker, on itself or the line above?
|
|
44
|
+
*
|
|
45
|
+
* The preceding line counts because a real exception deserves a sentence of explanation and a
|
|
46
|
+
* trailing comment long enough to hold one is unreadable. Only ONE line above — a wider window
|
|
47
|
+
* would let a marker drift away from the thing it excuses.
|
|
48
|
+
*/
|
|
49
|
+
export declare function IsAllowed(lines: string[], lineNumber: number): boolean;
|
|
50
|
+
/** The registered UI layering standard. */
|
|
51
|
+
export declare const UILayersCheck: StandardCheck;
|
|
52
|
+
/** A package that has not yet declared a layer, and whether it would pass if it did. */
|
|
53
|
+
export interface UndeclaredPackage {
|
|
54
|
+
/** Absolute directory. */
|
|
55
|
+
Dir: string;
|
|
56
|
+
Name: string;
|
|
57
|
+
/**
|
|
58
|
+
* Layers this package could honestly claim, strictest-first, never including `shell`.
|
|
59
|
+
* Empty means it needs work before it can be declared at all.
|
|
60
|
+
*/
|
|
61
|
+
WouldPassAs: UILayer[];
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Find packages with no `mjUILayer` and work out which layers they could honestly claim.
|
|
65
|
+
*
|
|
66
|
+
* This is what lets `mj standards adopt` declare the already-compliant packages instead of leaving
|
|
67
|
+
* a repo with a config that enforces nothing. It answers the question by **running the rules**
|
|
68
|
+
* against a hypothetical layer, not by editing anything — probing by writing a field to
|
|
69
|
+
* package.json and reverting it would be a data-loss bug waiting for an interrupted process.
|
|
70
|
+
*
|
|
71
|
+
* `WouldPassAs` is ordered strictest-first and never contains `shell`, so a caller taking
|
|
72
|
+
* `WouldPassAs[0]` gets the most informative honest label, and a package that passes nothing comes
|
|
73
|
+
* back with an empty array — "needs work", not "call it shell".
|
|
74
|
+
*/
|
|
75
|
+
export declare function ProbeUndeclaredPackages(repoRoot: string, roots: string[]): UndeclaredPackage[];
|
|
76
|
+
/** Write `mjUILayer` into a package's manifest, preserving formatting as best as JSON allows. */
|
|
77
|
+
export declare function DeclareLayer(packageDir: string, layer: UILayer): void;
|
|
78
|
+
//# sourceMappingURL=ui-layers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ui-layers.d.ts","sourceRoot":"","sources":["../../src/checks/ui-layers.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAIH,OAAO,KAAK,EAA6B,aAAa,EAAa,MAAM,aAAa,CAAC;AAEvF,wCAAwC;AACxC,MAAM,MAAM,OAAO,GAAG,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,CAAC;AA6ElE;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAqBpD;AAED,yCAAyC;AACzC,MAAM,WAAW,YAAY;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,YAAY,EAAE,CAoB3D;AAED;;;;;;GAMG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAItE;AAiID,2CAA2C;AAC3C,eAAO,MAAM,aAAa,EAAE,aA2F3B,CAAC;AAMF,wFAAwF;AACxF,MAAM,WAAW,iBAAiB;IAC9B,0BAA0B;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb;;;OAGG;IACH,WAAW,EAAE,OAAO,EAAE,CAAC;CAC1B;AAYD;;;;;;;;;;;GAWG;AACH,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,iBAAiB,EAAE,CAa9F;AAED,iGAAiG;AACjG,wBAAgB,YAAY,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI,CAKrE"}
|