indxel-cli 0.2.0 → 0.3.0

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/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/commands/init.ts","../src/detect.ts","../src/templates.ts","../src/commands/check.ts","../src/scanner.ts","../src/formatter.ts","../src/store.ts","../src/commands/crawl.ts","../src/commands/keywords.ts","../src/commands/index.ts"],"sourcesContent":["import { Command } from \"commander\";\nimport { initCommand } from \"./commands/init.js\";\nimport { checkCommand } from \"./commands/check.js\";\nimport { crawlCommand } from \"./commands/crawl.js\";\nimport { keywordsCommand } from \"./commands/keywords.js\";\nimport { indexCommand } from \"./commands/index.js\";\n\nexport function createProgram(): Command {\n const program = new Command();\n\n program\n .name(\"indxel\")\n .description(\"Infrastructure SEO developer-first. ESLint pour le SEO.\")\n .version(\"0.1.0\");\n\n program.addCommand(initCommand);\n program.addCommand(checkCommand);\n program.addCommand(crawlCommand);\n program.addCommand(keywordsCommand);\n program.addCommand(indexCommand);\n\n return program;\n}\n\nexport { initCommand, checkCommand, crawlCommand, keywordsCommand, indexCommand };\n","import { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport ora from \"ora\";\nimport { existsSync } from \"node:fs\";\nimport { writeFile, mkdir, readFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { detectProject } from \"../detect.js\";\nimport {\n seoConfigTemplate,\n sitemapTemplate,\n robotsTemplate,\n} from \"../templates.js\";\n\nconst PRE_PUSH_HOOK = `#!/bin/sh\n# indxel SEO guard — blocks push if critical SEO errors are found\necho \"\\\\033[36m[indxel]\\\\033[0m Running SEO check before push...\"\nnpx indxel-cli check --ci\nif [ $? -ne 0 ]; then\n echo \"\"\n echo \"\\\\033[31m[indxel] Push blocked — fix SEO errors first.\\\\033[0m\"\n echo \"\\\\033[2m Run 'npx indxel-cli check' for details.\\\\033[0m\"\n exit 1\nfi\n`;\n\nexport const initCommand = new Command(\"init\")\n .description(\"Initialize indxel in your Next.js project\")\n .option(\"--cwd <path>\", \"Project directory\", process.cwd())\n .option(\"--force\", \"Overwrite existing files\", false)\n .option(\"--hook\", \"Install git pre-push hook to block pushes on SEO errors\", false)\n .action(async (opts) => {\n const cwd = opts.cwd;\n const spinner = ora(\"Detecting project...\").start();\n\n // 1. Detect project\n const project = await detectProject(cwd);\n\n if (!project.isNextJs) {\n spinner.fail(\"Not a Next.js project\");\n console.log(\n chalk.dim(\" indxel currently supports Next.js projects only.\"),\n );\n console.log(\n chalk.dim(\" Make sure you're in a directory with a next.config file.\"),\n );\n process.exit(1);\n }\n\n spinner.succeed(\n `Detected Next.js ${project.nextVersion ?? \"\"} (${project.usesAppRouter ? \"App Router\" : \"Pages Router\"})`,\n );\n\n const ext = project.isTypeScript ? \"ts\" : \"js\";\n const filesCreated: string[] = [];\n\n // 2. Generate seo.config.ts\n if (!project.hasSeoConfig || opts.force) {\n const configPath = join(cwd, `seo.config.${ext}`);\n await writeFile(configPath, seoConfigTemplate(project.isTypeScript), \"utf-8\");\n filesCreated.push(`seo.config.${ext}`);\n console.log(chalk.green(\" ✓\") + ` Generated seo.config.${ext}`);\n } else {\n console.log(chalk.dim(` - seo.config.${ext} already exists (skip)`));\n }\n\n // 3. Generate sitemap.ts\n if (!project.hasSitemap || opts.force) {\n const sitemapPath = join(cwd, project.appDir, `sitemap.${ext}`);\n await writeFile(sitemapPath, sitemapTemplate(project.isTypeScript), \"utf-8\");\n filesCreated.push(`${project.appDir}/sitemap.${ext}`);\n console.log(chalk.green(\" ✓\") + ` Generated ${project.appDir}/sitemap.${ext}`);\n } else {\n console.log(chalk.dim(` - sitemap already exists (skip)`));\n }\n\n // 4. Generate robots.ts\n if (!project.hasRobots || opts.force) {\n const robotsPath = join(cwd, project.appDir, `robots.${ext}`);\n await writeFile(robotsPath, robotsTemplate(project.isTypeScript), \"utf-8\");\n filesCreated.push(`${project.appDir}/robots.${ext}`);\n console.log(chalk.green(\" ✓\") + ` Generated ${project.appDir}/robots.${ext}`);\n } else {\n console.log(chalk.dim(` - robots already exists (skip)`));\n }\n\n // 5. Git pre-push hook\n const gitDir = join(cwd, \".git\");\n const hasGit = existsSync(gitDir);\n\n if (opts.hook || opts.force) {\n if (!hasGit) {\n console.log(chalk.yellow(\" ⚠\") + \" No .git directory found — skip hook install\");\n } else {\n const hooksDir = join(gitDir, \"hooks\");\n const hookPath = join(hooksDir, \"pre-push\");\n\n // Check if a pre-push hook already exists\n if (existsSync(hookPath) && !opts.force) {\n const existing = await readFile(hookPath, \"utf-8\");\n if (existing.includes(\"indxel\")) {\n console.log(chalk.dim(\" - pre-push hook already installed (skip)\"));\n } else {\n console.log(chalk.yellow(\" ⚠\") + \" pre-push hook already exists (use --force to overwrite)\");\n }\n } else {\n await mkdir(hooksDir, { recursive: true });\n await writeFile(hookPath, PRE_PUSH_HOOK, { mode: 0o755 });\n filesCreated.push(\".git/hooks/pre-push\");\n console.log(chalk.green(\" ✓\") + \" Installed git pre-push hook\");\n }\n }\n } else if (hasGit) {\n console.log(chalk.dim(\" - Use --hook to install git pre-push guard\"));\n }\n\n // 6. Summary\n console.log(\"\");\n if (filesCreated.length > 0) {\n console.log(\n chalk.bold(` ${filesCreated.length} file${filesCreated.length > 1 ? \"s\" : \"\"} created.`),\n );\n } else {\n console.log(chalk.dim(\" Nothing to create — all files already exist.\"));\n console.log(chalk.dim(\" Use --force to overwrite.\"));\n }\n\n console.log(\"\");\n console.log(chalk.dim(\" Next steps:\"));\n console.log(chalk.dim(` 1. Edit seo.config.${ext} with your site details`));\n console.log(chalk.dim(\" 2. Run \") + chalk.bold(\"npx indxel check\") + chalk.dim(\" to audit your pages\"));\n if (!opts.hook && hasGit) {\n console.log(chalk.dim(\" 3. Run \") + chalk.bold(\"npx indxel init --hook\") + chalk.dim(\" to guard git pushes\"));\n }\n console.log(\"\");\n });\n","import { existsSync } from \"node:fs\";\nimport { readFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n\nexport interface ProjectInfo {\n /** Root directory of the project */\n root: string;\n /** Whether this is a Next.js project */\n isNextJs: boolean;\n /** Next.js version if detected */\n nextVersion?: string;\n /** Whether it uses App Router (has src/app or app directory) */\n usesAppRouter: boolean;\n /** The app directory path (relative) */\n appDir: string;\n /** Whether TypeScript is used */\n isTypeScript: boolean;\n /** Whether seo.config.ts/js already exists */\n hasSeoConfig: boolean;\n /** Whether sitemap.ts/js exists */\n hasSitemap: boolean;\n /** Whether robots.ts/js exists */\n hasRobots: boolean;\n}\n\n/** Detect project type and configuration from the given directory. */\nexport async function detectProject(cwd: string): Promise<ProjectInfo> {\n const info: ProjectInfo = {\n root: cwd,\n isNextJs: false,\n usesAppRouter: false,\n appDir: \"app\",\n isTypeScript: false,\n hasSeoConfig: false,\n hasSitemap: false,\n hasRobots: false,\n };\n\n // Check for Next.js config files\n const nextConfigs = [\n \"next.config.ts\",\n \"next.config.js\",\n \"next.config.mjs\",\n \"next.config.cjs\",\n ];\n info.isNextJs = nextConfigs.some((f) => existsSync(join(cwd, f)));\n\n // Read Next.js version from package.json\n const pkgPath = join(cwd, \"package.json\");\n if (existsSync(pkgPath)) {\n try {\n const pkg = JSON.parse(await readFile(pkgPath, \"utf-8\"));\n const nextDep = pkg.dependencies?.next ?? pkg.devDependencies?.next;\n if (nextDep) {\n info.isNextJs = true;\n info.nextVersion = nextDep.replace(/[\\^~>=<]/g, \"\").trim();\n }\n } catch {\n // Ignore parse errors\n }\n }\n\n // Check for TypeScript\n info.isTypeScript =\n existsSync(join(cwd, \"tsconfig.json\")) ||\n existsSync(join(cwd, \"tsconfig.ts\"));\n\n // Detect App Router directory\n if (existsSync(join(cwd, \"src\", \"app\"))) {\n info.usesAppRouter = true;\n info.appDir = \"src/app\";\n } else if (existsSync(join(cwd, \"app\"))) {\n info.usesAppRouter = true;\n info.appDir = \"app\";\n }\n\n // Check for existing SEO files (check both .ts and .js regardless of project type)\n info.hasSeoConfig =\n existsSync(join(cwd, \"seo.config.ts\")) ||\n existsSync(join(cwd, \"seo.config.js\"));\n\n info.hasSitemap =\n existsSync(join(cwd, info.appDir, \"sitemap.ts\")) ||\n existsSync(join(cwd, info.appDir, \"sitemap.js\")) ||\n existsSync(join(cwd, info.appDir, \"sitemap.xml\"));\n\n info.hasRobots =\n existsSync(join(cwd, info.appDir, \"robots.ts\")) ||\n existsSync(join(cwd, info.appDir, \"robots.js\")) ||\n existsSync(join(cwd, info.appDir, \"robots.txt\"));\n\n return info;\n}\n","/** Generate the seo.config.ts template */\nexport function seoConfigTemplate(isTypeScript: boolean): string {\n if (isTypeScript) {\n return `import { defineSEO } from 'indxel'\n\nexport default defineSEO({\n siteName: 'My Site',\n siteUrl: 'https://example.com',\n titleTemplate: '%s | My Site',\n defaultDescription: 'A short description of your site for search engines.',\n defaultOGImage: '/og-image.png',\n locale: 'en_US',\n // twitter: {\n // handle: '@yourhandle',\n // cardType: 'summary_large_image',\n // },\n // organization: {\n // name: 'My Company',\n // logo: '/logo.png',\n // url: 'https://example.com',\n // },\n})\n`;\n }\n\n return `const { defineSEO } = require('indxel')\n\nmodule.exports = defineSEO({\n siteName: 'My Site',\n siteUrl: 'https://example.com',\n titleTemplate: '%s | My Site',\n defaultDescription: 'A short description of your site for search engines.',\n defaultOGImage: '/og-image.png',\n locale: 'en_US',\n})\n`;\n}\n\n/** Generate the sitemap.ts template */\nexport function sitemapTemplate(isTypeScript: boolean): string {\n if (isTypeScript) {\n return `import type { MetadataRoute } from 'next'\n\nexport default function sitemap(): MetadataRoute.Sitemap {\n const baseUrl = 'https://example.com'\n\n return [\n {\n url: baseUrl,\n lastModified: new Date(),\n changeFrequency: 'weekly',\n priority: 1,\n },\n // Add more pages here or generate dynamically:\n //\n // const posts = await getPosts()\n // return posts.map(post => ({\n // url: \\`\\${baseUrl}/blog/\\${post.slug}\\`,\n // lastModified: post.updatedAt,\n // changeFrequency: 'monthly',\n // priority: 0.7,\n // }))\n ]\n}\n`;\n }\n\n return `/** @returns {import('next').MetadataRoute.Sitemap} */\nexport default function sitemap() {\n const baseUrl = 'https://example.com'\n\n return [\n {\n url: baseUrl,\n lastModified: new Date(),\n changeFrequency: 'weekly',\n priority: 1,\n },\n ]\n}\n`;\n}\n\n/** Generate the robots.ts template */\nexport function robotsTemplate(isTypeScript: boolean): string {\n if (isTypeScript) {\n return `import type { MetadataRoute } from 'next'\n\nexport default function robots(): MetadataRoute.Robots {\n const baseUrl = 'https://example.com'\n\n return {\n rules: [\n {\n userAgent: '*',\n allow: '/',\n disallow: ['/api/', '/private/'],\n },\n ],\n sitemap: \\`\\${baseUrl}/sitemap.xml\\`,\n }\n}\n`;\n }\n\n return `/** @returns {import('next').MetadataRoute.Robots} */\nexport default function robots() {\n const baseUrl = 'https://example.com'\n\n return {\n rules: [\n {\n userAgent: '*',\n allow: '/',\n disallow: ['/api/', '/private/'],\n },\n ],\n sitemap: \\`\\${baseUrl}/sitemap.xml\\`,\n }\n}\n`;\n}\n","import { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport ora from \"ora\";\nimport { validateMetadata } from \"indxel\";\nimport { detectProject } from \"../detect.js\";\nimport { scanPages } from \"../scanner.js\";\nimport {\n formatPageResult,\n formatSummary,\n formatJSON,\n formatDiff,\n computeSummary,\n type CheckResult,\n} from \"../formatter.js\";\nimport { saveCheckResult, loadPreviousCheck } from \"../store.js\";\n\nexport const checkCommand = new Command(\"check\")\n .description(\"Audit SEO metadata for all pages in your project\")\n .option(\"--cwd <path>\", \"Project directory\", process.cwd())\n .option(\"--ci\", \"CI/CD mode — strict, exit 1 on any error\", false)\n .option(\"--diff\", \"Compare with previous check run\", false)\n .option(\"--json\", \"Output results as JSON\", false)\n .option(\"--strict\", \"Treat warnings as errors\", false)\n .action(async (opts) => {\n const cwd = opts.cwd;\n const isCI = opts.ci;\n const isStrict = opts.strict || isCI;\n const showDiff = opts.diff;\n const jsonOutput = opts.json;\n\n // 1. Detect project\n const spinner = ora(\"Detecting project...\").start();\n const project = await detectProject(cwd);\n\n if (!project.isNextJs) {\n spinner.fail(\"Not a Next.js project\");\n if (!jsonOutput) {\n console.log(chalk.dim(\" Run this command from a Next.js project root.\"));\n }\n process.exit(1);\n }\n\n if (!project.usesAppRouter) {\n spinner.fail(\"App Router not detected\");\n if (!jsonOutput) {\n console.log(chalk.dim(\" indxel requires Next.js App Router (src/app or app directory).\"));\n }\n process.exit(1);\n }\n\n // 2. Scan pages\n spinner.text = \"Scanning pages...\";\n const pages = await scanPages(cwd, project.appDir);\n\n if (pages.length === 0) {\n spinner.fail(\"No pages found\");\n if (!jsonOutput) {\n console.log(chalk.dim(` No page.tsx/ts files found in ${project.appDir}/`));\n }\n process.exit(1);\n }\n\n spinner.succeed(`Found ${pages.length} page${pages.length > 1 ? \"s\" : \"\"}`);\n\n // 3. Validate each page\n if (!jsonOutput) {\n console.log(\"\");\n console.log(chalk.bold(` Checking ${pages.length} pages...`));\n console.log(\"\");\n }\n\n const results: CheckResult[] = [];\n\n for (const page of pages) {\n const validation = validateMetadata(page.extractedMetadata, {\n strict: isStrict,\n });\n\n const result: CheckResult = { page, validation };\n results.push(result);\n\n if (!jsonOutput) {\n console.log(formatPageResult(result));\n }\n }\n\n // 4. Compute summary\n const summary = computeSummary(results);\n\n // 5. Save results for future diff\n await saveCheckResult(cwd, summary);\n\n // 6. Show diff if requested\n if (showDiff && !jsonOutput) {\n const previous = await loadPreviousCheck(cwd);\n if (previous) {\n console.log(formatDiff(summary, previous.summary));\n } else {\n console.log(chalk.dim(\"\\n No previous check found. Run again to see a diff.\\n\"));\n }\n }\n\n // 7. Output\n if (jsonOutput) {\n console.log(formatJSON(summary));\n } else {\n console.log(formatSummary(summary));\n }\n\n // 8. Exit code (non-zero on errors for both CI and interactive use)\n if (summary.criticalErrors > 0) {\n process.exit(1);\n }\n });\n","import { readFile } from \"node:fs/promises\";\nimport { join, relative, dirname, sep } from \"node:path\";\nimport { glob } from \"glob\";\nimport type { ResolvedMetadata } from \"indxel\";\n\nexport interface PageInfo {\n /** File path relative to project root */\n filePath: string;\n /** Route path (e.g., \"/blog/[slug]\") */\n route: string;\n /** Whether the page exports metadata or generateMetadata */\n hasMetadata: boolean;\n /** Whether the page exports generateMetadata (dynamic) */\n hasDynamicMetadata: boolean;\n /** Extracted static metadata fields (best effort from source parsing) */\n extractedMetadata: ResolvedMetadata;\n}\n\n/**\n * Scan the app directory for all page files and extract metadata info.\n * This does static analysis of the source code (no build required).\n */\nexport async function scanPages(\n projectRoot: string,\n appDir: string,\n): Promise<PageInfo[]> {\n const appDirFull = join(projectRoot, appDir);\n\n // Find all page.tsx/page.ts/page.jsx/page.js files\n const pageFiles = await glob(\"**/page.{tsx,ts,jsx,js}\", {\n cwd: appDirFull,\n ignore: [\"**/node_modules/**\", \"**/_*/**\"],\n });\n\n const pages: PageInfo[] = [];\n\n for (const file of pageFiles) {\n const fullPath = join(appDirFull, file);\n const content = await readFile(fullPath, \"utf-8\");\n const route = filePathToRoute(file);\n\n const page: PageInfo = {\n filePath: join(appDir, file),\n route,\n hasMetadata: false,\n hasDynamicMetadata: false,\n extractedMetadata: createEmptyMetadata(),\n };\n\n // Check for metadata exports\n page.hasDynamicMetadata = hasExport(content, \"generateMetadata\");\n page.hasMetadata = page.hasDynamicMetadata || hasExport(content, \"metadata\");\n\n // Extract static metadata (best effort)\n page.extractedMetadata = extractStaticMetadata(content);\n\n pages.push(page);\n }\n\n // Also check layout files for metadata\n const layoutFiles = await glob(\"**/layout.{tsx,ts,jsx,js}\", {\n cwd: appDirFull,\n ignore: [\"**/node_modules/**\", \"**/_*/**\"],\n });\n\n for (const file of layoutFiles) {\n const fullPath = join(appDirFull, file);\n const content = await readFile(fullPath, \"utf-8\");\n const route = filePathToRoute(file).replace(/\\/layout$/, \"\") || \"/\";\n\n // Check if the root layout has metadata (common pattern)\n const hasMetadataExport = hasExport(content, \"metadata\") || hasExport(content, \"generateMetadata\");\n if (hasMetadataExport) {\n // Enrich matching pages with layout metadata awareness\n const layoutMeta = extractStaticMetadata(content);\n for (const page of pages) {\n if (page.route.startsWith(route) || route === \"/\") {\n // Merge layout metadata as fallback (page-level takes precedence)\n mergeMetadata(page.extractedMetadata, layoutMeta);\n if (!page.hasMetadata) {\n page.hasMetadata = true;\n }\n }\n }\n }\n }\n\n return pages.sort((a, b) => a.route.localeCompare(b.route));\n}\n\n/** Convert a file path like \"blog/[slug]/page.tsx\" to route \"/blog/[slug]\" */\nfunction filePathToRoute(filePath: string): string {\n const dir = dirname(filePath);\n if (dir === \".\") return \"/\";\n // Normalize separators and add leading slash\n const route = \"/\" + dir.split(sep).join(\"/\");\n // Remove route groups like (marketing)\n return route.replace(/\\/\\([^)]+\\)/g, \"\") || \"/\";\n}\n\n/** Check if source code exports a given name */\nfunction hasExport(source: string, name: string): boolean {\n // Match: export const metadata, export async function generateMetadata, export function generateMetadata\n const patterns = [\n new RegExp(`export\\\\s+(const|let|var)\\\\s+${name}\\\\b`),\n new RegExp(`export\\\\s+(async\\\\s+)?function\\\\s+${name}\\\\b`),\n new RegExp(`export\\\\s+\\\\{[^}]*\\\\b${name}\\\\b[^}]*\\\\}`),\n ];\n return patterns.some((p) => p.test(source));\n}\n\n/**\n * Extract metadata from static `export const metadata = { ... }` patterns.\n * This is best-effort source code parsing (not AST — fast and simple).\n */\nfunction extractStaticMetadata(source: string): ResolvedMetadata {\n const meta = createEmptyMetadata();\n\n // Extract title from metadata object\n const titleMatch = source.match(\n /title\\s*:\\s*(?:[\"'`]([^\"'`]+)[\"'`]|`([^`]*)`)/,\n );\n if (titleMatch) {\n meta.title = titleMatch[1] ?? titleMatch[2] ?? null;\n }\n\n // Extract description\n const descMatch = source.match(\n /description\\s*:\\s*(?:[\"'`]([^\"'`]+)[\"'`]|`([^`]*)`)/,\n );\n if (descMatch) {\n meta.description = descMatch[1] ?? descMatch[2] ?? null;\n }\n\n // Check for openGraph object\n if (/openGraph\\s*:\\s*\\{/.test(source)) {\n // Extract OG title\n const ogTitleMatch = source.match(\n /openGraph\\s*:\\s*\\{[^}]*title\\s*:\\s*[\"'`]([^\"'`]+)[\"'`]/s,\n );\n if (ogTitleMatch) meta.ogTitle = ogTitleMatch[1];\n\n // Extract OG description\n const ogDescMatch = source.match(\n /openGraph\\s*:\\s*\\{[^}]*description\\s*:\\s*[\"'`]([^\"'`]+)[\"'`]/s,\n );\n if (ogDescMatch) meta.ogDescription = ogDescMatch[1];\n\n // Check for images\n if (/images\\s*:\\s*\\[/.test(source)) {\n meta.ogImage = \"[detected]\";\n }\n }\n\n // Check for twitter config\n if (/twitter\\s*:\\s*\\{/.test(source)) {\n const cardMatch = source.match(\n /card\\s*:\\s*[\"'`](summary|summary_large_image)[\"'`]/,\n );\n if (cardMatch) meta.twitterCard = cardMatch[1];\n }\n\n // Check for robots\n if (/robots\\s*:\\s*\\{/.test(source) || /robots\\s*:\\s*[\"'`]/.test(source)) {\n const robotsMatch = source.match(\n /robots\\s*:\\s*[\"'`]([^\"'`]+)[\"'`]/,\n );\n if (robotsMatch) meta.robots = robotsMatch[1];\n }\n\n // Check for alternates/canonical\n if (/alternates\\s*:\\s*\\{/.test(source)) {\n const canonicalMatch = source.match(\n /canonical\\s*:\\s*[\"'`]([^\"'`]+)[\"'`]/,\n );\n if (canonicalMatch) meta.canonical = canonicalMatch[1];\n }\n\n // Check for structured data (JSON-LD script tags)\n if (/application\\/ld\\+json/.test(source) || /generateLD/.test(source) || /JsonLD/.test(source)) {\n meta.structuredData = [{ \"@context\": \"https://schema.org\", \"@type\": \"detected\" }];\n }\n\n // Check for viewport\n if (/viewport\\s*[:=]/.test(source)) {\n meta.viewport = \"detected\";\n }\n\n // Check for icons/favicon\n if (/icons\\s*:\\s*\\{/.test(source) || /favicon/.test(source)) {\n meta.favicon = \"detected\";\n }\n\n return meta;\n}\n\nfunction createEmptyMetadata(): ResolvedMetadata {\n return {\n title: null,\n description: null,\n canonical: null,\n ogTitle: null,\n ogDescription: null,\n ogImage: null,\n ogType: null,\n twitterCard: null,\n twitterTitle: null,\n twitterDescription: null,\n robots: null,\n alternates: null,\n structuredData: null,\n viewport: null,\n favicon: null,\n };\n}\n\n/** Merge source metadata into target (target takes precedence if already set) */\nfunction mergeMetadata(target: ResolvedMetadata, source: ResolvedMetadata): void {\n for (const key of Object.keys(source) as (keyof ResolvedMetadata)[]) {\n if (target[key] === null || target[key] === undefined) {\n (target as Record<string, unknown>)[key] = source[key];\n }\n }\n}\n","import chalk from \"chalk\";\nimport type { ValidationResult } from \"indxel\";\nimport type { PageInfo } from \"./scanner.js\";\n\nexport interface CheckResult {\n page: PageInfo;\n validation: ValidationResult;\n}\n\nexport interface CheckSummary {\n results: CheckResult[];\n totalPages: number;\n passedPages: number;\n averageScore: number;\n grade: string;\n criticalErrors: number;\n}\n\n/** Format a single page check result for terminal output */\nexport function formatPageResult(result: CheckResult): string {\n const { page, validation } = result;\n const lines: string[] = [];\n\n const scoreColor = getScoreColor(validation.score);\n const icon = validation.errors.length > 0 ? chalk.red(\"x\") : chalk.green(\"✓\");\n\n lines.push(\n ` ${icon} ${chalk.bold(page.route)} ${scoreColor(`${validation.score}/100`)}`,\n );\n\n // Show errors\n for (const error of validation.errors) {\n lines.push(` ${chalk.red(\"x\")} ${error.message ?? error.name}`);\n }\n\n // Show warnings (only if there are also errors, to reduce noise)\n if (validation.errors.length > 0) {\n for (const warning of validation.warnings) {\n lines.push(` ${chalk.yellow(\"!\")} ${warning.message ?? warning.name}`);\n }\n }\n\n return lines.join(\"\\n\");\n}\n\n/** Format the complete check summary for terminal output */\nexport function formatSummary(summary: CheckSummary): string {\n const lines: string[] = [];\n const { totalPages, passedPages, averageScore, criticalErrors } = summary;\n\n lines.push(\"\");\n lines.push(chalk.dim(\" ─────────────────────────────────────\"));\n lines.push(\"\");\n\n // Overall score\n const scoreColor = getScoreColor(averageScore);\n lines.push(\n ` Score: ${scoreColor(chalk.bold(`${averageScore}/100`))} (${summary.grade})`,\n );\n\n // Pages summary\n const pagesColor = passedPages === totalPages ? chalk.green : chalk.yellow;\n lines.push(\n ` Pages: ${pagesColor(`${passedPages}/${totalPages}`)} pass SEO validation`,\n );\n\n // Error count\n if (criticalErrors > 0) {\n lines.push(\"\");\n lines.push(\n chalk.red(` ${criticalErrors} critical issue${criticalErrors > 1 ? \"s\" : \"\"}. Fix before deploying.`),\n );\n } else {\n lines.push(\"\");\n lines.push(chalk.green(\" All pages pass. Ship it.\"));\n }\n\n lines.push(\"\");\n return lines.join(\"\\n\");\n}\n\n/** Format results for --json output */\nexport function formatJSON(summary: CheckSummary): string {\n return JSON.stringify(\n {\n score: summary.averageScore,\n grade: summary.grade,\n totalPages: summary.totalPages,\n passedPages: summary.passedPages,\n criticalErrors: summary.criticalErrors,\n pages: summary.results.map((r) => ({\n route: r.page.route,\n file: r.page.filePath,\n score: r.validation.score,\n grade: r.validation.grade,\n errors: r.validation.errors.map((e) => ({\n id: e.id,\n message: e.message,\n })),\n warnings: r.validation.warnings.map((w) => ({\n id: w.id,\n message: w.message,\n })),\n })),\n },\n null,\n 2,\n );\n}\n\n/** Format a diff between two check runs */\nexport function formatDiff(\n current: CheckSummary,\n previous: CheckSummary,\n): string {\n const lines: string[] = [];\n\n lines.push(\"\");\n lines.push(chalk.bold(\" SEO Diff:\"));\n lines.push(\"\");\n\n const scoreDelta = current.averageScore - previous.averageScore;\n const scoreArrow = scoreDelta > 0 ? chalk.green(`+${scoreDelta}`) : scoreDelta < 0 ? chalk.red(`${scoreDelta}`) : chalk.dim(\"0\");\n lines.push(\n ` Score: ${previous.averageScore} -> ${current.averageScore} (${scoreArrow})`,\n );\n lines.push(\"\");\n\n // Build route maps\n const prevMap = new Map(previous.results.map((r) => [r.page.route, r]));\n const currMap = new Map(current.results.map((r) => [r.page.route, r]));\n\n // Regressions\n const regressions: string[] = [];\n for (const [route, curr] of currMap) {\n const prev = prevMap.get(route);\n if (!prev) continue;\n if (curr.validation.score < prev.validation.score) {\n regressions.push(\n ` ${chalk.red(\"-\")} ${route} ${prev.validation.score} -> ${curr.validation.score}`,\n );\n }\n }\n\n // Improvements\n const improvements: string[] = [];\n for (const [route, curr] of currMap) {\n const prev = prevMap.get(route);\n if (!prev) continue;\n if (curr.validation.score > prev.validation.score) {\n improvements.push(\n ` ${chalk.green(\"+\")} ${route} ${prev.validation.score} -> ${curr.validation.score}`,\n );\n }\n }\n\n // New pages\n const newPages: string[] = [];\n for (const route of currMap.keys()) {\n if (!prevMap.has(route)) {\n newPages.push(` ${chalk.blue(\"+\")} ${route} ${chalk.dim(\"[new]\")}`);\n }\n }\n\n // Removed pages\n const removed: string[] = [];\n for (const route of prevMap.keys()) {\n if (!currMap.has(route)) {\n removed.push(` ${chalk.dim(\"-\")} ${route} ${chalk.dim(\"[removed]\")}`);\n }\n }\n\n if (regressions.length > 0) {\n lines.push(chalk.red(` REGRESSIONS (${regressions.length}):`));\n lines.push(...regressions);\n lines.push(\"\");\n }\n\n if (improvements.length > 0) {\n lines.push(chalk.green(` IMPROVEMENTS (${improvements.length}):`));\n lines.push(...improvements);\n lines.push(\"\");\n }\n\n if (newPages.length > 0) {\n lines.push(chalk.blue(` NEW PAGES (${newPages.length}):`));\n lines.push(...newPages);\n lines.push(\"\");\n }\n\n if (removed.length > 0) {\n lines.push(chalk.dim(` REMOVED (${removed.length}):`));\n lines.push(...removed);\n lines.push(\"\");\n }\n\n if (regressions.length === 0 && improvements.length === 0 && newPages.length === 0 && removed.length === 0) {\n lines.push(chalk.dim(\" No changes detected.\"));\n lines.push(\"\");\n }\n\n return lines.join(\"\\n\");\n}\n\n/** Color a score value based on its range */\nfunction getScoreColor(score: number): (text: string) => string {\n if (score >= 90) return chalk.green;\n if (score >= 70) return chalk.yellow;\n return chalk.red;\n}\n\n/** Compute summary from results */\nexport function computeSummary(results: CheckResult[]): CheckSummary {\n const totalPages = results.length;\n const passedPages = results.filter((r) => r.validation.errors.length === 0).length;\n const averageScore =\n totalPages > 0\n ? Math.round(results.reduce((sum, r) => sum + r.validation.score, 0) / totalPages)\n : 0;\n const criticalErrors = results.reduce((sum, r) => sum + r.validation.errors.length, 0);\n\n let grade: string;\n if (averageScore >= 90) grade = \"A\";\n else if (averageScore >= 80) grade = \"B\";\n else if (averageScore >= 70) grade = \"C\";\n else if (averageScore >= 60) grade = \"D\";\n else grade = \"F\";\n\n return { results, totalPages, passedPages, averageScore, grade, criticalErrors };\n}\n","import { existsSync } from \"node:fs\";\nimport { readFile, writeFile, mkdir } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport type { CheckSummary } from \"./formatter.js\";\n\nconst STORE_DIR = \".indxel\";\nconst LAST_CHECK_FILE = \"last-check.json\";\n\nexport interface StoredCheck {\n timestamp: string;\n summary: CheckSummary;\n}\n\n/** Save the current check results for future diff comparison */\nexport async function saveCheckResult(\n cwd: string,\n summary: CheckSummary,\n): Promise<void> {\n const storeDir = join(cwd, STORE_DIR);\n\n if (!existsSync(storeDir)) {\n await mkdir(storeDir, { recursive: true });\n }\n\n const stored: StoredCheck = {\n timestamp: new Date().toISOString(),\n summary: {\n ...summary,\n // Serialize results with minimal data needed for diff\n results: summary.results.map((r) => ({\n page: {\n filePath: r.page.filePath,\n route: r.page.route,\n hasMetadata: r.page.hasMetadata,\n hasDynamicMetadata: r.page.hasDynamicMetadata,\n extractedMetadata: r.page.extractedMetadata,\n },\n validation: r.validation,\n })),\n },\n };\n\n await writeFile(\n join(storeDir, LAST_CHECK_FILE),\n JSON.stringify(stored, null, 2),\n \"utf-8\",\n );\n}\n\n/** Load the previous check result (or null if none exists) */\nexport async function loadPreviousCheck(\n cwd: string,\n): Promise<StoredCheck | null> {\n const filePath = join(cwd, STORE_DIR, LAST_CHECK_FILE);\n\n if (!existsSync(filePath)) {\n return null;\n }\n\n try {\n const data = await readFile(filePath, \"utf-8\");\n return JSON.parse(data) as StoredCheck;\n } catch {\n return null;\n }\n}\n\n/** Get the .indxel directory path */\nexport function getStoreDir(cwd: string): string {\n return join(cwd, STORE_DIR);\n}\n","import { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport ora from \"ora\";\nimport {\n crawlSite,\n fetchSitemap,\n compareSitemap,\n fetchRobots,\n checkUrlsAgainstRobots,\n verifyAssets,\n} from \"indxel\";\nimport type { CrawledPage } from \"indxel\";\n\nexport const crawlCommand = new Command(\"crawl\")\n .description(\"Crawl a live site, audit every page, check sitemap, robots.txt, and assets\")\n .argument(\"<url>\", \"URL to start crawling (e.g., https://yoursite.com)\")\n .option(\"--max-pages <n>\", \"Maximum pages to crawl\", \"50\")\n .option(\"--max-depth <n>\", \"Maximum link depth\", \"5\")\n .option(\"--delay <ms>\", \"Delay between requests in ms\", \"200\")\n .option(\"--json\", \"Output results as JSON\", false)\n .option(\"--strict\", \"Treat warnings as errors\", false)\n .option(\"--skip-assets\", \"Skip asset verification\", false)\n .option(\"--skip-sitemap\", \"Skip sitemap check\", false)\n .option(\"--skip-robots\", \"Skip robots.txt check\", false)\n .option(\"--ignore <patterns>\", \"Comma-separated path patterns to exclude from analysis (e.g. /app/*,/admin/*)\")\n .option(\"--push\", \"Push results to Indxel dashboard\", false)\n .option(\"--api-key <key>\", \"API key for --push (or set INDXEL_API_KEY env var)\")\n .action(async (url: string, opts) => {\n const jsonOutput = opts.json;\n const maxPages = parseInt(opts.maxPages, 10);\n const maxDepth = parseInt(opts.maxDepth, 10);\n const delay = parseInt(opts.delay, 10);\n\n // Ensure URL has protocol\n if (!url.startsWith(\"http://\") && !url.startsWith(\"https://\")) {\n url = `https://${url}`;\n }\n\n if (!jsonOutput) {\n console.log(\"\");\n console.log(chalk.bold(` indxel crawl`) + chalk.dim(` — ${url}`));\n console.log(\"\");\n }\n\n // 1. Robots.txt\n let robotsResult = null;\n if (!opts.skipRobots) {\n const robotsSpinner = jsonOutput ? null : ora(\"Checking robots.txt...\").start();\n robotsResult = await fetchRobots(url);\n\n if (!jsonOutput) {\n if (robotsResult.found) {\n robotsSpinner!.succeed(\"robots.txt found\");\n for (const w of robotsResult.warnings) {\n console.log(chalk.yellow(` ⚠ ${w}`));\n }\n if (robotsResult.sitemapUrls.length > 0) {\n console.log(chalk.dim(` Sitemap references: ${robotsResult.sitemapUrls.join(\", \")}`));\n }\n } else {\n robotsSpinner!.warn(\"robots.txt not found\");\n for (const e of robotsResult.errors) {\n console.log(chalk.dim(` ${e}`));\n }\n }\n console.log(\"\");\n }\n }\n\n // 2. Crawl\n const crawlSpinner = jsonOutput ? null : ora(\"Crawling...\").start();\n let crawledCount = 0;\n\n // Parse ignore patterns\n const ignorePatterns: string[] = opts.ignore\n ? opts.ignore.split(\",\").map((p: string) => p.trim()).filter(Boolean)\n : [];\n\n const crawlResult = await crawlSite(url, {\n maxPages,\n maxDepth,\n delay,\n strict: opts.strict,\n ignorePatterns,\n onPageCrawled: (page: CrawledPage) => {\n crawledCount++;\n if (crawlSpinner) {\n crawlSpinner.text = `Crawling... ${crawledCount} pages (current: ${page.url})`;\n }\n },\n });\n\n if (!jsonOutput) {\n crawlSpinner!.succeed(`Crawled ${crawlResult.totalPages} pages in ${(crawlResult.durationMs / 1000).toFixed(1)}s`);\n console.log(\"\");\n\n // Page results\n for (const page of crawlResult.pages) {\n if (page.error) {\n console.log(chalk.red(` ✗ ${page.url}`) + chalk.dim(` — ${page.error}`));\n continue;\n }\n\n const scoreColor =\n page.validation.score >= 90\n ? chalk.green\n : page.validation.score >= 70\n ? chalk.yellow\n : chalk.red;\n const icon =\n page.validation.errors.length > 0 ? chalk.red(\"✗\") : chalk.green(\"✓\");\n\n console.log(\n ` ${icon} ${page.url} ${scoreColor(`${page.validation.score}/100`)}`,\n );\n\n for (const error of page.validation.errors) {\n console.log(chalk.red(` ✗ ${error.message ?? error.description}`));\n }\n for (const warning of page.validation.warnings) {\n console.log(chalk.yellow(` ⚠ ${warning.message ?? warning.description}`));\n }\n }\n\n console.log(\"\");\n }\n\n // 3. Sitemap check\n let sitemapComparison = null;\n if (!opts.skipSitemap) {\n const sitemapSpinner = jsonOutput ? null : ora(\"Checking sitemap.xml...\").start();\n const sitemapResult = await fetchSitemap(url);\n\n if (!jsonOutput) {\n if (sitemapResult.found) {\n sitemapSpinner!.succeed(`sitemap.xml found — ${sitemapResult.urls.length} URLs`);\n\n // Compare with crawled pages\n const crawledUrls = crawlResult.pages\n .filter((p) => !p.error)\n .map((p) => p.url);\n sitemapComparison = compareSitemap(\n sitemapResult.urls.map((u) => u.loc),\n crawledUrls,\n );\n\n if (sitemapComparison.inCrawlOnly.length > 0) {\n console.log(chalk.yellow(` ⚠ ${sitemapComparison.inCrawlOnly.length} crawled pages missing from sitemap:`));\n for (const u of sitemapComparison.inCrawlOnly.slice(0, 10)) {\n console.log(chalk.dim(` - ${u}`));\n }\n }\n if (sitemapComparison.inSitemapOnly.length > 0) {\n console.log(chalk.yellow(` ⚠ ${sitemapComparison.inSitemapOnly.length} sitemap URLs not reachable:`));\n for (const u of sitemapComparison.inSitemapOnly.slice(0, 10)) {\n console.log(chalk.dim(` - ${u}`));\n }\n }\n if (sitemapComparison.issues.length === 0) {\n console.log(chalk.green(` ✓ Sitemap matches crawled pages`));\n }\n } else {\n sitemapSpinner!.warn(\"sitemap.xml not found\");\n for (const e of sitemapResult.errors) {\n console.log(chalk.dim(` ${e}`));\n }\n }\n console.log(\"\");\n }\n }\n\n // 4. Robots.txt URL check\n let robotsBlockedPages = null;\n if (robotsResult?.found && robotsResult.directives.length > 0) {\n const crawledUrls = crawlResult.pages.filter((p) => !p.error).map((p) => p.url);\n robotsBlockedPages = checkUrlsAgainstRobots(\n robotsResult.directives,\n crawledUrls,\n );\n const blocked = robotsBlockedPages.filter((c) => c.blocked);\n\n if (!jsonOutput && blocked.length > 0) {\n console.log(chalk.yellow(` ⚠ ${blocked.length} crawled pages are blocked by robots.txt:`));\n for (const b of blocked) {\n console.log(chalk.dim(` - ${b.path} (${b.blockedBy})`));\n }\n console.log(\"\");\n }\n }\n\n // 5. Asset verification\n let assetResult = null;\n if (!opts.skipAssets) {\n const assetSpinner = jsonOutput ? null : ora(\"Verifying assets (og:image, favicon, ...)...\").start();\n\n const pagesForAssetCheck = crawlResult.pages\n .filter((p) => !p.error)\n .map((p) => ({ url: p.url, metadata: p.metadata }));\n assetResult = await verifyAssets(pagesForAssetCheck);\n\n if (!jsonOutput) {\n assetSpinner!.succeed(`Verified ${assetResult.totalChecked} assets`);\n\n const brokenAssets = assetResult.checks.filter((c) => !c.ok);\n const warningAssets = assetResult.checks.filter((c) => c.warning);\n\n for (const asset of brokenAssets) {\n console.log(\n chalk.red(` ✗ ${asset.type}`) +\n chalk.dim(` ${asset.url}`) +\n chalk.red(` — ${asset.error ?? `HTTP ${asset.status}`}`),\n );\n }\n for (const asset of warningAssets) {\n console.log(\n chalk.yellow(` ⚠ ${asset.type}`) +\n chalk.dim(` ${asset.url}`) +\n chalk.yellow(` — ${asset.warning}`),\n );\n }\n if (brokenAssets.length === 0 && warningAssets.length === 0) {\n console.log(chalk.green(` ✓ All assets respond correctly`));\n }\n console.log(\"\");\n }\n }\n\n // 6. Cross-page analysis\n if (!jsonOutput) {\n const a = crawlResult.analysis;\n\n // Duplicate titles\n if (a.duplicateTitles.length > 0) {\n console.log(chalk.bold(\"- Duplicate titles\"));\n for (const dup of a.duplicateTitles.slice(0, 5)) {\n console.log(chalk.red(` ✗ \"${dup.title.length > 60 ? dup.title.slice(0, 57) + \"...\" : dup.title}\"`) + chalk.dim(` (${dup.urls.length} pages)`));\n for (const u of dup.urls.slice(0, 3)) console.log(chalk.dim(` ${u}`));\n if (dup.urls.length > 3) console.log(chalk.dim(` ...and ${dup.urls.length - 3} more`));\n }\n if (a.duplicateTitles.length > 5) console.log(chalk.dim(` ...and ${a.duplicateTitles.length - 5} more groups`));\n console.log(\"\");\n }\n\n // Duplicate descriptions\n if (a.duplicateDescriptions.length > 0) {\n console.log(chalk.bold(\"- Duplicate descriptions\"));\n for (const dup of a.duplicateDescriptions.slice(0, 5)) {\n const desc = dup.description.length > 60 ? dup.description.slice(0, 57) + \"...\" : dup.description;\n console.log(chalk.red(` ✗ \"${desc}\"`) + chalk.dim(` (${dup.urls.length} pages)`));\n for (const u of dup.urls.slice(0, 3)) console.log(chalk.dim(` ${u}`));\n if (dup.urls.length > 3) console.log(chalk.dim(` ...and ${dup.urls.length - 3} more`));\n }\n if (a.duplicateDescriptions.length > 5) console.log(chalk.dim(` ...and ${a.duplicateDescriptions.length - 5} more groups`));\n console.log(\"\");\n }\n\n // H1 issues\n if (a.h1Issues.length > 0) {\n const missing = a.h1Issues.filter(h => h.issue === \"missing\");\n const multiple = a.h1Issues.filter(h => h.issue === \"multiple\");\n console.log(chalk.bold(\"- H1 heading issues\"));\n if (missing.length > 0) {\n console.log(chalk.red(` ✗ ${missing.length} pages missing H1`));\n for (const h of missing.slice(0, 5)) console.log(chalk.dim(` ${h.url}`));\n if (missing.length > 5) console.log(chalk.dim(` ...and ${missing.length - 5} more`));\n }\n if (multiple.length > 0) {\n console.log(chalk.yellow(` ⚠ ${multiple.length} pages with multiple H1s`));\n for (const h of multiple.slice(0, 5)) console.log(chalk.dim(` ${h.url} (${h.count} H1s)`));\n if (multiple.length > 5) console.log(chalk.dim(` ...and ${multiple.length - 5} more`));\n }\n console.log(\"\");\n }\n\n // Broken internal links\n if (a.brokenInternalLinks.length > 0) {\n console.log(chalk.bold(\"- Broken internal links\"));\n for (const bl of a.brokenInternalLinks.slice(0, 10)) {\n console.log(chalk.red(` ✗ ${bl.to}`) + chalk.dim(` ← linked from ${bl.from} (${bl.status})`));\n }\n if (a.brokenInternalLinks.length > 10) console.log(chalk.dim(` ...and ${a.brokenInternalLinks.length - 10} more`));\n console.log(\"\");\n }\n\n // Redirects\n if (a.redirects.length > 0) {\n console.log(chalk.bold(\"- Redirect chains\"));\n for (const r of a.redirects.slice(0, 10)) {\n console.log(chalk.yellow(` ⚠ ${r.url}`));\n for (const step of r.chain) console.log(chalk.dim(` ${step}`));\n }\n if (a.redirects.length > 10) console.log(chalk.dim(` ...and ${a.redirects.length - 10} more`));\n console.log(\"\");\n }\n\n // Thin content\n if (a.thinContentPages.length > 0) {\n const realThin = a.thinContentPages.filter(tc => !tc.isAppPage);\n const appThin = a.thinContentPages.filter(tc => tc.isAppPage);\n\n if (realThin.length > 0) {\n console.log(chalk.bold(\"- Thin content\") + chalk.dim(\" (< 200 words)\"));\n for (const tc of realThin.slice(0, 10)) {\n console.log(chalk.yellow(` ⚠ ${tc.url}`) + chalk.dim(` — ${tc.wordCount} words`));\n }\n if (realThin.length > 10) console.log(chalk.dim(` ...and ${realThin.length - 10} more`));\n console.log(\"\");\n }\n if (appThin.length > 0) {\n console.log(chalk.bold(\"- App/wizard pages\") + chalk.dim(\" (client-rendered, low word count expected)\"));\n for (const tc of appThin.slice(0, 5)) {\n console.log(chalk.dim(` ℹ ${tc.url} — ${tc.wordCount} words`));\n }\n if (appThin.length > 5) console.log(chalk.dim(` ...and ${appThin.length - 5} more`));\n console.log(\"\");\n }\n }\n\n // Orphan pages\n if (a.orphanPages.length > 0) {\n console.log(chalk.bold(\"- Orphan pages\") + chalk.dim(\" (0 internal links pointing to them)\"));\n for (const o of a.orphanPages.slice(0, 10)) console.log(chalk.yellow(` ⚠ ${o}`));\n if (a.orphanPages.length > 10) console.log(chalk.dim(` ...and ${a.orphanPages.length - 10} more`));\n console.log(\"\");\n }\n\n // Slowest pages\n if (a.slowestPages.length > 0 && a.slowestPages[0].responseTimeMs > 1000) {\n console.log(chalk.bold(\"- Slowest pages\"));\n for (const sp of a.slowestPages.filter(p => p.responseTimeMs > 1000).slice(0, 5)) {\n const color = sp.responseTimeMs > 3000 ? chalk.red : chalk.yellow;\n console.log(color(` ⚠ ${sp.url}`) + chalk.dim(` — ${(sp.responseTimeMs / 1000).toFixed(1)}s`));\n }\n console.log(\"\");\n }\n\n // Structured data summary\n if (a.structuredDataSummary.length > 0) {\n console.log(chalk.bold(\"- Structured data (JSON-LD)\"));\n for (const sd of a.structuredDataSummary) {\n console.log(chalk.green(` ✓ ${sd.type}`) + chalk.dim(` — ${sd.count} page${sd.count > 1 ? \"s\" : \"\"}`));\n }\n const pagesWithSD = crawlResult.pages.filter(p => !p.error && p.structuredDataTypes.length > 0).length;\n const pagesWithout = crawlResult.pages.filter(p => !p.error).length - pagesWithSD;\n if (pagesWithout > 0) {\n console.log(chalk.yellow(` ⚠ ${pagesWithout} pages without any structured data`));\n }\n console.log(\"\");\n } else {\n console.log(chalk.bold(\"- Structured data (JSON-LD)\"));\n console.log(chalk.red(` ✗ No structured data found on any page`));\n console.log(\"\");\n }\n }\n\n // 7. Summary\n if (jsonOutput) {\n console.log(\n JSON.stringify(\n {\n crawl: crawlResult,\n robots: robotsResult,\n sitemap: sitemapComparison,\n assets: assetResult,\n },\n null,\n 2,\n ),\n );\n } else {\n const scoreColor =\n crawlResult.averageScore >= 90\n ? chalk.green\n : crawlResult.averageScore >= 70\n ? chalk.yellow\n : chalk.red;\n\n console.log(chalk.bold(\" ─── Summary ───\"));\n console.log(\"\");\n console.log(` Pages crawled: ${chalk.bold(String(crawlResult.totalPages))}`);\n console.log(` Average score: ${scoreColor(chalk.bold(`${crawlResult.averageScore}/100`))} (${crawlResult.grade})`);\n console.log(` Errors: ${crawlResult.totalErrors > 0 ? chalk.red(String(crawlResult.totalErrors)) : chalk.green(\"0\")}`);\n console.log(` Warnings: ${crawlResult.totalWarnings > 0 ? chalk.yellow(String(crawlResult.totalWarnings)) : chalk.green(\"0\")}`);\n if (assetResult) {\n console.log(` Broken assets: ${assetResult.totalBroken > 0 ? chalk.red(String(assetResult.totalBroken)) : chalk.green(\"0\")}`);\n }\n if (crawlResult.skippedUrls.length > 0) {\n console.log(chalk.dim(` Skipped: ${crawlResult.skippedUrls.length} URLs (over limit)`));\n }\n console.log(\"\");\n }\n\n // 8. Push to dashboard\n if (opts.push) {\n const apiKey = opts.apiKey || process.env.INDXEL_API_KEY;\n if (!apiKey) {\n if (!jsonOutput) {\n console.log(chalk.red(\" ✗ --push requires an API key. Use --api-key or set INDXEL_API_KEY.\"));\n console.log(chalk.dim(\" Get your key at https://indxel.com/dashboard/settings\"));\n console.log(\"\");\n }\n } else {\n const pushSpinner = jsonOutput ? null : ora(\"Pushing results to Indxel...\").start();\n try {\n const pushUrl = process.env.INDXEL_API_URL || \"https://www.indxel.com\";\n const res = await fetch(`${pushUrl}/api/cli/push`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${apiKey}`,\n },\n body: JSON.stringify({\n crawl: crawlResult,\n robots: robotsResult,\n sitemap: sitemapComparison,\n assets: assetResult,\n }),\n });\n if (res.ok) {\n const data = (await res.json()) as { checkId?: string };\n if (pushSpinner) pushSpinner.succeed(`Pushed to dashboard — check ${data.checkId}`);\n } else {\n const data = (await res.json().catch(() => ({}))) as { error?: string };\n if (pushSpinner) pushSpinner.fail(`Push failed: ${data.error || res.statusText}`);\n }\n } catch (err) {\n if (pushSpinner) pushSpinner.fail(`Push failed: ${err instanceof Error ? err.message : String(err)}`);\n }\n if (!jsonOutput) console.log(\"\");\n }\n }\n\n // Exit code\n if (crawlResult.totalErrors > 0) {\n process.exit(1);\n }\n });\n","import { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport ora from \"ora\";\nimport { researchKeywords, crawlSite, analyzeContentGaps } from \"indxel\";\n\nexport const keywordsCommand = new Command(\"keywords\")\n .description(\"Research keyword opportunities and find content gaps\")\n .argument(\"<seed>\", \"Seed keyword or topic to research\")\n .option(\"--locale <locale>\", \"Language locale\", \"en\")\n .option(\"--country <country>\", \"Country code\", \"us\")\n .option(\"--site <url>\", \"Site URL to analyze content gaps against\")\n .option(\"--max-pages <n>\", \"Maximum pages to crawl for gap analysis\", \"30\")\n .option(\"--json\", \"Output results as JSON\", false)\n .action(async (seed: string, opts) => {\n const jsonOutput = opts.json;\n\n if (!jsonOutput) {\n console.log(\"\");\n console.log(chalk.bold(` indxel keywords`) + chalk.dim(` — \"${seed}\"`));\n console.log(\"\");\n }\n\n // 1. Keyword research\n const kwSpinner = jsonOutput ? null : ora(\"Researching keywords...\").start();\n const kwResult = await researchKeywords(seed, {\n locale: opts.locale,\n country: opts.country,\n });\n\n if (!jsonOutput) {\n kwSpinner!.succeed(`Found ${kwResult.totalKeywords} keywords`);\n console.log(\"\");\n\n if (kwResult.suggestions.length > 0) {\n console.log(chalk.bold(` Direct suggestions (${kwResult.suggestions.length})`));\n for (const s of kwResult.suggestions) {\n console.log(` ${chalk.hex(\"#F4A261\")(s.keyword)}`);\n }\n console.log(\"\");\n }\n\n if (kwResult.questions.length > 0) {\n console.log(chalk.bold(` Questions (${kwResult.questions.length})`));\n for (const q of kwResult.questions.slice(0, 20)) {\n console.log(` ${chalk.cyan(\"?\")} ${q.keyword}`);\n }\n console.log(\"\");\n }\n\n if (kwResult.longTail.length > 0) {\n console.log(chalk.bold(` Long-tail (${kwResult.longTail.length})`));\n for (const lt of kwResult.longTail.slice(0, 20)) {\n console.log(chalk.dim(` ${lt.keyword}`));\n }\n if (kwResult.longTail.length > 20) {\n console.log(chalk.dim(` ... and ${kwResult.longTail.length - 20} more`));\n }\n console.log(\"\");\n }\n }\n\n // 2. Content gap analysis (if site URL provided)\n let gapResult = null;\n if (opts.site) {\n let siteUrl = opts.site;\n if (!siteUrl.startsWith(\"http://\") && !siteUrl.startsWith(\"https://\")) {\n siteUrl = `https://${siteUrl}`;\n }\n\n const crawlSpinner = jsonOutput ? null : ora(`Crawling ${siteUrl} for gap analysis...`).start();\n const crawlResult = await crawlSite(siteUrl, {\n maxPages: parseInt(opts.maxPages, 10),\n delay: 200,\n });\n\n if (!jsonOutput) {\n crawlSpinner!.succeed(`Crawled ${crawlResult.totalPages} pages`);\n }\n\n const allKeywords = [\n ...kwResult.suggestions,\n ...kwResult.questions,\n ...kwResult.longTail,\n ];\n\n const existingPages = crawlResult.pages\n .filter((p) => !p.error)\n .map((p) => ({ url: p.url, metadata: p.metadata }));\n\n gapResult = analyzeContentGaps(allKeywords, existingPages);\n\n if (!jsonOutput) {\n console.log(\"\");\n console.log(\n chalk.bold(` Content coverage: `) +\n `${gapResult.totalCovered}/${gapResult.totalKeywords} keywords (${gapResult.coveragePercent}%)`,\n );\n console.log(\"\");\n\n if (gapResult.gaps.length > 0) {\n const highGaps = gapResult.gaps.filter((g) => g.relevance === \"high\");\n const medGaps = gapResult.gaps.filter((g) => g.relevance === \"medium\");\n\n if (highGaps.length > 0) {\n console.log(chalk.bold.red(` High priority gaps (${highGaps.length})`));\n for (const gap of highGaps.slice(0, 15)) {\n console.log(\n chalk.red(` ✗ `) +\n `\"${gap.keyword}\" → ` +\n chalk.dim(`${gap.suggestedType} at ${gap.suggestedPath}`),\n );\n }\n console.log(\"\");\n }\n\n if (medGaps.length > 0) {\n console.log(chalk.bold.yellow(` Medium priority gaps (${medGaps.length})`));\n for (const gap of medGaps.slice(0, 10)) {\n console.log(\n chalk.yellow(` ⚠ `) +\n `\"${gap.keyword}\" → ` +\n chalk.dim(`${gap.suggestedType} at ${gap.suggestedPath}`),\n );\n }\n console.log(\"\");\n }\n }\n\n if (gapResult.gaps.length === 0) {\n console.log(chalk.green(` ✓ All keyword opportunities are covered`));\n console.log(\"\");\n }\n }\n }\n\n // JSON output\n if (jsonOutput) {\n console.log(\n JSON.stringify(\n { keywords: kwResult, contentGaps: gapResult },\n null,\n 2,\n ),\n );\n }\n });\n","import { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport ora from \"ora\";\nimport { fetchSitemap, fetchRobots } from \"indxel\";\n\nasync function checkPlan(apiKey: string): Promise<string | null> {\n try {\n const apiUrl = process.env.INDXEL_API_URL || \"https://www.indxel.com\";\n const res = await fetch(`${apiUrl}/api/cli/plan`, {\n headers: { Authorization: `Bearer ${apiKey}` },\n signal: AbortSignal.timeout(10000),\n });\n if (!res.ok) return null;\n const data = (await res.json()) as { plan?: string };\n return data.plan ?? null;\n } catch {\n return null;\n }\n}\n\nexport const indexCommand = new Command(\"index\")\n .description(\"Submit your pages to search engines and check indexation status\")\n .argument(\"<url>\", \"Site URL (e.g., https://yoursite.com)\")\n .option(\"--check\", \"Check which pages appear indexed (Pro+)\", false)\n .option(\"--indexnow-key <key>\", \"IndexNow API key for Bing/Yandex/DuckDuckGo submission (Pro+)\")\n .option(\"--api-key <key>\", \"Indxel API key (required for --check and --indexnow-key)\")\n .option(\"--json\", \"Output results as JSON\", false)\n .action(async (url: string, opts) => {\n const jsonOutput = opts.json;\n const needsPaid = opts.check || opts.indexnowKey;\n\n // Ensure URL has protocol\n if (!url.startsWith(\"http://\") && !url.startsWith(\"https://\")) {\n url = `https://${url}`;\n }\n\n let baseUrl: URL;\n try {\n baseUrl = new URL(url);\n } catch {\n console.error(chalk.red(\" Invalid URL.\"));\n process.exit(1);\n }\n\n const origin = baseUrl.origin;\n const host = baseUrl.hostname;\n\n if (!jsonOutput) {\n console.log(\"\");\n console.log(chalk.bold(\" indxel index\") + chalk.dim(` — ${origin}`));\n console.log(\"\");\n }\n\n // Gate paid features behind API key + plan check\n if (needsPaid) {\n const apiKey = opts.apiKey || process.env.INDXEL_API_KEY;\n if (!apiKey) {\n if (!jsonOutput) {\n console.log(chalk.red(\" ✗ --check and --indexnow-key require an API key (Pro plan).\"));\n console.log(chalk.dim(\" Use --api-key or set INDXEL_API_KEY.\"));\n console.log(chalk.dim(\" Get your key at https://indxel.com/dashboard/settings\"));\n console.log(\"\");\n }\n process.exit(1);\n }\n\n const plan = await checkPlan(apiKey);\n if (!plan) {\n if (!jsonOutput) {\n console.log(chalk.red(\" ✗ Invalid API key.\"));\n console.log(\"\");\n }\n process.exit(1);\n }\n\n if (plan === \"FREE\") {\n if (!jsonOutput) {\n console.log(chalk.red(\" ✗ IndexNow submission and indexation check require a Pro plan.\"));\n console.log(chalk.dim(\" Upgrade at https://indxel.com/pricing\"));\n console.log(\"\");\n }\n process.exit(1);\n }\n }\n\n // 1. Fetch sitemap\n const sitemapSpinner = jsonOutput ? null : ora(\"Fetching sitemap...\").start();\n const sitemapResult = await fetchSitemap(origin);\n const sitemapUrl = `${origin}/sitemap.xml`;\n\n if (!sitemapResult.found || sitemapResult.urls.length === 0) {\n if (sitemapSpinner) sitemapSpinner.fail(\"No sitemap found\");\n if (!jsonOutput) {\n console.log(chalk.dim(\" Create a sitemap first: \") + chalk.bold(\"npx indxel init\"));\n console.log(\"\");\n }\n if (jsonOutput) {\n console.log(JSON.stringify({ error: \"No sitemap found\" }, null, 2));\n }\n process.exit(1);\n }\n\n if (sitemapSpinner) sitemapSpinner.succeed(`Found sitemap — ${sitemapResult.urls.length} URLs`);\n\n // 2. Check robots.txt references sitemap\n const robotsSpinner = jsonOutput ? null : ora(\"Checking robots.txt...\").start();\n const robotsResult = await fetchRobots(origin);\n let sitemapInRobots = false;\n\n if (robotsResult.found) {\n sitemapInRobots = robotsResult.sitemapUrls.some((s) =>\n s.toLowerCase().includes(\"sitemap\"),\n );\n if (sitemapInRobots) {\n if (robotsSpinner) robotsSpinner.succeed(\"robots.txt references sitemap\");\n } else {\n if (robotsSpinner) robotsSpinner.warn(\"robots.txt found but doesn't reference sitemap\");\n if (!jsonOutput) {\n console.log(chalk.dim(` Add this to your robots.txt:`));\n console.log(chalk.dim(` Sitemap: ${sitemapUrl}`));\n }\n }\n } else {\n if (robotsSpinner) robotsSpinner.warn(\"No robots.txt found\");\n if (!jsonOutput) {\n console.log(chalk.dim(\" Create one with: \") + chalk.bold(\"npx indxel init\"));\n }\n }\n\n if (!jsonOutput) console.log(\"\");\n\n // 3. IndexNow submission (Bing, Yandex, DuckDuckGo, etc.)\n const indexNowKey = opts.indexnowKey || process.env.INDEXNOW_KEY;\n let indexNowResult: { submitted: boolean; engine: string; status?: number }[] = [];\n\n if (indexNowKey) {\n const urls = sitemapResult.urls.map((u) => u.loc);\n const indexNowSpinner = jsonOutput ? null : ora(\"Submitting via IndexNow...\").start();\n\n // IndexNow supports batch submission\n const indexNowEngines = [\n { name: \"Bing/Yandex\", endpoint: \"https://api.indexnow.org/indexnow\" },\n ];\n\n for (const engine of indexNowEngines) {\n try {\n const res = await fetch(engine.endpoint, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n host,\n key: indexNowKey,\n keyLocation: `${origin}/${indexNowKey}.txt`,\n urlList: urls.slice(0, 10000), // IndexNow limit\n }),\n signal: AbortSignal.timeout(15000),\n });\n\n if (res.ok || res.status === 200 || res.status === 202) {\n indexNowResult.push({ submitted: true, engine: engine.name, status: res.status });\n if (indexNowSpinner) indexNowSpinner.succeed(`IndexNow — ${urls.length} URLs submitted to ${engine.name}`);\n } else {\n indexNowResult.push({ submitted: false, engine: engine.name, status: res.status });\n if (indexNowSpinner) indexNowSpinner.warn(`IndexNow — ${engine.name} returned HTTP ${res.status}`);\n }\n } catch (err) {\n indexNowResult.push({ submitted: false, engine: engine.name });\n if (indexNowSpinner) indexNowSpinner.fail(`IndexNow — ${err instanceof Error ? err.message : \"failed\"}`);\n }\n }\n } else {\n if (!jsonOutput) {\n console.log(chalk.bold(\" IndexNow\") + chalk.dim(\" (Bing, Yandex, DuckDuckGo)\"));\n console.log(chalk.dim(\" Get instant indexing by setting up IndexNow:\"));\n console.log(chalk.dim(\" 1. Generate a key at \") + chalk.underline(\"https://www.bing.com/indexnow\"));\n console.log(chalk.dim(` 2. Host the key file at ${origin}/{key}.txt`));\n console.log(chalk.dim(\" 3. Run: \") + chalk.bold(`npx indxel index ${host} --indexnow-key YOUR_KEY`));\n console.log(\"\");\n }\n }\n\n if (!jsonOutput) {\n console.log(chalk.bold(\" Google Search Console\"));\n console.log(chalk.dim(\" Google requires manual setup via Search Console:\"));\n console.log(chalk.dim(\" 1. Go to \") + chalk.underline(\"https://search.google.com/search-console\"));\n console.log(chalk.dim(` 2. Add & verify ${host}`));\n console.log(chalk.dim(\" 3. Submit your sitemap: Sitemaps > Add > sitemap.xml\"));\n console.log(\"\");\n }\n\n // 4. Check indexation status (optional)\n let indexationResults: Array<{ url: string; indexed: boolean }> | null = null;\n\n if (opts.check) {\n const checkSpinner = jsonOutput ? null : ora(\"Checking indexation status...\").start();\n indexationResults = [];\n const urls = sitemapResult.urls.map((u) => u.loc);\n let indexedCount = 0;\n\n for (let i = 0; i < urls.length; i++) {\n const pageUrl = urls[i];\n if (checkSpinner) {\n checkSpinner.text = `Checking indexation... ${i + 1}/${urls.length}`;\n }\n\n try {\n const cacheUrl = `https://webcache.googleusercontent.com/search?q=cache:${encodeURIComponent(pageUrl)}`;\n const res = await fetch(cacheUrl, {\n method: \"HEAD\",\n signal: AbortSignal.timeout(5000),\n redirect: \"manual\",\n headers: {\n \"User-Agent\": \"Mozilla/5.0 (compatible; Indxel/0.1; +https://indxel.com)\",\n },\n });\n\n const indexed = res.status === 200 || res.status === 301 || res.status === 302;\n indexationResults.push({ url: pageUrl, indexed });\n if (indexed) indexedCount++;\n } catch {\n indexationResults.push({ url: pageUrl, indexed: false });\n }\n\n // Rate limit\n await new Promise((r) => setTimeout(r, 300));\n }\n\n if (checkSpinner) {\n checkSpinner.succeed(`Indexation: ${indexedCount}/${urls.length} pages found in Google cache`);\n }\n\n if (!jsonOutput) {\n console.log(\"\");\n const notIndexed = indexationResults.filter((r) => !r.indexed);\n\n if (notIndexed.length > 0) {\n console.log(chalk.bold(` Not indexed (${notIndexed.length})`));\n for (const r of notIndexed.slice(0, 20)) {\n console.log(chalk.red(\" ✗ \") + r.url);\n }\n if (notIndexed.length > 20) console.log(chalk.dim(` ... and ${notIndexed.length - 20} more`));\n console.log(\"\");\n }\n\n if (notIndexed.length === 0) {\n console.log(chalk.green(\" ✓ All pages appear indexed\"));\n console.log(\"\");\n }\n }\n }\n\n // 5. Summary\n if (jsonOutput) {\n console.log(JSON.stringify({\n sitemap: { url: sitemapUrl, urls: sitemapResult.urls.length },\n robotsTxt: { found: robotsResult.found, referencesSitemap: sitemapInRobots },\n indexNow: indexNowResult.length > 0 ? indexNowResult : null,\n indexation: indexationResults,\n }, null, 2));\n } else {\n console.log(chalk.bold(\" ─── Summary ───\"));\n console.log(\"\");\n console.log(` Sitemap: ${sitemapResult.urls.length} URLs`);\n console.log(` robots.txt: ${robotsResult.found ? (sitemapInRobots ? chalk.green(\"✓ references sitemap\") : chalk.yellow(\"⚠ missing sitemap ref\")) : chalk.red(\"✗ not found\")}`);\n if (indexNowResult.length > 0) {\n for (const r of indexNowResult) {\n console.log(` IndexNow: ${r.submitted ? chalk.green(\"✓ submitted\") : chalk.red(\"✗ failed\")} (${r.engine})`);\n }\n } else {\n console.log(` IndexNow: ${chalk.dim(\"not configured (use --indexnow-key)\")}`);\n }\n if (indexationResults) {\n const indexedCount = indexationResults.filter((r) => r.indexed).length;\n console.log(` Google cache: ${indexedCount}/${indexationResults.length} indexed`);\n }\n console.log(\"\");\n }\n });\n"],"mappings":"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","names":["Command","existsSync","readFile","join","join","existsSync","readFile","Command","chalk","ora","readFile","join","chalk","existsSync","readFile","writeFile","mkdir","join","Command","ora","chalk","Command","chalk","ora","Command","chalk","ora","crawlSite","Command","chalk","ora","fetchSitemap","fetchRobots","Command"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/commands/init.ts","../src/detect.ts","../src/store.ts","../src/templates.ts","../src/commands/check.ts","../src/scanner.ts","../src/config.ts","../src/formatter.ts","../src/fixer.ts","../src/commands/crawl.ts","../src/commands/keywords.ts","../src/commands/index.ts","../src/auth.ts","../src/commands/perf.ts","../src/commands/link.ts"],"sourcesContent":["import { Command } from \"commander\";\nimport { initCommand } from \"./commands/init.js\";\nimport { checkCommand } from \"./commands/check.js\";\nimport { crawlCommand } from \"./commands/crawl.js\";\nimport { keywordsCommand } from \"./commands/keywords.js\";\nimport { indexCommand } from \"./commands/index.js\";\nimport { perfCommand } from \"./commands/perf.js\";\nimport { linkCommand } from \"./commands/link.js\";\n\nexport function createProgram(): Command {\n const program = new Command();\n\n program\n .name(\"indxel\")\n .description(\"Infrastructure SEO developer-first. ESLint pour le SEO.\")\n .version(\"0.1.0\");\n\n program.addCommand(initCommand);\n program.addCommand(checkCommand);\n program.addCommand(crawlCommand);\n program.addCommand(keywordsCommand);\n program.addCommand(indexCommand);\n program.addCommand(perfCommand);\n program.addCommand(linkCommand);\n\n return program;\n}\n\nexport { initCommand, checkCommand, crawlCommand, keywordsCommand, indexCommand, perfCommand, linkCommand };\n","import { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport ora from \"ora\";\nimport { existsSync } from \"node:fs\";\nimport { writeFile, mkdir, readFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { detectProject } from \"../detect.js\";\nimport { generateIndexNowKey, saveIndexNowKey, loadIndexNowKey } from \"../store.js\";\nimport {\n seoConfigTemplate,\n sitemapTemplate,\n robotsTemplate,\n} from \"../templates.js\";\n\nconst PRE_PUSH_HOOK = `#!/bin/sh\n# indxel SEO guard — blocks push if critical SEO errors are found\necho \"\\\\033[36m[indxel]\\\\033[0m Running SEO check before push...\"\nnpx indxel-cli check --ci\nif [ $? -ne 0 ]; then\n echo \"\"\n echo \"\\\\033[31m[indxel] Push blocked — fix SEO errors first.\\\\033[0m\"\n echo \"\\\\033[2m Run 'npx indxel-cli check' for details.\\\\033[0m\"\n exit 1\nfi\n`;\n\nexport const initCommand = new Command(\"init\")\n .description(\"Initialize indxel in your Next.js project\")\n .option(\"--cwd <path>\", \"Project directory\", process.cwd())\n .option(\"--force\", \"Overwrite existing files\", false)\n .option(\"--hook\", \"Install git pre-push hook to block pushes on SEO errors\", false)\n .action(async (opts) => {\n const cwd = opts.cwd;\n const spinner = ora(\"Detecting project...\").start();\n\n // 1. Detect project\n const project = await detectProject(cwd);\n\n if (!project.isNextJs) {\n spinner.fail(\"Not a Next.js project\");\n console.log(\n chalk.dim(\" indxel currently supports Next.js projects only.\"),\n );\n console.log(\n chalk.dim(\" Make sure you're in a directory with a next.config file.\"),\n );\n process.exit(1);\n }\n\n spinner.succeed(\n `Detected Next.js ${project.nextVersion ?? \"\"} (${project.usesAppRouter ? \"App Router\" : \"Pages Router\"})`,\n );\n\n const ext = project.isTypeScript ? \"ts\" : \"js\";\n const filesCreated: string[] = [];\n\n // 2. Generate seo.config.ts\n if (!project.hasSeoConfig || opts.force) {\n const configPath = join(cwd, `seo.config.${ext}`);\n await writeFile(configPath, seoConfigTemplate(project.isTypeScript), \"utf-8\");\n filesCreated.push(`seo.config.${ext}`);\n console.log(chalk.green(\" ✓\") + ` Generated seo.config.${ext}`);\n } else {\n console.log(chalk.dim(` - seo.config.${ext} already exists (skip)`));\n }\n\n // 3. Generate sitemap.ts\n if (!project.hasSitemap || opts.force) {\n const sitemapPath = join(cwd, project.appDir, `sitemap.${ext}`);\n await writeFile(sitemapPath, sitemapTemplate(project.isTypeScript), \"utf-8\");\n filesCreated.push(`${project.appDir}/sitemap.${ext}`);\n console.log(chalk.green(\" ✓\") + ` Generated ${project.appDir}/sitemap.${ext}`);\n } else {\n console.log(chalk.dim(` - sitemap already exists (skip)`));\n }\n\n // 4. Generate robots.ts\n if (!project.hasRobots || opts.force) {\n const robotsPath = join(cwd, project.appDir, `robots.${ext}`);\n await writeFile(robotsPath, robotsTemplate(project.isTypeScript), \"utf-8\");\n filesCreated.push(`${project.appDir}/robots.${ext}`);\n console.log(chalk.green(\" ✓\") + ` Generated ${project.appDir}/robots.${ext}`);\n } else {\n console.log(chalk.dim(` - robots already exists (skip)`));\n }\n\n // 5. Git pre-push hook\n const gitDir = join(cwd, \".git\");\n const hasGit = existsSync(gitDir);\n\n if (opts.hook || opts.force) {\n if (!hasGit) {\n console.log(chalk.yellow(\" ⚠\") + \" No .git directory found — skip hook install\");\n } else {\n const hooksDir = join(gitDir, \"hooks\");\n const hookPath = join(hooksDir, \"pre-push\");\n\n // Check if a pre-push hook already exists\n if (existsSync(hookPath) && !opts.force) {\n const existing = await readFile(hookPath, \"utf-8\");\n if (existing.includes(\"indxel\")) {\n console.log(chalk.dim(\" - pre-push hook already installed (skip)\"));\n } else {\n console.log(chalk.yellow(\" ⚠\") + \" pre-push hook already exists (use --force to overwrite)\");\n }\n } else {\n await mkdir(hooksDir, { recursive: true });\n await writeFile(hookPath, PRE_PUSH_HOOK, { mode: 0o755 });\n filesCreated.push(\".git/hooks/pre-push\");\n console.log(chalk.green(\" ✓\") + \" Installed git pre-push hook\");\n }\n }\n } else if (hasGit) {\n console.log(chalk.dim(\" - Use --hook to install git pre-push guard\"));\n }\n\n // 6. IndexNow — zero-friction setup\n const existingKey = await loadIndexNowKey(cwd);\n if (!existingKey || opts.force) {\n const key = generateIndexNowKey();\n const publicDir = join(cwd, \"public\");\n if (!existsSync(publicDir)) {\n await mkdir(publicDir, { recursive: true });\n }\n await writeFile(join(publicDir, `${key}.txt`), key, \"utf-8\");\n await saveIndexNowKey(cwd, key);\n filesCreated.push(`public/${key}.txt`);\n console.log(chalk.green(\" ✓\") + \" IndexNow ready — Bing, Yandex & Naver will pick up your pages on deploy\");\n } else {\n // Key exists — make sure the public file is there too\n const keyFile = join(cwd, \"public\", `${existingKey}.txt`);\n if (existsSync(keyFile)) {\n console.log(chalk.dim(\" - IndexNow already set up (skip)\"));\n } else {\n const publicDir = join(cwd, \"public\");\n if (!existsSync(publicDir)) {\n await mkdir(publicDir, { recursive: true });\n }\n await writeFile(keyFile, existingKey, \"utf-8\");\n filesCreated.push(`public/${existingKey}.txt`);\n console.log(chalk.green(\" ✓\") + \" IndexNow key file restored\");\n }\n }\n\n // 7. Summary\n console.log(\"\");\n if (filesCreated.length > 0) {\n console.log(\n chalk.bold(` ${filesCreated.length} file${filesCreated.length > 1 ? \"s\" : \"\"} created.`),\n );\n } else {\n console.log(chalk.dim(\" Nothing to create — all files already exist.\"));\n console.log(chalk.dim(\" Use --force to overwrite.\"));\n }\n\n console.log(\"\");\n console.log(chalk.dim(\" Next steps:\"));\n console.log(chalk.dim(` 1. Edit seo.config.${ext} with your site details`));\n console.log(chalk.dim(\" 2. Run \") + chalk.bold(\"npx indxel check\") + chalk.dim(\" to audit your pages\"));\n if (!opts.hook && hasGit) {\n console.log(chalk.dim(\" 3. Run \") + chalk.bold(\"npx indxel init --hook\") + chalk.dim(\" to guard git pushes\"));\n }\n console.log(\"\");\n console.log(chalk.dim(\" Want continuous monitoring?\"));\n console.log(chalk.dim(\" Run \") + chalk.bold(\"npx indxel link\") + chalk.dim(\" to connect your dashboard.\"));\n console.log(\"\");\n });\n","import { existsSync } from \"node:fs\";\nimport { readFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n\nexport interface ProjectInfo {\n /** Root directory of the project */\n root: string;\n /** Whether this is a Next.js project */\n isNextJs: boolean;\n /** Next.js version if detected */\n nextVersion?: string;\n /** Whether it uses App Router (has src/app or app directory) */\n usesAppRouter: boolean;\n /** The app directory path (relative) */\n appDir: string;\n /** Whether TypeScript is used */\n isTypeScript: boolean;\n /** Whether seo.config.ts/js already exists */\n hasSeoConfig: boolean;\n /** Whether sitemap.ts/js exists */\n hasSitemap: boolean;\n /** Whether robots.ts/js exists */\n hasRobots: boolean;\n}\n\n/** Detect project type and configuration from the given directory. */\nexport async function detectProject(cwd: string): Promise<ProjectInfo> {\n const info: ProjectInfo = {\n root: cwd,\n isNextJs: false,\n usesAppRouter: false,\n appDir: \"app\",\n isTypeScript: false,\n hasSeoConfig: false,\n hasSitemap: false,\n hasRobots: false,\n };\n\n // Check for Next.js config files\n const nextConfigs = [\n \"next.config.ts\",\n \"next.config.js\",\n \"next.config.mjs\",\n \"next.config.cjs\",\n ];\n info.isNextJs = nextConfigs.some((f) => existsSync(join(cwd, f)));\n\n // Read Next.js version from package.json\n const pkgPath = join(cwd, \"package.json\");\n if (existsSync(pkgPath)) {\n try {\n const pkg = JSON.parse(await readFile(pkgPath, \"utf-8\"));\n const nextDep = pkg.dependencies?.next ?? pkg.devDependencies?.next;\n if (nextDep) {\n info.isNextJs = true;\n info.nextVersion = nextDep.replace(/[\\^~>=<]/g, \"\").trim();\n }\n } catch {\n // Ignore parse errors\n }\n }\n\n // Check for TypeScript\n info.isTypeScript =\n existsSync(join(cwd, \"tsconfig.json\")) ||\n existsSync(join(cwd, \"tsconfig.ts\"));\n\n // Detect App Router directory\n if (existsSync(join(cwd, \"src\", \"app\"))) {\n info.usesAppRouter = true;\n info.appDir = \"src/app\";\n } else if (existsSync(join(cwd, \"app\"))) {\n info.usesAppRouter = true;\n info.appDir = \"app\";\n }\n\n // Check for existing SEO files (check both .ts and .js regardless of project type)\n info.hasSeoConfig =\n existsSync(join(cwd, \"seo.config.ts\")) ||\n existsSync(join(cwd, \"seo.config.js\"));\n\n info.hasSitemap =\n existsSync(join(cwd, info.appDir, \"sitemap.ts\")) ||\n existsSync(join(cwd, info.appDir, \"sitemap.js\")) ||\n existsSync(join(cwd, info.appDir, \"sitemap.xml\"));\n\n info.hasRobots =\n existsSync(join(cwd, info.appDir, \"robots.ts\")) ||\n existsSync(join(cwd, info.appDir, \"robots.js\")) ||\n existsSync(join(cwd, info.appDir, \"robots.txt\"));\n\n return info;\n}\n","import { existsSync } from \"node:fs\";\nimport { readFile, writeFile, mkdir } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { randomBytes } from \"node:crypto\";\nimport type { CheckSummary } from \"./formatter.js\";\n\nconst STORE_DIR = \".indxel\";\nconst LAST_CHECK_FILE = \"last-check.json\";\nconst INDEXNOW_KEY_FILE = \"indexnow-key.txt\";\nconst CONFIG_FILE = \"config.json\";\n\nexport interface StoredCheck {\n timestamp: string;\n summary: CheckSummary;\n}\n\n/** Save the current check results for future diff comparison */\nexport async function saveCheckResult(\n cwd: string,\n summary: CheckSummary,\n): Promise<void> {\n const storeDir = join(cwd, STORE_DIR);\n\n if (!existsSync(storeDir)) {\n await mkdir(storeDir, { recursive: true });\n }\n\n const stored: StoredCheck = {\n timestamp: new Date().toISOString(),\n summary: {\n ...summary,\n // Serialize results with minimal data needed for diff\n results: summary.results.map((r) => ({\n page: {\n filePath: r.page.filePath,\n route: r.page.route,\n hasMetadata: r.page.hasMetadata,\n hasDynamicMetadata: r.page.hasDynamicMetadata,\n isClientComponent: r.page.isClientComponent,\n titleIsAbsolute: r.page.titleIsAbsolute,\n extractedMetadata: r.page.extractedMetadata,\n },\n validation: r.validation,\n })),\n },\n };\n\n await writeFile(\n join(storeDir, LAST_CHECK_FILE),\n JSON.stringify(stored, null, 2),\n \"utf-8\",\n );\n}\n\n/** Load the previous check result (or null if none exists) */\nexport async function loadPreviousCheck(\n cwd: string,\n): Promise<StoredCheck | null> {\n const filePath = join(cwd, STORE_DIR, LAST_CHECK_FILE);\n\n if (!existsSync(filePath)) {\n return null;\n }\n\n try {\n const data = await readFile(filePath, \"utf-8\");\n return JSON.parse(data) as StoredCheck;\n } catch {\n return null;\n }\n}\n\n/** Get the .indxel directory path */\nexport function getStoreDir(cwd: string): string {\n return join(cwd, STORE_DIR);\n}\n\n/** Generate a 32-character hex IndexNow key */\nexport function generateIndexNowKey(): string {\n return randomBytes(16).toString(\"hex\");\n}\n\n/** Save an IndexNow key to the .indxel store */\nexport async function saveIndexNowKey(cwd: string, key: string): Promise<void> {\n const storeDir = join(cwd, STORE_DIR);\n if (!existsSync(storeDir)) {\n await mkdir(storeDir, { recursive: true });\n }\n await writeFile(join(storeDir, INDEXNOW_KEY_FILE), key, \"utf-8\");\n}\n\n/** Load the IndexNow key from the .indxel store (or null if not set up) */\nexport async function loadIndexNowKey(cwd: string): Promise<string | null> {\n const filePath = join(cwd, STORE_DIR, INDEXNOW_KEY_FILE);\n if (!existsSync(filePath)) return null;\n try {\n const key = (await readFile(filePath, \"utf-8\")).trim();\n return key || null;\n } catch {\n return null;\n }\n}\n\n// --- Project config (set by `npx indxel link`) ---\n\nexport interface ProjectConfig {\n apiKey: string;\n projectId: string;\n projectName: string;\n linkedAt: string;\n}\n\n/** Save project config after linking */\nexport async function saveProjectConfig(\n cwd: string,\n config: ProjectConfig,\n): Promise<void> {\n const storeDir = join(cwd, STORE_DIR);\n if (!existsSync(storeDir)) {\n await mkdir(storeDir, { recursive: true });\n }\n await writeFile(\n join(storeDir, CONFIG_FILE),\n JSON.stringify(config, null, 2),\n \"utf-8\",\n );\n}\n\n/** Load project config (or null if not linked) */\nexport async function loadProjectConfig(\n cwd: string,\n): Promise<ProjectConfig | null> {\n const filePath = join(cwd, STORE_DIR, CONFIG_FILE);\n if (!existsSync(filePath)) return null;\n try {\n const data = await readFile(filePath, \"utf-8\");\n return JSON.parse(data) as ProjectConfig;\n } catch {\n return null;\n }\n}\n\n/**\n * Resolve API key from multiple sources (in priority order):\n * 1. Explicit --api-key flag\n * 2. INDXEL_API_KEY environment variable\n * 3. .indxel/config.json (set by `npx indxel link`)\n */\nexport async function resolveApiKey(\n explicit?: string,\n): Promise<string | null> {\n if (explicit) return explicit;\n if (process.env.INDXEL_API_KEY) return process.env.INDXEL_API_KEY;\n const config = await loadProjectConfig(process.cwd());\n return config?.apiKey ?? null;\n}\n","/** Generate the seo.config.ts template */\nexport function seoConfigTemplate(isTypeScript: boolean): string {\n if (isTypeScript) {\n return `import { defineSEO } from 'indxel'\n\nexport default defineSEO({\n siteName: 'My Site',\n siteUrl: 'https://example.com',\n titleTemplate: '%s | My Site',\n defaultDescription: 'A short description of your site for search engines.',\n defaultOGImage: '/og-image.png',\n locale: 'en_US',\n // twitter: {\n // handle: '@yourhandle',\n // cardType: 'summary_large_image',\n // },\n // organization: {\n // name: 'My Company',\n // logo: '/logo.png',\n // url: 'https://example.com',\n // },\n})\n`;\n }\n\n return `const { defineSEO } = require('indxel')\n\nmodule.exports = defineSEO({\n siteName: 'My Site',\n siteUrl: 'https://example.com',\n titleTemplate: '%s | My Site',\n defaultDescription: 'A short description of your site for search engines.',\n defaultOGImage: '/og-image.png',\n locale: 'en_US',\n})\n`;\n}\n\n/** Generate the sitemap.ts template */\nexport function sitemapTemplate(isTypeScript: boolean): string {\n if (isTypeScript) {\n return `import type { MetadataRoute } from 'next'\n\nexport default function sitemap(): MetadataRoute.Sitemap {\n const baseUrl = 'https://example.com'\n\n return [\n {\n url: baseUrl,\n lastModified: new Date(),\n changeFrequency: 'weekly',\n priority: 1,\n },\n // Add more pages here or generate dynamically:\n //\n // const posts = await getPosts()\n // return posts.map(post => ({\n // url: \\`\\${baseUrl}/blog/\\${post.slug}\\`,\n // lastModified: post.updatedAt,\n // changeFrequency: 'monthly',\n // priority: 0.7,\n // }))\n ]\n}\n`;\n }\n\n return `/** @returns {import('next').MetadataRoute.Sitemap} */\nexport default function sitemap() {\n const baseUrl = 'https://example.com'\n\n return [\n {\n url: baseUrl,\n lastModified: new Date(),\n changeFrequency: 'weekly',\n priority: 1,\n },\n ]\n}\n`;\n}\n\n/** Generate the robots.ts template */\nexport function robotsTemplate(isTypeScript: boolean): string {\n if (isTypeScript) {\n return `import type { MetadataRoute } from 'next'\n\nexport default function robots(): MetadataRoute.Robots {\n const baseUrl = 'https://example.com'\n\n return {\n rules: [\n {\n userAgent: '*',\n allow: '/',\n disallow: ['/api/', '/private/'],\n },\n ],\n sitemap: \\`\\${baseUrl}/sitemap.xml\\`,\n }\n}\n`;\n }\n\n return `/** @returns {import('next').MetadataRoute.Robots} */\nexport default function robots() {\n const baseUrl = 'https://example.com'\n\n return {\n rules: [\n {\n userAgent: '*',\n allow: '/',\n disallow: ['/api/', '/private/'],\n },\n ],\n sitemap: \\`\\${baseUrl}/sitemap.xml\\`,\n }\n}\n`;\n}\n","import { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport ora from \"ora\";\nimport { validateMetadata } from \"indxel\";\nimport { detectProject } from \"../detect.js\";\nimport { scanPages } from \"../scanner.js\";\nimport { loadConfig } from \"../config.js\";\nimport {\n formatPageResult,\n formatSkippedPage,\n formatSummary,\n formatJSON,\n formatDiff,\n computeSummary,\n type CheckResult,\n} from \"../formatter.js\";\nimport { saveCheckResult, loadPreviousCheck } from \"../store.js\";\nimport { generateFixSuggestions } from \"../fixer.js\";\n\nexport const checkCommand = new Command(\"check\")\n .description(\"Audit SEO metadata for all pages in your project\")\n .option(\"--cwd <path>\", \"Project directory\", process.cwd())\n .option(\"--ci\", \"CI/CD mode — strict, exit 1 on any error\", false)\n .option(\"--diff\", \"Compare with previous check run\", false)\n .option(\"--json\", \"Output results as JSON\", false)\n .option(\"--strict\", \"Treat warnings as errors\", false)\n .option(\"--min-score <score>\", \"Minimum score to pass (0-100, default: exit on any error)\")\n .option(\"--fix\", \"Show suggested metadata code to fix errors\", false)\n .action(async (opts) => {\n const cwd = opts.cwd;\n const isCI = opts.ci;\n const isStrict = opts.strict || isCI;\n const showDiff = opts.diff;\n const jsonOutput = opts.json;\n const showFix = opts.fix;\n\n // Load config file (.indxelrc.json, etc.)\n const config = await loadConfig(cwd);\n\n // --min-score flag overrides config, config overrides default\n const minScore = opts.minScore\n ? parseInt(opts.minScore, 10)\n : config.minScore ?? null;\n\n // 1. Detect project\n const spinner = ora(\"Detecting project...\").start();\n const project = await detectProject(cwd);\n\n if (!project.isNextJs) {\n spinner.fail(\"Not a Next.js project\");\n if (!jsonOutput) {\n console.log(chalk.dim(\" Run this command from a Next.js project root.\"));\n }\n process.exit(1);\n }\n\n if (!project.usesAppRouter) {\n spinner.fail(\"App Router not detected\");\n if (!jsonOutput) {\n console.log(chalk.dim(\" indxel requires Next.js App Router (src/app or app directory).\"));\n }\n process.exit(1);\n }\n\n // 2. Scan pages\n spinner.text = \"Scanning pages...\";\n const allPages = await scanPages(cwd, project.appDir);\n\n if (allPages.length === 0) {\n spinner.fail(\"No pages found\");\n if (!jsonOutput) {\n console.log(chalk.dim(` No page.tsx/ts files found in ${project.appDir}/`));\n }\n process.exit(1);\n }\n\n // Filter out ignored routes\n const ignoreRoutes = config.ignoreRoutes ?? [];\n const pages = ignoreRoutes.length > 0\n ? allPages.filter((p) => !ignoreRoutes.some((pattern) => matchRoute(p.route, pattern)))\n : allPages;\n const ignoredCount = allPages.length - pages.length;\n\n spinner.succeed(`Found ${allPages.length} page${allPages.length > 1 ? \"s\" : \"\"}${ignoredCount > 0 ? ` (${ignoredCount} ignored)` : \"\"}`);\n\n // 3. Separate static vs dynamic pages\n const staticPages = pages.filter((p) => !p.hasDynamicMetadata);\n const dynamicPages = pages.filter((p) => p.hasDynamicMetadata);\n\n if (!jsonOutput) {\n console.log(\"\");\n console.log(chalk.bold(` Checking ${staticPages.length} page${staticPages.length !== 1 ? \"s\" : \"\"}...`));\n if (dynamicPages.length > 0) {\n console.log(chalk.dim(` (${dynamicPages.length} dynamic page${dynamicPages.length !== 1 ? \"s\" : \"\"} skipped)`));\n }\n if (ignoredCount > 0) {\n console.log(chalk.dim(` (${ignoredCount} page${ignoredCount !== 1 ? \"s\" : \"\"} excluded by ignoreRoutes)`));\n }\n console.log(\"\");\n }\n\n // 4. Validate static pages only\n const results: CheckResult[] = [];\n\n for (const page of staticPages) {\n const validation = validateMetadata(page.extractedMetadata, {\n strict: isStrict,\n disabledRules: config.disabledRules,\n });\n\n const result: CheckResult = { page, validation };\n results.push(result);\n\n if (!jsonOutput) {\n console.log(formatPageResult(result));\n }\n }\n\n // Show skipped dynamic pages\n if (!jsonOutput && dynamicPages.length > 0) {\n console.log(\"\");\n for (const page of dynamicPages) {\n console.log(formatSkippedPage(page));\n }\n }\n\n // 5. Compute summary (score only counts static pages)\n const summary = computeSummary(results, dynamicPages.length);\n\n // 6. Save results for future diff\n await saveCheckResult(cwd, summary);\n\n // 7. Show diff if requested\n if (showDiff && !jsonOutput) {\n const previous = await loadPreviousCheck(cwd);\n if (previous) {\n console.log(formatDiff(summary, previous.summary));\n } else {\n console.log(chalk.dim(\"\\n No previous check found. Run again to see a diff.\\n\"));\n }\n }\n\n // 8. Output\n if (jsonOutput) {\n console.log(formatJSON(summary));\n } else {\n console.log(formatSummary(summary));\n }\n\n // 9. Show fix suggestions if requested\n if (showFix && !jsonOutput) {\n const fixes = generateFixSuggestions(results, config.baseUrl);\n if (fixes.length > 0) {\n console.log(chalk.bold(\" Suggested fixes:\\n\"));\n for (const fix of fixes) {\n console.log(fix);\n }\n }\n }\n\n // 10. Exit code\n if (minScore !== null) {\n // --min-score mode: fail only if score is below threshold\n if (summary.averageScore < minScore) {\n if (!jsonOutput) {\n console.log(\n chalk.red(` Score ${summary.averageScore} is below minimum ${minScore}.`),\n );\n }\n process.exit(1);\n }\n } else if (summary.criticalErrors > 0) {\n // Default mode: fail on any error\n process.exit(1);\n }\n });\n\n/** Match a route against a pattern with simple glob support.\n * Supports trailing /* for prefix matching (e.g., \"/dashboard/*\" matches \"/dashboard/settings\"). */\nfunction matchRoute(route: string, pattern: string): boolean {\n if (pattern.endsWith(\"/*\")) {\n const prefix = pattern.slice(0, -2);\n return route === prefix || route.startsWith(prefix + \"/\");\n }\n return route === pattern;\n}\n","import { readFile } from \"node:fs/promises\";\nimport { join, relative, dirname, sep } from \"node:path\";\nimport { glob } from \"glob\";\nimport type { ResolvedMetadata } from \"indxel\";\n\nexport interface PageInfo {\n /** File path relative to project root */\n filePath: string;\n /** Route path (e.g., \"/blog/[slug]\") */\n route: string;\n /** Whether the page exports metadata or generateMetadata */\n hasMetadata: boolean;\n /** Whether the page exports generateMetadata (dynamic) */\n hasDynamicMetadata: boolean;\n /** Whether the page is a client component ('use client') */\n isClientComponent: boolean;\n /** Whether the title uses absolute: (skip template) */\n titleIsAbsolute: boolean;\n /** Extracted static metadata fields (best effort from source parsing) */\n extractedMetadata: ResolvedMetadata;\n}\n\n/**\n * Scan the app directory for all page files and extract metadata info.\n * This does static analysis of the source code (no build required).\n */\nexport async function scanPages(\n projectRoot: string,\n appDir: string,\n): Promise<PageInfo[]> {\n const appDirFull = join(projectRoot, appDir);\n\n // Find all page.tsx/page.ts/page.jsx/page.js files\n const pageFiles = await glob(\"**/page.{tsx,ts,jsx,js}\", {\n cwd: appDirFull,\n ignore: [\"**/node_modules/**\", \"**/_*/**\"],\n });\n\n const pages: PageInfo[] = [];\n\n for (const file of pageFiles) {\n const fullPath = join(appDirFull, file);\n const content = await readFile(fullPath, \"utf-8\");\n const route = filePathToRoute(file);\n const isClient = isClientComponent(content);\n\n const page: PageInfo = {\n filePath: join(appDir, file),\n route,\n hasMetadata: false,\n hasDynamicMetadata: false,\n isClientComponent: isClient,\n titleIsAbsolute: false,\n extractedMetadata: createEmptyMetadata(),\n };\n\n // Check for metadata exports\n page.hasDynamicMetadata = hasExport(content, \"generateMetadata\");\n page.hasMetadata = page.hasDynamicMetadata || hasExport(content, \"metadata\");\n\n // Extract static metadata (best effort)\n if (page.hasDynamicMetadata) {\n // generateMetadata() pages can't be analyzed statically — regex can't\n // parse function bodies. Leave metadata empty; `indxel crawl` handles these.\n } else if (!isClient || page.hasMetadata) {\n // Skip extraction for client components without metadata export —\n // regex would match JSX content instead of actual metadata\n page.extractedMetadata = extractStaticMetadata(content);\n // Check if the title was from absolute: (no template should be applied)\n const metaBlock = findMetadataBlock(content);\n if (metaBlock && /absolute\\s*:\\s*[\"'`]/.test(metaBlock)) {\n page.titleIsAbsolute = true;\n }\n }\n\n pages.push(page);\n }\n\n // Also check layout files for metadata\n const layoutFiles = await glob(\"**/layout.{tsx,ts,jsx,js}\", {\n cwd: appDirFull,\n ignore: [\"**/node_modules/**\", \"**/_*/**\"],\n });\n\n // Sort layouts by depth descending — deeper layouts get merge priority,\n // root layout fills remaining gaps last\n const sortedLayouts = layoutFiles.sort((a, b) => {\n const depthA = a.split(sep).length;\n const depthB = b.split(sep).length;\n return depthB - depthA;\n });\n\n for (const file of sortedLayouts) {\n const fullPath = join(appDirFull, file);\n const content = await readFile(fullPath, \"utf-8\");\n const route = filePathToRoute(file).replace(/\\/layout$/, \"\") || \"/\";\n\n const hasMetadataExport = hasExport(content, \"metadata\") || hasExport(content, \"generateMetadata\");\n if (hasMetadataExport) {\n const layoutMeta = extractStaticMetadata(content);\n\n // Extract title template from layout for title resolution\n const templateMatch = content.match(/template\\s*:\\s*[\"'`]([^\"'`]+)[\"'`]/);\n const titleTemplate = templateMatch?.[1] ?? null;\n\n for (const page of pages) {\n if (page.route.startsWith(route) || route === \"/\") {\n // If the page has its own title (not absolute) and layout has a template, resolve it\n if (page.extractedMetadata.title && titleTemplate && !page.titleIsAbsolute) {\n page.extractedMetadata.title = titleTemplate.replace(\"%s\", page.extractedMetadata.title);\n page.titleIsAbsolute = true; // prevent double-templating from parent layouts\n }\n\n // Merge layout metadata as fallback (page-level takes precedence)\n mergeMetadata(page.extractedMetadata, layoutMeta);\n if (!page.hasMetadata) {\n page.hasMetadata = true;\n }\n }\n }\n }\n }\n\n return pages.sort((a, b) => a.route.localeCompare(b.route));\n}\n\n/** Convert a file path like \"blog/[slug]/page.tsx\" to route \"/blog/[slug]\" */\nfunction filePathToRoute(filePath: string): string {\n const dir = dirname(filePath);\n if (dir === \".\") return \"/\";\n // Normalize separators and add leading slash\n const route = \"/\" + dir.split(sep).join(\"/\");\n // Remove route groups like (marketing)\n return route.replace(/\\/\\([^)]+\\)/g, \"\") || \"/\";\n}\n\n/** Check if the source starts with 'use client' directive */\nfunction isClientComponent(source: string): boolean {\n // Match 'use client' or \"use client\" at the start of the file (ignoring whitespace/comments)\n return /^[\\s]*(['\"])use client\\1/.test(source);\n}\n\n/** Check if source code exports a given name */\nfunction hasExport(source: string, name: string): boolean {\n // Match: export const metadata, export async function generateMetadata, export function generateMetadata\n const patterns = [\n new RegExp(`export\\\\s+(const|let|var)\\\\s+${name}\\\\b`),\n new RegExp(`export\\\\s+(async\\\\s+)?function\\\\s+${name}\\\\b`),\n new RegExp(`export\\\\s+\\\\{[^}]*\\\\b${name}\\\\b[^}]*\\\\}`),\n ];\n return patterns.some((p) => p.test(source));\n}\n\n/**\n * Find the metadata export block in source code using brace-matching.\n * Returns the block content or null if not found.\n */\nfunction findMetadataBlock(source: string): string | null {\n const match = source.match(/export\\s+(const|let|var)\\s+metadata[\\s:]/);\n if (!match || match.index === undefined) return null;\n\n const start = source.indexOf(\"{\", match.index);\n if (start === -1) return null;\n\n let depth = 0;\n for (let i = start; i < source.length; i++) {\n if (source[i] === \"{\") depth++;\n else if (source[i] === \"}\") {\n depth--;\n if (depth === 0) return source.substring(start, i + 1);\n }\n }\n return null;\n}\n\n/**\n * Extract metadata from static `export const metadata = { ... }` patterns.\n * This is best-effort source code parsing (not AST — fast and simple).\n */\nfunction extractStaticMetadata(source: string): ResolvedMetadata {\n const meta = createEmptyMetadata();\n\n // Scope extraction to the metadata export block when possible\n // This prevents matching JSX content or unrelated objects\n const metaBlock = findMetadataBlock(source) ?? source;\n\n // Extract title — handle multiple patterns:\n // 1. title: \"simple string\"\n // 2. title: { absolute: \"...\" }\n // 3. title: { default: \"...\" }\n const absoluteMatch = metaBlock.match(\n /absolute\\s*:\\s*[\"'`]([^\"'`]+)[\"'`]/,\n );\n if (absoluteMatch) {\n meta.title = absoluteMatch[1];\n } else {\n const defaultMatch = metaBlock.match(\n /default\\s*:\\s*[\"'`]([^\"'`]+)[\"'`]/,\n );\n if (defaultMatch) {\n meta.title = defaultMatch[1];\n } else {\n // Simple title: \"string\" — but only match top-level title, not nested ones\n const titleMatch = metaBlock.match(\n /(?:^|[,{\\n])\\s*title\\s*:\\s*[\"'`]([^\"'`]+)[\"'`]/,\n );\n if (titleMatch) {\n meta.title = titleMatch[1];\n }\n }\n }\n\n // Extract description — scope to metadata block\n const descMatch = metaBlock.match(\n /(?:^|[,{\\n])\\s*description\\s*:\\s*\\n?\\s*[\"'`]([^\"'`]+)[\"'`]/,\n );\n if (descMatch) {\n meta.description = descMatch[1];\n }\n\n // Check for openGraph object (scoped to metadata block)\n if (/openGraph\\s*:\\s*\\{/.test(metaBlock)) {\n const ogTitleMatch = metaBlock.match(\n /openGraph\\s*:\\s*\\{[^}]*title\\s*:\\s*[\"'`]([^\"'`]+)[\"'`]/s,\n );\n if (ogTitleMatch) meta.ogTitle = ogTitleMatch[1];\n\n const ogDescMatch = metaBlock.match(\n /openGraph\\s*:\\s*\\{[^}]*description\\s*:\\s*[\"'`]([^\"'`]+)[\"'`]/s,\n );\n if (ogDescMatch) meta.ogDescription = ogDescMatch[1];\n\n if (/images\\s*:\\s*\\[/.test(metaBlock)) {\n meta.ogImage = \"[detected]\";\n }\n }\n\n // Check for twitter config (scoped to metadata block)\n if (/twitter\\s*:\\s*\\{/.test(metaBlock)) {\n const cardMatch = metaBlock.match(\n /card\\s*:\\s*[\"'`](summary|summary_large_image)[\"'`]/,\n );\n if (cardMatch) meta.twitterCard = cardMatch[1];\n }\n\n // Check for robots (scoped to metadata block)\n if (/robots\\s*:\\s*\\{/.test(metaBlock) || /robots\\s*:\\s*[\"'`]/.test(metaBlock)) {\n const robotsMatch = metaBlock.match(\n /robots\\s*:\\s*[\"'`]([^\"'`]+)[\"'`]/,\n );\n if (robotsMatch) meta.robots = robotsMatch[1];\n }\n\n // Check for alternates/canonical (scoped to metadata block)\n if (/alternates\\s*:\\s*\\{/.test(metaBlock)) {\n const canonicalMatch = metaBlock.match(\n /canonical\\s*:\\s*[\"'`]([^\"'`]+)[\"'`]/,\n );\n if (canonicalMatch) meta.canonical = canonicalMatch[1];\n\n // Detect hreflang / languages declarations\n if (/languages\\s*:\\s*\\{/.test(metaBlock)) {\n const langs: Record<string, string> = {};\n const langMatches = metaBlock.matchAll(\n /[\"'`](\\w{2}(?:-\\w{2})?)[\"'`]\\s*:\\s*[\"'`]([^\"'`]+)[\"'`]/g,\n );\n for (const m of langMatches) {\n if (m[1] && m[2] && m[2].startsWith(\"http\")) {\n langs[m[1]] = m[2];\n }\n }\n if (Object.keys(langs).length > 0) {\n meta.alternates = langs;\n }\n }\n }\n\n // Check for structured data — search full source (JSON-LD can be in JSX, not metadata)\n if (/application\\/ld\\+json/.test(source) || /generateLD/.test(source) || /JsonLD/.test(source)) {\n meta.structuredData = [{ \"@context\": \"https://schema.org\", \"@type\": \"detected\" }];\n }\n\n // Check for viewport — search full source (can be a separate export)\n if (/viewport\\s*[:=]/.test(source)) {\n meta.viewport = \"detected\";\n }\n\n // Check for icons/favicon (scoped to metadata block)\n if (/icons\\s*:\\s*\\{/.test(metaBlock) || /favicon/.test(metaBlock)) {\n meta.favicon = \"detected\";\n }\n\n return meta;\n}\n\nfunction createEmptyMetadata(): ResolvedMetadata {\n return {\n title: null,\n description: null,\n canonical: null,\n ogTitle: null,\n ogDescription: null,\n ogImage: null,\n ogType: null,\n twitterCard: null,\n twitterTitle: null,\n twitterDescription: null,\n robots: null,\n alternates: null,\n structuredData: null,\n viewport: null,\n favicon: null,\n };\n}\n\n/** Merge source metadata into target (target takes precedence if already set) */\nfunction mergeMetadata(target: ResolvedMetadata, source: ResolvedMetadata): void {\n for (const key of Object.keys(source) as (keyof ResolvedMetadata)[]) {\n if (target[key] === null || target[key] === undefined) {\n (target as Record<string, unknown>)[key] = source[key];\n }\n }\n}\n","import { existsSync } from \"node:fs\";\nimport { readFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n\nexport interface IndxelConfig {\n /** Minimum score to pass (0-100). Overrides --min-score flag. */\n minScore?: number;\n /** Rule IDs to disable (won't count toward score). */\n disabledRules?: string[];\n /** Base URL for canonical URLs. */\n baseUrl?: string;\n /** Route patterns to exclude from checks (e.g., \"/dashboard/*\", \"/auth/*\"). */\n ignoreRoutes?: string[];\n}\n\nconst CONFIG_FILES = [\".indxelrc.json\", \".indxelrc\", \"indxel.config.json\"];\n\n/**\n * Load indxel config from the project root.\n * Searches for .indxelrc.json, .indxelrc, or indxel.config.json.\n */\nexport async function loadConfig(cwd: string): Promise<IndxelConfig> {\n for (const file of CONFIG_FILES) {\n const path = join(cwd, file);\n if (existsSync(path)) {\n try {\n const content = await readFile(path, \"utf-8\");\n return JSON.parse(content) as IndxelConfig;\n } catch {\n // Invalid JSON — ignore silently\n }\n }\n }\n return {};\n}\n","import chalk from \"chalk\";\nimport type { ValidationResult } from \"indxel\";\nimport type { PageInfo } from \"./scanner.js\";\n\nexport interface CheckResult {\n page: PageInfo;\n validation: ValidationResult;\n}\n\nexport interface CheckSummary {\n results: CheckResult[];\n totalPages: number;\n passedPages: number;\n averageScore: number;\n grade: string;\n /** Errors from critical-severity rules (blocks CI) */\n criticalErrors: number;\n /** Errors from optional-severity rules (score only) */\n optionalErrors: number;\n /** Pages with generateMetadata() skipped from static analysis */\n skippedDynamic: number;\n}\n\n/** Format a single page check result for terminal output */\nexport function formatPageResult(result: CheckResult): string {\n const { page, validation } = result;\n const lines: string[] = [];\n\n const scoreColor = getScoreColor(validation.score);\n const icon = validation.errors.length > 0 ? chalk.red(\"x\") : chalk.green(\"✓\");\n\n lines.push(\n ` ${icon} ${chalk.bold(page.route)} ${scoreColor(`${validation.score}/100`)}`,\n );\n\n // Show errors\n for (const error of validation.errors) {\n lines.push(` ${chalk.red(\"x\")} ${error.message ?? error.name}`);\n }\n\n // Show warnings (only if there are also errors, to reduce noise)\n if (validation.errors.length > 0) {\n for (const warning of validation.warnings) {\n lines.push(` ${chalk.yellow(\"!\")} ${warning.message ?? warning.name}`);\n }\n }\n\n return lines.join(\"\\n\");\n}\n\n/** Format the complete check summary for terminal output */\nexport function formatSummary(summary: CheckSummary): string {\n const lines: string[] = [];\n const { totalPages, passedPages, averageScore, criticalErrors } = summary;\n\n lines.push(\"\");\n lines.push(chalk.dim(\" ─────────────────────────────────────\"));\n lines.push(\"\");\n\n // Overall score\n const scoreColor = getScoreColor(averageScore);\n lines.push(\n ` Score: ${scoreColor(chalk.bold(`${averageScore}/100`))} (${summary.grade})`,\n );\n\n // Pages summary\n const pagesColor = passedPages === totalPages ? chalk.green : chalk.yellow;\n lines.push(\n ` Pages: ${pagesColor(`${passedPages}/${totalPages}`)} pass SEO validation`,\n );\n\n // Error count\n if (criticalErrors > 0) {\n lines.push(\"\");\n lines.push(\n chalk.red(` ${criticalErrors} critical issue${criticalErrors > 1 ? \"s\" : \"\"}. Fix before deploying.`),\n );\n if (summary.optionalErrors > 0) {\n lines.push(\n chalk.yellow(` ${summary.optionalErrors} optional issue${summary.optionalErrors > 1 ? \"s\" : \"\"} (won't block CI).`),\n );\n }\n } else if (summary.optionalErrors > 0) {\n lines.push(\"\");\n lines.push(chalk.yellow(` ${summary.optionalErrors} optional issue${summary.optionalErrors > 1 ? \"s\" : \"\"} (won't block CI).`));\n } else {\n lines.push(\"\");\n lines.push(chalk.green(\" All pages pass. Ship it.\"));\n }\n\n // Dynamic pages hint\n if (summary.skippedDynamic > 0) {\n lines.push(\"\");\n lines.push(\n chalk.cyan(\n ` ${summary.skippedDynamic} dynamic page${summary.skippedDynamic > 1 ? \"s\" : \"\"} skipped (generateMetadata).`,\n ),\n );\n lines.push(chalk.dim(\" Run `indxel crawl <url>` for accurate scores on dynamic pages.\"));\n }\n\n lines.push(\"\");\n return lines.join(\"\\n\");\n}\n\n/** Format results for --json output */\nexport function formatJSON(summary: CheckSummary): string {\n return JSON.stringify(\n {\n score: summary.averageScore,\n grade: summary.grade,\n totalPages: summary.totalPages,\n passedPages: summary.passedPages,\n criticalErrors: summary.criticalErrors,\n optionalErrors: summary.optionalErrors,\n skippedDynamic: summary.skippedDynamic,\n pages: summary.results.map((r) => ({\n route: r.page.route,\n file: r.page.filePath,\n score: r.validation.score,\n grade: r.validation.grade,\n errors: r.validation.errors.map((e) => ({\n id: e.id,\n message: e.message,\n })),\n warnings: r.validation.warnings.map((w) => ({\n id: w.id,\n message: w.message,\n })),\n })),\n },\n null,\n 2,\n );\n}\n\n/** Format a diff between two check runs */\nexport function formatDiff(\n current: CheckSummary,\n previous: CheckSummary,\n): string {\n const lines: string[] = [];\n\n lines.push(\"\");\n lines.push(chalk.bold(\" SEO Diff:\"));\n lines.push(\"\");\n\n const scoreDelta = current.averageScore - previous.averageScore;\n const scoreArrow = scoreDelta > 0 ? chalk.green(`+${scoreDelta}`) : scoreDelta < 0 ? chalk.red(`${scoreDelta}`) : chalk.dim(\"0\");\n lines.push(\n ` Score: ${previous.averageScore} -> ${current.averageScore} (${scoreArrow})`,\n );\n lines.push(\"\");\n\n // Build route maps\n const prevMap = new Map(previous.results.map((r) => [r.page.route, r]));\n const currMap = new Map(current.results.map((r) => [r.page.route, r]));\n\n // Regressions\n const regressions: string[] = [];\n for (const [route, curr] of currMap) {\n const prev = prevMap.get(route);\n if (!prev) continue;\n if (curr.validation.score < prev.validation.score) {\n regressions.push(\n ` ${chalk.red(\"-\")} ${route} ${prev.validation.score} -> ${curr.validation.score}`,\n );\n }\n }\n\n // Improvements\n const improvements: string[] = [];\n for (const [route, curr] of currMap) {\n const prev = prevMap.get(route);\n if (!prev) continue;\n if (curr.validation.score > prev.validation.score) {\n improvements.push(\n ` ${chalk.green(\"+\")} ${route} ${prev.validation.score} -> ${curr.validation.score}`,\n );\n }\n }\n\n // New pages\n const newPages: string[] = [];\n for (const route of currMap.keys()) {\n if (!prevMap.has(route)) {\n newPages.push(` ${chalk.blue(\"+\")} ${route} ${chalk.dim(\"[new]\")}`);\n }\n }\n\n // Removed pages\n const removed: string[] = [];\n for (const route of prevMap.keys()) {\n if (!currMap.has(route)) {\n removed.push(` ${chalk.dim(\"-\")} ${route} ${chalk.dim(\"[removed]\")}`);\n }\n }\n\n if (regressions.length > 0) {\n lines.push(chalk.red(` REGRESSIONS (${regressions.length}):`));\n lines.push(...regressions);\n lines.push(\"\");\n }\n\n if (improvements.length > 0) {\n lines.push(chalk.green(` IMPROVEMENTS (${improvements.length}):`));\n lines.push(...improvements);\n lines.push(\"\");\n }\n\n if (newPages.length > 0) {\n lines.push(chalk.blue(` NEW PAGES (${newPages.length}):`));\n lines.push(...newPages);\n lines.push(\"\");\n }\n\n if (removed.length > 0) {\n lines.push(chalk.dim(` REMOVED (${removed.length}):`));\n lines.push(...removed);\n lines.push(\"\");\n }\n\n if (regressions.length === 0 && improvements.length === 0 && newPages.length === 0 && removed.length === 0) {\n lines.push(chalk.dim(\" No changes detected.\"));\n lines.push(\"\");\n }\n\n return lines.join(\"\\n\");\n}\n\n/** Format a dynamic page that was skipped from static analysis */\nexport function formatSkippedPage(page: import(\"./scanner.js\").PageInfo): string {\n return ` ${chalk.cyan(\"~\")} ${chalk.bold(page.route)} ${chalk.dim(\"skipped — generateMetadata()\")}`;\n}\n\n/** Color a score value based on its range */\nfunction getScoreColor(score: number): (text: string) => string {\n if (score >= 90) return chalk.green;\n if (score >= 70) return chalk.yellow;\n return chalk.red;\n}\n\n/** Compute summary from results */\nexport function computeSummary(results: CheckResult[], skippedDynamic = 0): CheckSummary {\n const totalPages = results.length + skippedDynamic;\n const passedPages = results.filter((r) => r.validation.errors.length === 0).length;\n const averageScore =\n results.length > 0\n ? Math.round(results.reduce((sum, r) => sum + r.validation.score, 0) / results.length)\n : 0;\n\n let criticalErrors = 0;\n let optionalErrors = 0;\n for (const r of results) {\n for (const e of r.validation.errors) {\n if (e.severity === \"critical\") criticalErrors++;\n else optionalErrors++;\n }\n }\n\n let grade: string;\n if (averageScore >= 90) grade = \"A\";\n else if (averageScore >= 80) grade = \"B\";\n else if (averageScore >= 70) grade = \"C\";\n else if (averageScore >= 60) grade = \"D\";\n else grade = \"F\";\n\n return { results, totalPages, passedPages, averageScore, grade, criticalErrors, optionalErrors, skippedDynamic };\n}\n","import chalk from \"chalk\";\nimport type { CheckResult } from \"./formatter.js\";\n\n/**\n * Generate suggested metadata code snippets for pages with errors.\n * Returns an array of formatted strings ready for terminal output.\n */\nexport function generateFixSuggestions(\n results: CheckResult[],\n baseUrl?: string,\n): string[] {\n const output: string[] = [];\n const siteUrl = baseUrl ?? \"https://yoursite.com\";\n\n for (const { page, validation } of results) {\n if (validation.errors.length === 0 && validation.warnings.length === 0) continue;\n\n const errorIds = new Set(validation.errors.map((e) => e.id));\n const warnIds = new Set(validation.warnings.map((w) => w.id));\n const allIds = new Set([...errorIds, ...warnIds]);\n\n // Build a metadata object suggestion based on what's missing\n const meta: Record<string, unknown> = {};\n const extras: string[] = [];\n\n // Title\n if (allIds.has(\"title-present\")) {\n const suggestion = routeToTitle(page.route);\n meta.title = { absolute: suggestion };\n } else if (allIds.has(\"title-length\")) {\n const current = page.extractedMetadata.title ?? \"\";\n const len = current.length;\n if (len < 50) {\n extras.push(` ${chalk.dim(\"// Title is \" + len + \" chars — expand to 50-60\")}`);\n } else if (len > 60) {\n extras.push(` ${chalk.dim(\"// Title is \" + len + \" chars — shorten to 50-60\")}`);\n }\n }\n\n // Description\n if (allIds.has(\"description-present\")) {\n meta.description = routeToDescription(page.route);\n } else if (allIds.has(\"description-length\")) {\n const current = page.extractedMetadata.description ?? \"\";\n const len = current.length;\n if (len < 120) {\n extras.push(` ${chalk.dim(\"// Description is \" + len + \" chars — expand to 120-160\")}`);\n } else if (len > 160) {\n extras.push(` ${chalk.dim(\"// Description is \" + len + \" chars — shorten to 120-160\")}`);\n }\n }\n\n // Canonical\n if (allIds.has(\"canonical-url\")) {\n const canonical = `${siteUrl}${page.route === \"/\" ? \"\" : page.route}`;\n meta.alternates = { canonical };\n }\n\n // OG Image\n if (allIds.has(\"og-image\")) {\n meta.openGraph = { images: [`${siteUrl}/og-image.png`] };\n }\n\n // Structured data\n if (allIds.has(\"structured-data-present\")) {\n extras.push(` ${chalk.dim(\"// Add JSON-LD structured data (WebPage, Article, FAQ...)\")}`);\n extras.push(` ${chalk.dim(\"// See: https://developers.google.com/search/docs/appearance/structured-data\")}`);\n }\n\n // Twitter\n if (allIds.has(\"twitter-card\")) {\n meta.twitter = { card: \"summary_large_image\" };\n }\n\n // Skip pages with no actionable suggestions\n if (Object.keys(meta).length === 0 && extras.length === 0) continue;\n\n output.push(chalk.bold(` ${chalk.cyan(page.filePath)}`));\n\n if (Object.keys(meta).length > 0) {\n const code = formatMetadataObject(meta);\n output.push(` ${chalk.dim(\"Add/update in your page file:\")}`);\n output.push(\"\");\n for (const line of code.split(\"\\n\")) {\n output.push(` ${chalk.yellow(line)}`);\n }\n }\n\n for (const extra of extras) {\n output.push(extra);\n }\n\n output.push(\"\");\n }\n\n return output;\n}\n\n/** Generate a reasonable title suggestion from a route */\nfunction routeToTitle(route: string): string {\n if (route === \"/\") return \"Your Site — A brief description of what you do\";\n const segments = route.split(\"/\").filter(Boolean);\n const last = segments[segments.length - 1];\n const name = last\n .replace(/\\[.*?\\]/g, \"\")\n .replace(/-/g, \" \")\n .replace(/\\b\\w/g, (c) => c.toUpperCase())\n .trim();\n return `${name || \"Page\"} — Your Site`;\n}\n\n/** Generate a reasonable description suggestion from a route */\nfunction routeToDescription(route: string): string {\n if (route === \"/\") {\n return \"A clear, compelling description of your site in 120-160 characters. Include your main value proposition and a call to action.\";\n }\n const segments = route.split(\"/\").filter(Boolean);\n const last = segments[segments.length - 1];\n const name = last\n .replace(/\\[.*?\\]/g, \"\")\n .replace(/-/g, \" \")\n .trim();\n return `Learn more about ${name || \"this page\"}. Add a compelling 120-160 character description with your key value proposition here.`;\n}\n\n/** Format a metadata object as TypeScript code */\nfunction formatMetadataObject(meta: Record<string, unknown>): string {\n const lines: string[] = [\"export const metadata: Metadata = {\"];\n\n for (const [key, value] of Object.entries(meta)) {\n if (typeof value === \"string\") {\n lines.push(` ${key}: \"${value}\",`);\n } else if (typeof value === \"object\" && value !== null) {\n lines.push(` ${key}: ${JSON.stringify(value, null, 2).replace(/\\n/g, \"\\n \")},`);\n }\n }\n\n lines.push(\"};\");\n return lines.join(\"\\n\");\n}\n","import { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport ora from \"ora\";\nimport {\n crawlSite,\n fetchSitemap,\n compareSitemap,\n fetchRobots,\n checkUrlsAgainstRobots,\n verifyAssets,\n} from \"indxel\";\nimport type { CrawledPage } from \"indxel\";\nimport { resolveApiKey } from \"../store.js\";\n\nfunction scoreColor(score: number): typeof chalk {\n if (score >= 90) return chalk.green;\n if (score >= 70) return chalk.yellow;\n return chalk.red;\n}\n\nexport const crawlCommand = new Command(\"crawl\")\n .description(\"Crawl a live site, audit every page, check sitemap, robots.txt, and assets\")\n .argument(\"<url>\", \"URL to start crawling (e.g., https://yoursite.com)\")\n .option(\"--max-pages <n>\", \"Maximum pages to crawl\", \"200\")\n .option(\"--max-depth <n>\", \"Maximum link depth\", \"5\")\n .option(\"--delay <ms>\", \"Delay between requests in ms\", \"200\")\n .option(\"--json\", \"Output results as JSON\", false)\n .option(\"--strict\", \"Treat warnings as errors\", false)\n .option(\"--skip-assets\", \"Skip asset verification\", false)\n .option(\"--skip-sitemap\", \"Skip sitemap check\", false)\n .option(\"--skip-robots\", \"Skip robots.txt check\", false)\n .option(\"--ignore <patterns>\", \"Comma-separated path patterns to exclude from analysis (e.g. /app/*,/admin/*)\")\n .option(\"--push\", \"Push results to Indxel dashboard\", false)\n .option(\"--api-key <key>\", \"API key for --push (or set INDXEL_API_KEY env var)\")\n .action(async (url: string, opts) => {\n const jsonOutput = opts.json;\n const maxPages = parseInt(opts.maxPages, 10);\n const maxDepth = parseInt(opts.maxDepth, 10);\n const delay = parseInt(opts.delay, 10);\n\n // Ensure URL has protocol\n if (!url.startsWith(\"http://\") && !url.startsWith(\"https://\")) {\n url = `https://${url}`;\n }\n\n if (!jsonOutput) {\n console.log(\"\");\n console.log(chalk.bold(` indxel crawl`) + chalk.dim(` — ${url}`));\n console.log(\"\");\n }\n\n // 1. Robots.txt\n let robotsResult = null;\n if (!opts.skipRobots) {\n const robotsSpinner = jsonOutput ? null : ora(\"Checking robots.txt...\").start();\n robotsResult = await fetchRobots(url);\n\n if (!jsonOutput) {\n if (robotsResult.found) {\n robotsSpinner!.succeed(\"robots.txt found\");\n for (const w of robotsResult.warnings) {\n console.log(chalk.yellow(` ⚠ ${w}`));\n }\n if (robotsResult.sitemapUrls.length > 0) {\n console.log(chalk.dim(` Sitemap references: ${robotsResult.sitemapUrls.join(\", \")}`));\n }\n } else {\n robotsSpinner!.warn(\"robots.txt not found\");\n for (const e of robotsResult.errors) {\n console.log(chalk.dim(` ${e}`));\n }\n }\n console.log(\"\");\n }\n }\n\n // 2. Crawl\n const crawlSpinner = jsonOutput ? null : ora(\"Crawling...\").start();\n let crawledCount = 0;\n\n // Parse ignore patterns\n const ignorePatterns: string[] = opts.ignore\n ? opts.ignore.split(\",\").map((p: string) => p.trim()).filter(Boolean)\n : [];\n\n const crawlResult = await crawlSite(url, {\n maxPages,\n maxDepth,\n delay,\n strict: opts.strict,\n ignorePatterns,\n onPageCrawled: (page: CrawledPage) => {\n crawledCount++;\n if (crawlSpinner) {\n crawlSpinner.text = `Crawling... ${crawledCount} pages (current: ${page.url})`;\n }\n },\n });\n\n if (!jsonOutput) {\n crawlSpinner!.succeed(`Crawled ${crawlResult.totalPages} pages in ${(crawlResult.durationMs / 1000).toFixed(1)}s`);\n console.log(\"\");\n\n // Page results\n for (const page of crawlResult.pages) {\n if (page.error) {\n console.log(chalk.red(` ✗ ${page.url}`) + chalk.dim(` — ${page.error}`));\n continue;\n }\n\n const pageColor = scoreColor(page.validation.score);\n const icon =\n page.validation.errors.length > 0 ? chalk.red(\"✗\") : chalk.green(\"✓\");\n\n console.log(\n ` ${icon} ${page.url} ${pageColor(`${page.validation.score}/100`)}`,\n );\n\n for (const error of page.validation.errors) {\n console.log(chalk.red(` ✗ ${error.message ?? error.description}`));\n }\n for (const warning of page.validation.warnings) {\n console.log(chalk.yellow(` ⚠ ${warning.message ?? warning.description}`));\n }\n }\n\n console.log(\"\");\n }\n\n // 3. Sitemap check\n let sitemapComparison = null;\n if (!opts.skipSitemap) {\n const sitemapSpinner = jsonOutput ? null : ora(\"Checking sitemap.xml...\").start();\n const sitemapResult = await fetchSitemap(url);\n\n if (!jsonOutput) {\n if (sitemapResult.found) {\n sitemapSpinner!.succeed(`sitemap.xml found — ${sitemapResult.urls.length} URLs`);\n\n // Compare with crawled pages\n const crawledUrls = crawlResult.pages\n .filter((p) => !p.error)\n .map((p) => p.url);\n sitemapComparison = compareSitemap(\n sitemapResult.urls.map((u) => u.loc),\n crawledUrls,\n );\n\n if (sitemapComparison.inCrawlOnly.length > 0) {\n console.log(chalk.yellow(` ⚠ ${sitemapComparison.inCrawlOnly.length} crawled pages missing from sitemap:`));\n for (const u of sitemapComparison.inCrawlOnly.slice(0, 10)) {\n console.log(chalk.dim(` - ${u}`));\n }\n }\n if (sitemapComparison.inSitemapOnly.length > 0) {\n const hitLimit = crawlResult.totalPages >= maxPages;\n const label = hitLimit\n ? `${sitemapComparison.inSitemapOnly.length} sitemap URLs not crawled (limit: ${maxPages} — use --max-pages to increase)`\n : `${sitemapComparison.inSitemapOnly.length} sitemap URLs not reachable`;\n console.log(chalk.yellow(` ⚠ ${label}:`));\n for (const u of sitemapComparison.inSitemapOnly.slice(0, 10)) {\n console.log(chalk.dim(` - ${u}`));\n }\n }\n if (sitemapComparison.issues.length === 0) {\n console.log(chalk.green(` ✓ Sitemap matches crawled pages`));\n }\n } else {\n sitemapSpinner!.warn(\"sitemap.xml not found\");\n for (const e of sitemapResult.errors) {\n console.log(chalk.dim(` ${e}`));\n }\n }\n console.log(\"\");\n }\n }\n\n // 4. Robots.txt URL check\n let robotsBlockedPages = null;\n if (robotsResult?.found && robotsResult.directives.length > 0) {\n const crawledUrls = crawlResult.pages.filter((p) => !p.error).map((p) => p.url);\n robotsBlockedPages = checkUrlsAgainstRobots(\n robotsResult.directives,\n crawledUrls,\n );\n const blocked = robotsBlockedPages.filter((c) => c.blocked);\n\n if (!jsonOutput && blocked.length > 0) {\n console.log(chalk.yellow(` ⚠ ${blocked.length} crawled pages are blocked by robots.txt:`));\n for (const b of blocked) {\n console.log(chalk.dim(` - ${b.path} (${b.blockedBy})`));\n }\n console.log(\"\");\n }\n }\n\n // 5. Asset verification\n let assetResult = null;\n if (!opts.skipAssets) {\n const assetSpinner = jsonOutput ? null : ora(\"Verifying assets (og:image, favicon, ...)...\").start();\n\n const pagesForAssetCheck = crawlResult.pages\n .filter((p) => !p.error)\n .map((p) => ({ url: p.url, metadata: p.metadata }));\n assetResult = await verifyAssets(pagesForAssetCheck);\n\n if (!jsonOutput) {\n assetSpinner!.succeed(`Verified ${assetResult.totalChecked} assets`);\n\n const brokenAssets = assetResult.checks.filter((c) => !c.ok);\n const warningAssets = assetResult.checks.filter((c) => c.warning);\n\n for (const asset of brokenAssets) {\n console.log(\n chalk.red(` ✗ ${asset.type}`) +\n chalk.dim(` ${asset.url}`) +\n chalk.red(` — ${asset.error ?? `HTTP ${asset.status}`}`),\n );\n }\n for (const asset of warningAssets) {\n console.log(\n chalk.yellow(` ⚠ ${asset.type}`) +\n chalk.dim(` ${asset.url}`) +\n chalk.yellow(` — ${asset.warning}`),\n );\n }\n if (brokenAssets.length === 0 && warningAssets.length === 0) {\n console.log(chalk.green(` ✓ All assets respond correctly`));\n }\n console.log(\"\");\n }\n }\n\n // 6. Cross-page analysis\n if (!jsonOutput) {\n const a = crawlResult.analysis;\n\n // Duplicate titles\n if (a.duplicateTitles.length > 0) {\n console.log(chalk.bold(\"- Duplicate titles\"));\n for (const dup of a.duplicateTitles.slice(0, 5)) {\n console.log(chalk.red(` ✗ \"${dup.title.length > 60 ? dup.title.slice(0, 57) + \"...\" : dup.title}\"`) + chalk.dim(` (${dup.urls.length} pages)`));\n for (const u of dup.urls.slice(0, 3)) console.log(chalk.dim(` ${u}`));\n if (dup.urls.length > 3) console.log(chalk.dim(` ...and ${dup.urls.length - 3} more`));\n }\n if (a.duplicateTitles.length > 5) console.log(chalk.dim(` ...and ${a.duplicateTitles.length - 5} more groups`));\n console.log(\"\");\n }\n\n // Duplicate descriptions\n if (a.duplicateDescriptions.length > 0) {\n console.log(chalk.bold(\"- Duplicate descriptions\"));\n for (const dup of a.duplicateDescriptions.slice(0, 5)) {\n const desc = dup.description.length > 60 ? dup.description.slice(0, 57) + \"...\" : dup.description;\n console.log(chalk.red(` ✗ \"${desc}\"`) + chalk.dim(` (${dup.urls.length} pages)`));\n for (const u of dup.urls.slice(0, 3)) console.log(chalk.dim(` ${u}`));\n if (dup.urls.length > 3) console.log(chalk.dim(` ...and ${dup.urls.length - 3} more`));\n }\n if (a.duplicateDescriptions.length > 5) console.log(chalk.dim(` ...and ${a.duplicateDescriptions.length - 5} more groups`));\n console.log(\"\");\n }\n\n // H1 issues\n if (a.h1Issues.length > 0) {\n const missing = a.h1Issues.filter(h => h.issue === \"missing\");\n const multiple = a.h1Issues.filter(h => h.issue === \"multiple\");\n console.log(chalk.bold(\"- H1 heading issues\"));\n if (missing.length > 0) {\n console.log(chalk.red(` ✗ ${missing.length} pages missing H1`));\n for (const h of missing.slice(0, 5)) console.log(chalk.dim(` ${h.url}`));\n if (missing.length > 5) console.log(chalk.dim(` ...and ${missing.length - 5} more`));\n }\n if (multiple.length > 0) {\n console.log(chalk.yellow(` ⚠ ${multiple.length} pages with multiple H1s`));\n for (const h of multiple.slice(0, 5)) console.log(chalk.dim(` ${h.url} (${h.count} H1s)`));\n if (multiple.length > 5) console.log(chalk.dim(` ...and ${multiple.length - 5} more`));\n }\n console.log(\"\");\n }\n\n // Broken internal links\n if (a.brokenInternalLinks.length > 0) {\n console.log(chalk.bold(\"- Broken internal links\"));\n for (const bl of a.brokenInternalLinks.slice(0, 10)) {\n console.log(chalk.red(` ✗ ${bl.to}`) + chalk.dim(` ← linked from ${bl.from} (${bl.status})`));\n }\n if (a.brokenInternalLinks.length > 10) console.log(chalk.dim(` ...and ${a.brokenInternalLinks.length - 10} more`));\n console.log(\"\");\n }\n\n // Broken external links\n if (a.brokenExternalLinks.length > 0) {\n console.log(chalk.bold(\"- Broken external links\"));\n for (const bl of a.brokenExternalLinks.slice(0, 10)) {\n console.log(chalk.red(` ✗ ${bl.to}`) + chalk.dim(` ← linked from ${bl.from} (${bl.status})`));\n }\n if (a.brokenExternalLinks.length > 10) console.log(chalk.dim(` ...and ${a.brokenExternalLinks.length - 10} more`));\n console.log(\"\");\n }\n\n // Redirects\n if (a.redirects.length > 0) {\n console.log(chalk.bold(\"- Redirect chains\"));\n for (const r of a.redirects.slice(0, 10)) {\n console.log(chalk.yellow(` ⚠ ${r.url}`));\n for (const step of r.chain) console.log(chalk.dim(` ${step}`));\n }\n if (a.redirects.length > 10) console.log(chalk.dim(` ...and ${a.redirects.length - 10} more`));\n console.log(\"\");\n }\n\n // Thin content\n if (a.thinContentPages.length > 0) {\n const realThin = a.thinContentPages.filter(tc => !tc.isAppPage);\n const appThin = a.thinContentPages.filter(tc => tc.isAppPage);\n\n if (realThin.length > 0) {\n console.log(chalk.bold(\"- Thin content\") + chalk.dim(\" (< 200 words)\"));\n for (const tc of realThin.slice(0, 10)) {\n console.log(chalk.yellow(` ⚠ ${tc.url}`) + chalk.dim(` — ${tc.wordCount} words`));\n }\n if (realThin.length > 10) console.log(chalk.dim(` ...and ${realThin.length - 10} more`));\n console.log(\"\");\n }\n if (appThin.length > 0) {\n console.log(chalk.bold(\"- App/wizard pages\") + chalk.dim(\" (client-rendered, low word count expected)\"));\n for (const tc of appThin.slice(0, 5)) {\n console.log(chalk.dim(` ℹ ${tc.url} — ${tc.wordCount} words`));\n }\n if (appThin.length > 5) console.log(chalk.dim(` ...and ${appThin.length - 5} more`));\n console.log(\"\");\n }\n }\n\n // Orphan pages\n if (a.orphanPages.length > 0) {\n console.log(chalk.bold(\"- Orphan pages\") + chalk.dim(\" (0 internal links pointing to them)\"));\n for (const o of a.orphanPages.slice(0, 10)) console.log(chalk.yellow(` ⚠ ${o}`));\n if (a.orphanPages.length > 10) console.log(chalk.dim(` ...and ${a.orphanPages.length - 10} more`));\n console.log(\"\");\n }\n\n // Slowest pages\n if (a.slowestPages.length > 0 && a.slowestPages[0].responseTimeMs > 1000) {\n console.log(chalk.bold(\"- Slowest pages\"));\n for (const sp of a.slowestPages.filter(p => p.responseTimeMs > 1000).slice(0, 5)) {\n const color = sp.responseTimeMs > 3000 ? chalk.red : chalk.yellow;\n console.log(color(` ⚠ ${sp.url}`) + chalk.dim(` — ${(sp.responseTimeMs / 1000).toFixed(1)}s`));\n }\n console.log(\"\");\n }\n\n // Structured data summary\n if (a.structuredDataSummary.length > 0) {\n console.log(chalk.bold(\"- Structured data (JSON-LD)\"));\n for (const sd of a.structuredDataSummary) {\n console.log(chalk.green(` ✓ ${sd.type}`) + chalk.dim(` — ${sd.count} page${sd.count > 1 ? \"s\" : \"\"}`));\n }\n const pagesWithSD = crawlResult.pages.filter(p => !p.error && p.structuredDataTypes.length > 0).length;\n const pagesWithout = crawlResult.pages.filter(p => !p.error).length - pagesWithSD;\n if (pagesWithout > 0) {\n console.log(chalk.yellow(` ⚠ ${pagesWithout} pages without any structured data`));\n }\n console.log(\"\");\n } else {\n console.log(chalk.bold(\"- Structured data (JSON-LD)\"));\n console.log(chalk.red(` ✗ No structured data found on any page`));\n console.log(\"\");\n }\n\n // Image alt text issues\n if (a.imageAltIssues.length > 0) {\n console.log(chalk.bold(\"- Image alt text\"));\n for (const img of a.imageAltIssues.slice(0, 10)) {\n const color = img.missingAlt / img.total >= 0.5 ? chalk.red : chalk.yellow;\n const icon = img.missingAlt / img.total >= 0.5 ? \"✗\" : \"⚠\";\n console.log(color(` ${icon} ${img.url}`) + chalk.dim(` — ${img.missingAlt}/${img.total} images missing alt`));\n }\n if (a.imageAltIssues.length > 10) console.log(chalk.dim(` ...and ${a.imageAltIssues.length - 10} more`));\n console.log(\"\");\n }\n\n // Broken images\n if (a.brokenImages.length > 0) {\n console.log(chalk.bold(\"- Broken images\"));\n for (const img of a.brokenImages.slice(0, 10)) {\n const src = img.src.length > 80 ? img.src.slice(0, 77) + \"...\" : img.src;\n console.log(chalk.red(` ✗ ${src}`) + chalk.dim(` (${img.status}) — on ${img.pages.length} page${img.pages.length > 1 ? \"s\" : \"\"}`));\n for (const page of img.pages.slice(0, 3)) console.log(chalk.dim(` ${page}`));\n if (img.pages.length > 3) console.log(chalk.dim(` ...and ${img.pages.length - 3} more`));\n }\n if (a.brokenImages.length > 10) console.log(chalk.dim(` ...and ${a.brokenImages.length - 10} more`));\n console.log(\"\");\n }\n }\n\n // 7. Summary\n if (jsonOutput) {\n console.log(\n JSON.stringify(\n {\n crawl: crawlResult,\n robots: robotsResult,\n sitemap: sitemapComparison,\n assets: assetResult,\n },\n null,\n 2,\n ),\n );\n } else {\n const summaryColor = scoreColor(crawlResult.averageScore);\n\n console.log(chalk.bold(\" ─── Summary ───\"));\n console.log(\"\");\n const hitLimit = crawlResult.totalPages >= maxPages;\n console.log(` Pages crawled: ${chalk.bold(String(crawlResult.totalPages))}${hitLimit ? chalk.dim(` (limit: ${maxPages} — use --max-pages to crawl more)`) : \"\"}`);\n console.log(` Average score: ${summaryColor(chalk.bold(`${crawlResult.averageScore}/100`))} (${crawlResult.grade})`);\n console.log(` Errors: ${crawlResult.totalErrors > 0 ? chalk.red(String(crawlResult.totalErrors)) : chalk.green(\"0\")}`);\n console.log(` Warnings: ${crawlResult.totalWarnings > 0 ? chalk.yellow(String(crawlResult.totalWarnings)) : chalk.green(\"0\")}`);\n if (assetResult) {\n console.log(` Broken assets: ${assetResult.totalBroken > 0 ? chalk.red(String(assetResult.totalBroken)) : chalk.green(\"0\")}`);\n }\n if (crawlResult.skippedUrls.length > 0) {\n console.log(chalk.dim(` Skipped: ${crawlResult.skippedUrls.length} URLs (over limit)`));\n }\n console.log(\"\");\n }\n\n // 8. Push to dashboard\n if (opts.push) {\n const apiKey = await resolveApiKey(opts.apiKey);\n if (!apiKey) {\n if (!jsonOutput) {\n console.log(chalk.yellow(\" ⚠\") + \" To push results to your dashboard, link your project first:\");\n console.log(\"\");\n console.log(chalk.bold(\" npx indxel link\"));\n console.log(\"\");\n console.log(chalk.dim(\" Or use --api-key / set INDXEL_API_KEY.\"));\n console.log(\"\");\n }\n } else {\n const pushSpinner = jsonOutput ? null : ora(\"Pushing results to Indxel...\").start();\n try {\n const pushUrl = process.env.INDXEL_API_URL || \"https://indxel.com\";\n const res = await fetch(`${pushUrl}/api/cli/push`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${apiKey}`,\n },\n body: JSON.stringify({\n crawl: crawlResult,\n robots: robotsResult,\n sitemap: sitemapComparison,\n assets: assetResult,\n }),\n });\n if (res.ok) {\n const data = (await res.json()) as { checkId?: string };\n if (pushSpinner) pushSpinner.succeed(`Pushed to dashboard — check ${data.checkId}`);\n } else {\n const data = (await res.json().catch(() => ({}))) as { error?: string };\n if (pushSpinner) pushSpinner.fail(`Push failed: ${data.error || res.statusText}`);\n }\n } catch (err) {\n if (pushSpinner) pushSpinner.fail(`Push failed: ${err instanceof Error ? err.message : String(err)}`);\n }\n if (!jsonOutput) console.log(\"\");\n }\n }\n\n // Exit code\n if (crawlResult.totalErrors > 0) {\n process.exit(1);\n }\n });\n","import { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport ora from \"ora\";\nimport { researchKeywords, crawlSite, analyzeContentGaps } from \"indxel\";\n\nexport const keywordsCommand = new Command(\"keywords\")\n .description(\"Research keyword opportunities and find content gaps\")\n .argument(\"<seed>\", \"Seed keyword or topic to research\")\n .option(\"--locale <locale>\", \"Language locale\", \"en\")\n .option(\"--country <country>\", \"Country code\", \"us\")\n .option(\"--site <url>\", \"Site URL to analyze content gaps against\")\n .option(\"--max-pages <n>\", \"Maximum pages to crawl for gap analysis\", \"30\")\n .option(\"--json\", \"Output results as JSON\", false)\n .action(async (seed: string, opts) => {\n const jsonOutput = opts.json;\n\n if (!jsonOutput) {\n console.log(\"\");\n console.log(chalk.bold(` indxel keywords`) + chalk.dim(` — \"${seed}\"`));\n console.log(\"\");\n }\n\n // 1. Keyword research\n const kwSpinner = jsonOutput ? null : ora(\"Researching keywords...\").start();\n const kwResult = await researchKeywords(seed, {\n locale: opts.locale,\n country: opts.country,\n });\n\n if (!jsonOutput) {\n kwSpinner!.succeed(`Found ${kwResult.totalKeywords} keywords`);\n console.log(\"\");\n\n if (kwResult.suggestions.length > 0) {\n console.log(chalk.bold(` Direct suggestions (${kwResult.suggestions.length})`));\n for (const s of kwResult.suggestions) {\n console.log(` ${chalk.hex(\"#F4A261\")(s.keyword)}`);\n }\n console.log(\"\");\n }\n\n if (kwResult.questions.length > 0) {\n console.log(chalk.bold(` Questions (${kwResult.questions.length})`));\n for (const q of kwResult.questions.slice(0, 20)) {\n console.log(` ${chalk.cyan(\"?\")} ${q.keyword}`);\n }\n console.log(\"\");\n }\n\n if (kwResult.longTail.length > 0) {\n console.log(chalk.bold(` Long-tail (${kwResult.longTail.length})`));\n for (const lt of kwResult.longTail.slice(0, 20)) {\n console.log(chalk.dim(` ${lt.keyword}`));\n }\n if (kwResult.longTail.length > 20) {\n console.log(chalk.dim(` ... and ${kwResult.longTail.length - 20} more`));\n }\n console.log(\"\");\n }\n }\n\n // 2. Content gap analysis (if site URL provided)\n let gapResult = null;\n if (opts.site) {\n let siteUrl = opts.site;\n if (!siteUrl.startsWith(\"http://\") && !siteUrl.startsWith(\"https://\")) {\n siteUrl = `https://${siteUrl}`;\n }\n\n const crawlSpinner = jsonOutput ? null : ora(`Crawling ${siteUrl} for gap analysis...`).start();\n const crawlResult = await crawlSite(siteUrl, {\n maxPages: parseInt(opts.maxPages, 10),\n delay: 200,\n });\n\n if (!jsonOutput) {\n crawlSpinner!.succeed(`Crawled ${crawlResult.totalPages} pages`);\n }\n\n const allKeywords = [\n ...kwResult.suggestions,\n ...kwResult.questions,\n ...kwResult.longTail,\n ];\n\n const existingPages = crawlResult.pages\n .filter((p) => !p.error)\n .map((p) => ({ url: p.url, metadata: p.metadata }));\n\n gapResult = analyzeContentGaps(allKeywords, existingPages);\n\n if (!jsonOutput) {\n console.log(\"\");\n console.log(\n chalk.bold(` Content coverage: `) +\n `${gapResult.totalCovered}/${gapResult.totalKeywords} keywords (${gapResult.coveragePercent}%)`,\n );\n console.log(\"\");\n\n if (gapResult.gaps.length > 0) {\n const highGaps = gapResult.gaps.filter((g) => g.relevance === \"high\");\n const medGaps = gapResult.gaps.filter((g) => g.relevance === \"medium\");\n\n if (highGaps.length > 0) {\n console.log(chalk.bold.red(` High priority gaps (${highGaps.length})`));\n for (const gap of highGaps.slice(0, 15)) {\n console.log(\n chalk.red(` ✗ `) +\n `\"${gap.keyword}\" → ` +\n chalk.dim(`${gap.suggestedType} at ${gap.suggestedPath}`),\n );\n }\n console.log(\"\");\n }\n\n if (medGaps.length > 0) {\n console.log(chalk.bold.yellow(` Medium priority gaps (${medGaps.length})`));\n for (const gap of medGaps.slice(0, 10)) {\n console.log(\n chalk.yellow(` ⚠ `) +\n `\"${gap.keyword}\" → ` +\n chalk.dim(`${gap.suggestedType} at ${gap.suggestedPath}`),\n );\n }\n console.log(\"\");\n }\n }\n\n if (gapResult.gaps.length === 0) {\n console.log(chalk.green(` ✓ All keyword opportunities are covered`));\n console.log(\"\");\n }\n }\n }\n\n // JSON output\n if (jsonOutput) {\n console.log(\n JSON.stringify(\n { keywords: kwResult, contentGaps: gapResult },\n null,\n 2,\n ),\n );\n }\n });\n","import { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport ora from \"ora\";\nimport { fetchSitemap, fetchRobots } from \"indxel\";\nimport { checkPlan } from \"../auth.js\";\nimport { loadIndexNowKey, resolveApiKey } from \"../store.js\";\n\nfunction delay(ms: number): Promise<void> {\n return new Promise((r) => setTimeout(r, ms));\n}\n\nexport const indexCommand = new Command(\"index\")\n .description(\"Submit your pages to search engines and check indexation status\")\n .argument(\"<url>\", \"Site URL (e.g., https://yoursite.com)\")\n .option(\"--check\", \"Check which pages appear indexed (Pro+)\", false)\n .option(\"--indexnow-key <key>\", \"IndexNow key (auto-detected from .indxel/ if not specified)\")\n .option(\"--api-key <key>\", \"Indxel API key (required for --check and IndexNow submission)\")\n .option(\"--json\", \"Output results as JSON\", false)\n .action(async (url: string, opts) => {\n const jsonOutput = opts.json;\n const needsPaid = opts.check;\n\n // Helper: only log in human-readable mode\n function log(...args: unknown[]) {\n if (!jsonOutput) console.log(...args);\n }\n\n // Helper: create spinner only in human-readable mode\n function spin(text: string) {\n return jsonOutput ? null : ora(text).start();\n }\n\n // Ensure URL has protocol\n if (!url.startsWith(\"http://\") && !url.startsWith(\"https://\")) {\n url = `https://${url}`;\n }\n\n let baseUrl: URL;\n try {\n baseUrl = new URL(url);\n } catch {\n console.error(chalk.red(\" Invalid URL.\"));\n process.exit(1);\n }\n\n const origin = baseUrl.origin;\n const host = baseUrl.hostname;\n\n log(\"\");\n log(chalk.bold(\" indxel index\") + chalk.dim(` — ${origin}`));\n log(\"\");\n\n // Gate paid features behind API key + plan check\n if (needsPaid) {\n const apiKey = await resolveApiKey(opts.apiKey);\n if (!apiKey) {\n log(chalk.red(\" ✗ --check requires a linked project (Plus plan).\"));\n log(chalk.dim(\" Run: \") + chalk.bold(\"npx indxel link\"));\n log(chalk.dim(\" Or use --api-key / set INDXEL_API_KEY.\"));\n log(\"\");\n process.exit(1);\n }\n\n const plan = await checkPlan(apiKey);\n if (!plan) {\n log(chalk.red(\" ✗ Invalid API key.\"));\n log(\"\");\n process.exit(1);\n }\n\n if (plan === \"FREE\") {\n log(chalk.red(\" ✗ Indexation check requires a Pro plan.\"));\n log(chalk.dim(\" Upgrade at https://indxel.com/pricing\"));\n log(\"\");\n process.exit(1);\n }\n }\n\n // 1. Fetch sitemap\n const sitemapSpinner = spin(\"Fetching sitemap...\");\n const sitemapResult = await fetchSitemap(origin);\n const sitemapUrl = `${origin}/sitemap.xml`;\n\n if (!sitemapResult.found || sitemapResult.urls.length === 0) {\n sitemapSpinner?.fail(\"No sitemap found\");\n log(chalk.dim(\" Create a sitemap first: \") + chalk.bold(\"npx indxel init\"));\n log(\"\");\n if (jsonOutput) {\n console.log(JSON.stringify({ error: \"No sitemap found\" }, null, 2));\n }\n process.exit(1);\n }\n\n sitemapSpinner?.succeed(`Found sitemap — ${sitemapResult.urls.length} URLs`);\n\n // 2. Check robots.txt references sitemap\n const robotsSpinner = spin(\"Checking robots.txt...\");\n const robotsResult = await fetchRobots(origin);\n let sitemapInRobots = false;\n\n if (robotsResult.found) {\n sitemapInRobots = robotsResult.sitemapUrls.some((s) =>\n s.toLowerCase().includes(\"sitemap\"),\n );\n if (sitemapInRobots) {\n robotsSpinner?.succeed(\"robots.txt references sitemap\");\n } else {\n robotsSpinner?.warn(\"robots.txt found but doesn't reference sitemap\");\n log(chalk.dim(` Add this to your robots.txt:`));\n log(chalk.dim(` Sitemap: ${sitemapUrl}`));\n }\n } else {\n robotsSpinner?.warn(\"No robots.txt found\");\n log(chalk.dim(\" Create one with: \") + chalk.bold(\"npx indxel init\"));\n }\n\n log(\"\");\n\n // 3. IndexNow submission (Bing, Yandex, DuckDuckGo, etc.)\n // IndexNow is an open protocol — one-shot submission works without an account.\n const indexNowKey = opts.indexnowKey || process.env.INDEXNOW_KEY || await loadIndexNowKey(process.cwd());\n const indexNowResult: { submitted: boolean; engine: string; status?: number }[] = [];\n\n if (indexNowKey) {\n const urls = sitemapResult.urls.map((u) => u.loc);\n const indexNowSpinner = spin(\"Submitting via IndexNow...\");\n\n const indexNowEngines = [\n { name: \"Bing/Yandex\", endpoint: \"https://api.indexnow.org/indexnow\" },\n ];\n\n for (const engine of indexNowEngines) {\n try {\n const res = await fetch(engine.endpoint, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n host,\n key: indexNowKey,\n keyLocation: `${origin}/${indexNowKey}.txt`,\n urlList: urls.slice(0, 10000), // IndexNow limit\n }),\n signal: AbortSignal.timeout(15000),\n });\n\n if (res.ok || res.status === 202) {\n indexNowResult.push({ submitted: true, engine: engine.name, status: res.status });\n indexNowSpinner?.succeed(`IndexNow — ${urls.length} URLs submitted to ${engine.name}`);\n } else {\n indexNowResult.push({ submitted: false, engine: engine.name, status: res.status });\n indexNowSpinner?.warn(`IndexNow — ${engine.name} returned HTTP ${res.status}`);\n }\n } catch (err) {\n indexNowResult.push({ submitted: false, engine: engine.name });\n indexNowSpinner?.fail(`IndexNow — ${err instanceof Error ? err.message : \"failed\"}`);\n }\n }\n } else {\n log(chalk.bold(\" IndexNow\") + chalk.dim(\" (Bing, Yandex, DuckDuckGo)\"));\n log(chalk.dim(\" Not configured. Run \") + chalk.bold(\"npx indxel init\") + chalk.dim(\" to set it up automatically.\"));\n log(\"\");\n }\n\n log(chalk.bold(\" Google Search Console\"));\n log(chalk.dim(\" Google requires manual setup via Search Console:\"));\n log(chalk.dim(\" 1. Go to \") + chalk.underline(\"https://search.google.com/search-console\"));\n log(chalk.dim(` 2. Add & verify ${host}`));\n log(chalk.dim(\" 3. Submit your sitemap: Sitemaps > Add > sitemap.xml\"));\n log(\"\");\n\n // 4. Check indexation status (optional)\n let indexationResults: Array<{ url: string; indexed: boolean }> | null = null;\n\n if (opts.check) {\n const checkSpinner = spin(\"Checking indexation status...\");\n indexationResults = [];\n const urls = sitemapResult.urls.map((u) => u.loc);\n let indexedCount = 0;\n\n for (let i = 0; i < urls.length; i++) {\n const pageUrl = urls[i];\n if (checkSpinner) {\n checkSpinner.text = `Checking indexation... ${i + 1}/${urls.length}`;\n }\n\n try {\n const cacheUrl = `https://webcache.googleusercontent.com/search?q=cache:${encodeURIComponent(pageUrl)}`;\n const res = await fetch(cacheUrl, {\n method: \"HEAD\",\n signal: AbortSignal.timeout(5000),\n redirect: \"manual\",\n headers: {\n \"User-Agent\": \"Mozilla/5.0 (compatible; Indxel/0.1; +https://indxel.com)\",\n },\n });\n\n const indexed = res.status === 200 || res.status === 301 || res.status === 302;\n indexationResults.push({ url: pageUrl, indexed });\n if (indexed) indexedCount++;\n } catch {\n indexationResults.push({ url: pageUrl, indexed: false });\n }\n\n await delay(300);\n }\n\n checkSpinner?.succeed(`Indexation: ${indexedCount}/${urls.length} pages found in Google cache`);\n\n if (!jsonOutput) {\n console.log(\"\");\n const notIndexed = indexationResults.filter((r) => !r.indexed);\n\n if (notIndexed.length > 0) {\n console.log(chalk.bold(` Not indexed (${notIndexed.length})`));\n for (const r of notIndexed.slice(0, 20)) {\n console.log(chalk.red(\" ✗ \") + r.url);\n }\n if (notIndexed.length > 20) {\n console.log(chalk.dim(` ... and ${notIndexed.length - 20} more`));\n }\n console.log(\"\");\n } else {\n console.log(chalk.green(\" ✓ All pages appear indexed\"));\n console.log(\"\");\n }\n }\n }\n\n // 5. Summary\n if (jsonOutput) {\n console.log(JSON.stringify({\n sitemap: { url: sitemapUrl, urls: sitemapResult.urls.length },\n robotsTxt: { found: robotsResult.found, referencesSitemap: sitemapInRobots },\n indexNow: indexNowResult.length > 0 ? indexNowResult : null,\n indexation: indexationResults,\n }, null, 2));\n } else {\n console.log(chalk.bold(\" ─── Summary ───\"));\n console.log(\"\");\n console.log(` Sitemap: ${sitemapResult.urls.length} URLs`);\n\n let robotsStatus: string;\n if (!robotsResult.found) {\n robotsStatus = chalk.red(\"✗ not found\");\n } else if (sitemapInRobots) {\n robotsStatus = chalk.green(\"✓ references sitemap\");\n } else {\n robotsStatus = chalk.yellow(\"⚠ missing sitemap ref\");\n }\n console.log(` robots.txt: ${robotsStatus}`);\n\n if (indexNowResult.length > 0) {\n for (const r of indexNowResult) {\n const status = r.submitted ? chalk.green(\"✓ submitted\") : chalk.red(\"✗ failed\");\n console.log(` IndexNow: ${status} (${r.engine})`);\n }\n } else {\n console.log(` IndexNow: ${chalk.dim(\"not configured (run npx indxel init)\")}`);\n }\n if (indexationResults) {\n const indexedCount = indexationResults.filter((r) => r.indexed).length;\n console.log(` Google cache: ${indexedCount}/${indexationResults.length} indexed`);\n }\n console.log(\"\");\n }\n });\n","export async function checkPlan(apiKey: string): Promise<string | null> {\n try {\n const apiUrl = process.env.INDXEL_API_URL || \"https://indxel.com\";\n const res = await fetch(`${apiUrl}/api/cli/plan`, {\n headers: { Authorization: `Bearer ${apiKey}` },\n signal: AbortSignal.timeout(10000),\n });\n if (!res.ok) return null;\n const data = (await res.json()) as { plan?: string };\n return data.plan ?? null;\n } catch {\n return null;\n }\n}\n","import { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport ora from \"ora\";\nimport { fetchSitemap } from \"indxel\";\n\n// --- Types ---\n\ninterface PsiMetrics {\n performanceScore: number;\n lcp: number;\n cls: number;\n inp: number;\n fcp: number;\n si: number;\n tbt: number;\n}\n\ninterface PageResult {\n url: string;\n strategy: string;\n metrics: PsiMetrics | null;\n error?: string;\n}\n\n// --- CWV thresholds (Google's) ---\n\nconst THRESHOLDS = {\n lcp: { good: 2500, poor: 4000 },\n cls: { good: 0.1, poor: 0.25 },\n inp: { good: 200, poor: 500 },\n} as const;\n\n// --- Helpers ---\n\nfunction ratingFor(\n metric: \"lcp\" | \"cls\" | \"inp\",\n value: number,\n): \"good\" | \"needs-work\" | \"poor\" {\n const t = THRESHOLDS[metric];\n if (value <= t.good) return \"good\";\n if (value <= t.poor) return \"needs-work\";\n return \"poor\";\n}\n\nfunction colorForRating(rating: \"good\" | \"needs-work\" | \"poor\") {\n if (rating === \"good\") return chalk.green;\n if (rating === \"needs-work\") return chalk.yellow;\n return chalk.red;\n}\n\nfunction iconForRating(rating: \"good\" | \"needs-work\" | \"poor\") {\n if (rating === \"good\") return chalk.green(\"✓\");\n if (rating === \"needs-work\") return chalk.yellow(\"⚠\");\n return chalk.red(\"✗\");\n}\n\nfunction formatMs(ms: number): string {\n if (ms >= 1000) return `${(ms / 1000).toFixed(1)}s`;\n return `${Math.round(ms)}ms`;\n}\n\nfunction formatCls(value: number): string {\n return value.toFixed(2);\n}\n\nfunction scoreColor(score: number) {\n if (score >= 90) return chalk.green;\n if (score >= 50) return chalk.yellow;\n return chalk.red;\n}\n\nfunction delay(ms: number): Promise<void> {\n return new Promise((r) => setTimeout(r, ms));\n}\n\n// --- PSI API ---\n\nexport async function fetchPsi(\n url: string,\n strategy: \"mobile\" | \"desktop\",\n): Promise<PsiMetrics> {\n const params = new URLSearchParams({\n url,\n strategy,\n category: \"performance\",\n });\n\n const res = await fetch(\n `https://www.googleapis.com/pagespeedonline/v5/runPagespeed?${params}`,\n { signal: AbortSignal.timeout(60000) },\n );\n\n if (!res.ok) {\n const body = await res.text().catch(() => \"\");\n throw new Error(`PSI API returned HTTP ${res.status}: ${body.slice(0, 200)}`);\n }\n\n const data = await res.json();\n return parsePsiResponse(data);\n}\n\nexport function parsePsiResponse(data: any): PsiMetrics {\n const lr = data.lighthouseResult;\n if (!lr) throw new Error(\"No lighthouseResult in PSI response\");\n\n const perfScore = lr.categories?.performance?.score;\n if (perfScore == null) throw new Error(\"No performance score in PSI response\");\n\n return {\n performanceScore: Math.round(perfScore * 100),\n lcp: lr.audits?.[\"largest-contentful-paint\"]?.numericValue ?? 0,\n cls: lr.audits?.[\"cumulative-layout-shift\"]?.numericValue ?? 0,\n inp: lr.audits?.[\"interaction-to-next-paint\"]?.numericValue ?? 0,\n fcp: lr.audits?.[\"first-contentful-paint\"]?.numericValue ?? 0,\n si: lr.audits?.[\"speed-index\"]?.numericValue ?? 0,\n tbt: lr.audits?.[\"total-blocking-time\"]?.numericValue ?? 0,\n };\n}\n\nexport function checkBudgets(\n metrics: PsiMetrics,\n budgets: { lcp?: number; cls?: number; score?: number },\n): string[] {\n const failures: string[] = [];\n\n if (budgets.score != null && metrics.performanceScore < budgets.score) {\n failures.push(\n `Performance score ${metrics.performanceScore} is below budget ${budgets.score}`,\n );\n }\n if (budgets.lcp != null && metrics.lcp > budgets.lcp) {\n failures.push(\n `LCP ${formatMs(metrics.lcp)} exceeds budget ${formatMs(budgets.lcp)}`,\n );\n }\n if (budgets.cls != null && metrics.cls > budgets.cls) {\n failures.push(\n `CLS ${formatCls(metrics.cls)} exceeds budget ${formatCls(budgets.cls)}`,\n );\n }\n\n return failures;\n}\n\n// --- Output formatting ---\n\nfunction printPageResult(result: PageResult) {\n const { url, strategy, metrics, error } = result;\n\n console.log(\n chalk.bold(\" indxel perf\") + chalk.dim(` — ${url} (${strategy})`),\n );\n console.log(\"\");\n\n if (error || !metrics) {\n console.log(chalk.red(` ✗ ${error ?? \"Unknown error\"}`));\n console.log(\"\");\n return;\n }\n\n const sc = scoreColor(metrics.performanceScore);\n const perfIcon =\n metrics.performanceScore >= 90\n ? chalk.green(\"✓\")\n : metrics.performanceScore >= 50\n ? chalk.yellow(\"⚠\")\n : chalk.red(\"✗\");\n console.log(\n ` ${perfIcon} ${chalk.bold(\"Performance\")} ${sc(chalk.bold(`${metrics.performanceScore}/100`))}`,\n );\n console.log(\"\");\n\n // Core Web Vitals\n console.log(chalk.bold(\" Core Web Vitals\"));\n\n const lcpRating = ratingFor(\"lcp\", metrics.lcp);\n const clsRating = ratingFor(\"cls\", metrics.cls);\n const inpRating = ratingFor(\"inp\", metrics.inp);\n\n console.log(\n ` ${iconForRating(lcpRating)} ${colorForRating(lcpRating)(formatMs(metrics.lcp).padEnd(9))} ${chalk.dim(\"LCP Largest Contentful Paint\")}`,\n );\n console.log(\n ` ${iconForRating(clsRating)} ${colorForRating(clsRating)(formatCls(metrics.cls).padEnd(9))} ${chalk.dim(\"CLS Cumulative Layout Shift\")}`,\n );\n console.log(\n ` ${iconForRating(inpRating)} ${colorForRating(inpRating)(formatMs(metrics.inp).padEnd(9))} ${chalk.dim(\"INP Interaction to Next Paint\")}`,\n );\n console.log(\"\");\n\n // Other metrics\n console.log(chalk.bold(\" Other metrics\"));\n console.log(\n ` ${formatMs(metrics.fcp).padEnd(9)} ${chalk.dim(\"FCP First Contentful Paint\")}`,\n );\n console.log(\n ` ${formatMs(metrics.si).padEnd(9)} ${chalk.dim(\"SI Speed Index\")}`,\n );\n console.log(\n ` ${formatMs(metrics.tbt).padEnd(9)} ${chalk.dim(\"TBT Total Blocking Time\")}`,\n );\n console.log(\"\");\n}\n\nfunction printMultiPageSummary(results: PageResult[]) {\n const valid = results.filter((r) => r.metrics);\n if (valid.length === 0) return;\n\n const avgScore = Math.round(\n valid.reduce((s, r) => s + r.metrics!.performanceScore, 0) / valid.length,\n );\n const worstLcp = Math.max(...valid.map((r) => r.metrics!.lcp));\n const worstCls = Math.max(...valid.map((r) => r.metrics!.cls));\n const worstInp = Math.max(...valid.map((r) => r.metrics!.inp));\n\n console.log(chalk.bold(\" ─── Summary ───\"));\n console.log(\"\");\n console.log(` Pages tested: ${chalk.bold(String(results.length))}`);\n console.log(\n ` Avg score: ${scoreColor(avgScore)(chalk.bold(`${avgScore}/100`))}`,\n );\n\n const lcpR = ratingFor(\"lcp\", worstLcp);\n const clsR = ratingFor(\"cls\", worstCls);\n const inpR = ratingFor(\"inp\", worstInp);\n\n console.log(\n ` Worst LCP: ${colorForRating(lcpR)(formatMs(worstLcp))}`,\n );\n console.log(\n ` Worst CLS: ${colorForRating(clsR)(formatCls(worstCls))}`,\n );\n console.log(\n ` Worst INP: ${colorForRating(inpR)(formatMs(worstInp))}`,\n );\n console.log(\"\");\n}\n\n// --- Command ---\n\nexport const perfCommand = new Command(\"perf\")\n .description(\"Test Core Web Vitals and performance via PageSpeed Insights\")\n .argument(\"<url>\", \"URL to test (e.g., https://yoursite.com)\")\n .option(\n \"--strategy <strategy>\",\n \"Testing strategy: mobile or desktop\",\n \"mobile\",\n )\n .option(\n \"--pages <n>\",\n \"Test top N pages from sitemap (default: 1 = just the URL)\",\n \"1\",\n )\n .option(\"--json\", \"Output results as JSON\", false)\n .option(\"--budget-lcp <ms>\", \"Fail if LCP exceeds threshold (ms)\")\n .option(\"--budget-cls <score>\", \"Fail if CLS exceeds threshold\")\n .option(\"--budget-score <n>\", \"Fail if perf score below threshold\")\n .action(async (url: string, opts) => {\n const jsonOutput = opts.json;\n const strategy = opts.strategy as \"mobile\" | \"desktop\";\n const pageCount = parseInt(opts.pages, 10);\n\n if (strategy !== \"mobile\" && strategy !== \"desktop\") {\n console.error(\n chalk.red(\" --strategy must be 'mobile' or 'desktop'\"),\n );\n process.exit(1);\n }\n\n // Ensure URL has protocol\n if (!url.startsWith(\"http://\") && !url.startsWith(\"https://\")) {\n url = `https://${url}`;\n }\n\n try {\n new URL(url);\n } catch {\n console.error(chalk.red(\" Invalid URL.\"));\n process.exit(1);\n }\n\n // Collect URLs to test\n let urls: string[] = [url];\n\n if (pageCount > 1) {\n const sitemapSpinner = jsonOutput ? null : ora(\"Fetching sitemap...\").start();\n const sitemap = await fetchSitemap(url);\n\n if (sitemap.found && sitemap.urls.length > 0) {\n urls = sitemap.urls.slice(0, pageCount).map((u) => u.loc);\n sitemapSpinner?.succeed(\n `Found ${sitemap.urls.length} URLs, testing top ${urls.length}`,\n );\n } else {\n sitemapSpinner?.warn(\"No sitemap found, testing single URL\");\n }\n if (!jsonOutput) console.log(\"\");\n }\n\n // Run PSI for each URL\n const results: PageResult[] = [];\n\n for (let i = 0; i < urls.length; i++) {\n const targetUrl = urls[i];\n const spinner = jsonOutput\n ? null\n : ora(\n urls.length > 1\n ? `Testing ${i + 1}/${urls.length}: ${targetUrl}`\n : `Testing ${targetUrl} (${strategy})...`,\n ).start();\n\n try {\n const metrics = await fetchPsi(targetUrl, strategy);\n spinner?.stop();\n results.push({ url: targetUrl, strategy, metrics });\n\n if (!jsonOutput) {\n printPageResult({ url: targetUrl, strategy, metrics });\n }\n } catch (err) {\n const errMsg = err instanceof Error ? err.message : String(err);\n spinner?.fail(`Failed: ${targetUrl}`);\n results.push({ url: targetUrl, strategy, metrics: null, error: errMsg });\n\n if (!jsonOutput) {\n console.log(chalk.red(` ${errMsg}`));\n console.log(\"\");\n }\n }\n\n // Rate-limit delay between calls\n if (i < urls.length - 1) {\n await delay(2000);\n }\n }\n\n // Multi-page summary\n if (!jsonOutput && results.length > 1) {\n printMultiPageSummary(results);\n }\n\n // JSON output\n if (jsonOutput) {\n const output =\n results.length === 1\n ? {\n url: results[0].url,\n strategy: results[0].strategy,\n ...(results[0].metrics ?? {}),\n error: results[0].error ?? undefined,\n }\n : {\n strategy,\n pages: results.map((r) => ({\n url: r.url,\n ...(r.metrics ?? {}),\n error: r.error ?? undefined,\n })),\n summary: (() => {\n const valid = results.filter((r) => r.metrics);\n if (valid.length === 0) return null;\n return {\n avgScore: Math.round(\n valid.reduce(\n (s, r) => s + r.metrics!.performanceScore,\n 0,\n ) / valid.length,\n ),\n worstLcp: Math.max(\n ...valid.map((r) => r.metrics!.lcp),\n ),\n worstCls: Math.max(\n ...valid.map((r) => r.metrics!.cls),\n ),\n worstInp: Math.max(\n ...valid.map((r) => r.metrics!.inp),\n ),\n };\n })(),\n };\n console.log(JSON.stringify(output, null, 2));\n }\n\n // Budget enforcement\n const budgets = {\n lcp: opts.budgetLcp ? parseFloat(opts.budgetLcp) : undefined,\n cls: opts.budgetCls ? parseFloat(opts.budgetCls) : undefined,\n score: opts.budgetScore ? parseInt(opts.budgetScore, 10) : undefined,\n };\n\n const hasBudgets =\n budgets.lcp != null || budgets.cls != null || budgets.score != null;\n\n if (hasBudgets) {\n const allFailures: string[] = [];\n\n for (const r of results) {\n if (!r.metrics) continue;\n const failures = checkBudgets(r.metrics, budgets);\n if (failures.length > 0) {\n allFailures.push(...failures.map((f) => `${r.url}: ${f}`));\n }\n }\n\n if (allFailures.length > 0) {\n if (!jsonOutput) {\n console.log(chalk.red(chalk.bold(\" Budget exceeded:\")));\n for (const f of allFailures) {\n console.log(chalk.red(` ✗ ${f}`));\n }\n console.log(\"\");\n }\n process.exit(1);\n }\n }\n });\n","import { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport ora from \"ora\";\nimport { loadProjectConfig, saveProjectConfig, loadIndexNowKey } from \"../store.js\";\n\nfunction delay(ms: number): Promise<void> {\n return new Promise((r) => setTimeout(r, ms));\n}\n\nasync function openBrowser(url: string): Promise<void> {\n const { platform } = process;\n const { exec } = await import(\"node:child_process\");\n\n const cmd =\n platform === \"darwin\"\n ? \"open\"\n : platform === \"win32\"\n ? \"start\"\n : \"xdg-open\";\n\n exec(`${cmd} ${url}`);\n}\n\nexport const linkCommand = new Command(\"link\")\n .description(\"Link this project to your Indxel dashboard for monitoring\")\n .option(\"--api-key <key>\", \"Link directly with an API key (skip browser flow)\")\n .action(async (opts) => {\n const apiUrl = process.env.INDXEL_API_URL || \"https://indxel.com\";\n const cwd = process.cwd();\n\n console.log(\"\");\n console.log(chalk.bold(\" indxel link\"));\n console.log(\"\");\n\n // Check if already linked\n const existing = await loadProjectConfig(cwd);\n if (existing) {\n console.log(chalk.green(\" ✓\") + ` Already linked to ${chalk.bold(existing.projectName)}`);\n console.log(chalk.dim(` Project ID: ${existing.projectId}`));\n console.log(chalk.dim(` Linked at: ${existing.linkedAt}`));\n console.log(\"\");\n console.log(chalk.dim(\" To re-link, delete .indxel/config.json and run again.\"));\n console.log(\"\");\n return;\n }\n\n // Option 1: Direct API key\n if (opts.apiKey) {\n const spinner = ora(\"Verifying API key...\").start();\n\n try {\n const res = await fetch(`${apiUrl}/api/projects/by-key`, {\n headers: { Authorization: `Bearer ${opts.apiKey}` },\n signal: AbortSignal.timeout(10000),\n });\n\n if (!res.ok) {\n spinner.fail(\"Invalid API key.\");\n console.log(chalk.dim(\" Check your key at https://indxel.com/dashboard/settings\"));\n console.log(\"\");\n process.exit(1);\n }\n\n const body = (await res.json()) as { project: { id: string; name: string } };\n const project = body.project;\n spinner.succeed(`Linked to ${chalk.bold(project.name)}`);\n\n await saveProjectConfig(cwd, {\n apiKey: opts.apiKey,\n projectId: project.id,\n projectName: project.name,\n linkedAt: new Date().toISOString(),\n });\n\n // Sync IndexNow key if available\n await syncIndexNowKey(cwd, apiUrl, opts.apiKey, project.id);\n\n console.log(\"\");\n console.log(chalk.dim(\" Config saved to .indxel/config.json\"));\n console.log(chalk.dim(\" You can now use \") + chalk.bold(\"npx indxel crawl --push\") + chalk.dim(\" without --api-key.\"));\n console.log(\"\");\n return;\n } catch (err) {\n spinner.fail(err instanceof Error ? err.message : \"Connection failed\");\n console.log(\"\");\n process.exit(1);\n }\n }\n\n // Option 2: Device flow (browser-based)\n const initSpinner = ora(\"Starting device flow...\").start();\n\n let deviceCode: string;\n let userCode: string;\n\n try {\n const res = await fetch(`${apiUrl}/api/cli/auth`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n signal: AbortSignal.timeout(10000),\n });\n\n if (!res.ok) {\n initSpinner.fail(\"Could not start device flow.\");\n console.log(chalk.dim(\" You can also link directly: \") + chalk.bold(\"npx indxel link --api-key <your-key>\"));\n console.log(\"\");\n process.exit(1);\n }\n\n const data = (await res.json()) as { deviceCode: string; userCode: string };\n deviceCode = data.deviceCode;\n userCode = data.userCode;\n initSpinner.stop();\n } catch (err) {\n initSpinner.fail(err instanceof Error ? err.message : \"Connection failed\");\n console.log(chalk.dim(\" You can also link directly: \") + chalk.bold(\"npx indxel link --api-key <your-key>\"));\n console.log(\"\");\n process.exit(1);\n return; // unreachable, satisfies TS\n }\n\n const connectUrl = `${apiUrl}/cli/connect?code=${userCode}`;\n\n console.log(chalk.bold(\" Open this URL in your browser:\"));\n console.log(\"\");\n console.log(` ${chalk.underline(connectUrl)}`);\n console.log(\"\");\n console.log(` Your code: ${chalk.bold.cyan(userCode)}`);\n console.log(\"\");\n\n // Try to open browser automatically\n try {\n await openBrowser(connectUrl);\n console.log(chalk.dim(\" Browser opened automatically.\"));\n } catch {\n // Silently fail — user can open manually\n }\n\n // Poll for authorization\n const pollSpinner = ora(\"Waiting for authorization...\").start();\n const maxWait = 5 * 60 * 1000; // 5 minutes\n const pollInterval = 2000; // 2 seconds\n const startTime = Date.now();\n\n while (Date.now() - startTime < maxWait) {\n await delay(pollInterval);\n\n try {\n const res = await fetch(`${apiUrl}/api/cli/auth?code=${deviceCode}`, {\n signal: AbortSignal.timeout(10000),\n });\n\n if (res.status === 202) {\n // Still pending\n continue;\n }\n\n if (res.ok) {\n const data = (await res.json()) as {\n apiKey: string;\n projectId: string;\n projectName: string;\n };\n\n pollSpinner.succeed(`Linked to ${chalk.bold(data.projectName)}`);\n\n await saveProjectConfig(cwd, {\n apiKey: data.apiKey,\n projectId: data.projectId,\n projectName: data.projectName,\n linkedAt: new Date().toISOString(),\n });\n\n // Sync IndexNow key if available\n await syncIndexNowKey(cwd, apiUrl, data.apiKey, data.projectId);\n\n console.log(\"\");\n console.log(chalk.dim(\" Config saved to .indxel/config.json\"));\n console.log(chalk.dim(\" You can now use \") + chalk.bold(\"npx indxel crawl --push\") + chalk.dim(\" without --api-key.\"));\n console.log(\"\");\n return;\n }\n\n // Unexpected status\n pollSpinner.fail(\"Authorization failed.\");\n console.log(\"\");\n process.exit(1);\n } catch {\n // Network error — keep polling\n }\n }\n\n pollSpinner.fail(\"Timed out waiting for authorization (5 minutes).\");\n console.log(chalk.dim(\" Try again: \") + chalk.bold(\"npx indxel link\"));\n console.log(\"\");\n process.exit(1);\n });\n\n/**\n * Sync the local IndexNow key to the linked project on the dashboard.\n * This avoids the \"pending verification\" state in the dashboard UI.\n */\nasync function syncIndexNowKey(\n cwd: string,\n apiUrl: string,\n apiKey: string,\n projectId: string,\n): Promise<void> {\n const indexNowKey = await loadIndexNowKey(cwd);\n if (!indexNowKey) return;\n\n try {\n const res = await fetch(`${apiUrl}/api/projects/${projectId}/indexation/setup`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${apiKey}`,\n },\n body: JSON.stringify({ action: \"sync\", key: indexNowKey }),\n signal: AbortSignal.timeout(10000),\n });\n\n if (res.ok) {\n console.log(chalk.green(\" ✓\") + \" IndexNow key synced to dashboard\");\n }\n } catch {\n // Non-critical — skip silently\n }\n}\n"],"mappings":";AAAA,SAAS,WAAAA,gBAAe;;;ACAxB,SAAS,eAAe;AACxB,OAAO,WAAW;AAClB,OAAO,SAAS;AAChB,SAAS,cAAAC,mBAAkB;AAC3B,SAAS,aAAAC,YAAW,SAAAC,QAAO,YAAAC,iBAAgB;AAC3C,SAAS,QAAAC,aAAY;;;ACLrB,SAAS,kBAAkB;AAC3B,SAAS,gBAAgB;AACzB,SAAS,YAAY;AAwBrB,eAAsB,cAAc,KAAmC;AACrE,QAAM,OAAoB;AAAA,IACxB,MAAM;AAAA,IACN,UAAU;AAAA,IACV,eAAe;AAAA,IACf,QAAQ;AAAA,IACR,cAAc;AAAA,IACd,cAAc;AAAA,IACd,YAAY;AAAA,IACZ,WAAW;AAAA,EACb;AAGA,QAAM,cAAc;AAAA,IAClB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACA,OAAK,WAAW,YAAY,KAAK,CAAC,MAAM,WAAW,KAAK,KAAK,CAAC,CAAC,CAAC;AAGhE,QAAM,UAAU,KAAK,KAAK,cAAc;AACxC,MAAI,WAAW,OAAO,GAAG;AACvB,QAAI;AACF,YAAM,MAAM,KAAK,MAAM,MAAM,SAAS,SAAS,OAAO,CAAC;AACvD,YAAM,UAAU,IAAI,cAAc,QAAQ,IAAI,iBAAiB;AAC/D,UAAI,SAAS;AACX,aAAK,WAAW;AAChB,aAAK,cAAc,QAAQ,QAAQ,aAAa,EAAE,EAAE,KAAK;AAAA,MAC3D;AAAA,IACF,QAAQ;AAAA,IAER;AAAA,EACF;AAGA,OAAK,eACH,WAAW,KAAK,KAAK,eAAe,CAAC,KACrC,WAAW,KAAK,KAAK,aAAa,CAAC;AAGrC,MAAI,WAAW,KAAK,KAAK,OAAO,KAAK,CAAC,GAAG;AACvC,SAAK,gBAAgB;AACrB,SAAK,SAAS;AAAA,EAChB,WAAW,WAAW,KAAK,KAAK,KAAK,CAAC,GAAG;AACvC,SAAK,gBAAgB;AACrB,SAAK,SAAS;AAAA,EAChB;AAGA,OAAK,eACH,WAAW,KAAK,KAAK,eAAe,CAAC,KACrC,WAAW,KAAK,KAAK,eAAe,CAAC;AAEvC,OAAK,aACH,WAAW,KAAK,KAAK,KAAK,QAAQ,YAAY,CAAC,KAC/C,WAAW,KAAK,KAAK,KAAK,QAAQ,YAAY,CAAC,KAC/C,WAAW,KAAK,KAAK,KAAK,QAAQ,aAAa,CAAC;AAElD,OAAK,YACH,WAAW,KAAK,KAAK,KAAK,QAAQ,WAAW,CAAC,KAC9C,WAAW,KAAK,KAAK,KAAK,QAAQ,WAAW,CAAC,KAC9C,WAAW,KAAK,KAAK,KAAK,QAAQ,YAAY,CAAC;AAEjD,SAAO;AACT;;;AC5FA,SAAS,cAAAC,mBAAkB;AAC3B,SAAS,YAAAC,WAAU,WAAW,aAAa;AAC3C,SAAS,QAAAC,aAAY;AACrB,SAAS,mBAAmB;AAG5B,IAAM,YAAY;AAClB,IAAM,kBAAkB;AACxB,IAAM,oBAAoB;AAC1B,IAAM,cAAc;AAQpB,eAAsB,gBACpB,KACA,SACe;AACf,QAAM,WAAWA,MAAK,KAAK,SAAS;AAEpC,MAAI,CAACF,YAAW,QAAQ,GAAG;AACzB,UAAM,MAAM,UAAU,EAAE,WAAW,KAAK,CAAC;AAAA,EAC3C;AAEA,QAAM,SAAsB;AAAA,IAC1B,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,IAClC,SAAS;AAAA,MACP,GAAG;AAAA;AAAA,MAEH,SAAS,QAAQ,QAAQ,IAAI,CAAC,OAAO;AAAA,QACnC,MAAM;AAAA,UACJ,UAAU,EAAE,KAAK;AAAA,UACjB,OAAO,EAAE,KAAK;AAAA,UACd,aAAa,EAAE,KAAK;AAAA,UACpB,oBAAoB,EAAE,KAAK;AAAA,UAC3B,mBAAmB,EAAE,KAAK;AAAA,UAC1B,iBAAiB,EAAE,KAAK;AAAA,UACxB,mBAAmB,EAAE,KAAK;AAAA,QAC5B;AAAA,QACA,YAAY,EAAE;AAAA,MAChB,EAAE;AAAA,IACJ;AAAA,EACF;AAEA,QAAM;AAAA,IACJE,MAAK,UAAU,eAAe;AAAA,IAC9B,KAAK,UAAU,QAAQ,MAAM,CAAC;AAAA,IAC9B;AAAA,EACF;AACF;AAGA,eAAsB,kBACpB,KAC6B;AAC7B,QAAM,WAAWA,MAAK,KAAK,WAAW,eAAe;AAErD,MAAI,CAACF,YAAW,QAAQ,GAAG;AACzB,WAAO;AAAA,EACT;AAEA,MAAI;AACF,UAAM,OAAO,MAAMC,UAAS,UAAU,OAAO;AAC7C,WAAO,KAAK,MAAM,IAAI;AAAA,EACxB,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAQO,SAAS,sBAA8B;AAC5C,SAAO,YAAY,EAAE,EAAE,SAAS,KAAK;AACvC;AAGA,eAAsB,gBAAgB,KAAa,KAA4B;AAC7E,QAAM,WAAWE,MAAK,KAAK,SAAS;AACpC,MAAI,CAACC,YAAW,QAAQ,GAAG;AACzB,UAAM,MAAM,UAAU,EAAE,WAAW,KAAK,CAAC;AAAA,EAC3C;AACA,QAAM,UAAUD,MAAK,UAAU,iBAAiB,GAAG,KAAK,OAAO;AACjE;AAGA,eAAsB,gBAAgB,KAAqC;AACzE,QAAM,WAAWA,MAAK,KAAK,WAAW,iBAAiB;AACvD,MAAI,CAACC,YAAW,QAAQ,EAAG,QAAO;AAClC,MAAI;AACF,UAAM,OAAO,MAAMC,UAAS,UAAU,OAAO,GAAG,KAAK;AACrD,WAAO,OAAO;AAAA,EAChB,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAYA,eAAsB,kBACpB,KACA,QACe;AACf,QAAM,WAAWF,MAAK,KAAK,SAAS;AACpC,MAAI,CAACC,YAAW,QAAQ,GAAG;AACzB,UAAM,MAAM,UAAU,EAAE,WAAW,KAAK,CAAC;AAAA,EAC3C;AACA,QAAM;AAAA,IACJD,MAAK,UAAU,WAAW;AAAA,IAC1B,KAAK,UAAU,QAAQ,MAAM,CAAC;AAAA,IAC9B;AAAA,EACF;AACF;AAGA,eAAsB,kBACpB,KAC+B;AAC/B,QAAM,WAAWA,MAAK,KAAK,WAAW,WAAW;AACjD,MAAI,CAACC,YAAW,QAAQ,EAAG,QAAO;AAClC,MAAI;AACF,UAAM,OAAO,MAAMC,UAAS,UAAU,OAAO;AAC7C,WAAO,KAAK,MAAM,IAAI;AAAA,EACxB,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAQA,eAAsB,cACpB,UACwB;AACxB,MAAI,SAAU,QAAO;AACrB,MAAI,QAAQ,IAAI,eAAgB,QAAO,QAAQ,IAAI;AACnD,QAAM,SAAS,MAAM,kBAAkB,QAAQ,IAAI,CAAC;AACpD,SAAO,QAAQ,UAAU;AAC3B;;;AC1JO,SAAS,kBAAkB,cAA+B;AAC/D,MAAI,cAAc;AAChB,WAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAoBT;AAEA,SAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAWT;AAGO,SAAS,gBAAgB,cAA+B;AAC7D,MAAI,cAAc;AAChB,WAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAwBT;AAEA,SAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAcT;AAGO,SAAS,eAAe,cAA+B;AAC5D,MAAI,cAAc;AAChB,WAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAiBT;AAEA,SAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAgBT;;;AH3GA,IAAM,gBAAgB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAYf,IAAM,cAAc,IAAI,QAAQ,MAAM,EAC1C,YAAY,2CAA2C,EACvD,OAAO,gBAAgB,qBAAqB,QAAQ,IAAI,CAAC,EACzD,OAAO,WAAW,4BAA4B,KAAK,EACnD,OAAO,UAAU,2DAA2D,KAAK,EACjF,OAAO,OAAO,SAAS;AACtB,QAAM,MAAM,KAAK;AACjB,QAAM,UAAU,IAAI,sBAAsB,EAAE,MAAM;AAGlD,QAAM,UAAU,MAAM,cAAc,GAAG;AAEvC,MAAI,CAAC,QAAQ,UAAU;AACrB,YAAQ,KAAK,uBAAuB;AACpC,YAAQ;AAAA,MACN,MAAM,IAAI,oDAAoD;AAAA,IAChE;AACA,YAAQ;AAAA,MACN,MAAM,IAAI,4DAA4D;AAAA,IACxE;AACA,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,UAAQ;AAAA,IACN,oBAAoB,QAAQ,eAAe,EAAE,KAAK,QAAQ,gBAAgB,eAAe,cAAc;AAAA,EACzG;AAEA,QAAM,MAAM,QAAQ,eAAe,OAAO;AAC1C,QAAM,eAAyB,CAAC;AAGhC,MAAI,CAAC,QAAQ,gBAAgB,KAAK,OAAO;AACvC,UAAM,aAAaC,MAAK,KAAK,cAAc,GAAG,EAAE;AAChD,UAAMC,WAAU,YAAY,kBAAkB,QAAQ,YAAY,GAAG,OAAO;AAC5E,iBAAa,KAAK,cAAc,GAAG,EAAE;AACrC,YAAQ,IAAI,MAAM,MAAM,UAAK,IAAI,yBAAyB,GAAG,EAAE;AAAA,EACjE,OAAO;AACL,YAAQ,IAAI,MAAM,IAAI,kBAAkB,GAAG,wBAAwB,CAAC;AAAA,EACtE;AAGA,MAAI,CAAC,QAAQ,cAAc,KAAK,OAAO;AACrC,UAAM,cAAcD,MAAK,KAAK,QAAQ,QAAQ,WAAW,GAAG,EAAE;AAC9D,UAAMC,WAAU,aAAa,gBAAgB,QAAQ,YAAY,GAAG,OAAO;AAC3E,iBAAa,KAAK,GAAG,QAAQ,MAAM,YAAY,GAAG,EAAE;AACpD,YAAQ,IAAI,MAAM,MAAM,UAAK,IAAI,cAAc,QAAQ,MAAM,YAAY,GAAG,EAAE;AAAA,EAChF,OAAO;AACL,YAAQ,IAAI,MAAM,IAAI,mCAAmC,CAAC;AAAA,EAC5D;AAGA,MAAI,CAAC,QAAQ,aAAa,KAAK,OAAO;AACpC,UAAM,aAAaD,MAAK,KAAK,QAAQ,QAAQ,UAAU,GAAG,EAAE;AAC5D,UAAMC,WAAU,YAAY,eAAe,QAAQ,YAAY,GAAG,OAAO;AACzE,iBAAa,KAAK,GAAG,QAAQ,MAAM,WAAW,GAAG,EAAE;AACnD,YAAQ,IAAI,MAAM,MAAM,UAAK,IAAI,cAAc,QAAQ,MAAM,WAAW,GAAG,EAAE;AAAA,EAC/E,OAAO;AACL,YAAQ,IAAI,MAAM,IAAI,kCAAkC,CAAC;AAAA,EAC3D;AAGA,QAAM,SAASD,MAAK,KAAK,MAAM;AAC/B,QAAM,SAASE,YAAW,MAAM;AAEhC,MAAI,KAAK,QAAQ,KAAK,OAAO;AAC3B,QAAI,CAAC,QAAQ;AACX,cAAQ,IAAI,MAAM,OAAO,UAAK,IAAI,mDAA8C;AAAA,IAClF,OAAO;AACL,YAAM,WAAWF,MAAK,QAAQ,OAAO;AACrC,YAAM,WAAWA,MAAK,UAAU,UAAU;AAG1C,UAAIE,YAAW,QAAQ,KAAK,CAAC,KAAK,OAAO;AACvC,cAAM,WAAW,MAAMC,UAAS,UAAU,OAAO;AACjD,YAAI,SAAS,SAAS,QAAQ,GAAG;AAC/B,kBAAQ,IAAI,MAAM,IAAI,4CAA4C,CAAC;AAAA,QACrE,OAAO;AACL,kBAAQ,IAAI,MAAM,OAAO,UAAK,IAAI,0DAA0D;AAAA,QAC9F;AAAA,MACF,OAAO;AACL,cAAMC,OAAM,UAAU,EAAE,WAAW,KAAK,CAAC;AACzC,cAAMH,WAAU,UAAU,eAAe,EAAE,MAAM,IAAM,CAAC;AACxD,qBAAa,KAAK,qBAAqB;AACvC,gBAAQ,IAAI,MAAM,MAAM,UAAK,IAAI,8BAA8B;AAAA,MACjE;AAAA,IACF;AAAA,EACF,WAAW,QAAQ;AACjB,YAAQ,IAAI,MAAM,IAAI,8CAA8C,CAAC;AAAA,EACvE;AAGA,QAAM,cAAc,MAAM,gBAAgB,GAAG;AAC7C,MAAI,CAAC,eAAe,KAAK,OAAO;AAC9B,UAAM,MAAM,oBAAoB;AAChC,UAAM,YAAYD,MAAK,KAAK,QAAQ;AACpC,QAAI,CAACE,YAAW,SAAS,GAAG;AAC1B,YAAME,OAAM,WAAW,EAAE,WAAW,KAAK,CAAC;AAAA,IAC5C;AACA,UAAMH,WAAUD,MAAK,WAAW,GAAG,GAAG,MAAM,GAAG,KAAK,OAAO;AAC3D,UAAM,gBAAgB,KAAK,GAAG;AAC9B,iBAAa,KAAK,UAAU,GAAG,MAAM;AACrC,YAAQ,IAAI,MAAM,MAAM,UAAK,IAAI,+EAA0E;AAAA,EAC7G,OAAO;AAEL,UAAM,UAAUA,MAAK,KAAK,UAAU,GAAG,WAAW,MAAM;AACxD,QAAIE,YAAW,OAAO,GAAG;AACvB,cAAQ,IAAI,MAAM,IAAI,oCAAoC,CAAC;AAAA,IAC7D,OAAO;AACL,YAAM,YAAYF,MAAK,KAAK,QAAQ;AACpC,UAAI,CAACE,YAAW,SAAS,GAAG;AAC1B,cAAME,OAAM,WAAW,EAAE,WAAW,KAAK,CAAC;AAAA,MAC5C;AACA,YAAMH,WAAU,SAAS,aAAa,OAAO;AAC7C,mBAAa,KAAK,UAAU,WAAW,MAAM;AAC7C,cAAQ,IAAI,MAAM,MAAM,UAAK,IAAI,6BAA6B;AAAA,IAChE;AAAA,EACF;AAGA,UAAQ,IAAI,EAAE;AACd,MAAI,aAAa,SAAS,GAAG;AAC3B,YAAQ;AAAA,MACN,MAAM,KAAK,KAAK,aAAa,MAAM,QAAQ,aAAa,SAAS,IAAI,MAAM,EAAE,WAAW;AAAA,IAC1F;AAAA,EACF,OAAO;AACL,YAAQ,IAAI,MAAM,IAAI,qDAAgD,CAAC;AACvE,YAAQ,IAAI,MAAM,IAAI,6BAA6B,CAAC;AAAA,EACtD;AAEA,UAAQ,IAAI,EAAE;AACd,UAAQ,IAAI,MAAM,IAAI,eAAe,CAAC;AACtC,UAAQ,IAAI,MAAM,IAAI,0BAA0B,GAAG,yBAAyB,CAAC;AAC7E,UAAQ,IAAI,MAAM,IAAI,aAAa,IAAI,MAAM,KAAK,kBAAkB,IAAI,MAAM,IAAI,sBAAsB,CAAC;AACzG,MAAI,CAAC,KAAK,QAAQ,QAAQ;AACxB,YAAQ,IAAI,MAAM,IAAI,aAAa,IAAI,MAAM,KAAK,wBAAwB,IAAI,MAAM,IAAI,sBAAsB,CAAC;AAAA,EACjH;AACA,UAAQ,IAAI,EAAE;AACd,UAAQ,IAAI,MAAM,IAAI,+BAA+B,CAAC;AACtD,UAAQ,IAAI,MAAM,IAAI,UAAU,IAAI,MAAM,KAAK,iBAAiB,IAAI,MAAM,IAAI,6BAA6B,CAAC;AAC5G,UAAQ,IAAI,EAAE;AAChB,CAAC;;;AItKH,SAAS,WAAAI,gBAAe;AACxB,OAAOC,YAAW;AAClB,OAAOC,UAAS;AAChB,SAAS,wBAAwB;;;ACHjC,SAAS,YAAAC,iBAAgB;AACzB,SAAS,QAAAC,OAAgB,SAAS,WAAW;AAC7C,SAAS,YAAY;AAwBrB,eAAsB,UACpB,aACA,QACqB;AACrB,QAAM,aAAaA,MAAK,aAAa,MAAM;AAG3C,QAAM,YAAY,MAAM,KAAK,2BAA2B;AAAA,IACtD,KAAK;AAAA,IACL,QAAQ,CAAC,sBAAsB,UAAU;AAAA,EAC3C,CAAC;AAED,QAAM,QAAoB,CAAC;AAE3B,aAAW,QAAQ,WAAW;AAC5B,UAAM,WAAWA,MAAK,YAAY,IAAI;AACtC,UAAM,UAAU,MAAMD,UAAS,UAAU,OAAO;AAChD,UAAM,QAAQ,gBAAgB,IAAI;AAClC,UAAM,WAAW,kBAAkB,OAAO;AAE1C,UAAM,OAAiB;AAAA,MACrB,UAAUC,MAAK,QAAQ,IAAI;AAAA,MAC3B;AAAA,MACA,aAAa;AAAA,MACb,oBAAoB;AAAA,MACpB,mBAAmB;AAAA,MACnB,iBAAiB;AAAA,MACjB,mBAAmB,oBAAoB;AAAA,IACzC;AAGA,SAAK,qBAAqB,UAAU,SAAS,kBAAkB;AAC/D,SAAK,cAAc,KAAK,sBAAsB,UAAU,SAAS,UAAU;AAG3E,QAAI,KAAK,oBAAoB;AAAA,IAG7B,WAAW,CAAC,YAAY,KAAK,aAAa;AAGxC,WAAK,oBAAoB,sBAAsB,OAAO;AAEtD,YAAM,YAAY,kBAAkB,OAAO;AAC3C,UAAI,aAAa,uBAAuB,KAAK,SAAS,GAAG;AACvD,aAAK,kBAAkB;AAAA,MACzB;AAAA,IACF;AAEA,UAAM,KAAK,IAAI;AAAA,EACjB;AAGA,QAAM,cAAc,MAAM,KAAK,6BAA6B;AAAA,IAC1D,KAAK;AAAA,IACL,QAAQ,CAAC,sBAAsB,UAAU;AAAA,EAC3C,CAAC;AAID,QAAM,gBAAgB,YAAY,KAAK,CAAC,GAAG,MAAM;AAC/C,UAAM,SAAS,EAAE,MAAM,GAAG,EAAE;AAC5B,UAAM,SAAS,EAAE,MAAM,GAAG,EAAE;AAC5B,WAAO,SAAS;AAAA,EAClB,CAAC;AAED,aAAW,QAAQ,eAAe;AAChC,UAAM,WAAWA,MAAK,YAAY,IAAI;AACtC,UAAM,UAAU,MAAMD,UAAS,UAAU,OAAO;AAChD,UAAM,QAAQ,gBAAgB,IAAI,EAAE,QAAQ,aAAa,EAAE,KAAK;AAEhE,UAAM,oBAAoB,UAAU,SAAS,UAAU,KAAK,UAAU,SAAS,kBAAkB;AACjG,QAAI,mBAAmB;AACrB,YAAM,aAAa,sBAAsB,OAAO;AAGhD,YAAM,gBAAgB,QAAQ,MAAM,oCAAoC;AACxE,YAAM,gBAAgB,gBAAgB,CAAC,KAAK;AAE5C,iBAAW,QAAQ,OAAO;AACxB,YAAI,KAAK,MAAM,WAAW,KAAK,KAAK,UAAU,KAAK;AAEjD,cAAI,KAAK,kBAAkB,SAAS,iBAAiB,CAAC,KAAK,iBAAiB;AAC1E,iBAAK,kBAAkB,QAAQ,cAAc,QAAQ,MAAM,KAAK,kBAAkB,KAAK;AACvF,iBAAK,kBAAkB;AAAA,UACzB;AAGA,wBAAc,KAAK,mBAAmB,UAAU;AAChD,cAAI,CAAC,KAAK,aAAa;AACrB,iBAAK,cAAc;AAAA,UACrB;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,SAAO,MAAM,KAAK,CAAC,GAAG,MAAM,EAAE,MAAM,cAAc,EAAE,KAAK,CAAC;AAC5D;AAGA,SAAS,gBAAgB,UAA0B;AACjD,QAAM,MAAM,QAAQ,QAAQ;AAC5B,MAAI,QAAQ,IAAK,QAAO;AAExB,QAAM,QAAQ,MAAM,IAAI,MAAM,GAAG,EAAE,KAAK,GAAG;AAE3C,SAAO,MAAM,QAAQ,gBAAgB,EAAE,KAAK;AAC9C;AAGA,SAAS,kBAAkB,QAAyB;AAElD,SAAO,2BAA2B,KAAK,MAAM;AAC/C;AAGA,SAAS,UAAU,QAAgB,MAAuB;AAExD,QAAM,WAAW;AAAA,IACf,IAAI,OAAO,gCAAgC,IAAI,KAAK;AAAA,IACpD,IAAI,OAAO,qCAAqC,IAAI,KAAK;AAAA,IACzD,IAAI,OAAO,wBAAwB,IAAI,aAAa;AAAA,EACtD;AACA,SAAO,SAAS,KAAK,CAAC,MAAM,EAAE,KAAK,MAAM,CAAC;AAC5C;AAMA,SAAS,kBAAkB,QAA+B;AACxD,QAAM,QAAQ,OAAO,MAAM,0CAA0C;AACrE,MAAI,CAAC,SAAS,MAAM,UAAU,OAAW,QAAO;AAEhD,QAAM,QAAQ,OAAO,QAAQ,KAAK,MAAM,KAAK;AAC7C,MAAI,UAAU,GAAI,QAAO;AAEzB,MAAI,QAAQ;AACZ,WAAS,IAAI,OAAO,IAAI,OAAO,QAAQ,KAAK;AAC1C,QAAI,OAAO,CAAC,MAAM,IAAK;AAAA,aACd,OAAO,CAAC,MAAM,KAAK;AAC1B;AACA,UAAI,UAAU,EAAG,QAAO,OAAO,UAAU,OAAO,IAAI,CAAC;AAAA,IACvD;AAAA,EACF;AACA,SAAO;AACT;AAMA,SAAS,sBAAsB,QAAkC;AAC/D,QAAM,OAAO,oBAAoB;AAIjC,QAAM,YAAY,kBAAkB,MAAM,KAAK;AAM/C,QAAM,gBAAgB,UAAU;AAAA,IAC9B;AAAA,EACF;AACA,MAAI,eAAe;AACjB,SAAK,QAAQ,cAAc,CAAC;AAAA,EAC9B,OAAO;AACL,UAAM,eAAe,UAAU;AAAA,MAC7B;AAAA,IACF;AACA,QAAI,cAAc;AAChB,WAAK,QAAQ,aAAa,CAAC;AAAA,IAC7B,OAAO;AAEL,YAAM,aAAa,UAAU;AAAA,QAC3B;AAAA,MACF;AACA,UAAI,YAAY;AACd,aAAK,QAAQ,WAAW,CAAC;AAAA,MAC3B;AAAA,IACF;AAAA,EACF;AAGA,QAAM,YAAY,UAAU;AAAA,IAC1B;AAAA,EACF;AACA,MAAI,WAAW;AACb,SAAK,cAAc,UAAU,CAAC;AAAA,EAChC;AAGA,MAAI,qBAAqB,KAAK,SAAS,GAAG;AACxC,UAAM,eAAe,UAAU;AAAA,MAC7B;AAAA,IACF;AACA,QAAI,aAAc,MAAK,UAAU,aAAa,CAAC;AAE/C,UAAM,cAAc,UAAU;AAAA,MAC5B;AAAA,IACF;AACA,QAAI,YAAa,MAAK,gBAAgB,YAAY,CAAC;AAEnD,QAAI,kBAAkB,KAAK,SAAS,GAAG;AACrC,WAAK,UAAU;AAAA,IACjB;AAAA,EACF;AAGA,MAAI,mBAAmB,KAAK,SAAS,GAAG;AACtC,UAAM,YAAY,UAAU;AAAA,MAC1B;AAAA,IACF;AACA,QAAI,UAAW,MAAK,cAAc,UAAU,CAAC;AAAA,EAC/C;AAGA,MAAI,kBAAkB,KAAK,SAAS,KAAK,qBAAqB,KAAK,SAAS,GAAG;AAC7E,UAAM,cAAc,UAAU;AAAA,MAC5B;AAAA,IACF;AACA,QAAI,YAAa,MAAK,SAAS,YAAY,CAAC;AAAA,EAC9C;AAGA,MAAI,sBAAsB,KAAK,SAAS,GAAG;AACzC,UAAM,iBAAiB,UAAU;AAAA,MAC/B;AAAA,IACF;AACA,QAAI,eAAgB,MAAK,YAAY,eAAe,CAAC;AAGrD,QAAI,qBAAqB,KAAK,SAAS,GAAG;AACxC,YAAM,QAAgC,CAAC;AACvC,YAAM,cAAc,UAAU;AAAA,QAC5B;AAAA,MACF;AACA,iBAAW,KAAK,aAAa;AAC3B,YAAI,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,EAAE,CAAC,EAAE,WAAW,MAAM,GAAG;AAC3C,gBAAM,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;AAAA,QACnB;AAAA,MACF;AACA,UAAI,OAAO,KAAK,KAAK,EAAE,SAAS,GAAG;AACjC,aAAK,aAAa;AAAA,MACpB;AAAA,IACF;AAAA,EACF;AAGA,MAAI,wBAAwB,KAAK,MAAM,KAAK,aAAa,KAAK,MAAM,KAAK,SAAS,KAAK,MAAM,GAAG;AAC9F,SAAK,iBAAiB,CAAC,EAAE,YAAY,sBAAsB,SAAS,WAAW,CAAC;AAAA,EAClF;AAGA,MAAI,kBAAkB,KAAK,MAAM,GAAG;AAClC,SAAK,WAAW;AAAA,EAClB;AAGA,MAAI,iBAAiB,KAAK,SAAS,KAAK,UAAU,KAAK,SAAS,GAAG;AACjE,SAAK,UAAU;AAAA,EACjB;AAEA,SAAO;AACT;AAEA,SAAS,sBAAwC;AAC/C,SAAO;AAAA,IACL,OAAO;AAAA,IACP,aAAa;AAAA,IACb,WAAW;AAAA,IACX,SAAS;AAAA,IACT,eAAe;AAAA,IACf,SAAS;AAAA,IACT,QAAQ;AAAA,IACR,aAAa;AAAA,IACb,cAAc;AAAA,IACd,oBAAoB;AAAA,IACpB,QAAQ;AAAA,IACR,YAAY;AAAA,IACZ,gBAAgB;AAAA,IAChB,UAAU;AAAA,IACV,SAAS;AAAA,EACX;AACF;AAGA,SAAS,cAAc,QAA0B,QAAgC;AAC/E,aAAW,OAAO,OAAO,KAAK,MAAM,GAAiC;AACnE,QAAI,OAAO,GAAG,MAAM,QAAQ,OAAO,GAAG,MAAM,QAAW;AACrD,MAAC,OAAmC,GAAG,IAAI,OAAO,GAAG;AAAA,IACvD;AAAA,EACF;AACF;;;AClUA,SAAS,cAAAE,mBAAkB;AAC3B,SAAS,YAAAC,iBAAgB;AACzB,SAAS,QAAAC,aAAY;AAarB,IAAM,eAAe,CAAC,kBAAkB,aAAa,oBAAoB;AAMzE,eAAsB,WAAW,KAAoC;AACnE,aAAW,QAAQ,cAAc;AAC/B,UAAM,OAAOA,MAAK,KAAK,IAAI;AAC3B,QAAIF,YAAW,IAAI,GAAG;AACpB,UAAI;AACF,cAAM,UAAU,MAAMC,UAAS,MAAM,OAAO;AAC5C,eAAO,KAAK,MAAM,OAAO;AAAA,MAC3B,QAAQ;AAAA,MAER;AAAA,IACF;AAAA,EACF;AACA,SAAO,CAAC;AACV;;;AClCA,OAAOE,YAAW;AAwBX,SAAS,iBAAiB,QAA6B;AAC5D,QAAM,EAAE,MAAM,WAAW,IAAI;AAC7B,QAAM,QAAkB,CAAC;AAEzB,QAAMC,cAAa,cAAc,WAAW,KAAK;AACjD,QAAM,OAAO,WAAW,OAAO,SAAS,IAAID,OAAM,IAAI,GAAG,IAAIA,OAAM,MAAM,QAAG;AAE5E,QAAM;AAAA,IACJ,KAAK,IAAI,IAAIA,OAAM,KAAK,KAAK,KAAK,CAAC,KAAKC,YAAW,GAAG,WAAW,KAAK,MAAM,CAAC;AAAA,EAC/E;AAGA,aAAW,SAAS,WAAW,QAAQ;AACrC,UAAM,KAAK,OAAOD,OAAM,IAAI,GAAG,CAAC,IAAI,MAAM,WAAW,MAAM,IAAI,EAAE;AAAA,EACnE;AAGA,MAAI,WAAW,OAAO,SAAS,GAAG;AAChC,eAAW,WAAW,WAAW,UAAU;AACzC,YAAM,KAAK,OAAOA,OAAM,OAAO,GAAG,CAAC,IAAI,QAAQ,WAAW,QAAQ,IAAI,EAAE;AAAA,IAC1E;AAAA,EACF;AAEA,SAAO,MAAM,KAAK,IAAI;AACxB;AAGO,SAAS,cAAc,SAA+B;AAC3D,QAAM,QAAkB,CAAC;AACzB,QAAM,EAAE,YAAY,aAAa,cAAc,eAAe,IAAI;AAElE,QAAM,KAAK,EAAE;AACb,QAAM,KAAKA,OAAM,IAAI,kOAAyC,CAAC;AAC/D,QAAM,KAAK,EAAE;AAGb,QAAMC,cAAa,cAAc,YAAY;AAC7C,QAAM;AAAA,IACJ,YAAYA,YAAWD,OAAM,KAAK,GAAG,YAAY,MAAM,CAAC,CAAC,KAAK,QAAQ,KAAK;AAAA,EAC7E;AAGA,QAAM,aAAa,gBAAgB,aAAaA,OAAM,QAAQA,OAAM;AACpE,QAAM;AAAA,IACJ,YAAY,WAAW,GAAG,WAAW,IAAI,UAAU,EAAE,CAAC;AAAA,EACxD;AAGA,MAAI,iBAAiB,GAAG;AACtB,UAAM,KAAK,EAAE;AACb,UAAM;AAAA,MACJA,OAAM,IAAI,KAAK,cAAc,kBAAkB,iBAAiB,IAAI,MAAM,EAAE,yBAAyB;AAAA,IACvG;AACA,QAAI,QAAQ,iBAAiB,GAAG;AAC9B,YAAM;AAAA,QACJA,OAAM,OAAO,KAAK,QAAQ,cAAc,kBAAkB,QAAQ,iBAAiB,IAAI,MAAM,EAAE,oBAAoB;AAAA,MACrH;AAAA,IACF;AAAA,EACF,WAAW,QAAQ,iBAAiB,GAAG;AACrC,UAAM,KAAK,EAAE;AACb,UAAM,KAAKA,OAAM,OAAO,KAAK,QAAQ,cAAc,kBAAkB,QAAQ,iBAAiB,IAAI,MAAM,EAAE,oBAAoB,CAAC;AAAA,EACjI,OAAO;AACL,UAAM,KAAK,EAAE;AACb,UAAM,KAAKA,OAAM,MAAM,4BAA4B,CAAC;AAAA,EACtD;AAGA,MAAI,QAAQ,iBAAiB,GAAG;AAC9B,UAAM,KAAK,EAAE;AACb,UAAM;AAAA,MACJA,OAAM;AAAA,QACJ,KAAK,QAAQ,cAAc,gBAAgB,QAAQ,iBAAiB,IAAI,MAAM,EAAE;AAAA,MAClF;AAAA,IACF;AACA,UAAM,KAAKA,OAAM,IAAI,kEAAkE,CAAC;AAAA,EAC1F;AAEA,QAAM,KAAK,EAAE;AACb,SAAO,MAAM,KAAK,IAAI;AACxB;AAGO,SAAS,WAAW,SAA+B;AACxD,SAAO,KAAK;AAAA,IACV;AAAA,MACE,OAAO,QAAQ;AAAA,MACf,OAAO,QAAQ;AAAA,MACf,YAAY,QAAQ;AAAA,MACpB,aAAa,QAAQ;AAAA,MACrB,gBAAgB,QAAQ;AAAA,MACxB,gBAAgB,QAAQ;AAAA,MACxB,gBAAgB,QAAQ;AAAA,MACxB,OAAO,QAAQ,QAAQ,IAAI,CAAC,OAAO;AAAA,QACjC,OAAO,EAAE,KAAK;AAAA,QACd,MAAM,EAAE,KAAK;AAAA,QACb,OAAO,EAAE,WAAW;AAAA,QACpB,OAAO,EAAE,WAAW;AAAA,QACpB,QAAQ,EAAE,WAAW,OAAO,IAAI,CAAC,OAAO;AAAA,UACtC,IAAI,EAAE;AAAA,UACN,SAAS,EAAE;AAAA,QACb,EAAE;AAAA,QACF,UAAU,EAAE,WAAW,SAAS,IAAI,CAAC,OAAO;AAAA,UAC1C,IAAI,EAAE;AAAA,UACN,SAAS,EAAE;AAAA,QACb,EAAE;AAAA,MACJ,EAAE;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAGO,SAAS,WACd,SACA,UACQ;AACR,QAAM,QAAkB,CAAC;AAEzB,QAAM,KAAK,EAAE;AACb,QAAM,KAAKA,OAAM,KAAK,aAAa,CAAC;AACpC,QAAM,KAAK,EAAE;AAEb,QAAM,aAAa,QAAQ,eAAe,SAAS;AACnD,QAAM,aAAa,aAAa,IAAIA,OAAM,MAAM,IAAI,UAAU,EAAE,IAAI,aAAa,IAAIA,OAAM,IAAI,GAAG,UAAU,EAAE,IAAIA,OAAM,IAAI,GAAG;AAC/H,QAAM;AAAA,IACJ,YAAY,SAAS,YAAY,OAAO,QAAQ,YAAY,KAAK,UAAU;AAAA,EAC7E;AACA,QAAM,KAAK,EAAE;AAGb,QAAM,UAAU,IAAI,IAAI,SAAS,QAAQ,IAAI,CAAC,MAAM,CAAC,EAAE,KAAK,OAAO,CAAC,CAAC,CAAC;AACtE,QAAM,UAAU,IAAI,IAAI,QAAQ,QAAQ,IAAI,CAAC,MAAM,CAAC,EAAE,KAAK,OAAO,CAAC,CAAC,CAAC;AAGrE,QAAM,cAAwB,CAAC;AAC/B,aAAW,CAAC,OAAO,IAAI,KAAK,SAAS;AACnC,UAAM,OAAO,QAAQ,IAAI,KAAK;AAC9B,QAAI,CAAC,KAAM;AACX,QAAI,KAAK,WAAW,QAAQ,KAAK,WAAW,OAAO;AACjD,kBAAY;AAAA,QACV,OAAOA,OAAM,IAAI,GAAG,CAAC,IAAI,KAAK,KAAK,KAAK,WAAW,KAAK,OAAO,KAAK,WAAW,KAAK;AAAA,MACtF;AAAA,IACF;AAAA,EACF;AAGA,QAAM,eAAyB,CAAC;AAChC,aAAW,CAAC,OAAO,IAAI,KAAK,SAAS;AACnC,UAAM,OAAO,QAAQ,IAAI,KAAK;AAC9B,QAAI,CAAC,KAAM;AACX,QAAI,KAAK,WAAW,QAAQ,KAAK,WAAW,OAAO;AACjD,mBAAa;AAAA,QACX,OAAOA,OAAM,MAAM,GAAG,CAAC,IAAI,KAAK,KAAK,KAAK,WAAW,KAAK,OAAO,KAAK,WAAW,KAAK;AAAA,MACxF;AAAA,IACF;AAAA,EACF;AAGA,QAAM,WAAqB,CAAC;AAC5B,aAAW,SAAS,QAAQ,KAAK,GAAG;AAClC,QAAI,CAAC,QAAQ,IAAI,KAAK,GAAG;AACvB,eAAS,KAAK,OAAOA,OAAM,KAAK,GAAG,CAAC,IAAI,KAAK,KAAKA,OAAM,IAAI,OAAO,CAAC,EAAE;AAAA,IACxE;AAAA,EACF;AAGA,QAAM,UAAoB,CAAC;AAC3B,aAAW,SAAS,QAAQ,KAAK,GAAG;AAClC,QAAI,CAAC,QAAQ,IAAI,KAAK,GAAG;AACvB,cAAQ,KAAK,OAAOA,OAAM,IAAI,GAAG,CAAC,IAAI,KAAK,KAAKA,OAAM,IAAI,WAAW,CAAC,EAAE;AAAA,IAC1E;AAAA,EACF;AAEA,MAAI,YAAY,SAAS,GAAG;AAC1B,UAAM,KAAKA,OAAM,IAAI,kBAAkB,YAAY,MAAM,IAAI,CAAC;AAC9D,UAAM,KAAK,GAAG,WAAW;AACzB,UAAM,KAAK,EAAE;AAAA,EACf;AAEA,MAAI,aAAa,SAAS,GAAG;AAC3B,UAAM,KAAKA,OAAM,MAAM,mBAAmB,aAAa,MAAM,IAAI,CAAC;AAClE,UAAM,KAAK,GAAG,YAAY;AAC1B,UAAM,KAAK,EAAE;AAAA,EACf;AAEA,MAAI,SAAS,SAAS,GAAG;AACvB,UAAM,KAAKA,OAAM,KAAK,gBAAgB,SAAS,MAAM,IAAI,CAAC;AAC1D,UAAM,KAAK,GAAG,QAAQ;AACtB,UAAM,KAAK,EAAE;AAAA,EACf;AAEA,MAAI,QAAQ,SAAS,GAAG;AACtB,UAAM,KAAKA,OAAM,IAAI,cAAc,QAAQ,MAAM,IAAI,CAAC;AACtD,UAAM,KAAK,GAAG,OAAO;AACrB,UAAM,KAAK,EAAE;AAAA,EACf;AAEA,MAAI,YAAY,WAAW,KAAK,aAAa,WAAW,KAAK,SAAS,WAAW,KAAK,QAAQ,WAAW,GAAG;AAC1G,UAAM,KAAKA,OAAM,IAAI,wBAAwB,CAAC;AAC9C,UAAM,KAAK,EAAE;AAAA,EACf;AAEA,SAAO,MAAM,KAAK,IAAI;AACxB;AAGO,SAAS,kBAAkB,MAA+C;AAC/E,SAAO,KAAKA,OAAM,KAAK,GAAG,CAAC,IAAIA,OAAM,KAAK,KAAK,KAAK,CAAC,KAAKA,OAAM,IAAI,mCAA8B,CAAC;AACrG;AAGA,SAAS,cAAc,OAAyC;AAC9D,MAAI,SAAS,GAAI,QAAOA,OAAM;AAC9B,MAAI,SAAS,GAAI,QAAOA,OAAM;AAC9B,SAAOA,OAAM;AACf;AAGO,SAAS,eAAe,SAAwB,iBAAiB,GAAiB;AACvF,QAAM,aAAa,QAAQ,SAAS;AACpC,QAAM,cAAc,QAAQ,OAAO,CAAC,MAAM,EAAE,WAAW,OAAO,WAAW,CAAC,EAAE;AAC5E,QAAM,eACJ,QAAQ,SAAS,IACb,KAAK,MAAM,QAAQ,OAAO,CAAC,KAAK,MAAM,MAAM,EAAE,WAAW,OAAO,CAAC,IAAI,QAAQ,MAAM,IACnF;AAEN,MAAI,iBAAiB;AACrB,MAAI,iBAAiB;AACrB,aAAW,KAAK,SAAS;AACvB,eAAW,KAAK,EAAE,WAAW,QAAQ;AACnC,UAAI,EAAE,aAAa,WAAY;AAAA,UAC1B;AAAA,IACP;AAAA,EACF;AAEA,MAAI;AACJ,MAAI,gBAAgB,GAAI,SAAQ;AAAA,WACvB,gBAAgB,GAAI,SAAQ;AAAA,WAC5B,gBAAgB,GAAI,SAAQ;AAAA,WAC5B,gBAAgB,GAAI,SAAQ;AAAA,MAChC,SAAQ;AAEb,SAAO,EAAE,SAAS,YAAY,aAAa,cAAc,OAAO,gBAAgB,gBAAgB,eAAe;AACjH;;;AC5QA,OAAOE,YAAW;AAOX,SAAS,uBACd,SACA,SACU;AACV,QAAM,SAAmB,CAAC;AAC1B,QAAM,UAAU,WAAW;AAE3B,aAAW,EAAE,MAAM,WAAW,KAAK,SAAS;AAC1C,QAAI,WAAW,OAAO,WAAW,KAAK,WAAW,SAAS,WAAW,EAAG;AAExE,UAAM,WAAW,IAAI,IAAI,WAAW,OAAO,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC;AAC3D,UAAM,UAAU,IAAI,IAAI,WAAW,SAAS,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC;AAC5D,UAAM,SAAS,oBAAI,IAAI,CAAC,GAAG,UAAU,GAAG,OAAO,CAAC;AAGhD,UAAM,OAAgC,CAAC;AACvC,UAAM,SAAmB,CAAC;AAG1B,QAAI,OAAO,IAAI,eAAe,GAAG;AAC/B,YAAM,aAAa,aAAa,KAAK,KAAK;AAC1C,WAAK,QAAQ,EAAE,UAAU,WAAW;AAAA,IACtC,WAAW,OAAO,IAAI,cAAc,GAAG;AACrC,YAAM,UAAU,KAAK,kBAAkB,SAAS;AAChD,YAAM,MAAM,QAAQ;AACpB,UAAI,MAAM,IAAI;AACZ,eAAO,KAAK,KAAKA,OAAM,IAAI,iBAAiB,MAAM,+BAA0B,CAAC,EAAE;AAAA,MACjF,WAAW,MAAM,IAAI;AACnB,eAAO,KAAK,KAAKA,OAAM,IAAI,iBAAiB,MAAM,gCAA2B,CAAC,EAAE;AAAA,MAClF;AAAA,IACF;AAGA,QAAI,OAAO,IAAI,qBAAqB,GAAG;AACrC,WAAK,cAAc,mBAAmB,KAAK,KAAK;AAAA,IAClD,WAAW,OAAO,IAAI,oBAAoB,GAAG;AAC3C,YAAM,UAAU,KAAK,kBAAkB,eAAe;AACtD,YAAM,MAAM,QAAQ;AACpB,UAAI,MAAM,KAAK;AACb,eAAO,KAAK,KAAKA,OAAM,IAAI,uBAAuB,MAAM,iCAA4B,CAAC,EAAE;AAAA,MACzF,WAAW,MAAM,KAAK;AACpB,eAAO,KAAK,KAAKA,OAAM,IAAI,uBAAuB,MAAM,kCAA6B,CAAC,EAAE;AAAA,MAC1F;AAAA,IACF;AAGA,QAAI,OAAO,IAAI,eAAe,GAAG;AAC/B,YAAM,YAAY,GAAG,OAAO,GAAG,KAAK,UAAU,MAAM,KAAK,KAAK,KAAK;AACnE,WAAK,aAAa,EAAE,UAAU;AAAA,IAChC;AAGA,QAAI,OAAO,IAAI,UAAU,GAAG;AAC1B,WAAK,YAAY,EAAE,QAAQ,CAAC,GAAG,OAAO,eAAe,EAAE;AAAA,IACzD;AAGA,QAAI,OAAO,IAAI,yBAAyB,GAAG;AACzC,aAAO,KAAK,KAAKA,OAAM,IAAI,2DAA2D,CAAC,EAAE;AACzF,aAAO,KAAK,KAAKA,OAAM,IAAI,8EAA8E,CAAC,EAAE;AAAA,IAC9G;AAGA,QAAI,OAAO,IAAI,cAAc,GAAG;AAC9B,WAAK,UAAU,EAAE,MAAM,sBAAsB;AAAA,IAC/C;AAGA,QAAI,OAAO,KAAK,IAAI,EAAE,WAAW,KAAK,OAAO,WAAW,EAAG;AAE3D,WAAO,KAAKA,OAAM,KAAK,KAAKA,OAAM,KAAK,KAAK,QAAQ,CAAC,EAAE,CAAC;AAExD,QAAI,OAAO,KAAK,IAAI,EAAE,SAAS,GAAG;AAChC,YAAM,OAAO,qBAAqB,IAAI;AACtC,aAAO,KAAK,KAAKA,OAAM,IAAI,+BAA+B,CAAC,EAAE;AAC7D,aAAO,KAAK,EAAE;AACd,iBAAW,QAAQ,KAAK,MAAM,IAAI,GAAG;AACnC,eAAO,KAAK,OAAOA,OAAM,OAAO,IAAI,CAAC,EAAE;AAAA,MACzC;AAAA,IACF;AAEA,eAAW,SAAS,QAAQ;AAC1B,aAAO,KAAK,KAAK;AAAA,IACnB;AAEA,WAAO,KAAK,EAAE;AAAA,EAChB;AAEA,SAAO;AACT;AAGA,SAAS,aAAa,OAAuB;AAC3C,MAAI,UAAU,IAAK,QAAO;AAC1B,QAAM,WAAW,MAAM,MAAM,GAAG,EAAE,OAAO,OAAO;AAChD,QAAM,OAAO,SAAS,SAAS,SAAS,CAAC;AACzC,QAAM,OAAO,KACV,QAAQ,YAAY,EAAE,EACtB,QAAQ,MAAM,GAAG,EACjB,QAAQ,SAAS,CAAC,MAAM,EAAE,YAAY,CAAC,EACvC,KAAK;AACR,SAAO,GAAG,QAAQ,MAAM;AAC1B;AAGA,SAAS,mBAAmB,OAAuB;AACjD,MAAI,UAAU,KAAK;AACjB,WAAO;AAAA,EACT;AACA,QAAM,WAAW,MAAM,MAAM,GAAG,EAAE,OAAO,OAAO;AAChD,QAAM,OAAO,SAAS,SAAS,SAAS,CAAC;AACzC,QAAM,OAAO,KACV,QAAQ,YAAY,EAAE,EACtB,QAAQ,MAAM,GAAG,EACjB,KAAK;AACR,SAAO,oBAAoB,QAAQ,WAAW;AAChD;AAGA,SAAS,qBAAqB,MAAuC;AACnE,QAAM,QAAkB,CAAC,qCAAqC;AAE9D,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,IAAI,GAAG;AAC/C,QAAI,OAAO,UAAU,UAAU;AAC7B,YAAM,KAAK,KAAK,GAAG,MAAM,KAAK,IAAI;AAAA,IACpC,WAAW,OAAO,UAAU,YAAY,UAAU,MAAM;AACtD,YAAM,KAAK,KAAK,GAAG,KAAK,KAAK,UAAU,OAAO,MAAM,CAAC,EAAE,QAAQ,OAAO,MAAM,CAAC,GAAG;AAAA,IAClF;AAAA,EACF;AAEA,QAAM,KAAK,IAAI;AACf,SAAO,MAAM,KAAK,IAAI;AACxB;;;AJxHO,IAAM,eAAe,IAAIC,SAAQ,OAAO,EAC5C,YAAY,kDAAkD,EAC9D,OAAO,gBAAgB,qBAAqB,QAAQ,IAAI,CAAC,EACzD,OAAO,QAAQ,iDAA4C,KAAK,EAChE,OAAO,UAAU,mCAAmC,KAAK,EACzD,OAAO,UAAU,0BAA0B,KAAK,EAChD,OAAO,YAAY,4BAA4B,KAAK,EACpD,OAAO,uBAAuB,2DAA2D,EACzF,OAAO,SAAS,8CAA8C,KAAK,EACnE,OAAO,OAAO,SAAS;AACtB,QAAM,MAAM,KAAK;AACjB,QAAM,OAAO,KAAK;AAClB,QAAM,WAAW,KAAK,UAAU;AAChC,QAAM,WAAW,KAAK;AACtB,QAAM,aAAa,KAAK;AACxB,QAAM,UAAU,KAAK;AAGrB,QAAM,SAAS,MAAM,WAAW,GAAG;AAGnC,QAAM,WAAW,KAAK,WAClB,SAAS,KAAK,UAAU,EAAE,IAC1B,OAAO,YAAY;AAGvB,QAAM,UAAUC,KAAI,sBAAsB,EAAE,MAAM;AAClD,QAAM,UAAU,MAAM,cAAc,GAAG;AAEvC,MAAI,CAAC,QAAQ,UAAU;AACrB,YAAQ,KAAK,uBAAuB;AACpC,QAAI,CAAC,YAAY;AACf,cAAQ,IAAIC,OAAM,IAAI,iDAAiD,CAAC;AAAA,IAC1E;AACA,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,MAAI,CAAC,QAAQ,eAAe;AAC1B,YAAQ,KAAK,yBAAyB;AACtC,QAAI,CAAC,YAAY;AACf,cAAQ,IAAIA,OAAM,IAAI,kEAAkE,CAAC;AAAA,IAC3F;AACA,YAAQ,KAAK,CAAC;AAAA,EAChB;AAGA,UAAQ,OAAO;AACf,QAAM,WAAW,MAAM,UAAU,KAAK,QAAQ,MAAM;AAEpD,MAAI,SAAS,WAAW,GAAG;AACzB,YAAQ,KAAK,gBAAgB;AAC7B,QAAI,CAAC,YAAY;AACf,cAAQ,IAAIA,OAAM,IAAI,mCAAmC,QAAQ,MAAM,GAAG,CAAC;AAAA,IAC7E;AACA,YAAQ,KAAK,CAAC;AAAA,EAChB;AAGA,QAAM,eAAe,OAAO,gBAAgB,CAAC;AAC7C,QAAM,QAAQ,aAAa,SAAS,IAChC,SAAS,OAAO,CAAC,MAAM,CAAC,aAAa,KAAK,CAAC,YAAY,WAAW,EAAE,OAAO,OAAO,CAAC,CAAC,IACpF;AACJ,QAAM,eAAe,SAAS,SAAS,MAAM;AAE7C,UAAQ,QAAQ,SAAS,SAAS,MAAM,QAAQ,SAAS,SAAS,IAAI,MAAM,EAAE,GAAG,eAAe,IAAI,KAAK,YAAY,cAAc,EAAE,EAAE;AAGvI,QAAM,cAAc,MAAM,OAAO,CAAC,MAAM,CAAC,EAAE,kBAAkB;AAC7D,QAAM,eAAe,MAAM,OAAO,CAAC,MAAM,EAAE,kBAAkB;AAE7D,MAAI,CAAC,YAAY;AACf,YAAQ,IAAI,EAAE;AACd,YAAQ,IAAIA,OAAM,KAAK,cAAc,YAAY,MAAM,QAAQ,YAAY,WAAW,IAAI,MAAM,EAAE,KAAK,CAAC;AACxG,QAAI,aAAa,SAAS,GAAG;AAC3B,cAAQ,IAAIA,OAAM,IAAI,MAAM,aAAa,MAAM,gBAAgB,aAAa,WAAW,IAAI,MAAM,EAAE,WAAW,CAAC;AAAA,IACjH;AACA,QAAI,eAAe,GAAG;AACpB,cAAQ,IAAIA,OAAM,IAAI,MAAM,YAAY,QAAQ,iBAAiB,IAAI,MAAM,EAAE,4BAA4B,CAAC;AAAA,IAC5G;AACA,YAAQ,IAAI,EAAE;AAAA,EAChB;AAGA,QAAM,UAAyB,CAAC;AAEhC,aAAW,QAAQ,aAAa;AAC9B,UAAM,aAAa,iBAAiB,KAAK,mBAAmB;AAAA,MAC1D,QAAQ;AAAA,MACR,eAAe,OAAO;AAAA,IACxB,CAAC;AAED,UAAM,SAAsB,EAAE,MAAM,WAAW;AAC/C,YAAQ,KAAK,MAAM;AAEnB,QAAI,CAAC,YAAY;AACf,cAAQ,IAAI,iBAAiB,MAAM,CAAC;AAAA,IACtC;AAAA,EACF;AAGA,MAAI,CAAC,cAAc,aAAa,SAAS,GAAG;AAC1C,YAAQ,IAAI,EAAE;AACd,eAAW,QAAQ,cAAc;AAC/B,cAAQ,IAAI,kBAAkB,IAAI,CAAC;AAAA,IACrC;AAAA,EACF;AAGA,QAAM,UAAU,eAAe,SAAS,aAAa,MAAM;AAG3D,QAAM,gBAAgB,KAAK,OAAO;AAGlC,MAAI,YAAY,CAAC,YAAY;AAC3B,UAAM,WAAW,MAAM,kBAAkB,GAAG;AAC5C,QAAI,UAAU;AACZ,cAAQ,IAAI,WAAW,SAAS,SAAS,OAAO,CAAC;AAAA,IACnD,OAAO;AACL,cAAQ,IAAIA,OAAM,IAAI,yDAAyD,CAAC;AAAA,IAClF;AAAA,EACF;AAGA,MAAI,YAAY;AACd,YAAQ,IAAI,WAAW,OAAO,CAAC;AAAA,EACjC,OAAO;AACL,YAAQ,IAAI,cAAc,OAAO,CAAC;AAAA,EACpC;AAGA,MAAI,WAAW,CAAC,YAAY;AAC1B,UAAM,QAAQ,uBAAuB,SAAS,OAAO,OAAO;AAC5D,QAAI,MAAM,SAAS,GAAG;AACpB,cAAQ,IAAIA,OAAM,KAAK,sBAAsB,CAAC;AAC9C,iBAAW,OAAO,OAAO;AACvB,gBAAQ,IAAI,GAAG;AAAA,MACjB;AAAA,IACF;AAAA,EACF;AAGA,MAAI,aAAa,MAAM;AAErB,QAAI,QAAQ,eAAe,UAAU;AACnC,UAAI,CAAC,YAAY;AACf,gBAAQ;AAAA,UACNA,OAAM,IAAI,WAAW,QAAQ,YAAY,qBAAqB,QAAQ,GAAG;AAAA,QAC3E;AAAA,MACF;AACA,cAAQ,KAAK,CAAC;AAAA,IAChB;AAAA,EACF,WAAW,QAAQ,iBAAiB,GAAG;AAErC,YAAQ,KAAK,CAAC;AAAA,EAChB;AACF,CAAC;AAIH,SAAS,WAAW,OAAe,SAA0B;AAC3D,MAAI,QAAQ,SAAS,IAAI,GAAG;AAC1B,UAAM,SAAS,QAAQ,MAAM,GAAG,EAAE;AAClC,WAAO,UAAU,UAAU,MAAM,WAAW,SAAS,GAAG;AAAA,EAC1D;AACA,SAAO,UAAU;AACnB;;;AKzLA,SAAS,WAAAC,gBAAe;AACxB,OAAOC,YAAW;AAClB,OAAOC,UAAS;AAChB;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAIP,SAAS,WAAW,OAA6B;AAC/C,MAAI,SAAS,GAAI,QAAOC,OAAM;AAC9B,MAAI,SAAS,GAAI,QAAOA,OAAM;AAC9B,SAAOA,OAAM;AACf;AAEO,IAAM,eAAe,IAAIC,SAAQ,OAAO,EAC5C,YAAY,4EAA4E,EACxF,SAAS,SAAS,oDAAoD,EACtE,OAAO,mBAAmB,0BAA0B,KAAK,EACzD,OAAO,mBAAmB,sBAAsB,GAAG,EACnD,OAAO,gBAAgB,gCAAgC,KAAK,EAC5D,OAAO,UAAU,0BAA0B,KAAK,EAChD,OAAO,YAAY,4BAA4B,KAAK,EACpD,OAAO,iBAAiB,2BAA2B,KAAK,EACxD,OAAO,kBAAkB,sBAAsB,KAAK,EACpD,OAAO,iBAAiB,yBAAyB,KAAK,EACtD,OAAO,uBAAuB,+EAA+E,EAC7G,OAAO,UAAU,oCAAoC,KAAK,EAC1D,OAAO,mBAAmB,oDAAoD,EAC9E,OAAO,OAAO,KAAa,SAAS;AACnC,QAAM,aAAa,KAAK;AACxB,QAAM,WAAW,SAAS,KAAK,UAAU,EAAE;AAC3C,QAAM,WAAW,SAAS,KAAK,UAAU,EAAE;AAC3C,QAAMC,SAAQ,SAAS,KAAK,OAAO,EAAE;AAGrC,MAAI,CAAC,IAAI,WAAW,SAAS,KAAK,CAAC,IAAI,WAAW,UAAU,GAAG;AAC7D,UAAM,WAAW,GAAG;AAAA,EACtB;AAEA,MAAI,CAAC,YAAY;AACf,YAAQ,IAAI,EAAE;AACd,YAAQ,IAAIF,OAAM,KAAK,gBAAgB,IAAIA,OAAM,IAAI,WAAM,GAAG,EAAE,CAAC;AACjE,YAAQ,IAAI,EAAE;AAAA,EAChB;AAGA,MAAI,eAAe;AACnB,MAAI,CAAC,KAAK,YAAY;AACpB,UAAM,gBAAgB,aAAa,OAAOG,KAAI,wBAAwB,EAAE,MAAM;AAC9E,mBAAe,MAAM,YAAY,GAAG;AAEpC,QAAI,CAAC,YAAY;AACf,UAAI,aAAa,OAAO;AACtB,sBAAe,QAAQ,kBAAkB;AACzC,mBAAW,KAAK,aAAa,UAAU;AACrC,kBAAQ,IAAIH,OAAM,OAAO,YAAO,CAAC,EAAE,CAAC;AAAA,QACtC;AACA,YAAI,aAAa,YAAY,SAAS,GAAG;AACvC,kBAAQ,IAAIA,OAAM,IAAI,yBAAyB,aAAa,YAAY,KAAK,IAAI,CAAC,EAAE,CAAC;AAAA,QACvF;AAAA,MACF,OAAO;AACL,sBAAe,KAAK,sBAAsB;AAC1C,mBAAW,KAAK,aAAa,QAAQ;AACnC,kBAAQ,IAAIA,OAAM,IAAI,KAAK,CAAC,EAAE,CAAC;AAAA,QACjC;AAAA,MACF;AACA,cAAQ,IAAI,EAAE;AAAA,IAChB;AAAA,EACF;AAGA,QAAM,eAAe,aAAa,OAAOG,KAAI,aAAa,EAAE,MAAM;AAClE,MAAI,eAAe;AAGnB,QAAM,iBAA2B,KAAK,SAClC,KAAK,OAAO,MAAM,GAAG,EAAE,IAAI,CAAC,MAAc,EAAE,KAAK,CAAC,EAAE,OAAO,OAAO,IAClE,CAAC;AAEL,QAAM,cAAc,MAAM,UAAU,KAAK;AAAA,IACvC;AAAA,IACA;AAAA,IACA,OAAAD;AAAA,IACA,QAAQ,KAAK;AAAA,IACb;AAAA,IACA,eAAe,CAAC,SAAsB;AACpC;AACA,UAAI,cAAc;AAChB,qBAAa,OAAO,eAAe,YAAY,oBAAoB,KAAK,GAAG;AAAA,MAC7E;AAAA,IACF;AAAA,EACF,CAAC;AAED,MAAI,CAAC,YAAY;AACf,iBAAc,QAAQ,WAAW,YAAY,UAAU,cAAc,YAAY,aAAa,KAAM,QAAQ,CAAC,CAAC,GAAG;AACjH,YAAQ,IAAI,EAAE;AAGd,eAAW,QAAQ,YAAY,OAAO;AACpC,UAAI,KAAK,OAAO;AACd,gBAAQ,IAAIF,OAAM,IAAI,YAAO,KAAK,GAAG,EAAE,IAAIA,OAAM,IAAI,WAAM,KAAK,KAAK,EAAE,CAAC;AACxE;AAAA,MACF;AAEA,YAAM,YAAY,WAAW,KAAK,WAAW,KAAK;AAClD,YAAM,OACJ,KAAK,WAAW,OAAO,SAAS,IAAIA,OAAM,IAAI,QAAG,IAAIA,OAAM,MAAM,QAAG;AAEtE,cAAQ;AAAA,QACN,KAAK,IAAI,IAAI,KAAK,GAAG,IAAI,UAAU,GAAG,KAAK,WAAW,KAAK,MAAM,CAAC;AAAA,MACpE;AAEA,iBAAW,SAAS,KAAK,WAAW,QAAQ;AAC1C,gBAAQ,IAAIA,OAAM,IAAI,cAAS,MAAM,WAAW,MAAM,WAAW,EAAE,CAAC;AAAA,MACtE;AACA,iBAAW,WAAW,KAAK,WAAW,UAAU;AAC9C,gBAAQ,IAAIA,OAAM,OAAO,cAAS,QAAQ,WAAW,QAAQ,WAAW,EAAE,CAAC;AAAA,MAC7E;AAAA,IACF;AAEA,YAAQ,IAAI,EAAE;AAAA,EAChB;AAGA,MAAI,oBAAoB;AACxB,MAAI,CAAC,KAAK,aAAa;AACrB,UAAM,iBAAiB,aAAa,OAAOG,KAAI,yBAAyB,EAAE,MAAM;AAChF,UAAM,gBAAgB,MAAM,aAAa,GAAG;AAE5C,QAAI,CAAC,YAAY;AACf,UAAI,cAAc,OAAO;AACvB,uBAAgB,QAAQ,4BAAuB,cAAc,KAAK,MAAM,OAAO;AAG/E,cAAM,cAAc,YAAY,MAC7B,OAAO,CAAC,MAAM,CAAC,EAAE,KAAK,EACtB,IAAI,CAAC,MAAM,EAAE,GAAG;AACnB,4BAAoB;AAAA,UAClB,cAAc,KAAK,IAAI,CAAC,MAAM,EAAE,GAAG;AAAA,UACnC;AAAA,QACF;AAEA,YAAI,kBAAkB,YAAY,SAAS,GAAG;AAC5C,kBAAQ,IAAIH,OAAM,OAAO,YAAO,kBAAkB,YAAY,MAAM,sCAAsC,CAAC;AAC3G,qBAAW,KAAK,kBAAkB,YAAY,MAAM,GAAG,EAAE,GAAG;AAC1D,oBAAQ,IAAIA,OAAM,IAAI,SAAS,CAAC,EAAE,CAAC;AAAA,UACrC;AAAA,QACF;AACA,YAAI,kBAAkB,cAAc,SAAS,GAAG;AAC9C,gBAAM,WAAW,YAAY,cAAc;AAC3C,gBAAM,QAAQ,WACV,GAAG,kBAAkB,cAAc,MAAM,qCAAqC,QAAQ,yCACtF,GAAG,kBAAkB,cAAc,MAAM;AAC7C,kBAAQ,IAAIA,OAAM,OAAO,YAAO,KAAK,GAAG,CAAC;AACzC,qBAAW,KAAK,kBAAkB,cAAc,MAAM,GAAG,EAAE,GAAG;AAC5D,oBAAQ,IAAIA,OAAM,IAAI,SAAS,CAAC,EAAE,CAAC;AAAA,UACrC;AAAA,QACF;AACA,YAAI,kBAAkB,OAAO,WAAW,GAAG;AACzC,kBAAQ,IAAIA,OAAM,MAAM,wCAAmC,CAAC;AAAA,QAC9D;AAAA,MACF,OAAO;AACL,uBAAgB,KAAK,uBAAuB;AAC5C,mBAAW,KAAK,cAAc,QAAQ;AACpC,kBAAQ,IAAIA,OAAM,IAAI,KAAK,CAAC,EAAE,CAAC;AAAA,QACjC;AAAA,MACF;AACA,cAAQ,IAAI,EAAE;AAAA,IAChB;AAAA,EACF;AAGA,MAAI,qBAAqB;AACzB,MAAI,cAAc,SAAS,aAAa,WAAW,SAAS,GAAG;AAC7D,UAAM,cAAc,YAAY,MAAM,OAAO,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,MAAM,EAAE,GAAG;AAC9E,yBAAqB;AAAA,MACnB,aAAa;AAAA,MACb;AAAA,IACF;AACA,UAAM,UAAU,mBAAmB,OAAO,CAAC,MAAM,EAAE,OAAO;AAE1D,QAAI,CAAC,cAAc,QAAQ,SAAS,GAAG;AACrC,cAAQ,IAAIA,OAAM,OAAO,YAAO,QAAQ,MAAM,2CAA2C,CAAC;AAC1F,iBAAW,KAAK,SAAS;AACvB,gBAAQ,IAAIA,OAAM,IAAI,SAAS,EAAE,IAAI,KAAK,EAAE,SAAS,GAAG,CAAC;AAAA,MAC3D;AACA,cAAQ,IAAI,EAAE;AAAA,IAChB;AAAA,EACF;AAGA,MAAI,cAAc;AAClB,MAAI,CAAC,KAAK,YAAY;AACpB,UAAM,eAAe,aAAa,OAAOG,KAAI,8CAA8C,EAAE,MAAM;AAEnG,UAAM,qBAAqB,YAAY,MACpC,OAAO,CAAC,MAAM,CAAC,EAAE,KAAK,EACtB,IAAI,CAAC,OAAO,EAAE,KAAK,EAAE,KAAK,UAAU,EAAE,SAAS,EAAE;AACpD,kBAAc,MAAM,aAAa,kBAAkB;AAEnD,QAAI,CAAC,YAAY;AACf,mBAAc,QAAQ,YAAY,YAAY,YAAY,SAAS;AAEnE,YAAM,eAAe,YAAY,OAAO,OAAO,CAAC,MAAM,CAAC,EAAE,EAAE;AAC3D,YAAM,gBAAgB,YAAY,OAAO,OAAO,CAAC,MAAM,EAAE,OAAO;AAEhE,iBAAW,SAAS,cAAc;AAChC,gBAAQ;AAAA,UACNH,OAAM,IAAI,YAAO,MAAM,IAAI,EAAE,IAC7BA,OAAM,IAAI,IAAI,MAAM,GAAG,EAAE,IACzBA,OAAM,IAAI,WAAM,MAAM,SAAS,QAAQ,MAAM,MAAM,EAAE,EAAE;AAAA,QACzD;AAAA,MACF;AACA,iBAAW,SAAS,eAAe;AACjC,gBAAQ;AAAA,UACNA,OAAM,OAAO,YAAO,MAAM,IAAI,EAAE,IAChCA,OAAM,IAAI,IAAI,MAAM,GAAG,EAAE,IACzBA,OAAM,OAAO,WAAM,MAAM,OAAO,EAAE;AAAA,QACpC;AAAA,MACF;AACA,UAAI,aAAa,WAAW,KAAK,cAAc,WAAW,GAAG;AAC3D,gBAAQ,IAAIA,OAAM,MAAM,uCAAkC,CAAC;AAAA,MAC7D;AACA,cAAQ,IAAI,EAAE;AAAA,IAChB;AAAA,EACF;AAGA,MAAI,CAAC,YAAY;AACf,UAAM,IAAI,YAAY;AAGtB,QAAI,EAAE,gBAAgB,SAAS,GAAG;AAChC,cAAQ,IAAIA,OAAM,KAAK,oBAAoB,CAAC;AAC5C,iBAAW,OAAO,EAAE,gBAAgB,MAAM,GAAG,CAAC,GAAG;AAC/C,gBAAQ,IAAIA,OAAM,IAAI,aAAQ,IAAI,MAAM,SAAS,KAAK,IAAI,MAAM,MAAM,GAAG,EAAE,IAAI,QAAQ,IAAI,KAAK,GAAG,IAAIA,OAAM,IAAI,KAAK,IAAI,KAAK,MAAM,SAAS,CAAC;AAC/I,mBAAW,KAAK,IAAI,KAAK,MAAM,GAAG,CAAC,EAAG,SAAQ,IAAIA,OAAM,IAAI,OAAO,CAAC,EAAE,CAAC;AACvE,YAAI,IAAI,KAAK,SAAS,EAAG,SAAQ,IAAIA,OAAM,IAAI,cAAc,IAAI,KAAK,SAAS,CAAC,OAAO,CAAC;AAAA,MAC1F;AACA,UAAI,EAAE,gBAAgB,SAAS,EAAG,SAAQ,IAAIA,OAAM,IAAI,YAAY,EAAE,gBAAgB,SAAS,CAAC,cAAc,CAAC;AAC/G,cAAQ,IAAI,EAAE;AAAA,IAChB;AAGA,QAAI,EAAE,sBAAsB,SAAS,GAAG;AACtC,cAAQ,IAAIA,OAAM,KAAK,0BAA0B,CAAC;AAClD,iBAAW,OAAO,EAAE,sBAAsB,MAAM,GAAG,CAAC,GAAG;AACrD,cAAM,OAAO,IAAI,YAAY,SAAS,KAAK,IAAI,YAAY,MAAM,GAAG,EAAE,IAAI,QAAQ,IAAI;AACtF,gBAAQ,IAAIA,OAAM,IAAI,aAAQ,IAAI,GAAG,IAAIA,OAAM,IAAI,KAAK,IAAI,KAAK,MAAM,SAAS,CAAC;AACjF,mBAAW,KAAK,IAAI,KAAK,MAAM,GAAG,CAAC,EAAG,SAAQ,IAAIA,OAAM,IAAI,OAAO,CAAC,EAAE,CAAC;AACvE,YAAI,IAAI,KAAK,SAAS,EAAG,SAAQ,IAAIA,OAAM,IAAI,cAAc,IAAI,KAAK,SAAS,CAAC,OAAO,CAAC;AAAA,MAC1F;AACA,UAAI,EAAE,sBAAsB,SAAS,EAAG,SAAQ,IAAIA,OAAM,IAAI,YAAY,EAAE,sBAAsB,SAAS,CAAC,cAAc,CAAC;AAC3H,cAAQ,IAAI,EAAE;AAAA,IAChB;AAGA,QAAI,EAAE,SAAS,SAAS,GAAG;AACzB,YAAM,UAAU,EAAE,SAAS,OAAO,OAAK,EAAE,UAAU,SAAS;AAC5D,YAAM,WAAW,EAAE,SAAS,OAAO,OAAK,EAAE,UAAU,UAAU;AAC9D,cAAQ,IAAIA,OAAM,KAAK,qBAAqB,CAAC;AAC7C,UAAI,QAAQ,SAAS,GAAG;AACtB,gBAAQ,IAAIA,OAAM,IAAI,YAAO,QAAQ,MAAM,mBAAmB,CAAC;AAC/D,mBAAW,KAAK,QAAQ,MAAM,GAAG,CAAC,EAAG,SAAQ,IAAIA,OAAM,IAAI,OAAO,EAAE,GAAG,EAAE,CAAC;AAC1E,YAAI,QAAQ,SAAS,EAAG,SAAQ,IAAIA,OAAM,IAAI,cAAc,QAAQ,SAAS,CAAC,OAAO,CAAC;AAAA,MACxF;AACA,UAAI,SAAS,SAAS,GAAG;AACvB,gBAAQ,IAAIA,OAAM,OAAO,YAAO,SAAS,MAAM,0BAA0B,CAAC;AAC1E,mBAAW,KAAK,SAAS,MAAM,GAAG,CAAC,EAAG,SAAQ,IAAIA,OAAM,IAAI,OAAO,EAAE,GAAG,KAAK,EAAE,KAAK,OAAO,CAAC;AAC5F,YAAI,SAAS,SAAS,EAAG,SAAQ,IAAIA,OAAM,IAAI,cAAc,SAAS,SAAS,CAAC,OAAO,CAAC;AAAA,MAC1F;AACA,cAAQ,IAAI,EAAE;AAAA,IAChB;AAGA,QAAI,EAAE,oBAAoB,SAAS,GAAG;AACpC,cAAQ,IAAIA,OAAM,KAAK,yBAAyB,CAAC;AACjD,iBAAW,MAAM,EAAE,oBAAoB,MAAM,GAAG,EAAE,GAAG;AACnD,gBAAQ,IAAIA,OAAM,IAAI,YAAO,GAAG,EAAE,EAAE,IAAIA,OAAM,IAAI,uBAAkB,GAAG,IAAI,KAAK,GAAG,MAAM,GAAG,CAAC;AAAA,MAC/F;AACA,UAAI,EAAE,oBAAoB,SAAS,GAAI,SAAQ,IAAIA,OAAM,IAAI,YAAY,EAAE,oBAAoB,SAAS,EAAE,OAAO,CAAC;AAClH,cAAQ,IAAI,EAAE;AAAA,IAChB;AAGA,QAAI,EAAE,oBAAoB,SAAS,GAAG;AACpC,cAAQ,IAAIA,OAAM,KAAK,yBAAyB,CAAC;AACjD,iBAAW,MAAM,EAAE,oBAAoB,MAAM,GAAG,EAAE,GAAG;AACnD,gBAAQ,IAAIA,OAAM,IAAI,YAAO,GAAG,EAAE,EAAE,IAAIA,OAAM,IAAI,uBAAkB,GAAG,IAAI,KAAK,GAAG,MAAM,GAAG,CAAC;AAAA,MAC/F;AACA,UAAI,EAAE,oBAAoB,SAAS,GAAI,SAAQ,IAAIA,OAAM,IAAI,YAAY,EAAE,oBAAoB,SAAS,EAAE,OAAO,CAAC;AAClH,cAAQ,IAAI,EAAE;AAAA,IAChB;AAGA,QAAI,EAAE,UAAU,SAAS,GAAG;AAC1B,cAAQ,IAAIA,OAAM,KAAK,mBAAmB,CAAC;AAC3C,iBAAW,KAAK,EAAE,UAAU,MAAM,GAAG,EAAE,GAAG;AACxC,gBAAQ,IAAIA,OAAM,OAAO,YAAO,EAAE,GAAG,EAAE,CAAC;AACxC,mBAAW,QAAQ,EAAE,MAAO,SAAQ,IAAIA,OAAM,IAAI,OAAO,IAAI,EAAE,CAAC;AAAA,MAClE;AACA,UAAI,EAAE,UAAU,SAAS,GAAI,SAAQ,IAAIA,OAAM,IAAI,YAAY,EAAE,UAAU,SAAS,EAAE,OAAO,CAAC;AAC9F,cAAQ,IAAI,EAAE;AAAA,IAChB;AAGA,QAAI,EAAE,iBAAiB,SAAS,GAAG;AACjC,YAAM,WAAW,EAAE,iBAAiB,OAAO,QAAM,CAAC,GAAG,SAAS;AAC9D,YAAM,UAAU,EAAE,iBAAiB,OAAO,QAAM,GAAG,SAAS;AAE5D,UAAI,SAAS,SAAS,GAAG;AACvB,gBAAQ,IAAIA,OAAM,KAAK,gBAAgB,IAAIA,OAAM,IAAI,gBAAgB,CAAC;AACtE,mBAAW,MAAM,SAAS,MAAM,GAAG,EAAE,GAAG;AACtC,kBAAQ,IAAIA,OAAM,OAAO,YAAO,GAAG,GAAG,EAAE,IAAIA,OAAM,IAAI,WAAM,GAAG,SAAS,QAAQ,CAAC;AAAA,QACnF;AACA,YAAI,SAAS,SAAS,GAAI,SAAQ,IAAIA,OAAM,IAAI,YAAY,SAAS,SAAS,EAAE,OAAO,CAAC;AACxF,gBAAQ,IAAI,EAAE;AAAA,MAChB;AACA,UAAI,QAAQ,SAAS,GAAG;AACtB,gBAAQ,IAAIA,OAAM,KAAK,oBAAoB,IAAIA,OAAM,IAAI,6CAA6C,CAAC;AACvG,mBAAW,MAAM,QAAQ,MAAM,GAAG,CAAC,GAAG;AACpC,kBAAQ,IAAIA,OAAM,IAAI,YAAO,GAAG,GAAG,WAAM,GAAG,SAAS,QAAQ,CAAC;AAAA,QAChE;AACA,YAAI,QAAQ,SAAS,EAAG,SAAQ,IAAIA,OAAM,IAAI,YAAY,QAAQ,SAAS,CAAC,OAAO,CAAC;AACpF,gBAAQ,IAAI,EAAE;AAAA,MAChB;AAAA,IACF;AAGA,QAAI,EAAE,YAAY,SAAS,GAAG;AAC5B,cAAQ,IAAIA,OAAM,KAAK,gBAAgB,IAAIA,OAAM,IAAI,sCAAsC,CAAC;AAC5F,iBAAW,KAAK,EAAE,YAAY,MAAM,GAAG,EAAE,EAAG,SAAQ,IAAIA,OAAM,OAAO,YAAO,CAAC,EAAE,CAAC;AAChF,UAAI,EAAE,YAAY,SAAS,GAAI,SAAQ,IAAIA,OAAM,IAAI,YAAY,EAAE,YAAY,SAAS,EAAE,OAAO,CAAC;AAClG,cAAQ,IAAI,EAAE;AAAA,IAChB;AAGA,QAAI,EAAE,aAAa,SAAS,KAAK,EAAE,aAAa,CAAC,EAAE,iBAAiB,KAAM;AACxE,cAAQ,IAAIA,OAAM,KAAK,iBAAiB,CAAC;AACzC,iBAAW,MAAM,EAAE,aAAa,OAAO,OAAK,EAAE,iBAAiB,GAAI,EAAE,MAAM,GAAG,CAAC,GAAG;AAChF,cAAM,QAAQ,GAAG,iBAAiB,MAAOA,OAAM,MAAMA,OAAM;AAC3D,gBAAQ,IAAI,MAAM,YAAO,GAAG,GAAG,EAAE,IAAIA,OAAM,IAAI,YAAO,GAAG,iBAAiB,KAAM,QAAQ,CAAC,CAAC,GAAG,CAAC;AAAA,MAChG;AACA,cAAQ,IAAI,EAAE;AAAA,IAChB;AAGA,QAAI,EAAE,sBAAsB,SAAS,GAAG;AACtC,cAAQ,IAAIA,OAAM,KAAK,6BAA6B,CAAC;AACrD,iBAAW,MAAM,EAAE,uBAAuB;AACxC,gBAAQ,IAAIA,OAAM,MAAM,YAAO,GAAG,IAAI,EAAE,IAAIA,OAAM,IAAI,WAAM,GAAG,KAAK,QAAQ,GAAG,QAAQ,IAAI,MAAM,EAAE,EAAE,CAAC;AAAA,MACxG;AACA,YAAM,cAAc,YAAY,MAAM,OAAO,OAAK,CAAC,EAAE,SAAS,EAAE,oBAAoB,SAAS,CAAC,EAAE;AAChG,YAAM,eAAe,YAAY,MAAM,OAAO,OAAK,CAAC,EAAE,KAAK,EAAE,SAAS;AACtE,UAAI,eAAe,GAAG;AACpB,gBAAQ,IAAIA,OAAM,OAAO,YAAO,YAAY,oCAAoC,CAAC;AAAA,MACnF;AACA,cAAQ,IAAI,EAAE;AAAA,IAChB,OAAO;AACL,cAAQ,IAAIA,OAAM,KAAK,6BAA6B,CAAC;AACrD,cAAQ,IAAIA,OAAM,IAAI,+CAA0C,CAAC;AACjE,cAAQ,IAAI,EAAE;AAAA,IAChB;AAGA,QAAI,EAAE,eAAe,SAAS,GAAG;AAC/B,cAAQ,IAAIA,OAAM,KAAK,kBAAkB,CAAC;AAC1C,iBAAW,OAAO,EAAE,eAAe,MAAM,GAAG,EAAE,GAAG;AAC/C,cAAM,QAAQ,IAAI,aAAa,IAAI,SAAS,MAAMA,OAAM,MAAMA,OAAM;AACpE,cAAM,OAAO,IAAI,aAAa,IAAI,SAAS,MAAM,WAAM;AACvD,gBAAQ,IAAI,MAAM,KAAK,IAAI,IAAI,IAAI,GAAG,EAAE,IAAIA,OAAM,IAAI,WAAM,IAAI,UAAU,IAAI,IAAI,KAAK,qBAAqB,CAAC;AAAA,MAC/G;AACA,UAAI,EAAE,eAAe,SAAS,GAAI,SAAQ,IAAIA,OAAM,IAAI,YAAY,EAAE,eAAe,SAAS,EAAE,OAAO,CAAC;AACxG,cAAQ,IAAI,EAAE;AAAA,IAChB;AAGA,QAAI,EAAE,aAAa,SAAS,GAAG;AAC7B,cAAQ,IAAIA,OAAM,KAAK,iBAAiB,CAAC;AACzC,iBAAW,OAAO,EAAE,aAAa,MAAM,GAAG,EAAE,GAAG;AAC7C,cAAM,MAAM,IAAI,IAAI,SAAS,KAAK,IAAI,IAAI,MAAM,GAAG,EAAE,IAAI,QAAQ,IAAI;AACrE,gBAAQ,IAAIA,OAAM,IAAI,YAAO,GAAG,EAAE,IAAIA,OAAM,IAAI,KAAK,IAAI,MAAM,eAAU,IAAI,MAAM,MAAM,QAAQ,IAAI,MAAM,SAAS,IAAI,MAAM,EAAE,EAAE,CAAC;AACnI,mBAAW,QAAQ,IAAI,MAAM,MAAM,GAAG,CAAC,EAAG,SAAQ,IAAIA,OAAM,IAAI,OAAO,IAAI,EAAE,CAAC;AAC9E,YAAI,IAAI,MAAM,SAAS,EAAG,SAAQ,IAAIA,OAAM,IAAI,cAAc,IAAI,MAAM,SAAS,CAAC,OAAO,CAAC;AAAA,MAC5F;AACA,UAAI,EAAE,aAAa,SAAS,GAAI,SAAQ,IAAIA,OAAM,IAAI,YAAY,EAAE,aAAa,SAAS,EAAE,OAAO,CAAC;AACpG,cAAQ,IAAI,EAAE;AAAA,IAChB;AAAA,EACF;AAGA,MAAI,YAAY;AACd,YAAQ;AAAA,MACN,KAAK;AAAA,QACH;AAAA,UACE,OAAO;AAAA,UACP,QAAQ;AAAA,UACR,SAAS;AAAA,UACT,QAAQ;AAAA,QACV;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF,OAAO;AACL,UAAM,eAAe,WAAW,YAAY,YAAY;AAExD,YAAQ,IAAIA,OAAM,KAAK,iDAAmB,CAAC;AAC3C,YAAQ,IAAI,EAAE;AACd,UAAM,WAAW,YAAY,cAAc;AAC3C,YAAQ,IAAI,qBAAqBA,OAAM,KAAK,OAAO,YAAY,UAAU,CAAC,CAAC,GAAG,WAAWA,OAAM,IAAI,YAAY,QAAQ,wCAAmC,IAAI,EAAE,EAAE;AAClK,YAAQ,IAAI,qBAAqB,aAAaA,OAAM,KAAK,GAAG,YAAY,YAAY,MAAM,CAAC,CAAC,KAAK,YAAY,KAAK,GAAG;AACrH,YAAQ,IAAI,qBAAqB,YAAY,cAAc,IAAIA,OAAM,IAAI,OAAO,YAAY,WAAW,CAAC,IAAIA,OAAM,MAAM,GAAG,CAAC,EAAE;AAC9H,YAAQ,IAAI,qBAAqB,YAAY,gBAAgB,IAAIA,OAAM,OAAO,OAAO,YAAY,aAAa,CAAC,IAAIA,OAAM,MAAM,GAAG,CAAC,EAAE;AACrI,QAAI,aAAa;AACf,cAAQ,IAAI,qBAAqB,YAAY,cAAc,IAAIA,OAAM,IAAI,OAAO,YAAY,WAAW,CAAC,IAAIA,OAAM,MAAM,GAAG,CAAC,EAAE;AAAA,IAChI;AACA,QAAI,YAAY,YAAY,SAAS,GAAG;AACtC,cAAQ,IAAIA,OAAM,IAAI,qBAAqB,YAAY,YAAY,MAAM,oBAAoB,CAAC;AAAA,IAChG;AACA,YAAQ,IAAI,EAAE;AAAA,EAChB;AAGA,MAAI,KAAK,MAAM;AACb,UAAM,SAAS,MAAM,cAAc,KAAK,MAAM;AAC9C,QAAI,CAAC,QAAQ;AACX,UAAI,CAAC,YAAY;AACf,gBAAQ,IAAIA,OAAM,OAAO,UAAK,IAAI,8DAA8D;AAChG,gBAAQ,IAAI,EAAE;AACd,gBAAQ,IAAIA,OAAM,KAAK,qBAAqB,CAAC;AAC7C,gBAAQ,IAAI,EAAE;AACd,gBAAQ,IAAIA,OAAM,IAAI,0CAA0C,CAAC;AACjE,gBAAQ,IAAI,EAAE;AAAA,MAChB;AAAA,IACF,OAAO;AACL,YAAM,cAAc,aAAa,OAAOG,KAAI,8BAA8B,EAAE,MAAM;AAClF,UAAI;AACF,cAAM,UAAU,QAAQ,IAAI,kBAAkB;AAC9C,cAAM,MAAM,MAAM,MAAM,GAAG,OAAO,iBAAiB;AAAA,UACjD,QAAQ;AAAA,UACR,SAAS;AAAA,YACP,gBAAgB;AAAA,YAChB,eAAe,UAAU,MAAM;AAAA,UACjC;AAAA,UACA,MAAM,KAAK,UAAU;AAAA,YACnB,OAAO;AAAA,YACP,QAAQ;AAAA,YACR,SAAS;AAAA,YACT,QAAQ;AAAA,UACV,CAAC;AAAA,QACH,CAAC;AACD,YAAI,IAAI,IAAI;AACV,gBAAM,OAAQ,MAAM,IAAI,KAAK;AAC7B,cAAI,YAAa,aAAY,QAAQ,oCAA+B,KAAK,OAAO,EAAE;AAAA,QACpF,OAAO;AACL,gBAAM,OAAQ,MAAM,IAAI,KAAK,EAAE,MAAM,OAAO,CAAC,EAAE;AAC/C,cAAI,YAAa,aAAY,KAAK,gBAAgB,KAAK,SAAS,IAAI,UAAU,EAAE;AAAA,QAClF;AAAA,MACF,SAAS,KAAK;AACZ,YAAI,YAAa,aAAY,KAAK,gBAAgB,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC,EAAE;AAAA,MACtG;AACA,UAAI,CAAC,WAAY,SAAQ,IAAI,EAAE;AAAA,IACjC;AAAA,EACF;AAGA,MAAI,YAAY,cAAc,GAAG;AAC/B,YAAQ,KAAK,CAAC;AAAA,EAChB;AACF,CAAC;;;AC5dH,SAAS,WAAAC,gBAAe;AACxB,OAAOC,YAAW;AAClB,OAAOC,UAAS;AAChB,SAAS,kBAAkB,aAAAC,YAAW,0BAA0B;AAEzD,IAAM,kBAAkB,IAAIH,SAAQ,UAAU,EAClD,YAAY,sDAAsD,EAClE,SAAS,UAAU,mCAAmC,EACtD,OAAO,qBAAqB,mBAAmB,IAAI,EACnD,OAAO,uBAAuB,gBAAgB,IAAI,EAClD,OAAO,gBAAgB,0CAA0C,EACjE,OAAO,mBAAmB,2CAA2C,IAAI,EACzE,OAAO,UAAU,0BAA0B,KAAK,EAChD,OAAO,OAAO,MAAc,SAAS;AACpC,QAAM,aAAa,KAAK;AAExB,MAAI,CAAC,YAAY;AACf,YAAQ,IAAI,EAAE;AACd,YAAQ,IAAIC,OAAM,KAAK,mBAAmB,IAAIA,OAAM,IAAI,YAAO,IAAI,GAAG,CAAC;AACvE,YAAQ,IAAI,EAAE;AAAA,EAChB;AAGA,QAAM,YAAY,aAAa,OAAOC,KAAI,yBAAyB,EAAE,MAAM;AAC3E,QAAM,WAAW,MAAM,iBAAiB,MAAM;AAAA,IAC5C,QAAQ,KAAK;AAAA,IACb,SAAS,KAAK;AAAA,EAChB,CAAC;AAED,MAAI,CAAC,YAAY;AACf,cAAW,QAAQ,SAAS,SAAS,aAAa,WAAW;AAC7D,YAAQ,IAAI,EAAE;AAEd,QAAI,SAAS,YAAY,SAAS,GAAG;AACnC,cAAQ,IAAID,OAAM,KAAK,yBAAyB,SAAS,YAAY,MAAM,GAAG,CAAC;AAC/E,iBAAW,KAAK,SAAS,aAAa;AACpC,gBAAQ,IAAI,KAAKA,OAAM,IAAI,SAAS,EAAE,EAAE,OAAO,CAAC,EAAE;AAAA,MACpD;AACA,cAAQ,IAAI,EAAE;AAAA,IAChB;AAEA,QAAI,SAAS,UAAU,SAAS,GAAG;AACjC,cAAQ,IAAIA,OAAM,KAAK,gBAAgB,SAAS,UAAU,MAAM,GAAG,CAAC;AACpE,iBAAW,KAAK,SAAS,UAAU,MAAM,GAAG,EAAE,GAAG;AAC/C,gBAAQ,IAAI,KAAKA,OAAM,KAAK,GAAG,CAAC,IAAI,EAAE,OAAO,EAAE;AAAA,MACjD;AACA,cAAQ,IAAI,EAAE;AAAA,IAChB;AAEA,QAAI,SAAS,SAAS,SAAS,GAAG;AAChC,cAAQ,IAAIA,OAAM,KAAK,gBAAgB,SAAS,SAAS,MAAM,GAAG,CAAC;AACnE,iBAAW,MAAM,SAAS,SAAS,MAAM,GAAG,EAAE,GAAG;AAC/C,gBAAQ,IAAIA,OAAM,IAAI,KAAK,GAAG,OAAO,EAAE,CAAC;AAAA,MAC1C;AACA,UAAI,SAAS,SAAS,SAAS,IAAI;AACjC,gBAAQ,IAAIA,OAAM,IAAI,aAAa,SAAS,SAAS,SAAS,EAAE,OAAO,CAAC;AAAA,MAC1E;AACA,cAAQ,IAAI,EAAE;AAAA,IAChB;AAAA,EACF;AAGA,MAAI,YAAY;AAChB,MAAI,KAAK,MAAM;AACb,QAAI,UAAU,KAAK;AACnB,QAAI,CAAC,QAAQ,WAAW,SAAS,KAAK,CAAC,QAAQ,WAAW,UAAU,GAAG;AACrE,gBAAU,WAAW,OAAO;AAAA,IAC9B;AAEA,UAAM,eAAe,aAAa,OAAOC,KAAI,YAAY,OAAO,sBAAsB,EAAE,MAAM;AAC9F,UAAM,cAAc,MAAMC,WAAU,SAAS;AAAA,MAC3C,UAAU,SAAS,KAAK,UAAU,EAAE;AAAA,MACpC,OAAO;AAAA,IACT,CAAC;AAED,QAAI,CAAC,YAAY;AACf,mBAAc,QAAQ,WAAW,YAAY,UAAU,QAAQ;AAAA,IACjE;AAEA,UAAM,cAAc;AAAA,MAClB,GAAG,SAAS;AAAA,MACZ,GAAG,SAAS;AAAA,MACZ,GAAG,SAAS;AAAA,IACd;AAEA,UAAM,gBAAgB,YAAY,MAC/B,OAAO,CAAC,MAAM,CAAC,EAAE,KAAK,EACtB,IAAI,CAAC,OAAO,EAAE,KAAK,EAAE,KAAK,UAAU,EAAE,SAAS,EAAE;AAEpD,gBAAY,mBAAmB,aAAa,aAAa;AAEzD,QAAI,CAAC,YAAY;AACf,cAAQ,IAAI,EAAE;AACd,cAAQ;AAAA,QACNF,OAAM,KAAK,sBAAsB,IAC/B,GAAG,UAAU,YAAY,IAAI,UAAU,aAAa,cAAc,UAAU,eAAe;AAAA,MAC/F;AACA,cAAQ,IAAI,EAAE;AAEd,UAAI,UAAU,KAAK,SAAS,GAAG;AAC7B,cAAM,WAAW,UAAU,KAAK,OAAO,CAAC,MAAM,EAAE,cAAc,MAAM;AACpE,cAAM,UAAU,UAAU,KAAK,OAAO,CAAC,MAAM,EAAE,cAAc,QAAQ;AAErE,YAAI,SAAS,SAAS,GAAG;AACvB,kBAAQ,IAAIA,OAAM,KAAK,IAAI,yBAAyB,SAAS,MAAM,GAAG,CAAC;AACvE,qBAAW,OAAO,SAAS,MAAM,GAAG,EAAE,GAAG;AACvC,oBAAQ;AAAA,cACNA,OAAM,IAAI,WAAM,IACd,IAAI,IAAI,OAAO,cACfA,OAAM,IAAI,GAAG,IAAI,aAAa,OAAO,IAAI,aAAa,EAAE;AAAA,YAC5D;AAAA,UACF;AACA,kBAAQ,IAAI,EAAE;AAAA,QAChB;AAEA,YAAI,QAAQ,SAAS,GAAG;AACtB,kBAAQ,IAAIA,OAAM,KAAK,OAAO,2BAA2B,QAAQ,MAAM,GAAG,CAAC;AAC3E,qBAAW,OAAO,QAAQ,MAAM,GAAG,EAAE,GAAG;AACtC,oBAAQ;AAAA,cACNA,OAAM,OAAO,WAAM,IACjB,IAAI,IAAI,OAAO,cACfA,OAAM,IAAI,GAAG,IAAI,aAAa,OAAO,IAAI,aAAa,EAAE;AAAA,YAC5D;AAAA,UACF;AACA,kBAAQ,IAAI,EAAE;AAAA,QAChB;AAAA,MACF;AAEA,UAAI,UAAU,KAAK,WAAW,GAAG;AAC/B,gBAAQ,IAAIA,OAAM,MAAM,gDAA2C,CAAC;AACpE,gBAAQ,IAAI,EAAE;AAAA,MAChB;AAAA,IACF;AAAA,EACF;AAGA,MAAI,YAAY;AACd,YAAQ;AAAA,MACN,KAAK;AAAA,QACH,EAAE,UAAU,UAAU,aAAa,UAAU;AAAA,QAC7C;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF,CAAC;;;ACjJH,SAAS,WAAAG,gBAAe;AACxB,OAAOC,YAAW;AAClB,OAAOC,UAAS;AAChB,SAAS,gBAAAC,eAAc,eAAAC,oBAAmB;;;ACH1C,eAAsB,UAAU,QAAwC;AACtE,MAAI;AACF,UAAM,SAAS,QAAQ,IAAI,kBAAkB;AAC7C,UAAM,MAAM,MAAM,MAAM,GAAG,MAAM,iBAAiB;AAAA,MAChD,SAAS,EAAE,eAAe,UAAU,MAAM,GAAG;AAAA,MAC7C,QAAQ,YAAY,QAAQ,GAAK;AAAA,IACnC,CAAC;AACD,QAAI,CAAC,IAAI,GAAI,QAAO;AACpB,UAAM,OAAQ,MAAM,IAAI,KAAK;AAC7B,WAAO,KAAK,QAAQ;AAAA,EACtB,QAAQ;AACN,WAAO;AAAA,EACT;AACF;;;ADNA,SAAS,MAAM,IAA2B;AACxC,SAAO,IAAI,QAAQ,CAAC,MAAM,WAAW,GAAG,EAAE,CAAC;AAC7C;AAEO,IAAM,eAAe,IAAIC,SAAQ,OAAO,EAC5C,YAAY,iEAAiE,EAC7E,SAAS,SAAS,uCAAuC,EACzD,OAAO,WAAW,2CAA2C,KAAK,EAClE,OAAO,wBAAwB,6DAA6D,EAC5F,OAAO,mBAAmB,+DAA+D,EACzF,OAAO,UAAU,0BAA0B,KAAK,EAChD,OAAO,OAAO,KAAa,SAAS;AACnC,QAAM,aAAa,KAAK;AACxB,QAAM,YAAY,KAAK;AAGvB,WAAS,OAAO,MAAiB;AAC/B,QAAI,CAAC,WAAY,SAAQ,IAAI,GAAG,IAAI;AAAA,EACtC;AAGA,WAAS,KAAK,MAAc;AAC1B,WAAO,aAAa,OAAOC,KAAI,IAAI,EAAE,MAAM;AAAA,EAC7C;AAGA,MAAI,CAAC,IAAI,WAAW,SAAS,KAAK,CAAC,IAAI,WAAW,UAAU,GAAG;AAC7D,UAAM,WAAW,GAAG;AAAA,EACtB;AAEA,MAAI;AACJ,MAAI;AACF,cAAU,IAAI,IAAI,GAAG;AAAA,EACvB,QAAQ;AACN,YAAQ,MAAMC,OAAM,IAAI,gBAAgB,CAAC;AACzC,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,QAAM,SAAS,QAAQ;AACvB,QAAM,OAAO,QAAQ;AAErB,MAAI,EAAE;AACN,MAAIA,OAAM,KAAK,gBAAgB,IAAIA,OAAM,IAAI,WAAM,MAAM,EAAE,CAAC;AAC5D,MAAI,EAAE;AAGN,MAAI,WAAW;AACb,UAAM,SAAS,MAAM,cAAc,KAAK,MAAM;AAC9C,QAAI,CAAC,QAAQ;AACX,UAAIA,OAAM,IAAI,yDAAoD,CAAC;AACnE,UAAIA,OAAM,IAAI,WAAW,IAAIA,OAAM,KAAK,iBAAiB,CAAC;AAC1D,UAAIA,OAAM,IAAI,4CAA4C,CAAC;AAC3D,UAAI,EAAE;AACN,cAAQ,KAAK,CAAC;AAAA,IAChB;AAEA,UAAM,OAAO,MAAM,UAAU,MAAM;AACnC,QAAI,CAAC,MAAM;AACT,UAAIA,OAAM,IAAI,2BAAsB,CAAC;AACrC,UAAI,EAAE;AACN,cAAQ,KAAK,CAAC;AAAA,IAChB;AAEA,QAAI,SAAS,QAAQ;AACnB,UAAIA,OAAM,IAAI,gDAA2C,CAAC;AAC1D,UAAIA,OAAM,IAAI,2CAA2C,CAAC;AAC1D,UAAI,EAAE;AACN,cAAQ,KAAK,CAAC;AAAA,IAChB;AAAA,EACF;AAGA,QAAM,iBAAiB,KAAK,qBAAqB;AACjD,QAAM,gBAAgB,MAAMC,cAAa,MAAM;AAC/C,QAAM,aAAa,GAAG,MAAM;AAE5B,MAAI,CAAC,cAAc,SAAS,cAAc,KAAK,WAAW,GAAG;AAC3D,oBAAgB,KAAK,kBAAkB;AACvC,QAAID,OAAM,IAAI,4BAA4B,IAAIA,OAAM,KAAK,iBAAiB,CAAC;AAC3E,QAAI,EAAE;AACN,QAAI,YAAY;AACd,cAAQ,IAAI,KAAK,UAAU,EAAE,OAAO,mBAAmB,GAAG,MAAM,CAAC,CAAC;AAAA,IACpE;AACA,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,kBAAgB,QAAQ,wBAAmB,cAAc,KAAK,MAAM,OAAO;AAG3E,QAAM,gBAAgB,KAAK,wBAAwB;AACnD,QAAM,eAAe,MAAME,aAAY,MAAM;AAC7C,MAAI,kBAAkB;AAEtB,MAAI,aAAa,OAAO;AACtB,sBAAkB,aAAa,YAAY;AAAA,MAAK,CAAC,MAC/C,EAAE,YAAY,EAAE,SAAS,SAAS;AAAA,IACpC;AACA,QAAI,iBAAiB;AACnB,qBAAe,QAAQ,+BAA+B;AAAA,IACxD,OAAO;AACL,qBAAe,KAAK,gDAAgD;AACpE,UAAIF,OAAM,IAAI,gCAAgC,CAAC;AAC/C,UAAIA,OAAM,IAAI,cAAc,UAAU,EAAE,CAAC;AAAA,IAC3C;AAAA,EACF,OAAO;AACL,mBAAe,KAAK,qBAAqB;AACzC,QAAIA,OAAM,IAAI,qBAAqB,IAAIA,OAAM,KAAK,iBAAiB,CAAC;AAAA,EACtE;AAEA,MAAI,EAAE;AAIN,QAAM,cAAc,KAAK,eAAe,QAAQ,IAAI,gBAAgB,MAAM,gBAAgB,QAAQ,IAAI,CAAC;AACvG,QAAM,iBAA4E,CAAC;AAEnF,MAAI,aAAa;AACf,UAAM,OAAO,cAAc,KAAK,IAAI,CAAC,MAAM,EAAE,GAAG;AAChD,UAAM,kBAAkB,KAAK,4BAA4B;AAEzD,UAAM,kBAAkB;AAAA,MACtB,EAAE,MAAM,eAAe,UAAU,oCAAoC;AAAA,IACvE;AAEA,eAAW,UAAU,iBAAiB;AACpC,UAAI;AACF,cAAM,MAAM,MAAM,MAAM,OAAO,UAAU;AAAA,UACvC,QAAQ;AAAA,UACR,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,UAC9C,MAAM,KAAK,UAAU;AAAA,YACnB;AAAA,YACA,KAAK;AAAA,YACL,aAAa,GAAG,MAAM,IAAI,WAAW;AAAA,YACrC,SAAS,KAAK,MAAM,GAAG,GAAK;AAAA;AAAA,UAC9B,CAAC;AAAA,UACD,QAAQ,YAAY,QAAQ,IAAK;AAAA,QACnC,CAAC;AAED,YAAI,IAAI,MAAM,IAAI,WAAW,KAAK;AAChC,yBAAe,KAAK,EAAE,WAAW,MAAM,QAAQ,OAAO,MAAM,QAAQ,IAAI,OAAO,CAAC;AAChF,2BAAiB,QAAQ,mBAAc,KAAK,MAAM,sBAAsB,OAAO,IAAI,EAAE;AAAA,QACvF,OAAO;AACL,yBAAe,KAAK,EAAE,WAAW,OAAO,QAAQ,OAAO,MAAM,QAAQ,IAAI,OAAO,CAAC;AACjF,2BAAiB,KAAK,mBAAc,OAAO,IAAI,kBAAkB,IAAI,MAAM,EAAE;AAAA,QAC/E;AAAA,MACF,SAAS,KAAK;AACZ,uBAAe,KAAK,EAAE,WAAW,OAAO,QAAQ,OAAO,KAAK,CAAC;AAC7D,yBAAiB,KAAK,mBAAc,eAAe,QAAQ,IAAI,UAAU,QAAQ,EAAE;AAAA,MACrF;AAAA,IACF;AAAA,EACF,OAAO;AACL,QAAIA,OAAM,KAAK,YAAY,IAAIA,OAAM,IAAI,6BAA6B,CAAC;AACvE,QAAIA,OAAM,IAAI,wBAAwB,IAAIA,OAAM,KAAK,iBAAiB,IAAIA,OAAM,IAAI,8BAA8B,CAAC;AACnH,QAAI,EAAE;AAAA,EACR;AAEA,MAAIA,OAAM,KAAK,yBAAyB,CAAC;AACzC,MAAIA,OAAM,IAAI,oDAAoD,CAAC;AACnE,MAAIA,OAAM,IAAI,eAAe,IAAIA,OAAM,UAAU,0CAA0C,CAAC;AAC5F,MAAIA,OAAM,IAAI,uBAAuB,IAAI,EAAE,CAAC;AAC5C,MAAIA,OAAM,IAAI,0DAA0D,CAAC;AACzE,MAAI,EAAE;AAGN,MAAI,oBAAqE;AAEzE,MAAI,KAAK,OAAO;AACd,UAAM,eAAe,KAAK,+BAA+B;AACzD,wBAAoB,CAAC;AACrB,UAAM,OAAO,cAAc,KAAK,IAAI,CAAC,MAAM,EAAE,GAAG;AAChD,QAAI,eAAe;AAEnB,aAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;AACpC,YAAM,UAAU,KAAK,CAAC;AACtB,UAAI,cAAc;AAChB,qBAAa,OAAO,0BAA0B,IAAI,CAAC,IAAI,KAAK,MAAM;AAAA,MACpE;AAEA,UAAI;AACF,cAAM,WAAW,yDAAyD,mBAAmB,OAAO,CAAC;AACrG,cAAM,MAAM,MAAM,MAAM,UAAU;AAAA,UAChC,QAAQ;AAAA,UACR,QAAQ,YAAY,QAAQ,GAAI;AAAA,UAChC,UAAU;AAAA,UACV,SAAS;AAAA,YACP,cAAc;AAAA,UAChB;AAAA,QACF,CAAC;AAED,cAAM,UAAU,IAAI,WAAW,OAAO,IAAI,WAAW,OAAO,IAAI,WAAW;AAC3E,0BAAkB,KAAK,EAAE,KAAK,SAAS,QAAQ,CAAC;AAChD,YAAI,QAAS;AAAA,MACf,QAAQ;AACN,0BAAkB,KAAK,EAAE,KAAK,SAAS,SAAS,MAAM,CAAC;AAAA,MACzD;AAEA,YAAM,MAAM,GAAG;AAAA,IACjB;AAEA,kBAAc,QAAQ,eAAe,YAAY,IAAI,KAAK,MAAM,8BAA8B;AAE9F,QAAI,CAAC,YAAY;AACf,cAAQ,IAAI,EAAE;AACd,YAAM,aAAa,kBAAkB,OAAO,CAAC,MAAM,CAAC,EAAE,OAAO;AAE7D,UAAI,WAAW,SAAS,GAAG;AACzB,gBAAQ,IAAIA,OAAM,KAAK,kBAAkB,WAAW,MAAM,GAAG,CAAC;AAC9D,mBAAW,KAAK,WAAW,MAAM,GAAG,EAAE,GAAG;AACvC,kBAAQ,IAAIA,OAAM,IAAI,WAAM,IAAI,EAAE,GAAG;AAAA,QACvC;AACA,YAAI,WAAW,SAAS,IAAI;AAC1B,kBAAQ,IAAIA,OAAM,IAAI,aAAa,WAAW,SAAS,EAAE,OAAO,CAAC;AAAA,QACnE;AACA,gBAAQ,IAAI,EAAE;AAAA,MAChB,OAAO;AACL,gBAAQ,IAAIA,OAAM,MAAM,mCAA8B,CAAC;AACvD,gBAAQ,IAAI,EAAE;AAAA,MAChB;AAAA,IACF;AAAA,EACF;AAGA,MAAI,YAAY;AACd,YAAQ,IAAI,KAAK,UAAU;AAAA,MACzB,SAAS,EAAE,KAAK,YAAY,MAAM,cAAc,KAAK,OAAO;AAAA,MAC5D,WAAW,EAAE,OAAO,aAAa,OAAO,mBAAmB,gBAAgB;AAAA,MAC3E,UAAU,eAAe,SAAS,IAAI,iBAAiB;AAAA,MACvD,YAAY;AAAA,IACd,GAAG,MAAM,CAAC,CAAC;AAAA,EACb,OAAO;AACL,YAAQ,IAAIA,OAAM,KAAK,iDAAmB,CAAC;AAC3C,YAAQ,IAAI,EAAE;AACd,YAAQ,IAAI,qBAAqB,cAAc,KAAK,MAAM,OAAO;AAEjE,QAAI;AACJ,QAAI,CAAC,aAAa,OAAO;AACvB,qBAAeA,OAAM,IAAI,kBAAa;AAAA,IACxC,WAAW,iBAAiB;AAC1B,qBAAeA,OAAM,MAAM,2BAAsB;AAAA,IACnD,OAAO;AACL,qBAAeA,OAAM,OAAO,4BAAuB;AAAA,IACrD;AACA,YAAQ,IAAI,qBAAqB,YAAY,EAAE;AAE/C,QAAI,eAAe,SAAS,GAAG;AAC7B,iBAAW,KAAK,gBAAgB;AAC9B,cAAM,SAAS,EAAE,YAAYA,OAAM,MAAM,kBAAa,IAAIA,OAAM,IAAI,eAAU;AAC9E,gBAAQ,IAAI,qBAAqB,MAAM,KAAK,EAAE,MAAM,GAAG;AAAA,MACzD;AAAA,IACF,OAAO;AACL,cAAQ,IAAI,qBAAqBA,OAAM,IAAI,sCAAsC,CAAC,EAAE;AAAA,IACtF;AACA,QAAI,mBAAmB;AACrB,YAAM,eAAe,kBAAkB,OAAO,CAAC,MAAM,EAAE,OAAO,EAAE;AAChE,cAAQ,IAAI,qBAAqB,YAAY,IAAI,kBAAkB,MAAM,UAAU;AAAA,IACrF;AACA,YAAQ,IAAI,EAAE;AAAA,EAChB;AACF,CAAC;;;AEzQH,SAAS,WAAAG,gBAAe;AACxB,OAAOC,YAAW;AAClB,OAAOC,UAAS;AAChB,SAAS,gBAAAC,qBAAoB;AAuB7B,IAAM,aAAa;AAAA,EACjB,KAAK,EAAE,MAAM,MAAM,MAAM,IAAK;AAAA,EAC9B,KAAK,EAAE,MAAM,KAAK,MAAM,KAAK;AAAA,EAC7B,KAAK,EAAE,MAAM,KAAK,MAAM,IAAI;AAC9B;AAIA,SAAS,UACP,QACA,OACgC;AAChC,QAAM,IAAI,WAAW,MAAM;AAC3B,MAAI,SAAS,EAAE,KAAM,QAAO;AAC5B,MAAI,SAAS,EAAE,KAAM,QAAO;AAC5B,SAAO;AACT;AAEA,SAAS,eAAe,QAAwC;AAC9D,MAAI,WAAW,OAAQ,QAAOF,OAAM;AACpC,MAAI,WAAW,aAAc,QAAOA,OAAM;AAC1C,SAAOA,OAAM;AACf;AAEA,SAAS,cAAc,QAAwC;AAC7D,MAAI,WAAW,OAAQ,QAAOA,OAAM,MAAM,QAAG;AAC7C,MAAI,WAAW,aAAc,QAAOA,OAAM,OAAO,QAAG;AACpD,SAAOA,OAAM,IAAI,QAAG;AACtB;AAEA,SAAS,SAAS,IAAoB;AACpC,MAAI,MAAM,IAAM,QAAO,IAAI,KAAK,KAAM,QAAQ,CAAC,CAAC;AAChD,SAAO,GAAG,KAAK,MAAM,EAAE,CAAC;AAC1B;AAEA,SAAS,UAAU,OAAuB;AACxC,SAAO,MAAM,QAAQ,CAAC;AACxB;AAEA,SAASG,YAAW,OAAe;AACjC,MAAI,SAAS,GAAI,QAAOH,OAAM;AAC9B,MAAI,SAAS,GAAI,QAAOA,OAAM;AAC9B,SAAOA,OAAM;AACf;AAEA,SAASI,OAAM,IAA2B;AACxC,SAAO,IAAI,QAAQ,CAAC,MAAM,WAAW,GAAG,EAAE,CAAC;AAC7C;AAIA,eAAsB,SACpB,KACA,UACqB;AACrB,QAAM,SAAS,IAAI,gBAAgB;AAAA,IACjC;AAAA,IACA;AAAA,IACA,UAAU;AAAA,EACZ,CAAC;AAED,QAAM,MAAM,MAAM;AAAA,IAChB,8DAA8D,MAAM;AAAA,IACpE,EAAE,QAAQ,YAAY,QAAQ,GAAK,EAAE;AAAA,EACvC;AAEA,MAAI,CAAC,IAAI,IAAI;AACX,UAAM,OAAO,MAAM,IAAI,KAAK,EAAE,MAAM,MAAM,EAAE;AAC5C,UAAM,IAAI,MAAM,yBAAyB,IAAI,MAAM,KAAK,KAAK,MAAM,GAAG,GAAG,CAAC,EAAE;AAAA,EAC9E;AAEA,QAAM,OAAO,MAAM,IAAI,KAAK;AAC5B,SAAO,iBAAiB,IAAI;AAC9B;AAEO,SAAS,iBAAiB,MAAuB;AACtD,QAAM,KAAK,KAAK;AAChB,MAAI,CAAC,GAAI,OAAM,IAAI,MAAM,qCAAqC;AAE9D,QAAM,YAAY,GAAG,YAAY,aAAa;AAC9C,MAAI,aAAa,KAAM,OAAM,IAAI,MAAM,sCAAsC;AAE7E,SAAO;AAAA,IACL,kBAAkB,KAAK,MAAM,YAAY,GAAG;AAAA,IAC5C,KAAK,GAAG,SAAS,0BAA0B,GAAG,gBAAgB;AAAA,IAC9D,KAAK,GAAG,SAAS,yBAAyB,GAAG,gBAAgB;AAAA,IAC7D,KAAK,GAAG,SAAS,2BAA2B,GAAG,gBAAgB;AAAA,IAC/D,KAAK,GAAG,SAAS,wBAAwB,GAAG,gBAAgB;AAAA,IAC5D,IAAI,GAAG,SAAS,aAAa,GAAG,gBAAgB;AAAA,IAChD,KAAK,GAAG,SAAS,qBAAqB,GAAG,gBAAgB;AAAA,EAC3D;AACF;AAEO,SAAS,aACd,SACA,SACU;AACV,QAAM,WAAqB,CAAC;AAE5B,MAAI,QAAQ,SAAS,QAAQ,QAAQ,mBAAmB,QAAQ,OAAO;AACrE,aAAS;AAAA,MACP,qBAAqB,QAAQ,gBAAgB,oBAAoB,QAAQ,KAAK;AAAA,IAChF;AAAA,EACF;AACA,MAAI,QAAQ,OAAO,QAAQ,QAAQ,MAAM,QAAQ,KAAK;AACpD,aAAS;AAAA,MACP,OAAO,SAAS,QAAQ,GAAG,CAAC,mBAAmB,SAAS,QAAQ,GAAG,CAAC;AAAA,IACtE;AAAA,EACF;AACA,MAAI,QAAQ,OAAO,QAAQ,QAAQ,MAAM,QAAQ,KAAK;AACpD,aAAS;AAAA,MACP,OAAO,UAAU,QAAQ,GAAG,CAAC,mBAAmB,UAAU,QAAQ,GAAG,CAAC;AAAA,IACxE;AAAA,EACF;AAEA,SAAO;AACT;AAIA,SAAS,gBAAgB,QAAoB;AAC3C,QAAM,EAAE,KAAK,UAAU,SAAS,MAAM,IAAI;AAE1C,UAAQ;AAAA,IACNJ,OAAM,KAAK,eAAe,IAAIA,OAAM,IAAI,WAAM,GAAG,KAAK,QAAQ,GAAG;AAAA,EACnE;AACA,UAAQ,IAAI,EAAE;AAEd,MAAI,SAAS,CAAC,SAAS;AACrB,YAAQ,IAAIA,OAAM,IAAI,YAAO,SAAS,eAAe,EAAE,CAAC;AACxD,YAAQ,IAAI,EAAE;AACd;AAAA,EACF;AAEA,QAAM,KAAKG,YAAW,QAAQ,gBAAgB;AAC9C,QAAM,WACJ,QAAQ,oBAAoB,KACxBH,OAAM,MAAM,QAAG,IACf,QAAQ,oBAAoB,KAC1BA,OAAM,OAAO,QAAG,IAChBA,OAAM,IAAI,QAAG;AACrB,UAAQ;AAAA,IACN,KAAK,QAAQ,IAAIA,OAAM,KAAK,aAAa,CAAC,KAAK,GAAGA,OAAM,KAAK,GAAG,QAAQ,gBAAgB,MAAM,CAAC,CAAC;AAAA,EAClG;AACA,UAAQ,IAAI,EAAE;AAGd,UAAQ,IAAIA,OAAM,KAAK,mBAAmB,CAAC;AAE3C,QAAM,YAAY,UAAU,OAAO,QAAQ,GAAG;AAC9C,QAAM,YAAY,UAAU,OAAO,QAAQ,GAAG;AAC9C,QAAM,YAAY,UAAU,OAAO,QAAQ,GAAG;AAE9C,UAAQ;AAAA,IACN,KAAK,cAAc,SAAS,CAAC,IAAI,eAAe,SAAS,EAAE,SAAS,QAAQ,GAAG,EAAE,OAAO,CAAC,CAAC,CAAC,IAAIA,OAAM,IAAI,+BAA+B,CAAC;AAAA,EAC3I;AACA,UAAQ;AAAA,IACN,KAAK,cAAc,SAAS,CAAC,IAAI,eAAe,SAAS,EAAE,UAAU,QAAQ,GAAG,EAAE,OAAO,CAAC,CAAC,CAAC,IAAIA,OAAM,IAAI,8BAA8B,CAAC;AAAA,EAC3I;AACA,UAAQ;AAAA,IACN,KAAK,cAAc,SAAS,CAAC,IAAI,eAAe,SAAS,EAAE,SAAS,QAAQ,GAAG,EAAE,OAAO,CAAC,CAAC,CAAC,IAAIA,OAAM,IAAI,gCAAgC,CAAC;AAAA,EAC5I;AACA,UAAQ,IAAI,EAAE;AAGd,UAAQ,IAAIA,OAAM,KAAK,iBAAiB,CAAC;AACzC,UAAQ;AAAA,IACN,OAAO,SAAS,QAAQ,GAAG,EAAE,OAAO,CAAC,CAAC,IAAIA,OAAM,IAAI,6BAA6B,CAAC;AAAA,EACpF;AACA,UAAQ;AAAA,IACN,OAAO,SAAS,QAAQ,EAAE,EAAE,OAAO,CAAC,CAAC,IAAIA,OAAM,IAAI,kBAAkB,CAAC;AAAA,EACxE;AACA,UAAQ;AAAA,IACN,OAAO,SAAS,QAAQ,GAAG,EAAE,OAAO,CAAC,CAAC,IAAIA,OAAM,IAAI,0BAA0B,CAAC;AAAA,EACjF;AACA,UAAQ,IAAI,EAAE;AAChB;AAEA,SAAS,sBAAsB,SAAuB;AACpD,QAAM,QAAQ,QAAQ,OAAO,CAAC,MAAM,EAAE,OAAO;AAC7C,MAAI,MAAM,WAAW,EAAG;AAExB,QAAM,WAAW,KAAK;AAAA,IACpB,MAAM,OAAO,CAAC,GAAG,MAAM,IAAI,EAAE,QAAS,kBAAkB,CAAC,IAAI,MAAM;AAAA,EACrE;AACA,QAAM,WAAW,KAAK,IAAI,GAAG,MAAM,IAAI,CAAC,MAAM,EAAE,QAAS,GAAG,CAAC;AAC7D,QAAM,WAAW,KAAK,IAAI,GAAG,MAAM,IAAI,CAAC,MAAM,EAAE,QAAS,GAAG,CAAC;AAC7D,QAAM,WAAW,KAAK,IAAI,GAAG,MAAM,IAAI,CAAC,MAAM,EAAE,QAAS,GAAG,CAAC;AAE7D,UAAQ,IAAIA,OAAM,KAAK,iDAAmB,CAAC;AAC3C,UAAQ,IAAI,EAAE;AACd,UAAQ,IAAI,qBAAqBA,OAAM,KAAK,OAAO,QAAQ,MAAM,CAAC,CAAC,EAAE;AACrE,UAAQ;AAAA,IACN,qBAAqBG,YAAW,QAAQ,EAAEH,OAAM,KAAK,GAAG,QAAQ,MAAM,CAAC,CAAC;AAAA,EAC1E;AAEA,QAAM,OAAO,UAAU,OAAO,QAAQ;AACtC,QAAM,OAAO,UAAU,OAAO,QAAQ;AACtC,QAAM,OAAO,UAAU,OAAO,QAAQ;AAEtC,UAAQ;AAAA,IACN,qBAAqB,eAAe,IAAI,EAAE,SAAS,QAAQ,CAAC,CAAC;AAAA,EAC/D;AACA,UAAQ;AAAA,IACN,qBAAqB,eAAe,IAAI,EAAE,UAAU,QAAQ,CAAC,CAAC;AAAA,EAChE;AACA,UAAQ;AAAA,IACN,qBAAqB,eAAe,IAAI,EAAE,SAAS,QAAQ,CAAC,CAAC;AAAA,EAC/D;AACA,UAAQ,IAAI,EAAE;AAChB;AAIO,IAAM,cAAc,IAAID,SAAQ,MAAM,EAC1C,YAAY,6DAA6D,EACzE,SAAS,SAAS,0CAA0C,EAC5D;AAAA,EACC;AAAA,EACA;AAAA,EACA;AACF,EACC;AAAA,EACC;AAAA,EACA;AAAA,EACA;AACF,EACC,OAAO,UAAU,0BAA0B,KAAK,EAChD,OAAO,qBAAqB,oCAAoC,EAChE,OAAO,wBAAwB,+BAA+B,EAC9D,OAAO,sBAAsB,oCAAoC,EACjE,OAAO,OAAO,KAAa,SAAS;AACnC,QAAM,aAAa,KAAK;AACxB,QAAM,WAAW,KAAK;AACtB,QAAM,YAAY,SAAS,KAAK,OAAO,EAAE;AAEzC,MAAI,aAAa,YAAY,aAAa,WAAW;AACnD,YAAQ;AAAA,MACNC,OAAM,IAAI,4CAA4C;AAAA,IACxD;AACA,YAAQ,KAAK,CAAC;AAAA,EAChB;AAGA,MAAI,CAAC,IAAI,WAAW,SAAS,KAAK,CAAC,IAAI,WAAW,UAAU,GAAG;AAC7D,UAAM,WAAW,GAAG;AAAA,EACtB;AAEA,MAAI;AACF,QAAI,IAAI,GAAG;AAAA,EACb,QAAQ;AACN,YAAQ,MAAMA,OAAM,IAAI,gBAAgB,CAAC;AACzC,YAAQ,KAAK,CAAC;AAAA,EAChB;AAGA,MAAI,OAAiB,CAAC,GAAG;AAEzB,MAAI,YAAY,GAAG;AACjB,UAAM,iBAAiB,aAAa,OAAOC,KAAI,qBAAqB,EAAE,MAAM;AAC5E,UAAM,UAAU,MAAMC,cAAa,GAAG;AAEtC,QAAI,QAAQ,SAAS,QAAQ,KAAK,SAAS,GAAG;AAC5C,aAAO,QAAQ,KAAK,MAAM,GAAG,SAAS,EAAE,IAAI,CAAC,MAAM,EAAE,GAAG;AACxD,sBAAgB;AAAA,QACd,SAAS,QAAQ,KAAK,MAAM,sBAAsB,KAAK,MAAM;AAAA,MAC/D;AAAA,IACF,OAAO;AACL,sBAAgB,KAAK,sCAAsC;AAAA,IAC7D;AACA,QAAI,CAAC,WAAY,SAAQ,IAAI,EAAE;AAAA,EACjC;AAGA,QAAM,UAAwB,CAAC;AAE/B,WAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;AACpC,UAAM,YAAY,KAAK,CAAC;AACxB,UAAM,UAAU,aACZ,OACAD;AAAA,MACE,KAAK,SAAS,IACV,WAAW,IAAI,CAAC,IAAI,KAAK,MAAM,KAAK,SAAS,KAC7C,WAAW,SAAS,KAAK,QAAQ;AAAA,IACvC,EAAE,MAAM;AAEZ,QAAI;AACF,YAAM,UAAU,MAAM,SAAS,WAAW,QAAQ;AAClD,eAAS,KAAK;AACd,cAAQ,KAAK,EAAE,KAAK,WAAW,UAAU,QAAQ,CAAC;AAElD,UAAI,CAAC,YAAY;AACf,wBAAgB,EAAE,KAAK,WAAW,UAAU,QAAQ,CAAC;AAAA,MACvD;AAAA,IACF,SAAS,KAAK;AACZ,YAAM,SAAS,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC9D,eAAS,KAAK,WAAW,SAAS,EAAE;AACpC,cAAQ,KAAK,EAAE,KAAK,WAAW,UAAU,SAAS,MAAM,OAAO,OAAO,CAAC;AAEvE,UAAI,CAAC,YAAY;AACf,gBAAQ,IAAID,OAAM,IAAI,KAAK,MAAM,EAAE,CAAC;AACpC,gBAAQ,IAAI,EAAE;AAAA,MAChB;AAAA,IACF;AAGA,QAAI,IAAI,KAAK,SAAS,GAAG;AACvB,YAAMI,OAAM,GAAI;AAAA,IAClB;AAAA,EACF;AAGA,MAAI,CAAC,cAAc,QAAQ,SAAS,GAAG;AACrC,0BAAsB,OAAO;AAAA,EAC/B;AAGA,MAAI,YAAY;AACd,UAAM,SACJ,QAAQ,WAAW,IACf;AAAA,MACE,KAAK,QAAQ,CAAC,EAAE;AAAA,MAChB,UAAU,QAAQ,CAAC,EAAE;AAAA,MACrB,GAAI,QAAQ,CAAC,EAAE,WAAW,CAAC;AAAA,MAC3B,OAAO,QAAQ,CAAC,EAAE,SAAS;AAAA,IAC7B,IACA;AAAA,MACE;AAAA,MACA,OAAO,QAAQ,IAAI,CAAC,OAAO;AAAA,QACzB,KAAK,EAAE;AAAA,QACP,GAAI,EAAE,WAAW,CAAC;AAAA,QAClB,OAAO,EAAE,SAAS;AAAA,MACpB,EAAE;AAAA,MACF,UAAU,MAAM;AACd,cAAM,QAAQ,QAAQ,OAAO,CAAC,MAAM,EAAE,OAAO;AAC7C,YAAI,MAAM,WAAW,EAAG,QAAO;AAC/B,eAAO;AAAA,UACL,UAAU,KAAK;AAAA,YACb,MAAM;AAAA,cACJ,CAAC,GAAG,MAAM,IAAI,EAAE,QAAS;AAAA,cACzB;AAAA,YACF,IAAI,MAAM;AAAA,UACZ;AAAA,UACA,UAAU,KAAK;AAAA,YACb,GAAG,MAAM,IAAI,CAAC,MAAM,EAAE,QAAS,GAAG;AAAA,UACpC;AAAA,UACA,UAAU,KAAK;AAAA,YACb,GAAG,MAAM,IAAI,CAAC,MAAM,EAAE,QAAS,GAAG;AAAA,UACpC;AAAA,UACA,UAAU,KAAK;AAAA,YACb,GAAG,MAAM,IAAI,CAAC,MAAM,EAAE,QAAS,GAAG;AAAA,UACpC;AAAA,QACF;AAAA,MACF,GAAG;AAAA,IACL;AACN,YAAQ,IAAI,KAAK,UAAU,QAAQ,MAAM,CAAC,CAAC;AAAA,EAC7C;AAGA,QAAM,UAAU;AAAA,IACd,KAAK,KAAK,YAAY,WAAW,KAAK,SAAS,IAAI;AAAA,IACnD,KAAK,KAAK,YAAY,WAAW,KAAK,SAAS,IAAI;AAAA,IACnD,OAAO,KAAK,cAAc,SAAS,KAAK,aAAa,EAAE,IAAI;AAAA,EAC7D;AAEA,QAAM,aACJ,QAAQ,OAAO,QAAQ,QAAQ,OAAO,QAAQ,QAAQ,SAAS;AAEjE,MAAI,YAAY;AACd,UAAM,cAAwB,CAAC;AAE/B,eAAW,KAAK,SAAS;AACvB,UAAI,CAAC,EAAE,QAAS;AAChB,YAAM,WAAW,aAAa,EAAE,SAAS,OAAO;AAChD,UAAI,SAAS,SAAS,GAAG;AACvB,oBAAY,KAAK,GAAG,SAAS,IAAI,CAAC,MAAM,GAAG,EAAE,GAAG,KAAK,CAAC,EAAE,CAAC;AAAA,MAC3D;AAAA,IACF;AAEA,QAAI,YAAY,SAAS,GAAG;AAC1B,UAAI,CAAC,YAAY;AACf,gBAAQ,IAAIJ,OAAM,IAAIA,OAAM,KAAK,oBAAoB,CAAC,CAAC;AACvD,mBAAW,KAAK,aAAa;AAC3B,kBAAQ,IAAIA,OAAM,IAAI,YAAO,CAAC,EAAE,CAAC;AAAA,QACnC;AACA,gBAAQ,IAAI,EAAE;AAAA,MAChB;AACA,cAAQ,KAAK,CAAC;AAAA,IAChB;AAAA,EACF;AACF,CAAC;;;AChaH,SAAS,WAAAK,gBAAe;AACxB,OAAOC,YAAW;AAClB,OAAOC,UAAS;AAGhB,SAASC,OAAM,IAA2B;AACxC,SAAO,IAAI,QAAQ,CAAC,MAAM,WAAW,GAAG,EAAE,CAAC;AAC7C;AAEA,eAAe,YAAY,KAA4B;AACrD,QAAM,EAAE,SAAS,IAAI;AACrB,QAAM,EAAE,KAAK,IAAI,MAAM,OAAO,eAAoB;AAElD,QAAM,MACJ,aAAa,WACT,SACA,aAAa,UACX,UACA;AAER,OAAK,GAAG,GAAG,IAAI,GAAG,EAAE;AACtB;AAEO,IAAM,cAAc,IAAIC,SAAQ,MAAM,EAC1C,YAAY,2DAA2D,EACvE,OAAO,mBAAmB,mDAAmD,EAC7E,OAAO,OAAO,SAAS;AACtB,QAAM,SAAS,QAAQ,IAAI,kBAAkB;AAC7C,QAAM,MAAM,QAAQ,IAAI;AAExB,UAAQ,IAAI,EAAE;AACd,UAAQ,IAAIC,OAAM,KAAK,eAAe,CAAC;AACvC,UAAQ,IAAI,EAAE;AAGd,QAAM,WAAW,MAAM,kBAAkB,GAAG;AAC5C,MAAI,UAAU;AACZ,YAAQ,IAAIA,OAAM,MAAM,UAAK,IAAI,sBAAsBA,OAAM,KAAK,SAAS,WAAW,CAAC,EAAE;AACzF,YAAQ,IAAIA,OAAM,IAAI,mBAAmB,SAAS,SAAS,EAAE,CAAC;AAC9D,YAAQ,IAAIA,OAAM,IAAI,kBAAkB,SAAS,QAAQ,EAAE,CAAC;AAC5D,YAAQ,IAAI,EAAE;AACd,YAAQ,IAAIA,OAAM,IAAI,yDAAyD,CAAC;AAChF,YAAQ,IAAI,EAAE;AACd;AAAA,EACF;AAGA,MAAI,KAAK,QAAQ;AACf,UAAM,UAAUC,KAAI,sBAAsB,EAAE,MAAM;AAElD,QAAI;AACF,YAAM,MAAM,MAAM,MAAM,GAAG,MAAM,wBAAwB;AAAA,QACvD,SAAS,EAAE,eAAe,UAAU,KAAK,MAAM,GAAG;AAAA,QAClD,QAAQ,YAAY,QAAQ,GAAK;AAAA,MACnC,CAAC;AAED,UAAI,CAAC,IAAI,IAAI;AACX,gBAAQ,KAAK,kBAAkB;AAC/B,gBAAQ,IAAID,OAAM,IAAI,2DAA2D,CAAC;AAClF,gBAAQ,IAAI,EAAE;AACd,gBAAQ,KAAK,CAAC;AAAA,MAChB;AAEA,YAAM,OAAQ,MAAM,IAAI,KAAK;AAC7B,YAAM,UAAU,KAAK;AACrB,cAAQ,QAAQ,aAAaA,OAAM,KAAK,QAAQ,IAAI,CAAC,EAAE;AAEvD,YAAM,kBAAkB,KAAK;AAAA,QAC3B,QAAQ,KAAK;AAAA,QACb,WAAW,QAAQ;AAAA,QACnB,aAAa,QAAQ;AAAA,QACrB,WAAU,oBAAI,KAAK,GAAE,YAAY;AAAA,MACnC,CAAC;AAGD,YAAM,gBAAgB,KAAK,QAAQ,KAAK,QAAQ,QAAQ,EAAE;AAE1D,cAAQ,IAAI,EAAE;AACd,cAAQ,IAAIA,OAAM,IAAI,uCAAuC,CAAC;AAC9D,cAAQ,IAAIA,OAAM,IAAI,oBAAoB,IAAIA,OAAM,KAAK,yBAAyB,IAAIA,OAAM,IAAI,qBAAqB,CAAC;AACtH,cAAQ,IAAI,EAAE;AACd;AAAA,IACF,SAAS,KAAK;AACZ,cAAQ,KAAK,eAAe,QAAQ,IAAI,UAAU,mBAAmB;AACrE,cAAQ,IAAI,EAAE;AACd,cAAQ,KAAK,CAAC;AAAA,IAChB;AAAA,EACF;AAGA,QAAM,cAAcC,KAAI,yBAAyB,EAAE,MAAM;AAEzD,MAAI;AACJ,MAAI;AAEJ,MAAI;AACF,UAAM,MAAM,MAAM,MAAM,GAAG,MAAM,iBAAiB;AAAA,MAChD,QAAQ;AAAA,MACR,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,MAC9C,QAAQ,YAAY,QAAQ,GAAK;AAAA,IACnC,CAAC;AAED,QAAI,CAAC,IAAI,IAAI;AACX,kBAAY,KAAK,8BAA8B;AAC/C,cAAQ,IAAID,OAAM,IAAI,gCAAgC,IAAIA,OAAM,KAAK,sCAAsC,CAAC;AAC5G,cAAQ,IAAI,EAAE;AACd,cAAQ,KAAK,CAAC;AAAA,IAChB;AAEA,UAAM,OAAQ,MAAM,IAAI,KAAK;AAC7B,iBAAa,KAAK;AAClB,eAAW,KAAK;AAChB,gBAAY,KAAK;AAAA,EACnB,SAAS,KAAK;AACZ,gBAAY,KAAK,eAAe,QAAQ,IAAI,UAAU,mBAAmB;AACzE,YAAQ,IAAIA,OAAM,IAAI,gCAAgC,IAAIA,OAAM,KAAK,sCAAsC,CAAC;AAC5G,YAAQ,IAAI,EAAE;AACd,YAAQ,KAAK,CAAC;AACd;AAAA,EACF;AAEA,QAAM,aAAa,GAAG,MAAM,qBAAqB,QAAQ;AAEzD,UAAQ,IAAIA,OAAM,KAAK,kCAAkC,CAAC;AAC1D,UAAQ,IAAI,EAAE;AACd,UAAQ,IAAI,KAAKA,OAAM,UAAU,UAAU,CAAC,EAAE;AAC9C,UAAQ,IAAI,EAAE;AACd,UAAQ,IAAI,gBAAgBA,OAAM,KAAK,KAAK,QAAQ,CAAC,EAAE;AACvD,UAAQ,IAAI,EAAE;AAGd,MAAI;AACF,UAAM,YAAY,UAAU;AAC5B,YAAQ,IAAIA,OAAM,IAAI,iCAAiC,CAAC;AAAA,EAC1D,QAAQ;AAAA,EAER;AAGA,QAAM,cAAcC,KAAI,8BAA8B,EAAE,MAAM;AAC9D,QAAM,UAAU,IAAI,KAAK;AACzB,QAAM,eAAe;AACrB,QAAM,YAAY,KAAK,IAAI;AAE3B,SAAO,KAAK,IAAI,IAAI,YAAY,SAAS;AACvC,UAAMH,OAAM,YAAY;AAExB,QAAI;AACF,YAAM,MAAM,MAAM,MAAM,GAAG,MAAM,sBAAsB,UAAU,IAAI;AAAA,QACnE,QAAQ,YAAY,QAAQ,GAAK;AAAA,MACnC,CAAC;AAED,UAAI,IAAI,WAAW,KAAK;AAEtB;AAAA,MACF;AAEA,UAAI,IAAI,IAAI;AACV,cAAM,OAAQ,MAAM,IAAI,KAAK;AAM7B,oBAAY,QAAQ,aAAaE,OAAM,KAAK,KAAK,WAAW,CAAC,EAAE;AAE/D,cAAM,kBAAkB,KAAK;AAAA,UAC3B,QAAQ,KAAK;AAAA,UACb,WAAW,KAAK;AAAA,UAChB,aAAa,KAAK;AAAA,UAClB,WAAU,oBAAI,KAAK,GAAE,YAAY;AAAA,QACnC,CAAC;AAGD,cAAM,gBAAgB,KAAK,QAAQ,KAAK,QAAQ,KAAK,SAAS;AAE9D,gBAAQ,IAAI,EAAE;AACd,gBAAQ,IAAIA,OAAM,IAAI,uCAAuC,CAAC;AAC9D,gBAAQ,IAAIA,OAAM,IAAI,oBAAoB,IAAIA,OAAM,KAAK,yBAAyB,IAAIA,OAAM,IAAI,qBAAqB,CAAC;AACtH,gBAAQ,IAAI,EAAE;AACd;AAAA,MACF;AAGA,kBAAY,KAAK,uBAAuB;AACxC,cAAQ,IAAI,EAAE;AACd,cAAQ,KAAK,CAAC;AAAA,IAChB,QAAQ;AAAA,IAER;AAAA,EACF;AAEA,cAAY,KAAK,kDAAkD;AACnE,UAAQ,IAAIA,OAAM,IAAI,eAAe,IAAIA,OAAM,KAAK,iBAAiB,CAAC;AACtE,UAAQ,IAAI,EAAE;AACd,UAAQ,KAAK,CAAC;AAChB,CAAC;AAMH,eAAe,gBACb,KACA,QACA,QACA,WACe;AACf,QAAM,cAAc,MAAM,gBAAgB,GAAG;AAC7C,MAAI,CAAC,YAAa;AAElB,MAAI;AACF,UAAM,MAAM,MAAM,MAAM,GAAG,MAAM,iBAAiB,SAAS,qBAAqB;AAAA,MAC9E,QAAQ;AAAA,MACR,SAAS;AAAA,QACP,gBAAgB;AAAA,QAChB,eAAe,UAAU,MAAM;AAAA,MACjC;AAAA,MACA,MAAM,KAAK,UAAU,EAAE,QAAQ,QAAQ,KAAK,YAAY,CAAC;AAAA,MACzD,QAAQ,YAAY,QAAQ,GAAK;AAAA,IACnC,CAAC;AAED,QAAI,IAAI,IAAI;AACV,cAAQ,IAAIA,OAAM,MAAM,UAAK,IAAI,mCAAmC;AAAA,IACtE;AAAA,EACF,QAAQ;AAAA,EAER;AACF;;;Af3NO,SAAS,gBAAyB;AACvC,QAAM,UAAU,IAAIE,SAAQ;AAE5B,UACG,KAAK,QAAQ,EACb,YAAY,yDAAyD,EACrE,QAAQ,OAAO;AAElB,UAAQ,WAAW,WAAW;AAC9B,UAAQ,WAAW,YAAY;AAC/B,UAAQ,WAAW,YAAY;AAC/B,UAAQ,WAAW,eAAe;AAClC,UAAQ,WAAW,YAAY;AAC/B,UAAQ,WAAW,WAAW;AAC9B,UAAQ,WAAW,WAAW;AAE9B,SAAO;AACT;","names":["Command","existsSync","writeFile","mkdir","readFile","join","existsSync","readFile","join","join","existsSync","readFile","join","writeFile","existsSync","readFile","mkdir","Command","chalk","ora","readFile","join","existsSync","readFile","join","chalk","scoreColor","chalk","Command","ora","chalk","Command","chalk","ora","chalk","Command","delay","ora","Command","chalk","ora","crawlSite","Command","chalk","ora","fetchSitemap","fetchRobots","Command","ora","chalk","fetchSitemap","fetchRobots","Command","chalk","ora","fetchSitemap","scoreColor","delay","Command","chalk","ora","delay","Command","chalk","ora","Command"]}