@higgsfield/video-editor-mcp 1.0.7 → 1.1.1-dev.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 (189) hide show
  1. package/THIRD_PARTY_NOTICES.md +24 -24
  2. package/dist/cli.mjs +134 -125
  3. package/dist/index.html +136 -133
  4. package/dist/launcher.mjs +90 -90
  5. package/dist/server.mjs +1553 -1389
  6. package/node_modules/@higgsfield/higgsedit/README.md +181 -1
  7. package/node_modules/@higgsfield/higgsedit/dist/capture-page.js +902 -314
  8. package/node_modules/@higgsfield/higgsedit/dist/chunk-2JYLVSVV.mjs +1594 -0
  9. package/node_modules/@higgsfield/higgsedit/dist/chunk-2WKNH7OL.mjs +16 -0
  10. package/node_modules/@higgsfield/higgsedit/dist/{chunk-OMKZ5BXM.mjs → chunk-5LTTL3Q3.mjs} +1 -1
  11. package/node_modules/@higgsfield/higgsedit/dist/chunk-7PYXSJS7.mjs +717 -0
  12. package/node_modules/@higgsfield/higgsedit/dist/{chunk-MLJAIZGP.mjs → chunk-BH2QF635.mjs} +33 -326
  13. package/node_modules/@higgsfield/higgsedit/dist/{chunk-WZR5PZM7.mjs → chunk-BV5COOQZ.mjs} +250 -161
  14. package/node_modules/@higgsfield/higgsedit/dist/{chunk-HTCYVKFX.mjs → chunk-C3GSB3XZ.mjs} +8 -7
  15. package/node_modules/@higgsfield/higgsedit/dist/{chunk-CYH2EUQV.mjs → chunk-DVN4LUXV.mjs} +13 -4
  16. package/node_modules/@higgsfield/higgsedit/dist/chunk-F4CMIG5G.mjs +36 -0
  17. package/node_modules/@higgsfield/higgsedit/dist/chunk-IEPPEDEU.mjs +33 -0
  18. package/node_modules/@higgsfield/higgsedit/dist/{chunk-UVAZ6I6U.mjs → chunk-KIWGVAPJ.mjs} +16 -12
  19. package/node_modules/@higgsfield/higgsedit/dist/{chunk-L6QDNSL3.mjs → chunk-L5LWBA6A.mjs} +5 -5
  20. package/node_modules/@higgsfield/higgsedit/dist/chunk-LMQR3DHT.mjs +37 -0
  21. package/node_modules/@higgsfield/higgsedit/dist/chunk-LTKMGZ6T.mjs +58 -0
  22. package/node_modules/@higgsfield/higgsedit/dist/{chunk-VI6IV6JP.mjs → chunk-MV2JTTBQ.mjs} +65 -47
  23. package/node_modules/@higgsfield/higgsedit/dist/{chunk-4D6AXU4B.mjs → chunk-NARTAWRN.mjs} +50 -30
  24. package/node_modules/@higgsfield/higgsedit/dist/{chunk-27NBQ5FA.mjs → chunk-NUXTKQNM.mjs} +33 -21
  25. package/node_modules/@higgsfield/higgsedit/dist/chunk-OCIZ36XD.mjs +40 -0
  26. package/node_modules/@higgsfield/higgsedit/dist/{chunk-MK6PL7N4.mjs → chunk-OF6RMSM2.mjs} +19 -17
  27. package/node_modules/@higgsfield/higgsedit/dist/{chunk-6BETMESC.mjs → chunk-P2BGHTRR.mjs} +2 -2
  28. package/node_modules/@higgsfield/higgsedit/dist/{chunk-EKFC4S4M.mjs → chunk-PAHMD6SU.mjs} +5 -0
  29. package/node_modules/@higgsfield/higgsedit/dist/{chunk-QVLAEV3U.mjs → chunk-PFQYUJQL.mjs} +3 -4
  30. package/node_modules/@higgsfield/higgsedit/dist/chunk-QJTILFBS.mjs +335 -0
  31. package/node_modules/@higgsfield/higgsedit/dist/chunk-QQ3GGKDN.mjs +21 -0
  32. package/node_modules/@higgsfield/higgsedit/dist/chunk-TH7TK67K.mjs +23 -0
  33. package/node_modules/@higgsfield/higgsedit/dist/{chunk-SIMO6I3D.mjs → chunk-UDL5AHKO.mjs} +163 -158
  34. package/node_modules/@higgsfield/higgsedit/dist/chunk-UMWOUQN3.mjs +60 -0
  35. package/node_modules/@higgsfield/higgsedit/dist/{chunk-3AIM3THH.mjs → chunk-VLM5EOWJ.mjs} +4 -4
  36. package/node_modules/@higgsfield/higgsedit/dist/chunk-WENFTPXQ.mjs +403 -0
  37. package/node_modules/@higgsfield/higgsedit/dist/chunk-YLVXQIPX.mjs +464 -0
  38. package/node_modules/@higgsfield/higgsedit/dist/editor/.vite/manifest.json +559 -506
  39. package/node_modules/@higgsfield/higgsedit/dist/editor/assets/agent-corner-bottom-q4hZltI-.svg +431 -0
  40. package/node_modules/@higgsfield/higgsedit/dist/editor/assets/agent-corner-top-BJYI-I24.svg +431 -0
  41. package/node_modules/@higgsfield/higgsedit/dist/editor/assets/confirmation-BTnwl3LS.css +1 -0
  42. package/node_modules/@higgsfield/higgsedit/dist/editor/assets/drag-Bt_t4HZO.css +1 -0
  43. package/node_modules/@higgsfield/higgsedit/dist/editor/assets/local-B3OTAV_A.css +1 -0
  44. package/node_modules/@higgsfield/higgsedit/dist/editor/assets/menubar-2Y1Y2XJt.css +1 -0
  45. package/node_modules/@higgsfield/higgsedit/dist/editor/assets/model-DdE4hCgf.css +1 -0
  46. package/node_modules/@higgsfield/higgsedit/dist/editor/assets/{IconText1-CzbCrP7v.css → notifications-B08L1jSe.css} +1 -1
  47. package/node_modules/@higgsfield/higgsedit/dist/editor/assets/{panel-g852pZf_.css → panel-BRN_AbBM.css} +1 -1
  48. package/node_modules/@higgsfield/higgsedit/dist/editor/assets/panel-CYELNqrv.css +1 -0
  49. package/node_modules/@higgsfield/higgsedit/dist/editor/assets/panel-DYLpT6oA.css +1 -0
  50. package/node_modules/@higgsfield/higgsedit/dist/editor/assets/panel-v84HaGTZ.css +1 -0
  51. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/IconChainLink1-Bxb1Or0F.js +1 -0
  52. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/{IconCheckmark2Medium-daaES9uF.js → IconCheckmark2Medium-hegaz9mQ.js} +1 -1
  53. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/{IconChevronDownSmall-BhTBJk26.js → IconChevronDownSmall-DaruzJwU.js} +1 -1
  54. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/IconClosedCaptioning-BPqcqKsD.js +1 -0
  55. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/{IconCrossMedium-acfnCXOM.js → IconCrossMedium-BsPFJzc6.js} +1 -1
  56. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/IconOpenaiFilled-D1fzthmi.js +1 -0
  57. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/{IconPause-pTeVSvUe.js → IconPause-ClNg8pao.js} +1 -1
  58. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/{IconPlayFilled-CwdgIuDG.js → IconPlayFilled-CHb-7GSx.js} +1 -1
  59. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/IconSparklesSoftFilled-o7o33KRn.js +1 -0
  60. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/ai-composer-B9h-eaki.js +567 -0
  61. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/auto-layout-BO20Tg4B.js +1 -0
  62. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/{button-CjG6GcgF.js → button-Cg0U0zpV.js} +1 -1
  63. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/canvas-Bw4CVzfw.js +1 -0
  64. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/capabilities-BCd4-zPF.js +1 -0
  65. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/commands-QeSqAbCt.js +1 -0
  66. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/components-tXMtIZNL.js +51 -0
  67. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/confirmation-CO2PHR_z.js +1 -0
  68. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/dom-6aoQn29n.js +1 -0
  69. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/drag-Dw8b_vO2.js +1 -0
  70. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/{editing-CjWbiCxv.js → editing-Cy-SaOyB.js} +1 -1
  71. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/edits-CqLBqir0.js +1 -0
  72. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/export-dialog-BjBskOe3.js +2 -0
  73. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/factories-Bw_iQrUL.js +1 -0
  74. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/id3-CSR0NCRI.js +2 -0
  75. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/import-DP49i4ke.js +1 -0
  76. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/import-error-CMz9sLPe.js +1 -0
  77. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/ingest-DsmIc415.js +1 -0
  78. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/jsx-runtime-B5yqYJvp.js +1 -0
  79. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/{media-Bwjxu-0U.js → media-DQw6vU_T.js} +1 -1
  80. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/menubar-D31srALX.js +1 -0
  81. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/meters-D0nZVEJs.js +1 -0
  82. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/mode-DEG6doKF.js +1 -0
  83. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/model-Duf9fszJ.js +2 -0
  84. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/model-DyAkLA69.js +1 -0
  85. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/notifications-DqWZNIrK.js +9 -0
  86. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/palette-HT83gWgL.js +1 -0
  87. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/panel-B5Mvm6dg.js +7 -0
  88. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/panel-BC90wyvd.js +1 -0
  89. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/panel-Bw_ZJ2JI.js +3 -0
  90. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/panel-DNS060Nt.js +3 -0
  91. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/panel-DSgxIrEq.js +2 -0
  92. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/panel-DgBttE5O.js +1 -0
  93. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/panel-assets-_T2bHsHW.js +771 -0
  94. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/panel-inspector-DfHvAt5X.js +2 -0
  95. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/panel-nBZvHlkA.js +1 -0
  96. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/panel-timeline-DsCpJVSt.js +327 -0
  97. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/panel-viewport-CEhZwZ67.js +280 -0
  98. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/projects-2_tW9Do7.js +1 -0
  99. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/react-dom-1uB7Vbbb.js +1 -0
  100. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/schemas-CddYAOcj.js +64 -0
  101. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/session-BpFeKAI2.js +1 -0
  102. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/src-BLG3tYBa.js +2 -0
  103. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/styles-e2n2A_JN.js +284 -0
  104. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/supercomputer-CuV0zYKd.js +24 -0
  105. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/tabs-XeAgs9cs.js +1 -0
  106. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/toggle-DbNEaSIl.js +1 -0
  107. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/transport-C8Ll3qFl.js +69 -0
  108. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/transport-bar-Dv1LPFbu.js +1 -0
  109. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/useOpenInteractionType-HWSfSsp2.js +1 -0
  110. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/useRenderElement-D4SOg3N_.js +1 -0
  111. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/value-EB7YmAdS.js +1 -0
  112. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/writeback-support-fj5rA9k3.js +1 -0
  113. package/node_modules/@higgsfield/higgsedit/dist/editor/editor-B-WAkLt7.js +372 -0
  114. package/node_modules/@higgsfield/higgsedit/dist/higgsedit.mjs +39 -24
  115. package/node_modules/@higgsfield/higgsedit/dist/jsx/hooks.d.ts +26 -0
  116. package/node_modules/@higgsfield/higgsedit/dist/jsx/index.d.ts +17 -0
  117. package/node_modules/@higgsfield/higgsedit/dist/jsx/inspect.d.ts +42 -0
  118. package/node_modules/@higgsfield/higgsedit/dist/jsx/jsx-runtime.d.ts +28 -0
  119. package/node_modules/@higgsfield/higgsedit/dist/jsx/svg.d.ts +9 -0
  120. package/node_modules/@higgsfield/higgsedit/dist/jsx/time.d.ts +6 -0
  121. package/node_modules/@higgsfield/higgsedit/dist/jsx/types.d.ts +420 -0
  122. package/node_modules/@higgsfield/higgsedit/package.json +28 -20
  123. package/package.json +4 -3
  124. package/plugin/.codex-plugin/plugin.json +1 -1
  125. package/plugin/plugin.json +1 -1
  126. package/plugin/skills/video-editing/references/caption-titling.md +1 -1
  127. package/plugin/skills/video-editing/references/local-setup.md +3 -3
  128. package/node_modules/@higgsfield/higgsedit/dist/chunk-C6SASQHE.mjs +0 -424
  129. package/node_modules/@higgsfield/higgsedit/dist/chunk-FZ5U36SQ.mjs +0 -83
  130. package/node_modules/@higgsfield/higgsedit/dist/chunk-QLPCYN6K.mjs +0 -292
  131. package/node_modules/@higgsfield/higgsedit/dist/editor/assets/edit-drag-D2EV5ddd.css +0 -1
  132. package/node_modules/@higgsfield/higgsedit/dist/editor/assets/editor-CuRHT75g.css +0 -1
  133. package/node_modules/@higgsfield/higgsedit/dist/editor/assets/panel-DnuQD7ja.css +0 -1
  134. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/FieldControl-B0fenhBJ.js +0 -2
  135. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/IconChainLink1-Cwv1X7hi.js +0 -1
  136. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/IconEyeOpen-BqTT9_VV.js +0 -1
  137. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/IconEyeSlash-Whv58c1m.js +0 -1
  138. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/IconPencil-Dr17k_7e.js +0 -1
  139. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/IconPlay-BroH3ziH.js +0 -1
  140. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/IconPlusSmall-43T9aE3d.js +0 -1
  141. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/IconText1-BaP_p9DW.js +0 -1
  142. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/IconTrashCan-DX2w2AIC.js +0 -1
  143. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/ai-composer-C-l0eIdP.js +0 -560
  144. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/captions-Cd-bDG3G.js +0 -1
  145. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/clip-highlight-DpAvcA4x.js +0 -1
  146. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/components-e3ZbUVns.js +0 -1
  147. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/disposables-CwUPjcuA.js +0 -1
  148. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/drag-HLBkto5o.js +0 -1
  149. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/dropdown-BJ04G_X3.js +0 -1
  150. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/edit-drag-Bg6LggKC.js +0 -1
  151. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/edits-a2IixhrN.js +0 -1
  152. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/export-dialog-4I4gqI5V.js +0 -2
  153. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/face-tracker-DzVfjVOO.js +0 -1
  154. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/fit-imported-media-CaCB0x0b.js +0 -1
  155. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/generation-queue-DuL2F4-_.js +0 -1
  156. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/import-error-CMARA0Hy.js +0 -1
  157. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/jsx-runtime-B-hcVAMW.js +0 -1
  158. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/menubar-Bs26OdwP.js +0 -1
  159. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/meters-YEr9OQjq.js +0 -1
  160. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/paints-DS2Msf91.js +0 -67
  161. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/palette-CcS9IcAC.js +0 -1
  162. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/panel-7M3uQokX.js +0 -1
  163. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/panel-BBK1NyG-.js +0 -1
  164. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/panel-CHZTs7By.js +0 -4
  165. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/panel-DaSOa3MP.js +0 -2
  166. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/panel-DlK3RYVo.js +0 -1
  167. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/panel-Dst5OKWu.js +0 -2
  168. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/panel-H_ZoDiKK.js +0 -2
  169. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/panel-Rn9Z7Eek.js +0 -3
  170. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/panel-assets-FAghGFG3.js +0 -678
  171. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/panel-inspector-DEqULBNF.js +0 -260
  172. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/panel-timeline-0GYNz1uc.js +0 -333
  173. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/panel-viewport-DOWjJi5-.js +0 -317
  174. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/projects-BBJc7h5_.js +0 -2
  175. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/session-B9sZaFKC.js +0 -1
  176. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/supercomputer-CX-LCL6Y.js +0 -24
  177. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/tabs-CvKQ-eas.js +0 -1
  178. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/toggle-CrzrwiDZ.js +0 -1
  179. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/transport-BgRfk-Qq.js +0 -69
  180. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/transport-bar-C9nqAfE2.js +0 -1
  181. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/typography-C5-w9LOu-kD3uLKkf.js +0 -1
  182. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/useOpenInteractionType-DbrQ6Ehu.js +0 -1
  183. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/useRenderElement-bbxXdYq0.js +0 -1
  184. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/writeback-support-BZfNpkmB.js +0 -1
  185. package/node_modules/@higgsfield/higgsedit/dist/editor/editor-Csn2_T_e.js +0 -293
  186. package/node_modules/@higgsfield/higgsedit/dist/export-settings.mjs +0 -75
  187. package/node_modules/@higgsfield/higgsedit/dist/history.mjs +0 -295
  188. package/node_modules/@higgsfield/higgsedit/dist/media-upload.mjs +0 -381
  189. package/node_modules/@higgsfield/higgsedit/dist/proxy.mjs +0 -170
