@tenphi/tasty 3.7.0 → 3.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{babel-DWCsafYw.d.ts → babel-Zs1Q03qt.d.ts} +2 -2
- package/dist/chunks/async-storage-CG5HnUT5.js +20 -0
- package/dist/chunks/async-storage-CG5HnUT5.js.map +1 -0
- package/dist/chunks/build-config-CUQVwdWF.js +42 -0
- package/dist/chunks/build-config-CUQVwdWF.js.map +1 -0
- package/dist/{collector-B3OsM252.js → chunks/collector-B0LTHw6Z.js} +6 -125
- package/dist/chunks/collector-B0LTHw6Z.js.map +1 -0
- package/dist/chunks/config-engine-C3pF9EK9.js +267 -0
- package/dist/chunks/config-engine-C3pF9EK9.js.map +1 -0
- package/dist/chunks/css-definitions-D_it4XZH.js +875 -0
- package/dist/chunks/css-definitions-D_it4XZH.js.map +1 -0
- package/dist/{css-resources-Cyl_axbI.js → chunks/css-resources-BN8apgxt.js} +1 -8
- package/dist/chunks/css-resources-BN8apgxt.js.map +1 -0
- package/dist/chunks/debug-C9LeNVoJ.js +501 -0
- package/dist/chunks/debug-C9LeNVoJ.js.map +1 -0
- package/dist/chunks/dsl-C5yuAn41.js +1373 -0
- package/dist/chunks/dsl-C5yuAn41.js.map +1 -0
- package/dist/chunks/hydration-TRcz5vnk.js +41 -0
- package/dist/chunks/hydration-TRcz5vnk.js.map +1 -0
- package/dist/chunks/react-runtime-O-OUrKLH.js +557 -0
- package/dist/chunks/react-runtime-O-OUrKLH.js.map +1 -0
- package/dist/chunks/runtime-engine-DvnE2g-E.js +2437 -0
- package/dist/chunks/runtime-engine-DvnE2g-E.js.map +1 -0
- package/dist/chunks/runtime-state-BTDqSYBk.js +127 -0
- package/dist/chunks/runtime-state-BTDqSYBk.js.map +1 -0
- package/dist/{merge-styles-DuoZEsm9.js → chunks/shared-utils-DWA4LjIa.js} +55 -54
- package/dist/chunks/shared-utils-DWA4LjIa.js.map +1 -0
- package/dist/chunks/style-engine-C1ECBZxR.js +5131 -0
- package/dist/chunks/style-engine-C1ECBZxR.js.map +1 -0
- package/dist/{css-writer-Bgowobbx.js → chunks/zero-engine-B6EnYcXY.js} +3 -120
- package/dist/chunks/zero-engine-B6EnYcXY.js.map +1 -0
- package/dist/{collector-BTVXj2hS.d.ts → collector-hl5KNH7k.d.ts} +6 -4
- package/dist/{config-LfIDmVHx.d.ts → config-DWL1ZYue.d.ts} +20 -25
- package/dist/core/index.d.ts +5 -5
- package/dist/core/index.js +9 -6
- package/dist/{index-Bm9ltvdH.d.ts → index-D9N9GV24.d.ts} +96 -82
- package/dist/index.d.ts +5 -5
- package/dist/index.js +11 -922
- package/dist/{merge-styles-BcLl1u_d.d.ts → merge-styles-C_oMoJVd.d.ts} +2 -2
- package/dist/ssr/astro-client.js +1 -14
- package/dist/ssr/astro-client.js.map +1 -1
- package/dist/ssr/astro-middleware-extract-static.js +1 -1
- package/dist/ssr/astro-middleware-extract.js +1 -1
- package/dist/ssr/astro-middleware-static.js +1 -12
- package/dist/ssr/astro-middleware-static.js.map +1 -1
- package/dist/ssr/astro-middleware.js +1 -13
- package/dist/ssr/astro-middleware.js.map +1 -1
- package/dist/ssr/astro.js +219 -1
- package/dist/ssr/astro.js.map +1 -0
- package/dist/ssr/index.d.ts +6 -6
- package/dist/ssr/index.js +4 -4
- package/dist/ssr/next-config.d.ts +1 -1
- package/dist/ssr/next-config.js +29 -20
- package/dist/ssr/next-config.js.map +1 -1
- package/dist/ssr/next.d.ts +1 -1
- package/dist/ssr/next.js +5 -37
- package/dist/ssr/next.js.map +1 -1
- package/dist/static/index.d.ts +2 -2
- package/dist/static/index.js +1 -19
- package/dist/static/index.js.map +1 -1
- package/dist/{index-BmogEzTo.d.ts → types-jKZNpias.d.ts} +845 -804
- package/dist/zero/babel.d.ts +1 -1
- package/dist/zero/babel.js +25 -96
- package/dist/zero/babel.js.map +1 -1
- package/dist/zero/index.d.ts +1 -1
- package/dist/zero/index.js +1 -1
- package/dist/zero/next.d.ts +1 -1
- package/dist/zero/next.js +0 -31
- package/dist/zero/next.js.map +1 -1
- package/docs/ai-agents.md +8 -3
- package/docs/debug.md +2 -5
- package/docs/methodology.md +3 -3
- package/docs/pipeline.md +3 -0
- package/docs/runtime-benchmarks.md +105 -68
- package/docs/styles.md +43 -11
- package/package.json +48 -5
- package/dist/astro-CeYENy2x.js +0 -301
- package/dist/astro-CeYENy2x.js.map +0 -1
- package/dist/async-storage-DKK-wTD4.js +0 -44
- package/dist/async-storage-DKK-wTD4.js.map +0 -1
- package/dist/collector-B3OsM252.js.map +0 -1
- package/dist/config-B3gPdCqd.js +0 -12421
- package/dist/config-B3gPdCqd.js.map +0 -1
- package/dist/context-CA8YKeMn.js +0 -24
- package/dist/context-CA8YKeMn.js.map +0 -1
- package/dist/core-DGm0CFHP.js +0 -1732
- package/dist/core-DGm0CFHP.js.map +0 -1
- package/dist/css-resources-Cyl_axbI.js.map +0 -1
- package/dist/css-writer-Bgowobbx.js.map +0 -1
- package/dist/format-global-rules-DklyaXv-.js +0 -22
- package/dist/format-global-rules-DklyaXv-.js.map +0 -1
- package/dist/format-rules-XRw9u7d4.js +0 -104
- package/dist/format-rules-XRw9u7d4.js.map +0 -1
- package/dist/hydrate-CNOmZprz.js +0 -37
- package/dist/hydrate-CNOmZprz.js.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/keyframes-DE-OE76F.js +0 -535
- package/dist/keyframes-DE-OE76F.js.map +0 -1
- package/dist/merge-styles-DuoZEsm9.js.map +0 -1
- package/dist/resolve-recipes-H9NqOQuP.js +0 -144
- package/dist/resolve-recipes-H9NqOQuP.js.map +0 -1
- package/dist/ssr-collector-ref-COs_ioWl.js +0 -29
- package/dist/ssr-collector-ref-COs_ioWl.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"css-definitions-D_it4XZH.js","names":[],"sources":["../../src/functions/index.ts","../../src/properties/defaults.ts","../../src/properties/index.ts","../../src/utils/hash.ts","../../src/utils/name-prefix.ts","../../src/properties/property-type-resolver.ts","../../src/font-face/index.ts","../../src/counter-style/index.ts","../../src/keyframes/index.ts","../../src/ssr/format-property.ts","../../src/ssr/format-keyframes.ts","../../src/ssr/format-rules.ts","../../src/ssr/format-global-rules.ts","../../src/ssr/artifacts.ts"],"sourcesContent":["/**\n * Function Utilities\n *\n * Utilities for extracting and processing CSS @function definitions in styles.\n * Custom functions are permanent once injected and do not need cleanup.\n *\n * Token syntax:\n * - Function name keys use `$$name` (the literal callable `--name`), matching\n * the call site `$$name(...)`. `$name` and `--name` are also accepted.\n * - Parameters and local variables use `$name` (declared/referenced as a custom\n * property), exactly like a normal styles object.\n * - `result`, local-variable values, and parameter defaults flow through the\n * Tasty DSL parser, so units, color tokens, auto-calc, and fallbacks all work.\n */\n\nimport type { FunctionDefinition, FunctionParameter } from '../injector/types';\nimport type { StyleDetails } from '../parser/types';\nimport type { Styles } from '../styles/types';\nimport { customFunction, parseStyle } from '../utils/styles';\n\n// ============================================================================\n// Constants\n// ============================================================================\n\nconst FUNCTION_KEY = '@function';\n\n/** Descriptor keys that are not local-variable declarations. */\nconst RESERVED_KEYS = new Set(['args', 'returns', 'result']);\n\n/**\n * A parse-time function: receives the parsed (comma-separated) argument groups\n * and returns a CSS value string. This is the JS flavor of the unified\n * `functions` config (bare-name keys), distinct from declarative `@function`\n * definitions (`$$`-prefixed keys).\n */\nexport type ParseFunction = (groups: StyleDetails[]) => string;\n\n/**\n * The unified `functions` map: keys are either bare names (parse functions,\n * value is a function) or `$$name`/`$name`/`--name` (declarative CSS functions,\n * value is a {@link FunctionDefinition} object).\n */\nexport type FunctionsConfig = Record<\n string,\n FunctionDefinition | ParseFunction\n>;\n\n// ============================================================================\n// Extraction Functions\n// ============================================================================\n\n/**\n * Check if styles object has a local @function definition.\n */\nexport function hasLocalFunctions(styles: Styles): boolean {\n return FUNCTION_KEY in styles;\n}\n\n/**\n * Extract local @function definitions from a styles object.\n * Returns null if none (fast path).\n */\nexport function extractLocalFunctions(\n styles: Styles,\n): Record<string, FunctionDefinition> | null {\n const functions = styles[FUNCTION_KEY];\n if (!functions || typeof functions !== 'object') {\n return null;\n }\n return functions as Record<string, FunctionDefinition>;\n}\n\n// ============================================================================\n// Token Parsing\n// ============================================================================\n\n/**\n * Parse a function name token into its CSS custom name.\n * Accepts `$$name`, `$name`, `--name`, or bare `name` → `--name`.\n */\nexport function parseFunctionName(token: string): string {\n if (token.startsWith('$$')) return `--${token.slice(2)}`;\n if (token.startsWith('$')) return `--${token.slice(1)}`;\n if (token.startsWith('--')) return token;\n return `--${token}`;\n}\n\n/**\n * Parse a parameter / local-variable name token into its CSS custom name.\n * Accepts `$name`, `--name`, or bare `name` → `--name`.\n */\nexport function parseParamName(token: string): string {\n if (token.startsWith('$')) return `--${token.slice(1)}`;\n if (token.startsWith('--')) return token;\n return `--${token}`;\n}\n\n// ============================================================================\n// CSS Formatting\n// ============================================================================\n\n/**\n * Format a single parameter (`--name <type>: default`).\n */\nfunction formatParameter(token: string, param: FunctionParameter): string {\n const name = parseParamName(token);\n\n if (param === true) {\n return name;\n }\n\n if (typeof param === 'string') {\n return param ? `${name} ${param}` : name;\n }\n\n let out = name;\n if (param.syntax) {\n out += ` ${param.syntax}`;\n }\n if (param.default !== undefined) {\n out += `: ${parseStyle(param.default).output}`;\n }\n return out;\n}\n\n/**\n * Format the function prelude: `@function --name(params) returns <type>`.\n */\nexport function formatFunctionPrelude(\n name: string,\n args: FunctionDefinition['args'],\n returns?: string,\n): string {\n const cssName = parseFunctionName(name);\n\n let params = '';\n if (Array.isArray(args)) {\n params = args.map((token) => formatParameter(token, true)).join(', ');\n } else if (args) {\n params = Object.entries(args)\n .map(([token, param]) => formatParameter(token, param))\n .join(', ');\n }\n\n const returnsPart = returns ? ` returns ${returns}` : '';\n\n return `@function ${cssName}(${params})${returnsPart}`;\n}\n\n/**\n * Format the inner declarations of a @function rule (local variables + result).\n */\nexport function formatFunctionDeclarations(def: FunctionDefinition): string {\n const parts: string[] = [];\n\n for (const key of Object.keys(def)) {\n if (RESERVED_KEYS.has(key) || !key.startsWith('$')) continue;\n const value = def[key as `$${string}`];\n if (value === undefined) continue;\n parts.push(`${parseParamName(key)}: ${parseStyle(value).output};`);\n }\n\n parts.push(`result: ${parseStyle(def.result).output};`);\n\n return parts.join(' ');\n}\n\n/**\n * Format a complete @function rule as CSS.\n */\nexport function formatFunctionRule(\n name: string,\n def: FunctionDefinition,\n): string {\n const prelude = formatFunctionPrelude(name, def.args, def.returns);\n return `${prelude} { ${formatFunctionDeclarations(def)} }`;\n}\n\n// ============================================================================\n// Unified `functions` config: value-type split\n// ============================================================================\n\n/** A key is a CSS-function key when it carries the `$`/`--` prefix. */\nfunction isCssFunctionKey(key: string): boolean {\n return key.startsWith('$') || key.startsWith('--');\n}\n\n/** Discriminate a unified `functions` entry by its value type. */\nfunction isParseFunction(\n value: FunctionDefinition | ParseFunction,\n): value is ParseFunction {\n return typeof value === 'function';\n}\n\nexport type FunctionMismatch =\n | 'expected-definition' // function value under a `$$` key\n | 'expected-parse-function'; // object value under a bare key\n\n/**\n * Split the unified `functions` map into the two internal registries:\n * - `parseFuncs`: JS parse functions (bare keys).\n * - `functionDefs`: declarative CSS `@function` definitions (`$$` keys).\n *\n * Entries whose key prefix does not match the value type are reported via\n * `onMismatch` and skipped.\n */\nexport function splitFunctions(\n map: FunctionsConfig,\n onMismatch?: (key: string, kind: FunctionMismatch) => void,\n): {\n parseFuncs: Record<string, ParseFunction>;\n functionDefs: Record<string, FunctionDefinition>;\n} {\n const parseFuncs: Record<string, ParseFunction> = {};\n const functionDefs: Record<string, FunctionDefinition> = {};\n\n for (const [key, value] of Object.entries(map)) {\n const cssKey = isCssFunctionKey(key);\n if (isParseFunction(value)) {\n if (cssKey) {\n onMismatch?.(key, 'expected-definition');\n continue;\n }\n parseFuncs[key] = value;\n } else {\n if (!cssKey) {\n onMismatch?.(key, 'expected-parse-function');\n continue;\n }\n functionDefs[key] = value;\n }\n }\n\n return { parseFuncs, functionDefs };\n}\n\n// ============================================================================\n// Polyfill: compile a declarative @function into a parse-function closure\n// ============================================================================\n\nfunction escapeRegExp(str: string): string {\n return str.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n}\n\nconst paramBareName = (token: string): string => parseParamName(token).slice(2);\n\n/**\n * Rewrite `var(--name)` references for declared parameter/local names to a\n * collision-resistant, function-scoped prefix. This guarantees that later\n * value substitution only ever targets the function's own variables and can\n * never accidentally match a real element-level `var(--name)` introduced by an\n * argument value (e.g. the `--gap` used by Tasty units). Blanket prefix — no\n * exact-collision detection.\n */\nfunction prefixDeclaredVars(\n template: string,\n declared: string[],\n prefixOf: (bare: string) => string,\n): string {\n let out = template;\n for (const bare of declared) {\n const re = new RegExp(`var\\\\(\\\\s*--${escapeRegExp(bare)}(?![\\\\w-])`, 'g');\n out = out.replace(re, `var(--${prefixOf(bare)}`);\n }\n return out;\n}\n\n/**\n * Replace the prefixed `var(--<prefixed>)` / `var(--<prefixed>, fallback)`\n * references with their mapped values, iterating so that local variables that\n * reference parameters (or other locals) resolve fully.\n */\nfunction substituteVars(\n template: string,\n valueMap: Map<string, string>,\n): string {\n let out = template;\n for (let iter = 0; iter < 30; iter++) {\n let changed = false;\n for (const [name, value] of valueMap) {\n const re = new RegExp(\n `var\\\\(\\\\s*--${escapeRegExp(name)}\\\\s*(?:,[^)]*)?\\\\)`,\n 'g',\n );\n const next = out.replace(re, () => {\n changed = true;\n return value;\n });\n out = next;\n }\n if (!changed) break;\n }\n return out;\n}\n\n/** Function names currently being expanded, to guard against recursion cycles. */\nconst inProgress = new Set<string>();\n\n/**\n * Compile a declarative `@function` definition into a parse-function closure\n * that fully inlines the call into plain CSS (the `@function` polyfill).\n *\n * Parameters and local variables are substituted directly with their values,\n * so no function-internal custom properties are emitted (collisions are\n * structurally impossible). Self/mutually-recursive functions are not expanded:\n * the cycle guard bails and the call is left untouched.\n */\nexport function compileFunctionClosure(\n name: string,\n def: FunctionDefinition,\n): ParseFunction {\n const cssName = parseFunctionName(name);\n // Function-scoped, collision-resistant prefix for this function's variables.\n const prefixOf = (bare: string): string => `tf-${cssName.slice(2)}-${bare}`;\n\n const params: { prefixed: string; default?: string }[] = [];\n if (Array.isArray(def.args)) {\n for (const token of def.args) {\n params.push({ prefixed: prefixOf(paramBareName(token)) });\n }\n } else if (def.args) {\n for (const [token, param] of Object.entries(def.args)) {\n let dflt: string | undefined;\n if (param && typeof param === 'object' && param.default !== undefined) {\n dflt = parseStyle(param.default).output;\n }\n params.push({ prefixed: prefixOf(paramBareName(token)), default: dflt });\n }\n }\n\n const localKeys = Object.keys(def).filter(\n (key) => !RESERVED_KEYS.has(key) && key.startsWith('$'),\n );\n\n const declared = [\n ...(Array.isArray(def.args)\n ? def.args.map(paramBareName)\n : def.args\n ? Object.keys(def.args).map(paramBareName)\n : []),\n ...localKeys.map(paramBareName),\n ];\n\n // Built lazily on first call so that nested function calls referenced by the\n // result are resolved against the fully-populated registry.\n let built = false;\n let resultTemplate = '';\n const localTemplates: { prefixed: string; value: string }[] = [];\n\n const build = () => {\n built = true;\n resultTemplate = prefixDeclaredVars(\n parseStyle(def.result).output,\n declared,\n prefixOf,\n );\n for (const key of localKeys) {\n const value = def[key as `$${string}`];\n if (value === undefined) continue;\n localTemplates.push({\n prefixed: prefixOf(paramBareName(key)),\n value: prefixDeclaredVars(parseStyle(value).output, declared, prefixOf),\n });\n }\n };\n\n return (groups: StyleDetails[]): string => {\n if (inProgress.has(cssName)) return '';\n inProgress.add(cssName);\n try {\n if (!built) build();\n\n const valueMap = new Map<string, string>();\n params.forEach((param, index) => {\n const arg = groups[index]?.output?.trim();\n valueMap.set(param.prefixed, arg || param.default || '');\n });\n for (const local of localTemplates) {\n valueMap.set(local.prefixed, local.value);\n }\n\n return substituteVars(resultTemplate, valueMap);\n } finally {\n inProgress.delete(cssName);\n }\n };\n}\n\n/** CSS function name -> serialized definition, to dedupe polyfill registration. */\nconst registeredFunctionDefs = new Map<string, string>();\n\n/**\n * Register a declarative `@function` as a parse-function closure so the parser\n * inlines its call sites. Deduplicated by name + definition; a later, different\n * definition of the same name overrides the previous one (local wins).\n */\nexport function registerFunctionPolyfill(\n name: string,\n definition: FunctionDefinition,\n): void {\n const cssName = parseFunctionName(name);\n const serialized = JSON.stringify(definition);\n if (registeredFunctionDefs.get(cssName) === serialized) return;\n registeredFunctionDefs.set(cssName, serialized);\n customFunction(cssName, compileFunctionClosure(name, definition));\n}\n\n/** Register all local `@function` definitions from a styles object (polyfill). */\nexport function registerLocalFunctionPolyfills(styles: Styles): void {\n const local = extractLocalFunctions(styles);\n if (!local) return;\n for (const [name, definition] of Object.entries(local)) {\n registerFunctionPolyfill(name, definition);\n }\n}\n\n/** Clear polyfill registration bookkeeping (used by resetConfig in tests). */\nexport function resetFunctionPolyfills(): void {\n registeredFunctionDefs.clear();\n}\n","import type { PropertyDefinition } from '../injector/types';\n\n/**\n * Default properties shipped with Tasty.\n *\n * Kept with the property formatter so runtime and build-time configuration\n * paths can share the same list without importing the browser runtime.\n */\nexport const DEFAULT_PROPERTIES: Record<string, PropertyDefinition> = {\n // Used by dual-fill feature to enable CSS transitions on the second fill color\n '#tasty-second-fill': {\n inherits: false,\n initialValue: 'transparent',\n },\n // The inherited color, published by the `color` handler for anything that\n // wants it as a color rather than as the `currentcolor` keyword. (`#current`\n // itself compiles to the keyword.) `initial-value: currentcolor` makes it a\n // true stand-in where nothing published it: a registered `<color>` property\n // keeps the keyword as its computed value and resolves it against each\n // element's own color. `transparent` here would render a reader invisible.\n '#current': {\n inherits: true,\n initialValue: 'currentcolor',\n },\n // White and black are fundamental colors that need explicit initial values.\n '#white': {\n inherits: true,\n initialValue: 'rgb(255 255 255)',\n },\n '#black': {\n inherits: true,\n initialValue: 'rgb(0 0 0)',\n },\n // Shorthand for transparent\n '#clear': {\n inherits: true,\n initialValue: 'transparent',\n },\n // Default border color\n '#border': {\n inherits: true,\n initialValue: 'rgb(0 0 0)',\n },\n\n // ---- Core design tokens used by style handlers ----\n // These provide sensible defaults so Tasty works standalone without a design system.\n // Consuming projects (e.g. uikit) override these by defining tokens on :root.\n\n $gap: {\n syntax: '<length>',\n inherits: true,\n initialValue: '4px',\n },\n $radius: {\n syntax: '<length>',\n inherits: true,\n initialValue: '6px',\n },\n '$border-width': {\n syntax: '<length>',\n inherits: true,\n initialValue: '1px',\n },\n '$outline-width': {\n syntax: '<length>',\n inherits: true,\n initialValue: '3px',\n },\n $transition: {\n syntax: '<time>',\n inherits: true,\n initialValue: '80ms',\n },\n // Used by radius.ts for `radius=\"leaf\"` modifier\n '$sharp-radius': {\n syntax: '<length>',\n inherits: true,\n initialValue: '0px',\n },\n // Used by preset.ts for `preset=\"name / strong\"`\n '$bold-font-weight': {\n syntax: '<number>',\n inherits: true,\n initialValue: '700',\n },\n // Used by preset.ts as fallback font stacks\n '$font-sans-fallback': {\n syntax: '*',\n inherits: true,\n initialValue:\n 'system-ui, -apple-system, \"Segoe UI\", Roboto, Helvetica, Arial, \"Apple Color Emoji\", \"Segoe UI Emoji\", sans-serif',\n },\n '$font-mono-fallback': {\n syntax: '*',\n inherits: true,\n initialValue:\n 'ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace',\n },\n};\n","/**\n * Properties Utilities\n *\n * Utilities for extracting and processing CSS @property definitions in styles.\n * Unlike keyframes, properties are permanent once registered and don't need cleanup.\n *\n * Property names use tasty token syntax:\n * - `$name` for regular properties → `--name`\n * - `#name` for color properties → `--name-color` (auto-sets syntax: '<color>')\n */\n\nimport type { PropertyDefinition } from '../injector/types';\nimport { RE_NUMBER, RE_RAW_UNIT } from '../parser/const';\nimport type { Styles } from '../styles/types';\n\n// ============================================================================\n// Constants\n// ============================================================================\n\nconst PROPERTIES_KEY = '@property';\n\n/**\n * Valid CSS custom property name pattern (after the -- prefix).\n * Must start with a letter or underscore, followed by letters, digits, hyphens, or underscores.\n */\nconst VALID_PROPERTY_NAME_PATTERN = /^[a-z_][a-z0-9-_]*$/i;\n\n// ============================================================================\n// Validation Functions\n// ============================================================================\n\n/**\n * Validate a CSS custom property name (the part after --).\n * Returns true if the name is valid for use as a CSS custom property.\n */\nexport function isValidPropertyName(name: string): boolean {\n return VALID_PROPERTY_NAME_PATTERN.test(name);\n}\n\n/**\n * Result of parsing a property token.\n */\ninterface ParsedPropertyToken {\n /** The CSS custom property name (e.g., '--my-prop') */\n cssName: string;\n /** Whether this is a color property */\n isColor: boolean;\n /** Whether the token was valid */\n isValid: boolean;\n /** Error message if invalid */\n error?: string;\n}\n\n// ============================================================================\n// Extraction Functions\n// ============================================================================\n\n/**\n * Check if styles object has local @property definition.\n * Fast path: single property lookup.\n */\nexport function hasLocalProperties(styles: Styles): boolean {\n return PROPERTIES_KEY in styles;\n}\n\n/**\n * Extract local @property from styles object.\n * Returns null if no local properties (fast path).\n */\nexport function extractLocalProperties(\n styles: Styles,\n): Record<string, PropertyDefinition> | null {\n const properties = styles[PROPERTIES_KEY];\n if (!properties || typeof properties !== 'object') {\n return null;\n }\n return properties as Record<string, PropertyDefinition>;\n}\n\n// ============================================================================\n// Token Parsing Functions\n// ============================================================================\n\n/**\n * Parse a property token name and return the CSS property name and whether it's a color.\n * Supports tasty token syntax and validates the property name.\n *\n * Token formats:\n * - `$name` → { cssName: '--name', isColor: false }\n * - `#name` → { cssName: '--name-color', isColor: true }\n * - `--name` → { cssName: '--name', isColor: false } (legacy, auto-detect color by suffix)\n * - `name` → { cssName: '--name', isColor: false } (legacy)\n *\n * @param token - The property token to parse\n * @returns Parsed result with cssName, isColor, isValid, and optional error\n */\nexport function parsePropertyToken(token: string): ParsedPropertyToken {\n if (!token || typeof token !== 'string') {\n return {\n cssName: '',\n isColor: false,\n isValid: false,\n error: 'Property token must be a non-empty string',\n };\n }\n\n let name: string;\n let isColor: boolean;\n\n if (token.startsWith('$')) {\n // Regular property token: $name → --name\n name = token.slice(1);\n isColor = false;\n } else if (token.startsWith('#')) {\n // Color property token: #name → --name-color\n name = token.slice(1);\n isColor = true;\n } else if (token.startsWith('--')) {\n // Legacy format with -- prefix\n name = token.slice(2);\n isColor = token.endsWith('-color');\n } else {\n // Legacy format without prefix\n name = token;\n isColor = token.endsWith('-color');\n }\n\n // Validate the name\n if (!name) {\n return {\n cssName: '',\n isColor,\n isValid: false,\n error: 'Property name cannot be empty',\n };\n }\n\n if (!isValidPropertyName(name)) {\n return {\n cssName: '',\n isColor,\n isValid: false,\n error: `Invalid property name \"${name}\". Must start with a letter or underscore, followed by letters, digits, hyphens, or underscores.`,\n };\n }\n\n // Build the CSS custom property name\n // For #name tokens, we add -color suffix\n // For legacy formats (--name-color or name-color), the name already includes -color\n let cssName: string;\n if (token.startsWith('#')) {\n // Color token: #name → --name-color\n cssName = `--${name}-color`;\n } else {\n // All other formats: just add -- prefix\n cssName = `--${name}`;\n }\n\n return {\n cssName,\n isColor,\n isValid: true,\n };\n}\n\n// ============================================================================\n// Normalization Functions\n// ============================================================================\n\n/**\n * Normalize a property name to the CSS custom property format.\n *\n * @deprecated Use parsePropertyToken instead for proper token handling\n */\nexport function normalizePropertyName(name: string): string {\n const result = parsePropertyToken(name);\n return result.isValid ? result.cssName : `--${name}`;\n}\n\n/**\n * Normalize a property definition to a consistent string representation.\n * Used for comparing definitions to detect type conflicts.\n *\n * Only `syntax` and `inherits` are compared — `initialValue` is intentionally\n * excluded because different components may set different defaults for the\n * same typed property (e.g. auto-inferred `0px` vs explicit `6px`).\n *\n * Keys are sorted alphabetically to ensure consistent comparison:\n * { inherits: true, syntax: '<color>' } === { syntax: '<color>', inherits: true }\n */\nexport function normalizePropertyDefinition(def: PropertyDefinition): string {\n const normalized: Record<string, unknown> = {};\n\n if (def.inherits !== undefined) {\n normalized.inherits = def.inherits;\n }\n if (def.syntax !== undefined) {\n normalized.syntax = def.syntax;\n }\n\n return JSON.stringify(normalized);\n}\n\n/**\n * Result of getEffectiveDefinition.\n */\ninterface EffectiveDefinitionResult {\n /** The CSS custom property name */\n cssName: string;\n /** The effective property definition */\n definition: PropertyDefinition;\n /** Whether the token was valid */\n isValid: boolean;\n /** Error message if invalid */\n error?: string;\n}\n\n/**\n * Get the effective property definition for a token.\n * For color tokens (#name), auto-sets syntax to '<color>' and defaults initialValue to 'transparent'.\n *\n * @param token - Property token ($name, #name, --name, or plain name)\n * @param userDefinition - User-provided definition options\n * @returns Effective definition with cssName, definition, isValid, and optional error\n */\nexport function getEffectiveDefinition(\n token: string,\n userDefinition: PropertyDefinition,\n): EffectiveDefinitionResult {\n const parsed = parsePropertyToken(token);\n\n if (!parsed.isValid) {\n return {\n cssName: '',\n definition: userDefinition,\n isValid: false,\n error: parsed.error,\n };\n }\n\n if (parsed.isColor) {\n // Color properties have fixed syntax and default initialValue\n return {\n cssName: parsed.cssName,\n definition: {\n syntax: '<color>', // Always '<color>' for color tokens, cannot be overridden\n inherits: userDefinition.inherits, // Allow inherits to be customized\n initialValue: userDefinition.initialValue ?? 'transparent', // Default to transparent\n },\n isValid: true,\n };\n }\n\n // Regular properties use the definition as-is\n return {\n cssName: parsed.cssName,\n definition: userDefinition,\n isValid: true,\n };\n}\n\n// ============================================================================\n// Value Type Inference\n// ============================================================================\n\n/**\n * Result of inferring a CSS @property syntax from a value.\n */\ninterface InferredSyntax {\n syntax: string;\n initialValue: string;\n}\n\nconst UNIT_TO_SYNTAX: Record<string, InferredSyntax> = {};\n\nconst LENGTH_UNITS = [\n 'px',\n 'em',\n 'rem',\n 'vw',\n 'vh',\n 'vmin',\n 'vmax',\n 'ch',\n 'ex',\n 'cap',\n 'ic',\n 'lh',\n 'rlh',\n 'svw',\n 'svh',\n 'lvw',\n 'lvh',\n 'dvw',\n 'dvh',\n 'cqw',\n 'cqh',\n 'cqi',\n 'cqb',\n 'cqmin',\n 'cqmax',\n];\n\nconst ANGLE_UNITS = ['deg', 'rad', 'grad', 'turn'];\nconst TIME_UNITS = ['ms', 's'];\n\nfor (const u of LENGTH_UNITS) {\n UNIT_TO_SYNTAX[u] = { syntax: '<length-percentage>', initialValue: '0px' };\n}\nUNIT_TO_SYNTAX['%'] = { syntax: '<length-percentage>', initialValue: '0px' };\nfor (const u of ANGLE_UNITS) {\n UNIT_TO_SYNTAX[u] = { syntax: '<angle>', initialValue: '0deg' };\n}\nfor (const u of TIME_UNITS) {\n UNIT_TO_SYNTAX[u] = { syntax: '<time>', initialValue: '0s' };\n}\n\n/**\n * Infer CSS @property syntax from a concrete value.\n * Detects numeric types: \\<number\\>, \\<length-percentage\\>, \\<angle\\>, \\<time\\>.\n * Length and percentage values both map to \\<length-percentage\\> for maximum flexibility.\n * Color properties are handled separately via the #name token convention\n * (--name-color gets \\<color\\> syntax automatically in getEffectiveDefinition).\n *\n * @param value - The CSS value to infer from (e.g. '10px', '1', '45deg')\n * @returns Inferred syntax and initial value, or null if not inferable\n */\nexport function inferSyntaxFromValue(value: string): InferredSyntax | null {\n if (!value || typeof value !== 'string') return null;\n\n const trimmed = value.trim();\n if (!trimmed) return null;\n\n if (RE_NUMBER.test(trimmed)) {\n // Bare zero is ambiguous (could be <length>, <angle>, <percentage>, etc.)\n if (parseFloat(trimmed) === 0) return null;\n return { syntax: '<number>', initialValue: '0' };\n }\n\n const unitMatch = trimmed.match(RE_RAW_UNIT);\n if (unitMatch) {\n const unit = unitMatch[2];\n const mapping = UNIT_TO_SYNTAX[unit];\n if (mapping) return mapping;\n }\n\n return null;\n}\n","/**\n * Fast string hash (djb2) for deduplication keys.\n * Not cryptographic — just collision-resistant enough for cache keys.\n */\nexport function hashString(str: string): string {\n let hash = 5381;\n for (let i = 0; i < str.length; i++) {\n hash = ((hash << 5) + hash + str.charCodeAt(i)) | 0;\n }\n return (hash >>> 0).toString(36);\n}\n","/**\n * Name prefix utilities for generated identifiers.\n *\n * Tasty generates three kinds of identifiers from content hashes:\n * - class names (used in DOM `class` attribute)\n * - keyframe names (used in CSS `animation`)\n * - counter-style names (used in CSS `list-style-type`)\n *\n * All three derive from a single configurable prefix so that an app\n * can namespace every identifier under one string. Discriminator letters\n * (`k`, `c`) keep the three kinds visually distinct in devtools — they\n * are not required for correctness (CSS keeps these in separate\n * namespaces), only for readability.\n *\n * The runtime / SSR / RSC paths must agree on the prefix; otherwise the\n * client-side hash for a given style will not match the server-rendered\n * class and hydration breaks. The zero-runtime build path uses a\n * different default (`'ts'`) so its classes can't collide with runtime\n * (`'t'`) classes when both are loaded on the same page.\n */\n\n/** Default prefix used by the runtime / SSR / RSC paths. */\nexport const DEFAULT_NAME_PREFIX = 't';\n\n/** Default prefix used by the zero-runtime (`tastyStatic`) build path. */\nexport const DEFAULT_ZERO_NAME_PREFIX = 'ts';\n\n/**\n * Allowed shape: starts with a letter or underscore, then letters/\n * digits/underscore/hyphen. Length capped at 32 to keep generated\n * names sane. Matches the CSS identifier rules for the common case\n * while keeping the surface conservative.\n */\nconst NAME_PREFIX_PATTERN = /^[a-zA-Z_][a-zA-Z0-9_-]{0,31}$/;\n\n/**\n * Validate a `namePrefix` value.\n * Throws a TypeError with a descriptive message on invalid input so\n * misconfiguration fails loudly at `configure()` time rather than\n * surfacing later as broken hydration.\n */\nexport function validateNamePrefix(prefix: unknown): void {\n if (typeof prefix !== 'string') {\n throw new TypeError(\n `[Tasty] namePrefix must be a string, got ${typeof prefix}.`,\n );\n }\n if (!NAME_PREFIX_PATTERN.test(prefix)) {\n throw new TypeError(\n `[Tasty] namePrefix \"${prefix}\" is invalid. ` +\n `It must start with a letter (a-z, A-Z) or \"_\", contain only ` +\n `letters, digits, \"_\" or \"-\", and be 1-32 characters long. ` +\n `Examples: \"t\", \"ts\", \"myapp-\", \"_foo\".`,\n );\n }\n}\n\n/**\n * Build a class name: `${prefix}${hash}`.\n * The hash is appended verbatim — supply a separator inside the prefix\n * itself if you want one (e.g. `'myapp-'`).\n */\nexport function makeClassName(prefix: string, hash: string): string {\n return `${prefix}${hash}`;\n}\n\n/**\n * Build a keyframe name: `${prefix}k${suffix}`.\n * The `k` discriminator keeps keyframe names visually distinct from\n * class names sharing the same prefix. `suffix` is typically a content\n * hash but may be a counter for ad-hoc allocation.\n */\nexport function makeKeyframeName(prefix: string, suffix: string): string {\n return `${prefix}k${suffix}`;\n}\n\n/**\n * Build a counter-style name: `${prefix}c${suffix}`.\n * The `c` discriminator keeps counter-style names visually distinct\n * from class names sharing the same prefix.\n */\nexport function makeCounterStyleName(prefix: string, suffix: string): string {\n return `${prefix}c${suffix}`;\n}\n\n/** Escape a string for safe inclusion in a regex literal. */\nfunction escapeRegex(str: string): string {\n return str.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n}\n\n/**\n * Regex matching any tasty class for the given prefix.\n * Used by the runtime GC's DOM scan and class-allocation bookkeeping.\n */\nexport function tastyClassRegex(prefix: string): RegExp {\n return new RegExp(`^${escapeRegex(prefix)}[a-z0-9]+$`);\n}\n\n/**\n * Global regex extracting tasty class names from RSC-inlined CSS.\n * Looks for the doubled-specificity pattern `.cls.cls` that\n * `formatRules()` always emits, which makes extraction reliable.\n */\nexport function rscClassRegexGlobal(prefix: string): RegExp {\n return new RegExp(`\\\\.(${escapeRegex(prefix)}[a-z0-9]+)\\\\.\\\\1`, 'g');\n}\n","/**\n * PropertyTypeResolver\n *\n * Automatically infers CSS @property types from custom property values.\n * Supports deferred resolution for var() reference chains of arbitrary depth.\n */\n\nimport { inferSyntaxFromValue } from './index';\n\n/**\n * One `--name: value` declaration, with the surrounding whitespace dropped.\n *\n * The value is anchored on `\\S` at both ends so no two quantifiers can claim\n * the same character. A lazy `(.+?)\\s*$` is quadratic on a value of nothing\n * but spaces — every split point gets tried (CodeQL `js/polynomial-redos`).\n */\nconst CUSTOM_PROP_DECL = /^\\s*(--[a-z0-9_-]+)\\s*:\\s*(\\S|\\S.*\\S)\\s*$/i;\nconst SINGLE_VAR_REF = /^var\\((--[a-z0-9_-]+)\\)$/i;\n\nexport class PropertyTypeResolver {\n /** propName → the prop it depends on */\n private pendingDeps = new Map<string, string>();\n /** propName → list of props waiting on it */\n private reverseDeps = new Map<string, string[]>();\n\n /**\n * Scan CSS declarations and auto-register @property for custom properties\n * whose types can be inferred from their values.\n */\n scanDeclarations(\n declarations: string,\n isPropertyDefined: (name: string) => boolean,\n registerProperty: (\n name: string,\n syntax: string,\n initialValue: string,\n ) => void,\n ): void {\n if (!declarations.includes('--')) return;\n\n const parts = declarations.split(/;+/);\n\n for (const part of parts) {\n if (!part.trim()) continue;\n\n const match = CUSTOM_PROP_DECL.exec(part);\n if (!match) continue;\n\n const propName = match[1];\n const value = match[2].trim();\n\n if (isPropertyDefined(propName)) continue;\n\n // Name-based: --*-color properties are always <color> (from #name tokens)\n if (propName.endsWith('-color')) {\n registerProperty(propName, '<color>', 'transparent');\n continue;\n }\n\n // Name-based: --*-line-height accepts numbers, lengths, and percentages\n if (propName.endsWith('-line-height')) {\n registerProperty(propName, '<number> | <length-percentage>', '0');\n continue;\n }\n\n // Name-based: --*-opacity accepts numbers and percentages\n if (propName.endsWith('-opacity')) {\n registerProperty(propName, '<number> | <percentage>', '0');\n continue;\n }\n\n // Single var() reference → record dependency for deferred resolution\n const varMatch = SINGLE_VAR_REF.exec(value);\n if (varMatch) {\n const depName = varMatch[1];\n this.addDependency(propName, depName);\n continue;\n }\n\n // Skip complex expressions (calc, multiple var, etc.)\n if (this.isComplexValue(value)) continue;\n\n const inferred = inferSyntaxFromValue(value);\n if (!inferred) continue;\n\n this.resolve(\n propName,\n inferred.syntax,\n inferred.initialValue,\n isPropertyDefined,\n registerProperty,\n );\n }\n }\n\n private addDependency(propName: string, depName: string): void {\n if (propName === depName) return;\n\n this.pendingDeps.set(propName, depName);\n\n let dependents = this.reverseDeps.get(depName);\n if (!dependents) {\n dependents = [];\n this.reverseDeps.set(depName, dependents);\n }\n if (!dependents.includes(propName)) {\n dependents.push(propName);\n }\n }\n\n private resolve(\n propName: string,\n syntax: string,\n initialValue: string,\n isPropertyDefined: (name: string) => boolean,\n registerProperty: (\n name: string,\n syntax: string,\n initialValue: string,\n ) => void,\n resolving?: Set<string>,\n ): void {\n if (!resolving) resolving = new Set();\n if (resolving.has(propName)) return;\n resolving.add(propName);\n\n if (!isPropertyDefined(propName)) {\n registerProperty(propName, syntax, initialValue);\n }\n\n const dependents = this.reverseDeps.get(propName);\n if (dependents) {\n this.reverseDeps.delete(propName);\n\n for (const dependent of dependents) {\n this.pendingDeps.delete(dependent);\n\n if (isPropertyDefined(dependent)) continue;\n\n this.resolve(\n dependent,\n syntax,\n initialValue,\n isPropertyDefined,\n registerProperty,\n resolving,\n );\n }\n }\n }\n\n private isComplexValue(value: string): boolean {\n if (value.includes('calc(')) return true;\n const firstVar = value.indexOf('var(');\n if (firstVar === -1) return false;\n if (value.indexOf('var(', firstVar + 4) !== -1) return true;\n return !SINGLE_VAR_REF.test(value);\n }\n}\n","/**\n * Font Face Utilities\n *\n * Utilities for extracting and processing CSS @font-face definitions in styles.\n * Font-face rules are permanent once injected and do not need cleanup.\n */\n\nimport type { FontFaceDescriptors, FontFaceInput } from '../injector/types';\nimport type { Styles } from '../styles/types';\n\n// ============================================================================\n// Constants\n// ============================================================================\n\nconst FONT_FACE_KEY = '@font-face';\n\n// ============================================================================\n// Extraction Functions\n// ============================================================================\n\n/**\n * Check if styles object has local @font-face definition.\n */\nexport function hasLocalFontFace(styles: Styles): boolean {\n return FONT_FACE_KEY in styles;\n}\n\n/**\n * Extract local @font-face from styles object.\n * Returns null if no local font faces (fast path).\n */\nexport function extractLocalFontFace(\n styles: Styles,\n): Record<string, FontFaceInput> | null {\n const fontFace = styles[FONT_FACE_KEY];\n if (!fontFace || typeof fontFace !== 'object') {\n return null;\n }\n return fontFace as Record<string, FontFaceInput>;\n}\n\n// ============================================================================\n// CSS Formatting\n// ============================================================================\n\nconst FONT_FACE_DESCRIPTOR_MAP: Record<string, string> = {\n fontWeight: 'font-weight',\n fontStyle: 'font-style',\n fontStretch: 'font-stretch',\n fontDisplay: 'font-display',\n unicodeRange: 'unicode-range',\n ascentOverride: 'ascent-override',\n descentOverride: 'descent-override',\n lineGapOverride: 'line-gap-override',\n sizeAdjust: 'size-adjust',\n fontFeatureSettings: 'font-feature-settings',\n fontVariationSettings: 'font-variation-settings',\n};\n\n/**\n * Format the inner declarations of a @font-face rule (no wrapper).\n * Used by the injector which needs selector and declarations separately.\n */\nexport function formatFontFaceDeclarations(\n family: string,\n descriptors: FontFaceDescriptors,\n): string {\n const parts: string[] = [];\n\n parts.push(`font-family: \"${family}\";`);\n parts.push(`src: ${descriptors.src};`);\n\n for (const [key, cssName] of Object.entries(FONT_FACE_DESCRIPTOR_MAP)) {\n const value = descriptors[key as keyof FontFaceDescriptors];\n if (value !== undefined) {\n parts.push(`${cssName}: ${value};`);\n }\n }\n\n return parts.join(' ');\n}\n\n/**\n * Format a single @font-face rule as CSS.\n */\nexport function formatFontFaceRule(\n family: string,\n descriptors: FontFaceDescriptors,\n): string {\n return `@font-face { ${formatFontFaceDeclarations(family, descriptors)} }`;\n}\n\n/**\n * Format all @font-face rules for a family (handles single or array form).\n * Returns an array of CSS strings, one per rule.\n */\nexport function formatFontFaceRules(\n family: string,\n input: FontFaceInput,\n): string[] {\n const descriptors = Array.isArray(input) ? input : [input];\n return descriptors.map((desc) => formatFontFaceRule(family, desc));\n}\n\n/**\n * Generate a content hash for deduplication of a single font-face rule.\n */\nexport function fontFaceContentHash(\n family: string,\n descriptors: FontFaceDescriptors,\n): string {\n return JSON.stringify({ family, ...descriptors });\n}\n","/**\n * Counter Style Utilities\n *\n * Utilities for extracting and processing CSS @counter-style definitions in styles.\n * Counter-style rules are permanent once injected and do not need cleanup.\n */\n\nimport type { CounterStyleDescriptors } from '../injector/types';\nimport type { Styles } from '../styles/types';\n\n// ============================================================================\n// Constants\n// ============================================================================\n\nconst COUNTER_STYLE_KEY = '@counter-style';\n\n// ============================================================================\n// Extraction Functions\n// ============================================================================\n\n/**\n * Check if styles object has local @counter-style definition.\n */\nexport function hasLocalCounterStyle(styles: Styles): boolean {\n return COUNTER_STYLE_KEY in styles;\n}\n\n/**\n * Extract local @counter-style from styles object.\n * Returns null if no local counter styles (fast path).\n */\nexport function extractLocalCounterStyle(\n styles: Styles,\n): Record<string, CounterStyleDescriptors> | null {\n const counterStyle = styles[COUNTER_STYLE_KEY];\n if (!counterStyle || typeof counterStyle !== 'object') {\n return null;\n }\n return counterStyle as Record<string, CounterStyleDescriptors>;\n}\n\n// ============================================================================\n// CSS Formatting\n// ============================================================================\n\nconst COUNTER_STYLE_DESCRIPTOR_MAP: Record<string, string> = {\n system: 'system',\n symbols: 'symbols',\n additiveSymbols: 'additive-symbols',\n prefix: 'prefix',\n suffix: 'suffix',\n negative: 'negative',\n range: 'range',\n pad: 'pad',\n fallback: 'fallback',\n speakAs: 'speak-as',\n};\n\n/**\n * Format the inner declarations of a @counter-style rule (no wrapper).\n * Used by the injector which needs selector and declarations separately.\n */\nexport function formatCounterStyleDeclarations(\n descriptors: CounterStyleDescriptors,\n): string {\n const parts: string[] = [];\n\n for (const [key, cssName] of Object.entries(COUNTER_STYLE_DESCRIPTOR_MAP)) {\n const value = descriptors[key as keyof CounterStyleDescriptors];\n if (value !== undefined) {\n parts.push(`${cssName}: ${value};`);\n }\n }\n\n return parts.join(' ');\n}\n\n/**\n * Format a @counter-style rule as CSS.\n */\nexport function formatCounterStyleRule(\n name: string,\n descriptors: CounterStyleDescriptors,\n): string {\n return `@counter-style ${name} { ${formatCounterStyleDeclarations(descriptors)} }`;\n}\n","/**\n * Keyframes Utilities\n *\n * Optimized utilities for extracting and processing keyframes in styles.\n * Designed for zero overhead when no keyframes are used.\n */\n\nimport type { KeyframesSteps } from '../injector/types';\nimport type { Styles } from '../styles/types';\nimport { hashString } from '../utils/hash';\n\n// ============================================================================\n// Constants\n// ============================================================================\n\nconst KEYFRAMES_KEY = '@keyframes';\n\n/**\n * Pattern to extract animation names from CSS animation property values.\n * Animation name is typically the first identifier in the shorthand.\n * Handles: \"fadeIn 300ms ease-in\", \"pulse 1s infinite\", etc.\n *\n * CSS animation shorthand order (all optional except name):\n * animation: name | duration | timing | delay | iteration | direction | fill-mode | play-state\n *\n * Animation names must:\n * - Start with a letter, underscore, or hyphen (but not a digit or CSS keyword)\n * - Not be CSS keywords: none, initial, inherit, unset, revert\n */\nconst NON_NAME_KEYWORDS = new Set(\n 'none initial inherit unset revert auto normal running paused reverse alternate alternate-reverse forwards backwards both ease linear ease-in ease-out ease-in-out step-start step-end'.split(\n ' ',\n ),\n);\n\n// ============================================================================\n// Extraction Functions\n// ============================================================================\n\n/**\n * Check if styles object has local @keyframes definition.\n * Fast path: single property lookup.\n */\nexport function hasLocalKeyframes(styles: Styles): boolean {\n return KEYFRAMES_KEY in styles;\n}\n\n/**\n * Extract local @keyframes from styles object.\n * Returns null if no local keyframes (fast path).\n */\nexport function extractLocalKeyframes(\n styles: Styles,\n): Record<string, KeyframesSteps> | null {\n const keyframes = styles[KEYFRAMES_KEY];\n if (!keyframes || typeof keyframes !== 'object') {\n return null;\n }\n return keyframes as Record<string, KeyframesSteps>;\n}\n\n/**\n * Merge local and global keyframes.\n * Local keyframes take priority over global.\n * Returns null if no keyframes exist (fast path).\n */\nexport function mergeKeyframes(\n local: Record<string, KeyframesSteps> | null,\n global: Record<string, KeyframesSteps> | null,\n): Record<string, KeyframesSteps> | null {\n if (!local && !global) return null;\n if (!local) return global;\n if (!global) return local;\n // Local overrides global\n return { ...global, ...local };\n}\n\n// ============================================================================\n// Animation Name Extraction\n// ============================================================================\n\n/**\n * Extract animation name from a single animation value.\n * Returns null if no valid name found.\n *\n * Examples:\n * - \"fadeIn 300ms ease-in\" → \"fadeIn\"\n * - \"1s pulse infinite\" → \"pulse\" (name can be anywhere)\n * - \"none\" → null (CSS keyword)\n * - \"300ms ease-in\" → null (no name, just duration/timing)\n */\nfunction extractAnimationNameFromValue(value: string): string | null {\n for (const part of value.trim().split(/\\s+/)) {\n const lower = part.toLowerCase();\n if (NON_NAME_KEYWORDS.has(lower)) continue;\n\n // Skip time values, iteration counts, and timing functions with arguments.\n if (\n part === 'infinite' ||\n /^(?:-?[\\d.]+m?s|\\d+|(?:cubic-bezier|steps)\\()/i.test(part)\n )\n continue;\n\n // Check if it looks like a valid animation name\n const match = /^([a-zA-Z_-][a-zA-Z0-9_-]*)/.exec(part);\n if (match) {\n return match[1];\n }\n }\n\n return null;\n}\n\n/**\n * Extract all animation names from an animation property value.\n * Handles multiple animations separated by commas.\n *\n * Example: \"fadeIn 300ms, slideIn 500ms ease-out\" → [\"fadeIn\", \"slideIn\"]\n */\nfunction collectAnimationNamesFromValue(value: string, names: Set<string>) {\n for (const animation of value.split(',')) {\n const name = extractAnimationNameFromValue(animation);\n if (name) names.add(name);\n }\n}\n\n/**\n * Extract animation names from a style value (handles mappings and arrays).\n */\nfunction extractAnimationNamesFromStyleValue(\n value: unknown,\n names: Set<string>,\n): void {\n if (typeof value === 'string') {\n collectAnimationNamesFromValue(value, names);\n } else if (Array.isArray(value)) {\n // Responsive array\n for (const v of value) {\n extractAnimationNamesFromStyleValue(v, names);\n }\n } else if (value && typeof value === 'object') {\n // State mapping\n for (const v of Object.values(value)) {\n extractAnimationNamesFromStyleValue(v, names);\n }\n }\n}\n\nfunction collectAnimationNamesFromStyles(\n styles: Styles,\n names: Set<string>,\n): void {\n if ('animation' in styles) {\n extractAnimationNamesFromStyleValue(styles.animation, names);\n }\n\n if ('animationName' in styles) {\n extractAnimationNamesFromStyleValue(styles.animationName, names);\n }\n\n for (const [key, value] of Object.entries(styles)) {\n if (key === '$' || key === KEYFRAMES_KEY) continue;\n\n if (\n (key.startsWith('&') || key.startsWith('.') || /^[A-Z]/.test(key)) &&\n value &&\n typeof value === 'object'\n ) {\n collectAnimationNamesFromStyles(value as Styles, names);\n }\n }\n}\n\n/**\n * Extract all animation names referenced in styles.\n * Scans 'animation' and 'animationName' properties including in state mappings.\n * Returns empty set if no animation properties found (fast path).\n */\nexport function extractAnimationNamesFromStyles(styles: Styles): Set<string> {\n const names = new Set<string>();\n collectAnimationNamesFromStyles(styles, names);\n return names;\n}\n\n/**\n * The name a local `@keyframes` block is emitted under.\n *\n * Content-addressed, and a pure function of what was authored: the same steps\n * always produce the same name, and different steps under the same authored\n * name cannot collide. That is what lets the server and the client agree —\n * a name handed out by whichever injector happened to see the definition first\n * depends on run order, so the two would disagree on both the animation name\n * and the class that references it.\n */\nexport function resolveKeyframesName(\n authored: string,\n steps: KeyframesSteps,\n): string {\n return `${authored}-${hashString(JSON.stringify(steps))}`;\n}\n\n/**\n * The emitted name for every local `@keyframes` in `styles`, by authored name.\n * Pure — the server, the RSC pass and the client all reach the same answer.\n */\nexport function resolveKeyframesNames(\n used: Record<string, KeyframesSteps>,\n): Map<string, string> {\n const names = new Map<string, string>();\n\n for (const [authored, steps] of Object.entries(used)) {\n names.set(authored, resolveKeyframesName(authored, steps));\n }\n\n return names;\n}\n\n/** Replace local animation names and collect the definitions each rule uses. */\nexport function replaceAnimationNames(\n declarations: string,\n nameMap: Map<string, string>,\n usedNames: Set<string>,\n): string {\n // Fast path: no animation properties\n if (nameMap.size === 0 || !declarations.includes('animation'))\n return declarations;\n\n const parts = declarations.split(';');\n let modified = false;\n\n for (let i = 0; i < parts.length; i++) {\n const part = parts[i];\n const colonIdx = part.indexOf(':');\n if (colonIdx === -1) continue;\n\n const prop = part.slice(0, colonIdx).trim().toLowerCase();\n\n if (prop === 'animation' || prop === 'animation-name') {\n const prefix = part.slice(0, colonIdx + 1);\n let value = part.slice(colonIdx + 1);\n\n for (const original of nameMap.keys()) {\n if (findWord(value, original) !== -1) usedNames.add(original);\n }\n\n for (const [original, injected] of nameMap) {\n if (original === injected) continue;\n const next = replaceWord(value, original, injected);\n if (next !== value) {\n value = next;\n modified = true;\n }\n }\n\n parts[i] = prefix + value;\n }\n }\n\n return modified ? parts.join(';') : declarations;\n}\n\n/**\n * Replace a word in a string (word boundary aware, no regex).\n */\nfunction replaceWord(str: string, word: string, replacement: string): string {\n let result = str;\n let idx = 0;\n\n while ((idx = findWord(result, word, idx)) !== -1) {\n result =\n result.slice(0, idx) + replacement + result.slice(idx + word.length);\n idx += replacement.length;\n }\n\n return result;\n}\n\nfunction findWord(str: string, word: string, from = 0): number {\n let idx = from;\n\n while ((idx = str.indexOf(word, idx)) !== -1) {\n const before = idx === 0 ? ' ' : str[idx - 1];\n const end = idx + word.length;\n const after = end === str.length ? ' ' : str[end];\n\n if (!/[\\w-]/.test(before + after)) {\n return idx;\n }\n idx = end;\n }\n\n return -1;\n}\n\n// ============================================================================\n// Filter Functions\n// ============================================================================\n\n/**\n * Filter keyframes to only those that are actually used.\n * Returns null if no keyframes are used (fast path).\n */\nexport function filterUsedKeyframes(\n keyframes: Record<string, KeyframesSteps> | null,\n usedNames: Set<string>,\n): Record<string, KeyframesSteps> | null {\n if (!keyframes || usedNames.size === 0) return null;\n\n const used: Record<string, KeyframesSteps> = {};\n let hasAny = false;\n\n for (const name of usedNames) {\n if (keyframes[name]) {\n used[name] = keyframes[name];\n hasAny = true;\n }\n }\n\n return hasAny ? used : null;\n}\n","/**\n * Format @property CSS rules for SSR output.\n *\n * Replicates the CSS construction from StyleInjector.property()\n * but returns a CSS string instead of inserting into the DOM.\n */\n\nimport type { PropertyDefinition } from '../injector/types';\nimport { getEffectiveDefinition } from '../properties';\nimport type { StyleValue } from '../utils/styles';\nimport { parseStyle } from '../utils/styles';\n\n/**\n * Format a single @property rule as a CSS string.\n *\n * Returns the full `@property --name { ... }` text, or empty string\n * if the token is invalid.\n */\nexport function formatPropertyCSS(\n token: string,\n definition: PropertyDefinition,\n): string {\n const result = getEffectiveDefinition(token, definition);\n if (!result.isValid) return '';\n\n return buildPropertyRule(result.cssName, result.definition);\n}\n\nfunction buildPropertyRule(\n cssName: string,\n definition: PropertyDefinition,\n): string {\n const parts: string[] = [];\n\n if (definition.syntax != null) {\n let syntax = String(definition.syntax).trim();\n if (!/^['\"]/u.test(syntax)) syntax = `\"${syntax}\"`;\n parts.push(`syntax: ${syntax};`);\n }\n\n const inherits = definition.inherits ?? true;\n parts.push(`inherits: ${inherits ? 'true' : 'false'};`);\n\n if (definition.initialValue != null) {\n let initialValueStr: string;\n if (typeof definition.initialValue === 'number') {\n initialValueStr = String(definition.initialValue);\n } else {\n initialValueStr = parseStyle(\n definition.initialValue as StyleValue,\n ).output;\n }\n parts.push(`initial-value: ${initialValueStr};`);\n }\n\n const declarations = parts.join(' ').trim();\n return `@property ${cssName} { ${declarations} }`;\n}\n","/**\n * Format @keyframes CSS rules for SSR output.\n *\n * Replicates the stepsToCSS logic from SheetManager but as a\n * standalone function that doesn't need DOM access.\n */\n\nimport type { KeyframesSteps } from '../injector/types';\nimport { createStyle, STYLE_HANDLER_MAP } from '../styles';\nimport type { CSSMap, StyleHandler, StyleValueStateMap } from '../utils/styles';\n\n/**\n * Convert keyframes steps to a CSS string.\n * Replicates SheetManager.stepsToCSS() without the class instance.\n */\nfunction stepsToCSS(steps: KeyframesSteps): string {\n const rules: string[] = [];\n\n for (const [key, value] of Object.entries(steps)) {\n if (typeof value === 'string') {\n rules.push(`${key} { ${value.trim()} }`);\n continue;\n }\n\n const styleMap = (value || {}) as StyleValueStateMap;\n const styleNames = Object.keys(styleMap).sort();\n const handlerQueue: StyleHandler[] = [];\n const seenHandlers = new Set<StyleHandler>();\n\n styleNames.forEach((styleName) => {\n let handlers = STYLE_HANDLER_MAP[styleName];\n if (!handlers) {\n handlers = STYLE_HANDLER_MAP[styleName] = [createStyle(styleName)];\n }\n\n handlers.forEach((handler) => {\n if (!seenHandlers.has(handler)) {\n seenHandlers.add(handler);\n handlerQueue.push(handler);\n }\n });\n });\n\n const declarationPairs: { prop: string; value: string }[] = [];\n\n handlerQueue.forEach((handler) => {\n const lookup = handler.__lookupStyles;\n const filteredMap = lookup.reduce<StyleValueStateMap>((acc, name) => {\n const v = styleMap[name];\n if (v !== undefined) acc[name] = v;\n return acc;\n }, {});\n\n const result = handler(filteredMap);\n if (!result) return;\n\n const results = Array.isArray(result) ? result : [result];\n results.forEach((cssMap) => {\n if (!cssMap || typeof cssMap !== 'object') return;\n const { $: _$, ...props } = cssMap as CSSMap;\n\n Object.entries(props).forEach(([prop, val]) => {\n if (val == null || val === '') return;\n\n if (Array.isArray(val)) {\n val.forEach((v) => {\n if (v != null && v !== '') {\n declarationPairs.push({ prop, value: String(v) });\n }\n });\n } else {\n declarationPairs.push({ prop, value: String(val) });\n }\n });\n });\n });\n\n const declarations = declarationPairs\n .map((d) => `${d.prop}: ${d.value}`)\n .join('; ');\n\n rules.push(`${key} { ${declarations.trim()} }`);\n }\n\n return rules.join(' ');\n}\n\n/**\n * Format a @keyframes rule as a CSS string.\n */\nexport function formatKeyframesCSS(\n name: string,\n steps: KeyframesSteps,\n): string {\n const cssSteps = stepsToCSS(steps);\n return `@keyframes ${name} { ${cssSteps} }`;\n}\n","/**\n * Shared CSS rule formatting utility.\n *\n * Extracted from SheetManager to allow both the DOM-based injector (client)\n * and the ServerStyleCollector (server) to produce identical CSS text\n * from StyleResult arrays.\n */\n\nimport type { StyleResult } from '../pipeline';\n\n/**\n * Resolve selectors for a rule, applying className-based specificity doubling\n * and rootPrefix handling. Mirrors the logic in StyleInjector.inject().\n */\nfunction resolveSelector(rule: StyleResult, className: string): string {\n let selector = rule.selector;\n\n if (rule.needsClassName) {\n const selectorParts = selector ? selector.split('|||') : [''];\n const classPrefix = `.${className}.${className}`;\n\n selector = selectorParts\n .map((part) => {\n const classSelector = part ? `${classPrefix}${part}` : classPrefix;\n\n if (rule.rootPrefix) {\n return `${rule.rootPrefix} ${classSelector}`;\n }\n return classSelector;\n })\n .join(', ');\n }\n\n return selector;\n}\n\ninterface GroupedRule {\n selector: string;\n declarations: string;\n atRules?: string[];\n startingStyle?: boolean;\n}\n\n/**\n * Group rules by selector + at-rules + startingStyle and merge their declarations.\n * Mirrors the grouping logic in SheetManager.insertRule().\n */\nfunction groupRules(rules: GroupedRule[]): GroupedRule[] {\n const groupMap = new Map<string, GroupedRule>();\n const order: string[] = [];\n\n const atKey = (at?: string[]) => (at && at.length ? at.join('|') : '');\n\n for (const r of rules) {\n const key = `${atKey(r.atRules)}||${r.selector}||${r.startingStyle ? '1' : '0'}`;\n const existing = groupMap.get(key);\n if (existing) {\n existing.declarations = existing.declarations\n ? `${existing.declarations} ${r.declarations}`\n : r.declarations;\n } else {\n groupMap.set(key, {\n selector: r.selector,\n atRules: r.atRules,\n startingStyle: r.startingStyle,\n declarations: r.declarations,\n });\n order.push(key);\n }\n }\n\n return order.map((key) => groupMap.get(key)!);\n}\n\n/**\n * Format an array of StyleResult rules into a CSS text string.\n *\n * Applies className-based specificity doubling (.cls.cls),\n * groups rules by selector + at-rules, and wraps with at-rule blocks.\n *\n * Produces the same CSS text as SheetManager.insertRule() would insert\n * into the DOM, but as a plain string suitable for SSR output.\n */\nexport function formatRules(rules: StyleResult[], className: string): string {\n if (rules.length === 0) return '';\n\n const resolvedRules = rules.map((rule) => ({\n selector: resolveSelector(rule, className),\n declarations: rule.declarations,\n atRules: rule.atRules,\n startingStyle: rule.startingStyle,\n }));\n\n const grouped = groupRules(resolvedRules);\n const cssRules: string[] = [];\n\n for (const rule of grouped) {\n const innerContent = rule.startingStyle\n ? `@starting-style { ${rule.declarations} }`\n : rule.declarations;\n const baseRule = `${rule.selector} { ${innerContent} }`;\n\n let fullRule = baseRule;\n if (rule.atRules && rule.atRules.length > 0) {\n fullRule = rule.atRules.reduce(\n (css, atRule) => `${atRule} { ${css} }`,\n baseRule,\n );\n }\n\n cssRules.push(fullRule);\n }\n\n return cssRules.join('\\n');\n}\n","/**\n * Format global CSS rules for SSR output.\n *\n * Unlike formatRules() which applies className-based specificity doubling,\n * this function formats rules that already have their full selectors\n * (from renderStyles called with a selector string).\n */\n\nimport type { StyleResult } from '../pipeline';\n\n/**\n * Format an array of global StyleResult rules into a CSS text string.\n *\n * Rules already have their full selectors applied by renderStyles().\n * Handles rootPrefix prepending and at-rule wrapping.\n */\nexport function formatGlobalRules(rules: StyleResult[]): string {\n if (rules.length === 0) return '';\n\n const cssRules: string[] = [];\n\n for (const rule of rules) {\n const selector = rule.rootPrefix\n ? `${rule.rootPrefix} ${rule.selector}`\n : rule.selector;\n\n const baseRule = `${selector} { ${rule.declarations} }`;\n\n let fullRule = baseRule;\n if (rule.atRules && rule.atRules.length > 0) {\n fullRule = rule.atRules.reduce(\n (css, atRule) => `${atRule} { ${css} }`,\n baseRule,\n );\n }\n\n cssRules.push(fullRule);\n }\n\n return cssRules.join('\\n');\n}\n","import { hashString } from '../utils/hash';\n\nexport type ServerStyleArtifactKind =\n | 'property'\n | 'font-face'\n | 'counter-style'\n | 'function'\n | 'raw'\n | 'global'\n | 'chunk'\n | 'keyframes';\n\nexport interface ServerStyleArtifact {\n /** Stable identifier derived from the artifact kind, logical key, and CSS. */\n id: string;\n kind: ServerStyleArtifactKind;\n css: string;\n /** Zero-based position in the collector's final cascade order. */\n order: number;\n}\n\nexport function createServerStyleArtifact(\n kind: ServerStyleArtifactKind,\n key: string,\n css: string,\n order: number,\n): ServerStyleArtifact {\n const content = `${kind}\\0${key}\\0${css}`;\n\n return {\n id: `${kind}:${hashString(content)}:${content.length.toString(36)}`,\n kind,\n css,\n order,\n };\n}\n"],"mappings":"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"}
|
|
@@ -1,11 +1,4 @@
|
|
|
1
1
|
//#region src/ssr/css-resources.ts
|
|
2
|
-
/**
|
|
3
|
-
* Find CSS resource references that cannot safely move to a shared stylesheet.
|
|
4
|
-
*
|
|
5
|
-
* This is intentionally a small scanner rather than a CSS parser. It handles
|
|
6
|
-
* comments, strings, escaped identifiers, url(), string-valued image/src
|
|
7
|
-
* functions, and string @import rules without interpreting unrelated CSS.
|
|
8
|
-
*/
|
|
9
2
|
function skipCSSString(css, start, quote) {
|
|
10
3
|
for (let index = start + 1; index < css.length; index++) if (css[index] === "\\") index++;
|
|
11
4
|
else if (css[index] === quote) return index + 1;
|
|
@@ -146,4 +139,4 @@ function findUnsafeCSSResource(css, rejectRootRelative) {
|
|
|
146
139
|
//#endregion
|
|
147
140
|
export { findUnsafeCSSResource as t };
|
|
148
141
|
|
|
149
|
-
//# sourceMappingURL=css-resources-
|
|
142
|
+
//# sourceMappingURL=css-resources-BN8apgxt.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"css-resources-BN8apgxt.js","names":[],"sources":["../../src/ssr/css-resources.ts"],"sourcesContent":["/**\n * Find CSS resource references that cannot safely move to a shared stylesheet.\n *\n * This is intentionally a small scanner rather than a CSS parser. It handles\n * comments, strings, escaped identifiers, url(), string-valued image/src\n * functions, and string @import rules without interpreting unrelated CSS.\n */\n\nfunction skipCSSString(css: string, start: number, quote: string): number {\n for (let index = start + 1; index < css.length; index++) {\n if (css[index] === '\\\\') {\n index++;\n } else if (css[index] === quote) {\n return index + 1;\n }\n }\n return css.length;\n}\n\nfunction decodeCSSEscapes(value: string): string {\n return value.replace(\n /\\\\(?:([\\da-f]{1,6})\\s?|\\r\\n|[\\n\\r\\f]|(.))/gi,\n (_match, hex: string | undefined, escaped: string | undefined) => {\n if (hex) {\n const codePoint = Number.parseInt(hex, 16);\n return codePoint === 0 || codePoint > 0x10ffff\n ? '\\ufffd'\n : String.fromCodePoint(codePoint);\n }\n return escaped ?? '';\n },\n );\n}\n\nfunction readCSSIdentifier(\n css: string,\n start: number,\n): { name: string; end: number } | null {\n let name = '';\n let index = start;\n\n while (index < css.length) {\n const char = css[index];\n if (/[-_a-z\\d]/i.test(char) || char.charCodeAt(0) >= 0x80) {\n name += char;\n index++;\n continue;\n }\n if (char !== '\\\\' || index + 1 >= css.length) break;\n\n const hex = css.slice(index + 1).match(/^[\\da-f]{1,6}/i)?.[0];\n if (hex) {\n name += decodeCSSEscapes(`\\\\${hex}`);\n index += hex.length + 1;\n if (/\\s/.test(css[index] ?? '')) index++;\n continue;\n }\n\n if (/\\r|\\n|\\f/.test(css[index + 1])) break;\n name += css[index + 1];\n index += 2;\n }\n\n return index === start ? null : { name, end: index };\n}\n\nfunction skipCSSWhitespaceAndComments(css: string, start: number): number {\n let index = start;\n for (;;) {\n while (/\\s/.test(css[index] ?? '')) index++;\n if (css[index] !== '/' || css[index + 1] !== '*') return index;\n const commentEnd = css.indexOf('*/', index + 2);\n if (commentEnd === -1) return css.length;\n index = commentEnd + 2;\n }\n}\n\nexport interface UnsafeCSSResource {\n url: string;\n rootRelative: boolean;\n}\n\nfunction classifyCSSResource(\n rawURL: string,\n rejectRootRelative: boolean,\n): UnsafeCSSResource | null {\n const url = decodeCSSEscapes(rawURL).trim();\n if (!url || url.startsWith('//') || /^[a-z][a-z\\d+.-]*:/i.test(url)) {\n return null;\n }\n if (url.startsWith('/')) {\n return rejectRootRelative ? { url: rawURL, rootRelative: true } : null;\n }\n return { url: rawURL, rootRelative: false };\n}\n\nexport function findUnsafeCSSResource(\n css: string,\n rejectRootRelative: boolean,\n): UnsafeCSSResource | null {\n const functionStack: (string | null)[] = [];\n const stringResourceFunctions = new Set([\n 'image',\n 'image-set',\n '-webkit-image-set',\n 'src',\n ]);\n\n for (let index = 0; index < css.length; index++) {\n if (css[index] === '/' && css[index + 1] === '*') {\n const commentEnd = css.indexOf('*/', index + 2);\n index = commentEnd === -1 ? css.length : commentEnd + 1;\n continue;\n }\n\n const quote = css[index];\n if (quote === '\"' || quote === \"'\") {\n const stringEnd = skipCSSString(css, index, quote);\n if (stringResourceFunctions.has(functionStack.at(-1) ?? '')) {\n const unsafe = classifyCSSResource(\n css.slice(index + 1, stringEnd - 1),\n rejectRootRelative,\n );\n if (unsafe) return unsafe;\n }\n index = stringEnd - 1;\n continue;\n }\n\n if (css[index] === ')') {\n functionStack.pop();\n continue;\n }\n\n if (css[index] === '(') {\n functionStack.push(null);\n continue;\n }\n\n if (css[index] === '@') {\n const atRule = readCSSIdentifier(css, index + 1);\n if (atRule?.name.toLowerCase() === 'import') {\n const valueStart = skipCSSWhitespaceAndComments(css, atRule.end);\n const importQuote = css[valueStart];\n if (importQuote === '\"' || importQuote === \"'\") {\n const valueEnd = skipCSSString(css, valueStart, importQuote);\n const unsafe = classifyCSSResource(\n css.slice(valueStart + 1, valueEnd - 1),\n rejectRootRelative,\n );\n if (unsafe) return unsafe;\n }\n }\n continue;\n }\n\n const identifier = readCSSIdentifier(css, index);\n if (!identifier || css[identifier.end] !== '(') continue;\n\n const functionName = identifier.name.toLowerCase();\n if (functionName !== 'url') {\n functionStack.push(functionName);\n index = identifier.end;\n continue;\n }\n\n const valueStart = skipCSSWhitespaceAndComments(css, identifier.end + 1);\n const urlQuote = css[valueStart];\n const quoted = urlQuote === '\"' || urlQuote === \"'\";\n let valueEnd: number;\n if (quoted) {\n valueEnd = skipCSSString(css, valueStart, urlQuote) - 1;\n index = css.indexOf(')', valueEnd + 1);\n } else {\n valueEnd = valueStart;\n while (valueEnd < css.length && css[valueEnd] !== ')') {\n if (css[valueEnd] === '\\\\') valueEnd++;\n valueEnd++;\n }\n index = valueEnd;\n }\n\n if (index === -1) return null;\n const unsafe = classifyCSSResource(\n css.slice(valueStart + (quoted ? 1 : 0), valueEnd),\n rejectRootRelative,\n );\n if (unsafe) return unsafe;\n }\n\n return null;\n}\n"],"mappings":"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"}
|