@drskillissue/ganko 0.2.72 → 0.2.81

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.
@@ -150,7 +150,6 @@ var CHAR_DOUBLE_QUOTE = 34;
150
150
  var CHAR_SINGLE_QUOTE = 39;
151
151
  var CHAR_A = 97;
152
152
  var CHAR_E = 101;
153
- var CHAR_H = 104;
154
153
  var CHAR_I = 105;
155
154
  var CHAR_M = 109;
156
155
  var CHAR_N = 110;
@@ -521,7 +520,6 @@ var ID_STICKY = /#([a-zA-Z_-][a-zA-Z0-9_-]*)/y;
521
520
  var CLASS_STICKY = /\.([a-zA-Z_-][a-zA-Z0-9_-]*)/y;
522
521
  var ATTRIBUTE_STICKY = /\[([^\]]+)\]/y;
523
522
  var PSEUDO_ELEMENT_STICKY = /::([a-zA-Z-]+)(?:\([^)]*\))?/y;
524
- var PSEUDO_CLASS_STICKY = /:([a-zA-Z-]+)(?:\([^)]*\))?/y;
525
523
  var ELEMENT_STICKY = /([a-zA-Z][a-zA-Z0-9-]*)/y;
526
524
  var WHITESPACE_SPLIT = /\s+/;
527
525
  var FUNCTION_CALL_RE = /([a-zA-Z_][\w-]*)\s*\(/g;
@@ -4020,6 +4018,10 @@ function getStaticStringFromJSXValue(node) {
4020
4018
  if (ts7.isTemplateExpression(expression) && expression.templateSpans.length === 0) {
4021
4019
  return expression.head.text;
4022
4020
  }
4021
+ if (ts7.isBinaryExpression(expression) && expression.operatorToken.kind === ts7.SyntaxKind.QuestionQuestionToken) {
4022
+ const fallback = getStaticStringFromJSXValue(expression.right);
4023
+ if (fallback !== null) return fallback;
4024
+ }
4023
4025
  }
4024
4026
  return null;
4025
4027
  }
