@freeappstore/cli 0.4.47 → 0.4.48
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/dist/commands/add.d.ts +3 -0
- package/dist/commands/add.d.ts.map +1 -0
- package/dist/commands/add.js +17 -0
- package/dist/commands/add.js.map +1 -0
- package/dist/commands/init.d.ts +2 -0
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +11 -0
- package/dist/commands/init.js.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/lib/capabilities.d.ts +22 -0
- package/dist/lib/capabilities.d.ts.map +1 -0
- package/dist/lib/capabilities.js +160 -0
- package/dist/lib/capabilities.js.map +1 -0
- package/dist/lib/capabilities.test.d.ts +2 -0
- package/dist/lib/capabilities.test.d.ts.map +1 -0
- package/dist/lib/capabilities.test.js +104 -0
- package/dist/lib/capabilities.test.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"add.d.ts","sourceRoot":"","sources":["../../src/commands/add.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGpC,eAAO,MAAM,UAAU,SAgBnB,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import { installCapabilities, presets } from '../lib/capabilities.js';
|
|
3
|
+
export const addCommand = new Command('add')
|
|
4
|
+
.description('Install bundled first-party browser capabilities without overwriting edits.')
|
|
5
|
+
.argument('[capabilities...]', 'Capability IDs (currently: connectivity)')
|
|
6
|
+
.option('--preset <name>', 'Capability list: minimal | connectivity')
|
|
7
|
+
.option('--dry-run', 'Print the plan without writing files')
|
|
8
|
+
.option('--update', 'Explicitly update tracked generated files if unedited')
|
|
9
|
+
.action(async (ids, opts) => {
|
|
10
|
+
if (opts.preset && !Object.hasOwn(presets, opts.preset))
|
|
11
|
+
throw new Error(`Unknown preset: ${opts.preset}`);
|
|
12
|
+
if (!ids.length && !opts.preset)
|
|
13
|
+
throw new Error('Choose a capability or --preset.');
|
|
14
|
+
const plan = await installCapabilities(process.cwd(), [...(presets[opts.preset ?? 'minimal'] ?? []), ...ids], opts);
|
|
15
|
+
process.stdout.write(`${plan.join('\n')}\n`);
|
|
16
|
+
});
|
|
17
|
+
//# sourceMappingURL=add.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"add.js","sourceRoot":"","sources":["../../src/commands/add.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,mBAAmB,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AAEtE,MAAM,CAAC,MAAM,UAAU,GAAG,IAAI,OAAO,CAAC,KAAK,CAAC;KACzC,WAAW,CAAC,6EAA6E,CAAC;KAC1F,QAAQ,CAAC,mBAAmB,EAAE,0CAA0C,CAAC;KACzE,MAAM,CAAC,iBAAiB,EAAE,yCAAyC,CAAC;KACpE,MAAM,CAAC,WAAW,EAAE,sCAAsC,CAAC;KAC3D,MAAM,CAAC,UAAU,EAAE,uDAAuD,CAAC;KAC3E,MAAM,CAAC,KAAK,EAAE,GAAa,EAAE,IAA6D,EAAE,EAAE;IAC7F,IAAI,IAAI,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC;QACrD,MAAM,IAAI,KAAK,CAAC,mBAAmB,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;IACpD,IAAI,CAAC,GAAG,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,MAAM;QAAE,MAAM,IAAI,KAAK,CAAC,kCAAkC,CAAC,CAAC;IACrF,MAAM,IAAI,GAAG,MAAM,mBAAmB,CACpC,OAAO,CAAC,GAAG,EAAE,EACb,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,IAAI,SAAS,CAAC,IAAI,EAAE,CAAC,EAAE,GAAG,GAAG,CAAC,EACtD,IAAI,CACL,CAAC;IACF,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC/C,CAAC,CAAC,CAAC"}
|
package/dist/commands/init.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAIpC,QAAA,MAAM,SAAS;;;;;;CAQL,CAAC;AAEX,KAAK,YAAY,GAAG,MAAM,OAAO,SAAS,CAAC;AAE3C;;;;GAIG;AACH,eAAO,MAAM,cAAc,2EAAiE,CAAC;AAE7F,eAAO,MAAM,aAAa,EAA6B,YAAY,EAAE,CAAC;AA2BtE;;;GAGG;AACH,wBAAsB,OAAO,CAAC,IAAI,EAAE;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,YAAY,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,GAAG,OAAO,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,iBAAiB,EAAE,MAAM,CAAA;CAAE,CAAC,CAqDvD;AAED,eAAO,MAAM,WAAW,SAwCrB,CAAC"}
|
package/dist/commands/init.js
CHANGED
|
@@ -3,6 +3,7 @@ import { access, readdir, readFile, rm, writeFile } from 'node:fs/promises';
|
|
|
3
3
|
import { extname, join, resolve } from 'node:path';
|
|
4
4
|
import { Command } from 'commander';
|
|
5
5
|
import { assertValidAppId } from '../lib/app-id.js';
|
|
6
|
+
import { installCapabilities, presets, resolveCapabilities } from '../lib/capabilities.js';
|
|
6
7
|
const TEMPLATES = {
|
|
7
8
|
// FreeAppStore templates
|
|
8
9
|
standalone: 'freeappstore-online/template-standalone',
|
|
@@ -48,6 +49,11 @@ const SKIP_DIRS = new Set(['.git', 'node_modules', 'dist', '.next', '.cache']);
|
|
|
48
49
|
*/
|
|
49
50
|
export async function runInit(opts) {
|
|
50
51
|
assertValidAppId(opts.appId);
|
|
52
|
+
const preset = opts.preset ?? 'minimal';
|
|
53
|
+
if (!Object.hasOwn(presets, preset))
|
|
54
|
+
throw new Error(`Unknown preset: ${preset}`);
|
|
55
|
+
const capabilities = [...(presets[preset] ?? []), ...(opts.capabilities ?? [])];
|
|
56
|
+
resolveCapabilities(capabilities);
|
|
51
57
|
const template = opts.template ?? 'standalone';
|
|
52
58
|
if (!(template in TEMPLATES)) {
|
|
53
59
|
throw new Error(`Unknown template "${template}". Choose: ${ALL_TEMPLATES.join(', ')}.`);
|
|
@@ -74,6 +80,7 @@ export async function runInit(opts) {
|
|
|
74
80
|
...config,
|
|
75
81
|
appId: opts.appId,
|
|
76
82
|
}, null, 2)}\n`);
|
|
83
|
+
await installCapabilities(target, capabilities);
|
|
77
84
|
await run('git', ['init', '-q', '-b', 'main'], target);
|
|
78
85
|
// Stage and commit the template so the new repo has a real first commit.
|
|
79
86
|
// Without this, `git push` after fas publish fails with "src refspec
|
|
@@ -86,6 +93,8 @@ export const initCommand = new Command('init')
|
|
|
86
93
|
.description('Scaffold a new free app or game from a template.')
|
|
87
94
|
.argument('<app-id>', 'Short id (lowercase, single word). e.g. "calendar" or "asteroids"')
|
|
88
95
|
.option('-t, --template <name>', `Template: ${ALL_TEMPLATES.join(' | ')}`, 'standalone')
|
|
96
|
+
.option('--capabilities <ids>', 'Comma-separated first-party capability IDs')
|
|
97
|
+
.option('--preset <name>', 'Capability list: minimal | connectivity', 'minimal')
|
|
89
98
|
.action(async (appId, opts) => {
|
|
90
99
|
if (!(opts.template in TEMPLATES)) {
|
|
91
100
|
process.stderr.write(`Unknown template "${opts.template}". Choose: ${ALL_TEMPLATES.join(', ')}.\n`);
|
|
@@ -94,6 +103,8 @@ export const initCommand = new Command('init')
|
|
|
94
103
|
const result = await runInit({
|
|
95
104
|
appId,
|
|
96
105
|
template: opts.template,
|
|
106
|
+
capabilities: opts.capabilities?.split(',').filter(Boolean) ?? [],
|
|
107
|
+
preset: opts.preset ?? 'minimal',
|
|
97
108
|
});
|
|
98
109
|
const isGame = GAME_TEMPLATES.has(opts.template);
|
|
99
110
|
const publishCmd = isGame ? 'fas publish --store games' : 'fas publish';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAC3C,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC5E,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACnD,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -3,6 +3,7 @@ import { readFileSync } from 'node:fs';
|
|
|
3
3
|
import { dirname, join } from 'node:path';
|
|
4
4
|
import { fileURLToPath } from 'node:url';
|
|
5
5
|
import { Command } from 'commander';
|
|
6
|
+
import { addCommand } from './commands/add.js';
|
|
6
7
|
import { adminCommand } from './commands/admin.js';
|
|
7
8
|
import { buildTargetCommand } from './commands/build-target.js';
|
|
8
9
|
import { checkCommand } from './commands/check.js';
|
|
@@ -36,6 +37,7 @@ program.addCommand(loginCommand);
|
|
|
36
37
|
program.addCommand(logoutCommand);
|
|
37
38
|
program.addCommand(whoamiCommand);
|
|
38
39
|
program.addCommand(initCommand);
|
|
40
|
+
program.addCommand(addCommand);
|
|
39
41
|
program.addCommand(publishCommand);
|
|
40
42
|
program.addCommand(logsCommand);
|
|
41
43
|
program.addCommand(doctorCommand);
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAChE,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AAChE,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAE9D,6EAA6E;AAC7E,wEAAwE;AACxE,2CAA2C;AAC3C,MAAM,IAAI,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AACrD,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,cAAc,CAAC,EAAE,MAAM,CAAC,CAE5E,CAAC;AAEF,oEAAoE;AACpE,sBAAsB,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;AAEpC,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,KAAK,CAAC;KACX,WAAW,CAAC,8DAA8D,CAAC;KAC3E,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;AAExB,OAAO,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC;AACjC,OAAO,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC;AAClC,OAAO,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC;AAClC,OAAO,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC;AAChC,OAAO,CAAC,UAAU,CAAC,cAAc,CAAC,CAAC;AACnC,OAAO,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC;AAChC,OAAO,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC;AAClC,OAAO,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC;AACjC,OAAO,CAAC,UAAU,CAAC,kBAAkB,CAAC,CAAC;AACvC,OAAO,CAAC,UAAU,CAAC,kBAAkB,CAAC,CAAC;AACvC,OAAO,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC;AAChC,OAAO,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC;AAClC,OAAO,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC;AACjC,OAAO,CAAC,UAAU,CAAC,cAAc,CAAC,CAAC;AACnC,OAAO,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC;AACjC,OAAO,CAAC,UAAU,CAAC,cAAc,CAAC,CAAC;AAEnC,kEAAkE;AAClE,+EAA+E;AAC/E,KAAK,UAAU,IAAI;IACjB,IAAI,OAAO,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC9B,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;YAC1B,0DAA0D;YAC1D,OAAO,CAAC,UAAU,EAAE,CAAC;YACrB,OAAO;QACT,CAAC;QACD,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,MAAM,CAAC,gBAAgB,CAAC,CAAC;QACpD,MAAM,QAAQ,EAAE,CAAC;QACjB,OAAO;IACT,CAAC;IACD,MAAM,OAAO,CAAC,UAAU,EAAE,CAAC;AAC7B,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAY,EAAE,EAAE;IAC5B,MAAM,GAAG,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IAC7D,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,GAAG,IAAI,CAAC,CAAC;IACtC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { writeFile } from 'node:fs/promises';
|
|
2
|
+
export interface Capability {
|
|
3
|
+
id: string;
|
|
4
|
+
version: string;
|
|
5
|
+
dependencies: Record<string, string>;
|
|
6
|
+
environment: 'browser';
|
|
7
|
+
files: Record<string, string>;
|
|
8
|
+
configChanges: string[];
|
|
9
|
+
validate: (content: string) => boolean;
|
|
10
|
+
}
|
|
11
|
+
/** Bounded, bundled first-party code only. No downloaded install hooks. */
|
|
12
|
+
export declare const registry: Record<string, Capability>;
|
|
13
|
+
export declare const presets: Record<string, string[]>;
|
|
14
|
+
export declare function resolveCapabilities(ids: string[], source?: Record<string, Capability>): Capability[];
|
|
15
|
+
export declare function installCapabilities(rootPath: string, ids: string[], options?: {
|
|
16
|
+
dryRun?: boolean;
|
|
17
|
+
update?: boolean;
|
|
18
|
+
source?: Record<string, Capability>;
|
|
19
|
+
/** Injectable writer for failure/retry verification. */
|
|
20
|
+
write?: typeof writeFile;
|
|
21
|
+
}): Promise<string[]>;
|
|
22
|
+
//# sourceMappingURL=capabilities.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"capabilities.d.ts","sourceRoot":"","sources":["../../src/lib/capabilities.ts"],"names":[],"mappings":"AACA,OAAO,EAAsC,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAGjF,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACrC,WAAW,EAAE,SAAS,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9B,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,QAAQ,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC;CACxC;AAED,2EAA2E;AAC3E,eAAO,MAAM,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAuB/C,CAAC;AAEF,eAAO,MAAM,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAmD,CAAC;AAYjG,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE,MAAM,6BAAW,GAAG,UAAU,EAAE,CAkBlF;AA8BD,wBAAsB,mBAAmB,CACvC,QAAQ,EAAE,MAAM,EAChB,GAAG,EAAE,MAAM,EAAE,EACb,OAAO,GAAE;IACP,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IACpC,wDAAwD;IACxD,KAAK,CAAC,EAAE,OAAO,SAAS,CAAC;CACrB,GACL,OAAO,CAAC,MAAM,EAAE,CAAC,CA+EnB"}
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
import { createHash, randomUUID } from 'node:crypto';
|
|
2
|
+
import { lstat, mkdir, readFile, rename, rm, writeFile } from 'node:fs/promises';
|
|
3
|
+
import { dirname, join, resolve } from 'node:path';
|
|
4
|
+
/** Bounded, bundled first-party code only. No downloaded install hooks. */
|
|
5
|
+
export const registry = {
|
|
6
|
+
connectivity: {
|
|
7
|
+
id: 'connectivity',
|
|
8
|
+
version: '1.0.0',
|
|
9
|
+
dependencies: {},
|
|
10
|
+
environment: 'browser',
|
|
11
|
+
files: {
|
|
12
|
+
'fas-capabilities/connectivity.ts': `/** Browser connectivity hints; online does not guarantee server reachability. */
|
|
13
|
+
export function watchConnectivity(listener: (online: boolean) => void): () => void {
|
|
14
|
+
const update = () => listener(navigator.onLine);
|
|
15
|
+
window.addEventListener('online', update);
|
|
16
|
+
window.addEventListener('offline', update);
|
|
17
|
+
update();
|
|
18
|
+
return () => {
|
|
19
|
+
window.removeEventListener('online', update);
|
|
20
|
+
window.removeEventListener('offline', update);
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
`,
|
|
24
|
+
},
|
|
25
|
+
configChanges: [],
|
|
26
|
+
validate: (content) => content.includes('export function watchConnectivity'),
|
|
27
|
+
},
|
|
28
|
+
};
|
|
29
|
+
export const presets = { minimal: [], connectivity: ['connectivity'] };
|
|
30
|
+
const manifestName = '.fas-capabilities.json';
|
|
31
|
+
const hash = (value) => createHash('sha256').update(value).digest('hex');
|
|
32
|
+
export function resolveCapabilities(ids, source = registry) {
|
|
33
|
+
const result = [];
|
|
34
|
+
const visiting = new Set();
|
|
35
|
+
const done = new Set();
|
|
36
|
+
function visit(id, version) {
|
|
37
|
+
const cap = Object.hasOwn(source, id) ? source[id] : undefined;
|
|
38
|
+
if (!cap || (version && cap.version !== version))
|
|
39
|
+
throw new Error(`Unknown or incompatible capability: ${id}${version ? `@${version}` : ''}`);
|
|
40
|
+
if (visiting.has(id))
|
|
41
|
+
throw new Error(`Capability dependency cycle: ${id}`);
|
|
42
|
+
if (done.has(id))
|
|
43
|
+
return;
|
|
44
|
+
visiting.add(id);
|
|
45
|
+
for (const [dep, required] of Object.entries(cap.dependencies))
|
|
46
|
+
visit(dep, required);
|
|
47
|
+
visiting.delete(id);
|
|
48
|
+
done.add(id);
|
|
49
|
+
result.push(cap);
|
|
50
|
+
}
|
|
51
|
+
for (const id of ids)
|
|
52
|
+
visit(id);
|
|
53
|
+
return result;
|
|
54
|
+
}
|
|
55
|
+
async function readOptional(path) {
|
|
56
|
+
try {
|
|
57
|
+
return await readFile(path, 'utf8');
|
|
58
|
+
}
|
|
59
|
+
catch (error) {
|
|
60
|
+
if (error.code === 'ENOENT')
|
|
61
|
+
return undefined;
|
|
62
|
+
throw error;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
/** Reject symlinks as well as traversal, including in existing parent directories. */
|
|
66
|
+
async function safePath(root, file) {
|
|
67
|
+
if (!/^[a-zA-Z0-9_.-]+(?:\/[a-zA-Z0-9_.-]+)*$/.test(file) ||
|
|
68
|
+
file.split('/').some((part) => part === '..' || part === '.'))
|
|
69
|
+
throw new Error(`Unsafe capability path: ${file}`);
|
|
70
|
+
let current = root;
|
|
71
|
+
for (const part of file.split('/')) {
|
|
72
|
+
current = join(current, part);
|
|
73
|
+
try {
|
|
74
|
+
if ((await lstat(current)).isSymbolicLink())
|
|
75
|
+
throw new Error(`Symlink conflict: ${file}`);
|
|
76
|
+
}
|
|
77
|
+
catch (error) {
|
|
78
|
+
if (error.code !== 'ENOENT')
|
|
79
|
+
throw error;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
return current;
|
|
83
|
+
}
|
|
84
|
+
export async function installCapabilities(rootPath, ids, options = {}) {
|
|
85
|
+
const root = resolve(rootPath);
|
|
86
|
+
const packageText = await readOptional(join(root, 'package.json'));
|
|
87
|
+
if (!packageText)
|
|
88
|
+
throw new Error('Run fas add in an app root containing package.json.');
|
|
89
|
+
JSON.parse(packageText);
|
|
90
|
+
const manifestPath = await safePath(root, manifestName);
|
|
91
|
+
const text = await readOptional(manifestPath);
|
|
92
|
+
const manifest = text ? JSON.parse(text) : { schemaVersion: 1, capabilities: {} };
|
|
93
|
+
if (manifest.schemaVersion !== 1 ||
|
|
94
|
+
!manifest.capabilities ||
|
|
95
|
+
typeof manifest.capabilities !== 'object')
|
|
96
|
+
throw new Error('Unsupported capability manifest.');
|
|
97
|
+
const plan = [];
|
|
98
|
+
const writes = [];
|
|
99
|
+
const owners = new Set();
|
|
100
|
+
for (const cap of resolveCapabilities(ids, options.source)) {
|
|
101
|
+
const old = Object.hasOwn(manifest.capabilities, cap.id)
|
|
102
|
+
? manifest.capabilities[cap.id]
|
|
103
|
+
: undefined;
|
|
104
|
+
if (old && old.version !== cap.version && !options.update)
|
|
105
|
+
throw new Error(`${cap.id}: installed ${old.version}; review --dry-run --update before updating to ${cap.version}.`);
|
|
106
|
+
const files = {};
|
|
107
|
+
for (const [file, content] of Object.entries(cap.files)) {
|
|
108
|
+
if (owners.has(file))
|
|
109
|
+
throw new Error(`Multiple capabilities own ${file}`);
|
|
110
|
+
owners.add(file);
|
|
111
|
+
for (const [other, owned] of Object.entries(manifest.capabilities)) {
|
|
112
|
+
if (other !== cap.id && Object.hasOwn(owned.files, file))
|
|
113
|
+
throw new Error(`Ownership conflict: ${file} belongs to ${other}`);
|
|
114
|
+
}
|
|
115
|
+
if (!cap.validate(content))
|
|
116
|
+
throw new Error(`Capability validation failed: ${cap.id}/${file}`);
|
|
117
|
+
const path = await safePath(root, file);
|
|
118
|
+
const current = await readOptional(path);
|
|
119
|
+
const expected = old?.files[file];
|
|
120
|
+
if (current !== undefined && current !== content && (!expected || hash(current) !== expected))
|
|
121
|
+
throw new Error(`Edited or unowned file conflict: ${file}. Preserve your changes and resolve manually.`);
|
|
122
|
+
files[file] = hash(content);
|
|
123
|
+
if (current !== content) {
|
|
124
|
+
plan.push(`${current === undefined ? 'CREATE' : 'UPDATE'} ${file} (${cap.id}@${cap.version})\n${content
|
|
125
|
+
.split('\n')
|
|
126
|
+
.map((line) => `+ ${line}`)
|
|
127
|
+
.join('\n')}`);
|
|
128
|
+
writes.push({ path, content });
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
// Removed files are retained and remain tracked: no implicit destructive migrations.
|
|
132
|
+
manifest.capabilities[cap.id] = { version: cap.version, files: { ...old?.files, ...files } };
|
|
133
|
+
}
|
|
134
|
+
const next = `${JSON.stringify(manifest, null, 2)}\n`;
|
|
135
|
+
if (next !== text)
|
|
136
|
+
plan.push(`UPDATE ${manifestName}\n${next}`);
|
|
137
|
+
if (!options.dryRun) {
|
|
138
|
+
const write = options.write ??
|
|
139
|
+
(async (path, content) => {
|
|
140
|
+
const temporary = `${path}.${randomUUID()}.tmp`;
|
|
141
|
+
try {
|
|
142
|
+
await writeFile(temporary, content, { flag: 'wx' });
|
|
143
|
+
await rename(temporary, path);
|
|
144
|
+
}
|
|
145
|
+
finally {
|
|
146
|
+
await rm(temporary, { force: true });
|
|
147
|
+
}
|
|
148
|
+
});
|
|
149
|
+
// Write files first. A retry safely adopts exact generated bytes if interrupted
|
|
150
|
+
// before recording ownership; a differing file is always a conflict.
|
|
151
|
+
for (const item of writes) {
|
|
152
|
+
await mkdir(dirname(item.path), { recursive: true });
|
|
153
|
+
await write(item.path, item.content);
|
|
154
|
+
}
|
|
155
|
+
if (next !== text)
|
|
156
|
+
await write(manifestPath, next);
|
|
157
|
+
}
|
|
158
|
+
return plan.length ? plan : ['No changes.'];
|
|
159
|
+
}
|
|
160
|
+
//# sourceMappingURL=capabilities.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"capabilities.js","sourceRoot":"","sources":["../../src/lib/capabilities.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"capabilities.test.d.ts","sourceRoot":"","sources":["../../src/lib/capabilities.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { mkdtemp, readFile, rm, writeFile } from 'node:fs/promises';
|
|
2
|
+
import { tmpdir } from 'node:os';
|
|
3
|
+
import { join } from 'node:path';
|
|
4
|
+
import { afterEach, expect, it } from 'vitest';
|
|
5
|
+
import { installCapabilities, registry, resolveCapabilities, } from './capabilities.js';
|
|
6
|
+
const roots = [];
|
|
7
|
+
async function app() {
|
|
8
|
+
const root = await mkdtemp(join(tmpdir(), 'fas-cap-'));
|
|
9
|
+
roots.push(root);
|
|
10
|
+
await writeFile(join(root, 'package.json'), '{}');
|
|
11
|
+
await writeFile(join(root, 'user.txt'), 'keep');
|
|
12
|
+
return root;
|
|
13
|
+
}
|
|
14
|
+
afterEach(async () => {
|
|
15
|
+
for (const root of roots.splice(0))
|
|
16
|
+
await rm(root, { recursive: true, force: true });
|
|
17
|
+
});
|
|
18
|
+
const cap = (id, dependencies = {}) => ({
|
|
19
|
+
id,
|
|
20
|
+
version: '1.0.0',
|
|
21
|
+
dependencies,
|
|
22
|
+
environment: 'browser',
|
|
23
|
+
files: { [`${id}.ts`]: id },
|
|
24
|
+
configChanges: [],
|
|
25
|
+
validate: () => true,
|
|
26
|
+
});
|
|
27
|
+
it('resolves dependencies before dependents and rejects incompatible versions and cycles', () => {
|
|
28
|
+
const source = { a: cap('a', { b: '1.0.0' }), b: cap('b') };
|
|
29
|
+
expect(resolveCapabilities(['a', 'b'], source).map((c) => c.id)).toEqual(['b', 'a']);
|
|
30
|
+
expect(() => resolveCapabilities(['a'], { ...source, b: { ...source.b, version: '2.0.0' } })).toThrow('incompatible');
|
|
31
|
+
expect(() => resolveCapabilities(['a'], { ...source, b: cap('b', { a: '1.0.0' }) })).toThrow('cycle');
|
|
32
|
+
});
|
|
33
|
+
it('adopts existing apps, previews without writes, installs idempotently and preserves unrelated files', async () => {
|
|
34
|
+
const root = await app();
|
|
35
|
+
expect((await installCapabilities(root, ['connectivity'], { dryRun: true })).join()).toContain('CREATE');
|
|
36
|
+
await expect(readFile(join(root, '.fas-capabilities.json'))).rejects.toThrow();
|
|
37
|
+
await installCapabilities(root, ['connectivity']);
|
|
38
|
+
expect(await installCapabilities(root, ['connectivity'])).toEqual(['No changes.']);
|
|
39
|
+
expect(await readFile(join(root, 'user.txt'), 'utf8')).toBe('keep');
|
|
40
|
+
});
|
|
41
|
+
it('rejects developer edits before making any changes', async () => {
|
|
42
|
+
const root = await app();
|
|
43
|
+
await installCapabilities(root, ['connectivity']);
|
|
44
|
+
const file = join(root, 'fas-capabilities/connectivity.ts');
|
|
45
|
+
await writeFile(file, 'developer code');
|
|
46
|
+
await expect(installCapabilities(root, ['connectivity'])).rejects.toThrow('conflict');
|
|
47
|
+
expect(await readFile(file, 'utf8')).toBe('developer code');
|
|
48
|
+
});
|
|
49
|
+
it('retries safely after partial failure without silently adopting different bytes', async () => {
|
|
50
|
+
const root = await app();
|
|
51
|
+
const source = { a: cap('a'), b: cap('b') };
|
|
52
|
+
let count = 0;
|
|
53
|
+
await expect(installCapabilities(root, ['a', 'b'], {
|
|
54
|
+
source,
|
|
55
|
+
write: (async (...args) => {
|
|
56
|
+
if (++count === 2)
|
|
57
|
+
throw new Error('disk failure');
|
|
58
|
+
return writeFile(...args);
|
|
59
|
+
}),
|
|
60
|
+
})).rejects.toThrow('disk failure');
|
|
61
|
+
await installCapabilities(root, ['a', 'b'], { source });
|
|
62
|
+
expect(await installCapabilities(root, ['a', 'b'], { source })).toEqual(['No changes.']);
|
|
63
|
+
});
|
|
64
|
+
it('requires explicit updates and retains removed files', async () => {
|
|
65
|
+
const root = await app();
|
|
66
|
+
await installCapabilities(root, ['a'], { source: { a: cap('a') } });
|
|
67
|
+
const a = { ...cap('a'), version: '2.0.0', files: { 'new.ts': 'new' } };
|
|
68
|
+
await expect(installCapabilities(root, ['a'], { source: { a } })).rejects.toThrow('--update');
|
|
69
|
+
await installCapabilities(root, ['a'], { source: { a }, update: true });
|
|
70
|
+
expect(await readFile(join(root, 'a.ts'), 'utf8')).toBe('a');
|
|
71
|
+
});
|
|
72
|
+
it('rejects unowned collisions, overlapping ownership and traversal', async () => {
|
|
73
|
+
const root = await app();
|
|
74
|
+
await writeFile(join(root, 'a.ts'), 'mine');
|
|
75
|
+
await expect(installCapabilities(root, ['a'], { source: { a: cap('a') } })).rejects.toThrow('conflict');
|
|
76
|
+
await expect(installCapabilities(root, ['x'], {
|
|
77
|
+
source: { x: { ...cap('x'), files: { '../escape': 'bad' } } },
|
|
78
|
+
})).rejects.toThrow('Unsafe');
|
|
79
|
+
const a = cap('a');
|
|
80
|
+
const b = { ...cap('b'), files: a.files };
|
|
81
|
+
await rm(join(root, 'a.ts'));
|
|
82
|
+
await expect(installCapabilities(root, ['a', 'b'], { source: { a, b } })).rejects.toThrow('Multiple');
|
|
83
|
+
await expect(readFile(join(root, 'a.ts'))).rejects.toThrow();
|
|
84
|
+
expect(registry.connectivity?.environment).toBe('browser');
|
|
85
|
+
});
|
|
86
|
+
it('retries an interrupted version update and detects edits afterwards', async () => {
|
|
87
|
+
const root = await app();
|
|
88
|
+
await installCapabilities(root, ['a'], { source: { a: cap('a') } });
|
|
89
|
+
const source = { a: { ...cap('a'), version: '2.0.0', files: { 'a.ts': 'updated' } } };
|
|
90
|
+
await expect(installCapabilities(root, ['a'], {
|
|
91
|
+
source,
|
|
92
|
+
update: true,
|
|
93
|
+
write: (async (path, content) => {
|
|
94
|
+
if (path.endsWith('.json'))
|
|
95
|
+
throw new Error('interrupted');
|
|
96
|
+
await writeFile(path, content);
|
|
97
|
+
}),
|
|
98
|
+
})).rejects.toThrow('interrupted');
|
|
99
|
+
await installCapabilities(root, ['a'], { source, update: true });
|
|
100
|
+
expect(await readFile(join(root, 'a.ts'), 'utf8')).toBe('updated');
|
|
101
|
+
await writeFile(join(root, 'a.ts'), 'edited');
|
|
102
|
+
await expect(installCapabilities(root, ['a'], { source, update: true })).rejects.toThrow('conflict');
|
|
103
|
+
});
|
|
104
|
+
//# sourceMappingURL=capabilities.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"capabilities.test.js","sourceRoot":"","sources":["../../src/lib/capabilities.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACpE,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAC/C,OAAO,EAEL,mBAAmB,EACnB,QAAQ,EACR,mBAAmB,GACpB,MAAM,mBAAmB,CAAC;AAE3B,MAAM,KAAK,GAAa,EAAE,CAAC;AAC3B,KAAK,UAAU,GAAG;IAChB,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,UAAU,CAAC,CAAC,CAAC;IACvD,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACjB,MAAM,SAAS,CAAC,IAAI,CAAC,IAAI,EAAE,cAAc,CAAC,EAAE,IAAI,CAAC,CAAC;IAClD,MAAM,SAAS,CAAC,IAAI,CAAC,IAAI,EAAE,UAAU,CAAC,EAAE,MAAM,CAAC,CAAC;IAChD,OAAO,IAAI,CAAC;AACd,CAAC;AACD,SAAS,CAAC,KAAK,IAAI,EAAE;IACnB,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC;QAAE,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;AACvF,CAAC,CAAC,CAAC;AACH,MAAM,GAAG,GAAG,CAAC,EAAU,EAAE,YAAY,GAAG,EAAE,EAAc,EAAE,CAAC,CAAC;IAC1D,EAAE;IACF,OAAO,EAAE,OAAO;IAChB,YAAY;IACZ,WAAW,EAAE,SAAS;IACtB,KAAK,EAAE,EAAE,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE,EAAE;IAC3B,aAAa,EAAE,EAAE;IACjB,QAAQ,EAAE,GAAG,EAAE,CAAC,IAAI;CACrB,CAAC,CAAC;AAEH,EAAE,CAAC,sFAAsF,EAAE,GAAG,EAAE;IAC9F,MAAM,MAAM,GAAG,EAAE,CAAC,EAAE,GAAG,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;IAC5D,MAAM,CAAC,mBAAmB,CAAC,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC;IACrF,MAAM,CAAC,GAAG,EAAE,CACV,mBAAmB,CAAC,CAAC,GAAG,CAAC,EAAE,EAAE,GAAG,MAAM,EAAE,CAAC,EAAE,EAAE,GAAG,MAAM,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,EAAE,CAAC,CAChF,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;IAC1B,MAAM,CAAC,GAAG,EAAE,CAAC,mBAAmB,CAAC,CAAC,GAAG,CAAC,EAAE,EAAE,GAAG,MAAM,EAAE,CAAC,EAAE,GAAG,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAC1F,OAAO,CACR,CAAC;AACJ,CAAC,CAAC,CAAC;AACH,EAAE,CAAC,oGAAoG,EAAE,KAAK,IAAI,EAAE;IAClH,MAAM,IAAI,GAAG,MAAM,GAAG,EAAE,CAAC;IACzB,MAAM,CAAC,CAAC,MAAM,mBAAmB,CAAC,IAAI,EAAE,CAAC,cAAc,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,SAAS,CAC5F,QAAQ,CACT,CAAC;IACF,MAAM,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,wBAAwB,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;IAC/E,MAAM,mBAAmB,CAAC,IAAI,EAAE,CAAC,cAAc,CAAC,CAAC,CAAC;IAClD,MAAM,CAAC,MAAM,mBAAmB,CAAC,IAAI,EAAE,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC;IACnF,MAAM,CAAC,MAAM,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,UAAU,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;AACtE,CAAC,CAAC,CAAC;AACH,EAAE,CAAC,mDAAmD,EAAE,KAAK,IAAI,EAAE;IACjE,MAAM,IAAI,GAAG,MAAM,GAAG,EAAE,CAAC;IACzB,MAAM,mBAAmB,CAAC,IAAI,EAAE,CAAC,cAAc,CAAC,CAAC,CAAC;IAClD,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,EAAE,kCAAkC,CAAC,CAAC;IAC5D,MAAM,SAAS,CAAC,IAAI,EAAE,gBAAgB,CAAC,CAAC;IACxC,MAAM,MAAM,CAAC,mBAAmB,CAAC,IAAI,EAAE,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IACtF,MAAM,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;AAC9D,CAAC,CAAC,CAAC;AACH,EAAE,CAAC,gFAAgF,EAAE,KAAK,IAAI,EAAE;IAC9F,MAAM,IAAI,GAAG,MAAM,GAAG,EAAE,CAAC;IACzB,MAAM,MAAM,GAAG,EAAE,CAAC,EAAE,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;IAC5C,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,MAAM,MAAM,CACV,mBAAmB,CAAC,IAAI,EAAE,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE;QACpC,MAAM;QACN,KAAK,EAAE,CAAC,KAAK,EAAE,GAAG,IAAkC,EAAE,EAAE;YACtD,IAAI,EAAE,KAAK,KAAK,CAAC;gBAAE,MAAM,IAAI,KAAK,CAAC,cAAc,CAAC,CAAC;YACnD,OAAO,SAAS,CAAC,GAAG,IAAI,CAAC,CAAC;QAC5B,CAAC,CAAqB;KACvB,CAAC,CACH,CAAC,OAAO,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;IAClC,MAAM,mBAAmB,CAAC,IAAI,EAAE,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;IACxD,MAAM,CAAC,MAAM,mBAAmB,CAAC,IAAI,EAAE,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC;AAC3F,CAAC,CAAC,CAAC;AACH,EAAE,CAAC,qDAAqD,EAAE,KAAK,IAAI,EAAE;IACnE,MAAM,IAAI,GAAG,MAAM,GAAG,EAAE,CAAC;IACzB,MAAM,mBAAmB,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,GAAG,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC;IACpE,MAAM,CAAC,GAAG,EAAE,GAAG,GAAG,CAAC,GAAG,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE,CAAC;IACxE,MAAM,MAAM,CAAC,mBAAmB,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IAC9F,MAAM,mBAAmB,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;IACxE,MAAM,CAAC,MAAM,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC/D,CAAC,CAAC,CAAC;AACH,EAAE,CAAC,iEAAiE,EAAE,KAAK,IAAI,EAAE;IAC/E,MAAM,IAAI,GAAG,MAAM,GAAG,EAAE,CAAC;IACzB,MAAM,SAAS,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,CAAC;IAC5C,MAAM,MAAM,CAAC,mBAAmB,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,GAAG,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CACzF,UAAU,CACX,CAAC;IACF,MAAM,MAAM,CACV,mBAAmB,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,EAAE;QAC/B,MAAM,EAAE,EAAE,CAAC,EAAE,EAAE,GAAG,GAAG,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,EAAE,WAAW,EAAE,KAAK,EAAE,EAAE,EAAE;KAC9D,CAAC,CACH,CAAC,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IAC5B,MAAM,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;IACnB,MAAM,CAAC,GAAG,EAAE,GAAG,GAAG,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC;IAC1C,MAAM,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC;IAC7B,MAAM,MAAM,CAAC,mBAAmB,CAAC,IAAI,EAAE,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CACvF,UAAU,CACX,CAAC;IACF,MAAM,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;IAC7D,MAAM,CAAC,QAAQ,CAAC,YAAY,EAAE,WAAW,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;AAC7D,CAAC,CAAC,CAAC;AAEH,EAAE,CAAC,oEAAoE,EAAE,KAAK,IAAI,EAAE;IAClF,MAAM,IAAI,GAAG,MAAM,GAAG,EAAE,CAAC;IACzB,MAAM,mBAAmB,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,GAAG,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC;IACpE,MAAM,MAAM,GAAG,EAAE,CAAC,EAAE,EAAE,GAAG,GAAG,CAAC,GAAG,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,EAAE,EAAE,CAAC;IACtF,MAAM,MAAM,CACV,mBAAmB,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,EAAE;QAC/B,MAAM;QACN,MAAM,EAAE,IAAI;QACZ,KAAK,EAAE,CAAC,KAAK,EAAE,IAAY,EAAE,OAAe,EAAE,EAAE;YAC9C,IAAI,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC;gBAAE,MAAM,IAAI,KAAK,CAAC,aAAa,CAAC,CAAC;YAC3D,MAAM,SAAS,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QACjC,CAAC,CAAqB;KACvB,CAAC,CACH,CAAC,OAAO,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC;IACjC,MAAM,mBAAmB,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;IACjE,MAAM,CAAC,MAAM,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IACnE,MAAM,SAAS,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,EAAE,QAAQ,CAAC,CAAC;IAC9C,MAAM,MAAM,CAAC,mBAAmB,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CACtF,UAAU,CACX,CAAC;AACJ,CAAC,CAAC,CAAC"}
|