hyperframes 0.8.142 → 0.8.144

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 (222) hide show
  1. package/dist/{add-YS2RCWEK.js → add-CWRTVGDB.js} +18 -17
  2. package/dist/{animatedGifPrep-SAMCDT7T.js → animatedGifPrep-JTOHIWI4.js} +15 -14
  3. package/dist/{asset-BLWC2NWB.js → asset-KU2Z4UFM.js} +4 -4
  4. package/dist/{assetCataloger-FVNBBRP3.js → assetCataloger-3CS2P7PA.js} +8 -7
  5. package/dist/{auth-DRZB7OAC.js → auth-IDSOIQWG.js} +1 -1
  6. package/dist/{autoUpdate-I5I3BOJK.js → autoUpdate-373B4BA2.js} +2 -2
  7. package/dist/{backgroundChecks-VR2QHGNY.js → backgroundChecks-53Q3NAMG.js} +3 -3
  8. package/dist/backgroundChecksWorker.js +3 -3
  9. package/dist/{batchRender-4YUHQI6X.js → batchRender-UKZA6BME.js} +11 -10
  10. package/dist/{beats-7OT7ALV3.js → beats-N5JGEOFR.js} +33 -28
  11. package/dist/{benchmark-Q2XQCRTR.js → benchmark-CUN3LN4V.js} +15 -14
  12. package/dist/{browser-7VAWQQZC.js → browser-NCZT5AP6.js} +40 -56
  13. package/dist/{bundleWithLocalizedFonts-DDMLLL2R.js → bundleWithLocalizedFonts-FWC7PE2D.js} +2 -2
  14. package/dist/{capture-HEJS6M5A.js → capture-QBLG3VJR.js} +26 -25
  15. package/dist/{capture-U7ABPKS5.js → capture-YLS32UHT.js} +2 -2
  16. package/dist/{catalog-DVJ3XPDN.js → catalog-HIWNAFHW.js} +19 -18
  17. package/dist/{catch-up-DF6AVSN2.js → catch-up-HGS7KIAC.js} +5 -5
  18. package/dist/{check-KXORRWAE.js → check-FH6UYYLO.js} +78 -66
  19. package/dist/{checkBrowser-J7HZJTRH.js → checkBrowser-RNWNOMCZ.js} +93 -41
  20. package/dist/{chunk-R2JEKLDZ.js → chunk-2DA2BBNY.js} +3 -3
  21. package/dist/{chunk-TQFG7HTI.js → chunk-3RM2ETQT.js} +0 -168
  22. package/dist/{chunk-YFT3BL7N.js → chunk-3VYNNWVA.js} +30 -12
  23. package/dist/{chunk-7FCDA4RH.js → chunk-3XTEXWNN.js} +8 -5
  24. package/dist/{chunk-PFCFR3KZ.js → chunk-442JNXRM.js} +1 -1
  25. package/dist/{chunk-BPZVDBHY.js → chunk-4LAR447G.js} +1 -1
  26. package/dist/{chunk-AM5L5YIA.js → chunk-4OA4LDTU.js} +1 -1
  27. package/dist/{chunk-DZEVA7DI.js → chunk-4OC7MQNB.js} +2 -2
  28. package/dist/{chunk-75JJVANE.js → chunk-54QISXOC.js} +3 -3
  29. package/dist/{chunk-FZK35GT4.js → chunk-5HJ343GH.js} +1 -1
  30. package/dist/{chunk-IDX52YJN.js → chunk-5VMR4WBS.js} +458 -159
  31. package/dist/{chunk-OSUKETIH.js → chunk-5WADG7PR.js} +1 -1
  32. package/dist/{chunk-JYYOAKHS.js → chunk-6IIGT7BX.js} +1 -1
  33. package/dist/{chunk-6UYZB4TY.js → chunk-7RAYSCYT.js} +4 -4
  34. package/dist/{chunk-WTMUCJ6Z.js → chunk-7SDCIWHQ.js} +11 -2
  35. package/dist/{chunk-LAOCA3MQ.js → chunk-A4Q7W4LV.js} +13 -8
  36. package/dist/{chunk-B6SMSALD.js → chunk-A53CBD24.js} +18 -12
  37. package/dist/{chunk-4PFZPP2N.js → chunk-A6S35NYA.js} +54 -16
  38. package/dist/{chunk-JOTLPC6S.js → chunk-AUBOF2PN.js} +1 -1
  39. package/dist/{chunk-WCJGTLPF.js → chunk-BHVFTYSI.js} +6 -3
  40. package/dist/chunk-BSQ7XANM.js +210 -0
  41. package/dist/{chunk-LCSMOLGX.js → chunk-BYSBRF24.js} +69 -8
  42. package/dist/{chunk-U7E736AJ.js → chunk-DDIVWXN7.js} +32 -14
  43. package/dist/{chunk-KOEWEFHK.js → chunk-DIRJ322I.js} +10 -5
  44. package/dist/{chunk-HMUF7FEO.js → chunk-EX6C672Y.js} +2 -2
  45. package/dist/{chunk-QGRFOOLE.js → chunk-F2SMS24Q.js} +288 -85
  46. package/dist/{chunk-5Z63TBTX.js → chunk-FH7WODJH.js} +1 -1
  47. package/dist/{chunk-XTLBLWOV.js → chunk-GEWKFRFI.js} +1 -1
  48. package/dist/{chunk-RVCWIIZ7.js → chunk-GV5R5B7Q.js} +1 -1
  49. package/dist/{chunk-TY6XOHEM.js → chunk-GZM2EFOE.js} +3 -3
  50. package/dist/chunk-GZVP4TWN.js +76 -0
  51. package/dist/{chunk-QXPCARFE.js → chunk-I5KY7EZP.js} +1 -1
  52. package/dist/{chunk-IW2CKH6A.js → chunk-IEIJRMLZ.js} +94 -59
  53. package/dist/chunk-IR35BCLK.js +13 -0
  54. package/dist/{chunk-JFKL3WAE.js → chunk-IWFLMU2N.js} +104 -19
  55. package/dist/{chunk-EFDXGAAD.js → chunk-JEHFZQYT.js} +1 -1
  56. package/dist/{chunk-IHFUKJOR.js → chunk-K2FLNJVB.js} +8 -2
  57. package/dist/{chunk-KDPYVTEU.js → chunk-KBB4RG6F.js} +6 -1
  58. package/dist/{chunk-LJAU4TPS.js → chunk-KFKZ3ISO.js} +2 -2
  59. package/dist/{sherpa-ZYTNFHD5.js → chunk-L5TUCXWR.js} +11 -44
  60. package/dist/{chunk-KYN364DU.js → chunk-LC3RQURJ.js} +7 -9
  61. package/dist/{chunk-IMY4QQTQ.js → chunk-LFX2HEYP.js} +8 -8
  62. package/dist/{chunk-PXSM4HPB.js → chunk-MAYCCGMQ.js} +12 -3
  63. package/dist/{chunk-OZUQF4NB.js → chunk-MQZVBHEY.js} +123 -8
  64. package/dist/{chunk-FWRNQOLT.js → chunk-MXNDKDFT.js} +3 -3
  65. package/dist/{chunk-A4KQZXZI.js → chunk-NE55C6S5.js} +4 -2
  66. package/dist/{chunk-GYE63V4P.js → chunk-NOPBBSLA.js} +24 -19
  67. package/dist/{chunk-H2X52H2N.js → chunk-NV4RXIQ7.js} +3 -3
  68. package/dist/{chunk-WGVOWWVK.js → chunk-OIDN7G42.js} +3 -3
  69. package/dist/{chunk-DPHJKWP5.js → chunk-OUSLVRO4.js} +107 -108
  70. package/dist/{chunk-JLKMWY2T.js → chunk-P6WH6QTV.js} +8 -5
  71. package/dist/{chunk-7M4KAPAA.js → chunk-PUGIRFPX.js} +2 -2
  72. package/dist/{chunk-6RAD4BCC.js → chunk-QATWIE4K.js} +2 -2
  73. package/dist/{chunk-D2KNWIQ6.js → chunk-QFSCCQIR.js} +1 -1
  74. package/dist/{chunk-XGMNQQTJ.js → chunk-RG3QWWIE.js} +1 -1
  75. package/dist/{chunk-MVTUV4TP.js → chunk-RI53TS2Y.js} +14 -6
  76. package/dist/{chunk-LQASVU3I.js → chunk-RVFEDAUV.js} +12 -4
  77. package/dist/{chunk-GK4AIFIH.js → chunk-SDYDNHEE.js} +34 -3
  78. package/dist/{chunk-WSGY5CDQ.js → chunk-SLCFKB3Y.js} +14 -10
  79. package/dist/{chunk-2NCHQUPX.js → chunk-SQLK7SJL.js} +1 -1
  80. package/dist/{chunk-PMRBLBUP.js → chunk-T42U2W2R.js} +14 -2
  81. package/dist/chunk-UPFUC4DB.js +136 -0
  82. package/dist/{chunk-IXCTG2WY.js → chunk-VYSUZEJG.js} +5 -5
  83. package/dist/chunk-WJB7WI4J.js +3753 -0
  84. package/dist/{chunk-YEIFI443.js → chunk-WPNE5NEP.js} +1 -1
  85. package/dist/{chunk-YHRZQJXH.js → chunk-XGFHYAYN.js} +265 -68
  86. package/dist/{chunk-LBKDQKWV.js → chunk-XU5GGV6R.js} +1 -1
  87. package/dist/{chunk-LTGGTEMA.js → chunk-Y6UPYWJS.js} +2 -2
  88. package/dist/{chunk-OKCR3JTO.js → chunk-YJXHMIZA.js} +13 -10
  89. package/dist/{chunk-JU6Y5TTZ.js → chunk-YUAXFWSQ.js} +3 -3
  90. package/dist/{chunk-TVCRUG2S.js → chunk-ZEUONDQG.js} +1 -1
  91. package/dist/{chunk-THXFSPLV.js → chunk-ZIRIDSDB.js} +1 -1
  92. package/dist/{chunk-6UM3R7PP.js → chunk-ZOA2SC4P.js} +129 -60
  93. package/dist/{clean-KTHTV5G5.js → clean-KPX27IKJ.js} +27 -26
  94. package/dist/cli.js +70 -160
  95. package/dist/{cloud-ARSZWALC.js → cloud-P7DAOISN.js} +4 -4
  96. package/dist/{cloudrun-NM7RXOCL.js → cloudrun-XM56TBOH.js} +13 -12
  97. package/dist/commands/contrast-audit.browser.js +60 -4
  98. package/dist/commands/layout-audit.browser.js +68 -0
  99. package/dist/{compare-CY4UO3RW.js → compare-F6YAFZZM.js} +37 -36
  100. package/dist/{compiler-VTH2D3ID.js → compiler-JZ4GNFMG.js} +16 -10
  101. package/dist/{component-FRUIAXIR.js → component-3CFOGIQA.js} +5 -5
  102. package/dist/{compositions-CUSY6ZYY.js → compositions-CPCMWF24.js} +38 -33
  103. package/dist/{delete-KT3VHP4L.js → delete-GYVKOKB6.js} +4 -4
  104. package/dist/{deterministicFonts-F6WIVL2W.js → deterministicFonts-U2BIMGPG.js} +3 -3
  105. package/dist/{dist-7SZU7MA7.js → dist-KDJTFJHA.js} +7 -6
  106. package/dist/{dist-2GC6XKRQ.js → dist-YPWQDWJ4.js} +42 -40
  107. package/dist/{doctor-4ROTBL5U.js → doctor-GWI3B6JT.js} +21 -20
  108. package/dist/{dom-IROKGVJI.js → dom-37K6YOH4.js} +2 -2
  109. package/dist/{events-QJDVMKSR.js → events-BRRUDPPT.js} +3 -3
  110. package/dist/{events-Q5PXT5UC.js → events-V2QFN4YM.js} +2 -2
  111. package/dist/{feedback-PQ7TWESA.js → feedback-CXMD7FWL.js} +14 -13
  112. package/dist/{ffmpeg-QIUFEFTY.js → ffmpeg-T5SH2EFJ.js} +3 -2
  113. package/dist/{figma-JN5DDBDS.js → figma-YABDWD66.js} +3 -3
  114. package/dist/fontLocalizeCli.js +18 -17
  115. package/dist/{get-KT6OTERO.js → get-L2SOQKHX.js} +4 -4
  116. package/dist/{gpuPolicy-LCBWVGEH.js → gpuPolicy-NBJNWHYS.js} +19 -16
  117. package/dist/{grade-compare-VS3RP73G.js → grade-compare-STXQPKYQ.js} +39 -38
  118. package/dist/{help-AD6FIZIO.js → help-4H6BSFLB.js} +2 -2
  119. package/dist/{history-ZRWYRY7R.js → history-4IQOLTHJ.js} +6 -6
  120. package/dist/hyperframe-runtime.js +56 -56
  121. package/dist/hyperframe.manifest.json +1 -1
  122. package/dist/hyperframe.runtime.iife.js +56 -56
  123. package/dist/hyperframes-player.global.js +3 -3
  124. package/dist/hyperframes-slideshow.global.js +23 -23
  125. package/dist/{info-WBBQA2AX.js → info-2CZOTNBC.js} +17 -16
  126. package/dist/{init-A2XBDFGF.js → init-6BXK42VS.js} +46 -46
  127. package/dist/{inspect-CLTZHA5O.js → inspect-VKU47TBH.js} +38 -37
  128. package/dist/{installer-WQDRVXH4.js → installer-T2BSSUDY.js} +11 -10
  129. package/dist/{keyframes-3FYOK6H6.js → keyframes-IEYVHRPI.js} +10 -10
  130. package/dist/{lambda-Y2PA2BGS.js → lambda-TIKG25CK.js} +12 -11
  131. package/dist/{layout-4KP5O7IJ.js → layout-XOI4PT7A.js} +38 -37
  132. package/dist/{lint-V4GRFHOJ.js → lint-DWCMVIX5.js} +14 -13
  133. package/dist/{lintProject-RG2KGAXB.js → lintProject-UBZ3TDHU.js} +7 -6
  134. package/dist/{list-OQ4VED6E.js → list-7GXKG5QM.js} +5 -5
  135. package/dist/{login-W47NKN5S.js → login-BQ5L2UHX.js} +4 -4
  136. package/dist/{manager-CT3D67CG.js → manager-BPSR6D3V.js} +2 -2
  137. package/dist/{manager-524RPYO7.js → manager-RFZNG5YT.js} +2 -2
  138. package/dist/{manager-DXB7JDHU.js → manager-YKMHR6LN.js} +9 -6
  139. package/dist/{media-treatment-HJYL3EME.js → media-treatment-IFB7OSZ3.js} +24 -22
  140. package/dist/{models-DYBAD2GQ.js → models-TY4PJ545.js} +68 -27
  141. package/dist/{motionShot-7NE2YBB3.js → motionShot-WXMFHICW.js} +33 -33
  142. package/dist/{normalize-IGLHCWTF.js → normalize-U3SL5VG3.js} +19 -8
  143. package/dist/{normalize-audio-INKCLMS2.js → normalize-audio-RFD776HQ.js} +10 -6
  144. package/dist/{open-TYC5THVY.js → open-7IXXGO2E.js} +5 -5
  145. package/dist/parakeetRunner-IHLYYMTZ.js +67 -0
  146. package/dist/{pipeline-EVKEPQEW.js → pipeline-TXKPLL2U.js} +20 -18
  147. package/dist/{play-QMZEM6X3.js → play-J2KP64UK.js} +31 -29
  148. package/dist/{preflight-Y5DN5D37.js → preflight-B4AFK3RG.js} +4 -4
  149. package/dist/{present-Y7IK3C4W.js → present-MHHNRVRA.js} +26 -25
  150. package/dist/{preview-5OQRYE6A.js → preview-CONUOFFQ.js} +28 -27
  151. package/dist/{producer-Q6G6JU7B.js → producer-ZI46K7HH.js} +1 -1
  152. package/dist/{projectConfig-RJN3DKDB.js → projectConfig-FGGVG5MV.js} +13 -12
  153. package/dist/{publication-QCPGGN3U.js → publication-TXFBMW6B.js} +8 -7
  154. package/dist/{publish-VZLFIGYY.js → publish-YZSPBFRD.js} +18 -17
  155. package/dist/{remove-background-TKOEHBA5.js → remove-background-4ATVLHLG.js} +22 -20
  156. package/dist/{render-KIIIF6PS.js → render-6FBYLYGJ.js} +20 -19
  157. package/dist/{render-XTXE5CRU.js → render-GFW5BPES.js} +13 -12
  158. package/dist/{render-X3NFNVEQ.js → render-MH4IUPWB.js} +41 -40
  159. package/dist/{render-batch-M55YZLZ5.js → render-batch-XUCZ2PUJ.js} +13 -12
  160. package/dist/{renderCancellation-X5BEHAZU.js → renderCancellation-XF7M7IUP.js} +18 -16
  161. package/dist/renderSetupWorker.js +37 -48
  162. package/dist/{resolver-GAMXRA42.js → resolver-W7AYCQGS.js} +10 -9
  163. package/dist/sherpa-LDUB5NLY.js +75 -0
  164. package/dist/sherpaWorker.js +2 -1
  165. package/dist/skills/hyperframes-cli/references/doctor-browser.md +24 -1
  166. package/dist/skills/hyperframes-cli/references/lint-validate-inspect.md +1 -1
  167. package/dist/skills/media-use/scripts/lib/cache.mjs +28 -14
  168. package/dist/skills/media-use/scripts/lib/cache.test.mjs +110 -0
  169. package/dist/skills/media-use/scripts/lib/duck.mjs +2 -1
  170. package/dist/skills/media-use/scripts/lib/duck.test.mjs +87 -0
  171. package/dist/skills/media-use/scripts/lib/probe.mjs +6 -1
  172. package/dist/skills/media-use/scripts/lib/probe.test.mjs +73 -0
  173. package/dist/skills/media-use/scripts/lib/words.mjs +1 -1
  174. package/dist/{skills-CZHVAD3J.js → skills-VENERS5X.js} +7 -7
  175. package/dist/{skillsUpdateCheck-6WLLX53A.js → skillsUpdateCheck-UXFYTACG.js} +3 -3
  176. package/dist/{slideshow-EJ4IMY6P.js → slideshow-4OJEPWNZ.js} +1 -1
  177. package/dist/{snapshot-K7BTJPYQ.js → snapshot-C6T74HTI.js} +44 -40
  178. package/dist/{src-YUW26JU5.js → src-FS5RSVEI.js} +17 -16
  179. package/dist/{src-3I3RH3V5.js → src-VUJ2FUFK.js} +18 -13
  180. package/dist/{staticProjectServer-IKCSGN2B.js → staticProjectServer-V2RZ4DWD.js} +23 -22
  181. package/dist/studio/assets/hyperframes-player-Bw_jIaSX.js +473 -0
  182. package/dist/studio/assets/{index-B-wffzRH.js → index-BVM9NuWl.js} +153 -153
  183. package/dist/studio/assets/{index-D3Vij9t1.js → index-Cj7W_c7p.js} +1 -1
  184. package/dist/studio/assets/{index-D5q2_7Gw.js → index-DyH9dT7b.js} +1 -1
  185. package/dist/studio/{chunk-TFLU2MGI.js → chunk-3GHTHPZD.js} +8 -1
  186. package/dist/studio/chunk-3GHTHPZD.js.map +1 -0
  187. package/dist/studio/{chunk-H2DUOXTF.js → chunk-G3EDKRZH.js} +3 -3
  188. package/dist/studio/{chunk-UYWON5AX.js → chunk-PEAKCOUW.js} +7 -3
  189. package/dist/studio/chunk-PEAKCOUW.js.map +1 -0
  190. package/dist/studio/{chunk-LOVBLSMR.js → chunk-Y2OHHNM2.js} +35 -19
  191. package/dist/studio/chunk-Y2OHHNM2.js.map +1 -0
  192. package/dist/studio/{domEditingLayers-KBTPQKGA.js → domEditingLayers-PYST4G45.js} +3 -3
  193. package/dist/studio/index.html +1 -1
  194. package/dist/studio/index.js +261 -230
  195. package/dist/studio/index.js.map +1 -1
  196. package/dist/studio/player.js +3 -3
  197. package/dist/studio/ui.d.ts +4 -5
  198. package/dist/studio/ui.js +1 -1
  199. package/dist/{studio-api-SQ3NXFSM.js → studio-api-TQE7KWKO.js} +22 -17
  200. package/dist/{studioServer-VVEO7XCH.js → studioServer-CYKSQK7L.js} +81 -64
  201. package/dist/{synthesize-77PTU6C5.js → synthesize-UCI4X5O7.js} +6 -6
  202. package/dist/{telemetry-FQDKR5XA.js → telemetry-A23PPRD6.js} +3 -3
  203. package/dist/{timeline-N6ZASFNE.js → timeline-T3QSGT3A.js} +143 -99
  204. package/dist/{tokens-2OIIBBCW.js → tokens-RT5HWA6C.js} +4 -4
  205. package/dist/{transcribe-7YTUCXDX.js → transcribe-FOLNOC5G.js} +116 -52
  206. package/dist/{transcribe-4F6MK73N.js → transcribe-HCF64LQK.js} +23 -20
  207. package/dist/{tts-TOHSPWEG.js → tts-B6AHFQEO.js} +6 -6
  208. package/dist/{updateCheck-AZ2COZFR.js → updateCheck-27PIP3AA.js} +2 -2
  209. package/dist/{upgrade-QAJEYB4X.js → upgrade-TVGXBUPJ.js} +2 -2
  210. package/dist/{urlDownloader-LSMFEO3R.js → urlDownloader-KBLBJKRL.js} +14 -13
  211. package/dist/{validate-GW5MDL36.js → validate-ZMYGK4QI.js} +40 -27
  212. package/dist/{video-PRNOKUK3.js → video-AVE5GIGM.js} +15 -14
  213. package/package.json +1 -1
  214. package/dist/chunk-J4UX3RS3.js +0 -3717
  215. package/dist/studio/assets/hyperframes-player-sAsRuV73.js +0 -473
  216. package/dist/studio/chunk-LOVBLSMR.js.map +0 -1
  217. package/dist/studio/chunk-TFLU2MGI.js.map +0 -1
  218. package/dist/studio/chunk-UYWON5AX.js.map +0 -1
  219. package/dist/{chunk-HBBJFK6I.js → chunk-APDLWWFG.js} +0 -0
  220. package/dist/{screenshotCapture-TEUIWXWN.js → screenshotCapture-3JXXUZND.js} +3 -3
  221. /package/dist/studio/{chunk-H2DUOXTF.js.map → chunk-G3EDKRZH.js.map} +0 -0
  222. /package/dist/studio/{domEditingLayers-KBTPQKGA.js.map → domEditingLayers-PYST4G45.js.map} +0 -0
