@cementic/cementic-test 0.2.6 → 0.2.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/cli.ts","../src/commands/new.ts","../src/commands/normalize.ts","../src/commands/test.ts","../src/commands/tc.ts","../src/core/prefix.ts","../src/core/llm.ts","../src/core/analyse.ts","../src/core/capture.ts","../src/core/report.ts","../src/commands/report.ts","../src/commands/serve.ts","../src/commands/flow.ts","../src/commands/ci.ts"],"sourcesContent":["import { Command } from 'commander';\nimport { createRequire } from 'node:module';\nimport { newCmd } from './commands/new.js';\nimport { normalizeCmd } from './commands/normalize.js';\nimport { genCmd } from './commands/gen.js';\nimport { testCmd } from './commands/test.js';\nimport { tcCmd } from './commands/tc.js';\nimport { reportCmd } from './commands/report.js';\nimport { serveCmd } from './commands/serve.js';\nimport { flowCmd } from './commands/flow.js';\nimport { ciCmd } from './commands/ci.js';\n\nconst require = createRequire(import.meta.url);\nconst { version } = require('../package.json');\n\nconst program = new Command();\nprogram\n .name('ct')\n .description('CementicTest CLI: cases → normalized → POM tests → Playwright')\n .version(version);\n\nprogram.addCommand(newCmd());\nprogram.addCommand(normalizeCmd());\nprogram.addCommand(genCmd());\nprogram.addCommand(testCmd());\nprogram.addCommand(tcCmd());\nprogram.addCommand(reportCmd());\nprogram.addCommand(serveCmd());\nprogram.addCommand(flowCmd());\nprogram.addCommand(ciCmd());\n\nprogram.parseAsync(process.argv);","import { Command } from 'commander';\nimport { mkdirSync, writeFileSync, existsSync, readFileSync, cpSync, readdirSync, statSync } from 'node:fs';\nimport { join, resolve } from 'node:path';\nimport { execSync } from 'node:child_process';\nimport { fileURLToPath } from 'node:url';\nimport { dirname } from 'node:path';\nimport { platform, release } from 'node:os';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\nfunction resolveTemplatePath(templateDir: string): string | undefined {\n const candidates = [\n resolve(__dirname, `templates/${templateDir}`),\n resolve(__dirname, `../templates/${templateDir}`),\n resolve(__dirname, `../../templates/${templateDir}`),\n resolve(process.cwd(), `templates/${templateDir}`),\n ];\n\n return candidates.find(candidate => existsSync(candidate));\n}\n\nexport function newCmd() {\n const cmd = new Command('new')\n .arguments('<projectName>')\n .description('Scaffold a new CementicTest + Playwright project from scratch')\n .addHelpText('after', `\nExamples:\n $ ct new my-awesome-test-suite\n $ ct new e2e-ts --lang ts\n $ ct new e2e-tests --no-browsers\n`)\n .option('--mode <mode>', 'greenfield|enhance', 'greenfield')\n .option('--lang <lang>', 'Scaffold language (js|ts)', 'js')\n .option('--no-browsers', 'do not run \"npx playwright install\" during setup')\n .action((projectName: string, opts) => {\n const root = process.cwd();\n const projectPath = join(root, projectName);\n\n console.log(`🚀 Initializing new CementicTest project in ${projectName}...`);\n\n // 1. Create project directory\n if (existsSync(projectPath)) {\n console.error(`❌ Directory ${projectName} already exists.`);\n process.exit(1);\n }\n mkdirSync(projectPath, { recursive: true });\n\n const lang = opts.lang === 'ts' ? 'ts' : 'js';\n const templateDir = lang === 'ts' ? 'student-framework-ts' : 'student-framework';\n const templatePath = resolveTemplatePath(templateDir);\n\n if (!templatePath) {\n console.error(`❌ Could not locate template \"${templateDir}\"`);\n console.error('Please ensure the package is built correctly with templates included.');\n process.exit(1);\n }\n\n console.log(`📦 Copying template from ${templatePath}...`);\n \n // Recursive copy function\n function copyRecursive(src: string, dest: string) {\n if (statSync(src).isDirectory()) {\n mkdirSync(dest, { recursive: true });\n readdirSync(src).forEach(child => {\n copyRecursive(join(src, child), join(dest, child));\n });\n } else {\n cpSync(src, dest);\n }\n }\n\n copyRecursive(templatePath, projectPath);\n\n // 2.5 Adjust for OS compatibility (macOS 13/Ventura or older)\n if (platform() === 'darwin') {\n const osRelease = release();\n const majorVersion = parseInt(osRelease.split('.')[0], 10);\n \n // macOS 13 is Darwin 22. macOS 14 is Darwin 23.\n if (majorVersion < 23) {\n console.log('🍎 Detected macOS 13 or older. Adjusting versions for compatibility...');\n const pkgJsonPath = join(projectPath, 'package.json');\n if (existsSync(pkgJsonPath)) {\n try {\n const pkgContent = readFileSync(pkgJsonPath, 'utf-8');\n const pkg = JSON.parse(pkgContent);\n if (pkg.devDependencies) {\n pkg.devDependencies['@playwright/test'] = '^1.48.2';\n pkg.devDependencies['allure-playwright'] = '^2.15.1';\n writeFileSync(pkgJsonPath, JSON.stringify(pkg, null, 2));\n console.log('✅ Downgraded @playwright/test and allure-playwright for legacy macOS support.');\n }\n } catch (err) {\n console.warn('⚠️ Failed to adjust package.json for OS compatibility:', err);\n }\n }\n }\n }\n\n // 3. Initialize git\n try {\n execSync('git init', { cwd: projectPath, stdio: 'ignore' });\n // Create .gitignore if not exists (template should have it, but just in case)\n const gitignorePath = join(projectPath, '.gitignore');\n if (!existsSync(gitignorePath)) {\n writeFileSync(gitignorePath, 'node_modules\\n.env\\ntest-results\\nplaywright-report\\n.cementic\\n');\n }\n } catch (e) {\n console.warn('⚠️ Failed to initialize git repository.');\n }\n\n // 4. Install dependencies\n console.log('📦 Installing dependencies...');\n try {\n execSync('npm install', { cwd: projectPath, stdio: 'inherit' });\n } catch (e) {\n console.error('❌ Failed to install dependencies. Please run \"npm install\" manually.');\n }\n\n // 5. Install browsers (optional)\n // Commander maps --no-browsers to opts.browsers = false\n if (opts.browsers !== false) {\n console.log('🌐 Installing Playwright browsers...');\n try {\n execSync('npx playwright install', { cwd: projectPath, stdio: 'inherit' });\n } catch (e) {\n console.warn('⚠️ Failed to install browsers. Run \"npx playwright install\" manually.');\n }\n }\n\n console.log(`\\n✅ Project ${projectName} created successfully!`);\n console.log(`\\nTo get started:\\n`);\n console.log(` cd ${projectName}`);\n console.log(` npx playwright test`);\n console.log(`\\nHappy testing! 🧪`);\n });\n\n return cmd;\n}\n","import { Command } from 'commander';\nimport fg from 'fast-glob';\nimport { readFileSync, mkdirSync, writeFileSync, statSync } from 'node:fs';\nimport { join, basename, resolve } from 'node:path';\n\ntype NormalizedCase = {\n id?: string;\n title: string;\n tags?: string[];\n steps: string[];\n step_hints?: Array<{ selector?: string }>;\n expected: string[];\n assertion_hints?: Array<{ playwright?: string }>;\n needs_review: boolean;\n review_reasons: string[];\n source: string;\n url?: string;\n};\n\n/** Grab @tags from the title line */\nfunction parseTags(title: string): { clean: string; tags: string[] } {\n const tags = Array.from(title.matchAll(/@([\\w-]+)/g)).map((m) => m[1]);\n const clean = title.replace(/@[\\w-]+/g, '').trim();\n return { clean, tags };\n}\n\n/** Try to extract an ID prefix like AUTH-001 from the title */\nfunction parseId(title: string): string | undefined {\n const m = title.match(/\\b([A-Z]+-\\d+)\\b/);\n return m?.[1];\n}\n\nfunction stripIdPrefixFromTitle(title: string, id?: string): string {\n if (!id) return title.trim();\n return title.replace(new RegExp(`^${id}\\\\s*[—\\\\-–:]\\\\s*`), '').trim();\n}\n\n/** Split a markdown file into case blocks by top-level \"# \" headings */\nfunction splitCasesByHeading(fileText: string): Array<{ titleLine: string; body: string }> {\n const lines = fileText.split(/\\r?\\n/);\n const blocks: Array<{ titleLine: string; body: string }> = [];\n let currentTitle: string | null = null;\n let buf: string[] = [];\n\n const flush = () => {\n if (currentTitle !== null) {\n blocks.push({ titleLine: currentTitle, body: buf.join('\\n') });\n }\n buf = [];\n };\n\n for (const line of lines) {\n const h1 = line.match(/^\\s*#\\s+(.+)$/); // \"# Title\"\n if (h1) {\n if (currentTitle !== null) flush();\n currentTitle = h1[1].trim();\n } else {\n buf.push(line);\n }\n }\n if (currentTitle !== null) flush();\n\n // If no H1 at all, treat whole file as one case (first non-empty line is title).\n if (blocks.length === 0) {\n const first = lines.find((l) => l.trim());\n const title = first?.replace(/^#\\s*/, '').trim() || 'Untitled';\n return [{ titleLine: title, body: lines.join('\\n') }];\n }\n return blocks;\n}\n\n/** From a case body, extract Steps and Expected sections */\nfunction extractSections(body: string): {\n steps: string[];\n stepHints: Array<{ selector?: string }>;\n expected: string[];\n assertionHints: Array<{ playwright?: string }>;\n} {\n // Find sections by H2 headings\n // Supports: \"## Steps\", \"## Expected\", \"## Expected Results\"\n const sectionRegex = /^\\s*##\\s*(.+?)\\s*$/gim;\n const sections: Record<string, string> = {};\n let match: RegExpExecArray | null;\n const indices: Array<{ name: string; index: number }> = [];\n\n while ((match = sectionRegex.exec(body))) {\n indices.push({ name: match[1].toLowerCase(), index: match.index });\n }\n\n // Add end sentinel\n indices.push({ name: '__END__', index: body.length });\n\n for (let i = 0; i < indices.length - 1; i++) {\n const name = indices[i].name;\n const slice = body.slice(indices[i].index, indices[i + 1].index);\n sections[name] = slice;\n }\n\n const stepsBlock =\n sections['steps'] ??\n ''; // if absent, we’ll infer from bullets later\n\n const expectedBlock =\n sections['expected'] ??\n sections['expected results'] ??\n sections['then'] ??\n '';\n\n const bullet = /^\\s*(?:\\d+\\.|[-*])\\s+(.+)$/gm;\n\n const parsedSteps = Array.from(stepsBlock.matchAll(bullet)).map((m) => parseHintedLine(m[1].trim(), 'selector'));\n const steps = parsedSteps.map((entry) => entry.text);\n const stepHints = parsedSteps.map((entry) => ({ selector: entry.hint }));\n\n // Fallback: if no dedicated steps section, collect bullets until a new H2\n if (steps.length === 0) {\n const alt = Array.from(body.matchAll(bullet)).map((m) => parseHintedLine(m[1].trim(), 'selector'));\n // Heuristic: take the first bullet run in the body\n steps.push(...alt.map((entry) => entry.text));\n stepHints.push(...alt.map((entry) => ({ selector: entry.hint })));\n }\n\n const parsedExpected = Array.from(expectedBlock.matchAll(bullet)).map((m) => parseHintedLine(m[1].trim(), 'playwright'));\n const expectedLines = parsedExpected.map((entry) => entry.text);\n const assertionHints = parsedExpected.map((entry) => ({ playwright: entry.hint }));\n\n // Fallback: lines that start with Expected/Then/Verify/Assert in the whole body\n if (expectedLines.length === 0) {\n const exp = Array.from(\n body.matchAll(/^\\s*(?:Expected|Then|Verify|Assert)[^\\n]*:?[\\s-]*(.+)$/gim)\n ).map((m) => parseHintedLine(m[1].trim(), 'playwright'));\n expectedLines.push(...exp.map((entry) => entry.text));\n assertionHints.push(...exp.map((entry) => ({ playwright: entry.hint })));\n }\n\n return { steps, stepHints, expected: expectedLines, assertionHints };\n}\n\nfunction extractUrlMetadata(body: string): string | undefined {\n const match = body.match(/<!--\\s*ct:url\\s+(https?:\\/\\/[^\\s>]+)\\s*-->/i);\n return match?.[1];\n}\n\nfunction stripCtMetadata(body: string): string {\n return body.replace(/^\\s*<!--\\s*ct:url\\s+https?:\\/\\/[^\\s>]+\\s*-->\\s*\\n?/im, '');\n}\n\nfunction parseHintedLine(\n value: string,\n hintType: 'selector' | 'playwright',\n): { text: string; hint?: string } {\n const match = value.match(new RegExp(`^(.*?)\\\\s*<!--\\\\s*${hintType}:\\\\s*([\\\\s\\\\S]*?)\\\\s*-->\\\\s*$`, 'i'));\n if (!match) return { text: value.trim() };\n return {\n text: match[1].trim(),\n hint: match[2].trim() || undefined,\n };\n}\n\nfunction extractUrlFromSteps(steps: string[]): string | undefined {\n for (const step of steps) {\n const match = step.match(/https?:\\/\\/[^\\s'\"]+/i);\n if (match) return match[0];\n }\n return undefined;\n}\n\n/** Build one normalized case from a title line + body */\nfunction normalizeOne(titleLine: string, body: string, source: string): NormalizedCase {\n const { clean, tags } = parseTags(titleLine);\n const id = parseId(clean);\n const metadataUrl = extractUrlMetadata(body);\n const cleanBody = stripCtMetadata(body);\n const { steps, stepHints, expected, assertionHints } = extractSections(cleanBody);\n const reviewReasons: string[] = [];\n\n if (steps.length === 0) reviewReasons.push('No steps section or bullets were parsed');\n if (expected.length === 0) reviewReasons.push('No expected results section or assertions were parsed');\n\n return {\n id,\n title: stripIdPrefixFromTitle(clean, id),\n tags: tags.length ? tags : undefined,\n steps,\n step_hints: stepHints.some(hint => hint.selector) ? stepHints : undefined,\n expected,\n assertion_hints: assertionHints.some(hint => hint.playwright) ? assertionHints : undefined,\n needs_review: reviewReasons.length > 0,\n review_reasons: reviewReasons,\n source,\n url: metadataUrl ?? extractUrlFromSteps(steps),\n };\n}\n\n/** ===== Commander command ===== */\nexport function normalizeCmd() {\n const cmd = new Command('normalize')\n .argument('<path>', 'Input directory or file pattern containing test cases (Markdown, Text, CSV)')\n .description('Convert human-readable test cases into machine-readable JSON format')\n .addHelpText('after', `\nExamples:\n $ ct normalize ./cases\n $ ct normalize \"cases/**/*.md\"\n $ ct normalize ./cases --and-gen --lang ts (Normalize and generate tests in one go)\n`)\n .option('--report', 'Generate a summary report of the normalization process', true)\n .option('--and-gen', 'Automatically run test generation after normalization', false)\n .option('--lang <lang>', 'Target language for generation (ts|js) when using --and-gen', 'ts')\n .action(async (inputPath: string, opts: { report?: boolean; andGen?: boolean; lang?: string }) => {\n // Accept directory OR glob\n let patterns: string[] = [];\n try {\n const abs = resolve(inputPath);\n if (statSync(abs).isDirectory()) {\n const base = inputPath.replace(/\\/$/, '');\n patterns = [`${base}/**/*.{md,markdown,txt,feature,csv,json}`];\n } else {\n patterns = [inputPath];\n }\n } catch {\n patterns = [inputPath];\n }\n\n const files = await fg(patterns, { dot: false, onlyFiles: true });\n if (files.length === 0) {\n console.error(`No files found for: ${inputPath}`);\n process.exit(2);\n }\n\n const outDir = '.cementic/normalized';\n mkdirSync(outDir, { recursive: true });\n\n const index = {\n summary: { total: 0, parsed: 0, withWarnings: 0 },\n cases: [] as Array<{ file: string; normalized: string; status: string }>\n };\n\n for (const f of files) {\n const content = readFileSync(f, 'utf8');\n\n // Split into multiple cases by \"# \"\n const blocks = splitCasesByHeading(content);\n for (const block of blocks) {\n const norm = normalizeOne(block.titleLine, block.body, f);\n\n // filename: <stem>.<ID or sanitized-title>.json\n const stem = basename(f).replace(/\\.[^/.]+$/, '');\n const suffix = (norm.id || norm.title).replace(/[^\\w-]+/g, '-');\n const outFile = join(outDir, `${stem}.${suffix}.json`);\n\n writeFileSync(outFile, JSON.stringify(norm, null, 2));\n\n index.summary.total++;\n index.summary.parsed++;\n if (norm.needs_review) index.summary.withWarnings++;\n index.cases.push({ file: f, normalized: outFile, status: norm.needs_review ? 'warning' : 'ok' });\n }\n }\n\n writeFileSync(join(outDir, '_index.json'), JSON.stringify(index, null, 2));\n\n if (opts.report !== false) {\n const lines = [\n '# Normalize Report',\n '',\n `Total cases: ${index.summary.total} | Parsed: ${index.summary.parsed} | With warnings: ${index.summary.withWarnings}`,\n '',\n '| Source File | Normalized JSON | Status |',\n '|-------------|-----------------|--------|',\n ...index.cases.map(c => `| ${c.file} | ${c.normalized} | ${c.status} |`)\n ];\n mkdirSync('.cementic/reports', { recursive: true });\n writeFileSync('.cementic/reports/normalize-report.md', lines.join('\\n'));\n }\n\n console.log(`✅ Normalized ${index.summary.parsed} case(s). Output → .cementic/normalized/`);\n\n if (opts.andGen) {\n const { gen } = await import('./gen.js');\n await gen({ lang: opts.lang || 'ts', out: 'tests/generated' });\n }\n });\n\n return cmd;\n}\n","import { Command } from 'commander';\nimport { spawn } from 'node:child_process';\n\nexport function testCmd() {\n const cmd = new Command('test')\n .description('Run Playwright tests via \"npx playwright test\"')\n .allowUnknownOption(true)\n .allowExcessArguments(true)\n .argument('[...pwArgs]', 'Arguments to pass through to Playwright')\n .action((pwArgs: string[] = []) => {\n const child = spawn(\n 'npx',\n ['playwright', 'test', ...pwArgs],\n {\n stdio: 'inherit',\n shell: process.platform === 'win32', // needed for Windows\n }\n );\n\n child.on('exit', (code) => {\n process.exit(code ?? 0);\n });\n });\n\n return cmd;\n}","import { Command } from 'commander';\nimport { mkdirSync, writeFileSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { createInterface } from 'node:readline/promises';\nimport { stdin as input, stdout as output } from 'node:process';\nimport { inferPrefix } from '../core/prefix.js';\nimport { generateTcMarkdownWithAi } from '../core/llm.js';\nimport { analyseElements } from '../core/analyse.js';\nimport { captureElements, toPageSummary } from '../core/capture.js';\nimport {\n printCaptureReport,\n saveCaptureJson,\n saveCasesMarkdown,\n saveSpecPreview,\n} from '../core/report.js';\n\nfunction slugify(text: string): string {\n return (\n text\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-+|-+$/g, '') || 'tc'\n );\n}\n\nfunction injectUrlMetadata(markdown: string, url?: string): string {\n if (!url || /<!--\\s*ct:url\\s+/i.test(markdown)) return markdown;\n\n const lines = markdown.split('\\n');\n const output: string[] = [];\n\n for (let i = 0; i < lines.length; i++) {\n output.push(lines[i]);\n if (/^\\s*#\\s+/.test(lines[i])) {\n output.push(`<!-- ct:url ${url} -->`);\n }\n }\n\n return output.join('\\n');\n}\n\nfunction buildManualCasesMarkdown(opts: {\n prefix: string;\n feature: string;\n url?: string;\n numCases: number;\n startIndex?: number;\n}): string {\n const { prefix, feature, url, numCases } = opts;\n const startIndex = opts.startIndex ?? 1;\n const lines: string[] = [];\n\n for (let i = 0; i < numCases; i++) {\n const idx = startIndex + i;\n const id = `${prefix}-${String(idx).padStart(3, '0')}`;\n\n lines.push(`# ${id} — ${feature} - scenario ${idx} @regression @ui`);\n if (url) lines.push(`<!-- ct:url ${url} -->`);\n lines.push(`## Steps`);\n lines.push(`1. Navigate to ${url ?? '<PAGE_URL>'}`);\n lines.push(`2. Perform the main user action for this scenario`);\n lines.push(`3. Observe the result`);\n lines.push('');\n lines.push(`## Expected Results`);\n lines.push(`- The page responds correctly for this scenario`);\n lines.push(`- UI reflects the expected change`);\n lines.push('');\n lines.push('');\n }\n\n return lines.join('\\n');\n}\n\nasync function promptBasicQuestions(opts: {\n url?: string;\n feature?: string;\n appDescription?: string;\n numCases?: number;\n}) {\n // Non-interactive mode: all required options were passed as flags\n if (opts.feature) {\n const n = Math.min(Math.max(opts.numCases ?? 3, 1), 10);\n return {\n feature: opts.feature,\n appDescription: opts.appDescription ?? '',\n numCases: n,\n url: opts.url,\n };\n }\n\n // Interactive mode\n const rl = createInterface({ input, output });\n\n const feature = (await rl.question('🧩 Feature or page to test: ')).trim();\n const appDescription = (await rl.question('📝 Short app description (optional): ')).trim();\n const numCasesRaw = (await rl.question('🔢 How many test cases? (1–10) [3]: ')).trim();\n\n rl.close();\n\n let numCases = parseInt(numCasesRaw, 10);\n if (isNaN(numCases) || numCases < 1) numCases = 3;\n if (numCases > 10) numCases = 10;\n\n return { feature, appDescription, numCases, url: opts.url };\n}\n\nasync function runTcInteractive(params: {\n url?: string;\n explicitPrefix?: string;\n feature?: string;\n appDescription?: string;\n numCases?: number;\n useAi: boolean;\n headed?: boolean;\n captureOnly?: boolean;\n}) {\n const { feature, appDescription, numCases, url } = await promptBasicQuestions({\n url: params.url,\n feature: params.feature,\n appDescription: params.appDescription,\n numCases: params.numCases,\n });\n\n const prefix = inferPrefix({\n featureText: feature,\n url,\n explicitPrefix: params.explicitPrefix,\n });\n\n mkdirSync('cases', { recursive: true });\n const fileName = `${prefix.toLowerCase()}-${slugify(feature)}.md`;\n const fullPath = join('cases', fileName);\n\n let markdown: string;\n\n if (params.useAi) {\n let pageSummary = undefined;\n\n if (url) {\n try {\n console.log(`🔍 Capturing page: ${url}`);\n const elementMap = await captureElements(url, {\n headless: !(params.headed ?? false),\n verbose: true,\n });\n printCaptureReport(elementMap);\n\n const jsonPath = saveCaptureJson(elementMap);\n console.log(`📄 Saved capture JSON → ${jsonPath}`);\n\n if (params.captureOnly) {\n console.log('Capture-only mode requested. No test cases were generated.');\n return;\n }\n\n const analysis = await analyseElements(elementMap, { verbose: true });\n printCaptureReport(elementMap, analysis);\n\n const previewPath = saveSpecPreview(analysis);\n if (previewPath) {\n console.log(`🧪 Saved preview spec → ${previewPath}`);\n }\n\n const captureFileName = `${prefix.toLowerCase()}-${slugify(feature)}.md`;\n const generatedPath = saveCasesMarkdown(analysis, 'cases', captureFileName);\n console.log(`✅ Capture-based AI generated test cases → ${generatedPath}`);\n console.log('\\nNext steps:');\n console.log(` ct normalize ${generatedPath} --and-gen --lang ts`);\n console.log(' ct test');\n return;\n } catch (e: any) {\n console.warn(`⚠️ Capture flow failed (${e?.message ?? e}). Falling back to the legacy AI case writer.`);\n if (params.captureOnly) {\n return;\n }\n }\n }\n\n try {\n if (pageSummary === undefined && url) {\n const elementMap = await captureElements(url, {\n headless: true,\n verbose: false,\n });\n pageSummary = toPageSummary(elementMap);\n }\n\n markdown = await generateTcMarkdownWithAi({\n appDescription: appDescription || undefined,\n feature,\n url,\n pageSummary,\n prefix,\n startIndex: 1,\n numCases,\n });\n markdown = injectUrlMetadata(markdown, url);\n console.log('✅ AI generated test cases.');\n } catch (err: any) {\n console.warn(`⚠️ AI generation failed (${err?.message ?? err}). Falling back to manual templates.`);\n markdown = buildManualCasesMarkdown({ prefix, feature, url, numCases, startIndex: 1 });\n console.log('📝 Generated manual test case templates instead.');\n }\n } else {\n markdown = buildManualCasesMarkdown({ prefix, feature, url, numCases, startIndex: 1 });\n console.log('📝 Generated manual test case templates (pass --ai to use AI).');\n }\n\n writeFileSync(fullPath, markdown);\n\n console.log(`\\n✍️ Wrote ${numCases} case(s) → ${fullPath}`);\n console.log('\\nNext steps:');\n console.log(' ct normalize ./cases --and-gen --lang ts');\n console.log(' ct test');\n}\n\n// ─── Shared options factory ───────────────────────────────────────────────────\n\nfunction addSharedOptions(cmd: Command): Command {\n return cmd\n .option('--ai', 'Use AI to generate test cases (requires API key)')\n .option('--prefix <prefix>', 'Explicit ID prefix, e.g. AUTH, DASH, CART')\n .option('--feature <name>', 'Feature name — skips interactive prompt')\n .option('--desc <text>', 'App description — skips interactive prompt')\n .option('--count <n>', 'Number of cases (1–10)', parseInt);\n}\n\nfunction resolveCommanderOpts<T extends Record<string, unknown>>(opts: T | Command): T {\n if (typeof (opts as Command).optsWithGlobals === 'function') {\n return (opts as Command).optsWithGlobals<T>();\n }\n if (typeof (opts as Command).opts === 'function') {\n return (opts as Command).opts<T>();\n }\n return opts as T;\n}\n\n// ─── Command definition ───────────────────────────────────────────────────────\n\nexport function tcCmd() {\n const root = new Command('tc')\n .description('Create CementicTest case files (Markdown) under ./cases')\n .addHelpText('after', `\nExamples:\n $ ct tc --feature \"Login form\" --ai\n $ ct tc --feature \"Checkout\" --count 5 --prefix CHK\n $ ct tc url https://example.com/login --ai --feature \"Auth\"\n`);\n\n addSharedOptions(root).action(\n async (opts: { ai?: boolean; prefix?: string; feature?: string; desc?: string; count?: number } | Command) => {\n const resolvedOpts = resolveCommanderOpts<{ ai?: boolean; prefix?: string; feature?: string; desc?: string; count?: number }>(opts);\n await runTcInteractive({\n url: undefined,\n explicitPrefix: resolvedOpts.prefix,\n feature: resolvedOpts.feature,\n appDescription: resolvedOpts.desc,\n numCases: resolvedOpts.count,\n useAi: resolvedOpts.ai ?? false,\n });\n }\n );\n\n addSharedOptions(\n root\n .command('url')\n .argument('<url>', 'Page URL to use as live capture and AI context')\n .description('Generate test cases with capture-aware context from a specific live page')\n .option('--headed', 'Show the browser while capturing the page')\n .option('--capture-only', 'Run live page capture and save artifacts without generating cases')\n ).action(\n async (\n url: string,\n opts: { ai?: boolean; prefix?: string; feature?: string; desc?: string; count?: number; headed?: boolean; captureOnly?: boolean } | Command,\n command?: Command,\n ) => {\n const resolvedOpts = resolveCommanderOpts<{ ai?: boolean; prefix?: string; feature?: string; desc?: string; count?: number; headed?: boolean; captureOnly?: boolean }>(command ?? opts);\n await runTcInteractive({\n url,\n explicitPrefix: resolvedOpts.prefix,\n feature: resolvedOpts.feature,\n appDescription: resolvedOpts.desc,\n numCases: resolvedOpts.count,\n useAi: resolvedOpts.ai ?? false,\n headed: resolvedOpts.headed ?? false,\n captureOnly: resolvedOpts.captureOnly ?? false,\n });\n }\n );\n\n return root;\n}\n","// src/core/prefix.ts\n\nconst PREFIX_MAP: Array<{ keywords: string[]; prefix: string }> = [\n { keywords: ['login', 'sign in', 'signin', 'auth', 'authentication'], prefix: 'AUTH' },\n { keywords: ['dashboard', 'home'], prefix: 'DASH' },\n { keywords: ['profile', 'account'], prefix: 'PROF' },\n { keywords: ['cart', 'basket'], prefix: 'CART' },\n { keywords: ['checkout', 'payment', 'pay'], prefix: 'CHK' },\n { keywords: ['order', 'orders'], prefix: 'ORD' },\n { keywords: ['settings', 'preferences', 'config'], prefix: 'SET' },\n];\n\nfunction normalizeText(text: string): string {\n return text.toLowerCase().trim();\n}\n\nfunction deriveFromFreeText(text: string): string | undefined {\n const norm = normalizeText(text);\n for (const entry of PREFIX_MAP) {\n if (entry.keywords.some(k => norm.includes(k))) {\n return entry.prefix;\n }\n }\n // fallback: first word, first 4 alphanumerics\n const firstWord = norm.split(/\\s+/).find(w => /[a-z0-9]/.test(w));\n if (!firstWord) return undefined;\n return firstWord.replace(/[^a-z0-9]/gi, '').slice(0, 4).toUpperCase() || undefined;\n}\n\nfunction deriveFromUrl(url: string): string | undefined {\n try {\n const u = new URL(url);\n const segments = u.pathname.split('/').filter(Boolean);\n const last = segments[segments.length - 1] || '';\n if (!last) return undefined;\n return deriveFromFreeText(last);\n } catch {\n return undefined;\n }\n}\n\nexport function inferPrefix(params: {\n featureText?: string;\n url?: string;\n explicitPrefix?: string;\n}): string {\n // 1) explicit flag wins\n if (params.explicitPrefix) {\n return params.explicitPrefix.trim().toUpperCase();\n }\n\n // 2) feature text\n if (params.featureText) {\n const fromFeature = deriveFromFreeText(params.featureText);\n if (fromFeature) return fromFeature;\n }\n\n // 3) url\n if (params.url) {\n const fromUrl = deriveFromUrl(params.url);\n if (fromUrl) return fromUrl;\n }\n\n // 4) last-resort default\n return 'TC';\n}","import type { PageSummary } from './capture.js';\n\nexport type TcAiContext = {\n appDescription?: string;\n feature: string;\n url?: string;\n pageSummary?: PageSummary;\n prefix: string;\n startIndex: number;\n numCases: number;\n};\n\n// ─── Prompt builders ──────────────────────────────────────────────────────────\n\nfunction buildSystemMessage(): string {\n return `\nYou are a senior QA engineer and test automation specialist.\n\nYour job:\n- Receive context about a web feature or page\n- Generate high-quality, realistic UI test cases\n- Format them in strict Markdown that a downstream parser will process\n\nYou MUST follow this format exactly for each test case:\n\n# <ID> — <Short title> @<tag1> @<tag2>\n## Steps\n1. <user action>\n2. <user action>\n\n## Expected Results\n- <verifiable outcome>\n- <verifiable outcome>\n\nRules:\n- ID must be PREFIX-NNN where NNN is zero-padded 3 digits starting from startIndex\n- Use 1–3 tags: @smoke @regression @auth @ui @critical @happy-path @negative\n- Steps = concrete user actions (\"Click the 'Sign In' button\", \"Fill in email with 'user@example.com'\")\n- Expected Results = verifiable UI outcomes (\"Error message 'Invalid credentials' is visible\", \"Page redirects to /dashboard\")\n- Include both happy-path AND negative/edge-case tests\n- Do NOT explain or add preamble — output ONLY the test cases\n- No code blocks, no extra headings outside the pattern\n`.trim();\n}\n\nfunction buildUserMessage(ctx: TcAiContext): string {\n const lines: string[] = [];\n\n lines.push(`App / product description:`);\n lines.push(ctx.appDescription || 'N/A');\n lines.push('');\n\n lines.push(`Feature or page to test:`);\n lines.push(ctx.feature);\n lines.push('');\n\n if (ctx.url) {\n lines.push(`Page URL: ${ctx.url}`);\n lines.push('');\n }\n\n if (ctx.pageSummary) {\n const s = ctx.pageSummary;\n lines.push(`Live page analysis:`);\n\n if (s.title) lines.push(`- Page title: ${s.title}`);\n\n if (s.headings.length) {\n lines.push(`- Headings: ${s.headings.join(' | ')}`);\n }\n\n if (s.inputs.length) {\n const inputDescs = s.inputs.map(i => {\n const parts = [\n i.label && `label=\"${i.label}\"`,\n i.placeholder && `placeholder=\"${i.placeholder}\"`,\n i.name && `name=\"${i.name}\"`,\n i.type && i.type !== 'text' && `type=\"${i.type}\"`,\n i.testId && `data-testid=\"${i.testId}\"`,\n ].filter(Boolean);\n return parts.join(', ');\n });\n lines.push(`- Form inputs: ${inputDescs.join(' | ')}`);\n }\n\n if (s.buttons.length) {\n lines.push(`- Buttons: ${s.buttons.join(' | ')}`);\n }\n\n if (s.links.length) {\n lines.push(`- Links: ${s.links.slice(0, 20).join(' | ')}`);\n }\n\n lines.push('');\n }\n\n lines.push(`Test ID prefix: ${ctx.prefix}`);\n lines.push(`Start numbering from: ${String(ctx.startIndex).padStart(3, '0')}`);\n lines.push(`Number of test cases: ${ctx.numCases}`);\n lines.push('');\n lines.push(`Include a mix of: happy-path flows, validation/error cases, and edge cases.`);\n lines.push(`Output ONLY the test cases. No explanation, no preamble.`);\n\n return lines.join('\\n');\n}\n\n// ─── Provider detection ───────────────────────────────────────────────────────\n\ntype Provider = 'anthropic' | 'openai';\n\nfunction detectProvider(): {\n provider: Provider;\n apiKey: string;\n model: string;\n baseUrl: string;\n} {\n // Anthropic — first-class support\n const anthropicKey =\n process.env.ANTHROPIC_API_KEY ??\n process.env.CT_ANTHROPIC_API_KEY ??\n '';\n\n // OpenAI-compatible fallback\n const openaiKey =\n process.env.CT_LLM_API_KEY ??\n process.env.OPENAI_API_KEY ??\n '';\n\n // Explicit provider override\n const explicitProvider = (process.env.CT_LLM_PROVIDER ?? '').toLowerCase();\n\n if (explicitProvider === 'anthropic' || (anthropicKey && explicitProvider !== 'openai')) {\n if (!anthropicKey) {\n throw new Error(\n 'CT_LLM_PROVIDER=anthropic but no ANTHROPIC_API_KEY found.\\n' +\n 'Set ANTHROPIC_API_KEY=your-key or switch to OPENAI_API_KEY.'\n );\n }\n return {\n provider: 'anthropic',\n apiKey: anthropicKey,\n model: process.env.CT_LLM_MODEL ?? 'claude-sonnet-4-5',\n baseUrl: 'https://api.anthropic.com',\n };\n }\n\n if (openaiKey) {\n return {\n provider: 'openai',\n apiKey: openaiKey,\n model: process.env.CT_LLM_MODEL ?? 'gpt-4o-mini',\n baseUrl: process.env.CT_LLM_BASE_URL ?? 'https://api.openai.com/v1',\n };\n }\n\n throw new Error(\n 'No LLM API key found.\\n' +\n ' For Claude: export ANTHROPIC_API_KEY=your-key\\n' +\n ' For OpenAI: export OPENAI_API_KEY=your-key\\n' +\n ' Any OpenAI-compatible endpoint: set CT_LLM_API_KEY + CT_LLM_BASE_URL'\n );\n}\n\n// ─── Anthropic call ───────────────────────────────────────────────────────────\n\nasync function callAnthropic(\n apiKey: string,\n model: string,\n system: string,\n user: string\n): Promise<string> {\n const response = await fetch('https://api.anthropic.com/v1/messages', {\n method: 'POST',\n headers: {\n 'x-api-key': apiKey,\n 'anthropic-version': '2023-06-01',\n 'content-type': 'application/json',\n },\n body: JSON.stringify({\n model,\n max_tokens: 4096,\n system,\n messages: [{ role: 'user', content: user }],\n }),\n });\n\n if (!response.ok) {\n const text = await response.text();\n throw new Error(`Anthropic API error ${response.status}: ${text}`);\n }\n\n const json: any = await response.json();\n const content = json.content?.[0]?.text?.trim() ?? '';\n if (!content) throw new Error('Anthropic response had no content');\n return content;\n}\n\n// ─── OpenAI-compatible call ───────────────────────────────────────────────────\n\nasync function callOpenAi(\n apiKey: string,\n model: string,\n baseUrl: string,\n system: string,\n user: string\n): Promise<string> {\n const response = await fetch(`${baseUrl}/chat/completions`, {\n method: 'POST',\n headers: {\n Authorization: `Bearer ${apiKey}`,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n model,\n temperature: 0.2,\n messages: [\n { role: 'system', content: system },\n { role: 'user', content: user },\n ],\n }),\n });\n\n if (!response.ok) {\n const text = await response.text();\n throw new Error(`OpenAI API error ${response.status}: ${text}`);\n }\n\n const json: any = await response.json();\n const content = json.choices?.[0]?.message?.content?.trim() ?? '';\n if (!content) throw new Error('OpenAI response had no content');\n return content;\n}\n\n// ─── Public API ───────────────────────────────────────────────────────────────\n\nexport async function generateTcMarkdownWithAi(ctx: TcAiContext): Promise<string> {\n const { provider, apiKey, model, baseUrl } = detectProvider();\n\n const system = buildSystemMessage();\n const user = buildUserMessage(ctx);\n\n console.log(`🤖 Using ${provider === 'anthropic' ? 'Claude' : 'OpenAI-compatible'} (${model})`);\n\n if (provider === 'anthropic') {\n return callAnthropic(apiKey, model, system, user);\n }\n return callOpenAi(apiKey, model, baseUrl, system, user);\n}\n","import type { ElementMap } from './capture.js';\n\ntype ProviderName = 'deepseek' | 'anthropic' | 'gemini' | 'qwen' | 'kimi' | 'openai';\n\ntype ProviderConfig = {\n provider: ProviderName;\n displayName: string;\n apiKey: string;\n model: string;\n baseUrl?: string;\n};\n\nexport type AnalysisStep = {\n action: 'navigate' | 'fill' | 'click' | 'select' | 'check' | 'keyboard' | 'hover';\n selector: string;\n value: string;\n human: string;\n};\n\nexport type AnalysisAssertion = {\n type: string;\n selector: string;\n expected: string;\n human: string;\n playwright: string;\n};\n\nexport type AnalysisScenario = {\n id: string;\n title: string;\n tags: string[];\n steps: AnalysisStep[];\n assertions: AnalysisAssertion[];\n narrator: string;\n codeLevel: 'beginner' | 'intermediate' | 'advanced';\n};\n\nexport type AnalysisResult = {\n url: string;\n feature: string;\n suggestedPrefix: string;\n scenarios: AnalysisScenario[];\n analysisNotes?: string;\n audioSummary?: string;\n};\n\nexport async function analyseElements(\n elementMap: ElementMap,\n options: { verbose?: boolean } = {},\n): Promise<AnalysisResult> {\n const { verbose = false } = options;\n const { provider, displayName, apiKey, model, baseUrl } = detectProvider();\n\n log(verbose, `\\n[analyse] Sending capture to ${displayName} (${model})`);\n\n const systemPrompt = buildSystemPrompt();\n const userPrompt = buildUserPrompt(elementMap);\n\n const rawResponse = provider === 'anthropic'\n ? await callAnthropic(apiKey, model, systemPrompt, userPrompt)\n : await callOpenAi(apiKey, model, baseUrl ?? 'https://api.openai.com/v1', systemPrompt, userPrompt);\n\n const parsed = parseAnalysisJson(rawResponse);\n return sanitizeAnalysis(parsed, elementMap);\n}\n\nfunction detectProvider(): ProviderConfig {\n const explicitProvider = (process.env.CT_LLM_PROVIDER ?? '').toLowerCase();\n\n const providers: Record<ProviderName, ProviderConfig> = {\n deepseek: {\n provider: 'deepseek',\n displayName: 'DeepSeek',\n apiKey: process.env.DEEPSEEK_API_KEY ?? process.env.CT_DEEPSEEK_API_KEY ?? '',\n model: process.env.CT_LLM_MODEL ?? process.env.DEEPSEEK_MODEL ?? 'deepseek-chat',\n baseUrl: process.env.DEEPSEEK_BASE_URL ?? 'https://api.deepseek.com/v1',\n },\n anthropic: {\n provider: 'anthropic',\n displayName: 'Claude',\n apiKey: process.env.ANTHROPIC_API_KEY ?? process.env.CT_ANTHROPIC_API_KEY ?? '',\n model: process.env.CT_LLM_MODEL ?? process.env.ANTHROPIC_MODEL ?? 'claude-sonnet-4-5',\n },\n gemini: {\n provider: 'gemini',\n displayName: 'Gemini',\n apiKey: process.env.GEMINI_API_KEY ?? process.env.GOOGLE_API_KEY ?? '',\n model: process.env.CT_LLM_MODEL ?? process.env.GEMINI_MODEL ?? 'gemini-2.5-flash',\n baseUrl: process.env.GEMINI_BASE_URL ?? 'https://generativelanguage.googleapis.com/v1beta/openai',\n },\n qwen: {\n provider: 'qwen',\n displayName: 'Qwen',\n apiKey: process.env.QWEN_API_KEY ?? '',\n model: process.env.CT_LLM_MODEL ?? process.env.QWEN_MODEL ?? 'qwen-plus',\n baseUrl: process.env.QWEN_BASE_URL ?? 'https://dashscope-intl.aliyuncs.com/compatible-mode/v1',\n },\n kimi: {\n provider: 'kimi',\n displayName: 'Kimi',\n apiKey: process.env.KIMI_API_KEY ?? process.env.MOONSHOT_API_KEY ?? '',\n model: process.env.CT_LLM_MODEL ?? process.env.KIMI_MODEL ?? 'moonshot-v1-8k',\n baseUrl: process.env.KIMI_BASE_URL ?? 'https://api.moonshot.ai/v1',\n },\n openai: {\n provider: 'openai',\n displayName: 'OpenAI-compatible',\n apiKey: process.env.OPENAI_API_KEY ?? process.env.CT_LLM_API_KEY ?? '',\n model: process.env.CT_LLM_MODEL ?? process.env.OPENAI_MODEL ?? 'gpt-4o-mini',\n baseUrl: process.env.CT_LLM_BASE_URL ?? 'https://api.openai.com/v1',\n },\n };\n\n if (explicitProvider) {\n if (!(explicitProvider in providers)) {\n throw new Error(`Unsupported CT_LLM_PROVIDER=\"${explicitProvider}\". Use deepseek, anthropic, gemini, qwen, kimi, or openai.`);\n }\n\n const selected = providers[explicitProvider as ProviderName];\n if (!selected.apiKey) {\n throw new Error(`CT_LLM_PROVIDER=${explicitProvider} is set but the matching API key is missing.`);\n }\n return selected;\n }\n\n for (const providerName of ['deepseek', 'anthropic', 'gemini', 'qwen', 'kimi', 'openai'] as const) {\n if (providers[providerName].apiKey) return providers[providerName];\n }\n\n throw new Error(\n 'No LLM API key found.\\n' +\n ' DeepSeek: export DEEPSEEK_API_KEY=your-key\\n' +\n ' Anthropic: export ANTHROPIC_API_KEY=your-key\\n' +\n ' Gemini: export GEMINI_API_KEY=your-key\\n' +\n ' Qwen: export QWEN_API_KEY=your-key\\n' +\n ' Kimi: export KIMI_API_KEY=your-key\\n' +\n ' OpenAI: export OPENAI_API_KEY=your-key'\n );\n}\n\nfunction buildSystemPrompt(): string {\n return `\nYou are a senior QA automation engineer and Playwright expert working on CementicTest.\n\nYour job is to analyse a structured map of interactive elements extracted from a live web page,\nthen produce a complete set of Playwright test scenarios.\n\nRULES:\n1. Use only selectors provided in the ElementMap.\n2. Every assertion must include an exact \"playwright\" field with a complete await expect(...) statement.\n3. Use clearly fake data like user@example.com.\n4. Include both happy-path and negative scenarios, but stay evidence-backed.\n5. Output only valid JSON matching the requested schema.\n6. Do not invent redirect targets, success pages, error text, password clearing, or security scenarios unless the capture explicitly supports them.\n7. If no status or alert region was captured, avoid scenarios that depend on unseen server-side validation messages.\n8. Prefer 3 to 5 realistic scenarios.\n\nOUTPUT SCHEMA:\n{\n \"url\": string,\n \"feature\": string,\n \"suggestedPrefix\": string,\n \"scenarios\": [\n {\n \"id\": string,\n \"title\": string,\n \"tags\": string[],\n \"steps\": [\n {\n \"action\": \"navigate\"|\"fill\"|\"click\"|\"select\"|\"check\"|\"keyboard\"|\"hover\",\n \"selector\": string,\n \"value\": string,\n \"human\": string\n }\n ],\n \"assertions\": [\n {\n \"type\": string,\n \"selector\": string,\n \"expected\": string,\n \"human\": string,\n \"playwright\": string\n }\n ],\n \"narrator\": string,\n \"codeLevel\": \"beginner\"|\"intermediate\"|\"advanced\"\n }\n ],\n \"analysisNotes\": string,\n \"audioSummary\": string\n}`.trim();\n}\n\nfunction buildUserPrompt(elementMap: ElementMap): string {\n const lines: string[] = [];\n\n lines.push('PAGE INFORMATION');\n lines.push(`URL: ${elementMap.url}`);\n lines.push(`Title: ${elementMap.title}`);\n lines.push(`Captured in: ${elementMap.mode} mode`);\n lines.push('');\n\n for (const category of ['input', 'button', 'link', 'heading', 'status'] as const) {\n const items = elementMap.elements.filter((element) => element.category === category);\n if (items.length === 0) continue;\n\n lines.push(`${category.toUpperCase()}S (${items.length} found):`);\n for (const item of items.slice(0, category === 'link' ? 10 : items.length)) {\n lines.push(` - [${item.confidence}] ${item.selector}`);\n lines.push(` Purpose: ${item.purpose}`);\n if (item.selectorAlt.length > 0) {\n lines.push(` Fallbacks: ${item.selectorAlt.slice(0, 2).join(' | ')}`);\n }\n }\n lines.push('');\n }\n\n if (elementMap.warnings.length > 0) {\n lines.push('CAPTURE WARNINGS:');\n for (const warning of elementMap.warnings) {\n lines.push(` - ${warning}`);\n }\n lines.push('');\n }\n\n const interactiveCount = elementMap.elements.filter((element) => (\n element.category === 'input' || element.category === 'button' || element.category === 'link'\n )).length;\n const statusCount = elementMap.elements.filter((element) => element.category === 'status').length;\n\n lines.push('EVIDENCE CONSTRAINTS:');\n lines.push(` - Interactive elements captured: ${interactiveCount}`);\n lines.push(` - Status or alert regions captured: ${statusCount}`);\n lines.push(' - If no redirect target is explicitly captured, do not assert a destination path.');\n lines.push(' - If no status region was captured, avoid exact server-side credential error claims.');\n lines.push('');\n lines.push('Generate only the JSON response.');\n\n return lines.join('\\n');\n}\n\nasync function callAnthropic(\n apiKey: string,\n model: string,\n systemPrompt: string,\n userPrompt: string,\n): Promise<string> {\n const response = await fetch('https://api.anthropic.com/v1/messages', {\n method: 'POST',\n headers: {\n 'x-api-key': apiKey,\n 'anthropic-version': '2023-06-01',\n 'content-type': 'application/json',\n },\n body: JSON.stringify({\n model,\n max_tokens: 4096,\n system: systemPrompt,\n messages: [{ role: 'user', content: userPrompt }],\n }),\n });\n\n if (!response.ok) {\n throw new Error(`Anthropic API ${response.status}: ${await response.text()}`);\n }\n\n const json: any = await response.json();\n const content = json.content?.[0]?.text?.trim() ?? '';\n if (!content) throw new Error('Anthropic returned empty content');\n return content;\n}\n\nasync function callOpenAi(\n apiKey: string,\n model: string,\n baseUrl: string,\n systemPrompt: string,\n userPrompt: string,\n): Promise<string> {\n const response = await fetch(`${baseUrl}/chat/completions`, {\n method: 'POST',\n headers: {\n Authorization: `Bearer ${apiKey}`,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n model,\n temperature: 0.1,\n messages: [\n { role: 'system', content: systemPrompt },\n { role: 'user', content: userPrompt },\n ],\n }),\n });\n\n if (!response.ok) {\n throw new Error(`OpenAI API ${response.status}: ${await response.text()}`);\n }\n\n const json: any = await response.json();\n const content = json.choices?.[0]?.message?.content?.trim() ?? '';\n if (!content) throw new Error('OpenAI-compatible provider returned empty content');\n return content;\n}\n\nfunction parseAnalysisJson(raw: string): AnalysisResult {\n const stripped = raw\n .replace(/^```(?:json)?\\s*/m, '')\n .replace(/\\s*```\\s*$/m, '')\n .trim();\n\n try {\n return JSON.parse(stripped);\n } catch (error: any) {\n throw new Error(\n `Failed to parse LLM response as JSON.\\nParse error: ${error?.message ?? error}\\nRaw response:\\n${raw.slice(0, 500)}`\n );\n }\n}\n\nfunction sanitizeAnalysis(analysis: AnalysisResult, elementMap: ElementMap): AnalysisResult {\n const selectors = new Set(elementMap.elements.map((element) => element.selector));\n const rawScenarios = Array.isArray(analysis.scenarios) ? analysis.scenarios : [];\n const currentUrl = new URL(elementMap.url);\n const knownPaths = new Set([\n currentUrl.pathname,\n ...elementMap.elements\n .filter((element) => element.category === 'link')\n .map((element) => {\n const href = element.attributes?.href;\n if (typeof href !== 'string') return '';\n try {\n return new URL(href, elementMap.url).pathname;\n } catch {\n return href;\n }\n })\n .filter(Boolean),\n ]);\n\n const sanitizedScenarios = rawScenarios\n .map((scenario) => normalizeScenario(scenario, selectors))\n .filter((scenario) => scenario.steps.length > 0 && scenario.assertions.length > 0)\n .map((scenario) => ({\n ...scenario,\n tags: scenario.tags.map(normalizeTag),\n assertions: scenario.assertions.filter((assertion) => {\n if (assertion.type !== 'url') return true;\n const combined = `${assertion.expected} ${assertion.human} ${assertion.playwright}`;\n const pathMatch = combined.match(/\\/[a-z0-9/_-]+/i);\n if (!pathMatch) return true;\n return knownPaths.has(pathMatch[0]);\n }),\n }))\n .filter((scenario) => scenario.assertions.length > 0)\n .slice(0, 5);\n\n const finalScenarios = sanitizedScenarios.length > 0\n ? sanitizedScenarios\n : buildFallbackScenarios(elementMap, analysis.suggestedPrefix || 'FLOW');\n\n return {\n ...analysis,\n url: analysis.url || elementMap.url,\n feature: analysis.feature || inferFeatureName(elementMap),\n suggestedPrefix: (analysis.suggestedPrefix || inferPrefix(elementMap)).toUpperCase(),\n scenarios: finalScenarios,\n analysisNotes: [\n analysis.analysisNotes,\n `Sanitized to ${finalScenarios.length} evidence-backed scenario(s) from ${rawScenarios.length} raw scenario(s).`,\n ].filter(Boolean).join(' '),\n audioSummary: analysis.audioSummary || buildAudioSummary(analysis.feature || inferFeatureName(elementMap), finalScenarios),\n };\n}\n\nfunction normalizeScenario(candidate: any, selectors: Set<string>): AnalysisScenario {\n return {\n id: candidate?.id ?? 'FLOW-001',\n title: candidate?.title ?? 'Captured page flow',\n tags: Array.isArray(candidate?.tags) ? candidate.tags : [],\n steps: Array.isArray(candidate?.steps)\n ? candidate.steps.filter((step: any) => step?.selector === 'page' || selectors.has(step?.selector))\n : [],\n assertions: Array.isArray(candidate?.assertions)\n ? candidate.assertions.filter((assertion: any) => assertion?.selector === 'page' || selectors.has(assertion?.selector))\n : [],\n narrator: candidate?.narrator ?? 'Let us run this captured test flow.',\n codeLevel: candidate?.codeLevel ?? 'beginner',\n };\n}\n\nfunction buildFallbackScenarios(elementMap: ElementMap, prefix: string): AnalysisScenario[] {\n const heading = elementMap.elements.find((element) => element.category === 'heading');\n const emailInput = elementMap.elements.find((element) => (\n element.category === 'input' &&\n (element.attributes.type === 'email' || /email/.test(`${element.name ?? ''} ${String(element.attributes.label ?? '')}`.toLowerCase()))\n ));\n const passwordInput = elementMap.elements.find((element) => (\n element.category === 'input' && element.attributes.type === 'password'\n ));\n const submitButton = elementMap.elements.find((element) => (\n element.category === 'button' && /login|sign in|submit|continue/i.test(element.name ?? '')\n )) ?? elementMap.elements.find((element) => element.category === 'button');\n\n const scenarios: AnalysisScenario[] = [];\n const tag = (value: string) => normalizeTag(value);\n const nextId = (index: number) => `${prefix}-${String(900 + index).padStart(3, '0')}`;\n\n if (heading) {\n scenarios.push({\n id: nextId(scenarios.length + 1),\n title: 'Page loads with expected heading',\n tags: [tag('smoke'), tag('page-load')],\n steps: [\n {\n action: 'navigate',\n selector: 'page',\n value: elementMap.url,\n human: 'Navigate to the captured page',\n },\n ],\n assertions: [\n {\n type: 'visible',\n selector: heading.selector,\n expected: 'visible',\n human: `${heading.name || 'Primary heading'} is visible`,\n playwright: `await expect(page.${heading.selector}).toBeVisible();`,\n },\n ],\n narrator: 'We will first confirm that the expected page heading is visible.',\n codeLevel: 'beginner',\n });\n }\n\n if (emailInput && passwordInput && submitButton) {\n scenarios.push({\n id: nextId(scenarios.length + 1),\n title: 'Submitting without a password keeps the user on the form',\n tags: [tag('validation'), tag('negative')],\n steps: [\n {\n action: 'navigate',\n selector: 'page',\n value: elementMap.url,\n human: 'Navigate to the captured page',\n },\n {\n action: 'fill',\n selector: emailInput.selector,\n value: 'user@example.com',\n human: 'Fill in the email field',\n },\n {\n action: 'click',\n selector: submitButton.selector,\n value: '',\n human: 'Click the submit button',\n },\n ],\n assertions: [\n {\n type: 'url',\n selector: 'page',\n expected: new URL(elementMap.url).pathname,\n human: 'User remains on the same page',\n playwright: `await expect(page).toHaveURL('${elementMap.url}');`,\n },\n {\n type: 'visible',\n selector: passwordInput.selector,\n expected: 'visible',\n human: 'Password field stays visible for correction',\n playwright: `await expect(page.${passwordInput.selector}).toBeVisible();`,\n },\n ],\n narrator: 'Next we will leave the password blank and confirm the form does not advance.',\n codeLevel: 'beginner',\n });\n }\n\n return scenarios.slice(0, 5);\n}\n\nfunction inferFeatureName(elementMap: ElementMap): string {\n const heading = elementMap.elements.find((element) => element.category === 'heading' && element.name);\n return heading?.name || elementMap.title || 'Captured page';\n}\n\nfunction inferPrefix(elementMap: ElementMap): string {\n const source = `${elementMap.title} ${elementMap.url}`.toLowerCase();\n if (/\\blogin|sign in|auth/.test(source)) return 'AUTH';\n if (/\\bcheckout|cart|payment/.test(source)) return 'CHK';\n if (/\\bdashboard/.test(source)) return 'DASH';\n return 'FLOW';\n}\n\nfunction buildAudioSummary(feature: string, scenarios: AnalysisScenario[]): string {\n return `We finished validating ${feature || 'the captured page'} with ${scenarios.length} evidence-backed scenario${scenarios.length === 1 ? '' : 's'}.`;\n}\n\nfunction normalizeTag(value: string): string {\n const cleaned = String(value ?? '').trim().replace(/^@+/, '');\n return cleaned ? `@${cleaned}` : '@ui';\n}\n\nfunction log(verbose: boolean, message: string): void {\n if (verbose) console.log(message);\n}\n","export type InputDescriptor = {\n label?: string;\n placeholder?: string;\n name?: string;\n type?: string;\n testId?: string;\n};\n\nexport type PageSummary = {\n url: string;\n title?: string;\n headings: string[];\n buttons: string[];\n links: string[];\n inputs: InputDescriptor[];\n landmarks: string[];\n rawLength: number;\n};\n\nexport type CaptureMode = 'headless' | 'headed';\nexport type CaptureConfidence = 'high' | 'medium' | 'low';\nexport type CaptureCategory = 'input' | 'button' | 'link' | 'heading' | 'status';\n\nexport type CapturedElement = {\n category: CaptureCategory;\n role: string;\n name?: string;\n selector: string;\n selectorAlt: string[];\n purpose: string;\n confidence: CaptureConfidence;\n attributes: Record<string, unknown>;\n};\n\nexport type ElementMap = {\n url: string;\n title: string;\n timestamp: string;\n mode: CaptureMode;\n summary: {\n totalElements: number;\n byCategory: Partial<Record<CaptureCategory, number>>;\n };\n elements: CapturedElement[];\n warnings: string[];\n};\n\ntype CaptureOptions = {\n headless?: boolean;\n timeoutMs?: number;\n verbose?: boolean;\n userAgent?: string;\n};\n\ntype DomButton = {\n tag: string;\n text?: string;\n testId?: string;\n id?: string;\n type?: string;\n disabled: boolean;\n selector?: string | null;\n cssPath?: string | null;\n};\n\ntype DomInput = {\n tag: string;\n type: string;\n label?: string;\n placeholder?: string;\n name?: string;\n id?: string;\n testId?: string;\n required: boolean;\n selector?: string | null;\n cssPath?: string | null;\n};\n\ntype DomLink = {\n text: string;\n href?: string;\n testId?: string;\n external: boolean;\n selector: string;\n};\n\ntype DomHeading = {\n level: string;\n text: string;\n selector: string;\n};\n\ntype DomStatusRegion = {\n role: string;\n ariaLive?: string;\n text?: string;\n selector: string;\n};\n\ntype DomForm = {\n id?: string;\n label?: string;\n action?: string;\n method: string;\n fieldCount: number;\n index: number;\n};\n\ntype DomData = {\n buttons: DomButton[];\n inputs: DomInput[];\n links: DomLink[];\n headings: DomHeading[];\n landmarks: Array<{ role: string; label: string }>;\n statusRegions: DomStatusRegion[];\n forms: DomForm[];\n pageUrl: string;\n pageTitle: string;\n};\n\nconst SETTLE_MS = 1200;\nconst DEFAULT_TIMEOUT_MS = 30_000;\nconst MAX_PER_CATEGORY = 50;\n\nexport async function captureElements(url: string, options: CaptureOptions = {}): Promise<ElementMap> {\n const {\n headless = true,\n timeoutMs = DEFAULT_TIMEOUT_MS,\n verbose = false,\n userAgent = 'Mozilla/5.0 (compatible; CementicTest/0.2.5 capture)',\n } = options;\n\n const chromium = await loadChromium();\n const mode: CaptureMode = headless ? 'headless' : 'headed';\n log(verbose, `\\n[capture] Starting ${mode} capture: ${url}`);\n\n const browser = await chromium.launch({\n headless,\n slowMo: headless ? 0 : 150,\n });\n\n const context = await browser.newContext({\n userAgent,\n viewport: { width: 1280, height: 800 },\n ignoreHTTPSErrors: true,\n });\n\n const page = await context.newPage();\n\n try {\n log(verbose, ` -> Navigating (timeout: ${timeoutMs}ms)`);\n await page.goto(url, {\n waitUntil: 'domcontentloaded',\n timeout: timeoutMs,\n });\n\n log(verbose, ` -> Waiting ${SETTLE_MS}ms for page settle`);\n await page.waitForTimeout(SETTLE_MS);\n\n log(verbose, ' -> Extracting accessibility snapshot');\n const a11ySnapshot = await getAccessibilitySnapshot(page, verbose);\n\n log(verbose, ' -> Extracting DOM data');\n const domData = await page.evaluate(extractDomData);\n\n const title = await page.title();\n const finalUrl = page.url();\n const elements = buildElementMap(domData);\n const warnings = buildWarnings(elements, domData, a11ySnapshot);\n const byCategory: Partial<Record<CaptureCategory, number>> = {};\n\n for (const element of elements) {\n byCategory[element.category] = (byCategory[element.category] ?? 0) + 1;\n }\n\n const result: ElementMap = {\n url: finalUrl,\n title,\n timestamp: new Date().toISOString(),\n mode,\n summary: {\n totalElements: elements.length,\n byCategory,\n },\n elements,\n warnings,\n };\n\n log(verbose, ` -> Captured ${elements.length} testable elements from \"${title}\"`);\n return result;\n } finally {\n await browser.close();\n }\n}\n\nexport function toPageSummary(elementMap: ElementMap): PageSummary {\n const inputs = elementMap.elements\n .filter((element): element is CapturedElement => element.category === 'input')\n .slice(0, 30)\n .map((element) => ({\n label: asString(element.attributes.label),\n placeholder: asString(element.attributes.placeholder),\n name: asString(element.attributes.name),\n type: asString(element.attributes.type),\n testId: asString(element.attributes.testId),\n }));\n\n return {\n url: elementMap.url,\n title: elementMap.title,\n headings: elementMap.elements\n .filter((element) => element.category === 'heading')\n .map((element) => element.name ?? '')\n .filter(Boolean)\n .slice(0, 20),\n buttons: elementMap.elements\n .filter((element) => element.category === 'button')\n .map((element) => element.name ?? '')\n .filter(Boolean)\n .slice(0, 30),\n links: elementMap.elements\n .filter((element) => element.category === 'link')\n .map((element) => element.name ?? '')\n .filter(Boolean)\n .slice(0, 50),\n inputs,\n landmarks: [],\n rawLength: elementMap.elements.length,\n };\n}\n\nasync function loadChromium(): Promise<any> {\n try {\n return (await import('playwright-core')).chromium;\n } catch {}\n\n try {\n return (await import('@playwright/test')).chromium;\n } catch {}\n\n throw new Error(\n 'Playwright is required for live page capture. Install it in the target project with \"npm install -D @playwright/test\" and \"npx playwright install chromium\".'\n );\n}\n\nfunction extractDomData(): DomData {\n const localMaxPerCategory = 50;\n const attr = (el: Element, name: string): string | undefined => el.getAttribute(name)?.trim() || undefined;\n const text = (el: Element | null): string | undefined => el?.textContent?.replace(/\\s+/g, ' ').trim() || undefined;\n const jsString = (value: string) => JSON.stringify(value);\n\n const findLabel = (el: Element): string | undefined => {\n const id = attr(el, 'id');\n\n if (id) {\n const labelEl = document.querySelector(`label[for=\"${id}\"]`);\n if (labelEl) return text(labelEl);\n }\n\n const ariaLabel = attr(el, 'aria-label');\n if (ariaLabel) return ariaLabel;\n\n const labelledBy = attr(el, 'aria-labelledby');\n if (labelledBy) {\n const labelEl = document.getElementById(labelledBy);\n if (labelEl) return text(labelEl);\n }\n\n const closestLabel = el.closest('label');\n if (closestLabel) {\n const raw = text(closestLabel) || '';\n const placeholder = attr(el, 'placeholder') || '';\n return raw.replace(placeholder, '').trim() || undefined;\n }\n\n const previous = el.previousElementSibling;\n if (previous?.tagName === 'LABEL') return text(previous);\n\n return undefined;\n };\n\n const buildSelector = (el: Element, labelText?: string, buttonText?: string): string | null => {\n const testId = attr(el, 'data-testid');\n if (testId) return `getByTestId(${jsString(testId)})`;\n\n const id = attr(el, 'id');\n if (id && !id.match(/^(ember|react|vue|ng|auto|rand)/i)) {\n return `locator(${jsString(`#${id}`)})`;\n }\n\n const ariaLabel = attr(el, 'aria-label');\n if (ariaLabel) {\n return `getByRole(${jsString(el.getAttribute('role') || el.tagName.toLowerCase())}, { name: ${jsString(ariaLabel)} })`;\n }\n\n if (labelText) {\n const tag = el.tagName.toLowerCase();\n if (tag === 'input' || tag === 'textarea' || tag === 'select') {\n return `getByLabel(${jsString(labelText)})`;\n }\n }\n\n if (buttonText) return `getByRole('button', { name: ${jsString(buttonText)} })`;\n\n const name = attr(el, 'name');\n if (name) return `locator(${jsString(`[name=\"${name}\"]`)})`;\n\n return null;\n };\n\n const buttons: DomButton[] = [];\n document.querySelectorAll('button, [role=\"button\"], input[type=\"submit\"], input[type=\"button\"]').forEach((el) => {\n const buttonText = attr(el, 'aria-label') || text(el) || attr(el, 'value');\n const testId = attr(el, 'data-testid');\n const id = attr(el, 'id');\n const type = attr(el, 'type');\n const disabled = el.hasAttribute('disabled') || el.getAttribute('aria-disabled') === 'true';\n const selector = buildSelector(el, undefined, buttonText);\n\n if (buttonText || testId) {\n buttons.push({\n tag: el.tagName.toLowerCase(),\n text: buttonText,\n testId,\n id,\n type,\n disabled,\n selector,\n cssPath: testId ? `[data-testid=\"${testId}\"]` : (id ? `#${id}` : null),\n });\n }\n });\n\n const inputs: DomInput[] = [];\n document.querySelectorAll('input:not([type=\"hidden\"]):not([type=\"submit\"]):not([type=\"button\"]), textarea, select').forEach((el) => {\n const label = findLabel(el);\n const placeholder = attr(el, 'placeholder');\n const name = attr(el, 'name');\n const id = attr(el, 'id');\n const type = attr(el, 'type') || el.tagName.toLowerCase();\n const testId = attr(el, 'data-testid');\n const required = el.hasAttribute('required');\n const selector = buildSelector(el, label);\n\n if (label || placeholder || name || testId || id) {\n inputs.push({\n tag: el.tagName.toLowerCase(),\n type,\n label,\n placeholder,\n name,\n id,\n testId,\n required,\n selector,\n cssPath: testId ? `[data-testid=\"${testId}\"]` : (id ? `#${id}` : (name ? `[name=\"${name}\"]` : null)),\n });\n }\n });\n\n const links: DomLink[] = [];\n document.querySelectorAll('a[href]').forEach((el) => {\n const linkText = attr(el, 'aria-label') || text(el);\n const href = attr(el, 'href');\n const testId = attr(el, 'data-testid');\n\n if (!linkText || href === '#') return;\n\n links.push({\n text: linkText,\n href,\n testId,\n external: Boolean(href?.startsWith('http') && !href.includes(window.location.hostname)),\n selector: testId\n ? `getByTestId(${jsString(testId)})`\n : `getByRole('link', { name: ${jsString(linkText)} })`,\n });\n });\n\n const headings: DomHeading[] = [];\n document.querySelectorAll('h1, h2, h3').forEach((el) => {\n const headingText = text(el);\n if (headingText) {\n headings.push({\n level: el.tagName.toLowerCase(),\n text: headingText,\n selector: `getByRole('heading', { name: ${jsString(headingText)} })`,\n });\n }\n });\n\n const landmarks: Array<{ role: string; label: string }> = [];\n document.querySelectorAll('[role], main, nav, header, footer, aside, section[aria-label]').forEach((el) => {\n const role = attr(el, 'role') || el.tagName.toLowerCase();\n const label = attr(el, 'aria-label') || text(el)?.slice(0, 40);\n if (role && label) landmarks.push({ role, label });\n });\n\n const statusRegions: DomStatusRegion[] = [];\n document.querySelectorAll('[role=\"alert\"], [role=\"status\"], [aria-live]').forEach((el) => {\n const role = attr(el, 'role') || 'live';\n statusRegions.push({\n role,\n ariaLive: attr(el, 'aria-live'),\n text: text(el),\n selector: el.getAttribute('role')\n ? `getByRole(${jsString(role)})`\n : `locator('[aria-live]')`,\n });\n });\n\n const forms: DomForm[] = [];\n document.querySelectorAll('form').forEach((form, index) => {\n forms.push({\n id: attr(form, 'id'),\n label: attr(form, 'aria-label') || attr(form, 'aria-labelledby'),\n action: attr(form, 'action'),\n method: attr(form, 'method') || 'get',\n fieldCount: form.querySelectorAll('input, textarea, select').length,\n index,\n });\n });\n\n return {\n buttons: buttons.slice(0, localMaxPerCategory),\n inputs: inputs.slice(0, localMaxPerCategory),\n links: links.slice(0, localMaxPerCategory),\n headings: headings.slice(0, 20),\n landmarks,\n statusRegions,\n forms,\n pageUrl: window.location.href,\n pageTitle: document.title,\n };\n}\n\nfunction buildElementMap(domData: DomData): CapturedElement[] {\n const elements: CapturedElement[] = [];\n\n for (const input of domData.inputs) {\n const displayName = input.label || input.placeholder || input.name || input.testId;\n if (!displayName) continue;\n\n const selector = input.selector\n || (input.testId ? `getByTestId(${JSON.stringify(input.testId)})` : null)\n || (input.label ? `getByLabel(${JSON.stringify(input.label)})` : null)\n || (input.id ? `locator(${JSON.stringify(`#${input.id}`)})` : null)\n || (input.name ? `locator(${JSON.stringify(`[name=\"${input.name}\"]`)})` : null)\n || `locator(${JSON.stringify(`${input.tag}[placeholder=\"${input.placeholder ?? ''}\"]`)})`;\n\n const selectorAlt: string[] = [];\n if (input.id && !selector.includes(`#${input.id}`)) selectorAlt.push(`locator(${JSON.stringify(`#${input.id}`)})`);\n if (input.name && !selector.includes(input.name)) selectorAlt.push(`locator(${JSON.stringify(`[name=\"${input.name}\"]`)})`);\n if (input.testId && !selector.includes(input.testId)) selectorAlt.push(`getByTestId(${JSON.stringify(input.testId)})`);\n if (input.placeholder && !selector.includes(input.placeholder)) selectorAlt.push(`getByPlaceholder(${JSON.stringify(input.placeholder)})`);\n if (input.label && !selector.includes(input.label)) selectorAlt.push(`getByLabel(${JSON.stringify(input.label)})`);\n\n elements.push({\n category: 'input',\n role: input.type === 'checkbox' ? 'checkbox' : 'textbox',\n name: displayName,\n selector,\n selectorAlt,\n purpose: input.required\n ? `Required ${input.type} field - \"${displayName}\"`\n : `${input.type} field - \"${displayName}\"`,\n confidence: input.testId || input.label || input.id ? 'high' : (input.placeholder ? 'medium' : 'low'),\n attributes: {\n type: input.type,\n label: input.label,\n placeholder: input.placeholder,\n name: input.name,\n id: input.id,\n testId: input.testId,\n required: input.required,\n tag: input.tag,\n },\n });\n }\n\n for (const button of domData.buttons) {\n const displayName = button.text || button.testId;\n if (!displayName) continue;\n\n const selector = button.selector\n || (button.testId ? `getByTestId(${JSON.stringify(button.testId)})` : null)\n || (button.text ? `getByRole('button', { name: ${JSON.stringify(button.text)} })` : null)\n || (button.id ? `locator(${JSON.stringify(`#${button.id}`)})` : null)\n || `locator('button')`;\n\n const selectorAlt: string[] = [];\n if (button.id && !selector.includes(button.id)) selectorAlt.push(`locator(${JSON.stringify(`#${button.id}`)})`);\n if (button.testId && !selector.includes(button.testId)) selectorAlt.push(`getByTestId(${JSON.stringify(button.testId)})`);\n if (button.text && !selector.includes(button.text)) selectorAlt.push(`getByText(${JSON.stringify(button.text)})`);\n if (button.cssPath) selectorAlt.push(`locator(${JSON.stringify(button.cssPath)})`);\n\n elements.push({\n category: 'button',\n role: 'button',\n name: displayName,\n selector,\n selectorAlt,\n purpose: button.disabled\n ? `Disabled button - \"${displayName}\"`\n : button.type === 'submit'\n ? `Form submit button - \"${displayName}\"`\n : `Button - \"${displayName}\"`,\n confidence: button.testId || button.text ? 'high' : (button.id ? 'medium' : 'low'),\n attributes: {\n text: button.text,\n testId: button.testId,\n id: button.id,\n type: button.type,\n disabled: button.disabled,\n tag: button.tag,\n },\n });\n }\n\n for (const link of domData.links) {\n elements.push({\n category: 'link',\n role: 'link',\n name: link.text,\n selector: link.selector,\n selectorAlt: link.testId ? [`getByTestId(${JSON.stringify(link.testId)})`] : [],\n purpose: link.external\n ? `External link to \"${link.href}\" - \"${link.text}\"`\n : `Internal navigation link - \"${link.text}\" -> ${link.href}`,\n confidence: link.testId ? 'high' : 'medium',\n attributes: {\n text: link.text,\n href: link.href,\n testId: link.testId,\n external: link.external,\n },\n });\n }\n\n for (const heading of domData.headings) {\n elements.push({\n category: 'heading',\n role: 'heading',\n name: heading.text,\n selector: heading.selector,\n selectorAlt: [`getByText(${JSON.stringify(heading.text)})`],\n purpose: `Page ${heading.level} heading - use to assert the correct page or section loaded`,\n confidence: 'medium',\n attributes: {\n level: heading.level,\n text: heading.text,\n },\n });\n }\n\n for (const status of domData.statusRegions) {\n elements.push({\n category: 'status',\n role: status.role,\n name: status.text || status.role,\n selector: status.selector,\n selectorAlt: [],\n purpose: 'Live region - use to assert error messages, success toasts, and validation feedback',\n confidence: 'medium',\n attributes: {\n role: status.role,\n ariaLive: status.ariaLive,\n currentText: status.text,\n },\n });\n }\n\n return elements;\n}\n\nfunction buildWarnings(\n elements: CapturedElement[],\n domData: DomData,\n a11ySnapshot: unknown,\n): string[] {\n const warnings: string[] = [];\n\n if (!a11ySnapshot) {\n warnings.push('Playwright accessibility snapshot was unavailable. Capture continued using DOM extraction only.');\n }\n\n const lowConfidenceInputs = elements.filter((element) => element.category === 'input' && element.confidence === 'low');\n if (lowConfidenceInputs.length > 0) {\n warnings.push(\n `${lowConfidenceInputs.length} input(s) have low-confidence selectors. Consider adding data-testid attributes to: ${lowConfidenceInputs.map((element) => element.name).filter(Boolean).join(', ')}`\n );\n }\n\n if (domData.statusRegions.length === 0) {\n warnings.push('No ARIA alert or status regions detected. Error message assertions may need manual selector adjustments after generation.');\n }\n\n for (const form of domData.forms) {\n const hasSubmit = domData.buttons.some((button) => button.type === 'submit');\n if (form.fieldCount > 0 && !hasSubmit) {\n warnings.push(\n `Form ${form.id || `#${form.index}`} has ${form.fieldCount} field(s) but no detected submit button. It may use keyboard submit or a custom handler.`\n );\n }\n }\n\n if (domData.links.length >= MAX_PER_CATEGORY) {\n warnings.push(`Link count hit the ${MAX_PER_CATEGORY} capture limit. Generation will focus on forms and buttons.`);\n }\n\n const interactive = elements.filter((element) => (\n element.category === 'button' || element.category === 'input' || element.category === 'link'\n ));\n if (interactive.length === 0) {\n warnings.push('No interactive elements detected. The page may require authentication, render later than the current settle window, or be mostly static content.');\n }\n\n return warnings;\n}\n\nfunction log(verbose: boolean, message: string): void {\n if (verbose) console.log(message);\n}\n\nasync function getAccessibilitySnapshot(page: any, verbose: boolean): Promise<unknown> {\n if (!page.accessibility || typeof page.accessibility.snapshot !== 'function') {\n log(verbose, ' -> Accessibility snapshot API unavailable; continuing with DOM-only capture');\n return null;\n }\n\n try {\n return await page.accessibility.snapshot({ interestingOnly: false });\n } catch (error: any) {\n log(verbose, ` -> Accessibility snapshot failed (${error?.message ?? error}); continuing with DOM-only capture`);\n return null;\n }\n}\n\nfunction asString(value: unknown): string | undefined {\n return typeof value === 'string' ? value : undefined;\n}\n","import { mkdirSync, writeFileSync } from 'node:fs';\nimport { join } from 'node:path';\nimport type { AnalysisResult } from './analyse.js';\nimport type { ElementMap } from './capture.js';\n\nexport function printCaptureReport(elementMap: ElementMap, analysis?: AnalysisResult | null): void {\n console.log('');\n console.log('='.repeat(60));\n console.log('CementicTest Capture Report');\n console.log('='.repeat(60));\n console.log(`URL: ${elementMap.url}`);\n console.log(`Title: ${elementMap.title}`);\n console.log(`Captured: ${elementMap.timestamp} (${elementMap.mode})`);\n console.log('');\n console.log('Elements:');\n\n for (const [category, count] of Object.entries(elementMap.summary.byCategory)) {\n console.log(` ${category}: ${count}`);\n }\n\n if (elementMap.warnings.length > 0) {\n console.log('');\n console.log('Warnings:');\n for (const warning of elementMap.warnings) {\n console.log(` - ${warning}`);\n }\n }\n\n if (analysis) {\n console.log('');\n console.log(`AI scenarios: ${analysis.scenarios.length}`);\n console.log(`Feature: ${analysis.feature}`);\n console.log(`Prefix: ${analysis.suggestedPrefix}`);\n }\n\n console.log('');\n}\n\nexport function saveCaptureJson(\n elementMap: ElementMap,\n analysis?: AnalysisResult | null,\n outputDir = '.cementic/capture',\n): string {\n mkdirSync(outputDir, { recursive: true });\n\n const fileName = `capture-${slugify(elementMap.url)}-${Date.now()}.json`;\n const filePath = join(outputDir, fileName);\n\n writeFileSync(filePath, JSON.stringify({\n _meta: {\n version: '0.2.5',\n generatedAt: new Date().toISOString(),\n tool: '@cementic/cementic-test',\n },\n elementMap,\n analysis: analysis ?? null,\n }, null, 2));\n\n return filePath;\n}\n\nexport function buildCasesMarkdown(analysis: AnalysisResult): string {\n const lines: string[] = [];\n\n for (const scenario of analysis.scenarios) {\n lines.push(`# ${scenario.id} — ${scenario.title} ${scenario.tags.map(normalizeTag).join(' ')}`.trim());\n lines.push(`<!-- ct:url ${analysis.url} -->`);\n lines.push(`<!-- ct:feature ${analysis.feature} -->`);\n lines.push(`<!-- ct:generated-by capture -->`);\n lines.push(`<!-- narrator: ${sanitizeComment(scenario.narrator)} -->`);\n lines.push(`<!-- code-level: ${scenario.codeLevel} -->`);\n lines.push('');\n lines.push('## Steps');\n\n scenario.steps.forEach((step, index) => {\n const hint = step.selector && step.selector !== 'page'\n ? ` <!-- selector: ${step.selector} -->`\n : '';\n lines.push(`${index + 1}. ${step.human}${hint}`);\n });\n\n lines.push('');\n lines.push('## Expected Results');\n\n scenario.assertions.forEach((assertion) => {\n const hint = assertion.playwright\n ? ` <!-- playwright: ${sanitizeComment(assertion.playwright)} -->`\n : '';\n lines.push(`- ${assertion.human}${hint}`);\n });\n\n lines.push('');\n lines.push('---');\n lines.push('');\n }\n\n return lines.join('\\n');\n}\n\nexport function saveCasesMarkdown(\n analysis: AnalysisResult,\n outputDir = 'cases',\n fileName?: string,\n): string {\n mkdirSync(outputDir, { recursive: true });\n\n const resolvedFileName = fileName ?? `${slugify(analysis.feature || analysis.url)}.md`;\n const filePath = join(outputDir, resolvedFileName);\n\n writeFileSync(filePath, buildCasesMarkdown(analysis));\n return filePath;\n}\n\nexport function saveSpecPreview(\n analysis: AnalysisResult,\n outputDir = 'tests/preview',\n): string | null {\n if (analysis.scenarios.length === 0) return null;\n\n mkdirSync(outputDir, { recursive: true });\n\n const fileName = `spec-preview-${slugify(analysis.url)}-${Date.now()}.spec.cjs`;\n const filePath = join(outputDir, fileName);\n const lines: string[] = [];\n\n lines.push('/**');\n lines.push(' * CementicTest Capture Preview');\n lines.push(` * Generated from: ${analysis.url}`);\n lines.push(` * Feature: ${analysis.feature}`);\n lines.push(' */');\n lines.push('');\n lines.push(`const { test, expect } = require('@playwright/test');`);\n lines.push('');\n\n for (const scenario of analysis.scenarios) {\n lines.push(`test(${JSON.stringify(`${scenario.id} — ${scenario.title}`)}, async ({ page }) => {`);\n for (const step of scenario.steps) {\n if (step.action === 'navigate') {\n lines.push(` await page.goto(${JSON.stringify(step.value)});`);\n continue;\n }\n\n if (step.selector === 'page') continue;\n const selector = `page.${step.selector}`;\n\n if (step.action === 'fill') lines.push(` await ${selector}.fill(${JSON.stringify(step.value)});`);\n if (step.action === 'click') lines.push(` await ${selector}.click();`);\n if (step.action === 'select') lines.push(` await ${selector}.selectOption(${JSON.stringify(step.value)});`);\n if (step.action === 'check') lines.push(` await ${selector}.check();`);\n if (step.action === 'keyboard') lines.push(` await page.keyboard.press(${JSON.stringify(step.value)});`);\n if (step.action === 'hover') lines.push(` await ${selector}.hover();`);\n }\n\n for (const assertion of scenario.assertions) {\n lines.push(` ${ensureStatement(assertion.playwright)}`);\n }\n\n lines.push('});');\n lines.push('');\n }\n\n writeFileSync(filePath, lines.join('\\n'));\n return filePath;\n}\n\nfunction slugify(value: string): string {\n return (value || 'capture')\n .replace(/^https?:\\/\\//, '')\n .replace(/[^a-zA-Z0-9]+/g, '-')\n .replace(/^-|-$/g, '')\n .toLowerCase()\n .slice(0, 60);\n}\n\nfunction normalizeTag(value: string): string {\n const cleaned = String(value ?? '').trim();\n if (!cleaned) return '@ui';\n return cleaned.startsWith('@') ? cleaned : `@${cleaned}`;\n}\n\nfunction sanitizeComment(value: string): string {\n return String(value ?? '').replace(/-->/g, '-- >');\n}\n\nfunction ensureStatement(value: string): string {\n const trimmed = String(value ?? '').trim();\n if (!trimmed) return '// TODO: add assertion';\n return trimmed.endsWith(';') ? trimmed : `${trimmed};`;\n}\n","import { Command } from 'commander';\nimport { spawn } from 'node:child_process';\n\nexport function reportCmd() {\n const cmd = new Command('report')\n .description('Open the Playwright HTML report')\n .action(() => {\n console.log('📊 Opening Playwright HTML report...');\n \n const child = spawn(\n 'npx',\n ['playwright', 'show-report'],\n {\n stdio: 'inherit',\n shell: process.platform === 'win32',\n }\n );\n\n child.on('exit', (code) => {\n process.exit(code ?? 0);\n });\n });\n\n return cmd;\n}\n","import { Command } from 'commander';\nimport { spawn } from 'node:child_process';\nimport { existsSync } from 'node:fs';\nimport { join } from 'node:path';\n\nexport function serveCmd() {\n const cmd = new Command('serve')\n .description('Serve the Allure report')\n .action(() => {\n console.log('📊 Serving Allure report...');\n\n // Try to find the local allure binary first (more reliable than global/npx sometimes)\n const localAllureBin = join(process.cwd(), 'node_modules', 'allure-commandline', 'bin', 'allure');\n \n let executable = 'npx';\n let args = ['allure', 'serve', './allure-results'];\n\n // If we can find the direct binary, use it (node node_modules/.../allure)\n // This bypasses the \"require('../')\" issue in the .bin wrapper\n if (existsSync(localAllureBin)) {\n executable = 'node';\n args = [localAllureBin, 'serve', './allure-results'];\n }\n\n console.log(`> ${executable} ${args.join(' ')}`);\n\n const child = spawn(\n executable,\n args,\n {\n stdio: 'inherit',\n shell: process.platform === 'win32',\n }\n );\n\n child.on('exit', (code) => {\n process.exit(code ?? 0);\n });\n });\n\n return cmd;\n}\n","import { Command } from 'commander';\nimport { spawn } from 'node:child_process';\nimport { resolve } from 'node:path';\n\nfunction runStep(cmd: string, args: string[], stepName: string): Promise<void> {\n return new Promise((resolve, reject) => {\n console.log(`\\n🌊 Flow Step: ${stepName}`);\n console.log(`> ${cmd} ${args.join(' ')}`);\n\n const child = spawn(cmd, args, {\n stdio: 'inherit',\n shell: process.platform === 'win32',\n });\n\n child.on('exit', (code) => {\n if (code === 0) {\n resolve();\n } else {\n reject(new Error(`${stepName} failed with exit code ${code}`));\n }\n });\n });\n}\n\nexport function flowCmd() {\n const cmd = new Command('flow')\n .description('End-to-end flow: Normalize -> Generate -> Run Tests')\n .argument('[casesDir]', 'Directory containing test cases', './cases')\n .option('--lang <lang>', 'Target language (ts|js)', 'ts')\n .option('--no-run', 'Skip running tests')\n .action(async (casesDir, opts) => {\n const cliBin = resolve(process.argv[1]); // The current CLI executable\n\n try {\n // 1. Normalize\n await runStep(process.execPath, [cliBin, 'normalize', casesDir], 'Normalize Cases');\n\n // 2. Generate\n await runStep(process.execPath, [cliBin, 'gen', '--lang', opts.lang], 'Generate Tests');\n\n // 3. Test (unless skipped)\n if (opts.run) {\n await runStep(process.execPath, [cliBin, 'test'], 'Run Playwright Tests');\n } else {\n console.log('\\n⏭️ Skipping test execution (--no-run)');\n }\n\n console.log('\\n✅ Flow completed successfully!');\n } catch (err: any) {\n console.error(`\\n❌ Flow failed: ${err.message}`);\n process.exit(1);\n }\n });\n\n return cmd;\n}\n","import { Command } from 'commander';\nimport { mkdirSync, writeFileSync, existsSync } from 'node:fs';\nimport { join } from 'node:path';\n\nconst WORKFLOW_CONTENT = `name: Playwright Tests\non:\n push:\n branches: [ main, master ]\n pull_request:\n branches: [ main, master ]\njobs:\n test:\n timeout-minutes: 60\n runs-on: ubuntu-latest\n steps:\n - uses: actions/checkout@v4\n - uses: actions/setup-node@v4\n with:\n node-version: lts/*\n - name: Install dependencies\n run: npm ci\n - name: Install Playwright Browsers\n run: npx playwright install --with-deps\n - name: Run Playwright tests\n run: npx playwright test\n - uses: actions/upload-artifact@v4\n if: always()\n with:\n name: playwright-report\n path: playwright-report/\n retention-days: 30\n`;\n\nexport function ciCmd() {\n const cmd = new Command('ci')\n .description('Generate GitHub Actions workflow for CI')\n .action(() => {\n const githubDir = join(process.cwd(), '.github');\n const workflowsDir = join(githubDir, 'workflows');\n const workflowFile = join(workflowsDir, 'cementic.yml');\n\n console.log('🤖 Setting up CI/CD workflow...');\n\n if (!existsSync(workflowsDir)) {\n mkdirSync(workflowsDir, { recursive: true });\n console.log(`Created directory: ${workflowsDir}`);\n }\n\n if (existsSync(workflowFile)) {\n console.warn(`⚠️ Workflow file already exists at ${workflowFile}. Skipping.`);\n return;\n }\n\n writeFileSync(workflowFile, WORKFLOW_CONTENT.trim() + '\\n');\n console.log(`✅ CI workflow generated at: ${workflowFile}`);\n console.log('Next steps:');\n console.log('1. Commit and push the new file');\n console.log('2. Check the \"Actions\" tab in your GitHub repository');\n });\n\n return cmd;\n}\n"],"mappings":";;;;;;AAAA,SAAS,WAAAA,gBAAe;AACxB,SAAS,qBAAqB;;;ACD9B,SAAS,eAAe;AACxB,SAAS,WAAW,eAAe,YAAY,cAAc,QAAQ,aAAa,gBAAgB;AAClG,SAAS,MAAM,eAAe;AAC9B,SAAS,gBAAgB;AACzB,SAAS,qBAAqB;AAC9B,SAAS,eAAe;AACxB,SAAS,UAAU,eAAe;AAElC,IAAM,aAAa,cAAc,YAAY,GAAG;AAChD,IAAM,YAAY,QAAQ,UAAU;AAEpC,SAAS,oBAAoB,aAAyC;AACpE,QAAM,aAAa;AAAA,IACjB,QAAQ,WAAW,aAAa,WAAW,EAAE;AAAA,IAC7C,QAAQ,WAAW,gBAAgB,WAAW,EAAE;AAAA,IAChD,QAAQ,WAAW,mBAAmB,WAAW,EAAE;AAAA,IACnD,QAAQ,QAAQ,IAAI,GAAG,aAAa,WAAW,EAAE;AAAA,EACnD;AAEA,SAAO,WAAW,KAAK,eAAa,WAAW,SAAS,CAAC;AAC3D;AAEO,SAAS,SAAS;AACvB,QAAM,MAAM,IAAI,QAAQ,KAAK,EAC1B,UAAU,eAAe,EACzB,YAAY,+DAA+D,EAC3E,YAAY,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA,CAKzB,EACI,OAAO,iBAAiB,sBAAsB,YAAY,EAC1D,OAAO,iBAAiB,6BAA6B,IAAI,EACzD,OAAO,iBAAiB,kDAAkD,EAC1E,OAAO,CAAC,aAAqB,SAAS;AACrC,UAAM,OAAO,QAAQ,IAAI;AACzB,UAAM,cAAc,KAAK,MAAM,WAAW;AAE1C,YAAQ,IAAI,sDAA+C,WAAW,KAAK;AAG3E,QAAI,WAAW,WAAW,GAAG;AAC3B,cAAQ,MAAM,oBAAe,WAAW,kBAAkB;AAC1D,cAAQ,KAAK,CAAC;AAAA,IAChB;AACA,cAAU,aAAa,EAAE,WAAW,KAAK,CAAC;AAE1C,UAAM,OAAO,KAAK,SAAS,OAAO,OAAO;AACzC,UAAM,cAAc,SAAS,OAAO,yBAAyB;AAC7D,UAAM,eAAe,oBAAoB,WAAW;AAEpD,QAAI,CAAC,cAAc;AACjB,cAAQ,MAAM,qCAAgC,WAAW,GAAG;AAC5D,cAAQ,MAAM,uEAAuE;AACrF,cAAQ,KAAK,CAAC;AAAA,IAChB;AAEA,YAAQ,IAAI,mCAA4B,YAAY,KAAK;AAGzD,aAAS,cAAc,KAAa,MAAc;AAChD,UAAI,SAAS,GAAG,EAAE,YAAY,GAAG;AAC/B,kBAAU,MAAM,EAAE,WAAW,KAAK,CAAC;AACnC,oBAAY,GAAG,EAAE,QAAQ,WAAS;AAChC,wBAAc,KAAK,KAAK,KAAK,GAAG,KAAK,MAAM,KAAK,CAAC;AAAA,QACnD,CAAC;AAAA,MACH,OAAO;AACL,eAAO,KAAK,IAAI;AAAA,MAClB;AAAA,IACF;AAEA,kBAAc,cAAc,WAAW;AAGvC,QAAI,SAAS,MAAM,UAAU;AAC3B,YAAM,YAAY,QAAQ;AAC1B,YAAM,eAAe,SAAS,UAAU,MAAM,GAAG,EAAE,CAAC,GAAG,EAAE;AAGzD,UAAI,eAAe,IAAI;AACnB,gBAAQ,IAAI,+EAAwE;AACpF,cAAM,cAAc,KAAK,aAAa,cAAc;AACpD,YAAI,WAAW,WAAW,GAAG;AACzB,cAAI;AACA,kBAAM,aAAa,aAAa,aAAa,OAAO;AACpD,kBAAM,MAAM,KAAK,MAAM,UAAU;AACjC,gBAAI,IAAI,iBAAiB;AACrB,kBAAI,gBAAgB,kBAAkB,IAAI;AAC1C,kBAAI,gBAAgB,mBAAmB,IAAI;AAC3C,4BAAc,aAAa,KAAK,UAAU,KAAK,MAAM,CAAC,CAAC;AACvD,sBAAQ,IAAI,oFAA+E;AAAA,YAC/F;AAAA,UACJ,SAAS,KAAK;AACV,oBAAQ,KAAK,oEAA0D,GAAG;AAAA,UAC9E;AAAA,QACJ;AAAA,MACJ;AAAA,IACF;AAGA,QAAI;AACF,eAAS,YAAY,EAAE,KAAK,aAAa,OAAO,SAAS,CAAC;AAE1D,YAAM,gBAAgB,KAAK,aAAa,YAAY;AACpD,UAAI,CAAC,WAAW,aAAa,GAAG;AAC5B,sBAAc,eAAe,kEAAkE;AAAA,MACnG;AAAA,IACF,SAAS,GAAG;AACV,cAAQ,KAAK,mDAAyC;AAAA,IACxD;AAGA,YAAQ,IAAI,sCAA+B;AAC3C,QAAI;AACF,eAAS,eAAe,EAAE,KAAK,aAAa,OAAO,UAAU,CAAC;AAAA,IAChE,SAAS,GAAG;AACV,cAAQ,MAAM,2EAAsE;AAAA,IACtF;AAIA,QAAI,KAAK,aAAa,OAAO;AAC3B,cAAQ,IAAI,6CAAsC;AAClD,UAAI;AACF,iBAAS,0BAA0B,EAAE,KAAK,aAAa,OAAO,UAAU,CAAC;AAAA,MAC3E,SAAS,GAAG;AACV,gBAAQ,KAAK,iFAAuE;AAAA,MACtF;AAAA,IACF;AAEA,YAAQ,IAAI;AAAA,iBAAe,WAAW,wBAAwB;AAC9D,YAAQ,IAAI;AAAA;AAAA,CAAqB;AACjC,YAAQ,IAAI,QAAQ,WAAW,EAAE;AACjC,YAAQ,IAAI,uBAAuB;AACnC,YAAQ,IAAI;AAAA,yBAAqB;AAAA,EACnC,CAAC;AAEH,SAAO;AACT;;;AC3IA,SAAS,WAAAC,gBAAe;AACxB,OAAO,QAAQ;AACf,SAAS,gBAAAC,eAAc,aAAAC,YAAW,iBAAAC,gBAAe,YAAAC,iBAAgB;AACjE,SAAS,QAAAC,OAAM,UAAU,WAAAC,gBAAe;AAiBxC,SAAS,UAAU,OAAkD;AACnE,QAAM,OAAO,MAAM,KAAK,MAAM,SAAS,YAAY,CAAC,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;AACrE,QAAM,QAAQ,MAAM,QAAQ,YAAY,EAAE,EAAE,KAAK;AACjD,SAAO,EAAE,OAAO,KAAK;AACvB;AAGA,SAAS,QAAQ,OAAmC;AAClD,QAAM,IAAI,MAAM,MAAM,kBAAkB;AACxC,SAAO,IAAI,CAAC;AACd;AAEA,SAAS,uBAAuB,OAAe,IAAqB;AAClE,MAAI,CAAC,GAAI,QAAO,MAAM,KAAK;AAC3B,SAAO,MAAM,QAAQ,IAAI,OAAO,IAAI,EAAE,4BAAkB,GAAG,EAAE,EAAE,KAAK;AACtE;AAGA,SAAS,oBAAoB,UAA8D;AACzF,QAAM,QAAQ,SAAS,MAAM,OAAO;AACpC,QAAM,SAAqD,CAAC;AAC5D,MAAI,eAA8B;AAClC,MAAI,MAAgB,CAAC;AAErB,QAAM,QAAQ,MAAM;AAClB,QAAI,iBAAiB,MAAM;AACzB,aAAO,KAAK,EAAE,WAAW,cAAc,MAAM,IAAI,KAAK,IAAI,EAAE,CAAC;AAAA,IAC/D;AACA,UAAM,CAAC;AAAA,EACT;AAEA,aAAW,QAAQ,OAAO;AACxB,UAAM,KAAK,KAAK,MAAM,eAAe;AACrC,QAAI,IAAI;AACN,UAAI,iBAAiB,KAAM,OAAM;AACjC,qBAAe,GAAG,CAAC,EAAE,KAAK;AAAA,IAC5B,OAAO;AACL,UAAI,KAAK,IAAI;AAAA,IACf;AAAA,EACF;AACA,MAAI,iBAAiB,KAAM,OAAM;AAGjC,MAAI,OAAO,WAAW,GAAG;AACvB,UAAM,QAAQ,MAAM,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC;AACxC,UAAM,QAAQ,OAAO,QAAQ,SAAS,EAAE,EAAE,KAAK,KAAK;AACpD,WAAO,CAAC,EAAE,WAAW,OAAO,MAAM,MAAM,KAAK,IAAI,EAAE,CAAC;AAAA,EACtD;AACA,SAAO;AACT;AAGA,SAAS,gBAAgB,MAKvB;AAGA,QAAM,eAAe;AACrB,QAAM,WAAmC,CAAC;AAC1C,MAAI;AACJ,QAAM,UAAkD,CAAC;AAEzD,SAAQ,QAAQ,aAAa,KAAK,IAAI,GAAI;AACxC,YAAQ,KAAK,EAAE,MAAM,MAAM,CAAC,EAAE,YAAY,GAAG,OAAO,MAAM,MAAM,CAAC;AAAA,EACnE;AAGA,UAAQ,KAAK,EAAE,MAAM,WAAW,OAAO,KAAK,OAAO,CAAC;AAEpD,WAAS,IAAI,GAAG,IAAI,QAAQ,SAAS,GAAG,KAAK;AAC3C,UAAM,OAAO,QAAQ,CAAC,EAAE;AACxB,UAAM,QAAQ,KAAK,MAAM,QAAQ,CAAC,EAAE,OAAO,QAAQ,IAAI,CAAC,EAAE,KAAK;AAC/D,aAAS,IAAI,IAAI;AAAA,EACnB;AAEA,QAAM,aACJ,SAAS,OAAO,KAChB;AAEF,QAAM,gBACJ,SAAS,UAAU,KACnB,SAAS,kBAAkB,KAC3B,SAAS,MAAM,KACf;AAEF,QAAM,SAAS;AAEf,QAAM,cAAc,MAAM,KAAK,WAAW,SAAS,MAAM,CAAC,EAAE,IAAI,CAAC,MAAM,gBAAgB,EAAE,CAAC,EAAE,KAAK,GAAG,UAAU,CAAC;AAC/G,QAAM,QAAQ,YAAY,IAAI,CAAC,UAAU,MAAM,IAAI;AACnD,QAAM,YAAY,YAAY,IAAI,CAAC,WAAW,EAAE,UAAU,MAAM,KAAK,EAAE;AAGvE,MAAI,MAAM,WAAW,GAAG;AACtB,UAAM,MAAM,MAAM,KAAK,KAAK,SAAS,MAAM,CAAC,EAAE,IAAI,CAAC,MAAM,gBAAgB,EAAE,CAAC,EAAE,KAAK,GAAG,UAAU,CAAC;AAEjG,UAAM,KAAK,GAAG,IAAI,IAAI,CAAC,UAAU,MAAM,IAAI,CAAC;AAC5C,cAAU,KAAK,GAAG,IAAI,IAAI,CAAC,WAAW,EAAE,UAAU,MAAM,KAAK,EAAE,CAAC;AAAA,EAClE;AAEA,QAAM,iBAAiB,MAAM,KAAK,cAAc,SAAS,MAAM,CAAC,EAAE,IAAI,CAAC,MAAM,gBAAgB,EAAE,CAAC,EAAE,KAAK,GAAG,YAAY,CAAC;AACvH,QAAM,gBAAgB,eAAe,IAAI,CAAC,UAAU,MAAM,IAAI;AAC9D,QAAM,iBAAiB,eAAe,IAAI,CAAC,WAAW,EAAE,YAAY,MAAM,KAAK,EAAE;AAGjF,MAAI,cAAc,WAAW,GAAG;AAC9B,UAAM,MAAM,MAAM;AAAA,MAChB,KAAK,SAAS,2DAA2D;AAAA,IAC3E,EAAE,IAAI,CAAC,MAAM,gBAAgB,EAAE,CAAC,EAAE,KAAK,GAAG,YAAY,CAAC;AACvD,kBAAc,KAAK,GAAG,IAAI,IAAI,CAAC,UAAU,MAAM,IAAI,CAAC;AACpD,mBAAe,KAAK,GAAG,IAAI,IAAI,CAAC,WAAW,EAAE,YAAY,MAAM,KAAK,EAAE,CAAC;AAAA,EACzE;AAEA,SAAO,EAAE,OAAO,WAAW,UAAU,eAAe,eAAe;AACrE;AAEA,SAAS,mBAAmB,MAAkC;AAC5D,QAAM,QAAQ,KAAK,MAAM,6CAA6C;AACtE,SAAO,QAAQ,CAAC;AAClB;AAEA,SAAS,gBAAgB,MAAsB;AAC7C,SAAO,KAAK,QAAQ,wDAAwD,EAAE;AAChF;AAEA,SAAS,gBACP,OACA,UACiC;AACjC,QAAM,QAAQ,MAAM,MAAM,IAAI,OAAO,qBAAqB,QAAQ,iCAAiC,GAAG,CAAC;AACvG,MAAI,CAAC,MAAO,QAAO,EAAE,MAAM,MAAM,KAAK,EAAE;AACxC,SAAO;AAAA,IACL,MAAM,MAAM,CAAC,EAAE,KAAK;AAAA,IACpB,MAAM,MAAM,CAAC,EAAE,KAAK,KAAK;AAAA,EAC3B;AACF;AAEA,SAAS,oBAAoB,OAAqC;AAChE,aAAW,QAAQ,OAAO;AACxB,UAAM,QAAQ,KAAK,MAAM,sBAAsB;AAC/C,QAAI,MAAO,QAAO,MAAM,CAAC;AAAA,EAC3B;AACA,SAAO;AACT;AAGA,SAAS,aAAa,WAAmB,MAAc,QAAgC;AACrF,QAAM,EAAE,OAAO,KAAK,IAAI,UAAU,SAAS;AAC3C,QAAM,KAAK,QAAQ,KAAK;AACxB,QAAM,cAAc,mBAAmB,IAAI;AAC3C,QAAM,YAAY,gBAAgB,IAAI;AACtC,QAAM,EAAE,OAAO,WAAW,UAAU,eAAe,IAAI,gBAAgB,SAAS;AAChF,QAAM,gBAA0B,CAAC;AAEjC,MAAI,MAAM,WAAW,EAAG,eAAc,KAAK,yCAAyC;AACpF,MAAI,SAAS,WAAW,EAAG,eAAc,KAAK,uDAAuD;AAErG,SAAO;AAAA,IACL;AAAA,IACA,OAAO,uBAAuB,OAAO,EAAE;AAAA,IACvC,MAAM,KAAK,SAAS,OAAO;AAAA,IAC3B;AAAA,IACA,YAAY,UAAU,KAAK,UAAQ,KAAK,QAAQ,IAAI,YAAY;AAAA,IAChE;AAAA,IACA,iBAAiB,eAAe,KAAK,UAAQ,KAAK,UAAU,IAAI,iBAAiB;AAAA,IACjF,cAAc,cAAc,SAAS;AAAA,IACrC,gBAAgB;AAAA,IAChB;AAAA,IACA,KAAK,eAAe,oBAAoB,KAAK;AAAA,EAC/C;AACF;AAGO,SAAS,eAAe;AAC7B,QAAM,MAAM,IAAIN,SAAQ,WAAW,EAChC,SAAS,UAAU,6EAA6E,EAChG,YAAY,qEAAqE,EACjF,YAAY,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA,CAKzB,EACI,OAAO,YAAY,0DAA0D,IAAI,EACjF,OAAO,aAAa,yDAAyD,KAAK,EAClF,OAAO,iBAAiB,+DAA+D,IAAI,EAC3F,OAAO,OAAO,WAAmB,SAAgE;AAEhG,QAAI,WAAqB,CAAC;AAC1B,QAAI;AACF,YAAM,MAAMM,SAAQ,SAAS;AAC7B,UAAIF,UAAS,GAAG,EAAE,YAAY,GAAG;AAC/B,cAAM,OAAO,UAAU,QAAQ,OAAO,EAAE;AACxC,mBAAW,CAAC,GAAG,IAAI,0CAA0C;AAAA,MAC/D,OAAO;AACL,mBAAW,CAAC,SAAS;AAAA,MACvB;AAAA,IACF,QAAQ;AACN,iBAAW,CAAC,SAAS;AAAA,IACvB;AAEA,UAAM,QAAQ,MAAM,GAAG,UAAU,EAAE,KAAK,OAAO,WAAW,KAAK,CAAC;AAChE,QAAI,MAAM,WAAW,GAAG;AACtB,cAAQ,MAAM,uBAAuB,SAAS,EAAE;AAChD,cAAQ,KAAK,CAAC;AAAA,IAChB;AAEA,UAAM,SAAS;AACf,IAAAF,WAAU,QAAQ,EAAE,WAAW,KAAK,CAAC;AAErC,UAAM,QAAQ;AAAA,MACZ,SAAS,EAAE,OAAO,GAAG,QAAQ,GAAG,cAAc,EAAE;AAAA,MAChD,OAAO,CAAC;AAAA,IACV;AAEA,eAAW,KAAK,OAAO;AACrB,YAAM,UAAUD,cAAa,GAAG,MAAM;AAGtC,YAAM,SAAS,oBAAoB,OAAO;AAC1C,iBAAW,SAAS,QAAQ;AAC1B,cAAM,OAAO,aAAa,MAAM,WAAW,MAAM,MAAM,CAAC;AAGxD,cAAM,OAAO,SAAS,CAAC,EAAE,QAAQ,aAAa,EAAE;AAChD,cAAM,UAAU,KAAK,MAAM,KAAK,OAAO,QAAQ,YAAY,GAAG;AAC9D,cAAM,UAAUI,MAAK,QAAQ,GAAG,IAAI,IAAI,MAAM,OAAO;AAErD,QAAAF,eAAc,SAAS,KAAK,UAAU,MAAM,MAAM,CAAC,CAAC;AAEpD,cAAM,QAAQ;AACd,cAAM,QAAQ;AACd,YAAI,KAAK,aAAc,OAAM,QAAQ;AACrC,cAAM,MAAM,KAAK,EAAE,MAAM,GAAG,YAAY,SAAS,QAAQ,KAAK,eAAe,YAAY,KAAK,CAAC;AAAA,MACjG;AAAA,IACF;AAEA,IAAAA,eAAcE,MAAK,QAAQ,aAAa,GAAG,KAAK,UAAU,OAAO,MAAM,CAAC,CAAC;AAEzE,QAAI,KAAK,WAAW,OAAO;AACzB,YAAM,QAAQ;AAAA,QACZ;AAAA,QACA;AAAA,QACA,gBAAgB,MAAM,QAAQ,KAAK,cAAc,MAAM,QAAQ,MAAM,qBAAqB,MAAM,QAAQ,YAAY;AAAA,QACpH;AAAA,QACA;AAAA,QACA;AAAA,QACA,GAAG,MAAM,MAAM,IAAI,OAAK,KAAK,EAAE,IAAI,MAAM,EAAE,UAAU,MAAM,EAAE,MAAM,IAAI;AAAA,MACzE;AACA,MAAAH,WAAU,qBAAqB,EAAE,WAAW,KAAK,CAAC;AAClD,MAAAC,eAAc,yCAAyC,MAAM,KAAK,IAAI,CAAC;AAAA,IACzE;AAEA,YAAQ,IAAI,qBAAgB,MAAM,QAAQ,MAAM,+CAA0C;AAE1F,QAAI,KAAK,QAAQ;AACf,YAAM,EAAE,IAAI,IAAI,MAAM,OAAO,mBAAU;AACvC,YAAM,IAAI,EAAE,MAAM,KAAK,QAAQ,MAAM,KAAK,kBAAkB,CAAC;AAAA,IAC/D;AAAA,EACF,CAAC;AAEH,SAAO;AACT;;;AC5RA,SAAS,WAAAI,gBAAe;AACxB,SAAS,aAAa;AAEf,SAAS,UAAU;AACxB,QAAM,MAAM,IAAIA,SAAQ,MAAM,EAC3B,YAAY,gDAAgD,EAC5D,mBAAmB,IAAI,EACvB,qBAAqB,IAAI,EACzB,SAAS,eAAe,yCAAyC,EACjE,OAAO,CAAC,SAAmB,CAAC,MAAM;AACjC,UAAM,QAAQ;AAAA,MACZ;AAAA,MACA,CAAC,cAAc,QAAQ,GAAG,MAAM;AAAA,MAChC;AAAA,QACE,OAAO;AAAA,QACP,OAAO,QAAQ,aAAa;AAAA;AAAA,MAC9B;AAAA,IACF;AAEA,UAAM,GAAG,QAAQ,CAAC,SAAS;AACzB,cAAQ,KAAK,QAAQ,CAAC;AAAA,IACxB,CAAC;AAAA,EACH,CAAC;AAEH,SAAO;AACT;;;ACzBA,SAAS,WAAAC,gBAAe;AACxB,SAAS,aAAAC,YAAW,iBAAAC,sBAAqB;AACzC,SAAS,QAAAC,aAAY;AACrB,SAAS,uBAAuB;AAChC,SAAS,SAAS,OAAO,UAAU,cAAc;;;ACFjD,IAAM,aAA4D;AAAA,EAChE,EAAE,UAAU,CAAC,SAAS,WAAW,UAAU,QAAQ,gBAAgB,GAAG,QAAQ,OAAO;AAAA,EACrF,EAAE,UAAU,CAAC,aAAa,MAAM,GAAG,QAAQ,OAAO;AAAA,EAClD,EAAE,UAAU,CAAC,WAAW,SAAS,GAAG,QAAQ,OAAO;AAAA,EACnD,EAAE,UAAU,CAAC,QAAQ,QAAQ,GAAG,QAAQ,OAAO;AAAA,EAC/C,EAAE,UAAU,CAAC,YAAY,WAAW,KAAK,GAAG,QAAQ,MAAM;AAAA,EAC1D,EAAE,UAAU,CAAC,SAAS,QAAQ,GAAG,QAAQ,MAAM;AAAA,EAC/C,EAAE,UAAU,CAAC,YAAY,eAAe,QAAQ,GAAG,QAAQ,MAAM;AACnE;AAEA,SAAS,cAAc,MAAsB;AAC3C,SAAO,KAAK,YAAY,EAAE,KAAK;AACjC;AAEA,SAAS,mBAAmB,MAAkC;AAC5D,QAAM,OAAO,cAAc,IAAI;AAC/B,aAAW,SAAS,YAAY;AAC9B,QAAI,MAAM,SAAS,KAAK,OAAK,KAAK,SAAS,CAAC,CAAC,GAAG;AAC9C,aAAO,MAAM;AAAA,IACf;AAAA,EACF;AAEA,QAAM,YAAY,KAAK,MAAM,KAAK,EAAE,KAAK,OAAK,WAAW,KAAK,CAAC,CAAC;AAChE,MAAI,CAAC,UAAW,QAAO;AACvB,SAAO,UAAU,QAAQ,eAAe,EAAE,EAAE,MAAM,GAAG,CAAC,EAAE,YAAY,KAAK;AAC3E;AAEA,SAAS,cAAc,KAAiC;AACtD,MAAI;AACF,UAAM,IAAI,IAAI,IAAI,GAAG;AACrB,UAAM,WAAW,EAAE,SAAS,MAAM,GAAG,EAAE,OAAO,OAAO;AACrD,UAAM,OAAO,SAAS,SAAS,SAAS,CAAC,KAAK;AAC9C,QAAI,CAAC,KAAM,QAAO;AAClB,WAAO,mBAAmB,IAAI;AAAA,EAChC,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEO,SAAS,YAAY,QAIjB;AAET,MAAI,OAAO,gBAAgB;AACzB,WAAO,OAAO,eAAe,KAAK,EAAE,YAAY;AAAA,EAClD;AAGA,MAAI,OAAO,aAAa;AACtB,UAAM,cAAc,mBAAmB,OAAO,WAAW;AACzD,QAAI,YAAa,QAAO;AAAA,EAC1B;AAGA,MAAI,OAAO,KAAK;AACd,UAAM,UAAU,cAAc,OAAO,GAAG;AACxC,QAAI,QAAS,QAAO;AAAA,EACtB;AAGA,SAAO;AACT;;;ACnDA,SAAS,qBAA6B;AACpC,SAAO;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,EA2BP,KAAK;AACP;AAEA,SAAS,iBAAiB,KAA0B;AAClD,QAAM,QAAkB,CAAC;AAEzB,QAAM,KAAK,4BAA4B;AACvC,QAAM,KAAK,IAAI,kBAAkB,KAAK;AACtC,QAAM,KAAK,EAAE;AAEb,QAAM,KAAK,0BAA0B;AACrC,QAAM,KAAK,IAAI,OAAO;AACtB,QAAM,KAAK,EAAE;AAEb,MAAI,IAAI,KAAK;AACX,UAAM,KAAK,aAAa,IAAI,GAAG,EAAE;AACjC,UAAM,KAAK,EAAE;AAAA,EACf;AAEA,MAAI,IAAI,aAAa;AACnB,UAAM,IAAI,IAAI;AACd,UAAM,KAAK,qBAAqB;AAEhC,QAAI,EAAE,MAAO,OAAM,KAAK,iBAAiB,EAAE,KAAK,EAAE;AAElD,QAAI,EAAE,SAAS,QAAQ;AACrB,YAAM,KAAK,eAAe,EAAE,SAAS,KAAK,KAAK,CAAC,EAAE;AAAA,IACpD;AAEA,QAAI,EAAE,OAAO,QAAQ;AACnB,YAAM,aAAa,EAAE,OAAO,IAAI,OAAK;AACnC,cAAM,QAAQ;AAAA,UACZ,EAAE,SAAS,UAAU,EAAE,KAAK;AAAA,UAC5B,EAAE,eAAe,gBAAgB,EAAE,WAAW;AAAA,UAC9C,EAAE,QAAQ,SAAS,EAAE,IAAI;AAAA,UACzB,EAAE,QAAQ,EAAE,SAAS,UAAU,SAAS,EAAE,IAAI;AAAA,UAC9C,EAAE,UAAU,gBAAgB,EAAE,MAAM;AAAA,QACtC,EAAE,OAAO,OAAO;AAChB,eAAO,MAAM,KAAK,IAAI;AAAA,MACxB,CAAC;AACD,YAAM,KAAK,kBAAkB,WAAW,KAAK,KAAK,CAAC,EAAE;AAAA,IACvD;AAEA,QAAI,EAAE,QAAQ,QAAQ;AACpB,YAAM,KAAK,cAAc,EAAE,QAAQ,KAAK,KAAK,CAAC,EAAE;AAAA,IAClD;AAEA,QAAI,EAAE,MAAM,QAAQ;AAClB,YAAM,KAAK,YAAY,EAAE,MAAM,MAAM,GAAG,EAAE,EAAE,KAAK,KAAK,CAAC,EAAE;AAAA,IAC3D;AAEA,UAAM,KAAK,EAAE;AAAA,EACf;AAEA,QAAM,KAAK,mBAAmB,IAAI,MAAM,EAAE;AAC1C,QAAM,KAAK,yBAAyB,OAAO,IAAI,UAAU,EAAE,SAAS,GAAG,GAAG,CAAC,EAAE;AAC7E,QAAM,KAAK,yBAAyB,IAAI,QAAQ,EAAE;AAClD,QAAM,KAAK,EAAE;AACb,QAAM,KAAK,6EAA6E;AACxF,QAAM,KAAK,0DAA0D;AAErE,SAAO,MAAM,KAAK,IAAI;AACxB;AAMA,SAAS,iBAKP;AAEA,QAAM,eACJ,QAAQ,IAAI,qBACZ,QAAQ,IAAI,wBACZ;AAGF,QAAM,YACJ,QAAQ,IAAI,kBACZ,QAAQ,IAAI,kBACZ;AAGF,QAAM,oBAAoB,QAAQ,IAAI,mBAAmB,IAAI,YAAY;AAEzE,MAAI,qBAAqB,eAAgB,gBAAgB,qBAAqB,UAAW;AACvF,QAAI,CAAC,cAAc;AACjB,YAAM,IAAI;AAAA,QACR;AAAA,MAEF;AAAA,IACF;AACA,WAAO;AAAA,MACL,UAAU;AAAA,MACV,QAAQ;AAAA,MACR,OAAO,QAAQ,IAAI,gBAAgB;AAAA,MACnC,SAAS;AAAA,IACX;AAAA,EACF;AAEA,MAAI,WAAW;AACb,WAAO;AAAA,MACL,UAAU;AAAA,MACV,QAAQ;AAAA,MACR,OAAO,QAAQ,IAAI,gBAAgB;AAAA,MACnC,SAAS,QAAQ,IAAI,mBAAmB;AAAA,IAC1C;AAAA,EACF;AAEA,QAAM,IAAI;AAAA,IACR;AAAA,EAIF;AACF;AAIA,eAAe,cACb,QACA,OACA,QACA,MACiB;AACjB,QAAM,WAAW,MAAM,MAAM,yCAAyC;AAAA,IACpE,QAAQ;AAAA,IACR,SAAS;AAAA,MACP,aAAa;AAAA,MACb,qBAAqB;AAAA,MACrB,gBAAgB;AAAA,IAClB;AAAA,IACA,MAAM,KAAK,UAAU;AAAA,MACnB;AAAA,MACA,YAAY;AAAA,MACZ;AAAA,MACA,UAAU,CAAC,EAAE,MAAM,QAAQ,SAAS,KAAK,CAAC;AAAA,IAC5C,CAAC;AAAA,EACH,CAAC;AAED,MAAI,CAAC,SAAS,IAAI;AAChB,UAAM,OAAO,MAAM,SAAS,KAAK;AACjC,UAAM,IAAI,MAAM,uBAAuB,SAAS,MAAM,KAAK,IAAI,EAAE;AAAA,EACnE;AAEA,QAAM,OAAY,MAAM,SAAS,KAAK;AACtC,QAAM,UAAU,KAAK,UAAU,CAAC,GAAG,MAAM,KAAK,KAAK;AACnD,MAAI,CAAC,QAAS,OAAM,IAAI,MAAM,mCAAmC;AACjE,SAAO;AACT;AAIA,eAAe,WACb,QACA,OACA,SACA,QACA,MACiB;AACjB,QAAM,WAAW,MAAM,MAAM,GAAG,OAAO,qBAAqB;AAAA,IAC1D,QAAQ;AAAA,IACR,SAAS;AAAA,MACP,eAAe,UAAU,MAAM;AAAA,MAC/B,gBAAgB;AAAA,IAClB;AAAA,IACA,MAAM,KAAK,UAAU;AAAA,MACnB;AAAA,MACA,aAAa;AAAA,MACb,UAAU;AAAA,QACR,EAAE,MAAM,UAAU,SAAS,OAAO;AAAA,QAClC,EAAE,MAAM,QAAQ,SAAS,KAAK;AAAA,MAChC;AAAA,IACF,CAAC;AAAA,EACH,CAAC;AAED,MAAI,CAAC,SAAS,IAAI;AAChB,UAAM,OAAO,MAAM,SAAS,KAAK;AACjC,UAAM,IAAI,MAAM,oBAAoB,SAAS,MAAM,KAAK,IAAI,EAAE;AAAA,EAChE;AAEA,QAAM,OAAY,MAAM,SAAS,KAAK;AACtC,QAAM,UAAU,KAAK,UAAU,CAAC,GAAG,SAAS,SAAS,KAAK,KAAK;AAC/D,MAAI,CAAC,QAAS,OAAM,IAAI,MAAM,gCAAgC;AAC9D,SAAO;AACT;AAIA,eAAsB,yBAAyB,KAAmC;AAChF,QAAM,EAAE,UAAU,QAAQ,OAAO,QAAQ,IAAI,eAAe;AAE5D,QAAM,SAAS,mBAAmB;AAClC,QAAM,OAAS,iBAAiB,GAAG;AAEnC,UAAQ,IAAI,mBAAY,aAAa,cAAc,WAAW,mBAAmB,KAAK,KAAK,GAAG;AAE9F,MAAI,aAAa,aAAa;AAC5B,WAAO,cAAc,QAAQ,OAAO,QAAQ,IAAI;AAAA,EAClD;AACA,SAAO,WAAW,QAAQ,OAAO,SAAS,QAAQ,IAAI;AACxD;;;ACzMA,eAAsB,gBACpB,YACA,UAAiC,CAAC,GACT;AACzB,QAAM,EAAE,UAAU,MAAM,IAAI;AAC5B,QAAM,EAAE,UAAU,aAAa,QAAQ,OAAO,QAAQ,IAAIC,gBAAe;AAEzE,MAAI,SAAS;AAAA,+BAAkC,WAAW,KAAK,KAAK,GAAG;AAEvE,QAAM,eAAe,kBAAkB;AACvC,QAAM,aAAa,gBAAgB,UAAU;AAE7C,QAAM,cAAc,aAAa,cAC7B,MAAMC,eAAc,QAAQ,OAAO,cAAc,UAAU,IAC3D,MAAMC,YAAW,QAAQ,OAAO,WAAW,6BAA6B,cAAc,UAAU;AAEpG,QAAM,SAAS,kBAAkB,WAAW;AAC5C,SAAO,iBAAiB,QAAQ,UAAU;AAC5C;AAEA,SAASF,kBAAiC;AACxC,QAAM,oBAAoB,QAAQ,IAAI,mBAAmB,IAAI,YAAY;AAEzE,QAAM,YAAkD;AAAA,IACtD,UAAU;AAAA,MACR,UAAU;AAAA,MACV,aAAa;AAAA,MACb,QAAQ,QAAQ,IAAI,oBAAoB,QAAQ,IAAI,uBAAuB;AAAA,MAC3E,OAAO,QAAQ,IAAI,gBAAgB,QAAQ,IAAI,kBAAkB;AAAA,MACjE,SAAS,QAAQ,IAAI,qBAAqB;AAAA,IAC5C;AAAA,IACA,WAAW;AAAA,MACT,UAAU;AAAA,MACV,aAAa;AAAA,MACb,QAAQ,QAAQ,IAAI,qBAAqB,QAAQ,IAAI,wBAAwB;AAAA,MAC7E,OAAO,QAAQ,IAAI,gBAAgB,QAAQ,IAAI,mBAAmB;AAAA,IACpE;AAAA,IACA,QAAQ;AAAA,MACN,UAAU;AAAA,MACV,aAAa;AAAA,MACb,QAAQ,QAAQ,IAAI,kBAAkB,QAAQ,IAAI,kBAAkB;AAAA,MACpE,OAAO,QAAQ,IAAI,gBAAgB,QAAQ,IAAI,gBAAgB;AAAA,MAC/D,SAAS,QAAQ,IAAI,mBAAmB;AAAA,IAC1C;AAAA,IACA,MAAM;AAAA,MACJ,UAAU;AAAA,MACV,aAAa;AAAA,MACb,QAAQ,QAAQ,IAAI,gBAAgB;AAAA,MACpC,OAAO,QAAQ,IAAI,gBAAgB,QAAQ,IAAI,cAAc;AAAA,MAC7D,SAAS,QAAQ,IAAI,iBAAiB;AAAA,IACxC;AAAA,IACA,MAAM;AAAA,MACJ,UAAU;AAAA,MACV,aAAa;AAAA,MACb,QAAQ,QAAQ,IAAI,gBAAgB,QAAQ,IAAI,oBAAoB;AAAA,MACpE,OAAO,QAAQ,IAAI,gBAAgB,QAAQ,IAAI,cAAc;AAAA,MAC7D,SAAS,QAAQ,IAAI,iBAAiB;AAAA,IACxC;AAAA,IACA,QAAQ;AAAA,MACN,UAAU;AAAA,MACV,aAAa;AAAA,MACb,QAAQ,QAAQ,IAAI,kBAAkB,QAAQ,IAAI,kBAAkB;AAAA,MACpE,OAAO,QAAQ,IAAI,gBAAgB,QAAQ,IAAI,gBAAgB;AAAA,MAC/D,SAAS,QAAQ,IAAI,mBAAmB;AAAA,IAC1C;AAAA,EACF;AAEA,MAAI,kBAAkB;AACpB,QAAI,EAAE,oBAAoB,YAAY;AACpC,YAAM,IAAI,MAAM,gCAAgC,gBAAgB,4DAA4D;AAAA,IAC9H;AAEA,UAAM,WAAW,UAAU,gBAAgC;AAC3D,QAAI,CAAC,SAAS,QAAQ;AACpB,YAAM,IAAI,MAAM,mBAAmB,gBAAgB,8CAA8C;AAAA,IACnG;AACA,WAAO;AAAA,EACT;AAEA,aAAW,gBAAgB,CAAC,YAAY,aAAa,UAAU,QAAQ,QAAQ,QAAQ,GAAY;AACjG,QAAI,UAAU,YAAY,EAAE,OAAQ,QAAO,UAAU,YAAY;AAAA,EACnE;AAEA,QAAM,IAAI;AAAA,IACR;AAAA,EAOF;AACF;AAEA,SAAS,oBAA4B;AACnC,SAAO;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;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GAiDN,KAAK;AACR;AAEA,SAAS,gBAAgB,YAAgC;AACvD,QAAM,QAAkB,CAAC;AAEzB,QAAM,KAAK,kBAAkB;AAC7B,QAAM,KAAK,QAAQ,WAAW,GAAG,EAAE;AACnC,QAAM,KAAK,UAAU,WAAW,KAAK,EAAE;AACvC,QAAM,KAAK,gBAAgB,WAAW,IAAI,OAAO;AACjD,QAAM,KAAK,EAAE;AAEb,aAAW,YAAY,CAAC,SAAS,UAAU,QAAQ,WAAW,QAAQ,GAAY;AAChF,UAAM,QAAQ,WAAW,SAAS,OAAO,CAAC,YAAY,QAAQ,aAAa,QAAQ;AACnF,QAAI,MAAM,WAAW,EAAG;AAExB,UAAM,KAAK,GAAG,SAAS,YAAY,CAAC,MAAM,MAAM,MAAM,UAAU;AAChE,eAAW,QAAQ,MAAM,MAAM,GAAG,aAAa,SAAS,KAAK,MAAM,MAAM,GAAG;AAC1E,YAAM,KAAK,QAAQ,KAAK,UAAU,KAAK,KAAK,QAAQ,EAAE;AACtD,YAAM,KAAK,gBAAgB,KAAK,OAAO,EAAE;AACzC,UAAI,KAAK,YAAY,SAAS,GAAG;AAC/B,cAAM,KAAK,kBAAkB,KAAK,YAAY,MAAM,GAAG,CAAC,EAAE,KAAK,KAAK,CAAC,EAAE;AAAA,MACzE;AAAA,IACF;AACA,UAAM,KAAK,EAAE;AAAA,EACf;AAEA,MAAI,WAAW,SAAS,SAAS,GAAG;AAClC,UAAM,KAAK,mBAAmB;AAC9B,eAAW,WAAW,WAAW,UAAU;AACzC,YAAM,KAAK,OAAO,OAAO,EAAE;AAAA,IAC7B;AACA,UAAM,KAAK,EAAE;AAAA,EACf;AAEA,QAAM,mBAAmB,WAAW,SAAS,OAAO,CAAC,YACnD,QAAQ,aAAa,WAAW,QAAQ,aAAa,YAAY,QAAQ,aAAa,MACvF,EAAE;AACH,QAAM,cAAc,WAAW,SAAS,OAAO,CAAC,YAAY,QAAQ,aAAa,QAAQ,EAAE;AAE3F,QAAM,KAAK,uBAAuB;AAClC,QAAM,KAAK,sCAAsC,gBAAgB,EAAE;AACnE,QAAM,KAAK,yCAAyC,WAAW,EAAE;AACjE,QAAM,KAAK,qFAAqF;AAChG,QAAM,KAAK,wFAAwF;AACnG,QAAM,KAAK,EAAE;AACb,QAAM,KAAK,kCAAkC;AAE7C,SAAO,MAAM,KAAK,IAAI;AACxB;AAEA,eAAeC,eACb,QACA,OACA,cACA,YACiB;AACjB,QAAM,WAAW,MAAM,MAAM,yCAAyC;AAAA,IACpE,QAAQ;AAAA,IACR,SAAS;AAAA,MACP,aAAa;AAAA,MACb,qBAAqB;AAAA,MACrB,gBAAgB;AAAA,IAClB;AAAA,IACA,MAAM,KAAK,UAAU;AAAA,MACnB;AAAA,MACA,YAAY;AAAA,MACZ,QAAQ;AAAA,MACR,UAAU,CAAC,EAAE,MAAM,QAAQ,SAAS,WAAW,CAAC;AAAA,IAClD,CAAC;AAAA,EACH,CAAC;AAED,MAAI,CAAC,SAAS,IAAI;AAChB,UAAM,IAAI,MAAM,iBAAiB,SAAS,MAAM,KAAK,MAAM,SAAS,KAAK,CAAC,EAAE;AAAA,EAC9E;AAEA,QAAM,OAAY,MAAM,SAAS,KAAK;AACtC,QAAM,UAAU,KAAK,UAAU,CAAC,GAAG,MAAM,KAAK,KAAK;AACnD,MAAI,CAAC,QAAS,OAAM,IAAI,MAAM,kCAAkC;AAChE,SAAO;AACT;AAEA,eAAeC,YACb,QACA,OACA,SACA,cACA,YACiB;AACjB,QAAM,WAAW,MAAM,MAAM,GAAG,OAAO,qBAAqB;AAAA,IAC1D,QAAQ;AAAA,IACR,SAAS;AAAA,MACP,eAAe,UAAU,MAAM;AAAA,MAC/B,gBAAgB;AAAA,IAClB;AAAA,IACA,MAAM,KAAK,UAAU;AAAA,MACnB;AAAA,MACA,aAAa;AAAA,MACb,UAAU;AAAA,QACR,EAAE,MAAM,UAAU,SAAS,aAAa;AAAA,QACxC,EAAE,MAAM,QAAQ,SAAS,WAAW;AAAA,MACtC;AAAA,IACF,CAAC;AAAA,EACH,CAAC;AAED,MAAI,CAAC,SAAS,IAAI;AAChB,UAAM,IAAI,MAAM,cAAc,SAAS,MAAM,KAAK,MAAM,SAAS,KAAK,CAAC,EAAE;AAAA,EAC3E;AAEA,QAAM,OAAY,MAAM,SAAS,KAAK;AACtC,QAAM,UAAU,KAAK,UAAU,CAAC,GAAG,SAAS,SAAS,KAAK,KAAK;AAC/D,MAAI,CAAC,QAAS,OAAM,IAAI,MAAM,mDAAmD;AACjF,SAAO;AACT;AAEA,SAAS,kBAAkB,KAA6B;AACtD,QAAM,WAAW,IACd,QAAQ,qBAAqB,EAAE,EAC/B,QAAQ,eAAe,EAAE,EACzB,KAAK;AAER,MAAI;AACF,WAAO,KAAK,MAAM,QAAQ;AAAA,EAC5B,SAAS,OAAY;AACnB,UAAM,IAAI;AAAA,MACR;AAAA,eAAuD,OAAO,WAAW,KAAK;AAAA;AAAA,EAAoB,IAAI,MAAM,GAAG,GAAG,CAAC;AAAA,IACrH;AAAA,EACF;AACF;AAEA,SAAS,iBAAiB,UAA0B,YAAwC;AAC1F,QAAM,YAAY,IAAI,IAAI,WAAW,SAAS,IAAI,CAAC,YAAY,QAAQ,QAAQ,CAAC;AAChF,QAAM,eAAe,MAAM,QAAQ,SAAS,SAAS,IAAI,SAAS,YAAY,CAAC;AAC/E,QAAM,aAAa,IAAI,IAAI,WAAW,GAAG;AACzC,QAAM,aAAa,oBAAI,IAAI;AAAA,IACzB,WAAW;AAAA,IACX,GAAG,WAAW,SACX,OAAO,CAAC,YAAY,QAAQ,aAAa,MAAM,EAC/C,IAAI,CAAC,YAAY;AAChB,YAAM,OAAO,QAAQ,YAAY;AACjC,UAAI,OAAO,SAAS,SAAU,QAAO;AACrC,UAAI;AACF,eAAO,IAAI,IAAI,MAAM,WAAW,GAAG,EAAE;AAAA,MACvC,QAAQ;AACN,eAAO;AAAA,MACT;AAAA,IACF,CAAC,EACA,OAAO,OAAO;AAAA,EACnB,CAAC;AAED,QAAM,qBAAqB,aACxB,IAAI,CAAC,aAAa,kBAAkB,UAAU,SAAS,CAAC,EACxD,OAAO,CAAC,aAAa,SAAS,MAAM,SAAS,KAAK,SAAS,WAAW,SAAS,CAAC,EAChF,IAAI,CAAC,cAAc;AAAA,IAClB,GAAG;AAAA,IACH,MAAM,SAAS,KAAK,IAAI,YAAY;AAAA,IACpC,YAAY,SAAS,WAAW,OAAO,CAAC,cAAc;AACpD,UAAI,UAAU,SAAS,MAAO,QAAO;AACrC,YAAM,WAAW,GAAG,UAAU,QAAQ,IAAI,UAAU,KAAK,IAAI,UAAU,UAAU;AACjF,YAAM,YAAY,SAAS,MAAM,iBAAiB;AAClD,UAAI,CAAC,UAAW,QAAO;AACvB,aAAO,WAAW,IAAI,UAAU,CAAC,CAAC;AAAA,IACpC,CAAC;AAAA,EACH,EAAE,EACD,OAAO,CAAC,aAAa,SAAS,WAAW,SAAS,CAAC,EACnD,MAAM,GAAG,CAAC;AAEb,QAAM,iBAAiB,mBAAmB,SAAS,IAC/C,qBACA,uBAAuB,YAAY,SAAS,mBAAmB,MAAM;AAEzE,SAAO;AAAA,IACL,GAAG;AAAA,IACH,KAAK,SAAS,OAAO,WAAW;AAAA,IAChC,SAAS,SAAS,WAAW,iBAAiB,UAAU;AAAA,IACxD,kBAAkB,SAAS,mBAAmBC,aAAY,UAAU,GAAG,YAAY;AAAA,IACnF,WAAW;AAAA,IACX,eAAe;AAAA,MACb,SAAS;AAAA,MACT,gBAAgB,eAAe,MAAM,qCAAqC,aAAa,MAAM;AAAA,IAC/F,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG;AAAA,IAC1B,cAAc,SAAS,gBAAgB,kBAAkB,SAAS,WAAW,iBAAiB,UAAU,GAAG,cAAc;AAAA,EAC3H;AACF;AAEA,SAAS,kBAAkB,WAAgB,WAA0C;AACnF,SAAO;AAAA,IACL,IAAI,WAAW,MAAM;AAAA,IACrB,OAAO,WAAW,SAAS;AAAA,IAC3B,MAAM,MAAM,QAAQ,WAAW,IAAI,IAAI,UAAU,OAAO,CAAC;AAAA,IACzD,OAAO,MAAM,QAAQ,WAAW,KAAK,IACjC,UAAU,MAAM,OAAO,CAAC,SAAc,MAAM,aAAa,UAAU,UAAU,IAAI,MAAM,QAAQ,CAAC,IAChG,CAAC;AAAA,IACL,YAAY,MAAM,QAAQ,WAAW,UAAU,IAC3C,UAAU,WAAW,OAAO,CAAC,cAAmB,WAAW,aAAa,UAAU,UAAU,IAAI,WAAW,QAAQ,CAAC,IACpH,CAAC;AAAA,IACL,UAAU,WAAW,YAAY;AAAA,IACjC,WAAW,WAAW,aAAa;AAAA,EACrC;AACF;AAEA,SAAS,uBAAuB,YAAwB,QAAoC;AAC1F,QAAM,UAAU,WAAW,SAAS,KAAK,CAAC,YAAY,QAAQ,aAAa,SAAS;AACpF,QAAM,aAAa,WAAW,SAAS,KAAK,CAAC,YAC3C,QAAQ,aAAa,YACpB,QAAQ,WAAW,SAAS,WAAW,QAAQ,KAAK,GAAG,QAAQ,QAAQ,EAAE,IAAI,OAAO,QAAQ,WAAW,SAAS,EAAE,CAAC,GAAG,YAAY,CAAC,EACrI;AACD,QAAM,gBAAgB,WAAW,SAAS,KAAK,CAAC,YAC9C,QAAQ,aAAa,WAAW,QAAQ,WAAW,SAAS,UAC7D;AACD,QAAM,eAAe,WAAW,SAAS,KAAK,CAAC,YAC7C,QAAQ,aAAa,YAAY,iCAAiC,KAAK,QAAQ,QAAQ,EAAE,CAC1F,KAAK,WAAW,SAAS,KAAK,CAAC,YAAY,QAAQ,aAAa,QAAQ;AAEzE,QAAM,YAAgC,CAAC;AACvC,QAAM,MAAM,CAAC,UAAkB,aAAa,KAAK;AACjD,QAAM,SAAS,CAAC,UAAkB,GAAG,MAAM,IAAI,OAAO,MAAM,KAAK,EAAE,SAAS,GAAG,GAAG,CAAC;AAEnF,MAAI,SAAS;AACX,cAAU,KAAK;AAAA,MACb,IAAI,OAAO,UAAU,SAAS,CAAC;AAAA,MAC/B,OAAO;AAAA,MACP,MAAM,CAAC,IAAI,OAAO,GAAG,IAAI,WAAW,CAAC;AAAA,MACrC,OAAO;AAAA,QACL;AAAA,UACE,QAAQ;AAAA,UACR,UAAU;AAAA,UACV,OAAO,WAAW;AAAA,UAClB,OAAO;AAAA,QACT;AAAA,MACF;AAAA,MACA,YAAY;AAAA,QACV;AAAA,UACE,MAAM;AAAA,UACN,UAAU,QAAQ;AAAA,UAClB,UAAU;AAAA,UACV,OAAO,GAAG,QAAQ,QAAQ,iBAAiB;AAAA,UAC3C,YAAY,qBAAqB,QAAQ,QAAQ;AAAA,QACnD;AAAA,MACF;AAAA,MACA,UAAU;AAAA,MACV,WAAW;AAAA,IACb,CAAC;AAAA,EACH;AAEA,MAAI,cAAc,iBAAiB,cAAc;AAC/C,cAAU,KAAK;AAAA,MACb,IAAI,OAAO,UAAU,SAAS,CAAC;AAAA,MAC/B,OAAO;AAAA,MACP,MAAM,CAAC,IAAI,YAAY,GAAG,IAAI,UAAU,CAAC;AAAA,MACzC,OAAO;AAAA,QACL;AAAA,UACE,QAAQ;AAAA,UACR,UAAU;AAAA,UACV,OAAO,WAAW;AAAA,UAClB,OAAO;AAAA,QACT;AAAA,QACA;AAAA,UACE,QAAQ;AAAA,UACR,UAAU,WAAW;AAAA,UACrB,OAAO;AAAA,UACP,OAAO;AAAA,QACT;AAAA,QACA;AAAA,UACE,QAAQ;AAAA,UACR,UAAU,aAAa;AAAA,UACvB,OAAO;AAAA,UACP,OAAO;AAAA,QACT;AAAA,MACF;AAAA,MACA,YAAY;AAAA,QACV;AAAA,UACE,MAAM;AAAA,UACN,UAAU;AAAA,UACV,UAAU,IAAI,IAAI,WAAW,GAAG,EAAE;AAAA,UAClC,OAAO;AAAA,UACP,YAAY,iCAAiC,WAAW,GAAG;AAAA,QAC7D;AAAA,QACA;AAAA,UACE,MAAM;AAAA,UACN,UAAU,cAAc;AAAA,UACxB,UAAU;AAAA,UACV,OAAO;AAAA,UACP,YAAY,qBAAqB,cAAc,QAAQ;AAAA,QACzD;AAAA,MACF;AAAA,MACA,UAAU;AAAA,MACV,WAAW;AAAA,IACb,CAAC;AAAA,EACH;AAEA,SAAO,UAAU,MAAM,GAAG,CAAC;AAC7B;AAEA,SAAS,iBAAiB,YAAgC;AACxD,QAAM,UAAU,WAAW,SAAS,KAAK,CAAC,YAAY,QAAQ,aAAa,aAAa,QAAQ,IAAI;AACpG,SAAO,SAAS,QAAQ,WAAW,SAAS;AAC9C;AAEA,SAASA,aAAY,YAAgC;AACnD,QAAM,SAAS,GAAG,WAAW,KAAK,IAAI,WAAW,GAAG,GAAG,YAAY;AACnE,MAAI,uBAAuB,KAAK,MAAM,EAAG,QAAO;AAChD,MAAI,0BAA0B,KAAK,MAAM,EAAG,QAAO;AACnD,MAAI,cAAc,KAAK,MAAM,EAAG,QAAO;AACvC,SAAO;AACT;AAEA,SAAS,kBAAkB,SAAiB,WAAuC;AACjF,SAAO,0BAA0B,WAAW,mBAAmB,SAAS,UAAU,MAAM,4BAA4B,UAAU,WAAW,IAAI,KAAK,GAAG;AACvJ;AAEA,SAAS,aAAa,OAAuB;AAC3C,QAAM,UAAU,OAAO,SAAS,EAAE,EAAE,KAAK,EAAE,QAAQ,OAAO,EAAE;AAC5D,SAAO,UAAU,IAAI,OAAO,KAAK;AACnC;AAEA,SAAS,IAAI,SAAkB,SAAuB;AACpD,MAAI,QAAS,SAAQ,IAAI,OAAO;AAClC;;;ACpYA,IAAM,YAAY;AAClB,IAAM,qBAAqB;AAC3B,IAAM,mBAAmB;AAEzB,eAAsB,gBAAgB,KAAa,UAA0B,CAAC,GAAwB;AACpG,QAAM;AAAA,IACJ,WAAW;AAAA,IACX,YAAY;AAAA,IACZ,UAAU;AAAA,IACV,YAAY;AAAA,EACd,IAAI;AAEJ,QAAM,WAAW,MAAM,aAAa;AACpC,QAAM,OAAoB,WAAW,aAAa;AAClD,EAAAC,KAAI,SAAS;AAAA,qBAAwB,IAAI,aAAa,GAAG,EAAE;AAE3D,QAAM,UAAU,MAAM,SAAS,OAAO;AAAA,IACpC;AAAA,IACA,QAAQ,WAAW,IAAI;AAAA,EACzB,CAAC;AAED,QAAM,UAAU,MAAM,QAAQ,WAAW;AAAA,IACvC;AAAA,IACA,UAAU,EAAE,OAAO,MAAM,QAAQ,IAAI;AAAA,IACrC,mBAAmB;AAAA,EACrB,CAAC;AAED,QAAM,OAAO,MAAM,QAAQ,QAAQ;AAEnC,MAAI;AACF,IAAAA,KAAI,SAAS,6BAA6B,SAAS,KAAK;AACxD,UAAM,KAAK,KAAK,KAAK;AAAA,MACnB,WAAW;AAAA,MACX,SAAS;AAAA,IACX,CAAC;AAED,IAAAA,KAAI,SAAS,gBAAgB,SAAS,oBAAoB;AAC1D,UAAM,KAAK,eAAe,SAAS;AAEnC,IAAAA,KAAI,SAAS,wCAAwC;AACrD,UAAM,eAAe,MAAM,yBAAyB,MAAM,OAAO;AAEjE,IAAAA,KAAI,SAAS,0BAA0B;AACvC,UAAM,UAAU,MAAM,KAAK,SAAS,cAAc;AAElD,UAAM,QAAQ,MAAM,KAAK,MAAM;AAC/B,UAAM,WAAW,KAAK,IAAI;AAC1B,UAAM,WAAW,gBAAgB,OAAO;AACxC,UAAM,WAAW,cAAc,UAAU,SAAS,YAAY;AAC9D,UAAM,aAAuD,CAAC;AAE9D,eAAW,WAAW,UAAU;AAC9B,iBAAW,QAAQ,QAAQ,KAAK,WAAW,QAAQ,QAAQ,KAAK,KAAK;AAAA,IACvE;AAEA,UAAM,SAAqB;AAAA,MACzB,KAAK;AAAA,MACL;AAAA,MACA,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,MAClC;AAAA,MACA,SAAS;AAAA,QACP,eAAe,SAAS;AAAA,QACxB;AAAA,MACF;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAEA,IAAAA,KAAI,SAAS,iBAAiB,SAAS,MAAM,4BAA4B,KAAK,GAAG;AACjF,WAAO;AAAA,EACT,UAAE;AACA,UAAM,QAAQ,MAAM;AAAA,EACtB;AACF;AAEO,SAAS,cAAc,YAAqC;AACjE,QAAM,SAAS,WAAW,SACvB,OAAO,CAAC,YAAwC,QAAQ,aAAa,OAAO,EAC5E,MAAM,GAAG,EAAE,EACX,IAAI,CAAC,aAAa;AAAA,IACjB,OAAO,SAAS,QAAQ,WAAW,KAAK;AAAA,IACxC,aAAa,SAAS,QAAQ,WAAW,WAAW;AAAA,IACpD,MAAM,SAAS,QAAQ,WAAW,IAAI;AAAA,IACtC,MAAM,SAAS,QAAQ,WAAW,IAAI;AAAA,IACtC,QAAQ,SAAS,QAAQ,WAAW,MAAM;AAAA,EAC5C,EAAE;AAEJ,SAAO;AAAA,IACL,KAAK,WAAW;AAAA,IAChB,OAAO,WAAW;AAAA,IAClB,UAAU,WAAW,SAClB,OAAO,CAAC,YAAY,QAAQ,aAAa,SAAS,EAClD,IAAI,CAAC,YAAY,QAAQ,QAAQ,EAAE,EACnC,OAAO,OAAO,EACd,MAAM,GAAG,EAAE;AAAA,IACd,SAAS,WAAW,SACjB,OAAO,CAAC,YAAY,QAAQ,aAAa,QAAQ,EACjD,IAAI,CAAC,YAAY,QAAQ,QAAQ,EAAE,EACnC,OAAO,OAAO,EACd,MAAM,GAAG,EAAE;AAAA,IACd,OAAO,WAAW,SACf,OAAO,CAAC,YAAY,QAAQ,aAAa,MAAM,EAC/C,IAAI,CAAC,YAAY,QAAQ,QAAQ,EAAE,EACnC,OAAO,OAAO,EACd,MAAM,GAAG,EAAE;AAAA,IACd;AAAA,IACA,WAAW,CAAC;AAAA,IACZ,WAAW,WAAW,SAAS;AAAA,EACjC;AACF;AAEA,eAAe,eAA6B;AAC1C,MAAI;AACF,YAAQ,MAAM,OAAO,iBAAiB,GAAG;AAAA,EAC3C,QAAQ;AAAA,EAAC;AAET,MAAI;AACF,YAAQ,MAAM,OAAO,kBAAkB,GAAG;AAAA,EAC5C,QAAQ;AAAA,EAAC;AAET,QAAM,IAAI;AAAA,IACR;AAAA,EACF;AACF;AAEA,SAAS,iBAA0B;AACjC,QAAM,sBAAsB;AAC5B,QAAM,OAAO,CAAC,IAAa,SAAqC,GAAG,aAAa,IAAI,GAAG,KAAK,KAAK;AACjG,QAAM,OAAO,CAAC,OAA2C,IAAI,aAAa,QAAQ,QAAQ,GAAG,EAAE,KAAK,KAAK;AACzG,QAAM,WAAW,CAAC,UAAkB,KAAK,UAAU,KAAK;AAExD,QAAM,YAAY,CAAC,OAAoC;AACrD,UAAM,KAAK,KAAK,IAAI,IAAI;AAExB,QAAI,IAAI;AACN,YAAM,UAAU,SAAS,cAAc,cAAc,EAAE,IAAI;AAC3D,UAAI,QAAS,QAAO,KAAK,OAAO;AAAA,IAClC;AAEA,UAAM,YAAY,KAAK,IAAI,YAAY;AACvC,QAAI,UAAW,QAAO;AAEtB,UAAM,aAAa,KAAK,IAAI,iBAAiB;AAC7C,QAAI,YAAY;AACd,YAAM,UAAU,SAAS,eAAe,UAAU;AAClD,UAAI,QAAS,QAAO,KAAK,OAAO;AAAA,IAClC;AAEA,UAAM,eAAe,GAAG,QAAQ,OAAO;AACvC,QAAI,cAAc;AAChB,YAAM,MAAM,KAAK,YAAY,KAAK;AAClC,YAAM,cAAc,KAAK,IAAI,aAAa,KAAK;AAC/C,aAAO,IAAI,QAAQ,aAAa,EAAE,EAAE,KAAK,KAAK;AAAA,IAChD;AAEA,UAAM,WAAW,GAAG;AACpB,QAAI,UAAU,YAAY,QAAS,QAAO,KAAK,QAAQ;AAEvD,WAAO;AAAA,EACT;AAEA,QAAM,gBAAgB,CAAC,IAAa,WAAoB,eAAuC;AAC7F,UAAM,SAAS,KAAK,IAAI,aAAa;AACrC,QAAI,OAAQ,QAAO,eAAe,SAAS,MAAM,CAAC;AAElD,UAAM,KAAK,KAAK,IAAI,IAAI;AACxB,QAAI,MAAM,CAAC,GAAG,MAAM,kCAAkC,GAAG;AACvD,aAAO,WAAW,SAAS,IAAI,EAAE,EAAE,CAAC;AAAA,IACtC;AAEA,UAAM,YAAY,KAAK,IAAI,YAAY;AACvC,QAAI,WAAW;AACb,aAAO,aAAa,SAAS,GAAG,aAAa,MAAM,KAAK,GAAG,QAAQ,YAAY,CAAC,CAAC,aAAa,SAAS,SAAS,CAAC;AAAA,IACnH;AAEA,QAAI,WAAW;AACb,YAAM,MAAM,GAAG,QAAQ,YAAY;AACnC,UAAI,QAAQ,WAAW,QAAQ,cAAc,QAAQ,UAAU;AAC7D,eAAO,cAAc,SAAS,SAAS,CAAC;AAAA,MAC1C;AAAA,IACF;AAEA,QAAI,WAAY,QAAO,+BAA+B,SAAS,UAAU,CAAC;AAE1E,UAAM,OAAO,KAAK,IAAI,MAAM;AAC5B,QAAI,KAAM,QAAO,WAAW,SAAS,UAAU,IAAI,IAAI,CAAC;AAExD,WAAO;AAAA,EACT;AAEA,QAAM,UAAuB,CAAC;AAC9B,WAAS,iBAAiB,qEAAqE,EAAE,QAAQ,CAAC,OAAO;AAC/G,UAAM,aAAa,KAAK,IAAI,YAAY,KAAK,KAAK,EAAE,KAAK,KAAK,IAAI,OAAO;AACzE,UAAM,SAAS,KAAK,IAAI,aAAa;AACrC,UAAM,KAAK,KAAK,IAAI,IAAI;AACxB,UAAM,OAAO,KAAK,IAAI,MAAM;AAC5B,UAAM,WAAW,GAAG,aAAa,UAAU,KAAK,GAAG,aAAa,eAAe,MAAM;AACrF,UAAM,WAAW,cAAc,IAAI,QAAW,UAAU;AAExD,QAAI,cAAc,QAAQ;AACxB,cAAQ,KAAK;AAAA,QACX,KAAK,GAAG,QAAQ,YAAY;AAAA,QAC5B,MAAM;AAAA,QACN;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA,SAAS,SAAS,iBAAiB,MAAM,OAAQ,KAAK,IAAI,EAAE,KAAK;AAAA,MACnE,CAAC;AAAA,IACH;AAAA,EACF,CAAC;AAED,QAAM,SAAqB,CAAC;AAC5B,WAAS,iBAAiB,wFAAwF,EAAE,QAAQ,CAAC,OAAO;AAClI,UAAM,QAAQ,UAAU,EAAE;AAC1B,UAAM,cAAc,KAAK,IAAI,aAAa;AAC1C,UAAM,OAAO,KAAK,IAAI,MAAM;AAC5B,UAAM,KAAK,KAAK,IAAI,IAAI;AACxB,UAAM,OAAO,KAAK,IAAI,MAAM,KAAK,GAAG,QAAQ,YAAY;AACxD,UAAM,SAAS,KAAK,IAAI,aAAa;AACrC,UAAM,WAAW,GAAG,aAAa,UAAU;AAC3C,UAAM,WAAW,cAAc,IAAI,KAAK;AAExC,QAAI,SAAS,eAAe,QAAQ,UAAU,IAAI;AAChD,aAAO,KAAK;AAAA,QACV,KAAK,GAAG,QAAQ,YAAY;AAAA,QAC5B;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA,SAAS,SAAS,iBAAiB,MAAM,OAAQ,KAAK,IAAI,EAAE,KAAM,OAAO,UAAU,IAAI,OAAO;AAAA,MAChG,CAAC;AAAA,IACH;AAAA,EACF,CAAC;AAED,QAAM,QAAmB,CAAC;AAC1B,WAAS,iBAAiB,SAAS,EAAE,QAAQ,CAAC,OAAO;AACnD,UAAM,WAAW,KAAK,IAAI,YAAY,KAAK,KAAK,EAAE;AAClD,UAAM,OAAO,KAAK,IAAI,MAAM;AAC5B,UAAM,SAAS,KAAK,IAAI,aAAa;AAErC,QAAI,CAAC,YAAY,SAAS,IAAK;AAE/B,UAAM,KAAK;AAAA,MACT,MAAM;AAAA,MACN;AAAA,MACA;AAAA,MACA,UAAU,QAAQ,MAAM,WAAW,MAAM,KAAK,CAAC,KAAK,SAAS,OAAO,SAAS,QAAQ,CAAC;AAAA,MACtF,UAAU,SACN,eAAe,SAAS,MAAM,CAAC,MAC/B,6BAA6B,SAAS,QAAQ,CAAC;AAAA,IACrD,CAAC;AAAA,EACH,CAAC;AAED,QAAM,WAAyB,CAAC;AAChC,WAAS,iBAAiB,YAAY,EAAE,QAAQ,CAAC,OAAO;AACtD,UAAM,cAAc,KAAK,EAAE;AAC3B,QAAI,aAAa;AACf,eAAS,KAAK;AAAA,QACZ,OAAO,GAAG,QAAQ,YAAY;AAAA,QAC9B,MAAM;AAAA,QACN,UAAU,gCAAgC,SAAS,WAAW,CAAC;AAAA,MACjE,CAAC;AAAA,IACH;AAAA,EACF,CAAC;AAED,QAAM,YAAoD,CAAC;AAC3D,WAAS,iBAAiB,+DAA+D,EAAE,QAAQ,CAAC,OAAO;AACzG,UAAM,OAAO,KAAK,IAAI,MAAM,KAAK,GAAG,QAAQ,YAAY;AACxD,UAAM,QAAQ,KAAK,IAAI,YAAY,KAAK,KAAK,EAAE,GAAG,MAAM,GAAG,EAAE;AAC7D,QAAI,QAAQ,MAAO,WAAU,KAAK,EAAE,MAAM,MAAM,CAAC;AAAA,EACnD,CAAC;AAED,QAAM,gBAAmC,CAAC;AAC1C,WAAS,iBAAiB,8CAA8C,EAAE,QAAQ,CAAC,OAAO;AACxF,UAAM,OAAO,KAAK,IAAI,MAAM,KAAK;AACjC,kBAAc,KAAK;AAAA,MACjB;AAAA,MACA,UAAU,KAAK,IAAI,WAAW;AAAA,MAC9B,MAAM,KAAK,EAAE;AAAA,MACb,UAAU,GAAG,aAAa,MAAM,IAC5B,aAAa,SAAS,IAAI,CAAC,MAC3B;AAAA,IACN,CAAC;AAAA,EACH,CAAC;AAED,QAAM,QAAmB,CAAC;AAC1B,WAAS,iBAAiB,MAAM,EAAE,QAAQ,CAAC,MAAM,UAAU;AACzD,UAAM,KAAK;AAAA,MACT,IAAI,KAAK,MAAM,IAAI;AAAA,MACnB,OAAO,KAAK,MAAM,YAAY,KAAK,KAAK,MAAM,iBAAiB;AAAA,MAC/D,QAAQ,KAAK,MAAM,QAAQ;AAAA,MAC3B,QAAQ,KAAK,MAAM,QAAQ,KAAK;AAAA,MAChC,YAAY,KAAK,iBAAiB,yBAAyB,EAAE;AAAA,MAC7D;AAAA,IACF,CAAC;AAAA,EACH,CAAC;AAED,SAAO;AAAA,IACL,SAAS,QAAQ,MAAM,GAAG,mBAAmB;AAAA,IAC7C,QAAQ,OAAO,MAAM,GAAG,mBAAmB;AAAA,IAC3C,OAAO,MAAM,MAAM,GAAG,mBAAmB;AAAA,IACzC,UAAU,SAAS,MAAM,GAAG,EAAE;AAAA,IAC9B;AAAA,IACA;AAAA,IACA;AAAA,IACA,SAAS,OAAO,SAAS;AAAA,IACzB,WAAW,SAAS;AAAA,EACtB;AACF;AAEA,SAAS,gBAAgB,SAAqC;AAC5D,QAAM,WAA8B,CAAC;AAErC,aAAWC,UAAS,QAAQ,QAAQ;AAClC,UAAM,cAAcA,OAAM,SAASA,OAAM,eAAeA,OAAM,QAAQA,OAAM;AAC5E,QAAI,CAAC,YAAa;AAElB,UAAM,WAAWA,OAAM,aACjBA,OAAM,SAAS,eAAe,KAAK,UAAUA,OAAM,MAAM,CAAC,MAAM,UAChEA,OAAM,QAAQ,cAAc,KAAK,UAAUA,OAAM,KAAK,CAAC,MAAM,UAC7DA,OAAM,KAAK,WAAW,KAAK,UAAU,IAAIA,OAAM,EAAE,EAAE,CAAC,MAAM,UAC1DA,OAAM,OAAO,WAAW,KAAK,UAAU,UAAUA,OAAM,IAAI,IAAI,CAAC,MAAM,SACvE,WAAW,KAAK,UAAU,GAAGA,OAAM,GAAG,iBAAiBA,OAAM,eAAe,EAAE,IAAI,CAAC;AAExF,UAAM,cAAwB,CAAC;AAC/B,QAAIA,OAAM,MAAM,CAAC,SAAS,SAAS,IAAIA,OAAM,EAAE,EAAE,EAAG,aAAY,KAAK,WAAW,KAAK,UAAU,IAAIA,OAAM,EAAE,EAAE,CAAC,GAAG;AACjH,QAAIA,OAAM,QAAQ,CAAC,SAAS,SAASA,OAAM,IAAI,EAAG,aAAY,KAAK,WAAW,KAAK,UAAU,UAAUA,OAAM,IAAI,IAAI,CAAC,GAAG;AACzH,QAAIA,OAAM,UAAU,CAAC,SAAS,SAASA,OAAM,MAAM,EAAG,aAAY,KAAK,eAAe,KAAK,UAAUA,OAAM,MAAM,CAAC,GAAG;AACrH,QAAIA,OAAM,eAAe,CAAC,SAAS,SAASA,OAAM,WAAW,EAAG,aAAY,KAAK,oBAAoB,KAAK,UAAUA,OAAM,WAAW,CAAC,GAAG;AACzI,QAAIA,OAAM,SAAS,CAAC,SAAS,SAASA,OAAM,KAAK,EAAG,aAAY,KAAK,cAAc,KAAK,UAAUA,OAAM,KAAK,CAAC,GAAG;AAEjH,aAAS,KAAK;AAAA,MACZ,UAAU;AAAA,MACV,MAAMA,OAAM,SAAS,aAAa,aAAa;AAAA,MAC/C,MAAM;AAAA,MACN;AAAA,MACA;AAAA,MACA,SAASA,OAAM,WACX,YAAYA,OAAM,IAAI,aAAa,WAAW,MAC9C,GAAGA,OAAM,IAAI,aAAa,WAAW;AAAA,MACzC,YAAYA,OAAM,UAAUA,OAAM,SAASA,OAAM,KAAK,SAAUA,OAAM,cAAc,WAAW;AAAA,MAC/F,YAAY;AAAA,QACV,MAAMA,OAAM;AAAA,QACZ,OAAOA,OAAM;AAAA,QACb,aAAaA,OAAM;AAAA,QACnB,MAAMA,OAAM;AAAA,QACZ,IAAIA,OAAM;AAAA,QACV,QAAQA,OAAM;AAAA,QACd,UAAUA,OAAM;AAAA,QAChB,KAAKA,OAAM;AAAA,MACb;AAAA,IACF,CAAC;AAAA,EACH;AAEA,aAAW,UAAU,QAAQ,SAAS;AACpC,UAAM,cAAc,OAAO,QAAQ,OAAO;AAC1C,QAAI,CAAC,YAAa;AAElB,UAAM,WAAW,OAAO,aAClB,OAAO,SAAS,eAAe,KAAK,UAAU,OAAO,MAAM,CAAC,MAAM,UAClE,OAAO,OAAO,+BAA+B,KAAK,UAAU,OAAO,IAAI,CAAC,QAAQ,UAChF,OAAO,KAAK,WAAW,KAAK,UAAU,IAAI,OAAO,EAAE,EAAE,CAAC,MAAM,SAC7D;AAEL,UAAM,cAAwB,CAAC;AAC/B,QAAI,OAAO,MAAM,CAAC,SAAS,SAAS,OAAO,EAAE,EAAG,aAAY,KAAK,WAAW,KAAK,UAAU,IAAI,OAAO,EAAE,EAAE,CAAC,GAAG;AAC9G,QAAI,OAAO,UAAU,CAAC,SAAS,SAAS,OAAO,MAAM,EAAG,aAAY,KAAK,eAAe,KAAK,UAAU,OAAO,MAAM,CAAC,GAAG;AACxH,QAAI,OAAO,QAAQ,CAAC,SAAS,SAAS,OAAO,IAAI,EAAG,aAAY,KAAK,aAAa,KAAK,UAAU,OAAO,IAAI,CAAC,GAAG;AAChH,QAAI,OAAO,QAAS,aAAY,KAAK,WAAW,KAAK,UAAU,OAAO,OAAO,CAAC,GAAG;AAEjF,aAAS,KAAK;AAAA,MACZ,UAAU;AAAA,MACV,MAAM;AAAA,MACN,MAAM;AAAA,MACN;AAAA,MACA;AAAA,MACA,SAAS,OAAO,WACZ,sBAAsB,WAAW,MACjC,OAAO,SAAS,WACd,yBAAyB,WAAW,MACpC,aAAa,WAAW;AAAA,MAC9B,YAAY,OAAO,UAAU,OAAO,OAAO,SAAU,OAAO,KAAK,WAAW;AAAA,MAC5E,YAAY;AAAA,QACV,MAAM,OAAO;AAAA,QACb,QAAQ,OAAO;AAAA,QACf,IAAI,OAAO;AAAA,QACX,MAAM,OAAO;AAAA,QACb,UAAU,OAAO;AAAA,QACjB,KAAK,OAAO;AAAA,MACd;AAAA,IACF,CAAC;AAAA,EACH;AAEA,aAAW,QAAQ,QAAQ,OAAO;AAChC,aAAS,KAAK;AAAA,MACZ,UAAU;AAAA,MACV,MAAM;AAAA,MACN,MAAM,KAAK;AAAA,MACX,UAAU,KAAK;AAAA,MACf,aAAa,KAAK,SAAS,CAAC,eAAe,KAAK,UAAU,KAAK,MAAM,CAAC,GAAG,IAAI,CAAC;AAAA,MAC9E,SAAS,KAAK,WACV,qBAAqB,KAAK,IAAI,QAAQ,KAAK,IAAI,MAC/C,+BAA+B,KAAK,IAAI,QAAQ,KAAK,IAAI;AAAA,MAC7D,YAAY,KAAK,SAAS,SAAS;AAAA,MACnC,YAAY;AAAA,QACV,MAAM,KAAK;AAAA,QACX,MAAM,KAAK;AAAA,QACX,QAAQ,KAAK;AAAA,QACb,UAAU,KAAK;AAAA,MACjB;AAAA,IACF,CAAC;AAAA,EACH;AAEA,aAAW,WAAW,QAAQ,UAAU;AACtC,aAAS,KAAK;AAAA,MACZ,UAAU;AAAA,MACV,MAAM;AAAA,MACN,MAAM,QAAQ;AAAA,MACd,UAAU,QAAQ;AAAA,MAClB,aAAa,CAAC,aAAa,KAAK,UAAU,QAAQ,IAAI,CAAC,GAAG;AAAA,MAC1D,SAAS,QAAQ,QAAQ,KAAK;AAAA,MAC9B,YAAY;AAAA,MACZ,YAAY;AAAA,QACV,OAAO,QAAQ;AAAA,QACf,MAAM,QAAQ;AAAA,MAChB;AAAA,IACF,CAAC;AAAA,EACH;AAEA,aAAW,UAAU,QAAQ,eAAe;AAC1C,aAAS,KAAK;AAAA,MACZ,UAAU;AAAA,MACV,MAAM,OAAO;AAAA,MACb,MAAM,OAAO,QAAQ,OAAO;AAAA,MAC5B,UAAU,OAAO;AAAA,MACjB,aAAa,CAAC;AAAA,MACd,SAAS;AAAA,MACT,YAAY;AAAA,MACZ,YAAY;AAAA,QACV,MAAM,OAAO;AAAA,QACb,UAAU,OAAO;AAAA,QACjB,aAAa,OAAO;AAAA,MACtB;AAAA,IACF,CAAC;AAAA,EACH;AAEA,SAAO;AACT;AAEA,SAAS,cACP,UACA,SACA,cACU;AACV,QAAM,WAAqB,CAAC;AAE5B,MAAI,CAAC,cAAc;AACjB,aAAS,KAAK,iGAAiG;AAAA,EACjH;AAEA,QAAM,sBAAsB,SAAS,OAAO,CAAC,YAAY,QAAQ,aAAa,WAAW,QAAQ,eAAe,KAAK;AACrH,MAAI,oBAAoB,SAAS,GAAG;AAClC,aAAS;AAAA,MACP,GAAG,oBAAoB,MAAM,uFAAuF,oBAAoB,IAAI,CAAC,YAAY,QAAQ,IAAI,EAAE,OAAO,OAAO,EAAE,KAAK,IAAI,CAAC;AAAA,IACnM;AAAA,EACF;AAEA,MAAI,QAAQ,cAAc,WAAW,GAAG;AACtC,aAAS,KAAK,2HAA2H;AAAA,EAC3I;AAEA,aAAW,QAAQ,QAAQ,OAAO;AAChC,UAAM,YAAY,QAAQ,QAAQ,KAAK,CAAC,WAAW,OAAO,SAAS,QAAQ;AAC3E,QAAI,KAAK,aAAa,KAAK,CAAC,WAAW;AACrC,eAAS;AAAA,QACP,QAAQ,KAAK,MAAM,IAAI,KAAK,KAAK,EAAE,QAAQ,KAAK,UAAU;AAAA,MAC5D;AAAA,IACF;AAAA,EACF;AAEA,MAAI,QAAQ,MAAM,UAAU,kBAAkB;AAC5C,aAAS,KAAK,sBAAsB,gBAAgB,6DAA6D;AAAA,EACnH;AAEA,QAAM,cAAc,SAAS,OAAO,CAAC,YACnC,QAAQ,aAAa,YAAY,QAAQ,aAAa,WAAW,QAAQ,aAAa,MACvF;AACD,MAAI,YAAY,WAAW,GAAG;AAC5B,aAAS,KAAK,kJAAkJ;AAAA,EAClK;AAEA,SAAO;AACT;AAEA,SAASD,KAAI,SAAkB,SAAuB;AACpD,MAAI,QAAS,SAAQ,IAAI,OAAO;AAClC;AAEA,eAAe,yBAAyB,MAAW,SAAoC;AACrF,MAAI,CAAC,KAAK,iBAAiB,OAAO,KAAK,cAAc,aAAa,YAAY;AAC5E,IAAAA,KAAI,SAAS,+EAA+E;AAC5F,WAAO;AAAA,EACT;AAEA,MAAI;AACF,WAAO,MAAM,KAAK,cAAc,SAAS,EAAE,iBAAiB,MAAM,CAAC;AAAA,EACrE,SAAS,OAAY;AACnB,IAAAA,KAAI,SAAS,uCAAuC,OAAO,WAAW,KAAK,qCAAqC;AAChH,WAAO;AAAA,EACT;AACF;AAEA,SAAS,SAAS,OAAoC;AACpD,SAAO,OAAO,UAAU,WAAW,QAAQ;AAC7C;;;AChoBA,SAAS,aAAAE,YAAW,iBAAAC,sBAAqB;AACzC,SAAS,QAAAC,aAAY;AAId,SAAS,mBAAmB,YAAwB,UAAwC;AACjG,UAAQ,IAAI,EAAE;AACd,UAAQ,IAAI,IAAI,OAAO,EAAE,CAAC;AAC1B,UAAQ,IAAI,6BAA6B;AACzC,UAAQ,IAAI,IAAI,OAAO,EAAE,CAAC;AAC1B,UAAQ,IAAI,QAAQ,WAAW,GAAG,EAAE;AACpC,UAAQ,IAAI,UAAU,WAAW,KAAK,EAAE;AACxC,UAAQ,IAAI,aAAa,WAAW,SAAS,KAAK,WAAW,IAAI,GAAG;AACpE,UAAQ,IAAI,EAAE;AACd,UAAQ,IAAI,WAAW;AAEvB,aAAW,CAAC,UAAU,KAAK,KAAK,OAAO,QAAQ,WAAW,QAAQ,UAAU,GAAG;AAC7E,YAAQ,IAAI,KAAK,QAAQ,KAAK,KAAK,EAAE;AAAA,EACvC;AAEA,MAAI,WAAW,SAAS,SAAS,GAAG;AAClC,YAAQ,IAAI,EAAE;AACd,YAAQ,IAAI,WAAW;AACvB,eAAW,WAAW,WAAW,UAAU;AACzC,cAAQ,IAAI,OAAO,OAAO,EAAE;AAAA,IAC9B;AAAA,EACF;AAEA,MAAI,UAAU;AACZ,YAAQ,IAAI,EAAE;AACd,YAAQ,IAAI,iBAAiB,SAAS,UAAU,MAAM,EAAE;AACxD,YAAQ,IAAI,YAAY,SAAS,OAAO,EAAE;AAC1C,YAAQ,IAAI,WAAW,SAAS,eAAe,EAAE;AAAA,EACnD;AAEA,UAAQ,IAAI,EAAE;AAChB;AAEO,SAAS,gBACd,YACA,UACA,YAAY,qBACJ;AACR,EAAAF,WAAU,WAAW,EAAE,WAAW,KAAK,CAAC;AAExC,QAAM,WAAW,WAAW,QAAQ,WAAW,GAAG,CAAC,IAAI,KAAK,IAAI,CAAC;AACjE,QAAM,WAAWE,MAAK,WAAW,QAAQ;AAEzC,EAAAD,eAAc,UAAU,KAAK,UAAU;AAAA,IACrC,OAAO;AAAA,MACL,SAAS;AAAA,MACT,cAAa,oBAAI,KAAK,GAAE,YAAY;AAAA,MACpC,MAAM;AAAA,IACR;AAAA,IACA;AAAA,IACA,UAAU,YAAY;AAAA,EACxB,GAAG,MAAM,CAAC,CAAC;AAEX,SAAO;AACT;AAEO,SAAS,mBAAmB,UAAkC;AACnE,QAAM,QAAkB,CAAC;AAEzB,aAAW,YAAY,SAAS,WAAW;AACzC,UAAM,KAAK,KAAK,SAAS,EAAE,WAAM,SAAS,KAAK,IAAI,SAAS,KAAK,IAAIE,aAAY,EAAE,KAAK,GAAG,CAAC,GAAG,KAAK,CAAC;AACrG,UAAM,KAAK,eAAe,SAAS,GAAG,MAAM;AAC5C,UAAM,KAAK,mBAAmB,SAAS,OAAO,MAAM;AACpD,UAAM,KAAK,kCAAkC;AAC7C,UAAM,KAAK,kBAAkB,gBAAgB,SAAS,QAAQ,CAAC,MAAM;AACrE,UAAM,KAAK,oBAAoB,SAAS,SAAS,MAAM;AACvD,UAAM,KAAK,EAAE;AACb,UAAM,KAAK,UAAU;AAErB,aAAS,MAAM,QAAQ,CAAC,MAAM,UAAU;AACtC,YAAM,OAAO,KAAK,YAAY,KAAK,aAAa,SAC5C,mBAAmB,KAAK,QAAQ,SAChC;AACJ,YAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,KAAK,KAAK,GAAG,IAAI,EAAE;AAAA,IACjD,CAAC;AAED,UAAM,KAAK,EAAE;AACb,UAAM,KAAK,qBAAqB;AAEhC,aAAS,WAAW,QAAQ,CAAC,cAAc;AACzC,YAAM,OAAO,UAAU,aACnB,qBAAqB,gBAAgB,UAAU,UAAU,CAAC,SAC1D;AACJ,YAAM,KAAK,KAAK,UAAU,KAAK,GAAG,IAAI,EAAE;AAAA,IAC1C,CAAC;AAED,UAAM,KAAK,EAAE;AACb,UAAM,KAAK,KAAK;AAChB,UAAM,KAAK,EAAE;AAAA,EACf;AAEA,SAAO,MAAM,KAAK,IAAI;AACxB;AAEO,SAAS,kBACd,UACA,YAAY,SACZ,UACQ;AACR,EAAAH,WAAU,WAAW,EAAE,WAAW,KAAK,CAAC;AAExC,QAAM,mBAAmB,YAAY,GAAG,QAAQ,SAAS,WAAW,SAAS,GAAG,CAAC;AACjF,QAAM,WAAWE,MAAK,WAAW,gBAAgB;AAEjD,EAAAD,eAAc,UAAU,mBAAmB,QAAQ,CAAC;AACpD,SAAO;AACT;AAEO,SAAS,gBACd,UACA,YAAY,iBACG;AACf,MAAI,SAAS,UAAU,WAAW,EAAG,QAAO;AAE5C,EAAAD,WAAU,WAAW,EAAE,WAAW,KAAK,CAAC;AAExC,QAAM,WAAW,gBAAgB,QAAQ,SAAS,GAAG,CAAC,IAAI,KAAK,IAAI,CAAC;AACpE,QAAM,WAAWE,MAAK,WAAW,QAAQ;AACzC,QAAM,QAAkB,CAAC;AAEzB,QAAM,KAAK,KAAK;AAChB,QAAM,KAAK,iCAAiC;AAC5C,QAAM,KAAK,sBAAsB,SAAS,GAAG,EAAE;AAC/C,QAAM,KAAK,eAAe,SAAS,OAAO,EAAE;AAC5C,QAAM,KAAK,KAAK;AAChB,QAAM,KAAK,EAAE;AACb,QAAM,KAAK,uDAAuD;AAClE,QAAM,KAAK,EAAE;AAEb,aAAW,YAAY,SAAS,WAAW;AACzC,UAAM,KAAK,QAAQ,KAAK,UAAU,GAAG,SAAS,EAAE,WAAM,SAAS,KAAK,EAAE,CAAC,yBAAyB;AAChG,eAAW,QAAQ,SAAS,OAAO;AACjC,UAAI,KAAK,WAAW,YAAY;AAC9B,cAAM,KAAK,qBAAqB,KAAK,UAAU,KAAK,KAAK,CAAC,IAAI;AAC9D;AAAA,MACF;AAEA,UAAI,KAAK,aAAa,OAAQ;AAC9B,YAAM,WAAW,QAAQ,KAAK,QAAQ;AAEtC,UAAI,KAAK,WAAW,OAAQ,OAAM,KAAK,WAAW,QAAQ,SAAS,KAAK,UAAU,KAAK,KAAK,CAAC,IAAI;AACjG,UAAI,KAAK,WAAW,QAAS,OAAM,KAAK,WAAW,QAAQ,WAAW;AACtE,UAAI,KAAK,WAAW,SAAU,OAAM,KAAK,WAAW,QAAQ,iBAAiB,KAAK,UAAU,KAAK,KAAK,CAAC,IAAI;AAC3G,UAAI,KAAK,WAAW,QAAS,OAAM,KAAK,WAAW,QAAQ,WAAW;AACtE,UAAI,KAAK,WAAW,WAAY,OAAM,KAAK,+BAA+B,KAAK,UAAU,KAAK,KAAK,CAAC,IAAI;AACxG,UAAI,KAAK,WAAW,QAAS,OAAM,KAAK,WAAW,QAAQ,WAAW;AAAA,IACxE;AAEA,eAAW,aAAa,SAAS,YAAY;AAC3C,YAAM,KAAK,KAAK,gBAAgB,UAAU,UAAU,CAAC,EAAE;AAAA,IACzD;AAEA,UAAM,KAAK,KAAK;AAChB,UAAM,KAAK,EAAE;AAAA,EACf;AAEA,EAAAD,eAAc,UAAU,MAAM,KAAK,IAAI,CAAC;AACxC,SAAO;AACT;AAEA,SAAS,QAAQ,OAAuB;AACtC,UAAQ,SAAS,WACd,QAAQ,gBAAgB,EAAE,EAC1B,QAAQ,kBAAkB,GAAG,EAC7B,QAAQ,UAAU,EAAE,EACpB,YAAY,EACZ,MAAM,GAAG,EAAE;AAChB;AAEA,SAASE,cAAa,OAAuB;AAC3C,QAAM,UAAU,OAAO,SAAS,EAAE,EAAE,KAAK;AACzC,MAAI,CAAC,QAAS,QAAO;AACrB,SAAO,QAAQ,WAAW,GAAG,IAAI,UAAU,IAAI,OAAO;AACxD;AAEA,SAAS,gBAAgB,OAAuB;AAC9C,SAAO,OAAO,SAAS,EAAE,EAAE,QAAQ,QAAQ,MAAM;AACnD;AAEA,SAAS,gBAAgB,OAAuB;AAC9C,QAAM,UAAU,OAAO,SAAS,EAAE,EAAE,KAAK;AACzC,MAAI,CAAC,QAAS,QAAO;AACrB,SAAO,QAAQ,SAAS,GAAG,IAAI,UAAU,GAAG,OAAO;AACrD;;;AL5KA,SAASC,SAAQ,MAAsB;AACrC,SACE,KACG,YAAY,EACZ,QAAQ,eAAe,GAAG,EAC1B,QAAQ,YAAY,EAAE,KAAK;AAElC;AAEA,SAAS,kBAAkB,UAAkB,KAAsB;AACjE,MAAI,CAAC,OAAO,oBAAoB,KAAK,QAAQ,EAAG,QAAO;AAEvD,QAAM,QAAQ,SAAS,MAAM,IAAI;AACjC,QAAMC,UAAmB,CAAC;AAE1B,WAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACrC,IAAAA,QAAO,KAAK,MAAM,CAAC,CAAC;AACpB,QAAI,WAAW,KAAK,MAAM,CAAC,CAAC,GAAG;AAC7B,MAAAA,QAAO,KAAK,eAAe,GAAG,MAAM;AAAA,IACtC;AAAA,EACF;AAEA,SAAOA,QAAO,KAAK,IAAI;AACzB;AAEA,SAAS,yBAAyB,MAMvB;AACT,QAAM,EAAE,QAAQ,SAAS,KAAK,SAAS,IAAI;AAC3C,QAAM,aAAa,KAAK,cAAc;AACtC,QAAM,QAAkB,CAAC;AAEzB,WAAS,IAAI,GAAG,IAAI,UAAU,KAAK;AACjC,UAAM,MAAM,aAAa;AACzB,UAAM,KAAM,GAAG,MAAM,IAAI,OAAO,GAAG,EAAE,SAAS,GAAG,GAAG,CAAC;AAErD,UAAM,KAAK,KAAK,EAAE,WAAM,OAAO,eAAe,GAAG,kBAAkB;AACnE,QAAI,IAAK,OAAM,KAAK,eAAe,GAAG,MAAM;AAC5C,UAAM,KAAK,UAAU;AACrB,UAAM,KAAK,kBAAkB,OAAO,YAAY,EAAE;AAClD,UAAM,KAAK,mDAAmD;AAC9D,UAAM,KAAK,uBAAuB;AAClC,UAAM,KAAK,EAAE;AACb,UAAM,KAAK,qBAAqB;AAChC,UAAM,KAAK,iDAAiD;AAC5D,UAAM,KAAK,mCAAmC;AAC9C,UAAM,KAAK,EAAE;AACb,UAAM,KAAK,EAAE;AAAA,EACf;AAEA,SAAO,MAAM,KAAK,IAAI;AACxB;AAEA,eAAe,qBAAqB,MAKjC;AAED,MAAI,KAAK,SAAS;AAChB,UAAM,IAAI,KAAK,IAAI,KAAK,IAAI,KAAK,YAAY,GAAG,CAAC,GAAG,EAAE;AACtD,WAAO;AAAA,MACL,SAAS,KAAK;AAAA,MACd,gBAAgB,KAAK,kBAAkB;AAAA,MACvC,UAAU;AAAA,MACV,KAAK,KAAK;AAAA,IACZ;AAAA,EACF;AAGA,QAAM,KAAK,gBAAgB,EAAE,OAAO,OAAO,CAAC;AAE5C,QAAM,WAAkB,MAAM,GAAG,SAAS,qCAA8B,GAAG,KAAK;AAChF,QAAM,kBAAkB,MAAM,GAAG,SAAS,8CAAuC,GAAG,KAAK;AACzF,QAAM,eAAkB,MAAM,GAAG,SAAS,kDAAsC,GAAG,KAAK;AAExF,KAAG,MAAM;AAET,MAAI,WAAW,SAAS,aAAa,EAAE;AACvC,MAAI,MAAM,QAAQ,KAAK,WAAW,EAAG,YAAW;AAChD,MAAI,WAAW,GAAI,YAAW;AAE9B,SAAO,EAAE,SAAS,gBAAgB,UAAU,KAAK,KAAK,IAAI;AAC5D;AAEA,eAAe,iBAAiB,QAS7B;AACD,QAAM,EAAE,SAAS,gBAAgB,UAAU,IAAI,IAAI,MAAM,qBAAqB;AAAA,IAC5E,KAAgB,OAAO;AAAA,IACvB,SAAgB,OAAO;AAAA,IACvB,gBAAgB,OAAO;AAAA,IACvB,UAAgB,OAAO;AAAA,EACzB,CAAC;AAED,QAAM,SAAS,YAAY;AAAA,IACzB,aAAgB;AAAA,IAChB;AAAA,IACA,gBAAgB,OAAO;AAAA,EACzB,CAAC;AAED,EAAAC,WAAU,SAAS,EAAE,WAAW,KAAK,CAAC;AACtC,QAAM,WAAW,GAAG,OAAO,YAAY,CAAC,IAAIF,SAAQ,OAAO,CAAC;AAC5D,QAAM,WAAWG,MAAK,SAAS,QAAQ;AAEvC,MAAI;AAEJ,MAAI,OAAO,OAAO;AAChB,QAAI,cAAc;AAElB,QAAI,KAAK;AACP,UAAI;AACF,gBAAQ,IAAI,6BAAsB,GAAG,EAAE;AACvC,cAAM,aAAa,MAAM,gBAAgB,KAAK;AAAA,UAC5C,UAAU,EAAE,OAAO,UAAU;AAAA,UAC7B,SAAS;AAAA,QACX,CAAC;AACD,2BAAmB,UAAU;AAE7B,cAAM,WAAW,gBAAgB,UAAU;AAC3C,gBAAQ,IAAI,uCAA2B,QAAQ,EAAE;AAEjD,YAAI,OAAO,aAAa;AACtB,kBAAQ,IAAI,4DAA4D;AACxE;AAAA,QACF;AAEA,cAAM,WAAW,MAAM,gBAAgB,YAAY,EAAE,SAAS,KAAK,CAAC;AACpE,2BAAmB,YAAY,QAAQ;AAEvC,cAAM,cAAc,gBAAgB,QAAQ;AAC5C,YAAI,aAAa;AACf,kBAAQ,IAAI,uCAA2B,WAAW,EAAE;AAAA,QACtD;AAEA,cAAM,kBAAkB,GAAG,OAAO,YAAY,CAAC,IAAIH,SAAQ,OAAO,CAAC;AACnE,cAAM,gBAAgB,kBAAkB,UAAU,SAAS,eAAe;AAC1E,gBAAQ,IAAI,uDAA6C,aAAa,EAAE;AACxE,gBAAQ,IAAI,eAAe;AAC3B,gBAAQ,IAAI,kBAAkB,aAAa,sBAAsB;AACjE,gBAAQ,IAAI,WAAW;AACvB;AAAA,MACF,SAAS,GAAQ;AACf,gBAAQ,KAAK,sCAA4B,GAAG,WAAW,CAAC,+CAA+C;AACvG,YAAI,OAAO,aAAa;AACtB;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,QAAI;AACF,UAAI,gBAAgB,UAAa,KAAK;AACpC,cAAM,aAAa,MAAM,gBAAgB,KAAK;AAAA,UAC5C,UAAU;AAAA,UACV,SAAS;AAAA,QACX,CAAC;AACD,sBAAc,cAAc,UAAU;AAAA,MACxC;AAEA,iBAAW,MAAM,yBAAyB;AAAA,QACxC,gBAAgB,kBAAkB;AAAA,QAClC;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA,YAAY;AAAA,QACZ;AAAA,MACF,CAAC;AACD,iBAAW,kBAAkB,UAAU,GAAG;AAC1C,cAAQ,IAAI,iCAA4B;AAAA,IAC1C,SAAS,KAAU;AACjB,cAAQ,KAAK,uCAA6B,KAAK,WAAW,GAAG,sCAAsC;AACnG,iBAAW,yBAAyB,EAAE,QAAQ,SAAS,KAAK,UAAU,YAAY,EAAE,CAAC;AACrF,cAAQ,IAAI,yDAAkD;AAAA,IAChE;AAAA,EACF,OAAO;AACL,eAAW,yBAAyB,EAAE,QAAQ,SAAS,KAAK,UAAU,YAAY,EAAE,CAAC;AACrF,YAAQ,IAAI,uEAAgE;AAAA,EAC9E;AAEA,EAAAI,eAAc,UAAU,QAAQ;AAEhC,UAAQ,IAAI;AAAA,sBAAe,QAAQ,mBAAc,QAAQ,EAAE;AAC3D,UAAQ,IAAI,eAAe;AAC3B,UAAQ,IAAI,4CAA4C;AACxD,UAAQ,IAAI,WAAW;AACzB;AAIA,SAAS,iBAAiB,KAAuB;AAC/C,SAAO,IACJ,OAAO,QAAqB,kDAAkD,EAC9E,OAAO,qBAAqB,2CAA2C,EACvE,OAAO,oBAAqB,8CAAyC,EACrE,OAAO,iBAAqB,iDAA4C,EACxE,OAAO,eAAqB,+BAA0B,QAAQ;AACnE;AAEA,SAAS,qBAAwD,MAAsB;AACrF,MAAI,OAAQ,KAAiB,oBAAoB,YAAY;AAC3D,WAAQ,KAAiB,gBAAmB;AAAA,EAC9C;AACA,MAAI,OAAQ,KAAiB,SAAS,YAAY;AAChD,WAAQ,KAAiB,KAAQ;AAAA,EACnC;AACA,SAAO;AACT;AAIO,SAAS,QAAQ;AACtB,QAAM,OAAO,IAAIC,SAAQ,IAAI,EAC1B,YAAY,yDAAyD,EACrE,YAAY,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA,CAKzB;AAEC,mBAAiB,IAAI,EAAE;AAAA,IACrB,OAAO,SAAuG;AAC5G,YAAM,eAAe,qBAAyG,IAAI;AAClI,YAAM,iBAAiB;AAAA,QACrB,KAAgB;AAAA,QAChB,gBAAgB,aAAa;AAAA,QAC7B,SAAgB,aAAa;AAAA,QAC7B,gBAAgB,aAAa;AAAA,QAC7B,UAAgB,aAAa;AAAA,QAC7B,OAAgB,aAAa,MAAM;AAAA,MACrC,CAAC;AAAA,IACH;AAAA,EACF;AAEA;AAAA,IACE,KACG,QAAQ,KAAK,EACb,SAAS,SAAS,gDAAgD,EAClE,YAAY,0EAA0E,EACtF,OAAO,YAAY,2CAA2C,EAC9D,OAAO,kBAAkB,mEAAmE;AAAA,EACjG,EAAE;AAAA,IACA,OACE,KACA,MACA,YACG;AACH,YAAM,eAAe,qBAAkJ,WAAW,IAAI;AACtL,YAAM,iBAAiB;AAAA,QACrB;AAAA,QACA,gBAAgB,aAAa;AAAA,QAC7B,SAAgB,aAAa;AAAA,QAC7B,gBAAgB,aAAa;AAAA,QAC7B,UAAgB,aAAa;AAAA,QAC7B,OAAgB,aAAa,MAAM;AAAA,QACnC,QAAgB,aAAa,UAAU;AAAA,QACvC,aAAgB,aAAa,eAAe;AAAA,MAC9C,CAAC;AAAA,IACH;AAAA,EACF;AAEA,SAAO;AACT;;;AMnSA,SAAS,WAAAC,gBAAe;AACxB,SAAS,SAAAC,cAAa;AAEf,SAAS,YAAY;AAC1B,QAAM,MAAM,IAAID,SAAQ,QAAQ,EAC7B,YAAY,iCAAiC,EAC7C,OAAO,MAAM;AACZ,YAAQ,IAAI,6CAAsC;AAElD,UAAM,QAAQC;AAAA,MACZ;AAAA,MACA,CAAC,cAAc,aAAa;AAAA,MAC5B;AAAA,QACE,OAAO;AAAA,QACP,OAAO,QAAQ,aAAa;AAAA,MAC9B;AAAA,IACF;AAEA,UAAM,GAAG,QAAQ,CAAC,SAAS;AACzB,cAAQ,KAAK,QAAQ,CAAC;AAAA,IACxB,CAAC;AAAA,EACH,CAAC;AAEH,SAAO;AACT;;;ACxBA,SAAS,WAAAC,gBAAe;AACxB,SAAS,SAAAC,cAAa;AACtB,SAAS,cAAAC,mBAAkB;AAC3B,SAAS,QAAAC,aAAY;AAEd,SAAS,WAAW;AACzB,QAAM,MAAM,IAAIH,SAAQ,OAAO,EAC5B,YAAY,yBAAyB,EACrC,OAAO,MAAM;AACZ,YAAQ,IAAI,oCAA6B;AAGzC,UAAM,iBAAiBG,MAAK,QAAQ,IAAI,GAAG,gBAAgB,sBAAsB,OAAO,QAAQ;AAEhG,QAAI,aAAa;AACjB,QAAI,OAAO,CAAC,UAAU,SAAS,kBAAkB;AAIjD,QAAID,YAAW,cAAc,GAAG;AAC7B,mBAAa;AACb,aAAO,CAAC,gBAAgB,SAAS,kBAAkB;AAAA,IACtD;AAEA,YAAQ,IAAI,KAAK,UAAU,IAAI,KAAK,KAAK,GAAG,CAAC,EAAE;AAE/C,UAAM,QAAQD;AAAA,MACZ;AAAA,MACA;AAAA,MACA;AAAA,QACE,OAAO;AAAA,QACP,OAAO,QAAQ,aAAa;AAAA,MAC9B;AAAA,IACF;AAEA,UAAM,GAAG,QAAQ,CAAC,SAAS;AACzB,cAAQ,KAAK,QAAQ,CAAC;AAAA,IACxB,CAAC;AAAA,EACH,CAAC;AAEH,SAAO;AACT;;;ACzCA,SAAS,WAAAG,gBAAe;AACxB,SAAS,SAAAC,cAAa;AACtB,SAAS,WAAAC,gBAAe;AAExB,SAAS,QAAQ,KAAa,MAAgB,UAAiC;AAC7E,SAAO,IAAI,QAAQ,CAACA,UAAS,WAAW;AACtC,YAAQ,IAAI;AAAA,uBAAmB,QAAQ,EAAE;AACzC,YAAQ,IAAI,KAAK,GAAG,IAAI,KAAK,KAAK,GAAG,CAAC,EAAE;AAExC,UAAM,QAAQD,OAAM,KAAK,MAAM;AAAA,MAC7B,OAAO;AAAA,MACP,OAAO,QAAQ,aAAa;AAAA,IAC9B,CAAC;AAED,UAAM,GAAG,QAAQ,CAAC,SAAS;AACzB,UAAI,SAAS,GAAG;AACd,QAAAC,SAAQ;AAAA,MACV,OAAO;AACL,eAAO,IAAI,MAAM,GAAG,QAAQ,0BAA0B,IAAI,EAAE,CAAC;AAAA,MAC/D;AAAA,IACF,CAAC;AAAA,EACH,CAAC;AACH;AAEO,SAAS,UAAU;AACxB,QAAM,MAAM,IAAIF,SAAQ,MAAM,EAC3B,YAAY,qDAAqD,EACjE,SAAS,cAAc,mCAAmC,SAAS,EACnE,OAAO,iBAAiB,2BAA2B,IAAI,EACvD,OAAO,YAAY,oBAAoB,EACvC,OAAO,OAAO,UAAU,SAAS;AAChC,UAAM,SAASE,SAAQ,QAAQ,KAAK,CAAC,CAAC;AAEtC,QAAI;AAEF,YAAM,QAAQ,QAAQ,UAAU,CAAC,QAAQ,aAAa,QAAQ,GAAG,iBAAiB;AAGlF,YAAM,QAAQ,QAAQ,UAAU,CAAC,QAAQ,OAAO,UAAU,KAAK,IAAI,GAAG,gBAAgB;AAGtF,UAAI,KAAK,KAAK;AACX,cAAM,QAAQ,QAAQ,UAAU,CAAC,QAAQ,MAAM,GAAG,sBAAsB;AAAA,MAC3E,OAAO;AACL,gBAAQ,IAAI,oDAA0C;AAAA,MACxD;AAEA,cAAQ,IAAI,uCAAkC;AAAA,IAChD,SAAS,KAAU;AACjB,cAAQ,MAAM;AAAA,sBAAoB,IAAI,OAAO,EAAE;AAC/C,cAAQ,KAAK,CAAC;AAAA,IAChB;AAAA,EACF,CAAC;AAEH,SAAO;AACT;;;ACvDA,SAAS,WAAAC,gBAAe;AACxB,SAAS,aAAAC,YAAW,iBAAAC,gBAAe,cAAAC,mBAAkB;AACrD,SAAS,QAAAC,aAAY;AAErB,IAAM,mBAAmB;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;AA6BlB,SAAS,QAAQ;AACtB,QAAM,MAAM,IAAIJ,SAAQ,IAAI,EACzB,YAAY,yCAAyC,EACrD,OAAO,MAAM;AACZ,UAAM,YAAYI,MAAK,QAAQ,IAAI,GAAG,SAAS;AAC/C,UAAM,eAAeA,MAAK,WAAW,WAAW;AAChD,UAAM,eAAeA,MAAK,cAAc,cAAc;AAEtD,YAAQ,IAAI,wCAAiC;AAE7C,QAAI,CAACD,YAAW,YAAY,GAAG;AAC7B,MAAAF,WAAU,cAAc,EAAE,WAAW,KAAK,CAAC;AAC3C,cAAQ,IAAI,sBAAsB,YAAY,EAAE;AAAA,IAClD;AAEA,QAAIE,YAAW,YAAY,GAAG;AAC5B,cAAQ,KAAK,iDAAuC,YAAY,aAAa;AAC7E;AAAA,IACF;AAEA,IAAAD,eAAc,cAAc,iBAAiB,KAAK,IAAI,IAAI;AAC1D,YAAQ,IAAI,oCAA+B,YAAY,EAAE;AACzD,YAAQ,IAAI,aAAa;AACzB,YAAQ,IAAI,iCAAiC;AAC7C,YAAQ,IAAI,sDAAsD;AAAA,EACpE,CAAC;AAEH,SAAO;AACT;;;AbjDA,IAAMG,WAAU,cAAc,YAAY,GAAG;AAC7C,IAAM,EAAE,QAAQ,IAAIA,SAAQ,iBAAiB;AAE7C,IAAM,UAAU,IAAIC,SAAQ;AAC5B,QACG,KAAK,IAAI,EACT,YAAY,8EAA+D,EAC3E,QAAQ,OAAO;AAElB,QAAQ,WAAW,OAAO,CAAC;AAC3B,QAAQ,WAAW,aAAa,CAAC;AACjC,QAAQ,WAAW,OAAO,CAAC;AAC3B,QAAQ,WAAW,QAAQ,CAAC;AAC5B,QAAQ,WAAW,MAAM,CAAC;AAC1B,QAAQ,WAAW,UAAU,CAAC;AAC9B,QAAQ,WAAW,SAAS,CAAC;AAC7B,QAAQ,WAAW,QAAQ,CAAC;AAC5B,QAAQ,WAAW,MAAM,CAAC;AAE1B,QAAQ,WAAW,QAAQ,IAAI;","names":["Command","Command","readFileSync","mkdirSync","writeFileSync","statSync","join","resolve","Command","Command","mkdirSync","writeFileSync","join","detectProvider","callAnthropic","callOpenAi","inferPrefix","log","input","mkdirSync","writeFileSync","join","normalizeTag","slugify","output","mkdirSync","join","writeFileSync","Command","Command","spawn","Command","spawn","existsSync","join","Command","spawn","resolve","Command","mkdirSync","writeFileSync","existsSync","join","require","Command"]}
1
+ {"version":3,"sources":["../src/cli.ts","../src/commands/new.ts","../src/commands/normalize.ts","../src/commands/test.ts","../src/commands/tc.ts","../src/core/prefix.ts","../src/core/llm-provider.ts","../src/core/llm.ts","../src/core/analyse.ts","../src/core/playwright.ts","../src/core/capture.ts","../src/core/report.ts","../src/commands/report.ts","../src/commands/serve.ts","../src/commands/flow.ts","../src/commands/ci.ts"],"sourcesContent":["import { Command } from 'commander';\nimport { createRequire } from 'node:module';\nimport { newCmd } from './commands/new.js';\nimport { normalizeCmd } from './commands/normalize.js';\nimport { genCmd } from './commands/gen.js';\nimport { testCmd } from './commands/test.js';\nimport { tcCmd } from './commands/tc.js';\nimport { reportCmd } from './commands/report.js';\nimport { serveCmd } from './commands/serve.js';\nimport { flowCmd } from './commands/flow.js';\nimport { ciCmd } from './commands/ci.js';\n\nconst require = createRequire(import.meta.url);\nconst { version } = require('../package.json');\n\nconst program = new Command();\nprogram\n .name('ct')\n .description('CementicTest CLI: cases → normalized → POM tests → Playwright')\n .version(version);\n\nprogram.addCommand(newCmd());\nprogram.addCommand(normalizeCmd());\nprogram.addCommand(genCmd());\nprogram.addCommand(testCmd());\nprogram.addCommand(tcCmd());\nprogram.addCommand(reportCmd());\nprogram.addCommand(serveCmd());\nprogram.addCommand(flowCmd());\nprogram.addCommand(ciCmd());\n\nprogram.parseAsync(process.argv);","import { Command } from 'commander';\nimport { mkdirSync, writeFileSync, existsSync, readFileSync, cpSync, readdirSync, statSync } from 'node:fs';\nimport { join, resolve } from 'node:path';\nimport { execSync } from 'node:child_process';\nimport { fileURLToPath } from 'node:url';\nimport { dirname } from 'node:path';\nimport { platform, release } from 'node:os';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\nconst LEGACY_MACOS_DARWIN_MAJOR = 23;\n\nfunction resolveTemplatePath(templateDir: string): string | undefined {\n const candidates = [\n resolve(__dirname, `templates/${templateDir}`),\n resolve(__dirname, `../templates/${templateDir}`),\n resolve(__dirname, `../../templates/${templateDir}`),\n resolve(process.cwd(), `templates/${templateDir}`),\n ];\n\n return candidates.find(candidate => existsSync(candidate));\n}\n\nexport function newCmd() {\n const cmd = new Command('new')\n .arguments('<projectName>')\n .description('Scaffold a new CementicTest + Playwright project from scratch')\n .addHelpText('after', `\nExamples:\n $ ct new my-awesome-test-suite\n $ ct new e2e-ts --lang ts\n $ ct new e2e-tests --no-browsers\n`)\n .option('--mode <mode>', 'greenfield|enhance', 'greenfield')\n .option('--lang <lang>', 'Scaffold language (js|ts)', 'js')\n .option('--no-browsers', 'do not run \"npx playwright install\" during setup')\n .action((projectName: string, opts) => {\n const root = process.cwd();\n const projectPath = join(root, projectName);\n\n console.log(`🚀 Initializing new CementicTest project in ${projectName}...`);\n\n // 1. Create project directory\n if (existsSync(projectPath)) {\n console.error(`❌ Directory ${projectName} already exists.`);\n process.exit(1);\n }\n mkdirSync(projectPath, { recursive: true });\n\n const lang = opts.lang === 'ts' ? 'ts' : 'js';\n const templateDir = lang === 'ts' ? 'student-framework-ts' : 'student-framework';\n const templatePath = resolveTemplatePath(templateDir);\n\n if (!templatePath) {\n console.error(`❌ Could not locate template \"${templateDir}\"`);\n console.error('Please ensure the package is built correctly with templates included.');\n process.exit(1);\n }\n\n console.log(`📦 Copying template from ${templatePath}...`);\n \n // Recursive copy function\n function copyRecursive(src: string, dest: string) {\n if (statSync(src).isDirectory()) {\n mkdirSync(dest, { recursive: true });\n readdirSync(src).forEach(child => {\n copyRecursive(join(src, child), join(dest, child));\n });\n } else {\n cpSync(src, dest);\n }\n }\n\n copyRecursive(templatePath, projectPath);\n\n // 2.5 Adjust for OS compatibility (macOS 13/Ventura or older)\n const legacyMacOs = isLegacyMacOs();\n if (legacyMacOs) {\n console.log('🍎 Detected macOS 13 or older. Adjusting versions for compatibility...');\n const pkgJsonPath = join(projectPath, 'package.json');\n if (existsSync(pkgJsonPath)) {\n try {\n const pkgContent = readFileSync(pkgJsonPath, 'utf-8');\n const pkg = JSON.parse(pkgContent);\n if (pkg.devDependencies) {\n pkg.devDependencies['@playwright/test'] = '^1.48.2';\n pkg.devDependencies['allure-playwright'] = '^2.15.1';\n writeFileSync(pkgJsonPath, JSON.stringify(pkg, null, 2));\n console.log('✅ Pinned Playwright packages for legacy macOS compatibility.');\n }\n } catch (err) {\n console.warn('⚠️ Failed to adjust package.json for OS compatibility:', err);\n }\n }\n }\n\n // 3. Initialize git\n try {\n execSync('git init', { cwd: projectPath, stdio: 'ignore' });\n // Create .gitignore if not exists (template should have it, but just in case)\n const gitignorePath = join(projectPath, '.gitignore');\n if (!existsSync(gitignorePath)) {\n writeFileSync(gitignorePath, 'node_modules\\n.env\\ntest-results\\nplaywright-report\\n.cementic\\n');\n }\n } catch (e) {\n console.warn('⚠️ Failed to initialize git repository.');\n }\n\n // 4. Install dependencies\n console.log('📦 Installing dependencies...');\n let dependenciesInstalled = false;\n try {\n execSync('npm install', { cwd: projectPath, stdio: 'inherit' });\n dependenciesInstalled = true;\n } catch (e) {\n console.error('❌ Failed to install dependencies. Please run \"npm install\" manually.');\n }\n\n // 5. Install browsers (optional)\n // Commander maps --no-browsers to opts.browsers = false\n if (opts.browsers !== false && dependenciesInstalled) {\n console.log('🌐 Installing Playwright browsers...');\n try {\n if (legacyMacOs) {\n console.log('⚠️ WebKit is not supported on this macOS version. Installing Chromium only...');\n execSync('npx playwright install chromium', { cwd: projectPath, stdio: 'inherit' });\n console.log('✅ Chromium installed successfully.');\n } else {\n execSync('npx playwright install', { cwd: projectPath, stdio: 'inherit' });\n console.log('✅ Playwright browsers installed successfully.');\n }\n } catch (e) {\n console.warn('⚠️ Browser installation did not complete. You can finish setup with:');\n console.warn(' npx playwright install chromium');\n }\n }\n\n console.log(`\\n✅ Project ${projectName} created successfully!`);\n console.log(`\\nTo get started:\\n`);\n console.log(` cd ${projectName}`);\n console.log(` npx playwright test`);\n console.log(`\\nHappy testing! 🧪`);\n });\n\n return cmd;\n}\n\nfunction isLegacyMacOs(): boolean {\n if (platform() !== 'darwin') return false;\n\n const majorVersion = parseInt(release().split('.')[0], 10);\n return Number.isFinite(majorVersion) && majorVersion < LEGACY_MACOS_DARWIN_MAJOR;\n}\n","import { Command } from 'commander';\nimport fg from 'fast-glob';\nimport { readFileSync, mkdirSync, writeFileSync, statSync } from 'node:fs';\nimport { join, basename, resolve } from 'node:path';\n\ntype NormalizedCase = {\n id?: string;\n title: string;\n tags?: string[];\n steps: string[];\n step_hints?: Array<{ selector?: string }>;\n expected: string[];\n assertion_hints?: Array<{ playwright?: string }>;\n needs_review: boolean;\n review_reasons: string[];\n source: string;\n url?: string;\n};\n\n/** Grab @tags from the title line */\nfunction parseTags(title: string): { clean: string; tags: string[] } {\n const tags = Array.from(title.matchAll(/@([\\w-]+)/g)).map((m) => m[1]);\n const clean = title.replace(/@[\\w-]+/g, '').trim();\n return { clean, tags };\n}\n\n/** Try to extract an ID prefix like AUTH-001 from the title */\nfunction parseId(title: string): string | undefined {\n const m = title.match(/\\b([A-Z]+-\\d+)\\b/);\n return m?.[1];\n}\n\nfunction stripIdPrefixFromTitle(title: string, id?: string): string {\n if (!id) return title.trim();\n return title.replace(new RegExp(`^${id}\\\\s*[—\\\\-–:]\\\\s*`), '').trim();\n}\n\n/** Split a markdown file into case blocks by top-level \"# \" headings */\nfunction splitCasesByHeading(fileText: string): Array<{ titleLine: string; body: string }> {\n const lines = fileText.split(/\\r?\\n/);\n const blocks: Array<{ titleLine: string; body: string }> = [];\n let currentTitle: string | null = null;\n let buf: string[] = [];\n\n const flush = () => {\n if (currentTitle !== null) {\n blocks.push({ titleLine: currentTitle, body: buf.join('\\n') });\n }\n buf = [];\n };\n\n for (const line of lines) {\n const h1 = line.match(/^\\s*#\\s+(.+)$/); // \"# Title\"\n if (h1) {\n if (currentTitle !== null) flush();\n currentTitle = h1[1].trim();\n } else {\n buf.push(line);\n }\n }\n if (currentTitle !== null) flush();\n\n // If no H1 at all, treat whole file as one case (first non-empty line is title).\n if (blocks.length === 0) {\n const first = lines.find((l) => l.trim());\n const title = first?.replace(/^#\\s*/, '').trim() || 'Untitled';\n return [{ titleLine: title, body: lines.join('\\n') }];\n }\n return blocks;\n}\n\n/** From a case body, extract Steps and Expected sections */\nfunction extractSections(body: string): {\n steps: string[];\n stepHints: Array<{ selector?: string }>;\n expected: string[];\n assertionHints: Array<{ playwright?: string }>;\n} {\n // Find sections by H2 headings\n // Supports: \"## Steps\", \"## Expected\", \"## Expected Results\"\n const sectionRegex = /^\\s*##\\s*(.+?)\\s*$/gim;\n const sections: Record<string, string> = {};\n let match: RegExpExecArray | null;\n const indices: Array<{ name: string; index: number }> = [];\n\n while ((match = sectionRegex.exec(body))) {\n indices.push({ name: match[1].toLowerCase(), index: match.index });\n }\n\n // Add end sentinel\n indices.push({ name: '__END__', index: body.length });\n\n for (let i = 0; i < indices.length - 1; i++) {\n const name = indices[i].name;\n const slice = body.slice(indices[i].index, indices[i + 1].index);\n sections[name] = slice;\n }\n\n const stepsBlock =\n sections['steps'] ??\n ''; // if absent, we’ll infer from bullets later\n\n const expectedBlock =\n sections['expected'] ??\n sections['expected results'] ??\n sections['then'] ??\n '';\n\n const bullet = /^\\s*(?:\\d+\\.|[-*])\\s+(.+)$/gm;\n\n const parsedSteps = Array.from(stepsBlock.matchAll(bullet)).map((m) => parseHintedLine(m[1].trim(), 'selector'));\n const steps = parsedSteps.map((entry) => entry.text);\n const stepHints = parsedSteps.map((entry) => ({ selector: entry.hint }));\n\n // Fallback: if no dedicated steps section, collect bullets until a new H2\n if (steps.length === 0) {\n const alt = Array.from(body.matchAll(bullet)).map((m) => parseHintedLine(m[1].trim(), 'selector'));\n // Heuristic: take the first bullet run in the body\n steps.push(...alt.map((entry) => entry.text));\n stepHints.push(...alt.map((entry) => ({ selector: entry.hint })));\n }\n\n const parsedExpected = Array.from(expectedBlock.matchAll(bullet)).map((m) => parseHintedLine(m[1].trim(), 'playwright'));\n const expectedLines = parsedExpected.map((entry) => entry.text);\n const assertionHints = parsedExpected.map((entry) => ({ playwright: entry.hint }));\n\n // Fallback: lines that start with Expected/Then/Verify/Assert in the whole body\n if (expectedLines.length === 0) {\n const exp = Array.from(\n body.matchAll(/^\\s*(?:Expected|Then|Verify|Assert)[^\\n]*:?[\\s-]*(.+)$/gim)\n ).map((m) => parseHintedLine(m[1].trim(), 'playwright'));\n expectedLines.push(...exp.map((entry) => entry.text));\n assertionHints.push(...exp.map((entry) => ({ playwright: entry.hint })));\n }\n\n return { steps, stepHints, expected: expectedLines, assertionHints };\n}\n\nfunction extractUrlMetadata(body: string): string | undefined {\n const match = body.match(/<!--\\s*ct:url\\s+(https?:\\/\\/[^\\s>]+)\\s*-->/i);\n return match?.[1];\n}\n\nfunction stripCtMetadata(body: string): string {\n return body.replace(/^\\s*<!--\\s*ct:url\\s+https?:\\/\\/[^\\s>]+\\s*-->\\s*\\n?/im, '');\n}\n\nfunction parseHintedLine(\n value: string,\n hintType: 'selector' | 'playwright',\n): { text: string; hint?: string } {\n const match = value.match(new RegExp(`^(.*?)\\\\s*<!--\\\\s*${hintType}:\\\\s*([\\\\s\\\\S]*?)\\\\s*-->\\\\s*$`, 'i'));\n if (!match) return { text: value.trim() };\n return {\n text: match[1].trim(),\n hint: match[2].trim() || undefined,\n };\n}\n\nfunction extractUrlFromSteps(steps: string[]): string | undefined {\n for (const step of steps) {\n const match = step.match(/https?:\\/\\/[^\\s'\"]+/i);\n if (match) return match[0];\n }\n return undefined;\n}\n\n/** Build one normalized case from a title line + body */\nfunction normalizeOne(titleLine: string, body: string, source: string): NormalizedCase {\n const { clean, tags } = parseTags(titleLine);\n const id = parseId(clean);\n const metadataUrl = extractUrlMetadata(body);\n const cleanBody = stripCtMetadata(body);\n const { steps, stepHints, expected, assertionHints } = extractSections(cleanBody);\n const reviewReasons: string[] = [];\n\n if (steps.length === 0) reviewReasons.push('No steps section or bullets were parsed');\n if (expected.length === 0) reviewReasons.push('No expected results section or assertions were parsed');\n\n return {\n id,\n title: stripIdPrefixFromTitle(clean, id),\n tags: tags.length ? tags : undefined,\n steps,\n step_hints: stepHints.some(hint => hint.selector) ? stepHints : undefined,\n expected,\n assertion_hints: assertionHints.some(hint => hint.playwright) ? assertionHints : undefined,\n needs_review: reviewReasons.length > 0,\n review_reasons: reviewReasons,\n source,\n url: metadataUrl ?? extractUrlFromSteps(steps),\n };\n}\n\n/** ===== Commander command ===== */\nexport function normalizeCmd() {\n const cmd = new Command('normalize')\n .argument('<path>', 'Input directory or file pattern containing test cases (Markdown, Text, CSV)')\n .description('Convert human-readable test cases into machine-readable JSON format')\n .addHelpText('after', `\nExamples:\n $ ct normalize ./cases\n $ ct normalize \"cases/**/*.md\"\n $ ct normalize ./cases --and-gen --lang ts (Normalize and generate tests in one go)\n`)\n .option('--report', 'Generate a summary report of the normalization process', true)\n .option('--and-gen', 'Automatically run test generation after normalization', false)\n .option('--lang <lang>', 'Target language for generation (ts|js) when using --and-gen', 'ts')\n .action(async (inputPath: string, opts: { report?: boolean; andGen?: boolean; lang?: string }) => {\n // Accept directory OR glob\n let patterns: string[] = [];\n try {\n const abs = resolve(inputPath);\n if (statSync(abs).isDirectory()) {\n const base = inputPath.replace(/\\/$/, '');\n patterns = [`${base}/**/*.{md,markdown,txt,feature,csv,json}`];\n } else {\n patterns = [inputPath];\n }\n } catch {\n patterns = [inputPath];\n }\n\n const files = await fg(patterns, { dot: false, onlyFiles: true });\n if (files.length === 0) {\n console.error(`No files found for: ${inputPath}`);\n process.exit(2);\n }\n\n const outDir = '.cementic/normalized';\n mkdirSync(outDir, { recursive: true });\n\n const index = {\n summary: { total: 0, parsed: 0, withWarnings: 0 },\n cases: [] as Array<{ file: string; normalized: string; status: string }>\n };\n\n for (const f of files) {\n const content = readFileSync(f, 'utf8');\n\n // Split into multiple cases by \"# \"\n const blocks = splitCasesByHeading(content);\n for (const block of blocks) {\n const norm = normalizeOne(block.titleLine, block.body, f);\n\n // filename: <stem>.<ID or sanitized-title>.json\n const stem = basename(f).replace(/\\.[^/.]+$/, '');\n const suffix = (norm.id || norm.title).replace(/[^\\w-]+/g, '-');\n const outFile = join(outDir, `${stem}.${suffix}.json`);\n\n writeFileSync(outFile, JSON.stringify(norm, null, 2));\n\n index.summary.total++;\n index.summary.parsed++;\n if (norm.needs_review) index.summary.withWarnings++;\n index.cases.push({ file: f, normalized: outFile, status: norm.needs_review ? 'warning' : 'ok' });\n }\n }\n\n writeFileSync(join(outDir, '_index.json'), JSON.stringify(index, null, 2));\n\n if (opts.report !== false) {\n const lines = [\n '# Normalize Report',\n '',\n `Total cases: ${index.summary.total} | Parsed: ${index.summary.parsed} | With warnings: ${index.summary.withWarnings}`,\n '',\n '| Source File | Normalized JSON | Status |',\n '|-------------|-----------------|--------|',\n ...index.cases.map(c => `| ${c.file} | ${c.normalized} | ${c.status} |`)\n ];\n mkdirSync('.cementic/reports', { recursive: true });\n writeFileSync('.cementic/reports/normalize-report.md', lines.join('\\n'));\n }\n\n console.log(`✅ Normalized ${index.summary.parsed} case(s). Output → .cementic/normalized/`);\n\n if (opts.andGen) {\n const { gen } = await import('./gen.js');\n await gen({ lang: opts.lang || 'ts', out: 'tests/generated' });\n }\n });\n\n return cmd;\n}\n","import { Command } from 'commander';\nimport { spawn } from 'node:child_process';\n\nexport function testCmd() {\n const cmd = new Command('test')\n .description('Run Playwright tests via \"npx playwright test\"')\n .allowUnknownOption(true)\n .allowExcessArguments(true)\n .argument('[...pwArgs]', 'Arguments to pass through to Playwright')\n .action((pwArgs: string[] = []) => {\n const child = spawn(\n 'npx',\n ['playwright', 'test', ...pwArgs],\n {\n stdio: 'inherit',\n shell: process.platform === 'win32', // needed for Windows\n }\n );\n\n child.on('exit', (code) => {\n process.exit(code ?? 0);\n });\n });\n\n return cmd;\n}","import { Command } from 'commander';\nimport { mkdirSync, writeFileSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { createInterface } from 'node:readline/promises';\nimport { stdin as input, stdout as output } from 'node:process';\nimport { inferPrefix } from '../core/prefix.js';\nimport { generateTcMarkdownWithAi } from '../core/llm.js';\nimport { analyseElements } from '../core/analyse.js';\nimport { captureElements, formatCaptureFailure, toPageSummary } from '../core/capture.js';\nimport {\n printCaptureReport,\n saveCaptureJson,\n saveCasesMarkdown,\n saveSpecPreview,\n} from '../core/report.js';\n\nfunction slugify(text: string): string {\n return (\n text\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-+|-+$/g, '') || 'tc'\n );\n}\n\nfunction injectUrlMetadata(markdown: string, url?: string): string {\n if (!url || /<!--\\s*ct:url\\s+/i.test(markdown)) return markdown;\n\n const lines = markdown.split('\\n');\n const output: string[] = [];\n\n for (let i = 0; i < lines.length; i++) {\n output.push(lines[i]);\n if (/^\\s*#\\s+/.test(lines[i])) {\n output.push(`<!-- ct:url ${url} -->`);\n }\n }\n\n return output.join('\\n');\n}\n\nfunction buildManualCasesMarkdown(opts: {\n prefix: string;\n feature: string;\n url?: string;\n numCases: number;\n startIndex?: number;\n}): string {\n const { prefix, feature, url, numCases } = opts;\n const startIndex = opts.startIndex ?? 1;\n const lines: string[] = [];\n\n for (let i = 0; i < numCases; i++) {\n const idx = startIndex + i;\n const id = `${prefix}-${String(idx).padStart(3, '0')}`;\n\n lines.push(`# ${id} — ${feature} - scenario ${idx} @regression @ui`);\n if (url) lines.push(`<!-- ct:url ${url} -->`);\n lines.push(`## Steps`);\n lines.push(`1. Navigate to ${url ?? '<PAGE_URL>'}`);\n lines.push(`2. Perform the main user action for this scenario`);\n lines.push(`3. Observe the result`);\n lines.push('');\n lines.push(`## Expected Results`);\n lines.push(`- The page responds correctly for this scenario`);\n lines.push(`- UI reflects the expected change`);\n lines.push('');\n lines.push('');\n }\n\n return lines.join('\\n');\n}\n\nasync function promptBasicQuestions(opts: {\n url?: string;\n feature?: string;\n appDescription?: string;\n numCases?: number;\n}) {\n // Non-interactive mode: all required options were passed as flags\n if (opts.feature) {\n const n = Math.min(Math.max(opts.numCases ?? 3, 1), 10);\n return {\n feature: opts.feature,\n appDescription: opts.appDescription ?? '',\n numCases: n,\n url: opts.url,\n };\n }\n\n // Interactive mode\n const rl = createInterface({ input, output });\n\n const feature = (await rl.question('🧩 Feature or page to test: ')).trim();\n const appDescription = (await rl.question('📝 Short app description (optional): ')).trim();\n const numCasesRaw = (await rl.question('🔢 How many test cases? (1–10) [3]: ')).trim();\n\n rl.close();\n\n let numCases = parseInt(numCasesRaw, 10);\n if (isNaN(numCases) || numCases < 1) numCases = 3;\n if (numCases > 10) numCases = 10;\n\n return { feature, appDescription, numCases, url: opts.url };\n}\n\nasync function runTcInteractive(params: {\n url?: string;\n explicitPrefix?: string;\n feature?: string;\n appDescription?: string;\n numCases?: number;\n useAi: boolean;\n headed?: boolean;\n captureOnly?: boolean;\n}) {\n const { feature, appDescription, numCases, url } = await promptBasicQuestions({\n url: params.url,\n feature: params.feature,\n appDescription: params.appDescription,\n numCases: params.numCases,\n });\n\n const prefix = inferPrefix({\n featureText: feature,\n url,\n explicitPrefix: params.explicitPrefix,\n });\n\n mkdirSync('cases', { recursive: true });\n const fileName = `${prefix.toLowerCase()}-${slugify(feature)}.md`;\n const fullPath = join('cases', fileName);\n\n let markdown: string;\n let pageSummary = undefined;\n\n if (params.useAi) {\n if (url) {\n try {\n console.log(`🔍 Capturing page: ${url}`);\n const elementMap = await captureElements(url, {\n headless: !(params.headed ?? false),\n verbose: true,\n });\n printCaptureReport(elementMap);\n\n const jsonPath = saveCaptureJson(elementMap);\n console.log(`📄 Saved capture JSON → ${jsonPath}`);\n pageSummary = toPageSummary(elementMap);\n\n if (params.captureOnly) {\n console.log('Capture-only mode requested. No test cases were generated.');\n return;\n }\n\n const analysis = await analyseElements(elementMap, { verbose: true });\n printCaptureReport(elementMap, analysis);\n\n const previewPath = saveSpecPreview(analysis);\n if (previewPath) {\n console.log(`🧪 Saved preview spec → ${previewPath}`);\n }\n\n const captureFileName = `${prefix.toLowerCase()}-${slugify(feature)}.md`;\n const generatedPath = saveCasesMarkdown(analysis, 'cases', captureFileName);\n console.log(`✅ Capture-based AI generated test cases → ${generatedPath}`);\n console.log('\\nNext steps:');\n console.log(` ct normalize ${generatedPath} --and-gen --lang ts`);\n console.log(' ct test');\n return;\n } catch (e: any) {\n printWarningBlock(formatCaptureFailure(e));\n console.warn('⚠️ Falling back to AI text generation without capture context.');\n if (params.captureOnly) {\n return;\n }\n }\n }\n\n try {\n markdown = await generateTcMarkdownWithAi({\n appDescription: appDescription || undefined,\n feature,\n url,\n pageSummary,\n prefix,\n startIndex: 1,\n numCases,\n });\n markdown = injectUrlMetadata(markdown, url);\n console.log('✅ AI generated test cases.');\n } catch (err: any) {\n printWarningBlock([\n 'AI generation failed.',\n err?.message ?? String(err),\n ]);\n markdown = buildManualCasesMarkdown({ prefix, feature, url, numCases, startIndex: 1 });\n console.log('📝 Generated manual test case templates instead.');\n }\n } else {\n markdown = buildManualCasesMarkdown({ prefix, feature, url, numCases, startIndex: 1 });\n console.log('📝 Generated manual test case templates (pass --ai to use AI).');\n }\n\n writeFileSync(fullPath, markdown);\n\n console.log(`\\n✍️ Wrote ${numCases} case(s) → ${fullPath}`);\n console.log('\\nNext steps:');\n console.log(' ct normalize ./cases --and-gen --lang ts');\n console.log(' ct test');\n}\n\nfunction printWarningBlock(lines: string[]): void {\n if (lines.length === 0) return;\n\n console.warn(`⚠️ ${lines[0]}`);\n for (const line of lines.slice(1)) {\n console.warn(line);\n }\n}\n\n// ─── Shared options factory ───────────────────────────────────────────────────\n\nfunction addSharedOptions(cmd: Command): Command {\n return cmd\n .option('--ai', 'Use AI to generate test cases (requires API key)')\n .option('--prefix <prefix>', 'Explicit ID prefix, e.g. AUTH, DASH, CART')\n .option('--feature <name>', 'Feature name — skips interactive prompt')\n .option('--desc <text>', 'App description — skips interactive prompt')\n .option('--count <n>', 'Number of cases (1–10)', parseInt);\n}\n\nfunction resolveCommanderOpts<T extends Record<string, unknown>>(opts: T | Command): T {\n if (typeof (opts as Command).optsWithGlobals === 'function') {\n return (opts as Command).optsWithGlobals<T>();\n }\n if (typeof (opts as Command).opts === 'function') {\n return (opts as Command).opts<T>();\n }\n return opts as T;\n}\n\n// ─── Command definition ───────────────────────────────────────────────────────\n\nexport function tcCmd() {\n const root = new Command('tc')\n .description('Create CementicTest case files (Markdown) under ./cases')\n .addHelpText('after', `\nExamples:\n $ ct tc --feature \"Login form\" --ai\n $ ct tc --feature \"Checkout\" --count 5 --prefix CHK\n $ ct tc url https://example.com/login --ai --feature \"Auth\"\n`);\n\n addSharedOptions(root).action(\n async (opts: { ai?: boolean; prefix?: string; feature?: string; desc?: string; count?: number } | Command) => {\n const resolvedOpts = resolveCommanderOpts<{ ai?: boolean; prefix?: string; feature?: string; desc?: string; count?: number }>(opts);\n await runTcInteractive({\n url: undefined,\n explicitPrefix: resolvedOpts.prefix,\n feature: resolvedOpts.feature,\n appDescription: resolvedOpts.desc,\n numCases: resolvedOpts.count,\n useAi: resolvedOpts.ai ?? false,\n });\n }\n );\n\n addSharedOptions(\n root\n .command('url')\n .argument('<url>', 'Page URL to use as live capture and AI context')\n .description('Generate test cases with capture-aware context from a specific live page')\n .option('--headed', 'Show the browser while capturing the page')\n .option('--capture-only', 'Run live page capture and save artifacts without generating cases')\n ).action(\n async (\n url: string,\n opts: { ai?: boolean; prefix?: string; feature?: string; desc?: string; count?: number; headed?: boolean; captureOnly?: boolean } | Command,\n command?: Command,\n ) => {\n const resolvedOpts = resolveCommanderOpts<{ ai?: boolean; prefix?: string; feature?: string; desc?: string; count?: number; headed?: boolean; captureOnly?: boolean }>(command ?? opts);\n await runTcInteractive({\n url,\n explicitPrefix: resolvedOpts.prefix,\n feature: resolvedOpts.feature,\n appDescription: resolvedOpts.desc,\n numCases: resolvedOpts.count,\n useAi: resolvedOpts.ai ?? false,\n headed: resolvedOpts.headed ?? false,\n captureOnly: resolvedOpts.captureOnly ?? false,\n });\n }\n );\n\n return root;\n}\n","// src/core/prefix.ts\n\nconst PREFIX_MAP: Array<{ keywords: string[]; prefix: string }> = [\n { keywords: ['login', 'sign in', 'signin', 'auth', 'authentication'], prefix: 'AUTH' },\n { keywords: ['dashboard', 'home'], prefix: 'DASH' },\n { keywords: ['profile', 'account'], prefix: 'PROF' },\n { keywords: ['cart', 'basket'], prefix: 'CART' },\n { keywords: ['checkout', 'payment', 'pay'], prefix: 'CHK' },\n { keywords: ['order', 'orders'], prefix: 'ORD' },\n { keywords: ['settings', 'preferences', 'config'], prefix: 'SET' },\n];\n\nfunction normalizeText(text: string): string {\n return text.toLowerCase().trim();\n}\n\nfunction deriveFromFreeText(text: string): string | undefined {\n const norm = normalizeText(text);\n for (const entry of PREFIX_MAP) {\n if (entry.keywords.some(k => norm.includes(k))) {\n return entry.prefix;\n }\n }\n // fallback: first word, first 4 alphanumerics\n const firstWord = norm.split(/\\s+/).find(w => /[a-z0-9]/.test(w));\n if (!firstWord) return undefined;\n return firstWord.replace(/[^a-z0-9]/gi, '').slice(0, 4).toUpperCase() || undefined;\n}\n\nfunction deriveFromUrl(url: string): string | undefined {\n try {\n const u = new URL(url);\n const segments = u.pathname.split('/').filter(Boolean);\n const last = segments[segments.length - 1] || '';\n if (!last) return undefined;\n return deriveFromFreeText(last);\n } catch {\n return undefined;\n }\n}\n\nexport function inferPrefix(params: {\n featureText?: string;\n url?: string;\n explicitPrefix?: string;\n}): string {\n // 1) explicit flag wins\n if (params.explicitPrefix) {\n return params.explicitPrefix.trim().toUpperCase();\n }\n\n // 2) feature text\n if (params.featureText) {\n const fromFeature = deriveFromFreeText(params.featureText);\n if (fromFeature) return fromFeature;\n }\n\n // 3) url\n if (params.url) {\n const fromUrl = deriveFromUrl(params.url);\n if (fromUrl) return fromUrl;\n }\n\n // 4) last-resort default\n return 'TC';\n}","export type ProviderName = 'deepseek' | 'anthropic' | 'gemini' | 'qwen' | 'kimi' | 'openai';\nexport type ProviderTransport = 'anthropic' | 'openai-compatible';\n\nexport type ProviderConfig = {\n provider: ProviderName;\n displayName: string;\n apiKey: string;\n model: string;\n baseUrl?: string;\n transport: ProviderTransport;\n};\n\nconst PROVIDER_ORDER: ProviderName[] = ['deepseek', 'anthropic', 'gemini', 'qwen', 'kimi', 'openai'];\n\nexport function resolveLlmProvider(env: NodeJS.ProcessEnv = process.env): ProviderConfig {\n const explicitProvider = (env.CT_LLM_PROVIDER ?? '').trim().toLowerCase();\n const providers = buildProviderConfigs(env);\n\n if (explicitProvider) {\n if (!(explicitProvider in providers)) {\n throw new Error(\n `Unsupported CT_LLM_PROVIDER=\"${explicitProvider}\". Use deepseek, anthropic, gemini, qwen, kimi, or openai.`\n );\n }\n\n const selected = providers[explicitProvider as ProviderName];\n if (!selected.apiKey) {\n throw new Error(\n `CT_LLM_PROVIDER=${explicitProvider} is set but the matching API key is missing.\\n${buildProviderSetupHelp()}`\n );\n }\n\n return selected;\n }\n\n for (const providerName of PROVIDER_ORDER) {\n if (providers[providerName].apiKey) return providers[providerName];\n }\n\n throw new Error(`No LLM API key found.\\n${buildProviderSetupHelp()}`);\n}\n\nexport function buildProviderSetupHelp(): string {\n return [\n ' OpenAI: export OPENAI_API_KEY=your-key',\n ' Anthropic: export ANTHROPIC_API_KEY=your-key',\n ' Gemini: export GEMINI_API_KEY=your-key',\n ' DeepSeek: export DEEPSEEK_API_KEY=your-key',\n ' Qwen: export QWEN_API_KEY=your-key',\n ' Kimi: export KIMI_API_KEY=your-key',\n ' Generic: export CT_LLM_API_KEY=your-key',\n ' export CT_LLM_BASE_URL=https://your-openai-compatible-endpoint/v1',\n ].join('\\n');\n}\n\nfunction buildProviderConfigs(env: NodeJS.ProcessEnv): Record<ProviderName, ProviderConfig> {\n return {\n deepseek: {\n provider: 'deepseek',\n displayName: 'DeepSeek',\n apiKey: env.DEEPSEEK_API_KEY ?? env.CT_DEEPSEEK_API_KEY ?? '',\n model: env.CT_LLM_MODEL ?? env.DEEPSEEK_MODEL ?? 'deepseek-chat',\n baseUrl: env.DEEPSEEK_BASE_URL ?? 'https://api.deepseek.com/v1',\n transport: 'openai-compatible',\n },\n anthropic: {\n provider: 'anthropic',\n displayName: 'Claude',\n apiKey: env.ANTHROPIC_API_KEY ?? env.CT_ANTHROPIC_API_KEY ?? '',\n model: env.CT_LLM_MODEL ?? env.ANTHROPIC_MODEL ?? 'claude-sonnet-4-5',\n baseUrl: 'https://api.anthropic.com',\n transport: 'anthropic',\n },\n gemini: {\n provider: 'gemini',\n displayName: 'Gemini',\n apiKey: env.GEMINI_API_KEY ?? env.GOOGLE_API_KEY ?? '',\n model: env.CT_LLM_MODEL ?? env.GEMINI_MODEL ?? 'gemini-2.5-flash',\n baseUrl: env.GEMINI_BASE_URL ?? 'https://generativelanguage.googleapis.com/v1beta/openai',\n transport: 'openai-compatible',\n },\n qwen: {\n provider: 'qwen',\n displayName: 'Qwen',\n apiKey: env.QWEN_API_KEY ?? '',\n model: env.CT_LLM_MODEL ?? env.QWEN_MODEL ?? 'qwen-plus',\n baseUrl: env.QWEN_BASE_URL ?? 'https://dashscope-intl.aliyuncs.com/compatible-mode/v1',\n transport: 'openai-compatible',\n },\n kimi: {\n provider: 'kimi',\n displayName: 'Kimi',\n apiKey: env.KIMI_API_KEY ?? env.MOONSHOT_API_KEY ?? '',\n model: env.CT_LLM_MODEL ?? env.KIMI_MODEL ?? 'moonshot-v1-8k',\n baseUrl: env.KIMI_BASE_URL ?? 'https://api.moonshot.ai/v1',\n transport: 'openai-compatible',\n },\n openai: {\n provider: 'openai',\n displayName: env.CT_LLM_API_KEY && env.CT_LLM_BASE_URL ? 'OpenAI-compatible' : 'OpenAI',\n apiKey: env.CT_LLM_API_KEY ?? env.OPENAI_API_KEY ?? '',\n model: env.CT_LLM_MODEL ?? env.OPENAI_MODEL ?? 'gpt-4o-mini',\n baseUrl: env.CT_LLM_BASE_URL ?? 'https://api.openai.com/v1',\n transport: 'openai-compatible',\n },\n };\n}\n","import type { PageSummary } from './capture.js';\nimport { resolveLlmProvider } from './llm-provider.js';\n\nexport type TcAiContext = {\n appDescription?: string;\n feature: string;\n url?: string;\n pageSummary?: PageSummary;\n prefix: string;\n startIndex: number;\n numCases: number;\n};\n\n// ─── Prompt builders ──────────────────────────────────────────────────────────\n\nfunction buildSystemMessage(): string {\n return `\nYou are a senior QA engineer and test automation specialist.\n\nYour job:\n- Receive context about a web feature or page\n- Generate high-quality, realistic UI test cases\n- Format them in strict Markdown that a downstream parser will process\n\nYou MUST follow this format exactly for each test case:\n\n# <ID> — <Short title> @<tag1> @<tag2>\n## Steps\n1. <user action>\n2. <user action>\n\n## Expected Results\n- <verifiable outcome>\n- <verifiable outcome>\n\nRules:\n- ID must be PREFIX-NNN where NNN is zero-padded 3 digits starting from startIndex\n- Use 1–3 tags: @smoke @regression @auth @ui @critical @happy-path @negative\n- Steps = concrete user actions (\"Click the 'Sign In' button\", \"Fill in email with 'user@example.com'\")\n- Expected Results = verifiable UI outcomes (\"Error message 'Invalid credentials' is visible\", \"Page redirects to /dashboard\")\n- Include both happy-path AND negative/edge-case tests\n- Do NOT explain or add preamble — output ONLY the test cases\n- No code blocks, no extra headings outside the pattern\n`.trim();\n}\n\nfunction buildUserMessage(ctx: TcAiContext): string {\n const lines: string[] = [];\n\n lines.push(`App / product description:`);\n lines.push(ctx.appDescription || 'N/A');\n lines.push('');\n\n lines.push(`Feature or page to test:`);\n lines.push(ctx.feature);\n lines.push('');\n\n if (ctx.url) {\n lines.push(`Page URL: ${ctx.url}`);\n lines.push('');\n }\n\n if (ctx.pageSummary) {\n const s = ctx.pageSummary;\n lines.push(`Live page analysis:`);\n\n if (s.title) lines.push(`- Page title: ${s.title}`);\n\n if (s.headings.length) {\n lines.push(`- Headings: ${s.headings.join(' | ')}`);\n }\n\n if (s.inputs.length) {\n const inputDescs = s.inputs.map(i => {\n const parts = [\n i.label && `label=\"${i.label}\"`,\n i.placeholder && `placeholder=\"${i.placeholder}\"`,\n i.name && `name=\"${i.name}\"`,\n i.type && i.type !== 'text' && `type=\"${i.type}\"`,\n i.testId && `data-testid=\"${i.testId}\"`,\n ].filter(Boolean);\n return parts.join(', ');\n });\n lines.push(`- Form inputs: ${inputDescs.join(' | ')}`);\n }\n\n if (s.buttons.length) {\n lines.push(`- Buttons: ${s.buttons.join(' | ')}`);\n }\n\n if (s.links.length) {\n lines.push(`- Links: ${s.links.slice(0, 20).join(' | ')}`);\n }\n\n lines.push('');\n }\n\n lines.push(`Test ID prefix: ${ctx.prefix}`);\n lines.push(`Start numbering from: ${String(ctx.startIndex).padStart(3, '0')}`);\n lines.push(`Number of test cases: ${ctx.numCases}`);\n lines.push('');\n lines.push(`Include a mix of: happy-path flows, validation/error cases, and edge cases.`);\n lines.push(`Output ONLY the test cases. No explanation, no preamble.`);\n\n return lines.join('\\n');\n}\n\n// ─── Anthropic call ───────────────────────────────────────────────────────────\n\nasync function callAnthropic(\n apiKey: string,\n model: string,\n system: string,\n user: string\n): Promise<string> {\n const response = await fetch('https://api.anthropic.com/v1/messages', {\n method: 'POST',\n headers: {\n 'x-api-key': apiKey,\n 'anthropic-version': '2023-06-01',\n 'content-type': 'application/json',\n },\n body: JSON.stringify({\n model,\n max_tokens: 4096,\n system,\n messages: [{ role: 'user', content: user }],\n }),\n });\n\n if (!response.ok) {\n const text = await response.text();\n throw new Error(`Anthropic API error ${response.status}: ${text}`);\n }\n\n const json: any = await response.json();\n const content = json.content?.[0]?.text?.trim() ?? '';\n if (!content) throw new Error('Anthropic response had no content');\n return content;\n}\n\n// ─── OpenAI-compatible call ───────────────────────────────────────────────────\n\nasync function callOpenAiCompatible(\n apiKey: string,\n model: string,\n baseUrl: string,\n displayName: string,\n system: string,\n user: string\n): Promise<string> {\n const response = await fetch(`${baseUrl}/chat/completions`, {\n method: 'POST',\n headers: {\n Authorization: `Bearer ${apiKey}`,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n model,\n temperature: 0.2,\n messages: [\n { role: 'system', content: system },\n { role: 'user', content: user },\n ],\n }),\n });\n\n if (!response.ok) {\n const text = await response.text();\n throw new Error(`${displayName} API error ${response.status}: ${text}`);\n }\n\n const json: any = await response.json();\n const content = json.choices?.[0]?.message?.content?.trim() ?? '';\n if (!content) throw new Error('OpenAI response had no content');\n return content;\n}\n\n// ─── Public API ───────────────────────────────────────────────────────────────\n\nexport async function generateTcMarkdownWithAi(ctx: TcAiContext): Promise<string> {\n const providerConfig = resolveLlmProvider();\n\n const system = buildSystemMessage();\n const user = buildUserMessage(ctx);\n\n console.log(`🤖 Using ${providerConfig.displayName} (${providerConfig.model})`);\n\n if (providerConfig.transport === 'anthropic') {\n return callAnthropic(providerConfig.apiKey, providerConfig.model, system, user);\n }\n\n return callOpenAiCompatible(\n providerConfig.apiKey,\n providerConfig.model,\n providerConfig.baseUrl ?? 'https://api.openai.com/v1',\n providerConfig.displayName,\n system,\n user,\n );\n}\n","import type { CapturedElement, ElementMap } from './capture.js';\nimport { resolveLlmProvider } from './llm-provider.js';\n\nexport type AnalysisStep = {\n action: 'navigate' | 'fill' | 'click' | 'select' | 'check' | 'keyboard' | 'hover';\n selector: string;\n value: string;\n human: string;\n};\n\nexport type AnalysisAssertion = {\n type: string;\n selector: string;\n expected: string;\n human: string;\n playwright: string;\n};\n\nexport type AnalysisScenario = {\n id: string;\n title: string;\n tags: string[];\n steps: AnalysisStep[];\n assertions: AnalysisAssertion[];\n narrator: string;\n codeLevel: 'beginner' | 'intermediate' | 'advanced';\n};\n\nexport type AnalysisResult = {\n url: string;\n feature: string;\n suggestedPrefix: string;\n scenarios: AnalysisScenario[];\n analysisNotes?: string;\n audioSummary?: string;\n};\n\ntype AuthElements = {\n usernameInput?: CapturedElement;\n passwordInput?: CapturedElement;\n submitButton?: CapturedElement;\n heading?: CapturedElement;\n};\n\nexport async function analyseElements(\n elementMap: ElementMap,\n options: { verbose?: boolean } = {},\n): Promise<AnalysisResult> {\n const { verbose = false } = options;\n const providerConfig = resolveLlmProvider();\n\n log(verbose, `\\n[analyse] Sending capture to ${providerConfig.displayName} (${providerConfig.model})`);\n\n const systemPrompt = buildSystemPrompt();\n const userPrompt = buildUserPrompt(elementMap);\n\n const rawResponse = providerConfig.transport === 'anthropic'\n ? await callAnthropic(providerConfig.apiKey, providerConfig.model, systemPrompt, userPrompt)\n : await callOpenAiCompatible(\n providerConfig.apiKey,\n providerConfig.model,\n providerConfig.baseUrl ?? 'https://api.openai.com/v1',\n providerConfig.displayName,\n systemPrompt,\n userPrompt,\n );\n\n const parsed = parseAnalysisJson(rawResponse);\n return sanitizeAnalysis(parsed, elementMap);\n}\n\nfunction buildSystemPrompt(): string {\n return `\nYou are a senior QA automation engineer and Playwright expert working on CementicTest.\n\nYour job is to analyse a structured map of interactive elements extracted from a live web page,\nthen produce a complete set of Playwright test scenarios.\n\nRULES:\n1. Use only selectors provided in the ElementMap.\n2. Every assertion must include an exact \"playwright\" field with a complete await expect(...) statement.\n3. Use clearly fake data like user@example.com.\n4. Include both happy-path and negative scenarios, but stay evidence-backed.\n5. Output only valid JSON matching the requested schema.\n6. Do not invent redirect targets, success pages, error text, password clearing, or security scenarios unless the capture explicitly supports them.\n7. If no status or alert region was captured, avoid scenarios that depend on unseen server-side validation messages.\n8. Prefer 3 to 5 realistic scenarios.\n9. The \"selector\" field must be the raw selector expression from the ElementMap, such as locator(\"#username\") or getByRole('button', { name: \"Login\" }). Never wrap selectors in page. or page.locator(\"...\") inside JSON.\n10. If a page clearly contains login or auth fields, do not create submit scenarios that only click the button. Include realistic fill steps for captured username/email and password inputs.\n\nOUTPUT SCHEMA:\n{\n \"url\": string,\n \"feature\": string,\n \"suggestedPrefix\": string,\n \"scenarios\": [\n {\n \"id\": string,\n \"title\": string,\n \"tags\": string[],\n \"steps\": [\n {\n \"action\": \"navigate\"|\"fill\"|\"click\"|\"select\"|\"check\"|\"keyboard\"|\"hover\",\n \"selector\": string,\n \"value\": string,\n \"human\": string\n }\n ],\n \"assertions\": [\n {\n \"type\": string,\n \"selector\": string,\n \"expected\": string,\n \"human\": string,\n \"playwright\": string\n }\n ],\n \"narrator\": string,\n \"codeLevel\": \"beginner\"|\"intermediate\"|\"advanced\"\n }\n ],\n \"analysisNotes\": string,\n \"audioSummary\": string\n}`.trim();\n}\n\nfunction buildUserPrompt(elementMap: ElementMap): string {\n const lines: string[] = [];\n const authElements = detectAuthElements(elementMap);\n\n lines.push('PAGE INFORMATION');\n lines.push(`URL: ${elementMap.url}`);\n lines.push(`Title: ${elementMap.title}`);\n lines.push(`Captured in: ${elementMap.mode} mode`);\n lines.push('');\n\n for (const category of ['input', 'button', 'link', 'heading', 'status'] as const) {\n const items = elementMap.elements.filter((element) => element.category === category);\n if (items.length === 0) continue;\n\n lines.push(`${category.toUpperCase()}S (${items.length} found):`);\n for (const item of items.slice(0, category === 'link' ? 10 : items.length)) {\n lines.push(` - [${item.confidence}] ${item.selector}`);\n lines.push(` Purpose: ${item.purpose}`);\n if (item.selectorAlt.length > 0) {\n lines.push(` Fallbacks: ${item.selectorAlt.slice(0, 2).join(' | ')}`);\n }\n }\n lines.push('');\n }\n\n if (elementMap.warnings.length > 0) {\n lines.push('CAPTURE WARNINGS:');\n for (const warning of elementMap.warnings) {\n lines.push(` - ${warning}`);\n }\n lines.push('');\n }\n\n const interactiveCount = elementMap.elements.filter((element) => (\n element.category === 'input' || element.category === 'button' || element.category === 'link'\n )).length;\n const statusCount = elementMap.elements.filter((element) => element.category === 'status').length;\n\n lines.push('EVIDENCE CONSTRAINTS:');\n lines.push(` - Interactive elements captured: ${interactiveCount}`);\n lines.push(` - Status or alert regions captured: ${statusCount}`);\n lines.push(' - If no redirect target is explicitly captured, do not assert a destination path.');\n lines.push(' - If no status region was captured, avoid exact server-side credential error claims.');\n if (authElements.usernameInput && authElements.passwordInput && authElements.submitButton) {\n lines.push(' - This page contains a captured auth form. Include fill steps for the username/email and password fields in credential-submission scenarios.');\n lines.push(' - For auth pages without captured post-submit evidence, prefer evidence-backed form-state assertions over invented success redirects.');\n }\n lines.push('');\n lines.push('Generate only the JSON response.');\n\n return lines.join('\\n');\n}\n\nasync function callAnthropic(\n apiKey: string,\n model: string,\n systemPrompt: string,\n userPrompt: string,\n): Promise<string> {\n const response = await fetch('https://api.anthropic.com/v1/messages', {\n method: 'POST',\n headers: {\n 'x-api-key': apiKey,\n 'anthropic-version': '2023-06-01',\n 'content-type': 'application/json',\n },\n body: JSON.stringify({\n model,\n max_tokens: 4096,\n system: systemPrompt,\n messages: [{ role: 'user', content: userPrompt }],\n }),\n });\n\n if (!response.ok) {\n throw new Error(`Anthropic API ${response.status}: ${await response.text()}`);\n }\n\n const json: any = await response.json();\n const content = json.content?.[0]?.text?.trim() ?? '';\n if (!content) throw new Error('Anthropic returned empty content');\n return content;\n}\n\nasync function callOpenAiCompatible(\n apiKey: string,\n model: string,\n baseUrl: string,\n displayName: string,\n systemPrompt: string,\n userPrompt: string,\n): Promise<string> {\n const response = await fetch(`${baseUrl}/chat/completions`, {\n method: 'POST',\n headers: {\n Authorization: `Bearer ${apiKey}`,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n model,\n temperature: 0.1,\n messages: [\n { role: 'system', content: systemPrompt },\n { role: 'user', content: userPrompt },\n ],\n }),\n });\n\n if (!response.ok) {\n throw new Error(`${displayName} API ${response.status}: ${await response.text()}`);\n }\n\n const json: any = await response.json();\n const content = json.choices?.[0]?.message?.content?.trim() ?? '';\n if (!content) throw new Error('OpenAI-compatible provider returned empty content');\n return content;\n}\n\nfunction parseAnalysisJson(raw: string): AnalysisResult {\n const stripped = raw\n .replace(/^```(?:json)?\\s*/m, '')\n .replace(/\\s*```\\s*$/m, '')\n .trim();\n\n try {\n return JSON.parse(stripped);\n } catch (error: any) {\n throw new Error(\n `Failed to parse LLM response as JSON.\\nParse error: ${error?.message ?? error}\\nRaw response:\\n${raw.slice(0, 500)}`\n );\n }\n}\n\nfunction sanitizeAnalysis(analysis: AnalysisResult, elementMap: ElementMap): AnalysisResult {\n const selectors = new Set<string>();\n for (const element of elementMap.elements) {\n selectors.add(element.selector);\n for (const alt of element.selectorAlt) selectors.add(alt);\n }\n\n const rawScenarios = Array.isArray(analysis.scenarios) ? analysis.scenarios : [];\n const currentUrl = new URL(elementMap.url);\n const authElements = detectAuthElements(elementMap);\n const knownPaths = new Set([\n currentUrl.pathname,\n ...elementMap.elements\n .filter((element) => element.category === 'link')\n .map((element) => {\n const href = element.attributes?.href;\n if (typeof href !== 'string') return '';\n try {\n return new URL(href, elementMap.url).pathname;\n } catch {\n return href;\n }\n })\n .filter(Boolean),\n ]);\n\n const sanitizedScenarios = rawScenarios\n .map((scenario) => normalizeScenario(scenario, selectors, elementMap.url))\n .filter((scenario) => scenario.steps.length > 0 && scenario.assertions.length > 0)\n .map((scenario) => ({\n ...scenario,\n tags: scenario.tags.map(normalizeTag),\n assertions: scenario.assertions.filter((assertion) => {\n if (assertion.type !== 'url') return true;\n const combined = `${assertion.expected} ${assertion.human} ${assertion.playwright}`;\n const pathMatch = combined.match(/\\/[a-z0-9/_-]+/i);\n if (!pathMatch) return true;\n return knownPaths.has(pathMatch[0]);\n }),\n }))\n .filter((scenario) => scenario.assertions.length > 0)\n .slice(0, 5);\n\n const useAuthFallback = shouldUseAuthFallback(authElements, sanitizedScenarios);\n const finalScenarios = useAuthFallback\n ? buildAuthFallbackScenarios(elementMap, analysis.suggestedPrefix || inferPrefix(elementMap), authElements)\n : sanitizedScenarios.length > 0\n ? sanitizedScenarios\n : buildFallbackScenarios(elementMap, analysis.suggestedPrefix || 'FLOW');\n\n return {\n ...analysis,\n url: analysis.url || elementMap.url,\n feature: analysis.feature || inferFeatureName(elementMap),\n suggestedPrefix: (analysis.suggestedPrefix || inferPrefix(elementMap)).toUpperCase(),\n scenarios: finalScenarios,\n analysisNotes: [\n analysis.analysisNotes,\n useAuthFallback ? 'Replaced low-evidence auth scenarios with deterministic evidence-backed auth coverage.' : '',\n `Sanitized to ${finalScenarios.length} evidence-backed scenario(s) from ${rawScenarios.length} raw scenario(s).`,\n ].filter(Boolean).join(' '),\n audioSummary: analysis.audioSummary || buildAudioSummary(analysis.feature || inferFeatureName(elementMap), finalScenarios),\n };\n}\n\nfunction normalizeScenario(candidate: any, selectors: Set<string>, url: string): AnalysisScenario {\n const steps = Array.isArray(candidate?.steps)\n ? candidate.steps\n .map((step: any) => normalizeStep(step, selectors))\n .filter(Boolean) as AnalysisStep[]\n : [];\n\n const assertions = Array.isArray(candidate?.assertions)\n ? candidate.assertions\n .map((assertion: any) => normalizeAssertion(assertion, selectors))\n .filter(Boolean) as AnalysisAssertion[]\n : [];\n\n const normalizedSteps = ensureNavigateStep(steps, url);\n\n return {\n id: candidate?.id ?? 'FLOW-001',\n title: candidate?.title ?? 'Captured page flow',\n tags: Array.isArray(candidate?.tags) ? candidate.tags : [],\n steps: normalizedSteps,\n assertions,\n narrator: candidate?.narrator ?? 'Let us run this captured test flow.',\n codeLevel: candidate?.codeLevel ?? 'beginner',\n };\n}\n\nfunction normalizeStep(candidate: any, selectors: Set<string>): AnalysisStep | null {\n if (!candidate) return null;\n\n const selector = String(candidate.selector ?? '').trim();\n if (selector !== 'page' && !selectors.has(selector)) return null;\n\n const action = String(candidate.action ?? '').trim() as AnalysisStep['action'];\n if (!['navigate', 'fill', 'click', 'select', 'check', 'keyboard', 'hover'].includes(action)) return null;\n\n return {\n action,\n selector,\n value: String(candidate.value ?? ''),\n human: String(candidate.human ?? '').trim() || defaultStepHuman(action, selector, String(candidate.value ?? '')),\n };\n}\n\nfunction normalizeAssertion(candidate: any, selectors: Set<string>): AnalysisAssertion | null {\n if (!candidate) return null;\n\n const selector = String(candidate.selector ?? '').trim();\n if (selector !== 'page' && !selectors.has(selector)) return null;\n\n const assertion: AnalysisAssertion = {\n type: String(candidate.type ?? 'visible').trim() || 'visible',\n selector,\n expected: String(candidate.expected ?? '').trim(),\n human: String(candidate.human ?? '').trim() || 'Expected state is verified',\n playwright: String(candidate.playwright ?? '').trim(),\n };\n\n assertion.playwright = normalizePlaywrightAssertion(assertion);\n return assertion;\n}\n\nfunction buildFallbackScenarios(elementMap: ElementMap, prefix: string): AnalysisScenario[] {\n const heading = elementMap.elements.find((element) => element.category === 'heading');\n const emailInput = elementMap.elements.find((element) => (\n element.category === 'input' &&\n (element.attributes.type === 'email' || /email/.test(`${element.name ?? ''} ${String(element.attributes.label ?? '')}`.toLowerCase()))\n ));\n const passwordInput = elementMap.elements.find((element) => (\n element.category === 'input' && element.attributes.type === 'password'\n ));\n const submitButton = elementMap.elements.find((element) => (\n element.category === 'button' && /login|sign in|submit|continue/i.test(element.name ?? '')\n )) ?? elementMap.elements.find((element) => element.category === 'button');\n\n const scenarios: AnalysisScenario[] = [];\n const tag = (value: string) => normalizeTag(value);\n const nextId = (index: number) => `${prefix}-${String(900 + index).padStart(3, '0')}`;\n\n if (heading) {\n scenarios.push({\n id: nextId(scenarios.length + 1),\n title: 'Page loads with expected heading',\n tags: [tag('smoke'), tag('page-load')],\n steps: [\n {\n action: 'navigate',\n selector: 'page',\n value: elementMap.url,\n human: 'Navigate to the captured page',\n },\n ],\n assertions: [\n {\n type: 'visible',\n selector: heading.selector,\n expected: 'visible',\n human: `${heading.name || 'Primary heading'} is visible`,\n playwright: `await expect(page.${heading.selector}).toBeVisible();`,\n },\n ],\n narrator: 'We will first confirm that the expected page heading is visible.',\n codeLevel: 'beginner',\n });\n }\n\n if (emailInput && passwordInput && submitButton) {\n scenarios.push({\n id: nextId(scenarios.length + 1),\n title: 'Submitting without a password keeps the user on the form',\n tags: [tag('validation'), tag('negative')],\n steps: [\n {\n action: 'navigate',\n selector: 'page',\n value: elementMap.url,\n human: 'Navigate to the captured page',\n },\n {\n action: 'fill',\n selector: emailInput.selector,\n value: 'user@example.com',\n human: 'Fill in the email field',\n },\n {\n action: 'click',\n selector: submitButton.selector,\n value: '',\n human: 'Click the submit button',\n },\n ],\n assertions: [\n {\n type: 'url',\n selector: 'page',\n expected: new URL(elementMap.url).pathname,\n human: 'User remains on the same page',\n playwright: `await expect(page).toHaveURL('${elementMap.url}');`,\n },\n {\n type: 'visible',\n selector: passwordInput.selector,\n expected: 'visible',\n human: 'Password field stays visible for correction',\n playwright: `await expect(page.${passwordInput.selector}).toBeVisible();`,\n },\n ],\n narrator: 'Next we will leave the password blank and confirm the form does not advance.',\n codeLevel: 'beginner',\n });\n }\n\n return scenarios.slice(0, 5);\n}\n\nfunction buildAuthFallbackScenarios(\n elementMap: ElementMap,\n prefix: string,\n authElements: AuthElements,\n): AnalysisScenario[] {\n const { usernameInput, passwordInput, submitButton, heading } = authElements;\n if (!usernameInput || !passwordInput || !submitButton) {\n return buildFallbackScenarios(elementMap, prefix);\n }\n\n const scenarios: AnalysisScenario[] = [];\n const tag = (value: string) => normalizeTag(value);\n const nextId = (index: number) => `${prefix}-${String(index).padStart(3, '0')}`;\n const usernameValue = inferAuthValue(usernameInput, 'username');\n const passwordValue = inferAuthValue(passwordInput, 'password');\n\n scenarios.push({\n id: nextId(1),\n title: 'Login form renders expected controls',\n tags: [tag('smoke'), tag('auth')],\n steps: [\n {\n action: 'navigate',\n selector: 'page',\n value: elementMap.url,\n human: 'Navigate to the login page',\n },\n ],\n assertions: [\n ...(heading ? [{\n type: 'visible',\n selector: heading.selector,\n expected: 'visible',\n human: `${heading.name || 'Login heading'} is visible`,\n playwright: visibleAssertion(heading.selector),\n }] : []),\n {\n type: 'visible',\n selector: usernameInput.selector,\n expected: 'visible',\n human: `${usernameInput.name || 'Username field'} is visible`,\n playwright: visibleAssertion(usernameInput.selector),\n },\n {\n type: 'visible',\n selector: passwordInput.selector,\n expected: 'visible',\n human: `${passwordInput.name || 'Password field'} is visible`,\n playwright: visibleAssertion(passwordInput.selector),\n },\n {\n type: 'visible',\n selector: submitButton.selector,\n expected: 'visible',\n human: `${submitButton.name || 'Submit button'} is visible`,\n playwright: visibleAssertion(submitButton.selector),\n },\n ],\n narrator: 'We first confirm that the captured login form is present and interactive.',\n codeLevel: 'beginner',\n });\n\n scenarios.push({\n id: nextId(2),\n title: 'User can enter credentials before submission',\n tags: [tag('auth'), tag('happy-path')],\n steps: [\n {\n action: 'navigate',\n selector: 'page',\n value: elementMap.url,\n human: 'Navigate to the login page',\n },\n {\n action: 'fill',\n selector: usernameInput.selector,\n value: usernameValue,\n human: 'Fill in the username field',\n },\n {\n action: 'fill',\n selector: passwordInput.selector,\n value: passwordValue,\n human: 'Fill in the password field',\n },\n ],\n assertions: [\n {\n type: 'value',\n selector: usernameInput.selector,\n expected: usernameValue,\n human: 'Username input contains the entered value',\n playwright: valueAssertion(usernameInput.selector, usernameValue),\n },\n {\n type: 'value',\n selector: passwordInput.selector,\n expected: passwordValue,\n human: 'Password input contains the entered value',\n playwright: valueAssertion(passwordInput.selector, passwordValue),\n },\n {\n type: 'visible',\n selector: submitButton.selector,\n expected: 'visible',\n human: `${submitButton.name || 'Submit button'} remains visible`,\n playwright: visibleAssertion(submitButton.selector),\n },\n ],\n narrator: 'Next we verify that both credential fields accept input before we submit the form.',\n codeLevel: 'beginner',\n });\n\n scenarios.push({\n id: nextId(3),\n title: 'Submitting without a password keeps the login form visible',\n tags: [tag('auth'), tag('negative')],\n steps: [\n {\n action: 'navigate',\n selector: 'page',\n value: elementMap.url,\n human: 'Navigate to the login page',\n },\n {\n action: 'fill',\n selector: usernameInput.selector,\n value: usernameValue,\n human: 'Fill in the username field',\n },\n {\n action: 'click',\n selector: submitButton.selector,\n value: '',\n human: 'Click the login button',\n },\n ],\n assertions: [\n {\n type: 'url',\n selector: 'page',\n expected: elementMap.url,\n human: 'User remains on the same login URL',\n playwright: `await expect(page).toHaveURL('${elementMap.url}');`,\n },\n {\n type: 'visible',\n selector: passwordInput.selector,\n expected: 'visible',\n human: 'Password field remains visible for correction',\n playwright: visibleAssertion(passwordInput.selector),\n },\n {\n type: 'visible',\n selector: submitButton.selector,\n expected: 'visible',\n human: `${submitButton.name || 'Login button'} remains visible`,\n playwright: visibleAssertion(submitButton.selector),\n },\n ],\n narrator: 'Finally we submit incomplete credentials and confirm the captured login form remains available for correction.',\n codeLevel: 'beginner',\n });\n\n return scenarios;\n}\n\nfunction inferFeatureName(elementMap: ElementMap): string {\n const heading = elementMap.elements.find((element) => element.category === 'heading' && element.name);\n return heading?.name || elementMap.title || 'Captured page';\n}\n\nfunction inferPrefix(elementMap: ElementMap): string {\n const source = `${elementMap.title} ${elementMap.url}`.toLowerCase();\n if (/\\blogin|sign in|auth/.test(source)) return 'AUTH';\n if (/\\bcheckout|cart|payment/.test(source)) return 'CHK';\n if (/\\bdashboard/.test(source)) return 'DASH';\n return 'FLOW';\n}\n\nfunction buildAudioSummary(feature: string, scenarios: AnalysisScenario[]): string {\n return `We finished validating ${feature || 'the captured page'} with ${scenarios.length} evidence-backed scenario${scenarios.length === 1 ? '' : 's'}.`;\n}\n\nfunction normalizeTag(value: string): string {\n const cleaned = String(value ?? '').trim().replace(/^@+/, '');\n return cleaned ? `@${cleaned}` : '@ui';\n}\n\nfunction detectAuthElements(elementMap: ElementMap): AuthElements {\n const usernameInput = elementMap.elements.find((element) => (\n element.category === 'input' &&\n /user(name)?|email|login/.test(`${element.name ?? ''} ${String(element.attributes.label ?? '')} ${String(element.attributes.name ?? '')}`.toLowerCase())\n ));\n const passwordInput = elementMap.elements.find((element) => (\n element.category === 'input' && String(element.attributes.type ?? '').toLowerCase() === 'password'\n ));\n const submitButton = elementMap.elements.find((element) => (\n element.category === 'button' && /login|log in|sign in|submit|continue/.test((element.name ?? '').toLowerCase())\n )) ?? elementMap.elements.find((element) => element.category === 'button');\n const heading = elementMap.elements.find((element) => (\n element.category === 'heading' && /login|sign in|auth/.test((element.name ?? '').toLowerCase())\n )) ?? elementMap.elements.find((element) => element.category === 'heading');\n\n return { usernameInput, passwordInput, submitButton, heading };\n}\n\nfunction shouldUseAuthFallback(authElements: AuthElements, scenarios: AnalysisScenario[]): boolean {\n if (!authElements.usernameInput || !authElements.passwordInput || !authElements.submitButton) return false;\n if (scenarios.length === 0) return true;\n\n const hasCredentialEntry = scenarios.some((scenario) => {\n const filledSelectors = new Set(\n scenario.steps\n .filter((step) => step.action === 'fill')\n .map((step) => step.selector),\n );\n\n return filledSelectors.has(authElements.usernameInput!.selector) && filledSelectors.has(authElements.passwordInput!.selector);\n });\n\n const hasBrokenLocatorWrapper = scenarios.some((scenario) => (\n scenario.assertions.some((assertion) => /page\\.locator\\((['\"])(getBy|locator\\()/i.test(assertion.playwright))\n ));\n\n return hasBrokenLocatorWrapper || !hasCredentialEntry;\n}\n\nfunction defaultStepHuman(action: AnalysisStep['action'], selector: string, value: string): string {\n if (action === 'navigate') return `Navigate to ${value || 'the page'}`;\n if (action === 'fill') return `Fill the field ${selector}`;\n if (action === 'click') return `Click ${selector}`;\n if (action === 'select') return `Select ${value} in ${selector}`;\n if (action === 'check') return `Check ${selector}`;\n if (action === 'keyboard') return `Press ${value}`;\n return `Interact with ${selector}`;\n}\n\nfunction normalizePlaywrightAssertion(assertion: AnalysisAssertion): string {\n const repaired = scopeBareSelectorsInAssertion(unwrapWrappedSelectorAssertion(assertion.playwright));\n if (repaired) return ensureStatement(repaired);\n\n const built = buildPlaywrightAssertion(assertion);\n if (built) return built;\n\n return ensureStatement(assertion.playwright);\n}\n\nfunction unwrapWrappedSelectorAssertion(playwright: string): string {\n const trimmed = String(playwright ?? '').trim();\n if (!trimmed) return '';\n\n return trimmed.replace(\n /page\\.locator\\(([\"'])(getBy(?:Role|Text|Label|Placeholder|TestId)\\((?:\\\\.|(?!\\1).)*?\\)|locator\\((?:\\\\.|(?!\\1).)*?\\))\\1\\)/g,\n 'page.$2',\n );\n}\n\nfunction scopeBareSelectorsInAssertion(playwright: string): string {\n const trimmed = String(playwright ?? '').trim();\n if (!trimmed) return '';\n\n return trimmed.replace(\n /\\bexpect\\((getByRole|getByText|getByLabel|getByPlaceholder|getByTestId|locator)\\(/g,\n 'expect(page.$1(',\n );\n}\n\nfunction buildPlaywrightAssertion(assertion: AnalysisAssertion): string {\n if (assertion.selector === 'page') {\n if (assertion.type === 'url' && assertion.expected) {\n return `await expect(page).toHaveURL(${JSON.stringify(assertion.expected)});`;\n }\n return '';\n }\n\n const target = selectorTarget(assertion.selector);\n if (!target) return '';\n\n if (assertion.type === 'value' && assertion.expected) {\n return `await expect(${target}).toHaveValue(${JSON.stringify(assertion.expected)});`;\n }\n\n const combined = `${assertion.expected} ${assertion.human} ${assertion.playwright}`.toLowerCase();\n if (/hidden|not visible|no longer visible|disappear/.test(combined)) {\n return `await expect(${target}).not.toBeVisible();`;\n }\n\n return `await expect(${target}).toBeVisible();`;\n}\n\nfunction selectorTarget(selector: string): string {\n const trimmed = String(selector ?? '').trim();\n if (!trimmed || trimmed === 'page') return 'page';\n if (trimmed.startsWith('page.')) return trimmed;\n return `page.${trimmed}`;\n}\n\nfunction visibleAssertion(selector: string): string {\n return `await expect(${selectorTarget(selector)}).toBeVisible();`;\n}\n\nfunction valueAssertion(selector: string, value: string): string {\n return `await expect(${selectorTarget(selector)}).toHaveValue(${JSON.stringify(value)});`;\n}\n\nfunction inferAuthValue(element: CapturedElement, kind: 'username' | 'password'): string {\n if (kind === 'password') return 'Secret123!';\n\n const haystack = `${element.name ?? ''} ${String(element.attributes.label ?? '')} ${String(element.attributes.name ?? '')}`.toLowerCase();\n if (/email/.test(haystack)) return 'user@example.com';\n return 'testuser';\n}\n\nfunction ensureStatement(value: string): string {\n const trimmed = String(value ?? '').trim();\n if (!trimmed) return '';\n return trimmed.endsWith(';') ? trimmed : `${trimmed};`;\n}\n\nfunction ensureNavigateStep(steps: AnalysisStep[], url: string): AnalysisStep[] {\n if (!url || steps.length === 0) return steps;\n if (steps.some((step) => step.action === 'navigate')) return steps;\n\n return [\n {\n action: 'navigate',\n selector: 'page',\n value: url,\n human: `Navigate to ${url}`,\n },\n ...steps,\n ];\n}\n\nfunction log(verbose: boolean, message: string): void {\n if (verbose) console.log(message);\n}\n","import { existsSync } from 'node:fs';\nimport { dirname, join, resolve } from 'node:path';\nimport { createRequire } from 'node:module';\nimport { fileURLToPath, pathToFileURL } from 'node:url';\n\ntype PlaywrightPackageName = '@playwright/test' | 'playwright-core';\n\nexport type PlaywrightResolution = {\n packageName: PlaywrightPackageName;\n resolvedPath: string;\n searchRoot: string;\n chromium: any;\n};\n\nconst require = createRequire(import.meta.url);\nconst moduleDir = dirname(fileURLToPath(import.meta.url));\n\nexport async function resolvePlaywrightChromium(cwd = process.cwd()): Promise<PlaywrightResolution> {\n const searchRoots = buildSearchRoots(cwd);\n\n for (const packageName of ['@playwright/test', 'playwright-core'] as const) {\n for (const searchRoot of searchRoots) {\n const resolvedPath = resolveFromRoot(packageName, searchRoot);\n if (!resolvedPath) continue;\n\n const imported = await import(pathToFileURL(resolvedPath).href);\n const chromium = imported.chromium ?? imported.default?.chromium;\n\n if (chromium) {\n return {\n packageName,\n resolvedPath,\n searchRoot,\n chromium,\n };\n }\n }\n }\n\n throw new Error(\n 'Playwright runtime not found in this project.\\n' +\n 'Try:\\n' +\n ' npm install\\n' +\n ' npx playwright install chromium'\n );\n}\n\nfunction buildSearchRoots(cwd: string): string[] {\n const roots = [resolve(cwd)];\n const projectRoot = findNearestProjectRoot(cwd);\n\n if (projectRoot && projectRoot !== roots[0]) {\n roots.push(projectRoot);\n }\n\n roots.push(moduleDir);\n return Array.from(new Set(roots));\n}\n\nfunction findNearestProjectRoot(startDir: string): string | undefined {\n let currentDir = resolve(startDir);\n\n while (true) {\n if (existsSync(join(currentDir, 'package.json'))) {\n return currentDir;\n }\n\n const parentDir = dirname(currentDir);\n if (parentDir === currentDir) return undefined;\n currentDir = parentDir;\n }\n}\n\nfunction resolveFromRoot(packageName: PlaywrightPackageName, searchRoot: string): string | undefined {\n try {\n return require.resolve(packageName, { paths: [searchRoot] });\n } catch {\n return undefined;\n }\n}\n","import { resolvePlaywrightChromium } from './playwright.js';\n\nexport type InputDescriptor = {\n label?: string;\n placeholder?: string;\n name?: string;\n type?: string;\n testId?: string;\n};\n\nexport type PageSummary = {\n url: string;\n title?: string;\n headings: string[];\n buttons: string[];\n links: string[];\n inputs: InputDescriptor[];\n landmarks: string[];\n rawLength: number;\n};\n\nexport type CaptureMode = 'headless' | 'headed';\nexport type CaptureConfidence = 'high' | 'medium' | 'low';\nexport type CaptureCategory = 'input' | 'button' | 'link' | 'heading' | 'status';\nexport type CaptureErrorCode = 'PLAYWRIGHT_NOT_FOUND' | 'BROWSER_NOT_INSTALLED' | 'PAGE_LOAD_FAILED' | 'CAPTURE_FAILED';\n\nexport type CapturedElement = {\n category: CaptureCategory;\n role: string;\n name?: string;\n selector: string;\n selectorAlt: string[];\n purpose: string;\n confidence: CaptureConfidence;\n attributes: Record<string, unknown>;\n};\n\nexport type ElementMap = {\n url: string;\n title: string;\n timestamp: string;\n mode: CaptureMode;\n summary: {\n totalElements: number;\n byCategory: Partial<Record<CaptureCategory, number>>;\n };\n elements: CapturedElement[];\n warnings: string[];\n};\n\ntype CaptureOptions = {\n headless?: boolean;\n timeoutMs?: number;\n verbose?: boolean;\n userAgent?: string;\n};\n\ntype DomButton = {\n tag: string;\n text?: string;\n testId?: string;\n id?: string;\n type?: string;\n disabled: boolean;\n selector?: string | null;\n cssPath?: string | null;\n};\n\ntype DomInput = {\n tag: string;\n type: string;\n label?: string;\n placeholder?: string;\n name?: string;\n id?: string;\n testId?: string;\n required: boolean;\n selector?: string | null;\n cssPath?: string | null;\n};\n\ntype DomLink = {\n text: string;\n href?: string;\n testId?: string;\n external: boolean;\n selector: string;\n};\n\ntype DomHeading = {\n level: string;\n text: string;\n selector: string;\n};\n\ntype DomStatusRegion = {\n role: string;\n ariaLive?: string;\n text?: string;\n selector: string;\n};\n\ntype DomForm = {\n id?: string;\n label?: string;\n action?: string;\n method: string;\n fieldCount: number;\n index: number;\n};\n\ntype DomData = {\n buttons: DomButton[];\n inputs: DomInput[];\n links: DomLink[];\n headings: DomHeading[];\n landmarks: Array<{ role: string; label: string }>;\n statusRegions: DomStatusRegion[];\n forms: DomForm[];\n pageUrl: string;\n pageTitle: string;\n};\n\nconst SETTLE_MS = 1200;\nconst DEFAULT_TIMEOUT_MS = 30_000;\nconst MAX_PER_CATEGORY = 50;\n\nexport class CaptureRuntimeError extends Error {\n code: CaptureErrorCode;\n\n constructor(code: CaptureErrorCode, message: string, options?: { cause?: unknown }) {\n super(message);\n this.name = 'CaptureRuntimeError';\n this.code = code;\n if (options?.cause !== undefined) {\n (this as Error & { cause?: unknown }).cause = options.cause;\n }\n }\n}\n\nexport async function captureElements(url: string, options: CaptureOptions = {}): Promise<ElementMap> {\n const {\n headless = true,\n timeoutMs = DEFAULT_TIMEOUT_MS,\n verbose = false,\n userAgent = 'Mozilla/5.0 (compatible; CementicTest/0.2.7 capture)',\n } = options;\n\n const chromium = await loadChromium();\n const mode: CaptureMode = headless ? 'headless' : 'headed';\n log(verbose, `\\n[capture] Starting ${mode} capture: ${url}`);\n\n let browser: any;\n\n try {\n browser = await chromium.launch({\n headless,\n slowMo: headless ? 0 : 150,\n });\n } catch (error: any) {\n throw classifyCaptureError(error);\n }\n\n const context = await browser.newContext({\n userAgent,\n viewport: { width: 1280, height: 800 },\n ignoreHTTPSErrors: true,\n });\n\n const page = await context.newPage();\n\n try {\n log(verbose, ` -> Navigating (timeout: ${timeoutMs}ms)`);\n try {\n await page.goto(url, {\n waitUntil: 'domcontentloaded',\n timeout: timeoutMs,\n });\n } catch (error: any) {\n throw new CaptureRuntimeError(\n 'PAGE_LOAD_FAILED',\n `Page load failed for ${url}. ${error?.message ?? error}`,\n { cause: error },\n );\n }\n\n log(verbose, ` -> Waiting ${SETTLE_MS}ms for page settle`);\n await page.waitForTimeout(SETTLE_MS);\n\n log(verbose, ' -> Extracting accessibility snapshot');\n const a11ySnapshot = await getAccessibilitySnapshot(page, verbose);\n\n log(verbose, ' -> Extracting DOM data');\n const domData = await page.evaluate(extractDomData);\n\n const title = await page.title();\n const finalUrl = page.url();\n const elements = buildElementMap(domData);\n const warnings = buildWarnings(elements, domData, a11ySnapshot);\n const byCategory: Partial<Record<CaptureCategory, number>> = {};\n\n for (const element of elements) {\n byCategory[element.category] = (byCategory[element.category] ?? 0) + 1;\n }\n\n const result: ElementMap = {\n url: finalUrl,\n title,\n timestamp: new Date().toISOString(),\n mode,\n summary: {\n totalElements: elements.length,\n byCategory,\n },\n elements,\n warnings,\n };\n\n log(verbose, ` -> Captured ${elements.length} testable elements from \"${title}\"`);\n return result;\n } catch (error: any) {\n throw classifyCaptureError(error);\n } finally {\n await browser?.close();\n }\n}\n\nexport function toPageSummary(elementMap: ElementMap): PageSummary {\n const inputs = elementMap.elements\n .filter((element): element is CapturedElement => element.category === 'input')\n .slice(0, 30)\n .map((element) => ({\n label: asString(element.attributes.label),\n placeholder: asString(element.attributes.placeholder),\n name: asString(element.attributes.name),\n type: asString(element.attributes.type),\n testId: asString(element.attributes.testId),\n }));\n\n return {\n url: elementMap.url,\n title: elementMap.title,\n headings: elementMap.elements\n .filter((element) => element.category === 'heading')\n .map((element) => element.name ?? '')\n .filter(Boolean)\n .slice(0, 20),\n buttons: elementMap.elements\n .filter((element) => element.category === 'button')\n .map((element) => element.name ?? '')\n .filter(Boolean)\n .slice(0, 30),\n links: elementMap.elements\n .filter((element) => element.category === 'link')\n .map((element) => element.name ?? '')\n .filter(Boolean)\n .slice(0, 50),\n inputs,\n landmarks: [],\n rawLength: elementMap.elements.length,\n };\n}\n\nasync function loadChromium(): Promise<any> {\n try {\n const resolution = await resolvePlaywrightChromium(process.cwd());\n return resolution.chromium;\n } catch (error: any) {\n throw new CaptureRuntimeError(\n 'PLAYWRIGHT_NOT_FOUND',\n error?.message ??\n 'Playwright runtime not found in this project.\\nTry:\\n npm install\\n npx playwright install chromium',\n { cause: error },\n );\n }\n}\n\nfunction extractDomData(): DomData {\n const localMaxPerCategory = 50;\n const attr = (el: Element, name: string): string | undefined => el.getAttribute(name)?.trim() || undefined;\n const text = (el: Element | null): string | undefined => el?.textContent?.replace(/\\s+/g, ' ').trim() || undefined;\n const jsString = (value: string) => JSON.stringify(value);\n\n const findLabel = (el: Element): string | undefined => {\n const id = attr(el, 'id');\n\n if (id) {\n const labelEl = document.querySelector(`label[for=\"${id}\"]`);\n if (labelEl) return text(labelEl);\n }\n\n const ariaLabel = attr(el, 'aria-label');\n if (ariaLabel) return ariaLabel;\n\n const labelledBy = attr(el, 'aria-labelledby');\n if (labelledBy) {\n const labelEl = document.getElementById(labelledBy);\n if (labelEl) return text(labelEl);\n }\n\n const closestLabel = el.closest('label');\n if (closestLabel) {\n const raw = text(closestLabel) || '';\n const placeholder = attr(el, 'placeholder') || '';\n return raw.replace(placeholder, '').trim() || undefined;\n }\n\n const previous = el.previousElementSibling;\n if (previous?.tagName === 'LABEL') return text(previous);\n\n return undefined;\n };\n\n const buildSelector = (el: Element, labelText?: string, buttonText?: string): string | null => {\n const testId = attr(el, 'data-testid');\n if (testId) return `getByTestId(${jsString(testId)})`;\n\n const id = attr(el, 'id');\n if (id && !id.match(/^(ember|react|vue|ng|auto|rand)/i)) {\n return `locator(${jsString(`#${id}`)})`;\n }\n\n const ariaLabel = attr(el, 'aria-label');\n if (ariaLabel) {\n return `getByRole(${jsString(el.getAttribute('role') || el.tagName.toLowerCase())}, { name: ${jsString(ariaLabel)} })`;\n }\n\n if (labelText) {\n const tag = el.tagName.toLowerCase();\n if (tag === 'input' || tag === 'textarea' || tag === 'select') {\n return `getByLabel(${jsString(labelText)})`;\n }\n }\n\n if (buttonText) return `getByRole('button', { name: ${jsString(buttonText)} })`;\n\n const name = attr(el, 'name');\n if (name) return `locator(${jsString(`[name=\"${name}\"]`)})`;\n\n return null;\n };\n\n const buttons: DomButton[] = [];\n document.querySelectorAll('button, [role=\"button\"], input[type=\"submit\"], input[type=\"button\"]').forEach((el) => {\n const buttonText = attr(el, 'aria-label') || text(el) || attr(el, 'value');\n const testId = attr(el, 'data-testid');\n const id = attr(el, 'id');\n const type = attr(el, 'type');\n const disabled = el.hasAttribute('disabled') || el.getAttribute('aria-disabled') === 'true';\n const selector = buildSelector(el, undefined, buttonText);\n\n if (buttonText || testId) {\n buttons.push({\n tag: el.tagName.toLowerCase(),\n text: buttonText,\n testId,\n id,\n type,\n disabled,\n selector,\n cssPath: testId ? `[data-testid=\"${testId}\"]` : (id ? `#${id}` : null),\n });\n }\n });\n\n const inputs: DomInput[] = [];\n document.querySelectorAll('input:not([type=\"hidden\"]):not([type=\"submit\"]):not([type=\"button\"]), textarea, select').forEach((el) => {\n const label = findLabel(el);\n const placeholder = attr(el, 'placeholder');\n const name = attr(el, 'name');\n const id = attr(el, 'id');\n const type = attr(el, 'type') || el.tagName.toLowerCase();\n const testId = attr(el, 'data-testid');\n const required = el.hasAttribute('required');\n const selector = buildSelector(el, label);\n\n if (label || placeholder || name || testId || id) {\n inputs.push({\n tag: el.tagName.toLowerCase(),\n type,\n label,\n placeholder,\n name,\n id,\n testId,\n required,\n selector,\n cssPath: testId ? `[data-testid=\"${testId}\"]` : (id ? `#${id}` : (name ? `[name=\"${name}\"]` : null)),\n });\n }\n });\n\n const links: DomLink[] = [];\n document.querySelectorAll('a[href]').forEach((el) => {\n const linkText = attr(el, 'aria-label') || text(el);\n const href = attr(el, 'href');\n const testId = attr(el, 'data-testid');\n\n if (!linkText || href === '#') return;\n\n links.push({\n text: linkText,\n href,\n testId,\n external: Boolean(href?.startsWith('http') && !href.includes(window.location.hostname)),\n selector: testId\n ? `getByTestId(${jsString(testId)})`\n : `getByRole('link', { name: ${jsString(linkText)} })`,\n });\n });\n\n const headings: DomHeading[] = [];\n document.querySelectorAll('h1, h2, h3').forEach((el) => {\n const headingText = text(el);\n if (headingText) {\n headings.push({\n level: el.tagName.toLowerCase(),\n text: headingText,\n selector: `getByRole('heading', { name: ${jsString(headingText)} })`,\n });\n }\n });\n\n const landmarks: Array<{ role: string; label: string }> = [];\n document.querySelectorAll('[role], main, nav, header, footer, aside, section[aria-label]').forEach((el) => {\n const role = attr(el, 'role') || el.tagName.toLowerCase();\n const label = attr(el, 'aria-label') || text(el)?.slice(0, 40);\n if (role && label) landmarks.push({ role, label });\n });\n\n const statusRegions: DomStatusRegion[] = [];\n document.querySelectorAll('[role=\"alert\"], [role=\"status\"], [aria-live]').forEach((el) => {\n const role = attr(el, 'role') || 'live';\n statusRegions.push({\n role,\n ariaLive: attr(el, 'aria-live'),\n text: text(el),\n selector: el.getAttribute('role')\n ? `getByRole(${jsString(role)})`\n : `locator('[aria-live]')`,\n });\n });\n\n const forms: DomForm[] = [];\n document.querySelectorAll('form').forEach((form, index) => {\n forms.push({\n id: attr(form, 'id'),\n label: attr(form, 'aria-label') || attr(form, 'aria-labelledby'),\n action: attr(form, 'action'),\n method: attr(form, 'method') || 'get',\n fieldCount: form.querySelectorAll('input, textarea, select').length,\n index,\n });\n });\n\n return {\n buttons: buttons.slice(0, localMaxPerCategory),\n inputs: inputs.slice(0, localMaxPerCategory),\n links: links.slice(0, localMaxPerCategory),\n headings: headings.slice(0, 20),\n landmarks,\n statusRegions,\n forms,\n pageUrl: window.location.href,\n pageTitle: document.title,\n };\n}\n\nfunction buildElementMap(domData: DomData): CapturedElement[] {\n const elements: CapturedElement[] = [];\n\n for (const input of domData.inputs) {\n const displayName = input.label || input.placeholder || input.name || input.testId;\n if (!displayName) continue;\n\n const selector = input.selector\n || (input.testId ? `getByTestId(${JSON.stringify(input.testId)})` : null)\n || (input.label ? `getByLabel(${JSON.stringify(input.label)})` : null)\n || (input.id ? `locator(${JSON.stringify(`#${input.id}`)})` : null)\n || (input.name ? `locator(${JSON.stringify(`[name=\"${input.name}\"]`)})` : null)\n || `locator(${JSON.stringify(`${input.tag}[placeholder=\"${input.placeholder ?? ''}\"]`)})`;\n\n const selectorAlt: string[] = [];\n if (input.id && !selector.includes(`#${input.id}`)) selectorAlt.push(`locator(${JSON.stringify(`#${input.id}`)})`);\n if (input.name && !selector.includes(input.name)) selectorAlt.push(`locator(${JSON.stringify(`[name=\"${input.name}\"]`)})`);\n if (input.testId && !selector.includes(input.testId)) selectorAlt.push(`getByTestId(${JSON.stringify(input.testId)})`);\n if (input.placeholder && !selector.includes(input.placeholder)) selectorAlt.push(`getByPlaceholder(${JSON.stringify(input.placeholder)})`);\n if (input.label && !selector.includes(input.label)) selectorAlt.push(`getByLabel(${JSON.stringify(input.label)})`);\n\n elements.push({\n category: 'input',\n role: input.type === 'checkbox' ? 'checkbox' : 'textbox',\n name: displayName,\n selector,\n selectorAlt,\n purpose: input.required\n ? `Required ${input.type} field - \"${displayName}\"`\n : `${input.type} field - \"${displayName}\"`,\n confidence: input.testId || input.label || input.id ? 'high' : (input.placeholder ? 'medium' : 'low'),\n attributes: {\n type: input.type,\n label: input.label,\n placeholder: input.placeholder,\n name: input.name,\n id: input.id,\n testId: input.testId,\n required: input.required,\n tag: input.tag,\n },\n });\n }\n\n for (const button of domData.buttons) {\n const displayName = button.text || button.testId;\n if (!displayName) continue;\n\n const selector = button.selector\n || (button.testId ? `getByTestId(${JSON.stringify(button.testId)})` : null)\n || (button.text ? `getByRole('button', { name: ${JSON.stringify(button.text)} })` : null)\n || (button.id ? `locator(${JSON.stringify(`#${button.id}`)})` : null)\n || `locator('button')`;\n\n const selectorAlt: string[] = [];\n if (button.id && !selector.includes(button.id)) selectorAlt.push(`locator(${JSON.stringify(`#${button.id}`)})`);\n if (button.testId && !selector.includes(button.testId)) selectorAlt.push(`getByTestId(${JSON.stringify(button.testId)})`);\n if (button.text && !selector.includes(button.text)) selectorAlt.push(`getByText(${JSON.stringify(button.text)})`);\n if (button.cssPath) selectorAlt.push(`locator(${JSON.stringify(button.cssPath)})`);\n\n elements.push({\n category: 'button',\n role: 'button',\n name: displayName,\n selector,\n selectorAlt,\n purpose: button.disabled\n ? `Disabled button - \"${displayName}\"`\n : button.type === 'submit'\n ? `Form submit button - \"${displayName}\"`\n : `Button - \"${displayName}\"`,\n confidence: button.testId || button.text ? 'high' : (button.id ? 'medium' : 'low'),\n attributes: {\n text: button.text,\n testId: button.testId,\n id: button.id,\n type: button.type,\n disabled: button.disabled,\n tag: button.tag,\n },\n });\n }\n\n for (const link of domData.links) {\n elements.push({\n category: 'link',\n role: 'link',\n name: link.text,\n selector: link.selector,\n selectorAlt: link.testId ? [`getByTestId(${JSON.stringify(link.testId)})`] : [],\n purpose: link.external\n ? `External link to \"${link.href}\" - \"${link.text}\"`\n : `Internal navigation link - \"${link.text}\" -> ${link.href}`,\n confidence: link.testId ? 'high' : 'medium',\n attributes: {\n text: link.text,\n href: link.href,\n testId: link.testId,\n external: link.external,\n },\n });\n }\n\n for (const heading of domData.headings) {\n elements.push({\n category: 'heading',\n role: 'heading',\n name: heading.text,\n selector: heading.selector,\n selectorAlt: [`getByText(${JSON.stringify(heading.text)})`],\n purpose: `Page ${heading.level} heading - use to assert the correct page or section loaded`,\n confidence: 'medium',\n attributes: {\n level: heading.level,\n text: heading.text,\n },\n });\n }\n\n for (const status of domData.statusRegions) {\n elements.push({\n category: 'status',\n role: status.role,\n name: status.text || status.role,\n selector: status.selector,\n selectorAlt: [],\n purpose: 'Live region - use to assert error messages, success toasts, and validation feedback',\n confidence: 'medium',\n attributes: {\n role: status.role,\n ariaLive: status.ariaLive,\n currentText: status.text,\n },\n });\n }\n\n return elements;\n}\n\nfunction buildWarnings(\n elements: CapturedElement[],\n domData: DomData,\n a11ySnapshot: unknown,\n): string[] {\n const warnings: string[] = [];\n\n if (!a11ySnapshot) {\n warnings.push('Playwright accessibility snapshot was unavailable. Capture continued using DOM extraction only.');\n }\n\n const lowConfidenceInputs = elements.filter((element) => element.category === 'input' && element.confidence === 'low');\n if (lowConfidenceInputs.length > 0) {\n warnings.push(\n `${lowConfidenceInputs.length} input(s) have low-confidence selectors. Consider adding data-testid attributes to: ${lowConfidenceInputs.map((element) => element.name).filter(Boolean).join(', ')}`\n );\n }\n\n if (domData.statusRegions.length === 0) {\n warnings.push('No ARIA alert or status regions detected. Error message assertions may need manual selector adjustments after generation.');\n }\n\n for (const form of domData.forms) {\n const hasSubmit = domData.buttons.some((button) => button.type === 'submit');\n if (form.fieldCount > 0 && !hasSubmit) {\n warnings.push(\n `Form ${form.id || `#${form.index}`} has ${form.fieldCount} field(s) but no detected submit button. It may use keyboard submit or a custom handler.`\n );\n }\n }\n\n if (domData.links.length >= MAX_PER_CATEGORY) {\n warnings.push(`Link count hit the ${MAX_PER_CATEGORY} capture limit. Generation will focus on forms and buttons.`);\n }\n\n const interactive = elements.filter((element) => (\n element.category === 'button' || element.category === 'input' || element.category === 'link'\n ));\n if (interactive.length === 0) {\n warnings.push('No interactive elements detected. The page may require authentication, render later than the current settle window, or be mostly static content.');\n }\n\n return warnings;\n}\n\nfunction log(verbose: boolean, message: string): void {\n if (verbose) console.log(message);\n}\n\nasync function getAccessibilitySnapshot(page: any, verbose: boolean): Promise<unknown> {\n if (!page.accessibility || typeof page.accessibility.snapshot !== 'function') {\n log(verbose, ' -> Accessibility snapshot API unavailable; continuing with DOM-only capture');\n return null;\n }\n\n try {\n return await page.accessibility.snapshot({ interestingOnly: false });\n } catch (error: any) {\n log(verbose, ` -> Accessibility snapshot failed (${error?.message ?? error}); continuing with DOM-only capture`);\n return null;\n }\n}\n\nfunction asString(value: unknown): string | undefined {\n return typeof value === 'string' ? value : undefined;\n}\n\nexport function formatCaptureFailure(error: unknown): string[] {\n const resolved = classifyCaptureError(error);\n\n if (resolved.code === 'PLAYWRIGHT_NOT_FOUND') {\n return [\n 'Playwright not resolvable.',\n 'Playwright runtime not found in this project.',\n 'Try:',\n ' npm install',\n ' npx playwright install chromium',\n ];\n }\n\n if (resolved.code === 'BROWSER_NOT_INSTALLED') {\n return [\n 'Browser not installed.',\n 'Playwright resolved, but Chromium is not installed for this project.',\n 'Try:',\n ' npx playwright install chromium',\n ];\n }\n\n if (resolved.code === 'PAGE_LOAD_FAILED') {\n return [\n 'Page load failed.',\n resolved.message,\n ];\n }\n\n return [\n 'Capture failed.',\n resolved.message,\n ];\n}\n\nfunction classifyCaptureError(error: unknown): CaptureRuntimeError {\n if (error instanceof CaptureRuntimeError) {\n return error;\n }\n\n const message = errorMessage(error);\n\n if (isBrowserInstallError(message)) {\n return new CaptureRuntimeError(\n 'BROWSER_NOT_INSTALLED',\n 'Playwright resolved, but Chromium is not installed for this project.',\n { cause: error },\n );\n }\n\n if (isPlaywrightNotFoundError(message)) {\n return new CaptureRuntimeError(\n 'PLAYWRIGHT_NOT_FOUND',\n 'Playwright runtime not found in this project.',\n { cause: error },\n );\n }\n\n return new CaptureRuntimeError('CAPTURE_FAILED', message || 'Unknown capture failure.', { cause: error });\n}\n\nfunction isBrowserInstallError(message: string): boolean {\n return /Executable doesn't exist|browserType\\.launch: Executable doesn't exist|Please run the following command|playwright install/i.test(message);\n}\n\nfunction isPlaywrightNotFoundError(message: string): boolean {\n return /Playwright runtime not found|Cannot find package ['\"](?:@playwright\\/test|playwright-core)['\"]/i.test(message);\n}\n\nfunction errorMessage(error: unknown): string {\n if (error instanceof Error) return error.message;\n return String(error ?? '');\n}\n","import { mkdirSync, writeFileSync } from 'node:fs';\nimport { join } from 'node:path';\nimport type { AnalysisResult } from './analyse.js';\nimport type { ElementMap } from './capture.js';\n\nexport function printCaptureReport(elementMap: ElementMap, analysis?: AnalysisResult | null): void {\n console.log('');\n console.log('='.repeat(60));\n console.log('CementicTest Capture Report');\n console.log('='.repeat(60));\n console.log(`URL: ${elementMap.url}`);\n console.log(`Title: ${elementMap.title}`);\n console.log(`Captured: ${elementMap.timestamp} (${elementMap.mode})`);\n console.log('');\n console.log('Elements:');\n\n for (const [category, count] of Object.entries(elementMap.summary.byCategory)) {\n console.log(` ${category}: ${count}`);\n }\n\n if (elementMap.warnings.length > 0) {\n console.log('');\n console.log('Warnings:');\n for (const warning of elementMap.warnings) {\n console.log(` - ${warning}`);\n }\n }\n\n if (analysis) {\n console.log('');\n console.log(`AI scenarios: ${analysis.scenarios.length}`);\n console.log(`Feature: ${analysis.feature}`);\n console.log(`Prefix: ${analysis.suggestedPrefix}`);\n }\n\n console.log('');\n}\n\nexport function saveCaptureJson(\n elementMap: ElementMap,\n analysis?: AnalysisResult | null,\n outputDir = '.cementic/capture',\n): string {\n mkdirSync(outputDir, { recursive: true });\n\n const fileName = `capture-${slugify(elementMap.url)}-${Date.now()}.json`;\n const filePath = join(outputDir, fileName);\n\n writeFileSync(filePath, JSON.stringify({\n _meta: {\n version: '0.2.7',\n generatedAt: new Date().toISOString(),\n tool: '@cementic/cementic-test',\n },\n elementMap,\n analysis: analysis ?? null,\n }, null, 2));\n\n return filePath;\n}\n\nexport function buildCasesMarkdown(analysis: AnalysisResult): string {\n const lines: string[] = [];\n\n for (const scenario of analysis.scenarios) {\n lines.push(`# ${scenario.id} — ${scenario.title} ${scenario.tags.map(normalizeTag).join(' ')}`.trim());\n lines.push(`<!-- ct:url ${analysis.url} -->`);\n lines.push(`<!-- ct:feature ${analysis.feature} -->`);\n lines.push(`<!-- ct:generated-by capture -->`);\n lines.push(`<!-- narrator: ${sanitizeComment(scenario.narrator)} -->`);\n lines.push(`<!-- code-level: ${scenario.codeLevel} -->`);\n lines.push('');\n lines.push('## Steps');\n\n scenario.steps.forEach((step, index) => {\n const hint = step.selector && step.selector !== 'page'\n ? ` <!-- selector: ${step.selector} -->`\n : '';\n lines.push(`${index + 1}. ${step.human}${hint}`);\n });\n\n lines.push('');\n lines.push('## Expected Results');\n\n scenario.assertions.forEach((assertion) => {\n const hint = assertion.playwright\n ? ` <!-- playwright: ${sanitizeComment(assertion.playwright)} -->`\n : '';\n lines.push(`- ${assertion.human}${hint}`);\n });\n\n lines.push('');\n lines.push('---');\n lines.push('');\n }\n\n return lines.join('\\n');\n}\n\nexport function saveCasesMarkdown(\n analysis: AnalysisResult,\n outputDir = 'cases',\n fileName?: string,\n): string {\n mkdirSync(outputDir, { recursive: true });\n\n const resolvedFileName = fileName ?? `${slugify(analysis.feature || analysis.url)}.md`;\n const filePath = join(outputDir, resolvedFileName);\n\n writeFileSync(filePath, buildCasesMarkdown(analysis));\n return filePath;\n}\n\nexport function saveSpecPreview(\n analysis: AnalysisResult,\n outputDir = 'tests/preview',\n): string | null {\n if (analysis.scenarios.length === 0) return null;\n\n mkdirSync(outputDir, { recursive: true });\n\n const fileName = `spec-preview-${slugify(analysis.url)}-${Date.now()}.spec.cjs`;\n const filePath = join(outputDir, fileName);\n const lines: string[] = [];\n\n lines.push('/**');\n lines.push(' * CementicTest Capture Preview');\n lines.push(` * Generated from: ${analysis.url}`);\n lines.push(` * Feature: ${analysis.feature}`);\n lines.push(' */');\n lines.push('');\n lines.push(`const { test, expect } = require('@playwright/test');`);\n lines.push('');\n\n for (const scenario of analysis.scenarios) {\n lines.push(`test(${JSON.stringify(`${scenario.id} — ${scenario.title}`)}, async ({ page }) => {`);\n for (const step of scenario.steps) {\n if (step.action === 'navigate') {\n lines.push(` await page.goto(${JSON.stringify(step.value)});`);\n continue;\n }\n\n if (step.selector === 'page') continue;\n const selector = `page.${step.selector}`;\n\n if (step.action === 'fill') lines.push(` await ${selector}.fill(${JSON.stringify(step.value)});`);\n if (step.action === 'click') lines.push(` await ${selector}.click();`);\n if (step.action === 'select') lines.push(` await ${selector}.selectOption(${JSON.stringify(step.value)});`);\n if (step.action === 'check') lines.push(` await ${selector}.check();`);\n if (step.action === 'keyboard') lines.push(` await page.keyboard.press(${JSON.stringify(step.value)});`);\n if (step.action === 'hover') lines.push(` await ${selector}.hover();`);\n }\n\n for (const assertion of scenario.assertions) {\n lines.push(` ${ensureStatement(assertion.playwright)}`);\n }\n\n lines.push('});');\n lines.push('');\n }\n\n writeFileSync(filePath, lines.join('\\n'));\n return filePath;\n}\n\nfunction slugify(value: string): string {\n return (value || 'capture')\n .replace(/^https?:\\/\\//, '')\n .replace(/[^a-zA-Z0-9]+/g, '-')\n .replace(/^-|-$/g, '')\n .toLowerCase()\n .slice(0, 60);\n}\n\nfunction normalizeTag(value: string): string {\n const cleaned = String(value ?? '').trim();\n if (!cleaned) return '@ui';\n return cleaned.startsWith('@') ? cleaned : `@${cleaned}`;\n}\n\nfunction sanitizeComment(value: string): string {\n return String(value ?? '').replace(/-->/g, '-- >');\n}\n\nfunction ensureStatement(value: string): string {\n const trimmed = String(value ?? '').trim();\n if (!trimmed) return '// TODO: add assertion';\n return trimmed.endsWith(';') ? trimmed : `${trimmed};`;\n}\n","import { Command } from 'commander';\nimport { spawn } from 'node:child_process';\n\nexport function reportCmd() {\n const cmd = new Command('report')\n .description('Open the Playwright HTML report')\n .action(() => {\n console.log('📊 Opening Playwright HTML report...');\n \n const child = spawn(\n 'npx',\n ['playwright', 'show-report'],\n {\n stdio: 'inherit',\n shell: process.platform === 'win32',\n }\n );\n\n child.on('exit', (code) => {\n process.exit(code ?? 0);\n });\n });\n\n return cmd;\n}\n","import { Command } from 'commander';\nimport { spawn } from 'node:child_process';\nimport { existsSync } from 'node:fs';\nimport { join } from 'node:path';\n\nexport function serveCmd() {\n const cmd = new Command('serve')\n .description('Serve the Allure report')\n .action(() => {\n console.log('📊 Serving Allure report...');\n\n // Try to find the local allure binary first (more reliable than global/npx sometimes)\n const localAllureBin = join(process.cwd(), 'node_modules', 'allure-commandline', 'bin', 'allure');\n \n let executable = 'npx';\n let args = ['allure', 'serve', './allure-results'];\n\n // If we can find the direct binary, use it (node node_modules/.../allure)\n // This bypasses the \"require('../')\" issue in the .bin wrapper\n if (existsSync(localAllureBin)) {\n executable = 'node';\n args = [localAllureBin, 'serve', './allure-results'];\n }\n\n console.log(`> ${executable} ${args.join(' ')}`);\n\n const child = spawn(\n executable,\n args,\n {\n stdio: 'inherit',\n shell: process.platform === 'win32',\n }\n );\n\n child.on('exit', (code) => {\n process.exit(code ?? 0);\n });\n });\n\n return cmd;\n}\n","import { Command } from 'commander';\nimport { spawn } from 'node:child_process';\nimport { resolve } from 'node:path';\n\nfunction runStep(cmd: string, args: string[], stepName: string): Promise<void> {\n return new Promise((resolve, reject) => {\n console.log(`\\n🌊 Flow Step: ${stepName}`);\n console.log(`> ${cmd} ${args.join(' ')}`);\n\n const child = spawn(cmd, args, {\n stdio: 'inherit',\n shell: process.platform === 'win32',\n });\n\n child.on('exit', (code) => {\n if (code === 0) {\n resolve();\n } else {\n reject(new Error(`${stepName} failed with exit code ${code}`));\n }\n });\n });\n}\n\nexport function flowCmd() {\n const cmd = new Command('flow')\n .description('End-to-end flow: Normalize -> Generate -> Run Tests')\n .argument('[casesDir]', 'Directory containing test cases', './cases')\n .option('--lang <lang>', 'Target language (ts|js)', 'ts')\n .option('--no-run', 'Skip running tests')\n .action(async (casesDir, opts) => {\n const cliBin = resolve(process.argv[1]); // The current CLI executable\n\n try {\n // 1. Normalize\n await runStep(process.execPath, [cliBin, 'normalize', casesDir], 'Normalize Cases');\n\n // 2. Generate\n await runStep(process.execPath, [cliBin, 'gen', '--lang', opts.lang], 'Generate Tests');\n\n // 3. Test (unless skipped)\n if (opts.run) {\n await runStep(process.execPath, [cliBin, 'test'], 'Run Playwright Tests');\n } else {\n console.log('\\n⏭️ Skipping test execution (--no-run)');\n }\n\n console.log('\\n✅ Flow completed successfully!');\n } catch (err: any) {\n console.error(`\\n❌ Flow failed: ${err.message}`);\n process.exit(1);\n }\n });\n\n return cmd;\n}\n","import { Command } from 'commander';\nimport { mkdirSync, writeFileSync, existsSync } from 'node:fs';\nimport { join } from 'node:path';\n\nconst WORKFLOW_CONTENT = `name: Playwright Tests\non:\n push:\n branches: [ main, master ]\n pull_request:\n branches: [ main, master ]\njobs:\n test:\n timeout-minutes: 60\n runs-on: ubuntu-latest\n steps:\n - uses: actions/checkout@v4\n - uses: actions/setup-node@v4\n with:\n node-version: lts/*\n - name: Install dependencies\n run: npm ci\n - name: Install Playwright Browsers\n run: npx playwright install --with-deps\n - name: Run Playwright tests\n run: npx playwright test\n - uses: actions/upload-artifact@v4\n if: always()\n with:\n name: playwright-report\n path: playwright-report/\n retention-days: 30\n`;\n\nexport function ciCmd() {\n const cmd = new Command('ci')\n .description('Generate GitHub Actions workflow for CI')\n .action(() => {\n const githubDir = join(process.cwd(), '.github');\n const workflowsDir = join(githubDir, 'workflows');\n const workflowFile = join(workflowsDir, 'cementic.yml');\n\n console.log('🤖 Setting up CI/CD workflow...');\n\n if (!existsSync(workflowsDir)) {\n mkdirSync(workflowsDir, { recursive: true });\n console.log(`Created directory: ${workflowsDir}`);\n }\n\n if (existsSync(workflowFile)) {\n console.warn(`⚠️ Workflow file already exists at ${workflowFile}. Skipping.`);\n return;\n }\n\n writeFileSync(workflowFile, WORKFLOW_CONTENT.trim() + '\\n');\n console.log(`✅ CI workflow generated at: ${workflowFile}`);\n console.log('Next steps:');\n console.log('1. Commit and push the new file');\n console.log('2. Check the \"Actions\" tab in your GitHub repository');\n });\n\n return cmd;\n}\n"],"mappings":"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","names":["Command","createRequire","Command","readFileSync","mkdirSync","writeFileSync","statSync","join","resolve","Command","Command","mkdirSync","writeFileSync","join","callAnthropic","callOpenAiCompatible","inferPrefix","existsSync","dirname","join","resolve","fileURLToPath","require","log","input","mkdirSync","writeFileSync","join","normalizeTag","ensureStatement","slugify","output","mkdirSync","join","writeFileSync","Command","Command","spawn","Command","spawn","existsSync","join","Command","spawn","resolve","Command","mkdirSync","writeFileSync","existsSync","join","require","createRequire","Command"]}