{"version":3,"file":"twind.esnext.js","sources":["../src/colors.ts","../src/internal/changed.ts","../src/utils.ts","../src/internal/to-class-name.ts","../src/internal/precedence.ts","../src/internal/sorted-insertion-index.ts","../src/internal/stringify.ts","../src/internal/theme.ts","../src/internal/context.ts","../src/internal/registry.ts","../src/internal/define.ts","../src/internal/format.ts","../src/internal/parse.ts","../src/internal/serialize.ts","../src/internal/merge.ts","../src/internal/translate.ts","../src/define-config.ts","../src/twind.ts","../src/observe.ts","../src/sheets.ts","../src/runtime.ts","../src/consume.ts","../src/internal/interleave.ts","../src/internal/astish.ts","../src/css.ts","../src/internal/interpolate.ts","../src/cx.ts","../src/extract.ts","../src/inject-global.ts","../src/inline.ts","../src/keyframes.ts","../src/nested.ts","../src/rules.ts","../src/style.ts","../src/tx.ts"],"sourcesContent":["import type { ColorValue, ColorFunctionOptions } from './types'\n\nfunction parseColorComponent(chars: string, factor: number): number {\n return Math.round(parseInt(chars, 16) * factor)\n}\n\nexport function toColorValue(color: ColorValue, options: ColorFunctionOptions = {}): string {\n if (typeof color == 'function') {\n return color(options)\n }\n\n const { opacityValue = '1', opacityVariable } = options\n const opacity = opacityVariable ? `var(${opacityVariable})` : opacityValue\n\n if (opacity == '1') return color\n if (opacity == '0') return '#0000'\n\n // rgb hex: #0123 and #001122\n if (color[0] == '#' && (color.length == 4 || color.length == 7)) {\n const size = (color.length - 1) / 3\n const factor = [17, 1, 0.062272][size - 1]\n\n // eslint-disable-next-line @typescript-eslint/restrict-template-expressions\n return `rgba(${[\n parseColorComponent(color.substr(1, size), factor),\n parseColorComponent(color.substr(1 + size, size), factor),\n parseColorComponent(color.substr(1 + 2 * size, size), factor),\n opacity,\n ]})`\n }\n\n return color\n}\n","/**\n * Determines if two class name strings contain the same classes.\n *\n * @param a first class names\n * @param b second class names\n * @returns are they different\n */\nexport function changed(a: string, b: string): boolean {\n // eslint-disable-next-line @typescript-eslint/restrict-plus-operands\n return a != b && '' + a.split(' ').sort() != '' + b.split(' ').sort()\n}\n","/* eslint-disable @typescript-eslint/no-explicit-any */\nimport type { MaybeArray, ScreenValue } from './types'\n\nexport const escape =\n (typeof CSS !== 'undefined' && CSS.escape) ||\n // Simplified: escaping only special characters\n // Needed for NodeJS and Edge <79 (https://caniuse.com/mdn-api_css_escape)\n ((className: string): string =>\n className\n // Simplifed escape testing only for chars that we know happen to be in tailwind directives\n .replace(/[!\"'`*+.,;:\\\\/<=>?@#$%&^|~()[\\]{}]/g, '\\\\$&')\n // If the character is the first character and is in the range [0-9] (2xl, ...)\n // https://drafts.csswg.org/cssom/#escape-a-character-as-code-point\n .replace(/^\\d/, '\\\\3$& '))\n\n// Based on https://stackoverflow.com/a/52171480\nexport function hash(value: string): string {\n // eslint-disable-next-line no-var\n for (var h = 9, index = value.length; index--; ) {\n h = Math.imul(h ^ value.charCodeAt(index), 0x5f356495)\n }\n\n return '#' + ((h ^ (h >>> 9)) >>> 0).toString(36)\n}\n\nexport function mql(screen: MaybeArray, prefix = '@media '): string {\n return (\n prefix +\n asArray(screen)\n .map((screen) => {\n if (typeof screen == 'string') {\n screen = { min: screen }\n }\n\n return (\n (screen as { raw?: string }).raw ||\n Object.keys(screen)\n .map((feature) => `(${feature}-width:${(screen as Record)[feature]})`)\n .join(' and ')\n )\n })\n .join(',')\n )\n}\n\nexport function asArray(value: T = [] as unknown as T): T extends Array ? T : T[] {\n return (Array.isArray(value) ? value : value == null ? [] : [value]) as T extends Array\n ? T\n : T[]\n}\n\nexport function identity(value: T): T {\n return value\n}\n\nexport function noop(): void {\n // no-op\n}\n","import type { ParsedRule } from './parse'\n\nexport function toClassName(rule: ParsedRule): string {\n return [...rule.v, (rule.i ? '!' : '') + rule.n].join(':')\n}\n","import type { BaseTheme, Context } from '../types'\nimport type { ParsedRule } from './parse'\nimport { asArray, mql } from '../utils'\nimport { toClassName } from './to-class-name'\n\n// Based on https://github.com/kripod/otion\n// License MIT\n\n// export const enum Shifts {\n// darkMode = 30,\n// layer = 27,\n// screens = 26,\n// responsive = 22,\n// atRules = 18,\n// variants = 0,\n// }\n\nexport const Layer = {\n /**\n * 1. `default` (public)\n */\n d /* efaults */: 0b000 << 27 /* Shifts.layer */,\n\n /**\n * 2. `base` (public) —for things like reset rules or default styles applied to plain HTML elements.\n */\n b /* ase */: 0b001 << 27 /* Shifts.layer */,\n\n /**\n * 3. `components` (public, used by `style()`) — is for class-based styles that you want to be able to override with utilities.\n */\n c /* omponents */: 0b010 << 27 /* Shifts.layer */,\n // reserved for style():\n // - props: 0b011\n // - when: 0b100\n\n /**\n * 6. `shortcuts` (public, used by `apply()`) — `~(...)`\n */\n s /* hortcuts */: 0b101 << 27 /* Shifts.layer */,\n\n /**\n * 6. `utilities` (public) — for small, single-purpose classes\n */\n u /* tilities */: 0b110 << 27 /* Shifts.layer */,\n\n /**\n * 7. `overrides` (public, used by `css()`)\n */\n o /* verrides */: 0b111 << 27 /* Shifts.layer */,\n} as const\n\n/*\nTo have a predictable styling the styles must be ordered.\n\nThis order is represented by a precedence number. The lower values\nare inserted before higher values. Meaning higher precedence styles\noverwrite lower precedence styles.\n\nEach rule has some traits that are put into a bit set which form\nthe precedence:\n\n| bits | trait |\n| ---- | ---------------------------------------------------- |\n| 1 | dark mode |\n| 2 | layer: preflight, global, components, utilities, css |\n| 1 | screens: is this a responsive variation of a rule |\n| 5 | responsive based on min-width |\n| 4 | at-rules |\n| 18 | pseudo and group variants |\n| 4 | number of declarations (descending) |\n| 4 | greatest precedence of properties |\n\n**Dark Mode: 1 bit**\n\nFlag for dark mode rules.\n\n**Layer: 3 bits**\n\n- defaults = 0: The preflight styles and any base styles registered by plugins.\n- vase = 1: The global styles registered by plugins.\n- components = 2\n- variants = 3\n- compounds = 4\n- shortcuts = 5\n- utilities = 6: Utility classes and any utility classes registered by plugins.\n- css = 7: Styles generated by css\n\n**Screens: 1 bit**\n\nFlag for screen variants. They may not always have a `min-width` to be detected by _Responsive_ below.\n\n**Responsive: 4 bits**\n\nBased on extracted `min-width` value:\n\n- 576px -> 3\n- 1536px -> 10\n- 36rem -> 3\n- 96rem -> 9\n\n**At-Rules: 4 bits**\n\nBased on the count of special chars (`-:,`) within the at-rule.\n\n**Pseudo and group variants: 18 bits**\n\nEnsures predictable order of pseudo classes.\n\n- https://bitsofco.de/when-do-the-hover-focus-and-active-pseudo-classes-apply/#orderofstyleshoverthenfocusthenactive\n- https://developer.mozilla.org/docs/Web/CSS/:active#Active_links\n- https://github.com/tailwindlabs/tailwindcss/blob/master/stubs/defaultConfig.stub.js#L718\n\n**Number of declarations (descending): 4 bits**\n\nAllows single declaration styles to overwrite styles from multi declaration styles.\n\n**Greatest precedence of properties: 4 bits**\n\nEnsure shorthand properties are inserted before longhand properties; eg longhand override shorthand\n*/\n\nexport function moveToLayer(precedence: number, layer: number): number {\n // Set layer (first reset, than set)\n return (precedence & ~Layer.o) | layer\n}\n\n/*\nTo set a bit: n |= mask;\nTo clear a bit: n &= ~mask;\nTo test if a bit is set: (n & mask)\n\nBit shifts for the primary bits:\n\n| bits | trait | shift |\n| ---- | ------------------------------------------------------- | ----- |\n| 1 | dark mode | 30 |\n| 3 | layer: preflight, global, components, utilities, css | 27 |\n| 1 | screens: is this a responsive variation of a rule | 26 |\n| 4 | responsive based on min-width, max-width or width | 22 |\n| 4 | at-rules | 18 |\n| 18 | pseudo and group variants | 0 |\n\nLayer: 0 - 7: 3 bits\n - defaults: 0 << 27\n - base: 1 << 27\n - components: 2 << 27\n - variants: 3 << 27\n - joints: 4 << 27\n - shortcuts: 5 << 27\n - utilities: 6 << 27\n - overrides: 7 << 27\n\nThese are calculated by serialize and added afterwards:\n\n| bits | trait |\n| ---- | ----------------------------------- |\n| 4 | number of selectors (descending) |\n| 4 | number of declarations (descending) |\n| 4 | greatest precedence of properties |\n\nThese are added by shifting the primary bits using multiplication as js only\nsupports bit shift up to 32 bits.\n*/\n\n// Colon and dash count of string (ascending)\nexport function seperatorPrecedence(string: string): number {\n return string.match(/[-=:;]/g)?.length || 0\n}\n\nexport function atRulePrecedence(css: string): number {\n // 0=none, 1=sm, 2=md, 3=lg, 4=xl, 5=2xl, 6=??, 7=??\n // 0 - 15: 4 bits (max 150rem or 2250px)\n // 576px -> 3\n // 1536px -> 10\n // 36rem -> 3\n // 96rem -> 9\n return (\n (Math.min(\n /(?:^|width[^\\d]+)(\\d+(?:.\\d+)?)(p)?/.test(css) ? +RegExp.$1 / (RegExp.$2 ? 15 : 1) / 10 : 0,\n 15,\n ) <<\n 22) /* Shifts.responsive */ |\n (Math.min(seperatorPrecedence(css), 15) << 18) /* Shifts.atRules */\n )\n}\n\n// Pesudo variant presedence\n// Chars 3 - 8: Uniquely identifies a pseudo selector\n// represented as a bit set for each relevant value\n// 18 bits: one for each variant plus one for unknown variants\n//\n// ':group-*' variants are normalized to their native pseudo class (':group-hover' -> ':hover')\n// as they already have a higher selector presedence due to the add '.group' ('.group:hover .group-hover:...')\n\n// Sources:\n// - https://bitsofco.de/when-do-the-hover-focus-and-active-pseudo-classes-apply/#orderofstyleshoverthenfocusthenactive\n// - https://developer.mozilla.org/docs/Web/CSS/:active#Active_links\n// - https://github.com/tailwindlabs/tailwindcss/blob/master/stubs/defaultConfig.stub.js#L931\n\nconst PRECEDENCES_BY_PSEUDO_CLASS = [\n /* fi */ 'rst-c' /* hild: 0 */,\n /* la */ 'st-ch' /* ild: 1 */,\n // even and odd use: nth-child\n /* nt */ 'h-chi' /* ld: 2 */,\n /* an */ 'y-lin' /* k: 3 */,\n /* li */ 'nk' /* : 4 */,\n /* vi */ 'sited' /* : 5 */,\n /* ch */ 'ecked' /* : 6 */,\n /* em */ 'pty' /* : 7 */,\n /* re */ 'ad-on' /* ly: 8 */,\n /* fo */ 'cus-w' /* ithin : 9 */,\n /* ho */ 'ver' /* : 10 */,\n /* fo */ 'cus' /* : 11 */,\n /* fo */ 'cus-v' /* isible : 12 */,\n /* ac */ 'tive' /* : 13 */,\n /* di */ 'sable' /* d : 14 */,\n /* op */ 'tiona' /* l: 15 */,\n /* re */ 'quire' /* d: 16 */,\n]\n\nfunction pseudoPrecedence(selector: string): number {\n // use first found pseudo-class\n\n return (\n 1 <<\n ~(\n (/:([a-z-]+)/.test(selector) &&\n ~PRECEDENCES_BY_PSEUDO_CLASS.indexOf(RegExp.$1.slice(2, 7))) ||\n ~17\n )\n )\n}\n\n// https://github.com/kripod/otion/blob/main/packages/otion/src/propertyMatchers.ts\n// \"+1\": [\n// \t/* ^border-.*(w|c|sty) */\n// \t\"border-.*(width,color,style)\",\n\n// \t/* ^[tlbr].{2,4}m?$ */\n// \t\"top\",\n// \t\"left\",\n// \t\"bottom\",\n// \t\"right\",\n\n// \t/* ^c.{7}$ */\n// \t\"continue\",\n// ],\n\n// \"-1\": [\n// \t/* ^[fl].{5}l */\n// \t\"flex-flow\",\n// \t\"line-clamp\",\n\n// \t/* ^g.{8}$ */\n// \t\"grid-area\",\n\n// \t/* ^pl */\n// \t\"place-content\",\n// \t\"place-items\",\n// \t\"place-self\",\n// ],\n\n// group: 1 => +1\n// group: 2 => -1\n\n// 0 - 15 => 4 bits\n// Ignore vendor prefixed and custom properties\nexport function declarationPropertyPrecedence(property: string): number {\n return property[0] == '-'\n ? 0\n : seperatorPrecedence(property) +\n (/^(?:(border-(?!w|c|sty)|[tlbr].{2,4}m?$|c.{7}$)|([fl].{5}l|g.{8}$|pl))/.test(property)\n ? +!!RegExp.$1 /* +1 */ || -!!RegExp.$2 /* -1 */\n : 0) +\n 1\n}\n\nexport interface ConvertedRule {\n /** The name to use for `&` expansion in selectors. Maybe empty for at-rules like `@import`, `@font-face`, `@media`, ... */\n n?: string | undefined\n\n /** The calculated precedence taking all variants into account. */\n p: number\n\n /** The rulesets (selectors and at-rules). expanded variants `@media ...`, `@supports ...`, `&:focus`, `.dark &` */\n r?: string[]\n\n /** Is this rule `!important` eg something like `!underline` or `!bg-red-500` or `!red-500` */\n i?: boolean | undefined\n}\n\nexport function convert(\n { n: name, i: important, v: variants = [] }: Partial,\n context: Context,\n precedence: number,\n conditions?: string[],\n): ConvertedRule {\n if (name) {\n name = toClassName({ n: name, i: important, v: variants })\n }\n\n conditions = [...asArray(conditions)]\n\n for (const variant of variants) {\n const screen = context.theme('screens', variant)\n\n const condition = (screen && mql(screen)) || context.v(variant)\n\n conditions.push(condition)\n\n precedence |= screen\n ? (1 << 26) /* Shifts.screens */ | atRulePrecedence(condition)\n : variant == 'dark'\n ? 1 << 30 /* Shifts.darkMode */\n : condition[0] == '@'\n ? atRulePrecedence(condition)\n : pseudoPrecedence(condition)\n }\n\n return { n: name, p: precedence, r: conditions, i: important }\n}\n","/* eslint-disable @typescript-eslint/restrict-plus-operands */\nimport type { TwindRule } from '../types'\nimport { Layer } from './precedence'\n\nconst collator = new Intl.Collator('en', { numeric: true })\n\n/**\n * Find the array index of where to add an element to keep it sorted.\n *\n * @returns The insertion index\n */\nexport function sortedInsertionIndex(array: readonly TwindRule[], element: TwindRule): number {\n // Find position using binary search\n // eslint-disable-next-line no-var\n for (var low = 0, high = array.length; low < high; ) {\n const pivot = (high + low) >> 1\n\n // Less-Then-Equal to add new equal element after all existing equal elements (stable sort)\n if (compareTwindRules(array[pivot], element) <= 0) {\n low = pivot + 1\n } else {\n high = pivot\n }\n }\n\n return high\n}\n\nexport function compareTwindRules(a: TwindRule, b: TwindRule): number {\n // base and overrides (css) layers are kept in order they are declared\n const layer = a.p & Layer.o\n\n if (layer == (b.p & Layer.o) && (layer == Layer.b || layer == Layer.o)) {\n return 0\n }\n\n return (\n a.p - b.p ||\n a.o - b.o ||\n // XXX: should we compare the conditions as well — already included in precedence\n // collator.compare(a.r as unknown as string, b.r as unknown as string) ||\n collator.compare(a.n as string, b.n as string)\n )\n}\n","/* eslint-disable @typescript-eslint/restrict-plus-operands */\nimport type { TwindRule } from '../types'\nimport { escape } from '../utils'\n\nexport function stringify(rule: TwindRule): string | undefined {\n if (rule.d) {\n const groups: string[] = []\n\n const selector = replaceEach(\n // merge all conditions into a selector string\n rule.r.reduce((selector, condition) => {\n if (condition[0] == '@') {\n groups.push(condition)\n return selector\n }\n\n // Go over the selector and replace the matching multiple selectors if any\n return condition ? merge(selector, condition) : selector\n }, '&'),\n // replace '&' with rule name or an empty string\n (selectorPart) => replaceReference(selectorPart, rule.n ? '.' + escape(rule.n) : ''),\n )\n\n if (selector) {\n groups.push(selector.replace(/:merge\\((.+?)\\)/g, '$1'))\n }\n\n return groups.reduceRight((body, grouping) => grouping + '{' + body + '}', rule.d)\n }\n}\n\nfunction replaceEach(selector: string, iteratee: (selectorPart: string) => string): string {\n return selector.replace(\n / *((?:\\(.+?\\)|\\[.+?\\]|[^,])+) *(,|$)/g,\n (_, selectorPart: string, comma: string) => iteratee(selectorPart) + comma,\n )\n}\n\nfunction replaceReference(selector: string, reference: string): string {\n return selector.replace(/&/g, reference)\n}\n\nfunction merge(selector: string, condition: string): string {\n return replaceEach(selector, (selectorPart) =>\n replaceEach(\n condition,\n // If the current condition has a nested selector replace it\n (conditionPart) => {\n const mergeMatch = /(:merge\\(.+?\\))(:[a-z-]+|\\\\[.+])/.exec(conditionPart)\n\n if (mergeMatch) {\n const selectorIndex = selectorPart.indexOf(mergeMatch[1])\n\n if (~selectorIndex) {\n // [':merge(.group):hover .rule', ':merge(.group):focus &'] -> ':merge(.group):focus:hover .rule'\n // ':merge(.group)' + ':focus' + ':hover .rule'\n return (\n selectorPart.slice(0, selectorIndex) +\n mergeMatch[0] +\n selectorPart.slice(selectorIndex + mergeMatch[1].length)\n )\n }\n\n // [':merge(.peer):focus~&', ':merge(.group):hover &'] -> ':merge(.peer):focus~:merge(.group):hover &'\n return replaceReference(selectorPart, conditionPart)\n }\n\n // Return the current selector with the key matching multiple selectors if any\n return replaceReference(conditionPart, selectorPart)\n },\n ),\n )\n}\n","/* eslint-disable @typescript-eslint/no-unsafe-return */\n/* eslint-disable @typescript-eslint/no-unsafe-argument */\n/* eslint-disable @typescript-eslint/no-unsafe-call */\n/* eslint-disable @typescript-eslint/no-unsafe-member-access */\n/* eslint-disable @typescript-eslint/no-unsafe-assignment */\n/* eslint-disable @typescript-eslint/no-explicit-any */\nimport type {\n BaseTheme,\n MaybeColorValue,\n ThemeConfig,\n ThemeFunction,\n ThemeSectionResolverContext,\n} from '../types'\n\nexport function makeThemeFunction({\n extend = {},\n ...base\n}: ThemeConfig): ThemeFunction {\n const resolved: Record = {}\n\n const resolveContext: ThemeSectionResolverContext = {\n colors: theme('colors'),\n\n theme,\n\n // Stub implementation as negated values are automatically infered and do _not_ need to be in the theme\n negative() {\n return {}\n },\n\n breakpoints(screens) {\n const breakpoints = {} as Record\n\n for (const key in screens) {\n if (typeof screens[key] == 'string') {\n breakpoints['screen-' + key] = screens[key] as string\n }\n }\n\n return breakpoints\n },\n }\n\n return theme as ThemeFunction\n\n function theme(sectionKey?: string, key?: string, defaultValue?: any): any {\n if (sectionKey) {\n if (/[.[]/.test(sectionKey)) {\n const path: string[] = []\n\n // dotted deep access: colors.gray.500 or or spacing[2.5]\n sectionKey.replace(\n /\\[([^\\]]+)\\]|([^.[]+)/g,\n (_, $1, $2 = $1) => path.push($2) as unknown as string,\n )\n\n sectionKey = path.shift() as string\n defaultValue = key\n key = path.join('-')\n }\n\n const section =\n resolved[sectionKey] ||\n // two-step deref to allow extend section to reference base section\n Object.assign(\n Object.assign(\n // Make sure to not get into recursive calls\n (resolved[sectionKey] = {}),\n deref(base, sectionKey),\n ),\n deref(extend, sectionKey),\n )\n\n if (key == null) return section\n\n return section[key || 'DEFAULT'] ?? defaultValue\n }\n\n // Collect the whole theme\n const result = {} as Record\n\n for (const section in base) {\n result[section] = theme(section)\n }\n\n return result\n }\n\n function deref(source: any, section: string): any {\n let value = source[section]\n\n if (typeof value == 'function') {\n value = value(resolveContext)\n }\n\n if (value && /color/i.test(section)) {\n return flattenColorPalette(value)\n }\n\n return value\n }\n}\n\nfunction flattenColorPalette(colors: Record, path: string[] = []): any {\n const flattend: Record = {}\n\n for (const key in colors) {\n const value = colors[key]\n const keyPath = key == 'DEFAULT' ? path : [...path, key]\n\n if (typeof value == 'object') {\n Object.assign(flattend, flattenColorPalette(value, keyPath))\n }\n\n flattend[keyPath.join('-')] = value\n\n if (key == 'DEFAULT') {\n flattend[[...path, key].join('-')] = value\n }\n }\n\n return flattend\n}\n","import type {\n BaseTheme,\n Context,\n RuleResult,\n TwindConfig,\n CSSProperties,\n MatchResult,\n MaybeArray,\n RuleResolver,\n MatchConverter,\n Rule,\n CSSObject,\n Variant,\n VariantResult,\n VariantResolver,\n Falsey,\n} from '../types'\n\nimport { makeThemeFunction } from './theme'\nimport { asArray, escape, hash as defaultHash, identity } from '../utils'\n\ntype ResolveFunction = (\n className: string,\n context: Context,\n) => RuleResult\n\ntype VariantFunction = (\n variant: string,\n context: Context,\n) => VariantResult\n\nexport function createContext({\n theme,\n darkMode,\n variants,\n rules,\n hash,\n stringify,\n ignorelist,\n}: TwindConfig): Context {\n // Used to cache resolved rule values\n const variantCache = new Map()\n\n // lazy created resolve functions\n const variantResolvers = new Map, VariantFunction>()\n\n // Used to cache resolved rule values\n const ruleCache = new Map()\n\n // lazy created resolve functions\n const ruleResolvers = new Map, ResolveFunction>()\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-argument\n const ignored = createRegExpExecutor(ignorelist, (value, condition) => condition.test(value))\n\n // add dark as last variant to allow user to override it\n // we can modify variants as it has been passed through defineConfig which already made a copy\n variants.push([\n 'dark',\n darkMode == 'class'\n ? '.dark &'\n : typeof darkMode === 'string' && darkMode != 'media'\n ? darkMode // a custom selector\n : '@media (prefers-color-scheme:dark)',\n ])\n\n return {\n theme: makeThemeFunction(theme),\n\n e: escape,\n\n h:\n typeof hash == 'function'\n ? (value) => hash(value, defaultHash)\n : hash\n ? defaultHash\n : identity,\n\n s(property, value) {\n return stringify(property, value, this)\n },\n\n v(value) {\n if (!variantCache.has(value)) {\n variantCache.set(\n value,\n find(value, variants, variantResolvers, getVariantResolver, this) || '&:' + value,\n )\n }\n\n return variantCache.get(value) as string\n },\n\n r(value) {\n if (!ruleCache.has(value)) {\n ruleCache.set(\n value,\n // TODO console.warn(`[twind] unknown rule \"${value}\"`),\n !ignored(value, this) && find(value, rules, ruleResolvers, getRuleResolver, this),\n )\n }\n\n return ruleCache.get(value)\n },\n }\n}\n\nfunction find(\n value: Value,\n list: Config[],\n cache: Map) => Result>,\n getResolver: (item: Config) => (value: Value, context: Context) => Result,\n context: Context,\n) {\n for (const item of list) {\n let resolver = cache.get(item)\n\n if (!resolver) {\n cache.set(item, (resolver = getResolver(item)))\n }\n\n const resolved = resolver(value, context)\n\n if (resolved) return resolved\n }\n}\n\nfunction getVariantResolver(\n variant: Variant,\n): VariantFunction {\n return createVariantFunction(variant[0], variant[1])\n}\n\nfunction getRuleResolver(\n rule: Rule,\n): ResolveFunction {\n if (Array.isArray(rule)) {\n return createResolveFunction(rule[0], rule[1], rule[2])\n }\n\n return createResolveFunction(rule)\n}\n\nfunction createVariantFunction(\n patterns: MaybeArray,\n\n resolve: string | VariantResolver,\n): VariantFunction {\n return createResolve(patterns, typeof resolve == 'function' ? resolve : () => resolve)\n}\n\nfunction createResolveFunction(\n patterns: MaybeArray,\n\n resolve?: keyof CSSProperties | string | CSSObject | RuleResolver,\n\n convert?: MatchConverter,\n): ResolveFunction {\n return createResolve(\n patterns,\n !resolve\n ? (match) =>\n ({\n [match[1]]: maybeNegate(\n match.input,\n match.slice(2).find(Boolean) || match.$$ || match.input,\n ),\n } as CSSObject)\n : typeof resolve == 'function'\n ? resolve\n : typeof resolve == 'string' && /^[\\w-]+$/.test(resolve) // a CSS property alias\n ? (match, context) =>\n ({\n [resolve]: convert\n ? convert(match, context)\n : maybeNegate(match.input, match.slice(1).find(Boolean) || match.$$ || match.input),\n } as CSSObject)\n : // CSSObject, shortcut or apply\n () => resolve,\n )\n}\n\nfunction maybeNegate($_: string, value: string): string {\n return $_[0] == '-' ? `calc(${value} * -1)` : value\n}\n\nfunction createResolve(\n patterns: MaybeArray,\n resolve: (match: MatchResult, context: Context) => Result,\n): (value: string, context: Context) => Result | undefined {\n return createRegExpExecutor(patterns, (value, condition, context) => {\n const match = condition.exec(value) as MatchResult | Falsey\n\n if (match) {\n // MATCH.$_ = value\n match.$$ = value.slice(match[0].length)\n\n return resolve(match, context)\n }\n })\n}\n\nfunction createRegExpExecutor(\n patterns: MaybeArray,\n run: (value: string, condition: RegExp, context: Context) => Result,\n): (value: string, context: Context) => Result | undefined {\n const conditions = asArray(patterns).map(toCondition)\n\n return (value, context) => {\n for (const condition of conditions) {\n const result = run(value, condition, context)\n\n if (result) return result\n }\n }\n}\n\n/**\n * Executes a search on a string using a regular expression pattern, and returns an array containing the results of that search.\n * @param string The String object or string literal on which to perform the search.\n */\n// type Condition = (string: string) => RegExpExecArray | Falsey\n\nfunction toCondition(value: string | RegExp): RegExp {\n // \"visible\" -> /^visible$/\n // \"(float)-(left|right|none)\" -> /^(float)-(left|right|none)$/\n // \"auto-rows-\" -> /^auto-rows-/\n // \"gap(-|$)\" -> /^gap(-|$)/\n\n // PERF: try to detect if we can skip the regex execution\n // if (typeof value == 'string') {\n // const prefix = /^[\\w-#~@]+(?!\\?)/.exec(value)?.[0]\n // value = new RegExp('^' + value + (value.includes('$') || value.slice(-1) == '-' ? '' : '$'))\n // if (prefix) {\n // return (string) => string.startsWith(prefix) && (value as RegExp).exec(string)\n // }\n // }\n // return (string) => (value as RegExp).exec(string)\n\n return typeof value == 'string'\n ? new RegExp('^' + value + (value.includes('$') || value.slice(-1) == '-' ? '' : '$'))\n : value\n}\n","import type { BaseTheme, Context, Falsey, RuleResult, TwindRule } from '../types'\nimport type { ParsedRule } from './parse'\n\nconst registry = new Map()\n\nexport type RegisterCallback = (rule: ParsedRule, context: Context) => Falsey | TwindRule[]\n\nexport function register(className: string, factory: RegisterCallback): string {\n registry.set(className, factory)\n return className\n}\n\nexport function resolve(\n rule: ParsedRule,\n context: Context,\n): RuleResult | TwindRule[] {\n const factory = registry.get(rule.n)\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument\n return factory ? factory(rule, context as any) : context.r(rule.n)\n}\n","import type { Falsey } from '../types'\nimport type { ParsedRule } from './parse'\nimport { convert } from './precedence'\nimport { register } from './registry'\nimport { translateWith } from './translate'\n\nexport function define(\n className: string,\n layer: number,\n rules: Falsey | ParsedRule[],\n useOrderOfRules?: boolean,\n): string {\n return register(className, (rule, context) => {\n const { n: name, p: precedence, r: conditions, i: important } = convert(rule, context, layer)\n\n return (\n rules &&\n translateWith(\n name as string,\n layer,\n rules,\n context,\n precedence,\n conditions,\n important,\n useOrderOfRules,\n )\n )\n })\n}\n","import type { ParsedRule } from './parse'\nimport { toClassName } from './to-class-name'\n\nexport function format(rules: ParsedRule[], seperator = ','): string {\n return rules.map(toClassName).join(seperator)\n}\n","import { hash } from '../utils'\nimport { define } from './define'\nimport { format } from './format'\nimport { Layer } from './precedence'\n\nexport interface ParsedRule {\n /**\n * The utility name including `-` if set, but without `!` and variants\n */\n readonly n: string\n\n /**\n * All variants without trailing colon: `hover`, `after:`, `[...]`\n */\n readonly v: string[]\n\n /**\n * Something like `!underline` or `!bg-red-500` or `!red-500`\n */\n readonly i?: boolean\n}\n\nfunction createRule(active: string[], current: ParsedRule[][]): void {\n if (active[active.length - 1] != '(') {\n const variants: string[] = []\n let important = false\n let negated = false\n let name = ''\n\n for (let value of active) {\n if (value == '(' || /[~@]$/.test(value)) continue\n\n if (value[0] == '!') {\n value = value.slice(1)\n important = !important\n }\n\n if (value.endsWith(':')) {\n variants[value == 'dark:' ? 'unshift' : 'push'](value.slice(0, -1))\n continue\n }\n\n if (value[0] == '-') {\n value = value.slice(1)\n negated = !negated\n }\n\n if (value.endsWith('-')) {\n value = value.slice(0, -1)\n }\n\n if (value && value != '&') {\n name += (name && '-') + value\n }\n }\n\n if (name) {\n if (negated) name = '-' + name\n\n current[0].push({ n: name, v: variants.filter(uniq), i: important })\n }\n }\n}\n\nfunction uniq(value: T, index: number, values: T[]): boolean {\n return values.indexOf(value) == index\n}\n\n// Remove comments (multiline and single line)\nexport function removeComments(tokens: string): string {\n return tokens.replace(/\\/\\*[^]*?\\*\\/|\\/\\/[^]*?$|\\s\\s+|\\n/gm, ' ')\n}\n\nconst cache = new Map()\n\nexport function parse(token: string): ParsedRule[] {\n let parsed = cache.get(token)\n\n if (!parsed) {\n token = removeComments(token)\n\n // Stack of active groupings (`(`), variants, or nested (`~` or `@`)\n const active: string[] = []\n\n // Stack of current rule list to put new rules in\n // the first `0` element is the current list\n const current: ParsedRule[][] = [[]]\n\n let startIndex = 0\n let skip = 0\n let position = 0\n\n // eslint-disable-next-line no-inner-declarations\n const commit = (isRule?: boolean, endOffset = 0) => {\n if (startIndex != position) {\n active.push(token.slice(startIndex, position + endOffset))\n\n if (isRule) {\n createRule(active, current)\n }\n }\n startIndex = position + 1\n }\n\n for (; position < token.length; position++) {\n const char = token[position]\n\n if (skip) {\n // within [...]\n // skip over until not skipping\n // ignore escaped chars\n if (token[position - 1] != '\\\\') {\n skip += +(char == '[') || -(char == ']')\n }\n } else if (char == '[') {\n // start to skip\n skip += 1\n } else if (char == '(') {\n // hover:(...) or utilitity-(...)\n commit()\n active.push(char)\n } else if (char == ':') {\n // hover: or after::\n if (token[position + 1] != ':') {\n commit(false, 1)\n }\n } else if (/[\\s,)]/.test(char)) {\n // whitespace, comma or closing brace\n commit(true)\n\n let lastGroup = active.lastIndexOf('(')\n\n if (char == ')') {\n // Close nested block\n const nested = active[lastGroup - 1]\n\n if (/[~@]$/.test(nested)) {\n const rules = current.shift() as ParsedRule[]\n\n active.length = lastGroup\n\n // remove variants that are already applied through active\n createRule([...active, '#'], current)\n const { v } = current[0].pop() as ParsedRule\n\n for (const rule of rules) {\n // if a rule has dark we need to splice after the first entry eg dark\n rule.v.splice(+(rule.v[0] == 'dark') - +(v[0] == 'dark'), v.length)\n }\n\n createRule(\n [\n ...active,\n define(\n // named nested\n nested.length > 1\n ? nested.slice(0, -1) + hash(JSON.stringify([nested, rules]))\n : nested + '(' + format(rules) + ')',\n Layer.s,\n rules,\n /@$/.test(nested),\n ),\n ],\n current,\n )\n }\n\n lastGroup = active.lastIndexOf('(', lastGroup - 1)\n }\n\n active.length = lastGroup + 1\n } else if (/[~@]/.test(char) && token[position + 1] == '(') {\n // start nested block\n // ~(...) or button~(...)\n // @(...) or button@(...)\n current.unshift([])\n }\n }\n\n // Consume remaining stack\n commit(true)\n\n cache.set(token, (parsed = current[0]))\n }\n\n return parsed\n}\n","import type { CSSObject, Falsey, Context, TwindRule, BaseTheme, MaybeArray } from '../types'\nimport type { ParsedRule } from './parse'\nimport type { ConvertedRule } from './precedence'\nimport { Layer, moveToLayer } from './precedence'\nimport { mql, hash, asArray } from '../utils'\n\nimport { atRulePrecedence, declarationPropertyPrecedence, convert } from './precedence'\nimport { stringify } from './stringify'\nimport { translateWith } from './translate'\nimport { parse } from './parse'\nimport { compareTwindRules } from './sorted-insertion-index'\n\nexport function serialize(\n style: CSSObject | Falsey,\n rule: Partial,\n context: Context,\n precedence: number,\n conditions: string[] = [],\n): TwindRule[] {\n return serialize$(style, convert(rule, context, precedence, conditions), context)\n}\n\nfunction serialize$(\n style: CSSObject | Falsey,\n { n: name, p: precedence, r: conditions = [], i: important }: ConvertedRule,\n context: Context,\n): TwindRule[] {\n const rules: TwindRule[] = []\n\n // The generated declaration block eg body of the css rule\n let declarations = ''\n\n // This ensures that 'border-top-width' has a higher precedence than 'border-top'\n let maxPropertyPrecedence = 0\n\n // More specific utilities have less declarations and a higher precedence\n let numberOfDeclarations = 0\n\n for (let key in style || {}) {\n const value = (style as Record)[key]\n\n if (key[0] == '@') {\n // at rules: https://developer.mozilla.org/en-US/docs/Web/CSS/At-rule\n if (!value) continue\n\n // @apply ...;\n if (key[1] == 'a') {\n rules.push(\n ...translateWith(\n name as string,\n precedence,\n parse(value as string),\n context,\n precedence,\n conditions,\n important,\n true /* useOrderOfRules */,\n ),\n )\n continue\n }\n\n // @layer \n if (key[1] == 'l') {\n for (const css of asArray(value as MaybeArray)) {\n rules.push(\n ...serialize$(\n css,\n {\n n: name,\n p: moveToLayer(precedence, Layer[key[7] as 'b']),\n r: conditions,\n i: important,\n },\n context,\n ),\n )\n }\n\n continue\n }\n\n // @import\n if (key[1] == 'i') {\n rules.push({\n // before all layers\n p: -1,\n o: 0,\n r: [],\n d: asArray(value)\n .filter(Boolean)\n .map((value) => key + ' ' + (value as string))\n .join(';'),\n })\n continue\n }\n\n // @keyframes\n // @font-face\n // TODO @font-feature-values\n if (key[1] == 'k' || key[1] == 'f') {\n // Use base layer\n // TODO support arrays?\n rules.push({\n p: Layer.d,\n o: 0,\n r: [key],\n d: serialize$(value as CSSObject, { p: Layer.d }, context)\n .map(stringify)\n .join(''),\n })\n continue\n }\n // -> All other are handled below; same as selector\n }\n\n // @media\n // @supports\n // selector\n if (typeof value == 'object' && !Array.isArray(value)) {\n // at-rule or non-global selector\n if (key[0] == '@' || key.includes('&')) {\n let rulePrecedence = precedence\n if (key[0] == '@') {\n // Handle `@media screen(sm)` and `@media (screen(sm) or ...)`\n key = key.replace(/\\bscreen\\(([^)]+)\\)/g, (_, screenKey) => {\n const screen = context.theme('screens', screenKey)\n\n if (screen) {\n rulePrecedence |= 1 << 26 /* Shifts.screens */\n return mql(screen, '')\n }\n\n return _\n })\n\n rulePrecedence |= atRulePrecedence(key)\n }\n\n rules.push(\n ...serialize$(\n value as CSSObject,\n {\n n: name,\n p: rulePrecedence,\n r: [...conditions, key],\n i: important,\n },\n context,\n ),\n )\n } else {\n // global selector\n rules.push(...serialize$(value as CSSObject, { p: precedence, r: [key] }, context))\n }\n } else if (key == 'label' && value) {\n name = (value as string) + hash(JSON.stringify([precedence, important, style]))\n } else if (value || value === 0) {\n // property -> hyphenate\n key = key.replace(/[A-Z]/g, (_) => '-' + _.toLowerCase())\n\n // Update precedence\n numberOfDeclarations += 1\n maxPropertyPrecedence = Math.max(maxPropertyPrecedence, declarationPropertyPrecedence(key))\n\n declarations +=\n (declarations ? ';' : '') +\n asArray(value)\n .map((value) =>\n context.s(\n key,\n // support theme(...) function in values\n // calc(100vh - theme('spacing.12'))\n // eslint-disable-next-line @typescript-eslint/restrict-plus-operands\n resolveThemeFunction('' + value, context) + (important ? ' !important' : ''),\n ),\n )\n .join(';')\n }\n }\n\n // PERF: prevent unshift using `rules = [{}]` above and then `rules[0] = {...}`\n rules.unshift({\n n: name && context.h(name),\n\n p: precedence,\n\n o:\n // number of declarations (descending)\n Math.max(0, 15 - numberOfDeclarations) +\n // greatest precedence of properties\n // if there is no property precedence this is most likely a custom property only declaration\n // these have the highest precedence\n Math.min(maxPropertyPrecedence || 15, 15) * 1.5,\n\n r: conditions,\n\n // stringified declarations\n d: declarations,\n })\n\n return rules.sort(compareTwindRules)\n}\n\nexport function resolveThemeFunction(\n value: string,\n context: Context,\n): string {\n // support theme(...) function in values\n // calc(100vh - theme('spacing.12'))\n // theme('borderColor.DEFAULT', 'currentColor')\n\n // PERF: check for theme before running the regexp\n // if (value.includes('theme')) {\n return value.replace(\n /theme\\(([\"'`])?(.+?)\\1(?:\\s*,\\s*([\"'`])?(.+?)\\3)?\\)/g,\n (_, __, key, ___, value) => context.theme(key, value) as string,\n )\n // }\n\n // return value\n}\n","/* eslint-disable @typescript-eslint/restrict-plus-operands */\nimport type { TwindRule } from '../types'\n\nexport function merge(rules: TwindRule[], name: string): TwindRule[] {\n // merge:\n // - same conditions\n // - replace name with hash of name + condititions + declarations\n // - precedence:\n // - combine bits or use max precendence\n // - set layer bit to merged\n const result: TwindRule[] = []\n\n let current: TwindRule | undefined\n\n for (const rule of rules) {\n if (!rule.d) {\n result.push({ ...rule, n: rule.n && name })\n } else if (current?.p == rule.p && '' + current.r == '' + rule.r) {\n current.c = [current.c, rule.c].filter(Boolean).join(' ')\n current.d = [current.d, rule.d].filter(Boolean).join(';')\n } else {\n // only set name for named rules eg not for global or className propagation rules\n result.push((current = { ...rule, n: rule.n && name }))\n }\n }\n\n return result\n}\n","/* eslint-disable @typescript-eslint/restrict-plus-operands */\nimport type { TwindRule, Context, BaseTheme } from '../types'\nimport type { ParsedRule } from './parse'\n\nimport { parse } from './parse'\nimport { convert, Layer, moveToLayer } from './precedence'\n\nimport { resolve } from './registry'\nimport { serialize } from './serialize'\nimport { sortedInsertionIndex } from './sorted-insertion-index'\nimport { toClassName } from './to-class-name'\nimport { asArray } from '../utils'\nimport { merge } from './merge'\n\nexport function translate(\n rules: readonly ParsedRule[],\n context: Context,\n precedence = Layer.u,\n conditions?: string[],\n important?: boolean,\n): TwindRule[] {\n // Sorted by precedence\n const result: TwindRule[] = []\n\n for (const rule of rules) {\n for (const cssRule of translate$(rule, context, precedence, conditions, important)) {\n result.splice(sortedInsertionIndex(result, cssRule), 0, cssRule)\n }\n }\n\n return result\n}\n\nfunction translate$(\n rule: ParsedRule,\n context: Context,\n precedence: number,\n conditions?: string[],\n important?: boolean,\n): TwindRule[] {\n rule = { ...rule, i: rule.i || important }\n\n const resolved = resolve(rule, context)\n\n if (!resolved) {\n // propagate className as is\n return [{ c: toClassName(rule), p: 0, o: 0, r: [] }]\n }\n\n // a list of class names\n if (typeof resolved == 'string') {\n // eslint-disable-next-line @typescript-eslint/no-extra-semi\n ;({ r: conditions, p: precedence } = convert(rule, context, precedence, conditions))\n\n return merge(translate(parse(resolved), context, precedence, conditions, rule.i), rule.n)\n }\n\n if (Array.isArray(resolved)) {\n return resolved.map((rule) => ({\n o: 0,\n ...rule,\n r: [...asArray(conditions), ...asArray(rule.r)],\n p: moveToLayer(precedence, rule.p ?? precedence),\n }))\n }\n\n return serialize(resolved, rule, context, precedence, conditions)\n}\n\nexport function translateWith(\n name: string,\n layer: number,\n rules: ParsedRule[],\n context: Context,\n precedence: number,\n conditions?: string[] | undefined,\n important?: boolean | undefined,\n useOrderOfRules?: boolean,\n) {\n return merge(\n (useOrderOfRules\n ? rules.flatMap((rule) => translate([rule], context, precedence, conditions, important))\n : translate(rules, context, precedence, conditions, important)\n ).map((rule) =>\n // do not move defaults\n // move only rules with a name unless they are in the base layer\n rule.p & Layer.o && (rule.n || layer == Layer.b)\n ? { ...rule, p: moveToLayer(rule.p, layer), o: 0 }\n : rule,\n ),\n name,\n )\n}\n","/* eslint-disable @typescript-eslint/no-explicit-any */\nimport type {\n BaseTheme,\n Preset,\n TwindConfig,\n TwindUserConfig,\n ExtractThemes,\n TwindPresetConfig,\n} from './types'\n\nimport { asArray } from './utils'\n\nexport function defineConfig[] = Preset[]>({\n presets = [] as unknown as Presets,\n ...userConfig\n}: TwindUserConfig): TwindConfig> {\n // most user config values go first to have precendence over preset config\n // only `preflight` and `theme` are applied as last preset to override all presets\n let config: TwindConfig> = {\n preflight: userConfig.preflight !== false && [],\n darkMode: undefined,\n theme: {},\n variants: asArray(userConfig.variants),\n rules: asArray(userConfig.rules),\n ignorelist: asArray(userConfig.ignorelist),\n hash: userConfig.hash,\n stringify: userConfig.stringify || noprefix,\n }\n\n for (const preset of asArray([\n ...presets,\n {\n darkMode: userConfig.darkMode,\n preflight: userConfig.preflight !== false && asArray(userConfig.preflight),\n theme: userConfig.theme as TwindConfig>['theme'],\n } as TwindPresetConfig,\n ])) {\n const {\n preflight,\n darkMode = config.darkMode,\n theme,\n variants,\n rules,\n hash = config.hash,\n ignorelist,\n stringify = config.stringify,\n } = typeof preset == 'function' ? preset(config) : (preset as TwindPresetConfig)\n\n config = {\n // values defined by user or previous presets take precedence\n preflight: config.preflight !== false &&\n preflight !== false && [...config.preflight, ...asArray(preflight)],\n\n darkMode,\n\n theme: {\n ...config.theme,\n ...theme,\n extend: {\n ...config.theme.extend,\n ...theme?.extend,\n },\n },\n\n variants: [...config.variants, ...asArray(variants)],\n rules: [...config.rules, ...asArray(rules)],\n ignorelist: [...config.ignorelist, ...asArray(ignorelist)],\n\n hash,\n stringify,\n } as TwindConfig>\n }\n\n return config\n}\n\nfunction noprefix(property: string, value: string): string {\n return property + ':' + value\n}\n","/* eslint-disable @typescript-eslint/no-explicit-any */\nimport type {\n BaseTheme,\n ExtractThemes,\n Preset,\n Twind,\n Sheet,\n TwindConfig,\n TwindRule,\n TwindUserConfig,\n} from './types'\n\nimport { sortedInsertionIndex } from './internal/sorted-insertion-index'\nimport { stringify } from './internal/stringify'\nimport { createContext } from './internal/context'\nimport { translate, translateWith } from './internal/translate'\nimport { parse } from './internal/parse'\nimport { defineConfig } from './define-config'\nimport { asArray } from './utils'\nimport { serialize } from './internal/serialize'\nimport { Layer } from './internal/precedence'\n\nexport function twind(\n config: TwindConfig,\n sheet: Sheet,\n): Twind\n\nexport function twind<\n Theme = BaseTheme,\n Presets extends Preset[] = Preset[],\n Target = unknown,\n>(\n config: TwindUserConfig,\n sheet: Sheet,\n): Twind, Target>\n\nexport function twind(userConfig: TwindConfig | TwindUserConfig, sheet: Sheet): Twind {\n const config = defineConfig(userConfig as TwindUserConfig)\n\n const context = createContext(config)\n\n // Map of tokens to generated className\n const cache = new Map()\n\n // An array of precedence by index within the sheet\n // always sorted\n const sortedPrecedences: TwindRule[] = []\n\n // Cache for already inserted css rules\n // to prevent double insertions\n const insertedRules = new Set()\n\n function insert(rule: TwindRule): string | undefined {\n rule = { ...rule, n: rule.n && context.h(rule.n) }\n\n const css = stringify(rule)\n\n // If not already inserted\n if (css && !insertedRules.has(css)) {\n // Mark rule as inserted\n insertedRules.add(css)\n\n // Find the correct position\n const index = sortedInsertionIndex(sortedPrecedences, rule)\n\n // Insert\n sheet.insert(css, index, rule)\n\n // Update sorted index\n sortedPrecedences.splice(index, 0, rule)\n }\n\n return rule.n\n }\n\n return Object.defineProperties(\n function tw(tokens) {\n if (!cache.size) {\n for (let preflight of asArray(config.preflight)) {\n if (typeof preflight == 'function') {\n preflight = preflight(context)\n }\n\n if (preflight) {\n // eslint-disable-next-line @typescript-eslint/no-extra-semi\n ;(typeof preflight == 'string'\n ? translateWith('', Layer.b, parse(preflight), context, Layer.b, [], false, true)\n : serialize(preflight, {}, context, Layer.b)\n ).forEach(insert)\n }\n }\n }\n\n let className = cache.get(tokens)\n\n if (!className) {\n const classNames = new Set()\n\n for (const rule of translate(parse(tokens), context)) {\n classNames.add(rule.c).add(insert(rule))\n }\n\n className = [...classNames].filter(Boolean).join(' ')\n\n // Remember the generated class name\n cache.set(tokens, className).set(className, className)\n }\n\n return className\n } as Twind,\n Object.getOwnPropertyDescriptors({\n get target() {\n return sheet.target\n },\n\n theme: context.theme,\n\n clear() {\n sheet.clear()\n insertedRules.clear()\n cache.clear()\n sortedPrecedences.length = 0\n },\n\n destroy() {\n this.clear()\n sheet.destroy()\n },\n }),\n )\n}\n","import type { BaseTheme, Twind } from './types'\n\nimport { changed } from './internal/changed'\nimport { tw as tw$ } from './runtime'\n\nexport function observe(\n tw: Twind = tw$ as Twind,\n target = typeof document != 'undefined' && document.documentElement,\n): Twind {\n if (!target) return tw\n\n const observer = new MutationObserver(handleMutationRecords)\n\n observer.observe(target, {\n attributeFilter: ['class'],\n subtree: true,\n childList: true,\n })\n\n // handle class attribute on target\n handleClassAttributeChange(target)\n\n // handle children of target\n handleMutationRecords([{ target, type: '' }])\n\n // monkey patch tw.destroy to disconnect this observer\n // eslint-disable-next-line @typescript-eslint/unbound-method\n const { destroy } = tw\n tw.destroy = () => {\n observer.disconnect()\n destroy.call(tw)\n }\n\n return tw\n\n function handleMutationRecords(records: MinimalMutationRecord[]): void {\n for (const { type, target } of records) {\n if (type[0] == 'a' /* attribute */) {\n // class attribute has been changed\n handleClassAttributeChange(target as Element)\n } else {\n /* childList */\n // some nodes have been added — find all with a class attribute\n // eslint-disable-next-line @typescript-eslint/no-extra-semi\n ;(target as Element).querySelectorAll('[class]').forEach(handleClassAttributeChange)\n }\n }\n\n // remove pending mutations — these are triggered by updating the class attributes\n observer.takeRecords()\n // XXX maybe we need to handle all pending mutations\n // observer.takeRecords().forEach(handleMutation)\n }\n\n function handleClassAttributeChange(target: Element): void {\n // Not using target.classList.value (not supported in all browsers) or target.class (this is an SVGAnimatedString for svg)\n const tokens = target.getAttribute('class')\n\n let className: string\n\n // try do keep classNames unmodified\n if (tokens && changed(tokens, (className = tw(tokens)))) {\n // Not using `target.className = ...` as that is read-only for SVGElements\n target.setAttribute('class', className)\n }\n }\n}\n\n/**\n * Simplified MutationRecord which allows us to pass an\n * ArrayLike (compatible with Array and NodeList) `addedNodes` and\n * omit other properties we are not interested in.\n */\ninterface MinimalMutationRecord {\n readonly type: string\n readonly target: Node\n}\n","import type { Sheet } from './types'\nimport { asArray } from './utils'\n\ndeclare global {\n interface Window {\n tw?: HTMLStyleElement\n }\n}\n\nlet el: HTMLStyleElement\nfunction createStyleElement(\n // 1. look for existing style element — usually from SSR\n // 2. append to document.head — this assumes that document.head has at least one child node\n referenceNode = document.querySelector('style[data-twind]') || (document.head.lastChild as Node),\n): HTMLStyleElement {\n // insert new style element after existing element which allows to override styles\n return (referenceNode.parentNode as Node).insertBefore(\n ((el = document.createElement('style')), (el.dataset.twind = ''), el),\n referenceNode.nextSibling,\n )\n}\n\nexport function cssom(target = createStyleElement().sheet as CSSStyleSheet): Sheet {\n return {\n target,\n\n clear() {\n // remove all added rules\n for (let index = target.cssRules.length; index--; ) {\n target.deleteRule(index)\n }\n },\n\n destroy() {\n target.ownerNode?.remove()\n },\n\n insert(css, index) {\n try {\n // Insert\n target.insertRule(css, index)\n } catch (error) {\n // Empty rule to keep index valid — not using `*{}` as that would show up in all rules (DX)\n target.insertRule(':root{}', index)\n\n // Some thrown errors are because of specific pseudo classes\n // lets filter them to prevent unnecessary warnings\n // ::-moz-focus-inner\n // :-moz-focusring\n if (!/:-[mwo]/.test(css)) {\n console.warn(error, css)\n }\n }\n },\n }\n}\n\nexport function dom(target = createStyleElement()): Sheet {\n return {\n target,\n\n clear() {\n // remove all added nodes\n while (target.childNodes.length) {\n target.removeChild(target.lastChild as Node)\n }\n },\n\n destroy() {\n target.remove()\n },\n\n insert(css, index) {\n target.insertBefore(document.createTextNode(css), target.childNodes[index] || null)\n },\n }\n}\n\nexport function virtual(target: string[] = []): Sheet {\n return {\n target,\n\n clear() {\n target.length = 0\n },\n\n destroy() {\n this.clear()\n },\n\n insert(css, index) {\n target.splice(index, 0, css)\n },\n }\n}\n\nexport function stringify(target: unknown): string {\n // string[] | CSSStyleSheet | HTMLStyleElement\n return (\n (target as HTMLStyleElement).innerHTML ||\n // eslint-disable-next-line @typescript-eslint/restrict-plus-operands\n ((target as CSSStyleSheet).cssRules\n ? Array.from((target as CSSStyleSheet).cssRules, (rule) => rule.cssText)\n : asArray(target)\n ).join('')\n )\n}\n","/* eslint-disable @typescript-eslint/no-explicit-any */\nimport type {\n Twind,\n BaseTheme,\n TwindConfig,\n Sheet,\n TwindUserConfig,\n ExtractThemes,\n Preset,\n} from './types'\n\nimport { twind } from './twind'\nimport { observe } from './observe'\nimport { cssom, virtual } from './sheets'\nimport { noop } from './utils'\n\nexport function auto(setup: () => void): () => void {\n // If we run in the browser we call setup at latest when the body is inserted\n // This algorith works well for _normal_ scripts (``)\n // but not for modules because those are executed __after__ the DOM is ready\n // and we would have FOUC\n if (typeof document != 'undefined' && document.currentScript) {\n const cancelAutoSetup = () => observer.disconnect()\n\n const observer: MutationObserver = new MutationObserver((mutationsList) => {\n for (const { target } of mutationsList) {\n // If we reach the body we immediately run the setup to prevent FOUC\n if (target === document.body) {\n setup()\n return cancelAutoSetup()\n }\n }\n })\n\n observer.observe(document.documentElement, {\n childList: true,\n subtree: true,\n })\n\n return cancelAutoSetup\n }\n\n return noop\n}\n\n/**\n * A proxy to the currently active Twind instance.\n */\nexport const tw = /* @__PURE__ */ Object.defineProperties(\n // just exposing the active as tw should work with most bundlers\n // as ES module export can be re-assigned BUT some bundlers to not honor this\n // -> using a delegation proxy here\n function tw(...args) {\n return active(...args)\n } as Twind,\n Object.getOwnPropertyDescriptors({\n get target() {\n return active.target\n },\n theme(...args: unknown[]) {\n return active.theme(...(args as []))\n },\n\n clear() {\n return active.clear()\n },\n\n destroy() {\n return active.destroy()\n },\n }),\n)\n\nlet active: Twind\n\n/**\n * Manages a single Twind instance — works in browser, Node.js, Deno, workers...\n *\n * @param config\n * @param sheet\n * @param target\n * @returns\n */\nexport function setup(\n config?: TwindConfig,\n sheet?: Sheet,\n target?: HTMLElement,\n): Twind\n\nexport function setup<\n Theme = BaseTheme,\n Presets extends Preset[] = Preset[],\n SheetTarget = unknown,\n>(\n config?: TwindUserConfig,\n sheet?: Sheet,\n target?: HTMLElement,\n): Twind, SheetTarget>\n\nexport function setup(\n config: TwindConfig | TwindUserConfig = {},\n sheet: Sheet = (typeof document != 'undefined'\n ? cssom()\n : virtual()) as unknown as Sheet,\n target?: HTMLElement,\n): Twind {\n const firstRun = !active\n\n if (!firstRun) {\n active.destroy()\n }\n\n active = observe(twind(config as TwindUserConfig, sheet), target)\n\n if (firstRun && typeof document != 'undefined') {\n // first run in browser\n\n // remove server-side generated style element\n // after `observe` twind has taken over and the SSR styles are no longer used\n document.querySelector('style[data-twind=ssr]')?.remove()\n\n // If they body was hidden autofocus the first element\n if (!document.activeElement) {\n // eslint-disable-next-line @typescript-eslint/no-extra-semi, @typescript-eslint/no-unnecessary-type-assertion\n ;(document.querySelector('[autofocus]') as HTMLElement | null)?.focus()\n }\n }\n\n return active as Twind\n}\n","import { changed } from './internal/changed'\nimport { tw as tw$ } from './runtime'\n\n/**\n * Used for static HTML processing (usually to provide SSR support for your javascript-powered web apps)\n *\n * **Note**: Consider using {@link inject} or {@link extract} instead.\n *\n * 1. parse the markup and process element classes with the provided Twind instance\n * 2. update the class attributes _if_ necessary\n * 3. return the HTML string with the final element classes\n *\n * ```js\n * import { consume, stringify, tw } from 'twind'\n *\n * function render() {\n * const html = renderApp()\n *\n * // clear all styles — optional\n * tw.clear()\n *\n * // generated markup\n * const markup = consume(html)\n *\n * // create CSS\n * const css = stringify(tw.target)\n *\n * // inject as last element into the head\n * return markup.replace('', ``)\n * }\n * ```\n *\n * You can provide your own Twind instance:\n *\n * ```js\n * import { consume, stringify } from 'twind'\n * import { tw } from './custom/twind/instance'\n *\n * function render() {\n * const html = renderApp()\n *\n * // clear all styles — optional\n * tw.clear()\n *\n * // generated markup\n * const markup = consume(html)\n *\n * // create CSS\n * const css = stringify(tw.target)\n *\n * // inject as last element into the head\n * return markup.replace('', ``)\n * }\n * ```\n *\n * @param markup HTML to process\n * @param tw a {@link Twind} instance\n * @returns possibly modified HTML\n */\nexport function consume(markup: string, tw: (className: string) => string = tw$): string {\n let result = ''\n let lastChunkStart = 0\n\n extract(markup, (startIndex, endIndex, quote) => {\n const value = markup.slice(startIndex, endIndex)\n const className = tw(value)\n\n // We only need to shift things around if we need to actually change the markup\n if (changed(value, className)) {\n // We've hit another mutation boundary\n\n // Add quote if necessary\n quote = quote ? '' : '\"'\n\n result += markup.slice(lastChunkStart, startIndex) + quote + className + quote\n\n lastChunkStart = endIndex\n }\n })\n\n // Combine the current result with the tail-end of the input\n return result + markup.slice(lastChunkStart, markup.length)\n}\n\n// For now we are using a simple parser adapted from htm (https://github.com/developit/htm/blob/master/src/build.mjs)\n// If we find any issues we can switch to something more sophisticated like\n// - https://github.com/acrazing/html5parser\n// - https://github.com/fb55/htmlparser2\n\nconst MODE_SLASH = 0\nconst MODE_TEXT = 1\nconst MODE_WHITESPACE = 2\nconst MODE_TAGNAME = 3\nconst MODE_COMMENT = 4\nconst MODE_ATTRIBUTE = 5\n\nfunction extract(\n markup: string,\n onClass: (startIndex: number, endIndex: number, quote: string) => void,\n): void {\n let mode = MODE_TEXT\n let startIndex = 0\n let quote = ''\n let attributeName = ''\n\n const commit = (currentIndex: number): void => {\n if (mode == MODE_ATTRIBUTE && attributeName == 'class') {\n onClass(startIndex, currentIndex, quote)\n }\n }\n\n for (let position = 0; position < markup.length; position++) {\n const char = markup[position]\n\n if (mode == MODE_TEXT) {\n if (char == '<') {\n mode = markup.substr(position + 1, 3) == '!--' ? MODE_COMMENT : MODE_TAGNAME\n }\n } else if (mode == MODE_COMMENT) {\n // Ignore everything until the last three characters are '-', '-' and '>'\n if (char == '>' && markup.slice(position - 2, position) == '--') {\n mode = MODE_TEXT\n }\n } else if (quote) {\n if (char == quote && markup[position - 1] != '\\\\') {\n commit(position)\n mode = MODE_WHITESPACE\n quote = ''\n }\n } else if (char == '\"' || char == \"'\") {\n quote = char\n startIndex += 1\n } else if (char == '>') {\n commit(position)\n mode = MODE_TEXT\n } else if (!mode) {\n // MODE_SLASH\n // Ignore everything until the tag ends\n } else if (char == '=') {\n attributeName = markup.slice(startIndex, position)\n mode = MODE_ATTRIBUTE\n startIndex = position + 1\n } else if (char == '/' && (mode < MODE_ATTRIBUTE || markup[position + 1] == '>')) {\n commit(position)\n mode = MODE_SLASH\n } else if (/\\s/.test(char)) {\n // \n commit(position)\n mode = MODE_WHITESPACE\n startIndex = position + 1\n }\n }\n}\n","export function interleave(\n strings: TemplateStringsArray,\n interpolations: readonly Interpolations[],\n handle: (interpolation: Interpolations) => string,\n): string {\n return interpolations.reduce(\n (result: string, interpolation, index) => result + handle(interpolation) + strings[index + 1],\n strings[0],\n )\n}\n","import type { CSSObject, CSSValue } from '../types'\nimport { interleave } from './interleave'\nimport { removeComments } from './parse'\n\nexport function astish(\n strings: CSSObject | string | TemplateStringsArray,\n interpolations: readonly CSSValue[],\n): CSSObject[] {\n return Array.isArray(strings)\n ? astish$(\n interleave(strings as TemplateStringsArray, interpolations, (interpolation) =>\n interpolation != null && typeof interpolation != 'boolean'\n ? (interpolation as unknown as string)\n : '',\n ),\n )\n : typeof strings == 'string'\n ? astish$(strings)\n : [strings as CSSObject]\n}\n\n// Based on https://github.com/cristianbote/goober/blob/master/src/core/astish.js\nconst newRule = / *(?:(?:([\\u0080-\\uFFFF\\w-%@]+) *:? *([^{;]+?);|([^;}{]*?) *{)|(}))/g\n\n/**\n * Convert a css style string into a object\n */\nfunction astish$(css: string): CSSObject[] {\n css = removeComments(css)\n\n const rules: CSSObject[] = []\n const tree: string[] = []\n let block: RegExpExecArray | null\n\n while ((block = newRule.exec(css))) {\n // Remove the current entry\n if (block[4]) tree.pop()\n\n if (block[3]) {\n // new nested\n tree.push(block[3])\n } else if (!block[4]) {\n rules.push(\n tree.reduceRight((css, block) => ({ [block]: css }), {\n [block[1]]: block[2],\n } as CSSObject),\n )\n }\n }\n\n return rules\n}\n","import type { CSSObject, CSSValue } from './types'\n\nimport { register } from './internal/registry'\nimport { serialize } from './internal/serialize'\nimport { hash } from './utils'\nimport { Layer } from './internal/precedence'\nimport { merge } from './internal/merge'\nimport { astish } from './internal/astish'\n\nexport function css(strings: TemplateStringsArray, ...interpolations: readonly CSSValue[]): string\n\nexport function css(style: CSSObject | string): string\n\nexport function css(\n strings: CSSObject | string | TemplateStringsArray,\n ...interpolations: readonly CSSValue[]\n): string {\n const ast = astish(strings, interpolations)\n\n const className = (ast.find((o) => o.label)?.label || 'css') + hash(JSON.stringify(ast))\n\n return register(className, (rule, context) =>\n merge(\n ast.flatMap((css) => serialize(css, rule, context, Layer.o)),\n className,\n ),\n )\n}\n","import type { Class } from '../types'\nimport { interleave } from './interleave'\n\n// based on https://github.com/lukeed/clsx and https://github.com/jorgebucaran/classcat\nexport function interpolate(\n strings: TemplateStringsArray | Class,\n interpolations: Class[],\n): string {\n return Array.isArray(strings) && Array.isArray((strings as unknown as TemplateStringsArray).raw)\n ? interleave(strings as unknown as TemplateStringsArray, interpolations, (value) =>\n toString(value).trim(),\n )\n : interpolations\n .filter(Boolean)\n .reduce(\n (result: string, value) => result + toString(value),\n strings ? toString(strings as Class) : '',\n )\n}\n\nfunction toString(value: Class): string {\n let result = ''\n let tmp: string\n\n if (value && typeof value == 'object') {\n if (Array.isArray(value)) {\n if ((tmp = interpolate(value[0], value.slice(1)))) {\n result += ' ' + tmp\n }\n } else {\n for (const key in value) {\n if (value[key]) result += ' ' + key\n }\n }\n } else if (value != null && typeof value != 'boolean') {\n // eslint-disable-next-line @typescript-eslint/restrict-plus-operands\n result += ' ' + value\n }\n\n return result\n}\n","import type { Class } from './types'\nimport { parse } from './internal/parse'\nimport { format } from './internal/format'\nimport { interpolate } from './internal/interpolate'\n\nexport function cx(strings: TemplateStringsArray | Class, ...interpolations: Class[]): string {\n return format(parse(interpolate(strings, interpolations)), ' ')\n}\n","import { consume } from './consume'\nimport { stringify } from './sheets'\nimport { tw as tw$ } from './runtime'\n\n/**\n * Result of {@link extract}\n */\nexport interface ExtractResult {\n /** The possibly modified HTML */\n html: string\n\n /** The generated CSS */\n css: string\n}\n\n/**\n * Used for static HTML processing (usually to provide SSR support for your javascript-powered web apps)\n *\n * **Note**: Consider using {@link inject} instead.\n *\n * **Note**: This {@link Twind.clear clears} the Twind instance before processing the HTML.\n *\n * 1. parse the markup and process element classes with the provided Twind instance\n * 2. update the class attributes _if_ necessary\n * 3. return the HTML string with the final element classes\n *\n * ```js\n * import { extract } from 'twind'\n *\n * function render() {\n * const { html, css } = extract(renderApp())\n *\n * // inject as last element into the head\n * return html.replace('', ``)\n * }\n * ```\n *\n * You can provide your own Twind instance:\n *\n * ```js\n * import { extract } from 'twind'\n * import { tw } from './custom/twind/instance'\n *\n * function render() {\n * const { html, css } = extract(renderApp(), tw)\n *\n * // inject as last element into the head\n * return html.replace('', ``)\n * }\n * ```\n *\n * @param markup HTML to process\n * @param tw a {@link Twind} instance (default: twind managed tw)\n * @returns the possibly modified html and css\n */\nexport function extract(html: string, tw = tw$): ExtractResult {\n tw.clear()\n return { html: consume(html, tw), css: stringify(tw.target) }\n}\n","import type { CSSNested, CSSObject, CSSValue } from './types'\n\nimport { tw as tw$ } from './runtime'\nimport { astish } from './internal/astish'\nimport { css } from './css'\n\n/**\n * Injects styles into the global scope and is useful for applications such as gloabl styles, CSS resets or font faces.\n *\n * It **does not** return a class name, but adds the styles within the base layer to the stylesheet directly.\n */\nexport function injectGlobal(\n this: ((tokens: string) => string) | undefined | void,\n style: CSSNested | string,\n): void\n\nexport function injectGlobal(\n this: ((tokens: string) => string) | undefined | void,\n strings: TemplateStringsArray,\n ...interpolations: readonly CSSValue[]\n): void\n\nexport function injectGlobal(\n this: ((tokens: string) => string) | undefined | void,\n strings: CSSNested | string | TemplateStringsArray,\n ...interpolations: readonly CSSValue[]\n): void {\n const tw = typeof this == 'function' ? this : tw$\n\n tw(\n css({\n '@layer base': astish(strings as CSSObject, interpolations),\n } as CSSObject),\n )\n}\n","import { extract } from './extract'\nimport { tw as tw$ } from './runtime'\nimport { identity } from './utils'\n\n/**\n * Options for {@link inline}\n */\nexport interface InlineOptions {\n /**\n * {@link Twind} instance to use (default: {@link tw$ | module tw})\n */\n tw?: typeof tw$\n\n /**\n * Allows to minify the resulting CSS.\n */\n minify?: InlineMinify\n}\n\nexport interface InlineMinify {\n /**\n * Called to minify the CSS.\n *\n * @param css the CSS to minify\n * @param html the HTML that will be used — allows to only include above-the-fold CSS\n * @return the resulting CSS\n */\n (css: string, html: string): string\n}\n/**\n * Used for static HTML processing (usually to provide SSR support for your javascript-powered web apps)\n *\n * **Note**: This {@link Twind.clear clears} the Twind instance before processing the HTML.\n *\n * 1. parse the markup and process element classes with the provided Twind instance\n * 2. update the class attributes _if_ necessary\n * 3. inject a style element with the CSS as last element into the head\n * 4. return the HTML string with the final element classes\n *\n * ```js\n * import { inline } from 'twind'\n *\n * function render() {\n * return inline(renderApp())\n * }\n * ```\n *\n * Minify CSS with [@parcel/css](https://www.npmjs.com/package/@parcel/css):\n *\n * ```js\n * import { inline } from 'twind'\n * import { transform } from '@parcel/css'\n *\n * function render() {\n * return inline(renderApp(), { minify: (css) => transform({ filename: 'twind.css', code: Buffer.from(css), minify: true }) })\n * }\n * ```\n *\n * You can provide your own Twind instance:\n *\n * ```js\n * import { inline } from 'twind'\n * import { tw } from './custom/twind/instance'\n *\n * function render() {\n * return inline(renderApp(), { tw })\n * }\n * ```\n *\n * @param markup HTML to process\n * @param tw a {@link Twind} instance\n * @returns the resulting HTML\n */\nexport function inline(markup: string, options: InlineOptions['tw'] | InlineOptions = {}): string {\n const { tw = tw$, minify = identity } =\n typeof options == 'function' ? ({ tw: options } as InlineOptions) : options\n\n const { html, css } = extract(markup, tw)\n\n // inject as last element into the head\n return html.replace('', ``)\n}\n","import type { CSSObject, CSSValue, StringLike } from './types'\n\nimport { escape, hash } from './utils'\nimport { tw as tw$ } from './runtime'\nimport { astish } from './internal/astish'\nimport { css } from './css'\n\nexport interface KeyframesFunction {\n (style: CSSObject | string): StringLike\n\n (strings: TemplateStringsArray, ...interpolations: readonly CSSValue[]): StringLike\n\n bind(thisArg?: ((tokens: string) => string) | undefined | void): Keyframes & {\n [label: string]: KeyframesFunction\n }\n}\n\nexport type Keyframes = KeyframesFunction & {\n [label: string]: KeyframesFunction\n}\n\nexport const keyframes = /* @__PURE__ */ bind()\n\nfunction bind(thisArg: ((tokens: string) => string) | undefined | void): Keyframes {\n return new Proxy(\n function keyframes(\n strings: CSSObject | string | TemplateStringsArray,\n ...interpolations: readonly CSSValue[]\n ): StringLike {\n return keyframes$(thisArg, '', strings, interpolations)\n } as Keyframes,\n {\n get(target, name) {\n if (name === 'bind') {\n return bind\n }\n\n if (name in target) return target[name as string]\n\n return function namedKeyframes(\n strings: CSSObject | string | TemplateStringsArray,\n ...interpolations: readonly CSSValue[]\n ): StringLike {\n return keyframes$(thisArg, name as string, strings, interpolations)\n }\n },\n },\n )\n}\n\nfunction keyframes$(\n thisArg: ((tokens: string) => string) | undefined | void,\n name: string,\n strings: CSSObject | string | TemplateStringsArray,\n interpolations: readonly CSSValue[],\n): StringLike {\n const ast = astish(strings, interpolations)\n\n const keyframeName = escape(name + hash(JSON.stringify([name, ast])))\n\n // lazy inject keyframes\n return {\n toString() {\n // lazy access tw\n const tw = typeof thisArg == 'function' ? thisArg : tw$\n\n tw(\n css({\n [`@keyframes ${keyframeName}`]: astish(strings, interpolations),\n } as unknown as CSSObject),\n )\n\n return keyframeName\n },\n } as StringLike\n}\n","import type { Class, Nested } from './types'\nimport { format } from './internal/format'\nimport { parse } from './internal/parse'\nimport { interpolate } from './internal/interpolate'\n\nexport const apply = /* @__PURE__ */ nested('@')\nexport const shortcut = /* @__PURE__ */ nested('~')\n\nfunction nested(marker: string): Nested {\n return new Proxy(\n function nested(strings: TemplateStringsArray | Class, ...interpolations: Class[]): string {\n return nested$('', strings, interpolations)\n } as Nested,\n {\n get(target, name) {\n if (name in target) return target[name as string]\n\n return function namedNested(\n strings: TemplateStringsArray | Class,\n ...interpolations: Class[]\n ): string {\n return nested$(name as string, strings, interpolations)\n }\n },\n },\n )\n\n function nested$(\n name: string,\n strings: TemplateStringsArray | Class,\n interpolations: Class[],\n ): string {\n return format(parse(name + marker + '(' + interpolate(strings, interpolations) + ')'))\n }\n}\n","/* eslint-disable @typescript-eslint/no-extra-semi */\nimport type {\n Context,\n ColorValue,\n ColorFunction,\n BaseTheme,\n MatchResult,\n RuleResolver,\n CSSProperties,\n CSSObject,\n RuleResult,\n ThemeValue,\n KebabCase,\n} from './types'\n\nimport { toColorValue } from './colors'\nimport { resolveThemeFunction } from './internal/serialize'\n\nexport type ThemeMatchResult = MatchResult & {\n /** The found theme value */\n _: Value\n}\n\nexport type ThemeRuleResolver = (\n match: ThemeMatchResult,\n context: Context,\n) => RuleResult\n\nexport type ThemeMatchConverter = (\n match: ThemeMatchResult,\n context: Context,\n) => string\n\nexport function fromTheme<\n Theme extends BaseTheme = BaseTheme,\n Section extends keyof Theme & string = keyof Theme & string,\n>(\n /** Theme section to use (default: `$1` — The first matched group) */\n section?: '' | Section | KebabCase
,\n\n /** The css property (default: value of {@link section}) */\n resolve?: keyof CSSProperties | ThemeRuleResolver, Theme>,\n\n convert?: ThemeMatchConverter, Theme>,\n): RuleResolver {\n const factory: (\n match: ThemeMatchResult>,\n context: Context,\n section: Section,\n ) => RuleResult = !resolve\n ? ({ 1: $1, _ }, context, section) => ({ [$1 || section]: _ } as CSSObject)\n : typeof resolve == 'string'\n ? (match, context) => ({ [resolve]: convert ? convert(match, context) : match._ } as CSSObject)\n : resolve\n\n return (match, context) => {\n const themeSection = camelize(section || match[1]) as Section\n\n const value =\n context.theme(themeSection, match.$$) ??\n /** Arbitrary lookup type */\n // https://github.com/tailwindlabs/tailwindcss/blob/875c850b37a57bc651e1fed91e3d89af11bdc79f/src/util/pluginUtils.js#L163\n // type?: 'lookup' | 'color' | 'line-width' | 'length' | 'any' | 'shadow'\n (arbitrary(match.$$, themeSection, context) as ThemeValue)\n\n if (value != null) {\n ;(match as ThemeMatchResult>)._ =\n match.input[0] == '-'\n ? (`calc(${value as string} * -1)` as ThemeValue)\n : value\n\n return factory(match as ThemeMatchResult>, context, themeSection)\n }\n }\n}\n\nexport type FilterByThemeValue = {\n [key in keyof Theme & string]: ThemeValue extends Value ? Theme[key] : never\n}\n\nexport interface ColorFromThemeValue {\n value: string\n color: ColorFunction\n}\n\nexport interface ColorFromThemeOptions<\n Theme extends BaseTheme = BaseTheme,\n Section extends keyof FilterByThemeValue = keyof FilterByThemeValue<\n Theme,\n ColorValue\n >,\n OpacitySection extends keyof FilterByThemeValue = keyof FilterByThemeValue<\n Theme,\n string\n >,\n> {\n /** Theme section to use (default: `$0.replace('-', 'Color')` — The matched string with `Color` appended) */\n section?: Section | KebabCase
\n /** The css property (default: value of {@link section}) */\n property?: keyof CSSProperties\n /** `--tw-${$0}opacity` -> '--tw-text-opacity' */\n opacityVariable?: string | false\n /** `section.replace('Color', 'Opacity')` -> 'textOpacity' */\n opacitySection?: OpacitySection\n selector?: string\n}\n\nexport function colorFromTheme<\n Theme extends BaseTheme = BaseTheme,\n Section extends keyof FilterByThemeValue = keyof FilterByThemeValue<\n Theme,\n ColorValue\n >,\n OpacitySection extends keyof FilterByThemeValue = keyof FilterByThemeValue<\n Theme,\n string\n >,\n>(\n options: ColorFromThemeOptions = {},\n resolve?: ThemeRuleResolver,\n): RuleResolver {\n return (match, context) => {\n // text- -> textColor\n // ring-offset(?:-|$) -> ringOffsetColor\n const { section = (camelize(match[0]).replace('-', '') + 'Color') as Section } = options\n\n // extract color and opacity\n // rose-500 -> ['rose-500']\n // [hsl(0_100%_/_50%)] -> ['[hsl(0_100%_/_50%)]']\n // indigo-500/100 -> ['indigo-500', '100']\n // [hsl(0_100%_/_50%)]/[.25] -> ['[hsl(0_100%_/_50%)]', '[.25]']\n // eslint-disable-next-line no-sparse-arrays\n if (!/^(\\[[^\\]]+]|[^/]+?)(?:\\/(.+))?$/.test(match.$$)) return\n\n const { $1: colorMatch, $2: opacityMatch } = RegExp\n\n const colorValue =\n (context.theme(section, colorMatch) as ColorValue) || arbitrary(colorMatch, section, context)\n\n if (!colorValue) return\n\n const {\n // text- -> --tw-text-opacity\n // ring-offset(?:-|$) -> --tw-ring-offset-opacity\n // TODO move this default into preset-tailwind?\n opacityVariable = `--tw-${match[0].replace(/-$/, '')}-opacity`,\n opacitySection = section.replace('Color', 'Opacity') as OpacitySection,\n property = section,\n selector,\n } = options\n\n const opacityValue =\n (context.theme(opacitySection, opacityMatch || 'DEFAULT') as string | undefined) ||\n (opacityMatch && arbitrary(opacityMatch, opacitySection, context))\n\n const color = toColorValue(colorValue, {\n opacityVariable: opacityVariable || undefined,\n opacityValue: opacityValue || undefined,\n })\n\n // if (typeof color != 'string') {\n // console.warn(`Invalid color ${colorMatch} (from ${match.input}):`, color)\n // return\n // }\n\n if (resolve) {\n ;(match as ThemeMatchResult)._ = {\n value: color,\n color: (options) => toColorValue(colorValue, options),\n }\n\n return resolve(match as ThemeMatchResult, context)\n }\n\n const properties = {} as Record\n\n if (opacityVariable && color.includes(opacityVariable)) {\n properties[opacityVariable] = opacityValue || '1'\n }\n\n properties[property] = color\n\n return (selector ? { [selector]: properties } : properties) as CSSObject\n }\n}\n\nexport function arbitrary(\n value: string,\n section: string,\n context: Context,\n): string | undefined {\n if (value[0] == '[' && value.slice(-1) == ']') {\n value = resolveThemeFunction(value.slice(1, -1), context)\n\n // TODO remove arbitrary type prefix — we do not need it but user may use it\n // https://github.com/tailwindlabs/tailwindcss/blob/master/src/util/dataTypes.js\n // url, number, percentage, length, line-width, shadow, color, image, gradient, position, family-name, lookup, any, generic-name, absolute-size, relative-size\n\n // If this is a color section and the value is a hex color, color function or color name\n if (/color|fill|stroke/i.test(section)) {\n if (/^(#|((hsl|rgb)a?|hwb|lab|lch|color)\\(|[a-z]+$)/.test(value)) {\n return value\n }\n } else if (/image/i.test(section)) {\n // url(, [a-z]-gradient(, image(, cross-fade(, image-set(\n if (/^[a-z-]+\\(/.test(value)) {\n return value\n }\n } else {\n // TODO how to differentiate arbitary values for\n // - backgroundSize vs backgroundPosition\n // - fontWeight vs fontFamily\n\n if (value.includes('calc(')) {\n value = value.replace(\n /(-?\\d*\\.?\\d(?!\\b-.+[,)](?![^+\\-/*])\\D)(?:%|[a-z]+)?|\\))([+\\-/*])/g,\n '$1 $2 ',\n )\n }\n\n // Convert `_` to ` `, except for escaped underscores `\\_` but not between brackets\n return value\n .replace(\n /(^|[^\\\\])_+(?![^(]*\\))/g,\n (fullMatch, characterBefore: string) =>\n characterBefore + ' '.repeat(fullMatch.length - 1),\n )\n .replace(/\\\\_(?![^(]*\\))/g, '_')\n }\n }\n}\n\nfunction camelize(value: string): string {\n return value.replace(/-./g, (x) => x[1].toUpperCase())\n}\n","/* eslint-disable @typescript-eslint/restrict-plus-operands */\n// Based on https://github.com/modulz/stitches\n// License MIT\n\nimport type { Falsey, MatchResult } from './types'\nimport { parse } from './internal/parse'\nimport { Layer } from './internal/precedence'\n\nimport { escape, hash } from './utils'\nimport { define } from './internal/define'\n\nexport type StrictMorphVariant = T extends number\n ? `${T}` | T\n : T extends 'true'\n ? true | T\n : T extends 'false'\n ? false | T\n : T\n\nexport type MorphVariant = T extends number\n ? `${T}` | T\n : T extends 'true'\n ? boolean | T\n : T extends 'false'\n ? boolean | T\n : T extends `${number}`\n ? number | T\n : T\n\nexport type StyleTokenValue = string | Falsey\n\n// No support for thunks yet — these may use props that are not in the generated class name\n// and may therefore override each other\nexport type StyleToken = StyleTokenValue\n\n/**\n * Allows to extract the supported properties of a style function.\n *\n * Here is an example for `react`\n * ```js\n * import { HTMLAttributes } from \"react\";\n * import { style, PropsOf } from \"twind\";\n * const button = style({ ... })\n * type ButtonProps = PropsOf\n * export const Button = (props: ButtonProps & HTMLAttributes) => {\n * return