@@ -11,12 +11,12 @@ import {
11
11
  iterateFontFamilyDeclarations,
12
12
  normalizeSystemFontPrimaryFamilies,
13
13
  resolveFontFamilyDeclarationFamilies
14
- } from "./chunk-7M4KAPAA.js";
14
+ } from "./chunk-PUGIRFPX.js";
15
15
  import {
16
16
  EncoderInterruptedError,
17
17
  encoderFailureError,
18
18
  prepareAnimatedGifInputs
19
- } from "./chunk-WGVOWWVK.js";
19
+ } from "./chunk-OIDN7G42.js";
20
20
  import {
21
21
  createStudioPositionSeekReapplyScript
22
22
  } from "./chunk-KC5XXX3X.js";
@@ -79,6 +79,7 @@ import {
79
79
  extractAllVideoFrames,
80
80
  extractAudioMetadata,
81
81
  extractMediaMetadata,
82
+ extractVideoFramesRange,
82
83
  extractionFrameCountForDuration,
83
84
  fetchPublicHttpsText,
84
85
  fingerprintElementId,
@@ -141,7 +142,7 @@ import {
141
142
  validateEngineConfigSnapshot,
142
143
  verifyDiskDrawElementSamples,
143
144
  writeCapturedFrame
144
- } from "./chunk-IDX52YJN.js";
145
+ } from "./chunk-5VMR4WBS.js";
145
146
  import {
146
147
  assignBundledRuntimeCompositionIds,
147
148
  buildVariablesByCompScript,
@@ -150,8 +151,9 @@ import {
150
151
  ensureExternalLinkTag,
151
152
  ensureExternalScriptTag,
152
153
  inlineSubCompositions,
154
+ parsesAsScript,
153
155
  prepareFlattenedInnerRoot
154
- } from "./chunk-DPHJKWP5.js";
156
+ } from "./chunk-OUSLVRO4.js";
155
157
  import {
156
158
  LOW_MEMORY_TOTAL_MB_THRESHOLD,
157
159
  getCgroupMemoryLimitMb,
@@ -172,18 +174,7 @@ import {
172
174
  resolveAbsoluteMediaStartSeconds,
173
175
  resolveAuthoredTimingWindow,
174
176
  toFps
175
- } from "./chunk-YFT3BL7N.js";
176
- import {
177
- CANVAS_DIMENSIONS,
178
- HTML_BODY_CSS_HEIGHT_FIRST_RE,
179
- HTML_BODY_CSS_WIDTH_FIRST_RE,
180
- VALID_CANVAS_RESOLUTIONS,
181
- checkOutputResolutionCompatibility,
182
- extractMediaSrcMutations,
183
- isAspectAgnosticResolutionAlias,
184
- normalizeResolutionFlag,
185
- suggestMatchingPreset
186
- } from "./chunk-OZUQF4NB.js";
177
+ } from "./chunk-3VYNNWVA.js";
187
178
  import {
188
179
  COMPOSITION_SOURCE_URL,
189
180
  HF_COLOR_GRADING_ATTR,
@@ -210,10 +201,21 @@ import {
210
201
  shouldClampResolvedMediaDuration,
211
202
  sourceTimeAt,
212
203
  styleElementsFor
213
- } from "./chunk-J4UX3RS3.js";
204
+ } from "./chunk-WJB7WI4J.js";
214
205
  import {
215
206
  MAX_AUDIO_GAIN
216
207
  } from "./chunk-YA62XGXS.js";
