hyperframes 0.8.30 → 0.8.31

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.
@@ -3433,10 +3433,10 @@ function compareDocumentPosition(nodeA, nodeB) {
3433
3433
  function uniqueSort(nodes) {
3434
3434
  nodes = nodes.filter((node, i, arr) => !arr.includes(node, i + 1));
3435
3435
  nodes.sort((a, b) => {
3436
- const relative8 = compareDocumentPosition(a, b);
3437
- if (relative8 & DocumentPosition.PRECEDING) {
3436
+ const relative9 = compareDocumentPosition(a, b);
3437
+ if (relative9 & DocumentPosition.PRECEDING) {
3438
3438
  return -1;
3439
- } else if (relative8 & DocumentPosition.FOLLOWING) {
3439
+ } else if (relative9 & DocumentPosition.FOLLOWING) {
3440
3440
  return 1;
3441
3441
  }
3442
3442
  return 0;
@@ -9651,12 +9651,12 @@ var require_CSSValueExpression = __commonJS({
9651
9651
  return false;
9652
9652
  }
9653
9653
  };
9654
- CSSOM.CSSValueExpression.prototype._parseJSString = function(token, idx, sep6) {
9655
- var endIdx = this._findMatchedIdx(token, idx, sep6), text;
9654
+ CSSOM.CSSValueExpression.prototype._parseJSString = function(token, idx, sep7) {
9655
+ var endIdx = this._findMatchedIdx(token, idx, sep7), text;
9656
9656
  if (endIdx === -1) {
9657
9657
  return false;
9658
9658
  } else {
9659
- text = token.substring(idx, endIdx + sep6.length);
9659
+ text = token.substring(idx, endIdx + sep7.length);
9660
9660
  return {
9661
9661
  idx: endIdx,
9662
9662
  text
@@ -9696,15 +9696,15 @@ var require_CSSValueExpression = __commonJS({
9696
9696
  if (!isLegal) {
9697
9697
  return false;
9698
9698
  } else {
9699
- var sep6 = "/";
9700
- return this._parseJSString(token, idx, sep6);
9699
+ var sep7 = "/";
9700
+ return this._parseJSString(token, idx, sep7);
9701
9701
  }
9702
9702
  };
9703
- CSSOM.CSSValueExpression.prototype._findMatchedIdx = function(token, idx, sep6) {
9703
+ CSSOM.CSSValueExpression.prototype._findMatchedIdx = function(token, idx, sep7) {
9704
9704
  var startIdx = idx, endIdx;
9705
9705
  var NOT_FOUND = -1;
9706
9706
  while (true) {
9707
- endIdx = token.indexOf(sep6, startIdx + 1);
9707
+ endIdx = token.indexOf(sep7, startIdx + 1);
9708
9708
  if (endIdx === -1) {
9709
9709
  endIdx = NOT_FOUND;
9710
9710
  break;
@@ -16993,7 +16993,7 @@ var require_util = __commonJS({
16993
16993
  }
16994
16994
  path = url.path;
16995
16995
  }
16996
- var isAbsolute5 = exports.isAbsolute(path);
16996
+ var isAbsolute6 = exports.isAbsolute(path);
16997
16997
  var parts = path.split(/\/+/);
16998
16998
  for (var part, up = 0, i = parts.length - 1; i >= 0; i--) {
16999
16999
  part = parts[i];
@@ -17013,7 +17013,7 @@ var require_util = __commonJS({
17013
17013
  }
17014
17014
  path = parts.join("/");
17015
17015
  if (path === "") {
17016
- path = isAbsolute5 ? "/" : ".";
17016
+ path = isAbsolute6 ? "/" : ".";
17017
17017
  }
17018
17018
  if (url) {
17019
17019
  url.path = path;
@@ -17058,7 +17058,7 @@ var require_util = __commonJS({
17058
17058
  exports.isAbsolute = function(aPath) {
17059
17059
  return aPath.charAt(0) === "/" || urlRegexp.test(aPath);
17060
17060
  };
17061
- function relative8(aRoot, aPath) {
17061
+ function relative9(aRoot, aPath) {
17062
17062
  if (aRoot === "") {
17063
17063
  aRoot = ".";
17064
17064
  }
@@ -17077,7 +17077,7 @@ var require_util = __commonJS({
17077
17077
  }
17078
17078
  return Array(level + 1).join("../") + aPath.substr(aRoot.length + 1);
17079
17079
  }
17080
- exports.relative = relative8;
17080
+ exports.relative = relative9;
17081
17081
  var supportsNullProto = (function() {
17082
17082
  var obj = /* @__PURE__ */ Object.create(null);
17083
17083
  return !("__proto__" in obj);
@@ -27953,9 +27953,9 @@ var require_printer = __commonJS({
27953
27953
  }
27954
27954
  case "ForStatement": {
27955
27955
  var init = path.call(print, "init");
27956
- var sep6 = init.length > 1 ? ";\n" : "; ";
27956
+ var sep7 = init.length > 1 ? ";\n" : "; ";
27957
27957
  var forParen = "for (";
27958
- var indented = (0, lines_1.fromString)(sep6).join([init, path.call(print, "test"), path.call(print, "update")]).indentTail(forParen.length);
27958
+ var indented = (0, lines_1.fromString)(sep7).join([init, path.call(print, "test"), path.call(print, "update")]).indentTail(forParen.length);
27959
27959
  var head = (0, lines_1.concat)([forParen, indented, ")"]);
27960
27960
  var clause = adjustClause(path.call(print, "body"), options);
27961
27961
  parts.push(head);
@@ -69673,57 +69673,264 @@ function stripStringLiterals(source) {
69673
69673
  (literal2) => literal2[0] + " ".repeat(Math.max(0, literal2.length - 1))
69674
69674
  );
69675
69675
  }
69676
- function stripJsComments(source) {
69676
+ function scanJsComments(source) {
69677
69677
  let out = "";
69678
69678
  let i = 0;
69679
69679
  let quote = null;
69680
69680
  let escaped = false;
69681
+ let inRegex = false;
69682
+ let inRegexClass = false;
69683
+ let regexMisread = false;
69684
+ const ctx = new CodeContext();
69685
+ const emitCode = (ch) => {
69686
+ out += ch;
69687
+ ctx.push(ch);
69688
+ };
69689
+ const emitOpaque = (ch) => {
69690
+ out += ch;
69691
+ ctx.push(" ");
69692
+ };
69681
69693
  while (i < source.length) {
69682
69694
  const ch = source[i] ?? "";
69683
69695
  const next = source[i + 1] ?? "";
69684
- if (quote) {
69696
+ if (inRegex) {
69685
69697
  out += ch;
69686
69698
  if (escaped) {
69687
69699
  escaped = false;
69700
+ if (ch === "\n" || ch === "\r") {
69701
+ inRegex = false;
69702
+ inRegexClass = false;
69703
+ regexMisread = true;
69704
+ }
69705
+ } else if (ch === "\\") {
69706
+ escaped = true;
69707
+ } else if (ch === "[") {
69708
+ inRegexClass = true;
69709
+ } else if (ch === "]") {
69710
+ inRegexClass = false;
69711
+ } else if (ch === "/" && !inRegexClass) {
69712
+ inRegex = false;
69713
+ ctx.push(ch);
69714
+ } else if (ch === "\n" || ch === "\r") {
69715
+ inRegex = false;
69716
+ inRegexClass = false;
69717
+ regexMisread = true;
69718
+ }
69719
+ i += 1;
69720
+ continue;
69721
+ }
69722
+ if (quote) {
69723
+ if (escaped) {
69724
+ escaped = false;
69725
+ emitOpaque(ch);
69688
69726
  } else if (ch === "\\") {
69689
69727
  escaped = true;
69728
+ emitOpaque(ch);
69690
69729
  } else if (ch === quote) {
69691
69730
  quote = null;
69731
+ emitCode(ch);
69732
+ } else {
69733
+ emitOpaque(ch);
69692
69734
  }
69693
69735
  i += 1;
69694
69736
  continue;
69695
69737
  }
69696
69738
  if (ch === "'" || ch === '"' || ch === "`") {
69697
69739
  quote = ch;
69698
- out += ch;
69740
+ emitCode(ch);
69699
69741
  i += 1;
69700
69742
  continue;
69701
69743
  }
69702
69744
  if (ch === "/" && next === "/") {
69703
69745
  out += " ";
69746
+ ctx.push(" ");
69747
+ ctx.push(" ");
69704
69748
  i += 2;
69705
69749
  while (i < source.length && source[i] !== "\n" && source[i] !== "\r") {
69706
69750
  out += " ";
69751
+ ctx.push(" ");
69707
69752
  i += 1;
69708
69753
  }
69709
69754
  continue;
69710
69755
  }
69711
69756
  if (ch === "/" && next === "*") {
69712
69757
  out += " ";
69758
+ ctx.push(" ");
69759
+ ctx.push(" ");
69713
69760
  i += 2;
69714
69761
  while (i < source.length) {
69715
69762
  const blockCh = source[i] ?? "";
69716
69763
  const blockNext = source[i + 1] ?? "";
69717
69764
  if (blockCh === "*" && blockNext === "/") {
69718
69765
  out += " ";
69766
+ ctx.push(" ");
69767
+ ctx.push(" ");
69719
69768
  i += 2;
69720
69769
  break;
69721
69770
  }
69722
- out += blockCh === "\n" || blockCh === "\r" ? blockCh : " ";
69771
+ const kept = blockCh === "\n" || blockCh === "\r" ? blockCh : " ";
69772
+ out += kept;
69773
+ ctx.push(kept);
69723
69774
  i += 1;
69724
69775
  }
69725
69776
  continue;
69726
69777
  }
69778
+ if (ch === "/" && ctx.startsRegexLiteral()) {
69779
+ inRegex = true;
69780
+ emitCode(ch);
69781
+ i += 1;
69782
+ continue;
69783
+ }
69784
+ emitCode(ch);
69785
+ i += 1;
69786
+ }
69787
+ return { out, balanced: quote === null && !inRegex && !regexMisread };
69788
+ }
69789
+ function stripJsComments(source) {
69790
+ return scanJsComments(source).out;
69791
+ }
69792
+ function stripJsCode(source) {
69793
+ const { out, balanced } = scanJsComments(source);
69794
+ return balanced ? stripJsStringLiterals(out) : source;
69795
+ }
69796
+ function stripJsStringLiterals(source) {
69797
+ let out = "";
69798
+ let i = 0;
69799
+ const templateBraces = [];
69800
+ const ctx = new CodeContext();
69801
+ let quote = null;
69802
+ let escaped = false;
69803
+ let inRegex = false;
69804
+ let inRegexClass = false;
69805
+ let regexMisread = false;
69806
+ const blank = (ch) => ch === "\n" || ch === "\r" ? ch : " ";
69807
+ const emit = (text) => {
69808
+ out += text;
69809
+ for (const ch of text) ctx.push(ch);
69810
+ };
69811
+ while (i < source.length) {
69812
+ const ch = source[i] ?? "";
69813
+ const next = source[i + 1] ?? "";
69814
+ if (inRegex) {
69815
+ if (escaped) {
69816
+ escaped = false;
69817
+ if (ch === "\n" || ch === "\r") {
69818
+ inRegex = false;
69819
+ inRegexClass = false;
69820
+ regexMisread = true;
69821
+ }
69822
+ emit(blank(ch));
69823
+ } else if (ch === "\\") {
69824
+ escaped = true;
69825
+ emit(" ");
69826
+ } else if (ch === "[") {
69827
+ inRegexClass = true;
69828
+ emit(" ");
69829
+ } else if (ch === "]") {
69830
+ inRegexClass = false;
69831
+ emit(" ");
69832
+ } else if (ch === "/" && !inRegexClass) {
69833
+ inRegex = false;
69834
+ emit(ch);
69835
+ } else if (ch === "\n" || ch === "\r") {
69836
+ inRegex = false;
69837
+ inRegexClass = false;
69838
+ escaped = false;
69839
+ regexMisread = true;
69840
+ emit(ch);
69841
+ } else {
69842
+ emit(" ");
69843
+ }
69844
+ i += 1;
69845
+ continue;
69846
+ }
69847
+ if (quote) {
69848
+ if (escaped) {
69849
+ escaped = false;
69850
+ emit(blank(ch));
69851
+ } else if (ch === "\\") {
69852
+ escaped = true;
69853
+ emit(" ");
69854
+ } else if (ch === quote) {
69855
+ quote = null;
69856
+ emit(ch);
69857
+ } else if (ch === "`" || quote !== "`" || ch !== "$" || next !== "{") {
69858
+ emit(blank(ch));
69859
+ } else {
69860
+ templateBraces.push(0);
69861
+ quote = null;
69862
+ emit("${");
69863
+ i += 2;
69864
+ continue;
69865
+ }
69866
+ i += 1;
69867
+ continue;
69868
+ }
69869
+ if (ch === "'" || ch === '"' || ch === "`") {
69870
+ quote = ch;
69871
+ emit(ch);
69872
+ i += 1;
69873
+ continue;
69874
+ }
69875
+ if (ch === "/" && next !== "/" && next !== "*" && ctx.startsRegexLiteral()) {
69876
+ inRegex = true;
69877
+ emit(ch);
69878
+ i += 1;
69879
+ continue;
69880
+ }
69881
+ if (templateBraces.length > 0) {
69882
+ const depth = templateBraces[templateBraces.length - 1] ?? 0;
69883
+ if (ch === "{") templateBraces[templateBraces.length - 1] = depth + 1;
69884
+ else if (ch === "}") {
69885
+ if (depth === 0) {
69886
+ templateBraces.pop();
69887
+ quote = "`";
69888
+ emit(ch);
69889
+ i += 1;
69890
+ continue;
69891
+ }
69892
+ templateBraces[templateBraces.length - 1] = depth - 1;
69893
+ }
69894
+ }
69895
+ emit(ch);
69896
+ i += 1;
69897
+ }
69898
+ if (quote !== null || templateBraces.length > 0 || inRegex || regexMisread) return source;
69899
+ return out;
69900
+ }
69901
+ function stripCssComments(source) {
69902
+ let out = "";
69903
+ let i = 0;
69904
+ let quote = null;
69905
+ while (i < source.length) {
69906
+ const ch = source[i] ?? "";
69907
+ if (quote) {
69908
+ out += ch;
69909
+ if (ch === "\\") {
69910
+ out += source[i + 1] ?? "";
69911
+ i += 2;
69912
+ continue;
69913
+ }
69914
+ if (ch === quote) quote = null;
69915
+ i += 1;
69916
+ continue;
69917
+ }
69918
+ if (ch === '"' || ch === "'") {
69919
+ quote = ch;
69920
+ out += ch;
69921
+ i += 1;
69922
+ continue;
69923
+ }
69924
+ if (ch === "/" && source[i + 1] === "*") {
69925
+ const end = source.indexOf("*/", i + 2);
69926
+ const stop = end === -1 ? source.length : end + 2;
69927
+ for (let j = i; j < stop; j += 1) {
69928
+ const c = source[j] ?? "";
69929
+ out += c === "\n" || c === "\r" ? c : " ";
69930
+ }
69931
+ i = stop;
69932
+ continue;
69933
+ }
69727
69934
  out += ch;
69728
69935
  i += 1;
69729
69936
  }
@@ -69975,6 +70182,7 @@ function srcKind(src) {
69975
70182
  if (!mime) return null;
69976
70183
  if (mime.startsWith("image/")) return "image";
69977
70184
  if (mime.startsWith("video/")) return "video";
70185
+ if (mime.startsWith("audio/")) return "audio";
69978
70186
  return null;
69979
70187
  }
69980
70188
  if (lower.startsWith("blob:")) return null;
@@ -69994,6 +70202,7 @@ function srcKind(src) {
69994
70202
  const ext = base2.slice(dot + 1).toLowerCase();
69995
70203
  if (IMAGE_SRC_EXT.has(ext)) return "image";
69996
70204
  if (VIDEO_SRC_EXT.has(ext)) return "video";
70205
+ if (AUDIO_SRC_EXT.has(ext)) return "audio";
69997
70206
  return null;
69998
70207
  }
69999
70208
  function findMediaSrcKindMismatchFindings(ctx) {
@@ -70004,16 +70213,15 @@ function findMediaSrcKindMismatchFindings(ctx) {
70004
70213
  if (!src) continue;
70005
70214
  const kind = srcKind(src);
70006
70215
  if (kind === null) continue;
70007
- if (tag.name === "video" && kind !== "image") continue;
70008
- if (tag.name === "img" && kind !== "video") continue;
70009
- const elementId = readAttr(tag.raw, "id") || void 0;
70010
70216
  const expected = tag.name === "video" ? "video" : "image";
70217
+ if (kind === expected) continue;
70218
+ const elementId = readAttr(tag.raw, "id") || void 0;
70011
70219
  findings.push({
70012
70220
  code: "media_src_kind_mismatch",
70013
70221
  severity: "error",
70014
- message: `<${tag.name}${elementId ? ` id="${elementId}"` : ""}> src is a ${kind}, not a ${expected}. The producer fail-closes when the tag and file kind disagree.`,
70222
+ message: `<${tag.name}${elementId ? ` id="${elementId}"` : ""}> src is ${SRC_KIND_NOUN[kind]}, not ${SRC_KIND_NOUN[expected]}. The producer fail-closes when the tag and file kind disagree.`,
70015
70223
  elementId,
70016
- fixHint: tag.name === "video" ? "Use <img> for a still, or point <video> at a video URL (mp4/webm/mov/\u2026)." : "Use <video> for a video URL, or point <img> at a still (png/jpg/webp/\u2026).",
70224
+ fixHint: tag.name === "video" ? "Use <img> for a still, <audio> for sound, or point <video> at a video URL (mp4/webm/mov/\u2026)." : "Use <video> for a video URL, <audio> for sound, or point <img> at a still (png/jpg/webp/\u2026).",
70017
70225
  snippet: truncateSnippet(tag.raw)
70018
70226
  });
70019
70227
  }
@@ -70409,6 +70617,14 @@ function isHiddenGsapState(values) {
70409
70617
  const display = stringValue(values.display)?.toLowerCase();
70410
70618
  return zeroValue(values.opacity) || zeroValue(values.autoAlpha) || visibility === "hidden" || display === "none";
70411
70619
  }
70620
+ function hiddenSetTargetSelectors(target, aliases2) {
70621
+ const parts = target.startsWith("[") && target.endsWith("]") ? target.slice(1, -1).split(",") : [target];
70622
+ return parts.flatMap((part) => {
70623
+ const trimmed = part.trim();
70624
+ const resolved = /^(["'`])([^"'`]+)\1$/.exec(trimmed)?.[2] ?? aliases2.get(trimmed);
70625
+ return resolved === void 0 ? [] : resolved.split(",");
70626
+ }).map((selector) => selector.trim()).filter((selector) => selector.length > 0);
70627
+ }
70412
70628
  function extractStandaloneHiddenSelectors(script) {
70413
70629
  const selectors = /* @__PURE__ */ new Set();
70414
70630
  const source = stripJsComments(script);
@@ -70419,16 +70635,15 @@ function extractStandaloneHiddenSelectors(script) {
70419
70635
  )) {
70420
70636
  aliases2.set(match2[1] ?? "", match2[3] ?? "");
70421
70637
  }
70422
- const pattern = /gsap\.set\s*\(\s*([^,]+?)\s*,\s*\{([\s\S]*?)\}\s*\)/g;
70638
+ const pattern = /gsap\.set\s*\(\s*(\[[^[\]]*\]|"[^"]*"|'[^']*'|`[^`]*`|[^,()[\]]+?)\s*,\s*\{([\s\S]*?)\}\s*\)/g;
70423
70639
  let match;
70424
70640
  while ((match = pattern.exec(source)) !== null) {
70425
70641
  if (indexInsideNonIifeRange(match.index, source, functionRanges)) continue;
70426
- const target = (match[1] ?? "").trim();
70427
- const selector = /^(["'`])([^"'`]+)\1$/.exec(target)?.[2] ?? aliases2.get(target);
70428
- if (!selector) continue;
70642
+ const targets = hiddenSetTargetSelectors((match[1] ?? "").trim(), aliases2);
70643
+ if (targets.length === 0) continue;
70429
70644
  const body = match[2] ?? "";
70430
70645
  if (/(?:opacity|autoAlpha)\s*:\s*0(?:\.0+)?\s*(?:,|$)/.test(body)) {
70431
- selectors.add(selector);
70646
+ for (const selector of targets) selectors.add(selector);
70432
70647
  }
70433
70648
  }
70434
70649
  return selectors;
@@ -71216,7 +71431,7 @@ function collectTextureCss(styles) {
71216
71431
  }
71217
71432
  return { definedTextureClasses, dropShadowRules };
71218
71433
  }
71219
- function stripCssComments(css) {
71434
+ function stripCssComments2(css) {
71220
71435
  return css.replace(/\/\*[\s\S]*?\*\//g, " ");
71221
71436
  }
71222
71437
  function extractFontFaceFamilies(styles) {
@@ -71224,7 +71439,7 @@ function extractFontFaceFamilies(styles) {
71224
71439
  const fontFaceRe = /@font-face\s*\{[^}]*\}/gi;
71225
71440
  const familyRe = /font-family\s*:\s*(['"]?)([^;'"]+)\1/i;
71226
71441
  for (const style of styles) {
71227
- const content = stripCssComments(style.content);
71442
+ const content = stripCssComments2(style.content);
71228
71443
  let match;
71229
71444
  while ((match = fontFaceRe.exec(content)) !== null) {
71230
71445
  const familyMatch = match[0].match(familyRe);
@@ -71245,7 +71460,7 @@ function extractUsedFontFamilies(styles) {
71245
71460
  const seen = /* @__PURE__ */ new Set();
71246
71461
  const propRe = /font-family\s*:\s*([^;}{]+)/gi;
71247
71462
  for (const style of styles) {
71248
- const withoutFontFace = stripCssComments(style.content).replace(/@font-face\s*\{[^}]*\}/gi, "");
71463
+ const withoutFontFace = stripCssComments2(style.content).replace(/@font-face\s*\{[^}]*\}/gi, "");
71249
71464
  let match;
71250
71465
  while ((match = propRe.exec(withoutFontFace)) !== null) {
71251
71466
  for (const part of match[1].split(",")) {
@@ -71403,7 +71618,7 @@ async function lintHyperframeHtml(html, options = {}) {
71403
71618
  timings: { totalMs: performance.now() - startedAt, ...timings }
71404
71619
  };
71405
71620
  }
71406
- var import_postcss_selector_parser, COMPOSITION_ID_IN_CSS_PATTERN, TIMELINE_REGISTRY_INIT_PATTERN, TIMELINE_REGISTRY_OBJECT_LITERAL_PATTERN, TIMELINE_REGISTRY_ASSIGN_PATTERN, WINDOW_TIMELINE_ASSIGN_PATTERN, INVALID_SCRIPT_CLOSE_PATTERN, TIMELINE_REGISTRY_KEY_PATTERN, TIMELINE_REGISTRY_OBJECT_OPEN_PATTERN, TIMELINE_REGISTRY_OBJECT_ENTRY_PATTERN, VISIBLE_MARKUP_COMMENT_PATTERN, VISIBLE_MARKUP_COMMENT_PROTECTED_BLOCK_PATTERN, coreRules, IMAGE_SRC_EXT, VIDEO_SRC_EXT, mediaRules, AUDIO_GROUP_TIMING_ATTRS, SCENE_BOUNDARY_EPSILON_SECONDS, UNRESOLVED_TARGET, gsapWindowsCache, CONFLICTING_TRANSLATE_PROPS, CONFLICTING_SCALE_PROPS, RELATIVE_TWEEN_VALUE, TRANSFORM_SENSITIVE_READ, TRANSFORM_INVARIANT_READ, CALLBACK_MEASUREMENT_PATTERN, NUMBER_METHODS, gsapRules, captionRules, MAX_COMPOSITION_LINES, MAX_TIMED_ELEMENTS_PER_TRACK, TRACK_DENSITY_EXEMPT_TAGS, CAPTION_CUE_TOKEN, HEAVY_OVERLAY_ELEMENT_COUNT_WARN, HEAVY_OVERLAY_EXEMPT_TAGS, HEAVY_OVERLAY_CSS_PATTERN, INLINE_STYLE_DISPLAY_NONE_PATTERN, compositionRules, adapterRules, TEXTURE_BASE_CLASS, TEXTURE_CLASS_PREFIX, textureRules, GENERIC_FAMILIES, fontRules, slideshowRules, RULE_GROUPS, LINT_RULE_COUNT, LINT_RULE_GROUP_COUNTS;
71621
+ var import_postcss_selector_parser, COMPOSITION_ID_IN_CSS_PATTERN, TIMELINE_REGISTRY_INIT_PATTERN, TIMELINE_REGISTRY_OBJECT_LITERAL_PATTERN, TIMELINE_REGISTRY_ASSIGN_PATTERN, WINDOW_TIMELINE_ASSIGN_PATTERN, INVALID_SCRIPT_CLOSE_PATTERN, TIMELINE_REGISTRY_KEY_PATTERN, TIMELINE_REGISTRY_OBJECT_OPEN_PATTERN, TIMELINE_REGISTRY_OBJECT_ENTRY_PATTERN, REGEX_ALLOWED_BEFORE, REGEX_ALLOWED_KEYWORDS, WORD_CHAR, CodeContext, VISIBLE_MARKUP_COMMENT_PATTERN, VISIBLE_MARKUP_COMMENT_PROTECTED_BLOCK_PATTERN, coreRules, IMAGE_SRC_EXT, VIDEO_SRC_EXT, AUDIO_SRC_EXT, SRC_KIND_NOUN, mediaRules, AUDIO_GROUP_TIMING_ATTRS, SCENE_BOUNDARY_EPSILON_SECONDS, UNRESOLVED_TARGET, gsapWindowsCache, CONFLICTING_TRANSLATE_PROPS, CONFLICTING_SCALE_PROPS, RELATIVE_TWEEN_VALUE, TRANSFORM_SENSITIVE_READ, TRANSFORM_INVARIANT_READ, CALLBACK_MEASUREMENT_PATTERN, NUMBER_METHODS, gsapRules, captionRules, MAX_COMPOSITION_LINES, MAX_TIMED_ELEMENTS_PER_TRACK, TRACK_DENSITY_EXEMPT_TAGS, CAPTION_CUE_TOKEN, HEAVY_OVERLAY_ELEMENT_COUNT_WARN, HEAVY_OVERLAY_EXEMPT_TAGS, HEAVY_OVERLAY_CSS_PATTERN, INLINE_STYLE_DISPLAY_NONE_PATTERN, compositionRules, adapterRules, TEXTURE_BASE_CLASS, TEXTURE_CLASS_PREFIX, textureRules, GENERIC_FAMILIES, fontRules, slideshowRules, RULE_GROUPS, LINT_RULE_COUNT, LINT_RULE_GROUP_COUNTS;
71407
71622
  var init_dist3 = __esm({
71408
71623
  "../lint/dist/index.js"() {
71409
71624
  "use strict";
@@ -71424,6 +71639,53 @@ var init_dist3 = __esm({
71424
71639
  TIMELINE_REGISTRY_KEY_PATTERN = /window\.__timelines(?:\[\s*["']([^"']+)["']\s*\]|\.\s*([A-Za-z_$][\w$]*))\s*=/g;
71425
71640
  TIMELINE_REGISTRY_OBJECT_OPEN_PATTERN = /window\.__timelines\s*=\s*\{/i;
71426
71641
  TIMELINE_REGISTRY_OBJECT_ENTRY_PATTERN = /(?:["']([^"']+)["']|([A-Za-z_$][\w$]*))\s*:\s*[A-Za-z_$][\w$]*/g;
71642
+ REGEX_ALLOWED_BEFORE = new Set("=(,:[!&|?{};+-*%^~<>");
71643
+ REGEX_ALLOWED_KEYWORDS = /* @__PURE__ */ new Set([
71644
+ "return",
71645
+ "typeof",
71646
+ "instanceof",
71647
+ "in",
71648
+ "of",
71649
+ "new",
71650
+ "delete",
71651
+ "void",
71652
+ "case",
71653
+ "do",
71654
+ "else",
71655
+ "yield",
71656
+ "await"
71657
+ ]);
71658
+ WORD_CHAR = /[A-Za-z0-9_$]/;
71659
+ CodeContext = class {
71660
+ last = "";
71661
+ prev = "";
71662
+ word = "";
71663
+ wordEnded = false;
71664
+ wordAfterDot = false;
71665
+ push(ch) {
71666
+ if (ch === " " || ch === " " || ch === "\n" || ch === "\r") {
71667
+ this.wordEnded = true;
71668
+ return;
71669
+ }
71670
+ if (WORD_CHAR.test(ch)) {
71671
+ if (this.wordEnded || this.word === "") this.wordAfterDot = this.last === ".";
71672
+ this.word = this.wordEnded ? ch : this.word + ch;
71673
+ } else {
71674
+ this.word = "";
71675
+ this.wordAfterDot = false;
71676
+ }
71677
+ this.wordEnded = false;
71678
+ this.prev = this.last;
71679
+ this.last = ch;
71680
+ }
71681
+ startsRegexLiteral() {
71682
+ if (this.last === "") return true;
71683
+ if (WORD_CHAR.test(this.last))
71684
+ return !this.wordAfterDot && REGEX_ALLOWED_KEYWORDS.has(this.word);
71685
+ if ((this.last === "+" || this.last === "-") && this.prev === this.last) return false;
71686
+ return REGEX_ALLOWED_BEFORE.has(this.last);
71687
+ }
71688
+ };
71427
71689
  VISIBLE_MARKUP_COMMENT_PATTERN = /\/\*[\s\S]*?\*\//g;
71428
71690
  VISIBLE_MARKUP_COMMENT_PROTECTED_BLOCK_PATTERN = /<(style|script|template|title|noscript|pre|code|textarea|text)\b[^>]*>[\s\S]*?<\/\1(?:\s[^>]*)?>/gi;
71429
71691
  coreRules = [
@@ -71737,6 +71999,12 @@ var init_dist3 = __esm({
71737
71999
  "mpg",
71738
72000
  "mpeg"
71739
72001
  ]);
72002
+ AUDIO_SRC_EXT = /* @__PURE__ */ new Set(["mp3", "wav", "aac", "flac", "opus", "aiff", "wma"]);
72003
+ SRC_KIND_NOUN = {
72004
+ image: "an image",
72005
+ video: "a video",
72006
+ audio: "an audio file"
72007
+ };
71740
72008
  mediaRules = [
71741
72009
  // duplicate_media_id + duplicate_media_discovery_risk
71742
72010
  ({ tags }) => {
@@ -72143,6 +72411,9 @@ var init_dist3 = __esm({
72143
72411
  // fallow-ignore-next-line complexity
72144
72412
  async ({ source, tags, scripts, styles, rootCompositionId }) => {
72145
72413
  const findings = [];
72414
+ const authoredHiddenSelectors = new Set(
72415
+ scripts.flatMap((script) => [...extractStandaloneHiddenSelectors(script.content)])
72416
+ );
72146
72417
  const clipIds = /* @__PURE__ */ new Map();
72147
72418
  const clipClasses = /* @__PURE__ */ new Map();
72148
72419
  for (const tag of tags) {
@@ -72235,9 +72506,10 @@ ${right.raw}`)
72235
72506
  );
72236
72507
  }).sort((a, b) => a.position - b.position);
72237
72508
  const startsHiddenAtZero = visibilityWindows.some(
72238
- (win) => win.position <= SCENE_BOUNDARY_EPSILON_SECONDS && isHiddenGsapState(win.propertyValues)
72509
+ (win) => win.position <= SCENE_BOUNDARY_EPSILON_SECONDS && (isHiddenGsapState(win.propertyValues) || win.fromPropertyValues !== void 0 && isHiddenGsapState(win.fromPropertyValues))
72239
72510
  );
72240
72511
  if (startsHiddenAtZero) continue;
72512
+ if (selectors.some((selector2) => authoredHiddenSelectors.has(selector2))) continue;
72241
72513
  const firstVisible = visibilityWindows.find((win) => makesOverlayVisible(win));
72242
72514
  if (!firstVisible) continue;
72243
72515
  const selector = selectors.find(
@@ -73564,8 +73836,8 @@ ${other.raw}`)
73564
73836
  });
73565
73837
  }
73566
73838
  };
73567
- for (const style of styles) scan(style.content);
73568
- for (const script of scripts) scan(script.content);
73839
+ for (const style of styles) scan(stripCssComments(style.content));
73840
+ for (const script of scripts) scan(stripJsComments(script.content));
73569
73841
  return findings;
73570
73842
  },
73571
73843
  // template_literal_selector
@@ -73573,14 +73845,17 @@ ${other.raw}`)
73573
73845
  const findings = [];
73574
73846
  for (const script of scripts) {
73575
73847
  const templateLiteralSelectorPattern = /(?:querySelector|querySelectorAll)\s*\(\s*`[^`]*\$\{[^}]+\}[^`]*`\s*\)/g;
73848
+ const scanned = stripJsCode(script.content);
73576
73849
  let tlMatch;
73577
- while ((tlMatch = templateLiteralSelectorPattern.exec(script.content)) !== null) {
73850
+ while ((tlMatch = templateLiteralSelectorPattern.exec(scanned)) !== null) {
73578
73851
  findings.push({
73579
73852
  code: "template_literal_selector",
73580
73853
  severity: "error",
73581
73854
  message: "querySelector uses a template literal variable (e.g. `${compId}`). The HTML bundler's CSS parser crashes on these. Use a hardcoded string instead.",
73582
73855
  fixHint: "Replace the template literal variable with a hardcoded string. The bundler's CSS parser cannot handle interpolated variables in script content.",
73583
- snippet: truncateSnippet(tlMatch[0])
73856
+ snippet: truncateSnippet(
73857
+ script.content.slice(tlMatch.index, tlMatch.index + tlMatch[0].length)
73858
+ )
73584
73859
  });
73585
73860
  }
73586
73861
  }
@@ -73682,7 +73957,7 @@ ${other.raw}`)
73682
73957
  if (isRegistrySourceFile(options.filePath) || isRegistryInstalledFile(rawSource)) return [];
73683
73958
  const findings = [];
73684
73959
  for (const script of scripts) {
73685
- const stripped = stripJsComments(script.content);
73960
+ const stripped = stripJsCode(script.content);
73686
73961
  if (/requestAnimationFrame\s*\(/.test(stripped)) {
73687
73962
  findings.push({
73688
73963
  code: "requestanimationframe_in_composition",
@@ -97455,8 +97730,16 @@ import { serve as serve3 } from "@hono/node-server";
97455
97730
 
97456
97731
  // ../producer/src/services/hyperframeLint.ts
97457
97732
  init_dist3();
97458
- import { existsSync as existsSync30, readFileSync as readFileSync13, statSync as statSync11 } from "fs";
97459
- import { resolve as resolve14, join as join44 } from "path";
97733
+ import {
97734
+ existsSync as existsSync30,
97735
+ readFileSync as readFileSync13,
97736
+ statSync as statSync11,
97737
+ openSync as openSync7,
97738
+ fstatSync as fstatSync5,
97739
+ closeSync as closeSync8,
97740
+ constants as constants5
97741
+ } from "fs";
97742
+ import { resolve as resolve14, join as join44, relative as relative3, isAbsolute as isAbsolute4, sep as sep4 } from "path";
97460
97743
  function isStringRecord(value) {
97461
97744
  if (!value || typeof value !== "object" || Array.isArray(value)) {
97462
97745
  return false;
@@ -97482,6 +97765,23 @@ function pickEntryFile(files, preferredEntryFile) {
97482
97765
  }
97483
97766
  return null;
97484
97767
  }
97768
+ function readEntryHtml(filePath) {
97769
+ let fd;
97770
+ try {
97771
+ fd = openSync7(filePath, constants5.O_RDONLY | constants5.O_NONBLOCK);
97772
+ } catch (error) {
97773
+ if (error instanceof Error && "code" in error && (error.code === "ENOENT" || error.code === "ENOTDIR"))
97774
+ return null;
97775
+ if (!statSync11(filePath, { throwIfNoEntry: false })?.isFile()) return null;
97776
+ throw error;
97777
+ }
97778
+ try {
97779
+ if (!fstatSync5(fd).isFile()) return null;
97780
+ return readFileSync13(fd, "utf-8");
97781
+ } finally {
97782
+ closeSync8(fd);
97783
+ }
97784
+ }
97485
97785
  function readProjectEntryFile(projectDir, preferredEntryFile) {
97486
97786
  const absProjectDir = resolve14(projectDir);
97487
97787
  if (!existsSync30(absProjectDir) || !statSync11(absProjectDir).isDirectory()) {
@@ -97492,13 +97792,15 @@ function readProjectEntryFile(projectDir, preferredEntryFile) {
97492
97792
  );
97493
97793
  for (const entryFile of entryCandidates) {
97494
97794
  const absoluteEntryPath = resolve14(absProjectDir, entryFile);
97495
- if (!absoluteEntryPath.startsWith(absProjectDir)) {
97795
+ const entryRelativePath = relative3(absProjectDir, absoluteEntryPath);
97796
+ if (entryRelativePath === ".." || entryRelativePath.startsWith(`..${sep4}`) || isAbsolute4(entryRelativePath)) {
97496
97797
  return { error: `Entry file must stay inside project directory: ${entryFile}` };
97497
97798
  }
97498
- if (existsSync30(absoluteEntryPath) && statSync11(absoluteEntryPath).isFile()) {
97799
+ const html = readEntryHtml(absoluteEntryPath);
97800
+ if (html !== null) {
97499
97801
  return {
97500
97802
  entryFile,
97501
- html: readFileSync13(absoluteEntryPath, "utf-8"),
97803
+ html,
97502
97804
  source: "projectDir"
97503
97805
  };
97504
97806
  }
@@ -98280,11 +98582,11 @@ init_src();
98280
98582
  init_dist2();
98281
98583
  init_src();
98282
98584
  import { cpSync as cpSync2, existsSync as existsSync35, mkdirSync as mkdirSync20, renameSync as renameSync7, rmSync as rmSync16, writeFileSync as writeFileSync13 } from "fs";
98283
- import { join as join50, relative as relative5, sep as sep4 } from "path";
98585
+ import { join as join50, relative as relative6, sep as sep5 } from "path";
98284
98586
 
98285
98587
  // ../producer/src/services/render/stages/freezePlan.ts
98286
98588
  import { existsSync as existsSync33, mkdirSync as mkdirSync19, readFileSync as readFileSync14, readdirSync as readdirSync12, writeFileSync as writeFileSync12 } from "fs";
98287
- import { join as join47, relative as relative3, resolve as resolve16 } from "path";
98589
+ import { join as join47, relative as relative4, resolve as resolve16 } from "path";
98288
98590
 
98289
98591
  // ../producer/src/services/distributed/planProtocol.ts
98290
98592
  var PLAN_SCHEMA_VERSION = 1;
@@ -98336,7 +98638,7 @@ var execFile3 = promisify4(execFileCallback);
98336
98638
  // ../producer/src/services/distributed/planSize.ts
98337
98639
  import { createHash as createHash10 } from "crypto";
98338
98640
  import { lstatSync as lstatSync5, readdirSync as readdirSync13 } from "fs";
98339
- import { extname as extname7, join as join49, relative as relative4 } from "path";
98641
+ import { extname as extname7, join as join49, relative as relative5 } from "path";
98340
98642
  var PLAN_ROOT_CATEGORY = {
98341
98643
  compiled: "compiled",
98342
98644
  [PLAN_AUDIO_RELATIVE_PATH]: "audio",
@@ -98356,13 +98658,13 @@ var FREEZE_OWNED_PLAN_FILES = [
98356
98658
  // ../producer/src/services/distributed/planV2.ts
98357
98659
  init_src();
98358
98660
  import {
98359
- closeSync as closeSync8,
98661
+ closeSync as closeSync9,
98360
98662
  copyFileSync as copyFileSync8,
98361
98663
  existsSync as existsSync37,
98362
98664
  lstatSync as lstatSync6,
98363
98665
  mkdirSync as mkdirSync22,
98364
98666
  mkdtempSync as mkdtempSync14,
98365
- openSync as openSync7,
98667
+ openSync as openSync8,
98366
98668
  readFileSync as readFileSync16,
98367
98669
  readSync as readSync3,
98368
98670
  readdirSync as readdirSync14,
@@ -98373,7 +98675,7 @@ import {
98373
98675
  } from "fs";
98374
98676
  import { createHash as createHash11 } from "crypto";
98375
98677
  import { tmpdir as tmpdir9 } from "os";
98376
- import { dirname as dirname23, isAbsolute as isAbsolute4, join as join53, relative as relative6, resolve as resolve17, sep as sep5 } from "path";
98678
+ import { dirname as dirname23, isAbsolute as isAbsolute5, join as join53, relative as relative7, resolve as resolve17, sep as sep6 } from "path";
98377
98679
 
98378
98680
  // ../producer/src/services/distributed/planV2Publisher.ts
98379
98681
  import {
@@ -98422,7 +98724,7 @@ init_src();
98422
98724
  // ../producer/src/services/distributed/projectHash.ts
98423
98725
  import { readdirSync as readdirSync17, readFileSync as readFileSync19 } from "fs";
98424
98726
  import { createHash as createHash12 } from "crypto";
98425
- import { join as join57, relative as relative7 } from "path";
98727
+ import { join as join57, relative as relative8 } from "path";
98426
98728
 
98427
98729
  // src/fontLocalize.ts
98428
98730
  function safeVersion(version2) {
@@ -98463,8 +98765,8 @@ async function runFontLocalize(io, localize) {
98463
98765
  }
98464
98766
 
98465
98767
  // src/version.ts
98466
- var VERSION = true ? "0.8.30" : "0.0.0-dev";
98467
- var PRODUCER_VERSION = true ? "0.8.30" : "0.0.0-dev";
98768
+ var VERSION = true ? "0.8.31" : "0.0.0-dev";
98769
+ var PRODUCER_VERSION = true ? "0.8.31" : "0.0.0-dev";
98468
98770
 
98469
98771
  // src/fontLocalizeCli.ts
98470
98772
  async function readStdin() {