{"version":3,"sources":["../src/utils/files.ts","../src/utils/regex.ts","../src/core/scanner.ts","../src/core/transformer.ts"],"names":["path","glob","readFile","writeFile","copyFile"],"mappings":"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","file":"transformer.cjs","sourcesContent":["/**\n * File utilities for Classpresso\n */\n\nimport { readFile, writeFile, stat, copyFile } from 'fs/promises';\nimport { glob } from 'glob';\nimport path from 'path';\nimport type { FileStats } from '../types/index.js';\n\n/**\n * Default file patterns to scan in build output\n *\n * These patterns support all major frameworks when pointing to their build directories:\n * - Next.js: --dir .next\n * - Astro: --dir dist\n * - Nuxt: --dir .output\n * - SvelteKit: --dir build (or .svelte-kit)\n * - Remix: --dir build\n * - Solid Start: --dir .output (or dist)\n * - Qwik: --dir dist\n * - Angular: --dir dist/[project-name]\n * - Gatsby: --dir public\n * - Vite/Vue/React: --dir dist\n * - Ember: --dir dist\n * - VitePress: --dir .vitepress/dist\n * - Docusaurus: --dir build\n * - Eleventy (11ty): --dir _site\n * - Hugo: --dir public\n * - Parcel: --dir dist\n * - Preact: --dir build (or dist)\n * - Gridsome: --dir dist\n * - RedwoodJS: --dir web/dist\n * - Webpack: --dir dist\n */\nexport const DEFAULT_PATTERNS = [\n  // === Next.js (.next directory) ===\n  // Client-side chunks\n  'static/chunks/**/*.js',\n  'static/css/**/*.css',\n  // Server components (Next.js App Router)\n  'server/app/**/*.js',\n  'server/app/**/*.html',\n  'server/app/**/*.rsc',\n  // Server chunks (contains Client Component code used for hydration)\n  'server/chunks/**/*.js',\n  // Standalone build (Next.js output: 'standalone')\n  'standalone/.next/static/chunks/**/*.js',\n  'standalone/.next/static/css/**/*.css',\n  'standalone/.next/server/app/**/*.js',\n  'standalone/.next/server/app/**/*.html',\n  'standalone/.next/server/app/**/*.rsc',\n  'standalone/.next/server/chunks/**/*.js',\n\n  // === Nuxt (.output directory) ===\n  'public/**/*.html',\n  'public/**/*.js',\n  'public/**/*.css',\n  'public/_nuxt/**/*.js',\n  'public/_nuxt/**/*.css',\n  'server/**/*.mjs',\n  'server/chunks/**/*.mjs',\n\n  // === SvelteKit (build directory) ===\n  // Static adapter output\n  '**/*.html',\n  '_app/**/*.js',\n  '_app/**/*.css',\n  // Node adapter output\n  'client/**/*.js',\n  'client/**/*.css',\n  'server/**/*.js',\n\n  // === Astro (dist directory) ===\n  '_astro/**/*.js',\n  '_astro/**/*.css',\n  // SSR/Hybrid build - Client assets\n  'client/_astro/**/*.js',\n  'client/_astro/**/*.css',\n\n  // === Remix (build directory) ===\n  'client/**/*.js',\n  'client/**/*.css',\n  'server/**/*.js',\n\n  // === Solid Start (.output or dist directory) ===\n  'public/**/*.html',\n  'public/**/*.js',\n  'public/**/*.css',\n  '_build/**/*.js',\n  '_build/**/*.css',\n\n  // === Qwik (dist directory) ===\n  'build/**/*.js',\n  'build/**/*.css',\n  'q-*.js',\n\n  // === Angular (dist/[project] directory) ===\n  // Angular 17+ uses browser subdirectory\n  'browser/**/*.js',\n  'browser/**/*.css',\n  'browser/**/*.html',\n  // Legacy Angular output\n  '*.js',\n  '*.css',\n  '*.html',\n\n  // === Gatsby (public directory) ===\n  'page-data/**/*.json',\n  '*.js',\n  '*.css',\n  '*.html',\n\n  // === Vite/Vue/React generic (dist directory) ===\n  'assets/**/*.js',\n  'assets/**/*.css',\n  'index.html',\n\n  // === Ember (dist directory) ===\n  'assets/**/*.js',\n  'assets/**/*.css',\n  '*.html',\n\n  // === VitePress (.vitepress/dist directory) ===\n  'assets/**/*.js',\n  'assets/**/*.css',\n  '**/*.html',\n\n  // === Docusaurus (build directory) ===\n  'assets/**/*.js',\n  'assets/**/*.css',\n  '**/*.html',\n\n  // === Eleventy/11ty (_site directory) ===\n  '**/*.html',\n  '**/*.js',\n  '**/*.css',\n\n  // === Hugo (public directory) ===\n  '**/*.html',\n  '**/*.js',\n  '**/*.css',\n\n  // === Parcel (dist directory) ===\n  '*.html',\n  '*.js',\n  '*.css',\n\n  // === Preact (build directory) ===\n  'bundle.js',\n  'bundle.*.js',\n  '*.css',\n  '*.html',\n\n  // === Gridsome (dist directory) ===\n  'assets/**/*.js',\n  'assets/**/*.css',\n  '**/*.html',\n\n  // === RedwoodJS (web/dist directory) ===\n  'static/**/*.js',\n  'static/**/*.css',\n  '*.html',\n\n  // === Webpack generic (dist directory) ===\n  '*.js',\n  '*.css',\n  '*.html',\n  'js/**/*.js',\n  'css/**/*.css',\n];\n\n/**\n * Find files matching patterns in a build directory\n */\nexport async function findFiles(\n  buildDir: string,\n  patterns: string[]\n): Promise<string[]> {\n  // Create full patterns and deduplicate\n  const globPatterns = [...new Set(patterns.map(p => path.join(buildDir, p)))];\n\n  // Use windowsPathsNoEscape for Windows compatibility\n  const allFiles = await glob(globPatterns, {\n    nodir: true,\n    windowsPathsNoEscape: true\n  });\n\n  // Remove duplicates (in case patterns overlap)\n  return [...new Set(allFiles)];\n}\n\n/**\n * Read file content as string\n */\nexport async function readFileContent(filePath: string): Promise<string> {\n  return readFile(filePath, 'utf-8');\n}\n\n/**\n * Write content to file\n */\nexport async function writeFileContent(\n  filePath: string,\n  content: string\n): Promise<void> {\n  await writeFile(filePath, content, 'utf-8');\n}\n\n/**\n * Get file size in bytes\n */\nexport async function getFileSize(filePath: string): Promise<number> {\n  const stats = await stat(filePath);\n  return stats.size;\n}\n\n/**\n * Create a backup of a file\n */\nexport async function backupFile(filePath: string): Promise<string> {\n  const backupPath = `${filePath}.classpresso-backup`;\n  await copyFile(filePath, backupPath);\n  return backupPath;\n}\n\n/**\n * Get file stats for a list of files\n */\nexport async function getFileStats(filePaths: string[]): Promise<FileStats[]> {\n  const stats: FileStats[] = [];\n\n  for (const filePath of filePaths) {\n    try {\n      const size = await getFileSize(filePath);\n      stats.push({\n        path: filePath,\n        originalSize: size,\n        modified: false,\n      });\n    } catch {\n      // Skip files that can't be read\n    }\n  }\n\n  return stats;\n}\n\n/**\n * Check if a file is a JavaScript file\n */\nexport function isJSFile(filePath: string): boolean {\n  return /\\.(js|mjs|cjs)$/.test(filePath);\n}\n\n/**\n * Check if a file is a CSS file\n */\nexport function isCSSFile(filePath: string): boolean {\n  return /\\.css$/.test(filePath);\n}\n\n/**\n * Check if a file is an HTML file\n */\nexport function isHTMLFile(filePath: string): boolean {\n  return /\\.(html|htm)$/.test(filePath);\n}\n\n/**\n * Check if a file is an RSC payload\n */\nexport function isRSCFile(filePath: string): boolean {\n  return /\\.rsc$/.test(filePath);\n}\n\n/**\n * Check if a file matches any exclusion pattern\n * Patterns can be glob-style (e.g., \"**\\/Demo*\", \"**\\/ClassTester*\")\n */\nexport function shouldExcludeFile(filePath: string, excludePatterns: string[]): boolean {\n  if (!excludePatterns || excludePatterns.length === 0) {\n    return false;\n  }\n\n  // Normalize path for consistent matching\n  const normalizedPath = filePath.replace(/\\\\/g, '/');\n\n  for (const pattern of excludePatterns) {\n    // Convert glob pattern to regex\n    // Support: ** (any path), * (any chars), ? (single char)\n    const regexPattern = pattern\n      .replace(/\\\\/g, '/')\n      .replace(/\\*\\*/g, '{{DOUBLESTAR}}')\n      .replace(/\\*/g, '[^/]*')\n      .replace(/\\?/g, '.')\n      .replace(/{{DOUBLESTAR}}/g, '.*');\n\n    const regex = new RegExp(regexPattern);\n    if (regex.test(normalizedPath)) {\n      return true;\n    }\n  }\n\n  return false;\n}\n\n/**\n * Filter files to exclude those matching exclusion patterns\n */\nexport function filterExcludedFiles(files: string[], excludePatterns: string[]): string[] {\n  if (!excludePatterns || excludePatterns.length === 0) {\n    return files;\n  }\n\n  return files.filter(filePath => !shouldExcludeFile(filePath, excludePatterns));\n}\n","/**\n * Regex utilities for Classpresso\n */\n\n/**\n * Escape special regex characters in a string\n */\nexport function escapeRegex(str: string): string {\n  return str.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n}\n\n/**\n * Patterns to match className in various contexts\n */\nexport const CLASS_PATTERNS = {\n  // JSX: className=\"...\"\n  jsxDouble: /className\\s*=\\s*\"([^\"]+)\"/g,\n\n  // JSX: className='...'\n  jsxSingle: /className\\s*=\\s*'([^']+)'/g,\n\n  // React createElement: className:\"...\"\n  createElementDouble: /className\\s*:\\s*\"([^\"]+)\"/g,\n\n  // React createElement: className:'...'\n  createElementSingle: /className\\s*:\\s*'([^']+)'/g,\n\n  // Minified: \"className\",\"...\"\n  minifiedComma: /\"className\"\\s*,\\s*\"([^\"]+)\"/g,\n\n  // HTML: class=\"...\"\n  htmlDouble: /\\bclass\\s*=\\s*\"([^\"]+)\"/g,\n\n  // HTML: class='...'\n  htmlSingle: /\\bclass\\s*=\\s*'([^']+)'/g,\n\n  // HTML entity encoded: class=&quot;...&quot;\n  htmlEntityDouble: /\\bclass=&quot;([^&]+)&quot;/g,\n\n  // HTML entity encoded: class=&#34;...&#34; (numeric entity)\n  htmlNumericDouble: /\\bclass=&#34;([^&]+)&#34;/g,\n\n  // RSC payload: \\\"className\\\":\\\"...\\\" (escaped JSON in Next.js RSC payloads)\n  rscPayload: /\\\\\"className\\\\\"\\s*:\\s*\\\\\"([^\"\\\\]+)\\\\\"/g,\n\n  // Vue/Quasar createElement: class:\"...\" (Vue uses 'class' not 'className')\n  vueCreateElementDouble: /\\bclass\\s*:\\s*\"([^\"]+)\"/g,\n\n  // Vue/Quasar createElement: class:'...'\n  vueCreateElementSingle: /\\bclass\\s*:\\s*'([^']+)'/g,\n\n  // JSX: className=`...` (static template literal, no dynamic expressions)\n  jsxBacktick: /className\\s*=\\s*`([^`$]+)`/g,\n\n  // React createElement: className:`...` (static template literal, no dynamic expressions)\n  createElementBacktick: /className\\s*:\\s*`([^`$]+)`/g,\n};\n\n/**\n * All patterns combined for extraction\n */\nexport const ALL_CLASS_PATTERNS = [\n  CLASS_PATTERNS.jsxDouble,\n  CLASS_PATTERNS.jsxSingle,\n  CLASS_PATTERNS.createElementDouble,\n  CLASS_PATTERNS.createElementSingle,\n  CLASS_PATTERNS.minifiedComma,\n  CLASS_PATTERNS.htmlDouble,\n  CLASS_PATTERNS.htmlSingle,\n  CLASS_PATTERNS.htmlEntityDouble,\n  CLASS_PATTERNS.htmlNumericDouble,\n  CLASS_PATTERNS.rscPayload,\n  CLASS_PATTERNS.vueCreateElementDouble,\n  CLASS_PATTERNS.vueCreateElementSingle,\n  CLASS_PATTERNS.jsxBacktick,\n  CLASS_PATTERNS.createElementBacktick,\n];\n\n/**\n * Check if a class string contains dynamic expressions\n */\nexport function isDynamicClassString(classString: string): boolean {\n  // Template literal expression\n  if (classString.includes('${')) return true;\n\n  // Ternary operator (likely dynamic)\n  if (/\\s*\\?\\s*/.test(classString) && classString.includes(':')) return true;\n\n  // Function call\n  if (/\\w+\\s*\\(/.test(classString)) return true;\n\n  // Variable reference (camelCase or UPPER_CASE that's not a valid class)\n  if (/^[a-z][a-zA-Z0-9]*$/.test(classString) && !classString.includes('-')) return true;\n\n  return false;\n}\n\n/**\n * Patterns to extract the static base portion of template literal class names\n * These capture the static classes before the ${...} dynamic expression\n */\nexport const DYNAMIC_BASE_PATTERNS = [\n  // className:`base classes ${...}`\n  /className\\s*:\\s*`([^`$]+)\\s*\\$\\{/g,\n  // className=`base classes ${...}` (JSX)\n  /className\\s*=\\s*`([^`$]+)\\s*\\$\\{/g,\n  // class:`base classes ${...}` (rare but possible)\n  /\\bclass\\s*:\\s*`([^`$]+)\\s*\\$\\{/g,\n];\n\n/**\n * Patterns to extract the static base portion of .concat() calls\n * Minified React often uses \"\".concat(\"base\", \" \", variant) for className\n * These are treated as dynamic and should be skipped\n */\nexport const CONCAT_BASE_PATTERNS = [\n  // className:\"\".concat(\"base classes\",...) - the base before concat\n  /className\\s*:\\s*\"\"\\s*\\.concat\\s*\\(\\s*\"([^\"]+)\"/g,\n  // className:''.concat('base classes',...)\n  /className\\s*:\\s*''\\s*\\.concat\\s*\\(\\s*'([^']+)'/g,\n];\n\n/**\n * Extract static base patterns from .concat() calls\n * Returns the static class portion from the first concat argument\n */\nexport function extractConcatBaseStrings(content: string): string[] {\n  const results: string[] = [];\n\n  for (const pattern of CONCAT_BASE_PATTERNS) {\n    pattern.lastIndex = 0;\n    let match;\n    while ((match = pattern.exec(content)) !== null) {\n      const baseString = match[1]?.trim();\n      if (baseString && baseString.length > 0) {\n        results.push(baseString);\n      }\n    }\n  }\n\n  return results;\n}\n\n/**\n * Extract static base patterns from template literals with dynamic expressions\n * Returns the static class portion before ${...}\n */\nexport function extractDynamicBaseStrings(\n  content: string\n): string[] {\n  const results: string[] = [];\n\n  for (const pattern of DYNAMIC_BASE_PATTERNS) {\n    pattern.lastIndex = 0;\n    let match;\n    while ((match = pattern.exec(content)) !== null) {\n      const baseString = match[1]?.trim();\n      if (baseString && baseString.length > 0) {\n        results.push(baseString);\n      }\n    }\n  }\n\n  return results;\n}\n\n/**\n * Create a replacement pattern for a class string\n */\nexport function createReplacementPatterns(original: string): RegExp[] {\n  const escaped = escapeRegex(original);\n\n  return [\n    new RegExp(`(className\\\\s*=\\\\s*)\"${escaped}\"`, 'g'),\n    new RegExp(`(className\\\\s*=\\\\s*)'${escaped}'`, 'g'),\n    new RegExp(`(className\\\\s*:\\\\s*)\"${escaped}\"`, 'g'),\n    new RegExp(`(className\\\\s*:\\\\s*)'${escaped}'`, 'g'),\n    new RegExp(`(\"className\"\\\\s*,\\\\s*)\"${escaped}\"`, 'g'),\n    new RegExp(`(class\\\\s*=\\\\s*)\"${escaped}\"`, 'g'),\n    new RegExp(`(class\\\\s*=\\\\s*)'${escaped}'`, 'g'),\n    // HTML entity encoded quotes\n    new RegExp(`(class=&quot;)${escaped}(&quot;)`, 'g'),\n    new RegExp(`(class=&#34;)${escaped}(&#34;)`, 'g'),\n    // Vue/Quasar class: syntax\n    new RegExp(`(\\\\bclass\\\\s*:\\\\s*)\"${escaped}\"`, 'g'),\n    new RegExp(`(\\\\bclass\\\\s*:\\\\s*)'${escaped}'`, 'g'),\n    // Static template literals\n    new RegExp(`(className\\\\s*=\\\\s*)\\`${escaped}\\``, 'g'),\n    new RegExp(`(className\\\\s*:\\\\s*)\\`${escaped}\\``, 'g'),\n  ];\n}\n","/**\n * Scanner - Extracts className patterns from build output\n */\n\nimport type {\n  ClasspressoConfig,\n  ClassOccurrence,\n  FileLocation,\n  ScanResult,\n  FileStats,\n  DynamicBasePattern,\n  SourceFileType,\n} from '../types/index.js';\nimport {\n  findFiles,\n  readFileContent,\n  getFileSize,\n  isJSFile,\n  isHTMLFile,\n  isRSCFile,\n  DEFAULT_PATTERNS,\n  filterExcludedFiles,\n} from '../utils/files.js';\nimport { ALL_CLASS_PATTERNS, isDynamicClassString, extractDynamicBaseStrings, extractConcatBaseStrings } from '../utils/regex.js';\n\n/**\n * Determine the source file type\n */\nfunction getSourceFileType(filePath: string): SourceFileType {\n  if (isHTMLFile(filePath)) return 'html';\n  if (isRSCFile(filePath)) return 'rsc';\n  return 'js';\n}\n\n/**\n * Check if pattern A's classes are a proper subset of pattern B's classes.\n * A is a proper subset of B if all classes in A are in B, and B has more classes.\n */\nexport function isProperSubset(classesA: string[], classesB: string[]): boolean {\n  if (classesA.length >= classesB.length) return false;\n\n  const setB = new Set(classesB);\n  return classesA.every(cls => setB.has(cls));\n}\n\n/**\n * Detect patterns that appear in JS but are subsets of HTML patterns.\n * These are likely className props that get merged with component classes.\n */\nexport function detectMergeablePatterns(\n  occurrences: Map<string, ClassOccurrence>\n): Set<string> {\n  const mergeablePatterns = new Set<string>();\n\n  // Get all JS-only patterns and HTML patterns\n  const jsPatterns: ClassOccurrence[] = [];\n  const htmlPatterns: ClassOccurrence[] = [];\n\n  for (const [, occurrence] of occurrences) {\n    if (occurrence.sourceTypes.has('js')) {\n      jsPatterns.push(occurrence);\n    }\n    if (occurrence.sourceTypes.has('html') || occurrence.sourceTypes.has('rsc')) {\n      htmlPatterns.push(occurrence);\n    }\n  }\n\n  // For each JS pattern, check if it's a subset of any HTML pattern\n  for (const jsPattern of jsPatterns) {\n    for (const htmlPattern of htmlPatterns) {\n      if (isProperSubset(jsPattern.classes, htmlPattern.classes)) {\n        // This JS pattern's classes appear as part of a larger HTML pattern\n        // It's likely a className prop that gets merged\n        mergeablePatterns.add(jsPattern.normalizedKey);\n        break;\n      }\n    }\n  }\n\n  return mergeablePatterns;\n}\n\n/**\n * Check if any class in a list contains a dynamic library prefix.\n * These are classes generated at runtime by libraries like lucide-react, heroicons, etc.\n */\nexport function containsDynamicPrefix(\n  classes: string[],\n  dynamicPrefixes: string[]\n): boolean {\n  for (const cls of classes) {\n    for (const prefix of dynamicPrefixes) {\n      // For prefixes ending with '-' (e.g., \"fa-\", \"icon-\"), just check startsWith\n      if (prefix.endsWith('-')) {\n        if (cls.startsWith(prefix)) {\n          return true;\n        }\n      } else {\n        // For prefixes without '-' (e.g., \"lucide\", \"fas\", \"far\", \"fab\"),\n        // match exact or followed by '-' to avoid false positives\n        // e.g., \"fab\" matches \"fab\" or \"fab-icon\", but not \"fabric\"\n        if (cls === prefix || cls.startsWith(prefix + '-')) {\n          return true;\n        }\n      }\n    }\n  }\n  return false;\n}\n\n/**\n * Check if a class occurrence is safe for SSR hydration.\n * A pattern is hydration-safe if it appears in BOTH:\n * - Server context (html or rsc)\n * - Client context (js)\n *\n * If a pattern only appears in one context, transforming it would cause\n * React hydration mismatches.\n */\nexport function isHydrationSafe(occurrence: ClassOccurrence): boolean {\n  const hasServerContext = occurrence.sourceTypes.has('html') || occurrence.sourceTypes.has('rsc');\n  const hasClientContext = occurrence.sourceTypes.has('js');\n\n  // Must appear in both server and client contexts to be safe\n  return hasServerContext && hasClientContext;\n}\n\n/**\n * Returns true for classes whose CSS rule cannot be expressed as flat declarations\n * on a single-class selector — i.e., classes that require a media query wrapper,\n * an @container wrapper, or a combinator child selector to function correctly.\n *\n * Consolidating these into a plain `.cp-xxx { ... }` rule silently drops the\n * wrapping context, producing a visually broken build with no warning.\n *\n * Detected categories:\n *  - Any variant prefix:    md:, hover:, dark:, focus:, group-hover:, data-[x]:, etc.\n *  - Container queries:     @sm, @md, @[800px], etc.\n *  - Combinator utilities:  space-x-*, space-y-*, divide-x-*, divide-y-*\n */\nexport function isNonFlattenableClass(className: string): boolean {\n  // Variant prefixes — any colon in the class name means it needs a wrapper\n  if (className.includes(':')) return true;\n  // Container queries\n  if (className.startsWith('@')) return true;\n  // Combinator utilities that generate child selectors like `.space-y-6 > :not(:last-child)`\n  if (/^space-[xy]/.test(className)) return true;\n  if (/^divide-[xy]/.test(className)) return true;\n  return false;\n}\n\n/**\n * Check if a class should be excluded based on config\n */\nexport function shouldExcludeClass(\n  className: string,\n  exclude: ClasspressoConfig['exclude']\n): boolean {\n  // Check prefix patterns\n  if (exclude.prefixes) {\n    for (const prefix of exclude.prefixes) {\n      if (className.startsWith(prefix)) return true;\n    }\n  }\n\n  // Check suffix patterns\n  if (exclude.suffixes) {\n    for (const suffix of exclude.suffixes) {\n      if (className.endsWith(suffix)) return true;\n    }\n  }\n\n  // Check exact matches\n  if (exclude.classes) {\n    if (exclude.classes.includes(className)) return true;\n  }\n\n  // Check regex patterns\n  if (exclude.patterns) {\n    for (const pattern of exclude.patterns) {\n      if (pattern.test(className)) return true;\n    }\n  }\n\n  return false;\n}\n\n/**\n * Normalize a class string for consistent comparison\n * - Splits into individual classes\n * - Removes excluded classes\n * - Sorts alphabetically\n * - Joins back together\n */\nexport function normalizeClassString(\n  classString: string,\n  exclude: ClasspressoConfig['exclude'],\n  excludeNonFlattenable: boolean = false\n): { normalized: string; classes: string[]; excludedClasses: string[] } {\n  const allClasses = classString.split(/\\s+/).filter(Boolean);\n  const includedClasses: string[] = [];\n  const excludedClasses: string[] = [];\n\n  for (const cls of allClasses) {\n    if (shouldExcludeClass(cls, exclude) || (excludeNonFlattenable && isNonFlattenableClass(cls))) {\n      excludedClasses.push(cls);\n    } else {\n      includedClasses.push(cls);\n    }\n  }\n\n  // Sort for consistent comparison\n  const sorted = [...includedClasses].sort();\n  return {\n    normalized: sorted.join(' '),\n    classes: includedClasses,\n    excludedClasses,\n  };\n}\n\n/**\n * Extract class strings from file content\n */\nexport function extractClassStrings(\n  content: string,\n  filePath: string\n): Array<{ classString: string; location: FileLocation }> {\n  const results: Array<{ classString: string; location: FileLocation }> = [];\n  const seen = new Set<string>();\n\n  for (const pattern of ALL_CLASS_PATTERNS) {\n    // Reset regex lastIndex\n    pattern.lastIndex = 0;\n\n    let match;\n    while ((match = pattern.exec(content)) !== null) {\n      const classString = match[1];\n\n      // Skip empty strings\n      if (!classString || !classString.trim()) continue;\n\n      // Skip dynamic expressions\n      if (isDynamicClassString(classString)) continue;\n\n      // Skip if already seen at this exact position (same file and character offset)\n      // This allows duplicate strings in the same file (e.g., bundled components)\n      // while avoiding double-counting from overlapping regex patterns\n      const key = `${filePath}:${match.index}:${classString}`;\n      if (seen.has(key)) continue;\n      seen.add(key);\n\n      // Calculate approximate line number\n      const beforeMatch = content.substring(0, match.index);\n      const line = (beforeMatch.match(/\\n/g) || []).length + 1;\n\n      results.push({\n        classString: classString.trim(),\n        location: {\n          filePath,\n          line,\n        },\n      });\n    }\n  }\n\n  return results;\n}\n\n/**\n * Scan build directory for className patterns\n */\nexport async function scanBuildOutput(\n  config: ClasspressoConfig\n): Promise<ScanResult> {\n  const occurrences = new Map<string, ClassOccurrence>();\n  const dynamicBasePatterns = new Map<string, DynamicBasePattern>();\n  const fileStats: FileStats[] = [];\n  const errors: string[] = [];\n\n  // Find all files to scan\n  const patterns = config.include.length > 0 ? config.include : DEFAULT_PATTERNS;\n  const allFiles = await findFiles(config.buildDir, patterns);\n\n  // Filter out excluded files\n  const files = filterExcludedFiles(allFiles, config.exclude.files || []);\n\n  if (config.verbose) {\n    console.log(`Found ${allFiles.length} files, scanning ${files.length} (${allFiles.length - files.length} excluded)`);\n  }\n\n  for (const filePath of files) {\n    try {\n      // Skip non-relevant file types\n      if (!isJSFile(filePath) && !isHTMLFile(filePath) && !isRSCFile(filePath)) {\n        continue;\n      }\n\n      const content = await readFileContent(filePath);\n      const size = await getFileSize(filePath);\n\n      fileStats.push({\n        path: filePath,\n        originalSize: size,\n        modified: false,\n      });\n\n      // Extract dynamic base patterns from JS files (for hydration safety)\n      // These include template literals with ${} and .concat() calls\n      if (isJSFile(filePath)) {\n        // Get bases from template literals: className:`base ${dynamic}`\n        const dynamicBases = extractDynamicBaseStrings(content);\n        // Get bases from concat calls: className:\"\".concat(\"base\", variant)\n        const concatBases = extractConcatBaseStrings(content);\n\n        // Combine all dynamic bases\n        const allDynamicBases = [...dynamicBases, ...concatBases];\n\n        for (const baseString of allDynamicBases) {\n          const { normalized, classes } = normalizeClassString(baseString, config.exclude, config.excludeNonFlattenableClasses);\n\n          // Skip if too few classes\n          if (classes.length < config.minClasses) continue;\n\n          const location: FileLocation = { filePath };\n\n          if (dynamicBasePatterns.has(normalized)) {\n            dynamicBasePatterns.get(normalized)!.locations.push(location);\n          } else {\n            dynamicBasePatterns.set(normalized, {\n              baseClasses: classes,\n              normalizedKey: normalized,\n              locations: [location],\n            });\n          }\n        }\n      }\n\n      const classStrings = extractClassStrings(content, filePath);\n      const sourceType = getSourceFileType(filePath);\n\n      for (const { classString, location } of classStrings) {\n        const { normalized, classes, excludedClasses } = normalizeClassString(\n          classString,\n          config.exclude,\n          config.excludeNonFlattenableClasses\n        );\n\n        // Skip if all classes were excluded\n        if (classes.length === 0) continue;\n\n        // Skip single classes (no benefit to consolidate)\n        if (classes.length < config.minClasses) continue;\n\n        // Skip patterns containing dynamic library prefixes (e.g., lucide-react, heroicons)\n        // These are generated at runtime and transforming them causes hydration mismatches\n        if (config.excludeDynamicPatterns && containsDynamicPrefix(classes, config.dynamicPrefixes)) {\n          continue;\n        }\n\n        if (occurrences.has(normalized)) {\n          const existing = occurrences.get(normalized)!;\n          existing.count++;\n          existing.locations.push(location);\n          existing.sourceTypes.add(sourceType);\n        } else {\n          occurrences.set(normalized, {\n            classString,\n            normalizedKey: normalized,\n            count: 1,\n            locations: [location],\n            classes,\n            excludedClasses,\n            sourceTypes: new Set([sourceType]),\n          });\n        }\n      }\n    } catch (err) {\n      errors.push(`Error scanning ${filePath}: ${err}`);\n    }\n  }\n\n  // Detect patterns that are likely className props that get merged\n  const mergeablePatterns = detectMergeablePatterns(occurrences);\n\n  if (config.verbose && mergeablePatterns.size > 0) {\n    console.log(`Found ${mergeablePatterns.size} patterns that appear to be merged className props`);\n  }\n\n  return {\n    occurrences,\n    files: fileStats,\n    errors,\n    dynamicBasePatterns,\n    mergeablePatterns,\n  };\n}\n","/**\n * Transformer - Replaces class patterns in build output\n */\n\nimport type { ClassMapping, TransformResult, ClasspressoConfig, DynamicBasePattern } from '../types/index.js';\nimport {\n  findFiles,\n  readFileContent,\n  writeFileContent,\n  backupFile,\n  isJSFile,\n  isHTMLFile,\n  isRSCFile,\n  DEFAULT_PATTERNS,\n  filterExcludedFiles,\n} from '../utils/files.js';\nimport { escapeRegex } from '../utils/regex.js';\nimport { normalizeClassString } from './scanner.js';\n\ninterface MatchPattern {\n  regex: RegExp;\n  supportsDataAttr: boolean;\n}\n\n/**\n * Check if a set of classes is a superset of any dynamic base pattern\n * This helps prevent hydration mismatches in React/Next.js\n */\nfunction isSupersetOfDynamicBase(\n  classes: string[],\n  dynamicBasePatterns: Map<string, DynamicBasePattern>\n): boolean {\n  const classSet = new Set(classes);\n\n  for (const [, pattern] of dynamicBasePatterns) {\n    // Check if all base classes are present in the target classes\n    const allBasePresent = pattern.baseClasses.every(cls => classSet.has(cls));\n\n    // If all base classes are present and target has MORE classes, it's a superset\n    if (allBasePresent && classes.length > pattern.baseClasses.length) {\n      return true;\n    }\n  }\n\n  return false;\n}\n\n/**\n * Check if a set of classes exactly matches any dynamic base pattern\n */\nfunction matchesDynamicBase(\n  classes: string[],\n  dynamicBasePatterns: Map<string, DynamicBasePattern>\n): boolean {\n  const classSet = new Set(classes);\n\n  for (const [, pattern] of dynamicBasePatterns) {\n    if (classes.length !== pattern.baseClasses.length) continue;\n\n    const allMatch = pattern.baseClasses.every(cls => classSet.has(cls));\n    if (allMatch) return true;\n  }\n\n  return false;\n}\n\n/**\n * Build a regex pattern to match a class string in various contexts\n */\nfunction buildMatchPatterns(classString: string): MatchPattern[] {\n  const escaped = escapeRegex(classString);\n\n  return [\n    // className=\"...\" (JSX/HTML) - supports data attributes\n    { regex: new RegExp(`(className\\\\s*=\\\\s*\")${escaped}(\")`,'g'), supportsDataAttr: true },\n    { regex: new RegExp(`(className\\\\s*=\\\\s*')${escaped}(')`,'g'), supportsDataAttr: true },\n\n    // className:\"...\" (React createElement) - no data attr support\n    { regex: new RegExp(`(className\\\\s*:\\\\s*\")${escaped}(\")`,'g'), supportsDataAttr: false },\n    { regex: new RegExp(`(className\\\\s*:\\\\s*')${escaped}(')`,'g'), supportsDataAttr: false },\n\n    // Template literals: className:`...` (static content only)\n    { regex: new RegExp(`(className\\\\s*:\\\\s*\\`)${escaped}(\\`)`,'g'), supportsDataAttr: false },\n\n    // Template literals with dynamic suffix: className:`... ${...}`\n    // Matches static prefix before ${...} expression\n    { regex: new RegExp(`(className\\\\s*:\\\\s*\\`)${escaped}( \\\\$\\\\{)`,'g'), supportsDataAttr: false },\n\n    // \"className\",\"...\" (minified) - no data attr support\n    { regex: new RegExp(`(\"className\"\\\\s*,\\\\s*\")${escaped}(\")`,'g'), supportsDataAttr: false },\n\n    // class=\"...\" (HTML) - supports data attributes\n    { regex: new RegExp(`(\\\\bclass\\\\s*=\\\\s*\")${escaped}(\")`,'g'), supportsDataAttr: true },\n    { regex: new RegExp(`(\\\\bclass\\\\s*=\\\\s*')${escaped}(')`,'g'), supportsDataAttr: true },\n\n    // class:\"...\" (Vue/Quasar createElement) - no data attr support\n    { regex: new RegExp(`(\\\\bclass\\\\s*:\\\\s*\")${escaped}(\")`,'g'), supportsDataAttr: false },\n    { regex: new RegExp(`(\\\\bclass\\\\s*:\\\\s*')${escaped}(')`,'g'), supportsDataAttr: false },\n\n    // HTML entity encoded: class=&quot;...&quot; - supports data attributes\n    { regex: new RegExp(`(class=&quot;)${escaped}(&quot;)`,'g'), supportsDataAttr: true },\n    { regex: new RegExp(`(class=&#34;)${escaped}(&#34;)`,'g'), supportsDataAttr: true },\n\n    // RSC payload (escaped JSON in HTML): \\\"className\\\":\\\"...\\\"\n    // This is used in Next.js self.__next_f.push() payloads\n    { regex: new RegExp(`(\\\\\\\\\"className\\\\\\\\\"\\\\s*:\\\\s*\\\\\\\\\")${escaped}(\\\\\\\\\")`, 'g'), supportsDataAttr: false },\n  ];\n}\n\n/**\n * Replace a single class pattern in content\n */\nfunction replacePattern(\n  content: string,\n  originalClasses: string,\n  consolidated: string,\n  excludedClasses: string[],\n  originalClassList: string[],\n  addDataAttributes: boolean\n): { content: string; replacements: number } {\n  let replacements = 0;\n  let result = content;\n\n  // Build the replacement string (consolidated + excluded classes)\n  const replacement = excludedClasses.length > 0\n    ? `${consolidated} ${excludedClasses.join(' ')}`\n    : consolidated;\n\n  // Build the data attribute string\n  const dataAttr = addDataAttributes\n    ? ` data-cp-original=\"${originalClassList.join(' ')}\"`\n    : '';\n\n  // Try exact match first\n  const patterns = buildMatchPatterns(originalClasses);\n\n  for (const { regex: pattern, supportsDataAttr } of patterns) {\n    const beforeLength = result.length;\n    const suffix = (addDataAttributes && supportsDataAttr) ? dataAttr : '';\n    result = result.replace(pattern, `$1${replacement}$2${suffix}`);\n    if (result.length !== beforeLength) {\n      // Count replacements (approximate)\n      const matches = content.match(pattern);\n      if (matches) replacements += matches.length;\n    }\n  }\n\n  return { content: result, replacements };\n}\n\n/**\n * Find all variations of a class pattern that should be replaced\n * This handles cases where classes appear in different orders\n */\nfunction findClassVariations(\n  content: string,\n  mapping: ClassMapping,\n  config: ClasspressoConfig\n): string[] {\n  const variations: string[] = [];\n  const targetClasses = new Set(mapping.classes);\n\n  // Create regex patterns to find className attributes (including HTML entity encoded and template literals)\n  const classAttrPatterns = [\n    /(?:className|class)\\s*[=:]\\s*[\"']([^\"']+)[\"']/g,\n    /class=&quot;([^&]+)&quot;/g,\n    /class=&#34;([^&]+)&#34;/g,\n    // Template literals - static only: className:`...`\n    /(?:className|class)\\s*:\\s*`([^`$]+)`/g,\n    // Template literals with dynamic suffix: className:`... ${...}`\n    // Captures the static part before the ${\n    /(?:className|class)\\s*:\\s*`([^`$]+) \\$\\{/g,\n    // RSC payload (escaped JSON in HTML): \\\"className\\\":\\\"...\\\"\n    // Used in Next.js self.__next_f.push() payloads\n    /\\\\\"className\\\\\"\\s*:\\s*\\\\\"([^\"\\\\]+)\\\\\"/g,\n  ];\n\n  for (const classAttrRegex of classAttrPatterns) {\n    classAttrRegex.lastIndex = 0;\n    let match;\n    while ((match = classAttrRegex.exec(content)) !== null) {\n      const classString = match[1];\n      const { classes } = normalizeClassString(classString, config.exclude);\n\n      // Check if this class string contains all the target classes\n      if (classes.length >= targetClasses.size) {\n        const classSet = new Set(classes);\n        let allPresent = true;\n\n        for (const targetClass of targetClasses) {\n          if (!classSet.has(targetClass)) {\n            allPresent = false;\n            break;\n          }\n        }\n\n        // If all target classes are present and it's an exact match\n        if (allPresent && classes.length === targetClasses.size) {\n          variations.push(classString);\n        }\n      }\n    }\n  }\n\n  return [...new Set(variations)];\n}\n\n/**\n * Transform a single file\n */\nasync function transformFile(\n  filePath: string,\n  mappings: ClassMapping[],\n  config: ClasspressoConfig,\n  dryRun: boolean,\n  dynamicBasePatterns: Map<string, DynamicBasePattern>,\n  mergeablePatterns: Set<string>\n): Promise<{ modified: boolean; replacements: number; skippedForHydration: number; error?: string }> {\n  try {\n    let content = await readFileContent(filePath);\n    let totalReplacements = 0;\n    let skippedForHydration = 0;\n    const originalContent = content;\n    const isJS = isJSFile(filePath);\n\n    for (const mapping of mappings) {\n      // Skip patterns that would cause hydration mismatches (SSR mode only)\n      // In non-SSR builds there is no server-rendered HTML to reconcile against,\n      // so template-literal base patterns pose no hydration risk.\n      if (config.ssr && dynamicBasePatterns.size > 0) {\n        // Skip if the pattern is a superset of OR exactly matches a dynamic base\n        // This prevents hydration mismatches in React/Next.js where:\n        // - HTML has rendered result: \"px-4 py-2 bg-blue\" (superset of base)\n        // - JS has template literal: `px-4 py-2 ${dynamic}` (base pattern)\n        // - Static JS may also have: \"px-4 py-2 bg-blue\" (same as HTML)\n        // All must stay untransformed to match at hydration time\n        const isSuperset = isSupersetOfDynamicBase(mapping.classes, dynamicBasePatterns);\n        const isExact = matchesDynamicBase(mapping.classes, dynamicBasePatterns);\n\n        if (isSuperset || isExact) {\n          skippedForHydration++;\n          continue;\n        }\n      }\n\n      // Skip mergeable patterns in JS files (SSR mode only)\n      // These are patterns that appear in JS as className props but get merged\n      // with component-internal classes in the HTML output during SSR.\n      // In non-SSR builds, className props are applied client-side only and\n      // there is no server-rendered HTML to cause a mismatch.\n      // NOTE: In SSR mode, mergeable patterns are also filtered at pattern detection\n      // time (pattern-detector.ts) to ensure consistent transformation across files.\n      if (config.ssr && isJS && mergeablePatterns.has(mapping.original)) {\n        skippedForHydration++;\n        continue;\n      }\n\n      // Find all variations of this pattern in the file\n      const variations = findClassVariations(content, mapping, config);\n\n      for (const variation of variations) {\n        const { content: newContent, replacements } = replacePattern(\n          content,\n          variation,\n          mapping.consolidated,\n          mapping.excludedClasses,\n          mapping.classes,\n          config.dataAttributes\n        );\n        content = newContent;\n        totalReplacements += replacements;\n      }\n    }\n\n    const modified = content !== originalContent;\n\n    if (modified && !dryRun) {\n      if (config.backup) {\n        await backupFile(filePath);\n      }\n      await writeFileContent(filePath, content);\n    }\n\n    return { modified, replacements: totalReplacements, skippedForHydration };\n  } catch (err) {\n    return {\n      modified: false,\n      replacements: 0,\n      skippedForHydration: 0,\n      error: `Error transforming ${filePath}: ${err}`,\n    };\n  }\n}\n\n/**\n * Transform all files in the build output\n */\nexport async function transformBuildOutput(\n  mappings: ClassMapping[],\n  config: ClasspressoConfig,\n  dryRun: boolean = false,\n  dynamicBasePatterns: Map<string, DynamicBasePattern> = new Map(),\n  mergeablePatterns: Set<string> = new Set()\n): Promise<TransformResult> {\n  if (config.verbose) {\n    if (dynamicBasePatterns.size > 0) {\n      console.log(`  ℹ Found ${dynamicBasePatterns.size} dynamic base patterns (template literals)`);\n    }\n    if (mergeablePatterns.size > 0) {\n      console.log(`  ℹ Found ${mergeablePatterns.size} mergeable patterns (className props)`);\n    }\n  }\n\n  const patterns = config.include.length > 0 ? config.include : DEFAULT_PATTERNS;\n  const allFiles = await findFiles(config.buildDir, patterns);\n\n  // Filter out excluded files\n  const files = filterExcludedFiles(allFiles, config.exclude.files || []);\n\n  if (config.verbose && allFiles.length !== files.length) {\n    console.log(`  ℹ Excluded ${allFiles.length - files.length} files from transformation`);\n  }\n\n  let filesModified = 0;\n  let totalBytesChanged = 0;\n  let totalSkippedForHydration = 0;\n  const errors: string[] = [];\n\n  for (const filePath of files) {\n    // Only transform JS, HTML, and RSC files\n    if (!isJSFile(filePath) && !isHTMLFile(filePath) && !isRSCFile(filePath)) {\n      continue;\n    }\n\n    const result = await transformFile(filePath, mappings, config, dryRun, dynamicBasePatterns, mergeablePatterns);\n\n    if (result.error) {\n      errors.push(result.error);\n    }\n\n    if (result.modified) {\n      filesModified++;\n      // Estimate bytes changed based on replacements\n      totalBytesChanged += result.replacements * 10; // Rough estimate\n    }\n\n    totalSkippedForHydration += result.skippedForHydration;\n  }\n\n  if (config.verbose && totalSkippedForHydration > 0) {\n    console.log(`Skipped ${totalSkippedForHydration} pattern transformations to prevent hydration mismatches`);\n  }\n\n  return {\n    filesModified,\n    bytesChanged: totalBytesChanged,\n    errors,\n  };\n}\n"]}