@vfrey/vfrey 0.0.1 → 1.0.0-beta.0

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 (603) hide show
  1. package/LICENSE +33 -0
  2. package/README.md +78 -3
  3. package/accounts.example.json +61 -0
  4. package/accounts.first-run.json +41 -0
  5. package/bin/vfrey.mjs +36 -0
  6. package/integration-tools/README.md +43 -0
  7. package/integration-tools/image/pillow.md +32 -0
  8. package/integration-tools/image/playwright.md +33 -0
  9. package/integration-tools/image/resvg.md +36 -0
  10. package/integration-tools/image/satori.md +36 -0
  11. package/integration-tools/image/sharp.md +38 -0
  12. package/integration-tools/video/blender.md +34 -0
  13. package/integration-tools/video/ffmpeg.md +41 -0
  14. package/integration-tools/video/manim.md +37 -0
  15. package/integration-tools/video/motion-canvas.md +37 -0
  16. package/integration-tools/video/remotion.md +50 -0
  17. package/integration-tools/video/revideo.md +32 -0
  18. package/package.json +74 -6
  19. package/skills/vfrey-orchestrator/SKILL.md +15 -0
  20. package/skills/vfrey-orchestrator/channel-video/SKILL.md +41 -0
  21. package/skills/vfrey-product/SKILL.md +63 -0
  22. package/skills/vfrey-product/examples/concurrency-vs-parallelism/framey/cook-one.svg +14 -0
  23. package/skills/vfrey-product/examples/concurrency-vs-parallelism/framey/cook-two.svg +22 -0
  24. package/skills/vfrey-product/examples/concurrency-vs-parallelism/framey/index.html +70 -0
  25. package/skills/vfrey-product/examples/concurrency-vs-parallelism/remotion/cook-one.svg +14 -0
  26. package/skills/vfrey-product/examples/concurrency-vs-parallelism/remotion/cook-two.svg +22 -0
  27. package/skills/vfrey-product/examples/concurrency-vs-parallelism/remotion/index.tsx +49 -0
  28. package/skills/vfrey-product/examples/concurrency-vs-parallelism/script.json +15 -0
  29. package/skills/vfrey-product/examples/octopus-facts/index.html +60 -0
  30. package/skills/vfrey-product/examples/octopus-facts/octopus.svg +8 -0
  31. package/skills/vfrey-product/examples/octopus-facts/script.json +14 -0
  32. package/skills/vfrey-product/push/SKILL.md +15 -0
  33. package/skills/vfrey-product/scenes/NOTICE +5 -0
  34. package/skills/vfrey-product/scenes/blocks.md +57 -0
  35. package/skills/vfrey-product/scenes/craft.md +118 -0
  36. package/skills/vfrey-product/scenes/motion.md +88 -0
  37. package/src/analytics/dashboard.ts +109 -0
  38. package/src/analytics/index.ts +260 -0
  39. package/src/api/client.ts +282 -0
  40. package/src/api/commands.ts +330 -0
  41. package/src/api/config.ts +34 -0
  42. package/src/api/creators.ts +463 -0
  43. package/src/api/credentials.ts +152 -0
  44. package/src/api/mail.ts +333 -0
  45. package/src/api/topics.ts +207 -0
  46. package/src/api/types.ts +205 -0
  47. package/src/cli.ts +467 -0
  48. package/src/cloud/executor.ts +281 -0
  49. package/src/cloud/job.ts +106 -0
  50. package/src/cloud/render-job.ts +187 -0
  51. package/src/config.ts +309 -0
  52. package/src/dashboard-link.ts +180 -0
  53. package/src/dashboard-start.ts +103 -0
  54. package/src/desk/channel.ts +64 -0
  55. package/src/desk/cli.ts +216 -0
  56. package/src/desk/creators-route.ts +129 -0
  57. package/src/desk/fonts/JetBrainsMono-OFL.txt +93 -0
  58. package/src/desk/fonts/google-sans-flex-latin.woff2 +0 -0
  59. package/src/desk/fonts/jetbrains-mono-medium.woff2 +0 -0
  60. package/src/desk/http.ts +460 -0
  61. package/src/desk/mail-route.ts +103 -0
  62. package/src/desk/overlay.ts +112 -0
  63. package/src/desk/preview.ts +422 -0
  64. package/src/desk/screens.ts +149 -0
  65. package/src/desk/secrets.ts +143 -0
  66. package/src/desk/series.ts +127 -0
  67. package/src/desk/state.ts +77 -0
  68. package/src/desk/studio-route.ts +119 -0
  69. package/src/desk/tick-runner.ts +66 -0
  70. package/src/desk/tick.ts +56 -0
  71. package/src/desk/topics-route.ts +41 -0
  72. package/src/desk/ui/app.css +505 -0
  73. package/src/desk/ui/app.js +185 -0
  74. package/src/desk/ui/apple-icon.png +0 -0
  75. package/src/desk/ui/components.js +79 -0
  76. package/src/desk/ui/core.js +156 -0
  77. package/src/desk/ui/favicon.ico +0 -0
  78. package/src/desk/ui/icon.svg +1 -0
  79. package/src/desk/ui/icons.js +49 -0
  80. package/src/desk/ui/index.html +41 -0
  81. package/src/desk/ui/metrics-math.d.ts +22 -0
  82. package/src/desk/ui/metrics-math.js +135 -0
  83. package/src/desk/ui/theme.js +5 -0
  84. package/src/desk/ui/views-creators.js +209 -0
  85. package/src/desk/ui/views-keys.js +114 -0
  86. package/src/desk/ui/views-mail.js +188 -0
  87. package/src/desk/ui/views-misc.js +123 -0
  88. package/src/desk/ui/views-review.js +119 -0
  89. package/src/desk/ui/views-runs.js +350 -0
  90. package/src/desk/ui/views-screens.js +163 -0
  91. package/src/desk/ui/views-series.js +318 -0
  92. package/src/desk/ui/views-topics.js +87 -0
  93. package/src/desk/verbs.ts +361 -0
  94. package/src/doctor.ts +212 -0
  95. package/src/drain.ts +14 -0
  96. package/src/engage/index.ts +217 -0
  97. package/src/generate/index.ts +110 -0
  98. package/src/generate/script.ts +152 -0
  99. package/src/generate/title.ts +78 -0
  100. package/src/help.ts +233 -0
  101. package/src/home.ts +45 -0
  102. package/src/llm/client.ts +177 -0
  103. package/src/log.ts +7 -0
  104. package/src/oauth/tokens.ts +189 -0
  105. package/src/oauth/vault.ts +72 -0
  106. package/src/pipeline/review.ts +642 -0
  107. package/src/pipeline/run.ts +443 -0
  108. package/src/pipeline/series-guard.ts +26 -0
  109. package/src/pipeline/source-fetch.ts +69 -0
  110. package/src/pipeline/stages.ts +728 -0
  111. package/src/pipeline/topics-source.ts +90 -0
  112. package/src/product/commands.ts +296 -0
  113. package/src/product/config-file.ts +38 -0
  114. package/src/product/engine-choice.ts +89 -0
  115. package/src/product/engines.ts +103 -0
  116. package/src/product/insights.ts +50 -0
  117. package/src/product/keys.ts +67 -0
  118. package/src/product/paths.ts +18 -0
  119. package/src/product/probes.ts +88 -0
  120. package/src/product/push-flow.ts +90 -0
  121. package/src/product/render-video.ts +21 -0
  122. package/src/product/short.ts +62 -0
  123. package/src/product/update.ts +32 -0
  124. package/src/project/canonical.ts +14 -0
  125. package/src/project/commands.ts +177 -0
  126. package/src/project/dashboard-status.ts +28 -0
  127. package/src/project/discover.ts +19 -0
  128. package/src/project/index-file.ts +73 -0
  129. package/src/project/marker.ts +87 -0
  130. package/src/project/migrate.ts +201 -0
  131. package/src/project/names.ts +27 -0
  132. package/src/project/notice.ts +16 -0
  133. package/src/project/open.ts +88 -0
  134. package/src/project/scaffold.ts +112 -0
  135. package/src/project/templates.ts +42 -0
  136. package/src/project/videos.ts +64 -0
  137. package/src/publish/facebook.ts +91 -0
  138. package/src/publish/index.ts +12 -0
  139. package/src/publish/instagram.ts +97 -0
  140. package/src/publish/rate.ts +62 -0
  141. package/src/publish/session.ts +242 -0
  142. package/src/publish/tiktok.ts +202 -0
  143. package/src/publish/youtube.ts +177 -0
  144. package/src/queue/desk-ops.ts +1170 -0
  145. package/src/queue/seal.ts +3 -0
  146. package/src/queue/store.ts +1006 -0
  147. package/src/remotion/AiLabel.tsx +26 -0
  148. package/src/remotion/Root.tsx +73 -0
  149. package/src/remotion/defaults.ts +26 -0
  150. package/src/remotion/films/claude/ClaudeFilm.tsx +1014 -0
  151. package/src/remotion/films/engine/EngineMark.tsx +17 -0
  152. package/src/remotion/films/rea/ReaShort.tsx +552 -0
  153. package/src/remotion/films/rea/drawings.tsx +907 -0
  154. package/src/remotion/films/rea/timing.ts +144 -0
  155. package/src/remotion/index.ts +4 -0
  156. package/src/remotion/templates/EditorialSplit.tsx +39 -0
  157. package/src/remotion/templates/KineticType.tsx +39 -0
  158. package/src/remotion/templates/SignalBoard.tsx +50 -0
  159. package/src/remotion/timing.ts +22 -0
  160. package/src/render/chrome.ts +78 -0
  161. package/src/render/engine-mark.ts +29 -0
  162. package/src/render/framey-template.ts +130 -0
  163. package/src/render/html-engine.ts +149 -0
  164. package/src/render/node-crypto-stub.ts +11 -0
  165. package/src/render/probe.ts +29 -0
  166. package/src/render/props.ts +17 -0
  167. package/src/render/vertical-short.ts +35 -0
  168. package/src/render/webpack.ts +33 -0
  169. package/src/render/worker.ts +65 -0
  170. package/src/scene/assets/fonts/TitanOne-OFL.txt +94 -0
  171. package/src/scene/assets/fonts/titan-one.woff2 +0 -0
  172. package/src/scene/assets/gsap/LICENSE.txt +8 -0
  173. package/src/scene/assets/gsap/gsap.min.js +11 -0
  174. package/src/scene/audio.ts +54 -0
  175. package/src/scene/blocks/LICENSE +190 -0
  176. package/src/scene/blocks/NOTICE +5 -0
  177. package/src/scene/blocks/bar-chart-race/bar-chart-race.html +585 -0
  178. package/src/scene/blocks/beat-freeze-cut/beat-freeze-cut.html +874 -0
  179. package/src/scene/blocks/camcorder-hud/camcorder-hud.html +164 -0
  180. package/src/scene/blocks/camera-dolly-zoom/camera-dolly-zoom.html +355 -0
  181. package/src/scene/blocks/code-diff/code-diff.html +817 -0
  182. package/src/scene/blocks/code-snippet-apple-terminal-pro/code-snippet-apple-terminal-pro.html +248 -0
  183. package/src/scene/blocks/code-typing/code-typing.html +764 -0
  184. package/src/scene/blocks/data-chart/data-chart.html +452 -0
  185. package/src/scene/blocks/flowchart-vertical/flowchart-vertical.html +454 -0
  186. package/src/scene/blocks/hw-scribble-transition/hw-scribble-transition.html +153 -0
  187. package/src/scene/blocks/index.json +824 -0
  188. package/src/scene/blocks/lt-accent-underline/lt-accent-underline.html +107 -0
  189. package/src/scene/blocks/lt-bold-block/lt-bold-block.html +109 -0
  190. package/src/scene/blocks/lt-clean-bar/lt-clean-bar.html +112 -0
  191. package/src/scene/blocks/lt-dark-card/lt-dark-card.html +111 -0
  192. package/src/scene/blocks/lt-kicker-name/lt-kicker-name.html +114 -0
  193. package/src/scene/blocks/lt-mask-reveal/lt-mask-reveal.html +120 -0
  194. package/src/scene/blocks/lt-neon-border/lt-neon-border.html +391 -0
  195. package/src/scene/blocks/lt-stack-bars/lt-stack-bars.html +109 -0
  196. package/src/scene/blocks/macos-notification/macos-notification.html +194 -0
  197. package/src/scene/blocks/mk-background/mk-background.html +236 -0
  198. package/src/scene/blocks/mk-callout-highlight/mk-callout-highlight.html +183 -0
  199. package/src/scene/blocks/mk-clone-wall-transition/mk-clone-wall-transition.html +226 -0
  200. package/src/scene/blocks/mk-line-graph/mk-line-graph.html +293 -0
  201. package/src/scene/blocks/mk-progress-stat/mk-progress-stat.html +186 -0
  202. package/src/scene/blocks/mk-specs-list/mk-specs-list.html +223 -0
  203. package/src/scene/blocks/news-ticker/news-ticker.html +409 -0
  204. package/src/scene/blocks/organic-light-leak-overlay/organic-light-leak-overlay.html +126 -0
  205. package/src/scene/blocks/oscilloscope-trace/oscilloscope-trace.html +519 -0
  206. package/src/scene/blocks/snow/snow.html +205 -0
  207. package/src/scene/blocks/split-flap-board/split-flap-board.html +347 -0
  208. package/src/scene/blocks/spotify-card/spotify-card.html +294 -0
  209. package/src/scene/blocks/starfield/starfield.html +188 -0
  210. package/src/scene/blocks/thread-message-stack/thread-message-stack.html +239 -0
  211. package/src/scene/blocks/week-in-merges/week-in-merges.html +470 -0
  212. package/src/scene/blocks/x-post/x-post.html +437 -0
  213. package/src/scene/blocks/yt-comment-card/yt-comment-card.html +319 -0
  214. package/src/scene/blocks/yt-lcd-background/yt-lcd-background.html +307 -0
  215. package/src/scene/blocks/yt-prism-title/yt-prism-title.html +205 -0
  216. package/src/scene/blocks.ts +229 -0
  217. package/src/scene/command.ts +272 -0
  218. package/src/scene/figure.ts +181 -0
  219. package/src/scene/glyphs.ts +107 -0
  220. package/src/scene/init.ts +86 -0
  221. package/src/scene/inspect/css-tree.d.ts +6 -0
  222. package/src/scene/inspect/page-scripts.ts +272 -0
  223. package/src/scene/inspect/report.ts +405 -0
  224. package/src/scene/inspect/run.ts +200 -0
  225. package/src/scene/inspect/source.ts +236 -0
  226. package/src/scene/label.ts +131 -0
  227. package/src/scene/net-guard.ts +74 -0
  228. package/src/scene/render.ts +292 -0
  229. package/src/scene/runtime/browser.ts +199 -0
  230. package/src/scene/runtime/core.ts +181 -0
  231. package/src/scene/runtime/react.tsx +115 -0
  232. package/src/scene/runtime/transitions.ts +133 -0
  233. package/src/scene/sanitize.ts +181 -0
  234. package/src/scene/scene.ts +152 -0
  235. package/src/scene/studio-command.ts +48 -0
  236. package/src/scene/studio-skin.ts +59 -0
  237. package/src/scene/studio.ts +337 -0
  238. package/src/scene/supply.ts +111 -0
  239. package/src/scene/timing.ts +288 -0
  240. package/src/scene/transitions/LICENSE +190 -0
  241. package/src/scene/transitions/NOTICE +5 -0
  242. package/src/scene/transitions/SOURCE.json +24 -0
  243. package/src/scene/transitions/transitions.global.js +38 -0
  244. package/src/scene/transitions.ts +26 -0
  245. package/src/service/all-projects.ts +153 -0
  246. package/src/service/commands.ts +256 -0
  247. package/src/service/due.ts +82 -0
  248. package/src/service/lock.ts +101 -0
  249. package/src/service/log-file.ts +56 -0
  250. package/src/service/state.ts +41 -0
  251. package/src/service/units.ts +90 -0
  252. package/src/service/worker.ts +51 -0
  253. package/src/skill-agents.ts +74 -0
  254. package/src/skill-install.ts +334 -0
  255. package/src/sync-write.ts +21 -0
  256. package/src/tick-report.ts +205 -0
  257. package/src/tts.ts +124 -0
  258. package/vendor/@vfrey/contracts/dist/account.d.ts +97 -0
  259. package/vendor/@vfrey/contracts/dist/account.js +27 -0
  260. package/vendor/@vfrey/contracts/dist/checks.d.ts +8 -0
  261. package/vendor/@vfrey/contracts/dist/checks.js +1 -0
  262. package/vendor/@vfrey/contracts/dist/credentials/crypto.d.ts +4 -0
  263. package/vendor/@vfrey/contracts/dist/credentials/crypto.js +38 -0
  264. package/vendor/@vfrey/contracts/dist/domain/advice-persona.d.ts +10 -0
  265. package/vendor/@vfrey/contracts/dist/domain/advice-persona.js +24 -0
  266. package/vendor/@vfrey/contracts/dist/domain/backoff.d.ts +13 -0
  267. package/vendor/@vfrey/contracts/dist/domain/backoff.js +27 -0
  268. package/vendor/@vfrey/contracts/dist/domain/cadence.d.ts +29 -0
  269. package/vendor/@vfrey/contracts/dist/domain/cadence.js +95 -0
  270. package/vendor/@vfrey/contracts/dist/domain/creators.d.ts +146 -0
  271. package/vendor/@vfrey/contracts/dist/domain/creators.js +2 -0
  272. package/vendor/@vfrey/contracts/dist/domain/disclosure.d.ts +127 -0
  273. package/vendor/@vfrey/contracts/dist/domain/disclosure.js +250 -0
  274. package/vendor/@vfrey/contracts/dist/domain/errors.d.ts +34 -0
  275. package/vendor/@vfrey/contracts/dist/domain/errors.js +68 -0
  276. package/vendor/@vfrey/contracts/dist/domain/redact.d.ts +1 -0
  277. package/vendor/@vfrey/contracts/dist/domain/redact.js +21 -0
  278. package/vendor/@vfrey/contracts/dist/domain/revenue.d.ts +13 -0
  279. package/vendor/@vfrey/contracts/dist/domain/revenue.js +16 -0
  280. package/vendor/@vfrey/contracts/dist/domain/safety.d.ts +20 -0
  281. package/vendor/@vfrey/contracts/dist/domain/safety.js +61 -0
  282. package/vendor/@vfrey/contracts/dist/domain/similarity.d.ts +13 -0
  283. package/vendor/@vfrey/contracts/dist/domain/similarity.js +100 -0
  284. package/vendor/@vfrey/contracts/dist/domain/templates.d.ts +18 -0
  285. package/vendor/@vfrey/contracts/dist/domain/templates.js +67 -0
  286. package/vendor/@vfrey/contracts/dist/domain/tiktok-chunks.d.ts +19 -0
  287. package/vendor/@vfrey/contracts/dist/domain/tiktok-chunks.js +52 -0
  288. package/vendor/@vfrey/contracts/dist/domain/topics.d.ts +78 -0
  289. package/vendor/@vfrey/contracts/dist/domain/topics.js +4 -0
  290. package/vendor/@vfrey/contracts/dist/domain/types.d.ts +216 -0
  291. package/vendor/@vfrey/contracts/dist/domain/types.js +1 -0
  292. package/vendor/@vfrey/contracts/dist/domain/variation.d.ts +57 -0
  293. package/vendor/@vfrey/contracts/dist/domain/variation.js +278 -0
  294. package/vendor/@vfrey/contracts/dist/events.d.ts +20 -0
  295. package/vendor/@vfrey/contracts/dist/events.js +1 -0
  296. package/vendor/@vfrey/contracts/dist/http.d.ts +11 -0
  297. package/vendor/@vfrey/contracts/dist/http.js +37 -0
  298. package/vendor/@vfrey/contracts/dist/index.d.ts +22 -0
  299. package/vendor/@vfrey/contracts/dist/index.js +22 -0
  300. package/vendor/@vfrey/contracts/dist/log.d.ts +2 -0
  301. package/vendor/@vfrey/contracts/dist/log.js +10 -0
  302. package/vendor/@vfrey/contracts/dist/mail.d.ts +55 -0
  303. package/vendor/@vfrey/contracts/dist/mail.js +1 -0
  304. package/vendor/@vfrey/contracts/package.json +18 -0
  305. package/vendor/@vfrey/ingest/dist/index.d.ts +41 -0
  306. package/vendor/@vfrey/ingest/dist/index.js +221 -0
  307. package/vendor/@vfrey/ingest/dist/parse.d.ts +5 -0
  308. package/vendor/@vfrey/ingest/dist/parse.js +165 -0
  309. package/vendor/@vfrey/ingest/package.json +21 -0
  310. package/vendor/framey/LICENSE +190 -0
  311. package/vendor/framey/NOTICE +15 -0
  312. package/vendor/framey/SOURCE.json +24 -0
  313. package/vendor/framey/STUDIO-SOURCE.json +9 -0
  314. package/vendor/framey/bin/framey-localize-fonts.mjs +12 -0
  315. package/vendor/framey/bin/framey.mjs +16 -0
  316. package/vendor/framey/dist/add-VMJD5KBS.js +75 -0
  317. package/vendor/framey/dist/animatedGifPrep-QPKGJ6PM.js +43 -0
  318. package/vendor/framey/dist/api.d.ts +211 -0
  319. package/vendor/framey/dist/api.js +76 -0
  320. package/vendor/framey/dist/appHistory-WW56FZTT.js +31 -0
  321. package/vendor/framey/dist/asset-WQKGOELE.js +26 -0
  322. package/vendor/framey/dist/audio-RSJWVWRA.js +1936 -0
  323. package/vendor/framey/dist/batchRender-3HPICDCT.js +366 -0
  324. package/vendor/framey/dist/beats-HL2BDUZI.js +273 -0
  325. package/vendor/framey/dist/benchmark-RWCWHI5Z.js +230 -0
  326. package/vendor/framey/dist/browser-ECYET3Q2.js +206 -0
  327. package/vendor/framey/dist/bundleWithLocalizedFonts-ALYBQEQT.js +52 -0
  328. package/vendor/framey/dist/captureCompositionFrame-4DA6SEH2.js +94 -0
  329. package/vendor/framey/dist/catalog-5JVDEUWK.js +979 -0
  330. package/vendor/framey/dist/catch-up-NEBCL5NO.js +106 -0
  331. package/vendor/framey/dist/check-F5N544ML.js +111 -0
  332. package/vendor/framey/dist/checkBrowser-LZ66CMJG.js +110 -0
  333. package/vendor/framey/dist/chunk-2K7Z2HVP.js +372 -0
  334. package/vendor/framey/dist/chunk-2UZQHDM7.js +323 -0
  335. package/vendor/framey/dist/chunk-2X4PQEYM.js +34 -0
  336. package/vendor/framey/dist/chunk-3422KMTD.js +168 -0
  337. package/vendor/framey/dist/chunk-3FYD4YEK.js +72 -0
  338. package/vendor/framey/dist/chunk-3GXQPCJC.js +682 -0
  339. package/vendor/framey/dist/chunk-3LM6YPBR.js +179 -0
  340. package/vendor/framey/dist/chunk-442JNXRM.js +20 -0
  341. package/vendor/framey/dist/chunk-4BNN5FGX.js +182 -0
  342. package/vendor/framey/dist/chunk-4P7NX5BM.js +11532 -0
  343. package/vendor/framey/dist/chunk-4UMPIPCQ.js +88 -0
  344. package/vendor/framey/dist/chunk-4YYJOFKS.js +28 -0
  345. package/vendor/framey/dist/chunk-54HJ63Q2.js +29 -0
  346. package/vendor/framey/dist/chunk-5ETJX6WM.js +89 -0
  347. package/vendor/framey/dist/chunk-5SG54JRS.js +68 -0
  348. package/vendor/framey/dist/chunk-634HSJ3J.js +58 -0
  349. package/vendor/framey/dist/chunk-66LREXGS.js +48 -0
  350. package/vendor/framey/dist/chunk-6BEFEWFB.js +25 -0
  351. package/vendor/framey/dist/chunk-6BNTGNGD.js +286 -0
  352. package/vendor/framey/dist/chunk-6DDPOHMK.js +140 -0
  353. package/vendor/framey/dist/chunk-6GV5XSOR.js +214 -0
  354. package/vendor/framey/dist/chunk-6JR2XUEE.js +127 -0
  355. package/vendor/framey/dist/chunk-73QVATIM.js +362 -0
  356. package/vendor/framey/dist/chunk-7FMUTGOH.js +279 -0
  357. package/vendor/framey/dist/chunk-7JQFJ6JJ.js +291 -0
  358. package/vendor/framey/dist/chunk-AHPGAESX.js +113 -0
  359. package/vendor/framey/dist/chunk-AHX34EFP.js +15 -0
  360. package/vendor/framey/dist/chunk-AJ5CSAEZ.js +487 -0
  361. package/vendor/framey/dist/chunk-B7RJV74O.js +5047 -0
  362. package/vendor/framey/dist/chunk-BL4U6U52.js +254 -0
  363. package/vendor/framey/dist/chunk-BSQ7XANM.js +210 -0
  364. package/vendor/framey/dist/chunk-BZ56MTDX.js +6 -0
  365. package/vendor/framey/dist/chunk-C5BO7PMT.js +282 -0
  366. package/vendor/framey/dist/chunk-CFUCHO4T.js +358 -0
  367. package/vendor/framey/dist/chunk-CZGHFATT.js +31 -0
  368. package/vendor/framey/dist/chunk-DLA44CMS.js +5649 -0
  369. package/vendor/framey/dist/chunk-DPVXBVLL.js +31292 -0
  370. package/vendor/framey/dist/chunk-DQBY7FRR.js +397 -0
  371. package/vendor/framey/dist/chunk-EAMLBAHA.js +154 -0
  372. package/vendor/framey/dist/chunk-EOVYQ3IG.js +143 -0
  373. package/vendor/framey/dist/chunk-EVMY7IPL.js +612 -0
  374. package/vendor/framey/dist/chunk-FG4BBFZI.js +122 -0
  375. package/vendor/framey/dist/chunk-FI4I7CME.js +56 -0
  376. package/vendor/framey/dist/chunk-FLREUEHW.js +2081 -0
  377. package/vendor/framey/dist/chunk-FUFP7A7S.js +1126 -0
  378. package/vendor/framey/dist/chunk-FV3PIKGH.js +56 -0
  379. package/vendor/framey/dist/chunk-FXMKHHPO.js +123 -0
  380. package/vendor/framey/dist/chunk-GGZAM5VH.js +1187 -0
  381. package/vendor/framey/dist/chunk-GKZEVJIB.js +39 -0
  382. package/vendor/framey/dist/chunk-GMECXFAN.js +57 -0
  383. package/vendor/framey/dist/chunk-GNEFDLFB.js +621 -0
  384. package/vendor/framey/dist/chunk-GPMLSOEG.js +19274 -0
  385. package/vendor/framey/dist/chunk-GPYVT5EE.js +59 -0
  386. package/vendor/framey/dist/chunk-H6IEMZEV.js +40 -0
  387. package/vendor/framey/dist/chunk-HEFQCIXR.js +170 -0
  388. package/vendor/framey/dist/chunk-HFQ4CWHA.js +118 -0
  389. package/vendor/framey/dist/chunk-HPDTCOKE.js +304 -0
  390. package/vendor/framey/dist/chunk-HTUHQKDB.js +548 -0
  391. package/vendor/framey/dist/chunk-HU2SPFNG.js +103 -0
  392. package/vendor/framey/dist/chunk-HVW7ABXD.js +19 -0
  393. package/vendor/framey/dist/chunk-IG7NDKXO.js +26 -0
  394. package/vendor/framey/dist/chunk-II3J3WXK.js +246 -0
  395. package/vendor/framey/dist/chunk-IR35BCLK.js +13 -0
  396. package/vendor/framey/dist/chunk-ISN5GRYI.js +20 -0
  397. package/vendor/framey/dist/chunk-IUONB55J.js +669 -0
  398. package/vendor/framey/dist/chunk-IVSUQR2B.js +161 -0
  399. package/vendor/framey/dist/chunk-IXU6PQSW.js +259 -0
  400. package/vendor/framey/dist/chunk-IZCW2NKT.js +29 -0
  401. package/vendor/framey/dist/chunk-JGXJU5PF.js +68 -0
  402. package/vendor/framey/dist/chunk-JHOCK3DG.js +27 -0
  403. package/vendor/framey/dist/chunk-JVBRJMOP.js +121 -0
  404. package/vendor/framey/dist/chunk-K4MJX7SR.js +17 -0
  405. package/vendor/framey/dist/chunk-K4WKGXRC.js +18 -0
  406. package/vendor/framey/dist/chunk-KGPLIH7B.js +127 -0
  407. package/vendor/framey/dist/chunk-KLIKCX6Q.js +63 -0
  408. package/vendor/framey/dist/chunk-KXTKKBOC.js +61 -0
  409. package/vendor/framey/dist/chunk-KZI44OPA.js +185 -0
  410. package/vendor/framey/dist/chunk-LEKZNRKI.js +45 -0
  411. package/vendor/framey/dist/chunk-LFGJWOVA.js +61 -0
  412. package/vendor/framey/dist/chunk-LLMSX6V6.js +17 -0
  413. package/vendor/framey/dist/chunk-LTGTN2TH.js +195 -0
  414. package/vendor/framey/dist/chunk-M2WBOQ2Q.js +54 -0
  415. package/vendor/framey/dist/chunk-MI5FTLYK.js +399 -0
  416. package/vendor/framey/dist/chunk-MLQP2QUF.js +1809 -0
  417. package/vendor/framey/dist/chunk-MMQ52NIZ.js +956 -0
  418. package/vendor/framey/dist/chunk-ND46XKK3.js +742 -0
  419. package/vendor/framey/dist/chunk-NYEXNSHM.js +504 -0
  420. package/vendor/framey/dist/chunk-O4YRB27L.js +57 -0
  421. package/vendor/framey/dist/chunk-O7BGSQ5F.js +92 -0
  422. package/vendor/framey/dist/chunk-OFQWTKPW.js +117 -0
  423. package/vendor/framey/dist/chunk-P5ZBLXJ6.js +91 -0
  424. package/vendor/framey/dist/chunk-P6LJ4Y32.js +4662 -0
  425. package/vendor/framey/dist/chunk-PKZ7RK5N.js +281 -0
  426. package/vendor/framey/dist/chunk-PURHAXFL.js +15 -0
  427. package/vendor/framey/dist/chunk-Q5X2B5WT.js +29 -0
  428. package/vendor/framey/dist/chunk-QAMKOG67.js +248 -0
  429. package/vendor/framey/dist/chunk-R6YBK4XX.js +514 -0
  430. package/vendor/framey/dist/chunk-RGLQURIX.js +2997 -0
  431. package/vendor/framey/dist/chunk-RNV3DM4S.js +3573 -0
  432. package/vendor/framey/dist/chunk-ROEW726S.js +4638 -0
  433. package/vendor/framey/dist/chunk-RQVDTPGD.js +6 -0
  434. package/vendor/framey/dist/chunk-RVZHGOGR.js +26 -0
  435. package/vendor/framey/dist/chunk-RXATE6FZ.js +385 -0
  436. package/vendor/framey/dist/chunk-S3S4TGEH.js +424 -0
  437. package/vendor/framey/dist/chunk-SDYDNHEE.js +11202 -0
  438. package/vendor/framey/dist/chunk-SSWBU67I.js +173 -0
  439. package/vendor/framey/dist/chunk-ST35C4K6.js +28 -0
  440. package/vendor/framey/dist/chunk-SZNTYTIV.js +990 -0
  441. package/vendor/framey/dist/chunk-T2EUWCJE.js +29 -0
  442. package/vendor/framey/dist/chunk-T6AGUTZJ.js +444 -0
  443. package/vendor/framey/dist/chunk-THJALHFJ.js +11131 -0
  444. package/vendor/framey/dist/chunk-TIQB63MX.js +18128 -0
  445. package/vendor/framey/dist/chunk-U242RTCT.js +134 -0
  446. package/vendor/framey/dist/chunk-UJZREAV6.js +3901 -0
  447. package/vendor/framey/dist/chunk-UMD3V7CU.js +264 -0
  448. package/vendor/framey/dist/chunk-UOFAE5RF.js +42 -0
  449. package/vendor/framey/dist/chunk-UTEIUGAZ.js +29 -0
  450. package/vendor/framey/dist/chunk-VAS6HQX3.js +138 -0
  451. package/vendor/framey/dist/chunk-VC76R6W2.js +27 -0
  452. package/vendor/framey/dist/chunk-VFZ7W5W7.js +226 -0
  453. package/vendor/framey/dist/chunk-VHNLZAE2.js +348 -0
  454. package/vendor/framey/dist/chunk-VMC4WSH5.js +278 -0
  455. package/vendor/framey/dist/chunk-VORQIH64.js +108 -0
  456. package/vendor/framey/dist/chunk-VTXFRIHO.js +186 -0
  457. package/vendor/framey/dist/chunk-W2LGJSEN.js +182 -0
  458. package/vendor/framey/dist/chunk-WKBM7NDG.js +32 -0
  459. package/vendor/framey/dist/chunk-WMQNIQDJ.js +2057 -0
  460. package/vendor/framey/dist/chunk-WN4XZC5F.js +504 -0
  461. package/vendor/framey/dist/chunk-WQ6ZXHFQ.js +133 -0
  462. package/vendor/framey/dist/chunk-X7HBSTCZ.js +53 -0
  463. package/vendor/framey/dist/chunk-X7MTZ4T2.js +6 -0
  464. package/vendor/framey/dist/chunk-XPTOJZJF.js +308 -0
  465. package/vendor/framey/dist/chunk-XT6MXC7A.js +6 -0
  466. package/vendor/framey/dist/chunk-XT7X6QCP.js +6 -0
  467. package/vendor/framey/dist/chunk-XTMDWNEC.js +2820 -0
  468. package/vendor/framey/dist/chunk-XUHOIDKG.js +6 -0
  469. package/vendor/framey/dist/chunk-XX7LTW5Y.js +138 -0
  470. package/vendor/framey/dist/chunk-Y3YGTZEG.js +382 -0
  471. package/vendor/framey/dist/chunk-Y5SBSGN7.js +346 -0
  472. package/vendor/framey/dist/chunk-YCMVI4MZ.js +625 -0
  473. package/vendor/framey/dist/chunk-YOR4CTCE.js +261 -0
  474. package/vendor/framey/dist/chunk-YPRBGITP.js +2748 -0
  475. package/vendor/framey/dist/chunk-ZKDMAOFU.js +32 -0
  476. package/vendor/framey/dist/chunk-ZW6DURPF.js +1318 -0
  477. package/vendor/framey/dist/clean-ZJOGDKDM.js +336 -0
  478. package/vendor/framey/dist/cli.js +439 -0
  479. package/vendor/framey/dist/cloudrun-HGJ3B6ZV.js +767 -0
  480. package/vendor/framey/dist/commands/contrast-audit.browser.js +643 -0
  481. package/vendor/framey/dist/commands/layout-audit.browser.js +2914 -0
  482. package/vendor/framey/dist/commands/motion-sample.browser.js +74 -0
  483. package/vendor/framey/dist/commands/motion-signature.browser.js +475 -0
  484. package/vendor/framey/dist/compare-W7UY3BAZ.js +463 -0
  485. package/vendor/framey/dist/compiler-TM3W6GYF.js +136 -0
  486. package/vendor/framey/dist/component-QF5VGYMU.js +176 -0
  487. package/vendor/framey/dist/compositions-XT3PMNDF.js +238 -0
  488. package/vendor/framey/dist/contactSheet-7W6GYHBQ.js +24 -0
  489. package/vendor/framey/dist/deploy-6FJPWKF2.js +299 -0
  490. package/vendor/framey/dist/destroy-HE2RIPKZ.js +57 -0
  491. package/vendor/framey/dist/deterministicFonts-RADD3BSX.js +50 -0
  492. package/vendor/framey/dist/dist-4S2FGGVY.js +422 -0
  493. package/vendor/framey/dist/dist-BE4B2EZE.js +32 -0
  494. package/vendor/framey/dist/dist-EWXJGN63.js +129 -0
  495. package/vendor/framey/dist/docs-VKIRFEEX.js +131 -0
  496. package/vendor/framey/dist/doctor-2UNJ2G7U.js +74 -0
  497. package/vendor/framey/dist/dom-37K6YOH4.js +14 -0
  498. package/vendor/framey/dist/dotEnv-7PZQTVIM.js +54 -0
  499. package/vendor/framey/dist/events-ACY3P2PA.js +76 -0
  500. package/vendor/framey/dist/events-IHB3B2MK.js +69 -0
  501. package/vendor/framey/dist/ffmpeg-DR5LGGSK.js +63 -0
  502. package/vendor/framey/dist/figma-BODVUPHB.js +63 -0
  503. package/vendor/framey/dist/fontData.generated-NXAOI4GH.js +13 -0
  504. package/vendor/framey/dist/fontLocalizeCli.js +142 -0
  505. package/vendor/framey/dist/gpuPolicy-XLEXORZY.js +49 -0
  506. package/vendor/framey/dist/grade-compare-GAXFQ74C.js +661 -0
  507. package/vendor/framey/dist/gsapParser-IEUSLYDJ.js +2885 -0
  508. package/vendor/framey/dist/gsapParserAcorn-LZJKCFQI.js +30 -0
  509. package/vendor/framey/dist/help-VCB5X2HS.js +184 -0
  510. package/vendor/framey/dist/history-ENGZEVFT.js +471 -0
  511. package/vendor/framey/dist/hyperframe.manifest.json +22 -0
  512. package/vendor/framey/dist/hyperframe.runtime.iife.js +1132 -0
  513. package/vendor/framey/dist/hyperframes-player.global.js +478 -0
  514. package/vendor/framey/dist/hyperframes-slideshow.global.js +148 -0
  515. package/vendor/framey/dist/info-WPCJHBMU.js +182 -0
  516. package/vendor/framey/dist/init-G4WGLYGD.js +1176 -0
  517. package/vendor/framey/dist/inspect-5IQ6CNEQ.js +106 -0
  518. package/vendor/framey/dist/installer-ML4HWUV7.js +40 -0
  519. package/vendor/framey/dist/keyframes-Q6XJO7VW.js +2755 -0
  520. package/vendor/framey/dist/lambda-A7JC74JF.js +468 -0
  521. package/vendor/framey/dist/layout-YET6XNXA.js +95 -0
  522. package/vendor/framey/dist/lint-I7FZN2VJ.js +162 -0
  523. package/vendor/framey/dist/lintProject-PDB3UN72.js +30 -0
  524. package/vendor/framey/dist/manager-CD6LJ7ZN.js +45 -0
  525. package/vendor/framey/dist/manager-WA4F2GST.js +67 -0
  526. package/vendor/framey/dist/media-treatment-BXYS4WVA.js +1030 -0
  527. package/vendor/framey/dist/media-use-LWH3MANK.js +113 -0
  528. package/vendor/framey/dist/models-K363FYM4.js +195 -0
  529. package/vendor/framey/dist/motionShot-GPAVWXLH.js +640 -0
  530. package/vendor/framey/dist/normalize-FASIPBUM.js +24 -0
  531. package/vendor/framey/dist/normalize-audio-VDWYRHN6.js +268 -0
  532. package/vendor/framey/dist/open-E3TB6P6J.js +128 -0
  533. package/vendor/framey/dist/parakeetRunner-UP34UOI2.js +58 -0
  534. package/vendor/framey/dist/pipeline-VXIUYEBU.js +64 -0
  535. package/vendor/framey/dist/play-BUTDQ4DV.js +353 -0
  536. package/vendor/framey/dist/policies-OLDYGFK5.js +309 -0
  537. package/vendor/framey/dist/preflight-2KZ2GWAZ.js +55 -0
  538. package/vendor/framey/dist/present-GXYSM7NX.js +353 -0
  539. package/vendor/framey/dist/preview-EKZ33JOJ.js +1910 -0
  540. package/vendor/framey/dist/producer-SKU5EV3J.js +13 -0
  541. package/vendor/framey/dist/progress-ZWB4Z4ET.js +76 -0
  542. package/vendor/framey/dist/projectConfig-3MZAYVTS.js +60 -0
  543. package/vendor/framey/dist/publication-DTKWNF74.js +33 -0
  544. package/vendor/framey/dist/remove-background-OY5L7XN2.js +265 -0
  545. package/vendor/framey/dist/render-CDV4GDFX.js +187 -0
  546. package/vendor/framey/dist/render-YE5YAMOD.js +2620 -0
  547. package/vendor/framey/dist/render-batch-ZAMFPCLL.js +274 -0
  548. package/vendor/framey/dist/renderSetupWorker.js +120 -0
  549. package/vendor/framey/dist/resolver-D5BIPSEW.js +42 -0
  550. package/vendor/framey/dist/runtimeVersion.js +18 -0
  551. package/vendor/framey/dist/sam-WFZXI4F7.js +23 -0
  552. package/vendor/framey/dist/shaderTransitionWorker.js +44 -0
  553. package/vendor/framey/dist/sherpa-RQWLV7I3.js +79 -0
  554. package/vendor/framey/dist/sherpaWorker.js +84 -0
  555. package/vendor/framey/dist/sites-AMOVABTK.js +54 -0
  556. package/vendor/framey/dist/skill-ZHVLH7KX.js +15 -0
  557. package/vendor/framey/dist/slideshow-SJGK4RQS.js +24 -0
  558. package/vendor/framey/dist/snapshot-TUXL6LBQ.js +1515 -0
  559. package/vendor/framey/dist/src-JHQGB2S6.js +215 -0
  560. package/vendor/framey/dist/src-Z5PGEMXB.js +532 -0
  561. package/vendor/framey/dist/state-B6H3WHCF.js +28 -0
  562. package/vendor/framey/dist/staticProjectServer-DFVZOUGI.js +63 -0
  563. package/vendor/framey/dist/studio/assets/hyperframes-player-DLaKjw0L.js +478 -0
  564. package/vendor/framey/dist/studio/assets/index-BX3KHhGX.js +71 -0
  565. package/vendor/framey/dist/studio/assets/index-CYbvOVp-.css +1 -0
  566. package/vendor/framey/dist/studio/assets/index-Dp3QEUGL.js +402 -0
  567. package/vendor/framey/dist/studio/assets/index-qrTAXbqc.js +531 -0
  568. package/vendor/framey/dist/studio/favicon.svg +14 -0
  569. package/vendor/framey/dist/studio/icons/timeline/audio.svg +7 -0
  570. package/vendor/framey/dist/studio/icons/timeline/captions.svg +5 -0
  571. package/vendor/framey/dist/studio/icons/timeline/composition.svg +12 -0
  572. package/vendor/framey/dist/studio/icons/timeline/image.svg +18 -0
  573. package/vendor/framey/dist/studio/icons/timeline/music.svg +10 -0
  574. package/vendor/framey/dist/studio/icons/timeline/text.svg +3 -0
  575. package/vendor/framey/dist/studio/index.html +23 -0
  576. package/vendor/framey/dist/studio-api-2NECGRMB.js +179 -0
  577. package/vendor/framey/dist/studioSelectionClient-IUUPKUHZ.js +25 -0
  578. package/vendor/framey/dist/studioServer-N2OPUMOQ.js +1569 -0
  579. package/vendor/framey/dist/synthesize-PKTB5ATG.js +183 -0
  580. package/vendor/framey/dist/system-7F3UEHQT.js +27 -0
  581. package/vendor/framey/dist/telemetry-DQGPEKM6.js +145 -0
  582. package/vendor/framey/dist/telemetry-UN55N6U6.js +77 -0
  583. package/vendor/framey/dist/timeline-LHUUMK63.js +1295 -0
  584. package/vendor/framey/dist/tokens-OLECWDFK.js +92 -0
  585. package/vendor/framey/dist/transcribe-O7HQKMIV.js +331 -0
  586. package/vendor/framey/dist/transcribe-UJESPBT5.js +76 -0
  587. package/vendor/framey/dist/tts-YCCQHZD4.js +234 -0
  588. package/vendor/framey/dist/urlDownloader-H2LXLG4U.js +48 -0
  589. package/vendor/framey/dist/usage-HG4WMM7A.js +2167 -0
  590. package/vendor/framey/dist/validate-F2XMN6EV.js +87 -0
  591. package/vendor/framey/dist/vendor/npm/gsap@3.15.0/GSAP-LICENSE.txt +8 -0
  592. package/vendor/framey/dist/vendor/npm/gsap@3.15.0/dist/CustomEase.min.js +11 -0
  593. package/vendor/framey/dist/vendor/npm/gsap@3.15.0/dist/MotionPathPlugin.min.js +11 -0
  594. package/vendor/framey/dist/vendor/npm/gsap@3.15.0/dist/gsap.min.js +11 -0
  595. package/vendor/framey/dist/warmCheck.js +220 -0
  596. package/vendor/framey/dist/warmCheckClient.js +139 -0
  597. package/vendor/framey/dist/workspaceBuildCheck-XYD2YTFW.js +133 -0
  598. package/vendor/framey-player/LICENSE +190 -0
  599. package/vendor/framey-player/NOTICE +16 -0
  600. package/vendor/framey-player/SOURCE.json +6 -0
  601. package/vendor/framey-player/hyperframes-player.global.js +478 -0
  602. package/vendor/framey.pin +1 -0
  603. package/bin/index.js +0 -3