@@ -0,0 +1,60 @@
1
+ #!/usr/bin/env node
2
+ import { createRequire as __higgseditRequire } from "node:module";
3
+ import { fileURLToPath as __higgseditPath } from "node:url";
4
+ const require = __higgseditRequire(import.meta.url);
5
+ const __filename = __higgseditPath(import.meta.url);
6
+ const __dirname = __filename.slice(0, __filename.lastIndexOf("/"));
7
+ import {
8
+ BUILTIN_COMPONENTS,
9
+ LOOP_COMPONENTS,
10
+ SourceProject,
11
+ analyze,
12
+ applyEdit,
13
+ applyEdits,
14
+ attributeOf,
15
+ elementOf,
16
+ idAllocator,
17
+ idOf,
18
+ initializerText,
19
+ inspectVariables,
20
+ isComponentTag,
21
+ isIntrinsicTag,
22
+ isLiteral,
23
+ listSources,
24
+ literalText,
25
+ literalValue,
26
+ locateConst,
27
+ parseKey,
28
+ sourceFacts,
29
+ stampProject,
30
+ tagName,
31
+ tagsIn
32
+ } from "./chunk-MV2JTTBQ.mjs";
33
+ import "./chunk-F7YUKEI5.mjs";
34
+ import "./chunk-75WO2NOF.mjs";
35
+ export {
36
+ BUILTIN_COMPONENTS,
37
+ LOOP_COMPONENTS,
38
+ SourceProject,
39
+ analyze,
40
+ applyEdit,
41
+ applyEdits,
42
+ attributeOf,
43
+ elementOf,
44
+ idAllocator,
45
+ idOf,
46
+ initializerText,
47
+ inspectVariables,
48
+ isComponentTag,
49
+ isIntrinsicTag,
50
+ isLiteral,
51
+ listSources,
52
+ literalText,
53
+ literalValue,
54
+ locateConst,
55
+ parseKey,
56
+ sourceFacts,
57
+ stampProject,
58
+ tagName,
59
+ tagsIn
60
+ };
@@ -10,11 +10,11 @@ import {
10
10
  requireWhisper,
11
11
  runTranscribe,
12
12
  transcribe
13
- } from "./chunk-L6QDNSL3.mjs";
14
- import "./chunk-MCVD2ZQV.mjs";
15
- import "./chunk-WZR5PZM7.mjs";
13
+ } from "./chunk-L5LWBA6A.mjs";
14
+ import "./chunk-PAHMD6SU.mjs";
15
+ import "./chunk-BV5COOQZ.mjs";
16
16
  import "./chunk-F7YUKEI5.mjs";
