hyperframes 0.4.15 → 0.4.16

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.
Files changed (2) hide show
  1. package/dist/cli.js +1008 -797
  2. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -54,7 +54,7 @@ var VERSION;
54
54
  var init_version = __esm({
55
55
  "src/version.ts"() {
56
56
  "use strict";
57
- VERSION = true ? "0.4.15" : "0.0.0-dev";
57
+ VERSION = true ? "0.4.16" : "0.0.0-dev";
58
58
  }
59
59
  });
60
60
 
@@ -5896,6 +5896,7 @@ var init_rewriteSubCompPaths = __esm({
5896
5896
 
5897
5897
  // ../core/src/inline-scripts/hyperframesRuntime.engine.ts
5898
5898
  import { buildSync } from "esbuild";
5899
+ import { existsSync } from "fs";
5899
5900
  import { dirname as dirname2, resolve as resolve2 } from "path";
5900
5901
  import { fileURLToPath } from "url";
5901
5902
  function applyDefaultParityMode(script, enabled) {
@@ -5908,6 +5909,7 @@ function applyDefaultParityMode(script, enabled) {
5908
5909
  }
5909
5910
  function buildHyperframesRuntimeScript(options = {}) {
5910
5911
  const entryPath = resolve2(dirname2(fileURLToPath(import.meta.url)), "../runtime/entry.ts");
5912
+ if (!existsSync(entryPath)) return null;
5911
5913
  const result = buildSync({
5912
5914
  entryPoints: [entryPath],
5913
5915
  bundle: true,
@@ -5984,6 +5986,18 @@ var init_hyperframe = __esm({
5984
5986
  }
5985
5987
  });
5986
5988
 
5989
+ // ../core/src/generated/runtime-inline.ts
5990
+ function getHyperframeRuntimeScript() {
5991
+ return RUNTIME_IIFE;
5992
+ }
5993
+ var RUNTIME_IIFE;
5994
+ var init_runtime_inline = __esm({
5995
+ "../core/src/generated/runtime-inline.ts"() {
5996
+ "use strict";
5997
+ RUNTIME_IIFE = '"use strict";(()=>{function xe(e){try{window.parent.postMessage(e,"*")}catch{}}function Nt(e){let t=n=>{let o=n.data;if(!o||o.source!=="hf-parent"||o.type!=="control")return;let r=o.action;if(r==="play"){e.onPlay();return}if(r==="pause"){e.onPause();return}if(r==="seek"){e.onSeek(Number(o.frame??0),o.seekMode??"commit");return}if(r==="set-muted"){e.onSetMuted(!!o.muted);return}if(r==="set-media-output-muted"){e.onSetMediaOutputMuted(!!o.muted);return}if(r==="set-playback-rate"){e.onSetPlaybackRate(Number(o.playbackRate??1));return}if(r==="enable-pick-mode"){e.onEnablePickMode();return}if(r==="disable-pick-mode"){e.onDisablePickMode();return}if(r==="flash-elements"){let i=o.selectors,u=o.duration||800;i&&An(i,u)}};return window.addEventListener("message",t),t}function An(e,t){if(!document.getElementById("__hf-flash-styles")){let n=document.createElement("style");n.id="__hf-flash-styles",n.textContent=`\n .__hf-flash {\n outline: 2px solid rgba(59, 130, 246, 0.6) !important;\n outline-offset: 2px !important;\n animation: __hf-flash-pulse ${t}ms ease-out forwards !important;\n }\n @keyframes __hf-flash-pulse {\n 0% { outline-color: rgba(59, 130, 246, 0.8); }\n 100% { outline-color: transparent; }\n }\n `,document.head.appendChild(n)}for(let n of e)try{document.querySelectorAll(n).forEach(r=>{r.classList.add("__hf-flash"),setTimeout(()=>r.classList.remove("__hf-flash"),t)})}catch{}}var et=null;function At(e){et=e}function Pe(e,t){if(et)try{et({source:"hf-preview",type:"analytics",event:e,properties:t??{}})}catch{}}function Et(e){let t=[],n=d=>{if(typeof d.getAnimations!="function")return[];try{return d.getAnimations()}catch{return[]}},o=(d,c)=>{for(let s of d){try{s.currentTime=c}catch{}try{s.pause()}catch{}}},r=d=>{for(let c of d)try{c.play()}catch{}},i=d=>{for(let c of d)try{c.pause()}catch{}},u=d=>{d.baseDelay?d.el.style.animationDelay=d.baseDelay:d.el.style.removeProperty("animation-delay"),d.basePlayState?d.el.style.animationPlayState=d.basePlayState:d.el.style.removeProperty("animation-play-state")};return{name:"css",discover:()=>{t=[];let d=document.querySelectorAll("*");for(let c of d){if(!(c instanceof HTMLElement))continue;let s=window.getComputedStyle(c);!s.animationName||s.animationName==="none"||t.push({el:c,baseDelay:c.style.animationDelay||"",basePlayState:c.style.animationPlayState||""})}},seek:d=>{let c=Number(d.time)||0;for(let s of t){if(!s.el.isConnected)continue;let a=e?.resolveStartSeconds?e.resolveStartSeconds(s.el):Number.parseFloat(s.el.getAttribute("data-start")??"0")||0,m=Math.max(0,c-a)*1e3,p=n(s.el);if(p.length>0){o(p,m);continue}s.el.style.animationPlayState="paused",s.el.style.animationDelay=`-${(m/1e3).toFixed(3)}s`}},pause:()=>{for(let d of t){if(!d.el.isConnected)continue;let c=n(d.el);c.length>0&&i(c),u(d)}},play:()=>{for(let d of t)d.el.isConnected&&(u(d),r(n(d.el)))},revert:()=>{t=[]}}}function yt(e){return{name:"gsap",discover:()=>{},seek:t=>{let n=e.getTimeline();if(!n)return;n.pause();let o=Math.max(0,Number(t.time)||0);typeof n.totalTime=="function"?n.totalTime(o,!1):n.seek(o,!1)},pause:()=>{let t=e.getTimeline();t&&t.pause()}}}function Ct(){return{name:"lottie",discover:()=>{try{let e=window.lottie;if(e&&typeof e.getRegisteredAnimations=="function"){let t=e.getRegisteredAnimations();if(Array.isArray(t)&&t.length>0){let n=window.__hfLottie??[],o=new Set(n);for(let r of t)o.has(r)||n.push(r);window.__hfLottie=n}}}catch{}},seek:e=>{let t=Math.max(0,Number(e.time)||0),n=window.__hfLottie;if(!(!n||n.length===0))for(let o of n)try{if(bt(o))o.goToAndStop(t*1e3,!1);else if(Mt(o)){if(typeof o.setCurrentRawFrameValue=="function"){let r=o.totalFrames??0,i=o.frameRate??30,u=t*i;r>0&&o.setCurrentRawFrameValue(Math.min(u,r-1))}else if(typeof o.seek=="function"){let r=o.duration??1,i=Math.min(100,t/r*100);o.seek(i)}}}catch{}},pause:()=>{let e=window.__hfLottie;if(!(!e||e.length===0))for(let t of e)try{(bt(t)||Mt(t))&&t.pause()}catch{}},revert:()=>{}}}function bt(e){return typeof e=="object"&&e!==null&&typeof e.goToAndStop=="function"}function Mt(e){return typeof e=="object"&&e!==null&&typeof e.pause=="function"&&("totalFrames"in e||"duration"in e)}function Dt(){let e=null,t=0;return{name:"three",discover:()=>{},seek:n=>{e=Math.max(0,Number(n.time)||0),t=e,window.__hfThreeTime=e;try{window.dispatchEvent(new CustomEvent("hf-seek",{detail:{time:e}}))}catch{}},pause:()=>{e==null&&(e=Math.max(0,t))},play:()=>{e=null},revert:()=>{e=null,t=0}}}function kt(){return{name:"waapi",discover:()=>{},seek:e=>{if(!document.getAnimations)return;let t=Math.max(0,(Number(e.time)||0)*1e3);for(let n of document.getAnimations()){try{n.currentTime=t}catch{}try{n.pause()}catch{}}},pause:()=>{if(document.getAnimations)for(let e of document.getAnimations())try{e.pause()}catch{}}}}function Lt(e){let t=Array.from(document.querySelectorAll("video[data-start], audio[data-start]")),n=[],o=[],r=0;for(let i of t){let u=e?.resolveStartSeconds?e.resolveStartSeconds(i):Number.parseFloat(i.dataset.start??"0");if(!Number.isFinite(u))continue;let d=Number.parseFloat(i.dataset.playbackStart??i.dataset.mediaStart??"0")||0,c=i.defaultPlaybackRate,s=Number.isFinite(c)&&c>0?Math.max(.1,Math.min(5,c)):1,a=i.loop,m=Number.isFinite(i.duration)&&i.duration>0?i.duration:null,p=Number.parseFloat(i.dataset.duration??"");(!Number.isFinite(p)||p<=0)&&m!=null&&(p=Math.max(0,(m-d)/s));let F=Number.isFinite(p)&&p>0?u+p:Number.POSITIVE_INFINITY,D=Number.parseFloat(i.dataset.volume??""),C={el:i,start:u,mediaStart:d,duration:Number.isFinite(p)&&p>0?p:Number.POSITIVE_INFINITY,end:F,volume:Number.isFinite(D)?D:null,playbackRate:s,loop:a,sourceDuration:m};n.push(C),i.tagName==="VIDEO"&&o.push(C),Number.isFinite(F)&&(r=Math.max(r,F))}return{timedMediaEls:t,mediaClips:n,videoClips:o,maxMediaEnd:r}}var tt=new WeakMap,Oe=new WeakSet;function En(e){if(Oe.has(e))return;Oe.add(e);let t=()=>Oe.delete(e);e.addEventListener("playing",t,{once:!0}),e.addEventListener("pause",t,{once:!0}),e.addEventListener("error",t,{once:!0})}function Tt(e){let t=!!(e.outputMuted||e.userMuted);for(let n of e.clips){let{el:o}=n;if(!o.isConnected)continue;let r=(e.timeSeconds-n.start)*n.playbackRate+n.mediaStart;if(e.timeSeconds>=n.start&&e.timeSeconds<n.end&&r>=0){if(n.loop&&n.sourceDuration!=null&&n.sourceDuration>0){let F=n.sourceDuration-n.mediaStart;F>0&&r>=n.sourceDuration&&(r=n.mediaStart+(r-n.mediaStart)%F)}n.volume!=null&&(o.volume=n.volume),t&&(o.muted=!0);try{o.playbackRate=n.playbackRate*e.playbackRate}catch{}let u=o.currentTime||0,d=Math.abs(u-r),c=r-u,s=tt.get(o);tt.set(o,c);let a=s===void 0,m=!a&&Math.abs(c-s)>.5,p=d>3;if(d>.5&&(a||m||p))try{o.currentTime=r}catch{}e.playing&&o.paused&&!Oe.has(o)?(o.preload!=="auto"&&(o.preload="auto"),En(o),o.play().catch(F=>{Oe.delete(o),(F&&typeof F=="object"&&"name"in F?String(F.name??""):"")==="NotAllowedError"&&e.onAutoplayBlocked?.()})):!e.playing&&!o.paused&&o.pause();continue}tt.delete(o),o.paused||o.pause()}}function wt(e){let t=!1,n=null,o=null,r=null,i=null;function u(S,x){try{window.dispatchEvent(new CustomEvent(S,{detail:x}))}catch{}}function d(S){r=S,u("hyperframe:picker:hovered",{elementInfo:r,isPickMode:t,timestamp:Date.now()})}function c(S){i=S,u("hyperframe:picker:selected",{elementInfo:i,isPickMode:t,timestamp:Date.now()})}function s(S){if(!S||S===document.body||S===document.documentElement)return!1;let x=S.tagName.toLowerCase();return!(x==="script"||x==="style"||x==="link"||x==="meta"||S.classList.contains("__hf-pick-highlight"))}function a(S){let x=S;if(x.id)return`#${x.id}`;let g=S.getAttribute("data-composition-id");if(g)return`[data-composition-id="${g}"]`;let E=S.getAttribute("data-composition-src");if(E)return`[data-composition-src="${E}"]`;let b=S.getAttribute("data-track-index");if(b)return`[data-track-index="${b}"]`;let y=S.tagName.toLowerCase(),v=S.parentElement;if(!v)return y;let _=v.querySelectorAll(`:scope > ${y}`);if(_.length===1)return y;for(let O=0;O<_.length;O+=1)if(_[O]===S)return`${y}:nth-of-type(${O+1})`;return y}function m(S){let x=S.tagName.toLowerCase(),g=(S.textContent??"").trim().replace(/\\s+/g," "),E=(b,y)=>b.length>y?`${b.slice(0,y-1)}\\u2026`:b;return x==="h1"||x==="h2"||x==="h3"?"Heading":x==="p"||x==="span"||x==="div"?g.length>0?E(g,56):"Text":x==="img"?"Image":x==="video"?"Video":x==="audio"?"Audio":x==="svg"?"Shape":S.getAttribute("data-composition-src")?"Composition":x==="section"?"Section":`${x.charAt(0).toUpperCase()}${x.slice(1)}`}function p(S,x,g){let E=typeof g=="number"&&g>0?g:8,b=[];if(document.elementsFromPoint)b=document.elementsFromPoint(S,x);else if(document.elementFromPoint){let _=document.elementFromPoint(S,x);b=_?[_]:[]}let y={},v=[];for(let _=0;_<b.length;_+=1){let O=b[_];if(!s(O))continue;let V=`${O.tagName}::${O.id||""}::${_}`;if(!y[V]&&(y[V]=!0,v.push(O),v.length>=E))break}return v}function F(S){let x=S.getBoundingClientRect(),g={};for(let b=0;b<S.attributes.length;b+=1){let y=S.attributes[b];y.name.startsWith("data-")&&(g[y.name]=y.value)}return{id:S.id||null,tagName:S.tagName.toLowerCase(),selector:a(S),label:m(S),boundingBox:{x:x.left,y:x.top,width:x.width,height:x.height},textContent:S.textContent?S.textContent.trim().slice(0,200):null,src:S.getAttribute("src")||S.getAttribute("data-composition-src")||null,dataAttributes:g}}function D(S,x,g){return p(S,x,g).map(F)}function C(S){if(!t)return;let g=p(S.clientX,S.clientY,1)[0]??(S.target instanceof Element?S.target:null);if(!s(g)||n===g)return;n&&n.classList.remove("__hf-pick-highlight"),n=g,g.classList.add("__hf-pick-highlight");let E=F(g);d(E),e.postMessage({source:"hf-preview",type:"element-hovered",elementInfo:E})}function T(S){if(!t)return;S.preventDefault(),S.stopPropagation(),S.stopImmediatePropagation();let x=D(S.clientX,S.clientY,8);x.length!==0&&(d(x[0]??null),e.postMessage({source:"hf-preview",type:"element-pick-candidates",candidates:x,selectedIndex:0,point:{x:S.clientX,y:S.clientY}}))}function U(S){S.key==="Escape"&&(k(),e.postMessage({source:"hf-preview",type:"pick-mode-cancelled"}))}function z(){t||(t=!0,o=document.createElement("style"),o.textContent=[".__hf-pick-highlight { outline: 2px solid #4f8cf7 !important; outline-offset: 2px; cursor: crosshair !important; }",".__hf-pick-active * { cursor: crosshair !important; }"].join(`\n`),document.head.appendChild(o),document.body.classList.add("__hf-pick-active"),document.addEventListener("mousemove",C,!0),document.addEventListener("click",T,!0),document.addEventListener("keydown",U,!0),u("hyperframe:picker:mode",{isPickMode:!0,timestamp:Date.now()}))}function k(){t&&(t=!1,n&&(n.classList.remove("__hf-pick-highlight"),n=null),o&&(o.remove(),o=null),document.body.classList.remove("__hf-pick-active"),document.removeEventListener("mousemove",C,!0),document.removeEventListener("click",T,!0),document.removeEventListener("keydown",U,!0),u("hyperframe:picker:mode",{isPickMode:!1,timestamp:Date.now()}))}function Q(){window.__HF_PICKER_API={enable:z,disable:k,isActive:()=>t,getHovered:()=>r,getSelected:()=>i,getCandidatesAtPoint:(S,x,g)=>Number.isFinite(S)&&Number.isFinite(x)?D(S,x,g):[],pickAtPoint:(S,x,g)=>{if(!Number.isFinite(S)||!Number.isFinite(x))return null;let E=D(S,x,8);if(!E.length)return null;let b=Math.max(0,Math.min(E.length-1,Number(g??0))),y=E[b]??null;return y?(c(y),e.postMessage({source:"hf-preview",type:"element-picked",elementInfo:y}),k(),y):null},pickManyAtPoint:(S,x,g)=>{if(!Number.isFinite(S)||!Number.isFinite(x))return[];let E=D(S,x,8);if(!E.length)return[];let b=[],y=Array.isArray(g)?g:[0];for(let v of y){let _=Math.max(0,Math.min(E.length-1,Math.floor(Number(v)))),O=E[_];if(!O)continue;b.some(w=>w.selector===O.selector&&w.tagName===O.tagName)||b.push(O)}return b.length?(c(b[0]??null),e.postMessage({source:"hf-preview",type:"element-picked-many",elementInfos:b}),k(),b):[]}},u("hyperframe:picker:api-ready",{hasApi:!0,timestamp:Date.now()})}return{enablePickMode:z,disablePickMode:k,installPickerApi:Q}}function nt(e,t){let n=Number.isFinite(t)&&t>0?t:30,o=Number.isFinite(e)&&e>0?e:0;return Math.floor(o*n+1e-9)/n}function Ue(e,t,n){if(e){for(let o of Object.values(e))if(!(!o||o===t))try{n(o)}catch{}}}function Bt(e,t,n){let o=nt(t,n);return e.pause(),typeof e.totalTime=="function"?e.totalTime(o,!1):e.seek(o,!1),o}function yn(e,t,n,o){let r=[];Ue(e,t,i=>{i.play(),r.push(i)});try{return Bt(t,n,o)}finally{for(let i of r)try{i.pause()}catch{}}}function bn(e,t){Ue(e,t,n=>{n.play()})}function Rt(e){return{_timeline:null,play:()=>{let t=e.getTimeline();if(!t||e.getIsPlaying())return;let n=Math.max(0,Number(e.getSafeDuration?.()??t.duration()??0)||0);n>0&&Math.max(0,Number(t.time())||0)>=n&&(t.pause(),t.seek(0,!1),e.onDeterministicSeek(0),e.setIsPlaying(!1),e.onSyncMedia(0,!1),e.onRenderFrameSeek(0)),typeof t.timeScale=="function"&&t.timeScale(e.getPlaybackRate()),t.play(),Ue(e.getTimelineRegistry?.(),t,o=>{typeof o.timeScale=="function"&&o.timeScale(e.getPlaybackRate()),o.play()}),e.onDeterministicPlay(),e.setIsPlaying(!0),e.onShowNativeVideos(),e.onStatePost(!0)},pause:()=>{let t=e.getTimeline();if(!t)return;t.pause(),Ue(e.getTimelineRegistry?.(),t,o=>{o.pause()});let n=Math.max(0,Number(t.time())||0);e.onDeterministicSeek(n),e.onDeterministicPause(),e.setIsPlaying(!1),e.onSyncMedia(n,!1),e.onRenderFrameSeek(n),e.onStatePost(!0)},seek:t=>{let n=e.getTimeline();if(!n)return;let o=Math.max(0,Number(t)||0),r=yn(e.getTimelineRegistry?.(),n,o,e.getCanonicalFps());e.onDeterministicSeek(r),e.setIsPlaying(!1),e.onSyncMedia(r,!1),e.onRenderFrameSeek(r),e.onStatePost(!0)},renderSeek:t=>{let n=e.getTimeline(),o=e.getCanonicalFps(),r=n?(bn(e.getTimelineRegistry?.(),n),Bt(n,t,o)):nt(Math.max(0,Number(t)||0),o);e.onDeterministicSeek(r),e.setIsPlaying(!1),e.onSyncMedia(r,!1),e.onRenderFrameSeek(r),e.onStatePost(!0)},getTime:()=>Number(e.getTimeline()?.time()??0),getDuration:()=>Number(e.getTimeline()?.duration()??0),isPlaying:()=>e.getIsPlaying(),setPlaybackRate:t=>e.setPlaybackRate(t),getPlaybackRate:()=>e.getPlaybackRate()}}function vt(){return{capturedTimeline:null,isPlaying:!1,rafId:null,currentTime:0,deterministicAdapters:[],parityModeEnabled:!0,canonicalFps:30,bridgeMuted:!1,mediaOutputMuted:!1,mediaAutoplayBlockedPosted:!1,playbackRate:1,bridgeLastPostedFrame:-1,bridgeLastPostedAt:0,bridgeLastPostedPlaying:!1,bridgeLastPostedMuted:!1,bridgeMaxPostIntervalMs:80,timelinePollIntervalId:null,controlBridgeHandler:null,clampDurationLoggedRaw:null,beforeUnloadHandler:null,domReadyHandler:null,injectedCompStyles:[],injectedCompScripts:[],cachedTimedMediaEls:[],cachedMediaClips:[],cachedVideoClips:[],cachedMediaTimelineDurationSeconds:0,tornDown:!1,maxTimelineDurationSeconds:1800,nativeVisualWatchdogTick:0}}var Mn="data-hf-authored-duration",Cn="data-hf-authored-end";function De(e){if(e==null||e==="")return null;let t=Number(e);return Number.isFinite(t)?t:null}function Dn(e){return De(e.getAttribute("data-duration"))}function kn(e){return De(e.getAttribute("data-end"))}function Ln(e){return De(e.getAttribute(Mn))}function Tn(e){return De(e.getAttribute(Cn))}function wn(e){let t=(e??"").trim();if(!t)return null;let n=De(t);if(n!=null)return{kind:"absolute",value:n};let o=t.match(/^([A-Za-z0-9_.:-]+)(?:\\s*([+-])\\s*([0-9]*\\.?[0-9]+))?$/);if(!o)return null;let r=(o[1]??"").trim();if(!r)return null;let i=o[2]??"+",u=o[3]??"0",d=Number.parseFloat(u),c=Number.isFinite(d)?Math.max(0,d):0,s=i==="-"?-c:c;return{kind:"reference",refId:r,offset:s}}function we(e){let t=e.timelineRegistry??{},n=e.includeAuthoredTimingAttrs??!1,o=new WeakMap,r=new WeakMap,i=new Set,u=a=>{let m=document.getElementById(a);return m||(document.querySelector(`[data-composition-id="${CSS.escape(a)}"]`)??null)},d=a=>{let m=r.get(a);if(m!==void 0)return m;let p=null,F=Dn(a)??(n?Ln(a):null);if(F!=null&&F>0&&(p=F),p==null||p<=0){let D=kn(a)??(n?Tn(a):null);if(D!=null){let C=s(a,0),T=D-C;Number.isFinite(T)&&T>0&&(p=T)}}if((p==null||p<=0)&&a instanceof HTMLMediaElement){let D=De(a.getAttribute("data-playback-start"))??De(a.getAttribute("data-media-start"))??0;Number.isFinite(a.duration)&&a.duration>D&&(p=a.duration-D)}if(p==null||p<=0){let D=a.getAttribute("data-composition-id");if(D){let C=t[D]??null;if(C&&typeof C.duration=="function")try{let T=Number(C.duration());Number.isFinite(T)&&T>0&&(p=T)}catch{}}}return p!=null&&Number.isFinite(p)&&p>0?(r.set(a,p),p):(r.set(a,null),null)},c=(a,m)=>{if(a.hasAttribute("data-composition-id")){let F=a.parentElement?.closest("[data-composition-id]");return F?s(F,m):0}let p=a.closest("[data-composition-id]");return p?s(p,m):0},s=(a,m)=>{let p=o.get(a);if(p!==void 0)return p??m;if(i.has(a))return m;i.add(a);try{let F=wn(a.getAttribute("data-start"));if(!F){if(a.hasAttribute("data-composition-id")){let z=a.parentElement;if(z&&(z.hasAttribute("data-composition-src")||z.hasAttribute("data-composition-id"))){let k=s(z,m);return o.set(a,k),k}}return o.set(a,m),m}if(F.kind==="absolute"){let z=Math.max(0,F.value),k=Math.max(0,c(a,m)+z);return o.set(a,k),k}let D=u(F.refId);if(!D)return o.set(a,m),m;let C=s(D,0),T=d(D);if(T==null||T<=0){let z=Math.max(0,C+F.offset);return o.set(a,z),z}let U=Math.max(0,C+T+F.offset);return o.set(a,U),U}finally{i.delete(a)}};return{resolveStartForElement:(a,m=0)=>s(a,Math.max(0,m)),resolveDurationForElement:a=>d(a)}}var Bn="data-hf-authored-duration",Rn="data-hf-authored-end";function fe(e){if(e==null||e==="")return null;let t=Number(e);return Number.isFinite(t)?t:null}function it(e){return fe(e.getAttribute("data-duration"))??fe(e.getAttribute(Bn))}function It(e){return fe(e.getAttribute("data-end"))??fe(e.getAttribute(Rn))}function ot(...e){let t=e.filter(n=>Number.isFinite(n??null));return t.length===0?null:Math.max(...t)}var Pt={composition:0,video:1,image:2,element:3,audio:4};function vn(e){if(e.length===0)return;let t=new Map;for(let u of e){let d=t.get(u.track)??new Set;d.add(u.kind),t.set(u.track,d)}if(!Array.from(t.values()).some(u=>u.size>1))return;let o=0,r=new Map,i=[...t.keys()].sort((u,d)=>u-d);for(let u of i){let d=t.get(u);if(d.size===1)r.set(`${u}:${[...d][0]}`,o++);else{let c=[...d].sort((s,a)=>(Pt[s]??99)-(Pt[a]??99));for(let s of c)r.set(`${u}:${s}`,o++)}}for(let u of e){let d=`${u.track}:${u.kind}`,c=r.get(d);c!=null&&(u.track=c)}}function _e(e){let t=String(e??"").trim();if(!t)return null;let n=t.toLowerCase();if(n.startsWith("data:")||n.startsWith("javascript:"))return null;try{return new URL(t,document.baseURI).toString()}catch{return t}}function In(e){let t=e.getAttribute("src")??e.getAttribute("data-src");if(t)return _e(t);let n=e.getAttribute("data-composition-src");if(n)return _e(n);let o=e.querySelector("img[src], video[src], audio[src], source[src]");return o?_e(o.getAttribute("src")):null}function Ot(e){let n=window.__timelines??{},o=we({timelineRegistry:n,includeAuthoredTimingAttrs:!0}),r=B=>{if(!B)return null;let M=n[B]??null;if(!M||typeof M.duration!="function")return null;try{let L=Number(M.duration());return Number.isFinite(L)&&L>0?L:null}catch{return null}},i=B=>{let M=fe(B.getAttribute("data-duration"));if(M!=null&&M>0)return M;let L=fe(B.getAttribute("data-playback-start"))??fe(B.getAttribute("data-media-start"))??0;return Number.isFinite(B.duration)&&B.duration>L?Math.max(0,B.duration-L):null},u=()=>{let B=Array.from(document.querySelectorAll("video[data-start], audio[data-start]"));if(B.length===0)return null;let M=0;for(let L of B){let J=o.resolveStartForElement(L,0);if(!Number.isFinite(J))continue;let X=i(L);X==null||X<=0||(M=Math.max(M,Math.max(0,J)+X))}return M>0?M:null},d=B=>{let M=B.trim().toLowerCase();return!(!M||M==="main"||M.includes("caption")||M.includes("ambient"))},c=(B,M)=>{let L=[],J=null,X=null,I=null,P=B.parentElement;for(;P;){let H=P.getAttribute("data-composition-id");H&&(L.push(H),!I&&P!==M&&(I=H),J==null&&(J=o.resolveStartForElement(P,0)),X==null&&(X=fe(P.getAttribute("data-duration"))??r(H)??null)),P=P.parentElement}return{parentCompositionId:I,compositionAncestors:L.reverse(),inheritedStart:J,inheritedDuration:X}},s=document.querySelector("[data-composition-id]"),a=Array.from(document.querySelectorAll("[data-composition-id]")),m=s?.getAttribute("data-composition-id")??null,p=s?o.resolveStartForElement(s,0):0,F=u(),D=F!=null?Math.max(0,F-Math.max(0,p)):null,C=r(m),T=it(s??document.body),U=ot(...a.filter(B=>B!==s).map(B=>{let M=o.resolveStartForElement(B,0),L=o.resolveDurationForElement(B)??r(B.getAttribute("data-composition-id"))??null;return!Number.isFinite(M)||L==null||L<=0?null:Math.max(0,M)+L})),z=U!=null?Math.max(0,U-Math.max(0,p)):null,k=typeof C=="number"&&Number.isFinite(C)&&C>0?C:null,Q=typeof T=="number"&&Number.isFinite(T)&&T>0?T:null,S=typeof D=="number"&&Number.isFinite(D)&&D>0?D:null,x=typeof z=="number"&&Number.isFinite(z)&&z>0?z:null,g=ot(S,x),E=k!=null&&g!=null&&k>g+1,b=Q??(E?g:ot(k,S,x)),y=b!=null?Math.min(b,e.maxTimelineDurationSeconds):null,_=(y!=null?p+y:null)??(typeof F=="number"&&Number.isFinite(F)&&F>0?F:null),O=(B,M)=>!Number.isFinite(M)||M<=0?0:_==null||!Number.isFinite(_)?M:!Number.isFinite(B)||B>=_?0:Math.max(0,Math.min(M,_-B)),V=[],w=[],K=Array.from(document.querySelectorAll("[data-start], [data-track-index], [data-composition-id], video, audio, img")),Z=0;for(let B=0;B<K.length;B+=1){let M=K[B];if(M===s||["SCRIPT","STYLE","LINK","META","TEMPLATE","NOSCRIPT"].includes(M.tagName))continue;let L=c(M,s),J=o.resolveStartForElement(M,L.inheritedStart??0),X=M.getAttribute("data-composition-id"),I=it(M);if((I==null||I<=0)&&X&&X!==m&&(I=r(X)),(I==null||I<=0)&&M instanceof HTMLMediaElement){let de=fe(M.getAttribute("data-playback-start"))??fe(M.getAttribute("data-media-start"))??0;Number.isFinite(M.duration)&&M.duration>0&&(I=Math.max(0,M.duration-de))}if(I==null||I<=0){let de=L.inheritedDuration;if(de!=null&&de>0){let he=(L.inheritedStart??0)+de;I=Math.max(0,he-J)}}if(I==null||I<=0||(I=O(J,I),I<=0))continue;let P=J+I;Z=Math.max(Z,P);let H=M.tagName.toLowerCase(),ce=X&&X!==m?"composition":H==="video"?"video":H==="audio"?"audio":H==="img"?"image":"element";V.push({id:M.id||X||`__node__index_${B}`,label:M.getAttribute("data-timeline-label")??M.getAttribute("data-label")??M.getAttribute("aria-label")??X??M.id??M.className?.split(" ")[0]??ce,start:J,duration:I,track:Number.parseInt(M.getAttribute("data-track-index")??M.getAttribute("data-track")??String(B),10)||0,kind:ce,tagName:H,compositionId:M.getAttribute("data-composition-id"),compositionAncestors:L.compositionAncestors,parentCompositionId:L.parentCompositionId,nodePath:null,compositionSrc:_e(M.getAttribute("data-composition-src")),assetUrl:In(M),timelineRole:M.getAttribute("data-timeline-role"),timelineLabel:M.getAttribute("data-timeline-label"),timelineGroup:M.getAttribute("data-timeline-group"),timelinePriority:fe(M.getAttribute("data-timeline-priority"))})}let W=new Set(V.map(B=>B.id)),j=s?.getAttribute("data-composition-id")??null,R=j?n[j]??null:null;if(R&&s){let B=R;if(typeof B.getChildren=="function")try{let M=B.getChildren(!0,!0,!1)??[],L=new Map;for(let I of s.children){let P=I;if(!P.id)continue;let H=P.tagName.toLowerCase();H==="script"||H==="style"||H==="link"||L.set(P,{id:P.id,start:1/0,end:-1/0})}let J=I=>{let P=I;for(;P;){if(L.has(P))return P;if(P===s)return null;P=P.parentElement}return null};for(let I of M){if(typeof I.targets!="function"||typeof I.startTime!="function"||typeof I.duration!="function")continue;let P=I.startTime(),H=I.parent;for(;H&&typeof H.startTime=="function";)P+=H.startTime(),H=H.parent;let ce=P+I.duration();if(!(!Number.isFinite(P)||!Number.isFinite(ce)))for(let de of I.targets()){if(!(de instanceof Element))continue;let Ae=J(de);if(!Ae)continue;let he=L.get(Ae);he&&(he.start=Math.min(he.start,P),he.end=Math.max(he.end,ce))}}let X=V.length>0?Math.max(...V.map(I=>I.track))+1:0;for(let[I,P]of L){if(P.start===1/0||P.end===-1/0)continue;let H=I;if(W.has(H.id))continue;let ce=Math.max(0,P.end-P.start);if(ce<=0)continue;let de=O(P.start,ce);de<=0||(Z=Math.max(Z,P.start+de),V.push({id:H.id,label:H.getAttribute("data-timeline-label")??H.getAttribute("data-label")??H.getAttribute("aria-label")??H.id,start:P.start,duration:de,track:Number.parseInt(H.getAttribute("data-track-index")??H.getAttribute("data-track")??"",10)||X,kind:"element",tagName:H.tagName.toLowerCase(),compositionId:H.getAttribute("data-composition-id"),compositionAncestors:j?[j]:[],parentCompositionId:j,nodePath:null,compositionSrc:null,assetUrl:null,timelineRole:H.getAttribute("data-timeline-role"),timelineLabel:H.getAttribute("data-timeline-label"),timelineGroup:H.getAttribute("data-timeline-group"),timelinePriority:fe(H.getAttribute("data-timeline-priority"))}),W.add(H.id))}}catch{}}if(s&&y!=null&&y>0){let B=V.length>0?Math.max(...V.map(M=>M.track))+1:0;for(let M of s.children){let L=M;if(!L.id||W.has(L.id))continue;let J=L.getAttribute("data-timeline-role");if(J!=="overlay"&&J!=="persistent-overlay")continue;let X=L.tagName.toLowerCase();if(X==="script"||X==="style"||X==="link"||X==="meta"||window.getComputedStyle(L).display==="none")continue;let P=O(0,y);P<=0||(Z=Math.max(Z,P),V.push({id:L.id,label:L.getAttribute("data-timeline-label")??L.getAttribute("data-label")??L.getAttribute("aria-label")??L.id,start:0,duration:P,track:Number.parseInt(L.getAttribute("data-track-index")??L.getAttribute("data-track")??"",10)||B,kind:"element",tagName:X,compositionId:L.getAttribute("data-composition-id"),compositionAncestors:j?[j]:[],parentCompositionId:j,nodePath:null,compositionSrc:null,assetUrl:null,timelineRole:J,timelineLabel:L.getAttribute("data-timeline-label"),timelineGroup:L.getAttribute("data-timeline-group"),timelinePriority:fe(L.getAttribute("data-timeline-priority"))}),W.add(L.id))}}vn(V);for(let B of a){if(B===s)continue;let M=B.getAttribute("data-composition-id");if(!M||!d(M))continue;let L=o.resolveStartForElement(B,0),J=it(B);if((J==null||J<=0)&&It(B)!=null){let H=It(B);J=Math.max(0,H-L)}let X=r(M),I=J&&J>0?J:X;if(I==null||I<=0)continue;let P=O(L,I);P<=0||w.push({id:M,label:B.getAttribute("data-label")??M,start:L,duration:P,thumbnailUrl:_e(B.getAttribute("data-thumbnail-url")),avatarName:null})}let $=Math.max(1,Math.min(Math.max(Z||1,y??0),e.maxTimelineDurationSeconds));return{source:"hf-preview",type:"timeline",durationInFrames:E&&Q==null?Number.POSITIVE_INFINITY:Math.max(1,Math.round($*Math.max(1,e.canonicalFps))),clips:V,scenes:w,compositionWidth:fe(s?.getAttribute("data-width"))??1920,compositionHeight:fe(s?.getAttribute("data-height"))??1080}}var Pn=/^(?![a-zA-Z][a-zA-Z\\d+\\-.]*:)(?!\\/\\/)(?!\\/)(?!\\.\\.?\\/).+/,On=e=>new Promise(t=>{let n=!1,o=Date.now(),r=null,i=u=>{n||(n=!0,r!=null&&window.clearTimeout(r),t({status:u,elapsedMs:Math.max(0,Date.now()-o)}))};e.addEventListener("load",()=>i("load"),{once:!0}),e.addEventListener("error",()=>i("error"),{once:!0}),r=window.setTimeout(()=>i("timeout"),8e3)});function rt(e){for(;e.firstChild;)e.removeChild(e.firstChild);e.textContent=""}function _t(e,t){let n=e.trim();if(!n)return e;try{return Pn.test(n)?new URL(n,document.baseURI).toString():t?new URL(n,t).toString():new URL(n,document.baseURI).toString()}catch{return e}}async function st(e){let t=null;e.hostCompositionId&&(t=Array.from(e.sourceNode.querySelectorAll("[data-composition-id]")).find(s=>s.getAttribute("data-composition-id")===e.hostCompositionId)??null);let n=t??e.sourceNode;if(e.headStyles)for(let c of e.headStyles){let s=c.cloneNode(!0);s instanceof HTMLStyleElement&&(document.head.appendChild(s),e.injectedStyles.push(s))}let o=Array.from(n.querySelectorAll("style"));for(let c of o){let s=c.cloneNode(!0);s instanceof HTMLStyleElement&&(document.head.appendChild(s),e.injectedStyles.push(s))}let r=[];if(e.headScripts)for(let c of e.headScripts){let s=c.getAttribute("type")?.trim()??"",a=c.getAttribute("src")?.trim()??"";if(a){let m=_t(a,e.compositionUrl);r.push({kind:"external",src:m,type:s})}else{let m=c.textContent?.trim()??"";m&&r.push({kind:"inline",content:m,type:s})}}let i=Array.from(n.querySelectorAll("script")),u=[...r];for(let c of i){let s=c.getAttribute("type")?.trim()??"",a=c.getAttribute("src")?.trim()??"";if(a){let m=_t(a,e.compositionUrl);u.push({kind:"external",src:m,type:s})}else{let m=c.textContent?.trim()??"";m&&u.push({kind:"inline",content:m,type:s})}c.parentNode?.removeChild(c)}let d=Array.from(n.querySelectorAll("style"));for(let c of d)c.parentNode?.removeChild(c);if(t){let c=document.importNode(t,!0),s=t.getAttribute("data-width"),a=t.getAttribute("data-height"),m=e.parseDimensionPx(s),p=e.parseDimensionPx(a);c.style.position="relative",c.style.width=m||"100%",c.style.height=p||"100%",m&&c.style.setProperty("--comp-width",m),p&&c.style.setProperty("--comp-height",p),s&&e.host.setAttribute("data-width",s),a&&e.host.setAttribute("data-height",a),m&&e.host instanceof HTMLElement&&(e.host.style.width=m),p&&e.host instanceof HTMLElement&&(e.host.style.height=p),e.host.appendChild(c)}else e.hasTemplate?e.host.appendChild(document.importNode(n,!0)):e.host.innerHTML=e.fallbackBodyInnerHtml;for(let c of u){let s=document.createElement("script");if(c.type&&(s.type=c.type),s.async=!1,c.kind==="external"?s.src=c.src:c.type.toLowerCase()==="module"?s.textContent=c.content:s.textContent=`(function(){${c.content}})();`,document.body.appendChild(s),e.injectedScripts.push(s),c.kind==="external"){let a=await On(s);a.status!=="load"&&e.onDiagnostic?.({code:"external_composition_script_load_issue",details:{hostCompositionId:e.hostCompositionId,hostCompositionSrc:e.hostCompositionSrc,resolvedScriptSrc:c.src,loadStatus:a.status,elapsedMs:a.elapsedMs}})}}}async function Wt(e){let t=Array.from(document.querySelectorAll("[data-composition-id]:not([data-composition-src])")).filter(n=>{if(n.children.length>0)return!1;let o=n.getAttribute("data-composition-id");return o?!!document.querySelector(`template#${CSS.escape(o)}-template`):!1});if(t.length!==0)for(let n of t){let o=n.getAttribute("data-composition-id"),r=document.querySelector(`template#${CSS.escape(o)}-template`);rt(n),await st({host:n,hostCompositionId:o,hostCompositionSrc:`template#${o}-template`,sourceNode:r.content,hasTemplate:!0,fallbackBodyInnerHtml:"",compositionUrl:null,injectedStyles:e.injectedStyles,injectedScripts:e.injectedScripts,parseDimensionPx:e.parseDimensionPx,onDiagnostic:e.onDiagnostic})}}async function Ht(e){let t=Array.from(document.querySelectorAll("[data-composition-src]"));t.length!==0&&await Promise.all(t.map(async n=>{let o=n.getAttribute("data-composition-src");if(!o)return;let r=null;try{r=new URL(o,document.baseURI)}catch{r=null}rt(n);try{let i=n.getAttribute("data-composition-id"),u=i!=null?document.querySelector(`template#${CSS.escape(i)}-template`):null;if(u){await st({host:n,hostCompositionId:i,hostCompositionSrc:o,sourceNode:u.content,hasTemplate:!0,fallbackBodyInnerHtml:"",compositionUrl:r,injectedStyles:e.injectedStyles,injectedScripts:e.injectedScripts,parseDimensionPx:e.parseDimensionPx,onDiagnostic:e.onDiagnostic});return}let d=await fetch(o);if(!d.ok)throw new Error(`HTTP ${d.status}`);let c=await d.text(),a=new DOMParser().parseFromString(c,"text/html"),m=(i?a.querySelector(`template#${CSS.escape(i)}-template`):null)??a.querySelector("template"),p=m?m.content:a.body,F=m?void 0:Array.from(a.head.querySelectorAll("style")),D=m?void 0:Array.from(a.head.querySelectorAll("script"));await st({host:n,hostCompositionId:i,hostCompositionSrc:o,sourceNode:p,hasTemplate:!!m,fallbackBodyInnerHtml:a.body.innerHTML,compositionUrl:r,injectedStyles:e.injectedStyles,injectedScripts:e.injectedScripts,parseDimensionPx:e.parseDimensionPx,headStyles:F,headScripts:D,onDiagnostic:e.onDiagnostic})}catch(i){e.onDiagnostic?.({code:"external_composition_load_failed",details:{hostCompositionId:n.getAttribute("data-composition-id"),hostCompositionSrc:o,errorMessage:i instanceof Error?i.message:"unknown_error"}}),rt(n)}}))}function at(){let e=window.gsap;e&&document.querySelectorAll(".caption-group").length!==0&&fetch("caption-overrides.json").then(t=>t.ok?t.json():null).then(t=>{if(!t||!Array.isArray(t)||t.length===0)return;let n=[],o=document.querySelectorAll(".caption-group");for(let r of o){let i=r.querySelectorAll(":scope > span");for(let u of i)n.push(u)}for(let r of t){let i=null;if(r.wordId&&(i=document.getElementById(r.wordId)),!i&&r.wordIndex!==void 0&&(i=n[r.wordIndex]??null),!i||!(i instanceof HTMLElement))continue;let u={},d={};if(r.x!==void 0&&(u.x=r.x),r.y!==void 0&&(u.y=r.y),r.scale!==void 0&&(u.scale=r.scale),r.rotation!==void 0&&(u.rotation=r.rotation),r.opacity!==void 0&&(d.opacity=r.opacity),r.fontSize!==void 0&&(d.fontSize=`${r.fontSize}px`),r.fontWeight!==void 0&&(d.fontWeight=r.fontWeight),r.fontFamily!==void 0&&(d.fontFamily=r.fontFamily),r.activeColor||r.dimColor){let s=e.getTweensOf(i).filter(m=>m.vars.color!==void 0).sort((m,p)=>m.startTime()-p.startTime()),a=s.length>0?String(s[0].vars.color):"";for(let m of s)String(m.vars.color)===a?r.dimColor&&(m.vars.color=r.dimColor):r.activeColor&&(m.vars.color=r.activeColor);r.dimColor&&e.set(i,{color:r.dimColor})}if(Object.keys(d).length>0&&e.set(i,d),Object.keys(u).length>0){let c=document.createElement("span");c.style.display="inline-block",c.dataset.captionWrapper="true",i.parentNode?.insertBefore(c,i),c.appendChild(i),e.set(c,u)}}}).catch(()=>{})}var jt="data-hf-authored-duration",zt="data-hf-authored-end";function Ut(){let e=vt(),t=window,n=null,o=null,r=[],i=new Set,u=null;if(typeof t.__hfRuntimeTeardown=="function")try{t.__hfRuntimeTeardown()}catch{}document.documentElement&&(document.documentElement.style.margin="0",document.documentElement.style.padding="0",document.documentElement.style.overflow="hidden"),document.body&&(document.body.style.margin="0",document.body.style.padding="0",document.body.style.overflow="hidden"),window.__timelines=window.__timelines||{};let d=l=>{r.push(l)},c=(l,h,f)=>{let A=f??`${l}:${JSON.stringify(h)}`;i.has(A)||(i.add(A),xe({source:"hf-preview",type:"diagnostic",code:l,details:h}))},s=l=>{let h={scale:1,focusX:960,focusY:540},f=[],A=[],N={time:l.getTime(),duration:l.getDuration(),isPlaying:l.isPlaying(),renderMode:!1,timelineDirty:!1};return{play:l.play,pause:l.pause,seek:l.seek,getTime:l.getTime,getDuration:l.getDuration,isPlaying:l.isPlaying,getMainTimeline:()=>null,getElementBounds:()=>{},getElementsAtPoint:()=>{},setElementPosition:()=>{},previewElementPosition:()=>{},setElementKeyframes:()=>{},setElementScale:()=>{},setElementFontSize:()=>{},setElementTextContent:()=>{},setElementTextColor:()=>{},setElementTextShadow:()=>{},setElementTextFontWeight:()=>{},setElementTextFontFamily:()=>{},setElementTextOutline:()=>{},setElementTextHighlight:()=>{},setElementVolume:()=>{},setStageZoom:()=>{},getStageZoom:()=>h,setStageZoomKeyframes:()=>{},getStageZoomKeyframes:()=>f,addElement:()=>!1,removeElement:()=>!1,updateElementTiming:()=>!1,setElementTiming:()=>{},updateElementSrc:()=>!1,updateElementLayer:()=>!1,updateElementBasePosition:()=>!1,markTimelineDirty:()=>{},isTimelineDirty:()=>!1,rebuildTimeline:()=>{},ensureTimeline:()=>{},enableRenderMode:()=>{},disableRenderMode:()=>{},renderSeek:l.renderSeek,getElementVisibility:()=>({visible:!1}),getVisibleElements:()=>A,getRenderState:()=>({...N,time:l.getTime(),duration:l.getDuration(),isPlaying:l.isPlaying()})}},a=1/60,m=.75,p=.75,F=.35,D=900,C=3,T=2,U=.05,z=100,k=240,Q=l=>{if(l instanceof Error)return l.message||String(l);if(typeof l=="string")return l;try{return JSON.stringify(l)}catch{return String(l??"")}},S=l=>{let h=l.toLowerCase();return h.includes("cannot read properties of null")||h.includes("cannot set properties of null")?{code:"runtime_null_dom_access",category:"dom-null-access"}:h.includes("failed to execute \'queryselector\'")?{code:"runtime_invalid_selector",category:"selector-invalid"}:h.includes("is not defined")?{code:"runtime_reference_missing",category:"reference-missing"}:{code:"runtime_script_error",category:"script-error"}},x=l=>{if(l==null||l.trim()==="")return null;let h=Number.parseFloat(l);return!Number.isFinite(h)||h<=0?null:`${h}px`},g=()=>{let l=document.querySelector(\'[data-composition-id][data-root="true"]\');if(l instanceof HTMLElement)return l;let h=Array.from(document.querySelectorAll("[data-composition-id]"));return h.length===0?null:h.find(f=>!f.parentElement?.closest("[data-composition-id]"))??h[0]??null},E=()=>{let l=g();if(!l)return;let h=x(l.getAttribute("data-width")),f=x(l.getAttribute("data-height"));h&&(l.style.width=h),f&&(l.style.height=f),h&&l.style.setProperty("--comp-width",h),f&&l.style.setProperty("--comp-height",f)},b=()=>{let l=g(),h=Array.from(document.querySelectorAll("[data-composition-id]")).filter(f=>f.hasAttribute("data-duration")||f.hasAttribute("data-end"));for(let f of h){if(l&&f===l)continue;let A=f.getAttribute("data-duration"),N=f.getAttribute("data-end");A!=null&&!f.hasAttribute(jt)&&f.setAttribute(jt,A),N!=null&&!f.hasAttribute(zt)&&f.setAttribute(zt,N),f.removeAttribute("data-duration"),f.removeAttribute("data-end")}},y=()=>{let l=g();if(!l)return;l.style.position||(l.style.position="relative"),l.style.overflow="hidden";let h=x(l.getAttribute("data-width")),f=x(l.getAttribute("data-height"));h&&(l.style.width=h),f&&(l.style.height=f);let A=Array.from(l.children);for(let N of A){let te=N.tagName.toLowerCase();if(te==="script"||te==="style"||te==="link"||te==="meta"||!N.hasAttribute("data-start"))continue;let le=(N.style.top==="0px"||N.style.top==="0")&&(N.style.left==="0px"||N.style.left==="0")&&N.style.width==="100%"&&N.style.height==="100%",Me=/translate\\(\\s*-50%\\s*,\\s*-50%\\s*\\)/.test(N.style.transform);if(le&&Me&&!N.hasAttribute("data-width")&&!N.hasAttribute("data-height")){let ge=N.style.top,Y=N.style.left,G=N.style.width,ee=N.style.height;N.style.top="",N.style.left="",N.style.width="",N.style.height="";let q=window.getComputedStyle(N);q.top!=="auto"||q.bottom!=="auto"||q.left!=="auto"||q.right!=="auto"||q.width!=="0px"||q.height!=="0px"||(N.style.top=ge,N.style.left=Y,N.style.width=G,N.style.height=ee)}let oe=window.getComputedStyle(N),ie=oe.position;if(ie!=="absolute"&&ie!=="fixed"&&(N.style.position="absolute"),!!N.style.top||!!N.style.bottom||oe.top!=="auto"||oe.bottom!=="auto"||(N.style.top="0"),!!N.style.left||!!N.style.right||oe.left!=="auto"||oe.right!=="auto"||(N.style.left="0"),te!=="audio"){let ge=x(N.getAttribute("data-width")),Y=x(N.getAttribute("data-height")),G=oe.width!=="0px"&&oe.width!=="auto",ee=oe.height!=="0px"&&oe.height!=="auto";ge?!N.style.width&&!G&&(N.style.width=ge):!N.style.width&&oe.width==="0px"&&(N.style.width="100%"),Y?!N.style.height&&!ee&&(N.style.height=Y):!N.style.height&&oe.height==="0px"&&(N.style.height="100%")}}},v=(l,h=0)=>we({timelineRegistry:window.__timelines??{}}).resolveStartForElement(l,h),_=l=>we({timelineRegistry:window.__timelines??{}}).resolveDurationForElement(l),O=!!document.querySelector("[data-composition-src]"),V=!1;{let l=document.querySelectorAll("[data-composition-id]:not([data-composition-src])");for(let h of l){let f=h.getAttribute("data-composition-id");if(f&&h.children.length===0&&document.querySelector(`template#${CSS.escape(f)}-template`)){V=!0;break}}}let w=!O&&!V,K=l=>{if(!l||typeof l.duration!="function")return null;try{let h=Number(l.duration());return Number.isFinite(h)?Math.max(0,h):null}catch{return null}},Z=l=>typeof l=="number"&&Number.isFinite(l)&&l>a,W=l=>{let h=Number(l.getAttribute("data-duration"));if(Number.isFinite(h)&&h>0)return h;let f=Number(l.getAttribute("data-playback-start")??l.getAttribute("data-media-start")??"0"),A=Number.isFinite(f)?Math.max(0,f):0;return Number.isFinite(l.duration)&&l.duration>A?Math.max(0,l.duration-A):null},j=()=>{let l=Array.from(document.querySelectorAll("video[data-start], audio[data-start]"));if(l.length===0)return null;let h=0;for(let f of l){let A=v(f,0);if(!Number.isFinite(A))continue;let N=W(f);N==null||N<=a||(h=Math.max(h,Math.max(0,A)+N))}return h>a?h:null},R=()=>{let l=j();return typeof l!="number"||!Number.isFinite(l)||l<=a?null:l},$=l=>Z(l)?Math.max(a,l*m):a,pe=(l,h=0)=>{let f=K(l),A=R(),N=Number.isFinite(h)&&h>a?h:0,te=0;Z(f)?te=Math.max(f,N):Z(A)?te=Math.max(A,N):te=N;let le=Math.max(1,Number(e.maxTimelineDurationSeconds)||1800);return te>0?Math.max(0,Math.min(te,le)):0},ue=()=>{let l=window.__timelines??{},h=we({timelineRegistry:l}),f=R(),A=$(f),N=Y=>{let G=document.querySelector(`[data-composition-id="${CSS.escape(Y)}"]`);return G?h.resolveStartForElement(G,0):0},te=Y=>{let G=window.gsap;if(!G||typeof G.timeline!="function")return null;let ee=G.timeline({paused:!0});for(let q of Y)ee.add(q.timeline,N(q.compositionId));return ee},le=(Y,G)=>{if(!Z(Y))return null;let ee=window.gsap;if(!ee||typeof ee.timeline!="function")return null;let q=ee.timeline({paused:!0});if(G)try{q.add(G,0)}catch{}let ne=q;if(typeof ne.to=="function")try{ne.to({},{duration:Y})}catch{}return q},Me=(Y,G)=>{let ee=Y;if(typeof ee.getChildren!="function")return[];try{let q=ee.getChildren(!0,!0,!0)??[];if(!Array.isArray(q))return[];let ne=[];for(let se of G)if(!q.some(Ce=>Ce===se.timeline))try{let Ce=N(se.compositionId);Y.add(se.timeline,Ce),ne.push(se.compositionId)}catch{}return ne}catch{return[]}},oe=g(),ie=oe?.getAttribute("data-composition-id")??null;if(!ie)return{timeline:null};let me=l[ie]??null,re=(()=>{if(!oe)return[];let Y=new Set,G=Array.from(oe.querySelectorAll("[data-composition-id]")),ee=[];for(let q of G){let ne=q.getAttribute("data-composition-id");if(!ne||ne===ie||Y.has(ne))continue;Y.add(ne);let se=l[ne]??null;if(!se||typeof se.play!="function"||typeof se.pause!="function")continue;let Te=K(se);ee.push({compositionId:ne,timeline:se,durationSeconds:Te??0})}return ee})(),ge=Y=>{for(let G of Y){let ee=G.timeline;if(typeof ee.paused=="function")try{ee.paused(!1)}catch{}}};if(re.length>0&&ge(re),me){let Y=re.length>0?Me(me,re):[];if((re.length>0||!document.querySelector("[data-composition-id]:not([data-composition-id=\'"+ie+"\'])"))&&(M=!0),Y.length>0)try{let q=me.time();me.seek(q,!1)}catch{}let G=K(me);if(!Z(G)&&re.length>0){let q=re.map(Nn=>Nn.compositionId),ne=te(re),se=K(ne);if(ne&&Z(se))return{timeline:ne,selectedTimelineIds:q,selectedDurationSeconds:se,mediaDurationFloorSeconds:f,diagnostics:{code:"root_timeline_unusable_fallback",details:{rootCompositionId:ie,rootDurationSeconds:G,fallbackKind:"composite_by_root_children",minCandidateDurationSeconds:A,selectedDurationSeconds:se,mediaDurationFloorSeconds:f,selectedTimelineIds:q,autoNestedChildren:Y}}};let Te=le(f??0,me),Ce=K(Te);if(Te&&Z(Ce))return{timeline:Te,selectedTimelineIds:[ie],selectedDurationSeconds:Ce,mediaDurationFloorSeconds:f,diagnostics:{code:"root_timeline_unusable_media_floor_fallback",details:{rootCompositionId:ie,rootDurationSeconds:G,fallbackKind:"media_duration_floor",mediaDurationFloorSeconds:f,selectedDurationSeconds:Ce,selectedTimelineIds:[ie],autoNestedChildren:Y}}}}if(!Z(G)&&re.length===0){let q=le(f??0,me),ne=K(q);if(q&&Z(ne))return{timeline:q,selectedTimelineIds:[ie],selectedDurationSeconds:ne,mediaDurationFloorSeconds:f,diagnostics:{code:"root_timeline_unusable_media_floor_fallback",details:{rootCompositionId:ie,rootDurationSeconds:G,fallbackKind:"media_duration_floor",mediaDurationFloorSeconds:f,selectedDurationSeconds:ne,selectedTimelineIds:[ie]}}}}let ee=oe?.getAttribute("data-duration");if(ee){let q=parseFloat(ee);if(Z(q)&&Z(G)&&q>=G+.5){let ne=me;if(typeof ne.to=="function")try{ne.to({},{duration:0},q)}catch{}let se=K(me);if(Z(se))return{timeline:me,selectedTimelineIds:[ie],selectedDurationSeconds:se,mediaDurationFloorSeconds:f,diagnostics:{code:"root_timeline_padded_to_declared_duration",details:{rootCompositionId:ie,rootDurationSeconds:G,rootDeclaredDur:q,newDur:se}}}}}return{timeline:me,selectedTimelineIds:[ie],selectedDurationSeconds:G,mediaDurationFloorSeconds:f,diagnostics:Y.length>0?{code:"root_timeline_auto_nested_children",details:{rootCompositionId:ie,selectedDurationSeconds:G,autoNestedChildren:Y}}:void 0}}if(re.length>0){let Y=re.map(q=>q.compositionId),G=te(re),ee=K(G);if(G)return{timeline:G,selectedTimelineIds:Y,selectedDurationSeconds:ee,mediaDurationFloorSeconds:f,diagnostics:{code:"root_timeline_missing_fallback",details:{rootCompositionId:ie,fallbackKind:"composite_by_root_children",minCandidateDurationSeconds:A,selectedDurationSeconds:ee,mediaDurationFloorSeconds:f,selectedTimelineIds:Y}}}}return{timeline:null}},B=()=>{let l=e.capturedTimeline;if(!l||typeof l.time!="function")return;let h=Number(l.time());Number.isFinite(h)&&(e.currentTime=Math.max(0,h))},M=!1,L=()=>{if(!w)return!1;let l=e.capturedTimeline,h=K(l),f=Z(h);if(l&&f&&M)return!1;let A=ue();return A.timeline?l&&l===A.timeline?(typeof l.timeScale=="function"&&l.timeScale(e.playbackRate),!1):(e.capturedTimeline=A.timeline,typeof e.capturedTimeline.timeScale=="function"&&e.capturedTimeline.timeScale(e.playbackRate),A.diagnostics&&xe({source:"hf-preview",type:"diagnostic",code:A.diagnostics.code,details:A.diagnostics.details}),xe({source:"hf-preview",type:"diagnostic",code:"timeline_bound",details:{selectedTimelineIds:A.selectedTimelineIds??[],selectedDurationSeconds:A.selectedDurationSeconds??null,mediaDurationFloorSeconds:A.mediaDurationFloorSeconds??null}}),!0):!1},J=()=>{let l=g();if(!(l instanceof HTMLElement))return;let h=l.getBoundingClientRect(),f=Number(l.getAttribute("data-width")),A=Number(l.getAttribute("data-height")),N=window.getComputedStyle(l),te=Number.isFinite(f)&&f>0&&Number.isFinite(A)&&A>0,le=h.width<=0||h.height<=0||l.clientWidth<=0||l.clientHeight<=0;!te||!le||c("root_stage_layout_zero",{compositionId:l.getAttribute("data-composition-id")??null,declaredWidth:f,declaredHeight:A,rectWidth:Math.round(h.width),rectHeight:Math.round(h.height),clientWidth:l.clientWidth,clientHeight:l.clientHeight,display:N.display,visibility:N.visibility,overflow:N.overflow},`root-stage-layout-zero:${l.getAttribute("data-composition-id")??"unknown"}`)},X=()=>{e.tornDown||(u!=null&&window.cancelAnimationFrame(u),u=window.requestAnimationFrame(()=>{u=null,J()}))},I=()=>{n=l=>{let h=Q(l.error??l.message).slice(0,k);if(!h)return;let f=S(h);xe({source:"hf-preview",type:"diagnostic",code:f.code,details:{category:f.category,message:h,filename:l.filename||null,line:Number.isFinite(l.lineno)?l.lineno:null,column:Number.isFinite(l.colno)?l.colno:null}})},o=l=>{let h=Q(l.reason).slice(0,k);if(!h)return;let f=S(h);xe({source:"hf-preview",type:"diagnostic",code:`${f.code}_unhandled_rejection`,details:{category:`${f.category}-unhandled-rejection`,message:h}})},window.addEventListener("error",n),window.addEventListener("unhandledrejection",o)},P=()=>{let l=Array.from(document.querySelectorAll("img, video, audio, source, link[rel=\'stylesheet\']"));for(let f of l){let A=()=>{if(!(f instanceof Element))return;let N=f.tagName.toLowerCase(),te=f.getAttribute("src")??f.getAttribute("href")??f.getAttribute("poster")??null,le=N==="link"?"runtime_stylesheet_load_failed":"runtime_asset_load_failed";c(le,{tagName:N,assetUrl:te,currentSrc:(f instanceof HTMLImageElement||f instanceof HTMLMediaElement)&&f.currentSrc||null,readyState:f instanceof HTMLMediaElement?f.readyState:null,networkState:f instanceof HTMLMediaElement?f.networkState:null},`${le}:${N}:${te??"unknown"}`)};f.addEventListener("error",A),d(()=>{f.removeEventListener("error",A)})}let h=document.fonts;h&&h.ready.then(()=>{if(e.tornDown)return;let f=Array.from(h).filter(A=>A.status==="error").map(A=>A.family).filter(A=>!!A).slice(0,10);f.length!==0&&c("runtime_font_load_issue",{failedFamilies:f,totalFaces:Array.from(h).length},`runtime-font-load-issue:${f.join("|")}`)}).catch(()=>{})},H=(l,h)=>{if(!l.timeline)return!1;let f=e.capturedTimeline;if(f&&f===l.timeline)return!1;let A=Math.max(0,e.currentTime||0),N=e.isPlaying;e.capturedTimeline=l.timeline,typeof e.capturedTimeline.timeScale=="function"&&e.capturedTimeline.timeScale(e.playbackRate);try{e.capturedTimeline.pause(),e.capturedTimeline.seek(A,!1),N&&e.capturedTimeline.play()}catch{}return xe({source:"hf-preview",type:"diagnostic",code:"timeline_loop_guard_rebind",details:{reason:h,previousTime:A,selectedTimelineIds:l.selectedTimelineIds??[],selectedDurationSeconds:l.selectedDurationSeconds??null,mediaDurationFloorSeconds:l.mediaDurationFloorSeconds??null}}),!0},ce=null,de=!1,Ae=new Set,he=()=>{e.tornDown||(ce!=null&&window.clearTimeout(ce),ce=window.setTimeout(()=>{if(e.tornDown)return;ce=null;let l=ue();if(!l.timeline||!Z(l.mediaDurationFloorSeconds??null))return;if(!e.capturedTimeline){L()&&(ke(),Ee(!0));return}if(de)return;let f=K(e.capturedTimeline),A=l.selectedDurationSeconds??K(l.timeline);Z(A)&&(!Z(f)||A>=f+U)&&H(l,"manual")&&(de=!0,xe({source:"hf-preview",type:"diagnostic",code:"timeline_rebind_after_media_metadata",details:{previousDurationSeconds:f??null,selectedDurationSeconds:A??null,selectedTimelineIds:l.selectedTimelineIds??[],mediaDurationFloorSeconds:l.mediaDurationFloorSeconds??null}}),ke(),Ee(!0))},z))},gn=()=>{for(let l of Ae)l.removeEventListener("loadedmetadata",he),l.removeEventListener("durationchange",he);Ae.clear()},Je=()=>{if(e.tornDown)return;let l=Array.from(document.querySelectorAll("video, audio"));for(let h of l)Ae.has(h)||(Ae.add(h),h.addEventListener("loadedmetadata",he),h.addEventListener("durationchange",he),h.preload!=="auto"&&(h.preload="auto"),h.readyState<HTMLMediaElement.HAVE_FUTURE_DATA&&h.load())},ht=()=>{let l=Lt({resolveStartSeconds:A=>v(A,0)});Tt({clips:l.mediaClips,timeSeconds:e.currentTime,playing:e.isPlaying,playbackRate:e.playbackRate,outputMuted:e.mediaOutputMuted,userMuted:e.bridgeMuted,onAutoplayBlocked:()=>{e.mediaAutoplayBlockedPosted||(e.mediaAutoplayBlockedPosted=!0,xe({source:"hf-preview",type:"media-autoplay-blocked"}))}});let h=document.querySelector("[data-composition-id]")?.getAttribute("data-composition-id")??null,f=Array.from(document.querySelectorAll("[data-start]"));for(let A of f){if(!(A instanceof HTMLElement))continue;let N=A.tagName.toLowerCase();if(N==="script"||N==="style"||N==="link"||N==="meta")continue;if(!A.getAttribute("data-composition-id")){let ge=A.closest("[data-composition-id]")?.getAttribute("data-composition-id")??null;if(ge&&ge!==h)continue}let le=v(A,0),Me=_(A),oe=Me!=null&&Me>0?le+Me:Number.POSITIVE_INFINITY,ie=oe,me=A.getAttribute("data-composition-id");if(me&&!Number.isFinite(oe)){let re=(window.__timelines??{})[me];if(re&&typeof re.duration=="function"){let ge=re.duration();ge>0&&(ie=le+ge)}}let Xe=e.currentTime>=le&&(Number.isFinite(ie)?e.currentTime<ie:!0);A.style.visibility=Xe?"visible":"hidden"}},Ee=l=>{B();let h=Math.max(0,Math.round((e.currentTime||0)*e.canonicalFps)),f=Date.now();(l||h!==e.bridgeLastPostedFrame||e.isPlaying!==e.bridgeLastPostedPlaying||e.bridgeMuted!==e.bridgeLastPostedMuted||f-e.bridgeLastPostedAt>=e.bridgeMaxPostIntervalMs)&&(e.bridgeLastPostedFrame=h,e.bridgeLastPostedPlaying=e.isPlaying,e.bridgeLastPostedMuted=e.bridgeMuted,e.bridgeLastPostedAt=f,xe({source:"hf-preview",type:"state",frame:h,isPlaying:e.isPlaying,muted:e.bridgeMuted,playbackRate:e.playbackRate}))},ke=()=>{b(),E(),y();let l=g();if(l){let f=x(l.getAttribute("data-width")),A=x(l.getAttribute("data-height")),N=f?parseInt(f,10):0,te=A?parseInt(A,10):0;N>0&&te>0&&xe({source:"hf-preview",type:"stage-size",width:N,height:te})}L();let h=Ot({canonicalFps:e.canonicalFps,maxTimelineDurationSeconds:e.maxTimelineDurationSeconds});window.__clipManifest=h,xe(h),X()},Ie=(l,h=0)=>{for(let f of e.deterministicAdapters){try{l==="discover"&&f.discover(),l==="pause"&&f.pause(),l==="play"&&f.play&&f.play()}catch{}if(l==="discover")try{f.seek({time:h})}catch{}}};if(w)at();else{let l={injectedStyles:e.injectedCompStyles,injectedScripts:e.injectedCompScripts,parseDimensionPx:x,onDiagnostic:({code:h,details:f})=>{xe({source:"hf-preview",type:"diagnostic",code:h,details:f})}};Ht(l).then(()=>Wt(l)).finally(()=>{w=!0,Ie("discover",e.currentTime),Je(),P(),at(),ke(),Ee(!0)})}let je=wt({postMessage:l=>xe(l)});je.installPickerApi();let gt=l=>{let h=Number(l);!Number.isFinite(h)||h<=0?e.playbackRate=1:e.playbackRate=Math.max(.1,Math.min(5,h)),e.capturedTimeline&&typeof e.capturedTimeline.timeScale=="function"&&e.capturedTimeline.timeScale(e.playbackRate);let f=document.querySelectorAll("video, audio");for(let A of f)if(A instanceof HTMLMediaElement)try{A.playbackRate=e.playbackRate}catch{}},ae=Rt({getTimeline:()=>e.capturedTimeline,setTimeline:l=>{e.capturedTimeline=l},getTimelineRegistry:()=>window.__timelines??{},getIsPlaying:()=>e.isPlaying,setIsPlaying:l=>{e.isPlaying=l},getPlaybackRate:()=>e.playbackRate,setPlaybackRate:gt,getCanonicalFps:()=>e.canonicalFps,onSyncMedia:(l,h)=>{e.currentTime=Math.max(0,Number(l)||0),e.isPlaying=h,ht()},onStatePost:Ee,onDeterministicSeek:l=>{for(let h of e.deterministicAdapters)try{h.seek({time:Number(l)||0})}catch{}},onDeterministicPause:()=>Ie("pause"),onDeterministicPlay:()=>Ie("play"),onRenderFrameSeek:()=>{},onShowNativeVideos:()=>{},getSafeDuration:()=>pe(e.capturedTimeline,0)});window.__player=s(ae),window.__playerReady=!0,window.__renderReady=!0,At(xe),Pe("composition_loaded",{duration:ae.getDuration(),compositionId:document.querySelector("[data-composition-id]")?.getAttribute("data-composition-id")??null}),e.controlBridgeHandler=Nt({onPlay:()=>{ae.play(),Pe("composition_played",{time:ae.getTime()})},onPause:()=>{ae.pause(),Pe("composition_paused",{time:ae.getTime()})},onSeek:(l,h)=>{let f=Math.max(0,l)/e.canonicalFps;ae.seek(f),Pe("composition_seeked",{time:f})},onSetMuted:l=>{e.bridgeMuted=l;let h=l||e.mediaOutputMuted,f=document.querySelectorAll("video, audio");for(let A of f)A instanceof HTMLMediaElement&&(A.muted=h)},onSetMediaOutputMuted:l=>{e.mediaOutputMuted=l;let h=l||e.bridgeMuted,f=document.querySelectorAll("video, audio");for(let A of f)A instanceof HTMLMediaElement&&(A.muted=h)},onSetPlaybackRate:l=>gt(l),onEnablePickMode:()=>je.enablePickMode(),onDisablePickMode:()=>je.disablePickMode()}),L(),e.capturedTimeline&&(ae._timeline=e.capturedTimeline),w&&setTimeout(()=>{let l=e.capturedTimeline;L()&&e.capturedTimeline!==l&&(ae._timeline=e.capturedTimeline),Ie("discover",e.currentTime),ke(),Ee(!0)},0),e.deterministicAdapters=[kt(),Et({resolveStartSeconds:l=>v(l,0)}),Ct(),Dt(),yt({getTimeline:()=>e.capturedTimeline})],I(),Ie("discover"),Je(),e.timelinePollIntervalId&&clearInterval(e.timelinePollIntervalId);let Qe=0,ze=null,St=0,Ze=!1,Le=0,Ft=()=>{St=Date.now(),Ze=!1,Le=0};e.timelinePollIntervalId=setInterval(()=>{Qe+=1;let h=e.isPlaying&&e.capturedTimeline!=null&&Math.max(0,e.currentTime||0)<T?!1:L();if(e.capturedTimeline&&!ae._timeline&&(ae._timeline=e.capturedTimeline),(h||Qe%20===0)&&ke(),Qe%10===0&&Je(),B(),e.isPlaying&&e.capturedTimeline){let f=Math.max(0,e.currentTime||0),A=ze,N=pe(e.capturedTimeline,0);if(N>0&&f>=N){ae.pause(),ae.seek(N),ze=N,Le=0,Ee(!0);return}if(A!=null&&A>=p&&f<=F?Le+=1:Le=0,!Ze&&Le>=C&&Date.now()-St>D){let le=ue();H(le,"loop_guard")&&(Ze=!0,Le=0)}ze=Math.max(0,e.currentTime||0)}else ze=Math.max(0,e.currentTime||0);e.isPlaying&&ht(),Ee(!1)},50),ke(),Ee(!0);let Sn=ae.seek;ae.seek=l=>{Ft(),Sn(l)};let Fn=ae.renderSeek;ae.renderSeek=l=>{Ft(),Fn(l)};let Ye=()=>{if(!e.tornDown){e.tornDown=!0,e.timelinePollIntervalId&&(clearInterval(e.timelinePollIntervalId),e.timelinePollIntervalId=null),ce!=null&&(window.clearTimeout(ce),ce=null),u!=null&&(window.cancelAnimationFrame(u),u=null),gn(),e.controlBridgeHandler&&(window.removeEventListener("message",e.controlBridgeHandler),e.controlBridgeHandler=null),n&&(window.removeEventListener("error",n),n=null),o&&(window.removeEventListener("unhandledrejection",o),o=null),e.beforeUnloadHandler&&(window.removeEventListener("beforeunload",e.beforeUnloadHandler),e.beforeUnloadHandler=null),je.disablePickMode();for(let l of e.deterministicAdapters)if(!(!l||typeof l.revert!="function"))try{l.revert()}catch{}e.deterministicAdapters=[];for(let l of r.splice(0))try{l()}catch{}for(let l of e.injectedCompStyles)try{l.remove()}catch{}e.injectedCompStyles=[];for(let l of e.injectedCompScripts)try{l.remove()}catch{}e.injectedCompScripts=[],e.capturedTimeline=null,t.__hfRuntimeTeardown===Ye&&(t.__hfRuntimeTeardown=null)}};t.__hfRuntimeTeardown=Ye,e.beforeUnloadHandler=Ye,window.addEventListener("beforeunload",e.beforeUnloadHandler)}var Gt=["BN","BN","BN","BN","BN","BN","BN","BN","BN","S","B","S","WS","B","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","B","B","B","S","WS","ON","ON","ET","ET","ET","ON","ON","ON","ON","ON","ES","CS","ES","CS","CS","EN","EN","EN","EN","EN","EN","EN","EN","EN","EN","CS","ON","ON","ON","ON","ON","ON","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","ON","ON","ON","ON","ON","ON","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","ON","ON","ON","ON","BN","BN","BN","BN","BN","BN","B","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","CS","ON","ET","ET","ET","ET","ON","ON","ON","ON","L","ON","ON","BN","ON","ON","ET","ET","EN","EN","ON","L","ON","ON","ON","EN","L","ON","ON","ON","ON","ON","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","ON","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","ON","L","L","L","L","L","L","L","L"],lt=[[697,698,"ON"],[706,719,"ON"],[722,735,"ON"],[741,749,"ON"],[751,767,"ON"],[768,879,"NSM"],[884,885,"ON"],[894,894,"ON"],[900,901,"ON"],[903,903,"ON"],[1014,1014,"ON"],[1155,1161,"NSM"],[1418,1418,"ON"],[1421,1422,"ON"],[1423,1423,"ET"],[1424,1424,"R"],[1425,1469,"NSM"],[1470,1470,"R"],[1471,1471,"NSM"],[1472,1472,"R"],[1473,1474,"NSM"],[1475,1475,"R"],[1476,1477,"NSM"],[1478,1478,"R"],[1479,1479,"NSM"],[1480,1535,"R"],[1536,1541,"AN"],[1542,1543,"ON"],[1544,1544,"AL"],[1545,1546,"ET"],[1547,1547,"AL"],[1548,1548,"CS"],[1549,1549,"AL"],[1550,1551,"ON"],[1552,1562,"NSM"],[1563,1610,"AL"],[1611,1631,"NSM"],[1632,1641,"AN"],[1642,1642,"ET"],[1643,1644,"AN"],[1645,1647,"AL"],[1648,1648,"NSM"],[1649,1749,"AL"],[1750,1756,"NSM"],[1757,1757,"AN"],[1758,1758,"ON"],[1759,1764,"NSM"],[1765,1766,"AL"],[1767,1768,"NSM"],[1769,1769,"ON"],[1770,1773,"NSM"],[1774,1775,"AL"],[1776,1785,"EN"],[1786,1808,"AL"],[1809,1809,"NSM"],[1810,1839,"AL"],[1840,1866,"NSM"],[1867,1957,"AL"],[1958,1968,"NSM"],[1969,1983,"AL"],[1984,2026,"R"],[2027,2035,"NSM"],[2036,2037,"R"],[2038,2041,"ON"],[2042,2044,"R"],[2045,2045,"NSM"],[2046,2069,"R"],[2070,2073,"NSM"],[2074,2074,"R"],[2075,2083,"NSM"],[2084,2084,"R"],[2085,2087,"NSM"],[2088,2088,"R"],[2089,2093,"NSM"],[2094,2136,"R"],[2137,2139,"NSM"],[2140,2143,"R"],[2144,2191,"AL"],[2192,2193,"AN"],[2194,2198,"AL"],[2199,2207,"NSM"],[2208,2249,"AL"],[2250,2273,"NSM"],[2274,2274,"AN"],[2275,2306,"NSM"],[2362,2362,"NSM"],[2364,2364,"NSM"],[2369,2376,"NSM"],[2381,2381,"NSM"],[2385,2391,"NSM"],[2402,2403,"NSM"],[2433,2433,"NSM"],[2492,2492,"NSM"],[2497,2500,"NSM"],[2509,2509,"NSM"],[2530,2531,"NSM"],[2546,2547,"ET"],[2555,2555,"ET"],[2558,2558,"NSM"],[2561,2562,"NSM"],[2620,2620,"NSM"],[2625,2626,"NSM"],[2631,2632,"NSM"],[2635,2637,"NSM"],[2641,2641,"NSM"],[2672,2673,"NSM"],[2677,2677,"NSM"],[2689,2690,"NSM"],[2748,2748,"NSM"],[2753,2757,"NSM"],[2759,2760,"NSM"],[2765,2765,"NSM"],[2786,2787,"NSM"],[2801,2801,"ET"],[2810,2815,"NSM"],[2817,2817,"NSM"],[2876,2876,"NSM"],[2879,2879,"NSM"],[2881,2884,"NSM"],[2893,2893,"NSM"],[2901,2902,"NSM"],[2914,2915,"NSM"],[2946,2946,"NSM"],[3008,3008,"NSM"],[3021,3021,"NSM"],[3059,3064,"ON"],[3065,3065,"ET"],[3066,3066,"ON"],[3072,3072,"NSM"],[3076,3076,"NSM"],[3132,3132,"NSM"],[3134,3136,"NSM"],[3142,3144,"NSM"],[3146,3149,"NSM"],[3157,3158,"NSM"],[3170,3171,"NSM"],[3192,3198,"ON"],[3201,3201,"NSM"],[3260,3260,"NSM"],[3276,3277,"NSM"],[3298,3299,"NSM"],[3328,3329,"NSM"],[3387,3388,"NSM"],[3393,3396,"NSM"],[3405,3405,"NSM"],[3426,3427,"NSM"],[3457,3457,"NSM"],[3530,3530,"NSM"],[3538,3540,"NSM"],[3542,3542,"NSM"],[3633,3633,"NSM"],[3636,3642,"NSM"],[3647,3647,"ET"],[3655,3662,"NSM"],[3761,3761,"NSM"],[3764,3772,"NSM"],[3784,3790,"NSM"],[3864,3865,"NSM"],[3893,3893,"NSM"],[3895,3895,"NSM"],[3897,3897,"NSM"],[3898,3901,"ON"],[3953,3966,"NSM"],[3968,3972,"NSM"],[3974,3975,"NSM"],[3981,3991,"NSM"],[3993,4028,"NSM"],[4038,4038,"NSM"],[4141,4144,"NSM"],[4146,4151,"NSM"],[4153,4154,"NSM"],[4157,4158,"NSM"],[4184,4185,"NSM"],[4190,4192,"NSM"],[4209,4212,"NSM"],[4226,4226,"NSM"],[4229,4230,"NSM"],[4237,4237,"NSM"],[4253,4253,"NSM"],[4957,4959,"NSM"],[5008,5017,"ON"],[5120,5120,"ON"],[5760,5760,"WS"],[5787,5788,"ON"],[5906,5908,"NSM"],[5938,5939,"NSM"],[5970,5971,"NSM"],[6002,6003,"NSM"],[6068,6069,"NSM"],[6071,6077,"NSM"],[6086,6086,"NSM"],[6089,6099,"NSM"],[6107,6107,"ET"],[6109,6109,"NSM"],[6128,6137,"ON"],[6144,6154,"ON"],[6155,6157,"NSM"],[6158,6158,"BN"],[6159,6159,"NSM"],[6277,6278,"NSM"],[6313,6313,"NSM"],[6432,6434,"NSM"],[6439,6440,"NSM"],[6450,6450,"NSM"],[6457,6459,"NSM"],[6464,6464,"ON"],[6468,6469,"ON"],[6622,6655,"ON"],[6679,6680,"NSM"],[6683,6683,"NSM"],[6742,6742,"NSM"],[6744,6750,"NSM"],[6752,6752,"NSM"],[6754,6754,"NSM"],[6757,6764,"NSM"],[6771,6780,"NSM"],[6783,6783,"NSM"],[6832,6877,"NSM"],[6880,6891,"NSM"],[6912,6915,"NSM"],[6964,6964,"NSM"],[6966,6970,"NSM"],[6972,6972,"NSM"],[6978,6978,"NSM"],[7019,7027,"NSM"],[7040,7041,"NSM"],[7074,7077,"NSM"],[7080,7081,"NSM"],[7083,7085,"NSM"],[7142,7142,"NSM"],[7144,7145,"NSM"],[7149,7149,"NSM"],[7151,7153,"NSM"],[7212,7219,"NSM"],[7222,7223,"NSM"],[7376,7378,"NSM"],[7380,7392,"NSM"],[7394,7400,"NSM"],[7405,7405,"NSM"],[7412,7412,"NSM"],[7416,7417,"NSM"],[7616,7679,"NSM"],[8125,8125,"ON"],[8127,8129,"ON"],[8141,8143,"ON"],[8157,8159,"ON"],[8173,8175,"ON"],[8189,8190,"ON"],[8192,8202,"WS"],[8203,8205,"BN"],[8207,8207,"R"],[8208,8231,"ON"],[8232,8232,"WS"],[8233,8233,"B"],[8234,8238,"BN"],[8239,8239,"CS"],[8240,8244,"ET"],[8245,8259,"ON"],[8260,8260,"CS"],[8261,8286,"ON"],[8287,8287,"WS"],[8288,8303,"BN"],[8304,8304,"EN"],[8308,8313,"EN"],[8314,8315,"ES"],[8316,8318,"ON"],[8320,8329,"EN"],[8330,8331,"ES"],[8332,8334,"ON"],[8352,8399,"ET"],[8400,8432,"NSM"],[8448,8449,"ON"],[8451,8454,"ON"],[8456,8457,"ON"],[8468,8468,"ON"],[8470,8472,"ON"],[8478,8483,"ON"],[8485,8485,"ON"],[8487,8487,"ON"],[8489,8489,"ON"],[8494,8494,"ET"],[8506,8507,"ON"],[8512,8516,"ON"],[8522,8525,"ON"],[8528,8543,"ON"],[8585,8587,"ON"],[8592,8721,"ON"],[8722,8722,"ES"],[8723,8723,"ET"],[8724,9013,"ON"],[9083,9108,"ON"],[9110,9257,"ON"],[9280,9290,"ON"],[9312,9351,"ON"],[9352,9371,"EN"],[9450,9899,"ON"],[9901,10239,"ON"],[10496,11123,"ON"],[11126,11263,"ON"],[11493,11498,"ON"],[11503,11505,"NSM"],[11513,11519,"ON"],[11647,11647,"NSM"],[11744,11775,"NSM"],[11776,11869,"ON"],[11904,11929,"ON"],[11931,12019,"ON"],[12032,12245,"ON"],[12272,12287,"ON"],[12288,12288,"WS"],[12289,12292,"ON"],[12296,12320,"ON"],[12330,12333,"NSM"],[12336,12336,"ON"],[12342,12343,"ON"],[12349,12351,"ON"],[12441,12442,"NSM"],[12443,12444,"ON"],[12448,12448,"ON"],[12539,12539,"ON"],[12736,12773,"ON"],[12783,12783,"ON"],[12829,12830,"ON"],[12880,12895,"ON"],[12924,12926,"ON"],[12977,12991,"ON"],[13004,13007,"ON"],[13175,13178,"ON"],[13278,13279,"ON"],[13311,13311,"ON"],[19904,19967,"ON"],[42128,42182,"ON"],[42509,42511,"ON"],[42607,42610,"NSM"],[42611,42611,"ON"],[42612,42621,"NSM"],[42622,42623,"ON"],[42654,42655,"NSM"],[42736,42737,"NSM"],[42752,42785,"ON"],[42888,42888,"ON"],[43010,43010,"NSM"],[43014,43014,"NSM"],[43019,43019,"NSM"],[43045,43046,"NSM"],[43048,43051,"ON"],[43052,43052,"NSM"],[43064,43065,"ET"],[43124,43127,"ON"],[43204,43205,"NSM"],[43232,43249,"NSM"],[43263,43263,"NSM"],[43302,43309,"NSM"],[43335,43345,"NSM"],[43392,43394,"NSM"],[43443,43443,"NSM"],[43446,43449,"NSM"],[43452,43453,"NSM"],[43493,43493,"NSM"],[43561,43566,"NSM"],[43569,43570,"NSM"],[43573,43574,"NSM"],[43587,43587,"NSM"],[43596,43596,"NSM"],[43644,43644,"NSM"],[43696,43696,"NSM"],[43698,43700,"NSM"],[43703,43704,"NSM"],[43710,43711,"NSM"],[43713,43713,"NSM"],[43756,43757,"NSM"],[43766,43766,"NSM"],[43882,43883,"ON"],[44005,44005,"NSM"],[44008,44008,"NSM"],[44013,44013,"NSM"],[64285,64285,"R"],[64286,64286,"NSM"],[64287,64296,"R"],[64297,64297,"ES"],[64298,64335,"R"],[64336,64450,"AL"],[64451,64466,"ON"],[64467,64829,"AL"],[64830,64847,"ON"],[64848,64911,"AL"],[64912,64913,"ON"],[64914,64967,"AL"],[64968,64975,"ON"],[64976,65007,"BN"],[65008,65020,"AL"],[65021,65023,"ON"],[65024,65039,"NSM"],[65040,65049,"ON"],[65056,65071,"NSM"],[65072,65103,"ON"],[65104,65104,"CS"],[65105,65105,"ON"],[65106,65106,"CS"],[65108,65108,"ON"],[65109,65109,"CS"],[65110,65118,"ON"],[65119,65119,"ET"],[65120,65121,"ON"],[65122,65123,"ES"],[65124,65126,"ON"],[65128,65128,"ON"],[65129,65130,"ET"],[65131,65131,"ON"],[65136,65278,"AL"],[65279,65279,"BN"],[65281,65282,"ON"],[65283,65285,"ET"],[65286,65290,"ON"],[65291,65291,"ES"],[65292,65292,"CS"],[65293,65293,"ES"],[65294,65295,"CS"],[65296,65305,"EN"],[65306,65306,"CS"],[65307,65312,"ON"],[65339,65344,"ON"],[65371,65381,"ON"],[65504,65505,"ET"],[65506,65508,"ON"],[65509,65510,"ET"],[65512,65518,"ON"],[65520,65528,"BN"],[65529,65533,"ON"],[65534,65535,"BN"],[65793,65793,"ON"],[65856,65932,"ON"],[65936,65948,"ON"],[65952,65952,"ON"],[66045,66045,"NSM"],[66272,66272,"NSM"],[66273,66299,"EN"],[66422,66426,"NSM"],[67584,67870,"R"],[67871,67871,"ON"],[67872,68096,"R"],[68097,68099,"NSM"],[68100,68100,"R"],[68101,68102,"NSM"],[68103,68107,"R"],[68108,68111,"NSM"],[68112,68151,"R"],[68152,68154,"NSM"],[68155,68158,"R"],[68159,68159,"NSM"],[68160,68324,"R"],[68325,68326,"NSM"],[68327,68408,"R"],[68409,68415,"ON"],[68416,68863,"R"],[68864,68899,"AL"],[68900,68903,"NSM"],[68904,68911,"AL"],[68912,68921,"AN"],[68922,68927,"AL"],[68928,68937,"AN"],[68938,68968,"R"],[68969,68973,"NSM"],[68974,68974,"ON"],[68975,69215,"R"],[69216,69246,"AN"],[69247,69290,"R"],[69291,69292,"NSM"],[69293,69311,"R"],[69312,69327,"AL"],[69328,69336,"ON"],[69337,69369,"AL"],[69370,69375,"NSM"],[69376,69423,"R"],[69424,69445,"AL"],[69446,69456,"NSM"],[69457,69487,"AL"],[69488,69505,"R"],[69506,69509,"NSM"],[69510,69631,"R"],[69633,69633,"NSM"],[69688,69702,"NSM"],[69714,69733,"ON"],[69744,69744,"NSM"],[69747,69748,"NSM"],[69759,69761,"NSM"],[69811,69814,"NSM"],[69817,69818,"NSM"],[69826,69826,"NSM"],[69888,69890,"NSM"],[69927,69931,"NSM"],[69933,69940,"NSM"],[70003,70003,"NSM"],[70016,70017,"NSM"],[70070,70078,"NSM"],[70089,70092,"NSM"],[70095,70095,"NSM"],[70191,70193,"NSM"],[70196,70196,"NSM"],[70198,70199,"NSM"],[70206,70206,"NSM"],[70209,70209,"NSM"],[70367,70367,"NSM"],[70371,70378,"NSM"],[70400,70401,"NSM"],[70459,70460,"NSM"],[70464,70464,"NSM"],[70502,70508,"NSM"],[70512,70516,"NSM"],[70587,70592,"NSM"],[70606,70606,"NSM"],[70608,70608,"NSM"],[70610,70610,"NSM"],[70625,70626,"NSM"],[70712,70719,"NSM"],[70722,70724,"NSM"],[70726,70726,"NSM"],[70750,70750,"NSM"],[70835,70840,"NSM"],[70842,70842,"NSM"],[70847,70848,"NSM"],[70850,70851,"NSM"],[71090,71093,"NSM"],[71100,71101,"NSM"],[71103,71104,"NSM"],[71132,71133,"NSM"],[71219,71226,"NSM"],[71229,71229,"NSM"],[71231,71232,"NSM"],[71264,71276,"ON"],[71339,71339,"NSM"],[71341,71341,"NSM"],[71344,71349,"NSM"],[71351,71351,"NSM"],[71453,71453,"NSM"],[71455,71455,"NSM"],[71458,71461,"NSM"],[71463,71467,"NSM"],[71727,71735,"NSM"],[71737,71738,"NSM"],[71995,71996,"NSM"],[71998,71998,"NSM"],[72003,72003,"NSM"],[72148,72151,"NSM"],[72154,72155,"NSM"],[72160,72160,"NSM"],[72193,72198,"NSM"],[72201,72202,"NSM"],[72243,72248,"NSM"],[72251,72254,"NSM"],[72263,72263,"NSM"],[72273,72278,"NSM"],[72281,72283,"NSM"],[72330,72342,"NSM"],[72344,72345,"NSM"],[72544,72544,"NSM"],[72546,72548,"NSM"],[72550,72550,"NSM"],[72752,72758,"NSM"],[72760,72765,"NSM"],[72850,72871,"NSM"],[72874,72880,"NSM"],[72882,72883,"NSM"],[72885,72886,"NSM"],[73009,73014,"NSM"],[73018,73018,"NSM"],[73020,73021,"NSM"],[73023,73029,"NSM"],[73031,73031,"NSM"],[73104,73105,"NSM"],[73109,73109,"NSM"],[73111,73111,"NSM"],[73459,73460,"NSM"],[73472,73473,"NSM"],[73526,73530,"NSM"],[73536,73536,"NSM"],[73538,73538,"NSM"],[73562,73562,"NSM"],[73685,73692,"ON"],[73693,73696,"ET"],[73697,73713,"ON"],[78912,78912,"NSM"],[78919,78933,"NSM"],[90398,90409,"NSM"],[90413,90415,"NSM"],[92912,92916,"NSM"],[92976,92982,"NSM"],[94031,94031,"NSM"],[94095,94098,"NSM"],[94178,94178,"ON"],[94180,94180,"NSM"],[113821,113822,"NSM"],[113824,113827,"BN"],[117760,117973,"ON"],[118e3,118009,"EN"],[118010,118012,"ON"],[118016,118451,"ON"],[118458,118480,"ON"],[118496,118512,"ON"],[118528,118573,"NSM"],[118576,118598,"NSM"],[119143,119145,"NSM"],[119155,119162,"BN"],[119163,119170,"NSM"],[119173,119179,"NSM"],[119210,119213,"NSM"],[119273,119274,"ON"],[119296,119361,"ON"],[119362,119364,"NSM"],[119365,119365,"ON"],[119552,119638,"ON"],[120513,120513,"ON"],[120539,120539,"ON"],[120571,120571,"ON"],[120597,120597,"ON"],[120629,120629,"ON"],[120655,120655,"ON"],[120687,120687,"ON"],[120713,120713,"ON"],[120745,120745,"ON"],[120771,120771,"ON"],[120782,120831,"EN"],[121344,121398,"NSM"],[121403,121452,"NSM"],[121461,121461,"NSM"],[121476,121476,"NSM"],[121499,121503,"NSM"],[121505,121519,"NSM"],[122880,122886,"NSM"],[122888,122904,"NSM"],[122907,122913,"NSM"],[122915,122916,"NSM"],[122918,122922,"NSM"],[123023,123023,"NSM"],[123184,123190,"NSM"],[123566,123566,"NSM"],[123628,123631,"NSM"],[123647,123647,"ET"],[124140,124143,"NSM"],[124398,124399,"NSM"],[124643,124643,"NSM"],[124646,124646,"NSM"],[124654,124655,"NSM"],[124661,124661,"NSM"],[124928,125135,"R"],[125136,125142,"NSM"],[125143,125251,"R"],[125252,125258,"NSM"],[125259,126063,"R"],[126064,126143,"AL"],[126144,126207,"R"],[126208,126287,"AL"],[126288,126463,"R"],[126464,126703,"AL"],[126704,126705,"ON"],[126706,126719,"AL"],[126720,126975,"R"],[126976,127019,"ON"],[127024,127123,"ON"],[127136,127150,"ON"],[127153,127167,"ON"],[127169,127183,"ON"],[127185,127221,"ON"],[127232,127242,"EN"],[127243,127247,"ON"],[127279,127279,"ON"],[127338,127343,"ON"],[127405,127405,"ON"],[127584,127589,"ON"],[127744,128728,"ON"],[128732,128748,"ON"],[128752,128764,"ON"],[128768,128985,"ON"],[128992,129003,"ON"],[129008,129008,"ON"],[129024,129035,"ON"],[129040,129095,"ON"],[129104,129113,"ON"],[129120,129159,"ON"],[129168,129197,"ON"],[129200,129211,"ON"],[129216,129217,"ON"],[129232,129240,"ON"],[129280,129623,"ON"],[129632,129645,"ON"],[129648,129660,"ON"],[129664,129674,"ON"],[129678,129734,"ON"],[129736,129736,"ON"],[129741,129756,"ON"],[129759,129770,"ON"],[129775,129784,"ON"],[129792,129938,"ON"],[129940,130031,"ON"],[130032,130041,"EN"],[130042,130042,"ON"],[131070,131071,"BN"],[196606,196607,"BN"],[262142,262143,"BN"],[327678,327679,"BN"],[393214,393215,"BN"],[458750,458751,"BN"],[524286,524287,"BN"],[589822,589823,"BN"],[655358,655359,"BN"],[720894,720895,"BN"],[786430,786431,"BN"],[851966,851967,"BN"],[917502,917759,"BN"],[917760,917999,"NSM"],[918e3,921599,"BN"],[983038,983039,"BN"],[1048574,1048575,"BN"],[1114110,1114111,"BN"]];function _n(e){if(e<=255)return Gt[e];let t=0,n=lt.length-1;for(;t<=n;){let o=t+n>>1,r=lt[o];if(e<r[0]){n=o-1;continue}if(e>r[1]){t=o+1;continue}return r[2]}return"L"}function Wn(e){let t=e.length;if(t===0)return null;let n=new Array(t),o=!1;for(let s=0;s<t;){let a=e.charCodeAt(s),m=a,p=1;if(a>=55296&&a<=56319&&s+1<t){let D=e.charCodeAt(s+1);D>=56320&&D<=57343&&(m=(a-55296<<10)+(D-56320)+65536,p=2)}let F=_n(m);(F==="R"||F==="AL"||F==="AN")&&(o=!0);for(let D=0;D<p;D++)n[s+D]=F;s+=p}if(!o)return null;let r=0;for(let s=0;s<t;s++){let a=n[s];if(a==="L"){r=0;break}if(a==="R"||a==="AL"){r=1;break}}let i=new Int8Array(t);for(let s=0;s<t;s++)i[s]=r;let u=r&1?"R":"L",d=u,c=d;for(let s=0;s<t;s++)n[s]==="NSM"?n[s]=c:c=n[s];c=d;for(let s=0;s<t;s++){let a=n[s];a==="EN"?n[s]=c==="AL"?"AN":"EN":(a==="R"||a==="L"||a==="AL")&&(c=a)}for(let s=0;s<t;s++)n[s]==="AL"&&(n[s]="R");for(let s=1;s<t-1;s++)n[s]==="ES"&&n[s-1]==="EN"&&n[s+1]==="EN"&&(n[s]="EN"),n[s]==="CS"&&(n[s-1]==="EN"||n[s-1]==="AN")&&n[s+1]===n[s-1]&&(n[s]=n[s-1]);for(let s=0;s<t;s++){if(n[s]!=="EN")continue;let a;for(a=s-1;a>=0&&n[a]==="ET";a--)n[a]="EN";for(a=s+1;a<t&&n[a]==="ET";a++)n[a]="EN"}for(let s=0;s<t;s++){let a=n[s];(a==="WS"||a==="ES"||a==="ET"||a==="CS")&&(n[s]="ON")}c=d;for(let s=0;s<t;s++){let a=n[s];a==="EN"?n[s]=c==="L"?"L":"EN":(a==="R"||a==="L")&&(c=a)}for(let s=0;s<t;s++){if(n[s]!=="ON")continue;let a=s+1;for(;a<t&&n[a]==="ON";)a++;let m=s>0?n[s-1]:d,p=a<t?n[a]:d,F=m!=="L"?"R":"L";if(F===(p!=="L"?"R":"L"))for(let C=s;C<a;C++)n[C]=F;s=a-1}for(let s=0;s<t;s++)n[s]==="ON"&&(n[s]=u);for(let s=0;s<t;s++){let a=n[s];(i[s]&1)===0?a==="R"?i[s]++:(a==="AN"||a==="EN")&&(i[s]+=2):(a==="L"||a==="AN"||a==="EN")&&i[s]++}return i}function qt(e,t){let n=Wn(e);if(n===null)return null;let o=new Int8Array(t.length);for(let r=0;r<t.length;r++)o[r]=n[t[r]];return o}var Hn=/[ \\t\\n\\r\\f]+/g,jn=/[\\t\\n\\r\\f]| {2,}|^ | $/;function zn(e){let t=e??"normal";return t==="pre-wrap"?{mode:t,preserveOrdinarySpaces:!0,preserveHardBreaks:!0}:{mode:t,preserveOrdinarySpaces:!1,preserveHardBreaks:!1}}function Un(e){if(!jn.test(e))return e;let t=e.replace(Hn," ");return t.charCodeAt(0)===32&&(t=t.slice(1)),t.length>0&&t.charCodeAt(t.length-1)===32&&(t=t.slice(0,-1)),t}function Gn(e){return/[\\r\\f]/.test(e)?e.replace(/\\r\\n/g,`\n`).replace(/[\\r\\f]/g,`\n`):e.replace(/\\r\\n/g,`\n`)}var ut=null,qn;function $n(){return ut===null&&(ut=new Intl.Segmenter(qn,{granularity:"word"})),ut}var Kn=/\\p{Script=Arabic}/u,Ge=/\\p{M}/u,Xt=/\\p{Nd}/u;function $t(e){return Kn.test(e)}function Kt(e){return e>=19968&&e<=40959||e>=13312&&e<=19903||e>=131072&&e<=173791||e>=173824&&e<=177983||e>=177984&&e<=178207||e>=178208&&e<=183983||e>=183984&&e<=191471||e>=191472&&e<=192093||e>=194560&&e<=195103||e>=196608&&e<=201551||e>=201552&&e<=205743||e>=205744&&e<=210041||e>=63744&&e<=64255||e>=12288&&e<=12351||e>=12352&&e<=12447||e>=12448&&e<=12543||e>=44032&&e<=55215||e>=65280&&e<=65519}function Fe(e){for(let t=0;t<e.length;t++){let n=e.charCodeAt(t);if(!(n<12288)){if(n>=55296&&n<=56319&&t+1<e.length){let o=e.charCodeAt(t+1);if(o>=56320&&o<=57343){let r=(n-55296<<10)+(o-56320)+65536;if(Kt(r))return!0;t++;continue}}if(Kt(n))return!0}}return!1}function Vn(e){let t=Ke(e);return t!==null&&($e.has(t)||ye.has(t))}var Jn=new Set(["\\xA0","\\u202F","\\u2060","\\uFEFF"]);function Qn(e){return Fe(e)}function Zn(e){let t=Ke(e);return t!==null&&Jn.has(t)}function qe(e){return!Vn(e)&&!Zn(e)}var $e=new Set(["\\uFF0C","\\uFF0E","\\uFF01","\\uFF1A","\\uFF1B","\\uFF1F","\\u3001","\\u3002","\\u30FB","\\uFF09","\\u3015","\\u3009","\\u300B","\\u300D","\\u300F","\\u3011","\\u3017","\\u3019","\\u301B","\\u30FC","\\u3005","\\u303B","\\u309D","\\u309E","\\u30FD","\\u30FE"]),He=new Set([\'"\',"(","[","{","\\u201C","\\u2018","\\xAB","\\u2039","\\uFF08","\\u3014","\\u3008","\\u300A","\\u300C","\\u300E","\\u3010","\\u3016","\\u3018","\\u301A"]),dt=new Set(["\'","\\u2019"]),ye=new Set([".",",","!","?",":",";","\\u060C","\\u061B","\\u061F","\\u0964","\\u0965","\\u104A","\\u104B","\\u104C","\\u104D","\\u104F",")","]","}","%",\'"\',"\\u201D","\\u2019","\\xBB","\\u203A","\\u2026"]),Yn=new Set([":",".","\\u060C","\\u061B"]),Xn=new Set(["\\u104F"]),ei=new Set(["\\u201D","\\u2019","\\xBB","\\u203A","\\u300D","\\u300F","\\u3011","\\u300B","\\u3009","\\u3015","\\uFF09"]);function ti(e){if(mt(e))return!0;let t=!1;for(let n of e){if(ye.has(n)){t=!0;continue}if(!(t&&Ge.test(n)))return!1}return t}function ni(e){for(let t of e)if(!$e.has(t)&&!ye.has(t))return!1;return e.length>0}function ii(e){if(mt(e))return!0;for(let t of e)if(!He.has(t)&&!dt.has(t)&&!Ge.test(t))return!1;return e.length>0}function mt(e){let t=!1;for(let n of e)if(!(n==="\\\\"||Ge.test(n))){if(He.has(n)||ye.has(n)||dt.has(n)){t=!0;continue}return!1}return t}function en(e,t){let n=t-1;if(n<=0)return Math.max(n,0);let o=e.charCodeAt(n);if(o<56320||o>57343)return n;let r=n-1;if(r<0)return n;let i=e.charCodeAt(r);return i>=55296&&i<=56319?r:n}function Ke(e){if(e.length===0)return null;let t=en(e,e.length);return e.slice(t)}function oi(e){let t=Array.from(e),n=t.length;for(;n>0;){let o=t[n-1];if(Ge.test(o)){n--;continue}if(He.has(o)||dt.has(o)){n--;continue}break}return n<=0||n===t.length?null:{head:t.slice(0,n).join(""),tail:t.slice(n).join("")}}function ri(e,t,n){return n==="text"&&!t&&e.length===1&&e!=="-"&&e!=="\\u2014"?e:null}function Vt(e,t,n,o){let r=t[o],i=e[o];if(r==null)return i;let u=n[o];if(i.length===u)return i;let d=r.repeat(u);return e[o]=d,d}function Jt(e,t){return e&&t!==null&&Yn.has(t)}function si(e){let t=Ke(e);return t!==null&&Xn.has(t)}function ai(e){if(e.length<2||e[0]!==" ")return null;let t=e.slice(1);return/^\\p{M}+$/u.test(t)?{space:" ",marks:t}:null}function Ve(e){let t=e.length;for(;t>0;){let n=en(e,t),o=e.slice(n,t);if(ei.has(o))return!0;if(!ye.has(o))return!1;t=n}return!1}function li(e,t){if(t.preserveOrdinarySpaces||t.preserveHardBreaks){if(e===" ")return"preserved-space";if(e===" ")return"tab";if(t.preserveHardBreaks&&e===`\n`)return"hard-break"}return e===" "?"space":e==="\\xA0"||e==="\\u202F"||e==="\\u2060"||e==="\\uFEFF"?"glue":e==="\\u200B"?"zero-width-break":e==="\\xAD"?"soft-hyphen":"text"}var ui=/[\\x20\\t\\n\\xA0\\xAD\\u200B\\u202F\\u2060\\uFEFF]/;function Se(e){return e.length===1?e[0]:e.join("")}function ci(e,t){let n=[];for(let o=e.length-1;o>=0;o--)n.push(e[o]);return n.push(t),Se(n)}function di(e,t,n,o){if(!ui.test(e))return[{text:e,isWordLike:t,kind:"text",start:n}];let r=[],i=null,u=[],d=n,c=!1,s=0;for(let a of e){let m=li(a,o),p=m==="text"&&t;if(i!==null&&m===i&&p===c){u.push(a),s+=a.length;continue}i!==null&&r.push({text:Se(u),isWordLike:c,kind:i,start:d}),i=m,u=[a],d=n+s,c=p,s+=a.length}return i!==null&&r.push({text:Se(u),isWordLike:c,kind:i,start:d}),r}function ct(e){return e==="space"||e==="preserved-space"||e==="zero-width-break"||e==="hard-break"}var mi=/^[A-Za-z][A-Za-z0-9+.-]*:$/;function xi(e,t){let n=e.texts[t];return n.startsWith("www.")?!0:mi.test(n)&&t+1<e.len&&e.kinds[t+1]==="text"&&e.texts[t+1]==="//"}function fi(e){return e.includes("?")&&(e.includes("://")||e.startsWith("www."))}function pi(e){let t=e.texts.slice(),n=e.isWordLike.slice(),o=e.kinds.slice(),r=e.starts.slice();for(let u=0;u<e.len;u++){if(o[u]!=="text"||!xi(e,u))continue;let d=[t[u]],c=u+1;for(;c<e.len&&!ct(o[c]);){d.push(t[c]),n[u]=!0;let s=t[c].includes("?");if(o[c]="text",t[c]="",c++,s)break}t[u]=Se(d)}let i=0;for(let u=0;u<t.length;u++){let d=t[u];d.length!==0&&(i!==u&&(t[i]=d,n[i]=n[u],o[i]=o[u],r[i]=r[u]),i++)}return t.length=i,n.length=i,o.length=i,r.length=i,{len:i,texts:t,isWordLike:n,kinds:o,starts:r}}function hi(e){let t=[],n=[],o=[],r=[];for(let i=0;i<e.len;i++){let u=e.texts[i];if(t.push(u),n.push(e.isWordLike[i]),o.push(e.kinds[i]),r.push(e.starts[i]),!fi(u))continue;let d=i+1;if(d>=e.len||ct(e.kinds[d]))continue;let c=[],s=e.starts[d],a=d;for(;a<e.len&&!ct(e.kinds[a]);)c.push(e.texts[a]),a++;c.length>0&&(t.push(Se(c)),n.push(!0),o.push("text"),r.push(s),i=a-1)}return{len:t.length,texts:t,isWordLike:n,kinds:o,starts:r}}var gi=new Set([":","-","/","\\xD7",",",".","+","\\u2013","\\u2014"]),Qt=/^[A-Za-z0-9_]+[,:;]*$/,Zt=/[,:;]+$/;function tn(e){for(let t of e)if(Xt.test(t))return!0;return!1}function We(e){if(e.length===0)return!1;for(let t of e)if(!(Xt.test(t)||gi.has(t)))return!1;return!0}function Si(e){let t=[],n=[],o=[],r=[];for(let i=0;i<e.len;i++){let u=e.texts[i],d=e.kinds[i];if(d==="text"&&We(u)&&tn(u)){let c=[u],s=i+1;for(;s<e.len&&e.kinds[s]==="text"&&We(e.texts[s]);)c.push(e.texts[s]),s++;t.push(Se(c)),n.push(!0),o.push("text"),r.push(e.starts[i]),i=s-1;continue}t.push(u),n.push(e.isWordLike[i]),o.push(d),r.push(e.starts[i])}return{len:t.length,texts:t,isWordLike:n,kinds:o,starts:r}}function Fi(e){let t=[],n=[],o=[],r=[];for(let i=0;i<e.len;i++){let u=e.texts[i],d=e.kinds[i],c=e.isWordLike[i];if(d==="text"&&c&&Qt.test(u)){let s=[u],a=Zt.test(u),m=i+1;for(;a&&m<e.len&&e.kinds[m]==="text"&&e.isWordLike[m]&&Qt.test(e.texts[m]);){let p=e.texts[m];s.push(p),a=Zt.test(p),m++}t.push(Se(s)),n.push(!0),o.push("text"),r.push(e.starts[i]),i=m-1;continue}t.push(u),n.push(c),o.push(d),r.push(e.starts[i])}return{len:t.length,texts:t,isWordLike:n,kinds:o,starts:r}}function Ni(e){let t=[],n=[],o=[],r=[];for(let i=0;i<e.len;i++){let u=e.texts[i];if(e.kinds[i]==="text"&&u.includes("-")){let d=u.split("-"),c=d.length>1;for(let s=0;s<d.length;s++){let a=d[s];if(!c)break;(a.length===0||!tn(a)||!We(a))&&(c=!1)}if(c){let s=0;for(let a=0;a<d.length;a++){let m=d[a],p=a<d.length-1?`${m}-`:m;t.push(p),n.push(!0),o.push("text"),r.push(e.starts[i]+s),s+=p.length}continue}}t.push(u),n.push(e.isWordLike[i]),o.push(e.kinds[i]),r.push(e.starts[i])}return{len:t.length,texts:t,isWordLike:n,kinds:o,starts:r}}function Ai(e){let t=[],n=[],o=[],r=[],i=0;for(;i<e.len;){let u=[e.texts[i]],d=e.isWordLike[i],c=e.kinds[i],s=e.starts[i];if(c==="glue"){let a=[u[0]],m=s;for(i++;i<e.len&&e.kinds[i]==="glue";)a.push(e.texts[i]),i++;let p=Se(a);if(i<e.len&&e.kinds[i]==="text")u[0]=p,u.push(e.texts[i]),d=e.isWordLike[i],c="text",s=m,i++;else{t.push(p),n.push(!1),o.push("glue"),r.push(m);continue}}else i++;if(c==="text")for(;i<e.len&&e.kinds[i]==="glue";){let a=[];for(;i<e.len&&e.kinds[i]==="glue";)a.push(e.texts[i]),i++;let m=Se(a);if(i<e.len&&e.kinds[i]==="text"){u.push(m,e.texts[i]),d=d||e.isWordLike[i],i++;continue}u.push(m)}t.push(Se(u)),n.push(d),o.push(c),r.push(s)}return{len:t.length,texts:t,isWordLike:n,kinds:o,starts:r}}function Ei(e){let t=e.texts.slice(),n=e.isWordLike.slice(),o=e.kinds.slice(),r=e.starts.slice();for(let i=0;i<t.length-1;i++){if(o[i]!=="text"||o[i+1]!=="text"||!Fe(t[i])||!Fe(t[i+1]))continue;let u=oi(t[i]);u!==null&&(t[i]=u.head,t[i+1]=u.tail+t[i+1],r[i+1]=r[i]+u.head.length)}return{len:t.length,texts:t,isWordLike:n,kinds:o,starts:r}}function Yt(e,t,n){let o=$n(),r=0,i=[],u=[],d=[],c=[],s=[],a=[],m=[],p=[],F=[],D=[],C=[],T=[];for(let x of o.segment(e))for(let g of di(x.segment,x.isWordLike??!1,x.index,n)){let K=function(){a[w]!==null&&(u[w]=[Vt(i,a,m,w)],a[w]=null),u[w].push(g.text),d[w]=d[w]||g.isWordLike,p[w]=p[w]||y,F[w]=F[w]||v,D[w]=O,C[w]=V,T[w]=Jt(F[w],_)},E=g.kind==="text",b=ri(g.text,g.isWordLike,g.kind),y=Fe(g.text),v=$t(g.text),_=Ke(g.text),O=Ve(g.text),V=si(g.text),w=r-1;t.carryCJKAfterClosingQuote&&E&&r>0&&c[w]==="text"&&y&&p[w]&&D[w]||E&&r>0&&c[w]==="text"&&ni(g.text)&&p[w]||E&&r>0&&c[w]==="text"&&C[w]?K():E&&r>0&&c[w]==="text"&&g.isWordLike&&v&&T[w]?(K(),d[w]=!0):b!==null&&r>0&&c[w]==="text"&&a[w]===b?m[w]=(m[w]??1)+1:E&&!g.isWordLike&&r>0&&c[w]==="text"&&(ti(g.text)||g.text==="-"&&d[w])?K():(i[r]=g.text,u[r]=[g.text],d[r]=g.isWordLike,c[r]=g.kind,s[r]=g.start,a[r]=b,m[r]=b===null?0:1,p[r]=y,F[r]=v,D[r]=O,C[r]=V,T[r]=Jt(v,_),r++)}for(let x=0;x<r;x++){if(a[x]!==null){i[x]=Vt(i,a,m,x);continue}i[x]=Se(u[x])}for(let x=1;x<r;x++)c[x]==="text"&&!d[x]&&mt(i[x])&&c[x-1]==="text"&&(i[x-1]+=i[x],d[x-1]=d[x-1]||d[x],i[x]="");let U=Array.from({length:r},()=>null),z=-1;for(let x=r-1;x>=0;x--){let g=i[x];if(g.length!==0){if(c[x]==="text"&&!d[x]&&ii(g)&&z>=0&&c[z]==="text"){let E=U[z]??[];E.push(g),U[z]=E,s[z]=s[x],i[x]="";continue}z=x}}for(let x=0;x<r;x++){let g=U[x];g!=null&&(i[x]=ci(g,i[x]))}let k=0;for(let x=0;x<r;x++){let g=i[x];g.length!==0&&(k!==x&&(i[k]=g,d[k]=d[x],c[k]=c[x],s[k]=s[x]),k++)}i.length=k,d.length=k,c.length=k,s.length=k;let Q=Ai({len:k,texts:i,isWordLike:d,kinds:c,starts:s}),S=Ei(Fi(Ni(Si(hi(pi(Q))))));for(let x=0;x<S.len-1;x++){let g=ai(S.texts[x]);g!==null&&(S.kinds[x]!=="space"&&S.kinds[x]!=="preserved-space"||S.kinds[x+1]!=="text"||!$t(S.texts[x+1])||(S.texts[x]=g.space,S.isWordLike[x]=!1,S.kinds[x]=S.kinds[x]==="preserved-space"?"preserved-space":"space",S.texts[x+1]=g.marks+S.texts[x+1],S.starts[x+1]=S.starts[x]+g.space.length))}return S}function yi(e,t){if(e.len===0)return[];if(!t.preserveHardBreaks)return[{startSegmentIndex:0,endSegmentIndex:e.len,consumedEndSegmentIndex:e.len}];let n=[],o=0;for(let r=0;r<e.len;r++)e.kinds[r]==="hard-break"&&(n.push({startSegmentIndex:o,endSegmentIndex:r,consumedEndSegmentIndex:r+1}),o=r+1);return o<e.len&&n.push({startSegmentIndex:o,endSegmentIndex:e.len,consumedEndSegmentIndex:e.len}),n}function bi(e){if(e.len<=1)return e;let t=[],n=[],o=[],r=[],i=null,u=!1,d=0,c=!1,s=!1;function a(){i!==null&&(t.push(Se(i)),n.push(u),o.push("text"),r.push(d),i=null)}for(let m=0;m<e.len;m++){let p=e.texts[m],F=e.kinds[m],D=e.isWordLike[m],C=e.starts[m];if(F==="text"){let T=Qn(p),U=qe(p);if(i!==null&&c&&s){i.push(p),u=u||D,c=c||T,s=U;continue}a(),i=[p],u=D,d=C,c=T,s=U;continue}a(),t.push(p),n.push(D),o.push(F),r.push(C)}return a(),{len:t.length,texts:t,isWordLike:n,kinds:o,starts:r}}function nn(e,t,n="normal",o="normal"){let r=zn(n),i=r.mode==="pre-wrap"?Gn(e):Un(e);if(i.length===0)return{normalized:i,chunks:[],len:0,texts:[],isWordLike:[],kinds:[],starts:[]};let u=o==="keep-all"?bi(Yt(i,t,r)):Yt(i,t,r);return{normalized:i,chunks:yi(u,r),...u}}var Be=null,on=new Map,Re=null,Mi=96,Ci=/\\p{Emoji_Presentation}/u,Di=/[\\p{Emoji_Presentation}\\p{Extended_Pictographic}\\p{Regional_Indicator}\\uFE0F\\u20E3]/u,xt=null,rn=new Map;function ft(){if(Be!==null)return Be;if(typeof OffscreenCanvas<"u")return Be=new OffscreenCanvas(1,1).getContext("2d"),Be;if(typeof document<"u")return Be=document.createElement("canvas").getContext("2d"),Be;throw new Error("Text measurement requires OffscreenCanvas or a DOM canvas context.")}function ki(e){let t=on.get(e);return t||(t=new Map,on.set(e,t)),t}function Ne(e,t){let n=t.get(e);return n===void 0&&(n={width:ft().measureText(e).width,containsCJK:Fe(e)},t.set(e,n)),n}function ve(){if(Re!==null)return Re;if(typeof navigator>"u")return Re={lineFitEpsilon:.005,carryCJKAfterClosingQuote:!1,preferPrefixWidthsForBreakableRuns:!1,preferEarlySoftHyphenBreak:!1},Re;let e=navigator.userAgent,n=navigator.vendor==="Apple Computer, Inc."&&e.includes("Safari/")&&!e.includes("Chrome/")&&!e.includes("Chromium/")&&!e.includes("CriOS/")&&!e.includes("FxiOS/")&&!e.includes("EdgiOS/"),o=e.includes("Chrome/")||e.includes("Chromium/")||e.includes("CriOS/")||e.includes("Edg/");return Re={lineFitEpsilon:n?1/64:.005,carryCJKAfterClosingQuote:o,preferPrefixWidthsForBreakableRuns:n,preferEarlySoftHyphenBreak:n},Re}function Li(e){let t=e.match(/(\\d+(?:\\.\\d+)?)\\s*px/);return t?parseFloat(t[1]):16}function sn(){return xt===null&&(xt=new Intl.Segmenter(void 0,{granularity:"grapheme"})),xt}function Ti(e){return Ci.test(e)||e.includes("\\uFE0F")}function an(e){return Di.test(e)}function wi(e,t){let n=rn.get(e);if(n!==void 0)return n;let o=ft();o.font=e;let r=o.measureText("\\u{1F600}").width;if(n=0,r>t+.5&&typeof document<"u"&&document.body!==null){let i=document.createElement("span");i.style.font=e,i.style.display="inline-block",i.style.visibility="hidden",i.style.position="absolute",i.textContent="\\u{1F600}",document.body.appendChild(i);let u=i.getBoundingClientRect().width;document.body.removeChild(i),r-u>.5&&(n=r-u)}return rn.set(e,n),n}function Bi(e){let t=0,n=sn();for(let o of n.segment(e))Ti(o.segment)&&t++;return t}function Ri(e,t){return t.emojiCount===void 0&&(t.emojiCount=Bi(e)),t.emojiCount}function be(e,t,n){return n===0?t.width:t.width-Ri(e,t)*n}function ln(e,t,n,o,r){if(t.breakableFitAdvances!==void 0)return t.breakableFitAdvances;let i=sn(),u=[];for(let a of i.segment(e))u.push(a.segment);if(u.length<=1)return t.breakableFitAdvances=null,t.breakableFitAdvances;if(r==="sum-graphemes"){let a=[];for(let m of u){let p=Ne(m,n);a.push(be(m,p,o))}return t.breakableFitAdvances=a,t.breakableFitAdvances}if(r==="pair-context"||u.length>Mi){let a=[],m=null,p=0;for(let F of u){let D=Ne(F,n),C=be(F,D,o);if(m===null)a.push(C);else{let T=m+F,U=Ne(T,n);a.push(be(T,U,o)-p)}m=F,p=C}return t.breakableFitAdvances=a,t.breakableFitAdvances}let d=[],c="",s=0;for(let a of u){c+=a;let m=Ne(c,n),p=be(c,m,o);d.push(p-s),s=p}return t.breakableFitAdvances=d,t.breakableFitAdvances}function un(e,t){let n=ft();n.font=e;let o=ki(e),r=Li(e),i=t?wi(e,r):0;return{cache:o,fontSize:r,emojiCorrection:i}}function vi(e,t){for(;t<e.widths.length;){let n=e.kinds[t];if(n!=="space"&&n!=="zero-width-break"&&n!=="soft-hyphen")break;t++}return t}function Ii(e,t){if(t<=0)return 0;let n=e%t;return Math.abs(n)<=1e-6?t:t-n}function Pi(e,t,n,o,r){let i=0,u=t;for(;i<e.length;){let d=u+e[i];if((i+1<e.length?d+r:d)>n+o)break;u=d,i++}return{fitCount:i,fittedWidth:u}}function cn(e,t){return e.simpleLineWalkFastPath?dn(e,t):mn(e,t)}function dn(e,t,n){let{widths:o,kinds:r,breakableFitAdvances:i}=e;if(o.length===0)return 0;let d=ve().lineFitEpsilon,c=t+d,s=0,a=0,m=!1,p=0,F=0,D=0,C=0,T=-1,U=0;function z(){T=-1,U=0}function k(b=D,y=C,v=a){s++,n?.({startSegmentIndex:p,startGraphemeIndex:F,endSegmentIndex:b,endGraphemeIndex:y,width:v}),a=0,m=!1,z()}function Q(b,y){m=!0,p=b,F=0,D=b+1,C=0,a=y}function S(b,y,v){m=!0,p=b,F=y,D=b,C=y+1,a=v}function x(b,y){if(!m){Q(b,y);return}a+=y,D=b+1,C=0}function g(b,y){let v=i[b];for(let _=y;_<v.length;_++){let O=v[_];m?a+O>c?(k(),S(b,_,O)):(a+=O,D=b,C=_+1):S(b,_,O)}m&&D===b&&C===v.length&&(D=b+1,C=0)}let E=0;for(;E<o.length&&!(!m&&(E=vi(e,E),E>=o.length));){let b=o[E],y=r[E],v=y==="space"||y==="preserved-space"||y==="tab"||y==="zero-width-break"||y==="soft-hyphen";if(!m){b>t&&i[E]!==null?g(E,0):Q(E,b),v&&(T=E+1,U=a-b),E++;continue}if(a+b>c){if(v){x(E,b),k(E+1,0,a-b),E++;continue}if(T>=0){if(D>T||D===T&&C>0){k();continue}k(T,0,U);continue}if(b>t&&i[E]!==null){k(),g(E,0),E++;continue}k();continue}x(E,b),v&&(T=E+1,U=a-b),E++}return m&&k(),s}function mn(e,t,n){if(e.simpleLineWalkFastPath)return dn(e,t,n);let{widths:o,lineEndFitAdvances:r,lineEndPaintAdvances:i,kinds:u,breakableFitAdvances:d,discretionaryHyphenWidth:c,tabStopAdvance:s,chunks:a}=e;if(o.length===0||a.length===0)return 0;let m=ve(),p=m.lineFitEpsilon,F=t+p,D=0,C=0,T=!1,U=0,z=0,k=0,Q=0,S=-1,x=0,g=0,E=null;function b(){S=-1,x=0,g=0,E=null}function y(W=k,j=Q,R=C){D++,n?.({startSegmentIndex:U,startGraphemeIndex:z,endSegmentIndex:W,endGraphemeIndex:j,width:R}),C=0,T=!1,b()}function v(W,j){T=!0,U=W,z=0,k=W+1,Q=0,C=j}function _(W,j,R){T=!0,U=W,z=j,k=W,Q=j+1,C=R}function O(W,j){if(!T){v(W,j);return}C+=j,k=W+1,Q=0}function V(W,j,R,$){if(!j)return;let pe=W==="tab"?0:r[R],ue=W==="tab"?$:i[R];S=R+1,x=C-$+pe,g=C-$+ue,E=W}function w(W,j){let R=d[W];for(let $=j;$<R.length;$++){let pe=R[$];T?C+pe>F?(y(),_(W,$,pe)):(C+=pe,k=W,Q=$+1):_(W,$,pe)}T&&k===W&&Q===R.length&&(k=W+1,Q=0)}function K(W){if(E!=="soft-hyphen")return!1;let j=d[W];if(j==null)return!1;let{fitCount:R,fittedWidth:$}=Pi(j,C,t,p,c);return R===0?!1:(C=$,k=W,Q=R,b(),R===j.length?(k=W+1,Q=0,!0):(y(W,R,$+c),w(W,R),!0))}function Z(W){D++,n?.({startSegmentIndex:W.startSegmentIndex,startGraphemeIndex:0,endSegmentIndex:W.consumedEndSegmentIndex,endGraphemeIndex:0,width:0}),b()}for(let W=0;W<a.length;W++){let j=a[W];if(j.startSegmentIndex===j.endSegmentIndex){Z(j);continue}T=!1,C=0,U=j.startSegmentIndex,z=0,k=j.startSegmentIndex,Q=0,b();let R=j.startSegmentIndex;for(;R<j.endSegmentIndex;){let $=u[R],pe=$==="space"||$==="preserved-space"||$==="tab"||$==="zero-width-break"||$==="soft-hyphen",ue=$==="tab"?Ii(C,s):o[R];if($==="soft-hyphen"){T&&(k=R+1,Q=0,S=R+1,x=C+c,g=C+c,E=$),R++;continue}if(!T){ue>t&&d[R]!==null?w(R,0):v(R,ue),V($,pe,R,ue),R++;continue}if(C+ue>F){let M=C+($==="tab"?0:r[R]),L=C+($==="tab"?ue:i[R]);if(E==="soft-hyphen"&&m.preferEarlySoftHyphenBreak&&x<=F){y(S,0,g);continue}if(E==="soft-hyphen"&&K(R)){R++;continue}if(pe&&M<=F){O(R,ue),y(R+1,0,L),R++;continue}if(S>=0&&x<=F){if(k>S||k===S&&Q>0){y();continue}let J=S;y(J,0,g),R=J;continue}if(ue>t&&d[R]!==null){y(),w(R,0),R++;continue}y();continue}O(R,ue),V($,pe,R,ue),R++}if(T){let $=S===j.consumedEndSegmentIndex?g:C;y(j.consumedEndSegmentIndex,0,$)}}return D}var pt=null;function Oi(){return pt===null&&(pt=new Intl.Segmenter(void 0,{granularity:"grapheme"})),pt}function _i(e){return e?{widths:[],lineEndFitAdvances:[],lineEndPaintAdvances:[],kinds:[],simpleLineWalkFastPath:!0,segLevels:null,breakableFitAdvances:[],discretionaryHyphenWidth:0,tabStopAdvance:0,chunks:[],segments:[]}:{widths:[],lineEndFitAdvances:[],lineEndPaintAdvances:[],kinds:[],simpleLineWalkFastPath:!0,segLevels:null,breakableFitAdvances:[],discretionaryHyphenWidth:0,tabStopAdvance:0,chunks:[]}}function Wi(e,t){let n=[],o=[],r=0,i=!1,u=!1,d=!1;function c(){o.length!==0&&(n.push({text:o.length===1?o[0]:o.join(""),start:r}),o=[],i=!1,u=!1,d=!1)}function s(m,p,F){o=[m],r=p,i=F,u=Ve(m),d=He.has(m)}function a(m,p){o.push(m),i=i||p;let F=Ve(m);m.length===1&&ye.has(m)?u=u||F:u=F,d=!1}for(let m of Oi().segment(e)){let p=m.segment,F=Fe(p);if(o.length===0){s(p,m.index,F);continue}if(d||$e.has(p)||ye.has(p)||t.carryCJKAfterClosingQuote&&F&&u){a(p,F);continue}if(!i&&!F){a(p,F);continue}c(),s(p,m.index,F)}return c(),n}function Hi(e){if(e.length<=1)return e;let t=[],n=[e[0].text],o=e[0].start,r=Fe(e[0].text),i=qe(e[0].text);function u(){t.push({text:n.length===1?n[0]:n.join(""),start:o})}for(let d=1;d<e.length;d++){let c=e[d],s=Fe(c.text),a=qe(c.text);if(r&&i){n.push(c.text),r=r||s,i=a;continue}u(),n=[c.text],o=c.start,r=s,i=a}return u(),t}function ji(e,t,n,o){let r=ve(),{cache:i,emojiCorrection:u}=un(t,an(e.normalized)),d=be("-",Ne("-",i),u),s=be(" ",Ne(" ",i),u)*8;if(e.len===0)return _i(n);let a=[],m=[],p=[],F=[],D=e.chunks.length<=1,C=n?[]:null,T=[],U=n?[]:null,z=Array.from({length:e.len});function k(g,E,b,y,v,_,O){v!=="text"&&v!=="space"&&v!=="zero-width-break"&&(D=!1),a.push(E),m.push(b),p.push(y),F.push(v),C?.push(_),T.push(O),U!==null&&U.push(g)}function Q(g,E,b,y,v){let _=Ne(g,i),O=be(g,_,u),V=E==="space"||E==="preserved-space"||E==="zero-width-break"?0:O,w=E==="space"||E==="zero-width-break"?0:O;if(v&&y&&g.length>1){let K="sum-graphemes";We(g)?K="pair-context":r.preferPrefixWidthsForBreakableRuns&&(K="segment-prefixes");let Z=ln(g,_,i,u,K);k(g,O,V,w,E,b,Z);return}k(g,O,V,w,E,b,null)}for(let g=0;g<e.len;g++){z[g]=a.length;let E=e.texts[g],b=e.isWordLike[g],y=e.kinds[g],v=e.starts[g];if(y==="soft-hyphen"){k(E,0,d,d,y,v,null);continue}if(y==="hard-break"){k(E,0,0,0,y,v,null);continue}if(y==="tab"){k(E,0,0,0,y,v,null);continue}let _=Ne(E,i);if(y==="text"&&_.containsCJK){let O=Wi(E,r),V=o==="keep-all"?Hi(O):O;for(let w=0;w<V.length;w++){let K=V[w];Q(K.text,"text",v+K.start,b,o==="keep-all"||!Fe(K.text))}continue}Q(E,y,v,b,!0)}let S=zi(e.chunks,z,a.length),x=C===null?null:qt(e.normalized,C);return U!==null?{widths:a,lineEndFitAdvances:m,lineEndPaintAdvances:p,kinds:F,simpleLineWalkFastPath:D,segLevels:x,breakableFitAdvances:T,discretionaryHyphenWidth:d,tabStopAdvance:s,chunks:S,segments:U}:{widths:a,lineEndFitAdvances:m,lineEndPaintAdvances:p,kinds:F,simpleLineWalkFastPath:D,segLevels:x,breakableFitAdvances:T,discretionaryHyphenWidth:d,tabStopAdvance:s,chunks:S}}function zi(e,t,n){let o=[];for(let r=0;r<e.length;r++){let i=e[r],u=i.startSegmentIndex<t.length?t[i.startSegmentIndex]:n,d=i.endSegmentIndex<t.length?t[i.endSegmentIndex]:n,c=i.consumedEndSegmentIndex<t.length?t[i.consumedEndSegmentIndex]:n;o.push({startSegmentIndex:u,endSegmentIndex:d,consumedEndSegmentIndex:c})}return o}function Ui(e,t,n,o){let r=o?.wordBreak??"normal",i=nn(e,ve(),o?.whiteSpace,r);return ji(i,t,n,r)}function xn(e,t,n){return Ui(e,t,!1,n)}function fn(e,t,n){let o=cn(e,t);return{lineCount:o,height:o*n}}var Gi={maxWidth:1600,baseFontSize:78,minFontSize:42,fontWeight:900,fontFamily:"Outfit",step:2};function pn(e,t){let n={...Gi,...t},o=1.2;for(let r=n.baseFontSize;r>=n.minFontSize;r-=n.step){let i=`${n.fontWeight} ${r}px ${n.fontFamily}`,u=xn(e,i),{lineCount:d}=fn(u,n.maxWidth,r*o);if(d<=1)return{fontSize:r,fits:!0}}return{fontSize:n.minFontSize,fits:!1}}window.__timelines=window.__timelines||{};window.__hyperframes={fitTextFontSize:pn};function hn(){let e=window;e.__hyperframeRuntimeBootstrapped||(e.__hyperframeRuntimeBootstrapped=!0,Ut())}document.readyState==="loading"?document.addEventListener("DOMContentLoaded",hn,{once:!0}):hn();})();\n';
5998
+ }
5999
+ });
6000
+
5987
6001
  // ../core/src/inline-scripts/parityContract.ts
5988
6002
  function quantizeTimeToFrame(timeSeconds, fps) {
5989
6003
  const safeFps = Number.isFinite(fps) && fps > 0 ? fps : 30;
@@ -9192,6 +9206,7 @@ __export(src_exports, {
9192
9206
  generateHyperframesStyles: () => generateHyperframesStyles,
9193
9207
  getAnimationsForElement: () => getAnimationsForElement,
9194
9208
  getDefaultStageZoom: () => getDefaultStageZoom,
9209
+ getHyperframeRuntimeScript: () => getHyperframeRuntimeScript,
9195
9210
  getStageStyles: () => getStageStyles,
9196
9211
  gsapAnimationsToKeyframes: () => gsapAnimationsToKeyframes,
9197
9212
  injectDurations: () => injectDurations,
@@ -9237,6 +9252,7 @@ var init_src = __esm({
9237
9252
  init_rewriteSubCompPaths();
9238
9253
  init_hyperframe();
9239
9254
  init_runtimeContract();
9255
+ init_runtime_inline();
9240
9256
  init_hyperframesRuntime_engine();
9241
9257
  init_parityContract();
9242
9258
  init_gsap2();
@@ -9450,12 +9466,12 @@ var init_generators = __esm({
9450
9466
  });
9451
9467
 
9452
9468
  // src/templates/remote.ts
9453
- import { existsSync } from "fs";
9469
+ import { existsSync as existsSync2 } from "fs";
9454
9470
  import { join as join3 } from "path";
9455
9471
  async function fetchRemoteTemplate(templateId, destDir) {
9456
9472
  const item = await resolveItem(templateId);
9457
9473
  await installItem(item, { destDir });
9458
- if (!existsSync(join3(destDir, "index.html"))) {
9474
+ if (!existsSync2(join3(destDir, "index.html"))) {
9459
9475
  throw new Error(
9460
9476
  `Example "${templateId}" installed but missing index.html. The registry item may be malformed.`
9461
9477
  );
@@ -9469,13 +9485,13 @@ var init_remote2 = __esm({
9469
9485
  });
9470
9486
 
9471
9487
  // src/telemetry/config.ts
9472
- import { existsSync as existsSync2, mkdirSync as mkdirSync2, readFileSync as readFileSync2, writeFileSync as writeFileSync2 } from "fs";
9488
+ import { existsSync as existsSync3, mkdirSync as mkdirSync2, readFileSync as readFileSync2, writeFileSync as writeFileSync2 } from "fs";
9473
9489
  import { join as join4 } from "path";
9474
9490
  import { homedir as homedir2 } from "os";
9475
9491
  import { randomUUID } from "crypto";
9476
9492
  function readConfig() {
9477
9493
  if (cachedConfig) return { ...cachedConfig };
9478
- if (!existsSync2(CONFIG_FILE)) {
9494
+ if (!existsSync3(CONFIG_FILE)) {
9479
9495
  const config = { ...DEFAULT_CONFIG, anonymousId: randomUUID() };
9480
9496
  writeConfig(config);
9481
9497
  return config;
@@ -9549,7 +9565,7 @@ var init_env = __esm({
9549
9565
 
9550
9566
  // src/telemetry/system.ts
9551
9567
  import { cpus, totalmem, platform, release } from "os";
9552
- import { existsSync as existsSync3, readFileSync as readFileSync3, statfsSync } from "fs";
9568
+ import { existsSync as existsSync4, readFileSync as readFileSync3, statfsSync } from "fs";
9553
9569
  function bytesToMb(bytes) {
9554
9570
  return Math.trunc(bytes / (1024 * 1024));
9555
9571
  }
@@ -9573,7 +9589,7 @@ function getSystemMeta() {
9573
9589
  }
9574
9590
  function detectDocker() {
9575
9591
  try {
9576
- if (existsSync3("/.dockerenv")) return true;
9592
+ if (existsSync4("/.dockerenv")) return true;
9577
9593
  if (platform() === "linux") {
9578
9594
  const cgroup = readFileSync3("/proc/1/cgroup", "utf-8");
9579
9595
  if (cgroup.includes("docker") || cgroup.includes("containerd")) return true;
@@ -9821,7 +9837,7 @@ import { get as httpsGet } from "https";
9821
9837
  import { pipeline } from "stream/promises";
9822
9838
  function downloadFile(url, dest) {
9823
9839
  const tmp = `${dest}.tmp`;
9824
- return new Promise((resolve37, reject) => {
9840
+ return new Promise((resolve38, reject) => {
9825
9841
  const follow = (u) => {
9826
9842
  httpsGet(u, (res) => {
9827
9843
  if (res.statusCode === 301 || res.statusCode === 302) {
@@ -9838,7 +9854,7 @@ function downloadFile(url, dest) {
9838
9854
  const file = createWriteStream(tmp);
9839
9855
  pipeline(res, file).then(() => {
9840
9856
  renameSync(tmp, dest);
9841
- resolve37();
9857
+ resolve38();
9842
9858
  }).catch((err) => {
9843
9859
  try {
9844
9860
  unlinkSync(tmp);
@@ -9875,7 +9891,7 @@ __export(manager_exports, {
9875
9891
  hasFFmpeg: () => hasFFmpeg
9876
9892
  });
9877
9893
  import { execFileSync } from "child_process";
9878
- import { existsSync as existsSync4, mkdirSync as mkdirSync3, rmSync } from "fs";
9894
+ import { existsSync as existsSync5, mkdirSync as mkdirSync3, rmSync } from "fs";
9879
9895
  import { homedir as homedir3, platform as platform2 } from "os";
9880
9896
  import { join as join5 } from "path";
9881
9897
  function getModelUrl(model) {
@@ -9897,7 +9913,7 @@ function whichBinary(name) {
9897
9913
  }
9898
9914
  function findFromEnv() {
9899
9915
  const envPath = process.env["HYPERFRAMES_WHISPER_PATH"];
9900
- if (envPath && existsSync4(envPath)) {
9916
+ if (envPath && existsSync5(envPath)) {
9901
9917
  return { executablePath: envPath, source: "env" };
9902
9918
  }
9903
9919
  return void 0;
@@ -9909,7 +9925,7 @@ function findFromSystem() {
9909
9925
  }
9910
9926
  if (platform2() === "darwin") {
9911
9927
  for (const p of ["/opt/homebrew/bin/whisper-cli", "/usr/local/bin/whisper-cli"]) {
9912
- if (existsSync4(p)) return { executablePath: p, source: "system" };
9928
+ if (existsSync5(p)) return { executablePath: p, source: "system" };
9913
9929
  }
9914
9930
  }
9915
9931
  return void 0;
@@ -9919,15 +9935,15 @@ function findBuiltBinary() {
9919
9935
  join5(BUILD_DIR, "build", "bin", "whisper-cli"),
9920
9936
  join5(BUILD_DIR, "build", "whisper-cli")
9921
9937
  ]) {
9922
- if (existsSync4(p)) return { executablePath: p, source: "build" };
9938
+ if (existsSync5(p)) return { executablePath: p, source: "build" };
9923
9939
  }
9924
9940
  return void 0;
9925
9941
  }
9926
9942
  function buildFromSource(onProgress) {
9927
- if (existsSync4(BUILD_DIR) && !findBuiltBinary()) {
9943
+ if (existsSync5(BUILD_DIR) && !findBuiltBinary()) {
9928
9944
  rmSync(BUILD_DIR, { recursive: true, force: true });
9929
9945
  }
9930
- if (!existsSync4(BUILD_DIR)) {
9946
+ if (!existsSync5(BUILD_DIR)) {
9931
9947
  onProgress?.("Downloading whisper.cpp...");
9932
9948
  mkdirSync3(join5(homedir3(), ".cache", "hyperframes", "whisper"), {
9933
9949
  recursive: true
@@ -10009,11 +10025,11 @@ async function ensureWhisper(options) {
10009
10025
  }
10010
10026
  async function ensureModel(model = DEFAULT_MODEL, options) {
10011
10027
  const modelPath = join5(MODELS_DIR, `ggml-${model}.bin`);
10012
- if (existsSync4(modelPath)) return modelPath;
10028
+ if (existsSync5(modelPath)) return modelPath;
10013
10029
  mkdirSync3(MODELS_DIR, { recursive: true });
10014
10030
  options?.onProgress?.(`Downloading model ${model}...`);
10015
10031
  await downloadFile(getModelUrl(model), modelPath);
10016
- if (!existsSync4(modelPath)) {
10032
+ if (!existsSync5(modelPath)) {
10017
10033
  throw new Error(`Model download failed: ${model}`);
10018
10034
  }
10019
10035
  return modelPath;
@@ -10328,7 +10344,7 @@ __export(transcribe_exports, {
10328
10344
  transcribe: () => transcribe
10329
10345
  });
10330
10346
  import { execFileSync as execFileSync2 } from "child_process";
10331
- import { existsSync as existsSync5, readFileSync as readFileSync6, mkdirSync as mkdirSync4, unlinkSync as unlinkSync2 } from "fs";
10347
+ import { existsSync as existsSync6, readFileSync as readFileSync6, mkdirSync as mkdirSync4, unlinkSync as unlinkSync2 } from "fs";
10332
10348
  import { join as join8, extname as extname2 } from "path";
10333
10349
  import { tmpdir } from "os";
10334
10350
  function detectLanguage(whisperPath, modelPath, wavPath) {
@@ -10502,7 +10518,7 @@ async function transcribe(inputPath, outputDir, options) {
10502
10518
  whisperArgs.push(wavPath);
10503
10519
  execFileSync2(whisper.executablePath, whisperArgs, { stdio: "ignore", timeout: 3e5 });
10504
10520
  const transcriptPath = `${outputBase}.json`;
10505
- if (!existsSync5(transcriptPath)) {
10521
+ if (!existsSync6(transcriptPath)) {
10506
10522
  throw new Error("Whisper did not produce output. Check the input file.");
10507
10523
  }
10508
10524
  const transcript = JSON.parse(readFileSync6(transcriptPath, "utf-8"));
@@ -10556,7 +10572,7 @@ function hasNpx() {
10556
10572
  }
10557
10573
  }
10558
10574
  function runSkillsAdd(repo) {
10559
- return new Promise((resolve37, reject) => {
10575
+ return new Promise((resolve38, reject) => {
10560
10576
  const child = spawn("npx", ["skills", "add", repo, "--all"], {
10561
10577
  stdio: "inherit",
10562
10578
  timeout: 12e4,
@@ -10570,7 +10586,7 @@ function runSkillsAdd(repo) {
10570
10586
  env: { ...process.env, GIT_CLONE_PROTECTION_ACTIVE: "0" }
10571
10587
  });
10572
10588
  child.on("close", (code, signal) => {
10573
- if (code === 0) resolve37();
10589
+ if (code === 0) resolve38();
10574
10590
  else if (signal === "SIGINT" || code === 130) process.exit(0);
10575
10591
  else reject(new Error(`npx skills add exited with code ${code}`));
10576
10592
  });
@@ -10625,7 +10641,7 @@ var init_lint = __esm({
10625
10641
  });
10626
10642
 
10627
10643
  // src/utils/lintProject.ts
10628
- import { existsSync as existsSync6, readFileSync as readFileSync7, readdirSync as readdirSync2 } from "fs";
10644
+ import { existsSync as existsSync7, readFileSync as readFileSync7, readdirSync as readdirSync2 } from "fs";
10629
10645
  import { join as join9, resolve as resolve5, extname as extname3 } from "path";
10630
10646
  function lintProject(project) {
10631
10647
  const results = [];
@@ -10640,7 +10656,7 @@ function lintProject(project) {
10640
10656
  totalInfos += rootResult.infoCount;
10641
10657
  const allHtmlSources = [rootHtml];
10642
10658
  const compositionsDir = resolve5(project.dir, "compositions");
10643
- if (existsSync6(compositionsDir)) {
10659
+ if (existsSync7(compositionsDir)) {
10644
10660
  const files = readdirSync2(compositionsDir).filter((f3) => f3.endsWith(".html"));
10645
10661
  for (const file of files) {
10646
10662
  const filePath = join9(compositionsDir, file);
@@ -10710,7 +10726,7 @@ function lintAudioSrcNotFound(projectDir, htmlSources) {
10710
10726
  if (/^(https?:|data:|blob:)/i.test(src)) continue;
10711
10727
  if (/^__[A-Z_]+__$/.test(src)) continue;
10712
10728
  const resolved = resolve5(projectDir, src);
10713
- if (!existsSync6(resolved)) {
10729
+ if (!existsSync7(resolved)) {
10714
10730
  missingSrcs.push(src);
10715
10731
  }
10716
10732
  }
@@ -11134,29 +11150,75 @@ var init_fileWatcher = __esm({
11134
11150
  });
11135
11151
 
11136
11152
  // src/server/runtimeSource.ts
11137
- async function loadRuntimeSourceFallback() {
11153
+ import { existsSync as existsSync8, readFileSync as readFileSync8 } from "fs";
11154
+ import { resolve as resolve7, dirname as dirname4 } from "path";
11155
+ async function loadRuntimeSource() {
11156
+ return await buildFromSource2() ?? await getInlinedRuntime() ?? readPrebuiltArtifact();
11157
+ }
11158
+ async function buildFromSource2() {
11159
+ if (!existsSync8(ENTRY_TS)) return null;
11138
11160
  try {
11139
11161
  const mod = await Promise.resolve().then(() => (init_src(), src_exports));
11140
11162
  if (typeof mod.loadHyperframeRuntimeSource === "function") {
11141
- return mod.loadHyperframeRuntimeSource();
11163
+ const source = mod.loadHyperframeRuntimeSource();
11164
+ if (source) return source;
11142
11165
  }
11143
- } catch (err) {
11144
- console.warn("[studio] Failed to load runtime source fallback:", err);
11166
+ } catch {
11167
+ }
11168
+ return null;
11169
+ }
11170
+ async function getInlinedRuntime() {
11171
+ try {
11172
+ const mod = await Promise.resolve().then(() => (init_src(), src_exports));
11173
+ if (typeof mod.getHyperframeRuntimeScript === "function") {
11174
+ return mod.getHyperframeRuntimeScript() ?? null;
11175
+ }
11176
+ } catch {
11177
+ }
11178
+ return null;
11179
+ }
11180
+ function readPrebuiltArtifact() {
11181
+ return readFromDir(__dirname) ?? readFromCoreDistDir() ?? readFromNodeModules();
11182
+ }
11183
+ function readFromDir(dir) {
11184
+ for (const name of ARTIFACT_NAMES) {
11185
+ const path2 = resolve7(dir, name);
11186
+ if (existsSync8(path2)) return readFileSync8(path2, "utf-8");
11145
11187
  }
11146
11188
  return null;
11147
11189
  }
11190
+ function readFromCoreDistDir() {
11191
+ return readFromDir(resolve7(__dirname, "..", "..", "..", "core", "dist"));
11192
+ }
11193
+ function readFromNodeModules() {
11194
+ const subPaths = ["node_modules/hyperframes/dist", "node_modules/@hyperframes/core/dist"];
11195
+ let dir = __dirname;
11196
+ for (; ; ) {
11197
+ for (const sub of subPaths) {
11198
+ const result = readFromDir(resolve7(dir, sub));
11199
+ if (result) return result;
11200
+ }
11201
+ const parent = dirname4(dir);
11202
+ if (parent === dir) break;
11203
+ dir = parent;
11204
+ }
11205
+ return null;
11206
+ }
11207
+ var ARTIFACT_NAMES, ENTRY_TS;
11148
11208
  var init_runtimeSource = __esm({
11149
11209
  "src/server/runtimeSource.ts"() {
11150
11210
  "use strict";
11211
+ ARTIFACT_NAMES = ["hyperframe-runtime.js", "hyperframe.runtime.iife.js"];
11212
+ ENTRY_TS = resolve7(__dirname, "..", "..", "..", "core", "src", "runtime", "entry.ts");
11151
11213
  }
11152
11214
  });
11153
11215
 
11154
11216
  // ../core/src/studio-api/helpers/safePath.ts
11155
- import { resolve as resolve7, sep, join as join10 } from "path";
11217
+ import { resolve as resolve8, sep, join as join10 } from "path";
11156
11218
  import { readdirSync as readdirSync3 } from "fs";
11157
11219
  function isSafePath(base, resolved) {
11158
- const norm = resolve7(base) + sep;
11159
- return resolved.startsWith(norm) || resolved === resolve7(base);
11220
+ const norm = resolve8(base) + sep;
11221
+ return resolved.startsWith(norm) || resolved === resolve8(base);
11160
11222
  }
11161
11223
  function walkDir(dir, prefix = "") {
11162
11224
  const files = [];
@@ -11211,8 +11273,8 @@ var init_projects = __esm({
11211
11273
  // ../core/src/studio-api/routes/files.ts
11212
11274
  import { bodyLimit } from "hono/body-limit";
11213
11275
  import {
11214
- existsSync as existsSync7,
11215
- readFileSync as readFileSync8,
11276
+ existsSync as existsSync9,
11277
+ readFileSync as readFileSync9,
11216
11278
  writeFileSync as writeFileSync5,
11217
11279
  mkdirSync as mkdirSync5,
11218
11280
  unlinkSync as unlinkSync3,
@@ -11221,7 +11283,7 @@ import {
11221
11283
  renameSync as renameSync2,
11222
11284
  readdirSync as readdirSync4
11223
11285
  } from "fs";
11224
- import { resolve as resolve8, dirname as dirname4, join as join11 } from "path";
11286
+ import { resolve as resolve9, dirname as dirname5, join as join11 } from "path";
11225
11287
  async function resolveProjectFile(c2, adapter2, opts) {
11226
11288
  const id = c2.req.param("id");
11227
11289
  const project = await adapter2.resolveProject(id);
@@ -11232,18 +11294,18 @@ async function resolveProjectFile(c2, adapter2, opts) {
11232
11294
  if (filePath.includes("\0")) {
11233
11295
  return { error: c2.json({ error: "forbidden" }, 403) };
11234
11296
  }
11235
- const absPath = resolve8(project.dir, filePath);
11297
+ const absPath = resolve9(project.dir, filePath);
11236
11298
  if (!isSafePath(project.dir, absPath)) {
11237
11299
  return { error: c2.json({ error: "forbidden" }, 403) };
11238
11300
  }
11239
- if (opts?.mustExist && !existsSync7(absPath)) {
11301
+ if (opts?.mustExist && !existsSync9(absPath)) {
11240
11302
  return { error: c2.json({ error: "not found" }, 404) };
11241
11303
  }
11242
11304
  return { project, filePath, absPath };
11243
11305
  }
11244
11306
  function ensureDir(filePath) {
11245
- const dir = dirname4(filePath);
11246
- if (!existsSync7(dir)) mkdirSync5(dir, { recursive: true });
11307
+ const dir = dirname5(filePath);
11308
+ if (!existsSync9(dir)) mkdirSync5(dir, { recursive: true });
11247
11309
  }
11248
11310
  function generateCopyPath(projectDir, originalPath) {
11249
11311
  const ext = originalPath.includes(".") ? "." + originalPath.split(".").pop() : "";
@@ -11252,7 +11314,7 @@ function generateCopyPath(projectDir, originalPath) {
11252
11314
  const cleanBase = copyMatch ? base.slice(0, -copyMatch[0].length) : base;
11253
11315
  let num = copyMatch ? copyMatch[1] ? parseInt(copyMatch[1]) + 1 : 2 : 1;
11254
11316
  let candidate = num === 1 ? `${cleanBase} (copy)${ext}` : `${cleanBase} (copy ${num})${ext}`;
11255
- while (existsSync7(resolve8(projectDir, candidate))) {
11317
+ while (existsSync9(resolve9(projectDir, candidate))) {
11256
11318
  num++;
11257
11319
  candidate = `${cleanBase} (copy ${num})${ext}`;
11258
11320
  }
@@ -11279,7 +11341,7 @@ function updateReferences(projectDir, oldPath, newPath) {
11279
11341
  );
11280
11342
  let updatedCount = 0;
11281
11343
  for (const file of textFiles) {
11282
- const content = readFileSync8(file, "utf-8");
11344
+ const content = readFileSync9(file, "utf-8");
11283
11345
  if (!content.includes(oldPath)) continue;
11284
11346
  const updated = content.split(oldPath).join(newPath);
11285
11347
  if (updated !== content) {
@@ -11293,7 +11355,7 @@ function registerFileRoutes(api, adapter2) {
11293
11355
  api.get("/projects/:id/files/*", async (c2) => {
11294
11356
  const res = await resolveProjectFile(c2, adapter2, { mustExist: true });
11295
11357
  if ("error" in res) return res.error;
11296
- const content = readFileSync8(res.absPath, "utf-8");
11358
+ const content = readFileSync9(res.absPath, "utf-8");
11297
11359
  return c2.json({ filename: res.filePath, content });
11298
11360
  });
11299
11361
  api.put("/projects/:id/files/*", async (c2) => {
@@ -11307,7 +11369,7 @@ function registerFileRoutes(api, adapter2) {
11307
11369
  api.post("/projects/:id/files/*", async (c2) => {
11308
11370
  const res = await resolveProjectFile(c2, adapter2);
11309
11371
  if ("error" in res) return res.error;
11310
- if (existsSync7(res.absPath)) {
11372
+ if (existsSync9(res.absPath)) {
11311
11373
  return c2.json({ error: "already exists" }, 409);
11312
11374
  }
11313
11375
  ensureDir(res.absPath);
@@ -11333,11 +11395,11 @@ function registerFileRoutes(api, adapter2) {
11333
11395
  if (!body.newPath || body.newPath.includes("\0")) {
11334
11396
  return c2.json({ error: "newPath required" }, 400);
11335
11397
  }
11336
- const newAbs = resolve8(res.project.dir, body.newPath);
11398
+ const newAbs = resolve9(res.project.dir, body.newPath);
11337
11399
  if (!isSafePath(res.project.dir, newAbs)) {
11338
11400
  return c2.json({ error: "forbidden" }, 403);
11339
11401
  }
11340
- if (existsSync7(newAbs)) {
11402
+ if (existsSync9(newAbs)) {
11341
11403
  return c2.json({ error: "already exists" }, 409);
11342
11404
  }
11343
11405
  ensureDir(newAbs);
@@ -11352,17 +11414,17 @@ function registerFileRoutes(api, adapter2) {
11352
11414
  if (!body.path || body.path.includes("\0")) {
11353
11415
  return c2.json({ error: "path required" }, 400);
11354
11416
  }
11355
- const srcAbs = resolve8(project.dir, body.path);
11356
- if (!isSafePath(project.dir, srcAbs) || !existsSync7(srcAbs)) {
11417
+ const srcAbs = resolve9(project.dir, body.path);
11418
+ if (!isSafePath(project.dir, srcAbs) || !existsSync9(srcAbs)) {
11357
11419
  return c2.json({ error: "not found" }, 404);
11358
11420
  }
11359
11421
  const copyPath = generateCopyPath(project.dir, body.path);
11360
- const destAbs = resolve8(project.dir, copyPath);
11422
+ const destAbs = resolve9(project.dir, copyPath);
11361
11423
  if (!isSafePath(project.dir, destAbs)) {
11362
11424
  return c2.json({ error: "forbidden" }, 403);
11363
11425
  }
11364
11426
  ensureDir(destAbs);
11365
- writeFileSync5(destAbs, readFileSync8(srcAbs));
11427
+ writeFileSync5(destAbs, readFileSync9(srcAbs));
11366
11428
  return c2.json({ ok: true, path: copyPath }, 201);
11367
11429
  });
11368
11430
  const MAX_UPLOAD_BYTES = 500 * 1024 * 1024;
@@ -11376,9 +11438,9 @@ function registerFileRoutes(api, adapter2) {
11376
11438
  const project = await adapter2.resolveProject(c2.req.param("id"));
11377
11439
  if (!project) return c2.json({ error: "not found" }, 404);
11378
11440
  const subDir = c2.req.query("dir") ?? "";
11379
- const targetDir = subDir ? resolve8(project.dir, subDir) : project.dir;
11441
+ const targetDir = subDir ? resolve9(project.dir, subDir) : project.dir;
11380
11442
  if (!isSafePath(project.dir, targetDir)) return c2.json({ error: "forbidden" }, 403);
11381
- if (subDir && !existsSync7(targetDir)) mkdirSync5(targetDir, { recursive: true });
11443
+ if (subDir && !existsSync9(targetDir)) mkdirSync5(targetDir, { recursive: true });
11382
11444
  const formData = await c2.req.formData();
11383
11445
  const uploaded = [];
11384
11446
  const skipped = [];
@@ -11390,22 +11452,22 @@ function registerFileRoutes(api, adapter2) {
11390
11452
  skipped.push(name);
11391
11453
  continue;
11392
11454
  }
11393
- const destPath = resolve8(targetDir, name);
11455
+ const destPath = resolve9(targetDir, name);
11394
11456
  if (!isSafePath(project.dir, destPath)) continue;
11395
11457
  let finalPath = destPath;
11396
11458
  let finalName = name;
11397
- if (existsSync7(finalPath)) {
11459
+ if (existsSync9(finalPath)) {
11398
11460
  const dotIdx = name.indexOf(".", name.startsWith(".") ? 1 : 0);
11399
11461
  const ext = dotIdx > 0 ? name.slice(dotIdx) : "";
11400
11462
  const base = dotIdx > 0 ? name.slice(0, dotIdx) : name;
11401
11463
  let n = 2;
11402
- while (n < 1e4 && existsSync7(resolve8(targetDir, `${base} (${n})${ext}`))) n++;
11464
+ while (n < 1e4 && existsSync9(resolve9(targetDir, `${base} (${n})${ext}`))) n++;
11403
11465
  if (n >= 1e4) {
11404
11466
  skipped.push(name);
11405
11467
  continue;
11406
11468
  }
11407
11469
  finalName = `${base} (${n})${ext}`;
11408
- finalPath = resolve8(targetDir, finalName);
11470
+ finalPath = resolve9(targetDir, finalName);
11409
11471
  }
11410
11472
  const buffer = Buffer.from(await value.arrayBuffer());
11411
11473
  writeFileSync5(finalPath, buffer);
@@ -15315,8 +15377,8 @@ var init_custom_element_registry = __esm({
15315
15377
  } : (element) => element.localName === localName;
15316
15378
  registry.set(localName, { Class, check });
15317
15379
  if (waiting.has(localName)) {
15318
- for (const resolve37 of waiting.get(localName))
15319
- resolve37(Class);
15380
+ for (const resolve38 of waiting.get(localName))
15381
+ resolve38(Class);
15320
15382
  waiting.delete(localName);
15321
15383
  }
15322
15384
  ownerDocument.querySelectorAll(
@@ -15356,13 +15418,13 @@ var init_custom_element_registry = __esm({
15356
15418
  */
15357
15419
  whenDefined(localName) {
15358
15420
  const { registry, waiting } = this;
15359
- return new Promise((resolve37) => {
15421
+ return new Promise((resolve38) => {
15360
15422
  if (registry.has(localName))
15361
- resolve37(registry.get(localName).Class);
15423
+ resolve38(registry.get(localName).Class);
15362
15424
  else {
15363
15425
  if (!waiting.has(localName))
15364
15426
  waiting.set(localName, []);
15365
- waiting.get(localName).push(resolve37);
15427
+ waiting.get(localName).push(resolve38);
15366
15428
  }
15367
15429
  });
15368
15430
  }
@@ -24063,12 +24125,12 @@ var init_esm10 = __esm({
24063
24125
  });
24064
24126
 
24065
24127
  // ../core/src/studio-api/helpers/subComposition.ts
24066
- import { existsSync as existsSync8, readFileSync as readFileSync9 } from "fs";
24128
+ import { existsSync as existsSync10, readFileSync as readFileSync10 } from "fs";
24067
24129
  import { join as join12 } from "path";
24068
24130
  function buildSubCompositionHtml(projectDir, compPath, runtimeUrl, baseHref) {
24069
24131
  const compFile = join12(projectDir, compPath);
24070
- if (!existsSync8(compFile)) return null;
24071
- const rawComp = readFileSync9(compFile, "utf-8");
24132
+ if (!existsSync10(compFile)) return null;
24133
+ const rawComp = readFileSync10(compFile, "utf-8");
24072
24134
  const templateMatch = rawComp.match(/<template[^>]*>([\s\S]*)<\/template>/i);
24073
24135
  const content = templateMatch?.[1] ?? rawComp;
24074
24136
  const { document: contentDoc } = parseHTML(
@@ -24088,8 +24150,8 @@ function buildSubCompositionHtml(projectDir, compPath, runtimeUrl, baseHref) {
24088
24150
  const rewrittenContent = contentDoc.body.innerHTML || content;
24089
24151
  const indexPath = join12(projectDir, "index.html");
24090
24152
  let headContent = "";
24091
- if (existsSync8(indexPath)) {
24092
- const indexHtml = readFileSync9(indexPath, "utf-8");
24153
+ if (existsSync10(indexPath)) {
24154
+ const indexHtml = readFileSync10(indexPath, "utf-8");
24093
24155
  const headMatch = indexHtml.match(/<head[^>]*>([\s\S]*?)<\/head>/i);
24094
24156
  headContent = headMatch?.[1] ?? "";
24095
24157
  }
@@ -24125,8 +24187,8 @@ var init_subComposition = __esm({
24125
24187
  });
24126
24188
 
24127
24189
  // ../core/src/studio-api/routes/preview.ts
24128
- import { existsSync as existsSync9, readFileSync as readFileSync10, statSync as statSync2 } from "fs";
24129
- import { resolve as resolve9 } from "path";
24190
+ import { existsSync as existsSync11, readFileSync as readFileSync11, statSync as statSync2 } from "fs";
24191
+ import { resolve as resolve10 } from "path";
24130
24192
  function registerPreviewRoutes(api, adapter2) {
24131
24193
  api.get("/projects/:id/preview", async (c2) => {
24132
24194
  const project = await adapter2.resolveProject(c2.req.param("id"));
@@ -24134,9 +24196,9 @@ function registerPreviewRoutes(api, adapter2) {
24134
24196
  try {
24135
24197
  let bundled = await adapter2.bundle(project.dir);
24136
24198
  if (!bundled) {
24137
- const indexPath = resolve9(project.dir, "index.html");
24138
- if (!existsSync9(indexPath)) return c2.text("not found", 404);
24139
- bundled = readFileSync10(indexPath, "utf-8");
24199
+ const indexPath = resolve10(project.dir, "index.html");
24200
+ if (!existsSync11(indexPath)) return c2.text("not found", 404);
24201
+ bundled = readFileSync11(indexPath, "utf-8");
24140
24202
  }
24141
24203
  if (!bundled.includes("hyperframe.runtime") && !bundled.includes("hyperframes-preview-runtime")) {
24142
24204
  const runtimeTag = `<script src="${adapter2.runtimeUrl}"></script>`;
@@ -24150,8 +24212,8 @@ ${runtimeTag}`;
24150
24212
  }
24151
24213
  return c2.html(bundled);
24152
24214
  } catch {
24153
- const file = resolve9(project.dir, "index.html");
24154
- if (existsSync9(file)) return c2.html(readFileSync10(file, "utf-8"));
24215
+ const file = resolve10(project.dir, "index.html");
24216
+ if (existsSync11(file)) return c2.html(readFileSync11(file, "utf-8"));
24155
24217
  return c2.text("not found", 404);
24156
24218
  }
24157
24219
  });
@@ -24161,8 +24223,8 @@ ${runtimeTag}`;
24161
24223
  const compPath = decodeURIComponent(
24162
24224
  c2.req.path.replace(`/projects/${project.id}/preview/comp/`, "").split("?")[0] ?? ""
24163
24225
  );
24164
- const compFile = resolve9(project.dir, compPath);
24165
- if (!isSafePath(project.dir, compFile) || !existsSync9(compFile) || !statSync2(compFile).isFile()) {
24226
+ const compFile = resolve10(project.dir, compPath);
24227
+ if (!isSafePath(project.dir, compFile) || !existsSync11(compFile) || !statSync2(compFile).isFile()) {
24166
24228
  return c2.text("not found", 404);
24167
24229
  }
24168
24230
  const baseHref = `/api/projects/${project.id}/preview/`;
@@ -24176,13 +24238,13 @@ ${runtimeTag}`;
24176
24238
  const subPath = decodeURIComponent(
24177
24239
  c2.req.path.replace(`/projects/${project.id}/preview/`, "").split("?")[0] ?? ""
24178
24240
  );
24179
- const file = resolve9(project.dir, subPath);
24180
- if (!isSafePath(project.dir, file) || !existsSync9(file) || !statSync2(file).isFile()) {
24241
+ const file = resolve10(project.dir, subPath);
24242
+ if (!isSafePath(project.dir, file) || !existsSync11(file) || !statSync2(file).isFile()) {
24181
24243
  return c2.text("not found", 404);
24182
24244
  }
24183
24245
  const contentType = getMimeType(subPath);
24184
24246
  const isText2 = /\.(html|css|js|json|svg|txt|md)$/i.test(subPath);
24185
- const buffer = isText2 ? Buffer.from(readFileSync10(file, "utf-8"), "utf-8") : readFileSync10(file);
24247
+ const buffer = isText2 ? Buffer.from(readFileSync11(file, "utf-8"), "utf-8") : readFileSync11(file);
24186
24248
  const totalSize2 = buffer.length;
24187
24249
  const rangeHeader = c2.req.header("Range");
24188
24250
  if (rangeHeader) {
@@ -24222,7 +24284,7 @@ var init_preview = __esm({
24222
24284
  });
24223
24285
 
24224
24286
  // ../core/src/studio-api/routes/lint.ts
24225
- import { readFileSync as readFileSync11 } from "fs";
24287
+ import { readFileSync as readFileSync12 } from "fs";
24226
24288
  import { join as join13 } from "path";
24227
24289
  function registerLintRoutes(api, adapter2) {
24228
24290
  api.get("/projects/:id/lint", async (c2) => {
@@ -24232,7 +24294,7 @@ function registerLintRoutes(api, adapter2) {
24232
24294
  const htmlFiles = walkDir(project.dir).filter((f3) => f3.endsWith(".html"));
24233
24295
  const allFindings = [];
24234
24296
  for (const file of htmlFiles) {
24235
- const content = readFileSync11(join13(project.dir, file), "utf-8");
24297
+ const content = readFileSync12(join13(project.dir, file), "utf-8");
24236
24298
  const result = await adapter2.lint(content, { filePath: file });
24237
24299
  if (result?.findings) {
24238
24300
  for (const f3 of result.findings) {
@@ -24256,7 +24318,7 @@ var init_lint2 = __esm({
24256
24318
 
24257
24319
  // ../core/src/studio-api/routes/render.ts
24258
24320
  import { streamSSE } from "hono/streaming";
24259
- import { existsSync as existsSync10, readFileSync as readFileSync12, mkdirSync as mkdirSync6, unlinkSync as unlinkSync4, readdirSync as readdirSync5, statSync as statSync3 } from "fs";
24321
+ import { existsSync as existsSync12, readFileSync as readFileSync13, mkdirSync as mkdirSync6, unlinkSync as unlinkSync4, readdirSync as readdirSync5, statSync as statSync3 } from "fs";
24260
24322
  import { join as join14 } from "path";
24261
24323
  function registerRenderRoutes(api, adapter2) {
24262
24324
  const renderJobs = /* @__PURE__ */ new Map();
@@ -24294,7 +24356,7 @@ function registerRenderRoutes(api, adapter2) {
24294
24356
  const timePart = now.toTimeString().slice(0, 8).replace(/:/g, "-");
24295
24357
  const jobId = `${project.id}_${datePart}_${timePart}`;
24296
24358
  const rendersDir = adapter2.rendersDir(project);
24297
- if (!existsSync10(rendersDir)) mkdirSync6(rendersDir, { recursive: true });
24359
+ if (!existsSync12(rendersDir)) mkdirSync6(rendersDir, { recursive: true });
24298
24360
  const ext = FORMAT_EXT2[format] ?? ".mp4";
24299
24361
  const outputPath = join14(rendersDir, `${jobId}${ext}`);
24300
24362
  const jobState = adapter2.startRender({
@@ -24361,12 +24423,12 @@ function registerRenderRoutes(api, adapter2) {
24361
24423
  api.get("/render/:jobId/view", (c2) => {
24362
24424
  const { jobId } = c2.req.param();
24363
24425
  const job = renderJobs.get(jobId);
24364
- if (!job?.outputPath || !existsSync10(job.outputPath)) {
24426
+ if (!job?.outputPath || !existsSync12(job.outputPath)) {
24365
24427
  return c2.json({ error: "not found" }, 404);
24366
24428
  }
24367
24429
  const contentType = renderContentType(job.outputPath);
24368
24430
  const filename = job.outputPath.split("/").pop() ?? `render.mp4`;
24369
- const content = readFileSync12(job.outputPath);
24431
+ const content = readFileSync13(job.outputPath);
24370
24432
  return new Response(content, {
24371
24433
  headers: {
24372
24434
  "Content-Type": contentType,
@@ -24379,12 +24441,12 @@ function registerRenderRoutes(api, adapter2) {
24379
24441
  api.get("/render/:jobId/download", (c2) => {
24380
24442
  const { jobId } = c2.req.param();
24381
24443
  const job = renderJobs.get(jobId);
24382
- if (!job?.outputPath || !existsSync10(job.outputPath)) {
24444
+ if (!job?.outputPath || !existsSync12(job.outputPath)) {
24383
24445
  return c2.json({ error: "not found" }, 404);
24384
24446
  }
24385
24447
  const contentType = renderContentType(job.outputPath);
24386
24448
  const filename = job.outputPath.split("/").pop() ?? `render.mp4`;
24387
- const content = readFileSync12(job.outputPath);
24449
+ const content = readFileSync13(job.outputPath);
24388
24450
  return new Response(content, {
24389
24451
  headers: {
24390
24452
  "Content-Type": contentType,
@@ -24399,7 +24461,7 @@ function registerRenderRoutes(api, adapter2) {
24399
24461
  const dir = state.outputPath.replace(/\/[^/]+$/, "");
24400
24462
  for (const ext of [".mp4", ".webm", ".mov", ".meta.json"]) {
24401
24463
  const fp = join14(dir, `${jobId}${ext}`);
24402
- if (existsSync10(fp)) unlinkSync4(fp);
24464
+ if (existsSync12(fp)) unlinkSync4(fp);
24403
24465
  }
24404
24466
  break;
24405
24467
  }
@@ -24414,9 +24476,9 @@ function registerRenderRoutes(api, adapter2) {
24414
24476
  if (!filename) return c2.json({ error: "missing filename" }, 400);
24415
24477
  const rendersDir = adapter2.rendersDir(project);
24416
24478
  const fp = join14(rendersDir, filename);
24417
- if (!existsSync10(fp)) return c2.json({ error: "not found" }, 404);
24479
+ if (!existsSync12(fp)) return c2.json({ error: "not found" }, 404);
24418
24480
  const contentType = renderContentType(fp);
24419
- const content = readFileSync12(fp);
24481
+ const content = readFileSync13(fp);
24420
24482
  return new Response(content, {
24421
24483
  headers: {
24422
24484
  "Content-Type": contentType,
@@ -24430,7 +24492,7 @@ function registerRenderRoutes(api, adapter2) {
24430
24492
  const project = await adapter2.resolveProject(c2.req.param("id"));
24431
24493
  if (!project) return c2.json({ error: "not found" }, 404);
24432
24494
  const rendersDir = adapter2.rendersDir(project);
24433
- if (!existsSync10(rendersDir)) return c2.json({ renders: [] });
24495
+ if (!existsSync12(rendersDir)) return c2.json({ renders: [] });
24434
24496
  const files = readdirSync5(rendersDir).filter((f3) => f3.endsWith(".mp4") || f3.endsWith(".webm") || f3.endsWith(".mov")).map((f3) => {
24435
24497
  const fp = join14(rendersDir, f3);
24436
24498
  const stat3 = statSync3(fp);
@@ -24438,9 +24500,9 @@ function registerRenderRoutes(api, adapter2) {
24438
24500
  const metaPath = join14(rendersDir, `${rid}.meta.json`);
24439
24501
  let status = "complete";
24440
24502
  let durationMs;
24441
- if (existsSync10(metaPath)) {
24503
+ if (existsSync12(metaPath)) {
24442
24504
  try {
24443
- const meta = JSON.parse(readFileSync12(metaPath, "utf-8"));
24505
+ const meta = JSON.parse(readFileSync13(metaPath, "utf-8"));
24444
24506
  if (meta.status === "failed") status = "failed";
24445
24507
  if (meta.durationMs) durationMs = meta.durationMs;
24446
24508
  } catch {
@@ -24476,7 +24538,7 @@ var init_render = __esm({
24476
24538
  });
24477
24539
 
24478
24540
  // ../core/src/studio-api/routes/thumbnail.ts
24479
- import { existsSync as existsSync11, readFileSync as readFileSync13, writeFileSync as writeFileSync6, mkdirSync as mkdirSync7 } from "fs";
24541
+ import { existsSync as existsSync13, readFileSync as readFileSync14, writeFileSync as writeFileSync6, mkdirSync as mkdirSync7 } from "fs";
24480
24542
  import { join as join15 } from "path";
24481
24543
  function registerThumbnailRoutes(api, adapter2) {
24482
24544
  api.get("/projects/:id/thumbnail/*", async (c2) => {
@@ -24498,8 +24560,8 @@ function registerThumbnailRoutes(api, adapter2) {
24498
24560
  let compH = vpHeight || 1080;
24499
24561
  if (!vpWidth) {
24500
24562
  const htmlFile = join15(project.dir, compPath);
24501
- if (existsSync11(htmlFile)) {
24502
- const html = readFileSync13(htmlFile, "utf-8");
24563
+ if (existsSync13(htmlFile)) {
24564
+ const html = readFileSync14(htmlFile, "utf-8");
24503
24565
  const wMatch = html.match(/data-width=["'](\d+)["']/);
24504
24566
  const hMatch = html.match(/data-height=["'](\d+)["']/);
24505
24567
  if (wMatch?.[1]) compW = parseInt(wMatch[1]);
@@ -24511,8 +24573,8 @@ function registerThumbnailRoutes(api, adapter2) {
24511
24573
  const selectorKey = selector ? `_${selector.replace(/[^a-zA-Z0-9_-]+/g, "_").slice(0, 80)}` : "";
24512
24574
  const cacheKey = `${THUMBNAIL_CACHE_VERSION}_${compPath.replace(/\//g, "_")}_${seekTime.toFixed(2)}${selectorKey}.jpg`;
24513
24575
  const cachePath2 = join15(cacheDir, cacheKey);
24514
- if (existsSync11(cachePath2)) {
24515
- return new Response(new Uint8Array(readFileSync13(cachePath2)), {
24576
+ if (existsSync13(cachePath2)) {
24577
+ return new Response(new Uint8Array(readFileSync14(cachePath2)), {
24516
24578
  headers: { "Content-Type": "image/jpeg", "Cache-Control": "public, max-age=60" }
24517
24579
  });
24518
24580
  }
@@ -24529,7 +24591,7 @@ function registerThumbnailRoutes(api, adapter2) {
24529
24591
  if (!buffer) {
24530
24592
  return c2.json({ error: "Thumbnail generation returned null" }, 500);
24531
24593
  }
24532
- if (!existsSync11(cacheDir)) mkdirSync7(cacheDir, { recursive: true });
24594
+ if (!existsSync13(cacheDir)) mkdirSync7(cacheDir, { recursive: true });
24533
24595
  writeFileSync6(cachePath2, buffer);
24534
24596
  return new Response(new Uint8Array(buffer), {
24535
24597
  headers: { "Content-Type": "image/jpeg", "Cache-Control": "public, max-age=60" }
@@ -24603,7 +24665,7 @@ __export(manager_exports2, {
24603
24665
  setBrowserPath: () => setBrowserPath
24604
24666
  });
24605
24667
  import { execSync } from "child_process";
24606
- import { existsSync as existsSync12, rmSync as rmSync3 } from "fs";
24668
+ import { existsSync as existsSync14, rmSync as rmSync3 } from "fs";
24607
24669
  import { homedir as homedir4 } from "os";
24608
24670
  import { join as join16 } from "path";
24609
24671
  import { Browser, detectBrowserPlatform, getInstalledBrowsers, install } from "@puppeteer/browsers";
@@ -24625,17 +24687,17 @@ function whichBinary2(name) {
24625
24687
  }
24626
24688
  }
24627
24689
  function findFromEnv2() {
24628
- if (_browserPathOverride && existsSync12(_browserPathOverride)) {
24690
+ if (_browserPathOverride && existsSync14(_browserPathOverride)) {
24629
24691
  return { executablePath: _browserPathOverride, source: "env" };
24630
24692
  }
24631
24693
  const envPath = process.env["HYPERFRAMES_BROWSER_PATH"];
24632
- if (envPath && existsSync12(envPath)) {
24694
+ if (envPath && existsSync14(envPath)) {
24633
24695
  return { executablePath: envPath, source: "env" };
24634
24696
  }
24635
24697
  return void 0;
24636
24698
  }
24637
24699
  async function findFromCache() {
24638
- if (!existsSync12(CACHE_DIR2)) {
24700
+ if (!existsSync14(CACHE_DIR2)) {
24639
24701
  return void 0;
24640
24702
  }
24641
24703
  const installed = await getInstalledBrowsers({ cacheDir: CACHE_DIR2 });
@@ -24647,7 +24709,7 @@ async function findFromCache() {
24647
24709
  }
24648
24710
  function findFromSystem2() {
24649
24711
  for (const p of SYSTEM_CHROME_PATHS) {
24650
- if (existsSync12(p)) {
24712
+ if (existsSync14(p)) {
24651
24713
  return { executablePath: p, source: "system" };
24652
24714
  }
24653
24715
  }
@@ -24681,7 +24743,7 @@ async function ensureBrowser(options) {
24681
24743
  return { executablePath: installed.executablePath, source: "download" };
24682
24744
  }
24683
24745
  function clearBrowser() {
24684
- if (!existsSync12(CACHE_DIR2)) {
24746
+ if (!existsSync14(CACHE_DIR2)) {
24685
24747
  return false;
24686
24748
  }
24687
24749
  rmSync3(CACHE_DIR2, { recursive: true, force: true });
@@ -24818,7 +24880,7 @@ var init_config2 = __esm({
24818
24880
  });
24819
24881
 
24820
24882
  // ../engine/src/services/browserManager.ts
24821
- import { existsSync as existsSync13, readdirSync as readdirSync6 } from "fs";
24883
+ import { existsSync as existsSync15, readdirSync as readdirSync6 } from "fs";
24822
24884
  import { join as join17 } from "path";
24823
24885
  import { homedir as homedir5 } from "os";
24824
24886
  async function getPuppeteer() {
@@ -24841,7 +24903,7 @@ function resolveHeadlessShellPath(config) {
24841
24903
  return process.env.PRODUCER_HEADLESS_SHELL_PATH;
24842
24904
  }
24843
24905
  const baseDir = join17(homedir5(), ".cache", "puppeteer", "chrome-headless-shell");
24844
- if (!existsSync13(baseDir)) return void 0;
24906
+ if (!existsSync15(baseDir)) return void 0;
24845
24907
  try {
24846
24908
  const versions = readdirSync6(baseDir).sort().reverse();
24847
24909
  for (const version of versions) {
@@ -24852,7 +24914,7 @@ function resolveHeadlessShellPath(config) {
24852
24914
  join17(baseDir, version, "chrome-headless-shell-win64", "chrome-headless-shell.exe")
24853
24915
  ];
24854
24916
  for (const binary of candidates) {
24855
- if (existsSync13(binary)) return binary;
24917
+ if (existsSync15(binary)) return binary;
24856
24918
  }
24857
24919
  }
24858
24920
  } catch {
@@ -25315,10 +25377,10 @@ var init_screenshotService = __esm({
25315
25377
  });
25316
25378
 
25317
25379
  // ../engine/src/services/frameCapture.ts
25318
- import { existsSync as existsSync14, mkdirSync as mkdirSync8, writeFileSync as writeFileSync7 } from "fs";
25380
+ import { existsSync as existsSync16, mkdirSync as mkdirSync8, writeFileSync as writeFileSync7 } from "fs";
25319
25381
  import { join as join18 } from "path";
25320
25382
  async function createCaptureSession(serverUrl, outputDir, options, onBeforeCapture = null, config) {
25321
- if (!existsSync14(outputDir)) mkdirSync8(outputDir, { recursive: true });
25383
+ if (!existsSync16(outputDir)) mkdirSync8(outputDir, { recursive: true });
25322
25384
  const headlessShell = resolveHeadlessShellPath(config);
25323
25385
  const isLinux = process.platform === "linux";
25324
25386
  const forceScreenshot = config?.forceScreenshot ?? DEFAULT_CONFIG2.forceScreenshot;
@@ -25396,7 +25458,7 @@ async function pollPageExpression(page, expression, timeoutMs, intervalMs = 100)
25396
25458
  while (Date.now() < deadline) {
25397
25459
  const ready = Boolean(await page.evaluate(expression));
25398
25460
  if (ready) return true;
25399
- await new Promise((resolve37) => setTimeout(resolve37, intervalMs));
25461
+ await new Promise((resolve38) => setTimeout(resolve38, intervalMs));
25400
25462
  }
25401
25463
  return Boolean(await page.evaluate(expression));
25402
25464
  }
@@ -25519,7 +25581,7 @@ async function initializeSession(session) {
25519
25581
  async function captureFrameErrorDiagnostics(session, frameIndex, time, error) {
25520
25582
  try {
25521
25583
  const diagnosticsDir = join18(session.outputDir, "diagnostics");
25522
- if (!existsSync14(diagnosticsDir)) mkdirSync8(diagnosticsDir, { recursive: true });
25584
+ if (!existsSync16(diagnosticsDir)) mkdirSync8(diagnosticsDir, { recursive: true });
25523
25585
  const base = join18(diagnosticsDir, `frame-error-${frameIndex}`);
25524
25586
  await session.page.screenshot({ path: `${base}.png`, type: "png", fullPage: true });
25525
25587
  const html = await session.page.content();
@@ -25639,7 +25701,7 @@ async function closeCaptureSession(session) {
25639
25701
  session.isInitialized = false;
25640
25702
  }
25641
25703
  function prepareCaptureSessionForReuse(session, outputDir, onBeforeCapture) {
25642
- if (!existsSync14(outputDir)) {
25704
+ if (!existsSync16(outputDir)) {
25643
25705
  mkdirSync8(outputDir, { recursive: true });
25644
25706
  }
25645
25707
  session.outputDir = outputDir;
@@ -25685,7 +25747,7 @@ var init_frameCapture = __esm({
25685
25747
  // ../engine/src/utils/gpuEncoder.ts
25686
25748
  import { spawn as spawn2 } from "child_process";
25687
25749
  async function detectGpuEncoder() {
25688
- return new Promise((resolve37) => {
25750
+ return new Promise((resolve38) => {
25689
25751
  const ffmpeg = spawn2("ffmpeg", ["-encoders"], {
25690
25752
  stdio: ["pipe", "pipe", "pipe"]
25691
25753
  });
@@ -25694,13 +25756,13 @@ async function detectGpuEncoder() {
25694
25756
  stdout2 += data.toString();
25695
25757
  });
25696
25758
  ffmpeg.on("close", () => {
25697
- if (stdout2.includes("h264_nvenc")) resolve37("nvenc");
25698
- else if (stdout2.includes("h264_videotoolbox")) resolve37("videotoolbox");
25699
- else if (stdout2.includes("h264_vaapi")) resolve37("vaapi");
25700
- else if (stdout2.includes("h264_qsv")) resolve37("qsv");
25701
- else resolve37(null);
25759
+ if (stdout2.includes("h264_nvenc")) resolve38("nvenc");
25760
+ else if (stdout2.includes("h264_videotoolbox")) resolve38("videotoolbox");
25761
+ else if (stdout2.includes("h264_vaapi")) resolve38("vaapi");
25762
+ else if (stdout2.includes("h264_qsv")) resolve38("qsv");
25763
+ else resolve38(null);
25702
25764
  });
25703
- ffmpeg.on("error", () => resolve37(null));
25765
+ ffmpeg.on("error", () => resolve38(null));
25704
25766
  });
25705
25767
  }
25706
25768
  async function getCachedGpuEncoder() {
@@ -25724,11 +25786,39 @@ function getGpuEncoderName(encoder, codec) {
25724
25786
  return codec === "h264" ? "libx264" : "libx265";
25725
25787
  }
25726
25788
  }
25727
- var cachedGpuEncoder;
25789
+ function mapPresetForGpuEncoder(encoder, preset) {
25790
+ switch (encoder) {
25791
+ case "nvenc":
25792
+ if (/^p[1-7]$/.test(preset)) return preset;
25793
+ return NVENC_PRESET_MAP[preset] ?? "p4";
25794
+ case "qsv":
25795
+ return QSV_PRESET_MAP[preset] ?? preset;
25796
+ default:
25797
+ return preset;
25798
+ }
25799
+ }
25800
+ var cachedGpuEncoder, NVENC_PRESET_MAP, QSV_PRESET_MAP;
25728
25801
  var init_gpuEncoder = __esm({
25729
25802
  "../engine/src/utils/gpuEncoder.ts"() {
25730
25803
  "use strict";
25731
25804
  cachedGpuEncoder = void 0;
25805
+ NVENC_PRESET_MAP = {
25806
+ ultrafast: "p1",
25807
+ superfast: "p1",
25808
+ veryfast: "p2",
25809
+ faster: "p3",
25810
+ fast: "p4",
25811
+ medium: "p4",
25812
+ slow: "p5",
25813
+ slower: "p6",
25814
+ veryslow: "p7",
25815
+ placebo: "p7"
25816
+ };
25817
+ QSV_PRESET_MAP = {
25818
+ ultrafast: "veryfast",
25819
+ superfast: "veryfast",
25820
+ placebo: "veryslow"
25821
+ };
25732
25822
  }
25733
25823
  });
25734
25824
 
@@ -25779,12 +25869,21 @@ var init_hdr = __esm({
25779
25869
 
25780
25870
  // ../engine/src/utils/runFfmpeg.ts
25781
25871
  import { spawn as spawn3 } from "child_process";
25872
+ function formatFfmpegError(exitCode, stderr, tailLines = DEFAULT_STDERR_TAIL_LINES) {
25873
+ const tail = (stderr ?? "").split(/\r?\n/).filter((line) => line.length > 0).slice(-tailLines).join("\n");
25874
+ if (exitCode === null) {
25875
+ return tail ? `[FFmpeg] ${tail}` : "[FFmpeg] process error";
25876
+ }
25877
+ return tail ? `FFmpeg exited with code ${exitCode}
25878
+ ffmpeg stderr (tail):
25879
+ ${tail}` : `FFmpeg exited with code ${exitCode}`;
25880
+ }
25782
25881
  async function runFfmpeg(args, opts) {
25783
25882
  const startMs = Date.now();
25784
25883
  const signal = opts?.signal;
25785
25884
  const timeout = opts?.timeout ?? DEFAULT_TIMEOUT;
25786
25885
  const onStderr = opts?.onStderr;
25787
- return new Promise((resolve37) => {
25886
+ return new Promise((resolve38) => {
25788
25887
  const ffmpeg = spawn3("ffmpeg", args);
25789
25888
  let stderr = "";
25790
25889
  const onAbort = () => {
@@ -25810,7 +25909,7 @@ async function runFfmpeg(args, opts) {
25810
25909
  ffmpeg.on("close", (code) => {
25811
25910
  clearTimeout(timer);
25812
25911
  if (signal) signal.removeEventListener("abort", onAbort);
25813
- resolve37({
25912
+ resolve38({
25814
25913
  success: !signal?.aborted && code === 0,
25815
25914
  exitCode: code,
25816
25915
  stderr,
@@ -25820,7 +25919,7 @@ async function runFfmpeg(args, opts) {
25820
25919
  ffmpeg.on("error", (err) => {
25821
25920
  clearTimeout(timer);
25822
25921
  if (signal) signal.removeEventListener("abort", onAbort);
25823
- resolve37({
25922
+ resolve38({
25824
25923
  success: false,
25825
25924
  exitCode: null,
25826
25925
  stderr: err.message,
@@ -25829,18 +25928,19 @@ async function runFfmpeg(args, opts) {
25829
25928
  });
25830
25929
  });
25831
25930
  }
25832
- var DEFAULT_TIMEOUT;
25931
+ var DEFAULT_TIMEOUT, DEFAULT_STDERR_TAIL_LINES;
25833
25932
  var init_runFfmpeg = __esm({
25834
25933
  "../engine/src/utils/runFfmpeg.ts"() {
25835
25934
  "use strict";
25836
25935
  DEFAULT_TIMEOUT = 3e5;
25936
+ DEFAULT_STDERR_TAIL_LINES = 15;
25837
25937
  }
25838
25938
  });
25839
25939
 
25840
25940
  // ../engine/src/services/chunkEncoder.ts
25841
25941
  import { spawn as spawn4 } from "child_process";
25842
- import { copyFileSync, existsSync as existsSync15, mkdirSync as mkdirSync9, readdirSync as readdirSync7, statSync as statSync4, writeFileSync as writeFileSync8 } from "fs";
25843
- import { join as join19, dirname as dirname5 } from "path";
25942
+ import { copyFileSync, existsSync as existsSync17, mkdirSync as mkdirSync9, readdirSync as readdirSync7, statSync as statSync4, writeFileSync as writeFileSync8 } from "fs";
25943
+ import { join as join19, dirname as dirname6 } from "path";
25844
25944
  function getEncoderPreset(quality, format = "mp4", hdr) {
25845
25945
  const base = ENCODER_PRESETS[quality];
25846
25946
  if (format === "webm") {
@@ -25894,7 +25994,7 @@ function buildEncoderArgs(options, inputArgs, outputPath, gpuEncoder = null) {
25894
25994
  args.push("-c:v", encoderName);
25895
25995
  switch (gpuEncoder) {
25896
25996
  case "nvenc":
25897
- args.push("-preset", preset);
25997
+ args.push("-preset", mapPresetForGpuEncoder("nvenc", preset));
25898
25998
  if (bitrate) args.push("-b:v", bitrate);
25899
25999
  else args.push("-cq", String(quality));
25900
26000
  break;
@@ -25913,7 +26013,7 @@ function buildEncoderArgs(options, inputArgs, outputPath, gpuEncoder = null) {
25913
26013
  else args.push("-qp", String(quality));
25914
26014
  break;
25915
26015
  case "qsv":
25916
- args.push("-preset", preset);
26016
+ args.push("-preset", mapPresetForGpuEncoder("qsv", preset));
25917
26017
  if (bitrate) args.push("-b:v", bitrate);
25918
26018
  else args.push("-global_quality", String(quality));
25919
26019
  break;
@@ -25990,8 +26090,8 @@ function buildEncoderArgs(options, inputArgs, outputPath, gpuEncoder = null) {
25990
26090
  }
25991
26091
  async function encodeFramesFromDir(framesDir, framePattern, outputPath, options, signal, config) {
25992
26092
  const startTime = Date.now();
25993
- const outputDir = dirname5(outputPath);
25994
- if (!existsSync15(outputDir)) mkdirSync9(outputDir, { recursive: true });
26093
+ const outputDir = dirname6(outputPath);
26094
+ if (!existsSync17(outputDir)) mkdirSync9(outputDir, { recursive: true });
25995
26095
  const files = readdirSync7(framesDir).filter((f3) => f3.match(/\.(jpg|jpeg|png)$/i));
25996
26096
  const frameCount = files.length;
25997
26097
  if (frameCount === 0) {
@@ -26011,7 +26111,7 @@ async function encodeFramesFromDir(framesDir, framePattern, outputPath, options,
26011
26111
  const inputPath = join19(framesDir, framePattern);
26012
26112
  const inputArgs = ["-framerate", String(options.fps), "-i", inputPath];
26013
26113
  const args = buildEncoderArgs(options, inputArgs, outputPath, gpuEncoder);
26014
- return new Promise((resolve37) => {
26114
+ return new Promise((resolve38) => {
26015
26115
  const ffmpeg = spawn4("ffmpeg", args);
26016
26116
  let stderr = "";
26017
26117
  const onAbort = () => {
@@ -26036,7 +26136,7 @@ async function encodeFramesFromDir(framesDir, framePattern, outputPath, options,
26036
26136
  if (signal) signal.removeEventListener("abort", onAbort);
26037
26137
  const durationMs = Date.now() - startTime;
26038
26138
  if (signal?.aborted) {
26039
- resolve37({
26139
+ resolve38({
26040
26140
  success: false,
26041
26141
  outputPath,
26042
26142
  durationMs,
@@ -26047,23 +26147,23 @@ async function encodeFramesFromDir(framesDir, framePattern, outputPath, options,
26047
26147
  return;
26048
26148
  }
26049
26149
  if (code !== 0) {
26050
- resolve37({
26150
+ resolve38({
26051
26151
  success: false,
26052
26152
  outputPath,
26053
26153
  durationMs,
26054
26154
  framesEncoded: 0,
26055
26155
  fileSize: 0,
26056
- error: `FFmpeg exited with code ${code}`
26156
+ error: formatFfmpegError(code, stderr)
26057
26157
  });
26058
26158
  return;
26059
26159
  }
26060
- const fileSize = existsSync15(outputPath) ? statSync4(outputPath).size : 0;
26061
- resolve37({ success: true, outputPath, durationMs, framesEncoded: frameCount, fileSize });
26160
+ const fileSize = existsSync17(outputPath) ? statSync4(outputPath).size : 0;
26161
+ resolve38({ success: true, outputPath, durationMs, framesEncoded: frameCount, fileSize });
26062
26162
  });
26063
26163
  ffmpeg.on("error", (err) => {
26064
26164
  clearTimeout(timer);
26065
26165
  if (signal) signal.removeEventListener("abort", onAbort);
26066
- resolve37({
26166
+ resolve38({
26067
26167
  success: false,
26068
26168
  outputPath,
26069
26169
  durationMs: Date.now() - startTime,
@@ -26089,8 +26189,8 @@ async function encodeFramesChunkedConcat(framesDir, framePattern, outputPath, op
26089
26189
  }
26090
26190
  const chunkSize = Math.max(30, Math.floor(chunkSizeFrames));
26091
26191
  const chunkCount = Math.ceil(files.length / chunkSize);
26092
- const chunkDir = join19(dirname5(outputPath), "chunk-encode");
26093
- if (!existsSync15(chunkDir)) mkdirSync9(chunkDir, { recursive: true });
26192
+ const chunkDir = join19(dirname6(outputPath), "chunk-encode");
26193
+ if (!existsSync17(chunkDir)) mkdirSync9(chunkDir, { recursive: true });
26094
26194
  const chunkPaths = [];
26095
26195
  for (let i2 = 0; i2 < chunkCount; i2++) {
26096
26196
  if (signal?.aborted) {
@@ -26121,18 +26221,18 @@ async function encodeFramesChunkedConcat(framesDir, framePattern, outputPath, op
26121
26221
  let gpuEncoder = null;
26122
26222
  if (options.useGpu) gpuEncoder = await getCachedGpuEncoder();
26123
26223
  const args = buildEncoderArgs(options, inputArgs, chunkPath, gpuEncoder);
26124
- const chunkResult = await new Promise((resolve37) => {
26224
+ const chunkResult = await new Promise((resolve38) => {
26125
26225
  const ffmpeg = spawn4("ffmpeg", args);
26126
26226
  let stderr = "";
26127
26227
  ffmpeg.stderr.on("data", (d) => {
26128
26228
  stderr += d.toString();
26129
26229
  });
26130
26230
  ffmpeg.on("close", (code) => {
26131
- if (code === 0) resolve37({ success: true });
26132
- else resolve37({ success: false, error: `Chunk ${i2} encode failed: ${stderr.slice(-400)}` });
26231
+ if (code === 0) resolve38({ success: true });
26232
+ else resolve38({ success: false, error: `Chunk ${i2} encode failed: ${stderr.slice(-400)}` });
26133
26233
  });
26134
26234
  ffmpeg.on("error", (err) => {
26135
- resolve37({ success: false, error: `Chunk ${i2} encode error: ${err.message}` });
26235
+ resolve38({ success: false, error: `Chunk ${i2} encode error: ${err.message}` });
26136
26236
  });
26137
26237
  });
26138
26238
  if (!chunkResult.success) {
@@ -26162,18 +26262,18 @@ async function encodeFramesChunkedConcat(framesDir, framePattern, outputPath, op
26162
26262
  "-y",
26163
26263
  outputPath
26164
26264
  ];
26165
- const concatResult = await new Promise((resolve37) => {
26265
+ const concatResult = await new Promise((resolve38) => {
26166
26266
  const ffmpeg = spawn4("ffmpeg", concatArgs);
26167
26267
  let stderr = "";
26168
26268
  ffmpeg.stderr.on("data", (d) => {
26169
26269
  stderr += d.toString();
26170
26270
  });
26171
26271
  ffmpeg.on("close", (code) => {
26172
- if (code === 0) resolve37({ success: true });
26173
- else resolve37({ success: false, error: `Chunk concat failed: ${stderr.slice(-400)}` });
26272
+ if (code === 0) resolve38({ success: true });
26273
+ else resolve38({ success: false, error: `Chunk concat failed: ${stderr.slice(-400)}` });
26174
26274
  });
26175
26275
  ffmpeg.on("error", (err) => {
26176
- resolve37({ success: false, error: `Chunk concat error: ${err.message}` });
26276
+ resolve38({ success: false, error: `Chunk concat error: ${err.message}` });
26177
26277
  });
26178
26278
  });
26179
26279
  if (!concatResult.success) {
@@ -26186,7 +26286,7 @@ async function encodeFramesChunkedConcat(framesDir, framePattern, outputPath, op
26186
26286
  error: concatResult.error
26187
26287
  };
26188
26288
  }
26189
- const fileSize = existsSync15(outputPath) ? statSync4(outputPath).size : 0;
26289
+ const fileSize = existsSync17(outputPath) ? statSync4(outputPath).size : 0;
26190
26290
  return {
26191
26291
  success: true,
26192
26292
  outputPath,
@@ -26196,8 +26296,8 @@ async function encodeFramesChunkedConcat(framesDir, framePattern, outputPath, op
26196
26296
  };
26197
26297
  }
26198
26298
  async function muxVideoWithAudio(videoPath, audioPath, outputPath, signal, config) {
26199
- const outputDir = dirname5(outputPath);
26200
- if (!existsSync15(outputDir)) mkdirSync9(outputDir, { recursive: true });
26299
+ const outputDir = dirname6(outputPath);
26300
+ if (!existsSync17(outputDir)) mkdirSync9(outputDir, { recursive: true });
26201
26301
  const isWebm = outputPath.endsWith(".webm");
26202
26302
  const isMov = outputPath.endsWith(".mov");
26203
26303
  const args = ["-i", videoPath, "-i", audioPath, "-c:v", "copy"];
@@ -26223,7 +26323,7 @@ async function muxVideoWithAudio(videoPath, audioPath, outputPath, signal, confi
26223
26323
  success: result.success,
26224
26324
  outputPath,
26225
26325
  durationMs: result.durationMs,
26226
- error: !result.success ? result.exitCode !== null ? `FFmpeg exited with code ${result.exitCode}` : `[FFmpeg] ${result.stderr}` : void 0
26326
+ error: !result.success ? formatFfmpegError(result.exitCode, result.stderr) : void 0
26227
26327
  };
26228
26328
  }
26229
26329
  async function applyFaststart(inputPath, outputPath, signal, config) {
@@ -26246,7 +26346,7 @@ async function applyFaststart(inputPath, outputPath, signal, config) {
26246
26346
  success: result.success,
26247
26347
  outputPath,
26248
26348
  durationMs: result.durationMs,
26249
- error: !result.success ? result.exitCode !== null ? `FFmpeg exited with code ${result.exitCode}` : `[FFmpeg] ${result.stderr}` : void 0
26349
+ error: !result.success ? formatFfmpegError(result.exitCode, result.stderr) : void 0
26250
26350
  };
26251
26351
  }
26252
26352
  var ENCODER_PRESETS;
@@ -26268,42 +26368,42 @@ var init_chunkEncoder = __esm({
26268
26368
 
26269
26369
  // ../engine/src/services/streamingEncoder.ts
26270
26370
  import { spawn as spawn5 } from "child_process";
26271
- import { existsSync as existsSync16, mkdirSync as mkdirSync10, statSync as statSync5 } from "fs";
26272
- import { dirname as dirname6 } from "path";
26371
+ import { existsSync as existsSync18, mkdirSync as mkdirSync10, statSync as statSync5 } from "fs";
26372
+ import { dirname as dirname7 } from "path";
26273
26373
  function createFrameReorderBuffer(startFrame, endFrame) {
26274
26374
  let cursor = startFrame;
26275
26375
  const pending = /* @__PURE__ */ new Map();
26276
- const enqueueAt = (frame, resolve37) => {
26376
+ const enqueueAt = (frame, resolve38) => {
26277
26377
  const list = pending.get(frame);
26278
26378
  if (list === void 0) {
26279
- pending.set(frame, [resolve37]);
26379
+ pending.set(frame, [resolve38]);
26280
26380
  } else {
26281
- list.push(resolve37);
26381
+ list.push(resolve38);
26282
26382
  }
26283
26383
  };
26284
26384
  const flushAt = (frame) => {
26285
26385
  const list = pending.get(frame);
26286
26386
  if (list === void 0) return;
26287
26387
  pending.delete(frame);
26288
- for (const resolve37 of list) resolve37();
26388
+ for (const resolve38 of list) resolve38();
26289
26389
  };
26290
- const waitForFrame = (frame) => new Promise((resolve37) => {
26390
+ const waitForFrame = (frame) => new Promise((resolve38) => {
26291
26391
  if (frame === cursor) {
26292
- resolve37();
26392
+ resolve38();
26293
26393
  return;
26294
26394
  }
26295
- enqueueAt(frame, resolve37);
26395
+ enqueueAt(frame, resolve38);
26296
26396
  });
26297
26397
  const advanceTo = (frame) => {
26298
26398
  cursor = frame;
26299
26399
  flushAt(frame);
26300
26400
  };
26301
- const waitForAllDone = () => new Promise((resolve37) => {
26401
+ const waitForAllDone = () => new Promise((resolve38) => {
26302
26402
  if (cursor >= endFrame) {
26303
- resolve37();
26403
+ resolve38();
26304
26404
  return;
26305
26405
  }
26306
- enqueueAt(endFrame, resolve37);
26406
+ enqueueAt(endFrame, resolve38);
26307
26407
  });
26308
26408
  return { waitForFrame, advanceTo, waitForAllDone };
26309
26409
  }
@@ -26355,7 +26455,7 @@ function buildStreamingArgs(options, outputPath, gpuEncoder = null) {
26355
26455
  args.push("-c:v", encoderName);
26356
26456
  switch (gpuEncoder) {
26357
26457
  case "nvenc":
26358
- args.push("-preset", preset);
26458
+ args.push("-preset", mapPresetForGpuEncoder("nvenc", preset));
26359
26459
  if (bitrate) args.push("-b:v", bitrate);
26360
26460
  else args.push("-cq", String(quality));
26361
26461
  break;
@@ -26374,7 +26474,7 @@ function buildStreamingArgs(options, outputPath, gpuEncoder = null) {
26374
26474
  else args.push("-qp", String(quality));
26375
26475
  break;
26376
26476
  case "qsv":
26377
- args.push("-preset", preset);
26477
+ args.push("-preset", mapPresetForGpuEncoder("qsv", preset));
26378
26478
  if (bitrate) args.push("-b:v", bitrate);
26379
26479
  else args.push("-global_quality", String(quality));
26380
26480
  break;
@@ -26450,8 +26550,8 @@ function buildStreamingArgs(options, outputPath, gpuEncoder = null) {
26450
26550
  return args;
26451
26551
  }
26452
26552
  async function spawnStreamingEncoder(outputPath, options, signal, config) {
26453
- const outputDir = dirname6(outputPath);
26454
- if (!existsSync16(outputDir)) mkdirSync10(outputDir, { recursive: true });
26553
+ const outputDir = dirname7(outputPath);
26554
+ if (!existsSync18(outputDir)) mkdirSync10(outputDir, { recursive: true });
26455
26555
  let gpuEncoder = null;
26456
26556
  if (options.useGpu) {
26457
26557
  gpuEncoder = await getCachedGpuEncoder();
@@ -26465,7 +26565,7 @@ async function spawnStreamingEncoder(outputPath, options, signal, config) {
26465
26565
  let stderr = "";
26466
26566
  let exitCode = null;
26467
26567
  let exitPromiseResolve = null;
26468
- const exitPromise = new Promise((resolve37) => exitPromiseResolve = resolve37);
26568
+ const exitPromise = new Promise((resolve38) => exitPromiseResolve = resolve38);
26469
26569
  ffmpeg.stderr?.on("data", (data) => {
26470
26570
  stderr += data.toString();
26471
26571
  });
@@ -26511,8 +26611,8 @@ Process error: ${err.message}`;
26511
26611
  if (signal) signal.removeEventListener("abort", onAbort);
26512
26612
  const stdin = ffmpeg.stdin;
26513
26613
  if (stdin && !stdin.destroyed) {
26514
- await new Promise((resolve37) => {
26515
- stdin.end(() => resolve37());
26614
+ await new Promise((resolve38) => {
26615
+ stdin.end(() => resolve38());
26516
26616
  });
26517
26617
  }
26518
26618
  await exitPromise;
@@ -26530,10 +26630,10 @@ Process error: ${err.message}`;
26530
26630
  success: false,
26531
26631
  durationMs,
26532
26632
  fileSize: 0,
26533
- error: `FFmpeg exited with code ${exitCode}`
26633
+ error: formatFfmpegError(exitCode, stderr)
26534
26634
  };
26535
26635
  }
26536
- const fileSize = existsSync16(outputPath) ? statSync5(outputPath).size : 0;
26636
+ const fileSize = existsSync18(outputPath) ? statSync5(outputPath).size : 0;
26537
26637
  return { success: true, durationMs, fileSize };
26538
26638
  },
26539
26639
  getExitStatus: () => exitStatus
@@ -26544,6 +26644,7 @@ var init_streamingEncoder = __esm({
26544
26644
  "../engine/src/services/streamingEncoder.ts"() {
26545
26645
  "use strict";
26546
26646
  init_gpuEncoder();
26647
+ init_runFfmpeg();
26547
26648
  init_hdr();
26548
26649
  init_config2();
26549
26650
  }
@@ -26551,10 +26652,10 @@ var init_streamingEncoder = __esm({
26551
26652
 
26552
26653
  // ../engine/src/utils/ffprobe.ts
26553
26654
  import { spawn as spawn6 } from "child_process";
26554
- import { readFileSync as readFileSync14 } from "fs";
26655
+ import { readFileSync as readFileSync15 } from "fs";
26555
26656
  import { extname as extname4 } from "path";
26556
26657
  function runFfprobe(args) {
26557
- return new Promise((resolve37, reject) => {
26658
+ return new Promise((resolve38, reject) => {
26558
26659
  const proc = spawn6("ffprobe", args);
26559
26660
  let stdout2 = "";
26560
26661
  let stderr = "";
@@ -26568,7 +26669,7 @@ function runFfprobe(args) {
26568
26669
  if (code !== 0) {
26569
26670
  reject(new Error(`[FFmpeg] ffprobe exited with code ${code}: ${stderr}`));
26570
26671
  } else {
26571
- resolve37(stdout2);
26672
+ resolve38(stdout2);
26572
26673
  }
26573
26674
  });
26574
26675
  proc.on("error", (err) => {
@@ -26645,7 +26746,7 @@ function extractPngMetadataFromBuffer(buf) {
26645
26746
  function extractStillImageMetadata(filePath) {
26646
26747
  if (extname4(filePath).toLowerCase() !== ".png") return null;
26647
26748
  try {
26648
- return extractPngMetadataFromBuffer(readFileSync14(filePath));
26749
+ return extractPngMetadataFromBuffer(readFileSync15(filePath));
26649
26750
  } catch {
26650
26751
  return null;
26651
26752
  }
@@ -26660,7 +26761,7 @@ function parseFrameRate(frameRateStr) {
26660
26761
  }
26661
26762
  return parseFloat(frameRateStr) || 0;
26662
26763
  }
26663
- async function extractVideoMetadata(filePath) {
26764
+ async function extractMediaMetadata(filePath) {
26664
26765
  const cached2 = videoMetadataCache.get(filePath);
26665
26766
  if (cached2) return cached2;
26666
26767
  const probePromise = (async () => {
@@ -26807,18 +26908,19 @@ async function analyzeKeyframeIntervalsUncached(filePath) {
26807
26908
  isProblematic: maxInterval > 2
26808
26909
  };
26809
26910
  }
26810
- var videoMetadataCache, audioMetadataCache, keyframeCache;
26911
+ var videoMetadataCache, audioMetadataCache, extractVideoMetadata, keyframeCache;
26811
26912
  var init_ffprobe = __esm({
26812
26913
  "../engine/src/utils/ffprobe.ts"() {
26813
26914
  "use strict";
26814
26915
  videoMetadataCache = /* @__PURE__ */ new Map();
26815
26916
  audioMetadataCache = /* @__PURE__ */ new Map();
26917
+ extractVideoMetadata = extractMediaMetadata;
26816
26918
  keyframeCache = /* @__PURE__ */ new Map();
26817
26919
  }
26818
26920
  });
26819
26921
 
26820
26922
  // ../engine/src/utils/urlDownloader.ts
26821
- import { createWriteStream as createWriteStream2, existsSync as existsSync17, mkdirSync as mkdirSync11 } from "fs";
26923
+ import { createWriteStream as createWriteStream2, existsSync as existsSync19, mkdirSync as mkdirSync11 } from "fs";
26822
26924
  import { createHash } from "crypto";
26823
26925
  import { join as join20, extname as extname5 } from "path";
26824
26926
  import { Readable } from "stream";
@@ -26831,19 +26933,19 @@ function getFilenameFromUrl(url) {
26831
26933
  }
26832
26934
  async function downloadToTemp(url, destDir, timeoutMs = 3e5) {
26833
26935
  const cachedPath = downloadPathCache.get(url);
26834
- if (cachedPath && existsSync17(cachedPath)) {
26936
+ if (cachedPath && existsSync19(cachedPath)) {
26835
26937
  return cachedPath;
26836
26938
  }
26837
26939
  const inFlight = inFlightDownloads.get(url);
26838
26940
  if (inFlight) {
26839
26941
  return inFlight;
26840
26942
  }
26841
- if (!existsSync17(destDir)) {
26943
+ if (!existsSync19(destDir)) {
26842
26944
  mkdirSync11(destDir, { recursive: true });
26843
26945
  }
26844
26946
  const filename = getFilenameFromUrl(url);
26845
26947
  const localPath = join20(destDir, filename);
26846
- if (existsSync17(localPath)) {
26948
+ if (existsSync19(localPath)) {
26847
26949
  downloadPathCache.set(url, localPath);
26848
26950
  return localPath;
26849
26951
  }
@@ -26891,8 +26993,8 @@ var init_urlDownloader = __esm({
26891
26993
 
26892
26994
  // ../engine/src/services/videoFrameExtractor.ts
26893
26995
  import { spawn as spawn7 } from "child_process";
26894
- import { existsSync as existsSync18, mkdirSync as mkdirSync12, readdirSync as readdirSync8, rmSync as rmSync4 } from "fs";
26895
- import { join as join21 } from "path";
26996
+ import { existsSync as existsSync20, mkdirSync as mkdirSync12, readdirSync as readdirSync8, rmSync as rmSync4 } from "fs";
26997
+ import { isAbsolute as isAbsolute2, join as join21 } from "path";
26896
26998
  function parseVideoElements(html) {
26897
26999
  const videos = [];
26898
27000
  const { document: document2 } = parseHTML(html);
@@ -26962,8 +27064,8 @@ async function extractVideoFramesRange(videoPath, videoId, startTime, duration,
26962
27064
  const ffmpegProcessTimeout = config?.ffmpegProcessTimeout ?? DEFAULT_CONFIG2.ffmpegProcessTimeout;
26963
27065
  const { fps, outputDir, quality = 95, format = "jpg" } = options;
26964
27066
  const videoOutputDir = join21(outputDir, videoId);
26965
- if (!existsSync18(videoOutputDir)) mkdirSync12(videoOutputDir, { recursive: true });
26966
- const metadata = await extractVideoMetadata(videoPath);
27067
+ if (!existsSync20(videoOutputDir)) mkdirSync12(videoOutputDir, { recursive: true });
27068
+ const metadata = await extractMediaMetadata(videoPath);
26967
27069
  const framePattern = `frame_%05d.${format}`;
26968
27070
  const outputPattern = join21(videoOutputDir, framePattern);
26969
27071
  const isHdr = isHdrColorSpace(metadata.colorSpace);
@@ -26982,7 +27084,7 @@ async function extractVideoFramesRange(videoPath, videoId, startTime, duration,
26982
27084
  args.push("-q:v", format === "jpg" ? String(Math.ceil((100 - quality) / 3)) : "0");
26983
27085
  if (format === "png") args.push("-compression_level", "6");
26984
27086
  args.push("-y", outputPattern);
26985
- return new Promise((resolve37, reject) => {
27087
+ return new Promise((resolve38, reject) => {
26986
27088
  const ffmpeg = spawn7("ffmpeg", args);
26987
27089
  let stderr = "";
26988
27090
  const onAbort = () => {
@@ -27017,7 +27119,7 @@ async function extractVideoFramesRange(videoPath, videoId, startTime, duration,
27017
27119
  files.forEach((file, index) => {
27018
27120
  framePaths.set(index, join21(videoOutputDir, file));
27019
27121
  });
27020
- resolve37({
27122
+ resolve38({
27021
27123
  videoId,
27022
27124
  srcPath: videoPath,
27023
27125
  outputDir: videoOutputDir,
@@ -27112,16 +27214,16 @@ async function extractAllVideoFrames(videos, baseDir, options, signal, config, c
27112
27214
  if (signal?.aborted) break;
27113
27215
  try {
27114
27216
  let videoPath = video.src;
27115
- if (!videoPath.startsWith("/") && !isHttpUrl(videoPath)) {
27217
+ if (!isAbsolute2(videoPath) && !isHttpUrl(videoPath)) {
27116
27218
  const fromCompiled = compiledDir ? join21(compiledDir, videoPath) : null;
27117
- videoPath = fromCompiled && existsSync18(fromCompiled) ? fromCompiled : join21(baseDir, videoPath);
27219
+ videoPath = fromCompiled && existsSync20(fromCompiled) ? fromCompiled : join21(baseDir, videoPath);
27118
27220
  }
27119
27221
  if (isHttpUrl(videoPath)) {
27120
27222
  const downloadDir = join21(options.outputDir, "_downloads");
27121
27223
  mkdirSync12(downloadDir, { recursive: true });
27122
27224
  videoPath = await downloadToTemp(videoPath, downloadDir);
27123
27225
  }
27124
- if (!existsSync18(videoPath)) {
27226
+ if (!existsSync20(videoPath)) {
27125
27227
  errors.push({ videoId: video.id, error: `Video file not found: ${videoPath}` });
27126
27228
  continue;
27127
27229
  }
@@ -27132,7 +27234,7 @@ async function extractAllVideoFrames(videos, baseDir, options, signal, config, c
27132
27234
  }
27133
27235
  const videoColorSpaces = await Promise.all(
27134
27236
  resolvedVideos.map(async ({ videoPath }) => {
27135
- const metadata = await extractVideoMetadata(videoPath);
27237
+ const metadata = await extractMediaMetadata(videoPath);
27136
27238
  return metadata.colorSpace;
27137
27239
  })
27138
27240
  );
@@ -27165,7 +27267,7 @@ async function extractAllVideoFrames(videos, baseDir, options, signal, config, c
27165
27267
  if (signal?.aborted) break;
27166
27268
  const entry = resolvedVideos[i2];
27167
27269
  if (!entry) continue;
27168
- const metadata = await extractVideoMetadata(entry.videoPath);
27270
+ const metadata = await extractMediaMetadata(entry.videoPath);
27169
27271
  if (!metadata.isVFR) continue;
27170
27272
  let segDuration = entry.video.end - entry.video.start;
27171
27273
  if (!Number.isFinite(segDuration) || segDuration <= 0) {
@@ -27201,7 +27303,7 @@ async function extractAllVideoFrames(videos, baseDir, options, signal, config, c
27201
27303
  try {
27202
27304
  let videoDuration = video.end - video.start;
27203
27305
  if (!Number.isFinite(videoDuration) || videoDuration <= 0) {
27204
- const metadata = await extractVideoMetadata(videoPath);
27306
+ const metadata = await extractMediaMetadata(videoPath);
27205
27307
  const sourceDuration = metadata.durationSeconds - video.mediaStart;
27206
27308
  videoDuration = sourceDuration > 0 ? sourceDuration : metadata.durationSeconds;
27207
27309
  video.end = video.start + videoDuration;
@@ -27352,7 +27454,7 @@ var init_videoFrameExtractor = __esm({
27352
27454
  }
27353
27455
  cleanup() {
27354
27456
  for (const video of this.videos.values()) {
27355
- if (existsSync18(video.extracted.outputDir)) {
27457
+ if (existsSync20(video.extracted.outputDir)) {
27356
27458
  rmSync4(video.extracted.outputDir, { recursive: true, force: true });
27357
27459
  }
27358
27460
  }
@@ -27660,8 +27762,8 @@ var init_videoFrameInjector = __esm({
27660
27762
  });
27661
27763
 
27662
27764
  // ../engine/src/services/audioMixer.ts
27663
- import { existsSync as existsSync19, mkdirSync as mkdirSync13, rmSync as rmSync5 } from "fs";
27664
- import { join as join22, dirname as dirname7 } from "path";
27765
+ import { existsSync as existsSync21, mkdirSync as mkdirSync13, rmSync as rmSync5 } from "fs";
27766
+ import { isAbsolute as isAbsolute3, join as join22, dirname as dirname8 } from "path";
27665
27767
  function parseAudioElements(html) {
27666
27768
  const elements = [];
27667
27769
  const { document: document2 } = parseHTML(html);
@@ -27711,8 +27813,8 @@ function parseAudioElements(html) {
27711
27813
  }
27712
27814
  async function extractAudioFromVideo(videoPath, outputPath, options, signal, config) {
27713
27815
  const ffmpegProcessTimeout = config?.ffmpegProcessTimeout ?? DEFAULT_CONFIG2.ffmpegProcessTimeout;
27714
- const outputDir = dirname7(outputPath);
27715
- if (!existsSync19(outputDir)) mkdirSync13(outputDir, { recursive: true });
27816
+ const outputDir = dirname8(outputPath);
27817
+ if (!existsSync21(outputDir)) mkdirSync13(outputDir, { recursive: true });
27716
27818
  const args = ["-i", videoPath];
27717
27819
  if (options?.startTime !== void 0) args.push("-ss", String(options.startTime));
27718
27820
  if (options?.duration !== void 0) args.push("-t", String(options.duration));
@@ -27738,8 +27840,8 @@ async function extractAudioFromVideo(videoPath, outputPath, options, signal, con
27738
27840
  }
27739
27841
  async function prepareAudioTrack(srcPath, outputPath, mediaStart, duration, signal, config) {
27740
27842
  const ffmpegProcessTimeout = config?.ffmpegProcessTimeout ?? DEFAULT_CONFIG2.ffmpegProcessTimeout;
27741
- const outputDir = dirname7(outputPath);
27742
- if (!existsSync19(outputDir)) mkdirSync13(outputDir, { recursive: true });
27843
+ const outputDir = dirname8(outputPath);
27844
+ if (!existsSync21(outputDir)) mkdirSync13(outputDir, { recursive: true });
27743
27845
  const args = [
27744
27846
  "-ss",
27745
27847
  String(mediaStart),
@@ -27774,8 +27876,8 @@ async function prepareAudioTrack(srcPath, outputPath, mediaStart, duration, sign
27774
27876
  }
27775
27877
  async function generateSilence(outputPath, duration, signal, config) {
27776
27878
  const ffmpegProcessTimeout = config?.ffmpegProcessTimeout ?? DEFAULT_CONFIG2.ffmpegProcessTimeout;
27777
- const outputDir = dirname7(outputPath);
27778
- if (!existsSync19(outputDir)) mkdirSync13(outputDir, { recursive: true });
27879
+ const outputDir = dirname8(outputPath);
27880
+ if (!existsSync21(outputDir)) mkdirSync13(outputDir, { recursive: true });
27779
27881
  const args = [
27780
27882
  "-f",
27781
27883
  "lavfi",
@@ -27817,8 +27919,8 @@ async function mixAudioTracks(tracks, outputPath, totalDuration, signal, config)
27817
27919
  error: result2.error
27818
27920
  };
27819
27921
  }
27820
- const outputDir = dirname7(outputPath);
27821
- if (!existsSync19(outputDir)) mkdirSync13(outputDir, { recursive: true });
27922
+ const outputDir = dirname8(outputPath);
27923
+ if (!existsSync21(outputDir)) mkdirSync13(outputDir, { recursive: true });
27822
27924
  const inputs = [];
27823
27925
  const filterParts = [];
27824
27926
  tracks.forEach((track, i2) => {
@@ -27879,7 +27981,7 @@ async function processCompositionAudio(elements, baseDir, workDir, outputPath, t
27879
27981
  const startMs = Date.now();
27880
27982
  const tracks = [];
27881
27983
  const errors = [];
27882
- if (!existsSync19(workDir)) mkdirSync13(workDir, { recursive: true });
27984
+ if (!existsSync21(workDir)) mkdirSync13(workDir, { recursive: true });
27883
27985
  await Promise.all(
27884
27986
  elements.map(async (element) => {
27885
27987
  if (signal?.aborted) {
@@ -27888,9 +27990,9 @@ async function processCompositionAudio(elements, baseDir, workDir, outputPath, t
27888
27990
  }
27889
27991
  try {
27890
27992
  let srcPath = element.src;
27891
- if (!srcPath.startsWith("/") && !isHttpUrl(srcPath)) {
27993
+ if (!isAbsolute3(srcPath) && !isHttpUrl(srcPath)) {
27892
27994
  const fromCompiled = compiledDir ? join22(compiledDir, srcPath) : null;
27893
- srcPath = fromCompiled && existsSync19(fromCompiled) ? fromCompiled : join22(baseDir, srcPath);
27995
+ srcPath = fromCompiled && existsSync21(fromCompiled) ? fromCompiled : join22(baseDir, srcPath);
27894
27996
  }
27895
27997
  if (isHttpUrl(srcPath)) {
27896
27998
  try {
@@ -27902,7 +28004,7 @@ async function processCompositionAudio(elements, baseDir, workDir, outputPath, t
27902
28004
  return;
27903
28005
  }
27904
28006
  }
27905
- if (!existsSync19(srcPath)) {
28007
+ if (!existsSync21(srcPath)) {
27906
28008
  errors.push(`Source not found: ${element.id} (${element.src})`);
27907
28009
  return;
27908
28010
  }
@@ -27983,7 +28085,7 @@ var init_audioMixer = __esm({
27983
28085
 
27984
28086
  // ../engine/src/services/parallelCoordinator.ts
27985
28087
  import { cpus as cpus2, freemem, totalmem as totalmem2 } from "os";
27986
- import { existsSync as existsSync20, mkdirSync as mkdirSync14, readdirSync as readdirSync9 } from "fs";
28088
+ import { existsSync as existsSync22, mkdirSync as mkdirSync14, readdirSync as readdirSync9 } from "fs";
27987
28089
  import { copyFile, rename } from "fs/promises";
27988
28090
  import { join as join23 } from "path";
27989
28091
  function calculateOptimalWorkers(totalFrames, requested, config) {
@@ -28036,7 +28138,7 @@ function distributeFrames(totalFrames, workerCount, workDir) {
28036
28138
  async function executeWorkerTask(task, serverUrl, captureOptions, createBeforeCaptureHook, signal, onFrameCaptured, onFrameBuffer, config) {
28037
28139
  const startTime = Date.now();
28038
28140
  let framesCaptured = 0;
28039
- if (!existsSync20(task.outputDir)) mkdirSync14(task.outputDir, { recursive: true });
28141
+ if (!existsSync22(task.outputDir)) mkdirSync14(task.outputDir, { recursive: true });
28040
28142
  let session = null;
28041
28143
  let perf;
28042
28144
  try {
@@ -28126,11 +28228,11 @@ async function executeParallelCapture(serverUrl, workDir, tasks, captureOptions,
28126
28228
  return results;
28127
28229
  }
28128
28230
  async function mergeWorkerFrames(workDir, tasks, outputDir) {
28129
- if (!existsSync20(outputDir)) mkdirSync14(outputDir, { recursive: true });
28231
+ if (!existsSync22(outputDir)) mkdirSync14(outputDir, { recursive: true });
28130
28232
  let totalFrames = 0;
28131
28233
  const sortedTasks = [...tasks].sort((a, b) => a.startFrame - b.startFrame);
28132
28234
  for (const task of sortedTasks) {
28133
- if (!existsSync20(task.outputDir)) {
28235
+ if (!existsSync22(task.outputDir)) {
28134
28236
  continue;
28135
28237
  }
28136
28238
  const files = readdirSync9(task.outputDir).filter((f3) => f3.startsWith("frame_") && (f3.endsWith(".jpg") || f3.endsWith(".png"))).sort();
@@ -28173,7 +28275,7 @@ var init_parallelCoordinator = __esm({
28173
28275
  // ../engine/src/services/fileServer.ts
28174
28276
  import { Hono as Hono2 } from "hono";
28175
28277
  import { serve } from "@hono/node-server";
28176
- import { readFileSync as readFileSync15, existsSync as existsSync21, statSync as statSync6 } from "fs";
28278
+ import { readFileSync as readFileSync16, existsSync as existsSync23, statSync as statSync6 } from "fs";
28177
28279
  import { join as join24, extname as extname6 } from "path";
28178
28280
  function stripEmbeddedRuntimeScripts(html) {
28179
28281
  if (!html) return html;
@@ -28245,30 +28347,30 @@ function createFileServer(options) {
28245
28347
  const relativePath = requestPath.replace(/^\//, "");
28246
28348
  const compiledPath = compiledDir ? join24(compiledDir, relativePath) : null;
28247
28349
  const hasCompiledFile = Boolean(
28248
- compiledPath && existsSync21(compiledPath) && statSync6(compiledPath).isFile()
28350
+ compiledPath && existsSync23(compiledPath) && statSync6(compiledPath).isFile()
28249
28351
  );
28250
28352
  const filePath = hasCompiledFile ? compiledPath : join24(projectDir, relativePath);
28251
- if (!existsSync21(filePath) || !statSync6(filePath).isFile()) {
28353
+ if (!existsSync23(filePath) || !statSync6(filePath).isFile()) {
28252
28354
  return c2.text("Not found", 404);
28253
28355
  }
28254
28356
  const ext = extname6(filePath).toLowerCase();
28255
28357
  const contentType = MIME_TYPES2[ext] || "application/octet-stream";
28256
28358
  if (ext === ".html") {
28257
- const rawHtml = readFileSync15(filePath, "utf-8");
28359
+ const rawHtml = readFileSync16(filePath, "utf-8");
28258
28360
  const html = relativePath === "index.html" ? injectScriptsIntoHtml(rawHtml, headScripts, bodyScripts, stripEmbeddedRuntime) : rawHtml;
28259
28361
  return c2.text(html, 200, { "Content-Type": contentType });
28260
28362
  }
28261
- const content = readFileSync15(filePath);
28363
+ const content = readFileSync16(filePath);
28262
28364
  return new Response(content, {
28263
28365
  status: 200,
28264
28366
  headers: { "Content-Type": contentType }
28265
28367
  });
28266
28368
  });
28267
- return new Promise((resolve37) => {
28369
+ return new Promise((resolve38) => {
28268
28370
  const server = serve({ fetch: app.fetch, port }, (info) => {
28269
28371
  const actualPort = info.port;
28270
28372
  const url = `http://localhost:${actualPort}`;
28271
- resolve37({
28373
+ resolve38({
28272
28374
  url,
28273
28375
  port: actualPort,
28274
28376
  close: () => server.close()
@@ -28773,20 +28875,58 @@ function normalizeObjectFit(value) {
28773
28875
  }
28774
28876
  function parseTransformMatrix(css) {
28775
28877
  if (!css || css === "none") return null;
28776
- const match = css.match(
28878
+ const match2d = css.match(
28777
28879
  /^matrix\(\s*([^,]+),\s*([^,]+),\s*([^,]+),\s*([^,]+),\s*([^,]+),\s*([^,)]+)\s*\)$/
28778
28880
  );
28779
- if (!match) return null;
28780
- const values = match.slice(1, 7).map(Number);
28781
- if (!values.every(Number.isFinite)) return null;
28782
- return values;
28881
+ if (match2d) {
28882
+ const values = match2d.slice(1, 7).map(Number);
28883
+ if (!values.every(Number.isFinite)) return null;
28884
+ return values;
28885
+ }
28886
+ const match3d = css.match(/^matrix3d\(\s*([^)]+)\)$/);
28887
+ if (match3d) {
28888
+ const raw = match3d[1];
28889
+ if (!raw) return null;
28890
+ const parts = raw.split(",").map((s2) => Number(s2.trim()));
28891
+ if (parts.length !== 16 || !parts.every(Number.isFinite)) return null;
28892
+ warnIfZSignificant(parts);
28893
+ return [
28894
+ parts[0],
28895
+ parts[1],
28896
+ parts[4],
28897
+ parts[5],
28898
+ parts[12],
28899
+ parts[13]
28900
+ ];
28901
+ }
28902
+ return null;
28903
+ }
28904
+ function warnIfZSignificant(parts) {
28905
+ if (warnedZSignificant) return;
28906
+ const a3 = parts[8] ?? 0;
28907
+ const b3 = parts[9] ?? 0;
28908
+ const c1 = parts[2] ?? 0;
28909
+ const c2 = parts[6] ?? 0;
28910
+ const c3 = parts[10] ?? 1;
28911
+ const d1 = parts[3] ?? 0;
28912
+ const d2 = parts[7] ?? 0;
28913
+ const d3 = parts[11] ?? 0;
28914
+ const d4 = parts[15] ?? 1;
28915
+ if (Math.abs(a3) > Z_EPSILON || Math.abs(b3) > Z_EPSILON || Math.abs(c1) > Z_EPSILON || Math.abs(c2) > Z_EPSILON || Math.abs(c3 - 1) > Z_EPSILON || Math.abs(d1) > Z_EPSILON || Math.abs(d2) > Z_EPSILON || Math.abs(d3) > Z_EPSILON || Math.abs(d4 - 1) > Z_EPSILON) {
28916
+ warnedZSignificant = true;
28917
+ console.warn(
28918
+ `[alphaBlit] parseTransformMatrix received a matrix3d with non-trivial 3D components (a3=${a3}, b3=${b3}, c1=${c1}, c2=${c2}, c3=${c3}, d1=${d1}, d2=${d2}, d3=${d3}, d4=${d4}). The engine projects 3D transforms to 2D (m11, m12, m21, m22, m41, m42) and silently discards perspective and out-of-plane rotation. If your composition uses real 3D (rotateX/Y, perspective), the rendered output will not match the studio preview. Z translation (translateZ) is dropped by design and does not trigger this warning. This warning is emitted once per process.`
28919
+ );
28920
+ }
28783
28921
  }
28784
- var SRGB_TO_HLG, SRGB_TO_PQ;
28922
+ var SRGB_TO_HLG, SRGB_TO_PQ, warnedZSignificant, Z_EPSILON;
28785
28923
  var init_alphaBlit = __esm({
28786
28924
  "../engine/src/utils/alphaBlit.ts"() {
28787
28925
  "use strict";
28788
28926
  SRGB_TO_HLG = buildSrgbToHdrLut("hlg");
28789
28927
  SRGB_TO_PQ = buildSrgbToHdrLut("pq");
28928
+ warnedZSignificant = false;
28929
+ Z_EPSILON = 1e-6;
28790
28930
  }
28791
28931
  });
28792
28932
 
@@ -29488,7 +29628,7 @@ var init_shaderTransitions = __esm({
29488
29628
  });
29489
29629
 
29490
29630
  // ../engine/src/services/hdrCapture.ts
29491
- import { existsSync as existsSync22, readdirSync as readdirSync10 } from "fs";
29631
+ import { existsSync as existsSync24, readdirSync as readdirSync10 } from "fs";
29492
29632
  import { join as join25 } from "path";
29493
29633
  import { homedir as homedir6 } from "os";
29494
29634
  function linearToPQ(L2) {
@@ -29606,7 +29746,7 @@ function float16ToPqRgb(rawBuffer, bytesPerRow, width, height) {
29606
29746
  }
29607
29747
  function resolveHeadedChromePath() {
29608
29748
  const baseDir = join25(homedir6(), ".cache", "puppeteer", "chrome");
29609
- if (!existsSync22(baseDir)) return void 0;
29749
+ if (!existsSync24(baseDir)) return void 0;
29610
29750
  const versions = readdirSync10(baseDir).sort().reverse();
29611
29751
  for (const version of versions) {
29612
29752
  const candidates = [
@@ -29632,7 +29772,7 @@ function resolveHeadedChromePath() {
29632
29772
  join25(baseDir, version, "chrome-win64", "chrome.exe")
29633
29773
  ];
29634
29774
  for (const binary of candidates) {
29635
- if (existsSync22(binary)) return binary;
29775
+ if (existsSync24(binary)) return binary;
29636
29776
  }
29637
29777
  }
29638
29778
  return void 0;
@@ -29746,6 +29886,7 @@ __export(src_exports2, {
29746
29886
  executeParallelCapture: () => executeParallelCapture,
29747
29887
  extractAllVideoFrames: () => extractAllVideoFrames,
29748
29888
  extractAudioMetadata: () => extractAudioMetadata,
29889
+ extractMediaMetadata: () => extractMediaMetadata,
29749
29890
  extractVideoFramesRange: () => extractVideoFramesRange,
29750
29891
  extractVideoMetadata: () => extractVideoMetadata,
29751
29892
  float16ToPqRgb: () => float16ToPqRgb,
@@ -29822,9 +29963,9 @@ var init_src2 = __esm({
29822
29963
  });
29823
29964
 
29824
29965
  // ../core/src/compiler/htmlCompiler.ts
29825
- import { resolve as resolve10 } from "path";
29966
+ import { resolve as resolve11 } from "path";
29826
29967
  function resolveMediaSrc(src, projectDir) {
29827
- return src.startsWith("http://") || src.startsWith("https://") ? src : resolve10(projectDir, src);
29968
+ return src.startsWith("http://") || src.startsWith("https://") ? src : resolve11(projectDir, src);
29828
29969
  }
29829
29970
  async function compileHtml(rawHtml, projectDir, probeMediaDuration) {
29830
29971
  const { html: staticCompiled, unresolved } = compileTimingAttrs(rawHtml);
@@ -29902,8 +30043,8 @@ var init_staticGuard = __esm({
29902
30043
  });
29903
30044
 
29904
30045
  // ../core/src/compiler/htmlBundler.ts
29905
- import { readFileSync as readFileSync16, existsSync as existsSync23 } from "fs";
29906
- import { join as join26, resolve as resolve11, isAbsolute as isAbsolute2, sep as sep2 } from "path";
30046
+ import { readFileSync as readFileSync17, existsSync as existsSync25 } from "fs";
30047
+ import { join as join26, resolve as resolve12, isAbsolute as isAbsolute4, sep as sep2 } from "path";
29907
30048
  import { transformSync } from "esbuild";
29908
30049
  function parseHTMLContent(html) {
29909
30050
  const trimmed = html.trimStart().toLowerCase();
@@ -29913,9 +30054,9 @@ function parseHTMLContent(html) {
29913
30054
  return parseHTML(`<!DOCTYPE html><html><head></head><body>${html}</body></html>`).document;
29914
30055
  }
29915
30056
  function safePath(projectDir, relativePath) {
29916
- const resolved = resolve11(projectDir, relativePath);
29917
- const normalizedBase = resolve11(projectDir) + sep2;
29918
- if (!resolved.startsWith(normalizedBase) && resolved !== resolve11(projectDir)) return null;
30057
+ const resolved = resolve12(projectDir, relativePath);
30058
+ const normalizedBase = resolve12(projectDir) + sep2;
30059
+ if (!resolved.startsWith(normalizedBase) && resolved !== resolve12(projectDir)) return null;
29919
30060
  return resolved;
29920
30061
  }
29921
30062
  function stripEmbeddedRuntimeScripts2(html) {
@@ -29968,20 +30109,20 @@ function injectInterceptor(html) {
29968
30109
  }
29969
30110
  function isRelativeUrl(url) {
29970
30111
  if (!url) return false;
29971
- return !url.startsWith("http://") && !url.startsWith("https://") && !url.startsWith("//") && !url.startsWith("data:") && !isAbsolute2(url);
30112
+ return !url.startsWith("http://") && !url.startsWith("https://") && !url.startsWith("//") && !url.startsWith("data:") && !isAbsolute4(url);
29972
30113
  }
29973
30114
  function safeReadFile(filePath) {
29974
- if (!existsSync23(filePath)) return null;
30115
+ if (!existsSync25(filePath)) return null;
29975
30116
  try {
29976
- return readFileSync16(filePath, "utf-8");
30117
+ return readFileSync17(filePath, "utf-8");
29977
30118
  } catch {
29978
30119
  return null;
29979
30120
  }
29980
30121
  }
29981
30122
  function safeReadFileBuffer(filePath) {
29982
- if (!existsSync23(filePath)) return null;
30123
+ if (!existsSync25(filePath)) return null;
29983
30124
  try {
29984
- return readFileSync16(filePath);
30125
+ return readFileSync17(filePath);
29985
30126
  } catch {
29986
30127
  return null;
29987
30128
  }
@@ -30173,8 +30314,8 @@ function stripJsCommentsParserSafe(source) {
30173
30314
  }
30174
30315
  async function bundleToSingleHtml(projectDir, options) {
30175
30316
  const indexPath = join26(projectDir, "index.html");
30176
- if (!existsSync23(indexPath)) throw new Error("index.html not found in project directory");
30177
- const rawHtml = readFileSync16(indexPath, "utf-8");
30317
+ if (!existsSync25(indexPath)) throw new Error("index.html not found in project directory");
30318
+ const rawHtml = readFileSync17(indexPath, "utf-8");
30178
30319
  const compiled = await compileHtml(rawHtml, projectDir, options?.probeMediaDuration);
30179
30320
  const staticGuard = validateHyperframeHtmlContract(compiled);
30180
30321
  if (!staticGuard.isValid) {
@@ -30449,8 +30590,8 @@ var init_compiler = __esm({
30449
30590
 
30450
30591
  // ../producer/src/services/hyperframeRuntimeLoader.ts
30451
30592
  import { createHash as createHash2 } from "crypto";
30452
- import { existsSync as existsSync24, readFileSync as readFileSync17 } from "fs";
30453
- import { dirname as dirname8, resolve as resolve12 } from "path";
30593
+ import { existsSync as existsSync26, readFileSync as readFileSync18 } from "fs";
30594
+ import { dirname as dirname9, resolve as resolve13 } from "path";
30454
30595
  import { fileURLToPath as fileURLToPath2 } from "url";
30455
30596
  function resolveHyperframeManifestPath() {
30456
30597
  if (process.env.PRODUCER_HYPERFRAME_MANIFEST_PATH) {
@@ -30462,7 +30603,7 @@ function resolveHyperframeManifestPath() {
30462
30603
  MODULE_RELATIVE_MANIFEST_PATH
30463
30604
  ];
30464
30605
  for (const candidate of candidates) {
30465
- if (existsSync24(candidate)) {
30606
+ if (existsSync26(candidate)) {
30466
30607
  return candidate;
30467
30608
  }
30468
30609
  }
@@ -30473,12 +30614,12 @@ function getVerifiedHyperframeRuntimeSource() {
30473
30614
  }
30474
30615
  function resolveVerifiedHyperframeRuntime() {
30475
30616
  const manifestPath = resolveHyperframeManifestPath();
30476
- if (!existsSync24(manifestPath)) {
30617
+ if (!existsSync26(manifestPath)) {
30477
30618
  throw new Error(
30478
30619
  `[HyperframeRuntimeLoader] Missing manifest at ${manifestPath}. Build core runtime artifacts before rendering.`
30479
30620
  );
30480
30621
  }
30481
- const manifestRaw = readFileSync17(manifestPath, "utf8");
30622
+ const manifestRaw = readFileSync18(manifestPath, "utf8");
30482
30623
  const manifest = JSON.parse(manifestRaw);
30483
30624
  const runtimeFileName = manifest.artifacts?.iife;
30484
30625
  if (!runtimeFileName || !manifest.sha256) {
@@ -30486,11 +30627,11 @@ function resolveVerifiedHyperframeRuntime() {
30486
30627
  `[HyperframeRuntimeLoader] Invalid manifest at ${manifestPath}; missing iife artifact or sha256.`
30487
30628
  );
30488
30629
  }
30489
- const runtimePath = resolve12(dirname8(manifestPath), runtimeFileName);
30490
- if (!existsSync24(runtimePath)) {
30630
+ const runtimePath = resolve13(dirname9(manifestPath), runtimeFileName);
30631
+ if (!existsSync26(runtimePath)) {
30491
30632
  throw new Error(`[HyperframeRuntimeLoader] Missing runtime artifact at ${runtimePath}.`);
30492
30633
  }
30493
- const runtimeSource = readFileSync17(runtimePath, "utf8");
30634
+ const runtimeSource = readFileSync18(runtimePath, "utf8");
30494
30635
  const runtimeSha = createHash2("sha256").update(runtimeSource, "utf8").digest("hex");
30495
30636
  if (runtimeSha !== manifest.sha256) {
30496
30637
  throw new Error(
@@ -30509,19 +30650,19 @@ var PRODUCER_DIR, SIBLING_MANIFEST_PATH, MODULE_RELATIVE_MANIFEST_PATH, CWD_RELA
30509
30650
  var init_hyperframeRuntimeLoader = __esm({
30510
30651
  "../producer/src/services/hyperframeRuntimeLoader.ts"() {
30511
30652
  "use strict";
30512
- PRODUCER_DIR = dirname8(fileURLToPath2(import.meta.url));
30513
- SIBLING_MANIFEST_PATH = resolve12(PRODUCER_DIR, "hyperframe.manifest.json");
30514
- MODULE_RELATIVE_MANIFEST_PATH = resolve12(
30653
+ PRODUCER_DIR = dirname9(fileURLToPath2(import.meta.url));
30654
+ SIBLING_MANIFEST_PATH = resolve13(PRODUCER_DIR, "hyperframe.manifest.json");
30655
+ MODULE_RELATIVE_MANIFEST_PATH = resolve13(
30515
30656
  PRODUCER_DIR,
30516
30657
  "../../../core/dist/hyperframe.manifest.json"
30517
30658
  );
30518
30659
  CWD_RELATIVE_MANIFEST_PATHS = [
30519
30660
  // When bundled to a single file (dist/public-server.js), the manifest
30520
30661
  // is copied as a sibling by build.mjs
30521
- resolve12(PRODUCER_DIR, "hyperframe.manifest.json"),
30522
- resolve12(process.cwd(), "packages/core/dist/hyperframe.manifest.json"),
30523
- resolve12(process.cwd(), "../core/dist/hyperframe.manifest.json"),
30524
- resolve12(process.cwd(), "core/dist/hyperframe.manifest.json")
30662
+ resolve13(PRODUCER_DIR, "hyperframe.manifest.json"),
30663
+ resolve13(process.cwd(), "packages/core/dist/hyperframe.manifest.json"),
30664
+ resolve13(process.cwd(), "../core/dist/hyperframe.manifest.json"),
30665
+ resolve13(process.cwd(), "core/dist/hyperframe.manifest.json")
30525
30666
  ];
30526
30667
  }
30527
30668
  });
@@ -30529,16 +30670,16 @@ var init_hyperframeRuntimeLoader = __esm({
30529
30670
  // ../producer/src/services/fileServer.ts
30530
30671
  import { Hono as Hono3 } from "hono";
30531
30672
  import { serve as serve2 } from "@hono/node-server";
30532
- import { readFileSync as readFileSync18, existsSync as existsSync25, realpathSync, statSync as statSync7 } from "fs";
30533
- import { join as join27, extname as extname7, resolve as resolve13, sep as sep3 } from "path";
30673
+ import { readFileSync as readFileSync19, existsSync as existsSync27, realpathSync, statSync as statSync7 } from "fs";
30674
+ import { join as join27, extname as extname7, resolve as resolve14, sep as sep3 } from "path";
30534
30675
  function isPathInside(child, parent, options = {}) {
30535
30676
  const { resolveSymlinks = false, pathModule } = options;
30536
- const resolveFn = pathModule?.resolve ?? resolve13;
30677
+ const resolveFn = pathModule?.resolve ?? resolve14;
30537
30678
  const separator = pathModule?.sep ?? sep3;
30538
30679
  const resolvedChild = resolveFn(child);
30539
30680
  const resolvedParent = resolveFn(parent);
30540
- const normalizedChild = resolveSymlinks && existsSync25(resolvedChild) ? realpathSync.native(resolvedChild) : resolvedChild;
30541
- const normalizedParent = resolveSymlinks && existsSync25(resolvedParent) ? realpathSync.native(resolvedParent) : resolvedParent;
30681
+ const normalizedChild = resolveSymlinks && existsSync27(resolvedChild) ? realpathSync.native(resolvedChild) : resolvedChild;
30682
+ const normalizedParent = resolveSymlinks && existsSync27(resolvedParent) ? realpathSync.native(resolvedParent) : resolvedParent;
30542
30683
  if (normalizedChild === normalizedParent) return true;
30543
30684
  const parentWithSep = normalizedParent.endsWith(separator) ? normalizedParent : normalizedParent + separator;
30544
30685
  return normalizedChild.startsWith(parentWithSep);
@@ -30628,13 +30769,13 @@ function createFileServer2(options) {
30628
30769
  let filePath = null;
30629
30770
  if (compiledDir) {
30630
30771
  const candidate = join27(compiledDir, relativePath);
30631
- if (existsSync25(candidate) && isPathInside(candidate, compiledDir, { resolveSymlinks: true }) && statSync7(candidate).isFile()) {
30772
+ if (existsSync27(candidate) && isPathInside(candidate, compiledDir, { resolveSymlinks: true }) && statSync7(candidate).isFile()) {
30632
30773
  filePath = candidate;
30633
30774
  }
30634
30775
  }
30635
30776
  if (!filePath) {
30636
30777
  const candidate = join27(projectDir, relativePath);
30637
- if (existsSync25(candidate) && isPathInside(candidate, projectDir, { resolveSymlinks: true }) && statSync7(candidate).isFile()) {
30778
+ if (existsSync27(candidate) && isPathInside(candidate, projectDir, { resolveSymlinks: true }) && statSync7(candidate).isFile()) {
30638
30779
  filePath = candidate;
30639
30780
  }
30640
30781
  }
@@ -30647,7 +30788,7 @@ function createFileServer2(options) {
30647
30788
  const ext = extname7(filePath).toLowerCase();
30648
30789
  const contentType = MIME_TYPES3[ext] || "application/octet-stream";
30649
30790
  if (ext === ".html") {
30650
- const rawHtml = readFileSync18(filePath, "utf-8");
30791
+ const rawHtml = readFileSync19(filePath, "utf-8");
30651
30792
  const isIndex = relativePath === "index.html";
30652
30793
  let html = rawHtml;
30653
30794
  if (preHeadScripts.length > 0) {
@@ -30656,16 +30797,16 @@ function createFileServer2(options) {
30656
30797
  html = isIndex ? injectScriptsIntoHtml2(html, headScripts, bodyScripts, stripEmbeddedRuntime) : html;
30657
30798
  return c2.text(html, 200, { "Content-Type": contentType });
30658
30799
  }
30659
- const content = readFileSync18(filePath);
30800
+ const content = readFileSync19(filePath);
30660
30801
  return new Response(content, {
30661
30802
  status: 200,
30662
30803
  headers: { "Content-Type": contentType }
30663
30804
  });
30664
30805
  });
30665
- return new Promise((resolve37) => {
30806
+ return new Promise((resolve38) => {
30666
30807
  const connections = /* @__PURE__ */ new Set();
30667
30808
  const server = serve2({ fetch: app.fetch, port }, (info) => {
30668
- resolve37({
30809
+ resolve38({
30669
30810
  url: `http://localhost:${info.port}`,
30670
30811
  port: info.port,
30671
30812
  close: () => {
@@ -31008,13 +31149,13 @@ var init_ffprobe2 = __esm({
31008
31149
  });
31009
31150
 
31010
31151
  // ../producer/src/utils/paths.ts
31011
- import { resolve as resolve14, basename, join as join28, relative as relative2, isAbsolute as isAbsolute3 } from "path";
31152
+ import { resolve as resolve15, basename, join as join28, relative as relative2, isAbsolute as isAbsolute5 } from "path";
31012
31153
  function isPathInside2(childPath, parentPath) {
31013
- const absChild = resolve14(childPath);
31014
- const absParent = resolve14(parentPath);
31154
+ const absChild = resolve15(childPath);
31155
+ const absParent = resolve15(parentPath);
31015
31156
  if (absChild === absParent) return true;
31016
31157
  const rel = relative2(absParent, absChild);
31017
- return rel !== "" && !rel.startsWith("..") && !isAbsolute3(rel);
31158
+ return rel !== "" && !rel.startsWith("..") && !isAbsolute5(rel);
31018
31159
  }
31019
31160
  function toExternalAssetKey(absPath) {
31020
31161
  if (absPath.startsWith("hf-ext/")) return absPath;
@@ -31027,17 +31168,17 @@ function toExternalAssetKey(absPath) {
31027
31168
  return "hf-ext/" + normalised;
31028
31169
  }
31029
31170
  function resolveRenderPaths(projectDir, outputPath, rendersDir = DEFAULT_RENDERS_DIR) {
31030
- const absoluteProjectDir = resolve14(projectDir);
31171
+ const absoluteProjectDir = resolve15(projectDir);
31031
31172
  const projectName = basename(absoluteProjectDir);
31032
31173
  const resolvedOutputPath = outputPath ?? join28(rendersDir, `${projectName}.mp4`);
31033
- const absoluteOutputPath = resolve14(resolvedOutputPath);
31174
+ const absoluteOutputPath = resolve15(resolvedOutputPath);
31034
31175
  return { absoluteProjectDir, absoluteOutputPath };
31035
31176
  }
31036
31177
  var DEFAULT_RENDERS_DIR;
31037
31178
  var init_paths = __esm({
31038
31179
  "../producer/src/utils/paths.ts"() {
31039
31180
  "use strict";
31040
- DEFAULT_RENDERS_DIR = process.env.PRODUCER_RENDERS_DIR ?? resolve14(new URL(import.meta.url).pathname, "../../..", "renders");
31181
+ DEFAULT_RENDERS_DIR = process.env.PRODUCER_RENDERS_DIR ?? resolve15(new URL(import.meta.url).pathname, "../../..", "renders");
31041
31182
  }
31042
31183
  });
31043
31184
 
@@ -31102,7 +31243,7 @@ var init_fontData_generated = __esm({
31102
31243
  });
31103
31244
 
31104
31245
  // ../producer/src/services/deterministicFonts.ts
31105
- import { existsSync as existsSync26, mkdirSync as mkdirSync15, readFileSync as readFileSync19, writeFileSync as writeFileSync9 } from "fs";
31246
+ import { existsSync as existsSync28, mkdirSync as mkdirSync15, readFileSync as readFileSync20, writeFileSync as writeFileSync9 } from "fs";
31106
31247
  import { homedir as homedir7 } from "os";
31107
31248
  import { join as join29 } from "path";
31108
31249
  function normalizeFamilyName(family) {
@@ -31216,7 +31357,7 @@ function fontSlug(familyName) {
31216
31357
  }
31217
31358
  function fontCacheDir(slug) {
31218
31359
  const dir = join29(GOOGLE_FONTS_CACHE_DIR, slug);
31219
- if (!existsSync26(dir)) {
31360
+ if (!existsSync28(dir)) {
31220
31361
  mkdirSync15(dir, { recursive: true });
31221
31362
  }
31222
31363
  return dir;
@@ -31248,7 +31389,7 @@ async function fetchGoogleFont(familyName) {
31248
31389
  const woff2Url = match[3] || "";
31249
31390
  if (!woff2Url) continue;
31250
31391
  const cachePath2 = cachedWoff2Path(slug, weight, style);
31251
- if (!existsSync26(cachePath2)) {
31392
+ if (!existsSync28(cachePath2)) {
31252
31393
  try {
31253
31394
  const fontRes = await fetch(woff2Url);
31254
31395
  if (!fontRes.ok) continue;
@@ -31258,7 +31399,7 @@ async function fetchGoogleFont(familyName) {
31258
31399
  continue;
31259
31400
  }
31260
31401
  }
31261
- const fontBytes = readFileSync19(cachePath2);
31402
+ const fontBytes = readFileSync20(cachePath2);
31262
31403
  const dataUri = `data:font/woff2;base64,${fontBytes.toString("base64")}`;
31263
31404
  faces.push({ weight, style, dataUri });
31264
31405
  }
@@ -31440,8 +31581,8 @@ var init_deterministicFonts = __esm({
31440
31581
  });
31441
31582
 
31442
31583
  // ../producer/src/services/htmlCompiler.ts
31443
- import { readFileSync as readFileSync20, existsSync as existsSync27, mkdirSync as mkdirSync16 } from "fs";
31444
- import { join as join30, dirname as dirname9, resolve as resolve15 } from "path";
31584
+ import { readFileSync as readFileSync21, existsSync as existsSync29, mkdirSync as mkdirSync16 } from "fs";
31585
+ import { join as join30, dirname as dirname10, resolve as resolve16 } from "path";
31445
31586
  import postcss from "postcss";
31446
31587
  function dedupeElementsById(elements) {
31447
31588
  const deduped = /* @__PURE__ */ new Map();
@@ -31492,7 +31633,7 @@ function detectRenderModeHints(html) {
31492
31633
  async function resolveMediaDuration(src, mediaStart, baseDir, downloadDir, tagName19) {
31493
31634
  let filePath = src;
31494
31635
  if (isHttpUrl(src)) {
31495
- if (!existsSync27(downloadDir)) mkdirSync16(downloadDir, { recursive: true });
31636
+ if (!existsSync29(downloadDir)) mkdirSync16(downloadDir, { recursive: true });
31496
31637
  try {
31497
31638
  filePath = await downloadToTemp(src, downloadDir);
31498
31639
  } catch {
@@ -31501,10 +31642,10 @@ async function resolveMediaDuration(src, mediaStart, baseDir, downloadDir, tagNa
31501
31642
  } else if (!filePath.startsWith("/")) {
31502
31643
  filePath = join30(baseDir, filePath);
31503
31644
  }
31504
- if (!existsSync27(filePath)) {
31645
+ if (!existsSync29(filePath)) {
31505
31646
  return { duration: 0, resolvedPath: filePath };
31506
31647
  }
31507
- const metadata = tagName19 === "video" ? await extractVideoMetadata(filePath) : await extractAudioMetadata(filePath);
31648
+ const metadata = tagName19 === "video" ? await extractMediaMetadata(filePath) : await extractAudioMetadata(filePath);
31508
31649
  const fileDuration = metadata.durationSeconds;
31509
31650
  const effectiveDuration = fileDuration - mediaStart;
31510
31651
  const duration = effectiveDuration > 0 ? effectiveDuration : fileDuration;
@@ -31566,14 +31707,14 @@ async function parseSubCompositions(html, projectDir, downloadDir, parentOffset
31566
31707
  const elEnd = elEndRaw ? parseFloat(elEndRaw) : Infinity;
31567
31708
  const absoluteStart = parentOffset + elStart;
31568
31709
  const absoluteEnd = Math.min(parentEnd, isFinite(elEnd) ? parentOffset + elEnd : Infinity);
31569
- const filePath = resolve15(projectDir, srcPath);
31710
+ const filePath = resolve16(projectDir, srcPath);
31570
31711
  if (visited.has(filePath)) {
31571
31712
  continue;
31572
31713
  }
31573
- if (!existsSync27(filePath)) {
31714
+ if (!existsSync29(filePath)) {
31574
31715
  continue;
31575
31716
  }
31576
- const rawSubHtml = readFileSync20(filePath, "utf-8");
31717
+ const rawSubHtml = readFileSync21(filePath, "utf-8");
31577
31718
  const nestedVisited = new Set(visited);
31578
31719
  nestedVisited.add(filePath);
31579
31720
  workItems.push({ srcPath, absoluteStart, absoluteEnd, filePath, rawSubHtml, nestedVisited });
@@ -31582,7 +31723,7 @@ async function parseSubCompositions(html, projectDir, downloadDir, parentOffset
31582
31723
  workItems.map(async (item) => {
31583
31724
  const { html: compiledSub } = await compileHtmlFile(
31584
31725
  item.rawSubHtml,
31585
- dirname9(item.filePath),
31726
+ dirname10(item.filePath),
31586
31727
  downloadDir
31587
31728
  );
31588
31729
  const nested = await parseSubCompositions(
@@ -31779,9 +31920,9 @@ function inlineSubCompositions(html, subCompositions, projectDir) {
31779
31920
  if (!srcPath) continue;
31780
31921
  let compHtml = subCompositions.get(srcPath) || null;
31781
31922
  if (!compHtml) {
31782
- const filePath = resolve15(projectDir, srcPath);
31783
- if (existsSync27(filePath)) {
31784
- compHtml = readFileSync20(filePath, "utf-8");
31923
+ const filePath = resolve16(projectDir, srcPath);
31924
+ if (existsSync29(filePath)) {
31925
+ compHtml = readFileSync21(filePath, "utf-8");
31785
31926
  }
31786
31927
  }
31787
31928
  if (!compHtml) {
@@ -31996,7 +32137,7 @@ ${safeText}
31996
32137
  return wrappedFragment ? document2.body.innerHTML || "" : document2.toString();
31997
32138
  }
31998
32139
  function collectExternalAssets(html, projectDir) {
31999
- const absProjectDir = resolve15(projectDir);
32140
+ const absProjectDir = resolve16(projectDir);
32000
32141
  const externalAssets = /* @__PURE__ */ new Map();
32001
32142
  const CSS_URL_RE2 = /\burl\(\s*(["']?)([^)"']+)\1\s*\)/g;
32002
32143
  function processPath(rawPath) {
@@ -32004,11 +32145,11 @@ function collectExternalAssets(html, projectDir) {
32004
32145
  if (!trimmed || trimmed.startsWith("/") || trimmed.startsWith("http://") || trimmed.startsWith("https://") || trimmed.startsWith("//") || trimmed.startsWith("data:") || trimmed.startsWith("#")) {
32005
32146
  return null;
32006
32147
  }
32007
- const absPath = resolve15(absProjectDir, trimmed);
32148
+ const absPath = resolve16(absProjectDir, trimmed);
32008
32149
  if (isPathInside2(absPath, absProjectDir)) {
32009
32150
  return null;
32010
32151
  }
32011
- if (!existsSync27(absPath)) return null;
32152
+ if (!existsSync29(absPath)) return null;
32012
32153
  const safeKey = toExternalAssetKey(absPath);
32013
32154
  externalAssets.set(safeKey, absPath);
32014
32155
  return safeKey;
@@ -32053,7 +32194,7 @@ function collectExternalAssets(html, projectDir) {
32053
32194
  };
32054
32195
  }
32055
32196
  async function compileForRender(projectDir, htmlPath, downloadDir) {
32056
- const rawHtml = readFileSync20(htmlPath, "utf-8");
32197
+ const rawHtml = readFileSync21(htmlPath, "utf-8");
32057
32198
  const { html: compiledHtml, unresolvedCompositions } = await compileHtmlFile(
32058
32199
  rawHtml,
32059
32200
  projectDir,
@@ -32085,9 +32226,9 @@ async function compileForRender(projectDir, htmlPath, downloadDir) {
32085
32226
  const images = dedupeElementsById([...mainImages, ...subImages]);
32086
32227
  for (const video of videos) {
32087
32228
  if (isHttpUrl(video.src)) continue;
32088
- const videoPath = resolve15(projectDir, video.src);
32229
+ const videoPath = resolve16(projectDir, video.src);
32089
32230
  const reencode = `ffmpeg -i "${video.src}" -c:v libx264 -r 30 -g 30 -keyint_min 30 -movflags +faststart -c:a copy output.mp4`;
32090
- Promise.all([analyzeKeyframeIntervals(videoPath), extractVideoMetadata(videoPath)]).then(([analysis, metadata]) => {
32231
+ Promise.all([analyzeKeyframeIntervals(videoPath), extractMediaMetadata(videoPath)]).then(([analysis, metadata]) => {
32091
32232
  if (analysis.isProblematic) {
32092
32233
  console.warn(
32093
32234
  `[Compiler] WARNING: Video "${video.id}" has sparse keyframes (max interval: ${analysis.maxIntervalSeconds}s). This causes seek failures and frame freezing. Re-encode with: ${reencode}`
@@ -32282,16 +32423,16 @@ var init_logger = __esm({
32282
32423
 
32283
32424
  // ../producer/src/services/renderOrchestrator.ts
32284
32425
  import {
32285
- existsSync as existsSync28,
32426
+ existsSync as existsSync30,
32286
32427
  mkdirSync as mkdirSync17,
32287
32428
  rmSync as rmSync6,
32288
- readFileSync as readFileSync21,
32429
+ readFileSync as readFileSync22,
32289
32430
  readdirSync as readdirSync11,
32290
32431
  writeFileSync as writeFileSync10,
32291
32432
  copyFileSync as copyFileSync2,
32292
32433
  appendFileSync
32293
32434
  } from "fs";
32294
- import { join as join31, dirname as dirname10, resolve as resolve16 } from "path";
32435
+ import { join as join31, dirname as dirname11, resolve as resolve17 } from "path";
32295
32436
  import { randomUUID as randomUUID2 } from "crypto";
32296
32437
  import { freemem as freemem2 } from "os";
32297
32438
  import { fileURLToPath as fileURLToPath3 } from "url";
@@ -32320,6 +32461,21 @@ function getMaxFrameIndex(frameDir) {
32320
32461
  frameDirMaxIndexCache.set(frameDir, max);
32321
32462
  return max;
32322
32463
  }
32464
+ function countNonZeroAlpha(rgba) {
32465
+ let n = 0;
32466
+ for (let p = 3; p < rgba.length; p += 4) {
32467
+ if (rgba[p] !== 0) n++;
32468
+ }
32469
+ return n;
32470
+ }
32471
+ function countNonZeroRgb48(buf) {
32472
+ let n = 0;
32473
+ for (let p = 0; p < buf.length; p += 6) {
32474
+ if (buf[p] !== 0 || buf[p + 1] !== 0 || buf[p + 2] !== 0 || buf[p + 3] !== 0 || buf[p + 4] !== 0 || buf[p + 5] !== 0)
32475
+ n++;
32476
+ }
32477
+ return n;
32478
+ }
32323
32479
  function updateJobStatus(job, status, stage, progress, onProgress) {
32324
32480
  job.status = status;
32325
32481
  job.currentStage = stage;
@@ -32368,16 +32524,16 @@ function writeCompiledArtifacts(compiled, workDir, includeSummary) {
32368
32524
  writeFileSync10(join31(compileDir, "index.html"), compiled.html, "utf-8");
32369
32525
  for (const [srcPath, html] of compiled.subCompositions) {
32370
32526
  const outPath = join31(compileDir, srcPath);
32371
- mkdirSync17(dirname10(outPath), { recursive: true });
32527
+ mkdirSync17(dirname11(outPath), { recursive: true });
32372
32528
  writeFileSync10(outPath, html, "utf-8");
32373
32529
  }
32374
32530
  for (const [relativePath, absolutePath] of compiled.externalAssets) {
32375
- const outPath = resolve16(join31(compileDir, relativePath));
32531
+ const outPath = resolve17(join31(compileDir, relativePath));
32376
32532
  if (!isPathInside2(outPath, compileDir)) {
32377
32533
  console.warn(`[Render] Skipping external asset with unsafe path: ${relativePath}`);
32378
32534
  continue;
32379
32535
  }
32380
- mkdirSync17(dirname10(outPath), { recursive: true });
32536
+ mkdirSync17(dirname11(outPath), { recursive: true });
32381
32537
  copyFileSync2(absolutePath, outPath);
32382
32538
  }
32383
32539
  if (includeSummary) {
@@ -32424,11 +32580,11 @@ function blitHdrVideoLayer(canvas, el, time, fps, hdrFrameDirs, hdrStartTimes, w
32424
32580
  const maxIndex = getMaxFrameIndex(frameDir);
32425
32581
  const effectiveIndex = maxIndex > 0 ? Math.min(videoFrameIndex, maxIndex) : videoFrameIndex;
32426
32582
  const framePath = join31(frameDir, `frame_${String(effectiveIndex).padStart(4, "0")}.png`);
32427
- if (!existsSync28(framePath)) {
32583
+ if (!existsSync30(framePath)) {
32428
32584
  return;
32429
32585
  }
32430
32586
  try {
32431
- const { data: hdrRgb, width: srcW, height: srcH } = decodePngToRgb48le(readFileSync21(framePath));
32587
+ const { data: hdrRgb, width: srcW, height: srcH } = decodePngToRgb48le(readFileSync22(framePath));
32432
32588
  if (sourceTransfer && targetTransfer && sourceTransfer !== targetTransfer) {
32433
32589
  convertTransfer(hdrRgb, sourceTransfer, targetTransfer);
32434
32590
  }
@@ -32519,6 +32675,165 @@ function blitHdrImageLayer(canvas, el, hdrImageBuffers, width, height, log2, sou
32519
32675
  }
32520
32676
  }
32521
32677
  }
32678
+ async function compositeHdrFrame(ctx, canvas, time, fullStacking, elementFilter, debugFrameIndex = -1) {
32679
+ const {
32680
+ log: log2,
32681
+ domSession,
32682
+ beforeCaptureHook,
32683
+ width,
32684
+ height,
32685
+ fps,
32686
+ effectiveHdr,
32687
+ nativeHdrImageIds,
32688
+ hdrImageBuffers,
32689
+ hdrFrameDirs,
32690
+ hdrVideoStartTimes,
32691
+ imageTransfers,
32692
+ videoTransfers,
32693
+ debugDumpEnabled,
32694
+ debugDumpDir
32695
+ } = ctx;
32696
+ const filteredStacking = elementFilter ? fullStacking.filter((e2) => elementFilter.has(e2.id)) : fullStacking;
32697
+ const layers = groupIntoLayers(filteredStacking);
32698
+ const shouldLog = debugDumpEnabled && debugFrameIndex >= 0;
32699
+ if (shouldLog) {
32700
+ log2.info("[diag] compositeToBuffer plan", {
32701
+ frame: debugFrameIndex,
32702
+ time: time.toFixed(3),
32703
+ filterSize: elementFilter?.size,
32704
+ fullStackingCount: fullStacking.length,
32705
+ filteredCount: filteredStacking.length,
32706
+ layerCount: layers.length,
32707
+ layers: layers.map(
32708
+ (l) => l.type === "hdr" ? {
32709
+ type: "hdr",
32710
+ id: l.element.id,
32711
+ z: l.element.zIndex,
32712
+ visible: l.element.visible,
32713
+ opacity: l.element.opacity,
32714
+ bounds: `${Math.round(l.element.x)},${Math.round(l.element.y)} ${Math.round(l.element.width)}x${Math.round(l.element.height)}`
32715
+ } : { type: "dom", ids: l.elementIds }
32716
+ )
32717
+ });
32718
+ }
32719
+ for (const [layerIdx, layer] of layers.entries()) {
32720
+ if (layer.type === "hdr") {
32721
+ const before2 = shouldLog ? countNonZeroRgb48(canvas) : 0;
32722
+ const isHdrImage = nativeHdrImageIds.has(layer.element.id);
32723
+ if (isHdrImage) {
32724
+ blitHdrImageLayer(
32725
+ canvas,
32726
+ layer.element,
32727
+ hdrImageBuffers,
32728
+ width,
32729
+ height,
32730
+ log2,
32731
+ imageTransfers.get(layer.element.id),
32732
+ effectiveHdr.transfer
32733
+ );
32734
+ } else {
32735
+ blitHdrVideoLayer(
32736
+ canvas,
32737
+ layer.element,
32738
+ time,
32739
+ fps,
32740
+ hdrFrameDirs,
32741
+ hdrVideoStartTimes,
32742
+ width,
32743
+ height,
32744
+ log2,
32745
+ videoTransfers.get(layer.element.id),
32746
+ effectiveHdr.transfer
32747
+ );
32748
+ }
32749
+ if (shouldLog) {
32750
+ const after2 = countNonZeroRgb48(canvas);
32751
+ if (isHdrImage) {
32752
+ const buf = hdrImageBuffers.get(layer.element.id);
32753
+ log2.info("[diag] hdr layer blit", {
32754
+ frame: debugFrameIndex,
32755
+ layerIdx,
32756
+ id: layer.element.id,
32757
+ kind: "image",
32758
+ pixelsAdded: after2 - before2,
32759
+ totalNonZero: after2,
32760
+ bufferDecoded: !!buf,
32761
+ bufferDims: buf ? `${buf.width}x${buf.height}` : null
32762
+ });
32763
+ } else {
32764
+ const frameDir = hdrFrameDirs.get(layer.element.id);
32765
+ const startTime = hdrVideoStartTimes.get(layer.element.id) ?? 0;
32766
+ const localTime = time - startTime;
32767
+ const frameNum = Math.floor(localTime * fps) + 1;
32768
+ const expectedFrame = frameDir ? join31(frameDir, `frame_${String(frameNum).padStart(4, "0")}.png`) : null;
32769
+ log2.info("[diag] hdr layer blit", {
32770
+ frame: debugFrameIndex,
32771
+ layerIdx,
32772
+ id: layer.element.id,
32773
+ kind: "video",
32774
+ pixelsAdded: after2 - before2,
32775
+ totalNonZero: after2,
32776
+ startTime,
32777
+ localTime: localTime.toFixed(3),
32778
+ hdrFrameNum: frameNum,
32779
+ expectedFrame,
32780
+ expectedFrameExists: expectedFrame ? existsSync30(expectedFrame) : false
32781
+ });
32782
+ }
32783
+ }
32784
+ } else {
32785
+ const allElementIds = fullStacking.map((e2) => e2.id);
32786
+ const layerIds = new Set(layer.elementIds);
32787
+ const hideIds = allElementIds.filter((id) => !layerIds.has(id));
32788
+ await domSession.page.evaluate((t3) => {
32789
+ if (window.__hf && typeof window.__hf.seek === "function") window.__hf.seek(t3);
32790
+ }, time);
32791
+ if (beforeCaptureHook) {
32792
+ await beforeCaptureHook(domSession.page, time);
32793
+ }
32794
+ await applyDomLayerMask(domSession.page, layer.elementIds, hideIds);
32795
+ const domPng = await captureAlphaPng(domSession.page, width, height);
32796
+ await removeDomLayerMask(domSession.page, hideIds);
32797
+ try {
32798
+ const { data: domRgba } = decodePng(domPng);
32799
+ const before2 = shouldLog ? countNonZeroRgb48(canvas) : 0;
32800
+ const alphaPixels = shouldLog ? countNonZeroAlpha(domRgba) : 0;
32801
+ blitRgba8OverRgb48le(domRgba, canvas, width, height, effectiveHdr.transfer);
32802
+ if (shouldLog && debugDumpDir) {
32803
+ const after2 = countNonZeroRgb48(canvas);
32804
+ const dumpName = `frame_${String(debugFrameIndex).padStart(4, "0")}_layer_${String(layerIdx).padStart(2, "0")}_dom.png`;
32805
+ const dumpPath = join31(debugDumpDir, dumpName);
32806
+ writeFileSync10(dumpPath, domPng);
32807
+ log2.info("[diag] dom layer blit", {
32808
+ frame: debugFrameIndex,
32809
+ layerIdx,
32810
+ layerIds: layer.elementIds,
32811
+ hideCount: hideIds.length,
32812
+ pngBytes: domPng.length,
32813
+ alphaPixels,
32814
+ pixelsAdded: after2 - before2,
32815
+ totalNonZero: after2,
32816
+ dumpPath
32817
+ });
32818
+ }
32819
+ } catch (err) {
32820
+ log2.warn("DOM layer decode/blit failed; skipping overlay", {
32821
+ layerIds: layer.elementIds,
32822
+ error: err instanceof Error ? err.message : String(err)
32823
+ });
32824
+ }
32825
+ }
32826
+ }
32827
+ if (shouldLog && debugDumpDir) {
32828
+ const finalNonZero = countNonZeroRgb48(canvas);
32829
+ log2.info("[diag] compositeToBuffer end", {
32830
+ frame: debugFrameIndex,
32831
+ finalNonZeroPixels: finalNonZero,
32832
+ totalPixels: width * height,
32833
+ coverage: (finalNonZero / (width * height) * 100).toFixed(1) + "%"
32834
+ });
32835
+ }
32836
+ }
32522
32837
  function createRenderJob(config) {
32523
32838
  return {
32524
32839
  id: randomUUID2(),
@@ -32559,10 +32874,10 @@ function extractStandaloneEntryFromIndex(indexHtml, entryFile) {
32559
32874
  return document2.toString();
32560
32875
  }
32561
32876
  async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSignal) {
32562
- const moduleDir = dirname10(fileURLToPath3(import.meta.url));
32563
- const producerRoot = process.env.PRODUCER_RENDERS_DIR ? resolve16(process.env.PRODUCER_RENDERS_DIR, "..") : resolve16(moduleDir, "../..");
32877
+ const moduleDir = dirname11(fileURLToPath3(import.meta.url));
32878
+ const producerRoot = process.env.PRODUCER_RENDERS_DIR ? resolve17(process.env.PRODUCER_RENDERS_DIR, "..") : resolve17(moduleDir, "../..");
32564
32879
  const debugDir = join31(producerRoot, ".debug");
32565
- const workDir = job.config.debug ? join31(debugDir, job.id) : join31(dirname10(outputPath), `work-${job.id}`);
32880
+ const workDir = job.config.debug ? join31(debugDir, job.id) : join31(dirname11(outputPath), `work-${job.id}`);
32566
32881
  const pipelineStart = Date.now();
32567
32882
  const log2 = job.config.logger ?? defaultLogger;
32568
32883
  let fileServer = null;
@@ -32594,28 +32909,28 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
32594
32909
  };
32595
32910
  job.startedAt = /* @__PURE__ */ new Date();
32596
32911
  assertNotAborted();
32597
- if (!existsSync28(workDir)) mkdirSync17(workDir, { recursive: true });
32912
+ if (!existsSync30(workDir)) mkdirSync17(workDir, { recursive: true });
32598
32913
  if (job.config.debug) {
32599
32914
  const logPath = join31(workDir, "render.log");
32600
32915
  restoreLogger = installDebugLogger(logPath, log2);
32601
32916
  }
32602
32917
  const entryFile = job.config.entryFile || "index.html";
32603
32918
  let htmlPath = join31(projectDir, entryFile);
32604
- if (!existsSync28(htmlPath)) {
32919
+ if (!existsSync30(htmlPath)) {
32605
32920
  throw new Error(`Entry file not found: ${htmlPath}`);
32606
32921
  }
32607
32922
  assertNotAborted();
32608
- const rawEntry = readFileSync21(htmlPath, "utf-8");
32923
+ const rawEntry = readFileSync22(htmlPath, "utf-8");
32609
32924
  if (entryFile !== "index.html" && rawEntry.trimStart().startsWith("<template")) {
32610
32925
  const wrapperPath = join31(workDir, "standalone-entry.html");
32611
32926
  const projectIndexPath = join31(projectDir, "index.html");
32612
- if (!existsSync28(projectIndexPath)) {
32927
+ if (!existsSync30(projectIndexPath)) {
32613
32928
  throw new Error(
32614
32929
  `Template entry file "${entryFile}" requires a project index.html to extract its render shell.`
32615
32930
  );
32616
32931
  }
32617
32932
  const standaloneHtml = extractStandaloneEntryFromIndex(
32618
- readFileSync21(projectIndexPath, "utf-8"),
32933
+ readFileSync22(projectIndexPath, "utf-8"),
32619
32934
  entryFile
32620
32935
  );
32621
32936
  if (!standaloneHtml) {
@@ -32859,11 +33174,11 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
32859
33174
  composition.videos.map(async (v) => {
32860
33175
  let videoPath = v.src;
32861
33176
  if (!videoPath.startsWith("/")) {
32862
- const fromCompiled = existsSync28(join31(compiledDir, videoPath)) ? join31(compiledDir, videoPath) : join31(projectDir, videoPath);
33177
+ const fromCompiled = existsSync30(join31(compiledDir, videoPath)) ? join31(compiledDir, videoPath) : join31(projectDir, videoPath);
32863
33178
  videoPath = fromCompiled;
32864
33179
  }
32865
- if (!existsSync28(videoPath)) return;
32866
- const meta = await extractVideoMetadata(videoPath);
33180
+ if (!existsSync30(videoPath)) return;
33181
+ const meta = await extractMediaMetadata(videoPath);
32867
33182
  if (isHdrColorSpace(meta.colorSpace)) {
32868
33183
  nativeHdrVideoIds.add(v.id);
32869
33184
  videoTransfers.set(v.id, detectTransfer(meta.colorSpace));
@@ -32880,11 +33195,11 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
32880
33195
  composition.images.map(async (img) => {
32881
33196
  let imgPath = img.src;
32882
33197
  if (!imgPath.startsWith("/")) {
32883
- const fromCompiled = existsSync28(join31(compiledDir, imgPath)) ? join31(compiledDir, imgPath) : join31(projectDir, imgPath);
33198
+ const fromCompiled = existsSync30(join31(compiledDir, imgPath)) ? join31(compiledDir, imgPath) : join31(projectDir, imgPath);
32884
33199
  imgPath = fromCompiled;
32885
33200
  }
32886
- if (!existsSync28(imgPath)) return null;
32887
- const meta = await extractVideoMetadata(imgPath);
33201
+ if (!existsSync30(imgPath)) return null;
33202
+ const meta = await extractMediaMetadata(imgPath);
32888
33203
  if (isHdrColorSpace(meta.colorSpace)) {
32889
33204
  nativeHdrImageIds.add(img.id);
32890
33205
  imageTransfers.set(img.id, detectTransfer(meta.colorSpace));
@@ -32988,7 +33303,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
32988
33303
  assertNotAborted();
32989
33304
  }
32990
33305
  const framesDir = join31(workDir, "captured-frames");
32991
- if (!existsSync28(framesDir)) mkdirSync17(framesDir, { recursive: true });
33306
+ if (!existsSync30(framesDir)) mkdirSync17(framesDir, { recursive: true });
32992
33307
  const captureOptions = {
32993
33308
  width,
32994
33309
  height,
@@ -32996,6 +33311,10 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
32996
33311
  format: needsAlpha ? "png" : "jpeg",
32997
33312
  quality: needsAlpha ? void 0 : job.config.quality === "draft" ? 80 : 95
32998
33313
  };
33314
+ const buildHdrCaptureOptions = () => ({
33315
+ ...captureOptions,
33316
+ skipReadinessVideoIds: Array.from(nativeHdrVideoIds)
33317
+ });
32999
33318
  const workerCount = calculateOptimalWorkers(totalFrames, job.config.workers, cfg);
33000
33319
  const FORMAT_EXT2 = { mp4: ".mp4", webm: ".webm", mov: ".mov" };
33001
33320
  const videoExt = FORMAT_EXT2[outputFormat] ?? ".mp4";
@@ -33022,7 +33341,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
33022
33341
  let srcPath = v.src;
33023
33342
  if (!srcPath.startsWith("/")) {
33024
33343
  const fromCompiled = join31(compiledDir, srcPath);
33025
- srcPath = existsSync28(fromCompiled) ? fromCompiled : join31(projectDir, srcPath);
33344
+ srcPath = existsSync30(fromCompiled) ? fromCompiled : join31(projectDir, srcPath);
33026
33345
  }
33027
33346
  hdrVideoSrcPaths.set(v.id, srcPath);
33028
33347
  }
@@ -33030,7 +33349,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
33030
33349
  const domSession = await createCaptureSession(
33031
33350
  fileServer.url,
33032
33351
  framesDir,
33033
- { ...captureOptions, skipReadinessVideoIds: Array.from(nativeHdrVideoIds) },
33352
+ buildHdrCaptureOptions(),
33034
33353
  createVideoFrameInjector(frameLookup),
33035
33354
  cfg
33036
33355
  );
@@ -33126,6 +33445,29 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
33126
33445
  }
33127
33446
  }
33128
33447
  }
33448
+ for (const [imageId, startTime] of hdrImageStartTimes) {
33449
+ if (hdrExtractionDims.has(imageId)) continue;
33450
+ const img = composition.images.find((i2) => i2.id === imageId);
33451
+ if (!img) continue;
33452
+ const duration = img.end - img.start;
33453
+ const retryTime = startTime + Math.min(0.5, duration * 0.1);
33454
+ await domSession.page.evaluate((t3) => {
33455
+ if (window.__hf && typeof window.__hf.seek === "function") window.__hf.seek(t3);
33456
+ }, retryTime);
33457
+ if (domSession.onBeforeCapture) {
33458
+ await domSession.onBeforeCapture(domSession.page, retryTime);
33459
+ }
33460
+ const retryStacking = await queryElementStacking(domSession.page, nativeHdrIds);
33461
+ for (const el of retryStacking) {
33462
+ if (el.id === imageId && el.isHdr && el.layoutWidth > 0 && el.layoutHeight > 0) {
33463
+ hdrExtractionDims.set(el.id, { width: el.layoutWidth, height: el.layoutHeight });
33464
+ if (!hdrImageFitInfo.has(el.id)) {
33465
+ hdrImageFitInfo.set(el.id, { fit: el.objectFit, position: el.objectPosition });
33466
+ }
33467
+ break;
33468
+ }
33469
+ }
33470
+ }
33129
33471
  for (const [videoId, srcPath] of hdrVideoSrcPaths) {
33130
33472
  const video = composition.videos.find((v) => v.id === videoId);
33131
33473
  if (!video) continue;
@@ -33168,7 +33510,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
33168
33510
  const hdrImageBuffers = /* @__PURE__ */ new Map();
33169
33511
  for (const [imageId, srcPath] of hdrImageSrcPaths) {
33170
33512
  try {
33171
- const decoded = decodePngToRgb48le(readFileSync21(srcPath));
33513
+ const decoded = decodePngToRgb48le(readFileSync22(srcPath));
33172
33514
  const layout2 = hdrExtractionDims.get(imageId);
33173
33515
  const fitInfo = hdrImageFitInfo.get(imageId);
33174
33516
  if (layout2 && (layout2.width !== decoded.width || layout2.height !== decoded.height)) {
@@ -33208,21 +33550,6 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
33208
33550
  }
33209
33551
  assertNotAborted();
33210
33552
  try {
33211
- let countNonZeroAlpha2 = function(rgba) {
33212
- let n = 0;
33213
- for (let p = 3; p < rgba.length; p += 4) {
33214
- if (rgba[p] !== 0) n++;
33215
- }
33216
- return n;
33217
- }, countNonZeroRgb482 = function(buf) {
33218
- let n = 0;
33219
- for (let p = 0; p < buf.length; p += 6) {
33220
- if (buf[p] !== 0 || buf[p + 1] !== 0 || buf[p + 2] !== 0 || buf[p + 3] !== 0 || buf[p + 4] !== 0 || buf[p + 5] !== 0)
33221
- n++;
33222
- }
33223
- return n;
33224
- };
33225
- var countNonZeroAlpha = countNonZeroAlpha2, countNonZeroRgb48 = countNonZeroRgb482;
33226
33553
  const beforeCaptureHook = domSession.onBeforeCapture;
33227
33554
  const cleanedUpVideos = /* @__PURE__ */ new Set();
33228
33555
  const hdrVideoEndTimes = /* @__PURE__ */ new Map();
@@ -33233,156 +33560,31 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
33233
33560
  }
33234
33561
  const debugDumpEnabled = process.env.KEEP_TEMP === "1";
33235
33562
  const debugDumpDir = debugDumpEnabled ? join31(framesDir, "debug-composite") : null;
33236
- if (debugDumpDir && !existsSync28(debugDumpDir)) {
33563
+ if (debugDumpDir && !existsSync30(debugDumpDir)) {
33237
33564
  mkdirSync17(debugDumpDir, { recursive: true });
33238
33565
  }
33239
- async function compositeToBuffer(canvas, time, fullStacking, elementFilter, debugFrameIndex = -1) {
33240
- const filteredStacking = elementFilter ? fullStacking.filter((e2) => elementFilter.has(e2.id)) : fullStacking;
33241
- const layers = groupIntoLayers(filteredStacking);
33242
- const shouldLog = debugDumpEnabled && debugFrameIndex >= 0;
33243
- if (shouldLog) {
33244
- log2.info("[diag] compositeToBuffer plan", {
33245
- frame: debugFrameIndex,
33246
- time: time.toFixed(3),
33247
- filterSize: elementFilter?.size,
33248
- fullStackingCount: fullStacking.length,
33249
- filteredCount: filteredStacking.length,
33250
- layerCount: layers.length,
33251
- layers: layers.map(
33252
- (l) => l.type === "hdr" ? {
33253
- type: "hdr",
33254
- id: l.element.id,
33255
- z: l.element.zIndex,
33256
- visible: l.element.visible,
33257
- opacity: l.element.opacity,
33258
- bounds: `${Math.round(l.element.x)},${Math.round(l.element.y)} ${Math.round(l.element.width)}x${Math.round(l.element.height)}`
33259
- } : { type: "dom", ids: l.elementIds }
33260
- )
33261
- });
33262
- }
33263
- for (const [layerIdx, layer] of layers.entries()) {
33264
- if (layer.type === "hdr") {
33265
- const before2 = shouldLog ? countNonZeroRgb482(canvas) : 0;
33266
- const isHdrImage = nativeHdrImageIds.has(layer.element.id);
33267
- if (isHdrImage) {
33268
- blitHdrImageLayer(
33269
- canvas,
33270
- layer.element,
33271
- hdrImageBuffers,
33272
- width,
33273
- height,
33274
- log2,
33275
- imageTransfers.get(layer.element.id),
33276
- effectiveHdr?.transfer
33277
- );
33278
- } else {
33279
- blitHdrVideoLayer(
33280
- canvas,
33281
- layer.element,
33282
- time,
33283
- job.config.fps,
33284
- hdrFrameDirs,
33285
- hdrVideoStartTimes,
33286
- width,
33287
- height,
33288
- log2,
33289
- videoTransfers.get(layer.element.id),
33290
- effectiveHdr?.transfer
33291
- );
33292
- }
33293
- if (shouldLog) {
33294
- const after2 = countNonZeroRgb482(canvas);
33295
- if (isHdrImage) {
33296
- const buf = hdrImageBuffers.get(layer.element.id);
33297
- log2.info("[diag] hdr layer blit", {
33298
- frame: debugFrameIndex,
33299
- layerIdx,
33300
- id: layer.element.id,
33301
- kind: "image",
33302
- pixelsAdded: after2 - before2,
33303
- totalNonZero: after2,
33304
- bufferDecoded: !!buf,
33305
- bufferDims: buf ? `${buf.width}x${buf.height}` : null
33306
- });
33307
- } else {
33308
- const frameDir = hdrFrameDirs.get(layer.element.id);
33309
- const startTime = hdrVideoStartTimes.get(layer.element.id) ?? 0;
33310
- const localTime = time - startTime;
33311
- const frameNum = Math.floor(localTime * job.config.fps) + 1;
33312
- const expectedFrame = frameDir ? join31(frameDir, `frame_${String(frameNum).padStart(4, "0")}.png`) : null;
33313
- log2.info("[diag] hdr layer blit", {
33314
- frame: debugFrameIndex,
33315
- layerIdx,
33316
- id: layer.element.id,
33317
- kind: "video",
33318
- pixelsAdded: after2 - before2,
33319
- totalNonZero: after2,
33320
- startTime,
33321
- localTime: localTime.toFixed(3),
33322
- hdrFrameNum: frameNum,
33323
- expectedFrame,
33324
- expectedFrameExists: expectedFrame ? existsSync28(expectedFrame) : false
33325
- });
33326
- }
33327
- }
33328
- } else {
33329
- const allElementIds = fullStacking.map((e2) => e2.id);
33330
- const layerIds = new Set(layer.elementIds);
33331
- const hideIds = allElementIds.filter((id) => !layerIds.has(id));
33332
- await domSession.page.evaluate((t3) => {
33333
- if (window.__hf && typeof window.__hf.seek === "function") window.__hf.seek(t3);
33334
- }, time);
33335
- if (beforeCaptureHook) {
33336
- await beforeCaptureHook(domSession.page, time);
33337
- }
33338
- await applyDomLayerMask(domSession.page, layer.elementIds, hideIds);
33339
- const domPng = await captureAlphaPng(domSession.page, width, height);
33340
- await removeDomLayerMask(domSession.page, hideIds);
33341
- try {
33342
- const { data: domRgba } = decodePng(domPng);
33343
- if (!effectiveHdr) {
33344
- throw new Error(
33345
- "Invariant violation: effectiveHdr is undefined inside HDR layer branch"
33346
- );
33347
- }
33348
- const before2 = shouldLog ? countNonZeroRgb482(canvas) : 0;
33349
- const alphaPixels = shouldLog ? countNonZeroAlpha2(domRgba) : 0;
33350
- blitRgba8OverRgb48le(domRgba, canvas, width, height, effectiveHdr.transfer);
33351
- if (shouldLog && debugDumpDir) {
33352
- const after2 = countNonZeroRgb482(canvas);
33353
- const dumpName = `frame_${String(debugFrameIndex).padStart(4, "0")}_layer_${String(layerIdx).padStart(2, "0")}_dom.png`;
33354
- const dumpPath = join31(debugDumpDir, dumpName);
33355
- writeFileSync10(dumpPath, domPng);
33356
- log2.info("[diag] dom layer blit", {
33357
- frame: debugFrameIndex,
33358
- layerIdx,
33359
- layerIds: layer.elementIds,
33360
- hideCount: hideIds.length,
33361
- pngBytes: domPng.length,
33362
- alphaPixels,
33363
- pixelsAdded: after2 - before2,
33364
- totalNonZero: after2,
33365
- dumpPath
33366
- });
33367
- }
33368
- } catch (err) {
33369
- log2.warn("DOM layer decode/blit failed; skipping overlay", {
33370
- layerIds: layer.elementIds,
33371
- error: err instanceof Error ? err.message : String(err)
33372
- });
33373
- }
33374
- }
33375
- }
33376
- if (shouldLog && debugDumpDir) {
33377
- const finalNonZero = countNonZeroRgb482(canvas);
33378
- log2.info("[diag] compositeToBuffer end", {
33379
- frame: debugFrameIndex,
33380
- finalNonZeroPixels: finalNonZero,
33381
- totalPixels: width * height,
33382
- coverage: (finalNonZero / (width * height) * 100).toFixed(1) + "%"
33383
- });
33384
- }
33566
+ if (!effectiveHdr) {
33567
+ throw new Error(
33568
+ "Internal: HDR render path entered without effectiveHdr \u2014 this is a bug."
33569
+ );
33385
33570
  }
33571
+ const hdrCompositeCtx = {
33572
+ log: log2,
33573
+ domSession,
33574
+ beforeCaptureHook,
33575
+ width,
33576
+ height,
33577
+ fps: job.config.fps,
33578
+ effectiveHdr,
33579
+ nativeHdrImageIds,
33580
+ hdrImageBuffers,
33581
+ hdrFrameDirs,
33582
+ hdrVideoStartTimes,
33583
+ imageTransfers,
33584
+ videoTransfers,
33585
+ debugDumpEnabled,
33586
+ debugDumpDir
33587
+ };
33386
33588
  const bufSize = width * height * 6;
33387
33589
  const hasTransitions = transitionRanges.length > 0;
33388
33590
  const transBufferA = hasTransitions ? Buffer.alloc(bufSize) : null;
@@ -33490,7 +33692,14 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
33490
33692
  hdrEncoder.writeFrame(transOutput);
33491
33693
  } else {
33492
33694
  normalCanvas.fill(0);
33493
- await compositeToBuffer(normalCanvas, time, stackingInfo, void 0, i2);
33695
+ await compositeHdrFrame(
33696
+ hdrCompositeCtx,
33697
+ normalCanvas,
33698
+ time,
33699
+ stackingInfo,
33700
+ void 0,
33701
+ i2
33702
+ );
33494
33703
  if (debugDumpEnabled && debugDumpDir && i2 % 30 === 0) {
33495
33704
  const previewPath = join31(
33496
33705
  debugDumpDir,
@@ -33609,7 +33818,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
33609
33818
  fileServer.url,
33610
33819
  workDir,
33611
33820
  tasks,
33612
- { ...captureOptions, skipReadinessVideoIds: Array.from(nativeHdrVideoIds) },
33821
+ buildHdrCaptureOptions(),
33613
33822
  () => createVideoFrameInjector(frameLookup),
33614
33823
  abortSignal,
33615
33824
  (progress) => {
@@ -33639,7 +33848,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
33639
33848
  const session = probeSession ?? await createCaptureSession(
33640
33849
  fileServer.url,
33641
33850
  framesDir,
33642
- { ...captureOptions, skipReadinessVideoIds: Array.from(nativeHdrVideoIds) },
33851
+ buildHdrCaptureOptions(),
33643
33852
  videoInjector,
33644
33853
  cfg
33645
33854
  );
@@ -33691,7 +33900,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
33691
33900
  fileServer.url,
33692
33901
  workDir,
33693
33902
  tasks,
33694
- { ...captureOptions, skipReadinessVideoIds: Array.from(nativeHdrVideoIds) },
33903
+ buildHdrCaptureOptions(),
33695
33904
  () => createVideoFrameInjector(frameLookup),
33696
33905
  abortSignal,
33697
33906
  (progress) => {
@@ -33722,7 +33931,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
33722
33931
  const session = probeSession ?? await createCaptureSession(
33723
33932
  fileServer.url,
33724
33933
  framesDir,
33725
- { ...captureOptions, skipReadinessVideoIds: Array.from(nativeHdrVideoIds) },
33934
+ buildHdrCaptureOptions(),
33726
33935
  videoInjector,
33727
33936
  cfg
33728
33937
  );
@@ -33867,7 +34076,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
33867
34076
  }
33868
34077
  }
33869
34078
  if (job.config.debug) {
33870
- if (existsSync28(outputPath)) {
34079
+ if (existsSync30(outputPath)) {
33871
34080
  const debugOutput = join31(workDir, `output${videoExt}`);
33872
34081
  copyFileSync2(outputPath, debugOutput);
33873
34082
  }
@@ -33954,7 +34163,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
33954
34163
  await safeCleanup(
33955
34164
  "remove workDir (error)",
33956
34165
  () => {
33957
- if (existsSync28(workDir)) rmSync6(workDir, { recursive: true, force: true });
34166
+ if (existsSync30(workDir)) rmSync6(workDir, { recursive: true, force: true });
33958
34167
  },
33959
34168
  log2
33960
34169
  );
@@ -34011,8 +34220,8 @@ var init_config3 = __esm({
34011
34220
  });
34012
34221
 
34013
34222
  // ../producer/src/services/hyperframeLint.ts
34014
- import { existsSync as existsSync29, readFileSync as readFileSync22, statSync as statSync8 } from "fs";
34015
- import { resolve as resolve17, join as join32 } from "path";
34223
+ import { existsSync as existsSync31, readFileSync as readFileSync23, statSync as statSync8 } from "fs";
34224
+ import { resolve as resolve18, join as join32 } from "path";
34016
34225
  function isStringRecord(value) {
34017
34226
  if (!value || typeof value !== "object" || Array.isArray(value)) {
34018
34227
  return false;
@@ -34039,22 +34248,22 @@ function pickEntryFile(files, preferredEntryFile) {
34039
34248
  return null;
34040
34249
  }
34041
34250
  function readProjectEntryFile(projectDir, preferredEntryFile) {
34042
- const absProjectDir = resolve17(projectDir);
34043
- if (!existsSync29(absProjectDir) || !statSync8(absProjectDir).isDirectory()) {
34251
+ const absProjectDir = resolve18(projectDir);
34252
+ if (!existsSync31(absProjectDir) || !statSync8(absProjectDir).isDirectory()) {
34044
34253
  return { error: `Project directory not found: ${absProjectDir}` };
34045
34254
  }
34046
34255
  const entryCandidates = [preferredEntryFile, "index.html", "src/index.html"].filter(
34047
34256
  (value) => typeof value === "string" && value.trim().length > 0
34048
34257
  );
34049
34258
  for (const entryFile of entryCandidates) {
34050
- const absoluteEntryPath = resolve17(absProjectDir, entryFile);
34259
+ const absoluteEntryPath = resolve18(absProjectDir, entryFile);
34051
34260
  if (!absoluteEntryPath.startsWith(absProjectDir)) {
34052
34261
  return { error: `Entry file must stay inside project directory: ${entryFile}` };
34053
34262
  }
34054
- if (existsSync29(absoluteEntryPath) && statSync8(absoluteEntryPath).isFile()) {
34263
+ if (existsSync31(absoluteEntryPath) && statSync8(absoluteEntryPath).isFile()) {
34055
34264
  return {
34056
34265
  entryFile,
34057
- html: readFileSync22(absoluteEntryPath, "utf-8"),
34266
+ html: readFileSync23(absoluteEntryPath, "utf-8"),
34058
34267
  source: "projectDir"
34059
34268
  };
34060
34269
  }
@@ -34122,10 +34331,10 @@ var init_semaphore = __esm({
34122
34331
  this.active++;
34123
34332
  return () => this.release();
34124
34333
  }
34125
- return new Promise((resolve37) => {
34334
+ return new Promise((resolve38) => {
34126
34335
  this.queue.push(() => {
34127
34336
  this.active++;
34128
- resolve37(() => this.release());
34337
+ resolve38(() => this.release());
34129
34338
  });
34130
34339
  });
34131
34340
  }
@@ -34148,7 +34357,7 @@ var init_semaphore = __esm({
34148
34357
 
34149
34358
  // ../producer/src/server.ts
34150
34359
  import {
34151
- existsSync as existsSync30,
34360
+ existsSync as existsSync32,
34152
34361
  mkdirSync as mkdirSync18,
34153
34362
  statSync as statSync9,
34154
34363
  mkdtempSync,
@@ -34156,7 +34365,7 @@ import {
34156
34365
  rmSync as rmSync7,
34157
34366
  createReadStream
34158
34367
  } from "fs";
34159
- import { resolve as resolve18, dirname as dirname11, join as join33 } from "path";
34368
+ import { resolve as resolve19, dirname as dirname12, join as join33 } from "path";
34160
34369
  import { tmpdir as tmpdir2 } from "os";
34161
34370
  import { parseArgs as parseArgs2 } from "util";
34162
34371
  import crypto2 from "crypto";
@@ -34178,12 +34387,12 @@ async function prepareRenderBody(body) {
34178
34387
  const options = parseRenderOptions(body);
34179
34388
  const projectDir = typeof body.projectDir === "string" ? body.projectDir : void 0;
34180
34389
  if (projectDir) {
34181
- const absProjectDir = resolve18(projectDir);
34182
- if (!existsSync30(absProjectDir) || !statSync9(absProjectDir).isDirectory()) {
34390
+ const absProjectDir = resolve19(projectDir);
34391
+ if (!existsSync32(absProjectDir) || !statSync9(absProjectDir).isDirectory()) {
34183
34392
  return { error: `Project directory not found: ${absProjectDir}` };
34184
34393
  }
34185
34394
  const entry = options.entryFile || "index.html";
34186
- if (!existsSync30(resolve18(absProjectDir, entry))) {
34395
+ if (!existsSync32(resolve19(absProjectDir, entry))) {
34187
34396
  return { error: `Entry file "${entry}" not found in project directory: ${absProjectDir}` };
34188
34397
  }
34189
34398
  return { prepared: { input: { projectDir: absProjectDir, ...options } } };
@@ -34224,7 +34433,7 @@ function resolveOutputPath(projectDir, outputCandidate, rendersDir, log2) {
34224
34433
  try {
34225
34434
  return resolveRenderPaths(projectDir, outputCandidate, rendersDir).absoluteOutputPath;
34226
34435
  } catch (error) {
34227
- const fallbackPath = resolve18(rendersDir, `producer-fallback-${Date.now()}.mp4`);
34436
+ const fallbackPath = resolve19(rendersDir, `producer-fallback-${Date.now()}.mp4`);
34228
34437
  log2.warn("Failed to resolve output path, using fallback", {
34229
34438
  fallback: fallbackPath,
34230
34439
  error: error instanceof Error ? error.message : String(error)
@@ -34331,8 +34540,8 @@ function createRenderHandlers(options = {}) {
34331
34540
  rendersDir,
34332
34541
  log2
34333
34542
  );
34334
- const outputDir = dirname11(absoluteOutputPath);
34335
- if (!existsSync30(outputDir)) mkdirSync18(outputDir, { recursive: true });
34543
+ const outputDir = dirname12(absoluteOutputPath);
34544
+ if (!existsSync32(outputDir)) mkdirSync18(outputDir, { recursive: true });
34336
34545
  const release2 = await renderSemaphore.acquire();
34337
34546
  log2.info("render started", {
34338
34547
  requestId,
@@ -34359,7 +34568,7 @@ function createRenderHandlers(options = {}) {
34359
34568
  log2.info(`render progress ${pct}%`, { requestId, stage: j2.currentStage, message });
34360
34569
  }
34361
34570
  });
34362
- const fileSize = existsSync30(absoluteOutputPath) ? statSync9(absoluteOutputPath).size : 0;
34571
+ const fileSize = existsSync32(absoluteOutputPath) ? statSync9(absoluteOutputPath).size : 0;
34363
34572
  const durationMs = Date.now() - t0;
34364
34573
  const outputToken = store.register(absoluteOutputPath);
34365
34574
  const outputUrl = `${outputUrlPrefix}/${outputToken}`;
@@ -34442,8 +34651,8 @@ function createRenderHandlers(options = {}) {
34442
34651
  rendersDir,
34443
34652
  log2
34444
34653
  );
34445
- const outputDir = dirname11(absoluteOutputPath);
34446
- if (!existsSync30(outputDir)) mkdirSync18(outputDir, { recursive: true });
34654
+ const outputDir = dirname12(absoluteOutputPath);
34655
+ if (!existsSync32(outputDir)) mkdirSync18(outputDir, { recursive: true });
34447
34656
  log2.info("render-stream started", { requestId, projectDir: input.projectDir });
34448
34657
  const job = createRenderJob({
34449
34658
  fps: input.fps,
@@ -34488,7 +34697,7 @@ function createRenderHandlers(options = {}) {
34488
34697
  },
34489
34698
  abortController.signal
34490
34699
  );
34491
- const fileSize = existsSync30(absoluteOutputPath) ? statSync9(absoluteOutputPath).size : 0;
34700
+ const fileSize = existsSync32(absoluteOutputPath) ? statSync9(absoluteOutputPath).size : 0;
34492
34701
  const outputToken = store.register(absoluteOutputPath);
34493
34702
  const outputUrl = `${outputUrlPrefix}/${outputToken}`;
34494
34703
  log2.info("render-stream completed", { requestId, fileSize, perf: job.perfSummary ?? null });
@@ -34547,7 +34756,7 @@ function createRenderHandlers(options = {}) {
34547
34756
  if (!artifact) {
34548
34757
  return c2.json({ success: false, error: "Output artifact not found or expired" }, 404);
34549
34758
  }
34550
- if (!existsSync30(artifact.path)) {
34759
+ if (!existsSync32(artifact.path)) {
34551
34760
  store.delete(token);
34552
34761
  return c2.json({ success: false, error: "Output artifact file missing" }, 404);
34553
34762
  }
@@ -34612,7 +34821,7 @@ var init_server = __esm({
34612
34821
  init_paths();
34613
34822
  init_logger();
34614
34823
  init_semaphore();
34615
- entryScript = process.argv[1] ? resolve18(process.argv[1]) : "";
34824
+ entryScript = process.argv[1] ? resolve19(process.argv[1]) : "";
34616
34825
  isPublicServerEntry = entryScript.endsWith("/public-server.js") || entryScript.endsWith("/src/server.ts");
34617
34826
  if (isPublicServerEntry) {
34618
34827
  const { values } = parseArgs2({
@@ -34684,19 +34893,21 @@ __export(studioServer_exports, {
34684
34893
  });
34685
34894
  import { Hono as Hono5 } from "hono";
34686
34895
  import { streamSSE as streamSSE3 } from "hono/streaming";
34687
- import { existsSync as existsSync31, readFileSync as readFileSync23, writeFileSync as writeFileSync12, statSync as statSync10 } from "fs";
34688
- import { resolve as resolve19, join as join34, basename as basename2 } from "path";
34896
+ import { existsSync as existsSync33, readFileSync as readFileSync24, writeFileSync as writeFileSync12, statSync as statSync10 } from "fs";
34897
+ import { resolve as resolve20, join as join34, basename as basename2 } from "path";
34689
34898
  function resolveDistDir() {
34690
- const builtPath = resolve19(__dirname, "studio");
34691
- if (existsSync31(resolve19(builtPath, "index.html"))) return builtPath;
34692
- const devPath = resolve19(__dirname, "..", "..", "..", "studio", "dist");
34693
- if (existsSync31(resolve19(devPath, "index.html"))) return devPath;
34899
+ const builtPath = resolve20(__dirname, "studio");
34900
+ if (existsSync33(resolve20(builtPath, "index.html"))) return builtPath;
34901
+ const devPath = resolve20(__dirname, "..", "..", "..", "studio", "dist");
34902
+ if (existsSync33(resolve20(devPath, "index.html"))) return devPath;
34694
34903
  return builtPath;
34695
34904
  }
34696
34905
  function resolveRuntimePath() {
34697
- const builtPath = resolve19(__dirname, "hyperframe-runtime.js");
34698
- if (existsSync31(builtPath)) return builtPath;
34699
- const devPath = resolve19(
34906
+ const builtPath = resolve20(__dirname, "hyperframe-runtime.js");
34907
+ if (existsSync33(builtPath)) return builtPath;
34908
+ const iifePath = resolve20(__dirname, "hyperframe.runtime.iife.js");
34909
+ if (existsSync33(iifePath)) return iifePath;
34910
+ const devPath = resolve20(
34700
34911
  __dirname,
34701
34912
  "..",
34702
34913
  "..",
@@ -34705,7 +34916,7 @@ function resolveRuntimePath() {
34705
34916
  "dist",
34706
34917
  "hyperframe.runtime.iife.js"
34707
34918
  );
34708
- if (existsSync31(devPath)) return devPath;
34919
+ if (existsSync33(devPath)) return devPath;
34709
34920
  return builtPath;
34710
34921
  }
34711
34922
  async function getThumbnailBrowser() {
@@ -34882,7 +35093,7 @@ function createStudioServer(options) {
34882
35093
  });
34883
35094
  app.get("/api/runtime.js", (c2) => {
34884
35095
  const serve4 = async () => {
34885
- const runtimeSource = await loadRuntimeSourceFallback() ?? (existsSync31(runtimePath) ? readFileSync23(runtimePath, "utf-8") : null);
35096
+ const runtimeSource = await loadRuntimeSource() ?? (existsSync33(runtimePath) ? readFileSync24(runtimePath, "utf-8") : null);
34886
35097
  if (!runtimeSource) return c2.text("runtime not available", 404);
34887
35098
  return c2.body(runtimeSource, 200, {
34888
35099
  "Content-Type": "text/javascript",
@@ -34917,27 +35128,27 @@ function createStudioServer(options) {
34917
35128
  return api.fetch(forwardReq);
34918
35129
  });
34919
35130
  app.get("/assets/*", (c2) => {
34920
- const filePath = resolve19(studioDir, c2.req.path.slice(1));
34921
- if (!existsSync31(filePath) || !statSync10(filePath).isFile()) return c2.text("not found", 404);
34922
- const content = readFileSync23(filePath);
35131
+ const filePath = resolve20(studioDir, c2.req.path.slice(1));
35132
+ if (!existsSync33(filePath) || !statSync10(filePath).isFile()) return c2.text("not found", 404);
35133
+ const content = readFileSync24(filePath);
34923
35134
  return new Response(content, {
34924
35135
  headers: { "Content-Type": getMimeType(filePath), "Cache-Control": "no-store" }
34925
35136
  });
34926
35137
  });
34927
35138
  app.get("/icons/*", (c2) => {
34928
- const filePath = resolve19(studioDir, c2.req.path.slice(1));
34929
- if (!existsSync31(filePath) || !statSync10(filePath).isFile()) return c2.text("not found", 404);
34930
- const content = readFileSync23(filePath);
35139
+ const filePath = resolve20(studioDir, c2.req.path.slice(1));
35140
+ if (!existsSync33(filePath) || !statSync10(filePath).isFile()) return c2.text("not found", 404);
35141
+ const content = readFileSync24(filePath);
34931
35142
  return new Response(content, {
34932
35143
  headers: { "Content-Type": getMimeType(filePath), "Cache-Control": "no-store" }
34933
35144
  });
34934
35145
  });
34935
35146
  app.get("*", (c2) => {
34936
- const indexPath = resolve19(studioDir, "index.html");
34937
- if (!existsSync31(indexPath)) {
35147
+ const indexPath = resolve20(studioDir, "index.html");
35148
+ if (!existsSync33(indexPath)) {
34938
35149
  return c2.text("Studio not found. Rebuild with: pnpm run build", 500);
34939
35150
  }
34940
- return c2.html(readFileSync23(indexPath, "utf-8"));
35151
+ return c2.html(readFileSync24(indexPath, "utf-8"));
34941
35152
  });
34942
35153
  return { app, watcher };
34943
35154
  }
@@ -34961,32 +35172,32 @@ __export(preview_exports, {
34961
35172
  examples: () => examples
34962
35173
  });
34963
35174
  import { spawn as spawn8 } from "child_process";
34964
- import { existsSync as existsSync32, lstatSync, symlinkSync, unlinkSync as unlinkSync5, readlinkSync, mkdirSync as mkdirSync19 } from "fs";
34965
- import { resolve as resolve20, dirname as dirname12, basename as basename3, join as join35 } from "path";
35175
+ import { existsSync as existsSync34, lstatSync, symlinkSync, unlinkSync as unlinkSync5, readlinkSync, mkdirSync as mkdirSync19 } from "fs";
35176
+ import { resolve as resolve21, dirname as dirname13, basename as basename3, join as join35 } from "path";
34966
35177
  import { fileURLToPath as fileURLToPath4 } from "url";
34967
35178
  import { createRequire } from "module";
34968
35179
  async function runDevMode(dir, projectName) {
34969
35180
  const thisFile = fileURLToPath4(import.meta.url);
34970
- const repoRoot = resolve20(dirname12(thisFile), "..", "..", "..", "..");
35181
+ const repoRoot = resolve21(dirname13(thisFile), "..", "..", "..", "..");
34971
35182
  const projectsDir = join35(repoRoot, "packages", "studio", "data", "projects");
34972
35183
  const pName = projectName ?? basename3(dir);
34973
35184
  const symlinkPath = join35(projectsDir, pName);
34974
35185
  mkdirSync19(projectsDir, { recursive: true });
34975
35186
  let createdSymlink = false;
34976
35187
  if (dir !== symlinkPath) {
34977
- if (existsSync32(symlinkPath)) {
35188
+ if (existsSync34(symlinkPath)) {
34978
35189
  try {
34979
35190
  const stat3 = lstatSync(symlinkPath);
34980
35191
  if (stat3.isSymbolicLink()) {
34981
35192
  const target = readlinkSync(symlinkPath);
34982
- if (resolve20(target) !== resolve20(dir)) {
35193
+ if (resolve21(target) !== resolve21(dir)) {
34983
35194
  unlinkSync5(symlinkPath);
34984
35195
  }
34985
35196
  }
34986
35197
  } catch {
34987
35198
  }
34988
35199
  }
34989
- if (!existsSync32(symlinkPath)) {
35200
+ if (!existsSync34(symlinkPath)) {
34990
35201
  symlinkSync(dir, symlinkPath, "dir");
34991
35202
  createdSymlink = true;
34992
35203
  }
@@ -35028,13 +35239,13 @@ async function runDevMode(dir, projectName) {
35028
35239
  if (createdSymlink) {
35029
35240
  process.on("exit", () => {
35030
35241
  try {
35031
- if (existsSync32(symlinkPath)) unlinkSync5(symlinkPath);
35242
+ if (existsSync34(symlinkPath)) unlinkSync5(symlinkPath);
35032
35243
  } catch {
35033
35244
  }
35034
35245
  });
35035
35246
  }
35036
- return new Promise((resolve37) => {
35037
- child.on("close", () => resolve37());
35247
+ return new Promise((resolve38) => {
35248
+ child.on("close", () => resolve38());
35038
35249
  });
35039
35250
  }
35040
35251
  function hasLocalStudio(dir) {
@@ -35048,19 +35259,19 @@ function hasLocalStudio(dir) {
35048
35259
  }
35049
35260
  async function runLocalStudioMode(dir, projectName) {
35050
35261
  const req = createRequire(join35(dir, "package.json"));
35051
- const studioPkgPath = dirname12(req.resolve("@hyperframes/studio/package.json"));
35262
+ const studioPkgPath = dirname13(req.resolve("@hyperframes/studio/package.json"));
35052
35263
  const pName = projectName ?? basename3(dir);
35053
35264
  const projectsDir = join35(studioPkgPath, "data", "projects");
35054
35265
  const symlinkPath = join35(projectsDir, pName);
35055
35266
  mkdirSync19(projectsDir, { recursive: true });
35056
35267
  let createdSymlink = false;
35057
35268
  if (dir !== symlinkPath) {
35058
- if (existsSync32(symlinkPath) && lstatSync(symlinkPath).isSymbolicLink()) {
35059
- if (resolve20(readlinkSync(symlinkPath)) !== resolve20(dir)) {
35269
+ if (existsSync34(symlinkPath) && lstatSync(symlinkPath).isSymbolicLink()) {
35270
+ if (resolve21(readlinkSync(symlinkPath)) !== resolve21(dir)) {
35060
35271
  unlinkSync5(symlinkPath);
35061
35272
  }
35062
35273
  }
35063
- if (!existsSync32(symlinkPath)) {
35274
+ if (!existsSync34(symlinkPath)) {
35064
35275
  symlinkSync(dir, symlinkPath, "dir");
35065
35276
  createdSymlink = true;
35066
35277
  }
@@ -35099,13 +35310,13 @@ async function runLocalStudioMode(dir, projectName) {
35099
35310
  if (createdSymlink) {
35100
35311
  process.on("exit", () => {
35101
35312
  try {
35102
- if (existsSync32(symlinkPath)) unlinkSync5(symlinkPath);
35313
+ if (existsSync34(symlinkPath)) unlinkSync5(symlinkPath);
35103
35314
  } catch {
35104
35315
  }
35105
35316
  });
35106
35317
  }
35107
- return new Promise((resolve37) => {
35108
- child.on("close", () => resolve37());
35318
+ return new Promise((resolve38) => {
35319
+ child.on("close", () => resolve38());
35109
35320
  });
35110
35321
  }
35111
35322
  async function runEmbeddedMode(dir, startPort, projectName, forceNew = false) {
@@ -35236,11 +35447,11 @@ var init_preview2 = __esm({
35236
35447
  return;
35237
35448
  }
35238
35449
  const rawArg = args.dir;
35239
- const dir = resolve20(rawArg ?? ".");
35450
+ const dir = resolve21(rawArg ?? ".");
35240
35451
  const isImplicitCwd = !rawArg || rawArg === "." || rawArg === "./";
35241
35452
  const projectName = isImplicitCwd ? basename3(process.env.PWD ?? dir) : basename3(dir);
35242
35453
  const indexPath = join35(dir, "index.html");
35243
- if (existsSync32(indexPath)) {
35454
+ if (existsSync34(indexPath)) {
35244
35455
  const project = { dir, name: projectName, indexPath };
35245
35456
  const lintResult = lintProject(project);
35246
35457
  if (lintResult.totalErrors > 0 || lintResult.totalWarnings > 0) {
@@ -35269,15 +35480,15 @@ __export(init_exports, {
35269
35480
  examples: () => examples2
35270
35481
  });
35271
35482
  import {
35272
- existsSync as existsSync33,
35483
+ existsSync as existsSync35,
35273
35484
  mkdirSync as mkdirSync20,
35274
35485
  copyFileSync as copyFileSync3,
35275
35486
  cpSync,
35276
35487
  writeFileSync as writeFileSync13,
35277
- readFileSync as readFileSync24,
35488
+ readFileSync as readFileSync25,
35278
35489
  readdirSync as readdirSync12
35279
35490
  } from "fs";
35280
- import { resolve as resolve21, basename as basename4, join as join36, dirname as dirname13 } from "path";
35491
+ import { resolve as resolve22, basename as basename4, join as join36, dirname as dirname14 } from "path";
35281
35492
  import { fileURLToPath as fileURLToPath5 } from "url";
35282
35493
  import { execFileSync as execFileSync4, spawn as spawn9 } from "child_process";
35283
35494
  function probeVideo(filePath) {
@@ -35346,10 +35557,10 @@ function transcodeToMp4(inputPath, outputPath) {
35346
35557
  });
35347
35558
  }
35348
35559
  function resolveAssetDir(devSegments, builtSegments) {
35349
- const base = dirname13(fileURLToPath5(import.meta.url));
35350
- const devPath = resolve21(base, ...devSegments);
35351
- const builtPath = resolve21(base, ...builtSegments);
35352
- return existsSync33(devPath) ? devPath : builtPath;
35560
+ const base = dirname14(fileURLToPath5(import.meta.url));
35561
+ const devPath = resolve22(base, ...devSegments);
35562
+ const builtPath = resolve22(base, ...builtSegments);
35563
+ return existsSync35(devPath) ? devPath : builtPath;
35353
35564
  }
35354
35565
  function getStaticTemplateDir(templateId) {
35355
35566
  return resolveAssetDir(["..", "templates", templateId], ["templates", templateId]);
@@ -35360,7 +35571,7 @@ function getSharedTemplateDir() {
35360
35571
  function patchVideoSrc(dir, videoFilename, durationSeconds) {
35361
35572
  const htmlFiles = readdirSync12(dir, { withFileTypes: true, recursive: true }).filter((e2) => e2.isFile() && e2.name.endsWith(".html")).map((e2) => join36(e2.parentPath ?? e2.path, e2.name));
35362
35573
  for (const file of htmlFiles) {
35363
- let content = readFileSync24(file, "utf-8");
35574
+ let content = readFileSync25(file, "utf-8");
35364
35575
  if (videoFilename) {
35365
35576
  content = content.replaceAll("__VIDEO_SRC__", videoFilename);
35366
35577
  } else {
@@ -35433,7 +35644,7 @@ async function handleVideoFile(videoPath, destDir, interactive) {
35433
35644
  }
35434
35645
  if (shouldTranscode) {
35435
35646
  const mp4Name = localVideoName.replace(/\.[^.]+$/, ".mp4");
35436
- const mp4Path = resolve21(destDir, mp4Name);
35647
+ const mp4Path = resolve22(destDir, mp4Name);
35437
35648
  const spin = be();
35438
35649
  spin.start("Transcoding to H.264 MP4...");
35439
35650
  const ok = await transcodeToMp4(videoPath, mp4Path);
@@ -35442,10 +35653,10 @@ async function handleVideoFile(videoPath, destDir, interactive) {
35442
35653
  localVideoName = mp4Name;
35443
35654
  } else {
35444
35655
  spin.stop(c.warn("Transcode failed \u2014 copying original file"));
35445
- copyFileSync3(videoPath, resolve21(destDir, localVideoName));
35656
+ copyFileSync3(videoPath, resolve22(destDir, localVideoName));
35446
35657
  }
35447
35658
  } else {
35448
- copyFileSync3(videoPath, resolve21(destDir, localVideoName));
35659
+ copyFileSync3(videoPath, resolve22(destDir, localVideoName));
35449
35660
  }
35450
35661
  } else {
35451
35662
  if (interactive) {
@@ -35455,24 +35666,24 @@ async function handleVideoFile(videoPath, destDir, interactive) {
35455
35666
  console.log(c.warn("ffmpeg not installed \u2014 cannot transcode. Copying original."));
35456
35667
  console.log(c.dim("Install: ") + c.accent("brew install ffmpeg"));
35457
35668
  }
35458
- copyFileSync3(videoPath, resolve21(destDir, localVideoName));
35669
+ copyFileSync3(videoPath, resolve22(destDir, localVideoName));
35459
35670
  }
35460
35671
  } else {
35461
- copyFileSync3(videoPath, resolve21(destDir, localVideoName));
35672
+ copyFileSync3(videoPath, resolve22(destDir, localVideoName));
35462
35673
  }
35463
35674
  return { meta, localVideoName };
35464
35675
  }
35465
35676
  async function scaffoldProject(destDir, name, templateId, localVideoName, durationSeconds) {
35466
35677
  mkdirSync20(destDir, { recursive: true });
35467
35678
  const templateDir = getStaticTemplateDir(templateId);
35468
- if (existsSync33(templateDir)) {
35679
+ if (existsSync35(templateDir)) {
35469
35680
  cpSync(templateDir, destDir, { recursive: true });
35470
35681
  } else {
35471
35682
  await fetchRemoteTemplate(templateId, destDir);
35472
35683
  }
35473
35684
  patchVideoSrc(destDir, localVideoName, durationSeconds);
35474
35685
  writeFileSync13(
35475
- resolve21(destDir, "meta.json"),
35686
+ resolve22(destDir, "meta.json"),
35476
35687
  JSON.stringify(
35477
35688
  {
35478
35689
  id: name,
@@ -35484,15 +35695,15 @@ async function scaffoldProject(destDir, name, templateId, localVideoName, durati
35484
35695
  ),
35485
35696
  "utf-8"
35486
35697
  );
35487
- if (!existsSync33(resolve21(destDir, "hyperframes.json"))) {
35698
+ if (!existsSync35(resolve22(destDir, "hyperframes.json"))) {
35488
35699
  const { writeProjectConfig: writeProjectConfig2, DEFAULT_PROJECT_CONFIG: DEFAULT_PROJECT_CONFIG2 } = await Promise.resolve().then(() => (init_projectConfig(), projectConfig_exports));
35489
35700
  writeProjectConfig2(destDir, DEFAULT_PROJECT_CONFIG2);
35490
35701
  }
35491
35702
  const sharedDir = getSharedTemplateDir();
35492
- if (existsSync33(sharedDir)) {
35703
+ if (existsSync35(sharedDir)) {
35493
35704
  for (const entry of readdirSync12(sharedDir, { withFileTypes: true })) {
35494
35705
  const src = join36(sharedDir, entry.name);
35495
- const dest = resolve21(destDir, entry.name);
35706
+ const dest = resolve22(destDir, entry.name);
35496
35707
  if (entry.isFile() || entry.isSymbolicLink()) {
35497
35708
  copyFileSync3(src, dest);
35498
35709
  }
@@ -35604,8 +35815,8 @@ var init_init = __esm({
35604
35815
  if (!interactive) {
35605
35816
  const templateId2 = exampleFlag ?? "blank";
35606
35817
  const name2 = args.name ?? "my-video";
35607
- const destDir2 = resolve21(name2);
35608
- if (existsSync33(destDir2) && readdirSync12(destDir2).length > 0) {
35818
+ const destDir2 = resolve22(name2);
35819
+ if (existsSync35(destDir2) && readdirSync12(destDir2).length > 0) {
35609
35820
  console.error(c.error(`Directory already exists and is not empty: ${name2}`));
35610
35821
  process.exit(1);
35611
35822
  }
@@ -35618,8 +35829,8 @@ var init_init = __esm({
35618
35829
  process.exit(1);
35619
35830
  }
35620
35831
  if (videoFlag) {
35621
- const videoPath = resolve21(videoFlag);
35622
- if (!existsSync33(videoPath)) {
35832
+ const videoPath = resolve22(videoFlag);
35833
+ if (!existsSync35(videoPath)) {
35623
35834
  console.error(c.error(`Video file not found: ${videoFlag}`));
35624
35835
  process.exit(1);
35625
35836
  }
@@ -35632,13 +35843,13 @@ var init_init = __esm({
35632
35843
  );
35633
35844
  }
35634
35845
  if (audioFlag) {
35635
- const audioPath = resolve21(audioFlag);
35636
- if (!existsSync33(audioPath)) {
35846
+ const audioPath = resolve22(audioFlag);
35847
+ if (!existsSync35(audioPath)) {
35637
35848
  console.error(c.error(`Audio file not found: ${audioFlag}`));
35638
35849
  process.exit(1);
35639
35850
  }
35640
35851
  sourceFilePath2 = audioPath;
35641
- copyFileSync3(audioPath, resolve21(destDir2, basename4(audioPath)));
35852
+ copyFileSync3(audioPath, resolve22(destDir2, basename4(audioPath)));
35642
35853
  console.log(`Audio: ${basename4(audioPath)}`);
35643
35854
  }
35644
35855
  if (sourceFilePath2 && !skipTranscribe) {
@@ -35678,8 +35889,8 @@ var init_init = __esm({
35678
35889
  process.exit(1);
35679
35890
  }
35680
35891
  trackInitTemplate(templateId2);
35681
- const transcriptFile2 = resolve21(destDir2, "transcript.json");
35682
- if (existsSync33(transcriptFile2)) {
35892
+ const transcriptFile2 = resolve22(destDir2, "transcript.json");
35893
+ if (existsSync35(transcriptFile2)) {
35683
35894
  await patchTranscript(destDir2, transcriptFile2);
35684
35895
  }
35685
35896
  console.log(c.success(`Created ${c.accent(name2 + "/")}`));
@@ -35730,8 +35941,8 @@ var init_init = __esm({
35730
35941
  }
35731
35942
  name = nameResult;
35732
35943
  }
35733
- const destDir = resolve21(name);
35734
- if (existsSync33(destDir) && readdirSync12(destDir).length > 0) {
35944
+ const destDir = resolve22(name);
35945
+ if (existsSync35(destDir) && readdirSync12(destDir).length > 0) {
35735
35946
  const overwrite = await Rt({
35736
35947
  message: `Directory ${c.accent(name)} already exists and is not empty. Overwrite?`,
35737
35948
  initialValue: false
@@ -35745,8 +35956,8 @@ var init_init = __esm({
35745
35956
  let sourceFilePath;
35746
35957
  let videoDuration;
35747
35958
  if (videoFlag) {
35748
- const videoPath = resolve21(videoFlag);
35749
- if (!existsSync33(videoPath)) {
35959
+ const videoPath = resolve22(videoFlag);
35960
+ if (!existsSync35(videoPath)) {
35750
35961
  R2.error(`File not found: ${videoFlag}`);
35751
35962
  Nt("Setup cancelled.");
35752
35963
  process.exit(1);
@@ -35757,15 +35968,15 @@ var init_init = __esm({
35757
35968
  localVideoName = result.localVideoName;
35758
35969
  videoDuration = result.meta.durationSeconds;
35759
35970
  } else if (audioFlag) {
35760
- const audioPath = resolve21(audioFlag);
35761
- if (!existsSync33(audioPath)) {
35971
+ const audioPath = resolve22(audioFlag);
35972
+ if (!existsSync35(audioPath)) {
35762
35973
  R2.error(`File not found: ${audioFlag}`);
35763
35974
  Nt("Setup cancelled.");
35764
35975
  process.exit(1);
35765
35976
  }
35766
35977
  mkdirSync20(destDir, { recursive: true });
35767
35978
  sourceFilePath = audioPath;
35768
- copyFileSync3(audioPath, resolve21(destDir, basename4(audioPath)));
35979
+ copyFileSync3(audioPath, resolve22(destDir, basename4(audioPath)));
35769
35980
  R2.info(`Audio copied to ${c.accent(basename4(audioPath))}`);
35770
35981
  }
35771
35982
  if (sourceFilePath) {
@@ -35850,8 +36061,8 @@ ${c.dim("Use --example blank for offline use.")}`
35850
36061
  process.exit(1);
35851
36062
  }
35852
36063
  trackInitTemplate(templateId);
35853
- const transcriptFile = resolve21(destDir, "transcript.json");
35854
- if (existsSync33(transcriptFile)) {
36064
+ const transcriptFile = resolve22(destDir, "transcript.json");
36065
+ if (existsSync35(transcriptFile)) {
35855
36066
  await patchTranscript(destDir, transcriptFile);
35856
36067
  }
35857
36068
  const files = readdirSync12(destDir);
@@ -35937,8 +36148,8 @@ __export(add_exports, {
35937
36148
  remapTarget: () => remapTarget,
35938
36149
  runAdd: () => runAdd
35939
36150
  });
35940
- import { existsSync as existsSync34 } from "fs";
35941
- import { resolve as resolve22, relative as relative3 } from "path";
36151
+ import { existsSync as existsSync36 } from "fs";
36152
+ import { resolve as resolve23, relative as relative3 } from "path";
35942
36153
  function remapTarget(item, originalTarget, paths) {
35943
36154
  if (item.type === "hyperframes:block") {
35944
36155
  const blocksDir = paths.blocks.replace(/\/+$/, "");
@@ -35961,10 +36172,10 @@ function buildSnippet(item, relativeTarget) {
35961
36172
  return "";
35962
36173
  }
35963
36174
  async function runAdd(opts) {
35964
- const projectDir = resolve22(opts.projectDir);
36175
+ const projectDir = resolve23(opts.projectDir);
35965
36176
  let config = loadProjectConfig(projectDir);
35966
- const hasConfig = existsSync34(projectConfigPath(projectDir));
35967
- if (!hasConfig && existsSync34(resolve22(projectDir, "index.html"))) {
36177
+ const hasConfig = existsSync36(projectConfigPath(projectDir));
36178
+ if (!hasConfig && existsSync36(resolve23(projectDir, "index.html"))) {
35968
36179
  writeProjectConfig(projectDir, DEFAULT_PROJECT_CONFIG);
35969
36180
  config = DEFAULT_PROJECT_CONFIG;
35970
36181
  }
@@ -36060,13 +36271,13 @@ var init_add = __esm({
36060
36271
  }
36061
36272
  },
36062
36273
  async run({ args }) {
36063
- const projectDir = resolve22(args.dir ?? process.cwd());
36274
+ const projectDir = resolve23(args.dir ?? process.cwd());
36064
36275
  const json = args.json === true;
36065
36276
  const skipClipboard = args["no-clipboard"] === true;
36066
- const hasConfigBefore = existsSync34(projectConfigPath(projectDir));
36277
+ const hasConfigBefore = existsSync36(projectConfigPath(projectDir));
36067
36278
  try {
36068
36279
  const result = await runAdd({ name: args.name, projectDir, skipClipboard });
36069
- const wroteConfig = !hasConfigBefore && existsSync34(projectConfigPath(projectDir));
36280
+ const wroteConfig = !hasConfigBefore && existsSync36(projectConfigPath(projectDir));
36070
36281
  if (json) {
36071
36282
  console.log(JSON.stringify(result));
36072
36283
  return;
@@ -36108,7 +36319,7 @@ __export(catalog_exports, {
36108
36319
  default: () => catalog_default,
36109
36320
  examples: () => examples4
36110
36321
  });
36111
- import { resolve as resolve23 } from "path";
36322
+ import { resolve as resolve24 } from "path";
36112
36323
  var examples4, catalog_default;
36113
36324
  var init_catalog = __esm({
36114
36325
  "src/commands/catalog.ts"() {
@@ -36152,7 +36363,7 @@ var init_catalog = __esm({
36152
36363
  async run({ args }) {
36153
36364
  const json = args.json === true;
36154
36365
  const interactive = args["human-friendly"] === true;
36155
- const dir = resolve23(process.cwd());
36366
+ const dir = resolve24(process.cwd());
36156
36367
  const config = loadProjectConfig(dir) ?? DEFAULT_PROJECT_CONFIG;
36157
36368
  let typeFilter;
36158
36369
  if (args.type === "block") typeFilter = "hyperframes:block";
@@ -36276,17 +36487,17 @@ var init_format = __esm({
36276
36487
  });
36277
36488
 
36278
36489
  // src/utils/project.ts
36279
- import { existsSync as existsSync35, statSync as statSync11 } from "fs";
36280
- import { resolve as resolve24, basename as basename5 } from "path";
36490
+ import { existsSync as existsSync37, statSync as statSync11 } from "fs";
36491
+ import { resolve as resolve25, basename as basename5 } from "path";
36281
36492
  function resolveProject(dirArg) {
36282
- const dir = resolve24(dirArg ?? ".");
36493
+ const dir = resolve25(dirArg ?? ".");
36283
36494
  const name = basename5(dir);
36284
- const indexPath = resolve24(dir, "index.html");
36285
- if (!existsSync35(dir) || !statSync11(dir).isDirectory()) {
36495
+ const indexPath = resolve25(dir, "index.html");
36496
+ if (!existsSync37(dir) || !statSync11(dir).isDirectory()) {
36286
36497
  errorBox("Not a directory: " + dir);
36287
36498
  process.exit(1);
36288
36499
  }
36289
- if (!existsSync35(indexPath)) {
36500
+ if (!existsSync37(indexPath)) {
36290
36501
  errorBox(
36291
36502
  "No composition found in " + dir,
36292
36503
  "No index.html file found.",
@@ -36309,22 +36520,22 @@ __export(play_exports, {
36309
36520
  default: () => play_default,
36310
36521
  examples: () => examples5
36311
36522
  });
36312
- import { existsSync as existsSync36, readFileSync as readFileSync25 } from "fs";
36313
- import { resolve as resolve25, dirname as dirname14 } from "path";
36523
+ import { existsSync as existsSync38, readFileSync as readFileSync26 } from "fs";
36524
+ import { resolve as resolve26, dirname as dirname15 } from "path";
36314
36525
  function commandDir() {
36315
- return dirname14(new URL(import.meta.url).pathname);
36526
+ return dirname15(new URL(import.meta.url).pathname);
36316
36527
  }
36317
36528
  function resolveRuntimePath2() {
36318
36529
  const d = commandDir();
36319
36530
  const candidates = [
36320
36531
  // Bundled with CLI dist
36321
- resolve25(d, "hyperframe-runtime.js"),
36322
- resolve25(d, "..", "hyperframe-runtime.js"),
36532
+ resolve26(d, "hyperframe-runtime.js"),
36533
+ resolve26(d, "..", "hyperframe-runtime.js"),
36323
36534
  // Monorepo dev: commands/ → src/ → cli/ → packages/ then into core/dist/
36324
- resolve25(d, "..", "..", "..", "core", "dist", "hyperframe.runtime.iife.js")
36535
+ resolve26(d, "..", "..", "..", "core", "dist", "hyperframe.runtime.iife.js")
36325
36536
  ];
36326
36537
  for (const p of candidates) {
36327
- if (existsSync36(p)) return p;
36538
+ if (existsSync38(p)) return p;
36328
36539
  }
36329
36540
  return null;
36330
36541
  }
@@ -36332,13 +36543,13 @@ function resolvePlayerPath() {
36332
36543
  const d = commandDir();
36333
36544
  const candidates = [
36334
36545
  // Monorepo dev: commands/ → src/ → cli/ → packages/ then into player/dist/
36335
- resolve25(d, "..", "..", "..", "player", "dist", "hyperframes-player.global.js"),
36546
+ resolve26(d, "..", "..", "..", "player", "dist", "hyperframes-player.global.js"),
36336
36547
  // Bundled with CLI dist
36337
- resolve25(d, "hyperframes-player.global.js"),
36338
- resolve25(d, "..", "hyperframes-player.global.js")
36548
+ resolve26(d, "hyperframes-player.global.js"),
36549
+ resolve26(d, "..", "hyperframes-player.global.js")
36339
36550
  ];
36340
36551
  for (const p of candidates) {
36341
- if (existsSync36(p)) return p;
36552
+ if (existsSync38(p)) return p;
36342
36553
  }
36343
36554
  return null;
36344
36555
  }
@@ -36425,23 +36636,23 @@ var init_play = __esm({
36425
36636
  const { createAdaptorServer } = await import("@hono/node-server");
36426
36637
  const app = new Hono6();
36427
36638
  app.get("/player.js", (ctx) => {
36428
- return ctx.body(readFileSync25(playerPath, "utf-8"), 200, {
36639
+ return ctx.body(readFileSync26(playerPath, "utf-8"), 200, {
36429
36640
  "Content-Type": "application/javascript",
36430
36641
  "Cache-Control": "no-cache"
36431
36642
  });
36432
36643
  });
36433
36644
  app.get("/runtime.js", (ctx) => {
36434
- return ctx.body(readFileSync25(runtimePath, "utf-8"), 200, {
36645
+ return ctx.body(readFileSync26(runtimePath, "utf-8"), 200, {
36435
36646
  "Content-Type": "application/javascript",
36436
36647
  "Cache-Control": "no-cache"
36437
36648
  });
36438
36649
  });
36439
36650
  app.get("/composition/*", async (ctx) => {
36440
36651
  const reqPath = ctx.req.path.replace("/composition/", "");
36441
- const filePath = resolve25(project.dir, reqPath);
36652
+ const filePath = resolve26(project.dir, reqPath);
36442
36653
  if (!filePath.startsWith(project.dir)) return ctx.text("Forbidden", 403);
36443
- if (!existsSync36(filePath)) return ctx.text("Not found", 404);
36444
- const content = readFileSync25(filePath, "utf-8");
36654
+ if (!existsSync38(filePath)) return ctx.text("Not found", 404);
36655
+ const content = readFileSync26(filePath, "utf-8");
36445
36656
  if (filePath.endsWith(".html")) {
36446
36657
  const injected = injectRuntime(content);
36447
36658
  return ctx.html(injected);
@@ -36460,7 +36671,7 @@ var init_play = __esm({
36460
36671
  mp3: "audio/mpeg",
36461
36672
  wav: "audio/wav"
36462
36673
  };
36463
- return ctx.body(readFileSync25(filePath), 200, {
36674
+ return ctx.body(readFileSync26(filePath), 200, {
36464
36675
  "Content-Type": types3[ext] ?? "application/octet-stream"
36465
36676
  });
36466
36677
  });
@@ -36517,7 +36728,7 @@ var init_play = __esm({
36517
36728
 
36518
36729
  // src/utils/publishProject.ts
36519
36730
  import { basename as basename6, join as join37, relative as relative4 } from "path";
36520
- import { readdirSync as readdirSync13, readFileSync as readFileSync26, statSync as statSync12 } from "fs";
36731
+ import { readdirSync as readdirSync13, readFileSync as readFileSync27, statSync as statSync12 } from "fs";
36521
36732
  import AdmZip from "adm-zip";
36522
36733
  function shouldIgnoreSegment(segment) {
36523
36734
  return segment.startsWith(".") || IGNORED_DIRS.has(segment) || IGNORED_FILES.has(segment);
@@ -36544,7 +36755,7 @@ function createPublishArchive(projectDir) {
36544
36755
  }
36545
36756
  const archive = new AdmZip();
36546
36757
  for (const filePath of filePaths) {
36547
- archive.addFile(filePath, readFileSync26(join37(projectDir, filePath)));
36758
+ archive.addFile(filePath, readFileSync27(join37(projectDir, filePath)));
36548
36759
  }
36549
36760
  return {
36550
36761
  buffer: archive.toBuffer(),
@@ -36599,8 +36810,8 @@ __export(publish_exports, {
36599
36810
  default: () => publish_default,
36600
36811
  examples: () => examples6
36601
36812
  });
36602
- import { basename as basename7, resolve as resolve26 } from "path";
36603
- import { existsSync as existsSync37 } from "fs";
36813
+ import { basename as basename7, resolve as resolve27 } from "path";
36814
+ import { existsSync as existsSync39 } from "fs";
36604
36815
  import { join as join38 } from "path";
36605
36816
  var examples6, publish_default;
36606
36817
  var init_publish = __esm({
@@ -36633,11 +36844,11 @@ var init_publish = __esm({
36633
36844
  },
36634
36845
  async run({ args }) {
36635
36846
  const rawArg = args.dir;
36636
- const dir = resolve26(rawArg ?? ".");
36847
+ const dir = resolve27(rawArg ?? ".");
36637
36848
  const isImplicitCwd = !rawArg || rawArg === "." || rawArg === "./";
36638
36849
  const projectName = isImplicitCwd ? basename7(process.env["PWD"] ?? dir) : basename7(dir);
36639
36850
  const indexPath = join38(dir, "index.html");
36640
- if (existsSync37(indexPath)) {
36851
+ if (existsSync39(indexPath)) {
36641
36852
  const lintResult = lintProject({ dir, name: projectName, indexPath });
36642
36853
  if (lintResult.totalErrors > 0 || lintResult.totalWarnings > 0) {
36643
36854
  console.log();
@@ -36808,9 +37019,9 @@ __export(render_exports, {
36808
37019
  default: () => render_default,
36809
37020
  examples: () => examples7
36810
37021
  });
36811
- import { mkdirSync as mkdirSync21, readFileSync as readFileSync27, statSync as statSync13, writeFileSync as writeFileSync14, rmSync as rmSync8 } from "fs";
37022
+ import { mkdirSync as mkdirSync21, readFileSync as readFileSync28, statSync as statSync13, writeFileSync as writeFileSync14, rmSync as rmSync8 } from "fs";
36812
37023
  import { cpus as cpus3, freemem as freemem3, tmpdir as tmpdir3 } from "os";
36813
- import { resolve as resolve27, dirname as dirname15, join as join39, basename as basename8 } from "path";
37024
+ import { resolve as resolve28, dirname as dirname16, join as join39, basename as basename8 } from "path";
36814
37025
  import { execFileSync as execFileSync5, spawn as spawn10 } from "child_process";
36815
37026
  function defaultWorkerCount() {
36816
37027
  return Math.max(1, Math.min(Math.floor(CPU_CORE_COUNT * 3 / 4), 8));
@@ -36819,8 +37030,8 @@ function dockerImageTag(version) {
36819
37030
  return `${DOCKER_IMAGE_PREFIX}:${version}`;
36820
37031
  }
36821
37032
  function resolveDockerfilePath() {
36822
- const builtPath = resolve27(__dirname, "docker", "Dockerfile.render");
36823
- const devPath = resolve27(__dirname, "..", "src", "docker", "Dockerfile.render");
37033
+ const builtPath = resolve28(__dirname, "docker", "Dockerfile.render");
37034
+ const devPath = resolve28(__dirname, "..", "src", "docker", "Dockerfile.render");
36824
37035
  for (const p of [builtPath, devPath]) {
36825
37036
  try {
36826
37037
  statSync13(p);
@@ -36849,7 +37060,7 @@ function ensureDockerImage(version, quiet) {
36849
37060
  const dockerfilePath = resolveDockerfilePath();
36850
37061
  const tmpDir = join39(tmpdir3(), `hyperframes-docker-${Date.now()}`);
36851
37062
  mkdirSync21(tmpDir, { recursive: true });
36852
- writeFileSync14(join39(tmpDir, "Dockerfile"), readFileSync27(dockerfilePath));
37063
+ writeFileSync14(join39(tmpDir, "Dockerfile"), readFileSync28(dockerfilePath));
36853
37064
  try {
36854
37065
  execFileSync5(
36855
37066
  "docker",
@@ -36893,12 +37104,12 @@ async function renderDocker(projectDir, outputPath, options) {
36893
37104
  );
36894
37105
  process.exit(1);
36895
37106
  }
36896
- const outputDir = dirname15(outputPath);
37107
+ const outputDir = dirname16(outputPath);
36897
37108
  const outputFilename = basename8(outputPath);
36898
37109
  const dockerArgs = buildDockerRunArgs({
36899
37110
  imageTag,
36900
- projectDir: resolve27(projectDir),
36901
- outputDir: resolve27(outputDir),
37111
+ projectDir: resolve28(projectDir),
37112
+ outputDir: resolve28(outputDir),
36902
37113
  outputFilename,
36903
37114
  options: {
36904
37115
  fps: options.fps,
@@ -37173,13 +37384,13 @@ var init_render2 = __esm({
37173
37384
  }
37174
37385
  process.env.PRODUCER_MAX_CONCURRENT_RENDERS = String(parsed);
37175
37386
  }
37176
- const rendersDir = resolve27("renders");
37387
+ const rendersDir = resolve28("renders");
37177
37388
  const ext = FORMAT_EXT[format] ?? ".mp4";
37178
37389
  const now = /* @__PURE__ */ new Date();
37179
37390
  const datePart = now.toISOString().slice(0, 10);
37180
37391
  const timePart = now.toTimeString().slice(0, 8).replace(/:/g, "-");
37181
- const outputPath = args.output ? resolve27(args.output) : join39(rendersDir, `${project.name}_${datePart}_${timePart}${ext}`);
37182
- mkdirSync21(dirname15(outputPath), { recursive: true });
37392
+ const outputPath = args.output ? resolve28(args.output) : join39(rendersDir, `${project.name}_${datePart}_${timePart}${ext}`);
37393
+ mkdirSync21(dirname16(outputPath), { recursive: true });
37183
37394
  const useDocker = args.docker ?? false;
37184
37395
  const useGpu = args.gpu ?? false;
37185
37396
  const quiet = args.quiet ?? false;
@@ -37526,7 +37737,7 @@ __export(info_exports, {
37526
37737
  default: () => info_default,
37527
37738
  examples: () => examples9
37528
37739
  });
37529
- import { readFileSync as readFileSync28, readdirSync as readdirSync14, statSync as statSync14 } from "fs";
37740
+ import { readFileSync as readFileSync29, readdirSync as readdirSync14, statSync as statSync14 } from "fs";
37530
37741
  import { join as join40 } from "path";
37531
37742
  function totalSize(dir) {
37532
37743
  let total = 0;
@@ -37563,7 +37774,7 @@ var init_info = __esm({
37563
37774
  },
37564
37775
  async run({ args }) {
37565
37776
  const project = resolveProject(args.dir);
37566
- const html = readFileSync28(project.indexPath, "utf-8");
37777
+ const html = readFileSync29(project.indexPath, "utf-8");
37567
37778
  ensureDOMParser();
37568
37779
  const parsed = parseHtml(html);
37569
37780
  const tracks = new Set(parsed.elements.map((el) => el.zIndex));
@@ -37619,8 +37830,8 @@ __export(compositions_exports, {
37619
37830
  default: () => compositions_default,
37620
37831
  examples: () => examples10
37621
37832
  });
37622
- import { existsSync as existsSync38, readFileSync as readFileSync29 } from "fs";
37623
- import { resolve as resolve28, dirname as dirname16 } from "path";
37833
+ import { existsSync as existsSync40, readFileSync as readFileSync30 } from "fs";
37834
+ import { resolve as resolve29, dirname as dirname17 } from "path";
37624
37835
  function parseCompositions(html, baseDir) {
37625
37836
  const parser = new DOMParser();
37626
37837
  const doc = parser.parseFromString(html, "text/html");
@@ -37632,9 +37843,9 @@ function parseCompositions(html, baseDir) {
37632
37843
  const height = parseInt(div.getAttribute("data-height") ?? "1080", 10);
37633
37844
  const compositionSrc = div.getAttribute("data-composition-src");
37634
37845
  if (compositionSrc) {
37635
- const subPath = resolve28(baseDir, compositionSrc);
37636
- if (existsSync38(subPath)) {
37637
- const subHtml = readFileSync29(subPath, "utf-8");
37846
+ const subPath = resolve29(baseDir, compositionSrc);
37847
+ if (existsSync40(subPath)) {
37848
+ const subHtml = readFileSync30(subPath, "utf-8");
37638
37849
  const subInfo = parseSubComposition(subHtml, id, width, height);
37639
37850
  compositions.push({ ...subInfo, source: compositionSrc });
37640
37851
  return;
@@ -37728,9 +37939,9 @@ var init_compositions = __esm({
37728
37939
  },
37729
37940
  async run({ args }) {
37730
37941
  const project = resolveProject(args.dir);
37731
- const html = readFileSync29(project.indexPath, "utf-8");
37942
+ const html = readFileSync30(project.indexPath, "utf-8");
37732
37943
  ensureDOMParser();
37733
- const compositions = parseCompositions(html, dirname16(project.indexPath));
37944
+ const compositions = parseCompositions(html, dirname17(project.indexPath));
37734
37945
  if (compositions.length === 0) {
37735
37946
  console.log(`${c.success("\u25C7")} ${c.accent(project.name)} \u2014 no compositions found`);
37736
37947
  return;
@@ -37766,8 +37977,8 @@ __export(benchmark_exports, {
37766
37977
  default: () => benchmark_default,
37767
37978
  examples: () => examples11
37768
37979
  });
37769
- import { existsSync as existsSync39, statSync as statSync15 } from "fs";
37770
- import { resolve as resolve29, join as join41 } from "path";
37980
+ import { existsSync as existsSync41, statSync as statSync15 } from "fs";
37981
+ import { resolve as resolve30, join as join41 } from "path";
37771
37982
  var examples11, DEFAULT_CONFIGS, benchmark_default;
37772
37983
  var init_benchmark = __esm({
37773
37984
  "src/commands/benchmark.ts"() {
@@ -37809,7 +38020,7 @@ var init_benchmark = __esm({
37809
38020
  process.exit(1);
37810
38021
  }
37811
38022
  const jsonOutput = args.json ?? false;
37812
- const benchDir = resolve29("renders", ".benchmark");
38023
+ const benchDir = resolve30("renders", ".benchmark");
37813
38024
  let producer = null;
37814
38025
  try {
37815
38026
  producer = await loadProducer();
@@ -37856,7 +38067,7 @@ var init_benchmark = __esm({
37856
38067
  await producer.executeRenderJob(job, project.dir, outputPath);
37857
38068
  const elapsedMs = Date.now() - startTime;
37858
38069
  let fileSize = null;
37859
- if (existsSync39(outputPath)) {
38070
+ if (existsSync41(outputPath)) {
37860
38071
  const stat3 = statSync15(outputPath);
37861
38072
  fileSize = stat3.size;
37862
38073
  }
@@ -38072,8 +38283,8 @@ __export(transcribe_exports2, {
38072
38283
  default: () => transcribe_default,
38073
38284
  examples: () => examples13
38074
38285
  });
38075
- import { existsSync as existsSync40, writeFileSync as writeFileSync15 } from "fs";
38076
- import { resolve as resolve30, join as join42, extname as extname8 } from "path";
38286
+ import { existsSync as existsSync42, writeFileSync as writeFileSync15 } from "fs";
38287
+ import { resolve as resolve31, join as join42, extname as extname8 } from "path";
38077
38288
  async function importTranscript(inputPath, dir, json) {
38078
38289
  const { loadTranscript: loadTranscript2, patchCaptionHtml: patchCaptionHtml2 } = await Promise.resolve().then(() => (init_normalize(), normalize_exports));
38079
38290
  const { words, format } = loadTranscript2(inputPath);
@@ -38197,12 +38408,12 @@ var init_transcribe2 = __esm({
38197
38408
  }
38198
38409
  },
38199
38410
  async run({ args }) {
38200
- const inputPath = resolve30(args.input);
38201
- if (!existsSync40(inputPath)) {
38411
+ const inputPath = resolve31(args.input);
38412
+ if (!existsSync42(inputPath)) {
38202
38413
  console.error(c.error(`File not found: ${args.input}`));
38203
38414
  process.exit(1);
38204
38415
  }
38205
- const dir = resolve30(args.dir ?? ".");
38416
+ const dir = resolve31(args.dir ?? ".");
38206
38417
  const ext = extname8(inputPath).toLowerCase();
38207
38418
  const isImport = ext === ".json" || ext === ".srt" || ext === ".vtt";
38208
38419
  if (isImport) {
@@ -38219,7 +38430,7 @@ var init_transcribe2 = __esm({
38219
38430
  });
38220
38431
 
38221
38432
  // src/tts/manager.ts
38222
- import { existsSync as existsSync41, mkdirSync as mkdirSync22 } from "fs";
38433
+ import { existsSync as existsSync43, mkdirSync as mkdirSync22 } from "fs";
38223
38434
  import { homedir as homedir8 } from "os";
38224
38435
  import { join as join43 } from "path";
38225
38436
  function inferLangFromVoiceId(voiceId) {
@@ -38231,7 +38442,7 @@ function isSupportedLang(value) {
38231
38442
  }
38232
38443
  async function ensureModel2(model = DEFAULT_MODEL2, options) {
38233
38444
  const modelPath = join43(MODELS_DIR2, `${model}.onnx`);
38234
- if (existsSync41(modelPath)) return modelPath;
38445
+ if (existsSync43(modelPath)) return modelPath;
38235
38446
  const url = MODEL_URLS[model];
38236
38447
  if (!url) {
38237
38448
  throw new Error(
@@ -38241,18 +38452,18 @@ async function ensureModel2(model = DEFAULT_MODEL2, options) {
38241
38452
  mkdirSync22(MODELS_DIR2, { recursive: true });
38242
38453
  options?.onProgress?.(`Downloading TTS model ${model} (~311 MB)...`);
38243
38454
  await downloadFile(url, modelPath);
38244
- if (!existsSync41(modelPath)) {
38455
+ if (!existsSync43(modelPath)) {
38245
38456
  throw new Error(`Model download failed: ${model}`);
38246
38457
  }
38247
38458
  return modelPath;
38248
38459
  }
38249
38460
  async function ensureVoices(options) {
38250
38461
  const voicesPath = join43(VOICES_DIR, "voices-v1.0.bin");
38251
- if (existsSync41(voicesPath)) return voicesPath;
38462
+ if (existsSync43(voicesPath)) return voicesPath;
38252
38463
  mkdirSync22(VOICES_DIR, { recursive: true });
38253
38464
  options?.onProgress?.("Downloading voice data (~27 MB)...");
38254
38465
  await downloadFile(VOICES_URL, voicesPath);
38255
- if (!existsSync41(voicesPath)) {
38466
+ if (!existsSync43(voicesPath)) {
38256
38467
  throw new Error("Voice data download failed");
38257
38468
  }
38258
38469
  return voicesPath;
@@ -38325,8 +38536,8 @@ __export(synthesize_exports, {
38325
38536
  synthesize: () => synthesize
38326
38537
  });
38327
38538
  import { execFileSync as execFileSync6 } from "child_process";
38328
- import { existsSync as existsSync42, writeFileSync as writeFileSync16, mkdirSync as mkdirSync23, readdirSync as readdirSync15, unlinkSync as unlinkSync6 } from "fs";
38329
- import { join as join44, dirname as dirname17, basename as basename9 } from "path";
38539
+ import { existsSync as existsSync44, writeFileSync as writeFileSync16, mkdirSync as mkdirSync23, readdirSync as readdirSync15, unlinkSync as unlinkSync6 } from "fs";
38540
+ import { join as join44, dirname as dirname18, basename as basename9 } from "path";
38330
38541
  import { homedir as homedir9 } from "os";
38331
38542
  function findPython() {
38332
38543
  for (const name of ["python3", "python"]) {
@@ -38362,7 +38573,7 @@ function hasPythonPackage(python, pkg) {
38362
38573
  }
38363
38574
  }
38364
38575
  function ensureSynthScript() {
38365
- if (!existsSync42(SCRIPT_PATH)) {
38576
+ if (!existsSync44(SCRIPT_PATH)) {
38366
38577
  mkdirSync23(SCRIPT_DIR, { recursive: true });
38367
38578
  writeFileSync16(SCRIPT_PATH, SYNTH_SCRIPT);
38368
38579
  const currentName = basename9(SCRIPT_PATH);
@@ -38404,7 +38615,7 @@ async function synthesize(text, outputPath, options) {
38404
38615
  ensureVoices({ onProgress: options?.onProgress })
38405
38616
  ]);
38406
38617
  const scriptPath = ensureSynthScript();
38407
- mkdirSync23(dirname17(outputPath), { recursive: true });
38618
+ mkdirSync23(dirname18(outputPath), { recursive: true });
38408
38619
  options?.onProgress?.(`Generating speech with voice ${voice} (${lang})...`);
38409
38620
  try {
38410
38621
  const stdout2 = execFileSync6(
@@ -38416,7 +38627,7 @@ async function synthesize(text, outputPath, options) {
38416
38627
  stdio: ["pipe", "pipe", "pipe"]
38417
38628
  }
38418
38629
  );
38419
- if (!existsSync42(outputPath)) {
38630
+ if (!existsSync44(outputPath)) {
38420
38631
  throw new Error("Synthesis completed but no output file was created");
38421
38632
  }
38422
38633
  const lines = stdout2.trim().split("\n");
@@ -38429,7 +38640,7 @@ async function synthesize(text, outputPath, options) {
38429
38640
  langApplied: result.langApplied
38430
38641
  };
38431
38642
  } catch (err) {
38432
- if (err instanceof SyntaxError && existsSync42(outputPath)) {
38643
+ if (err instanceof SyntaxError && existsSync44(outputPath)) {
38433
38644
  throw new Error(
38434
38645
  "Speech was generated but metadata could not be read. Check the output file manually."
38435
38646
  );
@@ -38491,8 +38702,8 @@ __export(tts_exports, {
38491
38702
  default: () => tts_default,
38492
38703
  examples: () => examples14
38493
38704
  });
38494
- import { existsSync as existsSync43, readFileSync as readFileSync30 } from "fs";
38495
- import { resolve as resolve31, extname as extname9 } from "path";
38705
+ import { existsSync as existsSync45, readFileSync as readFileSync31 } from "fs";
38706
+ import { resolve as resolve32, extname as extname9 } from "path";
38496
38707
  function listVoices(json) {
38497
38708
  const rows = BUNDLED_VOICES.map((v) => ({ ...v, defaultLang: inferLangFromVoiceId(v.id) }));
38498
38709
  if (json) {
@@ -38600,9 +38811,9 @@ var init_tts = __esm({
38600
38811
  process.exit(1);
38601
38812
  }
38602
38813
  let text;
38603
- const maybeFile = resolve31(args.input);
38604
- if (existsSync43(maybeFile) && extname9(maybeFile).toLowerCase() === ".txt") {
38605
- text = readFileSync30(maybeFile, "utf-8").trim();
38814
+ const maybeFile = resolve32(args.input);
38815
+ if (existsSync45(maybeFile) && extname9(maybeFile).toLowerCase() === ".txt") {
38816
+ text = readFileSync31(maybeFile, "utf-8").trim();
38606
38817
  if (!text) {
38607
38818
  console.error(c.error("File is empty."));
38608
38819
  process.exit(1);
@@ -38614,7 +38825,7 @@ var init_tts = __esm({
38614
38825
  console.error(c.error("No text provided."));
38615
38826
  process.exit(1);
38616
38827
  }
38617
- const output = resolve31(args.output ?? "speech.wav");
38828
+ const output = resolve32(args.output ?? "speech.wav");
38618
38829
  const voice = args.voice ?? DEFAULT_VOICE;
38619
38830
  const speed = args.speed ? parseFloat(args.speed) : 1;
38620
38831
  if (isNaN(speed) || speed <= 0 || speed > 3) {
@@ -38694,15 +38905,15 @@ __export(docs_exports, {
38694
38905
  default: () => docs_default,
38695
38906
  examples: () => examples15
38696
38907
  });
38697
- import { readFileSync as readFileSync31, existsSync as existsSync44 } from "fs";
38698
- import { resolve as resolve32, dirname as dirname18, join as join45 } from "path";
38908
+ import { readFileSync as readFileSync32, existsSync as existsSync46 } from "fs";
38909
+ import { resolve as resolve33, dirname as dirname19, join as join45 } from "path";
38699
38910
  import { fileURLToPath as fileURLToPath6 } from "url";
38700
38911
  function docsDir() {
38701
38912
  const thisFile = fileURLToPath6(import.meta.url);
38702
- const dir = dirname18(thisFile);
38703
- const devPath = resolve32(dir, "..", "docs");
38704
- const builtPath = resolve32(dir, "docs");
38705
- return existsSync44(devPath) ? devPath : builtPath;
38913
+ const dir = dirname19(thisFile);
38914
+ const devPath = resolve33(dir, "..", "docs");
38915
+ const builtPath = resolve33(dir, "docs");
38916
+ return existsSync46(devPath) ? devPath : builtPath;
38706
38917
  }
38707
38918
  function formatInlineCode(line) {
38708
38919
  return line.replace(/`([^`]+)`/g, (_match, code) => c.accent(code));
@@ -38800,11 +39011,11 @@ var init_docs = __esm({
38800
39011
  process.exit(1);
38801
39012
  }
38802
39013
  const filePath = join45(docsDir(), entry.file);
38803
- if (!existsSync44(filePath)) {
39014
+ if (!existsSync46(filePath)) {
38804
39015
  console.error(c.error(`Doc file not found: ${filePath}`));
38805
39016
  process.exit(1);
38806
39017
  }
38807
- const content = readFileSync31(filePath, "utf-8");
39018
+ const content = readFileSync32(filePath, "utf-8");
38808
39019
  console.log();
38809
39020
  renderMarkdown(content);
38810
39021
  }
@@ -39230,8 +39441,8 @@ var validate_exports = {};
39230
39441
  __export(validate_exports, {
39231
39442
  default: () => validate_default
39232
39443
  });
39233
- import { existsSync as existsSync45, readFileSync as readFileSync32 } from "fs";
39234
- import { resolve as resolve33, join as join46, dirname as dirname19 } from "path";
39444
+ import { existsSync as existsSync47, readFileSync as readFileSync33 } from "fs";
39445
+ import { resolve as resolve34, join as join46, dirname as dirname20 } from "path";
39235
39446
  import { fileURLToPath as fileURLToPath7 } from "url";
39236
39447
  async function getCompositionDuration2(page) {
39237
39448
  return page.evaluate(() => {
@@ -39277,7 +39488,7 @@ async function validateInBrowser(projectDir, opts) {
39277
39488
  const { bundleToSingleHtml: bundleToSingleHtml2 } = await Promise.resolve().then(() => (init_compiler(), compiler_exports));
39278
39489
  const { ensureBrowser: ensureBrowser2 } = await Promise.resolve().then(() => (init_manager2(), manager_exports2));
39279
39490
  let html = await bundleToSingleHtml2(projectDir);
39280
- const runtimePath = resolve33(
39491
+ const runtimePath = resolve34(
39281
39492
  __dirname2,
39282
39493
  "..",
39283
39494
  "..",
@@ -39286,8 +39497,8 @@ async function validateInBrowser(projectDir, opts) {
39286
39497
  "dist",
39287
39498
  "hyperframe.runtime.iife.js"
39288
39499
  );
39289
- if (existsSync45(runtimePath)) {
39290
- const runtimeSource = readFileSync32(runtimePath, "utf-8");
39500
+ if (existsSync47(runtimePath)) {
39501
+ const runtimeSource = readFileSync33(runtimePath, "utf-8");
39291
39502
  html = html.replace(
39292
39503
  /<script[^>]*data-hyperframes-preview-runtime[^>]*src="[^"]*"[^>]*><\/script>/,
39293
39504
  () => `<script data-hyperframes-preview-runtime="1">${runtimeSource}</script>`
@@ -39303,9 +39514,9 @@ async function validateInBrowser(projectDir, opts) {
39303
39514
  return;
39304
39515
  }
39305
39516
  const filePath = join46(projectDir, decodeURIComponent(url));
39306
- if (existsSync45(filePath)) {
39517
+ if (existsSync47(filePath)) {
39307
39518
  res.writeHead(200, { "Content-Type": getMimeType2(filePath) });
39308
- res.end(readFileSync32(filePath));
39519
+ res.end(readFileSync33(filePath));
39309
39520
  return;
39310
39521
  }
39311
39522
  res.writeHead(404);
@@ -39393,7 +39604,7 @@ var init_validate = __esm({
39393
39604
  init_updateCheck();
39394
39605
  init_contrast_audit_browser();
39395
39606
  __filename = fileURLToPath7(import.meta.url);
39396
- __dirname2 = dirname19(__filename);
39607
+ __dirname2 = dirname20(__filename);
39397
39608
  CONTRAST_SAMPLES = 5;
39398
39609
  SEEK_SETTLE_MS = 150;
39399
39610
  validate_default = defineCommand({
@@ -39496,9 +39707,9 @@ __export(snapshot_exports, {
39496
39707
  examples: () => examples19
39497
39708
  });
39498
39709
  import { spawn as spawn11 } from "child_process";
39499
- import { existsSync as existsSync46, mkdtempSync as mkdtempSync2, readFileSync as readFileSync33, mkdirSync as mkdirSync24, rmSync as rmSync9 } from "fs";
39710
+ import { existsSync as existsSync48, mkdtempSync as mkdtempSync2, readFileSync as readFileSync34, mkdirSync as mkdirSync24, rmSync as rmSync9 } from "fs";
39500
39711
  import { tmpdir as tmpdir4 } from "os";
39501
- import { resolve as resolve34, join as join47, dirname as dirname20, relative as relative5, isAbsolute as isAbsolute4 } from "path";
39712
+ import { resolve as resolve35, join as join47, dirname as dirname21, relative as relative5, isAbsolute as isAbsolute6 } from "path";
39502
39713
  import { fileURLToPath as fileURLToPath8 } from "url";
39503
39714
  async function extractVideoFrameToBuffer(videoPath, timeSeconds) {
39504
39715
  const tmp = mkdtempSync2(join47(tmpdir4(), "hf-snapshot-frame-"));
@@ -39540,8 +39751,8 @@ async function extractVideoFrameToBuffer(videoPath, timeSeconds) {
39540
39751
  });
39541
39752
  }
39542
39753
  );
39543
- if (result.code !== 0 || result.timedOut || !existsSync46(outPath)) return null;
39544
- return readFileSync33(outPath);
39754
+ if (result.code !== 0 || result.timedOut || !existsSync48(outPath)) return null;
39755
+ return readFileSync34(outPath);
39545
39756
  } finally {
39546
39757
  try {
39547
39758
  rmSync9(tmp, { recursive: true, force: true });
@@ -39554,7 +39765,7 @@ async function captureSnapshots(projectDir, opts) {
39554
39765
  const { ensureBrowser: ensureBrowser2 } = await Promise.resolve().then(() => (init_manager2(), manager_exports2));
39555
39766
  const numFrames = opts.frames ?? 5;
39556
39767
  let html = await bundleToSingleHtml2(projectDir);
39557
- const runtimePath = resolve34(
39768
+ const runtimePath = resolve35(
39558
39769
  __dirname3,
39559
39770
  "..",
39560
39771
  "..",
@@ -39563,8 +39774,8 @@ async function captureSnapshots(projectDir, opts) {
39563
39774
  "dist",
39564
39775
  "hyperframe.runtime.iife.js"
39565
39776
  );
39566
- if (existsSync46(runtimePath)) {
39567
- const runtimeSource = readFileSync33(runtimePath, "utf-8");
39777
+ if (existsSync48(runtimePath)) {
39778
+ const runtimeSource = readFileSync34(runtimePath, "utf-8");
39568
39779
  html = html.replace(
39569
39780
  /<script[^>]*data-hyperframes-preview-runtime[^>]*src="[^"]*"[^>]*><\/script>/,
39570
39781
  () => `<script data-hyperframes-preview-runtime="1">${runtimeSource}</script>`
@@ -39579,16 +39790,16 @@ async function captureSnapshots(projectDir, opts) {
39579
39790
  res.end(html);
39580
39791
  return;
39581
39792
  }
39582
- const filePath = resolve34(projectDir, decodeURIComponent(url).replace(/^\//, ""));
39793
+ const filePath = resolve35(projectDir, decodeURIComponent(url).replace(/^\//, ""));
39583
39794
  const rel = relative5(projectDir, filePath);
39584
- if (rel.startsWith("..") || isAbsolute4(rel)) {
39795
+ if (rel.startsWith("..") || isAbsolute6(rel)) {
39585
39796
  res.writeHead(403);
39586
39797
  res.end();
39587
39798
  return;
39588
39799
  }
39589
- if (existsSync46(filePath)) {
39800
+ if (existsSync48(filePath)) {
39590
39801
  res.writeHead(200, { "Content-Type": getMimeType2(filePath) });
39591
- res.end(readFileSync33(filePath));
39802
+ res.end(readFileSync34(filePath));
39592
39803
  return;
39593
39804
  }
39594
39805
  res.writeHead(404);
@@ -39720,9 +39931,9 @@ async function captureSnapshots(projectDir, opts) {
39720
39931
  try {
39721
39932
  const url = new URL(v.src);
39722
39933
  const decodedPath = decodeURIComponent(url.pathname).replace(/^\//, "");
39723
- const candidate = resolve34(projectDir, decodedPath);
39934
+ const candidate = resolve35(projectDir, decodedPath);
39724
39935
  const rel = relative5(projectDir, candidate);
39725
- if (!rel.startsWith("..") && !isAbsolute4(rel) && existsSync46(candidate)) {
39936
+ if (!rel.startsWith("..") && !isAbsolute6(rel) && existsSync48(candidate)) {
39726
39937
  filePath = candidate;
39727
39938
  }
39728
39939
  } catch {
@@ -39768,7 +39979,7 @@ var init_snapshot = __esm({
39768
39979
  init_project();
39769
39980
  init_colors();
39770
39981
  __filename2 = fileURLToPath8(import.meta.url);
39771
- __dirname3 = dirname20(__filename2);
39982
+ __dirname3 = dirname21(__filename2);
39772
39983
  FFMPEG_EXTRACT_TIMEOUT_MS = 3e4;
39773
39984
  examples19 = [
39774
39985
  ["Capture 5 key frames from a composition", "snapshot captures/stripe"],
@@ -40787,7 +40998,7 @@ var init_animationCataloger = __esm({
40787
40998
  });
40788
40999
 
40789
41000
  // src/capture/mediaCapture.ts
40790
- import { mkdirSync as mkdirSync26, writeFileSync as writeFileSync18, readdirSync as readdirSync16, readFileSync as readFileSync34, statSync as statSync16 } from "fs";
41001
+ import { mkdirSync as mkdirSync26, writeFileSync as writeFileSync18, readdirSync as readdirSync16, readFileSync as readFileSync35, statSync as statSync16 } from "fs";
40791
41002
  import { join as join49 } from "path";
40792
41003
  async function saveLottieAnimations(discoveredLotties, lottieDir) {
40793
41004
  let savedCount = 0;
@@ -40854,7 +41065,7 @@ async function renderLottiePreviews(chromeBrowser, lottieDir, outputDir) {
40854
41065
  for (const file of readdirSync16(lottieDir)) {
40855
41066
  if (!file.endsWith(".json")) continue;
40856
41067
  try {
40857
- const raw = JSON.parse(readFileSync34(join49(lottieDir, file), "utf-8"));
41068
+ const raw = JSON.parse(readFileSync35(join49(lottieDir, file), "utf-8"));
40858
41069
  const fr = raw.fr || 30;
40859
41070
  const dur = ((raw.op || 0) - (raw.ip || 0)) / fr;
40860
41071
  const previewName = file.replace(".json", "-preview.png");
@@ -40864,7 +41075,7 @@ async function renderLottiePreviews(chromeBrowser, lottieDir, outputDir) {
40864
41075
  try {
40865
41076
  previewPage = await chromeBrowser.newPage();
40866
41077
  await previewPage.setViewport({ width: 400, height: 400 });
40867
- const animData = JSON.parse(readFileSync34(join49(lottieDir, file), "utf-8"));
41078
+ const animData = JSON.parse(readFileSync35(join49(lottieDir, file), "utf-8"));
40868
41079
  const midFrame = Math.floor(((raw.op || 0) - (raw.ip || 0)) * 0.3);
40869
41080
  await previewPage.setContent(
40870
41081
  `<!DOCTYPE html>
@@ -41309,7 +41520,7 @@ var require_p_retry = __commonJS({
41309
41520
  return error;
41310
41521
  };
41311
41522
  var isNetworkError = (errorMessage) => networkErrorMsgs.includes(errorMessage);
41312
- var pRetry2 = (input, options) => new Promise((resolve37, reject) => {
41523
+ var pRetry2 = (input, options) => new Promise((resolve38, reject) => {
41313
41524
  options = {
41314
41525
  onFailedAttempt: () => {
41315
41526
  },
@@ -41319,7 +41530,7 @@ var require_p_retry = __commonJS({
41319
41530
  const operation = retry.operation(options);
41320
41531
  operation.attempt(async (attemptNumber) => {
41321
41532
  try {
41322
- resolve37(await input(attemptNumber));
41533
+ resolve38(await input(attemptNumber));
41323
41534
  } catch (error) {
41324
41535
  if (!(error instanceof Error)) {
41325
41536
  reject(new TypeError(`Non-error was thrown: "${error}". You should only throw errors.`));
@@ -41855,8 +42066,8 @@ var require_retry3 = __commonJS({
41855
42066
  }
41856
42067
  const delay = getNextRetryDelay(config);
41857
42068
  err.config.retryConfig.currentRetryAttempt += 1;
41858
- const backoff = config.retryBackoff ? config.retryBackoff(err, delay) : new Promise((resolve37) => {
41859
- setTimeout(resolve37, delay);
42069
+ const backoff = config.retryBackoff ? config.retryBackoff(err, delay) : new Promise((resolve38) => {
42070
+ setTimeout(resolve38, delay);
41860
42071
  });
41861
42072
  if (config.onRetryAttempt) {
41862
42073
  await config.onRetryAttempt(err);
@@ -42764,8 +42975,8 @@ var require_helpers = __commonJS({
42764
42975
  function req(url, opts = {}) {
42765
42976
  const href = typeof url === "string" ? url : url.href;
42766
42977
  const req2 = (href.startsWith("https:") ? https2 : http4).request(url, opts);
42767
- const promise = new Promise((resolve37, reject) => {
42768
- req2.once("response", resolve37).once("error", reject).end();
42978
+ const promise = new Promise((resolve38, reject) => {
42979
+ req2.once("response", resolve38).once("error", reject).end();
42769
42980
  });
42770
42981
  req2.then = promise.then.bind(promise);
42771
42982
  return req2;
@@ -42942,7 +43153,7 @@ var require_parse_proxy_response = __commonJS({
42942
43153
  var debug_1 = __importDefault(require_src2());
42943
43154
  var debug = (0, debug_1.default)("https-proxy-agent:parse-proxy-response");
42944
43155
  function parseProxyResponse(socket) {
42945
- return new Promise((resolve37, reject) => {
43156
+ return new Promise((resolve38, reject) => {
42946
43157
  let buffersLength = 0;
42947
43158
  const buffers = [];
42948
43159
  function read() {
@@ -43008,7 +43219,7 @@ var require_parse_proxy_response = __commonJS({
43008
43219
  }
43009
43220
  debug("got proxy server response: %o %o", firstLine, headers);
43010
43221
  cleanup();
43011
- resolve37({
43222
+ resolve38({
43012
43223
  connect: {
43013
43224
  statusCode,
43014
43225
  statusText,
@@ -43252,7 +43463,7 @@ var require_ponyfill_es2018 = __commonJS({
43252
43463
  return new originalPromise(executor);
43253
43464
  }
43254
43465
  function promiseResolvedWith(value) {
43255
- return newPromise((resolve37) => resolve37(value));
43466
+ return newPromise((resolve38) => resolve38(value));
43256
43467
  }
43257
43468
  function promiseRejectedWith(reason) {
43258
43469
  return originalPromiseReject(reason);
@@ -43422,8 +43633,8 @@ var require_ponyfill_es2018 = __commonJS({
43422
43633
  return new TypeError("Cannot " + name + " a stream using a released reader");
43423
43634
  }
43424
43635
  function defaultReaderClosedPromiseInitialize(reader) {
43425
- reader._closedPromise = newPromise((resolve37, reject) => {
43426
- reader._closedPromise_resolve = resolve37;
43636
+ reader._closedPromise = newPromise((resolve38, reject) => {
43637
+ reader._closedPromise_resolve = resolve38;
43427
43638
  reader._closedPromise_reject = reject;
43428
43639
  });
43429
43640
  }
@@ -43597,8 +43808,8 @@ var require_ponyfill_es2018 = __commonJS({
43597
43808
  }
43598
43809
  let resolvePromise;
43599
43810
  let rejectPromise;
43600
- const promise = newPromise((resolve37, reject) => {
43601
- resolvePromise = resolve37;
43811
+ const promise = newPromise((resolve38, reject) => {
43812
+ resolvePromise = resolve38;
43602
43813
  rejectPromise = reject;
43603
43814
  });
43604
43815
  const readRequest = {
@@ -43703,8 +43914,8 @@ var require_ponyfill_es2018 = __commonJS({
43703
43914
  const reader = this._reader;
43704
43915
  let resolvePromise;
43705
43916
  let rejectPromise;
43706
- const promise = newPromise((resolve37, reject) => {
43707
- resolvePromise = resolve37;
43917
+ const promise = newPromise((resolve38, reject) => {
43918
+ resolvePromise = resolve38;
43708
43919
  rejectPromise = reject;
43709
43920
  });
43710
43921
  const readRequest = {
@@ -44723,8 +44934,8 @@ var require_ponyfill_es2018 = __commonJS({
44723
44934
  }
44724
44935
  let resolvePromise;
44725
44936
  let rejectPromise;
44726
- const promise = newPromise((resolve37, reject) => {
44727
- resolvePromise = resolve37;
44937
+ const promise = newPromise((resolve38, reject) => {
44938
+ resolvePromise = resolve38;
44728
44939
  rejectPromise = reject;
44729
44940
  });
44730
44941
  const readIntoRequest = {
@@ -45036,10 +45247,10 @@ var require_ponyfill_es2018 = __commonJS({
45036
45247
  wasAlreadyErroring = true;
45037
45248
  reason = void 0;
45038
45249
  }
45039
- const promise = newPromise((resolve37, reject) => {
45250
+ const promise = newPromise((resolve38, reject) => {
45040
45251
  stream._pendingAbortRequest = {
45041
45252
  _promise: void 0,
45042
- _resolve: resolve37,
45253
+ _resolve: resolve38,
45043
45254
  _reject: reject,
45044
45255
  _reason: reason,
45045
45256
  _wasAlreadyErroring: wasAlreadyErroring
@@ -45056,9 +45267,9 @@ var require_ponyfill_es2018 = __commonJS({
45056
45267
  if (state === "closed" || state === "errored") {
45057
45268
  return promiseRejectedWith(new TypeError(`The stream (in ${state} state) is not in the writable state and cannot be closed`));
45058
45269
  }
45059
- const promise = newPromise((resolve37, reject) => {
45270
+ const promise = newPromise((resolve38, reject) => {
45060
45271
  const closeRequest = {
45061
- _resolve: resolve37,
45272
+ _resolve: resolve38,
45062
45273
  _reject: reject
45063
45274
  };
45064
45275
  stream._closeRequest = closeRequest;
@@ -45071,9 +45282,9 @@ var require_ponyfill_es2018 = __commonJS({
45071
45282
  return promise;
45072
45283
  }
45073
45284
  function WritableStreamAddWriteRequest(stream) {
45074
- const promise = newPromise((resolve37, reject) => {
45285
+ const promise = newPromise((resolve38, reject) => {
45075
45286
  const writeRequest = {
45076
- _resolve: resolve37,
45287
+ _resolve: resolve38,
45077
45288
  _reject: reject
45078
45289
  };
45079
45290
  stream._writeRequests.push(writeRequest);
@@ -45689,8 +45900,8 @@ var require_ponyfill_es2018 = __commonJS({
45689
45900
  return new TypeError("Cannot " + name + " a stream using a released writer");
45690
45901
  }
45691
45902
  function defaultWriterClosedPromiseInitialize(writer) {
45692
- writer._closedPromise = newPromise((resolve37, reject) => {
45693
- writer._closedPromise_resolve = resolve37;
45903
+ writer._closedPromise = newPromise((resolve38, reject) => {
45904
+ writer._closedPromise_resolve = resolve38;
45694
45905
  writer._closedPromise_reject = reject;
45695
45906
  writer._closedPromiseState = "pending";
45696
45907
  });
@@ -45726,8 +45937,8 @@ var require_ponyfill_es2018 = __commonJS({
45726
45937
  writer._closedPromiseState = "resolved";
45727
45938
  }
45728
45939
  function defaultWriterReadyPromiseInitialize(writer) {
45729
- writer._readyPromise = newPromise((resolve37, reject) => {
45730
- writer._readyPromise_resolve = resolve37;
45940
+ writer._readyPromise = newPromise((resolve38, reject) => {
45941
+ writer._readyPromise_resolve = resolve38;
45731
45942
  writer._readyPromise_reject = reject;
45732
45943
  });
45733
45944
  writer._readyPromiseState = "pending";
@@ -45814,7 +46025,7 @@ var require_ponyfill_es2018 = __commonJS({
45814
46025
  source._disturbed = true;
45815
46026
  let shuttingDown = false;
45816
46027
  let currentWrite = promiseResolvedWith(void 0);
45817
- return newPromise((resolve37, reject) => {
46028
+ return newPromise((resolve38, reject) => {
45818
46029
  let abortAlgorithm;
45819
46030
  if (signal !== void 0) {
45820
46031
  abortAlgorithm = () => {
@@ -45959,7 +46170,7 @@ var require_ponyfill_es2018 = __commonJS({
45959
46170
  if (isError) {
45960
46171
  reject(error);
45961
46172
  } else {
45962
- resolve37(void 0);
46173
+ resolve38(void 0);
45963
46174
  }
45964
46175
  return null;
45965
46176
  }
@@ -46240,8 +46451,8 @@ var require_ponyfill_es2018 = __commonJS({
46240
46451
  let branch1;
46241
46452
  let branch2;
46242
46453
  let resolveCancelPromise;
46243
- const cancelPromise = newPromise((resolve37) => {
46244
- resolveCancelPromise = resolve37;
46454
+ const cancelPromise = newPromise((resolve38) => {
46455
+ resolveCancelPromise = resolve38;
46245
46456
  });
46246
46457
  function pullAlgorithm() {
46247
46458
  if (reading) {
@@ -46332,8 +46543,8 @@ var require_ponyfill_es2018 = __commonJS({
46332
46543
  let branch1;
46333
46544
  let branch2;
46334
46545
  let resolveCancelPromise;
46335
- const cancelPromise = newPromise((resolve37) => {
46336
- resolveCancelPromise = resolve37;
46546
+ const cancelPromise = newPromise((resolve38) => {
46547
+ resolveCancelPromise = resolve38;
46337
46548
  });
46338
46549
  function forwardReaderError(thisReader) {
46339
46550
  uponRejection(thisReader._closedPromise, (r2) => {
@@ -47113,8 +47324,8 @@ var require_ponyfill_es2018 = __commonJS({
47113
47324
  const writableHighWaterMark = ExtractHighWaterMark(writableStrategy, 1);
47114
47325
  const writableSizeAlgorithm = ExtractSizeAlgorithm(writableStrategy);
47115
47326
  let startPromise_resolve;
47116
- const startPromise = newPromise((resolve37) => {
47117
- startPromise_resolve = resolve37;
47327
+ const startPromise = newPromise((resolve38) => {
47328
+ startPromise_resolve = resolve38;
47118
47329
  });
47119
47330
  InitializeTransformStream(this, startPromise, writableHighWaterMark, writableSizeAlgorithm, readableHighWaterMark, readableSizeAlgorithm);
47120
47331
  SetUpTransformStreamDefaultControllerFromTransformer(this, transformer);
@@ -47207,8 +47418,8 @@ var require_ponyfill_es2018 = __commonJS({
47207
47418
  if (stream._backpressureChangePromise !== void 0) {
47208
47419
  stream._backpressureChangePromise_resolve();
47209
47420
  }
47210
- stream._backpressureChangePromise = newPromise((resolve37) => {
47211
- stream._backpressureChangePromise_resolve = resolve37;
47421
+ stream._backpressureChangePromise = newPromise((resolve38) => {
47422
+ stream._backpressureChangePromise_resolve = resolve38;
47212
47423
  });
47213
47424
  stream._backpressure = backpressure;
47214
47425
  }
@@ -47376,8 +47587,8 @@ var require_ponyfill_es2018 = __commonJS({
47376
47587
  return controller._finishPromise;
47377
47588
  }
47378
47589
  const readable = stream._readable;
47379
- controller._finishPromise = newPromise((resolve37, reject) => {
47380
- controller._finishPromise_resolve = resolve37;
47590
+ controller._finishPromise = newPromise((resolve38, reject) => {
47591
+ controller._finishPromise_resolve = resolve38;
47381
47592
  controller._finishPromise_reject = reject;
47382
47593
  });
47383
47594
  const cancelPromise = controller._cancelAlgorithm(reason);
@@ -47403,8 +47614,8 @@ var require_ponyfill_es2018 = __commonJS({
47403
47614
  return controller._finishPromise;
47404
47615
  }
47405
47616
  const readable = stream._readable;
47406
- controller._finishPromise = newPromise((resolve37, reject) => {
47407
- controller._finishPromise_resolve = resolve37;
47617
+ controller._finishPromise = newPromise((resolve38, reject) => {
47618
+ controller._finishPromise_resolve = resolve38;
47408
47619
  controller._finishPromise_reject = reject;
47409
47620
  });
47410
47621
  const flushPromise = controller._flushAlgorithm();
@@ -47434,8 +47645,8 @@ var require_ponyfill_es2018 = __commonJS({
47434
47645
  return controller._finishPromise;
47435
47646
  }
47436
47647
  const writable = stream._writable;
47437
- controller._finishPromise = newPromise((resolve37, reject) => {
47438
- controller._finishPromise_resolve = resolve37;
47648
+ controller._finishPromise = newPromise((resolve38, reject) => {
47649
+ controller._finishPromise_resolve = resolve38;
47439
47650
  controller._finishPromise_reject = reject;
47440
47651
  });
47441
47652
  const cancelPromise = controller._cancelAlgorithm(reason);
@@ -49404,7 +49615,7 @@ import zlib from "zlib";
49404
49615
  import Stream2, { PassThrough as PassThrough2, pipeline as pump } from "stream";
49405
49616
  import { Buffer as Buffer3 } from "buffer";
49406
49617
  async function fetch3(url, options_) {
49407
- return new Promise((resolve37, reject) => {
49618
+ return new Promise((resolve38, reject) => {
49408
49619
  const request = new Request2(url, options_);
49409
49620
  const { parsedURL, options } = getNodeRequestOptions(request);
49410
49621
  if (!supportedSchemas.has(parsedURL.protocol)) {
@@ -49413,7 +49624,7 @@ async function fetch3(url, options_) {
49413
49624
  if (parsedURL.protocol === "data:") {
49414
49625
  const data = dist_default(request.url);
49415
49626
  const response2 = new Response2(data, { headers: { "Content-Type": data.typeFull } });
49416
- resolve37(response2);
49627
+ resolve38(response2);
49417
49628
  return;
49418
49629
  }
49419
49630
  const send = (parsedURL.protocol === "https:" ? https : http3).request;
@@ -49535,7 +49746,7 @@ async function fetch3(url, options_) {
49535
49746
  if (responseReferrerPolicy) {
49536
49747
  requestOptions.referrerPolicy = responseReferrerPolicy;
49537
49748
  }
49538
- resolve37(fetch3(new Request2(locationURL, requestOptions)));
49749
+ resolve38(fetch3(new Request2(locationURL, requestOptions)));
49539
49750
  finalize();
49540
49751
  return;
49541
49752
  }
@@ -49568,7 +49779,7 @@ async function fetch3(url, options_) {
49568
49779
  const codings = headers.get("Content-Encoding");
49569
49780
  if (!request.compress || request.method === "HEAD" || codings === null || response_.statusCode === 204 || response_.statusCode === 304) {
49570
49781
  response = new Response2(body, responseOptions);
49571
- resolve37(response);
49782
+ resolve38(response);
49572
49783
  return;
49573
49784
  }
49574
49785
  const zlibOptions = {
@@ -49582,7 +49793,7 @@ async function fetch3(url, options_) {
49582
49793
  }
49583
49794
  });
49584
49795
  response = new Response2(body, responseOptions);
49585
- resolve37(response);
49796
+ resolve38(response);
49586
49797
  return;
49587
49798
  }
49588
49799
  if (codings === "deflate" || codings === "x-deflate") {
@@ -49606,12 +49817,12 @@ async function fetch3(url, options_) {
49606
49817
  });
49607
49818
  }
49608
49819
  response = new Response2(body, responseOptions);
49609
- resolve37(response);
49820
+ resolve38(response);
49610
49821
  });
49611
49822
  raw.once("end", () => {
49612
49823
  if (!response) {
49613
49824
  response = new Response2(body, responseOptions);
49614
- resolve37(response);
49825
+ resolve38(response);
49615
49826
  }
49616
49827
  });
49617
49828
  return;
@@ -49623,11 +49834,11 @@ async function fetch3(url, options_) {
49623
49834
  }
49624
49835
  });
49625
49836
  response = new Response2(body, responseOptions);
49626
- resolve37(response);
49837
+ resolve38(response);
49627
49838
  return;
49628
49839
  }
49629
49840
  response = new Response2(body, responseOptions);
49630
- resolve37(response);
49841
+ resolve38(response);
49631
49842
  });
49632
49843
  writeToStream(request_, request).catch(reject);
49633
49844
  });
@@ -55709,7 +55920,7 @@ var require_jwtaccess = __commonJS({
55709
55920
  }
55710
55921
  }
55711
55922
  fromStreamAsync(inputStream) {
55712
- return new Promise((resolve37, reject) => {
55923
+ return new Promise((resolve38, reject) => {
55713
55924
  if (!inputStream) {
55714
55925
  reject(new Error("Must pass in a stream containing the service account auth settings."));
55715
55926
  }
@@ -55718,7 +55929,7 @@ var require_jwtaccess = __commonJS({
55718
55929
  try {
55719
55930
  const data = JSON.parse(s2);
55720
55931
  this.fromJSON(data);
55721
- resolve37();
55932
+ resolve38();
55722
55933
  } catch (err) {
55723
55934
  reject(err);
55724
55935
  }
@@ -55957,7 +56168,7 @@ var require_jwtclient = __commonJS({
55957
56168
  }
55958
56169
  }
55959
56170
  fromStreamAsync(inputStream) {
55960
- return new Promise((resolve37, reject) => {
56171
+ return new Promise((resolve38, reject) => {
55961
56172
  if (!inputStream) {
55962
56173
  throw new Error("Must pass in a stream containing the service account auth settings.");
55963
56174
  }
@@ -55966,7 +56177,7 @@ var require_jwtclient = __commonJS({
55966
56177
  try {
55967
56178
  const data = JSON.parse(s2);
55968
56179
  this.fromJSON(data);
55969
- resolve37();
56180
+ resolve38();
55970
56181
  } catch (e2) {
55971
56182
  reject(e2);
55972
56183
  }
@@ -56099,7 +56310,7 @@ var require_refreshclient = __commonJS({
56099
56310
  }
56100
56311
  }
56101
56312
  async fromStreamAsync(inputStream) {
56102
- return new Promise((resolve37, reject) => {
56313
+ return new Promise((resolve38, reject) => {
56103
56314
  if (!inputStream) {
56104
56315
  return reject(new Error("Must pass in a stream containing the user refresh token."));
56105
56316
  }
@@ -56108,7 +56319,7 @@ var require_refreshclient = __commonJS({
56108
56319
  try {
56109
56320
  const data = JSON.parse(s2);
56110
56321
  this.fromJSON(data);
56111
- return resolve37();
56322
+ return resolve38();
56112
56323
  } catch (err) {
56113
56324
  return reject(err);
56114
56325
  }
@@ -57941,7 +58152,7 @@ var require_pluggable_auth_handler = __commonJS({
57941
58152
  * @return A promise that resolves with the executable response.
57942
58153
  */
57943
58154
  retrieveResponseFromExecutable(envMap) {
57944
- return new Promise((resolve37, reject) => {
58155
+ return new Promise((resolve38, reject) => {
57945
58156
  const child = childProcess.spawn(this.commandComponents[0], this.commandComponents.slice(1), {
57946
58157
  env: { ...process.env, ...Object.fromEntries(envMap) }
57947
58158
  });
@@ -57963,7 +58174,7 @@ var require_pluggable_auth_handler = __commonJS({
57963
58174
  try {
57964
58175
  const responseJson = JSON.parse(output);
57965
58176
  const response = new executable_response_1.ExecutableResponse(responseJson);
57966
- return resolve37(response);
58177
+ return resolve38(response);
57967
58178
  } catch (error) {
57968
58179
  if (error instanceof executable_response_1.ExecutableResponseError) {
57969
58180
  return reject(error);
@@ -58866,7 +59077,7 @@ var require_googleauth = __commonJS({
58866
59077
  }
58867
59078
  }
58868
59079
  fromStreamAsync(inputStream, options) {
58869
- return new Promise((resolve37, reject) => {
59080
+ return new Promise((resolve38, reject) => {
58870
59081
  if (!inputStream) {
58871
59082
  throw new Error("Must pass in a stream containing the Google auth settings.");
58872
59083
  }
@@ -58876,7 +59087,7 @@ var require_googleauth = __commonJS({
58876
59087
  try {
58877
59088
  const data = JSON.parse(chunks.join(""));
58878
59089
  const r2 = this._cacheClientFromJSON(data, options);
58879
- return resolve37(r2);
59090
+ return resolve38(r2);
58880
59091
  } catch (err) {
58881
59092
  if (!this.keyFilename)
58882
59093
  throw err;
@@ -58886,7 +59097,7 @@ var require_googleauth = __commonJS({
58886
59097
  });
58887
59098
  this.cachedCredential = client;
58888
59099
  this.setGapicJWTValues(client);
58889
- return resolve37(client);
59100
+ return resolve38(client);
58890
59101
  }
58891
59102
  } catch (err) {
58892
59103
  return reject(err);
@@ -58922,17 +59133,17 @@ var require_googleauth = __commonJS({
58922
59133
  * Run the Google Cloud SDK command that prints the default project ID
58923
59134
  */
58924
59135
  async getDefaultServiceProjectId() {
58925
- return new Promise((resolve37) => {
59136
+ return new Promise((resolve38) => {
58926
59137
  (0, child_process_1.exec)("gcloud config config-helper --format json", (err, stdout2) => {
58927
59138
  if (!err && stdout2) {
58928
59139
  try {
58929
59140
  const projectId = JSON.parse(stdout2).configuration.properties.core.project;
58930
- resolve37(projectId);
59141
+ resolve38(projectId);
58931
59142
  return;
58932
59143
  } catch (e2) {
58933
59144
  }
58934
59145
  }
58935
- resolve37(null);
59146
+ resolve38(null);
58936
59147
  });
58937
59148
  });
58938
59149
  }
@@ -66704,14 +66915,14 @@ function __asyncValues(o) {
66704
66915
  }, i2);
66705
66916
  function verb(n) {
66706
66917
  i2[n] = o[n] && function(v) {
66707
- return new Promise(function(resolve37, reject) {
66708
- v = o[n](v), settle(resolve37, reject, v.done, v.value);
66918
+ return new Promise(function(resolve38, reject) {
66919
+ v = o[n](v), settle(resolve38, reject, v.done, v.value);
66709
66920
  });
66710
66921
  };
66711
66922
  }
66712
- function settle(resolve37, reject, d, v) {
66923
+ function settle(resolve38, reject, d, v) {
66713
66924
  Promise.resolve(v).then(function(v2) {
66714
- resolve37({ value: v2, done: d });
66925
+ resolve38({ value: v2, done: d });
66715
66926
  }, reject);
66716
66927
  }
66717
66928
  }
@@ -77214,8 +77425,8 @@ var init_node4 = __esm({
77214
77425
  const url = `${websocketBaseUrl}/ws/google.ai.generativelanguage.${apiVersion}.GenerativeService.BidiGenerateMusic?key=${apiKey}`;
77215
77426
  let onopenResolve = () => {
77216
77427
  };
77217
- const onopenPromise = new Promise((resolve37) => {
77218
- onopenResolve = resolve37;
77428
+ const onopenPromise = new Promise((resolve38) => {
77429
+ onopenResolve = resolve38;
77219
77430
  });
77220
77431
  const callbacks = params.callbacks;
77221
77432
  const onopenAwaitedCallback = function() {
@@ -77421,8 +77632,8 @@ var init_node4 = __esm({
77421
77632
  }
77422
77633
  let onopenResolve = () => {
77423
77634
  };
77424
- const onopenPromise = new Promise((resolve37) => {
77425
- onopenResolve = resolve37;
77635
+ const onopenPromise = new Promise((resolve38) => {
77636
+ onopenResolve = resolve38;
77426
77637
  });
77427
77638
  const callbacks = params.callbacks;
77428
77639
  const onopenAwaitedCallback = function() {
@@ -79731,7 +79942,7 @@ var init_node4 = __esm({
79731
79942
  return void 0;
79732
79943
  }
79733
79944
  };
79734
- sleep$1 = (ms) => new Promise((resolve37) => setTimeout(resolve37, ms));
79945
+ sleep$1 = (ms) => new Promise((resolve38) => setTimeout(resolve38, ms));
79735
79946
  FallbackEncoder = ({ headers, body }) => {
79736
79947
  return {
79737
79948
  bodyHeaders: {
@@ -80240,8 +80451,8 @@ ${underline2}`);
80240
80451
  };
80241
80452
  APIPromise = class _APIPromise extends Promise {
80242
80453
  constructor(client, responsePromise, parseResponse = defaultParseResponse) {
80243
- super((resolve37) => {
80244
- resolve37(null);
80454
+ super((resolve38) => {
80455
+ resolve38(null);
80245
80456
  });
80246
80457
  this.responsePromise = responsePromise;
80247
80458
  this.parseResponse = parseResponse;
@@ -81482,7 +81693,7 @@ ${underline2}`);
81482
81693
  });
81483
81694
 
81484
81695
  // src/capture/contentExtractor.ts
81485
- import { readdirSync as readdirSync17, statSync as statSync18, readFileSync as readFileSync35 } from "fs";
81696
+ import { readdirSync as readdirSync17, statSync as statSync18, readFileSync as readFileSync36 } from "fs";
81486
81697
  import { join as join50 } from "path";
81487
81698
  async function detectLibraries(page, capturedShaders) {
81488
81699
  let detectedLibraries = [];
@@ -81615,7 +81826,7 @@ async function captionImagesWithGemini(outputDir, progress, warnings) {
81615
81826
  const filePath = join50(outputDir, "assets", file);
81616
81827
  const stat3 = statSync18(filePath);
81617
81828
  if (stat3.size > 4e6) return { file, caption: "" };
81618
- const buffer = readFileSync35(filePath);
81829
+ const buffer = readFileSync36(filePath);
81619
81830
  const base64 = buffer.toString("base64");
81620
81831
  const ext = file.split(".").pop()?.toLowerCase() || "png";
81621
81832
  const mimeType = ext === "jpg" ? "image/jpeg" : `image/${ext}`;
@@ -81801,15 +82012,15 @@ var init_agentPromptGenerator = __esm({
81801
82012
  });
81802
82013
 
81803
82014
  // src/capture/scaffolding.ts
81804
- import { existsSync as existsSync47, writeFileSync as writeFileSync20, readFileSync as readFileSync36 } from "fs";
81805
- import { join as join52, resolve as resolve35 } from "path";
82015
+ import { existsSync as existsSync49, writeFileSync as writeFileSync20, readFileSync as readFileSync37 } from "fs";
82016
+ import { join as join52, resolve as resolve36 } from "path";
81806
82017
  function loadEnvFile(startDir) {
81807
82018
  try {
81808
- let dir = resolve35(startDir);
82019
+ let dir = resolve36(startDir);
81809
82020
  for (let i2 = 0; i2 < 5; i2++) {
81810
- const envPath = resolve35(dir, ".env");
82021
+ const envPath = resolve36(dir, ".env");
81811
82022
  try {
81812
- const envContent = readFileSync36(envPath, "utf-8");
82023
+ const envContent = readFileSync37(envPath, "utf-8");
81813
82024
  for (const line of envContent.split("\n")) {
81814
82025
  const trimmed = line.trim();
81815
82026
  if (!trimmed || trimmed.startsWith("#")) continue;
@@ -81821,7 +82032,7 @@ function loadEnvFile(startDir) {
81821
82032
  }
81822
82033
  break;
81823
82034
  } catch {
81824
- dir = resolve35(dir, "..");
82035
+ dir = resolve36(dir, "..");
81825
82036
  }
81826
82037
  }
81827
82038
  } catch {
@@ -81829,7 +82040,7 @@ function loadEnvFile(startDir) {
81829
82040
  }
81830
82041
  async function generateProjectScaffold(outputDir, url, tokens, animationCatalog, hasScreenshots, hasLotties, hasShaders, catalogedAssets, progress, warnings, detectedLibraries) {
81831
82042
  const metaPath = join52(outputDir, "meta.json");
81832
- if (!existsSync47(metaPath)) {
82043
+ if (!existsSync49(metaPath)) {
81833
82044
  const hostname = new URL(url).hostname.replace(/^www\./, "");
81834
82045
  writeFileSync20(
81835
82046
  metaPath,
@@ -82216,7 +82427,7 @@ var capture_exports = {};
82216
82427
  __export(capture_exports, {
82217
82428
  captureWebsite: () => captureWebsite
82218
82429
  });
82219
- import { mkdirSync as mkdirSync28, writeFileSync as writeFileSync22, existsSync as existsSync48 } from "fs";
82430
+ import { mkdirSync as mkdirSync28, writeFileSync as writeFileSync22, existsSync as existsSync50 } from "fs";
82220
82431
  import { join as join54 } from "path";
82221
82432
  async function captureWebsite(opts, onProgress) {
82222
82433
  const {
@@ -82546,7 +82757,7 @@ async function captureWebsite(opts, onProgress) {
82546
82757
  animationCatalog,
82547
82758
  screenshots.length > 0,
82548
82759
  discoveredLotties.length > 0,
82549
- existsSync48(join54(outputDir, "extracted", "shaders.json")),
82760
+ existsSync50(join54(outputDir, "extracted", "shaders.json")),
82550
82761
  catalogedAssets,
82551
82762
  progress,
82552
82763
  warnings,
@@ -82588,7 +82799,7 @@ __export(capture_exports2, {
82588
82799
  default: () => capture_default,
82589
82800
  examples: () => examples20
82590
82801
  });
82591
- import { resolve as resolve36 } from "path";
82802
+ import { resolve as resolve37 } from "path";
82592
82803
  var examples20, capture_default;
82593
82804
  var init_capture2 = __esm({
82594
82805
  "src/commands/capture.ts"() {
@@ -82647,7 +82858,7 @@ var init_capture2 = __esm({
82647
82858
  const hostname = new URL(url).hostname.replace(/^www\./, "");
82648
82859
  outputName = `captures/${hostname.replace(/\./g, "-")}`;
82649
82860
  }
82650
- const outputDir = resolve36(outputName);
82861
+ const outputDir = resolve37(outputName);
82651
82862
  const isJson = args.json;
82652
82863
  if (!isJson) {
82653
82864
  const { c: c2 } = await Promise.resolve().then(() => (init_colors(), colors_exports));