zet-x 1.0.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 ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 ZET Digital
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,358 @@
1
+ # ZET X
2
+
3
+ > **X** stands for **execute** — a lightweight task runner for your project.
4
+
5
+ A project-level task runner for teams. Define dev commands in a config file, run them with `x <command>`.
6
+
7
+ Built for the team at ZET Digital for internal use. You're welcome to use it too.
8
+
9
+ > This is not a CLI framework like Commander or Yargs. Those help you build CLIs. This is a task runner — it runs your project's commands.
10
+
11
+ ## Install
12
+
13
+ ```sh
14
+ npm install -g zet-x
15
+ ```
16
+
17
+ Requires Node.js ^18.19 or >=20.6.
18
+
19
+ ### Shell Completion (Optional)
20
+
21
+ Add to your shell profile to enable tab completions in your terminal:
22
+
23
+ ```sh
24
+ # bash
25
+ eval "$(x cli init-completion bash)"
26
+
27
+ # zsh (macOS)
28
+ eval "$(x cli init-completion zsh)"
29
+ ```
30
+
31
+ Common shell profile locations:
32
+ - **bash**: `~/.bashrc` or `~/.bash_profile`
33
+ - **zsh**: `~/.zshrc`
34
+
35
+ ## Getting Started
36
+
37
+ ```sh
38
+ mkdir my-project && cd my-project
39
+ x init
40
+ x hello
41
+ ```
42
+
43
+ `x init` creates an `x.config.mjs` with a starter command. Edit it to add your own. Run `x` or `x --help` to see all registered commands.
44
+
45
+ ## Configuration File
46
+
47
+ `x` traverses up from the current directory looking for `x.config.mjs`. Commands are registered as side effects via named imports.
48
+
49
+ ```js
50
+ import { register } from 'zet-x';
51
+
52
+ register('up', 'Start containers')
53
+ .run`docker compose up -d`;
54
+ ```
55
+
56
+ ## API Reference
57
+
58
+ ### Command Registration
59
+
60
+ ```js
61
+ import { register, group } from 'zet-x';
62
+
63
+ // Simple command
64
+ register('up', 'Start containers')
65
+ .run`docker compose up -d`;
66
+
67
+ // With signature (args, options, rest)
68
+ register('deploy {env} {--Force}', 'Deploy to environment')
69
+ .callback(async ($) => {
70
+ const env = $.arg('env');
71
+ $.info(`Deploying to ${env}...`);
72
+ if ($.option('--force')) $.warn('Force deploy enabled');
73
+ await $.mustRun`deploy.sh ${env}`;
74
+ });
75
+
76
+ // Group
77
+ const db = group('db', 'Database');
78
+ db.register('migrate ...', 'Run migrations').run`docker compose exec app migrate ...`;
79
+ ```
80
+
81
+ ### Signature Syntax
82
+
83
+ ```
84
+ command-name {arg} {arg?} {arg desc} {--option} {--option=} {--Option} {--Opt-Name=} ...
85
+ ```
86
+
87
+ | Token | Meaning |
88
+ |---|---|
89
+ | `{name}` | Required positional argument |
90
+ | `{name?}` | Optional positional argument |
91
+ | `{name description}` | Required argument with description |
92
+ | `{name? description}` | Optional argument with description |
93
+ | `{--name}` | Boolean option (flag) |
94
+ | `{--name=}` | Option that accepts a value |
95
+ | `{--Name}` | Boolean option with short flag `-N` |
96
+ | `{--Preserve-Cache=}` | Value option with short flag `-PC` |
97
+ | `...` | Accept extra arguments (rest) |
98
+
99
+ Short flags are derived from uppercase letters at the start of hyphen-separated segments: `--Preserve-Cache` -> `-PC`. The long name is always stored lowercase.
100
+
101
+ ### `.run` — Defining Commands
102
+
103
+ `.run` works as both a tagged template (recommended) and a regular function call.
104
+
105
+ **Tagged template (recommended)** — whitespace in static parts is split into separate arguments. Interpolated values are kept as single tokens (safe for paths with spaces).
106
+
107
+ ```js
108
+ register('build', 'Build project').run`npm run build`;
109
+
110
+ // Interpolation keeps the value as one token
111
+ const target = 'my output dir';
112
+ register('clean', 'Clean output').run`rm -rf ${target}`;
113
+
114
+ // Rest args with ...
115
+ register('npm ...', 'Run npm').run`npm ...`;
116
+ // x npm install lodash -> npm install lodash
117
+ ```
118
+
119
+ **Function call** — also accepts variadic string arguments for programmatic use.
120
+
121
+ ```js
122
+ register('up', 'Start containers').run('docker', 'compose', 'up', '-d');
123
+ ```
124
+
125
+ ### `.userCwd()` Method
126
+
127
+ Run a command from the user's current working directory instead of the project root:
128
+
129
+ ```js
130
+ register('ls', 'List files')
131
+ .userCwd()
132
+ .run`ls -la`;
133
+ ```
134
+
135
+ ### Templates
136
+
137
+ Reuse common command prefixes:
138
+
139
+ ```js
140
+ import { register, template } from 'zet-x';
141
+
142
+ const compose = template((service) => ['docker', 'compose', 'exec', '-it', service]);
143
+
144
+ register('shell', 'Open shell')
145
+ .run`${compose('app')} bash`;
146
+
147
+ register('migrate ...', 'Run migrations')
148
+ .run`${compose('app')} migrate ...`;
149
+ ```
150
+
151
+ Template functions can return an array of strings or a single string (which gets split on whitespace). Templates validate argument count based on `fn.length`. Zero-arg templates can be used without `()` — `${compose}` works the same as `${compose()}`.
152
+
153
+ ### Callback with `$` Context
154
+
155
+ Callbacks receive an `ExecutionContext` object (`$`) with everything needed to run commands and access parsed arguments:
156
+
157
+ ```js
158
+ register('deploy {env} {--Verbose}')
159
+ .callback(async ($) => {
160
+ const env = $.arg('env'); // string | null
161
+ const verbose = $.option('--verbose'); // string | true | null
162
+
163
+ // Run a command (output visible) — does not throw on failure
164
+ await $.run`deploy.sh ${env}`;
165
+
166
+ // Run and throw on failure
167
+ await $.mustRun`deploy.sh ${env}`;
168
+
169
+ // Run silently (capture output)
170
+ const result = await $.silent`git rev-parse HEAD`;
171
+ $.info(`Deployed ${result.stdout.trim()}`);
172
+ });
173
+ ```
174
+
175
+ `$.run` and `$.silent` also accept variadic args: `await $.run('docker', 'compose', 'up')`.
176
+
177
+ `$.run` does not throw on failure — use `$.mustRun` or chain `.throw()` to stop on errors.
178
+
179
+ #### `$` Methods
180
+
181
+ | Method | Description |
182
+ |---|---|
183
+ | `$.arg(name)` | Get parsed argument (`string \| null`) |
184
+ | `$.option('--name')` | Get option (`string \| true \| null`) |
185
+ | `$.run\`cmd\`` | Spawn with inherited stdio |
186
+ | `$.mustRun\`cmd\`` | Like `$.run` but throws on non-zero exit code |
187
+ | `$.silent\`cmd\`` | Spawn with piped stdio, returns `CommandOutput` |
188
+ | `$.mustSilent\`cmd\`` | Like `$.silent` but throws on non-zero exit code |
189
+ | `$.info(msg)` | Green message to stdout |
190
+ | `$.warn(msg)` | Yellow message to stderr |
191
+ | `$.error(msg)` | Red message to stderr |
192
+ | `$.confirm(msg)` | Yellow prompt `[y/N]`, returns `boolean` |
193
+ | `$.prompt(msg)` | Cyan prompt, returns the answer |
194
+ | `$.root` | Project root — callable: `$.root('src')`, or string: `` `${$.root}` `` |
195
+ | `$.user` | User CWD — callable: `$.user('test')`, or string: `` `${$.user}` `` |
196
+ | `$.cd(path)` | Change working directory for subsequent `run`/`silent` calls |
197
+
198
+ `$.root` and `$.user` are `PathHelper` objects — they work as both functions and strings via `Symbol.toPrimitive`.
199
+
200
+ #### `CommandOutput`
201
+
202
+ Returned by `$.silent`:
203
+
204
+ | Property | Type |
205
+ |---|---|
206
+ | `.code` | `number` |
207
+ | `.output` | `string \| null` (combined stdout+stderr) |
208
+ | `.stdout` | `string \| null` |
209
+ | `.stderr` | `string \| null` |
210
+ | `.succeeded` | `boolean` |
211
+ | `.failed` | `boolean` |
212
+ | `.throw()` | Throws if failed, returns `this` if succeeded |
213
+
214
+ ### Groups
215
+
216
+ Organize commands under a prefix:
217
+
218
+ ```js
219
+ import { group } from 'zet-x';
220
+
221
+ const db = group('db', 'Database');
222
+ db.register('migrate ...', 'Run migrations').run`docker compose exec app migrate ...`;
223
+ db.register('seed', 'Seed database').run`docker compose exec app db-seed`;
224
+ ```
225
+
226
+ ```sh
227
+ x db migrate --fresh
228
+ x db seed
229
+ ```
230
+
231
+ The names `init` and `cli` are reserved and cannot be used as group prefixes or command names.
232
+
233
+ ### Splitting Config Files
234
+
235
+ Use standard ES module imports to split your config across multiple files:
236
+
237
+ ```js
238
+ // x.config.mjs
239
+ import { register } from 'zet-x';
240
+ import './x/docker.mjs';
241
+ import './x/deploy.mjs';
242
+
243
+ register('hello', 'Say hello').run`echo hi`;
244
+ ```
245
+
246
+ ```js
247
+ // x/docker.mjs
248
+ import { register, template } from 'zet-x';
249
+
250
+ const compose = template((service) => ['docker', 'compose', 'exec', '-it', service]);
251
+ register('shell', 'Open shell').run`${compose('app')} bash`;
252
+ ```
253
+
254
+ Templates and groups defined in one file are available to all files — they share the same module singleton. Export a template from a shared file and import it wherever needed:
255
+
256
+ ```js
257
+ // x/shared.mjs
258
+ import { template } from 'zet-x';
259
+ export const compose = template((service) => ['docker', 'compose', 'exec', '-it', service]);
260
+ ```
261
+
262
+ ```js
263
+ // x/docker.mjs
264
+ import { register } from 'zet-x';
265
+ import { compose } from './shared.mjs';
266
+
267
+ register('shell', 'Open shell').run`${compose('app')} bash`;
268
+ register('logs', 'View logs').run`docker compose logs -f`;
269
+ ```
270
+
271
+ ### Config Paths
272
+
273
+ ```js
274
+ import { setAiPublishPath, setIdePublishPath, autoPublishIde } from 'zet-x';
275
+
276
+ setAiPublishPath('docs/'); // zet-x.md -> docs/zet-x.md
277
+ setAiPublishPath('.claude/skills/project/SKILL.md'); // exact file path
278
+ setIdePublishPath('.types/'); // .d.ts -> .types/.x/index.d.ts
279
+ autoPublishIde(); // auto-regenerate .x/index.d.ts on every run
280
+ ```
281
+
282
+ ## Built-in Commands
283
+
284
+ ### `x init`
285
+
286
+ Creates `x.config.mjs` in the current directory with a starter command.
287
+
288
+ ### `x cli publish ai`
289
+
290
+ Generates `zet-x.md` — an AI agent reference for your project's commands. By default writes to the project root. Configure with `setAiPublishPath()`.
291
+
292
+ ### `x cli publish ide`
293
+
294
+ Generates TypeScript declarations for IDE autocompletion. By default writes to `.x/` (with `.gitignore`). Configure with `setIdePublishPath()`.
295
+
296
+ ### `x cli init-completion <bash|zsh>`
297
+
298
+ Outputs a shell completion script.
299
+
300
+ ### Auto-generated Help
301
+
302
+ ```sh
303
+ x --help # global help
304
+ x <command> --help # command-specific help
305
+ ```
306
+
307
+ ### Auto-generated Types
308
+
309
+ When `autoPublishIde()` is called in your config, `x` regenerates `.x/index.d.ts` with TypeScript declarations for IDE support on every run. This happens silently and never breaks normal operation. You can also generate types on demand with `x cli publish ide`.
310
+
311
+ ## Full Example
312
+
313
+ ```js
314
+ import { register, group, template, setAiPublishPath } from 'zet-x';
315
+
316
+ setAiPublishPath('docs/');
317
+
318
+ const compose = template((service) => ['docker', 'compose', 'exec', '-it', service]);
319
+
320
+ // Groups
321
+ const db = group('db', 'Database');
322
+ db.register('migrate ...', 'Run migrations')
323
+ .run`${compose('app')} db-migrate ...`;
324
+ db.register('seed', 'Seed database')
325
+ .run`${compose('app')} db-seed`;
326
+
327
+ // Root commands
328
+ register('up', 'Start all containers')
329
+ .run`docker compose up -d`;
330
+
331
+ register('down', 'Stop all containers')
332
+ .run`docker compose down`;
333
+
334
+ register('deploy {env} {--Force}', 'Deploy to environment')
335
+ .callback(async ($) => {
336
+ const env = $.arg('env');
337
+ if ($.option('--force')) {
338
+ $.warn('Force deploy — skipping checks');
339
+ } else if (!await $.confirm(`Deploy to ${env}?`)) {
340
+ return;
341
+ }
342
+ $.info(`Deploying to ${env}...`);
343
+ await $.mustRun`deploy.sh ${env}`;
344
+ });
345
+ ```
346
+
347
+ ## How It Works
348
+
349
+ 1. `x` binary traverses up from CWD to find `x.config.mjs`
350
+ 2. Sets up a module resolution hook so the config can `import { register } from 'zet-x'`
351
+ 3. Imports the config (side effects register commands), then runs the matched command
352
+ 4. Commands run from the project root — use `$.root` and `$.user` in callbacks to resolve paths, or `.userCwd()` to run from the user's directory
353
+
354
+ ## Test
355
+
356
+ ```sh
357
+ npm test
358
+ ```
package/bin/x.mjs ADDED
@@ -0,0 +1,154 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { existsSync, readFileSync, writeFileSync } from "node:fs";
4
+ import { join, dirname } from "node:path";
5
+ import { spawn } from "node:child_process";
6
+ import { fileURLToPath, pathToFileURL } from "node:url";
7
+
8
+ const CONFIG_NAME = "x.config.mjs";
9
+
10
+ const cliArgs = process.argv.slice(2);
11
+
12
+ if (cliArgs[0] === "--version" || cliArgs[0] === "-v") {
13
+ const pkg = JSON.parse(readFileSync(join(dirname(fileURLToPath(import.meta.url)), "..", "package.json"), "utf8"));
14
+ process.stdout.write(pkg.version + "\n");
15
+ process.exit(0);
16
+ }
17
+
18
+ if (cliArgs[0] === "init") {
19
+ const configFile = join(process.cwd(), "x.config.mjs");
20
+ if (existsSync(configFile)) {
21
+ process.stderr.write("x is already initialized in this directory\n");
22
+ process.exit(1);
23
+ }
24
+ writeFileSync(
25
+ configFile,
26
+ `import { register } from 'zet-x';
27
+
28
+ register('hello', 'Say hello')
29
+ .callback(($) => {
30
+ $.info('Hello from ZET X!');
31
+ });
32
+ `
33
+ );
34
+ process.stdout.write("Created x.config.mjs\n");
35
+ process.exit(0);
36
+ }
37
+
38
+
39
+ if (cliArgs[0] === "cli" && cliArgs[1] === "init-completion") {
40
+ const shell = cliArgs[2];
41
+ if (shell === "bash") {
42
+ process.stdout.write(`_x_completions() {
43
+ local cur=\${COMP_WORDS[COMP_CWORD]}
44
+ local completions
45
+ if [ $COMP_CWORD -eq 1 ]; then
46
+ completions=$(x --completions 2>/dev/null)
47
+ elif [ $COMP_CWORD -eq 2 ]; then
48
+ completions=$(x --completions "\${COMP_WORDS[1]}" 2>/dev/null)
49
+ elif [ $COMP_CWORD -eq 3 ]; then
50
+ completions=$(x --completions "\${COMP_WORDS[1]}" "\${COMP_WORDS[2]}" 2>/dev/null)
51
+ fi
52
+ COMPREPLY=( $(compgen -W "$completions" -- "$cur") )
53
+ }
54
+ complete -F _x_completions x
55
+ `);
56
+ process.exit(0);
57
+ } else if (shell === "zsh") {
58
+ process.stdout.write(`#compdef x
59
+ _x() {
60
+ local -a commands
61
+ if (( CURRENT == 2 )); then
62
+ commands=(\${(f)"$(x --completions 2>/dev/null)"})
63
+ _describe 'command' commands
64
+ elif (( CURRENT == 3 )); then
65
+ commands=(\${(f)"$(x --completions \${words[2]} 2>/dev/null)"})
66
+ _describe 'subcommand' commands
67
+ elif (( CURRENT == 4 )); then
68
+ commands=(\${(f)"$(x --completions \${words[2]} \${words[3]} 2>/dev/null)"})
69
+ _describe 'subcommand' commands
70
+ fi
71
+ }
72
+ _x "$@"
73
+ `);
74
+ process.exit(0);
75
+ } else {
76
+ process.stderr.write("Usage: x cli init-completion <bash|zsh>\n");
77
+ process.exit(1);
78
+ }
79
+ }
80
+
81
+
82
+ function findConfig(startDir) {
83
+ let dir = startDir;
84
+ while (true) {
85
+ const candidate = join(dir, CONFIG_NAME);
86
+ if (existsSync(candidate)) return candidate;
87
+ const parent = dirname(dir);
88
+ if (parent === dir) break;
89
+ dir = parent;
90
+ }
91
+ return null;
92
+ }
93
+
94
+ const configPath = findConfig(process.cwd());
95
+
96
+ if (!configPath) {
97
+ process.stderr.write(
98
+ "x: cannot find x.config.mjs in the current or any parent directory\n"
99
+ );
100
+ process.exit(1);
101
+ }
102
+
103
+ // Register a module resolution hook so configs can `import { register } from 'zet-x'`
104
+ const pkgRoot = dirname(dirname(fileURLToPath(import.meta.url)));
105
+ const [major, minor] = process.versions.node.split(".").map(Number);
106
+
107
+ const supported = (major === 18 && minor >= 19) || (major === 20 && minor >= 6) || major > 20;
108
+ if (!supported) {
109
+ const y = !process.env.NO_COLOR && process.stderr.isTTY ? "\x1b[1;33m" : "";
110
+ const r = y ? "\x1b[0m" : "";
111
+ process.stderr.write(
112
+ `${y}x: Node.js ${process.versions.node} is not supported. Requires ^18.19 or >=20.6.${r}\n`
113
+ );
114
+ }
115
+
116
+ const nodeArgs = [];
117
+
118
+ if (major > 20 || (major === 20 && minor >= 6) || (major === 18 && minor >= 19)) {
119
+ nodeArgs.push(
120
+ "--import",
121
+ pathToFileURL(join(pkgRoot, "dist", "register.js")).href
122
+ );
123
+ } else {
124
+ nodeArgs.push(
125
+ "--loader",
126
+ pathToFileURL(join(pkgRoot, "dist", "loader.js")).href
127
+ );
128
+ }
129
+
130
+ const runnerPath = join(pkgRoot, "dist", "runner.js");
131
+ const projectRoot = dirname(configPath);
132
+
133
+ const child = spawn(
134
+ process.execPath,
135
+ [...nodeArgs, runnerPath, configPath, ...process.argv.slice(2)],
136
+ {
137
+ stdio: "inherit",
138
+ env: {
139
+ ...process.env,
140
+ X_ROOT_DIR: projectRoot,
141
+ },
142
+ }
143
+ );
144
+
145
+ process.on("SIGTERM", () => child.kill("SIGTERM"));
146
+ process.on("SIGINT", () => child.kill("SIGINT"));
147
+
148
+ child.on("close", (code, signal) => {
149
+ if (signal) {
150
+ process.kill(process.pid, signal);
151
+ } else {
152
+ process.exit(code ?? 1);
153
+ }
154
+ });
@@ -0,0 +1,40 @@
1
+ import { CommandOutput } from "./shared.js";
2
+ export declare const REST_SYMBOL: unique symbol;
3
+ export declare function buildRunParts(strings: TemplateStringsArray, values: unknown[]): (string | symbol)[];
4
+ export declare function expandRestSymbol(parts: (string | symbol)[], restArgs: string[]): string[];
5
+ export declare function spawnCommand(parts: string[], options: {
6
+ stdio: "inherit" | "pipe";
7
+ cwd?: string;
8
+ }): Promise<CommandOutput>;
9
+ export interface PathHelper {
10
+ (sub?: string): string;
11
+ [Symbol.toPrimitive](): string;
12
+ toString(): string;
13
+ }
14
+ export declare function createPathHelper(basePath: string): PathHelper;
15
+ export declare class ExecutionContext {
16
+ private _args;
17
+ private _options;
18
+ private _restArgs;
19
+ private _rootDir;
20
+ private _userDir;
21
+ private _cwd;
22
+ private _rootHelper;
23
+ private _userHelper;
24
+ constructor(args: Record<string, string>, options: Record<string, string | true>, restArgs: string[], rootDir: string, userDir: string, initialCwd: string);
25
+ arg(name: string): string | null;
26
+ option(name: string): string | true | null;
27
+ run(stringsOrParts: TemplateStringsArray | unknown, ...values: unknown[]): Promise<CommandOutput>;
28
+ mustRun(stringsOrParts: TemplateStringsArray | unknown, ...values: unknown[]): Promise<CommandOutput>;
29
+ silent(stringsOrParts: TemplateStringsArray | unknown, ...values: unknown[]): Promise<CommandOutput>;
30
+ mustSilent(stringsOrParts: TemplateStringsArray | unknown, ...values: unknown[]): Promise<CommandOutput>;
31
+ info(msg: string): void;
32
+ warn(msg: string): void;
33
+ error(msg: string): void;
34
+ confirm(msg: string): Promise<boolean>;
35
+ prompt(msg: string): Promise<string>;
36
+ get root(): PathHelper;
37
+ get user(): PathHelper;
38
+ cd(path: string): void;
39
+ }
40
+ //# sourceMappingURL=context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,aAAa,EAAgC,MAAM,aAAa,CAAC;AAG1E,eAAO,MAAM,WAAW,EAAE,OAAO,MAAuB,CAAC;AAGzD,wBAAgB,aAAa,CAAC,OAAO,EAAE,oBAAoB,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,CA4BnG;AAGD,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAUzF;AAGD,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE;IAAE,KAAK,EAAE,SAAS,GAAG,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,aAAa,CAAC,CA6C1H;AAGD,MAAM,WAAW,UAAU;IACzB,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACvB,CAAC,MAAM,CAAC,WAAW,CAAC,IAAI,MAAM,CAAC;IAC/B,QAAQ,IAAI,MAAM,CAAC;CACpB;AAED,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,UAAU,CAK7D;AAGD,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,KAAK,CAAyB;IACtC,OAAO,CAAC,QAAQ,CAAgC;IAChD,OAAO,CAAC,SAAS,CAAW;IAC5B,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,IAAI,CAAS;IACrB,OAAO,CAAC,WAAW,CAAa;IAChC,OAAO,CAAC,WAAW,CAAa;gBAG9B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC5B,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC,EACtC,QAAQ,EAAE,MAAM,EAAE,EAClB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,MAAM;IAYpB,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAIhC,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,GAAG,IAAI;IAI1C,GAAG,CAAC,cAAc,EAAE,oBAAoB,GAAG,OAAO,EAAE,GAAG,MAAM,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,aAAa,CAAC;IAW3F,OAAO,CAAC,cAAc,EAAE,oBAAoB,GAAG,OAAO,EAAE,GAAG,MAAM,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,aAAa,CAAC;IAK3G,MAAM,CAAC,cAAc,EAAE,oBAAoB,GAAG,OAAO,EAAE,GAAG,MAAM,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,aAAa,CAAC;IAW9F,UAAU,CAAC,cAAc,EAAE,oBAAoB,GAAG,OAAO,EAAE,GAAG,MAAM,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,aAAa,CAAC;IAK9G,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAIvB,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAIvB,KAAK,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAIlB,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAetC,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAc1C,IAAI,IAAI,IAAI,UAAU,CAErB;IAED,IAAI,IAAI,IAAI,UAAU,CAErB;IAED,EAAE,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;CAGvB"}