azcodr 2.0.0 → 2.1.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/.agents/hooks.json +3 -3
- package/.github/workflows/publish.yml +0 -4
- package/bin/azcodr.js +9 -4
- package/lib/cli-parse.d.ts +32 -0
- package/lib/cli-parse.d.ts.map +1 -0
- package/lib/cli-parse.js +45 -41
- package/lib/cli-parse.js.map +1 -0
- package/lib/cli-target.d.ts +66 -0
- package/lib/cli-target.d.ts.map +1 -0
- package/lib/cli-target.js +89 -96
- package/lib/cli-target.js.map +1 -0
- package/lib/cli.d.ts +40 -0
- package/lib/cli.d.ts.map +1 -0
- package/lib/cli.js +122 -136
- package/lib/cli.js.map +1 -0
- package/lib/errors.d.ts +39 -0
- package/lib/errors.d.ts.map +1 -0
- package/lib/errors.js +16 -18
- package/lib/errors.js.map +1 -0
- package/lib/git.d.ts +15 -0
- package/lib/git.d.ts.map +1 -0
- package/lib/git.js +25 -22
- package/lib/git.js.map +1 -0
- package/lib/guards.d.ts +35 -0
- package/lib/guards.d.ts.map +1 -0
- package/lib/guards.js +62 -63
- package/lib/guards.js.map +1 -0
- package/lib/index.d.ts +6 -199
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +4 -5
- package/lib/index.js.map +1 -0
- package/lib/links.d.ts +28 -0
- package/lib/links.d.ts.map +1 -0
- package/lib/links.js +105 -99
- package/lib/links.js.map +1 -0
- package/lib/permissions.d.ts +9 -0
- package/lib/permissions.d.ts.map +1 -0
- package/lib/permissions.js +36 -36
- package/lib/permissions.js.map +1 -0
- package/lib/repo.d.ts +20 -0
- package/lib/repo.d.ts.map +1 -0
- package/lib/repo.js +73 -71
- package/lib/repo.js.map +1 -0
- package/lib/scaffold.d.ts +80 -0
- package/lib/scaffold.d.ts.map +1 -0
- package/lib/scaffold.js +159 -196
- package/lib/scaffold.js.map +1 -0
- package/memory.md +16 -0
- package/package.json +13 -3
- package/scripts/test_coverage.js +2 -2
- package/scripts/validate/adr.js +11 -7
- package/scripts/validate/io.js +7 -9
- package/scripts/validate/links.js +6 -7
- package/scripts/validate/parity.js +5 -7
- package/scripts/validate/root.js +6 -7
- package/scripts/validate/rules.js +7 -9
- package/scripts/validate/skills.js +8 -10
- package/scripts/validate/text.js +3 -5
- package/scripts/validate-cli.js +1 -2
- package/scripts/validate.js +37 -19
- package/src/cli-parse.ts +77 -0
- package/src/cli-target.ts +167 -0
- package/src/cli.ts +240 -0
- package/src/errors.ts +35 -0
- package/src/git.ts +34 -0
- package/src/guards.ts +101 -0
- package/src/index.ts +39 -0
- package/src/links.ts +139 -0
- package/src/permissions.ts +42 -0
- package/src/repo.ts +94 -0
- package/src/scaffold.ts +273 -0
package/.agents/hooks.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"safety-guard": {
|
|
3
|
-
"enabled":
|
|
3
|
+
"enabled": false,
|
|
4
4
|
"PreToolUse": [
|
|
5
5
|
{
|
|
6
6
|
"matcher": "run_command",
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
]
|
|
16
16
|
},
|
|
17
17
|
"post-tool-lint": {
|
|
18
|
-
"enabled":
|
|
18
|
+
"enabled": false,
|
|
19
19
|
"PostToolUse": [
|
|
20
20
|
{
|
|
21
21
|
"matcher": "run_command",
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
]
|
|
31
31
|
},
|
|
32
32
|
"stop-verifier": {
|
|
33
|
-
"enabled":
|
|
33
|
+
"enabled": false,
|
|
34
34
|
"Stop": [
|
|
35
35
|
{
|
|
36
36
|
"type": "command",
|
|
@@ -181,10 +181,6 @@ jobs:
|
|
|
181
181
|
publish-jsr:
|
|
182
182
|
name: Publish to JSR
|
|
183
183
|
needs: verify
|
|
184
|
-
# Requires a native ESM entrypoint. The npm package is CommonJS, which JSR
|
|
185
|
-
# explicitly forbids ("You cannot publish CommonJS modules"). Disabled with
|
|
186
|
-
# a stated reason rather than failing every release.
|
|
187
|
-
if: false
|
|
188
184
|
runs-on: ubuntu-24.04
|
|
189
185
|
timeout-minutes: 15
|
|
190
186
|
steps:
|
package/bin/azcodr.js
CHANGED
|
@@ -1,14 +1,19 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
'use strict';
|
|
3
2
|
|
|
4
3
|
/**
|
|
5
4
|
* CLI entry point. All logic lives in lib/cli.js so it is unit-testable;
|
|
6
5
|
* this file only wires the process boundary (argv in, exit code out).
|
|
7
6
|
*/
|
|
8
|
-
|
|
7
|
+
import fs from 'node:fs';
|
|
8
|
+
import path from 'node:path';
|
|
9
|
+
import process from 'node:process';
|
|
10
|
+
import * as cli from '../lib/cli.js';
|
|
9
11
|
|
|
10
|
-
|
|
12
|
+
const isDirectRun = process.argv[1] ? fs.realpathSync(path.resolve(process.argv[1])).toLowerCase() === fs.realpathSync(import.meta.filename).toLowerCase() : false;
|
|
13
|
+
|
|
14
|
+
if (isDirectRun) {
|
|
11
15
|
cli.main();
|
|
12
16
|
}
|
|
13
17
|
|
|
14
|
-
|
|
18
|
+
export * from '../lib/cli.js';
|
|
19
|
+
export default cli;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Argument parsing for the azcodr CLI.
|
|
3
|
+
*
|
|
4
|
+
* Table-driven: every boolean flag is one Map entry, so adding a flag cannot
|
|
5
|
+
* raise the complexity of the parser itself.
|
|
6
|
+
*/
|
|
7
|
+
export interface CliParsedOptions {
|
|
8
|
+
targetDir: string | null;
|
|
9
|
+
force: boolean;
|
|
10
|
+
noGit: boolean;
|
|
11
|
+
dryRun: boolean;
|
|
12
|
+
silent: boolean;
|
|
13
|
+
terminal: 'help' | 'version' | 'unknown-flag' | 'extra-arg' | null;
|
|
14
|
+
message?: string;
|
|
15
|
+
}
|
|
16
|
+
export type BooleanFlagKey = 'force' | 'noGit' | 'dryRun' | 'silent';
|
|
17
|
+
export declare function emptyOptions(): Omit<CliParsedOptions, 'terminal' | 'message'>;
|
|
18
|
+
export declare const BOOLEAN_FLAGS: Map<string, BooleanFlagKey>;
|
|
19
|
+
export interface ArgOutcome {
|
|
20
|
+
terminal: 'help' | 'version' | 'unknown-flag' | 'extra-arg' | null;
|
|
21
|
+
message?: string;
|
|
22
|
+
}
|
|
23
|
+
export declare function applyArg(state: Omit<CliParsedOptions, 'terminal' | 'message'>, arg: string): ArgOutcome;
|
|
24
|
+
export declare function parseArgs(rawArgs: readonly string[]): CliParsedOptions;
|
|
25
|
+
declare const _default: {
|
|
26
|
+
emptyOptions: typeof emptyOptions;
|
|
27
|
+
BOOLEAN_FLAGS: Map<string, BooleanFlagKey>;
|
|
28
|
+
applyArg: typeof applyArg;
|
|
29
|
+
parseArgs: typeof parseArgs;
|
|
30
|
+
};
|
|
31
|
+
export default _default;
|
|
32
|
+
//# sourceMappingURL=cli-parse.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli-parse.d.ts","sourceRoot":"","sources":["../src/cli-parse.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,WAAW,gBAAgB;IAC/B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,KAAK,EAAE,OAAO,CAAC;IACf,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,OAAO,CAAC;IAChB,MAAM,EAAE,OAAO,CAAC;IAChB,QAAQ,EAAE,MAAM,GAAG,SAAS,GAAG,cAAc,GAAG,WAAW,GAAG,IAAI,CAAC;IACnE,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,MAAM,cAAc,GAAG,OAAO,GAAG,OAAO,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAErE,wBAAgB,YAAY,IAAI,IAAI,CAAC,gBAAgB,EAAE,UAAU,GAAG,SAAS,CAAC,CAE7E;AAED,eAAO,MAAM,aAAa,6BAQxB,CAAC;AAEH,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,MAAM,GAAG,SAAS,GAAG,cAAc,GAAG,WAAW,GAAG,IAAI,CAAC;IACnE,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,wBAAgB,QAAQ,CACtB,KAAK,EAAE,IAAI,CAAC,gBAAgB,EAAE,UAAU,GAAG,SAAS,CAAC,EACrD,GAAG,EAAE,MAAM,GACV,UAAU,CAsBZ;AAED,wBAAgB,SAAS,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,GAAG,gBAAgB,CAStE;;;;;;;AAED,wBAAoE"}
|
package/lib/cli-parse.js
CHANGED
|
@@ -1,51 +1,55 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
1
|
/**
|
|
4
2
|
* Argument parsing for the azcodr CLI.
|
|
5
3
|
*
|
|
6
4
|
* Table-driven: every boolean flag is one Map entry, so adding a flag cannot
|
|
7
5
|
* raise the complexity of the parser itself.
|
|
8
6
|
*/
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
return { targetDir: null, force: false, noGit: false, dryRun: false, silent: false };
|
|
7
|
+
export function emptyOptions() {
|
|
8
|
+
return { targetDir: null, force: false, noGit: false, dryRun: false, silent: false };
|
|
12
9
|
}
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
['--silent', 'silent']
|
|
10
|
+
export const BOOLEAN_FLAGS = new Map([
|
|
11
|
+
['-f', 'force'],
|
|
12
|
+
['--force', 'force'],
|
|
13
|
+
['--no-git', 'noGit'],
|
|
14
|
+
['-d', 'dryRun'],
|
|
15
|
+
['--dry-run', 'dryRun'],
|
|
16
|
+
['-s', 'silent'],
|
|
17
|
+
['--silent', 'silent']
|
|
22
18
|
]);
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
19
|
+
export function applyArg(state, arg) {
|
|
20
|
+
if (arg === '-h' || arg === '--help')
|
|
21
|
+
return { terminal: 'help' };
|
|
22
|
+
if (arg === '-v' || arg === '--version')
|
|
23
|
+
return { terminal: 'version' };
|
|
24
|
+
const flag = BOOLEAN_FLAGS.get(arg);
|
|
25
|
+
if (flag !== undefined) {
|
|
26
|
+
state[flag] = true;
|
|
27
|
+
return { terminal: null };
|
|
28
|
+
}
|
|
29
|
+
if (arg.startsWith('-')) {
|
|
30
|
+
return {
|
|
31
|
+
terminal: 'unknown-flag',
|
|
32
|
+
message: `Unknown argument '${arg}'. Run 'npx azcodr --help' for available options.`
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
if (!state.targetDir) {
|
|
36
|
+
state.targetDir = arg;
|
|
37
|
+
return { terminal: null };
|
|
38
|
+
}
|
|
39
|
+
return {
|
|
40
|
+
terminal: 'extra-arg',
|
|
41
|
+
message: `Unexpected argument '${arg}'. Run 'npx azcodr --help' for available options.`
|
|
42
|
+
};
|
|
40
43
|
}
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
44
|
+
export function parseArgs(rawArgs) {
|
|
45
|
+
const state = emptyOptions();
|
|
46
|
+
for (const arg of rawArgs) {
|
|
47
|
+
const outcome = applyArg(state, arg);
|
|
48
|
+
if (outcome.terminal !== null) {
|
|
49
|
+
return { ...state, terminal: outcome.terminal, message: outcome.message };
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
return { ...state, terminal: null, message: undefined };
|
|
49
53
|
}
|
|
50
|
-
|
|
51
|
-
|
|
54
|
+
export default { emptyOptions, BOOLEAN_FLAGS, applyArg, parseArgs };
|
|
55
|
+
//# sourceMappingURL=cli-parse.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli-parse.js","sourceRoot":"","sources":["../src/cli-parse.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAcH,MAAM,UAAU,YAAY;IAC1B,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;AACvF,CAAC;AAED,MAAM,CAAC,MAAM,aAAa,GAAG,IAAI,GAAG,CAAyB;IAC3D,CAAC,IAAI,EAAE,OAAO,CAAC;IACf,CAAC,SAAS,EAAE,OAAO,CAAC;IACpB,CAAC,UAAU,EAAE,OAAO,CAAC;IACrB,CAAC,IAAI,EAAE,QAAQ,CAAC;IAChB,CAAC,WAAW,EAAE,QAAQ,CAAC;IACvB,CAAC,IAAI,EAAE,QAAQ,CAAC;IAChB,CAAC,UAAU,EAAE,QAAQ,CAAC;CACvB,CAAC,CAAC;AAOH,MAAM,UAAU,QAAQ,CACtB,KAAqD,EACrD,GAAW;IAEX,IAAI,GAAG,KAAK,IAAI,IAAI,GAAG,KAAK,QAAQ;QAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC;IAClE,IAAI,GAAG,KAAK,IAAI,IAAI,GAAG,KAAK,WAAW;QAAE,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC;IACxE,MAAM,IAAI,GAAG,aAAa,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACpC,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;QACvB,KAAK,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;QACnB,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;IAC5B,CAAC;IACD,IAAI,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QACxB,OAAO;YACL,QAAQ,EAAE,cAAc;YACxB,OAAO,EAAE,qBAAqB,GAAG,mDAAmD;SACrF,CAAC;IACJ,CAAC;IACD,IAAI,CAAC,KAAK,CAAC,SAAS,EAAE,CAAC;QACrB,KAAK,CAAC,SAAS,GAAG,GAAG,CAAC;QACtB,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;IAC5B,CAAC;IACD,OAAO;QACL,QAAQ,EAAE,WAAW;QACrB,OAAO,EAAE,wBAAwB,GAAG,mDAAmD;KACxF,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,OAA0B;IAClD,MAAM,KAAK,GAAG,YAAY,EAAE,CAAC;IAC7B,KAAK,MAAM,GAAG,IAAI,OAAO,EAAE,CAAC;QAC1B,MAAM,OAAO,GAAG,QAAQ,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;QACrC,IAAI,OAAO,CAAC,QAAQ,KAAK,IAAI,EAAE,CAAC;YAC9B,OAAO,EAAE,GAAG,KAAK,EAAE,QAAQ,EAAE,OAAO,CAAC,QAAQ,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,CAAC;QAC5E,CAAC;IACH,CAAC;IACD,OAAO,EAAE,GAAG,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,OAAO,EAAE,SAAS,EAAE,CAAC;AAC1D,CAAC;AAED,eAAe,EAAE,YAAY,EAAE,aAAa,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
export interface AskQuestionOptions {
|
|
2
|
+
input?: NodeJS.ReadableStream;
|
|
3
|
+
output?: NodeJS.WritableStream;
|
|
4
|
+
}
|
|
5
|
+
export declare function askQuestion(query: string, { input, output }?: AskQuestionOptions): Promise<string>;
|
|
6
|
+
export interface PromptIo {
|
|
7
|
+
stdin: NodeJS.ReadStream | (NodeJS.ReadableStream & {
|
|
8
|
+
isTTY?: boolean;
|
|
9
|
+
});
|
|
10
|
+
stdout: NodeJS.WriteStream | NodeJS.WritableStream;
|
|
11
|
+
}
|
|
12
|
+
export declare function promptForTargetDir(io: PromptIo): Promise<string>;
|
|
13
|
+
export declare function rejectBadTarget(resolvedTarget: string, templateDir: string): string | null;
|
|
14
|
+
export interface ResolveTargetIo extends PromptIo {
|
|
15
|
+
cwd: string;
|
|
16
|
+
templateDir: string;
|
|
17
|
+
}
|
|
18
|
+
export interface ResolveTargetResult {
|
|
19
|
+
resolvedTarget: string;
|
|
20
|
+
chosen: string;
|
|
21
|
+
error: string | null;
|
|
22
|
+
}
|
|
23
|
+
export declare function resolveTargetDir(targetDir: string | null, io: ResolveTargetIo): Promise<ResolveTargetResult>;
|
|
24
|
+
export type TargetDirectoryStatus = 'missing' | 'not-a-directory' | 'empty' | 'non-empty';
|
|
25
|
+
export interface TargetStatusResult {
|
|
26
|
+
status: TargetDirectoryStatus;
|
|
27
|
+
count: number;
|
|
28
|
+
}
|
|
29
|
+
export declare function targetStatus(resolvedTarget: string): TargetStatusResult;
|
|
30
|
+
export interface ConfirmOverwriteIo extends PromptIo {
|
|
31
|
+
out: (msg: string) => void;
|
|
32
|
+
}
|
|
33
|
+
export interface ConfirmOverwriteResult {
|
|
34
|
+
confirmed: boolean;
|
|
35
|
+
aborted: boolean;
|
|
36
|
+
}
|
|
37
|
+
export declare function confirmOverwrite(targetDir: string, count: number, io: ConfirmOverwriteIo): Promise<ConfirmOverwriteResult>;
|
|
38
|
+
export interface EnsureWritableOptions {
|
|
39
|
+
chosen: string;
|
|
40
|
+
resolvedTarget: string;
|
|
41
|
+
force: boolean;
|
|
42
|
+
io: ConfirmOverwriteIo & {
|
|
43
|
+
err: (msg: string) => void;
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
export interface EnsureWritableResult {
|
|
47
|
+
force?: boolean;
|
|
48
|
+
exitCode?: number;
|
|
49
|
+
message?: string | null;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Ensures the target may be written. Returns { force } on success or
|
|
53
|
+
* { exitCode, message? } when the CLI must stop before scaffolding.
|
|
54
|
+
*/
|
|
55
|
+
export declare function ensureWritableTarget(options: EnsureWritableOptions): Promise<EnsureWritableResult>;
|
|
56
|
+
declare const _default: {
|
|
57
|
+
askQuestion: typeof askQuestion;
|
|
58
|
+
promptForTargetDir: typeof promptForTargetDir;
|
|
59
|
+
rejectBadTarget: typeof rejectBadTarget;
|
|
60
|
+
resolveTargetDir: typeof resolveTargetDir;
|
|
61
|
+
targetStatus: typeof targetStatus;
|
|
62
|
+
confirmOverwrite: typeof confirmOverwrite;
|
|
63
|
+
ensureWritableTarget: typeof ensureWritableTarget;
|
|
64
|
+
};
|
|
65
|
+
export default _default;
|
|
66
|
+
//# sourceMappingURL=cli-target.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli-target.d.ts","sourceRoot":"","sources":["../src/cli-target.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,kBAAkB;IACjC,KAAK,CAAC,EAAE,MAAM,CAAC,cAAc,CAAC;IAC9B,MAAM,CAAC,EAAE,MAAM,CAAC,cAAc,CAAC;CAChC;AAED,wBAAgB,WAAW,CACzB,KAAK,EAAE,MAAM,EACb,EAAE,KAAqB,EAAE,MAAuB,EAAE,GAAE,kBAAuB,GAC1E,OAAO,CAAC,MAAM,CAAC,CAmBjB;AAED,MAAM,WAAW,QAAQ;IACvB,KAAK,EAAE,MAAM,CAAC,UAAU,GAAG,CAAC,MAAM,CAAC,cAAc,GAAG;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;IACzE,MAAM,EAAE,MAAM,CAAC,WAAW,GAAG,MAAM,CAAC,cAAc,CAAC;CACpD;AAED,wBAAsB,kBAAkB,CAAC,EAAE,EAAE,QAAQ,GAAG,OAAO,CAAC,MAAM,CAAC,CAQtE;AAED,wBAAgB,eAAe,CAAC,cAAc,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAQ1F;AAED,MAAM,WAAW,eAAgB,SAAQ,QAAQ;IAC/C,GAAG,EAAE,MAAM,CAAC;IACZ,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,mBAAmB;IAClC,cAAc,EAAE,MAAM,CAAC;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CACtB;AAED,wBAAsB,gBAAgB,CACpC,SAAS,EAAE,MAAM,GAAG,IAAI,EACxB,EAAE,EAAE,eAAe,GAClB,OAAO,CAAC,mBAAmB,CAAC,CAO9B;AAED,MAAM,MAAM,qBAAqB,GAAG,SAAS,GAAG,iBAAiB,GAAG,OAAO,GAAG,WAAW,CAAC;AAE1F,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,qBAAqB,CAAC;IAC9B,KAAK,EAAE,MAAM,CAAC;CACf;AAED,wBAAgB,YAAY,CAAC,cAAc,EAAE,MAAM,GAAG,kBAAkB,CAKvE;AAED,MAAM,WAAW,kBAAmB,SAAQ,QAAQ;IAClD,GAAG,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;CAC5B;AAED,MAAM,WAAW,sBAAsB;IACrC,SAAS,EAAE,OAAO,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,wBAAsB,gBAAgB,CACpC,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,MAAM,EACb,EAAE,EAAE,kBAAkB,GACrB,OAAO,CAAC,sBAAsB,CAAC,CAYjC;AAED,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,MAAM,CAAC;IACf,cAAc,EAAE,MAAM,CAAC;IACvB,KAAK,EAAE,OAAO,CAAC;IACf,EAAE,EAAE,kBAAkB,GAAG;QAAE,GAAG,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAA;KAAE,CAAC;CACzD;AAED,MAAM,WAAW,oBAAoB;IACnC,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB;AAED;;;GAGG;AACH,wBAAsB,oBAAoB,CACxC,OAAO,EAAE,qBAAqB,GAC7B,OAAO,CAAC,oBAAoB,CAAC,CAa/B;;;;;;;;;;AAED,wBAQE"}
|
package/lib/cli-target.js
CHANGED
|
@@ -1,109 +1,102 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import readline from 'node:readline';
|
|
3
|
+
import fs from 'node:fs';
|
|
4
|
+
import process from 'node:process';
|
|
5
|
+
import { isProtectedTarget } from './guards.js';
|
|
6
|
+
export function askQuestion(query, { input = process.stdin, output = process.stdout } = {}) {
|
|
7
|
+
const rl = readline.createInterface({ input, output });
|
|
8
|
+
return new Promise((resolve) => {
|
|
9
|
+
let resolved = false;
|
|
10
|
+
rl.question(query, (answer) => {
|
|
11
|
+
if (!resolved) {
|
|
12
|
+
resolved = true;
|
|
13
|
+
rl.close();
|
|
14
|
+
resolve(answer.trim());
|
|
15
|
+
}
|
|
16
|
+
});
|
|
17
|
+
rl.on('close', () => {
|
|
18
|
+
if (!resolved) {
|
|
19
|
+
resolved = true;
|
|
20
|
+
resolve('');
|
|
21
|
+
}
|
|
22
|
+
});
|
|
19
23
|
});
|
|
20
|
-
rl.on('close', () => {
|
|
21
|
-
if (!resolved) {
|
|
22
|
-
resolved = true;
|
|
23
|
-
resolve('');
|
|
24
|
-
}
|
|
25
|
-
});
|
|
26
|
-
});
|
|
27
24
|
}
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
25
|
+
export async function promptForTargetDir(io) {
|
|
26
|
+
const { stdin, stdout } = io;
|
|
27
|
+
if (!stdin.isTTY)
|
|
28
|
+
return '.';
|
|
29
|
+
const answer = await askQuestion('? Where would you like to initialize your project? (./) ', {
|
|
30
|
+
input: stdin,
|
|
31
|
+
output: stdout
|
|
32
|
+
});
|
|
33
|
+
return answer || '.';
|
|
37
34
|
}
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
// validateTarget, so this is defence in depth, not the sole check.
|
|
47
|
-
if (isProtectedTarget(resolvedTarget, { templateDir })) {
|
|
48
|
-
return `Refusing to scaffold into protected directory: ${resolvedTarget}. Choose a project subdirectory instead.`;
|
|
49
|
-
}
|
|
50
|
-
return null;
|
|
35
|
+
export function rejectBadTarget(resolvedTarget, templateDir) {
|
|
36
|
+
if (resolvedTarget === templateDir) {
|
|
37
|
+
return `Cannot scaffold into the template directory itself: ${resolvedTarget}`;
|
|
38
|
+
}
|
|
39
|
+
if (isProtectedTarget(resolvedTarget, { templateDir })) {
|
|
40
|
+
return `Refusing to scaffold into protected directory: ${resolvedTarget}. Choose a project subdirectory instead.`;
|
|
41
|
+
}
|
|
42
|
+
return null;
|
|
51
43
|
}
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
44
|
+
export async function resolveTargetDir(targetDir, io) {
|
|
45
|
+
const { cwd, templateDir } = io;
|
|
46
|
+
const chosen = targetDir || (await promptForTargetDir(io));
|
|
47
|
+
const resolvedTarget = path.resolve(cwd, chosen);
|
|
48
|
+
const rejection = rejectBadTarget(resolvedTarget, templateDir);
|
|
49
|
+
if (rejection !== null)
|
|
50
|
+
return { resolvedTarget, chosen, error: rejection };
|
|
51
|
+
return { resolvedTarget, chosen, error: null };
|
|
60
52
|
}
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
53
|
+
export function targetStatus(resolvedTarget) {
|
|
54
|
+
if (!fs.existsSync(resolvedTarget))
|
|
55
|
+
return { status: 'missing', count: 0 };
|
|
56
|
+
if (!fs.statSync(resolvedTarget).isDirectory())
|
|
57
|
+
return { status: 'not-a-directory', count: 0 };
|
|
58
|
+
const count = fs.readdirSync(resolvedTarget).length;
|
|
59
|
+
return { status: count === 0 ? 'empty' : 'non-empty', count };
|
|
67
60
|
}
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
return { confirmed: false, aborted: true };
|
|
79
|
-
}
|
|
80
|
-
return { confirmed: true, aborted: false };
|
|
61
|
+
export async function confirmOverwrite(targetDir, count, io) {
|
|
62
|
+
const { stdin, stdout, out } = io;
|
|
63
|
+
if (!stdin.isTTY)
|
|
64
|
+
return { confirmed: false, aborted: false };
|
|
65
|
+
const confirm = await askQuestion(`⚠️ Target directory '${targetDir}' is not empty (${count} items). Continue? (y/N) `, { input: stdin, output: stdout });
|
|
66
|
+
if (confirm.toLowerCase() !== 'y' && confirm.toLowerCase() !== 'yes') {
|
|
67
|
+
out('Scaffolding aborted.');
|
|
68
|
+
return { confirmed: false, aborted: true };
|
|
69
|
+
}
|
|
70
|
+
return { confirmed: true, aborted: false };
|
|
81
71
|
}
|
|
82
|
-
|
|
83
72
|
/**
|
|
84
73
|
* Ensures the target may be written. Returns { force } on success or
|
|
85
74
|
* { exitCode, message? } when the CLI must stop before scaffolding.
|
|
86
75
|
*/
|
|
87
|
-
async function ensureWritableTarget(
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
76
|
+
export async function ensureWritableTarget(options) {
|
|
77
|
+
const { chosen, resolvedTarget, force, io } = options;
|
|
78
|
+
const { err } = io;
|
|
79
|
+
const { status, count } = targetStatus(resolvedTarget);
|
|
80
|
+
if (status === 'missing' || status === 'empty' || force)
|
|
81
|
+
return { force };
|
|
82
|
+
if (status === 'not-a-directory') {
|
|
83
|
+
return { exitCode: 1, message: `Target '${resolvedTarget}' already exists and is not a directory.` };
|
|
84
|
+
}
|
|
85
|
+
const { confirmed, aborted } = await confirmOverwrite(chosen, count, io);
|
|
86
|
+
if (aborted)
|
|
87
|
+
return { exitCode: 0, message: null };
|
|
88
|
+
if (confirmed)
|
|
89
|
+
return { force: true };
|
|
90
|
+
err(`Target directory '${resolvedTarget}' is not empty. Use --force to proceed.`);
|
|
91
|
+
return { exitCode: 1, message: null };
|
|
99
92
|
}
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
ensureWritableTarget
|
|
93
|
+
export default {
|
|
94
|
+
askQuestion,
|
|
95
|
+
promptForTargetDir,
|
|
96
|
+
rejectBadTarget,
|
|
97
|
+
resolveTargetDir,
|
|
98
|
+
targetStatus,
|
|
99
|
+
confirmOverwrite,
|
|
100
|
+
ensureWritableTarget
|
|
109
101
|
};
|
|
102
|
+
//# sourceMappingURL=cli-target.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli-target.js","sourceRoot":"","sources":["../src/cli-target.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,QAAQ,MAAM,eAAe,CAAC;AACrC,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,OAAO,MAAM,cAAc,CAAC;AACnC,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAOhD,MAAM,UAAU,WAAW,CACzB,KAAa,EACb,EAAE,KAAK,GAAG,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,KAAyB,EAAE;IAE3E,MAAM,EAAE,GAAG,QAAQ,CAAC,eAAe,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;IAEvD,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,IAAI,QAAQ,GAAG,KAAK,CAAC;QACrB,EAAE,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC,MAAc,EAAE,EAAE;YACpC,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACd,QAAQ,GAAG,IAAI,CAAC;gBAChB,EAAE,CAAC,KAAK,EAAE,CAAC;gBACX,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;YACzB,CAAC;QACH,CAAC,CAAC,CAAC;QACH,EAAE,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE;YAClB,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACd,QAAQ,GAAG,IAAI,CAAC;gBAChB,OAAO,CAAC,EAAE,CAAC,CAAC;YACd,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC;AAOD,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,EAAY;IACnD,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC;IAC7B,IAAI,CAAC,KAAK,CAAC,KAAK;QAAE,OAAO,GAAG,CAAC;IAC7B,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,0DAA0D,EAAE;QAC3F,KAAK,EAAE,KAAK;QACZ,MAAM,EAAE,MAAM;KACf,CAAC,CAAC;IACH,OAAO,MAAM,IAAI,GAAG,CAAC;AACvB,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,cAAsB,EAAE,WAAmB;IACzE,IAAI,cAAc,KAAK,WAAW,EAAE,CAAC;QACnC,OAAO,uDAAuD,cAAc,EAAE,CAAC;IACjF,CAAC;IACD,IAAI,iBAAiB,CAAC,cAAc,EAAE,EAAE,WAAW,EAAE,CAAC,EAAE,CAAC;QACvD,OAAO,kDAAkD,cAAc,0CAA0C,CAAC;IACpH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAaD,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,SAAwB,EACxB,EAAmB;IAEnB,MAAM,EAAE,GAAG,EAAE,WAAW,EAAE,GAAG,EAAE,CAAC;IAChC,MAAM,MAAM,GAAG,SAAS,IAAI,CAAC,MAAM,kBAAkB,CAAC,EAAE,CAAC,CAAC,CAAC;IAC3D,MAAM,cAAc,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;IACjD,MAAM,SAAS,GAAG,eAAe,CAAC,cAAc,EAAE,WAAW,CAAC,CAAC;IAC/D,IAAI,SAAS,KAAK,IAAI;QAAE,OAAO,EAAE,cAAc,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC;IAC5E,OAAO,EAAE,cAAc,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;AACjD,CAAC;AASD,MAAM,UAAU,YAAY,CAAC,cAAsB;IACjD,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,cAAc,CAAC;QAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC;IAC3E,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAC,WAAW,EAAE;QAAE,OAAO,EAAE,MAAM,EAAE,iBAAiB,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC;IAC/F,MAAM,KAAK,GAAG,EAAE,CAAC,WAAW,CAAC,cAAc,CAAC,CAAC,MAAM,CAAC;IACpD,OAAO,EAAE,MAAM,EAAE,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,WAAW,EAAE,KAAK,EAAE,CAAC;AAChE,CAAC;AAWD,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,SAAiB,EACjB,KAAa,EACb,EAAsB;IAEtB,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC;IAClC,IAAI,CAAC,KAAK,CAAC,KAAK;QAAE,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;IAC9D,MAAM,OAAO,GAAG,MAAM,WAAW,CAC/B,yBAAyB,SAAS,mBAAmB,KAAK,2BAA2B,EACrF,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,CACjC,CAAC;IACF,IAAI,OAAO,CAAC,WAAW,EAAE,KAAK,GAAG,IAAI,OAAO,CAAC,WAAW,EAAE,KAAK,KAAK,EAAE,CAAC;QACrE,GAAG,CAAC,sBAAsB,CAAC,CAAC;QAC5B,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IAC7C,CAAC;IACD,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;AAC7C,CAAC;AAeD;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,OAA8B;IAE9B,MAAM,EAAE,MAAM,EAAE,cAAc,EAAE,KAAK,EAAE,EAAE,EAAE,GAAG,OAAO,CAAC;IACtD,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC;IACnB,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,YAAY,CAAC,cAAc,CAAC,CAAC;IACvD,IAAI,MAAM,KAAK,SAAS,IAAI,MAAM,KAAK,OAAO,IAAI,KAAK;QAAE,OAAO,EAAE,KAAK,EAAE,CAAC;IAC1E,IAAI,MAAM,KAAK,iBAAiB,EAAE,CAAC;QACjC,OAAO,EAAE,QAAQ,EAAE,CAAC,EAAE,OAAO,EAAE,WAAW,cAAc,0CAA0C,EAAE,CAAC;IACvG,CAAC;IACD,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,GAAG,MAAM,gBAAgB,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC;IACzE,IAAI,OAAO;QAAE,OAAO,EAAE,QAAQ,EAAE,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IACnD,IAAI,SAAS;QAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;IACtC,GAAG,CAAC,qBAAqB,cAAc,yCAAyC,CAAC,CAAC;IAClF,OAAO,EAAE,QAAQ,EAAE,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;AACxC,CAAC;AAED,eAAe;IACb,WAAW;IACX,kBAAkB;IAClB,eAAe;IACf,gBAAgB;IAChB,YAAY;IACZ,gBAAgB;IAChB,oBAAoB;CACrB,CAAC"}
|
package/lib/cli.d.ts
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type { ScaffoldOptions, ScaffoldResult } from './scaffold.js';
|
|
2
|
+
import { askQuestion } from './cli-target.js';
|
|
3
|
+
export declare function printHelp(out?: (msg: string) => void): void;
|
|
4
|
+
export declare function printVersion(out?: (msg: string) => void): void;
|
|
5
|
+
export interface CliIo {
|
|
6
|
+
out?: (msg: string) => void;
|
|
7
|
+
err?: (msg: string) => void;
|
|
8
|
+
exit?: (code: number) => void | number;
|
|
9
|
+
stdin?: NodeJS.ReadableStream & {
|
|
10
|
+
isTTY?: boolean;
|
|
11
|
+
};
|
|
12
|
+
stdout?: NodeJS.WritableStream;
|
|
13
|
+
cwd?: string;
|
|
14
|
+
templateDir?: string;
|
|
15
|
+
scaffold?: (options?: ScaffoldOptions) => ScaffoldResult;
|
|
16
|
+
}
|
|
17
|
+
export interface NormalizedCliIo {
|
|
18
|
+
out: (msg: string) => void;
|
|
19
|
+
err: (msg: string) => void;
|
|
20
|
+
exit: (code: number) => void | number;
|
|
21
|
+
stdin: NodeJS.ReadableStream & {
|
|
22
|
+
isTTY?: boolean;
|
|
23
|
+
};
|
|
24
|
+
stdout: NodeJS.WritableStream;
|
|
25
|
+
cwd: string;
|
|
26
|
+
templateDir: string;
|
|
27
|
+
scaffoldFn: (options?: ScaffoldOptions) => ScaffoldResult;
|
|
28
|
+
}
|
|
29
|
+
export declare function runCli(rawArgs?: string[], io?: CliIo): Promise<void | number>;
|
|
30
|
+
export declare function main(): Promise<void>;
|
|
31
|
+
export { askQuestion };
|
|
32
|
+
declare const _default: {
|
|
33
|
+
runCli: typeof runCli;
|
|
34
|
+
main: typeof main;
|
|
35
|
+
printHelp: typeof printHelp;
|
|
36
|
+
printVersion: typeof printVersion;
|
|
37
|
+
askQuestion: typeof askQuestion;
|
|
38
|
+
};
|
|
39
|
+
export default _default;
|
|
40
|
+
//# sourceMappingURL=cli.d.ts.map
|
package/lib/cli.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAGrE,OAAO,EAAE,WAAW,EAA0C,MAAM,iBAAiB,CAAC;AAatF,wBAAgB,SAAS,CAAC,GAAG,GAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAkB,GAAG,IAAI,CAwBxE;AAED,wBAAgB,YAAY,CAAC,GAAG,GAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAkB,GAAG,IAAI,CAE3E;AAED,MAAM,WAAW,KAAK;IACpB,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5B,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5B,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,GAAG,MAAM,CAAC;IACvC,KAAK,CAAC,EAAE,MAAM,CAAC,cAAc,GAAG;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC;IACpD,MAAM,CAAC,EAAE,MAAM,CAAC,cAAc,CAAC;IAC/B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,eAAe,KAAK,cAAc,CAAC;CAC1D;AAED,MAAM,WAAW,eAAe;IAC9B,GAAG,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IAC3B,GAAG,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IAC3B,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,GAAG,MAAM,CAAC;IACtC,KAAK,EAAE,MAAM,CAAC,cAAc,GAAG;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC;IACnD,MAAM,EAAE,MAAM,CAAC,cAAc,CAAC;IAC9B,GAAG,EAAE,MAAM,CAAC;IACZ,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,CAAC,OAAO,CAAC,EAAE,eAAe,KAAK,cAAc,CAAC;CAC3D;AA6HD,wBAAsB,MAAM,CAC1B,OAAO,GAAE,MAAM,EAA0B,EACzC,EAAE,GAAE,KAAU,GACb,OAAO,CAAC,IAAI,GAAG,MAAM,CAAC,CAqBxB;AAED,wBAAsB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAO1C;AAED,OAAO,EAAE,WAAW,EAAE,CAAC;;;;;;;;AAEvB,wBAME"}
|