208
+ import {
209
+ CANVAS_DIMENSIONS,
210
+ HTML_BODY_CSS_HEIGHT_FIRST_RE,
211
+ HTML_BODY_CSS_WIDTH_FIRST_RE,
212
+ VALID_CANVAS_RESOLUTIONS,
213
+ checkOutputResolutionCompatibility,
214
+ extractMediaSrcMutations,
215
+ isAspectAgnosticResolutionAlias,
216
+ normalizeResolutionFlag,
217
+ suggestMatchingPreset
218
+ } from "./chunk-MQZVBHEY.js";
217
219
  import {
218
220
  redactKnownPaths,
219
221
  redactTelemetryString
@@ -223,23 +225,26 @@ import {
223
225
  } from "./chunk-TWWSYAKJ.js";
224
226
  import {
225
227
  lintHyperframeHtml
226
- } from "./chunk-IW2CKH6A.js";
228
+ } from "./chunk-IEIJRMLZ.js";
227
229
  import {
228
230
  isUnresolvedAssetPlaceholder,
229
231
  readProjectFile,
230
232
  resolveProjectRelativeSrc
231
- } from "./chunk-JFKL3WAE.js";
233
+ } from "./chunk-IWFLMU2N.js";
234
+ import {
235
+ checkSubCompositionUsability
236
+ } from "./chunk-3RM2ETQT.js";
232
237
  import {
233
238
  CSS_URL_RE,
234
- checkSubCompositionUsability,
239
+ decodedUrlPath,
235
240
  isNonRelativeUrl,
236
241
  rewriteAssetPaths,
237
242
  rewriteCssAssetUrls,
238
243
  rewriteInlineStyleAssetUrls
239
- } from "./chunk-TQFG7HTI.js";
244
+ } from "./chunk-BSQ7XANM.js";
240
245
  import {
241
246
  parseHTML
242
- } from "./chunk-GK4AIFIH.js";
247
+ } from "./chunk-SDYDNHEE.js";
243
248
  import {
244
249
  TRANSITIONS,
245
250
  convertTransfer,
@@ -5691,8 +5696,9 @@ async function resolveMediaDuration(src, mediaStart, playbackRate, baseDir, down
5691
5696
  } catch {
5692
5697
  return { duration: null, resolvedPath: src };
5693
5698
  }
5694
- } else if (!filePath.startsWith("/")) {
5695
- filePath = join12(baseDir, filePath);
5699
+ } else {
5700
+ filePath = decodedUrlPath(src);
5701
+ if (!filePath.startsWith("/")) filePath = join12(baseDir, filePath);
5696
5702
  }
