@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.
package/dist/index.cjs CHANGED
@@ -234,7 +234,6 @@ var CHAR_DOUBLE_QUOTE = 34;
234
234
  var CHAR_SINGLE_QUOTE = 39;
235
235
  var CHAR_A = 97;
236
236
  var CHAR_E = 101;
237
- var CHAR_H = 104;
238
237
  var CHAR_I = 105;
239
238
  var CHAR_M = 109;
240
239
  var CHAR_N = 110;
@@ -605,7 +604,6 @@ var ID_STICKY = /#([a-zA-Z_-][a-zA-Z0-9_-]*)/y;
605
604
  var CLASS_STICKY = /\.([a-zA-Z_-][a-zA-Z0-9_-]*)/y;
606
605
  var ATTRIBUTE_STICKY = /\[([^\]]+)\]/y;
607
606
  var PSEUDO_ELEMENT_STICKY = /::([a-zA-Z-]+)(?:\([^)]*\))?/y;
608
- var PSEUDO_CLASS_STICKY = /:([a-zA-Z-]+)(?:\([^)]*\))?/y;
609
607
  var ELEMENT_STICKY = /([a-zA-Z][a-zA-Z0-9-]*)/y;
610
608
  var WHITESPACE_SPLIT = /\s+/;
611
609
  var FUNCTION_CALL_RE = /([a-zA-Z_][\w-]*)\s*\(/g;
@@ -3980,6 +3978,10 @@ function getStaticStringFromJSXValue(node) {
3980
3978
  if (import_typescript4.default.isTemplateExpression(expression) && expression.templateSpans.length === 0) {
3981
3979
  return expression.head.text;
3982
3980
  }
3981
+ if (import_typescript4.default.isBinaryExpression(expression) && expression.operatorToken.kind === import_typescript4.default.SyntaxKind.QuestionQuestionToken) {
3982
+ const fallback = getStaticStringFromJSXValue(expression.right);
3983
+ if (fallback !== null) return fallback;
3984
+ }
3983
3985
  }
3984
3986
  return null;
3985
3987
  }
@@ -23268,7 +23270,7 @@ function splitWhitespaceTokens(value2) {
23268
23270
  return out;
23269
23271
  }