17
- import "./chunk-EKFC4S4M.mjs";
17
+ import "./chunk-MCVD2ZQV.mjs";
18
18
  import "./chunk-75WO2NOF.mjs";
19
19
  export {
20
20
  DEFAULT_MODEL,
@@ -0,0 +1,403 @@
1
+ #!/usr/bin/env node
2
+ import { createRequire as __higgseditRequire } from "node:module";
3
+ import { fileURLToPath as __higgseditPath } from "node:url";
4
+ const require = __higgseditRequire(import.meta.url);
5
+ const __filename = __higgseditPath(import.meta.url);
6
+ const __dirname = __filename.slice(0, __filename.lastIndexOf("/"));
7
+ import {
8
+ decodeFrame,
9
+ encodePng,
10
+ frameAt,
11
+ frameTime,
12
+ videoSource
13
+ } from "./chunk-QJTILFBS.mjs";
14
+ import {
15
+ ffmpeg,
16
+ probe
17
+ } from "./chunk-PAHMD6SU.mjs";
18
+ import {
19
+ MaskFile,
20
+ decodeMaskRuns
21
+ } from "./chunk-BV5COOQZ.mjs";
22
+ import {
23
+ flag,
24
+ flags
25
+ } from "./chunk-MCVD2ZQV.mjs";
26
+
27
+ // src/select.ts
28
+ import { existsSync, mkdirSync, mkdtempSync, openAsBlob, renameSync, rmSync, writeFileSync } from "node:fs";
29
+ import { tmpdir } from "node:os";
30
+ import { dirname, join, resolve } from "node:path";
31
+ var SelectError = class extends Error {
32
+ status;
33
+ code;
34
+ constructor(message, status, code) {
35
+ super(message);
36
+ this.name = "SelectError";
37
+ this.status = status;
38
+ this.code = code;
39
+ }
40
+ };
41
+ var MAX_CONCEPTS = 8;
42
+ var MAX_CONCEPT_CHARS = 64;
43
+ var MAX_POINTS = 16;
44
+ var MAX_TRACK_SECONDS = 60;
45
+ var SHORT_SIDE = 1008;
46
+ var SELECT_TIMEOUT_MS = 12e4;
47
+ var POLL_TIMEOUT_MS = 6e4;
48
+ function selectBackend(env = process.env) {
49
+ const url = env.HIGGSEDIT_SELECT_URL || void 0;
50
+ if (!url) return void 0;
51
+ let parsed;
52
+ try {
53
+ parsed = new URL(url);
54
+ } catch {
55
+ throw new SelectError(`HIGGSEDIT_SELECT_URL ${url}: not a URL`, 503, "unconfigured");
56
+ }
57
+ if (parsed.protocol !== "http:" && parsed.protocol !== "https:") throw new SelectError(`HIGGSEDIT_SELECT_URL ${url}: must be http(s)`, 503, "unconfigured");
58
+ const token = env.HIGGSEDIT_SELECT_TOKEN || void 0;
59
+ return { url: url.replace(/\/+$/, ""), ...token ? { token } : {} };
60
+ }
61
+ function requireSelectBackend() {
62
+ const backend = selectBackend();
63
+ if (!backend) throw new SelectError("HIGGSEDIT_SELECT_URL is not set: point it at a select server (docs/select.md)", 503, "unconfigured");
64
+ return backend;
65
+ }
66
+ var bad = (message) => new SelectError(message, 400);
67
+ function unit(v, what) {
68
+ if (typeof v !== "number" || !(v >= 0 && v <= 1)) throw bad(`${what} must be a number in 0..1 of the frame, not ${JSON.stringify(v)}`);
69
+ return v;
70
+ }
71
+ function points(raw, what) {
72
+ if (raw === void 0 || raw === null) return void 0;
73
+ if (!Array.isArray(raw) || raw.length > MAX_POINTS) throw bad(`${what} must be a list of at most ${MAX_POINTS} {x, y} points`);
74
+ return raw.map((p, i) => {
75
+ if (typeof p !== "object" || p === null) throw bad(`${what}[${i}] must be {x, y}`);
76
+ const { x, y } = p;
77
+ return { x: unit(x, `${what}[${i}].x`), y: unit(y, `${what}[${i}].y`) };
78
+ });
79
+ }
80
+ var conceptsOf = (text) => text.split(",").map((c) => c.trim()).filter(Boolean);
81
+ function parsePrompt(raw) {
82
+ if (typeof raw !== "object" || raw === null || Array.isArray(raw)) throw bad("prompt must be an object: {text} or {points, exclude, box}");
83
+ const r = raw;
84
+ const unknown = Object.keys(r).filter((k) => !["text", "points", "exclude", "box"].includes(k));
85
+ if (unknown.length) throw bad(`prompt has unknown fields: ${unknown.toSorted().join(", ")}`);
86
+ const include = points(r.points, "prompt.points");
87
+ const exclude = points(r.exclude, "prompt.exclude");
88
+ let box;
89
+ if (r.box !== void 0 && r.box !== null) {
90
+ if (!Array.isArray(r.box) || r.box.length !== 4) throw bad("prompt.box must be [x0, y0, x1, y1] in 0..1");
91
+ box = r.box.map((v) => unit(v, "prompt.box"));
92
+ if (!(box[2] > box[0] && box[3] > box[1])) throw bad("prompt.box must have x1 > x0 and y1 > y0");
93
+ }
94
+ if (r.text !== void 0 && r.text !== null) {
95
+ if (typeof r.text !== "string") throw bad("prompt.text must be a string");
96
+ const concepts = conceptsOf(r.text);
97
+ if (!concepts.length) throw bad("prompt.text is empty");
98
+ if (concepts.length > MAX_CONCEPTS) throw bad(`prompt.text names ${concepts.length} concepts; the limit is ${MAX_CONCEPTS}`);
99
+ const long = concepts.find((c) => c.length > MAX_CONCEPT_CHARS);
100
+ if (long) throw bad(`concept "${long.slice(0, 20)}\u2026" is over ${MAX_CONCEPT_CHARS} characters`);
101
+ if (include?.length || exclude?.length || box) throw bad("prompt.text selects every instance of a concept and cannot be combined with points or a box");
102
+ return { text: r.text };
103
+ }
104
+ if (!include?.length && !box) throw bad("prompt needs text, a point on the object or a box around it");
105
+ return { ...include ? { points: include } : {}, ...exclude?.length ? { exclude } : {}, ...box ? { box } : {} };
106
+ }
107
+ async function failure(r) {
108
+ let detail = r.statusText;
109
+ try {
110
+ const body = await r.json();
111
+ if (typeof body.error === "string") detail = body.error;
112
+ } catch {
113
+ }
114
+ return new SelectError(`select server: ${r.status} ${detail}`, r.status);
115
+ }
116
+ async function call(backend, path, init = {}, timeoutMs) {
117
+ const base = `${backend.url}/`;
118
+ const url = new URL(path, base);
119
+ const headers = new Headers(init.headers);
120
+ if (backend.token && url.origin === new URL(base).origin) headers.set("authorization", `Bearer ${backend.token}`);
121
+ const signals = [init.signal, timeoutMs ? AbortSignal.timeout(timeoutMs) : void 0].filter((s) => Boolean(s));
122
+ let r;
123
+ try {
124
+ r = await fetch(url, { ...init, headers, ...signals.length ? { signal: AbortSignal.any(signals) } : {} });
125
+ } catch (error) {
126
+ if (error instanceof Error && error.name === "TimeoutError") throw new SelectError(`select server: no answer from ${url.href} within ${Math.round(timeoutMs / 1e3)} s`, 504);
127
+ if (error instanceof Error && error.name === "AbortError") throw error;
128
+ throw new SelectError(`select server: ${url.href} is unreachable: ${error instanceof Error ? error.cause instanceof Error ? error.cause.message : error.message : String(error)}`, 502);
129
+ }
130
+ if (!r.ok) throw await failure(r);
131
+ return r;
132
+ }
133
+ async function selectStatus(env = process.env) {
134
+ let backend;
135
+ try {
136
+ backend = selectBackend(env);
137
+ } catch (error) {
138
+ return { url: env.HIGGSEDIT_SELECT_URL ?? "", answers: false, detail: error.message };
139
+ }
140
+ if (!backend) return { url: null };
141
+ try {
142
+ const info = await (await call(backend, "v1", {}, 1e4)).json();
143
+ return { url: backend.url, answers: true, detail: `${String(info.model)}, contract ${String(info.contract)}` };
144
+ } catch (error) {
145
+ return { url: backend.url, answers: false, detail: error.message.replace(/^select server: /, "") };
146
+ }
147
+ }
148
+ var round = (v, places = 6) => Math.round(v * 10 ** places) / 10 ** places;
149
+ function sentSize([w, h]) {
150
+ const k = Math.min(w, h) >= SHORT_SIDE ? SHORT_SIDE / Math.min(w, h) : 1;
151
+ return [Math.round(w * k), Math.round(h * k)];
152
+ }
153
+ async function source(media) {
154
+ const file = resolve(media);
155
+ if (!existsSync(file)) throw new SelectError(`${media}: no such file`, 404);
156
+ const [src, info] = await Promise.all([videoSource(file), probe(file)]);
157
+ return { file, src, display: info.display };
158
+ }
159
+ function checkTime(src, t, what) {
160
+ if (!(t >= 0 && t <= src.duration)) throw bad(`${what} ${t} s is outside ${src.file} (0..${round(src.duration, 3)} s)`);
161
+ }
162
+ async function output(proc, what, input) {
163
+ const out = [];
164
+ let stderr = "";
165
+ proc.stdout.on("data", (d) => out.push(d));
166
+ proc.stderr.on("data", (d) => stderr += String(d));
167
+ if (input) proc.stdin.end(input);
168
+ const code = await new Promise((done) => proc.on("close", done));
169
+ if (code !== 0) throw new Error(`ffmpeg could not ${what}: ${stderr.trim() || `exit ${String(code)}`}`);
170
+ return Buffer.concat(out);
171
+ }
172
+ async function grabFrame(media, time) {
173
+ const { src, display } = await source(media);
174
+ checkTime(src, time, "time");
175
+ const index = frameAt(src, time);
176
+ const [width, height] = sentSize(display);
177
+ const rgba = await decodeFrame(src, index, width, height);
178
+ const jpeg = await output(ffmpeg(["-f", "rawvideo", "-pix_fmt", "rgba", "-s", `${width}x${height}`, "-i", "-", "-frames:v", "1", "-q:v", "2", "-f", "mjpeg", "-"], "pipe"), "encode the frame as JPEG", rgba);
179
+ return { jpeg, rgba, width, height, time: round(frameTime(src, index)) };
180
+ }
181
+ async function selectFrame(frame, prompt, backend = requireSelectBackend()) {
182
+ const r = await call(backend, "v1/select", { method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify({ image: frame.jpeg.toString("base64"), prompt }) }, SELECT_TIMEOUT_MS);
183
+ const body = await r.json();
184
+ if (!Array.isArray(body.objects) || typeof body.width !== "number" || typeof body.height !== "number") throw new SelectError("select server: the answer is not a selection", 502);
185
+ return { width: body.width, height: body.height, objects: body.objects, time: frame.time };
186
+ }
187
+ async function select(media, time, prompt) {
188
+ const backend = requireSelectBackend();
189
+ return selectFrame(await grabFrame(media, time), prompt, backend);
190
+ }
191
+ async function pickObject(media, time, prompt, index) {
192
+ if (!("text" in prompt)) {
193
+ if (index !== 0) throw bad(`a click prompt selects one object, so the pick is 0, not ${index}`);
194
+ return { prompt };
195
+ }
196
+ const selection = await select(media, time, prompt);
197
+ const object = selection.objects[index];
198
+ if (!object) throw bad(`nothing to pick as object ${index}: "${prompt.text}" found ${selection.objects.length} at ${selection.time} s`);
199
+ return { prompt: { text: object.label }, ...object.box ? { pick: object.box } : {} };
200
+ }
201
+ async function encodeSpan(src, first, last, size, out) {
202
+ const half = 0.5 / src.fps;
203
+ const from = src.timestamps[first] - half;
204
+ const to = last < src.timestamps.length ? `*lt(t\\,${(src.timestamps[last] - half).toFixed(6)})` : "";
205
+ const seek = Math.max(0, src.timestamps[first] - src.origin - 2);
206
+ await output(
207
+ ffmpeg([
208
+ "-copyts",
209
+ "-ss",
210
+ seek.toFixed(6),
211
+ "-noaccurate_seek",
212
+ "-i",
213
+ src.file,
214
+ "-map",
215
+ "0:v:0",
216
+ "-an",
217
+ "-sn",
218
+ "-dn",
219
+ "-vf",
220
+ `select=gte(t\\,${from.toFixed(6)})${to},setpts=PTS-STARTPTS,scale=${size[0]}:${size[1]}:flags=area,format=yuv420p`,
221
+ "-fps_mode",
222
+ "passthrough",
223
+ "-c:v",
224
+ "libx264",
225
+ "-preset",
226
+ "veryfast",
227
+ "-crf",
228
+ "20",
229
+ "-movflags",
230
+ "+faststart",
231
+ "-f",
232
+ "mp4",
233
+ "-y",
234
+ out
235
+ ]),
236
+ `cut ${src.file} for upload`
237
+ );
238
+ }
239
+ function withHeader(bytes, header) {
240
+ const length = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength).getUint32(4, true);
241
+ const json = new TextEncoder().encode(JSON.stringify({ version: 1, ...header }));
242
+ const out = new Uint8Array(8 + json.length + bytes.length - 8 - length);
243
+ out.set(bytes.subarray(0, 4), 0);
244
+ new DataView(out.buffer).setUint32(4, json.length, true);
245
+ out.set(json, 8);
246
+ out.set(bytes.subarray(8 + length), 8 + json.length);
247
+ return out;
248
+ }
249
+ var sleep = (ms, signal) => new Promise((done, fail) => {
250
+ const timer = setTimeout(done, ms);
251
+ signal?.addEventListener("abort", () => {
252
+ clearTimeout(timer);
253
+ fail(signal.reason);
254
+ }, { once: true });
255
+ });
256
+ async function track(media, options) {
257
+ const backend = requireSelectBackend();
258
+ if (!options.out.endsWith(".mask")) throw bad(`${options.out}: a mask file ends in .mask`);
259
+ if ("text" in options.prompt && conceptsOf(options.prompt.text).length > 1) throw bad("a track follows one concept; send the picked object's label as prompt.text");
260
+ const { file, src, display } = await source(media);
261
+ const n = src.timestamps.length;
262
+ if (n < 2) throw bad(`${media} is a still image; only a video can be tracked`);
263
+ checkTime(src, options.time, "time");
264
+ const start = options.start ?? Math.max(0, options.time - 2.5);
265
+ const end = Math.min(options.end ?? options.time + 2.5, src.duration);
266
+ checkTime(src, start, "start");
267
+ if (!(end > start)) throw bad(`end ${end} s must come after start ${start} s`);
268
+ if (end - start > MAX_TRACK_SECONDS) throw bad(`a track spans at most ${MAX_TRACK_SECONDS} s, not ${round(end - start, 3)} s`);
269
+ const first = frameAt(src, start);
270
+ const last = end >= src.duration - 1e-6 ? n : frameAt(src, end);
271
+ const seed = frameAt(src, options.time);
272
+ if (!(seed >= first && seed < last)) throw bad(`the prompted frame (${options.time} s) must lie in the tracked span ${start}..${end} s`);
273
+ const frames = last - first;
274
+ const [w, h] = sentSize(display);
275
+ const size = [Math.round(w / 2) * 2, Math.round(h / 2) * 2];
276
+ const work = mkdtempSync(join(tmpdir(), "higgsedit-select-"));
277
+ let id;
278
+ try {
279
+ const video = join(work, "span.mp4");
280
+ await encodeSpan(src, first, last, size, video);
281
+ const sent = (await probe(video)).timestamps.length;
282
+ if (sent !== frames) throw new Error(`the span of ${media} came out as ${sent} frames, not ${frames}`);
283
+ const form = new FormData();
284
+ form.set("video", await openAsBlob(video, { type: "video/mp4" }), "span.mp4");
285
+ form.set("prompt", JSON.stringify(options.prompt));
286
+ form.set("at", String(round(src.timestamps[seed] - src.timestamps[first])));
287
+ if (options.pick) form.set("pick", JSON.stringify(options.pick));
288
+ const posted = await (await call(backend, "v1/tracks", { method: "POST", body: form, ...options.signal ? { signal: options.signal } : {} })).json();
289
+ if (typeof posted.id !== "string" || !posted.id) throw new SelectError("select server: the track was accepted without an id", 502);
290
+ id = posted.id;
291
+ } finally {
292
+ rmSync(work, { recursive: true, force: true });
293
+ }
294
+ const deadline = Date.now() + 2 * 36e5;
295
+ let job;
296
+ for (; ; ) {
297
+ await sleep(1e3, options.signal);
298
+ job = await (await call(backend, `v1/tracks/${encodeURIComponent(id)}`, options.signal ? { signal: options.signal } : {}, POLL_TIMEOUT_MS)).json();
299
+ if (job.progress) options.onProgress?.(job.progress.done, job.progress.total);
300
+ if (job.status === "succeeded") break;
301
+ if (job.status === "failed") throw new SelectError(`select track ${id} failed: ${job.error ?? "no reason given"}`, 502);
302
+ if (job.status !== "queued" && job.status !== "running") throw new SelectError(`select track ${id}: unknown status "${String(job.status)}"`, 502);
303
+ if (Date.now() > deadline) throw new SelectError(`select track ${id}: still ${job.status} after 2 h`, 504);
304
+ }
305
+ if (!job.mask_url) throw new SelectError(`select track ${id} succeeded without a mask_url`, 502);
306
+ const bytes = new Uint8Array(await (await call(backend, job.mask_url, options.signal ? { signal: options.signal } : {}, POLL_TIMEOUT_MS)).arrayBuffer());
307
+ const mask = MaskFile.parse(bytes).header;
308
+ if (mask.frames !== frames) throw new SelectError(`select track ${id}: the mask has ${mask.frames} frames for ${frames} sent`, 502);
309
+ const startTime = round(frameTime(src, first));
310
+ const recipe = { media: file, at: round(frameTime(src, seed)), prompt: options.prompt, ...options.pick ? { pick: options.pick } : {}, span: [round(start, 3), round(end, 3)], server: backend.url, job: id };
311
+ const { version: _version, frames: _frames, ...rest } = mask;
312
+ const out = resolve(options.out);
313
+ mkdirSync(dirname(out), { recursive: true });
314
+ const part = `${out}.${process.pid}.part`;
315
+ writeFileSync(part, withHeader(bytes, { ...rest, source: display, frameRate: src.fps, start: startTime, frames, recipe }));
316
+ renameSync(part, out);
317
+ return { path: out, job: id, frames, frameRate: src.fps, start: startTime, end: round(startTime + frames / src.fps, 3), grid: mask.grid, source: display };
318
+ }
319
+ function cellsOf(mask) {
320
+ const out = new Uint8Array(mask.size[0] * mask.size[1]);
321
+ decodeMaskRuns(Buffer.from(mask.rle, "base64"), out);
322
+ return out;
323
+ }
324
+ var TINT = [209, 254, 23];
325
+ function overlay(frame, selection) {
326
+ const rgba = new Uint8Array(frame.rgba);
327
+ for (const object of selection.objects) {
328
+ const cells = cellsOf(object.mask);
329
+ for (let i = 0; i < cells.length; i++) {
330
+ if (!cells[i]) continue;
331
+ for (let c = 0; c < 3; c++) rgba[i * 4 + c] = Math.round((rgba[i * 4 + c] + TINT[c]) / 2);
332
+ }
333
+ }
334
+ return encodePng(rgba, frame.width, frame.height);
335
+ }
336
+ function point(value, what) {
337
+ const [x, y, extra] = value.split(",").map(Number);
338
+ if (x === void 0 || y === void 0 || extra !== void 0 || Number.isNaN(x) || Number.isNaN(y)) throw bad(`${what} "${value}" must be x,y`);
339
+ return { x, y };
340
+ }
341
+ var SELECT_USAGE = `usage: higgsedit select <media> --at t (--text "a, b" | --point x,y [--exclude x,y] [--box x0,y0,x1,y1]) [--json] [--overlay sel.png] [--pick n --start t --end t -o out.mask]`;
342
+ async function runSelect(args, print) {
343
+ const media = args.positional[0];
344
+ if (!media) throw new Error(SELECT_USAGE);
345
+ const box = flag(args, "box", "b")?.split(",").map(Number);
346
+ if (box && (box.length !== 4 || box.some(Number.isNaN))) throw bad("--box must be x0,y0,x1,y1");
347
+ const include = flags(args, "point", "p").map((v) => point(v, "--point"));
348
+ const exclude = flags(args, "exclude", "x").map((v) => point(v, "--exclude"));
349
+ const text = flag(args, "text");
350
+ const prompt = parsePrompt({ ...text !== void 0 ? { text } : {}, ...include.length ? { points: include } : {}, ...exclude.length ? { exclude } : {}, ...box ? { box } : {} });
351
+ requireSelectBackend();
352
+ const { mediaSeconds } = await import("./chunk-KIWGVAPJ.mjs");
353
+ const fps = await mediaSeconds.fps(media);
354
+ const time = mediaSeconds.parse(flag(args, "at", "t"), fps, "--at") ?? 0;
355
+ const out = flag(args, "o", "out");
356
+ if (out) {
357
+ const index = Number(flag(args, "pick") ?? 0);
358
+ if (!Number.isInteger(index) || index < 0) throw bad(`--pick must be an object's index (0, 1, \u2026)`);
359
+ const start = mediaSeconds.parse(flag(args, "start", "s"), fps, "--start");
360
+ const end = mediaSeconds.parse(flag(args, "end", "e"), fps, "--end");
361
+ const picked = await pickObject(media, time, prompt, index);
362
+ const r = await track(media, {
363
+ time,
364
+ ...picked,
365
+ ...start !== void 0 ? { start } : {},
366
+ ...end !== void 0 ? { end } : {},
367
+ out,
368
+ onProgress: (done, total) => process.stderr.write(`tracking ${done}/${total}
369
+ `)
370
+ });
371
+ print(r, () => [`wrote ${r.path}`, ` ${r.frames} frames @ ${round(r.frameRate, 3)} fps, ${r.start}..${r.end} s, job ${r.job}`, ` use it as mask={{ src: "<path to it in the project>" }} on the clip`].join("\n"));
372
+ return 0;
373
+ }
374
+ const frame = await grabFrame(media, time);
375
+ const selection = await selectFrame(frame, prompt);
376
+ const overlayPath = flag(args, "overlay");
377
+ if (overlayPath) writeFileSync(overlayPath, overlay(frame, selection));
378
+ const pad = Math.max(0, ...selection.objects.map((o) => o.label.length));
379
+ print(
380
+ selection,
381
+ () => [
382
+ `${media} at ${selection.time} s (${selection.width}x${selection.height}): ${selection.objects.length} object${selection.objects.length === 1 ? "" : "s"}`,
383
+ ...selection.objects.map((o) => ` ${o.id} ${o.label.padEnd(pad)} ${o.score.toFixed(2)} box ${o.box ? o.box.join(",") : "none"} area ${o.area}`),
384
+ ...overlayPath ? [` overlay ${overlayPath}`] : []
385
+ ].join("\n")
386
+ );
387
+ return 0;
388
+ }
389
+
390
+ export {
391
+ SelectError,
392
+ selectBackend,
393
+ requireSelectBackend,
394
+ parsePrompt,
395
+ selectStatus,
396
+ grabFrame,
397
+ selectFrame,
398
+ select,
399
+ pickObject,
400
+ track,
401
+ SELECT_USAGE,
402
+ runSelect
403
+ };