@fnd-platform/cli 1.0.0-alpha.2 → 1.0.0-alpha.20

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.
@@ -0,0 +1,371 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.toPascalCase = toPascalCase;
4
+ exports.getProjectName = getProjectName;
5
+ exports.getStackOutput = getStackOutput;
6
+ exports.getStackOutputs = getStackOutputs;
7
+ exports.hasPackage = hasPackage;
8
+ exports.findBuildDirectory = findBuildDirectory;
9
+ exports.promptConfirmation = promptConfirmation;
10
+ exports.buildStackName = buildStackName;
11
+ exports.syncToS3 = syncToS3;
12
+ exports.invalidateCloudFront = invalidateCloudFront;
13
+ exports.buildPackage = buildPackage;
14
+ exports.validateAwsCli = validateAwsCli;
15
+ exports.listProjectStacks = listProjectStacks;
16
+ const child_process_1 = require("child_process");
17
+ const fs_1 = require("fs");
18
+ const path_1 = require("path");
19
+ const readline_1 = require("readline");
20
+ const logger_js_1 = require("./logger.js");
21
+ /**
22
+ * Converts a string to PascalCase.
23
+ *
24
+ * @param str - String to convert
25
+ * @returns PascalCase string
26
+ *
27
+ * @example
28
+ * ```typescript
29
+ * toPascalCase('my-project-name'); // 'MyProjectName'
30
+ * toPascalCase('hello_world'); // 'HelloWorld'
31
+ * ```
32
+ */
33
+ function toPascalCase(str) {
34
+ return str
35
+ .split(/[-_\s]+/)
36
+ .map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())
37
+ .join('');
38
+ }
39
+ /**
40
+ * Extracts the project name from .projenrc.ts.
41
+ *
42
+ * @param projectRoot - Path to project root
43
+ * @returns Project name
44
+ * @throws Error if .projenrc.ts is not found or name cannot be extracted
45
+ *
46
+ * @example
47
+ * ```typescript
48
+ * const name = getProjectName('/path/to/project');
49
+ * // Returns 'my-app'
50
+ * ```
51
+ */
52
+ function getProjectName(projectRoot) {
53
+ const projenrcPath = (0, path_1.join)(projectRoot, '.projenrc.ts');
54
+ if (!(0, fs_1.existsSync)(projenrcPath)) {
55
+ throw new Error(`.projenrc.ts not found at ${projenrcPath}`);
56
+ }
57
+ const content = (0, fs_1.readFileSync)(projenrcPath, 'utf-8');
58
+ // Try to match: name: 'project-name' or name: "project-name"
59
+ const nameMatch = content.match(/name:\s*['"]([^'"]+)['"]/);
60
+ if (nameMatch) {
61
+ return nameMatch[1];
62
+ }
63
+ // Fallback: try to get from package.json
64
+ const packageJsonPath = (0, path_1.join)(projectRoot, 'package.json');
65
+ if ((0, fs_1.existsSync)(packageJsonPath)) {
66
+ const packageJson = JSON.parse((0, fs_1.readFileSync)(packageJsonPath, 'utf-8'));
67
+ if (packageJson.name) {
68
+ return packageJson.name;
69
+ }
70
+ }
71
+ throw new Error('Could not extract project name from .projenrc.ts or package.json');
72
+ }
73
+ /**
74
+ * Gets a CloudFormation stack output value using AWS CLI.
75
+ *
76
+ * @param stackName - Name of the CloudFormation stack
77
+ * @param outputKey - Key of the output to retrieve
78
+ * @returns Output value, or null if not found
79
+ *
80
+ * @example
81
+ * ```typescript
82
+ * const apiUrl = getStackOutput('MyAppApiStack-dev', 'ApiUrl');
83
+ * // Returns 'https://abc123.execute-api.us-east-1.amazonaws.com/dev'
84
+ * ```
85
+ */
86
+ function getStackOutput(stackName, outputKey) {
87
+ try {
88
+ const result = (0, child_process_1.execSync)(`aws cloudformation describe-stacks --stack-name "${stackName}" --query "Stacks[0].Outputs[?OutputKey=='${outputKey}'].OutputValue" --output text`, { encoding: 'utf-8', stdio: ['pipe', 'pipe', 'pipe'] }).trim();
89
+ return result && result !== 'None' ? result : null;
90
+ }
91
+ catch {
92
+ logger_js_1.logger.debug(`Failed to get output ${outputKey} from stack ${stackName}`);
93
+ return null;
94
+ }
95
+ }
96
+ /**
97
+ * Gets all relevant stack outputs for deployment.
98
+ *
99
+ * @param projectRoot - Path to project root
100
+ * @param stage - Deployment stage
101
+ * @returns Stack outputs
102
+ *
103
+ * @example
104
+ * ```typescript
105
+ * const outputs = getStackOutputs('/path/to/project', 'dev');
106
+ * console.log(outputs.apiUrl);
107
+ * ```
108
+ */
109
+ function getStackOutputs(projectRoot, stage) {
110
+ const projectName = getProjectName(projectRoot);
111
+ const pascalName = toPascalCase(projectName);
112
+ const outputs = {};
113
+ // Auth Stack outputs (Cognito)
114
+ const authStackName = `${pascalName}AuthStack-${stage}`;
115
+ outputs.userPoolId = getStackOutput(authStackName, 'UserPoolId') ?? undefined;
116
+ outputs.userPoolClientId = getStackOutput(authStackName, 'UserPoolClientId') ?? undefined;
117
+ // API Stack outputs
118
+ const apiStackName = `${pascalName}ApiStack-${stage}`;
119
+ outputs.apiUrl = getStackOutput(apiStackName, 'ApiUrl') ?? undefined;
120
+ // Frontend Stack outputs
121
+ const frontendStackName = `${pascalName}FrontendStack-${stage}`;
122
+ outputs.frontendBucket = getStackOutput(frontendStackName, 'FrontendBucketName') ?? undefined;
123
+ outputs.frontendDistributionId =
124
+ getStackOutput(frontendStackName, 'FrontendDistributionId') ?? undefined;
125
+ outputs.frontendUrl = getStackOutput(frontendStackName, 'FrontendUrl') ?? undefined;
126
+ // CMS Stack outputs
127
+ const cmsStackName = `${pascalName}CmsStack-${stage}`;
128
+ outputs.cmsBucket = getStackOutput(cmsStackName, 'CmsBucketName') ?? undefined;
129
+ outputs.cmsDistributionId = getStackOutput(cmsStackName, 'CmsDistributionId') ?? undefined;
130
+ outputs.cmsUrl = getStackOutput(cmsStackName, 'CmsUrl') ?? undefined;
131
+ return outputs;
132
+ }
133
+ /**
134
+ * Checks if a package exists in the project.
135
+ *
136
+ * @param projectRoot - Path to project root
137
+ * @param packageName - Name of the package to check
138
+ * @returns True if package exists
139
+ *
140
+ * @example
141
+ * ```typescript
142
+ * if (hasPackage('/path/to/project', 'frontend')) {
143
+ * console.log('Frontend package exists');
144
+ * }
145
+ * ```
146
+ */
147
+ function hasPackage(projectRoot, packageName) {
148
+ const packagePath = (0, path_1.join)(projectRoot, 'packages', packageName);
149
+ return (0, fs_1.existsSync)(packagePath);
150
+ }
151
+ /**
152
+ * Finds the build output directory for a package.
153
+ * Checks common build output directories: build/client, build, dist.
154
+ *
155
+ * @param packagePath - Path to the package
156
+ * @returns Path to build directory, or null if not found
157
+ *
158
+ * @example
159
+ * ```typescript
160
+ * const buildDir = findBuildDirectory('/path/to/project/packages/frontend');
161
+ * // Returns '/path/to/project/packages/frontend/build/client'
162
+ * ```
163
+ */
164
+ function findBuildDirectory(packagePath) {
165
+ // Check for Remix/Vite SPA build output (build/client)
166
+ const buildClientDir = (0, path_1.join)(packagePath, 'build', 'client');
167
+ if ((0, fs_1.existsSync)(buildClientDir)) {
168
+ return buildClientDir;
169
+ }
170
+ // Check for standard build directory
171
+ const buildDir = (0, path_1.join)(packagePath, 'build');
172
+ if ((0, fs_1.existsSync)(buildDir)) {
173
+ // If build exists but we need client assets, look for index.html
174
+ const hasIndex = (0, fs_1.existsSync)((0, path_1.join)(buildDir, 'index.html'));
175
+ if (hasIndex) {
176
+ return buildDir;
177
+ }
178
+ }
179
+ // Check for dist directory (some build tools use this)
180
+ const distDir = (0, path_1.join)(packagePath, 'dist');
181
+ if ((0, fs_1.existsSync)(distDir)) {
182
+ return distDir;
183
+ }
184
+ return null;
185
+ }
186
+ /**
187
+ * Prompts the user for confirmation.
188
+ *
189
+ * @param message - Message to display
190
+ * @returns True if user confirms
191
+ *
192
+ * @example
193
+ * ```typescript
194
+ * const confirmed = await promptConfirmation('Are you sure you want to destroy dev?');
195
+ * if (!confirmed) {
196
+ * console.log('Operation cancelled');
197
+ * }
198
+ * ```
199
+ */
200
+ async function promptConfirmation(message) {
201
+ const rl = (0, readline_1.createInterface)({
202
+ input: process.stdin,
203
+ output: process.stdout,
204
+ });
205
+ return new Promise((resolve) => {
206
+ rl.question(`${message} (y/N): `, (answer) => {
207
+ rl.close();
208
+ resolve(answer.toLowerCase() === 'y' || answer.toLowerCase() === 'yes');
209
+ });
210
+ });
211
+ }
212
+ /**
213
+ * Builds a stack name following the project convention.
214
+ *
215
+ * @param projectName - Name of the project
216
+ * @param stackType - Type of stack (e.g., 'Api', 'Frontend', 'Cms')
217
+ * @param stage - Deployment stage
218
+ * @returns Full stack name
219
+ *
220
+ * @example
221
+ * ```typescript
222
+ * const stackName = buildStackName('my-app', 'Frontend', 'dev');
223
+ * // Returns 'MyAppFrontendStack-dev'
224
+ * ```
225
+ */
226
+ function buildStackName(projectName, stackType, stage) {
227
+ const pascalName = toPascalCase(projectName);
228
+ return `${pascalName}${stackType}Stack-${stage}`;
229
+ }
230
+ /**
231
+ * Syncs a local directory to an S3 bucket.
232
+ *
233
+ * @param localDir - Local directory path
234
+ * @param bucket - S3 bucket name
235
+ * @param verbose - Show verbose output
236
+ *
237
+ * @example
238
+ * ```typescript
239
+ * syncToS3('/path/to/build', 'my-app-frontend-dev-123456789', true);
240
+ * ```
241
+ */
242
+ function syncToS3(localDir, bucket, verbose = false) {
243
+ logger_js_1.logger.info(`Syncing ${localDir} to s3://${bucket}/`);
244
+ const command = `aws s3 sync "${localDir}" "s3://${bucket}/" --delete`;
245
+ logger_js_1.logger.debug(`Running: ${command}`);
246
+ try {
247
+ (0, child_process_1.execSync)(command, {
248
+ stdio: verbose ? 'inherit' : ['pipe', 'pipe', 'pipe'],
249
+ });
250
+ logger_js_1.logger.success(`Synced assets to s3://${bucket}/`);
251
+ }
252
+ catch (error) {
253
+ throw new Error(`Failed to sync to S3: ${error.message}`);
254
+ }
255
+ }
256
+ /**
257
+ * Creates a CloudFront invalidation for all paths.
258
+ *
259
+ * @param distributionId - CloudFront distribution ID
260
+ * @param verbose - Show verbose output
261
+ *
262
+ * @example
263
+ * ```typescript
264
+ * invalidateCloudFront('E1234567890ABC', true);
265
+ * ```
266
+ */
267
+ function invalidateCloudFront(distributionId, verbose = false) {
268
+ logger_js_1.logger.info(`Invalidating CloudFront distribution ${distributionId}`);
269
+ const command = `aws cloudfront create-invalidation --distribution-id "${distributionId}" --paths "/*"`;
270
+ logger_js_1.logger.debug(`Running: ${command}`);
271
+ try {
272
+ const result = (0, child_process_1.execSync)(command, {
273
+ encoding: 'utf-8',
274
+ stdio: verbose ? 'inherit' : ['pipe', 'pipe', 'pipe'],
275
+ });
276
+ if (!verbose) {
277
+ // Extract invalidation ID from response
278
+ const invalidationMatch = result.match(/"Id":\s*"([^"]+)"/);
279
+ if (invalidationMatch) {
280
+ logger_js_1.logger.info(`CloudFront invalidation created: ${invalidationMatch[1]}`);
281
+ }
282
+ }
283
+ logger_js_1.logger.success('CloudFront invalidation initiated (runs asynchronously)');
284
+ }
285
+ catch (error) {
286
+ throw new Error(`Failed to invalidate CloudFront: ${error.message}`);
287
+ }
288
+ }
289
+ /**
290
+ * Builds a frontend or CMS package with the API URL set.
291
+ *
292
+ * @param packagePath - Path to the package
293
+ * @param apiUrl - API URL to set as environment variable
294
+ * @param verbose - Show verbose output
295
+ *
296
+ * @example
297
+ * ```typescript
298
+ * buildPackage('/path/to/frontend', 'https://api.example.com', true);
299
+ * ```
300
+ */
301
+ function buildPackage(packagePath, apiUrl, verbose = false) {
302
+ const packageName = packagePath.split('/').pop();
303
+ logger_js_1.logger.info(`Building ${packageName} with API URL: ${apiUrl}`);
304
+ const command = 'pnpm build';
305
+ logger_js_1.logger.debug(`Running: ${command} in ${packagePath}`);
306
+ try {
307
+ (0, child_process_1.execSync)(command, {
308
+ cwd: packagePath,
309
+ stdio: verbose ? 'inherit' : ['pipe', 'pipe', 'pipe'],
310
+ env: {
311
+ ...process.env,
312
+ VITE_API_URL: apiUrl,
313
+ API_URL: apiUrl,
314
+ },
315
+ });
316
+ logger_js_1.logger.success(`Built ${packageName}`);
317
+ }
318
+ catch (error) {
319
+ throw new Error(`Failed to build ${packageName}: ${error.message}`);
320
+ }
321
+ }
322
+ /**
323
+ * Validates that AWS CLI is available and configured.
324
+ *
325
+ * @throws Error if AWS CLI is not available or not configured
326
+ */
327
+ function validateAwsCli() {
328
+ try {
329
+ (0, child_process_1.execSync)('aws --version', { stdio: ['pipe', 'pipe', 'pipe'] });
330
+ }
331
+ catch {
332
+ throw new Error('AWS CLI is not installed or not in PATH. ' +
333
+ 'Install it from https://aws.amazon.com/cli/ and run `aws configure`.');
334
+ }
335
+ try {
336
+ (0, child_process_1.execSync)('aws sts get-caller-identity', { stdio: ['pipe', 'pipe', 'pipe'] });
337
+ }
338
+ catch {
339
+ throw new Error('AWS credentials not configured. Run `aws configure` or set AWS environment variables.');
340
+ }
341
+ }
342
+ /**
343
+ * Lists all stacks in a project for a given stage.
344
+ *
345
+ * @param projectRoot - Path to project root
346
+ * @param stage - Deployment stage
347
+ * @returns Array of stack names
348
+ */
349
+ function listProjectStacks(projectRoot, stage) {
350
+ const projectName = getProjectName(projectRoot);
351
+ const pascalName = toPascalCase(projectName);
352
+ const stacks = [];
353
+ // Check for infrastructure stacks directory
354
+ const stacksDir = (0, path_1.join)(projectRoot, 'packages', 'infra', 'src', 'stacks');
355
+ if ((0, fs_1.existsSync)(stacksDir)) {
356
+ const files = (0, fs_1.readdirSync)(stacksDir);
357
+ for (const file of files) {
358
+ if (file.endsWith('-stack.ts')) {
359
+ // Extract stack name from file (e.g., 'api-stack.ts' -> 'Api')
360
+ const stackType = file
361
+ .replace('-stack.ts', '')
362
+ .split('-')
363
+ .map((w) => w.charAt(0).toUpperCase() + w.slice(1))
364
+ .join('');
365
+ stacks.push(`${pascalName}${stackType}Stack-${stage}`);
366
+ }
367
+ }
368
+ }
369
+ return stacks;
370
+ }
371
+ //# sourceMappingURL=deploy-utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deploy-utils.js","sourceRoot":"","sources":["../../src/lib/deploy-utils.ts"],"names":[],"mappings":"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"}
@@ -1,3 +1,78 @@
1
+ /**
2
+ * Configuration for a stack to be added to app.ts.
3
+ */
4
+ export interface StackConfig {
5
+ /**
6
+ * Display name of the stack (e.g., 'Frontend' or 'Cms').
7
+ */
8
+ name: string;
9
+ /**
10
+ * Class name of the stack (e.g., 'FrontendStack' or 'CmsStack').
11
+ */
12
+ className: string;
13
+ /**
14
+ * Import path for the stack (e.g., './stacks/frontend-stack').
15
+ */
16
+ importPath: string;
17
+ /**
18
+ * Variable name for the stack instance (e.g., 'frontendStack' or 'cmsStack').
19
+ */
20
+ variableName: string;
21
+ /**
22
+ * Array of stack variable names this stack depends on.
23
+ */
24
+ dependsOn: string[];
25
+ /**
26
+ * Props string to pass to stack constructor (e.g., '{ env, stage, apiUrl: apiStack.apiUrl }').
27
+ */
28
+ props: string;
29
+ /**
30
+ * Description for the stack comment.
31
+ */
32
+ description: string;
33
+ }
34
+ /**
35
+ * Options for generating a frontend stack.
36
+ */
37
+ export interface GenerateFrontendStackOptions {
38
+ /**
39
+ * Path to the project root.
40
+ */
41
+ projectPath: string;
42
+ /**
43
+ * Name of the project.
44
+ */
45
+ projectName: string;
46
+ /**
47
+ * Name of the API package.
48
+ */
49
+ apiName: string;
50
+ /**
51
+ * Name of the frontend package (default: 'frontend').
52
+ */
53
+ frontendName?: string;
54
+ }
55
+ /**
56
+ * Options for generating a CMS stack.
57
+ */
58
+ export interface GenerateCmsStackOptions {
59
+ /**
60
+ * Path to the project root.
61
+ */
62
+ projectPath: string;
63
+ /**
64
+ * Name of the project.
65
+ */
66
+ projectName: string;
67
+ /**
68
+ * Name of the API package.
69
+ */
70
+ apiName: string;
71
+ /**
72
+ * Name of the CMS package (default: 'cms').
73
+ */
74
+ cmsName?: string;
75
+ }
1
76
  /**
2
77
  * Options for generating the infrastructure package.
3
78
  */
