mycontext-cli 2.0.34 → 2.0.36

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,323 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.GenerateScreensCommand = void 0;
40
+ exports.registerGenerateScreensCommand = registerGenerateScreensCommand;
41
+ const chalk_1 = __importDefault(require("chalk"));
42
+ const fs = __importStar(require("fs-extra"));
43
+ const path_1 = __importDefault(require("path"));
44
+ const fileNames_1 = require("../constants/fileNames");
45
+ const spinner_1 = require("../utils/spinner");
46
+ const logger_1 = require("../utils/logger");
47
+ const geminiClient_1 = require("../utils/geminiClient");
48
+ const child_process_1 = require("child_process");
49
+ const util_1 = require("util");
50
+ const execAsync = (0, util_1.promisify)(child_process_1.exec);
51
+ /**
52
+ * Generate visual screens (HTML/PNG) using Gemini API + nanobanana-style generation
53
+ * Reads context from .mycontext/ and generates screens with realistic previews
54
+ */
55
+ class GenerateScreensCommand {
56
+ constructor() {
57
+ this.spinner = new spinner_1.EnhancedSpinner("Generating screens...");
58
+ this.geminiClient = new geminiClient_1.GeminiClient();
59
+ }
60
+ async execute(screenName, options = {}) {
61
+ const projectPath = process.cwd();
62
+ const contextDir = path_1.default.join(projectPath, ".mycontext");
63
+ const screensDir = path_1.default.join(contextDir, "screens");
64
+ this.spinner.start();
65
+ // Check if .mycontext directory exists
66
+ if (!fs.existsSync(contextDir)) {
67
+ this.spinner.fail("No .mycontext directory found");
68
+ console.log(chalk_1.default.red("\n❌ No .mycontext directory found. Run 'mycontext init' first."));
69
+ return;
70
+ }
71
+ // Check if Gemini client is available
72
+ if (!this.geminiClient.hasApiKey()) {
73
+ this.spinner.fail("Gemini API key not found");
74
+ console.log(chalk_1.default.red("\n❌ Gemini API key not found. Set GEMINI_API_KEY in .mycontext/.env"));
75
+ console.log(chalk_1.default.blue("\n💡 Get your free API key at: https://aistudio.google.com/apikey"));
76
+ return;
77
+ }
78
+ try {
79
+ // Create screens directory if it doesn't exist
80
+ await fs.ensureDir(screensDir);
81
+ // Load context files
82
+ const context = await this.loadContext(contextDir);
83
+ // Determine which screens to generate
84
+ const screensToGenerate = await this.determineScreens(screenName, context, options);
85
+ this.spinner.succeed("Context loaded");
86
+ console.log(chalk_1.default.blue(`\n🎨 Generating ${screensToGenerate.length} screen(s)...\n`));
87
+ // Generate screens
88
+ const generatedScreens = [];
89
+ for (const screen of screensToGenerate) {
90
+ const screenSpinner = new spinner_1.EnhancedSpinner(`Generating ${screen.name}...`);
91
+ screenSpinner.start();
92
+ try {
93
+ const metadata = await this.generateScreen(screen, context, screensDir, options);
94
+ generatedScreens.push(metadata);
95
+ screenSpinner.succeed(`Generated ${screen.name}`);
96
+ }
97
+ catch (error) {
98
+ screenSpinner.fail(`Failed to generate ${screen.name}`);
99
+ logger_1.logger.error(`Screen generation error:`, error.message);
100
+ }
101
+ }
102
+ // Update screens manifest
103
+ await this.updateScreensManifest(screensDir, generatedScreens);
104
+ // Show summary
105
+ console.log(chalk_1.default.green(`\n✅ Generated ${generatedScreens.length} screen(s)`));
106
+ console.log(chalk_1.default.gray(` Output: ${screensDir}`));
107
+ // Auto-open in browser if requested
108
+ if (options.open !== false && generatedScreens.length > 0) {
109
+ await this.openInBrowser(screensDir, generatedScreens[0]);
110
+ }
111
+ }
112
+ catch (error) {
113
+ this.spinner.fail("Screen generation failed");
114
+ logger_1.logger.error("Error generating screens:", error.message);
115
+ throw error;
116
+ }
117
+ }
118
+ /**
119
+ * Load context files for screen generation
120
+ */
121
+ async loadContext(contextDir) {
122
+ const context = {};
123
+ // Load PRD
124
+ const prdPath = path_1.default.join(contextDir, fileNames_1.CONTEXT_FILES.PRD);
125
+ if (fs.existsSync(prdPath)) {
126
+ context.prd = fs.readFileSync(prdPath, "utf8");
127
+ }
128
+ // Load brand guidelines
129
+ const brandPath = path_1.default.join(contextDir, fileNames_1.CONTEXT_FILES.BRANDING);
130
+ if (fs.existsSync(brandPath)) {
131
+ context.brand = fs.readFileSync(brandPath, "utf8");
132
+ }
133
+ // Load user flows
134
+ const flowsPath = path_1.default.join(contextDir, fileNames_1.CONTEXT_FILES.USER_FLOWS);
135
+ if (fs.existsSync(flowsPath)) {
136
+ context.flows = fs.readFileSync(flowsPath, "utf8");
137
+ }
138
+ // Load features
139
+ const featuresPath = path_1.default.join(contextDir, fileNames_1.CONTEXT_FILES.FEATURES);
140
+ if (fs.existsSync(featuresPath)) {
141
+ context.features = fs.readFileSync(featuresPath, "utf8");
142
+ }
143
+ // Load sample data
144
+ const sampleDataPath = path_1.default.join(contextDir, "sample-data.json");
145
+ if (fs.existsSync(sampleDataPath)) {
146
+ try {
147
+ context.sampleData = JSON.parse(fs.readFileSync(sampleDataPath, "utf8"));
148
+ }
149
+ catch (error) {
150
+ logger_1.logger.warn("Could not load sample data");
151
+ }
152
+ }
153
+ return context;
154
+ }
155
+ /**
156
+ * Determine which screens to generate based on options and context
157
+ */
158
+ async determineScreens(screenName, context, options) {
159
+ const screens = [];
160
+ if (screenName) {
161
+ // Generate specific screen
162
+ screens.push({
163
+ name: screenName,
164
+ prompt: `Generate a ${screenName} screen for this application`,
165
+ });
166
+ }
167
+ else if (options.all) {
168
+ // Generate all screens from flows
169
+ const screenNames = this.extractScreenNamesFromFlows(context.flows);
170
+ screenNames.forEach((name) => {
171
+ screens.push({
172
+ name,
173
+ prompt: `Generate a ${name} screen for this application`,
174
+ });
175
+ });
176
+ }
177
+ else {
178
+ // Generate common screens
179
+ screens.push({ name: "home", prompt: "Generate a home/landing page" }, { name: "login", prompt: "Generate a login screen" }, { name: "dashboard", prompt: "Generate a dashboard screen" });
180
+ }
181
+ return screens;
182
+ }
183
+ /**
184
+ * Extract screen names from user flows
185
+ */
186
+ extractScreenNamesFromFlows(flows) {
187
+ if (!flows)
188
+ return [];
189
+ const screenNames = [];
190
+ const lines = flows.split("\n");
191
+ // Look for screen mentions in flows
192
+ lines.forEach((line) => {
193
+ // Match patterns like "1. Login Screen", "- Dashboard", etc.
194
+ const match = line.match(/(?:^|\s)([A-Z][a-z]+(?:\s[A-Z][a-z]+)*)\s*(?:Screen|Page|View)/i);
195
+ if (match && match[1]) {
196
+ const name = match[1].toLowerCase().replace(/\s+/g, "-");
197
+ if (!screenNames.includes(name)) {
198
+ screenNames.push(name);
199
+ }
200
+ }
201
+ });
202
+ return screenNames.length > 0 ? screenNames : ["home", "dashboard"];
203
+ }
204
+ /**
205
+ * Generate a single screen
206
+ */
207
+ async generateScreen(screen, context, screensDir, options) {
208
+ const includeScreenshot = options.format?.includes("png") || options.includeScreenshot || false;
209
+ // Generate visual screen using Gemini
210
+ const result = await this.geminiClient.generateVisualScreen(screen.prompt, context, { includeScreenshot });
211
+ // Create screen directory
212
+ const screenDir = path_1.default.join(screensDir, screen.name);
213
+ await fs.ensureDir(screenDir);
214
+ // Save HTML
215
+ const htmlPath = path_1.default.join(screenDir, "index.html");
216
+ await fs.writeFile(htmlPath, result.html, "utf8");
217
+ // Save screenshot if generated
218
+ if (result.screenshot) {
219
+ const pngPath = path_1.default.join(screenDir, "preview.png");
220
+ const buffer = Buffer.from(result.screenshot, "base64");
221
+ await fs.writeFile(pngPath, buffer);
222
+ }
223
+ // Save context metadata
224
+ const contextPath = path_1.default.join(screenDir, "context.json");
225
+ await fs.writeFile(contextPath, JSON.stringify({
226
+ prd: context.prd?.substring(0, 1000),
227
+ brand: context.brand?.substring(0, 500),
228
+ sampleData: context.sampleData,
229
+ }, null, 2), "utf8");
230
+ // Save generation metadata
231
+ const metadataPath = path_1.default.join(screenDir, "metadata.json");
232
+ const metadata = {
233
+ name: screen.name,
234
+ prompt: screen.prompt,
235
+ model: result.metadata.model,
236
+ timestamp: result.metadata.timestamp,
237
+ format: ["html", result.screenshot ? "png" : null].filter(Boolean),
238
+ path: screenDir,
239
+ };
240
+ await fs.writeFile(metadataPath, JSON.stringify(metadata, null, 2), "utf8");
241
+ return metadata;
242
+ }
243
+ /**
244
+ * Update screens manifest file
245
+ */
246
+ async updateScreensManifest(screensDir, screens) {
247
+ const manifestPath = path_1.default.join(screensDir, "screens-manifest.json");
248
+ // Load existing manifest if it exists
249
+ let manifest = {
250
+ screens: [],
251
+ lastUpdated: new Date().toISOString(),
252
+ };
253
+ if (fs.existsSync(manifestPath)) {
254
+ try {
255
+ manifest = JSON.parse(fs.readFileSync(manifestPath, "utf8"));
256
+ }
257
+ catch (error) {
258
+ logger_1.logger.warn("Could not load existing manifest");
259
+ }
260
+ }
261
+ // Update manifest with new screens
262
+ screens.forEach((newScreen) => {
263
+ const existingIndex = manifest.screens.findIndex((s) => s.name === newScreen.name);
264
+ if (existingIndex >= 0) {
265
+ manifest.screens[existingIndex] = newScreen;
266
+ }
267
+ else {
268
+ manifest.screens.push(newScreen);
269
+ }
270
+ });
271
+ manifest.lastUpdated = new Date().toISOString();
272
+ // Save manifest
273
+ await fs.writeFile(manifestPath, JSON.stringify(manifest, null, 2), "utf8");
274
+ }
275
+ /**
276
+ * Open generated screen in browser
277
+ */
278
+ async openInBrowser(screensDir, screen) {
279
+ const htmlPath = path_1.default.join(screen.path, "index.html");
280
+ if (!fs.existsSync(htmlPath)) {
281
+ logger_1.logger.warn("HTML file not found, cannot open in browser");
282
+ return;
283
+ }
284
+ try {
285
+ console.log(chalk_1.default.blue("\n🌐 Opening screen in browser..."));
286
+ // Platform-specific open command
287
+ const command = process.platform === "darwin"
288
+ ? "open"
289
+ : process.platform === "win32"
290
+ ? "start"
291
+ : "xdg-open";
292
+ await execAsync(`${command} "${htmlPath}"`);
293
+ }
294
+ catch (error) {
295
+ logger_1.logger.warn("Could not auto-open browser:", error);
296
+ console.log(chalk_1.default.gray(`\n💡 Manually open: ${htmlPath}`));
297
+ }
298
+ }
299
+ }
300
+ exports.GenerateScreensCommand = GenerateScreensCommand;
301
+ /**
302
+ * Register the generate:screens command
303
+ */
304
+ function registerGenerateScreensCommand(program) {
305
+ program
306
+ .command("generate:screens [screen-name]")
307
+ .alias("gs")
308
+ .description("Generate visual screens (HTML/PNG) using Gemini API with full context")
309
+ .option("-a, --all", "Generate all screens from user flows")
310
+ .option("-f, --format <formats>", "Output formats: html, png, or both", "html")
311
+ .option("-o, --output <path>", "Output directory (default: .mycontext/screens)")
312
+ .option("-s, --screenshot", "Include PNG screenshots (requires puppeteer)")
313
+ .option("--no-open", "Don't auto-open in browser")
314
+ .option("-v, --verbose", "Show detailed output")
315
+ .action(async (screenName, options) => {
316
+ const command = new GenerateScreensCommand();
317
+ await command.execute(screenName, {
318
+ ...options,
319
+ includeScreenshot: options.screenshot || options.format?.includes("png"),
320
+ });
321
+ });
322
+ }
323
+ //# sourceMappingURL=generate-screens.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generate-screens.js","sourceRoot":"","sources":["../../src/commands/generate-screens.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,94 @@
1
+ {
2
+ "claude": {
3
+ "enabled": true,
4
+ "priority": 0,
5
+ "models": {
6
+ "default": "claude-sonnet-4-20250514",
7
+ "fast": "claude-3-5-haiku-20241022",
8
+ "advanced": "claude-opus-4-20250514"
9
+ },
10
+ "api": {
11
+ "baseUrl": "https://api.anthropic.com/v1",
12
+ "timeout": 120000,
13
+ "retries": 3
14
+ }
15
+ },
16
+ "openrouter": {
17
+ "enabled": true,
18
+ "priority": 1,
19
+ "models": {
20
+ "default": "deepseek/deepseek-r1-distill-llama-70b",
21
+ "fast": "deepseek/deepseek-r1-distill-qwen-32b",
22
+ "advanced": "deepseek/deepseek-r1"
23
+ },
24
+ "api": {
25
+ "baseUrl": "https://openrouter.ai/api/v1",
26
+ "timeout": 120000,
27
+ "retries": 3
28
+ }
29
+ },
30
+ "gemini": {
31
+ "enabled": true,
32
+ "priority": 2,
33
+ "models": {
34
+ "default": "gemini-2.0-flash-exp",
35
+ "fast": "gemini-1.5-flash-latest",
36
+ "advanced": "gemini-2.0-flash-thinking-exp-01-21"
37
+ },
38
+ "api": {
39
+ "baseUrl": "https://generativelanguage.googleapis.com/v1beta",
40
+ "timeout": 120000,
41
+ "retries": 3
42
+ }
43
+ },
44
+ "xai": {
45
+ "enabled": true,
46
+ "priority": 3,
47
+ "models": {
48
+ "default": "grok-beta",
49
+ "fast": "grok-beta",
50
+ "advanced": "grok-beta"
51
+ },
52
+ "api": {
53
+ "baseUrl": "https://api.x.ai/v1",
54
+ "timeout": 120000,
55
+ "retries": 3
56
+ }
57
+ },
58
+ "openai": {
59
+ "enabled": true,
60
+ "priority": 4,
61
+ "models": {
62
+ "default": "gpt-4o",
63
+ "fast": "gpt-4o-mini",
64
+ "advanced": "o1"
65
+ },
66
+ "api": {
67
+ "baseUrl": "https://api.openai.com/v1",
68
+ "timeout": 120000,
69
+ "retries": 3
70
+ }
71
+ },
72
+ "huggingface": {
73
+ "enabled": false,
74
+ "priority": 10,
75
+ "models": {
76
+ "default": "mistralai/Mixtral-8x7B-Instruct-v0.1"
77
+ },
78
+ "api": {
79
+ "baseUrl": "https://api-inference.huggingface.co",
80
+ "timeout": 60000,
81
+ "retries": 2
82
+ }
83
+ },
84
+ "fallback": {
85
+ "enabled": true,
86
+ "priority": 99,
87
+ "models": {},
88
+ "api": {
89
+ "baseUrl": "",
90
+ "timeout": 60000,
91
+ "retries": 1
92
+ }
93
+ }
94
+ }
package/dist/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "mycontext-cli",
3
- "version": "2.0.34",
4
- "description": "Component-first visual builder with zero-error guarantees. Generate and validate React/Next.js components one at a time, preview them visually, then scale to complete applications using Claude Agent SDK.",
3
+ "version": "2.0.36",
4
+ "description": "Spec-Driven Development for the AI Era - Generate comprehensive context + visual screens, then code with Claude/Cursor",
5
5
  "main": "dist/cli.js",
