@mmnto/totem 2.12.3 → 2.14.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.
Files changed (50) hide show
  1. package/dist/artifacts/legs.d.ts +36 -0
  2. package/dist/artifacts/legs.d.ts.map +1 -1
  3. package/dist/artifacts/legs.js +72 -0
  4. package/dist/artifacts/legs.js.map +1 -1
  5. package/dist/artifacts/legs.test.js +60 -1
  6. package/dist/artifacts/legs.test.js.map +1 -1
  7. package/dist/cli-resolve.d.ts +116 -0
  8. package/dist/cli-resolve.d.ts.map +1 -0
  9. package/dist/cli-resolve.js +248 -0
  10. package/dist/cli-resolve.js.map +1 -0
  11. package/dist/cli-resolve.test.d.ts +2 -0
  12. package/dist/cli-resolve.test.d.ts.map +1 -0
  13. package/dist/cli-resolve.test.js +328 -0
  14. package/dist/cli-resolve.test.js.map +1 -0
  15. package/dist/config-schema.d.ts +34 -0
  16. package/dist/config-schema.d.ts.map +1 -1
  17. package/dist/config-schema.js +20 -0
  18. package/dist/config-schema.js.map +1 -1
  19. package/dist/config-schema.test.js +55 -0
  20. package/dist/config-schema.test.js.map +1 -1
  21. package/dist/errors.d.ts +39 -1
  22. package/dist/errors.d.ts.map +1 -1
  23. package/dist/errors.js +42 -0
  24. package/dist/errors.js.map +1 -1
  25. package/dist/index.d.ts +8 -5
  26. package/dist/index.d.ts.map +1 -1
  27. package/dist/index.js +4 -3
  28. package/dist/index.js.map +1 -1
  29. package/dist/ingest/pipeline.js +3 -1
  30. package/dist/ingest/pipeline.js.map +1 -1
  31. package/dist/ingest/pipeline.test.js +23 -0
  32. package/dist/ingest/pipeline.test.js.map +1 -1
  33. package/dist/ledger.d.ts +4 -4
  34. package/dist/spine/authored-rule.d.ts +225 -4
  35. package/dist/spine/authored-rule.d.ts.map +1 -1
  36. package/dist/spine/authored-rule.js +147 -10
  37. package/dist/spine/authored-rule.js.map +1 -1
  38. package/dist/spine/authored-rule.test.js +196 -2
  39. package/dist/spine/authored-rule.test.js.map +1 -1
  40. package/dist/spine/authoring-ledger.d.ts +90 -1
  41. package/dist/spine/authoring-ledger.d.ts.map +1 -1
  42. package/dist/spine/authoring-ledger.test.js +3 -3
  43. package/dist/spine/authoring-ledger.test.js.map +1 -1
  44. package/dist/store/lance-store.d.ts +43 -7
  45. package/dist/store/lance-store.d.ts.map +1 -1
  46. package/dist/store/lance-store.js +70 -13
  47. package/dist/store/lance-store.js.map +1 -1
  48. package/dist/store/lance-store.test.js +92 -2
  49. package/dist/store/lance-store.test.js.map +1 -1
  50. package/package.json +5 -1