23270
23272
  function parseQuadShorthand(raw) {
23271
- const parts = splitWhitespaceTokens(raw);
23273
+ const parts = splitTopLevelWhitespace(raw);
23272
23274
  if (parts.length === 1) {
23273
23275
  const p0 = parts[0];
23274
23276
  if (!p0) return null;
@@ -23292,7 +23294,7 @@ function parseQuadShorthand(raw) {
23292
23294
  return null;
23293
23295
  }
23294
23296
  function parseBlockShorthand(raw) {
23295
- const parts = splitWhitespaceTokens(raw);
23297
+ const parts = splitTopLevelWhitespace(raw);
23296
23298
  if (parts.length === 1) {
23297
23299
  const p0 = parts[0];
23298
23300
  if (!p0) return null;
@@ -23377,8 +23379,14 @@ var NUMERIC_VALUE = /^([0-9]*\.?[0-9]+)(px|rem|em|pt)?$/;
23377
23379
  function parsePxValue(raw, contextFontSize = 16) {
23378
23380
  const trimmed = raw.trim().toLowerCase();
23379
23381
  if (trimmed.length === 0) return null;
23380
- if (trimmed.includes("var(") || trimmed.includes("calc(") || trimmed.includes("%")) return null;
23382
+ if (trimmed.includes("var(") || trimmed.includes("%")) return null;
23381
23383
  if (CSS_WIDE_KEYWORDS.has(trimmed)) return null;
23384
+ if (trimmed.includes("calc(")) {
23385
+ return tryEvalConstantCalc(trimmed, contextFontSize);
23386
+ }
23387
+ if (trimmed.startsWith("min(") || trimmed.startsWith("max(") || trimmed.startsWith("clamp(")) {
23388
+ return tryEvalMathFunction(trimmed, contextFontSize);
23389
+ }
23382
23390
  const match = NUMERIC_VALUE.exec(trimmed);
23383
23391
  if (!match) return null;
23384
23392
  const num = Number(match[1]);
@@ -23389,6 +23397,135 @@ function parsePxValue(raw, contextFontSize = 16) {
23389
23397
  if (unit === "pt") return num * 1.333;
23390
23398
  return null;
23391
23399
  }
23400
+ var CALC_CONSTANT_RE = /^calc\((.+)\)$/;
23401
+ var CALC_TOKEN_RE = /([0-9]*\.?[0-9]+)(px|rem|em|pt)?|([+\-*/])/g;
23402
+ function tryEvalConstantCalc(raw, contextFontSize) {
23403
+ const match = CALC_CONSTANT_RE.exec(raw);
23404
+ if (!match || !match[1]) return null;
23405
+ const inner = match[1].trim();
23406
+ if (inner.includes("var(") || inner.includes("%") || inner.includes("env(") || inner.includes("calc(")) return null;
23407
+ const values = [];
23408
+ const operators = [];
23409
+ let lastWasValue = false;
23410
+ CALC_TOKEN_RE.lastIndex = 0;
23411
+ let tokenMatch;
23412
+ while ((tokenMatch = CALC_TOKEN_RE.exec(inner)) !== null) {
23413
+ const op = tokenMatch[3];
23414
+ if (op !== void 0) {
23415
+ if (!lastWasValue && op === "-") {
23416
+ const nextToken = CALC_TOKEN_RE.exec(inner);
23417
+ if (!nextToken || nextToken[3] !== void 0) return null;
23418
+ const px2 = calcTokenToPx(nextToken, contextFontSize);
23419
+ if (px2 === null) return null;
23420
+ values.push(-px2);
23421
+ lastWasValue = true;
23422
+ continue;
23423
+ }
23424
+ if (!lastWasValue) return null;
23425
+ operators.push(op);
23426
+ lastWasValue = false;
23427
+ continue;
23428
+ }
23429
+ const px = calcTokenToPx(tokenMatch, contextFontSize);
23430
+ if (px === null) return null;
23431
+ values.push(px);
23432
+ lastWasValue = true;
23433
+ }
23434
+ if (values.length === 0 || values.length !== operators.length + 1) return null;
23435
+ const firstValue = values[0];
23436
+ if (firstValue === void 0) return null;
23437
+ const reducedValues = [firstValue];
23438
+ const reducedOps = [];
23439
+ for (let i = 0; i < operators.length; i++) {
23440
+ const op = operators[i];
23441
+ const right = values[i + 1];
23442
+ if (op === void 0 || right === void 0) return null;
23443
+ if (op === "*") {
23444
+ const last = reducedValues[reducedValues.length - 1];
23445
+ if (last === void 0) return null;
23446
+ reducedValues[reducedValues.length - 1] = last * right;
23447
+ } else if (op === "/") {
23448
+ if (right === 0) return null;
23449
+ const last = reducedValues[reducedValues.length - 1];
23450
+ if (last === void 0) return null;
23451
+ reducedValues[reducedValues.length - 1] = last / right;
23452
+ } else {
23453
+ reducedValues.push(right);
23454
+ reducedOps.push(op);
23455
+ }
23456
+ }
23457
+ const base = reducedValues[0];
23458
+ if (base === void 0) return null;
23459
+ let result = base;
23460
+ for (let i = 0; i < reducedOps.length; i++) {
23461
+ const op = reducedOps[i];
23462
+ const right = reducedValues[i + 1];
23463
+ if (op === void 0 || right === void 0) return null;
23464
+ if (op === "+") result += right;
23465
+ else if (op === "-") result -= right;
23466
+ else return null;
23467
+ }
23468
+ return Number.isFinite(result) ? result : null;
23469
+ }
23470
+ function calcTokenToPx(tokenMatch, contextFontSize) {
23471
+ const num = Number(tokenMatch[1]);
23472
+ if (Number.isNaN(num)) return null;
23473
+ const unit = tokenMatch[2] ?? "";
23474
+ if (unit === "px" || unit === "") return num;
23475
+ if (unit === "rem") return num * 16;
23476
+ if (unit === "em") return num * contextFontSize;
23477
+ if (unit === "pt") return num * 1.333;
23478
+ return null;
23479
+ }
23480
+ var MATH_FN_RE = /^(min|max|clamp)\((.+)\)$/;
23481
+ function tryEvalMathFunction(raw, contextFontSize) {
23482
+ const match = MATH_FN_RE.exec(raw);
23483
+ if (!match || !match[1] || !match[2]) return null;
23484
+ const fn = match[1];
23485
+ const inner = match[2];
23486
+ const args = splitMathArgs(inner);
23487
+ if (args === null) return null;
23488
+ const values = [];
23489
+ for (let i = 0; i < args.length; i++) {
23490
+ const arg = args[i];
23491
+ if (!arg) return null;
23492
+ const px = parsePxValue(arg.trim(), contextFontSize);
23493
+ if (px === null) return null;
23494
+ values.push(px);
23495
+ }
23496
+ if (values.length === 0) return null;
23497
+ if (fn === "min") return Math.min(...values);
23498
+ if (fn === "max") return Math.max(...values);
23499
+ if (fn === "clamp") {
23500
+ if (values.length !== 3) return null;
23501
+ const [lo, val, hi] = values;
23502
+ return Math.max(lo, Math.min(val, hi));
23503
+ }
23504
+ return null;
23505
+ }
23506
+ function splitMathArgs(inner) {
23507
+ const args = [];
23508
+ let depth = 0;
23509
+ let start = 0;
23510
+ for (let i = 0; i < inner.length; i++) {
23511
+ const ch = inner[i];
23512
+ if (ch === "(") depth++;
23513
+ else if (ch === ")") {
23514
+ if (depth > 0) depth--;
23515
+ else return null;
23516
+ } else if (ch === "," && depth === 0) {
23517
+ const arg = inner.slice(start, i).trim();
23518
+ if (arg.length === 0) return null;
23519
+ args.push(arg);
23520
+ start = i + 1;
23521
+ }
23522
+ }
23523
+ if (depth !== 0) return null;
23524
+ const tail = inner.slice(start).trim();
23525
+ if (tail.length === 0) return null;
23526
+ args.push(tail);
23527
+ return args;
23528
+ }
23392
23529
  function parseUnitlessValue(raw) {
23393
23530
  const trimmed = raw.trim().toLowerCase();
23394
23531
  if (trimmed.length === 0) return null;
@@ -23790,19 +23927,6 @@ var FONT_GENERIC_FAMILY_SET = /* @__PURE__ */ new Set([
23790
23927
  ]);
23791
23928
  var FONT_LAYOUT_PROPERTIES = /* @__PURE__ */ new Set(["font-family"]);
23792
23929
  var WHITESPACE_RE2 = /\s+/;
23793
- function classifyRuleElementKinds(rule) {
23794
- const kinds = rule.elementKinds;
23795
- for (let i = 0; i < rule.selectors.length; i++) {
23796
- const sel = rule.selectors[i];
23797
- if (!sel) continue;
23798
- const parts = sel.parts;
23799
- for (let j = 0; j < parts.length; j++) {
23800
- const part = parts[j];
23801
- if (!part) continue;
23802
- classifyPart(part, kinds);
23803
- }
23804
- }
23805
- }
23806
23930
  function classifyPart(part, kinds) {
23807
23931
  if (part.type === "element") {
23808
23932
  const lower = part.value.toLowerCase();
@@ -23930,7 +24054,19 @@ var CSSGraph = class {
23930
24054
  parseErrors = [];
23931
24055
  failedFilePaths = [];
23932
24056
  tokenCategories = [];
23933
- filesWithLayers = /* @__PURE__ */ new Set();
24057
+ _filesWithLayers = null;
24058
+ get filesWithLayers() {
24059
+ if (this._filesWithLayers === null) {
24060
+ const result = /* @__PURE__ */ new Set();
24061
+ for (let i = 0; i < this.layers.length; i++) {
24062
+ const layer = this.layers[i];
24063
+ if (!layer) continue;
24064
+ result.add(layer.file.path);
24065
+ }
24066
+ this._filesWithLayers = result;
24067
+ }
24068
+ return this._filesWithLayers;
24069
+ }
23934
24070
  selectorsByPseudoClass = /* @__PURE__ */ new Map();
23935
24071
  knownKeyframeNames = /* @__PURE__ */ new Set();
23936
24072
  unresolvedAnimationRefs = [];
@@ -23942,17 +24078,61 @@ var CSSGraph = class {
23942
24078
  multiDeclarationProperties = /* @__PURE__ */ new Map();
23943
24079
  /** Declarations whose parent rule is inside a @keyframes block. */
23944
24080
  keyframeDeclarations = [];
23945
- /** Rules with zero declarations and zero nested rules. */
23946
- emptyRules = [];
24081
+ /** Rules with zero declarations, zero nested rules, and zero nested at-rules. */
24082
+ _emptyRules = null;
24083
+ get emptyRules() {
24084
+ if (this._emptyRules === null) {
24085
+ this._emptyRules = this.rules.filter((r) => r.declarations.length === 0 && r.nestedRules.length === 0 && r.nestedAtRules.length === 0);
24086
+ }
24087
+ return this._emptyRules;
24088
+ }
23947
24089
  /** @keyframes at-rules with no effective keyframe declarations. */
23948
- emptyKeyframes = [];
23949
- colorDeclarations = [];
23950
- calcDeclarations = [];
23951
- varDeclarations = [];
23952
- urlDeclarations = [];
23953
- vendorPrefixedDeclarations = [];
23954
- hardcodedColorDeclarations = [];
23955
- overqualifiedSelectors = [];
24090
+ _emptyKeyframes = null;
24091
+ get emptyKeyframes() {
24092
+ if (this._emptyKeyframes === null) {
24093
+ const result = [];
24094
+ for (let i = 0; i < this.keyframes.length; i++) {
24095
+ const kf = this.keyframes[i];
24096
+ if (!kf) continue;
24097
+ if (!kf.parsedParams.animationName) continue;
24098
+ if (kf.rules.length === 0) {
24099
+ result.push(kf);
24100
+ continue;
24101
+ }
24102
+ let hasDeclaration = false;
24103
+ for (let j = 0; j < kf.rules.length; j++) {
24104
+ const kfRule = kf.rules[j];
24105
+ if (!kfRule) continue;
24106
+ if (kfRule.declarations.length > 0) {
24107
+ hasDeclaration = true;
24108
+ break;
24109
+ }
24110
+ }
24111
+ if (!hasDeclaration) result.push(kf);
24112
+ }
24113
+ this._emptyKeyframes = result;
24114
+ }
24115
+ return this._emptyKeyframes;
24116
+ }
24117
+ _overqualifiedSelectors = null;
24118
+ get overqualifiedSelectors() {
24119
+ if (this._overqualifiedSelectors === null) {
24120
+ const result = [];
24121
+ for (let i = 0, len = this.idSelectors.length; i < len; i++) {
24122
+ const sel = this.idSelectors[i];
24123
+ if (!sel) continue;
24124
+ const compounds = sel.compounds;
24125
+ if (compounds.length === 0) continue;
24126
+ const subject = compounds[compounds.length - 1];
24127
+ if (!subject) continue;
24128
+ if (subject.idValue !== null && (subject.tagName !== null || subject.classes.length > 0 || subject.attributes.length > 0)) {
24129
+ result.push(sel);
24130
+ }
24131
+ }
24132
+ this._overqualifiedSelectors = result;
24133
+ }
24134
+ return this._overqualifiedSelectors;
24135
+ }
23956
24136
  idSelectors = [];
23957
24137
  attributeSelectors = [];
23958
24138
  universalSelectors = [];
@@ -23968,7 +24148,13 @@ var CSSGraph = class {
23968
24148
  usedFontFamilies = /* @__PURE__ */ new Set();
23969
24149
  /** Tailwind validator for utility class lookup (null if not a Tailwind project). */
23970
24150
  tailwind;
23971
- deepNestedRules = [];
24151
+ _deepNestedRules = null;
24152
+ get deepNestedRules() {
24153
+ if (this._deepNestedRules === null) {
24154
+ this._deepNestedRules = this.rules.filter((r) => r.depth > 3);
24155
+ }
24156
+ return this._deepNestedRules;
24157
+ }
23972
24158
  constructor(input) {
23973
24159
  this.options = input.options ?? {};
23974
24160
  this.tailwind = input.tailwind ?? null;
@@ -24033,13 +24219,57 @@ var CSSGraph = class {
24033
24219
  }
24034
24220
  addSelector(selector) {
24035
24221
  this.selectors.push(selector);
24222
+ const anchor = selector.anchor;
24223
+ if (anchor.subjectTag === null) {
24224
+ this.selectorsWithoutSubjectTag.push(selector);
24225
+ } else {
24226
+ const existingByTag = this.selectorsBySubjectTag.get(anchor.subjectTag);
24227
+ if (existingByTag) existingByTag.push(selector);
24228
+ else this.selectorsBySubjectTag.set(anchor.subjectTag, [selector]);
24229
+ }
24230
+ if (anchor.targetsCheckbox) this.selectorsTargetingCheckbox.push(selector);
24231
+ if (anchor.targetsTableCell) this.selectorsTargetingTableCell.push(selector);
24232
+ const compounds = selector.compounds;
24233
+ for (let ci = 0; ci < compounds.length; ci++) {
24234
+ const compound = compounds[ci];
24235
+ if (!compound) continue;
24236
+ const cls = compound.classes;
24237
+ for (let j = 0; j < cls.length; j++) {
24238
+ const className = cls[j];
24239
+ if (!className) continue;
24240
+ const existing = this.classNameIndex.get(className);
24241
+ if (existing) existing.push(selector);
24242
+ else this.classNameIndex.set(className, [selector]);
24243
+ }
24244
+ }
24245
+ const complexity = selector.complexity;
24246
+ const flags = complexity._flags;
24247
+ if (hasFlag(flags, SEL_HAS_ID)) this.idSelectors.push(selector);
24248
+ if (hasFlag(flags, SEL_HAS_ATTRIBUTE)) this.attributeSelectors.push(selector);
24249
+ if (hasFlag(flags, SEL_HAS_UNIVERSAL)) this.universalSelectors.push(selector);
24250
+ const pseudoClasses = complexity.pseudoClasses;
24251
+ for (let j = 0; j < pseudoClasses.length; j++) {
24252
+ const pc = pseudoClasses[j];
24253
+ if (!pc) continue;
24254
+ const pcExisting = this.selectorsByPseudoClass.get(pc);
24255
+ if (pcExisting) pcExisting.push(selector);
24256
+ else this.selectorsByPseudoClass.set(pc, [selector]);
24257
+ }
24036
24258
  }
24037
24259
  addDeclaration(decl) {
24038
24260
  this.declarations.push(decl);
24039
- const existing = this.declarationsByProperty.get(decl.property);
24261
+ const property = decl.property;
24262
+ const existing = this.declarationsByProperty.get(property);
24040
24263
  if (existing) existing.push(decl);
24041
- else this.declarationsByProperty.set(decl.property, [decl]);
24264
+ else this.declarationsByProperty.set(property, [decl]);
24042
24265
  if (hasFlag(decl._flags, DECL_IS_IMPORTANT) || decl.node.important) this.importantDeclarations.push(decl);
24266
+ if (decl.rule !== null) {
24267
+ const p = property.toLowerCase();
24268
+ const ruleIndex = decl.rule.declarationIndex;
24269
+ const ruleExisting = ruleIndex.get(p);
24270
+ if (ruleExisting) ruleExisting.push(decl);
24271
+ else ruleIndex.set(p, [decl]);
24272
+ }
24043
24273
  }
24044
24274
  addVariable(variable) {
24045
24275
  this.variables.push(variable);
@@ -24173,39 +24403,12 @@ var CSSGraph = class {
24173
24403
  * Called after all phases complete.
24174
24404
  */
24175
24405
  buildDerivedIndexes() {
24176
- this.buildRuleDeclarationIndexes();
24177
24406
  this.buildContainingMediaStacks();
24178
- this.buildKeyframeIndex();
24407
+ this.buildKeyframeIndexes();
24179
24408
  this.buildContainerNameIndexes();
24180
- this.buildElementKinds();
24181
- this.buildFilesWithLayers();
24182
- this.buildSelectorPseudoClassIndex();
24183
24409
  this.buildMultiDeclarationProperties();
24184
- this.buildKeyframeDeclarations();
24185
- this.buildKeyframeLayoutMutationsByName();
24186
- this.buildEmptyRules();
24187
- this.buildEmptyKeyframes();
24188
- this.buildDeclarationDerivedIndexes();
24189
- this.buildSelectorDerivedIndexes();
24190
24410
  this.buildLayoutPropertiesByClassToken();
24191
- this.buildFontFamilyUsageByRule();
24192
- this.buildFontFaceDescriptorsByFamily();
24193
- this.buildRuleDerivedIndexes();
24194
- }
24195
- buildRuleDeclarationIndexes() {
24196
- for (let i = 0; i < this.rules.length; i++) {
24197
- const rule = this.rules[i];
24198
- if (!rule) continue;
24199
- const index = rule.declarationIndex;
24200
- for (let j = 0; j < rule.declarations.length; j++) {
24201
- const d = rule.declarations[j];
24202
- if (!d) continue;
24203
- const p = d.property.toLowerCase();
24204
- const existing = index.get(p);
24205
- if (existing) existing.push(d);
24206
- else index.set(p, [d]);
24207
- }
24208
- }
24411
+ this.buildFontIndexes();
24209
24412
  }
24210
24413
  buildContainingMediaStacks() {
24211
24414
  for (let i = 0; i < this.rules.length; i++) {
@@ -24220,7 +24423,7 @@ var CSSGraph = class {
24220
24423
  rule.containingMediaStack = medias;
24221
24424
  }
24222
24425
  }
24223
- buildKeyframeIndex() {
24426
+ buildKeyframeIndexes() {
24224
24427
  const IGNORED = /* @__PURE__ */ new Set([...CSS_WIDE_KEYWORDS, "none"]);
24225
24428
  for (let i = 0; i < this.keyframes.length; i++) {
24226
24429
  const kf = this.keyframes[i];
@@ -24242,6 +24445,47 @@ var CSSGraph = class {
24242
24445
  this.unresolvedAnimationRefs.push({ declaration: d, name });
24243
24446
  }
24244
24447
  }
24448
+ const byAnimationByProperty = /* @__PURE__ */ new Map();
24449
+ for (let i = 0; i < this.declarations.length; i++) {
24450
+ const d = this.declarations[i];
24451
+ if (!d) continue;
24452
+ const rule = d.rule;
24453
+ if (!rule) continue;
24454
+ const parent = rule.parent;
24455
+ if (!parent) continue;
24456
+ if (parent.kind === "rule") continue;
24457
+ if (parent.kind !== "keyframes") continue;
24458
+ this.keyframeDeclarations.push(d);
24459
+ const property = d.property.toLowerCase();
24460
+ if (!LAYOUT_ANIMATION_MUTATION_PROPERTIES.has(property)) continue;
24461
+ const animationName = normalizeAnimationName(parent.params);
24462
+ if (!animationName) continue;
24463
+ let byProperty = byAnimationByProperty.get(animationName);
24464
+ if (!byProperty) {
24465
+ byProperty = /* @__PURE__ */ new Map();
24466
+ byAnimationByProperty.set(animationName, byProperty);
24467
+ }
24468
+ let bucket = byProperty.get(property);
24469
+ if (!bucket) {
24470
+ bucket = { values: /* @__PURE__ */ new Set(), declarations: [] };
24471
+ byProperty.set(property, bucket);
24472
+ }
24473
+ bucket.values.add(normalizeCssValue(d.value));
24474
+ bucket.declarations.push(d);
24475
+ }
24476
+ for (const [animationName, byProperty] of byAnimationByProperty) {
24477
+ const mutations = [];
24478
+ for (const [property, bucket] of byProperty) {
24479
+ if (bucket.values.size <= 1) continue;
24480
+ mutations.push({
24481
+ property,
24482
+ values: [...bucket.values],
24483
+ declarations: bucket.declarations
24484
+ });
24485
+ }
24486
+ if (mutations.length === 0) continue;
24487
+ this.keyframeLayoutMutationsByName.set(animationName, mutations);
24488
+ }
24245
24489
  }
24246
24490
  buildContainerNameIndexes() {
24247
24491
  for (let i = 0; i < this.declarations.length; i++) {
@@ -24285,34 +24529,6 @@ var CSSGraph = class {
24285
24529
  }
24286
24530
  }
24287
24531
  }
24288
- buildElementKinds() {
24289
- for (let i = 0; i < this.rules.length; i++) {
24290
- const rule = this.rules[i];
24291
- if (!rule) continue;
24292
- classifyRuleElementKinds(rule);
24293
- }
24294
- }
24295
- buildFilesWithLayers() {
24296
- for (let i = 0; i < this.layers.length; i++) {
24297
- const layer = this.layers[i];
24298
- if (!layer) continue;
24299
- this.filesWithLayers.add(layer.file.path);
24300
- }
24301
- }
24302
- buildSelectorPseudoClassIndex() {
24303
- for (let i = 0; i < this.selectors.length; i++) {
24304
- const sel = this.selectors[i];
24305
- if (!sel) continue;
24306
- const pseudoClasses = sel.complexity.pseudoClasses;
24307
- for (let j = 0; j < pseudoClasses.length; j++) {
24308
- const pc = pseudoClasses[j];
24309
- if (!pc) continue;
24310
- const existing = this.selectorsByPseudoClass.get(pc);
24311
- if (existing) existing.push(sel);
24312
- else this.selectorsByPseudoClass.set(pc, [sel]);
24313
- }
24314
- }
24315
- }
24316
24532
  /**
24317
24533
  * Sort each declarationsByProperty list by sourceOrder and populate
24318
24534
  * multiDeclarationProperties with only those having 2+ entries.
@@ -24325,162 +24541,6 @@ var CSSGraph = class {
24325
24541
  }
24326
24542
  }
24327
24543
  }
24328
- /**
24329
- * Collect declarations whose parent rule is inside a @keyframes block.
24330
- */
24331
- buildKeyframeDeclarations() {
24332
- for (let i = 0; i < this.declarations.length; i++) {
24333
- const d = this.declarations[i];
24334
- if (!d) continue;
24335
- const rule = d.rule;
24336
- if (!rule) continue;
24337
- const parent = rule.parent;
24338
- if (!parent) continue;
24339
- if (parent.kind === "rule") continue;
24340
- if (parent.kind !== "keyframes") continue;
24341
- this.keyframeDeclarations.push(d);
24342
- }
24343
- }
24344
- buildKeyframeLayoutMutationsByName() {
24345
- const byAnimationByProperty = /* @__PURE__ */ new Map();
24346
- for (let i = 0; i < this.keyframeDeclarations.length; i++) {
24347
- const declaration = this.keyframeDeclarations[i];
24348
- if (!declaration) continue;
24349
- const rule = declaration.rule;
24350
- if (!rule || rule.parent === null || rule.parent.kind !== "keyframes") continue;
24351
- const property = declaration.property.toLowerCase();
24352
- if (!LAYOUT_ANIMATION_MUTATION_PROPERTIES.has(property)) continue;
24353
- const animationName = normalizeAnimationName(rule.parent.params);
24354
- if (!animationName) continue;
24355
- let byProperty = byAnimationByProperty.get(animationName);
24356
- if (!byProperty) {
24357
- byProperty = /* @__PURE__ */ new Map();
24358
- byAnimationByProperty.set(animationName, byProperty);
24359
- }
24360
- let bucket = byProperty.get(property);
24361
- if (!bucket) {
24362
- bucket = { values: /* @__PURE__ */ new Set(), declarations: [] };
24363
- byProperty.set(property, bucket);
24364
- }
24365
- bucket.values.add(normalizeCssValue(declaration.value));
24366
- bucket.declarations.push(declaration);
24367
- }
24368
- for (const [animationName, byProperty] of byAnimationByProperty) {
24369
- const mutations = [];
24370
- for (const [property, bucket] of byProperty) {
24371
- if (bucket.values.size <= 1) continue;
24372
- mutations.push({
24373
- property,
24374
- values: [...bucket.values],
24375
- declarations: bucket.declarations
24376
- });
24377
- }
24378
- if (mutations.length === 0) continue;
24379
- this.keyframeLayoutMutationsByName.set(animationName, mutations);
24380
- }
24381
- }
24382
- /**
24383
- * Collect rules with no declarations and no nested rules.
24384
- */
24385
- buildEmptyRules() {
24386
- for (let i = 0; i < this.rules.length; i++) {
24387
- const rule = this.rules[i];
24388
- if (!rule) continue;
24389
- if (rule.declarations.length === 0 && rule.nestedRules.length === 0) {
24390
- this.emptyRules.push(rule);
24391
- }
24392
- }
24393
- }
24394
- /**
24395
- * Collect @keyframes with no effective keyframe declarations.
24396
- */
24397
- buildEmptyKeyframes() {
24398
- for (let i = 0; i < this.keyframes.length; i++) {
24399
- const kf = this.keyframes[i];
24400
- if (!kf) continue;
24401
- if (!kf.parsedParams.animationName) continue;
24402
- if (kf.rules.length === 0) {
24403
- this.emptyKeyframes.push(kf);
24404
- continue;
24405
- }
24406
- let hasDeclaration = false;
24407
- for (let j = 0; j < kf.rules.length; j++) {
24408
- const kfRule = kf.rules[j];
24409
- if (!kfRule) continue;
24410
- if (kfRule.declarations.length > 0) {
24411
- hasDeclaration = true;
24412
- break;
24413
- }
24414
- }
24415
- if (!hasDeclaration) this.emptyKeyframes.push(kf);
24416
- }
24417
- }
24418
- buildDeclarationDerivedIndexes() {
24419
- const HARDCODED_HEX = /^#[0-9a-f]{3,8}$/i;
24420
- for (let i = 0, len = this.declarations.length; i < len; i++) {
24421
- const d = this.declarations[i];
24422
- if (!d) continue;
24423
- const pv = d.parsedValue;
24424
- if (pv.colors.length > 0) this.colorDeclarations.push(d);
24425
- if (pv.hasCalc) this.calcDeclarations.push(d);
24426
- if (pv.hasVar) this.varDeclarations.push(d);
24427
- if (pv.hasUrl) this.urlDeclarations.push(d);
24428
- if (d.property.charCodeAt(0) === CHAR_HYPHEN && d.property.charCodeAt(1) !== CHAR_HYPHEN) {
24429
- this.vendorPrefixedDeclarations.push(d);
24430
- }
24431
- if (!pv.hasVar && pv.colors.length > 0) {
24432
- for (let j = 0, clen = pv.colors.length; j < clen; j++) {
24433
- const c = pv.colors[j];
24434
- if (!c) continue;
24435
- if (HARDCODED_HEX.test(c) || c.charCodeAt(0) === CHAR_R || c.charCodeAt(0) === CHAR_H) {
24436
- this.hardcodedColorDeclarations.push(d);
24437
- break;
24438
- }
24439
- }
24440
- }
24441
- }
24442
- }
24443
- buildSelectorDerivedIndexes() {
24444
- for (let i = 0, len = this.selectors.length; i < len; i++) {
24445
- const sel = this.selectors[i];
24446
- if (!sel) continue;
24447
- const parts = sel.parts;
24448
- const anchor = sel.anchor;
24449
- if (anchor.subjectTag === null) {
24450
- this.selectorsWithoutSubjectTag.push(sel);
24451
- } else {
24452
- const existingByTag = this.selectorsBySubjectTag.get(anchor.subjectTag);
24453
- if (existingByTag) existingByTag.push(sel);
24454
- else this.selectorsBySubjectTag.set(anchor.subjectTag, [sel]);
24455
- }
24456
- if (anchor.targetsCheckbox) this.selectorsTargetingCheckbox.push(sel);
24457
- if (anchor.targetsTableCell) this.selectorsTargetingTableCell.push(sel);
24458
- for (let j = 0, plen = parts.length; j < plen; j++) {
24459
- const part = parts[j];
24460
- if (!part) continue;
24461
- if (part.type === "class") {
24462
- const existing = this.classNameIndex.get(part.value);
24463
- if (existing) existing.push(sel);
24464
- else this.classNameIndex.set(part.value, [sel]);
24465
- }
24466
- }
24467
- const flags = sel.complexity._flags;
24468
- if (hasFlag(flags, SEL_HAS_ID)) {
24469
- this.idSelectors.push(sel);
24470
- for (let j = 0, plen = parts.length; j < plen; j++) {
24471
- const p = parts[j];
24472
- if (!p) continue;
24473
- const t = p.type;
24474
- if (t === "element" || t === "class" || t === "attribute") {
24475
- this.overqualifiedSelectors.push(sel);
24476
- break;
24477
- }
24478
- }
24479
- }
24480
- if (hasFlag(flags, SEL_HAS_ATTRIBUTE)) this.attributeSelectors.push(sel);
24481
- if (hasFlag(flags, SEL_HAS_UNIVERSAL)) this.universalSelectors.push(sel);
24482
- }
24483
- }
24484
24544
  buildLayoutPropertiesByClassToken() {
24485
24545
  const byClass = /* @__PURE__ */ new Map();
24486
24546
  for (let i = 0; i < this.selectors.length; i++) {
@@ -24511,7 +24571,7 @@ var CSSGraph = class {
24511
24571
  this.layoutPropertiesByClassToken.set(className, [...properties]);
24512
24572
  }
24513
24573
  }
24514
- buildFontFamilyUsageByRule() {
24574
+ buildFontIndexes() {
24515
24575
  const declarations = this.declarationsForProperties(...FONT_LAYOUT_PROPERTIES);
24516
24576
  for (let i = 0; i < declarations.length; i++) {
24517
24577
  const declaration = declarations[i];
@@ -24538,8 +24598,6 @@ var CSSGraph = class {
24538
24598
  }
24539
24599
  this.usedFontFamiliesByRule.set(rule.id, [...merged]);
24540
24600
  }
24541
- }
24542
- buildFontFaceDescriptorsByFamily() {
24543
24601
  const byFamily = /* @__PURE__ */ new Map();
24544
24602
  for (let i = 0; i < this.fontFaces.length; i++) {
24545
24603
  const fontFace = this.fontFaces[i];
@@ -24571,13 +24629,6 @@ var CSSGraph = class {
24571
24629
  this.fontFaceDescriptorsByFamily.set(family, descriptors);
24572
24630
  }
24573
24631
  }
24574
- buildRuleDerivedIndexes() {
24575
- for (let i = 0, len = this.rules.length; i < len; i++) {
24576
- const rule = this.rules[i];
24577
- if (!rule) continue;
24578
- if (rule.depth > 3) this.deepNestedRules.push(rule);
24579
- }
24580
- }
24581
24632
  buildUnusedIndexes() {
24582
24633
  for (const v of this.variables) {
24583
24634
  if (!hasFlag(v._flags, VAR_IS_USED)) this.unusedVariables.push(v);
@@ -24891,102 +24942,6 @@ function buildComplexity(combinators, hasId, hasUniversal, hasAttribute, hasPseu
24891
24942
  }
24892
24943
 
24893
24944
  // src/css/parser/selector.ts
24894
- function parseSelector(raw) {
24895
- let start = 0;
24896
- let end = raw.length;
24897
- while (start < end && isWhitespace(raw.charCodeAt(start))) start++;
24898
- while (end > start && isWhitespace(raw.charCodeAt(end - 1))) end--;
24899
- if (start === end) return [];
24900
- const input = start === 0 && end === raw.length ? raw : raw.substring(start, end);
24901
- const len = input.length;
24902
- const parts = [];
24903
- let pos = 0;
24904
- while (pos < len) {
24905
- const char = input.charCodeAt(pos);
24906
- if (isWhitespace(char) || isCombinator(char)) {
24907
- pos++;
24908
- continue;
24909
- }
24910
- if (char === CHAR_AMPERSAND) {
24911
- parts.push({ type: "nesting", value: "&", raw: "&" });
24912
- pos++;
24913
- continue;
24914
- }
24915
- if (char === CHAR_ASTERISK) {
24916
- parts.push({ type: "universal", value: "*", raw: "*" });
24917
- pos++;
24918
- continue;
24919
- }
24920
- if (char === CHAR_HASH) {
24921
- ID_STICKY.lastIndex = pos;
24922
- const match = ID_STICKY.exec(input);
24923
- if (match) {
24924
- const val = match[1];
24925
- if (!val) break;
24926
- parts.push({ type: "id", value: val, raw: match[0] });
24927
- pos = ID_STICKY.lastIndex;
24928
- continue;
24929
- }
24930
- }
24931
- if (char === CHAR_DOT) {
24932
- CLASS_STICKY.lastIndex = pos;
24933
- const match = CLASS_STICKY.exec(input);
24934
- if (match) {
24935
- const val = match[1];
24936
- if (!val) break;
24937
- parts.push({ type: "class", value: val, raw: match[0] });
24938
- pos = CLASS_STICKY.lastIndex;
24939
- continue;
24940
- }
24941
- }
24942
- if (char === CHAR_OPEN_BRACKET) {
24943
- ATTRIBUTE_STICKY.lastIndex = pos;
24944
- const match = ATTRIBUTE_STICKY.exec(input);
24945
- if (match) {
24946
- const val = match[1];
24947
- if (!val) break;
24948
- parts.push({ type: "attribute", value: val, raw: match[0] });
24949
- pos = ATTRIBUTE_STICKY.lastIndex;
24950
- continue;
24951
- }
24952
- }
24953
- if (char === CHAR_COLON) {
24954
- if (pos + 1 < len && input.charCodeAt(pos + 1) === CHAR_COLON) {
24955
- PSEUDO_ELEMENT_STICKY.lastIndex = pos;
24956
- const match2 = PSEUDO_ELEMENT_STICKY.exec(input);
24957
- if (match2) {
24958
- const val = match2[1];
24959
- if (!val) break;
24960
- parts.push({ type: "pseudo-element", value: val, raw: match2[0] });
24961
- pos = PSEUDO_ELEMENT_STICKY.lastIndex;
24962
- continue;
24963
- }
24964
- }
24965
- PSEUDO_CLASS_STICKY.lastIndex = pos;
24966
- const match = PSEUDO_CLASS_STICKY.exec(input);
24967
- if (match) {
24968
- const val = match[1];
24969
- if (!val) break;
24970
- parts.push({ type: "pseudo-class", value: val, raw: match[0] });
24971
- pos = PSEUDO_CLASS_STICKY.lastIndex;
24972
- continue;
24973
- }
24974
- }
24975
- if (isAlpha(char)) {
24976
- ELEMENT_STICKY.lastIndex = pos;
24977
- const match = ELEMENT_STICKY.exec(input);
24978
- if (match) {
24979
- const val = match[1];
24980
- if (!val) break;
24981
- parts.push({ type: "element", value: val, raw: match[0] });
24982
- pos = ELEMENT_STICKY.lastIndex;
24983
- continue;
24984
- }
24985
- }
24986
- pos++;
24987
- }
24988
- return parts;
24989
- }
24990
24945
  function parseSelectorList(selectorText) {
24991
24946
  const len = selectorText.length;
24992
24947
  if (len === 0) return [];
@@ -25074,18 +25029,80 @@ function extractPseudoClasses(selector) {
25074
25029
  }
25075
25030
  return pseudoClasses;
25076
25031
  }
25077
- function parseSelectorComplete(raw) {
25032
+ var CHAR_BACKSLASH = 92;
25033
+ function readCssIdentifier(input, start) {
25034
+ const length = input.length;
25035
+ let i = start;
25036
+ let hasEscape = false;
25037
+ while (i < length) {
25038
+ const code = input.charCodeAt(i);
25039
+ if (code === CHAR_BACKSLASH) {
25040
+ if (i + 1 >= length) break;
25041
+ hasEscape = true;
25042
+ i = skipCssEscape(input, i + 1);
25043
+ continue;
25044
+ }
25045
+ if (!isIdentChar(code)) break;
25046
+ i++;
25047
+ }
25048
+ if (i === start) return null;
25049
+ if (!hasEscape) {
25050
+ return { value: input.slice(start, i), end: i };
25051
+ }
25052
+ const parts = [];
25053
+ let j = start;
25054
+ while (j < i) {
25055
+ const code = input.charCodeAt(j);
25056
+ if (code !== CHAR_BACKSLASH) {
25057
+ parts.push(String.fromCharCode(code));
25058
+ j++;
25059
+ continue;
25060
+ }
25061
+ j++;
25062
+ if (j >= i) break;
25063
+ const first = input.charCodeAt(j);
25064
+ if (!isHexDigit(first)) {
25065
+ parts.push(String.fromCharCode(first));
25066
+ j++;
25067
+ continue;
25068
+ }
25069
+ const hexStart = j;
25070
+ const maxHex = Math.min(j + 6, i);
25071
+ while (j < maxHex && isHexDigit(input.charCodeAt(j))) j++;
25072
+ const codePoint = Number.parseInt(input.slice(hexStart, j), 16);
25073
+ if (codePoint > 0 && codePoint <= 1114111) parts.push(String.fromCodePoint(codePoint));
25074
+ if (j < i && isWhitespace(input.charCodeAt(j))) j++;
25075
+ }
25076
+ return { value: parts.join(""), end: i };
25077
+ }
25078
+ function skipCssEscape(input, afterBackslash) {
25079
+ const length = input.length;
25080
+ if (afterBackslash >= length) return afterBackslash;
25081
+ const first = input.charCodeAt(afterBackslash);
25082
+ if (!isHexDigit(first)) return afterBackslash + 1;
25083
+ let end = afterBackslash + 1;
25084
+ const maxHex = Math.min(afterBackslash + 6, length);
25085
+ while (end < maxHex && isHexDigit(input.charCodeAt(end))) end++;
25086
+ if (end < length && isWhitespace(input.charCodeAt(end))) end++;
25087
+ return end;
25088
+ }
25089
+ var ATTRIBUTE_EXISTS_RE = /^[-_a-zA-Z][-_a-zA-Z0-9]*$/;
25090
+ var ATTRIBUTE_CONSTRAINT_RE = /^([-_a-zA-Z][-_a-zA-Z0-9]*)\s*(=|~=|\|=|\^=|\$=|\*=)\s*(?:"([^"]*)"|'([^']*)'|([^\s"']+))(?:\s+([iIsS]))?$/;
25091
+ var MAX_PSEUDO_PARSE_DEPTH = 4;
25092
+ function parseSelectorComplete(raw, _depth) {
25078
25093
  let start = 0;
25079
25094
  let end = raw.length;
25080
25095
  while (start < end && isWhitespace(raw.charCodeAt(start))) start++;
25081
25096
  while (end > start && isWhitespace(raw.charCodeAt(end - 1))) end--;
25082
25097
  if (start === end) {
25083
- return { parts: [], combinators: [], specificity: [0, 0, 0, 0], complexity: MINIMAL_COMPLEXITY };
25098
+ return { parts: [], compounds: [], combinators: [], specificity: [0, 0, 0, 0], complexity: MINIMAL_COMPLEXITY };
25084
25099
  }
25085
25100
  const input = start === 0 && end === raw.length ? raw : raw.substring(start, end);
25086
25101
  const len = input.length;
25087
- const parts = [];
25102
+ const allParts = [];
25103
+ let currentCompoundParts = [];
25088
25104
  const combinators = [];
25105
+ const compounds = [];
25089
25106
  let ids = 0;
25090
25107
  let classes = 0;
25091
25108
  let elements = 0;
@@ -25095,10 +25112,11 @@ function parseSelectorComplete(raw) {
25095
25112
  let hasPseudoClassFlag = false;
25096
25113
  let hasPseudoElementFlag = false;
25097
25114
  let hasNesting = false;
25098
- const pseudoClasses = [];
25099
- const pseudoElements = [];
25115
+ const pseudoClassNames = [];
25116
+ const pseudoElementNames = [];
25100
25117
  let pos = 0;
25101
25118
  let inCompound = false;
25119
+ const depth = _depth ?? 0;
25102
25120
  while (pos < len) {
25103
25121
  const char = input.charCodeAt(pos);
25104
25122
  if (isWhitespace(char) || isCombinator(char)) {
@@ -25123,6 +25141,8 @@ function parseSelectorComplete(raw) {
25123
25141
  }
25124
25142
  }
25125
25143
  if (scanPos < len) {
25144
+ compounds.push(finalizeCompound(currentCompoundParts, depth));
25145
+ currentCompoundParts = [];
25126
25146
  combinators.push(sawCombinator ?? "descendant");
25127
25147
  inCompound = false;
25128
25148
  }
@@ -25134,13 +25154,17 @@ function parseSelectorComplete(raw) {
25134
25154
  }
25135
25155
  inCompound = true;
25136
25156
  if (char === CHAR_AMPERSAND) {
25137
- parts.push({ type: "nesting", value: "&", raw: "&" });
25157
+ const part = { type: "nesting", value: "&", raw: "&" };
25158
+ allParts.push(part);
25159
+ currentCompoundParts.push(part);
25138
25160
  hasNesting = true;
25139
25161
  pos++;
25140
25162
  continue;
25141
25163
  }
25142
25164
  if (char === CHAR_ASTERISK) {
25143
- parts.push({ type: "universal", value: "*", raw: "*" });
25165
+ const part = { type: "universal", value: "*", raw: "*" };
25166
+ allParts.push(part);
25167
+ currentCompoundParts.push(part);
25144
25168
  hasUniversal = true;
25145
25169
  pos++;
25146
25170
  continue;
@@ -25151,10 +25175,26 @@ function parseSelectorComplete(raw) {
25151
25175
  if (match) {
25152
25176
  const val = match[1];
25153
25177
  if (!val) break;
25154
- parts.push({ type: "id", value: val, raw: match[0] });
25178
+ const ident2 = readCssIdentifier(input, pos + 1);
25179
+ const idVal = ident2 ? ident2.value : val;
25180
+ const idRaw = ident2 ? input.slice(pos, ident2.end) : match[0];
25181
+ const idEnd = ident2 ? ident2.end : ID_STICKY.lastIndex;
25182
+ const part = { type: "id", value: idVal, raw: idRaw };
25183
+ allParts.push(part);
25184
+ currentCompoundParts.push(part);
25155
25185
  ids++;
25156
25186
  hasId = true;
25157
- pos = ID_STICKY.lastIndex;
25187
+ pos = idEnd;
25188
+ continue;
25189
+ }
25190
+ const ident = readCssIdentifier(input, pos + 1);
25191
+ if (ident) {
25192
+ const part = { type: "id", value: ident.value, raw: input.slice(pos, ident.end) };
25193
+ allParts.push(part);
25194
+ currentCompoundParts.push(part);
25195
+ ids++;
25196
+ hasId = true;
25197
+ pos = ident.end;
25158
25198
  continue;
25159
25199
  }
25160
25200
  }
@@ -25164,9 +25204,24 @@ function parseSelectorComplete(raw) {
25164
25204
  if (match) {
25165
25205
  const val = match[1];
25166
25206
  if (!val) break;
25167
- parts.push({ type: "class", value: val, raw: match[0] });
25207
+ const ident2 = readCssIdentifier(input, pos + 1);
25208
+ const clsVal = ident2 ? ident2.value : val;
25209
+ const clsRaw = ident2 ? input.slice(pos, ident2.end) : match[0];
25210
+ const clsEnd = ident2 ? ident2.end : CLASS_STICKY.lastIndex;
25211
+ const part = { type: "class", value: clsVal, raw: clsRaw };
25212
+ allParts.push(part);
25213
+ currentCompoundParts.push(part);
25214
+ classes++;
25215
+ pos = clsEnd;
25216
+ continue;
25217
+ }
25218
+ const ident = readCssIdentifier(input, pos + 1);
25219
+ if (ident) {
25220
+ const part = { type: "class", value: ident.value, raw: input.slice(pos, ident.end) };
25221
+ allParts.push(part);
25222
+ currentCompoundParts.push(part);
25168
25223
  classes++;
25169
- pos = CLASS_STICKY.lastIndex;
25224
+ pos = ident.end;
25170
25225
  continue;
25171
25226
  }
25172
25227
  }
@@ -25176,7 +25231,9 @@ function parseSelectorComplete(raw) {
25176
25231
  if (match) {
25177
25232
  const val = match[1];
25178
25233
  if (!val) break;
25179
- parts.push({ type: "attribute", value: val, raw: match[0] });
25234
+ const part = { type: "attribute", value: val, raw: match[0] };
25235
+ allParts.push(part);
25236
+ currentCompoundParts.push(part);
25180
25237
  classes++;
25181
25238
  hasAttribute = true;
25182
25239
  pos = ATTRIBUTE_STICKY.lastIndex;
@@ -25190,10 +25247,12 @@ function parseSelectorComplete(raw) {
25190
25247
  if (match) {
25191
25248
  const val = match[1];
25192
25249
  if (!val) break;
25193
- parts.push({ type: "pseudo-element", value: val, raw: match[0] });
25250
+ const part = { type: "pseudo-element", value: val, raw: match[0] };
25251
+ allParts.push(part);
25252
+ currentCompoundParts.push(part);
25194
25253
  elements++;
25195
25254
  hasPseudoElementFlag = true;
25196
- pseudoElements.push(val);
25255
+ pseudoElementNames.push(val);
25197
25256
  pos = PSEUDO_ELEMENT_STICKY.lastIndex;
25198
25257
  continue;
25199
25258
  }
@@ -25219,19 +25278,25 @@ function parseSelectorComplete(raw) {
25219
25278
  const fullMatch = input.substring(pseudoStart, argEnd);
25220
25279
  const argContent = input.substring(nameEnd + 1, argEnd - 1);
25221
25280
  if (pseudoName === "where") {
25222
- parts.push({ type: "pseudo-class", value: pseudoName, raw: fullMatch });
25281
+ const part2 = { type: "pseudo-class", value: pseudoName, raw: fullMatch };
25282
+ allParts.push(part2);
25283
+ currentCompoundParts.push(part2);
25223
25284
  hasPseudoClassFlag = true;
25224
- pseudoClasses.push(pseudoName);
25285
+ pseudoClassNames.push(pseudoName);
25225
25286
  } else if (pseudoName === "is" || pseudoName === "not" || pseudoName === "has") {
25226
- parts.push({ type: "pseudo-class", value: pseudoName, raw: fullMatch });
25287
+ const part2 = { type: "pseudo-class", value: pseudoName, raw: fullMatch };
25288
+ allParts.push(part2);
25289
+ currentCompoundParts.push(part2);
25227
25290
  hasPseudoClassFlag = true;
25228
- pseudoClasses.push(pseudoName);
25291
+ pseudoClassNames.push(pseudoName);
25229
25292
  const args = splitPseudoArgs(argContent);
25230
25293
  let maxIds = 0, maxClasses = 0, maxElements = 0;
25231
- for (const arg of args) {
25294
+ for (let ai = 0; ai < args.length; ai++) {
25295
+ const arg = args[ai];
25296
+ if (!arg) continue;
25232
25297
  const trimmed = arg.trim();
25233
25298
  if (trimmed) {
25234
- const { specificity: argSpec } = parseSelectorComplete(trimmed);
25299
+ const { specificity: argSpec } = parseSelectorComplete(trimmed, depth + 1);
25235
25300
  if (argSpec[1] > maxIds || argSpec[1] === maxIds && argSpec[2] > maxClasses || argSpec[1] === maxIds && argSpec[2] === maxClasses && argSpec[3] > maxElements) {
25236
25301
  maxIds = argSpec[1];
25237
25302
  maxClasses = argSpec[2];
@@ -25243,18 +25308,22 @@ function parseSelectorComplete(raw) {
25243
25308
  classes += maxClasses;
25244
25309
  elements += maxElements;
25245
25310
  } else {
25246
- parts.push({ type: "pseudo-class", value: pseudoName, raw: fullMatch });
25311
+ const part2 = { type: "pseudo-class", value: pseudoName, raw: fullMatch };
25312
+ allParts.push(part2);
25313
+ currentCompoundParts.push(part2);
25247
25314
  hasPseudoClassFlag = true;
25248
- pseudoClasses.push(pseudoName);
25315
+ pseudoClassNames.push(pseudoName);
25249
25316
  classes++;
25250
25317
  }
25251
25318
  pos = argEnd;
25252
25319
  continue;
25253
25320
  }
25254
25321
  const rawMatch = input.substring(pseudoStart, nameEnd);
25255
- parts.push({ type: "pseudo-class", value: pseudoName, raw: rawMatch });
25322
+ const part = { type: "pseudo-class", value: pseudoName, raw: rawMatch };
25323
+ allParts.push(part);
25324
+ currentCompoundParts.push(part);
25256
25325
  hasPseudoClassFlag = true;
25257
- pseudoClasses.push(pseudoName);
25326
+ pseudoClassNames.push(pseudoName);
25258
25327
  classes++;
25259
25328
  pos = nameEnd;
25260
25329
  continue;
@@ -25266,7 +25335,9 @@ function parseSelectorComplete(raw) {
25266
25335
  if (match) {
25267
25336
  const val = match[1];
25268
25337
  if (!val) break;
25269
- parts.push({ type: "element", value: val, raw: match[0] });
25338
+ const part = { type: "element", value: val, raw: match[0] };
25339
+ allParts.push(part);
25340
+ currentCompoundParts.push(part);
25270
25341
  elements++;
25271
25342
  pos = ELEMENT_STICKY.lastIndex;
25272
25343
  continue;
@@ -25274,6 +25345,9 @@ function parseSelectorComplete(raw) {
25274
25345
  }
25275
25346
  pos++;
25276
25347
  }
25348
+ if (currentCompoundParts.length > 0) {
25349
+ compounds.push(finalizeCompound(currentCompoundParts, depth));
25350
+ }
25277
25351
  const complexity = buildComplexity(
25278
25352
  combinators,
25279
25353
  hasId,
@@ -25282,16 +25356,157 @@ function parseSelectorComplete(raw) {
25282
25356
  hasPseudoClassFlag,
25283
25357
  hasPseudoElementFlag,
25284
25358
  hasNesting,
25285
- pseudoClasses,
25286
- pseudoElements
25359
+ pseudoClassNames,
25360
+ pseudoElementNames
25287
25361
  );
25288
25362
  return {
25289
- parts,
25363
+ parts: allParts,
25364
+ compounds,
25290
25365
  combinators,
25291
25366
  specificity: [0, ids, classes, elements],
25292
25367
  complexity
25293
25368
  };
25294
25369
  }
25370
+ function finalizeCompound(parts, depth) {
25371
+ let tagName = null;
25372
+ let idValue = null;
25373
+ const classes = [];
25374
+ const seenClasses = /* @__PURE__ */ new Set();
25375
+ const attributes = [];
25376
+ const pseudoClasses = [];
25377
+ for (let i = 0; i < parts.length; i++) {
25378
+ const part = parts[i];
25379
+ if (!part) continue;
25380
+ if (part.type === "element") {
25381
+ tagName = part.value.toLowerCase();
25382
+ } else if (part.type === "id") {
25383
+ idValue = part.value;
25384
+ } else if (part.type === "class") {
25385
+ if (!seenClasses.has(part.value)) {
25386
+ seenClasses.add(part.value);
25387
+ classes.push(part.value);
25388
+ }
25389
+ } else if (part.type === "attribute") {
25390
+ const constraint = parseAttributeConstraintFromRaw(part.value);
25391
+ if (constraint) attributes.push(constraint);
25392
+ } else if (part.type === "pseudo-class") {
25393
+ const parsed = parsePseudoToParsedConstraint(part.value, part.raw, depth);
25394
+ if (parsed) pseudoClasses.push(parsed);
25395
+ }
25396
+ }
25397
+ return { parts, tagName, idValue, classes, attributes, pseudoClasses };
25398
+ }
25399
+ function parseAttributeConstraintFromRaw(raw) {
25400
+ const trimmed = raw.trim();
25401
+ const constrained = ATTRIBUTE_CONSTRAINT_RE.exec(trimmed);
25402
+ if (constrained) {
25403
+ const operatorToken = constrained[2];
25404
+ if (!operatorToken) return null;
25405
+ const operator = mapAttrOperator(operatorToken);
25406
+ if (operator === null) return null;
25407
+ const value2 = constrained[3] ?? constrained[4] ?? constrained[5] ?? null;
25408
+ if (value2 === null) return null;
25409
+ const nameToken = constrained[1];
25410
+ if (!nameToken) return null;
25411
+ return {
25412
+ name: nameToken.toLowerCase(),
25413
+ operator,
25414
+ value: value2,
25415
+ caseInsensitive: (constrained[6] ?? "").toLowerCase() === "i"
25416
+ };
25417
+ }
25418
+ if (!ATTRIBUTE_EXISTS_RE.test(trimmed)) return null;
25419
+ return { name: trimmed.toLowerCase(), operator: "exists", value: null, caseInsensitive: false };
25420
+ }
25421
+ function mapAttrOperator(op) {
25422
+ if (op === "=") return "equals";
25423
+ if (op === "~=") return "includes-word";
25424
+ if (op === "|=") return "dash-prefix";
25425
+ if (op === "^=") return "prefix";
25426
+ if (op === "$=") return "suffix";
25427
+ if (op === "*=") return "contains";
25428
+ return null;
25429
+ }
25430
+ function parsePseudoToParsedConstraint(name, raw, depth) {
25431
+ const lowerName = name.toLowerCase();
25432
+ if (lowerName === "first-child") return { name: lowerName, raw, kind: 1 /* FirstChild */, nthPattern: null, nestedCompounds: null };
25433
+ if (lowerName === "last-child") return { name: lowerName, raw, kind: 2 /* LastChild */, nthPattern: null, nestedCompounds: null };
25434
+ if (lowerName === "only-child") return { name: lowerName, raw, kind: 3 /* OnlyChild */, nthPattern: null, nestedCompounds: null };
25435
+ const parenIdx = raw.indexOf("(");
25436
+ if (parenIdx === -1) {
25437
+ return { name: lowerName, raw, kind: 0 /* Simple */, nthPattern: null, nestedCompounds: null };
25438
+ }
25439
+ const argContent = raw.substring(parenIdx + 1, raw.length - 1);
25440
+ if (lowerName === "nth-child") {
25441
+ const pattern = parseNthPatternFromArg(argContent);
25442
+ return pattern ? { name: lowerName, raw, kind: 4 /* NthChild */, nthPattern: pattern, nestedCompounds: null } : null;
25443
+ }
25444
+ if (lowerName === "nth-last-child") {
25445
+ const pattern = parseNthPatternFromArg(argContent);
25446
+ return pattern ? { name: lowerName, raw, kind: 5 /* NthLastChild */, nthPattern: pattern, nestedCompounds: null } : null;
25447
+ }
25448
+ if (lowerName === "nth-of-type") {
25449
+ const pattern = parseNthPatternFromArg(argContent);
25450
+ return pattern ? { name: lowerName, raw, kind: 6 /* NthOfType */, nthPattern: pattern, nestedCompounds: null } : null;
25451
+ }
25452
+ if (lowerName === "nth-last-of-type") {
25453
+ const pattern = parseNthPatternFromArg(argContent);
25454
+ return pattern ? { name: lowerName, raw, kind: 7 /* NthLastOfType */, nthPattern: pattern, nestedCompounds: null } : null;
25455
+ }
25456
+ if (lowerName === "is" || lowerName === "where") {
25457
+ if (depth >= MAX_PSEUDO_PARSE_DEPTH) return { name: lowerName, raw, kind: 8 /* MatchesAny */, nthPattern: null, nestedCompounds: null };
25458
+ const nested = parseNestedCompoundGroups(argContent, depth + 1);
25459
+ return { name: lowerName, raw, kind: 8 /* MatchesAny */, nthPattern: null, nestedCompounds: nested };
25460
+ }
25461
+ if (lowerName === "not") {
25462
+ if (depth >= MAX_PSEUDO_PARSE_DEPTH) return { name: lowerName, raw, kind: 9 /* NoneOf */, nthPattern: null, nestedCompounds: null };
25463
+ const nested = parseNestedCompoundGroups(argContent, depth + 1);
25464
+ return { name: lowerName, raw, kind: 9 /* NoneOf */, nthPattern: null, nestedCompounds: nested };
25465
+ }
25466
+ return { name: lowerName, raw, kind: 0 /* Simple */, nthPattern: null, nestedCompounds: null };
25467
+ }
25468
+ function parseNestedCompoundGroups(argContent, depth) {
25469
+ const args = splitPseudoArgs(argContent);
25470
+ const groups = [];
25471
+ for (let i = 0; i < args.length; i++) {
25472
+ const arg = args[i];
25473
+ if (!arg) continue;
25474
+ const trimmed = arg.trim();
25475
+ if (!trimmed) continue;
25476
+ const result = parseSelectorComplete(trimmed, depth);
25477
+ if (result.compounds.length > 0) {
25478
+ groups.push(result.compounds.slice());
25479
+ }
25480
+ }
25481
+ return groups;
25482
+ }
25483
+ function parseNthPatternFromArg(raw) {
25484
+ const normalized = raw.trim().toLowerCase().replaceAll(" ", "");
25485
+ if (normalized.length === 0) return null;
25486
+ if (normalized === "odd") return { step: 2, offset: 1 };
25487
+ if (normalized === "even") return { step: 2, offset: 0 };
25488
+ const nIndex = normalized.indexOf("n");
25489
+ if (nIndex === -1) {
25490
+ const value2 = Number.parseInt(normalized, 10);
25491
+ if (Number.isNaN(value2)) return null;
25492
+ return { step: 0, offset: value2 };
25493
+ }
25494
+ const stepPart = normalized.slice(0, nIndex);
25495
+ const offsetPart = normalized.slice(nIndex + 1);
25496
+ let step;
25497
+ if (stepPart.length === 0 || stepPart === "+") step = 1;
25498
+ else if (stepPart === "-") step = -1;
25499
+ else {
25500
+ step = Number.parseInt(stepPart, 10);
25501
+ if (Number.isNaN(step)) return null;
25502
+ }
25503
+ let offset = 0;
25504
+ if (offsetPart.length > 0) {
25505
+ offset = Number.parseInt(offsetPart, 10);
25506
+ if (Number.isNaN(offset)) return null;
25507
+ }
25508
+ return { step, offset };
25509
+ }
25295
25510
  function splitPseudoArgs(content) {
25296
25511
  const result = [];
25297
25512
  let start = 0;
@@ -25640,8 +25855,6 @@ function extractVarReferences(value2) {
25640
25855
 
25641
25856
  // src/css/phases/ast.ts
25642
25857
  var CSS_IDENT = /^[-_a-zA-Z][-_a-zA-Z0-9]*$/;
25643
- var ATTRIBUTE_EXISTS_RE = /^[-_a-zA-Z][-_a-zA-Z0-9]*$/;
25644
- var ATTRIBUTE_CONSTRAINT_RE = /^([-_a-zA-Z][-_a-zA-Z0-9]*)\s*(=|~=|\|=|\^=|\$=|\*=)\s*(?:"([^"]*)"|'([^']*)'|([^\s"']+))(?:\s+([iIsS]))?$/;
25645
25858
  var ROOT_CONTEXT = {
25646
25859
  parentRule: null,
25647
25860
  parentAtRule: null,
@@ -26108,142 +26321,6 @@ function getRuleBlockOffsets(file, startOffset, endOffset) {
26108
26321
  blockEndOffset: close
26109
26322
  };
26110
26323
  }
26111
- function extractSubjectCompound(raw) {
26112
- const len = raw.length;
26113
- if (len === 0) return "";
26114
- let end = len - 1;
26115
- while (end >= 0 && isWhitespace(raw.charCodeAt(end))) end--;
26116
- if (end < 0) return "";
26117
- let parenDepth = 0;
26118
- let bracketDepth = 0;
26119
- for (let i = end; i >= 0; i--) {
26120
- const code = raw.charCodeAt(i);
26121
- if (code === CHAR_CLOSE_PAREN) {
26122
- parenDepth++;
26123
- continue;
26124
- }
26125
- if (code === CHAR_OPEN_PAREN) {
26126
- if (parenDepth > 0) parenDepth--;
26127
- continue;
26128
- }
26129
- if (code === CHAR_CLOSE_BRACKET) {
26130
- bracketDepth++;
26131
- continue;
26132
- }
26133
- if (code === CHAR_OPEN_BRACKET) {
26134
- if (bracketDepth > 0) bracketDepth--;
26135
- continue;
26136
- }
26137
- if (parenDepth > 0 || bracketDepth > 0) continue;
26138
- if (code === CHAR_GT || code === CHAR_PLUS || code === CHAR_TILDE) {
26139
- return raw.slice(i + 1, end + 1).trim();
26140
- }
26141
- if (!isWhitespace(code)) continue;
26142
- return raw.slice(i + 1, end + 1).trim();
26143
- }
26144
- return raw.slice(0, end + 1).trim();
26145
- }
26146
- function parseAnchorAttributes(parts) {
26147
- const out = [];
26148
- for (let i = 0; i < parts.length; i++) {
26149
- const part = parts[i];
26150
- if (!part) continue;
26151
- if (part.type !== "attribute") continue;
26152
- const trimmed = part.value.trim();
26153
- const constrained = ATTRIBUTE_CONSTRAINT_RE.exec(trimmed);
26154
- if (constrained) {
26155
- const opToken = constrained[2];
26156
- if (!opToken) continue;
26157
- const operator = mapAttributeOperatorFromToken(opToken);
26158
- if (operator === null) continue;
26159
- const value2 = constrained[3] ?? constrained[4] ?? constrained[5] ?? null;
26160
- if (value2 === null) continue;
26161
- const attrName = constrained[1];
26162
- if (!attrName) continue;
26163
- out.push({
26164
- name: attrName.toLowerCase(),
26165
- operator,
26166
- value: value2,
26167
- caseInsensitive: (constrained[6] ?? "").toLowerCase() === "i"
26168
- });
26169
- continue;
26170
- }
26171
- if (!ATTRIBUTE_EXISTS_RE.test(trimmed)) continue;
26172
- out.push({
26173
- name: trimmed.toLowerCase(),
26174
- operator: "exists",
26175
- value: null,
26176
- caseInsensitive: false
26177
- });
26178
- }
26179
- return out;
26180
- }
26181
- function mapAttributeOperatorFromToken(operator) {
26182
- if (operator === "=") return "equals";
26183
- if (operator === "~=") return "includes-word";
26184
- if (operator === "|=") return "dash-prefix";
26185
- if (operator === "^=") return "prefix";
26186
- if (operator === "$=") return "suffix";
26187
- if (operator === "*=") return "contains";
26188
- return null;
26189
- }
26190
- function buildSelectorAnchor(raw, parts, combinators) {
26191
- const subjectCompound = extractSubjectCompound(raw);
26192
- const subjectParts = parseSelector(subjectCompound);
26193
- let subjectTag = null;
26194
- const classes = [];
26195
- const seenClasses = /* @__PURE__ */ new Set();
26196
- for (let i = 0; i < subjectParts.length; i++) {
26197
- const part = subjectParts[i];
26198
- if (!part) continue;
26199
- if (part.type === "element") {
26200
- subjectTag = part.value.toLowerCase();
26201
- continue;
26202
- }
26203
- if (part.type !== "class") continue;
26204
- const cls = part.value;
26205
- if (seenClasses.has(cls)) continue;
26206
- seenClasses.add(cls);
26207
- classes.push(cls);
26208
- }
26209
- const attributes = parseAnchorAttributes(subjectParts);
26210
- const includesDescendantCombinator = combinators.includes("descendant");
26211
- let includesPseudoSelector = false;
26212
- let includesNesting = false;
26213
- for (let i = 0; i < parts.length; i++) {
26214
- const part = parts[i];
26215
- if (!part) continue;
26216
- if (part.type === "pseudo-class" || part.type === "pseudo-element") {
26217
- includesPseudoSelector = true;
26218
- continue;
26219
- }
26220
- if (part.type === "nesting") includesNesting = true;
26221
- }
26222
- let hasCheckboxAttribute = false;
26223
- for (let i = 0; i < attributes.length; i++) {
26224
- const a = attributes[i];
26225
- if (!a) continue;
26226
- if (a.name !== "type") continue;
26227
- if (a.operator !== "equals") continue;
26228
- if (a.value === null) continue;
26229
- const normalized = a.caseInsensitive ? a.value.toLowerCase() : a.value;
26230
- if (normalized !== "checkbox") continue;
26231
- hasCheckboxAttribute = true;
26232
- break;
26233
- }
26234
- const targetsCheckbox = (subjectTag === "input" || subjectTag === null) && hasCheckboxAttribute;
26235
- const targetsTableCell = subjectTag === "td" || subjectTag === "th";
26236
- return {
26237
- subjectTag,
26238
- classes,
26239
- attributes,
26240
- includesDescendantCombinator,
26241
- includesPseudoSelector,
26242
- dynamic: includesPseudoSelector || includesNesting,
26243
- targetsCheckbox,
26244
- targetsTableCell
26245
- };
26246
- }
26247
26324
  function createRuleEntity(graph, node, file, context) {
26248
26325
  const { parentRule, parentAtRule, containingMedia, containingLayer, depth } = context;
26249
26326
  const id = graph.nextRuleId();
@@ -26290,9 +26367,55 @@ function createRuleEntity(graph, node, file, context) {
26290
26367
  }
26291
26368
  function createSelectorEntity(graph, raw, rule) {
26292
26369
  const id = graph.nextSelectorId();
26293
- const { parts, specificity, complexity } = parseSelectorComplete(raw);
26370
+ const { parts, compounds, combinators, specificity, complexity } = parseSelectorComplete(raw);
26294
26371
  const specificityScore = specificityToScore(specificity);
26295
- const anchor = buildSelectorAnchor(raw, parts, complexity.combinators);
26372
+ const kinds = rule.elementKinds;
26373
+ for (let k = 0; k < parts.length; k++) {
26374
+ const part = parts[k];
26375
+ if (part) classifyPart(part, kinds);
26376
+ }
26377
+ const subject = compounds.length > 0 ? compounds[compounds.length - 1] : null;
26378
+ let includesPseudoSelector = false;
26379
+ let includesNesting = false;
26380
+ for (let i = 0; i < parts.length; i++) {
26381
+ const part = parts[i];
26382
+ if (!part) continue;
26383
+ if (part.type === "pseudo-class" || part.type === "pseudo-element") {
26384
+ includesPseudoSelector = true;
26385
+ continue;
26386
+ }
26387
+ if (part.type === "nesting") includesNesting = true;
26388
+ }
26389
+ const subjectTag = subject?.tagName ?? null;
26390
+ const subjectIdValue = subject?.idValue ?? null;
26391
+ const subjectClasses = subject?.classes ?? [];
26392
+ const subjectAttributes = subject?.attributes ?? [];
26393
+ const includesDescendantCombinator = combinators.includes("descendant");
26394
+ let hasCheckboxAttribute = false;
26395
+ for (let i = 0; i < subjectAttributes.length; i++) {
26396
+ const a = subjectAttributes[i];
26397
+ if (!a) continue;
26398
+ if (a.name !== "type") continue;
26399
+ if (a.operator !== "equals") continue;
26400
+ if (a.value === null) continue;
26401
+ const normalized = a.caseInsensitive ? a.value.toLowerCase() : a.value;
26402
+ if (normalized !== "checkbox") continue;
26403
+ hasCheckboxAttribute = true;
26404
+ break;
26405
+ }
26406
+ const targetsCheckbox = (subjectTag === "input" || subjectTag === null) && hasCheckboxAttribute;
26407
+ const targetsTableCell = subjectTag === "td" || subjectTag === "th";
26408
+ const anchor = {
26409
+ subjectTag,
26410
+ idValue: subjectIdValue,
26411
+ classes: subjectClasses,
26412
+ attributes: subjectAttributes,
26413
+ includesDescendantCombinator,
26414
+ includesPseudoSelector,
26415
+ dynamic: includesPseudoSelector || includesNesting,
26416
+ targetsCheckbox,
26417
+ targetsTableCell
26418
+ };
26296
26419
  return {
26297
26420
  id,
26298
26421
  raw,
@@ -26300,6 +26423,8 @@ function createSelectorEntity(graph, raw, rule) {
26300
26423
  specificity,
26301
26424
  specificityScore,
26302
26425
  complexity,
26426
+ compounds,
26427
+ combinators,
26303
26428
  parts: parts.length > 0 ? parts : [],
26304
26429
  anchor,
26305
26430
  overrides: [],
@@ -27960,57 +28085,31 @@ var mediaQueryOverlapConflict = defineCSSRule({
27960
28085
  var messages101 = {
27961
28086
  descendingSpecificity: "Lower-specificity selector `{{laterSelector}}` appears after `{{earlierSelector}}` for `{{property}}`, creating brittle cascade behavior."
27962
28087
  };
27963
- var UNSUPPORTED_TYPES = /* @__PURE__ */ new Set(["attribute", "pseudo-class", "pseudo-element", "universal", "nesting"]);
27964
28088
  function extractCompounds(selector) {
27965
- const parts = selector.parts;
27966
- if (parts.length === 0) return null;
27967
- for (let i = 0; i < parts.length; i++) {
27968
- const part = parts[i];
27969
- if (!part) continue;
27970
- if (UNSUPPORTED_TYPES.has(part.type)) return null;
28089
+ const selectorCompounds = selector.compounds;
28090
+ if (selectorCompounds.length === 0) return null;
28091
+ for (let i = 0; i < selectorCompounds.length; i++) {
28092
+ const sc = selectorCompounds[i];
28093
+ if (!sc) continue;
28094
+ const parts = sc.parts;
28095
+ for (let j = 0; j < parts.length; j++) {
28096
+ const part = parts[j];
28097
+ if (!part) continue;
28098
+ const t = part.type;
28099
+ if (t === "attribute" || t === "pseudo-class" || t === "pseudo-element" || t === "universal" || t === "nesting") return null;
28100
+ }
27971
28101
  }
27972
- return splitIntoCompounds(selector);
27973
- }
27974
- function splitIntoCompounds(selector) {
27975
- const raw = selector.raw;
27976
- const combinators = selector.complexity.combinators;
27977
- const segments = splitRawByCombinators(raw);
27978
- if (!segments || segments.length !== combinators.length + 1) return null;
27979
28102
  const compounds = [];
27980
- for (let i = 0; i < segments.length; i++) {
27981
- const seg = segments[i];
27982
- if (!seg) continue;
27983
- const compound = parseCompoundFromParts(seg);
27984
- if (!compound) return null;
27985
- compounds.push(compound);
28103
+ for (let i = 0; i < selectorCompounds.length; i++) {
28104
+ const sc = selectorCompounds[i];
28105
+ if (!sc) continue;
28106
+ const ids = [];
28107
+ if (sc.idValue !== null) ids.push(sc.idValue);
28108
+ if (!sc.tagName && sc.classes.length === 0 && ids.length === 0) return null;
28109
+ compounds.push({ tag: sc.tagName, classes: sc.classes, ids });
27986
28110
  }
27987
28111
  return compounds;
27988
28112
  }
27989
- var COMBINATOR_SPLIT = /\s*[>+~]\s*|\s+/;
27990
- function splitRawByCombinators(raw) {
27991
- const trimmed = raw.trim();
27992
- if (trimmed.length === 0) return null;
27993
- const segments = trimmed.split(COMBINATOR_SPLIT).filter((s) => s.length > 0);
27994
- return segments.length > 0 ? segments : null;
27995
- }
27996
- var COMPOUND_TOKEN = /([.#]?)([_a-zA-Z][_a-zA-Z0-9-]*)/g;
27997
- function parseCompoundFromParts(segment) {
27998
- let tag = null;
27999
- const classes = [];
28000
- const ids = [];
28001
- COMPOUND_TOKEN.lastIndex = 0;
28002
- let match;
28003
- while ((match = COMPOUND_TOKEN.exec(segment)) !== null) {
28004
- const prefix = match[1];
28005
- const value2 = match[2];
28006
- if (!value2) continue;
28007
- if (prefix === ".") classes.push(value2);
28008
- else if (prefix === "#") ids.push(value2);
28009
- else tag = value2;
28010
- }
28011
- if (!tag && classes.length === 0 && ids.length === 0) return null;
28012
- return { tag, classes, ids };
28013
- }
28014
28113
  function hasToken(list, token) {
28015
28114
  for (let i = 0; i < list.length; i++) {
28016
28115
  if (list[i] === token) return true;
@@ -28052,8 +28151,8 @@ function isProvableDescendingPair(earlier, later) {
28052
28151
  if (!earlierCompounds) return false;
28053
28152
  const laterCompounds = extractCompounds(later);
28054
28153
  if (!laterCompounds) return false;
28055
- const earlierCombinators = earlier.complexity.combinators;
28056
- const laterCombinators = later.complexity.combinators;
28154
+ const earlierCombinators = earlier.combinators;
28155
+ const laterCombinators = later.combinators;
28057
28156
  if (earlierCompounds.length !== laterCompounds.length) return false;
28058
28157
  if (earlierCombinators.length !== laterCombinators.length) return false;
28059
28158
  for (let i = 0; i < earlierCombinators.length; i++) {
@@ -30810,6 +30909,8 @@ var layoutSignalNames = [
30810
30909
  "min-width",
30811
30910
  "min-block-size",
30812
30911
  "min-height",
30912
+ "max-width",
30913
+ "max-height",
30813
30914
  "aspect-ratio",
30814
30915
  "vertical-align",
30815
30916
  "display",
@@ -30828,6 +30929,7 @@ var layoutSignalNames = [
30828
30929
  "place-items",
30829
30930
  "place-self",
30830
30931
  "flex-direction",
30932
+ "flex-basis",
30831
30933
  "grid-auto-flow",
30832
30934
  "appearance",
30833
30935
  "box-sizing",
@@ -30915,80 +31017,6 @@ function parseSignedPxValue(raw) {
30915
31017
  return parsePxValue(trimmed);
30916
31018
  }
30917
31019
 
30918
- // src/cross-file/layout/shorthand-expansion.ts
30919
- var QUAD_EXPANSIONS = /* @__PURE__ */ new Map([
30920
- ["padding", ["padding-top", "padding-right", "padding-bottom", "padding-left"]],
30921
- ["border-width", ["border-top-width", "border-right-width", "border-bottom-width", "border-left-width"]],
30922
- ["margin", ["margin-top", "margin-right", "margin-bottom", "margin-left"]],
30923
- ["inset", ["top", "right", "bottom", "left"]]
30924
- ]);
30925
- var BLOCK_EXPANSIONS = /* @__PURE__ */ new Map([
30926
- ["margin-block", ["margin-top", "margin-bottom"]],
30927
- ["padding-block", ["padding-top", "padding-bottom"]],
30928
- ["inset-block", ["inset-block-start", "inset-block-end"]]
30929
- ]);
30930
- function expandShorthand(property, value2) {
30931
- const quadTarget = QUAD_EXPANSIONS.get(property);
30932
- if (quadTarget !== void 0) {
30933
- const parsed = parseQuadShorthand(value2);
30934
- if (parsed === null) return null;
30935
- return [
30936
- { name: quadTarget[0], value: parsed.top },
30937
- { name: quadTarget[1], value: parsed.right },
30938
- { name: quadTarget[2], value: parsed.bottom },
30939
- { name: quadTarget[3], value: parsed.left }
30940
- ];
30941
- }
30942
- const blockTarget = BLOCK_EXPANSIONS.get(property);
30943
- if (blockTarget !== void 0) {
30944
- const parsed = parseBlockShorthand(value2);
30945
- if (parsed === null) return null;
30946
- return [
30947
- { name: blockTarget[0], value: parsed.start },
30948
- { name: blockTarget[1], value: parsed.end }
30949
- ];
30950
- }
30951
- if (property === "flex-flow") {
30952
- return expandFlexFlow(value2);
30953
- }
30954
- return void 0;
30955
- }
30956
- var FLEX_DIRECTION_VALUES = /* @__PURE__ */ new Set(["row", "row-reverse", "column", "column-reverse"]);
30957
- function expandFlexFlow(value2) {
30958
- const tokens = splitWhitespaceTokens(value2.trim().toLowerCase());
30959
- if (tokens.length === 0) return null;
30960
- if (tokens.length > 2) return null;
30961
- let direction = null;
30962
- let wrap = null;
30963
- for (let i = 0; i < tokens.length; i++) {
30964
- const token = tokens[i];
30965
- if (!token) continue;
30966
- if (FLEX_DIRECTION_VALUES.has(token)) {
30967
- if (direction !== null) return null;
30968
- direction = token;
30969
- } else {
30970
- if (wrap !== null) return null;
30971
- wrap = token;
30972
- }
30973
- }
30974
- const out = [];
30975
- if (direction !== null) {
30976
- out.push({ name: "flex-direction", value: direction });
30977
- }
30978
- if (wrap !== null) {
30979
- out.push({ name: "flex-wrap", value: wrap });
30980
- }
30981
- return out.length > 0 ? out : null;
30982
- }
30983
- function getShorthandLonghandNames(property) {
30984
- const quad = QUAD_EXPANSIONS.get(property);
30985
- if (quad !== void 0) return [...quad];
30986
- const block = BLOCK_EXPANSIONS.get(property);
30987
- if (block !== void 0) return [...block];
30988
- if (property === "flex-flow") return ["flex-direction", "flex-wrap"];
30989
- return null;
30990
- }
30991
-
30992
31020
  // src/cross-file/layout/util.ts
30993
31021
  var CONTROL_ELEMENT_TAGS = /* @__PURE__ */ new Set([
30994
31022
  "input",
@@ -31093,6 +31121,7 @@ var MONITORED_SHORTHAND_SET = /* @__PURE__ */ new Set([
31093
31121
  "border-width",
31094
31122
  "margin-block",
31095
31123
  "padding-block",
31124
+ "padding-inline",
31096
31125
  "inset-block",
31097
31126
  "flex-flow"
31098
31127
  ]);
@@ -31105,6 +31134,9 @@ var LENGTH_SIGNAL_SET = /* @__PURE__ */ new Set([
31105
31134
  "min-width",
31106
31135
  "min-block-size",
31107
31136
  "min-height",
31137
+ "max-width",
31138
+ "max-height",
31139
+ "flex-basis",
31108
31140
  "top",
31109
31141
  "bottom",
31110
31142
  "margin-top",
@@ -31158,11 +31190,11 @@ function isMonitoredSignal(property) {
31158
31190
  }
31159
31191
  function isControlTag(tag) {
31160
31192
  if (tag === null) return false;
31161
- return CONTROL_ELEMENT_TAGS.has(tag.toLowerCase());
31193
+ return CONTROL_ELEMENT_TAGS.has(tag);
31162
31194
  }
31163
31195
  function isReplacedTag(tag) {
31164
31196
  if (tag === null) return false;
31165
- return REPLACED_ELEMENT_TAGS.has(tag.toLowerCase());
31197
+ return REPLACED_ELEMENT_TAGS.has(tag);
31166
31198
  }
31167
31199
  function normalizeSignalMapWithCounts(values) {
31168
31200
  const out = /* @__PURE__ */ new Map();
@@ -31177,16 +31209,12 @@ function normalizeSignalMapWithCounts(values) {
31177
31209
  null
31178
31210
  );
31179
31211
  out.set("font-size", parsedFontSize);
31180
- if (parsedFontSize.kind === "known" && parsedFontSize.guard.kind === 0 /* Unconditional */) {
31212
+ if (parsedFontSize.kind === 0 /* Known */ && parsedFontSize.guard.kind === 0 /* Unconditional */) {
31181
31213
  fontSizePx = parsedFontSize.px;
31182
31214
  }
31183
31215
  }
31184
31216
  for (const [property, declaration] of values) {
31185
31217
  if (property === "font-size") continue;
31186
- if (MONITORED_SHORTHAND_SET.has(property)) {
31187
- applyExpandedShorthand(out, property, declaration, fontSizePx);
31188
- continue;
31189
- }
31190
31218
  const name = toMonitoredSignalName(property);
31191
31219
  if (!name) continue;
31192
31220
  const normalized = normalizeSignal(
@@ -31206,7 +31234,7 @@ function normalizeSignalMapWithCounts(values) {
31206
31234
  conditionalSignalCount++;
31207
31235
  continue;
31208
31236
  }
31209
- if (value2.kind === "known") {
31237
+ if (value2.kind === 0 /* Known */) {
31210
31238
  knownSignalCount++;
31211
31239
  continue;
31212
31240
  }
@@ -31219,30 +31247,6 @@ function normalizeSignalMapWithCounts(values) {
31219
31247
  conditionalSignalCount
31220
31248
  };
31221
31249
  }
31222
- function applyExpandedShorthand(out, property, declaration, fontSizePx) {
31223
- const expanded = expandShorthand(property, declaration.value);
31224
- if (expanded === null) {
31225
- const reason = `${property} value is not statically parseable`;
31226
- const longhandNames = getShorthandLonghandNames(property);
31227
- if (longhandNames === null) return;
31228
- for (let i = 0; i < longhandNames.length; i++) {
31229
- const longhand = longhandNames[i];
31230
- if (!longhand) continue;
31231
- const name = MONITORED_SIGNAL_NAME_MAP.get(longhand);
31232
- if (name === void 0) continue;
31233
- out.set(name, createUnknown(name, declaration.source, declaration.guardProvenance, reason));
31234
- }
31235
- return;
31236
- }
31237
- if (expanded === void 0) return;
31238
- for (let i = 0; i < expanded.length; i++) {
31239
- const entry = expanded[i];
31240
- if (!entry) continue;
31241
- const name = MONITORED_SIGNAL_NAME_MAP.get(entry.name);
31242
- if (name === void 0) continue;
31243
- out.set(name, normalizeSignal(name, entry.value, declaration.source, declaration.guardProvenance, fontSizePx));
31244
- }
31245
- }
31246
31250
  function toMonitoredSignalName(property) {
31247
31251
  return MONITORED_SIGNAL_NAME_MAP.get(property) ?? null;
31248
31252
  }
@@ -31283,13 +31287,13 @@ function parseAspectRatio(name, raw, source, guard) {
31283
31287
  if (!Number.isFinite(left) || !Number.isFinite(right) || left <= 0 || right <= 0) {
31284
31288
  return createUnknown(name, source, guard, "aspect-ratio ratio is invalid");
31285
31289
  }
31286
- return createKnown(name, raw, source, guard, null, 1 /* Unitless */, "exact");
31290
+ return createKnown(name, trimmed, source, guard, null, 1 /* Unitless */, 0 /* Exact */);
31287
31291
  }
31288
31292
  const ratio = Number(trimmed);
31289
31293
  if (!Number.isFinite(ratio) || ratio <= 0) {
31290
31294
  return createUnknown(name, source, guard, "aspect-ratio is not statically parseable");
31291
31295
  }
31292
- return createKnown(name, raw, source, guard, null, 1 /* Unitless */, "exact");
31296
+ return createKnown(name, trimmed, source, guard, null, 1 /* Unitless */, 0 /* Exact */);
31293
31297
  }
31294
31298
  function parseContainIntrinsicSize(name, raw, source, guard) {
31295
31299
  const trimmed = raw.trim().toLowerCase();
@@ -31307,18 +31311,19 @@ function parseContainIntrinsicSize(name, raw, source, guard) {
31307
31311
  const part = parts[i];
31308
31312
  if (!part) continue;
31309
31313
  const px = parseSignedPxValue(part);
31310
- if (px !== null) return createKnown(name, raw, source, guard, px, 0 /* Px */, "exact");
31314
+ if (px !== null) return createKnown(name, trimmed, source, guard, px, 0 /* Px */, 0 /* Exact */);
31311
31315
  }
31312
31316
  return createUnknown(name, source, guard, "contain-intrinsic-size is not statically parseable in px");
31313
31317
  }
31314
31318
  function parseLineHeight(name, raw, source, guard, fontSizePx) {
31319
+ const normalized = raw.trim().toLowerCase();
31315
31320
  const unitless = parseUnitlessValue(raw);
31316
31321
  if (unitless !== null) {
31317
31322
  const base = fontSizePx === null ? 16 : fontSizePx;
31318
- return createKnown(name, raw, source, guard, unitless * base, 1 /* Unitless */, "estimated");
31323
+ return createKnown(name, normalized, source, guard, unitless * base, 1 /* Unitless */, 1 /* Estimated */);
31319
31324
  }
31320
31325
  const px = parseSignedPxValue(raw);
31321
- if (px !== null) return createKnown(name, raw, source, guard, px, 0 /* Px */, "exact");
31326
+ if (px !== null) return createKnown(name, normalized, source, guard, px, 0 /* Px */, 0 /* Exact */);
31322
31327
  return createUnknown(name, source, guard, "line-height is not statically parseable");
31323
31328
  }
31324
31329
  var DIMENSION_KEYWORD_SET = /* @__PURE__ */ new Set([
@@ -31327,16 +31332,21 @@ var DIMENSION_KEYWORD_SET = /* @__PURE__ */ new Set([
31327
31332
  "fit-content",
31328
31333
  "min-content",
31329
31334
  "max-content",
31330
- "stretch"
31335
+ "stretch",
31336
+ "inherit",
31337
+ "initial",
31338
+ "unset",
31339
+ "revert",
31340
+ "revert-layer"
31331
31341
  ]);
31332
31342
  function parseLength(name, raw, source, guard) {
31333
31343
  const px = parseSignedPxValue(raw);
31344
+ const normalized = raw.trim().toLowerCase();
31334
31345
  if (px !== null) {
31335
- return createKnown(name, raw, source, guard, px, 0 /* Px */, "exact");
31346
+ return createKnown(name, normalized, source, guard, px, 0 /* Px */, 0 /* Exact */);
31336
31347
  }
31337
- const normalized = raw.trim().toLowerCase();
31338
31348
  if (DIMENSION_KEYWORD_SET.has(normalized) || normalized.startsWith("fit-content(")) {
31339
- return createKnown(name, raw, source, guard, null, 2 /* Keyword */, "exact");
31349
+ return createKnown(name, normalized, source, guard, null, 2 /* Keyword */, 0 /* Exact */);
31340
31350
  }
31341
31351
  return createUnknown(name, source, guard, "length is not statically parseable in px");
31342
31352
  }
@@ -31348,7 +31358,7 @@ function parseKeyword(name, raw, source, guard) {
31348
31358
  if (hasDynamicExpression(normalized)) {
31349
31359
  return createUnknown(name, source, guard, "keyword uses runtime-dependent function");
31350
31360
  }
31351
- return createKnown(name, raw, source, guard, null, 2 /* Keyword */, "exact");
31361
+ return createKnown(name, normalized, source, guard, null, 2 /* Keyword */, 0 /* Exact */);
31352
31362
  }
31353
31363
  function parseTransform(name, raw, source, guard) {
31354
31364
  const normalized = raw.trim().toLowerCase();
@@ -31359,7 +31369,7 @@ function parseTransform(name, raw, source, guard) {
31359
31369
  return createUnknown(name, source, guard, "transform uses runtime-dependent function");
31360
31370
  }
31361
31371
  const y = extractTransformYPx(normalized);
31362
- if (y !== null) return createKnown(name, raw, source, guard, y, 0 /* Px */, "exact");
31372
+ if (y !== null) return createKnown(name, normalized, source, guard, y, 0 /* Px */, 0 /* Exact */);
31363
31373
  return createUnknown(name, source, guard, "transform has non-translational or non-px functions");
31364
31374
  }
31365
31375
  function parseTranslateProperty(name, raw, source, guard) {
@@ -31371,24 +31381,20 @@ function parseTranslateProperty(name, raw, source, guard) {
31371
31381
  return createUnknown(name, source, guard, "translate uses runtime-dependent function");
31372
31382
  }
31373
31383
  const y = extractTranslatePropertyYPx(trimmed);
31374
- if (y !== null) return createKnown(name, raw, source, guard, y, 0 /* Px */, "exact");
31384
+ if (y !== null) return createKnown(name, trimmed, source, guard, y, 0 /* Px */, 0 /* Exact */);
31375
31385
  return createUnknown(name, source, guard, "translate property vertical component is not px");
31376
31386
  }
31377
31387
  function hasDynamicExpression(raw) {
31378
31388
  if (raw.includes("var(")) return true;
31379
- if (raw.includes("calc(")) return true;
31380
31389
  if (raw.includes("env(")) return true;
31381
31390
  if (raw.includes("attr(")) return true;
31382
- if (raw.includes("min(")) return true;
31383
- if (raw.includes("max(")) return true;
31384
- if (raw.includes("clamp(")) return true;
31385
31391
  return false;
31386
31392
  }
31387
- function createKnown(name, raw, source, guard, px, unit, quality) {
31393
+ function createKnown(name, normalized, source, guard, px, unit, quality) {
31388
31394
  return {
31389
- kind: "known",
31395
+ kind: 0 /* Known */,
31390
31396
  name,
31391
- normalized: raw.trim().toLowerCase(),
31397
+ normalized,
31392
31398
  source,
31393
31399
  guard,
31394
31400
  unit,
@@ -31398,7 +31404,7 @@ function createKnown(name, raw, source, guard, px, unit, quality) {
31398
31404
  }
31399
31405
  function createUnknown(name, source, guard, reason) {
31400
31406
  return {
31401
- kind: "unknown",
31407
+ kind: 1 /* Unknown */,
31402
31408
  name,
31403
31409
  source,
31404
31410
  guard,
@@ -31414,49 +31420,23 @@ var INHERITED_SIGNAL_NAMES = [
31414
31420
  "direction"
31415
31421
  ];
31416
31422
  function collectSignalSnapshot(context, node) {
31417
- const existing = context.layout.snapshotByElementNode.get(node);
31418
- if (existing) {
31423
+ const record = context.layout.records.get(node);
31424
+ if (record) {
31419
31425
  context.layout.perf.signalSnapshotCacheHits++;
31420
- return existing;
31421
- }
31422
- throw new Error(`missing precomputed layout snapshot for ${node.key}`);
31423
- }
31424
- function buildSignalSnapshotIndex(elements, cascadeByElementNode, perf) {
31425
- const snapshotByElementNode = /* @__PURE__ */ new WeakMap();
31426
- for (let i = 0; i < elements.length; i++) {
31427
- const element = elements[i];
31428
- if (!element) continue;
31429
- buildSnapshotForNode(element, cascadeByElementNode, snapshotByElementNode, perf);
31426
+ return record.snapshot;
31430
31427
  }
31431
- return snapshotByElementNode;
31428
+ throw new Error(`missing precomputed layout record for ${node.key}`);
31432
31429
  }
31433
- function buildSnapshotForNode(node, cascadeByElementNode, snapshotByElementNode, perf) {
31434
- const existing = snapshotByElementNode.get(node);
31435
- if (existing) {
31436
- perf.signalSnapshotCacheHits++;
31437
- return existing;
31438
- }
31439
- const raw = cascadeByElementNode.get(node);
31440
- if (!raw) {
31441
- throw new Error(`missing cascade map for ${node.key}`);
31442
- }
31443
- const normalized = normalizeSignalMapWithCounts(raw);
31444
- const parent = node.parentElementNode;
31445
- const parentSnapshot = parent ? buildSnapshotForNode(parent, cascadeByElementNode, snapshotByElementNode, perf) : null;
31430
+ function buildSnapshotFromCascade(node, cascade, parentSnapshot) {
31431
+ const normalized = normalizeSignalMapWithCounts(cascade);
31446
31432
  const inherited = inheritSignalsFromParent(parentSnapshot, normalized.signals);
31447
- const knownSignalCount = normalized.knownSignalCount + inherited.knownDelta;
31448
- const unknownSignalCount = normalized.unknownSignalCount + inherited.unknownDelta;
31449
- const conditionalSignalCount = normalized.conditionalSignalCount + inherited.conditionalDelta;
31450
- const snapshot = {
31433
+ return {
31451
31434
  node,
31452
31435
  signals: inherited.signals,
31453
- knownSignalCount,
31454
- unknownSignalCount,
31455
- conditionalSignalCount
31436
+ knownSignalCount: normalized.knownSignalCount + inherited.knownDelta,
31437
+ unknownSignalCount: normalized.unknownSignalCount + inherited.unknownDelta,
31438
+ conditionalSignalCount: normalized.conditionalSignalCount + inherited.conditionalDelta
31456
31439
  };
31457
- snapshotByElementNode.set(node, snapshot);
31458
- perf.signalSnapshotsBuilt++;
31459
- return snapshot;
31460
31440
  }
31461
31441
  function inheritSignalsFromParent(parentSnapshot, local) {
31462
31442
  if (!parentSnapshot) {
@@ -31483,7 +31463,7 @@ function inheritSignalsFromParent(parentSnapshot, local) {
31483
31463
  conditionalDelta++;
31484
31464
  continue;
31485
31465
  }
31486
- if (inheritedValue.kind === "known") {
31466
+ if (inheritedValue.kind === 0 /* Known */) {
31487
31467
  knownDelta++;
31488
31468
  continue;
31489
31469
  }
@@ -31516,10 +31496,10 @@ var EMPTY_STATEFUL_BASE_VALUE_INDEX = /* @__PURE__ */ new Map();
31516
31496
  var EMPTY_LAYOUT_RESERVED_SPACE_FACT = Object.freeze({
31517
31497
  hasReservedSpace: false,
31518
31498
  reasons: EMPTY_RESERVED_SPACE_REASONS,
31519
- hasUsableInlineDimension: false,
31520
- hasUsableBlockDimension: false,
31521
31499
  hasContainIntrinsicSize: false,
31522
- hasUsableAspectRatio: false
31500
+ hasUsableAspectRatio: false,
31501
+ hasDeclaredInlineDimension: false,
31502
+ hasDeclaredBlockDimension: false
31523
31503
  });
31524
31504
  var EMPTY_LAYOUT_SCROLL_CONTAINER_FACT = Object.freeze({
31525
31505
  isScrollContainer: false,
@@ -31552,12 +31532,12 @@ var EMPTY_LAYOUT_CONDITIONAL_DELTA_FACT = Object.freeze({
31552
31532
  function readKnownSignalWithGuard(snapshot, name) {
31553
31533
  const value2 = snapshot.signals.get(name);
31554
31534
  if (!value2) return null;
31555
- if (value2.kind !== "known") return null;
31535
+ if (value2.kind !== 0 /* Known */) return null;
31556
31536
  return value2;
31557
31537
  }
31558
31538
  function toEvidenceKind(value2) {
31559
31539
  if (value2.guard.kind === 1 /* Conditional */) return 2 /* Conditional */;
31560
- if (value2.quality === "estimated") return 1 /* Interval */;
31540
+ if (value2.quality === 1 /* Estimated */) return 1 /* Interval */;
31561
31541
  return 0 /* Exact */;
31562
31542
  }
31563
31543
  function readNormalizedSignalEvidence(snapshot, name) {
@@ -31568,7 +31548,7 @@ function readNormalizedSignalEvidence(snapshot, name) {
31568
31548
  kind: 3 /* Unknown */
31569
31549
  };
31570
31550
  }
31571
- if (value2.kind !== "known") {
31551
+ if (value2.kind !== 0 /* Known */) {
31572
31552
  if (value2.guard.kind === 1 /* Conditional */) {
31573
31553
  return {
31574
31554
  value: null,
@@ -31622,19 +31602,19 @@ function hasEffectivePosition(snapshot) {
31622
31602
  return position !== "static";
31623
31603
  }
31624
31604
  function readReservedSpaceFact(graph, node) {
31625
- return graph.reservedSpaceFactsByNode.get(node) ?? EMPTY_LAYOUT_RESERVED_SPACE_FACT;
31605
+ return graph.records.get(node)?.reservedSpace ?? EMPTY_LAYOUT_RESERVED_SPACE_FACT;
31626
31606
  }
31627
31607
  function readScrollContainerFact(graph, node) {
31628
- return graph.scrollContainerFactsByNode.get(node) ?? EMPTY_LAYOUT_SCROLL_CONTAINER_FACT;
31608
+ return graph.records.get(node)?.scrollContainer ?? EMPTY_LAYOUT_SCROLL_CONTAINER_FACT;
31629
31609
  }
31630
31610
  function readFlowParticipationFact(graph, node) {
31631
- return graph.flowParticipationFactsByNode.get(node) ?? EMPTY_LAYOUT_FLOW_PARTICIPATION_FACT;
31611
+ return graph.records.get(node)?.flowParticipation ?? EMPTY_LAYOUT_FLOW_PARTICIPATION_FACT;
31632
31612
  }
31633
31613
  function readContainingBlockFact(graph, node) {
31634
- return graph.containingBlockFactsByNode.get(node) ?? EMPTY_LAYOUT_CONTAINING_BLOCK_FACT;
31614
+ return graph.records.get(node)?.containingBlock ?? EMPTY_LAYOUT_CONTAINING_BLOCK_FACT;
31635
31615
  }
31636
31616
  function readConditionalSignalDeltaFact(graph, node, name) {
31637
- const byProperty = graph.conditionalSignalDeltaFactsByNode.get(node);
31617
+ const byProperty = graph.records.get(node)?.conditionalDelta;
31638
31618
  if (!byProperty) return EMPTY_LAYOUT_CONDITIONAL_DELTA_FACT;
31639
31619
  return byProperty.get(name) ?? EMPTY_LAYOUT_CONDITIONAL_DELTA_FACT;
31640
31620
  }
@@ -31662,7 +31642,7 @@ function readScrollContainerElements(graph) {
31662
31642
  return graph.scrollContainerElements;
31663
31643
  }
31664
31644
  function readBaselineOffsetFacts(graph, node) {
31665
- return graph.baselineOffsetFactsByNode.get(node) ?? EMPTY_BASELINE_FACTS;
31645
+ return graph.records.get(node)?.baselineOffsets ?? EMPTY_BASELINE_FACTS;
31666
31646
  }
31667
31647
  function readElementRef(graph, node) {
31668
31648
  return readElementRefById(graph, node.solidFile, node.elementId);
@@ -32516,23 +32496,44 @@ function collectCSSScopeBySolidFile(solids, css, moduleResolver) {
32516
32496
  if (!imp) continue;
32517
32497
  if (imp.isTypeOnly) continue;
32518
32498
  const resolvedCssPath = resolver.resolveCss(solid.file, imp.source);
32519
- if (resolvedCssPath === null) continue;
32520
- const transitiveScope = getOrCollectTransitiveScope(
32521
- resolvedCssPath,
32522
- resolver,
32523
- cssFilesByNormalizedPath,
32524
- transitiveScopeByEntryPath
32525
- );
32526
- for (let k = 0; k < transitiveScope.length; k++) {
32527
- const ts137 = transitiveScope[k];
32528
- if (!ts137) continue;
32529
- scope.add(ts137);
32499
+ if (resolvedCssPath !== null) {
32500
+ const transitiveScope = getOrCollectTransitiveScope(
32501
+ resolvedCssPath,
32502
+ resolver,
32503
+ cssFilesByNormalizedPath,
32504
+ transitiveScopeByEntryPath
32505
+ );
32506
+ for (let k = 0; k < transitiveScope.length; k++) {
32507
+ const ts137 = transitiveScope[k];
32508
+ if (!ts137) continue;
32509
+ scope.add(ts137);
32510
+ }
32511
+ if (imp.specifiers.length === 0) {
32512
+ for (let k = 0; k < transitiveScope.length; k++) {
32513
+ const ts137 = transitiveScope[k];
32514
+ if (!ts137) continue;
32515
+ globalSideEffectScope.add(ts137);
32516
+ }
32517
+ }
32530
32518
  }
32531
- if (imp.specifiers.length !== 0) continue;
32532
- for (let k = 0; k < transitiveScope.length; k++) {
32533
- const ts137 = transitiveScope[k];
32534
- if (!ts137) continue;
32535
- globalSideEffectScope.add(ts137);
32519
+ if (imp.specifiers.length !== 0) {
32520
+ const resolvedSolidPath = resolver.resolveSolid(solid.file, imp.source);
32521
+ if (resolvedSolidPath !== null) {
32522
+ const componentCssPath = resolveColocatedCss(resolvedSolidPath, cssFilesByNormalizedPath);
32523
+ if (componentCssPath !== null) {
32524
+ const componentCssScope = getOrCollectTransitiveScope(
32525
+ componentCssPath,
32526
+ resolver,
32527
+ cssFilesByNormalizedPath,
32528
+ transitiveScopeByEntryPath
32529
+ );
32530
+ for (let k = 0; k < componentCssScope.length; k++) {
32531
+ const cs = componentCssScope[k];
32532
+ if (!cs) continue;
32533
+ scope.add(cs);
32534
+ }
32535
+ }
32536
+ }
32536
32537
  }
32537
32538
  }
32538
32539
  localScopeBySolidFile.set(solid.file, scope);
@@ -32754,6 +32755,7 @@ var import_node_fs5 = require("fs");
32754
32755
  var import_node_path4 = require("path");
32755
32756
  var import_typescript126 = __toESM(require("typescript"), 1);
32756
32757
  var EMPTY_ATTRIBUTES = /* @__PURE__ */ new Map();
32758
+ var EMPTY_PROP_BINDINGS = /* @__PURE__ */ new Map();
32757
32759
  var TRANSPARENT_SOLID_PRIMITIVES = /* @__PURE__ */ new Set([
32758
32760
  "For",
32759
32761
  "Index",
@@ -32822,9 +32824,10 @@ function createLayoutComponentHostResolver(solids, moduleResolver, logger = noop
32822
32824
  const staticAttributes = innerHost !== null ? mergeStaticAttributes(entry.staticAttributes, innerHost.descriptor.staticAttributes) : entry.staticAttributes;
32823
32825
  const staticClassTokens = innerHost !== null ? mergeStaticClassTokens(entry.staticClassTokens, innerHost.descriptor.staticClassTokens) : entry.staticClassTokens;
32824
32826
  const forwardsChildren = entry.forwardsChildren || innerHost !== null && innerHost.descriptor.forwardsChildren;
32827
+ const attributePropBindings = innerHost !== null ? mergePropBindings(entry.attributePropBindings, innerHost.descriptor.attributePropBindings) : entry.attributePropBindings;
32825
32828
  if (logger.isLevelEnabled(Level.Trace)) logger.trace(`[component-host] resolved: tagName=${tagName}, attrs=[${[...staticAttributes.keys()]}], classes=[${staticClassTokens}]`);
32826
32829
  return {
32827
- descriptor: { tagName, staticAttributes, staticClassTokens, forwardsChildren },
32830
+ descriptor: { tagName, staticAttributes, staticClassTokens, forwardsChildren, attributePropBindings },
32828
32831
  hostElementRef: innerHost?.hostElementRef ?? null
32829
32832
  };
32830
32833
  }
@@ -33251,7 +33254,8 @@ function resolveHostEntryFromJSXElement(graph, node) {
33251
33254
  tagName: element.tagName,
33252
33255
  staticAttributes: collectStaticAttributes(element),
33253
33256
  staticClassTokens: getStaticClassTokensForElementEntity(graph, element),
33254
- forwardsChildren: detectChildrenForwarding(element)
33257
+ forwardsChildren: detectChildrenForwarding(element),
33258
+ attributePropBindings: collectAttributePropBindings(element)
33255
33259
  },
33256
33260
  hostElementRef: { solid: graph, element }
33257
33261
  };
@@ -33266,7 +33270,8 @@ function resolveHostEntryFromJSXElement(graph, node) {
33266
33270
  filePath: graph.file,
33267
33271
  staticAttributes: collectStaticAttributes(element),
33268
33272
  staticClassTokens: getStaticClassTokensForElementEntity(graph, element),
33269
- forwardsChildren: detectChildrenForwarding(element)
33273
+ forwardsChildren: detectChildrenForwarding(element),
33274
+ attributePropBindings: collectAttributePropBindings(element)
33270
33275
  };
33271
33276
  }
33272
33277
  function isContextProviderTag(tag) {
@@ -33454,6 +33459,41 @@ function collectStaticAttributes(element) {
33454
33459
  if (out === null) return EMPTY_ATTRIBUTES;
33455
33460
  return out;
33456
33461
  }
33462
+ function extractPropMemberName(node) {
33463
+ if (!import_typescript126.default.isJsxExpression(node)) return null;
33464
+ const expression = node.expression;
33465
+ if (!expression) return null;
33466
+ return extractMemberNameFromExpression(expression);
33467
+ }
33468
+ function extractMemberNameFromExpression(expression) {
33469
+ if (import_typescript126.default.isPropertyAccessExpression(expression)) {
33470
+ return expression.name.text;
33471
+ }
33472
+ if (import_typescript126.default.isCallExpression(expression) && import_typescript126.default.isPropertyAccessExpression(expression.expression) && expression.arguments.length === 0) {
33473
+ return expression.expression.name.text;
33474
+ }
33475
+ if (import_typescript126.default.isBinaryExpression(expression) && expression.operatorToken.kind === import_typescript126.default.SyntaxKind.QuestionQuestionToken) {
33476
+ return extractMemberNameFromExpression(expression.left);
33477
+ }
33478
+ return null;
33479
+ }
33480
+ function collectAttributePropBindings(element) {
33481
+ let out = null;
33482
+ for (let i = 0; i < element.attributes.length; i++) {
33483
+ const attribute = element.attributes[i];
33484
+ if (!attribute) continue;
33485
+ if (!import_typescript126.default.isJsxAttribute(attribute.node)) continue;
33486
+ if (!attribute.name) continue;
33487
+ if (attribute.valueNode === null) continue;
33488
+ const propName = extractPropMemberName(attribute.valueNode);
33489
+ if (propName === null) continue;
33490
+ const attrName = attribute.name.toLowerCase();
33491
+ if (out === null) out = /* @__PURE__ */ new Map();
33492
+ out.set(attrName, propName);
33493
+ }
33494
+ if (out === null) return EMPTY_PROP_BINDINGS;
33495
+ return out;
33496
+ }
33457
33497
  function collectTopLevelVariableInitializers(graph) {
33458
33498
  const out = /* @__PURE__ */ new Map();
33459
33499
  for (let i = 0; i < graph.variables.length; i++) {
@@ -33579,7 +33619,12 @@ function areHostDescriptorsEqual(left, right) {
33579
33619
  if (left.tagName !== right.tagName) return false;
33580
33620
  if (left.forwardsChildren !== right.forwardsChildren) return false;
33581
33621
  if (!areStringListsEqual(left.staticClassTokens, right.staticClassTokens)) return false;
33582
- return areAttributeMapsEqual(left.staticAttributes, right.staticAttributes);
33622
+ if (!areAttributeMapsEqual(left.staticAttributes, right.staticAttributes)) return false;
33623
+ if (left.attributePropBindings.size !== right.attributePropBindings.size) return false;
33624
+ for (const [key, value2] of left.attributePropBindings) {
33625
+ if (right.attributePropBindings.get(key) !== value2) return false;
33626
+ }
33627
+ return true;
33583
33628
  }
33584
33629
  function areComponentHostEntriesEqual(left, right) {
33585
33630
  if (left.resolution !== right.resolution) return false;
@@ -33622,6 +33667,18 @@ function mergeStaticAttributes(outer, inner) {
33622
33667
  }
33623
33668
  return out;
33624
33669
  }
33670
+ function mergePropBindings(outer, inner) {
33671
+ if (inner.size === 0) return outer;
33672
+ if (outer.size === 0) return inner;
33673
+ const out = /* @__PURE__ */ new Map();
33674
+ for (const [name, value2] of inner) {
33675
+ out.set(name, value2);
33676
+ }
33677
+ for (const [name, value2] of outer) {
33678
+ out.set(name, value2);
33679
+ }
33680
+ return out;
33681
+ }
33625
33682
  var HTML_TAG_NAMES = /* @__PURE__ */ new Set([
33626
33683
  "a",
33627
33684
  "abbr",
@@ -33766,9 +33823,6 @@ function mergeStaticClassTokens(outer, inner) {
33766
33823
  }
33767
33824
 
33768
33825
  // src/cross-file/layout/selector-match.ts
33769
- var ATTRIBUTE_EXISTS_RE2 = /^[-_a-zA-Z][-_a-zA-Z0-9]*$/;
33770
- var ATTRIBUTE_CONSTRAINT_RE2 = /^([-_a-zA-Z][-_a-zA-Z0-9]*)\s*(=|~=|\|=|\^=|\$=|\*=)\s*(?:"([^"]*)"|'([^']*)'|([^\s"']+))(?:\s+([iIsS]))?$/;
33771
- var MAX_PSEUDO_COMPILE_DEPTH = 4;
33772
33826
  var STATEFUL_PSEUDO_CLASSES = /* @__PURE__ */ new Set([
33773
33827
  "active",
33774
33828
  "checked",
@@ -33792,14 +33846,25 @@ var STATEFUL_PSEUDO_CLASSES = /* @__PURE__ */ new Set([
33792
33846
  "valid",
33793
33847
  "visited"
33794
33848
  ]);
33849
+ var EMPTY_PSEUDO = {
33850
+ firstChild: false,
33851
+ lastChild: false,
33852
+ onlyChild: false,
33853
+ nthChild: null,
33854
+ nthLastChild: null,
33855
+ nthOfType: null,
33856
+ nthLastOfType: null,
33857
+ anyOfGroups: [],
33858
+ noneOfGroups: []
33859
+ };
33795
33860
  function compileSelectorMatcher(selector) {
33796
- const parsed = parseSelectorPattern(selector.raw);
33797
- if (parsed === null) return null;
33861
+ const selectorCompounds = selector.compounds;
33862
+ if (selectorCompounds.length === 0) return null;
33798
33863
  const compoundsLeftToRight = [];
33799
- for (let i = 0; i < parsed.compounds.length; i++) {
33800
- const compoundRaw = parsed.compounds[i];
33801
- if (compoundRaw === void 0) continue;
33802
- const compiled = compileCompound(compoundRaw, 0);
33864
+ for (let i = 0; i < selectorCompounds.length; i++) {
33865
+ const sc = selectorCompounds[i];
33866
+ if (sc === void 0) continue;
33867
+ const compiled = buildCompiledCompound(sc);
33803
33868
  if (compiled === null) return null;
33804
33869
  compoundsLeftToRight.push(compiled);
33805
33870
  }
@@ -33816,9 +33881,125 @@ function compileSelectorMatcher(selector) {
33816
33881
  },
33817
33882
  requirements: resolveFeatureRequirements(compoundsLeftToRight),
33818
33883
  compoundsRightToLeft: compoundsLeftToRight.toReversed(),
33819
- combinatorsRightToLeft: parsed.combinators.toReversed()
33884
+ combinatorsRightToLeft: selector.combinators.toReversed()
33820
33885
  };
33821
33886
  }
33887
+ function buildCompiledCompound(sc) {
33888
+ const parts = sc.parts;
33889
+ for (let i = 0; i < parts.length; i++) {
33890
+ const part = parts[i];
33891
+ if (!part) continue;
33892
+ if (part.type === "pseudo-element") return null;
33893
+ }
33894
+ const pseudoConstraints = sc.pseudoClasses;
33895
+ if (pseudoConstraints.length === 0) {
33896
+ return {
33897
+ tagName: sc.tagName,
33898
+ idValue: sc.idValue,
33899
+ classes: sc.classes,
33900
+ attributes: sc.attributes,
33901
+ pseudo: EMPTY_PSEUDO
33902
+ };
33903
+ }
33904
+ let firstChild = false;
33905
+ let lastChild = false;
33906
+ let onlyChild = false;
33907
+ let nthChild = null;
33908
+ let nthLastChild = null;
33909
+ let nthOfType = null;
33910
+ let nthLastOfType = null;
33911
+ const anyOfGroups = [];
33912
+ const noneOfGroups = [];
33913
+ for (let i = 0; i < pseudoConstraints.length; i++) {
33914
+ const pc = pseudoConstraints[i];
33915
+ if (!pc) continue;
33916
+ if (pc.kind === 0 /* Simple */) {
33917
+ if (STATEFUL_PSEUDO_CLASSES.has(pc.name)) return null;
33918
+ continue;
33919
+ }
33920
+ if (pc.kind === 1 /* FirstChild */) {
33921
+ firstChild = true;
33922
+ continue;
33923
+ }
33924
+ if (pc.kind === 2 /* LastChild */) {
33925
+ lastChild = true;
33926
+ continue;
33927
+ }
33928
+ if (pc.kind === 3 /* OnlyChild */) {
33929
+ firstChild = true;
33930
+ lastChild = true;
33931
+ onlyChild = true;
33932
+ continue;
33933
+ }
33934
+ if (pc.kind === 4 /* NthChild */) {
33935
+ if (!pc.nthPattern) return null;
33936
+ nthChild = pc.nthPattern;
33937
+ continue;
33938
+ }
33939
+ if (pc.kind === 5 /* NthLastChild */) {
33940
+ if (!pc.nthPattern) return null;
33941
+ nthLastChild = pc.nthPattern;
33942
+ continue;
33943
+ }
33944
+ if (pc.kind === 6 /* NthOfType */) {
33945
+ if (!pc.nthPattern) return null;
33946
+ nthOfType = pc.nthPattern;
33947
+ continue;
33948
+ }
33949
+ if (pc.kind === 7 /* NthLastOfType */) {
33950
+ if (!pc.nthPattern) return null;
33951
+ nthLastOfType = pc.nthPattern;
33952
+ continue;
33953
+ }
33954
+ if (pc.kind === 8 /* MatchesAny */) {
33955
+ if (pc.nestedCompounds && pc.nestedCompounds.length > 0) {
33956
+ const group = buildNestedGroup(pc.nestedCompounds);
33957
+ if (group === null) return null;
33958
+ if (group.length > 0) anyOfGroups.push(group);
33959
+ }
33960
+ continue;
33961
+ }
33962
+ if (pc.kind === 9 /* NoneOf */) {
33963
+ if (pc.nestedCompounds && pc.nestedCompounds.length > 0) {
33964
+ const group = buildNestedGroup(pc.nestedCompounds);
33965
+ if (group === null) return null;
33966
+ if (group.length > 0) noneOfGroups.push(group);
33967
+ }
33968
+ continue;
33969
+ }
33970
+ }
33971
+ return {
33972
+ tagName: sc.tagName,
33973
+ idValue: sc.idValue,
33974
+ classes: sc.classes,
33975
+ attributes: sc.attributes,
33976
+ pseudo: {
33977
+ firstChild,
33978
+ lastChild,
33979
+ onlyChild,
33980
+ nthChild,
33981
+ nthLastChild,
33982
+ nthOfType,
33983
+ nthLastOfType,
33984
+ anyOfGroups,
33985
+ noneOfGroups
33986
+ }
33987
+ };
33988
+ }
33989
+ function buildNestedGroup(nestedCompounds) {
33990
+ const out = [];
33991
+ for (let i = 0; i < nestedCompounds.length; i++) {
33992
+ const compoundGroup = nestedCompounds[i];
33993
+ if (!compoundGroup) continue;
33994
+ if (compoundGroup.length !== 1) continue;
33995
+ const sc = compoundGroup[0];
33996
+ if (!sc) continue;
33997
+ const compiled = buildCompiledCompound(sc);
33998
+ if (compiled === null) return null;
33999
+ out.push(compiled);
34000
+ }
34001
+ return out;
34002
+ }
33822
34003
  function collectSubjectAttributeNames(subject) {
33823
34004
  if (subject.attributes.length === 0) return [];
33824
34005
  const names = /* @__PURE__ */ new Set();
@@ -33894,42 +34075,42 @@ function compoundGroupNeedsAttributes(groups) {
33894
34075
  }
33895
34076
  return false;
33896
34077
  }
33897
- function selectorMatchesLayoutElement(matcher, node, perf, fileRootElements = null, logger = noopLogger) {
34078
+ function selectorMatchesLayoutElement(matcher, node, perf, fileRootElements = null, logger = noopLogger, fileElementIndex = null) {
33898
34079
  const firstCompound = matcher.compoundsRightToLeft[0];
33899
- if (firstCompound === void 0) return "no-match";
34080
+ if (firstCompound === void 0) return 1 /* NoMatch */;
33900
34081
  const subjectResult = matchesCompound(node, firstCompound);
33901
- if (subjectResult === "no-match") return "no-match";
34082
+ if (subjectResult === 1 /* NoMatch */) return 1 /* NoMatch */;
33902
34083
  if (matcher.compoundsRightToLeft.length === 1) return subjectResult;
33903
- const chainResult = matchesChain(matcher, node, 0, perf, fileRootElements, logger);
33904
- if (chainResult === "no-match") return "no-match";
33905
- if (subjectResult === "conditional" || chainResult === "conditional") return "conditional";
33906
- return "match";
34084
+ const chainResult = matchesChain(matcher, node, 0, perf, fileRootElements, logger, fileElementIndex);
34085
+ if (chainResult === 1 /* NoMatch */) return 1 /* NoMatch */;
34086
+ if (subjectResult === 2 /* Conditional */ || chainResult === 2 /* Conditional */) return 2 /* Conditional */;
34087
+ return 0 /* Match */;
33907
34088
  }
33908
- function matchesChain(matcher, node, index, perf, fileRootElements, logger) {
34089
+ function matchesChain(matcher, node, index, perf, fileRootElements, logger, fileElementIndex = null) {
33909
34090
  const combinator = matcher.combinatorsRightToLeft[index];
33910
- if (combinator === void 0) return "no-match";
34091
+ if (combinator === void 0) return 1 /* NoMatch */;
33911
34092
  const nextIndex = index + 1;
33912
34093
  const targetCompound = matcher.compoundsRightToLeft[nextIndex];
33913
- if (targetCompound === void 0) return "no-match";
34094
+ if (targetCompound === void 0) return 1 /* NoMatch */;
33914
34095
  const isFinal = nextIndex === matcher.compoundsRightToLeft.length - 1;
33915
34096
  if (combinator === "child") {
33916
34097
  const parent = node.parentElementNode;
33917
- if (parent === null) return "no-match";
34098
+ if (parent === null) return 1 /* NoMatch */;
33918
34099
  perf.ancestryChecks++;
33919
34100
  const compoundResult = matchesCompound(parent, targetCompound);
33920
- if (compoundResult === "no-match") return "no-match";
34101
+ if (compoundResult === 1 /* NoMatch */) return 1 /* NoMatch */;
33921
34102
  if (isFinal) return compoundResult;
33922
- const chainResult = matchesChain(matcher, parent, nextIndex, perf, fileRootElements, logger);
34103
+ const chainResult = matchesChain(matcher, parent, nextIndex, perf, fileRootElements, logger, fileElementIndex);
33923
34104
  return mergeMatchResults(compoundResult, chainResult);
33924
34105
  }
33925
34106
  if (combinator === "adjacent") {
33926
34107
  const sibling = node.previousSiblingNode;
33927
- if (sibling === null) return "no-match";
34108
+ if (sibling === null) return 1 /* NoMatch */;
33928
34109
  perf.ancestryChecks++;
33929
34110
  const compoundResult = matchesCompound(sibling, targetCompound);
33930
- if (compoundResult === "no-match") return "no-match";
34111
+ if (compoundResult === 1 /* NoMatch */) return 1 /* NoMatch */;
33931
34112
  if (isFinal) return compoundResult;
33932
- const chainResult = matchesChain(matcher, sibling, nextIndex, perf, fileRootElements, logger);
34113
+ const chainResult = matchesChain(matcher, sibling, nextIndex, perf, fileRootElements, logger, fileElementIndex);
33933
34114
  return mergeMatchResults(compoundResult, chainResult);
33934
34115
  }
33935
34116
  if (combinator === "sibling") {
@@ -33937,26 +34118,26 @@ function matchesChain(matcher, node, index, perf, fileRootElements, logger) {
33937
34118
  while (sibling !== null) {
33938
34119
  perf.ancestryChecks++;
33939
34120
  const compoundResult = matchesCompound(sibling, targetCompound);
33940
- if (compoundResult !== "no-match") {
34121
+ if (compoundResult !== 1 /* NoMatch */) {
33941
34122
  if (isFinal) return compoundResult;
33942
- const chainResult = matchesChain(matcher, sibling, nextIndex, perf, fileRootElements, logger);
33943
- if (chainResult !== "no-match") return mergeMatchResults(compoundResult, chainResult);
34123
+ const chainResult = matchesChain(matcher, sibling, nextIndex, perf, fileRootElements, logger, fileElementIndex);
34124
+ if (chainResult !== 1 /* NoMatch */) return mergeMatchResults(compoundResult, chainResult);
33944
34125
  }
33945
34126
  sibling = sibling.previousSiblingNode;
33946
34127
  }
33947
- return "no-match";
34128
+ return 1 /* NoMatch */;
33948
34129
  }
33949
- let bestResult = "no-match";
34130
+ let bestResult = 1 /* NoMatch */;
33950
34131
  let ancestor = node.parentElementNode;
33951
34132
  while (ancestor !== null) {
33952
34133
  perf.ancestryChecks++;
33953
34134
  const compoundResult = matchesCompound(ancestor, targetCompound);
33954
- if (compoundResult !== "no-match") {
34135
+ if (compoundResult !== 1 /* NoMatch */) {
33955
34136
  if (isFinal) return compoundResult;
33956
- const chainResult = matchesChain(matcher, ancestor, nextIndex, perf, fileRootElements, logger);
33957
- if (chainResult !== "no-match") {
34137
+ const chainResult = matchesChain(matcher, ancestor, nextIndex, perf, fileRootElements, logger, fileElementIndex);
34138
+ if (chainResult !== 1 /* NoMatch */) {
33958
34139
  const merged = mergeMatchResults(compoundResult, chainResult);
33959
- if (merged === "match") return "match";
34140
+ if (merged === 0 /* Match */) return 0 /* Match */;
33960
34141
  bestResult = merged;
33961
34142
  }
33962
34143
  }
@@ -33974,30 +34155,50 @@ function matchesChain(matcher, node, index, perf, fileRootElements, logger) {
33974
34155
  if (root.solidFile !== node.solidFile) continue;
33975
34156
  perf.ancestryChecks++;
33976
34157
  const compoundResult = matchesCompound(root, targetCompound);
33977
- if (logger.isLevelEnabled(Level.Trace) && compoundResult === "no-match") {
34158
+ if (logger.isLevelEnabled(Level.Trace) && compoundResult === 1 /* NoMatch */) {
33978
34159
  logger.trace(`[selector-match] fallback MISS: root=${root.key} tag=${root.tagName} attrs=[${[...root.attributes.entries()].map(([k, v]) => `${k}=${v}`).join(",")}]`);
33979
34160
  }
33980
- if (compoundResult !== "no-match") {
34161
+ if (compoundResult !== 1 /* NoMatch */) {
33981
34162
  if (logger.isLevelEnabled(Level.Debug)) {
33982
34163
  const compoundDesc = describeCompound(targetCompound);
33983
34164
  logger.debug(`[selector-match] fallback HIT: node=${node.key} tag=${node.tagName} matched root=${root.key} tag=${root.tagName} compound=${compoundDesc} isFinal=${isFinal}`);
33984
34165
  }
33985
34166
  if (isFinal) return compoundResult;
33986
- const chainResult = matchesChain(matcher, root, nextIndex, perf, fileRootElements, logger);
33987
- if (chainResult !== "no-match") {
34167
+ const chainResult = matchesChain(matcher, root, nextIndex, perf, fileRootElements, logger, fileElementIndex);
34168
+ if (chainResult !== 1 /* NoMatch */) {
33988
34169
  const merged = mergeMatchResults(compoundResult, chainResult);
33989
- if (merged === "match") return "match";
34170
+ if (merged === 0 /* Match */) return 0 /* Match */;
33990
34171
  bestResult = merged;
33991
34172
  }
33992
34173
  }
33993
34174
  }
33994
34175
  }
34176
+ if (fileElementIndex !== null && bestResult === 1 /* NoMatch */) {
34177
+ const candidates = resolveCompoundCandidates(fileElementIndex, targetCompound);
34178
+ if (candidates !== null) {
34179
+ for (let r = 0; r < candidates.length; r++) {
34180
+ const elem = candidates[r];
34181
+ if (elem === void 0) continue;
34182
+ if (elem === node) continue;
34183
+ perf.ancestryChecks++;
34184
+ const compoundResult = matchesCompound(elem, targetCompound);
34185
+ if (compoundResult !== 1 /* NoMatch */) {
34186
+ if (logger.isLevelEnabled(Level.Debug)) {
34187
+ const compoundDesc = describeCompound(targetCompound);
34188
+ logger.debug(`[selector-match] indexed fallback HIT: node=${node.key} tag=${node.tagName} matched elem=${elem.key} tag=${elem.tagName} compound=${compoundDesc}`);
34189
+ }
34190
+ bestResult = 2 /* Conditional */;
34191
+ break;
34192
+ }
34193
+ }
34194
+ }
34195
+ }
33995
34196
  return bestResult;
33996
34197
  }
33997
34198
  function mergeMatchResults(a, b) {
33998
- if (a === "no-match" || b === "no-match") return "no-match";
33999
- if (a === "conditional" || b === "conditional") return "conditional";
34000
- return "match";
34199
+ if (a === 1 /* NoMatch */ || b === 1 /* NoMatch */) return 1 /* NoMatch */;
34200
+ if (a === 2 /* Conditional */ || b === 2 /* Conditional */) return 2 /* Conditional */;
34201
+ return 0 /* Match */;
34001
34202
  }
34002
34203
  function describeCompound(compound) {
34003
34204
  const parts = [];
@@ -34016,16 +34217,31 @@ function describeCompound(compound) {
34016
34217
  if (compound.idValue !== null) parts.push(`#${compound.idValue}`);
34017
34218
  return parts.join("") || "*";
34018
34219
  }
34220
+ function resolveCompoundCandidates(index, compound) {
34221
+ if (compound.idValue !== null) {
34222
+ return index.byDispatchKey.get(`id:${compound.idValue}`) ?? null;
34223
+ }
34224
+ if (compound.classes.length > 0 && compound.classes[0] !== void 0) {
34225
+ return index.byDispatchKey.get(`class:${compound.classes[0]}`) ?? null;
34226
+ }
34227
+ if (compound.attributes.length > 0 && compound.attributes[0] !== void 0) {
34228
+ return index.byDispatchKey.get(`attr:${compound.attributes[0].name}`) ?? null;
34229
+ }
34230
+ if (compound.tagName !== null) {
34231
+ return index.byTagName.get(compound.tagName) ?? null;
34232
+ }
34233
+ return null;
34234
+ }
34019
34235
  function matchesCompound(node, compound) {
34020
- if (compound.tagName !== null && node.tagName !== compound.tagName) return "no-match";
34236
+ if (compound.tagName !== null && node.tagName !== compound.tagName) return 1 /* NoMatch */;
34021
34237
  if (compound.idValue !== null) {
34022
34238
  const id = node.attributes.get("id");
34023
- if (id !== compound.idValue) return "no-match";
34239
+ if (id !== compound.idValue) return 1 /* NoMatch */;
34024
34240
  }
34025
- if (!matchesRequiredClasses(compound.classes, node.classTokenSet)) return "no-match";
34241
+ if (!matchesRequiredClasses(compound.classes, node.classTokenSet)) return 1 /* NoMatch */;
34026
34242
  const attrResult = matchesRequiredAttributes(compound.attributes, node.attributes);
34027
- if (attrResult === "no-match") return "no-match";
34028
- if (!matchesPseudoConstraints(node, compound.pseudo)) return "no-match";
34243
+ if (attrResult === 1 /* NoMatch */) return 1 /* NoMatch */;
34244
+ if (!matchesPseudoConstraints(node, compound.pseudo)) return 1 /* NoMatch */;
34029
34245
  return attrResult;
34030
34246
  }
34031
34247
  function matchesPseudoConstraints(node, pseudo) {
@@ -34051,7 +34267,7 @@ function matchesPseudoConstraints(node, pseudo) {
34051
34267
  for (let j = 0; j < group.length; j++) {
34052
34268
  const compound = group[j];
34053
34269
  if (compound === void 0) continue;
34054
- if (matchesCompound(node, compound) === "no-match") continue;
34270
+ if (matchesCompound(node, compound) === 1 /* NoMatch */) continue;
34055
34271
  matched = true;
34056
34272
  break;
34057
34273
  }
@@ -34063,607 +34279,12 @@ function matchesPseudoConstraints(node, pseudo) {
34063
34279
  for (let j = 0; j < group.length; j++) {
34064
34280
  const compound = group[j];
34065
34281
  if (compound === void 0) continue;
34066
- if (matchesCompound(node, compound) === "no-match") continue;
34282
+ if (matchesCompound(node, compound) === 1 /* NoMatch */) continue;
34067
34283
  return false;
34068
34284
  }
34069
34285
  }
34070
34286
  return true;
34071
34287
  }
34072
- function parseSelectorPattern(raw) {
34073
- const compounds = [];
34074
- const combinators = [];
34075
- const length = raw.length;
34076
- let start = 0;
34077
- let bracketDepth = 0;
34078
- let parenDepth = 0;
34079
- let i = 0;
34080
- while (i < length) {
34081
- const code = raw.charCodeAt(i);
34082
- if (code === CHAR_OPEN_BRACKET) {
34083
- bracketDepth++;
34084
- i++;
34085
- continue;
34086
- }
34087
- if (code === CHAR_CLOSE_BRACKET) {
34088
- if (bracketDepth > 0) bracketDepth--;
34089
- i++;
34090
- continue;
34091
- }
34092
- if (code === CHAR_OPEN_PAREN) {
34093
- parenDepth++;
34094
- i++;
34095
- continue;
34096
- }
34097
- if (code === CHAR_CLOSE_PAREN) {
34098
- if (parenDepth > 0) parenDepth--;
34099
- i++;
34100
- continue;
34101
- }
34102
- if (bracketDepth === 0 && parenDepth === 0) {
34103
- if (code === CHAR_GT || code === CHAR_PLUS || code === CHAR_TILDE) {
34104
- const compound = raw.slice(start, i).trim();
34105
- if (compound.length === 0) return null;
34106
- compounds.push(compound);
34107
- combinators.push(combinatorFromCode(code));
34108
- i++;
34109
- while (i < length && isWhitespace(raw.charCodeAt(i))) i++;
34110
- start = i;
34111
- continue;
34112
- }
34113
- if (isWhitespace(code)) {
34114
- const compound = raw.slice(start, i).trim();
34115
- if (compound.length > 0) compounds.push(compound);
34116
- while (i < length && isWhitespace(raw.charCodeAt(i))) i++;
34117
- if (i >= length) break;
34118
- const next = raw.charCodeAt(i);
34119
- if (next === CHAR_GT || next === CHAR_PLUS || next === CHAR_TILDE) {
34120
- if (compound.length === 0) return null;
34121
- combinators.push(combinatorFromCode(next));
34122
- i++;
34123
- while (i < length && isWhitespace(raw.charCodeAt(i))) i++;
34124
- start = i;
34125
- continue;
34126
- }
34127
- if (compound.length > 0) combinators.push("descendant");
34128
- start = i;
34129
- continue;
34130
- }
34131
- }
34132
- i++;
34133
- }
34134
- const trailing = raw.slice(start).trim();
34135
- if (trailing.length > 0) compounds.push(trailing);
34136
- if (compounds.length === 0) return null;
34137
- if (combinators.length !== compounds.length - 1) return null;
34138
- return { compounds, combinators };
34139
- }
34140
- function combinatorFromCode(code) {
34141
- if (code === CHAR_GT) return "child";
34142
- if (code === CHAR_PLUS) return "adjacent";
34143
- return "sibling";
34144
- }
34145
- function compileCompound(raw, depth) {
34146
- if (depth > MAX_PSEUDO_COMPILE_DEPTH) return null;
34147
- const parts = parseCompoundParts(raw);
34148
- if (parts.length === 0) return null;
34149
- let tagName = null;
34150
- let idValue = null;
34151
- const classes = [];
34152
- const seenClasses = /* @__PURE__ */ new Set();
34153
- const attributes = [];
34154
- let firstChild = false;
34155
- let lastChild = false;
34156
- let onlyChild = false;
34157
- let nthChild = null;
34158
- let nthLastChild = null;
34159
- let nthOfType = null;
34160
- let nthLastOfType = null;
34161
- const anyOfGroups = [];
34162
- const noneOfGroups = [];
34163
- for (let i = 0; i < parts.length; i++) {
34164
- const part = parts[i];
34165
- if (part === void 0) continue;
34166
- if (part.type === "element") {
34167
- tagName = part.value.toLowerCase();
34168
- continue;
34169
- }
34170
- if (part.type === "universal") continue;
34171
- if (part.type === "id") {
34172
- idValue = part.value;
34173
- continue;
34174
- }
34175
- if (part.type === "class") {
34176
- if (seenClasses.has(part.value)) continue;
34177
- seenClasses.add(part.value);
34178
- classes.push(part.value);
34179
- continue;
34180
- }
34181
- if (part.type === "attribute") {
34182
- const attribute = parseAttributeConstraint(part.value);
34183
- if (attribute === null) return null;
34184
- attributes.push(attribute);
34185
- continue;
34186
- }
34187
- if (part.type === "pseudo-class") {
34188
- const pseudo = parsePseudoConstraint(part.raw, depth);
34189
- if (pseudo === null) return null;
34190
- if (pseudo.kind === "first-child") {
34191
- firstChild = true;
34192
- continue;
34193
- }
34194
- if (pseudo.kind === "last-child") {
34195
- lastChild = true;
34196
- continue;
34197
- }
34198
- if (pseudo.kind === "only-child") {
34199
- firstChild = true;
34200
- lastChild = true;
34201
- onlyChild = true;
34202
- continue;
34203
- }
34204
- if (pseudo.kind === "nth-child") {
34205
- if (nthChild !== null && !isSameNthPattern(nthChild, pseudo.value)) return null;
34206
- nthChild = pseudo.value;
34207
- continue;
34208
- }
34209
- if (pseudo.kind === "nth-last-child") {
34210
- if (nthLastChild !== null && !isSameNthPattern(nthLastChild, pseudo.value)) return null;
34211
- nthLastChild = pseudo.value;
34212
- continue;
34213
- }
34214
- if (pseudo.kind === "nth-of-type") {
34215
- if (nthOfType !== null && !isSameNthPattern(nthOfType, pseudo.value)) return null;
34216
- nthOfType = pseudo.value;
34217
- continue;
34218
- }
34219
- if (pseudo.kind === "nth-last-of-type") {
34220
- if (nthLastOfType !== null && !isSameNthPattern(nthLastOfType, pseudo.value)) return null;
34221
- nthLastOfType = pseudo.value;
34222
- continue;
34223
- }
34224
- if (pseudo.kind === "ignore") continue;
34225
- if (pseudo.kind === "matches-any") {
34226
- anyOfGroups.push(pseudo.selectors);
34227
- continue;
34228
- }
34229
- noneOfGroups.push(pseudo.selectors);
34230
- continue;
34231
- }
34232
- return null;
34233
- }
34234
- if (firstChild && nthChild !== null && !matchesNthPattern(1, nthChild)) return null;
34235
- if (lastChild && nthLastChild !== null && !matchesNthPattern(1, nthLastChild)) return null;
34236
- return {
34237
- tagName,
34238
- idValue,
34239
- classes,
34240
- attributes,
34241
- pseudo: {
34242
- firstChild,
34243
- lastChild,
34244
- onlyChild,
34245
- nthChild,
34246
- nthLastChild,
34247
- nthOfType,
34248
- nthLastOfType,
34249
- anyOfGroups,
34250
- noneOfGroups
34251
- }
34252
- };
34253
- }
34254
- function parseAttributeConstraint(raw) {
34255
- const trimmed = raw.trim();
34256
- const constrained = ATTRIBUTE_CONSTRAINT_RE2.exec(trimmed);
34257
- if (constrained) {
34258
- const operatorToken = constrained[2];
34259
- if (operatorToken === void 0) return null;
34260
- const operator = mapAttributeOperatorFromToken2(operatorToken);
34261
- if (operator === null) return null;
34262
- const value2 = constrained[3] ?? constrained[4] ?? constrained[5] ?? null;
34263
- if (value2 === null) return null;
34264
- const nameToken = constrained[1];
34265
- if (nameToken === void 0) return null;
34266
- return {
34267
- name: nameToken.toLowerCase(),
34268
- operator,
34269
- value: value2,
34270
- caseInsensitive: (constrained[6] ?? "").toLowerCase() === "i"
34271
- };
34272
- }
34273
- if (!ATTRIBUTE_EXISTS_RE2.test(trimmed)) return null;
34274
- return {
34275
- name: trimmed.toLowerCase(),
34276
- operator: "exists",
34277
- value: null,
34278
- caseInsensitive: false
34279
- };
34280
- }
34281
- function mapAttributeOperatorFromToken2(operator) {
34282
- if (operator === "=") return "equals";
34283
- if (operator === "~=") return "includes-word";
34284
- if (operator === "|=") return "dash-prefix";
34285
- if (operator === "^=") return "prefix";
34286
- if (operator === "$=") return "suffix";
34287
- if (operator === "*=") return "contains";
34288
- return null;
34289
- }
34290
- function parsePseudoConstraint(raw, depth) {
34291
- const trimmed = raw.trim();
34292
- const normalized = trimmed.toLowerCase();
34293
- if (normalized === ":first-child") return { kind: "first-child" };
34294
- if (normalized === ":last-child") return { kind: "last-child" };
34295
- if (normalized === ":only-child") return { kind: "only-child" };
34296
- const nthChild = parseNthPseudoArgument(trimmed, "nth-child");
34297
- if (nthChild !== void 0) {
34298
- if (nthChild === null) return null;
34299
- return { kind: "nth-child", value: nthChild };
34300
- }
34301
- const nthLastChild = parseNthPseudoArgument(trimmed, "nth-last-child");
34302
- if (nthLastChild !== void 0) {
34303
- if (nthLastChild === null) return null;
34304
- return { kind: "nth-last-child", value: nthLastChild };
34305
- }
34306
- const nthOfType = parseNthPseudoArgument(trimmed, "nth-of-type");
34307
- if (nthOfType !== void 0) {
34308
- if (nthOfType === null) return null;
34309
- return { kind: "nth-of-type", value: nthOfType };
34310
- }
34311
- const nthLastOfType = parseNthPseudoArgument(trimmed, "nth-last-of-type");
34312
- if (nthLastOfType !== void 0) {
34313
- if (nthLastOfType === null) return null;
34314
- return { kind: "nth-last-of-type", value: nthLastOfType };
34315
- }
34316
- const name = readPseudoName(normalized);
34317
- if (name === null) return null;
34318
- if (STATEFUL_PSEUDO_CLASSES.has(name)) return null;
34319
- if (name !== "is" && name !== "where" && name !== "not") {
34320
- return { kind: "ignore" };
34321
- }
34322
- const content = extractFunctionalPseudoContent(trimmed, name);
34323
- if (content === null) return null;
34324
- const selectors = compileFunctionalPseudoArguments(content, depth + 1);
34325
- if (selectors === null || selectors.length === 0) return null;
34326
- if (name === "not") {
34327
- return {
34328
- kind: "matches-none",
34329
- selectors
34330
- };
34331
- }
34332
- return {
34333
- kind: "matches-any",
34334
- selectors
34335
- };
34336
- }
34337
- function parseNthPseudoArgument(raw, name) {
34338
- const content = extractFunctionalPseudoContent(raw, name);
34339
- if (content === null) return void 0;
34340
- return parseNthPattern(content);
34341
- }
34342
- function parseNthPattern(raw) {
34343
- const normalized = raw.trim().toLowerCase().replaceAll(" ", "");
34344
- if (normalized.length === 0) return null;
34345
- if (normalized === "odd") {
34346
- return { step: 2, offset: 1 };
34347
- }
34348
- if (normalized === "even") {
34349
- return { step: 2, offset: 0 };
34350
- }
34351
- const nIndex = normalized.indexOf("n");
34352
- if (nIndex === -1) {
34353
- const value2 = Number.parseInt(normalized, 10);
34354
- if (Number.isNaN(value2)) return null;
34355
- return { step: 0, offset: value2 };
34356
- }
34357
- const stepPart = normalized.slice(0, nIndex);
34358
- const offsetPart = normalized.slice(nIndex + 1);
34359
- let step;
34360
- if (stepPart.length === 0 || stepPart === "+") {
34361
- step = 1;
34362
- } else if (stepPart === "-") {
34363
- step = -1;
34364
- } else {
34365
- step = Number.parseInt(stepPart, 10);
34366
- if (Number.isNaN(step)) return null;
34367
- }
34368
- let offset = 0;
34369
- if (offsetPart.length > 0) {
34370
- offset = Number.parseInt(offsetPart, 10);
34371
- if (Number.isNaN(offset)) return null;
34372
- }
34373
- return {
34374
- step,
34375
- offset
34376
- };
34377
- }
34378
- function extractFunctionalPseudoContent(raw, name) {
34379
- const prefix = `:${name}(`;
34380
- if (!raw.toLowerCase().startsWith(prefix)) return null;
34381
- if (!raw.endsWith(")")) return null;
34382
- return raw.slice(prefix.length, -1);
34383
- }
34384
- function compileFunctionalPseudoArguments(content, depth) {
34385
- if (depth > MAX_PSEUDO_COMPILE_DEPTH) return null;
34386
- const args = splitTopLevelSelectorArguments(content);
34387
- if (args.length === 0) return null;
34388
- const out = [];
34389
- for (let i = 0; i < args.length; i++) {
34390
- const arg = args[i];
34391
- if (arg === void 0) return null;
34392
- const raw = arg.trim();
34393
- if (raw.length === 0) return null;
34394
- const parsed = parseSelectorPattern(raw);
34395
- if (parsed === null) return null;
34396
- if (parsed.combinators.length !== 0) return null;
34397
- if (parsed.compounds.length !== 1) return null;
34398
- const compoundRaw = parsed.compounds[0];
34399
- if (compoundRaw === void 0) return null;
34400
- const compiled = compileCompound(compoundRaw, depth);
34401
- if (compiled === null) return null;
34402
- out.push(compiled);
34403
- }
34404
- return out;
34405
- }
34406
- function splitTopLevelSelectorArguments(content) {
34407
- const out = [];
34408
- let start = 0;
34409
- let parenDepth = 0;
34410
- let bracketDepth = 0;
34411
- let quote = null;
34412
- for (let i = 0; i < content.length; i++) {
34413
- const code = content.charCodeAt(i);
34414
- if (quote !== null) {
34415
- if (code === quote) quote = null;
34416
- continue;
34417
- }
34418
- if (code === CHAR_SINGLE_QUOTE || code === CHAR_DOUBLE_QUOTE) {
34419
- quote = code;
34420
- continue;
34421
- }
34422
- if (code === CHAR_OPEN_PAREN) {
34423
- parenDepth++;
34424
- continue;
34425
- }
34426
- if (code === CHAR_CLOSE_PAREN) {
34427
- if (parenDepth > 0) parenDepth--;
34428
- continue;
34429
- }
34430
- if (code === CHAR_OPEN_BRACKET) {
34431
- bracketDepth++;
34432
- continue;
34433
- }
34434
- if (code === CHAR_CLOSE_BRACKET) {
34435
- if (bracketDepth > 0) bracketDepth--;
34436
- continue;
34437
- }
34438
- if (code !== CHAR_COMMA) continue;
34439
- if (parenDepth !== 0) continue;
34440
- if (bracketDepth !== 0) continue;
34441
- out.push(content.slice(start, i));
34442
- start = i + 1;
34443
- }
34444
- out.push(content.slice(start));
34445
- return out;
34446
- }
34447
- function parseCompoundParts(raw) {
34448
- const trimmed = raw.trim();
34449
- if (trimmed.length === 0) return [];
34450
- const out = [];
34451
- const length = trimmed.length;
34452
- let i = 0;
34453
- let allowsElement = true;
34454
- while (i < length) {
34455
- const code = trimmed.charCodeAt(i);
34456
- if (code === CHAR_OPEN_BRACKET) {
34457
- const end = readBracketed(trimmed, i);
34458
- if (end === null) return [];
34459
- const inner = trimmed.slice(i + 1, end - 1);
34460
- out.push({
34461
- type: "attribute",
34462
- value: inner,
34463
- raw: trimmed.slice(i, end)
34464
- });
34465
- i = end;
34466
- allowsElement = false;
34467
- continue;
34468
- }
34469
- if (code === 35) {
34470
- const ident2 = readIdentifier(trimmed, i + 1);
34471
- if (ident2.consumed === 0) return [];
34472
- out.push({
34473
- type: "id",
34474
- value: ident2.value,
34475
- raw: trimmed.slice(i, i + 1 + ident2.consumed)
34476
- });
34477
- i += 1 + ident2.consumed;
34478
- allowsElement = false;
34479
- continue;
34480
- }
34481
- if (code === 46) {
34482
- const ident2 = readIdentifier(trimmed, i + 1);
34483
- if (ident2.consumed === 0) return [];
34484
- out.push({
34485
- type: "class",
34486
- value: ident2.value,
34487
- raw: trimmed.slice(i, i + 1 + ident2.consumed)
34488
- });
34489
- i += 1 + ident2.consumed;
34490
- allowsElement = false;
34491
- continue;
34492
- }
34493
- if (code === 58) {
34494
- const pseudo = readPseudo(trimmed, i);
34495
- if (pseudo === null) return [];
34496
- out.push(pseudo);
34497
- i += pseudo.raw.length;
34498
- allowsElement = false;
34499
- continue;
34500
- }
34501
- if (code === 42) {
34502
- out.push({
34503
- type: "universal",
34504
- value: "*",
34505
- raw: "*"
34506
- });
34507
- i++;
34508
- allowsElement = false;
34509
- continue;
34510
- }
34511
- if (!allowsElement) return [];
34512
- const ident = readIdentifier(trimmed, i);
34513
- if (ident.consumed === 0) return [];
34514
- out.push({
34515
- type: "element",
34516
- value: ident.value,
34517
- raw: trimmed.slice(i, i + ident.consumed)
34518
- });
34519
- i += ident.consumed;
34520
- allowsElement = false;
34521
- }
34522
- return out;
34523
- }
34524
- function readPseudo(input, start) {
34525
- const second = input.charCodeAt(start + 1);
34526
- if (second === 58) return null;
34527
- let i = start + 1;
34528
- while (i < input.length) {
34529
- const code = input.charCodeAt(i);
34530
- if (!isIdentChar(code)) break;
34531
- i++;
34532
- }
34533
- if (i === start + 1) return null;
34534
- const value2 = input.slice(start + 1, i);
34535
- if (input.charCodeAt(i) !== CHAR_OPEN_PAREN) {
34536
- return {
34537
- type: "pseudo-class",
34538
- value: value2,
34539
- raw: input.slice(start, i)
34540
- };
34541
- }
34542
- const end = readParenthesized(input, i);
34543
- if (end === null) return null;
34544
- return {
34545
- type: "pseudo-class",
34546
- value: value2,
34547
- raw: input.slice(start, end)
34548
- };
34549
- }
34550
- function readBracketed(input, start) {
34551
- let quote = null;
34552
- let depth = 0;
34553
- for (let i = start; i < input.length; i++) {
34554
- const code = input.charCodeAt(i);
34555
- if (quote !== null) {
34556
- if (code === quote) quote = null;
34557
- continue;
34558
- }
34559
- if (code === CHAR_SINGLE_QUOTE || code === CHAR_DOUBLE_QUOTE) {
34560
- quote = code;
34561
- continue;
34562
- }
34563
- if (code === CHAR_OPEN_BRACKET) {
34564
- depth++;
34565
- continue;
34566
- }
34567
- if (code !== CHAR_CLOSE_BRACKET) continue;
34568
- depth--;
34569
- if (depth === 0) return i + 1;
34570
- if (depth < 0) return null;
34571
- }
34572
- return null;
34573
- }
34574
- function readParenthesized(input, start) {
34575
- let quote = null;
34576
- let depth = 0;
34577
- for (let i = start; i < input.length; i++) {
34578
- const code = input.charCodeAt(i);
34579
- if (quote !== null) {
34580
- if (code === quote) quote = null;
34581
- continue;
34582
- }
34583
- if (code === CHAR_SINGLE_QUOTE || code === CHAR_DOUBLE_QUOTE) {
34584
- quote = code;
34585
- continue;
34586
- }
34587
- if (code === CHAR_OPEN_PAREN) {
34588
- depth++;
34589
- continue;
34590
- }
34591
- if (code !== CHAR_CLOSE_PAREN) continue;
34592
- depth--;
34593
- if (depth === 0) return i + 1;
34594
- if (depth < 0) return null;
34595
- }
34596
- return null;
34597
- }
34598
- var EMPTY_IDENTIFIER = { value: "", consumed: 0 };
34599
- function readIdentifier(input, start) {
34600
- const length = input.length;
34601
- let i = start;
34602
- let hasEscape = false;
34603
- while (i < length) {
34604
- const code = input.charCodeAt(i);
34605
- if (code === CHAR_BACKSLASH) {
34606
- if (i + 1 >= length) break;
34607
- hasEscape = true;
34608
- i = skipCssEscapeSequence(input, i + 1);
34609
- continue;
34610
- }
34611
- if (!isIdentChar(code)) break;
34612
- i++;
34613
- }
34614
- const consumed = i - start;
34615
- if (consumed === 0) return EMPTY_IDENTIFIER;
34616
- if (!hasEscape) {
34617
- const value2 = input.slice(start, i);
34618
- return { value: value2, consumed };
34619
- }
34620
- return { value: decodeCssEscapes(input, start, i), consumed };
34621
- }
34622
- var CHAR_BACKSLASH = 92;
34623
- function skipCssEscapeSequence(input, afterBackslash) {
34624
- const length = input.length;
34625
- if (afterBackslash >= length) return afterBackslash;
34626
- const first = input.charCodeAt(afterBackslash);
34627
- if (!isHexDigit(first)) return afterBackslash + 1;
34628
- let end = afterBackslash + 1;
34629
- const maxHex = Math.min(afterBackslash + 6, length);
34630
- while (end < maxHex && isHexDigit(input.charCodeAt(end))) end++;
34631
- if (end < length && isWhitespace(input.charCodeAt(end))) end++;
34632
- return end;
34633
- }
34634
- function decodeCssEscapes(input, start, end) {
34635
- const parts = [];
34636
- let i = start;
34637
- while (i < end) {
34638
- const code = input.charCodeAt(i);
34639
- if (code !== CHAR_BACKSLASH) {
34640
- parts.push(String.fromCharCode(code));
34641
- i++;
34642
- continue;
34643
- }
34644
- i++;
34645
- if (i >= end) break;
34646
- const first = input.charCodeAt(i);
34647
- if (!isHexDigit(first)) {
34648
- parts.push(String.fromCharCode(first));
34649
- i++;
34650
- continue;
34651
- }
34652
- const hexStart = i;
34653
- const maxHex = Math.min(i + 6, end);
34654
- while (i < maxHex && isHexDigit(input.charCodeAt(i))) i++;
34655
- const codePoint = Number.parseInt(input.slice(hexStart, i), 16);
34656
- if (codePoint > 0 && codePoint <= 1114111) {
34657
- parts.push(String.fromCodePoint(codePoint));
34658
- }
34659
- if (i < end && isWhitespace(input.charCodeAt(i))) i++;
34660
- }
34661
- return parts.join("");
34662
- }
34663
- function isSameNthPattern(left, right) {
34664
- if (left.step !== right.step) return false;
34665
- return left.offset === right.offset;
34666
- }
34667
34288
  function matchesNthPattern(index, pattern) {
34668
34289
  if (index < 1) return false;
34669
34290
  const step = pattern.step;
@@ -34682,20 +34303,6 @@ function matchesNthPattern(index, pattern) {
34682
34303
  if (delta < 0) return false;
34683
34304
  return delta % positiveStep === 0;
34684
34305
  }
34685
- function readPseudoName(raw) {
34686
- if (!raw.startsWith(":")) return null;
34687
- let index = 1;
34688
- while (index < raw.length) {
34689
- const code = raw.charCodeAt(index);
34690
- const isUpper = code >= 65 && code <= 90;
34691
- const isLower = code >= 97 && code <= 122;
34692
- const isDash = code === 45;
34693
- if (!isUpper && !isLower && !isDash) break;
34694
- index++;
34695
- }
34696
- if (index <= 1) return null;
34697
- return raw.slice(1, index);
34698
- }
34699
34306
  function matchesRequiredClasses(required, actual) {
34700
34307
  if (required.length === 0) return true;
34701
34308
  if (actual.size === 0) return false;
@@ -34708,24 +34315,24 @@ function matchesRequiredClasses(required, actual) {
34708
34315
  return true;
34709
34316
  }
34710
34317
  function matchesRequiredAttributes(required, actual) {
34711
- if (required.length === 0) return "match";
34318
+ if (required.length === 0) return 0 /* Match */;
34712
34319
  let hasConditional = false;
34713
34320
  for (let i = 0; i < required.length; i++) {
34714
34321
  const constraint = required[i];
34715
34322
  if (constraint === void 0) continue;
34716
- if (!actual.has(constraint.name)) return "no-match";
34323
+ if (!actual.has(constraint.name)) return 1 /* NoMatch */;
34717
34324
  if (constraint.operator === "exists") continue;
34718
34325
  const actualValue = actual.get(constraint.name);
34719
- if (actualValue === void 0) return "no-match";
34326
+ if (actualValue === void 0) return 1 /* NoMatch */;
34720
34327
  if (actualValue === null) {
34721
34328
  hasConditional = true;
34722
34329
  continue;
34723
34330
  }
34724
- if (constraint.value === null) return "no-match";
34331
+ if (constraint.value === null) return 1 /* NoMatch */;
34725
34332
  if (matchesAttributeValue(actualValue, constraint)) continue;
34726
- return "no-match";
34333
+ return 1 /* NoMatch */;
34727
34334
  }
34728
- return hasConditional ? "conditional" : "match";
34335
+ return hasConditional ? 2 /* Conditional */ : 0 /* Match */;
34729
34336
  }
34730
34337
  function matchesAttributeValue(actualValue, constraint) {
34731
34338
  const expectedValue = constraint.value;
@@ -34899,11 +34506,11 @@ function accumulateSnapshotFacts(snapshot, sink) {
34899
34506
  sink.addConditional();
34900
34507
  continue;
34901
34508
  }
34902
- if (value2.kind === "unknown") {
34509
+ if (value2.kind === 1 /* Unknown */) {
34903
34510
  sink.addUnknown();
34904
34511
  continue;
34905
34512
  }
34906
- if (value2.quality === "estimated" && value2.px !== null) {
34513
+ if (value2.quality === 1 /* Estimated */ && value2.px !== null) {
34907
34514
  sink.addInterval();
34908
34515
  continue;
34909
34516
  }
@@ -35245,7 +34852,7 @@ function checkHeightContributions(snapshot, state) {
35245
34852
  if (!signalName) continue;
35246
34853
  const signal = snapshot.signals.get(signalName);
35247
34854
  if (!signal) continue;
35248
- if (signal.kind !== "known") continue;
34855
+ if (signal.kind !== 0 /* Known */) continue;
35249
34856
  if (signal.px !== null && signal.px > 0) {
35250
34857
  state.hasHeightContributingDescendant = true;
35251
34858
  return;
@@ -35255,7 +34862,7 @@ function checkHeightContributions(snapshot, state) {
35255
34862
  function checkVerticalAlignMitigation(snapshot, state) {
35256
34863
  const verticalAlign = snapshot.signals.get("vertical-align");
35257
34864
  if (!verticalAlign) return;
35258
- if (verticalAlign.kind !== "known") return;
34865
+ if (verticalAlign.kind !== 0 /* Known */) return;
35259
34866
  if (VERTICAL_ALIGN_MITIGATIONS.has(verticalAlign.normalized)) {
35260
34867
  state.hasVerticalAlignMitigation = true;
35261
34868
  }
@@ -36441,16 +36048,16 @@ function establishesFormattingContext2(node, snapshotByElementNode) {
36441
36048
  const snapshot = snapshotByElementNode.get(node);
36442
36049
  if (snapshot) {
36443
36050
  const displaySignal = snapshot.signals.get("display");
36444
- if (displaySignal && displaySignal.kind === "known") {
36051
+ if (displaySignal && displaySignal.kind === 0 /* Known */) {
36445
36052
  return !isInlineLevelDisplay(displaySignal.normalized);
36446
36053
  }
36447
36054
  const overflowSignal = snapshot.signals.get("overflow");
36448
- if (overflowSignal && overflowSignal.kind === "known") {
36055
+ if (overflowSignal && overflowSignal.kind === 0 /* Known */) {
36449
36056
  const ov = overflowSignal.normalized;
36450
36057
  if (ov !== "visible" && ov !== "clip") return true;
36451
36058
  }
36452
36059
  const overflowYSignal = snapshot.signals.get("overflow-y");
36453
- if (overflowYSignal && overflowYSignal.kind === "known") {
36060
+ if (overflowYSignal && overflowYSignal.kind === 0 /* Known */) {
36454
36061
  const ov = overflowYSignal.normalized;
36455
36062
  if (ov !== "visible" && ov !== "clip") return true;
36456
36063
  }
@@ -36643,18 +36250,21 @@ function buildSelectorCandidatesByNode(elements, scopedSelectorsBySolidFile, per
36643
36250
  }
36644
36251
  return out;
36645
36252
  }
36253
+ function buildDispatchKeys(idValue, classTokens, attributeNames) {
36254
+ const out = [];
36255
+ if (idValue !== null) out.push(`id:${idValue}`);
36256
+ for (let i = 0; i < classTokens.length; i++) out.push(`class:${classTokens[i]}`);
36257
+ for (let i = 0; i < attributeNames.length; i++) out.push(`attr:${attributeNames[i]}`);
36258
+ if (out.length <= 1) return out;
36259
+ out.sort();
36260
+ return dedupeSorted(out);
36261
+ }
36646
36262
  function buildSelectorDispatchKeys(attributes, classTokens) {
36647
36263
  const out = [];
36648
36264
  const idValue = attributes.get("id");
36649
- if (idValue !== null && idValue !== void 0) {
36650
- out.push(`id:${idValue}`);
36651
- }
36652
- for (let i = 0; i < classTokens.length; i++) {
36653
- out.push(`class:${classTokens[i]}`);
36654
- }
36655
- for (const attributeName of attributes.keys()) {
36656
- out.push(`attr:${attributeName}`);
36657
- }
36265
+ if (idValue !== null && idValue !== void 0) out.push(`id:${idValue}`);
36266
+ for (let i = 0; i < classTokens.length; i++) out.push(`class:${classTokens[i]}`);
36267
+ for (const attributeName of attributes.keys()) out.push(`attr:${attributeName}`);
36658
36268
  if (out.length <= 1) return out;
36659
36269
  out.sort();
36660
36270
  return dedupeSorted(out);
@@ -36798,19 +36408,11 @@ function selectorMatchesDispatchKeys(candidate, dispatchKeys) {
36798
36408
  return subjectIndex === candidate.subjectDispatchKeys.length;
36799
36409
  }
36800
36410
  function resolveSubjectDispatchKeys(matcher) {
36801
- const out = [];
36802
- if (matcher.subject.idValue !== null) {
36803
- out.push(`id:${matcher.subject.idValue}`);
36804
- }
36805
- for (let i = 0; i < matcher.subject.classes.length; i++) {
36806
- out.push(`class:${matcher.subject.classes[i]}`);
36807
- }
36808
- for (let i = 0; i < matcher.subject.attributeNames.length; i++) {
36809
- out.push(`attr:${matcher.subject.attributeNames[i]}`);
36810
- }
36811
- if (out.length <= 1) return out;
36812
- out.sort();
36813
- return dedupeSorted(out);
36411
+ return buildDispatchKeys(
36412
+ matcher.subject.idValue,
36413
+ matcher.subject.classes,
36414
+ matcher.subject.attributeNames
36415
+ );
36814
36416
  }
36815
36417
  function dedupeSorted(values) {
36816
36418
  if (values.length <= 1) return values;
@@ -36880,6 +36482,94 @@ function normalizeWithCache(cache, path) {
36880
36482
  return normalized;
36881
36483
  }
36882
36484
 
36485
+ // src/cross-file/layout/shorthand-expansion.ts
36486
+ var QUAD_EXPANSIONS = /* @__PURE__ */ new Map([
36487
+ ["padding", ["padding-top", "padding-right", "padding-bottom", "padding-left"]],
36488
+ ["border-width", ["border-top-width", "border-right-width", "border-bottom-width", "border-left-width"]],
36489
+ ["margin", ["margin-top", "margin-right", "margin-bottom", "margin-left"]],
36490
+ ["inset", ["top", "right", "bottom", "left"]]
36491
+ ]);
36492
+ var BLOCK_EXPANSIONS = /* @__PURE__ */ new Map([
36493
+ ["margin-block", ["margin-top", "margin-bottom"]],
36494
+ ["padding-block", ["padding-top", "padding-bottom"]],
36495
+ ["inset-block", ["inset-block-start", "inset-block-end"]]
36496
+ ]);
36497
+ var INLINE_EXPANSIONS = /* @__PURE__ */ new Map([
36498
+ ["padding-inline", ["padding-left", "padding-right"]]
36499
+ ]);
36500
+ function expandShorthand(property, value2) {
36501
+ const quadTarget = QUAD_EXPANSIONS.get(property);
36502
+ if (quadTarget !== void 0) {
36503
+ const parsed = parseQuadShorthand(value2);
36504
+ if (parsed === null) return null;
36505
+ return [
36506
+ { name: quadTarget[0], value: parsed.top },
36507
+ { name: quadTarget[1], value: parsed.right },
36508
+ { name: quadTarget[2], value: parsed.bottom },
36509
+ { name: quadTarget[3], value: parsed.left }
36510
+ ];
36511
+ }
36512
+ const blockTarget = BLOCK_EXPANSIONS.get(property);
36513
+ if (blockTarget !== void 0) {
36514
+ const parsed = parseBlockShorthand(value2);
36515
+ if (parsed === null) return null;
36516
+ return [
36517
+ { name: blockTarget[0], value: parsed.start },
36518
+ { name: blockTarget[1], value: parsed.end }
36519
+ ];
36520
+ }
36521
+ const inlineTarget = INLINE_EXPANSIONS.get(property);
36522
+ if (inlineTarget !== void 0) {
36523
+ const parsed = parseBlockShorthand(value2);
36524
+ if (parsed === null) return null;
36525
+ return [
36526
+ { name: inlineTarget[0], value: parsed.start },
36527
+ { name: inlineTarget[1], value: parsed.end }
36528
+ ];
36529
+ }
36530
+ if (property === "flex-flow") {
36531
+ return expandFlexFlow(value2);
36532
+ }
36533
+ return void 0;
36534
+ }
36535
+ var FLEX_DIRECTION_VALUES = /* @__PURE__ */ new Set(["row", "row-reverse", "column", "column-reverse"]);
36536
+ function expandFlexFlow(value2) {
36537
+ const tokens = splitWhitespaceTokens(value2.trim().toLowerCase());
36538
+ if (tokens.length === 0) return null;
36539
+ if (tokens.length > 2) return null;
36540
+ let direction = null;
36541
+ let wrap = null;
36542
+ for (let i = 0; i < tokens.length; i++) {
36543
+ const token = tokens[i];
36544
+ if (!token) continue;
36545
+ if (FLEX_DIRECTION_VALUES.has(token)) {
36546
+ if (direction !== null) return null;
36547
+ direction = token;
36548
+ } else {
36549
+ if (wrap !== null) return null;
36550
+ wrap = token;
36551
+ }
36552
+ }
36553
+ const out = [];
36554
+ if (direction !== null) {
36555
+ out.push({ name: "flex-direction", value: direction });
36556
+ }
36557
+ if (wrap !== null) {
36558
+ out.push({ name: "flex-wrap", value: wrap });
36559
+ }
36560
+ return out.length > 0 ? out : null;
36561
+ }
36562
+ function getShorthandLonghandNames(property) {
36563
+ const quad = QUAD_EXPANSIONS.get(property);
36564
+ if (quad !== void 0) return [...quad];
36565
+ const block = BLOCK_EXPANSIONS.get(property);
36566
+ if (block !== void 0) return [...block];
36567
+ const inline = INLINE_EXPANSIONS.get(property);
36568
+ if (inline !== void 0) return [...inline];
36569
+ if (property === "flex-flow") return ["flex-direction", "flex-wrap"];
36570
+ return null;
36571
+ }
36572
+
36883
36573
  // src/cross-file/layout/stateful-rule-index.ts
36884
36574
  var EMPTY_STATEFUL_SELECTOR_ENTRY_LIST = [];
36885
36575
  var EMPTY_LAYOUT_NORMALIZED_DECLARATION_LIST = [];
@@ -37097,7 +36787,6 @@ var DYNAMIC_ATTRIBUTE_GUARD = {
37097
36787
  key: "dynamic-attribute:*"
37098
36788
  };
37099
36789
  var SCROLLABLE_VALUES = /* @__PURE__ */ new Set(["auto", "scroll"]);
37100
- var EMPTY_EXPANSION_RESULT = [];
37101
36790
  function collectMonitoredDeclarations(selector, layerOrder, guard) {
37102
36791
  const out = [];
37103
36792
  const declarations = selector.rule.declarations;
@@ -37106,59 +36795,50 @@ function collectMonitoredDeclarations(selector, layerOrder, guard) {
37106
36795
  if (!declaration) continue;
37107
36796
  const property = declaration.property.toLowerCase();
37108
36797
  if (!isMonitoredSignal(property)) continue;
37109
- const monitored = toMonitoredSignalKey(property);
37110
- if (!monitored) continue;
37111
- out.push({
37112
- property: monitored,
37113
- value: declaration.value,
37114
- guardProvenance: guard,
37115
- position: {
37116
- layer: declaration.cascadePosition.layer,
37117
- layerOrder,
37118
- sourceOrder: declaration.sourceOrder,
37119
- specificity: selector.specificity,
37120
- specificityScore: selector.specificityScore,
37121
- isImportant: declaration.cascadePosition.isImportant || declaration.node.important
36798
+ const position = {
36799
+ layer: declaration.cascadePosition.layer,
36800
+ layerOrder,
36801
+ sourceOrder: declaration.sourceOrder,
36802
+ specificity: selector.specificity,
36803
+ specificityScore: selector.specificityScore,
36804
+ isImportant: declaration.cascadePosition.isImportant || declaration.node.important
36805
+ };
36806
+ const directSignal = MONITORED_SIGNAL_NAME_MAP.get(property);
36807
+ if (directSignal !== void 0) {
36808
+ out.push({ property: directSignal, value: declaration.value, guardProvenance: guard, position });
36809
+ continue;
36810
+ }
36811
+ const value2 = declaration.value.trim().toLowerCase();
36812
+ const expanded = expandShorthand(property, value2);
36813
+ if (expanded === void 0) continue;
36814
+ if (expanded === null) {
36815
+ const longhandNames = getShorthandLonghandNames(property);
36816
+ if (longhandNames === null) continue;
36817
+ for (let j = 0; j < longhandNames.length; j++) {
36818
+ const longhand = longhandNames[j];
36819
+ if (!longhand) continue;
36820
+ const signal = MONITORED_SIGNAL_NAME_MAP.get(longhand);
36821
+ if (signal === void 0) continue;
36822
+ out.push({ property: signal, value: declaration.value, guardProvenance: guard, position });
37122
36823
  }
37123
- });
36824
+ continue;
36825
+ }
36826
+ for (let j = 0; j < expanded.length; j++) {
36827
+ const entry = expanded[j];
36828
+ if (!entry) continue;
36829
+ const signal = MONITORED_SIGNAL_NAME_MAP.get(entry.name);
36830
+ if (signal === void 0) continue;
36831
+ out.push({ property: signal, value: entry.value, guardProvenance: guard, position });
36832
+ }
37124
36833
  }
37125
36834
  return out;
37126
36835
  }
37127
- function toMonitoredSignalKey(property) {
37128
- const signal = MONITORED_SIGNAL_NAME_MAP.get(property);
37129
- if (signal) return signal;
37130
- switch (property) {
37131
- case "padding":
37132
- case "border-width":
37133
- case "margin-block":
37134
- case "padding-block":
37135
- case "inset-block":
37136
- case "flex-flow":
37137
- return property;
37138
- default:
37139
- return null;
37140
- }
37141
- }
37142
36836
  function expandMonitoredDeclarationForDelta(declaration) {
37143
- const value2 = declaration.value.trim().toLowerCase();
37144
- const expanded = expandShorthand(declaration.property, value2);
37145
- if (expanded !== void 0) {
37146
- if (expanded === null) return EMPTY_EXPANSION_RESULT;
37147
- const filtered = [];
37148
- for (let i = 0; i < expanded.length; i++) {
37149
- const entry = expanded[i];
37150
- if (!entry) continue;
37151
- const signalName2 = MONITORED_SIGNAL_NAME_MAP.get(entry.name);
37152
- if (signalName2 !== void 0) filtered.push({ name: signalName2, value: entry.value });
37153
- }
37154
- return filtered;
37155
- }
37156
- const signalName = MONITORED_SIGNAL_NAME_MAP.get(declaration.property);
37157
- if (signalName === void 0) return EMPTY_EXPANSION_RESULT;
37158
- return [{ name: signalName, value: value2 }];
36837
+ return [{ name: declaration.property, value: declaration.value.trim().toLowerCase() }];
37159
36838
  }
37160
36839
  function appendMatchingEdgesFromSelectorIds(ctx, selectorIds, node, applies, appliesByElementNodeMutable) {
37161
36840
  const fileRoots = ctx.rootElementsByFile.get(node.solidFile) ?? null;
36841
+ const fileElementIndex = ctx.fileElementIndexByFile.get(node.solidFile) ?? null;
37162
36842
  for (let i = 0; i < selectorIds.length; i++) {
37163
36843
  const selectorId = selectorIds[i];
37164
36844
  if (selectorId === void 0) continue;
@@ -37170,13 +36850,13 @@ function appendMatchingEdgesFromSelectorIds(ctx, selectorIds, node, applies, app
37170
36850
  if (!selector) {
37171
36851
  throw new Error(`missing selector ${selectorId}`);
37172
36852
  }
37173
- const matchResult = selectorMatchesLayoutElement(metadata.matcher, node, ctx.perf, fileRoots, ctx.logger);
37174
- if (matchResult === "no-match") continue;
36853
+ const matchResult = selectorMatchesLayoutElement(metadata.matcher, node, ctx.perf, fileRoots, ctx.logger, fileElementIndex);
36854
+ if (matchResult === 1 /* NoMatch */) continue;
37175
36855
  const edge = {
37176
36856
  selectorId: selector.id,
37177
36857
  specificityScore: selector.specificityScore,
37178
36858
  sourceOrder: selector.rule.sourceOrder,
37179
- conditionalMatch: matchResult === "conditional"
36859
+ conditionalMatch: matchResult === 2 /* Conditional */
37180
36860
  };
37181
36861
  applies.push(edge);
37182
36862
  ctx.perf.matchEdgesCreated++;
@@ -37233,7 +36913,54 @@ function augmentCascadeWithTailwind(cascade, node, tailwind) {
37233
36913
  }
37234
36914
  }
37235
36915
  }
37236
- function buildCascadeMapForElement(node, edges, monitoredDeclarationsBySelectorId, tailwind) {
36916
+ var MAX_VAR_SUBSTITUTION_DEPTH = 10;
36917
+ function resolveVarReferencesInCascade(cascade, variablesByName) {
36918
+ for (const [property, declaration] of cascade) {
36919
+ if (!declaration.value.includes("var(")) continue;
36920
+ const resolved = substituteVarReferences(declaration.value, variablesByName, 0);
36921
+ if (resolved !== declaration.value) {
36922
+ cascade.set(property, {
36923
+ value: resolved,
36924
+ source: declaration.source,
36925
+ guardProvenance: declaration.guardProvenance
36926
+ });
36927
+ }
36928
+ }
36929
+ }
36930
+ function substituteVarReferences(value2, variablesByName, depth) {
36931
+ if (depth >= MAX_VAR_SUBSTITUTION_DEPTH) return value2;
36932
+ const refs = extractVarReferences(value2);
36933
+ if (refs.length === 0) return value2;
36934
+ let result = value2;
36935
+ for (let i = refs.length - 1; i >= 0; i--) {
36936
+ const ref = refs[i];
36937
+ if (!ref) continue;
36938
+ const candidates = variablesByName.get(ref.name);
36939
+ const resolvedValue = candidates !== void 0 && candidates.length > 0 ? selectBestVariableValue(candidates) : ref.fallback;
36940
+ if (resolvedValue === null) continue;
36941
+ result = result.slice(0, ref.sourceIndex) + resolvedValue + result.slice(ref.sourceIndex + ref.raw.length);
36942
+ }
36943
+ if (result !== value2 && result.includes("var(")) {
36944
+ return substituteVarReferences(result, variablesByName, depth + 1);
36945
+ }
36946
+ return result;
36947
+ }
36948
+ function selectBestVariableValue(candidates) {
36949
+ let bestGlobal = null;
36950
+ for (let i = 0; i < candidates.length; i++) {
36951
+ const candidate = candidates[i];
36952
+ if (!candidate) continue;
36953
+ if (candidate.scope.type === "global") {
36954
+ if (bestGlobal === null || candidate.declaration.sourceOrder > bestGlobal.declaration.sourceOrder) {
36955
+ bestGlobal = candidate;
36956
+ }
36957
+ }
36958
+ }
36959
+ if (bestGlobal !== null) return bestGlobal.value;
36960
+ const first = candidates[0];
36961
+ return first ? first.value : null;
36962
+ }
36963
+ function buildCascadeMapForElement(node, edges, monitoredDeclarationsBySelectorId, tailwind, variablesByName) {
37237
36964
  const out = /* @__PURE__ */ new Map();
37238
36965
  const positions = /* @__PURE__ */ new Map();
37239
36966
  for (let i = 0; i < edges.length; i++) {
@@ -37291,6 +37018,9 @@ function buildCascadeMapForElement(node, edges, monitoredDeclarationsBySelectorI
37291
37018
  if (tailwind !== null) {
37292
37019
  augmentCascadeWithTailwind(out, node, tailwind);
37293
37020
  }
37021
+ if (variablesByName !== null) {
37022
+ resolveVarReferencesInCascade(out, variablesByName);
37023
+ }
37294
37024
  return out;
37295
37025
  }
37296
37026
  function compareLayoutEdge(a, b) {
@@ -37331,14 +37061,14 @@ function resolveRuleLayerOrder(rule, css) {
37331
37061
  if (!name) return 0;
37332
37062
  return css.layerOrder.get(name) ?? 0;
37333
37063
  }
37334
- function buildConditionalDeltaIndex(elements, appliesByNode, monitoredDeclarationsBySelectorId, selectorsById) {
37064
+ function buildConditionalDeltaIndex(elements, records, monitoredDeclarationsBySelectorId, selectorsById) {
37335
37065
  const conditionalSignalDeltaFactsByNode = /* @__PURE__ */ new Map();
37336
37066
  const elementsWithConditionalDeltaBySignal = /* @__PURE__ */ new Map();
37337
37067
  const baselineOffsetFactsByNode = /* @__PURE__ */ new Map();
37338
37068
  for (let i = 0; i < elements.length; i++) {
37339
37069
  const node = elements[i];
37340
37070
  if (!node) continue;
37341
- const edges = appliesByNode.get(node);
37071
+ const edges = records.get(node)?.edges;
37342
37072
  let factByProperty = null;
37343
37073
  if (edges !== void 0 && edges.length > 0) {
37344
37074
  const byProperty = /* @__PURE__ */ new Map();
@@ -37693,7 +37423,7 @@ function collectLayoutElementRecordsForSolid(solid, selectorRequirements, inline
37693
37423
  const classTokenSet = classTokens.length === 0 ? EMPTY_CLASS_TOKEN_SET : createClassTokenSet(classTokens);
37694
37424
  const inlineStyleKeys = getStaticStyleKeysForElement(solid, element.id);
37695
37425
  const localAttributes = selectorRequirements.needsAttributes ? collectStaticAttributes(element) : EMPTY_ATTRIBUTES2;
37696
- const attributes = mergeAttributes(localAttributes, meta.resolvedHost?.descriptor.staticAttributes);
37426
+ const attributes = mergeAttributes(localAttributes, meta.resolvedHost?.descriptor.staticAttributes, meta.resolvedHost?.descriptor.attributePropBindings);
37697
37427
  const selectorDispatchKeys = buildSelectorDispatchKeys(attributes, classTokens);
37698
37428
  const inlineStyleValues = inlineStyleValuesByElementId.get(element.id) ?? EMPTY_INLINE_STYLE_VALUES;
37699
37429
  const textualContent = getTextualContentState(element, textContentMemo, compositionMetaByElementId, logger);
@@ -37749,7 +37479,63 @@ function collectCompositionMetaByElementId(solid, componentHostResolver) {
37749
37479
  function resolveHostForElement(componentHostResolver, solidFile, element) {
37750
37480
  if (element.tag === null) return null;
37751
37481
  if (element.isDomElement) return null;
37752
- return componentHostResolver.resolveHost(solidFile, element.tag);
37482
+ const defaultHost = componentHostResolver.resolveHost(solidFile, element.tag);
37483
+ const asTag = extractPolymorphicAsTag(element);
37484
+ if (asTag !== null) {
37485
+ const asHost = componentHostResolver.resolveHost(solidFile, asTag);
37486
+ if (asHost !== null) return composePolymorphicHost(defaultHost, asHost);
37487
+ }
37488
+ return defaultHost;
37489
+ }
37490
+ function extractPolymorphicAsTag(element) {
37491
+ for (let i = 0; i < element.attributes.length; i++) {
37492
+ const attr = element.attributes[i];
37493
+ if (!attr) continue;
37494
+ if (attr.name !== "as") continue;
37495
+ if (attr.valueNode === null) continue;
37496
+ if (!import_typescript127.default.isJsxExpression(attr.valueNode)) continue;
37497
+ const expression = attr.valueNode.expression;
37498
+ if (!expression) continue;
37499
+ if (import_typescript127.default.isIdentifier(expression)) return expression.text;
37500
+ if (import_typescript127.default.isPropertyAccessExpression(expression)) return expression.getText();
37501
+ return null;
37502
+ }
37503
+ return null;
37504
+ }
37505
+ function composePolymorphicHost(outerHost, asHost) {
37506
+ if (outerHost === null) return asHost;
37507
+ const outerDesc = outerHost.descriptor;
37508
+ const asDesc = asHost.descriptor;
37509
+ const staticAttributes = /* @__PURE__ */ new Map();
37510
+ for (const [name, value2] of outerDesc.staticAttributes) staticAttributes.set(name, value2);
37511
+ for (const [name, value2] of asDesc.staticAttributes) staticAttributes.set(name, value2);
37512
+ const classTokenSet = /* @__PURE__ */ new Set();
37513
+ const staticClassTokens = [];
37514
+ for (const token of outerDesc.staticClassTokens) {
37515
+ if (!classTokenSet.has(token)) {
37516
+ classTokenSet.add(token);
37517
+ staticClassTokens.push(token);
37518
+ }
37519
+ }
37520
+ for (const token of asDesc.staticClassTokens) {
37521
+ if (!classTokenSet.has(token)) {
37522
+ classTokenSet.add(token);
37523
+ staticClassTokens.push(token);
37524
+ }
37525
+ }
37526
+ const attributePropBindings = /* @__PURE__ */ new Map();
37527
+ for (const [name, value2] of outerDesc.attributePropBindings) attributePropBindings.set(name, value2);
37528
+ for (const [name, value2] of asDesc.attributePropBindings) attributePropBindings.set(name, value2);
37529
+ return {
37530
+ descriptor: {
37531
+ tagName: asDesc.tagName ?? outerDesc.tagName,
37532
+ staticAttributes,
37533
+ staticClassTokens,
37534
+ forwardsChildren: asDesc.forwardsChildren || outerDesc.forwardsChildren,
37535
+ attributePropBindings
37536
+ },
37537
+ hostElementRef: asHost.hostElementRef ?? outerHost.hostElementRef
37538
+ };
37753
37539
  }
37754
37540
  function resolveTransparentPrimitiveStatus(componentHostResolver, solidFile, element, resolvedHost) {
37755
37541
  if (element.tag === null) return false;
@@ -37792,11 +37578,21 @@ function mergeClassTokens(localTokens, hostTokens) {
37792
37578
  }
37793
37579
  return out;
37794
37580
  }
37795
- function mergeAttributes(localAttributes, hostAttributes) {
37581
+ function mergeAttributes(localAttributes, hostAttributes, propBindings) {
37796
37582
  if (hostAttributes === void 0 || hostAttributes.size === 0) return localAttributes;
37797
- if (localAttributes.size === 0) return hostAttributes;
37583
+ if (localAttributes.size === 0 && (propBindings === void 0 || propBindings.size === 0)) return hostAttributes;
37798
37584
  const out = /* @__PURE__ */ new Map();
37799
37585
  for (const [name, value2] of hostAttributes) {
37586
+ if (propBindings !== void 0) {
37587
+ const propName = propBindings.get(name);
37588
+ if (propName !== void 0) {
37589
+ const callSiteValue = localAttributes.get(propName);
37590
+ if (callSiteValue !== void 0 && callSiteValue !== null) {
37591
+ out.set(name, callSiteValue);
37592
+ continue;
37593
+ }
37594
+ }
37595
+ }
37800
37596
  out.set(name, value2);
37801
37597
  }
37802
37598
  for (const [name, value2] of localAttributes) {
@@ -37862,7 +37658,9 @@ function resolveSiblingTypeCount(totalsByParentId, parentElementId, tagName, sib
37862
37658
 
37863
37659
  // src/cross-file/layout/build.ts
37864
37660
  var EMPTY_NUMBER_LIST2 = [];
37865
- var NON_RESERVING_DIMENSION_KEYWORDS = /* @__PURE__ */ new Set(["auto", "none", "fit-content", "min-content", "max-content", "stretch"]);
37661
+ var EMPTY_EDGE_LIST = Object.freeze([]);
37662
+ var NON_RESERVING_DIMENSION_KEYWORDS = /* @__PURE__ */ new Set(["auto", "none", "fit-content", "min-content", "max-content", "stretch", "inherit", "initial", "unset", "revert", "revert-layer"]);
37663
+ 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"]);
37866
37664
  function buildLayoutGraph(solids, css, logger = noopLogger) {
37867
37665
  const perf = createLayoutPerfStats();
37868
37666
  const startedAt = performance.now();
@@ -37877,7 +37675,6 @@ function buildLayoutGraph(solids, css, logger = noopLogger) {
37877
37675
  const selectorsById = /* @__PURE__ */ new Map();
37878
37676
  const monitoredDeclarationsBySelectorId = /* @__PURE__ */ new Map();
37879
37677
  const selectorMetadataById = /* @__PURE__ */ new Map();
37880
- const cascadeByElementNode = /* @__PURE__ */ new WeakMap();
37881
37678
  for (let i = 0; i < css.selectors.length; i++) {
37882
37679
  const selector = css.selectors[i];
37883
37680
  if (!selector) continue;
@@ -37950,7 +37747,7 @@ function buildLayoutGraph(solids, css, logger = noopLogger) {
37950
37747
  };
37951
37748
  const textContentMemo = /* @__PURE__ */ new Map();
37952
37749
  const inlineStyleValuesByElementId = collectInlineStyleValuesByElementId(solid);
37953
- const records = collectLayoutElementRecordsForSolid(
37750
+ const records2 = collectLayoutElementRecordsForSolid(
37954
37751
  solid,
37955
37752
  selectorRequirements,
37956
37753
  inlineStyleValuesByElementId,
@@ -37958,12 +37755,12 @@ function buildLayoutGraph(solids, css, logger = noopLogger) {
37958
37755
  componentHostResolver,
37959
37756
  logger
37960
37757
  );
37961
- const siblingTotals = collectSiblingTotals(records);
37758
+ const siblingTotals = collectSiblingTotals(records2);
37962
37759
  const nodeByElementId = /* @__PURE__ */ new Map();
37963
37760
  const lastChildByParentId = /* @__PURE__ */ new Map();
37964
37761
  const siblingTypeSeenByParentId = /* @__PURE__ */ new Map();
37965
- for (let i = 0; i < records.length; i++) {
37966
- const record = records[i];
37762
+ for (let i = 0; i < records2.length; i++) {
37763
+ const record = records2[i];
37967
37764
  if (!record) continue;
37968
37765
  const parentElementId = record.parentElementId;
37969
37766
  const parentNode = parentElementId === null ? null : nodeByElementId.get(parentElementId) ?? null;
@@ -38028,6 +37825,7 @@ function buildLayoutGraph(solids, css, logger = noopLogger) {
38028
37825
  }
38029
37826
  }
38030
37827
  }
37828
+ const fileElementIndexByFile = buildFileElementIndexByFile(elements);
38031
37829
  if (logger.isLevelEnabled(Level.Debug)) {
38032
37830
  for (const [file, roots] of rootElementsByFile) {
38033
37831
  const descs = roots.map((r) => `${r.key}(tag=${r.tagName}, attrs=[${[...r.attributes.entries()].map(([k, v]) => `${k}=${v}`).join(",")}])`);
@@ -38039,63 +37837,138 @@ function buildLayoutGraph(solids, css, logger = noopLogger) {
38039
37837
  selectorMetadataById,
38040
37838
  selectorsById,
38041
37839
  rootElementsByFile,
37840
+ fileElementIndexByFile,
38042
37841
  perf,
38043
37842
  logger
38044
37843
  };
38045
- for (let i = 0; i < elements.length; i++) {
38046
- const node = elements[i];
38047
- if (!node) continue;
38048
- const selectorIds = selectorCandidatesByNode.get(node) ?? EMPTY_NUMBER_LIST2;
38049
- if (selectorIds.length === 0) continue;
38050
- appendMatchingEdgesFromSelectorIds(
38051
- selectorMatchCtx,
38052
- selectorIds,
38053
- node,
38054
- applies,
38055
- appliesByElementNodeMutable
38056
- );
38057
- }
38058
- perf.selectorMatchMs = performance.now() - selectorMatchStartedAt;
38059
- const cascadeStartedAt = performance.now();
38060
- for (const edges of appliesByElementNodeMutable.values()) {
38061
- edges.sort(compareLayoutEdge);
38062
- }
38063
- const appliesByNode = /* @__PURE__ */ new Map();
38064
37844
  const tailwind = css.tailwind;
37845
+ const records = /* @__PURE__ */ new Map();
37846
+ const snapshotByElementNode = /* @__PURE__ */ new WeakMap();
37847
+ const snapshotHotSignalsByNode = /* @__PURE__ */ new Map();
37848
+ const elementsByTagName = /* @__PURE__ */ new Map();
37849
+ const elementsByKnownSignalValue = /* @__PURE__ */ new Map();
37850
+ const dynamicSlotCandidateElements = [];
37851
+ const scrollContainerElements = [];
37852
+ const positionedAncestorByKey = /* @__PURE__ */ new Map();
37853
+ const trace = logger.isLevelEnabled(Level.Trace);
38065
37854
  for (let i = 0; i < elements.length; i++) {
38066
37855
  const node = elements[i];
38067
37856
  if (!node) continue;
38068
- const edges = appliesByElementNodeMutable.get(node) ?? [];
38069
- const cascade = buildCascadeMapForElement(node, edges, monitoredDeclarationsBySelectorId, tailwind);
38070
- cascadeByElementNode.set(node, cascade);
38071
- appliesByNode.set(node, edges);
38072
- }
38073
- perf.cascadeBuildMs = performance.now() - cascadeStartedAt;
38074
- if (logger.isLevelEnabled(Level.Trace)) {
38075
- for (let i = 0; i < elements.length; i++) {
38076
- const node = elements[i];
38077
- if (!node) continue;
38078
- const cascade = cascadeByElementNode.get(node);
38079
- if (!cascade || cascade.size === 0) continue;
37857
+ const selectorIds = selectorCandidatesByNode.get(node) ?? EMPTY_NUMBER_LIST2;
37858
+ if (selectorIds.length > 0) {
37859
+ appendMatchingEdgesFromSelectorIds(
37860
+ selectorMatchCtx,
37861
+ selectorIds,
37862
+ node,
37863
+ applies,
37864
+ appliesByElementNodeMutable
37865
+ );
37866
+ }
37867
+ const mutableEdges = appliesByElementNodeMutable.get(node);
37868
+ if (mutableEdges) mutableEdges.sort(compareLayoutEdge);
37869
+ const edges = mutableEdges ?? EMPTY_EDGE_LIST;
37870
+ const cascade = buildCascadeMapForElement(node, edges, monitoredDeclarationsBySelectorId, tailwind, css.variablesByName);
37871
+ if (trace && cascade.size > 0) {
38080
37872
  const displayDecl = cascade.get("display");
38081
37873
  const flexDirDecl = cascade.get("flex-direction");
38082
- if (!displayDecl && !flexDirDecl) continue;
38083
- const displayGuard = displayDecl?.guardProvenance.kind === 1 /* Conditional */ ? "conditional" : "unconditional";
38084
- const flexDirGuard = flexDirDecl?.guardProvenance.kind === 1 /* Conditional */ ? "conditional" : "unconditional";
38085
- logger.trace(
38086
- `[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(",")}]`
38087
- );
37874
+ if (displayDecl || flexDirDecl) {
37875
+ const displayGuard = displayDecl?.guardProvenance.kind === 1 /* Conditional */ ? "conditional" : "unconditional";
37876
+ const flexDirGuard = flexDirDecl?.guardProvenance.kind === 1 /* Conditional */ ? "conditional" : "unconditional";
37877
+ logger.trace(
37878
+ `[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(",")}]`
37879
+ );
37880
+ }
37881
+ }
37882
+ const parentSnapshot = node.parentElementNode ? records.get(node.parentElementNode)?.snapshot ?? null : null;
37883
+ const snapshot = buildSnapshotFromCascade(node, cascade, parentSnapshot);
37884
+ snapshotByElementNode.set(node, snapshot);
37885
+ perf.signalSnapshotsBuilt++;
37886
+ if (node.textualContent === 2 /* Unknown */ && node.siblingCount >= 2) {
37887
+ dynamicSlotCandidateElements.push(node);
37888
+ }
37889
+ if (node.tagName) {
37890
+ const existing = elementsByTagName.get(node.tagName);
37891
+ if (existing) existing.push(node);
37892
+ else elementsByTagName.set(node.tagName, [node]);
37893
+ }
37894
+ for (const [signal, value2] of snapshot.signals) {
37895
+ if (value2.kind !== 0 /* Known */) continue;
37896
+ let byValue = elementsByKnownSignalValue.get(signal);
37897
+ if (!byValue) {
37898
+ byValue = /* @__PURE__ */ new Map();
37899
+ elementsByKnownSignalValue.set(signal, byValue);
37900
+ }
37901
+ const existingNodes = byValue.get(value2.normalized);
37902
+ if (existingNodes) existingNodes.push(node);
37903
+ else byValue.set(value2.normalized, [node]);
38088
37904
  }
37905
+ const parentKey = node.parentElementNode?.key ?? null;
37906
+ let nearestPositionedAncestorKey = null;
37907
+ let nearestPositionedAncestorHasReservedSpace = false;
37908
+ if (parentKey !== null) {
37909
+ const parentPositioned = positionedAncestorByKey.get(parentKey);
37910
+ if (parentPositioned !== void 0) {
37911
+ nearestPositionedAncestorKey = parentPositioned.key;
37912
+ nearestPositionedAncestorHasReservedSpace = parentPositioned.hasReservedSpace;
37913
+ }
37914
+ }
37915
+ const containingBlock = {
37916
+ nearestPositionedAncestorKey,
37917
+ nearestPositionedAncestorHasReservedSpace
37918
+ };
37919
+ const reservedSpace = computeReservedSpaceFact(snapshot);
37920
+ const scrollContainer = computeScrollContainerFact(snapshot);
37921
+ if (scrollContainer.isScrollContainer) scrollContainerElements.push(node);
37922
+ const flowParticipation = computeFlowParticipationFact(snapshot);
37923
+ const hotSignals = computeHotSignals(snapshot);
37924
+ snapshotHotSignalsByNode.set(node, hotSignals);
37925
+ const positionSignal = snapshot.signals.get("position");
37926
+ const isPositioned = positionSignal !== void 0 && positionSignal.kind === 0 /* Known */ && positionSignal.normalized !== "static";
37927
+ if (isPositioned) {
37928
+ positionedAncestorByKey.set(node.key, { key: node.key, hasReservedSpace: reservedSpace.hasReservedSpace });
37929
+ } else if (parentKey !== null) {
37930
+ const inherited = positionedAncestorByKey.get(parentKey);
37931
+ if (inherited !== void 0) positionedAncestorByKey.set(node.key, inherited);
37932
+ }
37933
+ records.set(node, {
37934
+ ref: elementRefsBySolidFileAndIdMutable.get(node.solidFile)?.get(node.elementId) ?? null,
37935
+ edges,
37936
+ cascade,
37937
+ snapshot,
37938
+ hotSignals,
37939
+ reservedSpace,
37940
+ scrollContainer,
37941
+ flowParticipation,
37942
+ containingBlock,
37943
+ conditionalDelta: null,
37944
+ baselineOffsets: null
37945
+ });
38089
37946
  }
38090
- const snapshotByElementNode = buildSignalSnapshotIndex(elements, cascadeByElementNode, perf);
38091
- const measurementNodeByRootKey = buildMeasurementNodeIndex(elements, childrenByParentNodeMutable, snapshotByElementNode);
38092
- const factIndex = buildElementFactIndex(elements, snapshotByElementNode);
37947
+ perf.selectorMatchMs = performance.now() - selectorMatchStartedAt;
38093
37948
  const conditionalDeltaIndex = buildConditionalDeltaIndex(
38094
37949
  elements,
38095
- appliesByNode,
37950
+ records,
38096
37951
  monitoredDeclarationsBySelectorId,
38097
37952
  selectorsById
38098
37953
  );
37954
+ for (const [node, deltaByProperty] of conditionalDeltaIndex.conditionalSignalDeltaFactsByNode) {
37955
+ const record = records.get(node);
37956
+ if (!record) continue;
37957
+ const baselineOffsets = conditionalDeltaIndex.baselineOffsetFactsByNode.get(node) ?? null;
37958
+ records.set(node, {
37959
+ ref: record.ref,
37960
+ edges: record.edges,
37961
+ cascade: record.cascade,
37962
+ snapshot: record.snapshot,
37963
+ hotSignals: record.hotSignals,
37964
+ reservedSpace: record.reservedSpace,
37965
+ scrollContainer: record.scrollContainer,
37966
+ flowParticipation: record.flowParticipation,
37967
+ containingBlock: record.containingBlock,
37968
+ conditionalDelta: deltaByProperty,
37969
+ baselineOffsets
37970
+ });
37971
+ }
38099
37972
  const elementsWithConditionalOverflowDelta = buildConditionalDeltaSignalGroupElements(
38100
37973
  conditionalDeltaIndex.elementsWithConditionalDeltaBySignal,
38101
37974
  ["overflow", "overflow-y"]
@@ -38104,6 +37977,7 @@ function buildLayoutGraph(solids, css, logger = noopLogger) {
38104
37977
  conditionalDeltaIndex.elementsWithConditionalDeltaBySignal,
38105
37978
  layoutOffsetSignals
38106
37979
  );
37980
+ const measurementNodeByRootKey = buildMeasurementNodeIndex(elements, childrenByParentNodeMutable, snapshotByElementNode);
38107
37981
  const statefulRuleIndexes = buildStatefulRuleIndexes(css.rules);
38108
37982
  const contextByParentNode = buildContextIndex(childrenByParentNodeMutable, snapshotByElementNode, perf, logger);
38109
37983
  const cohortIndex = buildCohortIndex({
@@ -38111,7 +37985,7 @@ function buildLayoutGraph(solids, css, logger = noopLogger) {
38111
37985
  contextByParentNode,
38112
37986
  measurementNodeByRootKey,
38113
37987
  snapshotByElementNode,
38114
- snapshotHotSignalsByNode: factIndex.snapshotHotSignalsByNode
37988
+ snapshotHotSignalsByNode
38115
37989
  });
38116
37990
  finalizeTableCellBaselineRelevance(contextByParentNode, cohortIndex.verticalAlignConsensusByParent);
38117
37991
  perf.conditionalSignals = cohortIndex.conditionalSignals;
@@ -38128,122 +38002,71 @@ function buildLayoutGraph(solids, css, logger = noopLogger) {
38128
38002
  elementBySolidFileAndId: elementBySolidFileAndIdMutable,
38129
38003
  elementRefsBySolidFileAndId: elementRefsBySolidFileAndIdMutable,
38130
38004
  hostElementRefsByNode: hostElementRefsByNodeMutable,
38131
- appliesByNode,
38132
38005
  selectorCandidatesByNode,
38133
38006
  selectorsById,
38134
38007
  measurementNodeByRootKey,
38135
- snapshotHotSignalsByNode: factIndex.snapshotHotSignalsByNode,
38136
- elementsByTagName: factIndex.elementsByTagName,
38008
+ records,
38009
+ elementsByTagName,
38137
38010
  elementsWithConditionalDeltaBySignal: conditionalDeltaIndex.elementsWithConditionalDeltaBySignal,
38138
38011
  elementsWithConditionalOverflowDelta,
38139
38012
  elementsWithConditionalOffsetDelta,
38140
- elementsByKnownSignalValue: factIndex.elementsByKnownSignalValue,
38141
- dynamicSlotCandidateElements: factIndex.dynamicSlotCandidateElements,
38142
- scrollContainerElements: factIndex.scrollContainerElements,
38143
- reservedSpaceFactsByNode: factIndex.reservedSpaceFactsByNode,
38144
- scrollContainerFactsByNode: factIndex.scrollContainerFactsByNode,
38145
- flowParticipationFactsByNode: factIndex.flowParticipationFactsByNode,
38146
- containingBlockFactsByNode: factIndex.containingBlockFactsByNode,
38147
- conditionalSignalDeltaFactsByNode: conditionalDeltaIndex.conditionalSignalDeltaFactsByNode,
38148
- baselineOffsetFactsByNode: conditionalDeltaIndex.baselineOffsetFactsByNode,
38013
+ elementsByKnownSignalValue,
38014
+ dynamicSlotCandidateElements,
38015
+ scrollContainerElements,
38149
38016
  statefulSelectorEntriesByRuleId: statefulRuleIndexes.selectorEntriesByRuleId,
38150
38017
  statefulNormalizedDeclarationsByRuleId: statefulRuleIndexes.normalizedDeclarationsByRuleId,
38151
38018
  statefulBaseValueIndex: statefulRuleIndexes.baseValueIndex,
38152
38019
  cohortStatsByParentNode: cohortIndex.statsByParentNode,
38153
- cascadeByElementNode,
38154
- snapshotByElementNode,
38155
38020
  contextByParentNode,
38156
38021
  perf
38157
38022
  };
38158
38023
  }
38159
- function buildElementFactIndex(elements, snapshotByElementNode) {
38160
- const reservedSpaceFactsByNode = /* @__PURE__ */ new Map();
38161
- const scrollContainerFactsByNode = /* @__PURE__ */ new Map();
38162
- const flowParticipationFactsByNode = /* @__PURE__ */ new Map();
38163
- const containingBlockFactsByNode = /* @__PURE__ */ new Map();
38164
- const snapshotHotSignalsByNode = /* @__PURE__ */ new Map();
38165
- const elementsByTagName = /* @__PURE__ */ new Map();
38166
- const elementsByKnownSignalValue = /* @__PURE__ */ new Map();
38167
- const dynamicSlotCandidateElements = [];
38168
- const scrollContainerElements = [];
38169
- const positionedAncestorByKey = /* @__PURE__ */ new Map();
38024
+ function buildFileElementIndexByFile(elements) {
38025
+ const byFileDispatch = /* @__PURE__ */ new Map();
38026
+ const byFileTag = /* @__PURE__ */ new Map();
38170
38027
  for (let i = 0; i < elements.length; i++) {
38171
38028
  const node = elements[i];
38172
38029
  if (!node) continue;
38173
- const snapshot = snapshotByElementNode.get(node);
38174
- if (node.textualContent === 2 /* Unknown */ && node.siblingCount >= 2) {
38175
- dynamicSlotCandidateElements.push(node);
38176
- }
38177
- if (node.tagName) {
38178
- const existing = elementsByTagName.get(node.tagName);
38030
+ if (node.parentElementNode === null) continue;
38031
+ const file = node.solidFile;
38032
+ let dispatchMap = byFileDispatch.get(file);
38033
+ if (!dispatchMap) {
38034
+ dispatchMap = /* @__PURE__ */ new Map();
38035
+ byFileDispatch.set(file, dispatchMap);
38036
+ }
38037
+ const keys = node.selectorDispatchKeys;
38038
+ for (let j = 0; j < keys.length; j++) {
38039
+ const key = keys[j];
38040
+ if (!key) continue;
38041
+ const existing = dispatchMap.get(key);
38179
38042
  if (existing) {
38180
38043
  existing.push(node);
38181
38044
  } else {
38182
- elementsByTagName.set(node.tagName, [node]);
38045
+ dispatchMap.set(key, [node]);
38183
38046
  }
38184
38047
  }
38185
- const parentKey = node.parentElementNode?.key ?? null;
38186
- let nearestPositionedAncestorKey = null;
38187
- let nearestPositionedAncestorHasReservedSpace = false;
38188
- if (parentKey !== null) {
38189
- const parentPositioned = positionedAncestorByKey.get(parentKey);
38190
- if (parentPositioned !== void 0) {
38191
- nearestPositionedAncestorKey = parentPositioned.key;
38192
- nearestPositionedAncestorHasReservedSpace = parentPositioned.hasReservedSpace;
38048
+ if (node.tagName !== null) {
38049
+ let tagMap = byFileTag.get(file);
38050
+ if (!tagMap) {
38051
+ tagMap = /* @__PURE__ */ new Map();
38052
+ byFileTag.set(file, tagMap);
38193
38053
  }
38194
- }
38195
- containingBlockFactsByNode.set(node, {
38196
- nearestPositionedAncestorKey,
38197
- nearestPositionedAncestorHasReservedSpace
38198
- });
38199
- if (!snapshot) continue;
38200
- const reservedSpaceFact = computeReservedSpaceFact(snapshot);
38201
- reservedSpaceFactsByNode.set(node, reservedSpaceFact);
38202
- const scrollFact = computeScrollContainerFact(snapshot);
38203
- scrollContainerFactsByNode.set(node, scrollFact);
38204
- if (scrollFact.isScrollContainer) scrollContainerElements.push(node);
38205
- flowParticipationFactsByNode.set(node, computeFlowParticipationFact(snapshot));
38206
- snapshotHotSignalsByNode.set(node, computeHotSignals(snapshot));
38207
- const positionSignal = snapshot.signals.get("position");
38208
- const isPositioned = positionSignal !== void 0 && positionSignal.kind === "known" && positionSignal.normalized !== "static";
38209
- if (isPositioned) {
38210
- positionedAncestorByKey.set(node.key, {
38211
- key: node.key,
38212
- hasReservedSpace: reservedSpaceFact.hasReservedSpace
38213
- });
38214
- } else if (parentKey !== null) {
38215
- const inherited = positionedAncestorByKey.get(parentKey);
38216
- if (inherited !== void 0) {
38217
- positionedAncestorByKey.set(node.key, inherited);
38218
- }
38219
- }
38220
- for (const [signal, value2] of snapshot.signals) {
38221
- if (value2.kind !== "known") continue;
38222
- const normalized = value2.normalized;
38223
- let byValue = elementsByKnownSignalValue.get(signal);
38224
- if (!byValue) {
38225
- byValue = /* @__PURE__ */ new Map();
38226
- elementsByKnownSignalValue.set(signal, byValue);
38227
- }
38228
- const existingNodes = byValue.get(normalized);
38229
- if (existingNodes) {
38230
- existingNodes.push(node);
38054
+ const existing = tagMap.get(node.tagName);
38055
+ if (existing) {
38056
+ existing.push(node);
38231
38057
  } else {
38232
- byValue.set(normalized, [node]);
38058
+ tagMap.set(node.tagName, [node]);
38233
38059
  }
38234
38060
  }
38235
38061
  }
38236
- return {
38237
- reservedSpaceFactsByNode,
38238
- scrollContainerFactsByNode,
38239
- scrollContainerElements,
38240
- flowParticipationFactsByNode,
38241
- containingBlockFactsByNode,
38242
- snapshotHotSignalsByNode,
38243
- elementsByTagName,
38244
- elementsByKnownSignalValue,
38245
- dynamicSlotCandidateElements
38246
- };
38062
+ const out = /* @__PURE__ */ new Map();
38063
+ for (const [file, dispatchMap] of byFileDispatch) {
38064
+ out.set(file, {
38065
+ byDispatchKey: dispatchMap,
38066
+ byTagName: byFileTag.get(file) ?? /* @__PURE__ */ new Map()
38067
+ });
38068
+ }
38069
+ return out;
38247
38070
  }
38248
38071
  var ABSENT_NUMERIC = Object.freeze({
38249
38072
  present: false,
@@ -38256,7 +38079,7 @@ var ABSENT_NORMALIZED = Object.freeze({
38256
38079
  kind: 3 /* Unknown */
38257
38080
  });
38258
38081
  function toHotNumeric(signal) {
38259
- if (signal.kind !== "known") {
38082
+ if (signal.kind !== 0 /* Known */) {
38260
38083
  return {
38261
38084
  present: true,
38262
38085
  value: null,
@@ -38266,11 +38089,11 @@ function toHotNumeric(signal) {
38266
38089
  return {
38267
38090
  present: true,
38268
38091
  value: signal.px,
38269
- kind: signal.guard.kind === 1 /* Conditional */ ? 2 /* Conditional */ : signal.quality === "estimated" ? 1 /* Interval */ : 0 /* Exact */
38092
+ kind: signal.guard.kind === 1 /* Conditional */ ? 2 /* Conditional */ : signal.quality === 1 /* Estimated */ ? 1 /* Interval */ : 0 /* Exact */
38270
38093
  };
38271
38094
  }
38272
38095
  function toHotNormalized(signal) {
38273
- if (signal.kind !== "known") {
38096
+ if (signal.kind !== 0 /* Known */) {
38274
38097
  return {
38275
38098
  present: true,
38276
38099
  value: null,
@@ -38280,7 +38103,7 @@ function toHotNormalized(signal) {
38280
38103
  return {
38281
38104
  present: true,
38282
38105
  value: signal.normalized,
38283
- kind: signal.guard.kind === 1 /* Conditional */ ? 2 /* Conditional */ : signal.quality === "estimated" ? 1 /* Interval */ : 0 /* Exact */
38106
+ kind: signal.guard.kind === 1 /* Conditional */ ? 2 /* Conditional */ : signal.quality === 1 /* Estimated */ ? 1 /* Interval */ : 0 /* Exact */
38284
38107
  };
38285
38108
  }
38286
38109
  function computeHotSignals(snapshot) {
@@ -38395,62 +38218,61 @@ function computeHotSignals(snapshot) {
38395
38218
  }
38396
38219
  function computeReservedSpaceFact(snapshot) {
38397
38220
  const reasons = [];
38398
- const hasHeight = hasPositiveOrDeclaredDimension(snapshot, "height");
38221
+ const hasHeight = hasDeclaredDimension(snapshot, "height");
38399
38222
  if (hasHeight) reasons.push("height");
38400
- const hasBlockSize = hasPositiveOrDeclaredDimension(snapshot, "block-size");
38223
+ const hasBlockSize = hasDeclaredDimension(snapshot, "block-size");
38401
38224
  if (hasBlockSize) reasons.push("block-size");
38402
- const hasMinHeight = hasPositiveOrDeclaredDimension(snapshot, "min-height");
38225
+ const hasMinHeight = hasDeclaredDimension(snapshot, "min-height");
38403
38226
  if (hasMinHeight) reasons.push("min-height");
38404
- const hasMinBlockSize = hasPositiveOrDeclaredDimension(snapshot, "min-block-size");
38227
+ const hasMinBlockSize = hasDeclaredDimension(snapshot, "min-block-size");
38405
38228
  if (hasMinBlockSize) reasons.push("min-block-size");
38406
- const hasContainIntrinsic = hasPositiveOrDeclaredDimension(snapshot, "contain-intrinsic-size");
38229
+ const hasContainIntrinsic = hasDeclaredDimension(snapshot, "contain-intrinsic-size");
38407
38230
  if (hasContainIntrinsic) reasons.push("contain-intrinsic-size");
38408
38231
  const hasAspectRatio = hasUsableAspectRatio(snapshot);
38409
38232
  if (hasAspectRatio) {
38410
- if (hasPositiveOrDeclaredDimension(snapshot, "width")) reasons.push("aspect-ratio+width");
38411
- if (hasPositiveOrDeclaredDimension(snapshot, "inline-size")) reasons.push("aspect-ratio+inline-size");
38412
- if (hasPositiveOrDeclaredDimension(snapshot, "min-width")) reasons.push("aspect-ratio+min-width");
38233
+ if (hasDeclaredDimension(snapshot, "width")) reasons.push("aspect-ratio+width");
38234
+ if (hasDeclaredDimension(snapshot, "inline-size")) reasons.push("aspect-ratio+inline-size");
38235
+ if (hasDeclaredDimension(snapshot, "min-width")) reasons.push("aspect-ratio+min-width");
38413
38236
  if (hasMinBlockSize) reasons.push("aspect-ratio+min-block-size");
38414
38237
  if (hasMinHeight) reasons.push("aspect-ratio+min-height");
38415
38238
  }
38416
38239
  return {
38417
38240
  hasReservedSpace: reasons.length > 0,
38418
38241
  reasons,
38419
- hasUsableInlineDimension: hasPositiveOrDeclaredDimension(snapshot, "width") || hasPositiveOrDeclaredDimension(snapshot, "inline-size") || hasPositiveOrDeclaredDimension(snapshot, "min-width"),
38420
- hasUsableBlockDimension: hasHeight || hasBlockSize || hasMinHeight || hasMinBlockSize,
38421
38242
  hasContainIntrinsicSize: hasContainIntrinsic,
38422
- hasUsableAspectRatio: hasAspectRatio
38243
+ hasUsableAspectRatio: hasAspectRatio,
38244
+ hasDeclaredBlockDimension: hasHeight || hasBlockSize || hasMinHeight || hasMinBlockSize,
38245
+ hasDeclaredInlineDimension: hasDeclaredDimension(snapshot, "width") || hasDeclaredDimension(snapshot, "inline-size") || hasDeclaredDimension(snapshot, "min-width") || hasDeclaredDimension(snapshot, "flex-basis") || isBlockLevelDisplay(snapshot)
38423
38246
  };
38424
38247
  }
38425
- function hasPositiveOrDeclaredDimension(snapshot, property) {
38248
+ function hasDeclaredDimension(snapshot, property) {
38426
38249
  const signal = snapshot.signals.get(property);
38427
38250
  if (!signal) return false;
38428
- if (signal.guard.kind !== 0 /* Unconditional */) return false;
38429
- let normalized = "";
38430
- if (signal.kind === "known") {
38251
+ if (signal.kind === 0 /* Known */) {
38431
38252
  if (signal.px !== null) return signal.px > 0;
38432
- normalized = signal.normalized.trim().toLowerCase();
38253
+ if (signal.normalized.length === 0) return false;
38254
+ return !isNonReservingDimension(signal.normalized);
38433
38255
  }
38434
- if (signal.kind === "unknown") {
38256
+ if (signal.kind === 1 /* Unknown */) {
38435
38257
  return signal.source !== null;
38436
38258
  }
38437
- if (normalized.length === 0) return false;
38438
- if (isNonReservingDimension(normalized)) return false;
38439
- return true;
38259
+ return false;
38260
+ }
38261
+ function isBlockLevelDisplay(snapshot) {
38262
+ const signal = snapshot.signals.get("display");
38263
+ if (!signal || signal.kind !== 0 /* Known */) return false;
38264
+ return BLOCK_LEVEL_DISPLAY_VALUES.has(signal.normalized);
38440
38265
  }
38441
38266
  function hasUsableAspectRatio(snapshot) {
38442
38267
  const signal = snapshot.signals.get("aspect-ratio");
38443
38268
  if (!signal) return false;
38444
38269
  if (signal.guard.kind !== 0 /* Unconditional */) return false;
38445
- if (signal.kind === "unknown") {
38270
+ if (signal.kind === 1 /* Unknown */) {
38446
38271
  return false;
38447
38272
  }
38448
- let normalized = "";
38449
- if (signal.kind === "known") {
38450
- normalized = signal.normalized.trim().toLowerCase();
38451
- }
38452
- if (normalized.length === 0) return false;
38453
- return normalized !== "auto";
38273
+ if (signal.kind !== 0 /* Known */) return false;
38274
+ if (signal.normalized.length === 0) return false;
38275
+ return signal.normalized !== "auto";
38454
38276
  }
38455
38277
  function isNonReservingDimension(value2) {
38456
38278
  if (NON_RESERVING_DIMENSION_KEYWORDS.has(value2)) return true;
@@ -38460,8 +38282,8 @@ function isNonReservingDimension(value2) {
38460
38282
  function computeScrollContainerFact(snapshot) {
38461
38283
  const overflowSignal = snapshot.signals.get("overflow");
38462
38284
  const overflowYSignal = snapshot.signals.get("overflow-y");
38463
- const overflow = overflowSignal && overflowSignal.kind === "known" ? overflowSignal.normalized : null;
38464
- const overflowY = overflowYSignal && overflowYSignal.kind === "known" ? overflowYSignal.normalized : null;
38285
+ const overflow = overflowSignal && overflowSignal.kind === 0 /* Known */ ? overflowSignal.normalized : null;
38286
+ const overflowY = overflowYSignal && overflowYSignal.kind === 0 /* Known */ ? overflowYSignal.normalized : null;
38465
38287
  const shorthandAxis = parseOverflowShorthandAxis(overflow);
38466
38288
  const yFromLonghand = parseSingleAxisScroll(overflowY);
38467
38289
  const xScroll = shorthandAxis.x;
@@ -38509,7 +38331,7 @@ function toScrollAxis(x, y) {
38509
38331
  }
38510
38332
  function computeFlowParticipationFact(snapshot) {
38511
38333
  const signal = snapshot.signals.get("position");
38512
- if (!signal || signal.kind !== "known") {
38334
+ if (!signal || signal.kind !== 0 /* Known */) {
38513
38335
  return {
38514
38336
  inFlow: true,
38515
38337
  position: null,
@@ -38541,8 +38363,8 @@ function buildContextIndex(childrenByParentNode, snapshotByElementNode, perf, lo
38541
38363
  if (trace) {
38542
38364
  const displaySignal = snapshot.signals.get("display");
38543
38365
  const flexDirSignal = snapshot.signals.get("flex-direction");
38544
- const displayDesc = displaySignal ? `${displaySignal.kind}:${displaySignal.kind === "known" ? displaySignal.normalized : "?"}(guard=${displaySignal.guard.kind === 1 /* Conditional */ ? "conditional" : "unconditional"})` : "absent";
38545
- const flexDirDesc = flexDirSignal ? `${flexDirSignal.kind}:${flexDirSignal.kind === "known" ? flexDirSignal.normalized : "?"}(guard=${flexDirSignal.guard.kind === 1 /* Conditional */ ? "conditional" : "unconditional"})` : "absent";
38366
+ const displayDesc = displaySignal ? `${displaySignal.kind}:${displaySignal.kind === 0 /* Known */ ? displaySignal.normalized : "?"}(guard=${displaySignal.guard.kind === 1 /* Conditional */ ? "conditional" : "unconditional"})` : "absent";
38367
+ const flexDirDesc = flexDirSignal ? `${flexDirSignal.kind}:${flexDirSignal.kind === 0 /* Known */ ? flexDirSignal.normalized : "?"}(guard=${flexDirSignal.guard.kind === 1 /* Conditional */ ? "conditional" : "unconditional"})` : "absent";
38546
38368
  logger.trace(
38547
38369
  `[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}`
38548
38370
  );
@@ -40609,8 +40431,8 @@ function hasReservedSize(solid, attributes, element, reservedSpaceFact, hostElem
40609
40431
  const hostJsxWidth = hostElementRef !== null ? readPositiveJsxAttribute(hostElementRef.solid, hostElementRef.element, "width") : false;
40610
40432
  const hostJsxHeight = hostElementRef !== null ? readPositiveJsxAttribute(hostElementRef.solid, hostElementRef.element, "height") : false;
40611
40433
  if (attrWidth && attrHeight || jsxAttrWidth && jsxAttrHeight || hostJsxWidth && hostJsxHeight) return true;
40612
- const hasAnyWidth = attrWidth || jsxAttrWidth || hostJsxWidth || reservedSpaceFact.hasUsableInlineDimension;
40613
- const hasAnyHeight = attrHeight || jsxAttrHeight || hostJsxHeight || reservedSpaceFact.hasUsableBlockDimension || reservedSpaceFact.hasContainIntrinsicSize;
40434
+ const hasAnyWidth = attrWidth || jsxAttrWidth || hostJsxWidth || reservedSpaceFact.hasDeclaredInlineDimension;
40435
+ const hasAnyHeight = attrHeight || jsxAttrHeight || hostJsxHeight || reservedSpaceFact.hasDeclaredBlockDimension || reservedSpaceFact.hasContainIntrinsicSize;
40614
40436
  if (reservedSpaceFact.hasUsableAspectRatio && (hasAnyWidth || hasAnyHeight)) return true;
40615
40437
  if (reservedSpaceFact.hasContainIntrinsicSize && (hasAnyWidth || hasAnyHeight)) return true;
40616
40438
  return false;
@@ -41087,7 +40909,7 @@ function collectConditionalOffsets(layout, node, snapshot) {
41087
40909
  const signal = snapshot.signals.get(name);
41088
40910
  if (!signal) continue;
41089
40911
  if (signal.guard.kind !== 1 /* Conditional */) continue;
41090
- if (signal.kind !== "known") continue;
40912
+ if (signal.kind !== 0 /* Known */) continue;
41091
40913
  if (signal.px === null) continue;
41092
40914
  if (Math.abs(signal.px) <= 0.25) continue;
41093
40915
  out.push({ property: name, value: signal.px, guardKey: signal.guard.key });
@@ -41110,7 +40932,7 @@ function hasEffectivePositionForConditionalOffset(snapshot, guardKey) {
41110
40932
  if (hasEffectivePosition(snapshot)) return true;
41111
40933
  const position = snapshot.signals.get("position");
41112
40934
  if (!position) return false;
41113
- if (position.kind !== "known") return false;
40935
+ if (position.kind !== 0 /* Known */) return false;
41114
40936
  if (position.guard.kind !== 1 /* Conditional */) return false;
41115
40937
  if (position.guard.key !== guardKey) return false;
41116
40938
  return position.normalized !== "static";
@@ -41570,6 +41392,9 @@ function isVisuallyHidden(snapshot) {
41570
41392
  const opacityAttr = node.inlineStyleValues.get("opacity");
41571
41393
  if (opacityAttr === "0") return true;
41572
41394
  if (node.classTokenSet.has("opacity-0")) return true;
41395
+ const width = readKnownPx(snapshot, "width");
41396
+ const height = readKnownPx(snapshot, "height");
41397
+ if (width === 1 && height === 1) return true;
41573
41398
  return false;
41574
41399
  }
41575
41400
  var jsxLayoutPolicyTouchTarget = defineCrossRule({
@@ -41621,6 +41446,18 @@ var jsxLayoutPolicyTouchTarget = defineCrossRule({
41621
41446
  tag,
41622
41447
  policyName
41623
41448
  );
41449
+ checkDimension(
41450
+ snapshot,
41451
+ "max-height",
41452
+ kind === "button" ? policy.minButtonHeight : policy.minInputHeight,
41453
+ layout,
41454
+ node,
41455
+ emit,
41456
+ "heightTooSmall",
41457
+ messages161.heightTooSmall,
41458
+ tag,
41459
+ policyName
41460
+ );
41624
41461
  checkDimension(
41625
41462
  snapshot,
41626
41463
  "width",
@@ -41645,6 +41482,18 @@ var jsxLayoutPolicyTouchTarget = defineCrossRule({
41645
41482
  tag,
41646
41483
  policyName
41647
41484
  );
41485
+ checkDimension(
41486
+ snapshot,
41487
+ "max-width",
41488
+ kind === "button" ? policy.minButtonWidth : policy.minTouchTarget,
41489
+ layout,
41490
+ node,
41491
+ emit,
41492
+ "widthTooSmall",
41493
+ messages161.widthTooSmall,
41494
+ tag,
41495
+ policyName
41496
+ );
41648
41497
  if (kind === "button") {
41649
41498
  checkDimension(
41650
41499
  snapshot,
@@ -41674,7 +41523,7 @@ var jsxLayoutPolicyTouchTarget = defineCrossRule({
41674
41523
  const reservedSpace = readReservedSpaceFact(layout, node);
41675
41524
  const minBlock = kind === "button" ? policy.minButtonHeight : policy.minInputHeight;
41676
41525
  const minInline = kind === "button" ? policy.minButtonWidth : policy.minTouchTarget;
41677
- if (!reservedSpace.hasUsableBlockDimension) {
41526
+ if (!reservedSpace.hasDeclaredBlockDimension) {
41678
41527
  emitLayoutDiagnostic(
41679
41528
  layout,
41680
41529
  node,
@@ -41686,7 +41535,7 @@ var jsxLayoutPolicyTouchTarget = defineCrossRule({
41686
41535
  { tag, min: String(minBlock), policy: policyName }
41687
41536
  );
41688
41537
  }
41689
- if (!reservedSpace.hasUsableInlineDimension) {
41538
+ if (!reservedSpace.hasDeclaredInlineDimension) {
41690
41539
  emitLayoutDiagnostic(
41691
41540
  layout,
41692
41541
  node,