5697
5703
  if (!existsSync9(filePath)) {
5698
5704
  return { duration: null, resolvedPath: filePath };
@@ -5937,8 +5943,8 @@ function coalesceHeadStylesAndBodyScripts(html) {
5937
5943
  const { document: document2 } = parseHTML(html);
5938
5944
  const head = document2.querySelector("head");
5939
5945
  const body = document2.querySelector("body");
5940
- if (!head) return html;
5941
- const styleEls = Array.from(head.querySelectorAll("style"));
5946
+ if (!head && !body) return html;
5947
+ const styleEls = head ? Array.from(head.querySelectorAll("style")) : [];
5942
5948
  const importRe = /@import\s+url\([^)]*\)\s*;|@import\s+["'][^"']+["']\s*;/gi;
5943
5949
  for (const run of styleEls.length > 1 ? headStyleRuns(styleEls) : []) {
5944
5950
  const imports = [];
@@ -5968,6 +5974,7 @@ function coalesceHeadStylesAndBodyScripts(html) {
5968
5974
  Array.from(body.querySelectorAll("script"))
5969
5975
  )) {
5970
5976
  const mergedJs = members.map((el) => (el.textContent || "").trim()).filter(Boolean).join("\n;\n").trim();
5977
+ if (mergedJs && !parsesAsScript(mergedJs)) continue;
5971
5978
  for (const el of members) el.remove();
5972
5979
  if (!mergedJs) continue;
5973
5980
  const script = document2.createElement("script");
@@ -6067,9 +6074,12 @@ function inlineSubCompositions2(html, subCompositions, projectDir, variableOverr
6067
6074
  let pending = variablesByCompScript ? [variablesByCompScript] : [];
6068
6075
  const flushInline = () => {
6069
6076
  if (!pending.length) return;
6070
- const scriptEl = document2.createElement("script");
6071
- scriptEl.textContent = pending.join("\n;\n");
6072
- body.appendChild(scriptEl);
6077
+ const joined = pending.join("\n;\n");
6078
+ for (const text of parsesAsScript(joined) ? [joined] : pending) {
6079
+ const scriptEl = document2.createElement("script");
6080
+ scriptEl.textContent = text;
6081
+ body.appendChild(scriptEl);
6082
+ }
6073
6083
  pending = [];
6074
6084
  };
6075
6085
  for (const item of result.scriptItems) {
@@ -6493,7 +6503,7 @@ async function readLocalFont(absPath) {
6493
6503
  return { kind: "inline", buffer: Buffer.concat(chunks, totalBytes) };
6494
6504
  }
6495
6505
  async function embedLocalFontFaces(html, projectDir) {
6496
- const { fontToDataUri: toDataUri } = await import("./deterministicFonts-F6WIVL2W.js");
6506
+ const { fontToDataUri: toDataUri } = await import("./deterministicFonts-U2BIMGPG.js");
6497
6507
  const styleBlockRe = /<style\b[^>]*>([\s\S]*?)<\/style>/gi;
6498
6508
  const fontFaceRe = /@font-face\s*\{([^}]*)\}/gi;
6499
6509
  let result = html;
@@ -7295,7 +7305,8 @@ async function runProbeStage(input) {
7295
7305
  width,
7296
7306
  height,
7297
7307
  needsAlpha,
7298
- deviceScaleFactor
7308
+ deviceScaleFactor,
7309
+ subTimelineWaitMemo
7299
7310
  } = input;
7300
7311
  let { compiled } = input;
7301
7312
  const probeCfg = cfg.forceScreenshot === forceScreenshot ? cfg : { ...cfg, forceScreenshot };
@@ -7351,7 +7362,8 @@ async function runProbeStage(input) {
7351
7362
  variables: job.config.variables,
7352
7363
  deviceScaleFactor,
7353
7364
  motionBlur,
7354
- requiresWebGpu: compositionRequiresWebGpu(compiled.html)
7365
+ requiresWebGpu: compositionRequiresWebGpu(compiled.html),
7366
+ subTimelineWaitMemo
7355
7367
  };
7356
7368
  const PROBE_MAX_ATTEMPTS = 2;
7357
7369
  for (let attempt = 1; attempt <= PROBE_MAX_ATTEMPTS; attempt++) {
@@ -8029,7 +8041,8 @@ async function runExtractVideosStage(input) {
8029
8041
  composition,
8030
8042
  abortSignal,
8031
8043
  assertNotAborted,
8032
- materializeSymlinks
8044
+ materializeSymlinks,
8045
+ deferRangeExtraction
8033
8046
  } = input;
8034
8047
  const stage2Start = Date.now();
8035
8048
  const extractionPolicy = resolveVideoExtractionPolicy();
@@ -8118,7 +8131,8 @@ async function runExtractVideosStage(input) {
8118
8131
  toneMapHdrToSdr: job.config.hdrMode === "force-sdr",
8119
8132
  timelineEnd: composition.duration,
8120
8133
  maxTransientRetries: extractionPolicy.maxTransientRetries,
8121
- collectProbeFailures: extractionPolicy.failureMode === "enforce"
8134
+ collectProbeFailures: extractionPolicy.failureMode === "enforce",
8135
+ deferRangeExtraction
8122
8136
  },
8123
8137
  abortSignal,
8124
8138
  cfg,
@@ -11512,6 +11526,7 @@ async function executeRenderPipeline(input) {
11512
11526
  cfg.protocolTimeout = scaledProtocolTimeout;
11513
11527
  updateCaptureObservability({ protocolTimeoutMs: scaledProtocolTimeout });
11514
11528
  }
11529
+ const subTimelineWaitMemo = {};
11515
11530
  const probeResult = await observeRenderStage(
11516
11531
  observability,
11517
11532
  "browser_probe",
@@ -11530,7 +11545,8 @@ async function executeRenderPipeline(input) {
11530
11545
  width,
11531
11546
  height,
11532
11547
  needsAlpha,
11533
- deviceScaleFactor
11548
+ deviceScaleFactor,
11549
+ subTimelineWaitMemo
11534
11550
  }),
11535
11551
  // Browser probe is pre-capture; report `browser calibrating` so a
11536
11552
  // slow probe (~64s SwiftShader warm-up on Windows was the reported
@@ -11760,6 +11776,7 @@ async function executeRenderPipeline(input) {
11760
11776
  ...captureOptions,
11761
11777
  videoMetadataHints,
11762
11778
  skipReadinessVideoIds: videoReadinessSkipIds,
11779
+ subTimelineWaitMemo,
11763
11780
  // Probe-resolved duration: drawElement self-verification derives its
11764
11781
  // sample frame indices from this so they land inside the drained range.
11765
11782
  compositionDurationSeconds: job.duration,
@@ -13624,7 +13641,10 @@ function prepareHyperframeLintBody(body) {
13624
13641
  return { error: "Missing lint source: provide projectDir, files, or html" };
13625
13642
  }
13626
13643
  async function runHyperframeLint(prepared) {
13627
- return lintHyperframeHtml(prepared.html, { filePath: prepared.entryFile });
13644
+ return lintHyperframeHtml(prepared.html, {
13645
+ filePath: prepared.entryFile,
13646
+ compSrcPath: prepared.entryFile
13647
+ });
13628
13648
  }
13629
13649
 
13630
13650
  // ../producer/src/services/healthWorker.ts
@@ -14319,7 +14339,7 @@ function startServer(options = {}) {
14319
14339
  });
14320
14340
  async function shutdown(signal) {
14321
14341
  log.info(`Received ${signal}, shutting down`);
14322
- const { drainBrowserPool } = await import("./src-3I3RH3V5.js");
14342
+ const { drainBrowserPool } = await import("./src-VUJ2FUFK.js");
14323
14343
  await drainBrowserPool().catch(() => {
14324
14344
  });
14325
14345
  const handle = await Promise.race([
@@ -14355,8 +14375,17 @@ if (isPublicServerEntry) {
14355
14375
  }
14356
14376
 
14357
14377
  // ../producer/src/services/distributed/plan.ts
14358
- import { cpSync as cpSync2, existsSync as existsSync21, mkdirSync as mkdirSync11, renameSync as renameSync4, rmSync as rmSync10, writeFileSync as writeFileSync8 } from "fs";
14359
- import { join as join32, relative as relative6, sep as sep3 } from "path";
14378
+ import {
14379
+ copyFileSync as copyFileSync4,
14380
+ cpSync as cpSync2,
14381
+ existsSync as existsSync21,
14382
+ linkSync,
14383
+ mkdirSync as mkdirSync11,
14384
+ renameSync as renameSync4,
14385
+ rmSync as rmSync10,
14386
+ writeFileSync as writeFileSync8
14387
+ } from "fs";
14388
+ import { extname as extname5, isAbsolute as isAbsolute3, join as join32, relative as relative6, sep as sep3 } from "path";
14360
14389
 
14361
14390
  // ../producer/src/services/render/stages/freezePlan.ts
14362
14391
  import { existsSync as existsSync19, mkdirSync as mkdirSync10, readFileSync as readFileSync9, readdirSync as readdirSync6, writeFileSync as writeFileSync7 } from "fs";
@@ -14756,6 +14785,24 @@ function readNonNegativeInteger(value, field) {
14756
14785
  }
14757
14786
  return value;
14758
14787
  }
14788
+ function readDeferredFrameRange(value, field) {
14789
+ const range = readRecord(value, field);
14790
+ const sourcePath = readNonEmptyString(range.sourcePath, `${field}.sourcePath`);
14791
+ if (sourcePath.startsWith("/") || sourcePath.split(/[\\/]/).some((part) => part === "..")) {
14792
+ metadataError(`${field}.sourcePath`, "must stay inside the plan directory");
14793
+ }
14794
+ const durationSeconds = readFiniteNumber(range.durationSeconds, `${field}.durationSeconds`);
14795
+ if (durationSeconds <= 0) metadataError(`${field}.durationSeconds`, "must be positive");
14796
+ if (range.format !== "jpg" && range.format !== "png") {
14797
+ metadataError(`${field}.format`, 'must be "jpg" or "png"');
14798
+ }
14799
+ return {
14800
+ sourcePath,
14801
+ startTime: readFiniteNumber(range.startTime, `${field}.startTime`),
14802
+ durationSeconds,
14803
+ format: range.format
14804
+ };
14805
+ }
14759
14806
  function readRateSpec(value, field) {
14760
14807
  if (value === void 0) return void 0;
14761
14808
  if (typeof value === "number") return readFiniteNumber(value, field);
@@ -14824,7 +14871,8 @@ function parsePlanVideosJson(value) {
14824
14871
  framePattern: readNonEmptyString(entry.framePattern, `${field}.framePattern`),
14825
14872
  fps: readFiniteNumber(entry.fps, `${field}.fps`),
14826
14873
  totalFrames: readNonNegativeInteger(entry.totalFrames, `${field}.totalFrames`),
14827
- metadata: readVideoMetadata(entry.metadata, `${field}.metadata`)
14874
+ metadata: readVideoMetadata(entry.metadata, `${field}.metadata`),
14875
+ ...entry.deferredRange === void 0 ? {} : { deferredRange: readDeferredFrameRange(entry.deferredRange, `${field}.deferredRange`) }
14828
14876
  };
14829
14877
  });
14830
14878
  const videoIds = /* @__PURE__ */ new Set();
@@ -15329,6 +15377,39 @@ function resolveDistributedEngineConfig(config) {
15329
15377
  forceScreenshotExplicitlyOptedOut: true
15330
15378
  };
15331
15379
  }
15380
+ function pathInside(root, path) {
15381
+ const rel = relative6(root, path);
15382
+ return rel === "" || rel.startsWith("..") || isAbsolute3(rel) ? null : rel;
15383
+ }
15384
+ function createVideoSourceShipper(input) {
15385
+ const shipped = /* @__PURE__ */ new Map();
15386
+ return (srcPath) => {
15387
+ const known = shipped.get(srcPath);
15388
+ if (known) return known;
15389
+ const stagedRel = pathInside(input.workVideoFramesDir, srcPath);
15390
+ const current = stagedRel === null ? srcPath : join32(input.planDir, "video-frames", stagedRel);
15391
+ let result = null;
15392
+ for (const root of stagedRel === null ? [input.workCompiledDir, input.projectDir] : []) {
15393
+ const rel = pathInside(root, srcPath);
15394
+ if (rel !== null && existsSync21(join32(input.planDir, "compiled", rel))) {
15395
+ result = ["compiled", ...rel.split(sep3)].join("/");
15396
+ break;
15397
+ }
15398
+ }
15399
+ if (result === null) {
15400
+ result = `video-sources/${shipped.size}${extname5(current)}`;
15401
+ const destination = join32(input.planDir, ...result.split("/"));
15402
+ mkdirSync11(join32(input.planDir, "video-sources"), { recursive: true });
15403
+ try {
15404
+ linkSync(current, destination);
15405
+ } catch {
15406
+ copyFileSync4(current, destination);
15407
+ }
15408
+ }
15409
+ shipped.set(srcPath, result);
15410
+ return result;
15411
+ };
15412
+ }
15332
15413
  async function buildLocalExecutionPlan(projectDir, config, executionPlanDir, options = {}) {
15333
15414
  const planDir = executionPlanDir;
15334
15415
  rejectUnsupportedDistributedFormat(config);
@@ -15428,7 +15509,8 @@ async function buildLocalExecutionPlan(projectDir, config, executionPlanDir, opt
15428
15509
  width,
15429
15510
  height,
15430
15511
  needsAlpha,
15431
- deviceScaleFactor
15512
+ deviceScaleFactor,
15513
+ subTimelineWaitMemo: {}
15432
15514
  });
15433
15515
  compiled = probeResult.compiled;
15434
15516
  job.duration = probeResult.duration;
@@ -15442,7 +15524,7 @@ async function buildLocalExecutionPlan(projectDir, config, executionPlanDir, opt
15442
15524
  if (probeResult.fileServer) closeFileServerSafely(probeResult.fileServer, "plan", log);
15443
15525
  if (probeResult.probeSession) {
15444
15526
  try {
15445
- const { closeCaptureSession: closeCaptureSession2 } = await import("./src-3I3RH3V5.js");
15527
+ const { closeCaptureSession: closeCaptureSession2 } = await import("./src-VUJ2FUFK.js");
15446
15528
  await closeCaptureSession2(probeResult.probeSession);
15447
15529
  } catch (err) {
15448
15530
  log.warn("[plan] probe session close failed", {
@@ -15465,7 +15547,8 @@ async function buildLocalExecutionPlan(projectDir, config, executionPlanDir, opt
15465
15547
  composition,
15466
15548
  abortSignal,
15467
15549
  assertNotAborted,
15468
- materializeSymlinks: true
15550
+ materializeSymlinks: true,
15551
+ deferRangeExtraction: options.deferVideoExtraction
15469
15552
  });
15470
15553
  if (extractResult.failureToEnforce) throw extractResult.failureToEnforce;
15471
15554
  if (extractResult.extractionResult) {
@@ -15488,6 +15571,7 @@ async function buildLocalExecutionPlan(projectDir, config, executionPlanDir, opt
15488
15571
  const stagedVideoFrames = join32(compiledDir, "__hyperframes_video_frames");
15489
15572
  const videoFramesDst = join32(planDir, "video-frames");
15490
15573
  if (existsSync21(videoFramesDst)) rmSync10(videoFramesDst, { recursive: true, force: true });
15574
+ rmSync10(join32(planDir, "video-sources"), { recursive: true, force: true });
15491
15575
  if (existsSync21(stagedVideoFrames)) {
15492
15576
  renameSync4(stagedVideoFrames, videoFramesDst);
15493
15577
  } else {
@@ -15495,6 +15579,12 @@ async function buildLocalExecutionPlan(projectDir, config, executionPlanDir, opt
15495
15579
  }
15496
15580
  if (existsSync21(finalCompiledDir)) rmSync10(finalCompiledDir, { recursive: true, force: true });
15497
15581
  renameSync4(compiledDir, finalCompiledDir);
15582
+ const shipVideoSource = createVideoSourceShipper({
15583
+ planDir,
15584
+ projectDir,
15585
+ workCompiledDir: compiledDir,
15586
+ workVideoFramesDir: stagedVideoFrames
15587
+ });
15498
15588
  const planVideosJson = buildPlanVideosJson({
15499
15589
  videos: composition.videos,
15500
15590
  compositionEnd: job.duration ?? Number.NaN,
@@ -15504,7 +15594,8 @@ async function buildLocalExecutionPlan(projectDir, config, executionPlanDir, opt
15504
15594
  framePattern: ext.framePattern,
15505
15595
  fps: ext.fps,
15506
15596
  totalFrames: ext.totalFrames,
15507
- metadata: ext.metadata
15597
+ metadata: ext.metadata,
15598
+ ...ext.deferredRange ? { deferredRange: { ...ext.deferredRange, sourcePath: shipVideoSource(ext.srcPath) } } : {}
15508
15599
  }))
15509
15600
  });
15510
15601
  mkdirSync11(join32(planDir, "meta"), { recursive: true });
@@ -15624,7 +15715,7 @@ async function plan(projectDir, config, planDir) {
15624
15715
  // ../producer/src/services/distributed/planV2.ts
15625
15716
  import {
15626
15717
  closeSync as closeSync6,
15627
- copyFileSync as copyFileSync5,
15718
+ copyFileSync as copyFileSync6,
15628
15719
  existsSync as existsSync23,
15629
15720
  lstatSync as lstatSync3,
15630
15721
  mkdirSync as mkdirSync13,
@@ -15640,13 +15731,13 @@ import {
15640
15731
  } from "fs";
15641
15732
  import { createHash as createHash7 } from "crypto";
15642
15733
  import { tmpdir as tmpdir4 } from "os";
15643
- import { dirname as dirname14, isAbsolute as isAbsolute3, join as join35, relative as relative7, resolve as resolve10, sep as sep4 } from "path";
15734
+ import { dirname as dirname14, isAbsolute as isAbsolute4, join as join35, relative as relative7, resolve as resolve10, sep as sep4 } from "path";
15644
15735
 
15645
15736
  // ../producer/src/services/distributed/planV2Publisher.ts
15646
15737
  import {
15647
- copyFileSync as copyFileSync4,
15738
+ copyFileSync as copyFileSync5,
15648
15739
  existsSync as existsSync22,
15649
- linkSync,
15740
+ linkSync as linkSync2,
15650
15741
  mkdirSync as mkdirSync12,
15651
15742
  mkdtempSync as mkdtempSync5,
15652
15743
  renameSync as renameSync5,
@@ -15718,7 +15809,7 @@ var LocalPlanV2ArtifactPublisher = class {
15718
15809
  throw new PlanV2IntegrityError(`output directory already exists: ${destinationDir}`);
15719
15810
  }
15720
15811
  this.destinationDir = destinationDir;
15721
- this.#linkFile = options.linkFile ?? linkSync;
15812
+ this.#linkFile = options.linkFile ?? linkSync2;
15722
15813
  mkdirSync12(dirname13(destinationDir), { recursive: true });
15723
15814
  this.temporaryDir = mkdtempSync5(join34(dirname13(destinationDir), ".plan-v2-publish-"));
15724
15815
  }
@@ -15740,7 +15831,7 @@ var LocalPlanV2ArtifactPublisher = class {
15740
15831
  this.#linkFile(blob.sourcePath, temporaryPath);
15741
15832
  } catch (error) {
15742
15833
  if (!canFallbackToCopy(error)) throw error;
15743
- copyFileSync4(blob.sourcePath, temporaryPath);
15834
+ copyFileSync5(blob.sourcePath, temporaryPath);
15744
15835
  }
15745
15836
  renameSync5(temporaryPath, destinationPath);
15746
15837
  } finally {
@@ -15791,7 +15882,7 @@ function readJsonFile(path, label) {
15791
15882
  }
15792
15883
  function assertSafeRelativePath(path) {
15793
15884
  const normalized = path.split(/[\\/]+/);
15794
- if (path.length === 0 || isAbsolute3(path) || normalized.some((part) => part === "" || part === "." || part === "..")) {
15885
+ if (path.length === 0 || isAbsolute4(path) || normalized.some((part) => part === "" || part === "." || part === "..")) {
15795
15886
  throw new PlanV2IntegrityError(`unsafe artifact path: ${JSON.stringify(path)}`);
15796
15887
  }
15797
15888
  }
@@ -15873,7 +15964,7 @@ function artifactTargets(path, videoDependencies) {
15873
15964
  if (path === "meta/composition.json" || path === "meta/videos.json" || path.startsWith("compiled/")) {
15874
15965
  return { chunks: "all", assembler: false };
15875
15966
  }
15876
- if (path.startsWith("video-frames/")) {
15967
+ if (path.startsWith("video-frames/") || path.startsWith("video-sources/")) {
15877
15968
  return {
15878
15969
  chunks: videoDependencies === null ? "all" : videoDependencies.get(path) ?? [],
15879
15970
  assembler: false
@@ -15884,6 +15975,13 @@ function artifactTargets(path, videoDependencies) {
15884
15975
  function listVideoFramePaths(executionPlanDir, videos) {
15885
15976
  return videos.extracted.map((video) => {
15886
15977
  const outputDir = resolveExtractedVideoOutputDir(executionPlanDir, video.videoId);
15978
+ if (video.deferredRange) {
15979
+ const framePaths2 = /* @__PURE__ */ new Map();
15980
+ for (let index = 0; index < video.totalFrames; index++) {
15981
+ framePaths2.set(index, join35(outputDir, String(index)));
15982
+ }
15983
+ return { ...video, outputDir, framePaths: framePaths2, ownedByLookup: false };
15984
+ }
15887
15985
  const frameNames = readdirSync8(outputDir).sort();
15888
15986
  const framePaths = /* @__PURE__ */ new Map();
15889
15987
  for (const frameName of frameNames) {
@@ -15976,12 +16074,31 @@ function buildVideoChunkDependencies(executionPlanDir, dimensions) {
15976
16074
  extracted,
15977
16075
  resolveRenderFpsConfig({ num: fpsNum, den: fpsDen }).value
15978
16076
  );
16077
+ const deferredSources = new Map(
16078
+ parsedVideos.extracted.flatMap(
16079
+ (video) => video.deferredRange ? [[video.videoId, video.deferredRange.sourcePath]] : []
16080
+ )
16081
+ );
16082
+ const dependencies = collectChunkVideoDependencies({
16083
+ executionPlanDir,
16084
+ table,
16085
+ chunks: parsedChunks,
16086
+ fpsNum,
16087
+ fpsDen,
16088
+ deferredSources
16089
+ });
16090
+ return {
16091
+ mode: deferredSources.size > 0 ? "source-extract" : "exact-rendered-frames",
16092
+ dependencies
16093
+ };
16094
+ }
16095
+ function collectChunkVideoDependencies(input) {
15979
16096
  const mutable = /* @__PURE__ */ new Map();
15980
- for (const chunk of parsedChunks) {
16097
+ for (const chunk of input.chunks) {
15981
16098
  for (let frame = chunk.startFrame; frame < chunk.endFrame; frame++) {
15982
- const globalTime = frame * fpsDen / fpsNum;
15983
- for (const payload of table.getActiveFramePayloads(globalTime).values()) {
15984
- const path = relative7(resolve10(executionPlanDir), payload.framePath).split(sep4).join("/");
16099
+ const globalTime = frame * input.fpsDen / input.fpsNum;
16100
+ for (const [videoId, payload] of input.table.getActiveFramePayloads(globalTime)) {
16101
+ const path = input.deferredSources.get(videoId) ?? relative7(resolve10(input.executionPlanDir), payload.framePath).split(sep4).join("/");
15985
16102
  assertSafeRelativePath(path);
15986
16103
  const indexes = mutable.get(path) ?? /* @__PURE__ */ new Set();
15987
16104
  indexes.add(chunk.index);
@@ -15989,12 +16106,7 @@ function buildVideoChunkDependencies(executionPlanDir, dimensions) {
15989
16106
  }
15990
16107
  }
15991
16108
  }
15992
- return {
15993
- mode: "exact-rendered-frames",
15994
- dependencies: new Map(
15995
- [...mutable].map(([path, indexes]) => [path, [...indexes].sort((a, b) => a - b)])
15996
- )
15997
- };
16109
+ return new Map([...mutable].map(([path, indexes]) => [path, [...indexes].sort((a, b) => a - b)]));
15998
16110
  }
15999
16111
  function manifestPayload(manifest) {
16000
16112
  return manifest;
@@ -16008,7 +16120,7 @@ function writeBlob(sourcePath, destinationPath) {
16008
16120
  const temporaryDir = mkdtempSync6(join35(dirname14(destinationPath), ".plan-v2-blob-"));
16009
16121
  const temporaryPath = join35(temporaryDir, "blob");
16010
16122
  try {
16011
- copyFileSync5(sourcePath, temporaryPath);
16123
+ copyFileSync6(sourcePath, temporaryPath);
16012
16124
  renameSync6(temporaryPath, destinationPath);
16013
16125
  } finally {
16014
16126
  rmSync12(temporaryDir, { recursive: true, force: true });
@@ -16046,7 +16158,7 @@ function buildPlanV2Publication(executionPlanDir) {
16046
16158
  for (const file of listFiles(executionPlanDir)) {
16047
16159
  if (isExtractionCacheCompleteSentinelPath(file.path)) continue;
16048
16160
  const targets = artifactTargets(file.path, videoDependencyPlan.dependencies);
16049
- if (file.path.startsWith("video-frames/") && targets.chunks !== "all" && targets.chunks.length === 0 && !targets.assembler) {
16161
+ if ((file.path.startsWith("video-frames/") || file.path.startsWith("video-sources/")) && targets.chunks !== "all" && targets.chunks.length === 0 && !targets.assembler) {
16050
16162
  continue;
16051
16163
  }
16052
16164
  const sha256 = sha256File(file.absolutePath);
@@ -16114,14 +16226,21 @@ function createPlanV2FromV1(executionPlanDir, planV2Dir) {
16114
16226
  async function publishPlanV2FromExecutionPlan(executionPlanDir, publisher) {
16115
16227
  try {
16116
16228
  const publication = buildPlanV2Publication(executionPlanDir);
16117
- const concurrency = 16;
16118
- for (let offset = 0; offset < publication.blobs.length; offset += concurrency) {
16119
- const batch = publication.blobs.slice(offset, offset + concurrency);
16120
- const results = await Promise.allSettled(batch.map((blob) => publisher.putBlob(blob)));
16121
- for (const result of results) {
16122
- if (result.status === "rejected") throw result.reason;
16229
+ const uploadSlots = 32;
16230
+ let next = 0;
16231
+ let failure;
16232
+ const upload = async () => {
16233
+ while (!failure && next < publication.blobs.length) {
16234
+ const blob = publication.blobs[next++];
16235
+ try {
16236
+ await publisher.putBlob(blob);
16237
+ } catch (reason) {
16238
+ failure ??= { reason };
16239
+ }
16123
16240
  }
16124
- }
16241
+ };
16242
+ await Promise.all(Array.from({ length: uploadSlots }, upload));
16243
+ if (failure) throw failure.reason;
16125
16244
  await publisher.commitManifest(canonicalJsonStringify(publication.manifest));
16126
16245
  return publication.manifest;
16127
16246
  } catch (error) {
@@ -16139,7 +16258,8 @@ async function planV2WithPublisher(projectDir, config, publisher, options = {})
16139
16258
  const stagingRoot = mkdtempSync6(join35(options.stagingParentDir ?? tmpdir4(), ".execution-plan-"));
16140
16259
  try {
16141
16260
  await buildLocalExecutionPlan(projectDir, config, stagingRoot, {
16142
- executionPlanSizeLimitBytes: Number.MAX_SAFE_INTEGER
16261
+ executionPlanSizeLimitBytes: Number.MAX_SAFE_INTEGER,
16262
+ deferVideoExtraction: true
16143
16263
  });
16144
16264
  return await publishPlanV2FromExecutionPlan(stagingRoot, publisher);
16145
16265
  } catch (error) {
@@ -16268,7 +16388,7 @@ function parsePlanV2Manifest(value) {
16268
16388
  }
16269
16389
  if (!paths.has("plan.json"))
16270
16390
  throw new PlanV2IntegrityError("manifest must include the local execution plan.json artifact");
16271
- if (!isRecord3(value.limitations) || value.limitations.videoDependencyMode !== "exact-rendered-frames" && value.limitations.videoDependencyMode !== "full-source-pack") {
16391
+ if (!isRecord3(value.limitations) || value.limitations.videoDependencyMode !== "exact-rendered-frames" && value.limitations.videoDependencyMode !== "full-source-pack" && value.limitations.videoDependencyMode !== "source-extract") {
16272
16392
  throw new PlanV2IntegrityError("unsupported video dependency mode");
16273
16393
  }
16274
16394
  const parsed = {
@@ -16348,7 +16468,7 @@ function materializePlanV2Target(planV2Dir, target, destinationDir) {
16348
16468
  for (const { artifact, sourcePath } of verified) {
16349
16469
  const destinationPath = join35(tempDir, ...artifact.path.split("/"));
16350
16470
  mkdirSync13(dirname14(destinationPath), { recursive: true });
16351
- copyFileSync5(sourcePath, destinationPath);
16471
+ copyFileSync6(sourcePath, destinationPath);
16352
16472
  }
16353
16473
  if (target.role === "chunk") materializeExtractedVideoDirectories(tempDir);
16354
16474
  writeFileSync10(
@@ -16662,7 +16782,7 @@ function mergePngFrameDirs(chunkPaths, outputPath, totalFrames, audioPath, start
16662
16782
  // ../producer/src/services/distributed/renderChunk.ts
16663
16783
  import { randomBytes } from "crypto";
16664
16784
  import { existsSync as existsSync25, mkdirSync as mkdirSync15, readFileSync as readFileSync13, readdirSync as readdirSync10, rmSync as rmSync14, writeFileSync as writeFileSync12 } from "fs";
16665
- import { extname as extname5, join as join37 } from "path";
16785
+ import { extname as extname6, join as join37 } from "path";
16666
16786
  var FFMPEG_VERSION_MISMATCH = "FFMPEG_VERSION_MISMATCH";
16667
16787
  var PLAN_HASH_MISMATCH = "PLAN_HASH_MISMATCH";
16668
16788
  var MISSING_PLAN_ARTIFACT = "MISSING_PLAN_ARTIFACT";
@@ -16757,7 +16877,7 @@ function rebuildExtractedFramesFromPlanDir(planDir, videos, indexMode = "dense-v
16757
16877
  `[renderChunk] planDir missing extracted video frames for ${JSON.stringify(v.videoId)}: ${outputDir} not present. plan() should have written frames here; the planDir is malformed.`
16758
16878
  );
16759
16879
  }
16760
- const ext = (extname5(v.framePattern) || ".jpg").toLowerCase();
16880
+ const ext = (extname6(v.framePattern) || ".jpg").toLowerCase();
16761
16881
  const frames = readdirSync10(outputDir).filter((name) => name.toLowerCase().endsWith(ext)).sort((left, right) => {
16762
16882
  const leftNumber = frameNumberFromFileName(left);
16763
16883
  const rightNumber = frameNumberFromFileName(right);
@@ -16791,6 +16911,76 @@ function rebuildExtractedFramesFromPlanDir(planDir, videos, indexMode = "dense-v
16791
16911
  }
16792
16912
  return result;
16793
16913
  }
16914
+ function contiguousRuns(sortedIndexes) {
16915
+ const runs = [];
16916
+ for (const index of sortedIndexes) {
16917
+ const last = runs[runs.length - 1];
16918
+ if (last && last.firstFrame + last.frames === index) last.frames++;
16919
+ else runs.push({ firstFrame: index, frames: 1 });
16920
+ }
16921
+ return runs;
16922
+ }
16923
+ async function extractDeferredVideoFramesForChunk(input) {
16924
+ const deferred = input.planVideos.extracted.filter((video) => video.deferredRange);
16925
+ if (deferred.length === 0) return [];
16926
+ const table = createFrameLookupTable(
16927
+ input.planVideos.videos,
16928
+ deferred.map((video) => ({
16929
+ ...video,
16930
+ outputDir: input.outputRoot,
16931
+ framePaths: new Map(Array.from({ length: video.totalFrames }, (_, i) => [i, String(i)]))
16932
+ })),
16933
+ resolveRenderFpsConfig(input.fps).value
16934
+ );
16935
+ const shown = /* @__PURE__ */ new Map();
16936
+ for (let frame = input.slice.startFrame; frame < input.slice.endFrame; frame++) {
16937
+ const globalTime = frame * input.fps.den / input.fps.num;
16938
+ for (const [videoId, payload] of table.getActiveFramePayloads(globalTime)) {
16939
+ const indexes = shown.get(videoId) ?? /* @__PURE__ */ new Set();
16940
+ indexes.add(payload.frameIndex);
16941
+ shown.set(videoId, indexes);
16942
+ }
16943
+ }
16944
+ return Promise.all(
16945
+ deferred.map(async (video) => {
16946
+ const outputDir = join37(input.outputRoot, video.videoId);
16947
+ const indexes = [...shown.get(video.videoId) ?? []].sort((a, b) => a - b);
16948
+ if (indexes.length === 0) {
16949
+ return { ...video, outputDir, framePaths: /* @__PURE__ */ new Map(), ownedByLookup: false };
16950
+ }
16951
+ const range = video.deferredRange;
16952
+ const sourcePath = join37(input.planDir, ...range.sourcePath.split("/"));
16953
+ if (!existsSync25(sourcePath)) {
16954
+ throw new RenderChunkValidationError(
16955
+ MISSING_PLAN_ARTIFACT,
16956
+ `[renderChunk] planDir is missing the source for video ${JSON.stringify(video.videoId)}: ${range.sourcePath}`
16957
+ );
16958
+ }
16959
+ const extracted = await extractVideoFramesRange(
16960
+ sourcePath,
16961
+ video.videoId,
16962
+ range.startTime,
16963
+ range.durationSeconds,
16964
+ {
16965
+ fps: input.fps,
16966
+ outputDir: input.outputRoot,
16967
+ format: range.format,
16968
+ frameRanges: contiguousRuns(indexes)
16969
+ },
16970
+ void 0,
16971
+ input.cfg
16972
+ );
16973
+ const missing = indexes.find((index) => !extracted.framePaths.has(index));
16974
+ if (missing !== void 0) {
16975
+ throw new RenderChunkValidationError(
16976
+ INVALID_VIDEO_METADATA,
16977
+ `[renderChunk] video ${JSON.stringify(video.videoId)} has no frame ${missing}; the plan expected ${video.totalFrames} frames from ${range.sourcePath}.`
16978
+ );
16979
+ }
16980
+ return { ...video, outputDir, framePaths: extracted.framePaths, ownedByLookup: false };
16981
+ })
16982
+ );
16983
+ }
16794
16984
  function hashChunkOutput(outputPath, kind) {
16795
16985
  if (kind === "file") return sha256Hex(readFileSync13(outputPath));
16796
16986
  const entries = readdirSync10(outputPath).filter((name) => /\.(png|jpg|jpeg)$/i.test(name)).sort();
@@ -16924,23 +17114,34 @@ async function renderChunk(planDir, chunkIndex, outputChunkPath) {
16924
17114
  // the software-GPU clamp so buildChromeArgs includes BeginFrameControl.
16925
17115
  forceScreenshotExplicitlyOptedOut: !encoder.forceScreenshot
16926
17116
  };
17117
+ const workDir = `${outputChunkPath}.work.${process.pid}.${randomBytes(4).toString("hex")}`;
17118
+ mkdirSync15(workDir, { recursive: true });
17119
+ const framesDir = join37(workDir, "captured-frames");
17120
+ mkdirSync15(framesDir, { recursive: true });
17121
+ const videoFramesDir = `${workDir}.video-frames`;
16927
17122
  const videoFrameLookup = planVideos && planVideos.extracted.length > 0 ? createFrameLookupTable(
16928
17123
  planVideos.videos,
16929
- rebuildExtractedFramesFromPlanDir(
16930
- planDir,
16931
- planVideos.extracted,
16932
- v2Manifest === null ? "dense-v1" : "sparse-v2"
16933
- ),
17124
+ [
17125
+ ...rebuildExtractedFramesFromPlanDir(
17126
+ planDir,
17127
+ planVideos.extracted.filter((video) => !video.deferredRange),
17128
+ v2Manifest === null ? "dense-v1" : "sparse-v2"
17129
+ ),
17130
+ ...await extractDeferredVideoFramesForChunk({
17131
+ planDir,
17132
+ planVideos,
17133
+ slice,
17134
+ fps: { num: plan2.dimensions.fpsNum, den: plan2.dimensions.fpsDen },
17135
+ outputRoot: videoFramesDir,
17136
+ cfg
17137
+ })
17138
+ ],
16934
17139
  resolveRenderFpsConfig(job.config.fps).value
16935
17140
  ) : null;
16936
17141
  const createChunkVideoFrameInjector = createChunkVideoFrameInjectorFactory(videoFrameLookup);
16937
17142
  const videoCaptureBeyondViewport = resolveVideoCaptureBeyondViewport(
16938
17143
  planVideos?.videos.length ?? 0
16939
17144
  );
16940
- const workDir = `${outputChunkPath}.work.${process.pid}.${randomBytes(4).toString("hex")}`;
16941
- mkdirSync15(workDir, { recursive: true });
16942
- const framesDir = join37(workDir, "captured-frames");
16943
- mkdirSync15(framesDir, { recursive: true });
16944
17145
  const fileServer = await createFileServer({
16945
17146
  projectDir: compiledDir,
16946
17147
  compiledDir,
@@ -16963,6 +17164,7 @@ async function renderChunk(planDir, chunkIndex, outputChunkPath) {
16963
17164
  // declare `data-composition-variables` leave this undefined and the
16964
17165
  // engine skips the `evaluateOnNewDocument` injection.
16965
17166
  variables: encoder.variables,
17167
+ subTimelineWaitMemo: {},
16966
17168
  ...videoCaptureBeyondViewport !== void 0 ? { captureBeyondViewport: videoCaptureBeyondViewport } : {},
16967
17169
  // lock the BeginFrame warmup loop to a fixed iteration count so
16968
17170
  // `beginFrameTimeTicks` is host-independent. Only chunks ever set this.
@@ -17217,6 +17419,7 @@ async function renderChunk(planDir, chunkIndex, outputChunkPath) {
17217
17419
  `, "utf-8");
17218
17420
  try {
17219
17421
  rmSync14(workDir, { recursive: true, force: true, maxRetries: 3, retryDelay: 100 });
17422
+ rmSync14(videoFramesDir, { recursive: true, force: true, maxRetries: 3, retryDelay: 100 });
17220
17423
  } catch (err) {
17221
17424
  log.warn("[renderChunk] failed to remove work dir", {
17222
17425
  workDir,