@@ -0,0 +1,248 @@
1
+ /**
2
+ * Resolve Totem's own CLI entry explicitly (mmnto-ai/totem#3008).
3
+ *
4
+ * One resolver for every caller that must run "the Totem CLI": the CLI's
5
+ * prefer-local re-exec (`resolveLocalEntry`) and the MCP server's spawning
6
+ * tools (`resolveTotemCli`). Tiers, first hit wins:
7
+ *
8
+ * 1. **Workspace build** — `packages/cli/dist/index.js`, identity-guarded on
9
+ * `packages/cli/package.json` naming `@mmnto/cli`, walking up.
10
+ * 2. **Pinned install** — `node_modules/@mmnto/cli/dist/index.js`, walking up.
11
+ * 3. **npm-layout global on PATH** — the two npm global layouts only.
12
+ *
13
+ * Otherwise a refusal that names what was looked for.
14
+ *
15
+ * **Identity is the install path.** An install that sits at
16
+ * `node_modules/@mmnto/cli` is ours by the package manager's own namespace,
17
+ * whatever its manifest is called, so a fork installed under that alias runs
18
+ * here as it does in the CLI's re-exec and the git hooks, and the result
19
+ * carries its real name (`aliasOf`). Where there is no such path, the
20
+ * manifest's name decides: the workspace build (`packages/cli`), and a global
21
+ * whose `totem` link resolves outside `node_modules` (a linked development
22
+ * install). A bare `totem` name is never the identity.
23
+ *
24
+ * These tiers differ on purpose from the git hooks' cascade
25
+ * (`buildResolveBlock` in the CLI's install-hooks): a spawn inside a tool call
26
+ * runs unattended, with nobody at a terminal to see what was fetched or run,
27
+ * so it stops at a local entry or an npm-layout global and never falls back to
28
+ * a package manager or the network.
29
+ *
30
+ * Light by contract: imports only `node:fs` and `node:path`, so it is also
31
+ * exported as the `@mmnto/totem/cli-resolve` subpath for callers that must
32
+ * not load the core barrel.
33
+ */
34
+ import * as fs from 'node:fs';
35
+ import * as path from 'node:path';
36
+ const VERSION_RE = /"version"\s*:\s*"([^"]+)"/;
37
+ const NAME_IS_CLI_RE = /"name"\s*:\s*"@mmnto\/cli"/;
38
+ const PACKAGES_DIR = 'packages';
39
+ const DIST_DIR = 'dist';
40
+ const NODE_MODULES_DIR = 'node_modules';
41
+ const ENTRY_FILE = 'index.js';
42
+ const PACKAGE_JSON = 'package.json';
43
+ const CLI_PACKAGE = 'cli';
44
+ const SCOPE_DIR = '@mmnto';
45
+ const CLI_NAME = '@mmnto/cli';
46
+ const BIN_NAME = 'totem';
47
+ /** The path tail that identifies an install of the CLI under a `node_modules` directory. */
48
+ const ENTRY_TAIL = [
49
+ NODE_MODULES_DIR,
50
+ SCOPE_DIR,
51
+ CLI_PACKAGE,
52
+ DIST_DIR,
53
+ ENTRY_FILE,
54
+ ];
55
+ /** Executable names a non-npm-layout `totem` may carry on PATH (reported, never run). */
56
+ const BIN_VARIANTS = [
57
+ BIN_NAME,
58
+ `${BIN_NAME}.cmd`,
59
+ `${BIN_NAME}.exe`,
60
+ `${BIN_NAME}.ps1`,
61
+ ];
62
+ export const NODE_CLI_RESOLVE_FS = {
63
+ exists: (p) => fs.existsSync(p),
64
+ isFile: (p) => fs.statSync(p).isFile(),
65
+ readText: (p) => fs.readFileSync(p, 'utf-8'),
66
+ realpath: (p) => fs.realpathSync(p),
67
+ };
68
+ /** Probe-grade version read — no JSON.parse, no fail-open catch. */
69
+ function readVersion(pkgJsonPath, fsx) {
70
+ if (!fsx.exists(pkgJsonPath))
71
+ return undefined;
72
+ return VERSION_RE.exec(fsx.readText(pkgJsonPath))?.[1];
73
+ }
74
+ /** True when `pkgJsonPath` exists and names `@mmnto/cli`. */
75
+ function namesCli(pkgJsonPath, fsx) {
76
+ return fsx.exists(pkgJsonPath) && NAME_IS_CLI_RE.test(fsx.readText(pkgJsonPath));
77
+ }
78
+ /**
79
+ * Resolve the project-local CLI entry by walking up from `cwd`:
80
+ *
81
+ * 1. **Workspace-HEAD** — `packages/cli/dist/index.js`, identity-guarded on
82
+ * `packages/cli/package.json` declaring `@mmnto/cli` (the dogfood monorepo;
83
+ * the build you just made wins over any installed copy).
84
+ * 2. **Pinned dependency** — `node_modules/@mmnto/cli/dist/index.js`, the
85
+ * project's version-locked install via the package's own entry point.
86
+ *
87
+ * Both tiers require the BUILT entry to exist. A read failure mid-walk throws;
88
+ * the caller decides the posture.
89
+ */
90
+ export function resolveLocalEntry(cwd, fsx = NODE_CLI_RESOLVE_FS) {
91
+ let dir = path.resolve(cwd);
92
+ for (;;) {
93
+ const workspacePkg = path.join(dir, PACKAGES_DIR, CLI_PACKAGE, PACKAGE_JSON);
94
+ const workspaceEntry = path.join(dir, PACKAGES_DIR, CLI_PACKAGE, DIST_DIR, ENTRY_FILE);
95
+ if (fsx.exists(workspaceEntry) && namesCli(workspacePkg, fsx)) {
96
+ return { entry: workspaceEntry, version: readVersion(workspacePkg, fsx), tier: 'workspace' };
97
+ }
98
+ const pinnedDir = path.join(dir, NODE_MODULES_DIR, SCOPE_DIR, CLI_PACKAGE);
99
+ const pinnedEntry = path.join(pinnedDir, DIST_DIR, ENTRY_FILE);
100
+ if (fsx.exists(pinnedEntry)) {
101
+ return {
102
+ entry: pinnedEntry,
103
+ version: readVersion(path.join(pinnedDir, PACKAGE_JSON), fsx),
104
+ tier: 'pinned',
105
+ };
106
+ }
107
+ const parent = path.dirname(dir);
108
+ if (parent === dir)
109
+ return undefined;
110
+ dir = parent;
111
+ }
112
+ }
113
+ /**
114
+ * Run one filesystem probe of the PATH scan; undefined when it throws. The
115
+ * global tier never throws: a PATH directory with a dangling link, an
116
+ * unreadable `package.json` or an unreadable entry is "not a hit" there, and
117
+ * the scan moves on to the next directory. The local walk does not use this:
118
+ * a read failure mid-walk throws, as it always has.
119
+ */
120
+ function attempt(probe) {
121
+ // totem-context: intentional probe — the catch below does not rethrow by
122
+ // design (mmnto-ai/totem#3008): one unreadable PATH directory must not stop
123
+ // the scan before a valid install later on PATH is tried.
124
+ try {
125
+ return probe();
126
+ // totem-context: intentional degradation — see directive above the try; placed on the line before the catch keyword, where the rule reads it.
127
+ }
128
+ catch {
129
+ return undefined;
130
+ }
131
+ }
132
+ /** The manifest's TOP-LEVEL `name`; undefined when it is absent, unreadable or not JSON. Never throws. */
133
+ function manifestName(pkgJsonPath, fsx) {
134
+ if (!fsx.exists(pkgJsonPath))
135
+ return undefined;
136
+ const parsed = attempt(() => JSON.parse(fsx.readText(pkgJsonPath)));
137
+ if (typeof parsed !== 'object' || parsed === null)
138
+ return undefined;
139
+ const name = parsed.name;
140
+ return typeof name === 'string' ? name : undefined;
141
+ }
142
+ /** The manifest's own name when it is readable and is not `@mmnto/cli` (a fork under the alias). */
143
+ function aliasOf(pkgJsonPath, fsx) {
144
+ const name = manifestName(pkgJsonPath, fsx);
145
+ return name !== undefined && name !== CLI_NAME ? name : undefined;
146
+ }
147
+ /** True when `entry` sits at `…/node_modules/@mmnto/cli/dist/index.js`: the install path is the identity. */
148
+ function sitsAtCliPath(entry) {
149
+ const tail = entry.split(/[\\/]/).slice(-ENTRY_TAIL.length);
150
+ return tail.length === ENTRY_TAIL.length && tail.every((part, i) => part === ENTRY_TAIL[i]);
151
+ }
152
+ /** True when a `totem` FILE (any of the shim names) sits in `dir`. Never throws. */
153
+ function findShim(dir, fsx) {
154
+ for (const name of BIN_VARIANTS) {
155
+ const candidate = path.join(dir, name);
156
+ if (fsx.exists(candidate) && attempt(() => fsx.isFile(candidate)) === true)
157
+ return candidate;
158
+ }
159
+ return undefined;
160
+ }
161
+ function globalEntry(entry, pkgJsonPath, fsx) {
162
+ const alias = aliasOf(pkgJsonPath, fsx);
163
+ return {
164
+ entry,
165
+ version: attempt(() => readVersion(pkgJsonPath, fsx)),
166
+ tier: 'global',
167
+ ...(alias !== undefined ? { aliasOf: alias } : {}),
168
+ };
169
+ }
170
+ /** A global hit in one PATH directory, by the two npm layouts, or undefined. Never throws. */
171
+ function probeGlobalDir(dir, fsx) {
172
+ // (a) The win32 npm layout: the `totem` shim sits beside `node_modules`, and
173
+ // the install is `<prefix>/node_modules/@mmnto/cli`. Identity is that path,
174
+ // so a fork installed under the alias is a hit. A directory that holds the
175
+ // package but no shim is not a global install: nothing a shell would run.
176
+ const packagedDir = path.join(dir, NODE_MODULES_DIR, SCOPE_DIR, CLI_PACKAGE);
177
+ const packagedEntry = path.join(packagedDir, DIST_DIR, ENTRY_FILE);
178
+ if (fsx.exists(packagedEntry) && findShim(dir, fsx) !== undefined) {
179
+ return globalEntry(packagedEntry, path.join(packagedDir, PACKAGE_JSON), fsx);
180
+ }
181
+ // (b) The POSIX npm layout: `<bin>/totem` is a symlink to `<pkg>/dist/index.js`.
182
+ // Ours when the resolved entry sits at `node_modules/@mmnto/cli` (the path),
183
+ // or, where the link resolves elsewhere (a linked development install), when
184
+ // the manifest's top-level name is `@mmnto/cli`.
185
+ const shim = path.join(dir, BIN_NAME);
186
+ if (!fsx.exists(shim))
187
+ return undefined;
188
+ const real = attempt(() => fsx.realpath(shim));
189
+ if (real === undefined || !real.endsWith('.js') || !fsx.exists(real))
190
+ return undefined;
191
+ const realPkg = path.join(path.dirname(path.dirname(real)), PACKAGE_JSON);
192
+ if (!sitsAtCliPath(real) && manifestName(realPkg, fsx) !== CLI_NAME)
193
+ return undefined;
194
+ return globalEntry(real, realPkg, fsx);
195
+ }
196
+ /**
197
+ * Find an npm-layout global install of `@mmnto/cli` on PATH, first hit wins.
198
+ * A `totem` FILE (a directory of that name is not one) found in a directory
199
+ * that yields no hit is reported in `unverified` and never run. Never throws.
200
+ */
201
+ export function resolveGlobalEntry(pathEnv, fsx = NODE_CLI_RESOLVE_FS) {
202
+ const unverified = [];
203
+ for (const dir of (pathEnv ?? '').split(path.delimiter)) {
204
+ if (!dir)
205
+ continue;
206
+ const hit = probeGlobalDir(dir, fsx);
207
+ if (hit !== undefined)
208
+ return { hit, unverified };
209
+ const shim = findShim(dir, fsx);
210
+ if (shim !== undefined)
211
+ unverified.push(shim);
212
+ }
213
+ return { unverified };
214
+ }
215
+ /**
216
+ * Resolve the Totem CLI for an unattended spawn: the workspace build, then the
217
+ * pinned install (both walking up from `startDir`), then an npm-layout global
218
+ * on PATH. Otherwise `{ ok: false }` with the places looked and any `totem`
219
+ * found on PATH that could not be verified.
220
+ */
221
+ export function resolveTotemCli(startDir, opts) {
222
+ const fsx = opts?.fs ?? NODE_CLI_RESOLVE_FS;
223
+ const local = resolveLocalEntry(startDir, fsx);
224
+ if (local !== undefined) {
225
+ // The pinned tier is identified by its path under `node_modules`, so a fork
226
+ // installed under the alias runs; its manifest's own name rides along.
227
+ const alias = local.tier === 'pinned'
228
+ ? aliasOf(path.join(path.dirname(path.dirname(local.entry)), PACKAGE_JSON), fsx)
229
+ : undefined;
230
+ return alias !== undefined ? { ok: true, ...local, aliasOf: alias } : { ok: true, ...local };
231
+ }
232
+ const globalProbe = resolveGlobalEntry(opts?.pathEnv ?? process.env.PATH, fsx);
233
+ if (globalProbe.hit !== undefined) {
234
+ return globalProbe.unverified.length > 0
235
+ ? { ok: true, ...globalProbe.hit, unverified: globalProbe.unverified }
236
+ : { ok: true, ...globalProbe.hit };
237
+ }
238
+ return {
239
+ ok: false,
240
+ looked: [
241
+ `a workspace build at packages/cli/dist/index.js, walking up from ${startDir}`,
242
+ `a pinned install at node_modules/@mmnto/cli/dist/index.js, walking up from ${startDir}`,
243
+ 'an npm-layout global install of @mmnto/cli on PATH',
244
+ ],
245
+ unverified: globalProbe.unverified,
246
+ };
247
+ }
248
+ //# sourceMappingURL=cli-resolve.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli-resolve.js","sourceRoot":"","sources":["../src/cli-resolve.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=cli-resolve.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli-resolve.test.d.ts","sourceRoot":"","sources":["../src/cli-resolve.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,328 @@
1
+ import * as fs from 'node:fs';
2
+ import * as os from 'node:os';
3
+ import * as path from 'node:path';
4
+ import { afterEach, beforeEach, describe, expect, it } from 'vitest';
5
+ import { resolveGlobalEntry, resolveLocalEntry, resolveTotemCli } from './cli-resolve.js';
6
+ function writeWorkspaceTier(root, name = '@mmnto/cli') {
7
+ fs.mkdirSync(path.join(root, 'packages', 'cli', 'dist'), { recursive: true });
8
+ fs.writeFileSync(path.join(root, 'packages', 'cli', 'package.json'), `{"name":"${name}","version":"9.9.9"}`);
9
+ const entry = path.join(root, 'packages', 'cli', 'dist', 'index.js');
10
+ fs.writeFileSync(entry, '');
11
+ return entry;
12
+ }
13
+ function writePinnedTier(root) {
14
+ const pkgDir = path.join(root, 'node_modules', '@mmnto', 'cli');
15
+ fs.mkdirSync(path.join(pkgDir, 'dist'), { recursive: true });
16
+ fs.writeFileSync(path.join(pkgDir, 'package.json'), '{"name":"@mmnto/cli","version":"8.8.8"}');
17
+ const entry = path.join(pkgDir, 'dist', 'index.js');
18
+ fs.writeFileSync(entry, '');
19
+ return entry;
20
+ }
21
+ /**
22
+ * An in-memory filesystem seam: `files` maps a path to its text, `links` maps
23
+ * a link path to its realpath target. A link counts as existing. `dirs` exist
24
+ * and are not files; `unreadable` paths exist as files whose read throws.
25
+ */
26
+ function fakeFs(files, links = {}, extra = {}) {
27
+ const dirs = new Set(extra.dirs ?? []);
28
+ const unreadable = new Set(extra.unreadable ?? []);
29
+ return {
30
+ exists: (p) => p in files || p in links || dirs.has(p) || unreadable.has(p),
31
+ isFile: (p) => p in files || p in links || unreadable.has(p),
32
+ readText: (p) => {
33
+ if (unreadable.has(p))
34
+ throw new Error(`EACCES: permission denied, open ${p}`);
35
+ const text = files[p];
36
+ if (text === undefined)
37
+ throw new Error(`ENOENT: ${p}`);
38
+ return text;
39
+ },
40
+ realpath: (p) => {
41
+ const target = links[p];
42
+ if (target === undefined)
43
+ throw new Error(`EINVAL: not a link: ${p}`);
44
+ return target;
45
+ },
46
+ };
47
+ }
48
+ const CLI_PKG = '{"name":"@mmnto/cli","version":"7.7.7"}';
49
+ const OTHER_PKG = '{"name":"totem","version":"5.2.0"}';
50
+ const FORK_PKG = '{"name":"@acme/cli","version":"2.13.0-acme.1"}';
51
+ const NESTED_PKG = '{"name":"someone-else","config":{"name":"@mmnto/cli"},"version":"1.0.0"}';
52
+ describe('resolveLocalEntry (moved from the CLI re-exec; mmnto-ai/totem#3008)', () => {
53
+ let tmpRoot;
54
+ beforeEach(() => {
55
+ tmpRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'totem-cli-resolve-'));
56
+ });
57
+ afterEach(() => {
58
+ fs.rmSync(tmpRoot, { recursive: true, force: true });
59
+ });
60
+ it('workspace tier: resolves the workspace build, identity-guarded on the package name', () => {
61
+ const entry = writeWorkspaceTier(tmpRoot);
62
+ expect(resolveLocalEntry(tmpRoot)).toEqual({ entry, version: '9.9.9', tier: 'workspace' });
63
+ });
64
+ it('workspace guard: a packages/cli/package.json naming another package does not match', () => {
65
+ writeWorkspaceTier(tmpRoot, 'someone-elses-cli');
66
+ expect(resolveLocalEntry(tmpRoot)).toBeUndefined();
67
+ });
68
+ it('workspace tier requires the built entry — package.json alone is not enough', () => {
69
+ writeWorkspaceTier(tmpRoot);
70
+ fs.rmSync(path.join(tmpRoot, 'packages', 'cli', 'dist', 'index.js'));
71
+ expect(resolveLocalEntry(tmpRoot)).toBeUndefined();
72
+ });
73
+ it('pinned tier: resolves the pinned @mmnto/cli entry', () => {
74
+ const entry = writePinnedTier(tmpRoot);
75
+ expect(resolveLocalEntry(tmpRoot)).toEqual({ entry, version: '8.8.8', tier: 'pinned' });
76
+ });
77
+ it('a node_modules/totem/ directory does not match', () => {
78
+ const foreign = path.join(tmpRoot, 'node_modules', 'totem');
79
+ fs.mkdirSync(path.join(foreign, 'dist'), { recursive: true });
80
+ fs.writeFileSync(path.join(foreign, 'package.json'), OTHER_PKG);
81
+ fs.writeFileSync(path.join(foreign, 'dist', 'index.js'), '');
82
+ expect(resolveLocalEntry(tmpRoot)).toBeUndefined();
83
+ });
84
+ it('the workspace tier beats the pinned tier when both are present', () => {
85
+ const workspaceEntry = writeWorkspaceTier(tmpRoot);
86
+ writePinnedTier(tmpRoot);
87
+ expect(resolveLocalEntry(tmpRoot)?.entry).toBe(workspaceEntry);
88
+ });
89
+ it('walks up from a nested directory', () => {
90
+ const entry = writePinnedTier(tmpRoot);
91
+ const nested = path.join(tmpRoot, 'src', 'deep');
92
+ fs.mkdirSync(nested, { recursive: true });
93
+ expect(resolveLocalEntry(nested)?.entry).toBe(entry);
94
+ });
95
+ it('no local install anywhere → undefined', () => {
96
+ expect(resolveLocalEntry(tmpRoot)).toBeUndefined();
97
+ });
98
+ it('a read failure mid-walk throws; the caller decides the posture', () => {
99
+ // packages/cli/package.json as a DIRECTORY: exists passes, the read throws EISDIR.
100
+ fs.mkdirSync(path.join(tmpRoot, 'packages', 'cli', 'dist'), { recursive: true });
101
+ fs.writeFileSync(path.join(tmpRoot, 'packages', 'cli', 'dist', 'index.js'), '');
102
+ fs.mkdirSync(path.join(tmpRoot, 'packages', 'cli', 'package.json'));
103
+ expect(() => resolveLocalEntry(tmpRoot)).toThrow();
104
+ });
105
+ });
106
+ describe('resolveGlobalEntry (mmnto-ai/totem#3008)', () => {
107
+ const binA = path.join(path.sep, 'bin-a');
108
+ const binB = path.join(path.sep, 'bin-b');
109
+ const pathEnv = [binA, binB].join(path.delimiter);
110
+ it('win32 npm layout: the totem shim beside <dir>/node_modules/@mmnto/cli/dist/index.js', () => {
111
+ const pkgDir = path.join(binB, 'node_modules', '@mmnto', 'cli');
112
+ const entry = path.join(pkgDir, 'dist', 'index.js');
113
+ const fsx = fakeFs({
114
+ [path.join(binB, 'totem.cmd')]: '',
115
+ [entry]: '',
116
+ [path.join(pkgDir, 'package.json')]: CLI_PKG,
117
+ });
118
+ expect(resolveGlobalEntry(pathEnv, fsx)).toEqual({
119
+ hit: { entry, version: '7.7.7', tier: 'global' },
120
+ unverified: [],
121
+ });
122
+ });
123
+ it('POSIX npm layout: <dir>/totem realpaths to <pkg>/dist/index.js and <pkg>/package.json names @mmnto/cli', () => {
124
+ const pkgDir = path.join(path.sep, 'lib', 'node_modules', '@mmnto', 'cli');
125
+ const entry = path.join(pkgDir, 'dist', 'index.js');
126
+ const fsx = fakeFs({ [entry]: '', [path.join(pkgDir, 'package.json')]: CLI_PKG }, { [path.join(binA, 'totem')]: entry });
127
+ expect(resolveGlobalEntry(pathEnv, fsx)).toEqual({
128
+ hit: { entry, version: '7.7.7', tier: 'global' },
129
+ unverified: [],
130
+ });
131
+ });
132
+ it('a global whose package.json names another package is not a hit', () => {
133
+ const pkgDir = path.join(path.sep, 'lib', 'node_modules', 'totem');
134
+ const entry = path.join(pkgDir, 'dist', 'index.js');
135
+ const shim = path.join(binA, 'totem');
136
+ const fsx = fakeFs({ [entry]: '', [path.join(pkgDir, 'package.json')]: OTHER_PKG }, { [shim]: entry });
137
+ const probe = resolveGlobalEntry(pathEnv, fsx);
138
+ expect(probe.hit).toBeUndefined();
139
+ expect(probe.unverified).toEqual([shim]);
140
+ });
141
+ it('a directory holding node_modules/@mmnto/cli but no totem shim is not a global install', () => {
142
+ const pkgDir = path.join(binA, 'node_modules', '@mmnto', 'cli');
143
+ const fsx = fakeFs({
144
+ [path.join(pkgDir, 'dist', 'index.js')]: '',
145
+ [path.join(pkgDir, 'package.json')]: CLI_PKG,
146
+ });
147
+ expect(resolveGlobalEntry(pathEnv, fsx)).toEqual({ unverified: [] });
148
+ });
149
+ it('a fork installed globally under the alias is a hit by its path, and its own name is reported', () => {
150
+ const pkgDir = path.join(binA, 'node_modules', '@mmnto', 'cli');
151
+ const entry = path.join(pkgDir, 'dist', 'index.js');
152
+ const fsx = fakeFs({
153
+ [path.join(binA, 'totem.cmd')]: '',
154
+ [entry]: '',
155
+ [path.join(pkgDir, 'package.json')]: FORK_PKG,
156
+ });
157
+ expect(resolveGlobalEntry(pathEnv, fsx)).toEqual({
158
+ hit: { entry, version: '2.13.0-acme.1', tier: 'global', aliasOf: '@acme/cli' },
159
+ unverified: [],
160
+ });
161
+ });
162
+ it('POSIX: a link that resolves outside node_modules is a hit when the manifest names @mmnto/cli (a linked install)', () => {
163
+ const pkgDir = path.join(path.sep, 'src', 'totem', 'packages', 'cli');
164
+ const entry = path.join(pkgDir, 'dist', 'index.js');
165
+ const fsx = fakeFs({ [entry]: '', [path.join(pkgDir, 'package.json')]: CLI_PKG }, { [path.join(binA, 'totem')]: entry });
166
+ expect(resolveGlobalEntry(pathEnv, fsx)).toEqual({
167
+ hit: { entry, version: '7.7.7', tier: 'global' },
168
+ unverified: [],
169
+ });
170
+ });
171
+ it('POSIX: a manifest that carries @mmnto/cli only as a nested name is not a hit', () => {
172
+ const pkgDir = path.join(path.sep, 'opt', 'someone-else');
173
+ const entry = path.join(pkgDir, 'dist', 'index.js');
174
+ const shim = path.join(binA, 'totem');
175
+ const fsx = fakeFs({ [entry]: '', [path.join(pkgDir, 'package.json')]: NESTED_PKG }, { [shim]: entry });
176
+ expect(resolveGlobalEntry(pathEnv, fsx)).toEqual({ unverified: [shim] });
177
+ });
178
+ it('a totem.cmd on PATH with no npm layout lands in unverified', () => {
179
+ const cmd = path.join(binA, 'totem.cmd');
180
+ const fsx = fakeFs({ [cmd]: '@echo off' });
181
+ expect(resolveGlobalEntry(pathEnv, fsx)).toEqual({ unverified: [cmd] });
182
+ });
183
+ it('a totem link that cannot be resolved is not a hit, and nothing throws', () => {
184
+ const shim = path.join(binA, 'totem');
185
+ const fsx = fakeFs({ [shim]: '#!/bin/sh' });
186
+ expect(resolveGlobalEntry(pathEnv, fsx)).toEqual({ unverified: [shim] });
187
+ });
188
+ it('the first hit wins and keeps what was found unverified before it', () => {
189
+ const cmd = path.join(binA, 'totem.cmd');
190
+ const pkgDir = path.join(binB, 'node_modules', '@mmnto', 'cli');
191
+ const entry = path.join(pkgDir, 'dist', 'index.js');
192
+ const fsx = fakeFs({
193
+ [cmd]: '',
194
+ [path.join(binB, 'totem.cmd')]: '',
195
+ [entry]: '',
196
+ [path.join(pkgDir, 'package.json')]: CLI_PKG,
197
+ });
198
+ expect(resolveGlobalEntry(pathEnv, fsx)).toEqual({
199
+ hit: { entry, version: '7.7.7', tier: 'global' },
200
+ unverified: [cmd],
201
+ });
202
+ });
203
+ it('an unreadable package.json never stops the scan: a shimless directory is skipped and a valid install later on PATH is found', () => {
204
+ const badDir = path.join(binA, 'node_modules', '@mmnto', 'cli');
205
+ const badPkg = path.join(badDir, 'package.json');
206
+ const goodDir = path.join(binB, 'node_modules', '@mmnto', 'cli');
207
+ const entry = path.join(goodDir, 'dist', 'index.js');
208
+ const fsx = fakeFs({
209
+ [path.join(badDir, 'dist', 'index.js')]: '',
210
+ [path.join(binB, 'totem.cmd')]: '',
211
+ [entry]: '',
212
+ [path.join(goodDir, 'package.json')]: CLI_PKG,
213
+ }, {}, { unreadable: [badPkg] });
214
+ expect(resolveGlobalEntry(pathEnv, fsx)).toEqual({
215
+ hit: { entry, version: '7.7.7', tier: 'global' },
216
+ unverified: [],
217
+ });
218
+ });
219
+ it('an unreadable package.json behind a POSIX link: the path still identifies the install, the version is unknown, nothing throws', () => {
220
+ const pkgDir = path.join(path.sep, 'lib', 'node_modules', '@mmnto', 'cli');
221
+ const entry = path.join(pkgDir, 'dist', 'index.js');
222
+ const shim = path.join(binA, 'totem');
223
+ const fsx = fakeFs({ [entry]: '' }, { [shim]: entry }, { unreadable: [path.join(pkgDir, 'package.json')] });
224
+ expect(resolveGlobalEntry(pathEnv, fsx)).toEqual({
225
+ hit: { entry, version: undefined, tier: 'global' },
226
+ unverified: [],
227
+ });
228
+ });
229
+ it('an unreadable package.json behind a POSIX link that resolves outside node_modules is not a hit', () => {
230
+ const pkgDir = path.join(path.sep, 'opt', 'unknown');
231
+ const entry = path.join(pkgDir, 'dist', 'index.js');
232
+ const shim = path.join(binA, 'totem');
233
+ const fsx = fakeFs({ [entry]: '' }, { [shim]: entry }, { unreadable: [path.join(pkgDir, 'package.json')] });
234
+ expect(resolveGlobalEntry(pathEnv, fsx)).toEqual({ unverified: [shim] });
235
+ });
236
+ it('a directory named totem is not reported as an executable', () => {
237
+ const fsx = fakeFs({}, {}, { dirs: [path.join(binA, 'totem')] });
238
+ expect(resolveGlobalEntry(pathEnv, fsx)).toEqual({ unverified: [] });
239
+ });
240
+ it('an undefined or empty PATH finds nothing', () => {
241
+ expect(resolveGlobalEntry(undefined, fakeFs({}))).toEqual({ unverified: [] });
242
+ expect(resolveGlobalEntry('', fakeFs({}))).toEqual({ unverified: [] });
243
+ });
244
+ });
245
+ describe('resolveTotemCli (mmnto-ai/totem#3008)', () => {
246
+ // Resolved, because the local walk resolves its start (a drive letter on win32).
247
+ const start = path.resolve(path.sep, 'proj');
248
+ it('prefers a local entry over a global one', () => {
249
+ const local = path.join(start, 'node_modules', '@mmnto', 'cli', 'dist', 'index.js');
250
+ const bin = path.join(path.sep, 'bin');
251
+ const globalDir = path.join(bin, 'node_modules', '@mmnto', 'cli');
252
+ const fsx = fakeFs({
253
+ [local]: '',
254
+ [path.join(globalDir, 'dist', 'index.js')]: '',
255
+ [path.join(globalDir, 'package.json')]: CLI_PKG,
256
+ });
257
+ expect(resolveTotemCli(start, { pathEnv: bin, fs: fsx })).toEqual({
258
+ ok: true,
259
+ entry: local,
260
+ version: undefined,
261
+ tier: 'pinned',
262
+ });
263
+ });
264
+ it('falls through to an npm-layout global when nothing local resolves', () => {
265
+ const bin = path.join(path.sep, 'bin');
266
+ const globalDir = path.join(bin, 'node_modules', '@mmnto', 'cli');
267
+ const entry = path.join(globalDir, 'dist', 'index.js');
268
+ const fsx = fakeFs({
269
+ [path.join(bin, 'totem.cmd')]: '',
270
+ [entry]: '',
271
+ [path.join(globalDir, 'package.json')]: CLI_PKG,
272
+ });
273
+ expect(resolveTotemCli(start, { pathEnv: bin, fs: fsx })).toEqual({
274
+ ok: true,
275
+ entry,
276
+ version: '7.7.7',
277
+ tier: 'global',
278
+ });
279
+ });
280
+ it('a pinned fork installed under the alias resolves by its path, and its own name is reported', () => {
281
+ const pkgDir = path.join(start, 'node_modules', '@mmnto', 'cli');
282
+ const entry = path.join(pkgDir, 'dist', 'index.js');
283
+ const fsx = fakeFs({ [entry]: '', [path.join(pkgDir, 'package.json')]: FORK_PKG });
284
+ expect(resolveTotemCli(start, { pathEnv: '', fs: fsx })).toEqual({
285
+ ok: true,
286
+ entry,
287
+ version: '2.13.0-acme.1',
288
+ tier: 'pinned',
289
+ aliasOf: '@acme/cli',
290
+ });
291
+ });
292
+ it('a global hit carries the unverified totem that was skipped before it on PATH', () => {
293
+ const shims = path.join(path.sep, 'shims');
294
+ const bin = path.join(path.sep, 'bin');
295
+ const cmd = path.join(shims, 'totem.cmd');
296
+ const globalDir = path.join(bin, 'node_modules', '@mmnto', 'cli');
297
+ const entry = path.join(globalDir, 'dist', 'index.js');
298
+ const fsx = fakeFs({
299
+ [cmd]: '',
300
+ [path.join(bin, 'totem.cmd')]: '',
301
+ [entry]: '',
302
+ [path.join(globalDir, 'package.json')]: CLI_PKG,
303
+ });
304
+ const pathEnv = [shims, bin].join(path.delimiter);
305
+ expect(resolveTotemCli(start, { pathEnv, fs: fsx })).toEqual({
306
+ ok: true,
307
+ entry,
308
+ version: '7.7.7',
309
+ tier: 'global',
310
+ unverified: [cmd],
311
+ });
312
+ });
313
+ it('returns the three places looked when nothing resolves', () => {
314
+ const bin = path.join(path.sep, 'bin');
315
+ const cmd = path.join(bin, 'totem.cmd');
316
+ const result = resolveTotemCli(start, { pathEnv: bin, fs: fakeFs({ [cmd]: '' }) });
317
+ expect(result).toEqual({
318
+ ok: false,
319
+ looked: [
320
+ `a workspace build at packages/cli/dist/index.js, walking up from ${start}`,
321
+ `a pinned install at node_modules/@mmnto/cli/dist/index.js, walking up from ${start}`,
322
+ 'an npm-layout global install of @mmnto/cli on PATH',
323
+ ],
324
+ unverified: [cmd],
325
+ });
326
+ });
327
+ });
328
+ //# sourceMappingURL=cli-resolve.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli-resolve.test.js","sourceRoot":"","sources":["../src/cli-resolve.test.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAElC,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAGrE,OAAO,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAE1F,SAAS,kBAAkB,CAAC,IAAY,EAAE,IAAI,GAAG,YAAY;IAC3D,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC9E,EAAE,CAAC,aAAa,CACd,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,cAAc,CAAC,EAClD,YAAY,IAAI,sBAAsB,CACvC,CAAC;IACF,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC;IACrE,EAAE,CAAC,aAAa,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IAC5B,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,eAAe,CAAC,IAAY;IACnC,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,cAAc,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC;IAChE,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC7D,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,cAAc,CAAC,EAAE,yCAAyC,CAAC,CAAC;IAC/F,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC;IACpD,EAAE,CAAC,aAAa,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IAC5B,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;GAIG;AACH,SAAS,MAAM,CACb,KAA6B,EAC7B,QAAgC,EAAE,EAClC,QAAoD,EAAE;IAEtD,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC;IACvC,MAAM,UAAU,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,UAAU,IAAI,EAAE,CAAC,CAAC;IACnD,OAAO;QACL,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,IAAI,KAAK,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC;QAC3E,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,IAAI,KAAK,IAAI,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC;QAC5D,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE;YACd,IAAI,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC;gBAAE,MAAM,IAAI,KAAK,CAAC,mCAAmC,CAAC,EAAE,CAAC,CAAC;YAC/E,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;YACtB,IAAI,IAAI,KAAK,SAAS;gBAAE,MAAM,IAAI,KAAK,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;YACxD,OAAO,IAAI,CAAC;QACd,CAAC;QACD,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE;YACd,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;YACxB,IAAI,MAAM,KAAK,SAAS;gBAAE,MAAM,IAAI,KAAK,CAAC,uBAAuB,CAAC,EAAE,CAAC,CAAC;YACtE,OAAO,MAAM,CAAC;QAChB,CAAC;KACF,CAAC;AACJ,CAAC;AAED,MAAM,OAAO,GAAG,yCAAyC,CAAC;AAC1D,MAAM,SAAS,GAAG,oCAAoC,CAAC;AACvD,MAAM,QAAQ,GAAG,gDAAgD,CAAC;AAClE,MAAM,UAAU,GAAG,0EAA0E,CAAC;AAE9F,QAAQ,CAAC,qEAAqE,EAAE,GAAG,EAAE;IACnF,IAAI,OAAe,CAAC;IAEpB,UAAU,CAAC,GAAG,EAAE;QACd,OAAO,GAAG,EAAE,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,oBAAoB,CAAC,CAAC,CAAC;IACzE,CAAC,CAAC,CAAC;IAEH,SAAS,CAAC,GAAG,EAAE;QACb,EAAE,CAAC,MAAM,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IACvD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oFAAoF,EAAE,GAAG,EAAE;QAC5F,MAAM,KAAK,GAAG,kBAAkB,CAAC,OAAO,CAAC,CAAC;QAC1C,MAAM,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC,CAAC;IAC7F,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oFAAoF,EAAE,GAAG,EAAE;QAC5F,kBAAkB,CAAC,OAAO,EAAE,mBAAmB,CAAC,CAAC;QACjD,MAAM,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAC,CAAC,aAAa,EAAE,CAAC;IACrD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,4EAA4E,EAAE,GAAG,EAAE;QACpF,kBAAkB,CAAC,OAAO,CAAC,CAAC;QAC5B,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC;QACrE,MAAM,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAC,CAAC,aAAa,EAAE,CAAC;IACrD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mDAAmD,EAAE,GAAG,EAAE;QAC3D,MAAM,KAAK,GAAG,eAAe,CAAC,OAAO,CAAC,CAAC;QACvC,MAAM,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC;IAC1F,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gDAAgD,EAAE,GAAG,EAAE;QACxD,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,cAAc,EAAE,OAAO,CAAC,CAAC;QAC5D,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC9D,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,cAAc,CAAC,EAAE,SAAS,CAAC,CAAC;QAChE,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,EAAE,CAAC,CAAC;QAC7D,MAAM,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAC,CAAC,aAAa,EAAE,CAAC;IACrD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gEAAgE,EAAE,GAAG,EAAE;QACxE,MAAM,cAAc,GAAG,kBAAkB,CAAC,OAAO,CAAC,CAAC;QACnD,eAAe,CAAC,OAAO,CAAC,CAAC;QACzB,MAAM,CAAC,iBAAiB,CAAC,OAAO,CAAC,EAAE,KAAK,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;IACjE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kCAAkC,EAAE,GAAG,EAAE;QAC1C,MAAM,KAAK,GAAG,eAAe,CAAC,OAAO,CAAC,CAAC;QACvC,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;QACjD,EAAE,CAAC,SAAS,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC1C,MAAM,CAAC,iBAAiB,CAAC,MAAM,CAAC,EAAE,KAAK,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACvD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uCAAuC,EAAE,GAAG,EAAE;QAC/C,MAAM,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAC,CAAC,aAAa,EAAE,CAAC;IACrD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gEAAgE,EAAE,GAAG,EAAE;QACxE,mFAAmF;QACnF,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACjF,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,EAAE,CAAC,CAAC;QAChF,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,cAAc,CAAC,CAAC,CAAC;QACpE,MAAM,CAAC,GAAG,EAAE,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;IACrD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,0CAA0C,EAAE,GAAG,EAAE;IACxD,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;IAC1C,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;IAC1C,MAAM,OAAO,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAElD,EAAE,CAAC,qFAAqF,EAAE,GAAG,EAAE;QAC7F,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,cAAc,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC;QAChE,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC;QACpD,MAAM,GAAG,GAAG,MAAM,CAAC;YACjB,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC,EAAE,EAAE;YAClC,CAAC,KAAK,CAAC,EAAE,EAAE;YACX,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC,EAAE,OAAO;SAC7C,CAAC,CAAC;QACH,MAAM,CAAC,kBAAkB,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC;YAC/C,GAAG,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE;YAChD,UAAU,EAAE,EAAE;SACf,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wGAAwG,EAAE,GAAG,EAAE;QAChH,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,EAAE,cAAc,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC;QAC3E,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC;QACpD,MAAM,GAAG,GAAG,MAAM,CAChB,EAAE,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC,EAAE,OAAO,EAAE,EAC7D,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,EAAE,KAAK,EAAE,CACtC,CAAC;QACF,MAAM,CAAC,kBAAkB,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC;YAC/C,GAAG,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE;YAChD,UAAU,EAAE,EAAE;SACf,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gEAAgE,EAAE,GAAG,EAAE;QACxE,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,EAAE,cAAc,EAAE,OAAO,CAAC,CAAC;QACnE,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC;QACpD,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QACtC,MAAM,GAAG,GAAG,MAAM,CAChB,EAAE,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC,EAAE,SAAS,EAAE,EAC/D,EAAE,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,CAClB,CAAC;QACF,MAAM,KAAK,GAAG,kBAAkB,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;QAC/C,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,aAAa,EAAE,CAAC;QAClC,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IAC3C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uFAAuF,EAAE,GAAG,EAAE;QAC/F,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,cAAc,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC;QAChE,MAAM,GAAG,GAAG,MAAM,CAAC;YACjB,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC,EAAE,EAAE;YAC3C,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC,EAAE,OAAO;SAC7C,CAAC,CAAC;QACH,MAAM,CAAC,kBAAkB,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,UAAU,EAAE,EAAE,EAAE,CAAC,CAAC;IACvE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,8FAA8F,EAAE,GAAG,EAAE;QACtG,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,cAAc,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC;QAChE,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC;QACpD,MAAM,GAAG,GAAG,MAAM,CAAC;YACjB,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC,EAAE,EAAE;YAClC,CAAC,KAAK,CAAC,EAAE,EAAE;YACX,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC,EAAE,QAAQ;SAC9C,CAAC,CAAC;QACH,MAAM,CAAC,kBAAkB,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC;YAC/C,GAAG,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,eAAe,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,WAAW,EAAE;YAC9E,UAAU,EAAE,EAAE;SACf,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iHAAiH,EAAE,GAAG,EAAE;QACzH,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,EAAE,OAAO,EAAE,UAAU,EAAE,KAAK,CAAC,CAAC;QACtE,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC;QACpD,MAAM,GAAG,GAAG,MAAM,CAChB,EAAE,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC,EAAE,OAAO,EAAE,EAC7D,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,EAAE,KAAK,EAAE,CACtC,CAAC;QACF,MAAM,CAAC,kBAAkB,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC;YAC/C,GAAG,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE;YAChD,UAAU,EAAE,EAAE;SACf,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,8EAA8E,EAAE,GAAG,EAAE;QACtF,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,EAAE,cAAc,CAAC,CAAC;QAC1D,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC;QACpD,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QACtC,MAAM,GAAG,GAAG,MAAM,CAChB,EAAE,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC,EAAE,UAAU,EAAE,EAChE,EAAE,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,CAClB,CAAC;QACF,MAAM,CAAC,kBAAkB,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,UAAU,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC3E,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,4DAA4D,EAAE,GAAG,EAAE;QACpE,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;QACzC,MAAM,GAAG,GAAG,MAAM,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,WAAW,EAAE,CAAC,CAAC;QAC3C,MAAM,CAAC,kBAAkB,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,UAAU,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAC1E,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uEAAuE,EAAE,GAAG,EAAE;QAC/E,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QACtC,MAAM,GAAG,GAAG,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,WAAW,EAAE,CAAC,CAAC;QAC5C,MAAM,CAAC,kBAAkB,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,UAAU,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC3E,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kEAAkE,EAAE,GAAG,EAAE;QAC1E,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;QACzC,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,cAAc,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC;QAChE,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC;QACpD,MAAM,GAAG,GAAG,MAAM,CAAC;YACjB,CAAC,GAAG,CAAC,EAAE,EAAE;YACT,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC,EAAE,EAAE;YAClC,CAAC,KAAK,CAAC,EAAE,EAAE;YACX,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC,EAAE,OAAO;SAC7C,CAAC,CAAC;QACH,MAAM,CAAC,kBAAkB,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC;YAC/C,GAAG,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE;YAChD,UAAU,EAAE,CAAC,GAAG,CAAC;SAClB,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6HAA6H,EAAE,GAAG,EAAE;QACrI,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,cAAc,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC;QAChE,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;QACjD,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,cAAc,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC;QACjE,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC;QACrD,MAAM,GAAG,GAAG,MAAM,CAChB;YACE,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC,EAAE,EAAE;YAC3C,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC,EAAE,EAAE;YAClC,CAAC,KAAK,CAAC,EAAE,EAAE;YACX,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,cAAc,CAAC,CAAC,EAAE,OAAO;SAC9C,EACD,EAAE,EACF,EAAE,UAAU,EAAE,CAAC,MAAM,CAAC,EAAE,CACzB,CAAC;QACF,MAAM,CAAC,kBAAkB,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC;YAC/C,GAAG,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE;YAChD,UAAU,EAAE,EAAE;SACf,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+HAA+H,EAAE,GAAG,EAAE;QACvI,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,EAAE,cAAc,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC;QAC3E,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC;QACpD,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QACtC,MAAM,GAAG,GAAG,MAAM,CAChB,EAAE,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,EACf,EAAE,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,EACjB,EAAE,UAAU,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC,EAAE,CACpD,CAAC;QACF,MAAM,CAAC,kBAAkB,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC;YAC/C,GAAG,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,QAAQ,EAAE;YAClD,UAAU,EAAE,EAAE;SACf,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gGAAgG,EAAE,GAAG,EAAE;QACxG,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC;QACrD,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC;QACpD,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QACtC,MAAM,GAAG,GAAG,MAAM,CAChB,EAAE,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,EACf,EAAE,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,EACjB,EAAE,UAAU,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC,EAAE,CACpD,CAAC;QACF,MAAM,CAAC,kBAAkB,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,UAAU,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC3E,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0DAA0D,EAAE,GAAG,EAAE;QAClE,MAAM,GAAG,GAAG,MAAM,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC;QACjE,MAAM,CAAC,kBAAkB,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,UAAU,EAAE,EAAE,EAAE,CAAC,CAAC;IACvE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0CAA0C,EAAE,GAAG,EAAE;QAClD,MAAM,CAAC,kBAAkB,CAAC,SAAS,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,UAAU,EAAE,EAAE,EAAE,CAAC,CAAC;QAC9E,MAAM,CAAC,kBAAkB,CAAC,EAAE,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,UAAU,EAAE,EAAE,EAAE,CAAC,CAAC;IACzE,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,uCAAuC,EAAE,GAAG,EAAE;IACrD,iFAAiF;IACjF,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;IAE7C,EAAE,CAAC,yCAAyC,EAAE,GAAG,EAAE;QACjD,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,cAAc,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC;QACpF,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QACvC,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,cAAc,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC;QAClE,MAAM,GAAG,GAAG,MAAM,CAAC;YACjB,CAAC,KAAK,CAAC,EAAE,EAAE;YACX,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC,EAAE,EAAE;YAC9C,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,cAAc,CAAC,CAAC,EAAE,OAAO;SAChD,CAAC,CAAC;QACH,MAAM,CAAC,eAAe,CAAC,KAAK,EAAE,EAAE,OAAO,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC;YAChE,EAAE,EAAE,IAAI;YACR,KAAK,EAAE,KAAK;YACZ,OAAO,EAAE,SAAS;YAClB,IAAI,EAAE,QAAQ;SACf,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mEAAmE,EAAE,GAAG,EAAE;QAC3E,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QACvC,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,cAAc,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC;QAClE,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC;QACvD,MAAM,GAAG,GAAG,MAAM,CAAC;YACjB,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC,EAAE,EAAE;YACjC,CAAC,KAAK,CAAC,EAAE,EAAE;YACX,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,cAAc,CAAC,CAAC,EAAE,OAAO;SAChD,CAAC,CAAC;QACH,MAAM,CAAC,eAAe,CAAC,KAAK,EAAE,EAAE,OAAO,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC;YAChE,EAAE,EAAE,IAAI;YACR,KAAK;YACL,OAAO,EAAE,OAAO;YAChB,IAAI,EAAE,QAAQ;SACf,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,4FAA4F,EAAE,GAAG,EAAE;QACpG,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,cAAc,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC;QACjE,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC;QACpD,MAAM,GAAG,GAAG,MAAM,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC;QACnF,MAAM,CAAC,eAAe,CAAC,KAAK,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC;YAC/D,EAAE,EAAE,IAAI;YACR,KAAK;YACL,OAAO,EAAE,eAAe;YACxB,IAAI,EAAE,QAAQ;YACd,OAAO,EAAE,WAAW;SACrB,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,8EAA8E,EAAE,GAAG,EAAE;QACtF,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;QAC3C,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QACvC,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC;QAC1C,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,cAAc,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC;QAClE,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC;QACvD,MAAM,GAAG,GAAG,MAAM,CAAC;YACjB,CAAC,GAAG,CAAC,EAAE,EAAE;YACT,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC,EAAE,EAAE;YACjC,CAAC,KAAK,CAAC,EAAE,EAAE;YACX,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,cAAc,CAAC,CAAC,EAAE,OAAO;SAChD,CAAC,CAAC;QACH,MAAM,OAAO,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAClD,MAAM,CAAC,eAAe,CAAC,KAAK,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC;YAC3D,EAAE,EAAE,IAAI;YACR,KAAK;YACL,OAAO,EAAE,OAAO;YAChB,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE,CAAC,GAAG,CAAC;SAClB,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uDAAuD,EAAE,GAAG,EAAE;QAC/D,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QACvC,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC;QACxC,MAAM,MAAM,GAAG,eAAe,CAAC,KAAK,EAAE,EAAE,OAAO,EAAE,GAAG,EAAE,EAAE,EAAE,MAAM,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC;QACnF,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC;YACrB,EAAE,EAAE,KAAK;YACT,MAAM,EAAE;gBACN,oEAAoE,KAAK,EAAE;gBAC3E,8EAA8E,KAAK,EAAE;gBACrF,oDAAoD;aACrD;YACD,UAAU,EAAE,CAAC,GAAG,CAAC;SAClB,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}