6
6
  "bin": {
7
7
  "mycontext-cli": "dist/cli.js",
@@ -0,0 +1,92 @@
1
+ export interface GeminiMessage {
2
+ role: "user" | "assistant" | "system";
3
+ content: string;
4
+ }
5
+ export interface GeminiGenerationConfig {
6
+ temperature?: number;
7
+ maxTokens?: number;
8
+ topP?: number;
9
+ topK?: number;
10
+ stopSequences?: string[];
11
+ }
12
+ export interface GeminiResponse {
13
+ content: string;
14
+ model: string;
15
+ finishReason?: string;
16
+ usage?: {
17
+ promptTokens: number;
18
+ completionTokens: number;
19
+ totalTokens: number;
20
+ };
21
+ }
22
+ export interface GeminiVisualResponse {
23
+ html: string;
24
+ screenshot?: string;
25
+ metadata: {
26
+ model: string;
27
+ timestamp: string;
28
+ prompt: string;
29
+ };
30
+ }
31
+ /**
32
+ * Gemini API Client with nanobanana support for visual generation
33
+ * Supports both text generation and HTML/screenshot generation
34
+ */
35
+ export declare class GeminiClient {
36
+ private apiKey;
37
+ private baseUrl;
38
+ private client;
39
+ private model;
40
+ constructor();
41
+ /**
42
+ * Get Gemini API key from environment
43
+ */
44
+ private getApiKey;
45
+ /**
46
+ * Check if Gemini client has a valid API key
47
+ */
48
+ hasApiKey(): boolean;
49
+ /**
50
+ * Generate text completion using Gemini
51
+ */
52
+ generateText(messages: GeminiMessage[], config?: GeminiGenerationConfig): Promise<GeminiResponse>;
53
+ /**
54
+ * Generate visual screen (HTML + optional screenshot) using Gemini + nanobanana
55
+ * This uses Gemini's multimodal capabilities to generate HTML
56
+ */
57
+ generateVisualScreen(prompt: string, context?: {
58
+ prd?: string;
59
+ brand?: string;
60
+ flows?: string;
61
+ sampleData?: any;
62
+ }, config?: GeminiGenerationConfig & {
63
+ includeScreenshot?: boolean;
64
+ }): Promise<GeminiVisualResponse>;
65
+ /**
66
+ * Build comprehensive prompt for visual screen generation
67
+ */
68
+ private buildVisualPrompt;
69
+ /**
70
+ * Extract HTML from Gemini response (handles markdown code blocks)
71
+ */
72
+ private extractHtml;
73
+ /**
74
+ * Generate screenshot from HTML using nanobanana-style approach
75
+ * For now, this is a placeholder - actual implementation would use puppeteer/playwright
76
+ * or a headless browser API
77
+ */
78
+ private generateScreenshot;
79
+ /**
80
+ * Convert messages to Gemini API format
81
+ */
82
+ private convertMessages;
83
+ /**
84
+ * Test Gemini API connection
85
+ */
86
+ testConnection(): Promise<boolean>;
87
+ /**
88
+ * Get available Gemini models
89
+ */
90
+ listModels(): Promise<string[]>;
91
+ }
92
+ //# sourceMappingURL=geminiClient.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"geminiClient.d.ts","sourceRoot":"","sources":["../../src/utils/geminiClient.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,GAAG,WAAW,GAAG,QAAQ,CAAC;IACtC,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,sBAAsB;IACrC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;CAC1B;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,KAAK,CAAC,EAAE;QACN,YAAY,EAAE,MAAM,CAAC;QACrB,gBAAgB,EAAE,MAAM,CAAC;QACzB,WAAW,EAAE,MAAM,CAAC;KACrB,CAAC;CACH;AAED,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE;QACR,KAAK,EAAE,MAAM,CAAC;QACd,SAAS,EAAE,MAAM,CAAC;QAClB,MAAM,EAAE,MAAM,CAAC;KAChB,CAAC;CACH;AAED;;;GAGG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,MAAM,CAAgB;IAC9B,OAAO,CAAC,KAAK,CAAS;;IAgBtB;;OAEG;IACH,OAAO,CAAC,SAAS;IAejB;;OAEG;IACH,SAAS,IAAI,OAAO;IASpB;;OAEG;IACG,YAAY,CAChB,QAAQ,EAAE,aAAa,EAAE,EACzB,MAAM,CAAC,EAAE,sBAAsB,GAC9B,OAAO,CAAC,cAAc,CAAC;IA+C1B;;;OAGG;IACG,oBAAoB,CACxB,MAAM,EAAE,MAAM,EACd,OAAO,CAAC,EAAE;QACR,GAAG,CAAC,EAAE,MAAM,CAAC;QACb,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,UAAU,CAAC,EAAE,GAAG,CAAC;KAClB,EACD,MAAM,CAAC,EAAE,sBAAsB,GAAG;QAAE,iBAAiB,CAAC,EAAE,OAAO,CAAA;KAAE,GAChE,OAAO,CAAC,oBAAoB,CAAC;IA6ChC;;OAEG;IACH,OAAO,CAAC,iBAAiB;IA8CzB;;OAEG;IACH,OAAO,CAAC,WAAW;IAuBnB;;;;OAIG;YACW,kBAAkB;IAmBhC;;OAEG;IACH,OAAO,CAAC,eAAe;IASvB;;OAEG;IACG,cAAc,IAAI,OAAO,CAAC,OAAO,CAAC;IAexC;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;CAWtC"}