@@ -21,4 +96,47 @@ export interface InfraGeneratorOptions {
21
96
  * @param options - Generation options
22
97
  */
23
98
  export declare function generateInfraPackage(options: InfraGeneratorOptions): void;
99
+ /**
100
+ * Returns the frontend-stack.ts template using FndRemixSite for Lambda-based SSR.
101
+ *
102
+ * @param projectName - Name of the project
103
+ * @param frontendPackageName - Name of the frontend package (default: 'frontend')
104
+ * @returns Generated TypeScript code for frontend stack
105
+ */
106
+ export declare function getFrontendStackTemplate(projectName: string, frontendPackageName?: string): string;
107
+ /**
108
+ * Returns the cms-stack.ts template using FndRemixSite for Lambda-based SSR.
109
+ *
110
+ * @param projectName - Name of the project
111
+ * @param cmsPackageName - Name of the CMS package (default: 'cms')
112
+ * @returns Generated TypeScript code for CMS stack
113
+ */
114
+ export declare function getCmsStackTemplate(projectName: string, cmsPackageName?: string): string;
115
+ /**
116
+ * Updates app.ts to add a new stack.
117
+ *
118
+ * This function performs incremental updates to the existing app.ts file:
119
+ * 1. Adds import statement for the new stack
120
+ * 2. Adds stack instantiation code
121
+ * 3. Adds dependency declarations
122
+ * 4. Updates the output summary if present
123
+ *
124
+ * @param appTsPath - Path to the app.ts file
125
+ * @param config - Stack configuration
126
+ * @param projectName - Name of the project (for console output)
127
+ * @returns true if update was successful, false if stack already exists
128
+ */
129
+ export declare function updateAppTsForStack(appTsPath: string, config: StackConfig, projectName: string): boolean;
130
+ /**
131
+ * Generates the frontend stack and updates app.ts.
132
+ *
133
+ * @param options - Generation options
134
+ */
135
+ export declare function generateFrontendStack(options: GenerateFrontendStackOptions): Promise<void>;
136
+ /**
137
+ * Generates the CMS stack and updates app.ts.
138
+ *
139
+ * @param options - Generation options
140
+ */
141
+ export declare function generateCmsStack(options: GenerateCmsStackOptions): Promise<void>;
24
142
  //# sourceMappingURL=infra-generator.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"infra-generator.d.ts","sourceRoot":"","sources":["../../src/lib/infra-generator.ts"],"names":[],"mappings":"AAIA;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC;;OAEG;IACH,WAAW,EAAE,MAAM,CAAC;IAEpB;;OAEG;IACH,WAAW,EAAE,MAAM,CAAC;IAEpB;;OAEG;IACH,cAAc,EAAE,MAAM,CAAC;CACxB;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,qBAAqB,GAAG,IAAI,CA2BzE"}
1
+ {"version":3,"file":"infra-generator.d.ts","sourceRoot":"","sources":["../../src/lib/infra-generator.ts"],"names":[],"mappings":"AAIA;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B;;OAEG;IACH,IAAI,EAAE,MAAM,CAAC;IAEb;;OAEG;IACH,SAAS,EAAE,MAAM,CAAC;IAElB;;OAEG;IACH,UAAU,EAAE,MAAM,CAAC;IAEnB;;OAEG;IACH,YAAY,EAAE,MAAM,CAAC;IAErB;;OAEG;IACH,SAAS,EAAE,MAAM,EAAE,CAAC;IAEpB;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IAEd;;OAEG;IACH,WAAW,EAAE,MAAM,CAAC;CACrB;AAED;;GAEG;AACH,MAAM,WAAW,4BAA4B;IAC3C;;OAEG;IACH,WAAW,EAAE,MAAM,CAAC;IAEpB;;OAEG;IACH,WAAW,EAAE,MAAM,CAAC;IAEpB;;OAEG;IACH,OAAO,EAAE,MAAM,CAAC;IAEhB;;OAEG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACtC;;OAEG;IACH,WAAW,EAAE,MAAM,CAAC;IAEpB;;OAEG;IACH,WAAW,EAAE,MAAM,CAAC;IAEpB;;OAEG;IACH,OAAO,EAAE,MAAM,CAAC;IAEhB;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC;;OAEG;IACH,WAAW,EAAE,MAAM,CAAC;IAEpB;;OAEG;IACH,WAAW,EAAE,MAAM,CAAC;IAEpB;;OAEG;IACH,cAAc,EAAE,MAAM,CAAC;CACxB;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,qBAAqB,GAAG,IAAI,CAuCzE;AAuuBD;;;;;;GAMG;AACH,wBAAgB,wBAAwB,CACtC,WAAW,EAAE,MAAM,EACnB,mBAAmB,SAAa,GAC/B,MAAM,CAiFR;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,WAAW,EAAE,MAAM,EAAE,cAAc,SAAQ,GAAG,MAAM,CAqFvF;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,mBAAmB,CACjC,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,WAAW,EACnB,WAAW,EAAE,MAAM,GAClB,OAAO,CA0FT;AA2BD;;;;GAIG;AACH,wBAAsB,qBAAqB,CACzC,OAAO,EAAE,4BAA4B,GACpC,OAAO,CAAC,IAAI,CAAC,CAqDf;AAED;;;;GAIG;AACH,wBAAsB,gBAAgB,CACpC,OAAO,EAAE,uBAAuB,GAC/B,OAAO,CAAC,IAAI,CAAC,CAoDf"}