UNPKG

weapp-tailwindcss

Version:

把 tailwindcss 原子化样式思想,带给小程序开发者们! bring tailwindcss to miniprogram developers!

1,520 lines 118 kB
import { resolveUniUtsPlatform as resolveUniUtsPlatform$1 } from "./framework.js"; import { c as withCssMacroStyleOptions, i as hasCssMacroTailwindV4Source, o as transformCssMacroCss, s as transformCssMacroTailwindV4Source, t as hasCssMacroStyleOptions } from "./auto-2dg_uhEJ.js"; import { n as _defineProperty, t as omitUndefined } from "./object-Bvy6-w9r.js"; import "./utils-MVwpU07P.js"; import { createRequire } from "node:module"; import fs, { existsSync, readFileSync, readdirSync, realpathSync } from "node:fs"; import path from "node:path"; import process from "node:process"; import { createTailwindGenerationSession, createTailwindV4Engine, extractRawCandidates, loadTailwindV4DesignSystem, resolveProjectSourceFiles, resolveTailwindV4Source, resolveValidTailwindV4Candidates as resolveValidTailwindV4Candidates$1 } from "@tailwindcss-mangle/engine"; import { analyzeTailwindCssDirectives, createStyleHandler, filterExistingCssRules, finalizeMiniProgramCss, hasMiniProgramCssSpecificityPlaceholders, isTailwindCssGenerationDirective, isTailwindCssImportAtRule, isTailwindCssPackageJsonImportRequest, normalizeTailwindCssImportRequest, normalizeTailwindcssWebRpxDeclarations, parseTailwindCssConfigRequest, parseTailwindCssDirectiveRequest, postcss, protectDynamicColorMixAlpha, pruneMiniProgramGeneratedCss, pruneMiniProgramGeneratedCss as pruneMiniProgramGeneratedCss$1, removeUnsupportedCascadeLayers, removeUnsupportedMiniProgramAtRules, stripMiniProgramCssSpecificityPlaceholders } from "@weapp-tailwindcss/postcss"; import { LRUCache } from "lru-cache"; import { stat } from "node:fs/promises"; import micromatch from "micromatch"; //#region src/runtime-branch/generator-target-env.ts const explicitGeneratorTargetEnvKeys = ["WEAPP_TW_TARGET", "WEAPP_TAILWINDCSS_TARGET"]; const uniWebPlatformEnvKeys = ["UNI_PLATFORM", "UNI_UTS_PLATFORM"]; const mpxWebPlatformEnvKeys = ["MPX_CLI_MODE", "MPX_CURRENT_TARGET_MODE"]; function getEnvValue(key) { return typeof process === "undefined" ? void 0 : process.env[key]; } function normalizeGeneratorTargetValue(value) { return value === "weapp" || value === "web" ? value : void 0; } function isUniWebPlatform(value) { const normalized = value?.trim().toLowerCase(); return normalized === "h5" || normalized?.startsWith("web") === true; } function isUniAppWebViewPlatform(value) { const normalized = value?.trim().toLowerCase(); return normalized === "app" || normalized === "app-plus"; } function isUniNativeAppPlatform(value) { return (value?.trim().toLowerCase())?.startsWith("app-") === true; } function isMpxWebPlatform(value) { return value?.trim().toLowerCase() === "web"; } function inferGeneratorTargetFromExplicitEnv() { for (const key of explicitGeneratorTargetEnvKeys) { const target = normalizeGeneratorTargetValue(getEnvValue(key)); if (target !== void 0) return target; } } function shouldUseWebGeneratorTargetFromEnv() { return uniWebPlatformEnvKeys.some((key) => isUniWebPlatform(getEnvValue(key))) || isUniAppWebViewPlatform(getEnvValue("UNI_PLATFORM")) && !isUniNativeAppPlatform(getEnvValue("UNI_UTS_PLATFORM")) || mpxWebPlatformEnvKeys.some((key) => isMpxWebPlatform(getEnvValue(key))) || getEnvValue("TARO_ENV") === "h5"; } function shouldUseUniAppWebRpxCompatibility(appType) { return appType === "uni-app-vite" || appType === "uni-app-x" || shouldUseWebGeneratorTargetFromEnv(); } function shouldUseUniAppViteWebViewGeneratorTarget(appType, platform = getEnvValue("UNI_PLATFORM")) { return appType === "uni-app-vite" && isUniAppWebViewPlatform(platform); } function inferGeneratorTargetFromEnv() { return inferGeneratorTargetFromExplicitEnv() ?? (shouldUseWebGeneratorTargetFromEnv() ? "web" : "weapp"); } //#endregion //#region src/tailwindcss/v4-engine/candidates.ts const UNSUPPORTED_MINI_PROGRAM_TAILWIND_V4_CANDIDATE_RE = /(?:^|:)(?:group|peer|in|not-in)-[^\s:]*\/|(?:^|:)(?:in|not-in)-\[/; function isUnsupportedMiniProgramTailwindV4Candidate(candidate) { return UNSUPPORTED_MINI_PROGRAM_TAILWIND_V4_CANDIDATE_RE.test(candidate); } function filterUnsupportedMiniProgramTailwindV4Candidates(candidates) { if (!candidates) return; return new Set([...candidates].filter((candidate) => !isUnsupportedMiniProgramTailwindV4Candidate(candidate))); } //#endregion //#region src/tailwindcss/v4-engine/generator/rpx-candidates.ts const RPX_LENGTH_UTILITY_PATTERN = String.raw`text|border(?:-[trblxyse])?|bg|outline|ring`; const BARE_RPX_LENGTH_CANDIDATE_RE = new RegExp(String.raw`(^|:)(!?)(${RPX_LENGTH_UTILITY_PATTERN})-\[([-+]?(?:\d+|\d*\.\d+)rpx)\](.*)$`, "u"); const BARE_RPX_LENGTH_HINT_CANDIDATE_RE = new RegExp(String.raw`(?:^|:)!?(${RPX_LENGTH_UTILITY_PATTERN})-\[length:([-+]?(?:\d+|\d*\.\d+)rpx)\].*$`, "u"); const RPX_LENGTH_SELECTOR_RE = new RegExp(String.raw`(${RPX_LENGTH_UTILITY_PATTERN})-\\\[length\\:((?:\\[.+-]|[+\-.\d])+rpx)\\\]`, "g"); function normalizeRpxLengthCandidate(candidate) { return candidate.replace(BARE_RPX_LENGTH_CANDIDATE_RE, (_match, prefix, important, utility, value, suffix) => { return `${prefix}${important}${utility}-[length:${value}]${suffix}`; }); } function normalizeRpxLengthCandidates(candidates) { const normalized = /* @__PURE__ */ new Set(); const restoreCandidates = /* @__PURE__ */ new Map(); for (const candidate of candidates) { const normalizedCandidate = normalizeRpxLengthCandidate(candidate); normalized.add(normalizedCandidate); if (normalizedCandidate !== candidate) restoreCandidates.set(normalizedCandidate, candidate); } return { candidates: normalized, restoreCandidates }; } function restoreRpxLengthCandidates(candidates, restoreCandidates) { if (restoreCandidates.size === 0) return new Set(candidates); return new Set([...candidates].map((candidate) => restoreCandidates.get(candidate) ?? candidate)); } function normalizeCssEscapedRpxSelectorValue(value) { return value.replace(/\\([.+-])/g, "$1"); } function restoreRpxLengthCssSelectors(css, restoreCandidates) { if (restoreCandidates.size === 0 || !css.includes("\\[length\\:")) return css; const restoredUtilities = new Set([...restoreCandidates.keys()].map((candidate) => { const match = BARE_RPX_LENGTH_HINT_CANDIDATE_RE.exec(candidate); return match ? `${match[1]}:${match[2]}` : void 0; }).filter((value) => Boolean(value))); return css.replace(RPX_LENGTH_SELECTOR_RE, (match, utility, value) => { return restoredUtilities.has(`${utility}:${normalizeCssEscapedRpxSelectorValue(value)}`) ? `${utility}-\\[${value}\\]` : match; }); } const INCREMENTAL_GENERATE_ENTRY_CANDIDATES_MAX = 12e3; const INCREMENTAL_GENERATE_ENTRY_CSS_BYTES_MAX = 2 * 1024 * 1024; const incrementalGenerateCache = new LRUCache({ max: 8 }); const incrementalGenerateTaskCache = new LRUCache({ max: 32 }); function collectCandidates(candidates) { return new Set(candidates ?? []); } function hasRemovedCandidates(previousCandidates, nextCandidates) { for (const candidate of previousCandidates) if (!nextCandidates.has(candidate)) return true; return false; } function createStableJson(value) { if (value === void 0) return "undefined"; if (value === null || typeof value !== "object") return JSON.stringify(value); if (Array.isArray(value)) return `[${value.map((item) => createStableJson(item)).join(",")}]`; return `{${Object.keys(value).sort().map((key) => { const record = value; return `${JSON.stringify(key)}:${createStableJson(record[key])}`; }).join(",")}}`; } function createDependencyFingerprint(files) { return files.map((file) => { try { const stat = fs.statSync(file); return `${file}:${stat.size}:${stat.mtimeMs}`; } catch { return `${file}:missing`; } }).join("|"); } function createTailwindV4SourceCacheKey(source) { return [ source.projectRoot, source.base, createStableJson(source.baseFallbacks), source.css, createDependencyFingerprint(source.dependencies) ].join("\0"); } function createIncrementalGenerateCacheKey(source, target, styleOptions) { return [ createTailwindV4SourceCacheKey(source), target, createStableJson(styleOptions) ].join("\0"); } function createIncrementalGenerateTaskCacheKey(cacheKey, requestedCandidates, scanSources) { return [ cacheKey, scanSources === true ? "scan:1" : "scan:0", [...requestedCandidates].sort().join("\n") ].join("\0"); } function runIncrementalGenerateTask(cacheKey, requestedCandidates, scanSources, task) { const taskKey = createIncrementalGenerateTaskCacheKey(cacheKey, requestedCandidates, scanSources); const cachedTask = incrementalGenerateTaskCache.get(taskKey); if (cachedTask) return cachedTask; const promise = task(); incrementalGenerateTaskCache.set(taskKey, promise); promise.finally(() => { if (incrementalGenerateTaskCache.get(taskKey) === promise) incrementalGenerateTaskCache.delete(taskKey); }); return promise; } function createIncrementalDesignSystemPromise(source, cacheKey) { const promise = loadTailwindV4DesignSystem(source); promise.catch(() => { if (incrementalGenerateCache.get(cacheKey)?.designSystemPromise === promise) incrementalGenerateCache.delete(cacheKey); }); return promise; } function resolveTargetCandidates(candidates, target) { const collected = collectCandidates(candidates); return target === "weapp" ? filterUnsupportedMiniProgramTailwindV4Candidates(collected) : collected; } function collectSeenCandidates(generated) { return new Set(generated.classSet); } function createIncrementalStyleOptions(styleOptions) { return { ...styleOptions, isMainChunk: false }; } function resolveStyleOptions(source, options) { return hasCssMacroTailwindV4Source(source.css) ? withCssMacroStyleOptions(options) : options; } function collectCustomPropertyValues(css) { const values = /* @__PURE__ */ new Map(); try { postcss.parse(css).walkDecls((decl) => { if (decl.prop.startsWith("--")) values.set(decl.prop, decl.value.trim()); }); } catch {} return values; } function mergeCustomPropertyValues(target, css) { for (const [prop, value] of collectCustomPropertyValues(css)) target.set(prop, value); } function createStableTextSignature(input) { let hash = 2166136261; for (let i = 0; i < input.length; i++) { hash ^= input.charCodeAt(i); hash = Math.imul(hash, 16777619); } return (hash >>> 0).toString(36); } function summarizeIncrementalCacheKey(key) { return { keyHash: createStableTextSignature(key), keyBytes: key.length }; } function shouldRebuildIncrementalEntry(cached, requestedCandidates, missingCandidates) { return cached.seenCandidates.size + missingCandidates.length > 12e3 || cached.css.length > 2097152 || cached.rawCss.length > 2097152 || requestedCandidates.size > 12e3; } function shouldAdmitIncrementalEntry(requestedCandidates, generated) { return requestedCandidates.size <= 12e3 && generated.css.length <= 2097152 && generated.rawCss.length <= 2097152; } function seedIncrementalGenerateCache(options) { if (!shouldAdmitIncrementalEntry(options.requestedCandidates, options.generated)) return false; const cacheKey = createIncrementalGenerateCacheKey(options.compatibleSource, options.target, options.styleOptions); const customPropertyValues = collectCustomPropertyValues(options.compatibleSource.css); mergeCustomPropertyValues(customPropertyValues, options.generated.css); incrementalGenerateCache.set(cacheKey, { seenCandidates: collectSeenCandidates(options.generated), classSet: new Set(options.generated.classSet), css: options.generated.css, rawCss: options.generated.rawCss, customPropertyValues, designSystemPromise: createIncrementalDesignSystemPromise(options.compatibleSource, cacheKey), dependencies: options.generated.dependencies, sources: options.generated.sources, root: options.generated.root, target: options.generated.target }); return true; } function shouldNormalizeRpxLengthCandidatesForTarget(target, styleOptions) { if (target !== "web") return true; return shouldUseUniAppWebRpxCompatibility(styleOptions?.appType); } function normalizeTargetRpxLengthCandidates(candidates, target, styleOptions) { return shouldNormalizeRpxLengthCandidatesForTarget(target, styleOptions) ? normalizeRpxLengthCandidates(candidates) : { candidates: new Set(candidates), restoreCandidates: /* @__PURE__ */ new Map() }; } //#endregion //#region src/tailwindcss/v4-engine/generator/cache-stats.ts function getTailwindV4IncrementalGenerateCacheStats() { return { max: 8, entryCandidatesMax: INCREMENTAL_GENERATE_ENTRY_CANDIDATES_MAX, entryCssBytesMax: INCREMENTAL_GENERATE_ENTRY_CSS_BYTES_MAX, size: incrementalGenerateCache.size, taskMax: 32, taskSize: incrementalGenerateTaskCache.size, entries: [...incrementalGenerateCache.entries()].map(([key, entry]) => ({ ...summarizeIncrementalCacheKey(key), candidates: entry.seenCandidates.size, classSet: entry.classSet.size, cssBytes: entry.css.length, rawCssBytes: entry.rawCss.length })), keys: [...incrementalGenerateCache.keys()].map(summarizeIncrementalCacheKey), taskKeys: [...incrementalGenerateTaskCache.keys()].map(summarizeIncrementalCacheKey) }; } //#endregion //#region src/tailwindcss/v4-engine/css-macro-source.ts function resolveCssMacroTailwindV4Source(source) { const css = transformCssMacroTailwindV4Source(source.css); return css === source.css ? source : { ...source, css }; } //#endregion //#region src/tailwindcss/v4-engine/miniprogram.ts const defaultStyleHandler = createStyleHandler({ cssChildCombinatorReplaceValue: ["view", "text"], cssRemoveHoverPseudoClass: true, isMainChunk: true, majorVersion: 4 }); const CSS_DECLARATION_URL_RE = /(:\s*)url\(([^\n\r"';[\]{}]*[[\]{}][^\n\r;]*)\)(?=\s*;)/g; function normalizeTailwindV4GeneratedUrlValues(css) { return css.replace(CSS_DECLARATION_URL_RE, (match, prefix, urlValue) => { try { return `${prefix}url("${urlValue.replaceAll("\\", "\\\\").replaceAll("\"", "\\\"")}")`; } catch { return match; } }); } async function transformTailwindV4CssToWeapp(css, options) { const compatibleCss = normalizeTailwindV4GeneratedUrlValues(hasCssMacroStyleOptions(options) ? await transformCssMacroCss(css, options) : css); const customPropertyValues = options?.customPropertyValues; const protectedCss = protectDynamicColorMixAlpha(compatibleCss, { customPropertyValues }); const result = await defaultStyleHandler(protectedCss.css, { cssChildCombinatorReplaceValue: ["view", "text"], cssRemoveHoverPseudoClass: true, isMainChunk: true, majorVersion: 4, ...options }); const pruneOptions = { preserveContentInit: options?.uniAppX === true && options.uniAppXCssTarget === "uvue" ? false : void 0, preservePreflight: true, preserveConditionalComments: hasCssMacroStyleOptions(options) }; return pruneMiniProgramGeneratedCss$1(protectedCss.restore(result.css), pruneOptions); } function transformTailwindV4WebRpxCss(css) { if (!css.includes("rpx")) return css; try { const root = postcss.parse(css); return normalizeTailwindcssWebRpxDeclarations(root, { majorVersion: 4 }) ? root.toString() : css; } catch { return css; } } async function transformTailwindV4CssByTarget(css, target, options) { if (target === "weapp") return transformTailwindV4CssToWeapp(css, options); const resolvedWebCss = await (hasCssMacroStyleOptions(options) ? transformCssMacroCss(css, options) : css); return shouldUseUniAppWebRpxCompatibility(options?.appType) ? transformTailwindV4WebRpxCss(resolvedWebCss) : resolvedWebCss; } //#endregion //#region src/tailwindcss/v4-engine/tailwind-v4-default-colors.ts const TAILWIND_V4_COLOR_STEPS = [ "50", "100", "200", "300", "400", "500", "600", "700", "800", "900", "950" ]; const TAILWIND_V4_COLOR_PALETTE = { slate: [ "#f8fafc", "#f1f5f9", "#e2e8f0", "#cad5e2", "#90a1b9", "#62748e", "#45556c", "#314158", "#1d293d", "#0f172b", "#020618" ], gray: [ "#f9fafb", "#f3f4f6", "#e5e7eb", "#d1d5dc", "#99a1af", "#6a7282", "#4a5565", "#364153", "#1e2939", "#101828", "#030712" ], zinc: [ "#fafafa", "#f4f4f5", "#e4e4e7", "#d4d4d8", "#9f9fa9", "#71717b", "#52525c", "#3f3f46", "#27272a", "#18181b", "#09090b" ], neutral: [ "#fafafa", "#f5f5f5", "#e5e5e5", "#d4d4d4", "#a1a1a1", "#737373", "#525252", "#404040", "#262626", "#171717", "#0a0a0a" ], stone: [ "#fafaf9", "#f5f5f4", "#e7e5e4", "#d6d3d1", "#a6a09b", "#79716b", "#57534d", "#44403b", "#292524", "#1c1917", "#0c0a09" ], mauve: [ "#fafafa", "#f3f1f3", "#e7e4e7", "#d7d0d7", "#a89ea9", "#79697b", "#594c5b", "#463947", "#2a212c", "#1d161e", "#0c090c" ], olive: [ "#fbfbf9", "#f4f4f0", "#e8e8e3", "#d8d8d0", "#abab9c", "#7c7c67", "#5b5b4b", "#474739", "#2b2b22", "#1d1d16", "#0c0c09" ], mist: [ "#f9fbfb", "#f1f3f3", "#e3e7e8", "#d0d6d8", "#9ca8ab", "#67787c", "#4b585b", "#394447", "#22292b", "#161b1d", "#090b0c" ], taupe: [ "#fbfaf9", "#f3f1f1", "#e8e4e3", "#d8d2d0", "#aba09c", "#7c6d67", "#5b4f4b", "#473c39", "#2b2422", "#1d1816", "#0c0a09" ], red: [ "#fef2f2", "#ffe2e2", "#ffc9c9", "#ffa2a2", "#ff6467", "#fb2c36", "#e7000b", "#c10007", "#9f0712", "#82181a", "#460809" ], orange: [ "#fff7ed", "#ffedd4", "#ffd6a7", "#ffb86a", "#ff8904", "#ff6900", "#f54900", "#ca3500", "#9f2d00", "#7e2a0c", "#441306" ], amber: [ "#fffbeb", "#fef3c6", "#fee685", "#ffd230", "#ffb900", "#fe9a00", "#e17100", "#bb4d00", "#973c00", "#7b3306", "#461901" ], yellow: [ "#fefce8", "#fef9c2", "#fff085", "#ffdf20", "#fdc700", "#f0b100", "#d08700", "#a65f00", "#894b00", "#733e0a", "#432004" ], lime: [ "#f7fee7", "#ecfcca", "#d8f999", "#bbf451", "#9ae600", "#7ccf00", "#5ea500", "#497d00", "#3c6300", "#35530e", "#192e03" ], green: [ "#f0fdf4", "#dcfce7", "#b9f8cf", "#7bf1a8", "#05df72", "#00c950", "#00a63e", "#008236", "#016630", "#0d542b", "#032e15" ], emerald: [ "#ecfdf5", "#d0fae5", "#a4f4cf", "#5ee9b5", "#00d492", "#00bc7d", "#009966", "#007a55", "#006045", "#004f3b", "#002c22" ], teal: [ "#f0fdfa", "#cbfbf1", "#96f7e4", "#46ecd5", "#00d5be", "#00bba7", "#009689", "#00786f", "#005f5a", "#0b4f4a", "#022f2e" ], cyan: [ "#ecfeff", "#cefafe", "#a2f4fd", "#53eafd", "#00d3f2", "#00b8db", "#0092b8", "#007595", "#005f78", "#104e64", "#053345" ], sky: [ "#f0f9ff", "#dff2fe", "#b8e6fe", "#74d4ff", "#00bcff", "#00a6f4", "#0084d1", "#0069a8", "#00598a", "#024a70", "#052f4a" ], blue: [ "#eff6ff", "#dbeafe", "#bedbff", "#8ec5ff", "#51a2ff", "#2b7fff", "#155dfc", "#1447e6", "#193cb8", "#1c398e", "#162456" ], indigo: [ "#eef2ff", "#e0e7ff", "#c6d2ff", "#a3b3ff", "#7c86ff", "#615fff", "#4f39f6", "#432dd7", "#372aac", "#312c85", "#1e1a4d" ], violet: [ "#f5f3ff", "#ede9fe", "#ddd6ff", "#c4b4ff", "#a684ff", "#8e51ff", "#7f22fe", "#7008e7", "#5d0ec0", "#4d179a", "#2f0d68" ], purple: [ "#faf5ff", "#f3e8ff", "#e9d4ff", "#dab2ff", "#c27aff", "#ad46ff", "#9810fa", "#8200db", "#6e11b0", "#59168b", "#3c0366" ], fuchsia: [ "#fdf4ff", "#fae8ff", "#f6cfff", "#f4a8ff", "#ed6aff", "#e12afb", "#c800de", "#a800b7", "#8a0194", "#721378", "#4b004f" ], pink: [ "#fdf2f8", "#fce7f3", "#fccee8", "#fda5d5", "#fb64b6", "#f6339a", "#e60076", "#c6005c", "#a3004c", "#861043", "#510424" ], rose: [ "#fff1f2", "#ffe4e6", "#ffccd3", "#ffa1ad", "#ff637e", "#ff2056", "#ec003f", "#c70036", "#a50036", "#8b0836", "#4d0218" ] }; function createTailwindV4DefaultColorThemeCss() { const declarations = [" --color-black: #000;", " --color-white: #fff;"]; for (const [color, values] of Object.entries(TAILWIND_V4_COLOR_PALETTE)) for (let index = 0; index < TAILWIND_V4_COLOR_STEPS.length; index++) declarations.push(` --color-${color}-${TAILWIND_V4_COLOR_STEPS[index]}: ${values[index]};`); return [ "@theme {", ...declarations, "}" ].join("\n"); } //#endregion //#region src/tailwindcss/v4-engine/generator/css-compat.ts const require$1 = createRequire(import.meta.url); const tailwindThemeCssCache = /* @__PURE__ */ new Map(); function findLeadingImportInsertionIndex(css) { const importPattern = /(?:^|\n)\s*@import\b[^;]*;/g; let insertionIndex = 0; let match = importPattern.exec(css); while (match !== null) { insertionIndex = match.index + match[0].length; match = importPattern.exec(css); } return insertionIndex; } function readCachedCss(file) { const cached = tailwindThemeCssCache.get(file); if (cached !== void 0) return cached; const css = readFileSync(file, "utf8"); tailwindThemeCssCache.set(file, css); return css; } function resolveTailwindV4ThemeCssFromImport(css) { const root = postcss.parse(css); let resolved; root.walkAtRules("import", (rule) => { if (resolved) return; const specifier = parseCssImportSpecifier$2(rule.params); if (!specifier || !path.isAbsolute(specifier) || path.basename(specifier) !== "index.css") return; const themeCss = path.join(path.dirname(specifier), "theme.css"); if (existsSync(themeCss)) resolved = themeCss; }); return resolved; } function resolveTailwindV4ThemeCssFromBase(base) { try { return createRequire(path.join(base, "package.json")).resolve("tailwindcss/theme.css"); } catch { try { return require$1.resolve("tailwindcss/theme.css"); } catch { return; } } } function resolveTailwindV4DefaultThemeCss(source) { try { const themeCss = resolveTailwindV4ThemeCssFromImport(source.css) ?? resolveTailwindV4ThemeCssFromBase(source.base); return themeCss ? readCachedCss(themeCss) : createTailwindV4DefaultColorThemeCss(); } catch { return createTailwindV4DefaultColorThemeCss(); } } function applyMiniProgramTailwindV4DefaultColorCss(css, source) { const themeCss = resolveTailwindV4DefaultThemeCss(source); const insertionIndex = findLeadingImportInsertionIndex(css); if (insertionIndex === 0) return `${themeCss}\n${css}`; return `${css.slice(0, insertionIndex)}\n${themeCss}\n${css.slice(insertionIndex)}`; } function parseCssImportSpecifier$2(params) { const value = params.trim(); const quoted = /^(['"])(.*?)\1/.exec(value); if (quoted) return quoted[2]; const url = /^url\(\s*(?:(['"])(.*?)\1|([^'")\s]+))\s*\)/.exec(value); return url?.[2] ?? url?.[3]; } function isTailwindCssPreflightImport(params) { const specifier = parseCssImportSpecifier$2(params); return specifier === "tailwindcss/preflight.css" || specifier === "tailwindcss/preflight"; } function removeTailwindV4PreflightImports(css) { if (!css.includes("preflight")) return css; let root; try { root = postcss.parse(css); } catch { return css; } let changed = false; root.walkAtRules("import", (rule) => { if (isTailwindCssPreflightImport(rule.params)) { rule.remove(); changed = true; } }); return changed ? root.toString() : css; } function hasThemeParent(rule) { let parent = rule.parent; while (parent) { if (parent.type === "atrule" && parent.name === "theme") return true; parent = parent.parent; } return false; } function isVendorPrefixedKeyframes(rule) { return rule.name.startsWith("-") && rule.name.endsWith("keyframes"); } function removeUnsupportedThemeVendorKeyframes(css) { if (!css.includes("@theme") || !css.includes("@-")) return css; let root; try { root = postcss.parse(css); } catch { return css; } let changed = false; root.walkAtRules((rule) => { if (isVendorPrefixedKeyframes(rule) && hasThemeParent(rule)) { rule.remove(); changed = true; } }); return changed ? root.toString() : css; } function createCompatibleSource(source, target) { const filteredSourceCss = target === "weapp" ? removeTailwindV4PreflightImports(source.css) : source.css; const compatibleSourceCss = removeUnsupportedThemeVendorKeyframes(target === "weapp" ? applyMiniProgramTailwindV4DefaultColorCss(filteredSourceCss, source) : filteredSourceCss); return compatibleSourceCss === source.css ? source : { ...source, css: compatibleSourceCss }; } //#endregion //#region src/tailwindcss/v4-engine/generator/native-session.ts var TailwindV4NativeSessionPool = class { constructor(createSession = createTailwindGenerationSession) { this.createSession = createSession; _defineProperty(this, "sessions", /* @__PURE__ */ new Map()); _defineProperty(this, "disposed", false); } generate(target, sourceKey, source, request) { const entry = this.getSession(target, sourceKey, source); const generated = entry.pending.then(() => entry.session.generate(request)); entry.pending = generated.then(() => void 0, () => void 0); return generated; } dispose() { for (const entry of this.sessions.values()) this.disposeEntry(entry); this.sessions.clear(); this.disposed = true; } get size() { return this.sessions.size; } getSession(target, sourceKey, source) { if (this.disposed) throw new Error("TailwindV4NativeSessionPool 已释放。"); const cached = this.sessions.get(target); if (cached?.sourceKey === sourceKey) return cached; if (cached) this.disposeEntry(cached); const session = this.createSession(source); const entry = { pending: Promise.resolve(), session, sourceKey }; this.sessions.set(target, entry); return entry; } disposeEntry(entry) { entry.pending.then(() => entry.session.dispose()); } }; function createEngineSourceEntries(sources, sourceId) { return sources.map((source, index) => ({ id: `${sourceId}:candidate-source:${index}`, ...source })); } function serializeTailwindGenerationArtifact(artifact) { return [...artifact.fragments].sort((left, right) => left.order - right.order).map((fragment) => fragment.root.toString()).join("\n"); } //#endregion //#region src/tailwindcss/source-scan.ts const DEFAULT_SOURCE_SCAN_EXTENSIONS = [ "html", "wxml", "axml", "jxml", "ksml", "ttml", "qml", "tyml", "xhsml", "swan", "vue", "mpx", "js", "jsx", "ts", "tsx" ]; const FULL_SOURCE_SCAN_EXTENSIONS = [ "js", "jsx", "mjs", "cjs", "ts", "tsx", "mts", "cts", "vue", "uvue", "nvue", "svelte", "mpx", "html", "wxml", "axml", "jxml", "ksml", "ttml", "qml", "tyml", "xhsml", "swan", "css", "wxss", "acss", "jxss", "ttss", "qss", "tyss", "scss", "sass", "less", "styl", "stylus" ]; function createSourceScanPattern(extensions = DEFAULT_SOURCE_SCAN_EXTENSIONS) { return `**/*.{${extensions.join(",")}}`; } const FULL_SOURCE_SCAN_PATTERN = createSourceScanPattern(FULL_SOURCE_SCAN_EXTENSIONS); const FULL_SOURCE_SCAN_EXTENSION_RE = new RegExp(`\\.(?:${FULL_SOURCE_SCAN_EXTENSIONS.map((extension) => extension.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")).join("|")})$`); function toPosixPath(value) { return value.split(path.sep).join("/"); } function resolveSourceScanPath(value) { const resolved = path.resolve(value); try { return realpathSync.native(resolved); } catch { return resolved; } } function normalizeEntryPattern(entry) { return path.isAbsolute(entry.pattern) ? toPosixPath(path.relative(resolveSourceScanPath(entry.base), entry.pattern)) : entry.pattern; } function isFileMatchedByTailwindSourceEntry(file, entry) { const relative = toPosixPath(path.relative(resolveSourceScanPath(entry.base), file)); return relative && !relative.startsWith("../") && !path.isAbsolute(relative) && micromatch.isMatch(relative, normalizeEntryPattern(entry)); } function isFileExcludedByTailwindSourceEntries(file, entries) { if (!entries?.length) return false; const resolvedFile = resolveSourceScanPath(file); return entries.some((entry) => entry.negated && isFileMatchedByTailwindSourceEntry(resolvedFile, entry)); } function isFileMatchedByTailwindSourceEntries(file, entries) { if (!entries?.length) return true; const positiveEntries = entries.filter((entry) => !entry.negated); const negativeEntries = entries.filter((entry) => entry.negated); const resolvedFile = resolveSourceScanPath(file); if (positiveEntries.length === 0) return !negativeEntries.some((entry) => isFileMatchedByTailwindSourceEntry(resolvedFile, entry)); if (!positiveEntries.some((entry) => isFileMatchedByTailwindSourceEntry(resolvedFile, entry))) return false; return !negativeEntries.some((entry) => isFileMatchedByTailwindSourceEntry(resolvedFile, entry)); } function createTailwindSourceEntryMatcher(entries) { if (!entries?.length) return; return (file) => isFileMatchedByTailwindSourceEntries(file, entries); } function resolveTailwindV4CssSourceBase(source, fallbackBase) { if (typeof source.base === "string" && source.base.length > 0) return source.base; if (typeof source.file === "string" && source.file.length > 0) return path.dirname(source.file); return fallbackBase; } function parseConfigParam(params) { const value = params.trim(); return /^(['"])(.+)\1$/.exec(value)?.[2]; } function isLegacyContentObject(value) { return typeof value === "object" && value !== null && "files" in value; } function normalizeGlobPattern(pattern) { return pattern.startsWith("./") ? pattern.slice(2) : pattern; } function hasGlobMagic(value) { return /[*?[\]{}()!+@]/.test(value); } function splitStaticGlobPrefix(pattern) { const segments = normalizeGlobPattern(pattern).split(/[\\/]+/); const prefix = []; const rest = []; let reachedGlob = false; for (const segment of segments) { if (!reachedGlob && segment && !hasGlobMagic(segment)) { prefix.push(segment); continue; } reachedGlob = true; rest.push(segment); } return { prefix, rest }; } function normalizeLegacyContentEntries(content, base, options = {}) { if (typeof content === "string") { const negated = content.startsWith("!"); return [{ base, negated, pattern: normalizeGlobPattern(negated ? content.slice(1) : content) }]; } if (Array.isArray(content)) return content.flatMap((item) => normalizeLegacyContentEntries(item, base, options)); if (isLegacyContentObject(content)) return normalizeLegacyContentEntries(content.files, content.relative && options.relativeBase ? options.relativeBase : base, options); return []; } async function pathExistsAsDirectory(file) { try { return (await stat(file)).isDirectory(); } catch { return false; } } async function resolveTailwindSourceEntry(sourcePath, base, negated, defaultPattern = createSourceScanPattern()) { const absoluteSource = path.isAbsolute(sourcePath) ? path.resolve(sourcePath) : path.resolve(base, sourcePath); if (await pathExistsAsDirectory(absoluteSource)) return { base: absoluteSource, negated, pattern: normalizeGlobPattern(defaultPattern) }; if (path.isAbsolute(sourcePath) && hasGlobMagic(sourcePath)) { const { prefix, rest } = splitStaticGlobPrefix(sourcePath); const root = path.parse(sourcePath).root; const normalizedPrefix = prefix[0] === "" ? prefix.slice(1) : prefix; if (rest.length > 0) return { base: path.resolve(root, ...normalizedPrefix), negated, pattern: normalizeGlobPattern(rest.join("/")) }; } if (path.isAbsolute(sourcePath)) return { base: path.dirname(absoluteSource), negated, pattern: normalizeGlobPattern(path.basename(absoluteSource)) }; const { prefix, rest } = splitStaticGlobPrefix(sourcePath); if (prefix.length > 0 && rest.length > 0) return { base: path.resolve(base, ...prefix), negated, pattern: normalizeGlobPattern(rest.join("/")) }; return { base, negated, pattern: normalizeGlobPattern(sourcePath) }; } function parseSourceFileParam(params) { const value = params.trim(); if (!value || value === "none" || value.startsWith("inline(")) return; const negated = value.startsWith("not "); const sourceValue = negated ? value.slice(4).trim() : value; if (sourceValue.startsWith("inline(")) return; const match = /^(['"])(.+)\1$/.exec(sourceValue); return match?.[2] ? { negated, sourcePath: match[2] } : void 0; } async function resolveCssSourceEntries(root, base, defaultPattern = createSourceScanPattern()) { const entries = []; const tasks = []; root.walkAtRules("source", (rule) => { const parsed = parseSourceFileParam(rule.params); if (!parsed) return; tasks.push(resolveTailwindSourceEntry(parsed.sourcePath, base, parsed.negated, defaultPattern)); }); entries.push(...await Promise.all(tasks)); return entries; } async function expandTailwindSourceEntries(entries, options = {}) { if (entries.length === 0) return []; const files = /* @__PURE__ */ new Set(); const entriesByBase = /* @__PURE__ */ new Map(); for (const entry of entries) { const base = path.resolve(entry.base); const group = entriesByBase.get(base) ?? []; group.push({ ...entry, base }); entriesByBase.set(base, group); } await Promise.all([...entriesByBase.entries()].map(async ([base, group]) => { const ignoredSources = options.ignore?.map((pattern) => ({ base, pattern: normalizeGlobPattern(pattern), negated: true })); const matched = await resolveProjectSourceFiles({ cwd: base, sources: group, ...ignoredSources === void 0 ? {} : { ignoredSources } }); for (const file of matched) files.add(path.resolve(file)); })); return [...files].filter((file) => !isFileExcludedByTailwindSourceEntries(file, entries)); } //#endregion //#region src/tailwindcss/v4-engine/generator/scan-sources.ts const TAILWIND_V4_DEFAULT_IGNORED_SOURCE_PATTERNS = [ "**/.git/**", "**/.hg/**", "**/.jj/**", "**/.next/**", "**/.parcel-cache/**", "**/.pnpm-store/**", "**/.svelte-kit/**", "**/.svn/**", "**/.turbo/**", "**/.venv/**", "**/.vercel/**", "**/.yarn/**", "**/__pycache__/**", "**/node_modules/**", "**/venv/**", "**/*.less", "**/*.lock", "**/*.sass", "**/*.scss", "**/*.styl", "**/*.log", "**/tailwind.config.js", "**/tailwind.config.cjs", "**/tailwind.config.mjs", "**/tailwind.config.ts", "**/tailwind.config.cts", "**/tailwind.config.mts", "**/tailwind.config.*.js", "**/tailwind.config.*.cjs", "**/tailwind.config.*.mjs", "**/tailwind.config.*.ts", "**/tailwind.config.*.cts", "**/tailwind.config.*.mts", "**/package-lock.json", "**/pnpm-lock.yaml", "**/bun.lockb", "**/.gitignore", "**/.env", "**/.env.*" ]; function parseImportSourceParam(params) { const match = /\bsource\(\s*(none|(['"])(.*?)\2)\s*\)/.exec(params); if (!match) return; return { none: match[1] === "none", sourcePath: match[3] }; } function parseCssImportSpecifier$1(params) { const value = params.trim(); const quoted = /^(['"])(.*?)\1/.exec(value); if (quoted) return quoted[2]; const url = /^url\(\s*(?:(['"])(.*?)\1|([^'")\s]+))\s*\)/.exec(value); return url?.[2] ?? url?.[3]; } function isTailwindCssImport(params) { const specifier = parseCssImportSpecifier$1(params); return specifier === "tailwindcss" || specifier?.startsWith("tailwindcss/") || specifier?.replaceAll("\\", "/").endsWith("/tailwindcss/index.css"); } function resolveSourceBase(base, sourcePath) { return path.isAbsolute(sourcePath) ? sourcePath : path.resolve(base, sourcePath); } function createDefaultIgnoredScanSources(base) { return TAILWIND_V4_DEFAULT_IGNORED_SOURCE_PATTERNS.map((pattern) => ({ base, pattern, negated: true })); } function normalizeCssDefinedScanSources(base, entries) { return entries.length > 0 && entries.every((entry) => entry.negated) ? [{ base, pattern: "**/*", negated: false }, ...entries] : entries; } function resolveDefaultSourceBase(source) { return source.projectRoot ?? source.cwd ?? source.base; } async function resolveCssDefinedScanSources(source) { let importSourceBase; let hasSourceNone = false; let hasTailwindImport = false; const from = source.dependencies[0]; let root; try { root = postcss.parse(source.css, { from }); } catch { return; } root.walkAtRules((rule) => { if (rule.name === "import") { if (!isTailwindCssImport(rule.params)) return; hasTailwindImport = true; const sourceParam = parseImportSourceParam(rule.params); if (sourceParam?.none) hasSourceNone = true; if (sourceParam?.sourcePath) importSourceBase = resolveSourceBase(source.base, sourceParam.sourcePath); } }); const sourcePatterns = await resolveCssSourceEntries(root, source.base, "**/*"); if (!importSourceBase) { if (sourcePatterns.length > 0) return [...normalizeCssDefinedScanSources(source.base, sourcePatterns), ...createDefaultIgnoredScanSources(source.base)]; if (hasSourceNone) return false; if (hasTailwindImport) { const defaultBase = resolveDefaultSourceBase(source); return [await resolveTailwindSourceEntry(".", defaultBase, false, "**/*"), ...createDefaultIgnoredScanSources(defaultBase)]; } return; } return [ await resolveTailwindSourceEntry(".", importSourceBase, false, "**/*"), ...sourcePatterns, ...createDefaultIgnoredScanSources(importSourceBase) ]; } async function resolveScanSources(source, scanSources) { if (scanSources !== true) return scanSources; return await resolveCssDefinedScanSources(source) ?? false; } function resolveCompiledSourceRoot(source) { let root = null; try { postcss.parse(source.css).walkAtRules("import", (rule) => { if (!isTailwindCssImport(rule.params)) return; const sourceParam = parseImportSourceParam(rule.params); if (sourceParam?.none) { root = "none"; return false; } if (sourceParam?.sourcePath) { root = { base: source.base, pattern: sourceParam.sourcePath }; return false; } }); } catch {} return root; } //#endregion //#region src/tailwindcss/v4-engine/generator/engine.ts function isCssSyntaxError(error) { return error instanceof Error && error.name === "CssSyntaxError"; } function createTailwindV4Engine$1(source) { const generationSessions = new TailwindV4NativeSessionPool(); const incrementalCacheKeys = /* @__PURE__ */ new Set(); const validationEngine = createTailwindV4Engine(source); async function generateOnce(generateSource, options = {}) { const { scanSources = true, styleOptions, target = "weapp", ...patchOptions } = options; const resolvedStyleOptions = resolveStyleOptions(generateSource, styleOptions); const compatibleSource = createCompatibleSource(resolveCssMacroTailwindV4Source(generateSource), target); const resolvedScanSources = await resolveScanSources(generateSource, scanSources); const filesystemCandidates = Array.isArray(resolvedScanSources) ? new Set(await extractRawCandidates(resolvedScanSources, { ...patchOptions.bareArbitraryValues === void 0 ? {} : { bareArbitraryValues: patchOptions.bareArbitraryValues } })) : void 0; const normalizedCandidates = normalizeTargetRpxLengthCandidates(resolveTargetCandidates(/* @__PURE__ */ new Set([...collectCandidates(patchOptions.candidates), ...filesystemCandidates ?? []]), target), target, resolvedStyleOptions); const sourceId = compatibleSource.dependencies[0] ?? compatibleSource.base; const generationRequest = { ...patchOptions.bareArbitraryValues === void 0 ? {} : { bareArbitraryValues: patchOptions.bareArbitraryValues }, ...patchOptions.sources === void 0 ? {} : { sourceEntries: createEngineSourceEntries(patchOptions.sources, sourceId) }, candidates: normalizedCandidates.candidates }; let generatedCss; let classSet; let rawCandidates; let dependencies; try { const artifact = await generationSessions.generate(target, createTailwindV4SourceCacheKey(compatibleSource), compatibleSource, generationRequest); generatedCss = serializeTailwindGenerationArtifact(artifact); classSet = artifact.classSet; rawCandidates = artifact.rawCandidates; dependencies = artifact.dependencies; } catch (error) { if (!isCssSyntaxError(error)) throw error; const legacyResult = await createTailwindV4Engine(compatibleSource).generate({ ...patchOptions.bareArbitraryValues === void 0 ? {} : { bareArbitraryValues: patchOptions.bareArbitraryValues }, ...patchOptions.sources === void 0 ? {} : { sources: patchOptions.sources }, candidates: normalizedCandidates.candidates, scanSources: false }); generatedCss = legacyResult.css; classSet = legacyResult.classSet; rawCandidates = legacyResult.rawCandidates; dependencies = legacyResult.dependencies; } const sources = Array.isArray(resolvedScanSources) ? resolvedScanSources : []; const rawCss = restoreRpxLengthCssSelectors(generatedCss, normalizedCandidates.restoreCandidates); const css = await transformTailwindV4CssByTarget(rawCss, target, resolvedStyleOptions); return { classSet: restoreRpxLengthCandidates(classSet, normalizedCandidates.restoreCandidates), rawCandidates: restoreRpxLengthCandidates(rawCandidates, normalizedCandidates.restoreCandidates), dependencies, root: resolveCompiledSourceRoot(compatibleSource), sources, css, rawCss, target }; } async function generateWithIncrementalCache(options = {}) { const target = options.target ?? "weapp"; const cssMacroSource = resolveCssMacroTailwindV4Source(source); const compatibleSource = createCompatibleSource(cssMacroSource, target); const requestedCandidates = resolveTargetCandidates(options.candidates, target); const styleOptions = resolveStyleOptions(source, options.styleOptions); if ((options.sources?.length ?? 0) > 0 || options.bareArbitraryValues !== void 0 || Array.isArray(options.scanSources)) return generateOnce(cssMacroSource, options); const cacheKey = createIncrementalGenerateCacheKey(compatibleSource, target, styleOptions); incrementalCacheKeys.add(cacheKey); if (options.scanSources === true) return runIncrementalGenerateTask(cacheKey, requestedCandidates, options.scanSources, async () => { const generated = await generateOnce(cssMacroSource, options); if (!seedIncrementalGenerateCache({ compatibleSource, generated, requestedCandidates, styleOptions, target })) incrementalGenerateCache.delete(cacheKey); return generated; }); const cached = incrementalGenerateCache.get(cacheKey); if (cached) { if (hasRemovedCandidates(cached.seenCandidates, requestedCandidates)) return runIncrementalGenerateTask(cacheKey, requestedCandidates, options.scanSources, async () => { const generated = await generateOnce(cssMacroSource, options); if (!seedIncrementalGenerateCache({ compatibleSource, generated, requestedCandidates, styleOptions, target })) incrementalGenerateCache.delete(cacheKey); return generated; }); const missingCandidates = [...requestedCandidates].filter((candidate) => !cached.seenCandidates.has(candidate)); if (missingCandidates.length === 0) return { css: cached.css, rawCss: cached.rawCss, incrementalCss: "", incrementalRawCss: "", classSet: new Set(cached.classSet), rawCandidates: new Set(cached.seenCandidates), dependencies: cached.dependencies, sources: cached.sources, root: cached.root, target: cached.target }; if (shouldRebuildIncrementalEntry(cached, requestedCandidates, missingCandidates)) return runIncrementalGenerateTask(cacheKey, requestedCandidates, options.scanSources, async () => { const generated = await generateOnce(cssMacroSource, options); if (!seedIncrementalGenerateCache({ compatibleSource, generated, requestedCandidates, styleOptions, target })) incrementalGenerateCache.delete(cacheKey); return generated; }); return runIncrementalGenerateTask(cacheKey, requestedCandidates, options.scanSources, async () => { const designSystem = await cached.designSystemPromise; const normalizedMissing = normalizeTargetRpxLengthCandidates(missingCandidates, target, styleOptions); const normalizedMissingCandidates = [...normalizedMissing.candidates]; const cssByCandidate = designSystem.candidatesToCss(normalizedMissingCandidates); const rawCssParts = []; const classSet = /* @__PURE__ */ new Set(); for (let index = 0; index < normalizedMissingCandidates.length; index += 1) { const candidate = normalizedMissingCandidates[index]; const css = cssByCandidate[index]; if (candidate && typeof css === "string" && css.trim().length > 0) { rawCssParts.push(restoreRpxLengthCssSelectors(css, normalizedMissing.restoreCandidates)); classSet.add(normalizedMissing.restoreCandidates.get(candidate) ?? candidate); } } const rawCss = rawCssParts.join("\n"); const incrementalCss = rawCss.length > 0 ? await transformTailwindV4CssByTarget(rawCss, target, { ...createIncrementalStyleOptions(styleOptions), customPropertyValues: cached.customPropertyValues }) : ""; for (const candidate of missingCandidates) cached.seenCandidates.add(candidate); for (const className of classSet) cached.classSet.add(className); cached.css = [cached.css, incrementalCss].filter(Boolean).join("\n"); cached.rawCss = [cached.rawCss, rawCss].filter(Boolean).join("\n"); mergeCustomPropertyValues(cached.customPropertyValues, incrementalCss); return { css: cached.css, rawCss: cached.rawCss, incrementalCss, incrementalRawCss: rawCss, classSet: new Set(cached.classSet), rawCandidates: new Set(cached.seenCandidates), dependencies: cached.dependencies, sources: cached.sources, root: cached.root, target: cached.target }; }); } return runIncrementalGenerateTask(cacheKey, requestedCandidates, options.scanSources, async () => { const generated = await generateOnce(cssMacroSource, options); seedIncrementalGenerateCache({ compatibleSource, generated, requestedCandidates, styleOptions, target }); return generated; }); } async function generate(options = {}) { return options.incrementalCache ? generateWithIncrementalCache(options) : generateOnce(source, options); } return { source, loadDesignSystem: validationEngine.loadDesignSystem, validateCandidates: validationEngine.validateCandidates, generate, dispose() { generationSessions.dispose(); for (const cacheKey of incrementalCacheKeys) incrementalGenerateCache.delete(cacheKey); incrementalCacheKeys.clear(); } }; } //#endregion //#region src/bundlers/shared/generator-css/config-directive.ts function quoteCssString(value) { return value.replaceAll("\\", "\\\\").replaceAll("\"", "\\\""); } function toCssPath(value) { return value.replaceAll("\\", "/"); } function prependConfigDirective(css, config) { if (!config || /@config\s+/.test(css)) return css; return `@config "${quoteCssString(toCssPath(config))}";\n${css}`; } function normalizeConfigDirective(css, config) { if (!config || !/@config\s+/.test(css)) return css; return css.replace(/@config\s+(["'])(.+?)\1\s*;?/, `@config "${quoteCssString(toCssPath(config))}";`); } //#endregion //#region src/bundlers/shared/generator-css/markers.ts const TAILWIND_V4_BANNER_RE = /\/\*!\s*tailwindcss v4\./; const TAILWIND_ESCAPED_UTILITY_MARKER_RE = /\.[^,{]{0,512}(?:\\:|\\\[|\\#)/; const TAILWIND_ROOT_THEME_MARKER_RE = /(?::root\s*,\s*:host|:host\s*,\s*page\s*,\s*\.tw-root\s*,\s*wx-root-portal-content)[^{]{0,256}\{[^}]{0,4096}(?:--spacing\b|--(?:color|text|font|default|radius)-)/; const GENERATOR_PLACEHOLDER_MARKER_RE = /\/\*!\s*weapp-tailwindcss generator-placeholder\s*\*\//i; const GENERATOR_PLACEHOLDER_MARKER_GLOBAL_RE = /\/\*!\s*weapp-tailwindcss generator-placeholder\s*\*\/\s*/gi; const TAILWIND_BANNER_PREFIX_RE = /^\/\*!\s*tailwindcss v[^*]*\*\/\s*/i; const TAILWIND_BANNER_RE = /\/\*!\s*tailwindcss v[^*]*\*\//i; const TAILWIND_BANNER_GLOBAL_RE = /\/\*!\s*tailwindcss v[^*]*\*\/\s*/gi; const VITE_MARKER_RE = /\/\*\$vite\$:[^*]*\*\//g; function createCssAppend(base, extra) { if (!base) return extra; if (!extra) return base; return `${base}\n${extra}`; } function splitTailwindV4GeneratedCssBySourceOrder(rawSource, rawTailwindCss) { const trimmedRaw = rawSource.trim(); const trimmedTailwind = rawTailwindCss.trim(); if (trimmedRaw === trimmedTailwind) return { before: "", after: "" }; if (trimmedTailwind.startsWith(trimmedRaw)) return { before: "", after: "" }; const start = rawSource.indexOf(rawTailwindCss); if (start === -1) return; return { before: rawSource.slice(0, start), after: rawSource.slice(start + rawTailwindCss.length) }; } function splitGeneratorPlaceholderCssBySourceOrder(rawSource, rawTailwindCss) { const match = GENERATOR_PLACEHOLDER_MARKER_RE.exec(rawSource); if (!match || match.index === void 0) return; let afterStart = match.index + match[0].length; while (/\s/.test(rawSource[afterStart] ?? "")) afterStart++; if (rawTailwindCss && rawSource.slice(afterStart).startsWith(rawTailwindCss)) { afterStart += rawTailwindCss.length; while (/\s/.test(rawSource[afterStart] ?? "")) afterStart++; } return { before: rawSource.slice(0, match.index), after: rawSource.slice(afterStart) }; } function splitTailwindGeneratedCssByBanner(rawSource, start) { const match = start === void 0 ? TAILWIND_BANNER_RE.exec(rawSource) : { index: start }; if (!match || match.index === void 0) return; return { before: rawSource.slice(0, match.index), after: [...rawSource.slice(match.index).matchAll(VITE_MARKER_RE)].map((item) => item[0]).join("\n") }; } function stripTailwindBanner(css) { return css.replace(TAILWIND_BANNER_PREFIX_RE, ""); } function stripTailwindBanners(css) { return css.replace(TAILWIND_BANNER_GLOBAL_RE, ""); } function stripGeneratorPlaceholderMarkers(css) { return css.replace(GENERATOR_PLACEHOLDER_MARKER_GLOBAL_RE, ""); } function hasTailwindGeneratedCss(rawSource) { return TAILWIND_V4_BANNER_RE.test(rawSource); } function hasTailwindGeneratedCssMarkers(rawSource) { if (rawSource.includes("--tw-") || rawSource.includes("tailwindcss v") || rawSource.includes(":not(#\\#)") || GENERATOR_PLACEHOLDER_MARKER_RE.test(rawSource)) return true; if (!rawSource.includes("\\:") && !rawSource.includes("\\[") && !rawSource.includes("\\#") && !rawSource.includes("--color-") && !rawSource.includes("--spacing") && !rawSource.