@@ -23206,57 +23208,31 @@ var mediaQueryOverlapConflict = defineCSSRule({
23206
23208
  var messages101 = {
23207
23209
  descendingSpecificity: "Lower-specificity selector `{{laterSelector}}` appears after `{{earlierSelector}}` for `{{property}}`, creating brittle cascade behavior."
23208
23210
  };
23209
- var UNSUPPORTED_TYPES = /* @__PURE__ */ new Set(["attribute", "pseudo-class", "pseudo-element", "universal", "nesting"]);
23210
23211
  function extractCompounds(selector) {
23211
- const parts = selector.parts;
23212
- if (parts.length === 0) return null;
23213
- for (let i = 0; i < parts.length; i++) {
23214
- const part = parts[i];
23215
- if (!part) continue;
23216
- if (UNSUPPORTED_TYPES.has(part.type)) return null;
23212
+ const selectorCompounds = selector.compounds;
23213
+ if (selectorCompounds.length === 0) return null;
23214
+ for (let i = 0; i < selectorCompounds.length; i++) {
23215
+ const sc = selectorCompounds[i];
23216
+ if (!sc) continue;
23217
+ const parts = sc.parts;
23218
+ for (let j = 0; j < parts.length; j++) {
23219
+ const part = parts[j];
23220
+ if (!part) continue;
23221
+ const t = part.type;
23222
+ if (t === "attribute" || t === "pseudo-class" || t === "pseudo-element" || t === "universal" || t === "nesting") return null;
23223
+ }
23217
23224
  }
23218
- return splitIntoCompounds(selector);
23219
- }
23220
- function splitIntoCompounds(selector) {
23221
- const raw = selector.raw;
23222
- const combinators = selector.complexity.combinators;
23223
- const segments = splitRawByCombinators(raw);
23224
- if (!segments || segments.length !== combinators.length + 1) return null;
23225
23225
  const compounds = [];
23226
- for (let i = 0; i < segments.length; i++) {
23227
- const seg = segments[i];
23228
- if (!seg) continue;
23229
- const compound = parseCompoundFromParts(seg);
23230
- if (!compound) return null;
23231
- compounds.push(compound);
23226
+ for (let i = 0; i < selectorCompounds.length; i++) {
23227
+ const sc = selectorCompounds[i];
23228
+ if (!sc) continue;
23229
+ const ids = [];
23230
+ if (sc.idValue !== null) ids.push(sc.idValue);
23231
+ if (!sc.tagName && sc.classes.length === 0 && ids.length === 0) return null;
23232
+ compounds.push({ tag: sc.tagName, classes: sc.classes, ids });
23232
23233
  }
23233
23234
  return compounds;
23234
23235
  }
23235
- var COMBINATOR_SPLIT = /\s*[>+~]\s*|\s+/;
23236
- function splitRawByCombinators(raw) {
23237
- const trimmed = raw.trim();
23238
- if (trimmed.length === 0) return null;
23239
- const segments = trimmed.split(COMBINATOR_SPLIT).filter((s) => s.length > 0);
23240
- return segments.length > 0 ? segments : null;
23241
- }
23242
- var COMPOUND_TOKEN = /([.#]?)([_a-zA-Z][_a-zA-Z0-9-]*)/g;
23243
- function parseCompoundFromParts(segment) {
23244
- let tag = null;
23245
- const classes = [];
23246
- const ids = [];
23247
- COMPOUND_TOKEN.lastIndex = 0;
23248
- let match;
23249
- while ((match = COMPOUND_TOKEN.exec(segment)) !== null) {
23250
- const prefix = match[1];
23251
- const value2 = match[2];
23252
- if (!value2) continue;
23253
- if (prefix === ".") classes.push(value2);
23254
- else if (prefix === "#") ids.push(value2);
23255
- else tag = value2;
23256
- }
23257
- if (!tag && classes.length === 0 && ids.length === 0) return null;
23258
- return { tag, classes, ids };
23259
- }
23260
23236
  function hasToken(list, token) {
23261
23237
  for (let i = 0; i < list.length; i++) {
23262
23238
  if (list[i] === token) return true;
@@ -23298,8 +23274,8 @@ function isProvableDescendingPair(earlier, later) {
23298
23274
  if (!earlierCompounds) return false;
23299
23275
  const laterCompounds = extractCompounds(later);
23300
23276
  if (!laterCompounds) return false;
23301
- const earlierCombinators = earlier.complexity.combinators;
23302
- const laterCombinators = later.complexity.combinators;
23277
+ const earlierCombinators = earlier.combinators;
23278
+ const laterCombinators = later.combinators;
23303
23279
  if (earlierCompounds.length !== laterCompounds.length) return false;
23304
23280
  if (earlierCombinators.length !== laterCombinators.length) return false;
23305
23281
  for (let i = 0; i < earlierCombinators.length; i++) {
@@ -23579,7 +23555,7 @@ function splitWhitespaceTokens(value2) {
23579
23555
  return out;
23580
23556
  }
23581
23557
  function parseQuadShorthand(raw) {
23582
- const parts = splitWhitespaceTokens(raw);
23558
+ const parts = splitTopLevelWhitespace(raw);
23583
23559
  if (parts.length === 1) {
23584
23560
  const p0 = parts[0];
23585
23561
  if (!p0) return null;
@@ -23603,7 +23579,7 @@ function parseQuadShorthand(raw) {
23603
23579
  return null;
23604
23580
  }
23605
23581
  function parseBlockShorthand(raw) {
23606
- const parts = splitWhitespaceTokens(raw);
23582
+ const parts = splitTopLevelWhitespace(raw);
23607
23583
  if (parts.length === 1) {
23608
23584
  const p0 = parts[0];
23609
23585
  if (!p0) return null;
@@ -23688,8 +23664,14 @@ var NUMERIC_VALUE = /^([0-9]*\.?[0-9]+)(px|rem|em|pt)?$/;
23688
23664
  function parsePxValue(raw, contextFontSize = 16) {
23689
23665
  const trimmed = raw.trim().toLowerCase();
23690
23666
  if (trimmed.length === 0) return null;
23691
- if (trimmed.includes("var(") || trimmed.includes("calc(") || trimmed.includes("%")) return null;
23667
+ if (trimmed.includes("var(") || trimmed.includes("%")) return null;
23692
23668
  if (CSS_WIDE_KEYWORDS.has(trimmed)) return null;
23669
+ if (trimmed.includes("calc(")) {
23670
+ return tryEvalConstantCalc(trimmed, contextFontSize);
23671
+ }
23672
+ if (trimmed.startsWith("min(") || trimmed.startsWith("max(") || trimmed.startsWith("clamp(")) {
23673
+ return tryEvalMathFunction(trimmed, contextFontSize);
23674
+ }
23693
23675
  const match = NUMERIC_VALUE.exec(trimmed);
23694
23676
  if (!match) return null;
23695
23677
  const num = Number(match[1]);
@@ -23700,6 +23682,135 @@ function parsePxValue(raw, contextFontSize = 16) {
23700
23682
  if (unit === "pt") return num * 1.333;
23701
23683
  return null;
23702
23684
  }
23685
+ var CALC_CONSTANT_RE = /^calc\((.+)\)$/;
23686
+ var CALC_TOKEN_RE = /([0-9]*\.?[0-9]+)(px|rem|em|pt)?|([+\-*/])/g;
23687
+ function tryEvalConstantCalc(raw, contextFontSize) {
23688
+ const match = CALC_CONSTANT_RE.exec(raw);
23689
+ if (!match || !match[1]) return null;
23690
+ const inner = match[1].trim();
23691
+ if (inner.includes("var(") || inner.includes("%") || inner.includes("env(") || inner.includes("calc(")) return null;
23692
+ const values = [];
23693
+ const operators = [];
23694
+ let lastWasValue = false;
23695
+ CALC_TOKEN_RE.lastIndex = 0;
23696
+ let tokenMatch;
23697
+ while ((tokenMatch = CALC_TOKEN_RE.exec(inner)) !== null) {
23698
+ const op = tokenMatch[3];
23699
+ if (op !== void 0) {
23700
+ if (!lastWasValue && op === "-") {
23701
+ const nextToken = CALC_TOKEN_RE.exec(inner);
23702
+ if (!nextToken || nextToken[3] !== void 0) return null;
23703
+ const px2 = calcTokenToPx(nextToken, contextFontSize);
23704
+ if (px2 === null) return null;
23705
+ values.push(-px2);
23706
+ lastWasValue = true;
23707
+ continue;
23708
+ }
23709
+ if (!lastWasValue) return null;
23710
+ operators.push(op);
23711
+ lastWasValue = false;
23712
+ continue;
23713
+ }
23714
+ const px = calcTokenToPx(tokenMatch, contextFontSize);
23715
+ if (px === null) return null;
23716
+ values.push(px);
23717
+ lastWasValue = true;
23718
+ }
23719
+ if (values.length === 0 || values.length !== operators.length + 1) return null;
23720
+ const firstValue = values[0];
23721
+ if (firstValue === void 0) return null;
23722
+ const reducedValues = [firstValue];
23723
+ const reducedOps = [];
23724
+ for (let i = 0; i < operators.length; i++) {
23725
+ const op = operators[i];
23726
+ const right = values[i + 1];
23727
+ if (op === void 0 || right === void 0) return null;
23728
+ if (op === "*") {
23729
+ const last = reducedValues[reducedValues.length - 1];
23730
+ if (last === void 0) return null;
23731
+ reducedValues[reducedValues.length - 1] = last * right;
23732
+ } else if (op === "/") {
23733
+ if (right === 0) return null;
23734
+ const last = reducedValues[reducedValues.length - 1];
23735
+ if (last === void 0) return null;
23736
+ reducedValues[reducedValues.length - 1] = last / right;
23737
+ } else {
23738
+ reducedValues.push(right);
23739
+ reducedOps.push(op);
23740
+ }
23741
+ }
23742
+ const base = reducedValues[0];
23743
+ if (base === void 0) return null;
23744
+ let result = base;
23745
+ for (let i = 0; i < reducedOps.length; i++) {
23746
+ const op = reducedOps[i];
23747
+ const right = reducedValues[i + 1];
23748
+ if (op === void 0 || right === void 0) return null;
23749
+ if (op === "+") result += right;
23750
+ else if (op === "-") result -= right;
23751
+ else return null;
23752
+ }
23753
+ return Number.isFinite(result) ? result : null;
23754
+ }
23755
+ function calcTokenToPx(tokenMatch, contextFontSize) {
23756
+ const num = Number(tokenMatch[1]);
23757
+ if (Number.isNaN(num)) return null;
23758
+ const unit = tokenMatch[2] ?? "";
23759
+ if (unit === "px" || unit === "") return num;
23760
+ if (unit === "rem") return num * 16;
23761
+ if (unit === "em") return num * contextFontSize;
23762
+ if (unit === "pt") return num * 1.333;
23763
+ return null;
23764
+ }
23765
+ var MATH_FN_RE = /^(min|max|clamp)\((.+)\)$/;
23766
+ function tryEvalMathFunction(raw, contextFontSize) {
23767
+ const match = MATH_FN_RE.exec(raw);
23768
+ if (!match || !match[1] || !match[2]) return null;
23769
+ const fn = match[1];
23770
+ const inner = match[2];
23771
+ const args = splitMathArgs(inner);
23772
+ if (args === null) return null;
23773
+ const values = [];
23774
+ for (let i = 0; i < args.length; i++) {
23775
+ const arg = args[i];
23776
+ if (!arg) return null;
23777
+ const px = parsePxValue(arg.trim(), contextFontSize);
23778
+ if (px === null) return null;
23779
+ values.push(px);
23780
+ }
23781
+ if (values.length === 0) return null;
23782
+ if (fn === "min") return Math.min(...values);
23783
+ if (fn === "max") return Math.max(...values);
23784
+ if (fn === "clamp") {
23785
+ if (values.length !== 3) return null;
23786
+ const [lo, val, hi] = values;
23787
+ return Math.max(lo, Math.min(val, hi));
23788
+ }
23789
+ return null;
23790
+ }
23791
+ function splitMathArgs(inner) {
23792
+ const args = [];
23793
+ let depth = 0;
23794
+ let start = 0;
23795
+ for (let i = 0; i < inner.length; i++) {
23796
+ const ch = inner[i];
23797
+ if (ch === "(") depth++;
23798
+ else if (ch === ")") {
23799
+ if (depth > 0) depth--;
23800
+ else return null;
23801
+ } else if (ch === "," && depth === 0) {
23802
+ const arg = inner.slice(start, i).trim();
23803
+ if (arg.length === 0) return null;
23804
+ args.push(arg);
23805
+ start = i + 1;
23806
+ }
23807
+ }
23808
+ if (depth !== 0) return null;
23809
+ const tail = inner.slice(start).trim();
23810
+ if (tail.length === 0) return null;
23811
+ args.push(tail);
23812
+ return args;
23813
+ }
23703
23814
  function parseUnitlessValue(raw) {
23704
23815
  const trimmed = raw.trim().toLowerCase();
23705
23816
  if (trimmed.length === 0) return null;
@@ -26251,19 +26362,6 @@ var FONT_GENERIC_FAMILY_SET = /* @__PURE__ */ new Set([
26251
26362
  ]);
26252
26363
  var FONT_LAYOUT_PROPERTIES = /* @__PURE__ */ new Set(["font-family"]);
26253
26364
  var WHITESPACE_RE2 = /\s+/;
26254
- function classifyRuleElementKinds(rule) {
26255
- const kinds = rule.elementKinds;
26256
- for (let i = 0; i < rule.selectors.length; i++) {
26257
- const sel = rule.selectors[i];
26258
- if (!sel) continue;
26259
- const parts = sel.parts;
26260
- for (let j = 0; j < parts.length; j++) {
26261
- const part = parts[j];
26262
- if (!part) continue;
26263
- classifyPart(part, kinds);
26264
- }
26265
- }
26266
- }
26267
26365
  function classifyPart(part, kinds) {
26268
26366
  if (part.type === "element") {
26269
26367
  const lower = part.value.toLowerCase();
@@ -26391,7 +26489,19 @@ var CSSGraph = class {
26391
26489
  parseErrors = [];
26392
26490
  failedFilePaths = [];
26393
26491
  tokenCategories = [];
26394
- filesWithLayers = /* @__PURE__ */ new Set();
26492
+ _filesWithLayers = null;
26493
+ get filesWithLayers() {
26494
+ if (this._filesWithLayers === null) {
26495
+ const result = /* @__PURE__ */ new Set();
26496
+ for (let i = 0; i < this.layers.length; i++) {
26497
+ const layer = this.layers[i];
26498
+ if (!layer) continue;
26499
+ result.add(layer.file.path);
26500
+ }
26501
+ this._filesWithLayers = result;
26502
+ }
26503
+ return this._filesWithLayers;
26504
+ }
26395
26505
  selectorsByPseudoClass = /* @__PURE__ */ new Map();
26396
26506
  knownKeyframeNames = /* @__PURE__ */ new Set();
26397
26507
  unresolvedAnimationRefs = [];
@@ -26403,17 +26513,61 @@ var CSSGraph = class {
26403
26513
  multiDeclarationProperties = /* @__PURE__ */ new Map();
26404
26514
  /** Declarations whose parent rule is inside a @keyframes block. */
26405
26515
  keyframeDeclarations = [];
26406
- /** Rules with zero declarations and zero nested rules. */
26407
- emptyRules = [];
26516
+ /** Rules with zero declarations, zero nested rules, and zero nested at-rules. */
26517
+ _emptyRules = null;
26518
+ get emptyRules() {
26519
+ if (this._emptyRules === null) {
26520
+ this._emptyRules = this.rules.filter((r) => r.declarations.length === 0 && r.nestedRules.length === 0 && r.nestedAtRules.length === 0);
26521
+ }
26522
+ return this._emptyRules;
26523
+ }
26408
26524
  /** @keyframes at-rules with no effective keyframe declarations. */
26409
- emptyKeyframes = [];
26410
- colorDeclarations = [];
26411
- calcDeclarations = [];
26412
- varDeclarations = [];
26413
- urlDeclarations = [];
26414
- vendorPrefixedDeclarations = [];
26415
- hardcodedColorDeclarations = [];
26416
- overqualifiedSelectors = [];
26525
+ _emptyKeyframes = null;
26526
+ get emptyKeyframes() {
26527
+ if (this._emptyKeyframes === null) {
26528
+ const result = [];
26529
+ for (let i = 0; i < this.keyframes.length; i++) {
26530
+ const kf = this.keyframes[i];
26531
+ if (!kf) continue;
26532
+ if (!kf.parsedParams.animationName) continue;
26533
+ if (kf.rules.length === 0) {
26534
+ result.push(kf);
26535
+ continue;
26536
+ }
26537
+ let hasDeclaration = false;
26538
+ for (let j = 0; j < kf.rules.length; j++) {
26539
+ const kfRule = kf.rules[j];
26540
+ if (!kfRule) continue;
26541
+ if (kfRule.declarations.length > 0) {
26542
+ hasDeclaration = true;
26543
+ break;
26544
+ }
26545
+ }
26546
+ if (!hasDeclaration) result.push(kf);
26547
+ }
26548
+ this._emptyKeyframes = result;
26549
+ }
26550
+ return this._emptyKeyframes;
26551
+ }
26552
+ _overqualifiedSelectors = null;
26553
+ get overqualifiedSelectors() {
26554
+ if (this._overqualifiedSelectors === null) {
26555
+ const result = [];
26556
+ for (let i = 0, len = this.idSelectors.length; i < len; i++) {
26557
+ const sel = this.idSelectors[i];
26558
+ if (!sel) continue;
26559
+ const compounds = sel.compounds;
26560
+ if (compounds.length === 0) continue;
26561
+ const subject = compounds[compounds.length - 1];
26562
+ if (!subject) continue;
26563
+ if (subject.idValue !== null && (subject.tagName !== null || subject.classes.length > 0 || subject.attributes.length > 0)) {
26564
+ result.push(sel);
26565
+ }
26566
+ }
26567
+ this._overqualifiedSelectors = result;
26568
+ }
26569
+ return this._overqualifiedSelectors;
26570
+ }
26417
26571
  idSelectors = [];
26418
26572
  attributeSelectors = [];
26419
26573
  universalSelectors = [];
@@ -26429,7 +26583,13 @@ var CSSGraph = class {
26429
26583
  usedFontFamilies = /* @__PURE__ */ new Set();
26430
26584
  /** Tailwind validator for utility class lookup (null if not a Tailwind project). */
26431
26585
  tailwind;
26432
- deepNestedRules = [];
26586
+ _deepNestedRules = null;
26587
+ get deepNestedRules() {
26588
+ if (this._deepNestedRules === null) {
26589
+ this._deepNestedRules = this.rules.filter((r) => r.depth > 3);
26590
+ }
26591
+ return this._deepNestedRules;
26592
+ }
26433
26593
  constructor(input) {
26434
26594
  this.options = input.options ?? {};
26435
26595
  this.tailwind = input.tailwind ?? null;
@@ -26494,13 +26654,57 @@ var CSSGraph = class {
26494
26654
  }
26495
26655
  addSelector(selector) {
26496
26656
  this.selectors.push(selector);
26657
+ const anchor = selector.anchor;
26658
+ if (anchor.subjectTag === null) {
26659
+ this.selectorsWithoutSubjectTag.push(selector);
26660
+ } else {
26661
+ const existingByTag = this.selectorsBySubjectTag.get(anchor.subjectTag);
26662
+ if (existingByTag) existingByTag.push(selector);
26663
+ else this.selectorsBySubjectTag.set(anchor.subjectTag, [selector]);
26664
+ }
26665
+ if (anchor.targetsCheckbox) this.selectorsTargetingCheckbox.push(selector);
26666
+ if (anchor.targetsTableCell) this.selectorsTargetingTableCell.push(selector);
26667
+ const compounds = selector.compounds;
26668
+ for (let ci = 0; ci < compounds.length; ci++) {
26669
+ const compound = compounds[ci];
26670
+ if (!compound) continue;
26671
+ const cls = compound.classes;
26672
+ for (let j = 0; j < cls.length; j++) {
26673
+ const className = cls[j];
26674
+ if (!className) continue;
26675
+ const existing = this.classNameIndex.get(className);
26676
+ if (existing) existing.push(selector);
26677
+ else this.classNameIndex.set(className, [selector]);
26678
+ }
26679
+ }
26680
+ const complexity = selector.complexity;
26681
+ const flags = complexity._flags;
26682
+ if (hasFlag(flags, SEL_HAS_ID)) this.idSelectors.push(selector);
26683
+ if (hasFlag(flags, SEL_HAS_ATTRIBUTE)) this.attributeSelectors.push(selector);
26684
+ if (hasFlag(flags, SEL_HAS_UNIVERSAL)) this.universalSelectors.push(selector);
26685
+ const pseudoClasses = complexity.pseudoClasses;
26686
+ for (let j = 0; j < pseudoClasses.length; j++) {
26687
+ const pc = pseudoClasses[j];
26688
+ if (!pc) continue;
26689
+ const pcExisting = this.selectorsByPseudoClass.get(pc);
26690
+ if (pcExisting) pcExisting.push(selector);
26691
+ else this.selectorsByPseudoClass.set(pc, [selector]);
26692
+ }
26497
26693
  }
26498
26694
  addDeclaration(decl) {
26499
26695
  this.declarations.push(decl);
26500
- const existing = this.declarationsByProperty.get(decl.property);
26696
+ const property = decl.property;
26697
+ const existing = this.declarationsByProperty.get(property);
26501
26698
  if (existing) existing.push(decl);
26502
- else this.declarationsByProperty.set(decl.property, [decl]);
26699
+ else this.declarationsByProperty.set(property, [decl]);
26503
26700
  if (hasFlag(decl._flags, DECL_IS_IMPORTANT) || decl.node.important) this.importantDeclarations.push(decl);
26701
+ if (decl.rule !== null) {
26702
+ const p = property.toLowerCase();
26703
+ const ruleIndex = decl.rule.declarationIndex;
26704
+ const ruleExisting = ruleIndex.get(p);
26705
+ if (ruleExisting) ruleExisting.push(decl);
26706
+ else ruleIndex.set(p, [decl]);
26707
+ }
26504
26708
  }
26505
26709
  addVariable(variable) {
26506
26710
  this.variables.push(variable);
@@ -26634,39 +26838,12 @@ var CSSGraph = class {
26634
26838
  * Called after all phases complete.
26635
26839
  */
26636
26840
  buildDerivedIndexes() {
26637
- this.buildRuleDeclarationIndexes();
26638
26841
  this.buildContainingMediaStacks();
26639
- this.buildKeyframeIndex();
26842
+ this.buildKeyframeIndexes();
26640
26843
  this.buildContainerNameIndexes();
26641
- this.buildElementKinds();
26642
- this.buildFilesWithLayers();
26643
- this.buildSelectorPseudoClassIndex();
26644
26844
  this.buildMultiDeclarationProperties();
26645
- this.buildKeyframeDeclarations();
26646
- this.buildKeyframeLayoutMutationsByName();
26647
- this.buildEmptyRules();
26648
- this.buildEmptyKeyframes();
26649
- this.buildDeclarationDerivedIndexes();
26650
- this.buildSelectorDerivedIndexes();
26651
26845
  this.buildLayoutPropertiesByClassToken();
26652
- this.buildFontFamilyUsageByRule();
26653
- this.buildFontFaceDescriptorsByFamily();
26654
- this.buildRuleDerivedIndexes();
26655
- }
26656
- buildRuleDeclarationIndexes() {
26657
- for (let i = 0; i < this.rules.length; i++) {
26658
- const rule = this.rules[i];
26659
- if (!rule) continue;
26660
- const index = rule.declarationIndex;
26661
- for (let j = 0; j < rule.declarations.length; j++) {
26662
- const d = rule.declarations[j];
26663
- if (!d) continue;
26664
- const p = d.property.toLowerCase();
26665
- const existing = index.get(p);
26666
- if (existing) existing.push(d);
26667
- else index.set(p, [d]);
26668
- }
26669
- }
26846
+ this.buildFontIndexes();
26670
26847
  }
26671
26848
  buildContainingMediaStacks() {
26672
26849
  for (let i = 0; i < this.rules.length; i++) {
@@ -26681,7 +26858,7 @@ var CSSGraph = class {
26681
26858
  rule.containingMediaStack = medias;
26682
26859
  }
26683
26860
  }
26684
- buildKeyframeIndex() {
26861
+ buildKeyframeIndexes() {
26685
26862
  const IGNORED = /* @__PURE__ */ new Set([...CSS_WIDE_KEYWORDS, "none"]);
26686
26863
  for (let i = 0; i < this.keyframes.length; i++) {
26687
26864
  const kf = this.keyframes[i];
@@ -26703,6 +26880,47 @@ var CSSGraph = class {
26703
26880
  this.unresolvedAnimationRefs.push({ declaration: d, name });
26704
26881
  }
26705
26882
  }
26883
+ const byAnimationByProperty = /* @__PURE__ */ new Map();
26884
+ for (let i = 0; i < this.declarations.length; i++) {
26885
+ const d = this.declarations[i];
26886
+ if (!d) continue;
26887
+ const rule = d.rule;
26888
+ if (!rule) continue;
26889
+ const parent = rule.parent;
26890
+ if (!parent) continue;
26891
+ if (parent.kind === "rule") continue;
26892
+ if (parent.kind !== "keyframes") continue;
26893
+ this.keyframeDeclarations.push(d);
26894
+ const property = d.property.toLowerCase();
26895
+ if (!LAYOUT_ANIMATION_MUTATION_PROPERTIES.has(property)) continue;
26896
+ const animationName = normalizeAnimationName(parent.params);
26897
+ if (!animationName) continue;
26898
+ let byProperty = byAnimationByProperty.get(animationName);
26899
+ if (!byProperty) {
26900
+ byProperty = /* @__PURE__ */ new Map();
26901
+ byAnimationByProperty.set(animationName, byProperty);
26902
+ }
26903
+ let bucket = byProperty.get(property);
26904
+ if (!bucket) {
26905
+ bucket = { values: /* @__PURE__ */ new Set(), declarations: [] };
26906
+ byProperty.set(property, bucket);
26907
+ }
26908
+ bucket.values.add(normalizeCssValue(d.value));
26909
+ bucket.declarations.push(d);
26910
+ }
26911
+ for (const [animationName, byProperty] of byAnimationByProperty) {
26912
+ const mutations = [];
26913
+ for (const [property, bucket] of byProperty) {
26914
+ if (bucket.values.size <= 1) continue;
26915
+ mutations.push({
26916
+ property,
26917
+ values: [...bucket.values],
26918
+ declarations: bucket.declarations
26919
+ });
26920
+ }
26921
+ if (mutations.length === 0) continue;
26922
+ this.keyframeLayoutMutationsByName.set(animationName, mutations);
26923
+ }
26706
26924
  }
26707
26925
  buildContainerNameIndexes() {
26708
26926
  for (let i = 0; i < this.declarations.length; i++) {
@@ -26746,34 +26964,6 @@ var CSSGraph = class {
26746
26964
  }
26747
26965
  }
26748
26966
  }
26749
- buildElementKinds() {
26750
- for (let i = 0; i < this.rules.length; i++) {
26751
- const rule = this.rules[i];
26752
- if (!rule) continue;
26753
- classifyRuleElementKinds(rule);
26754
- }
26755
- }
26756
- buildFilesWithLayers() {
26757
- for (let i = 0; i < this.layers.length; i++) {
26758
- const layer = this.layers[i];
26759
- if (!layer) continue;
26760
- this.filesWithLayers.add(layer.file.path);
26761
- }
26762
- }
26763
- buildSelectorPseudoClassIndex() {
26764
- for (let i = 0; i < this.selectors.length; i++) {
26765
- const sel = this.selectors[i];
26766
- if (!sel) continue;
26767
- const pseudoClasses = sel.complexity.pseudoClasses;
26768
- for (let j = 0; j < pseudoClasses.length; j++) {
26769
- const pc = pseudoClasses[j];
26770
- if (!pc) continue;
26771
- const existing = this.selectorsByPseudoClass.get(pc);
26772
- if (existing) existing.push(sel);
26773
- else this.selectorsByPseudoClass.set(pc, [sel]);
26774
- }
26775
- }
26776
- }
26777
26967
  /**
26778
26968
  * Sort each declarationsByProperty list by sourceOrder and populate
26779
26969
  * multiDeclarationProperties with only those having 2+ entries.
@@ -26786,162 +26976,6 @@ var CSSGraph = class {
26786
26976
  }
26787
26977
  }
26788
26978
  }
26789
- /**
26790
- * Collect declarations whose parent rule is inside a @keyframes block.
26791
- */
26792
- buildKeyframeDeclarations() {
26793
- for (let i = 0; i < this.declarations.length; i++) {
26794
- const d = this.declarations[i];
26795
- if (!d) continue;
26796
- const rule = d.rule;
26797
- if (!rule) continue;
26798
- const parent = rule.parent;
26799
- if (!parent) continue;
26800
- if (parent.kind === "rule") continue;
26801
- if (parent.kind !== "keyframes") continue;
26802
- this.keyframeDeclarations.push(d);
26803
- }
26804
- }
26805
- buildKeyframeLayoutMutationsByName() {
26806
- const byAnimationByProperty = /* @__PURE__ */ new Map();
26807
- for (let i = 0; i < this.keyframeDeclarations.length; i++) {
26808
- const declaration = this.keyframeDeclarations[i];
26809
- if (!declaration) continue;
26810
- const rule = declaration.rule;
26811
- if (!rule || rule.parent === null || rule.parent.kind !== "keyframes") continue;
26812
- const property = declaration.property.toLowerCase();
26813
- if (!LAYOUT_ANIMATION_MUTATION_PROPERTIES.has(property)) continue;
26814
- const animationName = normalizeAnimationName(rule.parent.params);
26815
- if (!animationName) continue;
26816
- let byProperty = byAnimationByProperty.get(animationName);
26817
- if (!byProperty) {
26818
- byProperty = /* @__PURE__ */ new Map();
26819
- byAnimationByProperty.set(animationName, byProperty);
26820
- }
26821
- let bucket = byProperty.get(property);
26822
- if (!bucket) {
26823
- bucket = { values: /* @__PURE__ */ new Set(), declarations: [] };
26824
- byProperty.set(property, bucket);
26825
- }
26826
- bucket.values.add(normalizeCssValue(declaration.value));
26827
- bucket.declarations.push(declaration);
26828
- }
26829
- for (const [animationName, byProperty] of byAnimationByProperty) {
26830
- const mutations = [];
26831
- for (const [property, bucket] of byProperty) {
26832
- if (bucket.values.size <= 1) continue;
26833
- mutations.push({
26834
- property,
26835
- values: [...bucket.values],
26836
- declarations: bucket.declarations
26837
- });
26838
- }
26839
- if (mutations.length === 0) continue;
26840
- this.keyframeLayoutMutationsByName.set(animationName, mutations);
26841
- }
26842
- }
26843
- /**
26844
- * Collect rules with no declarations and no nested rules.
26845
- */
26846
- buildEmptyRules() {
26847
- for (let i = 0; i < this.rules.length; i++) {
26848
- const rule = this.rules[i];
26849
- if (!rule) continue;
26850
- if (rule.declarations.length === 0 && rule.nestedRules.length === 0) {
26851
- this.emptyRules.push(rule);
26852
- }
26853
- }
26854
- }
26855
- /**
26856
- * Collect @keyframes with no effective keyframe declarations.
26857
- */
26858
- buildEmptyKeyframes() {
26859
- for (let i = 0; i < this.keyframes.length; i++) {
26860
- const kf = this.keyframes[i];
26861
- if (!kf) continue;
26862
- if (!kf.parsedParams.animationName) continue;
26863
- if (kf.rules.length === 0) {
26864
- this.emptyKeyframes.push(kf);
26865
- continue;
26866
- }
26867
- let hasDeclaration = false;
26868
- for (let j = 0; j < kf.rules.length; j++) {
26869
- const kfRule = kf.rules[j];
26870
- if (!kfRule) continue;
26871
- if (kfRule.declarations.length > 0) {
26872
- hasDeclaration = true;
26873
- break;
26874
- }
26875
- }
26876
- if (!hasDeclaration) this.emptyKeyframes.push(kf);
26877
- }
26878
- }
26879
- buildDeclarationDerivedIndexes() {
26880
- const HARDCODED_HEX = /^#[0-9a-f]{3,8}$/i;
26881
- for (let i = 0, len = this.declarations.length; i < len; i++) {
26882
- const d = this.declarations[i];
26883
- if (!d) continue;
26884
- const pv = d.parsedValue;
26885
- if (pv.colors.length > 0) this.colorDeclarations.push(d);
26886
- if (pv.hasCalc) this.calcDeclarations.push(d);
26887
- if (pv.hasVar) this.varDeclarations.push(d);
26888
- if (pv.hasUrl) this.urlDeclarations.push(d);
26889
- if (d.property.charCodeAt(0) === CHAR_HYPHEN && d.property.charCodeAt(1) !== CHAR_HYPHEN) {
26890
- this.vendorPrefixedDeclarations.push(d);
26891
- }
26892
- if (!pv.hasVar && pv.colors.length > 0) {
26893
- for (let j = 0, clen = pv.colors.length; j < clen; j++) {
26894
- const c = pv.colors[j];
26895
- if (!c) continue;
26896
- if (HARDCODED_HEX.test(c) || c.charCodeAt(0) === CHAR_R || c.charCodeAt(0) === CHAR_H) {
26897
- this.hardcodedColorDeclarations.push(d);
26898
- break;
26899
- }
26900
- }
26901
- }
26902
- }
26903
- }
26904
- buildSelectorDerivedIndexes() {
26905
- for (let i = 0, len = this.selectors.length; i < len; i++) {
26906
- const sel = this.selectors[i];
26907
- if (!sel) continue;
26908
- const parts = sel.parts;
26909
- const anchor = sel.anchor;
26910
- if (anchor.subjectTag === null) {
26911
- this.selectorsWithoutSubjectTag.push(sel);
26912
- } else {
26913
- const existingByTag = this.selectorsBySubjectTag.get(anchor.subjectTag);
26914
- if (existingByTag) existingByTag.push(sel);
26915
- else this.selectorsBySubjectTag.set(anchor.subjectTag, [sel]);
26916
- }
26917
- if (anchor.targetsCheckbox) this.selectorsTargetingCheckbox.push(sel);
26918
- if (anchor.targetsTableCell) this.selectorsTargetingTableCell.push(sel);
26919
- for (let j = 0, plen = parts.length; j < plen; j++) {
26920
- const part = parts[j];
26921
- if (!part) continue;
26922
- if (part.type === "class") {
26923
- const existing = this.classNameIndex.get(part.value);
26924
- if (existing) existing.push(sel);
26925
- else this.classNameIndex.set(part.value, [sel]);
26926
- }
26927
- }
26928
- const flags = sel.complexity._flags;
26929
- if (hasFlag(flags, SEL_HAS_ID)) {
26930
- this.idSelectors.push(sel);
26931
- for (let j = 0, plen = parts.length; j < plen; j++) {
26932
- const p = parts[j];
26933
- if (!p) continue;
26934
- const t = p.type;
26935
- if (t === "element" || t === "class" || t === "attribute") {
26936
- this.overqualifiedSelectors.push(sel);
26937
- break;
26938
- }
26939
- }
26940
- }
26941
- if (hasFlag(flags, SEL_HAS_ATTRIBUTE)) this.attributeSelectors.push(sel);
26942
- if (hasFlag(flags, SEL_HAS_UNIVERSAL)) this.universalSelectors.push(sel);
26943
- }
26944
- }
26945
26979
  buildLayoutPropertiesByClassToken() {
26946
26980
  const byClass = /* @__PURE__ */ new Map();
26947
26981
  for (let i = 0; i < this.selectors.length; i++) {
@@ -26972,7 +27006,7 @@ var CSSGraph = class {
26972
27006
  this.layoutPropertiesByClassToken.set(className, [...properties]);
26973
27007
  }
26974
27008
  }
26975
- buildFontFamilyUsageByRule() {
27009
+ buildFontIndexes() {
26976
27010
  const declarations = this.declarationsForProperties(...FONT_LAYOUT_PROPERTIES);
26977
27011
  for (let i = 0; i < declarations.length; i++) {
26978
27012
  const declaration = declarations[i];
@@ -26999,8 +27033,6 @@ var CSSGraph = class {
26999
27033
  }
27000
27034
  this.usedFontFamiliesByRule.set(rule.id, [...merged]);
27001
27035
  }
27002
- }
27003
- buildFontFaceDescriptorsByFamily() {
27004
27036
  const byFamily = /* @__PURE__ */ new Map();
27005
27037
  for (let i = 0; i < this.fontFaces.length; i++) {
27006
27038
  const fontFace = this.fontFaces[i];
@@ -27032,13 +27064,6 @@ var CSSGraph = class {
27032
27064
  this.fontFaceDescriptorsByFamily.set(family, descriptors);
27033
27065
  }
27034
27066
  }
27035
- buildRuleDerivedIndexes() {
27036
- for (let i = 0, len = this.rules.length; i < len; i++) {
27037
- const rule = this.rules[i];
27038
- if (!rule) continue;
27039
- if (rule.depth > 3) this.deepNestedRules.push(rule);
27040
- }
27041
- }
27042
27067
  buildUnusedIndexes() {
27043
27068
  for (const v of this.variables) {
27044
27069
  if (!hasFlag(v._flags, VAR_IS_USED)) this.unusedVariables.push(v);
@@ -27352,102 +27377,6 @@ function buildComplexity(combinators, hasId, hasUniversal, hasAttribute, hasPseu
27352
27377
  }
27353
27378
 
27354
27379
  // src/css/parser/selector.ts
27355
- function parseSelector(raw) {
27356
- let start = 0;
27357
- let end = raw.length;
27358
- while (start < end && isWhitespace(raw.charCodeAt(start))) start++;
27359
- while (end > start && isWhitespace(raw.charCodeAt(end - 1))) end--;
27360
- if (start === end) return [];
27361
- const input = start === 0 && end === raw.length ? raw : raw.substring(start, end);
27362
- const len = input.length;
27363
- const parts = [];
27364
- let pos = 0;
27365
- while (pos < len) {
27366
- const char = input.charCodeAt(pos);
27367
- if (isWhitespace(char) || isCombinator(char)) {
27368
- pos++;
27369
- continue;
27370
- }
27371
- if (char === CHAR_AMPERSAND) {
27372
- parts.push({ type: "nesting", value: "&", raw: "&" });
27373
- pos++;
27374
- continue;
27375
- }
27376
- if (char === CHAR_ASTERISK) {
27377
- parts.push({ type: "universal", value: "*", raw: "*" });
27378
- pos++;
27379
- continue;
27380
- }
27381
- if (char === CHAR_HASH) {
27382
- ID_STICKY.lastIndex = pos;
27383
- const match = ID_STICKY.exec(input);
27384
- if (match) {
27385
- const val = match[1];
27386
- if (!val) break;
27387
- parts.push({ type: "id", value: val, raw: match[0] });
27388
- pos = ID_STICKY.lastIndex;
27389
- continue;
27390
- }
27391
- }
27392
- if (char === CHAR_DOT) {
27393
- CLASS_STICKY.lastIndex = pos;
27394
- const match = CLASS_STICKY.exec(input);
27395
- if (match) {
27396
- const val = match[1];
27397
- if (!val) break;
27398
- parts.push({ type: "class", value: val, raw: match[0] });
27399
- pos = CLASS_STICKY.lastIndex;
27400
- continue;
27401
- }
27402
- }
27403
- if (char === CHAR_OPEN_BRACKET) {
27404
- ATTRIBUTE_STICKY.lastIndex = pos;
27405
- const match = ATTRIBUTE_STICKY.exec(input);
27406
- if (match) {
27407
- const val = match[1];
27408
- if (!val) break;
27409
- parts.push({ type: "attribute", value: val, raw: match[0] });
27410
- pos = ATTRIBUTE_STICKY.lastIndex;
27411
- continue;
27412
- }
27413
- }
27414
- if (char === CHAR_COLON) {
27415
- if (pos + 1 < len && input.charCodeAt(pos + 1) === CHAR_COLON) {
27416
- PSEUDO_ELEMENT_STICKY.lastIndex = pos;
27417
- const match2 = PSEUDO_ELEMENT_STICKY.exec(input);
27418
- if (match2) {
27419
- const val = match2[1];
27420
- if (!val) break;
27421
- parts.push({ type: "pseudo-element", value: val, raw: match2[0] });
27422
- pos = PSEUDO_ELEMENT_STICKY.lastIndex;
27423
- continue;
27424
- }
27425
- }
27426
- PSEUDO_CLASS_STICKY.lastIndex = pos;
27427
- const match = PSEUDO_CLASS_STICKY.exec(input);
27428
- if (match) {
27429
- const val = match[1];
27430
- if (!val) break;
27431
- parts.push({ type: "pseudo-class", value: val, raw: match[0] });
27432
- pos = PSEUDO_CLASS_STICKY.lastIndex;
27433
- continue;
27434
- }
27435
- }
27436
- if (isAlpha(char)) {
27437
- ELEMENT_STICKY.lastIndex = pos;
27438
- const match = ELEMENT_STICKY.exec(input);
27439
- if (match) {
27440
- const val = match[1];
27441
- if (!val) break;
27442
- parts.push({ type: "element", value: val, raw: match[0] });
27443
- pos = ELEMENT_STICKY.lastIndex;
27444
- continue;
27445
- }
27446
- }
27447
- pos++;
27448
- }
27449
- return parts;
27450
- }
27451
27380
  function parseSelectorList(selectorText) {
27452
27381
  const len = selectorText.length;
27453
27382
  if (len === 0) return [];
@@ -27535,18 +27464,80 @@ function extractPseudoClasses(selector) {
27535
27464
  }
27536
27465
  return pseudoClasses;
27537
27466
  }
27538
- function parseSelectorComplete(raw) {
27467
+ var CHAR_BACKSLASH = 92;
27468
+ function readCssIdentifier(input, start) {
27469
+ const length = input.length;
27470
+ let i = start;
27471
+ let hasEscape = false;
27472
+ while (i < length) {
27473
+ const code = input.charCodeAt(i);
27474
+ if (code === CHAR_BACKSLASH) {
27475
+ if (i + 1 >= length) break;
27476
+ hasEscape = true;
27477
+ i = skipCssEscape(input, i + 1);
27478
+ continue;
27479
+ }
27480
+ if (!isIdentChar(code)) break;
27481
+ i++;
27482
+ }
27483
+ if (i === start) return null;
27484
+ if (!hasEscape) {
27485
+ return { value: input.slice(start, i), end: i };
27486
+ }
27487
+ const parts = [];
27488
+ let j = start;
27489
+ while (j < i) {
27490
+ const code = input.charCodeAt(j);
27491
+ if (code !== CHAR_BACKSLASH) {
27492
+ parts.push(String.fromCharCode(code));
27493
+ j++;
27494
+ continue;
27495
+ }
27496
+ j++;
27497
+ if (j >= i) break;
27498
+ const first = input.charCodeAt(j);
27499
+ if (!isHexDigit(first)) {
27500
+ parts.push(String.fromCharCode(first));
27501
+ j++;
27502
+ continue;
27503
+ }
27504
+ const hexStart = j;
27505
+ const maxHex = Math.min(j + 6, i);
27506
+ while (j < maxHex && isHexDigit(input.charCodeAt(j))) j++;
27507
+ const codePoint = Number.parseInt(input.slice(hexStart, j), 16);
27508
+ if (codePoint > 0 && codePoint <= 1114111) parts.push(String.fromCodePoint(codePoint));
27509
+ if (j < i && isWhitespace(input.charCodeAt(j))) j++;
27510
+ }
27511
+ return { value: parts.join(""), end: i };
27512
+ }
27513
+ function skipCssEscape(input, afterBackslash) {
27514
+ const length = input.length;
27515
+ if (afterBackslash >= length) return afterBackslash;
27516
+ const first = input.charCodeAt(afterBackslash);
27517
+ if (!isHexDigit(first)) return afterBackslash + 1;
27518
+ let end = afterBackslash + 1;
27519
+ const maxHex = Math.min(afterBackslash + 6, length);
27520
+ while (end < maxHex && isHexDigit(input.charCodeAt(end))) end++;
27521
+ if (end < length && isWhitespace(input.charCodeAt(end))) end++;
27522
+ return end;
27523
+ }
27524
+ var ATTRIBUTE_EXISTS_RE = /^[-_a-zA-Z][-_a-zA-Z0-9]*$/;
27525
+ var ATTRIBUTE_CONSTRAINT_RE = /^([-_a-zA-Z][-_a-zA-Z0-9]*)\s*(=|~=|\|=|\^=|\$=|\*=)\s*(?:"([^"]*)"|'([^']*)'|([^\s"']+))(?:\s+([iIsS]))?$/;
27526
+ var MAX_PSEUDO_PARSE_DEPTH = 4;
27527
+ function parseSelectorComplete(raw, _depth) {
27539
27528
  let start = 0;
27540
27529
  let end = raw.length;
27541
27530
  while (start < end && isWhitespace(raw.charCodeAt(start))) start++;
27542
27531
  while (end > start && isWhitespace(raw.charCodeAt(end - 1))) end--;
27543
27532
  if (start === end) {
27544
- return { parts: [], combinators: [], specificity: [0, 0, 0, 0], complexity: MINIMAL_COMPLEXITY };
27533
+ return { parts: [], compounds: [], combinators: [], specificity: [0, 0, 0, 0], complexity: MINIMAL_COMPLEXITY };
27545
27534
  }
27546
27535
  const input = start === 0 && end === raw.length ? raw : raw.substring(start, end);
27547
27536
  const len = input.length;
27548
- const parts = [];
27537
+ const allParts = [];
27538
+ let currentCompoundParts = [];
27549
27539
  const combinators = [];
27540
+ const compounds = [];
27550
27541
  let ids = 0;
27551
27542
  let classes = 0;
27552
27543
  let elements = 0;
@@ -27556,10 +27547,11 @@ function parseSelectorComplete(raw) {
27556
27547
  let hasPseudoClassFlag = false;
27557
27548
  let hasPseudoElementFlag = false;
27558
27549
  let hasNesting = false;
27559
- const pseudoClasses = [];
27560
- const pseudoElements = [];
27550
+ const pseudoClassNames = [];
27551
+ const pseudoElementNames = [];
27561
27552
  let pos = 0;
27562
27553
  let inCompound = false;
27554
+ const depth = _depth ?? 0;
27563
27555
  while (pos < len) {
27564
27556
  const char = input.charCodeAt(pos);
27565
27557
  if (isWhitespace(char) || isCombinator(char)) {
@@ -27584,6 +27576,8 @@ function parseSelectorComplete(raw) {
27584
27576
  }
27585
27577
  }
27586
27578
  if (scanPos < len) {
27579
+ compounds.push(finalizeCompound(currentCompoundParts, depth));
27580
+ currentCompoundParts = [];
27587
27581
  combinators.push(sawCombinator ?? "descendant");
27588
27582
  inCompound = false;
27589
27583
  }
@@ -27595,13 +27589,17 @@ function parseSelectorComplete(raw) {
27595
27589
  }
27596
27590
  inCompound = true;
27597
27591
  if (char === CHAR_AMPERSAND) {
27598
- parts.push({ type: "nesting", value: "&", raw: "&" });
27592
+ const part = { type: "nesting", value: "&", raw: "&" };
27593
+ allParts.push(part);
27594
+ currentCompoundParts.push(part);
27599
27595
  hasNesting = true;
27600
27596
  pos++;
27601
27597
  continue;
27602
27598
  }
27603
27599
  if (char === CHAR_ASTERISK) {
27604
- parts.push({ type: "universal", value: "*", raw: "*" });
27600
+ const part = { type: "universal", value: "*", raw: "*" };
27601
+ allParts.push(part);
27602
+ currentCompoundParts.push(part);
27605
27603
  hasUniversal = true;
27606
27604
  pos++;
27607
27605
  continue;
@@ -27612,10 +27610,26 @@ function parseSelectorComplete(raw) {
27612
27610
  if (match) {
27613
27611
  const val = match[1];
27614
27612
  if (!val) break;
27615
- parts.push({ type: "id", value: val, raw: match[0] });
27613
+ const ident2 = readCssIdentifier(input, pos + 1);
27614
+ const idVal = ident2 ? ident2.value : val;
27615
+ const idRaw = ident2 ? input.slice(pos, ident2.end) : match[0];
27616
+ const idEnd = ident2 ? ident2.end : ID_STICKY.lastIndex;
27617
+ const part = { type: "id", value: idVal, raw: idRaw };
27618
+ allParts.push(part);
27619
+ currentCompoundParts.push(part);
27616
27620
  ids++;
27617
27621
  hasId = true;
27618
- pos = ID_STICKY.lastIndex;
27622
+ pos = idEnd;
27623
+ continue;
27624
+ }
27625
+ const ident = readCssIdentifier(input, pos + 1);
27626
+ if (ident) {
27627
+ const part = { type: "id", value: ident.value, raw: input.slice(pos, ident.end) };
27628
+ allParts.push(part);
27629
+ currentCompoundParts.push(part);
27630
+ ids++;
27631
+ hasId = true;
27632
+ pos = ident.end;
27619
27633
  continue;
27620
27634
  }
27621
27635
  }
@@ -27625,9 +27639,24 @@ function parseSelectorComplete(raw) {
27625
27639
  if (match) {
27626
27640
  const val = match[1];
27627
27641
  if (!val) break;
27628
- parts.push({ type: "class", value: val, raw: match[0] });
27642
+ const ident2 = readCssIdentifier(input, pos + 1);
27643
+ const clsVal = ident2 ? ident2.value : val;
27644
+ const clsRaw = ident2 ? input.slice(pos, ident2.end) : match[0];
27645
+ const clsEnd = ident2 ? ident2.end : CLASS_STICKY.lastIndex;
27646
+ const part = { type: "class", value: clsVal, raw: clsRaw };
27647
+ allParts.push(part);
27648
+ currentCompoundParts.push(part);
27649
+ classes++;
27650
+ pos = clsEnd;
27651
+ continue;
27652
+ }
27653
+ const ident = readCssIdentifier(input, pos + 1);
27654
+ if (ident) {
27655
+ const part = { type: "class", value: ident.value, raw: input.slice(pos, ident.end) };
27656
+ allParts.push(part);
27657
+ currentCompoundParts.push(part);
27629
27658
  classes++;
27630
- pos = CLASS_STICKY.lastIndex;
27659
+ pos = ident.end;
27631
27660
  continue;
27632
27661
  }
27633
27662
  }
@@ -27637,7 +27666,9 @@ function parseSelectorComplete(raw) {
27637
27666
  if (match) {
27638
27667
  const val = match[1];
27639
27668
  if (!val) break;
27640
- parts.push({ type: "attribute", value: val, raw: match[0] });
27669
+ const part = { type: "attribute", value: val, raw: match[0] };
27670
+ allParts.push(part);
27671
+ currentCompoundParts.push(part);
27641
27672
  classes++;
27642
27673
  hasAttribute = true;
27643
27674
  pos = ATTRIBUTE_STICKY.lastIndex;
@@ -27651,10 +27682,12 @@ function parseSelectorComplete(raw) {
27651
27682
  if (match) {
27652
27683
  const val = match[1];
27653
27684
  if (!val) break;
27654
- parts.push({ type: "pseudo-element", value: val, raw: match[0] });
27685
+ const part = { type: "pseudo-element", value: val, raw: match[0] };
27686
+ allParts.push(part);
27687
+ currentCompoundParts.push(part);
27655
27688
  elements++;
27656
27689
  hasPseudoElementFlag = true;
27657
- pseudoElements.push(val);
27690
+ pseudoElementNames.push(val);
27658
27691
  pos = PSEUDO_ELEMENT_STICKY.lastIndex;
27659
27692
  continue;
27660
27693
  }
@@ -27680,19 +27713,25 @@ function parseSelectorComplete(raw) {
27680
27713
  const fullMatch = input.substring(pseudoStart, argEnd);
27681
27714
  const argContent = input.substring(nameEnd + 1, argEnd - 1);
27682
27715
  if (pseudoName === "where") {
27683
- parts.push({ type: "pseudo-class", value: pseudoName, raw: fullMatch });
27716
+ const part2 = { type: "pseudo-class", value: pseudoName, raw: fullMatch };
27717
+ allParts.push(part2);
27718
+ currentCompoundParts.push(part2);
27684
27719
  hasPseudoClassFlag = true;
27685
- pseudoClasses.push(pseudoName);
27720
+ pseudoClassNames.push(pseudoName);
27686
27721
  } else if (pseudoName === "is" || pseudoName === "not" || pseudoName === "has") {
27687
- parts.push({ type: "pseudo-class", value: pseudoName, raw: fullMatch });
27722
+ const part2 = { type: "pseudo-class", value: pseudoName, raw: fullMatch };
27723
+ allParts.push(part2);
27724
+ currentCompoundParts.push(part2);
27688
27725
  hasPseudoClassFlag = true;
27689
- pseudoClasses.push(pseudoName);
27726
+ pseudoClassNames.push(pseudoName);
27690
27727
  const args = splitPseudoArgs(argContent);
27691
27728
  let maxIds = 0, maxClasses = 0, maxElements = 0;
27692
- for (const arg of args) {
27729
+ for (let ai = 0; ai < args.length; ai++) {
27730
+ const arg = args[ai];
27731
+ if (!arg) continue;
27693
27732
  const trimmed = arg.trim();
27694
27733
  if (trimmed) {
27695
- const { specificity: argSpec } = parseSelectorComplete(trimmed);
27734
+ const { specificity: argSpec } = parseSelectorComplete(trimmed, depth + 1);
27696
27735
  if (argSpec[1] > maxIds || argSpec[1] === maxIds && argSpec[2] > maxClasses || argSpec[1] === maxIds && argSpec[2] === maxClasses && argSpec[3] > maxElements) {
27697
27736
  maxIds = argSpec[1];
27698
27737
  maxClasses = argSpec[2];
@@ -27704,18 +27743,22 @@ function parseSelectorComplete(raw) {
27704
27743
  classes += maxClasses;
27705
27744
  elements += maxElements;
27706
27745
  } else {
27707
- parts.push({ type: "pseudo-class", value: pseudoName, raw: fullMatch });
27746
+ const part2 = { type: "pseudo-class", value: pseudoName, raw: fullMatch };
27747
+ allParts.push(part2);
27748
+ currentCompoundParts.push(part2);
27708
27749
  hasPseudoClassFlag = true;
27709
- pseudoClasses.push(pseudoName);
27750
+ pseudoClassNames.push(pseudoName);
27710
27751
  classes++;
27711
27752
  }
27712
27753
  pos = argEnd;
27713
27754
  continue;
27714
27755
  }
27715
27756
  const rawMatch = input.substring(pseudoStart, nameEnd);
27716
- parts.push({ type: "pseudo-class", value: pseudoName, raw: rawMatch });
27757
+ const part = { type: "pseudo-class", value: pseudoName, raw: rawMatch };
27758
+ allParts.push(part);
27759
+ currentCompoundParts.push(part);
27717
27760
  hasPseudoClassFlag = true;
27718
- pseudoClasses.push(pseudoName);
27761
+ pseudoClassNames.push(pseudoName);
27719
27762
  classes++;
27720
27763
  pos = nameEnd;
27721
27764
  continue;
@@ -27727,7 +27770,9 @@ function parseSelectorComplete(raw) {
27727
27770
  if (match) {
27728
27771
  const val = match[1];
27729
27772
  if (!val) break;
27730
- parts.push({ type: "element", value: val, raw: match[0] });
27773
+ const part = { type: "element", value: val, raw: match[0] };
27774
+ allParts.push(part);
27775
+ currentCompoundParts.push(part);
27731
27776
  elements++;
27732
27777
  pos = ELEMENT_STICKY.lastIndex;
27733
27778
  continue;
@@ -27735,6 +27780,9 @@ function parseSelectorComplete(raw) {
27735
27780
  }
27736
27781
  pos++;
27737
27782
  }
27783
+ if (currentCompoundParts.length > 0) {
27784
+ compounds.push(finalizeCompound(currentCompoundParts, depth));
27785
+ }
27738
27786
  const complexity = buildComplexity(
27739
27787
  combinators,
27740
27788
  hasId,
@@ -27743,16 +27791,157 @@ function parseSelectorComplete(raw) {
27743
27791
  hasPseudoClassFlag,
27744
27792
  hasPseudoElementFlag,
27745
27793
  hasNesting,
27746
- pseudoClasses,
27747
- pseudoElements
27794
+ pseudoClassNames,
27795
+ pseudoElementNames
27748
27796
  );
27749
27797
  return {
27750
- parts,
27798
+ parts: allParts,
27799
+ compounds,
27751
27800
  combinators,
27752
27801
  specificity: [0, ids, classes, elements],
27753
27802
  complexity
27754
27803
  };
27755
27804
  }
27805
+ function finalizeCompound(parts, depth) {
27806
+ let tagName = null;
27807
+ let idValue = null;
27808
+ const classes = [];
27809
+ const seenClasses = /* @__PURE__ */ new Set();
27810
+ const attributes = [];
27811
+ const pseudoClasses = [];
27812
+ for (let i = 0; i < parts.length; i++) {
27813
+ const part = parts[i];
27814
+ if (!part) continue;
27815
+ if (part.type === "element") {
27816
+ tagName = part.value.toLowerCase();
27817
+ } else if (part.type === "id") {
27818
+ idValue = part.value;
27819
+ } else if (part.type === "class") {
27820
+ if (!seenClasses.has(part.value)) {
27821
+ seenClasses.add(part.value);
27822
+ classes.push(part.value);
27823
+ }
27824
+ } else if (part.type === "attribute") {
27825
+ const constraint = parseAttributeConstraintFromRaw(part.value);
27826
+ if (constraint) attributes.push(constraint);
27827
+ } else if (part.type === "pseudo-class") {
27828
+ const parsed = parsePseudoToParsedConstraint(part.value, part.raw, depth);
27829
+ if (parsed) pseudoClasses.push(parsed);
27830
+ }
27831
+ }
27832
+ return { parts, tagName, idValue, classes, attributes, pseudoClasses };
27833
+ }
27834
+ function parseAttributeConstraintFromRaw(raw) {
27835
+ const trimmed = raw.trim();
27836
+ const constrained = ATTRIBUTE_CONSTRAINT_RE.exec(trimmed);
27837
+ if (constrained) {
27838
+ const operatorToken = constrained[2];
27839
+ if (!operatorToken) return null;
27840
+ const operator = mapAttrOperator(operatorToken);
27841
+ if (operator === null) return null;
27842
+ const value2 = constrained[3] ?? constrained[4] ?? constrained[5] ?? null;
27843
+ if (value2 === null) return null;
27844
+ const nameToken = constrained[1];
27845
+ if (!nameToken) return null;
27846
+ return {
27847
+ name: nameToken.toLowerCase(),
27848
+ operator,
27849
+ value: value2,
27850
+ caseInsensitive: (constrained[6] ?? "").toLowerCase() === "i"
27851
+ };
27852
+ }
27853
+ if (!ATTRIBUTE_EXISTS_RE.test(trimmed)) return null;
27854
+ return { name: trimmed.toLowerCase(), operator: "exists", value: null, caseInsensitive: false };
27855
+ }
27856
+ function mapAttrOperator(op) {
27857
+ if (op === "=") return "equals";
27858
+ if (op === "~=") return "includes-word";
27859
+ if (op === "|=") return "dash-prefix";
27860
+ if (op === "^=") return "prefix";
27861
+ if (op === "$=") return "suffix";
27862
+ if (op === "*=") return "contains";
27863
+ return null;
27864
+ }
27865
+ function parsePseudoToParsedConstraint(name, raw, depth) {
27866
+ const lowerName = name.toLowerCase();
27867
+ if (lowerName === "first-child") return { name: lowerName, raw, kind: 1 /* FirstChild */, nthPattern: null, nestedCompounds: null };
27868
+ if (lowerName === "last-child") return { name: lowerName, raw, kind: 2 /* LastChild */, nthPattern: null, nestedCompounds: null };
27869
+ if (lowerName === "only-child") return { name: lowerName, raw, kind: 3 /* OnlyChild */, nthPattern: null, nestedCompounds: null };
27870
+ const parenIdx = raw.indexOf("(");
27871
+ if (parenIdx === -1) {
27872
+ return { name: lowerName, raw, kind: 0 /* Simple */, nthPattern: null, nestedCompounds: null };
27873
+ }
27874
+ const argContent = raw.substring(parenIdx + 1, raw.length - 1);
27875
+ if (lowerName === "nth-child") {
27876
+ const pattern = parseNthPatternFromArg(argContent);
27877
+ return pattern ? { name: lowerName, raw, kind: 4 /* NthChild */, nthPattern: pattern, nestedCompounds: null } : null;
27878
+ }
27879
+ if (lowerName === "nth-last-child") {
27880
+ const pattern = parseNthPatternFromArg(argContent);
27881
+ return pattern ? { name: lowerName, raw, kind: 5 /* NthLastChild */, nthPattern: pattern, nestedCompounds: null } : null;
27882
+ }
27883
+ if (lowerName === "nth-of-type") {
27884
+ const pattern = parseNthPatternFromArg(argContent);
27885
+ return pattern ? { name: lowerName, raw, kind: 6 /* NthOfType */, nthPattern: pattern, nestedCompounds: null } : null;
27886
+ }
27887
+ if (lowerName === "nth-last-of-type") {
27888
+ const pattern = parseNthPatternFromArg(argContent);
27889
+ return pattern ? { name: lowerName, raw, kind: 7 /* NthLastOfType */, nthPattern: pattern, nestedCompounds: null } : null;
27890
+ }
27891
+ if (lowerName === "is" || lowerName === "where") {
27892
+ if (depth >= MAX_PSEUDO_PARSE_DEPTH) return { name: lowerName, raw, kind: 8 /* MatchesAny */, nthPattern: null, nestedCompounds: null };
27893
+ const nested = parseNestedCompoundGroups(argContent, depth + 1);
27894
+ return { name: lowerName, raw, kind: 8 /* MatchesAny */, nthPattern: null, nestedCompounds: nested };
27895
+ }
27896
+ if (lowerName === "not") {
27897
+ if (depth >= MAX_PSEUDO_PARSE_DEPTH) return { name: lowerName, raw, kind: 9 /* NoneOf */, nthPattern: null, nestedCompounds: null };
27898
+ const nested = parseNestedCompoundGroups(argContent, depth + 1);
27899
+ return { name: lowerName, raw, kind: 9 /* NoneOf */, nthPattern: null, nestedCompounds: nested };
27900
+ }
27901
+ return { name: lowerName, raw, kind: 0 /* Simple */, nthPattern: null, nestedCompounds: null };
27902
+ }
27903
+ function parseNestedCompoundGroups(argContent, depth) {
27904
+ const args = splitPseudoArgs(argContent);
27905
+ const groups = [];
27906
+ for (let i = 0; i < args.length; i++) {
27907
+ const arg = args[i];
27908
+ if (!arg) continue;
27909
+ const trimmed = arg.trim();
27910
+ if (!trimmed) continue;
27911
+ const result = parseSelectorComplete(trimmed, depth);
27912
+ if (result.compounds.length > 0) {
27913
+ groups.push(result.compounds.slice());
27914
+ }
27915
+ }
27916
+ return groups;
27917
+ }
27918
+ function parseNthPatternFromArg(raw) {
27919
+ const normalized = raw.trim().toLowerCase().replaceAll(" ", "");
27920
+ if (normalized.length === 0) return null;
27921
+ if (normalized === "odd") return { step: 2, offset: 1 };
27922
+ if (normalized === "even") return { step: 2, offset: 0 };
27923
+ const nIndex = normalized.indexOf("n");
27924
+ if (nIndex === -1) {
27925
+ const value2 = Number.parseInt(normalized, 10);
27926
+ if (Number.isNaN(value2)) return null;
27927
+ return { step: 0, offset: value2 };
27928
+ }
27929
+ const stepPart = normalized.slice(0, nIndex);
27930
+ const offsetPart = normalized.slice(nIndex + 1);
27931
+ let step;
27932
+ if (stepPart.length === 0 || stepPart === "+") step = 1;
27933
+ else if (stepPart === "-") step = -1;
27934
+ else {
27935
+ step = Number.parseInt(stepPart, 10);
27936
+ if (Number.isNaN(step)) return null;
27937
+ }
27938
+ let offset = 0;
27939
+ if (offsetPart.length > 0) {
27940
+ offset = Number.parseInt(offsetPart, 10);
27941
+ if (Number.isNaN(offset)) return null;
27942
+ }
27943
+ return { step, offset };
27944
+ }
27756
27945
  function splitPseudoArgs(content) {
27757
27946
  const result = [];
27758
27947
  let start = 0;
@@ -28101,8 +28290,6 @@ function extractVarReferences(value2) {
28101
28290
 
28102
28291
  // src/css/phases/ast.ts
28103
28292
  var CSS_IDENT = /^[-_a-zA-Z][-_a-zA-Z0-9]*$/;
28104
- var ATTRIBUTE_EXISTS_RE = /^[-_a-zA-Z][-_a-zA-Z0-9]*$/;
28105
- var ATTRIBUTE_CONSTRAINT_RE = /^([-_a-zA-Z][-_a-zA-Z0-9]*)\s*(=|~=|\|=|\^=|\$=|\*=)\s*(?:"([^"]*)"|'([^']*)'|([^\s"']+))(?:\s+([iIsS]))?$/;
28106
28293
  var ROOT_CONTEXT = {
28107
28294
  parentRule: null,
28108
28295
  parentAtRule: null,
@@ -28569,142 +28756,6 @@ function getRuleBlockOffsets(file, startOffset, endOffset) {
28569
28756
  blockEndOffset: close
28570
28757
  };
28571
28758
  }
28572
- function extractSubjectCompound(raw) {
28573
- const len = raw.length;
28574
- if (len === 0) return "";
28575
- let end = len - 1;
28576
- while (end >= 0 && isWhitespace(raw.charCodeAt(end))) end--;
28577
- if (end < 0) return "";
28578
- let parenDepth = 0;
28579
- let bracketDepth = 0;
28580
- for (let i = end; i >= 0; i--) {
28581
- const code = raw.charCodeAt(i);
28582
- if (code === CHAR_CLOSE_PAREN) {
28583
- parenDepth++;
28584
- continue;
28585
- }
28586
- if (code === CHAR_OPEN_PAREN) {
28587
- if (parenDepth > 0) parenDepth--;
28588
- continue;
28589
- }
28590
- if (code === CHAR_CLOSE_BRACKET) {
28591
- bracketDepth++;
28592
- continue;
28593
- }
28594
- if (code === CHAR_OPEN_BRACKET) {
28595
- if (bracketDepth > 0) bracketDepth--;
28596
- continue;
28597
- }
28598
- if (parenDepth > 0 || bracketDepth > 0) continue;
28599
- if (code === CHAR_GT || code === CHAR_PLUS || code === CHAR_TILDE) {
28600
- return raw.slice(i + 1, end + 1).trim();
28601
- }
28602
- if (!isWhitespace(code)) continue;
28603
- return raw.slice(i + 1, end + 1).trim();
28604
- }
28605
- return raw.slice(0, end + 1).trim();
28606
- }
28607
- function parseAnchorAttributes(parts) {
28608
- const out = [];
28609
- for (let i = 0; i < parts.length; i++) {
28610
- const part = parts[i];
28611
- if (!part) continue;
28612
- if (part.type !== "attribute") continue;
28613
- const trimmed = part.value.trim();
28614
- const constrained = ATTRIBUTE_CONSTRAINT_RE.exec(trimmed);
28615
- if (constrained) {
28616
- const opToken = constrained[2];
28617
- if (!opToken) continue;
28618
- const operator = mapAttributeOperatorFromToken(opToken);
28619
- if (operator === null) continue;
28620
- const value2 = constrained[3] ?? constrained[4] ?? constrained[5] ?? null;
28621
- if (value2 === null) continue;
28622
- const attrName = constrained[1];
28623
- if (!attrName) continue;
28624
- out.push({
28625
- name: attrName.toLowerCase(),
28626
- operator,
28627
- value: value2,
28628
- caseInsensitive: (constrained[6] ?? "").toLowerCase() === "i"
28629
- });
28630
- continue;
28631
- }
28632
- if (!ATTRIBUTE_EXISTS_RE.test(trimmed)) continue;
28633
- out.push({
28634
- name: trimmed.toLowerCase(),
28635
- operator: "exists",
28636
- value: null,
28637
- caseInsensitive: false
28638
- });
28639
- }
28640
- return out;
28641
- }
28642
- function mapAttributeOperatorFromToken(operator) {
28643
- if (operator === "=") return "equals";
28644
- if (operator === "~=") return "includes-word";
28645
- if (operator === "|=") return "dash-prefix";
28646
- if (operator === "^=") return "prefix";
28647
- if (operator === "$=") return "suffix";
28648
- if (operator === "*=") return "contains";
28649
- return null;
28650
- }
28651
- function buildSelectorAnchor(raw, parts, combinators) {
28652
- const subjectCompound = extractSubjectCompound(raw);
28653
- const subjectParts = parseSelector(subjectCompound);
28654
- let subjectTag = null;
28655
- const classes = [];
28656
- const seenClasses = /* @__PURE__ */ new Set();
28657
- for (let i = 0; i < subjectParts.length; i++) {
28658
- const part = subjectParts[i];
28659
- if (!part) continue;
28660
- if (part.type === "element") {
28661
- subjectTag = part.value.toLowerCase();
28662
- continue;
28663
- }
28664
- if (part.type !== "class") continue;
28665
- const cls = part.value;
28666
- if (seenClasses.has(cls)) continue;
28667
- seenClasses.add(cls);
28668
- classes.push(cls);
28669
- }
28670
- const attributes = parseAnchorAttributes(subjectParts);
28671
- const includesDescendantCombinator = combinators.includes("descendant");
28672
- let includesPseudoSelector = false;
28673
- let includesNesting = false;
28674
- for (let i = 0; i < parts.length; i++) {
28675
- const part = parts[i];
28676
- if (!part) continue;
28677
- if (part.type === "pseudo-class" || part.type === "pseudo-element") {
28678
- includesPseudoSelector = true;
28679
- continue;
28680
- }
28681
- if (part.type === "nesting") includesNesting = true;
28682
- }
28683
- let hasCheckboxAttribute = false;
28684
- for (let i = 0; i < attributes.length; i++) {
28685
- const a = attributes[i];
28686
- if (!a) continue;
28687
- if (a.name !== "type") continue;
28688
- if (a.operator !== "equals") continue;
28689
- if (a.value === null) continue;
28690
- const normalized = a.caseInsensitive ? a.value.toLowerCase() : a.value;
28691
- if (normalized !== "checkbox") continue;
28692
- hasCheckboxAttribute = true;
28693
- break;
28694
- }
28695
- const targetsCheckbox = (subjectTag === "input" || subjectTag === null) && hasCheckboxAttribute;
28696
- const targetsTableCell = subjectTag === "td" || subjectTag === "th";
28697
- return {
28698
- subjectTag,
28699
- classes,
28700
- attributes,
28701
- includesDescendantCombinator,
28702
- includesPseudoSelector,
28703
- dynamic: includesPseudoSelector || includesNesting,
28704
- targetsCheckbox,
28705
- targetsTableCell
28706
- };
28707
- }
28708
28759
  function createRuleEntity(graph, node, file, context) {
28709
28760
  const { parentRule, parentAtRule, containingMedia, containingLayer, depth } = context;
28710
28761
  const id = graph.nextRuleId();
@@ -28751,9 +28802,55 @@ function createRuleEntity(graph, node, file, context) {
28751
28802
  }
28752
28803
  function createSelectorEntity(graph, raw, rule) {
28753
28804
  const id = graph.nextSelectorId();
28754
- const { parts, specificity, complexity } = parseSelectorComplete(raw);
28805
+ const { parts, compounds, combinators, specificity, complexity } = parseSelectorComplete(raw);
28755
28806
  const specificityScore = specificityToScore(specificity);
28756
- const anchor = buildSelectorAnchor(raw, parts, complexity.combinators);
28807
+ const kinds = rule.elementKinds;
28808
+ for (let k = 0; k < parts.length; k++) {
28809
+ const part = parts[k];
28810
+ if (part) classifyPart(part, kinds);
28811
+ }
28812
+ const subject = compounds.length > 0 ? compounds[compounds.length - 1] : null;
28813
+ let includesPseudoSelector = false;
28814
+ let includesNesting = false;
28815
+ for (let i = 0; i < parts.length; i++) {
28816
+ const part = parts[i];
28817
+ if (!part) continue;
28818
+ if (part.type === "pseudo-class" || part.type === "pseudo-element") {
28819
+ includesPseudoSelector = true;
28820
+ continue;
28821
+ }
28822
+ if (part.type === "nesting") includesNesting = true;
28823
+ }
28824
+ const subjectTag = subject?.tagName ?? null;
28825
+ const subjectIdValue = subject?.idValue ?? null;
28826
+ const subjectClasses = subject?.classes ?? [];
28827
+ const subjectAttributes = subject?.attributes ?? [];
28828
+ const includesDescendantCombinator = combinators.includes("descendant");
28829
+ let hasCheckboxAttribute = false;
28830
+ for (let i = 0; i < subjectAttributes.length; i++) {
28831
+ const a = subjectAttributes[i];
28832
+ if (!a) continue;
28833
+ if (a.name !== "type") continue;
28834
+ if (a.operator !== "equals") continue;
28835
+ if (a.value === null) continue;
28836
+ const normalized = a.caseInsensitive ? a.value.toLowerCase() : a.value;
28837
+ if (normalized !== "checkbox") continue;
28838
+ hasCheckboxAttribute = true;
28839
+ break;
28840
+ }
28841
+ const targetsCheckbox = (subjectTag === "input" || subjectTag === null) && hasCheckboxAttribute;
28842
+ const targetsTableCell = subjectTag === "td" || subjectTag === "th";
28843
+ const anchor = {
28844
+ subjectTag,
28845
+ idValue: subjectIdValue,
28846
+ classes: subjectClasses,
28847
+ attributes: subjectAttributes,
28848
+ includesDescendantCombinator,
28849
+ includesPseudoSelector,
28850
+ dynamic: includesPseudoSelector || includesNesting,
28851
+ targetsCheckbox,
28852
+ targetsTableCell
28853
+ };
28757
28854
  return {
28758
28855
  id,
28759
28856
  raw,
@@ -28761,6 +28858,8 @@ function createSelectorEntity(graph, raw, rule) {
28761
28858
  specificity,
28762
28859
  specificityScore,
28763
28860
  complexity,
28861
+ compounds,
28862
+ combinators,
28764
28863
  parts: parts.length > 0 ? parts : [],
28765
28864
  anchor,
28766
28865
  overrides: [],
@@ -30761,23 +30860,44 @@ function collectCSSScopeBySolidFile(solids, css, moduleResolver) {
30761
30860
  if (!imp) continue;
30762
30861
  if (imp.isTypeOnly) continue;
30763
30862
  const resolvedCssPath = resolver.resolveCss(solid.file, imp.source);
30764
- if (resolvedCssPath === null) continue;
30765
- const transitiveScope = getOrCollectTransitiveScope(
30766
- resolvedCssPath,
30767
- resolver,
30768
- cssFilesByNormalizedPath,
30769
- transitiveScopeByEntryPath
30770
- );
30771
- for (let k = 0; k < transitiveScope.length; k++) {
30772
- const ts137 = transitiveScope[k];
30773
- if (!ts137) continue;
30774
- scope.add(ts137);
30863
+ if (resolvedCssPath !== null) {
30864
+ const transitiveScope = getOrCollectTransitiveScope(
30865
+ resolvedCssPath,
30866
+ resolver,
30867
+ cssFilesByNormalizedPath,
30868
+ transitiveScopeByEntryPath
30869
+ );
30870
+ for (let k = 0; k < transitiveScope.length; k++) {
30871
+ const ts137 = transitiveScope[k];
30872
+ if (!ts137) continue;
30873
+ scope.add(ts137);
30874
+ }
30875
+ if (imp.specifiers.length === 0) {
30876
+ for (let k = 0; k < transitiveScope.length; k++) {
30877
+ const ts137 = transitiveScope[k];
30878
+ if (!ts137) continue;
30879
+ globalSideEffectScope.add(ts137);
30880
+ }
30881
+ }
30775
30882
  }
30776
- if (imp.specifiers.length !== 0) continue;
30777
- for (let k = 0; k < transitiveScope.length; k++) {
30778
- const ts137 = transitiveScope[k];
30779
- if (!ts137) continue;
30780
- globalSideEffectScope.add(ts137);
30883
+ if (imp.specifiers.length !== 0) {
30884
+ const resolvedSolidPath = resolver.resolveSolid(solid.file, imp.source);
30885
+ if (resolvedSolidPath !== null) {
30886
+ const componentCssPath = resolveColocatedCss(resolvedSolidPath, cssFilesByNormalizedPath);
30887
+ if (componentCssPath !== null) {
30888
+ const componentCssScope = getOrCollectTransitiveScope(
30889
+ componentCssPath,
30890
+ resolver,
30891
+ cssFilesByNormalizedPath,
30892
+ transitiveScopeByEntryPath
30893
+ );
30894
+ for (let k = 0; k < componentCssScope.length; k++) {
30895
+ const cs = componentCssScope[k];
30896
+ if (!cs) continue;
30897
+ scope.add(cs);
30898
+ }
30899
+ }
30900
+ }
30781
30901
  }
30782
30902
  }
30783
30903
  localScopeBySolidFile.set(solid.file, scope);
@@ -30861,6 +30981,8 @@ var layoutSignalNames = [
30861
30981
  "min-width",
30862
30982
  "min-block-size",
30863
30983
  "min-height",
30984
+ "max-width",
30985
+ "max-height",
30864
30986
  "aspect-ratio",
30865
30987
  "vertical-align",
30866
30988
  "display",
@@ -30879,6 +31001,7 @@ var layoutSignalNames = [
30879
31001
  "place-items",
30880
31002
  "place-self",
30881
31003
  "flex-direction",
31004
+ "flex-basis",
30882
31005
  "grid-auto-flow",
30883
31006
  "appearance",
30884
31007
  "box-sizing",
@@ -31147,6 +31270,7 @@ import { readFileSync as readFileSync4 } from "fs";
31147
31270
  import { resolve as resolve4 } from "path";
31148
31271
  import ts123 from "typescript";
31149
31272
  var EMPTY_ATTRIBUTES = /* @__PURE__ */ new Map();
31273
+ var EMPTY_PROP_BINDINGS = /* @__PURE__ */ new Map();
31150
31274
  var TRANSPARENT_SOLID_PRIMITIVES = /* @__PURE__ */ new Set([
31151
31275
  "For",
31152
31276
  "Index",
@@ -31215,9 +31339,10 @@ function createLayoutComponentHostResolver(solids, moduleResolver, logger = noop
31215
31339
  const staticAttributes = innerHost !== null ? mergeStaticAttributes(entry.staticAttributes, innerHost.descriptor.staticAttributes) : entry.staticAttributes;
31216
31340
  const staticClassTokens = innerHost !== null ? mergeStaticClassTokens(entry.staticClassTokens, innerHost.descriptor.staticClassTokens) : entry.staticClassTokens;
31217
31341
  const forwardsChildren = entry.forwardsChildren || innerHost !== null && innerHost.descriptor.forwardsChildren;
31342
+ const attributePropBindings = innerHost !== null ? mergePropBindings(entry.attributePropBindings, innerHost.descriptor.attributePropBindings) : entry.attributePropBindings;
31218
31343
  if (logger.isLevelEnabled(Level.Trace)) logger.trace(`[component-host] resolved: tagName=${tagName}, attrs=[${[...staticAttributes.keys()]}], classes=[${staticClassTokens}]`);
31219
31344
  return {
31220
- descriptor: { tagName, staticAttributes, staticClassTokens, forwardsChildren },
31345
+ descriptor: { tagName, staticAttributes, staticClassTokens, forwardsChildren, attributePropBindings },
31221
31346
  hostElementRef: innerHost?.hostElementRef ?? null
31222
31347
  };
31223
31348
  }
@@ -31644,7 +31769,8 @@ function resolveHostEntryFromJSXElement(graph, node) {
31644
31769
  tagName: element.tagName,
31645
31770
  staticAttributes: collectStaticAttributes(element),
31646
31771
  staticClassTokens: getStaticClassTokensForElementEntity(graph, element),
31647
- forwardsChildren: detectChildrenForwarding(element)
31772
+ forwardsChildren: detectChildrenForwarding(element),
31773
+ attributePropBindings: collectAttributePropBindings(element)
31648
31774
  },
31649
31775
  hostElementRef: { solid: graph, element }
31650
31776
  };
@@ -31659,7 +31785,8 @@ function resolveHostEntryFromJSXElement(graph, node) {
31659
31785
  filePath: graph.file,
31660
31786
  staticAttributes: collectStaticAttributes(element),
31661
31787
  staticClassTokens: getStaticClassTokensForElementEntity(graph, element),
31662
- forwardsChildren: detectChildrenForwarding(element)
31788
+ forwardsChildren: detectChildrenForwarding(element),
31789
+ attributePropBindings: collectAttributePropBindings(element)
31663
31790
  };
31664
31791
  }
31665
31792
  function isContextProviderTag(tag) {
@@ -31847,6 +31974,41 @@ function collectStaticAttributes(element) {
31847
31974
  if (out === null) return EMPTY_ATTRIBUTES;
31848
31975
  return out;
31849
31976
  }
31977
+ function extractPropMemberName(node) {
31978
+ if (!ts123.isJsxExpression(node)) return null;
31979
+ const expression = node.expression;
31980
+ if (!expression) return null;
31981
+ return extractMemberNameFromExpression(expression);
31982
+ }
31983
+ function extractMemberNameFromExpression(expression) {
31984
+ if (ts123.isPropertyAccessExpression(expression)) {
31985
+ return expression.name.text;
31986
+ }
31987
+ if (ts123.isCallExpression(expression) && ts123.isPropertyAccessExpression(expression.expression) && expression.arguments.length === 0) {
31988
+ return expression.expression.name.text;
31989
+ }
31990
+ if (ts123.isBinaryExpression(expression) && expression.operatorToken.kind === ts123.SyntaxKind.QuestionQuestionToken) {
31991
+ return extractMemberNameFromExpression(expression.left);
31992
+ }
31993
+ return null;
31994
+ }
31995
+ function collectAttributePropBindings(element) {
31996
+ let out = null;
31997
+ for (let i = 0; i < element.attributes.length; i++) {
31998
+ const attribute = element.attributes[i];
31999
+ if (!attribute) continue;
32000
+ if (!ts123.isJsxAttribute(attribute.node)) continue;
32001
+ if (!attribute.name) continue;
32002
+ if (attribute.valueNode === null) continue;
32003
+ const propName = extractPropMemberName(attribute.valueNode);
32004
+ if (propName === null) continue;
32005
+ const attrName = attribute.name.toLowerCase();
32006
+ if (out === null) out = /* @__PURE__ */ new Map();
32007
+ out.set(attrName, propName);
32008
+ }
32009
+ if (out === null) return EMPTY_PROP_BINDINGS;
32010
+ return out;
32011
+ }
31850
32012
  function collectTopLevelVariableInitializers(graph) {
31851
32013
  const out = /* @__PURE__ */ new Map();
31852
32014
  for (let i = 0; i < graph.variables.length; i++) {
@@ -31972,7 +32134,12 @@ function areHostDescriptorsEqual(left, right) {
31972
32134
  if (left.tagName !== right.tagName) return false;
31973
32135
  if (left.forwardsChildren !== right.forwardsChildren) return false;
31974
32136
  if (!areStringListsEqual(left.staticClassTokens, right.staticClassTokens)) return false;
31975
- return areAttributeMapsEqual(left.staticAttributes, right.staticAttributes);
32137
+ if (!areAttributeMapsEqual(left.staticAttributes, right.staticAttributes)) return false;
32138
+ if (left.attributePropBindings.size !== right.attributePropBindings.size) return false;
32139
+ for (const [key, value2] of left.attributePropBindings) {
32140
+ if (right.attributePropBindings.get(key) !== value2) return false;
32141
+ }
32142
+ return true;
31976
32143
  }
31977
32144
  function areComponentHostEntriesEqual(left, right) {
31978
32145
  if (left.resolution !== right.resolution) return false;
@@ -32015,6 +32182,18 @@ function mergeStaticAttributes(outer, inner) {
32015
32182
  }
32016
32183
  return out;
32017
32184
  }
32185
+ function mergePropBindings(outer, inner) {
32186
+ if (inner.size === 0) return outer;
32187
+ if (outer.size === 0) return inner;
32188
+ const out = /* @__PURE__ */ new Map();
32189
+ for (const [name, value2] of inner) {
32190
+ out.set(name, value2);
32191
+ }
32192
+ for (const [name, value2] of outer) {
32193
+ out.set(name, value2);
32194
+ }
32195
+ return out;
32196
+ }
32018
32197
  var HTML_TAG_NAMES = /* @__PURE__ */ new Set([
32019
32198
  "a",
32020
32199
  "abbr",
@@ -32220,80 +32399,6 @@ function parseSignedPxValue(raw) {
32220
32399
  return parsePxValue(trimmed);
32221
32400
  }
32222
32401
 
32223
- // src/cross-file/layout/shorthand-expansion.ts
32224
- var QUAD_EXPANSIONS = /* @__PURE__ */ new Map([
32225
- ["padding", ["padding-top", "padding-right", "padding-bottom", "padding-left"]],
32226
- ["border-width", ["border-top-width", "border-right-width", "border-bottom-width", "border-left-width"]],
32227
- ["margin", ["margin-top", "margin-right", "margin-bottom", "margin-left"]],
32228
- ["inset", ["top", "right", "bottom", "left"]]
32229
- ]);
32230
- var BLOCK_EXPANSIONS = /* @__PURE__ */ new Map([
32231
- ["margin-block", ["margin-top", "margin-bottom"]],
32232
- ["padding-block", ["padding-top", "padding-bottom"]],
32233
- ["inset-block", ["inset-block-start", "inset-block-end"]]
32234
- ]);
32235
- function expandShorthand(property, value2) {
32236
- const quadTarget = QUAD_EXPANSIONS.get(property);
32237
- if (quadTarget !== void 0) {
32238
- const parsed = parseQuadShorthand(value2);
32239
- if (parsed === null) return null;
32240
- return [
32241
- { name: quadTarget[0], value: parsed.top },
32242
- { name: quadTarget[1], value: parsed.right },
32243
- { name: quadTarget[2], value: parsed.bottom },
32244
- { name: quadTarget[3], value: parsed.left }
32245
- ];
32246
- }
32247
- const blockTarget = BLOCK_EXPANSIONS.get(property);
32248
- if (blockTarget !== void 0) {
32249
- const parsed = parseBlockShorthand(value2);
32250
- if (parsed === null) return null;
32251
- return [
32252
- { name: blockTarget[0], value: parsed.start },
32253
- { name: blockTarget[1], value: parsed.end }
32254
- ];
32255
- }
32256
- if (property === "flex-flow") {
32257
- return expandFlexFlow(value2);
32258
- }
32259
- return void 0;
32260
- }
32261
- var FLEX_DIRECTION_VALUES = /* @__PURE__ */ new Set(["row", "row-reverse", "column", "column-reverse"]);
32262
- function expandFlexFlow(value2) {
32263
- const tokens = splitWhitespaceTokens(value2.trim().toLowerCase());
32264
- if (tokens.length === 0) return null;
32265
- if (tokens.length > 2) return null;
32266
- let direction = null;
32267
- let wrap = null;
32268
- for (let i = 0; i < tokens.length; i++) {
32269
- const token = tokens[i];
32270
- if (!token) continue;
32271
- if (FLEX_DIRECTION_VALUES.has(token)) {
32272
- if (direction !== null) return null;
32273
- direction = token;
32274
- } else {
32275
- if (wrap !== null) return null;
32276
- wrap = token;
32277
- }
32278
- }
32279
- const out = [];
32280
- if (direction !== null) {
32281
- out.push({ name: "flex-direction", value: direction });
32282
- }
32283
- if (wrap !== null) {
32284
- out.push({ name: "flex-wrap", value: wrap });
32285
- }
32286
- return out.length > 0 ? out : null;
32287
- }
32288
- function getShorthandLonghandNames(property) {
32289
- const quad = QUAD_EXPANSIONS.get(property);
32290
- if (quad !== void 0) return [...quad];
32291
- const block = BLOCK_EXPANSIONS.get(property);
32292
- if (block !== void 0) return [...block];
32293
- if (property === "flex-flow") return ["flex-direction", "flex-wrap"];
32294
- return null;
32295
- }
32296
-
32297
32402
  // src/cross-file/layout/signal-normalization.ts
32298
32403
  var MONITORED_SIGNAL_SET = new Set(layoutSignalNames);
32299
32404
  var MONITORED_SIGNAL_NAME_MAP = new Map(
@@ -32304,6 +32409,7 @@ var MONITORED_SHORTHAND_SET = /* @__PURE__ */ new Set([
32304
32409
  "border-width",
32305
32410
  "margin-block",
32306
32411
  "padding-block",
32412
+ "padding-inline",
32307
32413
  "inset-block",
32308
32414
  "flex-flow"
32309
32415
  ]);
@@ -32316,6 +32422,9 @@ var LENGTH_SIGNAL_SET = /* @__PURE__ */ new Set([
32316
32422
  "min-width",
32317
32423
  "min-block-size",
32318
32424
  "min-height",
32425
+ "max-width",
32426
+ "max-height",
32427
+ "flex-basis",
32319
32428
  "top",
32320
32429
  "bottom",
32321
32430
  "margin-top",
@@ -32369,11 +32478,11 @@ function isMonitoredSignal(property) {
32369
32478
  }
32370
32479
  function isControlTag(tag) {
32371
32480
  if (tag === null) return false;
32372
- return CONTROL_ELEMENT_TAGS.has(tag.toLowerCase());
32481
+ return CONTROL_ELEMENT_TAGS.has(tag);
32373
32482
  }
32374
32483
  function isReplacedTag(tag) {
32375
32484
  if (tag === null) return false;
32376
- return REPLACED_ELEMENT_TAGS.has(tag.toLowerCase());
32485
+ return REPLACED_ELEMENT_TAGS.has(tag);
32377
32486
  }
32378
32487
  function normalizeSignalMapWithCounts(values) {
32379
32488
  const out = /* @__PURE__ */ new Map();
@@ -32388,16 +32497,12 @@ function normalizeSignalMapWithCounts(values) {
32388
32497
  null
32389
32498
  );
32390
32499
  out.set("font-size", parsedFontSize);
32391
- if (parsedFontSize.kind === "known" && parsedFontSize.guard.kind === 0 /* Unconditional */) {
32500
+ if (parsedFontSize.kind === 0 /* Known */ && parsedFontSize.guard.kind === 0 /* Unconditional */) {
32392
32501
  fontSizePx = parsedFontSize.px;
32393
32502
  }
32394
32503
  }
32395
32504
  for (const [property, declaration] of values) {
32396
32505
  if (property === "font-size") continue;
32397
- if (MONITORED_SHORTHAND_SET.has(property)) {
32398
- applyExpandedShorthand(out, property, declaration, fontSizePx);
32399
- continue;
32400
- }
32401
32506
  const name = toMonitoredSignalName(property);
32402
32507
  if (!name) continue;
32403
32508
  const normalized = normalizeSignal(
@@ -32417,7 +32522,7 @@ function normalizeSignalMapWithCounts(values) {
32417
32522
  conditionalSignalCount++;
32418
32523
  continue;
32419
32524
  }
32420
- if (value2.kind === "known") {
32525
+ if (value2.kind === 0 /* Known */) {
32421
32526
  knownSignalCount++;
32422
32527
  continue;
32423
32528
  }
@@ -32430,30 +32535,6 @@ function normalizeSignalMapWithCounts(values) {
32430
32535
  conditionalSignalCount
32431
32536
  };
32432
32537
  }
32433
- function applyExpandedShorthand(out, property, declaration, fontSizePx) {
32434
- const expanded = expandShorthand(property, declaration.value);
32435
- if (expanded === null) {
32436
- const reason = `${property} value is not statically parseable`;
32437
- const longhandNames = getShorthandLonghandNames(property);
32438
- if (longhandNames === null) return;
32439
- for (let i = 0; i < longhandNames.length; i++) {
32440
- const longhand = longhandNames[i];
32441
- if (!longhand) continue;
32442
- const name = MONITORED_SIGNAL_NAME_MAP.get(longhand);
32443
- if (name === void 0) continue;
32444
- out.set(name, createUnknown(name, declaration.source, declaration.guardProvenance, reason));
32445
- }
32446
- return;
32447
- }
32448
- if (expanded === void 0) return;
32449
- for (let i = 0; i < expanded.length; i++) {
32450
- const entry = expanded[i];
32451
- if (!entry) continue;
32452
- const name = MONITORED_SIGNAL_NAME_MAP.get(entry.name);
32453
- if (name === void 0) continue;
32454
- out.set(name, normalizeSignal(name, entry.value, declaration.source, declaration.guardProvenance, fontSizePx));
32455
- }
32456
- }
32457
32538
  function toMonitoredSignalName(property) {
32458
32539
  return MONITORED_SIGNAL_NAME_MAP.get(property) ?? null;
32459
32540
  }
@@ -32494,13 +32575,13 @@ function parseAspectRatio(name, raw, source, guard) {
32494
32575
  if (!Number.isFinite(left) || !Number.isFinite(right) || left <= 0 || right <= 0) {
32495
32576
  return createUnknown(name, source, guard, "aspect-ratio ratio is invalid");
32496
32577
  }
32497
- return createKnown(name, raw, source, guard, null, 1 /* Unitless */, "exact");
32578
+ return createKnown(name, trimmed, source, guard, null, 1 /* Unitless */, 0 /* Exact */);
32498
32579
  }
32499
32580
  const ratio = Number(trimmed);
32500
32581
  if (!Number.isFinite(ratio) || ratio <= 0) {
32501
32582
  return createUnknown(name, source, guard, "aspect-ratio is not statically parseable");
32502
32583
  }
32503
- return createKnown(name, raw, source, guard, null, 1 /* Unitless */, "exact");
32584
+ return createKnown(name, trimmed, source, guard, null, 1 /* Unitless */, 0 /* Exact */);
32504
32585
  }
32505
32586
  function parseContainIntrinsicSize(name, raw, source, guard) {
32506
32587
  const trimmed = raw.trim().toLowerCase();
@@ -32518,18 +32599,19 @@ function parseContainIntrinsicSize(name, raw, source, guard) {
32518
32599
  const part = parts[i];
32519
32600
  if (!part) continue;
32520
32601
  const px = parseSignedPxValue(part);
32521
- if (px !== null) return createKnown(name, raw, source, guard, px, 0 /* Px */, "exact");
32602
+ if (px !== null) return createKnown(name, trimmed, source, guard, px, 0 /* Px */, 0 /* Exact */);
32522
32603
  }
32523
32604
  return createUnknown(name, source, guard, "contain-intrinsic-size is not statically parseable in px");
32524
32605
  }
32525
32606
  function parseLineHeight(name, raw, source, guard, fontSizePx) {
32607
+ const normalized = raw.trim().toLowerCase();
32526
32608
  const unitless = parseUnitlessValue(raw);
32527
32609
  if (unitless !== null) {
32528
32610
  const base = fontSizePx === null ? 16 : fontSizePx;
32529
- return createKnown(name, raw, source, guard, unitless * base, 1 /* Unitless */, "estimated");
32611
+ return createKnown(name, normalized, source, guard, unitless * base, 1 /* Unitless */, 1 /* Estimated */);
32530
32612
  }
32531
32613
  const px = parseSignedPxValue(raw);
32532
- if (px !== null) return createKnown(name, raw, source, guard, px, 0 /* Px */, "exact");
32614
+ if (px !== null) return createKnown(name, normalized, source, guard, px, 0 /* Px */, 0 /* Exact */);
32533
32615
  return createUnknown(name, source, guard, "line-height is not statically parseable");
32534
32616
  }
32535
32617
  var DIMENSION_KEYWORD_SET = /* @__PURE__ */ new Set([
@@ -32538,16 +32620,21 @@ var DIMENSION_KEYWORD_SET = /* @__PURE__ */ new Set([
32538
32620
  "fit-content",
32539
32621
  "min-content",
32540
32622
  "max-content",
32541
- "stretch"
32623
+ "stretch",
32624
+ "inherit",
32625
+ "initial",
32626
+ "unset",
32627
+ "revert",
32628
+ "revert-layer"
32542
32629
  ]);
32543
32630
  function parseLength(name, raw, source, guard) {
32544
32631
  const px = parseSignedPxValue(raw);
32632
+ const normalized = raw.trim().toLowerCase();
32545
32633
  if (px !== null) {
32546
- return createKnown(name, raw, source, guard, px, 0 /* Px */, "exact");
32634
+ return createKnown(name, normalized, source, guard, px, 0 /* Px */, 0 /* Exact */);
32547
32635
  }
32548
- const normalized = raw.trim().toLowerCase();
32549
32636
  if (DIMENSION_KEYWORD_SET.has(normalized) || normalized.startsWith("fit-content(")) {
32550
- return createKnown(name, raw, source, guard, null, 2 /* Keyword */, "exact");
32637
+ return createKnown(name, normalized, source, guard, null, 2 /* Keyword */, 0 /* Exact */);
32551
32638
  }
32552
32639
  return createUnknown(name, source, guard, "length is not statically parseable in px");
32553
32640
  }
@@ -32559,7 +32646,7 @@ function parseKeyword(name, raw, source, guard) {
32559
32646
  if (hasDynamicExpression(normalized)) {
32560
32647
  return createUnknown(name, source, guard, "keyword uses runtime-dependent function");
32561
32648
  }
32562
- return createKnown(name, raw, source, guard, null, 2 /* Keyword */, "exact");
32649
+ return createKnown(name, normalized, source, guard, null, 2 /* Keyword */, 0 /* Exact */);
32563
32650
  }
32564
32651
  function parseTransform(name, raw, source, guard) {
32565
32652
  const normalized = raw.trim().toLowerCase();
@@ -32570,7 +32657,7 @@ function parseTransform(name, raw, source, guard) {
32570
32657
  return createUnknown(name, source, guard, "transform uses runtime-dependent function");
32571
32658
  }
32572
32659
  const y = extractTransformYPx(normalized);
32573
- if (y !== null) return createKnown(name, raw, source, guard, y, 0 /* Px */, "exact");
32660
+ if (y !== null) return createKnown(name, normalized, source, guard, y, 0 /* Px */, 0 /* Exact */);
32574
32661
  return createUnknown(name, source, guard, "transform has non-translational or non-px functions");
32575
32662
  }
32576
32663
  function parseTranslateProperty(name, raw, source, guard) {
@@ -32582,24 +32669,20 @@ function parseTranslateProperty(name, raw, source, guard) {
32582
32669
  return createUnknown(name, source, guard, "translate uses runtime-dependent function");
32583
32670
  }
32584
32671
  const y = extractTranslatePropertyYPx(trimmed);
32585
- if (y !== null) return createKnown(name, raw, source, guard, y, 0 /* Px */, "exact");
32672
+ if (y !== null) return createKnown(name, trimmed, source, guard, y, 0 /* Px */, 0 /* Exact */);
32586
32673
  return createUnknown(name, source, guard, "translate property vertical component is not px");
32587
32674
  }
32588
32675
  function hasDynamicExpression(raw) {
32589
32676
  if (raw.includes("var(")) return true;
32590
- if (raw.includes("calc(")) return true;
32591
32677
  if (raw.includes("env(")) return true;
32592
32678
  if (raw.includes("attr(")) return true;
32593
- if (raw.includes("min(")) return true;
32594
- if (raw.includes("max(")) return true;
32595
- if (raw.includes("clamp(")) return true;
32596
32679
  return false;
32597
32680
  }
32598
- function createKnown(name, raw, source, guard, px, unit, quality) {
32681
+ function createKnown(name, normalized, source, guard, px, unit, quality) {
32599
32682
  return {
32600
- kind: "known",
32683
+ kind: 0 /* Known */,
32601
32684
  name,
32602
- normalized: raw.trim().toLowerCase(),
32685
+ normalized,
32603
32686
  source,
32604
32687
  guard,
32605
32688
  unit,
@@ -32609,7 +32692,7 @@ function createKnown(name, raw, source, guard, px, unit, quality) {
32609
32692
  }
32610
32693
  function createUnknown(name, source, guard, reason) {
32611
32694
  return {
32612
- kind: "unknown",
32695
+ kind: 1 /* Unknown */,
32613
32696
  name,
32614
32697
  source,
32615
32698
  guard,
@@ -32618,9 +32701,6 @@ function createUnknown(name, source, guard, reason) {
32618
32701
  }
32619
32702
 
32620
32703
  // src/cross-file/layout/selector-match.ts
32621
- var ATTRIBUTE_EXISTS_RE2 = /^[-_a-zA-Z][-_a-zA-Z0-9]*$/;
32622
- var ATTRIBUTE_CONSTRAINT_RE2 = /^([-_a-zA-Z][-_a-zA-Z0-9]*)\s*(=|~=|\|=|\^=|\$=|\*=)\s*(?:"([^"]*)"|'([^']*)'|([^\s"']+))(?:\s+([iIsS]))?$/;
32623
- var MAX_PSEUDO_COMPILE_DEPTH = 4;
32624
32704
  var STATEFUL_PSEUDO_CLASSES = /* @__PURE__ */ new Set([
32625
32705
  "active",
32626
32706
  "checked",
@@ -32644,14 +32724,25 @@ var STATEFUL_PSEUDO_CLASSES = /* @__PURE__ */ new Set([
32644
32724
  "valid",
32645
32725
  "visited"
32646
32726
  ]);
32727
+ var EMPTY_PSEUDO = {
32728
+ firstChild: false,
32729
+ lastChild: false,
32730
+ onlyChild: false,
32731
+ nthChild: null,
32732
+ nthLastChild: null,
32733
+ nthOfType: null,
32734
+ nthLastOfType: null,
32735
+ anyOfGroups: [],
32736
+ noneOfGroups: []
32737
+ };
32647
32738
  function compileSelectorMatcher(selector) {
32648
- const parsed = parseSelectorPattern(selector.raw);
32649
- if (parsed === null) return null;
32739
+ const selectorCompounds = selector.compounds;
32740
+ if (selectorCompounds.length === 0) return null;
32650
32741
  const compoundsLeftToRight = [];
32651
- for (let i = 0; i < parsed.compounds.length; i++) {
32652
- const compoundRaw = parsed.compounds[i];
32653
- if (compoundRaw === void 0) continue;
32654
- const compiled = compileCompound(compoundRaw, 0);
32742
+ for (let i = 0; i < selectorCompounds.length; i++) {
32743
+ const sc = selectorCompounds[i];
32744
+ if (sc === void 0) continue;
32745
+ const compiled = buildCompiledCompound(sc);
32655
32746
  if (compiled === null) return null;
32656
32747
  compoundsLeftToRight.push(compiled);
32657
32748
  }
@@ -32668,9 +32759,125 @@ function compileSelectorMatcher(selector) {
32668
32759
  },
32669
32760
  requirements: resolveFeatureRequirements(compoundsLeftToRight),
32670
32761
  compoundsRightToLeft: compoundsLeftToRight.toReversed(),
32671
- combinatorsRightToLeft: parsed.combinators.toReversed()
32762
+ combinatorsRightToLeft: selector.combinators.toReversed()
32672
32763
  };
32673
32764
  }
32765
+ function buildCompiledCompound(sc) {
32766
+ const parts = sc.parts;
32767
+ for (let i = 0; i < parts.length; i++) {
32768
+ const part = parts[i];
32769
+ if (!part) continue;
32770
+ if (part.type === "pseudo-element") return null;
32771
+ }
32772
+ const pseudoConstraints = sc.pseudoClasses;
32773
+ if (pseudoConstraints.length === 0) {
32774
+ return {
32775
+ tagName: sc.tagName,
32776
+ idValue: sc.idValue,
32777
+ classes: sc.classes,
32778
+ attributes: sc.attributes,
32779
+ pseudo: EMPTY_PSEUDO
32780
+ };
32781
+ }
32782
+ let firstChild = false;
32783
+ let lastChild = false;
32784
+ let onlyChild = false;
32785
+ let nthChild = null;
32786
+ let nthLastChild = null;
32787
+ let nthOfType = null;
32788
+ let nthLastOfType = null;
32789
+ const anyOfGroups = [];
32790
+ const noneOfGroups = [];
32791
+ for (let i = 0; i < pseudoConstraints.length; i++) {
32792
+ const pc = pseudoConstraints[i];
32793
+ if (!pc) continue;
32794
+ if (pc.kind === 0 /* Simple */) {
32795
+ if (STATEFUL_PSEUDO_CLASSES.has(pc.name)) return null;
32796
+ continue;
32797
+ }
32798
+ if (pc.kind === 1 /* FirstChild */) {
32799
+ firstChild = true;
32800
+ continue;
32801
+ }
32802
+ if (pc.kind === 2 /* LastChild */) {
32803
+ lastChild = true;
32804
+ continue;
32805
+ }
32806
+ if (pc.kind === 3 /* OnlyChild */) {
32807
+ firstChild = true;
32808
+ lastChild = true;
32809
+ onlyChild = true;
32810
+ continue;
32811
+ }
32812
+ if (pc.kind === 4 /* NthChild */) {
32813
+ if (!pc.nthPattern) return null;
32814
+ nthChild = pc.nthPattern;
32815
+ continue;
32816
+ }
32817
+ if (pc.kind === 5 /* NthLastChild */) {
32818
+ if (!pc.nthPattern) return null;
32819
+ nthLastChild = pc.nthPattern;
32820
+ continue;
32821
+ }
32822
+ if (pc.kind === 6 /* NthOfType */) {
32823
+ if (!pc.nthPattern) return null;
32824
+ nthOfType = pc.nthPattern;
32825
+ continue;
32826
+ }
32827
+ if (pc.kind === 7 /* NthLastOfType */) {
32828
+ if (!pc.nthPattern) return null;
32829
+ nthLastOfType = pc.nthPattern;
32830
+ continue;
32831
+ }
32832
+ if (pc.kind === 8 /* MatchesAny */) {
32833
+ if (pc.nestedCompounds && pc.nestedCompounds.length > 0) {
32834
+ const group = buildNestedGroup(pc.nestedCompounds);
32835
+ if (group === null) return null;
32836
+ if (group.length > 0) anyOfGroups.push(group);
32837
+ }
32838
+ continue;
32839
+ }
32840
+ if (pc.kind === 9 /* NoneOf */) {
32841
+ if (pc.nestedCompounds && pc.nestedCompounds.length > 0) {
32842
+ const group = buildNestedGroup(pc.nestedCompounds);
32843
+ if (group === null) return null;
32844
+ if (group.length > 0) noneOfGroups.push(group);
32845
+ }
32846
+ continue;
32847
+ }
32848
+ }
32849
+ return {
32850
+ tagName: sc.tagName,
32851
+ idValue: sc.idValue,
32852
+ classes: sc.classes,
32853
+ attributes: sc.attributes,
32854
+ pseudo: {
32855
+ firstChild,
32856
+ lastChild,
32857
+ onlyChild,
32858
+ nthChild,
32859
+ nthLastChild,
32860
+ nthOfType,
32861
+ nthLastOfType,
32862
+ anyOfGroups,
32863
+ noneOfGroups
32864
+ }
32865
+ };
32866
+ }
32867
+ function buildNestedGroup(nestedCompounds) {
32868
+ const out = [];
32869
+ for (let i = 0; i < nestedCompounds.length; i++) {
32870
+ const compoundGroup = nestedCompounds[i];
32871
+ if (!compoundGroup) continue;
32872
+ if (compoundGroup.length !== 1) continue;
32873
+ const sc = compoundGroup[0];
32874
+ if (!sc) continue;
32875
+ const compiled = buildCompiledCompound(sc);
32876
+ if (compiled === null) return null;
32877
+ out.push(compiled);
32878
+ }
32879
+ return out;
32880
+ }
32674
32881
  function collectSubjectAttributeNames(subject) {
32675
32882
  if (subject.attributes.length === 0) return [];
32676
32883
  const names = /* @__PURE__ */ new Set();
@@ -32746,42 +32953,42 @@ function compoundGroupNeedsAttributes(groups) {
32746
32953
  }
32747
32954
  return false;
32748
32955
  }
32749
- function selectorMatchesLayoutElement(matcher, node, perf, fileRootElements = null, logger = noopLogger) {
32956
+ function selectorMatchesLayoutElement(matcher, node, perf, fileRootElements = null, logger = noopLogger, fileElementIndex = null) {
32750
32957
  const firstCompound = matcher.compoundsRightToLeft[0];
32751
- if (firstCompound === void 0) return "no-match";
32958
+ if (firstCompound === void 0) return 1 /* NoMatch */;
32752
32959
  const subjectResult = matchesCompound(node, firstCompound);
32753
- if (subjectResult === "no-match") return "no-match";
32960
+ if (subjectResult === 1 /* NoMatch */) return 1 /* NoMatch */;
32754
32961
  if (matcher.compoundsRightToLeft.length === 1) return subjectResult;
32755
- const chainResult = matchesChain(matcher, node, 0, perf, fileRootElements, logger);
32756
- if (chainResult === "no-match") return "no-match";
32757
- if (subjectResult === "conditional" || chainResult === "conditional") return "conditional";
32758
- return "match";
32962
+ const chainResult = matchesChain(matcher, node, 0, perf, fileRootElements, logger, fileElementIndex);
32963
+ if (chainResult === 1 /* NoMatch */) return 1 /* NoMatch */;
32964
+ if (subjectResult === 2 /* Conditional */ || chainResult === 2 /* Conditional */) return 2 /* Conditional */;
32965
+ return 0 /* Match */;
32759
32966
  }
32760
- function matchesChain(matcher, node, index, perf, fileRootElements, logger) {
32967
+ function matchesChain(matcher, node, index, perf, fileRootElements, logger, fileElementIndex = null) {
32761
32968
  const combinator = matcher.combinatorsRightToLeft[index];
32762
- if (combinator === void 0) return "no-match";
32969
+ if (combinator === void 0) return 1 /* NoMatch */;
32763
32970
  const nextIndex = index + 1;
32764
32971
  const targetCompound = matcher.compoundsRightToLeft[nextIndex];
32765
- if (targetCompound === void 0) return "no-match";
32972
+ if (targetCompound === void 0) return 1 /* NoMatch */;
32766
32973
  const isFinal = nextIndex === matcher.compoundsRightToLeft.length - 1;
32767
32974
  if (combinator === "child") {
32768
32975
  const parent = node.parentElementNode;
32769
- if (parent === null) return "no-match";
32976
+ if (parent === null) return 1 /* NoMatch */;
32770
32977
  perf.ancestryChecks++;
32771
32978
  const compoundResult = matchesCompound(parent, targetCompound);
32772
- if (compoundResult === "no-match") return "no-match";
32979
+ if (compoundResult === 1 /* NoMatch */) return 1 /* NoMatch */;
32773
32980
  if (isFinal) return compoundResult;
32774
- const chainResult = matchesChain(matcher, parent, nextIndex, perf, fileRootElements, logger);
32981
+ const chainResult = matchesChain(matcher, parent, nextIndex, perf, fileRootElements, logger, fileElementIndex);
32775
32982
  return mergeMatchResults(compoundResult, chainResult);
32776
32983
  }
32777
32984
  if (combinator === "adjacent") {
32778
32985
  const sibling = node.previousSiblingNode;
32779
- if (sibling === null) return "no-match";
32986
+ if (sibling === null) return 1 /* NoMatch */;
32780
32987
  perf.ancestryChecks++;
32781
32988
  const compoundResult = matchesCompound(sibling, targetCompound);
32782
- if (compoundResult === "no-match") return "no-match";
32989
+ if (compoundResult === 1 /* NoMatch */) return 1 /* NoMatch */;
32783
32990
  if (isFinal) return compoundResult;
32784
- const chainResult = matchesChain(matcher, sibling, nextIndex, perf, fileRootElements, logger);
32991
+ const chainResult = matchesChain(matcher, sibling, nextIndex, perf, fileRootElements, logger, fileElementIndex);
32785
32992
  return mergeMatchResults(compoundResult, chainResult);
32786
32993
  }
32787
32994
  if (combinator === "sibling") {
@@ -32789,26 +32996,26 @@ function matchesChain(matcher, node, index, perf, fileRootElements, logger) {
32789
32996
  while (sibling !== null) {
32790
32997
  perf.ancestryChecks++;
32791
32998
  const compoundResult = matchesCompound(sibling, targetCompound);
32792
- if (compoundResult !== "no-match") {
32999
+ if (compoundResult !== 1 /* NoMatch */) {
32793
33000
  if (isFinal) return compoundResult;
32794
- const chainResult = matchesChain(matcher, sibling, nextIndex, perf, fileRootElements, logger);
32795
- if (chainResult !== "no-match") return mergeMatchResults(compoundResult, chainResult);
33001
+ const chainResult = matchesChain(matcher, sibling, nextIndex, perf, fileRootElements, logger, fileElementIndex);
33002
+ if (chainResult !== 1 /* NoMatch */) return mergeMatchResults(compoundResult, chainResult);
32796
33003
  }
32797
33004
  sibling = sibling.previousSiblingNode;
32798
33005
  }
32799
- return "no-match";
33006
+ return 1 /* NoMatch */;
32800
33007
  }
32801
- let bestResult = "no-match";
33008
+ let bestResult = 1 /* NoMatch */;
32802
33009
  let ancestor = node.parentElementNode;
32803
33010
  while (ancestor !== null) {
32804
33011
  perf.ancestryChecks++;
32805
33012
  const compoundResult = matchesCompound(ancestor, targetCompound);
32806
- if (compoundResult !== "no-match") {
33013
+ if (compoundResult !== 1 /* NoMatch */) {
32807
33014
  if (isFinal) return compoundResult;
32808
- const chainResult = matchesChain(matcher, ancestor, nextIndex, perf, fileRootElements, logger);
32809
- if (chainResult !== "no-match") {
33015
+ const chainResult = matchesChain(matcher, ancestor, nextIndex, perf, fileRootElements, logger, fileElementIndex);
33016
+ if (chainResult !== 1 /* NoMatch */) {
32810
33017
  const merged = mergeMatchResults(compoundResult, chainResult);
32811
- if (merged === "match") return "match";
33018
+ if (merged === 0 /* Match */) return 0 /* Match */;
32812
33019
  bestResult = merged;
32813
33020
  }
32814
33021
  }
@@ -32826,30 +33033,50 @@ function matchesChain(matcher, node, index, perf, fileRootElements, logger) {
32826
33033
  if (root.solidFile !== node.solidFile) continue;
32827
33034
  perf.ancestryChecks++;
32828
33035
  const compoundResult = matchesCompound(root, targetCompound);
32829
- if (logger.isLevelEnabled(Level.Trace) && compoundResult === "no-match") {
33036
+ if (logger.isLevelEnabled(Level.Trace) && compoundResult === 1 /* NoMatch */) {
32830
33037
  logger.trace(`[selector-match] fallback MISS: root=${root.key} tag=${root.tagName} attrs=[${[...root.attributes.entries()].map(([k, v]) => `${k}=${v}`).join(",")}]`);
32831
33038
  }
32832
- if (compoundResult !== "no-match") {
33039
+ if (compoundResult !== 1 /* NoMatch */) {
32833
33040
  if (logger.isLevelEnabled(Level.Debug)) {
32834
33041
  const compoundDesc = describeCompound(targetCompound);
32835
33042
  logger.debug(`[selector-match] fallback HIT: node=${node.key} tag=${node.tagName} matched root=${root.key} tag=${root.tagName} compound=${compoundDesc} isFinal=${isFinal}`);
32836
33043
  }
32837
33044
  if (isFinal) return compoundResult;
32838
- const chainResult = matchesChain(matcher, root, nextIndex, perf, fileRootElements, logger);
32839
- if (chainResult !== "no-match") {
33045
+ const chainResult = matchesChain(matcher, root, nextIndex, perf, fileRootElements, logger, fileElementIndex);
33046
+ if (chainResult !== 1 /* NoMatch */) {
32840
33047
  const merged = mergeMatchResults(compoundResult, chainResult);
32841
- if (merged === "match") return "match";
33048
+ if (merged === 0 /* Match */) return 0 /* Match */;
32842
33049
  bestResult = merged;
32843
33050
  }
32844
33051
  }
32845
33052
  }
32846
33053
  }
33054
+ if (fileElementIndex !== null && bestResult === 1 /* NoMatch */) {
33055
+ const candidates = resolveCompoundCandidates(fileElementIndex, targetCompound);
33056
+ if (candidates !== null) {
33057
+ for (let r = 0; r < candidates.length; r++) {
33058
+ const elem = candidates[r];
33059
+ if (elem === void 0) continue;
33060
+ if (elem === node) continue;
33061
+ perf.ancestryChecks++;
33062
+ const compoundResult = matchesCompound(elem, targetCompound);
33063
+ if (compoundResult !== 1 /* NoMatch */) {
33064
+ if (logger.isLevelEnabled(Level.Debug)) {
33065
+ const compoundDesc = describeCompound(targetCompound);
33066
+ logger.debug(`[selector-match] indexed fallback HIT: node=${node.key} tag=${node.tagName} matched elem=${elem.key} tag=${elem.tagName} compound=${compoundDesc}`);
33067
+ }
33068
+ bestResult = 2 /* Conditional */;
33069
+ break;
33070
+ }
33071
+ }
33072
+ }
33073
+ }
32847
33074
  return bestResult;
32848
33075
  }
32849
33076
  function mergeMatchResults(a, b) {
32850
- if (a === "no-match" || b === "no-match") return "no-match";
32851
- if (a === "conditional" || b === "conditional") return "conditional";
32852
- return "match";
33077
+ if (a === 1 /* NoMatch */ || b === 1 /* NoMatch */) return 1 /* NoMatch */;
33078
+ if (a === 2 /* Conditional */ || b === 2 /* Conditional */) return 2 /* Conditional */;
33079
+ return 0 /* Match */;
32853
33080
  }
32854
33081
  function describeCompound(compound) {
32855
33082
  const parts = [];
@@ -32868,16 +33095,31 @@ function describeCompound(compound) {
32868
33095
  if (compound.idValue !== null) parts.push(`#${compound.idValue}`);
32869
33096
  return parts.join("") || "*";
32870
33097
  }
33098
+ function resolveCompoundCandidates(index, compound) {
33099
+ if (compound.idValue !== null) {
33100
+ return index.byDispatchKey.get(`id:${compound.idValue}`) ?? null;
33101
+ }
33102
+ if (compound.classes.length > 0 && compound.classes[0] !== void 0) {
33103
+ return index.byDispatchKey.get(`class:${compound.classes[0]}`) ?? null;
33104
+ }
33105
+ if (compound.attributes.length > 0 && compound.attributes[0] !== void 0) {
33106
+ return index.byDispatchKey.get(`attr:${compound.attributes[0].name}`) ?? null;
33107
+ }
33108
+ if (compound.tagName !== null) {
33109
+ return index.byTagName.get(compound.tagName) ?? null;
33110
+ }
33111
+ return null;
33112
+ }
32871
33113
  function matchesCompound(node, compound) {
32872
- if (compound.tagName !== null && node.tagName !== compound.tagName) return "no-match";
33114
+ if (compound.tagName !== null && node.tagName !== compound.tagName) return 1 /* NoMatch */;
32873
33115
  if (compound.idValue !== null) {
32874
33116
  const id = node.attributes.get("id");
32875
- if (id !== compound.idValue) return "no-match";
33117
+ if (id !== compound.idValue) return 1 /* NoMatch */;
32876
33118
  }
32877
- if (!matchesRequiredClasses(compound.classes, node.classTokenSet)) return "no-match";
33119
+ if (!matchesRequiredClasses(compound.classes, node.classTokenSet)) return 1 /* NoMatch */;
32878
33120
  const attrResult = matchesRequiredAttributes(compound.attributes, node.attributes);
32879
- if (attrResult === "no-match") return "no-match";
32880
- if (!matchesPseudoConstraints(node, compound.pseudo)) return "no-match";
33121
+ if (attrResult === 1 /* NoMatch */) return 1 /* NoMatch */;
33122
+ if (!matchesPseudoConstraints(node, compound.pseudo)) return 1 /* NoMatch */;
32881
33123
  return attrResult;
32882
33124
  }
32883
33125
  function matchesPseudoConstraints(node, pseudo) {
@@ -32903,7 +33145,7 @@ function matchesPseudoConstraints(node, pseudo) {
32903
33145
  for (let j = 0; j < group.length; j++) {
32904
33146
  const compound = group[j];
32905
33147
  if (compound === void 0) continue;
32906
- if (matchesCompound(node, compound) === "no-match") continue;
33148
+ if (matchesCompound(node, compound) === 1 /* NoMatch */) continue;
32907
33149
  matched = true;
32908
33150
  break;
32909
33151
  }
@@ -32915,607 +33157,12 @@ function matchesPseudoConstraints(node, pseudo) {
32915
33157
  for (let j = 0; j < group.length; j++) {
32916
33158
  const compound = group[j];
32917
33159
  if (compound === void 0) continue;
32918
- if (matchesCompound(node, compound) === "no-match") continue;
33160
+ if (matchesCompound(node, compound) === 1 /* NoMatch */) continue;
32919
33161
  return false;
32920
33162
  }
32921
33163
  }
32922
33164
  return true;
32923
33165
  }
32924
- function parseSelectorPattern(raw) {
32925
- const compounds = [];
32926
- const combinators = [];
32927
- const length = raw.length;
32928
- let start = 0;
32929
- let bracketDepth = 0;
32930
- let parenDepth = 0;
32931
- let i = 0;
32932
- while (i < length) {
32933
- const code = raw.charCodeAt(i);
32934
- if (code === CHAR_OPEN_BRACKET) {
32935
- bracketDepth++;
32936
- i++;
32937
- continue;
32938
- }
32939
- if (code === CHAR_CLOSE_BRACKET) {
32940
- if (bracketDepth > 0) bracketDepth--;
32941
- i++;
32942
- continue;
32943
- }
32944
- if (code === CHAR_OPEN_PAREN) {
32945
- parenDepth++;
32946
- i++;
32947
- continue;
32948
- }
32949
- if (code === CHAR_CLOSE_PAREN) {
32950
- if (parenDepth > 0) parenDepth--;
32951
- i++;
32952
- continue;
32953
- }
32954
- if (bracketDepth === 0 && parenDepth === 0) {
32955
- if (code === CHAR_GT || code === CHAR_PLUS || code === CHAR_TILDE) {
32956
- const compound = raw.slice(start, i).trim();
32957
- if (compound.length === 0) return null;
32958
- compounds.push(compound);
32959
- combinators.push(combinatorFromCode(code));
32960
- i++;
32961
- while (i < length && isWhitespace(raw.charCodeAt(i))) i++;
32962
- start = i;
32963
- continue;
32964
- }
32965
- if (isWhitespace(code)) {
32966
- const compound = raw.slice(start, i).trim();
32967
- if (compound.length > 0) compounds.push(compound);
32968
- while (i < length && isWhitespace(raw.charCodeAt(i))) i++;
32969
- if (i >= length) break;
32970
- const next = raw.charCodeAt(i);
32971
- if (next === CHAR_GT || next === CHAR_PLUS || next === CHAR_TILDE) {
32972
- if (compound.length === 0) return null;
32973
- combinators.push(combinatorFromCode(next));
32974
- i++;
32975
- while (i < length && isWhitespace(raw.charCodeAt(i))) i++;
32976
- start = i;
32977
- continue;
32978
- }
32979
- if (compound.length > 0) combinators.push("descendant");
32980
- start = i;
32981
- continue;
32982
- }
32983
- }
32984
- i++;
32985
- }
32986
- const trailing = raw.slice(start).trim();
32987
- if (trailing.length > 0) compounds.push(trailing);
32988
- if (compounds.length === 0) return null;
32989
- if (combinators.length !== compounds.length - 1) return null;
32990
- return { compounds, combinators };
32991
- }
32992
- function combinatorFromCode(code) {
32993
- if (code === CHAR_GT) return "child";
32994
- if (code === CHAR_PLUS) return "adjacent";
32995
- return "sibling";
32996
- }
32997
- function compileCompound(raw, depth) {
32998
- if (depth > MAX_PSEUDO_COMPILE_DEPTH) return null;
32999
- const parts = parseCompoundParts(raw);
33000
- if (parts.length === 0) return null;
33001
- let tagName = null;
33002
- let idValue = null;
33003
- const classes = [];
33004
- const seenClasses = /* @__PURE__ */ new Set();
33005
- const attributes = [];
33006
- let firstChild = false;
33007
- let lastChild = false;
33008
- let onlyChild = false;
33009
- let nthChild = null;
33010
- let nthLastChild = null;
33011
- let nthOfType = null;
33012
- let nthLastOfType = null;
33013
- const anyOfGroups = [];
33014
- const noneOfGroups = [];
33015
- for (let i = 0; i < parts.length; i++) {
33016
- const part = parts[i];
33017
- if (part === void 0) continue;
33018
- if (part.type === "element") {
33019
- tagName = part.value.toLowerCase();
33020
- continue;
33021
- }
33022
- if (part.type === "universal") continue;
33023
- if (part.type === "id") {
33024
- idValue = part.value;
33025
- continue;
33026
- }
33027
- if (part.type === "class") {
33028
- if (seenClasses.has(part.value)) continue;
33029
- seenClasses.add(part.value);
33030
- classes.push(part.value);
33031
- continue;
33032
- }
33033
- if (part.type === "attribute") {
33034
- const attribute = parseAttributeConstraint(part.value);
33035
- if (attribute === null) return null;
33036
- attributes.push(attribute);
33037
- continue;
33038
- }
33039
- if (part.type === "pseudo-class") {
33040
- const pseudo = parsePseudoConstraint(part.raw, depth);
33041
- if (pseudo === null) return null;
33042
- if (pseudo.kind === "first-child") {
33043
- firstChild = true;
33044
- continue;
33045
- }
33046
- if (pseudo.kind === "last-child") {
33047
- lastChild = true;
33048
- continue;
33049
- }
33050
- if (pseudo.kind === "only-child") {
33051
- firstChild = true;
33052
- lastChild = true;
33053
- onlyChild = true;
33054
- continue;
33055
- }
33056
- if (pseudo.kind === "nth-child") {
33057
- if (nthChild !== null && !isSameNthPattern(nthChild, pseudo.value)) return null;
33058
- nthChild = pseudo.value;
33059
- continue;
33060
- }
33061
- if (pseudo.kind === "nth-last-child") {
33062
- if (nthLastChild !== null && !isSameNthPattern(nthLastChild, pseudo.value)) return null;
33063
- nthLastChild = pseudo.value;
33064
- continue;
33065
- }
33066
- if (pseudo.kind === "nth-of-type") {
33067
- if (nthOfType !== null && !isSameNthPattern(nthOfType, pseudo.value)) return null;
33068
- nthOfType = pseudo.value;
33069
- continue;
33070
- }
33071
- if (pseudo.kind === "nth-last-of-type") {
33072
- if (nthLastOfType !== null && !isSameNthPattern(nthLastOfType, pseudo.value)) return null;
33073
- nthLastOfType = pseudo.value;
33074
- continue;
33075
- }
33076
- if (pseudo.kind === "ignore") continue;
33077
- if (pseudo.kind === "matches-any") {
33078
- anyOfGroups.push(pseudo.selectors);
33079
- continue;
33080
- }
33081
- noneOfGroups.push(pseudo.selectors);
33082
- continue;
33083
- }
33084
- return null;
33085
- }
33086
- if (firstChild && nthChild !== null && !matchesNthPattern(1, nthChild)) return null;
33087
- if (lastChild && nthLastChild !== null && !matchesNthPattern(1, nthLastChild)) return null;
33088
- return {
33089
- tagName,
33090
- idValue,
33091
- classes,
33092
- attributes,
33093
- pseudo: {
33094
- firstChild,
33095
- lastChild,
33096
- onlyChild,
33097
- nthChild,
33098
- nthLastChild,
33099
- nthOfType,
33100
- nthLastOfType,
33101
- anyOfGroups,
33102
- noneOfGroups
33103
- }
33104
- };
33105
- }
33106
- function parseAttributeConstraint(raw) {
33107
- const trimmed = raw.trim();
33108
- const constrained = ATTRIBUTE_CONSTRAINT_RE2.exec(trimmed);
33109
- if (constrained) {
33110
- const operatorToken = constrained[2];
33111
- if (operatorToken === void 0) return null;
33112
- const operator = mapAttributeOperatorFromToken2(operatorToken);
33113
- if (operator === null) return null;
33114
- const value2 = constrained[3] ?? constrained[4] ?? constrained[5] ?? null;
33115
- if (value2 === null) return null;
33116
- const nameToken = constrained[1];
33117
- if (nameToken === void 0) return null;
33118
- return {
33119
- name: nameToken.toLowerCase(),
33120
- operator,
33121
- value: value2,
33122
- caseInsensitive: (constrained[6] ?? "").toLowerCase() === "i"
33123
- };
33124
- }
33125
- if (!ATTRIBUTE_EXISTS_RE2.test(trimmed)) return null;
33126
- return {
33127
- name: trimmed.toLowerCase(),
33128
- operator: "exists",
33129
- value: null,
33130
- caseInsensitive: false
33131
- };
33132
- }
33133
- function mapAttributeOperatorFromToken2(operator) {
33134
- if (operator === "=") return "equals";
33135
- if (operator === "~=") return "includes-word";
33136
- if (operator === "|=") return "dash-prefix";
33137
- if (operator === "^=") return "prefix";
33138
- if (operator === "$=") return "suffix";
33139
- if (operator === "*=") return "contains";
33140
- return null;
33141
- }
33142
- function parsePseudoConstraint(raw, depth) {
33143
- const trimmed = raw.trim();
33144
- const normalized = trimmed.toLowerCase();
33145
- if (normalized === ":first-child") return { kind: "first-child" };
33146
- if (normalized === ":last-child") return { kind: "last-child" };
33147
- if (normalized === ":only-child") return { kind: "only-child" };
33148
- const nthChild = parseNthPseudoArgument(trimmed, "nth-child");
33149
- if (nthChild !== void 0) {
33150
- if (nthChild === null) return null;
33151
- return { kind: "nth-child", value: nthChild };
33152
- }
33153
- const nthLastChild = parseNthPseudoArgument(trimmed, "nth-last-child");
33154
- if (nthLastChild !== void 0) {
33155
- if (nthLastChild === null) return null;
33156
- return { kind: "nth-last-child", value: nthLastChild };
33157
- }
33158
- const nthOfType = parseNthPseudoArgument(trimmed, "nth-of-type");
33159
- if (nthOfType !== void 0) {
33160
- if (nthOfType === null) return null;
33161
- return { kind: "nth-of-type", value: nthOfType };
33162
- }
33163
- const nthLastOfType = parseNthPseudoArgument(trimmed, "nth-last-of-type");
33164
- if (nthLastOfType !== void 0) {
33165
- if (nthLastOfType === null) return null;
33166
- return { kind: "nth-last-of-type", value: nthLastOfType };
33167
- }
33168
- const name = readPseudoName(normalized);
33169
- if (name === null) return null;
33170
- if (STATEFUL_PSEUDO_CLASSES.has(name)) return null;
33171
- if (name !== "is" && name !== "where" && name !== "not") {
33172
- return { kind: "ignore" };
33173
- }
33174
- const content = extractFunctionalPseudoContent(trimmed, name);
33175
- if (content === null) return null;
33176
- const selectors = compileFunctionalPseudoArguments(content, depth + 1);
33177
- if (selectors === null || selectors.length === 0) return null;
33178
- if (name === "not") {
33179
- return {
33180
- kind: "matches-none",
33181
- selectors
33182
- };
33183
- }
33184
- return {
33185
- kind: "matches-any",
33186
- selectors
33187
- };
33188
- }
33189
- function parseNthPseudoArgument(raw, name) {
33190
- const content = extractFunctionalPseudoContent(raw, name);
33191
- if (content === null) return void 0;
33192
- return parseNthPattern(content);
33193
- }
33194
- function parseNthPattern(raw) {
33195
- const normalized = raw.trim().toLowerCase().replaceAll(" ", "");
33196
- if (normalized.length === 0) return null;
33197
- if (normalized === "odd") {
33198
- return { step: 2, offset: 1 };
33199
- }
33200
- if (normalized === "even") {
33201
- return { step: 2, offset: 0 };
33202
- }
33203
- const nIndex = normalized.indexOf("n");
33204
- if (nIndex === -1) {
33205
- const value2 = Number.parseInt(normalized, 10);
33206
- if (Number.isNaN(value2)) return null;
33207
- return { step: 0, offset: value2 };
33208
- }
33209
- const stepPart = normalized.slice(0, nIndex);
33210
- const offsetPart = normalized.slice(nIndex + 1);
33211
- let step;
33212
- if (stepPart.length === 0 || stepPart === "+") {
33213
- step = 1;
33214
- } else if (stepPart === "-") {
33215
- step = -1;
33216
- } else {
33217
- step = Number.parseInt(stepPart, 10);
33218
- if (Number.isNaN(step)) return null;
33219
- }
33220
- let offset = 0;
33221
- if (offsetPart.length > 0) {
33222
- offset = Number.parseInt(offsetPart, 10);
33223
- if (Number.isNaN(offset)) return null;
33224
- }
33225
- return {
33226
- step,
33227
- offset
33228
- };
33229
- }
33230
- function extractFunctionalPseudoContent(raw, name) {
33231
- const prefix = `:${name}(`;
33232
- if (!raw.toLowerCase().startsWith(prefix)) return null;
33233
- if (!raw.endsWith(")")) return null;
33234
- return raw.slice(prefix.length, -1);
33235
- }
33236
- function compileFunctionalPseudoArguments(content, depth) {
33237
- if (depth > MAX_PSEUDO_COMPILE_DEPTH) return null;
33238
- const args = splitTopLevelSelectorArguments(content);
33239
- if (args.length === 0) return null;
33240
- const out = [];
33241
- for (let i = 0; i < args.length; i++) {
33242
- const arg = args[i];
33243
- if (arg === void 0) return null;
33244
- const raw = arg.trim();
33245
- if (raw.length === 0) return null;
33246
- const parsed = parseSelectorPattern(raw);
33247
- if (parsed === null) return null;
33248
- if (parsed.combinators.length !== 0) return null;
33249
- if (parsed.compounds.length !== 1) return null;
33250
- const compoundRaw = parsed.compounds[0];
33251
- if (compoundRaw === void 0) return null;
33252
- const compiled = compileCompound(compoundRaw, depth);
33253
- if (compiled === null) return null;
33254
- out.push(compiled);
33255
- }
33256
- return out;
33257
- }
33258
- function splitTopLevelSelectorArguments(content) {
33259
- const out = [];
33260
- let start = 0;
33261
- let parenDepth = 0;
33262
- let bracketDepth = 0;
33263
- let quote = null;
33264
- for (let i = 0; i < content.length; i++) {
33265
- const code = content.charCodeAt(i);
33266
- if (quote !== null) {
33267
- if (code === quote) quote = null;
33268
- continue;
33269
- }
33270
- if (code === CHAR_SINGLE_QUOTE || code === CHAR_DOUBLE_QUOTE) {
33271
- quote = code;
33272
- continue;
33273
- }
33274
- if (code === CHAR_OPEN_PAREN) {
33275
- parenDepth++;
33276
- continue;
33277
- }
33278
- if (code === CHAR_CLOSE_PAREN) {
33279
- if (parenDepth > 0) parenDepth--;
33280
- continue;
33281
- }
33282
- if (code === CHAR_OPEN_BRACKET) {
33283
- bracketDepth++;
33284
- continue;
33285
- }
33286
- if (code === CHAR_CLOSE_BRACKET) {
33287
- if (bracketDepth > 0) bracketDepth--;
33288
- continue;
33289
- }
33290
- if (code !== CHAR_COMMA) continue;
33291
- if (parenDepth !== 0) continue;
33292
- if (bracketDepth !== 0) continue;
33293
- out.push(content.slice(start, i));
33294
- start = i + 1;
33295
- }
33296
- out.push(content.slice(start));
33297
- return out;
33298
- }
33299
- function parseCompoundParts(raw) {
33300
- const trimmed = raw.trim();
33301
- if (trimmed.length === 0) return [];
33302
- const out = [];
33303
- const length = trimmed.length;
33304
- let i = 0;
33305
- let allowsElement = true;
33306
- while (i < length) {
33307
- const code = trimmed.charCodeAt(i);
33308
- if (code === CHAR_OPEN_BRACKET) {
33309
- const end = readBracketed(trimmed, i);
33310
- if (end === null) return [];
33311
- const inner = trimmed.slice(i + 1, end - 1);
33312
- out.push({
33313
- type: "attribute",
33314
- value: inner,
33315
- raw: trimmed.slice(i, end)
33316
- });
33317
- i = end;
33318
- allowsElement = false;
33319
- continue;
33320
- }
33321
- if (code === 35) {
33322
- const ident2 = readIdentifier(trimmed, i + 1);
33323
- if (ident2.consumed === 0) return [];
33324
- out.push({
33325
- type: "id",
33326
- value: ident2.value,
33327
- raw: trimmed.slice(i, i + 1 + ident2.consumed)
33328
- });
33329
- i += 1 + ident2.consumed;
33330
- allowsElement = false;
33331
- continue;
33332
- }
33333
- if (code === 46) {
33334
- const ident2 = readIdentifier(trimmed, i + 1);
33335
- if (ident2.consumed === 0) return [];
33336
- out.push({
33337
- type: "class",
33338
- value: ident2.value,
33339
- raw: trimmed.slice(i, i + 1 + ident2.consumed)
33340
- });
33341
- i += 1 + ident2.consumed;
33342
- allowsElement = false;
33343
- continue;
33344
- }
33345
- if (code === 58) {
33346
- const pseudo = readPseudo(trimmed, i);
33347
- if (pseudo === null) return [];
33348
- out.push(pseudo);
33349
- i += pseudo.raw.length;
33350
- allowsElement = false;
33351
- continue;
33352
- }
33353
- if (code === 42) {
33354
- out.push({
33355
- type: "universal",
33356
- value: "*",
33357
- raw: "*"
33358
- });
33359
- i++;
33360
- allowsElement = false;
33361
- continue;
33362
- }
33363
- if (!allowsElement) return [];
33364
- const ident = readIdentifier(trimmed, i);
33365
- if (ident.consumed === 0) return [];
33366
- out.push({
33367
- type: "element",
33368
- value: ident.value,
33369
- raw: trimmed.slice(i, i + ident.consumed)
33370
- });
33371
- i += ident.consumed;
33372
- allowsElement = false;
33373
- }
33374
- return out;
33375
- }
33376
- function readPseudo(input, start) {
33377
- const second = input.charCodeAt(start + 1);
33378
- if (second === 58) return null;
33379
- let i = start + 1;
33380
- while (i < input.length) {
33381
- const code = input.charCodeAt(i);
33382
- if (!isIdentChar(code)) break;
33383
- i++;
33384
- }
33385
- if (i === start + 1) return null;
33386
- const value2 = input.slice(start + 1, i);
33387
- if (input.charCodeAt(i) !== CHAR_OPEN_PAREN) {
33388
- return {
33389
- type: "pseudo-class",
33390
- value: value2,
33391
- raw: input.slice(start, i)
33392
- };
33393
- }
33394
- const end = readParenthesized(input, i);
33395
- if (end === null) return null;
33396
- return {
33397
- type: "pseudo-class",
33398
- value: value2,
33399
- raw: input.slice(start, end)
33400
- };
33401
- }
33402
- function readBracketed(input, start) {
33403
- let quote = null;
33404
- let depth = 0;
33405
- for (let i = start; i < input.length; i++) {
33406
- const code = input.charCodeAt(i);
33407
- if (quote !== null) {
33408
- if (code === quote) quote = null;
33409
- continue;
33410
- }
33411
- if (code === CHAR_SINGLE_QUOTE || code === CHAR_DOUBLE_QUOTE) {
33412
- quote = code;
33413
- continue;
33414
- }
33415
- if (code === CHAR_OPEN_BRACKET) {
33416
- depth++;
33417
- continue;
33418
- }
33419
- if (code !== CHAR_CLOSE_BRACKET) continue;
33420
- depth--;
33421
- if (depth === 0) return i + 1;
33422
- if (depth < 0) return null;
33423
- }
33424
- return null;
33425
- }
33426
- function readParenthesized(input, start) {
33427
- let quote = null;
33428
- let depth = 0;
33429
- for (let i = start; i < input.length; i++) {
33430
- const code = input.charCodeAt(i);
33431
- if (quote !== null) {
33432
- if (code === quote) quote = null;
33433
- continue;
33434
- }
33435
- if (code === CHAR_SINGLE_QUOTE || code === CHAR_DOUBLE_QUOTE) {
33436
- quote = code;
33437
- continue;
33438
- }
33439
- if (code === CHAR_OPEN_PAREN) {
33440
- depth++;
33441
- continue;
33442
- }
33443
- if (code !== CHAR_CLOSE_PAREN) continue;
33444
- depth--;
33445
- if (depth === 0) return i + 1;
33446
- if (depth < 0) return null;
33447
- }
33448
- return null;
33449
- }
33450
- var EMPTY_IDENTIFIER = { value: "", consumed: 0 };
33451
- function readIdentifier(input, start) {
33452
- const length = input.length;
33453
- let i = start;
33454
- let hasEscape = false;
33455
- while (i < length) {
33456
- const code = input.charCodeAt(i);
33457
- if (code === CHAR_BACKSLASH) {
33458
- if (i + 1 >= length) break;
33459
- hasEscape = true;
33460
- i = skipCssEscapeSequence(input, i + 1);
33461
- continue;
33462
- }
33463
- if (!isIdentChar(code)) break;
33464
- i++;
33465
- }
33466
- const consumed = i - start;
33467
- if (consumed === 0) return EMPTY_IDENTIFIER;
33468
- if (!hasEscape) {
33469
- const value2 = input.slice(start, i);
33470
- return { value: value2, consumed };
33471
- }
33472
- return { value: decodeCssEscapes(input, start, i), consumed };
33473
- }
33474
- var CHAR_BACKSLASH = 92;
33475
- function skipCssEscapeSequence(input, afterBackslash) {
33476
- const length = input.length;
33477
- if (afterBackslash >= length) return afterBackslash;
33478
- const first = input.charCodeAt(afterBackslash);
33479
- if (!isHexDigit(first)) return afterBackslash + 1;
33480
- let end = afterBackslash + 1;
33481
- const maxHex = Math.min(afterBackslash + 6, length);
33482
- while (end < maxHex && isHexDigit(input.charCodeAt(end))) end++;
33483
- if (end < length && isWhitespace(input.charCodeAt(end))) end++;
33484
- return end;
33485
- }
33486
- function decodeCssEscapes(input, start, end) {
33487
- const parts = [];
33488
- let i = start;
33489
- while (i < end) {
33490
- const code = input.charCodeAt(i);
33491
- if (code !== CHAR_BACKSLASH) {
33492
- parts.push(String.fromCharCode(code));
33493
- i++;
33494
- continue;
33495
- }
33496
- i++;
33497
- if (i >= end) break;
33498
- const first = input.charCodeAt(i);
33499
- if (!isHexDigit(first)) {
33500
- parts.push(String.fromCharCode(first));
33501
- i++;
33502
- continue;
33503
- }
33504
- const hexStart = i;
33505
- const maxHex = Math.min(i + 6, end);
33506
- while (i < maxHex && isHexDigit(input.charCodeAt(i))) i++;
33507
- const codePoint = Number.parseInt(input.slice(hexStart, i), 16);
33508
- if (codePoint > 0 && codePoint <= 1114111) {
33509
- parts.push(String.fromCodePoint(codePoint));
33510
- }
33511
- if (i < end && isWhitespace(input.charCodeAt(i))) i++;
33512
- }
33513
- return parts.join("");
33514
- }
33515
- function isSameNthPattern(left, right) {
33516
- if (left.step !== right.step) return false;
33517
- return left.offset === right.offset;
33518
- }
33519
33166
  function matchesNthPattern(index, pattern) {
33520
33167
  if (index < 1) return false;
33521
33168
  const step = pattern.step;
@@ -33534,20 +33181,6 @@ function matchesNthPattern(index, pattern) {
33534
33181
  if (delta < 0) return false;
33535
33182
  return delta % positiveStep === 0;
33536
33183
  }
33537
- function readPseudoName(raw) {
33538
- if (!raw.startsWith(":")) return null;
33539
- let index = 1;
33540
- while (index < raw.length) {
33541
- const code = raw.charCodeAt(index);
33542
- const isUpper = code >= 65 && code <= 90;
33543
- const isLower = code >= 97 && code <= 122;
33544
- const isDash = code === 45;
33545
- if (!isUpper && !isLower && !isDash) break;
33546
- index++;
33547
- }
33548
- if (index <= 1) return null;
33549
- return raw.slice(1, index);
33550
- }
33551
33184
  function matchesRequiredClasses(required, actual) {
33552
33185
  if (required.length === 0) return true;
33553
33186
  if (actual.size === 0) return false;
@@ -33560,24 +33193,24 @@ function matchesRequiredClasses(required, actual) {
33560
33193
  return true;
33561
33194
  }
33562
33195
  function matchesRequiredAttributes(required, actual) {
33563
- if (required.length === 0) return "match";
33196
+ if (required.length === 0) return 0 /* Match */;
33564
33197
  let hasConditional = false;
33565
33198
  for (let i = 0; i < required.length; i++) {
33566
33199
  const constraint = required[i];
33567
33200
  if (constraint === void 0) continue;
33568
- if (!actual.has(constraint.name)) return "no-match";
33201
+ if (!actual.has(constraint.name)) return 1 /* NoMatch */;
33569
33202
  if (constraint.operator === "exists") continue;
33570
33203
  const actualValue = actual.get(constraint.name);
33571
- if (actualValue === void 0) return "no-match";
33204
+ if (actualValue === void 0) return 1 /* NoMatch */;
33572
33205
  if (actualValue === null) {
33573
33206
  hasConditional = true;
33574
33207
  continue;
33575
33208
  }
33576
- if (constraint.value === null) return "no-match";
33209
+ if (constraint.value === null) return 1 /* NoMatch */;
33577
33210
  if (matchesAttributeValue(actualValue, constraint)) continue;
33578
- return "no-match";
33211
+ return 1 /* NoMatch */;
33579
33212
  }
33580
- return hasConditional ? "conditional" : "match";
33213
+ return hasConditional ? 2 /* Conditional */ : 0 /* Match */;
33581
33214
  }
33582
33215
  function matchesAttributeValue(actualValue, constraint) {
33583
33216
  const expectedValue = constraint.value;
@@ -33695,49 +33328,23 @@ var INHERITED_SIGNAL_NAMES = [
33695
33328
  "direction"
33696
33329
  ];
33697
33330
  function collectSignalSnapshot(context, node) {
33698
- const existing = context.layout.snapshotByElementNode.get(node);
33699
- if (existing) {
33331
+ const record = context.layout.records.get(node);
33332
+ if (record) {
33700
33333
  context.layout.perf.signalSnapshotCacheHits++;
33701
- return existing;
33702
- }
33703
- throw new Error(`missing precomputed layout snapshot for ${node.key}`);
33704
- }
33705
- function buildSignalSnapshotIndex(elements, cascadeByElementNode, perf) {
33706
- const snapshotByElementNode = /* @__PURE__ */ new WeakMap();
33707
- for (let i = 0; i < elements.length; i++) {
33708
- const element = elements[i];
33709
- if (!element) continue;
33710
- buildSnapshotForNode(element, cascadeByElementNode, snapshotByElementNode, perf);
33334
+ return record.snapshot;
33711
33335
  }
33712
- return snapshotByElementNode;
33336
+ throw new Error(`missing precomputed layout record for ${node.key}`);
33713
33337
  }
33714
- function buildSnapshotForNode(node, cascadeByElementNode, snapshotByElementNode, perf) {
33715
- const existing = snapshotByElementNode.get(node);
33716
- if (existing) {
33717
- perf.signalSnapshotCacheHits++;
33718
- return existing;
33719
- }
33720
- const raw = cascadeByElementNode.get(node);
33721
- if (!raw) {
33722
- throw new Error(`missing cascade map for ${node.key}`);
33723
- }
33724
- const normalized = normalizeSignalMapWithCounts(raw);
33725
- const parent = node.parentElementNode;
33726
- const parentSnapshot = parent ? buildSnapshotForNode(parent, cascadeByElementNode, snapshotByElementNode, perf) : null;
33338
+ function buildSnapshotFromCascade(node, cascade, parentSnapshot) {
33339
+ const normalized = normalizeSignalMapWithCounts(cascade);
33727
33340
  const inherited = inheritSignalsFromParent(parentSnapshot, normalized.signals);
33728
- const knownSignalCount = normalized.knownSignalCount + inherited.knownDelta;
33729
- const unknownSignalCount = normalized.unknownSignalCount + inherited.unknownDelta;
33730
- const conditionalSignalCount = normalized.conditionalSignalCount + inherited.conditionalDelta;
33731
- const snapshot = {
33341
+ return {
33732
33342
  node,
33733
33343
  signals: inherited.signals,
33734
- knownSignalCount,
33735
- unknownSignalCount,
33736
- conditionalSignalCount
33344
+ knownSignalCount: normalized.knownSignalCount + inherited.knownDelta,
33345
+ unknownSignalCount: normalized.unknownSignalCount + inherited.unknownDelta,
33346
+ conditionalSignalCount: normalized.conditionalSignalCount + inherited.conditionalDelta
33737
33347
  };
33738
- snapshotByElementNode.set(node, snapshot);
33739
- perf.signalSnapshotsBuilt++;
33740
- return snapshot;
33741
33348
  }
33742
33349
  function inheritSignalsFromParent(parentSnapshot, local) {
33743
33350
  if (!parentSnapshot) {
@@ -33764,7 +33371,7 @@ function inheritSignalsFromParent(parentSnapshot, local) {
33764
33371
  conditionalDelta++;
33765
33372
  continue;
33766
33373
  }
33767
- if (inheritedValue.kind === "known") {
33374
+ if (inheritedValue.kind === 0 /* Known */) {
33768
33375
  knownDelta++;
33769
33376
  continue;
33770
33377
  }
@@ -33802,10 +33409,10 @@ var EMPTY_STATEFUL_BASE_VALUE_INDEX = /* @__PURE__ */ new Map();
33802
33409
  var EMPTY_LAYOUT_RESERVED_SPACE_FACT = Object.freeze({
33803
33410
  hasReservedSpace: false,
33804
33411
  reasons: EMPTY_RESERVED_SPACE_REASONS,
33805
- hasUsableInlineDimension: false,
33806
- hasUsableBlockDimension: false,
33807
33412
  hasContainIntrinsicSize: false,
33808
- hasUsableAspectRatio: false
33413
+ hasUsableAspectRatio: false,
33414
+ hasDeclaredInlineDimension: false,
33415
+ hasDeclaredBlockDimension: false
33809
33416
  });
33810
33417
  var EMPTY_LAYOUT_SCROLL_CONTAINER_FACT = Object.freeze({
33811
33418
  isScrollContainer: false,
@@ -33838,12 +33445,12 @@ var EMPTY_LAYOUT_CONDITIONAL_DELTA_FACT = Object.freeze({
33838
33445
  function readKnownSignalWithGuard(snapshot, name) {
33839
33446
  const value2 = snapshot.signals.get(name);
33840
33447
  if (!value2) return null;
33841
- if (value2.kind !== "known") return null;
33448
+ if (value2.kind !== 0 /* Known */) return null;
33842
33449
  return value2;
33843
33450
  }
33844
33451
  function toEvidenceKind(value2) {
33845
33452
  if (value2.guard.kind === 1 /* Conditional */) return 2 /* Conditional */;
33846
- if (value2.quality === "estimated") return 1 /* Interval */;
33453
+ if (value2.quality === 1 /* Estimated */) return 1 /* Interval */;
33847
33454
  return 0 /* Exact */;
33848
33455
  }
33849
33456
  function readNormalizedSignalEvidence(snapshot, name) {
@@ -33854,7 +33461,7 @@ function readNormalizedSignalEvidence(snapshot, name) {
33854
33461
  kind: 3 /* Unknown */
33855
33462
  };
33856
33463
  }
33857
- if (value2.kind !== "known") {
33464
+ if (value2.kind !== 0 /* Known */) {
33858
33465
  if (value2.guard.kind === 1 /* Conditional */) {
33859
33466
  return {
33860
33467
  value: null,
@@ -33908,19 +33515,19 @@ function hasEffectivePosition(snapshot) {
33908
33515
  return position !== "static";
33909
33516
  }
33910
33517
  function readReservedSpaceFact(graph, node) {
33911
- return graph.reservedSpaceFactsByNode.get(node) ?? EMPTY_LAYOUT_RESERVED_SPACE_FACT;
33518
+ return graph.records.get(node)?.reservedSpace ?? EMPTY_LAYOUT_RESERVED_SPACE_FACT;
33912
33519
  }
33913
33520
  function readScrollContainerFact(graph, node) {
33914
- return graph.scrollContainerFactsByNode.get(node) ?? EMPTY_LAYOUT_SCROLL_CONTAINER_FACT;
33521
+ return graph.records.get(node)?.scrollContainer ?? EMPTY_LAYOUT_SCROLL_CONTAINER_FACT;
33915
33522
  }
33916
33523
  function readFlowParticipationFact(graph, node) {
33917
- return graph.flowParticipationFactsByNode.get(node) ?? EMPTY_LAYOUT_FLOW_PARTICIPATION_FACT;
33524
+ return graph.records.get(node)?.flowParticipation ?? EMPTY_LAYOUT_FLOW_PARTICIPATION_FACT;
33918
33525
  }
33919
33526
  function readContainingBlockFact(graph, node) {
33920
- return graph.containingBlockFactsByNode.get(node) ?? EMPTY_LAYOUT_CONTAINING_BLOCK_FACT;
33527
+ return graph.records.get(node)?.containingBlock ?? EMPTY_LAYOUT_CONTAINING_BLOCK_FACT;
33921
33528
  }
33922
33529
  function readConditionalSignalDeltaFact(graph, node, name) {
33923
- const byProperty = graph.conditionalSignalDeltaFactsByNode.get(node);
33530
+ const byProperty = graph.records.get(node)?.conditionalDelta;
33924
33531
  if (!byProperty) return EMPTY_LAYOUT_CONDITIONAL_DELTA_FACT;
33925
33532
  return byProperty.get(name) ?? EMPTY_LAYOUT_CONDITIONAL_DELTA_FACT;
33926
33533
  }
@@ -33948,7 +33555,7 @@ function readScrollContainerElements(graph) {
33948
33555
  return graph.scrollContainerElements;
33949
33556
  }
33950
33557
  function readBaselineOffsetFacts(graph, node) {
33951
- return graph.baselineOffsetFactsByNode.get(node) ?? EMPTY_BASELINE_FACTS;
33558
+ return graph.records.get(node)?.baselineOffsets ?? EMPTY_BASELINE_FACTS;
33952
33559
  }
33953
33560
  function readElementRef(graph, node) {
33954
33561
  return readElementRefById(graph, node.solidFile, node.elementId);
@@ -34373,11 +33980,11 @@ function accumulateSnapshotFacts(snapshot, sink) {
34373
33980
  sink.addConditional();
34374
33981
  continue;
34375
33982
  }
34376
- if (value2.kind === "unknown") {
33983
+ if (value2.kind === 1 /* Unknown */) {
34377
33984
  sink.addUnknown();
34378
33985
  continue;
34379
33986
  }
34380
- if (value2.quality === "estimated" && value2.px !== null) {
33987
+ if (value2.quality === 1 /* Estimated */ && value2.px !== null) {
34381
33988
  sink.addInterval();
34382
33989
  continue;
34383
33990
  }
@@ -34719,7 +34326,7 @@ function checkHeightContributions(snapshot, state) {
34719
34326
  if (!signalName) continue;
34720
34327
  const signal = snapshot.signals.get(signalName);
34721
34328
  if (!signal) continue;
34722
- if (signal.kind !== "known") continue;
34329
+ if (signal.kind !== 0 /* Known */) continue;
34723
34330
  if (signal.px !== null && signal.px > 0) {
34724
34331
  state.hasHeightContributingDescendant = true;
34725
34332
  return;
@@ -34729,7 +34336,7 @@ function checkHeightContributions(snapshot, state) {
34729
34336
  function checkVerticalAlignMitigation(snapshot, state) {
34730
34337
  const verticalAlign = snapshot.signals.get("vertical-align");
34731
34338
  if (!verticalAlign) return;
34732
- if (verticalAlign.kind !== "known") return;
34339
+ if (verticalAlign.kind !== 0 /* Known */) return;
34733
34340
  if (VERTICAL_ALIGN_MITIGATIONS.has(verticalAlign.normalized)) {
34734
34341
  state.hasVerticalAlignMitigation = true;
34735
34342
  }
@@ -35915,16 +35522,16 @@ function establishesFormattingContext2(node, snapshotByElementNode) {
35915
35522
  const snapshot = snapshotByElementNode.get(node);
35916
35523
  if (snapshot) {
35917
35524
  const displaySignal = snapshot.signals.get("display");
35918
- if (displaySignal && displaySignal.kind === "known") {
35525
+ if (displaySignal && displaySignal.kind === 0 /* Known */) {
35919
35526
  return !isInlineLevelDisplay(displaySignal.normalized);
35920
35527
  }
35921
35528
  const overflowSignal = snapshot.signals.get("overflow");
35922
- if (overflowSignal && overflowSignal.kind === "known") {
35529
+ if (overflowSignal && overflowSignal.kind === 0 /* Known */) {
35923
35530
  const ov = overflowSignal.normalized;
35924
35531
  if (ov !== "visible" && ov !== "clip") return true;
35925
35532
  }
35926
35533
  const overflowYSignal = snapshot.signals.get("overflow-y");
35927
- if (overflowYSignal && overflowYSignal.kind === "known") {
35534
+ if (overflowYSignal && overflowYSignal.kind === 0 /* Known */) {
35928
35535
  const ov = overflowYSignal.normalized;
35929
35536
  if (ov !== "visible" && ov !== "clip") return true;
35930
35537
  }
@@ -36117,18 +35724,21 @@ function buildSelectorCandidatesByNode(elements, scopedSelectorsBySolidFile, per
36117
35724
  }
36118
35725
  return out;
36119
35726
  }
35727
+ function buildDispatchKeys(idValue, classTokens, attributeNames) {
35728
+ const out = [];
35729
+ if (idValue !== null) out.push(`id:${idValue}`);
35730
+ for (let i = 0; i < classTokens.length; i++) out.push(`class:${classTokens[i]}`);
35731
+ for (let i = 0; i < attributeNames.length; i++) out.push(`attr:${attributeNames[i]}`);
35732
+ if (out.length <= 1) return out;
35733
+ out.sort();
35734
+ return dedupeSorted(out);
35735
+ }
36120
35736
  function buildSelectorDispatchKeys(attributes, classTokens) {
36121
35737
  const out = [];
36122
35738
  const idValue = attributes.get("id");
36123
- if (idValue !== null && idValue !== void 0) {
36124
- out.push(`id:${idValue}`);
36125
- }
36126
- for (let i = 0; i < classTokens.length; i++) {
36127
- out.push(`class:${classTokens[i]}`);
36128
- }
36129
- for (const attributeName of attributes.keys()) {
36130
- out.push(`attr:${attributeName}`);
36131
- }
35739
+ if (idValue !== null && idValue !== void 0) out.push(`id:${idValue}`);
35740
+ for (let i = 0; i < classTokens.length; i++) out.push(`class:${classTokens[i]}`);
35741
+ for (const attributeName of attributes.keys()) out.push(`attr:${attributeName}`);
36132
35742
  if (out.length <= 1) return out;
36133
35743
  out.sort();
36134
35744
  return dedupeSorted(out);
@@ -36272,19 +35882,11 @@ function selectorMatchesDispatchKeys(candidate, dispatchKeys) {
36272
35882
  return subjectIndex === candidate.subjectDispatchKeys.length;
36273
35883
  }
36274
35884
  function resolveSubjectDispatchKeys(matcher) {
36275
- const out = [];
36276
- if (matcher.subject.idValue !== null) {
36277
- out.push(`id:${matcher.subject.idValue}`);
36278
- }
36279
- for (let i = 0; i < matcher.subject.classes.length; i++) {
36280
- out.push(`class:${matcher.subject.classes[i]}`);
36281
- }
36282
- for (let i = 0; i < matcher.subject.attributeNames.length; i++) {
36283
- out.push(`attr:${matcher.subject.attributeNames[i]}`);
36284
- }
36285
- if (out.length <= 1) return out;
36286
- out.sort();
36287
- return dedupeSorted(out);
35885
+ return buildDispatchKeys(
35886
+ matcher.subject.idValue,
35887
+ matcher.subject.classes,
35888
+ matcher.subject.attributeNames
35889
+ );
36288
35890
  }
36289
35891
  function dedupeSorted(values) {
36290
35892
  if (values.length <= 1) return values;
@@ -36354,6 +35956,94 @@ function normalizeWithCache(cache, path) {
36354
35956
  return normalized;
36355
35957
  }
36356
35958
 
35959
+ // src/cross-file/layout/shorthand-expansion.ts
35960
+ var QUAD_EXPANSIONS = /* @__PURE__ */ new Map([
35961
+ ["padding", ["padding-top", "padding-right", "padding-bottom", "padding-left"]],
35962
+ ["border-width", ["border-top-width", "border-right-width", "border-bottom-width", "border-left-width"]],
35963
+ ["margin", ["margin-top", "margin-right", "margin-bottom", "margin-left"]],
35964
+ ["inset", ["top", "right", "bottom", "left"]]
35965
+ ]);
35966
+ var BLOCK_EXPANSIONS = /* @__PURE__ */ new Map([
35967
+ ["margin-block", ["margin-top", "margin-bottom"]],
35968
+ ["padding-block", ["padding-top", "padding-bottom"]],
35969
+ ["inset-block", ["inset-block-start", "inset-block-end"]]
35970
+ ]);
35971
+ var INLINE_EXPANSIONS = /* @__PURE__ */ new Map([
35972
+ ["padding-inline", ["padding-left", "padding-right"]]
35973
+ ]);
35974
+ function expandShorthand(property, value2) {
35975
+ const quadTarget = QUAD_EXPANSIONS.get(property);
35976
+ if (quadTarget !== void 0) {
35977
+ const parsed = parseQuadShorthand(value2);
35978
+ if (parsed === null) return null;
35979
+ return [
35980
+ { name: quadTarget[0], value: parsed.top },
35981
+ { name: quadTarget[1], value: parsed.right },
35982
+ { name: quadTarget[2], value: parsed.bottom },
35983
+ { name: quadTarget[3], value: parsed.left }
35984
+ ];
35985
+ }
35986
+ const blockTarget = BLOCK_EXPANSIONS.get(property);
35987
+ if (blockTarget !== void 0) {
35988
+ const parsed = parseBlockShorthand(value2);
35989
+ if (parsed === null) return null;
35990
+ return [
35991
+ { name: blockTarget[0], value: parsed.start },
35992
+ { name: blockTarget[1], value: parsed.end }
35993
+ ];
35994
+ }
35995
+ const inlineTarget = INLINE_EXPANSIONS.get(property);
35996
+ if (inlineTarget !== void 0) {
35997
+ const parsed = parseBlockShorthand(value2);
35998
+ if (parsed === null) return null;
35999
+ return [
36000
+ { name: inlineTarget[0], value: parsed.start },
36001
+ { name: inlineTarget[1], value: parsed.end }
36002
+ ];
36003
+ }
36004
+ if (property === "flex-flow") {
36005
+ return expandFlexFlow(value2);
36006
+ }
36007
+ return void 0;
36008
+ }
36009
+ var FLEX_DIRECTION_VALUES = /* @__PURE__ */ new Set(["row", "row-reverse", "column", "column-reverse"]);
36010
+ function expandFlexFlow(value2) {
36011
+ const tokens = splitWhitespaceTokens(value2.trim().toLowerCase());
36012
+ if (tokens.length === 0) return null;
36013
+ if (tokens.length > 2) return null;
36014
+ let direction = null;
36015
+ let wrap = null;
36016
+ for (let i = 0; i < tokens.length; i++) {
36017
+ const token = tokens[i];
36018
+ if (!token) continue;
36019
+ if (FLEX_DIRECTION_VALUES.has(token)) {
36020
+ if (direction !== null) return null;
36021
+ direction = token;
36022
+ } else {
36023
+ if (wrap !== null) return null;
36024
+ wrap = token;
36025
+ }
36026
+ }
36027
+ const out = [];
36028
+ if (direction !== null) {
36029
+ out.push({ name: "flex-direction", value: direction });
36030
+ }
36031
+ if (wrap !== null) {
36032
+ out.push({ name: "flex-wrap", value: wrap });
36033
+ }
36034
+ return out.length > 0 ? out : null;
36035
+ }
36036
+ function getShorthandLonghandNames(property) {
36037
+ const quad = QUAD_EXPANSIONS.get(property);
36038
+ if (quad !== void 0) return [...quad];
36039
+ const block = BLOCK_EXPANSIONS.get(property);
36040
+ if (block !== void 0) return [...block];
36041
+ const inline = INLINE_EXPANSIONS.get(property);
36042
+ if (inline !== void 0) return [...inline];
36043
+ if (property === "flex-flow") return ["flex-direction", "flex-wrap"];
36044
+ return null;
36045
+ }
36046
+
36357
36047
  // src/cross-file/layout/stateful-rule-index.ts
36358
36048
  var EMPTY_STATEFUL_SELECTOR_ENTRY_LIST = [];
36359
36049
  var EMPTY_LAYOUT_NORMALIZED_DECLARATION_LIST = [];
@@ -36571,7 +36261,6 @@ var DYNAMIC_ATTRIBUTE_GUARD = {
36571
36261
  key: "dynamic-attribute:*"
36572
36262
  };
36573
36263
  var SCROLLABLE_VALUES = /* @__PURE__ */ new Set(["auto", "scroll"]);
36574
- var EMPTY_EXPANSION_RESULT = [];
36575
36264
  function collectMonitoredDeclarations(selector, layerOrder, guard) {
36576
36265
  const out = [];
36577
36266
  const declarations = selector.rule.declarations;
@@ -36580,59 +36269,50 @@ function collectMonitoredDeclarations(selector, layerOrder, guard) {
36580
36269
  if (!declaration) continue;
36581
36270
  const property = declaration.property.toLowerCase();
36582
36271
  if (!isMonitoredSignal(property)) continue;
36583
- const monitored = toMonitoredSignalKey(property);
36584
- if (!monitored) continue;
36585
- out.push({
36586
- property: monitored,
36587
- value: declaration.value,
36588
- guardProvenance: guard,
36589
- position: {
36590
- layer: declaration.cascadePosition.layer,
36591
- layerOrder,
36592
- sourceOrder: declaration.sourceOrder,
36593
- specificity: selector.specificity,
36594
- specificityScore: selector.specificityScore,
36595
- isImportant: declaration.cascadePosition.isImportant || declaration.node.important
36272
+ const position = {
36273
+ layer: declaration.cascadePosition.layer,
36274
+ layerOrder,
36275
+ sourceOrder: declaration.sourceOrder,
36276
+ specificity: selector.specificity,
36277
+ specificityScore: selector.specificityScore,
36278
+ isImportant: declaration.cascadePosition.isImportant || declaration.node.important
36279
+ };
36280
+ const directSignal = MONITORED_SIGNAL_NAME_MAP.get(property);
36281
+ if (directSignal !== void 0) {
36282
+ out.push({ property: directSignal, value: declaration.value, guardProvenance: guard, position });
36283
+ continue;
36284
+ }
36285
+ const value2 = declaration.value.trim().toLowerCase();
36286
+ const expanded = expandShorthand(property, value2);
36287
+ if (expanded === void 0) continue;
36288
+ if (expanded === null) {
36289
+ const longhandNames = getShorthandLonghandNames(property);
36290
+ if (longhandNames === null) continue;
36291
+ for (let j = 0; j < longhandNames.length; j++) {
36292
+ const longhand = longhandNames[j];
36293
+ if (!longhand) continue;
36294
+ const signal = MONITORED_SIGNAL_NAME_MAP.get(longhand);
36295
+ if (signal === void 0) continue;
36296
+ out.push({ property: signal, value: declaration.value, guardProvenance: guard, position });
36596
36297
  }
36597
- });
36298
+ continue;
36299
+ }
36300
+ for (let j = 0; j < expanded.length; j++) {
36301
+ const entry = expanded[j];
36302
+ if (!entry) continue;
36303
+ const signal = MONITORED_SIGNAL_NAME_MAP.get(entry.name);
36304
+ if (signal === void 0) continue;
36305
+ out.push({ property: signal, value: entry.value, guardProvenance: guard, position });
36306
+ }
36598
36307
  }
36599
36308
  return out;
36600
36309
  }
36601
- function toMonitoredSignalKey(property) {
36602
- const signal = MONITORED_SIGNAL_NAME_MAP.get(property);
36603
- if (signal) return signal;
36604
- switch (property) {
36605
- case "padding":
36606
- case "border-width":
36607
- case "margin-block":
36608
- case "padding-block":
36609
- case "inset-block":
36610
- case "flex-flow":
36611
- return property;
36612
- default:
36613
- return null;
36614
- }
36615
- }
36616
36310
  function expandMonitoredDeclarationForDelta(declaration) {
36617
- const value2 = declaration.value.trim().toLowerCase();
36618
- const expanded = expandShorthand(declaration.property, value2);
36619
- if (expanded !== void 0) {
36620
- if (expanded === null) return EMPTY_EXPANSION_RESULT;
36621
- const filtered = [];
36622
- for (let i = 0; i < expanded.length; i++) {
36623
- const entry = expanded[i];
36624
- if (!entry) continue;
36625
- const signalName2 = MONITORED_SIGNAL_NAME_MAP.get(entry.name);
36626
- if (signalName2 !== void 0) filtered.push({ name: signalName2, value: entry.value });
36627
- }
36628
- return filtered;
36629
- }
36630
- const signalName = MONITORED_SIGNAL_NAME_MAP.get(declaration.property);
36631
- if (signalName === void 0) return EMPTY_EXPANSION_RESULT;
36632
- return [{ name: signalName, value: value2 }];
36311
+ return [{ name: declaration.property, value: declaration.value.trim().toLowerCase() }];
36633
36312
  }
36634
36313
  function appendMatchingEdgesFromSelectorIds(ctx, selectorIds, node, applies, appliesByElementNodeMutable) {
36635
36314
  const fileRoots = ctx.rootElementsByFile.get(node.solidFile) ?? null;
36315
+ const fileElementIndex = ctx.fileElementIndexByFile.get(node.solidFile) ?? null;
36636
36316
  for (let i = 0; i < selectorIds.length; i++) {
36637
36317
  const selectorId = selectorIds[i];
36638
36318
  if (selectorId === void 0) continue;
@@ -36644,13 +36324,13 @@ function appendMatchingEdgesFromSelectorIds(ctx, selectorIds, node, applies, app
36644
36324
  if (!selector) {
36645
36325
  throw new Error(`missing selector ${selectorId}`);
36646
36326
  }
36647
- const matchResult = selectorMatchesLayoutElement(metadata.matcher, node, ctx.perf, fileRoots, ctx.logger);
36648
- if (matchResult === "no-match") continue;
36327
+ const matchResult = selectorMatchesLayoutElement(metadata.matcher, node, ctx.perf, fileRoots, ctx.logger, fileElementIndex);
36328
+ if (matchResult === 1 /* NoMatch */) continue;
36649
36329
  const edge = {
36650
36330
  selectorId: selector.id,
36651
36331
  specificityScore: selector.specificityScore,
36652
36332
  sourceOrder: selector.rule.sourceOrder,
36653
- conditionalMatch: matchResult === "conditional"
36333
+ conditionalMatch: matchResult === 2 /* Conditional */
36654
36334
  };
36655
36335
  applies.push(edge);
36656
36336
  ctx.perf.matchEdgesCreated++;
@@ -36707,7 +36387,54 @@ function augmentCascadeWithTailwind(cascade, node, tailwind) {
36707
36387
  }
36708
36388
  }
36709
36389
  }
36710
- function buildCascadeMapForElement(node, edges, monitoredDeclarationsBySelectorId, tailwind) {
36390
+ var MAX_VAR_SUBSTITUTION_DEPTH = 10;
36391
+ function resolveVarReferencesInCascade(cascade, variablesByName) {
36392
+ for (const [property, declaration] of cascade) {
36393
+ if (!declaration.value.includes("var(")) continue;
36394
+ const resolved = substituteVarReferences(declaration.value, variablesByName, 0);
36395
+ if (resolved !== declaration.value) {
36396
+ cascade.set(property, {
36397
+ value: resolved,
36398
+ source: declaration.source,
36399
+ guardProvenance: declaration.guardProvenance
36400
+ });
36401
+ }
36402
+ }
36403
+ }
36404
+ function substituteVarReferences(value2, variablesByName, depth) {
36405
+ if (depth >= MAX_VAR_SUBSTITUTION_DEPTH) return value2;
36406
+ const refs = extractVarReferences(value2);
36407
+ if (refs.length === 0) return value2;
36408
+ let result = value2;
36409
+ for (let i = refs.length - 1; i >= 0; i--) {
36410
+ const ref = refs[i];
36411
+ if (!ref) continue;
36412
+ const candidates = variablesByName.get(ref.name);
36413
+ const resolvedValue = candidates !== void 0 && candidates.length > 0 ? selectBestVariableValue(candidates) : ref.fallback;
36414
+ if (resolvedValue === null) continue;
36415
+ result = result.slice(0, ref.sourceIndex) + resolvedValue + result.slice(ref.sourceIndex + ref.raw.length);
36416
+ }
36417
+ if (result !== value2 && result.includes("var(")) {
36418
+ return substituteVarReferences(result, variablesByName, depth + 1);
36419
+ }
36420
+ return result;
36421
+ }
36422
+ function selectBestVariableValue(candidates) {
36423
+ let bestGlobal = null;
36424
+ for (let i = 0; i < candidates.length; i++) {
36425
+ const candidate = candidates[i];
36426
+ if (!candidate) continue;
36427
+ if (candidate.scope.type === "global") {
36428
+ if (bestGlobal === null || candidate.declaration.sourceOrder > bestGlobal.declaration.sourceOrder) {
36429
+ bestGlobal = candidate;
36430
+ }
36431
+ }
36432
+ }
36433
+ if (bestGlobal !== null) return bestGlobal.value;
36434
+ const first = candidates[0];
36435
+ return first ? first.value : null;
36436
+ }
36437
+ function buildCascadeMapForElement(node, edges, monitoredDeclarationsBySelectorId, tailwind, variablesByName) {
36711
36438
  const out = /* @__PURE__ */ new Map();
36712
36439
  const positions = /* @__PURE__ */ new Map();
36713
36440
  for (let i = 0; i < edges.length; i++) {
@@ -36765,6 +36492,9 @@ function buildCascadeMapForElement(node, edges, monitoredDeclarationsBySelectorI
36765
36492
  if (tailwind !== null) {
36766
36493
  augmentCascadeWithTailwind(out, node, tailwind);
36767
36494
  }
36495
+ if (variablesByName !== null) {
36496
+ resolveVarReferencesInCascade(out, variablesByName);
36497
+ }
36768
36498
  return out;
36769
36499
  }
36770
36500
  function compareLayoutEdge(a, b) {
@@ -36805,14 +36535,14 @@ function resolveRuleLayerOrder(rule, css) {
36805
36535
  if (!name) return 0;
36806
36536
  return css.layerOrder.get(name) ?? 0;
36807
36537
  }
36808
- function buildConditionalDeltaIndex(elements, appliesByNode, monitoredDeclarationsBySelectorId, selectorsById) {
36538
+ function buildConditionalDeltaIndex(elements, records, monitoredDeclarationsBySelectorId, selectorsById) {
36809
36539
  const conditionalSignalDeltaFactsByNode = /* @__PURE__ */ new Map();
36810
36540
  const elementsWithConditionalDeltaBySignal = /* @__PURE__ */ new Map();
36811
36541
  const baselineOffsetFactsByNode = /* @__PURE__ */ new Map();
36812
36542
  for (let i = 0; i < elements.length; i++) {
36813
36543
  const node = elements[i];
36814
36544
  if (!node) continue;
36815
- const edges = appliesByNode.get(node);
36545
+ const edges = records.get(node)?.edges;
36816
36546
  let factByProperty = null;
36817
36547
  if (edges !== void 0 && edges.length > 0) {
36818
36548
  const byProperty = /* @__PURE__ */ new Map();
@@ -37167,7 +36897,7 @@ function collectLayoutElementRecordsForSolid(solid, selectorRequirements, inline
37167
36897
  const classTokenSet = classTokens.length === 0 ? EMPTY_CLASS_TOKEN_SET : createClassTokenSet(classTokens);
37168
36898
  const inlineStyleKeys = getStaticStyleKeysForElement(solid, element.id);
37169
36899
  const localAttributes = selectorRequirements.needsAttributes ? collectStaticAttributes(element) : EMPTY_ATTRIBUTES2;
37170
- const attributes = mergeAttributes(localAttributes, meta.resolvedHost?.descriptor.staticAttributes);
36900
+ const attributes = mergeAttributes(localAttributes, meta.resolvedHost?.descriptor.staticAttributes, meta.resolvedHost?.descriptor.attributePropBindings);
37171
36901
  const selectorDispatchKeys = buildSelectorDispatchKeys(attributes, classTokens);
37172
36902
  const inlineStyleValues = inlineStyleValuesByElementId.get(element.id) ?? EMPTY_INLINE_STYLE_VALUES;
37173
36903
  const textualContent = getTextualContentState(element, textContentMemo, compositionMetaByElementId, logger);
@@ -37223,7 +36953,63 @@ function collectCompositionMetaByElementId(solid, componentHostResolver) {
37223
36953
  function resolveHostForElement(componentHostResolver, solidFile, element) {
37224
36954
  if (element.tag === null) return null;
37225
36955
  if (element.isDomElement) return null;
37226
- return componentHostResolver.resolveHost(solidFile, element.tag);
36956
+ const defaultHost = componentHostResolver.resolveHost(solidFile, element.tag);
36957
+ const asTag = extractPolymorphicAsTag(element);
36958
+ if (asTag !== null) {
36959
+ const asHost = componentHostResolver.resolveHost(solidFile, asTag);
36960
+ if (asHost !== null) return composePolymorphicHost(defaultHost, asHost);
36961
+ }
36962
+ return defaultHost;
36963
+ }
36964
+ function extractPolymorphicAsTag(element) {
36965
+ for (let i = 0; i < element.attributes.length; i++) {
36966
+ const attr = element.attributes[i];
36967
+ if (!attr) continue;
36968
+ if (attr.name !== "as") continue;
36969
+ if (attr.valueNode === null) continue;
36970
+ if (!ts124.isJsxExpression(attr.valueNode)) continue;
36971
+ const expression = attr.valueNode.expression;
36972
+ if (!expression) continue;
36973
+ if (ts124.isIdentifier(expression)) return expression.text;
36974
+ if (ts124.isPropertyAccessExpression(expression)) return expression.getText();
36975
+ return null;
36976
+ }
36977
+ return null;
36978
+ }
36979
+ function composePolymorphicHost(outerHost, asHost) {
36980
+ if (outerHost === null) return asHost;
36981
+ const outerDesc = outerHost.descriptor;
36982
+ const asDesc = asHost.descriptor;
36983
+ const staticAttributes = /* @__PURE__ */ new Map();
36984
+ for (const [name, value2] of outerDesc.staticAttributes) staticAttributes.set(name, value2);
36985
+ for (const [name, value2] of asDesc.staticAttributes) staticAttributes.set(name, value2);
36986
+ const classTokenSet = /* @__PURE__ */ new Set();
36987
+ const staticClassTokens = [];
36988
+ for (const token of outerDesc.staticClassTokens) {
36989
+ if (!classTokenSet.has(token)) {
36990
+ classTokenSet.add(token);
36991
+ staticClassTokens.push(token);
36992
+ }
36993
+ }
36994
+ for (const token of asDesc.staticClassTokens) {
36995
+ if (!classTokenSet.has(token)) {
36996
+ classTokenSet.add(token);
36997
+ staticClassTokens.push(token);
36998
+ }
36999
+ }
37000
+ const attributePropBindings = /* @__PURE__ */ new Map();
37001
+ for (const [name, value2] of outerDesc.attributePropBindings) attributePropBindings.set(name, value2);
37002
+ for (const [name, value2] of asDesc.attributePropBindings) attributePropBindings.set(name, value2);
37003
+ return {
37004
+ descriptor: {
37005
+ tagName: asDesc.tagName ?? outerDesc.tagName,
37006
+ staticAttributes,
37007
+ staticClassTokens,
37008
+ forwardsChildren: asDesc.forwardsChildren || outerDesc.forwardsChildren,
37009
+ attributePropBindings
37010
+ },
37011
+ hostElementRef: asHost.hostElementRef ?? outerHost.hostElementRef
37012
+ };
37227
37013
  }
37228
37014
  function resolveTransparentPrimitiveStatus(componentHostResolver, solidFile, element, resolvedHost) {
37229
37015
  if (element.tag === null) return false;
@@ -37266,11 +37052,21 @@ function mergeClassTokens(localTokens, hostTokens) {
37266
37052
  }
37267
37053
  return out;
37268
37054
  }
37269
- function mergeAttributes(localAttributes, hostAttributes) {
37055
+ function mergeAttributes(localAttributes, hostAttributes, propBindings) {
37270
37056
  if (hostAttributes === void 0 || hostAttributes.size === 0) return localAttributes;
37271
- if (localAttributes.size === 0) return hostAttributes;
37057
+ if (localAttributes.size === 0 && (propBindings === void 0 || propBindings.size === 0)) return hostAttributes;
37272
37058
  const out = /* @__PURE__ */ new Map();
37273
37059
  for (const [name, value2] of hostAttributes) {
37060
+ if (propBindings !== void 0) {
37061
+ const propName = propBindings.get(name);
37062
+ if (propName !== void 0) {
37063
+ const callSiteValue = localAttributes.get(propName);
37064
+ if (callSiteValue !== void 0 && callSiteValue !== null) {
37065
+ out.set(name, callSiteValue);
37066
+ continue;
37067
+ }
37068
+ }
37069
+ }
37274
37070
  out.set(name, value2);
37275
37071
  }
37276
37072
  for (const [name, value2] of localAttributes) {
@@ -37336,7 +37132,9 @@ function resolveSiblingTypeCount(totalsByParentId, parentElementId, tagName, sib
37336
37132
 
37337
37133
  // src/cross-file/layout/build.ts
37338
37134
  var EMPTY_NUMBER_LIST2 = [];
37339
- var NON_RESERVING_DIMENSION_KEYWORDS = /* @__PURE__ */ new Set(["auto", "none", "fit-content", "min-content", "max-content", "stretch"]);
37135
+ var EMPTY_EDGE_LIST = Object.freeze([]);
37136
+ var NON_RESERVING_DIMENSION_KEYWORDS = /* @__PURE__ */ new Set(["auto", "none", "fit-content", "min-content", "max-content", "stretch", "inherit", "initial", "unset", "revert", "revert-layer"]);
37137
+ var BLOCK_LEVEL_DISPLAY_VALUES = /* @__PURE__ */ new Set(["block", "flex", "grid", "table", "list-item", "flow-root", "table-row", "table-cell", "table-caption", "table-row-group", "table-header-group", "table-footer-group", "table-column", "table-column-group"]);
37340
37138
  function buildLayoutGraph(solids, css, logger = noopLogger) {
37341
37139
  const perf = createLayoutPerfStats();
37342
37140
  const startedAt = performance.now();
@@ -37351,7 +37149,6 @@ function buildLayoutGraph(solids, css, logger = noopLogger) {
37351
37149
  const selectorsById = /* @__PURE__ */ new Map();
37352
37150
  const monitoredDeclarationsBySelectorId = /* @__PURE__ */ new Map();
37353
37151
  const selectorMetadataById = /* @__PURE__ */ new Map();
37354
- const cascadeByElementNode = /* @__PURE__ */ new WeakMap();
37355
37152
  for (let i = 0; i < css.selectors.length; i++) {
37356
37153
  const selector = css.selectors[i];
37357
37154
  if (!selector) continue;
@@ -37424,7 +37221,7 @@ function buildLayoutGraph(solids, css, logger = noopLogger) {
37424
37221
  };
37425
37222
  const textContentMemo = /* @__PURE__ */ new Map();
37426
37223
  const inlineStyleValuesByElementId = collectInlineStyleValuesByElementId(solid);
37427
- const records = collectLayoutElementRecordsForSolid(
37224
+ const records2 = collectLayoutElementRecordsForSolid(
37428
37225
  solid,
37429
37226
  selectorRequirements,
37430
37227
  inlineStyleValuesByElementId,
@@ -37432,12 +37229,12 @@ function buildLayoutGraph(solids, css, logger = noopLogger) {
37432
37229
  componentHostResolver,
37433
37230
  logger
37434
37231
  );
37435
- const siblingTotals = collectSiblingTotals(records);
37232
+ const siblingTotals = collectSiblingTotals(records2);
37436
37233
  const nodeByElementId = /* @__PURE__ */ new Map();
37437
37234
  const lastChildByParentId = /* @__PURE__ */ new Map();
37438
37235
  const siblingTypeSeenByParentId = /* @__PURE__ */ new Map();
37439
- for (let i = 0; i < records.length; i++) {
37440
- const record = records[i];
37236
+ for (let i = 0; i < records2.length; i++) {
37237
+ const record = records2[i];
37441
37238
  if (!record) continue;
37442
37239
  const parentElementId = record.parentElementId;
37443
37240
  const parentNode = parentElementId === null ? null : nodeByElementId.get(parentElementId) ?? null;
@@ -37502,6 +37299,7 @@ function buildLayoutGraph(solids, css, logger = noopLogger) {
37502
37299
  }
37503
37300
  }
37504
37301
  }
37302
+ const fileElementIndexByFile = buildFileElementIndexByFile(elements);
37505
37303
  if (logger.isLevelEnabled(Level.Debug)) {
37506
37304
  for (const [file, roots] of rootElementsByFile) {
37507
37305
  const descs = roots.map((r) => `${r.key}(tag=${r.tagName}, attrs=[${[...r.attributes.entries()].map(([k, v]) => `${k}=${v}`).join(",")}])`);
@@ -37513,63 +37311,138 @@ function buildLayoutGraph(solids, css, logger = noopLogger) {
37513
37311
  selectorMetadataById,
37514
37312
  selectorsById,
37515
37313
  rootElementsByFile,
37314
+ fileElementIndexByFile,
37516
37315
  perf,
37517
37316
  logger
37518
37317
  };
37519
- for (let i = 0; i < elements.length; i++) {
37520
- const node = elements[i];
37521
- if (!node) continue;
37522
- const selectorIds = selectorCandidatesByNode.get(node) ?? EMPTY_NUMBER_LIST2;
37523
- if (selectorIds.length === 0) continue;
37524
- appendMatchingEdgesFromSelectorIds(
37525
- selectorMatchCtx,
37526
- selectorIds,
37527
- node,
37528
- applies,
37529
- appliesByElementNodeMutable
37530
- );
37531
- }
37532
- perf.selectorMatchMs = performance.now() - selectorMatchStartedAt;
37533
- const cascadeStartedAt = performance.now();
37534
- for (const edges of appliesByElementNodeMutable.values()) {
37535
- edges.sort(compareLayoutEdge);
37536
- }
37537
- const appliesByNode = /* @__PURE__ */ new Map();
37538
37318
  const tailwind = css.tailwind;
37319
+ const records = /* @__PURE__ */ new Map();
37320
+ const snapshotByElementNode = /* @__PURE__ */ new WeakMap();
37321
+ const snapshotHotSignalsByNode = /* @__PURE__ */ new Map();
37322
+ const elementsByTagName = /* @__PURE__ */ new Map();
37323
+ const elementsByKnownSignalValue = /* @__PURE__ */ new Map();
37324
+ const dynamicSlotCandidateElements = [];
37325
+ const scrollContainerElements = [];
37326
+ const positionedAncestorByKey = /* @__PURE__ */ new Map();
37327
+ const trace = logger.isLevelEnabled(Level.Trace);
37539
37328
  for (let i = 0; i < elements.length; i++) {
37540
37329
  const node = elements[i];
37541
37330
  if (!node) continue;
37542
- const edges = appliesByElementNodeMutable.get(node) ?? [];
37543
- const cascade = buildCascadeMapForElement(node, edges, monitoredDeclarationsBySelectorId, tailwind);
37544
- cascadeByElementNode.set(node, cascade);
37545
- appliesByNode.set(node, edges);
37546
- }
37547
- perf.cascadeBuildMs = performance.now() - cascadeStartedAt;
37548
- if (logger.isLevelEnabled(Level.Trace)) {
37549
- for (let i = 0; i < elements.length; i++) {
37550
- const node = elements[i];
37551
- if (!node) continue;
37552
- const cascade = cascadeByElementNode.get(node);
37553
- if (!cascade || cascade.size === 0) continue;
37331
+ const selectorIds = selectorCandidatesByNode.get(node) ?? EMPTY_NUMBER_LIST2;
37332
+ if (selectorIds.length > 0) {
37333
+ appendMatchingEdgesFromSelectorIds(
37334
+ selectorMatchCtx,
37335
+ selectorIds,
37336
+ node,
37337
+ applies,
37338
+ appliesByElementNodeMutable
37339
+ );
37340
+ }
37341
+ const mutableEdges = appliesByElementNodeMutable.get(node);
37342
+ if (mutableEdges) mutableEdges.sort(compareLayoutEdge);
37343
+ const edges = mutableEdges ?? EMPTY_EDGE_LIST;
37344
+ const cascade = buildCascadeMapForElement(node, edges, monitoredDeclarationsBySelectorId, tailwind, css.variablesByName);
37345
+ if (trace && cascade.size > 0) {
37554
37346
  const displayDecl = cascade.get("display");
37555
37347
  const flexDirDecl = cascade.get("flex-direction");
37556
- if (!displayDecl && !flexDirDecl) continue;
37557
- const displayGuard = displayDecl?.guardProvenance.kind === 1 /* Conditional */ ? "conditional" : "unconditional";
37558
- const flexDirGuard = flexDirDecl?.guardProvenance.kind === 1 /* Conditional */ ? "conditional" : "unconditional";
37559
- logger.trace(
37560
- `[cascade] node=${node.key} tag=${node.tagName ?? "null"} display=${displayDecl ? `${displayDecl.value}(${displayGuard})` : "absent"} flex-direction=${flexDirDecl ? `${flexDirDecl.value}(${flexDirGuard})` : "absent"} edges=${(appliesByNode.get(node) ?? []).length} attrs=[${[...node.attributes.keys()].join(",")}]`
37561
- );
37348
+ if (displayDecl || flexDirDecl) {
37349
+ const displayGuard = displayDecl?.guardProvenance.kind === 1 /* Conditional */ ? "conditional" : "unconditional";
37350
+ const flexDirGuard = flexDirDecl?.guardProvenance.kind === 1 /* Conditional */ ? "conditional" : "unconditional";
37351
+ logger.trace(
37352
+ `[cascade] node=${node.key} tag=${node.tagName ?? "null"} display=${displayDecl ? `${displayDecl.value}(${displayGuard})` : "absent"} flex-direction=${flexDirDecl ? `${flexDirDecl.value}(${flexDirGuard})` : "absent"} edges=${edges.length} attrs=[${[...node.attributes.keys()].join(",")}]`
37353
+ );
37354
+ }
37355
+ }
37356
+ const parentSnapshot = node.parentElementNode ? records.get(node.parentElementNode)?.snapshot ?? null : null;
37357
+ const snapshot = buildSnapshotFromCascade(node, cascade, parentSnapshot);
37358
+ snapshotByElementNode.set(node, snapshot);
37359
+ perf.signalSnapshotsBuilt++;
37360
+ if (node.textualContent === 2 /* Unknown */ && node.siblingCount >= 2) {
37361
+ dynamicSlotCandidateElements.push(node);
37362
+ }
37363
+ if (node.tagName) {
37364
+ const existing = elementsByTagName.get(node.tagName);
37365
+ if (existing) existing.push(node);
37366
+ else elementsByTagName.set(node.tagName, [node]);
37367
+ }
37368
+ for (const [signal, value2] of snapshot.signals) {
37369
+ if (value2.kind !== 0 /* Known */) continue;
37370
+ let byValue = elementsByKnownSignalValue.get(signal);
37371
+ if (!byValue) {
37372
+ byValue = /* @__PURE__ */ new Map();
37373
+ elementsByKnownSignalValue.set(signal, byValue);
37374
+ }
37375
+ const existingNodes = byValue.get(value2.normalized);
37376
+ if (existingNodes) existingNodes.push(node);
37377
+ else byValue.set(value2.normalized, [node]);
37562
37378
  }
37379
+ const parentKey = node.parentElementNode?.key ?? null;
37380
+ let nearestPositionedAncestorKey = null;
37381
+ let nearestPositionedAncestorHasReservedSpace = false;
37382
+ if (parentKey !== null) {
37383
+ const parentPositioned = positionedAncestorByKey.get(parentKey);
37384
+ if (parentPositioned !== void 0) {
37385
+ nearestPositionedAncestorKey = parentPositioned.key;
37386
+ nearestPositionedAncestorHasReservedSpace = parentPositioned.hasReservedSpace;
37387
+ }
37388
+ }
37389
+ const containingBlock = {
37390
+ nearestPositionedAncestorKey,
37391
+ nearestPositionedAncestorHasReservedSpace
37392
+ };
37393
+ const reservedSpace = computeReservedSpaceFact(snapshot);
37394
+ const scrollContainer = computeScrollContainerFact(snapshot);
37395
+ if (scrollContainer.isScrollContainer) scrollContainerElements.push(node);
37396
+ const flowParticipation = computeFlowParticipationFact(snapshot);
37397
+ const hotSignals = computeHotSignals(snapshot);
37398
+ snapshotHotSignalsByNode.set(node, hotSignals);
37399
+ const positionSignal = snapshot.signals.get("position");
37400
+ const isPositioned = positionSignal !== void 0 && positionSignal.kind === 0 /* Known */ && positionSignal.normalized !== "static";
37401
+ if (isPositioned) {
37402
+ positionedAncestorByKey.set(node.key, { key: node.key, hasReservedSpace: reservedSpace.hasReservedSpace });
37403
+ } else if (parentKey !== null) {
37404
+ const inherited = positionedAncestorByKey.get(parentKey);
37405
+ if (inherited !== void 0) positionedAncestorByKey.set(node.key, inherited);
37406
+ }
37407
+ records.set(node, {
37408
+ ref: elementRefsBySolidFileAndIdMutable.get(node.solidFile)?.get(node.elementId) ?? null,
37409
+ edges,
37410
+ cascade,
37411
+ snapshot,
37412
+ hotSignals,
37413
+ reservedSpace,
37414
+ scrollContainer,
37415
+ flowParticipation,
37416
+ containingBlock,
37417
+ conditionalDelta: null,
37418
+ baselineOffsets: null
37419
+ });
37563
37420
  }
37564
- const snapshotByElementNode = buildSignalSnapshotIndex(elements, cascadeByElementNode, perf);
37565
- const measurementNodeByRootKey = buildMeasurementNodeIndex(elements, childrenByParentNodeMutable, snapshotByElementNode);
37566
- const factIndex = buildElementFactIndex(elements, snapshotByElementNode);
37421
+ perf.selectorMatchMs = performance.now() - selectorMatchStartedAt;
37567
37422
  const conditionalDeltaIndex = buildConditionalDeltaIndex(
37568
37423
  elements,
37569
- appliesByNode,
37424
+ records,
37570
37425
  monitoredDeclarationsBySelectorId,
37571
37426
  selectorsById
37572
37427
  );
37428
+ for (const [node, deltaByProperty] of conditionalDeltaIndex.conditionalSignalDeltaFactsByNode) {
37429
+ const record = records.get(node);
37430
+ if (!record) continue;
37431
+ const baselineOffsets = conditionalDeltaIndex.baselineOffsetFactsByNode.get(node) ?? null;
37432
+ records.set(node, {
37433
+ ref: record.ref,
37434
+ edges: record.edges,
37435
+ cascade: record.cascade,
37436
+ snapshot: record.snapshot,
37437
+ hotSignals: record.hotSignals,
37438
+ reservedSpace: record.reservedSpace,
37439
+ scrollContainer: record.scrollContainer,
37440
+ flowParticipation: record.flowParticipation,
37441
+ containingBlock: record.containingBlock,
37442
+ conditionalDelta: deltaByProperty,
37443
+ baselineOffsets
37444
+ });
37445
+ }
37573
37446
  const elementsWithConditionalOverflowDelta = buildConditionalDeltaSignalGroupElements(
37574
37447
  conditionalDeltaIndex.elementsWithConditionalDeltaBySignal,
37575
37448
  ["overflow", "overflow-y"]
@@ -37578,6 +37451,7 @@ function buildLayoutGraph(solids, css, logger = noopLogger) {
37578
37451
  conditionalDeltaIndex.elementsWithConditionalDeltaBySignal,
37579
37452
  layoutOffsetSignals
37580
37453
  );
37454
+ const measurementNodeByRootKey = buildMeasurementNodeIndex(elements, childrenByParentNodeMutable, snapshotByElementNode);
37581
37455
  const statefulRuleIndexes = buildStatefulRuleIndexes(css.rules);
37582
37456
  const contextByParentNode = buildContextIndex(childrenByParentNodeMutable, snapshotByElementNode, perf, logger);
37583
37457
  const cohortIndex = buildCohortIndex({
@@ -37585,7 +37459,7 @@ function buildLayoutGraph(solids, css, logger = noopLogger) {
37585
37459
  contextByParentNode,
37586
37460
  measurementNodeByRootKey,
37587
37461
  snapshotByElementNode,
37588
- snapshotHotSignalsByNode: factIndex.snapshotHotSignalsByNode
37462
+ snapshotHotSignalsByNode
37589
37463
  });
37590
37464
  finalizeTableCellBaselineRelevance(contextByParentNode, cohortIndex.verticalAlignConsensusByParent);
37591
37465
  perf.conditionalSignals = cohortIndex.conditionalSignals;
@@ -37602,122 +37476,71 @@ function buildLayoutGraph(solids, css, logger = noopLogger) {
37602
37476
  elementBySolidFileAndId: elementBySolidFileAndIdMutable,
37603
37477
  elementRefsBySolidFileAndId: elementRefsBySolidFileAndIdMutable,
37604
37478
  hostElementRefsByNode: hostElementRefsByNodeMutable,
37605
- appliesByNode,
37606
37479
  selectorCandidatesByNode,
37607
37480
  selectorsById,
37608
37481
  measurementNodeByRootKey,
37609
- snapshotHotSignalsByNode: factIndex.snapshotHotSignalsByNode,
37610
- elementsByTagName: factIndex.elementsByTagName,
37482
+ records,
37483
+ elementsByTagName,
37611
37484
  elementsWithConditionalDeltaBySignal: conditionalDeltaIndex.elementsWithConditionalDeltaBySignal,
37612
37485
  elementsWithConditionalOverflowDelta,
37613
37486
  elementsWithConditionalOffsetDelta,
37614
- elementsByKnownSignalValue: factIndex.elementsByKnownSignalValue,
37615
- dynamicSlotCandidateElements: factIndex.dynamicSlotCandidateElements,
37616
- scrollContainerElements: factIndex.scrollContainerElements,
37617
- reservedSpaceFactsByNode: factIndex.reservedSpaceFactsByNode,
37618
- scrollContainerFactsByNode: factIndex.scrollContainerFactsByNode,
37619
- flowParticipationFactsByNode: factIndex.flowParticipationFactsByNode,
37620
- containingBlockFactsByNode: factIndex.containingBlockFactsByNode,
37621
- conditionalSignalDeltaFactsByNode: conditionalDeltaIndex.conditionalSignalDeltaFactsByNode,
37622
- baselineOffsetFactsByNode: conditionalDeltaIndex.baselineOffsetFactsByNode,
37487
+ elementsByKnownSignalValue,
37488
+ dynamicSlotCandidateElements,
37489
+ scrollContainerElements,
37623
37490
  statefulSelectorEntriesByRuleId: statefulRuleIndexes.selectorEntriesByRuleId,
37624
37491
  statefulNormalizedDeclarationsByRuleId: statefulRuleIndexes.normalizedDeclarationsByRuleId,
37625
37492
  statefulBaseValueIndex: statefulRuleIndexes.baseValueIndex,
37626
37493
  cohortStatsByParentNode: cohortIndex.statsByParentNode,
37627
- cascadeByElementNode,
37628
- snapshotByElementNode,
37629
37494
  contextByParentNode,
37630
37495
  perf
37631
37496
  };
37632
37497
  }
37633
- function buildElementFactIndex(elements, snapshotByElementNode) {
37634
- const reservedSpaceFactsByNode = /* @__PURE__ */ new Map();
37635
- const scrollContainerFactsByNode = /* @__PURE__ */ new Map();
37636
- const flowParticipationFactsByNode = /* @__PURE__ */ new Map();
37637
- const containingBlockFactsByNode = /* @__PURE__ */ new Map();
37638
- const snapshotHotSignalsByNode = /* @__PURE__ */ new Map();
37639
- const elementsByTagName = /* @__PURE__ */ new Map();
37640
- const elementsByKnownSignalValue = /* @__PURE__ */ new Map();
37641
- const dynamicSlotCandidateElements = [];
37642
- const scrollContainerElements = [];
37643
- const positionedAncestorByKey = /* @__PURE__ */ new Map();
37498
+ function buildFileElementIndexByFile(elements) {
37499
+ const byFileDispatch = /* @__PURE__ */ new Map();
37500
+ const byFileTag = /* @__PURE__ */ new Map();
37644
37501
  for (let i = 0; i < elements.length; i++) {
37645
37502
  const node = elements[i];
37646
37503
  if (!node) continue;
37647
- const snapshot = snapshotByElementNode.get(node);
37648
- if (node.textualContent === 2 /* Unknown */ && node.siblingCount >= 2) {
37649
- dynamicSlotCandidateElements.push(node);
37650
- }
37651
- if (node.tagName) {
37652
- const existing = elementsByTagName.get(node.tagName);
37504
+ if (node.parentElementNode === null) continue;
37505
+ const file = node.solidFile;
37506
+ let dispatchMap = byFileDispatch.get(file);
37507
+ if (!dispatchMap) {
37508
+ dispatchMap = /* @__PURE__ */ new Map();
37509
+ byFileDispatch.set(file, dispatchMap);
37510
+ }
37511
+ const keys = node.selectorDispatchKeys;
37512
+ for (let j = 0; j < keys.length; j++) {
37513
+ const key = keys[j];
37514
+ if (!key) continue;
37515
+ const existing = dispatchMap.get(key);
37653
37516
  if (existing) {
37654
37517
  existing.push(node);
37655
37518
  } else {
37656
- elementsByTagName.set(node.tagName, [node]);
37519
+ dispatchMap.set(key, [node]);
37657
37520
  }
37658
37521
  }
37659
- const parentKey = node.parentElementNode?.key ?? null;
37660
- let nearestPositionedAncestorKey = null;
37661
- let nearestPositionedAncestorHasReservedSpace = false;
37662
- if (parentKey !== null) {
37663
- const parentPositioned = positionedAncestorByKey.get(parentKey);
37664
- if (parentPositioned !== void 0) {
37665
- nearestPositionedAncestorKey = parentPositioned.key;
37666
- nearestPositionedAncestorHasReservedSpace = parentPositioned.hasReservedSpace;
37522
+ if (node.tagName !== null) {
37523
+ let tagMap = byFileTag.get(file);
37524
+ if (!tagMap) {
37525
+ tagMap = /* @__PURE__ */ new Map();
37526
+ byFileTag.set(file, tagMap);
37667
37527
  }
37668
- }
37669
- containingBlockFactsByNode.set(node, {
37670
- nearestPositionedAncestorKey,
37671
- nearestPositionedAncestorHasReservedSpace
37672
- });
37673
- if (!snapshot) continue;
37674
- const reservedSpaceFact = computeReservedSpaceFact(snapshot);
37675
- reservedSpaceFactsByNode.set(node, reservedSpaceFact);
37676
- const scrollFact = computeScrollContainerFact(snapshot);
37677
- scrollContainerFactsByNode.set(node, scrollFact);
37678
- if (scrollFact.isScrollContainer) scrollContainerElements.push(node);
37679
- flowParticipationFactsByNode.set(node, computeFlowParticipationFact(snapshot));
37680
- snapshotHotSignalsByNode.set(node, computeHotSignals(snapshot));
37681
- const positionSignal = snapshot.signals.get("position");
37682
- const isPositioned = positionSignal !== void 0 && positionSignal.kind === "known" && positionSignal.normalized !== "static";
37683
- if (isPositioned) {
37684
- positionedAncestorByKey.set(node.key, {
37685
- key: node.key,
37686
- hasReservedSpace: reservedSpaceFact.hasReservedSpace
37687
- });
37688
- } else if (parentKey !== null) {
37689
- const inherited = positionedAncestorByKey.get(parentKey);
37690
- if (inherited !== void 0) {
37691
- positionedAncestorByKey.set(node.key, inherited);
37692
- }
37693
- }
37694
- for (const [signal, value2] of snapshot.signals) {
37695
- if (value2.kind !== "known") continue;
37696
- const normalized = value2.normalized;
37697
- let byValue = elementsByKnownSignalValue.get(signal);
37698
- if (!byValue) {
37699
- byValue = /* @__PURE__ */ new Map();
37700
- elementsByKnownSignalValue.set(signal, byValue);
37701
- }
37702
- const existingNodes = byValue.get(normalized);
37703
- if (existingNodes) {
37704
- existingNodes.push(node);
37528
+ const existing = tagMap.get(node.tagName);
37529
+ if (existing) {
37530
+ existing.push(node);
37705
37531
  } else {
37706
- byValue.set(normalized, [node]);
37532
+ tagMap.set(node.tagName, [node]);
37707
37533
  }
37708
37534
  }
37709
37535
  }
37710
- return {
37711
- reservedSpaceFactsByNode,
37712
- scrollContainerFactsByNode,
37713
- scrollContainerElements,
37714
- flowParticipationFactsByNode,
37715
- containingBlockFactsByNode,
37716
- snapshotHotSignalsByNode,
37717
- elementsByTagName,
37718
- elementsByKnownSignalValue,
37719
- dynamicSlotCandidateElements
37720
- };
37536
+ const out = /* @__PURE__ */ new Map();
37537
+ for (const [file, dispatchMap] of byFileDispatch) {
37538
+ out.set(file, {
37539
+ byDispatchKey: dispatchMap,
37540
+ byTagName: byFileTag.get(file) ?? /* @__PURE__ */ new Map()
37541
+ });
37542
+ }
37543
+ return out;
37721
37544
  }
37722
37545
  var ABSENT_NUMERIC = Object.freeze({
37723
37546
  present: false,
@@ -37730,7 +37553,7 @@ var ABSENT_NORMALIZED = Object.freeze({
37730
37553
  kind: 3 /* Unknown */
37731
37554
  });
37732
37555
  function toHotNumeric(signal) {
37733
- if (signal.kind !== "known") {
37556
+ if (signal.kind !== 0 /* Known */) {
37734
37557
  return {
37735
37558
  present: true,
37736
37559
  value: null,
@@ -37740,11 +37563,11 @@ function toHotNumeric(signal) {
37740
37563
  return {
37741
37564
  present: true,
37742
37565
  value: signal.px,
37743
- kind: signal.guard.kind === 1 /* Conditional */ ? 2 /* Conditional */ : signal.quality === "estimated" ? 1 /* Interval */ : 0 /* Exact */
37566
+ kind: signal.guard.kind === 1 /* Conditional */ ? 2 /* Conditional */ : signal.quality === 1 /* Estimated */ ? 1 /* Interval */ : 0 /* Exact */
37744
37567
  };
37745
37568
  }
37746
37569
  function toHotNormalized(signal) {
37747
- if (signal.kind !== "known") {
37570
+ if (signal.kind !== 0 /* Known */) {
37748
37571
  return {
37749
37572
  present: true,
37750
37573
  value: null,
@@ -37754,7 +37577,7 @@ function toHotNormalized(signal) {
37754
37577
  return {
37755
37578
  present: true,
37756
37579
  value: signal.normalized,
37757
- kind: signal.guard.kind === 1 /* Conditional */ ? 2 /* Conditional */ : signal.quality === "estimated" ? 1 /* Interval */ : 0 /* Exact */
37580
+ kind: signal.guard.kind === 1 /* Conditional */ ? 2 /* Conditional */ : signal.quality === 1 /* Estimated */ ? 1 /* Interval */ : 0 /* Exact */
37758
37581
  };
37759
37582
  }
37760
37583
  function computeHotSignals(snapshot) {
@@ -37869,62 +37692,61 @@ function computeHotSignals(snapshot) {
37869
37692
  }
37870
37693
  function computeReservedSpaceFact(snapshot) {
37871
37694
  const reasons = [];
37872
- const hasHeight = hasPositiveOrDeclaredDimension(snapshot, "height");
37695
+ const hasHeight = hasDeclaredDimension(snapshot, "height");
37873
37696
  if (hasHeight) reasons.push("height");
37874
- const hasBlockSize = hasPositiveOrDeclaredDimension(snapshot, "block-size");
37697
+ const hasBlockSize = hasDeclaredDimension(snapshot, "block-size");
37875
37698
  if (hasBlockSize) reasons.push("block-size");
37876
- const hasMinHeight = hasPositiveOrDeclaredDimension(snapshot, "min-height");
37699
+ const hasMinHeight = hasDeclaredDimension(snapshot, "min-height");
37877
37700
  if (hasMinHeight) reasons.push("min-height");
37878
- const hasMinBlockSize = hasPositiveOrDeclaredDimension(snapshot, "min-block-size");
37701
+ const hasMinBlockSize = hasDeclaredDimension(snapshot, "min-block-size");
37879
37702
  if (hasMinBlockSize) reasons.push("min-block-size");
37880
- const hasContainIntrinsic = hasPositiveOrDeclaredDimension(snapshot, "contain-intrinsic-size");
37703
+ const hasContainIntrinsic = hasDeclaredDimension(snapshot, "contain-intrinsic-size");
37881
37704
  if (hasContainIntrinsic) reasons.push("contain-intrinsic-size");
37882
37705
  const hasAspectRatio = hasUsableAspectRatio(snapshot);
37883
37706
  if (hasAspectRatio) {
37884
- if (hasPositiveOrDeclaredDimension(snapshot, "width")) reasons.push("aspect-ratio+width");
37885
- if (hasPositiveOrDeclaredDimension(snapshot, "inline-size")) reasons.push("aspect-ratio+inline-size");
37886
- if (hasPositiveOrDeclaredDimension(snapshot, "min-width")) reasons.push("aspect-ratio+min-width");
37707
+ if (hasDeclaredDimension(snapshot, "width")) reasons.push("aspect-ratio+width");
37708
+ if (hasDeclaredDimension(snapshot, "inline-size")) reasons.push("aspect-ratio+inline-size");
37709
+ if (hasDeclaredDimension(snapshot, "min-width")) reasons.push("aspect-ratio+min-width");
37887
37710
  if (hasMinBlockSize) reasons.push("aspect-ratio+min-block-size");
37888
37711
  if (hasMinHeight) reasons.push("aspect-ratio+min-height");
37889
37712
  }
37890
37713
  return {
37891
37714
  hasReservedSpace: reasons.length > 0,
37892
37715
  reasons,
37893
- hasUsableInlineDimension: hasPositiveOrDeclaredDimension(snapshot, "width") || hasPositiveOrDeclaredDimension(snapshot, "inline-size") || hasPositiveOrDeclaredDimension(snapshot, "min-width"),
37894
- hasUsableBlockDimension: hasHeight || hasBlockSize || hasMinHeight || hasMinBlockSize,
37895
37716
  hasContainIntrinsicSize: hasContainIntrinsic,
37896
- hasUsableAspectRatio: hasAspectRatio
37717
+ hasUsableAspectRatio: hasAspectRatio,
37718
+ hasDeclaredBlockDimension: hasHeight || hasBlockSize || hasMinHeight || hasMinBlockSize,
37719
+ hasDeclaredInlineDimension: hasDeclaredDimension(snapshot, "width") || hasDeclaredDimension(snapshot, "inline-size") || hasDeclaredDimension(snapshot, "min-width") || hasDeclaredDimension(snapshot, "flex-basis") || isBlockLevelDisplay(snapshot)
37897
37720
  };
37898
37721
  }
37899
- function hasPositiveOrDeclaredDimension(snapshot, property) {
37722
+ function hasDeclaredDimension(snapshot, property) {
37900
37723
  const signal = snapshot.signals.get(property);
37901
37724
  if (!signal) return false;
37902
- if (signal.guard.kind !== 0 /* Unconditional */) return false;
37903
- let normalized = "";
37904
- if (signal.kind === "known") {
37725
+ if (signal.kind === 0 /* Known */) {
37905
37726
  if (signal.px !== null) return signal.px > 0;
37906
- normalized = signal.normalized.trim().toLowerCase();
37727
+ if (signal.normalized.length === 0) return false;
37728
+ return !isNonReservingDimension(signal.normalized);
37907
37729
  }
37908
- if (signal.kind === "unknown") {
37730
+ if (signal.kind === 1 /* Unknown */) {
37909
37731
  return signal.source !== null;
37910
37732
  }
37911
- if (normalized.length === 0) return false;
37912
- if (isNonReservingDimension(normalized)) return false;
37913
- return true;
37733
+ return false;
37734
+ }
37735
+ function isBlockLevelDisplay(snapshot) {
37736
+ const signal = snapshot.signals.get("display");
37737
+ if (!signal || signal.kind !== 0 /* Known */) return false;
37738
+ return BLOCK_LEVEL_DISPLAY_VALUES.has(signal.normalized);
37914
37739
  }
37915
37740
  function hasUsableAspectRatio(snapshot) {
37916
37741
  const signal = snapshot.signals.get("aspect-ratio");
37917
37742
  if (!signal) return false;
37918
37743
  if (signal.guard.kind !== 0 /* Unconditional */) return false;
37919
- if (signal.kind === "unknown") {
37744
+ if (signal.kind === 1 /* Unknown */) {
37920
37745
  return false;
37921
37746
  }
37922
- let normalized = "";
37923
- if (signal.kind === "known") {
37924
- normalized = signal.normalized.trim().toLowerCase();
37925
- }
37926
- if (normalized.length === 0) return false;
37927
- return normalized !== "auto";
37747
+ if (signal.kind !== 0 /* Known */) return false;
37748
+ if (signal.normalized.length === 0) return false;
37749
+ return signal.normalized !== "auto";
37928
37750
  }
37929
37751
  function isNonReservingDimension(value2) {
37930
37752
  if (NON_RESERVING_DIMENSION_KEYWORDS.has(value2)) return true;
@@ -37934,8 +37756,8 @@ function isNonReservingDimension(value2) {
37934
37756
  function computeScrollContainerFact(snapshot) {
37935
37757
  const overflowSignal = snapshot.signals.get("overflow");
37936
37758
  const overflowYSignal = snapshot.signals.get("overflow-y");
37937
- const overflow = overflowSignal && overflowSignal.kind === "known" ? overflowSignal.normalized : null;
37938
- const overflowY = overflowYSignal && overflowYSignal.kind === "known" ? overflowYSignal.normalized : null;
37759
+ const overflow = overflowSignal && overflowSignal.kind === 0 /* Known */ ? overflowSignal.normalized : null;
37760
+ const overflowY = overflowYSignal && overflowYSignal.kind === 0 /* Known */ ? overflowYSignal.normalized : null;
37939
37761
  const shorthandAxis = parseOverflowShorthandAxis(overflow);
37940
37762
  const yFromLonghand = parseSingleAxisScroll(overflowY);
37941
37763
  const xScroll = shorthandAxis.x;
@@ -37983,7 +37805,7 @@ function toScrollAxis(x, y) {
37983
37805
  }
37984
37806
  function computeFlowParticipationFact(snapshot) {
37985
37807
  const signal = snapshot.signals.get("position");
37986
- if (!signal || signal.kind !== "known") {
37808
+ if (!signal || signal.kind !== 0 /* Known */) {
37987
37809
  return {
37988
37810
  inFlow: true,
37989
37811
  position: null,
@@ -38015,8 +37837,8 @@ function buildContextIndex(childrenByParentNode, snapshotByElementNode, perf, lo
38015
37837
  if (trace) {
38016
37838
  const displaySignal = snapshot.signals.get("display");
38017
37839
  const flexDirSignal = snapshot.signals.get("flex-direction");
38018
- const displayDesc = displaySignal ? `${displaySignal.kind}:${displaySignal.kind === "known" ? displaySignal.normalized : "?"}(guard=${displaySignal.guard.kind === 1 /* Conditional */ ? "conditional" : "unconditional"})` : "absent";
38019
- const flexDirDesc = flexDirSignal ? `${flexDirSignal.kind}:${flexDirSignal.kind === "known" ? flexDirSignal.normalized : "?"}(guard=${flexDirSignal.guard.kind === 1 /* Conditional */ ? "conditional" : "unconditional"})` : "absent";
37840
+ const displayDesc = displaySignal ? `${displaySignal.kind}:${displaySignal.kind === 0 /* Known */ ? displaySignal.normalized : "?"}(guard=${displaySignal.guard.kind === 1 /* Conditional */ ? "conditional" : "unconditional"})` : "absent";
37841
+ const flexDirDesc = flexDirSignal ? `${flexDirSignal.kind}:${flexDirSignal.kind === 0 /* Known */ ? flexDirSignal.normalized : "?"}(guard=${flexDirSignal.guard.kind === 1 /* Conditional */ ? "conditional" : "unconditional"})` : "absent";
38020
37842
  logger.trace(
38021
37843
  `[context] parent=${parent.key} tag=${parent.tagName ?? "null"} children=${children.length} display=${displayDesc} flex-direction=${flexDirDesc} \u2192 kind=${ctx.kind} certainty=${ctx.certainty} crossAxisIsBlockAxis=${ctx.crossAxisIsBlockAxis} baseline=${ctx.baselineRelevance}`
38022
37844
  );
@@ -40222,8 +40044,8 @@ function hasReservedSize(solid, attributes, element, reservedSpaceFact, hostElem
40222
40044
  const hostJsxWidth = hostElementRef !== null ? readPositiveJsxAttribute(hostElementRef.solid, hostElementRef.element, "width") : false;
40223
40045
  const hostJsxHeight = hostElementRef !== null ? readPositiveJsxAttribute(hostElementRef.solid, hostElementRef.element, "height") : false;
40224
40046
  if (attrWidth && attrHeight || jsxAttrWidth && jsxAttrHeight || hostJsxWidth && hostJsxHeight) return true;
40225
- const hasAnyWidth = attrWidth || jsxAttrWidth || hostJsxWidth || reservedSpaceFact.hasUsableInlineDimension;
40226
- const hasAnyHeight = attrHeight || jsxAttrHeight || hostJsxHeight || reservedSpaceFact.hasUsableBlockDimension || reservedSpaceFact.hasContainIntrinsicSize;
40047
+ const hasAnyWidth = attrWidth || jsxAttrWidth || hostJsxWidth || reservedSpaceFact.hasDeclaredInlineDimension;
40048
+ const hasAnyHeight = attrHeight || jsxAttrHeight || hostJsxHeight || reservedSpaceFact.hasDeclaredBlockDimension || reservedSpaceFact.hasContainIntrinsicSize;
40227
40049
  if (reservedSpaceFact.hasUsableAspectRatio && (hasAnyWidth || hasAnyHeight)) return true;
40228
40050
  if (reservedSpaceFact.hasContainIntrinsicSize && (hasAnyWidth || hasAnyHeight)) return true;
40229
40051
  return false;
@@ -40700,7 +40522,7 @@ function collectConditionalOffsets(layout, node, snapshot) {
40700
40522
  const signal = snapshot.signals.get(name);
40701
40523
  if (!signal) continue;
40702
40524
  if (signal.guard.kind !== 1 /* Conditional */) continue;
40703
- if (signal.kind !== "known") continue;
40525
+ if (signal.kind !== 0 /* Known */) continue;
40704
40526
  if (signal.px === null) continue;
40705
40527
  if (Math.abs(signal.px) <= 0.25) continue;
40706
40528
  out.push({ property: name, value: signal.px, guardKey: signal.guard.key });
@@ -40723,7 +40545,7 @@ function hasEffectivePositionForConditionalOffset(snapshot, guardKey) {
40723
40545
  if (hasEffectivePosition(snapshot)) return true;
40724
40546
  const position = snapshot.signals.get("position");
40725
40547
  if (!position) return false;
40726
- if (position.kind !== "known") return false;
40548
+ if (position.kind !== 0 /* Known */) return false;
40727
40549
  if (position.guard.kind !== 1 /* Conditional */) return false;
40728
40550
  if (position.guard.key !== guardKey) return false;
40729
40551
  return position.normalized !== "static";
@@ -41183,6 +41005,9 @@ function isVisuallyHidden(snapshot) {
41183
41005
  const opacityAttr = node.inlineStyleValues.get("opacity");
41184
41006
  if (opacityAttr === "0") return true;
41185
41007
  if (node.classTokenSet.has("opacity-0")) return true;
41008
+ const width = readKnownPx(snapshot, "width");
41009
+ const height = readKnownPx(snapshot, "height");
41010
+ if (width === 1 && height === 1) return true;
41186
41011
  return false;
41187
41012
  }
41188
41013
  var jsxLayoutPolicyTouchTarget = defineCrossRule({
@@ -41234,6 +41059,18 @@ var jsxLayoutPolicyTouchTarget = defineCrossRule({
41234
41059
  tag,
41235
41060
  policyName
41236
41061
  );
41062
+ checkDimension(
41063
+ snapshot,
41064
+ "max-height",
41065
+ kind === "button" ? policy.minButtonHeight : policy.minInputHeight,
41066
+ layout,
41067
+ node,
41068
+ emit,
41069
+ "heightTooSmall",
41070
+ messages161.heightTooSmall,
41071
+ tag,
41072
+ policyName
41073
+ );
41237
41074
  checkDimension(
41238
41075
  snapshot,
41239
41076
  "width",
@@ -41258,6 +41095,18 @@ var jsxLayoutPolicyTouchTarget = defineCrossRule({
41258
41095
  tag,
41259
41096
  policyName
41260
41097
  );
41098
+ checkDimension(
41099
+ snapshot,
41100
+ "max-width",
41101
+ kind === "button" ? policy.minButtonWidth : policy.minTouchTarget,
41102
+ layout,
41103
+ node,
41104
+ emit,
41105
+ "widthTooSmall",
41106
+ messages161.widthTooSmall,
41107
+ tag,
41108
+ policyName
41109
+ );
41261
41110
  if (kind === "button") {
41262
41111
  checkDimension(
41263
41112
  snapshot,
@@ -41287,7 +41136,7 @@ var jsxLayoutPolicyTouchTarget = defineCrossRule({
41287
41136
  const reservedSpace = readReservedSpaceFact(layout, node);
41288
41137
  const minBlock = kind === "button" ? policy.minButtonHeight : policy.minInputHeight;
41289
41138
  const minInline = kind === "button" ? policy.minButtonWidth : policy.minTouchTarget;
41290
- if (!reservedSpace.hasUsableBlockDimension) {
41139
+ if (!reservedSpace.hasDeclaredBlockDimension) {
41291
41140
  emitLayoutDiagnostic(
41292
41141
  layout,
41293
41142
  node,
@@ -41299,7 +41148,7 @@ var jsxLayoutPolicyTouchTarget = defineCrossRule({
41299
41148
  { tag, min: String(minBlock), policy: policyName }
41300
41149
  );
41301
41150
  }
41302
- if (!reservedSpace.hasUsableInlineDimension) {
41151
+ if (!reservedSpace.hasDeclaredInlineDimension) {
41303
41152
  emitLayoutDiagnostic(
41304
41153
  layout,
41305
41154
  node,
@@ -41465,4 +41314,4 @@ export {
41465
41314
  rules3,
41466
41315
  runCrossFileRules
41467
41316
  };
41468
- //# sourceMappingURL=chunk-MJKIL7DJ.js.map
41317
+ //# sourceMappingURL=chunk-QDFZ6A6X.js.map