@master/css-compiler 2.0.0-beta.99 → 2.0.0-rc.70

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/core.mjs ADDED
@@ -0,0 +1,2019 @@
1
+ import { createCSSDirectiveVariantReference, CSSDirectiveError, createCSSDirectiveSourceReference } from '@master/css-schema/css-directives';
2
+ import { getCSSTransform, encodeCSS, decodeCSS } from './css-transform.mjs';
3
+ export { setCSSTransform } from './css-transform.mjs';
4
+ import { removeSourceRanges, createSourceLocationResolver, collectCSSDirectiveRanges, replaceSourceRanges, findCSSClosingQuote, findCSSStatementEnd, findCSSBlockEnd, collectMasterCSSClassListTokenRanges, skipCSSWhitespace } from '@master/css-lexer';
5
+ import { collectStandaloneCSSDirectiveExtractionPolicy, removeStandaloneCSSDirectives, createCSSDirectiveExtractionPolicy } from './lexer/standalone-master.mjs';
6
+ export { findStandaloneCSSDirectiveStatements, findStandaloneMasterDirectiveStatements, mergeCSSDirectiveExtractionPolicy, removeStandaloneMasterDirectives } from './lexer/standalone-master.mjs';
7
+ import { combineSelectorLists } from './utils/selectors.mjs';
8
+
9
+ const MASTER_CUSTOM_AT_RULES = {
10
+ settings: {
11
+ prelude: '*',
12
+ body: 'style-block'
13
+ },
14
+ theme: {
15
+ prelude: '*',
16
+ body: 'style-block'
17
+ },
18
+ defaults: {
19
+ prelude: null,
20
+ body: 'style-block'
21
+ },
22
+ components: {
23
+ prelude: null,
24
+ body: 'style-block'
25
+ },
26
+ utilities: {
27
+ prelude: null,
28
+ body: 'style-block'
29
+ },
30
+ 'custom-variant': {
31
+ prelude: '*',
32
+ body: 'style-block'
33
+ },
34
+ variant: {
35
+ prelude: '*',
36
+ body: 'style-block'
37
+ },
38
+ dark: {
39
+ prelude: null,
40
+ body: 'style-block'
41
+ },
42
+ light: {
43
+ prelude: null,
44
+ body: 'style-block'
45
+ },
46
+ slot: {
47
+ prelude: null,
48
+ body: null
49
+ },
50
+ compose: {
51
+ prelude: '*',
52
+ body: null
53
+ },
54
+ reference: {
55
+ prelude: '<string>',
56
+ body: null
57
+ }
58
+ };
59
+ const MANAGED_DEFINITION_DIRECTIVE_LAYERS = {
60
+ defaults: 'defaults',
61
+ components: 'components',
62
+ utilities: 'utilities'
63
+ };
64
+ const MASTER_VARIANT_SHORTHAND_TOKENS = {
65
+ dark: '@dark',
66
+ light: '@light'
67
+ };
68
+ function createSourceReference(parsed, range) {
69
+ return createCSSDirectiveSourceReference(parsed.filename, {
70
+ start: range.start,
71
+ end: range.end
72
+ }, parsed.source);
73
+ }
74
+ function decodeCSSQuotedString(source) {
75
+ return source.replace(/\\([\s\S])/g, '$1');
76
+ }
77
+ function findCSSReferenceStatements(source, filename = 'master.css') {
78
+ const statements = [];
79
+ for (const range of collectCSSDirectiveRanges(source)){
80
+ if (range.name !== 'reference') continue;
81
+ if (range.depth !== 0) {
82
+ throw new Error('@reference must be top-level');
83
+ }
84
+ if (range.blockRange) {
85
+ throw new Error('@reference requires a statement');
86
+ }
87
+ if (!range.semicolonRange) {
88
+ throw new Error('@reference requires a semicolon');
89
+ }
90
+ if (range.quotedStringRanges.length !== 1) {
91
+ throw new Error('@reference requires one quoted CSS resource');
92
+ }
93
+ const prelude = source.slice(range.preludeRange.start, range.preludeRange.end).trim();
94
+ const quoted = source.slice(range.quotedStringRanges[0].start, range.quotedStringRanges[0].end);
95
+ if (prelude !== quoted) {
96
+ throw new Error('@reference only accepts one quoted CSS resource');
97
+ }
98
+ statements.push({
99
+ start: range.start,
100
+ end: range.end,
101
+ statement: source.slice(range.start, range.end),
102
+ source: decodeCSSQuotedString(source.slice(range.quotedStringRanges[0].contentRange.start, range.quotedStringRanges[0].contentRange.end)),
103
+ file: filename
104
+ });
105
+ }
106
+ return statements;
107
+ }
108
+ function removeCSSReferenceStatements(source, filename = 'master.css') {
109
+ return removeSourceRanges(source, findCSSReferenceStatements(source, filename));
110
+ }
111
+ function trimSourceRangeEnd(source, start, end) {
112
+ while(end > start && /\s/.test(source[end - 1] || ''))end--;
113
+ return end;
114
+ }
115
+ function createSelectorSourceReference(parsed, rule) {
116
+ const source = parsed.source;
117
+ const loc = rule.value?.loc;
118
+ const resolveLocation = parsed.sourceLocationResolver;
119
+ if (!source || !loc || !resolveLocation) return;
120
+ const start = resolveLocation({
121
+ line: loc.line,
122
+ column: loc.column
123
+ });
124
+ if (start === -1) return;
125
+ const statementEnd = findCSSStatementEnd(source, start);
126
+ if (statementEnd.reason !== 'block') return;
127
+ return createSourceReference(parsed, {
128
+ start,
129
+ end: trimSourceRangeEnd(source, start, statementEnd.end)
130
+ });
131
+ }
132
+ function parseOnOff(value) {
133
+ if (value === 'on') return true;
134
+ if (value === 'off') return false;
135
+ }
136
+ function parseDefaultMode(value) {
137
+ if (value === 'false') throw new Error('default-mode must be a mode name or none');
138
+ return value;
139
+ }
140
+ function parseNumber(value) {
141
+ const numberValue = Number(value);
142
+ if (!Number.isNaN(numberValue) && String(numberValue) === value) return numberValue;
143
+ }
144
+ function parseList(value) {
145
+ return value.split(',').flatMap((part)=>part.trim().split(/\s+/)).filter(Boolean);
146
+ }
147
+ function parseVariableValue(value) {
148
+ const trimmed = value.trim();
149
+ const numberValue = parseNumber(trimmed);
150
+ return numberValue === undefined ? trimmed : numberValue;
151
+ }
152
+ function addThemeMode(manifestInput, mode) {
153
+ manifestInput.modes ??= [];
154
+ if (!manifestInput.modes.includes(mode)) manifestInput.modes.push(mode);
155
+ }
156
+ function normalizeThemeTokenName(property) {
157
+ if (!property.startsWith('--')) {
158
+ throw new Error(`@theme token declarations must be CSS custom properties: ${property}`);
159
+ }
160
+ const name = property.slice(2);
161
+ if (!name) {
162
+ throw new Error('@theme token name cannot be empty');
163
+ }
164
+ return name;
165
+ }
166
+ function defineThemeVariable(manifestInput, property, rawValue, mode, inline, isStatic) {
167
+ const name = normalizeThemeTokenName(property);
168
+ const value = parseVariableValue(rawValue);
169
+ if (mode) {
170
+ addThemeMode(manifestInput, mode);
171
+ }
172
+ manifestInput.variables ??= [];
173
+ const definition = {
174
+ name,
175
+ value,
176
+ ...mode ? {
177
+ mode
178
+ } : {},
179
+ ...inline ? {
180
+ inline: true
181
+ } : {},
182
+ ...isStatic ? {
183
+ static: true
184
+ } : {}
185
+ };
186
+ const foundIndex = manifestInput.variables.findIndex((existing)=>existing.name === definition.name && existing.mode === definition.mode);
187
+ if (foundIndex !== -1) {
188
+ manifestInput.variables.splice(foundIndex, 1);
189
+ }
190
+ manifestInput.variables.push(definition);
191
+ }
192
+ function parseMasterOption(manifestInput, property, value) {
193
+ switch(property){
194
+ case 'root-size':
195
+ {
196
+ const rootSize = parseNumber(value);
197
+ if (rootSize === undefined) throw new Error('root-size must be a number');
198
+ manifestInput.rootSize = rootSize;
199
+ return true;
200
+ }
201
+ case 'base-unit':
202
+ {
203
+ const baseUnit = parseNumber(value);
204
+ if (baseUnit === undefined) throw new Error('base-unit must be a number');
205
+ manifestInput.baseUnit = baseUnit;
206
+ return true;
207
+ }
208
+ case 'default-mode':
209
+ manifestInput.defaultMode = parseDefaultMode(value);
210
+ return true;
211
+ case 'mode-trigger':
212
+ if (value !== 'class' && value !== 'media' && value !== 'host') {
213
+ throw new Error('mode-trigger must be class, media, or host');
214
+ }
215
+ manifestInput.modeTrigger = value;
216
+ return true;
217
+ case 'important':
218
+ {
219
+ const important = parseOnOff(value);
220
+ if (important === undefined) throw new Error('important must be on or off');
221
+ manifestInput.important = important;
222
+ return true;
223
+ }
224
+ case 'modes':
225
+ for (const mode of parseList(value)){
226
+ addThemeMode(manifestInput, mode);
227
+ }
228
+ return true;
229
+ case 'scope':
230
+ manifestInput.scope = value;
231
+ return true;
232
+ default:
233
+ return false;
234
+ }
235
+ }
236
+ function formatDeclaration(declaration) {
237
+ const result = getCSSTransform()({
238
+ filename: 'master-css-declaration.css',
239
+ code: encodeCSS('.x{}'),
240
+ visitor: {
241
+ Rule: {
242
+ style (rule) {
243
+ rule.value.declarations.declarations = [
244
+ declaration
245
+ ];
246
+ return rule;
247
+ }
248
+ }
249
+ }
250
+ });
251
+ const output = decodeCSS(result.code);
252
+ const bodyStart = output.indexOf('{');
253
+ const bodyEnd = output.lastIndexOf('}');
254
+ const body = output.slice(bodyStart + 1, bodyEnd).trim();
255
+ return body.replace(/;$/, '').trim();
256
+ }
257
+ function formatSelectors(selectors) {
258
+ const result = getCSSTransform()({
259
+ filename: 'master-css-selector.css',
260
+ code: encodeCSS('.x{color:red}'),
261
+ minify: true,
262
+ visitor: {
263
+ Rule: {
264
+ style (rule) {
265
+ rule.value.selectors = selectors;
266
+ return rule;
267
+ }
268
+ }
269
+ }
270
+ });
271
+ const output = decodeCSS(result.code);
272
+ return output.slice(0, output.indexOf('{')).trim();
273
+ }
274
+ function collectSelectorClassNames(value, classNames = new Set()) {
275
+ if (!value || typeof value !== 'object') return classNames;
276
+ if (Array.isArray(value)) {
277
+ for (const item of value){
278
+ collectSelectorClassNames(item, classNames);
279
+ }
280
+ return classNames;
281
+ }
282
+ const node = value;
283
+ if (node.type === 'class' && typeof node.name === 'string') {
284
+ classNames.add(node.name);
285
+ }
286
+ for (const key of Object.keys(node)){
287
+ collectSelectorClassNames(node[key], classNames);
288
+ }
289
+ return classNames;
290
+ }
291
+ function getSelectorClassNames(selector) {
292
+ return [
293
+ ...collectSelectorClassNames(selector)
294
+ ];
295
+ }
296
+ function recordNativeClassNames(parsed, classNames) {
297
+ for (const className of classNames){
298
+ if (!parsed.nativeClassNames.includes(className)) {
299
+ parsed.nativeClassNames.push(className);
300
+ }
301
+ }
302
+ }
303
+ function getNativeStyleSelectorFilters(rule, parsed, classFilter) {
304
+ const selectors = rule.value.selectors;
305
+ if (!selectors?.length) return;
306
+ const selectorEntries = selectors.map((selector)=>({
307
+ selector,
308
+ classNames: getSelectorClassNames(selector)
309
+ }));
310
+ recordNativeClassNames(parsed, selectorEntries.flatMap((entry)=>entry.classNames));
311
+ if (!classFilter) return;
312
+ const selectorFilters = selectorEntries.map(({ classNames })=>!classNames.length || classNames.some((className)=>classFilter.has(className)));
313
+ if (selectorFilters.every(Boolean)) return;
314
+ return selectorFilters;
315
+ }
316
+ function removeEmptyRuleBlock(rule) {
317
+ return rule.value?.rules?.length ? undefined : [];
318
+ }
319
+ function pruneEmptyRuleBlocks(code, filename) {
320
+ return getCSSTransform()({
321
+ filename,
322
+ code,
323
+ visitor: {
324
+ Rule: {
325
+ media: removeEmptyRuleBlock,
326
+ supports: removeEmptyRuleBlock,
327
+ container: removeEmptyRuleBlock,
328
+ 'starting-style': removeEmptyRuleBlock,
329
+ 'layer-block': removeEmptyRuleBlock
330
+ }
331
+ }
332
+ }).code;
333
+ }
334
+ function filterNativeCSS(code, filename, parsed, classFilter) {
335
+ const selectorFilters = [];
336
+ return getCSSTransform()({
337
+ filename,
338
+ code,
339
+ visitor: {
340
+ Rule: {
341
+ style (rule) {
342
+ const filters = getNativeStyleSelectorFilters(rule, parsed, classFilter);
343
+ if (!filters) return;
344
+ if (!filters.some(Boolean)) return [];
345
+ selectorFilters.push(...filters);
346
+ }
347
+ },
348
+ Selector () {
349
+ if (!selectorFilters.length) return;
350
+ if (!selectorFilters.shift()) return [];
351
+ }
352
+ }
353
+ }).code;
354
+ }
355
+ function formatDeclarationValue(declaration) {
356
+ if (declaration.property === 'unparsed') {
357
+ return formatTokenOrValues(declaration.value.value);
358
+ }
359
+ const formatted = formatDeclarationValueOverride(declaration);
360
+ if (formatted !== undefined) return formatted;
361
+ let declarationText;
362
+ try {
363
+ declarationText = formatDeclaration(declaration);
364
+ } catch (error) {
365
+ const fallback = formatDeclarationValueFallback(declaration);
366
+ if (fallback !== undefined) return fallback;
367
+ throw error;
368
+ }
369
+ const colonIndex = declarationText.indexOf(':');
370
+ return declarationText.slice(colonIndex + 1).trim();
371
+ }
372
+ function formatNumber(value) {
373
+ return String(value).replace(/^(-?)0\./, '$1.');
374
+ }
375
+ function formatDeclarationValueOverride(declaration) {
376
+ if (declaration.property !== 'aspect-ratio') return;
377
+ const value = declaration.value;
378
+ if (!Array.isArray(value.ratio)) return;
379
+ const ratio = `${formatNumber(value.ratio[0])}/${formatNumber(value.ratio[1])}`;
380
+ return value.auto ? `auto ${ratio}` : ratio;
381
+ }
382
+ function formatDimensionNumber(value) {
383
+ if (Number.isInteger(value) && Math.abs(value) >= 1_000_000_000) {
384
+ return value.toExponential().replace('e+', 'e');
385
+ }
386
+ return formatNumber(value);
387
+ }
388
+ function formatDimensionValue(value) {
389
+ if (value?.type !== 'dimension') return;
390
+ return `${formatDimensionNumber(value.value.value)}${value.value.unit}`;
391
+ }
392
+ function formatBorderRadiusCorner(value) {
393
+ if (!Array.isArray(value) || value.length !== 2) return;
394
+ const horizontal = formatDimensionValue(value[0]);
395
+ const vertical = formatDimensionValue(value[1]);
396
+ if (!horizontal || !vertical) return;
397
+ return horizontal === vertical ? horizontal : `${horizontal} ${vertical}`;
398
+ }
399
+ function formatDeclarationValueFallback(declaration) {
400
+ if (declaration.property === 'custom') {
401
+ const value = declaration.value;
402
+ if (Array.isArray(value.value)) return formatTokenOrValues(value.value);
403
+ }
404
+ if (declaration.property !== 'border-radius') return;
405
+ const value = declaration.value;
406
+ const corners = [
407
+ value.topLeft,
408
+ value.topRight,
409
+ value.bottomRight,
410
+ value.bottomLeft
411
+ ].map(formatBorderRadiusCorner);
412
+ const firstCorner = corners[0];
413
+ if (!firstCorner || corners.some((corner)=>corner !== firstCorner)) return;
414
+ return firstCorner;
415
+ }
416
+ function formatPropertyId(propertyId) {
417
+ return propertyId.property || '';
418
+ }
419
+ function formatVariableName(name) {
420
+ return name.ident;
421
+ }
422
+ function formatVariable(value) {
423
+ const name = formatVariableName(value.name);
424
+ const fallback = value.fallback && formatTokenOrValues(value.fallback);
425
+ return fallback ? `var(${name}, ${fallback})` : `var(${name})`;
426
+ }
427
+ function formatEnvironmentVariable(value) {
428
+ const name = value.name.ident || value.name.value || '';
429
+ const fallback = value.fallback && formatTokenOrValues(value.fallback);
430
+ return fallback ? `env(${name}, ${fallback})` : `env(${name})`;
431
+ }
432
+ function formatToken(token) {
433
+ switch(token.type){
434
+ case 'ident':
435
+ return token.value;
436
+ case 'at-keyword':
437
+ return '@' + token.value;
438
+ case 'hash':
439
+ case 'id-hash':
440
+ return '#' + token.value;
441
+ case 'string':
442
+ return JSON.stringify(token.value);
443
+ case 'unquoted-url':
444
+ return `url(${token.value})`;
445
+ case 'number':
446
+ return String(token.value);
447
+ case 'percentage':
448
+ return `${token.value * 100}%`;
449
+ case 'dimension':
450
+ return `${token.value}${token.unit}`;
451
+ case 'white-space':
452
+ return token.value;
453
+ case 'comment':
454
+ return `/*${token.value}*/`;
455
+ case 'colon':
456
+ return ':';
457
+ case 'semicolon':
458
+ return ';';
459
+ case 'comma':
460
+ return ',';
461
+ case 'delim':
462
+ return token.value;
463
+ case 'function':
464
+ return `${token.value}(`;
465
+ case 'parenthesis-block':
466
+ return '(';
467
+ case 'square-bracket-block':
468
+ return '[';
469
+ case 'curly-bracket-block':
470
+ return '{';
471
+ case 'close-parenthesis':
472
+ return ')';
473
+ case 'close-square-bracket':
474
+ return ']';
475
+ case 'close-curly-bracket':
476
+ return '}';
477
+ default:
478
+ return '';
479
+ }
480
+ }
481
+ function formatTokenOrValue(value) {
482
+ if (value.type === 'token') return formatToken(value.value);
483
+ if (value.type === 'dashed-ident') return value.value;
484
+ if (value.type === 'length') return `${formatNumber(value.value.value)}${value.value.unit}`;
485
+ if (value.type === 'angle') return `${formatNumber(value.value.value)}${value.value.type}`;
486
+ if (value.type === 'time') return value.value.type === 'seconds' ? `${formatNumber(value.value.value)}s` : `${formatNumber(value.value.value)}ms`;
487
+ if (value.type === 'resolution') return `${formatNumber(value.value.value)}${value.value.type}`;
488
+ if (value.type === 'var') return formatVariable(value.value);
489
+ if (value.type === 'env') return formatEnvironmentVariable(value.value);
490
+ if (value.type === 'function') return `${value.value.name}(${formatTokenOrValues(value.value.arguments)})`;
491
+ if (value.type === 'url') return `url(${JSON.stringify(value.value.url)})`;
492
+ if (value.type === 'animation-name') {
493
+ if (value.value.type === 'none') return 'none';
494
+ if (value.value.type === 'string') return JSON.stringify(value.value.value);
495
+ return value.value.value;
496
+ }
497
+ const declaration = {
498
+ property: 'custom',
499
+ value: {
500
+ name: '--x',
501
+ value: [
502
+ value
503
+ ]
504
+ }
505
+ };
506
+ return formatDeclarationValue(declaration);
507
+ }
508
+ function formatTokenOrValues(values) {
509
+ return values.map(formatTokenOrValue).join('').trim();
510
+ }
511
+ function formatPrelude(prelude) {
512
+ if (!prelude) return '';
513
+ if (typeof prelude === 'string') return prelude.trim();
514
+ if (Array.isArray(prelude)) return formatTokenOrValues(prelude);
515
+ if (prelude.type === 'token-list') return formatTokenOrValues(prelude.value);
516
+ if (Array.isArray(prelude.value)) return formatTokenOrValues(prelude.value);
517
+ if (typeof prelude.value === 'string') return prelude.value.trim();
518
+ return '';
519
+ }
520
+ const COMPARISON_OPERATORS = {
521
+ 'equal': '=',
522
+ 'greater-than': '>',
523
+ 'greater-than-equal': '>=',
524
+ 'less-than': '<',
525
+ 'less-than-equal': '<='
526
+ };
527
+ function formatFeatureValue(value) {
528
+ if (value === undefined || value === null) return '';
529
+ if (typeof value === 'string' || typeof value === 'number') return String(value);
530
+ switch(value.type){
531
+ case 'ident':
532
+ return value.value;
533
+ case 'number':
534
+ return String(value.value);
535
+ case 'length':
536
+ {
537
+ let resolvedValue = value.value;
538
+ while(resolvedValue && typeof resolvedValue === 'object' && 'value' in resolvedValue && !('unit' in resolvedValue)){
539
+ resolvedValue = resolvedValue.value;
540
+ }
541
+ if (typeof resolvedValue === 'number') return formatNumber(resolvedValue);
542
+ return `${formatNumber(resolvedValue.value)}${resolvedValue.unit || ''}`;
543
+ }
544
+ case 'ratio':
545
+ return `${value.value.numerator}/${value.value.denominator}`;
546
+ default:
547
+ return formatPrelude(value) || String(value.value ?? '');
548
+ }
549
+ }
550
+ function formatCondition(condition) {
551
+ if (!condition) return '';
552
+ switch(condition.type){
553
+ case 'feature':
554
+ {
555
+ const feature = condition.value;
556
+ switch(feature.type){
557
+ case 'plain':
558
+ return `(${feature.name}:${formatFeatureValue(feature.value)})`;
559
+ case 'range':
560
+ return `(${feature.name}${COMPARISON_OPERATORS[feature.operator] || feature.operator}${formatFeatureValue(feature.value)})`;
561
+ case 'boolean':
562
+ return `(${feature.name})`;
563
+ case 'interval':
564
+ return `(${formatFeatureValue(feature.start)}${COMPARISON_OPERATORS[feature.startOperator] || feature.startOperator}${feature.name}${COMPARISON_OPERATORS[feature.endOperator] || feature.endOperator}${formatFeatureValue(feature.end)})`;
565
+ default:
566
+ return '';
567
+ }
568
+ }
569
+ case 'operation':
570
+ return condition.conditions.map(formatCondition).filter(Boolean).join(` ${condition.operator} `);
571
+ case 'not':
572
+ return `not ${formatCondition(condition.value)}`;
573
+ default:
574
+ return '';
575
+ }
576
+ }
577
+ function formatMediaQuery(query) {
578
+ return query.mediaQueries.map((mediaQuery)=>{
579
+ const parts = [];
580
+ if (mediaQuery.qualifier) parts.push(mediaQuery.qualifier);
581
+ if (mediaQuery.mediaType && mediaQuery.mediaType !== 'all') parts.push(mediaQuery.mediaType);
582
+ const condition = formatCondition(mediaQuery.condition);
583
+ if (condition) {
584
+ if (parts.length) {
585
+ parts.push('and', condition);
586
+ } else {
587
+ parts.push(condition);
588
+ }
589
+ }
590
+ return parts.join(' ') || 'all';
591
+ }).join(', ');
592
+ }
593
+ function formatSupportsCondition(condition) {
594
+ switch(condition.type){
595
+ case 'declaration':
596
+ return `(${formatPropertyId(condition.propertyId)}:${formatFeatureValue(condition.value)})`;
597
+ case 'selector':
598
+ return `selector(${condition.value})`;
599
+ case 'not':
600
+ return `not ${formatSupportsCondition(condition.value)}`;
601
+ case 'and':
602
+ case 'or':
603
+ return condition.value.map(formatSupportsCondition).join(` ${condition.type} `);
604
+ default:
605
+ return '';
606
+ }
607
+ }
608
+ function formatNestedAtRule(rule) {
609
+ switch(rule.type){
610
+ case 'media':
611
+ return `@media ${formatMediaQuery(rule.value.query)}`;
612
+ case 'supports':
613
+ return `@supports ${formatSupportsCondition(rule.value.condition)}`;
614
+ case 'container':
615
+ {
616
+ const condition = formatCondition(rule.value.condition);
617
+ return `@container ${[
618
+ rule.value.name,
619
+ condition
620
+ ].filter(Boolean).join(' ')}`;
621
+ }
622
+ case 'starting-style':
623
+ return '@starting-style';
624
+ case 'layer-block':
625
+ return `@layer ${(rule.value.name || []).join('.')}`;
626
+ }
627
+ }
628
+ function getNestedAtRuleChildren(rule) {
629
+ if (rule.type === 'media' || rule.type === 'supports' || rule.type === 'container' || rule.type === 'starting-style' || rule.type === 'layer-block') {
630
+ return rule.value.rules;
631
+ }
632
+ }
633
+ function getParsedStyleDefinitions(parsed) {
634
+ parsed.styleDefinitions ??= [];
635
+ return parsed.styleDefinitions;
636
+ }
637
+ function nextStyleOrder(parsed) {
638
+ parsed.styleOrder = (parsed.styleOrder || 0) + 1;
639
+ return parsed.styleOrder;
640
+ }
641
+ function getDeclarationName(declaration) {
642
+ if (declaration.property === 'custom') return declaration.value.name;
643
+ if (declaration.property === 'unparsed') return formatPropertyId(declaration.value.propertyId);
644
+ return declaration.property;
645
+ }
646
+ function collectDeclarations(block) {
647
+ const declarations = {};
648
+ for (const declaration of block.declarations || []){
649
+ declarations[getDeclarationName(declaration)] = formatDeclarationValue(declaration);
650
+ }
651
+ for (const declaration of block.importantDeclarations || []){
652
+ declarations[getDeclarationName(declaration)] = `${formatDeclarationValue(declaration)} !important`;
653
+ }
654
+ return declarations;
655
+ }
656
+ const WEBKIT_PAIRED_DECLARATIONS = {
657
+ '-webkit-backdrop-filter': 'backdrop-filter',
658
+ '-webkit-box-decoration-break': 'box-decoration-break',
659
+ '-webkit-mask-image': 'mask-image',
660
+ '-webkit-text-decoration': 'text-decoration',
661
+ '-webkit-user-select': 'user-select'
662
+ };
663
+ const WEBKIT_ONLY_DECLARATIONS = {
664
+ '-webkit-box-orient': 'box-orient'
665
+ };
666
+ function escapeRegExp(value) {
667
+ return value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
668
+ }
669
+ function rawBlockContainsDeclaration(rawBlock, property) {
670
+ return new RegExp(`(?:^|[;{])\\s*${escapeRegExp(property)}\\s*:`).test(rawBlock);
671
+ }
672
+ function restoreRawWebkitPairedDeclarations(rule, parsed, declarations) {
673
+ const source = parsed.source;
674
+ const loc = rule.value?.loc;
675
+ const resolveLocation = parsed.sourceLocationResolver;
676
+ if (!source || !loc || !resolveLocation) return declarations;
677
+ const start = resolveLocation({
678
+ line: loc.line,
679
+ column: loc.column
680
+ });
681
+ if (start === -1) return declarations;
682
+ const statementEnd = findCSSStatementEnd(source, start);
683
+ if (statementEnd.reason !== 'block' || !statementEnd.delimiterRange) return declarations;
684
+ const blockEnd = findCSSBlockEnd(source, statementEnd.delimiterRange.start);
685
+ if (blockEnd === -1) return declarations;
686
+ const rawBlock = source.slice(statementEnd.delimiterRange.start + 1, blockEnd);
687
+ const restoredBefore = new Map();
688
+ const skippedProperties = new Set();
689
+ for(const prefixedProperty in WEBKIT_ONLY_DECLARATIONS){
690
+ if (declarations[prefixedProperty] !== undefined) continue;
691
+ const property = WEBKIT_ONLY_DECLARATIONS[prefixedProperty];
692
+ const value = declarations[property];
693
+ if (value === undefined) continue;
694
+ if (!rawBlockContainsDeclaration(rawBlock, prefixedProperty)) continue;
695
+ if (rawBlockContainsDeclaration(rawBlock, property)) continue;
696
+ restoredBefore.set(property, [
697
+ [
698
+ prefixedProperty,
699
+ value
700
+ ]
701
+ ]);
702
+ skippedProperties.add(property);
703
+ }
704
+ for(const prefixedProperty in WEBKIT_PAIRED_DECLARATIONS){
705
+ if (declarations[prefixedProperty] !== undefined) continue;
706
+ const property = WEBKIT_PAIRED_DECLARATIONS[prefixedProperty];
707
+ const value = declarations[property];
708
+ if (value === undefined) continue;
709
+ if (!rawBlockContainsDeclaration(rawBlock, prefixedProperty)) continue;
710
+ const restored = restoredBefore.get(property) || [];
711
+ restored.push([
712
+ prefixedProperty,
713
+ value
714
+ ]);
715
+ restoredBefore.set(property, restored);
716
+ }
717
+ if (!restoredBefore.size) return declarations;
718
+ const restoredDeclarations = {};
719
+ for(const property in declarations){
720
+ for (const [prefixedProperty, value] of restoredBefore.get(property) || []){
721
+ restoredDeclarations[prefixedProperty] = value;
722
+ }
723
+ if (skippedProperties.has(property)) continue;
724
+ restoredDeclarations[property] = declarations[property];
725
+ }
726
+ return restoredDeclarations;
727
+ }
728
+ function parseSettingsDeclarations(block, manifestInput) {
729
+ for (const declaration of block.declarations || []){
730
+ const property = getDeclarationName(declaration);
731
+ const value = formatDeclarationValue(declaration);
732
+ if (!parseMasterOption(manifestInput, property, value)) {
733
+ throw new Error(`Unsupported @settings option: ${property}`);
734
+ }
735
+ }
736
+ for (const declaration of block.importantDeclarations || []){
737
+ const property = getDeclarationName(declaration);
738
+ throw new Error(`@settings does not accept !important declarations: ${property}`);
739
+ }
740
+ }
741
+ function parseThemeDeclarations(block, manifestInput, mode, inline, isStatic) {
742
+ for (const declaration of block.declarations || []){
743
+ const property = getDeclarationName(declaration);
744
+ const value = formatDeclarationValue(declaration);
745
+ defineThemeVariable(manifestInput, property, value, mode, inline, isStatic);
746
+ }
747
+ for (const declaration of block.importantDeclarations || []){
748
+ const property = normalizeThemeTokenName(getDeclarationName(declaration));
749
+ throw new Error(`@theme token declarations cannot be !important: ${property}`);
750
+ }
751
+ }
752
+ function parseCustomVariantPrelude(prelude) {
753
+ const trimmed = prelude.trim();
754
+ const tokenMatch = /^(:{1,2}[-_a-zA-Z][-_a-zA-Z0-9]*|@[-_a-zA-Z][-_a-zA-Z0-9]*)$/.exec(trimmed);
755
+ if (!tokenMatch) return;
756
+ return {
757
+ token: tokenMatch[1]
758
+ };
759
+ }
760
+ function defineVariant(manifestInput, variant) {
761
+ manifestInput.variants ??= [];
762
+ const foundIndex = manifestInput.variants.findIndex((existing)=>existing.token === variant.token);
763
+ if (foundIndex !== -1) manifestInput.variants.splice(foundIndex, 1);
764
+ manifestInput.variants.push(variant);
765
+ }
766
+ function isSlotRule(rule) {
767
+ return (rule.type === 'unknown' || rule.type === 'custom') && rule.value?.name === 'slot';
768
+ }
769
+ function assertNotSlotRule(rule) {
770
+ if (isSlotRule(rule)) {
771
+ throw new Error('@slot can only be used inside @custom-variant');
772
+ }
773
+ }
774
+ function assertNoVariantTemplateDeclarations(rule, token) {
775
+ const declarations = collectDeclarations(rule.value.declarations);
776
+ if (Object.keys(declarations).length) {
777
+ throw new Error(`@custom-variant ${token} does not accept declarations`);
778
+ }
779
+ }
780
+ function createVariantTemplateBranch(path) {
781
+ const selector = path.selectors.reduce((current, selectorTemplate)=>selectorTemplate.replace(/&/g, current), '&');
782
+ return {
783
+ ...selector !== '&' ? {
784
+ selector
785
+ } : {},
786
+ ...path.atRules.length ? {
787
+ atRules: [
788
+ ...path.atRules
789
+ ]
790
+ } : {},
791
+ ...path.layer ? {
792
+ layer: path.layer
793
+ } : {}
794
+ };
795
+ }
796
+ function collectVariantTemplateBranches(rules, token, path = {
797
+ selectors: [],
798
+ atRules: []
799
+ }) {
800
+ const branches = [];
801
+ for (const child of rules){
802
+ if (isSlotRule(child)) {
803
+ branches.push(createVariantTemplateBranch(path));
804
+ continue;
805
+ }
806
+ if (isCustomVariantDefinition(child)) {
807
+ throw new Error('@custom-variant cannot be nested inside @custom-variant');
808
+ }
809
+ if (parseMasterVariantBlock(child)) {
810
+ throw new Error('@variant cannot be used inside @custom-variant');
811
+ }
812
+ if (child.type === 'keyframes') {
813
+ throw new Error('@keyframes cannot be used inside @custom-variant');
814
+ }
815
+ if (child.type === 'style') {
816
+ const selectors = child.value.selectors.map((selector)=>formatSelectors([
817
+ selector
818
+ ]));
819
+ for (const selector of selectors){
820
+ if (!selector.includes('&')) {
821
+ throw new Error(`@custom-variant ${token} selector value must include "&"`);
822
+ }
823
+ }
824
+ assertNoVariantTemplateDeclarations(child, token);
825
+ for (const selector of selectors){
826
+ branches.push(...collectVariantTemplateBranches(child.value.rules, token, {
827
+ ...path,
828
+ selectors: [
829
+ ...path.selectors,
830
+ selector
831
+ ]
832
+ }));
833
+ }
834
+ continue;
835
+ }
836
+ if (child.type === 'layer-block') {
837
+ const layer = formatNestedAtRule(child)?.replace(/^@layer\s+/, '').trim();
838
+ if (layer !== 'base' && layer !== 'defaults' && layer !== 'components' && layer !== 'utilities') {
839
+ throw new Error(`@custom-variant ${token} only accepts Master CSS layers`);
840
+ }
841
+ if (path.layer && path.layer !== layer) {
842
+ throw new Error(`@custom-variant ${token} cannot assign multiple layers`);
843
+ }
844
+ branches.push(...collectVariantTemplateBranches(child.value.rules, token, {
845
+ ...path,
846
+ layer
847
+ }));
848
+ continue;
849
+ }
850
+ const nestedAtRuleChildren = getNestedAtRuleChildren(child);
851
+ if (nestedAtRuleChildren) {
852
+ const atRule = formatNestedAtRule(child);
853
+ if (!atRule) {
854
+ throw new Error(`Unsupported nested at-rule in @custom-variant ${token}`);
855
+ }
856
+ branches.push(...collectVariantTemplateBranches(nestedAtRuleChildren, token, {
857
+ ...path,
858
+ atRules: [
859
+ ...path.atRules,
860
+ atRule
861
+ ]
862
+ }));
863
+ continue;
864
+ }
865
+ if (child.type === 'nested-declarations') {
866
+ const declarations = collectDeclarations(child.value.declarations);
867
+ if (Object.keys(declarations).length) {
868
+ throw new Error(`@custom-variant ${token} does not accept declarations`);
869
+ }
870
+ continue;
871
+ }
872
+ throw new Error(`Unsupported rule inside @custom-variant ${token}`);
873
+ }
874
+ return branches;
875
+ }
876
+ function parseVariantDefinition(rule, parsed) {
877
+ const prelude = parseCustomVariantPrelude(formatPrelude(rule.value.prelude));
878
+ if (!prelude) {
879
+ throw new Error('@custom-variant requires a full variant token');
880
+ }
881
+ const { token } = prelude;
882
+ const bodyRules = rule.value.body?.value;
883
+ if (bodyRules?.length) {
884
+ const branches = collectVariantTemplateBranches(bodyRules, token);
885
+ if (!branches.length) {
886
+ throw new Error(`@custom-variant ${token} requires @slot`);
887
+ }
888
+ defineVariant(parsed.manifestInput, {
889
+ token,
890
+ branches
891
+ });
892
+ return;
893
+ }
894
+ throw new Error(`@custom-variant ${token} requires a block body`);
895
+ }
896
+ function isCustomVariantDefinition(rule) {
897
+ return (rule.type === 'unknown' || rule.type === 'custom') && rule.value?.name === 'custom-variant';
898
+ }
899
+ function getManagedDefinitionDirectiveLayer(rule) {
900
+ if (rule.type !== 'custom' || !rule.value) return;
901
+ return MANAGED_DEFINITION_DIRECTIVE_LAYERS[rule.value.name];
902
+ }
903
+ function parseManagedStyleDefinitionSelector(selectors) {
904
+ const names = selectors.map((selector)=>selector[0]?.type === 'class' ? selector[0].name : undefined);
905
+ const name = names[0];
906
+ if (!name || names.some((eachName)=>eachName !== name)) return;
907
+ const selectorTexts = selectors.map((selector)=>{
908
+ const selectorText = formatSelectors([
909
+ selector
910
+ ]);
911
+ const classPattern = new RegExp(`^\\.${name.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}(?=$|[^a-zA-Z0-9_-])`);
912
+ return selectorText.replace(classPattern, '&');
913
+ });
914
+ return {
915
+ name,
916
+ selectors: selectorTexts,
917
+ selector: selectorTexts.join(',')
918
+ };
919
+ }
920
+ function parseManagedDefinitionNameSelector(selectors) {
921
+ if (selectors.length !== 1) return;
922
+ const selector = selectors[0];
923
+ if (selector.length !== 1) return;
924
+ const node = selector[0];
925
+ if (node?.type !== 'type' || node.namespace) return;
926
+ return {
927
+ name: node.name,
928
+ selectors: [
929
+ '&'
930
+ ],
931
+ selector: '&'
932
+ };
933
+ }
934
+ function takeComposeRange(parsed) {
935
+ const ranges = parsed.composeRanges || [];
936
+ const index = parsed.composeRangeIndex || 0;
937
+ parsed.composeRangeIndex = index + 1;
938
+ return ranges[index];
939
+ }
940
+ function trimSourceRange(source, range) {
941
+ let start = range.start;
942
+ let end = range.end;
943
+ while(start < end && /\s/.test(source[start] || ''))start++;
944
+ while(end > start && /\s/.test(source[end - 1] || ''))end--;
945
+ return {
946
+ start,
947
+ end
948
+ };
949
+ }
950
+ function createComposeQuotedSyntaxError(parsed, range) {
951
+ return new CSSDirectiveError('compose-quoted-syntax', '@compose only accepts unquoted class lists', createSourceReference(parsed, range));
952
+ }
953
+ function createComposeGroupSyntaxError(parsed, range) {
954
+ return new CSSDirectiveError('compose-group-syntax', '@compose does not accept group syntax', createSourceReference(parsed, range));
955
+ }
956
+ function validateComposeRange(parsed, range) {
957
+ const source = parsed.source || '';
958
+ if (range.blockRange) {
959
+ throw createComposeGroupSyntaxError(parsed, range.blockRange);
960
+ }
961
+ if (range.quotedStringRanges.length) {
962
+ throw createComposeQuotedSyntaxError(parsed, range.quotedStringRanges[0]);
963
+ }
964
+ const contentRange = trimSourceRange(source, range.preludeRange);
965
+ const classList = source.slice(contentRange.start, contentRange.end);
966
+ for (const token of collectMasterCSSClassListTokenRanges(classList)){
967
+ if (token.token.startsWith('{')) {
968
+ throw createComposeGroupSyntaxError(parsed, {
969
+ start: contentRange.start + token.start,
970
+ end: contentRange.start + token.end
971
+ });
972
+ }
973
+ }
974
+ }
975
+ function validateComposeRanges(parsed) {
976
+ for (const range of parsed.composeRanges || []){
977
+ validateComposeRange(parsed, range);
978
+ }
979
+ }
980
+ function parseComposeRule(rule, parsed) {
981
+ if (rule.type === 'custom' && rule.value.name === 'compose') {
982
+ const range = takeComposeRange(parsed);
983
+ const contentRange = range && parsed.source ? trimSourceRange(parsed.source, range.preludeRange) : undefined;
984
+ const classList = contentRange && parsed.source ? parsed.source.slice(contentRange.start, contentRange.end) : formatPrelude(rule.value.prelude);
985
+ const classTokens = collectMasterCSSClassListTokenRanges(classList);
986
+ return {
987
+ classNames: classTokens.map((token)=>({
988
+ className: token.token,
989
+ ...contentRange ? {
990
+ source: createSourceReference(parsed, {
991
+ start: contentRange.start + token.start,
992
+ end: contentRange.start + token.end
993
+ })
994
+ } : {}
995
+ })),
996
+ ...range ? {
997
+ directiveSource: createSourceReference(parsed, range)
998
+ } : {}
999
+ };
1000
+ }
1001
+ }
1002
+ function createComposePlacementError(parsed) {
1003
+ const range = takeComposeRange(parsed);
1004
+ return new CSSDirectiveError('compose-placement', '@compose requires a style rule', range ? createSourceReference(parsed, range) : undefined);
1005
+ }
1006
+ function getMasterVariantShorthandToken(name) {
1007
+ return name && MASTER_VARIANT_SHORTHAND_TOKENS[name];
1008
+ }
1009
+ function parseMasterVariantBlock(rule) {
1010
+ if (rule.type !== 'custom' && rule.type !== 'unknown') return;
1011
+ const shorthandToken = getMasterVariantShorthandToken(rule.value?.name);
1012
+ if (!shorthandToken && rule.value?.name !== 'variant') return;
1013
+ const prelude = formatPrelude(rule.value.prelude);
1014
+ if (shorthandToken && prelude) {
1015
+ throw new Error(`@${rule.value.name} does not accept a prelude`);
1016
+ }
1017
+ const token = shorthandToken || prelude;
1018
+ if (!token) {
1019
+ throw new Error('@variant requires a Master CSS variant');
1020
+ }
1021
+ if (!/^(?::{1,2}[^\s:]\S*|@\S+)$/.test(token)) {
1022
+ throw new Error('@variant requires a full variant token');
1023
+ }
1024
+ const rules = rule.value.body?.value;
1025
+ if (!Array.isArray(rules)) {
1026
+ throw new Error('@variant requires a style block');
1027
+ }
1028
+ return {
1029
+ token,
1030
+ rules: rules
1031
+ };
1032
+ }
1033
+ function isNestedStyleRule(rule) {
1034
+ return rule.type === 'style' || rule.type === 'media' || rule.type === 'supports' || rule.type === 'container' || rule.type === 'starting-style' || rule.type === 'layer-block' || Boolean(parseMasterVariantBlock(rule));
1035
+ }
1036
+ function collectDirectiveStyleRule(rule, parsed) {
1037
+ return collectDirectiveStyleRuleBody(rule.value.declarations, rule.value.rules, parsed, (declarations)=>restoreRawWebkitPairedDeclarations(rule, parsed, declarations));
1038
+ }
1039
+ function collectDirectiveStyleRuleBody(block, rules, parsed, transformDeclarations = (declarations)=>declarations) {
1040
+ const items = [];
1041
+ const declarations = transformDeclarations(collectDeclarations(block));
1042
+ if (Object.keys(declarations).length) {
1043
+ items.push({
1044
+ type: 'declarations',
1045
+ declarations
1046
+ });
1047
+ }
1048
+ for (const child of rules){
1049
+ assertNotSlotRule(child);
1050
+ if (child.type === 'nested-declarations') {
1051
+ const nestedDeclarations = collectDeclarations(child.value.declarations);
1052
+ if (Object.keys(nestedDeclarations).length) {
1053
+ items.push({
1054
+ type: 'declarations',
1055
+ declarations: nestedDeclarations
1056
+ });
1057
+ }
1058
+ continue;
1059
+ }
1060
+ if (isNestedStyleRule(child)) {
1061
+ items.push({
1062
+ type: 'nested',
1063
+ rule: child
1064
+ });
1065
+ continue;
1066
+ }
1067
+ const compose = parseComposeRule(child, parsed);
1068
+ if (compose) {
1069
+ items.push({
1070
+ type: 'compose',
1071
+ classNames: compose.classNames,
1072
+ ...compose.directiveSource ? {
1073
+ directiveSource: compose.directiveSource
1074
+ } : {}
1075
+ });
1076
+ continue;
1077
+ }
1078
+ throw new Error('Style definitions only accept declarations, @compose, nested selectors, and nested at-rules');
1079
+ }
1080
+ return items;
1081
+ }
1082
+ function combineStyleSelectorLists(parentSelectors, childSelectorAST) {
1083
+ const childSelectors = childSelectorAST.map((selector)=>formatSelectors([
1084
+ selector
1085
+ ]));
1086
+ return combineSelectorLists(parentSelectors, childSelectors);
1087
+ }
1088
+ const EMPTY_DECLARATION_BLOCK = {
1089
+ declarations: [],
1090
+ importantDeclarations: []
1091
+ };
1092
+ function parseStyleDefinitionBody(parsed, selectorDefinition, items, atRules = [], layer, name = selectorDefinition.name) {
1093
+ const definitions = getParsedStyleDefinitions(parsed);
1094
+ for (const item of items){
1095
+ if (item.type === 'compose') {
1096
+ definitions.push(...item.classNames.map(({ className, source })=>({
1097
+ type: 'compose',
1098
+ order: nextStyleOrder(parsed),
1099
+ className,
1100
+ selector: selectorDefinition.selector,
1101
+ ...source ? {
1102
+ source
1103
+ } : {},
1104
+ ...item.directiveSource ? {
1105
+ directiveSource: item.directiveSource
1106
+ } : {},
1107
+ ...selectorDefinition.source ? {
1108
+ selectorSource: selectorDefinition.source
1109
+ } : {},
1110
+ ...name ? {
1111
+ name
1112
+ } : {},
1113
+ ...atRules.length ? {
1114
+ atRules: [
1115
+ ...atRules
1116
+ ]
1117
+ } : {},
1118
+ ...layer ? {
1119
+ layer
1120
+ } : {}
1121
+ })));
1122
+ continue;
1123
+ }
1124
+ if (item.type === 'declarations') {
1125
+ if (!Object.keys(item.declarations).length) continue;
1126
+ definitions.push({
1127
+ type: 'native',
1128
+ order: nextStyleOrder(parsed),
1129
+ selector: selectorDefinition.selector,
1130
+ ...selectorDefinition.source ? {
1131
+ selectorSource: selectorDefinition.source
1132
+ } : {},
1133
+ ...name ? {
1134
+ name
1135
+ } : {},
1136
+ declarations: item.declarations,
1137
+ ...atRules.length ? {
1138
+ atRules: [
1139
+ ...atRules
1140
+ ]
1141
+ } : {},
1142
+ ...layer ? {
1143
+ layer
1144
+ } : {}
1145
+ });
1146
+ continue;
1147
+ }
1148
+ if (name) {
1149
+ parseNestedManagedStyleChildRule(item.rule, parsed, selectorDefinition, atRules, layer);
1150
+ } else {
1151
+ parseNestedNativeStyleChildRule(item.rule, parsed, selectorDefinition, atRules);
1152
+ }
1153
+ }
1154
+ if (name && !parsed.classNames.includes(name)) {
1155
+ parsed.classNames.push(name);
1156
+ }
1157
+ }
1158
+ function parseStyleRuleBody(rules, parsed, selectorDefinition, atRules = [], layer, name = selectorDefinition.name) {
1159
+ parseStyleDefinitionBody(parsed, selectorDefinition, collectDirectiveStyleRuleBody(EMPTY_DECLARATION_BLOCK, rules, parsed), atRules, layer, name);
1160
+ }
1161
+ function parseNestedManagedStyleChildRule(child, parsed, parentSelectorDefinition, atRules, layer) {
1162
+ assertNotSlotRule(child);
1163
+ if (child.type === 'layer-block') {
1164
+ throw new Error('Nested @layer blocks are not allowed inside managed style definitions');
1165
+ }
1166
+ const masterVariantBlock = parseMasterVariantBlock(child);
1167
+ if (masterVariantBlock) {
1168
+ parseStyleRuleBody(masterVariantBlock.rules, parsed, parentSelectorDefinition, [
1169
+ ...atRules,
1170
+ createCSSDirectiveVariantReference(masterVariantBlock.token)
1171
+ ], layer);
1172
+ return;
1173
+ }
1174
+ const nestedAtRuleChildren = getNestedAtRuleChildren(child);
1175
+ if (nestedAtRuleChildren) {
1176
+ const atRule = formatNestedAtRule(child);
1177
+ if (!atRule) {
1178
+ throw new Error('Unsupported nested at-rule in @master');
1179
+ }
1180
+ parseStyleRuleBody(nestedAtRuleChildren, parsed, parentSelectorDefinition, [
1181
+ ...atRules,
1182
+ atRule
1183
+ ], layer);
1184
+ return;
1185
+ }
1186
+ if (child.type === 'style') {
1187
+ parseManagedStyleRule(child, parsed, atRules, layer, parentSelectorDefinition);
1188
+ return;
1189
+ }
1190
+ throw new Error('Style definitions only accept declarations, @compose, nested selectors, and nested at-rules');
1191
+ }
1192
+ function parseManagedStyleRule(rule, parsed, atRules = [], layer, parentSelectorDefinition) {
1193
+ const selectorDefinition = parentSelectorDefinition ? (()=>{
1194
+ const selectors = combineStyleSelectorLists(parentSelectorDefinition.selectors, rule.value.selectors);
1195
+ return {
1196
+ name: parentSelectorDefinition.name,
1197
+ selectors,
1198
+ selector: selectors.join(','),
1199
+ source: createSelectorSourceReference(parsed, rule) || parentSelectorDefinition.source
1200
+ };
1201
+ })() : parseManagedStyleDefinitionSelector(rule.value.selectors);
1202
+ if (!selectorDefinition) {
1203
+ throw new Error('Managed style definition selector must start with a single class selector');
1204
+ }
1205
+ selectorDefinition.source ||= createSelectorSourceReference(parsed, rule);
1206
+ parseStyleDefinitionBody(parsed, selectorDefinition, collectDirectiveStyleRule(rule, parsed), atRules, layer);
1207
+ }
1208
+ function parseNativeSelectorDefinition(selectors, parentSelectorDefinition) {
1209
+ const selectorTexts = parentSelectorDefinition ? combineStyleSelectorLists(parentSelectorDefinition.selectors, selectors) : selectors.map((selector)=>formatSelectors([
1210
+ selector
1211
+ ]));
1212
+ return {
1213
+ selectors: selectorTexts,
1214
+ selector: selectorTexts.join(',')
1215
+ };
1216
+ }
1217
+ function parseNativeRuleBody(rules, parsed, atRules = [], parentSelectorDefinition) {
1218
+ for (const child of rules){
1219
+ assertNotSlotRule(child);
1220
+ const compose = parseComposeRule(child, parsed);
1221
+ if (compose && parentSelectorDefinition) {
1222
+ parseStyleDefinitionBody(parsed, parentSelectorDefinition, [
1223
+ {
1224
+ type: 'compose',
1225
+ classNames: compose.classNames,
1226
+ ...compose.directiveSource ? {
1227
+ directiveSource: compose.directiveSource
1228
+ } : {}
1229
+ }
1230
+ ], atRules, undefined, undefined);
1231
+ continue;
1232
+ }
1233
+ if (child.type === 'nested-declarations' && parentSelectorDefinition) {
1234
+ const declarations = collectDeclarations(child.value.declarations);
1235
+ if (Object.keys(declarations).length) {
1236
+ parseStyleDefinitionBody(parsed, parentSelectorDefinition, [
1237
+ {
1238
+ type: 'declarations',
1239
+ declarations
1240
+ }
1241
+ ], atRules, undefined, undefined);
1242
+ }
1243
+ continue;
1244
+ }
1245
+ const masterVariantBlock = parseMasterVariantBlock(child);
1246
+ if (masterVariantBlock) {
1247
+ parseNativeRuleBody(masterVariantBlock.rules, parsed, [
1248
+ ...atRules,
1249
+ createCSSDirectiveVariantReference(masterVariantBlock.token)
1250
+ ], parentSelectorDefinition);
1251
+ continue;
1252
+ }
1253
+ const nestedAtRuleChildren = getNestedAtRuleChildren(child);
1254
+ if (nestedAtRuleChildren) {
1255
+ const atRule = formatNestedAtRule(child);
1256
+ if (!atRule) {
1257
+ throw new Error('Unsupported nested at-rule in native CSS');
1258
+ }
1259
+ parseNativeRuleBody(nestedAtRuleChildren, parsed, [
1260
+ ...atRules,
1261
+ atRule
1262
+ ], parentSelectorDefinition);
1263
+ continue;
1264
+ }
1265
+ if (child.type === 'style') {
1266
+ parseNativeStyleRule(child, parsed, atRules, parentSelectorDefinition);
1267
+ continue;
1268
+ }
1269
+ if (child.type === 'keyframes') {
1270
+ throw new Error('@keyframes is not allowed inside @variant. Move managed animation definitions to top-level @theme.');
1271
+ }
1272
+ if (compose) {
1273
+ throw new CSSDirectiveError('compose-placement', '@compose requires a style rule', compose.directiveSource);
1274
+ }
1275
+ if (child.type === 'nested-declarations') {
1276
+ throw new Error('Native @variant blocks only accept style rules, declarations, @compose, and nested at-rules');
1277
+ }
1278
+ }
1279
+ }
1280
+ function parseNestedNativeStyleChildRule(child, parsed, parentSelectorDefinition, atRules) {
1281
+ assertNotSlotRule(child);
1282
+ const masterVariantBlock = parseMasterVariantBlock(child);
1283
+ if (masterVariantBlock) {
1284
+ parseNativeRuleBody(masterVariantBlock.rules, parsed, [
1285
+ ...atRules,
1286
+ createCSSDirectiveVariantReference(masterVariantBlock.token)
1287
+ ], parentSelectorDefinition);
1288
+ return;
1289
+ }
1290
+ const nestedAtRuleChildren = getNestedAtRuleChildren(child);
1291
+ if (nestedAtRuleChildren) {
1292
+ const atRule = formatNestedAtRule(child);
1293
+ if (!atRule) {
1294
+ throw new Error('Unsupported nested at-rule in native CSS');
1295
+ }
1296
+ parseNativeRuleBody(nestedAtRuleChildren, parsed, [
1297
+ ...atRules,
1298
+ atRule
1299
+ ], parentSelectorDefinition);
1300
+ return;
1301
+ }
1302
+ if (child.type === 'style') {
1303
+ parseNativeStyleRule(child, parsed, atRules, parentSelectorDefinition);
1304
+ return;
1305
+ }
1306
+ throw new Error('Native CSS rules only accept declarations, @compose, nested selectors, and nested at-rules');
1307
+ }
1308
+ function parseNativeStyleRule(rule, parsed, atRules = [], parentSelectorDefinition) {
1309
+ const selectorDefinition = parseNativeSelectorDefinition(rule.value.selectors, parentSelectorDefinition);
1310
+ selectorDefinition.source = createSelectorSourceReference(parsed, rule) || parentSelectorDefinition?.source;
1311
+ parseStyleDefinitionBody(parsed, selectorDefinition, collectDirectiveStyleRule(rule, parsed), atRules, undefined, undefined);
1312
+ }
1313
+ function formatKeyframeSelector(selector) {
1314
+ switch(selector.type){
1315
+ case 'from':
1316
+ case 'to':
1317
+ return selector.type;
1318
+ case 'percentage':
1319
+ return `${selector.value * 100}%`;
1320
+ case 'timeline-range-percentage':
1321
+ return `${selector.value.name} ${selector.value.percentage * 100}%`;
1322
+ }
1323
+ }
1324
+ function parseKeyframes(rule, manifestInput, isStatic) {
1325
+ const name = rule.value.name.value;
1326
+ if (!name) {
1327
+ throw new Error('@keyframes requires a name');
1328
+ }
1329
+ const keyframes = {};
1330
+ for (const keyframe of rule.value.keyframes){
1331
+ const declarations = collectDeclarations(keyframe.declarations);
1332
+ for (const selector of keyframe.selectors.map(formatKeyframeSelector)){
1333
+ keyframes[selector] = declarations;
1334
+ }
1335
+ }
1336
+ manifestInput.animations ??= {};
1337
+ manifestInput.animations[name] = keyframes;
1338
+ if (isStatic) {
1339
+ manifestInput.animationOptions ??= {};
1340
+ manifestInput.animationOptions[name] = {
1341
+ static: true
1342
+ };
1343
+ }
1344
+ }
1345
+ function getCustomRulePrelude(rule) {
1346
+ return rule.prelude ?? rule.value?.prelude;
1347
+ }
1348
+ function getCustomRuleBody(rule) {
1349
+ return rule.body ?? rule.value?.body;
1350
+ }
1351
+ function getSettingsSection(rule) {
1352
+ const prelude = formatPrelude(getCustomRulePrelude(rule));
1353
+ if (!prelude) return 'root';
1354
+ throw new Error(`Unsupported @settings section: ${prelude}`);
1355
+ }
1356
+ function getThemePrelude(rule) {
1357
+ const prelude = formatPrelude(getCustomRulePrelude(rule));
1358
+ if (!prelude) return {};
1359
+ const parts = prelude.split(/\s+/).filter(Boolean);
1360
+ let mode;
1361
+ let inline = false;
1362
+ let isStatic = false;
1363
+ for (const part of parts){
1364
+ if (part === 'inline' || part === 'static') {
1365
+ if (part === 'inline') {
1366
+ if (inline) throw new Error('@theme inline modifier cannot be repeated');
1367
+ inline = true;
1368
+ } else {
1369
+ if (isStatic) throw new Error('@theme static modifier cannot be repeated');
1370
+ isStatic = true;
1371
+ }
1372
+ continue;
1373
+ }
1374
+ if (mode) {
1375
+ throw new Error('@theme mode must be a single token');
1376
+ }
1377
+ mode = part;
1378
+ }
1379
+ if (inline && isStatic) {
1380
+ throw new Error('@theme inline and static cannot be combined');
1381
+ }
1382
+ if (inline && mode) {
1383
+ throw new Error('@theme inline cannot be mode-specific');
1384
+ }
1385
+ return {
1386
+ ...mode ? {
1387
+ mode
1388
+ } : {},
1389
+ ...inline ? {
1390
+ inline: true
1391
+ } : {},
1392
+ ...isStatic ? {
1393
+ static: true
1394
+ } : {}
1395
+ };
1396
+ }
1397
+ function parseSettingsStyleRule(rule) {
1398
+ if (parseManagedStyleDefinitionSelector(rule.value.selectors)) {
1399
+ throw new Error('@settings does not accept class definitions');
1400
+ }
1401
+ throw new Error(`Unsupported @settings selector: ${formatSelectors(rule.value.selectors)}`);
1402
+ }
1403
+ function parseSettingsChildRule(child, parsed, section) {
1404
+ if (child.type === 'layer-block') {
1405
+ throw new Error('@settings does not accept @layer');
1406
+ }
1407
+ const masterVariantBlock = parseMasterVariantBlock(child);
1408
+ if (masterVariantBlock) {
1409
+ throw new Error('@settings does not accept @variant');
1410
+ }
1411
+ const nestedAtRuleChildren = getNestedAtRuleChildren(child);
1412
+ if (nestedAtRuleChildren) {
1413
+ throw new Error('@settings does not accept nested at-rules');
1414
+ }
1415
+ if (child.type === 'nested-declarations') {
1416
+ parseSettingsDeclarations(child.value.declarations, parsed.manifestInput);
1417
+ return;
1418
+ }
1419
+ if (child.type === 'keyframes') {
1420
+ throw new Error('@settings does not accept @keyframes. Move managed animation definitions to top-level @theme.');
1421
+ }
1422
+ if (child.type === 'style') {
1423
+ parseSettingsStyleRule(child);
1424
+ return;
1425
+ }
1426
+ throw new Error(`Unsupported rule in @settings${section === 'root' ? '' : ' ' + section}`);
1427
+ }
1428
+ function parseSettingsRule(rule, parsed) {
1429
+ const section = getSettingsSection(rule);
1430
+ const body = getCustomRuleBody(rule);
1431
+ if (!Array.isArray(body?.value)) {
1432
+ throw new Error('@settings requires a style block');
1433
+ }
1434
+ for (const child of body.value){
1435
+ parseSettingsChildRule(child, parsed, section);
1436
+ }
1437
+ }
1438
+ function parseThemeRule(rule, parsed) {
1439
+ const { mode, inline, static: isStatic } = getThemePrelude(rule);
1440
+ const body = getCustomRuleBody(rule);
1441
+ if (!Array.isArray(body?.value)) {
1442
+ throw new Error('@theme requires a style block');
1443
+ }
1444
+ if (mode) addThemeMode(parsed.manifestInput, mode);
1445
+ for (const child of body.value){
1446
+ if (child.type === 'nested-declarations') {
1447
+ parseThemeDeclarations(child.value.declarations, parsed.manifestInput, mode, inline, isStatic);
1448
+ continue;
1449
+ }
1450
+ if (child.type === 'keyframes') {
1451
+ if (mode || inline) {
1452
+ throw new Error('@theme keyframes cannot be mode-specific or inline');
1453
+ }
1454
+ parseKeyframes(child, parsed.manifestInput, isStatic);
1455
+ continue;
1456
+ }
1457
+ throw new Error('@theme only accepts theme token declarations and @keyframes definitions');
1458
+ }
1459
+ }
1460
+ const MANAGED_DYNAMIC_SOURCE_KINDS = new Set([
1461
+ 'number',
1462
+ 'color',
1463
+ 'image'
1464
+ ]);
1465
+ const MANAGED_DYNAMIC_RAW_ANY_SOURCE = '*';
1466
+ function parseManagedPatternSegments(pattern) {
1467
+ const segments = [
1468
+ ...pattern.matchAll(/<([^<>]*)>/g)
1469
+ ];
1470
+ if (segments.length !== 1) {
1471
+ throw new Error('Managed pattern must contain exactly one <...> segment');
1472
+ }
1473
+ const [segment] = segments;
1474
+ const segmentStart = segment.index;
1475
+ const segmentEnd = segmentStart + segment[0].length;
1476
+ if (pattern.slice(0, segmentStart).includes('<') || pattern.slice(segmentEnd).includes('>')) {
1477
+ throw new Error('Managed pattern must contain exactly one <...> segment');
1478
+ }
1479
+ return {
1480
+ segment,
1481
+ segmentStart,
1482
+ segmentEnd,
1483
+ prefix: pattern.slice(0, segmentStart),
1484
+ suffix: pattern.slice(segmentEnd),
1485
+ rawValues: segment[1].trim()
1486
+ };
1487
+ }
1488
+ function parseManagedEnumPatternName(source) {
1489
+ const pattern = source.trim();
1490
+ if (!pattern) {
1491
+ throw new Error('Managed enum pattern requires a name');
1492
+ }
1493
+ const { prefix, suffix, rawValues } = parseManagedPatternSegments(pattern);
1494
+ if (!prefix || suffix) {
1495
+ throw new Error('Managed enum pattern must use a prefix before <...> and no suffix');
1496
+ }
1497
+ if (!rawValues) {
1498
+ throw new Error('Managed enum pattern cannot be empty');
1499
+ }
1500
+ if (rawValues.includes(',')) {
1501
+ throw new Error('Managed enum pattern values must use "|" separators like text-<left|right>');
1502
+ }
1503
+ const values = rawValues.split('|').map((value)=>value.trim());
1504
+ if (values.length < 2 || values.some((value)=>!value)) {
1505
+ throw new Error('Managed enum pattern requires at least two values separated by "|"');
1506
+ }
1507
+ for (const value of values){
1508
+ if (!/^-?[_a-zA-Z0-9][-_a-zA-Z0-9]*$/.test(value)) {
1509
+ throw new Error(`Invalid managed enum value: ${value}`);
1510
+ }
1511
+ }
1512
+ return {
1513
+ kind: 'pattern',
1514
+ name: `${prefix}<${values.join('|')}>`,
1515
+ pattern: {
1516
+ prefix,
1517
+ values
1518
+ }
1519
+ };
1520
+ }
1521
+ function parseManagedDynamicPatternName(source) {
1522
+ const pattern = source.trim();
1523
+ if (!pattern) {
1524
+ throw new Error('Managed dynamic utility requires a name');
1525
+ }
1526
+ const { prefix, suffix, rawValues } = parseManagedPatternSegments(pattern);
1527
+ if (!prefix.endsWith(':') || prefix === ':' || suffix) {
1528
+ throw new Error('Managed dynamic utilities must use key:<...> syntax');
1529
+ }
1530
+ const key = prefix.slice(0, -1);
1531
+ if (!/^-?[_a-zA-Z][-_a-zA-Z0-9]*$/.test(key)) {
1532
+ throw new Error(`Invalid managed dynamic utility key: ${key}`);
1533
+ }
1534
+ if (!rawValues) {
1535
+ throw new Error('Managed dynamic utility source list cannot be empty');
1536
+ }
1537
+ if (rawValues.includes(',')) {
1538
+ throw new Error('Managed dynamic utility source lists must use "|" separators like font:<~font-size|number>');
1539
+ }
1540
+ const values = rawValues.split('|').map((value)=>value.trim());
1541
+ if (values.some((value)=>!value)) {
1542
+ throw new Error('Managed dynamic utility source list cannot contain empty entries');
1543
+ }
1544
+ const variableAliasRefs = [];
1545
+ const canonicalValues = [];
1546
+ const literalValues = [];
1547
+ let kind;
1548
+ let arbitrary = false;
1549
+ const addCanonicalValue = (value, unique = false)=>{
1550
+ if (!unique || !canonicalValues.includes(value)) canonicalValues.push(value);
1551
+ };
1552
+ const addVariableAliasRef = (value)=>{
1553
+ if (!variableAliasRefs.includes(value)) variableAliasRefs.push(value);
1554
+ addCanonicalValue(value, true);
1555
+ };
1556
+ for (const value of values){
1557
+ if (value[0] === '~' || value[0] === '=') {
1558
+ const namespace = value.slice(1);
1559
+ if (!/^[_a-zA-Z][-_a-zA-Z0-9]*$/.test(namespace)) {
1560
+ throw new Error(`Invalid managed dynamic utility namespace: ${value}`);
1561
+ }
1562
+ addVariableAliasRef(value);
1563
+ continue;
1564
+ }
1565
+ if (MANAGED_DYNAMIC_SOURCE_KINDS.has(value)) {
1566
+ if (kind && kind !== value) {
1567
+ throw new Error('Managed dynamic utilities only support one raw value kind per entry');
1568
+ }
1569
+ kind = value;
1570
+ if (kind === 'color') addVariableAliasRef('~color');
1571
+ addCanonicalValue(value);
1572
+ continue;
1573
+ }
1574
+ if (value === MANAGED_DYNAMIC_RAW_ANY_SOURCE) {
1575
+ arbitrary = true;
1576
+ addCanonicalValue(value);
1577
+ continue;
1578
+ }
1579
+ if (/^-?[_a-zA-Z0-9][-_a-zA-Z0-9]*$/.test(value)) {
1580
+ if (!literalValues.includes(value)) literalValues.push(value);
1581
+ addCanonicalValue(value);
1582
+ continue;
1583
+ }
1584
+ throw new Error(`Unsupported managed dynamic utility source: ${value}`);
1585
+ }
1586
+ if (arbitrary && literalValues.length) {
1587
+ throw new Error('Managed dynamic utility wildcard cannot be combined with enum values');
1588
+ }
1589
+ if (literalValues.length) {
1590
+ if (variableAliasRefs.length) {
1591
+ throw new Error('Managed dynamic utility enum values cannot be combined with namespaces');
1592
+ }
1593
+ if (!kind && literalValues.length < 2) {
1594
+ throw new Error('Managed dynamic utility enum source requires at least two values separated by "|"');
1595
+ }
1596
+ }
1597
+ return {
1598
+ kind: 'dynamic',
1599
+ name: `${key}:<${canonicalValues.join('|')}>`,
1600
+ dynamic: {
1601
+ key,
1602
+ ...variableAliasRefs.length ? {
1603
+ variableAliasRefs
1604
+ } : {},
1605
+ ...kind ? {
1606
+ kind
1607
+ } : {},
1608
+ ...literalValues.length ? {
1609
+ values: literalValues
1610
+ } : {},
1611
+ ...arbitrary ? {
1612
+ arbitrary
1613
+ } : {}
1614
+ }
1615
+ };
1616
+ }
1617
+ function parseManagedPatternName(source) {
1618
+ const pattern = source.trim();
1619
+ const { prefix } = parseManagedPatternSegments(pattern);
1620
+ return prefix.endsWith(':') ? parseManagedDynamicPatternName(pattern) : parseManagedEnumPatternName(pattern);
1621
+ }
1622
+ function parseManagedPatternNameIfNeeded(source) {
1623
+ return source.includes('<') || source.includes('>') ? parseManagedPatternName(source) : undefined;
1624
+ }
1625
+ function ensureUtilityDefinitionRules(definition) {
1626
+ if (!definition.declarations) return;
1627
+ const declarations = definition.declarations;
1628
+ delete definition.declarations;
1629
+ const atRules = definition.atRules;
1630
+ delete definition.atRules;
1631
+ definition.rules ??= [];
1632
+ definition.rules.push({
1633
+ declarations,
1634
+ ...atRules?.length ? {
1635
+ atRules: [
1636
+ ...atRules
1637
+ ]
1638
+ } : {}
1639
+ });
1640
+ }
1641
+ function pushUtilityDefinitionRule(definition, declarations, selector = '&', atRules = []) {
1642
+ if (!Object.keys(declarations).length) return;
1643
+ const rule = {
1644
+ declarations,
1645
+ ...selector !== '&' ? {
1646
+ selector
1647
+ } : {},
1648
+ ...atRules.length ? {
1649
+ atRules: [
1650
+ ...atRules
1651
+ ]
1652
+ } : {}
1653
+ };
1654
+ if (!definition.declarations && !definition.rules?.length && !rule.selector && !rule.atRules) {
1655
+ definition.declarations = declarations;
1656
+ return;
1657
+ }
1658
+ ensureUtilityDefinitionRules(definition);
1659
+ definition.rules ??= [];
1660
+ definition.rules.push(rule);
1661
+ }
1662
+ function parseManagedPatternStyleDefinitionBody(parsed, definition, items, directiveName, selectors = [
1663
+ '&'
1664
+ ], atRules = []) {
1665
+ for (const item of items){
1666
+ if (item.type === 'declarations') {
1667
+ for (const selector of selectors){
1668
+ pushUtilityDefinitionRule(definition, item.declarations, selector, atRules);
1669
+ }
1670
+ continue;
1671
+ }
1672
+ if (item.type === 'compose') {
1673
+ throw new CSSDirectiveError('compose-placement', `@compose is not supported inside managed pattern definitions`, item.directiveSource);
1674
+ }
1675
+ parseManagedPatternChildRule(item.rule, parsed, definition, directiveName, selectors, atRules);
1676
+ }
1677
+ }
1678
+ function parseManagedPatternChildRule(child, parsed, definition, directiveName, selectors = [
1679
+ '&'
1680
+ ], atRules = []) {
1681
+ if (child.type === 'layer-block') {
1682
+ throw new Error(`Nested @layer blocks are not allowed inside @${directiveName}`);
1683
+ }
1684
+ assertNotSlotRule(child);
1685
+ const masterVariantBlock = parseMasterVariantBlock(child);
1686
+ if (masterVariantBlock) {
1687
+ parseManagedPatternStyleDefinitionBody(parsed, definition, collectDirectiveStyleRuleBody(EMPTY_DECLARATION_BLOCK, masterVariantBlock.rules, parsed), directiveName, selectors, [
1688
+ ...atRules,
1689
+ createCSSDirectiveVariantReference(masterVariantBlock.token)
1690
+ ]);
1691
+ return;
1692
+ }
1693
+ const nestedAtRuleChildren = getNestedAtRuleChildren(child);
1694
+ if (nestedAtRuleChildren) {
1695
+ const atRule = formatNestedAtRule(child);
1696
+ if (!atRule) {
1697
+ throw new Error(`Unsupported nested at-rule inside @${directiveName}`);
1698
+ }
1699
+ parseManagedPatternStyleDefinitionBody(parsed, definition, collectDirectiveStyleRuleBody(EMPTY_DECLARATION_BLOCK, nestedAtRuleChildren, parsed), directiveName, selectors, [
1700
+ ...atRules,
1701
+ atRule
1702
+ ]);
1703
+ return;
1704
+ }
1705
+ if (child.type === 'style') {
1706
+ parseManagedPatternStyleDefinitionBody(parsed, definition, collectDirectiveStyleRule(child, parsed), directiveName, combineStyleSelectorLists(selectors, child.value.selectors), atRules);
1707
+ return;
1708
+ }
1709
+ const compose = parseComposeRule(child, parsed);
1710
+ if (compose) {
1711
+ throw new CSSDirectiveError('compose-placement', `@compose is not supported inside managed pattern definitions`, compose.directiveSource);
1712
+ }
1713
+ if (child.type === 'keyframes') {
1714
+ throw new Error(`@keyframes is not allowed inside @${directiveName}. Move managed animation definitions to top-level @theme.`);
1715
+ }
1716
+ throw new Error(`Managed pattern definitions only accept declarations, nested selectors, and nested at-rules`);
1717
+ }
1718
+ function parseManagedPatternDefinitionRule(child, parsed, parsedPattern, atRules, layer, directiveName) {
1719
+ const definition = {
1720
+ name: parsedPattern.name,
1721
+ type: parsedPattern.kind === 'pattern' ? 'pattern' : 'dynamic',
1722
+ layer,
1723
+ ...parsedPattern.kind === 'pattern' ? {
1724
+ pattern: parsedPattern.pattern
1725
+ } : {
1726
+ dynamic: parsedPattern.dynamic
1727
+ }
1728
+ };
1729
+ parseManagedPatternStyleDefinitionBody(parsed, definition, collectDirectiveStyleRule(child, parsed), directiveName, [
1730
+ '&'
1731
+ ], atRules);
1732
+ parsed.manifestInput.utilities ??= [];
1733
+ parsed.manifestInput.utilities.push(definition);
1734
+ }
1735
+ function containsNativeStyleDirective(rule) {
1736
+ if ((rule.type === 'unknown' || rule.type === 'custom') && (rule.value?.name === 'compose' || rule.value?.name === 'variant' || rule.value?.name === 'slot' || getMasterVariantShorthandToken(rule.value?.name))) {
1737
+ return true;
1738
+ }
1739
+ if (rule.type === 'style') {
1740
+ return (rule.value.rules || []).some(containsNativeStyleDirective);
1741
+ }
1742
+ const nestedAtRuleChildren = getNestedAtRuleChildren(rule);
1743
+ if (nestedAtRuleChildren) {
1744
+ return nestedAtRuleChildren.some(containsNativeStyleDirective);
1745
+ }
1746
+ return false;
1747
+ }
1748
+ function createManagedDefinitionNameError(rule) {
1749
+ return new Error(`Managed definition names must be bare identifiers: ${formatSelectors(rule.value.selectors)}`);
1750
+ }
1751
+ function parseManagedDefinitionDirectiveChildRule(child, parsed, atRules, layer, directiveName) {
1752
+ if (child.type === 'layer-block') {
1753
+ throw new Error(`Nested @layer blocks are not allowed inside @${directiveName}`);
1754
+ }
1755
+ const masterVariantBlock = parseMasterVariantBlock(child);
1756
+ if (masterVariantBlock) {
1757
+ for (const nestedChild of masterVariantBlock.rules){
1758
+ parseManagedDefinitionDirectiveChildRule(nestedChild, parsed, [
1759
+ ...atRules,
1760
+ createCSSDirectiveVariantReference(masterVariantBlock.token)
1761
+ ], layer, directiveName);
1762
+ }
1763
+ return;
1764
+ }
1765
+ const nestedAtRuleChildren = getNestedAtRuleChildren(child);
1766
+ if (nestedAtRuleChildren) {
1767
+ const atRule = formatNestedAtRule(child);
1768
+ if (!atRule) {
1769
+ throw new Error(`Unsupported nested at-rule inside @${directiveName}`);
1770
+ }
1771
+ for (const nestedChild of nestedAtRuleChildren){
1772
+ parseManagedDefinitionDirectiveChildRule(nestedChild, parsed, [
1773
+ ...atRules,
1774
+ atRule
1775
+ ], layer, directiveName);
1776
+ }
1777
+ return;
1778
+ }
1779
+ if (child.type === 'nested-declarations') {
1780
+ throw new Error(`@${directiveName} only accepts bare managed names and nested at-rules`);
1781
+ }
1782
+ if (child.type === 'keyframes') {
1783
+ throw new Error('@keyframes is not allowed inside managed definition directives. Move managed animation definitions to top-level @theme.');
1784
+ }
1785
+ if (child.type === 'style') {
1786
+ const selectorSource = createSelectorSourceReference(parsed, child);
1787
+ const selectorText = selectorSource && parsed.source ? parsed.source.slice(selectorSource.range.start, selectorSource.range.end).trim() : '';
1788
+ const parsedPattern = parseManagedPatternNameIfNeeded(selectorText);
1789
+ const selectorDefinition = parseManagedDefinitionNameSelector(child.value.selectors);
1790
+ if (!selectorDefinition) {
1791
+ throw createManagedDefinitionNameError(child);
1792
+ }
1793
+ if (parsedPattern) {
1794
+ parseManagedPatternDefinitionRule(child, parsed, parsedPattern, atRules, layer, directiveName);
1795
+ return;
1796
+ }
1797
+ selectorDefinition.source = selectorSource;
1798
+ parseStyleDefinitionBody(parsed, selectorDefinition, collectDirectiveStyleRule(child, parsed), atRules, layer);
1799
+ return;
1800
+ }
1801
+ if ((child.type === 'unknown' || child.type === 'custom') && child.value?.name === 'compose') {
1802
+ throw createComposePlacementError(parsed);
1803
+ }
1804
+ if (isCustomVariantDefinition(child)) {
1805
+ throw new Error('@custom-variant must be top-level');
1806
+ }
1807
+ throw new Error(`Unsupported rule inside @${directiveName}`);
1808
+ }
1809
+ function parseManagedDefinitionDirectiveRule(rule, parsed) {
1810
+ const layer = getManagedDefinitionDirectiveLayer(rule);
1811
+ if (!layer) return;
1812
+ const body = getCustomRuleBody(rule);
1813
+ if (!Array.isArray(body?.value)) {
1814
+ throw new Error(`@${rule.value.name} requires a style block`);
1815
+ }
1816
+ for (const child of body.value){
1817
+ parseManagedDefinitionDirectiveChildRule(child, parsed, [], layer, rule.value.name);
1818
+ }
1819
+ }
1820
+ function isManagedDefinitionDirectiveRange(range) {
1821
+ return range.depth === 0 && (range.name === 'defaults' || range.name === 'components' || range.name === 'utilities') && range.blockContentRange;
1822
+ }
1823
+ function skipCSSWhitespaceAndComments(source, index, end) {
1824
+ while(index < end){
1825
+ index = skipCSSWhitespace(source, index);
1826
+ if (source[index] === '/' && source[index + 1] === '*') {
1827
+ const close = source.indexOf('*/', index + 2);
1828
+ index = close === -1 ? end : close + 2;
1829
+ continue;
1830
+ }
1831
+ break;
1832
+ }
1833
+ return index;
1834
+ }
1835
+ function createManagedPatternNameMask(length) {
1836
+ return 'm' + '_'.repeat(Math.max(0, length - 1));
1837
+ }
1838
+ function collectManagedPatternEntryNameMasks(source, start, end, replacements) {
1839
+ let index = start;
1840
+ while(index < end){
1841
+ index = skipCSSWhitespaceAndComments(source, index, end);
1842
+ if (index >= end) break;
1843
+ const char = source[index];
1844
+ if (char === '"' || char === '\'') {
1845
+ index = findCSSClosingQuote(source, index, char, end) + 1;
1846
+ continue;
1847
+ }
1848
+ const statementEnd = findCSSStatementEnd(source, index);
1849
+ if (char === '@') {
1850
+ if (statementEnd.reason === 'block' && statementEnd.delimiterRange) {
1851
+ const blockEnd = findCSSBlockEnd(source, statementEnd.delimiterRange.start);
1852
+ collectManagedPatternEntryNameMasks(source, statementEnd.delimiterRange.start + 1, blockEnd === -1 ? end : Math.min(blockEnd, end), replacements);
1853
+ index = blockEnd === -1 ? end : blockEnd + 1;
1854
+ continue;
1855
+ }
1856
+ index = Math.max(index + 1, statementEnd.end);
1857
+ continue;
1858
+ }
1859
+ if (statementEnd.reason === 'block' && statementEnd.delimiterRange) {
1860
+ const entryNameRange = trimSourceRange(source, {
1861
+ start: index,
1862
+ end: statementEnd.delimiterRange.start
1863
+ });
1864
+ const entryName = source.slice(entryNameRange.start, entryNameRange.end);
1865
+ if (parseManagedPatternNameIfNeeded(entryName)) {
1866
+ replacements.push({
1867
+ ...entryNameRange,
1868
+ replacement: createManagedPatternNameMask(entryNameRange.end - entryNameRange.start)
1869
+ });
1870
+ }
1871
+ const blockEnd = findCSSBlockEnd(source, statementEnd.delimiterRange.start);
1872
+ index = blockEnd === -1 ? end : blockEnd + 1;
1873
+ continue;
1874
+ }
1875
+ index = Math.max(index + 1, statementEnd.end);
1876
+ }
1877
+ }
1878
+ function maskManagedPatternEntryNames(source) {
1879
+ const replacements = [];
1880
+ for (const range of collectCSSDirectiveRanges(source)){
1881
+ if (!isManagedDefinitionDirectiveRange(range)) continue;
1882
+ if (!range.blockContentRange) continue;
1883
+ collectManagedPatternEntryNameMasks(source, range.blockContentRange.start, range.blockContentRange.end, replacements);
1884
+ }
1885
+ return replaceSourceRanges(source, replacements);
1886
+ }
1887
+ function compileCSS(source, options = {}) {
1888
+ const filename = options.from || 'master.css';
1889
+ const references = findCSSReferenceStatements(source, filename);
1890
+ const sourceWithoutReferences = removeSourceRanges(source, references);
1891
+ const parsed = {
1892
+ manifestInput: {},
1893
+ extractionPolicy: createCSSDirectiveExtractionPolicy(),
1894
+ classNames: [],
1895
+ nativeClassNames: [],
1896
+ warnings: [],
1897
+ source,
1898
+ filename,
1899
+ composeRanges: collectCSSDirectiveRanges(source).filter((range)=>range.name === 'compose'),
1900
+ composeRangeIndex: 0,
1901
+ sourceLocationResolver: createSourceLocationResolver(source)
1902
+ };
1903
+ const classFilter = options.classes === undefined ? undefined : new Set(options.classes);
1904
+ parsed.extractionPolicy = collectStandaloneCSSDirectiveExtractionPolicy(sourceWithoutReferences, filename);
1905
+ validateComposeRanges(parsed);
1906
+ const preprocessedSource = maskManagedPatternEntryNames(removeStandaloneCSSDirectives(sourceWithoutReferences, filename));
1907
+ let ruleDepth = 0;
1908
+ const transformed = getCSSTransform()({
1909
+ filename,
1910
+ code: encodeCSS(preprocessedSource),
1911
+ customAtRules: MASTER_CUSTOM_AT_RULES,
1912
+ visitor: {
1913
+ Rule (rule) {
1914
+ if (ruleDepth === 0) {
1915
+ if (isCustomVariantDefinition(rule)) {
1916
+ parseVariantDefinition(rule, parsed);
1917
+ return [];
1918
+ }
1919
+ const masterVariantBlock = parseMasterVariantBlock(rule);
1920
+ if (masterVariantBlock) {
1921
+ parseNativeRuleBody(masterVariantBlock.rules, parsed, [
1922
+ createCSSDirectiveVariantReference(masterVariantBlock.token)
1923
+ ]);
1924
+ return [];
1925
+ }
1926
+ const nestedAtRuleChildren = getNestedAtRuleChildren(rule);
1927
+ if (nestedAtRuleChildren && containsNativeStyleDirective(rule)) {
1928
+ const atRule = formatNestedAtRule(rule);
1929
+ if (!atRule) {
1930
+ throw new Error('Unsupported nested at-rule in native CSS');
1931
+ }
1932
+ parseNativeRuleBody(nestedAtRuleChildren, parsed, [
1933
+ atRule
1934
+ ]);
1935
+ return [];
1936
+ }
1937
+ if (rule.type === 'style' && containsNativeStyleDirective(rule)) {
1938
+ parseNativeStyleRule(rule, parsed);
1939
+ return [];
1940
+ }
1941
+ }
1942
+ if (rule.type === 'custom') {
1943
+ switch(rule.value.name){
1944
+ case 'settings':
1945
+ if (ruleDepth !== 0) {
1946
+ throw new Error('@settings must be top-level');
1947
+ }
1948
+ parseSettingsRule(rule, parsed);
1949
+ return [];
1950
+ case 'theme':
1951
+ if (ruleDepth !== 0) {
1952
+ throw new Error('@theme must be top-level');
1953
+ }
1954
+ parseThemeRule(rule, parsed);
1955
+ return [];
1956
+ case 'defaults':
1957
+ case 'components':
1958
+ case 'utilities':
1959
+ if (ruleDepth !== 0) {
1960
+ throw new Error(`@${rule.value.name} must be top-level`);
1961
+ }
1962
+ parseManagedDefinitionDirectiveRule(rule, parsed);
1963
+ return [];
1964
+ case 'compose':
1965
+ throw createComposePlacementError(parsed);
1966
+ case 'custom-variant':
1967
+ throw new Error('@custom-variant must be top-level');
1968
+ case 'variant':
1969
+ throw new Error('@variant requires a style rule or nested style rules');
1970
+ case 'reference':
1971
+ throw new Error('@reference must be top-level');
1972
+ }
1973
+ }
1974
+ ruleDepth++;
1975
+ },
1976
+ RuleExit () {
1977
+ ruleDepth--;
1978
+ }
1979
+ }
1980
+ });
1981
+ let remainingCSS = '';
1982
+ if (options.preserveNativeCSS !== false) {
1983
+ const filteredCode = filterNativeCSS(transformed.code, filename, parsed, classFilter);
1984
+ const remainingCode = classFilter ? pruneEmptyRuleBlocks(filteredCode, filename) : filteredCode;
1985
+ remainingCSS = decodeCSS(remainingCode).trim();
1986
+ }
1987
+ return {
1988
+ manifestInput: parsed.manifestInput,
1989
+ extractionPolicy: parsed.extractionPolicy,
1990
+ classNames: parsed.classNames,
1991
+ nativeClassNames: parsed.nativeClassNames,
1992
+ warnings: parsed.warnings,
1993
+ nativeCSS: remainingCSS,
1994
+ css: remainingCSS,
1995
+ generatedCSS: '',
1996
+ dependencies: [],
1997
+ ...references.length ? {
1998
+ references
1999
+ } : {},
2000
+ ...parsed.styleDefinitions ? {
2001
+ styleDefinitions: parsed.styleDefinitions
2002
+ } : {}
2003
+ };
2004
+ }
2005
+ function parseDirectives(source, options = {}) {
2006
+ const { manifestInput, extractionPolicy, classNames, nativeClassNames, warnings, styleDefinitions } = compileCSS(source, options);
2007
+ return {
2008
+ manifestInput,
2009
+ extractionPolicy,
2010
+ classNames,
2011
+ nativeClassNames,
2012
+ warnings,
2013
+ ...styleDefinitions ? {
2014
+ styleDefinitions
2015
+ } : {}
2016
+ };
2017
+ }
2018
+
2019
+ export { collectStandaloneCSSDirectiveExtractionPolicy, compileCSS, createCSSDirectiveExtractionPolicy, findCSSReferenceStatements, maskManagedPatternEntryNames, parseDirectives, removeCSSReferenceStatements, removeStandaloneCSSDirectives };