@@ -0,0 +1,195 @@
1
+ import { createRequire as __hf_createRequire } from "node:module";
2
+ import { fileURLToPath as __hf_fileURLToPath } from "node:url";
3
+ import { dirname as __hf_dirname } from "node:path";
4
+ var require = __hf_createRequire(import.meta.url);
5
+ var __filename = __hf_fileURLToPath(import.meta.url);
6
+ var __dirname = __hf_dirname(__filename);
7
+ import {
8
+ runRenderSetupWorker
9
+ } from "./chunk-BL4U6U52.js";
10
+ import {
11
+ HYPERFRAMES_BROWSER_MARKER_ARG
12
+ } from "./chunk-K4MJX7SR.js";
13
+ import {
14
+ terminateProcessTree
15
+ } from "./chunk-KGPLIH7B.js";
16
+
17
+ // src/utils/orphanCleanup.ts
18
+ import { execFileSync } from "child_process";
19
+ import { readFileSync } from "fs";
20
+ function killOrphanedProcesses() {
21
+ if (process.env.HYPERFRAMES_NO_ORPHAN_CLEANUP === "1" || process.platform === "win32") return 0;
22
+ return killOrphansMatching(HYPERFRAMES_BROWSER_MARKER_ARG);
23
+ }
24
+ async function killOrphanedProcessesForRender(signal) {
25
+ return runRenderSetupWorker("orphan-cleanup", {}, { signal, timeoutMs: 15e3 });
26
+ }
27
+ function killProcessTree(pid, signal = "SIGTERM") {
28
+ void terminateProcessTree(pid, { signal }).catch(() => void 0);
29
+ }
30
+ function processIdentity(pid) {
31
+ if (!Number.isInteger(pid) || pid <= 0) return null;
32
+ try {
33
+ if (process.platform === "win32") {
34
+ const created = execFileSync(
35
+ "powershell.exe",
36
+ [
37
+ "-NoProfile",
38
+ "-NonInteractive",
39
+ "-Command",
40
+ `$p = Get-CimInstance Win32_Process -Filter 'ProcessId = ${pid}' -ErrorAction SilentlyContinue; if ($p) { $p.CreationDate.ToFileTimeUtc() }`
41
+ ],
42
+ {
43
+ encoding: "utf8",
44
+ timeout: 2e3,
45
+ stdio: ["pipe", "pipe", "ignore"],
46
+ windowsHide: true
47
+ }
48
+ ).trim();
49
+ return created ? `windows:${created}` : null;
50
+ }
51
+ if (process.platform === "linux") {
52
+ const stat = readFileSync(`/proc/${pid}/stat`, "utf8");
53
+ const fields = stat.slice(stat.lastIndexOf(") ") + 2).trim().split(/\s+/);
54
+ const startTicks = fields[19];
55
+ return startTicks ? `linux:${startTicks}` : null;
56
+ }
57
+ const started = execFileSync("ps", ["-o", "lstart=", "-p", String(pid)], {
58
+ encoding: "utf8",
59
+ timeout: 2e3
60
+ }).trim();
61
+ return started ? `posix:${started}` : null;
62
+ } catch {
63
+ return null;
64
+ }
65
+ }
66
+ var holdsReusedPid = (parent, child) => parent.startedAt !== void 0 && child?.startedAt !== void 0 && parent.startedAt > child.startedAt;
67
+ function recordsToAncestors(pid, records) {
68
+ const byPid = new Map(records.map((record) => [record.pid, record]));
69
+ const ancestors = [];
70
+ const visited = /* @__PURE__ */ new Set([pid]);
71
+ let current = pid;
72
+ for (let depth = 0; depth < 64; depth++) {
73
+ const child = byPid.get(current);
74
+ const parent = child?.parentPid;
75
+ if (parent === void 0 || parent <= 1 || visited.has(parent)) break;
76
+ visited.add(parent);
77
+ const ancestor = byPid.get(parent);
78
+ if (!ancestor || holdsReusedPid(ancestor, child)) break;
79
+ ancestors.push({ pid: ancestor.pid, identity: ancestor.identity });
80
+ current = parent;
81
+ }
82
+ return ancestors;
83
+ }
84
+ function processAncestorSnapshot(pid) {
85
+ if (!Number.isInteger(pid) || pid <= 0 || process.platform === "linux") return [];
86
+ try {
87
+ if (process.platform === "win32") {
88
+ const output2 = execFileSync(
89
+ "powershell.exe",
90
+ [
91
+ "-NoProfile",
92
+ "-NonInteractive",
93
+ "-Command",
94
+ 'Get-CimInstance Win32_Process | ForEach-Object { "$($_.ProcessId) $($_.ParentProcessId) $($_.CreationDate.ToFileTimeUtc())" }'
95
+ ],
96
+ { encoding: "utf8", timeout: 2e3, stdio: ["pipe", "pipe", "ignore"], windowsHide: true }
97
+ );
98
+ const records2 = output2.split(/\r?\n/).map((line) => line.trim().split(/\s+/)).map(
99
+ ([processId, parentProcessId, creationDate]) => ({
100
+ pid: Number(processId),
101
+ parentPid: Number(parentProcessId),
102
+ identity: creationDate ? `windows:${creationDate}` : "",
103
+ startedAt: creationDate && /^\d+$/.test(creationDate) ? BigInt(creationDate) : void 0
104
+ })
105
+ ).filter(
106
+ (record) => Number.isInteger(record.pid) && record.pid > 0 && Number.isInteger(record.parentPid) && record.parentPid > 0 && record.identity !== ""
107
+ );
108
+ return recordsToAncestors(pid, records2);
109
+ }
110
+ const output = execFileSync("ps", ["-axo", "pid=,ppid=,lstart="], {
111
+ encoding: "utf8",
112
+ timeout: 2e3
113
+ });
114
+ const records = output.split(/\r?\n/).map((line) => line.match(/^\s*(\d+)\s+(\d+)\s+(.+)$/)).filter((match) => match !== null).map(([, processId, parentProcessId, started]) => ({
115
+ pid: Number(processId),
116
+ parentPid: Number(parentProcessId),
117
+ identity: `posix:${started?.trim() ?? ""}`
118
+ }));
119
+ return recordsToAncestors(pid, records);
120
+ } catch {
121
+ return [];
122
+ }
123
+ }
124
+ function processParentPid(pid) {
125
+ try {
126
+ const output = process.platform === "win32" ? execFileSync(
127
+ "powershell.exe",
128
+ [
129
+ "-NoProfile",
130
+ "-NonInteractive",
131
+ "-Command",
132
+ `$p = Get-CimInstance Win32_Process -Filter 'ProcessId = ${pid}' -ErrorAction SilentlyContinue; if ($p) { $p.ParentProcessId }`
133
+ ],
134
+ {
135
+ encoding: "utf8",
136
+ timeout: 2e3,
137
+ stdio: ["pipe", "pipe", "ignore"],
138
+ windowsHide: true
139
+ }
140
+ ) : execFileSync("ps", ["-o", "ppid=", "-p", String(pid)], {
141
+ encoding: "utf8",
142
+ timeout: 2e3
143
+ });
144
+ const parentPid = Number(output.trim());
145
+ return Number.isInteger(parentPid) && parentPid > 0 ? parentPid : null;
146
+ } catch {
147
+ return null;
148
+ }
149
+ }
150
+ function isProcessDescendant(childPid, ancestorPid, parentPid = processParentPid) {
151
+ if (childPid <= 0 || ancestorPid <= 0 || childPid === ancestorPid) return false;
152
+ const visited = /* @__PURE__ */ new Set();
153
+ let current = childPid;
154
+ for (let depth = 0; depth < 64; depth++) {
155
+ if (visited.has(current)) return false;
156
+ visited.add(current);
157
+ const parent = parentPid(current);
158
+ if (parent === ancestorPid) return true;
159
+ if (parent === null || parent <= 1) return false;
160
+ current = parent;
161
+ }
162
+ return false;
163
+ }
164
+ function killOrphansMatching(marker) {
165
+ const uid = process.getuid?.();
166
+ const owner = uid === void 0 ? ["-A"] : ["-U", String(uid)];
167
+ let table;
168
+ try {
169
+ table = execFileSync("ps", [...owner, "-ww", "-o", "pid=,ppid=,args="], {
170
+ encoding: "utf-8",
171
+ timeout: 3e3
172
+ });
173
+ } catch {
174
+ return 0;
175
+ }
176
+ let killed = 0;
177
+ for (const line of table.split("\n")) {
178
+ const match = line.match(/^\s*(\d+)\s+(\d+)\s+(.*)$/);
179
+ if (!match || match[2] !== "1") continue;
180
+ if (!match[3].split(/\s+/).includes(marker)) continue;
181
+ killProcessTree(Number(match[1]));
182
+ killed++;
183
+ }
184
+ return killed;
185
+ }
186
+
187
+ export {
188
+ killOrphanedProcesses,
189
+ killOrphanedProcessesForRender,
190
+ killProcessTree,
191
+ processIdentity,
192
+ processAncestorSnapshot,
193
+ processParentPid,
194
+ isProcessDescendant
195
+ };
@@ -0,0 +1,54 @@
1
+ import { createRequire as __hf_createRequire } from "node:module";
2
+ import { fileURLToPath as __hf_fileURLToPath } from "node:url";
3
+ import { dirname as __hf_dirname } from "node:path";
4
+ var require = __hf_createRequire(import.meta.url);
5
+ var __filename = __hf_fileURLToPath(import.meta.url);
6
+ var __dirname = __hf_dirname(__filename);
7
+ var __create = Object.create;
8
+ var __defProp = Object.defineProperty;
9
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
10
+ var __getOwnPropNames = Object.getOwnPropertyNames;
11
+ var __getProtoOf = Object.getPrototypeOf;
12
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
13
+ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
14
+ get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
15
+ }) : x)(function(x) {
16
+ if (typeof require !== "undefined") return require.apply(this, arguments);
17
+ throw Error('Dynamic require of "' + x + '" is not supported');
18
+ });
19
+ var __esm = (fn, res) => function __init() {
20
+ return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
21
+ };
22
+ var __commonJS = (cb, mod) => function __require2() {
23
+ return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
24
+ };
25
+ var __export = (target, all) => {
26
+ for (var name in all)
27
+ __defProp(target, name, { get: all[name], enumerable: true });
28
+ };
29
+ var __copyProps = (to, from, except, desc) => {
30
+ if (from && typeof from === "object" || typeof from === "function") {
31
+ for (let key of __getOwnPropNames(from))
32
+ if (!__hasOwnProp.call(to, key) && key !== except)
33
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
34
+ }
35
+ return to;
36
+ };
37
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
38
+ // If the importer is in node compatibility mode or this is not an ESM
39
+ // file that has been converted to a CommonJS file using a Babel-
40
+ // compatible transform (i.e. "__esModule" has not been set), then set
41
+ // "default" to the CommonJS "module.exports" for node compatibility.
42
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
43
+ mod
44
+ ));
45
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
46
+
47
+ export {
48
+ __require,
49
+ __esm,
50
+ __commonJS,
51
+ __export,
52
+ __toESM,
53
+ __toCommonJS
54
+ };
@@ -0,0 +1,399 @@
1
+ import { createRequire as __hf_createRequire } from "node:module";
2
+ import { fileURLToPath as __hf_fileURLToPath } from "node:url";
3
+ import { dirname as __hf_dirname } from "node:path";
4
+ var require = __hf_createRequire(import.meta.url);
5
+ var __filename = __hf_fileURLToPath(import.meta.url);
6
+ var __dirname = __hf_dirname(__filename);
7
+ import {
8
+ resolveWithinProject
9
+ } from "./chunk-7JQFJ6JJ.js";
10
+ import {
11
+ MAX_AUDIO_GAIN_DB,
12
+ formatAudioGain,
13
+ isAudibleVideoElement
14
+ } from "./chunk-X7HBSTCZ.js";
15
+ import {
16
+ decodeAuthoredAttribute
17
+ } from "./chunk-B7RJV74O.js";
18
+ import {
19
+ findFfBinary
20
+ } from "./chunk-VAS6HQX3.js";
21
+ import {
22
+ decodeWellFormedEscapes,
23
+ decodedUrlPath,
24
+ readMediaOffsetSeconds
25
+ } from "./chunk-BSQ7XANM.js";
26
+
27
+ // ../studio-server/dist/chunk-75IWAUSY.js
28
+ import { execFile } from "child_process";
29
+ import { isAbsolute, relative, resolve } from "path";
30
+ import { promisify } from "util";
31
+ import { existsSync } from "fs";
32
+ function requestSubPath(url, route) {
33
+ const routeSegments = route.split("/");
34
+ const segments = new URL(url).pathname.split("/");
35
+ const start = segments.indexOf(routeSegments[0] ?? "");
36
+ return decodeWellFormedEscapes(segments.slice(start + routeSegments.length).join("/"));
37
+ }
38
+ function requestedProjectPath(projectDir, field) {
39
+ const trimmed = field.trim().replace(/^[.]\//, "");
40
+ const named = resolveWithinProject(projectDir, trimmed);
41
+ return named && existsSync(named) ? trimmed : decodedUrlPath(trimmed);
42
+ }
43
+ var execFileAsync = promisify(execFile);
44
+ var FFMPEG_TIMEOUT_MS = 12e4;
45
+ function authoredNumber(raw, fallback, attribute, id, strictlyPositive = false) {
46
+ if (raw === void 0) return fallback;
47
+ const value = Number(raw);
48
+ if (!Number.isFinite(value) || (strictlyPositive ? value <= 0 : value < 0)) {
49
+ throw new Error(`Audio #${id} has an invalid ${attribute}: ${raw}`);
50
+ }
51
+ return value;
52
+ }
53
+ function attributeFromMatch(match, absoluteOffset) {
54
+ if (match.index === void 0) return null;
55
+ const name = match[1]?.toLowerCase();
56
+ const value = matchedAttributeValue(match);
57
+ if (!name || value === void 0) return null;
58
+ const whole = match[0];
59
+ const localValueStart = attributeValueStart(whole);
60
+ const valueStart = absoluteOffset + match.index + localValueStart;
61
+ return [
62
+ name,
63
+ {
64
+ value: decodeAuthoredAttribute(value),
65
+ valueStart,
66
+ valueEnd: valueStart + value.length
67
+ }
68
+ ];
69
+ }
70
+ function matchedAttributeValue(match) {
71
+ return match[2] ?? match[3] ?? match[4];
72
+ }
73
+ function attributeValueStart(attribute) {
74
+ let cursor = attribute.indexOf("=") + 1;
75
+ while (/\s/.test(attribute[cursor] ?? "")) cursor += 1;
76
+ const quote = attribute[cursor];
77
+ return quote === '"' || quote === "'" ? cursor + 1 : cursor;
78
+ }
79
+ function attributesInTag(html, from, to) {
80
+ const tag = html.slice(from, to);
81
+ const nameEnd = tag.search(/\s|\/?\s*>/);
82
+ const attributes = /* @__PURE__ */ new Map();
83
+ if (nameEnd < 0) return attributes;
84
+ const pattern = /([^\s=/>]+)\s*=\s*(?:"([^"]*)"|'([^']*)'|([^\s"'=<>`]+))/g;
85
+ for (const match of tag.slice(nameEnd).matchAll(pattern)) {
86
+ const attribute = attributeFromMatch(match, from + nameEnd);
87
+ if (attribute) attributes.set(...attribute);
88
+ }
89
+ return attributes;
90
+ }
91
+ function startTagEnd(html, start) {
92
+ let quote = "";
93
+ let end = start + 1;
94
+ for (; end < html.length; end += 1) {
95
+ const char = html[end];
96
+ if (quote) {
97
+ if (char === quote) quote = "";
98
+ } else if (char === '"' || char === "'") {
99
+ quote = char;
100
+ } else if (char === ">") {
101
+ return end + 1;
102
+ }
103
+ }
104
+ throw new Error("Unterminated HTML start tag");
105
+ }
106
+ function commentEnd(html, start) {
107
+ const end = html.indexOf("-->", start + 4);
108
+ if (end < 0) throw new Error("Unterminated HTML comment");
109
+ return end + 3;
110
+ }
111
+ var isSpaceAt = (html, index) => /\s/.test(html.charAt(index));
112
+ var isWordAt = (html, index) => /\w/.test(html.charAt(index));
113
+ function skipSpaces(html, index) {
114
+ let cursor = index;
115
+ while (cursor < html.length && isSpaceAt(html, cursor)) cursor++;
116
+ return cursor;
117
+ }
118
+ function parsedStartTag(html, start) {
119
+ let cursor = skipSpaces(html, start + 1);
120
+ const closing = html.charAt(cursor) === "/";
121
+ if (closing) cursor = skipSpaces(html, cursor + 1);
122
+ const nameStart = cursor;
123
+ if (!/[a-z]/i.test(html.charAt(cursor))) return null;
124
+ while (/[a-z\d:-]/i.test(html.charAt(cursor + 1))) cursor++;
125
+ let nameEnd = cursor + 1;
126
+ while (nameEnd > nameStart && isWordAt(html, nameEnd - 1) === isWordAt(html, nameEnd)) nameEnd--;
127
+ if (nameEnd === nameStart) return null;
128
+ return {
129
+ start,
130
+ end: startTagEnd(html, start),
131
+ closing,
132
+ name: html.slice(nameStart, nameEnd).toLowerCase()
133
+ };
134
+ }
135
+ function rawTextElementEnd(html, lower, tag) {
136
+ if (tag.closing || tag.name !== "script" && tag.name !== "style") return null;
137
+ const closeStart = lower.indexOf(`</${tag.name}`, tag.end);
138
+ if (closeStart < 0) throw new Error(`Unterminated <${tag.name}> element`);
139
+ return startTagEnd(html, closeStart);
140
+ }
141
+ function scanMarkup(html, lower, start) {
142
+ if (html.startsWith("<!--", start)) {
143
+ return { cursor: commentEnd(html, start), mediaRange: null };
144
+ }
145
+ const tag = parsedStartTag(html, start);
146
+ if (!tag) {
147
+ const marker = html[start + 1];
148
+ const cursor = marker === "!" || marker === "?" ? startTagEnd(html, start) : start + 1;
149
+ return { cursor, mediaRange: null };
150
+ }
151
+ const rawTextEnd = rawTextElementEnd(html, lower, tag);
152
+ if (rawTextEnd !== null) return { cursor: rawTextEnd, mediaRange: null };
153
+ return { cursor: tag.end, mediaRange: mediaRangeOf(tag) };
154
+ }
155
+ function mediaRangeOf(tag) {
156
+ if (tag.closing) return null;
157
+ if (tag.name === "audio" || tag.name === "video") {
158
+ return { start: tag.start, end: tag.end, name: tag.name };
159
+ }
160
+ return null;
161
+ }
162
+ function mediaTagRanges(html) {
163
+ const lower = html.toLowerCase();
164
+ const ranges = [];
165
+ let cursor = 0;
166
+ while (cursor < html.length) {
167
+ const start = html.indexOf("<", cursor);
168
+ if (start < 0) break;
169
+ const scanned = scanMarkup(html, lower, start);
170
+ if (scanned.mediaRange) ranges.push(scanned.mediaRange);
171
+ cursor = scanned.cursor;
172
+ }
173
+ return ranges;
174
+ }
175
+ function trimmedAttribute(attributes, name) {
176
+ return attributes.get(name)?.value.trim() ?? "";
177
+ }
178
+ function authoredDuration(attributes, id) {
179
+ const raw = attributes.get("data-duration")?.value;
180
+ if (raw !== void 0) return authoredNumber(raw, 0, "data-duration", id, true);
181
+ const rawEnd = attributes.get("data-end")?.value;
182
+ if (rawEnd === void 0) return null;
183
+ const end = authoredNumber(rawEnd, 0, "data-end", id, true);
184
+ const start = authoredNumber(attributes.get("data-start")?.value, 0, "data-start", id);
185
+ return end > start ? end - start : null;
186
+ }
187
+ function requiredAudioIdentity(attributes) {
188
+ const id = trimmedAttribute(attributes, "id");
189
+ const src = trimmedAttribute(attributes, "src");
190
+ if (!id) throw new Error("Every normalized <audio> element needs an id");
191
+ if (!src) throw new Error(`Audio #${id} has no src`);
192
+ return { id, src };
193
+ }
194
+ function authoredMediaStart(attributes, id) {
195
+ return readMediaOffsetSeconds((name) => {
196
+ const raw = attributes.get(name)?.value;
197
+ if (name === "data-media-start") authoredNumber(raw, 0, name, id);
198
+ return raw;
199
+ });
200
+ }
201
+ function hasBareAttribute(html, range, name) {
202
+ const unquoted = html.slice(range.start, range.end).replace(/"[^"]*"|'[^']*'/g, '""');
203
+ return new RegExp(`\\s${name}(?=[\\s/>=])`, "i").test(unquoted);
204
+ }
205
+ function isAudibleVideoTag(html, range, attributes) {
206
+ return isAudibleVideoElement({
207
+ tagName: "video",
208
+ hasAttribute: (name) => attributes.has(name) || hasBareAttribute(html, range, name),
209
+ getAttribute: (name) => attributes.get(name)?.value ?? null
210
+ });
211
+ }
212
+ function inScopeVideo(html, range, attributes) {
213
+ return isAudibleVideoTag(html, range, attributes) && trimmedAttribute(attributes, "id") !== "" && trimmedAttribute(attributes, "src") !== "";
214
+ }
215
+ function mediaTagFromRange(html, range) {
216
+ const attributes = attributesInTag(html, range.start, range.end);
217
+ if (range.name === "video" && !inScopeVideo(html, range, attributes)) return null;
218
+ const { id, src } = requiredAudioIdentity(attributes);
219
+ const volumeAttribute = attributes.get("data-volume") ?? null;
220
+ return {
221
+ tag: range.name,
222
+ id,
223
+ src,
224
+ volume: authoredNumber(volumeAttribute?.value, 1, "data-volume", id),
225
+ mediaStart: authoredMediaStart(attributes, id),
226
+ duration: authoredDuration(attributes, id),
227
+ playbackRate: authoredNumber(
228
+ attributes.get("data-playback-rate")?.value,
229
+ 1,
230
+ "data-playback-rate",
231
+ id,
232
+ true
233
+ ),
234
+ start: range.start,
235
+ end: range.end,
236
+ volumeAttribute
237
+ };
238
+ }
239
+ function audioTags(html) {
240
+ const seen = /* @__PURE__ */ new Set();
241
+ const tags = [];
242
+ for (const range of mediaTagRanges(html)) {
243
+ const tag = mediaTagFromRange(html, range);
244
+ if (!tag) continue;
245
+ if (seen.has(tag.id)) throw new Error(`Duplicate audio id "${tag.id}"`);
246
+ seen.add(tag.id);
247
+ tags.push(tag);
248
+ }
249
+ return tags;
250
+ }
251
+ function resolveLocalAudioPath(projectDir, src) {
252
+ const decoded = requestedProjectPath(projectDir, src);
253
+ if (!decoded || isAbsolute(decoded) || /^(?:[a-z][a-z\d+.-]*:|\/\/)/i.test(decoded)) {
254
+ throw new Error(`Audio source must be a local project file: ${src}`);
255
+ }
256
+ const root = resolve(projectDir);
257
+ const file = resolve(root, decoded);
258
+ const rel = relative(root, file);
259
+ if (!rel || rel === ".." || rel.startsWith(`..${process.platform === "win32" ? "\\" : "/"}`)) {
260
+ throw new Error(`Audio source must be a local project file: ${src}`);
261
+ }
262
+ return file;
263
+ }
264
+ function parseEbur128Summary(stderr) {
265
+ const summaryAt = stderr.lastIndexOf("Summary:");
266
+ const summary = summaryAt >= 0 ? stderr.slice(summaryAt) : "";
267
+ const integrated = summary.match(/\bI:\s*(-?\d+(?:\.\d+)?)\s+LUFS\b/);
268
+ const peak = summary.match(/\bPeak:\s*(-?\d+(?:\.\d+)?)\s+dBFS\b/);
269
+ const integratedLufs = Number(integrated?.[1]);
270
+ const truePeakDbfs = Number(peak?.[1]);
271
+ if (!Number.isFinite(integratedLufs)) {
272
+ throw new Error("FFmpeg did not report integrated loudness for this audio stream");
273
+ }
274
+ if (!Number.isFinite(truePeakDbfs)) {
275
+ throw new Error("FFmpeg did not report true peak for this audio stream");
276
+ }
277
+ return { integratedLufs, truePeakDbfs };
278
+ }
279
+ function gainDb(volume) {
280
+ return volume > 0 ? 20 * Math.log10(volume) : Number.NEGATIVE_INFINITY;
281
+ }
282
+ function audioNormalizationPlan(referenceTrack, targetTrack) {
283
+ if (!(referenceTrack.volume > 0) || !(targetTrack.volume > 0)) {
284
+ throw new Error("Muted audio cannot be used for loudness matching");
285
+ }
286
+ const referenceLufs = referenceTrack.integratedLufs + gainDb(referenceTrack.volume);
287
+ const targetLufs = targetTrack.integratedLufs + gainDb(targetTrack.volume);
288
+ const wantedGainDb = referenceLufs - targetTrack.integratedLufs;
289
+ if (wantedGainDb > MAX_AUDIO_GAIN_DB + 1e-9) {
290
+ throw new Error(
291
+ `Matching #${targetTrack.id} needs ${wantedGainDb.toFixed(1)} dB, beyond the +${MAX_AUDIO_GAIN_DB} dB authoring ceiling. A gap this large belongs in the source file, not the mixer: mixer gain raises the noise floor with the signal. Normalize ${targetTrack.id}'s asset offline (e.g. ffmpeg loudnorm), or lower #${referenceTrack.id} instead.`
292
+ );
293
+ }
294
+ const volume = 10 ** (wantedGainDb / 20);
295
+ const projectedTruePeakDbfs = targetTrack.truePeakDbfs + wantedGainDb;
296
+ if (projectedTruePeakDbfs > 0) {
297
+ throw new Error(
298
+ `Matching #${targetTrack.id} would clip at +${projectedTruePeakDbfs.toFixed(1)} dBFS; limit or preprocess the source first`
299
+ );
300
+ }
301
+ return {
302
+ referenceId: referenceTrack.id,
303
+ targetId: targetTrack.id,
304
+ referenceLufs,
305
+ targetLufs,
306
+ previousVolume: targetTrack.volume,
307
+ volume,
308
+ gainDb: wantedGainDb,
309
+ changeDb: wantedGainDb - gainDb(targetTrack.volume),
310
+ projectedLufs: targetTrack.integratedLufs + wantedGainDb,
311
+ projectedTruePeakDbfs
312
+ };
313
+ }
314
+ function updateAudioVolume(html, id, volume) {
315
+ const tag = audioTags(html).find((candidate) => candidate.id === id);
316
+ if (!tag) throw new Error(`Audio #${id} was not found`);
317
+ const value = formatAudioGain(volume);
318
+ if (tag.volumeAttribute) {
319
+ return html.slice(0, tag.volumeAttribute.valueStart) + value + html.slice(tag.volumeAttribute.valueEnd);
320
+ }
321
+ let insertion = tag.end - 1;
322
+ let tail = insertion - 1;
323
+ while (tail >= tag.start && /\s/.test(html[tail] ?? "")) tail -= 1;
324
+ if (html[tail] === "/") {
325
+ insertion = tail;
326
+ while (insertion > tag.start && /\s/.test(html[insertion - 1] ?? "")) insertion -= 1;
327
+ } else {
328
+ while (insertion > tag.start && /\s/.test(html[insertion - 1] ?? "")) insertion -= 1;
329
+ }
330
+ return html.slice(0, insertion) + ` data-volume="${value}"` + html.slice(insertion);
331
+ }
332
+ function loudnessMeasureArgs(file, tag) {
333
+ const args = ["-hide_banner", "-nostats"];
334
+ if (tag.mediaStart > 0) args.push("-ss", String(tag.mediaStart));
335
+ const sourceSpan = tag.duration === null ? null : tag.duration * (tag.playbackRate ?? 1);
336
+ if (sourceSpan !== null && sourceSpan > 0) args.push("-t", String(sourceSpan));
337
+ args.push("-i", file, "-map", "0:a:0", "-vn", "-af", "ebur128=peak=true", "-f", "null", "-");
338
+ return args;
339
+ }
340
+ async function measureAudio(ffmpegPath, file, tag) {
341
+ const result = await execFileAsync(ffmpegPath, loudnessMeasureArgs(file, tag), {
342
+ encoding: "utf8",
343
+ maxBuffer: 16 * 1024 * 1024,
344
+ timeout: FFMPEG_TIMEOUT_MS,
345
+ windowsHide: true
346
+ });
347
+ return parseEbur128Summary(result.stderr);
348
+ }
349
+ function requiredFfmpeg() {
350
+ const ffmpegPath = findFfBinary("ffmpeg", { configuredMustExist: true });
351
+ if (!ffmpegPath) throw new Error("FFmpeg is required to measure integrated loudness");
352
+ return ffmpegPath;
353
+ }
354
+ var DEFAULT_TARGET_LUFS = -16;
355
+ var NORMALIZE_TRUE_PEAK_CEILING_DBFS = -1.5;
356
+ var SILENCE_LUFS = -70;
357
+ function absoluteLoudnessPlan(track, targetLufs = DEFAULT_TARGET_LUFS) {
358
+ if (track.integratedLufs <= SILENCE_LUFS) {
359
+ throw new Error(`#${track.id} is silent in the played window; there is nothing to normalize`);
360
+ }
361
+ const wantedGainDb = targetLufs - track.integratedLufs;
362
+ const peakRoomDb = NORMALIZE_TRUE_PEAK_CEILING_DBFS - track.truePeakDbfs;
363
+ const limits = [
364
+ [null, wantedGainDb],
365
+ ["gain-ceiling", MAX_AUDIO_GAIN_DB],
366
+ ["true-peak", peakRoomDb]
367
+ ];
368
+ const [limitedBy, appliedGainDb] = limits.reduce(
369
+ (lowest, candidate) => candidate[1] < lowest[1] - 1e-9 ? candidate : lowest
370
+ );
371
+ const previousGainDb = track.volume > 0 ? gainDb(track.volume) : 0;
372
+ return {
373
+ targetId: track.id,
374
+ targetLufs,
375
+ sourceLufs: track.integratedLufs,
376
+ previousVolume: track.volume,
377
+ volume: 10 ** (appliedGainDb / 20),
378
+ gainDb: appliedGainDb,
379
+ changeDb: appliedGainDb - previousGainDb,
380
+ projectedLufs: track.integratedLufs + appliedGainDb,
381
+ projectedTruePeakDbfs: track.truePeakDbfs + appliedGainDb,
382
+ limitedBy
383
+ };
384
+ }
385
+
386
+ export {
387
+ requestSubPath,
388
+ requestedProjectPath,
389
+ audioTags,
390
+ resolveLocalAudioPath,
391
+ parseEbur128Summary,
392
+ audioNormalizationPlan,
393
+ updateAudioVolume,
394
+ loudnessMeasureArgs,
395
+ measureAudio,
396
+ requiredFfmpeg,
397
+ DEFAULT_TARGET_LUFS,
398
+ absoluteLoudnessPlan
399
+ };