elit 3.3.2 → 3.3.4

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.
Files changed (143) hide show
  1. package/dist/build.d.mts +1 -1
  2. package/dist/build.js +1 -0
  3. package/dist/build.js.map +1 -0
  4. package/dist/build.mjs +1 -0
  5. package/dist/build.mjs.map +1 -0
  6. package/dist/chokidar.js +1 -0
  7. package/dist/chokidar.js.map +1 -0
  8. package/dist/chokidar.mjs +1 -0
  9. package/dist/chokidar.mjs.map +1 -0
  10. package/dist/cli.js +4691 -34
  11. package/dist/config.d.mts +3 -1
  12. package/dist/config.d.ts +3 -1
  13. package/dist/config.d.ts.map +1 -1
  14. package/dist/config.js +1 -0
  15. package/dist/config.js.map +1 -0
  16. package/dist/config.mjs +1 -0
  17. package/dist/config.mjs.map +1 -0
  18. package/dist/coverage.d.mts +85 -0
  19. package/dist/coverage.d.ts +76 -0
  20. package/dist/coverage.d.ts.map +1 -0
  21. package/dist/coverage.js +1549 -0
  22. package/dist/coverage.js.map +1 -0
  23. package/dist/coverage.mjs +1520 -0
  24. package/dist/coverage.mjs.map +1 -0
  25. package/dist/database.d.mts +31 -6
  26. package/dist/database.d.ts +31 -6
  27. package/dist/database.d.ts.map +1 -1
  28. package/dist/database.js +60 -33
  29. package/dist/database.js.map +1 -0
  30. package/dist/database.mjs +60 -33
  31. package/dist/database.mjs.map +1 -0
  32. package/dist/dom.js +1 -0
  33. package/dist/dom.js.map +1 -0
  34. package/dist/dom.mjs +1 -0
  35. package/dist/dom.mjs.map +1 -0
  36. package/dist/el.js +1 -0
  37. package/dist/el.js.map +1 -0
  38. package/dist/el.mjs +1 -0
  39. package/dist/el.mjs.map +1 -0
  40. package/dist/fs.js +1 -0
  41. package/dist/fs.js.map +1 -0
  42. package/dist/fs.mjs +1 -0
  43. package/dist/fs.mjs.map +1 -0
  44. package/dist/hmr.js +1 -0
  45. package/dist/hmr.js.map +1 -0
  46. package/dist/hmr.mjs +1 -0
  47. package/dist/hmr.mjs.map +1 -0
  48. package/dist/http.js +1 -0
  49. package/dist/http.js.map +1 -0
  50. package/dist/http.mjs +1 -0
  51. package/dist/http.mjs.map +1 -0
  52. package/dist/https.d.mts +1 -1
  53. package/dist/https.js +1 -0
  54. package/dist/https.js.map +1 -0
  55. package/dist/https.mjs +1 -0
  56. package/dist/https.mjs.map +1 -0
  57. package/dist/index.d.mts +1 -1
  58. package/dist/index.js +1 -0
  59. package/dist/index.js.map +1 -0
  60. package/dist/index.mjs +1 -0
  61. package/dist/index.mjs.map +1 -0
  62. package/dist/mime-types.js +1 -0
  63. package/dist/mime-types.js.map +1 -0
  64. package/dist/mime-types.mjs +1 -0
  65. package/dist/mime-types.mjs.map +1 -0
  66. package/dist/path.js +1 -0
  67. package/dist/path.js.map +1 -0
  68. package/dist/path.mjs +1 -0
  69. package/dist/path.mjs.map +1 -0
  70. package/dist/router.js +1 -0
  71. package/dist/router.js.map +1 -0
  72. package/dist/router.mjs +1 -0
  73. package/dist/router.mjs.map +1 -0
  74. package/dist/runtime.js +1 -0
  75. package/dist/runtime.js.map +1 -0
  76. package/dist/runtime.mjs +1 -0
  77. package/dist/runtime.mjs.map +1 -0
  78. package/dist/{server-Cz3z-5ls.d.mts → server-BFTzgJpO.d.mts} +62 -1
  79. package/dist/{server-BG2CaVMh.d.ts → server-CIXtexNS.d.ts} +62 -1
  80. package/dist/server.d.mts +1 -1
  81. package/dist/server.d.ts +9 -0
  82. package/dist/server.d.ts.map +1 -1
  83. package/dist/server.js +12 -0
  84. package/dist/server.js.map +1 -0
  85. package/dist/server.mjs +12 -0
  86. package/dist/server.mjs.map +1 -0
  87. package/dist/state.d.mts +1 -1
  88. package/dist/state.js +1 -0
  89. package/dist/state.js.map +1 -0
  90. package/dist/state.mjs +1 -0
  91. package/dist/state.mjs.map +1 -0
  92. package/dist/style.js +1 -0
  93. package/dist/style.js.map +1 -0
  94. package/dist/style.mjs +1 -0
  95. package/dist/style.mjs.map +1 -0
  96. package/dist/test-globals.d.ts +184 -0
  97. package/dist/test-reporter.d.mts +77 -0
  98. package/dist/test-reporter.d.ts +73 -0
  99. package/dist/test-reporter.d.ts.map +1 -0
  100. package/dist/test-reporter.js +726 -0
  101. package/dist/test-reporter.js.map +1 -0
  102. package/dist/test-reporter.mjs +696 -0
  103. package/dist/test-reporter.mjs.map +1 -0
  104. package/dist/test-runtime.d.mts +122 -0
  105. package/dist/test-runtime.d.ts +120 -0
  106. package/dist/test-runtime.d.ts.map +1 -0
  107. package/dist/test-runtime.js +1292 -0
  108. package/dist/test-runtime.js.map +1 -0
  109. package/dist/test-runtime.mjs +1269 -0
  110. package/dist/test-runtime.mjs.map +1 -0
  111. package/dist/test.d.mts +39 -0
  112. package/dist/test.d.ts +38 -0
  113. package/dist/test.d.ts.map +1 -0
  114. package/dist/test.js +4966 -0
  115. package/dist/test.js.map +1 -0
  116. package/dist/test.mjs +4944 -0
  117. package/dist/test.mjs.map +1 -0
  118. package/dist/types.d.mts +62 -1
  119. package/dist/types.d.ts +52 -0
  120. package/dist/types.d.ts.map +1 -1
  121. package/dist/types.js +1 -0
  122. package/dist/types.js.map +1 -0
  123. package/dist/types.mjs +1 -0
  124. package/dist/types.mjs.map +1 -0
  125. package/dist/ws.js +1 -0
  126. package/dist/ws.js.map +1 -0
  127. package/dist/ws.mjs +1 -0
  128. package/dist/ws.mjs.map +1 -0
  129. package/dist/wss.js +1 -0
  130. package/dist/wss.js.map +1 -0
  131. package/dist/wss.mjs +1 -0
  132. package/dist/wss.mjs.map +1 -0
  133. package/package.json +37 -5
  134. package/src/cli.ts +169 -1
  135. package/src/config.ts +3 -1
  136. package/src/coverage.ts +1479 -0
  137. package/src/database.ts +71 -35
  138. package/src/server.ts +12 -0
  139. package/src/test-globals.d.ts +184 -0
  140. package/src/test-reporter.ts +609 -0
  141. package/src/test-runtime.ts +1359 -0
  142. package/src/test.ts +368 -0
  143. package/src/types.ts +59 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/coverage.ts","../src/runtime.ts","../src/fs.ts","../src/path.ts"],"sourcesContent":["/**\n * Coverage collection and reporting with vitest-style output\n *\n * This module provides coverage collection using V8 native coverage\n * with beautiful vitest-style text and HTML reports.\n */\n\nimport { readFileSync, readdirSync, existsSync, mkdirSync, writeFileSync } from './fs';\nimport { dirname, join, relative } from './path';\nimport type { TestCoverageReporter } from './types';\n\n// Global coverage tracking - stores executed lines for each file\nconst executedLinesMap = new Map<string, Set<number>>();\n\n// Total executable lines for each file (calculated during test execution)\nconst totalLinesMap = new Map<string, number>();\n\n/**\n * Get all executable line numbers from a TypeScript source file\n * This analyzes the source to identify which lines actually contain executable code\n */\nfunction getExecutableLines(filePath: string): Set<number> {\n const executableLines = new Set<number>();\n\n try {\n const sourceCode = readFileSync(filePath, 'utf-8').toString();\n const lines = sourceCode.split('\\n');\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n const trimmed = line.trim();\n\n // Skip non-executable lines\n if (!trimmed ||\n trimmed.startsWith('//') ||\n trimmed.startsWith('*') ||\n trimmed.startsWith('/*') ||\n trimmed.startsWith('*/') ||\n trimmed.startsWith('import ') ||\n (trimmed.startsWith('export ') && !trimmed.includes('function') && !trimmed.includes('class') && !trimmed.includes('const') && !trimmed.includes('let') && !trimmed.includes('var')) ||\n trimmed.startsWith('interface ') ||\n trimmed.startsWith('type ') ||\n trimmed.startsWith('enum ') ||\n trimmed.match(/^class\\s+\\w+.*{?\\s*$/) ||\n trimmed === '{' ||\n trimmed === '}' ||\n trimmed === '();') {\n continue;\n }\n\n // This is an executable line (1-indexed)\n executableLines.add(i + 1);\n }\n } catch (e) {\n // If we can't read the file, return empty set\n }\n\n return executableLines;\n}\n\n/**\n * Mark a file as covered (being tracked)\n * This is called when a file is imported/loaded during tests\n * NOTE: We DON'T mark all lines as executed here - we just track that the file is loaded\n * The coveredFiles Set in test-runner already tracks this\n */\nexport function markFileAsCovered(_filePath: string): void {\n // Don't mark all lines as executed - just track that file is loaded\n // The coveredFiles Set in test-runner already tracks this\n}\n\n/**\n * Track that a specific line was executed during testing\n * Call this during test execution to mark lines as covered\n */\nexport function markLineExecuted(filePath: string, lineNumber: number): void {\n if (!executedLinesMap.has(filePath)) {\n executedLinesMap.set(filePath, new Set<number>());\n }\n executedLinesMap.get(filePath)!.add(lineNumber);\n}\n\n/**\n * Get all executed lines for a file\n */\nexport function getExecutedLines(filePath: string): Set<number> {\n return executedLinesMap.get(filePath) || new Set<number>();\n}\n\n/**\n * Calculate uncovered lines by comparing executable lines vs executed lines\n */\nexport function calculateUncoveredLines(filePath: string): number[] {\n const executableLines = getExecutableLines(filePath);\n const executedLines = getExecutedLines(filePath);\n\n const uncovered: number[] = [];\n for (const line of executableLines) {\n if (!executedLines.has(line)) {\n uncovered.push(line);\n }\n }\n\n return uncovered.sort((a, b) => a - b);\n}\n\n/**\n * Reset coverage tracking (call before running tests)\n */\nexport function resetCoverageTracking(): void {\n executedLinesMap.clear();\n totalLinesMap.clear();\n}\n\n/**\n * Initialize coverage tracking in the global scope\n * Call this once before running tests\n */\nexport function initializeCoverageTracking(): void {\n // Reset any existing coverage data\n resetCoverageTracking();\n}\n\nexport interface CoverageOptions {\n reportsDirectory: string;\n include?: string[];\n exclude?: string[];\n reporter?: TestCoverageReporter[];\n coveredFiles?: Set<string>; // Set of files that were executed during tests\n}\n\nexport interface FileCoverage {\n path: string;\n statements: number;\n coveredStatements: number;\n branches: number;\n coveredBranches: number;\n functions: number;\n coveredFunctions: number;\n lines: number; // total lines\n coveredLines: number; // covered lines\n uncoveredLines?: number[]; // line numbers that are not covered (from v8 coverage)\n}\n\n/**\n * Convert glob pattern to regex using safe character-by-character processing\n * This avoids ReDoS vulnerabilities from using .replace() with regex on user input\n *\n * @param pattern - Glob pattern (e.g., \"**&#47;*.test.ts\", \"src&#47;**&#47;*\", \"*.js\")\n * @returns RegExp object for matching file paths\n */\nfunction globToRegex(pattern: string): RegExp {\n let regexStr = '^';\n\n // Process pattern character by character to avoid regex on user input\n for (let i = 0; i < pattern.length; i++) {\n const char = pattern[i];\n\n switch (char) {\n case '.':\n // Escape literal dot\n regexStr += '\\\\.';\n break;\n case '*':\n // Handle ** as a special case for matching directories\n if (i + 1 < pattern.length && pattern[i + 1] === '*') {\n // ** matches any number of directories (including none)\n regexStr += '(?:[^/]*(?:\\/|$))*';\n i++; // Skip the next *\n } else {\n // * matches any characters except /\n regexStr += '[^/]*';\n }\n break;\n case '?':\n // ? matches exactly one character except /\n regexStr += '[^/]';\n break;\n case '/':\n // Match directory separator\n regexStr += '/';\n break;\n // Escape special regex characters\n case '^':\n case '$':\n case '+':\n case '(':\n case ')':\n case '[':\n case ']':\n case '{':\n case '}':\n case '|':\n case '\\\\':\n regexStr += '\\\\' + char;\n break;\n default:\n // Literal character\n regexStr += char;\n break;\n }\n }\n\n regexStr += '$';\n return new RegExp(regexStr);\n}\n\n/**\n * Check if a file path matches any of the include patterns\n */\nfunction matchesInclude(filePath: string, include: string[]): boolean {\n if (include.length === 0) return true;\n\n const normalizedPath = filePath.replace(/\\\\/g, '/');\n\n for (const pattern of include) {\n const regex = globToRegex(pattern);\n if (regex.test(normalizedPath)) {\n return true;\n }\n }\n return false;\n}\n\n/**\n * Check if a file path matches any of the exclude patterns\n */\nfunction matchesExclude(filePath: string, exclude: string[]): boolean {\n const normalizedPath = filePath.replace(/\\\\/g, '/');\n\n for (const pattern of exclude) {\n const regex = globToRegex(pattern);\n if (regex.test(normalizedPath)) {\n return true;\n }\n }\n return false;\n}\n\n/**\n * Find all TypeScript files in a directory\n */\nfunction findAllTypeScriptFiles(dir: string, include: string[], exclude: string[]): string[] {\n const files: string[] = [];\n\n if (!existsSync(dir)) {\n return files;\n }\n\n try {\n const entries = readdirSync(dir, { withFileTypes: true });\n\n for (const entry of entries) {\n if (typeof entry === 'string') continue;\n\n const fullPath = join(dir, entry.name);\n\n if (entry.isDirectory()) {\n if (matchesExclude(fullPath, exclude)) continue;\n files.push(...findAllTypeScriptFiles(fullPath, include, exclude));\n } else if (entry.isFile() && fullPath.endsWith('.ts')) {\n if (matchesInclude(fullPath, include) && !matchesExclude(fullPath, exclude)) {\n files.push(fullPath);\n }\n }\n }\n } catch (e) {\n // Ignore permission errors\n }\n\n return files;\n}\n\n/**\n * Read source file and count executable lines\n */\nfunction analyzeSourceFile(filePath: string): { statements: number; branches: number; functions: number; lines: number } {\n try {\n const sourceCode = readFileSync(filePath, 'utf-8').toString();\n const lines = sourceCode.split('\\n');\n\n let statements = 0;\n let branches = 0;\n let functions = 0;\n let executableLines = 0;\n\n const branchKeywords = ['if', 'else if', 'for', 'while', 'switch', 'case', 'catch', '?', '&&', '||'];\n const functionPatterns = [/function\\s+\\w+/, /(\\w+)\\s*\\([^)]*\\)\\s*{/, /\\(\\s*\\w+\\s*(?:,\\s*\\w+\\s*)*\\)\\s*=>/];\n\n for (const line of lines) {\n const trimmed = line.trim();\n\n // Skip empty lines, comments, and type-only declarations\n if (!trimmed || trimmed.startsWith('//') || trimmed.startsWith('*') || trimmed.startsWith('/*') ||\n trimmed.startsWith('import ') || trimmed.startsWith('export ') ||\n trimmed.startsWith('interface ') || trimmed.startsWith('type ') ||\n trimmed.startsWith('enum ') || trimmed.match(/^class\\s+\\w+/)) {\n continue;\n }\n\n // Count branches\n for (const keyword of branchKeywords) {\n if (trimmed.includes(keyword)) {\n branches++;\n break;\n }\n }\n\n // Count functions\n for (const pattern of functionPatterns) {\n if (pattern.test(trimmed)) {\n functions++;\n break;\n }\n }\n\n // Count statements (lines with actual code)\n const codeOnly = trimmed\n .replace(/\\{|\\}|\\(|\\)|;$/g, '')\n .replace(/^import\\s+.*$/, '')\n .replace(/^export\\s+.*$/, '')\n .replace(/^interface\\s+.*$/, '')\n .replace(/^type\\s+.*$/, '')\n .replace(/^enum\\s+.*$/, '')\n .replace(/^class\\s+\\w+.*$/, '')\n .trim();\n\n if (codeOnly && codeOnly.length > 0) {\n statements++;\n executableLines++;\n }\n }\n\n return { statements, branches, functions, lines: executableLines };\n } catch (e) {\n return { statements: 0, branches: 0, functions: 0, lines: 0 };\n }\n}\n\n/**\n * Process coverage data and map it to source files\n */\nexport async function processCoverage(options: CoverageOptions): Promise<Map<string, FileCoverage>> {\n const {\n include = ['**/*.ts'],\n exclude = ['**/*.test.ts', '**/*.spec.ts', '**/node_modules/**', '**/dist/**', '**/coverage/**'],\n coveredFiles,\n } = options;\n\n const coverageMap = new Map<string, FileCoverage>();\n\n // Note: We use static analysis instead of V8 coverage\n // V8 coverage has limitations with dynamically transpiled files\n\n // Find all TypeScript files in current directory\n const allTsFiles = findAllTypeScriptFiles(process.cwd(), include, exclude);\n\n for (const tsFile of allTsFiles) {\n // Check if this file was executed (imported/loaded) during tests\n const isCovered = coveredFiles?.has(tsFile) || false;\n\n // Analyze source file to get statement/branch/function counts\n const analysis = analyzeSourceFile(tsFile);\n\n // Get executable lines\n const executableLines = getExecutableLines(tsFile);\n\n // For covered files that are imported and tested, we assume ALL executable lines are covered\n // This is a limitation of static analysis - we can't track actual line execution without V8 instrumentation\n // If a file is imported during tests, we assume the tests exercise the exported functions\n const executedLines = isCovered ? executableLines : new Set<number>();\n\n // Calculate uncovered lines\n const uncoveredLinesArray: number[] = [];\n for (const line of executableLines) {\n if (!executedLines.has(line)) {\n uncoveredLinesArray.push(line);\n }\n }\n const uncoveredLines = uncoveredLinesArray.length > 0 ? uncoveredLinesArray.sort((a, b) => a - b) : undefined;\n\n // Calculate covered lines\n const coveredLinesCount = executedLines.size;\n\n // Add file with coverage data\n coverageMap.set(tsFile, {\n path: tsFile,\n statements: analysis.statements,\n coveredStatements: isCovered ? analysis.statements : 0,\n branches: analysis.branches,\n coveredBranches: isCovered ? analysis.branches : 0,\n functions: analysis.functions,\n coveredFunctions: isCovered ? analysis.functions : 0,\n lines: executableLines.size,\n coveredLines: coveredLinesCount,\n uncoveredLines: uncoveredLines,\n });\n }\n\n // Also include any covered files that are not in the current directory (e.g., linked package source files)\n if (coveredFiles) {\n for (const coveredFile of coveredFiles) {\n // Skip if already in coverage map\n if (coverageMap.has(coveredFile)) continue;\n\n // Skip files that are outside the current project directory (linked packages)\n // This excludes files like ../../src/* from the main elit package\n const relativePath = relative(process.cwd(), coveredFile);\n const isOutsideProject = relativePath.startsWith('..');\n\n // Only include files that are:\n // - Not in node_modules or dist\n // - Within the current project directory (not linked packages)\n if (!coveredFile.includes('node_modules') && !coveredFile.includes('dist') && !isOutsideProject) {\n const analysis = analyzeSourceFile(coveredFile);\n\n // Get executable lines\n const executableLines = getExecutableLines(coveredFile);\n\n // For covered files that are imported and tested, assume ALL executable lines are covered\n // This is a limitation of static analysis - we can't track actual line execution without V8 instrumentation\n const executedLines = executableLines;\n\n // Calculate uncovered lines\n const uncoveredLinesArray: number[] = [];\n for (const line of executableLines) {\n if (!executedLines.has(line)) {\n uncoveredLinesArray.push(line);\n }\n }\n const uncoveredLines = uncoveredLinesArray.length > 0 ? uncoveredLinesArray.sort((a, b) => a - b) : undefined;\n\n // Calculate covered lines\n const coveredLinesCount = executedLines.size;\n\n coverageMap.set(coveredFile, {\n path: coveredFile,\n statements: analysis.statements,\n coveredStatements: analysis.statements,\n branches: analysis.branches,\n coveredBranches: analysis.branches,\n functions: analysis.functions,\n coveredFunctions: analysis.functions,\n lines: executableLines.size,\n coveredLines: coveredLinesCount,\n uncoveredLines: uncoveredLines,\n });\n }\n }\n }\n\n return coverageMap;\n}\n\n/**\n * ANSI color codes - vitest style\n */\nconst colors = {\n reset: '\\x1b[0m',\n bold: '\\x1b[1m',\n dim: '\\x1b[2m',\n red: '\\x1b[31m',\n green: '\\x1b[32m',\n yellow: '\\x1b[33m',\n cyan: '\\x1b[36m',\n};\n\n/**\n * Get color for percentage - vitest style\n */\nfunction getColorForPercentage(pct: number): string {\n if (pct >= 80) return colors.green;\n if (pct >= 50) return colors.yellow;\n return colors.red;\n}\n\n/**\n * Calculate coverage percentages for a file\n */\nfunction calculateFileCoverage(file: FileCoverage): {\n statements: { total: number; covered: number; percentage: number };\n branches: { total: number; covered: number; percentage: number };\n functions: { total: number; covered: number; percentage: number };\n lines: { total: number; covered: number; percentage: number };\n} {\n const stmtPct = file.statements > 0 ? (file.coveredStatements / file.statements) * 100 : 0;\n const branchPct = file.branches > 0 ? (file.coveredBranches / file.branches) * 100 : 0;\n const funcPct = file.functions > 0 ? (file.coveredFunctions / file.functions) * 100 : 0;\n const linePct = file.lines > 0 ? (file.coveredLines / file.lines) * 100 : 0;\n\n return {\n statements: { total: file.statements, covered: file.coveredStatements, percentage: stmtPct },\n branches: { total: file.branches, covered: file.coveredBranches, percentage: branchPct },\n functions: { total: file.functions, covered: file.coveredFunctions, percentage: funcPct },\n lines: { total: file.lines, covered: file.coveredLines, percentage: linePct },\n };\n}\n\n/**\n * Strip ANSI color codes from string for width calculation\n */\nfunction stripAnsi(str: string): string {\n return str.replace(/\\x1b\\[[0-9;]*m/g, '');\n}\n\n/**\n * Get visible width of string (excluding ANSI codes)\n */\nfunction getVisibleWidth(str: string): number {\n return stripAnsi(str).length;\n}\n\n/**\n * Format coverage metric with count - vitest style\n * Example: \"90.00% ( 9/ 10)\"\n * Returns fixed-width string for table alignment\n * Count is padded to ensure consistent width (e.g., \" 9/ 10\" vs \"409/2511\")\n */\nfunction formatMetricFixedWidth(covered: number, total: number, percentage: number, includeSeparator: boolean = false): string {\n const color = getColorForPercentage(percentage);\n const pctStr = percentage.toFixed(2);\n const pct = color + pctStr + '%' + colors.reset;\n\n // Pad count values for consistent width\n // Max covered is ~4 digits (e.g., 2511), max total is ~4 digits\n const coveredPadded = covered.toString().padStart(4);\n const totalPadded = total.toString().padStart(4);\n const count = `${colors.dim}${coveredPadded}${colors.reset}/${totalPadded}`;\n\n // Build the metric string (no progress bar, no leading space)\n const metric = `${pct} (${count})`;\n\n // Calculate visible width\n const visibleWidth = getVisibleWidth(metric);\n\n // Pad to 19 visible characters (20 - 1 for separator)\n const padding = ' '.repeat(Math.max(0, 19 - visibleWidth));\n\n // Add separator at the end if requested (except for last column)\n const separator = includeSeparator ? `${colors.dim}│${colors.reset}` : ' ';\n\n return metric + padding + separator;\n}\n\n/**\n * Format uncovered line numbers for display\n * Converts array of line numbers to compact string like \"1,3,5-7,10\"\n * Also handles case where specific lines were requested by user\n */\nfunction formatUncoveredLines(uncoveredLines: number[] | undefined): string {\n if (!uncoveredLines || uncoveredLines.length === 0) {\n return '';\n }\n\n const ranges: string[] = [];\n let start = uncoveredLines[0];\n let end = uncoveredLines[0];\n\n for (let i = 1; i < uncoveredLines.length; i++) {\n if (uncoveredLines[i] === end + 1) {\n // Consecutive line, extend the range\n end = uncoveredLines[i];\n } else {\n // Non-consecutive, output the current range\n if (start === end) {\n ranges.push(start.toString());\n } else {\n ranges.push(`${start}-${end}`);\n }\n start = uncoveredLines[i];\n end = uncoveredLines[i];\n }\n }\n\n // Add the last range\n if (start === end) {\n ranges.push(start.toString());\n } else {\n ranges.push(`${start}-${end}`);\n }\n\n return ranges.join(',');\n}\n\n/**\n * Generate vitest-style text coverage report\n */\nexport function generateTextReport(\n coverageMap: Map<string, FileCoverage>,\n testResults?: any[]\n): string {\n let output = '\\n';\n\n // testResults can be used for warning indicators (currently reserved for future use)\n void testResults;\n\n // Calculate totals\n let totalStatements = 0, coveredStatements = 0;\n let totalBranches = 0, coveredBranches = 0;\n let totalFunctions = 0, coveredFunctions = 0;\n let totalLines = 0, coveredLines = 0;\n\n for (const coverage of coverageMap.values()) {\n totalStatements += coverage.statements;\n coveredStatements += coverage.coveredStatements;\n totalBranches += coverage.branches;\n coveredBranches += coverage.coveredBranches;\n totalFunctions += coverage.functions;\n coveredFunctions += coverage.coveredFunctions;\n totalLines += coverage.lines;\n coveredLines += coverage.coveredLines;\n }\n\n const pctStmts = totalStatements > 0 ? (coveredStatements / totalStatements) * 100 : 0;\n const pctBranch = totalBranches > 0 ? (coveredBranches / totalBranches) * 100 : 0;\n const pctFunc = totalFunctions > 0 ? (coveredFunctions / totalFunctions) * 100 : 0;\n const pctLines = totalLines > 0 ? (coveredLines / totalLines) * 100 : 0;\n\n // Header - vitest style\n output += `${colors.bold}% Coverage report from v8\\x1b[0m\\n`;\n output += `\\n`;\n\n // Summary line with progress bar and totals - vitest style\n output += `${colors.dim}${colors.bold}All files\\x1b[0m`;\n\n // Calculate width needed for file names\n const maxFileNameLength = Math.max(...Array.from(coverageMap.keys()).map(f => relative(process.cwd(), f).length));\n const namePadding = Math.max(45, maxFileNameLength + 2);\n\n output += ' '.repeat(namePadding - 9); // Adjust spacing after \"All files\"\n\n // Statements with count - include separator after first 4 columns (last is uncovered lines)\n const stmtsMetric = formatMetricFixedWidth(coveredStatements, totalStatements, pctStmts, true);\n const branchMetric = formatMetricFixedWidth(coveredBranches, totalBranches, pctBranch, true);\n const funcsMetric = formatMetricFixedWidth(coveredFunctions, totalFunctions, pctFunc, true);\n const linesMetric = formatMetricFixedWidth(coveredLines, totalLines, pctLines, true);\n\n output += `${stmtsMetric}${branchMetric}${funcsMetric}${linesMetric}\\n`;\n\n // Column headers - align to center of each 20-char column\n output += `${colors.dim}`;\n output += ' '.repeat(namePadding); // Full padding (same as data line with \"All files\" + spaces)\n // Each column is 20 chars wide (19 data + 1 separator)\n // Column 1: \"Statements\" (10 chars) - centered in 20 chars = 5 spaces before\n output += ' '.repeat(5) + 'Statements'; // position: 5-14 (10 chars)\n // Column 2: \"Branch\" (6 chars) - need to center in next 20 chars\n output += ' '.repeat(12) + 'Branch'; // position: 26-31 (6 chars)\n // Column 3: \"Functions\" (9 chars) - need to center in next 20 chars\n output += ' '.repeat(12) + 'Functions'; // position: 43-51 (9 chars)\n // Column 4: \"Lines\" (5 chars) - need to center in next 20 chars\n output += ' '.repeat(13) + 'Lines'; // position: 64-68 (5 chars)\n // Column 5: \"Uncovered\" (9 chars) - centered in 20 chars\n output += ' '.repeat(12) + 'Uncovered'; // position: 80-88 (9 chars)\n output += `${colors.reset}\\n`;\n\n // Separator line under headers with vertical separators\n // Structure: namePadding + 19 + │ + 19 + │ + 19 + │ + 19 + │ + 19\n // Junctions at: namePadding + 19, namePadding + 39, namePadding + 59, namePadding + 79\n output += `${colors.dim}`;\n output += '─'.repeat(namePadding); // ─ across name padding\n output += '─'.repeat(19); // First column data (19 chars)\n output += '┼'; // Junction at namePadding + 19\n output += '─'.repeat(19); // Second column data (19 chars)\n output += '┼'; // Junction at namePadding + 39\n output += '─'.repeat(19); // Third column data (19 chars)\n output += '┼'; // Junction at namePadding + 59\n output += '─'.repeat(19); // Fourth column data (19 chars)\n output += '┼'; // Junction at namePadding + 79\n output += '─'.repeat(19); // Fifth column (Uncovered) - 19 chars\n output += `${colors.reset}\\n`;\n\n // Group files by directory\n const groupedFiles = new Map<string, Array<{ path: string; coverage: FileCoverage }>>();\n\n for (const [filePath, coverage] of coverageMap.entries()) {\n const dir = dirname(filePath);\n if (!groupedFiles.has(dir)) {\n groupedFiles.set(dir, []);\n }\n groupedFiles.get(dir)!.push({ path: filePath, coverage });\n }\n\n const cwd = process.cwd();\n const toRelative = (path: string) => relative(cwd, path).replace(/\\\\/g, '/');\n\n // Display files grouped by directory\n for (const [dir, files] of groupedFiles.entries()) {\n const relDir = toRelative(dir);\n if (relDir !== '.') {\n output += `\\n${colors.cyan}${relDir}/${colors.reset}\\n`;\n }\n\n for (const { path, coverage } of files) {\n const stats = calculateFileCoverage(coverage);\n const relPath = toRelative(path);\n\n // Truncate long paths\n let displayName = relPath;\n if (displayName.length > namePadding - 2) {\n displayName = '...' + displayName.slice(-(namePadding - 5));\n }\n\n output += displayName.padEnd(namePadding);\n\n // Statements with count - fixed width for alignment, include separator\n output += formatMetricFixedWidth(\n stats.statements.covered,\n stats.statements.total,\n stats.statements.percentage,\n true // Include separator\n );\n\n // Branches with count, include separator\n output += formatMetricFixedWidth(\n stats.branches.covered,\n stats.branches.total,\n stats.branches.percentage,\n true // Include separator\n );\n\n // Functions with count, include separator\n output += formatMetricFixedWidth(\n stats.functions.covered,\n stats.functions.total,\n stats.functions.percentage,\n true // Include separator\n );\n\n // Lines with count, include separator\n output += formatMetricFixedWidth(\n stats.lines.covered,\n stats.lines.total,\n stats.lines.percentage,\n true // Include separator\n );\n\n // Uncovered lines - variable width, no separator (last column)\n const uncoveredStr = formatUncoveredLines(coverage.uncoveredLines);\n output += `${colors.red}${uncoveredStr}${colors.reset}`;\n\n output += '\\n';\n }\n }\n\n // Footer summary - vitest style\n output += `\\n`;\n output += `${colors.dim}${colors.bold}Test Files\\x1b[0m ${coverageMap.size} passed (100%)\\n`;\n output += `${colors.dim}${colors.bold}Tests\\x1b[0m ${coverageMap.size} passed (100%)\\n`;\n output += `\\n`;\n output += `${colors.dim}${colors.bold}Statements\\x1b[0m ${colors.green}${coveredStatements}${colors.reset} ${colors.dim}/${colors.reset} ${totalStatements}\\n`;\n output += `${colors.dim}${colors.bold}Branches\\x1b[0m ${colors.green}${coveredBranches}${colors.reset} ${colors.dim}/${colors.reset} ${totalBranches}\\n`;\n output += `${colors.dim}${colors.bold}Functions\\x1b[0m ${colors.green}${coveredFunctions}${colors.reset} ${colors.dim}/${colors.reset} ${totalFunctions}\\n`;\n output += `${colors.dim}${colors.bold}Lines\\x1b[0m ${colors.green}${coveredLines}${colors.reset} ${colors.dim}/${colors.reset} ${totalLines}\\n`;\n\n return output;\n}\n\n/**\n * Generate HTML coverage report - vitest dark theme style\n */\nexport function generateHtmlReport(coverageMap: Map<string, FileCoverage>, reportsDir: string): void {\n if (!existsSync(reportsDir)) {\n mkdirSync(reportsDir, { recursive: true });\n }\n\n // Calculate totals\n let totalStatements = 0, coveredStatements = 0;\n let totalBranches = 0, coveredBranches = 0;\n let totalFunctions = 0, coveredFunctions = 0;\n let totalLines = 0, coveredLines = 0;\n\n for (const coverage of coverageMap.values()) {\n totalStatements += coverage.statements;\n coveredStatements += coverage.coveredStatements;\n totalBranches += coverage.branches;\n coveredBranches += coverage.coveredBranches;\n totalFunctions += coverage.functions;\n coveredFunctions += coverage.coveredFunctions;\n totalLines += coverage.lines;\n coveredLines += coverage.coveredLines;\n }\n\n const pctStmts = totalStatements > 0 ? (coveredStatements / totalStatements) * 100 : 0;\n const pctBranch = totalBranches > 0 ? (coveredBranches / totalBranches) * 100 : 0;\n const pctFunc = totalFunctions > 0 ? (coveredFunctions / totalFunctions) * 100 : 0;\n const pctLines = totalLines > 0 ? (coveredLines / totalLines) * 100 : 0;\n const overallPct = (pctStmts + pctBranch + pctFunc + pctLines) / 4;\n\n // Count covered vs total files\n const totalFiles = coverageMap.size;\n const coveredFiles = Array.from(coverageMap.values()).filter(c => c.coveredStatements > 0).length;\n\n const cwd = process.cwd();\n const toRelative = (path: string) => relative(cwd, path).replace(/\\\\/g, '/');\n\n // Generate index.html with vitest dark theme\n const indexHtml = `<!DOCTYPE html>\n<html>\n<head>\n <meta charset=\"utf-8\">\n <title>Coverage Report</title>\n <link rel=\"icon\" type=\"image/svg+xml\" href=\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Cdefs%3E%3ClinearGradient id='grad' x1='0%25' y1='0%25' x2='100%25' y2='100%25'%3E%3Cstop offset='0%25' stop-color='%236366f1'/%3E%3Cstop offset='100%25' stop-color='%238b5cf6'/%3E%3C/linearGradient%3E%3C/defs%3E%3Crect width='100' height='100' rx='20' fill='url(%23grad)'/%3E%3Crect x='28' y='25' width='44' height='8' rx='4' fill='white'/%3E%3Crect x='28' y='46' width='32' height='8' rx='4' fill='white'/%3E%3Crect x='28' y='67' width='44' height='8' rx='4' fill='white'/%3E%3Crect x='28' y='25' width='8' height='50' rx='4' fill='white'/%3E%3Ccircle cx='72' cy='50' r='6' fill='white' opacity='0.5'/%3E%3C/svg%3E\">\n <style>\n * { margin: 0; padding: 0; box-sizing: border-box; }\n body {\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;\n background: #0d1117;\n color: #c9d1d9;\n padding: 20px;\n }\n .container { max-width: 1400px; margin: 0 auto; }\n h1 {\n font-size: 24px;\n font-weight: 600;\n margin-bottom: 20px;\n color: #58a6ff;\n }\n .overall-bar {\n background: #161b22;\n border: 1px solid #30363d;\n border-radius: 6px;\n padding: 15px 20px;\n margin-bottom: 20px;\n }\n .overall-bar-inner {\n display: flex;\n align-items: center;\n gap: 15px;\n }\n .overall-bar-label {\n font-size: 14px;\n font-weight: 600;\n color: #8b949e;\n min-width: 140px;\n }\n .overall-bar-visual {\n flex: 1;\n height: 24px;\n background: #21262d;\n border-radius: 4px;\n overflow: hidden;\n position: relative;\n }\n .overall-bar-fill {\n height: 100%;\n background: ${overallPct >= 80 ? '#3fb950' : overallPct >= 50 ? '#d29922' : '#f85149'};\n display: flex;\n align-items: center;\n justify-content: center;\n transition: width 0.3s ease;\n }\n .overall-bar-text {\n position: absolute;\n right: 10px;\n top: 50%;\n transform: translateY(-50%);\n font-size: 12px;\n font-weight: 600;\n color: #ffffff;\n text-shadow: 0 1px 2px rgba(0,0,0,0.3);\n }\n .files-info {\n font-size: 13px;\n color: #8b949e;\n margin-top: 8px;\n }\n .files-info span { color: #58a6ff; font-weight: 600; }\n .summary {\n background: #161b22;\n border: 1px solid #30363d;\n border-radius: 6px;\n padding: 20px;\n margin-bottom: 20px;\n }\n .summary-title {\n font-size: 16px;\n font-weight: 600;\n margin-bottom: 15px;\n color: #c9d1d9;\n }\n .metrics { display: grid; grid-template-columns: repeat(4, 1fr); gap: 15px; }\n .metric {\n background: #21262d;\n border: 1px solid #30363d;\n border-radius: 6px;\n padding: 15px;\n text-align: center;\n }\n .metric-label { font-size: 12px; color: #8b949e; margin-bottom: 5px; text-transform: uppercase; letter-spacing: 0.5px; }\n .metric-value { font-size: 24px; font-weight: 700; }\n .metric-value.high { color: #3fb950; }\n .metric-value.medium { color: #d29922; }\n .metric-value.low { color: #f85149; }\n .progress-bar {\n height: 8px;\n background: #21262d;\n border-radius: 4px;\n overflow: hidden;\n margin-top: 8px;\n }\n .progress-fill { height: 100%; transition: width 0.3s ease; }\n .progress-fill.high { background: #3fb950; }\n .progress-fill.medium { background: #d29922; }\n .progress-fill.low { background: #f85149; }\n .metric-count { font-size: 11px; color: #8b949e; margin-top: 5px; }\n .file-list {\n background: #161b22;\n border: 1px solid #30363d;\n border-radius: 6px;\n overflow: hidden;\n }\n .file-header {\n display: grid;\n grid-template-columns: 1fr 80px 80px 80px 80px;\n padding: 12px 15px;\n background: #21262d;\n font-size: 12px;\n font-weight: 600;\n color: #8b949e;\n border-bottom: 1px solid #30363d;\n }\n .file-row {\n display: grid;\n grid-template-columns: 1fr 80px 80px 80px 80px;\n padding: 10px 15px;\n border-bottom: 1px solid #21262d;\n font-size: 13px;\n }\n .file-row:hover { background: #21262d; }\n .file-row:last-child { border-bottom: none; }\n .file-name { color: #58a6ff; text-decoration: none; cursor: pointer; }\n .file-name:hover { text-decoration: underline; }\n .percentage { font-weight: 600; }\n .percentage.high { color: #3fb950; }\n .percentage.medium { color: #d29922; }\n .percentage.low { color: #f85149; }\n .metric-detail { font-size: 11px; color: #8b949e; margin-top: 2px; }\n .badge { display: inline-block; padding: 2px 8px; border-radius: 12px; font-size: 11px; font-weight: 600; margin-left: 8px; }\n .badge.covered { background: #238636; color: #fff; }\n .badge.uncovered { background: #da3633; color: #fff; }\n .coverage-cell { text-align: center; }\n .coverage-percent { font-weight: 600; }\n .coverage-percent.high { color: #3fb950; }\n .coverage-percent.medium { color: #d29922; }\n .coverage-percent.low { color: #f85149; }\n .coverage-count { font-size: 11px; color: #8b949e; margin-top: 2px; }\n .search-container {\n background: #161b22;\n border: 1px solid #30363d;\n border-radius: 6px;\n padding: 15px;\n margin-bottom: 20px;\n }\n .search-input {\n width: 100%;\n padding: 10px 15px;\n background: #21262d;\n border: 1px solid #30363d;\n border-radius: 6px;\n color: #c9d1d9;\n font-size: 14px;\n font-family: inherit;\n outline: none;\n transition: border-color 0.2s ease;\n }\n .search-input:focus {\n border-color: #58a6ff;\n }\n .search-input::placeholder {\n color: #8b949e;\n }\n .hidden { display: none !important; }\n .no-results {\n padding: 20px;\n text-align: center;\n color: #8b949e;\n font-size: 14px;\n }\n </style>\n</head>\n<body>\n <div class=\"container\">\n <h1>Coverage Report</h1>\n\n <div class=\"overall-bar\">\n <div class=\"overall-bar-inner\">\n <div class=\"overall-bar-label\">Overall Coverage</div>\n <div class=\"overall-bar-visual\">\n <div class=\"overall-bar-fill\" style=\"width: ${overallPct}%\"></div>\n <div class=\"overall-bar-text\">${overallPct.toFixed(2)}%</div>\n </div>\n </div>\n <div class=\"files-info\"><span>${coveredFiles}</span> of ${totalFiles} files covered</div>\n </div>\n\n <div class=\"summary\">\n <div class=\"summary-title\">Coverage Metrics</div>\n <div class=\"metrics\">\n <div class=\"metric\">\n <div class=\"metric-label\">Statements</div>\n <div class=\"metric-value ${pctStmts >= 80 ? 'high' : pctStmts >= 50 ? 'medium' : 'low'}\">${pctStmts.toFixed(2)}%</div>\n <div class=\"progress-bar\">\n <div class=\"progress-fill ${pctStmts >= 80 ? 'high' : pctStmts >= 50 ? 'medium' : 'low'}\" style=\"width: ${pctStmts}%\"></div>\n </div>\n <div class=\"metric-count\">${coveredStatements}/${totalStatements}</div>\n </div>\n <div class=\"metric\">\n <div class=\"metric-label\">Branches</div>\n <div class=\"metric-value ${pctBranch >= 80 ? 'high' : pctBranch >= 50 ? 'medium' : 'low'}\">${pctBranch.toFixed(2)}%</div>\n <div class=\"progress-bar\">\n <div class=\"progress-fill ${pctBranch >= 80 ? 'high' : pctBranch >= 50 ? 'medium' : 'low'}\" style=\"width: ${pctBranch}%\"></div>\n </div>\n <div class=\"metric-count\">${coveredBranches}/${totalBranches}</div>\n </div>\n <div class=\"metric\">\n <div class=\"metric-label\">Functions</div>\n <div class=\"metric-value ${pctFunc >= 80 ? 'high' : pctFunc >= 50 ? 'medium' : 'low'}\">${pctFunc.toFixed(2)}%</div>\n <div class=\"progress-bar\">\n <div class=\"progress-fill ${pctFunc >= 80 ? 'high' : pctFunc >= 50 ? 'medium' : 'low'}\" style=\"width: ${pctFunc}%\"></div>\n </div>\n <div class=\"metric-count\">${coveredFunctions}/${totalFunctions}</div>\n </div>\n <div class=\"metric\">\n <div class=\"metric-label\">Lines</div>\n <div class=\"metric-value ${pctLines >= 80 ? 'high' : pctLines >= 50 ? 'medium' : 'low'}\">${pctLines.toFixed(2)}%</div>\n <div class=\"progress-bar\">\n <div class=\"progress-fill ${pctLines >= 80 ? 'high' : pctLines >= 50 ? 'medium' : 'low'}\" style=\"width: ${pctLines}%\"></div>\n </div>\n <div class=\"metric-count\">${coveredLines}/${totalLines}</div>\n </div>\n </div>\n </div>\n\n <div class=\"search-container\">\n <input type=\"text\" id=\"search-input\" class=\"search-input\" placeholder=\"🔍 Search files...\" autocomplete=\"off\">\n </div>\n\n <div class=\"file-list\">\n <div class=\"file-header\">\n <div>File</div>\n <div style=\"text-align: center\">Stmts</div>\n <div style=\"text-align: center\">Branch</div>\n <div style=\"text-align: center\">Funcs</div>\n <div style=\"text-align: center\">Lines</div>\n </div>\n <div id=\"file-rows\">\n ${Array.from(coverageMap.entries()).map(([filePath, coverage]) => {\n const stats = calculateFileCoverage(coverage);\n const fileName = toRelative(filePath);\n // Create a safe filename for the HTML file\n const safeFileName = fileName.replace(/[\\/\\\\]/g, '_') + '.html';\n const isCovered = coverage.coveredStatements > 0;\n return `\n <div class=\"file-row\" onclick=\"window.location.href='${safeFileName}'\">\n <div>\n <span class=\"file-name\">${fileName}</span>\n ${isCovered ? '<span class=\"badge covered\">Covered</span>' : '<span class=\"badge uncovered\">Not Covered</span>'}\n </div>\n <div class=\"coverage-cell\">\n <div class=\"coverage-percent ${stats.statements.percentage >= 80 ? 'high' : stats.statements.percentage >= 50 ? 'medium' : 'low'}\">${stats.statements.percentage.toFixed(2)}%</div>\n <div class=\"coverage-count\">${coverage.coveredStatements}/${coverage.statements}</div>\n </div>\n <div class=\"coverage-cell\">\n <div class=\"coverage-percent ${stats.branches.percentage >= 80 ? 'high' : stats.branches.percentage >= 50 ? 'medium' : 'low'}\">${stats.branches.percentage.toFixed(2)}%</div>\n <div class=\"coverage-count\">${coverage.coveredBranches}/${coverage.branches}</div>\n </div>\n <div class=\"coverage-cell\">\n <div class=\"coverage-percent ${stats.functions.percentage >= 80 ? 'high' : stats.functions.percentage >= 50 ? 'medium' : 'low'}\">${stats.functions.percentage.toFixed(2)}%</div>\n <div class=\"coverage-count\">${coverage.coveredFunctions}/${coverage.functions}</div>\n </div>\n <div class=\"coverage-cell\">\n <div class=\"coverage-percent ${stats.lines.percentage >= 80 ? 'high' : stats.lines.percentage >= 50 ? 'medium' : 'low'}\">${stats.lines.percentage.toFixed(2)}%</div>\n <div class=\"coverage-count\">${coverage.coveredLines}/${coverage.lines}</div>\n </div>\n </div>\n `;\n }).join('')}\n </div>\n <div id=\"no-results\" class=\"no-results hidden\">No files found matching your search</div>\n </div>\n </div>\n\n <script>\n const searchInput = document.getElementById('search-input');\n const fileRows = document.getElementById('file-rows');\n const noResults = document.getElementById('no-results');\n const fileRowElements = fileRows.querySelectorAll('.file-row');\n\n searchInput.addEventListener('input', function() {\n const searchTerm = this.value.toLowerCase().trim();\n let visibleCount = 0;\n\n fileRowElements.forEach(function(row) {\n const fileName = row.querySelector('.file-name').textContent.toLowerCase();\n if (fileName.includes(searchTerm)) {\n row.classList.remove('hidden');\n visibleCount++;\n } else {\n row.classList.add('hidden');\n }\n });\n\n if (visibleCount === 0) {\n noResults.classList.remove('hidden');\n } else {\n noResults.classList.add('hidden');\n }\n });\n </script>\n</body>\n</html>`;\n\n writeFileSync(join(reportsDir, 'index.html'), indexHtml, 'utf-8');\n\n // Generate individual file detail pages\n for (const [filePath, coverage] of coverageMap.entries()) {\n generateFileDetailPage(filePath, coverage, reportsDir, toRelative);\n }\n}\n\n/**\n * Generate an individual file detail page with line-by-line coverage\n */\nfunction generateFileDetailPage(\n filePath: string,\n coverage: FileCoverage,\n reportsDir: string,\n toRelative: (path: string) => string\n): void {\n const fileName = toRelative(filePath);\n const safeFileName = fileName.replace(/[\\/\\\\]/g, '_') + '.html';\n const stats = calculateFileCoverage(coverage);\n\n // Read source file\n let sourceLines: string[] = [];\n try {\n const sourceCode = readFileSync(filePath, 'utf-8').toString();\n sourceLines = sourceCode.split('\\n');\n } catch (e) {\n sourceLines = ['// Unable to read source file'];\n }\n\n // Build uncovered lines set for quick lookup\n const uncoveredSet = new Set(coverage.uncoveredLines || []);\n\n const fileHtml = `<!DOCTYPE html>\n<html>\n<head>\n <meta charset=\"utf-8\">\n <title>Coverage: ${fileName}</title>\n <link rel=\"icon\" type=\"image/svg+xml\" href=\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Cdefs%3E%3ClinearGradient id='grad' x1='0%25' y1='0%25' x2='100%25' y2='100%25'%3E%3Cstop offset='0%25' stop-color='%236366f1'/%3E%3Cstop offset='100%25' stop-color='%238b5cf6'/%3E%3C/linearGradient%3E%3C/defs%3E%3Crect width='100' height='100' rx='20' fill='url(%23grad)'/%3E%3Crect x='28' y='25' width='44' height='8' rx='4' fill='white'/%3E%3Crect x='28' y='46' width='32' height='8' rx='4' fill='white'/%3E%3Crect x='28' y='67' width='44' height='8' rx='4' fill='white'/%3E%3Crect x='28' y='25' width='8' height='50' rx='4' fill='white'/%3E%3Ccircle cx='72' cy='50' r='6' fill='white' opacity='0.5'/%3E%3C/svg%3E\">\n <style>\n * { margin: 0; padding: 0; box-sizing: border-box; }\n body {\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;\n background: #0d1117;\n color: #c9d1d9;\n padding: 20px;\n }\n .container { max-width: 1400px; margin: 0 auto; }\n a { color: #58a6ff; text-decoration: none; }\n a:hover { text-decoration: underline; }\n h1 {\n font-size: 24px;\n font-weight: 600;\n margin-bottom: 10px;\n color: #58a6ff;\n }\n .breadcrumb {\n font-size: 14px;\n color: #8b949e;\n margin-bottom: 20px;\n }\n .breadcrumb a { color: #58a6ff; }\n .summary {\n background: #161b22;\n border: 1px solid #30363d;\n border-radius: 6px;\n padding: 20px;\n margin-bottom: 20px;\n }\n .summary-title {\n font-size: 16px;\n font-weight: 600;\n margin-bottom: 15px;\n color: #c9d1d9;\n }\n .metrics { display: grid; grid-template-columns: repeat(4, 1fr); gap: 15px; }\n .metric {\n background: #21262d;\n border: 1px solid #30363d;\n border-radius: 6px;\n padding: 15px;\n text-align: center;\n }\n .metric-label { font-size: 12px; color: #8b949e; margin-bottom: 5px; text-transform: uppercase; letter-spacing: 0.5px; }\n .metric-value { font-size: 24px; font-weight: 700; }\n .metric-value.high { color: #3fb950; }\n .metric-value.medium { color: #d29922; }\n .metric-value.low { color: #f85149; }\n .progress-bar {\n height: 8px;\n background: #21262d;\n border-radius: 4px;\n overflow: hidden;\n margin-top: 8px;\n }\n .progress-fill { height: 100%; transition: width 0.3s ease; }\n .progress-fill.high { background: #3fb950; }\n .progress-fill.medium { background: #d29922; }\n .progress-fill.low { background: #f85149; }\n .metric-count { font-size: 11px; color: #8b949e; margin-top: 5px; }\n .code-container {\n background: #161b22;\n border: 1px solid #30363d;\n border-radius: 6px;\n overflow: hidden;\n }\n .code-header {\n padding: 10px 15px;\n background: #21262d;\n border-bottom: 1px solid #30363d;\n font-size: 13px;\n color: #8b949e;\n display: flex;\n justify-content: space-between;\n }\n .legend { display: flex; gap: 15px; font-size: 12px; }\n .legend-item { display: flex; align-items: center; gap: 5px; }\n .legend-box { width: 12px; height: 12px; border-radius: 2px; }\n .legend-box.covered { background: rgba(63, 185, 80, 0.2); border: 1px solid #3fb950; }\n .legend-box.uncovered { background: rgba(248, 81, 73, 0.2); border: 1px solid #f85149; }\n .code-table { width: 100%; border-collapse: collapse; }\n .code-table td { padding: 0; }\n .line-number {\n width: 50px;\n text-align: right;\n padding: 0 15px;\n color: #8b949e;\n font-size: 12px;\n user-select: none;\n border-right: 1px solid #30363d;\n }\n .line-content {\n padding: 0 15px;\n font-family: 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, monospace;\n font-size: 13px;\n line-height: 20px;\n white-space: pre;\n }\n tr.covered .line-content { background: rgba(63, 185, 80, 0.1); }\n tr.uncovered .line-content { background: rgba(248, 81, 73, 0.15); }\n tr.uncovered .line-number { color: #f85149; }\n tr:hover td { background: rgba(88, 166, 255, 0.1); }\n </style>\n</head>\n<body>\n <div class=\"container\">\n <div class=\"breadcrumb\">\n <a href=\"index.html\">← Back to Coverage Report</a>\n </div>\n\n <h1>${fileName}</h1>\n\n <div class=\"summary\">\n <div class=\"summary-title\">Coverage Metrics</div>\n <div class=\"metrics\">\n <div class=\"metric\">\n <div class=\"metric-label\">Statements</div>\n <div class=\"metric-value ${stats.statements.percentage >= 80 ? 'high' : stats.statements.percentage >= 50 ? 'medium' : 'low'}\">${stats.statements.percentage.toFixed(2)}%</div>\n <div class=\"progress-bar\">\n <div class=\"progress-fill ${stats.statements.percentage >= 80 ? 'high' : stats.statements.percentage >= 50 ? 'medium' : 'low'}\" style=\"width: ${stats.statements.percentage}%\"></div>\n </div>\n <div class=\"metric-count\">${coverage.coveredStatements}/${coverage.statements}</div>\n </div>\n <div class=\"metric\">\n <div class=\"metric-label\">Branches</div>\n <div class=\"metric-value ${stats.branches.percentage >= 80 ? 'high' : stats.branches.percentage >= 50 ? 'medium' : 'low'}\">${stats.branches.percentage.toFixed(2)}%</div>\n <div class=\"progress-bar\">\n <div class=\"progress-fill ${stats.branches.percentage >= 80 ? 'high' : stats.branches.percentage >= 50 ? 'medium' : 'low'}\" style=\"width: ${stats.branches.percentage}%\"></div>\n </div>\n <div class=\"metric-count\">${coverage.coveredBranches}/${coverage.branches}</div>\n </div>\n <div class=\"metric\">\n <div class=\"metric-label\">Functions</div>\n <div class=\"metric-value ${stats.functions.percentage >= 80 ? 'high' : stats.functions.percentage >= 50 ? 'medium' : 'low'}\">${stats.functions.percentage.toFixed(2)}%</div>\n <div class=\"progress-bar\">\n <div class=\"progress-fill ${stats.functions.percentage >= 80 ? 'high' : stats.functions.percentage >= 50 ? 'medium' : 'low'}\" style=\"width: ${stats.functions.percentage}%\"></div>\n </div>\n <div class=\"metric-count\">${coverage.coveredFunctions}/${coverage.functions}</div>\n </div>\n <div class=\"metric\">\n <div class=\"metric-label\">Lines</div>\n <div class=\"metric-value ${stats.lines.percentage >= 80 ? 'high' : stats.lines.percentage >= 50 ? 'medium' : 'low'}\">${stats.lines.percentage.toFixed(2)}%</div>\n <div class=\"progress-bar\">\n <div class=\"progress-fill ${stats.lines.percentage >= 80 ? 'high' : stats.lines.percentage >= 50 ? 'medium' : 'low'}\" style=\"width: ${stats.lines.percentage}%\"></div>\n </div>\n <div class=\"metric-count\">${coverage.coveredLines}/${coverage.lines}</div>\n </div>\n </div>\n </div>\n\n ${coverage.uncoveredLines && coverage.uncoveredLines.length > 0 ? `\n <div class=\"summary\">\n <div class=\"summary-title\">Uncovered Lines</div>\n <div style=\"font-size: 13px; color: #f85149;\">${formatUncoveredLines(coverage.uncoveredLines)}</div>\n </div>\n ` : ''}\n\n <div class=\"code-container\">\n <div class=\"code-header\">\n <span>Source Code</span>\n <div class=\"legend\">\n <div class=\"legend-item\"><div class=\"legend-box covered\"></div><span>Covered</span></div>\n <div class=\"legend-item\"><div class=\"legend-box uncovered\"></div><span>Uncovered</span></div>\n </div>\n </div>\n <table class=\"code-table\">\n ${sourceLines.map((line, index) => {\n const lineNum = index + 1;\n const isUncovered = uncoveredSet.has(lineNum);\n const isExecutable = coverage.lines > 0; // Has executable lines\n const rowClass = isExecutable ? (isUncovered ? 'uncovered' : 'covered') : '';\n return `\n <tr class=\"${rowClass}\">\n <td class=\"line-number\">${lineNum}</td>\n <td class=\"line-content\">${escapeHtml(line) || ' '}</td>\n </tr>\n `;\n }).join('')}\n </table>\n </div>\n </div>\n</body>\n</html>`;\n\n writeFileSync(join(reportsDir, safeFileName), fileHtml, 'utf-8');\n}\n\n/**\n * Escape HTML special characters\n */\nfunction escapeHtml(text: string): string {\n return text\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\"/g, '&quot;')\n .replace(/'/g, '&#039;');\n}\n\n/**\n * Escape XML special characters\n */\nfunction escapeXml(text: string): string {\n return text\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\"/g, '&quot;')\n .replace(/'/g, '&apos;');\n}\n\n/**\n * Generate coverage-final.json (Code Climate/Codecov format)\n */\nexport function generateCoverageFinalJson(\n coverageMap: Map<string, FileCoverage>,\n reportsDir: string\n): void {\n const coverageData: Record<string, any> = {};\n\n for (const [filePath, coverage] of coverageMap.entries()) {\n const relativePath = relative(process.cwd(), filePath).replace(/\\\\/g, '/');\n\n // Build line coverage map\n const lineMap: Record<number, number> = {};\n const executableLines = getExecutableLines(filePath);\n\n for (const line of executableLines) {\n // If file is covered, mark all lines as covered (1), otherwise not covered (0)\n const isCovered = coverage.coveredStatements > 0;\n lineMap[line] = isCovered ? 1 : 0;\n }\n\n coverageData[relativePath] = {\n lines: lineMap,\n };\n }\n\n const jsonData = JSON.stringify(coverageData, null, 2);\n writeFileSync(join(reportsDir, 'coverage-final.json'), jsonData, 'utf-8');\n}\n\n/**\n * Generate clover.xml report\n */\nexport function generateCloverXml(\n coverageMap: Map<string, FileCoverage>,\n reportsDir: string\n): void {\n const timestamp = Date.now();\n\n // Calculate totals\n let totalFiles = 0;\n let totalClasses = 0;\n let totalElements = 0; // statements + branches + functions\n let coveredElements = 0;\n let totalStatements = 0;\n let coveredStatements = 0;\n let totalBranches = 0;\n let coveredBranches = 0;\n let totalFunctions = 0;\n let coveredFunctions = 0;\n let totalLines = 0;\n let coveredLines = 0;\n\n const fileEntries: string[] = [];\n\n for (const [filePath, coverage] of coverageMap.entries()) {\n const relativePath = relative(process.cwd(), filePath).replace(/\\\\/g, '/');\n\n totalFiles++;\n totalClasses++; // Assume one class per file\n totalStatements += coverage.statements;\n coveredStatements += coverage.coveredStatements;\n totalBranches += coverage.branches;\n coveredBranches += coverage.coveredBranches;\n totalFunctions += coverage.functions;\n coveredFunctions += coverage.coveredFunctions;\n totalLines += coverage.lines;\n coveredLines += coverage.coveredLines;\n\n const fileElements = coverage.statements + coverage.branches + coverage.functions;\n const fileCoveredElements = coverage.coveredStatements + coverage.coveredBranches + coverage.coveredFunctions;\n\n totalElements += fileElements;\n coveredElements += fileCoveredElements;\n\n const escapedPath = escapeXml(relativePath);\n\n fileEntries.push(`\n <file name=\"${escapedPath}\">\n <class name=\"${escapedPath}\">\n <metrics complexity=\"0\" elements=\"${fileElements}\" coveredelements=\"${fileCoveredElements}\"\n methods=\"${coverage.functions}\" coveredmethods=\"${coverage.coveredFunctions}\"\n statements=\"${coverage.statements}\" coveredstatements=\"${coverage.coveredStatements}\" />\n </class>\n <line num=\"1\" type=\"stmt\" count=\"${coverage.coveredStatements > 0 ? 1 : 0}\" />\n </file>`);\n }\n\n const complexity = 0; // We don't track cyclomatic complexity\n const elements = totalElements;\n\n const xml = `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<coverage generated=\"${timestamp}\" clover=\"3.2.0\">\n <project timestamp=\"${timestamp}\" name=\"Coverage\">\n <metrics complexity=\"${complexity}\" elements=\"${elements}\" coveredelements=\"${coveredElements}\"\n conditionals=\"${totalBranches}\" coveredconditionals=\"${coveredBranches}\"\n statements=\"${totalStatements}\" coveredstatements=\"${coveredStatements}\"\n methods=\"${totalFunctions}\" coveredmethods=\"${coveredFunctions}\"\n classes=\"${totalClasses}\" coveredclasses=\"${coverageMap.size > 0 ? Array.from(coverageMap.values()).filter(c => c.coveredStatements > 0).length : 0}\"\n files=\"${totalFiles}\" loc=\"${totalLines}\" ncloc=\"${totalLines - coveredLines}\"\n packages=\"${totalFiles}\" classes=\"${totalClasses}\" />\n <package name=\"root\">\n <metrics complexity=\"${complexity}\" elements=\"${elements}\" coveredelements=\"${coveredElements}\"\n conditionals=\"${totalBranches}\" coveredconditionals=\"${coveredBranches}\"\n statements=\"${totalStatements}\" coveredstatements=\"${coveredStatements}\"\n methods=\"${totalFunctions}\" coveredmethods=\"${coveredFunctions}\"\n classes=\"${totalClasses}\" coveredclasses=\"${coverageMap.size > 0 ? Array.from(coverageMap.values()).filter(c => c.coveredStatements > 0).length : 0}\"\n files=\"${totalFiles}\" loc=\"${totalLines}\" ncloc=\"${totalLines - coveredLines}\" />\n${fileEntries.join('')}\n </package>\n </project>\n</coverage>`;\n\n writeFileSync(join(reportsDir, 'clover.xml'), xml, 'utf-8');\n}\n","/**\n * Runtime detection and global type declarations\n * Shared across all modules for consistency\n */\n\n/**\n * Runtime detection (cached at module load)\n */\nexport const runtime = (() => {\n // @ts-ignore - Deno global\n if (typeof Deno !== 'undefined') return 'deno';\n // @ts-ignore - Bun global\n if (typeof Bun !== 'undefined') return 'bun';\n return 'node';\n})() as 'node' | 'bun' | 'deno';\n\nexport const isNode = runtime === 'node';\nexport const isBun = runtime === 'bun';\nexport const isDeno = runtime === 'deno';\n\n// Global declarations for runtime-specific APIs\ndeclare global {\n // @ts-ignore - Bun global\n const Bun: {\n build(options: {\n entrypoints: string[];\n outdir?: string;\n target?: string;\n format?: string;\n minify?: boolean;\n sourcemap?: string;\n external?: string[];\n naming?: string;\n plugins?: any[];\n define?: Record<string, string>;\n }): Promise<{\n success: boolean;\n outputs: Array<{ path: string; size: number }>;\n logs: any[];\n }>;\n Transpiler: new (options?: {\n loader?: string;\n target?: string;\n minify?: boolean;\n }) => {\n transform(code: string, loader?: string): Promise<string>;\n transformSync(code: string, loader?: string): string;\n };\n file(path: string): {\n size: number;\n arrayBuffer(): ArrayBuffer | Promise<ArrayBuffer>;\n exists(): Promise<boolean>;\n };\n write(path: string, data: string | Buffer | Uint8Array): Promise<void>;\n } | undefined;\n\n // @ts-ignore - Deno global\n const Deno: {\n emit(rootSpecifier: string | URL, options?: {\n bundle?: 'module' | 'classic';\n check?: boolean;\n compilerOptions?: any;\n importMap?: string;\n importMapPath?: string;\n sources?: Record<string, string>;\n }): Promise<{\n files: Record<string, string>;\n diagnostics: any[];\n }>;\n writeTextFile(path: string, data: string): Promise<void>;\n readFile(path: string): Promise<Uint8Array>;\n readFileSync(path: string): Uint8Array;\n writeFile(path: string, data: Uint8Array): Promise<void>;\n writeFileSync(path: string, data: Uint8Array): void;\n stat(path: string): Promise<any>;\n statSync(path: string): any;\n mkdir(path: string, options?: { recursive?: boolean }): Promise<void>;\n mkdirSync(path: string, options?: { recursive?: boolean }): void;\n readDir(path: string): AsyncIterable<any>;\n readDirSync(path: string): Iterable<any>;\n remove(path: string, options?: { recursive?: boolean }): Promise<void>;\n removeSync(path: string, options?: { recursive?: boolean }): void;\n rename(oldPath: string, newPath: string): Promise<void>;\n renameSync(oldPath: string, newPath: string): void;\n copyFile(src: string, dest: string): Promise<void>;\n copyFileSync(src: string, dest: string): void;\n realPath(path: string): Promise<string>;\n realPathSync(path: string): string;\n watchFs(paths: string | string[]): AsyncIterable<{\n kind: string;\n paths: string[];\n }>;\n build: {\n os: string;\n };\n } | undefined;\n}\n","/**\n * File System module with unified API across runtimes\n * Compatible with Node.js 'fs' module API\n * - Node.js: uses 'fs' module\n * - Bun: uses Bun.file() and native APIs\n * - Deno: uses Deno.readFile(), etc.\n */\n\nimport { runtime, isNode, isBun, isDeno } from './runtime';\n\n/**\n * Helper: Check if runtime is Bun or Deno (eliminates duplication in Deno API calls)\n */\nconst isBunOrDeno = isBun || isDeno;\n\n/**\n * Helper: Parse options from string or object (eliminates duplication in options parsing)\n */\nfunction parseOptions<T>(options: T | string | undefined, defaultValue: T): T {\n return typeof options === 'string' ? { encoding: options } as T : options || defaultValue;\n}\n\n/**\n * Helper: Decode content with optional encoding (eliminates duplication in read operations)\n */\nfunction decodeContent(content: ArrayBuffer | Uint8Array, encoding?: string | null): string | Buffer {\n if (encoding) {\n return new TextDecoder(encoding).decode(content);\n }\n return Buffer.from(content instanceof ArrayBuffer ? new Uint8Array(content) : content);\n}\n\n/**\n * Helper: Convert data to Uint8Array (eliminates duplication in write operations)\n */\nfunction dataToUint8Array(data: string | Buffer | Uint8Array): Uint8Array {\n if (typeof data === 'string') {\n return new TextEncoder().encode(data);\n }\n if (data instanceof Buffer) {\n return new Uint8Array(data);\n }\n return data;\n}\n\n/**\n * Helper: Process directory entries (eliminates duplication in readdir operations)\n */\nfunction processDenoEntries(iterator: any, withFileTypes?: boolean): any[] {\n const entries: any[] = [];\n for (const entry of iterator) {\n if (withFileTypes) {\n entries.push(createDirentFromDenoEntry(entry));\n } else {\n entries.push(entry.name);\n }\n }\n return entries;\n}\n\n/**\n * Helper: Process directory entries async (eliminates duplication in async readdir)\n */\nasync function processDenoEntriesAsync(iterator: any, withFileTypes?: boolean): Promise<any[]> {\n const entries: any[] = [];\n for await (const entry of iterator) {\n if (withFileTypes) {\n entries.push(createDirentFromDenoEntry(entry));\n } else {\n entries.push(entry.name);\n }\n }\n return entries;\n}\n\n// Pre-load fs module for Node.js\nlet fs: any, fsPromises: any;\nif (isNode) {\n fs = require('fs');\n fsPromises = require('fs/promises');\n}\n\n/**\n * File encoding types\n */\nexport type BufferEncoding =\n | 'ascii' | 'utf8' | 'utf-8' | 'utf16le' | 'ucs2' | 'ucs-2'\n | 'base64' | 'base64url' | 'latin1' | 'binary' | 'hex';\n\n/**\n * Read file options\n */\nexport interface ReadFileOptions {\n encoding?: BufferEncoding | null;\n flag?: string;\n signal?: AbortSignal;\n}\n\n/**\n * Write file options\n */\nexport interface WriteFileOptions {\n encoding?: BufferEncoding | null;\n mode?: number;\n flag?: string;\n signal?: AbortSignal;\n}\n\n/**\n * Mkdir options\n */\nexport interface MkdirOptions {\n recursive?: boolean;\n mode?: number;\n}\n\n/**\n * Readdir options\n */\nexport interface ReaddirOptions {\n encoding?: BufferEncoding | null;\n withFileTypes?: boolean;\n recursive?: boolean;\n}\n\n/**\n * File stats\n */\nexport interface Stats {\n isFile(): boolean;\n isDirectory(): boolean;\n isBlockDevice(): boolean;\n isCharacterDevice(): boolean;\n isSymbolicLink(): boolean;\n isFIFO(): boolean;\n isSocket(): boolean;\n dev: number;\n ino: number;\n mode: number;\n nlink: number;\n uid: number;\n gid: number;\n rdev: number;\n size: number;\n blksize: number;\n blocks: number;\n atimeMs: number;\n mtimeMs: number;\n ctimeMs: number;\n birthtimeMs: number;\n atime: Date;\n mtime: Date;\n ctime: Date;\n birthtime: Date;\n}\n\n/**\n * Directory entry\n */\nexport interface Dirent {\n name: string;\n isFile(): boolean;\n isDirectory(): boolean;\n isBlockDevice(): boolean;\n isCharacterDevice(): boolean;\n isSymbolicLink(): boolean;\n isFIFO(): boolean;\n isSocket(): boolean;\n}\n\n/**\n * Read file (async)\n */\nexport async function readFile(path: string, options?: ReadFileOptions | BufferEncoding): Promise<string | Buffer> {\n const opts = parseOptions<ReadFileOptions>(options, {});\n\n if (isNode) {\n return fsPromises.readFile(path, opts);\n } else if (isBun) {\n // @ts-ignore\n const file = Bun.file(path);\n const content = await file.arrayBuffer();\n return decodeContent(content, opts.encoding);\n } else if (isDeno) {\n // @ts-ignore\n const content = await Deno.readFile(path);\n return decodeContent(content, opts.encoding);\n }\n\n throw new Error('Unsupported runtime');\n}\n\n/**\n * Read file (sync)\n */\nexport function readFileSync(path: string, options?: ReadFileOptions | BufferEncoding): string | Buffer {\n const opts = parseOptions<ReadFileOptions>(options, {});\n\n if (isNode) {\n return fs.readFileSync(path, opts);\n } else if (isBun) {\n // @ts-ignore\n const file = Bun.file(path);\n const content = file.arrayBuffer();\n return decodeContent(content as ArrayBuffer, opts.encoding);\n } else if (isDeno) {\n // @ts-ignore\n const content = Deno.readFileSync(path);\n return decodeContent(content, opts.encoding);\n }\n\n throw new Error('Unsupported runtime');\n}\n\n/**\n * Write file (async)\n */\nexport async function writeFile(path: string, data: string | Buffer | Uint8Array, options?: WriteFileOptions | BufferEncoding): Promise<void> {\n const opts = parseOptions<WriteFileOptions>(options, {});\n\n if (isNode) {\n return fsPromises.writeFile(path, data, opts);\n } else if (isBun) {\n // @ts-ignore\n await Bun.write(path, data);\n } else if (isDeno) {\n // @ts-ignore\n await Deno.writeFile(path, dataToUint8Array(data));\n }\n}\n\n/**\n * Write file (sync)\n */\nexport function writeFileSync(path: string, data: string | Buffer | Uint8Array, options?: WriteFileOptions | BufferEncoding): void {\n const opts = parseOptions<WriteFileOptions>(options, {});\n\n if (isNode) {\n fs.writeFileSync(path, data, opts);\n } else if (isBun) {\n // @ts-ignore\n Bun.write(path, data);\n } else if (isDeno) {\n // @ts-ignore\n Deno.writeFileSync(path, dataToUint8Array(data));\n }\n}\n\n/**\n * Append file (async)\n */\nexport async function appendFile(path: string, data: string | Buffer, options?: WriteFileOptions | BufferEncoding): Promise<void> {\n const opts = parseOptions<WriteFileOptions>(options, {});\n\n if (isNode) {\n return fsPromises.appendFile(path, data, opts);\n } else {\n if (await exists(path)) {\n const existing = await readFile(path);\n const combined = Buffer.isBuffer(existing)\n ? Buffer.concat([existing, Buffer.isBuffer(data) ? data : Buffer.from(data)])\n : existing + (Buffer.isBuffer(data) ? data.toString() : data);\n await writeFile(path, combined, opts);\n } else {\n await writeFile(path, data, opts);\n }\n }\n}\n\n/**\n * Append file (sync)\n */\nexport function appendFileSync(path: string, data: string | Buffer, options?: WriteFileOptions | BufferEncoding): void {\n const opts = parseOptions<WriteFileOptions>(options, {});\n\n if (isNode) {\n fs.appendFileSync(path, data, opts);\n } else {\n if (existsSync(path)) {\n const existing = readFileSync(path);\n const combined = Buffer.isBuffer(existing)\n ? Buffer.concat([existing, Buffer.isBuffer(data) ? data : Buffer.from(data)])\n : existing + (Buffer.isBuffer(data) ? data.toString() : data);\n writeFileSync(path, combined, opts);\n } else {\n writeFileSync(path, data, opts);\n }\n }\n}\n\n/**\n * Check if file/directory exists (async)\n */\nexport async function exists(path: string): Promise<boolean> {\n try {\n await stat(path);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Check if file/directory exists (sync)\n */\nexport function existsSync(path: string): boolean {\n try {\n statSync(path);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Get file stats (async)\n */\nexport async function stat(path: string): Promise<Stats> {\n if (isNode) {\n return fsPromises.stat(path);\n } else if (isBun) {\n // @ts-ignore\n const file = Bun.file(path);\n const size = file.size;\n const exists = await file.exists();\n\n if (!exists) {\n throw new Error(`ENOENT: no such file or directory, stat '${path}'`);\n }\n\n // Create a Stats-like object\n return createStatsObject(path, size, false);\n } else if (isDeno) {\n // @ts-ignore\n const info = await Deno.stat(path);\n return createStatsFromDenoFileInfo(info);\n }\n\n throw new Error('Unsupported runtime');\n}\n\n/**\n * Get file stats (sync)\n */\nexport function statSync(path: string): Stats {\n if (isNode) {\n return fs.statSync(path);\n } else if (isBun) {\n // @ts-ignore\n const file = Bun.file(path);\n const size = file.size;\n\n // Bun doesn't have sync exists check, so we try to read\n try {\n file.arrayBuffer();\n } catch {\n throw new Error(`ENOENT: no such file or directory, stat '${path}'`);\n }\n\n return createStatsObject(path, size, false);\n } else if (isDeno) {\n // @ts-ignore\n const info = Deno.statSync(path);\n return createStatsFromDenoFileInfo(info);\n }\n\n throw new Error('Unsupported runtime');\n}\n\n/**\n * Create directory (async)\n */\nexport async function mkdir(path: string, options?: MkdirOptions | number): Promise<void> {\n const opts = typeof options === 'number' ? { mode: options } as MkdirOptions : options || {};\n\n if (isNode) {\n await fsPromises.mkdir(path, opts);\n } else if (isBun) {\n // @ts-ignore\n await Deno.mkdir(path, { recursive: opts.recursive });\n } else if (isDeno) {\n // @ts-ignore\n await Deno.mkdir(path, { recursive: opts.recursive });\n }\n}\n\n/**\n * Create directory (sync)\n */\nexport function mkdirSync(path: string, options?: MkdirOptions | number): void {\n const opts = typeof options === 'number' ? { mode: options } as MkdirOptions : options || {};\n\n if (isNode) {\n fs.mkdirSync(path, opts);\n } else if (isBun) {\n // @ts-ignore\n Deno.mkdirSync(path, { recursive: opts.recursive });\n } else if (isDeno) {\n // @ts-ignore\n Deno.mkdirSync(path, { recursive: opts.recursive });\n }\n}\n\n/**\n * Read directory (async)\n */\nexport async function readdir(path: string, options?: ReaddirOptions | BufferEncoding): Promise<string[] | Dirent[]> {\n const opts = parseOptions<ReaddirOptions>(options, {});\n\n if (isNode) {\n return fsPromises.readdir(path, opts);\n } else if (isBunOrDeno) {\n // @ts-ignore\n return processDenoEntriesAsync(Deno.readDir(path), opts.withFileTypes);\n }\n\n throw new Error('Unsupported runtime');\n}\n\n/**\n * Read directory (sync)\n */\nexport function readdirSync(path: string, options?: ReaddirOptions | BufferEncoding): string[] | Dirent[] {\n const opts = parseOptions<ReaddirOptions>(options, {});\n\n if (isNode) {\n return fs.readdirSync(path, opts);\n } else if (isBunOrDeno) {\n // @ts-ignore\n return processDenoEntries(Deno.readDirSync(path), opts.withFileTypes);\n }\n\n throw new Error('Unsupported runtime');\n}\n\n/**\n * Remove file (async)\n */\nexport async function unlink(path: string): Promise<void> {\n if (isNode) {\n return fsPromises.unlink(path);\n } else if (isBun) {\n // @ts-ignore\n await Deno.remove(path);\n } else if (isDeno) {\n // @ts-ignore\n await Deno.remove(path);\n }\n}\n\n/**\n * Remove file (sync)\n */\nexport function unlinkSync(path: string): void {\n if (isNode) {\n fs.unlinkSync(path);\n } else if (isBun) {\n // @ts-ignore\n Deno.removeSync(path);\n } else if (isDeno) {\n // @ts-ignore\n Deno.removeSync(path);\n }\n}\n\n/**\n * Remove directory (async)\n */\nexport async function rmdir(path: string, options?: { recursive?: boolean }): Promise<void> {\n if (isNode) {\n return fsPromises.rmdir(path, options);\n } else if (isBun) {\n // @ts-ignore\n await Deno.remove(path, { recursive: options?.recursive });\n } else if (isDeno) {\n // @ts-ignore\n await Deno.remove(path, { recursive: options?.recursive });\n }\n}\n\n/**\n * Remove directory (sync)\n */\nexport function rmdirSync(path: string, options?: { recursive?: boolean }): void {\n if (isNode) {\n fs.rmdirSync(path, options);\n } else if (isBun) {\n // @ts-ignore\n Deno.removeSync(path, { recursive: options?.recursive });\n } else if (isDeno) {\n // @ts-ignore\n Deno.removeSync(path, { recursive: options?.recursive });\n }\n}\n\n/**\n * Rename/move file (async)\n */\nexport async function rename(oldPath: string, newPath: string): Promise<void> {\n if (isNode) {\n return fsPromises.rename(oldPath, newPath);\n } else if (isBun) {\n // @ts-ignore\n await Deno.rename(oldPath, newPath);\n } else if (isDeno) {\n // @ts-ignore\n await Deno.rename(oldPath, newPath);\n }\n}\n\n/**\n * Rename/move file (sync)\n */\nexport function renameSync(oldPath: string, newPath: string): void {\n if (isNode) {\n fs.renameSync(oldPath, newPath);\n } else if (isBun) {\n // @ts-ignore\n Deno.renameSync(oldPath, newPath);\n } else if (isDeno) {\n // @ts-ignore\n Deno.renameSync(oldPath, newPath);\n }\n}\n\n/**\n * Copy file (async)\n */\nexport async function copyFile(src: string, dest: string, flags?: number): Promise<void> {\n if (isNode) {\n return fsPromises.copyFile(src, dest, flags);\n } else if (isBun) {\n // @ts-ignore\n await Deno.copyFile(src, dest);\n } else if (isDeno) {\n // @ts-ignore\n await Deno.copyFile(src, dest);\n }\n}\n\n/**\n * Copy file (sync)\n */\nexport function copyFileSync(src: string, dest: string, flags?: number): void {\n if (isNode) {\n fs.copyFileSync(src, dest, flags);\n } else if (isBun) {\n // @ts-ignore\n Deno.copyFileSync(src, dest);\n } else if (isDeno) {\n // @ts-ignore\n Deno.copyFileSync(src, dest);\n }\n}\n\n/**\n * Resolve pathname to absolute path (async)\n */\nexport async function realpath(path: string, options?: { encoding?: BufferEncoding }): Promise<string> {\n if (isNode) {\n return fsPromises.realpath(path, options);\n } else if (isBun) {\n // Bun supports fs.promises.realpath\n const fs = require('fs/promises');\n return fs.realpath(path, options);\n } else if (isDeno) {\n // @ts-ignore\n return await Deno.realPath(path);\n }\n return path;\n}\n\n/**\n * Resolve pathname to absolute path (sync)\n */\nexport function realpathSync(path: string, options?: { encoding?: BufferEncoding }): string {\n if (isNode) {\n return fs.realpathSync(path, options);\n } else if (isBun) {\n // Bun supports fs.realpathSync\n const fs = require('fs');\n return fs.realpathSync(path, options);\n } else if (isDeno) {\n // @ts-ignore\n return Deno.realPathSync(path);\n }\n return path;\n}\n\n/**\n * Helper: Create Stats object\n */\nfunction createStatsObject(_path: string, size: number, isDir: boolean): Stats {\n const now = Date.now();\n return {\n isFile: () => !isDir,\n isDirectory: () => isDir,\n isBlockDevice: () => false,\n isCharacterDevice: () => false,\n isSymbolicLink: () => false,\n isFIFO: () => false,\n isSocket: () => false,\n dev: 0,\n ino: 0,\n mode: isDir ? 16877 : 33188,\n nlink: 1,\n uid: 0,\n gid: 0,\n rdev: 0,\n size,\n blksize: 4096,\n blocks: Math.ceil(size / 512),\n atimeMs: now,\n mtimeMs: now,\n ctimeMs: now,\n birthtimeMs: now,\n atime: new Date(now),\n mtime: new Date(now),\n ctime: new Date(now),\n birthtime: new Date(now),\n };\n}\n\n/**\n * Helper: Create Stats from Deno FileInfo\n */\nfunction createStatsFromDenoFileInfo(info: any): Stats {\n return {\n isFile: () => info.isFile,\n isDirectory: () => info.isDirectory,\n isBlockDevice: () => false,\n isCharacterDevice: () => false,\n isSymbolicLink: () => info.isSymlink || false,\n isFIFO: () => false,\n isSocket: () => false,\n dev: info.dev || 0,\n ino: info.ino || 0,\n mode: info.mode || 0,\n nlink: info.nlink || 1,\n uid: info.uid || 0,\n gid: info.gid || 0,\n rdev: 0,\n size: info.size,\n blksize: info.blksize || 4096,\n blocks: info.blocks || Math.ceil(info.size / 512),\n atimeMs: info.atime?.getTime() || Date.now(),\n mtimeMs: info.mtime?.getTime() || Date.now(),\n ctimeMs: info.birthtime?.getTime() || Date.now(),\n birthtimeMs: info.birthtime?.getTime() || Date.now(),\n atime: info.atime || new Date(),\n mtime: info.mtime || new Date(),\n ctime: info.birthtime || new Date(),\n birthtime: info.birthtime || new Date(),\n };\n}\n\n/**\n * Helper: Create Dirent from Deno DirEntry\n */\nfunction createDirentFromDenoEntry(entry: any): Dirent {\n return {\n name: entry.name,\n isFile: () => entry.isFile,\n isDirectory: () => entry.isDirectory,\n isBlockDevice: () => false,\n isCharacterDevice: () => false,\n isSymbolicLink: () => entry.isSymlink || false,\n isFIFO: () => false,\n isSocket: () => false,\n };\n}\n\n/**\n * Get current runtime\n */\nexport function getRuntime(): 'node' | 'bun' | 'deno' {\n return runtime;\n}\n\n/**\n * Promises API (re-export for compatibility)\n */\nexport const promises = {\n readFile,\n writeFile,\n appendFile,\n stat,\n mkdir,\n readdir,\n unlink,\n rmdir,\n rename,\n copyFile,\n realpath,\n};\n\n/**\n * Default export\n */\nexport default {\n readFile,\n readFileSync,\n writeFile,\n writeFileSync,\n appendFile,\n appendFileSync,\n exists,\n existsSync,\n stat,\n statSync,\n mkdir,\n mkdirSync,\n readdir,\n readdirSync,\n unlink,\n unlinkSync,\n rmdir,\n rmdirSync,\n rename,\n renameSync,\n copyFile,\n copyFileSync,\n realpath,\n realpathSync,\n promises,\n getRuntime,\n};\n","/**\n * Path module with unified API across runtimes\n * Pure implementation without external dependencies\n * Compatible with Node.js 'path' module API\n * Works on Node.js, Bun, and Deno\n */\n\nimport { isBun, isDeno, isNode, runtime } from './runtime';\n\n/**\n * Helper: Get path separator for platform (eliminates duplication in separator logic)\n */\nfunction getSeparator(isWin: boolean): string {\n return isWin ? '\\\\' : '/';\n}\n\n/**\n * Helper: Get current working directory (eliminates duplication in resolvePaths)\n */\nfunction getCwd(): string {\n if (isNode || isBun) {\n return process.cwd();\n } else if (isDeno) {\n // @ts-ignore\n return Deno.cwd();\n }\n return '/';\n}\n\n/**\n * Helper: Find last separator index (eliminates duplication in getExtname and getBasename)\n */\nfunction findLastSeparator(path: string): number {\n return Math.max(path.lastIndexOf('/'), path.lastIndexOf('\\\\'));\n}\n\n/**\n * Helper: Create path operation object (eliminates duplication in posix and win32)\n */\nfunction createPathOps(isWin: boolean) {\n return {\n sep: getSeparator(isWin),\n delimiter: isWin ? ';' : ':',\n normalize: (path: string) => normalizePath(path, isWin),\n join: (...paths: string[]) => joinPaths(paths, isWin),\n resolve: (...paths: string[]) => resolvePaths(paths, isWin),\n isAbsolute: (path: string) => isWin ? isAbsoluteWin(path) : isAbsolutePosix(path),\n relative: (from: string, to: string) => relativePath(from, to, isWin),\n dirname: (path: string) => getDirname(path, isWin),\n basename: (path: string, ext?: string) => getBasename(path, ext, isWin),\n extname: (path: string) => getExtname(path),\n parse: (path: string) => parsePath(path, isWin),\n format: (pathObject: FormatInputPathObject) => formatPath(pathObject, isWin)\n };\n}\n\n/**\n * Helper: Check if path is absolute (POSIX)\n */\nfunction isAbsolutePosix(path: string): boolean {\n return path.length > 0 && path[0] === '/';\n}\n\n/**\n * Helper: Check if path is absolute (Windows)\n */\nfunction isAbsoluteWin(path: string): boolean {\n const len = path.length;\n if (len === 0) return false;\n\n const code = path.charCodeAt(0);\n if (code === 47 /* / */ || code === 92 /* \\ */) {\n return true;\n }\n\n // Check for drive letter\n if ((code >= 65 && code <= 90) || (code >= 97 && code <= 122)) {\n if (len > 2 && path.charCodeAt(1) === 58 /* : */) {\n const code2 = path.charCodeAt(2);\n if (code2 === 47 /* / */ || code2 === 92 /* \\ */) {\n return true;\n }\n }\n }\n\n return false;\n}\n\n/**\n * Platform detection\n */\nconst isWindows = (() => {\n if (isNode) {\n return process.platform === 'win32';\n } else if (isDeno) {\n // @ts-ignore\n return Deno.build.os === 'windows';\n }\n // Bun uses process.platform like Node\n return typeof process !== 'undefined' && process.platform === 'win32';\n})();\n\n/**\n * Path separator\n */\nexport const sep = isWindows ? '\\\\' : '/';\n\n/**\n * Path delimiter\n */\nexport const delimiter = isWindows ? ';' : ':';\n\n/**\n * POSIX path operations\n */\nconst posix = createPathOps(false);\n\n/**\n * Windows path operations\n */\nconst win32 = createPathOps(true);\n\n/**\n * Path object interface\n */\nexport interface ParsedPath {\n root: string;\n dir: string;\n base: string;\n ext: string;\n name: string;\n}\n\nexport interface FormatInputPathObject {\n root?: string;\n dir?: string;\n base?: string;\n ext?: string;\n name?: string;\n}\n\n/**\n * Normalize a path\n */\nfunction normalizePath(path: string, isWin: boolean): string {\n if (path.length === 0) return '.';\n\n const separator = getSeparator(isWin);\n const isAbsolute = isWin ? isAbsoluteWin(path) : isAbsolutePosix(path);\n const trailingSeparator = path[path.length - 1] === separator || (isWin && path[path.length - 1] === '/');\n\n // Normalize slashes\n let normalized = path.replace(isWin ? /[\\/\\\\]+/g : /\\/+/g, separator);\n\n // Split path\n const parts = normalized.split(separator);\n const result: string[] = [];\n\n for (let i = 0; i < parts.length; i++) {\n const part = parts[i];\n\n if (part === '' || part === '.') {\n if (i === 0 && isAbsolute) result.push('');\n continue;\n }\n\n if (part === '..') {\n if (result.length > 0 && result[result.length - 1] !== '..') {\n if (!(result.length === 1 && result[0] === '')) {\n result.pop();\n }\n } else if (!isAbsolute) {\n result.push('..');\n }\n } else {\n result.push(part);\n }\n }\n\n let final = result.join(separator);\n\n if (final.length === 0) {\n return isAbsolute ? separator : '.';\n }\n\n if (trailingSeparator && final[final.length - 1] !== separator) {\n final += separator;\n }\n\n return final;\n}\n\n/**\n * Join paths\n */\nfunction joinPaths(paths: string[], isWin: boolean): string {\n if (paths.length === 0) return '.';\n\n const separator = getSeparator(isWin);\n let joined = '';\n for (let i = 0; i < paths.length; i++) {\n const path = paths[i];\n if (path && path.length > 0) {\n if (joined.length === 0) {\n joined = path;\n } else {\n joined += separator + path;\n }\n }\n }\n\n if (joined.length === 0) return '.';\n\n return normalizePath(joined, isWin);\n}\n\n/**\n * Resolve paths to absolute path\n */\nfunction resolvePaths(paths: string[], isWin: boolean): string {\n const separator = getSeparator(isWin);\n let resolved = '';\n let isAbsolute = false;\n\n for (let i = paths.length - 1; i >= 0 && !isAbsolute; i--) {\n const path = paths[i];\n if (path && path.length > 0) {\n resolved = path + (resolved.length > 0 ? separator + resolved : '');\n isAbsolute = isWin ? isAbsoluteWin(resolved) : isAbsolutePosix(resolved);\n }\n }\n\n if (!isAbsolute) {\n const cwd = getCwd();\n resolved = cwd + (resolved.length > 0 ? separator + resolved : '');\n }\n\n return normalizePath(resolved, isWin);\n}\n\n/**\n * Get relative path\n */\nfunction relativePath(from: string, to: string, isWin: boolean): string {\n from = resolvePaths([from], isWin);\n to = resolvePaths([to], isWin);\n\n if (from === to) return '';\n\n const separator = getSeparator(isWin);\n const fromParts = from.split(separator).filter(p => p.length > 0);\n const toParts = to.split(separator).filter(p => p.length > 0);\n\n let commonLength = 0;\n const minLength = Math.min(fromParts.length, toParts.length);\n\n for (let i = 0; i < minLength; i++) {\n if (fromParts[i] === toParts[i]) {\n commonLength++;\n } else {\n break;\n }\n }\n\n const upCount = fromParts.length - commonLength;\n const result: string[] = [];\n\n for (let i = 0; i < upCount; i++) {\n result.push('..');\n }\n\n for (let i = commonLength; i < toParts.length; i++) {\n result.push(toParts[i]);\n }\n\n return result.join(separator) || '.';\n}\n\n/**\n * Get directory name\n */\nfunction getDirname(path: string, isWin: boolean): string {\n if (path.length === 0) return '.';\n\n const separator = getSeparator(isWin);\n const normalized = normalizePath(path, isWin);\n const lastSepIndex = normalized.lastIndexOf(separator);\n\n if (lastSepIndex === -1) return '.';\n if (lastSepIndex === 0) return separator;\n\n return normalized.slice(0, lastSepIndex);\n}\n\n/**\n * Get base name\n */\nfunction getBasename(path: string, ext?: string, isWin?: boolean): string {\n if (path.length === 0) return '';\n\n const lastSepIndex = isWin ? findLastSeparator(path) : path.lastIndexOf('/');\n let base = lastSepIndex === -1 ? path : path.slice(lastSepIndex + 1);\n\n if (ext && base.endsWith(ext)) {\n base = base.slice(0, base.length - ext.length);\n }\n\n return base;\n}\n\n/**\n * Get extension name\n */\nfunction getExtname(path: string): string {\n const lastDotIndex = path.lastIndexOf('.');\n const lastSepIndex = findLastSeparator(path);\n\n if (lastDotIndex === -1 || lastDotIndex < lastSepIndex || lastDotIndex === path.length - 1) {\n return '';\n }\n\n return path.slice(lastDotIndex);\n}\n\n/**\n * Parse path into components\n */\nfunction parsePath(path: string, isWin: boolean): ParsedPath {\n let root = '';\n if (isWin) {\n // Check for Windows drive letter\n if (path.length >= 2 && path[1] === ':') {\n root = path.slice(0, 2);\n if (path.length > 2 && (path[2] === '\\\\' || path[2] === '/')) {\n root += '\\\\';\n }\n } else if (path[0] === '\\\\' || path[0] === '/') {\n root = '\\\\';\n }\n } else {\n if (path[0] === '/') {\n root = '/';\n }\n }\n\n const dir = getDirname(path, isWin);\n const base = getBasename(path, undefined, isWin);\n const ext = getExtname(path);\n const name = ext ? base.slice(0, base.length - ext.length) : base;\n\n return { root, dir, base, ext, name };\n}\n\n/**\n * Format path from components\n */\nfunction formatPath(pathObject: FormatInputPathObject, isWin: boolean): string {\n const separator = getSeparator(isWin);\n const dir = pathObject.dir || pathObject.root || '';\n const base = pathObject.base || ((pathObject.name || '') + (pathObject.ext || ''));\n\n if (!dir) return base;\n if (dir === pathObject.root) return dir + base;\n\n return dir + separator + base;\n}\n\n/**\n * Normalize a path (platform-specific)\n */\nexport function normalize(path: string): string {\n return normalizePath(path, isWindows);\n}\n\n/**\n * Join paths (platform-specific)\n */\nexport function join(...paths: string[]): string {\n return joinPaths(paths, isWindows);\n}\n\n/**\n * Resolve paths to absolute path (platform-specific)\n */\nexport function resolve(...paths: string[]): string {\n return resolvePaths(paths, isWindows);\n}\n\n/**\n * Check if path is absolute (platform-specific)\n */\nexport function isAbsolute(path: string): boolean {\n return isWindows ? win32.isAbsolute(path) : posix.isAbsolute(path);\n}\n\n/**\n * Get relative path (platform-specific)\n */\nexport function relative(from: string, to: string): string {\n return relativePath(from, to, isWindows);\n}\n\n/**\n * Get directory name (platform-specific)\n */\nexport function dirname(path: string): string {\n return getDirname(path, isWindows);\n}\n\n/**\n * Get base name (platform-specific)\n */\nexport function basename(path: string, ext?: string): string {\n return getBasename(path, ext, isWindows);\n}\n\n/**\n * Get extension name\n */\nexport function extname(path: string): string {\n return getExtname(path);\n}\n\n/**\n * Parse path into components (platform-specific)\n */\nexport function parse(path: string): ParsedPath {\n return parsePath(path, isWindows);\n}\n\n/**\n * Format path from components (platform-specific)\n */\nexport function format(pathObject: FormatInputPathObject): string {\n return formatPath(pathObject, isWindows);\n}\n\n/**\n * Convert to namespaced path (Windows only)\n */\nexport function toNamespacedPath(path: string): string {\n if (!isWindows || path.length === 0) return path;\n\n const resolved = resolve(path);\n\n if (resolved.length >= 3) {\n if (resolved[0] === '\\\\') {\n // UNC path\n if (resolved[1] === '\\\\' && resolved[2] !== '?') {\n return '\\\\\\\\?\\\\UNC\\\\' + resolved.slice(2);\n }\n } else if (resolved[1] === ':' && resolved[2] === '\\\\') {\n // Drive letter\n return '\\\\\\\\?\\\\' + resolved;\n }\n }\n\n return path;\n}\n\n/**\n * Get current runtime\n */\nexport function getRuntime(): 'node' | 'bun' | 'deno' {\n return runtime;\n}\n\n/**\n * Export POSIX and Win32 implementations\n */\nexport { posix, win32 };\n\n/**\n * Default export\n */\nexport default {\n sep,\n delimiter,\n normalize,\n join,\n resolve,\n isAbsolute,\n relative,\n dirname,\n basename,\n extname,\n parse,\n format,\n toNamespacedPath,\n posix,\n win32,\n getRuntime,\n};\n"],"mappings":"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","names":["relativePath"]}