supply-scan 1.0.2 → 1.1.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/README.md +31 -9
- package/dist/index.d.ts +1 -1
- package/dist/index.js +627 -383
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/rules/axios-2026.json +43 -11
- package/rules/chalk-debug-2025.json +72 -23
- package/rules/coa-rc-2021.json +32 -7
- package/rules/colors-faker-2022.json +12 -4
- package/rules/eslint-scope-2018.json +15 -5
- package/rules/event-stream-2018.json +14 -5
- package/rules/glassworm-2026.json +27 -7
- package/rules/lottie-player-2024.json +11 -3
- package/rules/node-ipc-2022.json +29 -8
- package/rules/shai-hulud-2025.json +27 -8
- package/rules/solana-web3-2024.json +13 -4
- package/rules/ua-parser-js-2021.json +24 -6
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/utils.ts","../src/ui.ts","../src/checks/packages.ts","../src/checks/files.ts","../src/checks/network.ts","../src/checks/processes.ts","../src/checks/cache.ts","../src/scanner.ts"],"sourcesContent":["import { fileURLToPath } from 'node:url';\nimport { dirname, join } from 'node:path';\nimport type { Rule } from './types.js';\nimport {\n parseArgs,\n loadRules,\n findProjects,\n getCommonProjectDirs,\n prompt,\n} from './utils.js';\nimport * as ui from './ui.js';\nimport { scan } from './scanner.js';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\nconst RULES_DIR = join(__dirname, '..', 'rules');\n\nconst VERSION = '1.0.0';\n\nconst HELP_TEXT = `\n${ui.c.white}supply-scan${ui.c.reset} — Universal npm supply chain attack scanner\n\n${ui.c.yellow}USAGE${ui.c.reset}\n npx supply-scan Interactive mode (default)\n npx supply-scan --all Scan all attacks, skip prompts\n npx supply-scan --rule axios-2026 Scan specific attack(s)\n npx supply-scan --list List all available rules\n npx supply-scan --ci CI mode (non-interactive)\n\n${ui.c.yellow}OPTIONS${ui.c.reset}\n -a, --all Scan all attacks (skip rule selection)\n -r, --rule <id> Scan specific rule (repeatable)\n -p, --path <dir> Scan specific directory\n -l, --list List all available rules\n --ci CI mode (non-interactive, exit codes only)\n -h, --help Show this help\n -v, --version Show version\n\n${ui.c.yellow}EXIT CODES${ui.c.reset}\n 0 All clear\n 1 Compromise detected\n 2 Warnings found\n\n${ui.c.yellow}EXAMPLES${ui.c.reset}\n npx supply-scan --path ~/projects/my-app\n npx supply-scan --rule axios-2026 --rule node-ipc-2022\n npx supply-scan --ci --all\n`;\n\nexport async function run(argv: string[]): Promise<void> {\n const opts = parseArgs(argv);\n\n // Handle --version\n if (opts.version) {\n console.log(VERSION);\n process.exit(0);\n }\n\n // Handle --help\n if (opts.help) {\n console.log(HELP_TEXT);\n process.exit(0);\n }\n\n // Load rules\n const allRules = loadRules(RULES_DIR);\n\n if (allRules.length === 0) {\n console.error(`${ui.c.red}No rules found in ${RULES_DIR}${ui.c.reset}`);\n process.exit(1);\n }\n\n // Handle --list\n if (opts.list) {\n ui.banner(allRules.length);\n ui.printRuleList(allRules);\n process.exit(0);\n }\n\n // Filter rules if --rule specified\n let selectedRules: Rule[];\n if (opts.rules.length > 0) {\n selectedRules = allRules.filter((r) => opts.rules.includes(r.id));\n if (selectedRules.length === 0) {\n console.error(`${ui.c.red}No matching rules found. Use --list to see available rules.${ui.c.reset}`);\n process.exit(1);\n }\n } else if (opts.all || opts.ci) {\n selectedRules = allRules;\n } else {\n // Interactive: show banner and rule selection\n ui.banner(allRules.length);\n selectedRules = await interactiveRuleSelection(allRules);\n }\n\n if (!opts.ci && (opts.all || opts.rules.length > 0)) {\n ui.banner(selectedRules.length);\n }\n\n // Determine scan directories\n let projectDirs: string[];\n\n if (opts.path) {\n if (!opts.ci) ui.spinnerStart('Searching for npm projects...');\n projectDirs = findProjects([opts.path]);\n if (!opts.ci) ui.spinnerStop();\n } else if (opts.ci || opts.all) {\n // Default to current directory in non-interactive modes\n if (!opts.ci) ui.spinnerStart('Searching for npm projects...');\n projectDirs = findProjects([process.cwd()]);\n if (!opts.ci) ui.spinnerStop();\n } else {\n projectDirs = await interactivePathSelection();\n }\n\n if (!opts.ci) {\n console.log(`\\n ${ui.c.dim}Scanning ${projectDirs.length} projects with ${selectedRules.length} rules...${ui.c.reset}`);\n }\n\n // Run scan\n const summary = await scan({\n rules: selectedRules,\n projectDirs,\n ci: opts.ci,\n });\n\n // Print summary\n if (!opts.ci) {\n ui.printSummary(summary);\n }\n\n // Exit code\n if (summary.failed > 0) {\n process.exit(1);\n } else if (summary.warnings > 0) {\n process.exit(2);\n } else {\n if (opts.ci) {\n console.log('OK');\n }\n process.exit(0);\n }\n}\n\n// ─── Interactive Prompts ────────────────────────────────────────────\n\nasync function interactiveRuleSelection(rules: Rule[]): Promise<Rule[]> {\n console.log('');\n console.log(` ${ui.c.white}Select attacks to scan:${ui.c.reset}`);\n console.log('');\n console.log(` ${ui.c.cyan}0${ui.c.reset}) ${ui.c.green}All attacks (${rules.length} rules)${ui.c.reset}`);\n\n for (let i = 0; i < rules.length; i++) {\n const r = rules[i];\n const sc = ui.severityColors[r.severity] || ui.c.dim;\n console.log(` ${ui.c.cyan}${i + 1}${ui.c.reset}) ${r.name} ${sc}(${r.severity})${ui.c.reset}`);\n }\n\n console.log('');\n const answer = await prompt(` ${ui.c.yellow}Enter numbers separated by commas (default=0): ${ui.c.reset}`);\n\n if (!answer || answer === '0') {\n return rules;\n }\n\n const indices = answer.split(',').map((s) => parseInt(s.trim(), 10) - 1);\n const selected = indices\n .filter((i) => i >= 0 && i < rules.length)\n .map((i) => rules[i]);\n\n return selected.length > 0 ? selected : rules;\n}\n\nasync function interactivePathSelection(): Promise<string[]> {\n console.log('');\n console.log(` ${ui.c.white}Where should I scan?${ui.c.reset}`);\n console.log('');\n console.log(` ${ui.c.cyan}1${ui.c.reset}) Current directory`);\n console.log(` ${ui.c.cyan}2${ui.c.reset}) Common project directories`);\n console.log(` ${ui.c.cyan}3${ui.c.reset}) Enter a custom path`);\n console.log('');\n\n const choice = await prompt(` ${ui.c.yellow}Choose (1/2/3, default=1): ${ui.c.reset}`);\n\n let baseDirs: string[];\n switch (choice) {\n case '2':\n baseDirs = getCommonProjectDirs();\n if (baseDirs.length === 0) {\n console.log(` ${ui.c.dim}No common directories found, scanning current directory...${ui.c.reset}`);\n baseDirs = [process.cwd()];\n }\n break;\n case '3': {\n const customPath = await prompt(` ${ui.c.cyan}Enter path: ${ui.c.reset}`);\n baseDirs = [customPath.replace(/^~/, process.env.HOME || '')];\n break;\n }\n default:\n baseDirs = [process.cwd()];\n }\n\n console.log('');\n ui.spinnerStart('Searching for npm projects...');\n const projects = findProjects(baseDirs);\n ui.spinnerStop();\n\n console.log(` ${ui.c.dim}Found ${projects.length} npm projects${ui.c.reset}`);\n\n return projects;\n}\n\n// ─── Auto-run when executed as CLI ──────────────────────────────────\n\nconst isCLI =\n process.argv[1]?.includes('supply-scan') ||\n process.argv[1]?.includes('dist/index');\n\nif (isCLI) {\n run(process.argv.slice(2));\n}\n","import { readFileSync, readdirSync, existsSync, statSync } from 'node:fs';\nimport { join, resolve } from 'node:path';\nimport { platform, homedir } from 'node:os';\nimport { execSync } from 'node:child_process';\nimport { createInterface } from 'node:readline';\nimport type { Rule, CLIOptions } from './types.js';\n\n// ─── OS Detection ───────────────────────────────────────────────────\n\nexport function getOS(): string {\n return platform();\n}\n\nexport function getHomeDir(): string {\n return homedir();\n}\n\n// ─── JSON Reader ────────────────────────────────────────────────────\n\nexport function readJSON<T>(path: string): T | null {\n try {\n const content = readFileSync(path, 'utf-8');\n return JSON.parse(content) as T;\n } catch {\n return null;\n }\n}\n\n// ─── Version Matching ───────────────────────────────────────────────\n\nexport function getPkgVersion(pkgJsonPath: string): string | null {\n const pkg = readJSON<{ version?: string }>(pkgJsonPath);\n return pkg?.version ?? null;\n}\n\nexport function isVersionCompromised(\n version: string | null,\n badVersions: string[]\n): boolean {\n if (!version) return false;\n return badVersions.includes(version);\n}\n\n// ─── Path Expansion ─────────────────────────────────────────────────\n\nexport function expandPath(p: string): string {\n let result = p;\n if (result.startsWith('~')) {\n result = join(homedir(), result.slice(1));\n }\n if (result.includes('%PROGRAMDATA%')) {\n result = result.replace('%PROGRAMDATA%', process.env.PROGRAMDATA || 'C:\\\\ProgramData');\n }\n if (result.includes('%TEMP%')) {\n result = result.replace('%TEMP%', process.env.TEMP || '/tmp');\n }\n if (result.includes('%USERPROFILE%')) {\n result = result.replace('%USERPROFILE%', homedir());\n }\n return result;\n}\n\n// ─── Project Discovery ──────────────────────────────────────────────\n\nexport function findProjects(baseDirs: string[], maxDepth = 8): string[] {\n const projects: Set<string> = new Set();\n\n function walk(dir: string, depth: number): void {\n if (depth > maxDepth) return;\n\n try {\n const entries = readdirSync(dir, { withFileTypes: true });\n for (const entry of entries) {\n if (!entry.isDirectory()) {\n if (entry.name === 'package.json' && depth > 0) {\n projects.add(dir);\n }\n continue;\n }\n\n // Skip irrelevant directories\n const skip = [\n 'node_modules', '.git', 'bower_components',\n '.cache', '.Trash', 'Library', '.npm',\n ];\n if (skip.includes(entry.name)) continue;\n\n walk(join(dir, entry.name), depth + 1);\n }\n } catch {\n // Permission denied or broken symlink\n }\n }\n\n // Also check base dir itself for package.json\n for (const base of baseDirs) {\n if (!existsSync(base)) continue;\n if (existsSync(join(base, 'package.json'))) {\n projects.add(base);\n }\n walk(base, 0);\n }\n\n return Array.from(projects);\n}\n\n// ─── Common Project Directories ─────────────────────────────────────\n\nexport function getCommonProjectDirs(): string[] {\n const home = homedir();\n const candidates = [\n 'Desktop', 'Documents', 'Projects', 'projects',\n 'Developer', 'dev', 'code', 'Code',\n 'Sites', 'sites', 'www', 'Work', 'work',\n 'workspace', 'Workspace', 'repos', 'Repos',\n 'src', 'github', 'GitHub',\n ];\n return candidates\n .map((d) => join(home, d))\n .filter((d) => existsSync(d));\n}\n\n// ─── Rule Loader ────────────────────────────────────────────────────\n\nexport function loadRules(rulesDir: string): Rule[] {\n const rules: Rule[] = [];\n\n try {\n const files = readdirSync(rulesDir).filter((f) => f.endsWith('.json'));\n for (const file of files) {\n const rule = readJSON<Rule>(join(rulesDir, file));\n if (rule && rule.id && rule.packages) {\n rules.push(rule);\n }\n }\n } catch {\n // Rules directory not found\n }\n\n // Sort by date descending (newest first)\n rules.sort((a, b) => b.date.localeCompare(a.date));\n return rules;\n}\n\n// ─── CLI Arg Parser ─────────────────────────────────────────────────\n\nexport function parseArgs(argv: string[]): CLIOptions {\n const opts: CLIOptions = {\n rules: [],\n all: false,\n list: false,\n path: null,\n ci: false,\n help: false,\n version: false,\n };\n\n for (let i = 0; i < argv.length; i++) {\n const arg = argv[i];\n switch (arg) {\n case '--all':\n case '-a':\n opts.all = true;\n break;\n case '--list':\n case '-l':\n opts.list = true;\n break;\n case '--ci':\n opts.ci = true;\n opts.all = true;\n break;\n case '--help':\n case '-h':\n opts.help = true;\n break;\n case '--version':\n case '-v':\n opts.version = true;\n break;\n case '--rule':\n case '-r':\n if (i + 1 < argv.length) {\n opts.rules.push(argv[++i]);\n }\n break;\n case '--path':\n case '-p':\n if (i + 1 < argv.length) {\n opts.path = resolve(argv[++i]);\n }\n break;\n }\n }\n\n return opts;\n}\n\n// ─── Shell Command Runner ───────────────────────────────────────────\n\nexport function runCommand(cmd: string): string {\n try {\n return execSync(cmd, { encoding: 'utf-8', timeout: 10000, stdio: ['pipe', 'pipe', 'pipe'] }).trim();\n } catch {\n return '';\n }\n}\n\n// ─── Interactive Prompt ─────────────────────────────────────────────\n\nexport function prompt(question: string): Promise<string> {\n const rl = createInterface({\n input: process.stdin,\n output: process.stdout,\n });\n return new Promise((resolve) => {\n rl.question(question, (answer) => {\n rl.close();\n resolve(answer.trim());\n });\n });\n}\n\n// ─── File Exists Check ──────────────────────────────────────────────\n\nexport function fileExists(path: string): boolean {\n try {\n return statSync(path).isFile();\n } catch {\n return false;\n }\n}\n\nexport function dirExists(path: string): boolean {\n try {\n return statSync(path).isDirectory();\n } catch {\n return false;\n }\n}\n\n","import { type ResultType, type CheckResult, type ScanSummary, type Rule } from './types.js';\n\n// ─── ANSI Color Codes (zero deps) ──────────────────────────────────\n\nconst ESC = '\\x1b';\n\nexport const c = {\n red: `${ESC}[1;31m`,\n green: `${ESC}[1;32m`,\n yellow: `${ESC}[1;33m`,\n cyan: `${ESC}[1;36m`,\n white: `${ESC}[1;37m`,\n dim: `${ESC}[2m`,\n bold: `${ESC}[1m`,\n reset: `${ESC}[0m`,\n bgRed: `${ESC}[41m`,\n bgGreen: `${ESC}[42m`,\n bgYellow: `${ESC}[43m`,\n bgBlue: `${ESC}[44m`,\n};\n\n// ─── Symbols ────────────────────────────────────────────────────────\n\nconst sym = {\n pass: '\\u2705',\n fail: '\\uD83D\\uDEA8',\n warn: '\\u26A0\\uFE0F ',\n info: '\\uD83D\\uDCA1',\n scan: '\\uD83D\\uDD0D',\n shield: '\\uD83D\\uDEE1\\uFE0F ',\n skull: '\\uD83D\\uDC80',\n clean: '\\u2728',\n gear: '\\u2699\\uFE0F ',\n pkg: '\\uD83D\\uDCE6',\n lock: '\\uD83D\\uDD12',\n globe: '\\uD83C\\uDF10',\n folder: '\\uD83D\\uDCC1',\n};\n\n// ─── Banner ─────────────────────────────────────────────────────────\n\nexport function banner(ruleCount: number): void {\n const w = process.stdout.write.bind(process.stdout);\n w('\\n');\n w(`${c.cyan} ___ _ _ ___ ___ _ _ _ ___ ___ _ _ _ ${c.reset}\\n`);\n w(`${c.cyan} / __| | | | _ \\\\ _ \\\\ | | | | | / __|/ __| /_\\\\ | \\\\| |${c.reset}\\n`);\n w(`${c.cyan} \\\\__ \\\\ |_| | _/ _/ |_| |_| |_| (__| (__ / _ \\\\| .\\` |${c.reset}\\n`);\n w(`${c.cyan} |___/\\\\___/|_| |_| \\\\__, |_____|\\\\___|\\\\___|_/ \\\\_\\\\_|\\\\_|${c.reset}\\n`);\n w(`${c.cyan} |___/ ${c.dim}v1.0.0${c.reset}\\n`);\n w('\\n');\n w(` ${c.white}Universal npm Supply Chain Attack Scanner${c.reset}\\n`);\n w(` ${c.dim}Detects ${ruleCount} known attacks | Zero dependencies${c.reset}\\n`);\n w('\\n');\n divider();\n}\n\n// ─── Divider ────────────────────────────────────────────────────────\n\nexport function divider(): void {\n console.log(`${c.dim}${'─'.repeat(60)}${c.reset}`);\n}\n\n// ─── Section Header ─────────────────────────────────────────────────\n\nexport function sectionHeader(num: number, total: number, title: string, icon: string): void {\n console.log('');\n console.log(`${c.bgBlue}${c.white}${c.bold} ${icon} CHECK ${num}/${total} │ ${title} ${c.reset}`);\n divider();\n}\n\n// ─── Result Formatters ──────────────────────────────────────────────\n\nexport function result(type: ResultType, msg: string): void {\n const icons: Record<ResultType, string> = {\n pass: sym.pass,\n fail: sym.fail,\n warn: sym.warn,\n info: sym.info,\n };\n const colors: Record<ResultType, string> = {\n pass: c.green,\n fail: `${c.red}${c.bold}`,\n warn: c.yellow,\n info: c.dim,\n };\n console.log(` ${icons[type]} ${colors[type]}${msg}${c.reset}`);\n}\n\nexport function resultDetail(msg: string): void {\n console.log(` ${c.red}→ ${msg}${c.reset}`);\n}\n\n// ─── Spinner ────────────────────────────────────────────────────────\n\nconst SPIN_FRAMES = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];\n\nlet spinnerTimer: ReturnType<typeof setInterval> | null = null;\nlet spinnerFrame = 0;\n\nexport function spinnerStart(msg: string): void {\n spinnerFrame = 0;\n spinnerTimer = setInterval(() => {\n const frame = SPIN_FRAMES[spinnerFrame % SPIN_FRAMES.length];\n process.stdout.write(`\\r ${c.cyan}${frame}${c.reset} ${c.dim}${msg}${c.reset}`);\n spinnerFrame++;\n }, 80);\n}\n\nexport function spinnerStop(): void {\n if (spinnerTimer) {\n clearInterval(spinnerTimer);\n spinnerTimer = null;\n process.stdout.write('\\r\\x1b[K');\n }\n}\n\n// ─── Progress Bar ───────────────────────────────────────────────────\n\nexport function progressBar(current: number, total: number, label: string): void {\n const width = 30;\n const pct = Math.round((current / total) * 100);\n const filled = Math.round((current / total) * width);\n const empty = width - filled;\n const bar = `${c.green}${'█'.repeat(filled)}${c.reset}${c.dim}${'░'.repeat(empty)}${c.reset}`;\n const name = label.length > 25 ? label.slice(0, 22) + '...' : label;\n process.stdout.write(`\\r ${c.dim}[${c.reset}${bar}${c.dim}]${c.reset} ${c.white}${pct}%${c.reset} ${c.dim}${name.padEnd(25)}${c.reset}`);\n}\n\nexport function progressClear(): void {\n process.stdout.write('\\r\\x1b[K');\n}\n\n// ─── Rule List ──────────────────────────────────────────────────────\n\nexport const severityColors: Record<string, string> = {\n critical: c.red,\n high: c.yellow,\n medium: c.cyan,\n low: c.dim,\n};\n\nexport function printRuleList(rules: Rule[]): void {\n console.log('');\n console.log(` ${c.white}Available attack rules (${rules.length}):${c.reset}`);\n console.log('');\n\n for (const rule of rules) {\n const sc = severityColors[rule.severity] || c.dim;\n const pkgCount =\n Object.keys(rule.packages.compromised).length +\n Object.keys(rule.packages.malicious).length;\n console.log(\n ` ${c.dim}•${c.reset} ${c.white}${rule.id.padEnd(25)}${c.reset} ${sc}${rule.severity.padEnd(10)}${c.reset} ${c.dim}${rule.date}${c.reset} ${c.dim}(${pkgCount} pkgs)${c.reset}`\n );\n console.log(` ${c.dim}${rule.description}${c.reset}`);\n }\n console.log('');\n}\n\n// ─── Summary ────────────────────────────────────────────────────────\n\nexport function printSummary(summary: ScanSummary): void {\n console.log('');\n console.log(`${c.cyan}${'═'.repeat(60)}${c.reset}`);\n console.log(` ${sym.shield} ${c.white}${c.bold}SCAN COMPLETE${c.reset}`);\n console.log(`${c.cyan}${'═'.repeat(60)}${c.reset}`);\n console.log('');\n console.log(` ${c.dim}Projects scanned:${c.reset} ${c.white}${summary.projectsScanned}${c.reset}`);\n console.log(` ${c.dim}Rules checked:${c.reset} ${c.white}${summary.rulesChecked}${c.reset}`);\n console.log(` ${c.dim}Total checks:${c.reset} ${c.white}${summary.totalChecks}${c.reset}`);\n console.log(` ${c.green}Passed:${c.reset} ${c.green}${summary.passed}${c.reset}`);\n console.log(` ${c.yellow}Warnings:${c.reset} ${c.yellow}${summary.warnings}${c.reset}`);\n console.log(` ${c.red}Failed:${c.reset} ${c.red}${summary.failed}${c.reset}`);\n console.log('');\n divider();\n\n if (summary.failed > 0) {\n console.log('');\n console.log(` ${c.bgRed}${c.white}${c.bold} ⛔ COMPROMISE DETECTED ⛔ ${c.reset}`);\n console.log('');\n console.log(` ${c.red}${c.bold}Immediate Actions Required:${c.reset}`);\n console.log('');\n console.log(` ${c.red}1.${c.reset} Disconnect from the network`);\n console.log(` ${c.red}2.${c.reset} Rotate ALL credentials, tokens, API keys, SSH keys`);\n console.log(` ${c.red}3.${c.reset} Remove compromised packages: ${c.white}npm install <pkg>@latest${c.reset}`);\n console.log(` ${c.red}4.${c.reset} Clean npm cache: ${c.white}npm cache clean --force${c.reset}`);\n console.log(` ${c.red}5.${c.reset} Review system for backdoors and persistence mechanisms`);\n console.log(` ${c.red}6.${c.reset} Consider full system wipe if RAT/worm was executed`);\n console.log('');\n\n if (summary.compromisedProjects.length > 0) {\n console.log(` ${c.red}${c.bold}Compromised Projects:${c.reset}`);\n for (const proj of summary.compromisedProjects) {\n console.log(` ${c.red}${sym.skull} ${proj}${c.reset}`);\n }\n console.log('');\n }\n\n // Show failed results grouped by rule\n const failedByRule = new Map<string, CheckResult[]>();\n for (const r of summary.results.filter((r) => r.type === 'fail')) {\n const arr = failedByRule.get(r.rule) || [];\n arr.push(r);\n failedByRule.set(r.rule, arr);\n }\n for (const [rule, results] of failedByRule) {\n console.log(` ${c.red}${c.bold}${rule}:${c.reset}`);\n for (const r of results) {\n console.log(` ${c.red}→ ${r.message}${c.reset}`);\n if (r.details) console.log(` ${c.dim}${r.details}${c.reset}`);\n }\n console.log('');\n }\n } else if (summary.warnings > 0) {\n console.log('');\n console.log(` ${c.bgYellow}${c.white}${c.bold} ⚠ WARNINGS FOUND — REVIEW RECOMMENDED ⚠ ${c.reset}`);\n console.log('');\n console.log(` ${c.yellow}Some items need manual review. Check the warnings above.${c.reset}`);\n console.log('');\n } else {\n console.log('');\n console.log(` ${c.bgGreen}${c.white}${c.bold} ${sym.clean} ALL CLEAR — NO COMPROMISE DETECTED ${sym.clean} ${c.reset}`);\n console.log('');\n console.log(` ${c.green}Your system appears clean from all known supply chain attacks.${c.reset}`);\n console.log('');\n console.log(` ${c.dim}Prevention tips:${c.reset}`);\n console.log(` ${c.cyan}›${c.reset} Use lockfiles and verify package integrity`);\n console.log(` ${c.cyan}›${c.reset} Pin dependencies to exact versions`);\n console.log(` ${c.cyan}›${c.reset} Enable npm audit in your CI/CD pipeline`);\n console.log(` ${c.cyan}›${c.reset} Monitor for SLSA provenance on critical packages`);\n console.log('');\n }\n\n divider();\n console.log('');\n console.log(` ${c.dim}Scan completed at ${new Date().toISOString()}${c.reset}`);\n console.log(` ${c.dim}https://github.com/AsyrafHussin/supply-scan${c.reset}`);\n console.log('');\n}\n","import { join } from 'node:path';\nimport { readFileSync } from 'node:fs';\nimport type { Rule, CheckResult } from '../types.js';\nimport { dirExists, getPkgVersion, isVersionCompromised } from '../utils.js';\n\nexport function checkPackages(\n rules: Rule[],\n projectDirs: string[]\n): CheckResult[] {\n const results: CheckResult[] = [];\n\n for (const dir of projectDirs) {\n // Cache lockfile contents per project (read once, check all rules)\n const lockfileCache = readLockfiles(dir);\n\n for (const rule of rules) {\n // Check compromised packages in node_modules\n for (const [pkg, badVersions] of Object.entries(rule.packages.compromised)) {\n const version = getPkgVersion(join(dir, 'node_modules', pkg, 'package.json'));\n if (version && isVersionCompromised(version, badVersions)) {\n results.push({\n type: 'fail',\n rule: rule.id,\n check: 'packages',\n message: `${pkg}@${version} is COMPROMISED`,\n details: `${rule.name} — ${dir}`,\n });\n }\n }\n\n // Check malicious packages (should not exist at all)\n for (const [pkg] of Object.entries(rule.packages.malicious)) {\n const pkgDir = join(dir, 'node_modules', pkg);\n if (dirExists(pkgDir)) {\n const version = getPkgVersion(join(pkgDir, 'package.json'));\n results.push({\n type: 'fail',\n rule: rule.id,\n check: 'packages',\n message: `Malicious package ${pkg}${version ? `@${version}` : ''} found`,\n details: `${rule.name} — ${dir}`,\n });\n }\n }\n\n // Check lockfiles for references\n checkLockfilesForRule(lockfileCache, dir, rule, results);\n }\n }\n\n return results;\n}\n\nfunction readLockfiles(dir: string): Map<string, string> {\n const cache = new Map<string, string>();\n // All supported lockfile formats: npm, yarn, pnpm, bun\n const lockfiles = [\n 'package-lock.json',\n 'yarn.lock',\n 'pnpm-lock.yaml',\n 'bun.lock', // bun text-based lockfile (bun v1.2+)\n 'bun.lockb', // bun binary lockfile (older bun)\n ];\n for (const name of lockfiles) {\n try {\n // bun.lockb is binary — read as latin1 so string search still works on package names\n const encoding = name === 'bun.lockb' ? 'latin1' : 'utf-8';\n cache.set(name, readFileSync(join(dir, name), encoding));\n } catch {\n // File doesn't exist\n }\n }\n return cache;\n}\n\nfunction checkLockfilesForRule(\n lockfileCache: Map<string, string>,\n dir: string,\n rule: Rule,\n results: CheckResult[]\n): void {\n for (const [lockfile, content] of lockfileCache) {\n // Check for malicious package names\n for (const pkg of Object.keys(rule.packages.malicious)) {\n if (content.includes(pkg)) {\n results.push({\n type: 'fail',\n rule: rule.id,\n check: 'lockfile',\n message: `${lockfile} references malicious package \"${pkg}\"`,\n details: `${rule.name} — ${dir}`,\n });\n }\n }\n\n // Check for compromised versions using specific patterns\n for (const [pkg, versions] of Object.entries(rule.packages.compromised)) {\n for (const ver of versions) {\n // Only match patterns that tie the package name to the version\n const tied = [\n `\"${pkg}\": \"${ver}\"`, // package-lock.json / bun.lock\n `${pkg}@${ver}`, // yarn.lock / pnpm-lock.yaml\n `\"${pkg}\",\"${ver}\"`, // bun.lockb binary format\n ];\n if (tied.some((p) => content.includes(p))) {\n results.push({\n type: 'warn',\n rule: rule.id,\n check: 'lockfile',\n message: `${lockfile} may reference ${pkg}@${ver}`,\n details: `${rule.name} — ${dir}`,\n });\n }\n }\n }\n }\n}\n","import type { Rule, CheckResult } from '../types.js';\nimport { expandPath, fileExists, getOS } from '../utils.js';\n\n/**\n * Check for known malware artifacts on disk.\n * Checks OS-specific file paths from rule IOCs.\n */\nexport function checkFiles(rules: Rule[]): CheckResult[] {\n const results: CheckResult[] = [];\n const os = getOS();\n\n for (const rule of rules) {\n const filePaths = rule.ioc.files?.[os];\n if (!filePaths || filePaths.length === 0) continue;\n\n for (const rawPath of filePaths) {\n const path = expandPath(rawPath);\n if (fileExists(path)) {\n results.push({\n type: 'fail',\n rule: rule.id,\n check: 'files',\n message: `Malware artifact found: ${path}`,\n details: rule.name,\n });\n }\n }\n }\n\n return results;\n}\n","import { readFileSync } from 'node:fs';\nimport type { Rule, CheckResult } from '../types.js';\nimport { getOS, runCommand } from '../utils.js';\n\n/**\n * Check for active C2 connections and network IOCs.\n */\nexport function checkNetwork(rules: Rule[]): CheckResult[] {\n const results: CheckResult[] = [];\n const os = getOS();\n\n // Collect all C2 IPs and domains from rules\n const allIPs = new Set<string>();\n const allDomains = new Set<string>();\n const ruleByIOC = new Map<string, string>();\n\n for (const rule of rules) {\n for (const ip of rule.ioc.ips ?? []) {\n allIPs.add(ip);\n ruleByIOC.set(ip, rule.id);\n }\n for (const domain of rule.ioc.domains ?? []) {\n allDomains.add(domain);\n ruleByIOC.set(domain, rule.id);\n }\n }\n\n if (allIPs.size === 0 && allDomains.size === 0) return results;\n\n // Check active connections\n const connections = getActiveConnections(os);\n for (const ip of allIPs) {\n if (connections.includes(ip)) {\n results.push({\n type: 'fail',\n rule: ruleByIOC.get(ip) || 'unknown',\n check: 'network',\n message: `Active connection to C2 IP: ${ip}`,\n details: 'Disconnect from network immediately!',\n });\n }\n }\n\n for (const domain of allDomains) {\n if (connections.includes(domain)) {\n results.push({\n type: 'fail',\n rule: ruleByIOC.get(domain) || 'unknown',\n check: 'network',\n message: `Active connection to C2 domain: ${domain}`,\n details: 'Disconnect from network immediately!',\n });\n }\n }\n\n // Check /etc/hosts\n checkHostsFile(allIPs, allDomains, ruleByIOC, results);\n\n return results;\n}\n\nfunction getActiveConnections(os: string): string {\n if (os === 'darwin' || os === 'linux') {\n return runCommand('lsof -i -n -P 2>/dev/null || netstat -an 2>/dev/null');\n } else if (os === 'win32') {\n return runCommand('netstat -an');\n }\n return '';\n}\n\nfunction checkHostsFile(\n ips: Set<string>,\n domains: Set<string>,\n ruleByIOC: Map<string, string>,\n results: CheckResult[]\n): void {\n try {\n const hosts = readFileSync('/etc/hosts', 'utf-8');\n for (const ip of ips) {\n if (hosts.includes(ip)) {\n results.push({\n type: 'warn',\n rule: ruleByIOC.get(ip) || 'unknown',\n check: 'network',\n message: `C2 IP ${ip} found in /etc/hosts`,\n });\n }\n }\n for (const domain of domains) {\n if (hosts.includes(domain)) {\n results.push({\n type: 'warn',\n rule: ruleByIOC.get(domain) || 'unknown',\n check: 'network',\n message: `C2 domain ${domain} found in /etc/hosts`,\n });\n }\n }\n } catch {\n // Can't read hosts file\n }\n}\n","import type { Rule, CheckResult } from '../types.js';\nimport { getOS, runCommand, dirExists } from '../utils.js';\n\n/**\n * Check for known malicious processes running on the system.\n */\nexport function checkProcesses(rules: Rule[]): CheckResult[] {\n const results: CheckResult[] = [];\n const os = getOS();\n\n // Collect all process patterns from rules\n const processPatterns = new Map<string, string>(); // pattern -> ruleId\n\n for (const rule of rules) {\n for (const proc of rule.ioc.processes ?? []) {\n processPatterns.set(proc, rule.id);\n }\n }\n\n if (processPatterns.size === 0) return results;\n\n // Get running processes\n const processList = getProcessList(os);\n if (!processList) return results;\n\n for (const [pattern, ruleId] of processPatterns) {\n if (processList.includes(pattern)) {\n results.push({\n type: 'fail',\n rule: ruleId,\n check: 'processes',\n message: `Suspicious process running: ${pattern}`,\n details: 'This may indicate an active compromise',\n });\n }\n }\n\n // Check macOS persistence mechanisms\n if (os === 'darwin') {\n checkMacOSPersistence(rules, results);\n }\n\n return results;\n}\n\nfunction getProcessList(os: string): string {\n if (os === 'darwin' || os === 'linux') {\n return runCommand('ps aux 2>/dev/null');\n } else if (os === 'win32') {\n return runCommand('tasklist /v 2>nul');\n }\n return '';\n}\n\nfunction checkMacOSPersistence(rules: Rule[], results: CheckResult[]): void {\n const launchDirs = [\n `${process.env.HOME}/Library/LaunchAgents`,\n '/Library/LaunchAgents',\n '/Library/LaunchDaemons',\n ];\n\n // Collect all IOC strings to search for\n const searchStrings = new Map<string, string>();\n for (const rule of rules) {\n for (const s of rule.ioc.strings ?? []) {\n searchStrings.set(s, rule.id);\n }\n for (const domain of rule.ioc.domains ?? []) {\n searchStrings.set(domain, rule.id);\n }\n for (const ip of rule.ioc.ips ?? []) {\n searchStrings.set(ip, rule.id);\n }\n }\n\n const existingDirs = launchDirs.filter(dirExists);\n if (existingDirs.length === 0 || searchStrings.size === 0) return;\n\n const pattern = Array.from(searchStrings.keys()).join('|');\n const hits = runCommand(\n `grep -rlE \"${pattern}\" ${existingDirs.map((d) => `\"${d}\"`).join(' ')} 2>/dev/null`\n );\n\n if (hits) {\n for (const file of hits.split('\\n').filter(Boolean)) {\n // Find which rule matched\n const content = runCommand(`cat \"${file}\" 2>/dev/null`);\n let matchedRule = 'unknown';\n for (const [s, ruleId] of searchStrings) {\n if (content.includes(s)) { matchedRule = ruleId; break; }\n }\n results.push({\n type: 'fail',\n rule: matchedRule,\n check: 'processes',\n message: `Suspicious LaunchAgent/Daemon: ${file}`,\n details: 'May indicate malware persistence',\n });\n }\n }\n}\n","import { join } from 'node:path';\nimport { homedir } from 'node:os';\nimport type { Rule, CheckResult } from '../types.js';\nimport { dirExists, runCommand } from '../utils.js';\n\ninterface CacheLocation {\n name: string;\n dir: string;\n cleanCmd: string;\n}\n\nfunction detectCaches(): CacheLocation[] {\n const home = homedir();\n const caches: CacheLocation[] = [];\n\n // npm\n const npmCache = runCommand('npm config get cache') || join(home, '.npm');\n if (dirExists(npmCache)) {\n caches.push({ name: 'npm', dir: npmCache, cleanCmd: 'npm cache clean --force' });\n }\n\n // pnpm\n const pnpmStore = runCommand('pnpm store path 2>/dev/null');\n if (pnpmStore && dirExists(pnpmStore)) {\n caches.push({ name: 'pnpm', dir: pnpmStore, cleanCmd: 'pnpm store prune' });\n }\n\n // yarn v1\n const yarnCache = runCommand('yarn cache dir 2>/dev/null');\n if (yarnCache && dirExists(yarnCache)) {\n caches.push({ name: 'yarn', dir: yarnCache, cleanCmd: 'yarn cache clean' });\n }\n\n // yarn v2+ (berry) — project-local .yarn/cache\n const yarnBerryCache = join(process.cwd(), '.yarn', 'cache');\n if (dirExists(yarnBerryCache)) {\n caches.push({ name: 'yarn-berry', dir: yarnBerryCache, cleanCmd: 'yarn cache clean --all' });\n }\n\n // bun\n const bunCache = join(home, '.bun', 'install', 'cache');\n if (dirExists(bunCache)) {\n caches.push({ name: 'bun', dir: bunCache, cleanCmd: 'bun pm cache rm' });\n }\n\n return caches;\n}\n\n/**\n * Scan all package manager caches for malicious packages.\n * Supports: npm, pnpm, yarn (v1 & v2+), bun.\n */\nexport function checkCache(rules: Rule[]): CheckResult[] {\n const results: CheckResult[] = [];\n const caches = detectCaches();\n\n if (caches.length === 0) return results;\n\n // Collect all malicious package names and compromised tarballs\n const maliciousPkgs = new Map<string, string>();\n const compromisedTarballs = new Map<string, string>();\n\n for (const rule of rules) {\n for (const pkg of Object.keys(rule.packages.malicious)) {\n maliciousPkgs.set(pkg, rule.id);\n }\n for (const [pkg, versions] of Object.entries(rule.packages.compromised)) {\n for (const ver of versions) {\n compromisedTarballs.set(`${pkg}-${ver}.tgz`, rule.id);\n }\n }\n }\n\n if (maliciousPkgs.size === 0 && compromisedTarballs.size === 0) return results;\n\n for (const cache of caches) {\n scanCacheDir(cache, maliciousPkgs, compromisedTarballs, results);\n }\n\n return results;\n}\n\nfunction scanCacheDir(\n cache: CacheLocation,\n maliciousPkgs: Map<string, string>,\n compromisedTarballs: Map<string, string>,\n results: CheckResult[]\n): void {\n // Find malicious package directories\n if (maliciousPkgs.size > 0) {\n const nameArgs = Array.from(maliciousPkgs.keys())\n .map((n) => `-name \"${n}\"`)\n .join(' -o ');\n const found = runCommand(\n `find \"${cache.dir}\" -maxdepth 4 -type d \\\\( ${nameArgs} \\\\) 2>/dev/null`\n );\n if (found) {\n for (const line of found.split('\\n').filter(Boolean)) {\n const name = line.split('/').pop() || '';\n const ruleId = maliciousPkgs.get(name);\n if (ruleId) {\n results.push({\n type: 'fail',\n rule: ruleId,\n check: 'cache',\n message: `Malicious package \"${name}\" found in ${cache.name} cache`,\n details: `Run: ${cache.cleanCmd}`,\n });\n }\n }\n }\n }\n\n // Find compromised tarballs\n if (compromisedTarballs.size > 0) {\n const nameArgs = Array.from(compromisedTarballs.keys())\n .map((n) => `-name \"${n}\"`)\n .join(' -o ');\n const found = runCommand(\n `find \"${cache.dir}\" -maxdepth 4 -type f \\\\( ${nameArgs} \\\\) 2>/dev/null`\n );\n if (found) {\n for (const line of found.split('\\n').filter(Boolean)) {\n const name = line.split('/').pop() || '';\n const ruleId = compromisedTarballs.get(name);\n if (ruleId) {\n results.push({\n type: 'warn',\n rule: ruleId,\n check: 'cache',\n message: `Compromised tarball ${name} in ${cache.name} cache`,\n details: `Run: ${cache.cleanCmd}`,\n });\n }\n }\n }\n }\n}\n","import type { Rule, CheckResult, ScanSummary } from './types.js';\nimport { checkPackages } from './checks/packages.js';\nimport { checkFiles } from './checks/files.js';\nimport { checkNetwork } from './checks/network.js';\nimport { checkProcesses } from './checks/processes.js';\nimport { checkCache } from './checks/cache.js';\nimport * as ui from './ui.js';\n\ninterface ScanOptions {\n rules: Rule[];\n projectDirs: string[];\n ci: boolean;\n}\n\ninterface CheckDef {\n title: string;\n icon: string;\n passMessage: string;\n run: () => CheckResult[];\n}\n\nexport async function scan(options: ScanOptions): Promise<ScanSummary> {\n const { rules, projectDirs, ci } = options;\n const allResults: CheckResult[] = [];\n\n const checks: CheckDef[] = [\n {\n title: 'COMPROMISED PACKAGES',\n icon: '\\uD83D\\uDCE6',\n passMessage: `All ${projectDirs.length} projects clean — no compromised packages`,\n run: () => checkPackages(rules, projectDirs),\n },\n {\n title: 'MALWARE FILES',\n icon: '\\uD83D\\uDC80',\n passMessage: 'No malware artifacts found on disk',\n run: () => checkFiles(rules),\n },\n {\n title: 'NETWORK CONNECTIONS',\n icon: '\\uD83C\\uDF10',\n passMessage: 'No active C2 connections detected',\n run: () => checkNetwork(rules),\n },\n {\n title: 'SUSPICIOUS PROCESSES',\n icon: '\\u2699\\uFE0F ',\n passMessage: 'No suspicious processes detected',\n run: () => checkProcesses(rules),\n },\n {\n title: 'PACKAGE MANAGER CACHES',\n icon: '\\uD83D\\uDCC1',\n passMessage: 'All package manager caches are clean',\n run: () => checkCache(rules),\n },\n ];\n\n const totalChecks = checks.length;\n\n for (let i = 0; i < checks.length; i++) {\n const check = checks[i];\n\n if (!ci) ui.sectionHeader(i + 1, totalChecks, check.title, check.icon);\n if (!ci) ui.spinnerStart(`Running ${check.title.toLowerCase()} check...`);\n\n const results = check.run();\n allResults.push(...results);\n\n if (!ci) ui.spinnerStop();\n if (!ci) displayResults(results, check.passMessage);\n }\n\n return buildSummary(allResults, projectDirs.length, rules.length, totalChecks);\n}\n\nfunction displayResults(results: CheckResult[], passMessage: string): void {\n if (results.filter((r) => r.type === 'fail' || r.type === 'warn').length === 0) {\n ui.result('pass', passMessage);\n }\n for (const r of results) {\n ui.result(r.type, r.message);\n if (r.details) ui.resultDetail(r.details);\n }\n}\n\nfunction buildSummary(\n results: CheckResult[],\n projectsScanned: number,\n rulesChecked: number,\n totalChecks: number\n): ScanSummary {\n const compromisedProjects = new Set<string>();\n for (const r of results) {\n if (r.type === 'fail' && r.details) {\n const match = r.details.match(/— (.+)$/);\n if (match) compromisedProjects.add(match[1]);\n }\n }\n\n const failCount = results.filter((r) => r.type === 'fail').length;\n const warnCount = results.filter((r) => r.type === 'warn').length;\n\n return {\n projectsScanned,\n rulesChecked,\n totalChecks: results.length || totalChecks,\n passed: results.length === 0 ? totalChecks : results.length - failCount - warnCount,\n failed: failCount,\n warnings: warnCount,\n results,\n compromisedProjects: Array.from(compromisedProjects),\n };\n}\n"],"mappings":";;;AAAA,SAAS,qBAAqB;AAC9B,SAAS,SAAS,QAAAA,aAAY;;;ACD9B,SAAS,cAAc,aAAa,YAAY,gBAAgB;AAChE,SAAS,MAAM,eAAe;AAC9B,SAAS,UAAU,eAAe;AAClC,SAAS,gBAAgB;AACzB,SAAS,uBAAuB;AAKzB,SAAS,QAAgB;AAC9B,SAAO,SAAS;AAClB;AAQO,SAAS,SAAY,MAAwB;AAClD,MAAI;AACF,UAAM,UAAU,aAAa,MAAM,OAAO;AAC1C,WAAO,KAAK,MAAM,OAAO;AAAA,EAC3B,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAIO,SAAS,cAAc,aAAoC;AAChE,QAAM,MAAM,SAA+B,WAAW;AACtD,SAAO,KAAK,WAAW;AACzB;AAEO,SAAS,qBACd,SACA,aACS;AACT,MAAI,CAAC,QAAS,QAAO;AACrB,SAAO,YAAY,SAAS,OAAO;AACrC;AAIO,SAAS,WAAW,GAAmB;AAC5C,MAAIC,UAAS;AACb,MAAIA,QAAO,WAAW,GAAG,GAAG;AAC1B,IAAAA,UAAS,KAAK,QAAQ,GAAGA,QAAO,MAAM,CAAC,CAAC;AAAA,EAC1C;AACA,MAAIA,QAAO,SAAS,eAAe,GAAG;AACpC,IAAAA,UAASA,QAAO,QAAQ,iBAAiB,QAAQ,IAAI,eAAe,iBAAiB;AAAA,EACvF;AACA,MAAIA,QAAO,SAAS,QAAQ,GAAG;AAC7B,IAAAA,UAASA,QAAO,QAAQ,UAAU,QAAQ,IAAI,QAAQ,MAAM;AAAA,EAC9D;AACA,MAAIA,QAAO,SAAS,eAAe,GAAG;AACpC,IAAAA,UAASA,QAAO,QAAQ,iBAAiB,QAAQ,CAAC;AAAA,EACpD;AACA,SAAOA;AACT;AAIO,SAAS,aAAa,UAAoB,WAAW,GAAa;AACvE,QAAM,WAAwB,oBAAI,IAAI;AAEtC,WAAS,KAAK,KAAa,OAAqB;AAC9C,QAAI,QAAQ,SAAU;AAEtB,QAAI;AACF,YAAM,UAAU,YAAY,KAAK,EAAE,eAAe,KAAK,CAAC;AACxD,iBAAW,SAAS,SAAS;AAC3B,YAAI,CAAC,MAAM,YAAY,GAAG;AACxB,cAAI,MAAM,SAAS,kBAAkB,QAAQ,GAAG;AAC9C,qBAAS,IAAI,GAAG;AAAA,UAClB;AACA;AAAA,QACF;AAGA,cAAM,OAAO;AAAA,UACX;AAAA,UAAgB;AAAA,UAAQ;AAAA,UACxB;AAAA,UAAU;AAAA,UAAU;AAAA,UAAW;AAAA,QACjC;AACA,YAAI,KAAK,SAAS,MAAM,IAAI,EAAG;AAE/B,aAAK,KAAK,KAAK,MAAM,IAAI,GAAG,QAAQ,CAAC;AAAA,MACvC;AAAA,IACF,QAAQ;AAAA,IAER;AAAA,EACF;AAGA,aAAW,QAAQ,UAAU;AAC3B,QAAI,CAAC,WAAW,IAAI,EAAG;AACvB,QAAI,WAAW,KAAK,MAAM,cAAc,CAAC,GAAG;AAC1C,eAAS,IAAI,IAAI;AAAA,IACnB;AACA,SAAK,MAAM,CAAC;AAAA,EACd;AAEA,SAAO,MAAM,KAAK,QAAQ;AAC5B;AAIO,SAAS,uBAAiC;AAC/C,QAAM,OAAO,QAAQ;AACrB,QAAM,aAAa;AAAA,IACjB;AAAA,IAAW;AAAA,IAAa;AAAA,IAAY;AAAA,IACpC;AAAA,IAAa;AAAA,IAAO;AAAA,IAAQ;AAAA,IAC5B;AAAA,IAAS;AAAA,IAAS;AAAA,IAAO;AAAA,IAAQ;AAAA,IACjC;AAAA,IAAa;AAAA,IAAa;AAAA,IAAS;AAAA,IACnC;AAAA,IAAO;AAAA,IAAU;AAAA,EACnB;AACA,SAAO,WACJ,IAAI,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC,EACxB,OAAO,CAAC,MAAM,WAAW,CAAC,CAAC;AAChC;AAIO,SAAS,UAAU,UAA0B;AAClD,QAAM,QAAgB,CAAC;AAEvB,MAAI;AACF,UAAM,QAAQ,YAAY,QAAQ,EAAE,OAAO,CAAC,MAAM,EAAE,SAAS,OAAO,CAAC;AACrE,eAAW,QAAQ,OAAO;AACxB,YAAM,OAAO,SAAe,KAAK,UAAU,IAAI,CAAC;AAChD,UAAI,QAAQ,KAAK,MAAM,KAAK,UAAU;AACpC,cAAM,KAAK,IAAI;AAAA,MACjB;AAAA,IACF;AAAA,EACF,QAAQ;AAAA,EAER;AAGA,QAAM,KAAK,CAAC,GAAG,MAAM,EAAE,KAAK,cAAc,EAAE,IAAI,CAAC;AACjD,SAAO;AACT;AAIO,SAAS,UAAU,MAA4B;AACpD,QAAM,OAAmB;AAAA,IACvB,OAAO,CAAC;AAAA,IACR,KAAK;AAAA,IACL,MAAM;AAAA,IACN,MAAM;AAAA,IACN,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,SAAS;AAAA,EACX;AAEA,WAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;AACpC,UAAM,MAAM,KAAK,CAAC;AAClB,YAAQ,KAAK;AAAA,MACX,KAAK;AAAA,MACL,KAAK;AACH,aAAK,MAAM;AACX;AAAA,MACF,KAAK;AAAA,MACL,KAAK;AACH,aAAK,OAAO;AACZ;AAAA,MACF,KAAK;AACH,aAAK,KAAK;AACV,aAAK,MAAM;AACX;AAAA,MACF,KAAK;AAAA,MACL,KAAK;AACH,aAAK,OAAO;AACZ;AAAA,MACF,KAAK;AAAA,MACL,KAAK;AACH,aAAK,UAAU;AACf;AAAA,MACF,KAAK;AAAA,MACL,KAAK;AACH,YAAI,IAAI,IAAI,KAAK,QAAQ;AACvB,eAAK,MAAM,KAAK,KAAK,EAAE,CAAC,CAAC;AAAA,QAC3B;AACA;AAAA,MACF,KAAK;AAAA,MACL,KAAK;AACH,YAAI,IAAI,IAAI,KAAK,QAAQ;AACvB,eAAK,OAAO,QAAQ,KAAK,EAAE,CAAC,CAAC;AAAA,QAC/B;AACA;AAAA,IACJ;AAAA,EACF;AAEA,SAAO;AACT;AAIO,SAAS,WAAW,KAAqB;AAC9C,MAAI;AACF,WAAO,SAAS,KAAK,EAAE,UAAU,SAAS,SAAS,KAAO,OAAO,CAAC,QAAQ,QAAQ,MAAM,EAAE,CAAC,EAAE,KAAK;AAAA,EACpG,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAIO,SAAS,OAAO,UAAmC;AACxD,QAAM,KAAK,gBAAgB;AAAA,IACzB,OAAO,QAAQ;AAAA,IACf,QAAQ,QAAQ;AAAA,EAClB,CAAC;AACD,SAAO,IAAI,QAAQ,CAACC,aAAY;AAC9B,OAAG,SAAS,UAAU,CAAC,WAAW;AAChC,SAAG,MAAM;AACT,MAAAA,SAAQ,OAAO,KAAK,CAAC;AAAA,IACvB,CAAC;AAAA,EACH,CAAC;AACH;AAIO,SAAS,WAAW,MAAuB;AAChD,MAAI;AACF,WAAO,SAAS,IAAI,EAAE,OAAO;AAAA,EAC/B,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEO,SAAS,UAAU,MAAuB;AAC/C,MAAI;AACF,WAAO,SAAS,IAAI,EAAE,YAAY;AAAA,EACpC,QAAQ;AACN,WAAO;AAAA,EACT;AACF;;;AC3OA,IAAM,MAAM;AAEL,IAAM,IAAI;AAAA,EACf,KAAK,GAAG,GAAG;AAAA,EACX,OAAO,GAAG,GAAG;AAAA,EACb,QAAQ,GAAG,GAAG;AAAA,EACd,MAAM,GAAG,GAAG;AAAA,EACZ,OAAO,GAAG,GAAG;AAAA,EACb,KAAK,GAAG,GAAG;AAAA,EACX,MAAM,GAAG,GAAG;AAAA,EACZ,OAAO,GAAG,GAAG;AAAA,EACb,OAAO,GAAG,GAAG;AAAA,EACb,SAAS,GAAG,GAAG;AAAA,EACf,UAAU,GAAG,GAAG;AAAA,EAChB,QAAQ,GAAG,GAAG;AAChB;AAIA,IAAM,MAAM;AAAA,EACV,MAAM;AAAA,EACN,MAAM;AAAA,EACN,MAAM;AAAA,EACN,MAAM;AAAA,EACN,MAAM;AAAA,EACN,QAAQ;AAAA,EACR,OAAO;AAAA,EACP,OAAO;AAAA,EACP,MAAM;AAAA,EACN,KAAK;AAAA,EACL,MAAM;AAAA,EACN,OAAO;AAAA,EACP,QAAQ;AACV;AAIO,SAAS,OAAO,WAAyB;AAC9C,QAAM,IAAI,QAAQ,OAAO,MAAM,KAAK,QAAQ,MAAM;AAClD,IAAE,IAAI;AACN,IAAE,GAAG,EAAE,IAAI,yDAAyD,EAAE,KAAK;AAAA,CAAI;AAC/E,IAAE,GAAG,EAAE,IAAI,6DAA6D,EAAE,KAAK;AAAA,CAAI;AACnF,IAAE,GAAG,EAAE,IAAI,6DAA6D,EAAE,KAAK;AAAA,CAAI;AACnF,IAAE,GAAG,EAAE,IAAI,gEAAgE,EAAE,KAAK;AAAA,CAAI;AACtF,IAAE,GAAG,EAAE,IAAI,sCAAsC,EAAE,GAAG,SAAS,EAAE,KAAK;AAAA,CAAI;AAC1E,IAAE,IAAI;AACN,IAAE,KAAK,EAAE,KAAK,4CAA4C,EAAE,KAAK;AAAA,CAAI;AACrE,IAAE,KAAK,EAAE,GAAG,WAAW,SAAS,qCAAqC,EAAE,KAAK;AAAA,CAAI;AAChF,IAAE,IAAI;AACN,UAAQ;AACV;AAIO,SAAS,UAAgB;AAC9B,UAAQ,IAAI,GAAG,EAAE,GAAG,GAAG,SAAI,OAAO,EAAE,CAAC,GAAG,EAAE,KAAK,EAAE;AACnD;AAIO,SAAS,cAAc,KAAa,OAAe,OAAe,MAAoB;AAC3F,UAAQ,IAAI,EAAE;AACd,UAAQ,IAAI,GAAG,EAAE,MAAM,GAAG,EAAE,KAAK,GAAG,EAAE,IAAI,KAAK,IAAI,WAAW,GAAG,IAAI,KAAK,aAAQ,KAAK,KAAK,EAAE,KAAK,EAAE;AACrG,UAAQ;AACV;AAIO,SAAS,OAAO,MAAkB,KAAmB;AAC1D,QAAM,QAAoC;AAAA,IACxC,MAAM,IAAI;AAAA,IACV,MAAM,IAAI;AAAA,IACV,MAAM,IAAI;AAAA,IACV,MAAM,IAAI;AAAA,EACZ;AACA,QAAM,SAAqC;AAAA,IACzC,MAAM,EAAE;AAAA,IACR,MAAM,GAAG,EAAE,GAAG,GAAG,EAAE,IAAI;AAAA,IACvB,MAAM,EAAE;AAAA,IACR,MAAM,EAAE;AAAA,EACV;AACA,UAAQ,IAAI,MAAM,MAAM,IAAI,CAAC,IAAI,OAAO,IAAI,CAAC,GAAG,GAAG,GAAG,EAAE,KAAK,EAAE;AACjE;AAEO,SAAS,aAAa,KAAmB;AAC9C,UAAQ,IAAI,SAAS,EAAE,GAAG,UAAK,GAAG,GAAG,EAAE,KAAK,EAAE;AAChD;AAIA,IAAM,cAAc,CAAC,UAAK,UAAK,UAAK,UAAK,UAAK,UAAK,UAAK,UAAK,UAAK,QAAG;AAErE,IAAI,eAAsD;AAC1D,IAAI,eAAe;AAEZ,SAAS,aAAa,KAAmB;AAC9C,iBAAe;AACf,iBAAe,YAAY,MAAM;AAC/B,UAAM,QAAQ,YAAY,eAAe,YAAY,MAAM;AAC3D,YAAQ,OAAO,MAAM,QAAQ,EAAE,IAAI,GAAG,KAAK,GAAG,EAAE,KAAK,IAAI,EAAE,GAAG,GAAG,GAAG,GAAG,EAAE,KAAK,EAAE;AAChF;AAAA,EACF,GAAG,EAAE;AACP;AAEO,SAAS,cAAoB;AAClC,MAAI,cAAc;AAChB,kBAAc,YAAY;AAC1B,mBAAe;AACf,YAAQ,OAAO,MAAM,UAAU;AAAA,EACjC;AACF;AAoBO,IAAM,iBAAyC;AAAA,EACpD,UAAU,EAAE;AAAA,EACZ,MAAM,EAAE;AAAA,EACR,QAAQ,EAAE;AAAA,EACV,KAAK,EAAE;AACT;AAEO,SAAS,cAAc,OAAqB;AACjD,UAAQ,IAAI,EAAE;AACd,UAAQ,IAAI,KAAK,EAAE,KAAK,2BAA2B,MAAM,MAAM,KAAK,EAAE,KAAK,EAAE;AAC7E,UAAQ,IAAI,EAAE;AAEd,aAAW,QAAQ,OAAO;AACxB,UAAM,KAAK,eAAe,KAAK,QAAQ,KAAK,EAAE;AAC9C,UAAM,WACJ,OAAO,KAAK,KAAK,SAAS,WAAW,EAAE,SACvC,OAAO,KAAK,KAAK,SAAS,SAAS,EAAE;AACvC,YAAQ;AAAA,MACN,MAAM,EAAE,GAAG,SAAI,EAAE,KAAK,IAAI,EAAE,KAAK,GAAG,KAAK,GAAG,OAAO,EAAE,CAAC,GAAG,EAAE,KAAK,IAAI,EAAE,GAAG,KAAK,SAAS,OAAO,EAAE,CAAC,GAAG,EAAE,KAAK,IAAI,EAAE,GAAG,GAAG,KAAK,IAAI,GAAG,EAAE,KAAK,KAAK,EAAE,GAAG,IAAI,QAAQ,SAAS,EAAE,KAAK;AAAA,IAClL;AACA,YAAQ,IAAI,QAAQ,EAAE,GAAG,GAAG,KAAK,WAAW,GAAG,EAAE,KAAK,EAAE;AAAA,EAC1D;AACA,UAAQ,IAAI,EAAE;AAChB;AAIO,SAAS,aAAa,SAA4B;AACvD,UAAQ,IAAI,EAAE;AACd,UAAQ,IAAI,GAAG,EAAE,IAAI,GAAG,SAAI,OAAO,EAAE,CAAC,GAAG,EAAE,KAAK,EAAE;AAClD,UAAQ,IAAI,KAAK,IAAI,MAAM,IAAI,EAAE,KAAK,GAAG,EAAE,IAAI,gBAAgB,EAAE,KAAK,EAAE;AACxE,UAAQ,IAAI,GAAG,EAAE,IAAI,GAAG,SAAI,OAAO,EAAE,CAAC,GAAG,EAAE,KAAK,EAAE;AAClD,UAAQ,IAAI,EAAE;AACd,UAAQ,IAAI,MAAM,EAAE,GAAG,oBAAoB,EAAE,KAAK,KAAK,EAAE,KAAK,GAAG,QAAQ,eAAe,GAAG,EAAE,KAAK,EAAE;AACpG,UAAQ,IAAI,MAAM,EAAE,GAAG,iBAAiB,EAAE,KAAK,QAAQ,EAAE,KAAK,GAAG,QAAQ,YAAY,GAAG,EAAE,KAAK,EAAE;AACjG,UAAQ,IAAI,MAAM,EAAE,GAAG,gBAAgB,EAAE,KAAK,SAAS,EAAE,KAAK,GAAG,QAAQ,WAAW,GAAG,EAAE,KAAK,EAAE;AAChG,UAAQ,IAAI,MAAM,EAAE,KAAK,UAAU,EAAE,KAAK,eAAe,EAAE,KAAK,GAAG,QAAQ,MAAM,GAAG,EAAE,KAAK,EAAE;AAC7F,UAAQ,IAAI,MAAM,EAAE,MAAM,YAAY,EAAE,KAAK,aAAa,EAAE,MAAM,GAAG,QAAQ,QAAQ,GAAG,EAAE,KAAK,EAAE;AACjG,UAAQ,IAAI,MAAM,EAAE,GAAG,UAAU,EAAE,KAAK,eAAe,EAAE,GAAG,GAAG,QAAQ,MAAM,GAAG,EAAE,KAAK,EAAE;AACzF,UAAQ,IAAI,EAAE;AACd,UAAQ;AAER,MAAI,QAAQ,SAAS,GAAG;AACtB,YAAQ,IAAI,EAAE;AACd,YAAQ,IAAI,MAAM,EAAE,KAAK,GAAG,EAAE,KAAK,GAAG,EAAE,IAAI,0CAAgC,EAAE,KAAK,EAAE;AACrF,YAAQ,IAAI,EAAE;AACd,YAAQ,IAAI,MAAM,EAAE,GAAG,GAAG,EAAE,IAAI,8BAA8B,EAAE,KAAK,EAAE;AACvE,YAAQ,IAAI,EAAE;AACd,YAAQ,IAAI,MAAM,EAAE,GAAG,KAAK,EAAE,KAAK,8BAA8B;AACjE,YAAQ,IAAI,MAAM,EAAE,GAAG,KAAK,EAAE,KAAK,qDAAqD;AACxF,YAAQ,IAAI,MAAM,EAAE,GAAG,KAAK,EAAE,KAAK,iCAAiC,EAAE,KAAK,2BAA2B,EAAE,KAAK,EAAE;AAC/G,YAAQ,IAAI,MAAM,EAAE,GAAG,KAAK,EAAE,KAAK,qBAAqB,EAAE,KAAK,0BAA0B,EAAE,KAAK,EAAE;AAClG,YAAQ,IAAI,MAAM,EAAE,GAAG,KAAK,EAAE,KAAK,yDAAyD;AAC5F,YAAQ,IAAI,MAAM,EAAE,GAAG,KAAK,EAAE,KAAK,qDAAqD;AACxF,YAAQ,IAAI,EAAE;AAEd,QAAI,QAAQ,oBAAoB,SAAS,GAAG;AAC1C,cAAQ,IAAI,MAAM,EAAE,GAAG,GAAG,EAAE,IAAI,wBAAwB,EAAE,KAAK,EAAE;AACjE,iBAAW,QAAQ,QAAQ,qBAAqB;AAC9C,gBAAQ,IAAI,SAAS,EAAE,GAAG,GAAG,IAAI,KAAK,IAAI,IAAI,GAAG,EAAE,KAAK,EAAE;AAAA,MAC5D;AACA,cAAQ,IAAI,EAAE;AAAA,IAChB;AAGA,UAAM,eAAe,oBAAI,IAA2B;AACpD,eAAW,KAAK,QAAQ,QAAQ,OAAO,CAACC,OAAMA,GAAE,SAAS,MAAM,GAAG;AAChE,YAAM,MAAM,aAAa,IAAI,EAAE,IAAI,KAAK,CAAC;AACzC,UAAI,KAAK,CAAC;AACV,mBAAa,IAAI,EAAE,MAAM,GAAG;AAAA,IAC9B;AACA,eAAW,CAAC,MAAM,OAAO,KAAK,cAAc;AAC1C,cAAQ,IAAI,MAAM,EAAE,GAAG,GAAG,EAAE,IAAI,GAAG,IAAI,IAAI,EAAE,KAAK,EAAE;AACpD,iBAAW,KAAK,SAAS;AACvB,gBAAQ,IAAI,SAAS,EAAE,GAAG,UAAK,EAAE,OAAO,GAAG,EAAE,KAAK,EAAE;AACpD,YAAI,EAAE,QAAS,SAAQ,IAAI,WAAW,EAAE,GAAG,GAAG,EAAE,OAAO,GAAG,EAAE,KAAK,EAAE;AAAA,MACrE;AACA,cAAQ,IAAI,EAAE;AAAA,IAChB;AAAA,EACF,WAAW,QAAQ,WAAW,GAAG;AAC/B,YAAQ,IAAI,EAAE;AACd,YAAQ,IAAI,MAAM,EAAE,QAAQ,GAAG,EAAE,KAAK,GAAG,EAAE,IAAI,+DAAgD,EAAE,KAAK,EAAE;AACxG,YAAQ,IAAI,EAAE;AACd,YAAQ,IAAI,MAAM,EAAE,MAAM,2DAA2D,EAAE,KAAK,EAAE;AAC9F,YAAQ,IAAI,EAAE;AAAA,EAChB,OAAO;AACL,YAAQ,IAAI,EAAE;AACd,YAAQ,IAAI,MAAM,EAAE,OAAO,GAAG,EAAE,KAAK,GAAG,EAAE,IAAI,KAAK,IAAI,KAAK,4CAAuC,IAAI,KAAK,KAAK,EAAE,KAAK,EAAE;AAC1H,YAAQ,IAAI,EAAE;AACd,YAAQ,IAAI,MAAM,EAAE,KAAK,iEAAiE,EAAE,KAAK,EAAE;AACnG,YAAQ,IAAI,EAAE;AACd,YAAQ,IAAI,MAAM,EAAE,GAAG,mBAAmB,EAAE,KAAK,EAAE;AACnD,YAAQ,IAAI,MAAM,EAAE,IAAI,SAAI,EAAE,KAAK,6CAA6C;AAChF,YAAQ,IAAI,MAAM,EAAE,IAAI,SAAI,EAAE,KAAK,qCAAqC;AACxE,YAAQ,IAAI,MAAM,EAAE,IAAI,SAAI,EAAE,KAAK,0CAA0C;AAC7E,YAAQ,IAAI,MAAM,EAAE,IAAI,SAAI,EAAE,KAAK,mDAAmD;AACtF,YAAQ,IAAI,EAAE;AAAA,EAChB;AAEA,UAAQ;AACR,UAAQ,IAAI,EAAE;AACd,UAAQ,IAAI,MAAM,EAAE,GAAG,sBAAqB,oBAAI,KAAK,GAAE,YAAY,CAAC,GAAG,EAAE,KAAK,EAAE;AAChF,UAAQ,IAAI,MAAM,EAAE,GAAG,8CAA8C,EAAE,KAAK,EAAE;AAC9E,UAAQ,IAAI,EAAE;AAChB;;;AC9OA,SAAS,QAAAC,aAAY;AACrB,SAAS,gBAAAC,qBAAoB;AAItB,SAAS,cACd,OACA,aACe;AACf,QAAM,UAAyB,CAAC;AAEhC,aAAW,OAAO,aAAa;AAE7B,UAAM,gBAAgB,cAAc,GAAG;AAEvC,eAAW,QAAQ,OAAO;AAExB,iBAAW,CAAC,KAAK,WAAW,KAAK,OAAO,QAAQ,KAAK,SAAS,WAAW,GAAG;AAC1E,cAAM,UAAU,cAAcC,MAAK,KAAK,gBAAgB,KAAK,cAAc,CAAC;AAC5E,YAAI,WAAW,qBAAqB,SAAS,WAAW,GAAG;AACzD,kBAAQ,KAAK;AAAA,YACX,MAAM;AAAA,YACN,MAAM,KAAK;AAAA,YACX,OAAO;AAAA,YACP,SAAS,GAAG,GAAG,IAAI,OAAO;AAAA,YAC1B,SAAS,GAAG,KAAK,IAAI,WAAM,GAAG;AAAA,UAChC,CAAC;AAAA,QACH;AAAA,MACF;AAGA,iBAAW,CAAC,GAAG,KAAK,OAAO,QAAQ,KAAK,SAAS,SAAS,GAAG;AAC3D,cAAM,SAASA,MAAK,KAAK,gBAAgB,GAAG;AAC5C,YAAI,UAAU,MAAM,GAAG;AACrB,gBAAM,UAAU,cAAcA,MAAK,QAAQ,cAAc,CAAC;AAC1D,kBAAQ,KAAK;AAAA,YACX,MAAM;AAAA,YACN,MAAM,KAAK;AAAA,YACX,OAAO;AAAA,YACP,SAAS,qBAAqB,GAAG,GAAG,UAAU,IAAI,OAAO,KAAK,EAAE;AAAA,YAChE,SAAS,GAAG,KAAK,IAAI,WAAM,GAAG;AAAA,UAChC,CAAC;AAAA,QACH;AAAA,MACF;AAGA,4BAAsB,eAAe,KAAK,MAAM,OAAO;AAAA,IACzD;AAAA,EACF;AAEA,SAAO;AACT;AAEA,SAAS,cAAc,KAAkC;AACvD,QAAM,QAAQ,oBAAI,IAAoB;AAEtC,QAAM,YAAY;AAAA,IAChB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA;AAAA,IACA;AAAA;AAAA,EACF;AACA,aAAW,QAAQ,WAAW;AAC5B,QAAI;AAEF,YAAM,WAAW,SAAS,cAAc,WAAW;AACnD,YAAM,IAAI,MAAMC,cAAaD,MAAK,KAAK,IAAI,GAAG,QAAQ,CAAC;AAAA,IACzD,QAAQ;AAAA,IAER;AAAA,EACF;AACA,SAAO;AACT;AAEA,SAAS,sBACP,eACA,KACA,MACA,SACM;AACN,aAAW,CAAC,UAAU,OAAO,KAAK,eAAe;AAE/C,eAAW,OAAO,OAAO,KAAK,KAAK,SAAS,SAAS,GAAG;AACtD,UAAI,QAAQ,SAAS,GAAG,GAAG;AACzB,gBAAQ,KAAK;AAAA,UACX,MAAM;AAAA,UACN,MAAM,KAAK;AAAA,UACX,OAAO;AAAA,UACP,SAAS,GAAG,QAAQ,kCAAkC,GAAG;AAAA,UACzD,SAAS,GAAG,KAAK,IAAI,WAAM,GAAG;AAAA,QAChC,CAAC;AAAA,MACH;AAAA,IACF;AAGA,eAAW,CAAC,KAAK,QAAQ,KAAK,OAAO,QAAQ,KAAK,SAAS,WAAW,GAAG;AACvE,iBAAW,OAAO,UAAU;AAE1B,cAAM,OAAO;AAAA,UACX,IAAI,GAAG,OAAO,GAAG;AAAA;AAAA,UACjB,GAAG,GAAG,IAAI,GAAG;AAAA;AAAA,UACb,IAAI,GAAG,MAAM,GAAG;AAAA;AAAA,QAClB;AACA,YAAI,KAAK,KAAK,CAAC,MAAM,QAAQ,SAAS,CAAC,CAAC,GAAG;AACzC,kBAAQ,KAAK;AAAA,YACX,MAAM;AAAA,YACN,MAAM,KAAK;AAAA,YACX,OAAO;AAAA,YACP,SAAS,GAAG,QAAQ,kBAAkB,GAAG,IAAI,GAAG;AAAA,YAChD,SAAS,GAAG,KAAK,IAAI,WAAM,GAAG;AAAA,UAChC,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;;;AC7GO,SAAS,WAAW,OAA8B;AACvD,QAAM,UAAyB,CAAC;AAChC,QAAM,KAAK,MAAM;AAEjB,aAAW,QAAQ,OAAO;AACxB,UAAM,YAAY,KAAK,IAAI,QAAQ,EAAE;AACrC,QAAI,CAAC,aAAa,UAAU,WAAW,EAAG;AAE1C,eAAW,WAAW,WAAW;AAC/B,YAAM,OAAO,WAAW,OAAO;AAC/B,UAAI,WAAW,IAAI,GAAG;AACpB,gBAAQ,KAAK;AAAA,UACX,MAAM;AAAA,UACN,MAAM,KAAK;AAAA,UACX,OAAO;AAAA,UACP,SAAS,2BAA2B,IAAI;AAAA,UACxC,SAAS,KAAK;AAAA,QAChB,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;;;AC9BA,SAAS,gBAAAE,qBAAoB;AAOtB,SAAS,aAAa,OAA8B;AACzD,QAAM,UAAyB,CAAC;AAChC,QAAM,KAAK,MAAM;AAGjB,QAAM,SAAS,oBAAI,IAAY;AAC/B,QAAM,aAAa,oBAAI,IAAY;AACnC,QAAM,YAAY,oBAAI,IAAoB;AAE1C,aAAW,QAAQ,OAAO;AACxB,eAAW,MAAM,KAAK,IAAI,OAAO,CAAC,GAAG;AACnC,aAAO,IAAI,EAAE;AACb,gBAAU,IAAI,IAAI,KAAK,EAAE;AAAA,IAC3B;AACA,eAAW,UAAU,KAAK,IAAI,WAAW,CAAC,GAAG;AAC3C,iBAAW,IAAI,MAAM;AACrB,gBAAU,IAAI,QAAQ,KAAK,EAAE;AAAA,IAC/B;AAAA,EACF;AAEA,MAAI,OAAO,SAAS,KAAK,WAAW,SAAS,EAAG,QAAO;AAGvD,QAAM,cAAc,qBAAqB,EAAE;AAC3C,aAAW,MAAM,QAAQ;AACvB,QAAI,YAAY,SAAS,EAAE,GAAG;AAC5B,cAAQ,KAAK;AAAA,QACX,MAAM;AAAA,QACN,MAAM,UAAU,IAAI,EAAE,KAAK;AAAA,QAC3B,OAAO;AAAA,QACP,SAAS,+BAA+B,EAAE;AAAA,QAC1C,SAAS;AAAA,MACX,CAAC;AAAA,IACH;AAAA,EACF;AAEA,aAAW,UAAU,YAAY;AAC/B,QAAI,YAAY,SAAS,MAAM,GAAG;AAChC,cAAQ,KAAK;AAAA,QACX,MAAM;AAAA,QACN,MAAM,UAAU,IAAI,MAAM,KAAK;AAAA,QAC/B,OAAO;AAAA,QACP,SAAS,mCAAmC,MAAM;AAAA,QAClD,SAAS;AAAA,MACX,CAAC;AAAA,IACH;AAAA,EACF;AAGA,iBAAe,QAAQ,YAAY,WAAW,OAAO;AAErD,SAAO;AACT;AAEA,SAAS,qBAAqB,IAAoB;AAChD,MAAI,OAAO,YAAY,OAAO,SAAS;AACrC,WAAO,WAAW,sDAAsD;AAAA,EAC1E,WAAW,OAAO,SAAS;AACzB,WAAO,WAAW,aAAa;AAAA,EACjC;AACA,SAAO;AACT;AAEA,SAAS,eACP,KACA,SACA,WACA,SACM;AACN,MAAI;AACF,UAAM,QAAQC,cAAa,cAAc,OAAO;AAChD,eAAW,MAAM,KAAK;AACpB,UAAI,MAAM,SAAS,EAAE,GAAG;AACtB,gBAAQ,KAAK;AAAA,UACX,MAAM;AAAA,UACN,MAAM,UAAU,IAAI,EAAE,KAAK;AAAA,UAC3B,OAAO;AAAA,UACP,SAAS,SAAS,EAAE;AAAA,QACtB,CAAC;AAAA,MACH;AAAA,IACF;AACA,eAAW,UAAU,SAAS;AAC5B,UAAI,MAAM,SAAS,MAAM,GAAG;AAC1B,gBAAQ,KAAK;AAAA,UACX,MAAM;AAAA,UACN,MAAM,UAAU,IAAI,MAAM,KAAK;AAAA,UAC/B,OAAO;AAAA,UACP,SAAS,aAAa,MAAM;AAAA,QAC9B,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF,QAAQ;AAAA,EAER;AACF;;;AC/FO,SAAS,eAAe,OAA8B;AAC3D,QAAM,UAAyB,CAAC;AAChC,QAAM,KAAK,MAAM;AAGjB,QAAM,kBAAkB,oBAAI,IAAoB;AAEhD,aAAW,QAAQ,OAAO;AACxB,eAAW,QAAQ,KAAK,IAAI,aAAa,CAAC,GAAG;AAC3C,sBAAgB,IAAI,MAAM,KAAK,EAAE;AAAA,IACnC;AAAA,EACF;AAEA,MAAI,gBAAgB,SAAS,EAAG,QAAO;AAGvC,QAAM,cAAc,eAAe,EAAE;AACrC,MAAI,CAAC,YAAa,QAAO;AAEzB,aAAW,CAAC,SAAS,MAAM,KAAK,iBAAiB;AAC/C,QAAI,YAAY,SAAS,OAAO,GAAG;AACjC,cAAQ,KAAK;AAAA,QACX,MAAM;AAAA,QACN,MAAM;AAAA,QACN,OAAO;AAAA,QACP,SAAS,+BAA+B,OAAO;AAAA,QAC/C,SAAS;AAAA,MACX,CAAC;AAAA,IACH;AAAA,EACF;AAGA,MAAI,OAAO,UAAU;AACnB,0BAAsB,OAAO,OAAO;AAAA,EACtC;AAEA,SAAO;AACT;AAEA,SAAS,eAAe,IAAoB;AAC1C,MAAI,OAAO,YAAY,OAAO,SAAS;AACrC,WAAO,WAAW,oBAAoB;AAAA,EACxC,WAAW,OAAO,SAAS;AACzB,WAAO,WAAW,mBAAmB;AAAA,EACvC;AACA,SAAO;AACT;AAEA,SAAS,sBAAsB,OAAe,SAA8B;AAC1E,QAAM,aAAa;AAAA,IACjB,GAAG,QAAQ,IAAI,IAAI;AAAA,IACnB;AAAA,IACA;AAAA,EACF;AAGA,QAAM,gBAAgB,oBAAI,IAAoB;AAC9C,aAAW,QAAQ,OAAO;AACxB,eAAW,KAAK,KAAK,IAAI,WAAW,CAAC,GAAG;AACtC,oBAAc,IAAI,GAAG,KAAK,EAAE;AAAA,IAC9B;AACA,eAAW,UAAU,KAAK,IAAI,WAAW,CAAC,GAAG;AAC3C,oBAAc,IAAI,QAAQ,KAAK,EAAE;AAAA,IACnC;AACA,eAAW,MAAM,KAAK,IAAI,OAAO,CAAC,GAAG;AACnC,oBAAc,IAAI,IAAI,KAAK,EAAE;AAAA,IAC/B;AAAA,EACF;AAEA,QAAM,eAAe,WAAW,OAAO,SAAS;AAChD,MAAI,aAAa,WAAW,KAAK,cAAc,SAAS,EAAG;AAE3D,QAAM,UAAU,MAAM,KAAK,cAAc,KAAK,CAAC,EAAE,KAAK,GAAG;AACzD,QAAM,OAAO;AAAA,IACX,cAAc,OAAO,KAAK,aAAa,IAAI,CAAC,MAAM,IAAI,CAAC,GAAG,EAAE,KAAK,GAAG,CAAC;AAAA,EACvE;AAEA,MAAI,MAAM;AACR,eAAW,QAAQ,KAAK,MAAM,IAAI,EAAE,OAAO,OAAO,GAAG;AAEnD,YAAM,UAAU,WAAW,QAAQ,IAAI,eAAe;AACtD,UAAI,cAAc;AAClB,iBAAW,CAAC,GAAG,MAAM,KAAK,eAAe;AACvC,YAAI,QAAQ,SAAS,CAAC,GAAG;AAAE,wBAAc;AAAQ;AAAA,QAAO;AAAA,MAC1D;AACA,cAAQ,KAAK;AAAA,QACX,MAAM;AAAA,QACN,MAAM;AAAA,QACN,OAAO;AAAA,QACP,SAAS,kCAAkC,IAAI;AAAA,QAC/C,SAAS;AAAA,MACX,CAAC;AAAA,IACH;AAAA,EACF;AACF;;;ACpGA,SAAS,QAAAC,aAAY;AACrB,SAAS,WAAAC,gBAAe;AAUxB,SAAS,eAAgC;AACvC,QAAM,OAAOC,SAAQ;AACrB,QAAM,SAA0B,CAAC;AAGjC,QAAM,WAAW,WAAW,sBAAsB,KAAKC,MAAK,MAAM,MAAM;AACxE,MAAI,UAAU,QAAQ,GAAG;AACvB,WAAO,KAAK,EAAE,MAAM,OAAO,KAAK,UAAU,UAAU,0BAA0B,CAAC;AAAA,EACjF;AAGA,QAAM,YAAY,WAAW,6BAA6B;AAC1D,MAAI,aAAa,UAAU,SAAS,GAAG;AACrC,WAAO,KAAK,EAAE,MAAM,QAAQ,KAAK,WAAW,UAAU,mBAAmB,CAAC;AAAA,EAC5E;AAGA,QAAM,YAAY,WAAW,4BAA4B;AACzD,MAAI,aAAa,UAAU,SAAS,GAAG;AACrC,WAAO,KAAK,EAAE,MAAM,QAAQ,KAAK,WAAW,UAAU,mBAAmB,CAAC;AAAA,EAC5E;AAGA,QAAM,iBAAiBA,MAAK,QAAQ,IAAI,GAAG,SAAS,OAAO;AAC3D,MAAI,UAAU,cAAc,GAAG;AAC7B,WAAO,KAAK,EAAE,MAAM,cAAc,KAAK,gBAAgB,UAAU,yBAAyB,CAAC;AAAA,EAC7F;AAGA,QAAM,WAAWA,MAAK,MAAM,QAAQ,WAAW,OAAO;AACtD,MAAI,UAAU,QAAQ,GAAG;AACvB,WAAO,KAAK,EAAE,MAAM,OAAO,KAAK,UAAU,UAAU,kBAAkB,CAAC;AAAA,EACzE;AAEA,SAAO;AACT;AAMO,SAAS,WAAW,OAA8B;AACvD,QAAM,UAAyB,CAAC;AAChC,QAAM,SAAS,aAAa;AAE5B,MAAI,OAAO,WAAW,EAAG,QAAO;AAGhC,QAAM,gBAAgB,oBAAI,IAAoB;AAC9C,QAAM,sBAAsB,oBAAI,IAAoB;AAEpD,aAAW,QAAQ,OAAO;AACxB,eAAW,OAAO,OAAO,KAAK,KAAK,SAAS,SAAS,GAAG;AACtD,oBAAc,IAAI,KAAK,KAAK,EAAE;AAAA,IAChC;AACA,eAAW,CAAC,KAAK,QAAQ,KAAK,OAAO,QAAQ,KAAK,SAAS,WAAW,GAAG;AACvE,iBAAW,OAAO,UAAU;AAC1B,4BAAoB,IAAI,GAAG,GAAG,IAAI,GAAG,QAAQ,KAAK,EAAE;AAAA,MACtD;AAAA,IACF;AAAA,EACF;AAEA,MAAI,cAAc,SAAS,KAAK,oBAAoB,SAAS,EAAG,QAAO;AAEvE,aAAW,SAAS,QAAQ;AAC1B,iBAAa,OAAO,eAAe,qBAAqB,OAAO;AAAA,EACjE;AAEA,SAAO;AACT;AAEA,SAAS,aACP,OACA,eACA,qBACA,SACM;AAEN,MAAI,cAAc,OAAO,GAAG;AAC1B,UAAM,WAAW,MAAM,KAAK,cAAc,KAAK,CAAC,EAC7C,IAAI,CAAC,MAAM,UAAU,CAAC,GAAG,EACzB,KAAK,MAAM;AACd,UAAM,QAAQ;AAAA,MACZ,SAAS,MAAM,GAAG,6BAA6B,QAAQ;AAAA,IACzD;AACA,QAAI,OAAO;AACT,iBAAW,QAAQ,MAAM,MAAM,IAAI,EAAE,OAAO,OAAO,GAAG;AACpD,cAAM,OAAO,KAAK,MAAM,GAAG,EAAE,IAAI,KAAK;AACtC,cAAM,SAAS,cAAc,IAAI,IAAI;AACrC,YAAI,QAAQ;AACV,kBAAQ,KAAK;AAAA,YACX,MAAM;AAAA,YACN,MAAM;AAAA,YACN,OAAO;AAAA,YACP,SAAS,sBAAsB,IAAI,cAAc,MAAM,IAAI;AAAA,YAC3D,SAAS,QAAQ,MAAM,QAAQ;AAAA,UACjC,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAGA,MAAI,oBAAoB,OAAO,GAAG;AAChC,UAAM,WAAW,MAAM,KAAK,oBAAoB,KAAK,CAAC,EACnD,IAAI,CAAC,MAAM,UAAU,CAAC,GAAG,EACzB,KAAK,MAAM;AACd,UAAM,QAAQ;AAAA,MACZ,SAAS,MAAM,GAAG,6BAA6B,QAAQ;AAAA,IACzD;AACA,QAAI,OAAO;AACT,iBAAW,QAAQ,MAAM,MAAM,IAAI,EAAE,OAAO,OAAO,GAAG;AACpD,cAAM,OAAO,KAAK,MAAM,GAAG,EAAE,IAAI,KAAK;AACtC,cAAM,SAAS,oBAAoB,IAAI,IAAI;AAC3C,YAAI,QAAQ;AACV,kBAAQ,KAAK;AAAA,YACX,MAAM;AAAA,YACN,MAAM;AAAA,YACN,OAAO;AAAA,YACP,SAAS,uBAAuB,IAAI,OAAO,MAAM,IAAI;AAAA,YACrD,SAAS,QAAQ,MAAM,QAAQ;AAAA,UACjC,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;;;ACpHA,eAAsB,KAAK,SAA4C;AACrE,QAAM,EAAE,OAAO,aAAa,GAAG,IAAI;AACnC,QAAM,aAA4B,CAAC;AAEnC,QAAM,SAAqB;AAAA,IACzB;AAAA,MACE,OAAO;AAAA,MACP,MAAM;AAAA,MACN,aAAa,OAAO,YAAY,MAAM;AAAA,MACtC,KAAK,MAAM,cAAc,OAAO,WAAW;AAAA,IAC7C;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,MAAM;AAAA,MACN,aAAa;AAAA,MACb,KAAK,MAAM,WAAW,KAAK;AAAA,IAC7B;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,MAAM;AAAA,MACN,aAAa;AAAA,MACb,KAAK,MAAM,aAAa,KAAK;AAAA,IAC/B;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,MAAM;AAAA,MACN,aAAa;AAAA,MACb,KAAK,MAAM,eAAe,KAAK;AAAA,IACjC;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,MAAM;AAAA,MACN,aAAa;AAAA,MACb,KAAK,MAAM,WAAW,KAAK;AAAA,IAC7B;AAAA,EACF;AAEA,QAAM,cAAc,OAAO;AAE3B,WAAS,IAAI,GAAG,IAAI,OAAO,QAAQ,KAAK;AACtC,UAAM,QAAQ,OAAO,CAAC;AAEtB,QAAI,CAAC,GAAI,CAAG,cAAc,IAAI,GAAG,aAAa,MAAM,OAAO,MAAM,IAAI;AACrE,QAAI,CAAC,GAAI,CAAG,aAAa,WAAW,MAAM,MAAM,YAAY,CAAC,WAAW;AAExE,UAAM,UAAU,MAAM,IAAI;AAC1B,eAAW,KAAK,GAAG,OAAO;AAE1B,QAAI,CAAC,GAAI,CAAG,YAAY;AACxB,QAAI,CAAC,GAAI,gBAAe,SAAS,MAAM,WAAW;AAAA,EACpD;AAEA,SAAO,aAAa,YAAY,YAAY,QAAQ,MAAM,QAAQ,WAAW;AAC/E;AAEA,SAAS,eAAe,SAAwB,aAA2B;AACzE,MAAI,QAAQ,OAAO,CAAC,MAAM,EAAE,SAAS,UAAU,EAAE,SAAS,MAAM,EAAE,WAAW,GAAG;AAC9E,IAAG,OAAO,QAAQ,WAAW;AAAA,EAC/B;AACA,aAAW,KAAK,SAAS;AACvB,IAAG,OAAO,EAAE,MAAM,EAAE,OAAO;AAC3B,QAAI,EAAE,QAAS,CAAG,aAAa,EAAE,OAAO;AAAA,EAC1C;AACF;AAEA,SAAS,aACP,SACA,iBACA,cACA,aACa;AACb,QAAM,sBAAsB,oBAAI,IAAY;AAC5C,aAAW,KAAK,SAAS;AACvB,QAAI,EAAE,SAAS,UAAU,EAAE,SAAS;AAClC,YAAM,QAAQ,EAAE,QAAQ,MAAM,SAAS;AACvC,UAAI,MAAO,qBAAoB,IAAI,MAAM,CAAC,CAAC;AAAA,IAC7C;AAAA,EACF;AAEA,QAAM,YAAY,QAAQ,OAAO,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE;AAC3D,QAAM,YAAY,QAAQ,OAAO,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE;AAE3D,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,aAAa,QAAQ,UAAU;AAAA,IAC/B,QAAQ,QAAQ,WAAW,IAAI,cAAc,QAAQ,SAAS,YAAY;AAAA,IAC1E,QAAQ;AAAA,IACR,UAAU;AAAA,IACV;AAAA,IACA,qBAAqB,MAAM,KAAK,mBAAmB;AAAA,EACrD;AACF;;;ARpGA,IAAM,aAAa,cAAc,YAAY,GAAG;AAChD,IAAM,YAAY,QAAQ,UAAU;AACpC,IAAM,YAAYC,MAAK,WAAW,MAAM,OAAO;AAE/C,IAAM,UAAU;AAEhB,IAAM,YAAY;AAAA,EACb,EAAE,KAAK,cAAiB,EAAE,KAAK;AAAA;AAAA,EAE/B,EAAE,MAAM,QAAW,EAAE,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAO1B,EAAE,MAAM,UAAa,EAAE,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAS5B,EAAE,MAAM,aAAgB,EAAE,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA,EAK/B,EAAE,MAAM,WAAc,EAAE,KAAK;AAAA;AAAA;AAAA;AAAA;AAMlC,eAAsB,IAAI,MAA+B;AACvD,QAAM,OAAO,UAAU,IAAI;AAG3B,MAAI,KAAK,SAAS;AAChB,YAAQ,IAAI,OAAO;AACnB,YAAQ,KAAK,CAAC;AAAA,EAChB;AAGA,MAAI,KAAK,MAAM;AACb,YAAQ,IAAI,SAAS;AACrB,YAAQ,KAAK,CAAC;AAAA,EAChB;AAGA,QAAM,WAAW,UAAU,SAAS;AAEpC,MAAI,SAAS,WAAW,GAAG;AACzB,YAAQ,MAAM,GAAM,EAAE,GAAG,qBAAqB,SAAS,GAAM,EAAE,KAAK,EAAE;AACtE,YAAQ,KAAK,CAAC;AAAA,EAChB;AAGA,MAAI,KAAK,MAAM;AACb,IAAG,OAAO,SAAS,MAAM;AACzB,IAAG,cAAc,QAAQ;AACzB,YAAQ,KAAK,CAAC;AAAA,EAChB;AAGA,MAAI;AACJ,MAAI,KAAK,MAAM,SAAS,GAAG;AACzB,oBAAgB,SAAS,OAAO,CAAC,MAAM,KAAK,MAAM,SAAS,EAAE,EAAE,CAAC;AAChE,QAAI,cAAc,WAAW,GAAG;AAC9B,cAAQ,MAAM,GAAM,EAAE,GAAG,8DAAiE,EAAE,KAAK,EAAE;AACnG,cAAQ,KAAK,CAAC;AAAA,IAChB;AAAA,EACF,WAAW,KAAK,OAAO,KAAK,IAAI;AAC9B,oBAAgB;AAAA,EAClB,OAAO;AAEL,IAAG,OAAO,SAAS,MAAM;AACzB,oBAAgB,MAAM,yBAAyB,QAAQ;AAAA,EACzD;AAEA,MAAI,CAAC,KAAK,OAAO,KAAK,OAAO,KAAK,MAAM,SAAS,IAAI;AACnD,IAAG,OAAO,cAAc,MAAM;AAAA,EAChC;AAGA,MAAI;AAEJ,MAAI,KAAK,MAAM;AACb,QAAI,CAAC,KAAK,GAAI,CAAG,aAAa,+BAA+B;AAC7D,kBAAc,aAAa,CAAC,KAAK,IAAI,CAAC;AACtC,QAAI,CAAC,KAAK,GAAI,CAAG,YAAY;AAAA,EAC/B,WAAW,KAAK,MAAM,KAAK,KAAK;AAE9B,QAAI,CAAC,KAAK,GAAI,CAAG,aAAa,+BAA+B;AAC7D,kBAAc,aAAa,CAAC,QAAQ,IAAI,CAAC,CAAC;AAC1C,QAAI,CAAC,KAAK,GAAI,CAAG,YAAY;AAAA,EAC/B,OAAO;AACL,kBAAc,MAAM,yBAAyB;AAAA,EAC/C;AAEA,MAAI,CAAC,KAAK,IAAI;AACZ,YAAQ,IAAI;AAAA,KAAW,EAAE,GAAG,YAAY,YAAY,MAAM,kBAAkB,cAAc,MAAM,YAAe,EAAE,KAAK,EAAE;AAAA,EAC1H;AAGA,QAAM,UAAU,MAAM,KAAK;AAAA,IACzB,OAAO;AAAA,IACP;AAAA,IACA,IAAI,KAAK;AAAA,EACX,CAAC;AAGD,MAAI,CAAC,KAAK,IAAI;AACZ,IAAG,aAAa,OAAO;AAAA,EACzB;AAGA,MAAI,QAAQ,SAAS,GAAG;AACtB,YAAQ,KAAK,CAAC;AAAA,EAChB,WAAW,QAAQ,WAAW,GAAG;AAC/B,YAAQ,KAAK,CAAC;AAAA,EAChB,OAAO;AACL,QAAI,KAAK,IAAI;AACX,cAAQ,IAAI,IAAI;AAAA,IAClB;AACA,YAAQ,KAAK,CAAC;AAAA,EAChB;AACF;AAIA,eAAe,yBAAyB,OAAgC;AACtE,UAAQ,IAAI,EAAE;AACd,UAAQ,IAAI,MAAS,EAAE,KAAK,0BAA6B,EAAE,KAAK,EAAE;AAClE,UAAQ,IAAI,EAAE;AACd,UAAQ,IAAI,MAAS,EAAE,IAAI,IAAO,EAAE,KAAK,KAAQ,EAAE,KAAK,gBAAgB,MAAM,MAAM,UAAa,EAAE,KAAK,EAAE;AAE1G,WAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACrC,UAAM,IAAI,MAAM,CAAC;AACjB,UAAM,KAAQ,eAAe,EAAE,QAAQ,KAAQ,EAAE;AACjD,YAAQ,IAAI,MAAS,EAAE,IAAI,GAAG,IAAI,CAAC,GAAM,EAAE,KAAK,KAAK,EAAE,IAAI,IAAI,EAAE,IAAI,EAAE,QAAQ,IAAO,EAAE,KAAK,EAAE;AAAA,EACjG;AAEA,UAAQ,IAAI,EAAE;AACd,QAAM,SAAS,MAAM,OAAO,MAAS,EAAE,MAAM,kDAAqD,EAAE,KAAK,EAAE;AAE3G,MAAI,CAAC,UAAU,WAAW,KAAK;AAC7B,WAAO;AAAA,EACT;AAEA,QAAM,UAAU,OAAO,MAAM,GAAG,EAAE,IAAI,CAAC,MAAM,SAAS,EAAE,KAAK,GAAG,EAAE,IAAI,CAAC;AACvE,QAAM,WAAW,QACd,OAAO,CAAC,MAAM,KAAK,KAAK,IAAI,MAAM,MAAM,EACxC,IAAI,CAAC,MAAM,MAAM,CAAC,CAAC;AAEtB,SAAO,SAAS,SAAS,IAAI,WAAW;AAC1C;AAEA,eAAe,2BAA8C;AAC3D,UAAQ,IAAI,EAAE;AACd,UAAQ,IAAI,MAAS,EAAE,KAAK,uBAA0B,EAAE,KAAK,EAAE;AAC/D,UAAQ,IAAI,EAAE;AACd,UAAQ,IAAI,MAAS,EAAE,IAAI,IAAO,EAAE,KAAK,qBAAqB;AAC9D,UAAQ,IAAI,MAAS,EAAE,IAAI,IAAO,EAAE,KAAK,8BAA8B;AACvE,UAAQ,IAAI,MAAS,EAAE,IAAI,IAAO,EAAE,KAAK,uBAAuB;AAChE,UAAQ,IAAI,EAAE;AAEd,QAAM,SAAS,MAAM,OAAO,MAAS,EAAE,MAAM,8BAAiC,EAAE,KAAK,EAAE;AAEvF,MAAI;AACJ,UAAQ,QAAQ;AAAA,IACd,KAAK;AACH,iBAAW,qBAAqB;AAChC,UAAI,SAAS,WAAW,GAAG;AACzB,gBAAQ,IAAI,MAAS,EAAE,GAAG,6DAAgE,EAAE,KAAK,EAAE;AACnG,mBAAW,CAAC,QAAQ,IAAI,CAAC;AAAA,MAC3B;AACA;AAAA,IACF,KAAK,KAAK;AACR,YAAM,aAAa,MAAM,OAAO,MAAS,EAAE,IAAI,eAAkB,EAAE,KAAK,EAAE;AAC1E,iBAAW,CAAC,WAAW,QAAQ,MAAM,QAAQ,IAAI,QAAQ,EAAE,CAAC;AAC5D;AAAA,IACF;AAAA,IACA;AACE,iBAAW,CAAC,QAAQ,IAAI,CAAC;AAAA,EAC7B;AAEA,UAAQ,IAAI,EAAE;AACd,EAAG,aAAa,+BAA+B;AAC/C,QAAM,WAAW,aAAa,QAAQ;AACtC,EAAG,YAAY;AAEf,UAAQ,IAAI,MAAS,EAAE,GAAG,SAAS,SAAS,MAAM,gBAAmB,EAAE,KAAK,EAAE;AAE9E,SAAO;AACT;AAIA,IAAM,QACJ,QAAQ,KAAK,CAAC,GAAG,SAAS,aAAa,KACvC,QAAQ,KAAK,CAAC,GAAG,SAAS,YAAY;AAExC,IAAI,OAAO;AACT,MAAI,QAAQ,KAAK,MAAM,CAAC,CAAC;AAC3B;","names":["join","result","resolve","r","join","readFileSync","join","readFileSync","readFileSync","readFileSync","join","homedir","homedir","join","join"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/args.ts","../src/rules.ts","../src/utils.ts","../src/prompt.ts","../src/ui.ts","../src/checks/packages.ts","../src/checks/files.ts","../src/checks/network.ts","../src/shell.ts","../src/checks/processes.ts","../src/checks/cache.ts","../src/scanner.ts"],"sourcesContent":["import { fileURLToPath } from 'node:url';\nimport { dirname, join } from 'node:path';\nimport type { Rule } from './types.js';\nimport { parseArgs } from './args.js';\nimport { loadRules } from './rules.js';\nimport { readJSON, findProjects, getCommonProjectDirs } from './utils.js';\nimport { prompt } from './prompt.js';\nimport * as ui from './ui.js';\nimport { scan } from './scanner.js';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\nconst RULES_DIR = join(__dirname, '..', 'rules');\nconst PKG_JSON_PATH = join(__dirname, '..', 'package.json');\n\nconst VERSION = readJSON<{ version: string }>(PKG_JSON_PATH)?.version ?? '0.0.0';\n\nconst HELP_TEXT = `\n${ui.c.white}supply-scan${ui.c.reset} — Universal npm supply chain attack scanner\n\n${ui.c.yellow}USAGE${ui.c.reset}\n npx supply-scan Interactive mode (default)\n npx supply-scan --all Scan all attacks, skip prompts\n npx supply-scan --rule axios-2026 Scan specific attack(s)\n npx supply-scan --list List all available rules\n npx supply-scan --ci CI mode (non-interactive)\n\n${ui.c.yellow}OPTIONS${ui.c.reset}\n -a, --all Scan all attacks (skip rule selection)\n -r, --rule <id> Scan specific rule (repeatable)\n -p, --path <dir> Scan specific directory\n -l, --list List all available rules\n --ci CI mode (non-interactive, exit codes only)\n -h, --help Show this help\n -v, --version Show version\n\n${ui.c.yellow}EXIT CODES${ui.c.reset}\n 0 All clear\n 1 Compromise detected\n 2 Warnings found\n\n${ui.c.yellow}EXAMPLES${ui.c.reset}\n npx supply-scan --path ~/projects/my-app\n npx supply-scan --rule axios-2026 --rule node-ipc-2022\n npx supply-scan --ci --all\n`;\n\nexport async function run(argv: string[]): Promise<number> {\n const opts = parseArgs(argv);\n\n // Handle --version\n if (opts.version) {\n console.log(VERSION);\n return 0;\n }\n\n // Handle --help\n if (opts.help) {\n console.log(HELP_TEXT);\n return 0;\n }\n\n // Load rules\n const allRules = loadRules(RULES_DIR);\n\n if (allRules.length === 0) {\n console.error(`${ui.c.red}No rules found in ${RULES_DIR}${ui.c.reset}`);\n return 1;\n }\n\n // Handle --list\n if (opts.list) {\n ui.banner(allRules.length, VERSION);\n ui.printRuleList(allRules);\n return 0;\n }\n\n // Filter rules if --rule specified\n let selectedRules: Rule[];\n if (opts.rules.length > 0) {\n selectedRules = allRules.filter((r) => opts.rules.includes(r.id));\n if (selectedRules.length === 0) {\n console.error(`${ui.c.red}No matching rules found. Use --list to see available rules.${ui.c.reset}`);\n return 1;\n }\n } else if (opts.all || opts.ci) {\n selectedRules = allRules;\n } else {\n // Interactive: show banner and rule selection\n ui.banner(allRules.length, VERSION);\n selectedRules = await interactiveRuleSelection(allRules);\n }\n\n if (!opts.ci && (opts.all || opts.rules.length > 0)) {\n ui.banner(selectedRules.length, VERSION);\n }\n\n // Determine scan directories\n let projectDirs: string[];\n\n if (opts.path) {\n projectDirs = discoverProjects([opts.path], opts.ci);\n } else if (opts.ci || opts.all) {\n projectDirs = discoverProjects([process.cwd()], opts.ci);\n } else {\n projectDirs = await interactivePathSelection();\n }\n\n if (!opts.ci) {\n console.log('');\n ui.info(`Scanning ${projectDirs.length} projects with ${selectedRules.length} rules...`);\n }\n\n // Run scan\n const summary = await scan({\n rules: selectedRules,\n projectDirs,\n ci: opts.ci,\n });\n\n // Print summary\n if (!opts.ci) {\n ui.printSummary(summary);\n }\n\n // Exit code\n if (summary.failed > 0) {\n return 1;\n } else if (summary.warnings > 0) {\n return 2;\n } else {\n if (opts.ci) {\n console.log('OK');\n }\n return 0;\n }\n}\n\nfunction discoverProjects(dirs: string[], ci: boolean): string[] {\n if (!ci) ui.spinnerStart('Searching for npm projects...');\n const projects = findProjects(dirs);\n if (!ci) {\n ui.spinnerStop();\n ui.success(`Found ${projects.length} projects`);\n }\n return projects;\n}\n\n// ─── Interactive Prompts ────────────────────────────────────────────\n\nasync function interactiveRuleSelection(rules: Rule[]): Promise<Rule[]> {\n console.log('');\n const selected = await ui.interactiveMultiSelect({\n message: 'Select attacks to scan:',\n items: rules.map((r) => ({\n label: r.name,\n value: r,\n hint: `${r.severity} ${r.date}`,\n })),\n allOption: { label: `All attacks (${rules.length} rules)` },\n });\n return selected.length > 0 ? selected : rules;\n}\n\nasync function interactivePathSelection(): Promise<string[]> {\n const choice = await ui.interactiveSingleSelect({\n message: 'Where should I scan?',\n items: [\n { label: 'Current directory', value: 'cwd' as const, hint: process.cwd() },\n { label: 'Common project directories', value: 'common' as const, hint: 'Desktop, Projects, dev...' },\n { label: 'Entire home directory', value: 'home' as const, hint: '(slower)' },\n { label: 'Enter a custom path', value: 'custom' as const },\n ],\n });\n\n let baseDirs: string[];\n switch (choice) {\n case 'common':\n baseDirs = getCommonProjectDirs();\n if (baseDirs.length === 0) {\n ui.info('No common directories found, scanning current directory...');\n baseDirs = [process.cwd()];\n } else {\n ui.info(`Scanning ${baseDirs.length} directories:`);\n for (const d of baseDirs.slice(0, 5)) {\n console.log(` ${ui.c.dim}${d}${ui.c.reset}`);\n }\n if (baseDirs.length > 5) console.log(` ${ui.c.dim}...and ${baseDirs.length - 5} more${ui.c.reset}`);\n }\n break;\n case 'home':\n baseDirs = [process.env.HOME || '/'];\n ui.info(`Scanning home directory (this may take a while)...`);\n break;\n case 'custom': {\n const customPath = await prompt(`\\n ${ui.c.cyan}Enter path:${ui.c.reset} `);\n baseDirs = [customPath.replace(/^~/, process.env.HOME || '')];\n break;\n }\n default:\n baseDirs = [process.cwd()];\n }\n\n console.log('');\n ui.spinnerStart('Searching for npm projects...');\n const projects = findProjects(baseDirs);\n ui.spinnerStop();\n ui.success(`Found ${projects.length} npm projects`);\n\n return projects;\n}\n\n// ─── Auto-run when executed as CLI ──────────────────────────────────\n\n// CLI entry — only runs when executed directly (not imported as library)\nconst isCLI =\n process.argv[1]?.endsWith('supply-scan') ||\n process.argv[1]?.endsWith('dist/index.js') ||\n process.argv[1]?.includes('/supply-scan/');\n\nif (isCLI) {\n run(process.argv.slice(2))\n .then((code) => process.exit(code))\n .catch((err) => {\n console.error(`${ui.c.red}Error: ${err instanceof Error ? err.message : err}${ui.c.reset}`);\n process.exit(1);\n });\n}\n","import { resolve } from 'node:path';\nimport type { CLIOptions } from './types.js';\n\nexport function parseArgs(argv: string[]): CLIOptions {\n const opts: CLIOptions = {\n rules: [],\n all: false,\n list: false,\n path: null,\n ci: false,\n help: false,\n version: false,\n };\n\n for (let i = 0; i < argv.length; i++) {\n const arg = argv[i];\n switch (arg) {\n case '--all':\n case '-a':\n opts.all = true;\n break;\n case '--list':\n case '-l':\n opts.list = true;\n break;\n case '--ci':\n opts.ci = true;\n opts.all = true;\n break;\n case '--help':\n case '-h':\n opts.help = true;\n break;\n case '--version':\n case '-v':\n opts.version = true;\n break;\n case '--rule':\n case '-r':\n if (i + 1 < argv.length) {\n opts.rules.push(argv[++i]);\n }\n break;\n case '--path':\n case '-p':\n if (i + 1 < argv.length) {\n opts.path = resolve(argv[++i]);\n }\n break;\n }\n }\n\n return opts;\n}\n","import { readdirSync } from 'node:fs';\nimport { join } from 'node:path';\nimport type { Rule } from './types.js';\nimport { readJSON } from './utils.js';\n\nfunction decodeB64(s: string): string {\n return Buffer.from(s, 'base64').toString('utf-8');\n}\n\nfunction decodeArray(arr?: string[]): string[] | undefined {\n return arr?.map(decodeB64);\n}\n\nfunction decodeRecord(rec?: Record<string, string[]>): Record<string, string[]> | undefined {\n if (!rec) return undefined;\n const result: Record<string, string[]> = {};\n for (const [key, vals] of Object.entries(rec)) {\n result[key] = vals.map(decodeB64);\n }\n return result;\n}\n\nfunction decodeRule(rule: Rule & { encoded?: boolean }): Rule {\n if (!rule.encoded || !rule.ioc) return rule;\n\n const ioc = rule.ioc;\n ioc.domains = decodeArray(ioc.domains);\n ioc.ips = decodeArray(ioc.ips);\n ioc.processes = decodeArray(ioc.processes);\n ioc.strings = decodeArray(ioc.strings);\n ioc.files = decodeRecord(ioc.files);\n\n return rule;\n}\n\nexport function loadRules(rulesDir: string): Rule[] {\n const rules: Rule[] = [];\n\n try {\n const files = readdirSync(rulesDir).filter((f) => f.endsWith('.json'));\n for (const file of files) {\n const rule = readJSON<Rule & { encoded?: boolean }>(join(rulesDir, file));\n if (rule && rule.id && rule.packages) {\n rules.push(decodeRule(rule));\n }\n }\n } catch {\n // Rules directory not found\n }\n\n rules.sort((a, b) => b.date.localeCompare(a.date));\n return rules;\n}\n","import { readFileSync, readdirSync, existsSync, statSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { platform, homedir } from 'node:os';\n\n// Re-export for test backward compatibility\nexport { parseArgs } from './args.js';\nexport { loadRules } from './rules.js';\n\nexport function escapeRegex(s: string): string {\n return s.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n}\n\nexport function getOS(): string {\n return platform();\n}\n\n// ─── JSON Reader ────────────────────────────────────────────────────\n\nexport function readJSON<T>(path: string): T | null {\n try {\n const content = readFileSync(path, 'utf-8');\n return JSON.parse(content) as T;\n } catch {\n return null;\n }\n}\n\n// ─── Version Matching ───────────────────────────────────────────────\n\nexport function getPkgVersion(pkgJsonPath: string): string | null {\n const pkg = readJSON<{ version?: string }>(pkgJsonPath);\n return pkg?.version ?? null;\n}\n\nexport function isVersionCompromised(\n version: string | null,\n badVersions: string[]\n): boolean {\n if (!version) return false;\n return badVersions.includes(version);\n}\n\n// ─── Path Expansion ─────────────────────────────────────────────────\n\nexport function expandPath(p: string): string {\n let result = p;\n if (result.startsWith('~')) {\n result = join(homedir(), result.slice(1));\n }\n if (result.includes('%PROGRAMDATA%')) {\n result = result.replace('%PROGRAMDATA%', process.env.PROGRAMDATA || 'C:\\\\ProgramData');\n }\n if (result.includes('%TEMP%')) {\n result = result.replace('%TEMP%', process.env.TEMP || '/tmp');\n }\n if (result.includes('%USERPROFILE%')) {\n result = result.replace('%USERPROFILE%', homedir());\n }\n return result;\n}\n\n// ─── Project Discovery ──────────────────────────────────────────────\n\nconst SKIP_DIRS = new Set([\n 'node_modules', '.git', 'bower_components',\n '.cache', '.Trash', 'Library', '.npm',\n]);\n\nexport function findProjects(baseDirs: string[], maxDepth = 8): string[] {\n const projects: Set<string> = new Set();\n\n function walk(dir: string, depth: number): void {\n if (depth > maxDepth) return;\n\n try {\n const entries = readdirSync(dir, { withFileTypes: true });\n for (const entry of entries) {\n if (!entry.isDirectory()) {\n if (entry.name === 'package.json' && depth > 0) {\n projects.add(dir);\n }\n continue;\n }\n if (SKIP_DIRS.has(entry.name)) continue;\n walk(join(dir, entry.name), depth + 1);\n }\n } catch {\n // Permission denied or broken symlink\n }\n }\n\n for (const base of baseDirs) {\n if (!existsSync(base)) continue;\n if (existsSync(join(base, 'package.json'))) {\n projects.add(base);\n }\n walk(base, 0);\n }\n\n return Array.from(projects);\n}\n\n// ─── Common Project Directories ─────────────────────────────────────\n\nexport function getCommonProjectDirs(): string[] {\n const home = homedir();\n const candidates = [\n 'Desktop', 'Documents', 'Projects', 'projects',\n 'Developer', 'dev', 'code', 'Code',\n 'Sites', 'sites', 'www', 'Work', 'work',\n 'workspace', 'Workspace', 'repos', 'Repos',\n 'src', 'github', 'GitHub',\n ];\n return candidates\n .map((d) => join(home, d))\n .filter((d) => existsSync(d));\n}\n\n// ─── File Exists Check ──────────────────────────────────────────────\n\nexport function fileExists(path: string): boolean {\n try {\n return statSync(path).isFile();\n } catch {\n return false;\n }\n}\n\nexport function dirExists(path: string): boolean {\n try {\n return statSync(path).isDirectory();\n } catch {\n return false;\n }\n}\n","import { createInterface } from 'node:readline';\n\nexport function prompt(question: string): Promise<string> {\n const rl = createInterface({\n input: process.stdin,\n output: process.stdout,\n });\n return new Promise((resolve) => {\n rl.question(question, (answer) => {\n rl.close();\n resolve(answer.trim());\n });\n });\n}\n","import { type ResultType, type CheckResult, type ScanSummary, type Rule } from './types.js';\n\n// ─── Terminal Detection ─────────────────────────────────────────────\n\nconst isTTY = !!process.stdout.isTTY;\nconst noColor = !!process.env.NO_COLOR || process.env.TERM === 'dumb';\nconst hasTruecolor = isTTY && !noColor && (\n process.env.COLORTERM === 'truecolor' ||\n process.env.COLORTERM === '24bit' ||\n !!process.env.WT_SESSION ||\n process.env.TERM_PROGRAM === 'vscode' ||\n process.env.TERM_PROGRAM === 'iTerm.app'\n);\nconst hasColor = isTTY && !noColor;\n\nconst ESC = '\\x1b';\n\n// ─── Color Helpers ──────────────────────────────────────────────────\n\nfunction fg(r: number, g: number, b: number): string {\n if (hasTruecolor) return `${ESC}[38;2;${r};${g};${b}m`;\n if (hasColor) return `${ESC}[36m`;\n return '';\n}\n\nfunction bg(r: number, g: number, b: number): string {\n if (hasTruecolor) return `${ESC}[48;2;${r};${g};${b}m`;\n if (hasColor) return `${ESC}[44m`;\n return '';\n}\n\nexport const c = {\n red: hasColor ? `${ESC}[1;31m` : '',\n green: hasColor ? `${ESC}[1;32m` : '',\n yellow: hasColor ? `${ESC}[1;33m` : '',\n cyan: hasColor ? `${ESC}[1;36m` : '',\n white: hasColor ? `${ESC}[1;37m` : '',\n dim: hasColor ? `${ESC}[2m` : '',\n bold: hasColor ? `${ESC}[1m` : '',\n reset: hasColor ? `${ESC}[0m` : '',\n bgRed: hasColor ? `${ESC}[41m` : '',\n bgGreen: hasColor ? `${ESC}[42m` : '',\n bgYellow: hasColor ? `${ESC}[43m` : '',\n bgBlue: hasColor ? `${ESC}[44m` : '',\n reverse: hasColor ? `${ESC}[7m` : '',\n};\n\n// ─── ANSI Helpers ───────────────────────────────────────────────────\n\nfunction termW(): number {\n return process.stdout.columns || 80;\n}\n\nconst W = () => Math.min(termW(), 70);\n\nfunction line(char = '─'): string {\n return `${c.dim}${char.repeat(W())}${c.reset}`;\n}\n\n// ─── Severity ───────────────────────────────────────────────────────\n\nfunction severityBadge(sev: string): string {\n const label = sev.toUpperCase();\n if (!hasColor) return `[${label}]`;\n const colors: Record<string, [number, number, number]> = {\n critical: [220, 38, 38],\n high: [234, 179, 8],\n medium: [59, 130, 246],\n low: [107, 114, 128],\n };\n const col = colors[sev] || [107, 114, 128];\n return `${bg(col[0], col[1], col[2])}${c.white} ${label} ${c.reset}`;\n}\n\n// ─── Result Badge ───────────────────────────────────────────────────\n\nfunction badge(type: ResultType): string {\n if (!hasColor) return `[${type.toUpperCase()}]`;\n const badges: Record<ResultType, string> = {\n pass: `${bg(34, 197, 94)}${c.white} PASS ${c.reset}`,\n fail: `${bg(239, 68, 68)}${c.white} FAIL ${c.reset}`,\n warn: `${bg(234, 179, 8)}${ESC}[30m WARN ${c.reset}`,\n info: `${bg(107, 114, 128)}${c.white} INFO ${c.reset}`,\n };\n return badges[type];\n}\n\n// ─── Banner ─────────────────────────────────────────────────────────\n\nexport function banner(ruleCount: number, version = '0.0.0'): void {\n const art = [\n ' ┌─┐┬ ┬┌─┐┌─┐┬ ┬ ┬ ┌─┐┌─┐┌─┐┌┐┌',\n ' └─┐│ │├─┘├─┘│ └┬┘ └─┐│ ├─┤│││',\n ' └─┘└─┘┴ ┴ ┴─┘ ┴ └─┘└─┘┴ ┴┘└┘',\n ];\n\n const vBadge = `${bg(59, 130, 246)}${c.white} v${version} ${c.reset}`;\n\n console.log('');\n for (let i = 0; i < art.length; i++) {\n const t = art.length > 1 ? i / (art.length - 1) : 0;\n const r = Math.round(0 + 120 * t);\n const g = Math.round(200 - 120 * t);\n const b = Math.round(255);\n console.log(`${fg(r, g, b)}${art[i]}${c.reset}`);\n }\n console.log('');\n console.log(` ${c.white}Universal npm Supply Chain Attack Scanner${c.reset} ${vBadge}`);\n console.log(` ${c.dim}Detects ${ruleCount} known attacks · Zero dependencies${c.reset}`);\n console.log('');\n console.log(line());\n}\n\n// ─── Divider ────────────────────────────────────────────────────────\n\nexport function divider(): void {\n console.log(line());\n}\n\n// ─── Section Header ─────────────────────────────────────────────────\n\nexport function sectionHeader(num: number, total: number, title: string, icon: string): void {\n const w = W();\n const step = `${bg(59, 130, 246)}${c.white} ${num}/${total} ${c.reset}`;\n const text = ` ${icon} ${step} ${c.white}${c.bold}${title}${c.reset} `;\n const textLen = 4 + 4 + title.length + 4; // approximate\n const fill = Math.max(w - textLen - 2, 0);\n console.log('');\n console.log(`${c.dim}──${c.reset}${text}${c.dim}${'─'.repeat(fill)}${c.reset}`);\n}\n\n// ─── Result Formatters ──────────────────────────────────────────────\n\nexport function result(type: ResultType, msg: string): void {\n const color = type === 'fail' ? c.red : type === 'warn' ? c.yellow : type === 'pass' ? c.green : c.dim;\n console.log(` ${badge(type)} ${color}${msg}${c.reset}`);\n}\n\nexport function resultDetail(msg: string): void {\n console.log(` ${c.dim}↳${c.reset} ${c.red}${msg}${c.reset}`);\n}\n\n// ─── Terminal Helpers ────────────────────────────────────────────────\n\nfunction hideCursor(): void {\n if (isTTY) process.stdout.write(`${ESC}[?25l`);\n}\n\nfunction showCursor(): void {\n if (isTTY) process.stdout.write(`${ESC}[?25h`);\n}\n\nfunction teardownStdin(listener: (data: Buffer) => void): void {\n if (process.stdin.isTTY) process.stdin.setRawMode(false);\n process.stdin.pause();\n process.stdin.removeListener('data', listener);\n showCursor();\n}\n\n// ─── Spinner ────────────────────────────────────────────────────────\n\nconst FRAMES = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];\n\n// Pre-compute spinner colors (10 frames)\nconst SPIN_COLORS = FRAMES.map((_, i) => {\n const r = Math.round(80 + 40 * Math.sin(i * 0.6));\n const g = Math.round(180 + 20 * Math.cos(i * 0.6));\n return fg(r, g, 255);\n});\n\nlet spinTimer: ReturnType<typeof setInterval> | null = null;\nlet spinIdx = 0;\n\nexport function spinnerStart(msg: string): void {\n spinIdx = 0;\n hideCursor();\n spinTimer = setInterval(() => {\n const i = spinIdx % FRAMES.length;\n process.stdout.write(`\\r${ESC}[2K ${SPIN_COLORS[i]}${FRAMES[i]}${c.reset} ${c.dim}${msg}${c.reset}`);\n spinIdx++;\n }, 80);\n}\n\nexport function spinnerStop(): void {\n if (spinTimer) {\n clearInterval(spinTimer);\n spinTimer = null;\n process.stdout.write(`\\r${ESC}[2K`);\n showCursor();\n }\n}\n\n// ─── Progress Bar ───────────────────────────────────────────────────\n\nexport function progressBar(current: number, total: number, label: string): void {\n const barW = 20;\n const ratio = total > 0 ? current / total : 0;\n const pct = Math.round(ratio * 100);\n const filled = Math.round(ratio * barW);\n const name = label.length > 20 ? label.slice(0, 17) + '...' : label;\n const bar = `${c.green}${'█'.repeat(filled)}${c.reset}${c.dim}${'░'.repeat(barW - filled)}${c.reset}`;\n process.stdout.write(`\\r${ESC}[2K ${bar} ${c.white}${String(pct).padStart(3)}%${c.reset} ${c.dim}${name}${c.reset}`);\n}\n\nexport function progressClear(): void {\n process.stdout.write(`\\r${ESC}[2K`);\n}\n\n// ─── Info Line ──────────────────────────────────────────────────────\n\nexport function info(msg: string): void {\n console.log(` ${c.dim}${msg}${c.reset}`);\n}\n\nexport function success(msg: string): void {\n console.log(` ${c.green}✓${c.reset} ${msg}`);\n}\n\n// ─── Rule List ──────────────────────────────────────────────────────\n\nexport function printRuleList(rules: Rule[]): void {\n console.log('');\n console.log(` ${c.white}${c.bold}Available rules (${rules.length}):${c.reset}`);\n console.log('');\n\n for (const rule of rules) {\n const pkgCount = Object.keys(rule.packages.compromised).length + Object.keys(rule.packages.malicious).length;\n console.log(` ${severityBadge(rule.severity)} ${c.white}${rule.id}${c.reset} ${c.dim}· ${rule.date} · ${pkgCount} pkgs${c.reset}`);\n console.log(` ${c.dim}${rule.description}${c.reset}`);\n }\n console.log('');\n}\n\n// ─── Summary ────────────────────────────────────────────────────────\n\nexport function printSummary(summary: ScanSummary): void {\n\n console.log('');\n console.log(line('═'));\n console.log('');\n\n // Stats\n console.log(` ${c.dim}Projects scanned${c.reset} ${c.white}${c.bold}${summary.projectsScanned}${c.reset}`);\n console.log(` ${c.dim}Rules checked${c.reset} ${c.white}${c.bold}${summary.rulesChecked}${c.reset}`);\n console.log('');\n console.log(` ${badge('pass')} ${c.green}${summary.passed}${c.reset} ${badge('warn')} ${c.yellow}${summary.warnings}${c.reset} ${badge('fail')} ${c.red}${summary.failed}${c.reset}`);\n console.log('');\n\n if (summary.failed > 0) {\n console.log(` ${bg(220, 38, 38)}${c.white}${c.bold} ⛔ COMPROMISE DETECTED ⛔ ${c.reset}`);\n console.log('');\n console.log(` ${c.red}${c.bold}Immediate Actions:${c.reset}`);\n console.log(` ${c.red}1.${c.reset} Disconnect from the network`);\n console.log(` ${c.red}2.${c.reset} Rotate ALL credentials, tokens, API keys`);\n console.log(` ${c.red}3.${c.reset} ${c.white}npm install <pkg>@latest${c.reset} for compromised packages`);\n console.log(` ${c.red}4.${c.reset} ${c.white}npm cache clean --force${c.reset}`);\n console.log(` ${c.red}5.${c.reset} Review system for backdoors and persistence`);\n\n if (summary.compromisedProjects.length > 0) {\n console.log('');\n console.log(` ${c.red}${c.bold}Compromised:${c.reset}`);\n for (const p of summary.compromisedProjects) {\n console.log(` ${c.red} → ${p}${c.reset}`);\n }\n }\n\n const byRule = new Map<string, CheckResult[]>();\n for (const r of summary.results.filter((r) => r.type === 'fail')) {\n const arr = byRule.get(r.rule) || [];\n arr.push(r);\n byRule.set(r.rule, arr);\n }\n for (const [rule, results] of byRule) {\n console.log('');\n console.log(` ${c.red}${c.bold}${rule}:${c.reset}`);\n for (const r of results) {\n console.log(` ${c.red}→ ${r.message}${c.reset}`);\n if (r.details) console.log(` ${c.dim}${r.details}${c.reset}`);\n }\n }\n } else if (summary.warnings > 0) {\n console.log(` ${bg(234, 179, 8)}${ESC}[30m${c.bold} ⚠ WARNINGS — REVIEW RECOMMENDED ⚠ ${c.reset}`);\n console.log('');\n console.log(` ${c.yellow}Some items need manual review.${c.reset}`);\n } else {\n console.log(` ${bg(34, 197, 94)}${c.white}${c.bold} ✓ ALL CLEAR ${c.reset}`);\n console.log('');\n console.log(` ${c.green}No supply chain compromises detected.${c.reset}`);\n console.log('');\n console.log(` ${c.dim}Tips:${c.reset}`);\n console.log(` ${c.cyan}›${c.reset} Use lockfiles and verify integrity`);\n console.log(` ${c.cyan}›${c.reset} Pin dependencies to exact versions`);\n console.log(` ${c.cyan}›${c.reset} Enable npm audit in CI/CD`);\n console.log(` ${c.cyan}›${c.reset} Monitor SLSA provenance on critical packages`);\n }\n\n console.log('');\n console.log(line('═'));\n console.log(` ${c.dim}${new Date().toISOString()}${c.reset}`);\n console.log(` ${c.dim}https://github.com/AsyrafHussin/supply-scan${c.reset}`);\n console.log('');\n}\n\n// ─── Interactive Select ─────────────────────────────────────────────\n\ninterface SelectItem<T> {\n label: string;\n value: T;\n hint?: string;\n}\n\nexport async function interactiveMultiSelect<T>(opts: {\n message: string;\n items: SelectItem<T>[];\n allOption?: { label: string };\n}): Promise<T[]> {\n if (!process.stdin.isTTY) return opts.items.map((i) => i.value);\n\n const items = opts.items;\n const hasAll = !!opts.allOption;\n const totalRows = hasAll ? items.length + 1 : items.length;\n let cursor = 0;\n const selected = new Set<number>();\n let allSelected = true;\n\n const headerLines = 3; // message + hint + blank\n const totalLines = headerLines + totalRows;\n\n function render(initial = false): void {\n if (!initial) process.stdout.write(`${ESC}[${totalLines}A`);\n\n process.stdout.write(`${ESC}[2K\\n`);\n process.stdout.write(`${ESC}[2K ${c.white}${c.bold}${opts.message}${c.reset}\\n`);\n process.stdout.write(`${ESC}[2K ${c.dim}↑↓ navigate · space toggle · enter confirm${c.reset}\\n`);\n\n if (hasAll) {\n const active = cursor === 0;\n const icon = allSelected ? `${c.green}◉${c.reset}` : `${c.dim}○${c.reset}`;\n const ptr = active ? `${c.cyan}❯${c.reset}` : ' ';\n const lbl = active ? `${c.green}${c.bold}${opts.allOption!.label}${c.reset}` : `${c.dim}${opts.allOption!.label}${c.reset}`;\n process.stdout.write(`${ESC}[2K ${ptr} ${icon} ${lbl}\\n`);\n }\n\n for (let i = 0; i < items.length; i++) {\n const idx = hasAll ? i + 1 : i;\n const active = cursor === idx;\n const sel = allSelected || selected.has(i);\n const icon = sel ? `${c.green}◉${c.reset}` : `${c.dim}○${c.reset}`;\n const ptr = active ? `${c.cyan}❯${c.reset}` : ' ';\n const hint = items[i].hint ? ` ${c.dim}${items[i].hint}${c.reset}` : '';\n const lbl = active ? `${c.white}${items[i].label}${c.reset}` : `${c.dim}${items[i].label}${c.reset}`;\n process.stdout.write(`${ESC}[2K ${ptr} ${icon} ${lbl}${hint}\\n`);\n }\n }\n\n return new Promise<T[]>((resolve) => {\n hideCursor();\n render(true);\n process.stdin.setRawMode(true);\n process.stdin.resume();\n\n // hasAll: indices 0 (all) + 1..N (items) → max = items.length\n // no all: indices 0..N-1 → max = items.length - 1\n const maxCursor = hasAll ? items.length : items.length - 1;\n\n const onData = (data: Buffer) => {\n const key = data.toString();\n if (key === '\\x1b[A') { cursor = cursor <= 0 ? maxCursor : cursor - 1; render(); }\n else if (key === '\\x1b[B') { cursor = cursor >= maxCursor ? 0 : cursor + 1; render(); }\n else if (key === ' ') {\n if (hasAll && cursor === 0) { allSelected = !allSelected; selected.clear(); }\n else {\n const ii = hasAll ? cursor - 1 : cursor;\n allSelected = false;\n if (selected.has(ii)) selected.delete(ii); else selected.add(ii);\n if (selected.size === items.length) { allSelected = true; selected.clear(); }\n }\n render();\n }\n else if (key === '\\r') {\n teardownStdin(onData);\n if (allSelected || selected.size === 0) {\n resolve(items.map((i) => i.value));\n } else {\n resolve([...selected].map((i) => items[i].value));\n }\n }\n else if (key === '\\x03') { teardownStdin(onData); process.exit(130); }\n };\n\n process.stdin.on('data', onData);\n });\n}\n\nexport async function interactiveSingleSelect<T>(opts: {\n message: string;\n items: SelectItem<T>[];\n}): Promise<T> {\n if (!process.stdin.isTTY) return opts.items[0].value;\n\n const items = opts.items;\n let cursor = 0;\n const headerLines = 3;\n const totalLines = headerLines + items.length;\n\n function render(initial = false): void {\n if (!initial) process.stdout.write(`${ESC}[${totalLines}A`);\n\n process.stdout.write(`${ESC}[2K\\n`);\n process.stdout.write(`${ESC}[2K ${c.white}${c.bold}${opts.message}${c.reset}\\n`);\n process.stdout.write(`${ESC}[2K ${c.dim}↑↓ navigate · enter select${c.reset}\\n`);\n\n for (let i = 0; i < items.length; i++) {\n const active = cursor === i;\n const ptr = active ? `${c.cyan}❯${c.reset}` : ' ';\n const hint = items[i].hint ? ` ${c.dim}${items[i].hint}${c.reset}` : '';\n const lbl = active ? `${c.white}${c.bold}${items[i].label}${c.reset}` : `${c.dim}${items[i].label}${c.reset}`;\n process.stdout.write(`${ESC}[2K ${ptr} ${lbl}${hint}\\n`);\n }\n }\n\n return new Promise<T>((resolve) => {\n hideCursor();\n render(true);\n process.stdin.setRawMode(true);\n process.stdin.resume();\n\n const onData = (data: Buffer) => {\n const key = data.toString();\n if (key === '\\x1b[A') { cursor = cursor <= 0 ? items.length - 1 : cursor - 1; render(); }\n else if (key === '\\x1b[B') { cursor = cursor >= items.length - 1 ? 0 : cursor + 1; render(); }\n else if (key === '\\r') { teardownStdin(onData); resolve(items[cursor].value); }\n else if (key === '\\x03') { teardownStdin(onData); process.exit(130); }\n };\n\n process.stdin.on('data', onData);\n });\n}\n","import { join } from 'node:path';\nimport { readFileSync, readdirSync } from 'node:fs';\nimport type { Rule, CheckResult } from '../types.js';\nimport { dirExists, getPkgVersion, isVersionCompromised, escapeRegex } from '../utils.js';\n\n// Pre-compiled regex cache to avoid recompilation in hot loops\nconst regexCache = new Map<string, RegExp>();\n\nfunction getMaliciousPkgRegex(pkg: string): RegExp {\n let re = regexCache.get(pkg);\n if (!re) {\n re = new RegExp(`[\"'/]${escapeRegex(pkg)}[\"'/@:]`);\n regexCache.set(pkg, re);\n }\n return re;\n}\n\nexport function checkPackages(\n rules: Rule[],\n projectDirs: string[]\n): CheckResult[] {\n const results: CheckResult[] = [];\n\n // Pre-compile all malicious package regexes before the project loop\n for (const rule of rules) {\n for (const pkg of Object.keys(rule.packages.malicious)) {\n getMaliciousPkgRegex(pkg);\n }\n }\n\n for (const dir of projectDirs) {\n const lockfileCache = readLockfiles(dir);\n\n // Cache getPkgVersion results per project to avoid redundant reads across rules\n const versionCache = new Map<string, string | null>();\n\n for (const rule of rules) {\n // Check compromised packages in node_modules\n for (const [pkg, badVersions] of Object.entries(rule.packages.compromised)) {\n const pkgJsonPath = join(dir, 'node_modules', pkg, 'package.json');\n let version = versionCache.get(pkgJsonPath);\n if (version === undefined) {\n version = getPkgVersion(pkgJsonPath);\n versionCache.set(pkgJsonPath, version);\n }\n if (version && isVersionCompromised(version, badVersions)) {\n results.push({\n type: 'fail',\n rule: rule.id,\n check: 'packages',\n message: `${pkg}@${version} is COMPROMISED`,\n details: `${rule.name} — ${dir}`,\n });\n }\n }\n\n // Check malicious packages (should not exist at all)\n for (const [pkg] of Object.entries(rule.packages.malicious)) {\n const pkgDir = join(dir, 'node_modules', pkg);\n if (dirExists(pkgDir)) {\n const pkgJsonPath = join(pkgDir, 'package.json');\n let version = versionCache.get(pkgJsonPath);\n if (version === undefined) {\n version = getPkgVersion(pkgJsonPath);\n versionCache.set(pkgJsonPath, version);\n }\n results.push({\n type: 'fail',\n rule: rule.id,\n check: 'packages',\n message: `Malicious package ${pkg}${version ? `@${version}` : ''} found`,\n details: `${rule.name} — ${dir}`,\n });\n }\n }\n\n checkLockfilesForRule(lockfileCache, dir, rule, results);\n }\n }\n\n return results;\n}\n\nconst LOCKFILE_NAMES = ['package-lock.json', 'yarn.lock', 'pnpm-lock.yaml', 'bun.lock', 'bun.lockb'];\n\nfunction readLockfiles(dir: string): Map<string, string> {\n const cache = new Map<string, string>();\n\n // Check which files exist first (cheaper than catching ENOENT per file)\n let dirEntries: Set<string>;\n try {\n dirEntries = new Set(readdirSync(dir));\n } catch {\n return cache;\n }\n\n for (const name of LOCKFILE_NAMES) {\n if (!dirEntries.has(name)) continue;\n try {\n const encoding = name === 'bun.lockb' ? 'latin1' : 'utf-8';\n cache.set(name, readFileSync(join(dir, name), encoding));\n } catch {\n // Read error\n }\n }\n return cache;\n}\n\nfunction checkLockfilesForRule(\n lockfileCache: Map<string, string>,\n dir: string,\n rule: Rule,\n results: CheckResult[]\n): void {\n for (const [lockfile, content] of lockfileCache) {\n // Check malicious packages using pre-compiled regex\n for (const pkg of Object.keys(rule.packages.malicious)) {\n if (getMaliciousPkgRegex(pkg).test(content)) {\n results.push({\n type: 'fail',\n rule: rule.id,\n check: 'lockfile',\n message: `${lockfile} references malicious package \"${pkg}\"`,\n details: `${rule.name} — ${dir}`,\n });\n }\n }\n\n // Check compromised versions using string matching (no regex needed — exact patterns)\n for (const [pkg, versions] of Object.entries(rule.packages.compromised)) {\n for (const ver of versions) {\n const tied = [\n `\"${pkg}\": \"${ver}\"`,\n `${pkg}@${ver}`,\n `\"${pkg}\",\"${ver}\"`,\n ];\n if (tied.some((p) => content.includes(p))) {\n results.push({\n type: 'warn',\n rule: rule.id,\n check: 'lockfile',\n message: `${lockfile} may reference ${pkg}@${ver}`,\n details: `${rule.name} — ${dir}`,\n });\n }\n }\n }\n }\n}\n","import type { Rule, CheckResult } from '../types.js';\nimport { expandPath, fileExists, getOS } from '../utils.js';\n\n/**\n * Check for known malware artifacts on disk.\n * Checks OS-specific file paths from rule IOCs.\n */\nexport function checkFiles(rules: Rule[]): CheckResult[] {\n const results: CheckResult[] = [];\n const os = getOS();\n\n for (const rule of rules) {\n const filePaths = rule.ioc.files?.[os];\n if (!filePaths || filePaths.length === 0) continue;\n\n for (const rawPath of filePaths) {\n const path = expandPath(rawPath);\n if (fileExists(path)) {\n results.push({\n type: 'fail',\n rule: rule.id,\n check: 'files',\n message: `Malware artifact found: ${path}`,\n details: rule.name,\n });\n }\n }\n }\n\n return results;\n}\n","import { readFileSync } from 'node:fs';\nimport type { Rule, CheckResult } from '../types.js';\nimport { getOS, escapeRegex } from '../utils.js';\nimport { runCommand } from '../shell.js';\n\nexport function checkNetwork(rules: Rule[]): CheckResult[] {\n const results: CheckResult[] = [];\n const os = getOS();\n\n // Collect all C2 IPs and domains — support multiple rules per IOC\n const rulesByIP = new Map<string, string[]>();\n const rulesByDomain = new Map<string, string[]>();\n\n for (const rule of rules) {\n for (const ip of rule.ioc.ips ?? []) {\n const arr = rulesByIP.get(ip) || [];\n arr.push(rule.id);\n rulesByIP.set(ip, arr);\n }\n for (const domain of rule.ioc.domains ?? []) {\n const arr = rulesByDomain.get(domain) || [];\n arr.push(rule.id);\n rulesByDomain.set(domain, arr);\n }\n }\n\n if (rulesByIP.size === 0 && rulesByDomain.size === 0) return results;\n\n // Check active connections line-by-line for exact matches\n const connectionLines = getActiveConnections(os).split('\\n');\n\n for (const [ip, ruleIds] of rulesByIP) {\n // Use word-boundary regex to avoid partial IP matches (e.g., 1.2.3.4 matching 21.2.3.40)\n const pattern = new RegExp(`(?:^|[\\\\s:])${escapeRegex(ip)}(?:[\\\\s:]|$)`);\n if (connectionLines.some((line) => pattern.test(line))) {\n results.push({\n type: 'fail',\n rule: ruleIds[0],\n check: 'network',\n message: `Active connection to C2 IP: ${ip}`,\n details: `Rules: ${ruleIds.join(', ')} — Disconnect from network immediately!`,\n });\n }\n }\n\n for (const [domain, ruleIds] of rulesByDomain) {\n const pattern = new RegExp(`(?:^|[\\\\s:])${escapeRegex(domain)}(?:[\\\\s:.]|$)`);\n if (connectionLines.some((line) => pattern.test(line))) {\n results.push({\n type: 'fail',\n rule: ruleIds[0],\n check: 'network',\n message: `Active connection to C2 domain: ${domain}`,\n details: `Rules: ${ruleIds.join(', ')} — Disconnect from network immediately!`,\n });\n }\n }\n\n checkHostsFile(os, rulesByIP, rulesByDomain, results);\n\n return results;\n}\n\nfunction getActiveConnections(os: string): string {\n if (os === 'darwin' || os === 'linux') {\n return runCommand('lsof -i -n -P 2>/dev/null || netstat -an 2>/dev/null');\n } else if (os === 'win32') {\n return runCommand('netstat -an');\n }\n return '';\n}\n\nfunction checkHostsFile(\n os: string,\n ips: Map<string, string[]>,\n domains: Map<string, string[]>,\n results: CheckResult[]\n): void {\n const hostsPath = os === 'win32'\n ? 'C:\\\\Windows\\\\System32\\\\drivers\\\\etc\\\\hosts'\n : '/etc/hosts';\n\n try {\n const hostsLines = readFileSync(hostsPath, 'utf-8').split('\\n');\n for (const [ip, ruleIds] of ips) {\n const pattern = new RegExp(`(?:^|\\\\s)${escapeRegex(ip)}(?:\\\\s|$)`);\n if (hostsLines.some((line) => pattern.test(line))) {\n results.push({\n type: 'warn',\n rule: ruleIds[0],\n check: 'network',\n message: `C2 IP ${ip} found in hosts file`,\n });\n }\n }\n for (const [domain, ruleIds] of domains) {\n const pattern = new RegExp(`(?:^|\\\\s)${escapeRegex(domain)}(?:\\\\s|$)`);\n if (hostsLines.some((line) => pattern.test(line))) {\n results.push({\n type: 'warn',\n rule: ruleIds[0],\n check: 'network',\n message: `C2 domain ${domain} found in hosts file`,\n });\n }\n }\n } catch {\n // Can't read hosts file\n }\n}\n","import { execSync, execFileSync } from 'node:child_process';\n\nconst TIMEOUT = 10000;\n\nexport function runCommand(cmd: string): string {\n try {\n return execSync(cmd, { encoding: 'utf-8', timeout: TIMEOUT, stdio: ['pipe', 'pipe', 'pipe'] }).trim();\n } catch {\n return '';\n }\n}\n\nexport function runSafe(cmd: string, args: string[]): string {\n try {\n return execFileSync(cmd, args, { encoding: 'utf-8', timeout: TIMEOUT, stdio: ['pipe', 'pipe', 'pipe'] }).trim();\n } catch {\n return '';\n }\n}\n","import type { Rule, CheckResult } from '../types.js';\nimport { getOS, dirExists, escapeRegex } from '../utils.js';\nimport { runCommand, runSafe } from '../shell.js';\n\nexport function checkProcesses(rules: Rule[]): CheckResult[] {\n const results: CheckResult[] = [];\n const os = getOS();\n\n // Collect process patterns — support multiple rules per pattern\n const rulesByProcess = new Map<string, string[]>();\n\n for (const rule of rules) {\n for (const proc of rule.ioc.processes ?? []) {\n const arr = rulesByProcess.get(proc) || [];\n arr.push(rule.id);\n rulesByProcess.set(proc, arr);\n }\n }\n\n if (rulesByProcess.size === 0) return results;\n\n const processLines = getProcessList(os).split('\\n');\n if (processLines.length === 0) return results;\n\n for (const [pattern, ruleIds] of rulesByProcess) {\n // Use word-boundary regex to avoid partial matches\n // e.g., \"ld.py\" should not match \"/usr/build.py\"\n const regex = new RegExp(`(?:^|[\\\\s/])${escapeRegex(pattern)}(?:\\\\s|$)`);\n if (processLines.some((line) => regex.test(line))) {\n results.push({\n type: 'fail',\n rule: ruleIds[0],\n check: 'processes',\n message: `Suspicious process running: ${pattern}`,\n details: `Rules: ${ruleIds.join(', ')} — May indicate active compromise`,\n });\n }\n }\n\n if (os === 'darwin') {\n checkMacOSPersistence(rules, results);\n }\n\n return results;\n}\n\nfunction getProcessList(os: string): string {\n if (os === 'darwin' || os === 'linux') {\n return runCommand('ps aux 2>/dev/null');\n } else if (os === 'win32') {\n return runCommand('tasklist /v 2>nul');\n }\n return '';\n}\n\nfunction checkMacOSPersistence(rules: Rule[], results: CheckResult[]): void {\n const launchDirs = [\n `${process.env.HOME}/Library/LaunchAgents`,\n '/Library/LaunchAgents',\n '/Library/LaunchDaemons',\n ];\n\n const searchStrings = new Map<string, string>();\n for (const rule of rules) {\n for (const s of rule.ioc.strings ?? []) {\n searchStrings.set(s, rule.id);\n }\n for (const domain of rule.ioc.domains ?? []) {\n searchStrings.set(domain, rule.id);\n }\n for (const ip of rule.ioc.ips ?? []) {\n searchStrings.set(ip, rule.id);\n }\n }\n\n const existingDirs = launchDirs.filter(dirExists);\n if (existingDirs.length === 0 || searchStrings.size === 0) return;\n\n const pattern = Array.from(searchStrings.keys()).join('|');\n const hits = runSafe('grep', ['-rlE', pattern, ...existingDirs]);\n\n if (hits) {\n for (const file of hits.split('\\n').filter(Boolean)) {\n const content = runSafe('cat', [file]);\n let matchedRule = 'unknown';\n for (const [s, ruleId] of searchStrings) {\n if (content.includes(s)) { matchedRule = ruleId; break; }\n }\n results.push({\n type: 'fail',\n rule: matchedRule,\n check: 'processes',\n message: `Suspicious LaunchAgent/Daemon: ${file}`,\n details: 'May indicate malware persistence',\n });\n }\n }\n}\n","import { join } from 'node:path';\nimport { homedir } from 'node:os';\nimport type { Rule, CheckResult } from '../types.js';\nimport { dirExists } from '../utils.js';\nimport { runCommand, runSafe } from '../shell.js';\n\ninterface CacheLocation {\n name: string;\n dir: string;\n cleanCmd: string;\n}\n\nfunction detectCaches(): CacheLocation[] {\n const home = homedir();\n const caches: CacheLocation[] = [];\n\n // npm\n const npmCache = runCommand('npm config get cache') || join(home, '.npm');\n if (dirExists(npmCache)) {\n caches.push({ name: 'npm', dir: npmCache, cleanCmd: 'npm cache clean --force' });\n }\n\n // pnpm\n const pnpmStore = runCommand('pnpm store path 2>/dev/null');\n if (pnpmStore && dirExists(pnpmStore)) {\n caches.push({ name: 'pnpm', dir: pnpmStore, cleanCmd: 'pnpm store prune' });\n }\n\n // yarn v1\n const yarnCache = runCommand('yarn cache dir 2>/dev/null');\n if (yarnCache && dirExists(yarnCache)) {\n caches.push({ name: 'yarn', dir: yarnCache, cleanCmd: 'yarn cache clean' });\n }\n\n // yarn v2+ (berry) — project-local .yarn/cache\n const yarnBerryCache = join(process.cwd(), '.yarn', 'cache');\n if (dirExists(yarnBerryCache)) {\n caches.push({ name: 'yarn-berry', dir: yarnBerryCache, cleanCmd: 'yarn cache clean --all' });\n }\n\n // bun\n const bunCache = join(home, '.bun', 'install', 'cache');\n if (dirExists(bunCache)) {\n caches.push({ name: 'bun', dir: bunCache, cleanCmd: 'bun pm cache rm' });\n }\n\n return caches;\n}\n\n/**\n * Scan all package manager caches for malicious packages.\n * Supports: npm, pnpm, yarn (v1 & v2+), bun.\n */\nexport function checkCache(rules: Rule[]): CheckResult[] {\n const results: CheckResult[] = [];\n const caches = detectCaches();\n\n if (caches.length === 0) return results;\n\n // Collect all malicious package names and compromised tarballs\n const maliciousPkgs = new Map<string, string>();\n const compromisedTarballs = new Map<string, string>();\n\n for (const rule of rules) {\n for (const pkg of Object.keys(rule.packages.malicious)) {\n maliciousPkgs.set(pkg, rule.id);\n }\n for (const [pkg, versions] of Object.entries(rule.packages.compromised)) {\n for (const ver of versions) {\n compromisedTarballs.set(`${pkg}-${ver}.tgz`, rule.id);\n }\n }\n }\n\n if (maliciousPkgs.size === 0 && compromisedTarballs.size === 0) return results;\n\n for (const cache of caches) {\n scanCacheDir(cache, maliciousPkgs, compromisedTarballs, results);\n }\n\n return results;\n}\n\nfunction findInCache(\n cacheDir: string,\n names: Map<string, string>,\n type: 'd' | 'f'\n): Map<string, string> {\n const hits = new Map<string, string>();\n if (names.size === 0) return hits;\n\n const nameExprs = Array.from(names.keys()).flatMap((n, i) =>\n i === 0 ? ['-name', n] : ['-o', '-name', n]\n );\n const found = runSafe('find', [cacheDir, '-maxdepth', '4', '-type', type, '(', ...nameExprs, ')']);\n if (found) {\n for (const line of found.split('\\n').filter(Boolean)) {\n const name = line.split('/').pop() || '';\n const ruleId = names.get(name);\n if (ruleId) hits.set(name, ruleId);\n }\n }\n return hits;\n}\n\nfunction scanCacheDir(\n cache: CacheLocation,\n maliciousPkgs: Map<string, string>,\n compromisedTarballs: Map<string, string>,\n results: CheckResult[]\n): void {\n for (const [name, ruleId] of findInCache(cache.dir, maliciousPkgs, 'd')) {\n results.push({\n type: 'fail',\n rule: ruleId,\n check: 'cache',\n message: `Malicious package \"${name}\" found in ${cache.name} cache`,\n details: `Run: ${cache.cleanCmd}`,\n });\n }\n\n for (const [name, ruleId] of findInCache(cache.dir, compromisedTarballs, 'f')) {\n results.push({\n type: 'warn',\n rule: ruleId,\n check: 'cache',\n message: `Compromised tarball ${name} in ${cache.name} cache`,\n details: `Run: ${cache.cleanCmd}`,\n });\n }\n}\n","import type { Rule, CheckResult, ScanSummary } from './types.js';\nimport { checkPackages } from './checks/packages.js';\nimport { checkFiles } from './checks/files.js';\nimport { checkNetwork } from './checks/network.js';\nimport { checkProcesses } from './checks/processes.js';\nimport { checkCache } from './checks/cache.js';\nimport * as ui from './ui.js';\n\ninterface ScanOptions {\n rules: Rule[];\n projectDirs: string[];\n ci: boolean;\n}\n\ninterface CheckDef {\n title: string;\n icon: string;\n passMessage: string;\n run: () => CheckResult[];\n}\n\nexport async function scan(options: ScanOptions): Promise<ScanSummary> {\n const { rules, projectDirs, ci } = options;\n const allResults: CheckResult[] = [];\n\n const checks: CheckDef[] = [\n {\n title: 'COMPROMISED PACKAGES',\n icon: '\\uD83D\\uDCE6',\n passMessage: `All ${projectDirs.length} projects clean — no compromised packages`,\n run: () => checkPackages(rules, projectDirs),\n },\n {\n title: 'MALWARE FILES',\n icon: '\\uD83D\\uDC80',\n passMessage: 'No malware artifacts found on disk',\n run: () => checkFiles(rules),\n },\n {\n title: 'NETWORK CONNECTIONS',\n icon: '\\uD83C\\uDF10',\n passMessage: 'No active C2 connections detected',\n run: () => checkNetwork(rules),\n },\n {\n title: 'SUSPICIOUS PROCESSES',\n icon: '\\u2699\\uFE0F ',\n passMessage: 'No suspicious processes detected',\n run: () => checkProcesses(rules),\n },\n {\n title: 'PACKAGE MANAGER CACHES',\n icon: '\\uD83D\\uDCC1',\n passMessage: 'All package manager caches are clean',\n run: () => checkCache(rules),\n },\n ];\n\n const totalChecks = checks.length;\n\n for (let i = 0; i < checks.length; i++) {\n const check = checks[i];\n\n if (!ci) ui.sectionHeader(i + 1, totalChecks, check.title, check.icon);\n if (!ci) ui.spinnerStart(`Running ${check.title.toLowerCase()} check...`);\n\n const results = check.run();\n allResults.push(...results);\n\n if (!ci) ui.spinnerStop();\n if (!ci) displayResults(results, check.passMessage);\n }\n\n return buildSummary(allResults, projectDirs.length, rules.length, totalChecks);\n}\n\nfunction displayResults(results: CheckResult[], passMessage: string): void {\n if (results.filter((r) => r.type === 'fail' || r.type === 'warn').length === 0) {\n ui.result('pass', passMessage);\n }\n for (const r of results) {\n ui.result(r.type, r.message);\n if (r.details) ui.resultDetail(r.details);\n }\n}\n\nfunction buildSummary(\n results: CheckResult[],\n projectsScanned: number,\n rulesChecked: number,\n totalChecks: number\n): ScanSummary {\n const compromisedProjects = new Set<string>();\n let failCount = 0;\n let warnCount = 0;\n let passCount = 0;\n\n for (const r of results) {\n if (r.type === 'fail') {\n failCount++;\n if (r.details) {\n const match = r.details.match(/— (.+)$/);\n if (match) compromisedProjects.add(match[1]);\n }\n } else if (r.type === 'warn') {\n warnCount++;\n } else if (r.type === 'pass') {\n passCount++;\n }\n }\n\n return {\n projectsScanned,\n rulesChecked,\n totalChecks: results.length || totalChecks,\n passed: results.length === 0 ? totalChecks : passCount,\n failed: failCount,\n warnings: warnCount,\n results,\n compromisedProjects: Array.from(compromisedProjects),\n };\n}\n"],"mappings":"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","names":["join","readdirSync","join","result","result","readdirSync","join","resolve","r","resolve","join","readFileSync","readdirSync","join","readdirSync","readFileSync","readFileSync","line","readFileSync","line","join","homedir","homedir","join","line","join"]}
|
package/package.json
CHANGED
package/rules/axios-2026.json
CHANGED
|
@@ -10,22 +10,54 @@
|
|
|
10
10
|
],
|
|
11
11
|
"packages": {
|
|
12
12
|
"compromised": {
|
|
13
|
-
"axios": [
|
|
13
|
+
"axios": [
|
|
14
|
+
"1.14.1",
|
|
15
|
+
"0.30.4"
|
|
16
|
+
]
|
|
14
17
|
},
|
|
15
18
|
"malicious": {
|
|
16
|
-
"plain-crypto-js": [
|
|
19
|
+
"plain-crypto-js": [
|
|
20
|
+
"4.2.0",
|
|
21
|
+
"4.2.1"
|
|
22
|
+
]
|
|
17
23
|
}
|
|
18
24
|
},
|
|
19
25
|
"ioc": {
|
|
20
26
|
"files": {
|
|
21
|
-
"darwin": [
|
|
22
|
-
|
|
23
|
-
|
|
27
|
+
"darwin": [
|
|
28
|
+
"L0xpYnJhcnkvQ2FjaGVzL2NvbS5hcHBsZS5hY3QubW9uZA==",
|
|
29
|
+
"L3RtcC82MjAyMDMz"
|
|
30
|
+
],
|
|
31
|
+
"linux": [
|
|
32
|
+
"L3RtcC9sZC5weQ=="
|
|
33
|
+
],
|
|
34
|
+
"win32": [
|
|
35
|
+
"JVBST0dSQU1EQVRBJVx3dC5leGU=",
|
|
36
|
+
"JVBST0dSQU1EQVRBJVxzeXN0ZW0uYmF0"
|
|
37
|
+
]
|
|
24
38
|
},
|
|
25
|
-
"domains": [
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
"
|
|
30
|
-
|
|
39
|
+
"domains": [
|
|
40
|
+
"c2ZyY2xhay5jb20=",
|
|
41
|
+
"Y2FsbG5yd2lzZS5jb20="
|
|
42
|
+
],
|
|
43
|
+
"ips": [
|
|
44
|
+
"MTQyLjExLjIwNi43Mw=="
|
|
45
|
+
],
|
|
46
|
+
"ports": [
|
|
47
|
+
8000
|
|
48
|
+
],
|
|
49
|
+
"processes": [
|
|
50
|
+
"Y29tLmFwcGxlLmFjdC5tb25k",
|
|
51
|
+
"d3QuZXhl",
|
|
52
|
+
"bGQucHk="
|
|
53
|
+
],
|
|
54
|
+
"strings": [
|
|
55
|
+
"T3JEZVJfNzA3Nw==",
|
|
56
|
+
"NjIwMjAzMw==",
|
|
57
|
+
"aWZzdGFwQHByb3Rvbg==",
|
|
58
|
+
"bnJ3aXNlQHByb3Rvbg==",
|
|
59
|
+
"cGFja2FnZS5tZA=="
|
|
60
|
+
]
|
|
61
|
+
},
|
|
62
|
+
"encoded": true
|
|
31
63
|
}
|
|
@@ -10,31 +10,80 @@
|
|
|
10
10
|
],
|
|
11
11
|
"packages": {
|
|
12
12
|
"compromised": {
|
|
13
|
-
"chalk": [
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
"
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
"color-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
"ansi
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
"
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
"
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
"
|
|
13
|
+
"chalk": [
|
|
14
|
+
"5.6.1"
|
|
15
|
+
],
|
|
16
|
+
"debug": [
|
|
17
|
+
"4.4.2"
|
|
18
|
+
],
|
|
19
|
+
"color-name": [
|
|
20
|
+
"2.0.1"
|
|
21
|
+
],
|
|
22
|
+
"strip-ansi": [
|
|
23
|
+
"7.1.1"
|
|
24
|
+
],
|
|
25
|
+
"color": [
|
|
26
|
+
"5.0.1"
|
|
27
|
+
],
|
|
28
|
+
"color-convert": [
|
|
29
|
+
"3.1.1"
|
|
30
|
+
],
|
|
31
|
+
"color-string": [
|
|
32
|
+
"2.1.1"
|
|
33
|
+
],
|
|
34
|
+
"has-ansi": [
|
|
35
|
+
"6.0.1"
|
|
36
|
+
],
|
|
37
|
+
"ansi-styles": [
|
|
38
|
+
"6.2.2"
|
|
39
|
+
],
|
|
40
|
+
"ansi-regex": [
|
|
41
|
+
"6.2.1"
|
|
42
|
+
],
|
|
43
|
+
"supports-color": [
|
|
44
|
+
"10.2.1"
|
|
45
|
+
],
|
|
46
|
+
"backslash": [
|
|
47
|
+
"0.2.1"
|
|
48
|
+
],
|
|
49
|
+
"wrap-ansi": [
|
|
50
|
+
"9.0.1"
|
|
51
|
+
],
|
|
52
|
+
"is-arrayish": [
|
|
53
|
+
"0.3.3"
|
|
54
|
+
],
|
|
55
|
+
"error-ex": [
|
|
56
|
+
"1.3.3"
|
|
57
|
+
],
|
|
58
|
+
"slice-ansi": [
|
|
59
|
+
"7.1.1"
|
|
60
|
+
],
|
|
61
|
+
"simple-swizzle": [
|
|
62
|
+
"0.2.3"
|
|
63
|
+
],
|
|
64
|
+
"chalk-template": [
|
|
65
|
+
"1.1.1"
|
|
66
|
+
],
|
|
67
|
+
"supports-hyperlinks": [
|
|
68
|
+
"4.1.1"
|
|
69
|
+
]
|
|
32
70
|
},
|
|
33
71
|
"malicious": {}
|
|
34
72
|
},
|
|
35
73
|
"ioc": {
|
|
36
|
-
"domains": [
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
74
|
+
"domains": [
|
|
75
|
+
"bnBtanMuaGVscA==",
|
|
76
|
+
"c3RhdGljLW13LWhvc3QuYi1jZG4ubmV0",
|
|
77
|
+
"aW1nLWRhdGEtYmFja3VwLmItY2RuLm5ldA==",
|
|
78
|
+
"d2Vic29ja2V0LWFwaTIucHVibGljdm0uY29t"
|
|
79
|
+
],
|
|
80
|
+
"ips": [
|
|
81
|
+
"MTg1LjcuODEuMTA4"
|
|
82
|
+
],
|
|
83
|
+
"strings": [
|
|
84
|
+
"bnBtanMuaGVscA==",
|
|
85
|
+
"c3RhdGljLW13LWhvc3QuYi1jZG4ubmV0"
|
|
86
|
+
]
|
|
87
|
+
},
|
|
88
|
+
"encoded": true
|
|
40
89
|
}
|
package/rules/coa-rc-2021.json
CHANGED
|
@@ -9,17 +9,42 @@
|
|
|
9
9
|
],
|
|
10
10
|
"packages": {
|
|
11
11
|
"compromised": {
|
|
12
|
-
"coa": [
|
|
13
|
-
|
|
12
|
+
"coa": [
|
|
13
|
+
"2.0.3",
|
|
14
|
+
"2.0.4",
|
|
15
|
+
"2.1.1",
|
|
16
|
+
"2.1.3",
|
|
17
|
+
"3.0.1",
|
|
18
|
+
"3.1.3"
|
|
19
|
+
],
|
|
20
|
+
"rc": [
|
|
21
|
+
"1.2.9",
|
|
22
|
+
"1.3.9",
|
|
23
|
+
"2.3.9"
|
|
24
|
+
]
|
|
14
25
|
},
|
|
15
26
|
"malicious": {}
|
|
16
27
|
},
|
|
17
28
|
"ioc": {
|
|
18
29
|
"files": {
|
|
19
|
-
"win32": [
|
|
30
|
+
"win32": [
|
|
31
|
+
"JVRFTVAlXGNvbXBpbGUuanM=",
|
|
32
|
+
"JVRFTVAlXGNvbXBpbGUuYmF0",
|
|
33
|
+
"JVRFTVAlXHNkZC5kbGw="
|
|
34
|
+
]
|
|
20
35
|
},
|
|
21
|
-
"domains": [
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
36
|
+
"domains": [
|
|
37
|
+
"cGFzdG9yY3J5cHRvZ3JhcGguYXQ="
|
|
38
|
+
],
|
|
39
|
+
"processes": [
|
|
40
|
+
"Y29tcGlsZS5iYXQ=",
|
|
41
|
+
"c2RkLmRsbA=="
|
|
42
|
+
],
|
|
43
|
+
"strings": [
|
|
44
|
+
"cGFzdG9yY3J5cHRvZ3JhcGguYXQ=",
|
|
45
|
+
"Y29tcGlsZS5qcw==",
|
|
46
|
+
"Y29tcGlsZS5iYXQ="
|
|
47
|
+
]
|
|
48
|
+
},
|
|
49
|
+
"encoded": true
|
|
25
50
|
}
|