@hyperframes/core 0.8.198 → 0.8.200

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.
@@ -23,7 +23,7 @@ import { buildVariablesByCompScript, dedupeFontFaceRules, hoistFontFaceRules, sc
23
23
  import { validateHyperframeHtmlContract } from "./staticGuard.js";
24
24
  import { getHyperframeRuntimeScript } from "../generated/runtime-inline.js";
25
25
  import { readDeclaredDefaults } from "../runtime/getVariables.js";
26
- import { ensureExternalLinkTag, inlineSubCompositions, refuseSwapsReachedByRootScripts, } from "./inlineSubCompositions.js";
26
+ import { ensureExternalLinkTag, inlineSubCompositions, isLibraryCopy, refuseSwapsReachedByRootScripts, } from "./inlineSubCompositions.js";
27
27
  import { isSafePath, resolveWithinProject } from "../safePath.js";
28
28
  import { ensureHfIds } from "@hyperframes/parsers/hf-ids";
29
29
  import { HF_COLOR_GRADING_ATTR } from "../colorGrading.js";
@@ -966,7 +966,8 @@ async function bundleProject(projectDir, options) {
966
966
  ].map((el) => {
967
967
  const src = el.getAttribute("src");
968
968
  const path = src && isRelativeUrl(src) ? resolveEntryUrl(src) : null;
969
- return src ? (path && safeReadFile(path)) || "" : el.textContent || "";
969
+ const text = src ? (path && safeReadFile(path)) || "" : el.textContent || "";
970
+ return isLibraryCopy(text) ? "" : text;
970
971
  })
971
972
  : [];
972
973
  // Inline sub-compositions (via shared function)
@@ -1006,6 +1007,10 @@ async function bundleProject(projectDir, options) {
1006
1007
  },
1007
1008
  flattenInnerRoot: prepareFlattenedInnerRoot,
1008
1009
  tagScenes: options?.sceneParts === true,
1010
+ readProjectScript: (path) => {
1011
+ const resolved = isRelativeUrl(path) ? resolveEntryUrl(path) : null;
1012
+ return resolved ? safeReadFile(resolved) : null;
1013
+ },
1009
1014
  readVariableDefaults: readDeclaredDefaults,
1010
1015
  parseHostVariables: parseHostVariableValues,
1011
1016
  buildScopeSelector: (compId) => cssAttributeSelector("data-composition-id", compId),
@@ -1025,6 +1030,10 @@ async function bundleProject(projectDir, options) {
1025
1030
  ...subCompResult.variablesByComp,
1026
1031
  };
1027
1032
  const seenCompScriptSrcs = new Set();
1033
+ const scenesBySrc = new Map();
1034
+ for (const item of subCompResult.scriptItems)
1035
+ if (item.kind !== "inline")
1036
+ scenesBySrc.set(item.src, (scenesBySrc.get(item.src) ?? new Set()).add(item.scene));
1028
1037
  for (const scriptItem of subCompResult.scriptItems) {
1029
1038
  if (scriptItem.kind === "inline") {
1030
1039
  pushRun(scriptRuns, scriptItem.scene, scriptItem.content);
@@ -1039,12 +1048,14 @@ async function bundleProject(projectDir, options) {
1039
1048
  if (seenCompScriptSrcs.has(extSrc))
1040
1049
  continue;
1041
1050
  seenCompScriptSrcs.add(extSrc);
1051
+ // Run once for the film when scenes share it: a scene mounts without the one that loaded it first.
1052
+ const scene = (scenesBySrc.get(extSrc)?.size ?? 0) > 1 ? undefined : scriptItem.scene;
1042
1053
  if (isRelativeUrl(extSrc) && scriptItem.type !== "module") {
1043
1054
  const jsPath = resolveEntryUrl(extSrc);
1044
1055
  const js = jsPath ? safeReadFile(jsPath) : null;
1045
1056
  if (js != null) {
1046
1057
  const chunk = () => preserveLocalScriptIntegrity(document, extSrc, resolveEntryUrl) ? "" : js;
1047
- pushRun(scriptRuns, scriptItem.scene, chunk);
1058
+ pushRun(scriptRuns, scene, chunk);
1048
1059
  continue;
1049
1060
  }
1050
1061
  }
@@ -11,6 +11,7 @@ import { type CompositionStyle } from "./scriptRuns.js";
11
11
  * `data-composition-file`).
12
12
  */
13
13
  import { type AssetExists } from "./rewriteSubCompPaths.js";
14
+ export declare const isLibraryCopy: (script: string) => boolean;
14
15
  /** Marks each scene whose nodes a script outside it names by selector, id or class: a swap would strand it. */
15
16
  export declare function refuseSwapsReachedByRootScripts(document: Document, rootScripts: string[]): void;
16
17
  export interface InlineSubCompositionsOptions {
@@ -98,6 +99,7 @@ export interface InlineSubCompositionsOptions {
98
99
  onMissingComposition?: (srcPath: string, reason?: string) => void;
99
100
  /** Tag each top-level host with `data-hf-scene` and report every part's scene, for preview swaps. */
100
101
  tagScenes?: boolean;
102
+ readProjectScript?: (path: string) => string | null;
101
103
  }
102
104
  export interface ExternalLink {
103
105
  href: string;
@@ -20,15 +20,74 @@ import { enumerateNestedCompositionHosts, planCompositionAssembly, extractedComp
20
20
  import { SCENE_NO_SWAP_ATTR, SCENE_PART_ATTR } from "../sceneParts.js";
21
21
  // Anything a scene script can leave running, pending or registered outside its timeline, or that
22
22
  // throws when run again: only the timeline is torn down when a scene is swapped, so when unsure, refuse.
23
- const SIDE_EFFECT_RE = /\b(addEventListener|requestAnimationFrame|requestIdleCallback|setTimeout|setInterval|queueMicrotask|getContext|WebGL\w*|WebGPU\w*|gpu|Worker|WebSocket|EventSource|Audio\w*|\w*Observer|fetch|import|eval|Function|Promise|async|await|delayedCall|ScrollTrigger|Draggable|anime|customElements|registerProperty|addListener|BroadcastChannel|pushState|replaceState|adoptedStyleSheets|documentElement|getElementsByTagName|lottie|THREE|__hf[A-Z]\w*)\b|\.then\s*\(|\.animate\s*\(|\.ticker\b|repeat\s*:\s*-1|\.repeat\s*\(\s*-1|defineProperty\s*\(\s*(window|globalThis|self|document)\b|\bfonts\s*\.\s*add\b|\.on[a-z]+\s*=(?!=)|\bon(resize|scroll|message|key\w+|click|pointer\w+|mouse\w+|wheel|visibilitychange|hashchange|popstate|error|load)\s*=(?!=)|\[\s*["']on[a-z]+["']\s*\]|document\s*\.\s*(head|body)\b|querySelector(All)?\(\s*["'](head|body)["']|\bgsap\s*\.\s*(?:to|from|fromTo)\s*\(|\bgsap\s*\.\s*timeline\s*\((?:[^()]|\([^()]*\))*\)\s*\.\s*(?:to|from|fromTo|set|add|call)\s*\(/;
23
+ const SIDE_EFFECT_RE = /\b(addEventListener|requestAnimationFrame|requestIdleCallback|setTimeout|setInterval|queueMicrotask|getContext|WebGL\w*|WebGPU\w*|gpu|Worker|WebSocket|EventSource|Audio\w*|\w*Observer|fetch|import|eval|Function|Promise|async|await|delayedCall|ScrollTrigger|Draggable|anime|customElements|registerProperty|addListener|BroadcastChannel|pushState|replaceState|adoptedStyleSheets|documentElement|getElementsByTagName|lottie|THREE|__hf[A-Z]\w*)\b|\.then\s*\(|\.ticker\b|repeat\s*:\s*-1|\.repeat\s*\(\s*-1|defineProperty\s*\(\s*(window|globalThis|self|document)\b|\bfonts\s*\.\s*add\b|\.on[a-z]+\s*=(?!=)|\bon(resize|scroll|message|key\w+|click|pointer\w+|mouse\w+|wheel|visibilitychange|hashchange|popstate|error|load)\s*=(?!=)|\[\s*["']on[a-z]+["']\s*\]|document\s*\.\s*(head|body)\b|querySelector(All)?\(\s*["'](head|body)["']|\bgsap\s*\.\s*(?:to|from|fromTo)\s*\(|\bgsap\s*\.\s*timeline\s*\((?:[^()]|\([^()]*\))*\)\s*\.\s*(?:to|from|fromTo|set|add|call)\s*\(/;
24
24
  // npm packages that only define globals when loaded; lottie-web is absent because it scans the page on load.
25
25
  const SWAP_SAFE_LIBRARY_URL = /^https:\/\/(cdn\.jsdelivr\.net\/npm|unpkg\.com)\/(gsap|three|d3|d3-[a-z-]+|topojson-client|clipper-lib)(@[^/]+)?\//;
26
26
  const isSwapSafeLibrary = (src) => URL.canParse(src) && SWAP_SAFE_LIBRARY_URL.test(new URL(src).href);
27
+ // GSAP's published file copied into a project, known by its license banner: it only defines globals too.
28
+ const GSAP_BANNER_RE = /^\s*\/\*!\s*\*\s*GSAP \d+\.\d+\.\d+\s*\*\s*https:\/\/gsap\.com\b/;
29
+ export const isLibraryCopy = (script) => GSAP_BANNER_RE.test(script);
30
+ // Waits on the page's fonts, ready or loading named faces: each settles once, leaving nothing behind.
31
+ const STRING_ARG = String.raw `(?:"(?:\\.|[^"\\\n])*"|'(?:\\.|[^'\\\n])*')`;
32
+ const FONT_LOAD = String.raw `document\s*\.\s*fonts\s*\.\s*load\s*\(\s*${STRING_ARG}\s*(?:,\s*${STRING_ARG}\s*)?\)`;
33
+ const FONT_PROMISE = String.raw `(?:document\s*\.\s*fonts\s*\.\s*ready\b|${FONT_LOAD}|Promise\s*\.\s*all\s*\(\s*\[\s*${FONT_LOAD}(?:\s*,\s*${FONT_LOAD})*\s*,?\s*\]\s*\))`;
34
+ const FONT_WAIT_RE = new RegExp(String.raw `\b${FONT_PROMISE}\s*\.\s*then\s*\(|\bawait\s+${FONT_PROMISE}`, "g");
35
+ // A canvas made only to measure text: never named, so nothing attaches it to the page or draws on it there.
36
+ const TEXT_MEASURE_CANVAS_RE = /\bdocument\s*\.\s*createElement\s*\(\s*(["'])canvas\1\s*\)\s*\.\s*getContext\s*\(\s*(["'])2d\2\s*\)/g;
37
+ // A timeline chained as it is registered: the registry holds it, so unmounting the scene stops it.
38
+ const REGISTERED_CHAIN_RE = /(\b(?:window\s*\.\s*)?__timelines\s*\[[^[\]]*\]\s*=\s*)gsap\s*\.\s*timeline\s*\(/g;
39
+ /** Whether a call of the browser's Element.animate may leave an animation: it gets timing, its second argument. */
40
+ function lastingAnimateCall(script) {
41
+ for (const call of script.matchAll(/\.animate\s*\(/g)) {
42
+ if (topLevelArgs(script, call.index + call[0].length) !== 1)
43
+ return true;
44
+ }
45
+ return false;
46
+ }
47
+ // Arguments of the call whose "(" ends before `from`; none, a spread or an unclosed call never count as one.
48
+ function topLevelArgs(script, from) {
49
+ let depth = 0;
50
+ let args = 1;
51
+ if (/^\s*(\.\.\.|\))/.test(script.slice(from)))
52
+ return Number.POSITIVE_INFINITY;
53
+ for (let i = from; i < script.length; i++) {
54
+ const ch = script[i];
55
+ if (ch === '"' || ch === "'" || ch === "`") {
56
+ const end = script.indexOf(ch, i + 1);
57
+ if (end < 0)
58
+ return Number.POSITIVE_INFINITY;
59
+ i = end;
60
+ }
61
+ else if ("([{".includes(ch))
62
+ depth++;
63
+ else if (")]}".includes(ch)) {
64
+ if (depth === 0)
65
+ return args;
66
+ depth--;
67
+ }
68
+ else if (ch === "," && depth === 0)
69
+ args++;
70
+ }
71
+ return Number.POSITIVE_INFINITY;
72
+ }
27
73
  /** Why an authored scene script cannot be swapped out cleanly, or null when it can. */
28
74
  function sceneScriptSwapRefusal(script) {
29
- const match = SIDE_EFFECT_RE.exec(script);
30
- return match ? `its script uses ${match[0].trim()}` : null;
75
+ const withoutFontWaits = script.replace(FONT_WAIT_RE, "");
76
+ const awaitedFontsOnly = /\bawait\b/.test(script) && !/\bawait\b/.test(withoutFontWaits);
77
+ let checked = (awaitedFontsOnly ? withoutFontWaits.replace(/\basync\b/g, "") : withoutFontWaits).replace(REGISTERED_CHAIN_RE, "$1(");
78
+ // The context hands its canvas back through .canvas, which could then reach the page.
79
+ if (!/\.\s*canvas\b/.test(checked))
80
+ checked = checked.replace(TEXT_MEASURE_CANVAS_RE, "");
81
+ const match = SIDE_EFFECT_RE.exec(checked);
82
+ if (match)
83
+ return `its script uses ${match[0].trim()}`;
84
+ return lastingAnimateCall(checked) ? "its script uses .animate(" : null;
31
85
  }
86
+ const projectScriptRefusal = (text) => text === null
87
+ ? "it runs a script that is not a known library"
88
+ : isLibraryCopy(text)
89
+ ? null
90
+ : sceneScriptSwapRefusal(text);
32
91
  // A quoted string in a script, in any of the three quote styles.
33
92
  const STRING_LITERAL_RE = /(["'`])((?:\\.|(?!\1)[^\\\n])*?)\1/g;
34
93
  // Text ending where createElement takes its tag: that string makes a node, it selects none.
@@ -135,7 +194,7 @@ function defaultBuildScopeSelector(compId) {
135
194
  */
136
195
  // fallow-ignore-next-line complexity
137
196
  export function inlineSubCompositions(document, hosts, options) {
138
- const { resolveHtml, parseHtml, hostIdentityMap, rewriteInlineStyles = false, flattenInnerRoot, compoundAuthoredRoot, readVariableDefaults, parseHostVariables, buildScopeSelector = defaultBuildScopeSelector, scriptErrorLabel = "[HyperFrames] composition script error:", onMissingComposition, assetExists, tagScenes = false, } = options;
197
+ const { resolveHtml, parseHtml, hostIdentityMap, rewriteInlineStyles = false, flattenInnerRoot, compoundAuthoredRoot, readVariableDefaults, parseHostVariables, buildScopeSelector = defaultBuildScopeSelector, scriptErrorLabel = "[HyperFrames] composition script error:", onMissingComposition, assetExists, tagScenes = false, readProjectScript, } = options;
139
198
  const rootStyles = [...document.querySelectorAll("style")];
140
199
  const styles = [];
141
200
  const styleScenes = [];
@@ -338,7 +397,7 @@ export function inlineSubCompositions(document, hosts, options) {
338
397
  ? sceneScriptSwapRefusal(scriptEl.textContent || "")
339
398
  : isSwapSafeLibrary(externalSrc)
340
399
  ? null
341
- : "it runs a script that is not a known library");
400
+ : projectScriptRefusal(readProjectScript?.(externalSrc) ?? null));
342
401
  if (type === "importmap") {
343
402
  const map = parseImportMap(scriptEl.textContent || "", (url) => {
344
403
  // The rebase drops a leading "./" and a trailing "/"; an import map address needs both.
@@ -1,5 +1,5 @@
1
1
  // Generated by scripts/build-position-edits-render.ts; do not edit.
2
- const POSITION_EDITS_RENDER_IIFE = '"use strict";(()=>{function T(){return globalThis}function P(e,t){if(typeof window>"u")return;let o=T(),r=o.__hf?.onSwallowed;if(r)try{r({label:e,error:t})}catch(s){}(o.__hfDebug||o.__HYPERFRAMES_DEBUG)&&console.debug(`[hyperframes] ${e} swallowed:`,t)}var x=null;function R(e,t){if(x)try{x({source:"hf-preview",type:"analytics",event:e,properties:t??{}})}catch(o){P("runtime.analytics.site1",o)}}var W="http://www.w3.org/1999/xhtml";function N(e){return e!=null&&e.nodeType===1}function k(e){return N(e)&&(e.namespaceURI===W||e.namespaceURI==="http://www.w3.org/2000/svg")}var w="data-hf-edit-base-x",y="data-hf-edit-base-y",m="data-hf-edit-original-translate",_=e=>{let t=parseFloat(e??"");return Number.isFinite(t)?t:0},O=e=>{let t=[],o=0,r="";for(let s of e.trim())s==="("&&(o+=1),s===")"&&(o=Math.max(0,o-1)),/\\s/.test(s)&&o===0?(r&&t.push(r),r=""):r+=s;return r&&t.push(r),t},$=/^-?(?:\\d+(?:\\.\\d+)?|\\.\\d+)px$/,E=(e,t)=>$.test(e)&&$.test(t)?`${parseFloat(e)+parseFloat(t)}px`:`calc(${e} + ${t})`,C=(e,t,o)=>{if(!e||e==="none")return`${t} ${o}`;let[r,s,a]=O(e);if(r===void 0)return`${t} ${o}`;if(s===void 0)return`${E(r,t)} ${o}`;let i=a===void 0?"":` ${a}`;return`${E(r,t)} ${E(s,o)}${i}`},V=e=>{try{e.ownerDocument.defaultView?.gsap?.getProperty?.(e,"x")}catch{}},j=e=>{let t=e.style.getPropertyValue("translate").trim();if(t)return t==="none"?"":t;try{let o=e.ownerDocument.defaultView,r=o?o.getComputedStyle(e).getPropertyValue("translate").trim():"";return r==="none"?"":r}catch{return""}},b=new WeakMap;function B(e,t){let o=b.get(e);if(!t?.force&&o!==void 0&&e.style.getPropertyValue("translate")!==o){R("position_edit_fold_skipped",{hfId:e.getAttribute("data-hf-id")});return}let r=_(e.getAttribute("data-x"))-_(e.getAttribute(w)),s=_(e.getAttribute("data-y"))-_(e.getAttribute(y));e.hasAttribute(m)||e.setAttribute(m,j(e)),o===void 0&&V(e);let a=e.getAttribute(m)??"",i=C(a,`${r}px`,`${s}px`);e.style.setProperty("translate",i),b.set(e,e.style.getPropertyValue("translate"))}function S(e,t){let o=e.querySelectorAll(`[${m}]:not([${w}]):not([${y}])`);for(let a=0;a<o.length;a++){let i=o[a];if(i===void 0||!k(i))continue;let g=i.getAttribute(m)??"";g===""?i.style.removeProperty("translate"):i.style.setProperty("translate",g),i.removeAttribute(m),b.delete(i)}let r=e.querySelectorAll(`[${w}], [${y}]`),s=0;for(let a=0;a<r.length;a++){let i=r[a];i===void 0||!k(i)||(B(i,t),s+=1)}return s}var L="__hfPositionEditsSeekReapplyWrapped",D=new WeakSet,F=new WeakMap,M=new WeakMap;function H(e){let t=e,o=()=>{try{S(t.document)}catch{}},r=n=>typeof n=="function"&&(D.has(n)||!!n[L]),s=n=>{D.add(n);try{Object.defineProperty(n,L,{value:!0})}catch{}},a=n=>{if(typeof n!="function"||r(n))return n;let l=function(...u){let d=n.apply(this,u);return o(),d};return s(l),l},i=(n,l)=>{let u=F.get(n);if(u?.has(l))return!0;let d=Object.getOwnPropertyDescriptor(n,l);if(d?.configurable===!1){let c=n[l];return typeof c=="function"&&(n[l]=a(c),o()),!1}let p=n[l],f=d?.set;return Object.defineProperty(n,l,{configurable:!0,enumerable:d?.enumerable??!0,get:()=>p,set:c=>{p=a(c),f?.call(n,c)}}),p=a(p),u??(u=new Set),u.add(l),F.set(n,u),o(),!0},g=(n,l)=>{let u=M.get(t),d=Object.getOwnPropertyDescriptor(t,n);if(!u?.has(n)){if(d?.configurable===!1){let c=t[n];return c?i(c,l):!1}let f=t[n];Object.defineProperty(t,n,{configurable:!0,enumerable:d?.enumerable??!0,get:()=>f,set:c=>{f=c,f&&i(f,l)}}),u??(u=new Set),u.add(n),M.set(t,u)}let p=t[n];return p?i(p,l):!1},h=()=>{let n=g("__hf","seek"),l=g("__player","renderSeek");return n&&l};if(h())return;let v=120,A=t.setInterval(()=>{if(h()){t.clearInterval(A);return}v-=1,v<=0&&t.clearInterval(A)},50)}function I(){document.querySelector(`[${w}], [${y}]`)&&(S(document),H(window))}document.readyState==="loading"?document.addEventListener("DOMContentLoaded",I,{once:!0}):I();})();\n';
2
+ const POSITION_EDITS_RENDER_IIFE = '"use strict";(()=>{function P(){return globalThis}function T(e,t){if(typeof window>"u")return;let o=P(),r=o.__hf?.onSwallowed;if(r)try{r({label:e,error:t})}catch(s){}(o.__hfDebug||o.__HYPERFRAMES_DEBUG)&&console.debug(`[hyperframes] ${e} swallowed:`,t)}var x=null;function R(e,t){if(x)try{x({source:"hf-preview",type:"analytics",event:e,properties:t??{}})}catch(o){T("runtime.analytics.site1",o)}}var W="http://www.w3.org/1999/xhtml";function N(e){return e!=null&&e.nodeType===1}function k(e){return N(e)&&(e.namespaceURI===W||e.namespaceURI==="http://www.w3.org/2000/svg")}var w="data-hf-edit-base-x",y="data-hf-edit-base-y",m="data-hf-edit-original-translate",_=e=>{let t=parseFloat(e??"");return Number.isFinite(t)?t:0},C=e=>{let t=[],o=0,r="";for(let s of e.trim())s==="("&&(o+=1),s===")"&&(o=Math.max(0,o-1)),/\\s/.test(s)&&o===0?(r&&t.push(r),r=""):r+=s;return r&&t.push(r),t},L=/^-?(?:\\d+(?:\\.\\d+)?|\\.\\d+)px$/,E=(e,t)=>L.test(e)&&L.test(t)?`${parseFloat(e)+parseFloat(t)}px`:`calc(${e} + ${t})`,O=(e,t,o)=>{if(!e||e==="none")return`${t} ${o}`;let[r,s,a]=C(e);if(r===void 0)return`${t} ${o}`;if(s===void 0)return`${E(r,t)} ${o}`;let i=a===void 0?"":` ${a}`;return`${E(r,t)} ${E(s,o)}${i}`},V=e=>{try{e.ownerDocument.defaultView?.gsap?.getProperty?.(e,"x")}catch{}},j=e=>{let t=e.style.getPropertyValue("translate").trim();if(t)return t==="none"?"":t;try{let o=e.ownerDocument.defaultView,r=o?o.getComputedStyle(e).getPropertyValue("translate").trim():"";return r==="none"?"":r}catch{return""}},b=new WeakMap;function B(e,t){let o=b.get(e);if(!t?.force&&o!==void 0&&e.style.getPropertyValue("translate")!==o){R("position_edit_fold_skipped",{hfId:e.getAttribute("data-hf-id")});return}let r=_(e.getAttribute("data-x"))-_(e.getAttribute(w)),s=_(e.getAttribute("data-y"))-_(e.getAttribute(y));e.hasAttribute(m)||e.setAttribute(m,j(e)),o===void 0&&V(e);let a=e.getAttribute(m)??"",i=O(a,`${r}px`,`${s}px`);e.style.setProperty("translate",i),b.set(e,e.style.getPropertyValue("translate"))}function S(e,t){let o=e.querySelectorAll(`[${m}]:not([${w}]):not([${y}])`);for(let a=0;a<o.length;a++){let i=o[a];if(i===void 0||!k(i))continue;let g=i.getAttribute(m)??"";g===""?i.style.removeProperty("translate"):i.style.setProperty("translate",g),i.removeAttribute(m),b.delete(i)}let r=e.querySelectorAll(`[${w}], [${y}]`),s=0;for(let a=0;a<r.length;a++){let i=r[a];i===void 0||!k(i)||(B(i,t),s+=1)}return s}var $="__hfPositionEditsSeekReapplyWrapped",D=new WeakSet,F=new WeakMap,I=new WeakMap;function M(e){let t=e,o=()=>{try{S(t.document)}catch{}},r=n=>typeof n=="function"&&(D.has(n)||!!n[$]),s=n=>{D.add(n);try{Object.defineProperty(n,$,{value:!0})}catch{}},a=n=>{if(typeof n!="function"||r(n))return n;let l=function(...u){let d=n.apply(this,u);return o(),d};return s(l),l},i=(n,l)=>{let u=F.get(n);if(u?.has(l))return!0;let d=Object.getOwnPropertyDescriptor(n,l);if(d?.configurable===!1){let c=n[l];return typeof c=="function"&&(n[l]=a(c),o()),!1}let p=n[l],f=d?.set;return Object.defineProperty(n,l,{configurable:!0,enumerable:d?.enumerable??!0,get:()=>p,set:c=>{p=a(c),f?.call(n,c)}}),p=a(p),u??(u=new Set),u.add(l),F.set(n,u),o(),!0},g=(n,l)=>{let u=I.get(t),d=Object.getOwnPropertyDescriptor(t,n);if(!u?.has(n)){if(d?.configurable===!1){let c=t[n];return c?i(c,l):!1}let f=t[n];Object.defineProperty(t,n,{configurable:!0,enumerable:d?.enumerable??!0,get:()=>f,set:c=>{f=c,f&&i(f,l)}}),u??(u=new Set),u.add(n),I.set(t,u)}let p=t[n];return p?i(p,l):!1},h=()=>{let n=g("__hf","seek"),l=g("__player","renderSeek");return n&&l};if(h())return;let v=120,A=t.setInterval(()=>{if(h()){t.clearInterval(A);return}v-=1,v<=0&&t.clearInterval(A)},50)}function H(){document.querySelector(`[${w}], [${y}]`)&&(S(document),M(window))}document.readyState==="loading"?document.addEventListener("DOMContentLoaded",H,{once:!0}):H();})();\n';
3
3
  /** Returns the pre-built position-edits render IIFE as a string constant. */
4
4
  export function getPositionEditsRenderScript() {
5
5
  return POSITION_EDITS_RENDER_IIFE;