mcp-lab-agent 2.0.0 → 2.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +42 -3
- package/dist/index.js +10 -0
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -254,15 +254,54 @@ Referência completa do CLI: `mcp-lab-agent --help`
|
|
|
254
254
|
|
|
255
255
|
## Configuração
|
|
256
256
|
|
|
257
|
-
###
|
|
257
|
+
### Opção 1: APIs Externas (Groq, Gemini, OpenAI)
|
|
258
|
+
|
|
259
|
+
```bash
|
|
260
|
+
# .env
|
|
261
|
+
GROQ_API_KEY=sua-key # Gratuito: https://console.groq.com/keys
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
### Opção 2: Ollama (Local, Sem Internet) ⭐ Recomendado para empresas
|
|
265
|
+
|
|
266
|
+
```bash
|
|
267
|
+
# 1. Instale o Ollama
|
|
268
|
+
brew install ollama # macOS
|
|
269
|
+
# ou: curl -fsSL https://ollama.com/install.sh | sh # Linux
|
|
270
|
+
|
|
271
|
+
# 2. Baixe o modelo
|
|
272
|
+
ollama pull llama3.1:8b
|
|
273
|
+
|
|
274
|
+
# 3. Inicie
|
|
275
|
+
ollama serve
|
|
276
|
+
|
|
277
|
+
# 4. Pronto! O agente detecta automaticamente
|
|
278
|
+
npx mcp-lab-agent auto "login flow"
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
**100% offline. Sem APIs externas. Ideal para ambientes corporativos.**
|
|
282
|
+
|
|
283
|
+
### Opção 3: LLM Interno da Empresa
|
|
284
|
+
|
|
285
|
+
```bash
|
|
286
|
+
# .env
|
|
287
|
+
QA_LAB_LLM_BASE_URL=https://llm-interno.empresa.com/v1
|
|
288
|
+
QA_LAB_LLM_API_KEY=sua-key-interna
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
**Guia completo:** [CONFIGURACAO_CORPORATIVA.md](CONFIGURACAO_CORPORATIVA.md)
|
|
292
|
+
|
|
293
|
+
### Variáveis de ambiente (todas opcionais)
|
|
258
294
|
|
|
259
295
|
| Variável | Uso |
|
|
260
296
|
|----------|-----|
|
|
261
297
|
| `GROQ_API_KEY` | Groq (gratuito, rápido) |
|
|
262
298
|
| `GEMINI_API_KEY` | Google Gemini |
|
|
263
299
|
| `OPENAI_API_KEY` | OpenAI |
|
|
264
|
-
| `
|
|
265
|
-
| `
|
|
300
|
+
| `OLLAMA_BASE_URL` | Ollama customizado (default: http://localhost:11434) |
|
|
301
|
+
| `QA_LAB_LLM_BASE_URL` | Endpoint LLM customizado (empresa) |
|
|
302
|
+
| `QA_LAB_LLM_API_KEY` | API key para LLM customizado |
|
|
303
|
+
| `QA_LAB_LLM_SIMPLE` | Modelo para tarefas simples |
|
|
304
|
+
| `QA_LAB_LLM_COMPLEX` | Modelo para tarefas complexas |
|
|
266
305
|
|
|
267
306
|
### Modo browser (opcional)
|
|
268
307
|
|
package/dist/index.js
CHANGED
|
@@ -18,8 +18,18 @@ function resolveLLMProvider(taskType = "simple") {
|
|
|
18
18
|
const GROQ_KEY = process.env.GROQ_API_KEY;
|
|
19
19
|
const GEMINI_KEY = process.env.GEMINI_API_KEY;
|
|
20
20
|
const OPENAI_KEY = process.env.OPENAI_API_KEY || process.env.QA_LAB_LLM_API_KEY;
|
|
21
|
+
const OLLAMA_URL = process.env.OLLAMA_BASE_URL || "http://localhost:11434";
|
|
22
|
+
const CUSTOM_URL = process.env.QA_LAB_LLM_BASE_URL;
|
|
21
23
|
const simpleModel = process.env.QA_LAB_LLM_SIMPLE;
|
|
22
24
|
const complexModel = process.env.QA_LAB_LLM_COMPLEX;
|
|
25
|
+
if (CUSTOM_URL) {
|
|
26
|
+
const model2 = taskType === "complex" ? complexModel || "llama3.1:70b" : simpleModel || "llama3.1:8b";
|
|
27
|
+
return { provider: "custom", apiKey: process.env.QA_LAB_LLM_API_KEY || "not-needed", baseUrl: CUSTOM_URL, model: model2 };
|
|
28
|
+
}
|
|
29
|
+
if (!GROQ_KEY && !GEMINI_KEY && !OPENAI_KEY) {
|
|
30
|
+
const model2 = taskType === "complex" ? complexModel || "llama3.1:70b" : simpleModel || "llama3.1:8b";
|
|
31
|
+
return { provider: "ollama", apiKey: "not-needed", baseUrl: `${OLLAMA_URL}/v1`, model: model2 };
|
|
32
|
+
}
|
|
23
33
|
let provider = GROQ_KEY ? "groq" : GEMINI_KEY ? "gemini" : "openai";
|
|
24
34
|
const apiKey = GROQ_KEY || GEMINI_KEY || OPENAI_KEY;
|
|
25
35
|
const baseUrl = provider === "groq" ? "https://api.groq.com/openai/v1" : provider === "gemini" ? "https://generativelanguage.googleapis.com/v1beta" : "https://api.openai.com/v1";
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.js"],"sourcesContent":["#!/usr/bin/env node\n/**\n * MCP Lab Agent - Standalone\n * MCP server genérico para QA automation em qualquer projeto.\n * Detecta automaticamente Cypress, Playwright, Jest, estrutura do projeto, etc.\n */\nimport { config } from \"dotenv\";\nimport { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\";\nimport { z } from \"zod\";\nimport { spawn } from \"node:child_process\";\nimport path from \"node:path\";\nimport fs from \"node:fs\";\n\nconst PROJECT_ROOT = process.cwd();\nconfig({ path: path.join(PROJECT_ROOT, \".env\") });\n\nconst server = new McpServer({\n name: \"mcp-lab-agent\",\n version: \"1.0.0\",\n});\n\n// ============================================================================\n// MODEL ROUTING - Rotear tarefas simples vs complexas (economia de custo)\n// ============================================================================\n\nconst TASK_COMPLEXITY = {\n simple: [\"generate_tests\", \"create_test_template\", \"suggest_fix\"],\n complex: [\"por_que_falhou\", \"suggest_selector_fix\", \"analyze_file_methods\"],\n};\n\nfunction resolveLLMProvider(taskType = \"simple\") {\n const GROQ_KEY = process.env.GROQ_API_KEY;\n const GEMINI_KEY = process.env.GEMINI_API_KEY;\n const OPENAI_KEY = process.env.OPENAI_API_KEY || process.env.QA_LAB_LLM_API_KEY;\n\n const simpleModel = process.env.QA_LAB_LLM_SIMPLE; // ex: gemini-1.5-flash, gpt-4o-mini\n const complexModel = process.env.QA_LAB_LLM_COMPLEX; // ex: llama-3.3-70b, gpt-4o\n\n let provider = GROQ_KEY ? \"groq\" : GEMINI_KEY ? \"gemini\" : \"openai\";\n const apiKey = GROQ_KEY || GEMINI_KEY || OPENAI_KEY;\n const baseUrl = provider === \"groq\"\n ? \"https://api.groq.com/openai/v1\"\n : provider === \"gemini\"\n ? \"https://generativelanguage.googleapis.com/v1beta\"\n : \"https://api.openai.com/v1\";\n\n let model;\n if (taskType === \"complex\") {\n model = complexModel || (provider === \"groq\" ? \"llama-3.3-70b-versatile\" : provider === \"gemini\" ? \"gemini-1.5-pro\" : \"gpt-4o\");\n } else {\n model = simpleModel || (provider === \"groq\" ? \"llama-3.1-8b-instant\" : provider === \"gemini\" ? \"gemini-1.5-flash\" : \"gpt-4o-mini\");\n }\n\n return { provider, apiKey, baseUrl, model };\n}\n\n// ============================================================================\n// PROJECT MEMORY - Cache de padrões para geração e análise\n// ============================================================================\n\nconst MEMORY_FILE = path.join(PROJECT_ROOT, \".qa-lab-memory.json\");\nconst FLOWS_CONFIG_FILE = path.join(PROJECT_ROOT, \"qa-lab-flows.json\");\n\nfunction loadProjectMemory() {\n const memory = { patterns: {}, conventions: {}, lastRun: null, selectors: [] };\n if (fs.existsSync(MEMORY_FILE)) {\n try {\n const raw = fs.readFileSync(MEMORY_FILE, \"utf8\");\n Object.assign(memory, JSON.parse(raw));\n } catch {}\n }\n if (fs.existsSync(FLOWS_CONFIG_FILE)) {\n try {\n const flows = JSON.parse(fs.readFileSync(FLOWS_CONFIG_FILE, \"utf8\"));\n memory.flows = flows.flows || [];\n } catch {}\n }\n return memory;\n}\n\nfunction saveProjectMemory(updates) {\n try {\n let data = loadProjectMemory();\n if (updates.patterns) data.patterns = { ...data.patterns, ...updates.patterns };\n if (updates.conventions) data.conventions = { ...data.conventions, ...updates.conventions };\n if (updates.selectors) data.selectors = [...new Set([...(data.selectors || []), ...updates.selectors])].slice(-100);\n if (updates.lastRun) data.lastRun = updates.lastRun;\n if (updates.learnings) {\n data.learnings = data.learnings || [];\n data.learnings.push(...updates.learnings);\n if (data.learnings.length > 200) data.learnings = data.learnings.slice(-150);\n }\n data.updatedAt = new Date().toISOString();\n fs.writeFileSync(MEMORY_FILE, JSON.stringify(data, null, 2), \"utf8\");\n } catch {}\n}\n\nfunction getMemoryStats() {\n const memory = loadProjectMemory();\n const learnings = memory.learnings || [];\n const successfulFixes = learnings.filter((l) => l.success);\n const selectorFixes = learnings.filter((l) => l.type === \"selector_fix\");\n const timingFixes = learnings.filter((l) => l.type === \"timing_fix\");\n const totalTests = learnings.filter((l) => l.type === \"test_generated\").length;\n const firstAttemptSuccess = learnings.filter((l) => l.type === \"test_generated\" && l.passedFirstTime).length;\n\n return {\n totalLearnings: learnings.length,\n successfulFixes: successfulFixes.length,\n selectorFixes: selectorFixes.length,\n timingFixes: timingFixes.length,\n testsGenerated: totalTests,\n firstAttemptSuccessRate: totalTests > 0 ? Math.round((firstAttemptSuccess / totalTests) * 100) : 0,\n };\n}\n\n// ============================================================================\n// FLAKY DETECTION - Padrões típicos de teste intermitente\n// ============================================================================\n\nconst FLAKY_PATTERNS = [\n { name: \"timing\", regex: /timeout|timed out|exceeded|wait|delay|slow|race condition/i, suggestion: \"Adicione wait explícito (ex: page.waitForSelector) ou aumente o timeout.\" },\n { name: \"ordering\", regex: /order|sequenc|flaky|intermittent|sometimes|random/i, suggestion: \"Issole o teste ou use beforeAll/afterAll para estado limpo. Evite dependência de ordem entre testes.\" },\n { name: \"selector\", regex: /element not found|selector|locator|cy\\.get|page\\.locator|Unable to find/i, suggestion: \"Use seletores estáveis: data-testid, role, texto acessível. Evite classes CSS dinâmicas.\" },\n { name: \"network\", regex: /ECONNREFUSED|network|fetch|axios|request failed|404|500/i, suggestion: \"Mocke APIs ou garanta que o backend esteja rodando. Use retry ou intercept.\" },\n { name: \"shared_state\", regex: /state|cleanup|beforeEach|afterEach|isolation/i, suggestion: \"Garanta beforeEach/afterEach para resetar estado. Evite variáveis globais compartilhadas.\" },\n];\n\nfunction detectFlakyPatterns(runOutput) {\n const detected = [];\n for (const p of FLAKY_PATTERNS) {\n if (p.regex.test(runOutput)) {\n detected.push({ pattern: p.name, suggestion: p.suggestion });\n }\n }\n const confidence = detected.length > 0 ? Math.min(0.5 + detected.length * 0.2, 0.95) : 0;\n return { isLikelyFlaky: confidence > 0.5, confidence, patterns: detected };\n}\n\n// ============================================================================\n// DETECÇÃO AUTOMÁTICA DE ESTRUTURA\n// ============================================================================\n\nfunction detectProjectStructure() {\n const structure = {\n hasTests: false,\n testFrameworks: [],\n testDirs: [],\n hasBackend: false,\n backendDir: null,\n hasFrontend: false,\n frontendDir: null,\n hasMobile: false,\n packageJson: null,\n pythonRequirements: null,\n };\n\n // Detectar Node.js/JavaScript/TypeScript\n const pkgPath = path.join(PROJECT_ROOT, \"package.json\");\n if (fs.existsSync(pkgPath)) {\n structure.packageJson = JSON.parse(fs.readFileSync(pkgPath, \"utf8\"));\n const deps = {\n ...structure.packageJson.dependencies,\n ...structure.packageJson.devDependencies,\n };\n\n // Frameworks E2E/UI\n if (deps.cypress) {\n structure.testFrameworks.push(\"cypress\");\n structure.hasTests = true;\n }\n if (deps[\"@playwright/test\"] || deps.playwright) {\n structure.testFrameworks.push(\"playwright\");\n structure.hasTests = true;\n }\n if (deps.webdriverio || deps[\"@wdio/cli\"]) {\n structure.testFrameworks.push(\"webdriverio\");\n structure.hasTests = true;\n }\n\n // Frameworks Unit/Integration\n if (deps.jest) {\n structure.testFrameworks.push(\"jest\");\n structure.hasTests = true;\n }\n if (deps.vitest) {\n structure.testFrameworks.push(\"vitest\");\n structure.hasTests = true;\n }\n if (deps.mocha) {\n structure.testFrameworks.push(\"mocha\");\n structure.hasTests = true;\n }\n if (deps.jasmine) {\n structure.testFrameworks.push(\"jasmine\");\n structure.hasTests = true;\n }\n\n // Frameworks Mobile\n if (deps.appium || deps[\"appium-webdriverio\"]) {\n structure.testFrameworks.push(\"appium\");\n structure.hasTests = true;\n structure.hasMobile = true;\n }\n if (deps.detox) {\n structure.testFrameworks.push(\"detox\");\n structure.hasTests = true;\n structure.hasMobile = true;\n }\n\n // API Testing\n if (deps.supertest) {\n structure.testFrameworks.push(\"supertest\");\n structure.hasTests = true;\n }\n if (deps[\"@pactum/pactum\"] || deps.pactum) {\n structure.testFrameworks.push(\"pactum\");\n structure.hasTests = true;\n }\n\n // Outros frameworks E2E\n if (deps.testcafe || deps[\"testcafe\"]) {\n structure.testFrameworks.push(\"testcafe\");\n structure.hasTests = true;\n }\n if (deps.nightwatch || deps[\"nightwatch\"]) {\n structure.testFrameworks.push(\"nightwatch\");\n structure.hasTests = true;\n }\n if (deps.puppeteer) {\n structure.testFrameworks.push(\"puppeteer\");\n structure.hasTests = true;\n }\n if (deps.codeceptjs || deps[\"codeceptjs\"]) {\n structure.testFrameworks.push(\"codeceptjs\");\n structure.hasTests = true;\n }\n\n // Backend detection\n if (deps.express || deps.fastify || deps[\"@nestjs/core\"] || deps.koa) {\n structure.hasBackend = true;\n }\n \n // Frontend detection\n if (deps.next || deps.react || deps.vue || deps.svelte || deps.angular) {\n structure.hasFrontend = true;\n }\n }\n\n // Detectar Python (Robot Framework, pytest, etc.)\n const requirementsPath = path.join(PROJECT_ROOT, \"requirements.txt\");\n if (fs.existsSync(requirementsPath)) {\n const requirements = fs.readFileSync(requirementsPath, \"utf8\");\n structure.pythonRequirements = requirements;\n\n if (/robotframework/i.test(requirements)) {\n structure.testFrameworks.push(\"robot\");\n structure.hasTests = true;\n }\n if (/pytest/i.test(requirements)) {\n structure.testFrameworks.push(\"pytest\");\n structure.hasTests = true;\n }\n if (/behave/i.test(requirements)) {\n structure.testFrameworks.push(\"behave\");\n structure.hasTests = true;\n }\n if (/requests/i.test(requirements)) {\n structure.hasBackend = true;\n }\n }\n\n // Detectar pastas de teste (genérico)\n const commonTestDirs = [\n \"tests\", \"test\", \"e2e\", \"cypress\", \"playwright\", \"__tests__\",\n \"specs\", \"spec\", \"integration\", \"unit\", \"functional\", \"robot\",\n \"features\", \"scenarios\", \"mobile\", \"api\",\n // Monorepo: subprojetos por framework\n \"playwright-js\", \"puppeteer-js\", \"testcafe-js\", \"wdio-webdriver-io\",\n \"nightwatch-js\", \"codeceptjs\", \"robot-framework\", \"selenium-python\"\n ];\n for (const dir of commonTestDirs) {\n const fullPath = path.join(PROJECT_ROOT, dir);\n if (fs.existsSync(fullPath) && fs.statSync(fullPath).isDirectory()) {\n structure.testDirs.push(dir);\n }\n }\n\n // Monorepo: escanear subdirs de primeiro nível que parecem ter testes\n const skipDirs = [\"node_modules\", \".git\", \"dist\", \"build\", \".next\", \".venv\"];\n try {\n const rootEntries = fs.readdirSync(PROJECT_ROOT, { withFileTypes: true });\n for (const e of rootEntries) {\n if (!e.isDirectory() || skipDirs.includes(e.name)) continue;\n const subPath = path.join(PROJECT_ROOT, e.name);\n if (structure.testDirs.includes(e.name)) continue;\n // Verificar se há package.json ou tests/ dentro\n const hasPkg = fs.existsSync(path.join(subPath, \"package.json\"));\n const hasTests = fs.existsSync(path.join(subPath, \"tests\")) ||\n fs.existsSync(path.join(subPath, \"test\")) ||\n fs.existsSync(path.join(subPath, \"e2e\")) ||\n fs.existsSync(path.join(subPath, \"__tests__\")) ||\n fs.existsSync(path.join(subPath, \"specs\"));\n if (hasPkg || hasTests) {\n structure.testDirs.push(e.name);\n }\n }\n } catch {}\n\n // Monorepo: detectar frameworks em package.json de subdirs\n for (const dir of structure.testDirs) {\n const subPkg = path.join(PROJECT_ROOT, dir, \"package.json\");\n if (!fs.existsSync(subPkg)) continue;\n try {\n const sub = JSON.parse(fs.readFileSync(subPkg, \"utf8\"));\n const subDeps = { ...(sub.dependencies || {}), ...(sub.devDependencies || {}) };\n const toAdd = [];\n if (subDeps.cypress && !structure.testFrameworks.includes(\"cypress\")) toAdd.push(\"cypress\");\n if ((subDeps[\"@playwright/test\"] || subDeps.playwright) && !structure.testFrameworks.includes(\"playwright\")) toAdd.push(\"playwright\");\n if ((subDeps.webdriverio || subDeps[\"@wdio/cli\"]) && !structure.testFrameworks.includes(\"webdriverio\")) toAdd.push(\"webdriverio\");\n if (subDeps.testcafe && !structure.testFrameworks.includes(\"testcafe\")) toAdd.push(\"testcafe\");\n if (subDeps.nightwatch && !structure.testFrameworks.includes(\"nightwatch\")) toAdd.push(\"nightwatch\");\n if (subDeps.puppeteer && !structure.testFrameworks.includes(\"puppeteer\")) toAdd.push(\"puppeteer\");\n if (subDeps.codeceptjs && !structure.testFrameworks.includes(\"codeceptjs\")) toAdd.push(\"codeceptjs\");\n if (subDeps.jest && !structure.testFrameworks.includes(\"jest\")) toAdd.push(\"jest\");\n toAdd.forEach((fw) => { structure.testFrameworks.push(fw); structure.hasTests = true; });\n } catch {}\n }\n\n // Monorepo: detectar Robot/pytest em requirements.txt de subdirs\n for (const dir of structure.testDirs) {\n const reqPath = path.join(PROJECT_ROOT, dir, \"requirements.txt\");\n if (!fs.existsSync(reqPath)) continue;\n try {\n const req = fs.readFileSync(reqPath, \"utf8\");\n if (/robotframework/i.test(req) && !structure.testFrameworks.includes(\"robot\")) {\n structure.testFrameworks.push(\"robot\");\n structure.hasTests = true;\n }\n if (/pytest|selenium/i.test(req) && !structure.testFrameworks.includes(\"pytest\")) {\n structure.testFrameworks.push(\"pytest\");\n structure.hasTests = true;\n }\n } catch {}\n }\n\n // Detectar backend\n const commonBackendDirs = [\"backend\", \"server\", \"api\", \"src\"];\n for (const dir of commonBackendDirs) {\n const fullPath = path.join(PROJECT_ROOT, dir);\n if (fs.existsSync(fullPath) && !structure.backendDir) {\n const hasServerFile = fs.existsSync(path.join(fullPath, \"server.js\")) ||\n fs.existsSync(path.join(fullPath, \"index.js\")) ||\n fs.existsSync(path.join(fullPath, \"app.js\"));\n if (hasServerFile) {\n structure.backendDir = dir;\n }\n }\n }\n\n // Detectar frontend\n const commonFrontendDirs = [\"frontend\", \"client\", \"web\", \"app\", \"src\"];\n for (const dir of commonFrontendDirs) {\n const fullPath = path.join(PROJECT_ROOT, dir);\n if (fs.existsSync(fullPath) && !structure.frontendDir) {\n const hasAppFile = fs.existsSync(path.join(fullPath, \"App.js\")) ||\n fs.existsSync(path.join(fullPath, \"App.tsx\")) ||\n fs.existsSync(path.join(fullPath, \"index.html\"));\n if (hasAppFile) {\n structure.frontendDir = dir;\n }\n }\n }\n\n return structure;\n}\n\n// ============================================================================\n// PADRÕES UNIVERSAIS DE ARQUIVOS DE TESTE (qualquer framework)\n// ============================================================================\n\nconst UNIVERSAL_TEST_PATTERNS = [\n /\\.(cy|spec|test)\\.(js|ts|jsx|tsx)$/i,\n /_test\\.(js|ts)$/i, // CodeceptJS\n /\\.robot$/i,\n /\\.feature$/i,\n /^(test_.*|.*_test)\\.py$/i,\n /\\.steps?\\.(js|ts|py)$/i,\n /\\.e2e\\.(js|ts)$/i,\n /\\.it\\.(js|ts)$/i,\n];\n\nfunction isTestFile(name) {\n return UNIVERSAL_TEST_PATTERNS.some((re) => re.test(name));\n}\n\nfunction collectTestFiles(structure, options = {}) {\n const { pattern, framework, maxContentFiles = 0 } = options;\n const results = [];\n\n for (const dir of structure.testDirs) {\n const fullPath = path.join(PROJECT_ROOT, dir);\n const walk = (p, base = \"\") => {\n if (!fs.existsSync(p)) return;\n const entries = fs.readdirSync(p, { withFileTypes: true });\n for (const e of entries) {\n const rel = base ? `${base}/${e.name}` : e.name;\n if (e.isDirectory()) {\n if (e.name === \"node_modules\" || e.name === \".git\" || e.name === \".venv\") continue;\n walk(path.join(p, e.name), rel);\n } else if (e.isFile() && isTestFile(e.name)) {\n const filePath = `${dir}/${rel}`;\n if (pattern && !filePath.toLowerCase().includes(pattern.toLowerCase())) continue;\n const inferredFw = inferFrameworkFromFile(e.name, structure, filePath);\n if (framework && framework !== \"all\" && inferredFw !== framework && !matchesFramework(inferredFw, framework)) continue;\n const entry = { path: filePath, inferredFramework: inferredFw };\n if (maxContentFiles > 0 && results.length < maxContentFiles) {\n try {\n entry.content = fs.readFileSync(path.join(PROJECT_ROOT, filePath), \"utf8\");\n } catch {}\n }\n results.push(entry);\n }\n }\n };\n walk(fullPath);\n }\n return results;\n}\n\nfunction inferFrameworkFromFile(name, structure = {}, filePath = \"\") {\n const pathLower = (filePath || \"\").toLowerCase().replace(/\\\\/g, \"/\");\n // Inferir pelo CAMINHO quando há múltiplos frameworks (ex: tests/cypress/, tests/selenium-python/)\n if (/[\\/]cypress[\\/\\-]/.test(pathLower)) return \"cypress\";\n if (/[\\/]playwright[\\/\\-]/.test(pathLower)) return \"playwright\";\n if (/[\\/]wdio[\\/\\-]|[\\/]webdriver[\\/\\-]/.test(pathLower)) return \"webdriverio\";\n if (/[\\/]appium[\\/\\-]/.test(pathLower)) return \"appium\";\n if (/[\\/]selenium-python[\\/]|[\\/]pytest[\\/\\-]/.test(pathLower)) return \"pytest\";\n if (/[\\/]robot[\\/\\-]/.test(pathLower)) return \"robot\";\n if (/[\\/]codecept[\\/\\-]/.test(pathLower)) return \"codeceptjs\";\n if (/[\\/]nightwatch[\\/\\-]/.test(pathLower)) return \"nightwatch\";\n if (/[\\/]testcafe[\\/\\-]/.test(pathLower)) return \"testcafe\";\n if (/[\\/]puppeteer[\\/\\-]/.test(pathLower)) return \"puppeteer\";\n if (/[\\/]behave[\\/\\-]|[\\/]features[\\/]/.test(pathLower)) return \"behave\";\n // Fallback: inferir pela extensão do arquivo\n if (/\\.cy\\.(js|ts|jsx|tsx)/i.test(name)) return \"cypress\";\n if (/_test\\.(js|ts)$/i.test(name)) return \"codeceptjs\";\n if (/\\.spec\\.(js|ts|jsx|tsx)/i.test(name)) {\n if (structure?.testFrameworks?.includes(\"webdriverio\")) return \"webdriverio\";\n if (structure?.testFrameworks?.includes(\"appium\")) return \"appium\";\n return \"playwright\";\n }\n if (/\\.test\\.(js|ts|jsx|tsx)/i.test(name)) return structure?.testFrameworks?.includes(\"vitest\") ? \"vitest\" : \"jest\";\n if (/\\.robot$/i.test(name)) return \"robot\";\n if (/\\.feature$/i.test(name)) return \"behave\";\n if (/\\.(py|steps?\\.py)$/i.test(name) || /^(test_.*|.*_test)\\.py$/i.test(name)) return \"pytest\";\n if (/\\.e2e\\.(js|ts)/i.test(name)) return \"playwright\";\n return \"unknown\";\n}\n\nfunction matchesFramework(inferred, requested) {\n const aliases = { spec: [\"playwright\", \"webdriverio\", \"appium\"] };\n if (inferred === requested) return true;\n return aliases[inferred]?.includes(requested);\n}\n\nfunction getFrameworkCwd(structure, preferredDirs) {\n for (const dir of preferredDirs) {\n if (structure.testDirs.includes(dir)) {\n return path.join(PROJECT_ROOT, dir);\n }\n }\n const fallback = structure.testDirs[0];\n return fallback ? path.join(PROJECT_ROOT, fallback) : PROJECT_ROOT;\n}\n\n// ============================================================================\n// MÉTRICAS DE NEGÓCIO - Helpers (FLOWS_CONFIG_FILE definido acima)\n// ============================================================================\n\nconst METRICS_FILE = path.join(PROJECT_ROOT, \".qa-lab-metrics.json\");\n\nfunction parseTestRunResult(runOutput, exitCode) {\n let passed = 0;\n let failed = 0;\n const jestMatch = runOutput.match(/Tests:\\s+(\\d+)\\s+passed(?:,\\s*(\\d+)\\s+failed)?/);\n if (jestMatch) {\n passed = parseInt(jestMatch[1], 10);\n failed = jestMatch[2] ? parseInt(jestMatch[2], 10) : 0;\n }\n const cypressPass = runOutput.match(/(\\d+)\\s+passing/);\n const cypressFail = runOutput.match(/(\\d+)\\s+failing/);\n if (cypressPass) passed = parseInt(cypressPass[1], 10);\n if (cypressFail) failed = parseInt(cypressFail[1], 10);\n const pwPass = runOutput.match(/(\\d+)\\s+passed/);\n const pwFail = runOutput.match(/(\\d+)\\s+failed/);\n if (pwPass) passed = parseInt(pwPass[1], 10);\n if (pwFail) failed = parseInt(pwFail[1], 10);\n if (passed === 0 && failed === 0) {\n if (exitCode === 0) passed = 1;\n else failed = 1;\n }\n return { passed, failed };\n}\n\nfunction appendMetricsEvent(event) {\n try {\n let data = { events: [], lastUpdated: new Date().toISOString() };\n if (fs.existsSync(METRICS_FILE)) {\n const raw = fs.readFileSync(METRICS_FILE, \"utf8\");\n try {\n data = JSON.parse(raw);\n } catch {}\n }\n data.events = data.events || [];\n data.events.push({ ...event, timestamp: event.timestamp || new Date().toISOString() });\n data.lastUpdated = new Date().toISOString();\n if (data.events.length > 500) data.events = data.events.slice(-400);\n fs.writeFileSync(METRICS_FILE, JSON.stringify(data, null, 2), \"utf8\");\n } catch {}\n}\n\nfunction extractFailuresFromOutput(runOutput) {\n const failures = [];\n const lines = runOutput.split(\"\\n\");\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n if (/fail|error|assertion|timeout|element not found|selector/i.test(line)) {\n failures.push({\n test: lines[Math.max(0, i - 1)]?.trim() || \"unknown\",\n message: line.trim().slice(0, 500),\n });\n }\n }\n return failures.slice(0, 20);\n}\n\n// ============================================================================\n// FERRAMENTAS GENÉRICAS\n// ============================================================================\n\nserver.registerTool(\n \"read_file\",\n {\n title: \"Ler qualquer arquivo\",\n description: \"Lê o conteúdo de QUALQUER arquivo do projeto por caminho. Use para specs, page objects, componentes, código fonte - qualquer formato.\",\n inputSchema: z.object({\n path: z.string().describe(\"Caminho relativo ao projeto (ex: cypress/e2e/login.cy.js, src/pages/Login.tsx, tests/login.robot).\"),\n encoding: z.enum([\"utf8\", \"utf-8\"]).optional().describe(\"Encoding. Default: utf8\"),\n }),\n outputSchema: z.object({\n ok: z.boolean(),\n content: z.string().optional(),\n error: z.string().optional(),\n }),\n },\n async ({ path: filePath, encoding = \"utf8\" }) => {\n const normalized = filePath.replace(/^\\//, \"\").replace(/\\\\/g, \"/\");\n const fullPath = path.join(PROJECT_ROOT, normalized);\n\n if (!fullPath.startsWith(PROJECT_ROOT)) {\n return {\n content: [{ type: \"text\", text: \"Caminho fora do projeto.\" }],\n structuredContent: { ok: false, error: \"Path outside project\" },\n };\n }\n if (!fs.existsSync(fullPath)) {\n return {\n content: [{ type: \"text\", text: `Arquivo não encontrado: ${normalized}` }],\n structuredContent: { ok: false, error: \"File not found\" },\n };\n }\n const stat = fs.statSync(fullPath);\n if (stat.isDirectory()) {\n return {\n content: [{ type: \"text\", text: \"É um diretório. Use um caminho de arquivo.\" }],\n structuredContent: { ok: false, error: \"Is directory\" },\n };\n }\n\n try {\n const content = fs.readFileSync(fullPath, encoding);\n return {\n content: [{ type: \"text\", text: content }],\n structuredContent: { ok: true, content },\n };\n } catch (err) {\n return {\n content: [{ type: \"text\", text: `Erro ao ler: ${err.message}` }],\n structuredContent: { ok: false, error: err.message },\n };\n }\n }\n);\n\nserver.registerTool(\n \"detect_project\",\n {\n title: \"Detectar estrutura do projeto\",\n description: \"Analisa o projeto e identifica frameworks de teste, pastas, backend, frontend.\",\n inputSchema: z.object({}),\n outputSchema: z.object({\n ok: z.boolean(),\n structure: z.object({\n hasTests: z.boolean(),\n testFrameworks: z.array(z.string()),\n testDirs: z.array(z.string()),\n hasBackend: z.boolean(),\n backendDir: z.string().nullable(),\n hasFrontend: z.boolean(),\n frontendDir: z.string().nullable(),\n }),\n }),\n },\n async () => {\n const structure = detectProjectStructure();\n const summary = [\n `Frameworks de teste: ${structure.testFrameworks.join(\", \") || \"nenhum\"}`,\n `Pastas de teste: ${structure.testDirs.join(\", \") || \"nenhuma\"}`,\n `Backend: ${structure.backendDir || \"não detectado\"}`,\n `Frontend: ${structure.frontendDir || \"não detectado\"}`,\n ].join(\"\\n\");\n\n return {\n content: [{ type: \"text\", text: summary }],\n structuredContent: { ok: true, structure },\n };\n }\n);\n\n// ============================================================================\n// WEB EVAL BROWSER - Modo browser (screenshots, network, console) via Playwright\n// ============================================================================\n\nserver.registerTool(\n \"web_eval_browser\",\n {\n title: \"Avaliar app no browser (screenshots, network, console)\",\n description: \"[Agente especializado: Browser] Abre a URL no navegador, captura screenshot, erros de console e requisições de rede. Inspirado em web-eval-agent. Requer: npm install playwright\",\n inputSchema: z.object({\n url: z.string().describe(\"URL para avaliar (ex: http://localhost:3000, https://exemplo.com).\"),\n screenshotPath: z.string().optional().describe(\"Caminho para salvar screenshot. Default: .qa-lab-screenshot.png\"),\n captureNetwork: z.boolean().optional().describe(\"Capturar requisições de rede. Default: true\"),\n captureConsole: z.boolean().optional().describe(\"Capturar logs e erros do console. Default: true\"),\n }),\n outputSchema: z.object({\n ok: z.boolean(),\n screenshotPath: z.string().optional(),\n consoleLogs: z.array(z.string()).optional(),\n consoleErrors: z.array(z.string()).optional(),\n networkRequests: z.array(z.object({ url: z.string(), method: z.string(), status: z.number().optional() })).optional(),\n error: z.string().optional(),\n }),\n },\n async ({ url, screenshotPath, captureNetwork = true, captureConsole = true }) => {\n let playwright;\n try {\n playwright = await import(\"playwright\");\n } catch (e) {\n return {\n content: [{\n type: \"text\",\n text: \"Playwright não instalado. Rode: npm install playwright (ou npx playwright install para browsers).\",\n }],\n structuredContent: { ok: false, error: \"Playwright not installed. Run: npm install playwright\" },\n };\n }\n\n const outPath = screenshotPath ? path.join(PROJECT_ROOT, screenshotPath.replace(/^\\//, \"\")) : path.join(PROJECT_ROOT, \".qa-lab-screenshot.png\");\n const consoleLogs = [];\n const consoleErrors = [];\n const networkRequests = [];\n\n try {\n const browser = await playwright.chromium.launch({ headless: true });\n const context = await browser.newContext();\n const page = await context.newPage();\n\n if (captureConsole) {\n page.on(\"console\", (msg) => {\n const text = msg.text();\n if (msg.type() === \"error\") consoleErrors.push(text);\n else consoleLogs.push(`[${msg.type()}] ${text}`);\n });\n }\n\n if (captureNetwork) {\n page.on(\"request\", (req) => {\n networkRequests.push({ url: req.url(), method: req.method(), status: undefined });\n });\n page.on(\"response\", (res) => {\n const req = networkRequests.find((r) => r.url === res.request().url());\n if (req) req.status = res.status();\n });\n }\n\n await page.goto(url, { waitUntil: \"networkidle\", timeout: 30000 });\n await page.screenshot({ path: outPath, fullPage: false });\n\n await browser.close();\n\n const relPath = path.relative(PROJECT_ROOT, outPath);\n let summary = `Screenshot salvo: ${relPath}`;\n if (consoleErrors.length) summary += `\\n\\n⚠️ ${consoleErrors.length} erro(s) no console:\\n${consoleErrors.slice(0, 5).join(\"\\n\")}`;\n if (networkRequests.length) summary += `\\n\\nRequisições: ${networkRequests.length}`;\n\n return {\n content: [{ type: \"text\", text: summary }],\n structuredContent: {\n ok: true,\n screenshotPath: relPath,\n consoleLogs: captureConsole ? consoleLogs.slice(0, 50) : undefined,\n consoleErrors: captureConsole && consoleErrors.length ? consoleErrors : undefined,\n networkRequests: captureNetwork ? networkRequests.slice(0, 30) : undefined,\n },\n };\n } catch (err) {\n return {\n content: [{ type: \"text\", text: `Erro: ${err.message}` }],\n structuredContent: { ok: false, error: err.message },\n };\n }\n }\n);\n\n// ============================================================================\n// QA ROUTE TASK - Agentes especializados (roteamento de tarefas)\n// ============================================================================\n\nconst QA_AGENTS = {\n autonomous: { tools: [\"qa_auto\"], desc: \"Modo autônomo: gera, roda, corrige e aprende (loop completo)\" },\n detection: { tools: [\"detect_project\", \"read_project\", \"list_test_files\"], desc: \"Detecção de estrutura, frameworks e arquivos\" },\n execution: { tools: [\"run_tests\", \"watch_tests\", \"get_test_coverage\"], desc: \"Execução de testes e cobertura\" },\n generation: { tools: [\"generate_tests\", \"write_test\", \"create_test_template\"], desc: \"Geração de testes com LLM\" },\n analysis: { tools: [\"analyze_failures\", \"por_que_falhou\", \"suggest_fix\", \"suggest_selector_fix\"], desc: \"Análise de falhas e sugestões\" },\n browser: { tools: [\"web_eval_browser\"], desc: \"Avaliação em browser real (screenshots, network, console)\" },\n reporting: { tools: [\"create_bug_report\", \"get_business_metrics\"], desc: \"Relatórios e métricas\" },\n learning: { tools: [\"qa_learning_stats\"], desc: \"Estatísticas de aprendizado e evolução\" },\n maintenance: { tools: [\"run_linter\", \"install_dependencies\", \"analyze_file_methods\"], desc: \"Manutenção e análise de código\" },\n};\n\nserver.registerTool(\n \"qa_route_task\",\n {\n title: \"Roteador de tarefas QA (agentes especializados)\",\n description: \"Recebe uma descrição da tarefa e retorna qual agente (conjunto de ferramentas) deve ser usado. Útil para encaminhar a ferramenta certa.\",\n inputSchema: z.object({\n task: z.string().describe(\"Descrição da tarefa (ex: 'rodar os testes', 'gerar teste de login', 'analisar por que falhou').\"),\n }),\n outputSchema: z.object({\n ok: z.boolean(),\n suggestedAgent: z.string(),\n suggestedTools: z.array(z.string()),\n description: z.string(),\n }),\n },\n async ({ task }) => {\n const t = task.toLowerCase();\n if (/autônomo|auto|completo|loop|aprende|corrige automaticamente/i.test(t)) {\n return { content: [{ type: \"text\", text: \"Agente: autonomous → qa_auto (loop completo: gera, roda, corrige, aprende)\" }], structuredContent: { ok: true, suggestedAgent: \"autonomous\", suggestedTools: QA_AGENTS.autonomous.tools, description: QA_AGENTS.autonomous.desc } };\n }\n if (/estatística|métrica de aprendizado|taxa de sucesso|learning|stats/i.test(t)) {\n return { content: [{ type: \"text\", text: \"Agente: learning → qa_learning_stats\" }], structuredContent: { ok: true, suggestedAgent: \"learning\", suggestedTools: QA_AGENTS.learning.tools, description: QA_AGENTS.learning.desc } };\n }\n if (/rodar|executar|run|test|coverage|watch/i.test(t)) {\n return { content: [{ type: \"text\", text: \"Agente: execution → run_tests, get_test_coverage\" }], structuredContent: { ok: true, suggestedAgent: \"execution\", suggestedTools: QA_AGENTS.execution.tools, description: QA_AGENTS.execution.desc } };\n }\n if (/gerar|criar|escrever|generate|write|template/i.test(t)) {\n return { content: [{ type: \"text\", text: \"Agente: generation → generate_tests, write_test\" }], structuredContent: { ok: true, suggestedAgent: \"generation\", suggestedTools: QA_AGENTS.generation.tools, description: QA_AGENTS.generation.desc } };\n }\n if (/analisar|por que|falhou|suggest|correção|selector|fix/i.test(t)) {\n return { content: [{ type: \"text\", text: \"Agente: analysis → analyze_failures, por_que_falhou, suggest_fix\" }], structuredContent: { ok: true, suggestedAgent: \"analysis\", suggestedTools: QA_AGENTS.analysis.tools, description: QA_AGENTS.analysis.desc } };\n }\n if (/browser|screenshot|navegador|avaliar|ux|network|console/i.test(t)) {\n return { content: [{ type: \"text\", text: \"Agente: browser → web_eval_browser\" }], structuredContent: { ok: true, suggestedAgent: \"browser\", suggestedTools: QA_AGENTS.browser.tools, description: QA_AGENTS.browser.desc } };\n }\n if (/detectar|estrutura|listar|arquivos|framework/i.test(t)) {\n return { content: [{ type: \"text\", text: \"Agente: detection → detect_project, list_test_files\" }], structuredContent: { ok: true, suggestedAgent: \"detection\", suggestedTools: QA_AGENTS.detection.tools, description: QA_AGENTS.detection.desc } };\n }\n if (/relatório|bug|métricas|metrics|coverage/i.test(t)) {\n return { content: [{ type: \"text\", text: \"Agente: reporting → create_bug_report, get_business_metrics\" }], structuredContent: { ok: true, suggestedAgent: \"reporting\", suggestedTools: QA_AGENTS.reporting.tools, description: QA_AGENTS.reporting.desc } };\n }\n return { content: [{ type: \"text\", text: \"Agente: detection (genérico)\" }], structuredContent: { ok: true, suggestedAgent: \"detection\", suggestedTools: QA_AGENTS.detection.tools, description: QA_AGENTS.detection.desc } };\n }\n);\n\nserver.registerTool(\n \"run_tests\",\n {\n title: \"Executar testes\",\n description: \"Roda testes do projeto. Suporta: Cypress, Playwright, WebdriverIO, Jest, Vitest, Mocha, Appium, Detox, Robot Framework, pytest, e mais. Detecta automaticamente.\",\n inputSchema: z.object({\n framework: z.enum([\n \"cypress\", \"playwright\", \"webdriverio\", \"jest\", \"vitest\", \"mocha\",\n \"appium\", \"detox\", \"robot\", \"pytest\", \"supertest\", \"pactum\",\n \"testcafe\", \"nightwatch\", \"puppeteer\", \"codeceptjs\", \"npm\"\n ]).optional().describe(\"Framework específico ou 'npm' para npm test.\"),\n spec: z.string().optional().describe(\"Caminho do spec (ex: cypress/e2e/test.cy.js).\"),\n suite: z.string().optional().describe(\"Suite ou pattern (ex: e2e, api).\"),\n explainOnFailure: z.boolean().optional().describe(\"Se true, quando falhar gera automaticamente: O que aconteceu, Por que falhou, O que fazer, Sugestão de correção. Requer API key.\"),\n }),\n outputSchema: z.object({\n status: z.enum([\"passed\", \"failed\", \"not_found\"]),\n message: z.string(),\n exitCode: z.number(),\n runOutput: z.string().optional(),\n }),\n },\n async ({ framework, spec, suite, explainOnFailure }) => {\n const structure = detectProjectStructure();\n \n if (!structure.hasTests) {\n return {\n content: [{ type: \"text\", text: \"Nenhum framework de teste detectado no projeto.\" }],\n structuredContent: {\n status: \"not_found\",\n message: \"No test framework found\",\n exitCode: 1,\n },\n };\n }\n\n let selectedFramework = framework;\n if (!selectedFramework && structure.testFrameworks.length > 0) {\n selectedFramework = structure.testFrameworks[0];\n }\n\n let cmd, args, cwd;\n\n // E2E/UI Frameworks\n if (selectedFramework === \"cypress\") {\n cmd = \"npx\";\n args = spec ? [\"cypress\", \"run\", \"--spec\", spec] : [\"cypress\", \"run\"];\n cwd = structure.testDirs.includes(\"cypress\") \n ? path.join(PROJECT_ROOT, \"cypress\")\n : structure.testDirs[0] \n ? path.join(PROJECT_ROOT, structure.testDirs[0])\n : PROJECT_ROOT;\n } else if (selectedFramework === \"playwright\") {\n cmd = \"npx\";\n args = spec ? [\"playwright\", \"test\", spec] : [\"playwright\", \"test\"];\n cwd = structure.testDirs.includes(\"playwright\")\n ? path.join(PROJECT_ROOT, \"playwright\")\n : structure.testDirs[0]\n ? path.join(PROJECT_ROOT, structure.testDirs[0])\n : PROJECT_ROOT;\n } else if (selectedFramework === \"webdriverio\") {\n cmd = \"npx\";\n args = spec ? [\"wdio\", \"run\", spec] : [\"wdio\", \"run\"];\n cwd = getFrameworkCwd(structure, [\"wdio-webdriver-io\", \"specs\", \"tests\"]);\n } else if (selectedFramework === \"testcafe\") {\n cmd = \"npx\";\n args = spec ? [\"testcafe\", spec] : [\"testcafe\"];\n cwd = getFrameworkCwd(structure, [\"testcafe-js\", \"testcafe\", \"tests\"]);\n } else if (selectedFramework === \"nightwatch\") {\n cmd = \"npx\";\n args = spec ? [\"nightwatch\", \"--test\", spec] : [\"nightwatch\"];\n cwd = getFrameworkCwd(structure, [\"nightwatch-js\", \"nightwatch\", \"tests\"]);\n } else if (selectedFramework === \"puppeteer\") {\n cmd = \"npx\";\n args = spec ? [\"jest\", spec, \"--config\", \"jest.config.js\"] : [\"jest\"];\n cwd = getFrameworkCwd(structure, [\"puppeteer-js\", \"puppeteer\", \"__tests__\"]);\n } else if (selectedFramework === \"codeceptjs\") {\n cmd = \"npx\";\n args = spec ? [\"codeceptjs\", \"run\", \"--grep\", spec] : [\"codeceptjs\", \"run\"];\n cwd = getFrameworkCwd(structure, [\"codeceptjs\", \"tests\"]);\n\n // Unit/Integration Frameworks\n } else if (selectedFramework === \"jest\") {\n cmd = \"npx\";\n args = [\"jest\"];\n if (spec) args.push(spec);\n cwd = PROJECT_ROOT;\n } else if (selectedFramework === \"vitest\") {\n cmd = \"npx\";\n args = [\"vitest\", \"run\"];\n if (spec) args.push(spec);\n cwd = PROJECT_ROOT;\n } else if (selectedFramework === \"mocha\") {\n cmd = \"npx\";\n args = spec ? [\"mocha\", spec] : [\"mocha\"];\n cwd = PROJECT_ROOT;\n \n // Mobile Frameworks\n } else if (selectedFramework === \"appium\") {\n cmd = \"npx\";\n args = spec ? [\"wdio\", \"run\", spec] : [\"wdio\", \"run\"];\n cwd = PROJECT_ROOT;\n } else if (selectedFramework === \"detox\") {\n cmd = \"npx\";\n args = [\"detox\", \"test\"];\n if (spec) args.push(spec);\n cwd = PROJECT_ROOT;\n \n // Python Frameworks\n } else if (selectedFramework === \"robot\") {\n cmd = \"robot\";\n args = spec ? [spec] : [structure.testDirs[0] || \"tests\"];\n cwd = PROJECT_ROOT;\n } else if (selectedFramework === \"pytest\") {\n cmd = \"pytest\";\n args = spec ? [spec] : [];\n cwd = PROJECT_ROOT;\n \n // API Testing\n } else if (selectedFramework === \"supertest\" || selectedFramework === \"pactum\") {\n cmd = \"npm\";\n args = [\"test\"];\n cwd = PROJECT_ROOT;\n \n // Fallback\n } else {\n cmd = \"npm\";\n args = [\"test\"];\n cwd = PROJECT_ROOT;\n }\n\n const startTime = Date.now();\n return new Promise((resolve) => {\n const child = spawn(cmd, args, {\n cwd,\n stdio: [\"inherit\", \"pipe\", \"pipe\"],\n shell: process.platform === \"win32\",\n env: { ...process.env },\n });\n\n let stdout = \"\";\n let stderr = \"\";\n if (child.stdout) {\n child.stdout.on(\"data\", (d) => {\n const s = d.toString();\n stdout += s;\n process.stdout.write(s);\n });\n }\n if (child.stderr) {\n child.stderr.on(\"data\", (d) => {\n const s = d.toString();\n stderr += s;\n process.stderr.write(s);\n });\n }\n\n child.on(\"close\", (code) => {\n const runOutput = [stdout, stderr].filter(Boolean).join(\"\\n\").trim();\n const passed = code === 0;\n const durationSeconds = Math.round((Date.now() - startTime) / 1000);\n if (!passed && runOutput) {\n try {\n fs.writeFileSync(path.join(PROJECT_ROOT, \".qa-lab-last-failure.log\"), runOutput, \"utf8\");\n } catch {}\n }\n const { passed: p, failed: f } = parseTestRunResult(runOutput, code);\n appendMetricsEvent({\n type: \"test_run\",\n framework: selectedFramework,\n spec: spec || undefined,\n passed: p,\n failed: f,\n durationSeconds,\n exitCode: code ?? 1,\n failures: !passed ? extractFailuresFromOutput(runOutput) : undefined,\n });\n if (passed) saveProjectMemory({ lastRun: { spec: spec || null, framework: selectedFramework, passed: p } });\n resolve({\n content: [{ type: \"text\", text: passed ? \"Testes executados com sucesso.\" : \"Falha na execução dos testes.\" }],\n structuredContent: {\n status: passed ? \"passed\" : \"failed\",\n message: passed ? \"Tests passed\" : \"Tests failed\",\n exitCode: code ?? 1,\n runOutput: !passed ? runOutput : undefined,\n },\n });\n });\n });\n }\n);\n\nserver.registerTool(\n \"read_project\",\n {\n title: \"Ler estrutura do projeto\",\n description: \"Lê package.json, specs existentes (qualquer framework: Cypress, Playwright, WDIO, Robot, pytest, etc) e retorna contexto. Use includeContent para trazer código de exemplos.\",\n inputSchema: z.object({\n includeContent: z.boolean().optional().describe(\"Se true, inclui conteúdo dos primeiros 3 arquivos de teste como referência. Default: false.\"),\n maxFiles: z.number().optional().describe(\"Máximo de arquivos cujo conteúdo será lido. Default: 3.\"),\n }),\n outputSchema: z.object({\n ok: z.boolean(),\n summary: z.string(),\n packageJson: z.object({}).passthrough().optional(),\n testFiles: z.array(z.string()).optional(),\n testFilesWithContent: z.array(z.object({ path: z.string(), content: z.string() })).optional(),\n }),\n },\n async ({ includeContent = false, maxFiles = 3 } = {}) => {\n const structure = detectProjectStructure();\n const collected = collectTestFiles(structure, {\n maxContentFiles: includeContent ? maxFiles : 0,\n });\n\n const testFiles = collected.map((e) => e.path);\n const testFilesWithContent = includeContent\n ? collected.filter((e) => e.content).map((e) => ({ path: e.path, content: e.content }))\n : undefined;\n\n const summary = [\n `Frameworks: ${structure.testFrameworks.join(\", \") || \"nenhum\"}`,\n `Arquivos de teste: ${testFiles.length} (qualquer framework)`,\n `Backend: ${structure.backendDir || \"não detectado\"}`,\n `Frontend: ${structure.frontendDir || \"não detectado\"}`,\n includeContent && testFilesWithContent?.length\n ? `Conteúdo incluído: ${testFilesWithContent.length} arquivo(s) como referência`\n : \"\",\n ]\n .filter(Boolean)\n .join(\"\\n\");\n\n return {\n content: [{ type: \"text\", text: summary }],\n structuredContent: {\n ok: true,\n summary,\n packageJson: structure.packageJson,\n testFiles: testFiles.slice(0, 100),\n testFilesWithContent,\n structure,\n },\n };\n }\n);\n\nserver.registerTool(\n \"generate_tests\",\n {\n title: \"Gerar ou traduzir testes com LLM\",\n description: \"Gera spec em QUALQUER framework. Aceita referência de outro framework: leia com read_file e passe em referenceCode. Traduz automaticamente (ex: Robot→Playwright, Cypress→WDIO).\",\n inputSchema: z.object({\n context: z.string().describe(\"Contexto do projeto (read_project) ou descrição.\"),\n request: z.string().describe(\"O que testar (ex: 'logout flow', 'teste de login') ou 'traduzir o teste abaixo'.\"),\n framework: z.enum([\n \"cypress\", \"playwright\", \"webdriverio\", \"jest\", \"vitest\", \"mocha\",\n \"appium\", \"robot\", \"pytest\", \"supertest\", \"behave\", \"detox\"\n ]).optional().describe(\"Framework alvo (detectado do projeto se omitido).\"),\n referenceCode: z.string().optional().describe(\"Código de referência em QUALQUER framework (Cypress, Robot, WDIO, etc). O LLM traduz/adapta para o framework alvo.\"),\n referencePaths: z.array(z.string()).optional().describe(\"Caminhos de arquivos para ler como referência. O agente lê e usa como padrão.\"),\n }),\n outputSchema: z.object({\n ok: z.boolean(),\n specContent: z.string().optional(),\n suggestedFileName: z.string().optional(),\n error: z.string().optional(),\n }),\n },\n async ({ context, request, framework, referenceCode, referencePaths }) => {\n const structure = detectProjectStructure();\n const fw = framework || structure.testFrameworks[0] || \"cypress\";\n\n let referenceBlock = \"\";\n if (referenceCode) referenceBlock += `\\n\\n--- CÓDIGO DE REFERÊNCIA (use como padrão, traduza/adapte para ${fw}) ---\\n${referenceCode.slice(0, 8000)}`;\n if (referencePaths?.length) {\n for (const p of referencePaths.slice(0, 5)) {\n const full = path.join(PROJECT_ROOT, p.replace(/^\\//, \"\").replace(/\\\\/g, \"/\"));\n if (fs.existsSync(full)) {\n try {\n const content = fs.readFileSync(full, \"utf8\");\n referenceBlock += `\\n\\n--- Arquivo: ${p} ---\\n${content.slice(0, 6000)}`;\n } catch {}\n }\n }\n }\n\n const llm = resolveLLMProvider(\"simple\");\n if (!llm.apiKey) {\n return {\n content: [{ type: \"text\", text: \"Configure GROQ_API_KEY, GEMINI_API_KEY ou OPENAI_API_KEY no .env\" }],\n structuredContent: { ok: false, error: \"No API key configured\" },\n };\n }\n const { provider, apiKey, baseUrl, model } = llm;\n\n const memory = loadProjectMemory();\n const memoryBlock = memory.flows?.length\n ? `\\n\\nFluxos do projeto (use como referência): ${memory.flows.map((f) => f.name || f.id).join(\", \")}`\n : \"\";\n const contextWithMemory = context + memoryBlock;\n\n const hasReference = Boolean(referenceBlock?.trim());\n const systemPrompt = hasReference\n ? `Você é um engenheiro de QA. TRADUZA/ADAPTE o código de referência para o framework ${fw}.\nO código de referência pode estar em QUALQUER framework (Cypress, Robot, Playwright, WDIO, Appium, pytest, etc).\n- Mantenha a MESMA lógica e fluxo de teste\n- Traduza seletores, comandos e asserções para ${fw}\n- Use Page Objects se o projeto já usa\n- Retorne SOMENTE o código, sem markdown`\n : `Você é um engenheiro de QA especializado em ${fw}. Gere APENAS o código do spec, sem explicações.\nFramework: ${fw}\nRegras:\n- Cypress: cy.request(), cy.visit(), cy.get()\n- Playwright: test(), test.describe(), page.goto(), page.locator()\n- WebdriverIO/Appium: describe(), it(), $(), browser.$\n- Jest/Vitest: describe(), test(), expect()\n- Robot: Keywords, [Tags], Steps\n- pytest: def test_*, assert, fixtures\n- Código limpo. Retorne SOMENTE o código, sem markdown`;\n\n const userPrompt = `Contexto do projeto:\n${contextWithMemory.slice(0, 5000)}\n\nGere um teste para: ${request}\nFramework alvo: ${fw}${referenceBlock}`;\n\n try {\n let specContent;\n if (provider === \"gemini\") {\n const url = `${baseUrl}/models/${model}:generateContent?key=${apiKey}`;\n const res = await fetch(url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n systemInstruction: { parts: [{ text: systemPrompt }] },\n contents: [{ parts: [{ text: userPrompt }] }],\n generationConfig: { temperature: 0.3, maxOutputTokens: 4096 },\n }),\n });\n const data = await res.json();\n specContent = data.candidates?.[0]?.content?.parts?.[0]?.text || \"\";\n } else {\n const res = await fetch(`${baseUrl}/chat/completions`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${apiKey}`,\n },\n body: JSON.stringify({\n model,\n messages: [\n { role: \"system\", content: systemPrompt },\n { role: \"user\", content: userPrompt },\n ],\n temperature: 0.3,\n max_tokens: 4096,\n }),\n });\n const data = await res.json();\n specContent = data.choices?.[0]?.message?.content || \"\";\n }\n\n specContent = specContent.replace(/^```(?:js|javascript)?\\n?/i, \"\").replace(/\\n?```\\s*$/i, \"\").trim();\n const fileName = request.toLowerCase().replace(/\\s+/g, \"-\").replace(/[^a-z0-9-]/g, \"\").slice(0, 40);\n\n return {\n content: [{ type: \"text\", text: `Spec gerado (${specContent.length} chars). Use write_test para gravar.` }],\n structuredContent: {\n ok: true,\n specContent,\n suggestedFileName: fileName,\n },\n };\n } catch (err) {\n return {\n content: [{ type: \"text\", text: `Erro ao gerar: ${err.message}` }],\n structuredContent: { ok: false, error: err.message },\n };\n }\n }\n);\n\nfunction getExtensionAndBaseDir(fw, structure) {\n const extMap = {\n cypress: \".cy.js\",\n playwright: \".spec.js\",\n jest: \".test.js\",\n vitest: \".test.js\",\n mocha: \".test.js\",\n webdriverio: \".spec.js\",\n appium: \".spec.js\",\n detox: \".e2e.js\",\n robot: \".robot\",\n pytest: \"_test.py\",\n behave: \".feature\",\n supertest: \".test.js\",\n pactum: \".test.js\",\n };\n const ext = extMap[fw] || \".spec.js\";\n\n const baseMap = {\n cypress: structure.testDirs.includes(\"cypress\") ? \"cypress\" : structure.testDirs[0] || \"tests\",\n playwright: structure.testDirs.includes(\"playwright\") ? \"playwright\" : structure.testDirs[0] || \"tests\",\n webdriverio: structure.testDirs.includes(\"specs\") ? \"specs\" : structure.testDirs[0] || \"tests\",\n appium: structure.testDirs.includes(\"specs\") ? \"specs\" : structure.testDirs[0] || \"tests\",\n robot: structure.testDirs.includes(\"robot\") ? \"robot\" : structure.testDirs[0] || \"tests\",\n behave: structure.testDirs.includes(\"features\") ? \"features\" : structure.testDirs[0] || \"tests\",\n };\n const baseDir = path.join(PROJECT_ROOT, baseMap[fw] || structure.testDirs[0] || \"tests\");\n return { ext, baseDir };\n}\n\nserver.registerTool(\n \"write_test\",\n {\n title: \"Escrever arquivo de teste\",\n description: \"Grava spec no disco. Suporta QUALQUER framework (Cypress, Playwright, WDIO, Appium, Robot, pytest, etc.). Detecta automaticamente pasta e extensão.\",\n inputSchema: z.object({\n name: z.string().describe(\"Nome do arquivo (ex: login-test, logout_spec).\"),\n content: z.string().describe(\"Conteúdo do spec.\"),\n framework: z.enum([\n \"cypress\", \"playwright\", \"jest\", \"vitest\", \"mocha\", \"webdriverio\",\n \"appium\", \"detox\", \"robot\", \"pytest\", \"behave\", \"supertest\"\n ]).optional().describe(\"Framework (detectado automaticamente se omitido).\"),\n subdir: z.string().optional().describe(\"Subpasta (ex: e2e, api). Default: raiz da pasta de testes.\"),\n }),\n outputSchema: z.object({\n ok: z.boolean(),\n path: z.string().optional(),\n error: z.string().optional(),\n }),\n },\n async ({ name, content, framework, subdir }) => {\n const structure = detectProjectStructure();\n const fw = framework || structure.testFrameworks[0];\n\n if (!fw) {\n return {\n content: [{ type: \"text\", text: \"Nenhum framework de teste detectado.\" }],\n structuredContent: { ok: false, error: \"No test framework\" },\n };\n }\n\n const { ext, baseDir } = getExtensionAndBaseDir(fw, structure);\n const safeName = name\n .replace(/[^a-z0-9-_]/gi, \"-\")\n .replace(/-+/g, \"-\")\n .replace(/_+/g, \"_\")\n .replace(/\\.(cy|spec|test|robot|feature|py)\\.?(js|ts|py)?$/i, \"\")\n .replace(/^[-_]+|[-_]+$/g, \"\");\n const fileName = ext.startsWith(\"_\") ? `${safeName}${ext}` : `${safeName}${ext}`;\n\n const targetDir = subdir ? path.join(baseDir, subdir) : baseDir;\n const filePath = path.join(targetDir, fileName);\n\n try {\n if (!fs.existsSync(targetDir)) {\n fs.mkdirSync(targetDir, { recursive: true });\n }\n fs.writeFileSync(filePath, content, \"utf8\");\n return {\n content: [{ type: \"text\", text: `Arquivo gravado: ${filePath}` }],\n structuredContent: { ok: true, path: filePath },\n };\n } catch (err) {\n return {\n content: [{ type: \"text\", text: `Erro ao gravar: ${err.message}` }],\n structuredContent: { ok: false, error: err.message },\n };\n }\n }\n);\n\nserver.registerTool(\n \"analyze_failures\",\n {\n title: \"Analisar falhas de testes\",\n description: \"Recebe output de testes e extrai falhas estruturadas.\",\n inputSchema: z.object({\n runOutput: z.string().describe(\"Output do teste (stdout/stderr).\"),\n }),\n outputSchema: z.object({\n ok: z.boolean(),\n summary: z.string(),\n failures: z.array(z.object({\n test: z.string().optional(),\n message: z.string().optional(),\n stack: z.string().optional(),\n })).optional(),\n }),\n },\n async ({ runOutput }) => {\n const failures = [];\n const lines = runOutput.split(\"\\n\");\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n if (/fail|error|assertion/i.test(line)) {\n failures.push({\n test: lines[i - 1] || \"unknown\",\n message: line.trim(),\n stack: lines.slice(i, i + 5).join(\"\\n\"),\n });\n }\n }\n\n const flakyAnalysis = detectFlakyPatterns(runOutput);\n let summary = failures.length\n ? `${failures.length} falha(s) detectada(s).`\n : \"Nenhuma falha detectada.\";\n if (flakyAnalysis.isLikelyFlaky) {\n summary += `\\n\\n⚠️ Possível teste flaky (${Math.round(flakyAnalysis.confidence * 100)}% confiança). Padrões: ${flakyAnalysis.patterns.map((p) => p.pattern).join(\", \")}.`;\n summary += \"\\n\\nSugestões:\";\n flakyAnalysis.patterns.forEach((p) => {\n summary += `\\n• ${p.pattern}: ${p.suggestion}`;\n });\n if (flakyAnalysis.patterns.some((p) => p.pattern === \"timing\" || p.pattern === \"network\")) {\n summary += \"\\n• Considere adicionar test.retry(2) ou equivalente para retries automáticos.\";\n }\n }\n\n return {\n content: [{ type: \"text\", text: summary }],\n structuredContent: {\n ok: true,\n summary,\n failures: failures.length ? failures : undefined,\n flaky: flakyAnalysis.isLikelyFlaky ? { confidence: flakyAnalysis.confidence, patterns: flakyAnalysis.patterns } : undefined,\n },\n };\n }\n);\n\n// ============================================================================\n// POR QUE FALHOU? - Explicação de falhas para juniores (escalável)\n// ============================================================================\n\nfunction formatFailureExplanation(data) {\n const lines = [\n \"## O que aconteceu\",\n \"\",\n data.oQueAconteceu || \"\",\n \"\",\n \"## Por que provavelmente falhou\",\n \"\",\n ...(Array.isArray(data.porQueProvavelmenteFalhou)\n ? data.porQueProvavelmenteFalhou.map((s) => `• ${s}`)\n : [data.porQueProvavelmenteFalhou || \"\"]),\n \"\",\n \"## O que fazer agora\",\n \"\",\n ...(Array.isArray(data.oQueFazerAgora)\n ? data.oQueFazerAgora.map((s, i) => `${i + 1}. ${s}`)\n : [data.oQueFazerAgora || \"\"]),\n ];\n if (data.sugestaoCorrecao) {\n lines.push(\"\", \"## Sugestão de correção\", \"\", \"```\" + (data.framework || \"js\"), data.sugestaoCorrecao, \"```\");\n }\n if (data.conceito) {\n lines.push(\"\", \"## Conceito\", \"\", data.conceito);\n }\n return lines.filter(Boolean).join(\"\\n\");\n}\n\nasync function callLlmForExplanation(provider, apiKey, baseUrl, model, systemPrompt, userPrompt) {\n if (provider === \"gemini\") {\n const url = `${baseUrl}/models/${model}:generateContent?key=${apiKey}`;\n const res = await fetch(url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n contents: [{ parts: [{ text: systemPrompt + \"\\n\\n\" + userPrompt }] }],\n generationConfig: { temperature: 0.2, maxOutputTokens: 4096 },\n }),\n });\n const data = await res.json();\n return data.candidates?.[0]?.content?.parts?.[0]?.text || \"\";\n }\n const res = await fetch(`${baseUrl}/chat/completions`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${apiKey}`,\n },\n body: JSON.stringify({\n model,\n messages: [\n { role: \"system\", content: systemPrompt },\n { role: \"user\", content: userPrompt },\n ],\n temperature: 0.2,\n max_tokens: 4096,\n }),\n });\n const data = await res.json();\n return data.choices?.[0]?.message?.content || \"\";\n}\n\n/** Gera explicação de falha (o que aconteceu, por que, o que fazer, sugestão). Usado por por_que_falhou e run_tests_and_explain. */\nasync function generateFailureExplanation(resolvedOutput, testFilePath = null) {\n const structure = detectProjectStructure();\n const fw = structure.testFrameworks[0] || \"unknown\";\n\n let testCode = \"\";\n if (testFilePath) {\n const normalized = testFilePath.replace(/^\\//, \"\").replace(/\\\\/g, \"/\");\n const fullPath = path.join(PROJECT_ROOT, normalized);\n if (fs.existsSync(fullPath) && !fs.statSync(fullPath).isDirectory()) {\n try {\n testCode = fs.readFileSync(fullPath, \"utf8\");\n } catch {}\n }\n }\n\n const llm = resolveLLMProvider(\"complex\");\n if (!llm.apiKey) {\n return { ok: false, error: \"No API key\", formattedText: null };\n }\n const { provider, apiKey, baseUrl, model } = llm;\n\n const fwHints = {\n webdriverio: \"WebdriverIO (describe/it, $, browser.$)\",\n appium: \"Appium/WebdriverIO (mobile, $, browser.$)\",\n playwright: \"Playwright (test, page, locator)\",\n cypress: \"Cypress (cy.get, cy.click)\",\n jest: \"Jest (describe, test, expect)\",\n vitest: \"Vitest (describe, test, expect)\",\n robot: \"Robot Framework\",\n pytest: \"pytest\",\n };\n\n const systemPrompt = `Você é um mentor de QA. Analise o output de falha e responda em JSON (apenas o JSON, sem markdown) com as chaves:\n- oQueAconteceu: string (explicação em português do que aconteceu, simples)\n- porQueProvavelmenteFalhou: array de strings (lista de possíveis causas, uma por item)\n- oQueFazerAgora: array de strings (passos numerados do que fazer)\n- sugestaoCorrecao: string ou null (código de correção se aplicável, no formato do framework)\n- conceito: string ou null (ex: \"Flaky test = teste intermitente. Geralmente por timing ou seletores frágeis.\")\n- framework: string (framework do projeto)\n\nFramework do projeto: ${fw}. ${fwHints[fw] || \"\"}\nResponda APENAS com o JSON válido, sem texto antes ou depois.`;\n\n const userPrompt = `Output do terminal/log (teste falhou):\n---\n${resolvedOutput.slice(0, 12000)}\n---\n${testCode ? `\\nCódigo do teste que falhou:\\n---\\n${testCode.slice(0, 6000)}\\n---` : \"\"}`;\n\n try {\n let raw = await callLlmForExplanation(provider, apiKey, baseUrl, model, systemPrompt, userPrompt);\n raw = raw.replace(/^```(?:json)?\\s*/i, \"\").replace(/\\s*```\\s*$/i, \"\").trim();\n let data = {};\n try {\n data = JSON.parse(raw);\n } catch {\n data = {\n oQueAconteceu: raw.slice(0, 500) || \"Não foi possível parsear a resposta.\",\n porQueProvavelmenteFalhou: [],\n oQueFazerAgora: [],\n sugestaoCorrecao: null,\n conceito: null,\n framework: fw,\n };\n }\n data.framework = data.framework || fw;\n if (testFilePath && data.sugestaoCorrecao) {\n saveProjectMemory({ patterns: { [testFilePath]: { lastFix: data.sugestaoCorrecao?.slice(0, 500) } } });\n }\n const formattedText = formatFailureExplanation(data);\n return { ok: true, formattedText, structuredContent: data };\n } catch (err) {\n return { ok: false, error: err.message, formattedText: null };\n }\n}\n\nserver.registerTool(\n \"por_que_falhou\",\n {\n title: \"Por que falhou? Explicação para juniores\",\n description: \"Traduz stack trace em explicação humana. Recebe output do terminal/log, lê o projeto e o teste (se path dado), e retorna: O que aconteceu, Por que falhou, O que fazer, Sugestão de correção, Conceito. Escalável e procedural.\",\n inputSchema: z.object({\n errorOutput: z.string().optional().describe(\"Output do terminal quando o teste falhou. Se vazio, lê automaticamente de .qa-lab-last-failure.log (capturado pelo run_tests). Cole aqui ou deixe vazio para usar última falha.\"),\n testFilePath: z.string().optional().describe(\"Caminho do arquivo de teste que falhou (ex: specs/login.spec.js). Se informado, o agente lê o código e dá sugestão mais precisa.\"),\n }),\n outputSchema: z.object({\n ok: z.boolean(),\n oQueAconteceu: z.string().optional(),\n porQueProvavelmenteFalhou: z.array(z.string()).optional(),\n oQueFazerAgora: z.array(z.string()).optional(),\n sugestaoCorrecao: z.string().optional(),\n conceito: z.string().optional(),\n framework: z.string().optional(),\n formattedText: z.string().optional(),\n error: z.string().optional(),\n }),\n },\n async ({ errorOutput, testFilePath }) => {\n const structure = detectProjectStructure();\n const fw = structure.testFrameworks[0] || \"unknown\";\n\n let resolvedOutput = errorOutput?.trim() || \"\";\n if (!resolvedOutput) {\n const lastFailurePath = path.join(PROJECT_ROOT, \".qa-lab-last-failure.log\");\n if (fs.existsSync(lastFailurePath)) {\n try {\n resolvedOutput = fs.readFileSync(lastFailurePath, \"utf8\");\n } catch {}\n }\n }\n if (!resolvedOutput) {\n return {\n content: [{\n type: \"text\",\n text: \"Nenhum output de erro fornecido e nenhuma falha recente capturada.\\n\\nComo usar:\\n1. Rode os testes (run_tests) – se falhar, a saída é salva automaticamente.\\n2. Ou cole aqui o output do terminal quando o teste falhou.\\n3. Depois peça: 'Por que falhou?' ou chame por_que_falhou.\",\n }],\n structuredContent: { ok: false, error: \"No error output\" },\n };\n }\n\n let testCode = \"\";\n if (testFilePath) {\n const normalized = testFilePath.replace(/^\\//, \"\").replace(/\\\\/g, \"/\");\n const fullPath = path.join(PROJECT_ROOT, normalized);\n if (fs.existsSync(fullPath) && !fs.statSync(fullPath).isDirectory()) {\n try {\n testCode = fs.readFileSync(fullPath, \"utf8\");\n } catch {}\n }\n }\n\n const llm = resolveLLMProvider(\"complex\");\n if (!llm.apiKey) {\n return {\n content: [{\n type: \"text\",\n text: \"Configure GROQ_API_KEY, GEMINI_API_KEY ou OPENAI_API_KEY no .env do projeto para usar a explicação com LLM.\",\n }],\n structuredContent: { ok: false, error: \"No API key configured\" },\n };\n }\n const { provider, apiKey, baseUrl, model } = llm;\n\n const fwHints = {\n webdriverio: \"WebdriverIO (describe/it, $, browser.$)\",\n appium: \"Appium/WebdriverIO (mobile, $, browser.$)\",\n playwright: \"Playwright (test, page, locator)\",\n cypress: \"Cypress (cy.get, cy.click)\",\n jest: \"Jest (describe, test, expect)\",\n vitest: \"Vitest (describe, test, expect)\",\n robot: \"Robot Framework\",\n pytest: \"pytest\",\n };\n\n const systemPrompt = `Você é um mentor de QA. Analise o output de falha e responda em JSON (apenas o JSON, sem markdown) com as chaves:\n- oQueAconteceu: string (explicação em português do que aconteceu, simples)\n- porQueProvavelmenteFalhou: array de strings (lista de possíveis causas, uma por item)\n- oQueFazerAgora: array de strings (passos numerados do que fazer)\n- sugestaoCorrecao: string ou null (código de correção se aplicável, no formato do framework)\n- conceito: string ou null (ex: \"Flaky test = teste intermitente. Geralmente por timing ou seletores frágeis.\")\n- framework: string (framework do projeto)\n\nFramework do projeto: ${fw}. ${fwHints[fw] || \"\"}\nResponda APENAS com o JSON válido, sem texto antes ou depois.`;\n\n const userPrompt = `Output do terminal/log (teste falhou):\n---\n${resolvedOutput.slice(0, 12000)}\n---\n${testCode ? `\\nCódigo do teste que falhou:\\n---\\n${testCode.slice(0, 6000)}\\n---` : \"\"}`;\n\n try {\n let raw = await callLlmForExplanation(provider, apiKey, baseUrl, model, systemPrompt, userPrompt);\n raw = raw.replace(/^```(?:json)?\\s*/i, \"\").replace(/\\s*```\\s*$/i, \"\").trim();\n\n let data = {};\n try {\n data = JSON.parse(raw);\n } catch {\n data = {\n oQueAconteceu: raw.slice(0, 500) || \"Não foi possível parsear a resposta.\",\n porQueProvavelmenteFalhou: [],\n oQueFazerAgora: [],\n sugestaoCorrecao: null,\n conceito: null,\n framework: fw,\n };\n }\n\n data.framework = data.framework || fw;\n const formattedText = formatFailureExplanation(data);\n\n return {\n content: [{ type: \"text\", text: formattedText }],\n structuredContent: {\n ok: true,\n oQueAconteceu: data.oQueAconteceu,\n porQueProvavelmenteFalhou: data.porQueProvavelmenteFalhou,\n oQueFazerAgora: data.oQueFazerAgora,\n sugestaoCorrecao: data.sugestaoCorrecao ?? null,\n conceito: data.conceito ?? null,\n framework: data.framework,\n formattedText,\n },\n };\n } catch (err) {\n return {\n content: [{ type: \"text\", text: `Erro ao analisar: ${err.message}` }],\n structuredContent: { ok: false, error: err.message },\n };\n }\n }\n);\n\n// ============================================================================\n// NOVAS FERRAMENTAS\n// ============================================================================\n\nserver.registerTool(\n \"suggest_fix\",\n {\n title: \"Sugerir correção para falhas\",\n description: \"Recebe análise de falhas e sugere correções (patch, refactor, etc.).\",\n inputSchema: z.object({\n failures: z.array(z.object({\n test: z.string().optional(),\n message: z.string().optional(),\n stack: z.string().optional(),\n })).describe(\"Resultado de analyze_failures.\"),\n }),\n outputSchema: z.object({\n ok: z.boolean(),\n suggestions: z.array(z.object({\n test: z.string().optional(),\n description: z.string(),\n fix: z.string().optional(),\n })),\n }),\n },\n async ({ failures }) => {\n const suggestions = [];\n\n for (const f of failures) {\n const msg = f.message || \"\";\n \n if (/element not found|selector|timeout/i.test(msg)) {\n suggestions.push({\n test: f.test,\n description: \"Elemento não encontrado ou timeout\",\n fix: \"Verifique seletores, adicione waits ou aumente timeout. Use data-testid para seletores mais estáveis.\",\n });\n } else if (/expected.*to.*but/i.test(msg)) {\n suggestions.push({\n test: f.test,\n description: \"Asserção falhou\",\n fix: \"Revise o valor esperado. Verifique se o estado da aplicação está correto antes da asserção.\",\n });\n } else if (/network|fetch|ECONNREFUSED/i.test(msg)) {\n suggestions.push({\n test: f.test,\n description: \"Erro de rede ou API não disponível\",\n fix: \"Verifique se o backend está rodando. Confirme a URL e porta da API.\",\n });\n } else {\n suggestions.push({\n test: f.test,\n description: \"Falha detectada\",\n fix: \"Revise o stack trace e o código do teste.\",\n });\n }\n }\n\n return {\n content: [{ type: \"text\", text: JSON.stringify(suggestions, null, 2) }],\n structuredContent: { ok: true, suggestions },\n };\n }\n);\n\n// ============================================================================\n// SELF-HEALING - Sugestão de correção de seletores quando UI muda\n// ============================================================================\n\nserver.registerTool(\n \"suggest_selector_fix\",\n {\n title: \"Sugerir correção de seletor (Self-healing)\",\n description: \"Quando um teste falha por elemento não encontrado (seletor quebrado após mudança de UI), usa LLM para sugerir seletor alternativo mais resiliente. Prioriza data-testid, role, texto acessível.\",\n inputSchema: z.object({\n testFilePath: z.string().describe(\"Caminho do arquivo de teste que falhou (ex: specs/login.spec.js).\"),\n errorOutput: z.string().optional().describe(\"Output do terminal da falha. Se vazio, lê de .qa-lab-last-failure.log.\"),\n framework: z.enum([\"cypress\", \"playwright\", \"webdriverio\", \"appium\"]).optional().describe(\"Framework do teste. Detectado automaticamente se omitido.\"),\n }),\n outputSchema: z.object({\n ok: z.boolean(),\n selectorSugerido: z.string().optional(),\n codigoCorrigido: z.string().optional(),\n explicacao: z.string().optional(),\n error: z.string().optional(),\n }),\n },\n async ({ testFilePath, errorOutput, framework }) => {\n const structure = detectProjectStructure();\n const fw = framework || inferFrameworkFromFile(testFilePath.split(\"/\").pop(), structure);\n\n let resolvedOutput = errorOutput;\n if (!resolvedOutput) {\n const logPath = path.join(PROJECT_ROOT, \".qa-lab-last-failure.log\");\n if (fs.existsSync(logPath)) {\n resolvedOutput = fs.readFileSync(logPath, \"utf8\");\n }\n }\n if (!resolvedOutput) {\n return {\n content: [{ type: \"text\", text: \"Nenhum output de erro. Rode os testes primeiro ou forneça errorOutput.\" }],\n structuredContent: { ok: false, error: \"No error output\" },\n };\n }\n\n if (!/element not found|selector|timeout|locator|cy\\.get|page\\.locator/i.test(resolvedOutput)) {\n return {\n content: [{ type: \"text\", text: \"A falha não parece ser de seletor/elemento. Use por_que_falhou ou suggest_fix para outros tipos de falha.\" }],\n structuredContent: { ok: false, error: \"Not a selector-related failure\" },\n };\n }\n\n let testCode = \"\";\n const fullPath = path.join(PROJECT_ROOT, testFilePath.replace(/^\\//, \"\").replace(/\\\\/g, \"/\"));\n if (fs.existsSync(fullPath)) {\n try {\n testCode = fs.readFileSync(fullPath, \"utf8\");\n } catch {}\n }\n\n const llm = resolveLLMProvider(\"complex\");\n if (!llm.apiKey) {\n return {\n content: [{ type: \"text\", text: \"Configure GROQ_API_KEY, GEMINI_API_KEY ou OPENAI_API_KEY no .env\" }],\n structuredContent: { ok: false, error: \"No API key configured\" },\n };\n }\n const { provider, apiKey, baseUrl, model } = llm;\n\n const fwHints = {\n cypress: \"Cypress: cy.get('[data-testid=...]'), cy.contains(), cy.get('button').filter(':visible')\",\n playwright: \"Playwright: page.getByRole(), page.getByTestId(), page.locator('button:has-text(\\\"...\\\")')\",\n webdriverio: \"WebdriverIO: $('[data-testid=...]'), $('button=Texto')\",\n appium: \"Appium: $('~accessibility-id'), $('//android.view.View')\",\n };\n\n const systemPrompt = `Você é um especialista em testes E2E. O teste falhou porque um seletor não encontrou o elemento (UI mudou).\nAnalise o erro e o código e responda APENAS em JSON (sem markdown) com as chaves:\n- selectorSugerido: string (o novo seletor recomendado, mais resiliente)\n- codigoCorrigido: string (bloco de código completo corrigido, apenas a parte relevante do teste)\n- explicacao: string (breve explicação em português: por que o antigo falhou e por que o novo é melhor)\n\nPriorize nesta ordem: data-testid > role + accessible name > texto visível > estrutura. Evite classes CSS e IDs que mudam.\n\nFramework: ${fw}. ${fwHints[fw] || \"\"}`;\n\n const userPrompt = `Output do erro:\n---\n${resolvedOutput.slice(0, 8000)}\n---\nCódigo do teste:\n---\n${testCode ? testCode.slice(0, 6000) : \"Não disponível\"}\n---`;\n\n try {\n let raw = await callLlmForExplanation(provider, apiKey, baseUrl, model, systemPrompt, userPrompt);\n raw = raw.replace(/^```(?:json)?\\s*/i, \"\").replace(/\\s*```\\s*$/i, \"\").trim();\n let data = {};\n try {\n data = JSON.parse(raw);\n } catch {\n data = {\n selectorSugerido: null,\n codigoCorrigido: raw.slice(0, 2000),\n explicacao: \"Não foi possível parsear. Resposta do LLM acima.\",\n };\n }\n\n const text = [\n data.explicacao && `## Explicação\\n${data.explicacao}`,\n data.selectorSugerido && `## Seletor sugerido\\n\\`${data.selectorSugerido}\\``,\n data.codigoCorrigido && `## Código corrigido\\n\\`\\`\\`${fw}\\n${data.codigoCorrigido}\\n\\`\\`\\``,\n ]\n .filter(Boolean)\n .join(\"\\n\\n\");\n\n return {\n content: [{ type: \"text\", text: text || JSON.stringify(data, null, 2) }],\n structuredContent: {\n ok: true,\n selectorSugerido: data.selectorSugerido,\n codigoCorrigido: data.codigoCorrigido,\n explicacao: data.explicacao,\n },\n };\n } catch (err) {\n return {\n content: [{ type: \"text\", text: `Erro ao chamar LLM: ${err.message}` }],\n structuredContent: { ok: false, error: err.message },\n };\n }\n }\n);\n\nserver.registerTool(\n \"analyze_file_methods\",\n {\n title: \"Analisar métodos de um arquivo\",\n description: \"Lê um arquivo, faz varredura em todos os métodos/funções e retorna análise detalhada: método correto?, melhor forma de escrever?, falso positivo?, coerência?, itens faltando?, parâmetros faltando?, imports faltando?. Requer API key (Groq/Gemini/OpenAI).\",\n inputSchema: z.object({\n path: z.string().describe(\"Caminho do arquivo (ex: src/utils.js, tests/login.cy.js, cypress/support/commands.js).\"),\n }),\n outputSchema: z.object({\n ok: z.boolean(),\n filePath: z.string().optional(),\n methods: z.array(z.object({\n name: z.string(),\n correto: z.boolean().optional(),\n melhorForma: z.string().optional(),\n falsoPositivo: z.boolean().optional(),\n falsoPositivoRazao: z.string().optional(),\n coerente: z.boolean().optional(),\n itensFaltando: z.array(z.string()).optional(),\n parametrosFaltando: z.array(z.string()).optional(),\n importsFaltando: z.array(z.string()).optional(),\n sugestao: z.string().optional(),\n })).optional(),\n importsFaltandoGlobal: z.array(z.string()).optional(),\n resumo: z.string().optional(),\n error: z.string().optional(),\n }),\n },\n async ({ path: filePath }) => {\n const normalized = filePath.replace(/^\\//, \"\").replace(/\\\\/g, \"/\");\n const fullPath = path.join(PROJECT_ROOT, normalized);\n\n if (!fullPath.startsWith(PROJECT_ROOT)) {\n return {\n content: [{ type: \"text\", text: \"Caminho fora do projeto.\" }],\n structuredContent: { ok: false, error: \"Path outside project\" },\n };\n }\n if (!fs.existsSync(fullPath)) {\n return {\n content: [{ type: \"text\", text: `Arquivo não encontrado: ${normalized}` }],\n structuredContent: { ok: false, error: \"File not found\" },\n };\n }\n const stat = fs.statSync(fullPath);\n if (stat.isDirectory()) {\n return {\n content: [{ type: \"text\", text: \"É um diretório. Informe um arquivo.\" }],\n structuredContent: { ok: false, error: \"Is directory\" },\n };\n }\n\n let fileContent = \"\";\n try {\n fileContent = fs.readFileSync(fullPath, \"utf8\");\n } catch (err) {\n return {\n content: [{ type: \"text\", text: `Erro ao ler: ${err.message}` }],\n structuredContent: { ok: false, error: err.message },\n };\n }\n\n const llm = resolveLLMProvider(\"complex\");\n if (!llm.apiKey) {\n return {\n content: [{\n type: \"text\",\n text: \"Configure GROQ_API_KEY, GEMINI_API_KEY ou OPENAI_API_KEY no .env para usar análise com LLM.\",\n }],\n structuredContent: { ok: false, error: \"No API key configured\" },\n };\n }\n const { provider, apiKey, baseUrl, model } = llm;\n\n const ext = path.extname(fullPath).toLowerCase();\n const lang = [\".ts\", \".tsx\"].includes(ext) ? \"TypeScript\" : [\".js\", \".jsx\"].includes(ext) ? \"JavaScript\" : [\".py\"].includes(ext) ? \"Python\" : \"código\";\n\n const systemPrompt = `Você é um revisor de código experiente em QA e testes. Analise o arquivo e cada método/função, respondendo em JSON válido (sem markdown) com a estrutura:\n\n{\n \"methods\": [\n {\n \"name\": \"nomeDoMetodo\",\n \"correto\": true | false,\n \"melhorForma\": \"explicação curta se há forma melhor de escrever\",\n \"falsoPositivo\": true | false,\n \"falsoPositivoRazao\": \"se falso positivo, por quê (ex: asserção muito permissiva)\",\n \"coerente\": true | false,\n \"coerenteDetalhe\": \"se incoerente, o que está inconsistente\",\n \"itensFaltando\": [\"item1\", \"item2\"],\n \"parametrosFaltando\": [\"param1\"],\n \"importsFaltando\": [\"moduloX\"],\n \"sugestao\": \"código ou texto de sugestão de melhoria\"\n }\n ],\n \"importsFaltandoGlobal\": [\"imports faltando no topo do arquivo\"],\n \"resumo\": \"resumo geral em 2-3 linhas\"\n}\n\nPara CADA método/função no arquivo, verifique:\n1. correto: a lógica está correta?\n2. melhorForma: há forma mais legível, performática ou idiomática de escrever?\n3. falsoPositivo: o método pode passar quando não deveria (asserção fraca, mock incorreto)?\n4. coerente: o método é coerente com o restante do código, naming, padrões?\n5. itensFaltando: falta try/catch, validação, cleanup, etc?\n6. parametrosFaltando: parâmetros que deveriam existir?\n7. importsFaltando: imports que o método usa mas não estão declarados?\n\nResponda APENAS com o JSON válido. Linguagem: ${lang}.`;\n\n const userPrompt = `Arquivo: ${normalized}\n\n\\`\\`\\`${lang}\n${fileContent.slice(0, 18000)}\n\\`\\`\\`\n\nAnalise cada método/função e retorne o JSON conforme especificado.`;\n\n try {\n let raw = await callLlmForExplanation(provider, apiKey, baseUrl, model, systemPrompt, userPrompt);\n raw = raw.replace(/^```(?:json)?\\s*/i, \"\").replace(/\\s*```\\s*$/i, \"\").trim();\n\n let data = {};\n try {\n data = JSON.parse(raw);\n } catch {\n data = {\n methods: [],\n importsFaltandoGlobal: [],\n resumo: raw.slice(0, 1000) || \"Não foi possível parsear a resposta do LLM.\",\n };\n }\n\n const lines = [\n `# Análise de métodos: ${normalized}`,\n \"\",\n data.resumo && `## Resumo\\n${data.resumo}`,\n data.importsFaltandoGlobal?.length > 0\n ? `\\n## Imports faltando (global)\\n${data.importsFaltandoGlobal.map((i) => `- ${i}`).join(\"\\n\")}`\n : \"\",\n \"\\n## Métodos analisados\\n\",\n ];\n\n for (const m of data.methods || []) {\n lines.push(`### ${m.name}`);\n lines.push(\"\");\n if (m.correto !== undefined) lines.push(`- **Correto:** ${m.correto ? \"✅ Sim\" : \"❌ Não\"}`);\n if (m.melhorForma) lines.push(`- **Melhor forma:** ${m.melhorForma}`);\n if (m.falsoPositivo) lines.push(`- **Falso positivo:** ⚠️ Sim - ${m.falsoPositivoRazao || \"verificar\"}`);\n if (m.coerente !== undefined) lines.push(`- **Coerente:** ${m.coerente ? \"✅ Sim\" : \"❌ Não\"}`);\n if (m.itensFaltando?.length) lines.push(`- **Itens faltando:** ${m.itensFaltando.join(\", \")}`);\n if (m.parametrosFaltando?.length) lines.push(`- **Parâmetros faltando:** ${m.parametrosFaltando.join(\", \")}`);\n if (m.importsFaltando?.length) lines.push(`- **Imports faltando:** ${m.importsFaltando.join(\", \")}`);\n if (m.sugestao) lines.push(`\\n**Sugestão:**\\n\\`\\`\\`\\n${m.sugestao}\\n\\`\\`\\``);\n lines.push(\"\");\n }\n\n const formattedText = lines.filter(Boolean).join(\"\\n\");\n\n return {\n content: [{ type: \"text\", text: formattedText }],\n structuredContent: {\n ok: true,\n filePath: normalized,\n methods: data.methods || [],\n importsFaltandoGlobal: data.importsFaltandoGlobal || [],\n resumo: data.resumo,\n },\n };\n } catch (err) {\n return {\n content: [{ type: \"text\", text: `Erro ao analisar: ${err.message}` }],\n structuredContent: { ok: false, error: err.message },\n };\n }\n }\n);\n\n\nserver.registerTool(\n \"create_bug_report\",\n {\n title: \"Criar relatório de bug\",\n description: \"Gera um bug report estruturado a partir de falhas de teste.\",\n inputSchema: z.object({\n failures: z.array(z.object({\n test: z.string().optional(),\n message: z.string().optional(),\n stack: z.string().optional(),\n })).describe(\"Falhas (de analyze_failures).\"),\n title: z.string().optional().describe(\"Título do bug.\"),\n }),\n outputSchema: z.object({\n ok: z.boolean(),\n report: z.string(),\n title: z.string(),\n }),\n },\n async ({ failures, title }) => {\n const bugTitle = title || `Falha em ${failures.length} teste(s)`;\n const lines = [\n `# ${bugTitle}`,\n \"\",\n \"## Resumo\",\n \"\",\n `${failures.length} teste(s) falharam durante a execução.`,\n \"\",\n \"## Falhas detectadas\",\n \"\",\n ];\n\n failures.forEach((f, i) => {\n lines.push(`### ${i + 1}. ${f.test || \"Teste desconhecido\"}`);\n lines.push(\"\");\n lines.push(`**Mensagem:** ${f.message || \"N/A\"}`);\n lines.push(\"\");\n if (f.stack) {\n lines.push(\"**Stack trace:**\");\n lines.push(\"```\");\n lines.push(f.stack);\n lines.push(\"```\");\n lines.push(\"\");\n }\n });\n\n lines.push(\"## Próximos passos\");\n lines.push(\"\");\n lines.push(\"- [ ] Reproduzir localmente\");\n lines.push(\"- [ ] Identificar causa raiz\");\n lines.push(\"- [ ] Aplicar correção\");\n lines.push(\"- [ ] Validar com testes\");\n\n const report = lines.join(\"\\n\");\n\n appendMetricsEvent({ type: \"bug_reported\", failuresCount: failures.length, title: bugTitle });\n\n return {\n content: [{ type: \"text\", text: report }],\n structuredContent: { ok: true, report, title: bugTitle },\n };\n }\n);\n\n// ============================================================================\n// MÉTRICAS DE NEGÓCIO - Relatório agregado\n// ============================================================================\n\nserver.registerTool(\n \"get_business_metrics\",\n {\n title: \"Obter métricas de negócio\",\n description: \"Retorna métricas: tempo até bug, custo por defeito (tempo estimado), cobertura por fluxo. Requer run_tests executados e opcionalmente qa-lab-flows.json.\",\n inputSchema: z.object({\n period: z.enum([\"7d\", \"30d\", \"all\"]).optional().describe(\"Período para analisar. Default: 30d.\"),\n }),\n outputSchema: z.object({\n ok: z.boolean(),\n timeToBug: z.object({\n avgHours: z.number(),\n lastFailureAt: z.string().optional(),\n runsWithFailures: z.number(),\n }).optional(),\n costPerDefect: z.object({\n avgMinutesPerDefect: z.number(),\n totalFailures: z.number(),\n estimatedHoursSpent: z.number(),\n }).optional(),\n flowCoverage: z.object({\n totalFlows: z.number(),\n coveredFlows: z.number(),\n percent: z.number(),\n details: z.array(z.object({ flow: z.string(), covered: z.boolean() })),\n }).optional(),\n summary: z.string(),\n }),\n },\n async ({ period = \"30d\" } = {}) => {\n const now = Date.now();\n const msByPeriod = { \"7d\": 7 * 24 * 60 * 60 * 1000, \"30d\": 30 * 24 * 60 * 60 * 1000, all: Infinity };\n const cutoff = now - msByPeriod[period];\n\n let data = { events: [] };\n if (fs.existsSync(METRICS_FILE)) {\n try {\n data = JSON.parse(fs.readFileSync(METRICS_FILE, \"utf8\"));\n } catch {}\n }\n\n const events = (data.events || []).filter((e) => new Date(e.timestamp).getTime() >= cutoff);\n\n const testRuns = events.filter((e) => e.type === \"test_run\");\n const failedRuns = testRuns.filter((e) => (e.failed || 0) > 0);\n const totalFailed = testRuns.reduce((sum, e) => sum + (e.failed || 0), 0);\n const totalDuration = testRuns.reduce((sum, e) => sum + (e.durationSeconds || 0), 0);\n\n let timeToBug = null;\n if (failedRuns.length > 0) {\n const lastFailure = failedRuns[failedRuns.length - 1];\n timeToBug = {\n avgHours: 0,\n lastFailureAt: lastFailure.timestamp,\n runsWithFailures: failedRuns.length,\n };\n if (failedRuns.length >= 2) {\n const deltas = [];\n for (let i = 1; i < failedRuns.length; i++) {\n const prev = new Date(failedRuns[i - 1].timestamp).getTime();\n const curr = new Date(failedRuns[i].timestamp).getTime();\n deltas.push((curr - prev) / (1000 * 60 * 60));\n }\n timeToBug.avgHours = deltas.reduce((a, b) => a + b, 0) / deltas.length;\n }\n }\n\n let costPerDefect = null;\n if (totalFailed > 0) {\n const estimatedMinutesSpent = totalDuration + totalFailed * 5;\n costPerDefect = {\n avgMinutesPerDefect: Math.round(estimatedMinutesSpent / totalFailed),\n totalFailures: totalFailed,\n estimatedHoursSpent: Math.round((estimatedMinutesSpent / 60) * 10) / 10,\n };\n }\n\n let flowCoverage = null;\n if (fs.existsSync(FLOWS_CONFIG_FILE)) {\n try {\n const flowsConfig = JSON.parse(fs.readFileSync(FLOWS_CONFIG_FILE, \"utf8\"));\n const flows = flowsConfig.flows || [];\n const structure = detectProjectStructure();\n const allTestFiles = new Set(collectTestFiles(structure).map((e) => e.path));\n\n const details = flows.map((f) => {\n const testFiles = f.testFiles || [];\n const covered = testFiles.some((tf) => allTestFiles.has(tf) || allTestFiles.has(tf.replace(/\\\\/g, \"/\")));\n return { flow: f.name || f.id || \"?\", covered };\n });\n\n flowCoverage = {\n totalFlows: flows.length,\n coveredFlows: details.filter((d) => d.covered).length,\n percent: flows.length ? Math.round((details.filter((d) => d.covered).length / flows.length) * 100) : 0,\n details,\n };\n } catch {}\n }\n\n const lines = [\n \"## Métricas de negócio\",\n \"\",\n `Período: ${period}`,\n \"\",\n timeToBug\n ? [\n \"### Tempo até bug\",\n `- Última falha: ${timeToBug.lastFailureAt || \"N/A\"}`,\n `- Execuções com falha: ${timeToBug.runsWithFailures}`,\n timeToBug.avgHours > 0 ? `- Média entre falhas: ${timeToBug.avgHours.toFixed(1)}h` : \"\",\n ]\n .filter(Boolean)\n .join(\"\\n\")\n : \"\",\n costPerDefect\n ? [\n \"### Custo por defeito (estimativa)\",\n `- Total de falhas: ${costPerDefect.totalFailures}`,\n `- Tempo médio por defeito: ~${costPerDefect.avgMinutesPerDefect} min`,\n `- Horas estimadas gastas: ${costPerDefect.estimatedHoursSpent}h`,\n ].join(\"\\n\")\n : \"\",\n flowCoverage\n ? [\n \"### Cobertura por fluxo\",\n `- Fluxos cobertos: ${flowCoverage.coveredFlows}/${flowCoverage.totalFlows} (${flowCoverage.percent}%)`,\n flowCoverage.details.map((d) => ` - ${d.flow}: ${d.covered ? \"✅\" : \"❌\"}`).join(\"\\n\"),\n ].join(\"\\n\")\n : \"\",\n ]\n .filter(Boolean)\n .join(\"\\n\\n\");\n\n if (!timeToBug && !costPerDefect && !flowCoverage) {\n const msg =\n \"Nenhuma métrica disponível. Rode run_tests para gerar dados. Para cobertura por fluxo, crie qa-lab-flows.json.\";\n return {\n content: [{ type: \"text\", text: msg }],\n structuredContent: { ok: false, summary: msg },\n };\n }\n\n const summary = [\n timeToBug && `${timeToBug.runsWithFailures} execuções com falha`,\n costPerDefect && `${costPerDefect.totalFailures} falhas (~${costPerDefect.avgMinutesPerDefect} min/defeito)`,\n flowCoverage && `${flowCoverage.coveredFlows}/${flowCoverage.totalFlows} fluxos cobertos`,\n ]\n .filter(Boolean)\n .join(\" | \");\n\n return {\n content: [{ type: \"text\", text: lines || summary }],\n structuredContent: {\n ok: true,\n timeToBug,\n costPerDefect,\n flowCoverage,\n summary,\n },\n };\n }\n);\n\nserver.registerTool(\n \"list_test_files\",\n {\n title: \"Listar arquivos de teste\",\n description: \"Lista TODOS os arquivos de teste (qualquer framework: Cypress, Playwright, WDIO, Robot, pytest, Behave, etc.) com filtro opcional.\",\n inputSchema: z.object({\n framework: z.enum([\n \"cypress\", \"playwright\", \"jest\", \"webdriverio\", \"appium\", \"robot\", \"pytest\", \"behave\", \"detox\", \"all\"\n ]).optional().describe(\"Filtrar por framework. Default: all.\"),\n pattern: z.string().optional().describe(\"Pattern para filtrar (ex: 'login', 'api').\"),\n }),\n outputSchema: z.object({\n ok: z.boolean(),\n files: z.array(z.string()),\n total: z.number(),\n }),\n },\n async ({ framework = \"all\", pattern } = {}) => {\n const structure = detectProjectStructure();\n const collected = collectTestFiles(structure, { framework, pattern });\n const allFiles = collected.map((e) => e.path);\n\n const summary = `Encontrados ${allFiles.length} arquivo(s) de teste (qualquer framework).`;\n\n return {\n content: [{ type: \"text\", text: `${summary}\\n\\n${allFiles.slice(0, 50).join(\"\\n\")}` }],\n structuredContent: { ok: true, files: allFiles, total: allFiles.length },\n };\n }\n);\n\nserver.registerTool(\n \"run_linter\",\n {\n title: \"Executar linter\",\n description: \"Roda ESLint, Prettier ou linter configurado no projeto.\",\n inputSchema: z.object({\n fix: z.boolean().optional().describe(\"Auto-fix (--fix). Default: false.\"),\n path: z.string().optional().describe(\"Caminho específico (ex: src/). Default: todo o projeto.\"),\n }),\n outputSchema: z.object({\n status: z.enum([\"passed\", \"failed\", \"not_found\"]),\n message: z.string(),\n exitCode: z.number(),\n output: z.string().optional(),\n }),\n },\n async ({ fix, path: targetPath }) => {\n const structure = detectProjectStructure();\n const scripts = structure.packageJson?.scripts || {};\n\n let cmd, args;\n if (scripts.lint) {\n cmd = \"npm\";\n args = [\"run\", \"lint\"];\n } else if (structure.packageJson?.devDependencies?.eslint || structure.packageJson?.dependencies?.eslint) {\n cmd = \"npx\";\n args = [\"eslint\", targetPath || \".\"];\n if (fix) args.push(\"--fix\");\n } else {\n return {\n content: [{ type: \"text\", text: \"Linter não detectado no projeto.\" }],\n structuredContent: { status: \"not_found\", message: \"No linter found\", exitCode: 1 },\n };\n }\n\n return new Promise((resolve) => {\n const child = spawn(cmd, args, {\n cwd: PROJECT_ROOT,\n stdio: [\"inherit\", \"pipe\", \"pipe\"],\n shell: process.platform === \"win32\",\n env: { ...process.env },\n });\n\n let stdout = \"\";\n let stderr = \"\";\n if (child.stdout) child.stdout.on(\"data\", (d) => { stdout += d.toString(); });\n if (child.stderr) child.stderr.on(\"data\", (d) => { stderr += d.toString(); });\n\n child.on(\"close\", (code) => {\n const output = [stdout, stderr].filter(Boolean).join(\"\\n\").trim();\n const passed = code === 0;\n resolve({\n content: [{ type: \"text\", text: passed ? \"Linter passou.\" : \"Linter encontrou problemas.\" }],\n structuredContent: {\n status: passed ? \"passed\" : \"failed\",\n message: passed ? \"Lint passed\" : \"Lint failed\",\n exitCode: code ?? 1,\n output: !passed ? output : undefined,\n },\n });\n });\n });\n }\n);\n\nserver.registerTool(\n \"install_dependencies\",\n {\n title: \"Instalar dependências\",\n description: \"Roda npm install, yarn install ou pnpm install (detecta automaticamente).\",\n inputSchema: z.object({\n packageManager: z.enum([\"npm\", \"yarn\", \"pnpm\", \"auto\"]).optional().describe(\"Package manager. Default: auto.\"),\n }),\n outputSchema: z.object({\n status: z.enum([\"success\", \"failed\"]),\n message: z.string(),\n exitCode: z.number(),\n }),\n },\n async ({ packageManager = \"auto\" }) => {\n let pm = packageManager;\n \n if (pm === \"auto\") {\n if (fs.existsSync(path.join(PROJECT_ROOT, \"yarn.lock\"))) pm = \"yarn\";\n else if (fs.existsSync(path.join(PROJECT_ROOT, \"pnpm-lock.yaml\"))) pm = \"pnpm\";\n else pm = \"npm\";\n }\n\n return new Promise((resolve) => {\n const child = spawn(pm, [\"install\"], {\n cwd: PROJECT_ROOT,\n stdio: \"inherit\",\n shell: process.platform === \"win32\",\n env: { ...process.env },\n });\n\n child.on(\"close\", (code) => {\n const passed = code === 0;\n resolve({\n content: [{ type: \"text\", text: passed ? \"Dependências instaladas.\" : \"Erro ao instalar dependências.\" }],\n structuredContent: {\n status: passed ? \"success\" : \"failed\",\n message: passed ? \"Dependencies installed\" : \"Install failed\",\n exitCode: code ?? 1,\n },\n });\n });\n });\n }\n);\n\nserver.registerTool(\n \"qa_learning_stats\",\n {\n title: \"Estatísticas de aprendizado\",\n description: \"[MÉTRICAS] Retorna métricas de aprendizado do agente: quantos testes gerados, taxa de sucesso na primeira tentativa, correções aplicadas, etc.\",\n inputSchema: z.object({}),\n outputSchema: z.object({\n totalLearnings: z.number(),\n successfulFixes: z.number(),\n selectorFixes: z.number(),\n timingFixes: z.number(),\n testsGenerated: z.number(),\n firstAttemptSuccessRate: z.number(),\n }),\n },\n async () => {\n const stats = getMemoryStats();\n const summary = `📊 **Estatísticas de Aprendizado**\n\n- Total de aprendizados: ${stats.totalLearnings}\n- Correções bem-sucedidas: ${stats.successfulFixes}\n- Correções de seletores: ${stats.selectorFixes}\n- Correções de timing: ${stats.timingFixes}\n- Testes gerados: ${stats.testsGenerated}\n- Taxa de sucesso na 1ª tentativa: ${stats.firstAttemptSuccessRate}%\n\n${stats.totalLearnings === 0 ? \"⚠️ Ainda não há aprendizados. Use qa_auto para gerar testes e aprender com erros.\" : \"\"}`;\n\n return {\n content: [{ type: \"text\", text: summary }],\n structuredContent: stats,\n };\n }\n);\n\nserver.registerTool(\n \"get_test_coverage\",\n {\n title: \"Obter cobertura de testes\",\n description: \"Roda testes com coverage (Jest, Playwright, Cypress com plugin).\",\n inputSchema: z.object({\n framework: z.enum([\"jest\", \"playwright\", \"cypress\"]).optional().describe(\"Framework. Default: detectado automaticamente.\"),\n }),\n outputSchema: z.object({\n status: z.enum([\"success\", \"failed\", \"not_supported\"]),\n message: z.string(),\n coveragePercent: z.number().optional(),\n output: z.string().optional(),\n }),\n },\n async ({ framework }) => {\n const structure = detectProjectStructure();\n const fw = framework || structure.testFrameworks[0];\n\n if (fw === \"jest\") {\n return new Promise((resolve) => {\n const child = spawn(\"npx\", [\"jest\", \"--coverage\"], {\n cwd: PROJECT_ROOT,\n stdio: [\"inherit\", \"pipe\", \"pipe\"],\n shell: process.platform === \"win32\",\n env: { ...process.env },\n });\n\n let stdout = \"\";\n if (child.stdout) child.stdout.on(\"data\", (d) => { stdout += d.toString(); });\n\n child.on(\"close\", (code) => {\n const coverageMatch = stdout.match(/All files.*?(\\d+\\.?\\d*)/);\n const coveragePercent = coverageMatch ? parseFloat(coverageMatch[1]) : undefined;\n\n resolve({\n content: [{ type: \"text\", text: `Coverage: ${coveragePercent || \"N/A\"}%` }],\n structuredContent: {\n status: code === 0 ? \"success\" : \"failed\",\n message: code === 0 ? \"Coverage generated\" : \"Coverage failed\",\n coveragePercent,\n output: stdout,\n },\n });\n });\n });\n }\n\n return {\n content: [{ type: \"text\", text: `Coverage não suportado para ${fw} ainda.` }],\n structuredContent: { status: \"not_supported\", message: \"Coverage not supported for this framework\" },\n };\n }\n);\n\nserver.registerTool(\n \"watch_tests\",\n {\n title: \"Rodar testes em modo watch\",\n description: \"Inicia testes em watch mode (Jest, Vitest). Útil para desenvolvimento.\",\n inputSchema: z.object({\n framework: z.enum([\"jest\", \"vitest\"]).optional().describe(\"Framework. Default: detectado.\"),\n }),\n outputSchema: z.object({\n status: z.string(),\n message: z.string(),\n }),\n },\n async ({ framework }) => {\n const structure = detectProjectStructure();\n const fw = framework || (structure.testFrameworks.includes(\"jest\") ? \"jest\" : \"vitest\");\n\n if (!structure.testFrameworks.includes(fw)) {\n return {\n content: [{ type: \"text\", text: `${fw} não detectado no projeto.` }],\n structuredContent: { status: \"not_found\", message: \"Framework not found\" },\n };\n }\n\n return {\n content: [{ type: \"text\", text: `Para watch mode, rode manualmente: npx ${fw} --watch` }],\n structuredContent: {\n status: \"info\",\n message: `Watch mode requires interactive terminal. Run: npx ${fw} --watch`,\n },\n };\n }\n);\n\nserver.registerTool(\n \"qa_auto\",\n {\n title: \"Modo autônomo: gera, roda, corrige e aprende\",\n description: \"[AGENTE AUTÔNOMO] Loop completo: detecta projeto → gera teste → roda → se falhar: analisa, corrige, roda de novo → aprende com erros. Repete até passar ou atingir max_retries.\",\n inputSchema: z.object({\n request: z.string().describe(\"O que testar (ex: 'login flow', 'checkout', 'API /users').\"),\n framework: z.enum([\n \"cypress\", \"playwright\", \"webdriverio\", \"jest\", \"vitest\", \"mocha\", \"appium\", \"robot\", \"pytest\"\n ]).optional().describe(\"Framework (detectado automaticamente se omitido).\"),\n maxRetries: z.number().optional().describe(\"Máximo de tentativas de correção. Default: 3.\"),\n }),\n outputSchema: z.object({\n ok: z.boolean(),\n testFilePath: z.string().optional(),\n attempts: z.number(),\n finalStatus: z.enum([\"passed\", \"failed\", \"max_retries\"]),\n learnings: z.array(z.object({ attempt: z.number(), action: z.string(), result: z.string() })).optional(),\n error: z.string().optional(),\n }),\n },\n async ({ request, framework, maxRetries = 3 }) => {\n const structure = detectProjectStructure();\n const fw = framework || structure.testFrameworks[0];\n if (!fw) {\n return {\n content: [{ type: \"text\", text: \"Nenhum framework detectado. Configure testes primeiro.\" }],\n structuredContent: { ok: false, error: \"No framework\", finalStatus: \"failed\", attempts: 0 },\n };\n }\n\n const llm = resolveLLMProvider(\"simple\");\n if (!llm.apiKey) {\n return {\n content: [{ type: \"text\", text: \"Configure GROQ_API_KEY, GEMINI_API_KEY ou OPENAI_API_KEY no .env\" }],\n structuredContent: { ok: false, error: \"No API key\", finalStatus: \"failed\", attempts: 0 },\n };\n }\n\n const learnings = [];\n const memory = loadProjectMemory();\n const contextLines = [\n `Frameworks: ${structure.testFrameworks.join(\", \")}`,\n `Pastas: ${structure.testDirs.join(\", \")}`,\n memory.flows?.length ? `Fluxos: ${memory.flows.map((f) => f.name || f.id).join(\", \")}` : \"\",\n ].filter(Boolean).join(\"\\n\");\n\n let testFilePath = null;\n let testContent = null;\n let attempt = 0;\n\n learnings.push({ attempt: 0, action: \"detect_project\", result: `${structure.testFrameworks.length} framework(s)` });\n\n for (attempt = 1; attempt <= maxRetries; attempt++) {\n learnings.push({ attempt, action: \"generate_tests\", result: \"gerando...\" });\n\n const { provider, apiKey, baseUrl, model } = llm;\n const memoryHints = memory.learnings?.filter((l) => l.success).slice(-10).map((l) => l.fix).join(\"\\n\") || \"\";\n const systemPrompt = `Você é um engenheiro de QA especializado em ${fw}. Gere APENAS o código do spec, sem explicações.\n${memoryHints ? `\\nAprendizados anteriores (use como referência):\\n${memoryHints.slice(0, 1000)}` : \"\"}\nRetorne SOMENTE o código, sem markdown.`;\n\n const userPrompt = `Contexto:\\n${contextLines}\\n\\nGere teste para: ${request}\\nFramework: ${fw}`;\n\n try {\n let specContent = \"\";\n if (provider === \"gemini\") {\n const url = `${baseUrl}/models/${model}:generateContent?key=${apiKey}`;\n const res = await fetch(url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n contents: [{ parts: [{ text: systemPrompt + \"\\n\\n\" + userPrompt }] }],\n generationConfig: { temperature: 0.3, maxOutputTokens: 4096 },\n }),\n });\n const data = await res.json();\n specContent = data.candidates?.[0]?.content?.parts?.[0]?.text || \"\";\n } else {\n const res = await fetch(`${baseUrl}/chat/completions`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\", Authorization: `Bearer ${apiKey}` },\n body: JSON.stringify({\n model,\n messages: [{ role: \"system\", content: systemPrompt }, { role: \"user\", content: userPrompt }],\n temperature: 0.3,\n max_tokens: 4096,\n }),\n });\n const data = await res.json();\n specContent = data.choices?.[0]?.message?.content || \"\";\n }\n specContent = specContent.replace(/^```(?:js|javascript|typescript)?\\n?/i, \"\").replace(/\\n?```\\s*$/i, \"\").trim();\n testContent = specContent;\n\n if (!testFilePath) {\n const fileName = request.toLowerCase().replace(/\\s+/g, \"-\").replace(/[^a-z0-9-]/g, \"\").slice(0, 30);\n const { ext, baseDir } = getExtensionAndBaseDir(fw, structure);\n const safeName = fileName + ext;\n testFilePath = path.join(baseDir, safeName);\n if (!fs.existsSync(baseDir)) fs.mkdirSync(baseDir, { recursive: true });\n }\n fs.writeFileSync(testFilePath, testContent, \"utf8\");\n learnings.push({ attempt, action: \"write_test\", result: `gravado: ${testFilePath}` });\n\n learnings.push({ attempt, action: \"run_tests\", result: \"executando...\" });\n const runResult = await new Promise((resolve) => {\n const child = spawn(\"npx\", [fw === \"cypress\" ? \"cypress\" : fw === \"playwright\" ? \"playwright\" : fw, fw === \"cypress\" ? \"run\" : fw === \"playwright\" ? \"test\" : \"run\", testFilePath], {\n cwd: PROJECT_ROOT,\n stdio: [\"inherit\", \"pipe\", \"pipe\"],\n shell: process.platform === \"win32\",\n });\n let stdout = \"\", stderr = \"\";\n if (child.stdout) child.stdout.on(\"data\", (d) => { stdout += d.toString(); });\n if (child.stderr) child.stderr.on(\"data\", (d) => { stderr += d.toString(); });\n child.on(\"close\", (code) => resolve({ code, output: [stdout, stderr].filter(Boolean).join(\"\\n\") }));\n });\n\n if (runResult.code === 0) {\n learnings.push({ attempt, action: \"run_tests\", result: \"✅ passou\" });\n saveProjectMemory({\n learnings: [{ type: \"test_generated\", request, framework: fw, success: true, passedFirstTime: attempt === 1, attempts: attempt, timestamp: new Date().toISOString() }],\n });\n return {\n content: [{ type: \"text\", text: `✅ Teste passou na tentativa ${attempt}!\\n\\nArquivo: ${testFilePath}\\n\\nAprendizados salvos.` }],\n structuredContent: { ok: true, testFilePath, attempts: attempt, finalStatus: \"passed\", learnings },\n };\n }\n\n learnings.push({ attempt, action: \"run_tests\", result: `❌ falhou (exit ${runResult.code})` });\n\n if (attempt >= maxRetries) {\n learnings.push({ attempt, action: \"max_retries\", result: \"limite atingido\" });\n saveProjectMemory({\n learnings: [{ type: \"test_generated\", request, framework: fw, success: false, attempts: attempt, timestamp: new Date().toISOString() }],\n });\n return {\n content: [{ type: \"text\", text: `❌ Teste falhou após ${attempt} tentativa(s).\\n\\nÚltimo erro:\\n${runResult.output.slice(0, 500)}` }],\n structuredContent: { ok: false, testFilePath, attempts: attempt, finalStatus: \"max_retries\", learnings },\n };\n }\n\n learnings.push({ attempt, action: \"analyze_failures\", result: \"analisando...\" });\n const flakyAnalysis = detectFlakyPatterns(runResult.output);\n const llmComplex = resolveLLMProvider(\"complex\");\n const explainResult = await generateFailureExplanation(runResult.output, testFilePath);\n\n if (!explainResult.ok || !explainResult.structuredContent?.sugestaoCorrecao) {\n learnings.push({ attempt, action: \"analyze_failures\", result: \"sem sugestão de correção\" });\n continue;\n }\n\n learnings.push({ attempt, action: \"apply_fix\", result: \"aplicando correção...\" });\n const fixedCode = explainResult.structuredContent.sugestaoCorrecao;\n testContent = fixedCode;\n fs.writeFileSync(testFilePath, testContent, \"utf8\");\n learnings.push({ attempt, action: \"apply_fix\", result: \"correção aplicada\" });\n\n if (flakyAnalysis.isLikelyFlaky) {\n saveProjectMemory({\n learnings: [{\n type: flakyAnalysis.patterns[0]?.pattern === \"selector\" ? \"selector_fix\" : \"timing_fix\",\n request,\n framework: fw,\n fix: fixedCode.slice(0, 500),\n success: false,\n timestamp: new Date().toISOString(),\n }],\n });\n }\n } catch (err) {\n learnings.push({ attempt, action: \"error\", result: err.message });\n return {\n content: [{ type: \"text\", text: `Erro na tentativa ${attempt}: ${err.message}` }],\n structuredContent: { ok: false, error: err.message, attempts: attempt, finalStatus: \"failed\", learnings },\n };\n }\n }\n\n return {\n content: [{ type: \"text\", text: `❌ Falhou após ${maxRetries} tentativa(s).` }],\n structuredContent: { ok: false, testFilePath, attempts: maxRetries, finalStatus: \"max_retries\", learnings },\n };\n }\n);\n\nserver.registerTool(\n \"create_test_template\",\n {\n title: \"Criar template de teste\",\n description: \"Gera template básico de teste (boilerplate) para o framework escolhido.\",\n inputSchema: z.object({\n framework: z.enum([\"cypress\", \"playwright\", \"jest\"]).describe(\"Framework.\"),\n type: z.enum([\"api\", \"ui\", \"unit\"]).optional().describe(\"Tipo de teste. Default: api.\"),\n }),\n outputSchema: z.object({\n ok: z.boolean(),\n template: z.string(),\n suggestedFileName: z.string(),\n }),\n },\n async ({ framework, type = \"api\" }) => {\n let template = \"\";\n let fileName = \"\";\n\n if (framework === \"cypress\") {\n fileName = `${type}-test.cy.js`;\n template = `describe('${type.toUpperCase()} Test', () => {\n it('should pass', () => {\n ${type === \"api\" ? \"cy.request('GET', 'http://localhost:3000/api/health').then((res) => {\\n expect(res.status).to.eq(200);\\n });\" : \"cy.visit('/');\\n cy.get('h1').should('be.visible');\"}\n });\n});`;\n } else if (framework === \"playwright\") {\n fileName = `${type}-test.spec.js`;\n template = `const { test, expect } = require('@playwright/test');\n\ntest.describe('${type.toUpperCase()} Test', () => {\n test('should pass', async ({ ${type === \"api\" ? \"request\" : \"page\"} }) => {\n ${type === \"api\" ? \"const res = await request.get('http://localhost:3000/api/health');\\n expect(res.status()).toBe(200);\" : \"await page.goto('/');\\n await expect(page.locator('h1')).toBeVisible();\"}\n });\n});`;\n } else {\n fileName = `${type}-test.test.js`;\n template = `describe('${type.toUpperCase()} Test', () => {\n test('should pass', ${type === \"api\" ? \"async () => {\\n const res = await fetch('http://localhost:3000/api/health');\\n expect(res.status).toBe(200);\\n }\" : \"() => {\\n expect(true).toBe(true);\\n }\"});\n});`;\n }\n\n return {\n content: [{ type: \"text\", text: `Template criado. Use write_test para gravar.` }],\n structuredContent: { ok: true, template, suggestedFileName: fileName },\n };\n }\n);\n\nasync function main() {\n const cmd = process.argv[2];\n\n if (cmd === \"--help\" || cmd === \"-h\") {\n console.log(`\nmcp-lab-agent - Agente autônomo de QA que aprende com os próprios erros\n\nUSO:\n mcp-lab-agent [comando] # Sem comando: inicia servidor MCP\n mcp-lab-agent --help # Mostra esta ajuda\n\nCOMANDOS CLI:\n detect [--json] Detecta frameworks e estrutura. Padrão: resumo. --json: JSON completo para scripts.\n route <tarefa> Sugere qual ferramenta usar (ex: route \"rodar testes\")\n list Lista ferramentas MCP disponíveis\n auto <descrição> [--max-retries N] [NOVO] Modo autônomo: gera teste, roda, corrige e aprende (default: 3 tentativas)\n stats [NOVO] Mostra estatísticas de aprendizado (taxa de sucesso, correções, etc.)\n\nEXEMPLOS:\n mcp-lab-agent auto \"login flow\" --max-retries 5\n mcp-lab-agent stats\n mcp-lab-agent detect --json\n\nINTEGRAÇÃO MCP (Cursor/Cline/Windsurf):\n Adicione ao ~/.cursor/mcp.json:\n {\n \"mcpServers\": {\n \"qa-lab-agent\": {\n \"command\": \"npx\",\n \"args\": [\"-y\", \"mcp-lab-agent\"],\n \"cwd\": \"\\${workspaceFolder}\"\n }\n }\n }\n`);\n process.exit(0);\n }\n\n if (cmd === \"detect\") {\n const structure = detectProjectStructure();\n const jsonOnly = process.argv.includes(\"--json\");\n if (jsonOnly) {\n console.log(JSON.stringify(structure, null, 2));\n } else {\n const lines = [\n \"\",\n \"mcp-lab-agent · detecção\",\n \"─\".repeat(40),\n `Frameworks: ${structure.testFrameworks.length ? structure.testFrameworks.join(\", \") : \"nenhum\"}`,\n `Pastas: ${structure.testDirs.length ? structure.testDirs.join(\", \") : \"nenhuma\"}`,\n `Backend: ${structure.backendDir || \"—\"}`,\n `Frontend: ${structure.frontendDir || \"—\"}`,\n `Mobile: ${structure.hasMobile ? \"sim\" : \"—\"}`,\n \"─\".repeat(40),\n \"(use --json para saída completa)\",\n \"\",\n ];\n console.log(lines.join(\"\\n\"));\n }\n process.exit(0);\n }\n\n if (cmd === \"list\") {\n const agents = Object.entries(QA_AGENTS).map(([k, v]) => ` ${k}: ${v.tools.join(\", \")}`);\n console.log(\"Agentes e ferramentas:\\n\" + agents.join(\"\\n\"));\n process.exit(0);\n }\n\n if (cmd === \"route\" && process.argv[3]) {\n const task = process.argv.slice(3).join(\" \");\n const t = task.toLowerCase();\n let agent = \"detection\";\n if (/autônomo|auto|completo|loop|aprende|corrige automaticamente/i.test(t)) agent = \"autonomous\";\n else if (/estatística|métrica de aprendizado|taxa de sucesso|learning|stats/i.test(t)) agent = \"learning\";\n else if (/rodar|executar|run|test|coverage|watch/i.test(t)) agent = \"execution\";\n else if (/gerar|criar|escrever|generate|write|template/i.test(t)) agent = \"generation\";\n else if (/analisar|por que|falhou|sugerir|fix|selector/i.test(t)) agent = \"analysis\";\n else if (/browser|navegador|screenshot|network|console/i.test(t)) agent = \"browser\";\n else if (/relatório|métrica|bug report/i.test(t)) agent = \"reporting\";\n else if (/linter|dependência|instalar|analisar método/i.test(t)) agent = \"maintenance\";\n const a = QA_AGENTS[agent] || QA_AGENTS.detection;\n console.log(JSON.stringify({ suggestedAgent: agent, suggestedTools: a.tools, description: a.desc }, null, 2));\n process.exit(0);\n }\n\n if (cmd === \"auto\") {\n const request = process.argv.slice(3).join(\" \");\n if (!request) {\n console.error(\"❌ Uso: mcp-lab-agent auto <descrição do teste> [--max-retries N]\");\n process.exit(1);\n }\n const maxRetriesIdx = process.argv.indexOf(\"--max-retries\");\n const maxRetries = maxRetriesIdx !== -1 && process.argv[maxRetriesIdx + 1] ? parseInt(process.argv[maxRetriesIdx + 1], 10) : 3;\n const cleanRequest = request.replace(/--max-retries\\s+\\d+/g, \"\").trim();\n\n console.log(`\\n🤖 Modo autônomo iniciado: \"${cleanRequest}\"\\n`);\n const structure = detectProjectStructure();\n const fw = structure.testFrameworks[0];\n if (!fw) {\n console.error(\"❌ Nenhum framework detectado.\");\n process.exit(1);\n }\n\n const llm = resolveLLMProvider(\"simple\");\n if (!llm.apiKey) {\n console.error(\"❌ Configure GROQ_API_KEY, GEMINI_API_KEY ou OPENAI_API_KEY no .env\");\n process.exit(1);\n }\n\n const memory = loadProjectMemory();\n const contextLines = [\n `Frameworks: ${structure.testFrameworks.join(\", \")}`,\n `Pastas: ${structure.testDirs.join(\", \")}`,\n memory.flows?.length ? `Fluxos: ${memory.flows.map((f) => f.name || f.id).join(\", \")}` : \"\",\n ].filter(Boolean).join(\"\\n\");\n\n let testFilePath = null;\n let testContent = null;\n\n for (let attempt = 1; attempt <= maxRetries; attempt++) {\n console.log(`\\n[Tentativa ${attempt}/${maxRetries}] Gerando teste...`);\n\n const { provider, apiKey, baseUrl, model } = llm;\n const memoryHints = memory.learnings?.filter((l) => l.success).slice(-10).map((l) => l.fix).join(\"\\n\") || \"\";\n const systemPrompt = `Você é um engenheiro de QA especializado em ${fw}. Gere APENAS o código do spec, sem explicações.\n${memoryHints ? `\\nAprendizados anteriores (use como referência):\\n${memoryHints.slice(0, 1000)}` : \"\"}\nRetorne SOMENTE o código, sem markdown.`;\n\n const userPrompt = `Contexto:\\n${contextLines}\\n\\nGere teste para: ${cleanRequest}\\nFramework: ${fw}`;\n\n try {\n let specContent = \"\";\n if (provider === \"gemini\") {\n const url = `${baseUrl}/models/${model}:generateContent?key=${apiKey}`;\n const res = await fetch(url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n contents: [{ parts: [{ text: systemPrompt + \"\\n\\n\" + userPrompt }] }],\n generationConfig: { temperature: 0.3, maxOutputTokens: 4096 },\n }),\n });\n const data = await res.json();\n specContent = data.candidates?.[0]?.content?.parts?.[0]?.text || \"\";\n } else {\n const res = await fetch(`${baseUrl}/chat/completions`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\", Authorization: `Bearer ${apiKey}` },\n body: JSON.stringify({\n model,\n messages: [{ role: \"system\", content: systemPrompt }, { role: \"user\", content: userPrompt }],\n temperature: 0.3,\n max_tokens: 4096,\n }),\n });\n const data = await res.json();\n specContent = data.choices?.[0]?.message?.content || \"\";\n }\n specContent = specContent.replace(/^```(?:js|javascript|typescript)?\\n?/i, \"\").replace(/\\n?```\\s*$/i, \"\").trim();\n testContent = specContent;\n\n if (!testFilePath) {\n const fileName = cleanRequest.toLowerCase().replace(/\\s+/g, \"-\").replace(/[^a-z0-9-]/g, \"\").slice(0, 30);\n const { ext, baseDir } = getExtensionAndBaseDir(fw, structure);\n const safeName = fileName + ext;\n testFilePath = path.join(baseDir, safeName);\n if (!fs.existsSync(baseDir)) fs.mkdirSync(baseDir, { recursive: true });\n }\n fs.writeFileSync(testFilePath, testContent, \"utf8\");\n console.log(`✅ Teste gravado: ${testFilePath}`);\n\n console.log(`\\n[Tentativa ${attempt}/${maxRetries}] Executando teste...`);\n const runResult = await new Promise((resolve) => {\n const child = spawn(\"npx\", [fw === \"cypress\" ? \"cypress\" : fw === \"playwright\" ? \"playwright\" : fw, fw === \"cypress\" ? \"run\" : fw === \"playwright\" ? \"test\" : \"run\", testFilePath], {\n cwd: PROJECT_ROOT,\n stdio: [\"inherit\", \"pipe\", \"pipe\"],\n shell: process.platform === \"win32\",\n });\n let stdout = \"\", stderr = \"\";\n if (child.stdout) child.stdout.on(\"data\", (d) => { stdout += d.toString(); });\n if (child.stderr) child.stderr.on(\"data\", (d) => { stderr += d.toString(); });\n child.on(\"close\", (code) => resolve({ code, output: [stdout, stderr].filter(Boolean).join(\"\\n\") }));\n });\n\n if (runResult.code === 0) {\n console.log(`\\n✅ Teste passou na tentativa ${attempt}!`);\n saveProjectMemory({\n learnings: [{ type: \"test_generated\", request: cleanRequest, framework: fw, success: true, passedFirstTime: attempt === 1, attempts: attempt, timestamp: new Date().toISOString() }],\n });\n console.log(`\\n📊 Aprendizado salvo. Use \"mcp-lab-agent stats\" para ver métricas.\\n`);\n process.exit(0);\n }\n\n console.log(`\\n❌ Teste falhou (exit ${runResult.code})`);\n console.log(`\\nSaída:\\n${runResult.output.slice(0, 800)}\\n`);\n\n if (attempt >= maxRetries) {\n console.log(`\\n❌ Limite de tentativas atingido (${maxRetries}).\\n`);\n saveProjectMemory({\n learnings: [{ type: \"test_generated\", request: cleanRequest, framework: fw, success: false, attempts: attempt, timestamp: new Date().toISOString() }],\n });\n process.exit(1);\n }\n\n console.log(`\\n[Tentativa ${attempt}/${maxRetries}] Analisando falha...`);\n const flakyAnalysis = detectFlakyPatterns(runResult.output);\n if (flakyAnalysis.isLikelyFlaky) {\n console.log(`⚠️ Flaky detectado (${flakyAnalysis.confidence.toFixed(2)}): ${flakyAnalysis.patterns.map((p) => p.pattern).join(\", \")}`);\n }\n\n const explainResult = await generateFailureExplanation(runResult.output, testFilePath);\n if (!explainResult.ok || !explainResult.structuredContent?.sugestaoCorrecao) {\n console.log(`⚠️ Não foi possível gerar correção. Tentando novamente...`);\n continue;\n }\n\n console.log(`\\n[Tentativa ${attempt}/${maxRetries}] Aplicando correção...`);\n const fixedCode = explainResult.structuredContent.sugestaoCorrecao;\n testContent = fixedCode;\n fs.writeFileSync(testFilePath, testContent, \"utf8\");\n console.log(`✅ Correção aplicada.`);\n\n if (flakyAnalysis.isLikelyFlaky) {\n saveProjectMemory({\n learnings: [{\n type: flakyAnalysis.patterns[0]?.pattern === \"selector\" ? \"selector_fix\" : \"timing_fix\",\n request: cleanRequest,\n framework: fw,\n fix: fixedCode.slice(0, 500),\n success: false,\n timestamp: new Date().toISOString(),\n }],\n });\n }\n } catch (err) {\n console.error(`\\n❌ Erro na tentativa ${attempt}: ${err.message}\\n`);\n process.exit(1);\n }\n }\n\n console.log(`\\n❌ Falhou após ${maxRetries} tentativa(s).\\n`);\n process.exit(1);\n }\n\n if (cmd === \"stats\") {\n const stats = getMemoryStats();\n console.log(`\n📊 Estatísticas de Aprendizado\n\nTotal de aprendizados: ${stats.totalLearnings}\nCorreções bem-sucedidas: ${stats.successfulFixes}\nCorreções de seletores: ${stats.selectorFixes}\nCorreções de timing: ${stats.timingFixes}\nTestes gerados: ${stats.testsGenerated}\nTaxa de sucesso na 1ª tentativa: ${stats.firstAttemptSuccessRate}%\n\n${stats.totalLearnings === 0 ? \"⚠️ Ainda não há aprendizados. Use 'mcp-lab-agent auto <descrição>' para gerar testes e aprender com erros.\" : \"\"}\n`);\n process.exit(0);\n }\n\n const transport = new StdioServerTransport();\n await server.connect(transport);\n}\n\nmain().catch((err) => {\n console.error(\"Erro no MCP server:\", err);\n process.exit(1);\n});\n"],"mappings":"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","names":["res","data"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.js"],"sourcesContent":["#!/usr/bin/env node\n/**\n * MCP Lab Agent - Standalone\n * MCP server genérico para QA automation em qualquer projeto.\n * Detecta automaticamente Cypress, Playwright, Jest, estrutura do projeto, etc.\n */\nimport { config } from \"dotenv\";\nimport { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\";\nimport { z } from \"zod\";\nimport { spawn } from \"node:child_process\";\nimport path from \"node:path\";\nimport fs from \"node:fs\";\n\nconst PROJECT_ROOT = process.cwd();\nconfig({ path: path.join(PROJECT_ROOT, \".env\") });\n\nconst server = new McpServer({\n name: \"mcp-lab-agent\",\n version: \"1.0.0\",\n});\n\n// ============================================================================\n// MODEL ROUTING - Rotear tarefas simples vs complexas (economia de custo)\n// ============================================================================\n\nconst TASK_COMPLEXITY = {\n simple: [\"generate_tests\", \"create_test_template\", \"suggest_fix\"],\n complex: [\"por_que_falhou\", \"suggest_selector_fix\", \"analyze_file_methods\"],\n};\n\nfunction resolveLLMProvider(taskType = \"simple\") {\n const GROQ_KEY = process.env.GROQ_API_KEY;\n const GEMINI_KEY = process.env.GEMINI_API_KEY;\n const OPENAI_KEY = process.env.OPENAI_API_KEY || process.env.QA_LAB_LLM_API_KEY;\n const OLLAMA_URL = process.env.OLLAMA_BASE_URL || \"http://localhost:11434\";\n const CUSTOM_URL = process.env.QA_LAB_LLM_BASE_URL;\n\n const simpleModel = process.env.QA_LAB_LLM_SIMPLE;\n const complexModel = process.env.QA_LAB_LLM_COMPLEX;\n\n if (CUSTOM_URL) {\n const model = taskType === \"complex\" ? (complexModel || \"llama3.1:70b\") : (simpleModel || \"llama3.1:8b\");\n return { provider: \"custom\", apiKey: process.env.QA_LAB_LLM_API_KEY || \"not-needed\", baseUrl: CUSTOM_URL, model };\n }\n\n if (!GROQ_KEY && !GEMINI_KEY && !OPENAI_KEY) {\n const model = taskType === \"complex\" ? (complexModel || \"llama3.1:70b\") : (simpleModel || \"llama3.1:8b\");\n return { provider: \"ollama\", apiKey: \"not-needed\", baseUrl: `${OLLAMA_URL}/v1`, model };\n }\n\n let provider = GROQ_KEY ? \"groq\" : GEMINI_KEY ? \"gemini\" : \"openai\";\n const apiKey = GROQ_KEY || GEMINI_KEY || OPENAI_KEY;\n const baseUrl = provider === \"groq\"\n ? \"https://api.groq.com/openai/v1\"\n : provider === \"gemini\"\n ? \"https://generativelanguage.googleapis.com/v1beta\"\n : \"https://api.openai.com/v1\";\n\n let model;\n if (taskType === \"complex\") {\n model = complexModel || (provider === \"groq\" ? \"llama-3.3-70b-versatile\" : provider === \"gemini\" ? \"gemini-1.5-pro\" : \"gpt-4o\");\n } else {\n model = simpleModel || (provider === \"groq\" ? \"llama-3.1-8b-instant\" : provider === \"gemini\" ? \"gemini-1.5-flash\" : \"gpt-4o-mini\");\n }\n\n return { provider, apiKey, baseUrl, model };\n}\n\n// ============================================================================\n// PROJECT MEMORY - Cache de padrões para geração e análise\n// ============================================================================\n\nconst MEMORY_FILE = path.join(PROJECT_ROOT, \".qa-lab-memory.json\");\nconst FLOWS_CONFIG_FILE = path.join(PROJECT_ROOT, \"qa-lab-flows.json\");\n\nfunction loadProjectMemory() {\n const memory = { patterns: {}, conventions: {}, lastRun: null, selectors: [] };\n if (fs.existsSync(MEMORY_FILE)) {\n try {\n const raw = fs.readFileSync(MEMORY_FILE, \"utf8\");\n Object.assign(memory, JSON.parse(raw));\n } catch {}\n }\n if (fs.existsSync(FLOWS_CONFIG_FILE)) {\n try {\n const flows = JSON.parse(fs.readFileSync(FLOWS_CONFIG_FILE, \"utf8\"));\n memory.flows = flows.flows || [];\n } catch {}\n }\n return memory;\n}\n\nfunction saveProjectMemory(updates) {\n try {\n let data = loadProjectMemory();\n if (updates.patterns) data.patterns = { ...data.patterns, ...updates.patterns };\n if (updates.conventions) data.conventions = { ...data.conventions, ...updates.conventions };\n if (updates.selectors) data.selectors = [...new Set([...(data.selectors || []), ...updates.selectors])].slice(-100);\n if (updates.lastRun) data.lastRun = updates.lastRun;\n if (updates.learnings) {\n data.learnings = data.learnings || [];\n data.learnings.push(...updates.learnings);\n if (data.learnings.length > 200) data.learnings = data.learnings.slice(-150);\n }\n data.updatedAt = new Date().toISOString();\n fs.writeFileSync(MEMORY_FILE, JSON.stringify(data, null, 2), \"utf8\");\n } catch {}\n}\n\nfunction getMemoryStats() {\n const memory = loadProjectMemory();\n const learnings = memory.learnings || [];\n const successfulFixes = learnings.filter((l) => l.success);\n const selectorFixes = learnings.filter((l) => l.type === \"selector_fix\");\n const timingFixes = learnings.filter((l) => l.type === \"timing_fix\");\n const totalTests = learnings.filter((l) => l.type === \"test_generated\").length;\n const firstAttemptSuccess = learnings.filter((l) => l.type === \"test_generated\" && l.passedFirstTime).length;\n\n return {\n totalLearnings: learnings.length,\n successfulFixes: successfulFixes.length,\n selectorFixes: selectorFixes.length,\n timingFixes: timingFixes.length,\n testsGenerated: totalTests,\n firstAttemptSuccessRate: totalTests > 0 ? Math.round((firstAttemptSuccess / totalTests) * 100) : 0,\n };\n}\n\n// ============================================================================\n// FLAKY DETECTION - Padrões típicos de teste intermitente\n// ============================================================================\n\nconst FLAKY_PATTERNS = [\n { name: \"timing\", regex: /timeout|timed out|exceeded|wait|delay|slow|race condition/i, suggestion: \"Adicione wait explícito (ex: page.waitForSelector) ou aumente o timeout.\" },\n { name: \"ordering\", regex: /order|sequenc|flaky|intermittent|sometimes|random/i, suggestion: \"Issole o teste ou use beforeAll/afterAll para estado limpo. Evite dependência de ordem entre testes.\" },\n { name: \"selector\", regex: /element not found|selector|locator|cy\\.get|page\\.locator|Unable to find/i, suggestion: \"Use seletores estáveis: data-testid, role, texto acessível. Evite classes CSS dinâmicas.\" },\n { name: \"network\", regex: /ECONNREFUSED|network|fetch|axios|request failed|404|500/i, suggestion: \"Mocke APIs ou garanta que o backend esteja rodando. Use retry ou intercept.\" },\n { name: \"shared_state\", regex: /state|cleanup|beforeEach|afterEach|isolation/i, suggestion: \"Garanta beforeEach/afterEach para resetar estado. Evite variáveis globais compartilhadas.\" },\n];\n\nfunction detectFlakyPatterns(runOutput) {\n const detected = [];\n for (const p of FLAKY_PATTERNS) {\n if (p.regex.test(runOutput)) {\n detected.push({ pattern: p.name, suggestion: p.suggestion });\n }\n }\n const confidence = detected.length > 0 ? Math.min(0.5 + detected.length * 0.2, 0.95) : 0;\n return { isLikelyFlaky: confidence > 0.5, confidence, patterns: detected };\n}\n\n// ============================================================================\n// DETECÇÃO AUTOMÁTICA DE ESTRUTURA\n// ============================================================================\n\nfunction detectProjectStructure() {\n const structure = {\n hasTests: false,\n testFrameworks: [],\n testDirs: [],\n hasBackend: false,\n backendDir: null,\n hasFrontend: false,\n frontendDir: null,\n hasMobile: false,\n packageJson: null,\n pythonRequirements: null,\n };\n\n // Detectar Node.js/JavaScript/TypeScript\n const pkgPath = path.join(PROJECT_ROOT, \"package.json\");\n if (fs.existsSync(pkgPath)) {\n structure.packageJson = JSON.parse(fs.readFileSync(pkgPath, \"utf8\"));\n const deps = {\n ...structure.packageJson.dependencies,\n ...structure.packageJson.devDependencies,\n };\n\n // Frameworks E2E/UI\n if (deps.cypress) {\n structure.testFrameworks.push(\"cypress\");\n structure.hasTests = true;\n }\n if (deps[\"@playwright/test\"] || deps.playwright) {\n structure.testFrameworks.push(\"playwright\");\n structure.hasTests = true;\n }\n if (deps.webdriverio || deps[\"@wdio/cli\"]) {\n structure.testFrameworks.push(\"webdriverio\");\n structure.hasTests = true;\n }\n\n // Frameworks Unit/Integration\n if (deps.jest) {\n structure.testFrameworks.push(\"jest\");\n structure.hasTests = true;\n }\n if (deps.vitest) {\n structure.testFrameworks.push(\"vitest\");\n structure.hasTests = true;\n }\n if (deps.mocha) {\n structure.testFrameworks.push(\"mocha\");\n structure.hasTests = true;\n }\n if (deps.jasmine) {\n structure.testFrameworks.push(\"jasmine\");\n structure.hasTests = true;\n }\n\n // Frameworks Mobile\n if (deps.appium || deps[\"appium-webdriverio\"]) {\n structure.testFrameworks.push(\"appium\");\n structure.hasTests = true;\n structure.hasMobile = true;\n }\n if (deps.detox) {\n structure.testFrameworks.push(\"detox\");\n structure.hasTests = true;\n structure.hasMobile = true;\n }\n\n // API Testing\n if (deps.supertest) {\n structure.testFrameworks.push(\"supertest\");\n structure.hasTests = true;\n }\n if (deps[\"@pactum/pactum\"] || deps.pactum) {\n structure.testFrameworks.push(\"pactum\");\n structure.hasTests = true;\n }\n\n // Outros frameworks E2E\n if (deps.testcafe || deps[\"testcafe\"]) {\n structure.testFrameworks.push(\"testcafe\");\n structure.hasTests = true;\n }\n if (deps.nightwatch || deps[\"nightwatch\"]) {\n structure.testFrameworks.push(\"nightwatch\");\n structure.hasTests = true;\n }\n if (deps.puppeteer) {\n structure.testFrameworks.push(\"puppeteer\");\n structure.hasTests = true;\n }\n if (deps.codeceptjs || deps[\"codeceptjs\"]) {\n structure.testFrameworks.push(\"codeceptjs\");\n structure.hasTests = true;\n }\n\n // Backend detection\n if (deps.express || deps.fastify || deps[\"@nestjs/core\"] || deps.koa) {\n structure.hasBackend = true;\n }\n \n // Frontend detection\n if (deps.next || deps.react || deps.vue || deps.svelte || deps.angular) {\n structure.hasFrontend = true;\n }\n }\n\n // Detectar Python (Robot Framework, pytest, etc.)\n const requirementsPath = path.join(PROJECT_ROOT, \"requirements.txt\");\n if (fs.existsSync(requirementsPath)) {\n const requirements = fs.readFileSync(requirementsPath, \"utf8\");\n structure.pythonRequirements = requirements;\n\n if (/robotframework/i.test(requirements)) {\n structure.testFrameworks.push(\"robot\");\n structure.hasTests = true;\n }\n if (/pytest/i.test(requirements)) {\n structure.testFrameworks.push(\"pytest\");\n structure.hasTests = true;\n }\n if (/behave/i.test(requirements)) {\n structure.testFrameworks.push(\"behave\");\n structure.hasTests = true;\n }\n if (/requests/i.test(requirements)) {\n structure.hasBackend = true;\n }\n }\n\n // Detectar pastas de teste (genérico)\n const commonTestDirs = [\n \"tests\", \"test\", \"e2e\", \"cypress\", \"playwright\", \"__tests__\",\n \"specs\", \"spec\", \"integration\", \"unit\", \"functional\", \"robot\",\n \"features\", \"scenarios\", \"mobile\", \"api\",\n // Monorepo: subprojetos por framework\n \"playwright-js\", \"puppeteer-js\", \"testcafe-js\", \"wdio-webdriver-io\",\n \"nightwatch-js\", \"codeceptjs\", \"robot-framework\", \"selenium-python\"\n ];\n for (const dir of commonTestDirs) {\n const fullPath = path.join(PROJECT_ROOT, dir);\n if (fs.existsSync(fullPath) && fs.statSync(fullPath).isDirectory()) {\n structure.testDirs.push(dir);\n }\n }\n\n // Monorepo: escanear subdirs de primeiro nível que parecem ter testes\n const skipDirs = [\"node_modules\", \".git\", \"dist\", \"build\", \".next\", \".venv\"];\n try {\n const rootEntries = fs.readdirSync(PROJECT_ROOT, { withFileTypes: true });\n for (const e of rootEntries) {\n if (!e.isDirectory() || skipDirs.includes(e.name)) continue;\n const subPath = path.join(PROJECT_ROOT, e.name);\n if (structure.testDirs.includes(e.name)) continue;\n // Verificar se há package.json ou tests/ dentro\n const hasPkg = fs.existsSync(path.join(subPath, \"package.json\"));\n const hasTests = fs.existsSync(path.join(subPath, \"tests\")) ||\n fs.existsSync(path.join(subPath, \"test\")) ||\n fs.existsSync(path.join(subPath, \"e2e\")) ||\n fs.existsSync(path.join(subPath, \"__tests__\")) ||\n fs.existsSync(path.join(subPath, \"specs\"));\n if (hasPkg || hasTests) {\n structure.testDirs.push(e.name);\n }\n }\n } catch {}\n\n // Monorepo: detectar frameworks em package.json de subdirs\n for (const dir of structure.testDirs) {\n const subPkg = path.join(PROJECT_ROOT, dir, \"package.json\");\n if (!fs.existsSync(subPkg)) continue;\n try {\n const sub = JSON.parse(fs.readFileSync(subPkg, \"utf8\"));\n const subDeps = { ...(sub.dependencies || {}), ...(sub.devDependencies || {}) };\n const toAdd = [];\n if (subDeps.cypress && !structure.testFrameworks.includes(\"cypress\")) toAdd.push(\"cypress\");\n if ((subDeps[\"@playwright/test\"] || subDeps.playwright) && !structure.testFrameworks.includes(\"playwright\")) toAdd.push(\"playwright\");\n if ((subDeps.webdriverio || subDeps[\"@wdio/cli\"]) && !structure.testFrameworks.includes(\"webdriverio\")) toAdd.push(\"webdriverio\");\n if (subDeps.testcafe && !structure.testFrameworks.includes(\"testcafe\")) toAdd.push(\"testcafe\");\n if (subDeps.nightwatch && !structure.testFrameworks.includes(\"nightwatch\")) toAdd.push(\"nightwatch\");\n if (subDeps.puppeteer && !structure.testFrameworks.includes(\"puppeteer\")) toAdd.push(\"puppeteer\");\n if (subDeps.codeceptjs && !structure.testFrameworks.includes(\"codeceptjs\")) toAdd.push(\"codeceptjs\");\n if (subDeps.jest && !structure.testFrameworks.includes(\"jest\")) toAdd.push(\"jest\");\n toAdd.forEach((fw) => { structure.testFrameworks.push(fw); structure.hasTests = true; });\n } catch {}\n }\n\n // Monorepo: detectar Robot/pytest em requirements.txt de subdirs\n for (const dir of structure.testDirs) {\n const reqPath = path.join(PROJECT_ROOT, dir, \"requirements.txt\");\n if (!fs.existsSync(reqPath)) continue;\n try {\n const req = fs.readFileSync(reqPath, \"utf8\");\n if (/robotframework/i.test(req) && !structure.testFrameworks.includes(\"robot\")) {\n structure.testFrameworks.push(\"robot\");\n structure.hasTests = true;\n }\n if (/pytest|selenium/i.test(req) && !structure.testFrameworks.includes(\"pytest\")) {\n structure.testFrameworks.push(\"pytest\");\n structure.hasTests = true;\n }\n } catch {}\n }\n\n // Detectar backend\n const commonBackendDirs = [\"backend\", \"server\", \"api\", \"src\"];\n for (const dir of commonBackendDirs) {\n const fullPath = path.join(PROJECT_ROOT, dir);\n if (fs.existsSync(fullPath) && !structure.backendDir) {\n const hasServerFile = fs.existsSync(path.join(fullPath, \"server.js\")) ||\n fs.existsSync(path.join(fullPath, \"index.js\")) ||\n fs.existsSync(path.join(fullPath, \"app.js\"));\n if (hasServerFile) {\n structure.backendDir = dir;\n }\n }\n }\n\n // Detectar frontend\n const commonFrontendDirs = [\"frontend\", \"client\", \"web\", \"app\", \"src\"];\n for (const dir of commonFrontendDirs) {\n const fullPath = path.join(PROJECT_ROOT, dir);\n if (fs.existsSync(fullPath) && !structure.frontendDir) {\n const hasAppFile = fs.existsSync(path.join(fullPath, \"App.js\")) ||\n fs.existsSync(path.join(fullPath, \"App.tsx\")) ||\n fs.existsSync(path.join(fullPath, \"index.html\"));\n if (hasAppFile) {\n structure.frontendDir = dir;\n }\n }\n }\n\n return structure;\n}\n\n// ============================================================================\n// PADRÕES UNIVERSAIS DE ARQUIVOS DE TESTE (qualquer framework)\n// ============================================================================\n\nconst UNIVERSAL_TEST_PATTERNS = [\n /\\.(cy|spec|test)\\.(js|ts|jsx|tsx)$/i,\n /_test\\.(js|ts)$/i, // CodeceptJS\n /\\.robot$/i,\n /\\.feature$/i,\n /^(test_.*|.*_test)\\.py$/i,\n /\\.steps?\\.(js|ts|py)$/i,\n /\\.e2e\\.(js|ts)$/i,\n /\\.it\\.(js|ts)$/i,\n];\n\nfunction isTestFile(name) {\n return UNIVERSAL_TEST_PATTERNS.some((re) => re.test(name));\n}\n\nfunction collectTestFiles(structure, options = {}) {\n const { pattern, framework, maxContentFiles = 0 } = options;\n const results = [];\n\n for (const dir of structure.testDirs) {\n const fullPath = path.join(PROJECT_ROOT, dir);\n const walk = (p, base = \"\") => {\n if (!fs.existsSync(p)) return;\n const entries = fs.readdirSync(p, { withFileTypes: true });\n for (const e of entries) {\n const rel = base ? `${base}/${e.name}` : e.name;\n if (e.isDirectory()) {\n if (e.name === \"node_modules\" || e.name === \".git\" || e.name === \".venv\") continue;\n walk(path.join(p, e.name), rel);\n } else if (e.isFile() && isTestFile(e.name)) {\n const filePath = `${dir}/${rel}`;\n if (pattern && !filePath.toLowerCase().includes(pattern.toLowerCase())) continue;\n const inferredFw = inferFrameworkFromFile(e.name, structure, filePath);\n if (framework && framework !== \"all\" && inferredFw !== framework && !matchesFramework(inferredFw, framework)) continue;\n const entry = { path: filePath, inferredFramework: inferredFw };\n if (maxContentFiles > 0 && results.length < maxContentFiles) {\n try {\n entry.content = fs.readFileSync(path.join(PROJECT_ROOT, filePath), \"utf8\");\n } catch {}\n }\n results.push(entry);\n }\n }\n };\n walk(fullPath);\n }\n return results;\n}\n\nfunction inferFrameworkFromFile(name, structure = {}, filePath = \"\") {\n const pathLower = (filePath || \"\").toLowerCase().replace(/\\\\/g, \"/\");\n // Inferir pelo CAMINHO quando há múltiplos frameworks (ex: tests/cypress/, tests/selenium-python/)\n if (/[\\/]cypress[\\/\\-]/.test(pathLower)) return \"cypress\";\n if (/[\\/]playwright[\\/\\-]/.test(pathLower)) return \"playwright\";\n if (/[\\/]wdio[\\/\\-]|[\\/]webdriver[\\/\\-]/.test(pathLower)) return \"webdriverio\";\n if (/[\\/]appium[\\/\\-]/.test(pathLower)) return \"appium\";\n if (/[\\/]selenium-python[\\/]|[\\/]pytest[\\/\\-]/.test(pathLower)) return \"pytest\";\n if (/[\\/]robot[\\/\\-]/.test(pathLower)) return \"robot\";\n if (/[\\/]codecept[\\/\\-]/.test(pathLower)) return \"codeceptjs\";\n if (/[\\/]nightwatch[\\/\\-]/.test(pathLower)) return \"nightwatch\";\n if (/[\\/]testcafe[\\/\\-]/.test(pathLower)) return \"testcafe\";\n if (/[\\/]puppeteer[\\/\\-]/.test(pathLower)) return \"puppeteer\";\n if (/[\\/]behave[\\/\\-]|[\\/]features[\\/]/.test(pathLower)) return \"behave\";\n // Fallback: inferir pela extensão do arquivo\n if (/\\.cy\\.(js|ts|jsx|tsx)/i.test(name)) return \"cypress\";\n if (/_test\\.(js|ts)$/i.test(name)) return \"codeceptjs\";\n if (/\\.spec\\.(js|ts|jsx|tsx)/i.test(name)) {\n if (structure?.testFrameworks?.includes(\"webdriverio\")) return \"webdriverio\";\n if (structure?.testFrameworks?.includes(\"appium\")) return \"appium\";\n return \"playwright\";\n }\n if (/\\.test\\.(js|ts|jsx|tsx)/i.test(name)) return structure?.testFrameworks?.includes(\"vitest\") ? \"vitest\" : \"jest\";\n if (/\\.robot$/i.test(name)) return \"robot\";\n if (/\\.feature$/i.test(name)) return \"behave\";\n if (/\\.(py|steps?\\.py)$/i.test(name) || /^(test_.*|.*_test)\\.py$/i.test(name)) return \"pytest\";\n if (/\\.e2e\\.(js|ts)/i.test(name)) return \"playwright\";\n return \"unknown\";\n}\n\nfunction matchesFramework(inferred, requested) {\n const aliases = { spec: [\"playwright\", \"webdriverio\", \"appium\"] };\n if (inferred === requested) return true;\n return aliases[inferred]?.includes(requested);\n}\n\nfunction getFrameworkCwd(structure, preferredDirs) {\n for (const dir of preferredDirs) {\n if (structure.testDirs.includes(dir)) {\n return path.join(PROJECT_ROOT, dir);\n }\n }\n const fallback = structure.testDirs[0];\n return fallback ? path.join(PROJECT_ROOT, fallback) : PROJECT_ROOT;\n}\n\n// ============================================================================\n// MÉTRICAS DE NEGÓCIO - Helpers (FLOWS_CONFIG_FILE definido acima)\n// ============================================================================\n\nconst METRICS_FILE = path.join(PROJECT_ROOT, \".qa-lab-metrics.json\");\n\nfunction parseTestRunResult(runOutput, exitCode) {\n let passed = 0;\n let failed = 0;\n const jestMatch = runOutput.match(/Tests:\\s+(\\d+)\\s+passed(?:,\\s*(\\d+)\\s+failed)?/);\n if (jestMatch) {\n passed = parseInt(jestMatch[1], 10);\n failed = jestMatch[2] ? parseInt(jestMatch[2], 10) : 0;\n }\n const cypressPass = runOutput.match(/(\\d+)\\s+passing/);\n const cypressFail = runOutput.match(/(\\d+)\\s+failing/);\n if (cypressPass) passed = parseInt(cypressPass[1], 10);\n if (cypressFail) failed = parseInt(cypressFail[1], 10);\n const pwPass = runOutput.match(/(\\d+)\\s+passed/);\n const pwFail = runOutput.match(/(\\d+)\\s+failed/);\n if (pwPass) passed = parseInt(pwPass[1], 10);\n if (pwFail) failed = parseInt(pwFail[1], 10);\n if (passed === 0 && failed === 0) {\n if (exitCode === 0) passed = 1;\n else failed = 1;\n }\n return { passed, failed };\n}\n\nfunction appendMetricsEvent(event) {\n try {\n let data = { events: [], lastUpdated: new Date().toISOString() };\n if (fs.existsSync(METRICS_FILE)) {\n const raw = fs.readFileSync(METRICS_FILE, \"utf8\");\n try {\n data = JSON.parse(raw);\n } catch {}\n }\n data.events = data.events || [];\n data.events.push({ ...event, timestamp: event.timestamp || new Date().toISOString() });\n data.lastUpdated = new Date().toISOString();\n if (data.events.length > 500) data.events = data.events.slice(-400);\n fs.writeFileSync(METRICS_FILE, JSON.stringify(data, null, 2), \"utf8\");\n } catch {}\n}\n\nfunction extractFailuresFromOutput(runOutput) {\n const failures = [];\n const lines = runOutput.split(\"\\n\");\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n if (/fail|error|assertion|timeout|element not found|selector/i.test(line)) {\n failures.push({\n test: lines[Math.max(0, i - 1)]?.trim() || \"unknown\",\n message: line.trim().slice(0, 500),\n });\n }\n }\n return failures.slice(0, 20);\n}\n\n// ============================================================================\n// FERRAMENTAS GENÉRICAS\n// ============================================================================\n\nserver.registerTool(\n \"read_file\",\n {\n title: \"Ler qualquer arquivo\",\n description: \"Lê o conteúdo de QUALQUER arquivo do projeto por caminho. Use para specs, page objects, componentes, código fonte - qualquer formato.\",\n inputSchema: z.object({\n path: z.string().describe(\"Caminho relativo ao projeto (ex: cypress/e2e/login.cy.js, src/pages/Login.tsx, tests/login.robot).\"),\n encoding: z.enum([\"utf8\", \"utf-8\"]).optional().describe(\"Encoding. Default: utf8\"),\n }),\n outputSchema: z.object({\n ok: z.boolean(),\n content: z.string().optional(),\n error: z.string().optional(),\n }),\n },\n async ({ path: filePath, encoding = \"utf8\" }) => {\n const normalized = filePath.replace(/^\\//, \"\").replace(/\\\\/g, \"/\");\n const fullPath = path.join(PROJECT_ROOT, normalized);\n\n if (!fullPath.startsWith(PROJECT_ROOT)) {\n return {\n content: [{ type: \"text\", text: \"Caminho fora do projeto.\" }],\n structuredContent: { ok: false, error: \"Path outside project\" },\n };\n }\n if (!fs.existsSync(fullPath)) {\n return {\n content: [{ type: \"text\", text: `Arquivo não encontrado: ${normalized}` }],\n structuredContent: { ok: false, error: \"File not found\" },\n };\n }\n const stat = fs.statSync(fullPath);\n if (stat.isDirectory()) {\n return {\n content: [{ type: \"text\", text: \"É um diretório. Use um caminho de arquivo.\" }],\n structuredContent: { ok: false, error: \"Is directory\" },\n };\n }\n\n try {\n const content = fs.readFileSync(fullPath, encoding);\n return {\n content: [{ type: \"text\", text: content }],\n structuredContent: { ok: true, content },\n };\n } catch (err) {\n return {\n content: [{ type: \"text\", text: `Erro ao ler: ${err.message}` }],\n structuredContent: { ok: false, error: err.message },\n };\n }\n }\n);\n\nserver.registerTool(\n \"detect_project\",\n {\n title: \"Detectar estrutura do projeto\",\n description: \"Analisa o projeto e identifica frameworks de teste, pastas, backend, frontend.\",\n inputSchema: z.object({}),\n outputSchema: z.object({\n ok: z.boolean(),\n structure: z.object({\n hasTests: z.boolean(),\n testFrameworks: z.array(z.string()),\n testDirs: z.array(z.string()),\n hasBackend: z.boolean(),\n backendDir: z.string().nullable(),\n hasFrontend: z.boolean(),\n frontendDir: z.string().nullable(),\n }),\n }),\n },\n async () => {\n const structure = detectProjectStructure();\n const summary = [\n `Frameworks de teste: ${structure.testFrameworks.join(\", \") || \"nenhum\"}`,\n `Pastas de teste: ${structure.testDirs.join(\", \") || \"nenhuma\"}`,\n `Backend: ${structure.backendDir || \"não detectado\"}`,\n `Frontend: ${structure.frontendDir || \"não detectado\"}`,\n ].join(\"\\n\");\n\n return {\n content: [{ type: \"text\", text: summary }],\n structuredContent: { ok: true, structure },\n };\n }\n);\n\n// ============================================================================\n// WEB EVAL BROWSER - Modo browser (screenshots, network, console) via Playwright\n// ============================================================================\n\nserver.registerTool(\n \"web_eval_browser\",\n {\n title: \"Avaliar app no browser (screenshots, network, console)\",\n description: \"[Agente especializado: Browser] Abre a URL no navegador, captura screenshot, erros de console e requisições de rede. Inspirado em web-eval-agent. Requer: npm install playwright\",\n inputSchema: z.object({\n url: z.string().describe(\"URL para avaliar (ex: http://localhost:3000, https://exemplo.com).\"),\n screenshotPath: z.string().optional().describe(\"Caminho para salvar screenshot. Default: .qa-lab-screenshot.png\"),\n captureNetwork: z.boolean().optional().describe(\"Capturar requisições de rede. Default: true\"),\n captureConsole: z.boolean().optional().describe(\"Capturar logs e erros do console. Default: true\"),\n }),\n outputSchema: z.object({\n ok: z.boolean(),\n screenshotPath: z.string().optional(),\n consoleLogs: z.array(z.string()).optional(),\n consoleErrors: z.array(z.string()).optional(),\n networkRequests: z.array(z.object({ url: z.string(), method: z.string(), status: z.number().optional() })).optional(),\n error: z.string().optional(),\n }),\n },\n async ({ url, screenshotPath, captureNetwork = true, captureConsole = true }) => {\n let playwright;\n try {\n playwright = await import(\"playwright\");\n } catch (e) {\n return {\n content: [{\n type: \"text\",\n text: \"Playwright não instalado. Rode: npm install playwright (ou npx playwright install para browsers).\",\n }],\n structuredContent: { ok: false, error: \"Playwright not installed. Run: npm install playwright\" },\n };\n }\n\n const outPath = screenshotPath ? path.join(PROJECT_ROOT, screenshotPath.replace(/^\\//, \"\")) : path.join(PROJECT_ROOT, \".qa-lab-screenshot.png\");\n const consoleLogs = [];\n const consoleErrors = [];\n const networkRequests = [];\n\n try {\n const browser = await playwright.chromium.launch({ headless: true });\n const context = await browser.newContext();\n const page = await context.newPage();\n\n if (captureConsole) {\n page.on(\"console\", (msg) => {\n const text = msg.text();\n if (msg.type() === \"error\") consoleErrors.push(text);\n else consoleLogs.push(`[${msg.type()}] ${text}`);\n });\n }\n\n if (captureNetwork) {\n page.on(\"request\", (req) => {\n networkRequests.push({ url: req.url(), method: req.method(), status: undefined });\n });\n page.on(\"response\", (res) => {\n const req = networkRequests.find((r) => r.url === res.request().url());\n if (req) req.status = res.status();\n });\n }\n\n await page.goto(url, { waitUntil: \"networkidle\", timeout: 30000 });\n await page.screenshot({ path: outPath, fullPage: false });\n\n await browser.close();\n\n const relPath = path.relative(PROJECT_ROOT, outPath);\n let summary = `Screenshot salvo: ${relPath}`;\n if (consoleErrors.length) summary += `\\n\\n⚠️ ${consoleErrors.length} erro(s) no console:\\n${consoleErrors.slice(0, 5).join(\"\\n\")}`;\n if (networkRequests.length) summary += `\\n\\nRequisições: ${networkRequests.length}`;\n\n return {\n content: [{ type: \"text\", text: summary }],\n structuredContent: {\n ok: true,\n screenshotPath: relPath,\n consoleLogs: captureConsole ? consoleLogs.slice(0, 50) : undefined,\n consoleErrors: captureConsole && consoleErrors.length ? consoleErrors : undefined,\n networkRequests: captureNetwork ? networkRequests.slice(0, 30) : undefined,\n },\n };\n } catch (err) {\n return {\n content: [{ type: \"text\", text: `Erro: ${err.message}` }],\n structuredContent: { ok: false, error: err.message },\n };\n }\n }\n);\n\n// ============================================================================\n// QA ROUTE TASK - Agentes especializados (roteamento de tarefas)\n// ============================================================================\n\nconst QA_AGENTS = {\n autonomous: { tools: [\"qa_auto\"], desc: \"Modo autônomo: gera, roda, corrige e aprende (loop completo)\" },\n detection: { tools: [\"detect_project\", \"read_project\", \"list_test_files\"], desc: \"Detecção de estrutura, frameworks e arquivos\" },\n execution: { tools: [\"run_tests\", \"watch_tests\", \"get_test_coverage\"], desc: \"Execução de testes e cobertura\" },\n generation: { tools: [\"generate_tests\", \"write_test\", \"create_test_template\"], desc: \"Geração de testes com LLM\" },\n analysis: { tools: [\"analyze_failures\", \"por_que_falhou\", \"suggest_fix\", \"suggest_selector_fix\"], desc: \"Análise de falhas e sugestões\" },\n browser: { tools: [\"web_eval_browser\"], desc: \"Avaliação em browser real (screenshots, network, console)\" },\n reporting: { tools: [\"create_bug_report\", \"get_business_metrics\"], desc: \"Relatórios e métricas\" },\n learning: { tools: [\"qa_learning_stats\"], desc: \"Estatísticas de aprendizado e evolução\" },\n maintenance: { tools: [\"run_linter\", \"install_dependencies\", \"analyze_file_methods\"], desc: \"Manutenção e análise de código\" },\n};\n\nserver.registerTool(\n \"qa_route_task\",\n {\n title: \"Roteador de tarefas QA (agentes especializados)\",\n description: \"Recebe uma descrição da tarefa e retorna qual agente (conjunto de ferramentas) deve ser usado. Útil para encaminhar a ferramenta certa.\",\n inputSchema: z.object({\n task: z.string().describe(\"Descrição da tarefa (ex: 'rodar os testes', 'gerar teste de login', 'analisar por que falhou').\"),\n }),\n outputSchema: z.object({\n ok: z.boolean(),\n suggestedAgent: z.string(),\n suggestedTools: z.array(z.string()),\n description: z.string(),\n }),\n },\n async ({ task }) => {\n const t = task.toLowerCase();\n if (/autônomo|auto|completo|loop|aprende|corrige automaticamente/i.test(t)) {\n return { content: [{ type: \"text\", text: \"Agente: autonomous → qa_auto (loop completo: gera, roda, corrige, aprende)\" }], structuredContent: { ok: true, suggestedAgent: \"autonomous\", suggestedTools: QA_AGENTS.autonomous.tools, description: QA_AGENTS.autonomous.desc } };\n }\n if (/estatística|métrica de aprendizado|taxa de sucesso|learning|stats/i.test(t)) {\n return { content: [{ type: \"text\", text: \"Agente: learning → qa_learning_stats\" }], structuredContent: { ok: true, suggestedAgent: \"learning\", suggestedTools: QA_AGENTS.learning.tools, description: QA_AGENTS.learning.desc } };\n }\n if (/rodar|executar|run|test|coverage|watch/i.test(t)) {\n return { content: [{ type: \"text\", text: \"Agente: execution → run_tests, get_test_coverage\" }], structuredContent: { ok: true, suggestedAgent: \"execution\", suggestedTools: QA_AGENTS.execution.tools, description: QA_AGENTS.execution.desc } };\n }\n if (/gerar|criar|escrever|generate|write|template/i.test(t)) {\n return { content: [{ type: \"text\", text: \"Agente: generation → generate_tests, write_test\" }], structuredContent: { ok: true, suggestedAgent: \"generation\", suggestedTools: QA_AGENTS.generation.tools, description: QA_AGENTS.generation.desc } };\n }\n if (/analisar|por que|falhou|suggest|correção|selector|fix/i.test(t)) {\n return { content: [{ type: \"text\", text: \"Agente: analysis → analyze_failures, por_que_falhou, suggest_fix\" }], structuredContent: { ok: true, suggestedAgent: \"analysis\", suggestedTools: QA_AGENTS.analysis.tools, description: QA_AGENTS.analysis.desc } };\n }\n if (/browser|screenshot|navegador|avaliar|ux|network|console/i.test(t)) {\n return { content: [{ type: \"text\", text: \"Agente: browser → web_eval_browser\" }], structuredContent: { ok: true, suggestedAgent: \"browser\", suggestedTools: QA_AGENTS.browser.tools, description: QA_AGENTS.browser.desc } };\n }\n if (/detectar|estrutura|listar|arquivos|framework/i.test(t)) {\n return { content: [{ type: \"text\", text: \"Agente: detection → detect_project, list_test_files\" }], structuredContent: { ok: true, suggestedAgent: \"detection\", suggestedTools: QA_AGENTS.detection.tools, description: QA_AGENTS.detection.desc } };\n }\n if (/relatório|bug|métricas|metrics|coverage/i.test(t)) {\n return { content: [{ type: \"text\", text: \"Agente: reporting → create_bug_report, get_business_metrics\" }], structuredContent: { ok: true, suggestedAgent: \"reporting\", suggestedTools: QA_AGENTS.reporting.tools, description: QA_AGENTS.reporting.desc } };\n }\n return { content: [{ type: \"text\", text: \"Agente: detection (genérico)\" }], structuredContent: { ok: true, suggestedAgent: \"detection\", suggestedTools: QA_AGENTS.detection.tools, description: QA_AGENTS.detection.desc } };\n }\n);\n\nserver.registerTool(\n \"run_tests\",\n {\n title: \"Executar testes\",\n description: \"Roda testes do projeto. Suporta: Cypress, Playwright, WebdriverIO, Jest, Vitest, Mocha, Appium, Detox, Robot Framework, pytest, e mais. Detecta automaticamente.\",\n inputSchema: z.object({\n framework: z.enum([\n \"cypress\", \"playwright\", \"webdriverio\", \"jest\", \"vitest\", \"mocha\",\n \"appium\", \"detox\", \"robot\", \"pytest\", \"supertest\", \"pactum\",\n \"testcafe\", \"nightwatch\", \"puppeteer\", \"codeceptjs\", \"npm\"\n ]).optional().describe(\"Framework específico ou 'npm' para npm test.\"),\n spec: z.string().optional().describe(\"Caminho do spec (ex: cypress/e2e/test.cy.js).\"),\n suite: z.string().optional().describe(\"Suite ou pattern (ex: e2e, api).\"),\n explainOnFailure: z.boolean().optional().describe(\"Se true, quando falhar gera automaticamente: O que aconteceu, Por que falhou, O que fazer, Sugestão de correção. Requer API key.\"),\n }),\n outputSchema: z.object({\n status: z.enum([\"passed\", \"failed\", \"not_found\"]),\n message: z.string(),\n exitCode: z.number(),\n runOutput: z.string().optional(),\n }),\n },\n async ({ framework, spec, suite, explainOnFailure }) => {\n const structure = detectProjectStructure();\n \n if (!structure.hasTests) {\n return {\n content: [{ type: \"text\", text: \"Nenhum framework de teste detectado no projeto.\" }],\n structuredContent: {\n status: \"not_found\",\n message: \"No test framework found\",\n exitCode: 1,\n },\n };\n }\n\n let selectedFramework = framework;\n if (!selectedFramework && structure.testFrameworks.length > 0) {\n selectedFramework = structure.testFrameworks[0];\n }\n\n let cmd, args, cwd;\n\n // E2E/UI Frameworks\n if (selectedFramework === \"cypress\") {\n cmd = \"npx\";\n args = spec ? [\"cypress\", \"run\", \"--spec\", spec] : [\"cypress\", \"run\"];\n cwd = structure.testDirs.includes(\"cypress\") \n ? path.join(PROJECT_ROOT, \"cypress\")\n : structure.testDirs[0] \n ? path.join(PROJECT_ROOT, structure.testDirs[0])\n : PROJECT_ROOT;\n } else if (selectedFramework === \"playwright\") {\n cmd = \"npx\";\n args = spec ? [\"playwright\", \"test\", spec] : [\"playwright\", \"test\"];\n cwd = structure.testDirs.includes(\"playwright\")\n ? path.join(PROJECT_ROOT, \"playwright\")\n : structure.testDirs[0]\n ? path.join(PROJECT_ROOT, structure.testDirs[0])\n : PROJECT_ROOT;\n } else if (selectedFramework === \"webdriverio\") {\n cmd = \"npx\";\n args = spec ? [\"wdio\", \"run\", spec] : [\"wdio\", \"run\"];\n cwd = getFrameworkCwd(structure, [\"wdio-webdriver-io\", \"specs\", \"tests\"]);\n } else if (selectedFramework === \"testcafe\") {\n cmd = \"npx\";\n args = spec ? [\"testcafe\", spec] : [\"testcafe\"];\n cwd = getFrameworkCwd(structure, [\"testcafe-js\", \"testcafe\", \"tests\"]);\n } else if (selectedFramework === \"nightwatch\") {\n cmd = \"npx\";\n args = spec ? [\"nightwatch\", \"--test\", spec] : [\"nightwatch\"];\n cwd = getFrameworkCwd(structure, [\"nightwatch-js\", \"nightwatch\", \"tests\"]);\n } else if (selectedFramework === \"puppeteer\") {\n cmd = \"npx\";\n args = spec ? [\"jest\", spec, \"--config\", \"jest.config.js\"] : [\"jest\"];\n cwd = getFrameworkCwd(structure, [\"puppeteer-js\", \"puppeteer\", \"__tests__\"]);\n } else if (selectedFramework === \"codeceptjs\") {\n cmd = \"npx\";\n args = spec ? [\"codeceptjs\", \"run\", \"--grep\", spec] : [\"codeceptjs\", \"run\"];\n cwd = getFrameworkCwd(structure, [\"codeceptjs\", \"tests\"]);\n\n // Unit/Integration Frameworks\n } else if (selectedFramework === \"jest\") {\n cmd = \"npx\";\n args = [\"jest\"];\n if (spec) args.push(spec);\n cwd = PROJECT_ROOT;\n } else if (selectedFramework === \"vitest\") {\n cmd = \"npx\";\n args = [\"vitest\", \"run\"];\n if (spec) args.push(spec);\n cwd = PROJECT_ROOT;\n } else if (selectedFramework === \"mocha\") {\n cmd = \"npx\";\n args = spec ? [\"mocha\", spec] : [\"mocha\"];\n cwd = PROJECT_ROOT;\n \n // Mobile Frameworks\n } else if (selectedFramework === \"appium\") {\n cmd = \"npx\";\n args = spec ? [\"wdio\", \"run\", spec] : [\"wdio\", \"run\"];\n cwd = PROJECT_ROOT;\n } else if (selectedFramework === \"detox\") {\n cmd = \"npx\";\n args = [\"detox\", \"test\"];\n if (spec) args.push(spec);\n cwd = PROJECT_ROOT;\n \n // Python Frameworks\n } else if (selectedFramework === \"robot\") {\n cmd = \"robot\";\n args = spec ? [spec] : [structure.testDirs[0] || \"tests\"];\n cwd = PROJECT_ROOT;\n } else if (selectedFramework === \"pytest\") {\n cmd = \"pytest\";\n args = spec ? [spec] : [];\n cwd = PROJECT_ROOT;\n \n // API Testing\n } else if (selectedFramework === \"supertest\" || selectedFramework === \"pactum\") {\n cmd = \"npm\";\n args = [\"test\"];\n cwd = PROJECT_ROOT;\n \n // Fallback\n } else {\n cmd = \"npm\";\n args = [\"test\"];\n cwd = PROJECT_ROOT;\n }\n\n const startTime = Date.now();\n return new Promise((resolve) => {\n const child = spawn(cmd, args, {\n cwd,\n stdio: [\"inherit\", \"pipe\", \"pipe\"],\n shell: process.platform === \"win32\",\n env: { ...process.env },\n });\n\n let stdout = \"\";\n let stderr = \"\";\n if (child.stdout) {\n child.stdout.on(\"data\", (d) => {\n const s = d.toString();\n stdout += s;\n process.stdout.write(s);\n });\n }\n if (child.stderr) {\n child.stderr.on(\"data\", (d) => {\n const s = d.toString();\n stderr += s;\n process.stderr.write(s);\n });\n }\n\n child.on(\"close\", (code) => {\n const runOutput = [stdout, stderr].filter(Boolean).join(\"\\n\").trim();\n const passed = code === 0;\n const durationSeconds = Math.round((Date.now() - startTime) / 1000);\n if (!passed && runOutput) {\n try {\n fs.writeFileSync(path.join(PROJECT_ROOT, \".qa-lab-last-failure.log\"), runOutput, \"utf8\");\n } catch {}\n }\n const { passed: p, failed: f } = parseTestRunResult(runOutput, code);\n appendMetricsEvent({\n type: \"test_run\",\n framework: selectedFramework,\n spec: spec || undefined,\n passed: p,\n failed: f,\n durationSeconds,\n exitCode: code ?? 1,\n failures: !passed ? extractFailuresFromOutput(runOutput) : undefined,\n });\n if (passed) saveProjectMemory({ lastRun: { spec: spec || null, framework: selectedFramework, passed: p } });\n resolve({\n content: [{ type: \"text\", text: passed ? \"Testes executados com sucesso.\" : \"Falha na execução dos testes.\" }],\n structuredContent: {\n status: passed ? \"passed\" : \"failed\",\n message: passed ? \"Tests passed\" : \"Tests failed\",\n exitCode: code ?? 1,\n runOutput: !passed ? runOutput : undefined,\n },\n });\n });\n });\n }\n);\n\nserver.registerTool(\n \"read_project\",\n {\n title: \"Ler estrutura do projeto\",\n description: \"Lê package.json, specs existentes (qualquer framework: Cypress, Playwright, WDIO, Robot, pytest, etc) e retorna contexto. Use includeContent para trazer código de exemplos.\",\n inputSchema: z.object({\n includeContent: z.boolean().optional().describe(\"Se true, inclui conteúdo dos primeiros 3 arquivos de teste como referência. Default: false.\"),\n maxFiles: z.number().optional().describe(\"Máximo de arquivos cujo conteúdo será lido. Default: 3.\"),\n }),\n outputSchema: z.object({\n ok: z.boolean(),\n summary: z.string(),\n packageJson: z.object({}).passthrough().optional(),\n testFiles: z.array(z.string()).optional(),\n testFilesWithContent: z.array(z.object({ path: z.string(), content: z.string() })).optional(),\n }),\n },\n async ({ includeContent = false, maxFiles = 3 } = {}) => {\n const structure = detectProjectStructure();\n const collected = collectTestFiles(structure, {\n maxContentFiles: includeContent ? maxFiles : 0,\n });\n\n const testFiles = collected.map((e) => e.path);\n const testFilesWithContent = includeContent\n ? collected.filter((e) => e.content).map((e) => ({ path: e.path, content: e.content }))\n : undefined;\n\n const summary = [\n `Frameworks: ${structure.testFrameworks.join(\", \") || \"nenhum\"}`,\n `Arquivos de teste: ${testFiles.length} (qualquer framework)`,\n `Backend: ${structure.backendDir || \"não detectado\"}`,\n `Frontend: ${structure.frontendDir || \"não detectado\"}`,\n includeContent && testFilesWithContent?.length\n ? `Conteúdo incluído: ${testFilesWithContent.length} arquivo(s) como referência`\n : \"\",\n ]\n .filter(Boolean)\n .join(\"\\n\");\n\n return {\n content: [{ type: \"text\", text: summary }],\n structuredContent: {\n ok: true,\n summary,\n packageJson: structure.packageJson,\n testFiles: testFiles.slice(0, 100),\n testFilesWithContent,\n structure,\n },\n };\n }\n);\n\nserver.registerTool(\n \"generate_tests\",\n {\n title: \"Gerar ou traduzir testes com LLM\",\n description: \"Gera spec em QUALQUER framework. Aceita referência de outro framework: leia com read_file e passe em referenceCode. Traduz automaticamente (ex: Robot→Playwright, Cypress→WDIO).\",\n inputSchema: z.object({\n context: z.string().describe(\"Contexto do projeto (read_project) ou descrição.\"),\n request: z.string().describe(\"O que testar (ex: 'logout flow', 'teste de login') ou 'traduzir o teste abaixo'.\"),\n framework: z.enum([\n \"cypress\", \"playwright\", \"webdriverio\", \"jest\", \"vitest\", \"mocha\",\n \"appium\", \"robot\", \"pytest\", \"supertest\", \"behave\", \"detox\"\n ]).optional().describe(\"Framework alvo (detectado do projeto se omitido).\"),\n referenceCode: z.string().optional().describe(\"Código de referência em QUALQUER framework (Cypress, Robot, WDIO, etc). O LLM traduz/adapta para o framework alvo.\"),\n referencePaths: z.array(z.string()).optional().describe(\"Caminhos de arquivos para ler como referência. O agente lê e usa como padrão.\"),\n }),\n outputSchema: z.object({\n ok: z.boolean(),\n specContent: z.string().optional(),\n suggestedFileName: z.string().optional(),\n error: z.string().optional(),\n }),\n },\n async ({ context, request, framework, referenceCode, referencePaths }) => {\n const structure = detectProjectStructure();\n const fw = framework || structure.testFrameworks[0] || \"cypress\";\n\n let referenceBlock = \"\";\n if (referenceCode) referenceBlock += `\\n\\n--- CÓDIGO DE REFERÊNCIA (use como padrão, traduza/adapte para ${fw}) ---\\n${referenceCode.slice(0, 8000)}`;\n if (referencePaths?.length) {\n for (const p of referencePaths.slice(0, 5)) {\n const full = path.join(PROJECT_ROOT, p.replace(/^\\//, \"\").replace(/\\\\/g, \"/\"));\n if (fs.existsSync(full)) {\n try {\n const content = fs.readFileSync(full, \"utf8\");\n referenceBlock += `\\n\\n--- Arquivo: ${p} ---\\n${content.slice(0, 6000)}`;\n } catch {}\n }\n }\n }\n\n const llm = resolveLLMProvider(\"simple\");\n if (!llm.apiKey) {\n return {\n content: [{ type: \"text\", text: \"Configure GROQ_API_KEY, GEMINI_API_KEY ou OPENAI_API_KEY no .env\" }],\n structuredContent: { ok: false, error: \"No API key configured\" },\n };\n }\n const { provider, apiKey, baseUrl, model } = llm;\n\n const memory = loadProjectMemory();\n const memoryBlock = memory.flows?.length\n ? `\\n\\nFluxos do projeto (use como referência): ${memory.flows.map((f) => f.name || f.id).join(\", \")}`\n : \"\";\n const contextWithMemory = context + memoryBlock;\n\n const hasReference = Boolean(referenceBlock?.trim());\n const systemPrompt = hasReference\n ? `Você é um engenheiro de QA. TRADUZA/ADAPTE o código de referência para o framework ${fw}.\nO código de referência pode estar em QUALQUER framework (Cypress, Robot, Playwright, WDIO, Appium, pytest, etc).\n- Mantenha a MESMA lógica e fluxo de teste\n- Traduza seletores, comandos e asserções para ${fw}\n- Use Page Objects se o projeto já usa\n- Retorne SOMENTE o código, sem markdown`\n : `Você é um engenheiro de QA especializado em ${fw}. Gere APENAS o código do spec, sem explicações.\nFramework: ${fw}\nRegras:\n- Cypress: cy.request(), cy.visit(), cy.get()\n- Playwright: test(), test.describe(), page.goto(), page.locator()\n- WebdriverIO/Appium: describe(), it(), $(), browser.$\n- Jest/Vitest: describe(), test(), expect()\n- Robot: Keywords, [Tags], Steps\n- pytest: def test_*, assert, fixtures\n- Código limpo. Retorne SOMENTE o código, sem markdown`;\n\n const userPrompt = `Contexto do projeto:\n${contextWithMemory.slice(0, 5000)}\n\nGere um teste para: ${request}\nFramework alvo: ${fw}${referenceBlock}`;\n\n try {\n let specContent;\n if (provider === \"gemini\") {\n const url = `${baseUrl}/models/${model}:generateContent?key=${apiKey}`;\n const res = await fetch(url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n systemInstruction: { parts: [{ text: systemPrompt }] },\n contents: [{ parts: [{ text: userPrompt }] }],\n generationConfig: { temperature: 0.3, maxOutputTokens: 4096 },\n }),\n });\n const data = await res.json();\n specContent = data.candidates?.[0]?.content?.parts?.[0]?.text || \"\";\n } else {\n const res = await fetch(`${baseUrl}/chat/completions`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${apiKey}`,\n },\n body: JSON.stringify({\n model,\n messages: [\n { role: \"system\", content: systemPrompt },\n { role: \"user\", content: userPrompt },\n ],\n temperature: 0.3,\n max_tokens: 4096,\n }),\n });\n const data = await res.json();\n specContent = data.choices?.[0]?.message?.content || \"\";\n }\n\n specContent = specContent.replace(/^```(?:js|javascript)?\\n?/i, \"\").replace(/\\n?```\\s*$/i, \"\").trim();\n const fileName = request.toLowerCase().replace(/\\s+/g, \"-\").replace(/[^a-z0-9-]/g, \"\").slice(0, 40);\n\n return {\n content: [{ type: \"text\", text: `Spec gerado (${specContent.length} chars). Use write_test para gravar.` }],\n structuredContent: {\n ok: true,\n specContent,\n suggestedFileName: fileName,\n },\n };\n } catch (err) {\n return {\n content: [{ type: \"text\", text: `Erro ao gerar: ${err.message}` }],\n structuredContent: { ok: false, error: err.message },\n };\n }\n }\n);\n\nfunction getExtensionAndBaseDir(fw, structure) {\n const extMap = {\n cypress: \".cy.js\",\n playwright: \".spec.js\",\n jest: \".test.js\",\n vitest: \".test.js\",\n mocha: \".test.js\",\n webdriverio: \".spec.js\",\n appium: \".spec.js\",\n detox: \".e2e.js\",\n robot: \".robot\",\n pytest: \"_test.py\",\n behave: \".feature\",\n supertest: \".test.js\",\n pactum: \".test.js\",\n };\n const ext = extMap[fw] || \".spec.js\";\n\n const baseMap = {\n cypress: structure.testDirs.includes(\"cypress\") ? \"cypress\" : structure.testDirs[0] || \"tests\",\n playwright: structure.testDirs.includes(\"playwright\") ? \"playwright\" : structure.testDirs[0] || \"tests\",\n webdriverio: structure.testDirs.includes(\"specs\") ? \"specs\" : structure.testDirs[0] || \"tests\",\n appium: structure.testDirs.includes(\"specs\") ? \"specs\" : structure.testDirs[0] || \"tests\",\n robot: structure.testDirs.includes(\"robot\") ? \"robot\" : structure.testDirs[0] || \"tests\",\n behave: structure.testDirs.includes(\"features\") ? \"features\" : structure.testDirs[0] || \"tests\",\n };\n const baseDir = path.join(PROJECT_ROOT, baseMap[fw] || structure.testDirs[0] || \"tests\");\n return { ext, baseDir };\n}\n\nserver.registerTool(\n \"write_test\",\n {\n title: \"Escrever arquivo de teste\",\n description: \"Grava spec no disco. Suporta QUALQUER framework (Cypress, Playwright, WDIO, Appium, Robot, pytest, etc.). Detecta automaticamente pasta e extensão.\",\n inputSchema: z.object({\n name: z.string().describe(\"Nome do arquivo (ex: login-test, logout_spec).\"),\n content: z.string().describe(\"Conteúdo do spec.\"),\n framework: z.enum([\n \"cypress\", \"playwright\", \"jest\", \"vitest\", \"mocha\", \"webdriverio\",\n \"appium\", \"detox\", \"robot\", \"pytest\", \"behave\", \"supertest\"\n ]).optional().describe(\"Framework (detectado automaticamente se omitido).\"),\n subdir: z.string().optional().describe(\"Subpasta (ex: e2e, api). Default: raiz da pasta de testes.\"),\n }),\n outputSchema: z.object({\n ok: z.boolean(),\n path: z.string().optional(),\n error: z.string().optional(),\n }),\n },\n async ({ name, content, framework, subdir }) => {\n const structure = detectProjectStructure();\n const fw = framework || structure.testFrameworks[0];\n\n if (!fw) {\n return {\n content: [{ type: \"text\", text: \"Nenhum framework de teste detectado.\" }],\n structuredContent: { ok: false, error: \"No test framework\" },\n };\n }\n\n const { ext, baseDir } = getExtensionAndBaseDir(fw, structure);\n const safeName = name\n .replace(/[^a-z0-9-_]/gi, \"-\")\n .replace(/-+/g, \"-\")\n .replace(/_+/g, \"_\")\n .replace(/\\.(cy|spec|test|robot|feature|py)\\.?(js|ts|py)?$/i, \"\")\n .replace(/^[-_]+|[-_]+$/g, \"\");\n const fileName = ext.startsWith(\"_\") ? `${safeName}${ext}` : `${safeName}${ext}`;\n\n const targetDir = subdir ? path.join(baseDir, subdir) : baseDir;\n const filePath = path.join(targetDir, fileName);\n\n try {\n if (!fs.existsSync(targetDir)) {\n fs.mkdirSync(targetDir, { recursive: true });\n }\n fs.writeFileSync(filePath, content, \"utf8\");\n return {\n content: [{ type: \"text\", text: `Arquivo gravado: ${filePath}` }],\n structuredContent: { ok: true, path: filePath },\n };\n } catch (err) {\n return {\n content: [{ type: \"text\", text: `Erro ao gravar: ${err.message}` }],\n structuredContent: { ok: false, error: err.message },\n };\n }\n }\n);\n\nserver.registerTool(\n \"analyze_failures\",\n {\n title: \"Analisar falhas de testes\",\n description: \"Recebe output de testes e extrai falhas estruturadas.\",\n inputSchema: z.object({\n runOutput: z.string().describe(\"Output do teste (stdout/stderr).\"),\n }),\n outputSchema: z.object({\n ok: z.boolean(),\n summary: z.string(),\n failures: z.array(z.object({\n test: z.string().optional(),\n message: z.string().optional(),\n stack: z.string().optional(),\n })).optional(),\n }),\n },\n async ({ runOutput }) => {\n const failures = [];\n const lines = runOutput.split(\"\\n\");\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n if (/fail|error|assertion/i.test(line)) {\n failures.push({\n test: lines[i - 1] || \"unknown\",\n message: line.trim(),\n stack: lines.slice(i, i + 5).join(\"\\n\"),\n });\n }\n }\n\n const flakyAnalysis = detectFlakyPatterns(runOutput);\n let summary = failures.length\n ? `${failures.length} falha(s) detectada(s).`\n : \"Nenhuma falha detectada.\";\n if (flakyAnalysis.isLikelyFlaky) {\n summary += `\\n\\n⚠️ Possível teste flaky (${Math.round(flakyAnalysis.confidence * 100)}% confiança). Padrões: ${flakyAnalysis.patterns.map((p) => p.pattern).join(\", \")}.`;\n summary += \"\\n\\nSugestões:\";\n flakyAnalysis.patterns.forEach((p) => {\n summary += `\\n• ${p.pattern}: ${p.suggestion}`;\n });\n if (flakyAnalysis.patterns.some((p) => p.pattern === \"timing\" || p.pattern === \"network\")) {\n summary += \"\\n• Considere adicionar test.retry(2) ou equivalente para retries automáticos.\";\n }\n }\n\n return {\n content: [{ type: \"text\", text: summary }],\n structuredContent: {\n ok: true,\n summary,\n failures: failures.length ? failures : undefined,\n flaky: flakyAnalysis.isLikelyFlaky ? { confidence: flakyAnalysis.confidence, patterns: flakyAnalysis.patterns } : undefined,\n },\n };\n }\n);\n\n// ============================================================================\n// POR QUE FALHOU? - Explicação de falhas para juniores (escalável)\n// ============================================================================\n\nfunction formatFailureExplanation(data) {\n const lines = [\n \"## O que aconteceu\",\n \"\",\n data.oQueAconteceu || \"\",\n \"\",\n \"## Por que provavelmente falhou\",\n \"\",\n ...(Array.isArray(data.porQueProvavelmenteFalhou)\n ? data.porQueProvavelmenteFalhou.map((s) => `• ${s}`)\n : [data.porQueProvavelmenteFalhou || \"\"]),\n \"\",\n \"## O que fazer agora\",\n \"\",\n ...(Array.isArray(data.oQueFazerAgora)\n ? data.oQueFazerAgora.map((s, i) => `${i + 1}. ${s}`)\n : [data.oQueFazerAgora || \"\"]),\n ];\n if (data.sugestaoCorrecao) {\n lines.push(\"\", \"## Sugestão de correção\", \"\", \"```\" + (data.framework || \"js\"), data.sugestaoCorrecao, \"```\");\n }\n if (data.conceito) {\n lines.push(\"\", \"## Conceito\", \"\", data.conceito);\n }\n return lines.filter(Boolean).join(\"\\n\");\n}\n\nasync function callLlmForExplanation(provider, apiKey, baseUrl, model, systemPrompt, userPrompt) {\n if (provider === \"gemini\") {\n const url = `${baseUrl}/models/${model}:generateContent?key=${apiKey}`;\n const res = await fetch(url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n contents: [{ parts: [{ text: systemPrompt + \"\\n\\n\" + userPrompt }] }],\n generationConfig: { temperature: 0.2, maxOutputTokens: 4096 },\n }),\n });\n const data = await res.json();\n return data.candidates?.[0]?.content?.parts?.[0]?.text || \"\";\n }\n const res = await fetch(`${baseUrl}/chat/completions`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${apiKey}`,\n },\n body: JSON.stringify({\n model,\n messages: [\n { role: \"system\", content: systemPrompt },\n { role: \"user\", content: userPrompt },\n ],\n temperature: 0.2,\n max_tokens: 4096,\n }),\n });\n const data = await res.json();\n return data.choices?.[0]?.message?.content || \"\";\n}\n\n/** Gera explicação de falha (o que aconteceu, por que, o que fazer, sugestão). Usado por por_que_falhou e run_tests_and_explain. */\nasync function generateFailureExplanation(resolvedOutput, testFilePath = null) {\n const structure = detectProjectStructure();\n const fw = structure.testFrameworks[0] || \"unknown\";\n\n let testCode = \"\";\n if (testFilePath) {\n const normalized = testFilePath.replace(/^\\//, \"\").replace(/\\\\/g, \"/\");\n const fullPath = path.join(PROJECT_ROOT, normalized);\n if (fs.existsSync(fullPath) && !fs.statSync(fullPath).isDirectory()) {\n try {\n testCode = fs.readFileSync(fullPath, \"utf8\");\n } catch {}\n }\n }\n\n const llm = resolveLLMProvider(\"complex\");\n if (!llm.apiKey) {\n return { ok: false, error: \"No API key\", formattedText: null };\n }\n const { provider, apiKey, baseUrl, model } = llm;\n\n const fwHints = {\n webdriverio: \"WebdriverIO (describe/it, $, browser.$)\",\n appium: \"Appium/WebdriverIO (mobile, $, browser.$)\",\n playwright: \"Playwright (test, page, locator)\",\n cypress: \"Cypress (cy.get, cy.click)\",\n jest: \"Jest (describe, test, expect)\",\n vitest: \"Vitest (describe, test, expect)\",\n robot: \"Robot Framework\",\n pytest: \"pytest\",\n };\n\n const systemPrompt = `Você é um mentor de QA. Analise o output de falha e responda em JSON (apenas o JSON, sem markdown) com as chaves:\n- oQueAconteceu: string (explicação em português do que aconteceu, simples)\n- porQueProvavelmenteFalhou: array de strings (lista de possíveis causas, uma por item)\n- oQueFazerAgora: array de strings (passos numerados do que fazer)\n- sugestaoCorrecao: string ou null (código de correção se aplicável, no formato do framework)\n- conceito: string ou null (ex: \"Flaky test = teste intermitente. Geralmente por timing ou seletores frágeis.\")\n- framework: string (framework do projeto)\n\nFramework do projeto: ${fw}. ${fwHints[fw] || \"\"}\nResponda APENAS com o JSON válido, sem texto antes ou depois.`;\n\n const userPrompt = `Output do terminal/log (teste falhou):\n---\n${resolvedOutput.slice(0, 12000)}\n---\n${testCode ? `\\nCódigo do teste que falhou:\\n---\\n${testCode.slice(0, 6000)}\\n---` : \"\"}`;\n\n try {\n let raw = await callLlmForExplanation(provider, apiKey, baseUrl, model, systemPrompt, userPrompt);\n raw = raw.replace(/^```(?:json)?\\s*/i, \"\").replace(/\\s*```\\s*$/i, \"\").trim();\n let data = {};\n try {\n data = JSON.parse(raw);\n } catch {\n data = {\n oQueAconteceu: raw.slice(0, 500) || \"Não foi possível parsear a resposta.\",\n porQueProvavelmenteFalhou: [],\n oQueFazerAgora: [],\n sugestaoCorrecao: null,\n conceito: null,\n framework: fw,\n };\n }\n data.framework = data.framework || fw;\n if (testFilePath && data.sugestaoCorrecao) {\n saveProjectMemory({ patterns: { [testFilePath]: { lastFix: data.sugestaoCorrecao?.slice(0, 500) } } });\n }\n const formattedText = formatFailureExplanation(data);\n return { ok: true, formattedText, structuredContent: data };\n } catch (err) {\n return { ok: false, error: err.message, formattedText: null };\n }\n}\n\nserver.registerTool(\n \"por_que_falhou\",\n {\n title: \"Por que falhou? Explicação para juniores\",\n description: \"Traduz stack trace em explicação humana. Recebe output do terminal/log, lê o projeto e o teste (se path dado), e retorna: O que aconteceu, Por que falhou, O que fazer, Sugestão de correção, Conceito. Escalável e procedural.\",\n inputSchema: z.object({\n errorOutput: z.string().optional().describe(\"Output do terminal quando o teste falhou. Se vazio, lê automaticamente de .qa-lab-last-failure.log (capturado pelo run_tests). Cole aqui ou deixe vazio para usar última falha.\"),\n testFilePath: z.string().optional().describe(\"Caminho do arquivo de teste que falhou (ex: specs/login.spec.js). Se informado, o agente lê o código e dá sugestão mais precisa.\"),\n }),\n outputSchema: z.object({\n ok: z.boolean(),\n oQueAconteceu: z.string().optional(),\n porQueProvavelmenteFalhou: z.array(z.string()).optional(),\n oQueFazerAgora: z.array(z.string()).optional(),\n sugestaoCorrecao: z.string().optional(),\n conceito: z.string().optional(),\n framework: z.string().optional(),\n formattedText: z.string().optional(),\n error: z.string().optional(),\n }),\n },\n async ({ errorOutput, testFilePath }) => {\n const structure = detectProjectStructure();\n const fw = structure.testFrameworks[0] || \"unknown\";\n\n let resolvedOutput = errorOutput?.trim() || \"\";\n if (!resolvedOutput) {\n const lastFailurePath = path.join(PROJECT_ROOT, \".qa-lab-last-failure.log\");\n if (fs.existsSync(lastFailurePath)) {\n try {\n resolvedOutput = fs.readFileSync(lastFailurePath, \"utf8\");\n } catch {}\n }\n }\n if (!resolvedOutput) {\n return {\n content: [{\n type: \"text\",\n text: \"Nenhum output de erro fornecido e nenhuma falha recente capturada.\\n\\nComo usar:\\n1. Rode os testes (run_tests) – se falhar, a saída é salva automaticamente.\\n2. Ou cole aqui o output do terminal quando o teste falhou.\\n3. Depois peça: 'Por que falhou?' ou chame por_que_falhou.\",\n }],\n structuredContent: { ok: false, error: \"No error output\" },\n };\n }\n\n let testCode = \"\";\n if (testFilePath) {\n const normalized = testFilePath.replace(/^\\//, \"\").replace(/\\\\/g, \"/\");\n const fullPath = path.join(PROJECT_ROOT, normalized);\n if (fs.existsSync(fullPath) && !fs.statSync(fullPath).isDirectory()) {\n try {\n testCode = fs.readFileSync(fullPath, \"utf8\");\n } catch {}\n }\n }\n\n const llm = resolveLLMProvider(\"complex\");\n if (!llm.apiKey) {\n return {\n content: [{\n type: \"text\",\n text: \"Configure GROQ_API_KEY, GEMINI_API_KEY ou OPENAI_API_KEY no .env do projeto para usar a explicação com LLM.\",\n }],\n structuredContent: { ok: false, error: \"No API key configured\" },\n };\n }\n const { provider, apiKey, baseUrl, model } = llm;\n\n const fwHints = {\n webdriverio: \"WebdriverIO (describe/it, $, browser.$)\",\n appium: \"Appium/WebdriverIO (mobile, $, browser.$)\",\n playwright: \"Playwright (test, page, locator)\",\n cypress: \"Cypress (cy.get, cy.click)\",\n jest: \"Jest (describe, test, expect)\",\n vitest: \"Vitest (describe, test, expect)\",\n robot: \"Robot Framework\",\n pytest: \"pytest\",\n };\n\n const systemPrompt = `Você é um mentor de QA. Analise o output de falha e responda em JSON (apenas o JSON, sem markdown) com as chaves:\n- oQueAconteceu: string (explicação em português do que aconteceu, simples)\n- porQueProvavelmenteFalhou: array de strings (lista de possíveis causas, uma por item)\n- oQueFazerAgora: array de strings (passos numerados do que fazer)\n- sugestaoCorrecao: string ou null (código de correção se aplicável, no formato do framework)\n- conceito: string ou null (ex: \"Flaky test = teste intermitente. Geralmente por timing ou seletores frágeis.\")\n- framework: string (framework do projeto)\n\nFramework do projeto: ${fw}. ${fwHints[fw] || \"\"}\nResponda APENAS com o JSON válido, sem texto antes ou depois.`;\n\n const userPrompt = `Output do terminal/log (teste falhou):\n---\n${resolvedOutput.slice(0, 12000)}\n---\n${testCode ? `\\nCódigo do teste que falhou:\\n---\\n${testCode.slice(0, 6000)}\\n---` : \"\"}`;\n\n try {\n let raw = await callLlmForExplanation(provider, apiKey, baseUrl, model, systemPrompt, userPrompt);\n raw = raw.replace(/^```(?:json)?\\s*/i, \"\").replace(/\\s*```\\s*$/i, \"\").trim();\n\n let data = {};\n try {\n data = JSON.parse(raw);\n } catch {\n data = {\n oQueAconteceu: raw.slice(0, 500) || \"Não foi possível parsear a resposta.\",\n porQueProvavelmenteFalhou: [],\n oQueFazerAgora: [],\n sugestaoCorrecao: null,\n conceito: null,\n framework: fw,\n };\n }\n\n data.framework = data.framework || fw;\n const formattedText = formatFailureExplanation(data);\n\n return {\n content: [{ type: \"text\", text: formattedText }],\n structuredContent: {\n ok: true,\n oQueAconteceu: data.oQueAconteceu,\n porQueProvavelmenteFalhou: data.porQueProvavelmenteFalhou,\n oQueFazerAgora: data.oQueFazerAgora,\n sugestaoCorrecao: data.sugestaoCorrecao ?? null,\n conceito: data.conceito ?? null,\n framework: data.framework,\n formattedText,\n },\n };\n } catch (err) {\n return {\n content: [{ type: \"text\", text: `Erro ao analisar: ${err.message}` }],\n structuredContent: { ok: false, error: err.message },\n };\n }\n }\n);\n\n// ============================================================================\n// NOVAS FERRAMENTAS\n// ============================================================================\n\nserver.registerTool(\n \"suggest_fix\",\n {\n title: \"Sugerir correção para falhas\",\n description: \"Recebe análise de falhas e sugere correções (patch, refactor, etc.).\",\n inputSchema: z.object({\n failures: z.array(z.object({\n test: z.string().optional(),\n message: z.string().optional(),\n stack: z.string().optional(),\n })).describe(\"Resultado de analyze_failures.\"),\n }),\n outputSchema: z.object({\n ok: z.boolean(),\n suggestions: z.array(z.object({\n test: z.string().optional(),\n description: z.string(),\n fix: z.string().optional(),\n })),\n }),\n },\n async ({ failures }) => {\n const suggestions = [];\n\n for (const f of failures) {\n const msg = f.message || \"\";\n \n if (/element not found|selector|timeout/i.test(msg)) {\n suggestions.push({\n test: f.test,\n description: \"Elemento não encontrado ou timeout\",\n fix: \"Verifique seletores, adicione waits ou aumente timeout. Use data-testid para seletores mais estáveis.\",\n });\n } else if (/expected.*to.*but/i.test(msg)) {\n suggestions.push({\n test: f.test,\n description: \"Asserção falhou\",\n fix: \"Revise o valor esperado. Verifique se o estado da aplicação está correto antes da asserção.\",\n });\n } else if (/network|fetch|ECONNREFUSED/i.test(msg)) {\n suggestions.push({\n test: f.test,\n description: \"Erro de rede ou API não disponível\",\n fix: \"Verifique se o backend está rodando. Confirme a URL e porta da API.\",\n });\n } else {\n suggestions.push({\n test: f.test,\n description: \"Falha detectada\",\n fix: \"Revise o stack trace e o código do teste.\",\n });\n }\n }\n\n return {\n content: [{ type: \"text\", text: JSON.stringify(suggestions, null, 2) }],\n structuredContent: { ok: true, suggestions },\n };\n }\n);\n\n// ============================================================================\n// SELF-HEALING - Sugestão de correção de seletores quando UI muda\n// ============================================================================\n\nserver.registerTool(\n \"suggest_selector_fix\",\n {\n title: \"Sugerir correção de seletor (Self-healing)\",\n description: \"Quando um teste falha por elemento não encontrado (seletor quebrado após mudança de UI), usa LLM para sugerir seletor alternativo mais resiliente. Prioriza data-testid, role, texto acessível.\",\n inputSchema: z.object({\n testFilePath: z.string().describe(\"Caminho do arquivo de teste que falhou (ex: specs/login.spec.js).\"),\n errorOutput: z.string().optional().describe(\"Output do terminal da falha. Se vazio, lê de .qa-lab-last-failure.log.\"),\n framework: z.enum([\"cypress\", \"playwright\", \"webdriverio\", \"appium\"]).optional().describe(\"Framework do teste. Detectado automaticamente se omitido.\"),\n }),\n outputSchema: z.object({\n ok: z.boolean(),\n selectorSugerido: z.string().optional(),\n codigoCorrigido: z.string().optional(),\n explicacao: z.string().optional(),\n error: z.string().optional(),\n }),\n },\n async ({ testFilePath, errorOutput, framework }) => {\n const structure = detectProjectStructure();\n const fw = framework || inferFrameworkFromFile(testFilePath.split(\"/\").pop(), structure);\n\n let resolvedOutput = errorOutput;\n if (!resolvedOutput) {\n const logPath = path.join(PROJECT_ROOT, \".qa-lab-last-failure.log\");\n if (fs.existsSync(logPath)) {\n resolvedOutput = fs.readFileSync(logPath, \"utf8\");\n }\n }\n if (!resolvedOutput) {\n return {\n content: [{ type: \"text\", text: \"Nenhum output de erro. Rode os testes primeiro ou forneça errorOutput.\" }],\n structuredContent: { ok: false, error: \"No error output\" },\n };\n }\n\n if (!/element not found|selector|timeout|locator|cy\\.get|page\\.locator/i.test(resolvedOutput)) {\n return {\n content: [{ type: \"text\", text: \"A falha não parece ser de seletor/elemento. Use por_que_falhou ou suggest_fix para outros tipos de falha.\" }],\n structuredContent: { ok: false, error: \"Not a selector-related failure\" },\n };\n }\n\n let testCode = \"\";\n const fullPath = path.join(PROJECT_ROOT, testFilePath.replace(/^\\//, \"\").replace(/\\\\/g, \"/\"));\n if (fs.existsSync(fullPath)) {\n try {\n testCode = fs.readFileSync(fullPath, \"utf8\");\n } catch {}\n }\n\n const llm = resolveLLMProvider(\"complex\");\n if (!llm.apiKey) {\n return {\n content: [{ type: \"text\", text: \"Configure GROQ_API_KEY, GEMINI_API_KEY ou OPENAI_API_KEY no .env\" }],\n structuredContent: { ok: false, error: \"No API key configured\" },\n };\n }\n const { provider, apiKey, baseUrl, model } = llm;\n\n const fwHints = {\n cypress: \"Cypress: cy.get('[data-testid=...]'), cy.contains(), cy.get('button').filter(':visible')\",\n playwright: \"Playwright: page.getByRole(), page.getByTestId(), page.locator('button:has-text(\\\"...\\\")')\",\n webdriverio: \"WebdriverIO: $('[data-testid=...]'), $('button=Texto')\",\n appium: \"Appium: $('~accessibility-id'), $('//android.view.View')\",\n };\n\n const systemPrompt = `Você é um especialista em testes E2E. O teste falhou porque um seletor não encontrou o elemento (UI mudou).\nAnalise o erro e o código e responda APENAS em JSON (sem markdown) com as chaves:\n- selectorSugerido: string (o novo seletor recomendado, mais resiliente)\n- codigoCorrigido: string (bloco de código completo corrigido, apenas a parte relevante do teste)\n- explicacao: string (breve explicação em português: por que o antigo falhou e por que o novo é melhor)\n\nPriorize nesta ordem: data-testid > role + accessible name > texto visível > estrutura. Evite classes CSS e IDs que mudam.\n\nFramework: ${fw}. ${fwHints[fw] || \"\"}`;\n\n const userPrompt = `Output do erro:\n---\n${resolvedOutput.slice(0, 8000)}\n---\nCódigo do teste:\n---\n${testCode ? testCode.slice(0, 6000) : \"Não disponível\"}\n---`;\n\n try {\n let raw = await callLlmForExplanation(provider, apiKey, baseUrl, model, systemPrompt, userPrompt);\n raw = raw.replace(/^```(?:json)?\\s*/i, \"\").replace(/\\s*```\\s*$/i, \"\").trim();\n let data = {};\n try {\n data = JSON.parse(raw);\n } catch {\n data = {\n selectorSugerido: null,\n codigoCorrigido: raw.slice(0, 2000),\n explicacao: \"Não foi possível parsear. Resposta do LLM acima.\",\n };\n }\n\n const text = [\n data.explicacao && `## Explicação\\n${data.explicacao}`,\n data.selectorSugerido && `## Seletor sugerido\\n\\`${data.selectorSugerido}\\``,\n data.codigoCorrigido && `## Código corrigido\\n\\`\\`\\`${fw}\\n${data.codigoCorrigido}\\n\\`\\`\\``,\n ]\n .filter(Boolean)\n .join(\"\\n\\n\");\n\n return {\n content: [{ type: \"text\", text: text || JSON.stringify(data, null, 2) }],\n structuredContent: {\n ok: true,\n selectorSugerido: data.selectorSugerido,\n codigoCorrigido: data.codigoCorrigido,\n explicacao: data.explicacao,\n },\n };\n } catch (err) {\n return {\n content: [{ type: \"text\", text: `Erro ao chamar LLM: ${err.message}` }],\n structuredContent: { ok: false, error: err.message },\n };\n }\n }\n);\n\nserver.registerTool(\n \"analyze_file_methods\",\n {\n title: \"Analisar métodos de um arquivo\",\n description: \"Lê um arquivo, faz varredura em todos os métodos/funções e retorna análise detalhada: método correto?, melhor forma de escrever?, falso positivo?, coerência?, itens faltando?, parâmetros faltando?, imports faltando?. Requer API key (Groq/Gemini/OpenAI).\",\n inputSchema: z.object({\n path: z.string().describe(\"Caminho do arquivo (ex: src/utils.js, tests/login.cy.js, cypress/support/commands.js).\"),\n }),\n outputSchema: z.object({\n ok: z.boolean(),\n filePath: z.string().optional(),\n methods: z.array(z.object({\n name: z.string(),\n correto: z.boolean().optional(),\n melhorForma: z.string().optional(),\n falsoPositivo: z.boolean().optional(),\n falsoPositivoRazao: z.string().optional(),\n coerente: z.boolean().optional(),\n itensFaltando: z.array(z.string()).optional(),\n parametrosFaltando: z.array(z.string()).optional(),\n importsFaltando: z.array(z.string()).optional(),\n sugestao: z.string().optional(),\n })).optional(),\n importsFaltandoGlobal: z.array(z.string()).optional(),\n resumo: z.string().optional(),\n error: z.string().optional(),\n }),\n },\n async ({ path: filePath }) => {\n const normalized = filePath.replace(/^\\//, \"\").replace(/\\\\/g, \"/\");\n const fullPath = path.join(PROJECT_ROOT, normalized);\n\n if (!fullPath.startsWith(PROJECT_ROOT)) {\n return {\n content: [{ type: \"text\", text: \"Caminho fora do projeto.\" }],\n structuredContent: { ok: false, error: \"Path outside project\" },\n };\n }\n if (!fs.existsSync(fullPath)) {\n return {\n content: [{ type: \"text\", text: `Arquivo não encontrado: ${normalized}` }],\n structuredContent: { ok: false, error: \"File not found\" },\n };\n }\n const stat = fs.statSync(fullPath);\n if (stat.isDirectory()) {\n return {\n content: [{ type: \"text\", text: \"É um diretório. Informe um arquivo.\" }],\n structuredContent: { ok: false, error: \"Is directory\" },\n };\n }\n\n let fileContent = \"\";\n try {\n fileContent = fs.readFileSync(fullPath, \"utf8\");\n } catch (err) {\n return {\n content: [{ type: \"text\", text: `Erro ao ler: ${err.message}` }],\n structuredContent: { ok: false, error: err.message },\n };\n }\n\n const llm = resolveLLMProvider(\"complex\");\n if (!llm.apiKey) {\n return {\n content: [{\n type: \"text\",\n text: \"Configure GROQ_API_KEY, GEMINI_API_KEY ou OPENAI_API_KEY no .env para usar análise com LLM.\",\n }],\n structuredContent: { ok: false, error: \"No API key configured\" },\n };\n }\n const { provider, apiKey, baseUrl, model } = llm;\n\n const ext = path.extname(fullPath).toLowerCase();\n const lang = [\".ts\", \".tsx\"].includes(ext) ? \"TypeScript\" : [\".js\", \".jsx\"].includes(ext) ? \"JavaScript\" : [\".py\"].includes(ext) ? \"Python\" : \"código\";\n\n const systemPrompt = `Você é um revisor de código experiente em QA e testes. Analise o arquivo e cada método/função, respondendo em JSON válido (sem markdown) com a estrutura:\n\n{\n \"methods\": [\n {\n \"name\": \"nomeDoMetodo\",\n \"correto\": true | false,\n \"melhorForma\": \"explicação curta se há forma melhor de escrever\",\n \"falsoPositivo\": true | false,\n \"falsoPositivoRazao\": \"se falso positivo, por quê (ex: asserção muito permissiva)\",\n \"coerente\": true | false,\n \"coerenteDetalhe\": \"se incoerente, o que está inconsistente\",\n \"itensFaltando\": [\"item1\", \"item2\"],\n \"parametrosFaltando\": [\"param1\"],\n \"importsFaltando\": [\"moduloX\"],\n \"sugestao\": \"código ou texto de sugestão de melhoria\"\n }\n ],\n \"importsFaltandoGlobal\": [\"imports faltando no topo do arquivo\"],\n \"resumo\": \"resumo geral em 2-3 linhas\"\n}\n\nPara CADA método/função no arquivo, verifique:\n1. correto: a lógica está correta?\n2. melhorForma: há forma mais legível, performática ou idiomática de escrever?\n3. falsoPositivo: o método pode passar quando não deveria (asserção fraca, mock incorreto)?\n4. coerente: o método é coerente com o restante do código, naming, padrões?\n5. itensFaltando: falta try/catch, validação, cleanup, etc?\n6. parametrosFaltando: parâmetros que deveriam existir?\n7. importsFaltando: imports que o método usa mas não estão declarados?\n\nResponda APENAS com o JSON válido. Linguagem: ${lang}.`;\n\n const userPrompt = `Arquivo: ${normalized}\n\n\\`\\`\\`${lang}\n${fileContent.slice(0, 18000)}\n\\`\\`\\`\n\nAnalise cada método/função e retorne o JSON conforme especificado.`;\n\n try {\n let raw = await callLlmForExplanation(provider, apiKey, baseUrl, model, systemPrompt, userPrompt);\n raw = raw.replace(/^```(?:json)?\\s*/i, \"\").replace(/\\s*```\\s*$/i, \"\").trim();\n\n let data = {};\n try {\n data = JSON.parse(raw);\n } catch {\n data = {\n methods: [],\n importsFaltandoGlobal: [],\n resumo: raw.slice(0, 1000) || \"Não foi possível parsear a resposta do LLM.\",\n };\n }\n\n const lines = [\n `# Análise de métodos: ${normalized}`,\n \"\",\n data.resumo && `## Resumo\\n${data.resumo}`,\n data.importsFaltandoGlobal?.length > 0\n ? `\\n## Imports faltando (global)\\n${data.importsFaltandoGlobal.map((i) => `- ${i}`).join(\"\\n\")}`\n : \"\",\n \"\\n## Métodos analisados\\n\",\n ];\n\n for (const m of data.methods || []) {\n lines.push(`### ${m.name}`);\n lines.push(\"\");\n if (m.correto !== undefined) lines.push(`- **Correto:** ${m.correto ? \"✅ Sim\" : \"❌ Não\"}`);\n if (m.melhorForma) lines.push(`- **Melhor forma:** ${m.melhorForma}`);\n if (m.falsoPositivo) lines.push(`- **Falso positivo:** ⚠️ Sim - ${m.falsoPositivoRazao || \"verificar\"}`);\n if (m.coerente !== undefined) lines.push(`- **Coerente:** ${m.coerente ? \"✅ Sim\" : \"❌ Não\"}`);\n if (m.itensFaltando?.length) lines.push(`- **Itens faltando:** ${m.itensFaltando.join(\", \")}`);\n if (m.parametrosFaltando?.length) lines.push(`- **Parâmetros faltando:** ${m.parametrosFaltando.join(\", \")}`);\n if (m.importsFaltando?.length) lines.push(`- **Imports faltando:** ${m.importsFaltando.join(\", \")}`);\n if (m.sugestao) lines.push(`\\n**Sugestão:**\\n\\`\\`\\`\\n${m.sugestao}\\n\\`\\`\\``);\n lines.push(\"\");\n }\n\n const formattedText = lines.filter(Boolean).join(\"\\n\");\n\n return {\n content: [{ type: \"text\", text: formattedText }],\n structuredContent: {\n ok: true,\n filePath: normalized,\n methods: data.methods || [],\n importsFaltandoGlobal: data.importsFaltandoGlobal || [],\n resumo: data.resumo,\n },\n };\n } catch (err) {\n return {\n content: [{ type: \"text\", text: `Erro ao analisar: ${err.message}` }],\n structuredContent: { ok: false, error: err.message },\n };\n }\n }\n);\n\n\nserver.registerTool(\n \"create_bug_report\",\n {\n title: \"Criar relatório de bug\",\n description: \"Gera um bug report estruturado a partir de falhas de teste.\",\n inputSchema: z.object({\n failures: z.array(z.object({\n test: z.string().optional(),\n message: z.string().optional(),\n stack: z.string().optional(),\n })).describe(\"Falhas (de analyze_failures).\"),\n title: z.string().optional().describe(\"Título do bug.\"),\n }),\n outputSchema: z.object({\n ok: z.boolean(),\n report: z.string(),\n title: z.string(),\n }),\n },\n async ({ failures, title }) => {\n const bugTitle = title || `Falha em ${failures.length} teste(s)`;\n const lines = [\n `# ${bugTitle}`,\n \"\",\n \"## Resumo\",\n \"\",\n `${failures.length} teste(s) falharam durante a execução.`,\n \"\",\n \"## Falhas detectadas\",\n \"\",\n ];\n\n failures.forEach((f, i) => {\n lines.push(`### ${i + 1}. ${f.test || \"Teste desconhecido\"}`);\n lines.push(\"\");\n lines.push(`**Mensagem:** ${f.message || \"N/A\"}`);\n lines.push(\"\");\n if (f.stack) {\n lines.push(\"**Stack trace:**\");\n lines.push(\"```\");\n lines.push(f.stack);\n lines.push(\"```\");\n lines.push(\"\");\n }\n });\n\n lines.push(\"## Próximos passos\");\n lines.push(\"\");\n lines.push(\"- [ ] Reproduzir localmente\");\n lines.push(\"- [ ] Identificar causa raiz\");\n lines.push(\"- [ ] Aplicar correção\");\n lines.push(\"- [ ] Validar com testes\");\n\n const report = lines.join(\"\\n\");\n\n appendMetricsEvent({ type: \"bug_reported\", failuresCount: failures.length, title: bugTitle });\n\n return {\n content: [{ type: \"text\", text: report }],\n structuredContent: { ok: true, report, title: bugTitle },\n };\n }\n);\n\n// ============================================================================\n// MÉTRICAS DE NEGÓCIO - Relatório agregado\n// ============================================================================\n\nserver.registerTool(\n \"get_business_metrics\",\n {\n title: \"Obter métricas de negócio\",\n description: \"Retorna métricas: tempo até bug, custo por defeito (tempo estimado), cobertura por fluxo. Requer run_tests executados e opcionalmente qa-lab-flows.json.\",\n inputSchema: z.object({\n period: z.enum([\"7d\", \"30d\", \"all\"]).optional().describe(\"Período para analisar. Default: 30d.\"),\n }),\n outputSchema: z.object({\n ok: z.boolean(),\n timeToBug: z.object({\n avgHours: z.number(),\n lastFailureAt: z.string().optional(),\n runsWithFailures: z.number(),\n }).optional(),\n costPerDefect: z.object({\n avgMinutesPerDefect: z.number(),\n totalFailures: z.number(),\n estimatedHoursSpent: z.number(),\n }).optional(),\n flowCoverage: z.object({\n totalFlows: z.number(),\n coveredFlows: z.number(),\n percent: z.number(),\n details: z.array(z.object({ flow: z.string(), covered: z.boolean() })),\n }).optional(),\n summary: z.string(),\n }),\n },\n async ({ period = \"30d\" } = {}) => {\n const now = Date.now();\n const msByPeriod = { \"7d\": 7 * 24 * 60 * 60 * 1000, \"30d\": 30 * 24 * 60 * 60 * 1000, all: Infinity };\n const cutoff = now - msByPeriod[period];\n\n let data = { events: [] };\n if (fs.existsSync(METRICS_FILE)) {\n try {\n data = JSON.parse(fs.readFileSync(METRICS_FILE, \"utf8\"));\n } catch {}\n }\n\n const events = (data.events || []).filter((e) => new Date(e.timestamp).getTime() >= cutoff);\n\n const testRuns = events.filter((e) => e.type === \"test_run\");\n const failedRuns = testRuns.filter((e) => (e.failed || 0) > 0);\n const totalFailed = testRuns.reduce((sum, e) => sum + (e.failed || 0), 0);\n const totalDuration = testRuns.reduce((sum, e) => sum + (e.durationSeconds || 0), 0);\n\n let timeToBug = null;\n if (failedRuns.length > 0) {\n const lastFailure = failedRuns[failedRuns.length - 1];\n timeToBug = {\n avgHours: 0,\n lastFailureAt: lastFailure.timestamp,\n runsWithFailures: failedRuns.length,\n };\n if (failedRuns.length >= 2) {\n const deltas = [];\n for (let i = 1; i < failedRuns.length; i++) {\n const prev = new Date(failedRuns[i - 1].timestamp).getTime();\n const curr = new Date(failedRuns[i].timestamp).getTime();\n deltas.push((curr - prev) / (1000 * 60 * 60));\n }\n timeToBug.avgHours = deltas.reduce((a, b) => a + b, 0) / deltas.length;\n }\n }\n\n let costPerDefect = null;\n if (totalFailed > 0) {\n const estimatedMinutesSpent = totalDuration + totalFailed * 5;\n costPerDefect = {\n avgMinutesPerDefect: Math.round(estimatedMinutesSpent / totalFailed),\n totalFailures: totalFailed,\n estimatedHoursSpent: Math.round((estimatedMinutesSpent / 60) * 10) / 10,\n };\n }\n\n let flowCoverage = null;\n if (fs.existsSync(FLOWS_CONFIG_FILE)) {\n try {\n const flowsConfig = JSON.parse(fs.readFileSync(FLOWS_CONFIG_FILE, \"utf8\"));\n const flows = flowsConfig.flows || [];\n const structure = detectProjectStructure();\n const allTestFiles = new Set(collectTestFiles(structure).map((e) => e.path));\n\n const details = flows.map((f) => {\n const testFiles = f.testFiles || [];\n const covered = testFiles.some((tf) => allTestFiles.has(tf) || allTestFiles.has(tf.replace(/\\\\/g, \"/\")));\n return { flow: f.name || f.id || \"?\", covered };\n });\n\n flowCoverage = {\n totalFlows: flows.length,\n coveredFlows: details.filter((d) => d.covered).length,\n percent: flows.length ? Math.round((details.filter((d) => d.covered).length / flows.length) * 100) : 0,\n details,\n };\n } catch {}\n }\n\n const lines = [\n \"## Métricas de negócio\",\n \"\",\n `Período: ${period}`,\n \"\",\n timeToBug\n ? [\n \"### Tempo até bug\",\n `- Última falha: ${timeToBug.lastFailureAt || \"N/A\"}`,\n `- Execuções com falha: ${timeToBug.runsWithFailures}`,\n timeToBug.avgHours > 0 ? `- Média entre falhas: ${timeToBug.avgHours.toFixed(1)}h` : \"\",\n ]\n .filter(Boolean)\n .join(\"\\n\")\n : \"\",\n costPerDefect\n ? [\n \"### Custo por defeito (estimativa)\",\n `- Total de falhas: ${costPerDefect.totalFailures}`,\n `- Tempo médio por defeito: ~${costPerDefect.avgMinutesPerDefect} min`,\n `- Horas estimadas gastas: ${costPerDefect.estimatedHoursSpent}h`,\n ].join(\"\\n\")\n : \"\",\n flowCoverage\n ? [\n \"### Cobertura por fluxo\",\n `- Fluxos cobertos: ${flowCoverage.coveredFlows}/${flowCoverage.totalFlows} (${flowCoverage.percent}%)`,\n flowCoverage.details.map((d) => ` - ${d.flow}: ${d.covered ? \"✅\" : \"❌\"}`).join(\"\\n\"),\n ].join(\"\\n\")\n : \"\",\n ]\n .filter(Boolean)\n .join(\"\\n\\n\");\n\n if (!timeToBug && !costPerDefect && !flowCoverage) {\n const msg =\n \"Nenhuma métrica disponível. Rode run_tests para gerar dados. Para cobertura por fluxo, crie qa-lab-flows.json.\";\n return {\n content: [{ type: \"text\", text: msg }],\n structuredContent: { ok: false, summary: msg },\n };\n }\n\n const summary = [\n timeToBug && `${timeToBug.runsWithFailures} execuções com falha`,\n costPerDefect && `${costPerDefect.totalFailures} falhas (~${costPerDefect.avgMinutesPerDefect} min/defeito)`,\n flowCoverage && `${flowCoverage.coveredFlows}/${flowCoverage.totalFlows} fluxos cobertos`,\n ]\n .filter(Boolean)\n .join(\" | \");\n\n return {\n content: [{ type: \"text\", text: lines || summary }],\n structuredContent: {\n ok: true,\n timeToBug,\n costPerDefect,\n flowCoverage,\n summary,\n },\n };\n }\n);\n\nserver.registerTool(\n \"list_test_files\",\n {\n title: \"Listar arquivos de teste\",\n description: \"Lista TODOS os arquivos de teste (qualquer framework: Cypress, Playwright, WDIO, Robot, pytest, Behave, etc.) com filtro opcional.\",\n inputSchema: z.object({\n framework: z.enum([\n \"cypress\", \"playwright\", \"jest\", \"webdriverio\", \"appium\", \"robot\", \"pytest\", \"behave\", \"detox\", \"all\"\n ]).optional().describe(\"Filtrar por framework. Default: all.\"),\n pattern: z.string().optional().describe(\"Pattern para filtrar (ex: 'login', 'api').\"),\n }),\n outputSchema: z.object({\n ok: z.boolean(),\n files: z.array(z.string()),\n total: z.number(),\n }),\n },\n async ({ framework = \"all\", pattern } = {}) => {\n const structure = detectProjectStructure();\n const collected = collectTestFiles(structure, { framework, pattern });\n const allFiles = collected.map((e) => e.path);\n\n const summary = `Encontrados ${allFiles.length} arquivo(s) de teste (qualquer framework).`;\n\n return {\n content: [{ type: \"text\", text: `${summary}\\n\\n${allFiles.slice(0, 50).join(\"\\n\")}` }],\n structuredContent: { ok: true, files: allFiles, total: allFiles.length },\n };\n }\n);\n\nserver.registerTool(\n \"run_linter\",\n {\n title: \"Executar linter\",\n description: \"Roda ESLint, Prettier ou linter configurado no projeto.\",\n inputSchema: z.object({\n fix: z.boolean().optional().describe(\"Auto-fix (--fix). Default: false.\"),\n path: z.string().optional().describe(\"Caminho específico (ex: src/). Default: todo o projeto.\"),\n }),\n outputSchema: z.object({\n status: z.enum([\"passed\", \"failed\", \"not_found\"]),\n message: z.string(),\n exitCode: z.number(),\n output: z.string().optional(),\n }),\n },\n async ({ fix, path: targetPath }) => {\n const structure = detectProjectStructure();\n const scripts = structure.packageJson?.scripts || {};\n\n let cmd, args;\n if (scripts.lint) {\n cmd = \"npm\";\n args = [\"run\", \"lint\"];\n } else if (structure.packageJson?.devDependencies?.eslint || structure.packageJson?.dependencies?.eslint) {\n cmd = \"npx\";\n args = [\"eslint\", targetPath || \".\"];\n if (fix) args.push(\"--fix\");\n } else {\n return {\n content: [{ type: \"text\", text: \"Linter não detectado no projeto.\" }],\n structuredContent: { status: \"not_found\", message: \"No linter found\", exitCode: 1 },\n };\n }\n\n return new Promise((resolve) => {\n const child = spawn(cmd, args, {\n cwd: PROJECT_ROOT,\n stdio: [\"inherit\", \"pipe\", \"pipe\"],\n shell: process.platform === \"win32\",\n env: { ...process.env },\n });\n\n let stdout = \"\";\n let stderr = \"\";\n if (child.stdout) child.stdout.on(\"data\", (d) => { stdout += d.toString(); });\n if (child.stderr) child.stderr.on(\"data\", (d) => { stderr += d.toString(); });\n\n child.on(\"close\", (code) => {\n const output = [stdout, stderr].filter(Boolean).join(\"\\n\").trim();\n const passed = code === 0;\n resolve({\n content: [{ type: \"text\", text: passed ? \"Linter passou.\" : \"Linter encontrou problemas.\" }],\n structuredContent: {\n status: passed ? \"passed\" : \"failed\",\n message: passed ? \"Lint passed\" : \"Lint failed\",\n exitCode: code ?? 1,\n output: !passed ? output : undefined,\n },\n });\n });\n });\n }\n);\n\nserver.registerTool(\n \"install_dependencies\",\n {\n title: \"Instalar dependências\",\n description: \"Roda npm install, yarn install ou pnpm install (detecta automaticamente).\",\n inputSchema: z.object({\n packageManager: z.enum([\"npm\", \"yarn\", \"pnpm\", \"auto\"]).optional().describe(\"Package manager. Default: auto.\"),\n }),\n outputSchema: z.object({\n status: z.enum([\"success\", \"failed\"]),\n message: z.string(),\n exitCode: z.number(),\n }),\n },\n async ({ packageManager = \"auto\" }) => {\n let pm = packageManager;\n \n if (pm === \"auto\") {\n if (fs.existsSync(path.join(PROJECT_ROOT, \"yarn.lock\"))) pm = \"yarn\";\n else if (fs.existsSync(path.join(PROJECT_ROOT, \"pnpm-lock.yaml\"))) pm = \"pnpm\";\n else pm = \"npm\";\n }\n\n return new Promise((resolve) => {\n const child = spawn(pm, [\"install\"], {\n cwd: PROJECT_ROOT,\n stdio: \"inherit\",\n shell: process.platform === \"win32\",\n env: { ...process.env },\n });\n\n child.on(\"close\", (code) => {\n const passed = code === 0;\n resolve({\n content: [{ type: \"text\", text: passed ? \"Dependências instaladas.\" : \"Erro ao instalar dependências.\" }],\n structuredContent: {\n status: passed ? \"success\" : \"failed\",\n message: passed ? \"Dependencies installed\" : \"Install failed\",\n exitCode: code ?? 1,\n },\n });\n });\n });\n }\n);\n\nserver.registerTool(\n \"qa_learning_stats\",\n {\n title: \"Estatísticas de aprendizado\",\n description: \"[MÉTRICAS] Retorna métricas de aprendizado do agente: quantos testes gerados, taxa de sucesso na primeira tentativa, correções aplicadas, etc.\",\n inputSchema: z.object({}),\n outputSchema: z.object({\n totalLearnings: z.number(),\n successfulFixes: z.number(),\n selectorFixes: z.number(),\n timingFixes: z.number(),\n testsGenerated: z.number(),\n firstAttemptSuccessRate: z.number(),\n }),\n },\n async () => {\n const stats = getMemoryStats();\n const summary = `📊 **Estatísticas de Aprendizado**\n\n- Total de aprendizados: ${stats.totalLearnings}\n- Correções bem-sucedidas: ${stats.successfulFixes}\n- Correções de seletores: ${stats.selectorFixes}\n- Correções de timing: ${stats.timingFixes}\n- Testes gerados: ${stats.testsGenerated}\n- Taxa de sucesso na 1ª tentativa: ${stats.firstAttemptSuccessRate}%\n\n${stats.totalLearnings === 0 ? \"⚠️ Ainda não há aprendizados. Use qa_auto para gerar testes e aprender com erros.\" : \"\"}`;\n\n return {\n content: [{ type: \"text\", text: summary }],\n structuredContent: stats,\n };\n }\n);\n\nserver.registerTool(\n \"get_test_coverage\",\n {\n title: \"Obter cobertura de testes\",\n description: \"Roda testes com coverage (Jest, Playwright, Cypress com plugin).\",\n inputSchema: z.object({\n framework: z.enum([\"jest\", \"playwright\", \"cypress\"]).optional().describe(\"Framework. Default: detectado automaticamente.\"),\n }),\n outputSchema: z.object({\n status: z.enum([\"success\", \"failed\", \"not_supported\"]),\n message: z.string(),\n coveragePercent: z.number().optional(),\n output: z.string().optional(),\n }),\n },\n async ({ framework }) => {\n const structure = detectProjectStructure();\n const fw = framework || structure.testFrameworks[0];\n\n if (fw === \"jest\") {\n return new Promise((resolve) => {\n const child = spawn(\"npx\", [\"jest\", \"--coverage\"], {\n cwd: PROJECT_ROOT,\n stdio: [\"inherit\", \"pipe\", \"pipe\"],\n shell: process.platform === \"win32\",\n env: { ...process.env },\n });\n\n let stdout = \"\";\n if (child.stdout) child.stdout.on(\"data\", (d) => { stdout += d.toString(); });\n\n child.on(\"close\", (code) => {\n const coverageMatch = stdout.match(/All files.*?(\\d+\\.?\\d*)/);\n const coveragePercent = coverageMatch ? parseFloat(coverageMatch[1]) : undefined;\n\n resolve({\n content: [{ type: \"text\", text: `Coverage: ${coveragePercent || \"N/A\"}%` }],\n structuredContent: {\n status: code === 0 ? \"success\" : \"failed\",\n message: code === 0 ? \"Coverage generated\" : \"Coverage failed\",\n coveragePercent,\n output: stdout,\n },\n });\n });\n });\n }\n\n return {\n content: [{ type: \"text\", text: `Coverage não suportado para ${fw} ainda.` }],\n structuredContent: { status: \"not_supported\", message: \"Coverage not supported for this framework\" },\n };\n }\n);\n\nserver.registerTool(\n \"watch_tests\",\n {\n title: \"Rodar testes em modo watch\",\n description: \"Inicia testes em watch mode (Jest, Vitest). Útil para desenvolvimento.\",\n inputSchema: z.object({\n framework: z.enum([\"jest\", \"vitest\"]).optional().describe(\"Framework. Default: detectado.\"),\n }),\n outputSchema: z.object({\n status: z.string(),\n message: z.string(),\n }),\n },\n async ({ framework }) => {\n const structure = detectProjectStructure();\n const fw = framework || (structure.testFrameworks.includes(\"jest\") ? \"jest\" : \"vitest\");\n\n if (!structure.testFrameworks.includes(fw)) {\n return {\n content: [{ type: \"text\", text: `${fw} não detectado no projeto.` }],\n structuredContent: { status: \"not_found\", message: \"Framework not found\" },\n };\n }\n\n return {\n content: [{ type: \"text\", text: `Para watch mode, rode manualmente: npx ${fw} --watch` }],\n structuredContent: {\n status: \"info\",\n message: `Watch mode requires interactive terminal. Run: npx ${fw} --watch`,\n },\n };\n }\n);\n\nserver.registerTool(\n \"qa_auto\",\n {\n title: \"Modo autônomo: gera, roda, corrige e aprende\",\n description: \"[AGENTE AUTÔNOMO] Loop completo: detecta projeto → gera teste → roda → se falhar: analisa, corrige, roda de novo → aprende com erros. Repete até passar ou atingir max_retries.\",\n inputSchema: z.object({\n request: z.string().describe(\"O que testar (ex: 'login flow', 'checkout', 'API /users').\"),\n framework: z.enum([\n \"cypress\", \"playwright\", \"webdriverio\", \"jest\", \"vitest\", \"mocha\", \"appium\", \"robot\", \"pytest\"\n ]).optional().describe(\"Framework (detectado automaticamente se omitido).\"),\n maxRetries: z.number().optional().describe(\"Máximo de tentativas de correção. Default: 3.\"),\n }),\n outputSchema: z.object({\n ok: z.boolean(),\n testFilePath: z.string().optional(),\n attempts: z.number(),\n finalStatus: z.enum([\"passed\", \"failed\", \"max_retries\"]),\n learnings: z.array(z.object({ attempt: z.number(), action: z.string(), result: z.string() })).optional(),\n error: z.string().optional(),\n }),\n },\n async ({ request, framework, maxRetries = 3 }) => {\n const structure = detectProjectStructure();\n const fw = framework || structure.testFrameworks[0];\n if (!fw) {\n return {\n content: [{ type: \"text\", text: \"Nenhum framework detectado. Configure testes primeiro.\" }],\n structuredContent: { ok: false, error: \"No framework\", finalStatus: \"failed\", attempts: 0 },\n };\n }\n\n const llm = resolveLLMProvider(\"simple\");\n if (!llm.apiKey) {\n return {\n content: [{ type: \"text\", text: \"Configure GROQ_API_KEY, GEMINI_API_KEY ou OPENAI_API_KEY no .env\" }],\n structuredContent: { ok: false, error: \"No API key\", finalStatus: \"failed\", attempts: 0 },\n };\n }\n\n const learnings = [];\n const memory = loadProjectMemory();\n const contextLines = [\n `Frameworks: ${structure.testFrameworks.join(\", \")}`,\n `Pastas: ${structure.testDirs.join(\", \")}`,\n memory.flows?.length ? `Fluxos: ${memory.flows.map((f) => f.name || f.id).join(\", \")}` : \"\",\n ].filter(Boolean).join(\"\\n\");\n\n let testFilePath = null;\n let testContent = null;\n let attempt = 0;\n\n learnings.push({ attempt: 0, action: \"detect_project\", result: `${structure.testFrameworks.length} framework(s)` });\n\n for (attempt = 1; attempt <= maxRetries; attempt++) {\n learnings.push({ attempt, action: \"generate_tests\", result: \"gerando...\" });\n\n const { provider, apiKey, baseUrl, model } = llm;\n const memoryHints = memory.learnings?.filter((l) => l.success).slice(-10).map((l) => l.fix).join(\"\\n\") || \"\";\n const systemPrompt = `Você é um engenheiro de QA especializado em ${fw}. Gere APENAS o código do spec, sem explicações.\n${memoryHints ? `\\nAprendizados anteriores (use como referência):\\n${memoryHints.slice(0, 1000)}` : \"\"}\nRetorne SOMENTE o código, sem markdown.`;\n\n const userPrompt = `Contexto:\\n${contextLines}\\n\\nGere teste para: ${request}\\nFramework: ${fw}`;\n\n try {\n let specContent = \"\";\n if (provider === \"gemini\") {\n const url = `${baseUrl}/models/${model}:generateContent?key=${apiKey}`;\n const res = await fetch(url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n contents: [{ parts: [{ text: systemPrompt + \"\\n\\n\" + userPrompt }] }],\n generationConfig: { temperature: 0.3, maxOutputTokens: 4096 },\n }),\n });\n const data = await res.json();\n specContent = data.candidates?.[0]?.content?.parts?.[0]?.text || \"\";\n } else {\n const res = await fetch(`${baseUrl}/chat/completions`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\", Authorization: `Bearer ${apiKey}` },\n body: JSON.stringify({\n model,\n messages: [{ role: \"system\", content: systemPrompt }, { role: \"user\", content: userPrompt }],\n temperature: 0.3,\n max_tokens: 4096,\n }),\n });\n const data = await res.json();\n specContent = data.choices?.[0]?.message?.content || \"\";\n }\n specContent = specContent.replace(/^```(?:js|javascript|typescript)?\\n?/i, \"\").replace(/\\n?```\\s*$/i, \"\").trim();\n testContent = specContent;\n\n if (!testFilePath) {\n const fileName = request.toLowerCase().replace(/\\s+/g, \"-\").replace(/[^a-z0-9-]/g, \"\").slice(0, 30);\n const { ext, baseDir } = getExtensionAndBaseDir(fw, structure);\n const safeName = fileName + ext;\n testFilePath = path.join(baseDir, safeName);\n if (!fs.existsSync(baseDir)) fs.mkdirSync(baseDir, { recursive: true });\n }\n fs.writeFileSync(testFilePath, testContent, \"utf8\");\n learnings.push({ attempt, action: \"write_test\", result: `gravado: ${testFilePath}` });\n\n learnings.push({ attempt, action: \"run_tests\", result: \"executando...\" });\n const runResult = await new Promise((resolve) => {\n const child = spawn(\"npx\", [fw === \"cypress\" ? \"cypress\" : fw === \"playwright\" ? \"playwright\" : fw, fw === \"cypress\" ? \"run\" : fw === \"playwright\" ? \"test\" : \"run\", testFilePath], {\n cwd: PROJECT_ROOT,\n stdio: [\"inherit\", \"pipe\", \"pipe\"],\n shell: process.platform === \"win32\",\n });\n let stdout = \"\", stderr = \"\";\n if (child.stdout) child.stdout.on(\"data\", (d) => { stdout += d.toString(); });\n if (child.stderr) child.stderr.on(\"data\", (d) => { stderr += d.toString(); });\n child.on(\"close\", (code) => resolve({ code, output: [stdout, stderr].filter(Boolean).join(\"\\n\") }));\n });\n\n if (runResult.code === 0) {\n learnings.push({ attempt, action: \"run_tests\", result: \"✅ passou\" });\n saveProjectMemory({\n learnings: [{ type: \"test_generated\", request, framework: fw, success: true, passedFirstTime: attempt === 1, attempts: attempt, timestamp: new Date().toISOString() }],\n });\n return {\n content: [{ type: \"text\", text: `✅ Teste passou na tentativa ${attempt}!\\n\\nArquivo: ${testFilePath}\\n\\nAprendizados salvos.` }],\n structuredContent: { ok: true, testFilePath, attempts: attempt, finalStatus: \"passed\", learnings },\n };\n }\n\n learnings.push({ attempt, action: \"run_tests\", result: `❌ falhou (exit ${runResult.code})` });\n\n if (attempt >= maxRetries) {\n learnings.push({ attempt, action: \"max_retries\", result: \"limite atingido\" });\n saveProjectMemory({\n learnings: [{ type: \"test_generated\", request, framework: fw, success: false, attempts: attempt, timestamp: new Date().toISOString() }],\n });\n return {\n content: [{ type: \"text\", text: `❌ Teste falhou após ${attempt} tentativa(s).\\n\\nÚltimo erro:\\n${runResult.output.slice(0, 500)}` }],\n structuredContent: { ok: false, testFilePath, attempts: attempt, finalStatus: \"max_retries\", learnings },\n };\n }\n\n learnings.push({ attempt, action: \"analyze_failures\", result: \"analisando...\" });\n const flakyAnalysis = detectFlakyPatterns(runResult.output);\n const llmComplex = resolveLLMProvider(\"complex\");\n const explainResult = await generateFailureExplanation(runResult.output, testFilePath);\n\n if (!explainResult.ok || !explainResult.structuredContent?.sugestaoCorrecao) {\n learnings.push({ attempt, action: \"analyze_failures\", result: \"sem sugestão de correção\" });\n continue;\n }\n\n learnings.push({ attempt, action: \"apply_fix\", result: \"aplicando correção...\" });\n const fixedCode = explainResult.structuredContent.sugestaoCorrecao;\n testContent = fixedCode;\n fs.writeFileSync(testFilePath, testContent, \"utf8\");\n learnings.push({ attempt, action: \"apply_fix\", result: \"correção aplicada\" });\n\n if (flakyAnalysis.isLikelyFlaky) {\n saveProjectMemory({\n learnings: [{\n type: flakyAnalysis.patterns[0]?.pattern === \"selector\" ? \"selector_fix\" : \"timing_fix\",\n request,\n framework: fw,\n fix: fixedCode.slice(0, 500),\n success: false,\n timestamp: new Date().toISOString(),\n }],\n });\n }\n } catch (err) {\n learnings.push({ attempt, action: \"error\", result: err.message });\n return {\n content: [{ type: \"text\", text: `Erro na tentativa ${attempt}: ${err.message}` }],\n structuredContent: { ok: false, error: err.message, attempts: attempt, finalStatus: \"failed\", learnings },\n };\n }\n }\n\n return {\n content: [{ type: \"text\", text: `❌ Falhou após ${maxRetries} tentativa(s).` }],\n structuredContent: { ok: false, testFilePath, attempts: maxRetries, finalStatus: \"max_retries\", learnings },\n };\n }\n);\n\nserver.registerTool(\n \"create_test_template\",\n {\n title: \"Criar template de teste\",\n description: \"Gera template básico de teste (boilerplate) para o framework escolhido.\",\n inputSchema: z.object({\n framework: z.enum([\"cypress\", \"playwright\", \"jest\"]).describe(\"Framework.\"),\n type: z.enum([\"api\", \"ui\", \"unit\"]).optional().describe(\"Tipo de teste. Default: api.\"),\n }),\n outputSchema: z.object({\n ok: z.boolean(),\n template: z.string(),\n suggestedFileName: z.string(),\n }),\n },\n async ({ framework, type = \"api\" }) => {\n let template = \"\";\n let fileName = \"\";\n\n if (framework === \"cypress\") {\n fileName = `${type}-test.cy.js`;\n template = `describe('${type.toUpperCase()} Test', () => {\n it('should pass', () => {\n ${type === \"api\" ? \"cy.request('GET', 'http://localhost:3000/api/health').then((res) => {\\n expect(res.status).to.eq(200);\\n });\" : \"cy.visit('/');\\n cy.get('h1').should('be.visible');\"}\n });\n});`;\n } else if (framework === \"playwright\") {\n fileName = `${type}-test.spec.js`;\n template = `const { test, expect } = require('@playwright/test');\n\ntest.describe('${type.toUpperCase()} Test', () => {\n test('should pass', async ({ ${type === \"api\" ? \"request\" : \"page\"} }) => {\n ${type === \"api\" ? \"const res = await request.get('http://localhost:3000/api/health');\\n expect(res.status()).toBe(200);\" : \"await page.goto('/');\\n await expect(page.locator('h1')).toBeVisible();\"}\n });\n});`;\n } else {\n fileName = `${type}-test.test.js`;\n template = `describe('${type.toUpperCase()} Test', () => {\n test('should pass', ${type === \"api\" ? \"async () => {\\n const res = await fetch('http://localhost:3000/api/health');\\n expect(res.status).toBe(200);\\n }\" : \"() => {\\n expect(true).toBe(true);\\n }\"});\n});`;\n }\n\n return {\n content: [{ type: \"text\", text: `Template criado. Use write_test para gravar.` }],\n structuredContent: { ok: true, template, suggestedFileName: fileName },\n };\n }\n);\n\nasync function main() {\n const cmd = process.argv[2];\n\n if (cmd === \"--help\" || cmd === \"-h\") {\n console.log(`\nmcp-lab-agent - Agente autônomo de QA que aprende com os próprios erros\n\nUSO:\n mcp-lab-agent [comando] # Sem comando: inicia servidor MCP\n mcp-lab-agent --help # Mostra esta ajuda\n\nCOMANDOS CLI:\n detect [--json] Detecta frameworks e estrutura. Padrão: resumo. --json: JSON completo para scripts.\n route <tarefa> Sugere qual ferramenta usar (ex: route \"rodar testes\")\n list Lista ferramentas MCP disponíveis\n auto <descrição> [--max-retries N] [NOVO] Modo autônomo: gera teste, roda, corrige e aprende (default: 3 tentativas)\n stats [NOVO] Mostra estatísticas de aprendizado (taxa de sucesso, correções, etc.)\n\nEXEMPLOS:\n mcp-lab-agent auto \"login flow\" --max-retries 5\n mcp-lab-agent stats\n mcp-lab-agent detect --json\n\nINTEGRAÇÃO MCP (Cursor/Cline/Windsurf):\n Adicione ao ~/.cursor/mcp.json:\n {\n \"mcpServers\": {\n \"qa-lab-agent\": {\n \"command\": \"npx\",\n \"args\": [\"-y\", \"mcp-lab-agent\"],\n \"cwd\": \"\\${workspaceFolder}\"\n }\n }\n }\n`);\n process.exit(0);\n }\n\n if (cmd === \"detect\") {\n const structure = detectProjectStructure();\n const jsonOnly = process.argv.includes(\"--json\");\n if (jsonOnly) {\n console.log(JSON.stringify(structure, null, 2));\n } else {\n const lines = [\n \"\",\n \"mcp-lab-agent · detecção\",\n \"─\".repeat(40),\n `Frameworks: ${structure.testFrameworks.length ? structure.testFrameworks.join(\", \") : \"nenhum\"}`,\n `Pastas: ${structure.testDirs.length ? structure.testDirs.join(\", \") : \"nenhuma\"}`,\n `Backend: ${structure.backendDir || \"—\"}`,\n `Frontend: ${structure.frontendDir || \"—\"}`,\n `Mobile: ${structure.hasMobile ? \"sim\" : \"—\"}`,\n \"─\".repeat(40),\n \"(use --json para saída completa)\",\n \"\",\n ];\n console.log(lines.join(\"\\n\"));\n }\n process.exit(0);\n }\n\n if (cmd === \"list\") {\n const agents = Object.entries(QA_AGENTS).map(([k, v]) => ` ${k}: ${v.tools.join(\", \")}`);\n console.log(\"Agentes e ferramentas:\\n\" + agents.join(\"\\n\"));\n process.exit(0);\n }\n\n if (cmd === \"route\" && process.argv[3]) {\n const task = process.argv.slice(3).join(\" \");\n const t = task.toLowerCase();\n let agent = \"detection\";\n if (/autônomo|auto|completo|loop|aprende|corrige automaticamente/i.test(t)) agent = \"autonomous\";\n else if (/estatística|métrica de aprendizado|taxa de sucesso|learning|stats/i.test(t)) agent = \"learning\";\n else if (/rodar|executar|run|test|coverage|watch/i.test(t)) agent = \"execution\";\n else if (/gerar|criar|escrever|generate|write|template/i.test(t)) agent = \"generation\";\n else if (/analisar|por que|falhou|sugerir|fix|selector/i.test(t)) agent = \"analysis\";\n else if (/browser|navegador|screenshot|network|console/i.test(t)) agent = \"browser\";\n else if (/relatório|métrica|bug report/i.test(t)) agent = \"reporting\";\n else if (/linter|dependência|instalar|analisar método/i.test(t)) agent = \"maintenance\";\n const a = QA_AGENTS[agent] || QA_AGENTS.detection;\n console.log(JSON.stringify({ suggestedAgent: agent, suggestedTools: a.tools, description: a.desc }, null, 2));\n process.exit(0);\n }\n\n if (cmd === \"auto\") {\n const request = process.argv.slice(3).join(\" \");\n if (!request) {\n console.error(\"❌ Uso: mcp-lab-agent auto <descrição do teste> [--max-retries N]\");\n process.exit(1);\n }\n const maxRetriesIdx = process.argv.indexOf(\"--max-retries\");\n const maxRetries = maxRetriesIdx !== -1 && process.argv[maxRetriesIdx + 1] ? parseInt(process.argv[maxRetriesIdx + 1], 10) : 3;\n const cleanRequest = request.replace(/--max-retries\\s+\\d+/g, \"\").trim();\n\n console.log(`\\n🤖 Modo autônomo iniciado: \"${cleanRequest}\"\\n`);\n const structure = detectProjectStructure();\n const fw = structure.testFrameworks[0];\n if (!fw) {\n console.error(\"❌ Nenhum framework detectado.\");\n process.exit(1);\n }\n\n const llm = resolveLLMProvider(\"simple\");\n if (!llm.apiKey) {\n console.error(\"❌ Configure GROQ_API_KEY, GEMINI_API_KEY ou OPENAI_API_KEY no .env\");\n process.exit(1);\n }\n\n const memory = loadProjectMemory();\n const contextLines = [\n `Frameworks: ${structure.testFrameworks.join(\", \")}`,\n `Pastas: ${structure.testDirs.join(\", \")}`,\n memory.flows?.length ? `Fluxos: ${memory.flows.map((f) => f.name || f.id).join(\", \")}` : \"\",\n ].filter(Boolean).join(\"\\n\");\n\n let testFilePath = null;\n let testContent = null;\n\n for (let attempt = 1; attempt <= maxRetries; attempt++) {\n console.log(`\\n[Tentativa ${attempt}/${maxRetries}] Gerando teste...`);\n\n const { provider, apiKey, baseUrl, model } = llm;\n const memoryHints = memory.learnings?.filter((l) => l.success).slice(-10).map((l) => l.fix).join(\"\\n\") || \"\";\n const systemPrompt = `Você é um engenheiro de QA especializado em ${fw}. Gere APENAS o código do spec, sem explicações.\n${memoryHints ? `\\nAprendizados anteriores (use como referência):\\n${memoryHints.slice(0, 1000)}` : \"\"}\nRetorne SOMENTE o código, sem markdown.`;\n\n const userPrompt = `Contexto:\\n${contextLines}\\n\\nGere teste para: ${cleanRequest}\\nFramework: ${fw}`;\n\n try {\n let specContent = \"\";\n if (provider === \"gemini\") {\n const url = `${baseUrl}/models/${model}:generateContent?key=${apiKey}`;\n const res = await fetch(url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n contents: [{ parts: [{ text: systemPrompt + \"\\n\\n\" + userPrompt }] }],\n generationConfig: { temperature: 0.3, maxOutputTokens: 4096 },\n }),\n });\n const data = await res.json();\n specContent = data.candidates?.[0]?.content?.parts?.[0]?.text || \"\";\n } else {\n const res = await fetch(`${baseUrl}/chat/completions`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\", Authorization: `Bearer ${apiKey}` },\n body: JSON.stringify({\n model,\n messages: [{ role: \"system\", content: systemPrompt }, { role: \"user\", content: userPrompt }],\n temperature: 0.3,\n max_tokens: 4096,\n }),\n });\n const data = await res.json();\n specContent = data.choices?.[0]?.message?.content || \"\";\n }\n specContent = specContent.replace(/^```(?:js|javascript|typescript)?\\n?/i, \"\").replace(/\\n?```\\s*$/i, \"\").trim();\n testContent = specContent;\n\n if (!testFilePath) {\n const fileName = cleanRequest.toLowerCase().replace(/\\s+/g, \"-\").replace(/[^a-z0-9-]/g, \"\").slice(0, 30);\n const { ext, baseDir } = getExtensionAndBaseDir(fw, structure);\n const safeName = fileName + ext;\n testFilePath = path.join(baseDir, safeName);\n if (!fs.existsSync(baseDir)) fs.mkdirSync(baseDir, { recursive: true });\n }\n fs.writeFileSync(testFilePath, testContent, \"utf8\");\n console.log(`✅ Teste gravado: ${testFilePath}`);\n\n console.log(`\\n[Tentativa ${attempt}/${maxRetries}] Executando teste...`);\n const runResult = await new Promise((resolve) => {\n const child = spawn(\"npx\", [fw === \"cypress\" ? \"cypress\" : fw === \"playwright\" ? \"playwright\" : fw, fw === \"cypress\" ? \"run\" : fw === \"playwright\" ? \"test\" : \"run\", testFilePath], {\n cwd: PROJECT_ROOT,\n stdio: [\"inherit\", \"pipe\", \"pipe\"],\n shell: process.platform === \"win32\",\n });\n let stdout = \"\", stderr = \"\";\n if (child.stdout) child.stdout.on(\"data\", (d) => { stdout += d.toString(); });\n if (child.stderr) child.stderr.on(\"data\", (d) => { stderr += d.toString(); });\n child.on(\"close\", (code) => resolve({ code, output: [stdout, stderr].filter(Boolean).join(\"\\n\") }));\n });\n\n if (runResult.code === 0) {\n console.log(`\\n✅ Teste passou na tentativa ${attempt}!`);\n saveProjectMemory({\n learnings: [{ type: \"test_generated\", request: cleanRequest, framework: fw, success: true, passedFirstTime: attempt === 1, attempts: attempt, timestamp: new Date().toISOString() }],\n });\n console.log(`\\n📊 Aprendizado salvo. Use \"mcp-lab-agent stats\" para ver métricas.\\n`);\n process.exit(0);\n }\n\n console.log(`\\n❌ Teste falhou (exit ${runResult.code})`);\n console.log(`\\nSaída:\\n${runResult.output.slice(0, 800)}\\n`);\n\n if (attempt >= maxRetries) {\n console.log(`\\n❌ Limite de tentativas atingido (${maxRetries}).\\n`);\n saveProjectMemory({\n learnings: [{ type: \"test_generated\", request: cleanRequest, framework: fw, success: false, attempts: attempt, timestamp: new Date().toISOString() }],\n });\n process.exit(1);\n }\n\n console.log(`\\n[Tentativa ${attempt}/${maxRetries}] Analisando falha...`);\n const flakyAnalysis = detectFlakyPatterns(runResult.output);\n if (flakyAnalysis.isLikelyFlaky) {\n console.log(`⚠️ Flaky detectado (${flakyAnalysis.confidence.toFixed(2)}): ${flakyAnalysis.patterns.map((p) => p.pattern).join(\", \")}`);\n }\n\n const explainResult = await generateFailureExplanation(runResult.output, testFilePath);\n if (!explainResult.ok || !explainResult.structuredContent?.sugestaoCorrecao) {\n console.log(`⚠️ Não foi possível gerar correção. Tentando novamente...`);\n continue;\n }\n\n console.log(`\\n[Tentativa ${attempt}/${maxRetries}] Aplicando correção...`);\n const fixedCode = explainResult.structuredContent.sugestaoCorrecao;\n testContent = fixedCode;\n fs.writeFileSync(testFilePath, testContent, \"utf8\");\n console.log(`✅ Correção aplicada.`);\n\n if (flakyAnalysis.isLikelyFlaky) {\n saveProjectMemory({\n learnings: [{\n type: flakyAnalysis.patterns[0]?.pattern === \"selector\" ? \"selector_fix\" : \"timing_fix\",\n request: cleanRequest,\n framework: fw,\n fix: fixedCode.slice(0, 500),\n success: false,\n timestamp: new Date().toISOString(),\n }],\n });\n }\n } catch (err) {\n console.error(`\\n❌ Erro na tentativa ${attempt}: ${err.message}\\n`);\n process.exit(1);\n }\n }\n\n console.log(`\\n❌ Falhou após ${maxRetries} tentativa(s).\\n`);\n process.exit(1);\n }\n\n if (cmd === \"stats\") {\n const stats = getMemoryStats();\n console.log(`\n📊 Estatísticas de Aprendizado\n\nTotal de aprendizados: ${stats.totalLearnings}\nCorreções bem-sucedidas: ${stats.successfulFixes}\nCorreções de seletores: ${stats.selectorFixes}\nCorreções de timing: ${stats.timingFixes}\nTestes gerados: ${stats.testsGenerated}\nTaxa de sucesso na 1ª tentativa: ${stats.firstAttemptSuccessRate}%\n\n${stats.totalLearnings === 0 ? \"⚠️ Ainda não há aprendizados. Use 'mcp-lab-agent auto <descrição>' para gerar testes e aprender com erros.\" : \"\"}\n`);\n process.exit(0);\n }\n\n const transport = new StdioServerTransport();\n await server.connect(transport);\n}\n\nmain().catch((err) => {\n console.error(\"Erro no MCP server:\", err);\n process.exit(1);\n});\n"],"mappings":";;;AAMA,SAAS,cAAc;AACvB,SAAS,iBAAiB;AAC1B,SAAS,4BAA4B;AACrC,SAAS,SAAS;AAClB,SAAS,aAAa;AACtB,OAAO,UAAU;AACjB,OAAO,QAAQ;AAEf,IAAM,eAAe,QAAQ,IAAI;AACjC,OAAO,EAAE,MAAM,KAAK,KAAK,cAAc,MAAM,EAAE,CAAC;AAEhD,IAAM,SAAS,IAAI,UAAU;AAAA,EAC3B,MAAM;AAAA,EACN,SAAS;AACX,CAAC;AAWD,SAAS,mBAAmB,WAAW,UAAU;AAC/C,QAAM,WAAW,QAAQ,IAAI;AAC7B,QAAM,aAAa,QAAQ,IAAI;AAC/B,QAAM,aAAa,QAAQ,IAAI,kBAAkB,QAAQ,IAAI;AAC7D,QAAM,aAAa,QAAQ,IAAI,mBAAmB;AAClD,QAAM,aAAa,QAAQ,IAAI;AAE/B,QAAM,cAAc,QAAQ,IAAI;AAChC,QAAM,eAAe,QAAQ,IAAI;AAEjC,MAAI,YAAY;AACd,UAAMA,SAAQ,aAAa,YAAa,gBAAgB,iBAAmB,eAAe;AAC1F,WAAO,EAAE,UAAU,UAAU,QAAQ,QAAQ,IAAI,sBAAsB,cAAc,SAAS,YAAY,OAAAA,OAAM;AAAA,EAClH;AAEA,MAAI,CAAC,YAAY,CAAC,cAAc,CAAC,YAAY;AAC3C,UAAMA,SAAQ,aAAa,YAAa,gBAAgB,iBAAmB,eAAe;AAC1F,WAAO,EAAE,UAAU,UAAU,QAAQ,cAAc,SAAS,GAAG,UAAU,OAAO,OAAAA,OAAM;AAAA,EACxF;AAEA,MAAI,WAAW,WAAW,SAAS,aAAa,WAAW;AAC3D,QAAM,SAAS,YAAY,cAAc;AACzC,QAAM,UAAU,aAAa,SACzB,mCACA,aAAa,WACX,qDACA;AAEN,MAAI;AACJ,MAAI,aAAa,WAAW;AAC1B,YAAQ,iBAAiB,aAAa,SAAS,4BAA4B,aAAa,WAAW,mBAAmB;AAAA,EACxH,OAAO;AACL,YAAQ,gBAAgB,aAAa,SAAS,yBAAyB,aAAa,WAAW,qBAAqB;AAAA,EACtH;AAEA,SAAO,EAAE,UAAU,QAAQ,SAAS,MAAM;AAC5C;AAMA,IAAM,cAAc,KAAK,KAAK,cAAc,qBAAqB;AACjE,IAAM,oBAAoB,KAAK,KAAK,cAAc,mBAAmB;AAErE,SAAS,oBAAoB;AAC3B,QAAM,SAAS,EAAE,UAAU,CAAC,GAAG,aAAa,CAAC,GAAG,SAAS,MAAM,WAAW,CAAC,EAAE;AAC7E,MAAI,GAAG,WAAW,WAAW,GAAG;AAC9B,QAAI;AACF,YAAM,MAAM,GAAG,aAAa,aAAa,MAAM;AAC/C,aAAO,OAAO,QAAQ,KAAK,MAAM,GAAG,CAAC;AAAA,IACvC,QAAQ;AAAA,IAAC;AAAA,EACX;AACA,MAAI,GAAG,WAAW,iBAAiB,GAAG;AACpC,QAAI;AACF,YAAM,QAAQ,KAAK,MAAM,GAAG,aAAa,mBAAmB,MAAM,CAAC;AACnE,aAAO,QAAQ,MAAM,SAAS,CAAC;AAAA,IACjC,QAAQ;AAAA,IAAC;AAAA,EACX;AACA,SAAO;AACT;AAEA,SAAS,kBAAkB,SAAS;AAClC,MAAI;AACF,QAAI,OAAO,kBAAkB;AAC7B,QAAI,QAAQ,SAAU,MAAK,WAAW,EAAE,GAAG,KAAK,UAAU,GAAG,QAAQ,SAAS;AAC9E,QAAI,QAAQ,YAAa,MAAK,cAAc,EAAE,GAAG,KAAK,aAAa,GAAG,QAAQ,YAAY;AAC1F,QAAI,QAAQ,UAAW,MAAK,YAAY,CAAC,GAAG,oBAAI,IAAI,CAAC,GAAI,KAAK,aAAa,CAAC,GAAI,GAAG,QAAQ,SAAS,CAAC,CAAC,EAAE,MAAM,IAAI;AAClH,QAAI,QAAQ,QAAS,MAAK,UAAU,QAAQ;AAC5C,QAAI,QAAQ,WAAW;AACrB,WAAK,YAAY,KAAK,aAAa,CAAC;AACpC,WAAK,UAAU,KAAK,GAAG,QAAQ,SAAS;AACxC,UAAI,KAAK,UAAU,SAAS,IAAK,MAAK,YAAY,KAAK,UAAU,MAAM,IAAI;AAAA,IAC7E;AACA,SAAK,aAAY,oBAAI,KAAK,GAAE,YAAY;AACxC,OAAG,cAAc,aAAa,KAAK,UAAU,MAAM,MAAM,CAAC,GAAG,MAAM;AAAA,EACrE,QAAQ;AAAA,EAAC;AACX;AAEA,SAAS,iBAAiB;AACxB,QAAM,SAAS,kBAAkB;AACjC,QAAM,YAAY,OAAO,aAAa,CAAC;AACvC,QAAM,kBAAkB,UAAU,OAAO,CAAC,MAAM,EAAE,OAAO;AACzD,QAAM,gBAAgB,UAAU,OAAO,CAAC,MAAM,EAAE,SAAS,cAAc;AACvE,QAAM,cAAc,UAAU,OAAO,CAAC,MAAM,EAAE,SAAS,YAAY;AACnE,QAAM,aAAa,UAAU,OAAO,CAAC,MAAM,EAAE,SAAS,gBAAgB,EAAE;AACxE,QAAM,sBAAsB,UAAU,OAAO,CAAC,MAAM,EAAE,SAAS,oBAAoB,EAAE,eAAe,EAAE;AAEtG,SAAO;AAAA,IACL,gBAAgB,UAAU;AAAA,IAC1B,iBAAiB,gBAAgB;AAAA,IACjC,eAAe,cAAc;AAAA,IAC7B,aAAa,YAAY;AAAA,IACzB,gBAAgB;AAAA,IAChB,yBAAyB,aAAa,IAAI,KAAK,MAAO,sBAAsB,aAAc,GAAG,IAAI;AAAA,EACnG;AACF;AAMA,IAAM,iBAAiB;AAAA,EACrB,EAAE,MAAM,UAAU,OAAO,8DAA8D,YAAY,8EAA2E;AAAA,EAC9K,EAAE,MAAM,YAAY,OAAO,sDAAsD,YAAY,0GAAuG;AAAA,EACpM,EAAE,MAAM,YAAY,OAAO,4EAA4E,YAAY,oGAA2F;AAAA,EAC9M,EAAE,MAAM,WAAW,OAAO,4DAA4D,YAAY,8EAA8E;AAAA,EAChL,EAAE,MAAM,gBAAgB,OAAO,iDAAiD,YAAY,+FAA4F;AAC1L;AAEA,SAAS,oBAAoB,WAAW;AACtC,QAAM,WAAW,CAAC;AAClB,aAAW,KAAK,gBAAgB;AAC9B,QAAI,EAAE,MAAM,KAAK,SAAS,GAAG;AAC3B,eAAS,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,EAAE,WAAW,CAAC;AAAA,IAC7D;AAAA,EACF;AACA,QAAM,aAAa,SAAS,SAAS,IAAI,KAAK,IAAI,MAAM,SAAS,SAAS,KAAK,IAAI,IAAI;AACvF,SAAO,EAAE,eAAe,aAAa,KAAK,YAAY,UAAU,SAAS;AAC3E;AAMA,SAAS,yBAAyB;AAChC,QAAM,YAAY;AAAA,IAChB,UAAU;AAAA,IACV,gBAAgB,CAAC;AAAA,IACjB,UAAU,CAAC;AAAA,IACX,YAAY;AAAA,IACZ,YAAY;AAAA,IACZ,aAAa;AAAA,IACb,aAAa;AAAA,IACb,WAAW;AAAA,IACX,aAAa;AAAA,IACb,oBAAoB;AAAA,EACtB;AAGA,QAAM,UAAU,KAAK,KAAK,cAAc,cAAc;AACtD,MAAI,GAAG,WAAW,OAAO,GAAG;AAC1B,cAAU,cAAc,KAAK,MAAM,GAAG,aAAa,SAAS,MAAM,CAAC;AACnE,UAAM,OAAO;AAAA,MACX,GAAG,UAAU,YAAY;AAAA,MACzB,GAAG,UAAU,YAAY;AAAA,IAC3B;AAGA,QAAI,KAAK,SAAS;AAChB,gBAAU,eAAe,KAAK,SAAS;AACvC,gBAAU,WAAW;AAAA,IACvB;AACA,QAAI,KAAK,kBAAkB,KAAK,KAAK,YAAY;AAC/C,gBAAU,eAAe,KAAK,YAAY;AAC1C,gBAAU,WAAW;AAAA,IACvB;AACA,QAAI,KAAK,eAAe,KAAK,WAAW,GAAG;AACzC,gBAAU,eAAe,KAAK,aAAa;AAC3C,gBAAU,WAAW;AAAA,IACvB;AAGA,QAAI,KAAK,MAAM;AACb,gBAAU,eAAe,KAAK,MAAM;AACpC,gBAAU,WAAW;AAAA,IACvB;AACA,QAAI,KAAK,QAAQ;AACf,gBAAU,eAAe,KAAK,QAAQ;AACtC,gBAAU,WAAW;AAAA,IACvB;AACA,QAAI,KAAK,OAAO;AACd,gBAAU,eAAe,KAAK,OAAO;AACrC,gBAAU,WAAW;AAAA,IACvB;AACA,QAAI,KAAK,SAAS;AAChB,gBAAU,eAAe,KAAK,SAAS;AACvC,gBAAU,WAAW;AAAA,IACvB;AAGA,QAAI,KAAK,UAAU,KAAK,oBAAoB,GAAG;AAC7C,gBAAU,eAAe,KAAK,QAAQ;AACtC,gBAAU,WAAW;AACrB,gBAAU,YAAY;AAAA,IACxB;AACA,QAAI,KAAK,OAAO;AACd,gBAAU,eAAe,KAAK,OAAO;AACrC,gBAAU,WAAW;AACrB,gBAAU,YAAY;AAAA,IACxB;AAGA,QAAI,KAAK,WAAW;AAClB,gBAAU,eAAe,KAAK,WAAW;AACzC,gBAAU,WAAW;AAAA,IACvB;AACA,QAAI,KAAK,gBAAgB,KAAK,KAAK,QAAQ;AACzC,gBAAU,eAAe,KAAK,QAAQ;AACtC,gBAAU,WAAW;AAAA,IACvB;AAGA,QAAI,KAAK,YAAY,KAAK,UAAU,GAAG;AACrC,gBAAU,eAAe,KAAK,UAAU;AACxC,gBAAU,WAAW;AAAA,IACvB;AACA,QAAI,KAAK,cAAc,KAAK,YAAY,GAAG;AACzC,gBAAU,eAAe,KAAK,YAAY;AAC1C,gBAAU,WAAW;AAAA,IACvB;AACA,QAAI,KAAK,WAAW;AAClB,gBAAU,eAAe,KAAK,WAAW;AACzC,gBAAU,WAAW;AAAA,IACvB;AACA,QAAI,KAAK,cAAc,KAAK,YAAY,GAAG;AACzC,gBAAU,eAAe,KAAK,YAAY;AAC1C,gBAAU,WAAW;AAAA,IACvB;AAGA,QAAI,KAAK,WAAW,KAAK,WAAW,KAAK,cAAc,KAAK,KAAK,KAAK;AACpE,gBAAU,aAAa;AAAA,IACzB;AAGA,QAAI,KAAK,QAAQ,KAAK,SAAS,KAAK,OAAO,KAAK,UAAU,KAAK,SAAS;AACtE,gBAAU,cAAc;AAAA,IAC1B;AAAA,EACF;AAGA,QAAM,mBAAmB,KAAK,KAAK,cAAc,kBAAkB;AACnE,MAAI,GAAG,WAAW,gBAAgB,GAAG;AACnC,UAAM,eAAe,GAAG,aAAa,kBAAkB,MAAM;AAC7D,cAAU,qBAAqB;AAE/B,QAAI,kBAAkB,KAAK,YAAY,GAAG;AACxC,gBAAU,eAAe,KAAK,OAAO;AACrC,gBAAU,WAAW;AAAA,IACvB;AACA,QAAI,UAAU,KAAK,YAAY,GAAG;AAChC,gBAAU,eAAe,KAAK,QAAQ;AACtC,gBAAU,WAAW;AAAA,IACvB;AACA,QAAI,UAAU,KAAK,YAAY,GAAG;AAChC,gBAAU,eAAe,KAAK,QAAQ;AACtC,gBAAU,WAAW;AAAA,IACvB;AACA,QAAI,YAAY,KAAK,YAAY,GAAG;AAClC,gBAAU,aAAa;AAAA,IACzB;AAAA,EACF;AAGA,QAAM,iBAAiB;AAAA,IACrB;AAAA,IAAS;AAAA,IAAQ;AAAA,IAAO;AAAA,IAAW;AAAA,IAAc;AAAA,IACjD;AAAA,IAAS;AAAA,IAAQ;AAAA,IAAe;AAAA,IAAQ;AAAA,IAAc;AAAA,IACtD;AAAA,IAAY;AAAA,IAAa;AAAA,IAAU;AAAA;AAAA,IAEnC;AAAA,IAAiB;AAAA,IAAgB;AAAA,IAAe;AAAA,IAChD;AAAA,IAAiB;AAAA,IAAc;AAAA,IAAmB;AAAA,EACpD;AACA,aAAW,OAAO,gBAAgB;AAChC,UAAM,WAAW,KAAK,KAAK,cAAc,GAAG;AAC5C,QAAI,GAAG,WAAW,QAAQ,KAAK,GAAG,SAAS,QAAQ,EAAE,YAAY,GAAG;AAClE,gBAAU,SAAS,KAAK,GAAG;AAAA,IAC7B;AAAA,EACF;AAGA,QAAM,WAAW,CAAC,gBAAgB,QAAQ,QAAQ,SAAS,SAAS,OAAO;AAC3E,MAAI;AACF,UAAM,cAAc,GAAG,YAAY,cAAc,EAAE,eAAe,KAAK,CAAC;AACxE,eAAW,KAAK,aAAa;AAC3B,UAAI,CAAC,EAAE,YAAY,KAAK,SAAS,SAAS,EAAE,IAAI,EAAG;AACnD,YAAM,UAAU,KAAK,KAAK,cAAc,EAAE,IAAI;AAC9C,UAAI,UAAU,SAAS,SAAS,EAAE,IAAI,EAAG;AAEzC,YAAM,SAAS,GAAG,WAAW,KAAK,KAAK,SAAS,cAAc,CAAC;AAC/D,YAAM,WAAW,GAAG,WAAW,KAAK,KAAK,SAAS,OAAO,CAAC,KACxD,GAAG,WAAW,KAAK,KAAK,SAAS,MAAM,CAAC,KACxC,GAAG,WAAW,KAAK,KAAK,SAAS,KAAK,CAAC,KACvC,GAAG,WAAW,KAAK,KAAK,SAAS,WAAW,CAAC,KAC7C,GAAG,WAAW,KAAK,KAAK,SAAS,OAAO,CAAC;AAC3C,UAAI,UAAU,UAAU;AACtB,kBAAU,SAAS,KAAK,EAAE,IAAI;AAAA,MAChC;AAAA,IACF;AAAA,EACF,QAAQ;AAAA,EAAC;AAGT,aAAW,OAAO,UAAU,UAAU;AACpC,UAAM,SAAS,KAAK,KAAK,cAAc,KAAK,cAAc;AAC1D,QAAI,CAAC,GAAG,WAAW,MAAM,EAAG;AAC5B,QAAI;AACF,YAAM,MAAM,KAAK,MAAM,GAAG,aAAa,QAAQ,MAAM,CAAC;AACtD,YAAM,UAAU,EAAE,GAAI,IAAI,gBAAgB,CAAC,GAAI,GAAI,IAAI,mBAAmB,CAAC,EAAG;AAC9E,YAAM,QAAQ,CAAC;AACf,UAAI,QAAQ,WAAW,CAAC,UAAU,eAAe,SAAS,SAAS,EAAG,OAAM,KAAK,SAAS;AAC1F,WAAK,QAAQ,kBAAkB,KAAK,QAAQ,eAAe,CAAC,UAAU,eAAe,SAAS,YAAY,EAAG,OAAM,KAAK,YAAY;AACpI,WAAK,QAAQ,eAAe,QAAQ,WAAW,MAAM,CAAC,UAAU,eAAe,SAAS,aAAa,EAAG,OAAM,KAAK,aAAa;AAChI,UAAI,QAAQ,YAAY,CAAC,UAAU,eAAe,SAAS,UAAU,EAAG,OAAM,KAAK,UAAU;AAC7F,UAAI,QAAQ,cAAc,CAAC,UAAU,eAAe,SAAS,YAAY,EAAG,OAAM,KAAK,YAAY;AACnG,UAAI,QAAQ,aAAa,CAAC,UAAU,eAAe,SAAS,WAAW,EAAG,OAAM,KAAK,WAAW;AAChG,UAAI,QAAQ,cAAc,CAAC,UAAU,eAAe,SAAS,YAAY,EAAG,OAAM,KAAK,YAAY;AACnG,UAAI,QAAQ,QAAQ,CAAC,UAAU,eAAe,SAAS,MAAM,EAAG,OAAM,KAAK,MAAM;AACjF,YAAM,QAAQ,CAAC,OAAO;AAAE,kBAAU,eAAe,KAAK,EAAE;AAAG,kBAAU,WAAW;AAAA,MAAM,CAAC;AAAA,IACzF,QAAQ;AAAA,IAAC;AAAA,EACX;AAGA,aAAW,OAAO,UAAU,UAAU;AACpC,UAAM,UAAU,KAAK,KAAK,cAAc,KAAK,kBAAkB;AAC/D,QAAI,CAAC,GAAG,WAAW,OAAO,EAAG;AAC7B,QAAI;AACF,YAAM,MAAM,GAAG,aAAa,SAAS,MAAM;AAC3C,UAAI,kBAAkB,KAAK,GAAG,KAAK,CAAC,UAAU,eAAe,SAAS,OAAO,GAAG;AAC9E,kBAAU,eAAe,KAAK,OAAO;AACrC,kBAAU,WAAW;AAAA,MACvB;AACA,UAAI,mBAAmB,KAAK,GAAG,KAAK,CAAC,UAAU,eAAe,SAAS,QAAQ,GAAG;AAChF,kBAAU,eAAe,KAAK,QAAQ;AACtC,kBAAU,WAAW;AAAA,MACvB;AAAA,IACF,QAAQ;AAAA,IAAC;AAAA,EACX;AAGA,QAAM,oBAAoB,CAAC,WAAW,UAAU,OAAO,KAAK;AAC5D,aAAW,OAAO,mBAAmB;AACnC,UAAM,WAAW,KAAK,KAAK,cAAc,GAAG;AAC5C,QAAI,GAAG,WAAW,QAAQ,KAAK,CAAC,UAAU,YAAY;AACpD,YAAM,gBAAgB,GAAG,WAAW,KAAK,KAAK,UAAU,WAAW,CAAC,KAClE,GAAG,WAAW,KAAK,KAAK,UAAU,UAAU,CAAC,KAC7C,GAAG,WAAW,KAAK,KAAK,UAAU,QAAQ,CAAC;AAC7C,UAAI,eAAe;AACjB,kBAAU,aAAa;AAAA,MACzB;AAAA,IACF;AAAA,EACF;AAGA,QAAM,qBAAqB,CAAC,YAAY,UAAU,OAAO,OAAO,KAAK;AACrE,aAAW,OAAO,oBAAoB;AACpC,UAAM,WAAW,KAAK,KAAK,cAAc,GAAG;AAC5C,QAAI,GAAG,WAAW,QAAQ,KAAK,CAAC,UAAU,aAAa;AACrD,YAAM,aAAa,GAAG,WAAW,KAAK,KAAK,UAAU,QAAQ,CAAC,KAC5D,GAAG,WAAW,KAAK,KAAK,UAAU,SAAS,CAAC,KAC5C,GAAG,WAAW,KAAK,KAAK,UAAU,YAAY,CAAC;AACjD,UAAI,YAAY;AACd,kBAAU,cAAc;AAAA,MAC1B;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AAMA,IAAM,0BAA0B;AAAA,EAC9B;AAAA,EACA;AAAA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEA,SAAS,WAAW,MAAM;AACxB,SAAO,wBAAwB,KAAK,CAAC,OAAO,GAAG,KAAK,IAAI,CAAC;AAC3D;AAEA,SAAS,iBAAiB,WAAW,UAAU,CAAC,GAAG;AACjD,QAAM,EAAE,SAAS,WAAW,kBAAkB,EAAE,IAAI;AACpD,QAAM,UAAU,CAAC;AAEjB,aAAW,OAAO,UAAU,UAAU;AACpC,UAAM,WAAW,KAAK,KAAK,cAAc,GAAG;AAC5C,UAAM,OAAO,CAAC,GAAG,OAAO,OAAO;AAC7B,UAAI,CAAC,GAAG,WAAW,CAAC,EAAG;AACvB,YAAM,UAAU,GAAG,YAAY,GAAG,EAAE,eAAe,KAAK,CAAC;AACzD,iBAAW,KAAK,SAAS;AACvB,cAAM,MAAM,OAAO,GAAG,IAAI,IAAI,EAAE,IAAI,KAAK,EAAE;AAC3C,YAAI,EAAE,YAAY,GAAG;AACnB,cAAI,EAAE,SAAS,kBAAkB,EAAE,SAAS,UAAU,EAAE,SAAS,QAAS;AAC1E,eAAK,KAAK,KAAK,GAAG,EAAE,IAAI,GAAG,GAAG;AAAA,QAChC,WAAW,EAAE,OAAO,KAAK,WAAW,EAAE,IAAI,GAAG;AAC3C,gBAAM,WAAW,GAAG,GAAG,IAAI,GAAG;AAC9B,cAAI,WAAW,CAAC,SAAS,YAAY,EAAE,SAAS,QAAQ,YAAY,CAAC,EAAG;AACxE,gBAAM,aAAa,uBAAuB,EAAE,MAAM,WAAW,QAAQ;AACrE,cAAI,aAAa,cAAc,SAAS,eAAe,aAAa,CAAC,iBAAiB,YAAY,SAAS,EAAG;AAC9G,gBAAM,QAAQ,EAAE,MAAM,UAAU,mBAAmB,WAAW;AAC9D,cAAI,kBAAkB,KAAK,QAAQ,SAAS,iBAAiB;AAC3D,gBAAI;AACF,oBAAM,UAAU,GAAG,aAAa,KAAK,KAAK,cAAc,QAAQ,GAAG,MAAM;AAAA,YAC3E,QAAQ;AAAA,YAAC;AAAA,UACX;AACA,kBAAQ,KAAK,KAAK;AAAA,QACpB;AAAA,MACF;AAAA,IACF;AACA,SAAK,QAAQ;AAAA,EACf;AACA,SAAO;AACT;AAEA,SAAS,uBAAuB,MAAM,YAAY,CAAC,GAAG,WAAW,IAAI;AACnE,QAAM,aAAa,YAAY,IAAI,YAAY,EAAE,QAAQ,OAAO,GAAG;AAEnE,MAAI,oBAAoB,KAAK,SAAS,EAAG,QAAO;AAChD,MAAI,uBAAuB,KAAK,SAAS,EAAG,QAAO;AACnD,MAAI,qCAAqC,KAAK,SAAS,EAAG,QAAO;AACjE,MAAI,mBAAmB,KAAK,SAAS,EAAG,QAAO;AAC/C,MAAI,2CAA2C,KAAK,SAAS,EAAG,QAAO;AACvE,MAAI,kBAAkB,KAAK,SAAS,EAAG,QAAO;AAC9C,MAAI,qBAAqB,KAAK,SAAS,EAAG,QAAO;AACjD,MAAI,uBAAuB,KAAK,SAAS,EAAG,QAAO;AACnD,MAAI,qBAAqB,KAAK,SAAS,EAAG,QAAO;AACjD,MAAI,sBAAsB,KAAK,SAAS,EAAG,QAAO;AAClD,MAAI,oCAAoC,KAAK,SAAS,EAAG,QAAO;AAEhE,MAAI,yBAAyB,KAAK,IAAI,EAAG,QAAO;AAChD,MAAI,mBAAmB,KAAK,IAAI,EAAG,QAAO;AAC1C,MAAI,2BAA2B,KAAK,IAAI,GAAG;AACzC,QAAI,WAAW,gBAAgB,SAAS,aAAa,EAAG,QAAO;AAC/D,QAAI,WAAW,gBAAgB,SAAS,QAAQ,EAAG,QAAO;AAC1D,WAAO;AAAA,EACT;AACA,MAAI,2BAA2B,KAAK,IAAI,EAAG,QAAO,WAAW,gBAAgB,SAAS,QAAQ,IAAI,WAAW;AAC7G,MAAI,YAAY,KAAK,IAAI,EAAG,QAAO;AACnC,MAAI,cAAc,KAAK,IAAI,EAAG,QAAO;AACrC,MAAI,sBAAsB,KAAK,IAAI,KAAK,2BAA2B,KAAK,IAAI,EAAG,QAAO;AACtF,MAAI,kBAAkB,KAAK,IAAI,EAAG,QAAO;AACzC,SAAO;AACT;AAEA,SAAS,iBAAiB,UAAU,WAAW;AAC7C,QAAM,UAAU,EAAE,MAAM,CAAC,cAAc,eAAe,QAAQ,EAAE;AAChE,MAAI,aAAa,UAAW,QAAO;AACnC,SAAO,QAAQ,QAAQ,GAAG,SAAS,SAAS;AAC9C;AAEA,SAAS,gBAAgB,WAAW,eAAe;AACjD,aAAW,OAAO,eAAe;AAC/B,QAAI,UAAU,SAAS,SAAS,GAAG,GAAG;AACpC,aAAO,KAAK,KAAK,cAAc,GAAG;AAAA,IACpC;AAAA,EACF;AACA,QAAM,WAAW,UAAU,SAAS,CAAC;AACrC,SAAO,WAAW,KAAK,KAAK,cAAc,QAAQ,IAAI;AACxD;AAMA,IAAM,eAAe,KAAK,KAAK,cAAc,sBAAsB;AAEnE,SAAS,mBAAmB,WAAW,UAAU;AAC/C,MAAI,SAAS;AACb,MAAI,SAAS;AACb,QAAM,YAAY,UAAU,MAAM,gDAAgD;AAClF,MAAI,WAAW;AACb,aAAS,SAAS,UAAU,CAAC,GAAG,EAAE;AAClC,aAAS,UAAU,CAAC,IAAI,SAAS,UAAU,CAAC,GAAG,EAAE,IAAI;AAAA,EACvD;AACA,QAAM,cAAc,UAAU,MAAM,iBAAiB;AACrD,QAAM,cAAc,UAAU,MAAM,iBAAiB;AACrD,MAAI,YAAa,UAAS,SAAS,YAAY,CAAC,GAAG,EAAE;AACrD,MAAI,YAAa,UAAS,SAAS,YAAY,CAAC,GAAG,EAAE;AACrD,QAAM,SAAS,UAAU,MAAM,gBAAgB;AAC/C,QAAM,SAAS,UAAU,MAAM,gBAAgB;AAC/C,MAAI,OAAQ,UAAS,SAAS,OAAO,CAAC,GAAG,EAAE;AAC3C,MAAI,OAAQ,UAAS,SAAS,OAAO,CAAC,GAAG,EAAE;AAC3C,MAAI,WAAW,KAAK,WAAW,GAAG;AAChC,QAAI,aAAa,EAAG,UAAS;AAAA,QACxB,UAAS;AAAA,EAChB;AACA,SAAO,EAAE,QAAQ,OAAO;AAC1B;AAEA,SAAS,mBAAmB,OAAO;AACjC,MAAI;AACF,QAAI,OAAO,EAAE,QAAQ,CAAC,GAAG,cAAa,oBAAI,KAAK,GAAE,YAAY,EAAE;AAC/D,QAAI,GAAG,WAAW,YAAY,GAAG;AAC/B,YAAM,MAAM,GAAG,aAAa,cAAc,MAAM;AAChD,UAAI;AACF,eAAO,KAAK,MAAM,GAAG;AAAA,MACvB,QAAQ;AAAA,MAAC;AAAA,IACX;AACA,SAAK,SAAS,KAAK,UAAU,CAAC;AAC9B,SAAK,OAAO,KAAK,EAAE,GAAG,OAAO,WAAW,MAAM,cAAa,oBAAI,KAAK,GAAE,YAAY,EAAE,CAAC;AACrF,SAAK,eAAc,oBAAI,KAAK,GAAE,YAAY;AAC1C,QAAI,KAAK,OAAO,SAAS,IAAK,MAAK,SAAS,KAAK,OAAO,MAAM,IAAI;AAClE,OAAG,cAAc,cAAc,KAAK,UAAU,MAAM,MAAM,CAAC,GAAG,MAAM;AAAA,EACtE,QAAQ;AAAA,EAAC;AACX;AAEA,SAAS,0BAA0B,WAAW;AAC5C,QAAM,WAAW,CAAC;AAClB,QAAM,QAAQ,UAAU,MAAM,IAAI;AAClC,WAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACrC,UAAM,OAAO,MAAM,CAAC;AACpB,QAAI,2DAA2D,KAAK,IAAI,GAAG;AACzE,eAAS,KAAK;AAAA,QACZ,MAAM,MAAM,KAAK,IAAI,GAAG,IAAI,CAAC,CAAC,GAAG,KAAK,KAAK;AAAA,QAC3C,SAAS,KAAK,KAAK,EAAE,MAAM,GAAG,GAAG;AAAA,MACnC,CAAC;AAAA,IACH;AAAA,EACF;AACA,SAAO,SAAS,MAAM,GAAG,EAAE;AAC7B;AAMA,OAAO;AAAA,EACL;AAAA,EACA;AAAA,IACE,OAAO;AAAA,IACP,aAAa;AAAA,IACb,aAAa,EAAE,OAAO;AAAA,MACpB,MAAM,EAAE,OAAO,EAAE,SAAS,oGAAoG;AAAA,MAC9H,UAAU,EAAE,KAAK,CAAC,QAAQ,OAAO,CAAC,EAAE,SAAS,EAAE,SAAS,yBAAyB;AAAA,IACnF,CAAC;AAAA,IACD,cAAc,EAAE,OAAO;AAAA,MACrB,IAAI,EAAE,QAAQ;AAAA,MACd,SAAS,EAAE,OAAO,EAAE,SAAS;AAAA,MAC7B,OAAO,EAAE,OAAO,EAAE,SAAS;AAAA,IAC7B,CAAC;AAAA,EACH;AAAA,EACA,OAAO,EAAE,MAAM,UAAU,WAAW,OAAO,MAAM;AAC/C,UAAM,aAAa,SAAS,QAAQ,OAAO,EAAE,EAAE,QAAQ,OAAO,GAAG;AACjE,UAAM,WAAW,KAAK,KAAK,cAAc,UAAU;AAEnD,QAAI,CAAC,SAAS,WAAW,YAAY,GAAG;AACtC,aAAO;AAAA,QACL,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,2BAA2B,CAAC;AAAA,QAC5D,mBAAmB,EAAE,IAAI,OAAO,OAAO,uBAAuB;AAAA,MAChE;AAAA,IACF;AACA,QAAI,CAAC,GAAG,WAAW,QAAQ,GAAG;AAC5B,aAAO;AAAA,QACL,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,8BAA2B,UAAU,GAAG,CAAC;AAAA,QACzE,mBAAmB,EAAE,IAAI,OAAO,OAAO,iBAAiB;AAAA,MAC1D;AAAA,IACF;AACA,UAAM,OAAO,GAAG,SAAS,QAAQ;AACjC,QAAI,KAAK,YAAY,GAAG;AACtB,aAAO;AAAA,QACL,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,mDAA6C,CAAC;AAAA,QAC9E,mBAAmB,EAAE,IAAI,OAAO,OAAO,eAAe;AAAA,MACxD;AAAA,IACF;AAEA,QAAI;AACF,YAAM,UAAU,GAAG,aAAa,UAAU,QAAQ;AAClD,aAAO;AAAA,QACL,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,QAAQ,CAAC;AAAA,QACzC,mBAAmB,EAAE,IAAI,MAAM,QAAQ;AAAA,MACzC;AAAA,IACF,SAAS,KAAK;AACZ,aAAO;AAAA,QACL,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,gBAAgB,IAAI,OAAO,GAAG,CAAC;AAAA,QAC/D,mBAAmB,EAAE,IAAI,OAAO,OAAO,IAAI,QAAQ;AAAA,MACrD;AAAA,IACF;AAAA,EACF;AACF;AAEA,OAAO;AAAA,EACL;AAAA,EACA;AAAA,IACE,OAAO;AAAA,IACP,aAAa;AAAA,IACb,aAAa,EAAE,OAAO,CAAC,CAAC;AAAA,IACxB,cAAc,EAAE,OAAO;AAAA,MACrB,IAAI,EAAE,QAAQ;AAAA,MACd,WAAW,EAAE,OAAO;AAAA,QAClB,UAAU,EAAE,QAAQ;AAAA,QACpB,gBAAgB,EAAE,MAAM,EAAE,OAAO,CAAC;AAAA,QAClC,UAAU,EAAE,MAAM,EAAE,OAAO,CAAC;AAAA,QAC5B,YAAY,EAAE,QAAQ;AAAA,QACtB,YAAY,EAAE,OAAO,EAAE,SAAS;AAAA,QAChC,aAAa,EAAE,QAAQ;AAAA,QACvB,aAAa,EAAE,OAAO,EAAE,SAAS;AAAA,MACnC,CAAC;AAAA,IACH,CAAC;AAAA,EACH;AAAA,EACA,YAAY;AACV,UAAM,YAAY,uBAAuB;AACzC,UAAM,UAAU;AAAA,MACd,wBAAwB,UAAU,eAAe,KAAK,IAAI,KAAK,QAAQ;AAAA,MACvE,oBAAoB,UAAU,SAAS,KAAK,IAAI,KAAK,SAAS;AAAA,MAC9D,YAAY,UAAU,cAAc,kBAAe;AAAA,MACnD,aAAa,UAAU,eAAe,kBAAe;AAAA,IACvD,EAAE,KAAK,IAAI;AAEX,WAAO;AAAA,MACL,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,QAAQ,CAAC;AAAA,MACzC,mBAAmB,EAAE,IAAI,MAAM,UAAU;AAAA,IAC3C;AAAA,EACF;AACF;AAMA,OAAO;AAAA,EACL;AAAA,EACA;AAAA,IACE,OAAO;AAAA,IACP,aAAa;AAAA,IACb,aAAa,EAAE,OAAO;AAAA,MACpB,KAAK,EAAE,OAAO,EAAE,SAAS,oEAAoE;AAAA,MAC7F,gBAAgB,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,iEAAiE;AAAA,MAChH,gBAAgB,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,mDAA6C;AAAA,MAC7F,gBAAgB,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,iDAAiD;AAAA,IACnG,CAAC;AAAA,IACD,cAAc,EAAE,OAAO;AAAA,MACrB,IAAI,EAAE,QAAQ;AAAA,MACd,gBAAgB,EAAE,OAAO,EAAE,SAAS;AAAA,MACpC,aAAa,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS;AAAA,MAC1C,eAAe,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS;AAAA,MAC5C,iBAAiB,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,GAAG,QAAQ,EAAE,OAAO,GAAG,QAAQ,EAAE,OAAO,EAAE,SAAS,EAAE,CAAC,CAAC,EAAE,SAAS;AAAA,MACpH,OAAO,EAAE,OAAO,EAAE,SAAS;AAAA,IAC7B,CAAC;AAAA,EACH;AAAA,EACA,OAAO,EAAE,KAAK,gBAAgB,iBAAiB,MAAM,iBAAiB,KAAK,MAAM;AAC/E,QAAI;AACJ,QAAI;AACF,mBAAa,MAAM,OAAO,YAAY;AAAA,IACxC,SAAS,GAAG;AACV,aAAO;AAAA,QACL,SAAS,CAAC;AAAA,UACR,MAAM;AAAA,UACN,MAAM;AAAA,QACR,CAAC;AAAA,QACD,mBAAmB,EAAE,IAAI,OAAO,OAAO,wDAAwD;AAAA,MACjG;AAAA,IACF;AAEA,UAAM,UAAU,iBAAiB,KAAK,KAAK,cAAc,eAAe,QAAQ,OAAO,EAAE,CAAC,IAAI,KAAK,KAAK,cAAc,wBAAwB;AAC9I,UAAM,cAAc,CAAC;AACrB,UAAM,gBAAgB,CAAC;AACvB,UAAM,kBAAkB,CAAC;AAEzB,QAAI;AACF,YAAM,UAAU,MAAM,WAAW,SAAS,OAAO,EAAE,UAAU,KAAK,CAAC;AACnE,YAAM,UAAU,MAAM,QAAQ,WAAW;AACzC,YAAM,OAAO,MAAM,QAAQ,QAAQ;AAEnC,UAAI,gBAAgB;AAClB,aAAK,GAAG,WAAW,CAAC,QAAQ;AAC1B,gBAAM,OAAO,IAAI,KAAK;AACtB,cAAI,IAAI,KAAK,MAAM,QAAS,eAAc,KAAK,IAAI;AAAA,cAC9C,aAAY,KAAK,IAAI,IAAI,KAAK,CAAC,KAAK,IAAI,EAAE;AAAA,QACjD,CAAC;AAAA,MACH;AAEA,UAAI,gBAAgB;AAClB,aAAK,GAAG,WAAW,CAAC,QAAQ;AAC1B,0BAAgB,KAAK,EAAE,KAAK,IAAI,IAAI,GAAG,QAAQ,IAAI,OAAO,GAAG,QAAQ,OAAU,CAAC;AAAA,QAClF,CAAC;AACD,aAAK,GAAG,YAAY,CAAC,QAAQ;AAC3B,gBAAM,MAAM,gBAAgB,KAAK,CAAC,MAAM,EAAE,QAAQ,IAAI,QAAQ,EAAE,IAAI,CAAC;AACrE,cAAI,IAAK,KAAI,SAAS,IAAI,OAAO;AAAA,QACnC,CAAC;AAAA,MACH;AAEA,YAAM,KAAK,KAAK,KAAK,EAAE,WAAW,eAAe,SAAS,IAAM,CAAC;AACjE,YAAM,KAAK,WAAW,EAAE,MAAM,SAAS,UAAU,MAAM,CAAC;AAExD,YAAM,QAAQ,MAAM;AAEpB,YAAM,UAAU,KAAK,SAAS,cAAc,OAAO;AACnD,UAAI,UAAU,qBAAqB,OAAO;AAC1C,UAAI,cAAc,OAAQ,YAAW;AAAA;AAAA,eAAU,cAAc,MAAM;AAAA,EAAyB,cAAc,MAAM,GAAG,CAAC,EAAE,KAAK,IAAI,CAAC;AAChI,UAAI,gBAAgB,OAAQ,YAAW;AAAA;AAAA,qBAAoB,gBAAgB,MAAM;AAEjF,aAAO;AAAA,QACL,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,QAAQ,CAAC;AAAA,QACzC,mBAAmB;AAAA,UACjB,IAAI;AAAA,UACJ,gBAAgB;AAAA,UAChB,aAAa,iBAAiB,YAAY,MAAM,GAAG,EAAE,IAAI;AAAA,UACzD,eAAe,kBAAkB,cAAc,SAAS,gBAAgB;AAAA,UACxE,iBAAiB,iBAAiB,gBAAgB,MAAM,GAAG,EAAE,IAAI;AAAA,QACnE;AAAA,MACF;AAAA,IACF,SAAS,KAAK;AACZ,aAAO;AAAA,QACL,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,SAAS,IAAI,OAAO,GAAG,CAAC;AAAA,QACxD,mBAAmB,EAAE,IAAI,OAAO,OAAO,IAAI,QAAQ;AAAA,MACrD;AAAA,IACF;AAAA,EACF;AACF;AAMA,IAAM,YAAY;AAAA,EAChB,YAAY,EAAE,OAAO,CAAC,SAAS,GAAG,MAAM,kEAA+D;AAAA,EACvG,WAAW,EAAE,OAAO,CAAC,kBAAkB,gBAAgB,iBAAiB,GAAG,MAAM,qDAA+C;AAAA,EAChI,WAAW,EAAE,OAAO,CAAC,aAAa,eAAe,mBAAmB,GAAG,MAAM,uCAAiC;AAAA,EAC9G,YAAY,EAAE,OAAO,CAAC,kBAAkB,cAAc,sBAAsB,GAAG,MAAM,kCAA4B;AAAA,EACjH,UAAU,EAAE,OAAO,CAAC,oBAAoB,kBAAkB,eAAe,sBAAsB,GAAG,MAAM,sCAAgC;AAAA,EACxI,SAAS,EAAE,OAAO,CAAC,kBAAkB,GAAG,MAAM,kEAA4D;AAAA,EAC1G,WAAW,EAAE,OAAO,CAAC,qBAAqB,sBAAsB,GAAG,MAAM,8BAAwB;AAAA,EACjG,UAAU,EAAE,OAAO,CAAC,mBAAmB,GAAG,MAAM,kDAAyC;AAAA,EACzF,aAAa,EAAE,OAAO,CAAC,cAAc,wBAAwB,sBAAsB,GAAG,MAAM,6CAAiC;AAC/H;AAEA,OAAO;AAAA,EACL;AAAA,EACA;AAAA,IACE,OAAO;AAAA,IACP,aAAa;AAAA,IACb,aAAa,EAAE,OAAO;AAAA,MACpB,MAAM,EAAE,OAAO,EAAE,SAAS,uGAAiG;AAAA,IAC7H,CAAC;AAAA,IACD,cAAc,EAAE,OAAO;AAAA,MACrB,IAAI,EAAE,QAAQ;AAAA,MACd,gBAAgB,EAAE,OAAO;AAAA,MACzB,gBAAgB,EAAE,MAAM,EAAE,OAAO,CAAC;AAAA,MAClC,aAAa,EAAE,OAAO;AAAA,IACxB,CAAC;AAAA,EACH;AAAA,EACA,OAAO,EAAE,KAAK,MAAM;AAClB,UAAM,IAAI,KAAK,YAAY;AAC3B,QAAI,+DAA+D,KAAK,CAAC,GAAG;AAC1E,aAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,kFAA6E,CAAC,GAAG,mBAAmB,EAAE,IAAI,MAAM,gBAAgB,cAAc,gBAAgB,UAAU,WAAW,OAAO,aAAa,UAAU,WAAW,KAAK,EAAE;AAAA,IAC9Q;AACA,QAAI,qEAAqE,KAAK,CAAC,GAAG;AAChF,aAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,4CAAuC,CAAC,GAAG,mBAAmB,EAAE,IAAI,MAAM,gBAAgB,YAAY,gBAAgB,UAAU,SAAS,OAAO,aAAa,UAAU,SAAS,KAAK,EAAE;AAAA,IAClO;AACA,QAAI,0CAA0C,KAAK,CAAC,GAAG;AACrD,aAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,wDAAmD,CAAC,GAAG,mBAAmB,EAAE,IAAI,MAAM,gBAAgB,aAAa,gBAAgB,UAAU,UAAU,OAAO,aAAa,UAAU,UAAU,KAAK,EAAE;AAAA,IACjP;AACA,QAAI,gDAAgD,KAAK,CAAC,GAAG;AAC3D,aAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,uDAAkD,CAAC,GAAG,mBAAmB,EAAE,IAAI,MAAM,gBAAgB,cAAc,gBAAgB,UAAU,WAAW,OAAO,aAAa,UAAU,WAAW,KAAK,EAAE;AAAA,IACnP;AACA,QAAI,yDAAyD,KAAK,CAAC,GAAG;AACpE,aAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,wEAAmE,CAAC,GAAG,mBAAmB,EAAE,IAAI,MAAM,gBAAgB,YAAY,gBAAgB,UAAU,SAAS,OAAO,aAAa,UAAU,SAAS,KAAK,EAAE;AAAA,IAC9P;AACA,QAAI,2DAA2D,KAAK,CAAC,GAAG;AACtE,aAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,0CAAqC,CAAC,GAAG,mBAAmB,EAAE,IAAI,MAAM,gBAAgB,WAAW,gBAAgB,UAAU,QAAQ,OAAO,aAAa,UAAU,QAAQ,KAAK,EAAE;AAAA,IAC7N;AACA,QAAI,gDAAgD,KAAK,CAAC,GAAG;AAC3D,aAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,2DAAsD,CAAC,GAAG,mBAAmB,EAAE,IAAI,MAAM,gBAAgB,aAAa,gBAAgB,UAAU,UAAU,OAAO,aAAa,UAAU,UAAU,KAAK,EAAE;AAAA,IACpP;AACA,QAAI,2CAA2C,KAAK,CAAC,GAAG;AACtD,aAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,mEAA8D,CAAC,GAAG,mBAAmB,EAAE,IAAI,MAAM,gBAAgB,aAAa,gBAAgB,UAAU,UAAU,OAAO,aAAa,UAAU,UAAU,KAAK,EAAE;AAAA,IAC5P;AACA,WAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,kCAA+B,CAAC,GAAG,mBAAmB,EAAE,IAAI,MAAM,gBAAgB,aAAa,gBAAgB,UAAU,UAAU,OAAO,aAAa,UAAU,UAAU,KAAK,EAAE;AAAA,EAC7N;AACF;AAEA,OAAO;AAAA,EACL;AAAA,EACA;AAAA,IACE,OAAO;AAAA,IACP,aAAa;AAAA,IACb,aAAa,EAAE,OAAO;AAAA,MACpB,WAAW,EAAE,KAAK;AAAA,QAChB;AAAA,QAAW;AAAA,QAAc;AAAA,QAAe;AAAA,QAAQ;AAAA,QAAU;AAAA,QAC1D;AAAA,QAAU;AAAA,QAAS;AAAA,QAAS;AAAA,QAAU;AAAA,QAAa;AAAA,QACnD;AAAA,QAAY;AAAA,QAAc;AAAA,QAAa;AAAA,QAAc;AAAA,MACvD,CAAC,EAAE,SAAS,EAAE,SAAS,iDAA8C;AAAA,MACrE,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,+CAA+C;AAAA,MACpF,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,kCAAkC;AAAA,MACxE,kBAAkB,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,2IAAkI;AAAA,IACtL,CAAC;AAAA,IACD,cAAc,EAAE,OAAO;AAAA,MACrB,QAAQ,EAAE,KAAK,CAAC,UAAU,UAAU,WAAW,CAAC;AAAA,MAChD,SAAS,EAAE,OAAO;AAAA,MAClB,UAAU,EAAE,OAAO;AAAA,MACnB,WAAW,EAAE,OAAO,EAAE,SAAS;AAAA,IACjC,CAAC;AAAA,EACH;AAAA,EACA,OAAO,EAAE,WAAW,MAAM,OAAO,iBAAiB,MAAM;AACtD,UAAM,YAAY,uBAAuB;AAEzC,QAAI,CAAC,UAAU,UAAU;AACvB,aAAO;AAAA,QACL,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,kDAAkD,CAAC;AAAA,QACnF,mBAAmB;AAAA,UACjB,QAAQ;AAAA,UACR,SAAS;AAAA,UACT,UAAU;AAAA,QACZ;AAAA,MACF;AAAA,IACF;AAEA,QAAI,oBAAoB;AACxB,QAAI,CAAC,qBAAqB,UAAU,eAAe,SAAS,GAAG;AAC7D,0BAAoB,UAAU,eAAe,CAAC;AAAA,IAChD;AAEA,QAAI,KAAK,MAAM;AAGf,QAAI,sBAAsB,WAAW;AACnC,YAAM;AACN,aAAO,OAAO,CAAC,WAAW,OAAO,UAAU,IAAI,IAAI,CAAC,WAAW,KAAK;AACpE,YAAM,UAAU,SAAS,SAAS,SAAS,IACvC,KAAK,KAAK,cAAc,SAAS,IACjC,UAAU,SAAS,CAAC,IACpB,KAAK,KAAK,cAAc,UAAU,SAAS,CAAC,CAAC,IAC7C;AAAA,IACN,WAAW,sBAAsB,cAAc;AAC7C,YAAM;AACN,aAAO,OAAO,CAAC,cAAc,QAAQ,IAAI,IAAI,CAAC,cAAc,MAAM;AAClE,YAAM,UAAU,SAAS,SAAS,YAAY,IAC1C,KAAK,KAAK,cAAc,YAAY,IACpC,UAAU,SAAS,CAAC,IACpB,KAAK,KAAK,cAAc,UAAU,SAAS,CAAC,CAAC,IAC7C;AAAA,IACN,WAAW,sBAAsB,eAAe;AAC9C,YAAM;AACN,aAAO,OAAO,CAAC,QAAQ,OAAO,IAAI,IAAI,CAAC,QAAQ,KAAK;AACpD,YAAM,gBAAgB,WAAW,CAAC,qBAAqB,SAAS,OAAO,CAAC;AAAA,IAC1E,WAAW,sBAAsB,YAAY;AAC3C,YAAM;AACN,aAAO,OAAO,CAAC,YAAY,IAAI,IAAI,CAAC,UAAU;AAC9C,YAAM,gBAAgB,WAAW,CAAC,eAAe,YAAY,OAAO,CAAC;AAAA,IACvE,WAAW,sBAAsB,cAAc;AAC7C,YAAM;AACN,aAAO,OAAO,CAAC,cAAc,UAAU,IAAI,IAAI,CAAC,YAAY;AAC5D,YAAM,gBAAgB,WAAW,CAAC,iBAAiB,cAAc,OAAO,CAAC;AAAA,IAC3E,WAAW,sBAAsB,aAAa;AAC5C,YAAM;AACN,aAAO,OAAO,CAAC,QAAQ,MAAM,YAAY,gBAAgB,IAAI,CAAC,MAAM;AACpE,YAAM,gBAAgB,WAAW,CAAC,gBAAgB,aAAa,WAAW,CAAC;AAAA,IAC7E,WAAW,sBAAsB,cAAc;AAC7C,YAAM;AACN,aAAO,OAAO,CAAC,cAAc,OAAO,UAAU,IAAI,IAAI,CAAC,cAAc,KAAK;AAC1E,YAAM,gBAAgB,WAAW,CAAC,cAAc,OAAO,CAAC;AAAA,IAG1D,WAAW,sBAAsB,QAAQ;AACvC,YAAM;AACN,aAAO,CAAC,MAAM;AACd,UAAI,KAAM,MAAK,KAAK,IAAI;AACxB,YAAM;AAAA,IACR,WAAW,sBAAsB,UAAU;AACzC,YAAM;AACN,aAAO,CAAC,UAAU,KAAK;AACvB,UAAI,KAAM,MAAK,KAAK,IAAI;AACxB,YAAM;AAAA,IACR,WAAW,sBAAsB,SAAS;AACxC,YAAM;AACN,aAAO,OAAO,CAAC,SAAS,IAAI,IAAI,CAAC,OAAO;AACxC,YAAM;AAAA,IAGR,WAAW,sBAAsB,UAAU;AACzC,YAAM;AACN,aAAO,OAAO,CAAC,QAAQ,OAAO,IAAI,IAAI,CAAC,QAAQ,KAAK;AACpD,YAAM;AAAA,IACR,WAAW,sBAAsB,SAAS;AACxC,YAAM;AACN,aAAO,CAAC,SAAS,MAAM;AACvB,UAAI,KAAM,MAAK,KAAK,IAAI;AACxB,YAAM;AAAA,IAGR,WAAW,sBAAsB,SAAS;AACxC,YAAM;AACN,aAAO,OAAO,CAAC,IAAI,IAAI,CAAC,UAAU,SAAS,CAAC,KAAK,OAAO;AACxD,YAAM;AAAA,IACR,WAAW,sBAAsB,UAAU;AACzC,YAAM;AACN,aAAO,OAAO,CAAC,IAAI,IAAI,CAAC;AACxB,YAAM;AAAA,IAGR,WAAW,sBAAsB,eAAe,sBAAsB,UAAU;AAC9E,YAAM;AACN,aAAO,CAAC,MAAM;AACd,YAAM;AAAA,IAGR,OAAO;AACL,YAAM;AACN,aAAO,CAAC,MAAM;AACd,YAAM;AAAA,IACR;AAEA,UAAM,YAAY,KAAK,IAAI;AAC3B,WAAO,IAAI,QAAQ,CAAC,YAAY;AAC9B,YAAM,QAAQ,MAAM,KAAK,MAAM;AAAA,QAC7B;AAAA,QACA,OAAO,CAAC,WAAW,QAAQ,MAAM;AAAA,QACjC,OAAO,QAAQ,aAAa;AAAA,QAC5B,KAAK,EAAE,GAAG,QAAQ,IAAI;AAAA,MACxB,CAAC;AAED,UAAI,SAAS;AACb,UAAI,SAAS;AACb,UAAI,MAAM,QAAQ;AAChB,cAAM,OAAO,GAAG,QAAQ,CAAC,MAAM;AAC7B,gBAAM,IAAI,EAAE,SAAS;AACrB,oBAAU;AACV,kBAAQ,OAAO,MAAM,CAAC;AAAA,QACxB,CAAC;AAAA,MACH;AACA,UAAI,MAAM,QAAQ;AAChB,cAAM,OAAO,GAAG,QAAQ,CAAC,MAAM;AAC7B,gBAAM,IAAI,EAAE,SAAS;AACrB,oBAAU;AACV,kBAAQ,OAAO,MAAM,CAAC;AAAA,QACxB,CAAC;AAAA,MACH;AAEA,YAAM,GAAG,SAAS,CAAC,SAAS;AAC1B,cAAM,YAAY,CAAC,QAAQ,MAAM,EAAE,OAAO,OAAO,EAAE,KAAK,IAAI,EAAE,KAAK;AACnE,cAAM,SAAS,SAAS;AACxB,cAAM,kBAAkB,KAAK,OAAO,KAAK,IAAI,IAAI,aAAa,GAAI;AAClE,YAAI,CAAC,UAAU,WAAW;AACxB,cAAI;AACF,eAAG,cAAc,KAAK,KAAK,cAAc,0BAA0B,GAAG,WAAW,MAAM;AAAA,UACzF,QAAQ;AAAA,UAAC;AAAA,QACX;AACA,cAAM,EAAE,QAAQ,GAAG,QAAQ,EAAE,IAAI,mBAAmB,WAAW,IAAI;AACnE,2BAAmB;AAAA,UACjB,MAAM;AAAA,UACN,WAAW;AAAA,UACX,MAAM,QAAQ;AAAA,UACd,QAAQ;AAAA,UACR,QAAQ;AAAA,UACR;AAAA,UACA,UAAU,QAAQ;AAAA,UAClB,UAAU,CAAC,SAAS,0BAA0B,SAAS,IAAI;AAAA,QAC7D,CAAC;AACD,YAAI,OAAQ,mBAAkB,EAAE,SAAS,EAAE,MAAM,QAAQ,MAAM,WAAW,mBAAmB,QAAQ,EAAE,EAAE,CAAC;AAC1G,gBAAQ;AAAA,UACN,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,SAAS,mCAAmC,sCAAgC,CAAC;AAAA,UAC7G,mBAAmB;AAAA,YACjB,QAAQ,SAAS,WAAW;AAAA,YAC5B,SAAS,SAAS,iBAAiB;AAAA,YACnC,UAAU,QAAQ;AAAA,YAClB,WAAW,CAAC,SAAS,YAAY;AAAA,UACnC;AAAA,QACF,CAAC;AAAA,MACH,CAAC;AAAA,IACH,CAAC;AAAA,EACH;AACF;AAEA,OAAO;AAAA,EACL;AAAA,EACA;AAAA,IACE,OAAO;AAAA,IACP,aAAa;AAAA,IACb,aAAa,EAAE,OAAO;AAAA,MACpB,gBAAgB,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,mGAA6F;AAAA,MAC7I,UAAU,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,kEAAyD;AAAA,IACpG,CAAC;AAAA,IACD,cAAc,EAAE,OAAO;AAAA,MACrB,IAAI,EAAE,QAAQ;AAAA,MACd,SAAS,EAAE,OAAO;AAAA,MAClB,aAAa,EAAE,OAAO,CAAC,CAAC,EAAE,YAAY,EAAE,SAAS;AAAA,MACjD,WAAW,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS;AAAA,MACxC,sBAAsB,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,GAAG,SAAS,EAAE,OAAO,EAAE,CAAC,CAAC,EAAE,SAAS;AAAA,IAC9F,CAAC;AAAA,EACH;AAAA,EACA,OAAO,EAAE,iBAAiB,OAAO,WAAW,EAAE,IAAI,CAAC,MAAM;AACvD,UAAM,YAAY,uBAAuB;AACzC,UAAM,YAAY,iBAAiB,WAAW;AAAA,MAC5C,iBAAiB,iBAAiB,WAAW;AAAA,IAC/C,CAAC;AAED,UAAM,YAAY,UAAU,IAAI,CAAC,MAAM,EAAE,IAAI;AAC7C,UAAM,uBAAuB,iBACzB,UAAU,OAAO,CAAC,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,EAAE,QAAQ,EAAE,IACpF;AAEJ,UAAM,UAAU;AAAA,MACd,eAAe,UAAU,eAAe,KAAK,IAAI,KAAK,QAAQ;AAAA,MAC9D,sBAAsB,UAAU,MAAM;AAAA,MACtC,YAAY,UAAU,cAAc,kBAAe;AAAA,MACnD,aAAa,UAAU,eAAe,kBAAe;AAAA,MACrD,kBAAkB,sBAAsB,SACpC,4BAAsB,qBAAqB,MAAM,mCACjD;AAAA,IACN,EACG,OAAO,OAAO,EACd,KAAK,IAAI;AAEZ,WAAO;AAAA,MACL,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,QAAQ,CAAC;AAAA,MACzC,mBAAmB;AAAA,QACjB,IAAI;AAAA,QACJ;AAAA,QACA,aAAa,UAAU;AAAA,QACvB,WAAW,UAAU,MAAM,GAAG,GAAG;AAAA,QACjC;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;AAEA,OAAO;AAAA,EACL;AAAA,EACA;AAAA,IACE,OAAO;AAAA,IACP,aAAa;AAAA,IACb,aAAa,EAAE,OAAO;AAAA,MACpB,SAAS,EAAE,OAAO,EAAE,SAAS,wDAAkD;AAAA,MAC/E,SAAS,EAAE,OAAO,EAAE,SAAS,kFAAkF;AAAA,MAC/G,WAAW,EAAE,KAAK;AAAA,QAChB;AAAA,QAAW;AAAA,QAAc;AAAA,QAAe;AAAA,QAAQ;AAAA,QAAU;AAAA,QAC1D;AAAA,QAAU;AAAA,QAAS;AAAA,QAAU;AAAA,QAAa;AAAA,QAAU;AAAA,MACtD,CAAC,EAAE,SAAS,EAAE,SAAS,mDAAmD;AAAA,MAC1E,eAAe,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,0HAAoH;AAAA,MAClK,gBAAgB,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS,EAAE,SAAS,wFAA+E;AAAA,IACzI,CAAC;AAAA,IACD,cAAc,EAAE,OAAO;AAAA,MACrB,IAAI,EAAE,QAAQ;AAAA,MACd,aAAa,EAAE,OAAO,EAAE,SAAS;AAAA,MACjC,mBAAmB,EAAE,OAAO,EAAE,SAAS;AAAA,MACvC,OAAO,EAAE,OAAO,EAAE,SAAS;AAAA,IAC7B,CAAC;AAAA,EACH;AAAA,EACA,OAAO,EAAE,SAAS,SAAS,WAAW,eAAe,eAAe,MAAM;AACxE,UAAM,YAAY,uBAAuB;AACzC,UAAM,KAAK,aAAa,UAAU,eAAe,CAAC,KAAK;AAEvD,QAAI,iBAAiB;AACrB,QAAI,cAAe,mBAAkB;AAAA;AAAA,0EAAsE,EAAE;AAAA,EAAU,cAAc,MAAM,GAAG,GAAI,CAAC;AACnJ,QAAI,gBAAgB,QAAQ;AAC1B,iBAAW,KAAK,eAAe,MAAM,GAAG,CAAC,GAAG;AAC1C,cAAM,OAAO,KAAK,KAAK,cAAc,EAAE,QAAQ,OAAO,EAAE,EAAE,QAAQ,OAAO,GAAG,CAAC;AAC7E,YAAI,GAAG,WAAW,IAAI,GAAG;AACvB,cAAI;AACF,kBAAM,UAAU,GAAG,aAAa,MAAM,MAAM;AAC5C,8BAAkB;AAAA;AAAA,eAAoB,CAAC;AAAA,EAAS,QAAQ,MAAM,GAAG,GAAI,CAAC;AAAA,UACxE,QAAQ;AAAA,UAAC;AAAA,QACX;AAAA,MACF;AAAA,IACF;AAEA,UAAM,MAAM,mBAAmB,QAAQ;AACvC,QAAI,CAAC,IAAI,QAAQ;AACf,aAAO;AAAA,QACL,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,mEAAmE,CAAC;AAAA,QACpG,mBAAmB,EAAE,IAAI,OAAO,OAAO,wBAAwB;AAAA,MACjE;AAAA,IACF;AACA,UAAM,EAAE,UAAU,QAAQ,SAAS,MAAM,IAAI;AAE7C,UAAM,SAAS,kBAAkB;AACjC,UAAM,cAAc,OAAO,OAAO,SAC9B;AAAA;AAAA,8CAAgD,OAAO,MAAM,IAAI,CAAC,MAAM,EAAE,QAAQ,EAAE,EAAE,EAAE,KAAK,IAAI,CAAC,KAClG;AACJ,UAAM,oBAAoB,UAAU;AAEpC,UAAM,eAAe,QAAQ,gBAAgB,KAAK,CAAC;AACnD,UAAM,eAAe,eACjB,kGAAsF,EAAE;AAAA;AAAA;AAAA,uDAG/C,EAAE;AAAA;AAAA,+CAG3C,qDAA+C,EAAE;AAAA,aAC5C,EAAE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAUX,UAAM,aAAa;AAAA,EACrB,kBAAkB,MAAM,GAAG,GAAI,CAAC;AAAA;AAAA,sBAEZ,OAAO;AAAA,kBACX,EAAE,GAAG,cAAc;AAEjC,QAAI;AACF,UAAI;AACJ,UAAI,aAAa,UAAU;AACzB,cAAM,MAAM,GAAG,OAAO,WAAW,KAAK,wBAAwB,MAAM;AACpE,cAAM,MAAM,MAAM,MAAM,KAAK;AAAA,UAC3B,QAAQ;AAAA,UACR,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,UAC9C,MAAM,KAAK,UAAU;AAAA,YACnB,mBAAmB,EAAE,OAAO,CAAC,EAAE,MAAM,aAAa,CAAC,EAAE;AAAA,YACrD,UAAU,CAAC,EAAE,OAAO,CAAC,EAAE,MAAM,WAAW,CAAC,EAAE,CAAC;AAAA,YAC5C,kBAAkB,EAAE,aAAa,KAAK,iBAAiB,KAAK;AAAA,UAC9D,CAAC;AAAA,QACH,CAAC;AACD,cAAM,OAAO,MAAM,IAAI,KAAK;AAC5B,sBAAc,KAAK,aAAa,CAAC,GAAG,SAAS,QAAQ,CAAC,GAAG,QAAQ;AAAA,MACnE,OAAO;AACL,cAAM,MAAM,MAAM,MAAM,GAAG,OAAO,qBAAqB;AAAA,UACrD,QAAQ;AAAA,UACR,SAAS;AAAA,YACP,gBAAgB;AAAA,YAChB,eAAe,UAAU,MAAM;AAAA,UACjC;AAAA,UACA,MAAM,KAAK,UAAU;AAAA,YACnB;AAAA,YACA,UAAU;AAAA,cACR,EAAE,MAAM,UAAU,SAAS,aAAa;AAAA,cACxC,EAAE,MAAM,QAAQ,SAAS,WAAW;AAAA,YACtC;AAAA,YACA,aAAa;AAAA,YACb,YAAY;AAAA,UACd,CAAC;AAAA,QACH,CAAC;AACD,cAAM,OAAO,MAAM,IAAI,KAAK;AAC5B,sBAAc,KAAK,UAAU,CAAC,GAAG,SAAS,WAAW;AAAA,MACvD;AAEA,oBAAc,YAAY,QAAQ,8BAA8B,EAAE,EAAE,QAAQ,eAAe,EAAE,EAAE,KAAK;AACpG,YAAM,WAAW,QAAQ,YAAY,EAAE,QAAQ,QAAQ,GAAG,EAAE,QAAQ,eAAe,EAAE,EAAE,MAAM,GAAG,EAAE;AAElG,aAAO;AAAA,QACL,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,gBAAgB,YAAY,MAAM,uCAAuC,CAAC;AAAA,QAC1G,mBAAmB;AAAA,UACjB,IAAI;AAAA,UACJ;AAAA,UACA,mBAAmB;AAAA,QACrB;AAAA,MACF;AAAA,IACF,SAAS,KAAK;AACZ,aAAO;AAAA,QACL,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,kBAAkB,IAAI,OAAO,GAAG,CAAC;AAAA,QACjE,mBAAmB,EAAE,IAAI,OAAO,OAAO,IAAI,QAAQ;AAAA,MACrD;AAAA,IACF;AAAA,EACF;AACF;AAEA,SAAS,uBAAuB,IAAI,WAAW;AAC7C,QAAM,SAAS;AAAA,IACb,SAAS;AAAA,IACT,YAAY;AAAA,IACZ,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,aAAa;AAAA,IACb,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,WAAW;AAAA,IACX,QAAQ;AAAA,EACV;AACA,QAAM,MAAM,OAAO,EAAE,KAAK;AAE1B,QAAM,UAAU;AAAA,IACd,SAAS,UAAU,SAAS,SAAS,SAAS,IAAI,YAAY,UAAU,SAAS,CAAC,KAAK;AAAA,IACvF,YAAY,UAAU,SAAS,SAAS,YAAY,IAAI,eAAe,UAAU,SAAS,CAAC,KAAK;AAAA,IAChG,aAAa,UAAU,SAAS,SAAS,OAAO,IAAI,UAAU,UAAU,SAAS,CAAC,KAAK;AAAA,IACvF,QAAQ,UAAU,SAAS,SAAS,OAAO,IAAI,UAAU,UAAU,SAAS,CAAC,KAAK;AAAA,IAClF,OAAO,UAAU,SAAS,SAAS,OAAO,IAAI,UAAU,UAAU,SAAS,CAAC,KAAK;AAAA,IACjF,QAAQ,UAAU,SAAS,SAAS,UAAU,IAAI,aAAa,UAAU,SAAS,CAAC,KAAK;AAAA,EAC1F;AACA,QAAM,UAAU,KAAK,KAAK,cAAc,QAAQ,EAAE,KAAK,UAAU,SAAS,CAAC,KAAK,OAAO;AACvF,SAAO,EAAE,KAAK,QAAQ;AACxB;AAEA,OAAO;AAAA,EACL;AAAA,EACA;AAAA,IACE,OAAO;AAAA,IACP,aAAa;AAAA,IACb,aAAa,EAAE,OAAO;AAAA,MACpB,MAAM,EAAE,OAAO,EAAE,SAAS,gDAAgD;AAAA,MAC1E,SAAS,EAAE,OAAO,EAAE,SAAS,sBAAmB;AAAA,MAChD,WAAW,EAAE,KAAK;AAAA,QAChB;AAAA,QAAW;AAAA,QAAc;AAAA,QAAQ;AAAA,QAAU;AAAA,QAAS;AAAA,QACpD;AAAA,QAAU;AAAA,QAAS;AAAA,QAAS;AAAA,QAAU;AAAA,QAAU;AAAA,MAClD,CAAC,EAAE,SAAS,EAAE,SAAS,mDAAmD;AAAA,MAC1E,QAAQ,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,4DAA4D;AAAA,IACrG,CAAC;AAAA,IACD,cAAc,EAAE,OAAO;AAAA,MACrB,IAAI,EAAE,QAAQ;AAAA,MACd,MAAM,EAAE,OAAO,EAAE,SAAS;AAAA,MAC1B,OAAO,EAAE,OAAO,EAAE,SAAS;AAAA,IAC7B,CAAC;AAAA,EACH;AAAA,EACA,OAAO,EAAE,MAAM,SAAS,WAAW,OAAO,MAAM;AAC9C,UAAM,YAAY,uBAAuB;AACzC,UAAM,KAAK,aAAa,UAAU,eAAe,CAAC;AAElD,QAAI,CAAC,IAAI;AACP,aAAO;AAAA,QACL,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,uCAAuC,CAAC;AAAA,QACxE,mBAAmB,EAAE,IAAI,OAAO,OAAO,oBAAoB;AAAA,MAC7D;AAAA,IACF;AAEA,UAAM,EAAE,KAAK,QAAQ,IAAI,uBAAuB,IAAI,SAAS;AAC7D,UAAM,WAAW,KACd,QAAQ,iBAAiB,GAAG,EAC5B,QAAQ,OAAO,GAAG,EAClB,QAAQ,OAAO,GAAG,EAClB,QAAQ,qDAAqD,EAAE,EAC/D,QAAQ,kBAAkB,EAAE;AAC/B,UAAM,WAAW,IAAI,WAAW,GAAG,IAAI,GAAG,QAAQ,GAAG,GAAG,KAAK,GAAG,QAAQ,GAAG,GAAG;AAE9E,UAAM,YAAY,SAAS,KAAK,KAAK,SAAS,MAAM,IAAI;AACxD,UAAM,WAAW,KAAK,KAAK,WAAW,QAAQ;AAE9C,QAAI;AACF,UAAI,CAAC,GAAG,WAAW,SAAS,GAAG;AAC7B,WAAG,UAAU,WAAW,EAAE,WAAW,KAAK,CAAC;AAAA,MAC7C;AACA,SAAG,cAAc,UAAU,SAAS,MAAM;AAC1C,aAAO;AAAA,QACL,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,oBAAoB,QAAQ,GAAG,CAAC;AAAA,QAChE,mBAAmB,EAAE,IAAI,MAAM,MAAM,SAAS;AAAA,MAChD;AAAA,IACF,SAAS,KAAK;AACZ,aAAO;AAAA,QACL,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,mBAAmB,IAAI,OAAO,GAAG,CAAC;AAAA,QAClE,mBAAmB,EAAE,IAAI,OAAO,OAAO,IAAI,QAAQ;AAAA,MACrD;AAAA,IACF;AAAA,EACF;AACF;AAEA,OAAO;AAAA,EACL;AAAA,EACA;AAAA,IACE,OAAO;AAAA,IACP,aAAa;AAAA,IACb,aAAa,EAAE,OAAO;AAAA,MACpB,WAAW,EAAE,OAAO,EAAE,SAAS,kCAAkC;AAAA,IACnE,CAAC;AAAA,IACD,cAAc,EAAE,OAAO;AAAA,MACrB,IAAI,EAAE,QAAQ;AAAA,MACd,SAAS,EAAE,OAAO;AAAA,MAClB,UAAU,EAAE,MAAM,EAAE,OAAO;AAAA,QACzB,MAAM,EAAE,OAAO,EAAE,SAAS;AAAA,QAC1B,SAAS,EAAE,OAAO,EAAE,SAAS;AAAA,QAC7B,OAAO,EAAE,OAAO,EAAE,SAAS;AAAA,MAC7B,CAAC,CAAC,EAAE,SAAS;AAAA,IACf,CAAC;AAAA,EACH;AAAA,EACA,OAAO,EAAE,UAAU,MAAM;AACvB,UAAM,WAAW,CAAC;AAClB,UAAM,QAAQ,UAAU,MAAM,IAAI;AAElC,aAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACrC,YAAM,OAAO,MAAM,CAAC;AACpB,UAAI,wBAAwB,KAAK,IAAI,GAAG;AACtC,iBAAS,KAAK;AAAA,UACZ,MAAM,MAAM,IAAI,CAAC,KAAK;AAAA,UACtB,SAAS,KAAK,KAAK;AAAA,UACnB,OAAO,MAAM,MAAM,GAAG,IAAI,CAAC,EAAE,KAAK,IAAI;AAAA,QACxC,CAAC;AAAA,MACH;AAAA,IACF;AAEA,UAAM,gBAAgB,oBAAoB,SAAS;AACnD,QAAI,UAAU,SAAS,SACnB,GAAG,SAAS,MAAM,4BAClB;AACJ,QAAI,cAAc,eAAe;AAC/B,iBAAW;AAAA;AAAA,wCAAgC,KAAK,MAAM,cAAc,aAAa,GAAG,CAAC,gCAA0B,cAAc,SAAS,IAAI,CAAC,MAAM,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;AACtK,iBAAW;AACX,oBAAc,SAAS,QAAQ,CAAC,MAAM;AACpC,mBAAW;AAAA,SAAO,EAAE,OAAO,KAAK,EAAE,UAAU;AAAA,MAC9C,CAAC;AACD,UAAI,cAAc,SAAS,KAAK,CAAC,MAAM,EAAE,YAAY,YAAY,EAAE,YAAY,SAAS,GAAG;AACzF,mBAAW;AAAA,MACb;AAAA,IACF;AAEA,WAAO;AAAA,MACL,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,QAAQ,CAAC;AAAA,MACzC,mBAAmB;AAAA,QACjB,IAAI;AAAA,QACJ;AAAA,QACA,UAAU,SAAS,SAAS,WAAW;AAAA,QACvC,OAAO,cAAc,gBAAgB,EAAE,YAAY,cAAc,YAAY,UAAU,cAAc,SAAS,IAAI;AAAA,MACpH;AAAA,IACF;AAAA,EACF;AACF;AAMA,SAAS,yBAAyB,MAAM;AACtC,QAAM,QAAQ;AAAA,IACZ;AAAA,IACA;AAAA,IACA,KAAK,iBAAiB;AAAA,IACtB;AAAA,IACA;AAAA,IACA;AAAA,IACA,GAAI,MAAM,QAAQ,KAAK,yBAAyB,IAC5C,KAAK,0BAA0B,IAAI,CAAC,MAAM,UAAK,CAAC,EAAE,IAClD,CAAC,KAAK,6BAA6B,EAAE;AAAA,IACzC;AAAA,IACA;AAAA,IACA;AAAA,IACA,GAAI,MAAM,QAAQ,KAAK,cAAc,IACjC,KAAK,eAAe,IAAI,CAAC,GAAG,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,IAClD,CAAC,KAAK,kBAAkB,EAAE;AAAA,EAChC;AACA,MAAI,KAAK,kBAAkB;AACzB,UAAM,KAAK,IAAI,oCAA2B,IAAI,SAAS,KAAK,aAAa,OAAO,KAAK,kBAAkB,KAAK;AAAA,EAC9G;AACA,MAAI,KAAK,UAAU;AACjB,UAAM,KAAK,IAAI,eAAe,IAAI,KAAK,QAAQ;AAAA,EACjD;AACA,SAAO,MAAM,OAAO,OAAO,EAAE,KAAK,IAAI;AACxC;AAEA,eAAe,sBAAsB,UAAU,QAAQ,SAAS,OAAO,cAAc,YAAY;AAC/F,MAAI,aAAa,UAAU;AACzB,UAAM,MAAM,GAAG,OAAO,WAAW,KAAK,wBAAwB,MAAM;AACpE,UAAMC,OAAM,MAAM,MAAM,KAAK;AAAA,MAC3B,QAAQ;AAAA,MACR,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,MAC9C,MAAM,KAAK,UAAU;AAAA,QACnB,UAAU,CAAC,EAAE,OAAO,CAAC,EAAE,MAAM,eAAe,SAAS,WAAW,CAAC,EAAE,CAAC;AAAA,QACpE,kBAAkB,EAAE,aAAa,KAAK,iBAAiB,KAAK;AAAA,MAC9D,CAAC;AAAA,IACH,CAAC;AACD,UAAMC,QAAO,MAAMD,KAAI,KAAK;AAC5B,WAAOC,MAAK,aAAa,CAAC,GAAG,SAAS,QAAQ,CAAC,GAAG,QAAQ;AAAA,EAC5D;AACA,QAAM,MAAM,MAAM,MAAM,GAAG,OAAO,qBAAqB;AAAA,IACrD,QAAQ;AAAA,IACR,SAAS;AAAA,MACP,gBAAgB;AAAA,MAChB,eAAe,UAAU,MAAM;AAAA,IACjC;AAAA,IACA,MAAM,KAAK,UAAU;AAAA,MACnB;AAAA,MACA,UAAU;AAAA,QACR,EAAE,MAAM,UAAU,SAAS,aAAa;AAAA,QACxC,EAAE,MAAM,QAAQ,SAAS,WAAW;AAAA,MACtC;AAAA,MACA,aAAa;AAAA,MACb,YAAY;AAAA,IACd,CAAC;AAAA,EACH,CAAC;AACD,QAAM,OAAO,MAAM,IAAI,KAAK;AAC5B,SAAO,KAAK,UAAU,CAAC,GAAG,SAAS,WAAW;AAChD;AAGA,eAAe,2BAA2B,gBAAgB,eAAe,MAAM;AAC7E,QAAM,YAAY,uBAAuB;AACzC,QAAM,KAAK,UAAU,eAAe,CAAC,KAAK;AAE1C,MAAI,WAAW;AACf,MAAI,cAAc;AAChB,UAAM,aAAa,aAAa,QAAQ,OAAO,EAAE,EAAE,QAAQ,OAAO,GAAG;AACrE,UAAM,WAAW,KAAK,KAAK,cAAc,UAAU;AACnD,QAAI,GAAG,WAAW,QAAQ,KAAK,CAAC,GAAG,SAAS,QAAQ,EAAE,YAAY,GAAG;AACnE,UAAI;AACF,mBAAW,GAAG,aAAa,UAAU,MAAM;AAAA,MAC7C,QAAQ;AAAA,MAAC;AAAA,IACX;AAAA,EACF;AAEA,QAAM,MAAM,mBAAmB,SAAS;AACxC,MAAI,CAAC,IAAI,QAAQ;AACf,WAAO,EAAE,IAAI,OAAO,OAAO,cAAc,eAAe,KAAK;AAAA,EAC/D;AACA,QAAM,EAAE,UAAU,QAAQ,SAAS,MAAM,IAAI;AAE7C,QAAM,UAAU;AAAA,IACd,aAAa;AAAA,IACb,QAAQ;AAAA,IACR,YAAY;AAAA,IACZ,SAAS;AAAA,IACT,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,QAAQ;AAAA,EACV;AAEA,QAAM,eAAe;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,wBAQC,EAAE,KAAK,QAAQ,EAAE,KAAK,EAAE;AAAA;AAG9C,QAAM,aAAa;AAAA;AAAA,EAEnB,eAAe,MAAM,GAAG,IAAK,CAAC;AAAA;AAAA,EAE9B,WAAW;AAAA;AAAA;AAAA,EAAuC,SAAS,MAAM,GAAG,GAAI,CAAC;AAAA,OAAU,EAAE;AAErF,MAAI;AACF,QAAI,MAAM,MAAM,sBAAsB,UAAU,QAAQ,SAAS,OAAO,cAAc,UAAU;AAChG,UAAM,IAAI,QAAQ,qBAAqB,EAAE,EAAE,QAAQ,eAAe,EAAE,EAAE,KAAK;AAC3E,QAAI,OAAO,CAAC;AACZ,QAAI;AACF,aAAO,KAAK,MAAM,GAAG;AAAA,IACvB,QAAQ;AACN,aAAO;AAAA,QACL,eAAe,IAAI,MAAM,GAAG,GAAG,KAAK;AAAA,QACpC,2BAA2B,CAAC;AAAA,QAC5B,gBAAgB,CAAC;AAAA,QACjB,kBAAkB;AAAA,QAClB,UAAU;AAAA,QACV,WAAW;AAAA,MACb;AAAA,IACF;AACA,SAAK,YAAY,KAAK,aAAa;AACnC,QAAI,gBAAgB,KAAK,kBAAkB;AACzC,wBAAkB,EAAE,UAAU,EAAE,CAAC,YAAY,GAAG,EAAE,SAAS,KAAK,kBAAkB,MAAM,GAAG,GAAG,EAAE,EAAE,EAAE,CAAC;AAAA,IACvG;AACA,UAAM,gBAAgB,yBAAyB,IAAI;AACnD,WAAO,EAAE,IAAI,MAAM,eAAe,mBAAmB,KAAK;AAAA,EAC5D,SAAS,KAAK;AACZ,WAAO,EAAE,IAAI,OAAO,OAAO,IAAI,SAAS,eAAe,KAAK;AAAA,EAC9D;AACF;AAEA,OAAO;AAAA,EACL;AAAA,EACA;AAAA,IACE,OAAO;AAAA,IACP,aAAa;AAAA,IACb,aAAa,EAAE,OAAO;AAAA,MACpB,aAAa,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,uLAAiL;AAAA,MAC7N,cAAc,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,8IAAkI;AAAA,IACjL,CAAC;AAAA,IACD,cAAc,EAAE,OAAO;AAAA,MACrB,IAAI,EAAE,QAAQ;AAAA,MACd,eAAe,EAAE,OAAO,EAAE,SAAS;AAAA,MACnC,2BAA2B,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS;AAAA,MACxD,gBAAgB,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS;AAAA,MAC7C,kBAAkB,EAAE,OAAO,EAAE,SAAS;AAAA,MACtC,UAAU,EAAE,OAAO,EAAE,SAAS;AAAA,MAC9B,WAAW,EAAE,OAAO,EAAE,SAAS;AAAA,MAC/B,eAAe,EAAE,OAAO,EAAE,SAAS;AAAA,MACnC,OAAO,EAAE,OAAO,EAAE,SAAS;AAAA,IAC7B,CAAC;AAAA,EACH;AAAA,EACA,OAAO,EAAE,aAAa,aAAa,MAAM;AACvC,UAAM,YAAY,uBAAuB;AACzC,UAAM,KAAK,UAAU,eAAe,CAAC,KAAK;AAE1C,QAAI,iBAAiB,aAAa,KAAK,KAAK;AAC5C,QAAI,CAAC,gBAAgB;AACnB,YAAM,kBAAkB,KAAK,KAAK,cAAc,0BAA0B;AAC1E,UAAI,GAAG,WAAW,eAAe,GAAG;AAClC,YAAI;AACF,2BAAiB,GAAG,aAAa,iBAAiB,MAAM;AAAA,QAC1D,QAAQ;AAAA,QAAC;AAAA,MACX;AAAA,IACF;AACA,QAAI,CAAC,gBAAgB;AACnB,aAAO;AAAA,QACL,SAAS,CAAC;AAAA,UACR,MAAM;AAAA,UACN,MAAM;AAAA,QACR,CAAC;AAAA,QACD,mBAAmB,EAAE,IAAI,OAAO,OAAO,kBAAkB;AAAA,MAC3D;AAAA,IACF;AAEA,QAAI,WAAW;AACf,QAAI,cAAc;AAChB,YAAM,aAAa,aAAa,QAAQ,OAAO,EAAE,EAAE,QAAQ,OAAO,GAAG;AACrE,YAAM,WAAW,KAAK,KAAK,cAAc,UAAU;AACnD,UAAI,GAAG,WAAW,QAAQ,KAAK,CAAC,GAAG,SAAS,QAAQ,EAAE,YAAY,GAAG;AACnE,YAAI;AACF,qBAAW,GAAG,aAAa,UAAU,MAAM;AAAA,QAC7C,QAAQ;AAAA,QAAC;AAAA,MACX;AAAA,IACF;AAEA,UAAM,MAAM,mBAAmB,SAAS;AACxC,QAAI,CAAC,IAAI,QAAQ;AACf,aAAO;AAAA,QACL,SAAS,CAAC;AAAA,UACR,MAAM;AAAA,UACN,MAAM;AAAA,QACR,CAAC;AAAA,QACD,mBAAmB,EAAE,IAAI,OAAO,OAAO,wBAAwB;AAAA,MACjE;AAAA,IACF;AACA,UAAM,EAAE,UAAU,QAAQ,SAAS,MAAM,IAAI;AAE7C,UAAM,UAAU;AAAA,MACd,aAAa;AAAA,MACb,QAAQ;AAAA,MACR,YAAY;AAAA,MACZ,SAAS;AAAA,MACT,MAAM;AAAA,MACN,QAAQ;AAAA,MACR,OAAO;AAAA,MACP,QAAQ;AAAA,IACV;AAEA,UAAM,eAAe;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,wBAQD,EAAE,KAAK,QAAQ,EAAE,KAAK,EAAE;AAAA;AAG5C,UAAM,aAAa;AAAA;AAAA,EAErB,eAAe,MAAM,GAAG,IAAK,CAAC;AAAA;AAAA,EAE9B,WAAW;AAAA;AAAA;AAAA,EAAuC,SAAS,MAAM,GAAG,GAAI,CAAC;AAAA,OAAU,EAAE;AAEnF,QAAI;AACF,UAAI,MAAM,MAAM,sBAAsB,UAAU,QAAQ,SAAS,OAAO,cAAc,UAAU;AAChG,YAAM,IAAI,QAAQ,qBAAqB,EAAE,EAAE,QAAQ,eAAe,EAAE,EAAE,KAAK;AAE3E,UAAI,OAAO,CAAC;AACZ,UAAI;AACF,eAAO,KAAK,MAAM,GAAG;AAAA,MACvB,QAAQ;AACN,eAAO;AAAA,UACL,eAAe,IAAI,MAAM,GAAG,GAAG,KAAK;AAAA,UACpC,2BAA2B,CAAC;AAAA,UAC5B,gBAAgB,CAAC;AAAA,UACjB,kBAAkB;AAAA,UAClB,UAAU;AAAA,UACV,WAAW;AAAA,QACb;AAAA,MACF;AAEA,WAAK,YAAY,KAAK,aAAa;AACnC,YAAM,gBAAgB,yBAAyB,IAAI;AAEnD,aAAO;AAAA,QACL,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,cAAc,CAAC;AAAA,QAC/C,mBAAmB;AAAA,UACjB,IAAI;AAAA,UACJ,eAAe,KAAK;AAAA,UACpB,2BAA2B,KAAK;AAAA,UAChC,gBAAgB,KAAK;AAAA,UACrB,kBAAkB,KAAK,oBAAoB;AAAA,UAC3C,UAAU,KAAK,YAAY;AAAA,UAC3B,WAAW,KAAK;AAAA,UAChB;AAAA,QACF;AAAA,MACF;AAAA,IACF,SAAS,KAAK;AACZ,aAAO;AAAA,QACL,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,qBAAqB,IAAI,OAAO,GAAG,CAAC;AAAA,QACpE,mBAAmB,EAAE,IAAI,OAAO,OAAO,IAAI,QAAQ;AAAA,MACrD;AAAA,IACF;AAAA,EACF;AACF;AAMA,OAAO;AAAA,EACL;AAAA,EACA;AAAA,IACE,OAAO;AAAA,IACP,aAAa;AAAA,IACb,aAAa,EAAE,OAAO;AAAA,MACpB,UAAU,EAAE,MAAM,EAAE,OAAO;AAAA,QACzB,MAAM,EAAE,OAAO,EAAE,SAAS;AAAA,QAC1B,SAAS,EAAE,OAAO,EAAE,SAAS;AAAA,QAC7B,OAAO,EAAE,OAAO,EAAE,SAAS;AAAA,MAC7B,CAAC,CAAC,EAAE,SAAS,gCAAgC;AAAA,IAC/C,CAAC;AAAA,IACD,cAAc,EAAE,OAAO;AAAA,MACrB,IAAI,EAAE,QAAQ;AAAA,MACd,aAAa,EAAE,MAAM,EAAE,OAAO;AAAA,QAC5B,MAAM,EAAE,OAAO,EAAE,SAAS;AAAA,QAC1B,aAAa,EAAE,OAAO;AAAA,QACtB,KAAK,EAAE,OAAO,EAAE,SAAS;AAAA,MAC3B,CAAC,CAAC;AAAA,IACJ,CAAC;AAAA,EACH;AAAA,EACA,OAAO,EAAE,SAAS,MAAM;AACtB,UAAM,cAAc,CAAC;AAErB,eAAW,KAAK,UAAU;AACxB,YAAM,MAAM,EAAE,WAAW;AAEzB,UAAI,sCAAsC,KAAK,GAAG,GAAG;AACnD,oBAAY,KAAK;AAAA,UACf,MAAM,EAAE;AAAA,UACR,aAAa;AAAA,UACb,KAAK;AAAA,QACP,CAAC;AAAA,MACH,WAAW,qBAAqB,KAAK,GAAG,GAAG;AACzC,oBAAY,KAAK;AAAA,UACf,MAAM,EAAE;AAAA,UACR,aAAa;AAAA,UACb,KAAK;AAAA,QACP,CAAC;AAAA,MACH,WAAW,8BAA8B,KAAK,GAAG,GAAG;AAClD,oBAAY,KAAK;AAAA,UACf,MAAM,EAAE;AAAA,UACR,aAAa;AAAA,UACb,KAAK;AAAA,QACP,CAAC;AAAA,MACH,OAAO;AACL,oBAAY,KAAK;AAAA,UACf,MAAM,EAAE;AAAA,UACR,aAAa;AAAA,UACb,KAAK;AAAA,QACP,CAAC;AAAA,MACH;AAAA,IACF;AAEA,WAAO;AAAA,MACL,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,KAAK,UAAU,aAAa,MAAM,CAAC,EAAE,CAAC;AAAA,MACtE,mBAAmB,EAAE,IAAI,MAAM,YAAY;AAAA,IAC7C;AAAA,EACF;AACF;AAMA,OAAO;AAAA,EACL;AAAA,EACA;AAAA,IACE,OAAO;AAAA,IACP,aAAa;AAAA,IACb,aAAa,EAAE,OAAO;AAAA,MACpB,cAAc,EAAE,OAAO,EAAE,SAAS,mEAAmE;AAAA,MACrG,aAAa,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,2EAAwE;AAAA,MACpH,WAAW,EAAE,KAAK,CAAC,WAAW,cAAc,eAAe,QAAQ,CAAC,EAAE,SAAS,EAAE,SAAS,2DAA2D;AAAA,IACvJ,CAAC;AAAA,IACD,cAAc,EAAE,OAAO;AAAA,MACrB,IAAI,EAAE,QAAQ;AAAA,MACd,kBAAkB,EAAE,OAAO,EAAE,SAAS;AAAA,MACtC,iBAAiB,EAAE,OAAO,EAAE,SAAS;AAAA,MACrC,YAAY,EAAE,OAAO,EAAE,SAAS;AAAA,MAChC,OAAO,EAAE,OAAO,EAAE,SAAS;AAAA,IAC7B,CAAC;AAAA,EACH;AAAA,EACA,OAAO,EAAE,cAAc,aAAa,UAAU,MAAM;AAClD,UAAM,YAAY,uBAAuB;AACzC,UAAM,KAAK,aAAa,uBAAuB,aAAa,MAAM,GAAG,EAAE,IAAI,GAAG,SAAS;AAEvF,QAAI,iBAAiB;AACrB,QAAI,CAAC,gBAAgB;AACnB,YAAM,UAAU,KAAK,KAAK,cAAc,0BAA0B;AAClE,UAAI,GAAG,WAAW,OAAO,GAAG;AAC1B,yBAAiB,GAAG,aAAa,SAAS,MAAM;AAAA,MAClD;AAAA,IACF;AACA,QAAI,CAAC,gBAAgB;AACnB,aAAO;AAAA,QACL,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,4EAAyE,CAAC;AAAA,QAC1G,mBAAmB,EAAE,IAAI,OAAO,OAAO,kBAAkB;AAAA,MAC3D;AAAA,IACF;AAEA,QAAI,CAAC,oEAAoE,KAAK,cAAc,GAAG;AAC7F,aAAO;AAAA,QACL,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,+GAA4G,CAAC;AAAA,QAC7I,mBAAmB,EAAE,IAAI,OAAO,OAAO,iCAAiC;AAAA,MAC1E;AAAA,IACF;AAEA,QAAI,WAAW;AACf,UAAM,WAAW,KAAK,KAAK,cAAc,aAAa,QAAQ,OAAO,EAAE,EAAE,QAAQ,OAAO,GAAG,CAAC;AAC5F,QAAI,GAAG,WAAW,QAAQ,GAAG;AAC3B,UAAI;AACF,mBAAW,GAAG,aAAa,UAAU,MAAM;AAAA,MAC7C,QAAQ;AAAA,MAAC;AAAA,IACX;AAEA,UAAM,MAAM,mBAAmB,SAAS;AACxC,QAAI,CAAC,IAAI,QAAQ;AACf,aAAO;AAAA,QACL,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,mEAAmE,CAAC;AAAA,QACpG,mBAAmB,EAAE,IAAI,OAAO,OAAO,wBAAwB;AAAA,MACjE;AAAA,IACF;AACA,UAAM,EAAE,UAAU,QAAQ,SAAS,MAAM,IAAI;AAE7C,UAAM,UAAU;AAAA,MACd,SAAS;AAAA,MACT,YAAY;AAAA,MACZ,aAAa;AAAA,MACb,QAAQ;AAAA,IACV;AAEA,UAAM,eAAe;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,aAQZ,EAAE,KAAK,QAAQ,EAAE,KAAK,EAAE;AAEjC,UAAM,aAAa;AAAA;AAAA,EAErB,eAAe,MAAM,GAAG,GAAI,CAAC;AAAA;AAAA;AAAA;AAAA,EAI7B,WAAW,SAAS,MAAM,GAAG,GAAI,IAAI,sBAAgB;AAAA;AAGnD,QAAI;AACF,UAAI,MAAM,MAAM,sBAAsB,UAAU,QAAQ,SAAS,OAAO,cAAc,UAAU;AAChG,YAAM,IAAI,QAAQ,qBAAqB,EAAE,EAAE,QAAQ,eAAe,EAAE,EAAE,KAAK;AAC3E,UAAI,OAAO,CAAC;AACZ,UAAI;AACF,eAAO,KAAK,MAAM,GAAG;AAAA,MACvB,QAAQ;AACN,eAAO;AAAA,UACL,kBAAkB;AAAA,UAClB,iBAAiB,IAAI,MAAM,GAAG,GAAI;AAAA,UAClC,YAAY;AAAA,QACd;AAAA,MACF;AAEA,YAAM,OAAO;AAAA,QACX,KAAK,cAAc;AAAA,EAAkB,KAAK,UAAU;AAAA,QACpD,KAAK,oBAAoB;AAAA,IAA0B,KAAK,gBAAgB;AAAA,QACxE,KAAK,mBAAmB;AAAA,QAA8B,EAAE;AAAA,EAAK,KAAK,eAAe;AAAA;AAAA,MACnF,EACG,OAAO,OAAO,EACd,KAAK,MAAM;AAEd,aAAO;AAAA,QACL,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,QAAQ,KAAK,UAAU,MAAM,MAAM,CAAC,EAAE,CAAC;AAAA,QACvE,mBAAmB;AAAA,UACjB,IAAI;AAAA,UACJ,kBAAkB,KAAK;AAAA,UACvB,iBAAiB,KAAK;AAAA,UACtB,YAAY,KAAK;AAAA,QACnB;AAAA,MACF;AAAA,IACF,SAAS,KAAK;AACZ,aAAO;AAAA,QACL,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,uBAAuB,IAAI,OAAO,GAAG,CAAC;AAAA,QACtE,mBAAmB,EAAE,IAAI,OAAO,OAAO,IAAI,QAAQ;AAAA,MACrD;AAAA,IACF;AAAA,EACF;AACF;AAEA,OAAO;AAAA,EACL;AAAA,EACA;AAAA,IACE,OAAO;AAAA,IACP,aAAa;AAAA,IACb,aAAa,EAAE,OAAO;AAAA,MACpB,MAAM,EAAE,OAAO,EAAE,SAAS,wFAAwF;AAAA,IACpH,CAAC;AAAA,IACD,cAAc,EAAE,OAAO;AAAA,MACrB,IAAI,EAAE,QAAQ;AAAA,MACd,UAAU,EAAE,OAAO,EAAE,SAAS;AAAA,MAC9B,SAAS,EAAE,MAAM,EAAE,OAAO;AAAA,QACxB,MAAM,EAAE,OAAO;AAAA,QACf,SAAS,EAAE,QAAQ,EAAE,SAAS;AAAA,QAC9B,aAAa,EAAE,OAAO,EAAE,SAAS;AAAA,QACjC,eAAe,EAAE,QAAQ,EAAE,SAAS;AAAA,QACpC,oBAAoB,EAAE,OAAO,EAAE,SAAS;AAAA,QACxC,UAAU,EAAE,QAAQ,EAAE,SAAS;AAAA,QAC/B,eAAe,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS;AAAA,QAC5C,oBAAoB,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS;AAAA,QACjD,iBAAiB,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS;AAAA,QAC9C,UAAU,EAAE,OAAO,EAAE,SAAS;AAAA,MAChC,CAAC,CAAC,EAAE,SAAS;AAAA,MACb,uBAAuB,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS;AAAA,MACpD,QAAQ,EAAE,OAAO,EAAE,SAAS;AAAA,MAC5B,OAAO,EAAE,OAAO,EAAE,SAAS;AAAA,IAC7B,CAAC;AAAA,EACH;AAAA,EACA,OAAO,EAAE,MAAM,SAAS,MAAM;AAC5B,UAAM,aAAa,SAAS,QAAQ,OAAO,EAAE,EAAE,QAAQ,OAAO,GAAG;AACjE,UAAM,WAAW,KAAK,KAAK,cAAc,UAAU;AAEnD,QAAI,CAAC,SAAS,WAAW,YAAY,GAAG;AACtC,aAAO;AAAA,QACL,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,2BAA2B,CAAC;AAAA,QAC5D,mBAAmB,EAAE,IAAI,OAAO,OAAO,uBAAuB;AAAA,MAChE;AAAA,IACF;AACA,QAAI,CAAC,GAAG,WAAW,QAAQ,GAAG;AAC5B,aAAO;AAAA,QACL,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,8BAA2B,UAAU,GAAG,CAAC;AAAA,QACzE,mBAAmB,EAAE,IAAI,OAAO,OAAO,iBAAiB;AAAA,MAC1D;AAAA,IACF;AACA,UAAM,OAAO,GAAG,SAAS,QAAQ;AACjC,QAAI,KAAK,YAAY,GAAG;AACtB,aAAO;AAAA,QACL,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,4CAAsC,CAAC;AAAA,QACvE,mBAAmB,EAAE,IAAI,OAAO,OAAO,eAAe;AAAA,MACxD;AAAA,IACF;AAEA,QAAI,cAAc;AAClB,QAAI;AACF,oBAAc,GAAG,aAAa,UAAU,MAAM;AAAA,IAChD,SAAS,KAAK;AACZ,aAAO;AAAA,QACL,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,gBAAgB,IAAI,OAAO,GAAG,CAAC;AAAA,QAC/D,mBAAmB,EAAE,IAAI,OAAO,OAAO,IAAI,QAAQ;AAAA,MACrD;AAAA,IACF;AAEA,UAAM,MAAM,mBAAmB,SAAS;AACxC,QAAI,CAAC,IAAI,QAAQ;AACf,aAAO;AAAA,QACL,SAAS,CAAC;AAAA,UACR,MAAM;AAAA,UACN,MAAM;AAAA,QACR,CAAC;AAAA,QACD,mBAAmB,EAAE,IAAI,OAAO,OAAO,wBAAwB;AAAA,MACjE;AAAA,IACF;AACA,UAAM,EAAE,UAAU,QAAQ,SAAS,MAAM,IAAI;AAE7C,UAAM,MAAM,KAAK,QAAQ,QAAQ,EAAE,YAAY;AAC/C,UAAM,OAAO,CAAC,OAAO,MAAM,EAAE,SAAS,GAAG,IAAI,eAAe,CAAC,OAAO,MAAM,EAAE,SAAS,GAAG,IAAI,eAAe,CAAC,KAAK,EAAE,SAAS,GAAG,IAAI,WAAW;AAE9I,UAAM,eAAe;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mDA+BuB,IAAI;AAEhD,UAAM,aAAa,YAAY,UAAU;AAAA;AAAA,QAErC,IAAI;AAAA,EACV,YAAY,MAAM,GAAG,IAAK,CAAC;AAAA;AAAA;AAAA;AAKzB,QAAI;AACF,UAAI,MAAM,MAAM,sBAAsB,UAAU,QAAQ,SAAS,OAAO,cAAc,UAAU;AAChG,YAAM,IAAI,QAAQ,qBAAqB,EAAE,EAAE,QAAQ,eAAe,EAAE,EAAE,KAAK;AAE3E,UAAI,OAAO,CAAC;AACZ,UAAI;AACF,eAAO,KAAK,MAAM,GAAG;AAAA,MACvB,QAAQ;AACN,eAAO;AAAA,UACL,SAAS,CAAC;AAAA,UACV,uBAAuB,CAAC;AAAA,UACxB,QAAQ,IAAI,MAAM,GAAG,GAAI,KAAK;AAAA,QAChC;AAAA,MACF;AAEA,YAAM,QAAQ;AAAA,QACZ,+BAAyB,UAAU;AAAA,QACnC;AAAA,QACA,KAAK,UAAU;AAAA,EAAc,KAAK,MAAM;AAAA,QACxC,KAAK,uBAAuB,SAAS,IACjC;AAAA;AAAA,EAAmC,KAAK,sBAAsB,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,EAAE,KAAK,IAAI,CAAC,KAC7F;AAAA,QACJ;AAAA,MACF;AAEA,iBAAW,KAAK,KAAK,WAAW,CAAC,GAAG;AAClC,cAAM,KAAK,OAAO,EAAE,IAAI,EAAE;AAC1B,cAAM,KAAK,EAAE;AACb,YAAI,EAAE,YAAY,OAAW,OAAM,KAAK,kBAAkB,EAAE,UAAU,eAAU,eAAO,EAAE;AACzF,YAAI,EAAE,YAAa,OAAM,KAAK,uBAAuB,EAAE,WAAW,EAAE;AACpE,YAAI,EAAE,cAAe,OAAM,KAAK,4CAAkC,EAAE,sBAAsB,WAAW,EAAE;AACvG,YAAI,EAAE,aAAa,OAAW,OAAM,KAAK,mBAAmB,EAAE,WAAW,eAAU,eAAO,EAAE;AAC5F,YAAI,EAAE,eAAe,OAAQ,OAAM,KAAK,yBAAyB,EAAE,cAAc,KAAK,IAAI,CAAC,EAAE;AAC7F,YAAI,EAAE,oBAAoB,OAAQ,OAAM,KAAK,iCAA8B,EAAE,mBAAmB,KAAK,IAAI,CAAC,EAAE;AAC5G,YAAI,EAAE,iBAAiB,OAAQ,OAAM,KAAK,2BAA2B,EAAE,gBAAgB,KAAK,IAAI,CAAC,EAAE;AACnG,YAAI,EAAE,SAAU,OAAM,KAAK;AAAA;AAAA;AAAA,EAA4B,EAAE,QAAQ;AAAA,OAAU;AAC3E,cAAM,KAAK,EAAE;AAAA,MACf;AAEA,YAAM,gBAAgB,MAAM,OAAO,OAAO,EAAE,KAAK,IAAI;AAErD,aAAO;AAAA,QACL,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,cAAc,CAAC;AAAA,QAC/C,mBAAmB;AAAA,UACjB,IAAI;AAAA,UACJ,UAAU;AAAA,UACV,SAAS,KAAK,WAAW,CAAC;AAAA,UAC1B,uBAAuB,KAAK,yBAAyB,CAAC;AAAA,UACtD,QAAQ,KAAK;AAAA,QACf;AAAA,MACF;AAAA,IACF,SAAS,KAAK;AACZ,aAAO;AAAA,QACL,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,qBAAqB,IAAI,OAAO,GAAG,CAAC;AAAA,QACpE,mBAAmB,EAAE,IAAI,OAAO,OAAO,IAAI,QAAQ;AAAA,MACrD;AAAA,IACF;AAAA,EACF;AACF;AAGA,OAAO;AAAA,EACL;AAAA,EACA;AAAA,IACE,OAAO;AAAA,IACP,aAAa;AAAA,IACb,aAAa,EAAE,OAAO;AAAA,MACpB,UAAU,EAAE,MAAM,EAAE,OAAO;AAAA,QACzB,MAAM,EAAE,OAAO,EAAE,SAAS;AAAA,QAC1B,SAAS,EAAE,OAAO,EAAE,SAAS;AAAA,QAC7B,OAAO,EAAE,OAAO,EAAE,SAAS;AAAA,MAC7B,CAAC,CAAC,EAAE,SAAS,+BAA+B;AAAA,MAC5C,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,mBAAgB;AAAA,IACxD,CAAC;AAAA,IACD,cAAc,EAAE,OAAO;AAAA,MACrB,IAAI,EAAE,QAAQ;AAAA,MACd,QAAQ,EAAE,OAAO;AAAA,MACjB,OAAO,EAAE,OAAO;AAAA,IAClB,CAAC;AAAA,EACH;AAAA,EACA,OAAO,EAAE,UAAU,MAAM,MAAM;AAC7B,UAAM,WAAW,SAAS,YAAY,SAAS,MAAM;AACrD,UAAM,QAAQ;AAAA,MACZ,KAAK,QAAQ;AAAA,MACb;AAAA,MACA;AAAA,MACA;AAAA,MACA,GAAG,SAAS,MAAM;AAAA,MAClB;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAEA,aAAS,QAAQ,CAAC,GAAG,MAAM;AACzB,YAAM,KAAK,OAAO,IAAI,CAAC,KAAK,EAAE,QAAQ,oBAAoB,EAAE;AAC5D,YAAM,KAAK,EAAE;AACb,YAAM,KAAK,iBAAiB,EAAE,WAAW,KAAK,EAAE;AAChD,YAAM,KAAK,EAAE;AACb,UAAI,EAAE,OAAO;AACX,cAAM,KAAK,kBAAkB;AAC7B,cAAM,KAAK,KAAK;AAChB,cAAM,KAAK,EAAE,KAAK;AAClB,cAAM,KAAK,KAAK;AAChB,cAAM,KAAK,EAAE;AAAA,MACf;AAAA,IACF,CAAC;AAED,UAAM,KAAK,uBAAoB;AAC/B,UAAM,KAAK,EAAE;AACb,UAAM,KAAK,6BAA6B;AACxC,UAAM,KAAK,8BAA8B;AACzC,UAAM,KAAK,8BAAwB;AACnC,UAAM,KAAK,0BAA0B;AAErC,UAAM,SAAS,MAAM,KAAK,IAAI;AAE9B,uBAAmB,EAAE,MAAM,gBAAgB,eAAe,SAAS,QAAQ,OAAO,SAAS,CAAC;AAE5F,WAAO;AAAA,MACL,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,OAAO,CAAC;AAAA,MACxC,mBAAmB,EAAE,IAAI,MAAM,QAAQ,OAAO,SAAS;AAAA,IACzD;AAAA,EACF;AACF;AAMA,OAAO;AAAA,EACL;AAAA,EACA;AAAA,IACE,OAAO;AAAA,IACP,aAAa;AAAA,IACb,aAAa,EAAE,OAAO;AAAA,MACpB,QAAQ,EAAE,KAAK,CAAC,MAAM,OAAO,KAAK,CAAC,EAAE,SAAS,EAAE,SAAS,yCAAsC;AAAA,IACjG,CAAC;AAAA,IACD,cAAc,EAAE,OAAO;AAAA,MACrB,IAAI,EAAE,QAAQ;AAAA,MACd,WAAW,EAAE,OAAO;AAAA,QAClB,UAAU,EAAE,OAAO;AAAA,QACnB,eAAe,EAAE,OAAO,EAAE,SAAS;AAAA,QACnC,kBAAkB,EAAE,OAAO;AAAA,MAC7B,CAAC,EAAE,SAAS;AAAA,MACZ,eAAe,EAAE,OAAO;AAAA,QACtB,qBAAqB,EAAE,OAAO;AAAA,QAC9B,eAAe,EAAE,OAAO;AAAA,QACxB,qBAAqB,EAAE,OAAO;AAAA,MAChC,CAAC,EAAE,SAAS;AAAA,MACZ,cAAc,EAAE,OAAO;AAAA,QACrB,YAAY,EAAE,OAAO;AAAA,QACrB,cAAc,EAAE,OAAO;AAAA,QACvB,SAAS,EAAE,OAAO;AAAA,QAClB,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,GAAG,SAAS,EAAE,QAAQ,EAAE,CAAC,CAAC;AAAA,MACvE,CAAC,EAAE,SAAS;AAAA,MACZ,SAAS,EAAE,OAAO;AAAA,IACpB,CAAC;AAAA,EACH;AAAA,EACA,OAAO,EAAE,SAAS,MAAM,IAAI,CAAC,MAAM;AACjC,UAAM,MAAM,KAAK,IAAI;AACrB,UAAM,aAAa,EAAE,MAAM,IAAI,KAAK,KAAK,KAAK,KAAM,OAAO,KAAK,KAAK,KAAK,KAAK,KAAM,KAAK,SAAS;AACnG,UAAM,SAAS,MAAM,WAAW,MAAM;AAEtC,QAAI,OAAO,EAAE,QAAQ,CAAC,EAAE;AACxB,QAAI,GAAG,WAAW,YAAY,GAAG;AAC/B,UAAI;AACF,eAAO,KAAK,MAAM,GAAG,aAAa,cAAc,MAAM,CAAC;AAAA,MACzD,QAAQ;AAAA,MAAC;AAAA,IACX;AAEA,UAAM,UAAU,KAAK,UAAU,CAAC,GAAG,OAAO,CAAC,MAAM,IAAI,KAAK,EAAE,SAAS,EAAE,QAAQ,KAAK,MAAM;AAE1F,UAAM,WAAW,OAAO,OAAO,CAAC,MAAM,EAAE,SAAS,UAAU;AAC3D,UAAM,aAAa,SAAS,OAAO,CAAC,OAAO,EAAE,UAAU,KAAK,CAAC;AAC7D,UAAM,cAAc,SAAS,OAAO,CAAC,KAAK,MAAM,OAAO,EAAE,UAAU,IAAI,CAAC;AACxE,UAAM,gBAAgB,SAAS,OAAO,CAAC,KAAK,MAAM,OAAO,EAAE,mBAAmB,IAAI,CAAC;AAEnF,QAAI,YAAY;AAChB,QAAI,WAAW,SAAS,GAAG;AACzB,YAAM,cAAc,WAAW,WAAW,SAAS,CAAC;AACpD,kBAAY;AAAA,QACV,UAAU;AAAA,QACV,eAAe,YAAY;AAAA,QAC3B,kBAAkB,WAAW;AAAA,MAC/B;AACA,UAAI,WAAW,UAAU,GAAG;AAC1B,cAAM,SAAS,CAAC;AAChB,iBAAS,IAAI,GAAG,IAAI,WAAW,QAAQ,KAAK;AAC1C,gBAAM,OAAO,IAAI,KAAK,WAAW,IAAI,CAAC,EAAE,SAAS,EAAE,QAAQ;AAC3D,gBAAM,OAAO,IAAI,KAAK,WAAW,CAAC,EAAE,SAAS,EAAE,QAAQ;AACvD,iBAAO,MAAM,OAAO,SAAS,MAAO,KAAK,GAAG;AAAA,QAC9C;AACA,kBAAU,WAAW,OAAO,OAAO,CAAC,GAAG,MAAM,IAAI,GAAG,CAAC,IAAI,OAAO;AAAA,MAClE;AAAA,IACF;AAEA,QAAI,gBAAgB;AACpB,QAAI,cAAc,GAAG;AACnB,YAAM,wBAAwB,gBAAgB,cAAc;AAC5D,sBAAgB;AAAA,QACd,qBAAqB,KAAK,MAAM,wBAAwB,WAAW;AAAA,QACnE,eAAe;AAAA,QACf,qBAAqB,KAAK,MAAO,wBAAwB,KAAM,EAAE,IAAI;AAAA,MACvE;AAAA,IACF;AAEA,QAAI,eAAe;AACnB,QAAI,GAAG,WAAW,iBAAiB,GAAG;AACpC,UAAI;AACF,cAAM,cAAc,KAAK,MAAM,GAAG,aAAa,mBAAmB,MAAM,CAAC;AACzE,cAAM,QAAQ,YAAY,SAAS,CAAC;AACpC,cAAM,YAAY,uBAAuB;AACzC,cAAM,eAAe,IAAI,IAAI,iBAAiB,SAAS,EAAE,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC;AAE3E,cAAM,UAAU,MAAM,IAAI,CAAC,MAAM;AAC/B,gBAAM,YAAY,EAAE,aAAa,CAAC;AAClC,gBAAM,UAAU,UAAU,KAAK,CAAC,OAAO,aAAa,IAAI,EAAE,KAAK,aAAa,IAAI,GAAG,QAAQ,OAAO,GAAG,CAAC,CAAC;AACvG,iBAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,QAAQ;AAAA,QAChD,CAAC;AAED,uBAAe;AAAA,UACb,YAAY,MAAM;AAAA,UAClB,cAAc,QAAQ,OAAO,CAAC,MAAM,EAAE,OAAO,EAAE;AAAA,UAC/C,SAAS,MAAM,SAAS,KAAK,MAAO,QAAQ,OAAO,CAAC,MAAM,EAAE,OAAO,EAAE,SAAS,MAAM,SAAU,GAAG,IAAI;AAAA,UACrG;AAAA,QACF;AAAA,MACF,QAAQ;AAAA,MAAC;AAAA,IACX;AAEA,UAAM,QAAQ;AAAA,MACZ;AAAA,MACA;AAAA,MACA,eAAY,MAAM;AAAA,MAClB;AAAA,MACA,YACI;AAAA,QACE;AAAA,QACA,sBAAmB,UAAU,iBAAiB,KAAK;AAAA,QACnD,gCAA0B,UAAU,gBAAgB;AAAA,QACpD,UAAU,WAAW,IAAI,4BAAyB,UAAU,SAAS,QAAQ,CAAC,CAAC,MAAM;AAAA,MACvF,EACG,OAAO,OAAO,EACd,KAAK,IAAI,IACZ;AAAA,MACJ,gBACI;AAAA,QACE;AAAA,QACA,sBAAsB,cAAc,aAAa;AAAA,QACjD,kCAA+B,cAAc,mBAAmB;AAAA,QAChE,6BAA6B,cAAc,mBAAmB;AAAA,MAChE,EAAE,KAAK,IAAI,IACX;AAAA,MACJ,eACI;AAAA,QACE;AAAA,QACA,sBAAsB,aAAa,YAAY,IAAI,aAAa,UAAU,KAAK,aAAa,OAAO;AAAA,QACnG,aAAa,QAAQ,IAAI,CAAC,MAAM,OAAO,EAAE,IAAI,KAAK,EAAE,UAAU,WAAM,QAAG,EAAE,EAAE,KAAK,IAAI;AAAA,MACtF,EAAE,KAAK,IAAI,IACX;AAAA,IACN,EACG,OAAO,OAAO,EACd,KAAK,MAAM;AAEd,QAAI,CAAC,aAAa,CAAC,iBAAiB,CAAC,cAAc;AACjD,YAAM,MACJ;AACF,aAAO;AAAA,QACL,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,IAAI,CAAC;AAAA,QACrC,mBAAmB,EAAE,IAAI,OAAO,SAAS,IAAI;AAAA,MAC/C;AAAA,IACF;AAEA,UAAM,UAAU;AAAA,MACd,aAAa,GAAG,UAAU,gBAAgB;AAAA,MAC1C,iBAAiB,GAAG,cAAc,aAAa,aAAa,cAAc,mBAAmB;AAAA,MAC7F,gBAAgB,GAAG,aAAa,YAAY,IAAI,aAAa,UAAU;AAAA,IACzE,EACG,OAAO,OAAO,EACd,KAAK,KAAK;AAEb,WAAO;AAAA,MACL,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,SAAS,QAAQ,CAAC;AAAA,MAClD,mBAAmB;AAAA,QACjB,IAAI;AAAA,QACJ;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;AAEA,OAAO;AAAA,EACL;AAAA,EACA;AAAA,IACE,OAAO;AAAA,IACP,aAAa;AAAA,IACb,aAAa,EAAE,OAAO;AAAA,MACpB,WAAW,EAAE,KAAK;AAAA,QAChB;AAAA,QAAW;AAAA,QAAc;AAAA,QAAQ;AAAA,QAAe;AAAA,QAAU;AAAA,QAAS;AAAA,QAAU;AAAA,QAAU;AAAA,QAAS;AAAA,MAClG,CAAC,EAAE,SAAS,EAAE,SAAS,sCAAsC;AAAA,MAC7D,SAAS,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,4CAA4C;AAAA,IACtF,CAAC;AAAA,IACD,cAAc,EAAE,OAAO;AAAA,MACrB,IAAI,EAAE,QAAQ;AAAA,MACd,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC;AAAA,MACzB,OAAO,EAAE,OAAO;AAAA,IAClB,CAAC;AAAA,EACH;AAAA,EACA,OAAO,EAAE,YAAY,OAAO,QAAQ,IAAI,CAAC,MAAM;AAC7C,UAAM,YAAY,uBAAuB;AACzC,UAAM,YAAY,iBAAiB,WAAW,EAAE,WAAW,QAAQ,CAAC;AACpE,UAAM,WAAW,UAAU,IAAI,CAAC,MAAM,EAAE,IAAI;AAE5C,UAAM,UAAU,eAAe,SAAS,MAAM;AAE9C,WAAO;AAAA,MACL,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,GAAG,OAAO;AAAA;AAAA,EAAO,SAAS,MAAM,GAAG,EAAE,EAAE,KAAK,IAAI,CAAC,GAAG,CAAC;AAAA,MACrF,mBAAmB,EAAE,IAAI,MAAM,OAAO,UAAU,OAAO,SAAS,OAAO;AAAA,IACzE;AAAA,EACF;AACF;AAEA,OAAO;AAAA,EACL;AAAA,EACA;AAAA,IACE,OAAO;AAAA,IACP,aAAa;AAAA,IACb,aAAa,EAAE,OAAO;AAAA,MACpB,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,mCAAmC;AAAA,MACxE,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,4DAAyD;AAAA,IAChG,CAAC;AAAA,IACD,cAAc,EAAE,OAAO;AAAA,MACrB,QAAQ,EAAE,KAAK,CAAC,UAAU,UAAU,WAAW,CAAC;AAAA,MAChD,SAAS,EAAE,OAAO;AAAA,MAClB,UAAU,EAAE,OAAO;AAAA,MACnB,QAAQ,EAAE,OAAO,EAAE,SAAS;AAAA,IAC9B,CAAC;AAAA,EACH;AAAA,EACA,OAAO,EAAE,KAAK,MAAM,WAAW,MAAM;AACnC,UAAM,YAAY,uBAAuB;AACzC,UAAM,UAAU,UAAU,aAAa,WAAW,CAAC;AAEnD,QAAI,KAAK;AACT,QAAI,QAAQ,MAAM;AAChB,YAAM;AACN,aAAO,CAAC,OAAO,MAAM;AAAA,IACvB,WAAW,UAAU,aAAa,iBAAiB,UAAU,UAAU,aAAa,cAAc,QAAQ;AACxG,YAAM;AACN,aAAO,CAAC,UAAU,cAAc,GAAG;AACnC,UAAI,IAAK,MAAK,KAAK,OAAO;AAAA,IAC5B,OAAO;AACL,aAAO;AAAA,QACL,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,sCAAmC,CAAC;AAAA,QACpE,mBAAmB,EAAE,QAAQ,aAAa,SAAS,mBAAmB,UAAU,EAAE;AAAA,MACpF;AAAA,IACF;AAEA,WAAO,IAAI,QAAQ,CAAC,YAAY;AAC9B,YAAM,QAAQ,MAAM,KAAK,MAAM;AAAA,QAC7B,KAAK;AAAA,QACL,OAAO,CAAC,WAAW,QAAQ,MAAM;AAAA,QACjC,OAAO,QAAQ,aAAa;AAAA,QAC5B,KAAK,EAAE,GAAG,QAAQ,IAAI;AAAA,MACxB,CAAC;AAED,UAAI,SAAS;AACb,UAAI,SAAS;AACb,UAAI,MAAM,OAAQ,OAAM,OAAO,GAAG,QAAQ,CAAC,MAAM;AAAE,kBAAU,EAAE,SAAS;AAAA,MAAG,CAAC;AAC5E,UAAI,MAAM,OAAQ,OAAM,OAAO,GAAG,QAAQ,CAAC,MAAM;AAAE,kBAAU,EAAE,SAAS;AAAA,MAAG,CAAC;AAE5E,YAAM,GAAG,SAAS,CAAC,SAAS;AAC1B,cAAM,SAAS,CAAC,QAAQ,MAAM,EAAE,OAAO,OAAO,EAAE,KAAK,IAAI,EAAE,KAAK;AAChE,cAAM,SAAS,SAAS;AACxB,gBAAQ;AAAA,UACN,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,SAAS,mBAAmB,8BAA8B,CAAC;AAAA,UAC3F,mBAAmB;AAAA,YACjB,QAAQ,SAAS,WAAW;AAAA,YAC5B,SAAS,SAAS,gBAAgB;AAAA,YAClC,UAAU,QAAQ;AAAA,YAClB,QAAQ,CAAC,SAAS,SAAS;AAAA,UAC7B;AAAA,QACF,CAAC;AAAA,MACH,CAAC;AAAA,IACH,CAAC;AAAA,EACH;AACF;AAEA,OAAO;AAAA,EACL;AAAA,EACA;AAAA,IACE,OAAO;AAAA,IACP,aAAa;AAAA,IACb,aAAa,EAAE,OAAO;AAAA,MACpB,gBAAgB,EAAE,KAAK,CAAC,OAAO,QAAQ,QAAQ,MAAM,CAAC,EAAE,SAAS,EAAE,SAAS,iCAAiC;AAAA,IAC/G,CAAC;AAAA,IACD,cAAc,EAAE,OAAO;AAAA,MACrB,QAAQ,EAAE,KAAK,CAAC,WAAW,QAAQ,CAAC;AAAA,MACpC,SAAS,EAAE,OAAO;AAAA,MAClB,UAAU,EAAE,OAAO;AAAA,IACrB,CAAC;AAAA,EACH;AAAA,EACA,OAAO,EAAE,iBAAiB,OAAO,MAAM;AACrC,QAAI,KAAK;AAET,QAAI,OAAO,QAAQ;AACjB,UAAI,GAAG,WAAW,KAAK,KAAK,cAAc,WAAW,CAAC,EAAG,MAAK;AAAA,eACrD,GAAG,WAAW,KAAK,KAAK,cAAc,gBAAgB,CAAC,EAAG,MAAK;AAAA,UACnE,MAAK;AAAA,IACZ;AAEA,WAAO,IAAI,QAAQ,CAAC,YAAY;AAC9B,YAAM,QAAQ,MAAM,IAAI,CAAC,SAAS,GAAG;AAAA,QACnC,KAAK;AAAA,QACL,OAAO;AAAA,QACP,OAAO,QAAQ,aAAa;AAAA,QAC5B,KAAK,EAAE,GAAG,QAAQ,IAAI;AAAA,MACxB,CAAC;AAED,YAAM,GAAG,SAAS,CAAC,SAAS;AAC1B,cAAM,SAAS,SAAS;AACxB,gBAAQ;AAAA,UACN,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,SAAS,gCAA6B,oCAAiC,CAAC;AAAA,UACxG,mBAAmB;AAAA,YACjB,QAAQ,SAAS,YAAY;AAAA,YAC7B,SAAS,SAAS,2BAA2B;AAAA,YAC7C,UAAU,QAAQ;AAAA,UACpB;AAAA,QACF,CAAC;AAAA,MACH,CAAC;AAAA,IACH,CAAC;AAAA,EACH;AACF;AAEA,OAAO;AAAA,EACL;AAAA,EACA;AAAA,IACE,OAAO;AAAA,IACP,aAAa;AAAA,IACb,aAAa,EAAE,OAAO,CAAC,CAAC;AAAA,IACxB,cAAc,EAAE,OAAO;AAAA,MACrB,gBAAgB,EAAE,OAAO;AAAA,MACzB,iBAAiB,EAAE,OAAO;AAAA,MAC1B,eAAe,EAAE,OAAO;AAAA,MACxB,aAAa,EAAE,OAAO;AAAA,MACtB,gBAAgB,EAAE,OAAO;AAAA,MACzB,yBAAyB,EAAE,OAAO;AAAA,IACpC,CAAC;AAAA,EACH;AAAA,EACA,YAAY;AACV,UAAM,QAAQ,eAAe;AAC7B,UAAM,UAAU;AAAA;AAAA,2BAEO,MAAM,cAAc;AAAA,mCAClB,MAAM,eAAe;AAAA,kCACtB,MAAM,aAAa;AAAA,+BACtB,MAAM,WAAW;AAAA,oBACtB,MAAM,cAAc;AAAA,wCACH,MAAM,uBAAuB;AAAA;AAAA,EAEhE,MAAM,mBAAmB,IAAI,sGAAsF,EAAE;AAEnH,WAAO;AAAA,MACL,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,QAAQ,CAAC;AAAA,MACzC,mBAAmB;AAAA,IACrB;AAAA,EACF;AACF;AAEA,OAAO;AAAA,EACL;AAAA,EACA;AAAA,IACE,OAAO;AAAA,IACP,aAAa;AAAA,IACb,aAAa,EAAE,OAAO;AAAA,MACpB,WAAW,EAAE,KAAK,CAAC,QAAQ,cAAc,SAAS,CAAC,EAAE,SAAS,EAAE,SAAS,gDAAgD;AAAA,IAC3H,CAAC;AAAA,IACD,cAAc,EAAE,OAAO;AAAA,MACrB,QAAQ,EAAE,KAAK,CAAC,WAAW,UAAU,eAAe,CAAC;AAAA,MACrD,SAAS,EAAE,OAAO;AAAA,MAClB,iBAAiB,EAAE,OAAO,EAAE,SAAS;AAAA,MACrC,QAAQ,EAAE,OAAO,EAAE,SAAS;AAAA,IAC9B,CAAC;AAAA,EACH;AAAA,EACA,OAAO,EAAE,UAAU,MAAM;AACvB,UAAM,YAAY,uBAAuB;AACzC,UAAM,KAAK,aAAa,UAAU,eAAe,CAAC;AAElD,QAAI,OAAO,QAAQ;AACjB,aAAO,IAAI,QAAQ,CAAC,YAAY;AAC9B,cAAM,QAAQ,MAAM,OAAO,CAAC,QAAQ,YAAY,GAAG;AAAA,UACjD,KAAK;AAAA,UACL,OAAO,CAAC,WAAW,QAAQ,MAAM;AAAA,UACjC,OAAO,QAAQ,aAAa;AAAA,UAC5B,KAAK,EAAE,GAAG,QAAQ,IAAI;AAAA,QACxB,CAAC;AAED,YAAI,SAAS;AACb,YAAI,MAAM,OAAQ,OAAM,OAAO,GAAG,QAAQ,CAAC,MAAM;AAAE,oBAAU,EAAE,SAAS;AAAA,QAAG,CAAC;AAE5E,cAAM,GAAG,SAAS,CAAC,SAAS;AAC1B,gBAAM,gBAAgB,OAAO,MAAM,yBAAyB;AAC5D,gBAAM,kBAAkB,gBAAgB,WAAW,cAAc,CAAC,CAAC,IAAI;AAEvE,kBAAQ;AAAA,YACN,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,aAAa,mBAAmB,KAAK,IAAI,CAAC;AAAA,YAC1E,mBAAmB;AAAA,cACjB,QAAQ,SAAS,IAAI,YAAY;AAAA,cACjC,SAAS,SAAS,IAAI,uBAAuB;AAAA,cAC7C;AAAA,cACA,QAAQ;AAAA,YACV;AAAA,UACF,CAAC;AAAA,QACH,CAAC;AAAA,MACH,CAAC;AAAA,IACH;AAEA,WAAO;AAAA,MACL,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,kCAA+B,EAAE,UAAU,CAAC;AAAA,MAC5E,mBAAmB,EAAE,QAAQ,iBAAiB,SAAS,4CAA4C;AAAA,IACrG;AAAA,EACF;AACF;AAEA,OAAO;AAAA,EACL;AAAA,EACA;AAAA,IACE,OAAO;AAAA,IACP,aAAa;AAAA,IACb,aAAa,EAAE,OAAO;AAAA,MACpB,WAAW,EAAE,KAAK,CAAC,QAAQ,QAAQ,CAAC,EAAE,SAAS,EAAE,SAAS,gCAAgC;AAAA,IAC5F,CAAC;AAAA,IACD,cAAc,EAAE,OAAO;AAAA,MACrB,QAAQ,EAAE,OAAO;AAAA,MACjB,SAAS,EAAE,OAAO;AAAA,IACpB,CAAC;AAAA,EACH;AAAA,EACA,OAAO,EAAE,UAAU,MAAM;AACvB,UAAM,YAAY,uBAAuB;AACzC,UAAM,KAAK,cAAc,UAAU,eAAe,SAAS,MAAM,IAAI,SAAS;AAE9E,QAAI,CAAC,UAAU,eAAe,SAAS,EAAE,GAAG;AAC1C,aAAO;AAAA,QACL,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,GAAG,EAAE,gCAA6B,CAAC;AAAA,QACnE,mBAAmB,EAAE,QAAQ,aAAa,SAAS,sBAAsB;AAAA,MAC3E;AAAA,IACF;AAEA,WAAO;AAAA,MACL,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,0CAA0C,EAAE,WAAW,CAAC;AAAA,MACxF,mBAAmB;AAAA,QACjB,QAAQ;AAAA,QACR,SAAS,sDAAsD,EAAE;AAAA,MACnE;AAAA,IACF;AAAA,EACF;AACF;AAEA,OAAO;AAAA,EACL;AAAA,EACA;AAAA,IACE,OAAO;AAAA,IACP,aAAa;AAAA,IACb,aAAa,EAAE,OAAO;AAAA,MACpB,SAAS,EAAE,OAAO,EAAE,SAAS,4DAA4D;AAAA,MACzF,WAAW,EAAE,KAAK;AAAA,QAChB;AAAA,QAAW;AAAA,QAAc;AAAA,QAAe;AAAA,QAAQ;AAAA,QAAU;AAAA,QAAS;AAAA,QAAU;AAAA,QAAS;AAAA,MACxF,CAAC,EAAE,SAAS,EAAE,SAAS,mDAAmD;AAAA,MAC1E,YAAY,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,wDAA+C;AAAA,IAC5F,CAAC;AAAA,IACD,cAAc,EAAE,OAAO;AAAA,MACrB,IAAI,EAAE,QAAQ;AAAA,MACd,cAAc,EAAE,OAAO,EAAE,SAAS;AAAA,MAClC,UAAU,EAAE,OAAO;AAAA,MACnB,aAAa,EAAE,KAAK,CAAC,UAAU,UAAU,aAAa,CAAC;AAAA,MACvD,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,OAAO,GAAG,QAAQ,EAAE,OAAO,GAAG,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC,EAAE,SAAS;AAAA,MACvG,OAAO,EAAE,OAAO,EAAE,SAAS;AAAA,IAC7B,CAAC;AAAA,EACH;AAAA,EACA,OAAO,EAAE,SAAS,WAAW,aAAa,EAAE,MAAM;AAChD,UAAM,YAAY,uBAAuB;AACzC,UAAM,KAAK,aAAa,UAAU,eAAe,CAAC;AAClD,QAAI,CAAC,IAAI;AACP,aAAO;AAAA,QACL,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,yDAAyD,CAAC;AAAA,QAC1F,mBAAmB,EAAE,IAAI,OAAO,OAAO,gBAAgB,aAAa,UAAU,UAAU,EAAE;AAAA,MAC5F;AAAA,IACF;AAEA,UAAM,MAAM,mBAAmB,QAAQ;AACvC,QAAI,CAAC,IAAI,QAAQ;AACf,aAAO;AAAA,QACL,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,mEAAmE,CAAC;AAAA,QACpG,mBAAmB,EAAE,IAAI,OAAO,OAAO,cAAc,aAAa,UAAU,UAAU,EAAE;AAAA,MAC1F;AAAA,IACF;AAEA,UAAM,YAAY,CAAC;AACnB,UAAM,SAAS,kBAAkB;AACjC,UAAM,eAAe;AAAA,MACnB,eAAe,UAAU,eAAe,KAAK,IAAI,CAAC;AAAA,MAClD,WAAW,UAAU,SAAS,KAAK,IAAI,CAAC;AAAA,MACxC,OAAO,OAAO,SAAS,WAAW,OAAO,MAAM,IAAI,CAAC,MAAM,EAAE,QAAQ,EAAE,EAAE,EAAE,KAAK,IAAI,CAAC,KAAK;AAAA,IAC3F,EAAE,OAAO,OAAO,EAAE,KAAK,IAAI;AAE3B,QAAI,eAAe;AACnB,QAAI,cAAc;AAClB,QAAI,UAAU;AAEd,cAAU,KAAK,EAAE,SAAS,GAAG,QAAQ,kBAAkB,QAAQ,GAAG,UAAU,eAAe,MAAM,gBAAgB,CAAC;AAElH,SAAK,UAAU,GAAG,WAAW,YAAY,WAAW;AAClD,gBAAU,KAAK,EAAE,SAAS,QAAQ,kBAAkB,QAAQ,aAAa,CAAC;AAE1E,YAAM,EAAE,UAAU,QAAQ,SAAS,MAAM,IAAI;AAC7C,YAAM,cAAc,OAAO,WAAW,OAAO,CAAC,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,EAAE,IAAI,CAAC,MAAM,EAAE,GAAG,EAAE,KAAK,IAAI,KAAK;AAC1G,YAAM,eAAe,qDAA+C,EAAE;AAAA,EAC1E,cAAc;AAAA;AAAA,EAAqD,YAAY,MAAM,GAAG,GAAI,CAAC,KAAK,EAAE;AAAA;AAGhG,YAAM,aAAa;AAAA,EAAc,YAAY;AAAA;AAAA,mBAAwB,OAAO;AAAA,aAAgB,EAAE;AAE9F,UAAI;AACF,YAAI,cAAc;AAClB,YAAI,aAAa,UAAU;AACzB,gBAAM,MAAM,GAAG,OAAO,WAAW,KAAK,wBAAwB,MAAM;AACpE,gBAAM,MAAM,MAAM,MAAM,KAAK;AAAA,YAC3B,QAAQ;AAAA,YACR,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,YAC9C,MAAM,KAAK,UAAU;AAAA,cACnB,UAAU,CAAC,EAAE,OAAO,CAAC,EAAE,MAAM,eAAe,SAAS,WAAW,CAAC,EAAE,CAAC;AAAA,cACpE,kBAAkB,EAAE,aAAa,KAAK,iBAAiB,KAAK;AAAA,YAC9D,CAAC;AAAA,UACH,CAAC;AACD,gBAAM,OAAO,MAAM,IAAI,KAAK;AAC5B,wBAAc,KAAK,aAAa,CAAC,GAAG,SAAS,QAAQ,CAAC,GAAG,QAAQ;AAAA,QACnE,OAAO;AACL,gBAAM,MAAM,MAAM,MAAM,GAAG,OAAO,qBAAqB;AAAA,YACrD,QAAQ;AAAA,YACR,SAAS,EAAE,gBAAgB,oBAAoB,eAAe,UAAU,MAAM,GAAG;AAAA,YACjF,MAAM,KAAK,UAAU;AAAA,cACnB;AAAA,cACA,UAAU,CAAC,EAAE,MAAM,UAAU,SAAS,aAAa,GAAG,EAAE,MAAM,QAAQ,SAAS,WAAW,CAAC;AAAA,cAC3F,aAAa;AAAA,cACb,YAAY;AAAA,YACd,CAAC;AAAA,UACH,CAAC;AACD,gBAAM,OAAO,MAAM,IAAI,KAAK;AAC5B,wBAAc,KAAK,UAAU,CAAC,GAAG,SAAS,WAAW;AAAA,QACvD;AACA,sBAAc,YAAY,QAAQ,yCAAyC,EAAE,EAAE,QAAQ,eAAe,EAAE,EAAE,KAAK;AAC/G,sBAAc;AAEd,YAAI,CAAC,cAAc;AACjB,gBAAM,WAAW,QAAQ,YAAY,EAAE,QAAQ,QAAQ,GAAG,EAAE,QAAQ,eAAe,EAAE,EAAE,MAAM,GAAG,EAAE;AAClG,gBAAM,EAAE,KAAK,QAAQ,IAAI,uBAAuB,IAAI,SAAS;AAC7D,gBAAM,WAAW,WAAW;AAC5B,yBAAe,KAAK,KAAK,SAAS,QAAQ;AAC1C,cAAI,CAAC,GAAG,WAAW,OAAO,EAAG,IAAG,UAAU,SAAS,EAAE,WAAW,KAAK,CAAC;AAAA,QACxE;AACA,WAAG,cAAc,cAAc,aAAa,MAAM;AAClD,kBAAU,KAAK,EAAE,SAAS,QAAQ,cAAc,QAAQ,YAAY,YAAY,GAAG,CAAC;AAEpF,kBAAU,KAAK,EAAE,SAAS,QAAQ,aAAa,QAAQ,gBAAgB,CAAC;AACxE,cAAM,YAAY,MAAM,IAAI,QAAQ,CAAC,YAAY;AAC/C,gBAAM,QAAQ,MAAM,OAAO,CAAC,OAAO,YAAY,YAAY,OAAO,eAAe,eAAe,IAAI,OAAO,YAAY,QAAQ,OAAO,eAAe,SAAS,OAAO,YAAY,GAAG;AAAA,YAClL,KAAK;AAAA,YACL,OAAO,CAAC,WAAW,QAAQ,MAAM;AAAA,YACjC,OAAO,QAAQ,aAAa;AAAA,UAC9B,CAAC;AACD,cAAI,SAAS,IAAI,SAAS;AAC1B,cAAI,MAAM,OAAQ,OAAM,OAAO,GAAG,QAAQ,CAAC,MAAM;AAAE,sBAAU,EAAE,SAAS;AAAA,UAAG,CAAC;AAC5E,cAAI,MAAM,OAAQ,OAAM,OAAO,GAAG,QAAQ,CAAC,MAAM;AAAE,sBAAU,EAAE,SAAS;AAAA,UAAG,CAAC;AAC5E,gBAAM,GAAG,SAAS,CAAC,SAAS,QAAQ,EAAE,MAAM,QAAQ,CAAC,QAAQ,MAAM,EAAE,OAAO,OAAO,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC;AAAA,QACpG,CAAC;AAED,YAAI,UAAU,SAAS,GAAG;AACxB,oBAAU,KAAK,EAAE,SAAS,QAAQ,aAAa,QAAQ,gBAAW,CAAC;AACnE,4BAAkB;AAAA,YAChB,WAAW,CAAC,EAAE,MAAM,kBAAkB,SAAS,WAAW,IAAI,SAAS,MAAM,iBAAiB,YAAY,GAAG,UAAU,SAAS,YAAW,oBAAI,KAAK,GAAE,YAAY,EAAE,CAAC;AAAA,UACvK,CAAC;AACD,iBAAO;AAAA,YACL,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,oCAA+B,OAAO;AAAA;AAAA,WAAiB,YAAY;AAAA;AAAA,sBAA2B,CAAC;AAAA,YAC/H,mBAAmB,EAAE,IAAI,MAAM,cAAc,UAAU,SAAS,aAAa,UAAU,UAAU;AAAA,UACnG;AAAA,QACF;AAEA,kBAAU,KAAK,EAAE,SAAS,QAAQ,aAAa,QAAQ,uBAAkB,UAAU,IAAI,IAAI,CAAC;AAE5F,YAAI,WAAW,YAAY;AACzB,oBAAU,KAAK,EAAE,SAAS,QAAQ,eAAe,QAAQ,kBAAkB,CAAC;AAC5E,4BAAkB;AAAA,YAChB,WAAW,CAAC,EAAE,MAAM,kBAAkB,SAAS,WAAW,IAAI,SAAS,OAAO,UAAU,SAAS,YAAW,oBAAI,KAAK,GAAE,YAAY,EAAE,CAAC;AAAA,UACxI,CAAC;AACD,iBAAO;AAAA,YACL,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,+BAAuB,OAAO;AAAA;AAAA;AAAA,EAAmC,UAAU,OAAO,MAAM,GAAG,GAAG,CAAC,GAAG,CAAC;AAAA,YACnI,mBAAmB,EAAE,IAAI,OAAO,cAAc,UAAU,SAAS,aAAa,eAAe,UAAU;AAAA,UACzG;AAAA,QACF;AAEA,kBAAU,KAAK,EAAE,SAAS,QAAQ,oBAAoB,QAAQ,gBAAgB,CAAC;AAC/E,cAAM,gBAAgB,oBAAoB,UAAU,MAAM;AAC1D,cAAM,aAAa,mBAAmB,SAAS;AAC/C,cAAM,gBAAgB,MAAM,2BAA2B,UAAU,QAAQ,YAAY;AAErF,YAAI,CAAC,cAAc,MAAM,CAAC,cAAc,mBAAmB,kBAAkB;AAC3E,oBAAU,KAAK,EAAE,SAAS,QAAQ,oBAAoB,QAAQ,oCAA2B,CAAC;AAC1F;AAAA,QACF;AAEA,kBAAU,KAAK,EAAE,SAAS,QAAQ,aAAa,QAAQ,8BAAwB,CAAC;AAChF,cAAM,YAAY,cAAc,kBAAkB;AAClD,sBAAc;AACd,WAAG,cAAc,cAAc,aAAa,MAAM;AAClD,kBAAU,KAAK,EAAE,SAAS,QAAQ,aAAa,QAAQ,0BAAoB,CAAC;AAE5E,YAAI,cAAc,eAAe;AAC/B,4BAAkB;AAAA,YAChB,WAAW,CAAC;AAAA,cACV,MAAM,cAAc,SAAS,CAAC,GAAG,YAAY,aAAa,iBAAiB;AAAA,cAC3E;AAAA,cACA,WAAW;AAAA,cACX,KAAK,UAAU,MAAM,GAAG,GAAG;AAAA,cAC3B,SAAS;AAAA,cACT,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,YACpC,CAAC;AAAA,UACH,CAAC;AAAA,QACH;AAAA,MACF,SAAS,KAAK;AACZ,kBAAU,KAAK,EAAE,SAAS,QAAQ,SAAS,QAAQ,IAAI,QAAQ,CAAC;AAChE,eAAO;AAAA,UACL,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,qBAAqB,OAAO,KAAK,IAAI,OAAO,GAAG,CAAC;AAAA,UAChF,mBAAmB,EAAE,IAAI,OAAO,OAAO,IAAI,SAAS,UAAU,SAAS,aAAa,UAAU,UAAU;AAAA,QAC1G;AAAA,MACF;AAAA,IACF;AAEA,WAAO;AAAA,MACL,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,yBAAiB,UAAU,iBAAiB,CAAC;AAAA,MAC7E,mBAAmB,EAAE,IAAI,OAAO,cAAc,UAAU,YAAY,aAAa,eAAe,UAAU;AAAA,IAC5G;AAAA,EACF;AACF;AAEA,OAAO;AAAA,EACL;AAAA,EACA;AAAA,IACE,OAAO;AAAA,IACP,aAAa;AAAA,IACb,aAAa,EAAE,OAAO;AAAA,MACpB,WAAW,EAAE,KAAK,CAAC,WAAW,cAAc,MAAM,CAAC,EAAE,SAAS,YAAY;AAAA,MAC1E,MAAM,EAAE,KAAK,CAAC,OAAO,MAAM,MAAM,CAAC,EAAE,SAAS,EAAE,SAAS,8BAA8B;AAAA,IACxF,CAAC;AAAA,IACD,cAAc,EAAE,OAAO;AAAA,MACrB,IAAI,EAAE,QAAQ;AAAA,MACd,UAAU,EAAE,OAAO;AAAA,MACnB,mBAAmB,EAAE,OAAO;AAAA,IAC9B,CAAC;AAAA,EACH;AAAA,EACA,OAAO,EAAE,WAAW,OAAO,MAAM,MAAM;AACrC,QAAI,WAAW;AACf,QAAI,WAAW;AAEf,QAAI,cAAc,WAAW;AAC3B,iBAAW,GAAG,IAAI;AAClB,iBAAW,aAAa,KAAK,YAAY,CAAC;AAAA;AAAA,MAE1C,SAAS,QAAQ,yHAAyH,wDAAwD;AAAA;AAAA;AAAA,IAGpM,WAAW,cAAc,cAAc;AACrC,iBAAW,GAAG,IAAI;AAClB,iBAAW;AAAA;AAAA,iBAEA,KAAK,YAAY,CAAC;AAAA,iCACF,SAAS,QAAQ,YAAY,MAAM;AAAA,MAC9D,SAAS,QAAQ,4GAA4G,4EAA4E;AAAA;AAAA;AAAA,IAG3M,OAAO;AACL,iBAAW,GAAG,IAAI;AAClB,iBAAW,aAAa,KAAK,YAAY,CAAC;AAAA,wBACxB,SAAS,QAAQ,4HAA4H,4CAA4C;AAAA;AAAA,IAE7M;AAEA,WAAO;AAAA,MACL,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,+CAA+C,CAAC;AAAA,MAChF,mBAAmB,EAAE,IAAI,MAAM,UAAU,mBAAmB,SAAS;AAAA,IACvE;AAAA,EACF;AACF;AAEA,eAAe,OAAO;AACpB,QAAM,MAAM,QAAQ,KAAK,CAAC;AAE1B,MAAI,QAAQ,YAAY,QAAQ,MAAM;AACpC,YAAQ,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CA8Bf;AACG,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,MAAI,QAAQ,UAAU;AACpB,UAAM,YAAY,uBAAuB;AACzC,UAAM,WAAW,QAAQ,KAAK,SAAS,QAAQ;AAC/C,QAAI,UAAU;AACZ,cAAQ,IAAI,KAAK,UAAU,WAAW,MAAM,CAAC,CAAC;AAAA,IAChD,OAAO;AACL,YAAM,QAAQ;AAAA,QACZ;AAAA,QACA;AAAA,QACA,SAAI,OAAO,EAAE;AAAA,QACb,eAAe,UAAU,eAAe,SAAS,UAAU,eAAe,KAAK,IAAI,IAAI,QAAQ;AAAA,QAC/F,cAAc,UAAU,SAAS,SAAS,UAAU,SAAS,KAAK,IAAI,IAAI,SAAS;AAAA,QACnF,cAAc,UAAU,cAAc,QAAG;AAAA,QACzC,cAAc,UAAU,eAAe,QAAG;AAAA,QAC1C,cAAc,UAAU,YAAY,QAAQ,QAAG;AAAA,QAC/C,SAAI,OAAO,EAAE;AAAA,QACb;AAAA,QACA;AAAA,MACF;AACA,cAAQ,IAAI,MAAM,KAAK,IAAI,CAAC;AAAA,IAC9B;AACA,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,MAAI,QAAQ,QAAQ;AAClB,UAAM,SAAS,OAAO,QAAQ,SAAS,EAAE,IAAI,CAAC,CAAC,GAAG,CAAC,MAAM,KAAK,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC,EAAE;AACxF,YAAQ,IAAI,6BAA6B,OAAO,KAAK,IAAI,CAAC;AAC1D,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,MAAI,QAAQ,WAAW,QAAQ,KAAK,CAAC,GAAG;AACtC,UAAM,OAAO,QAAQ,KAAK,MAAM,CAAC,EAAE,KAAK,GAAG;AAC3C,UAAM,IAAI,KAAK,YAAY;AAC3B,QAAI,QAAQ;AACZ,QAAI,+DAA+D,KAAK,CAAC,EAAG,SAAQ;AAAA,aAC3E,qEAAqE,KAAK,CAAC,EAAG,SAAQ;AAAA,aACtF,0CAA0C,KAAK,CAAC,EAAG,SAAQ;AAAA,aAC3D,gDAAgD,KAAK,CAAC,EAAG,SAAQ;AAAA,aACjE,gDAAgD,KAAK,CAAC,EAAG,SAAQ;AAAA,aACjE,gDAAgD,KAAK,CAAC,EAAG,SAAQ;AAAA,aACjE,gCAAgC,KAAK,CAAC,EAAG,SAAQ;AAAA,aACjD,+CAA+C,KAAK,CAAC,EAAG,SAAQ;AACzE,UAAM,IAAI,UAAU,KAAK,KAAK,UAAU;AACxC,YAAQ,IAAI,KAAK,UAAU,EAAE,gBAAgB,OAAO,gBAAgB,EAAE,OAAO,aAAa,EAAE,KAAK,GAAG,MAAM,CAAC,CAAC;AAC5G,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,MAAI,QAAQ,QAAQ;AAClB,UAAM,UAAU,QAAQ,KAAK,MAAM,CAAC,EAAE,KAAK,GAAG;AAC9C,QAAI,CAAC,SAAS;AACZ,cAAQ,MAAM,6EAAkE;AAChF,cAAQ,KAAK,CAAC;AAAA,IAChB;AACA,UAAM,gBAAgB,QAAQ,KAAK,QAAQ,eAAe;AAC1D,UAAM,aAAa,kBAAkB,MAAM,QAAQ,KAAK,gBAAgB,CAAC,IAAI,SAAS,QAAQ,KAAK,gBAAgB,CAAC,GAAG,EAAE,IAAI;AAC7H,UAAM,eAAe,QAAQ,QAAQ,wBAAwB,EAAE,EAAE,KAAK;AAEtE,YAAQ,IAAI;AAAA,wCAAiC,YAAY;AAAA,CAAK;AAC9D,UAAM,YAAY,uBAAuB;AACzC,UAAM,KAAK,UAAU,eAAe,CAAC;AACrC,QAAI,CAAC,IAAI;AACP,cAAQ,MAAM,oCAA+B;AAC7C,cAAQ,KAAK,CAAC;AAAA,IAChB;AAEA,UAAM,MAAM,mBAAmB,QAAQ;AACvC,QAAI,CAAC,IAAI,QAAQ;AACf,cAAQ,MAAM,yEAAoE;AAClF,cAAQ,KAAK,CAAC;AAAA,IAChB;AAEA,UAAM,SAAS,kBAAkB;AACjC,UAAM,eAAe;AAAA,MACnB,eAAe,UAAU,eAAe,KAAK,IAAI,CAAC;AAAA,MAClD,WAAW,UAAU,SAAS,KAAK,IAAI,CAAC;AAAA,MACxC,OAAO,OAAO,SAAS,WAAW,OAAO,MAAM,IAAI,CAAC,MAAM,EAAE,QAAQ,EAAE,EAAE,EAAE,KAAK,IAAI,CAAC,KAAK;AAAA,IAC3F,EAAE,OAAO,OAAO,EAAE,KAAK,IAAI;AAE3B,QAAI,eAAe;AACnB,QAAI,cAAc;AAElB,aAAS,UAAU,GAAG,WAAW,YAAY,WAAW;AACtD,cAAQ,IAAI;AAAA,aAAgB,OAAO,IAAI,UAAU,oBAAoB;AAErE,YAAM,EAAE,UAAU,QAAQ,SAAS,MAAM,IAAI;AAC7C,YAAM,cAAc,OAAO,WAAW,OAAO,CAAC,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,EAAE,IAAI,CAAC,MAAM,EAAE,GAAG,EAAE,KAAK,IAAI,KAAK;AAC1G,YAAM,eAAe,qDAA+C,EAAE;AAAA,EAC1E,cAAc;AAAA;AAAA,EAAqD,YAAY,MAAM,GAAG,GAAI,CAAC,KAAK,EAAE;AAAA;AAGhG,YAAM,aAAa;AAAA,EAAc,YAAY;AAAA;AAAA,mBAAwB,YAAY;AAAA,aAAgB,EAAE;AAEnG,UAAI;AACF,YAAI,cAAc;AAClB,YAAI,aAAa,UAAU;AACzB,gBAAM,MAAM,GAAG,OAAO,WAAW,KAAK,wBAAwB,MAAM;AACpE,gBAAM,MAAM,MAAM,MAAM,KAAK;AAAA,YAC3B,QAAQ;AAAA,YACR,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,YAC9C,MAAM,KAAK,UAAU;AAAA,cACnB,UAAU,CAAC,EAAE,OAAO,CAAC,EAAE,MAAM,eAAe,SAAS,WAAW,CAAC,EAAE,CAAC;AAAA,cACpE,kBAAkB,EAAE,aAAa,KAAK,iBAAiB,KAAK;AAAA,YAC9D,CAAC;AAAA,UACH,CAAC;AACD,gBAAM,OAAO,MAAM,IAAI,KAAK;AAC5B,wBAAc,KAAK,aAAa,CAAC,GAAG,SAAS,QAAQ,CAAC,GAAG,QAAQ;AAAA,QACnE,OAAO;AACL,gBAAM,MAAM,MAAM,MAAM,GAAG,OAAO,qBAAqB;AAAA,YACrD,QAAQ;AAAA,YACR,SAAS,EAAE,gBAAgB,oBAAoB,eAAe,UAAU,MAAM,GAAG;AAAA,YACjF,MAAM,KAAK,UAAU;AAAA,cACnB;AAAA,cACA,UAAU,CAAC,EAAE,MAAM,UAAU,SAAS,aAAa,GAAG,EAAE,MAAM,QAAQ,SAAS,WAAW,CAAC;AAAA,cAC3F,aAAa;AAAA,cACb,YAAY;AAAA,YACd,CAAC;AAAA,UACH,CAAC;AACD,gBAAM,OAAO,MAAM,IAAI,KAAK;AAC5B,wBAAc,KAAK,UAAU,CAAC,GAAG,SAAS,WAAW;AAAA,QACvD;AACA,sBAAc,YAAY,QAAQ,yCAAyC,EAAE,EAAE,QAAQ,eAAe,EAAE,EAAE,KAAK;AAC/G,sBAAc;AAEd,YAAI,CAAC,cAAc;AACjB,gBAAM,WAAW,aAAa,YAAY,EAAE,QAAQ,QAAQ,GAAG,EAAE,QAAQ,eAAe,EAAE,EAAE,MAAM,GAAG,EAAE;AACvG,gBAAM,EAAE,KAAK,QAAQ,IAAI,uBAAuB,IAAI,SAAS;AAC7D,gBAAM,WAAW,WAAW;AAC5B,yBAAe,KAAK,KAAK,SAAS,QAAQ;AAC1C,cAAI,CAAC,GAAG,WAAW,OAAO,EAAG,IAAG,UAAU,SAAS,EAAE,WAAW,KAAK,CAAC;AAAA,QACxE;AACA,WAAG,cAAc,cAAc,aAAa,MAAM;AAClD,gBAAQ,IAAI,yBAAoB,YAAY,EAAE;AAE9C,gBAAQ,IAAI;AAAA,aAAgB,OAAO,IAAI,UAAU,uBAAuB;AACxE,cAAM,YAAY,MAAM,IAAI,QAAQ,CAAC,YAAY;AAC/C,gBAAM,QAAQ,MAAM,OAAO,CAAC,OAAO,YAAY,YAAY,OAAO,eAAe,eAAe,IAAI,OAAO,YAAY,QAAQ,OAAO,eAAe,SAAS,OAAO,YAAY,GAAG;AAAA,YAClL,KAAK;AAAA,YACL,OAAO,CAAC,WAAW,QAAQ,MAAM;AAAA,YACjC,OAAO,QAAQ,aAAa;AAAA,UAC9B,CAAC;AACD,cAAI,SAAS,IAAI,SAAS;AAC1B,cAAI,MAAM,OAAQ,OAAM,OAAO,GAAG,QAAQ,CAAC,MAAM;AAAE,sBAAU,EAAE,SAAS;AAAA,UAAG,CAAC;AAC5E,cAAI,MAAM,OAAQ,OAAM,OAAO,GAAG,QAAQ,CAAC,MAAM;AAAE,sBAAU,EAAE,SAAS;AAAA,UAAG,CAAC;AAC5E,gBAAM,GAAG,SAAS,CAAC,SAAS,QAAQ,EAAE,MAAM,QAAQ,CAAC,QAAQ,MAAM,EAAE,OAAO,OAAO,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC;AAAA,QACpG,CAAC;AAED,YAAI,UAAU,SAAS,GAAG;AACxB,kBAAQ,IAAI;AAAA,mCAAiC,OAAO,GAAG;AACvD,4BAAkB;AAAA,YAChB,WAAW,CAAC,EAAE,MAAM,kBAAkB,SAAS,cAAc,WAAW,IAAI,SAAS,MAAM,iBAAiB,YAAY,GAAG,UAAU,SAAS,YAAW,oBAAI,KAAK,GAAE,YAAY,EAAE,CAAC;AAAA,UACrL,CAAC;AACD,kBAAQ,IAAI;AAAA;AAAA,CAAwE;AACpF,kBAAQ,KAAK,CAAC;AAAA,QAChB;AAEA,gBAAQ,IAAI;AAAA,4BAA0B,UAAU,IAAI,GAAG;AACvD,gBAAQ,IAAI;AAAA;AAAA,EAAa,UAAU,OAAO,MAAM,GAAG,GAAG,CAAC;AAAA,CAAI;AAE3D,YAAI,WAAW,YAAY;AACzB,kBAAQ,IAAI;AAAA,wCAAsC,UAAU;AAAA,CAAM;AAClE,4BAAkB;AAAA,YAChB,WAAW,CAAC,EAAE,MAAM,kBAAkB,SAAS,cAAc,WAAW,IAAI,SAAS,OAAO,UAAU,SAAS,YAAW,oBAAI,KAAK,GAAE,YAAY,EAAE,CAAC;AAAA,UACtJ,CAAC;AACD,kBAAQ,KAAK,CAAC;AAAA,QAChB;AAEA,gBAAQ,IAAI;AAAA,aAAgB,OAAO,IAAI,UAAU,uBAAuB;AACxE,cAAM,gBAAgB,oBAAoB,UAAU,MAAM;AAC1D,YAAI,cAAc,eAAe;AAC/B,kBAAQ,IAAI,iCAAuB,cAAc,WAAW,QAAQ,CAAC,CAAC,MAAM,cAAc,SAAS,IAAI,CAAC,MAAM,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC,EAAE;AAAA,QACvI;AAEA,cAAM,gBAAgB,MAAM,2BAA2B,UAAU,QAAQ,YAAY;AACrF,YAAI,CAAC,cAAc,MAAM,CAAC,cAAc,mBAAmB,kBAAkB;AAC3E,kBAAQ,IAAI,iFAA2D;AACvE;AAAA,QACF;AAEA,gBAAQ,IAAI;AAAA,aAAgB,OAAO,IAAI,UAAU,+BAAyB;AAC1E,cAAM,YAAY,cAAc,kBAAkB;AAClD,sBAAc;AACd,WAAG,cAAc,cAAc,aAAa,MAAM;AAClD,gBAAQ,IAAI,iCAAsB;AAElC,YAAI,cAAc,eAAe;AAC/B,4BAAkB;AAAA,YAChB,WAAW,CAAC;AAAA,cACV,MAAM,cAAc,SAAS,CAAC,GAAG,YAAY,aAAa,iBAAiB;AAAA,cAC3E,SAAS;AAAA,cACT,WAAW;AAAA,cACX,KAAK,UAAU,MAAM,GAAG,GAAG;AAAA,cAC3B,SAAS;AAAA,cACT,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,YACpC,CAAC;AAAA,UACH,CAAC;AAAA,QACH;AAAA,MACF,SAAS,KAAK;AACZ,gBAAQ,MAAM;AAAA,2BAAyB,OAAO,KAAK,IAAI,OAAO;AAAA,CAAI;AAClE,gBAAQ,KAAK,CAAC;AAAA,MAChB;AAAA,IACF;AAEA,YAAQ,IAAI;AAAA,wBAAmB,UAAU;AAAA,CAAkB;AAC3D,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,MAAI,QAAQ,SAAS;AACnB,UAAM,QAAQ,eAAe;AAC7B,YAAQ,IAAI;AAAA;AAAA;AAAA,yBAGS,MAAM,cAAc;AAAA,iCAClB,MAAM,eAAe;AAAA,gCACtB,MAAM,aAAa;AAAA,6BACtB,MAAM,WAAW;AAAA,kBACtB,MAAM,cAAc;AAAA,sCACH,MAAM,uBAAuB;AAAA;AAAA,EAE9D,MAAM,mBAAmB,IAAI,qIAA+G,EAAE;AAAA,CAC/I;AACG,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,QAAM,YAAY,IAAI,qBAAqB;AAC3C,QAAM,OAAO,QAAQ,SAAS;AAChC;AAEA,KAAK,EAAE,MAAM,CAAC,QAAQ;AACpB,UAAQ,MAAM,uBAAuB,GAAG;AACxC,UAAQ,KAAK,CAAC;AAChB,CAAC;","names":["model","res","data"]}
|
package/package.json
CHANGED