@fridaplatform-stk/figma2frida-mcp 1.0.8 → 1.0.9

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.
@@ -1874,7 +1874,7 @@ ${match.technical || "No technical documentation available"}
1874
1874
  };
1875
1875
 
1876
1876
  // src/figma2frida/services/auth/token-validator.ts
1877
- var VALIDATION_URL = "https://us-central1-figma2frida-mcp.cloudfunctions.net/validateSession";
1877
+ var VALIDATION_URL = "https://apis.f2fmcp.fridaplatform.online/validateSession";
1878
1878
  async function validateSession(sessionToken) {
1879
1879
  logger.info("\u{1F510} Validating session...");
1880
1880
  try {
@@ -2300,13 +2300,12 @@ var LOCAL_VERSION = "1.0.1";
2300
2300
  logger.info(`Figma2Frida MCP Server v${MCP_VERSION} (Server: ${LOCAL_VERSION}) [${ENVIRONMENT}]`);
2301
2301
  logger.info(`Transport: ${process.env.HTTP_STREAM === "true" ? "HTTP Stream" : "stdio"}`);
2302
2302
  logger.info(`Node.js: ${process.version}`);
2303
- logger.debug("Loading hardcoded configuration...");
2304
2303
  process.env.PINECONE_INDEX = "figma2frida";
2305
2304
  process.env.PINECONE_MIN_SCORE = "0.4";
2306
2305
  process.env.PINECONE_TOP_K = "12";
2307
2306
  process.env.FRIDA_PINECONE_PROXY_URL = "https://azf-frida-pinecone-proxy.azurewebsites.net";
2308
- process.env.FRIDA_API_URL = "https://frida-llm-api-dev.azurewebsites.net/v1/responses";
2309
- process.env.FRIDA_EMBEDDING_URL = "https://frida-llm-api.azurewebsites.net/v1/embeddings";
2307
+ process.env.FRIDA_API_URL = "https://frida.azure-api.net/frida-llm-api/v1/responses";
2308
+ process.env.FRIDA_EMBEDDING_URL = "https://frida.azure-api.net/frida-llm-api/v1/embeddings";
2310
2309
  process.env.FRIDA_EMBEDDING_MODEL = "text-embedding-ada-002";
2311
2310
  process.env.FRIDA_MODEL = "gpt-5.1-codex";
2312
2311
  process.env.FRIDA_MAX_TOKENS = "12000";
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/figma2frida/figma2frida.ts","../src/figma2frida/utils/logger.ts","../src/figma2frida/clients/figma-client.ts","../src/figma2frida/utils/design-query-extractor/metadata-extractor-simpler.ts","../src/figma2frida/utils/design-query-extractor/design-context-extractor.ts","../src/figma2frida/utils/design-query-extractor/query-builder.ts","../src/figma2frida/utils/design-query-extractor/index.ts","../src/figma2frida/services/pinecone/pinecone-service.ts","../src/figma2frida/utils/formatters.ts","../src/figma2frida/services/auth/token-validator.ts","../src/figma2frida/services/frida/frida-client.ts","../src/figma2frida/handlers/library-filter-handler.ts"],"sourcesContent":["#!/usr/bin/env node\n/**\n * Figma MCP Proxy Server\n * \n * Simple wrapper around official Figma Desktop MCP.\n * \n * Tools:\n * 1. test_figma_connection - Get a screenshot to verify connection\n * 2. figma_get_design_context - Get design data and generated code from Figma\n */\n\n// ============================================================================\n// IMPORTS (before environment setup)\n// ============================================================================\nimport { z } from \"zod\";\nimport yargs from \"yargs\";\nimport { hideBin } from \"yargs/helpers\";\nimport { FastMCP, type ContentResult, type Content } from \"fastmcp\";\nimport { createRequire } from \"module\";\nimport { fileURLToPath } from \"url\";\nimport { dirname, join } from \"path\";\n\n// ============================================================================\n// ENVIRONMENT CONFIGURATION (set before logger import)\n// ============================================================================\nconst ENVIRONMENT = \"production\"; // Change mode to \"production\" / \"development\"\nprocess.env.NODE_ENV = ENVIRONMENT; // Set BEFORE importing logger\n\n// Now import logger (it will read NODE_ENV correctly)\nimport { logger } from \"./utils/logger.js\";\nimport { FigmaClient } from \"./clients/figma-client.js\";\n// import { FigmaDesignContextResult } from \"./clients/figma-client.js\";\n// import { handleComponentSuggestion } from \"./handlers/component-suggestion-handler.js\";\n// import { ComponentExtractor } from \"./utils/component-extractor.js\";\n// import { ComponentLookupService } from \"./services/component-lookup.js\";\n// import type { ComponentMatch } from \"./services/pinecone/pinecone-service.js\";\nimport { DesignQueryExtractor } from \"./utils/design-query-extractor/index.js\";\nimport { PineconeSearchService } from \"./services/pinecone/pinecone-service.js\";\nimport { Formatters } from \"./utils/formatters.js\";\nimport { validateSession } from \"./services/auth/token-validator.js\";\nimport { filterComponentsWithFrida } from \"./handlers/library-filter-handler.js\";\n\n// ============================================================================\n// VERSION INFO\n// ============================================================================\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\nconst require = createRequire(import.meta.url);\n// When running from dist/figma2frida.js, __dirname is dist/, so go up one level to find package.json\nconst packageJson = require(join(__dirname, \"../package.json\"));\nconst MCP_VERSION = packageJson.version;\nconst LOCAL_VERSION = \"1.0.1\";\n\n// Initial startup log (visible in development, hidden in production)\nlogger.info(`Figma2Frida MCP Server v${MCP_VERSION} (Server: ${LOCAL_VERSION}) [${ENVIRONMENT}]`);\nlogger.info(`Transport: ${process.env.HTTP_STREAM === \"true\" ? \"HTTP Stream\" : \"stdio\"}`);\nlogger.info(`Node.js: ${process.version}`);\n\n// ============================================================================\n// HARDCODED CONFIGURATION - Set process.env variables\n// ============================================================================\nlogger.debug(\"Loading hardcoded configuration...\");\n\n// Pinecone Configuration\nprocess.env.PINECONE_INDEX = \"figma2frida\";\nprocess.env.PINECONE_MIN_SCORE = \"0.4\";\nprocess.env.PINECONE_TOP_K = \"12\";\nprocess.env.FRIDA_PINECONE_PROXY_URL = \"https://azf-frida-pinecone-proxy.azurewebsites.net\";\n\n// Frida AI Configuration\n// FRIDA_BEARER_TOKEN is set from session validation (see below)\n// Dev responses API (testing). Prod: https://frida.azure-api.net/frida-llm-api/v1/responses\nprocess.env.FRIDA_API_URL = \"https://frida-llm-api-dev.azurewebsites.net/v1/responses\";\nprocess.env.FRIDA_EMBEDDING_URL = \"https://frida-llm-api.azurewebsites.net/v1/embeddings\";\nprocess.env.FRIDA_EMBEDDING_MODEL = \"text-embedding-ada-002\";\nprocess.env.FRIDA_MODEL = \"gpt-5.1-codex\";\nprocess.env.FRIDA_MAX_TOKENS = \"12000\";\n\n// Server Configuration\nprocess.env.HTTP_STREAM = \"false\"; // Set to \"true\" for HTTP mode, \"false\" for stdio\nprocess.env.PORT = \"8080\";\n\n// Log configuration (only in debug mode - hide sensitive values in production)\nlogger.debug(`PINECONE_INDEX: ${process.env.PINECONE_INDEX}`);\nlogger.debug(`PINECONE_MIN_SCORE: ${process.env.PINECONE_MIN_SCORE}`);\nlogger.debug(`PINECONE_TOP_K: ${process.env.PINECONE_TOP_K}`);\nlogger.debug(`FRIDA_PINECONE_PROXY_URL: ${process.env.FRIDA_PINECONE_PROXY_URL}`);\nlogger.debug(`FRIDA_API_URL: ${process.env.FRIDA_API_URL}`);\nlogger.debug(`FRIDA_EMBEDDING_URL: ${process.env.FRIDA_EMBEDDING_URL}`);\nlogger.debug(`FRIDA_EMBEDDING_MODEL: ${process.env.FRIDA_EMBEDDING_MODEL}`);\nlogger.debug(`FRIDA_MODEL: ${process.env.FRIDA_MODEL}`);\nlogger.debug(`FRIDA_MAX_TOKENS: ${process.env.FRIDA_MAX_TOKENS}`);\nlogger.debug(`HTTP_STREAM: ${process.env.HTTP_STREAM}`);\nlogger.debug(`PORT: ${process.env.PORT}`);\nlogger.info(\"Configuration loaded\");\n\n// Parse command-line arguments - session token only\nconst argv = yargs(hideBin(process.argv))\n .option(\"session-token\", {\n type: \"string\",\n description: \"Session token for authentication\",\n demandOption: true,\n })\n .parseSync();\n\n// Validate session token from CLI\nconst SESSION_TOKEN = argv.sessionToken?.trim();\nif (!SESSION_TOKEN || SESSION_TOKEN === \"\") {\n logger.error(\"❌ SHUTDOWN: Invalid or missing --session-token.\");\n process.exit(1);\n}\n\n// ============================================================================\n// SESSION VALIDATION\n// ============================================================================\n// Validate session and retrieve config before proceeding\nlet PINECONE_NAMESPACE: string = \"\";\ntry {\n const session = await validateSession(SESSION_TOKEN);\n PINECONE_NAMESPACE = session.projectId;\n process.env.FRIDA_BEARER_TOKEN = session.llmopsApiKey;\n process.env.MCP_USER_EMAIL = session.email;\n process.env.MCP_USER_ID = session.userId;\n logger.info(`Authenticated as ${session.email}`);\n logger.debug(`PINECONE_NAMESPACE: ${PINECONE_NAMESPACE}`);\n logger.debug(`FRIDA_BEARER_TOKEN: ${session.llmopsApiKey.substring(0, 8)}... (hidden)`);\n} catch (error) {\n logger.error(\"❌ SHUTDOWN: Session validation failed. MCP server cannot start.\");\n process.exit(1);\n}\n\n// Read HTTP_STREAM and PORT from environment variables (.env file)\nconst HTTP_STREAM = process.env.HTTP_STREAM === \"true\" || process.env.HTTP_STREAM === \"1\";\nconst PORT = parseInt(process.env.PORT || \"8080\", 10);\n\n\nconst server = new FastMCP({\n instructions: `You are a Figma design developer. Use the available tools to analyze Figma designs.`,\n name: \"figma2frida_mcp\",\n version: MCP_VERSION,\n});\n\n// Initialize Figma MCP client\nlogger.debug(\"Initializing Figma Client...\");\nconst figmaClient = new FigmaClient(\"http://127.0.0.1:3845/sse\");\nlogger.debug(\"Figma Client object created\");\n\n// Connect to Figma MCP on startup\nlet figmaConnected = false;\nlogger.debug(\"Starting initial connection attempt to Figma MCP (non-blocking)...\");\n\nconst connectionStartTime = Date.now();\nfigmaClient\n .connect()\n .then(() => {\n const connectionTime = Date.now() - connectionStartTime;\n figmaConnected = true;\n logger.debug(`Connected to Figma MCP (${connectionTime}ms)`);\n })\n .catch((error) => {\n const connectionTime = Date.now() - connectionStartTime;\n logger.warn(`Failed to connect to Figma MCP (${connectionTime}ms)`);\n logger.debug(\"Error type:\", error?.constructor?.name || typeof error);\n logger.debug(\"Error message:\", error instanceof Error ? error.message : String(error));\n\n if (error && typeof error === 'object') {\n const errorObj = error as Record<string, unknown>;\n if ('code' in errorObj) {\n logger.debug(\"Error code:\", errorObj.code);\n }\n }\n\n if (error instanceof Error && error.stack) {\n logger.debug(\"Error stack:\", error.stack);\n }\n\n logger.warn(\"Make sure Figma Desktop is running with MCP enabled at http://127.0.0.1:3845/sse\");\n logger.debug(\"Tools will attempt to reconnect when called\");\n });\n\n\n// TOOL 1: Get Design Context (Design Data and Generated Code)\n// ============================================================================\n\nserver.addTool({\n name: \"analyze_design\",\n description: `Get design context from a Figma node including design data and generated code.\n\n**What this does:**\n- Fetches design data and generated code from Figma\n- Returns React/TypeScript code based on the Figma design\n- Includes design tokens and styling information\n\n**Output:**\n- Generated React/TypeScript code\n- Design tokens and styles\n- Design structure information\n\n**Usage:**\n- Set withLibrarySearch to enable component library search flow (default: false)\n\n**Input:**\njson\n{\n \"withLibrarySearch\": false\n}`,\n annotations: {\n title: \"Analyze Design\",\n readOnlyHint: true,\n openWorldHint: false,\n },\n parameters: z.object({\n withLibrarySearch: z\n .boolean()\n .optional()\n .default(false)\n .describe(\"Enable component library search flow (default: false). When true will trigger analyze_frame_extraction, when false call analyze_frame.\"),\n }),\n execute: async (args, _context) => {\n try {\n const withLibrarySearch = args.withLibrarySearch ?? false;\n logger.debug(`withLibrarySearch: ${withLibrarySearch}`);\n logger.debug(`figmaConnected flag: ${figmaConnected}`);\n\n if (!figmaConnected) {\n logger.warn(\"Early return: figmaConnected is false\");\n const result: ContentResult = {\n content: [{\n type: \"text\" as const,\n text: \"❌ Not connected to Figma MCP. Check logs for connection details.\"\n }],\n };\n return result;\n }\n\n logger.debug(\"Calling figmaClient.getDesignContext()...\");\n const designContext = await figmaClient.getDesignContext();\n\n if (!designContext.content || designContext.content.length === 0) {\n const result: ContentResult = {\n content: [{ type: \"text\" as const, text: \"❌ No design context returned\" }],\n };\n return result;\n }\n\n // Add mandatory workflow instruction - conditionally based on withLibrarySearch\n const workflowInstruction: Content = {\n type: \"text\" as const,\n text: `**MANDATORY NEXT STEP - YOU MUST COMPLETE:**\n\nAfter receiving this design context, you **MUST** call the tool ${withLibrarySearch ? '`analyze_frame_extraction`' : '`analyze_frame`'} to get the visual reference and keywords.\n`,\n };\n\n return {\n content: [...(designContext.content as Content[]), workflowInstruction],\n } as ContentResult;\n } catch (error) {\n logger.error(\"Failed to get design context:\", error instanceof Error ? error.message : String(error));\n const result: ContentResult = {\n content: [{\n type: \"text\" as const,\n text: `❌ Failed to get design context: ${error instanceof Error ? error.message : String(error)}`,\n }],\n };\n return result;\n }\n },\n});\n\n// TOOL 2: Get Screenshot (Visual Reference)\n// ============================================================================\n\nserver.addTool({\n name: \"analyze_frame\",\n description: `Get a screenshot of a Figma node for visual reference with UI element analysis.`,\n annotations: {\n title: \"Analyze Frame\",\n readOnlyHint: true,\n openWorldHint: false,\n },\n parameters: z.object({\n }),\n execute: async (_context) => {\n try {\n // logger.debug(`Tool called with nodeId: ${args.nodeId || 'current selection'}`);\n logger.debug(`figmaConnected flag: ${figmaConnected}`);\n\n if (!figmaConnected) {\n logger.warn(\"Early return: figmaConnected is false\");\n const result: ContentResult = {\n content: [{\n type: \"text\" as const,\n text: \"❌ Not connected to Figma MCP. Check logs for connection details.\"\n }],\n };\n return result;\n }\n\n logger.debug(\"Calling figmaClient.getScreenshot()...\");\n const screenshot = await figmaClient.getScreenshot();\n\n if (!screenshot.content || screenshot.content.length === 0) {\n const result: ContentResult = {\n content: [{ type: \"text\" as const, text: \"❌ No screenshot returned\" }],\n };\n return result;\n }\n\n // Add instruction for AI to analyze the image and provide UI elements list\n const analysisInstruction: Content = {\n type: \"text\" as const,\n text: `**Screenshot Retrieved**\n\nYou **MUST** analyze the screenshot image above and generate pixel perfect code to the Figma design.\n\n**Output:**\nGenerate complete, pixel perfect code that visually matches the screenshot with pixel-perfect accuracy. The generated code should be indistinguishable from the design when rendered.\n\n**What to Identify:**\n- **Interactive elements:** buttons, inputs, forms, dropdowns, checkboxes, radio buttons, switches, sliders, links\n- **Layout components:** cards, containers, headers, footers, navigation bars, sidebars, grids, columns\n- **Content elements:** text fields, labels, icons, images, badges, chips, avatars, dividers\n- **Form elements:** text inputs, textareas, select dropdowns, date pickers, file uploads\n- **Navigation:** menus, tabs, breadcrumbs, pagination, search bars\n- **Other:** modals, tooltips, alerts, notifications, toolbars, action bars\n`,\n };\n\n return {\n content: [analysisInstruction, ...(screenshot.content as Content[])],\n } as ContentResult;\n } catch (error) {\n logger.error(\"Failed to get screenshot:\", error instanceof Error ? error.message : String(error));\n const result: ContentResult = {\n content: [{\n type: \"text\" as const,\n text: `❌ Failed to get screenshot: ${error instanceof Error ? error.message : String(error)}`,\n }],\n };\n return result;\n }\n },\n});\n\n\n// ============================================================================\n// ============================================================================\n// CASE 2: FIGMA SUGGEST COMPONENTS\n// ============================================================================\n// ============================================================================\n\n// ============================================================================\n// TOOL 3: Figma Extract Components: Analyze All Extracted (Frame + Metadata + Design) and get components from library\n// From already having a screen I want to suggest components from the library that fit. Will call get_components_from_library.\n// ============================================================================\n\nserver.addTool({\n name: \"analyze_frame_extraction\",\n description: `Analyze all data from frame and extract to identify components and UI elements in parallel and return all results combined.\n\n**What this does:**\n- Executes tools 1 (screenshot), 2 (metadata), and 3 (design context) concurrently\n- Returns everything in one response: visual reference, structure, and generated code\n\n**Output:**\n- Keywords extracted from figma metadata and design context.\n\n**Input:**\njson\n{\n}\n`,\n annotations: {\n title: \"Analyze All Extracted\",\n readOnlyHint: true,\n openWorldHint: false,\n },\n parameters: z.object({\n }),\n execute: async ( _context) => {\n try {\n logger.debug(`figmaConnected flag: ${figmaConnected}`);\n\n if (!figmaConnected) {\n logger.warn(\"Early return: figmaConnected is false\");\n return {\n content: [{\n type: \"text\" as const,\n text: \"❌ Not connected to Figma MCP. Check logs for connection details.\"\n }],\n } as ContentResult;\n }\n\n\n const [screenshot, metadata, designContext] = await Promise.all([\n figmaClient.getScreenshot(),\n figmaClient.getMetadata(),\n figmaClient.getDesignContext(),\n ]);\n\n // Extract queries from metadata and design context\n const queryExtractor = new DesignQueryExtractor();\n\n // Extract query from metadata (using metadata-specific extraction)\n let metadataQuery = \"UI component\";\n try {\n // Use metadata-specific extraction method\n const metadataAsDesignContext = {\n content: metadata.content || []\n };\n metadataQuery = queryExtractor.extractQueryFromMetadata(metadataAsDesignContext);\n } catch (error) {\n logger.warn(\"Failed to extract query from metadata:\", error instanceof Error ? error.message : String(error));\n }\n\n // Extract query from design context\n let designContextQuery = \"UI component\";\n try {\n designContextQuery = queryExtractor.extractQuery(designContext, \"UI component\");\n } catch (error) {\n logger.warn(\"Failed to extract query from design context:\", error instanceof Error ? error.message : String(error));\n }\n\n const combined: Content[] = [];\n\n // Add screenshot first (needed for analysis)\n if (screenshot.content?.length) {\n combined.push(...(screenshot.content as Content[]));\n }\n\n // Add instruction to analyze screenshot and create description\n combined.push({\n type: \"text\" as const,\n text: `## 2. Frame Description\\n\\nYou **MUST** analyze the screenshot image above and identify all components and UI elements visible in the Figma frame.\\n\\n**What to Identify:**\\n- **Interactive elements:** buttons, inputs, forms, dropdowns, checkboxes, radio buttons, switches, sliders, links\\n- **Layout components:** cards, containers, headers, footers, navigation bars, sidebars, grids, columns\\n- **Content elements:** text fields, labels, icons, images, badges, chips, avatars, dividers\\n- **Form elements:** text inputs, textareas, select dropdowns, date pickers, file uploads\\n- **Navigation:** menus, tabs, breadcrumbs, pagination, search bars\\n- **Other:** modals, tooltips, alerts, notifications, toolbars, action bars.`,\n });\n\n combined.push({\n type: \"text\" as const,\n text: `\n**MANDATORY NEXT STEP — YOU MUST COMPLETE:**\n\nAfter receiving this analyze_frame_extraction output, you **MUST** call the tool \\`get_components_from_library\\` with a \\`query\\` that describes the UI elements, components, or patterns from the design above (a description of the components found in the UI\").\n\n**Required call:**\n\\`\\`\\`json\n{\n \"query\": \"your description query of the components and UI elements found in the UI. MANDATORY: MUST Include '${metadataQuery}' and '${designContextQuery}' \"\n}\n`,\n });\n\n return { content: combined } as ContentResult;\n } catch (error) {\n logger.error(\"analyze_frame_extraction failed:\", error instanceof Error ? error.message : String(error));\n return {\n content: [{\n type: \"text\" as const,\n text: `❌ analyze_frame_extraction failed: ${error instanceof Error ? error.message : String(error)}`,\n }],\n } as ContentResult;\n }\n },\n});\n\n// ============================================================================\n// TOOL 4: Get Components From Library BY Query\n// ============================================================================\n\nserver.addTool({\n name: \"get_components_from_library\",\n description: `Get components from library.`,\n annotations: {\n title: \"Get Components From Library\",\n readOnlyHint: true,\n openWorldHint: false,\n },\n parameters: z.object({\n query: z\n .string()\n .describe(\"User query text to search for components in the library.\"),\n }),\n execute: async (args, _context) => {\n try {\n logger.debug(\"get_components_from_library called\");\n logger.debug(`query: ${args.query}`);\n\n // Create PineconeSearchService instance with namespace\n const searchService = new PineconeSearchService({\n namespace: PINECONE_NAMESPACE,\n });\n\n // Search for components\n const searchResults = await searchService.search(args.query);\n\n // Filter components using Frida AI (if enabled)\n const { filteredResults } = await filterComponentsWithFrida({\n query: args.query,\n searchResults,\n });\n\n // Format results using Formatters\n const formattedResults = Formatters.toMarkdown(filteredResults);\n\n return {\n content: [\n {\n type: \"text\" as const,\n text: formattedResults,\n },\n ],\n };\n } catch (error) {\n logger.error(\"get_components_from_library error:\", error);\n return {\n content: [\n {\n type: \"text\" as const,\n text: `❌ Error: ${error instanceof Error ? error.message : String(error)}`,\n },\n ],\n };\n }\n },\n});\n\n\n// ============================================================================\n// ============================================================================\n// CASE 3: IMPROVE LAYOUT AND DESIGN\n// ============================================================================\n// ============================================================================\n\n// ============================================================================\n// TOOL: Improve Layout — Screenshot + refine generated code to match frame UI\n// ============================================================================\n\n// server.addTool({\n// name: \"improve_layout\",\n// description: `Get a screenshot of the Figma frame and improve the already generated code to look more like the frame UI.\n\n// **What this does:**\n// - Returns the screenshot image of the selected Figma node\n// - Instructs you to refine the existing generated code so it visually matches the frame better (spacing, alignment, typography, colors, etc.)\n\n// **When to use:**\n// - After you have generated code from \\`analyze_design\\` or \\`analyze_frame_extraction\\`\n// - When the output doesn't quite match the Figma design and you want to improve it\n\n// **Output:**\n// - Screenshot image\n// - Instruction to improve the code to match the frame UI\n\n// **Usage:**\n// - Provide a nodeId (e.g., \"315-2920\") or leave empty for current Figma selection\n\n// **Example:**\n// \\`\\`\\`json\n// {\n// \"nodeId\": \"315-2920\"\n// }\n// \\`\\`\\``,\n// annotations: {\n// title: \"Improve Layout\",\n// readOnlyHint: true,\n// openWorldHint: false,\n// },\n// parameters: z.object({\n// nodeId: z\n// .string()\n// .optional()\n// .describe('Figma node ID (e.g., \"315-2920\"). Leave empty for current selection.'),\n// }),\n// execute: async (args, _context) => {\n// try {\n// logger.debug(`improve_layout called with nodeId: ${args.nodeId ?? \"current selection\"}`);\n// logger.debug(`figmaConnected flag: ${figmaConnected}`);\n\n// if (!figmaConnected) {\n// logger.warn(\"Early return: figmaConnected is false\");\n// return {\n// content: [{\n// type: \"text\" as const,\n// text: \"❌ Not connected to Figma MCP. Check logs for connection details.\",\n// }],\n// } as ContentResult;\n// }\n\n// logger.debug(\"Calling figmaClient.getScreenshot() for improve_layout...\");\n// const screenshot = await figmaClient.getScreenshot(args.nodeId);\n\n// if (!screenshot.content || screenshot.content.length === 0) {\n// return {\n// content: [{ type: \"text\" as const, text: \"❌ No screenshot returned\" }],\n// } as ContentResult;\n// }\n\n// const instruction: Content = {\n// type: \"text\" as const,\n// text: `**Improve Layout**\n\n// You **MUST** use the screenshot image above as the visual reference. Improve the already generated code so it looks more like the frame UI.\n\n// **What to refine:**\n// - Spacing, padding, and margins\n// - Alignment and layout\n// - Typography (font sizes, weights, line height)\n// - Colors and contrast\n// - Border radius, shadows, and other visual details\n// - Any mismatch between the code output and the Figma design\n\n// Output the improved code.`,\n// };\n\n// return {\n// content: [instruction, ...(screenshot.content as Content[])],\n// } as ContentResult;\n// } catch (error) {\n// logger.error(\"improve_layout failed:\", error instanceof Error ? error.message : String(error));\n// return {\n// content: [{\n// type: \"text\" as const,\n// text: `❌ improve_layout failed: ${error instanceof Error ? error.message : String(error)}`,\n// }],\n// } as ContentResult;\n// }\n// },\n// });\n\n\n\n// ============================================================================\n// Start Server\n// ============================================================================\n\nif (HTTP_STREAM) {\n server.start({\n httpStream: {\n port: PORT,\n },\n transportType: \"httpStream\",\n });\n\n logger.info(\"Figma Proxy MCP Server running on HTTP Stream!\");\n logger.info(`Endpoint: http://localhost:${PORT}/mcp`);\n logger.debug(`Pinecone Namespace: ${PINECONE_NAMESPACE}`);\n logger.debug(`\nTest with curl:\ncurl -X POST http://localhost:${PORT}/mcp \\\\\n -H \"Content-Type: application/json\" \\\\\n -d '{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"tools/list\",\"params\":{}}'\n`);\n} else {\n server.start({ transportType: \"stdio\" });\n logger.info(\"Started with stdio transport (for MCP clients)\");\n}\n","/**\n * Structured Logger Utility\n * Provides leveled logging with environment-based filtering\n * \n * IMPORTANT: In stdio mode, all logs must go to stderr to avoid interfering\n * with MCP's JSON-RPC protocol on stdout.\n */\n\nenum LogLevel {\n DEBUG = 0,\n INFO = 1,\n WARN = 2,\n ERROR = 3,\n SILENT = 4,\n}\n\n/**\n * Gets the current log level dynamically.\n * This ensures it picks up changes to process.env.NODE_ENV made after import\n * (solving ESM hoisting issues).\n */\nfunction getLogLevel(): LogLevel {\n const isVerbose = process.argv.includes(\"--verbose\") || process.env.DEBUG === \"true\";\n const isProduction = process.env.NODE_ENV === \"production\";\n\n if (isProduction && !isVerbose) {\n return LogLevel.SILENT; // Production: No logs at all\n }\n \n // Development or Verbose: Show everything\n return LogLevel.DEBUG; \n}\n\n// Detect if we're in stdio mode (MCP uses stdout for JSON-RPC)\n// HTTP_STREAM is set in process.env before this module loads\nconst isStdioMode = process.env.HTTP_STREAM !== \"true\" && process.env.HTTP_STREAM !== \"1\";\n\n// Helper to write to stderr in stdio mode, stdout otherwise\nconst writeToLog = (level: string, message: string, ...args: any[]) => {\n const fullMessage = args.length > 0 \n ? `[${level}] ${message} ${args.map(arg => typeof arg === 'object' ? JSON.stringify(arg) : String(arg)).join(' ')}`\n : `[${level}] ${message}`;\n \n if (isStdioMode) {\n process.stderr.write(`${fullMessage}\\n`);\n } else {\n console.log(fullMessage);\n }\n};\n\nexport const logger = {\n debug: (message: string, ...args: any[]) => {\n if (getLogLevel() <= LogLevel.DEBUG) {\n writeToLog(\"DEBUG\", message, ...args);\n }\n },\n info: (message: string, ...args: any[]) => {\n if (getLogLevel() <= LogLevel.INFO) {\n writeToLog(\"INFO\", message, ...args);\n }\n },\n warn: (message: string, ...args: any[]) => {\n if (getLogLevel() <= LogLevel.WARN) {\n writeToLog(\"WARN\", message, ...args);\n }\n },\n error: (message: string, ...args: any[]) => {\n if (getLogLevel() <= LogLevel.ERROR) {\n writeToLog(\"ERROR\", message, ...args);\n }\n },\n};\n\n","/**\n * Figma MCP Client Wrapper\n * Connects to official Figma Desktop MCP via SSE\n */\n\nimport { Client } from \"@modelcontextprotocol/sdk/client/index.js\";\nimport { SSEClientTransport } from \"@modelcontextprotocol/sdk/client/sse.js\";\nimport { logger } from \"../utils/logger.js\";\n\nexport interface FigmaDesignContextResult {\n content: Array<{\n type: string;\n text?: string;\n [key: string]: unknown;\n }>;\n}\n\nexport interface FigmaScreenshotResult {\n content: Array<{\n type: string;\n data?: string;\n mimeType?: string;\n [key: string]: unknown;\n }>;\n}\n\nexport interface FigmaMetadataResult {\n content: Array<{\n type: string;\n text?: string;\n [key: string]: unknown;\n }>;\n}\n\n/**\n * Client for communicating with official Figma Desktop MCP\n */\nexport class FigmaClient {\n private client: Client | null = null;\n private connected: boolean = false;\n private figmaUrl: string;\n\n constructor(figmaUrl: string = \"http://127.0.0.1:3845/sse\") {\n this.figmaUrl = figmaUrl;\n }\n\n /**\n * Connect to Figma MCP server\n */\n async connect(retries: number = 3): Promise<void> {\n if (this.connected && this.client) {\n logger.debug(\"Already connected, skipping connection attempt\");\n return;\n }\n\n logger.debug(\"Starting connection attempt\");\n logger.debug(`URL: ${this.figmaUrl}`);\n logger.debug(`Max retries: ${retries}`);\n logger.debug(`Current status: connected=${this.connected}, client=${!!this.client}`);\n\n for (let attempt = 0; attempt < retries; attempt++) {\n const attemptStartTime = Date.now();\n logger.debug(`Attempt ${attempt + 1}/${retries} starting...`);\n\n try {\n logger.debug(\"Creating MCP Client object...\");\n this.client = new Client(\n {\n name: \"figma-proxy-client\",\n version: \"1.0.0\",\n },\n {\n capabilities: {\n tools: {},\n },\n },\n );\n logger.debug(\"Client object created\");\n\n logger.debug(`Creating SSE Transport for: ${this.figmaUrl}`);\n const transport = new SSEClientTransport(new URL(this.figmaUrl));\n logger.debug(\"Transport object created\");\n\n logger.debug(\"Attempting to connect...\");\n const connectStartTime = Date.now();\n await this.client.connect(transport);\n const connectTime = Date.now() - connectStartTime;\n logger.debug(`Connection established in ${connectTime}ms`);\n\n this.connected = true;\n const totalTime = Date.now() - attemptStartTime;\n\n logger.debug(`Connected to Figma MCP (${totalTime}ms)`);\n return;\n } catch (error) {\n const attemptTime = Date.now() - attemptStartTime;\n logger.debug(`Connection attempt ${attempt + 1}/${retries} FAILED (${attemptTime}ms)`);\n logger.debug(`Error type: ${error?.constructor?.name || typeof error}`);\n logger.debug(`Error message: ${error instanceof Error ? error.message : String(error)}`);\n\n // Log additional error properties if available\n if (error && typeof error === 'object') {\n const errorObj = error as Record<string, unknown>;\n if ('code' in errorObj) {\n logger.debug(`Error code: ${errorObj.code}`);\n }\n if ('cause' in errorObj) {\n logger.debug(\"Error cause:\", errorObj.cause);\n }\n if ('status' in errorObj) {\n logger.debug(`HTTP status: ${errorObj.status}`);\n }\n if ('statusText' in errorObj) {\n logger.debug(`HTTP status text: ${errorObj.statusText}`);\n }\n }\n\n if (error instanceof Error && error.stack) {\n logger.debug(\"Error stack:\", error.stack);\n }\n\n if (attempt === retries - 1) {\n logger.error(`All connection attempts failed (${retries} attempts)`);\n logger.error(`URL: ${this.figmaUrl}`);\n throw new Error(\n `Failed to connect to Figma MCP at ${this.figmaUrl} after ${retries} attempts. Make sure Figma Desktop is running with MCP enabled.`,\n );\n }\n\n const waitTime = 1000 * (attempt + 1);\n logger.debug(`Waiting ${waitTime}ms before retry...`);\n // Wait before retry (exponential backoff)\n await new Promise((resolve) =>\n setTimeout(resolve, waitTime),\n );\n logger.debug(\"Wait complete, retrying...\");\n }\n }\n }\n\n /**\n * Ensure connection is established\n */\n private async ensureConnected(): Promise<void> {\n if (!this.connected || !this.client) {\n logger.debug(\"ensureConnected() called - not connected, attempting connection...\");\n await this.connect();\n } else {\n logger.debug(\"ensureConnected() called - already connected, skipping\");\n }\n }\n\n /**\n * Normalize nodeId format: convert \"XXXX-XXXX\" to \"XXXX:XXXX\" for Figma MCP compatibility\n */\n private normalizeNodeId(nodeId?: string): string | undefined {\n if (!nodeId) return undefined;\n // Convert dash format to colon format (e.g., \"315-2920\" -> \"315:2920\")\n return nodeId.replace(/-/g, \":\");\n }\n\n /**\n * Call Figma's get_design_context tool\n */\n async getDesignContext(\n ): Promise<FigmaDesignContextResult> {\n await this.ensureConnected();\n\n\n const args = {\n // nodeId: undefined to use frame current selection,\n clientLanguages: \"typescript\",\n clientFrameworks: \"react\",\n forceCode: true,\n };\n\n logger.debug(\"Calling get_design_context with args:\", args);\n\n try {\n const result = await this.client!.callTool({\n name: \"get_design_context\",\n arguments: args,\n });\n\n // Filter content to only return items at index 0 (code) , 1 (rules to use and ignore) and 3 (design tokens)\n // Note: Figma returns 4 items total, but we only need these three for our workflow\n const parsedResult = result as FigmaDesignContextResult;\n if (parsedResult.content && Array.isArray(parsedResult.content)) {\n const filteredContent = [\n parsedResult.content[0], // Item 0: Generated React code\n parsedResult.content[1], // Item 1: Rules to Use and Ignore\n parsedResult.content[3], // Item 3: Design tokens/styles\n ].filter((item) => item !== undefined); // Remove undefined if index doesn't exist\n\n return {\n content: filteredContent,\n };\n }\n\n return parsedResult;\n } catch (error) {\n // Try reconnecting once on error\n logger.warn(\"Error calling get_design_context, attempting reconnect...\");\n this.connected = false;\n await this.connect();\n\n const result = await this.client!.callTool({\n name: \"get_design_context\",\n arguments: args\n });\n\n return result as FigmaDesignContextResult;\n }\n }\n\n /**\n * Call Figma's get_metadata tool to get actual node structure\n */\n async getMetadata(\n ): Promise<FigmaMetadataResult> {\n await this.ensureConnected();\n\n const args = {\n // nodeId: undefined to use frame current selection,\n clientLanguages: \"typescript\",\n clientFrameworks: \"react\",\n forceCode: true,\n };\n\n logger.debug(\"Calling get_metadata with args:\", args);\n\n try {\n const result = await this.client!.callTool({\n name: \"get_metadata\",\n arguments: args,\n });\n\n // Filter content to only return items at index 0 (raw metadata) \n // Note: Figma returns 4 items total, but we only need these three for our workflow\n const parsedResult = result as FigmaDesignContextResult;\n if (parsedResult.content && Array.isArray(parsedResult.content)) {\n const filteredContent = [\n parsedResult.content[0], // Item 0: Metadata Raw\n ].filter((item) => item !== undefined); // Remove undefined if index doesn't exist\n\n return {\n content: filteredContent,\n };\n }\n\n return parsedResult;\n } catch (error) {\n // Try reconnecting once on error\n logger.warn(\"Error calling get_metadata, attempting reconnect...\");\n this.connected = false;\n await this.connect();\n\n const result = await this.client!.callTool({\n name: \"get_metadata\",\n arguments: args,\n });\n\n return result as FigmaMetadataResult;\n }\n }\n\n /**\n * Call Figma's get_screenshot tool\n * Note: clientLanguages and clientFrameworks are not needed for screenshots\n * (only required for get_design_context which generates code)\n */\n async getScreenshot(\n ): Promise<FigmaScreenshotResult> {\n await this.ensureConnected();\n\n // Normalize nodeId format for Figma MCP compatibility\n\n try {\n const result = await this.client!.callTool({\n name: \"get_screenshot\",\n arguments: {\n // nodeId: undefined to use frame current selection,\n },\n });\n\n return result as FigmaScreenshotResult;\n } catch (error) {\n // Try reconnecting once on error\n logger.warn(\"Error calling get_screenshot, attempting reconnect...\");\n this.connected = false;\n await this.connect();\n\n const result = await this.client!.callTool({\n name: \"get_screenshot\",\n arguments: {\n // nodeId: undefined,\n },\n });\n\n return result as FigmaScreenshotResult;\n }\n }\n\n /**\n * Close connection\n */\n async disconnect(): Promise<void> {\n if (this.client) {\n await this.client.close();\n this.connected = false;\n this.client = null;\n logger.debug(\"Disconnected from Figma MCP\");\n }\n }\n}\n\n","/**\n * Metadata Extractor (Simpler)\n *\n * Extracts ALL `name=\"...\"` / `name='...'` attribute values from the Figma\n * metadata XML-like text and returns them as a list.\n *\n * This is intentionally minimal (no heuristics, no categorization).\n */\nexport class MetadataExtractorSimpler {\n /**\n * Returns every `name=` attribute value in appearance order.\n * Automatically removes exact duplicates (case-sensitive) while preserving first-seen order.\n *\n * Example match:\n * `<frame id=\"28:2524\" name=\"Referral/New 1.1\" ...>`\n * ^^^^^^^^^^^^^^^\n */\n extractNames(metadataText: string): string[] {\n if (!metadataText) return [];\n\n const names: string[] = [];\n const seen = new Set<string>();\n const matches = metadataText.matchAll(/\\bname\\s*=\\s*([\"'])(.*?)\\1/gi);\n\n for (const match of matches) {\n const raw = match[2];\n const name = typeof raw === \"string\" ? raw.trim() : \"\";\n \n // Only add if not empty and not already seen (exact duplicate check)\n if (name && !seen.has(name)) {\n seen.add(name);\n names.push(name);\n }\n }\n\n return names;\n }\n}\n\n","/**\n * Design Context Extractor\n * Extracts component information from Figma design context (code + tokens)\n */\n\nimport type { ComponentDescriptor } from \"./types.js\";\n\nexport class DesignContextExtractor {\n /**\n * Extract semantic information from JSX/HTML code and design tokens\n */\n extractFromCodeAndTokens(code: string, tokens: string, descriptor: ComponentDescriptor): void {\n // Extract from code section\n this.extractFromCode(code, descriptor);\n\n // Extract from design tokens\n this.extractFromTokens(tokens, descriptor);\n }\n\n /**\n * Extract semantic information from JSX/HTML code\n */\n private extractFromCode(code: string, descriptor: ComponentDescriptor): void {\n // Extract all data-name attributes to understand component structure\n const dataNameMatches = code.matchAll(/data-name=[\"']([^\"']+)[\"']/gi);\n const dataNames: string[] = [];\n \n for (const match of dataNameMatches) {\n const name = match[1].trim();\n if (name && name.length > 0) {\n dataNames.push(name.toLowerCase());\n }\n }\n\n // Track primary component (usually the first/root data-name)\n const primaryDataName = dataNames[0] || \"\";\n\n // 1. EXTRACT HIERARCHY from data-name structure\n this.extractHierarchy(dataNames, descriptor);\n\n // 2. IDENTIFY ALL COMPONENT TYPES from data-names and elements\n this.identifyComponents(code, dataNames, descriptor);\n\n // 3. DETERMINE PURPOSE from primary component and text content\n this.determinePurpose(code, primaryDataName, descriptor);\n\n // 4. EXTRACT VISUAL CHARACTERISTICS\n this.extractVisualTraits(code, dataNames, descriptor);\n\n // 5. EXTRACT LAYOUT PATTERNS\n this.extractLayoutPatterns(code, descriptor);\n\n // 6. DETECT INTERACTIONS\n this.detectInteractions(code, descriptor);\n\n // 7. EXTRACT REACT PROPS AND STATE\n this.extractReactPropsAndState(code, descriptor);\n\n // 8. EXTRACT SIZE AND SPACING PATTERNS\n this.extractSizeAndSpacing(code, descriptor);\n\n // 9. EXTRACT BORDER AND STYLING PATTERNS\n this.extractBorderAndStyling(code, descriptor);\n\n // 10. EXTRACT ADDITIONAL KEYWORDS\n this.extractKeywords(code, dataNames, descriptor);\n }\n\n /**\n * Extract hierarchy structure from data-name attributes\n * Identifies structural parts like Header, Body, Footer, Container, etc.\n */\n private extractHierarchy(dataNames: string[], descriptor: ComponentDescriptor): void {\n const hierarchyKeywords = [\n 'header', 'footer', 'body', 'container', 'content', 'wrapper',\n 'main', 'sidebar', 'nav', 'navigation', 'section', 'panel',\n 'card', 'tile', 'box', 'frame', 'group', 'stack', 'row', 'column',\n 'top'\n ];\n\n for (const name of dataNames) {\n const lowerName = name.toLowerCase();\n \n // Check if this data-name represents a structural part\n for (const keyword of hierarchyKeywords) {\n if (lowerName.includes(keyword)) {\n // Normalize to common terms\n if (keyword === 'nav' || keyword === 'navigation') {\n if (!descriptor.hierarchy.includes('navigation')) {\n descriptor.hierarchy.push('navigation');\n }\n } else if (keyword === 'content' || keyword === 'wrapper' || keyword === 'container') {\n if (!descriptor.hierarchy.includes('container')) {\n descriptor.hierarchy.push('container');\n }\n } else if (keyword === 'section' || keyword === 'panel') {\n if (!descriptor.hierarchy.includes('section')) {\n descriptor.hierarchy.push('section');\n }\n } else if (!descriptor.hierarchy.includes(keyword)) {\n descriptor.hierarchy.push(keyword);\n }\n break;\n }\n }\n }\n }\n\n /**\n * Identify all component types in the design\n */\n private identifyComponents(code: string, dataNames: string[], descriptor: ComponentDescriptor): void {\n const allText = code.toLowerCase() + \" \" + dataNames.join(\" \");\n\n // Extract React component/function names (e.g., \"function SearchInput\", \"const Button =\")\n const functionMatches = code.matchAll(/(?:function|const|export\\s+(?:default\\s+)?function)\\s+([A-Z][a-zA-Z0-9]*)/g);\n const componentNames: string[] = [];\n for (const match of functionMatches) {\n if (match[1]) componentNames.push(match[1].toLowerCase());\n }\n const componentNamesText = componentNames.join(\" \");\n\n // Combine all text for analysis\n const combinedText = allText + \" \" + componentNamesText;\n\n // Modal/Dialog/Overlay\n if (/modal|dialog|popup|overlay|sheet|drawer/i.test(combinedText)) {\n descriptor.components.add(\"modal\");\n }\n\n // Buttons - check component names, HTML tags, and data-names\n if (/<button/i.test(code) || /button|btn/i.test(combinedText)) {\n // Check for icon button first (more specific)\n if (/icon.*button|button.*icon|<button[^>]*>.*<img|<button[^>]*>.*<svg|<button[^>]*>.*icon/i.test(code) ||\n /showicon|iconbutton/i.test(combinedText)) {\n descriptor.components.add(\"icon button\");\n } else {\n descriptor.components.add(\"button\");\n }\n }\n\n // Form Inputs - check component names (e.g., SearchInput, TextInput), HTML tags, and data-names\n if (/<input/i.test(code) || /input|textfield|text.?field|searchinput|textinput/i.test(combinedText)) {\n descriptor.components.add(\"input\");\n // Check if it's a search input\n if (/search/i.test(combinedText) || /data-name.*search/i.test(code)) {\n descriptor.keywords.push(\"search\");\n descriptor.purpose = \"search interface\";\n }\n }\n if (/<textarea/i.test(code) || /textarea|text.?area/i.test(allText)) {\n descriptor.components.add(\"textarea\");\n }\n if (/<select/i.test(code) || /dropdown|select|picker|combobox/i.test(allText)) {\n descriptor.components.add(\"dropdown\");\n }\n if (/type=[\"']checkbox/i.test(code) || /checkbox|check.?box/i.test(allText)) {\n descriptor.components.add(\"checkbox\");\n }\n if (/type=[\"']radio/i.test(code) || /radio|radio.?button/i.test(allText)) {\n descriptor.components.add(\"radio\");\n }\n if (/switch|toggle/i.test(allText)) {\n descriptor.components.add(\"switch\");\n }\n if (/slider|range/i.test(allText)) {\n descriptor.components.add(\"slider\");\n }\n\n // Navigation - only detect if actual navbar/navigation element exists\n if (/<nav|<Navbar|navbar|nav.?bar|navigation.?bar|app.?bar/i.test(code)) {\n descriptor.components.add(\"navbar\");\n }\n if (/sidebar|side.?bar|side.?nav|drawer/i.test(allText)) {\n descriptor.components.add(\"sidebar\");\n }\n if (/breadcrumb|breadcrumbs|bread.?crumb/i.test(allText)) {\n descriptor.components.add(\"breadcrumb\");\n }\n if (/tab|tabs|tab.?bar|tab.?navigation/i.test(allText)) {\n descriptor.components.add(\"tabs\");\n }\n if (/menu|dropdown.?menu|context.?menu/i.test(allText)) {\n descriptor.components.add(\"menu\");\n }\n if (/pagination|pager|page.?navigation/i.test(allText)) {\n descriptor.components.add(\"pagination\");\n }\n\n // Data Display\n if (/<table|<tr|<td|<th/i.test(code) || /table|data.?table|grid.?table/i.test(allText)) {\n descriptor.components.add(\"table\");\n }\n if (/card|panel|tile/i.test(allText)) {\n descriptor.components.add(\"card\");\n }\n if (/list|list.?item/i.test(allText)) {\n descriptor.components.add(\"list\");\n }\n if (/grid|grid.?layout/i.test(allText)) {\n descriptor.components.add(\"grid\");\n }\n if (/calendar|date.?picker|date.?calendar/i.test(allText)) {\n descriptor.components.add(\"calendar\");\n }\n if (/chart|graph|visualization/i.test(allText)) {\n descriptor.components.add(\"chart\");\n }\n\n // Feedback\n if (/alert|notification|banner|message/i.test(allText)) {\n descriptor.components.add(\"alert\");\n }\n if (/badge|label|tag|chip/i.test(allText)) {\n descriptor.components.add(\"badge\");\n }\n if (/tooltip|popover|tip/i.test(allText)) {\n descriptor.components.add(\"tooltip\");\n }\n if (/progress|loader|spinner|loading/i.test(allText)) {\n descriptor.components.add(\"progress\");\n }\n if (/toast|snackbar/i.test(allText)) {\n descriptor.components.add(\"toast\");\n }\n\n // Layout - only detect if actual header/footer elements exist (not just data-name labels)\n if (/<header|<Header/i.test(code) || \n (/page.?header|site.?header|main.?header/i.test(allText) && !/data-name.*header/i.test(code))) {\n descriptor.components.add(\"header\");\n }\n if (/<footer|<Footer/i.test(code) || \n (/page.?footer|site.?footer|main.?footer/i.test(allText) && !/data-name.*footer/i.test(code))) {\n descriptor.components.add(\"footer\");\n }\n\n // Specialized\n if (/avatar|profile.?picture|user.?image/i.test(allText)) {\n descriptor.components.add(\"avatar\");\n }\n if (/stepper|steps|wizard/i.test(allText)) {\n descriptor.components.add(\"stepper\");\n }\n if (/accordion|collapsible|expandable/i.test(allText)) {\n descriptor.components.add(\"accordion\");\n }\n if (/carousel|slider|slideshow/i.test(allText)) {\n descriptor.components.add(\"carousel\");\n }\n if (/segmented.?control|segment/i.test(allText)) {\n descriptor.components.add(\"segmented control\");\n }\n }\n\n /**\n * Determine overall purpose of the design\n */\n private determinePurpose(code: string, primaryName: string, descriptor: ComponentDescriptor): void {\n const combinedText = (code + \" \" + primaryName).toLowerCase();\n\n // Action purposes\n if (/delete|remove|borrar/i.test(combinedText)) {\n descriptor.purpose = \"delete confirmation\";\n } else if (/edit|modify|change|update/i.test(combinedText)) {\n descriptor.purpose = \"edit form\";\n } else if (/create|new|add/i.test(combinedText)) {\n descriptor.purpose = \"create form\";\n } else if (/save|submit|apply/i.test(combinedText)) {\n descriptor.purpose = \"submit form\";\n } else if (/search|find|query/i.test(combinedText)) {\n descriptor.purpose = \"search interface\";\n } else if (/filter|sort|organize/i.test(combinedText)) {\n descriptor.purpose = \"data filtering\";\n } else if (/login|signin|sign.in|authenticate/i.test(combinedText)) {\n descriptor.purpose = \"authentication\";\n } else if (/register|signup|sign.up/i.test(combinedText)) {\n descriptor.purpose = \"registration\";\n } else if (/dashboard|overview|summary/i.test(combinedText)) {\n descriptor.purpose = \"dashboard\";\n } else if (/warning|alert|caution/i.test(combinedText)) {\n descriptor.purpose = \"warning\";\n } else if (/error|fail|problem/i.test(combinedText)) {\n descriptor.purpose = \"error\";\n } else if (/success|complete|done/i.test(combinedText)) {\n descriptor.purpose = \"success\";\n }\n }\n\n /**\n * Extract visual characteristics\n */\n private extractVisualTraits(code: string, dataNames: string[], descriptor: ComponentDescriptor): void {\n const allText = code.toLowerCase() + \" \" + dataNames.join(\" \");\n\n // Check data-names specifically for icon types (e.g., \"Info icon\", \"Search icon\")\n for (const dataName of dataNames) {\n const lowerDataName = dataName.toLowerCase();\n if (/icon/i.test(lowerDataName)) {\n if (/info|information/i.test(lowerDataName)) {\n descriptor.visual.push(\"info icon\");\n descriptor.keywords.push(\"info icon\");\n } else if (/search|magnify/i.test(lowerDataName)) {\n descriptor.visual.push(\"search icon\");\n descriptor.keywords.push(\"search icon\");\n } else if (/warning|alert|caution/i.test(lowerDataName)) {\n descriptor.visual.push(\"warning icon\");\n } else if (/success|check|confirm/i.test(lowerDataName)) {\n descriptor.visual.push(\"success icon\");\n } else if (/error|danger/i.test(lowerDataName)) {\n descriptor.visual.push(\"error icon\");\n } else if (/close|exit|dismiss/i.test(lowerDataName)) {\n descriptor.visual.push(\"close icon\");\n }\n }\n }\n\n // Icons from general patterns\n if (/icon|svg/i.test(allText)) {\n if (/warning|alert|caution/i.test(allText)) {\n descriptor.visual.push(\"warning icon\");\n }\n if (/close|exit|dismiss|×|cancel/i.test(allText)) {\n descriptor.visual.push(\"close icon\");\n }\n if (/success|check|confirm|✓/i.test(allText)) {\n descriptor.visual.push(\"success icon\");\n }\n if (/error|danger|problem|×/i.test(allText)) {\n descriptor.visual.push(\"error icon\");\n }\n if (/info|information|help|\\?/i.test(allText)) {\n descriptor.visual.push(\"info icon\");\n }\n if (/search|magnify|🔍/i.test(allText)) {\n descriptor.visual.push(\"search icon\");\n }\n }\n\n // Images\n if (/<img|<image/i.test(code) || /image|picture|photo|imgDash|imgAvatar/i.test(allText)) {\n descriptor.visual.push(\"image\");\n }\n\n // Check for field/container patterns (indicates form input structure)\n if (/field.*container|input.*container|search.*text/i.test(allText)) {\n descriptor.keywords.push(\"input field\");\n }\n }\n\n /**\n * Extract layout patterns from styling\n */\n private extractLayoutPatterns(code: string, descriptor: ComponentDescriptor): void {\n // Flex layouts\n if (/flex-col|flex.col/i.test(code) && /items-center|justify-center/i.test(code)) {\n descriptor.layout.push(\"centered vertical\");\n } else if (/flex-row/i.test(code) && /items-center|justify-center/i.test(code)) {\n descriptor.layout.push(\"centered horizontal\");\n } else if (/flex/i.test(code)) {\n descriptor.layout.push(\"flex layout\");\n }\n\n // Grid layouts\n if (/grid-cols|grid.cols/i.test(code)) {\n descriptor.layout.push(\"grid layout\");\n }\n\n // Visual effects\n if (/rounded-\\[?[0-9]/i.test(code) || /rounded-(?:sm|md|lg|xl|full)/i.test(code)) {\n descriptor.layout.push(\"rounded\");\n }\n \n if (/shadow-\\[/i.test(code) || /shadow-(?:sm|md|lg|xl|2xl)/i.test(code)) {\n descriptor.layout.push(\"elevated\");\n }\n\n // Responsive indicators\n if (/responsive|mobile|desktop|tablet/i.test(code)) {\n descriptor.layout.push(\"responsive\");\n }\n }\n\n /**\n * Detect interaction patterns\n */\n private detectInteractions(code: string, descriptor: ComponentDescriptor): void {\n const lowerCode = code.toLowerCase();\n\n // Dialog interactions\n if (descriptor.components.has(\"modal\")) {\n if (/confirm|yes|no|ok|cancel/i.test(code)) {\n descriptor.interactions.add(\"confirmation\");\n }\n if (/dismiss|close|exit/i.test(code)) {\n descriptor.interactions.add(\"dismissible\");\n }\n }\n\n // Form interactions\n if (descriptor.components.has(\"input\") || descriptor.components.has(\"button\")) {\n if (/submit|save|send|apply/i.test(lowerCode)) {\n descriptor.interactions.add(\"form submission\");\n }\n if (/validate|validation|error|required/i.test(lowerCode)) {\n descriptor.interactions.add(\"validation\");\n }\n }\n\n // Navigation interactions\n if (descriptor.components.has(\"tabs\") || descriptor.components.has(\"menu\")) {\n descriptor.interactions.add(\"navigation\");\n }\n\n // Data interactions\n if (descriptor.components.has(\"table\") || descriptor.components.has(\"list\")) {\n if (/sort|filter|search/i.test(lowerCode)) {\n descriptor.interactions.add(\"data manipulation\");\n }\n if (/select|checkbox|radio/i.test(lowerCode)) {\n descriptor.interactions.add(\"selection\");\n }\n }\n }\n\n /**\n * Extract React props and TypeScript state types\n */\n private extractReactPropsAndState(code: string, descriptor: ComponentDescriptor): void {\n // Extract TypeScript interface/type definitions\n const interfaceMatches = code.matchAll(/(?:interface|type)\\s+(\\w+Props)\\s*\\{/gi);\n for (const match of interfaceMatches) {\n const interfaceName = match[1].toLowerCase();\n if (/input|search|field/i.test(interfaceName)) {\n descriptor.components.add(\"input\");\n }\n if (/button/i.test(interfaceName)) {\n descriptor.components.add(\"button\");\n }\n if (/modal|dialog/i.test(interfaceName)) {\n descriptor.components.add(\"modal\");\n }\n }\n\n // Extract props that indicate features\n if (/showLabel|showlabel/i.test(code)) {\n descriptor.keywords.push(\"label\");\n }\n if (/showInfoIcon|showinfoicon|showInfo|showinfo/i.test(code)) {\n descriptor.keywords.push(\"info icon\");\n descriptor.visual.push(\"info icon\");\n }\n if (/showHelper|showhelper|helperText|helpertext/i.test(code)) {\n descriptor.keywords.push(\"helper\");\n descriptor.keywords.push(\"helper text\");\n }\n if (/showIcon|showicon/i.test(code)) {\n descriptor.keywords.push(\"icon\");\n }\n if (/showSearch|showsearch/i.test(code)) {\n descriptor.keywords.push(\"search\");\n descriptor.keywords.push(\"search icon\");\n }\n if (/filledText|filledtext/i.test(code)) {\n descriptor.keywords.push(\"filled\");\n descriptor.keywords.push(\"filled text\");\n }\n if (/placeholder/i.test(code)) {\n descriptor.keywords.push(\"placeholder\");\n }\n if (/className/i.test(code)) {\n descriptor.keywords.push(\"customizable\");\n }\n\n // Extract state types from TypeScript (e.g., state?: \"enabled\" | \"hover\" | \"error\")\n const stateMatches = code.matchAll(/state[?:].*[\"']([^\"']+)[\"']/gi);\n const states: string[] = [];\n for (const match of stateMatches) {\n if (match[1]) states.push(match[1].toLowerCase());\n }\n \n // Also extract from union types: \"enabled\" | \"hover\" | \"pressed\" | \"error\"\n const unionStateMatches = code.matchAll(/[\"'](enabled|hover|pressed|active-focus|read-only|error|success|disabled|loading|empty|filled)[\"']/gi);\n for (const match of unionStateMatches) {\n if (match[1]) states.push(match[1].toLowerCase());\n }\n\n // Process states\n for (const state of states) {\n if (state === \"error\") {\n descriptor.colors.push(\"error\");\n descriptor.visual.push(\"error state\");\n } else if (state === \"success\") {\n descriptor.colors.push(\"success\");\n descriptor.visual.push(\"success state\");\n } else if (state === \"disabled\") {\n descriptor.keywords.push(\"disabled\");\n } else if (state === \"loading\") {\n descriptor.components.add(\"progress\");\n } else if (state === \"hover\") {\n descriptor.keywords.push(\"hover\");\n descriptor.interactions.add(\"hover\");\n } else if (state === \"pressed\") {\n descriptor.keywords.push(\"pressed\");\n descriptor.interactions.add(\"press\");\n } else if (state === \"active-focus\") {\n descriptor.keywords.push(\"focus\");\n descriptor.keywords.push(\"active\");\n descriptor.interactions.add(\"focus\");\n } else if (state === \"read-only\") {\n descriptor.keywords.push(\"read only\");\n }\n }\n\n // Extract content types (e.g., content?: \"placeholder\" | \"filled text\")\n const contentMatches = code.matchAll(/content[?:].*[\"']([^\"']+)[\"']/gi);\n for (const match of contentMatches) {\n if (match[1]) {\n const content = match[1].toLowerCase();\n if (content.includes(\"placeholder\")) {\n descriptor.keywords.push(\"placeholder\");\n }\n if (content.includes(\"filled\")) {\n descriptor.keywords.push(\"filled\");\n descriptor.keywords.push(\"filled text\");\n }\n if (content.includes(\"empty\")) {\n descriptor.keywords.push(\"empty\");\n }\n }\n }\n \n if (/placeholder/i.test(code)) {\n descriptor.keywords.push(\"placeholder\");\n }\n if (/filled.*text|filledtext/i.test(code)) {\n descriptor.keywords.push(\"filled\");\n }\n\n // Extract from data-name patterns that indicate search\n if (/data-name.*search|search.*text|search.*input/i.test(code)) {\n descriptor.keywords.push(\"search\");\n descriptor.purpose = \"search interface\";\n }\n }\n\n /**\n * Extract size and spacing patterns from className and styles\n */\n private extractSizeAndSpacing(code: string, descriptor: ComponentDescriptor): void {\n // Size patterns (e.g., size-[24px], h-[48px], w-[1440px])\n if (/size-\\[(\\d+)|h-\\[(\\d+)|w-\\[(\\d+)|height:\\s*(\\d+)|width:\\s*(\\d+)/i.test(code)) {\n const sizeMatches = code.matchAll(/(?:size|h|w|height|width)[-:]?\\s*\\[?(\\d+)/gi);\n for (const match of sizeMatches) {\n const size = parseInt(match[1], 10);\n if (size >= 64) {\n descriptor.keywords.push(\"large\");\n } else if (size >= 48) {\n descriptor.keywords.push(\"medium\");\n } else if (size >= 24) {\n descriptor.keywords.push(\"small\");\n }\n // Icon sizes\n if (size === 24 || size === 48 || size === 64) {\n descriptor.keywords.push(`${size}px icon`);\n }\n }\n }\n\n // Gap/spacing patterns (e.g., gap-[4px], gap-[12px], gap-[16px])\n if (/gap-\\[(\\d+)|gap:\\s*(\\d+)/i.test(code)) {\n const gapMatches = code.matchAll(/gap[-:]?\\s*\\[?(\\d+)/gi);\n for (const match of gapMatches) {\n const gap = parseInt(match[1], 10);\n if (gap >= 16) {\n descriptor.keywords.push(\"spaced\");\n descriptor.layout.push(\"spaced layout\");\n } else if (gap >= 8) {\n descriptor.keywords.push(\"compact\");\n }\n }\n }\n\n // Padding patterns (e.g., p-[12px])\n if (/p-\\[(\\d+)|padding:\\s*(\\d+)/i.test(code)) {\n descriptor.keywords.push(\"padded\");\n }\n\n // Max/min height/width patterns\n if (/max-h-\\[(\\d+)|min-h-\\[(\\d+)|max-w-\\[(\\d+)|min-w-\\[(\\d+)/i.test(code)) {\n descriptor.keywords.push(\"constrained\");\n }\n }\n\n /**\n * Extract border and styling patterns\n */\n private extractBorderAndStyling(code: string, descriptor: ComponentDescriptor): void {\n // Border patterns\n if (/border\\s+border-\\[|border:\\s*1px|border-solid/i.test(code)) {\n descriptor.keywords.push(\"bordered\");\n // Check border color\n if (/border-\\[var\\(--color\\/border/i.test(code)) {\n descriptor.keywords.push(\"default border\");\n }\n if (/border-\\[var\\(--color\\/border\\/default/i.test(code)) {\n descriptor.keywords.push(\"border\");\n }\n }\n\n // Rounded corners (e.g., rounded-[8px], rounded-lg)\n if (/rounded-\\[(\\d+)|rounded-(?:sm|md|lg|xl|full)/i.test(code)) {\n const roundedMatches = code.matchAll(/rounded-\\[(\\d+)|rounded-(sm|md|lg|xl|full)/gi);\n for (const match of roundedMatches) {\n const value = match[1] || match[2];\n if (value === \"full\" || value === \"xl\") {\n descriptor.keywords.push(\"fully rounded\");\n } else {\n descriptor.keywords.push(\"rounded\");\n }\n }\n }\n\n // Background patterns\n if (/bg-\\[var\\(--color\\/surface|background:\\s*var\\(--color/i.test(code)) {\n descriptor.keywords.push(\"background\");\n if (/surface\\/flat|surface.*flat/i.test(code)) {\n descriptor.keywords.push(\"flat surface\");\n }\n if (/surface\\/floating|surface.*floating/i.test(code)) {\n descriptor.keywords.push(\"floating surface\");\n }\n }\n\n // Shadow patterns (already in layout, but add keywords)\n if (/shadow-\\[0px_0px_0px_0px/i.test(code)) {\n descriptor.keywords.push(\"no shadow\");\n } else if (/shadow-\\[|drop-shadow/i.test(code)) {\n descriptor.keywords.push(\"shadow\");\n }\n\n // Overflow patterns\n if (/overflow-clip|overflow-hidden/i.test(code)) {\n descriptor.keywords.push(\"clipped\");\n }\n\n // Flex patterns (more detailed)\n if (/flex\\s+flex-\\[1_0_0\\]|flex-1/i.test(code)) {\n descriptor.keywords.push(\"flexible\");\n descriptor.layout.push(\"flexible layout\");\n }\n\n // Content stretch pattern\n if (/content-stretch/i.test(code)) {\n descriptor.keywords.push(\"stretched\");\n descriptor.layout.push(\"stretched layout\");\n }\n }\n\n /**\n * Extract additional keywords from code and data-names for Pinecone search\n */\n private extractKeywords(code: string, dataNames: string[], descriptor: ComponentDescriptor): void {\n const allText = (code + \" \" + dataNames.join(\" \")).toLowerCase();\n\n // Dialog/modal keywords\n if (/modal|dialog|popup|overlay/i.test(allText)) {\n descriptor.keywords.push(\"dialog\");\n descriptor.keywords.push(\"overlay\");\n }\n\n // Destructive / irreversible action\n if (/delete|remove|borrar|irreversible|undo|destructive/i.test(allText)) {\n descriptor.keywords.push(\"destructive\");\n if (/irreversible|undo|no way to undo/i.test(allText)) {\n descriptor.keywords.push(\"irreversible\");\n }\n }\n\n // Button / action labels (common CTA words)\n if (/cancel|dismiss|close/i.test(allText)) {\n descriptor.keywords.push(\"cancel\");\n descriptor.keywords.push(\"dismissible\");\n }\n if (/\\bdelete\\b|remove|borrar/i.test(allText)) descriptor.keywords.push(\"delete\");\n if (/confirm|ok|submit|save|apply/i.test(allText)) descriptor.keywords.push(\"confirm\");\n\n // Support / hero icon (large centered icon)\n if (/support\\s*icon|hero|lead\\s*icon|centered\\s*icon|large\\s*icon/i.test(allText)) {\n descriptor.keywords.push(\"support icon\");\n descriptor.keywords.push(\"centered icon\");\n }\n\n // Structure keywords\n if (/header|body|footer|container/i.test(allText)) {\n if (/header.*body|body.*header/i.test(allText)) descriptor.keywords.push(\"header body\");\n }\n\n // Navigation / navbar keywords (e.g. NAV/Header, NAV/Top, Header/MenuPral)\n if (/data-name=[\"'][^\"']*\\bnav\\b|data-name=[\"'][^\"']*\\/nav\\b/i.test(allText) ||\n /\\bnav\\/|nav\\s*\\/|\\/nav\\b/i.test(allText)) {\n descriptor.keywords.push(\"navbar\");\n descriptor.keywords.push(\"navigation\");\n descriptor.keywords.push(\"top nav\");\n }\n if (/data-name=[\"'][^\"']*\\bmenu\\b|data-name=[\"'][^\"']*menu\\w*/i.test(allText)) {\n descriptor.keywords.push(\"menu\");\n }\n if (/data-name=[\"'][^\"']*\\btop\\b/i.test(allText) && /nav|header/i.test(allText)) {\n descriptor.keywords.push(\"top nav\");\n descriptor.keywords.push(\"header nav\");\n }\n // Nav links: multiple <p> inside nav-like structure\n const pCount = (code.match(/<p\\b|<\\/p>/gi) || []).length;\n if (pCount >= 3 && /nav|NAV|header|menu/i.test(allText)) {\n descriptor.keywords.push(\"nav links\");\n descriptor.keywords.push(\"navigation links\");\n }\n\n // Text / label / heading elements (<p>, <h1>-<h6>, <label>, <span>, etc.)\n if (/<p\\b|<\\/p>/i.test(code)) {\n descriptor.keywords.push(\"paragraph\");\n descriptor.keywords.push(\"text\");\n }\n if (/<h[1-6]\\b|<\\/h[1-6]>/i.test(code)) {\n descriptor.keywords.push(\"heading\");\n descriptor.keywords.push(\"title\");\n }\n if (/<label\\b|<\\/label>/i.test(code)) descriptor.keywords.push(\"label\");\n if (/<span\\b|<\\/span>/i.test(code)) {\n descriptor.keywords.push(\"text\");\n descriptor.keywords.push(\"label\");\n }\n if (/<figcaption\\b|<caption\\b/i.test(code)) descriptor.keywords.push(\"caption\");\n if (/<blockquote\\b/i.test(code)) descriptor.keywords.push(\"quote\");\n\n // Data-name hints for text roles (e.g. data-name=\"Title\", data-name=\"Description\")\n if (/data-name=[\"'][^\"']*\\btext\\b/i.test(allText)) descriptor.keywords.push(\"text\");\n if (/data-name=[\"'][^\"']*\\blabel\\b/i.test(allText)) {\n descriptor.keywords.push(\"label\");\n // Check for \"Label container\" pattern\n if (/data-name=[\"'][^\"']*label.*container/i.test(allText)) {\n descriptor.keywords.push(\"label container\");\n }\n }\n if (/data-name=[\"'][^\"']*\\btitle\\b/i.test(allText)) {\n descriptor.keywords.push(\"title\");\n descriptor.keywords.push(\"heading\");\n }\n if (/data-name=[\"'][^\"']*\\bheading\\b/i.test(allText)) {\n descriptor.keywords.push(\"heading\");\n descriptor.keywords.push(\"title\");\n }\n if (/data-name=[\"'][^\"']*\\b(paragraph|description)\\b/i.test(allText)) {\n descriptor.keywords.push(\"paragraph\");\n descriptor.keywords.push(\"text\");\n }\n if (/data-name=[\"'][^\"']*\\bsubtitle\\b/i.test(allText)) descriptor.keywords.push(\"subtitle\");\n if (/data-name=[\"'][^\"']*\\bbody\\b/i.test(allText)) descriptor.keywords.push(\"body text\");\n \n // Field/Container patterns\n if (/data-name=[\"'][^\"']*field.*container|data-name=[\"'][^\"']*input.*container/i.test(allText)) {\n descriptor.keywords.push(\"input field\");\n descriptor.keywords.push(\"field container\");\n }\n if (/data-name=[\"'][^\"']*search/i.test(allText)) {\n descriptor.keywords.push(\"search\");\n descriptor.purpose = \"search interface\";\n }\n if (/data-name=[\"'][^\"']*search.*text|data-name=[\"'][^\"']*search.*input|data-name=[\"'][^\"']*search\\s*\\+/i.test(allText)) {\n descriptor.keywords.push(\"search input\");\n descriptor.keywords.push(\"search\");\n }\n\n // State combinations in data-names (e.g., \"State=enabled, Content=filled text\")\n const stateContentMatches = code.matchAll(/data-name=[\"']([^\"']*state[^\"']*)[\"']/gi);\n for (const match of stateContentMatches) {\n const stateContent = match[1].toLowerCase();\n if (/state.*enabled/i.test(stateContent)) {\n descriptor.keywords.push(\"enabled\");\n }\n if (/state.*disabled/i.test(stateContent)) {\n descriptor.keywords.push(\"disabled\");\n }\n if (/state.*error/i.test(stateContent)) {\n descriptor.colors.push(\"error\");\n descriptor.keywords.push(\"error state\");\n }\n if (/state.*success/i.test(stateContent)) {\n descriptor.colors.push(\"success\");\n descriptor.keywords.push(\"success state\");\n }\n if (/content.*filled|content.*filled.*text/i.test(stateContent)) {\n descriptor.keywords.push(\"filled\");\n descriptor.keywords.push(\"filled text\");\n }\n if (/content.*placeholder/i.test(stateContent)) {\n descriptor.keywords.push(\"placeholder\");\n }\n if (/content.*empty/i.test(stateContent)) {\n descriptor.keywords.push(\"empty\");\n }\n }\n\n // Vector/Icon patterns in data-names\n if (/data-name=[\"'][^\"']*\\bvector\\b/i.test(allText)) {\n descriptor.keywords.push(\"vector\");\n descriptor.keywords.push(\"icon\");\n }\n\n // Import patterns (images, SVGs)\n if (/import\\s+img|import.*from.*svg|import.*from.*asset/i.test(code)) {\n descriptor.visual.push(\"image\");\n descriptor.keywords.push(\"image import\");\n }\n if (/import.*svg/i.test(code)) {\n descriptor.keywords.push(\"svg\");\n descriptor.keywords.push(\"icon\");\n }\n\n // Size/layout hints from code\n if (/size-\\[64|h-\\[64|w-\\[64|64px|size-\\[48|h-\\[48/i.test(code)) descriptor.keywords.push(\"large icon\");\n if (/gap-\\[16\\]|gap-\\[24\\]|gap-\\[32\\]/i.test(code)) descriptor.keywords.push(\"spaced\");\n if (/rounded-\\[8\\]|rounded-\\[12\\]|rounded-lg/i.test(code)) descriptor.keywords.push(\"rounded\");\n\n // Shadow / elevation from code\n if (/shadow-\\[|drop-shadow|elevation/i.test(allText)) descriptor.keywords.push(\"shadow\");\n\n // Conditional rendering patterns (e.g., if (state === \"enabled\" && content === \"filled text\"))\n if (/if\\s*\\(.*state.*===|if\\s*\\(.*content.*===/i.test(code)) {\n descriptor.keywords.push(\"conditional\");\n descriptor.keywords.push(\"stateful\");\n }\n\n // CSS class patterns (e.g., css-ew64yg, css-4hzbpn)\n if (/css-[a-z0-9]+/i.test(code)) {\n descriptor.keywords.push(\"styled\");\n }\n\n // Relative/absolute positioning\n if (/relative|absolute/i.test(code)) {\n descriptor.keywords.push(\"positioned\");\n }\n\n // Shrink/grow patterns\n if (/shrink-0|grow|flex-\\[1_0_0\\]/i.test(code)) {\n descriptor.keywords.push(\"flexible\");\n }\n\n // Min/max width/height patterns\n if (/min-w-|max-w-|min-h-|max-h-/i.test(code)) {\n descriptor.keywords.push(\"constrained\");\n }\n\n // Overflow patterns\n if (/overflow-clip|overflow-hidden|overflow-scroll/i.test(code)) {\n descriptor.keywords.push(\"overflow\");\n }\n\n // Inset patterns (e.g., inset-[8.33%])\n if (/inset-\\[/i.test(code)) {\n descriptor.keywords.push(\"inset\");\n }\n\n // Var() CSS variable patterns\n if (/var\\(--color|var\\(--typescale/i.test(code)) {\n descriptor.keywords.push(\"design tokens\");\n descriptor.keywords.push(\"themed\");\n }\n\n // Extract className values for additional patterns\n const classNameMatches = code.matchAll(/className=[\"']([^\"']+)[\"']/gi);\n for (const match of classNameMatches) {\n const className = match[1].toLowerCase();\n // Extract meaningful class patterns\n if (/flex|grid/i.test(className)) {\n descriptor.layout.push(\"flex layout\");\n }\n if (/items-center|justify-center/i.test(className)) {\n descriptor.layout.push(\"centered\");\n }\n if (/gap-/i.test(className)) {\n descriptor.keywords.push(\"spaced\");\n }\n if (/rounded/i.test(className)) {\n descriptor.keywords.push(\"rounded\");\n }\n if (/shadow/i.test(className)) {\n descriptor.keywords.push(\"shadow\");\n }\n }\n\n // Extract default prop values (e.g., showLabel = true, state = \"enabled\")\n const defaultPropMatches = code.matchAll(/(\\w+)\\s*=\\s*[\"']?([^\"',\\s\\)]+)[\"']?/gi);\n for (const match of defaultPropMatches) {\n const propName = match[1].toLowerCase();\n const propValue = match[2].toLowerCase();\n if (propName === \"state\" && propValue) {\n if (propValue === \"enabled\") descriptor.keywords.push(\"enabled\");\n if (propValue === \"disabled\") descriptor.keywords.push(\"disabled\");\n if (propValue === \"error\") {\n descriptor.colors.push(\"error\");\n descriptor.keywords.push(\"error state\");\n }\n if (propValue === \"success\") {\n descriptor.colors.push(\"success\");\n descriptor.keywords.push(\"success state\");\n }\n }\n if (propName === \"content\" && propValue) {\n if (propValue.includes(\"placeholder\")) descriptor.keywords.push(\"placeholder\");\n if (propValue.includes(\"filled\")) descriptor.keywords.push(\"filled\");\n }\n }\n }\n\n /**\n * Extract visual characteristics from design tokens\n * Parses Figma design token format: \"TokenName: Value\" or \"TokenName/SubToken: Value\"\n */\n private extractFromTokens(tokens: string, descriptor: ComponentDescriptor): void {\n if (!tokens || tokens.trim().length === 0) return;\n\n if (!descriptor.visual) descriptor.visual = [];\n if (!descriptor.colors) descriptor.colors = [];\n if (!descriptor.typography) descriptor.typography = [];\n if (!descriptor.effects) descriptor.effects = [];\n if (!descriptor.layout) descriptor.layout = [];\n if (!descriptor.keywords) descriptor.keywords = [];\n\n // Parse tokens - they're comma-separated: \"Token: Value, Token2: Value\"\n const tokenEntries = tokens.split(',').map(t => t.trim());\n\n for (const entry of tokenEntries) {\n // Extract token name and value\n // Format: \"TokenName/SubToken: Value\" or \"TokenName: Value\"\n const match = entry.match(/^([^:]+):\\s*(.+)$/);\n if (!match) continue;\n\n const tokenName = match[1].trim();\n const tokenValue = match[2].trim();\n const lowerTokenName = tokenName.toLowerCase();\n\n // Extract semantic color names\n if (lowerTokenName.includes('color') || lowerTokenName.includes('background') || \n lowerTokenName.includes('icon') || lowerTokenName.includes('text') ||\n lowerTokenName.includes('action') || lowerTokenName.includes('border')) {\n \n // Extract semantic color category\n if (lowerTokenName.includes('warning')) {\n if (!descriptor.colors.includes('warning')) {\n descriptor.colors.push('warning');\n }\n if (lowerTokenName.includes('background')) {\n descriptor.visual.push('warning background');\n }\n if (lowerTokenName.includes('icon')) {\n descriptor.visual.push('warning icon');\n }\n } else if (lowerTokenName.includes('error') || lowerTokenName.includes('danger')) {\n if (!descriptor.colors.includes('error')) {\n descriptor.colors.push('error');\n }\n if (lowerTokenName.includes('background')) {\n descriptor.visual.push('error background');\n }\n if (lowerTokenName.includes('icon')) {\n descriptor.visual.push('error icon');\n }\n } else if (lowerTokenName.includes('success')) {\n if (!descriptor.colors.includes('success')) {\n descriptor.colors.push('success');\n }\n if (lowerTokenName.includes('background')) {\n descriptor.visual.push('success background');\n }\n if (lowerTokenName.includes('icon')) {\n descriptor.visual.push('success icon');\n }\n } else if (lowerTokenName.includes('primary') || lowerTokenName.includes('main') || lowerTokenName.includes('brand')) {\n if (!descriptor.colors.includes('primary')) {\n descriptor.colors.push('primary');\n }\n if (lowerTokenName.includes('brand')) {\n descriptor.keywords.push('brand color');\n }\n } else if (lowerTokenName.includes('secondary') || lowerTokenName.includes('alternative')) {\n if (!descriptor.colors.includes('secondary')) {\n descriptor.colors.push('secondary');\n }\n } else if (lowerTokenName.includes('default') || lowerTokenName.includes('neutral')) {\n if (!descriptor.colors.includes('neutral')) {\n descriptor.colors.push('neutral');\n }\n } else if (lowerTokenName.includes('info')) {\n if (!descriptor.colors.includes('info')) {\n descriptor.colors.push('info');\n }\n descriptor.visual.push('info color');\n }\n }\n\n // Extract typography information\n if (lowerTokenName.includes('font') || lowerTokenName.includes('typescale') || \n lowerTokenName.includes('headline') || lowerTokenName.includes('body') ||\n lowerTokenName.includes('button') || lowerTokenName.includes('text') ||\n lowerTokenName.includes('label') || lowerTokenName.includes('helper') ||\n lowerTokenName.includes('placeholder')) {\n \n if (lowerTokenName.includes('headline')) {\n if (!descriptor.typography.includes('headline')) {\n descriptor.typography.push('headline');\n }\n // Extract size if available\n if (lowerTokenName.includes('large')) {\n descriptor.typography.push('large headline');\n } else if (lowerTokenName.includes('medium')) {\n descriptor.typography.push('medium headline');\n } else if (lowerTokenName.includes('small')) {\n descriptor.typography.push('small headline');\n }\n // Desktop/Mobile variants\n if (lowerTokenName.includes('desktop')) {\n descriptor.keywords.push('desktop');\n }\n if (lowerTokenName.includes('mobile')) {\n descriptor.keywords.push('mobile');\n }\n } else if (lowerTokenName.includes('body')) {\n if (!descriptor.typography.includes('body')) {\n descriptor.typography.push('body text');\n }\n if (lowerTokenName.includes('large')) {\n descriptor.typography.push('large body');\n } else if (lowerTokenName.includes('medium')) {\n descriptor.typography.push('medium body');\n } else if (lowerTokenName.includes('small')) {\n descriptor.typography.push('small body');\n }\n // Strong/default variations\n if (lowerTokenName.includes('strong')) {\n descriptor.typography.push('bold');\n descriptor.keywords.push('strong text');\n }\n if (lowerTokenName.includes('default')) {\n descriptor.keywords.push('default text');\n }\n } else if (lowerTokenName.includes('button')) {\n if (!descriptor.typography.includes('button')) {\n descriptor.typography.push('button text');\n }\n if (lowerTokenName.includes('large')) {\n descriptor.typography.push('large button');\n descriptor.keywords.push('large button');\n } else if (lowerTokenName.includes('medium')) {\n descriptor.typography.push('medium button');\n } else if (lowerTokenName.includes('small')) {\n descriptor.typography.push('small button');\n }\n } else if (lowerTokenName.includes('label')) {\n descriptor.keywords.push('label');\n if (lowerTokenName.includes('large')) {\n descriptor.keywords.push('large label');\n }\n } else if (lowerTokenName.includes('helper')) {\n descriptor.keywords.push('helper');\n descriptor.keywords.push('helper text');\n } else if (lowerTokenName.includes('placeholder')) {\n descriptor.keywords.push('placeholder');\n }\n\n // Extract font weight if mentioned\n if (tokenValue.includes('weight') || tokenValue.includes('700') || tokenValue.includes('bold')) {\n descriptor.typography.push('bold');\n } else if (tokenValue.includes('400') || tokenValue.includes('regular')) {\n descriptor.typography.push('regular');\n } else if (tokenValue.includes('600') || tokenValue.includes('semibold')) {\n descriptor.typography.push('semibold');\n }\n\n // Extract line height and letter spacing\n if (tokenValue.includes('lineHeight') || tokenValue.includes('line-height')) {\n descriptor.keywords.push('line height');\n }\n if (tokenValue.includes('letterSpacing') || tokenValue.includes('letter-spacing')) {\n descriptor.keywords.push('letter spacing');\n }\n }\n\n // Extract elevation and shadow effects\n if (lowerTokenName.includes('elevation') || lowerTokenName.includes('shadow') || \n lowerTokenName.includes('effect')) {\n \n if (lowerTokenName.includes('floating') || lowerTokenName.includes('raised')) {\n if (!descriptor.effects.includes('elevated')) {\n descriptor.effects.push('elevated');\n }\n descriptor.layout.push('elevated with shadow');\n } else if (lowerTokenName.includes('drop') || lowerTokenName.includes('shadow')) {\n if (!descriptor.effects.includes('shadow')) {\n descriptor.effects.push('shadow');\n }\n descriptor.layout.push('with shadow');\n } else if (lowerTokenName.includes('flat')) {\n descriptor.keywords.push('flat');\n descriptor.keywords.push('no elevation');\n }\n }\n\n // Extract surface types\n if (lowerTokenName.includes('surface')) {\n if (lowerTokenName.includes('flat')) {\n descriptor.keywords.push('flat surface');\n } else if (lowerTokenName.includes('floating')) {\n descriptor.keywords.push('floating surface');\n descriptor.layout.push('elevated');\n } else if (lowerTokenName.includes('raised')) {\n descriptor.keywords.push('raised surface');\n descriptor.layout.push('elevated');\n } else if (lowerTokenName.includes('state')) {\n if (lowerTokenName.includes('default')) {\n descriptor.keywords.push('default state');\n }\n }\n }\n\n // Extract background types\n if (lowerTokenName.includes('background')) {\n if (lowerTokenName.includes('alternative')) {\n descriptor.keywords.push('alternative background');\n if (lowerTokenName.includes('strong')) {\n descriptor.keywords.push('strong background');\n }\n } else if (lowerTokenName.includes('brand')) {\n descriptor.colors.push('primary');\n descriptor.keywords.push('brand background');\n }\n }\n\n // Extract border radius from rounded values\n if (lowerTokenName.includes('rounded') || lowerTokenName.includes('radius')) {\n descriptor.layout.push('rounded corners');\n }\n\n // Extract action colors (for buttons, CTAs)\n if (lowerTokenName.includes('action')) {\n if (lowerTokenName.includes('main') || lowerTokenName.includes('primary')) {\n descriptor.colors.push('primary');\n descriptor.keywords.push('primary action');\n } else if (lowerTokenName.includes('alternative')) {\n descriptor.colors.push('secondary');\n descriptor.keywords.push('alternative action');\n }\n if (lowerTokenName.includes('selected')) {\n descriptor.keywords.push('selected');\n }\n if (lowerTokenName.includes('on main') || lowerTokenName.includes('on-main')) {\n descriptor.keywords.push('on primary');\n }\n }\n }\n\n // Additional pattern matching for complex token formats\n // Match patterns like \"Background/warning: #FFFAEB\"\n const colorPattern = /(?:Background|Icon|Text|Action|Border)\\/([^:,\\s]+)/gi;\n let colorMatch;\n while ((colorMatch = colorPattern.exec(tokens)) !== null) {\n const semanticName = colorMatch[1].toLowerCase();\n if (semanticName && !descriptor.colors.includes(semanticName)) {\n descriptor.colors.push(semanticName);\n }\n }\n\n // Match elevation patterns\n if (/Elevation\\s+(?:raised|floating|flat)/i.test(tokens)) {\n if (!descriptor.effects.includes('elevated')) {\n descriptor.effects.push('elevated');\n }\n descriptor.layout.push('elevated with shadow');\n }\n\n // Detect Effect types (DROP_SHADOW, etc.)\n if (/Effect\\(.*DROP_SHADOW/i.test(tokens)) {\n if (!descriptor.effects.includes('shadow')) {\n descriptor.effects.push('shadow');\n }\n descriptor.layout.push('with shadow');\n }\n\n // Component specific exceptions (e.g., \"Component specific exceptions/Placeholder\")\n if (/Component\\s+specific\\s+exceptions/i.test(tokens)) {\n if (/placeholder/i.test(tokens)) {\n descriptor.keywords.push('placeholder');\n }\n if (/header.*icon/i.test(tokens)) {\n descriptor.keywords.push('header icon');\n }\n if (/button/i.test(tokens)) {\n descriptor.keywords.push('button');\n }\n }\n\n // Helper text detection\n if (/helper.*text|typescale.*helper/i.test(tokens)) {\n descriptor.keywords.push('helper');\n descriptor.keywords.push('helper text');\n }\n\n // Token-based keywords\n if (/Action\\/main|action.*main/i.test(tokens) && /#EC0000|#e00|red|danger/i.test(tokens)) {\n descriptor.keywords.push('destructive');\n descriptor.keywords.push('primary action');\n }\n if (/Elevation\\s+floating|elevation.*floating/i.test(tokens)) {\n descriptor.keywords.push('floating');\n }\n if (/Background\\/warning|Icon\\/warning|warning/i.test(tokens)) {\n descriptor.keywords.push('warning');\n }\n if (/Headline|headline|typescale/i.test(tokens)) {\n descriptor.keywords.push('headline');\n }\n if (/Body\\/Body|body.*default/i.test(tokens)) {\n descriptor.keywords.push('body text');\n }\n if (/Button Large|button\\/large|Button Large/i.test(tokens)) {\n descriptor.keywords.push('large button');\n }\n if (/Surface\\/floating|surface.*floating/i.test(tokens)) {\n descriptor.keywords.push('floating surface');\n descriptor.layout.push('elevated');\n }\n if (/Surface\\/raised|surface.*raised/i.test(tokens)) {\n descriptor.keywords.push('raised surface');\n descriptor.layout.push('elevated');\n }\n\n // Extract more color patterns (Text/info, Icon/soft, etc.)\n if (/Text\\/info|text.*info/i.test(tokens)) {\n descriptor.colors.push('info');\n descriptor.keywords.push('info text');\n }\n if (/Text\\/soft|text.*soft/i.test(tokens)) {\n descriptor.keywords.push('soft text');\n }\n if (/Icon\\/soft|icon.*soft/i.test(tokens)) {\n descriptor.keywords.push('soft icon');\n }\n if (/Icon\\/default|icon.*default/i.test(tokens)) {\n descriptor.keywords.push('default icon');\n }\n\n // Extract more typography patterns\n if (/Body.*Medium.*Strong|body.*medium.*strong/i.test(tokens)) {\n descriptor.typography.push('bold');\n descriptor.typography.push('medium body');\n descriptor.keywords.push('strong text');\n }\n if (/Body.*Medium.*Default|body.*medium.*default/i.test(tokens)) {\n descriptor.typography.push('medium body');\n descriptor.keywords.push('default text');\n }\n if (/Headline.*Desktop|headline.*desktop/i.test(tokens)) {\n descriptor.keywords.push('desktop');\n }\n if (/Headline.*Mobile|headline.*mobile/i.test(tokens)) {\n descriptor.keywords.push('mobile');\n }\n\n // Extract Surface/State patterns\n if (/Surface\\/State|surface.*state/i.test(tokens)) {\n descriptor.keywords.push('state surface');\n if (/default/i.test(tokens)) {\n descriptor.keywords.push('default state');\n }\n }\n\n // Extract more background patterns\n if (/Background\\/alternative|background.*alternative/i.test(tokens)) {\n descriptor.keywords.push('alternative background');\n }\n if (/Background\\/alternative.*strong|background.*alternative.*strong/i.test(tokens)) {\n descriptor.keywords.push('strong alternative background');\n }\n\n // Extract more border patterns\n if (/Border\\/default|border.*default/i.test(tokens)) {\n descriptor.keywords.push('default border');\n }\n if (/Border\\/alternative|border.*alternative/i.test(tokens)) {\n descriptor.keywords.push('alternative border');\n }\n\n // Extract Font family patterns\n if (/Font\\(family:|font.*family/i.test(tokens)) {\n descriptor.keywords.push('custom font');\n if (/Santander/i.test(tokens)) {\n descriptor.keywords.push('santander font');\n }\n }\n\n // Extract letter spacing and line height from Font() patterns\n if (/letterSpacing|letter-spacing/i.test(tokens)) {\n descriptor.keywords.push('letter spacing');\n }\n if (/lineHeight|line-height/i.test(tokens)) {\n descriptor.keywords.push('line height');\n }\n\n // Extract size from Font() patterns\n if (/size:\\s*(\\d+)/i.test(tokens)) {\n const sizeMatches = tokens.matchAll(/size:\\s*(\\d+)/gi);\n for (const match of sizeMatches) {\n const size = parseInt(match[1], 10);\n if (size >= 24) {\n descriptor.keywords.push('large text');\n } else if (size >= 16) {\n descriptor.keywords.push('medium text');\n } else {\n descriptor.keywords.push('small text');\n }\n }\n }\n }\n}\n","/**\n * Query Builder\n * Builds semantic queries from component descriptors\n */\n\nimport type { ComponentDescriptor } from \"./types.js\";\n\n/**\n * Build a natural language query from extracted descriptor\n * Prioritizes semantic richness for embedding-based search\n * Includes hierarchy and enhanced design token information\n */\nexport function buildSemanticQuery(descriptor: ComponentDescriptor, fallback: string): string {\n const queryParts: string[] = [];\n\n // 1. Add primary components (most important for matching)\n // Prioritize complex/specific components over generic ones\n const componentArray = Array.from(descriptor.components);\n const priorityComponents = prioritizeComponents(componentArray);\n \n if (priorityComponents.length > 0) {\n // For complex frames: include top 5-7 components\n // For simple frames: this will naturally be fewer\n queryParts.push(...priorityComponents.slice(0, 7));\n }\n\n // 2. Add hierarchy information (structural parts)\n if (descriptor.hierarchy.length > 0) {\n // Build hierarchy description\n const hierarchyParts = descriptor.hierarchy.slice(0, 4); // Limit to avoid too long\n if (hierarchyParts.length > 0) {\n // Create natural hierarchy description\n if (hierarchyParts.includes('header') && hierarchyParts.includes('body')) {\n queryParts.push('with header and body');\n } else if (hierarchyParts.includes('header') && hierarchyParts.includes('footer')) {\n queryParts.push('with header and footer');\n } else if (hierarchyParts.length === 1) {\n queryParts.push(`with ${hierarchyParts[0]}`);\n } else {\n // Add individual hierarchy parts\n queryParts.push(...hierarchyParts.slice(0, 3));\n }\n }\n }\n\n // 3. Add purpose if present (provides semantic context)\n if (descriptor.purpose) {\n queryParts.push(descriptor.purpose);\n }\n\n // 4. Add key interactions (helps match use cases)\n // Filter out interactions that are already covered by purpose\n if (descriptor.interactions.size > 0) {\n const interactions = Array.from(descriptor.interactions)\n .filter(interaction => {\n // Don't add \"confirmation\" if purpose already contains it\n if (interaction === \"confirmation\" && descriptor.purpose?.includes(\"confirmation\")) {\n return false;\n }\n return true;\n })\n .slice(0, 2);\n queryParts.push(...interactions);\n }\n\n // 5. Add semantic colors from design tokens\n if (descriptor.colors.length > 0) {\n queryParts.push(...descriptor.colors.slice(0, 3));\n }\n\n // 6. Add visual characteristics (helps with visual similarity)\n if (descriptor.visual.length > 0) {\n queryParts.push(...descriptor.visual.slice(0, 4));\n }\n\n // 7. Add typography information (if relevant)\n if (descriptor.typography.length > 0) {\n // Only add most distinctive typography features\n const distinctiveTypography = descriptor.typography.filter(t => \n t.includes('headline') || t.includes('bold') || t.includes('large')\n );\n if (distinctiveTypography.length > 0) {\n queryParts.push(...distinctiveTypography.slice(0, 2));\n }\n }\n\n // 8. Add effects (elevation, shadows)\n if (descriptor.effects.length > 0) {\n queryParts.push(...descriptor.effects.slice(0, 2));\n }\n\n // 9. Add layout traits (secondary importance)\n if (descriptor.layout.length > 0) {\n queryParts.push(...descriptor.layout.slice(0, 3));\n }\n\n // 10. Add additional keywords\n if (descriptor.keywords.length > 0) {\n queryParts.push(...descriptor.keywords.slice(0, 8));\n }\n\n // 11. Deduplicate terms (case-insensitive)\n const seen = new Set<string>();\n const uniqueParts = queryParts.filter(part => {\n const lower = part.toLowerCase();\n if (seen.has(lower)) {\n return false;\n }\n seen.add(lower);\n return true;\n });\n\n // Build final query\n if (uniqueParts.length > 0) {\n return uniqueParts.join(\" \");\n }\n\n return fallback;\n}\n\n/**\n * Prioritize components by specificity and importance\n * More specific components rank higher\n */\nexport function prioritizeComponents(components: string[]): string[] {\n const priority: { [key: string]: number } = {\n // High specificity - these are most valuable for matching\n \"segmented control\": 10,\n \"icon button\": 9,\n \"stepper\": 9,\n \"breadcrumb\": 9,\n \"calendar\": 9,\n \"carousel\": 9,\n \"accordion\": 9,\n \"datepicker\": 9,\n \"chart\": 8,\n \"table\": 8,\n \"navbar\": 8,\n \"sidebar\": 8,\n \"modal\": 8,\n \"tabs\": 8,\n \n // Medium specificity\n \"dropdown\": 7,\n \"slider\": 7,\n \"switch\": 7,\n \"checkbox\": 7,\n \"radio\": 7,\n \"textarea\": 7,\n \"pagination\": 7,\n \"card\": 7,\n \"menu\": 7,\n \"badge\": 6,\n \"tooltip\": 6,\n \"alert\": 6,\n \"progress\": 6,\n \"toast\": 6,\n \"avatar\": 6,\n \n // Lower specificity - common components\n \"button\": 5,\n \"input\": 5,\n \"list\": 4,\n \"grid\": 4,\n \"header\": 3,\n \"footer\": 3,\n \"icon\": 2,\n \"image\": 2,\n };\n\n return components.sort((a, b) => {\n const priorityA = priority[a] || 0;\n const priorityB = priority[b] || 0;\n return priorityB - priorityA;\n });\n}\n","/**\n * Design Query Extractor\n * \n * Main entry point for extracting semantic queries from Figma designs\n * optimized for Pinecone semantic/embedding-based search.\n */\n\nimport type { FigmaDesignContextResult } from \"../../clients/figma-client.js\";\nimport type { ComponentDescriptor } from \"./types.js\";\nimport { MetadataExtractorSimpler } from \"./metadata-extractor-simpler.js\";\nimport { DesignContextExtractor } from \"./design-context-extractor.js\";\nimport { buildSemanticQuery } from \"./query-builder.js\";\n\n/**\n * Extracts semantic descriptions from Figma design context for Pinecone search\n */\nexport class DesignQueryExtractor {\n private metadataExtractor: MetadataExtractorSimpler;\n private designContextExtractor: DesignContextExtractor;\n\n constructor() {\n this.metadataExtractor = new MetadataExtractorSimpler();\n this.designContextExtractor = new DesignContextExtractor();\n }\n\n /**\n * Extracts a semantic query optimized for embedding-based search from design context\n */\n extractQuery(\n designContext: FigmaDesignContextResult,\n fallbackQuery: string = \"UI component\",\n ): string {\n if (!designContext.content || designContext.content.length === 0) {\n return fallbackQuery;\n }\n\n const descriptor: ComponentDescriptor = {\n components: new Set<string>(),\n visual: [],\n layout: [],\n interactions: new Set<string>(),\n hierarchy: [],\n colors: [],\n typography: [],\n effects: [],\n keywords: [],\n };\n\n // Extract from each content item\n for (const item of designContext.content) {\n if (item.type === \"text\" && typeof item.text === \"string\") {\n const text = item.text;\n\n // Separate code from design tokens\n const parts = text.split(/These styles are contained in the design:/i);\n const codeSection = parts[0] || \"\";\n const tokensSection = parts[1] || \"\";\n\n // Extract from code and tokens\n this.designContextExtractor.extractFromCodeAndTokens(codeSection, tokensSection, descriptor);\n }\n }\n\n // Build semantic query from descriptor\n return buildSemanticQuery(descriptor, fallbackQuery);\n }\n\n /**\n * Extracts a semantic query from Figma metadata (XML-like structure)\n * Parses instance names and frame names to identify components\n */\n extractQueryFromMetadata(\n metadata: FigmaDesignContextResult,\n ): string {\n if (!metadata.content || metadata.content.length === 0) {\n return \"\";\n }\n\n const descriptor: ComponentDescriptor = {\n components: new Set<string>(),\n visual: [],\n layout: [],\n interactions: new Set<string>(),\n hierarchy: [],\n colors: [],\n typography: [],\n effects: [],\n keywords: [],\n };\n\n // Extract from each content item (metadata is typically in text format with XML-like structure)\n for (const item of metadata.content) {\n if (item.type === \"text\" && typeof item.text === \"string\") {\n const metadataText = item.text;\n // Extract all names from metadata and use them as keywords\n const names = this.metadataExtractor.extractNames(metadataText);\n descriptor.keywords.push(...names);\n }\n }\n\n // Build semantic query from descriptor (use empty string as fallback if no names found)\n return buildSemanticQuery(descriptor, \"\");\n }\n}\n\n// Re-export types and utilities\nexport type { ComponentDescriptor } from \"./types.js\";\nexport { MetadataExtractorSimpler } from \"./metadata-extractor-simpler.js\";\n","/**\n * Pinecone Search Service\n * Reusable service for semantic search of design system components\n * Uses Frida Pinecone Proxy API for secure access\n */\n\nimport \"dotenv/config\";\nimport { logger } from \"../../utils/logger.js\";\n\nexport interface ComponentMatch {\n id: string; // From match.id\n tag: string; // From metadata.tag\n score: number; // From match.score\n name: string; // From metadata.name\n framework: string; // From metadata.framework\n category: string; // From metadata.category\n overview: string; // From metadata.overview\n visual: string; // From metadata.visual\n technical: string; // From metadata.technical\n keywords: string[]; // From metadata.keywords\n}\n\nexport interface SearchOptions {\n minScore?: number;\n topK?: number;\n namespace?: string;\n}\n\nexport interface SearchResults {\n query: string;\n totalMatches: number;\n relevantMatches: number;\n matches: ComponentMatch[];\n searchMetadata: {\n minScore: number;\n topK: number;\n indexName: string;\n namespace?: string;\n };\n}\n\nexport interface PineconeSearchServiceOptions {\n namespace?: string;\n}\n\nexport class PineconeSearchService {\n private indexName: string;\n private namespace?: string;\n private minScore: number;\n private topK: number;\n private fridaEmbeddingUrl: string;\n private fridaApiKey: string;\n private fridaPineconeProxyUrl: string;\n private fridaEmbeddingModel: string;\n\n constructor(options: PineconeSearchServiceOptions = {}) {\n this.indexName = process.env.PINECONE_INDEX!;\n this.namespace = options.namespace;\n this.minScore = parseFloat(process.env.PINECONE_MIN_SCORE!);\n this.topK = parseInt(process.env.PINECONE_TOP_K!, 10);\n this.fridaEmbeddingUrl = process.env.FRIDA_EMBEDDING_URL!;\n this.fridaApiKey = process.env.FRIDA_BEARER_TOKEN!;\n this.fridaPineconeProxyUrl = process.env.FRIDA_PINECONE_PROXY_URL!;\n this.fridaEmbeddingModel = process.env.FRIDA_EMBEDDING_MODEL!;\n }\n\n /**\n * Generates embedding for a text using Frida API\n * @param text - Text to embed\n * @returns Promise<number[]> Embedding vector (1536 dimensions)\n */\n async generateEmbedding(text: string): Promise<number[]> {\n try {\n logger.debug(\"Calling Frida Embedding API...\");\n const startTime = Date.now();\n\n const response = await fetch(this.fridaEmbeddingUrl, {\n method: \"POST\",\n headers: {\n accept: \"application/json\",\n Authorization: `Bearer ${this.fridaApiKey}`,\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify({\n input: text,\n model: this.fridaEmbeddingModel,\n user_id: \"pinecone-search\",\n email: process.env.MCP_USER_EMAIL || \"figma2frida_mcp@fridaplatform.com\",\n }),\n });\n\n logger.debug(`API response status: ${response.status}`);\n\n if (!response.ok) {\n const errorText = await response.text();\n logger.error(\"API Error response:\", errorText);\n throw new Error(`API Error: ${response.status} ${response.statusText}`);\n }\n\n logger.debug(\"Parsing API response...\");\n const data = (await response.json()) as {\n data?: Array<{ embedding?: number[] }>;\n };\n\n if (!data.data || !data.data[0] || !data.data[0].embedding) {\n logger.error(\"Invalid response format:\", JSON.stringify(data).substring(0, 200));\n throw new Error(\"Invalid API response format\");\n }\n\n const embedding = data.data[0].embedding;\n const elapsed = Date.now() - startTime;\n logger.debug(`✓ Embedding generated (${embedding.length} dims) in ${elapsed}ms`);\n\n return embedding; // Returns 1536-dimensional array\n } catch (error) {\n logger.error(\"Error generating embedding:\", error);\n throw new Error(`Failed to generate embedding: ${error instanceof Error ? error.message : String(error)}`);\n }\n }\n\n /**\n * Parses a Pinecone match to structured format\n * New simplified schema: tag, name, framework, category, overview, visual, technical, keywords\n */\n private parseMatch(match: {\n id?: string;\n score?: number;\n metadata?: Record<string, unknown>;\n }): ComponentMatch {\n const metadata = match.metadata || {};\n\n return {\n id: match.id || \"unknown\",\n tag: (metadata.tag as string) || match.id || \"unknown\",\n score: match.score || 0,\n name: (metadata.name as string) || \"\",\n framework: (metadata.framework as string) || \"\",\n category: (metadata.category as string) || \"General\",\n overview: (metadata.overview as string) || \"\",\n visual: (metadata.visual as string) || \"\",\n technical: (metadata.technical as string) || \"\",\n keywords: Array.isArray(metadata.keywords) ? (metadata.keywords as string[]) : [],\n };\n }\n\n /**\n * Queries Pinecone via Frida Proxy API\n * @param embedding - Embedding vector\n * @param topK - Number of results to return\n * @param namespace - Optional namespace\n * @returns Query response from Pinecone\n */\n private async queryPineconeProxy(\n embedding: number[],\n topK: number,\n namespace?: string,\n ): Promise<{\n matches?: Array<{\n id?: string;\n score?: number;\n metadata?: Record<string, unknown>;\n }>;\n namespace?: string;\n }> {\n const url = `${this.fridaPineconeProxyUrl}/pinecone/data/${this.indexName}/query`;\n\n logger.debug(`Querying Frida Pinecone Proxy: ${url}${namespace ? ` (namespace: \"${namespace}\")` : \"\"}`);\n\n const requestBody: {\n vector: number[];\n topK: number;\n includeMetadata: boolean;\n namespace?: string;\n } = {\n vector: embedding,\n topK,\n includeMetadata: true,\n };\n\n // Add namespace to request body if provided\n if (namespace) {\n requestBody.namespace = namespace;\n }\n\n const startTime = Date.now();\n const response = await fetch(url, {\n method: \"POST\",\n headers: {\n \"Authorization\": `Bearer ${this.fridaApiKey}`,\n \"Content-Type\": \"application/json\",\n \"Accept\": \"application/json\",\n },\n body: JSON.stringify(requestBody),\n });\n\n const queryTime = Date.now() - startTime;\n logger.debug(`Proxy API response status: ${response.status} (${queryTime}ms)`);\n\n if (!response.ok) {\n const errorText = await response.text();\n logger.error(\"Proxy API Error response:\", errorText);\n throw new Error(`Pinecone Proxy API Error: ${response.status} ${response.statusText} - ${errorText}`);\n }\n\n const data = await response.json() as {\n matches?: Array<{\n id?: string;\n score?: number;\n metadata?: Record<string, unknown>;\n }>;\n namespace?: string;\n };\n\n return data;\n }\n\n /**\n * Searches for components in Pinecone via Frida Proxy\n * @param query - Search query\n * @param options - Search options\n * @returns Structured results\n */\n async search(query: string, options: SearchOptions = {}): Promise<SearchResults> {\n if (!query || typeof query !== \"string\") {\n throw new Error(\"Query must be a non-empty string\");\n }\n logger.debug(`[DEBUG] options object: ${JSON.stringify(options)}`);\n logger.debug(`[DEBUG] options.topK: ${options.topK}, type: ${typeof options.topK}`);\n logger.debug(`[DEBUG] options.topK !== undefined: ${options.topK !== undefined}`);\n logger.debug(`[DEBUG] this.topK (instance): ${this.topK}`);\n\n const minScore =\n options.minScore !== undefined ? options.minScore : this.minScore;\n const topK = options.topK !== undefined ? options.topK : this.topK;\n // Namespace: prioritize options.namespace, then this.namespace\n const namespace = options.namespace !== undefined ? options.namespace : this.namespace;\n\n logger.debug(`Starting search - Query: \"${query}\", topK: ${topK}, minScore: ${minScore}${namespace ? `, namespace: \"${namespace}\"` : \"\"}`);\n\n // Generate embedding for the query\n const embedding = await this.generateEmbedding(query);\n\n // Query Pinecone via Frida Proxy\n logger.debug(`Querying Pinecone index \"${this.indexName}\" via Frida Proxy${namespace ? ` namespace \"${namespace}\"` : \"\"}...`);\n const startTime = Date.now();\n\n const queryResponse = await this.queryPineconeProxy(embedding, topK, namespace);\n const queryTime = Date.now() - startTime;\n logger.debug(`Query completed in ${queryTime}ms - Found ${queryResponse.matches?.length || 0} matches`);\n\n // Process results\n const allMatches = queryResponse.matches || [];\n const relevantMatches = allMatches.filter((m) => (m.score || 0) >= minScore);\n\n logger.debug(`Filtered results: ${relevantMatches.length} relevant (score >= ${minScore}) out of ${allMatches.length} total`);\n\n return {\n query,\n totalMatches: allMatches.length,\n relevantMatches: relevantMatches.length,\n matches: relevantMatches.map((match) => this.parseMatch(match)),\n searchMetadata: {\n minScore,\n topK,\n indexName: this.indexName,\n namespace: namespace,\n },\n };\n }\n\n /**\n * Gets details of a specific component by tag or id\n * @param tag - Component tag or id (e.g.: 'wtw-button-split', 'my-badge')\n * @returns Component details or null if it doesn't exist\n */\n async getComponentDetails(tag: string): Promise<ComponentMatch | null> {\n if (!tag || typeof tag !== \"string\") {\n throw new Error(\"Tag must be a non-empty string\");\n }\n\n // Search for the specific component\n const results = await this.search(tag, { topK: 10, minScore: 0 });\n\n // Find exact match by tag or id\n const exactMatch = results.matches.find(\n (m) => m.tag === tag || m.id === tag\n );\n\n if (exactMatch) {\n return exactMatch;\n }\n\n // If no exact match, return the closest one\n if (results.matches.length > 0) {\n return results.matches[0];\n }\n\n return null;\n }\n\n /**\n * Searches for multiple components by tags\n * @param tags - Array of component tags\n * @returns Array of component details\n */\n async getMultipleComponents(tags: string[]): Promise<ComponentMatch[]> {\n if (!Array.isArray(tags)) {\n throw new Error(\"Tags must be an array\");\n }\n\n const results = await Promise.all(\n tags.map((tag) => this.getComponentDetails(tag)),\n );\n\n return results.filter(\n (r): r is ComponentMatch => r !== null,\n );\n }\n}\n\n","/**\n * Formatters\n * Utilities to format search results in different formats\n */\n\nimport type {\n ComponentMatch,\n SearchResults,\n} from \"../services/pinecone/pinecone-service.js\";\n\nexport class Formatters {\n /**\n * Formats results in structured format (JSON-friendly)\n */\n static toStructured(searchResults: SearchResults): {\n query: string;\n summary: {\n totalMatches: number;\n relevantMatches: number;\n minScore: number;\n };\n components: Array<{\n id: string;\n tag: string;\n score: number;\n name: string;\n framework: string;\n category: string;\n overview: string;\n visual: string;\n technical: string;\n keywords: string[];\n }>;\n } {\n return {\n query: searchResults.query,\n summary: {\n totalMatches: searchResults.totalMatches,\n relevantMatches: searchResults.relevantMatches,\n minScore: searchResults.searchMetadata.minScore,\n },\n components: searchResults.matches.map((match) => ({\n id: match.id,\n tag: match.tag,\n score: match.score,\n name: match.name,\n framework: match.framework,\n category: match.category,\n overview: match.overview,\n visual: match.visual,\n technical: match.technical,\n keywords: match.keywords,\n })),\n };\n }\n\n /**\n * Formats results in readable markdown format\n */\n static toMarkdown(searchResults: SearchResults): string {\n if (!searchResults.matches || searchResults.matches.length === 0) {\n return `## No similar components found\n\n**Query:** \"${searchResults.query}\"\n\nSuggestion: Try more general terms or verify that components are indexed.`;\n }\n\n //Verify to add or hide to show what was queried // **Query:** \"${searchResults.query}\"\n let markdown = `## Search Results\n**Components found:** ${searchResults.relevantMatches} of ${searchResults.totalMatches}\n---\n`;\n\n searchResults.matches.forEach((match, index) => {\n markdown += `### ${index + 1}. ${match.tag}\n\n**Technical Documentation:**\n${match.technical || \"No technical documentation available\"}\n\n---\n\n`;\n });\n\n return markdown;\n }\n\n /**\n * Formats multiple components for context in prompts\n * Uses JSON format for better LLM understanding\n */\n static matchesToContext(matches: ComponentMatch[]): string {\n if (!matches || matches.length === 0) {\n return \"No components found.\";\n }\n\n // Use JSON format for component documentation which works well with LLMs\n // This provides structured data that LLMs can parse better than plain text\n const componentsArray = matches.map((match) => ({\n tag: match.tag,\n score: match.score, // Pinecone ranking\n overview: match.overview,\n visual: match.visual,\n keywords: match.keywords,\n }));\n\n // Return as JSON string with clear structure\n return JSON.stringify({ components: componentsArray }, null, 2);\n }\n\n /**\n * Formats components with only essential fields (tag, score, overview) for lightweight filtering\n * Used when sending to Frida for tag-only filtering\n */\n static matchesToLightweightContext(matches: ComponentMatch[]): string {\n if (!matches || matches.length === 0) {\n return \"No components found.\";\n }\n\n // Only include tag, score, and overview for lightweight filtering\n const componentsArray = matches.map((match) => ({\n tag: match.tag,\n score: match.score,\n overview: match.overview,\n }));\n\n // Return as JSON string with clear structure\n return JSON.stringify({ components: componentsArray }, null, 2);\n }\n\n}\n\n","/**\n * Session Validator\n *\n * Validates a session token against the figma2frida backend.\n * Returns the projectId, llmopsApiKey, userId, and email\n * for the MCP server to use.\n */\n\nimport { logger } from \"../../utils/logger.js\";\n\nconst VALIDATION_URL = \"https://us-central1-figma2frida-mcp.cloudfunctions.net/validateSession\";\n\nexport interface SessionValidationResult {\n valid: boolean;\n projectId: string;\n llmopsApiKey: string;\n userId: string;\n email: string;\n}\n\n/**\n * Validates a session token and returns MCP config.\n *\n * @param sessionToken - The session token from --session-token CLI arg\n * @returns Session data including projectId, llmopsApiKey, userId, email\n */\nexport async function validateSession(sessionToken: string): Promise<SessionValidationResult> {\n logger.info(\"🔐 Validating session...\");\n\n try {\n const response = await fetch(VALIDATION_URL, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify({ sessionToken }),\n });\n\n const data = await response.json() as Record<string, unknown>;\n\n if (response.ok && data.valid === true) {\n logger.info(`✅ Session valid for ${data.email}`);\n return {\n valid: true,\n projectId: data.projectId as string,\n llmopsApiKey: data.llmopsApiKey as string,\n userId: data.userId as string,\n email: data.email as string,\n };\n }\n\n const errorMessage = (data.error as string) || \"Unknown error\";\n logger.error(`❌ Session validation failed: ${errorMessage}`);\n throw new Error(`Session validation failed: ${errorMessage}`);\n } catch (error) {\n if (error instanceof Error && error.message.startsWith(\"Session validation failed:\")) {\n throw error;\n }\n\n logger.error(\"❌ Failed to validate session:\", error instanceof Error ? error.message : String(error));\n\n if (error instanceof Error) {\n if (error.message.includes(\"fetch failed\") || error.message.includes(\"ECONNREFUSED\")) {\n throw new Error(\"Network error: Could not reach validation service\");\n } else if (error.message.includes(\"timeout\")) {\n throw new Error(\"Request timeout: Validation service did not respond in time\");\n }\n }\n\n throw new Error(`Session validation failed: ${error instanceof Error ? error.message : String(error)}`);\n }\n}\n","/**\n * Frida AI Client\n * Optional client for Frida AI integration\n */\n\nimport \"dotenv/config\";\nimport { logger } from \"../../utils/logger.js\";\n\n/**\n * `POST /v1/responses` non-stream body: `object: \"response\"`, `output` = items such as\n * `{ type: \"message\", content: [{ type: \"output_text\", text: \"...\" }] }`.\n */\nfunction extractFromResponsesApiOutput(data: Record<string, unknown>): { answer: string; parseSource: string } | null {\n const output = data.output;\n if (!Array.isArray(output)) {\n return null;\n }\n\n const textParts: string[] = [];\n for (const item of output) {\n if (!item || typeof item !== \"object\") {\n continue;\n }\n const o = item as Record<string, unknown>;\n if (o.type !== \"message\") {\n continue;\n }\n const content = o.content;\n if (!Array.isArray(content)) {\n continue;\n }\n for (const block of content) {\n if (!block || typeof block !== \"object\") {\n continue;\n }\n const b = block as Record<string, unknown>;\n if (b.type === \"output_text\" && typeof b.text === \"string\" && b.text.length > 0) {\n textParts.push(b.text);\n }\n }\n }\n\n const joined = textParts.join(\"\\n\").trim();\n if (!joined) {\n return null;\n }\n\n const parseSource =\n data.object === \"response\"\n ? \"response.output[].message.output_text\"\n : \"output[].message.output_text\";\n return { answer: joined, parseSource };\n}\n\n/** Parses Frida /responses JSON and records which top-level shape was used. */\nfunction parseFridaAnswer(data: Record<string, unknown>): { answer: string; parseSource: string } {\n if (typeof data.response === \"string\" && data.response) {\n return { answer: data.response, parseSource: \"response\" };\n }\n\n const structured = extractFromResponsesApiOutput(data);\n if (structured) {\n return structured;\n }\n\n if (typeof data.output === \"string\" && data.output) {\n return { answer: data.output, parseSource: \"output\" };\n }\n\n const choices = data.choices as Array<{ message?: { content?: unknown } }> | undefined;\n const msg = choices?.[0]?.message;\n if (msg && typeof msg.content === \"string\" && msg.content) {\n return { answer: msg.content, parseSource: \"choices[0].message.content\" };\n }\n\n if (typeof data.content === \"string\" && data.content) {\n return { answer: data.content, parseSource: \"content\" };\n }\n\n return { answer: JSON.stringify(data), parseSource: \"fallback_json\" };\n}\n\nexport interface FridaClientOptions {\n apiKey?: string;\n apiUrl?: string;\n model?: string;\n maxTokens?: number;\n}\n\nexport interface FridaResponse {\n success: boolean;\n error: string | null;\n response: string | null;\n metadata?: {\n model: string;\n tokensUsed: number | null;\n };\n}\n\nexport class FridaClient {\n private apiKey: string | undefined;\n private apiUrl: string | undefined;\n private model: string;\n private maxTokens: number;\n private enabled: boolean;\n\n constructor(options: FridaClientOptions = {}) {\n this.apiKey = options.apiKey || process.env.FRIDA_BEARER_TOKEN;\n this.apiUrl = options.apiUrl || process.env.FRIDA_API_URL;\n this.model = options.model || process.env.FRIDA_MODEL || \"gpt-5.1-codex\";\n this.maxTokens = options.maxTokens || (process.env.FRIDA_MAX_TOKENS ? parseInt(process.env.FRIDA_MAX_TOKENS, 10) : 4096);\n this.enabled = !!(this.apiKey && this.apiUrl);\n }\n\n /**\n * Checks if Frida is configured\n */\n isEnabled(): boolean {\n return this.enabled;\n }\n\n /**\n * Generates the unified prompt for component recommendation\n * Optimized for Approach B: lightweight context for selection, technical docs handled separately\n */\n buildPrompt(question: string, context: string): string {\n return `You are an expert design system specialist.\nYour goal is to analyze the Figma design context and recommend the mostly suitable component(s) from the design system.\n\n**CONTEXT:**\nThe user has a Figma design element and needs to know which component from the library to use.\nBelow is a list of available components with their visual descriptions and overviews.\n\n**AVAILABLE COMPONENTS:**\n${context}\n\n**INSTRUCTIONS:**\n1. Analyze the user's design description (Question).\n2. Compare it against the **Visual** and **Overview** of the available components.\n3. Select the best matching component(s).\n4. Provide a brief reasoning for your selection.\n\n**RESPONSE FORMAT:**\nYour response must be concise and follow this format:\n\n🎯 **Recommended Component:** [Tag]\n**Confidence:** [High/Medium/Low]\n**Reasoning:** [1-2 sentences explaining why this visual/functional description matches the design]\n\nUSER QUESTION:\n${question}`;\n }\n\n /**\n * Generates a prompt specifically for filtering components by tags only\n * Returns only component tags that match the query description\n */\n buildFilterPrompt(query: string, context: string): string {\n return `You are a design system expert. Analyze the query and component list below.\n\n**QUERY:** ${query}\n\n**AVAILABLE COMPONENTS:**\n${context}\n\n**TASK:** \nAnalyze the query description and compare it against the component overviews and scores.\nReturn ONLY the component tags (comma-separated) that best match the query description.\n\n**RESPONSE FORMAT:**\nReturn only the tags separated by commas. Do not include explanations, reasoning, or any other text.\nExample format: tag1, tag2, tag3\n\n**IMPORTANT:** Only return tags that are in the available components list above.`;\n }\n\n /**\n * Asks a question to Frida AI\n * @param question - User question\n * @param context - Context with component information\n * @returns Frida response\n */\n async ask(question: string, context: string): Promise<FridaResponse> {\n if (!this.enabled) {\n return {\n success: false,\n error:\n \"Frida AI is not configured. Set FRIDA_BEARER_TOKEN and FRIDA_API_URL in .env\",\n response: null,\n };\n }\n\n if (!question || typeof question !== \"string\") {\n return {\n success: false,\n error: \"Question must be a non-empty string\",\n response: null,\n };\n }\n\n logger.debug(\"CALLING FRIDA AI\");\n\n const prompt = this.buildPrompt(question, context);\n\n logger.debug(`API URL: ${this.apiUrl}`);\n logger.debug(`Model: ${this.model}`);\n logger.debug(`Question length: ${question.length} chars`);\n logger.debug(`Context length: ${context.length} chars`);\n logger.debug(`Max tokens: ${this.maxTokens}`);\n\n try {\n const startTime = Date.now();\n const response = await fetch(this.apiUrl!, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${this.apiKey}`,\n },\n body: JSON.stringify({\n model: this.model,\n input: prompt,\n max_tokens: this.maxTokens,\n stream: false,\n email: process.env.MCP_USER_EMAIL || \"figma2frida_mcp@fridaplatform.com\",\n }),\n });\n const fetchTime = Date.now() - startTime;\n logger.debug(`API request completed in ${fetchTime}ms - Status: ${response.status}`);\n\n if (!response.ok) {\n logger.error(`API Error: ${response.status} ${response.statusText}`);\n throw new Error(`API Error: ${response.status} ${response.statusText}`);\n }\n\n const data = (await response.json()) as Record<string, unknown>;\n const { answer, parseSource } = parseFridaAnswer(data);\n\n const tokensUsed = ((data.usage as { total_tokens?: number })?.total_tokens as number | null) || null;\n const answerPreview = answer.replace(/\\s+/g, \" \").slice(0, 200);\n logger.debug(\n `Frida answer preview (ask): \"${answerPreview}\" (from \"${parseSource}\")`,\n );\n\n logger.debug(\n `Frida response OK (ask): HTTP ${response.status} in ${fetchTime}ms — parsed from \"${parseSource}\", ${answer.length} chars, tokens=${tokensUsed ?? \"n/a\"}`,\n );\n\n return {\n success: true,\n error: null,\n response: answer,\n metadata: {\n model: this.model,\n tokensUsed,\n },\n };\n } catch (error) {\n logger.error(\"Error calling Frida AI:\", error);\n return {\n success: false,\n error: error instanceof Error ? error.message : String(error),\n response: null,\n };\n }\n }\n\n /**\n * Asks Frida AI to filter components and return only matching tags\n * Uses buildFilterPrompt instead of buildPrompt for tag-only responses\n * @param query - Search query description\n * @param context - Lightweight component context (tag, score, overview)\n * @returns Frida response with component tags\n */\n async askForFilter(query: string, context: string): Promise<FridaResponse> {\n if (!this.enabled) {\n return {\n success: false,\n error:\n \"Frida AI is not configured. Set FRIDA_BEARER_TOKEN and FRIDA_API_URL in .env\",\n response: null,\n };\n }\n\n if (!query || typeof query !== \"string\") {\n return {\n success: false,\n error: \"Query must be a non-empty string\",\n response: null,\n };\n }\n\n logger.debug(\"CALLING FRIDA AI FOR FILTERING\");\n\n // Use buildFilterPrompt instead of buildPrompt\n const prompt = this.buildFilterPrompt(query, context);\n\n logger.debug(`API URL: ${this.apiUrl}`);\n logger.debug(`Model: ${this.model}`);\n logger.debug(`Query length: ${query.length} chars`);\n logger.debug(`Context length: ${context.length} chars`);\n logger.debug(`Max tokens: ${this.maxTokens}`);\n\n try {\n const startTime = Date.now();\n const response = await fetch(this.apiUrl!, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${this.apiKey}`,\n },\n body: JSON.stringify({\n model: this.model,\n input: prompt,\n max_tokens: this.maxTokens,\n stream: false,\n email: process.env.MCP_USER_EMAIL || \"figma2frida_mcp@fridaplatform.com\",\n }),\n });\n const fetchTime = Date.now() - startTime;\n logger.debug(`API request completed in ${fetchTime}ms - Status: ${response.status}`);\n\n if (!response.ok) {\n logger.error(`API Error: ${response.status} ${response.statusText}`);\n throw new Error(`API Error: ${response.status} ${response.statusText}`);\n }\n\n const data = (await response.json()) as Record<string, unknown>;\n const { answer, parseSource } = parseFridaAnswer(data);\n\n const tokensUsed = ((data.usage as { total_tokens?: number })?.total_tokens as number | null) || null;\n const answerPreview = answer.replace(/\\s+/g, \" \").slice(0, 200);\n logger.debug(\n `Frida answer preview (filter): \"${answerPreview}\" (from \"${parseSource}\")`,\n );\n\n logger.debug(\n `Frida response OK (filter): HTTP ${response.status} in ${fetchTime}ms — parsed from \"${parseSource}\", ${answer.length} chars, tokens=${tokensUsed ?? \"n/a\"}`,\n );\n\n return {\n success: true,\n error: null,\n response: answer,\n metadata: {\n model: this.model,\n tokensUsed,\n },\n };\n } catch (error) {\n logger.error(\"Error calling Frida AI for filtering:\", error);\n return {\n success: false,\n error: error instanceof Error ? error.message : String(error),\n response: null,\n };\n }\n }\n}\n","/**\n * Library Filter Handler\n * Handles Frida AI filtering of component search results from Pinecone\n */\n\nimport type { ComponentMatch, SearchResults } from \"../services/pinecone/pinecone-service.js\";\nimport { FridaClient } from \"../services/frida/frida-client.js\";\nimport { Formatters } from \"../utils/formatters.js\";\nimport { logger } from \"../utils/logger.js\";\n\n/**\n * Parses component tags from Frida's response\n * Handles various formats: comma-separated, newline-separated, or list format\n */\nfunction parseTagsFromFridaResponse(response: string, availableTags: string[]): string[] {\n if (!response || typeof response !== \"string\") {\n return [];\n }\n\n // Normalize the response: remove markdown formatting, extra whitespace\n let normalized = response.trim();\n \n // Remove common markdown formatting\n normalized = normalized.replace(/\\*\\*/g, \"\"); // Remove bold\n normalized = normalized.replace(/#+/g, \"\"); // Remove headers\n normalized = normalized.replace(/```[\\s\\S]*?```/g, \"\"); // Remove code blocks\n \n // Try to extract tags from various formats\n // Format 1: Comma-separated (tag1, tag2, tag3)\n let tags: string[] = [];\n \n // Split by comma first\n const commaSplit = normalized.split(\",\").map(t => t.trim());\n \n // Also try splitting by newline\n const newlineSplit = normalized.split(/\\n+/).map(t => t.trim());\n \n // Combine both approaches and filter\n const allCandidates = [...commaSplit, ...newlineSplit]\n .map(tag => {\n // Remove common prefixes/suffixes\n tag = tag.replace(/^[-•*]\\s*/, \"\"); // Remove list markers\n tag = tag.replace(/^tag:\\s*/i, \"\"); // Remove \"tag:\" prefix\n tag = tag.replace(/^tags?:\\s*/i, \"\"); // Remove \"tags:\" prefix\n tag = tag.replace(/[.,;]$/, \"\"); // Remove trailing punctuation\n return tag.trim();\n })\n .filter(tag => tag.length > 0);\n\n // Match against available tags (case-insensitive)\n for (const candidate of allCandidates) {\n const candidateLower = candidate.toLowerCase();\n // Find exact match or partial match\n const matchedTag = availableTags.find(t => \n t.toLowerCase() === candidateLower || \n t.toLowerCase().includes(candidateLower) ||\n candidateLower.includes(t.toLowerCase())\n );\n \n if (matchedTag && !tags.includes(matchedTag)) {\n tags.push(matchedTag);\n }\n }\n\n logger.debug(`Parsed ${tags.length} tags from Frida response: ${tags.join(\", \")}`);\n return tags;\n}\n\nexport interface FilterComponentsOptions {\n query: string;\n searchResults: SearchResults;\n}\n\nexport interface FilterComponentsResult {\n filteredResults: SearchResults;\n wasFiltered: boolean;\n fridaResponseTime?: number;\n}\n\n/**\n * Filters component search results using Frida AI\n * If Frida is enabled, it will analyze the query and component overviews\n * to return only the most relevant component tags\n */\nexport async function filterComponentsWithFrida(\n options: FilterComponentsOptions\n): Promise<FilterComponentsResult> {\n const { query, searchResults } = options;\n\n // If no results, return early\n if (!searchResults.matches || searchResults.matches.length === 0) {\n return {\n filteredResults: searchResults,\n wasFiltered: false,\n };\n }\n\n // Create FridaClient instance for filtering\n const fridaClient = new FridaClient();\n \n let filteredMatches: ComponentMatch[] = searchResults.matches;\n let wasFiltered = false;\n let fridaResponseTime: number | undefined;\n \n // If Frida is enabled, use it to filter components\n if (fridaClient.isEnabled()) {\n try {\n logger.debug(\"Using Frida AI to filter components...\");\n \n // Create lightweight context with only (tag, score, overview)\n const lightweightContext = Formatters.matchesToLightweightContext(searchResults.matches);\n \n // Call Frida with askForFilter method (uses buildFilterPrompt internally)\n const fridaStartTime = Date.now();\n const fridaResponse = await fridaClient.askForFilter(query, lightweightContext);\n fridaResponseTime = Date.now() - fridaStartTime;\n \n logger.debug(`Frida AI filtering completed in ${fridaResponseTime}ms - Success: ${fridaResponse.success}`);\n \n if (fridaResponse.success && fridaResponse.response) {\n // Parse tags from Frida response\n const availableTags = searchResults.matches.map(m => m.tag);\n const selectedTags = parseTagsFromFridaResponse(fridaResponse.response, availableTags);\n \n if (selectedTags.length > 0) {\n // Filter matches to only include selected tags\n filteredMatches = searchResults.matches.filter(match => \n selectedTags.includes(match.tag)\n );\n \n wasFiltered = true;\n logger.debug(`Frida filtered ${filteredMatches.length} components from ${searchResults.matches.length} total matches`);\n } else {\n logger.warn(\"Frida returned no valid tags, using all Pinecone results\");\n }\n } else {\n logger.warn(`Frida filtering failed: ${fridaResponse.error || \"Unknown error\"}, using all Pinecone results`);\n }\n } catch (fridaError) {\n logger.warn(`Frida filtering error: ${fridaError instanceof Error ? fridaError.message : String(fridaError)}, using all Pinecone results`);\n // Continue with all results if Frida fails\n }\n } else {\n logger.debug(\"Frida AI not configured, skipping filtering step\");\n }\n\n // Create filtered search results\n const filteredSearchResults: SearchResults = {\n ...searchResults,\n matches: filteredMatches,\n relevantMatches: filteredMatches.length,\n };\n\n return {\n filteredResults: filteredSearchResults,\n wasFiltered,\n fridaResponseTime,\n };\n}\n"],"mappings":";;;AAcA,SAAS,SAAS;AAClB,OAAO,WAAW;AAClB,SAAS,eAAe;AACxB,SAAS,eAAiD;AAC1D,SAAS,qBAAqB;AAC9B,SAAS,qBAAqB;AAC9B,SAAS,SAAS,YAAY;;;ACC9B,SAAS,cAAwB;AAC/B,QAAM,YAAY,QAAQ,KAAK,SAAS,WAAW,KAAK,QAAQ,IAAI,UAAU;AAC9E,QAAM,eAAe,QAAQ,IAAI,aAAa;AAE9C,MAAI,gBAAgB,CAAC,WAAW;AAC9B,WAAO;AAAA,EACT;AAGA,SAAO;AACT;AAIA,IAAM,cAAc,QAAQ,IAAI,gBAAgB,UAAU,QAAQ,IAAI,gBAAgB;AAGtF,IAAM,aAAa,CAAC,OAAe,YAAoB,SAAgB;AACrE,QAAM,cAAc,KAAK,SAAS,IAC9B,IAAI,KAAK,KAAK,OAAO,IAAI,KAAK,IAAI,SAAO,OAAO,QAAQ,WAAW,KAAK,UAAU,GAAG,IAAI,OAAO,GAAG,CAAC,EAAE,KAAK,GAAG,CAAC,KAC/G,IAAI,KAAK,KAAK,OAAO;AAEzB,MAAI,aAAa;AACf,YAAQ,OAAO,MAAM,GAAG,WAAW;AAAA,CAAI;AAAA,EACzC,OAAO;AACL,YAAQ,IAAI,WAAW;AAAA,EACzB;AACF;AAEO,IAAM,SAAS;AAAA,EACpB,OAAO,CAAC,YAAoB,SAAgB;AAC1C,QAAI,YAAY,KAAK,eAAgB;AACnC,iBAAW,SAAS,SAAS,GAAG,IAAI;AAAA,IACtC;AAAA,EACF;AAAA,EACA,MAAM,CAAC,YAAoB,SAAgB;AACzC,QAAI,YAAY,KAAK,cAAe;AAClC,iBAAW,QAAQ,SAAS,GAAG,IAAI;AAAA,IACrC;AAAA,EACF;AAAA,EACA,MAAM,CAAC,YAAoB,SAAgB;AACzC,QAAI,YAAY,KAAK,cAAe;AAClC,iBAAW,QAAQ,SAAS,GAAG,IAAI;AAAA,IACrC;AAAA,EACF;AAAA,EACA,OAAO,CAAC,YAAoB,SAAgB;AAC1C,QAAI,YAAY,KAAK,eAAgB;AACnC,iBAAW,SAAS,SAAS,GAAG,IAAI;AAAA,IACtC;AAAA,EACF;AACF;;;AClEA,SAAS,cAAc;AACvB,SAAS,0BAA0B;AA+B5B,IAAM,cAAN,MAAkB;AAAA,EACf,SAAwB;AAAA,EACxB,YAAqB;AAAA,EACrB;AAAA,EAER,YAAY,WAAmB,6BAA6B;AAC1D,SAAK,WAAW;AAAA,EAClB;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,QAAQ,UAAkB,GAAkB;AAChD,QAAI,KAAK,aAAa,KAAK,QAAQ;AACjC,aAAO,MAAM,gDAAgD;AAC7D;AAAA,IACF;AAEA,WAAO,MAAM,6BAA6B;AAC1C,WAAO,MAAM,QAAQ,KAAK,QAAQ,EAAE;AACpC,WAAO,MAAM,gBAAgB,OAAO,EAAE;AACtC,WAAO,MAAM,6BAA6B,KAAK,SAAS,YAAY,CAAC,CAAC,KAAK,MAAM,EAAE;AAEnF,aAAS,UAAU,GAAG,UAAU,SAAS,WAAW;AAClD,YAAM,mBAAmB,KAAK,IAAI;AAClC,aAAO,MAAM,WAAW,UAAU,CAAC,IAAI,OAAO,cAAc;AAE5D,UAAI;AACF,eAAO,MAAM,+BAA+B;AAC5C,aAAK,SAAS,IAAI;AAAA,UAChB;AAAA,YACE,MAAM;AAAA,YACN,SAAS;AAAA,UACX;AAAA,UACA;AAAA,YACE,cAAc;AAAA,cACZ,OAAO,CAAC;AAAA,YACV;AAAA,UACF;AAAA,QACF;AACA,eAAO,MAAM,uBAAuB;AAEpC,eAAO,MAAM,+BAA+B,KAAK,QAAQ,EAAE;AAC3D,cAAM,YAAY,IAAI,mBAAmB,IAAI,IAAI,KAAK,QAAQ,CAAC;AAC/D,eAAO,MAAM,0BAA0B;AAEvC,eAAO,MAAM,0BAA0B;AACvC,cAAM,mBAAmB,KAAK,IAAI;AAClC,cAAM,KAAK,OAAO,QAAQ,SAAS;AACnC,cAAM,cAAc,KAAK,IAAI,IAAI;AACjC,eAAO,MAAM,6BAA6B,WAAW,IAAI;AAEzD,aAAK,YAAY;AACjB,cAAM,YAAY,KAAK,IAAI,IAAI;AAE/B,eAAO,MAAM,2BAA2B,SAAS,KAAK;AACtD;AAAA,MACF,SAAS,OAAO;AACd,cAAM,cAAc,KAAK,IAAI,IAAI;AACjC,eAAO,MAAM,sBAAsB,UAAU,CAAC,IAAI,OAAO,YAAY,WAAW,KAAK;AACrF,eAAO,MAAM,eAAe,OAAO,aAAa,QAAQ,OAAO,KAAK,EAAE;AACtE,eAAO,MAAM,kBAAkB,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC,EAAE;AAGvF,YAAI,SAAS,OAAO,UAAU,UAAU;AACtC,gBAAM,WAAW;AACjB,cAAI,UAAU,UAAU;AACtB,mBAAO,MAAM,eAAe,SAAS,IAAI,EAAE;AAAA,UAC7C;AACA,cAAI,WAAW,UAAU;AACvB,mBAAO,MAAM,gBAAgB,SAAS,KAAK;AAAA,UAC7C;AACA,cAAI,YAAY,UAAU;AACxB,mBAAO,MAAM,gBAAgB,SAAS,MAAM,EAAE;AAAA,UAChD;AACA,cAAI,gBAAgB,UAAU;AAC5B,mBAAO,MAAM,qBAAqB,SAAS,UAAU,EAAE;AAAA,UACzD;AAAA,QACF;AAEA,YAAI,iBAAiB,SAAS,MAAM,OAAO;AACzC,iBAAO,MAAM,gBAAgB,MAAM,KAAK;AAAA,QAC1C;AAEA,YAAI,YAAY,UAAU,GAAG;AAC3B,iBAAO,MAAM,mCAAmC,OAAO,YAAY;AACnE,iBAAO,MAAM,QAAQ,KAAK,QAAQ,EAAE;AACpC,gBAAM,IAAI;AAAA,YACR,qCAAqC,KAAK,QAAQ,UAAU,OAAO;AAAA,UACrE;AAAA,QACF;AAEA,cAAM,WAAW,OAAQ,UAAU;AACnC,eAAO,MAAM,WAAW,QAAQ,oBAAoB;AAEpD,cAAM,IAAI;AAAA,UAAQ,CAAC,YACjB,WAAW,SAAS,QAAQ;AAAA,QAC9B;AACA,eAAO,MAAM,4BAA4B;AAAA,MAC3C;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,kBAAiC;AAC7C,QAAI,CAAC,KAAK,aAAa,CAAC,KAAK,QAAQ;AACnC,aAAO,MAAM,oEAAoE;AACjF,YAAM,KAAK,QAAQ;AAAA,IACrB,OAAO;AACL,aAAO,MAAM,wDAAwD;AAAA,IACvE;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKQ,gBAAgB,QAAqC;AAC3D,QAAI,CAAC,OAAQ,QAAO;AAEpB,WAAO,OAAO,QAAQ,MAAM,GAAG;AAAA,EACjC;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,mBAC+B;AACnC,UAAM,KAAK,gBAAgB;AAG3B,UAAM,OAAO;AAAA;AAAA,MAEX,iBAAiB;AAAA,MACjB,kBAAkB;AAAA,MAClB,WAAW;AAAA,IACb;AAEA,WAAO,MAAM,yCAAyC,IAAI;AAE1D,QAAI;AACF,YAAM,SAAS,MAAM,KAAK,OAAQ,SAAS;AAAA,QACzC,MAAM;AAAA,QACN,WAAW;AAAA,MACb,CAAC;AAID,YAAM,eAAe;AACrB,UAAI,aAAa,WAAW,MAAM,QAAQ,aAAa,OAAO,GAAG;AAC/D,cAAM,kBAAkB;AAAA,UACtB,aAAa,QAAQ,CAAC;AAAA;AAAA,UACtB,aAAa,QAAQ,CAAC;AAAA;AAAA,UACtB,aAAa,QAAQ,CAAC;AAAA;AAAA,QACxB,EAAE,OAAO,CAAC,SAAS,SAAS,MAAS;AAErC,eAAO;AAAA,UACL,SAAS;AAAA,QACX;AAAA,MACF;AAEA,aAAO;AAAA,IACT,SAAS,OAAO;AAEd,aAAO,KAAK,2DAA2D;AACvE,WAAK,YAAY;AACjB,YAAM,KAAK,QAAQ;AAEnB,YAAM,SAAS,MAAM,KAAK,OAAQ,SAAS;AAAA,QACzC,MAAM;AAAA,QACN,WAAW;AAAA,MACb,CAAC;AAED,aAAO;AAAA,IACT;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,cAC0B;AAC9B,UAAM,KAAK,gBAAgB;AAE3B,UAAM,OAAO;AAAA;AAAA,MAEX,iBAAiB;AAAA,MACjB,kBAAkB;AAAA,MAClB,WAAW;AAAA,IACb;AAEA,WAAO,MAAM,mCAAmC,IAAI;AAEpD,QAAI;AACF,YAAM,SAAS,MAAM,KAAK,OAAQ,SAAS;AAAA,QACzC,MAAM;AAAA,QACN,WAAW;AAAA,MACb,CAAC;AAID,YAAM,eAAe;AACrB,UAAI,aAAa,WAAW,MAAM,QAAQ,aAAa,OAAO,GAAG;AAC/D,cAAM,kBAAkB;AAAA,UACtB,aAAa,QAAQ,CAAC;AAAA;AAAA,QACxB,EAAE,OAAO,CAAC,SAAS,SAAS,MAAS;AAErC,eAAO;AAAA,UACL,SAAS;AAAA,QACX;AAAA,MACF;AAEA,aAAO;AAAA,IACT,SAAS,OAAO;AAEd,aAAO,KAAK,qDAAqD;AACjE,WAAK,YAAY;AACjB,YAAM,KAAK,QAAQ;AAEnB,YAAM,SAAS,MAAM,KAAK,OAAQ,SAAS;AAAA,QACzC,MAAM;AAAA,QACN,WAAW;AAAA,MACb,CAAC;AAED,aAAO;AAAA,IACT;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,gBAC4B;AAChC,UAAM,KAAK,gBAAgB;AAI3B,QAAI;AACF,YAAM,SAAS,MAAM,KAAK,OAAQ,SAAS;AAAA,QACzC,MAAM;AAAA,QACN,WAAW;AAAA;AAAA,QAEX;AAAA,MACF,CAAC;AAED,aAAO;AAAA,IACT,SAAS,OAAO;AAEd,aAAO,KAAK,uDAAuD;AACnE,WAAK,YAAY;AACjB,YAAM,KAAK,QAAQ;AAEnB,YAAM,SAAS,MAAM,KAAK,OAAQ,SAAS;AAAA,QACzC,MAAM;AAAA,QACN,WAAW;AAAA;AAAA,QAEX;AAAA,MACF,CAAC;AAED,aAAO;AAAA,IACT;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,aAA4B;AAChC,QAAI,KAAK,QAAQ;AACf,YAAM,KAAK,OAAO,MAAM;AACxB,WAAK,YAAY;AACjB,WAAK,SAAS;AACd,aAAO,MAAM,6BAA6B;AAAA,IAC5C;AAAA,EACF;AACF;;;AClTO,IAAM,2BAAN,MAA+B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASpC,aAAa,cAAgC;AAC3C,QAAI,CAAC,aAAc,QAAO,CAAC;AAE3B,UAAM,QAAkB,CAAC;AACzB,UAAM,OAAO,oBAAI,IAAY;AAC7B,UAAM,UAAU,aAAa,SAAS,8BAA8B;AAEpE,eAAW,SAAS,SAAS;AAC3B,YAAM,MAAM,MAAM,CAAC;AACnB,YAAM,OAAO,OAAO,QAAQ,WAAW,IAAI,KAAK,IAAI;AAGpD,UAAI,QAAQ,CAAC,KAAK,IAAI,IAAI,GAAG;AAC3B,aAAK,IAAI,IAAI;AACb,cAAM,KAAK,IAAI;AAAA,MACjB;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AACF;;;AC9BO,IAAM,yBAAN,MAA6B;AAAA;AAAA;AAAA;AAAA,EAIlC,yBAAyB,MAAc,QAAgB,YAAuC;AAE5F,SAAK,gBAAgB,MAAM,UAAU;AAGrC,SAAK,kBAAkB,QAAQ,UAAU;AAAA,EAC3C;AAAA;AAAA;AAAA;AAAA,EAKQ,gBAAgB,MAAc,YAAuC;AAE3E,UAAM,kBAAkB,KAAK,SAAS,8BAA8B;AACpE,UAAM,YAAsB,CAAC;AAE7B,eAAW,SAAS,iBAAiB;AACnC,YAAM,OAAO,MAAM,CAAC,EAAE,KAAK;AAC3B,UAAI,QAAQ,KAAK,SAAS,GAAG;AAC3B,kBAAU,KAAK,KAAK,YAAY,CAAC;AAAA,MACnC;AAAA,IACF;AAGA,UAAM,kBAAkB,UAAU,CAAC,KAAK;AAGxC,SAAK,iBAAiB,WAAW,UAAU;AAG3C,SAAK,mBAAmB,MAAM,WAAW,UAAU;AAGnD,SAAK,iBAAiB,MAAM,iBAAiB,UAAU;AAGvD,SAAK,oBAAoB,MAAM,WAAW,UAAU;AAGpD,SAAK,sBAAsB,MAAM,UAAU;AAG3C,SAAK,mBAAmB,MAAM,UAAU;AAGxC,SAAK,0BAA0B,MAAM,UAAU;AAG/C,SAAK,sBAAsB,MAAM,UAAU;AAG3C,SAAK,wBAAwB,MAAM,UAAU;AAG7C,SAAK,gBAAgB,MAAM,WAAW,UAAU;AAAA,EAClD;AAAA;AAAA;AAAA;AAAA;AAAA,EAMQ,iBAAiB,WAAqB,YAAuC;AACnF,UAAM,oBAAoB;AAAA,MACxB;AAAA,MAAU;AAAA,MAAU;AAAA,MAAQ;AAAA,MAAa;AAAA,MAAW;AAAA,MACpD;AAAA,MAAQ;AAAA,MAAW;AAAA,MAAO;AAAA,MAAc;AAAA,MAAW;AAAA,MACnD;AAAA,MAAQ;AAAA,MAAQ;AAAA,MAAO;AAAA,MAAS;AAAA,MAAS;AAAA,MAAS;AAAA,MAAO;AAAA,MACzD;AAAA,IACF;AAEA,eAAW,QAAQ,WAAW;AAC5B,YAAM,YAAY,KAAK,YAAY;AAGnC,iBAAW,WAAW,mBAAmB;AACvC,YAAI,UAAU,SAAS,OAAO,GAAG;AAE/B,cAAI,YAAY,SAAS,YAAY,cAAc;AACjD,gBAAI,CAAC,WAAW,UAAU,SAAS,YAAY,GAAG;AAChD,yBAAW,UAAU,KAAK,YAAY;AAAA,YACxC;AAAA,UACF,WAAW,YAAY,aAAa,YAAY,aAAa,YAAY,aAAa;AACpF,gBAAI,CAAC,WAAW,UAAU,SAAS,WAAW,GAAG;AAC/C,yBAAW,UAAU,KAAK,WAAW;AAAA,YACvC;AAAA,UACF,WAAW,YAAY,aAAa,YAAY,SAAS;AACvD,gBAAI,CAAC,WAAW,UAAU,SAAS,SAAS,GAAG;AAC7C,yBAAW,UAAU,KAAK,SAAS;AAAA,YACrC;AAAA,UACF,WAAW,CAAC,WAAW,UAAU,SAAS,OAAO,GAAG;AAClD,uBAAW,UAAU,KAAK,OAAO;AAAA,UACnC;AACA;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKQ,mBAAmB,MAAc,WAAqB,YAAuC;AACnG,UAAM,UAAU,KAAK,YAAY,IAAI,MAAM,UAAU,KAAK,GAAG;AAG7D,UAAM,kBAAkB,KAAK,SAAS,4EAA4E;AAClH,UAAM,iBAA2B,CAAC;AAClC,eAAW,SAAS,iBAAiB;AACnC,UAAI,MAAM,CAAC,EAAG,gBAAe,KAAK,MAAM,CAAC,EAAE,YAAY,CAAC;AAAA,IAC1D;AACA,UAAM,qBAAqB,eAAe,KAAK,GAAG;AAGlD,UAAM,eAAe,UAAU,MAAM;AAGrC,QAAI,2CAA2C,KAAK,YAAY,GAAG;AACjE,iBAAW,WAAW,IAAI,OAAO;AAAA,IACnC;AAGA,QAAI,WAAW,KAAK,IAAI,KAAK,cAAc,KAAK,YAAY,GAAG;AAE7D,UAAI,yFAAyF,KAAK,IAAI,KAClG,uBAAuB,KAAK,YAAY,GAAG;AAC7C,mBAAW,WAAW,IAAI,aAAa;AAAA,MACzC,OAAO;AACL,mBAAW,WAAW,IAAI,QAAQ;AAAA,MACpC;AAAA,IACF;AAGA,QAAI,UAAU,KAAK,IAAI,KAAK,qDAAqD,KAAK,YAAY,GAAG;AACnG,iBAAW,WAAW,IAAI,OAAO;AAEjC,UAAI,UAAU,KAAK,YAAY,KAAK,qBAAqB,KAAK,IAAI,GAAG;AACnE,mBAAW,SAAS,KAAK,QAAQ;AACjC,mBAAW,UAAU;AAAA,MACvB;AAAA,IACF;AACA,QAAI,aAAa,KAAK,IAAI,KAAK,uBAAuB,KAAK,OAAO,GAAG;AACnE,iBAAW,WAAW,IAAI,UAAU;AAAA,IACtC;AACA,QAAI,WAAW,KAAK,IAAI,KAAK,mCAAmC,KAAK,OAAO,GAAG;AAC7E,iBAAW,WAAW,IAAI,UAAU;AAAA,IACtC;AACA,QAAI,qBAAqB,KAAK,IAAI,KAAK,uBAAuB,KAAK,OAAO,GAAG;AAC3E,iBAAW,WAAW,IAAI,UAAU;AAAA,IACtC;AACA,QAAI,kBAAkB,KAAK,IAAI,KAAK,uBAAuB,KAAK,OAAO,GAAG;AACxE,iBAAW,WAAW,IAAI,OAAO;AAAA,IACnC;AACA,QAAI,iBAAiB,KAAK,OAAO,GAAG;AAClC,iBAAW,WAAW,IAAI,QAAQ;AAAA,IACpC;AACA,QAAI,gBAAgB,KAAK,OAAO,GAAG;AACjC,iBAAW,WAAW,IAAI,QAAQ;AAAA,IACpC;AAGA,QAAI,yDAAyD,KAAK,IAAI,GAAG;AACvE,iBAAW,WAAW,IAAI,QAAQ;AAAA,IACpC;AACA,QAAI,sCAAsC,KAAK,OAAO,GAAG;AACvD,iBAAW,WAAW,IAAI,SAAS;AAAA,IACrC;AACA,QAAI,uCAAuC,KAAK,OAAO,GAAG;AACxD,iBAAW,WAAW,IAAI,YAAY;AAAA,IACxC;AACA,QAAI,qCAAqC,KAAK,OAAO,GAAG;AACtD,iBAAW,WAAW,IAAI,MAAM;AAAA,IAClC;AACA,QAAI,qCAAqC,KAAK,OAAO,GAAG;AACtD,iBAAW,WAAW,IAAI,MAAM;AAAA,IAClC;AACA,QAAI,qCAAqC,KAAK,OAAO,GAAG;AACtD,iBAAW,WAAW,IAAI,YAAY;AAAA,IACxC;AAGA,QAAI,sBAAsB,KAAK,IAAI,KAAK,iCAAiC,KAAK,OAAO,GAAG;AACtF,iBAAW,WAAW,IAAI,OAAO;AAAA,IACnC;AACA,QAAI,mBAAmB,KAAK,OAAO,GAAG;AACpC,iBAAW,WAAW,IAAI,MAAM;AAAA,IAClC;AACA,QAAI,mBAAmB,KAAK,OAAO,GAAG;AACpC,iBAAW,WAAW,IAAI,MAAM;AAAA,IAClC;AACA,QAAI,qBAAqB,KAAK,OAAO,GAAG;AACtC,iBAAW,WAAW,IAAI,MAAM;AAAA,IAClC;AACA,QAAI,wCAAwC,KAAK,OAAO,GAAG;AACzD,iBAAW,WAAW,IAAI,UAAU;AAAA,IACtC;AACA,QAAI,6BAA6B,KAAK,OAAO,GAAG;AAC9C,iBAAW,WAAW,IAAI,OAAO;AAAA,IACnC;AAGA,QAAI,qCAAqC,KAAK,OAAO,GAAG;AACtD,iBAAW,WAAW,IAAI,OAAO;AAAA,IACnC;AACA,QAAI,wBAAwB,KAAK,OAAO,GAAG;AACzC,iBAAW,WAAW,IAAI,OAAO;AAAA,IACnC;AACA,QAAI,uBAAuB,KAAK,OAAO,GAAG;AACxC,iBAAW,WAAW,IAAI,SAAS;AAAA,IACrC;AACA,QAAI,mCAAmC,KAAK,OAAO,GAAG;AACpD,iBAAW,WAAW,IAAI,UAAU;AAAA,IACtC;AACA,QAAI,kBAAkB,KAAK,OAAO,GAAG;AACnC,iBAAW,WAAW,IAAI,OAAO;AAAA,IACnC;AAGA,QAAI,mBAAmB,KAAK,IAAI,KAC3B,0CAA0C,KAAK,OAAO,KAAK,CAAC,qBAAqB,KAAK,IAAI,GAAI;AACjG,iBAAW,WAAW,IAAI,QAAQ;AAAA,IACpC;AACA,QAAI,mBAAmB,KAAK,IAAI,KAC3B,0CAA0C,KAAK,OAAO,KAAK,CAAC,qBAAqB,KAAK,IAAI,GAAI;AACjG,iBAAW,WAAW,IAAI,QAAQ;AAAA,IACpC;AAGA,QAAI,uCAAuC,KAAK,OAAO,GAAG;AACxD,iBAAW,WAAW,IAAI,QAAQ;AAAA,IACpC;AACA,QAAI,wBAAwB,KAAK,OAAO,GAAG;AACzC,iBAAW,WAAW,IAAI,SAAS;AAAA,IACrC;AACA,QAAI,oCAAoC,KAAK,OAAO,GAAG;AACrD,iBAAW,WAAW,IAAI,WAAW;AAAA,IACvC;AACA,QAAI,6BAA6B,KAAK,OAAO,GAAG;AAC9C,iBAAW,WAAW,IAAI,UAAU;AAAA,IACtC;AACA,QAAI,8BAA8B,KAAK,OAAO,GAAG;AAC/C,iBAAW,WAAW,IAAI,mBAAmB;AAAA,IAC/C;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKQ,iBAAiB,MAAc,aAAqB,YAAuC;AACjG,UAAM,gBAAgB,OAAO,MAAM,aAAa,YAAY;AAG5D,QAAI,wBAAwB,KAAK,YAAY,GAAG;AAC9C,iBAAW,UAAU;AAAA,IACvB,WAAW,6BAA6B,KAAK,YAAY,GAAG;AAC1D,iBAAW,UAAU;AAAA,IACvB,WAAW,kBAAkB,KAAK,YAAY,GAAG;AAC/C,iBAAW,UAAU;AAAA,IACvB,WAAW,qBAAqB,KAAK,YAAY,GAAG;AAClD,iBAAW,UAAU;AAAA,IACvB,WAAW,qBAAqB,KAAK,YAAY,GAAG;AAClD,iBAAW,UAAU;AAAA,IACvB,WAAW,wBAAwB,KAAK,YAAY,GAAG;AACrD,iBAAW,UAAU;AAAA,IACvB,WAAW,qCAAqC,KAAK,YAAY,GAAG;AAClE,iBAAW,UAAU;AAAA,IACvB,WAAW,2BAA2B,KAAK,YAAY,GAAG;AACxD,iBAAW,UAAU;AAAA,IACvB,WAAW,8BAA8B,KAAK,YAAY,GAAG;AAC3D,iBAAW,UAAU;AAAA,IACvB,WAAW,yBAAyB,KAAK,YAAY,GAAG;AACtD,iBAAW,UAAU;AAAA,IACvB,WAAW,sBAAsB,KAAK,YAAY,GAAG;AACnD,iBAAW,UAAU;AAAA,IACvB,WAAW,yBAAyB,KAAK,YAAY,GAAG;AACtD,iBAAW,UAAU;AAAA,IACvB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKQ,oBAAoB,MAAc,WAAqB,YAAuC;AACpG,UAAM,UAAU,KAAK,YAAY,IAAI,MAAM,UAAU,KAAK,GAAG;AAG7D,eAAW,YAAY,WAAW;AAChC,YAAM,gBAAgB,SAAS,YAAY;AAC3C,UAAI,QAAQ,KAAK,aAAa,GAAG;AAC/B,YAAI,oBAAoB,KAAK,aAAa,GAAG;AAC3C,qBAAW,OAAO,KAAK,WAAW;AAClC,qBAAW,SAAS,KAAK,WAAW;AAAA,QACtC,WAAW,kBAAkB,KAAK,aAAa,GAAG;AAChD,qBAAW,OAAO,KAAK,aAAa;AACpC,qBAAW,SAAS,KAAK,aAAa;AAAA,QACxC,WAAW,yBAAyB,KAAK,aAAa,GAAG;AACvD,qBAAW,OAAO,KAAK,cAAc;AAAA,QACvC,WAAW,yBAAyB,KAAK,aAAa,GAAG;AACvD,qBAAW,OAAO,KAAK,cAAc;AAAA,QACvC,WAAW,gBAAgB,KAAK,aAAa,GAAG;AAC9C,qBAAW,OAAO,KAAK,YAAY;AAAA,QACrC,WAAW,sBAAsB,KAAK,aAAa,GAAG;AACpD,qBAAW,OAAO,KAAK,YAAY;AAAA,QACrC;AAAA,MACF;AAAA,IACF;AAGA,QAAI,YAAY,KAAK,OAAO,GAAG;AAC7B,UAAI,yBAAyB,KAAK,OAAO,GAAG;AAC1C,mBAAW,OAAO,KAAK,cAAc;AAAA,MACvC;AACA,UAAI,+BAA+B,KAAK,OAAO,GAAG;AAChD,mBAAW,OAAO,KAAK,YAAY;AAAA,MACrC;AACA,UAAI,2BAA2B,KAAK,OAAO,GAAG;AAC5C,mBAAW,OAAO,KAAK,cAAc;AAAA,MACvC;AACA,UAAI,0BAA0B,KAAK,OAAO,GAAG;AAC3C,mBAAW,OAAO,KAAK,YAAY;AAAA,MACrC;AACA,UAAI,4BAA4B,KAAK,OAAO,GAAG;AAC7C,mBAAW,OAAO,KAAK,WAAW;AAAA,MACpC;AACA,UAAI,qBAAqB,KAAK,OAAO,GAAG;AACtC,mBAAW,OAAO,KAAK,aAAa;AAAA,MACtC;AAAA,IACF;AAGA,QAAI,eAAe,KAAK,IAAI,KAAK,yCAAyC,KAAK,OAAO,GAAG;AACvF,iBAAW,OAAO,KAAK,OAAO;AAAA,IAChC;AAGA,QAAI,kDAAkD,KAAK,OAAO,GAAG;AACnE,iBAAW,SAAS,KAAK,aAAa;AAAA,IACxC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKQ,sBAAsB,MAAc,YAAuC;AAEjF,QAAI,qBAAqB,KAAK,IAAI,KAAK,+BAA+B,KAAK,IAAI,GAAG;AAChF,iBAAW,OAAO,KAAK,mBAAmB;AAAA,IAC5C,WAAW,YAAY,KAAK,IAAI,KAAK,+BAA+B,KAAK,IAAI,GAAG;AAC9E,iBAAW,OAAO,KAAK,qBAAqB;AAAA,IAC9C,WAAW,QAAQ,KAAK,IAAI,GAAG;AAC7B,iBAAW,OAAO,KAAK,aAAa;AAAA,IACtC;AAGA,QAAI,uBAAuB,KAAK,IAAI,GAAG;AACrC,iBAAW,OAAO,KAAK,aAAa;AAAA,IACtC;AAGA,QAAI,oBAAoB,KAAK,IAAI,KAAK,gCAAgC,KAAK,IAAI,GAAG;AAChF,iBAAW,OAAO,KAAK,SAAS;AAAA,IAClC;AAEA,QAAI,aAAa,KAAK,IAAI,KAAK,8BAA8B,KAAK,IAAI,GAAG;AACvE,iBAAW,OAAO,KAAK,UAAU;AAAA,IACnC;AAGA,QAAI,oCAAoC,KAAK,IAAI,GAAG;AAClD,iBAAW,OAAO,KAAK,YAAY;AAAA,IACrC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKQ,mBAAmB,MAAc,YAAuC;AAC9E,UAAM,YAAY,KAAK,YAAY;AAGnC,QAAI,WAAW,WAAW,IAAI,OAAO,GAAG;AACtC,UAAI,4BAA4B,KAAK,IAAI,GAAG;AAC1C,mBAAW,aAAa,IAAI,cAAc;AAAA,MAC5C;AACA,UAAI,sBAAsB,KAAK,IAAI,GAAG;AACpC,mBAAW,aAAa,IAAI,aAAa;AAAA,MAC3C;AAAA,IACF;AAGA,QAAI,WAAW,WAAW,IAAI,OAAO,KAAK,WAAW,WAAW,IAAI,QAAQ,GAAG;AAC7E,UAAI,0BAA0B,KAAK,SAAS,GAAG;AAC7C,mBAAW,aAAa,IAAI,iBAAiB;AAAA,MAC/C;AACA,UAAI,sCAAsC,KAAK,SAAS,GAAG;AACzD,mBAAW,aAAa,IAAI,YAAY;AAAA,MAC1C;AAAA,IACF;AAGA,QAAI,WAAW,WAAW,IAAI,MAAM,KAAK,WAAW,WAAW,IAAI,MAAM,GAAG;AAC1E,iBAAW,aAAa,IAAI,YAAY;AAAA,IAC1C;AAGA,QAAI,WAAW,WAAW,IAAI,OAAO,KAAK,WAAW,WAAW,IAAI,MAAM,GAAG;AAC3E,UAAI,sBAAsB,KAAK,SAAS,GAAG;AACzC,mBAAW,aAAa,IAAI,mBAAmB;AAAA,MACjD;AACA,UAAI,yBAAyB,KAAK,SAAS,GAAG;AAC5C,mBAAW,aAAa,IAAI,WAAW;AAAA,MACzC;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKQ,0BAA0B,MAAc,YAAuC;AAErF,UAAM,mBAAmB,KAAK,SAAS,wCAAwC;AAC/E,eAAW,SAAS,kBAAkB;AACpC,YAAM,gBAAgB,MAAM,CAAC,EAAE,YAAY;AAC3C,UAAI,sBAAsB,KAAK,aAAa,GAAG;AAC7C,mBAAW,WAAW,IAAI,OAAO;AAAA,MACnC;AACA,UAAI,UAAU,KAAK,aAAa,GAAG;AACjC,mBAAW,WAAW,IAAI,QAAQ;AAAA,MACpC;AACA,UAAI,gBAAgB,KAAK,aAAa,GAAG;AACvC,mBAAW,WAAW,IAAI,OAAO;AAAA,MACnC;AAAA,IACF;AAGA,QAAI,uBAAuB,KAAK,IAAI,GAAG;AACrC,iBAAW,SAAS,KAAK,OAAO;AAAA,IAClC;AACA,QAAI,+CAA+C,KAAK,IAAI,GAAG;AAC7D,iBAAW,SAAS,KAAK,WAAW;AACpC,iBAAW,OAAO,KAAK,WAAW;AAAA,IACpC;AACA,QAAI,+CAA+C,KAAK,IAAI,GAAG;AAC7D,iBAAW,SAAS,KAAK,QAAQ;AACjC,iBAAW,SAAS,KAAK,aAAa;AAAA,IACxC;AACA,QAAI,qBAAqB,KAAK,IAAI,GAAG;AACnC,iBAAW,SAAS,KAAK,MAAM;AAAA,IACjC;AACA,QAAI,yBAAyB,KAAK,IAAI,GAAG;AACvC,iBAAW,SAAS,KAAK,QAAQ;AACjC,iBAAW,SAAS,KAAK,aAAa;AAAA,IACxC;AACA,QAAI,yBAAyB,KAAK,IAAI,GAAG;AACvC,iBAAW,SAAS,KAAK,QAAQ;AACjC,iBAAW,SAAS,KAAK,aAAa;AAAA,IACxC;AACA,QAAI,eAAe,KAAK,IAAI,GAAG;AAC7B,iBAAW,SAAS,KAAK,aAAa;AAAA,IACxC;AACA,QAAI,aAAa,KAAK,IAAI,GAAG;AAC3B,iBAAW,SAAS,KAAK,cAAc;AAAA,IACzC;AAGA,UAAM,eAAe,KAAK,SAAS,+BAA+B;AAClE,UAAM,SAAmB,CAAC;AAC1B,eAAW,SAAS,cAAc;AAChC,UAAI,MAAM,CAAC,EAAG,QAAO,KAAK,MAAM,CAAC,EAAE,YAAY,CAAC;AAAA,IAClD;AAGA,UAAM,oBAAoB,KAAK,SAAS,sGAAsG;AAC9I,eAAW,SAAS,mBAAmB;AACrC,UAAI,MAAM,CAAC,EAAG,QAAO,KAAK,MAAM,CAAC,EAAE,YAAY,CAAC;AAAA,IAClD;AAGA,eAAW,SAAS,QAAQ;AAC1B,UAAI,UAAU,SAAS;AACrB,mBAAW,OAAO,KAAK,OAAO;AAC9B,mBAAW,OAAO,KAAK,aAAa;AAAA,MACtC,WAAW,UAAU,WAAW;AAC9B,mBAAW,OAAO,KAAK,SAAS;AAChC,mBAAW,OAAO,KAAK,eAAe;AAAA,MACxC,WAAW,UAAU,YAAY;AAC/B,mBAAW,SAAS,KAAK,UAAU;AAAA,MACrC,WAAW,UAAU,WAAW;AAC9B,mBAAW,WAAW,IAAI,UAAU;AAAA,MACtC,WAAW,UAAU,SAAS;AAC5B,mBAAW,SAAS,KAAK,OAAO;AAChC,mBAAW,aAAa,IAAI,OAAO;AAAA,MACrC,WAAW,UAAU,WAAW;AAC9B,mBAAW,SAAS,KAAK,SAAS;AAClC,mBAAW,aAAa,IAAI,OAAO;AAAA,MACrC,WAAW,UAAU,gBAAgB;AACnC,mBAAW,SAAS,KAAK,OAAO;AAChC,mBAAW,SAAS,KAAK,QAAQ;AACjC,mBAAW,aAAa,IAAI,OAAO;AAAA,MACrC,WAAW,UAAU,aAAa;AAChC,mBAAW,SAAS,KAAK,WAAW;AAAA,MACtC;AAAA,IACF;AAGA,UAAM,iBAAiB,KAAK,SAAS,iCAAiC;AACtE,eAAW,SAAS,gBAAgB;AAClC,UAAI,MAAM,CAAC,GAAG;AACZ,cAAM,UAAU,MAAM,CAAC,EAAE,YAAY;AACrC,YAAI,QAAQ,SAAS,aAAa,GAAG;AACnC,qBAAW,SAAS,KAAK,aAAa;AAAA,QACxC;AACA,YAAI,QAAQ,SAAS,QAAQ,GAAG;AAC9B,qBAAW,SAAS,KAAK,QAAQ;AACjC,qBAAW,SAAS,KAAK,aAAa;AAAA,QACxC;AACA,YAAI,QAAQ,SAAS,OAAO,GAAG;AAC7B,qBAAW,SAAS,KAAK,OAAO;AAAA,QAClC;AAAA,MACF;AAAA,IACF;AAEA,QAAI,eAAe,KAAK,IAAI,GAAG;AAC7B,iBAAW,SAAS,KAAK,aAAa;AAAA,IACxC;AACA,QAAI,2BAA2B,KAAK,IAAI,GAAG;AACzC,iBAAW,SAAS,KAAK,QAAQ;AAAA,IACnC;AAGA,QAAI,gDAAgD,KAAK,IAAI,GAAG;AAC9D,iBAAW,SAAS,KAAK,QAAQ;AACjC,iBAAW,UAAU;AAAA,IACvB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKQ,sBAAsB,MAAc,YAAuC;AAEjF,QAAI,mEAAmE,KAAK,IAAI,GAAG;AACjF,YAAM,cAAc,KAAK,SAAS,6CAA6C;AAC/E,iBAAW,SAAS,aAAa;AAC/B,cAAM,OAAO,SAAS,MAAM,CAAC,GAAG,EAAE;AAClC,YAAI,QAAQ,IAAI;AACd,qBAAW,SAAS,KAAK,OAAO;AAAA,QAClC,WAAW,QAAQ,IAAI;AACrB,qBAAW,SAAS,KAAK,QAAQ;AAAA,QACnC,WAAW,QAAQ,IAAI;AACrB,qBAAW,SAAS,KAAK,OAAO;AAAA,QAClC;AAEA,YAAI,SAAS,MAAM,SAAS,MAAM,SAAS,IAAI;AAC7C,qBAAW,SAAS,KAAK,GAAG,IAAI,SAAS;AAAA,QAC3C;AAAA,MACF;AAAA,IACF;AAGA,QAAI,4BAA4B,KAAK,IAAI,GAAG;AAC1C,YAAM,aAAa,KAAK,SAAS,uBAAuB;AACxD,iBAAW,SAAS,YAAY;AAC9B,cAAM,MAAM,SAAS,MAAM,CAAC,GAAG,EAAE;AACjC,YAAI,OAAO,IAAI;AACb,qBAAW,SAAS,KAAK,QAAQ;AACjC,qBAAW,OAAO,KAAK,eAAe;AAAA,QACxC,WAAW,OAAO,GAAG;AACnB,qBAAW,SAAS,KAAK,SAAS;AAAA,QACpC;AAAA,MACF;AAAA,IACF;AAGA,QAAI,8BAA8B,KAAK,IAAI,GAAG;AAC5C,iBAAW,SAAS,KAAK,QAAQ;AAAA,IACnC;AAGA,QAAI,2DAA2D,KAAK,IAAI,GAAG;AACzE,iBAAW,SAAS,KAAK,aAAa;AAAA,IACxC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKQ,wBAAwB,MAAc,YAAuC;AAEnF,QAAI,iDAAiD,KAAK,IAAI,GAAG;AAC/D,iBAAW,SAAS,KAAK,UAAU;AAEnC,UAAI,iCAAiC,KAAK,IAAI,GAAG;AAC/C,mBAAW,SAAS,KAAK,gBAAgB;AAAA,MAC3C;AACA,UAAI,0CAA0C,KAAK,IAAI,GAAG;AACxD,mBAAW,SAAS,KAAK,QAAQ;AAAA,MACnC;AAAA,IACF;AAGA,QAAI,gDAAgD,KAAK,IAAI,GAAG;AAC9D,YAAM,iBAAiB,KAAK,SAAS,8CAA8C;AACnF,iBAAW,SAAS,gBAAgB;AAClC,cAAM,QAAQ,MAAM,CAAC,KAAK,MAAM,CAAC;AACjC,YAAI,UAAU,UAAU,UAAU,MAAM;AACtC,qBAAW,SAAS,KAAK,eAAe;AAAA,QAC1C,OAAO;AACL,qBAAW,SAAS,KAAK,SAAS;AAAA,QACpC;AAAA,MACF;AAAA,IACF;AAGA,QAAI,yDAAyD,KAAK,IAAI,GAAG;AACvE,iBAAW,SAAS,KAAK,YAAY;AACrC,UAAI,+BAA+B,KAAK,IAAI,GAAG;AAC7C,mBAAW,SAAS,KAAK,cAAc;AAAA,MACzC;AACA,UAAI,uCAAuC,KAAK,IAAI,GAAG;AACrD,mBAAW,SAAS,KAAK,kBAAkB;AAAA,MAC7C;AAAA,IACF;AAGA,QAAI,4BAA4B,KAAK,IAAI,GAAG;AAC1C,iBAAW,SAAS,KAAK,WAAW;AAAA,IACtC,WAAW,yBAAyB,KAAK,IAAI,GAAG;AAC9C,iBAAW,SAAS,KAAK,QAAQ;AAAA,IACnC;AAGA,QAAI,iCAAiC,KAAK,IAAI,GAAG;AAC/C,iBAAW,SAAS,KAAK,SAAS;AAAA,IACpC;AAGA,QAAI,gCAAgC,KAAK,IAAI,GAAG;AAC9C,iBAAW,SAAS,KAAK,UAAU;AACnC,iBAAW,OAAO,KAAK,iBAAiB;AAAA,IAC1C;AAGA,QAAI,mBAAmB,KAAK,IAAI,GAAG;AACjC,iBAAW,SAAS,KAAK,WAAW;AACpC,iBAAW,OAAO,KAAK,kBAAkB;AAAA,IAC3C;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKQ,gBAAgB,MAAc,WAAqB,YAAuC;AAChG,UAAM,WAAW,OAAO,MAAM,UAAU,KAAK,GAAG,GAAG,YAAY;AAG/D,QAAI,8BAA8B,KAAK,OAAO,GAAG;AAC/C,iBAAW,SAAS,KAAK,QAAQ;AACjC,iBAAW,SAAS,KAAK,SAAS;AAAA,IACpC;AAGA,QAAI,sDAAsD,KAAK,OAAO,GAAG;AACvE,iBAAW,SAAS,KAAK,aAAa;AACtC,UAAI,oCAAoC,KAAK,OAAO,GAAG;AACrD,mBAAW,SAAS,KAAK,cAAc;AAAA,MACzC;AAAA,IACF;AAGA,QAAI,wBAAwB,KAAK,OAAO,GAAG;AACzC,iBAAW,SAAS,KAAK,QAAQ;AACjC,iBAAW,SAAS,KAAK,aAAa;AAAA,IACxC;AACA,QAAI,4BAA4B,KAAK,OAAO,EAAG,YAAW,SAAS,KAAK,QAAQ;AAChF,QAAI,gCAAgC,KAAK,OAAO,EAAG,YAAW,SAAS,KAAK,SAAS;AAGrF,QAAI,gEAAgE,KAAK,OAAO,GAAG;AACjF,iBAAW,SAAS,KAAK,cAAc;AACvC,iBAAW,SAAS,KAAK,eAAe;AAAA,IAC1C;AAGA,QAAI,gCAAgC,KAAK,OAAO,GAAG;AACjD,UAAI,6BAA6B,KAAK,OAAO,EAAG,YAAW,SAAS,KAAK,aAAa;AAAA,IACxF;AAGA,QAAI,2DAA2D,KAAK,OAAO,KACvE,4BAA4B,KAAK,OAAO,GAAG;AAC7C,iBAAW,SAAS,KAAK,QAAQ;AACjC,iBAAW,SAAS,KAAK,YAAY;AACrC,iBAAW,SAAS,KAAK,SAAS;AAAA,IACpC;AACA,QAAI,4DAA4D,KAAK,OAAO,GAAG;AAC7E,iBAAW,SAAS,KAAK,MAAM;AAAA,IACjC;AACA,QAAI,+BAA+B,KAAK,OAAO,KAAK,cAAc,KAAK,OAAO,GAAG;AAC/E,iBAAW,SAAS,KAAK,SAAS;AAClC,iBAAW,SAAS,KAAK,YAAY;AAAA,IACvC;AAEA,UAAM,UAAU,KAAK,MAAM,cAAc,KAAK,CAAC,GAAG;AAClD,QAAI,UAAU,KAAK,uBAAuB,KAAK,OAAO,GAAG;AACvD,iBAAW,SAAS,KAAK,WAAW;AACpC,iBAAW,SAAS,KAAK,kBAAkB;AAAA,IAC7C;AAGA,QAAI,cAAc,KAAK,IAAI,GAAG;AAC5B,iBAAW,SAAS,KAAK,WAAW;AACpC,iBAAW,SAAS,KAAK,MAAM;AAAA,IACjC;AACA,QAAI,wBAAwB,KAAK,IAAI,GAAG;AACtC,iBAAW,SAAS,KAAK,SAAS;AAClC,iBAAW,SAAS,KAAK,OAAO;AAAA,IAClC;AACA,QAAI,sBAAsB,KAAK,IAAI,EAAG,YAAW,SAAS,KAAK,OAAO;AACtE,QAAI,oBAAoB,KAAK,IAAI,GAAG;AAClC,iBAAW,SAAS,KAAK,MAAM;AAC/B,iBAAW,SAAS,KAAK,OAAO;AAAA,IAClC;AACA,QAAI,4BAA4B,KAAK,IAAI,EAAG,YAAW,SAAS,KAAK,SAAS;AAC9E,QAAI,iBAAiB,KAAK,IAAI,EAAG,YAAW,SAAS,KAAK,OAAO;AAGjE,QAAI,gCAAgC,KAAK,OAAO,EAAG,YAAW,SAAS,KAAK,MAAM;AAClF,QAAI,iCAAiC,KAAK,OAAO,GAAG;AAClD,iBAAW,SAAS,KAAK,OAAO;AAEhC,UAAI,wCAAwC,KAAK,OAAO,GAAG;AACzD,mBAAW,SAAS,KAAK,iBAAiB;AAAA,MAC5C;AAAA,IACF;AACA,QAAI,iCAAiC,KAAK,OAAO,GAAG;AAClD,iBAAW,SAAS,KAAK,OAAO;AAChC,iBAAW,SAAS,KAAK,SAAS;AAAA,IACpC;AACA,QAAI,mCAAmC,KAAK,OAAO,GAAG;AACpD,iBAAW,SAAS,KAAK,SAAS;AAClC,iBAAW,SAAS,KAAK,OAAO;AAAA,IAClC;AACA,QAAI,mDAAmD,KAAK,OAAO,GAAG;AACpE,iBAAW,SAAS,KAAK,WAAW;AACpC,iBAAW,SAAS,KAAK,MAAM;AAAA,IACjC;AACA,QAAI,oCAAoC,KAAK,OAAO,EAAG,YAAW,SAAS,KAAK,UAAU;AAC1F,QAAI,gCAAgC,KAAK,OAAO,EAAG,YAAW,SAAS,KAAK,WAAW;AAGvF,QAAI,6EAA6E,KAAK,OAAO,GAAG;AAC9F,iBAAW,SAAS,KAAK,aAAa;AACtC,iBAAW,SAAS,KAAK,iBAAiB;AAAA,IAC5C;AACA,QAAI,8BAA8B,KAAK,OAAO,GAAG;AAC/C,iBAAW,SAAS,KAAK,QAAQ;AACjC,iBAAW,UAAU;AAAA,IACvB;AACA,QAAI,sGAAsG,KAAK,OAAO,GAAG;AACvH,iBAAW,SAAS,KAAK,cAAc;AACvC,iBAAW,SAAS,KAAK,QAAQ;AAAA,IACnC;AAGA,UAAM,sBAAsB,KAAK,SAAS,yCAAyC;AACnF,eAAW,SAAS,qBAAqB;AACvC,YAAM,eAAe,MAAM,CAAC,EAAE,YAAY;AAC1C,UAAI,kBAAkB,KAAK,YAAY,GAAG;AACxC,mBAAW,SAAS,KAAK,SAAS;AAAA,MACpC;AACA,UAAI,mBAAmB,KAAK,YAAY,GAAG;AACzC,mBAAW,SAAS,KAAK,UAAU;AAAA,MACrC;AACA,UAAI,gBAAgB,KAAK,YAAY,GAAG;AACtC,mBAAW,OAAO,KAAK,OAAO;AAC9B,mBAAW,SAAS,KAAK,aAAa;AAAA,MACxC;AACA,UAAI,kBAAkB,KAAK,YAAY,GAAG;AACxC,mBAAW,OAAO,KAAK,SAAS;AAChC,mBAAW,SAAS,KAAK,eAAe;AAAA,MAC1C;AACA,UAAI,yCAAyC,KAAK,YAAY,GAAG;AAC/D,mBAAW,SAAS,KAAK,QAAQ;AACjC,mBAAW,SAAS,KAAK,aAAa;AAAA,MACxC;AACA,UAAI,wBAAwB,KAAK,YAAY,GAAG;AAC9C,mBAAW,SAAS,KAAK,aAAa;AAAA,MACxC;AACA,UAAI,kBAAkB,KAAK,YAAY,GAAG;AACxC,mBAAW,SAAS,KAAK,OAAO;AAAA,MAClC;AAAA,IACF;AAGA,QAAI,kCAAkC,KAAK,OAAO,GAAG;AACnD,iBAAW,SAAS,KAAK,QAAQ;AACjC,iBAAW,SAAS,KAAK,MAAM;AAAA,IACjC;AAGA,QAAI,sDAAsD,KAAK,IAAI,GAAG;AACpE,iBAAW,OAAO,KAAK,OAAO;AAC9B,iBAAW,SAAS,KAAK,cAAc;AAAA,IACzC;AACA,QAAI,eAAe,KAAK,IAAI,GAAG;AAC7B,iBAAW,SAAS,KAAK,KAAK;AAC9B,iBAAW,SAAS,KAAK,MAAM;AAAA,IACjC;AAGA,QAAI,iDAAiD,KAAK,IAAI,EAAG,YAAW,SAAS,KAAK,YAAY;AACtG,QAAI,oCAAoC,KAAK,IAAI,EAAG,YAAW,SAAS,KAAK,QAAQ;AACrF,QAAI,2CAA2C,KAAK,IAAI,EAAG,YAAW,SAAS,KAAK,SAAS;AAG7F,QAAI,mCAAmC,KAAK,OAAO,EAAG,YAAW,SAAS,KAAK,QAAQ;AAGvF,QAAI,6CAA6C,KAAK,IAAI,GAAG;AAC3D,iBAAW,SAAS,KAAK,aAAa;AACtC,iBAAW,SAAS,KAAK,UAAU;AAAA,IACrC;AAGA,QAAI,iBAAiB,KAAK,IAAI,GAAG;AAC/B,iBAAW,SAAS,KAAK,QAAQ;AAAA,IACnC;AAGA,QAAI,qBAAqB,KAAK,IAAI,GAAG;AACnC,iBAAW,SAAS,KAAK,YAAY;AAAA,IACvC;AAGA,QAAI,gCAAgC,KAAK,IAAI,GAAG;AAC9C,iBAAW,SAAS,KAAK,UAAU;AAAA,IACrC;AAGA,QAAI,+BAA+B,KAAK,IAAI,GAAG;AAC7C,iBAAW,SAAS,KAAK,aAAa;AAAA,IACxC;AAGA,QAAI,iDAAiD,KAAK,IAAI,GAAG;AAC/D,iBAAW,SAAS,KAAK,UAAU;AAAA,IACrC;AAGA,QAAI,YAAY,KAAK,IAAI,GAAG;AAC1B,iBAAW,SAAS,KAAK,OAAO;AAAA,IAClC;AAGA,QAAI,iCAAiC,KAAK,IAAI,GAAG;AAC/C,iBAAW,SAAS,KAAK,eAAe;AACxC,iBAAW,SAAS,KAAK,QAAQ;AAAA,IACnC;AAGA,UAAM,mBAAmB,KAAK,SAAS,8BAA8B;AACrE,eAAW,SAAS,kBAAkB;AACpC,YAAM,YAAY,MAAM,CAAC,EAAE,YAAY;AAEvC,UAAI,aAAa,KAAK,SAAS,GAAG;AAChC,mBAAW,OAAO,KAAK,aAAa;AAAA,MACtC;AACA,UAAI,+BAA+B,KAAK,SAAS,GAAG;AAClD,mBAAW,OAAO,KAAK,UAAU;AAAA,MACnC;AACA,UAAI,QAAQ,KAAK,SAAS,GAAG;AAC3B,mBAAW,SAAS,KAAK,QAAQ;AAAA,MACnC;AACA,UAAI,WAAW,KAAK,SAAS,GAAG;AAC9B,mBAAW,SAAS,KAAK,SAAS;AAAA,MACpC;AACA,UAAI,UAAU,KAAK,SAAS,GAAG;AAC7B,mBAAW,SAAS,KAAK,QAAQ;AAAA,MACnC;AAAA,IACF;AAGA,UAAM,qBAAqB,KAAK,SAAS,uCAAuC;AAChF,eAAW,SAAS,oBAAoB;AACtC,YAAM,WAAW,MAAM,CAAC,EAAE,YAAY;AACtC,YAAM,YAAY,MAAM,CAAC,EAAE,YAAY;AACvC,UAAI,aAAa,WAAW,WAAW;AACrC,YAAI,cAAc,UAAW,YAAW,SAAS,KAAK,SAAS;AAC/D,YAAI,cAAc,WAAY,YAAW,SAAS,KAAK,UAAU;AACjE,YAAI,cAAc,SAAS;AACzB,qBAAW,OAAO,KAAK,OAAO;AAC9B,qBAAW,SAAS,KAAK,aAAa;AAAA,QACxC;AACA,YAAI,cAAc,WAAW;AAC3B,qBAAW,OAAO,KAAK,SAAS;AAChC,qBAAW,SAAS,KAAK,eAAe;AAAA,QAC1C;AAAA,MACF;AACA,UAAI,aAAa,aAAa,WAAW;AACvC,YAAI,UAAU,SAAS,aAAa,EAAG,YAAW,SAAS,KAAK,aAAa;AAC7E,YAAI,UAAU,SAAS,QAAQ,EAAG,YAAW,SAAS,KAAK,QAAQ;AAAA,MACrE;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMQ,kBAAkB,QAAgB,YAAuC;AAC/E,QAAI,CAAC,UAAU,OAAO,KAAK,EAAE,WAAW,EAAG;AAE3C,QAAI,CAAC,WAAW,OAAQ,YAAW,SAAS,CAAC;AAC7C,QAAI,CAAC,WAAW,OAAQ,YAAW,SAAS,CAAC;AAC7C,QAAI,CAAC,WAAW,WAAY,YAAW,aAAa,CAAC;AACrD,QAAI,CAAC,WAAW,QAAS,YAAW,UAAU,CAAC;AAC/C,QAAI,CAAC,WAAW,OAAQ,YAAW,SAAS,CAAC;AAC7C,QAAI,CAAC,WAAW,SAAU,YAAW,WAAW,CAAC;AAGjD,UAAM,eAAe,OAAO,MAAM,GAAG,EAAE,IAAI,OAAK,EAAE,KAAK,CAAC;AAExD,eAAW,SAAS,cAAc;AAGhC,YAAM,QAAQ,MAAM,MAAM,mBAAmB;AAC7C,UAAI,CAAC,MAAO;AAEZ,YAAM,YAAY,MAAM,CAAC,EAAE,KAAK;AAChC,YAAM,aAAa,MAAM,CAAC,EAAE,KAAK;AACjC,YAAM,iBAAiB,UAAU,YAAY;AAG7C,UAAI,eAAe,SAAS,OAAO,KAAK,eAAe,SAAS,YAAY,KACxE,eAAe,SAAS,MAAM,KAAK,eAAe,SAAS,MAAM,KACjE,eAAe,SAAS,QAAQ,KAAK,eAAe,SAAS,QAAQ,GAAG;AAG1E,YAAI,eAAe,SAAS,SAAS,GAAG;AACtC,cAAI,CAAC,WAAW,OAAO,SAAS,SAAS,GAAG;AAC1C,uBAAW,OAAO,KAAK,SAAS;AAAA,UAClC;AACA,cAAI,eAAe,SAAS,YAAY,GAAG;AACzC,uBAAW,OAAO,KAAK,oBAAoB;AAAA,UAC7C;AACA,cAAI,eAAe,SAAS,MAAM,GAAG;AACnC,uBAAW,OAAO,KAAK,cAAc;AAAA,UACvC;AAAA,QACF,WAAW,eAAe,SAAS,OAAO,KAAK,eAAe,SAAS,QAAQ,GAAG;AAChF,cAAI,CAAC,WAAW,OAAO,SAAS,OAAO,GAAG;AACxC,uBAAW,OAAO,KAAK,OAAO;AAAA,UAChC;AACA,cAAI,eAAe,SAAS,YAAY,GAAG;AACzC,uBAAW,OAAO,KAAK,kBAAkB;AAAA,UAC3C;AACA,cAAI,eAAe,SAAS,MAAM,GAAG;AACnC,uBAAW,OAAO,KAAK,YAAY;AAAA,UACrC;AAAA,QACF,WAAW,eAAe,SAAS,SAAS,GAAG;AAC7C,cAAI,CAAC,WAAW,OAAO,SAAS,SAAS,GAAG;AAC1C,uBAAW,OAAO,KAAK,SAAS;AAAA,UAClC;AACA,cAAI,eAAe,SAAS,YAAY,GAAG;AACzC,uBAAW,OAAO,KAAK,oBAAoB;AAAA,UAC7C;AACA,cAAI,eAAe,SAAS,MAAM,GAAG;AACnC,uBAAW,OAAO,KAAK,cAAc;AAAA,UACvC;AAAA,QACF,WAAW,eAAe,SAAS,SAAS,KAAK,eAAe,SAAS,MAAM,KAAK,eAAe,SAAS,OAAO,GAAG;AACpH,cAAI,CAAC,WAAW,OAAO,SAAS,SAAS,GAAG;AAC1C,uBAAW,OAAO,KAAK,SAAS;AAAA,UAClC;AACA,cAAI,eAAe,SAAS,OAAO,GAAG;AACpC,uBAAW,SAAS,KAAK,aAAa;AAAA,UACxC;AAAA,QACF,WAAW,eAAe,SAAS,WAAW,KAAK,eAAe,SAAS,aAAa,GAAG;AACzF,cAAI,CAAC,WAAW,OAAO,SAAS,WAAW,GAAG;AAC5C,uBAAW,OAAO,KAAK,WAAW;AAAA,UACpC;AAAA,QACF,WAAW,eAAe,SAAS,SAAS,KAAK,eAAe,SAAS,SAAS,GAAG;AACnF,cAAI,CAAC,WAAW,OAAO,SAAS,SAAS,GAAG;AAC1C,uBAAW,OAAO,KAAK,SAAS;AAAA,UAClC;AAAA,QACF,WAAW,eAAe,SAAS,MAAM,GAAG;AAC1C,cAAI,CAAC,WAAW,OAAO,SAAS,MAAM,GAAG;AACvC,uBAAW,OAAO,KAAK,MAAM;AAAA,UAC/B;AACA,qBAAW,OAAO,KAAK,YAAY;AAAA,QACrC;AAAA,MACF;AAGA,UAAI,eAAe,SAAS,MAAM,KAAK,eAAe,SAAS,WAAW,KACtE,eAAe,SAAS,UAAU,KAAK,eAAe,SAAS,MAAM,KACrE,eAAe,SAAS,QAAQ,KAAK,eAAe,SAAS,MAAM,KACnE,eAAe,SAAS,OAAO,KAAK,eAAe,SAAS,QAAQ,KACpE,eAAe,SAAS,aAAa,GAAG;AAE1C,YAAI,eAAe,SAAS,UAAU,GAAG;AACvC,cAAI,CAAC,WAAW,WAAW,SAAS,UAAU,GAAG;AAC/C,uBAAW,WAAW,KAAK,UAAU;AAAA,UACvC;AAEA,cAAI,eAAe,SAAS,OAAO,GAAG;AACpC,uBAAW,WAAW,KAAK,gBAAgB;AAAA,UAC7C,WAAW,eAAe,SAAS,QAAQ,GAAG;AAC5C,uBAAW,WAAW,KAAK,iBAAiB;AAAA,UAC9C,WAAW,eAAe,SAAS,OAAO,GAAG;AAC3C,uBAAW,WAAW,KAAK,gBAAgB;AAAA,UAC7C;AAEA,cAAI,eAAe,SAAS,SAAS,GAAG;AACtC,uBAAW,SAAS,KAAK,SAAS;AAAA,UACpC;AACA,cAAI,eAAe,SAAS,QAAQ,GAAG;AACrC,uBAAW,SAAS,KAAK,QAAQ;AAAA,UACnC;AAAA,QACF,WAAW,eAAe,SAAS,MAAM,GAAG;AAC1C,cAAI,CAAC,WAAW,WAAW,SAAS,MAAM,GAAG;AAC3C,uBAAW,WAAW,KAAK,WAAW;AAAA,UACxC;AACA,cAAI,eAAe,SAAS,OAAO,GAAG;AACpC,uBAAW,WAAW,KAAK,YAAY;AAAA,UACzC,WAAW,eAAe,SAAS,QAAQ,GAAG;AAC5C,uBAAW,WAAW,KAAK,aAAa;AAAA,UAC1C,WAAW,eAAe,SAAS,OAAO,GAAG;AAC3C,uBAAW,WAAW,KAAK,YAAY;AAAA,UACzC;AAEA,cAAI,eAAe,SAAS,QAAQ,GAAG;AACrC,uBAAW,WAAW,KAAK,MAAM;AACjC,uBAAW,SAAS,KAAK,aAAa;AAAA,UACxC;AACA,cAAI,eAAe,SAAS,SAAS,GAAG;AACtC,uBAAW,SAAS,KAAK,cAAc;AAAA,UACzC;AAAA,QACF,WAAW,eAAe,SAAS,QAAQ,GAAG;AAC5C,cAAI,CAAC,WAAW,WAAW,SAAS,QAAQ,GAAG;AAC7C,uBAAW,WAAW,KAAK,aAAa;AAAA,UAC1C;AACA,cAAI,eAAe,SAAS,OAAO,GAAG;AACpC,uBAAW,WAAW,KAAK,cAAc;AACzC,uBAAW,SAAS,KAAK,cAAc;AAAA,UACzC,WAAW,eAAe,SAAS,QAAQ,GAAG;AAC5C,uBAAW,WAAW,KAAK,eAAe;AAAA,UAC5C,WAAW,eAAe,SAAS,OAAO,GAAG;AAC3C,uBAAW,WAAW,KAAK,cAAc;AAAA,UAC3C;AAAA,QACF,WAAW,eAAe,SAAS,OAAO,GAAG;AAC3C,qBAAW,SAAS,KAAK,OAAO;AAChC,cAAI,eAAe,SAAS,OAAO,GAAG;AACpC,uBAAW,SAAS,KAAK,aAAa;AAAA,UACxC;AAAA,QACF,WAAW,eAAe,SAAS,QAAQ,GAAG;AAC5C,qBAAW,SAAS,KAAK,QAAQ;AACjC,qBAAW,SAAS,KAAK,aAAa;AAAA,QACxC,WAAW,eAAe,SAAS,aAAa,GAAG;AACjD,qBAAW,SAAS,KAAK,aAAa;AAAA,QACxC;AAGA,YAAI,WAAW,SAAS,QAAQ,KAAK,WAAW,SAAS,KAAK,KAAK,WAAW,SAAS,MAAM,GAAG;AAC9F,qBAAW,WAAW,KAAK,MAAM;AAAA,QACnC,WAAW,WAAW,SAAS,KAAK,KAAK,WAAW,SAAS,SAAS,GAAG;AACvE,qBAAW,WAAW,KAAK,SAAS;AAAA,QACtC,WAAW,WAAW,SAAS,KAAK,KAAK,WAAW,SAAS,UAAU,GAAG;AACxE,qBAAW,WAAW,KAAK,UAAU;AAAA,QACvC;AAGA,YAAI,WAAW,SAAS,YAAY,KAAK,WAAW,SAAS,aAAa,GAAG;AAC3E,qBAAW,SAAS,KAAK,aAAa;AAAA,QACxC;AACA,YAAI,WAAW,SAAS,eAAe,KAAK,WAAW,SAAS,gBAAgB,GAAG;AACjF,qBAAW,SAAS,KAAK,gBAAgB;AAAA,QAC3C;AAAA,MACF;AAGA,UAAI,eAAe,SAAS,WAAW,KAAK,eAAe,SAAS,QAAQ,KACxE,eAAe,SAAS,QAAQ,GAAG;AAErC,YAAI,eAAe,SAAS,UAAU,KAAK,eAAe,SAAS,QAAQ,GAAG;AAC5E,cAAI,CAAC,WAAW,QAAQ,SAAS,UAAU,GAAG;AAC5C,uBAAW,QAAQ,KAAK,UAAU;AAAA,UACpC;AACA,qBAAW,OAAO,KAAK,sBAAsB;AAAA,QAC/C,WAAW,eAAe,SAAS,MAAM,KAAK,eAAe,SAAS,QAAQ,GAAG;AAC/E,cAAI,CAAC,WAAW,QAAQ,SAAS,QAAQ,GAAG;AAC1C,uBAAW,QAAQ,KAAK,QAAQ;AAAA,UAClC;AACA,qBAAW,OAAO,KAAK,aAAa;AAAA,QACtC,WAAW,eAAe,SAAS,MAAM,GAAG;AAC1C,qBAAW,SAAS,KAAK,MAAM;AAC/B,qBAAW,SAAS,KAAK,cAAc;AAAA,QACzC;AAAA,MACF;AAGA,UAAI,eAAe,SAAS,SAAS,GAAG;AACtC,YAAI,eAAe,SAAS,MAAM,GAAG;AACnC,qBAAW,SAAS,KAAK,cAAc;AAAA,QACzC,WAAW,eAAe,SAAS,UAAU,GAAG;AAC9C,qBAAW,SAAS,KAAK,kBAAkB;AAC3C,qBAAW,OAAO,KAAK,UAAU;AAAA,QACnC,WAAW,eAAe,SAAS,QAAQ,GAAG;AAC5C,qBAAW,SAAS,KAAK,gBAAgB;AACzC,qBAAW,OAAO,KAAK,UAAU;AAAA,QACnC,WAAW,eAAe,SAAS,OAAO,GAAG;AAC3C,cAAI,eAAe,SAAS,SAAS,GAAG;AACtC,uBAAW,SAAS,KAAK,eAAe;AAAA,UAC1C;AAAA,QACF;AAAA,MACF;AAGA,UAAI,eAAe,SAAS,YAAY,GAAG;AACzC,YAAI,eAAe,SAAS,aAAa,GAAG;AAC1C,qBAAW,SAAS,KAAK,wBAAwB;AACjD,cAAI,eAAe,SAAS,QAAQ,GAAG;AACrC,uBAAW,SAAS,KAAK,mBAAmB;AAAA,UAC9C;AAAA,QACF,WAAW,eAAe,SAAS,OAAO,GAAG;AAC3C,qBAAW,OAAO,KAAK,SAAS;AAChC,qBAAW,SAAS,KAAK,kBAAkB;AAAA,QAC7C;AAAA,MACF;AAGA,UAAI,eAAe,SAAS,SAAS,KAAK,eAAe,SAAS,QAAQ,GAAG;AAC3E,mBAAW,OAAO,KAAK,iBAAiB;AAAA,MAC1C;AAGA,UAAI,eAAe,SAAS,QAAQ,GAAG;AACrC,YAAI,eAAe,SAAS,MAAM,KAAK,eAAe,SAAS,SAAS,GAAG;AACzE,qBAAW,OAAO,KAAK,SAAS;AAChC,qBAAW,SAAS,KAAK,gBAAgB;AAAA,QAC3C,WAAW,eAAe,SAAS,aAAa,GAAG;AACjD,qBAAW,OAAO,KAAK,WAAW;AAClC,qBAAW,SAAS,KAAK,oBAAoB;AAAA,QAC/C;AACA,YAAI,eAAe,SAAS,UAAU,GAAG;AACvC,qBAAW,SAAS,KAAK,UAAU;AAAA,QACrC;AACA,YAAI,eAAe,SAAS,SAAS,KAAK,eAAe,SAAS,SAAS,GAAG;AAC5E,qBAAW,SAAS,KAAK,YAAY;AAAA,QACvC;AAAA,MACF;AAAA,IACF;AAIA,UAAM,eAAe;AACrB,QAAI;AACJ,YAAQ,aAAa,aAAa,KAAK,MAAM,OAAO,MAAM;AACxD,YAAM,eAAe,WAAW,CAAC,EAAE,YAAY;AAC/C,UAAI,gBAAgB,CAAC,WAAW,OAAO,SAAS,YAAY,GAAG;AAC7D,mBAAW,OAAO,KAAK,YAAY;AAAA,MACrC;AAAA,IACF;AAGA,QAAI,wCAAwC,KAAK,MAAM,GAAG;AACxD,UAAI,CAAC,WAAW,QAAQ,SAAS,UAAU,GAAG;AAC5C,mBAAW,QAAQ,KAAK,UAAU;AAAA,MACpC;AACA,iBAAW,OAAO,KAAK,sBAAsB;AAAA,IAC/C;AAGA,QAAI,yBAAyB,KAAK,MAAM,GAAG;AACzC,UAAI,CAAC,WAAW,QAAQ,SAAS,QAAQ,GAAG;AAC1C,mBAAW,QAAQ,KAAK,QAAQ;AAAA,MAClC;AACA,iBAAW,OAAO,KAAK,aAAa;AAAA,IACtC;AAGA,QAAI,qCAAqC,KAAK,MAAM,GAAG;AACrD,UAAI,eAAe,KAAK,MAAM,GAAG;AAC/B,mBAAW,SAAS,KAAK,aAAa;AAAA,MACxC;AACA,UAAI,gBAAgB,KAAK,MAAM,GAAG;AAChC,mBAAW,SAAS,KAAK,aAAa;AAAA,MACxC;AACA,UAAI,UAAU,KAAK,MAAM,GAAG;AAC1B,mBAAW,SAAS,KAAK,QAAQ;AAAA,MACnC;AAAA,IACF;AAGA,QAAI,kCAAkC,KAAK,MAAM,GAAG;AAClD,iBAAW,SAAS,KAAK,QAAQ;AACjC,iBAAW,SAAS,KAAK,aAAa;AAAA,IACxC;AAGA,QAAI,6BAA6B,KAAK,MAAM,KAAK,2BAA2B,KAAK,MAAM,GAAG;AACxF,iBAAW,SAAS,KAAK,aAAa;AACtC,iBAAW,SAAS,KAAK,gBAAgB;AAAA,IAC3C;AACA,QAAI,4CAA4C,KAAK,MAAM,GAAG;AAC5D,iBAAW,SAAS,KAAK,UAAU;AAAA,IACrC;AACA,QAAI,6CAA6C,KAAK,MAAM,GAAG;AAC7D,iBAAW,SAAS,KAAK,SAAS;AAAA,IACpC;AACA,QAAI,+BAA+B,KAAK,MAAM,GAAG;AAC/C,iBAAW,SAAS,KAAK,UAAU;AAAA,IACrC;AACA,QAAI,4BAA4B,KAAK,MAAM,GAAG;AAC5C,iBAAW,SAAS,KAAK,WAAW;AAAA,IACtC;AACA,QAAI,2CAA2C,KAAK,MAAM,GAAG;AAC3D,iBAAW,SAAS,KAAK,cAAc;AAAA,IACzC;AACA,QAAI,uCAAuC,KAAK,MAAM,GAAG;AACvD,iBAAW,SAAS,KAAK,kBAAkB;AAC3C,iBAAW,OAAO,KAAK,UAAU;AAAA,IACnC;AACA,QAAI,mCAAmC,KAAK,MAAM,GAAG;AACnD,iBAAW,SAAS,KAAK,gBAAgB;AACzC,iBAAW,OAAO,KAAK,UAAU;AAAA,IACnC;AAGA,QAAI,yBAAyB,KAAK,MAAM,GAAG;AACzC,iBAAW,OAAO,KAAK,MAAM;AAC7B,iBAAW,SAAS,KAAK,WAAW;AAAA,IACtC;AACA,QAAI,yBAAyB,KAAK,MAAM,GAAG;AACzC,iBAAW,SAAS,KAAK,WAAW;AAAA,IACtC;AACA,QAAI,yBAAyB,KAAK,MAAM,GAAG;AACzC,iBAAW,SAAS,KAAK,WAAW;AAAA,IACtC;AACA,QAAI,+BAA+B,KAAK,MAAM,GAAG;AAC/C,iBAAW,SAAS,KAAK,cAAc;AAAA,IACzC;AAGA,QAAI,6CAA6C,KAAK,MAAM,GAAG;AAC7D,iBAAW,WAAW,KAAK,MAAM;AACjC,iBAAW,WAAW,KAAK,aAAa;AACxC,iBAAW,SAAS,KAAK,aAAa;AAAA,IACxC;AACA,QAAI,+CAA+C,KAAK,MAAM,GAAG;AAC/D,iBAAW,WAAW,KAAK,aAAa;AACxC,iBAAW,SAAS,KAAK,cAAc;AAAA,IACzC;AACA,QAAI,uCAAuC,KAAK,MAAM,GAAG;AACvD,iBAAW,SAAS,KAAK,SAAS;AAAA,IACpC;AACA,QAAI,qCAAqC,KAAK,MAAM,GAAG;AACrD,iBAAW,SAAS,KAAK,QAAQ;AAAA,IACnC;AAGA,QAAI,iCAAiC,KAAK,MAAM,GAAG;AACjD,iBAAW,SAAS,KAAK,eAAe;AACxC,UAAI,WAAW,KAAK,MAAM,GAAG;AAC3B,mBAAW,SAAS,KAAK,eAAe;AAAA,MAC1C;AAAA,IACF;AAGA,QAAI,mDAAmD,KAAK,MAAM,GAAG;AACnE,iBAAW,SAAS,KAAK,wBAAwB;AAAA,IACnD;AACA,QAAI,mEAAmE,KAAK,MAAM,GAAG;AACnF,iBAAW,SAAS,KAAK,+BAA+B;AAAA,IAC1D;AAGA,QAAI,mCAAmC,KAAK,MAAM,GAAG;AACnD,iBAAW,SAAS,KAAK,gBAAgB;AAAA,IAC3C;AACA,QAAI,2CAA2C,KAAK,MAAM,GAAG;AAC3D,iBAAW,SAAS,KAAK,oBAAoB;AAAA,IAC/C;AAGA,QAAI,8BAA8B,KAAK,MAAM,GAAG;AAC9C,iBAAW,SAAS,KAAK,aAAa;AACtC,UAAI,aAAa,KAAK,MAAM,GAAG;AAC7B,mBAAW,SAAS,KAAK,gBAAgB;AAAA,MAC3C;AAAA,IACF;AAGA,QAAI,gCAAgC,KAAK,MAAM,GAAG;AAChD,iBAAW,SAAS,KAAK,gBAAgB;AAAA,IAC3C;AACA,QAAI,0BAA0B,KAAK,MAAM,GAAG;AAC1C,iBAAW,SAAS,KAAK,aAAa;AAAA,IACxC;AAGA,QAAI,iBAAiB,KAAK,MAAM,GAAG;AACjC,YAAM,cAAc,OAAO,SAAS,iBAAiB;AACrD,iBAAW,SAAS,aAAa;AAC/B,cAAM,OAAO,SAAS,MAAM,CAAC,GAAG,EAAE;AAClC,YAAI,QAAQ,IAAI;AACd,qBAAW,SAAS,KAAK,YAAY;AAAA,QACvC,WAAW,QAAQ,IAAI;AACrB,qBAAW,SAAS,KAAK,aAAa;AAAA,QACxC,OAAO;AACL,qBAAW,SAAS,KAAK,YAAY;AAAA,QACvC;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;;;AC/xCO,SAAS,mBAAmB,YAAiC,UAA0B;AAC5F,QAAM,aAAuB,CAAC;AAI9B,QAAM,iBAAiB,MAAM,KAAK,WAAW,UAAU;AACvD,QAAM,qBAAqB,qBAAqB,cAAc;AAE9D,MAAI,mBAAmB,SAAS,GAAG;AAGjC,eAAW,KAAK,GAAG,mBAAmB,MAAM,GAAG,CAAC,CAAC;AAAA,EACnD;AAGA,MAAI,WAAW,UAAU,SAAS,GAAG;AAEnC,UAAM,iBAAiB,WAAW,UAAU,MAAM,GAAG,CAAC;AACtD,QAAI,eAAe,SAAS,GAAG;AAE7B,UAAI,eAAe,SAAS,QAAQ,KAAK,eAAe,SAAS,MAAM,GAAG;AACxE,mBAAW,KAAK,sBAAsB;AAAA,MACxC,WAAW,eAAe,SAAS,QAAQ,KAAK,eAAe,SAAS,QAAQ,GAAG;AACjF,mBAAW,KAAK,wBAAwB;AAAA,MAC1C,WAAW,eAAe,WAAW,GAAG;AACtC,mBAAW,KAAK,QAAQ,eAAe,CAAC,CAAC,EAAE;AAAA,MAC7C,OAAO;AAEL,mBAAW,KAAK,GAAG,eAAe,MAAM,GAAG,CAAC,CAAC;AAAA,MAC/C;AAAA,IACF;AAAA,EACF;AAGA,MAAI,WAAW,SAAS;AACtB,eAAW,KAAK,WAAW,OAAO;AAAA,EACpC;AAIA,MAAI,WAAW,aAAa,OAAO,GAAG;AACpC,UAAM,eAAe,MAAM,KAAK,WAAW,YAAY,EACpD,OAAO,iBAAe;AAErB,UAAI,gBAAgB,kBAAkB,WAAW,SAAS,SAAS,cAAc,GAAG;AAClF,eAAO;AAAA,MACT;AACA,aAAO;AAAA,IACT,CAAC,EACA,MAAM,GAAG,CAAC;AACb,eAAW,KAAK,GAAG,YAAY;AAAA,EACjC;AAGA,MAAI,WAAW,OAAO,SAAS,GAAG;AAChC,eAAW,KAAK,GAAG,WAAW,OAAO,MAAM,GAAG,CAAC,CAAC;AAAA,EAClD;AAGA,MAAI,WAAW,OAAO,SAAS,GAAG;AAChC,eAAW,KAAK,GAAG,WAAW,OAAO,MAAM,GAAG,CAAC,CAAC;AAAA,EAClD;AAGA,MAAI,WAAW,WAAW,SAAS,GAAG;AAEpC,UAAM,wBAAwB,WAAW,WAAW;AAAA,MAAO,OACzD,EAAE,SAAS,UAAU,KAAK,EAAE,SAAS,MAAM,KAAK,EAAE,SAAS,OAAO;AAAA,IACpE;AACA,QAAI,sBAAsB,SAAS,GAAG;AACpC,iBAAW,KAAK,GAAG,sBAAsB,MAAM,GAAG,CAAC,CAAC;AAAA,IACtD;AAAA,EACF;AAGA,MAAI,WAAW,QAAQ,SAAS,GAAG;AACjC,eAAW,KAAK,GAAG,WAAW,QAAQ,MAAM,GAAG,CAAC,CAAC;AAAA,EACnD;AAGA,MAAI,WAAW,OAAO,SAAS,GAAG;AAChC,eAAW,KAAK,GAAG,WAAW,OAAO,MAAM,GAAG,CAAC,CAAC;AAAA,EAClD;AAGA,MAAI,WAAW,SAAS,SAAS,GAAG;AAClC,eAAW,KAAK,GAAG,WAAW,SAAS,MAAM,GAAG,CAAC,CAAC;AAAA,EACpD;AAGA,QAAM,OAAO,oBAAI,IAAY;AAC7B,QAAM,cAAc,WAAW,OAAO,UAAQ;AAC5C,UAAM,QAAQ,KAAK,YAAY;AAC/B,QAAI,KAAK,IAAI,KAAK,GAAG;AACnB,aAAO;AAAA,IACT;AACA,SAAK,IAAI,KAAK;AACd,WAAO;AAAA,EACT,CAAC;AAGD,MAAI,YAAY,SAAS,GAAG;AAC1B,WAAO,YAAY,KAAK,GAAG;AAAA,EAC7B;AAEA,SAAO;AACT;AAMO,SAAS,qBAAqB,YAAgC;AACnE,QAAM,WAAsC;AAAA;AAAA,IAE1C,qBAAqB;AAAA,IACrB,eAAe;AAAA,IACf,WAAW;AAAA,IACX,cAAc;AAAA,IACd,YAAY;AAAA,IACZ,YAAY;AAAA,IACZ,aAAa;AAAA,IACb,cAAc;AAAA,IACd,SAAS;AAAA,IACT,SAAS;AAAA,IACT,UAAU;AAAA,IACV,WAAW;AAAA,IACX,SAAS;AAAA,IACT,QAAQ;AAAA;AAAA,IAGR,YAAY;AAAA,IACZ,UAAU;AAAA,IACV,UAAU;AAAA,IACV,YAAY;AAAA,IACZ,SAAS;AAAA,IACT,YAAY;AAAA,IACZ,cAAc;AAAA,IACd,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,SAAS;AAAA,IACT,WAAW;AAAA,IACX,SAAS;AAAA,IACT,YAAY;AAAA,IACZ,SAAS;AAAA,IACT,UAAU;AAAA;AAAA,IAGV,UAAU;AAAA,IACV,SAAS;AAAA,IACT,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,UAAU;AAAA,IACV,UAAU;AAAA,IACV,QAAQ;AAAA,IACR,SAAS;AAAA,EACX;AAEA,SAAO,WAAW,KAAK,CAAC,GAAG,MAAM;AAC/B,UAAM,YAAY,SAAS,CAAC,KAAK;AACjC,UAAM,YAAY,SAAS,CAAC,KAAK;AACjC,WAAO,YAAY;AAAA,EACrB,CAAC;AACH;;;AC/JO,IAAM,uBAAN,MAA2B;AAAA,EACxB;AAAA,EACA;AAAA,EAER,cAAc;AACZ,SAAK,oBAAoB,IAAI,yBAAyB;AACtD,SAAK,yBAAyB,IAAI,uBAAuB;AAAA,EAC3D;AAAA;AAAA;AAAA;AAAA,EAKA,aACE,eACA,gBAAwB,gBAChB;AACR,QAAI,CAAC,cAAc,WAAW,cAAc,QAAQ,WAAW,GAAG;AAChE,aAAO;AAAA,IACT;AAEA,UAAM,aAAkC;AAAA,MACtC,YAAY,oBAAI,IAAY;AAAA,MAC5B,QAAQ,CAAC;AAAA,MACT,QAAQ,CAAC;AAAA,MACT,cAAc,oBAAI,IAAY;AAAA,MAC9B,WAAW,CAAC;AAAA,MACZ,QAAQ,CAAC;AAAA,MACT,YAAY,CAAC;AAAA,MACb,SAAS,CAAC;AAAA,MACV,UAAU,CAAC;AAAA,IACb;AAGA,eAAW,QAAQ,cAAc,SAAS;AACxC,UAAI,KAAK,SAAS,UAAU,OAAO,KAAK,SAAS,UAAU;AACzD,cAAM,OAAO,KAAK;AAGlB,cAAM,QAAQ,KAAK,MAAM,4CAA4C;AACrE,cAAM,cAAc,MAAM,CAAC,KAAK;AAChC,cAAM,gBAAgB,MAAM,CAAC,KAAK;AAGlC,aAAK,uBAAuB,yBAAyB,aAAa,eAAe,UAAU;AAAA,MAC7F;AAAA,IACF;AAGA,WAAO,mBAAmB,YAAY,aAAa;AAAA,EACrD;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,yBACE,UACQ;AACR,QAAI,CAAC,SAAS,WAAW,SAAS,QAAQ,WAAW,GAAG;AACtD,aAAO;AAAA,IACT;AAEA,UAAM,aAAkC;AAAA,MACtC,YAAY,oBAAI,IAAY;AAAA,MAC5B,QAAQ,CAAC;AAAA,MACT,QAAQ,CAAC;AAAA,MACT,cAAc,oBAAI,IAAY;AAAA,MAC9B,WAAW,CAAC;AAAA,MACZ,QAAQ,CAAC;AAAA,MACT,YAAY,CAAC;AAAA,MACb,SAAS,CAAC;AAAA,MACV,UAAU,CAAC;AAAA,IACb;AAGA,eAAW,QAAQ,SAAS,SAAS;AACnC,UAAI,KAAK,SAAS,UAAU,OAAO,KAAK,SAAS,UAAU;AACzD,cAAM,eAAe,KAAK;AAE1B,cAAM,QAAQ,KAAK,kBAAkB,aAAa,YAAY;AAC9D,mBAAW,SAAS,KAAK,GAAG,KAAK;AAAA,MACnC;AAAA,IACF;AAGA,WAAO,mBAAmB,YAAY,EAAE;AAAA,EAC1C;AACF;;;ACjGA,OAAO;AAuCA,IAAM,wBAAN,MAA4B;AAAA,EACzB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAER,YAAY,UAAwC,CAAC,GAAG;AACtD,SAAK,YAAY,QAAQ,IAAI;AAC7B,SAAK,YAAY,QAAQ;AACzB,SAAK,WAAW,WAAW,QAAQ,IAAI,kBAAmB;AAC1D,SAAK,OAAO,SAAS,QAAQ,IAAI,gBAAiB,EAAE;AACpD,SAAK,oBAAoB,QAAQ,IAAI;AACrC,SAAK,cAAc,QAAQ,IAAI;AAC/B,SAAK,wBAAwB,QAAQ,IAAI;AACzC,SAAK,sBAAsB,QAAQ,IAAI;AAAA,EACzC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,kBAAkB,MAAiC;AACvD,QAAI;AACF,aAAO,MAAM,gCAAgC;AAC7C,YAAM,YAAY,KAAK,IAAI;AAE3B,YAAM,WAAW,MAAM,MAAM,KAAK,mBAAmB;AAAA,QACnD,QAAQ;AAAA,QACR,SAAS;AAAA,UACP,QAAQ;AAAA,UACR,eAAe,UAAU,KAAK,WAAW;AAAA,UACzC,gBAAgB;AAAA,QAClB;AAAA,QACA,MAAM,KAAK,UAAU;AAAA,UACnB,OAAO;AAAA,UACP,OAAO,KAAK;AAAA,UACZ,SAAS;AAAA,UACT,OAAO,QAAQ,IAAI,kBAAkB;AAAA,QACvC,CAAC;AAAA,MACH,CAAC;AAED,aAAO,MAAM,wBAAwB,SAAS,MAAM,EAAE;AAEtD,UAAI,CAAC,SAAS,IAAI;AAChB,cAAM,YAAY,MAAM,SAAS,KAAK;AACtC,eAAO,MAAM,uBAAuB,SAAS;AAC7C,cAAM,IAAI,MAAM,cAAc,SAAS,MAAM,IAAI,SAAS,UAAU,EAAE;AAAA,MACxE;AAEA,aAAO,MAAM,yBAAyB;AACtC,YAAM,OAAQ,MAAM,SAAS,KAAK;AAIlC,UAAI,CAAC,KAAK,QAAQ,CAAC,KAAK,KAAK,CAAC,KAAK,CAAC,KAAK,KAAK,CAAC,EAAE,WAAW;AAC1D,eAAO,MAAM,4BAA4B,KAAK,UAAU,IAAI,EAAE,UAAU,GAAG,GAAG,CAAC;AAC/E,cAAM,IAAI,MAAM,6BAA6B;AAAA,MAC/C;AAEA,YAAM,YAAY,KAAK,KAAK,CAAC,EAAE;AAC/B,YAAM,UAAU,KAAK,IAAI,IAAI;AAC7B,aAAO,MAAM,+BAA0B,UAAU,MAAM,aAAa,OAAO,IAAI;AAE/E,aAAO;AAAA,IACT,SAAS,OAAO;AACd,aAAO,MAAM,+BAA+B,KAAK;AACjD,YAAM,IAAI,MAAM,iCAAiC,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC,EAAE;AAAA,IAC3G;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMQ,WAAW,OAIA;AACjB,UAAM,WAAW,MAAM,YAAY,CAAC;AAEpC,WAAO;AAAA,MACL,IAAI,MAAM,MAAM;AAAA,MAChB,KAAM,SAAS,OAAkB,MAAM,MAAM;AAAA,MAC7C,OAAO,MAAM,SAAS;AAAA,MACtB,MAAO,SAAS,QAAmB;AAAA,MACnC,WAAY,SAAS,aAAwB;AAAA,MAC7C,UAAW,SAAS,YAAuB;AAAA,MAC3C,UAAW,SAAS,YAAuB;AAAA,MAC3C,QAAS,SAAS,UAAqB;AAAA,MACvC,WAAY,SAAS,aAAwB;AAAA,MAC7C,UAAU,MAAM,QAAQ,SAAS,QAAQ,IAAK,SAAS,WAAwB,CAAC;AAAA,IAClF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAc,mBACZ,WACA,MACA,WAQC;AACD,UAAM,MAAM,GAAG,KAAK,qBAAqB,kBAAkB,KAAK,SAAS;AAEzE,WAAO,MAAM,kCAAkC,GAAG,GAAG,YAAY,iBAAiB,SAAS,OAAO,EAAE,EAAE;AAEtG,UAAM,cAKF;AAAA,MACF,QAAQ;AAAA,MACR;AAAA,MACA,iBAAiB;AAAA,IACnB;AAGA,QAAI,WAAW;AACb,kBAAY,YAAY;AAAA,IAC1B;AAEA,UAAM,YAAY,KAAK,IAAI;AAC3B,UAAM,WAAW,MAAM,MAAM,KAAK;AAAA,MAChC,QAAQ;AAAA,MACR,SAAS;AAAA,QACP,iBAAiB,UAAU,KAAK,WAAW;AAAA,QAC3C,gBAAgB;AAAA,QAChB,UAAU;AAAA,MACZ;AAAA,MACA,MAAM,KAAK,UAAU,WAAW;AAAA,IAClC,CAAC;AAED,UAAM,YAAY,KAAK,IAAI,IAAI;AAC/B,WAAO,MAAM,8BAA8B,SAAS,MAAM,KAAK,SAAS,KAAK;AAE7E,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,YAAY,MAAM,SAAS,KAAK;AACtC,aAAO,MAAM,6BAA6B,SAAS;AACnD,YAAM,IAAI,MAAM,6BAA6B,SAAS,MAAM,IAAI,SAAS,UAAU,MAAM,SAAS,EAAE;AAAA,IACtG;AAEA,UAAM,OAAO,MAAM,SAAS,KAAK;AASjC,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,OAAO,OAAe,UAAyB,CAAC,GAA2B;AAC/E,QAAI,CAAC,SAAS,OAAO,UAAU,UAAU;AACvC,YAAM,IAAI,MAAM,kCAAkC;AAAA,IACpD;AACA,WAAO,MAAM,2BAA2B,KAAK,UAAU,OAAO,CAAC,EAAE;AACnE,WAAO,MAAM,yBAAyB,QAAQ,IAAI,WAAW,OAAO,QAAQ,IAAI,EAAE;AAClF,WAAO,MAAM,uCAAuC,QAAQ,SAAS,MAAS,EAAE;AAChF,WAAO,MAAM,iCAAiC,KAAK,IAAI,EAAE;AAEvD,UAAM,WACJ,QAAQ,aAAa,SAAY,QAAQ,WAAW,KAAK;AAC3D,UAAM,OAAO,QAAQ,SAAS,SAAY,QAAQ,OAAO,KAAK;AAE9D,UAAM,YAAY,QAAQ,cAAc,SAAY,QAAQ,YAAY,KAAK;AAE7E,WAAO,MAAM,6BAA6B,KAAK,YAAY,IAAI,eAAe,QAAQ,GAAG,YAAY,iBAAiB,SAAS,MAAM,EAAE,EAAE;AAGzI,UAAM,YAAY,MAAM,KAAK,kBAAkB,KAAK;AAGpD,WAAO,MAAM,4BAA4B,KAAK,SAAS,oBAAoB,YAAY,eAAe,SAAS,MAAM,EAAE,KAAK;AAC5H,UAAM,YAAY,KAAK,IAAI;AAE3B,UAAM,gBAAgB,MAAM,KAAK,mBAAmB,WAAW,MAAM,SAAS;AAC9E,UAAM,YAAY,KAAK,IAAI,IAAI;AAC/B,WAAO,MAAM,sBAAsB,SAAS,cAAc,cAAc,SAAS,UAAU,CAAC,UAAU;AAGtG,UAAM,aAAa,cAAc,WAAW,CAAC;AAC7C,UAAM,kBAAkB,WAAW,OAAO,CAAC,OAAO,EAAE,SAAS,MAAM,QAAQ;AAE3E,WAAO,MAAM,qBAAqB,gBAAgB,MAAM,uBAAuB,QAAQ,YAAY,WAAW,MAAM,QAAQ;AAE5H,WAAO;AAAA,MACL;AAAA,MACA,cAAc,WAAW;AAAA,MACzB,iBAAiB,gBAAgB;AAAA,MACjC,SAAS,gBAAgB,IAAI,CAAC,UAAU,KAAK,WAAW,KAAK,CAAC;AAAA,MAC9D,gBAAgB;AAAA,QACd;AAAA,QACA;AAAA,QACA,WAAW,KAAK;AAAA,QAChB;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,oBAAoB,KAA6C;AACrE,QAAI,CAAC,OAAO,OAAO,QAAQ,UAAU;AACnC,YAAM,IAAI,MAAM,gCAAgC;AAAA,IAClD;AAGA,UAAM,UAAU,MAAM,KAAK,OAAO,KAAK,EAAE,MAAM,IAAI,UAAU,EAAE,CAAC;AAGhE,UAAM,aAAa,QAAQ,QAAQ;AAAA,MACjC,CAAC,MAAM,EAAE,QAAQ,OAAO,EAAE,OAAO;AAAA,IACnC;AAEA,QAAI,YAAY;AACd,aAAO;AAAA,IACT;AAGA,QAAI,QAAQ,QAAQ,SAAS,GAAG;AAC9B,aAAO,QAAQ,QAAQ,CAAC;AAAA,IAC1B;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,sBAAsB,MAA2C;AACrE,QAAI,CAAC,MAAM,QAAQ,IAAI,GAAG;AACxB,YAAM,IAAI,MAAM,uBAAuB;AAAA,IACzC;AAEA,UAAM,UAAU,MAAM,QAAQ;AAAA,MAC5B,KAAK,IAAI,CAAC,QAAQ,KAAK,oBAAoB,GAAG,CAAC;AAAA,IACjD;AAEA,WAAO,QAAQ;AAAA,MACb,CAAC,MAA2B,MAAM;AAAA,IACpC;AAAA,EACF;AACF;;;ACpTO,IAAM,aAAN,MAAiB;AAAA;AAAA;AAAA;AAAA,EAItB,OAAO,aAAa,eAmBlB;AACA,WAAO;AAAA,MACL,OAAO,cAAc;AAAA,MACrB,SAAS;AAAA,QACP,cAAc,cAAc;AAAA,QAC5B,iBAAiB,cAAc;AAAA,QAC/B,UAAU,cAAc,eAAe;AAAA,MACzC;AAAA,MACA,YAAY,cAAc,QAAQ,IAAI,CAAC,WAAW;AAAA,QAChD,IAAI,MAAM;AAAA,QACV,KAAK,MAAM;AAAA,QACX,OAAO,MAAM;AAAA,QACb,MAAM,MAAM;AAAA,QACZ,WAAW,MAAM;AAAA,QACjB,UAAU,MAAM;AAAA,QAChB,UAAU,MAAM;AAAA,QAChB,QAAQ,MAAM;AAAA,QACd,WAAW,MAAM;AAAA,QACjB,UAAU,MAAM;AAAA,MAClB,EAAE;AAAA,IACJ;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,OAAO,WAAW,eAAsC;AACtD,QAAI,CAAC,cAAc,WAAW,cAAc,QAAQ,WAAW,GAAG;AAChE,aAAO;AAAA;AAAA,cAEC,cAAc,KAAK;AAAA;AAAA;AAAA,IAG7B;AAGA,QAAI,WAAW;AAAA,wBACK,cAAc,eAAe,OAAO,cAAc,YAAY;AAAA;AAAA;AAIlF,kBAAc,QAAQ,QAAQ,CAAC,OAAO,UAAU;AAC9C,kBAAY,OAAO,QAAQ,CAAC,KAAK,MAAM,GAAG;AAAA;AAAA;AAAA,EAG9C,MAAM,aAAa,sCAAsC;AAAA;AAAA;AAAA;AAAA;AAAA,IAKvD,CAAC;AAED,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,OAAO,iBAAiB,SAAmC;AACzD,QAAI,CAAC,WAAW,QAAQ,WAAW,GAAG;AACpC,aAAO;AAAA,IACT;AAIA,UAAM,kBAAkB,QAAQ,IAAI,CAAC,WAAW;AAAA,MAC9C,KAAK,MAAM;AAAA,MACX,OAAO,MAAM;AAAA;AAAA,MACb,UAAU,MAAM;AAAA,MAChB,QAAQ,MAAM;AAAA,MACd,UAAU,MAAM;AAAA,IAClB,EAAE;AAGF,WAAO,KAAK,UAAU,EAAE,YAAY,gBAAgB,GAAG,MAAM,CAAC;AAAA,EAChE;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,OAAO,4BAA4B,SAAmC;AACpE,QAAI,CAAC,WAAW,QAAQ,WAAW,GAAG;AACpC,aAAO;AAAA,IACT;AAGA,UAAM,kBAAkB,QAAQ,IAAI,CAAC,WAAW;AAAA,MAC9C,KAAK,MAAM;AAAA,MACX,OAAO,MAAM;AAAA,MACb,UAAU,MAAM;AAAA,IAClB,EAAE;AAGF,WAAO,KAAK,UAAU,EAAE,YAAY,gBAAgB,GAAG,MAAM,CAAC;AAAA,EAChE;AAEF;;;ACzHA,IAAM,iBAAiB;AAgBvB,eAAsB,gBAAgB,cAAwD;AAC5F,SAAO,KAAK,iCAA0B;AAEtC,MAAI;AACF,UAAM,WAAW,MAAM,MAAM,gBAAgB;AAAA,MAC3C,QAAQ;AAAA,MACR,SAAS;AAAA,QACP,gBAAgB;AAAA,MAClB;AAAA,MACA,MAAM,KAAK,UAAU,EAAE,aAAa,CAAC;AAAA,IACvC,CAAC;AAED,UAAM,OAAO,MAAM,SAAS,KAAK;AAEjC,QAAI,SAAS,MAAM,KAAK,UAAU,MAAM;AACtC,aAAO,KAAK,4BAAuB,KAAK,KAAK,EAAE;AAC/C,aAAO;AAAA,QACL,OAAO;AAAA,QACP,WAAW,KAAK;AAAA,QAChB,cAAc,KAAK;AAAA,QACnB,QAAQ,KAAK;AAAA,QACb,OAAO,KAAK;AAAA,MACd;AAAA,IACF;AAEA,UAAM,eAAgB,KAAK,SAAoB;AAC/C,WAAO,MAAM,qCAAgC,YAAY,EAAE;AAC3D,UAAM,IAAI,MAAM,8BAA8B,YAAY,EAAE;AAAA,EAC9D,SAAS,OAAO;AACd,QAAI,iBAAiB,SAAS,MAAM,QAAQ,WAAW,4BAA4B,GAAG;AACpF,YAAM;AAAA,IACR;AAEA,WAAO,MAAM,sCAAiC,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;AAEpG,QAAI,iBAAiB,OAAO;AAC1B,UAAI,MAAM,QAAQ,SAAS,cAAc,KAAK,MAAM,QAAQ,SAAS,cAAc,GAAG;AACpF,cAAM,IAAI,MAAM,mDAAmD;AAAA,MACrE,WAAW,MAAM,QAAQ,SAAS,SAAS,GAAG;AAC5C,cAAM,IAAI,MAAM,6DAA6D;AAAA,MAC/E;AAAA,IACF;AAEA,UAAM,IAAI,MAAM,8BAA8B,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC,EAAE;AAAA,EACxG;AACF;;;AClEA,OAAO;AAOP,SAAS,8BAA8B,MAA+E;AACpH,QAAM,SAAS,KAAK;AACpB,MAAI,CAAC,MAAM,QAAQ,MAAM,GAAG;AAC1B,WAAO;AAAA,EACT;AAEA,QAAM,YAAsB,CAAC;AAC7B,aAAW,QAAQ,QAAQ;AACzB,QAAI,CAAC,QAAQ,OAAO,SAAS,UAAU;AACrC;AAAA,IACF;AACA,UAAM,IAAI;AACV,QAAI,EAAE,SAAS,WAAW;AACxB;AAAA,IACF;AACA,UAAM,UAAU,EAAE;AAClB,QAAI,CAAC,MAAM,QAAQ,OAAO,GAAG;AAC3B;AAAA,IACF;AACA,eAAW,SAAS,SAAS;AAC3B,UAAI,CAAC,SAAS,OAAO,UAAU,UAAU;AACvC;AAAA,MACF;AACA,YAAM,IAAI;AACV,UAAI,EAAE,SAAS,iBAAiB,OAAO,EAAE,SAAS,YAAY,EAAE,KAAK,SAAS,GAAG;AAC/E,kBAAU,KAAK,EAAE,IAAI;AAAA,MACvB;AAAA,IACF;AAAA,EACF;AAEA,QAAM,SAAS,UAAU,KAAK,IAAI,EAAE,KAAK;AACzC,MAAI,CAAC,QAAQ;AACX,WAAO;AAAA,EACT;AAEA,QAAM,cACJ,KAAK,WAAW,aACZ,0CACA;AACN,SAAO,EAAE,QAAQ,QAAQ,YAAY;AACvC;AAGA,SAAS,iBAAiB,MAAwE;AAChG,MAAI,OAAO,KAAK,aAAa,YAAY,KAAK,UAAU;AACtD,WAAO,EAAE,QAAQ,KAAK,UAAU,aAAa,WAAW;AAAA,EAC1D;AAEA,QAAM,aAAa,8BAA8B,IAAI;AACrD,MAAI,YAAY;AACd,WAAO;AAAA,EACT;AAEA,MAAI,OAAO,KAAK,WAAW,YAAY,KAAK,QAAQ;AAClD,WAAO,EAAE,QAAQ,KAAK,QAAQ,aAAa,SAAS;AAAA,EACtD;AAEA,QAAM,UAAU,KAAK;AACrB,QAAM,MAAM,UAAU,CAAC,GAAG;AAC1B,MAAI,OAAO,OAAO,IAAI,YAAY,YAAY,IAAI,SAAS;AACzD,WAAO,EAAE,QAAQ,IAAI,SAAS,aAAa,6BAA6B;AAAA,EAC1E;AAEA,MAAI,OAAO,KAAK,YAAY,YAAY,KAAK,SAAS;AACpD,WAAO,EAAE,QAAQ,KAAK,SAAS,aAAa,UAAU;AAAA,EACxD;AAEA,SAAO,EAAE,QAAQ,KAAK,UAAU,IAAI,GAAG,aAAa,gBAAgB;AACtE;AAmBO,IAAM,cAAN,MAAkB;AAAA,EACf;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAER,YAAY,UAA8B,CAAC,GAAG;AAC5C,SAAK,SAAS,QAAQ,UAAU,QAAQ,IAAI;AAC5C,SAAK,SAAS,QAAQ,UAAU,QAAQ,IAAI;AAC5C,SAAK,QAAQ,QAAQ,SAAS,QAAQ,IAAI,eAAe;AACzD,SAAK,YAAY,QAAQ,cAAc,QAAQ,IAAI,mBAAmB,SAAS,QAAQ,IAAI,kBAAkB,EAAE,IAAI;AACnH,SAAK,UAAU,CAAC,EAAE,KAAK,UAAU,KAAK;AAAA,EACxC;AAAA;AAAA;AAAA;AAAA,EAKA,YAAqB;AACnB,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,YAAY,UAAkB,SAAyB;AACrD,WAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQT,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAgBP,QAAQ;AAAA,EACR;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,kBAAkB,OAAe,SAAyB;AACxD,WAAO;AAAA;AAAA,aAEE,KAAK;AAAA;AAAA;AAAA,EAGhB,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWP;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,IAAI,UAAkB,SAAyC;AACnE,QAAI,CAAC,KAAK,SAAS;AACjB,aAAO;AAAA,QACL,SAAS;AAAA,QACT,OACE;AAAA,QACF,UAAU;AAAA,MACZ;AAAA,IACF;AAEA,QAAI,CAAC,YAAY,OAAO,aAAa,UAAU;AAC7C,aAAO;AAAA,QACL,SAAS;AAAA,QACT,OAAO;AAAA,QACP,UAAU;AAAA,MACZ;AAAA,IACF;AAEA,WAAO,MAAM,kBAAkB;AAE/B,UAAM,SAAS,KAAK,YAAY,UAAU,OAAO;AAEjD,WAAO,MAAM,YAAY,KAAK,MAAM,EAAE;AACtC,WAAO,MAAM,UAAU,KAAK,KAAK,EAAE;AACnC,WAAO,MAAM,oBAAoB,SAAS,MAAM,QAAQ;AACxD,WAAO,MAAM,mBAAmB,QAAQ,MAAM,QAAQ;AACtD,WAAO,MAAM,eAAe,KAAK,SAAS,EAAE;AAE5C,QAAI;AACF,YAAM,YAAY,KAAK,IAAI;AAC3B,YAAM,WAAW,MAAM,MAAM,KAAK,QAAS;AAAA,QACzC,QAAQ;AAAA,QACR,SAAS;AAAA,UACP,gBAAgB;AAAA,UAChB,eAAe,UAAU,KAAK,MAAM;AAAA,QACtC;AAAA,QACA,MAAM,KAAK,UAAU;AAAA,UACnB,OAAO,KAAK;AAAA,UACZ,OAAO;AAAA,UACP,YAAY,KAAK;AAAA,UACjB,QAAQ;AAAA,UACR,OAAO,QAAQ,IAAI,kBAAkB;AAAA,QACvC,CAAC;AAAA,MACH,CAAC;AACD,YAAM,YAAY,KAAK,IAAI,IAAI;AAC/B,aAAO,MAAM,4BAA4B,SAAS,gBAAgB,SAAS,MAAM,EAAE;AAEnF,UAAI,CAAC,SAAS,IAAI;AAChB,eAAO,MAAM,cAAc,SAAS,MAAM,IAAI,SAAS,UAAU,EAAE;AACnE,cAAM,IAAI,MAAM,cAAc,SAAS,MAAM,IAAI,SAAS,UAAU,EAAE;AAAA,MACxE;AAEA,YAAM,OAAQ,MAAM,SAAS,KAAK;AAClC,YAAM,EAAE,QAAQ,YAAY,IAAI,iBAAiB,IAAI;AAErD,YAAM,aAAe,KAAK,OAAqC,gBAAkC;AACjG,YAAM,gBAAgB,OAAO,QAAQ,QAAQ,GAAG,EAAE,MAAM,GAAG,GAAG;AAC9D,aAAO;AAAA,QACL,gCAAgC,aAAa,YAAY,WAAW;AAAA,MACtE;AAEA,aAAO;AAAA,QACL,iCAAiC,SAAS,MAAM,OAAO,SAAS,0BAAqB,WAAW,MAAM,OAAO,MAAM,kBAAkB,cAAc,KAAK;AAAA,MAC1J;AAEA,aAAO;AAAA,QACL,SAAS;AAAA,QACT,OAAO;AAAA,QACP,UAAU;AAAA,QACV,UAAU;AAAA,UACR,OAAO,KAAK;AAAA,UACZ;AAAA,QACF;AAAA,MACF;AAAA,IACF,SAAS,OAAO;AACd,aAAO,MAAM,2BAA2B,KAAK;AAC7C,aAAO;AAAA,QACL,SAAS;AAAA,QACT,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,QAC5D,UAAU;AAAA,MACZ;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,aAAa,OAAe,SAAyC;AACzE,QAAI,CAAC,KAAK,SAAS;AACjB,aAAO;AAAA,QACL,SAAS;AAAA,QACT,OACE;AAAA,QACF,UAAU;AAAA,MACZ;AAAA,IACF;AAEA,QAAI,CAAC,SAAS,OAAO,UAAU,UAAU;AACvC,aAAO;AAAA,QACL,SAAS;AAAA,QACT,OAAO;AAAA,QACP,UAAU;AAAA,MACZ;AAAA,IACF;AAEA,WAAO,MAAM,gCAAgC;AAG7C,UAAM,SAAS,KAAK,kBAAkB,OAAO,OAAO;AAEpD,WAAO,MAAM,YAAY,KAAK,MAAM,EAAE;AACtC,WAAO,MAAM,UAAU,KAAK,KAAK,EAAE;AACnC,WAAO,MAAM,iBAAiB,MAAM,MAAM,QAAQ;AAClD,WAAO,MAAM,mBAAmB,QAAQ,MAAM,QAAQ;AACtD,WAAO,MAAM,eAAe,KAAK,SAAS,EAAE;AAE5C,QAAI;AACF,YAAM,YAAY,KAAK,IAAI;AAC3B,YAAM,WAAW,MAAM,MAAM,KAAK,QAAS;AAAA,QACzC,QAAQ;AAAA,QACR,SAAS;AAAA,UACP,gBAAgB;AAAA,UAChB,eAAe,UAAU,KAAK,MAAM;AAAA,QACtC;AAAA,QACA,MAAM,KAAK,UAAU;AAAA,UACnB,OAAO,KAAK;AAAA,UACZ,OAAO;AAAA,UACP,YAAY,KAAK;AAAA,UACjB,QAAQ;AAAA,UACR,OAAO,QAAQ,IAAI,kBAAkB;AAAA,QACvC,CAAC;AAAA,MACH,CAAC;AACD,YAAM,YAAY,KAAK,IAAI,IAAI;AAC/B,aAAO,MAAM,4BAA4B,SAAS,gBAAgB,SAAS,MAAM,EAAE;AAEnF,UAAI,CAAC,SAAS,IAAI;AAChB,eAAO,MAAM,cAAc,SAAS,MAAM,IAAI,SAAS,UAAU,EAAE;AACnE,cAAM,IAAI,MAAM,cAAc,SAAS,MAAM,IAAI,SAAS,UAAU,EAAE;AAAA,MACxE;AAEA,YAAM,OAAQ,MAAM,SAAS,KAAK;AAClC,YAAM,EAAE,QAAQ,YAAY,IAAI,iBAAiB,IAAI;AAErD,YAAM,aAAe,KAAK,OAAqC,gBAAkC;AACjG,YAAM,gBAAgB,OAAO,QAAQ,QAAQ,GAAG,EAAE,MAAM,GAAG,GAAG;AAC9D,aAAO;AAAA,QACL,mCAAmC,aAAa,YAAY,WAAW;AAAA,MACzE;AAEA,aAAO;AAAA,QACL,oCAAoC,SAAS,MAAM,OAAO,SAAS,0BAAqB,WAAW,MAAM,OAAO,MAAM,kBAAkB,cAAc,KAAK;AAAA,MAC7J;AAEA,aAAO;AAAA,QACL,SAAS;AAAA,QACT,OAAO;AAAA,QACP,UAAU;AAAA,QACV,UAAU;AAAA,UACR,OAAO,KAAK;AAAA,UACZ;AAAA,QACF;AAAA,MACF;AAAA,IACF,SAAS,OAAO;AACd,aAAO,MAAM,yCAAyC,KAAK;AAC3D,aAAO;AAAA,QACL,SAAS;AAAA,QACT,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,QAC5D,UAAU;AAAA,MACZ;AAAA,IACF;AAAA,EACF;AACF;;;ACvVA,SAAS,2BAA2B,UAAkB,eAAmC;AACvF,MAAI,CAAC,YAAY,OAAO,aAAa,UAAU;AAC7C,WAAO,CAAC;AAAA,EACV;AAGA,MAAI,aAAa,SAAS,KAAK;AAG/B,eAAa,WAAW,QAAQ,SAAS,EAAE;AAC3C,eAAa,WAAW,QAAQ,OAAO,EAAE;AACzC,eAAa,WAAW,QAAQ,mBAAmB,EAAE;AAIrD,MAAI,OAAiB,CAAC;AAGtB,QAAM,aAAa,WAAW,MAAM,GAAG,EAAE,IAAI,OAAK,EAAE,KAAK,CAAC;AAG1D,QAAM,eAAe,WAAW,MAAM,KAAK,EAAE,IAAI,OAAK,EAAE,KAAK,CAAC;AAG9D,QAAM,gBAAgB,CAAC,GAAG,YAAY,GAAG,YAAY,EAClD,IAAI,SAAO;AAEV,UAAM,IAAI,QAAQ,aAAa,EAAE;AACjC,UAAM,IAAI,QAAQ,aAAa,EAAE;AACjC,UAAM,IAAI,QAAQ,eAAe,EAAE;AACnC,UAAM,IAAI,QAAQ,UAAU,EAAE;AAC9B,WAAO,IAAI,KAAK;AAAA,EAClB,CAAC,EACA,OAAO,SAAO,IAAI,SAAS,CAAC;AAG/B,aAAW,aAAa,eAAe;AACrC,UAAM,iBAAiB,UAAU,YAAY;AAE7C,UAAM,aAAa,cAAc;AAAA,MAAK,OACpC,EAAE,YAAY,MAAM,kBACpB,EAAE,YAAY,EAAE,SAAS,cAAc,KACvC,eAAe,SAAS,EAAE,YAAY,CAAC;AAAA,IACzC;AAEA,QAAI,cAAc,CAAC,KAAK,SAAS,UAAU,GAAG;AAC5C,WAAK,KAAK,UAAU;AAAA,IACtB;AAAA,EACF;AAEA,SAAO,MAAM,UAAU,KAAK,MAAM,8BAA8B,KAAK,KAAK,IAAI,CAAC,EAAE;AACjF,SAAO;AACT;AAkBA,eAAsB,0BACpB,SACiC;AACjC,QAAM,EAAE,OAAO,cAAc,IAAI;AAGjC,MAAI,CAAC,cAAc,WAAW,cAAc,QAAQ,WAAW,GAAG;AAChE,WAAO;AAAA,MACL,iBAAiB;AAAA,MACjB,aAAa;AAAA,IACf;AAAA,EACF;AAGA,QAAM,cAAc,IAAI,YAAY;AAEpC,MAAI,kBAAoC,cAAc;AACtD,MAAI,cAAc;AAClB,MAAI;AAGJ,MAAI,YAAY,UAAU,GAAG;AAC3B,QAAI;AACF,aAAO,MAAM,wCAAwC;AAGrD,YAAM,qBAAqB,WAAW,4BAA4B,cAAc,OAAO;AAGvF,YAAM,iBAAiB,KAAK,IAAI;AAChC,YAAM,gBAAgB,MAAM,YAAY,aAAa,OAAO,kBAAkB;AAC9E,0BAAoB,KAAK,IAAI,IAAI;AAEjC,aAAO,MAAM,mCAAmC,iBAAiB,iBAAiB,cAAc,OAAO,EAAE;AAEzG,UAAI,cAAc,WAAW,cAAc,UAAU;AAEnD,cAAM,gBAAgB,cAAc,QAAQ,IAAI,OAAK,EAAE,GAAG;AAC1D,cAAM,eAAe,2BAA2B,cAAc,UAAU,aAAa;AAErF,YAAI,aAAa,SAAS,GAAG;AAE3B,4BAAkB,cAAc,QAAQ;AAAA,YAAO,WAC7C,aAAa,SAAS,MAAM,GAAG;AAAA,UACjC;AAEA,wBAAc;AACd,iBAAO,MAAM,kBAAkB,gBAAgB,MAAM,oBAAoB,cAAc,QAAQ,MAAM,gBAAgB;AAAA,QACvH,OAAO;AACL,iBAAO,KAAK,0DAA0D;AAAA,QACxE;AAAA,MACF,OAAO;AACL,eAAO,KAAK,2BAA2B,cAAc,SAAS,eAAe,8BAA8B;AAAA,MAC7G;AAAA,IACF,SAAS,YAAY;AACnB,aAAO,KAAK,0BAA0B,sBAAsB,QAAQ,WAAW,UAAU,OAAO,UAAU,CAAC,8BAA8B;AAAA,IAE3I;AAAA,EACF,OAAO;AACL,WAAO,MAAM,kDAAkD;AAAA,EACjE;AAGA,QAAM,wBAAuC;AAAA,IAC3C,GAAG;AAAA,IACH,SAAS;AAAA,IACT,iBAAiB,gBAAgB;AAAA,EACnC;AAEA,SAAO;AAAA,IACL,iBAAiB;AAAA,IACjB;AAAA,IACA;AAAA,EACF;AACF;;;AXrIA,IAAM,cAAc;AACpB,QAAQ,IAAI,WAAW;AAmBvB,IAAM,aAAa,cAAc,YAAY,GAAG;AAChD,IAAM,YAAY,QAAQ,UAAU;AACpC,IAAMA,WAAU,cAAc,YAAY,GAAG;AAE7C,IAAM,cAAcA,SAAQ,KAAK,WAAW,iBAAiB,CAAC;AAC9D,IAAM,cAAc,YAAY;AAChC,IAAM,gBAAgB;AAGtB,OAAO,KAAK,2BAA2B,WAAW,aAAa,aAAa,MAAM,WAAW,GAAG;AAChG,OAAO,KAAK,cAAc,QAAQ,IAAI,gBAAgB,SAAS,gBAAgB,OAAO,EAAE;AACxF,OAAO,KAAK,YAAY,QAAQ,OAAO,EAAE;AAKzC,OAAO,MAAM,oCAAoC;AAGjD,QAAQ,IAAI,iBAAiB;AAC7B,QAAQ,IAAI,qBAAqB;AACjC,QAAQ,IAAI,iBAAiB;AAC7B,QAAQ,IAAI,2BAA2B;AAKvC,QAAQ,IAAI,gBAAgB;AAC5B,QAAQ,IAAI,sBAAsB;AAClC,QAAQ,IAAI,wBAAwB;AACpC,QAAQ,IAAI,cAAc;AAC1B,QAAQ,IAAI,mBAAmB;AAG/B,QAAQ,IAAI,cAAc;AAC1B,QAAQ,IAAI,OAAO;AAGnB,OAAO,MAAM,mBAAmB,QAAQ,IAAI,cAAc,EAAE;AAC5D,OAAO,MAAM,uBAAuB,QAAQ,IAAI,kBAAkB,EAAE;AACpE,OAAO,MAAM,mBAAmB,QAAQ,IAAI,cAAc,EAAE;AAC5D,OAAO,MAAM,6BAA6B,QAAQ,IAAI,wBAAwB,EAAE;AAChF,OAAO,MAAM,kBAAkB,QAAQ,IAAI,aAAa,EAAE;AAC1D,OAAO,MAAM,wBAAwB,QAAQ,IAAI,mBAAmB,EAAE;AACtE,OAAO,MAAM,0BAA0B,QAAQ,IAAI,qBAAqB,EAAE;AAC1E,OAAO,MAAM,gBAAgB,QAAQ,IAAI,WAAW,EAAE;AACtD,OAAO,MAAM,qBAAqB,QAAQ,IAAI,gBAAgB,EAAE;AAChE,OAAO,MAAM,gBAAgB,QAAQ,IAAI,WAAW,EAAE;AACtD,OAAO,MAAM,SAAS,QAAQ,IAAI,IAAI,EAAE;AACxC,OAAO,KAAK,sBAAsB;AAGlC,IAAM,OAAO,MAAM,QAAQ,QAAQ,IAAI,CAAC,EACrC,OAAO,iBAAiB;AAAA,EACvB,MAAM;AAAA,EACN,aAAa;AAAA,EACb,cAAc;AAChB,CAAC,EACA,UAAU;AAGb,IAAM,gBAAgB,KAAK,cAAc,KAAK;AAC9C,IAAI,CAAC,iBAAiB,kBAAkB,IAAI;AAC1C,SAAO,MAAM,sDAAiD;AAC9D,UAAQ,KAAK,CAAC;AAChB;AAMA,IAAI,qBAA6B;AACjC,IAAI;AACF,QAAM,UAAU,MAAM,gBAAgB,aAAa;AACnD,uBAAqB,QAAQ;AAC7B,UAAQ,IAAI,qBAAqB,QAAQ;AACzC,UAAQ,IAAI,iBAAiB,QAAQ;AACrC,UAAQ,IAAI,cAAc,QAAQ;AAClC,SAAO,KAAK,oBAAoB,QAAQ,KAAK,EAAE;AAC/C,SAAO,MAAM,uBAAuB,kBAAkB,EAAE;AACxD,SAAO,MAAM,uBAAuB,QAAQ,aAAa,UAAU,GAAG,CAAC,CAAC,cAAc;AACxF,SAAS,OAAO;AACd,SAAO,MAAM,sEAAiE;AAC9E,UAAQ,KAAK,CAAC;AAChB;AAGA,IAAM,cAAc,QAAQ,IAAI,gBAAgB,UAAU,QAAQ,IAAI,gBAAgB;AACtF,IAAM,OAAO,SAAS,QAAQ,IAAI,QAAQ,QAAQ,EAAE;AAGpD,IAAM,SAAS,IAAI,QAAQ;AAAA,EACzB,cAAc;AAAA,EACd,MAAM;AAAA,EACN,SAAS;AACX,CAAC;AAGD,OAAO,MAAM,8BAA8B;AAC3C,IAAM,cAAc,IAAI,YAAY,2BAA2B;AAC/D,OAAO,MAAM,6BAA6B;AAG1C,IAAI,iBAAiB;AACrB,OAAO,MAAM,oEAAoE;AAEjF,IAAM,sBAAsB,KAAK,IAAI;AACrC,YACG,QAAQ,EACR,KAAK,MAAM;AACV,QAAM,iBAAiB,KAAK,IAAI,IAAI;AACpC,mBAAiB;AACjB,SAAO,MAAM,2BAA2B,cAAc,KAAK;AAC7D,CAAC,EACA,MAAM,CAAC,UAAU;AAChB,QAAM,iBAAiB,KAAK,IAAI,IAAI;AACpC,SAAO,KAAK,mCAAmC,cAAc,KAAK;AAClE,SAAO,MAAM,eAAe,OAAO,aAAa,QAAQ,OAAO,KAAK;AACpE,SAAO,MAAM,kBAAkB,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;AAErF,MAAI,SAAS,OAAO,UAAU,UAAU;AACtC,UAAM,WAAW;AACjB,QAAI,UAAU,UAAU;AACtB,aAAO,MAAM,eAAe,SAAS,IAAI;AAAA,IAC3C;AAAA,EACF;AAEA,MAAI,iBAAiB,SAAS,MAAM,OAAO;AACzC,WAAO,MAAM,gBAAgB,MAAM,KAAK;AAAA,EAC1C;AAEA,SAAO,KAAK,kFAAkF;AAC9F,SAAO,MAAM,6CAA6C;AAC5D,CAAC;AAMH,OAAO,QAAQ;AAAA,EACb,MAAM;AAAA,EACN,aAAa;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAoBb,aAAa;AAAA,IACX,OAAO;AAAA,IACP,cAAc;AAAA,IACd,eAAe;AAAA,EACjB;AAAA,EACA,YAAY,EAAE,OAAO;AAAA,IACnB,mBAAmB,EAChB,QAAQ,EACR,SAAS,EACT,QAAQ,KAAK,EACb,SAAS,wIAAwI;AAAA,EACtJ,CAAC;AAAA,EACD,SAAS,OAAO,MAAM,aAAa;AACjC,QAAI;AACF,YAAM,oBAAoB,KAAK,qBAAqB;AACpD,aAAO,MAAM,sBAAsB,iBAAiB,EAAE;AACtD,aAAO,MAAM,wBAAwB,cAAc,EAAE;AAErD,UAAI,CAAC,gBAAgB;AACnB,eAAO,KAAK,uCAAuC;AACnD,cAAM,SAAwB;AAAA,UAC5B,SAAS,CAAC;AAAA,YACR,MAAM;AAAA,YACN,MAAM;AAAA,UACR,CAAC;AAAA,QACH;AACA,eAAO;AAAA,MACT;AAEA,aAAO,MAAM,2CAA2C;AACxD,YAAM,gBAAgB,MAAM,YAAY,iBAAiB;AAEzD,UAAI,CAAC,cAAc,WAAW,cAAc,QAAQ,WAAW,GAAG;AAChE,cAAM,SAAwB;AAAA,UAC5B,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,oCAA+B,CAAC;AAAA,QAC3E;AACA,eAAO;AAAA,MACT;AAGA,YAAM,sBAA+B;AAAA,QACnC,MAAM;AAAA,QACN,MAAM;AAAA;AAAA,kEAEoD,oBAAoB,+BAA+B,iBAAiB;AAAA;AAAA,MAEhI;AAEA,aAAO;AAAA,QACL,SAAS,CAAC,GAAI,cAAc,SAAuB,mBAAmB;AAAA,MACxE;AAAA,IACF,SAAS,OAAO;AACd,aAAO,MAAM,iCAAiC,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;AACpG,YAAM,SAAwB;AAAA,QAC5B,SAAS,CAAC;AAAA,UACR,MAAM;AAAA,UACN,MAAM,wCAAmC,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;AAAA,QACjG,CAAC;AAAA,MACH;AACA,aAAO;AAAA,IACT;AAAA,EACF;AACF,CAAC;AAKD,OAAO,QAAQ;AAAA,EACb,MAAM;AAAA,EACN,aAAa;AAAA,EACb,aAAa;AAAA,IACX,OAAO;AAAA,IACP,cAAc;AAAA,IACd,eAAe;AAAA,EACjB;AAAA,EACA,YAAY,EAAE,OAAO,CACrB,CAAC;AAAA,EACD,SAAS,OAAO,aAAa;AAC3B,QAAI;AAEF,aAAO,MAAM,wBAAwB,cAAc,EAAE;AAErD,UAAI,CAAC,gBAAgB;AACnB,eAAO,KAAK,uCAAuC;AACnD,cAAM,SAAwB;AAAA,UAC5B,SAAS,CAAC;AAAA,YACR,MAAM;AAAA,YACN,MAAM;AAAA,UACR,CAAC;AAAA,QACH;AACA,eAAO;AAAA,MACT;AAEA,aAAO,MAAM,wCAAwC;AACrD,YAAM,aAAa,MAAM,YAAY,cAAc;AAEnD,UAAI,CAAC,WAAW,WAAW,WAAW,QAAQ,WAAW,GAAG;AAC1D,cAAM,SAAwB;AAAA,UAC5B,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,gCAA2B,CAAC;AAAA,QACvE;AACA,eAAO;AAAA,MACT;AAGA,YAAM,sBAA+B;AAAA,QACnC,MAAM;AAAA,QACN,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAeR;AAEA,aAAO;AAAA,QACL,SAAS,CAAC,qBAAqB,GAAI,WAAW,OAAqB;AAAA,MACrE;AAAA,IACF,SAAS,OAAO;AACd,aAAO,MAAM,6BAA6B,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;AAChG,YAAM,SAAwB;AAAA,QAC5B,SAAS,CAAC;AAAA,UACR,MAAM;AAAA,UACN,MAAM,oCAA+B,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;AAAA,QAC7F,CAAC;AAAA,MACH;AACA,aAAO;AAAA,IACT;AAAA,EACF;AACF,CAAC;AAcD,OAAO,QAAQ;AAAA,EACb,MAAM;AAAA,EACN,aAAa;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcb,aAAa;AAAA,IACX,OAAO;AAAA,IACP,cAAc;AAAA,IACd,eAAe;AAAA,EACjB;AAAA,EACA,YAAY,EAAE,OAAO,CACrB,CAAC;AAAA,EACD,SAAS,OAAQ,aAAa;AAC5B,QAAI;AACF,aAAO,MAAM,wBAAwB,cAAc,EAAE;AAErD,UAAI,CAAC,gBAAgB;AACnB,eAAO,KAAK,uCAAuC;AACnD,eAAO;AAAA,UACL,SAAS,CAAC;AAAA,YACR,MAAM;AAAA,YACN,MAAM;AAAA,UACR,CAAC;AAAA,QACH;AAAA,MACF;AAGA,YAAM,CAAC,YAAY,UAAU,aAAa,IAAI,MAAM,QAAQ,IAAI;AAAA,QAC9D,YAAY,cAAc;AAAA,QAC1B,YAAY,YAAY;AAAA,QACxB,YAAY,iBAAiB;AAAA,MAC/B,CAAC;AAGD,YAAM,iBAAiB,IAAI,qBAAqB;AAGhD,UAAI,gBAAgB;AACpB,UAAI;AAEF,cAAM,0BAA0B;AAAA,UAC9B,SAAS,SAAS,WAAW,CAAC;AAAA,QAChC;AACA,wBAAgB,eAAe,yBAAyB,uBAAuB;AAAA,MACjF,SAAS,OAAO;AACd,eAAO,KAAK,0CAA0C,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;AAAA,MAC9G;AAGA,UAAI,qBAAqB;AACzB,UAAI;AACF,6BAAqB,eAAe,aAAa,eAAe,cAAc;AAAA,MAChF,SAAS,OAAO;AACd,eAAO,KAAK,gDAAgD,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;AAAA,MACpH;AAEA,YAAM,WAAsB,CAAC;AAG7B,UAAI,WAAW,SAAS,QAAQ;AAC9B,iBAAS,KAAK,GAAI,WAAW,OAAqB;AAAA,MACpD;AAGA,eAAS,KAAK;AAAA,QACZ,MAAM;AAAA,QACN,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MACR,CAAC;AAED,eAAS,KAAK;AAAA,QACZ,MAAM;AAAA,QACN,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,iHAQmG,aAAa,UAAU,kBAAkB;AAAA;AAAA;AAAA,MAGpJ,CAAC;AAED,aAAO,EAAE,SAAS,SAAS;AAAA,IAC7B,SAAS,OAAO;AACd,aAAO,MAAM,oCAAoC,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;AACvG,aAAO;AAAA,QACL,SAAS,CAAC;AAAA,UACR,MAAM;AAAA,UACN,MAAM,2CAAsC,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;AAAA,QACpG,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF;AACF,CAAC;AAMD,OAAO,QAAQ;AAAA,EACb,MAAM;AAAA,EACN,aAAa;AAAA,EACb,aAAa;AAAA,IACX,OAAO;AAAA,IACP,cAAc;AAAA,IACd,eAAe;AAAA,EACjB;AAAA,EACA,YAAY,EAAE,OAAO;AAAA,IACnB,OAAO,EACJ,OAAO,EACP,SAAS,0DAA0D;AAAA,EACxE,CAAC;AAAA,EACD,SAAS,OAAO,MAAM,aAAa;AACjC,QAAI;AACF,aAAO,MAAM,oCAAoC;AACjD,aAAO,MAAM,UAAU,KAAK,KAAK,EAAE;AAGnC,YAAM,gBAAgB,IAAI,sBAAsB;AAAA,QAC9C,WAAW;AAAA,MACb,CAAC;AAGD,YAAM,gBAAgB,MAAM,cAAc,OAAO,KAAK,KAAK;AAG3D,YAAM,EAAE,gBAAgB,IAAI,MAAM,0BAA0B;AAAA,QAC1D,OAAO,KAAK;AAAA,QACZ;AAAA,MACF,CAAC;AAGD,YAAM,mBAAmB,WAAW,WAAW,eAAe;AAE9D,aAAO;AAAA,QACL,SAAS;AAAA,UACP;AAAA,YACE,MAAM;AAAA,YACN,MAAM;AAAA,UACR;AAAA,QACF;AAAA,MACF;AAAA,IACF,SAAS,OAAO;AACd,aAAO,MAAM,sCAAsC,KAAK;AACxD,aAAO;AAAA,QACL,SAAS;AAAA,UACP;AAAA,YACE,MAAM;AAAA,YACN,MAAM,iBAAY,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;AAAA,UAC1E;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF,CAAC;AA+GD,IAAI,aAAa;AACf,SAAO,MAAM;AAAA,IACX,YAAY;AAAA,MACV,MAAM;AAAA,IACR;AAAA,IACA,eAAe;AAAA,EACjB,CAAC;AAED,SAAO,KAAK,gDAAgD;AAC5D,SAAO,KAAK,8BAA8B,IAAI,MAAM;AACpD,SAAO,MAAM,uBAAuB,kBAAkB,EAAE;AACxD,SAAO,MAAM;AAAA;AAAA,gCAEiB,IAAI;AAAA;AAAA;AAAA,CAGnC;AACD,OAAO;AACL,SAAO,MAAM,EAAE,eAAe,QAAQ,CAAC;AACvC,SAAO,KAAK,gDAAgD;AAC9D;","names":["require"]}
1
+ {"version":3,"sources":["../src/figma2frida/figma2frida.ts","../src/figma2frida/utils/logger.ts","../src/figma2frida/clients/figma-client.ts","../src/figma2frida/utils/design-query-extractor/metadata-extractor-simpler.ts","../src/figma2frida/utils/design-query-extractor/design-context-extractor.ts","../src/figma2frida/utils/design-query-extractor/query-builder.ts","../src/figma2frida/utils/design-query-extractor/index.ts","../src/figma2frida/services/pinecone/pinecone-service.ts","../src/figma2frida/utils/formatters.ts","../src/figma2frida/services/auth/token-validator.ts","../src/figma2frida/services/frida/frida-client.ts","../src/figma2frida/handlers/library-filter-handler.ts"],"sourcesContent":["#!/usr/bin/env node\n/**\n * Figma MCP Proxy Server\n * \n * Simple wrapper around official Figma Desktop MCP.\n * \n * Tools:\n * 1. test_figma_connection - Get a screenshot to verify connection\n * 2. figma_get_design_context - Get design data and generated code from Figma\n */\n\n// ============================================================================\n// IMPORTS (before environment setup)\n// ============================================================================\nimport { z } from \"zod\";\nimport yargs from \"yargs\";\nimport { hideBin } from \"yargs/helpers\";\nimport { FastMCP, type ContentResult, type Content } from \"fastmcp\";\nimport { createRequire } from \"module\";\nimport { fileURLToPath } from \"url\";\nimport { dirname, join } from \"path\";\n\n// ============================================================================\n// ENVIRONMENT CONFIGURATION (set before logger import)\n// ============================================================================\nconst ENVIRONMENT = \"production\"; // Change mode to \"production\" / \"development\"\nprocess.env.NODE_ENV = ENVIRONMENT; // Set BEFORE importing logger\n\n// Now import logger (it will read NODE_ENV correctly)\nimport { logger } from \"./utils/logger.js\";\nimport { FigmaClient } from \"./clients/figma-client.js\";\n// import { FigmaDesignContextResult } from \"./clients/figma-client.js\";\n// import { handleComponentSuggestion } from \"./handlers/component-suggestion-handler.js\";\n// import { ComponentExtractor } from \"./utils/component-extractor.js\";\n// import { ComponentLookupService } from \"./services/component-lookup.js\";\n// import type { ComponentMatch } from \"./services/pinecone/pinecone-service.js\";\nimport { DesignQueryExtractor } from \"./utils/design-query-extractor/index.js\";\nimport { PineconeSearchService } from \"./services/pinecone/pinecone-service.js\";\nimport { Formatters } from \"./utils/formatters.js\";\nimport { validateSession } from \"./services/auth/token-validator.js\";\nimport { filterComponentsWithFrida } from \"./handlers/library-filter-handler.js\";\n\n// ============================================================================\n// VERSION INFO\n// ============================================================================\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\nconst require = createRequire(import.meta.url);\n// When running from dist/figma2frida.js, __dirname is dist/, so go up one level to find package.json\nconst packageJson = require(join(__dirname, \"../package.json\"));\nconst MCP_VERSION = packageJson.version;\nconst LOCAL_VERSION = \"1.0.1\";\n\n// Initial startup log (visible in development, hidden in production)\nlogger.info(`Figma2Frida MCP Server v${MCP_VERSION} (Server: ${LOCAL_VERSION}) [${ENVIRONMENT}]`);\nlogger.info(`Transport: ${process.env.HTTP_STREAM === \"true\" ? \"HTTP Stream\" : \"stdio\"}`);\nlogger.info(`Node.js: ${process.version}`);\n\n// ============================================================================\n// HARDCODED CONFIGURATION - Set process.env variables\n// ============================================================================\n\n\n// Pinecone Configuration\nprocess.env.PINECONE_INDEX = \"figma2frida\";\nprocess.env.PINECONE_MIN_SCORE = \"0.4\";\nprocess.env.PINECONE_TOP_K = \"12\";\nprocess.env.FRIDA_PINECONE_PROXY_URL = \"https://azf-frida-pinecone-proxy.azurewebsites.net\";\n\n// Frida AI Configuration\n// FRIDA_BEARER_TOKEN is set from session validation (see below)\n// Dev responses API (testing). Prod: https://frida.azure-api.net/frida-llm-api/v1/responses\n// process.env.FRIDA_API_URL = \"https://frida-llm-api-dev.azurewebsites.net/v1/responses\";\nprocess.env.FRIDA_API_URL = \"https://frida.azure-api.net/frida-llm-api/v1/responses\";\n// process.env.FRIDA_EMBEDDING_URL = \"https://frida-llm-api.azurewebsites.net/v1/embeddings\";\nprocess.env.FRIDA_EMBEDDING_URL = \"https://frida.azure-api.net/frida-llm-api/v1/embeddings\";\n\nprocess.env.FRIDA_EMBEDDING_MODEL = \"text-embedding-ada-002\";\nprocess.env.FRIDA_MODEL = \"gpt-5.1-codex\";\nprocess.env.FRIDA_MAX_TOKENS = \"12000\";\n\n// Server Configuration\nprocess.env.HTTP_STREAM = \"false\"; // Set to \"true\" for HTTP mode, \"false\" for stdio\nprocess.env.PORT = \"8080\";\n\n// Log configuration (only in debug mode - hide sensitive values in production)\nlogger.debug(`PINECONE_INDEX: ${process.env.PINECONE_INDEX}`);\nlogger.debug(`PINECONE_MIN_SCORE: ${process.env.PINECONE_MIN_SCORE}`);\nlogger.debug(`PINECONE_TOP_K: ${process.env.PINECONE_TOP_K}`);\nlogger.debug(`FRIDA_PINECONE_PROXY_URL: ${process.env.FRIDA_PINECONE_PROXY_URL}`);\nlogger.debug(`FRIDA_API_URL: ${process.env.FRIDA_API_URL}`);\nlogger.debug(`FRIDA_EMBEDDING_URL: ${process.env.FRIDA_EMBEDDING_URL}`);\nlogger.debug(`FRIDA_EMBEDDING_MODEL: ${process.env.FRIDA_EMBEDDING_MODEL}`);\nlogger.debug(`FRIDA_MODEL: ${process.env.FRIDA_MODEL}`);\nlogger.debug(`FRIDA_MAX_TOKENS: ${process.env.FRIDA_MAX_TOKENS}`);\nlogger.debug(`HTTP_STREAM: ${process.env.HTTP_STREAM}`);\nlogger.debug(`PORT: ${process.env.PORT}`);\nlogger.info(\"Configuration loaded\");\n\n// Parse command-line arguments - session token only\nconst argv = yargs(hideBin(process.argv))\n .option(\"session-token\", {\n type: \"string\",\n description: \"Session token for authentication\",\n demandOption: true,\n })\n .parseSync();\n\n// Validate session token from CLI\nconst SESSION_TOKEN = argv.sessionToken?.trim();\nif (!SESSION_TOKEN || SESSION_TOKEN === \"\") {\n logger.error(\"❌ SHUTDOWN: Invalid or missing --session-token.\");\n process.exit(1);\n}\n\n// ============================================================================\n// SESSION VALIDATION\n// ============================================================================\n// Validate session and retrieve config before proceeding\nlet PINECONE_NAMESPACE: string = \"\";\ntry {\n const session = await validateSession(SESSION_TOKEN);\n PINECONE_NAMESPACE = session.projectId;\n process.env.FRIDA_BEARER_TOKEN = session.llmopsApiKey;\n process.env.MCP_USER_EMAIL = session.email;\n process.env.MCP_USER_ID = session.userId;\n logger.info(`Authenticated as ${session.email}`);\n logger.debug(`PINECONE_NAMESPACE: ${PINECONE_NAMESPACE}`);\n logger.debug(`FRIDA_BEARER_TOKEN: ${session.llmopsApiKey.substring(0, 8)}... (hidden)`);\n} catch (error) {\n logger.error(\"❌ SHUTDOWN: Session validation failed. MCP server cannot start.\");\n process.exit(1);\n}\n\n// Read HTTP_STREAM and PORT from environment variables (.env file)\nconst HTTP_STREAM = process.env.HTTP_STREAM === \"true\" || process.env.HTTP_STREAM === \"1\";\nconst PORT = parseInt(process.env.PORT || \"8080\", 10);\n\n\nconst server = new FastMCP({\n instructions: `You are a Figma design developer. Use the available tools to analyze Figma designs.`,\n name: \"figma2frida_mcp\",\n version: MCP_VERSION,\n});\n\n// Initialize Figma MCP client\nlogger.debug(\"Initializing Figma Client...\");\nconst figmaClient = new FigmaClient(\"http://127.0.0.1:3845/sse\");\nlogger.debug(\"Figma Client object created\");\n\n// Connect to Figma MCP on startup\nlet figmaConnected = false;\nlogger.debug(\"Starting initial connection attempt to Figma MCP (non-blocking)...\");\n\nconst connectionStartTime = Date.now();\nfigmaClient\n .connect()\n .then(() => {\n const connectionTime = Date.now() - connectionStartTime;\n figmaConnected = true;\n logger.debug(`Connected to Figma MCP (${connectionTime}ms)`);\n })\n .catch((error) => {\n const connectionTime = Date.now() - connectionStartTime;\n logger.warn(`Failed to connect to Figma MCP (${connectionTime}ms)`);\n logger.debug(\"Error type:\", error?.constructor?.name || typeof error);\n logger.debug(\"Error message:\", error instanceof Error ? error.message : String(error));\n\n if (error && typeof error === 'object') {\n const errorObj = error as Record<string, unknown>;\n if ('code' in errorObj) {\n logger.debug(\"Error code:\", errorObj.code);\n }\n }\n\n if (error instanceof Error && error.stack) {\n logger.debug(\"Error stack:\", error.stack);\n }\n\n logger.warn(\"Make sure Figma Desktop is running with MCP enabled at http://127.0.0.1:3845/sse\");\n logger.debug(\"Tools will attempt to reconnect when called\");\n });\n\n\n// TOOL 1: Get Design Context (Design Data and Generated Code)\n// ============================================================================\n\nserver.addTool({\n name: \"analyze_design\",\n description: `Get design context from a Figma node including design data and generated code.\n\n**What this does:**\n- Fetches design data and generated code from Figma\n- Returns React/TypeScript code based on the Figma design\n- Includes design tokens and styling information\n\n**Output:**\n- Generated React/TypeScript code\n- Design tokens and styles\n- Design structure information\n\n**Usage:**\n- Set withLibrarySearch to enable component library search flow (default: false)\n\n**Input:**\njson\n{\n \"withLibrarySearch\": false\n}`,\n annotations: {\n title: \"Analyze Design\",\n readOnlyHint: true,\n openWorldHint: false,\n },\n parameters: z.object({\n withLibrarySearch: z\n .boolean()\n .optional()\n .default(false)\n .describe(\"Enable component library search flow (default: false). When true will trigger analyze_frame_extraction, when false call analyze_frame.\"),\n }),\n execute: async (args, _context) => {\n try {\n const withLibrarySearch = args.withLibrarySearch ?? false;\n logger.debug(`withLibrarySearch: ${withLibrarySearch}`);\n logger.debug(`figmaConnected flag: ${figmaConnected}`);\n\n if (!figmaConnected) {\n logger.warn(\"Early return: figmaConnected is false\");\n const result: ContentResult = {\n content: [{\n type: \"text\" as const,\n text: \"❌ Not connected to Figma MCP. Check logs for connection details.\"\n }],\n };\n return result;\n }\n\n logger.debug(\"Calling figmaClient.getDesignContext()...\");\n const designContext = await figmaClient.getDesignContext();\n\n if (!designContext.content || designContext.content.length === 0) {\n const result: ContentResult = {\n content: [{ type: \"text\" as const, text: \"❌ No design context returned\" }],\n };\n return result;\n }\n\n // Add mandatory workflow instruction - conditionally based on withLibrarySearch\n const workflowInstruction: Content = {\n type: \"text\" as const,\n text: `**MANDATORY NEXT STEP - YOU MUST COMPLETE:**\n\nAfter receiving this design context, you **MUST** call the tool ${withLibrarySearch ? '`analyze_frame_extraction`' : '`analyze_frame`'} to get the visual reference and keywords.\n`,\n };\n\n return {\n content: [...(designContext.content as Content[]), workflowInstruction],\n } as ContentResult;\n } catch (error) {\n logger.error(\"Failed to get design context:\", error instanceof Error ? error.message : String(error));\n const result: ContentResult = {\n content: [{\n type: \"text\" as const,\n text: `❌ Failed to get design context: ${error instanceof Error ? error.message : String(error)}`,\n }],\n };\n return result;\n }\n },\n});\n\n// TOOL 2: Get Screenshot (Visual Reference)\n// ============================================================================\n\nserver.addTool({\n name: \"analyze_frame\",\n description: `Get a screenshot of a Figma node for visual reference with UI element analysis.`,\n annotations: {\n title: \"Analyze Frame\",\n readOnlyHint: true,\n openWorldHint: false,\n },\n parameters: z.object({\n }),\n execute: async (_context) => {\n try {\n // logger.debug(`Tool called with nodeId: ${args.nodeId || 'current selection'}`);\n logger.debug(`figmaConnected flag: ${figmaConnected}`);\n\n if (!figmaConnected) {\n logger.warn(\"Early return: figmaConnected is false\");\n const result: ContentResult = {\n content: [{\n type: \"text\" as const,\n text: \"❌ Not connected to Figma MCP. Check logs for connection details.\"\n }],\n };\n return result;\n }\n\n logger.debug(\"Calling figmaClient.getScreenshot()...\");\n const screenshot = await figmaClient.getScreenshot();\n\n if (!screenshot.content || screenshot.content.length === 0) {\n const result: ContentResult = {\n content: [{ type: \"text\" as const, text: \"❌ No screenshot returned\" }],\n };\n return result;\n }\n\n // Add instruction for AI to analyze the image and provide UI elements list\n const analysisInstruction: Content = {\n type: \"text\" as const,\n text: `**Screenshot Retrieved**\n\nYou **MUST** analyze the screenshot image above and generate pixel perfect code to the Figma design.\n\n**Output:**\nGenerate complete, pixel perfect code that visually matches the screenshot with pixel-perfect accuracy. The generated code should be indistinguishable from the design when rendered.\n\n**What to Identify:**\n- **Interactive elements:** buttons, inputs, forms, dropdowns, checkboxes, radio buttons, switches, sliders, links\n- **Layout components:** cards, containers, headers, footers, navigation bars, sidebars, grids, columns\n- **Content elements:** text fields, labels, icons, images, badges, chips, avatars, dividers\n- **Form elements:** text inputs, textareas, select dropdowns, date pickers, file uploads\n- **Navigation:** menus, tabs, breadcrumbs, pagination, search bars\n- **Other:** modals, tooltips, alerts, notifications, toolbars, action bars\n`,\n };\n\n return {\n content: [analysisInstruction, ...(screenshot.content as Content[])],\n } as ContentResult;\n } catch (error) {\n logger.error(\"Failed to get screenshot:\", error instanceof Error ? error.message : String(error));\n const result: ContentResult = {\n content: [{\n type: \"text\" as const,\n text: `❌ Failed to get screenshot: ${error instanceof Error ? error.message : String(error)}`,\n }],\n };\n return result;\n }\n },\n});\n\n\n// ============================================================================\n// ============================================================================\n// CASE 2: FIGMA SUGGEST COMPONENTS\n// ============================================================================\n// ============================================================================\n\n// ============================================================================\n// TOOL 3: Figma Extract Components: Analyze All Extracted (Frame + Metadata + Design) and get components from library\n// From already having a screen I want to suggest components from the library that fit. Will call get_components_from_library.\n// ============================================================================\n\nserver.addTool({\n name: \"analyze_frame_extraction\",\n description: `Analyze all data from frame and extract to identify components and UI elements in parallel and return all results combined.\n\n**What this does:**\n- Executes tools 1 (screenshot), 2 (metadata), and 3 (design context) concurrently\n- Returns everything in one response: visual reference, structure, and generated code\n\n**Output:**\n- Keywords extracted from figma metadata and design context.\n\n**Input:**\njson\n{\n}\n`,\n annotations: {\n title: \"Analyze All Extracted\",\n readOnlyHint: true,\n openWorldHint: false,\n },\n parameters: z.object({\n }),\n execute: async ( _context) => {\n try {\n logger.debug(`figmaConnected flag: ${figmaConnected}`);\n\n if (!figmaConnected) {\n logger.warn(\"Early return: figmaConnected is false\");\n return {\n content: [{\n type: \"text\" as const,\n text: \"❌ Not connected to Figma MCP. Check logs for connection details.\"\n }],\n } as ContentResult;\n }\n\n\n const [screenshot, metadata, designContext] = await Promise.all([\n figmaClient.getScreenshot(),\n figmaClient.getMetadata(),\n figmaClient.getDesignContext(),\n ]);\n\n // Extract queries from metadata and design context\n const queryExtractor = new DesignQueryExtractor();\n\n // Extract query from metadata (using metadata-specific extraction)\n let metadataQuery = \"UI component\";\n try {\n // Use metadata-specific extraction method\n const metadataAsDesignContext = {\n content: metadata.content || []\n };\n metadataQuery = queryExtractor.extractQueryFromMetadata(metadataAsDesignContext);\n } catch (error) {\n logger.warn(\"Failed to extract query from metadata:\", error instanceof Error ? error.message : String(error));\n }\n\n // Extract query from design context\n let designContextQuery = \"UI component\";\n try {\n designContextQuery = queryExtractor.extractQuery(designContext, \"UI component\");\n } catch (error) {\n logger.warn(\"Failed to extract query from design context:\", error instanceof Error ? error.message : String(error));\n }\n\n const combined: Content[] = [];\n\n // Add screenshot first (needed for analysis)\n if (screenshot.content?.length) {\n combined.push(...(screenshot.content as Content[]));\n }\n\n // Add instruction to analyze screenshot and create description\n combined.push({\n type: \"text\" as const,\n text: `## 2. Frame Description\\n\\nYou **MUST** analyze the screenshot image above and identify all components and UI elements visible in the Figma frame.\\n\\n**What to Identify:**\\n- **Interactive elements:** buttons, inputs, forms, dropdowns, checkboxes, radio buttons, switches, sliders, links\\n- **Layout components:** cards, containers, headers, footers, navigation bars, sidebars, grids, columns\\n- **Content elements:** text fields, labels, icons, images, badges, chips, avatars, dividers\\n- **Form elements:** text inputs, textareas, select dropdowns, date pickers, file uploads\\n- **Navigation:** menus, tabs, breadcrumbs, pagination, search bars\\n- **Other:** modals, tooltips, alerts, notifications, toolbars, action bars.`,\n });\n\n combined.push({\n type: \"text\" as const,\n text: `\n**MANDATORY NEXT STEP — YOU MUST COMPLETE:**\n\nAfter receiving this analyze_frame_extraction output, you **MUST** call the tool \\`get_components_from_library\\` with a \\`query\\` that describes the UI elements, components, or patterns from the design above (a description of the components found in the UI\").\n\n**Required call:**\n\\`\\`\\`json\n{\n \"query\": \"your description query of the components and UI elements found in the UI. MANDATORY: MUST Include '${metadataQuery}' and '${designContextQuery}' \"\n}\n`,\n });\n\n return { content: combined } as ContentResult;\n } catch (error) {\n logger.error(\"analyze_frame_extraction failed:\", error instanceof Error ? error.message : String(error));\n return {\n content: [{\n type: \"text\" as const,\n text: `❌ analyze_frame_extraction failed: ${error instanceof Error ? error.message : String(error)}`,\n }],\n } as ContentResult;\n }\n },\n});\n\n// ============================================================================\n// TOOL 4: Get Components From Library BY Query\n// ============================================================================\n\nserver.addTool({\n name: \"get_components_from_library\",\n description: `Get components from library.`,\n annotations: {\n title: \"Get Components From Library\",\n readOnlyHint: true,\n openWorldHint: false,\n },\n parameters: z.object({\n query: z\n .string()\n .describe(\"User query text to search for components in the library.\"),\n }),\n execute: async (args, _context) => {\n try {\n logger.debug(\"get_components_from_library called\");\n logger.debug(`query: ${args.query}`);\n\n // Create PineconeSearchService instance with namespace\n const searchService = new PineconeSearchService({\n namespace: PINECONE_NAMESPACE,\n });\n\n // Search for components\n const searchResults = await searchService.search(args.query);\n\n // Filter components using Frida AI (if enabled)\n const { filteredResults } = await filterComponentsWithFrida({\n query: args.query,\n searchResults,\n });\n\n // Format results using Formatters\n const formattedResults = Formatters.toMarkdown(filteredResults);\n\n return {\n content: [\n {\n type: \"text\" as const,\n text: formattedResults,\n },\n ],\n };\n } catch (error) {\n logger.error(\"get_components_from_library error:\", error);\n return {\n content: [\n {\n type: \"text\" as const,\n text: `❌ Error: ${error instanceof Error ? error.message : String(error)}`,\n },\n ],\n };\n }\n },\n});\n\n\n// ============================================================================\n// ============================================================================\n// CASE 3: IMPROVE LAYOUT AND DESIGN\n// ============================================================================\n// ============================================================================\n\n// ============================================================================\n// TOOL: Improve Layout — Screenshot + refine generated code to match frame UI\n// ============================================================================\n\n// server.addTool({\n// name: \"improve_layout\",\n// description: `Get a screenshot of the Figma frame and improve the already generated code to look more like the frame UI.\n\n// **What this does:**\n// - Returns the screenshot image of the selected Figma node\n// - Instructs you to refine the existing generated code so it visually matches the frame better (spacing, alignment, typography, colors, etc.)\n\n// **When to use:**\n// - After you have generated code from \\`analyze_design\\` or \\`analyze_frame_extraction\\`\n// - When the output doesn't quite match the Figma design and you want to improve it\n\n// **Output:**\n// - Screenshot image\n// - Instruction to improve the code to match the frame UI\n\n// **Usage:**\n// - Provide a nodeId (e.g., \"315-2920\") or leave empty for current Figma selection\n\n// **Example:**\n// \\`\\`\\`json\n// {\n// \"nodeId\": \"315-2920\"\n// }\n// \\`\\`\\``,\n// annotations: {\n// title: \"Improve Layout\",\n// readOnlyHint: true,\n// openWorldHint: false,\n// },\n// parameters: z.object({\n// nodeId: z\n// .string()\n// .optional()\n// .describe('Figma node ID (e.g., \"315-2920\"). Leave empty for current selection.'),\n// }),\n// execute: async (args, _context) => {\n// try {\n// logger.debug(`improve_layout called with nodeId: ${args.nodeId ?? \"current selection\"}`);\n// logger.debug(`figmaConnected flag: ${figmaConnected}`);\n\n// if (!figmaConnected) {\n// logger.warn(\"Early return: figmaConnected is false\");\n// return {\n// content: [{\n// type: \"text\" as const,\n// text: \"❌ Not connected to Figma MCP. Check logs for connection details.\",\n// }],\n// } as ContentResult;\n// }\n\n// logger.debug(\"Calling figmaClient.getScreenshot() for improve_layout...\");\n// const screenshot = await figmaClient.getScreenshot(args.nodeId);\n\n// if (!screenshot.content || screenshot.content.length === 0) {\n// return {\n// content: [{ type: \"text\" as const, text: \"❌ No screenshot returned\" }],\n// } as ContentResult;\n// }\n\n// const instruction: Content = {\n// type: \"text\" as const,\n// text: `**Improve Layout**\n\n// You **MUST** use the screenshot image above as the visual reference. Improve the already generated code so it looks more like the frame UI.\n\n// **What to refine:**\n// - Spacing, padding, and margins\n// - Alignment and layout\n// - Typography (font sizes, weights, line height)\n// - Colors and contrast\n// - Border radius, shadows, and other visual details\n// - Any mismatch between the code output and the Figma design\n\n// Output the improved code.`,\n// };\n\n// return {\n// content: [instruction, ...(screenshot.content as Content[])],\n// } as ContentResult;\n// } catch (error) {\n// logger.error(\"improve_layout failed:\", error instanceof Error ? error.message : String(error));\n// return {\n// content: [{\n// type: \"text\" as const,\n// text: `❌ improve_layout failed: ${error instanceof Error ? error.message : String(error)}`,\n// }],\n// } as ContentResult;\n// }\n// },\n// });\n\n\n\n// ============================================================================\n// Start Server\n// ============================================================================\n\nif (HTTP_STREAM) {\n server.start({\n httpStream: {\n port: PORT,\n },\n transportType: \"httpStream\",\n });\n\n logger.info(\"Figma Proxy MCP Server running on HTTP Stream!\");\n logger.info(`Endpoint: http://localhost:${PORT}/mcp`);\n logger.debug(`Pinecone Namespace: ${PINECONE_NAMESPACE}`);\n logger.debug(`\nTest with curl:\ncurl -X POST http://localhost:${PORT}/mcp \\\\\n -H \"Content-Type: application/json\" \\\\\n -d '{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"tools/list\",\"params\":{}}'\n`);\n} else {\n server.start({ transportType: \"stdio\" });\n logger.info(\"Started with stdio transport (for MCP clients)\");\n}\n","/**\n * Structured Logger Utility\n * Provides leveled logging with environment-based filtering\n * \n * IMPORTANT: In stdio mode, all logs must go to stderr to avoid interfering\n * with MCP's JSON-RPC protocol on stdout.\n */\n\nenum LogLevel {\n DEBUG = 0,\n INFO = 1,\n WARN = 2,\n ERROR = 3,\n SILENT = 4,\n}\n\n/**\n * Gets the current log level dynamically.\n * This ensures it picks up changes to process.env.NODE_ENV made after import\n * (solving ESM hoisting issues).\n */\nfunction getLogLevel(): LogLevel {\n const isVerbose = process.argv.includes(\"--verbose\") || process.env.DEBUG === \"true\";\n const isProduction = process.env.NODE_ENV === \"production\";\n\n if (isProduction && !isVerbose) {\n return LogLevel.SILENT; // Production: No logs at all\n }\n \n // Development or Verbose: Show everything\n return LogLevel.DEBUG; \n}\n\n// Detect if we're in stdio mode (MCP uses stdout for JSON-RPC)\n// HTTP_STREAM is set in process.env before this module loads\nconst isStdioMode = process.env.HTTP_STREAM !== \"true\" && process.env.HTTP_STREAM !== \"1\";\n\n// Helper to write to stderr in stdio mode, stdout otherwise\nconst writeToLog = (level: string, message: string, ...args: any[]) => {\n const fullMessage = args.length > 0 \n ? `[${level}] ${message} ${args.map(arg => typeof arg === 'object' ? JSON.stringify(arg) : String(arg)).join(' ')}`\n : `[${level}] ${message}`;\n \n if (isStdioMode) {\n process.stderr.write(`${fullMessage}\\n`);\n } else {\n console.log(fullMessage);\n }\n};\n\nexport const logger = {\n debug: (message: string, ...args: any[]) => {\n if (getLogLevel() <= LogLevel.DEBUG) {\n writeToLog(\"DEBUG\", message, ...args);\n }\n },\n info: (message: string, ...args: any[]) => {\n if (getLogLevel() <= LogLevel.INFO) {\n writeToLog(\"INFO\", message, ...args);\n }\n },\n warn: (message: string, ...args: any[]) => {\n if (getLogLevel() <= LogLevel.WARN) {\n writeToLog(\"WARN\", message, ...args);\n }\n },\n error: (message: string, ...args: any[]) => {\n if (getLogLevel() <= LogLevel.ERROR) {\n writeToLog(\"ERROR\", message, ...args);\n }\n },\n};\n\n","/**\n * Figma MCP Client Wrapper\n * Connects to official Figma Desktop MCP via SSE\n */\n\nimport { Client } from \"@modelcontextprotocol/sdk/client/index.js\";\nimport { SSEClientTransport } from \"@modelcontextprotocol/sdk/client/sse.js\";\nimport { logger } from \"../utils/logger.js\";\n\nexport interface FigmaDesignContextResult {\n content: Array<{\n type: string;\n text?: string;\n [key: string]: unknown;\n }>;\n}\n\nexport interface FigmaScreenshotResult {\n content: Array<{\n type: string;\n data?: string;\n mimeType?: string;\n [key: string]: unknown;\n }>;\n}\n\nexport interface FigmaMetadataResult {\n content: Array<{\n type: string;\n text?: string;\n [key: string]: unknown;\n }>;\n}\n\n/**\n * Client for communicating with official Figma Desktop MCP\n */\nexport class FigmaClient {\n private client: Client | null = null;\n private connected: boolean = false;\n private figmaUrl: string;\n\n constructor(figmaUrl: string = \"http://127.0.0.1:3845/sse\") {\n this.figmaUrl = figmaUrl;\n }\n\n /**\n * Connect to Figma MCP server\n */\n async connect(retries: number = 3): Promise<void> {\n if (this.connected && this.client) {\n logger.debug(\"Already connected, skipping connection attempt\");\n return;\n }\n\n logger.debug(\"Starting connection attempt\");\n logger.debug(`URL: ${this.figmaUrl}`);\n logger.debug(`Max retries: ${retries}`);\n logger.debug(`Current status: connected=${this.connected}, client=${!!this.client}`);\n\n for (let attempt = 0; attempt < retries; attempt++) {\n const attemptStartTime = Date.now();\n logger.debug(`Attempt ${attempt + 1}/${retries} starting...`);\n\n try {\n logger.debug(\"Creating MCP Client object...\");\n this.client = new Client(\n {\n name: \"figma-proxy-client\",\n version: \"1.0.0\",\n },\n {\n capabilities: {\n tools: {},\n },\n },\n );\n logger.debug(\"Client object created\");\n\n logger.debug(`Creating SSE Transport for: ${this.figmaUrl}`);\n const transport = new SSEClientTransport(new URL(this.figmaUrl));\n logger.debug(\"Transport object created\");\n\n logger.debug(\"Attempting to connect...\");\n const connectStartTime = Date.now();\n await this.client.connect(transport);\n const connectTime = Date.now() - connectStartTime;\n logger.debug(`Connection established in ${connectTime}ms`);\n\n this.connected = true;\n const totalTime = Date.now() - attemptStartTime;\n\n logger.debug(`Connected to Figma MCP (${totalTime}ms)`);\n return;\n } catch (error) {\n const attemptTime = Date.now() - attemptStartTime;\n logger.debug(`Connection attempt ${attempt + 1}/${retries} FAILED (${attemptTime}ms)`);\n logger.debug(`Error type: ${error?.constructor?.name || typeof error}`);\n logger.debug(`Error message: ${error instanceof Error ? error.message : String(error)}`);\n\n // Log additional error properties if available\n if (error && typeof error === 'object') {\n const errorObj = error as Record<string, unknown>;\n if ('code' in errorObj) {\n logger.debug(`Error code: ${errorObj.code}`);\n }\n if ('cause' in errorObj) {\n logger.debug(\"Error cause:\", errorObj.cause);\n }\n if ('status' in errorObj) {\n logger.debug(`HTTP status: ${errorObj.status}`);\n }\n if ('statusText' in errorObj) {\n logger.debug(`HTTP status text: ${errorObj.statusText}`);\n }\n }\n\n if (error instanceof Error && error.stack) {\n logger.debug(\"Error stack:\", error.stack);\n }\n\n if (attempt === retries - 1) {\n logger.error(`All connection attempts failed (${retries} attempts)`);\n logger.error(`URL: ${this.figmaUrl}`);\n throw new Error(\n `Failed to connect to Figma MCP at ${this.figmaUrl} after ${retries} attempts. Make sure Figma Desktop is running with MCP enabled.`,\n );\n }\n\n const waitTime = 1000 * (attempt + 1);\n logger.debug(`Waiting ${waitTime}ms before retry...`);\n // Wait before retry (exponential backoff)\n await new Promise((resolve) =>\n setTimeout(resolve, waitTime),\n );\n logger.debug(\"Wait complete, retrying...\");\n }\n }\n }\n\n /**\n * Ensure connection is established\n */\n private async ensureConnected(): Promise<void> {\n if (!this.connected || !this.client) {\n logger.debug(\"ensureConnected() called - not connected, attempting connection...\");\n await this.connect();\n } else {\n logger.debug(\"ensureConnected() called - already connected, skipping\");\n }\n }\n\n /**\n * Normalize nodeId format: convert \"XXXX-XXXX\" to \"XXXX:XXXX\" for Figma MCP compatibility\n */\n private normalizeNodeId(nodeId?: string): string | undefined {\n if (!nodeId) return undefined;\n // Convert dash format to colon format (e.g., \"315-2920\" -> \"315:2920\")\n return nodeId.replace(/-/g, \":\");\n }\n\n /**\n * Call Figma's get_design_context tool\n */\n async getDesignContext(\n ): Promise<FigmaDesignContextResult> {\n await this.ensureConnected();\n\n\n const args = {\n // nodeId: undefined to use frame current selection,\n clientLanguages: \"typescript\",\n clientFrameworks: \"react\",\n forceCode: true,\n };\n\n logger.debug(\"Calling get_design_context with args:\", args);\n\n try {\n const result = await this.client!.callTool({\n name: \"get_design_context\",\n arguments: args,\n });\n\n // Filter content to only return items at index 0 (code) , 1 (rules to use and ignore) and 3 (design tokens)\n // Note: Figma returns 4 items total, but we only need these three for our workflow\n const parsedResult = result as FigmaDesignContextResult;\n if (parsedResult.content && Array.isArray(parsedResult.content)) {\n const filteredContent = [\n parsedResult.content[0], // Item 0: Generated React code\n parsedResult.content[1], // Item 1: Rules to Use and Ignore\n parsedResult.content[3], // Item 3: Design tokens/styles\n ].filter((item) => item !== undefined); // Remove undefined if index doesn't exist\n\n return {\n content: filteredContent,\n };\n }\n\n return parsedResult;\n } catch (error) {\n // Try reconnecting once on error\n logger.warn(\"Error calling get_design_context, attempting reconnect...\");\n this.connected = false;\n await this.connect();\n\n const result = await this.client!.callTool({\n name: \"get_design_context\",\n arguments: args\n });\n\n return result as FigmaDesignContextResult;\n }\n }\n\n /**\n * Call Figma's get_metadata tool to get actual node structure\n */\n async getMetadata(\n ): Promise<FigmaMetadataResult> {\n await this.ensureConnected();\n\n const args = {\n // nodeId: undefined to use frame current selection,\n clientLanguages: \"typescript\",\n clientFrameworks: \"react\",\n forceCode: true,\n };\n\n logger.debug(\"Calling get_metadata with args:\", args);\n\n try {\n const result = await this.client!.callTool({\n name: \"get_metadata\",\n arguments: args,\n });\n\n // Filter content to only return items at index 0 (raw metadata) \n // Note: Figma returns 4 items total, but we only need these three for our workflow\n const parsedResult = result as FigmaDesignContextResult;\n if (parsedResult.content && Array.isArray(parsedResult.content)) {\n const filteredContent = [\n parsedResult.content[0], // Item 0: Metadata Raw\n ].filter((item) => item !== undefined); // Remove undefined if index doesn't exist\n\n return {\n content: filteredContent,\n };\n }\n\n return parsedResult;\n } catch (error) {\n // Try reconnecting once on error\n logger.warn(\"Error calling get_metadata, attempting reconnect...\");\n this.connected = false;\n await this.connect();\n\n const result = await this.client!.callTool({\n name: \"get_metadata\",\n arguments: args,\n });\n\n return result as FigmaMetadataResult;\n }\n }\n\n /**\n * Call Figma's get_screenshot tool\n * Note: clientLanguages and clientFrameworks are not needed for screenshots\n * (only required for get_design_context which generates code)\n */\n async getScreenshot(\n ): Promise<FigmaScreenshotResult> {\n await this.ensureConnected();\n\n // Normalize nodeId format for Figma MCP compatibility\n\n try {\n const result = await this.client!.callTool({\n name: \"get_screenshot\",\n arguments: {\n // nodeId: undefined to use frame current selection,\n },\n });\n\n return result as FigmaScreenshotResult;\n } catch (error) {\n // Try reconnecting once on error\n logger.warn(\"Error calling get_screenshot, attempting reconnect...\");\n this.connected = false;\n await this.connect();\n\n const result = await this.client!.callTool({\n name: \"get_screenshot\",\n arguments: {\n // nodeId: undefined,\n },\n });\n\n return result as FigmaScreenshotResult;\n }\n }\n\n /**\n * Close connection\n */\n async disconnect(): Promise<void> {\n if (this.client) {\n await this.client.close();\n this.connected = false;\n this.client = null;\n logger.debug(\"Disconnected from Figma MCP\");\n }\n }\n}\n\n","/**\n * Metadata Extractor (Simpler)\n *\n * Extracts ALL `name=\"...\"` / `name='...'` attribute values from the Figma\n * metadata XML-like text and returns them as a list.\n *\n * This is intentionally minimal (no heuristics, no categorization).\n */\nexport class MetadataExtractorSimpler {\n /**\n * Returns every `name=` attribute value in appearance order.\n * Automatically removes exact duplicates (case-sensitive) while preserving first-seen order.\n *\n * Example match:\n * `<frame id=\"28:2524\" name=\"Referral/New 1.1\" ...>`\n * ^^^^^^^^^^^^^^^\n */\n extractNames(metadataText: string): string[] {\n if (!metadataText) return [];\n\n const names: string[] = [];\n const seen = new Set<string>();\n const matches = metadataText.matchAll(/\\bname\\s*=\\s*([\"'])(.*?)\\1/gi);\n\n for (const match of matches) {\n const raw = match[2];\n const name = typeof raw === \"string\" ? raw.trim() : \"\";\n \n // Only add if not empty and not already seen (exact duplicate check)\n if (name && !seen.has(name)) {\n seen.add(name);\n names.push(name);\n }\n }\n\n return names;\n }\n}\n\n","/**\n * Design Context Extractor\n * Extracts component information from Figma design context (code + tokens)\n */\n\nimport type { ComponentDescriptor } from \"./types.js\";\n\nexport class DesignContextExtractor {\n /**\n * Extract semantic information from JSX/HTML code and design tokens\n */\n extractFromCodeAndTokens(code: string, tokens: string, descriptor: ComponentDescriptor): void {\n // Extract from code section\n this.extractFromCode(code, descriptor);\n\n // Extract from design tokens\n this.extractFromTokens(tokens, descriptor);\n }\n\n /**\n * Extract semantic information from JSX/HTML code\n */\n private extractFromCode(code: string, descriptor: ComponentDescriptor): void {\n // Extract all data-name attributes to understand component structure\n const dataNameMatches = code.matchAll(/data-name=[\"']([^\"']+)[\"']/gi);\n const dataNames: string[] = [];\n \n for (const match of dataNameMatches) {\n const name = match[1].trim();\n if (name && name.length > 0) {\n dataNames.push(name.toLowerCase());\n }\n }\n\n // Track primary component (usually the first/root data-name)\n const primaryDataName = dataNames[0] || \"\";\n\n // 1. EXTRACT HIERARCHY from data-name structure\n this.extractHierarchy(dataNames, descriptor);\n\n // 2. IDENTIFY ALL COMPONENT TYPES from data-names and elements\n this.identifyComponents(code, dataNames, descriptor);\n\n // 3. DETERMINE PURPOSE from primary component and text content\n this.determinePurpose(code, primaryDataName, descriptor);\n\n // 4. EXTRACT VISUAL CHARACTERISTICS\n this.extractVisualTraits(code, dataNames, descriptor);\n\n // 5. EXTRACT LAYOUT PATTERNS\n this.extractLayoutPatterns(code, descriptor);\n\n // 6. DETECT INTERACTIONS\n this.detectInteractions(code, descriptor);\n\n // 7. EXTRACT REACT PROPS AND STATE\n this.extractReactPropsAndState(code, descriptor);\n\n // 8. EXTRACT SIZE AND SPACING PATTERNS\n this.extractSizeAndSpacing(code, descriptor);\n\n // 9. EXTRACT BORDER AND STYLING PATTERNS\n this.extractBorderAndStyling(code, descriptor);\n\n // 10. EXTRACT ADDITIONAL KEYWORDS\n this.extractKeywords(code, dataNames, descriptor);\n }\n\n /**\n * Extract hierarchy structure from data-name attributes\n * Identifies structural parts like Header, Body, Footer, Container, etc.\n */\n private extractHierarchy(dataNames: string[], descriptor: ComponentDescriptor): void {\n const hierarchyKeywords = [\n 'header', 'footer', 'body', 'container', 'content', 'wrapper',\n 'main', 'sidebar', 'nav', 'navigation', 'section', 'panel',\n 'card', 'tile', 'box', 'frame', 'group', 'stack', 'row', 'column',\n 'top'\n ];\n\n for (const name of dataNames) {\n const lowerName = name.toLowerCase();\n \n // Check if this data-name represents a structural part\n for (const keyword of hierarchyKeywords) {\n if (lowerName.includes(keyword)) {\n // Normalize to common terms\n if (keyword === 'nav' || keyword === 'navigation') {\n if (!descriptor.hierarchy.includes('navigation')) {\n descriptor.hierarchy.push('navigation');\n }\n } else if (keyword === 'content' || keyword === 'wrapper' || keyword === 'container') {\n if (!descriptor.hierarchy.includes('container')) {\n descriptor.hierarchy.push('container');\n }\n } else if (keyword === 'section' || keyword === 'panel') {\n if (!descriptor.hierarchy.includes('section')) {\n descriptor.hierarchy.push('section');\n }\n } else if (!descriptor.hierarchy.includes(keyword)) {\n descriptor.hierarchy.push(keyword);\n }\n break;\n }\n }\n }\n }\n\n /**\n * Identify all component types in the design\n */\n private identifyComponents(code: string, dataNames: string[], descriptor: ComponentDescriptor): void {\n const allText = code.toLowerCase() + \" \" + dataNames.join(\" \");\n\n // Extract React component/function names (e.g., \"function SearchInput\", \"const Button =\")\n const functionMatches = code.matchAll(/(?:function|const|export\\s+(?:default\\s+)?function)\\s+([A-Z][a-zA-Z0-9]*)/g);\n const componentNames: string[] = [];\n for (const match of functionMatches) {\n if (match[1]) componentNames.push(match[1].toLowerCase());\n }\n const componentNamesText = componentNames.join(\" \");\n\n // Combine all text for analysis\n const combinedText = allText + \" \" + componentNamesText;\n\n // Modal/Dialog/Overlay\n if (/modal|dialog|popup|overlay|sheet|drawer/i.test(combinedText)) {\n descriptor.components.add(\"modal\");\n }\n\n // Buttons - check component names, HTML tags, and data-names\n if (/<button/i.test(code) || /button|btn/i.test(combinedText)) {\n // Check for icon button first (more specific)\n if (/icon.*button|button.*icon|<button[^>]*>.*<img|<button[^>]*>.*<svg|<button[^>]*>.*icon/i.test(code) ||\n /showicon|iconbutton/i.test(combinedText)) {\n descriptor.components.add(\"icon button\");\n } else {\n descriptor.components.add(\"button\");\n }\n }\n\n // Form Inputs - check component names (e.g., SearchInput, TextInput), HTML tags, and data-names\n if (/<input/i.test(code) || /input|textfield|text.?field|searchinput|textinput/i.test(combinedText)) {\n descriptor.components.add(\"input\");\n // Check if it's a search input\n if (/search/i.test(combinedText) || /data-name.*search/i.test(code)) {\n descriptor.keywords.push(\"search\");\n descriptor.purpose = \"search interface\";\n }\n }\n if (/<textarea/i.test(code) || /textarea|text.?area/i.test(allText)) {\n descriptor.components.add(\"textarea\");\n }\n if (/<select/i.test(code) || /dropdown|select|picker|combobox/i.test(allText)) {\n descriptor.components.add(\"dropdown\");\n }\n if (/type=[\"']checkbox/i.test(code) || /checkbox|check.?box/i.test(allText)) {\n descriptor.components.add(\"checkbox\");\n }\n if (/type=[\"']radio/i.test(code) || /radio|radio.?button/i.test(allText)) {\n descriptor.components.add(\"radio\");\n }\n if (/switch|toggle/i.test(allText)) {\n descriptor.components.add(\"switch\");\n }\n if (/slider|range/i.test(allText)) {\n descriptor.components.add(\"slider\");\n }\n\n // Navigation - only detect if actual navbar/navigation element exists\n if (/<nav|<Navbar|navbar|nav.?bar|navigation.?bar|app.?bar/i.test(code)) {\n descriptor.components.add(\"navbar\");\n }\n if (/sidebar|side.?bar|side.?nav|drawer/i.test(allText)) {\n descriptor.components.add(\"sidebar\");\n }\n if (/breadcrumb|breadcrumbs|bread.?crumb/i.test(allText)) {\n descriptor.components.add(\"breadcrumb\");\n }\n if (/tab|tabs|tab.?bar|tab.?navigation/i.test(allText)) {\n descriptor.components.add(\"tabs\");\n }\n if (/menu|dropdown.?menu|context.?menu/i.test(allText)) {\n descriptor.components.add(\"menu\");\n }\n if (/pagination|pager|page.?navigation/i.test(allText)) {\n descriptor.components.add(\"pagination\");\n }\n\n // Data Display\n if (/<table|<tr|<td|<th/i.test(code) || /table|data.?table|grid.?table/i.test(allText)) {\n descriptor.components.add(\"table\");\n }\n if (/card|panel|tile/i.test(allText)) {\n descriptor.components.add(\"card\");\n }\n if (/list|list.?item/i.test(allText)) {\n descriptor.components.add(\"list\");\n }\n if (/grid|grid.?layout/i.test(allText)) {\n descriptor.components.add(\"grid\");\n }\n if (/calendar|date.?picker|date.?calendar/i.test(allText)) {\n descriptor.components.add(\"calendar\");\n }\n if (/chart|graph|visualization/i.test(allText)) {\n descriptor.components.add(\"chart\");\n }\n\n // Feedback\n if (/alert|notification|banner|message/i.test(allText)) {\n descriptor.components.add(\"alert\");\n }\n if (/badge|label|tag|chip/i.test(allText)) {\n descriptor.components.add(\"badge\");\n }\n if (/tooltip|popover|tip/i.test(allText)) {\n descriptor.components.add(\"tooltip\");\n }\n if (/progress|loader|spinner|loading/i.test(allText)) {\n descriptor.components.add(\"progress\");\n }\n if (/toast|snackbar/i.test(allText)) {\n descriptor.components.add(\"toast\");\n }\n\n // Layout - only detect if actual header/footer elements exist (not just data-name labels)\n if (/<header|<Header/i.test(code) || \n (/page.?header|site.?header|main.?header/i.test(allText) && !/data-name.*header/i.test(code))) {\n descriptor.components.add(\"header\");\n }\n if (/<footer|<Footer/i.test(code) || \n (/page.?footer|site.?footer|main.?footer/i.test(allText) && !/data-name.*footer/i.test(code))) {\n descriptor.components.add(\"footer\");\n }\n\n // Specialized\n if (/avatar|profile.?picture|user.?image/i.test(allText)) {\n descriptor.components.add(\"avatar\");\n }\n if (/stepper|steps|wizard/i.test(allText)) {\n descriptor.components.add(\"stepper\");\n }\n if (/accordion|collapsible|expandable/i.test(allText)) {\n descriptor.components.add(\"accordion\");\n }\n if (/carousel|slider|slideshow/i.test(allText)) {\n descriptor.components.add(\"carousel\");\n }\n if (/segmented.?control|segment/i.test(allText)) {\n descriptor.components.add(\"segmented control\");\n }\n }\n\n /**\n * Determine overall purpose of the design\n */\n private determinePurpose(code: string, primaryName: string, descriptor: ComponentDescriptor): void {\n const combinedText = (code + \" \" + primaryName).toLowerCase();\n\n // Action purposes\n if (/delete|remove|borrar/i.test(combinedText)) {\n descriptor.purpose = \"delete confirmation\";\n } else if (/edit|modify|change|update/i.test(combinedText)) {\n descriptor.purpose = \"edit form\";\n } else if (/create|new|add/i.test(combinedText)) {\n descriptor.purpose = \"create form\";\n } else if (/save|submit|apply/i.test(combinedText)) {\n descriptor.purpose = \"submit form\";\n } else if (/search|find|query/i.test(combinedText)) {\n descriptor.purpose = \"search interface\";\n } else if (/filter|sort|organize/i.test(combinedText)) {\n descriptor.purpose = \"data filtering\";\n } else if (/login|signin|sign.in|authenticate/i.test(combinedText)) {\n descriptor.purpose = \"authentication\";\n } else if (/register|signup|sign.up/i.test(combinedText)) {\n descriptor.purpose = \"registration\";\n } else if (/dashboard|overview|summary/i.test(combinedText)) {\n descriptor.purpose = \"dashboard\";\n } else if (/warning|alert|caution/i.test(combinedText)) {\n descriptor.purpose = \"warning\";\n } else if (/error|fail|problem/i.test(combinedText)) {\n descriptor.purpose = \"error\";\n } else if (/success|complete|done/i.test(combinedText)) {\n descriptor.purpose = \"success\";\n }\n }\n\n /**\n * Extract visual characteristics\n */\n private extractVisualTraits(code: string, dataNames: string[], descriptor: ComponentDescriptor): void {\n const allText = code.toLowerCase() + \" \" + dataNames.join(\" \");\n\n // Check data-names specifically for icon types (e.g., \"Info icon\", \"Search icon\")\n for (const dataName of dataNames) {\n const lowerDataName = dataName.toLowerCase();\n if (/icon/i.test(lowerDataName)) {\n if (/info|information/i.test(lowerDataName)) {\n descriptor.visual.push(\"info icon\");\n descriptor.keywords.push(\"info icon\");\n } else if (/search|magnify/i.test(lowerDataName)) {\n descriptor.visual.push(\"search icon\");\n descriptor.keywords.push(\"search icon\");\n } else if (/warning|alert|caution/i.test(lowerDataName)) {\n descriptor.visual.push(\"warning icon\");\n } else if (/success|check|confirm/i.test(lowerDataName)) {\n descriptor.visual.push(\"success icon\");\n } else if (/error|danger/i.test(lowerDataName)) {\n descriptor.visual.push(\"error icon\");\n } else if (/close|exit|dismiss/i.test(lowerDataName)) {\n descriptor.visual.push(\"close icon\");\n }\n }\n }\n\n // Icons from general patterns\n if (/icon|svg/i.test(allText)) {\n if (/warning|alert|caution/i.test(allText)) {\n descriptor.visual.push(\"warning icon\");\n }\n if (/close|exit|dismiss|×|cancel/i.test(allText)) {\n descriptor.visual.push(\"close icon\");\n }\n if (/success|check|confirm|✓/i.test(allText)) {\n descriptor.visual.push(\"success icon\");\n }\n if (/error|danger|problem|×/i.test(allText)) {\n descriptor.visual.push(\"error icon\");\n }\n if (/info|information|help|\\?/i.test(allText)) {\n descriptor.visual.push(\"info icon\");\n }\n if (/search|magnify|🔍/i.test(allText)) {\n descriptor.visual.push(\"search icon\");\n }\n }\n\n // Images\n if (/<img|<image/i.test(code) || /image|picture|photo|imgDash|imgAvatar/i.test(allText)) {\n descriptor.visual.push(\"image\");\n }\n\n // Check for field/container patterns (indicates form input structure)\n if (/field.*container|input.*container|search.*text/i.test(allText)) {\n descriptor.keywords.push(\"input field\");\n }\n }\n\n /**\n * Extract layout patterns from styling\n */\n private extractLayoutPatterns(code: string, descriptor: ComponentDescriptor): void {\n // Flex layouts\n if (/flex-col|flex.col/i.test(code) && /items-center|justify-center/i.test(code)) {\n descriptor.layout.push(\"centered vertical\");\n } else if (/flex-row/i.test(code) && /items-center|justify-center/i.test(code)) {\n descriptor.layout.push(\"centered horizontal\");\n } else if (/flex/i.test(code)) {\n descriptor.layout.push(\"flex layout\");\n }\n\n // Grid layouts\n if (/grid-cols|grid.cols/i.test(code)) {\n descriptor.layout.push(\"grid layout\");\n }\n\n // Visual effects\n if (/rounded-\\[?[0-9]/i.test(code) || /rounded-(?:sm|md|lg|xl|full)/i.test(code)) {\n descriptor.layout.push(\"rounded\");\n }\n \n if (/shadow-\\[/i.test(code) || /shadow-(?:sm|md|lg|xl|2xl)/i.test(code)) {\n descriptor.layout.push(\"elevated\");\n }\n\n // Responsive indicators\n if (/responsive|mobile|desktop|tablet/i.test(code)) {\n descriptor.layout.push(\"responsive\");\n }\n }\n\n /**\n * Detect interaction patterns\n */\n private detectInteractions(code: string, descriptor: ComponentDescriptor): void {\n const lowerCode = code.toLowerCase();\n\n // Dialog interactions\n if (descriptor.components.has(\"modal\")) {\n if (/confirm|yes|no|ok|cancel/i.test(code)) {\n descriptor.interactions.add(\"confirmation\");\n }\n if (/dismiss|close|exit/i.test(code)) {\n descriptor.interactions.add(\"dismissible\");\n }\n }\n\n // Form interactions\n if (descriptor.components.has(\"input\") || descriptor.components.has(\"button\")) {\n if (/submit|save|send|apply/i.test(lowerCode)) {\n descriptor.interactions.add(\"form submission\");\n }\n if (/validate|validation|error|required/i.test(lowerCode)) {\n descriptor.interactions.add(\"validation\");\n }\n }\n\n // Navigation interactions\n if (descriptor.components.has(\"tabs\") || descriptor.components.has(\"menu\")) {\n descriptor.interactions.add(\"navigation\");\n }\n\n // Data interactions\n if (descriptor.components.has(\"table\") || descriptor.components.has(\"list\")) {\n if (/sort|filter|search/i.test(lowerCode)) {\n descriptor.interactions.add(\"data manipulation\");\n }\n if (/select|checkbox|radio/i.test(lowerCode)) {\n descriptor.interactions.add(\"selection\");\n }\n }\n }\n\n /**\n * Extract React props and TypeScript state types\n */\n private extractReactPropsAndState(code: string, descriptor: ComponentDescriptor): void {\n // Extract TypeScript interface/type definitions\n const interfaceMatches = code.matchAll(/(?:interface|type)\\s+(\\w+Props)\\s*\\{/gi);\n for (const match of interfaceMatches) {\n const interfaceName = match[1].toLowerCase();\n if (/input|search|field/i.test(interfaceName)) {\n descriptor.components.add(\"input\");\n }\n if (/button/i.test(interfaceName)) {\n descriptor.components.add(\"button\");\n }\n if (/modal|dialog/i.test(interfaceName)) {\n descriptor.components.add(\"modal\");\n }\n }\n\n // Extract props that indicate features\n if (/showLabel|showlabel/i.test(code)) {\n descriptor.keywords.push(\"label\");\n }\n if (/showInfoIcon|showinfoicon|showInfo|showinfo/i.test(code)) {\n descriptor.keywords.push(\"info icon\");\n descriptor.visual.push(\"info icon\");\n }\n if (/showHelper|showhelper|helperText|helpertext/i.test(code)) {\n descriptor.keywords.push(\"helper\");\n descriptor.keywords.push(\"helper text\");\n }\n if (/showIcon|showicon/i.test(code)) {\n descriptor.keywords.push(\"icon\");\n }\n if (/showSearch|showsearch/i.test(code)) {\n descriptor.keywords.push(\"search\");\n descriptor.keywords.push(\"search icon\");\n }\n if (/filledText|filledtext/i.test(code)) {\n descriptor.keywords.push(\"filled\");\n descriptor.keywords.push(\"filled text\");\n }\n if (/placeholder/i.test(code)) {\n descriptor.keywords.push(\"placeholder\");\n }\n if (/className/i.test(code)) {\n descriptor.keywords.push(\"customizable\");\n }\n\n // Extract state types from TypeScript (e.g., state?: \"enabled\" | \"hover\" | \"error\")\n const stateMatches = code.matchAll(/state[?:].*[\"']([^\"']+)[\"']/gi);\n const states: string[] = [];\n for (const match of stateMatches) {\n if (match[1]) states.push(match[1].toLowerCase());\n }\n \n // Also extract from union types: \"enabled\" | \"hover\" | \"pressed\" | \"error\"\n const unionStateMatches = code.matchAll(/[\"'](enabled|hover|pressed|active-focus|read-only|error|success|disabled|loading|empty|filled)[\"']/gi);\n for (const match of unionStateMatches) {\n if (match[1]) states.push(match[1].toLowerCase());\n }\n\n // Process states\n for (const state of states) {\n if (state === \"error\") {\n descriptor.colors.push(\"error\");\n descriptor.visual.push(\"error state\");\n } else if (state === \"success\") {\n descriptor.colors.push(\"success\");\n descriptor.visual.push(\"success state\");\n } else if (state === \"disabled\") {\n descriptor.keywords.push(\"disabled\");\n } else if (state === \"loading\") {\n descriptor.components.add(\"progress\");\n } else if (state === \"hover\") {\n descriptor.keywords.push(\"hover\");\n descriptor.interactions.add(\"hover\");\n } else if (state === \"pressed\") {\n descriptor.keywords.push(\"pressed\");\n descriptor.interactions.add(\"press\");\n } else if (state === \"active-focus\") {\n descriptor.keywords.push(\"focus\");\n descriptor.keywords.push(\"active\");\n descriptor.interactions.add(\"focus\");\n } else if (state === \"read-only\") {\n descriptor.keywords.push(\"read only\");\n }\n }\n\n // Extract content types (e.g., content?: \"placeholder\" | \"filled text\")\n const contentMatches = code.matchAll(/content[?:].*[\"']([^\"']+)[\"']/gi);\n for (const match of contentMatches) {\n if (match[1]) {\n const content = match[1].toLowerCase();\n if (content.includes(\"placeholder\")) {\n descriptor.keywords.push(\"placeholder\");\n }\n if (content.includes(\"filled\")) {\n descriptor.keywords.push(\"filled\");\n descriptor.keywords.push(\"filled text\");\n }\n if (content.includes(\"empty\")) {\n descriptor.keywords.push(\"empty\");\n }\n }\n }\n \n if (/placeholder/i.test(code)) {\n descriptor.keywords.push(\"placeholder\");\n }\n if (/filled.*text|filledtext/i.test(code)) {\n descriptor.keywords.push(\"filled\");\n }\n\n // Extract from data-name patterns that indicate search\n if (/data-name.*search|search.*text|search.*input/i.test(code)) {\n descriptor.keywords.push(\"search\");\n descriptor.purpose = \"search interface\";\n }\n }\n\n /**\n * Extract size and spacing patterns from className and styles\n */\n private extractSizeAndSpacing(code: string, descriptor: ComponentDescriptor): void {\n // Size patterns (e.g., size-[24px], h-[48px], w-[1440px])\n if (/size-\\[(\\d+)|h-\\[(\\d+)|w-\\[(\\d+)|height:\\s*(\\d+)|width:\\s*(\\d+)/i.test(code)) {\n const sizeMatches = code.matchAll(/(?:size|h|w|height|width)[-:]?\\s*\\[?(\\d+)/gi);\n for (const match of sizeMatches) {\n const size = parseInt(match[1], 10);\n if (size >= 64) {\n descriptor.keywords.push(\"large\");\n } else if (size >= 48) {\n descriptor.keywords.push(\"medium\");\n } else if (size >= 24) {\n descriptor.keywords.push(\"small\");\n }\n // Icon sizes\n if (size === 24 || size === 48 || size === 64) {\n descriptor.keywords.push(`${size}px icon`);\n }\n }\n }\n\n // Gap/spacing patterns (e.g., gap-[4px], gap-[12px], gap-[16px])\n if (/gap-\\[(\\d+)|gap:\\s*(\\d+)/i.test(code)) {\n const gapMatches = code.matchAll(/gap[-:]?\\s*\\[?(\\d+)/gi);\n for (const match of gapMatches) {\n const gap = parseInt(match[1], 10);\n if (gap >= 16) {\n descriptor.keywords.push(\"spaced\");\n descriptor.layout.push(\"spaced layout\");\n } else if (gap >= 8) {\n descriptor.keywords.push(\"compact\");\n }\n }\n }\n\n // Padding patterns (e.g., p-[12px])\n if (/p-\\[(\\d+)|padding:\\s*(\\d+)/i.test(code)) {\n descriptor.keywords.push(\"padded\");\n }\n\n // Max/min height/width patterns\n if (/max-h-\\[(\\d+)|min-h-\\[(\\d+)|max-w-\\[(\\d+)|min-w-\\[(\\d+)/i.test(code)) {\n descriptor.keywords.push(\"constrained\");\n }\n }\n\n /**\n * Extract border and styling patterns\n */\n private extractBorderAndStyling(code: string, descriptor: ComponentDescriptor): void {\n // Border patterns\n if (/border\\s+border-\\[|border:\\s*1px|border-solid/i.test(code)) {\n descriptor.keywords.push(\"bordered\");\n // Check border color\n if (/border-\\[var\\(--color\\/border/i.test(code)) {\n descriptor.keywords.push(\"default border\");\n }\n if (/border-\\[var\\(--color\\/border\\/default/i.test(code)) {\n descriptor.keywords.push(\"border\");\n }\n }\n\n // Rounded corners (e.g., rounded-[8px], rounded-lg)\n if (/rounded-\\[(\\d+)|rounded-(?:sm|md|lg|xl|full)/i.test(code)) {\n const roundedMatches = code.matchAll(/rounded-\\[(\\d+)|rounded-(sm|md|lg|xl|full)/gi);\n for (const match of roundedMatches) {\n const value = match[1] || match[2];\n if (value === \"full\" || value === \"xl\") {\n descriptor.keywords.push(\"fully rounded\");\n } else {\n descriptor.keywords.push(\"rounded\");\n }\n }\n }\n\n // Background patterns\n if (/bg-\\[var\\(--color\\/surface|background:\\s*var\\(--color/i.test(code)) {\n descriptor.keywords.push(\"background\");\n if (/surface\\/flat|surface.*flat/i.test(code)) {\n descriptor.keywords.push(\"flat surface\");\n }\n if (/surface\\/floating|surface.*floating/i.test(code)) {\n descriptor.keywords.push(\"floating surface\");\n }\n }\n\n // Shadow patterns (already in layout, but add keywords)\n if (/shadow-\\[0px_0px_0px_0px/i.test(code)) {\n descriptor.keywords.push(\"no shadow\");\n } else if (/shadow-\\[|drop-shadow/i.test(code)) {\n descriptor.keywords.push(\"shadow\");\n }\n\n // Overflow patterns\n if (/overflow-clip|overflow-hidden/i.test(code)) {\n descriptor.keywords.push(\"clipped\");\n }\n\n // Flex patterns (more detailed)\n if (/flex\\s+flex-\\[1_0_0\\]|flex-1/i.test(code)) {\n descriptor.keywords.push(\"flexible\");\n descriptor.layout.push(\"flexible layout\");\n }\n\n // Content stretch pattern\n if (/content-stretch/i.test(code)) {\n descriptor.keywords.push(\"stretched\");\n descriptor.layout.push(\"stretched layout\");\n }\n }\n\n /**\n * Extract additional keywords from code and data-names for Pinecone search\n */\n private extractKeywords(code: string, dataNames: string[], descriptor: ComponentDescriptor): void {\n const allText = (code + \" \" + dataNames.join(\" \")).toLowerCase();\n\n // Dialog/modal keywords\n if (/modal|dialog|popup|overlay/i.test(allText)) {\n descriptor.keywords.push(\"dialog\");\n descriptor.keywords.push(\"overlay\");\n }\n\n // Destructive / irreversible action\n if (/delete|remove|borrar|irreversible|undo|destructive/i.test(allText)) {\n descriptor.keywords.push(\"destructive\");\n if (/irreversible|undo|no way to undo/i.test(allText)) {\n descriptor.keywords.push(\"irreversible\");\n }\n }\n\n // Button / action labels (common CTA words)\n if (/cancel|dismiss|close/i.test(allText)) {\n descriptor.keywords.push(\"cancel\");\n descriptor.keywords.push(\"dismissible\");\n }\n if (/\\bdelete\\b|remove|borrar/i.test(allText)) descriptor.keywords.push(\"delete\");\n if (/confirm|ok|submit|save|apply/i.test(allText)) descriptor.keywords.push(\"confirm\");\n\n // Support / hero icon (large centered icon)\n if (/support\\s*icon|hero|lead\\s*icon|centered\\s*icon|large\\s*icon/i.test(allText)) {\n descriptor.keywords.push(\"support icon\");\n descriptor.keywords.push(\"centered icon\");\n }\n\n // Structure keywords\n if (/header|body|footer|container/i.test(allText)) {\n if (/header.*body|body.*header/i.test(allText)) descriptor.keywords.push(\"header body\");\n }\n\n // Navigation / navbar keywords (e.g. NAV/Header, NAV/Top, Header/MenuPral)\n if (/data-name=[\"'][^\"']*\\bnav\\b|data-name=[\"'][^\"']*\\/nav\\b/i.test(allText) ||\n /\\bnav\\/|nav\\s*\\/|\\/nav\\b/i.test(allText)) {\n descriptor.keywords.push(\"navbar\");\n descriptor.keywords.push(\"navigation\");\n descriptor.keywords.push(\"top nav\");\n }\n if (/data-name=[\"'][^\"']*\\bmenu\\b|data-name=[\"'][^\"']*menu\\w*/i.test(allText)) {\n descriptor.keywords.push(\"menu\");\n }\n if (/data-name=[\"'][^\"']*\\btop\\b/i.test(allText) && /nav|header/i.test(allText)) {\n descriptor.keywords.push(\"top nav\");\n descriptor.keywords.push(\"header nav\");\n }\n // Nav links: multiple <p> inside nav-like structure\n const pCount = (code.match(/<p\\b|<\\/p>/gi) || []).length;\n if (pCount >= 3 && /nav|NAV|header|menu/i.test(allText)) {\n descriptor.keywords.push(\"nav links\");\n descriptor.keywords.push(\"navigation links\");\n }\n\n // Text / label / heading elements (<p>, <h1>-<h6>, <label>, <span>, etc.)\n if (/<p\\b|<\\/p>/i.test(code)) {\n descriptor.keywords.push(\"paragraph\");\n descriptor.keywords.push(\"text\");\n }\n if (/<h[1-6]\\b|<\\/h[1-6]>/i.test(code)) {\n descriptor.keywords.push(\"heading\");\n descriptor.keywords.push(\"title\");\n }\n if (/<label\\b|<\\/label>/i.test(code)) descriptor.keywords.push(\"label\");\n if (/<span\\b|<\\/span>/i.test(code)) {\n descriptor.keywords.push(\"text\");\n descriptor.keywords.push(\"label\");\n }\n if (/<figcaption\\b|<caption\\b/i.test(code)) descriptor.keywords.push(\"caption\");\n if (/<blockquote\\b/i.test(code)) descriptor.keywords.push(\"quote\");\n\n // Data-name hints for text roles (e.g. data-name=\"Title\", data-name=\"Description\")\n if (/data-name=[\"'][^\"']*\\btext\\b/i.test(allText)) descriptor.keywords.push(\"text\");\n if (/data-name=[\"'][^\"']*\\blabel\\b/i.test(allText)) {\n descriptor.keywords.push(\"label\");\n // Check for \"Label container\" pattern\n if (/data-name=[\"'][^\"']*label.*container/i.test(allText)) {\n descriptor.keywords.push(\"label container\");\n }\n }\n if (/data-name=[\"'][^\"']*\\btitle\\b/i.test(allText)) {\n descriptor.keywords.push(\"title\");\n descriptor.keywords.push(\"heading\");\n }\n if (/data-name=[\"'][^\"']*\\bheading\\b/i.test(allText)) {\n descriptor.keywords.push(\"heading\");\n descriptor.keywords.push(\"title\");\n }\n if (/data-name=[\"'][^\"']*\\b(paragraph|description)\\b/i.test(allText)) {\n descriptor.keywords.push(\"paragraph\");\n descriptor.keywords.push(\"text\");\n }\n if (/data-name=[\"'][^\"']*\\bsubtitle\\b/i.test(allText)) descriptor.keywords.push(\"subtitle\");\n if (/data-name=[\"'][^\"']*\\bbody\\b/i.test(allText)) descriptor.keywords.push(\"body text\");\n \n // Field/Container patterns\n if (/data-name=[\"'][^\"']*field.*container|data-name=[\"'][^\"']*input.*container/i.test(allText)) {\n descriptor.keywords.push(\"input field\");\n descriptor.keywords.push(\"field container\");\n }\n if (/data-name=[\"'][^\"']*search/i.test(allText)) {\n descriptor.keywords.push(\"search\");\n descriptor.purpose = \"search interface\";\n }\n if (/data-name=[\"'][^\"']*search.*text|data-name=[\"'][^\"']*search.*input|data-name=[\"'][^\"']*search\\s*\\+/i.test(allText)) {\n descriptor.keywords.push(\"search input\");\n descriptor.keywords.push(\"search\");\n }\n\n // State combinations in data-names (e.g., \"State=enabled, Content=filled text\")\n const stateContentMatches = code.matchAll(/data-name=[\"']([^\"']*state[^\"']*)[\"']/gi);\n for (const match of stateContentMatches) {\n const stateContent = match[1].toLowerCase();\n if (/state.*enabled/i.test(stateContent)) {\n descriptor.keywords.push(\"enabled\");\n }\n if (/state.*disabled/i.test(stateContent)) {\n descriptor.keywords.push(\"disabled\");\n }\n if (/state.*error/i.test(stateContent)) {\n descriptor.colors.push(\"error\");\n descriptor.keywords.push(\"error state\");\n }\n if (/state.*success/i.test(stateContent)) {\n descriptor.colors.push(\"success\");\n descriptor.keywords.push(\"success state\");\n }\n if (/content.*filled|content.*filled.*text/i.test(stateContent)) {\n descriptor.keywords.push(\"filled\");\n descriptor.keywords.push(\"filled text\");\n }\n if (/content.*placeholder/i.test(stateContent)) {\n descriptor.keywords.push(\"placeholder\");\n }\n if (/content.*empty/i.test(stateContent)) {\n descriptor.keywords.push(\"empty\");\n }\n }\n\n // Vector/Icon patterns in data-names\n if (/data-name=[\"'][^\"']*\\bvector\\b/i.test(allText)) {\n descriptor.keywords.push(\"vector\");\n descriptor.keywords.push(\"icon\");\n }\n\n // Import patterns (images, SVGs)\n if (/import\\s+img|import.*from.*svg|import.*from.*asset/i.test(code)) {\n descriptor.visual.push(\"image\");\n descriptor.keywords.push(\"image import\");\n }\n if (/import.*svg/i.test(code)) {\n descriptor.keywords.push(\"svg\");\n descriptor.keywords.push(\"icon\");\n }\n\n // Size/layout hints from code\n if (/size-\\[64|h-\\[64|w-\\[64|64px|size-\\[48|h-\\[48/i.test(code)) descriptor.keywords.push(\"large icon\");\n if (/gap-\\[16\\]|gap-\\[24\\]|gap-\\[32\\]/i.test(code)) descriptor.keywords.push(\"spaced\");\n if (/rounded-\\[8\\]|rounded-\\[12\\]|rounded-lg/i.test(code)) descriptor.keywords.push(\"rounded\");\n\n // Shadow / elevation from code\n if (/shadow-\\[|drop-shadow|elevation/i.test(allText)) descriptor.keywords.push(\"shadow\");\n\n // Conditional rendering patterns (e.g., if (state === \"enabled\" && content === \"filled text\"))\n if (/if\\s*\\(.*state.*===|if\\s*\\(.*content.*===/i.test(code)) {\n descriptor.keywords.push(\"conditional\");\n descriptor.keywords.push(\"stateful\");\n }\n\n // CSS class patterns (e.g., css-ew64yg, css-4hzbpn)\n if (/css-[a-z0-9]+/i.test(code)) {\n descriptor.keywords.push(\"styled\");\n }\n\n // Relative/absolute positioning\n if (/relative|absolute/i.test(code)) {\n descriptor.keywords.push(\"positioned\");\n }\n\n // Shrink/grow patterns\n if (/shrink-0|grow|flex-\\[1_0_0\\]/i.test(code)) {\n descriptor.keywords.push(\"flexible\");\n }\n\n // Min/max width/height patterns\n if (/min-w-|max-w-|min-h-|max-h-/i.test(code)) {\n descriptor.keywords.push(\"constrained\");\n }\n\n // Overflow patterns\n if (/overflow-clip|overflow-hidden|overflow-scroll/i.test(code)) {\n descriptor.keywords.push(\"overflow\");\n }\n\n // Inset patterns (e.g., inset-[8.33%])\n if (/inset-\\[/i.test(code)) {\n descriptor.keywords.push(\"inset\");\n }\n\n // Var() CSS variable patterns\n if (/var\\(--color|var\\(--typescale/i.test(code)) {\n descriptor.keywords.push(\"design tokens\");\n descriptor.keywords.push(\"themed\");\n }\n\n // Extract className values for additional patterns\n const classNameMatches = code.matchAll(/className=[\"']([^\"']+)[\"']/gi);\n for (const match of classNameMatches) {\n const className = match[1].toLowerCase();\n // Extract meaningful class patterns\n if (/flex|grid/i.test(className)) {\n descriptor.layout.push(\"flex layout\");\n }\n if (/items-center|justify-center/i.test(className)) {\n descriptor.layout.push(\"centered\");\n }\n if (/gap-/i.test(className)) {\n descriptor.keywords.push(\"spaced\");\n }\n if (/rounded/i.test(className)) {\n descriptor.keywords.push(\"rounded\");\n }\n if (/shadow/i.test(className)) {\n descriptor.keywords.push(\"shadow\");\n }\n }\n\n // Extract default prop values (e.g., showLabel = true, state = \"enabled\")\n const defaultPropMatches = code.matchAll(/(\\w+)\\s*=\\s*[\"']?([^\"',\\s\\)]+)[\"']?/gi);\n for (const match of defaultPropMatches) {\n const propName = match[1].toLowerCase();\n const propValue = match[2].toLowerCase();\n if (propName === \"state\" && propValue) {\n if (propValue === \"enabled\") descriptor.keywords.push(\"enabled\");\n if (propValue === \"disabled\") descriptor.keywords.push(\"disabled\");\n if (propValue === \"error\") {\n descriptor.colors.push(\"error\");\n descriptor.keywords.push(\"error state\");\n }\n if (propValue === \"success\") {\n descriptor.colors.push(\"success\");\n descriptor.keywords.push(\"success state\");\n }\n }\n if (propName === \"content\" && propValue) {\n if (propValue.includes(\"placeholder\")) descriptor.keywords.push(\"placeholder\");\n if (propValue.includes(\"filled\")) descriptor.keywords.push(\"filled\");\n }\n }\n }\n\n /**\n * Extract visual characteristics from design tokens\n * Parses Figma design token format: \"TokenName: Value\" or \"TokenName/SubToken: Value\"\n */\n private extractFromTokens(tokens: string, descriptor: ComponentDescriptor): void {\n if (!tokens || tokens.trim().length === 0) return;\n\n if (!descriptor.visual) descriptor.visual = [];\n if (!descriptor.colors) descriptor.colors = [];\n if (!descriptor.typography) descriptor.typography = [];\n if (!descriptor.effects) descriptor.effects = [];\n if (!descriptor.layout) descriptor.layout = [];\n if (!descriptor.keywords) descriptor.keywords = [];\n\n // Parse tokens - they're comma-separated: \"Token: Value, Token2: Value\"\n const tokenEntries = tokens.split(',').map(t => t.trim());\n\n for (const entry of tokenEntries) {\n // Extract token name and value\n // Format: \"TokenName/SubToken: Value\" or \"TokenName: Value\"\n const match = entry.match(/^([^:]+):\\s*(.+)$/);\n if (!match) continue;\n\n const tokenName = match[1].trim();\n const tokenValue = match[2].trim();\n const lowerTokenName = tokenName.toLowerCase();\n\n // Extract semantic color names\n if (lowerTokenName.includes('color') || lowerTokenName.includes('background') || \n lowerTokenName.includes('icon') || lowerTokenName.includes('text') ||\n lowerTokenName.includes('action') || lowerTokenName.includes('border')) {\n \n // Extract semantic color category\n if (lowerTokenName.includes('warning')) {\n if (!descriptor.colors.includes('warning')) {\n descriptor.colors.push('warning');\n }\n if (lowerTokenName.includes('background')) {\n descriptor.visual.push('warning background');\n }\n if (lowerTokenName.includes('icon')) {\n descriptor.visual.push('warning icon');\n }\n } else if (lowerTokenName.includes('error') || lowerTokenName.includes('danger')) {\n if (!descriptor.colors.includes('error')) {\n descriptor.colors.push('error');\n }\n if (lowerTokenName.includes('background')) {\n descriptor.visual.push('error background');\n }\n if (lowerTokenName.includes('icon')) {\n descriptor.visual.push('error icon');\n }\n } else if (lowerTokenName.includes('success')) {\n if (!descriptor.colors.includes('success')) {\n descriptor.colors.push('success');\n }\n if (lowerTokenName.includes('background')) {\n descriptor.visual.push('success background');\n }\n if (lowerTokenName.includes('icon')) {\n descriptor.visual.push('success icon');\n }\n } else if (lowerTokenName.includes('primary') || lowerTokenName.includes('main') || lowerTokenName.includes('brand')) {\n if (!descriptor.colors.includes('primary')) {\n descriptor.colors.push('primary');\n }\n if (lowerTokenName.includes('brand')) {\n descriptor.keywords.push('brand color');\n }\n } else if (lowerTokenName.includes('secondary') || lowerTokenName.includes('alternative')) {\n if (!descriptor.colors.includes('secondary')) {\n descriptor.colors.push('secondary');\n }\n } else if (lowerTokenName.includes('default') || lowerTokenName.includes('neutral')) {\n if (!descriptor.colors.includes('neutral')) {\n descriptor.colors.push('neutral');\n }\n } else if (lowerTokenName.includes('info')) {\n if (!descriptor.colors.includes('info')) {\n descriptor.colors.push('info');\n }\n descriptor.visual.push('info color');\n }\n }\n\n // Extract typography information\n if (lowerTokenName.includes('font') || lowerTokenName.includes('typescale') || \n lowerTokenName.includes('headline') || lowerTokenName.includes('body') ||\n lowerTokenName.includes('button') || lowerTokenName.includes('text') ||\n lowerTokenName.includes('label') || lowerTokenName.includes('helper') ||\n lowerTokenName.includes('placeholder')) {\n \n if (lowerTokenName.includes('headline')) {\n if (!descriptor.typography.includes('headline')) {\n descriptor.typography.push('headline');\n }\n // Extract size if available\n if (lowerTokenName.includes('large')) {\n descriptor.typography.push('large headline');\n } else if (lowerTokenName.includes('medium')) {\n descriptor.typography.push('medium headline');\n } else if (lowerTokenName.includes('small')) {\n descriptor.typography.push('small headline');\n }\n // Desktop/Mobile variants\n if (lowerTokenName.includes('desktop')) {\n descriptor.keywords.push('desktop');\n }\n if (lowerTokenName.includes('mobile')) {\n descriptor.keywords.push('mobile');\n }\n } else if (lowerTokenName.includes('body')) {\n if (!descriptor.typography.includes('body')) {\n descriptor.typography.push('body text');\n }\n if (lowerTokenName.includes('large')) {\n descriptor.typography.push('large body');\n } else if (lowerTokenName.includes('medium')) {\n descriptor.typography.push('medium body');\n } else if (lowerTokenName.includes('small')) {\n descriptor.typography.push('small body');\n }\n // Strong/default variations\n if (lowerTokenName.includes('strong')) {\n descriptor.typography.push('bold');\n descriptor.keywords.push('strong text');\n }\n if (lowerTokenName.includes('default')) {\n descriptor.keywords.push('default text');\n }\n } else if (lowerTokenName.includes('button')) {\n if (!descriptor.typography.includes('button')) {\n descriptor.typography.push('button text');\n }\n if (lowerTokenName.includes('large')) {\n descriptor.typography.push('large button');\n descriptor.keywords.push('large button');\n } else if (lowerTokenName.includes('medium')) {\n descriptor.typography.push('medium button');\n } else if (lowerTokenName.includes('small')) {\n descriptor.typography.push('small button');\n }\n } else if (lowerTokenName.includes('label')) {\n descriptor.keywords.push('label');\n if (lowerTokenName.includes('large')) {\n descriptor.keywords.push('large label');\n }\n } else if (lowerTokenName.includes('helper')) {\n descriptor.keywords.push('helper');\n descriptor.keywords.push('helper text');\n } else if (lowerTokenName.includes('placeholder')) {\n descriptor.keywords.push('placeholder');\n }\n\n // Extract font weight if mentioned\n if (tokenValue.includes('weight') || tokenValue.includes('700') || tokenValue.includes('bold')) {\n descriptor.typography.push('bold');\n } else if (tokenValue.includes('400') || tokenValue.includes('regular')) {\n descriptor.typography.push('regular');\n } else if (tokenValue.includes('600') || tokenValue.includes('semibold')) {\n descriptor.typography.push('semibold');\n }\n\n // Extract line height and letter spacing\n if (tokenValue.includes('lineHeight') || tokenValue.includes('line-height')) {\n descriptor.keywords.push('line height');\n }\n if (tokenValue.includes('letterSpacing') || tokenValue.includes('letter-spacing')) {\n descriptor.keywords.push('letter spacing');\n }\n }\n\n // Extract elevation and shadow effects\n if (lowerTokenName.includes('elevation') || lowerTokenName.includes('shadow') || \n lowerTokenName.includes('effect')) {\n \n if (lowerTokenName.includes('floating') || lowerTokenName.includes('raised')) {\n if (!descriptor.effects.includes('elevated')) {\n descriptor.effects.push('elevated');\n }\n descriptor.layout.push('elevated with shadow');\n } else if (lowerTokenName.includes('drop') || lowerTokenName.includes('shadow')) {\n if (!descriptor.effects.includes('shadow')) {\n descriptor.effects.push('shadow');\n }\n descriptor.layout.push('with shadow');\n } else if (lowerTokenName.includes('flat')) {\n descriptor.keywords.push('flat');\n descriptor.keywords.push('no elevation');\n }\n }\n\n // Extract surface types\n if (lowerTokenName.includes('surface')) {\n if (lowerTokenName.includes('flat')) {\n descriptor.keywords.push('flat surface');\n } else if (lowerTokenName.includes('floating')) {\n descriptor.keywords.push('floating surface');\n descriptor.layout.push('elevated');\n } else if (lowerTokenName.includes('raised')) {\n descriptor.keywords.push('raised surface');\n descriptor.layout.push('elevated');\n } else if (lowerTokenName.includes('state')) {\n if (lowerTokenName.includes('default')) {\n descriptor.keywords.push('default state');\n }\n }\n }\n\n // Extract background types\n if (lowerTokenName.includes('background')) {\n if (lowerTokenName.includes('alternative')) {\n descriptor.keywords.push('alternative background');\n if (lowerTokenName.includes('strong')) {\n descriptor.keywords.push('strong background');\n }\n } else if (lowerTokenName.includes('brand')) {\n descriptor.colors.push('primary');\n descriptor.keywords.push('brand background');\n }\n }\n\n // Extract border radius from rounded values\n if (lowerTokenName.includes('rounded') || lowerTokenName.includes('radius')) {\n descriptor.layout.push('rounded corners');\n }\n\n // Extract action colors (for buttons, CTAs)\n if (lowerTokenName.includes('action')) {\n if (lowerTokenName.includes('main') || lowerTokenName.includes('primary')) {\n descriptor.colors.push('primary');\n descriptor.keywords.push('primary action');\n } else if (lowerTokenName.includes('alternative')) {\n descriptor.colors.push('secondary');\n descriptor.keywords.push('alternative action');\n }\n if (lowerTokenName.includes('selected')) {\n descriptor.keywords.push('selected');\n }\n if (lowerTokenName.includes('on main') || lowerTokenName.includes('on-main')) {\n descriptor.keywords.push('on primary');\n }\n }\n }\n\n // Additional pattern matching for complex token formats\n // Match patterns like \"Background/warning: #FFFAEB\"\n const colorPattern = /(?:Background|Icon|Text|Action|Border)\\/([^:,\\s]+)/gi;\n let colorMatch;\n while ((colorMatch = colorPattern.exec(tokens)) !== null) {\n const semanticName = colorMatch[1].toLowerCase();\n if (semanticName && !descriptor.colors.includes(semanticName)) {\n descriptor.colors.push(semanticName);\n }\n }\n\n // Match elevation patterns\n if (/Elevation\\s+(?:raised|floating|flat)/i.test(tokens)) {\n if (!descriptor.effects.includes('elevated')) {\n descriptor.effects.push('elevated');\n }\n descriptor.layout.push('elevated with shadow');\n }\n\n // Detect Effect types (DROP_SHADOW, etc.)\n if (/Effect\\(.*DROP_SHADOW/i.test(tokens)) {\n if (!descriptor.effects.includes('shadow')) {\n descriptor.effects.push('shadow');\n }\n descriptor.layout.push('with shadow');\n }\n\n // Component specific exceptions (e.g., \"Component specific exceptions/Placeholder\")\n if (/Component\\s+specific\\s+exceptions/i.test(tokens)) {\n if (/placeholder/i.test(tokens)) {\n descriptor.keywords.push('placeholder');\n }\n if (/header.*icon/i.test(tokens)) {\n descriptor.keywords.push('header icon');\n }\n if (/button/i.test(tokens)) {\n descriptor.keywords.push('button');\n }\n }\n\n // Helper text detection\n if (/helper.*text|typescale.*helper/i.test(tokens)) {\n descriptor.keywords.push('helper');\n descriptor.keywords.push('helper text');\n }\n\n // Token-based keywords\n if (/Action\\/main|action.*main/i.test(tokens) && /#EC0000|#e00|red|danger/i.test(tokens)) {\n descriptor.keywords.push('destructive');\n descriptor.keywords.push('primary action');\n }\n if (/Elevation\\s+floating|elevation.*floating/i.test(tokens)) {\n descriptor.keywords.push('floating');\n }\n if (/Background\\/warning|Icon\\/warning|warning/i.test(tokens)) {\n descriptor.keywords.push('warning');\n }\n if (/Headline|headline|typescale/i.test(tokens)) {\n descriptor.keywords.push('headline');\n }\n if (/Body\\/Body|body.*default/i.test(tokens)) {\n descriptor.keywords.push('body text');\n }\n if (/Button Large|button\\/large|Button Large/i.test(tokens)) {\n descriptor.keywords.push('large button');\n }\n if (/Surface\\/floating|surface.*floating/i.test(tokens)) {\n descriptor.keywords.push('floating surface');\n descriptor.layout.push('elevated');\n }\n if (/Surface\\/raised|surface.*raised/i.test(tokens)) {\n descriptor.keywords.push('raised surface');\n descriptor.layout.push('elevated');\n }\n\n // Extract more color patterns (Text/info, Icon/soft, etc.)\n if (/Text\\/info|text.*info/i.test(tokens)) {\n descriptor.colors.push('info');\n descriptor.keywords.push('info text');\n }\n if (/Text\\/soft|text.*soft/i.test(tokens)) {\n descriptor.keywords.push('soft text');\n }\n if (/Icon\\/soft|icon.*soft/i.test(tokens)) {\n descriptor.keywords.push('soft icon');\n }\n if (/Icon\\/default|icon.*default/i.test(tokens)) {\n descriptor.keywords.push('default icon');\n }\n\n // Extract more typography patterns\n if (/Body.*Medium.*Strong|body.*medium.*strong/i.test(tokens)) {\n descriptor.typography.push('bold');\n descriptor.typography.push('medium body');\n descriptor.keywords.push('strong text');\n }\n if (/Body.*Medium.*Default|body.*medium.*default/i.test(tokens)) {\n descriptor.typography.push('medium body');\n descriptor.keywords.push('default text');\n }\n if (/Headline.*Desktop|headline.*desktop/i.test(tokens)) {\n descriptor.keywords.push('desktop');\n }\n if (/Headline.*Mobile|headline.*mobile/i.test(tokens)) {\n descriptor.keywords.push('mobile');\n }\n\n // Extract Surface/State patterns\n if (/Surface\\/State|surface.*state/i.test(tokens)) {\n descriptor.keywords.push('state surface');\n if (/default/i.test(tokens)) {\n descriptor.keywords.push('default state');\n }\n }\n\n // Extract more background patterns\n if (/Background\\/alternative|background.*alternative/i.test(tokens)) {\n descriptor.keywords.push('alternative background');\n }\n if (/Background\\/alternative.*strong|background.*alternative.*strong/i.test(tokens)) {\n descriptor.keywords.push('strong alternative background');\n }\n\n // Extract more border patterns\n if (/Border\\/default|border.*default/i.test(tokens)) {\n descriptor.keywords.push('default border');\n }\n if (/Border\\/alternative|border.*alternative/i.test(tokens)) {\n descriptor.keywords.push('alternative border');\n }\n\n // Extract Font family patterns\n if (/Font\\(family:|font.*family/i.test(tokens)) {\n descriptor.keywords.push('custom font');\n if (/Santander/i.test(tokens)) {\n descriptor.keywords.push('santander font');\n }\n }\n\n // Extract letter spacing and line height from Font() patterns\n if (/letterSpacing|letter-spacing/i.test(tokens)) {\n descriptor.keywords.push('letter spacing');\n }\n if (/lineHeight|line-height/i.test(tokens)) {\n descriptor.keywords.push('line height');\n }\n\n // Extract size from Font() patterns\n if (/size:\\s*(\\d+)/i.test(tokens)) {\n const sizeMatches = tokens.matchAll(/size:\\s*(\\d+)/gi);\n for (const match of sizeMatches) {\n const size = parseInt(match[1], 10);\n if (size >= 24) {\n descriptor.keywords.push('large text');\n } else if (size >= 16) {\n descriptor.keywords.push('medium text');\n } else {\n descriptor.keywords.push('small text');\n }\n }\n }\n }\n}\n","/**\n * Query Builder\n * Builds semantic queries from component descriptors\n */\n\nimport type { ComponentDescriptor } from \"./types.js\";\n\n/**\n * Build a natural language query from extracted descriptor\n * Prioritizes semantic richness for embedding-based search\n * Includes hierarchy and enhanced design token information\n */\nexport function buildSemanticQuery(descriptor: ComponentDescriptor, fallback: string): string {\n const queryParts: string[] = [];\n\n // 1. Add primary components (most important for matching)\n // Prioritize complex/specific components over generic ones\n const componentArray = Array.from(descriptor.components);\n const priorityComponents = prioritizeComponents(componentArray);\n \n if (priorityComponents.length > 0) {\n // For complex frames: include top 5-7 components\n // For simple frames: this will naturally be fewer\n queryParts.push(...priorityComponents.slice(0, 7));\n }\n\n // 2. Add hierarchy information (structural parts)\n if (descriptor.hierarchy.length > 0) {\n // Build hierarchy description\n const hierarchyParts = descriptor.hierarchy.slice(0, 4); // Limit to avoid too long\n if (hierarchyParts.length > 0) {\n // Create natural hierarchy description\n if (hierarchyParts.includes('header') && hierarchyParts.includes('body')) {\n queryParts.push('with header and body');\n } else if (hierarchyParts.includes('header') && hierarchyParts.includes('footer')) {\n queryParts.push('with header and footer');\n } else if (hierarchyParts.length === 1) {\n queryParts.push(`with ${hierarchyParts[0]}`);\n } else {\n // Add individual hierarchy parts\n queryParts.push(...hierarchyParts.slice(0, 3));\n }\n }\n }\n\n // 3. Add purpose if present (provides semantic context)\n if (descriptor.purpose) {\n queryParts.push(descriptor.purpose);\n }\n\n // 4. Add key interactions (helps match use cases)\n // Filter out interactions that are already covered by purpose\n if (descriptor.interactions.size > 0) {\n const interactions = Array.from(descriptor.interactions)\n .filter(interaction => {\n // Don't add \"confirmation\" if purpose already contains it\n if (interaction === \"confirmation\" && descriptor.purpose?.includes(\"confirmation\")) {\n return false;\n }\n return true;\n })\n .slice(0, 2);\n queryParts.push(...interactions);\n }\n\n // 5. Add semantic colors from design tokens\n if (descriptor.colors.length > 0) {\n queryParts.push(...descriptor.colors.slice(0, 3));\n }\n\n // 6. Add visual characteristics (helps with visual similarity)\n if (descriptor.visual.length > 0) {\n queryParts.push(...descriptor.visual.slice(0, 4));\n }\n\n // 7. Add typography information (if relevant)\n if (descriptor.typography.length > 0) {\n // Only add most distinctive typography features\n const distinctiveTypography = descriptor.typography.filter(t => \n t.includes('headline') || t.includes('bold') || t.includes('large')\n );\n if (distinctiveTypography.length > 0) {\n queryParts.push(...distinctiveTypography.slice(0, 2));\n }\n }\n\n // 8. Add effects (elevation, shadows)\n if (descriptor.effects.length > 0) {\n queryParts.push(...descriptor.effects.slice(0, 2));\n }\n\n // 9. Add layout traits (secondary importance)\n if (descriptor.layout.length > 0) {\n queryParts.push(...descriptor.layout.slice(0, 3));\n }\n\n // 10. Add additional keywords\n if (descriptor.keywords.length > 0) {\n queryParts.push(...descriptor.keywords.slice(0, 8));\n }\n\n // 11. Deduplicate terms (case-insensitive)\n const seen = new Set<string>();\n const uniqueParts = queryParts.filter(part => {\n const lower = part.toLowerCase();\n if (seen.has(lower)) {\n return false;\n }\n seen.add(lower);\n return true;\n });\n\n // Build final query\n if (uniqueParts.length > 0) {\n return uniqueParts.join(\" \");\n }\n\n return fallback;\n}\n\n/**\n * Prioritize components by specificity and importance\n * More specific components rank higher\n */\nexport function prioritizeComponents(components: string[]): string[] {\n const priority: { [key: string]: number } = {\n // High specificity - these are most valuable for matching\n \"segmented control\": 10,\n \"icon button\": 9,\n \"stepper\": 9,\n \"breadcrumb\": 9,\n \"calendar\": 9,\n \"carousel\": 9,\n \"accordion\": 9,\n \"datepicker\": 9,\n \"chart\": 8,\n \"table\": 8,\n \"navbar\": 8,\n \"sidebar\": 8,\n \"modal\": 8,\n \"tabs\": 8,\n \n // Medium specificity\n \"dropdown\": 7,\n \"slider\": 7,\n \"switch\": 7,\n \"checkbox\": 7,\n \"radio\": 7,\n \"textarea\": 7,\n \"pagination\": 7,\n \"card\": 7,\n \"menu\": 7,\n \"badge\": 6,\n \"tooltip\": 6,\n \"alert\": 6,\n \"progress\": 6,\n \"toast\": 6,\n \"avatar\": 6,\n \n // Lower specificity - common components\n \"button\": 5,\n \"input\": 5,\n \"list\": 4,\n \"grid\": 4,\n \"header\": 3,\n \"footer\": 3,\n \"icon\": 2,\n \"image\": 2,\n };\n\n return components.sort((a, b) => {\n const priorityA = priority[a] || 0;\n const priorityB = priority[b] || 0;\n return priorityB - priorityA;\n });\n}\n","/**\n * Design Query Extractor\n * \n * Main entry point for extracting semantic queries from Figma designs\n * optimized for Pinecone semantic/embedding-based search.\n */\n\nimport type { FigmaDesignContextResult } from \"../../clients/figma-client.js\";\nimport type { ComponentDescriptor } from \"./types.js\";\nimport { MetadataExtractorSimpler } from \"./metadata-extractor-simpler.js\";\nimport { DesignContextExtractor } from \"./design-context-extractor.js\";\nimport { buildSemanticQuery } from \"./query-builder.js\";\n\n/**\n * Extracts semantic descriptions from Figma design context for Pinecone search\n */\nexport class DesignQueryExtractor {\n private metadataExtractor: MetadataExtractorSimpler;\n private designContextExtractor: DesignContextExtractor;\n\n constructor() {\n this.metadataExtractor = new MetadataExtractorSimpler();\n this.designContextExtractor = new DesignContextExtractor();\n }\n\n /**\n * Extracts a semantic query optimized for embedding-based search from design context\n */\n extractQuery(\n designContext: FigmaDesignContextResult,\n fallbackQuery: string = \"UI component\",\n ): string {\n if (!designContext.content || designContext.content.length === 0) {\n return fallbackQuery;\n }\n\n const descriptor: ComponentDescriptor = {\n components: new Set<string>(),\n visual: [],\n layout: [],\n interactions: new Set<string>(),\n hierarchy: [],\n colors: [],\n typography: [],\n effects: [],\n keywords: [],\n };\n\n // Extract from each content item\n for (const item of designContext.content) {\n if (item.type === \"text\" && typeof item.text === \"string\") {\n const text = item.text;\n\n // Separate code from design tokens\n const parts = text.split(/These styles are contained in the design:/i);\n const codeSection = parts[0] || \"\";\n const tokensSection = parts[1] || \"\";\n\n // Extract from code and tokens\n this.designContextExtractor.extractFromCodeAndTokens(codeSection, tokensSection, descriptor);\n }\n }\n\n // Build semantic query from descriptor\n return buildSemanticQuery(descriptor, fallbackQuery);\n }\n\n /**\n * Extracts a semantic query from Figma metadata (XML-like structure)\n * Parses instance names and frame names to identify components\n */\n extractQueryFromMetadata(\n metadata: FigmaDesignContextResult,\n ): string {\n if (!metadata.content || metadata.content.length === 0) {\n return \"\";\n }\n\n const descriptor: ComponentDescriptor = {\n components: new Set<string>(),\n visual: [],\n layout: [],\n interactions: new Set<string>(),\n hierarchy: [],\n colors: [],\n typography: [],\n effects: [],\n keywords: [],\n };\n\n // Extract from each content item (metadata is typically in text format with XML-like structure)\n for (const item of metadata.content) {\n if (item.type === \"text\" && typeof item.text === \"string\") {\n const metadataText = item.text;\n // Extract all names from metadata and use them as keywords\n const names = this.metadataExtractor.extractNames(metadataText);\n descriptor.keywords.push(...names);\n }\n }\n\n // Build semantic query from descriptor (use empty string as fallback if no names found)\n return buildSemanticQuery(descriptor, \"\");\n }\n}\n\n// Re-export types and utilities\nexport type { ComponentDescriptor } from \"./types.js\";\nexport { MetadataExtractorSimpler } from \"./metadata-extractor-simpler.js\";\n","/**\n * Pinecone Search Service\n * Reusable service for semantic search of design system components\n * Uses Frida Pinecone Proxy API for secure access\n */\n\nimport \"dotenv/config\";\nimport { logger } from \"../../utils/logger.js\";\n\nexport interface ComponentMatch {\n id: string; // From match.id\n tag: string; // From metadata.tag\n score: number; // From match.score\n name: string; // From metadata.name\n framework: string; // From metadata.framework\n category: string; // From metadata.category\n overview: string; // From metadata.overview\n visual: string; // From metadata.visual\n technical: string; // From metadata.technical\n keywords: string[]; // From metadata.keywords\n}\n\nexport interface SearchOptions {\n minScore?: number;\n topK?: number;\n namespace?: string;\n}\n\nexport interface SearchResults {\n query: string;\n totalMatches: number;\n relevantMatches: number;\n matches: ComponentMatch[];\n searchMetadata: {\n minScore: number;\n topK: number;\n indexName: string;\n namespace?: string;\n };\n}\n\nexport interface PineconeSearchServiceOptions {\n namespace?: string;\n}\n\nexport class PineconeSearchService {\n private indexName: string;\n private namespace?: string;\n private minScore: number;\n private topK: number;\n private fridaEmbeddingUrl: string;\n private fridaApiKey: string;\n private fridaPineconeProxyUrl: string;\n private fridaEmbeddingModel: string;\n\n constructor(options: PineconeSearchServiceOptions = {}) {\n this.indexName = process.env.PINECONE_INDEX!;\n this.namespace = options.namespace;\n this.minScore = parseFloat(process.env.PINECONE_MIN_SCORE!);\n this.topK = parseInt(process.env.PINECONE_TOP_K!, 10);\n this.fridaEmbeddingUrl = process.env.FRIDA_EMBEDDING_URL!;\n this.fridaApiKey = process.env.FRIDA_BEARER_TOKEN!;\n this.fridaPineconeProxyUrl = process.env.FRIDA_PINECONE_PROXY_URL!;\n this.fridaEmbeddingModel = process.env.FRIDA_EMBEDDING_MODEL!;\n }\n\n /**\n * Generates embedding for a text using Frida API\n * @param text - Text to embed\n * @returns Promise<number[]> Embedding vector (1536 dimensions)\n */\n async generateEmbedding(text: string): Promise<number[]> {\n try {\n logger.debug(\"Calling Frida Embedding API...\");\n const startTime = Date.now();\n\n const response = await fetch(this.fridaEmbeddingUrl, {\n method: \"POST\",\n headers: {\n accept: \"application/json\",\n Authorization: `Bearer ${this.fridaApiKey}`,\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify({\n input: text,\n model: this.fridaEmbeddingModel,\n user_id: \"pinecone-search\",\n email: process.env.MCP_USER_EMAIL || \"figma2frida_mcp@fridaplatform.com\",\n }),\n });\n\n logger.debug(`API response status: ${response.status}`);\n\n if (!response.ok) {\n const errorText = await response.text();\n logger.error(\"API Error response:\", errorText);\n throw new Error(`API Error: ${response.status} ${response.statusText}`);\n }\n\n logger.debug(\"Parsing API response...\");\n const data = (await response.json()) as {\n data?: Array<{ embedding?: number[] }>;\n };\n\n if (!data.data || !data.data[0] || !data.data[0].embedding) {\n logger.error(\"Invalid response format:\", JSON.stringify(data).substring(0, 200));\n throw new Error(\"Invalid API response format\");\n }\n\n const embedding = data.data[0].embedding;\n const elapsed = Date.now() - startTime;\n logger.debug(`✓ Embedding generated (${embedding.length} dims) in ${elapsed}ms`);\n\n return embedding; // Returns 1536-dimensional array\n } catch (error) {\n logger.error(\"Error generating embedding:\", error);\n throw new Error(`Failed to generate embedding: ${error instanceof Error ? error.message : String(error)}`);\n }\n }\n\n /**\n * Parses a Pinecone match to structured format\n * New simplified schema: tag, name, framework, category, overview, visual, technical, keywords\n */\n private parseMatch(match: {\n id?: string;\n score?: number;\n metadata?: Record<string, unknown>;\n }): ComponentMatch {\n const metadata = match.metadata || {};\n\n return {\n id: match.id || \"unknown\",\n tag: (metadata.tag as string) || match.id || \"unknown\",\n score: match.score || 0,\n name: (metadata.name as string) || \"\",\n framework: (metadata.framework as string) || \"\",\n category: (metadata.category as string) || \"General\",\n overview: (metadata.overview as string) || \"\",\n visual: (metadata.visual as string) || \"\",\n technical: (metadata.technical as string) || \"\",\n keywords: Array.isArray(metadata.keywords) ? (metadata.keywords as string[]) : [],\n };\n }\n\n /**\n * Queries Pinecone via Frida Proxy API\n * @param embedding - Embedding vector\n * @param topK - Number of results to return\n * @param namespace - Optional namespace\n * @returns Query response from Pinecone\n */\n private async queryPineconeProxy(\n embedding: number[],\n topK: number,\n namespace?: string,\n ): Promise<{\n matches?: Array<{\n id?: string;\n score?: number;\n metadata?: Record<string, unknown>;\n }>;\n namespace?: string;\n }> {\n const url = `${this.fridaPineconeProxyUrl}/pinecone/data/${this.indexName}/query`;\n\n logger.debug(`Querying Frida Pinecone Proxy: ${url}${namespace ? ` (namespace: \"${namespace}\")` : \"\"}`);\n\n const requestBody: {\n vector: number[];\n topK: number;\n includeMetadata: boolean;\n namespace?: string;\n } = {\n vector: embedding,\n topK,\n includeMetadata: true,\n };\n\n // Add namespace to request body if provided\n if (namespace) {\n requestBody.namespace = namespace;\n }\n\n const startTime = Date.now();\n const response = await fetch(url, {\n method: \"POST\",\n headers: {\n \"Authorization\": `Bearer ${this.fridaApiKey}`,\n \"Content-Type\": \"application/json\",\n \"Accept\": \"application/json\",\n },\n body: JSON.stringify(requestBody),\n });\n\n const queryTime = Date.now() - startTime;\n logger.debug(`Proxy API response status: ${response.status} (${queryTime}ms)`);\n\n if (!response.ok) {\n const errorText = await response.text();\n logger.error(\"Proxy API Error response:\", errorText);\n throw new Error(`Pinecone Proxy API Error: ${response.status} ${response.statusText} - ${errorText}`);\n }\n\n const data = await response.json() as {\n matches?: Array<{\n id?: string;\n score?: number;\n metadata?: Record<string, unknown>;\n }>;\n namespace?: string;\n };\n\n return data;\n }\n\n /**\n * Searches for components in Pinecone via Frida Proxy\n * @param query - Search query\n * @param options - Search options\n * @returns Structured results\n */\n async search(query: string, options: SearchOptions = {}): Promise<SearchResults> {\n if (!query || typeof query !== \"string\") {\n throw new Error(\"Query must be a non-empty string\");\n }\n logger.debug(`[DEBUG] options object: ${JSON.stringify(options)}`);\n logger.debug(`[DEBUG] options.topK: ${options.topK}, type: ${typeof options.topK}`);\n logger.debug(`[DEBUG] options.topK !== undefined: ${options.topK !== undefined}`);\n logger.debug(`[DEBUG] this.topK (instance): ${this.topK}`);\n\n const minScore =\n options.minScore !== undefined ? options.minScore : this.minScore;\n const topK = options.topK !== undefined ? options.topK : this.topK;\n // Namespace: prioritize options.namespace, then this.namespace\n const namespace = options.namespace !== undefined ? options.namespace : this.namespace;\n\n logger.debug(`Starting search - Query: \"${query}\", topK: ${topK}, minScore: ${minScore}${namespace ? `, namespace: \"${namespace}\"` : \"\"}`);\n\n // Generate embedding for the query\n const embedding = await this.generateEmbedding(query);\n\n // Query Pinecone via Frida Proxy\n logger.debug(`Querying Pinecone index \"${this.indexName}\" via Frida Proxy${namespace ? ` namespace \"${namespace}\"` : \"\"}...`);\n const startTime = Date.now();\n\n const queryResponse = await this.queryPineconeProxy(embedding, topK, namespace);\n const queryTime = Date.now() - startTime;\n logger.debug(`Query completed in ${queryTime}ms - Found ${queryResponse.matches?.length || 0} matches`);\n\n // Process results\n const allMatches = queryResponse.matches || [];\n const relevantMatches = allMatches.filter((m) => (m.score || 0) >= minScore);\n\n logger.debug(`Filtered results: ${relevantMatches.length} relevant (score >= ${minScore}) out of ${allMatches.length} total`);\n\n return {\n query,\n totalMatches: allMatches.length,\n relevantMatches: relevantMatches.length,\n matches: relevantMatches.map((match) => this.parseMatch(match)),\n searchMetadata: {\n minScore,\n topK,\n indexName: this.indexName,\n namespace: namespace,\n },\n };\n }\n\n /**\n * Gets details of a specific component by tag or id\n * @param tag - Component tag or id (e.g.: 'wtw-button-split', 'my-badge')\n * @returns Component details or null if it doesn't exist\n */\n async getComponentDetails(tag: string): Promise<ComponentMatch | null> {\n if (!tag || typeof tag !== \"string\") {\n throw new Error(\"Tag must be a non-empty string\");\n }\n\n // Search for the specific component\n const results = await this.search(tag, { topK: 10, minScore: 0 });\n\n // Find exact match by tag or id\n const exactMatch = results.matches.find(\n (m) => m.tag === tag || m.id === tag\n );\n\n if (exactMatch) {\n return exactMatch;\n }\n\n // If no exact match, return the closest one\n if (results.matches.length > 0) {\n return results.matches[0];\n }\n\n return null;\n }\n\n /**\n * Searches for multiple components by tags\n * @param tags - Array of component tags\n * @returns Array of component details\n */\n async getMultipleComponents(tags: string[]): Promise<ComponentMatch[]> {\n if (!Array.isArray(tags)) {\n throw new Error(\"Tags must be an array\");\n }\n\n const results = await Promise.all(\n tags.map((tag) => this.getComponentDetails(tag)),\n );\n\n return results.filter(\n (r): r is ComponentMatch => r !== null,\n );\n }\n}\n\n","/**\n * Formatters\n * Utilities to format search results in different formats\n */\n\nimport type {\n ComponentMatch,\n SearchResults,\n} from \"../services/pinecone/pinecone-service.js\";\n\nexport class Formatters {\n /**\n * Formats results in structured format (JSON-friendly)\n */\n static toStructured(searchResults: SearchResults): {\n query: string;\n summary: {\n totalMatches: number;\n relevantMatches: number;\n minScore: number;\n };\n components: Array<{\n id: string;\n tag: string;\n score: number;\n name: string;\n framework: string;\n category: string;\n overview: string;\n visual: string;\n technical: string;\n keywords: string[];\n }>;\n } {\n return {\n query: searchResults.query,\n summary: {\n totalMatches: searchResults.totalMatches,\n relevantMatches: searchResults.relevantMatches,\n minScore: searchResults.searchMetadata.minScore,\n },\n components: searchResults.matches.map((match) => ({\n id: match.id,\n tag: match.tag,\n score: match.score,\n name: match.name,\n framework: match.framework,\n category: match.category,\n overview: match.overview,\n visual: match.visual,\n technical: match.technical,\n keywords: match.keywords,\n })),\n };\n }\n\n /**\n * Formats results in readable markdown format\n */\n static toMarkdown(searchResults: SearchResults): string {\n if (!searchResults.matches || searchResults.matches.length === 0) {\n return `## No similar components found\n\n**Query:** \"${searchResults.query}\"\n\nSuggestion: Try more general terms or verify that components are indexed.`;\n }\n\n //Verify to add or hide to show what was queried // **Query:** \"${searchResults.query}\"\n let markdown = `## Search Results\n**Components found:** ${searchResults.relevantMatches} of ${searchResults.totalMatches}\n---\n`;\n\n searchResults.matches.forEach((match, index) => {\n markdown += `### ${index + 1}. ${match.tag}\n\n**Technical Documentation:**\n${match.technical || \"No technical documentation available\"}\n\n---\n\n`;\n });\n\n return markdown;\n }\n\n /**\n * Formats multiple components for context in prompts\n * Uses JSON format for better LLM understanding\n */\n static matchesToContext(matches: ComponentMatch[]): string {\n if (!matches || matches.length === 0) {\n return \"No components found.\";\n }\n\n // Use JSON format for component documentation which works well with LLMs\n // This provides structured data that LLMs can parse better than plain text\n const componentsArray = matches.map((match) => ({\n tag: match.tag,\n score: match.score, // Pinecone ranking\n overview: match.overview,\n visual: match.visual,\n keywords: match.keywords,\n }));\n\n // Return as JSON string with clear structure\n return JSON.stringify({ components: componentsArray }, null, 2);\n }\n\n /**\n * Formats components with only essential fields (tag, score, overview) for lightweight filtering\n * Used when sending to Frida for tag-only filtering\n */\n static matchesToLightweightContext(matches: ComponentMatch[]): string {\n if (!matches || matches.length === 0) {\n return \"No components found.\";\n }\n\n // Only include tag, score, and overview for lightweight filtering\n const componentsArray = matches.map((match) => ({\n tag: match.tag,\n score: match.score,\n overview: match.overview,\n }));\n\n // Return as JSON string with clear structure\n return JSON.stringify({ components: componentsArray }, null, 2);\n }\n\n}\n\n","/**\n * Session Validator\n *\n * Validates a session token against the figma2frida backend.\n * Returns the projectId, llmopsApiKey, userId, and email\n * for the MCP server to use.\n */\n\nimport { logger } from \"../../utils/logger.js\";\n\nconst VALIDATION_URL =\n \"https://apis.f2fmcp.fridaplatform.online/validateSession\";\n\nexport interface SessionValidationResult {\n valid: boolean;\n projectId: string;\n llmopsApiKey: string;\n userId: string;\n email: string;\n}\n\n/**\n * Validates a session token and returns MCP config.\n *\n * @param sessionToken - The session token from --session-token CLI arg\n * @returns Session data including projectId, llmopsApiKey, userId, email\n */\nexport async function validateSession(sessionToken: string): Promise<SessionValidationResult> {\n logger.info(\"🔐 Validating session...\");\n\n try {\n const response = await fetch(VALIDATION_URL, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify({ sessionToken }),\n });\n\n const data = await response.json() as Record<string, unknown>;\n\n if (response.ok && data.valid === true) {\n logger.info(`✅ Session valid for ${data.email}`);\n return {\n valid: true,\n projectId: data.projectId as string,\n llmopsApiKey: data.llmopsApiKey as string,\n userId: data.userId as string,\n email: data.email as string,\n };\n }\n\n const errorMessage = (data.error as string) || \"Unknown error\";\n logger.error(`❌ Session validation failed: ${errorMessage}`);\n throw new Error(`Session validation failed: ${errorMessage}`);\n } catch (error) {\n if (error instanceof Error && error.message.startsWith(\"Session validation failed:\")) {\n throw error;\n }\n\n logger.error(\"❌ Failed to validate session:\", error instanceof Error ? error.message : String(error));\n\n if (error instanceof Error) {\n if (error.message.includes(\"fetch failed\") || error.message.includes(\"ECONNREFUSED\")) {\n throw new Error(\"Network error: Could not reach validation service\");\n } else if (error.message.includes(\"timeout\")) {\n throw new Error(\"Request timeout: Validation service did not respond in time\");\n }\n }\n\n throw new Error(`Session validation failed: ${error instanceof Error ? error.message : String(error)}`);\n }\n}\n","/**\n * Frida AI Client\n * Optional client for Frida AI integration\n */\n\nimport \"dotenv/config\";\nimport { logger } from \"../../utils/logger.js\";\n\n/**\n * `POST /v1/responses` non-stream body: `object: \"response\"`, `output` = items such as\n * `{ type: \"message\", content: [{ type: \"output_text\", text: \"...\" }] }`.\n */\nfunction extractFromResponsesApiOutput(data: Record<string, unknown>): { answer: string; parseSource: string } | null {\n const output = data.output;\n if (!Array.isArray(output)) {\n return null;\n }\n\n const textParts: string[] = [];\n for (const item of output) {\n if (!item || typeof item !== \"object\") {\n continue;\n }\n const o = item as Record<string, unknown>;\n if (o.type !== \"message\") {\n continue;\n }\n const content = o.content;\n if (!Array.isArray(content)) {\n continue;\n }\n for (const block of content) {\n if (!block || typeof block !== \"object\") {\n continue;\n }\n const b = block as Record<string, unknown>;\n if (b.type === \"output_text\" && typeof b.text === \"string\" && b.text.length > 0) {\n textParts.push(b.text);\n }\n }\n }\n\n const joined = textParts.join(\"\\n\").trim();\n if (!joined) {\n return null;\n }\n\n const parseSource =\n data.object === \"response\"\n ? \"response.output[].message.output_text\"\n : \"output[].message.output_text\";\n return { answer: joined, parseSource };\n}\n\n/** Parses Frida /responses JSON and records which top-level shape was used. */\nfunction parseFridaAnswer(data: Record<string, unknown>): { answer: string; parseSource: string } {\n if (typeof data.response === \"string\" && data.response) {\n return { answer: data.response, parseSource: \"response\" };\n }\n\n const structured = extractFromResponsesApiOutput(data);\n if (structured) {\n return structured;\n }\n\n if (typeof data.output === \"string\" && data.output) {\n return { answer: data.output, parseSource: \"output\" };\n }\n\n const choices = data.choices as Array<{ message?: { content?: unknown } }> | undefined;\n const msg = choices?.[0]?.message;\n if (msg && typeof msg.content === \"string\" && msg.content) {\n return { answer: msg.content, parseSource: \"choices[0].message.content\" };\n }\n\n if (typeof data.content === \"string\" && data.content) {\n return { answer: data.content, parseSource: \"content\" };\n }\n\n return { answer: JSON.stringify(data), parseSource: \"fallback_json\" };\n}\n\nexport interface FridaClientOptions {\n apiKey?: string;\n apiUrl?: string;\n model?: string;\n maxTokens?: number;\n}\n\nexport interface FridaResponse {\n success: boolean;\n error: string | null;\n response: string | null;\n metadata?: {\n model: string;\n tokensUsed: number | null;\n };\n}\n\nexport class FridaClient {\n private apiKey: string | undefined;\n private apiUrl: string | undefined;\n private model: string;\n private maxTokens: number;\n private enabled: boolean;\n\n constructor(options: FridaClientOptions = {}) {\n this.apiKey = options.apiKey || process.env.FRIDA_BEARER_TOKEN;\n this.apiUrl = options.apiUrl || process.env.FRIDA_API_URL;\n this.model = options.model || process.env.FRIDA_MODEL || \"gpt-5.1-codex\";\n this.maxTokens = options.maxTokens || (process.env.FRIDA_MAX_TOKENS ? parseInt(process.env.FRIDA_MAX_TOKENS, 10) : 4096);\n this.enabled = !!(this.apiKey && this.apiUrl);\n }\n\n /**\n * Checks if Frida is configured\n */\n isEnabled(): boolean {\n return this.enabled;\n }\n\n /**\n * Generates the unified prompt for component recommendation\n * Optimized for Approach B: lightweight context for selection, technical docs handled separately\n */\n buildPrompt(question: string, context: string): string {\n return `You are an expert design system specialist.\nYour goal is to analyze the Figma design context and recommend the mostly suitable component(s) from the design system.\n\n**CONTEXT:**\nThe user has a Figma design element and needs to know which component from the library to use.\nBelow is a list of available components with their visual descriptions and overviews.\n\n**AVAILABLE COMPONENTS:**\n${context}\n\n**INSTRUCTIONS:**\n1. Analyze the user's design description (Question).\n2. Compare it against the **Visual** and **Overview** of the available components.\n3. Select the best matching component(s).\n4. Provide a brief reasoning for your selection.\n\n**RESPONSE FORMAT:**\nYour response must be concise and follow this format:\n\n🎯 **Recommended Component:** [Tag]\n**Confidence:** [High/Medium/Low]\n**Reasoning:** [1-2 sentences explaining why this visual/functional description matches the design]\n\nUSER QUESTION:\n${question}`;\n }\n\n /**\n * Generates a prompt specifically for filtering components by tags only\n * Returns only component tags that match the query description\n */\n buildFilterPrompt(query: string, context: string): string {\n return `You are a design system expert. Analyze the query and component list below.\n\n**QUERY:** ${query}\n\n**AVAILABLE COMPONENTS:**\n${context}\n\n**TASK:** \nAnalyze the query description and compare it against the component overviews and scores.\nReturn ONLY the component tags (comma-separated) that best match the query description.\n\n**RESPONSE FORMAT:**\nReturn only the tags separated by commas. Do not include explanations, reasoning, or any other text.\nExample format: tag1, tag2, tag3\n\n**IMPORTANT:** Only return tags that are in the available components list above.`;\n }\n\n /**\n * Asks a question to Frida AI\n * @param question - User question\n * @param context - Context with component information\n * @returns Frida response\n */\n async ask(question: string, context: string): Promise<FridaResponse> {\n if (!this.enabled) {\n return {\n success: false,\n error:\n \"Frida AI is not configured. Set FRIDA_BEARER_TOKEN and FRIDA_API_URL in .env\",\n response: null,\n };\n }\n\n if (!question || typeof question !== \"string\") {\n return {\n success: false,\n error: \"Question must be a non-empty string\",\n response: null,\n };\n }\n\n logger.debug(\"CALLING FRIDA AI\");\n\n const prompt = this.buildPrompt(question, context);\n\n logger.debug(`API URL: ${this.apiUrl}`);\n logger.debug(`Model: ${this.model}`);\n logger.debug(`Question length: ${question.length} chars`);\n logger.debug(`Context length: ${context.length} chars`);\n logger.debug(`Max tokens: ${this.maxTokens}`);\n\n try {\n const startTime = Date.now();\n const response = await fetch(this.apiUrl!, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${this.apiKey}`,\n },\n body: JSON.stringify({\n model: this.model,\n input: prompt,\n max_tokens: this.maxTokens,\n stream: false,\n email: process.env.MCP_USER_EMAIL || \"figma2frida_mcp@fridaplatform.com\",\n }),\n });\n const fetchTime = Date.now() - startTime;\n logger.debug(`API request completed in ${fetchTime}ms - Status: ${response.status}`);\n\n if (!response.ok) {\n logger.error(`API Error: ${response.status} ${response.statusText}`);\n throw new Error(`API Error: ${response.status} ${response.statusText}`);\n }\n\n const data = (await response.json()) as Record<string, unknown>;\n const { answer, parseSource } = parseFridaAnswer(data);\n\n const tokensUsed = ((data.usage as { total_tokens?: number })?.total_tokens as number | null) || null;\n const answerPreview = answer.replace(/\\s+/g, \" \").slice(0, 200);\n logger.debug(\n `Frida answer preview (ask): \"${answerPreview}\" (from \"${parseSource}\")`,\n );\n\n logger.debug(\n `Frida response OK (ask): HTTP ${response.status} in ${fetchTime}ms — parsed from \"${parseSource}\", ${answer.length} chars, tokens=${tokensUsed ?? \"n/a\"}`,\n );\n\n return {\n success: true,\n error: null,\n response: answer,\n metadata: {\n model: this.model,\n tokensUsed,\n },\n };\n } catch (error) {\n logger.error(\"Error calling Frida AI:\", error);\n return {\n success: false,\n error: error instanceof Error ? error.message : String(error),\n response: null,\n };\n }\n }\n\n /**\n * Asks Frida AI to filter components and return only matching tags\n * Uses buildFilterPrompt instead of buildPrompt for tag-only responses\n * @param query - Search query description\n * @param context - Lightweight component context (tag, score, overview)\n * @returns Frida response with component tags\n */\n async askForFilter(query: string, context: string): Promise<FridaResponse> {\n if (!this.enabled) {\n return {\n success: false,\n error:\n \"Frida AI is not configured. Set FRIDA_BEARER_TOKEN and FRIDA_API_URL in .env\",\n response: null,\n };\n }\n\n if (!query || typeof query !== \"string\") {\n return {\n success: false,\n error: \"Query must be a non-empty string\",\n response: null,\n };\n }\n\n logger.debug(\"CALLING FRIDA AI FOR FILTERING\");\n\n // Use buildFilterPrompt instead of buildPrompt\n const prompt = this.buildFilterPrompt(query, context);\n\n logger.debug(`API URL: ${this.apiUrl}`);\n logger.debug(`Model: ${this.model}`);\n logger.debug(`Query length: ${query.length} chars`);\n logger.debug(`Context length: ${context.length} chars`);\n logger.debug(`Max tokens: ${this.maxTokens}`);\n\n try {\n const startTime = Date.now();\n const response = await fetch(this.apiUrl!, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${this.apiKey}`,\n },\n body: JSON.stringify({\n model: this.model,\n input: prompt,\n max_tokens: this.maxTokens,\n stream: false,\n email: process.env.MCP_USER_EMAIL || \"figma2frida_mcp@fridaplatform.com\",\n }),\n });\n const fetchTime = Date.now() - startTime;\n logger.debug(`API request completed in ${fetchTime}ms - Status: ${response.status}`);\n\n if (!response.ok) {\n logger.error(`API Error: ${response.status} ${response.statusText}`);\n throw new Error(`API Error: ${response.status} ${response.statusText}`);\n }\n\n const data = (await response.json()) as Record<string, unknown>;\n const { answer, parseSource } = parseFridaAnswer(data);\n\n const tokensUsed = ((data.usage as { total_tokens?: number })?.total_tokens as number | null) || null;\n const answerPreview = answer.replace(/\\s+/g, \" \").slice(0, 200);\n logger.debug(\n `Frida answer preview (filter): \"${answerPreview}\" (from \"${parseSource}\")`,\n );\n\n logger.debug(\n `Frida response OK (filter): HTTP ${response.status} in ${fetchTime}ms — parsed from \"${parseSource}\", ${answer.length} chars, tokens=${tokensUsed ?? \"n/a\"}`,\n );\n\n return {\n success: true,\n error: null,\n response: answer,\n metadata: {\n model: this.model,\n tokensUsed,\n },\n };\n } catch (error) {\n logger.error(\"Error calling Frida AI for filtering:\", error);\n return {\n success: false,\n error: error instanceof Error ? error.message : String(error),\n response: null,\n };\n }\n }\n}\n","/**\n * Library Filter Handler\n * Handles Frida AI filtering of component search results from Pinecone\n */\n\nimport type { ComponentMatch, SearchResults } from \"../services/pinecone/pinecone-service.js\";\nimport { FridaClient } from \"../services/frida/frida-client.js\";\nimport { Formatters } from \"../utils/formatters.js\";\nimport { logger } from \"../utils/logger.js\";\n\n/**\n * Parses component tags from Frida's response\n * Handles various formats: comma-separated, newline-separated, or list format\n */\nfunction parseTagsFromFridaResponse(response: string, availableTags: string[]): string[] {\n if (!response || typeof response !== \"string\") {\n return [];\n }\n\n // Normalize the response: remove markdown formatting, extra whitespace\n let normalized = response.trim();\n \n // Remove common markdown formatting\n normalized = normalized.replace(/\\*\\*/g, \"\"); // Remove bold\n normalized = normalized.replace(/#+/g, \"\"); // Remove headers\n normalized = normalized.replace(/```[\\s\\S]*?```/g, \"\"); // Remove code blocks\n \n // Try to extract tags from various formats\n // Format 1: Comma-separated (tag1, tag2, tag3)\n let tags: string[] = [];\n \n // Split by comma first\n const commaSplit = normalized.split(\",\").map(t => t.trim());\n \n // Also try splitting by newline\n const newlineSplit = normalized.split(/\\n+/).map(t => t.trim());\n \n // Combine both approaches and filter\n const allCandidates = [...commaSplit, ...newlineSplit]\n .map(tag => {\n // Remove common prefixes/suffixes\n tag = tag.replace(/^[-•*]\\s*/, \"\"); // Remove list markers\n tag = tag.replace(/^tag:\\s*/i, \"\"); // Remove \"tag:\" prefix\n tag = tag.replace(/^tags?:\\s*/i, \"\"); // Remove \"tags:\" prefix\n tag = tag.replace(/[.,;]$/, \"\"); // Remove trailing punctuation\n return tag.trim();\n })\n .filter(tag => tag.length > 0);\n\n // Match against available tags (case-insensitive)\n for (const candidate of allCandidates) {\n const candidateLower = candidate.toLowerCase();\n // Find exact match or partial match\n const matchedTag = availableTags.find(t => \n t.toLowerCase() === candidateLower || \n t.toLowerCase().includes(candidateLower) ||\n candidateLower.includes(t.toLowerCase())\n );\n \n if (matchedTag && !tags.includes(matchedTag)) {\n tags.push(matchedTag);\n }\n }\n\n logger.debug(`Parsed ${tags.length} tags from Frida response: ${tags.join(\", \")}`);\n return tags;\n}\n\nexport interface FilterComponentsOptions {\n query: string;\n searchResults: SearchResults;\n}\n\nexport interface FilterComponentsResult {\n filteredResults: SearchResults;\n wasFiltered: boolean;\n fridaResponseTime?: number;\n}\n\n/**\n * Filters component search results using Frida AI\n * If Frida is enabled, it will analyze the query and component overviews\n * to return only the most relevant component tags\n */\nexport async function filterComponentsWithFrida(\n options: FilterComponentsOptions\n): Promise<FilterComponentsResult> {\n const { query, searchResults } = options;\n\n // If no results, return early\n if (!searchResults.matches || searchResults.matches.length === 0) {\n return {\n filteredResults: searchResults,\n wasFiltered: false,\n };\n }\n\n // Create FridaClient instance for filtering\n const fridaClient = new FridaClient();\n \n let filteredMatches: ComponentMatch[] = searchResults.matches;\n let wasFiltered = false;\n let fridaResponseTime: number | undefined;\n \n // If Frida is enabled, use it to filter components\n if (fridaClient.isEnabled()) {\n try {\n logger.debug(\"Using Frida AI to filter components...\");\n \n // Create lightweight context with only (tag, score, overview)\n const lightweightContext = Formatters.matchesToLightweightContext(searchResults.matches);\n \n // Call Frida with askForFilter method (uses buildFilterPrompt internally)\n const fridaStartTime = Date.now();\n const fridaResponse = await fridaClient.askForFilter(query, lightweightContext);\n fridaResponseTime = Date.now() - fridaStartTime;\n \n logger.debug(`Frida AI filtering completed in ${fridaResponseTime}ms - Success: ${fridaResponse.success}`);\n \n if (fridaResponse.success && fridaResponse.response) {\n // Parse tags from Frida response\n const availableTags = searchResults.matches.map(m => m.tag);\n const selectedTags = parseTagsFromFridaResponse(fridaResponse.response, availableTags);\n \n if (selectedTags.length > 0) {\n // Filter matches to only include selected tags\n filteredMatches = searchResults.matches.filter(match => \n selectedTags.includes(match.tag)\n );\n \n wasFiltered = true;\n logger.debug(`Frida filtered ${filteredMatches.length} components from ${searchResults.matches.length} total matches`);\n } else {\n logger.warn(\"Frida returned no valid tags, using all Pinecone results\");\n }\n } else {\n logger.warn(`Frida filtering failed: ${fridaResponse.error || \"Unknown error\"}, using all Pinecone results`);\n }\n } catch (fridaError) {\n logger.warn(`Frida filtering error: ${fridaError instanceof Error ? fridaError.message : String(fridaError)}, using all Pinecone results`);\n // Continue with all results if Frida fails\n }\n } else {\n logger.debug(\"Frida AI not configured, skipping filtering step\");\n }\n\n // Create filtered search results\n const filteredSearchResults: SearchResults = {\n ...searchResults,\n matches: filteredMatches,\n relevantMatches: filteredMatches.length,\n };\n\n return {\n filteredResults: filteredSearchResults,\n wasFiltered,\n fridaResponseTime,\n };\n}\n"],"mappings":";;;AAcA,SAAS,SAAS;AAClB,OAAO,WAAW;AAClB,SAAS,eAAe;AACxB,SAAS,eAAiD;AAC1D,SAAS,qBAAqB;AAC9B,SAAS,qBAAqB;AAC9B,SAAS,SAAS,YAAY;;;ACC9B,SAAS,cAAwB;AAC/B,QAAM,YAAY,QAAQ,KAAK,SAAS,WAAW,KAAK,QAAQ,IAAI,UAAU;AAC9E,QAAM,eAAe,QAAQ,IAAI,aAAa;AAE9C,MAAI,gBAAgB,CAAC,WAAW;AAC9B,WAAO;AAAA,EACT;AAGA,SAAO;AACT;AAIA,IAAM,cAAc,QAAQ,IAAI,gBAAgB,UAAU,QAAQ,IAAI,gBAAgB;AAGtF,IAAM,aAAa,CAAC,OAAe,YAAoB,SAAgB;AACrE,QAAM,cAAc,KAAK,SAAS,IAC9B,IAAI,KAAK,KAAK,OAAO,IAAI,KAAK,IAAI,SAAO,OAAO,QAAQ,WAAW,KAAK,UAAU,GAAG,IAAI,OAAO,GAAG,CAAC,EAAE,KAAK,GAAG,CAAC,KAC/G,IAAI,KAAK,KAAK,OAAO;AAEzB,MAAI,aAAa;AACf,YAAQ,OAAO,MAAM,GAAG,WAAW;AAAA,CAAI;AAAA,EACzC,OAAO;AACL,YAAQ,IAAI,WAAW;AAAA,EACzB;AACF;AAEO,IAAM,SAAS;AAAA,EACpB,OAAO,CAAC,YAAoB,SAAgB;AAC1C,QAAI,YAAY,KAAK,eAAgB;AACnC,iBAAW,SAAS,SAAS,GAAG,IAAI;AAAA,IACtC;AAAA,EACF;AAAA,EACA,MAAM,CAAC,YAAoB,SAAgB;AACzC,QAAI,YAAY,KAAK,cAAe;AAClC,iBAAW,QAAQ,SAAS,GAAG,IAAI;AAAA,IACrC;AAAA,EACF;AAAA,EACA,MAAM,CAAC,YAAoB,SAAgB;AACzC,QAAI,YAAY,KAAK,cAAe;AAClC,iBAAW,QAAQ,SAAS,GAAG,IAAI;AAAA,IACrC;AAAA,EACF;AAAA,EACA,OAAO,CAAC,YAAoB,SAAgB;AAC1C,QAAI,YAAY,KAAK,eAAgB;AACnC,iBAAW,SAAS,SAAS,GAAG,IAAI;AAAA,IACtC;AAAA,EACF;AACF;;;AClEA,SAAS,cAAc;AACvB,SAAS,0BAA0B;AA+B5B,IAAM,cAAN,MAAkB;AAAA,EACf,SAAwB;AAAA,EACxB,YAAqB;AAAA,EACrB;AAAA,EAER,YAAY,WAAmB,6BAA6B;AAC1D,SAAK,WAAW;AAAA,EAClB;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,QAAQ,UAAkB,GAAkB;AAChD,QAAI,KAAK,aAAa,KAAK,QAAQ;AACjC,aAAO,MAAM,gDAAgD;AAC7D;AAAA,IACF;AAEA,WAAO,MAAM,6BAA6B;AAC1C,WAAO,MAAM,QAAQ,KAAK,QAAQ,EAAE;AACpC,WAAO,MAAM,gBAAgB,OAAO,EAAE;AACtC,WAAO,MAAM,6BAA6B,KAAK,SAAS,YAAY,CAAC,CAAC,KAAK,MAAM,EAAE;AAEnF,aAAS,UAAU,GAAG,UAAU,SAAS,WAAW;AAClD,YAAM,mBAAmB,KAAK,IAAI;AAClC,aAAO,MAAM,WAAW,UAAU,CAAC,IAAI,OAAO,cAAc;AAE5D,UAAI;AACF,eAAO,MAAM,+BAA+B;AAC5C,aAAK,SAAS,IAAI;AAAA,UAChB;AAAA,YACE,MAAM;AAAA,YACN,SAAS;AAAA,UACX;AAAA,UACA;AAAA,YACE,cAAc;AAAA,cACZ,OAAO,CAAC;AAAA,YACV;AAAA,UACF;AAAA,QACF;AACA,eAAO,MAAM,uBAAuB;AAEpC,eAAO,MAAM,+BAA+B,KAAK,QAAQ,EAAE;AAC3D,cAAM,YAAY,IAAI,mBAAmB,IAAI,IAAI,KAAK,QAAQ,CAAC;AAC/D,eAAO,MAAM,0BAA0B;AAEvC,eAAO,MAAM,0BAA0B;AACvC,cAAM,mBAAmB,KAAK,IAAI;AAClC,cAAM,KAAK,OAAO,QAAQ,SAAS;AACnC,cAAM,cAAc,KAAK,IAAI,IAAI;AACjC,eAAO,MAAM,6BAA6B,WAAW,IAAI;AAEzD,aAAK,YAAY;AACjB,cAAM,YAAY,KAAK,IAAI,IAAI;AAE/B,eAAO,MAAM,2BAA2B,SAAS,KAAK;AACtD;AAAA,MACF,SAAS,OAAO;AACd,cAAM,cAAc,KAAK,IAAI,IAAI;AACjC,eAAO,MAAM,sBAAsB,UAAU,CAAC,IAAI,OAAO,YAAY,WAAW,KAAK;AACrF,eAAO,MAAM,eAAe,OAAO,aAAa,QAAQ,OAAO,KAAK,EAAE;AACtE,eAAO,MAAM,kBAAkB,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC,EAAE;AAGvF,YAAI,SAAS,OAAO,UAAU,UAAU;AACtC,gBAAM,WAAW;AACjB,cAAI,UAAU,UAAU;AACtB,mBAAO,MAAM,eAAe,SAAS,IAAI,EAAE;AAAA,UAC7C;AACA,cAAI,WAAW,UAAU;AACvB,mBAAO,MAAM,gBAAgB,SAAS,KAAK;AAAA,UAC7C;AACA,cAAI,YAAY,UAAU;AACxB,mBAAO,MAAM,gBAAgB,SAAS,MAAM,EAAE;AAAA,UAChD;AACA,cAAI,gBAAgB,UAAU;AAC5B,mBAAO,MAAM,qBAAqB,SAAS,UAAU,EAAE;AAAA,UACzD;AAAA,QACF;AAEA,YAAI,iBAAiB,SAAS,MAAM,OAAO;AACzC,iBAAO,MAAM,gBAAgB,MAAM,KAAK;AAAA,QAC1C;AAEA,YAAI,YAAY,UAAU,GAAG;AAC3B,iBAAO,MAAM,mCAAmC,OAAO,YAAY;AACnE,iBAAO,MAAM,QAAQ,KAAK,QAAQ,EAAE;AACpC,gBAAM,IAAI;AAAA,YACR,qCAAqC,KAAK,QAAQ,UAAU,OAAO;AAAA,UACrE;AAAA,QACF;AAEA,cAAM,WAAW,OAAQ,UAAU;AACnC,eAAO,MAAM,WAAW,QAAQ,oBAAoB;AAEpD,cAAM,IAAI;AAAA,UAAQ,CAAC,YACjB,WAAW,SAAS,QAAQ;AAAA,QAC9B;AACA,eAAO,MAAM,4BAA4B;AAAA,MAC3C;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,kBAAiC;AAC7C,QAAI,CAAC,KAAK,aAAa,CAAC,KAAK,QAAQ;AACnC,aAAO,MAAM,oEAAoE;AACjF,YAAM,KAAK,QAAQ;AAAA,IACrB,OAAO;AACL,aAAO,MAAM,wDAAwD;AAAA,IACvE;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKQ,gBAAgB,QAAqC;AAC3D,QAAI,CAAC,OAAQ,QAAO;AAEpB,WAAO,OAAO,QAAQ,MAAM,GAAG;AAAA,EACjC;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,mBAC+B;AACnC,UAAM,KAAK,gBAAgB;AAG3B,UAAM,OAAO;AAAA;AAAA,MAEX,iBAAiB;AAAA,MACjB,kBAAkB;AAAA,MAClB,WAAW;AAAA,IACb;AAEA,WAAO,MAAM,yCAAyC,IAAI;AAE1D,QAAI;AACF,YAAM,SAAS,MAAM,KAAK,OAAQ,SAAS;AAAA,QACzC,MAAM;AAAA,QACN,WAAW;AAAA,MACb,CAAC;AAID,YAAM,eAAe;AACrB,UAAI,aAAa,WAAW,MAAM,QAAQ,aAAa,OAAO,GAAG;AAC/D,cAAM,kBAAkB;AAAA,UACtB,aAAa,QAAQ,CAAC;AAAA;AAAA,UACtB,aAAa,QAAQ,CAAC;AAAA;AAAA,UACtB,aAAa,QAAQ,CAAC;AAAA;AAAA,QACxB,EAAE,OAAO,CAAC,SAAS,SAAS,MAAS;AAErC,eAAO;AAAA,UACL,SAAS;AAAA,QACX;AAAA,MACF;AAEA,aAAO;AAAA,IACT,SAAS,OAAO;AAEd,aAAO,KAAK,2DAA2D;AACvE,WAAK,YAAY;AACjB,YAAM,KAAK,QAAQ;AAEnB,YAAM,SAAS,MAAM,KAAK,OAAQ,SAAS;AAAA,QACzC,MAAM;AAAA,QACN,WAAW;AAAA,MACb,CAAC;AAED,aAAO;AAAA,IACT;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,cAC0B;AAC9B,UAAM,KAAK,gBAAgB;AAE3B,UAAM,OAAO;AAAA;AAAA,MAEX,iBAAiB;AAAA,MACjB,kBAAkB;AAAA,MAClB,WAAW;AAAA,IACb;AAEA,WAAO,MAAM,mCAAmC,IAAI;AAEpD,QAAI;AACF,YAAM,SAAS,MAAM,KAAK,OAAQ,SAAS;AAAA,QACzC,MAAM;AAAA,QACN,WAAW;AAAA,MACb,CAAC;AAID,YAAM,eAAe;AACrB,UAAI,aAAa,WAAW,MAAM,QAAQ,aAAa,OAAO,GAAG;AAC/D,cAAM,kBAAkB;AAAA,UACtB,aAAa,QAAQ,CAAC;AAAA;AAAA,QACxB,EAAE,OAAO,CAAC,SAAS,SAAS,MAAS;AAErC,eAAO;AAAA,UACL,SAAS;AAAA,QACX;AAAA,MACF;AAEA,aAAO;AAAA,IACT,SAAS,OAAO;AAEd,aAAO,KAAK,qDAAqD;AACjE,WAAK,YAAY;AACjB,YAAM,KAAK,QAAQ;AAEnB,YAAM,SAAS,MAAM,KAAK,OAAQ,SAAS;AAAA,QACzC,MAAM;AAAA,QACN,WAAW;AAAA,MACb,CAAC;AAED,aAAO;AAAA,IACT;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,gBAC4B;AAChC,UAAM,KAAK,gBAAgB;AAI3B,QAAI;AACF,YAAM,SAAS,MAAM,KAAK,OAAQ,SAAS;AAAA,QACzC,MAAM;AAAA,QACN,WAAW;AAAA;AAAA,QAEX;AAAA,MACF,CAAC;AAED,aAAO;AAAA,IACT,SAAS,OAAO;AAEd,aAAO,KAAK,uDAAuD;AACnE,WAAK,YAAY;AACjB,YAAM,KAAK,QAAQ;AAEnB,YAAM,SAAS,MAAM,KAAK,OAAQ,SAAS;AAAA,QACzC,MAAM;AAAA,QACN,WAAW;AAAA;AAAA,QAEX;AAAA,MACF,CAAC;AAED,aAAO;AAAA,IACT;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,aAA4B;AAChC,QAAI,KAAK,QAAQ;AACf,YAAM,KAAK,OAAO,MAAM;AACxB,WAAK,YAAY;AACjB,WAAK,SAAS;AACd,aAAO,MAAM,6BAA6B;AAAA,IAC5C;AAAA,EACF;AACF;;;AClTO,IAAM,2BAAN,MAA+B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASpC,aAAa,cAAgC;AAC3C,QAAI,CAAC,aAAc,QAAO,CAAC;AAE3B,UAAM,QAAkB,CAAC;AACzB,UAAM,OAAO,oBAAI,IAAY;AAC7B,UAAM,UAAU,aAAa,SAAS,8BAA8B;AAEpE,eAAW,SAAS,SAAS;AAC3B,YAAM,MAAM,MAAM,CAAC;AACnB,YAAM,OAAO,OAAO,QAAQ,WAAW,IAAI,KAAK,IAAI;AAGpD,UAAI,QAAQ,CAAC,KAAK,IAAI,IAAI,GAAG;AAC3B,aAAK,IAAI,IAAI;AACb,cAAM,KAAK,IAAI;AAAA,MACjB;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AACF;;;AC9BO,IAAM,yBAAN,MAA6B;AAAA;AAAA;AAAA;AAAA,EAIlC,yBAAyB,MAAc,QAAgB,YAAuC;AAE5F,SAAK,gBAAgB,MAAM,UAAU;AAGrC,SAAK,kBAAkB,QAAQ,UAAU;AAAA,EAC3C;AAAA;AAAA;AAAA;AAAA,EAKQ,gBAAgB,MAAc,YAAuC;AAE3E,UAAM,kBAAkB,KAAK,SAAS,8BAA8B;AACpE,UAAM,YAAsB,CAAC;AAE7B,eAAW,SAAS,iBAAiB;AACnC,YAAM,OAAO,MAAM,CAAC,EAAE,KAAK;AAC3B,UAAI,QAAQ,KAAK,SAAS,GAAG;AAC3B,kBAAU,KAAK,KAAK,YAAY,CAAC;AAAA,MACnC;AAAA,IACF;AAGA,UAAM,kBAAkB,UAAU,CAAC,KAAK;AAGxC,SAAK,iBAAiB,WAAW,UAAU;AAG3C,SAAK,mBAAmB,MAAM,WAAW,UAAU;AAGnD,SAAK,iBAAiB,MAAM,iBAAiB,UAAU;AAGvD,SAAK,oBAAoB,MAAM,WAAW,UAAU;AAGpD,SAAK,sBAAsB,MAAM,UAAU;AAG3C,SAAK,mBAAmB,MAAM,UAAU;AAGxC,SAAK,0BAA0B,MAAM,UAAU;AAG/C,SAAK,sBAAsB,MAAM,UAAU;AAG3C,SAAK,wBAAwB,MAAM,UAAU;AAG7C,SAAK,gBAAgB,MAAM,WAAW,UAAU;AAAA,EAClD;AAAA;AAAA;AAAA;AAAA;AAAA,EAMQ,iBAAiB,WAAqB,YAAuC;AACnF,UAAM,oBAAoB;AAAA,MACxB;AAAA,MAAU;AAAA,MAAU;AAAA,MAAQ;AAAA,MAAa;AAAA,MAAW;AAAA,MACpD;AAAA,MAAQ;AAAA,MAAW;AAAA,MAAO;AAAA,MAAc;AAAA,MAAW;AAAA,MACnD;AAAA,MAAQ;AAAA,MAAQ;AAAA,MAAO;AAAA,MAAS;AAAA,MAAS;AAAA,MAAS;AAAA,MAAO;AAAA,MACzD;AAAA,IACF;AAEA,eAAW,QAAQ,WAAW;AAC5B,YAAM,YAAY,KAAK,YAAY;AAGnC,iBAAW,WAAW,mBAAmB;AACvC,YAAI,UAAU,SAAS,OAAO,GAAG;AAE/B,cAAI,YAAY,SAAS,YAAY,cAAc;AACjD,gBAAI,CAAC,WAAW,UAAU,SAAS,YAAY,GAAG;AAChD,yBAAW,UAAU,KAAK,YAAY;AAAA,YACxC;AAAA,UACF,WAAW,YAAY,aAAa,YAAY,aAAa,YAAY,aAAa;AACpF,gBAAI,CAAC,WAAW,UAAU,SAAS,WAAW,GAAG;AAC/C,yBAAW,UAAU,KAAK,WAAW;AAAA,YACvC;AAAA,UACF,WAAW,YAAY,aAAa,YAAY,SAAS;AACvD,gBAAI,CAAC,WAAW,UAAU,SAAS,SAAS,GAAG;AAC7C,yBAAW,UAAU,KAAK,SAAS;AAAA,YACrC;AAAA,UACF,WAAW,CAAC,WAAW,UAAU,SAAS,OAAO,GAAG;AAClD,uBAAW,UAAU,KAAK,OAAO;AAAA,UACnC;AACA;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKQ,mBAAmB,MAAc,WAAqB,YAAuC;AACnG,UAAM,UAAU,KAAK,YAAY,IAAI,MAAM,UAAU,KAAK,GAAG;AAG7D,UAAM,kBAAkB,KAAK,SAAS,4EAA4E;AAClH,UAAM,iBAA2B,CAAC;AAClC,eAAW,SAAS,iBAAiB;AACnC,UAAI,MAAM,CAAC,EAAG,gBAAe,KAAK,MAAM,CAAC,EAAE,YAAY,CAAC;AAAA,IAC1D;AACA,UAAM,qBAAqB,eAAe,KAAK,GAAG;AAGlD,UAAM,eAAe,UAAU,MAAM;AAGrC,QAAI,2CAA2C,KAAK,YAAY,GAAG;AACjE,iBAAW,WAAW,IAAI,OAAO;AAAA,IACnC;AAGA,QAAI,WAAW,KAAK,IAAI,KAAK,cAAc,KAAK,YAAY,GAAG;AAE7D,UAAI,yFAAyF,KAAK,IAAI,KAClG,uBAAuB,KAAK,YAAY,GAAG;AAC7C,mBAAW,WAAW,IAAI,aAAa;AAAA,MACzC,OAAO;AACL,mBAAW,WAAW,IAAI,QAAQ;AAAA,MACpC;AAAA,IACF;AAGA,QAAI,UAAU,KAAK,IAAI,KAAK,qDAAqD,KAAK,YAAY,GAAG;AACnG,iBAAW,WAAW,IAAI,OAAO;AAEjC,UAAI,UAAU,KAAK,YAAY,KAAK,qBAAqB,KAAK,IAAI,GAAG;AACnE,mBAAW,SAAS,KAAK,QAAQ;AACjC,mBAAW,UAAU;AAAA,MACvB;AAAA,IACF;AACA,QAAI,aAAa,KAAK,IAAI,KAAK,uBAAuB,KAAK,OAAO,GAAG;AACnE,iBAAW,WAAW,IAAI,UAAU;AAAA,IACtC;AACA,QAAI,WAAW,KAAK,IAAI,KAAK,mCAAmC,KAAK,OAAO,GAAG;AAC7E,iBAAW,WAAW,IAAI,UAAU;AAAA,IACtC;AACA,QAAI,qBAAqB,KAAK,IAAI,KAAK,uBAAuB,KAAK,OAAO,GAAG;AAC3E,iBAAW,WAAW,IAAI,UAAU;AAAA,IACtC;AACA,QAAI,kBAAkB,KAAK,IAAI,KAAK,uBAAuB,KAAK,OAAO,GAAG;AACxE,iBAAW,WAAW,IAAI,OAAO;AAAA,IACnC;AACA,QAAI,iBAAiB,KAAK,OAAO,GAAG;AAClC,iBAAW,WAAW,IAAI,QAAQ;AAAA,IACpC;AACA,QAAI,gBAAgB,KAAK,OAAO,GAAG;AACjC,iBAAW,WAAW,IAAI,QAAQ;AAAA,IACpC;AAGA,QAAI,yDAAyD,KAAK,IAAI,GAAG;AACvE,iBAAW,WAAW,IAAI,QAAQ;AAAA,IACpC;AACA,QAAI,sCAAsC,KAAK,OAAO,GAAG;AACvD,iBAAW,WAAW,IAAI,SAAS;AAAA,IACrC;AACA,QAAI,uCAAuC,KAAK,OAAO,GAAG;AACxD,iBAAW,WAAW,IAAI,YAAY;AAAA,IACxC;AACA,QAAI,qCAAqC,KAAK,OAAO,GAAG;AACtD,iBAAW,WAAW,IAAI,MAAM;AAAA,IAClC;AACA,QAAI,qCAAqC,KAAK,OAAO,GAAG;AACtD,iBAAW,WAAW,IAAI,MAAM;AAAA,IAClC;AACA,QAAI,qCAAqC,KAAK,OAAO,GAAG;AACtD,iBAAW,WAAW,IAAI,YAAY;AAAA,IACxC;AAGA,QAAI,sBAAsB,KAAK,IAAI,KAAK,iCAAiC,KAAK,OAAO,GAAG;AACtF,iBAAW,WAAW,IAAI,OAAO;AAAA,IACnC;AACA,QAAI,mBAAmB,KAAK,OAAO,GAAG;AACpC,iBAAW,WAAW,IAAI,MAAM;AAAA,IAClC;AACA,QAAI,mBAAmB,KAAK,OAAO,GAAG;AACpC,iBAAW,WAAW,IAAI,MAAM;AAAA,IAClC;AACA,QAAI,qBAAqB,KAAK,OAAO,GAAG;AACtC,iBAAW,WAAW,IAAI,MAAM;AAAA,IAClC;AACA,QAAI,wCAAwC,KAAK,OAAO,GAAG;AACzD,iBAAW,WAAW,IAAI,UAAU;AAAA,IACtC;AACA,QAAI,6BAA6B,KAAK,OAAO,GAAG;AAC9C,iBAAW,WAAW,IAAI,OAAO;AAAA,IACnC;AAGA,QAAI,qCAAqC,KAAK,OAAO,GAAG;AACtD,iBAAW,WAAW,IAAI,OAAO;AAAA,IACnC;AACA,QAAI,wBAAwB,KAAK,OAAO,GAAG;AACzC,iBAAW,WAAW,IAAI,OAAO;AAAA,IACnC;AACA,QAAI,uBAAuB,KAAK,OAAO,GAAG;AACxC,iBAAW,WAAW,IAAI,SAAS;AAAA,IACrC;AACA,QAAI,mCAAmC,KAAK,OAAO,GAAG;AACpD,iBAAW,WAAW,IAAI,UAAU;AAAA,IACtC;AACA,QAAI,kBAAkB,KAAK,OAAO,GAAG;AACnC,iBAAW,WAAW,IAAI,OAAO;AAAA,IACnC;AAGA,QAAI,mBAAmB,KAAK,IAAI,KAC3B,0CAA0C,KAAK,OAAO,KAAK,CAAC,qBAAqB,KAAK,IAAI,GAAI;AACjG,iBAAW,WAAW,IAAI,QAAQ;AAAA,IACpC;AACA,QAAI,mBAAmB,KAAK,IAAI,KAC3B,0CAA0C,KAAK,OAAO,KAAK,CAAC,qBAAqB,KAAK,IAAI,GAAI;AACjG,iBAAW,WAAW,IAAI,QAAQ;AAAA,IACpC;AAGA,QAAI,uCAAuC,KAAK,OAAO,GAAG;AACxD,iBAAW,WAAW,IAAI,QAAQ;AAAA,IACpC;AACA,QAAI,wBAAwB,KAAK,OAAO,GAAG;AACzC,iBAAW,WAAW,IAAI,SAAS;AAAA,IACrC;AACA,QAAI,oCAAoC,KAAK,OAAO,GAAG;AACrD,iBAAW,WAAW,IAAI,WAAW;AAAA,IACvC;AACA,QAAI,6BAA6B,KAAK,OAAO,GAAG;AAC9C,iBAAW,WAAW,IAAI,UAAU;AAAA,IACtC;AACA,QAAI,8BAA8B,KAAK,OAAO,GAAG;AAC/C,iBAAW,WAAW,IAAI,mBAAmB;AAAA,IAC/C;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKQ,iBAAiB,MAAc,aAAqB,YAAuC;AACjG,UAAM,gBAAgB,OAAO,MAAM,aAAa,YAAY;AAG5D,QAAI,wBAAwB,KAAK,YAAY,GAAG;AAC9C,iBAAW,UAAU;AAAA,IACvB,WAAW,6BAA6B,KAAK,YAAY,GAAG;AAC1D,iBAAW,UAAU;AAAA,IACvB,WAAW,kBAAkB,KAAK,YAAY,GAAG;AAC/C,iBAAW,UAAU;AAAA,IACvB,WAAW,qBAAqB,KAAK,YAAY,GAAG;AAClD,iBAAW,UAAU;AAAA,IACvB,WAAW,qBAAqB,KAAK,YAAY,GAAG;AAClD,iBAAW,UAAU;AAAA,IACvB,WAAW,wBAAwB,KAAK,YAAY,GAAG;AACrD,iBAAW,UAAU;AAAA,IACvB,WAAW,qCAAqC,KAAK,YAAY,GAAG;AAClE,iBAAW,UAAU;AAAA,IACvB,WAAW,2BAA2B,KAAK,YAAY,GAAG;AACxD,iBAAW,UAAU;AAAA,IACvB,WAAW,8BAA8B,KAAK,YAAY,GAAG;AAC3D,iBAAW,UAAU;AAAA,IACvB,WAAW,yBAAyB,KAAK,YAAY,GAAG;AACtD,iBAAW,UAAU;AAAA,IACvB,WAAW,sBAAsB,KAAK,YAAY,GAAG;AACnD,iBAAW,UAAU;AAAA,IACvB,WAAW,yBAAyB,KAAK,YAAY,GAAG;AACtD,iBAAW,UAAU;AAAA,IACvB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKQ,oBAAoB,MAAc,WAAqB,YAAuC;AACpG,UAAM,UAAU,KAAK,YAAY,IAAI,MAAM,UAAU,KAAK,GAAG;AAG7D,eAAW,YAAY,WAAW;AAChC,YAAM,gBAAgB,SAAS,YAAY;AAC3C,UAAI,QAAQ,KAAK,aAAa,GAAG;AAC/B,YAAI,oBAAoB,KAAK,aAAa,GAAG;AAC3C,qBAAW,OAAO,KAAK,WAAW;AAClC,qBAAW,SAAS,KAAK,WAAW;AAAA,QACtC,WAAW,kBAAkB,KAAK,aAAa,GAAG;AAChD,qBAAW,OAAO,KAAK,aAAa;AACpC,qBAAW,SAAS,KAAK,aAAa;AAAA,QACxC,WAAW,yBAAyB,KAAK,aAAa,GAAG;AACvD,qBAAW,OAAO,KAAK,cAAc;AAAA,QACvC,WAAW,yBAAyB,KAAK,aAAa,GAAG;AACvD,qBAAW,OAAO,KAAK,cAAc;AAAA,QACvC,WAAW,gBAAgB,KAAK,aAAa,GAAG;AAC9C,qBAAW,OAAO,KAAK,YAAY;AAAA,QACrC,WAAW,sBAAsB,KAAK,aAAa,GAAG;AACpD,qBAAW,OAAO,KAAK,YAAY;AAAA,QACrC;AAAA,MACF;AAAA,IACF;AAGA,QAAI,YAAY,KAAK,OAAO,GAAG;AAC7B,UAAI,yBAAyB,KAAK,OAAO,GAAG;AAC1C,mBAAW,OAAO,KAAK,cAAc;AAAA,MACvC;AACA,UAAI,+BAA+B,KAAK,OAAO,GAAG;AAChD,mBAAW,OAAO,KAAK,YAAY;AAAA,MACrC;AACA,UAAI,2BAA2B,KAAK,OAAO,GAAG;AAC5C,mBAAW,OAAO,KAAK,cAAc;AAAA,MACvC;AACA,UAAI,0BAA0B,KAAK,OAAO,GAAG;AAC3C,mBAAW,OAAO,KAAK,YAAY;AAAA,MACrC;AACA,UAAI,4BAA4B,KAAK,OAAO,GAAG;AAC7C,mBAAW,OAAO,KAAK,WAAW;AAAA,MACpC;AACA,UAAI,qBAAqB,KAAK,OAAO,GAAG;AACtC,mBAAW,OAAO,KAAK,aAAa;AAAA,MACtC;AAAA,IACF;AAGA,QAAI,eAAe,KAAK,IAAI,KAAK,yCAAyC,KAAK,OAAO,GAAG;AACvF,iBAAW,OAAO,KAAK,OAAO;AAAA,IAChC;AAGA,QAAI,kDAAkD,KAAK,OAAO,GAAG;AACnE,iBAAW,SAAS,KAAK,aAAa;AAAA,IACxC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKQ,sBAAsB,MAAc,YAAuC;AAEjF,QAAI,qBAAqB,KAAK,IAAI,KAAK,+BAA+B,KAAK,IAAI,GAAG;AAChF,iBAAW,OAAO,KAAK,mBAAmB;AAAA,IAC5C,WAAW,YAAY,KAAK,IAAI,KAAK,+BAA+B,KAAK,IAAI,GAAG;AAC9E,iBAAW,OAAO,KAAK,qBAAqB;AAAA,IAC9C,WAAW,QAAQ,KAAK,IAAI,GAAG;AAC7B,iBAAW,OAAO,KAAK,aAAa;AAAA,IACtC;AAGA,QAAI,uBAAuB,KAAK,IAAI,GAAG;AACrC,iBAAW,OAAO,KAAK,aAAa;AAAA,IACtC;AAGA,QAAI,oBAAoB,KAAK,IAAI,KAAK,gCAAgC,KAAK,IAAI,GAAG;AAChF,iBAAW,OAAO,KAAK,SAAS;AAAA,IAClC;AAEA,QAAI,aAAa,KAAK,IAAI,KAAK,8BAA8B,KAAK,IAAI,GAAG;AACvE,iBAAW,OAAO,KAAK,UAAU;AAAA,IACnC;AAGA,QAAI,oCAAoC,KAAK,IAAI,GAAG;AAClD,iBAAW,OAAO,KAAK,YAAY;AAAA,IACrC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKQ,mBAAmB,MAAc,YAAuC;AAC9E,UAAM,YAAY,KAAK,YAAY;AAGnC,QAAI,WAAW,WAAW,IAAI,OAAO,GAAG;AACtC,UAAI,4BAA4B,KAAK,IAAI,GAAG;AAC1C,mBAAW,aAAa,IAAI,cAAc;AAAA,MAC5C;AACA,UAAI,sBAAsB,KAAK,IAAI,GAAG;AACpC,mBAAW,aAAa,IAAI,aAAa;AAAA,MAC3C;AAAA,IACF;AAGA,QAAI,WAAW,WAAW,IAAI,OAAO,KAAK,WAAW,WAAW,IAAI,QAAQ,GAAG;AAC7E,UAAI,0BAA0B,KAAK,SAAS,GAAG;AAC7C,mBAAW,aAAa,IAAI,iBAAiB;AAAA,MAC/C;AACA,UAAI,sCAAsC,KAAK,SAAS,GAAG;AACzD,mBAAW,aAAa,IAAI,YAAY;AAAA,MAC1C;AAAA,IACF;AAGA,QAAI,WAAW,WAAW,IAAI,MAAM,KAAK,WAAW,WAAW,IAAI,MAAM,GAAG;AAC1E,iBAAW,aAAa,IAAI,YAAY;AAAA,IAC1C;AAGA,QAAI,WAAW,WAAW,IAAI,OAAO,KAAK,WAAW,WAAW,IAAI,MAAM,GAAG;AAC3E,UAAI,sBAAsB,KAAK,SAAS,GAAG;AACzC,mBAAW,aAAa,IAAI,mBAAmB;AAAA,MACjD;AACA,UAAI,yBAAyB,KAAK,SAAS,GAAG;AAC5C,mBAAW,aAAa,IAAI,WAAW;AAAA,MACzC;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKQ,0BAA0B,MAAc,YAAuC;AAErF,UAAM,mBAAmB,KAAK,SAAS,wCAAwC;AAC/E,eAAW,SAAS,kBAAkB;AACpC,YAAM,gBAAgB,MAAM,CAAC,EAAE,YAAY;AAC3C,UAAI,sBAAsB,KAAK,aAAa,GAAG;AAC7C,mBAAW,WAAW,IAAI,OAAO;AAAA,MACnC;AACA,UAAI,UAAU,KAAK,aAAa,GAAG;AACjC,mBAAW,WAAW,IAAI,QAAQ;AAAA,MACpC;AACA,UAAI,gBAAgB,KAAK,aAAa,GAAG;AACvC,mBAAW,WAAW,IAAI,OAAO;AAAA,MACnC;AAAA,IACF;AAGA,QAAI,uBAAuB,KAAK,IAAI,GAAG;AACrC,iBAAW,SAAS,KAAK,OAAO;AAAA,IAClC;AACA,QAAI,+CAA+C,KAAK,IAAI,GAAG;AAC7D,iBAAW,SAAS,KAAK,WAAW;AACpC,iBAAW,OAAO,KAAK,WAAW;AAAA,IACpC;AACA,QAAI,+CAA+C,KAAK,IAAI,GAAG;AAC7D,iBAAW,SAAS,KAAK,QAAQ;AACjC,iBAAW,SAAS,KAAK,aAAa;AAAA,IACxC;AACA,QAAI,qBAAqB,KAAK,IAAI,GAAG;AACnC,iBAAW,SAAS,KAAK,MAAM;AAAA,IACjC;AACA,QAAI,yBAAyB,KAAK,IAAI,GAAG;AACvC,iBAAW,SAAS,KAAK,QAAQ;AACjC,iBAAW,SAAS,KAAK,aAAa;AAAA,IACxC;AACA,QAAI,yBAAyB,KAAK,IAAI,GAAG;AACvC,iBAAW,SAAS,KAAK,QAAQ;AACjC,iBAAW,SAAS,KAAK,aAAa;AAAA,IACxC;AACA,QAAI,eAAe,KAAK,IAAI,GAAG;AAC7B,iBAAW,SAAS,KAAK,aAAa;AAAA,IACxC;AACA,QAAI,aAAa,KAAK,IAAI,GAAG;AAC3B,iBAAW,SAAS,KAAK,cAAc;AAAA,IACzC;AAGA,UAAM,eAAe,KAAK,SAAS,+BAA+B;AAClE,UAAM,SAAmB,CAAC;AAC1B,eAAW,SAAS,cAAc;AAChC,UAAI,MAAM,CAAC,EAAG,QAAO,KAAK,MAAM,CAAC,EAAE,YAAY,CAAC;AAAA,IAClD;AAGA,UAAM,oBAAoB,KAAK,SAAS,sGAAsG;AAC9I,eAAW,SAAS,mBAAmB;AACrC,UAAI,MAAM,CAAC,EAAG,QAAO,KAAK,MAAM,CAAC,EAAE,YAAY,CAAC;AAAA,IAClD;AAGA,eAAW,SAAS,QAAQ;AAC1B,UAAI,UAAU,SAAS;AACrB,mBAAW,OAAO,KAAK,OAAO;AAC9B,mBAAW,OAAO,KAAK,aAAa;AAAA,MACtC,WAAW,UAAU,WAAW;AAC9B,mBAAW,OAAO,KAAK,SAAS;AAChC,mBAAW,OAAO,KAAK,eAAe;AAAA,MACxC,WAAW,UAAU,YAAY;AAC/B,mBAAW,SAAS,KAAK,UAAU;AAAA,MACrC,WAAW,UAAU,WAAW;AAC9B,mBAAW,WAAW,IAAI,UAAU;AAAA,MACtC,WAAW,UAAU,SAAS;AAC5B,mBAAW,SAAS,KAAK,OAAO;AAChC,mBAAW,aAAa,IAAI,OAAO;AAAA,MACrC,WAAW,UAAU,WAAW;AAC9B,mBAAW,SAAS,KAAK,SAAS;AAClC,mBAAW,aAAa,IAAI,OAAO;AAAA,MACrC,WAAW,UAAU,gBAAgB;AACnC,mBAAW,SAAS,KAAK,OAAO;AAChC,mBAAW,SAAS,KAAK,QAAQ;AACjC,mBAAW,aAAa,IAAI,OAAO;AAAA,MACrC,WAAW,UAAU,aAAa;AAChC,mBAAW,SAAS,KAAK,WAAW;AAAA,MACtC;AAAA,IACF;AAGA,UAAM,iBAAiB,KAAK,SAAS,iCAAiC;AACtE,eAAW,SAAS,gBAAgB;AAClC,UAAI,MAAM,CAAC,GAAG;AACZ,cAAM,UAAU,MAAM,CAAC,EAAE,YAAY;AACrC,YAAI,QAAQ,SAAS,aAAa,GAAG;AACnC,qBAAW,SAAS,KAAK,aAAa;AAAA,QACxC;AACA,YAAI,QAAQ,SAAS,QAAQ,GAAG;AAC9B,qBAAW,SAAS,KAAK,QAAQ;AACjC,qBAAW,SAAS,KAAK,aAAa;AAAA,QACxC;AACA,YAAI,QAAQ,SAAS,OAAO,GAAG;AAC7B,qBAAW,SAAS,KAAK,OAAO;AAAA,QAClC;AAAA,MACF;AAAA,IACF;AAEA,QAAI,eAAe,KAAK,IAAI,GAAG;AAC7B,iBAAW,SAAS,KAAK,aAAa;AAAA,IACxC;AACA,QAAI,2BAA2B,KAAK,IAAI,GAAG;AACzC,iBAAW,SAAS,KAAK,QAAQ;AAAA,IACnC;AAGA,QAAI,gDAAgD,KAAK,IAAI,GAAG;AAC9D,iBAAW,SAAS,KAAK,QAAQ;AACjC,iBAAW,UAAU;AAAA,IACvB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKQ,sBAAsB,MAAc,YAAuC;AAEjF,QAAI,mEAAmE,KAAK,IAAI,GAAG;AACjF,YAAM,cAAc,KAAK,SAAS,6CAA6C;AAC/E,iBAAW,SAAS,aAAa;AAC/B,cAAM,OAAO,SAAS,MAAM,CAAC,GAAG,EAAE;AAClC,YAAI,QAAQ,IAAI;AACd,qBAAW,SAAS,KAAK,OAAO;AAAA,QAClC,WAAW,QAAQ,IAAI;AACrB,qBAAW,SAAS,KAAK,QAAQ;AAAA,QACnC,WAAW,QAAQ,IAAI;AACrB,qBAAW,SAAS,KAAK,OAAO;AAAA,QAClC;AAEA,YAAI,SAAS,MAAM,SAAS,MAAM,SAAS,IAAI;AAC7C,qBAAW,SAAS,KAAK,GAAG,IAAI,SAAS;AAAA,QAC3C;AAAA,MACF;AAAA,IACF;AAGA,QAAI,4BAA4B,KAAK,IAAI,GAAG;AAC1C,YAAM,aAAa,KAAK,SAAS,uBAAuB;AACxD,iBAAW,SAAS,YAAY;AAC9B,cAAM,MAAM,SAAS,MAAM,CAAC,GAAG,EAAE;AACjC,YAAI,OAAO,IAAI;AACb,qBAAW,SAAS,KAAK,QAAQ;AACjC,qBAAW,OAAO,KAAK,eAAe;AAAA,QACxC,WAAW,OAAO,GAAG;AACnB,qBAAW,SAAS,KAAK,SAAS;AAAA,QACpC;AAAA,MACF;AAAA,IACF;AAGA,QAAI,8BAA8B,KAAK,IAAI,GAAG;AAC5C,iBAAW,SAAS,KAAK,QAAQ;AAAA,IACnC;AAGA,QAAI,2DAA2D,KAAK,IAAI,GAAG;AACzE,iBAAW,SAAS,KAAK,aAAa;AAAA,IACxC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKQ,wBAAwB,MAAc,YAAuC;AAEnF,QAAI,iDAAiD,KAAK,IAAI,GAAG;AAC/D,iBAAW,SAAS,KAAK,UAAU;AAEnC,UAAI,iCAAiC,KAAK,IAAI,GAAG;AAC/C,mBAAW,SAAS,KAAK,gBAAgB;AAAA,MAC3C;AACA,UAAI,0CAA0C,KAAK,IAAI,GAAG;AACxD,mBAAW,SAAS,KAAK,QAAQ;AAAA,MACnC;AAAA,IACF;AAGA,QAAI,gDAAgD,KAAK,IAAI,GAAG;AAC9D,YAAM,iBAAiB,KAAK,SAAS,8CAA8C;AACnF,iBAAW,SAAS,gBAAgB;AAClC,cAAM,QAAQ,MAAM,CAAC,KAAK,MAAM,CAAC;AACjC,YAAI,UAAU,UAAU,UAAU,MAAM;AACtC,qBAAW,SAAS,KAAK,eAAe;AAAA,QAC1C,OAAO;AACL,qBAAW,SAAS,KAAK,SAAS;AAAA,QACpC;AAAA,MACF;AAAA,IACF;AAGA,QAAI,yDAAyD,KAAK,IAAI,GAAG;AACvE,iBAAW,SAAS,KAAK,YAAY;AACrC,UAAI,+BAA+B,KAAK,IAAI,GAAG;AAC7C,mBAAW,SAAS,KAAK,cAAc;AAAA,MACzC;AACA,UAAI,uCAAuC,KAAK,IAAI,GAAG;AACrD,mBAAW,SAAS,KAAK,kBAAkB;AAAA,MAC7C;AAAA,IACF;AAGA,QAAI,4BAA4B,KAAK,IAAI,GAAG;AAC1C,iBAAW,SAAS,KAAK,WAAW;AAAA,IACtC,WAAW,yBAAyB,KAAK,IAAI,GAAG;AAC9C,iBAAW,SAAS,KAAK,QAAQ;AAAA,IACnC;AAGA,QAAI,iCAAiC,KAAK,IAAI,GAAG;AAC/C,iBAAW,SAAS,KAAK,SAAS;AAAA,IACpC;AAGA,QAAI,gCAAgC,KAAK,IAAI,GAAG;AAC9C,iBAAW,SAAS,KAAK,UAAU;AACnC,iBAAW,OAAO,KAAK,iBAAiB;AAAA,IAC1C;AAGA,QAAI,mBAAmB,KAAK,IAAI,GAAG;AACjC,iBAAW,SAAS,KAAK,WAAW;AACpC,iBAAW,OAAO,KAAK,kBAAkB;AAAA,IAC3C;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKQ,gBAAgB,MAAc,WAAqB,YAAuC;AAChG,UAAM,WAAW,OAAO,MAAM,UAAU,KAAK,GAAG,GAAG,YAAY;AAG/D,QAAI,8BAA8B,KAAK,OAAO,GAAG;AAC/C,iBAAW,SAAS,KAAK,QAAQ;AACjC,iBAAW,SAAS,KAAK,SAAS;AAAA,IACpC;AAGA,QAAI,sDAAsD,KAAK,OAAO,GAAG;AACvE,iBAAW,SAAS,KAAK,aAAa;AACtC,UAAI,oCAAoC,KAAK,OAAO,GAAG;AACrD,mBAAW,SAAS,KAAK,cAAc;AAAA,MACzC;AAAA,IACF;AAGA,QAAI,wBAAwB,KAAK,OAAO,GAAG;AACzC,iBAAW,SAAS,KAAK,QAAQ;AACjC,iBAAW,SAAS,KAAK,aAAa;AAAA,IACxC;AACA,QAAI,4BAA4B,KAAK,OAAO,EAAG,YAAW,SAAS,KAAK,QAAQ;AAChF,QAAI,gCAAgC,KAAK,OAAO,EAAG,YAAW,SAAS,KAAK,SAAS;AAGrF,QAAI,gEAAgE,KAAK,OAAO,GAAG;AACjF,iBAAW,SAAS,KAAK,cAAc;AACvC,iBAAW,SAAS,KAAK,eAAe;AAAA,IAC1C;AAGA,QAAI,gCAAgC,KAAK,OAAO,GAAG;AACjD,UAAI,6BAA6B,KAAK,OAAO,EAAG,YAAW,SAAS,KAAK,aAAa;AAAA,IACxF;AAGA,QAAI,2DAA2D,KAAK,OAAO,KACvE,4BAA4B,KAAK,OAAO,GAAG;AAC7C,iBAAW,SAAS,KAAK,QAAQ;AACjC,iBAAW,SAAS,KAAK,YAAY;AACrC,iBAAW,SAAS,KAAK,SAAS;AAAA,IACpC;AACA,QAAI,4DAA4D,KAAK,OAAO,GAAG;AAC7E,iBAAW,SAAS,KAAK,MAAM;AAAA,IACjC;AACA,QAAI,+BAA+B,KAAK,OAAO,KAAK,cAAc,KAAK,OAAO,GAAG;AAC/E,iBAAW,SAAS,KAAK,SAAS;AAClC,iBAAW,SAAS,KAAK,YAAY;AAAA,IACvC;AAEA,UAAM,UAAU,KAAK,MAAM,cAAc,KAAK,CAAC,GAAG;AAClD,QAAI,UAAU,KAAK,uBAAuB,KAAK,OAAO,GAAG;AACvD,iBAAW,SAAS,KAAK,WAAW;AACpC,iBAAW,SAAS,KAAK,kBAAkB;AAAA,IAC7C;AAGA,QAAI,cAAc,KAAK,IAAI,GAAG;AAC5B,iBAAW,SAAS,KAAK,WAAW;AACpC,iBAAW,SAAS,KAAK,MAAM;AAAA,IACjC;AACA,QAAI,wBAAwB,KAAK,IAAI,GAAG;AACtC,iBAAW,SAAS,KAAK,SAAS;AAClC,iBAAW,SAAS,KAAK,OAAO;AAAA,IAClC;AACA,QAAI,sBAAsB,KAAK,IAAI,EAAG,YAAW,SAAS,KAAK,OAAO;AACtE,QAAI,oBAAoB,KAAK,IAAI,GAAG;AAClC,iBAAW,SAAS,KAAK,MAAM;AAC/B,iBAAW,SAAS,KAAK,OAAO;AAAA,IAClC;AACA,QAAI,4BAA4B,KAAK,IAAI,EAAG,YAAW,SAAS,KAAK,SAAS;AAC9E,QAAI,iBAAiB,KAAK,IAAI,EAAG,YAAW,SAAS,KAAK,OAAO;AAGjE,QAAI,gCAAgC,KAAK,OAAO,EAAG,YAAW,SAAS,KAAK,MAAM;AAClF,QAAI,iCAAiC,KAAK,OAAO,GAAG;AAClD,iBAAW,SAAS,KAAK,OAAO;AAEhC,UAAI,wCAAwC,KAAK,OAAO,GAAG;AACzD,mBAAW,SAAS,KAAK,iBAAiB;AAAA,MAC5C;AAAA,IACF;AACA,QAAI,iCAAiC,KAAK,OAAO,GAAG;AAClD,iBAAW,SAAS,KAAK,OAAO;AAChC,iBAAW,SAAS,KAAK,SAAS;AAAA,IACpC;AACA,QAAI,mCAAmC,KAAK,OAAO,GAAG;AACpD,iBAAW,SAAS,KAAK,SAAS;AAClC,iBAAW,SAAS,KAAK,OAAO;AAAA,IAClC;AACA,QAAI,mDAAmD,KAAK,OAAO,GAAG;AACpE,iBAAW,SAAS,KAAK,WAAW;AACpC,iBAAW,SAAS,KAAK,MAAM;AAAA,IACjC;AACA,QAAI,oCAAoC,KAAK,OAAO,EAAG,YAAW,SAAS,KAAK,UAAU;AAC1F,QAAI,gCAAgC,KAAK,OAAO,EAAG,YAAW,SAAS,KAAK,WAAW;AAGvF,QAAI,6EAA6E,KAAK,OAAO,GAAG;AAC9F,iBAAW,SAAS,KAAK,aAAa;AACtC,iBAAW,SAAS,KAAK,iBAAiB;AAAA,IAC5C;AACA,QAAI,8BAA8B,KAAK,OAAO,GAAG;AAC/C,iBAAW,SAAS,KAAK,QAAQ;AACjC,iBAAW,UAAU;AAAA,IACvB;AACA,QAAI,sGAAsG,KAAK,OAAO,GAAG;AACvH,iBAAW,SAAS,KAAK,cAAc;AACvC,iBAAW,SAAS,KAAK,QAAQ;AAAA,IACnC;AAGA,UAAM,sBAAsB,KAAK,SAAS,yCAAyC;AACnF,eAAW,SAAS,qBAAqB;AACvC,YAAM,eAAe,MAAM,CAAC,EAAE,YAAY;AAC1C,UAAI,kBAAkB,KAAK,YAAY,GAAG;AACxC,mBAAW,SAAS,KAAK,SAAS;AAAA,MACpC;AACA,UAAI,mBAAmB,KAAK,YAAY,GAAG;AACzC,mBAAW,SAAS,KAAK,UAAU;AAAA,MACrC;AACA,UAAI,gBAAgB,KAAK,YAAY,GAAG;AACtC,mBAAW,OAAO,KAAK,OAAO;AAC9B,mBAAW,SAAS,KAAK,aAAa;AAAA,MACxC;AACA,UAAI,kBAAkB,KAAK,YAAY,GAAG;AACxC,mBAAW,OAAO,KAAK,SAAS;AAChC,mBAAW,SAAS,KAAK,eAAe;AAAA,MAC1C;AACA,UAAI,yCAAyC,KAAK,YAAY,GAAG;AAC/D,mBAAW,SAAS,KAAK,QAAQ;AACjC,mBAAW,SAAS,KAAK,aAAa;AAAA,MACxC;AACA,UAAI,wBAAwB,KAAK,YAAY,GAAG;AAC9C,mBAAW,SAAS,KAAK,aAAa;AAAA,MACxC;AACA,UAAI,kBAAkB,KAAK,YAAY,GAAG;AACxC,mBAAW,SAAS,KAAK,OAAO;AAAA,MAClC;AAAA,IACF;AAGA,QAAI,kCAAkC,KAAK,OAAO,GAAG;AACnD,iBAAW,SAAS,KAAK,QAAQ;AACjC,iBAAW,SAAS,KAAK,MAAM;AAAA,IACjC;AAGA,QAAI,sDAAsD,KAAK,IAAI,GAAG;AACpE,iBAAW,OAAO,KAAK,OAAO;AAC9B,iBAAW,SAAS,KAAK,cAAc;AAAA,IACzC;AACA,QAAI,eAAe,KAAK,IAAI,GAAG;AAC7B,iBAAW,SAAS,KAAK,KAAK;AAC9B,iBAAW,SAAS,KAAK,MAAM;AAAA,IACjC;AAGA,QAAI,iDAAiD,KAAK,IAAI,EAAG,YAAW,SAAS,KAAK,YAAY;AACtG,QAAI,oCAAoC,KAAK,IAAI,EAAG,YAAW,SAAS,KAAK,QAAQ;AACrF,QAAI,2CAA2C,KAAK,IAAI,EAAG,YAAW,SAAS,KAAK,SAAS;AAG7F,QAAI,mCAAmC,KAAK,OAAO,EAAG,YAAW,SAAS,KAAK,QAAQ;AAGvF,QAAI,6CAA6C,KAAK,IAAI,GAAG;AAC3D,iBAAW,SAAS,KAAK,aAAa;AACtC,iBAAW,SAAS,KAAK,UAAU;AAAA,IACrC;AAGA,QAAI,iBAAiB,KAAK,IAAI,GAAG;AAC/B,iBAAW,SAAS,KAAK,QAAQ;AAAA,IACnC;AAGA,QAAI,qBAAqB,KAAK,IAAI,GAAG;AACnC,iBAAW,SAAS,KAAK,YAAY;AAAA,IACvC;AAGA,QAAI,gCAAgC,KAAK,IAAI,GAAG;AAC9C,iBAAW,SAAS,KAAK,UAAU;AAAA,IACrC;AAGA,QAAI,+BAA+B,KAAK,IAAI,GAAG;AAC7C,iBAAW,SAAS,KAAK,aAAa;AAAA,IACxC;AAGA,QAAI,iDAAiD,KAAK,IAAI,GAAG;AAC/D,iBAAW,SAAS,KAAK,UAAU;AAAA,IACrC;AAGA,QAAI,YAAY,KAAK,IAAI,GAAG;AAC1B,iBAAW,SAAS,KAAK,OAAO;AAAA,IAClC;AAGA,QAAI,iCAAiC,KAAK,IAAI,GAAG;AAC/C,iBAAW,SAAS,KAAK,eAAe;AACxC,iBAAW,SAAS,KAAK,QAAQ;AAAA,IACnC;AAGA,UAAM,mBAAmB,KAAK,SAAS,8BAA8B;AACrE,eAAW,SAAS,kBAAkB;AACpC,YAAM,YAAY,MAAM,CAAC,EAAE,YAAY;AAEvC,UAAI,aAAa,KAAK,SAAS,GAAG;AAChC,mBAAW,OAAO,KAAK,aAAa;AAAA,MACtC;AACA,UAAI,+BAA+B,KAAK,SAAS,GAAG;AAClD,mBAAW,OAAO,KAAK,UAAU;AAAA,MACnC;AACA,UAAI,QAAQ,KAAK,SAAS,GAAG;AAC3B,mBAAW,SAAS,KAAK,QAAQ;AAAA,MACnC;AACA,UAAI,WAAW,KAAK,SAAS,GAAG;AAC9B,mBAAW,SAAS,KAAK,SAAS;AAAA,MACpC;AACA,UAAI,UAAU,KAAK,SAAS,GAAG;AAC7B,mBAAW,SAAS,KAAK,QAAQ;AAAA,MACnC;AAAA,IACF;AAGA,UAAM,qBAAqB,KAAK,SAAS,uCAAuC;AAChF,eAAW,SAAS,oBAAoB;AACtC,YAAM,WAAW,MAAM,CAAC,EAAE,YAAY;AACtC,YAAM,YAAY,MAAM,CAAC,EAAE,YAAY;AACvC,UAAI,aAAa,WAAW,WAAW;AACrC,YAAI,cAAc,UAAW,YAAW,SAAS,KAAK,SAAS;AAC/D,YAAI,cAAc,WAAY,YAAW,SAAS,KAAK,UAAU;AACjE,YAAI,cAAc,SAAS;AACzB,qBAAW,OAAO,KAAK,OAAO;AAC9B,qBAAW,SAAS,KAAK,aAAa;AAAA,QACxC;AACA,YAAI,cAAc,WAAW;AAC3B,qBAAW,OAAO,KAAK,SAAS;AAChC,qBAAW,SAAS,KAAK,eAAe;AAAA,QAC1C;AAAA,MACF;AACA,UAAI,aAAa,aAAa,WAAW;AACvC,YAAI,UAAU,SAAS,aAAa,EAAG,YAAW,SAAS,KAAK,aAAa;AAC7E,YAAI,UAAU,SAAS,QAAQ,EAAG,YAAW,SAAS,KAAK,QAAQ;AAAA,MACrE;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMQ,kBAAkB,QAAgB,YAAuC;AAC/E,QAAI,CAAC,UAAU,OAAO,KAAK,EAAE,WAAW,EAAG;AAE3C,QAAI,CAAC,WAAW,OAAQ,YAAW,SAAS,CAAC;AAC7C,QAAI,CAAC,WAAW,OAAQ,YAAW,SAAS,CAAC;AAC7C,QAAI,CAAC,WAAW,WAAY,YAAW,aAAa,CAAC;AACrD,QAAI,CAAC,WAAW,QAAS,YAAW,UAAU,CAAC;AAC/C,QAAI,CAAC,WAAW,OAAQ,YAAW,SAAS,CAAC;AAC7C,QAAI,CAAC,WAAW,SAAU,YAAW,WAAW,CAAC;AAGjD,UAAM,eAAe,OAAO,MAAM,GAAG,EAAE,IAAI,OAAK,EAAE,KAAK,CAAC;AAExD,eAAW,SAAS,cAAc;AAGhC,YAAM,QAAQ,MAAM,MAAM,mBAAmB;AAC7C,UAAI,CAAC,MAAO;AAEZ,YAAM,YAAY,MAAM,CAAC,EAAE,KAAK;AAChC,YAAM,aAAa,MAAM,CAAC,EAAE,KAAK;AACjC,YAAM,iBAAiB,UAAU,YAAY;AAG7C,UAAI,eAAe,SAAS,OAAO,KAAK,eAAe,SAAS,YAAY,KACxE,eAAe,SAAS,MAAM,KAAK,eAAe,SAAS,MAAM,KACjE,eAAe,SAAS,QAAQ,KAAK,eAAe,SAAS,QAAQ,GAAG;AAG1E,YAAI,eAAe,SAAS,SAAS,GAAG;AACtC,cAAI,CAAC,WAAW,OAAO,SAAS,SAAS,GAAG;AAC1C,uBAAW,OAAO,KAAK,SAAS;AAAA,UAClC;AACA,cAAI,eAAe,SAAS,YAAY,GAAG;AACzC,uBAAW,OAAO,KAAK,oBAAoB;AAAA,UAC7C;AACA,cAAI,eAAe,SAAS,MAAM,GAAG;AACnC,uBAAW,OAAO,KAAK,cAAc;AAAA,UACvC;AAAA,QACF,WAAW,eAAe,SAAS,OAAO,KAAK,eAAe,SAAS,QAAQ,GAAG;AAChF,cAAI,CAAC,WAAW,OAAO,SAAS,OAAO,GAAG;AACxC,uBAAW,OAAO,KAAK,OAAO;AAAA,UAChC;AACA,cAAI,eAAe,SAAS,YAAY,GAAG;AACzC,uBAAW,OAAO,KAAK,kBAAkB;AAAA,UAC3C;AACA,cAAI,eAAe,SAAS,MAAM,GAAG;AACnC,uBAAW,OAAO,KAAK,YAAY;AAAA,UACrC;AAAA,QACF,WAAW,eAAe,SAAS,SAAS,GAAG;AAC7C,cAAI,CAAC,WAAW,OAAO,SAAS,SAAS,GAAG;AAC1C,uBAAW,OAAO,KAAK,SAAS;AAAA,UAClC;AACA,cAAI,eAAe,SAAS,YAAY,GAAG;AACzC,uBAAW,OAAO,KAAK,oBAAoB;AAAA,UAC7C;AACA,cAAI,eAAe,SAAS,MAAM,GAAG;AACnC,uBAAW,OAAO,KAAK,cAAc;AAAA,UACvC;AAAA,QACF,WAAW,eAAe,SAAS,SAAS,KAAK,eAAe,SAAS,MAAM,KAAK,eAAe,SAAS,OAAO,GAAG;AACpH,cAAI,CAAC,WAAW,OAAO,SAAS,SAAS,GAAG;AAC1C,uBAAW,OAAO,KAAK,SAAS;AAAA,UAClC;AACA,cAAI,eAAe,SAAS,OAAO,GAAG;AACpC,uBAAW,SAAS,KAAK,aAAa;AAAA,UACxC;AAAA,QACF,WAAW,eAAe,SAAS,WAAW,KAAK,eAAe,SAAS,aAAa,GAAG;AACzF,cAAI,CAAC,WAAW,OAAO,SAAS,WAAW,GAAG;AAC5C,uBAAW,OAAO,KAAK,WAAW;AAAA,UACpC;AAAA,QACF,WAAW,eAAe,SAAS,SAAS,KAAK,eAAe,SAAS,SAAS,GAAG;AACnF,cAAI,CAAC,WAAW,OAAO,SAAS,SAAS,GAAG;AAC1C,uBAAW,OAAO,KAAK,SAAS;AAAA,UAClC;AAAA,QACF,WAAW,eAAe,SAAS,MAAM,GAAG;AAC1C,cAAI,CAAC,WAAW,OAAO,SAAS,MAAM,GAAG;AACvC,uBAAW,OAAO,KAAK,MAAM;AAAA,UAC/B;AACA,qBAAW,OAAO,KAAK,YAAY;AAAA,QACrC;AAAA,MACF;AAGA,UAAI,eAAe,SAAS,MAAM,KAAK,eAAe,SAAS,WAAW,KACtE,eAAe,SAAS,UAAU,KAAK,eAAe,SAAS,MAAM,KACrE,eAAe,SAAS,QAAQ,KAAK,eAAe,SAAS,MAAM,KACnE,eAAe,SAAS,OAAO,KAAK,eAAe,SAAS,QAAQ,KACpE,eAAe,SAAS,aAAa,GAAG;AAE1C,YAAI,eAAe,SAAS,UAAU,GAAG;AACvC,cAAI,CAAC,WAAW,WAAW,SAAS,UAAU,GAAG;AAC/C,uBAAW,WAAW,KAAK,UAAU;AAAA,UACvC;AAEA,cAAI,eAAe,SAAS,OAAO,GAAG;AACpC,uBAAW,WAAW,KAAK,gBAAgB;AAAA,UAC7C,WAAW,eAAe,SAAS,QAAQ,GAAG;AAC5C,uBAAW,WAAW,KAAK,iBAAiB;AAAA,UAC9C,WAAW,eAAe,SAAS,OAAO,GAAG;AAC3C,uBAAW,WAAW,KAAK,gBAAgB;AAAA,UAC7C;AAEA,cAAI,eAAe,SAAS,SAAS,GAAG;AACtC,uBAAW,SAAS,KAAK,SAAS;AAAA,UACpC;AACA,cAAI,eAAe,SAAS,QAAQ,GAAG;AACrC,uBAAW,SAAS,KAAK,QAAQ;AAAA,UACnC;AAAA,QACF,WAAW,eAAe,SAAS,MAAM,GAAG;AAC1C,cAAI,CAAC,WAAW,WAAW,SAAS,MAAM,GAAG;AAC3C,uBAAW,WAAW,KAAK,WAAW;AAAA,UACxC;AACA,cAAI,eAAe,SAAS,OAAO,GAAG;AACpC,uBAAW,WAAW,KAAK,YAAY;AAAA,UACzC,WAAW,eAAe,SAAS,QAAQ,GAAG;AAC5C,uBAAW,WAAW,KAAK,aAAa;AAAA,UAC1C,WAAW,eAAe,SAAS,OAAO,GAAG;AAC3C,uBAAW,WAAW,KAAK,YAAY;AAAA,UACzC;AAEA,cAAI,eAAe,SAAS,QAAQ,GAAG;AACrC,uBAAW,WAAW,KAAK,MAAM;AACjC,uBAAW,SAAS,KAAK,aAAa;AAAA,UACxC;AACA,cAAI,eAAe,SAAS,SAAS,GAAG;AACtC,uBAAW,SAAS,KAAK,cAAc;AAAA,UACzC;AAAA,QACF,WAAW,eAAe,SAAS,QAAQ,GAAG;AAC5C,cAAI,CAAC,WAAW,WAAW,SAAS,QAAQ,GAAG;AAC7C,uBAAW,WAAW,KAAK,aAAa;AAAA,UAC1C;AACA,cAAI,eAAe,SAAS,OAAO,GAAG;AACpC,uBAAW,WAAW,KAAK,cAAc;AACzC,uBAAW,SAAS,KAAK,cAAc;AAAA,UACzC,WAAW,eAAe,SAAS,QAAQ,GAAG;AAC5C,uBAAW,WAAW,KAAK,eAAe;AAAA,UAC5C,WAAW,eAAe,SAAS,OAAO,GAAG;AAC3C,uBAAW,WAAW,KAAK,cAAc;AAAA,UAC3C;AAAA,QACF,WAAW,eAAe,SAAS,OAAO,GAAG;AAC3C,qBAAW,SAAS,KAAK,OAAO;AAChC,cAAI,eAAe,SAAS,OAAO,GAAG;AACpC,uBAAW,SAAS,KAAK,aAAa;AAAA,UACxC;AAAA,QACF,WAAW,eAAe,SAAS,QAAQ,GAAG;AAC5C,qBAAW,SAAS,KAAK,QAAQ;AACjC,qBAAW,SAAS,KAAK,aAAa;AAAA,QACxC,WAAW,eAAe,SAAS,aAAa,GAAG;AACjD,qBAAW,SAAS,KAAK,aAAa;AAAA,QACxC;AAGA,YAAI,WAAW,SAAS,QAAQ,KAAK,WAAW,SAAS,KAAK,KAAK,WAAW,SAAS,MAAM,GAAG;AAC9F,qBAAW,WAAW,KAAK,MAAM;AAAA,QACnC,WAAW,WAAW,SAAS,KAAK,KAAK,WAAW,SAAS,SAAS,GAAG;AACvE,qBAAW,WAAW,KAAK,SAAS;AAAA,QACtC,WAAW,WAAW,SAAS,KAAK,KAAK,WAAW,SAAS,UAAU,GAAG;AACxE,qBAAW,WAAW,KAAK,UAAU;AAAA,QACvC;AAGA,YAAI,WAAW,SAAS,YAAY,KAAK,WAAW,SAAS,aAAa,GAAG;AAC3E,qBAAW,SAAS,KAAK,aAAa;AAAA,QACxC;AACA,YAAI,WAAW,SAAS,eAAe,KAAK,WAAW,SAAS,gBAAgB,GAAG;AACjF,qBAAW,SAAS,KAAK,gBAAgB;AAAA,QAC3C;AAAA,MACF;AAGA,UAAI,eAAe,SAAS,WAAW,KAAK,eAAe,SAAS,QAAQ,KACxE,eAAe,SAAS,QAAQ,GAAG;AAErC,YAAI,eAAe,SAAS,UAAU,KAAK,eAAe,SAAS,QAAQ,GAAG;AAC5E,cAAI,CAAC,WAAW,QAAQ,SAAS,UAAU,GAAG;AAC5C,uBAAW,QAAQ,KAAK,UAAU;AAAA,UACpC;AACA,qBAAW,OAAO,KAAK,sBAAsB;AAAA,QAC/C,WAAW,eAAe,SAAS,MAAM,KAAK,eAAe,SAAS,QAAQ,GAAG;AAC/E,cAAI,CAAC,WAAW,QAAQ,SAAS,QAAQ,GAAG;AAC1C,uBAAW,QAAQ,KAAK,QAAQ;AAAA,UAClC;AACA,qBAAW,OAAO,KAAK,aAAa;AAAA,QACtC,WAAW,eAAe,SAAS,MAAM,GAAG;AAC1C,qBAAW,SAAS,KAAK,MAAM;AAC/B,qBAAW,SAAS,KAAK,cAAc;AAAA,QACzC;AAAA,MACF;AAGA,UAAI,eAAe,SAAS,SAAS,GAAG;AACtC,YAAI,eAAe,SAAS,MAAM,GAAG;AACnC,qBAAW,SAAS,KAAK,cAAc;AAAA,QACzC,WAAW,eAAe,SAAS,UAAU,GAAG;AAC9C,qBAAW,SAAS,KAAK,kBAAkB;AAC3C,qBAAW,OAAO,KAAK,UAAU;AAAA,QACnC,WAAW,eAAe,SAAS,QAAQ,GAAG;AAC5C,qBAAW,SAAS,KAAK,gBAAgB;AACzC,qBAAW,OAAO,KAAK,UAAU;AAAA,QACnC,WAAW,eAAe,SAAS,OAAO,GAAG;AAC3C,cAAI,eAAe,SAAS,SAAS,GAAG;AACtC,uBAAW,SAAS,KAAK,eAAe;AAAA,UAC1C;AAAA,QACF;AAAA,MACF;AAGA,UAAI,eAAe,SAAS,YAAY,GAAG;AACzC,YAAI,eAAe,SAAS,aAAa,GAAG;AAC1C,qBAAW,SAAS,KAAK,wBAAwB;AACjD,cAAI,eAAe,SAAS,QAAQ,GAAG;AACrC,uBAAW,SAAS,KAAK,mBAAmB;AAAA,UAC9C;AAAA,QACF,WAAW,eAAe,SAAS,OAAO,GAAG;AAC3C,qBAAW,OAAO,KAAK,SAAS;AAChC,qBAAW,SAAS,KAAK,kBAAkB;AAAA,QAC7C;AAAA,MACF;AAGA,UAAI,eAAe,SAAS,SAAS,KAAK,eAAe,SAAS,QAAQ,GAAG;AAC3E,mBAAW,OAAO,KAAK,iBAAiB;AAAA,MAC1C;AAGA,UAAI,eAAe,SAAS,QAAQ,GAAG;AACrC,YAAI,eAAe,SAAS,MAAM,KAAK,eAAe,SAAS,SAAS,GAAG;AACzE,qBAAW,OAAO,KAAK,SAAS;AAChC,qBAAW,SAAS,KAAK,gBAAgB;AAAA,QAC3C,WAAW,eAAe,SAAS,aAAa,GAAG;AACjD,qBAAW,OAAO,KAAK,WAAW;AAClC,qBAAW,SAAS,KAAK,oBAAoB;AAAA,QAC/C;AACA,YAAI,eAAe,SAAS,UAAU,GAAG;AACvC,qBAAW,SAAS,KAAK,UAAU;AAAA,QACrC;AACA,YAAI,eAAe,SAAS,SAAS,KAAK,eAAe,SAAS,SAAS,GAAG;AAC5E,qBAAW,SAAS,KAAK,YAAY;AAAA,QACvC;AAAA,MACF;AAAA,IACF;AAIA,UAAM,eAAe;AACrB,QAAI;AACJ,YAAQ,aAAa,aAAa,KAAK,MAAM,OAAO,MAAM;AACxD,YAAM,eAAe,WAAW,CAAC,EAAE,YAAY;AAC/C,UAAI,gBAAgB,CAAC,WAAW,OAAO,SAAS,YAAY,GAAG;AAC7D,mBAAW,OAAO,KAAK,YAAY;AAAA,MACrC;AAAA,IACF;AAGA,QAAI,wCAAwC,KAAK,MAAM,GAAG;AACxD,UAAI,CAAC,WAAW,QAAQ,SAAS,UAAU,GAAG;AAC5C,mBAAW,QAAQ,KAAK,UAAU;AAAA,MACpC;AACA,iBAAW,OAAO,KAAK,sBAAsB;AAAA,IAC/C;AAGA,QAAI,yBAAyB,KAAK,MAAM,GAAG;AACzC,UAAI,CAAC,WAAW,QAAQ,SAAS,QAAQ,GAAG;AAC1C,mBAAW,QAAQ,KAAK,QAAQ;AAAA,MAClC;AACA,iBAAW,OAAO,KAAK,aAAa;AAAA,IACtC;AAGA,QAAI,qCAAqC,KAAK,MAAM,GAAG;AACrD,UAAI,eAAe,KAAK,MAAM,GAAG;AAC/B,mBAAW,SAAS,KAAK,aAAa;AAAA,MACxC;AACA,UAAI,gBAAgB,KAAK,MAAM,GAAG;AAChC,mBAAW,SAAS,KAAK,aAAa;AAAA,MACxC;AACA,UAAI,UAAU,KAAK,MAAM,GAAG;AAC1B,mBAAW,SAAS,KAAK,QAAQ;AAAA,MACnC;AAAA,IACF;AAGA,QAAI,kCAAkC,KAAK,MAAM,GAAG;AAClD,iBAAW,SAAS,KAAK,QAAQ;AACjC,iBAAW,SAAS,KAAK,aAAa;AAAA,IACxC;AAGA,QAAI,6BAA6B,KAAK,MAAM,KAAK,2BAA2B,KAAK,MAAM,GAAG;AACxF,iBAAW,SAAS,KAAK,aAAa;AACtC,iBAAW,SAAS,KAAK,gBAAgB;AAAA,IAC3C;AACA,QAAI,4CAA4C,KAAK,MAAM,GAAG;AAC5D,iBAAW,SAAS,KAAK,UAAU;AAAA,IACrC;AACA,QAAI,6CAA6C,KAAK,MAAM,GAAG;AAC7D,iBAAW,SAAS,KAAK,SAAS;AAAA,IACpC;AACA,QAAI,+BAA+B,KAAK,MAAM,GAAG;AAC/C,iBAAW,SAAS,KAAK,UAAU;AAAA,IACrC;AACA,QAAI,4BAA4B,KAAK,MAAM,GAAG;AAC5C,iBAAW,SAAS,KAAK,WAAW;AAAA,IACtC;AACA,QAAI,2CAA2C,KAAK,MAAM,GAAG;AAC3D,iBAAW,SAAS,KAAK,cAAc;AAAA,IACzC;AACA,QAAI,uCAAuC,KAAK,MAAM,GAAG;AACvD,iBAAW,SAAS,KAAK,kBAAkB;AAC3C,iBAAW,OAAO,KAAK,UAAU;AAAA,IACnC;AACA,QAAI,mCAAmC,KAAK,MAAM,GAAG;AACnD,iBAAW,SAAS,KAAK,gBAAgB;AACzC,iBAAW,OAAO,KAAK,UAAU;AAAA,IACnC;AAGA,QAAI,yBAAyB,KAAK,MAAM,GAAG;AACzC,iBAAW,OAAO,KAAK,MAAM;AAC7B,iBAAW,SAAS,KAAK,WAAW;AAAA,IACtC;AACA,QAAI,yBAAyB,KAAK,MAAM,GAAG;AACzC,iBAAW,SAAS,KAAK,WAAW;AAAA,IACtC;AACA,QAAI,yBAAyB,KAAK,MAAM,GAAG;AACzC,iBAAW,SAAS,KAAK,WAAW;AAAA,IACtC;AACA,QAAI,+BAA+B,KAAK,MAAM,GAAG;AAC/C,iBAAW,SAAS,KAAK,cAAc;AAAA,IACzC;AAGA,QAAI,6CAA6C,KAAK,MAAM,GAAG;AAC7D,iBAAW,WAAW,KAAK,MAAM;AACjC,iBAAW,WAAW,KAAK,aAAa;AACxC,iBAAW,SAAS,KAAK,aAAa;AAAA,IACxC;AACA,QAAI,+CAA+C,KAAK,MAAM,GAAG;AAC/D,iBAAW,WAAW,KAAK,aAAa;AACxC,iBAAW,SAAS,KAAK,cAAc;AAAA,IACzC;AACA,QAAI,uCAAuC,KAAK,MAAM,GAAG;AACvD,iBAAW,SAAS,KAAK,SAAS;AAAA,IACpC;AACA,QAAI,qCAAqC,KAAK,MAAM,GAAG;AACrD,iBAAW,SAAS,KAAK,QAAQ;AAAA,IACnC;AAGA,QAAI,iCAAiC,KAAK,MAAM,GAAG;AACjD,iBAAW,SAAS,KAAK,eAAe;AACxC,UAAI,WAAW,KAAK,MAAM,GAAG;AAC3B,mBAAW,SAAS,KAAK,eAAe;AAAA,MAC1C;AAAA,IACF;AAGA,QAAI,mDAAmD,KAAK,MAAM,GAAG;AACnE,iBAAW,SAAS,KAAK,wBAAwB;AAAA,IACnD;AACA,QAAI,mEAAmE,KAAK,MAAM,GAAG;AACnF,iBAAW,SAAS,KAAK,+BAA+B;AAAA,IAC1D;AAGA,QAAI,mCAAmC,KAAK,MAAM,GAAG;AACnD,iBAAW,SAAS,KAAK,gBAAgB;AAAA,IAC3C;AACA,QAAI,2CAA2C,KAAK,MAAM,GAAG;AAC3D,iBAAW,SAAS,KAAK,oBAAoB;AAAA,IAC/C;AAGA,QAAI,8BAA8B,KAAK,MAAM,GAAG;AAC9C,iBAAW,SAAS,KAAK,aAAa;AACtC,UAAI,aAAa,KAAK,MAAM,GAAG;AAC7B,mBAAW,SAAS,KAAK,gBAAgB;AAAA,MAC3C;AAAA,IACF;AAGA,QAAI,gCAAgC,KAAK,MAAM,GAAG;AAChD,iBAAW,SAAS,KAAK,gBAAgB;AAAA,IAC3C;AACA,QAAI,0BAA0B,KAAK,MAAM,GAAG;AAC1C,iBAAW,SAAS,KAAK,aAAa;AAAA,IACxC;AAGA,QAAI,iBAAiB,KAAK,MAAM,GAAG;AACjC,YAAM,cAAc,OAAO,SAAS,iBAAiB;AACrD,iBAAW,SAAS,aAAa;AAC/B,cAAM,OAAO,SAAS,MAAM,CAAC,GAAG,EAAE;AAClC,YAAI,QAAQ,IAAI;AACd,qBAAW,SAAS,KAAK,YAAY;AAAA,QACvC,WAAW,QAAQ,IAAI;AACrB,qBAAW,SAAS,KAAK,aAAa;AAAA,QACxC,OAAO;AACL,qBAAW,SAAS,KAAK,YAAY;AAAA,QACvC;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;;;AC/xCO,SAAS,mBAAmB,YAAiC,UAA0B;AAC5F,QAAM,aAAuB,CAAC;AAI9B,QAAM,iBAAiB,MAAM,KAAK,WAAW,UAAU;AACvD,QAAM,qBAAqB,qBAAqB,cAAc;AAE9D,MAAI,mBAAmB,SAAS,GAAG;AAGjC,eAAW,KAAK,GAAG,mBAAmB,MAAM,GAAG,CAAC,CAAC;AAAA,EACnD;AAGA,MAAI,WAAW,UAAU,SAAS,GAAG;AAEnC,UAAM,iBAAiB,WAAW,UAAU,MAAM,GAAG,CAAC;AACtD,QAAI,eAAe,SAAS,GAAG;AAE7B,UAAI,eAAe,SAAS,QAAQ,KAAK,eAAe,SAAS,MAAM,GAAG;AACxE,mBAAW,KAAK,sBAAsB;AAAA,MACxC,WAAW,eAAe,SAAS,QAAQ,KAAK,eAAe,SAAS,QAAQ,GAAG;AACjF,mBAAW,KAAK,wBAAwB;AAAA,MAC1C,WAAW,eAAe,WAAW,GAAG;AACtC,mBAAW,KAAK,QAAQ,eAAe,CAAC,CAAC,EAAE;AAAA,MAC7C,OAAO;AAEL,mBAAW,KAAK,GAAG,eAAe,MAAM,GAAG,CAAC,CAAC;AAAA,MAC/C;AAAA,IACF;AAAA,EACF;AAGA,MAAI,WAAW,SAAS;AACtB,eAAW,KAAK,WAAW,OAAO;AAAA,EACpC;AAIA,MAAI,WAAW,aAAa,OAAO,GAAG;AACpC,UAAM,eAAe,MAAM,KAAK,WAAW,YAAY,EACpD,OAAO,iBAAe;AAErB,UAAI,gBAAgB,kBAAkB,WAAW,SAAS,SAAS,cAAc,GAAG;AAClF,eAAO;AAAA,MACT;AACA,aAAO;AAAA,IACT,CAAC,EACA,MAAM,GAAG,CAAC;AACb,eAAW,KAAK,GAAG,YAAY;AAAA,EACjC;AAGA,MAAI,WAAW,OAAO,SAAS,GAAG;AAChC,eAAW,KAAK,GAAG,WAAW,OAAO,MAAM,GAAG,CAAC,CAAC;AAAA,EAClD;AAGA,MAAI,WAAW,OAAO,SAAS,GAAG;AAChC,eAAW,KAAK,GAAG,WAAW,OAAO,MAAM,GAAG,CAAC,CAAC;AAAA,EAClD;AAGA,MAAI,WAAW,WAAW,SAAS,GAAG;AAEpC,UAAM,wBAAwB,WAAW,WAAW;AAAA,MAAO,OACzD,EAAE,SAAS,UAAU,KAAK,EAAE,SAAS,MAAM,KAAK,EAAE,SAAS,OAAO;AAAA,IACpE;AACA,QAAI,sBAAsB,SAAS,GAAG;AACpC,iBAAW,KAAK,GAAG,sBAAsB,MAAM,GAAG,CAAC,CAAC;AAAA,IACtD;AAAA,EACF;AAGA,MAAI,WAAW,QAAQ,SAAS,GAAG;AACjC,eAAW,KAAK,GAAG,WAAW,QAAQ,MAAM,GAAG,CAAC,CAAC;AAAA,EACnD;AAGA,MAAI,WAAW,OAAO,SAAS,GAAG;AAChC,eAAW,KAAK,GAAG,WAAW,OAAO,MAAM,GAAG,CAAC,CAAC;AAAA,EAClD;AAGA,MAAI,WAAW,SAAS,SAAS,GAAG;AAClC,eAAW,KAAK,GAAG,WAAW,SAAS,MAAM,GAAG,CAAC,CAAC;AAAA,EACpD;AAGA,QAAM,OAAO,oBAAI,IAAY;AAC7B,QAAM,cAAc,WAAW,OAAO,UAAQ;AAC5C,UAAM,QAAQ,KAAK,YAAY;AAC/B,QAAI,KAAK,IAAI,KAAK,GAAG;AACnB,aAAO;AAAA,IACT;AACA,SAAK,IAAI,KAAK;AACd,WAAO;AAAA,EACT,CAAC;AAGD,MAAI,YAAY,SAAS,GAAG;AAC1B,WAAO,YAAY,KAAK,GAAG;AAAA,EAC7B;AAEA,SAAO;AACT;AAMO,SAAS,qBAAqB,YAAgC;AACnE,QAAM,WAAsC;AAAA;AAAA,IAE1C,qBAAqB;AAAA,IACrB,eAAe;AAAA,IACf,WAAW;AAAA,IACX,cAAc;AAAA,IACd,YAAY;AAAA,IACZ,YAAY;AAAA,IACZ,aAAa;AAAA,IACb,cAAc;AAAA,IACd,SAAS;AAAA,IACT,SAAS;AAAA,IACT,UAAU;AAAA,IACV,WAAW;AAAA,IACX,SAAS;AAAA,IACT,QAAQ;AAAA;AAAA,IAGR,YAAY;AAAA,IACZ,UAAU;AAAA,IACV,UAAU;AAAA,IACV,YAAY;AAAA,IACZ,SAAS;AAAA,IACT,YAAY;AAAA,IACZ,cAAc;AAAA,IACd,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,SAAS;AAAA,IACT,WAAW;AAAA,IACX,SAAS;AAAA,IACT,YAAY;AAAA,IACZ,SAAS;AAAA,IACT,UAAU;AAAA;AAAA,IAGV,UAAU;AAAA,IACV,SAAS;AAAA,IACT,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,UAAU;AAAA,IACV,UAAU;AAAA,IACV,QAAQ;AAAA,IACR,SAAS;AAAA,EACX;AAEA,SAAO,WAAW,KAAK,CAAC,GAAG,MAAM;AAC/B,UAAM,YAAY,SAAS,CAAC,KAAK;AACjC,UAAM,YAAY,SAAS,CAAC,KAAK;AACjC,WAAO,YAAY;AAAA,EACrB,CAAC;AACH;;;AC/JO,IAAM,uBAAN,MAA2B;AAAA,EACxB;AAAA,EACA;AAAA,EAER,cAAc;AACZ,SAAK,oBAAoB,IAAI,yBAAyB;AACtD,SAAK,yBAAyB,IAAI,uBAAuB;AAAA,EAC3D;AAAA;AAAA;AAAA;AAAA,EAKA,aACE,eACA,gBAAwB,gBAChB;AACR,QAAI,CAAC,cAAc,WAAW,cAAc,QAAQ,WAAW,GAAG;AAChE,aAAO;AAAA,IACT;AAEA,UAAM,aAAkC;AAAA,MACtC,YAAY,oBAAI,IAAY;AAAA,MAC5B,QAAQ,CAAC;AAAA,MACT,QAAQ,CAAC;AAAA,MACT,cAAc,oBAAI,IAAY;AAAA,MAC9B,WAAW,CAAC;AAAA,MACZ,QAAQ,CAAC;AAAA,MACT,YAAY,CAAC;AAAA,MACb,SAAS,CAAC;AAAA,MACV,UAAU,CAAC;AAAA,IACb;AAGA,eAAW,QAAQ,cAAc,SAAS;AACxC,UAAI,KAAK,SAAS,UAAU,OAAO,KAAK,SAAS,UAAU;AACzD,cAAM,OAAO,KAAK;AAGlB,cAAM,QAAQ,KAAK,MAAM,4CAA4C;AACrE,cAAM,cAAc,MAAM,CAAC,KAAK;AAChC,cAAM,gBAAgB,MAAM,CAAC,KAAK;AAGlC,aAAK,uBAAuB,yBAAyB,aAAa,eAAe,UAAU;AAAA,MAC7F;AAAA,IACF;AAGA,WAAO,mBAAmB,YAAY,aAAa;AAAA,EACrD;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,yBACE,UACQ;AACR,QAAI,CAAC,SAAS,WAAW,SAAS,QAAQ,WAAW,GAAG;AACtD,aAAO;AAAA,IACT;AAEA,UAAM,aAAkC;AAAA,MACtC,YAAY,oBAAI,IAAY;AAAA,MAC5B,QAAQ,CAAC;AAAA,MACT,QAAQ,CAAC;AAAA,MACT,cAAc,oBAAI,IAAY;AAAA,MAC9B,WAAW,CAAC;AAAA,MACZ,QAAQ,CAAC;AAAA,MACT,YAAY,CAAC;AAAA,MACb,SAAS,CAAC;AAAA,MACV,UAAU,CAAC;AAAA,IACb;AAGA,eAAW,QAAQ,SAAS,SAAS;AACnC,UAAI,KAAK,SAAS,UAAU,OAAO,KAAK,SAAS,UAAU;AACzD,cAAM,eAAe,KAAK;AAE1B,cAAM,QAAQ,KAAK,kBAAkB,aAAa,YAAY;AAC9D,mBAAW,SAAS,KAAK,GAAG,KAAK;AAAA,MACnC;AAAA,IACF;AAGA,WAAO,mBAAmB,YAAY,EAAE;AAAA,EAC1C;AACF;;;ACjGA,OAAO;AAuCA,IAAM,wBAAN,MAA4B;AAAA,EACzB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAER,YAAY,UAAwC,CAAC,GAAG;AACtD,SAAK,YAAY,QAAQ,IAAI;AAC7B,SAAK,YAAY,QAAQ;AACzB,SAAK,WAAW,WAAW,QAAQ,IAAI,kBAAmB;AAC1D,SAAK,OAAO,SAAS,QAAQ,IAAI,gBAAiB,EAAE;AACpD,SAAK,oBAAoB,QAAQ,IAAI;AACrC,SAAK,cAAc,QAAQ,IAAI;AAC/B,SAAK,wBAAwB,QAAQ,IAAI;AACzC,SAAK,sBAAsB,QAAQ,IAAI;AAAA,EACzC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,kBAAkB,MAAiC;AACvD,QAAI;AACF,aAAO,MAAM,gCAAgC;AAC7C,YAAM,YAAY,KAAK,IAAI;AAE3B,YAAM,WAAW,MAAM,MAAM,KAAK,mBAAmB;AAAA,QACnD,QAAQ;AAAA,QACR,SAAS;AAAA,UACP,QAAQ;AAAA,UACR,eAAe,UAAU,KAAK,WAAW;AAAA,UACzC,gBAAgB;AAAA,QAClB;AAAA,QACA,MAAM,KAAK,UAAU;AAAA,UACnB,OAAO;AAAA,UACP,OAAO,KAAK;AAAA,UACZ,SAAS;AAAA,UACT,OAAO,QAAQ,IAAI,kBAAkB;AAAA,QACvC,CAAC;AAAA,MACH,CAAC;AAED,aAAO,MAAM,wBAAwB,SAAS,MAAM,EAAE;AAEtD,UAAI,CAAC,SAAS,IAAI;AAChB,cAAM,YAAY,MAAM,SAAS,KAAK;AACtC,eAAO,MAAM,uBAAuB,SAAS;AAC7C,cAAM,IAAI,MAAM,cAAc,SAAS,MAAM,IAAI,SAAS,UAAU,EAAE;AAAA,MACxE;AAEA,aAAO,MAAM,yBAAyB;AACtC,YAAM,OAAQ,MAAM,SAAS,KAAK;AAIlC,UAAI,CAAC,KAAK,QAAQ,CAAC,KAAK,KAAK,CAAC,KAAK,CAAC,KAAK,KAAK,CAAC,EAAE,WAAW;AAC1D,eAAO,MAAM,4BAA4B,KAAK,UAAU,IAAI,EAAE,UAAU,GAAG,GAAG,CAAC;AAC/E,cAAM,IAAI,MAAM,6BAA6B;AAAA,MAC/C;AAEA,YAAM,YAAY,KAAK,KAAK,CAAC,EAAE;AAC/B,YAAM,UAAU,KAAK,IAAI,IAAI;AAC7B,aAAO,MAAM,+BAA0B,UAAU,MAAM,aAAa,OAAO,IAAI;AAE/E,aAAO;AAAA,IACT,SAAS,OAAO;AACd,aAAO,MAAM,+BAA+B,KAAK;AACjD,YAAM,IAAI,MAAM,iCAAiC,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC,EAAE;AAAA,IAC3G;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMQ,WAAW,OAIA;AACjB,UAAM,WAAW,MAAM,YAAY,CAAC;AAEpC,WAAO;AAAA,MACL,IAAI,MAAM,MAAM;AAAA,MAChB,KAAM,SAAS,OAAkB,MAAM,MAAM;AAAA,MAC7C,OAAO,MAAM,SAAS;AAAA,MACtB,MAAO,SAAS,QAAmB;AAAA,MACnC,WAAY,SAAS,aAAwB;AAAA,MAC7C,UAAW,SAAS,YAAuB;AAAA,MAC3C,UAAW,SAAS,YAAuB;AAAA,MAC3C,QAAS,SAAS,UAAqB;AAAA,MACvC,WAAY,SAAS,aAAwB;AAAA,MAC7C,UAAU,MAAM,QAAQ,SAAS,QAAQ,IAAK,SAAS,WAAwB,CAAC;AAAA,IAClF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAc,mBACZ,WACA,MACA,WAQC;AACD,UAAM,MAAM,GAAG,KAAK,qBAAqB,kBAAkB,KAAK,SAAS;AAEzE,WAAO,MAAM,kCAAkC,GAAG,GAAG,YAAY,iBAAiB,SAAS,OAAO,EAAE,EAAE;AAEtG,UAAM,cAKF;AAAA,MACF,QAAQ;AAAA,MACR;AAAA,MACA,iBAAiB;AAAA,IACnB;AAGA,QAAI,WAAW;AACb,kBAAY,YAAY;AAAA,IAC1B;AAEA,UAAM,YAAY,KAAK,IAAI;AAC3B,UAAM,WAAW,MAAM,MAAM,KAAK;AAAA,MAChC,QAAQ;AAAA,MACR,SAAS;AAAA,QACP,iBAAiB,UAAU,KAAK,WAAW;AAAA,QAC3C,gBAAgB;AAAA,QAChB,UAAU;AAAA,MACZ;AAAA,MACA,MAAM,KAAK,UAAU,WAAW;AAAA,IAClC,CAAC;AAED,UAAM,YAAY,KAAK,IAAI,IAAI;AAC/B,WAAO,MAAM,8BAA8B,SAAS,MAAM,KAAK,SAAS,KAAK;AAE7E,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,YAAY,MAAM,SAAS,KAAK;AACtC,aAAO,MAAM,6BAA6B,SAAS;AACnD,YAAM,IAAI,MAAM,6BAA6B,SAAS,MAAM,IAAI,SAAS,UAAU,MAAM,SAAS,EAAE;AAAA,IACtG;AAEA,UAAM,OAAO,MAAM,SAAS,KAAK;AASjC,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,OAAO,OAAe,UAAyB,CAAC,GAA2B;AAC/E,QAAI,CAAC,SAAS,OAAO,UAAU,UAAU;AACvC,YAAM,IAAI,MAAM,kCAAkC;AAAA,IACpD;AACA,WAAO,MAAM,2BAA2B,KAAK,UAAU,OAAO,CAAC,EAAE;AACnE,WAAO,MAAM,yBAAyB,QAAQ,IAAI,WAAW,OAAO,QAAQ,IAAI,EAAE;AAClF,WAAO,MAAM,uCAAuC,QAAQ,SAAS,MAAS,EAAE;AAChF,WAAO,MAAM,iCAAiC,KAAK,IAAI,EAAE;AAEvD,UAAM,WACJ,QAAQ,aAAa,SAAY,QAAQ,WAAW,KAAK;AAC3D,UAAM,OAAO,QAAQ,SAAS,SAAY,QAAQ,OAAO,KAAK;AAE9D,UAAM,YAAY,QAAQ,cAAc,SAAY,QAAQ,YAAY,KAAK;AAE7E,WAAO,MAAM,6BAA6B,KAAK,YAAY,IAAI,eAAe,QAAQ,GAAG,YAAY,iBAAiB,SAAS,MAAM,EAAE,EAAE;AAGzI,UAAM,YAAY,MAAM,KAAK,kBAAkB,KAAK;AAGpD,WAAO,MAAM,4BAA4B,KAAK,SAAS,oBAAoB,YAAY,eAAe,SAAS,MAAM,EAAE,KAAK;AAC5H,UAAM,YAAY,KAAK,IAAI;AAE3B,UAAM,gBAAgB,MAAM,KAAK,mBAAmB,WAAW,MAAM,SAAS;AAC9E,UAAM,YAAY,KAAK,IAAI,IAAI;AAC/B,WAAO,MAAM,sBAAsB,SAAS,cAAc,cAAc,SAAS,UAAU,CAAC,UAAU;AAGtG,UAAM,aAAa,cAAc,WAAW,CAAC;AAC7C,UAAM,kBAAkB,WAAW,OAAO,CAAC,OAAO,EAAE,SAAS,MAAM,QAAQ;AAE3E,WAAO,MAAM,qBAAqB,gBAAgB,MAAM,uBAAuB,QAAQ,YAAY,WAAW,MAAM,QAAQ;AAE5H,WAAO;AAAA,MACL;AAAA,MACA,cAAc,WAAW;AAAA,MACzB,iBAAiB,gBAAgB;AAAA,MACjC,SAAS,gBAAgB,IAAI,CAAC,UAAU,KAAK,WAAW,KAAK,CAAC;AAAA,MAC9D,gBAAgB;AAAA,QACd;AAAA,QACA;AAAA,QACA,WAAW,KAAK;AAAA,QAChB;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,oBAAoB,KAA6C;AACrE,QAAI,CAAC,OAAO,OAAO,QAAQ,UAAU;AACnC,YAAM,IAAI,MAAM,gCAAgC;AAAA,IAClD;AAGA,UAAM,UAAU,MAAM,KAAK,OAAO,KAAK,EAAE,MAAM,IAAI,UAAU,EAAE,CAAC;AAGhE,UAAM,aAAa,QAAQ,QAAQ;AAAA,MACjC,CAAC,MAAM,EAAE,QAAQ,OAAO,EAAE,OAAO;AAAA,IACnC;AAEA,QAAI,YAAY;AACd,aAAO;AAAA,IACT;AAGA,QAAI,QAAQ,QAAQ,SAAS,GAAG;AAC9B,aAAO,QAAQ,QAAQ,CAAC;AAAA,IAC1B;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,sBAAsB,MAA2C;AACrE,QAAI,CAAC,MAAM,QAAQ,IAAI,GAAG;AACxB,YAAM,IAAI,MAAM,uBAAuB;AAAA,IACzC;AAEA,UAAM,UAAU,MAAM,QAAQ;AAAA,MAC5B,KAAK,IAAI,CAAC,QAAQ,KAAK,oBAAoB,GAAG,CAAC;AAAA,IACjD;AAEA,WAAO,QAAQ;AAAA,MACb,CAAC,MAA2B,MAAM;AAAA,IACpC;AAAA,EACF;AACF;;;ACpTO,IAAM,aAAN,MAAiB;AAAA;AAAA;AAAA;AAAA,EAItB,OAAO,aAAa,eAmBlB;AACA,WAAO;AAAA,MACL,OAAO,cAAc;AAAA,MACrB,SAAS;AAAA,QACP,cAAc,cAAc;AAAA,QAC5B,iBAAiB,cAAc;AAAA,QAC/B,UAAU,cAAc,eAAe;AAAA,MACzC;AAAA,MACA,YAAY,cAAc,QAAQ,IAAI,CAAC,WAAW;AAAA,QAChD,IAAI,MAAM;AAAA,QACV,KAAK,MAAM;AAAA,QACX,OAAO,MAAM;AAAA,QACb,MAAM,MAAM;AAAA,QACZ,WAAW,MAAM;AAAA,QACjB,UAAU,MAAM;AAAA,QAChB,UAAU,MAAM;AAAA,QAChB,QAAQ,MAAM;AAAA,QACd,WAAW,MAAM;AAAA,QACjB,UAAU,MAAM;AAAA,MAClB,EAAE;AAAA,IACJ;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,OAAO,WAAW,eAAsC;AACtD,QAAI,CAAC,cAAc,WAAW,cAAc,QAAQ,WAAW,GAAG;AAChE,aAAO;AAAA;AAAA,cAEC,cAAc,KAAK;AAAA;AAAA;AAAA,IAG7B;AAGA,QAAI,WAAW;AAAA,wBACK,cAAc,eAAe,OAAO,cAAc,YAAY;AAAA;AAAA;AAIlF,kBAAc,QAAQ,QAAQ,CAAC,OAAO,UAAU;AAC9C,kBAAY,OAAO,QAAQ,CAAC,KAAK,MAAM,GAAG;AAAA;AAAA;AAAA,EAG9C,MAAM,aAAa,sCAAsC;AAAA;AAAA;AAAA;AAAA;AAAA,IAKvD,CAAC;AAED,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,OAAO,iBAAiB,SAAmC;AACzD,QAAI,CAAC,WAAW,QAAQ,WAAW,GAAG;AACpC,aAAO;AAAA,IACT;AAIA,UAAM,kBAAkB,QAAQ,IAAI,CAAC,WAAW;AAAA,MAC9C,KAAK,MAAM;AAAA,MACX,OAAO,MAAM;AAAA;AAAA,MACb,UAAU,MAAM;AAAA,MAChB,QAAQ,MAAM;AAAA,MACd,UAAU,MAAM;AAAA,IAClB,EAAE;AAGF,WAAO,KAAK,UAAU,EAAE,YAAY,gBAAgB,GAAG,MAAM,CAAC;AAAA,EAChE;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,OAAO,4BAA4B,SAAmC;AACpE,QAAI,CAAC,WAAW,QAAQ,WAAW,GAAG;AACpC,aAAO;AAAA,IACT;AAGA,UAAM,kBAAkB,QAAQ,IAAI,CAAC,WAAW;AAAA,MAC9C,KAAK,MAAM;AAAA,MACX,OAAO,MAAM;AAAA,MACb,UAAU,MAAM;AAAA,IAClB,EAAE;AAGF,WAAO,KAAK,UAAU,EAAE,YAAY,gBAAgB,GAAG,MAAM,CAAC;AAAA,EAChE;AAEF;;;ACzHA,IAAM,iBACJ;AAgBF,eAAsB,gBAAgB,cAAwD;AAC5F,SAAO,KAAK,iCAA0B;AAEtC,MAAI;AACF,UAAM,WAAW,MAAM,MAAM,gBAAgB;AAAA,MAC3C,QAAQ;AAAA,MACR,SAAS;AAAA,QACP,gBAAgB;AAAA,MAClB;AAAA,MACA,MAAM,KAAK,UAAU,EAAE,aAAa,CAAC;AAAA,IACvC,CAAC;AAED,UAAM,OAAO,MAAM,SAAS,KAAK;AAEjC,QAAI,SAAS,MAAM,KAAK,UAAU,MAAM;AACtC,aAAO,KAAK,4BAAuB,KAAK,KAAK,EAAE;AAC/C,aAAO;AAAA,QACL,OAAO;AAAA,QACP,WAAW,KAAK;AAAA,QAChB,cAAc,KAAK;AAAA,QACnB,QAAQ,KAAK;AAAA,QACb,OAAO,KAAK;AAAA,MACd;AAAA,IACF;AAEA,UAAM,eAAgB,KAAK,SAAoB;AAC/C,WAAO,MAAM,qCAAgC,YAAY,EAAE;AAC3D,UAAM,IAAI,MAAM,8BAA8B,YAAY,EAAE;AAAA,EAC9D,SAAS,OAAO;AACd,QAAI,iBAAiB,SAAS,MAAM,QAAQ,WAAW,4BAA4B,GAAG;AACpF,YAAM;AAAA,IACR;AAEA,WAAO,MAAM,sCAAiC,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;AAEpG,QAAI,iBAAiB,OAAO;AAC1B,UAAI,MAAM,QAAQ,SAAS,cAAc,KAAK,MAAM,QAAQ,SAAS,cAAc,GAAG;AACpF,cAAM,IAAI,MAAM,mDAAmD;AAAA,MACrE,WAAW,MAAM,QAAQ,SAAS,SAAS,GAAG;AAC5C,cAAM,IAAI,MAAM,6DAA6D;AAAA,MAC/E;AAAA,IACF;AAEA,UAAM,IAAI,MAAM,8BAA8B,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC,EAAE;AAAA,EACxG;AACF;;;ACnEA,OAAO;AAOP,SAAS,8BAA8B,MAA+E;AACpH,QAAM,SAAS,KAAK;AACpB,MAAI,CAAC,MAAM,QAAQ,MAAM,GAAG;AAC1B,WAAO;AAAA,EACT;AAEA,QAAM,YAAsB,CAAC;AAC7B,aAAW,QAAQ,QAAQ;AACzB,QAAI,CAAC,QAAQ,OAAO,SAAS,UAAU;AACrC;AAAA,IACF;AACA,UAAM,IAAI;AACV,QAAI,EAAE,SAAS,WAAW;AACxB;AAAA,IACF;AACA,UAAM,UAAU,EAAE;AAClB,QAAI,CAAC,MAAM,QAAQ,OAAO,GAAG;AAC3B;AAAA,IACF;AACA,eAAW,SAAS,SAAS;AAC3B,UAAI,CAAC,SAAS,OAAO,UAAU,UAAU;AACvC;AAAA,MACF;AACA,YAAM,IAAI;AACV,UAAI,EAAE,SAAS,iBAAiB,OAAO,EAAE,SAAS,YAAY,EAAE,KAAK,SAAS,GAAG;AAC/E,kBAAU,KAAK,EAAE,IAAI;AAAA,MACvB;AAAA,IACF;AAAA,EACF;AAEA,QAAM,SAAS,UAAU,KAAK,IAAI,EAAE,KAAK;AACzC,MAAI,CAAC,QAAQ;AACX,WAAO;AAAA,EACT;AAEA,QAAM,cACJ,KAAK,WAAW,aACZ,0CACA;AACN,SAAO,EAAE,QAAQ,QAAQ,YAAY;AACvC;AAGA,SAAS,iBAAiB,MAAwE;AAChG,MAAI,OAAO,KAAK,aAAa,YAAY,KAAK,UAAU;AACtD,WAAO,EAAE,QAAQ,KAAK,UAAU,aAAa,WAAW;AAAA,EAC1D;AAEA,QAAM,aAAa,8BAA8B,IAAI;AACrD,MAAI,YAAY;AACd,WAAO;AAAA,EACT;AAEA,MAAI,OAAO,KAAK,WAAW,YAAY,KAAK,QAAQ;AAClD,WAAO,EAAE,QAAQ,KAAK,QAAQ,aAAa,SAAS;AAAA,EACtD;AAEA,QAAM,UAAU,KAAK;AACrB,QAAM,MAAM,UAAU,CAAC,GAAG;AAC1B,MAAI,OAAO,OAAO,IAAI,YAAY,YAAY,IAAI,SAAS;AACzD,WAAO,EAAE,QAAQ,IAAI,SAAS,aAAa,6BAA6B;AAAA,EAC1E;AAEA,MAAI,OAAO,KAAK,YAAY,YAAY,KAAK,SAAS;AACpD,WAAO,EAAE,QAAQ,KAAK,SAAS,aAAa,UAAU;AAAA,EACxD;AAEA,SAAO,EAAE,QAAQ,KAAK,UAAU,IAAI,GAAG,aAAa,gBAAgB;AACtE;AAmBO,IAAM,cAAN,MAAkB;AAAA,EACf;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAER,YAAY,UAA8B,CAAC,GAAG;AAC5C,SAAK,SAAS,QAAQ,UAAU,QAAQ,IAAI;AAC5C,SAAK,SAAS,QAAQ,UAAU,QAAQ,IAAI;AAC5C,SAAK,QAAQ,QAAQ,SAAS,QAAQ,IAAI,eAAe;AACzD,SAAK,YAAY,QAAQ,cAAc,QAAQ,IAAI,mBAAmB,SAAS,QAAQ,IAAI,kBAAkB,EAAE,IAAI;AACnH,SAAK,UAAU,CAAC,EAAE,KAAK,UAAU,KAAK;AAAA,EACxC;AAAA;AAAA;AAAA;AAAA,EAKA,YAAqB;AACnB,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,YAAY,UAAkB,SAAyB;AACrD,WAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQT,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAgBP,QAAQ;AAAA,EACR;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,kBAAkB,OAAe,SAAyB;AACxD,WAAO;AAAA;AAAA,aAEE,KAAK;AAAA;AAAA;AAAA,EAGhB,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWP;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,IAAI,UAAkB,SAAyC;AACnE,QAAI,CAAC,KAAK,SAAS;AACjB,aAAO;AAAA,QACL,SAAS;AAAA,QACT,OACE;AAAA,QACF,UAAU;AAAA,MACZ;AAAA,IACF;AAEA,QAAI,CAAC,YAAY,OAAO,aAAa,UAAU;AAC7C,aAAO;AAAA,QACL,SAAS;AAAA,QACT,OAAO;AAAA,QACP,UAAU;AAAA,MACZ;AAAA,IACF;AAEA,WAAO,MAAM,kBAAkB;AAE/B,UAAM,SAAS,KAAK,YAAY,UAAU,OAAO;AAEjD,WAAO,MAAM,YAAY,KAAK,MAAM,EAAE;AACtC,WAAO,MAAM,UAAU,KAAK,KAAK,EAAE;AACnC,WAAO,MAAM,oBAAoB,SAAS,MAAM,QAAQ;AACxD,WAAO,MAAM,mBAAmB,QAAQ,MAAM,QAAQ;AACtD,WAAO,MAAM,eAAe,KAAK,SAAS,EAAE;AAE5C,QAAI;AACF,YAAM,YAAY,KAAK,IAAI;AAC3B,YAAM,WAAW,MAAM,MAAM,KAAK,QAAS;AAAA,QACzC,QAAQ;AAAA,QACR,SAAS;AAAA,UACP,gBAAgB;AAAA,UAChB,eAAe,UAAU,KAAK,MAAM;AAAA,QACtC;AAAA,QACA,MAAM,KAAK,UAAU;AAAA,UACnB,OAAO,KAAK;AAAA,UACZ,OAAO;AAAA,UACP,YAAY,KAAK;AAAA,UACjB,QAAQ;AAAA,UACR,OAAO,QAAQ,IAAI,kBAAkB;AAAA,QACvC,CAAC;AAAA,MACH,CAAC;AACD,YAAM,YAAY,KAAK,IAAI,IAAI;AAC/B,aAAO,MAAM,4BAA4B,SAAS,gBAAgB,SAAS,MAAM,EAAE;AAEnF,UAAI,CAAC,SAAS,IAAI;AAChB,eAAO,MAAM,cAAc,SAAS,MAAM,IAAI,SAAS,UAAU,EAAE;AACnE,cAAM,IAAI,MAAM,cAAc,SAAS,MAAM,IAAI,SAAS,UAAU,EAAE;AAAA,MACxE;AAEA,YAAM,OAAQ,MAAM,SAAS,KAAK;AAClC,YAAM,EAAE,QAAQ,YAAY,IAAI,iBAAiB,IAAI;AAErD,YAAM,aAAe,KAAK,OAAqC,gBAAkC;AACjG,YAAM,gBAAgB,OAAO,QAAQ,QAAQ,GAAG,EAAE,MAAM,GAAG,GAAG;AAC9D,aAAO;AAAA,QACL,gCAAgC,aAAa,YAAY,WAAW;AAAA,MACtE;AAEA,aAAO;AAAA,QACL,iCAAiC,SAAS,MAAM,OAAO,SAAS,0BAAqB,WAAW,MAAM,OAAO,MAAM,kBAAkB,cAAc,KAAK;AAAA,MAC1J;AAEA,aAAO;AAAA,QACL,SAAS;AAAA,QACT,OAAO;AAAA,QACP,UAAU;AAAA,QACV,UAAU;AAAA,UACR,OAAO,KAAK;AAAA,UACZ;AAAA,QACF;AAAA,MACF;AAAA,IACF,SAAS,OAAO;AACd,aAAO,MAAM,2BAA2B,KAAK;AAC7C,aAAO;AAAA,QACL,SAAS;AAAA,QACT,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,QAC5D,UAAU;AAAA,MACZ;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,aAAa,OAAe,SAAyC;AACzE,QAAI,CAAC,KAAK,SAAS;AACjB,aAAO;AAAA,QACL,SAAS;AAAA,QACT,OACE;AAAA,QACF,UAAU;AAAA,MACZ;AAAA,IACF;AAEA,QAAI,CAAC,SAAS,OAAO,UAAU,UAAU;AACvC,aAAO;AAAA,QACL,SAAS;AAAA,QACT,OAAO;AAAA,QACP,UAAU;AAAA,MACZ;AAAA,IACF;AAEA,WAAO,MAAM,gCAAgC;AAG7C,UAAM,SAAS,KAAK,kBAAkB,OAAO,OAAO;AAEpD,WAAO,MAAM,YAAY,KAAK,MAAM,EAAE;AACtC,WAAO,MAAM,UAAU,KAAK,KAAK,EAAE;AACnC,WAAO,MAAM,iBAAiB,MAAM,MAAM,QAAQ;AAClD,WAAO,MAAM,mBAAmB,QAAQ,MAAM,QAAQ;AACtD,WAAO,MAAM,eAAe,KAAK,SAAS,EAAE;AAE5C,QAAI;AACF,YAAM,YAAY,KAAK,IAAI;AAC3B,YAAM,WAAW,MAAM,MAAM,KAAK,QAAS;AAAA,QACzC,QAAQ;AAAA,QACR,SAAS;AAAA,UACP,gBAAgB;AAAA,UAChB,eAAe,UAAU,KAAK,MAAM;AAAA,QACtC;AAAA,QACA,MAAM,KAAK,UAAU;AAAA,UACnB,OAAO,KAAK;AAAA,UACZ,OAAO;AAAA,UACP,YAAY,KAAK;AAAA,UACjB,QAAQ;AAAA,UACR,OAAO,QAAQ,IAAI,kBAAkB;AAAA,QACvC,CAAC;AAAA,MACH,CAAC;AACD,YAAM,YAAY,KAAK,IAAI,IAAI;AAC/B,aAAO,MAAM,4BAA4B,SAAS,gBAAgB,SAAS,MAAM,EAAE;AAEnF,UAAI,CAAC,SAAS,IAAI;AAChB,eAAO,MAAM,cAAc,SAAS,MAAM,IAAI,SAAS,UAAU,EAAE;AACnE,cAAM,IAAI,MAAM,cAAc,SAAS,MAAM,IAAI,SAAS,UAAU,EAAE;AAAA,MACxE;AAEA,YAAM,OAAQ,MAAM,SAAS,KAAK;AAClC,YAAM,EAAE,QAAQ,YAAY,IAAI,iBAAiB,IAAI;AAErD,YAAM,aAAe,KAAK,OAAqC,gBAAkC;AACjG,YAAM,gBAAgB,OAAO,QAAQ,QAAQ,GAAG,EAAE,MAAM,GAAG,GAAG;AAC9D,aAAO;AAAA,QACL,mCAAmC,aAAa,YAAY,WAAW;AAAA,MACzE;AAEA,aAAO;AAAA,QACL,oCAAoC,SAAS,MAAM,OAAO,SAAS,0BAAqB,WAAW,MAAM,OAAO,MAAM,kBAAkB,cAAc,KAAK;AAAA,MAC7J;AAEA,aAAO;AAAA,QACL,SAAS;AAAA,QACT,OAAO;AAAA,QACP,UAAU;AAAA,QACV,UAAU;AAAA,UACR,OAAO,KAAK;AAAA,UACZ;AAAA,QACF;AAAA,MACF;AAAA,IACF,SAAS,OAAO;AACd,aAAO,MAAM,yCAAyC,KAAK;AAC3D,aAAO;AAAA,QACL,SAAS;AAAA,QACT,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,QAC5D,UAAU;AAAA,MACZ;AAAA,IACF;AAAA,EACF;AACF;;;ACvVA,SAAS,2BAA2B,UAAkB,eAAmC;AACvF,MAAI,CAAC,YAAY,OAAO,aAAa,UAAU;AAC7C,WAAO,CAAC;AAAA,EACV;AAGA,MAAI,aAAa,SAAS,KAAK;AAG/B,eAAa,WAAW,QAAQ,SAAS,EAAE;AAC3C,eAAa,WAAW,QAAQ,OAAO,EAAE;AACzC,eAAa,WAAW,QAAQ,mBAAmB,EAAE;AAIrD,MAAI,OAAiB,CAAC;AAGtB,QAAM,aAAa,WAAW,MAAM,GAAG,EAAE,IAAI,OAAK,EAAE,KAAK,CAAC;AAG1D,QAAM,eAAe,WAAW,MAAM,KAAK,EAAE,IAAI,OAAK,EAAE,KAAK,CAAC;AAG9D,QAAM,gBAAgB,CAAC,GAAG,YAAY,GAAG,YAAY,EAClD,IAAI,SAAO;AAEV,UAAM,IAAI,QAAQ,aAAa,EAAE;AACjC,UAAM,IAAI,QAAQ,aAAa,EAAE;AACjC,UAAM,IAAI,QAAQ,eAAe,EAAE;AACnC,UAAM,IAAI,QAAQ,UAAU,EAAE;AAC9B,WAAO,IAAI,KAAK;AAAA,EAClB,CAAC,EACA,OAAO,SAAO,IAAI,SAAS,CAAC;AAG/B,aAAW,aAAa,eAAe;AACrC,UAAM,iBAAiB,UAAU,YAAY;AAE7C,UAAM,aAAa,cAAc;AAAA,MAAK,OACpC,EAAE,YAAY,MAAM,kBACpB,EAAE,YAAY,EAAE,SAAS,cAAc,KACvC,eAAe,SAAS,EAAE,YAAY,CAAC;AAAA,IACzC;AAEA,QAAI,cAAc,CAAC,KAAK,SAAS,UAAU,GAAG;AAC5C,WAAK,KAAK,UAAU;AAAA,IACtB;AAAA,EACF;AAEA,SAAO,MAAM,UAAU,KAAK,MAAM,8BAA8B,KAAK,KAAK,IAAI,CAAC,EAAE;AACjF,SAAO;AACT;AAkBA,eAAsB,0BACpB,SACiC;AACjC,QAAM,EAAE,OAAO,cAAc,IAAI;AAGjC,MAAI,CAAC,cAAc,WAAW,cAAc,QAAQ,WAAW,GAAG;AAChE,WAAO;AAAA,MACL,iBAAiB;AAAA,MACjB,aAAa;AAAA,IACf;AAAA,EACF;AAGA,QAAM,cAAc,IAAI,YAAY;AAEpC,MAAI,kBAAoC,cAAc;AACtD,MAAI,cAAc;AAClB,MAAI;AAGJ,MAAI,YAAY,UAAU,GAAG;AAC3B,QAAI;AACF,aAAO,MAAM,wCAAwC;AAGrD,YAAM,qBAAqB,WAAW,4BAA4B,cAAc,OAAO;AAGvF,YAAM,iBAAiB,KAAK,IAAI;AAChC,YAAM,gBAAgB,MAAM,YAAY,aAAa,OAAO,kBAAkB;AAC9E,0BAAoB,KAAK,IAAI,IAAI;AAEjC,aAAO,MAAM,mCAAmC,iBAAiB,iBAAiB,cAAc,OAAO,EAAE;AAEzG,UAAI,cAAc,WAAW,cAAc,UAAU;AAEnD,cAAM,gBAAgB,cAAc,QAAQ,IAAI,OAAK,EAAE,GAAG;AAC1D,cAAM,eAAe,2BAA2B,cAAc,UAAU,aAAa;AAErF,YAAI,aAAa,SAAS,GAAG;AAE3B,4BAAkB,cAAc,QAAQ;AAAA,YAAO,WAC7C,aAAa,SAAS,MAAM,GAAG;AAAA,UACjC;AAEA,wBAAc;AACd,iBAAO,MAAM,kBAAkB,gBAAgB,MAAM,oBAAoB,cAAc,QAAQ,MAAM,gBAAgB;AAAA,QACvH,OAAO;AACL,iBAAO,KAAK,0DAA0D;AAAA,QACxE;AAAA,MACF,OAAO;AACL,eAAO,KAAK,2BAA2B,cAAc,SAAS,eAAe,8BAA8B;AAAA,MAC7G;AAAA,IACF,SAAS,YAAY;AACnB,aAAO,KAAK,0BAA0B,sBAAsB,QAAQ,WAAW,UAAU,OAAO,UAAU,CAAC,8BAA8B;AAAA,IAE3I;AAAA,EACF,OAAO;AACL,WAAO,MAAM,kDAAkD;AAAA,EACjE;AAGA,QAAM,wBAAuC;AAAA,IAC3C,GAAG;AAAA,IACH,SAAS;AAAA,IACT,iBAAiB,gBAAgB;AAAA,EACnC;AAEA,SAAO;AAAA,IACL,iBAAiB;AAAA,IACjB;AAAA,IACA;AAAA,EACF;AACF;;;AXrIA,IAAM,cAAc;AACpB,QAAQ,IAAI,WAAW;AAmBvB,IAAM,aAAa,cAAc,YAAY,GAAG;AAChD,IAAM,YAAY,QAAQ,UAAU;AACpC,IAAMA,WAAU,cAAc,YAAY,GAAG;AAE7C,IAAM,cAAcA,SAAQ,KAAK,WAAW,iBAAiB,CAAC;AAC9D,IAAM,cAAc,YAAY;AAChC,IAAM,gBAAgB;AAGtB,OAAO,KAAK,2BAA2B,WAAW,aAAa,aAAa,MAAM,WAAW,GAAG;AAChG,OAAO,KAAK,cAAc,QAAQ,IAAI,gBAAgB,SAAS,gBAAgB,OAAO,EAAE;AACxF,OAAO,KAAK,YAAY,QAAQ,OAAO,EAAE;AAQzC,QAAQ,IAAI,iBAAiB;AAC7B,QAAQ,IAAI,qBAAqB;AACjC,QAAQ,IAAI,iBAAiB;AAC7B,QAAQ,IAAI,2BAA2B;AAMvC,QAAQ,IAAI,gBAAgB;AAE5B,QAAQ,IAAI,sBAAsB;AAElC,QAAQ,IAAI,wBAAwB;AACpC,QAAQ,IAAI,cAAc;AAC1B,QAAQ,IAAI,mBAAmB;AAG/B,QAAQ,IAAI,cAAc;AAC1B,QAAQ,IAAI,OAAO;AAGnB,OAAO,MAAM,mBAAmB,QAAQ,IAAI,cAAc,EAAE;AAC5D,OAAO,MAAM,uBAAuB,QAAQ,IAAI,kBAAkB,EAAE;AACpE,OAAO,MAAM,mBAAmB,QAAQ,IAAI,cAAc,EAAE;AAC5D,OAAO,MAAM,6BAA6B,QAAQ,IAAI,wBAAwB,EAAE;AAChF,OAAO,MAAM,kBAAkB,QAAQ,IAAI,aAAa,EAAE;AAC1D,OAAO,MAAM,wBAAwB,QAAQ,IAAI,mBAAmB,EAAE;AACtE,OAAO,MAAM,0BAA0B,QAAQ,IAAI,qBAAqB,EAAE;AAC1E,OAAO,MAAM,gBAAgB,QAAQ,IAAI,WAAW,EAAE;AACtD,OAAO,MAAM,qBAAqB,QAAQ,IAAI,gBAAgB,EAAE;AAChE,OAAO,MAAM,gBAAgB,QAAQ,IAAI,WAAW,EAAE;AACtD,OAAO,MAAM,SAAS,QAAQ,IAAI,IAAI,EAAE;AACxC,OAAO,KAAK,sBAAsB;AAGlC,IAAM,OAAO,MAAM,QAAQ,QAAQ,IAAI,CAAC,EACrC,OAAO,iBAAiB;AAAA,EACvB,MAAM;AAAA,EACN,aAAa;AAAA,EACb,cAAc;AAChB,CAAC,EACA,UAAU;AAGb,IAAM,gBAAgB,KAAK,cAAc,KAAK;AAC9C,IAAI,CAAC,iBAAiB,kBAAkB,IAAI;AAC1C,SAAO,MAAM,sDAAiD;AAC9D,UAAQ,KAAK,CAAC;AAChB;AAMA,IAAI,qBAA6B;AACjC,IAAI;AACF,QAAM,UAAU,MAAM,gBAAgB,aAAa;AACnD,uBAAqB,QAAQ;AAC7B,UAAQ,IAAI,qBAAqB,QAAQ;AACzC,UAAQ,IAAI,iBAAiB,QAAQ;AACrC,UAAQ,IAAI,cAAc,QAAQ;AAClC,SAAO,KAAK,oBAAoB,QAAQ,KAAK,EAAE;AAC/C,SAAO,MAAM,uBAAuB,kBAAkB,EAAE;AACxD,SAAO,MAAM,uBAAuB,QAAQ,aAAa,UAAU,GAAG,CAAC,CAAC,cAAc;AACxF,SAAS,OAAO;AACd,SAAO,MAAM,sEAAiE;AAC9E,UAAQ,KAAK,CAAC;AAChB;AAGA,IAAM,cAAc,QAAQ,IAAI,gBAAgB,UAAU,QAAQ,IAAI,gBAAgB;AACtF,IAAM,OAAO,SAAS,QAAQ,IAAI,QAAQ,QAAQ,EAAE;AAGpD,IAAM,SAAS,IAAI,QAAQ;AAAA,EACzB,cAAc;AAAA,EACd,MAAM;AAAA,EACN,SAAS;AACX,CAAC;AAGD,OAAO,MAAM,8BAA8B;AAC3C,IAAM,cAAc,IAAI,YAAY,2BAA2B;AAC/D,OAAO,MAAM,6BAA6B;AAG1C,IAAI,iBAAiB;AACrB,OAAO,MAAM,oEAAoE;AAEjF,IAAM,sBAAsB,KAAK,IAAI;AACrC,YACG,QAAQ,EACR,KAAK,MAAM;AACV,QAAM,iBAAiB,KAAK,IAAI,IAAI;AACpC,mBAAiB;AACjB,SAAO,MAAM,2BAA2B,cAAc,KAAK;AAC7D,CAAC,EACA,MAAM,CAAC,UAAU;AAChB,QAAM,iBAAiB,KAAK,IAAI,IAAI;AACpC,SAAO,KAAK,mCAAmC,cAAc,KAAK;AAClE,SAAO,MAAM,eAAe,OAAO,aAAa,QAAQ,OAAO,KAAK;AACpE,SAAO,MAAM,kBAAkB,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;AAErF,MAAI,SAAS,OAAO,UAAU,UAAU;AACtC,UAAM,WAAW;AACjB,QAAI,UAAU,UAAU;AACtB,aAAO,MAAM,eAAe,SAAS,IAAI;AAAA,IAC3C;AAAA,EACF;AAEA,MAAI,iBAAiB,SAAS,MAAM,OAAO;AACzC,WAAO,MAAM,gBAAgB,MAAM,KAAK;AAAA,EAC1C;AAEA,SAAO,KAAK,kFAAkF;AAC9F,SAAO,MAAM,6CAA6C;AAC5D,CAAC;AAMH,OAAO,QAAQ;AAAA,EACb,MAAM;AAAA,EACN,aAAa;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAoBb,aAAa;AAAA,IACX,OAAO;AAAA,IACP,cAAc;AAAA,IACd,eAAe;AAAA,EACjB;AAAA,EACA,YAAY,EAAE,OAAO;AAAA,IACnB,mBAAmB,EAChB,QAAQ,EACR,SAAS,EACT,QAAQ,KAAK,EACb,SAAS,wIAAwI;AAAA,EACtJ,CAAC;AAAA,EACD,SAAS,OAAO,MAAM,aAAa;AACjC,QAAI;AACF,YAAM,oBAAoB,KAAK,qBAAqB;AACpD,aAAO,MAAM,sBAAsB,iBAAiB,EAAE;AACtD,aAAO,MAAM,wBAAwB,cAAc,EAAE;AAErD,UAAI,CAAC,gBAAgB;AACnB,eAAO,KAAK,uCAAuC;AACnD,cAAM,SAAwB;AAAA,UAC5B,SAAS,CAAC;AAAA,YACR,MAAM;AAAA,YACN,MAAM;AAAA,UACR,CAAC;AAAA,QACH;AACA,eAAO;AAAA,MACT;AAEA,aAAO,MAAM,2CAA2C;AACxD,YAAM,gBAAgB,MAAM,YAAY,iBAAiB;AAEzD,UAAI,CAAC,cAAc,WAAW,cAAc,QAAQ,WAAW,GAAG;AAChE,cAAM,SAAwB;AAAA,UAC5B,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,oCAA+B,CAAC;AAAA,QAC3E;AACA,eAAO;AAAA,MACT;AAGA,YAAM,sBAA+B;AAAA,QACnC,MAAM;AAAA,QACN,MAAM;AAAA;AAAA,kEAEoD,oBAAoB,+BAA+B,iBAAiB;AAAA;AAAA,MAEhI;AAEA,aAAO;AAAA,QACL,SAAS,CAAC,GAAI,cAAc,SAAuB,mBAAmB;AAAA,MACxE;AAAA,IACF,SAAS,OAAO;AACd,aAAO,MAAM,iCAAiC,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;AACpG,YAAM,SAAwB;AAAA,QAC5B,SAAS,CAAC;AAAA,UACR,MAAM;AAAA,UACN,MAAM,wCAAmC,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;AAAA,QACjG,CAAC;AAAA,MACH;AACA,aAAO;AAAA,IACT;AAAA,EACF;AACF,CAAC;AAKD,OAAO,QAAQ;AAAA,EACb,MAAM;AAAA,EACN,aAAa;AAAA,EACb,aAAa;AAAA,IACX,OAAO;AAAA,IACP,cAAc;AAAA,IACd,eAAe;AAAA,EACjB;AAAA,EACA,YAAY,EAAE,OAAO,CACrB,CAAC;AAAA,EACD,SAAS,OAAO,aAAa;AAC3B,QAAI;AAEF,aAAO,MAAM,wBAAwB,cAAc,EAAE;AAErD,UAAI,CAAC,gBAAgB;AACnB,eAAO,KAAK,uCAAuC;AACnD,cAAM,SAAwB;AAAA,UAC5B,SAAS,CAAC;AAAA,YACR,MAAM;AAAA,YACN,MAAM;AAAA,UACR,CAAC;AAAA,QACH;AACA,eAAO;AAAA,MACT;AAEA,aAAO,MAAM,wCAAwC;AACrD,YAAM,aAAa,MAAM,YAAY,cAAc;AAEnD,UAAI,CAAC,WAAW,WAAW,WAAW,QAAQ,WAAW,GAAG;AAC1D,cAAM,SAAwB;AAAA,UAC5B,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,gCAA2B,CAAC;AAAA,QACvE;AACA,eAAO;AAAA,MACT;AAGA,YAAM,sBAA+B;AAAA,QACnC,MAAM;AAAA,QACN,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAeR;AAEA,aAAO;AAAA,QACL,SAAS,CAAC,qBAAqB,GAAI,WAAW,OAAqB;AAAA,MACrE;AAAA,IACF,SAAS,OAAO;AACd,aAAO,MAAM,6BAA6B,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;AAChG,YAAM,SAAwB;AAAA,QAC5B,SAAS,CAAC;AAAA,UACR,MAAM;AAAA,UACN,MAAM,oCAA+B,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;AAAA,QAC7F,CAAC;AAAA,MACH;AACA,aAAO;AAAA,IACT;AAAA,EACF;AACF,CAAC;AAcD,OAAO,QAAQ;AAAA,EACb,MAAM;AAAA,EACN,aAAa;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcb,aAAa;AAAA,IACX,OAAO;AAAA,IACP,cAAc;AAAA,IACd,eAAe;AAAA,EACjB;AAAA,EACA,YAAY,EAAE,OAAO,CACrB,CAAC;AAAA,EACD,SAAS,OAAQ,aAAa;AAC5B,QAAI;AACF,aAAO,MAAM,wBAAwB,cAAc,EAAE;AAErD,UAAI,CAAC,gBAAgB;AACnB,eAAO,KAAK,uCAAuC;AACnD,eAAO;AAAA,UACL,SAAS,CAAC;AAAA,YACR,MAAM;AAAA,YACN,MAAM;AAAA,UACR,CAAC;AAAA,QACH;AAAA,MACF;AAGA,YAAM,CAAC,YAAY,UAAU,aAAa,IAAI,MAAM,QAAQ,IAAI;AAAA,QAC9D,YAAY,cAAc;AAAA,QAC1B,YAAY,YAAY;AAAA,QACxB,YAAY,iBAAiB;AAAA,MAC/B,CAAC;AAGD,YAAM,iBAAiB,IAAI,qBAAqB;AAGhD,UAAI,gBAAgB;AACpB,UAAI;AAEF,cAAM,0BAA0B;AAAA,UAC9B,SAAS,SAAS,WAAW,CAAC;AAAA,QAChC;AACA,wBAAgB,eAAe,yBAAyB,uBAAuB;AAAA,MACjF,SAAS,OAAO;AACd,eAAO,KAAK,0CAA0C,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;AAAA,MAC9G;AAGA,UAAI,qBAAqB;AACzB,UAAI;AACF,6BAAqB,eAAe,aAAa,eAAe,cAAc;AAAA,MAChF,SAAS,OAAO;AACd,eAAO,KAAK,gDAAgD,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;AAAA,MACpH;AAEA,YAAM,WAAsB,CAAC;AAG7B,UAAI,WAAW,SAAS,QAAQ;AAC9B,iBAAS,KAAK,GAAI,WAAW,OAAqB;AAAA,MACpD;AAGA,eAAS,KAAK;AAAA,QACZ,MAAM;AAAA,QACN,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MACR,CAAC;AAED,eAAS,KAAK;AAAA,QACZ,MAAM;AAAA,QACN,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,iHAQmG,aAAa,UAAU,kBAAkB;AAAA;AAAA;AAAA,MAGpJ,CAAC;AAED,aAAO,EAAE,SAAS,SAAS;AAAA,IAC7B,SAAS,OAAO;AACd,aAAO,MAAM,oCAAoC,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;AACvG,aAAO;AAAA,QACL,SAAS,CAAC;AAAA,UACR,MAAM;AAAA,UACN,MAAM,2CAAsC,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;AAAA,QACpG,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF;AACF,CAAC;AAMD,OAAO,QAAQ;AAAA,EACb,MAAM;AAAA,EACN,aAAa;AAAA,EACb,aAAa;AAAA,IACX,OAAO;AAAA,IACP,cAAc;AAAA,IACd,eAAe;AAAA,EACjB;AAAA,EACA,YAAY,EAAE,OAAO;AAAA,IACnB,OAAO,EACJ,OAAO,EACP,SAAS,0DAA0D;AAAA,EACxE,CAAC;AAAA,EACD,SAAS,OAAO,MAAM,aAAa;AACjC,QAAI;AACF,aAAO,MAAM,oCAAoC;AACjD,aAAO,MAAM,UAAU,KAAK,KAAK,EAAE;AAGnC,YAAM,gBAAgB,IAAI,sBAAsB;AAAA,QAC9C,WAAW;AAAA,MACb,CAAC;AAGD,YAAM,gBAAgB,MAAM,cAAc,OAAO,KAAK,KAAK;AAG3D,YAAM,EAAE,gBAAgB,IAAI,MAAM,0BAA0B;AAAA,QAC1D,OAAO,KAAK;AAAA,QACZ;AAAA,MACF,CAAC;AAGD,YAAM,mBAAmB,WAAW,WAAW,eAAe;AAE9D,aAAO;AAAA,QACL,SAAS;AAAA,UACP;AAAA,YACE,MAAM;AAAA,YACN,MAAM;AAAA,UACR;AAAA,QACF;AAAA,MACF;AAAA,IACF,SAAS,OAAO;AACd,aAAO,MAAM,sCAAsC,KAAK;AACxD,aAAO;AAAA,QACL,SAAS;AAAA,UACP;AAAA,YACE,MAAM;AAAA,YACN,MAAM,iBAAY,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;AAAA,UAC1E;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF,CAAC;AA+GD,IAAI,aAAa;AACf,SAAO,MAAM;AAAA,IACX,YAAY;AAAA,MACV,MAAM;AAAA,IACR;AAAA,IACA,eAAe;AAAA,EACjB,CAAC;AAED,SAAO,KAAK,gDAAgD;AAC5D,SAAO,KAAK,8BAA8B,IAAI,MAAM;AACpD,SAAO,MAAM,uBAAuB,kBAAkB,EAAE;AACxD,SAAO,MAAM;AAAA;AAAA,gCAEiB,IAAI;AAAA;AAAA;AAAA,CAGnC;AACD,OAAO;AACL,SAAO,MAAM,EAAE,eAAe,QAAQ,CAAC;AACvC,SAAO,KAAK,gDAAgD;AAC9D;","names":["require"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fridaplatform-stk/figma2frida-mcp",
3
- "version": "1.0.8",
3
+ "version": "1.0.9",
4
4
  "main": "dist/figma2frida.js",
5
5
  "scripts": {
6
6
  "build": "tsup",