@ignix-social/editor 0.1.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 (586) hide show
  1. package/LICENSE +190 -0
  2. package/NOTICE +54 -0
  3. package/README.md +23 -0
  4. package/bin/ignix-editor.mjs +8 -0
  5. package/package.json +53 -0
  6. package/patches/index.mjs +53 -0
  7. package/scripts/build-ffmpeg-macos.sh +35 -0
  8. package/scripts/build-whisper-macos.sh +21 -0
  9. package/scripts/vendor.mjs +41 -0
  10. package/skills/ignix-editor/SKILL.md +132 -0
  11. package/src/audio.mjs +31 -0
  12. package/src/binaries.json +46 -0
  13. package/src/binaries.mjs +83 -0
  14. package/src/cli.mjs +254 -0
  15. package/src/prepare.mjs +74 -0
  16. package/src/runtime/ignix-frame.js +92 -0
  17. package/src/transcribe.mjs +71 -0
  18. package/src/validate.mjs +71 -0
  19. package/templates/blank/index.html +41 -0
  20. package/vendor/hyperframes/README.md +181 -0
  21. package/vendor/hyperframes/UPSTREAM.json +12 -0
  22. package/vendor/hyperframes/bin/hyperframes-localize-fonts.mjs +12 -0
  23. package/vendor/hyperframes/bin/hyperframes.mjs +11 -0
  24. package/vendor/hyperframes/dist/add-LR3ZR2A5.js +79 -0
  25. package/vendor/hyperframes/dist/agentPromptGenerator-VIIPZCJ3.js +143 -0
  26. package/vendor/hyperframes/dist/animatedGifPrep-P2T6YM7Z.js +34 -0
  27. package/vendor/hyperframes/dist/asset-BE2DOV72.js +26 -0
  28. package/vendor/hyperframes/dist/assetCataloger-VBLPHX24.js +340 -0
  29. package/vendor/hyperframes/dist/auth-RCQB2ZT7.js +60 -0
  30. package/vendor/hyperframes/dist/autoUpdate-RJAX3DAZ.js +268 -0
  31. package/vendor/hyperframes/dist/backgroundChecks-H2LCUIMJ.js +61 -0
  32. package/vendor/hyperframes/dist/backgroundChecksWorker.js +26 -0
  33. package/vendor/hyperframes/dist/batchRender-FT7AP7XH.js +355 -0
  34. package/vendor/hyperframes/dist/beat-analyzer.global.js +338 -0
  35. package/vendor/hyperframes/dist/beats-Y2EOP72P.js +309 -0
  36. package/vendor/hyperframes/dist/benchmark-MZ7GY3JW.js +231 -0
  37. package/vendor/hyperframes/dist/browser-HUTAMRQE.js +237 -0
  38. package/vendor/hyperframes/dist/bundleWithLocalizedFonts-5QOPOB5D.js +52 -0
  39. package/vendor/hyperframes/dist/capture-RLZA6EMR.js +4079 -0
  40. package/vendor/hyperframes/dist/capture-SZZ4IYJK.js +290 -0
  41. package/vendor/hyperframes/dist/captureFile-LYOJOUIE.js +15 -0
  42. package/vendor/hyperframes/dist/captureTimeout-PA4FYWT5.js +27 -0
  43. package/vendor/hyperframes/dist/catalog-KYU55EWR.js +1001 -0
  44. package/vendor/hyperframes/dist/check-TCG4PXLR.js +1697 -0
  45. package/vendor/hyperframes/dist/checkBrowser-RPMO4OW5.js +1032 -0
  46. package/vendor/hyperframes/dist/chunk-2EAXUCCE.js +88 -0
  47. package/vendor/hyperframes/dist/chunk-2EGFTPWD.js +1077 -0
  48. package/vendor/hyperframes/dist/chunk-2PSPARWP.js +6058 -0
  49. package/vendor/hyperframes/dist/chunk-2YN64IN5.js +5747 -0
  50. package/vendor/hyperframes/dist/chunk-3GXQPCJC.js +682 -0
  51. package/vendor/hyperframes/dist/chunk-3ZP5DXE7.js +15 -0
  52. package/vendor/hyperframes/dist/chunk-4NWOGZZS.js +1990 -0
  53. package/vendor/hyperframes/dist/chunk-4PFZPP2N.js +587 -0
  54. package/vendor/hyperframes/dist/chunk-4THIAPBL.js +128 -0
  55. package/vendor/hyperframes/dist/chunk-4YYJOFKS.js +28 -0
  56. package/vendor/hyperframes/dist/chunk-54HJ63Q2.js +29 -0
  57. package/vendor/hyperframes/dist/chunk-5ETJX6WM.js +89 -0
  58. package/vendor/hyperframes/dist/chunk-5IAKAQA7.js +389 -0
  59. package/vendor/hyperframes/dist/chunk-5Z63TBTX.js +37 -0
  60. package/vendor/hyperframes/dist/chunk-6BEFEWFB.js +25 -0
  61. package/vendor/hyperframes/dist/chunk-6CSYCFQV.js +68 -0
  62. package/vendor/hyperframes/dist/chunk-6CTIGJY7.js +154 -0
  63. package/vendor/hyperframes/dist/chunk-7HG4BFIN.js +93 -0
  64. package/vendor/hyperframes/dist/chunk-7JZ4FXP2.js +118 -0
  65. package/vendor/hyperframes/dist/chunk-A2Z4Z4VL.js +2961 -0
  66. package/vendor/hyperframes/dist/chunk-AMKC3AXA.js +25 -0
  67. package/vendor/hyperframes/dist/chunk-AVUUN2XD.js +4847 -0
  68. package/vendor/hyperframes/dist/chunk-AWDFDFI3.js +46 -0
  69. package/vendor/hyperframes/dist/chunk-AWNBM3MZ.js +94 -0
  70. package/vendor/hyperframes/dist/chunk-BXCMXMJQ.js +73 -0
  71. package/vendor/hyperframes/dist/chunk-BZ56MTDX.js +6 -0
  72. package/vendor/hyperframes/dist/chunk-CFKU7HTK.js +171 -0
  73. package/vendor/hyperframes/dist/chunk-CWPVM2QV.js +308 -0
  74. package/vendor/hyperframes/dist/chunk-DPVXBVLL.js +31292 -0
  75. package/vendor/hyperframes/dist/chunk-DQBY7FRR.js +397 -0
  76. package/vendor/hyperframes/dist/chunk-E6RPWJVC.js +213 -0
  77. package/vendor/hyperframes/dist/chunk-EISRN4E6.js +294 -0
  78. package/vendor/hyperframes/dist/chunk-EOVYQ3IG.js +143 -0
  79. package/vendor/hyperframes/dist/chunk-F3WZGU7C.js +479 -0
  80. package/vendor/hyperframes/dist/chunk-FCSIGXXP.js +366 -0
  81. package/vendor/hyperframes/dist/chunk-FI4I7CME.js +56 -0
  82. package/vendor/hyperframes/dist/chunk-FLWXXDNS.js +15 -0
  83. package/vendor/hyperframes/dist/chunk-GK4AIFIH.js +11171 -0
  84. package/vendor/hyperframes/dist/chunk-GMECXFAN.js +57 -0
  85. package/vendor/hyperframes/dist/chunk-GULOKZLI.js +155 -0
  86. package/vendor/hyperframes/dist/chunk-H4YZZ2VQ.js +68 -0
  87. package/vendor/hyperframes/dist/chunk-H6QMKUYA.js +477 -0
  88. package/vendor/hyperframes/dist/chunk-HBBJFK6I.js +273 -0
  89. package/vendor/hyperframes/dist/chunk-HRUGC23L.js +212 -0
  90. package/vendor/hyperframes/dist/chunk-HVW7ABXD.js +19 -0
  91. package/vendor/hyperframes/dist/chunk-HW6OYASV.js +344 -0
  92. package/vendor/hyperframes/dist/chunk-HWKCIWQT.js +3578 -0
  93. package/vendor/hyperframes/dist/chunk-I465DBM6.js +1214 -0
  94. package/vendor/hyperframes/dist/chunk-IGLEPPTN.js +24 -0
  95. package/vendor/hyperframes/dist/chunk-IGNAAHS3.js +433 -0
  96. package/vendor/hyperframes/dist/chunk-IHFUKJOR.js +85 -0
  97. package/vendor/hyperframes/dist/chunk-IQ3OUQ5Z.js +213 -0
  98. package/vendor/hyperframes/dist/chunk-ISN5GRYI.js +20 -0
  99. package/vendor/hyperframes/dist/chunk-IUZFXWSV.js +446 -0
  100. package/vendor/hyperframes/dist/chunk-JH556Q42.js +647 -0
  101. package/vendor/hyperframes/dist/chunk-JTHMTOMQ.js +601 -0
  102. package/vendor/hyperframes/dist/chunk-K2EQN4VU.js +405 -0
  103. package/vendor/hyperframes/dist/chunk-K2FTXJYH.js +16044 -0
  104. package/vendor/hyperframes/dist/chunk-K4WIOZFP.js +32 -0
  105. package/vendor/hyperframes/dist/chunk-K4WKGXRC.js +18 -0
  106. package/vendor/hyperframes/dist/chunk-KBJUXVOJ.js +172 -0
  107. package/vendor/hyperframes/dist/chunk-KC5XXX3X.js +590 -0
  108. package/vendor/hyperframes/dist/chunk-KNU5COPB.js +29 -0
  109. package/vendor/hyperframes/dist/chunk-KZI44OPA.js +185 -0
  110. package/vendor/hyperframes/dist/chunk-L3YOGIPG.js +48 -0
  111. package/vendor/hyperframes/dist/chunk-LAOCA3MQ.js +189 -0
  112. package/vendor/hyperframes/dist/chunk-LCSMOLGX.js +312 -0
  113. package/vendor/hyperframes/dist/chunk-LFGJWOVA.js +61 -0
  114. package/vendor/hyperframes/dist/chunk-LHSR3M4M.js +498 -0
  115. package/vendor/hyperframes/dist/chunk-LYNI3FOL.js +123 -0
  116. package/vendor/hyperframes/dist/chunk-M2WBOQ2Q.js +54 -0
  117. package/vendor/hyperframes/dist/chunk-MRF4AMKD.js +104 -0
  118. package/vendor/hyperframes/dist/chunk-MWB3ZIFM.js +852 -0
  119. package/vendor/hyperframes/dist/chunk-NGKM64BP.js +39 -0
  120. package/vendor/hyperframes/dist/chunk-NXMYHJAL.js +43 -0
  121. package/vendor/hyperframes/dist/chunk-OAF4XJOW.js +192 -0
  122. package/vendor/hyperframes/dist/chunk-OFQWTKPW.js +117 -0
  123. package/vendor/hyperframes/dist/chunk-P6LJ4Y32.js +4662 -0
  124. package/vendor/hyperframes/dist/chunk-PBN6GBJE.js +108 -0
  125. package/vendor/hyperframes/dist/chunk-PDAMK4Q5.js +28 -0
  126. package/vendor/hyperframes/dist/chunk-PFCFR3KZ.js +20 -0
  127. package/vendor/hyperframes/dist/chunk-PJ3HDUCY.js +108 -0
  128. package/vendor/hyperframes/dist/chunk-PMRBLBUP.js +152 -0
  129. package/vendor/hyperframes/dist/chunk-PPQUYWTW.js +240 -0
  130. package/vendor/hyperframes/dist/chunk-Q5X2B5WT.js +29 -0
  131. package/vendor/hyperframes/dist/chunk-Q7IU7MOR.js +351 -0
  132. package/vendor/hyperframes/dist/chunk-QC4FJVLM.js +371 -0
  133. package/vendor/hyperframes/dist/chunk-QNYYOUU3.js +1318 -0
  134. package/vendor/hyperframes/dist/chunk-RDNNAKEP.js +161 -0
  135. package/vendor/hyperframes/dist/chunk-RMHUQGRK.js +657 -0
  136. package/vendor/hyperframes/dist/chunk-RQVDTPGD.js +6 -0
  137. package/vendor/hyperframes/dist/chunk-RVCWIIZ7.js +68 -0
  138. package/vendor/hyperframes/dist/chunk-S3D6GE5W.js +72 -0
  139. package/vendor/hyperframes/dist/chunk-S3S4TGEH.js +424 -0
  140. package/vendor/hyperframes/dist/chunk-S7NPLFWV.js +11395 -0
  141. package/vendor/hyperframes/dist/chunk-SHB5VDMH.js +51 -0
  142. package/vendor/hyperframes/dist/chunk-TCLGPL65.js +860 -0
  143. package/vendor/hyperframes/dist/chunk-THXFSPLV.js +40 -0
  144. package/vendor/hyperframes/dist/chunk-TJSTGSAW.js +354 -0
  145. package/vendor/hyperframes/dist/chunk-TQFG7HTI.js +1024 -0
  146. package/vendor/hyperframes/dist/chunk-TVCRUG2S.js +265 -0
  147. package/vendor/hyperframes/dist/chunk-TWWSYAKJ.js +24 -0
  148. package/vendor/hyperframes/dist/chunk-U7CZBDMV.js +27 -0
  149. package/vendor/hyperframes/dist/chunk-UEZXMWG3.js +139 -0
  150. package/vendor/hyperframes/dist/chunk-UYEZTK4U.js +61 -0
  151. package/vendor/hyperframes/dist/chunk-VC76R6W2.js +27 -0
  152. package/vendor/hyperframes/dist/chunk-VFCKXTBB.js +159 -0
  153. package/vendor/hyperframes/dist/chunk-VWG7OQKU.js +22 -0
  154. package/vendor/hyperframes/dist/chunk-VXVRPIJA.js +105 -0
  155. package/vendor/hyperframes/dist/chunk-WBLXWOYK.js +15 -0
  156. package/vendor/hyperframes/dist/chunk-WERLJGIC.js +20 -0
  157. package/vendor/hyperframes/dist/chunk-WMQNIQDJ.js +2057 -0
  158. package/vendor/hyperframes/dist/chunk-WPHMNO44.js +4528 -0
  159. package/vendor/hyperframes/dist/chunk-X5HWXQPU.js +113 -0
  160. package/vendor/hyperframes/dist/chunk-X7MTZ4T2.js +6 -0
  161. package/vendor/hyperframes/dist/chunk-XH4DSOS5.js +59 -0
  162. package/vendor/hyperframes/dist/chunk-XS4EJSKU.js +23 -0
  163. package/vendor/hyperframes/dist/chunk-XT5P4QMO.js +181 -0
  164. package/vendor/hyperframes/dist/chunk-XT7X6QCP.js +6 -0
  165. package/vendor/hyperframes/dist/chunk-XUHOIDKG.js +6 -0
  166. package/vendor/hyperframes/dist/chunk-XUXGIA7H.js +485 -0
  167. package/vendor/hyperframes/dist/chunk-XZABUQTX.js +113 -0
  168. package/vendor/hyperframes/dist/chunk-Y6W4DVPS.js +356 -0
  169. package/vendor/hyperframes/dist/chunk-YEIFI443.js +44 -0
  170. package/vendor/hyperframes/dist/chunk-YQZNILVH.js +375 -0
  171. package/vendor/hyperframes/dist/chunk-Z27A7NUB.js +65 -0
  172. package/vendor/hyperframes/dist/chunk-Z6B37SNM.js +3081 -0
  173. package/vendor/hyperframes/dist/chunk-ZJUKFZ2P.js +10954 -0
  174. package/vendor/hyperframes/dist/chunk-ZKDMAOFU.js +32 -0
  175. package/vendor/hyperframes/dist/chunk-ZMXUQLI2.js +17219 -0
  176. package/vendor/hyperframes/dist/chunk-ZTZ7NCJT.js +58 -0
  177. package/vendor/hyperframes/dist/chunk-ZTZA4UWZ.js +108 -0
  178. package/vendor/hyperframes/dist/clean-W57E5YQ3.js +293 -0
  179. package/vendor/hyperframes/dist/cli.js +495 -0
  180. package/vendor/hyperframes/dist/cloud-FFTJGZ24.js +70 -0
  181. package/vendor/hyperframes/dist/cloudrun-AJUTHUEA.js +763 -0
  182. package/vendor/hyperframes/dist/colors-HKWSZCGK.js +15 -0
  183. package/vendor/hyperframes/dist/commands/contrast-audit.browser.js +459 -0
  184. package/vendor/hyperframes/dist/commands/layout-audit.browser.js +2102 -0
  185. package/vendor/hyperframes/dist/commands/motion-sample.browser.js +74 -0
  186. package/vendor/hyperframes/dist/commands/motion-signature.browser.js +374 -0
  187. package/vendor/hyperframes/dist/compare-AYCTT55F.js +421 -0
  188. package/vendor/hyperframes/dist/compiler-QO36EXLS.js +121 -0
  189. package/vendor/hyperframes/dist/component-VFFR2O7T.js +176 -0
  190. package/vendor/hyperframes/dist/compositions-QTVN3U2A.js +228 -0
  191. package/vendor/hyperframes/dist/contactSheet-27SRU7A4.js +22 -0
  192. package/vendor/hyperframes/dist/delete-ZAKYCB7I.js +114 -0
  193. package/vendor/hyperframes/dist/deploy-MX76RZ36.js +101 -0
  194. package/vendor/hyperframes/dist/destroy-H2TZBYHH.js +42 -0
  195. package/vendor/hyperframes/dist/deterministicFonts-HAEMV4TM.js +50 -0
  196. package/vendor/hyperframes/dist/dist-EWXJGN63.js +129 -0
  197. package/vendor/hyperframes/dist/dist-FNNGCKFS.js +29 -0
  198. package/vendor/hyperframes/dist/dist-S3PJNPXQ.js +392 -0
  199. package/vendor/hyperframes/dist/docker/Dockerfile.render +65 -0
  200. package/vendor/hyperframes/dist/docs/compositions.md +67 -0
  201. package/vendor/hyperframes/dist/docs/data-attributes.md +27 -0
  202. package/vendor/hyperframes/dist/docs/examples.md +19 -0
  203. package/vendor/hyperframes/dist/docs/gsap.md +26 -0
  204. package/vendor/hyperframes/dist/docs/rendering.md +35 -0
  205. package/vendor/hyperframes/dist/docs/troubleshooting.md +29 -0
  206. package/vendor/hyperframes/dist/docs-QAPJEGLS.js +131 -0
  207. package/vendor/hyperframes/dist/doctor-AI7C3FON.js +67 -0
  208. package/vendor/hyperframes/dist/dom-IROKGVJI.js +14 -0
  209. package/vendor/hyperframes/dist/dotEnv-AECLXQSO.js +14 -0
  210. package/vendor/hyperframes/dist/events-7LALYNKZ.js +92 -0
  211. package/vendor/hyperframes/dist/events-FQY3HGKZ.js +88 -0
  212. package/vendor/hyperframes/dist/feedback-WCMDMSTK.js +472 -0
  213. package/vendor/hyperframes/dist/ffmpeg-QIUFEFTY.js +35 -0
  214. package/vendor/hyperframes/dist/figma-64WY462P.js +63 -0
  215. package/vendor/hyperframes/dist/fontData.generated-NXAOI4GH.js +13 -0
  216. package/vendor/hyperframes/dist/fontLocalizeCli.js +132 -0
  217. package/vendor/hyperframes/dist/get-FPOMJMZB.js +103 -0
  218. package/vendor/hyperframes/dist/gpuPolicy-2ZUZE5D6.js +38 -0
  219. package/vendor/hyperframes/dist/grade-compare-E2CKPST4.js +647 -0
  220. package/vendor/hyperframes/dist/gsapParser-DIYYX6JT.js +2846 -0
  221. package/vendor/hyperframes/dist/gsapParserAcorn-E3GEIRZB.js +28 -0
  222. package/vendor/hyperframes/dist/help-YRQIDDML.js +197 -0
  223. package/vendor/hyperframes/dist/history-PP5NDRV3.js +571 -0
  224. package/vendor/hyperframes/dist/hyperframe-runtime.js +1081 -0
  225. package/vendor/hyperframes/dist/hyperframe.manifest.json +22 -0
  226. package/vendor/hyperframes/dist/hyperframe.runtime.iife.js +1081 -0
  227. package/vendor/hyperframes/dist/hyperframes-player.global.js +474 -0
  228. package/vendor/hyperframes/dist/hyperframes-slideshow.global.js +149 -0
  229. package/vendor/hyperframes/dist/info-SEX3B7JL.js +153 -0
  230. package/vendor/hyperframes/dist/init-U3AKHO5B.js +1147 -0
  231. package/vendor/hyperframes/dist/inspect-Q3K6EDEK.js +97 -0
  232. package/vendor/hyperframes/dist/installer-K6O5WF44.js +37 -0
  233. package/vendor/hyperframes/dist/keyframes-DC64JCI3.js +2602 -0
  234. package/vendor/hyperframes/dist/lambda-D7UMN4DJ.js +451 -0
  235. package/vendor/hyperframes/dist/layout-XSPPDHOO.js +86 -0
  236. package/vendor/hyperframes/dist/lib-TPG2ZMAX.js +128 -0
  237. package/vendor/hyperframes/dist/lint-7DQZE7L3.js +164 -0
  238. package/vendor/hyperframes/dist/lintProject-OHBBM3DJ.js +27 -0
  239. package/vendor/hyperframes/dist/list-4K5MVDQX.js +162 -0
  240. package/vendor/hyperframes/dist/login-NTX4OWXL.js +377 -0
  241. package/vendor/hyperframes/dist/logout-Q654A3SI.js +100 -0
  242. package/vendor/hyperframes/dist/manager-67P2XFXQ.js +34 -0
  243. package/vendor/hyperframes/dist/manager-CT3D67CG.js +38 -0
  244. package/vendor/hyperframes/dist/manager-GFN75DM4.js +30 -0
  245. package/vendor/hyperframes/dist/media-treatment-5FYAOPNL.js +972 -0
  246. package/vendor/hyperframes/dist/media-use-4XXGABIL.js +113 -0
  247. package/vendor/hyperframes/dist/models-C4E4IWJD.js +137 -0
  248. package/vendor/hyperframes/dist/motionShot-S4MIGMT5.js +614 -0
  249. package/vendor/hyperframes/dist/normalize-O76AC4HE.js +333 -0
  250. package/vendor/hyperframes/dist/normalize-audio-CSFTXLXD.js +276 -0
  251. package/vendor/hyperframes/dist/open-2ZD6BHZG.js +115 -0
  252. package/vendor/hyperframes/dist/pipeline-TNGWUZQC.js +54 -0
  253. package/vendor/hyperframes/dist/play-CTMUXX6E.js +349 -0
  254. package/vendor/hyperframes/dist/policies-FSDZVS2E.js +292 -0
  255. package/vendor/hyperframes/dist/preflight-SMNV6RW2.js +45 -0
  256. package/vendor/hyperframes/dist/present-WQVHV5CR.js +350 -0
  257. package/vendor/hyperframes/dist/preview-JOJXTH75.js +1820 -0
  258. package/vendor/hyperframes/dist/producer-ECLEN5RP.js +13 -0
  259. package/vendor/hyperframes/dist/progress-FBIEEB7Y.js +73 -0
  260. package/vendor/hyperframes/dist/projectConfig-HYJMJ5BY.js +56 -0
  261. package/vendor/hyperframes/dist/publication-HQ5Y3KBM.js +29 -0
  262. package/vendor/hyperframes/dist/publish-VHDYQASC.js +430 -0
  263. package/vendor/hyperframes/dist/refresh-K24ETHMA.js +53 -0
  264. package/vendor/hyperframes/dist/remove-background-W2YX2NVH.js +253 -0
  265. package/vendor/hyperframes/dist/render-AO5VX3YI.js +177 -0
  266. package/vendor/hyperframes/dist/render-LNO62LEL.js +2367 -0
  267. package/vendor/hyperframes/dist/render-TTQI7TGN.js +796 -0
  268. package/vendor/hyperframes/dist/render-batch-YH7CTWNY.js +284 -0
  269. package/vendor/hyperframes/dist/renderCancellation-JPIHE47X.js +35 -0
  270. package/vendor/hyperframes/dist/renderSetupWorker.js +79 -0
  271. package/vendor/hyperframes/dist/resolver-IZ647GBZ.js +38 -0
  272. package/vendor/hyperframes/dist/runtimeVersion.js +18 -0
  273. package/vendor/hyperframes/dist/screenshotCapture-ECBTLCU6.js +179 -0
  274. package/vendor/hyperframes/dist/shaderTransitionWorker.js +44 -0
  275. package/vendor/hyperframes/dist/sherpa-KKLNW6U2.js +314 -0
  276. package/vendor/hyperframes/dist/sherpaWorker.js +77 -0
  277. package/vendor/hyperframes/dist/sites-TNVKZS73.js +52 -0
  278. package/vendor/hyperframes/dist/skill-ZHVLH7KX.js +15 -0
  279. package/vendor/hyperframes/dist/skills/hyperframes/SKILL.md +152 -0
  280. package/vendor/hyperframes/dist/skills/hyperframes/references/brief-contract.md +108 -0
  281. package/vendor/hyperframes/dist/skills/hyperframes/references/brief-format.md +72 -0
  282. package/vendor/hyperframes/dist/skills/hyperframes/references/capability-menu.md +47 -0
  283. package/vendor/hyperframes/dist/skills/hyperframes/references/frame-worker-core.md +80 -0
  284. package/vendor/hyperframes/dist/skills/hyperframes/references/intent-interview.md +73 -0
  285. package/vendor/hyperframes/dist/skills/hyperframes/references/pitch-round.md +40 -0
  286. package/vendor/hyperframes/dist/skills/hyperframes/references/plugin-installation.md +43 -0
  287. package/vendor/hyperframes/dist/skills/hyperframes/references/production-loop.md +26 -0
  288. package/vendor/hyperframes/dist/skills/hyperframes/references/review-loop.md +37 -0
  289. package/vendor/hyperframes/dist/skills/hyperframes/references/route-briefs.md +11 -0
  290. package/vendor/hyperframes/dist/skills/hyperframes/references/routes/embedded-captions.md +11 -0
  291. package/vendor/hyperframes/dist/skills/hyperframes/references/routes/faceless-explainer.md +12 -0
  292. package/vendor/hyperframes/dist/skills/hyperframes/references/routes/general-video.md +12 -0
  293. package/vendor/hyperframes/dist/skills/hyperframes/references/routes/motion-graphics.md +11 -0
  294. package/vendor/hyperframes/dist/skills/hyperframes/references/routes/music-to-video.md +12 -0
  295. package/vendor/hyperframes/dist/skills/hyperframes/references/routes/pr-to-video.md +28 -0
  296. package/vendor/hyperframes/dist/skills/hyperframes/references/routes/product-launch-video.md +13 -0
  297. package/vendor/hyperframes/dist/skills/hyperframes/references/routes/remotion-to-hyperframes.md +9 -0
  298. package/vendor/hyperframes/dist/skills/hyperframes/references/routes/slideshow.md +11 -0
  299. package/vendor/hyperframes/dist/skills/hyperframes/references/routes/talking-head-recut.md +11 -0
  300. package/vendor/hyperframes/dist/skills/hyperframes/references/script-format.md +52 -0
  301. package/vendor/hyperframes/dist/skills/hyperframes/references/skill-lifecycle.md +35 -0
  302. package/vendor/hyperframes/dist/skills/hyperframes/references/storyboard-format.md +99 -0
  303. package/vendor/hyperframes/dist/skills/hyperframes/references/subagent-dispatch.md +35 -0
  304. package/vendor/hyperframes/dist/skills/hyperframes/references/workflow-catalog.md +10 -0
  305. package/vendor/hyperframes/dist/skills/hyperframes/scripts/lib/frame-packets-core.mjs +194 -0
  306. package/vendor/hyperframes/dist/skills/hyperframes/scripts/plugin-cli.mjs +88 -0
  307. package/vendor/hyperframes/dist/skills/hyperframes/scripts/plugin-cli.test.mjs +117 -0
  308. package/vendor/hyperframes/dist/skills/hyperframes-cli/SKILL.md +189 -0
  309. package/vendor/hyperframes/dist/skills/hyperframes-cli/references/beats.md +19 -0
  310. package/vendor/hyperframes/dist/skills/hyperframes-cli/references/cloud.md +163 -0
  311. package/vendor/hyperframes/dist/skills/hyperframes-cli/references/cloudrun.md +62 -0
  312. package/vendor/hyperframes/dist/skills/hyperframes-cli/references/compare-and-batch.md +105 -0
  313. package/vendor/hyperframes/dist/skills/hyperframes-cli/references/doctor-browser.md +57 -0
  314. package/vendor/hyperframes/dist/skills/hyperframes-cli/references/init-and-scaffold.md +74 -0
  315. package/vendor/hyperframes/dist/skills/hyperframes-cli/references/lambda.md +185 -0
  316. package/vendor/hyperframes/dist/skills/hyperframes-cli/references/lint-validate-inspect.md +132 -0
  317. package/vendor/hyperframes/dist/skills/hyperframes-cli/references/preview-render.md +193 -0
  318. package/vendor/hyperframes/dist/skills/hyperframes-cli/references/upgrade-info-misc.md +134 -0
  319. package/vendor/hyperframes/dist/skills/media-use/SKILL.md +100 -0
  320. package/vendor/hyperframes/dist/skills/media-use/audio/assets/sfx/CREDITS.md +35 -0
  321. package/vendor/hyperframes/dist/skills/media-use/audio/assets/sfx/chime.mp3 +0 -0
  322. package/vendor/hyperframes/dist/skills/media-use/audio/assets/sfx/click-soft.mp3 +0 -0
  323. package/vendor/hyperframes/dist/skills/media-use/audio/assets/sfx/click.mp3 +0 -0
  324. package/vendor/hyperframes/dist/skills/media-use/audio/assets/sfx/error.mp3 +0 -0
  325. package/vendor/hyperframes/dist/skills/media-use/audio/assets/sfx/glitch-1.mp3 +0 -0
  326. package/vendor/hyperframes/dist/skills/media-use/audio/assets/sfx/glitch-2.mp3 +0 -0
  327. package/vendor/hyperframes/dist/skills/media-use/audio/assets/sfx/glitch-3.mp3 +0 -0
  328. package/vendor/hyperframes/dist/skills/media-use/audio/assets/sfx/impact-bass-1.mp3 +0 -0
  329. package/vendor/hyperframes/dist/skills/media-use/audio/assets/sfx/impact-bass-2.mp3 +0 -0
  330. package/vendor/hyperframes/dist/skills/media-use/audio/assets/sfx/key-press.mp3 +0 -0
  331. package/vendor/hyperframes/dist/skills/media-use/audio/assets/sfx/manifest.json +97 -0
  332. package/vendor/hyperframes/dist/skills/media-use/audio/assets/sfx/notification.mp3 +0 -0
  333. package/vendor/hyperframes/dist/skills/media-use/audio/assets/sfx/ping.mp3 +0 -0
  334. package/vendor/hyperframes/dist/skills/media-use/audio/assets/sfx/pop.mp3 +0 -0
  335. package/vendor/hyperframes/dist/skills/media-use/audio/assets/sfx/riser.mp3 +0 -0
  336. package/vendor/hyperframes/dist/skills/media-use/audio/assets/sfx/sparkle.mp3 +0 -0
  337. package/vendor/hyperframes/dist/skills/media-use/audio/assets/sfx/typing.mp3 +0 -0
  338. package/vendor/hyperframes/dist/skills/media-use/audio/assets/sfx/whoosh-cinematic.mp3 +0 -0
  339. package/vendor/hyperframes/dist/skills/media-use/audio/assets/sfx/whoosh-short.mp3 +0 -0
  340. package/vendor/hyperframes/dist/skills/media-use/audio/assets/sfx/whoosh.mp3 +0 -0
  341. package/vendor/hyperframes/dist/skills/media-use/audio/references/bgm.md +76 -0
  342. package/vendor/hyperframes/dist/skills/media-use/audio/references/captions/authoring.md +163 -0
  343. package/vendor/hyperframes/dist/skills/media-use/audio/references/captions/motion.md +87 -0
  344. package/vendor/hyperframes/dist/skills/media-use/audio/references/captions/transcript-handling.md +97 -0
  345. package/vendor/hyperframes/dist/skills/media-use/audio/references/remove-background.md +143 -0
  346. package/vendor/hyperframes/dist/skills/media-use/audio/references/requirements.md +29 -0
  347. package/vendor/hyperframes/dist/skills/media-use/audio/references/sfx.md +42 -0
  348. package/vendor/hyperframes/dist/skills/media-use/audio/references/transcribe.md +52 -0
  349. package/vendor/hyperframes/dist/skills/media-use/audio/references/tts-to-captions.md +35 -0
  350. package/vendor/hyperframes/dist/skills/media-use/audio/references/tts.md +260 -0
  351. package/vendor/hyperframes/dist/skills/media-use/audio/scripts/audio.mjs +311 -0
  352. package/vendor/hyperframes/dist/skills/media-use/audio/scripts/audio.test.mjs +159 -0
  353. package/vendor/hyperframes/dist/skills/media-use/audio/scripts/gemini-pipeline.test.mjs +131 -0
  354. package/vendor/hyperframes/dist/skills/media-use/audio/scripts/heygen-tts.mjs +122 -0
  355. package/vendor/hyperframes/dist/skills/media-use/audio/scripts/heygen-tts.test.mjs +38 -0
  356. package/vendor/hyperframes/dist/skills/media-use/audio/scripts/heygen-voice.mjs +98 -0
  357. package/vendor/hyperframes/dist/skills/media-use/audio/scripts/heygen-voice.test.mjs +233 -0
  358. package/vendor/hyperframes/dist/skills/media-use/audio/scripts/lib/audio-meta.mjs +39 -0
  359. package/vendor/hyperframes/dist/skills/media-use/audio/scripts/lib/audio-meta.test.mjs +136 -0
  360. package/vendor/hyperframes/dist/skills/media-use/audio/scripts/lib/bgm-volume.mjs +4 -0
  361. package/vendor/hyperframes/dist/skills/media-use/audio/scripts/lib/bgm.mjs +257 -0
  362. package/vendor/hyperframes/dist/skills/media-use/audio/scripts/lib/bgm.test.mjs +74 -0
  363. package/vendor/hyperframes/dist/skills/media-use/audio/scripts/lib/concurrency.mjs +14 -0
  364. package/vendor/hyperframes/dist/skills/media-use/audio/scripts/lib/concurrency.test.mjs +41 -0
  365. package/vendor/hyperframes/dist/skills/media-use/audio/scripts/lib/gemini-auth.mjs +43 -0
  366. package/vendor/hyperframes/dist/skills/media-use/audio/scripts/lib/gemini-auth.py +52 -0
  367. package/vendor/hyperframes/dist/skills/media-use/audio/scripts/lib/gemini-auth.test.mjs +86 -0
  368. package/vendor/hyperframes/dist/skills/media-use/audio/scripts/lib/gemini-auth_test.py +90 -0
  369. package/vendor/hyperframes/dist/skills/media-use/audio/scripts/lib/gemini-tts.mjs +122 -0
  370. package/vendor/hyperframes/dist/skills/media-use/audio/scripts/lib/gemini-tts.test.mjs +243 -0
  371. package/vendor/hyperframes/dist/skills/media-use/audio/scripts/lib/heygen.mjs +197 -0
  372. package/vendor/hyperframes/dist/skills/media-use/audio/scripts/lib/heygen.test.mjs +185 -0
  373. package/vendor/hyperframes/dist/skills/media-use/audio/scripts/lib/media-record.mjs +114 -0
  374. package/vendor/hyperframes/dist/skills/media-use/audio/scripts/lib/media-record.test.mjs +205 -0
  375. package/vendor/hyperframes/dist/skills/media-use/audio/scripts/lib/python.mjs +77 -0
  376. package/vendor/hyperframes/dist/skills/media-use/audio/scripts/lib/python.test.mjs +136 -0
  377. package/vendor/hyperframes/dist/skills/media-use/audio/scripts/lib/sfx.mjs +165 -0
  378. package/vendor/hyperframes/dist/skills/media-use/audio/scripts/lib/sfx.test.mjs +121 -0
  379. package/vendor/hyperframes/dist/skills/media-use/audio/scripts/lib/tts.mjs +389 -0
  380. package/vendor/hyperframes/dist/skills/media-use/audio/scripts/lib/tts.spawn.test.mjs +158 -0
  381. package/vendor/hyperframes/dist/skills/media-use/audio/scripts/lib/tts.test.mjs +230 -0
  382. package/vendor/hyperframes/dist/skills/media-use/audio/scripts/lyria-recipe.py +136 -0
  383. package/vendor/hyperframes/dist/skills/media-use/audio/scripts/wait-bgm.mjs +175 -0
  384. package/vendor/hyperframes/dist/skills/media-use/audio/scripts/wait-bgm.test.mjs +108 -0
  385. package/vendor/hyperframes/dist/skills/media-use/luts/README.md +28 -0
  386. package/vendor/hyperframes/dist/skills/media-use/luts/index.json +57 -0
  387. package/vendor/hyperframes/dist/skills/media-use/references/audio.md +20 -0
  388. package/vendor/hyperframes/dist/skills/media-use/references/grading.md +160 -0
  389. package/vendor/hyperframes/dist/skills/media-use/references/media-treatment-recipes.md +929 -0
  390. package/vendor/hyperframes/dist/skills/media-use/references/media-treatments.md +202 -0
  391. package/vendor/hyperframes/dist/skills/media-use/references/memory.md +37 -0
  392. package/vendor/hyperframes/dist/skills/media-use/references/meta.md +61 -0
  393. package/vendor/hyperframes/dist/skills/media-use/references/operations.md +327 -0
  394. package/vendor/hyperframes/dist/skills/media-use/references/resolve.md +150 -0
  395. package/vendor/hyperframes/dist/skills/media-use/references/setup-providers.md +80 -0
  396. package/vendor/hyperframes/dist/skills/media-use/references/telemetry-dashboard.md +49 -0
  397. package/vendor/hyperframes/dist/skills/media-use/scripts/audio-duck.mjs +113 -0
  398. package/vendor/hyperframes/dist/skills/media-use/scripts/compatibility.test.mjs +96 -0
  399. package/vendor/hyperframes/dist/skills/media-use/scripts/dither.mjs +328 -0
  400. package/vendor/hyperframes/dist/skills/media-use/scripts/dither.test.mjs +176 -0
  401. package/vendor/hyperframes/dist/skills/media-use/scripts/eval.mjs +369 -0
  402. package/vendor/hyperframes/dist/skills/media-use/scripts/lib/adopt.mjs +128 -0
  403. package/vendor/hyperframes/dist/skills/media-use/scripts/lib/adopt.test.mjs +95 -0
  404. package/vendor/hyperframes/dist/skills/media-use/scripts/lib/bgm-provider.mjs +20 -0
  405. package/vendor/hyperframes/dist/skills/media-use/scripts/lib/brand-provider.mjs +59 -0
  406. package/vendor/hyperframes/dist/skills/media-use/scripts/lib/bundled-sfx-provider.mjs +119 -0
  407. package/vendor/hyperframes/dist/skills/media-use/scripts/lib/bundled-sfx-provider.test.mjs +139 -0
  408. package/vendor/hyperframes/dist/skills/media-use/scripts/lib/cache.mjs +148 -0
  409. package/vendor/hyperframes/dist/skills/media-use/scripts/lib/candidates.mjs +91 -0
  410. package/vendor/hyperframes/dist/skills/media-use/scripts/lib/candidates.test.mjs +155 -0
  411. package/vendor/hyperframes/dist/skills/media-use/scripts/lib/codex-provider.mjs +161 -0
  412. package/vendor/hyperframes/dist/skills/media-use/scripts/lib/codex-provider.test.mjs +34 -0
  413. package/vendor/hyperframes/dist/skills/media-use/scripts/lib/config-lock.d.mts +3 -0
  414. package/vendor/hyperframes/dist/skills/media-use/scripts/lib/config-lock.mjs +45 -0
  415. package/vendor/hyperframes/dist/skills/media-use/scripts/lib/config-lock.test.mjs +79 -0
  416. package/vendor/hyperframes/dist/skills/media-use/scripts/lib/coverage.test.mjs +136 -0
  417. package/vendor/hyperframes/dist/skills/media-use/scripts/lib/cube-build.mjs +181 -0
  418. package/vendor/hyperframes/dist/skills/media-use/scripts/lib/cube-build.test.mjs +80 -0
  419. package/vendor/hyperframes/dist/skills/media-use/scripts/lib/cube-validate.mjs +198 -0
  420. package/vendor/hyperframes/dist/skills/media-use/scripts/lib/cube-validate.test.mjs +125 -0
  421. package/vendor/hyperframes/dist/skills/media-use/scripts/lib/cutlist.mjs +184 -0
  422. package/vendor/hyperframes/dist/skills/media-use/scripts/lib/cutlist.test.mjs +162 -0
  423. package/vendor/hyperframes/dist/skills/media-use/scripts/lib/duck.mjs +95 -0
  424. package/vendor/hyperframes/dist/skills/media-use/scripts/lib/duck.test.mjs +153 -0
  425. package/vendor/hyperframes/dist/skills/media-use/scripts/lib/error-diffusion.mjs +230 -0
  426. package/vendor/hyperframes/dist/skills/media-use/scripts/lib/error-diffusion.test.mjs +102 -0
  427. package/vendor/hyperframes/dist/skills/media-use/scripts/lib/ff-binaries.mjs +37 -0
  428. package/vendor/hyperframes/dist/skills/media-use/scripts/lib/freeze.mjs +72 -0
  429. package/vendor/hyperframes/dist/skills/media-use/scripts/lib/freeze.test.mjs +138 -0
  430. package/vendor/hyperframes/dist/skills/media-use/scripts/lib/grade-analyzer.mjs +265 -0
  431. package/vendor/hyperframes/dist/skills/media-use/scripts/lib/grade-analyzer.test.mjs +285 -0
  432. package/vendor/hyperframes/dist/skills/media-use/scripts/lib/heygen-cli.mjs +191 -0
  433. package/vendor/hyperframes/dist/skills/media-use/scripts/lib/heygen-cli.test.mjs +301 -0
  434. package/vendor/hyperframes/dist/skills/media-use/scripts/lib/heygen-search.mjs +45 -0
  435. package/vendor/hyperframes/dist/skills/media-use/scripts/lib/heygen-search.test.mjs +49 -0
  436. package/vendor/hyperframes/dist/skills/media-use/scripts/lib/heygen-video-provider.mjs +138 -0
  437. package/vendor/hyperframes/dist/skills/media-use/scripts/lib/heygen-video-provider.test.mjs +435 -0
  438. package/vendor/hyperframes/dist/skills/media-use/scripts/lib/image-provider.mjs +44 -0
  439. package/vendor/hyperframes/dist/skills/media-use/scripts/lib/index-gen.mjs +63 -0
  440. package/vendor/hyperframes/dist/skills/media-use/scripts/lib/local-media-search.mjs +32 -0
  441. package/vendor/hyperframes/dist/skills/media-use/scripts/lib/local-models.mjs +318 -0
  442. package/vendor/hyperframes/dist/skills/media-use/scripts/lib/local-models.test.mjs +220 -0
  443. package/vendor/hyperframes/dist/skills/media-use/scripts/lib/local-run.mjs +78 -0
  444. package/vendor/hyperframes/dist/skills/media-use/scripts/lib/local-run.test.mjs +121 -0
  445. package/vendor/hyperframes/dist/skills/media-use/scripts/lib/logo-provider.mjs +244 -0
  446. package/vendor/hyperframes/dist/skills/media-use/scripts/lib/logo-provider.test.mjs +298 -0
  447. package/vendor/hyperframes/dist/skills/media-use/scripts/lib/ltx-video-provider.mjs +94 -0
  448. package/vendor/hyperframes/dist/skills/media-use/scripts/lib/ltx-video-provider.test.mjs +316 -0
  449. package/vendor/hyperframes/dist/skills/media-use/scripts/lib/lut-preset-provider.mjs +271 -0
  450. package/vendor/hyperframes/dist/skills/media-use/scripts/lib/lut-preset-provider.test.mjs +199 -0
  451. package/vendor/hyperframes/dist/skills/media-use/scripts/lib/manifest.d.mts +19 -0
  452. package/vendor/hyperframes/dist/skills/media-use/scripts/lib/manifest.mjs +279 -0
  453. package/vendor/hyperframes/dist/skills/media-use/scripts/lib/manifest.test.mjs +397 -0
  454. package/vendor/hyperframes/dist/skills/media-use/scripts/lib/match.mjs +47 -0
  455. package/vendor/hyperframes/dist/skills/media-use/scripts/lib/media-fetch.mjs +85 -0
  456. package/vendor/hyperframes/dist/skills/media-use/scripts/lib/media-fetch.test.mjs +197 -0
  457. package/vendor/hyperframes/dist/skills/media-use/scripts/lib/media-home.mjs +20 -0
  458. package/vendor/hyperframes/dist/skills/media-use/scripts/lib/media-home.test.mjs +61 -0
  459. package/vendor/hyperframes/dist/skills/media-use/scripts/lib/media-search.d.mts +9 -0
  460. package/vendor/hyperframes/dist/skills/media-use/scripts/lib/media-search.mjs +107 -0
  461. package/vendor/hyperframes/dist/skills/media-use/scripts/lib/mflux-provider.mjs +128 -0
  462. package/vendor/hyperframes/dist/skills/media-use/scripts/lib/mflux-provider.test.mjs +174 -0
  463. package/vendor/hyperframes/dist/skills/media-use/scripts/lib/misses.mjs +49 -0
  464. package/vendor/hyperframes/dist/skills/media-use/scripts/lib/misses.test.mjs +89 -0
  465. package/vendor/hyperframes/dist/skills/media-use/scripts/lib/npx-sync.mjs +31 -0
  466. package/vendor/hyperframes/dist/skills/media-use/scripts/lib/npx-sync.test.mjs +50 -0
  467. package/vendor/hyperframes/dist/skills/media-use/scripts/lib/parakeet-words.mjs +27 -0
  468. package/vendor/hyperframes/dist/skills/media-use/scripts/lib/parakeet-words.test.mjs +44 -0
  469. package/vendor/hyperframes/dist/skills/media-use/scripts/lib/prefs-store.mjs +180 -0
  470. package/vendor/hyperframes/dist/skills/media-use/scripts/lib/prefs-store.test.mjs +189 -0
  471. package/vendor/hyperframes/dist/skills/media-use/scripts/lib/probe.mjs +41 -0
  472. package/vendor/hyperframes/dist/skills/media-use/scripts/lib/probe.test.mjs +148 -0
  473. package/vendor/hyperframes/dist/skills/media-use/scripts/lib/providers.mjs +5 -0
  474. package/vendor/hyperframes/dist/skills/media-use/scripts/lib/recipe-store.mjs +367 -0
  475. package/vendor/hyperframes/dist/skills/media-use/scripts/lib/recipe-store.test.mjs +367 -0
  476. package/vendor/hyperframes/dist/skills/media-use/scripts/lib/registry.mjs +212 -0
  477. package/vendor/hyperframes/dist/skills/media-use/scripts/lib/registry.test.mjs +262 -0
  478. package/vendor/hyperframes/dist/skills/media-use/scripts/lib/search.mjs +24 -0
  479. package/vendor/hyperframes/dist/skills/media-use/scripts/lib/search.test.mjs +32 -0
  480. package/vendor/hyperframes/dist/skills/media-use/scripts/lib/sfx-provider.mjs +23 -0
  481. package/vendor/hyperframes/dist/skills/media-use/scripts/lib/specs.mjs +132 -0
  482. package/vendor/hyperframes/dist/skills/media-use/scripts/lib/specs.test.mjs +157 -0
  483. package/vendor/hyperframes/dist/skills/media-use/scripts/lib/stats.mjs +117 -0
  484. package/vendor/hyperframes/dist/skills/media-use/scripts/lib/stats.test.mjs +165 -0
  485. package/vendor/hyperframes/dist/skills/media-use/scripts/lib/svg-sanitize.mjs +21 -0
  486. package/vendor/hyperframes/dist/skills/media-use/scripts/lib/telemetry.mjs +210 -0
  487. package/vendor/hyperframes/dist/skills/media-use/scripts/lib/telemetry.test.mjs +437 -0
  488. package/vendor/hyperframes/dist/skills/media-use/scripts/lib/test-home.test.mjs +10 -0
  489. package/vendor/hyperframes/dist/skills/media-use/scripts/lib/transcriptCutFade.mjs +21 -0
  490. package/vendor/hyperframes/dist/skills/media-use/scripts/lib/transcriptCutFade.test.mjs +33 -0
  491. package/vendor/hyperframes/dist/skills/media-use/scripts/lib/tts-local-provider.mjs +94 -0
  492. package/vendor/hyperframes/dist/skills/media-use/scripts/lib/tts-local-provider.test.mjs +72 -0
  493. package/vendor/hyperframes/dist/skills/media-use/scripts/lib/usage.mjs +57 -0
  494. package/vendor/hyperframes/dist/skills/media-use/scripts/lib/usage.test.mjs +54 -0
  495. package/vendor/hyperframes/dist/skills/media-use/scripts/lib/voice-provider.mjs +57 -0
  496. package/vendor/hyperframes/dist/skills/media-use/scripts/lib/voice-provider.test.mjs +46 -0
  497. package/vendor/hyperframes/dist/skills/media-use/scripts/lib/words.mjs +18 -0
  498. package/vendor/hyperframes/dist/skills/media-use/scripts/prefs.mjs +70 -0
  499. package/vendor/hyperframes/dist/skills/media-use/scripts/recipe.mjs +103 -0
  500. package/vendor/hyperframes/dist/skills/media-use/scripts/resolve-plugin.test.mjs +62 -0
  501. package/vendor/hyperframes/dist/skills/media-use/scripts/resolve.mjs +1369 -0
  502. package/vendor/hyperframes/dist/skills/media-use/scripts/transcribe.mjs +194 -0
  503. package/vendor/hyperframes/dist/skills/media-use/scripts/transcribe.test.mjs +112 -0
  504. package/vendor/hyperframes/dist/skills/media-use/scripts/transcript-cut.mjs +270 -0
  505. package/vendor/hyperframes/dist/skills/media-use/scripts/transcript-cut.test.mjs +117 -0
  506. package/vendor/hyperframes/dist/skills-MJ2J4GEM.js +808 -0
  507. package/vendor/hyperframes/dist/skillsUpdateCheck-TKTYQN5R.js +26 -0
  508. package/vendor/hyperframes/dist/slideshow-EJ4IMY6P.js +24 -0
  509. package/vendor/hyperframes/dist/snapshot-KIVDUUMN.js +875 -0
  510. package/vendor/hyperframes/dist/src-6YQBJGWR.js +202 -0
  511. package/vendor/hyperframes/dist/src-PVYUYV3M.js +471 -0
  512. package/vendor/hyperframes/dist/state-KAXGHF77.js +26 -0
  513. package/vendor/hyperframes/dist/staticProjectServer-7EU666GS.js +49 -0
  514. package/vendor/hyperframes/dist/status-YM52BQ6S.js +311 -0
  515. package/vendor/hyperframes/dist/studio/assets/hyperframes-player-Cp8e_Zst.js +473 -0
  516. package/vendor/hyperframes/dist/studio/assets/index-BX3KHhGX.js +71 -0
  517. package/vendor/hyperframes/dist/studio/assets/index-CASEBNy2.js +1 -0
  518. package/vendor/hyperframes/dist/studio/assets/index-D11atkBt.css +1 -0
  519. package/vendor/hyperframes/dist/studio/assets/index-DMTt9nTf.js +531 -0
  520. package/vendor/hyperframes/dist/studio/assets/index-oE1pOdAy.js +399 -0
  521. package/vendor/hyperframes/dist/studio/chunk-5VSXRGIX.js +948 -0
  522. package/vendor/hyperframes/dist/studio/chunk-5VSXRGIX.js.map +1 -0
  523. package/vendor/hyperframes/dist/studio/chunk-7UQWVN52.js +938 -0
  524. package/vendor/hyperframes/dist/studio/chunk-7UQWVN52.js.map +1 -0
  525. package/vendor/hyperframes/dist/studio/chunk-EEXSYY5F.js +190 -0
  526. package/vendor/hyperframes/dist/studio/chunk-EEXSYY5F.js.map +1 -0
  527. package/vendor/hyperframes/dist/studio/chunk-FOEID72M.js +1441 -0
  528. package/vendor/hyperframes/dist/studio/chunk-FOEID72M.js.map +1 -0
  529. package/vendor/hyperframes/dist/studio/chunk-PZ5AY32C.js +10 -0
  530. package/vendor/hyperframes/dist/studio/chunk-PZ5AY32C.js.map +1 -0
  531. package/vendor/hyperframes/dist/studio/chunk-TDWGXBUT.js +1103 -0
  532. package/vendor/hyperframes/dist/studio/chunk-TDWGXBUT.js.map +1 -0
  533. package/vendor/hyperframes/dist/studio/domEditingLayers-IEVLO54Z.js +47 -0
  534. package/vendor/hyperframes/dist/studio/domEditingLayers-IEVLO54Z.js.map +1 -0
  535. package/vendor/hyperframes/dist/studio/favicon.svg +14 -0
  536. package/vendor/hyperframes/dist/studio/icons/timeline/audio.svg +7 -0
  537. package/vendor/hyperframes/dist/studio/icons/timeline/captions.svg +5 -0
  538. package/vendor/hyperframes/dist/studio/icons/timeline/composition.svg +12 -0
  539. package/vendor/hyperframes/dist/studio/icons/timeline/image.svg +18 -0
  540. package/vendor/hyperframes/dist/studio/icons/timeline/music.svg +10 -0
  541. package/vendor/hyperframes/dist/studio/icons/timeline/text.svg +3 -0
  542. package/vendor/hyperframes/dist/studio/index.css +165 -0
  543. package/vendor/hyperframes/dist/studio/index.css.map +1 -0
  544. package/vendor/hyperframes/dist/studio/index.d.ts +4296 -0
  545. package/vendor/hyperframes/dist/studio/index.html +23 -0
  546. package/vendor/hyperframes/dist/studio/index.js +99693 -0
  547. package/vendor/hyperframes/dist/studio/index.js.map +1 -0
  548. package/vendor/hyperframes/dist/studio/player.d.ts +30 -0
  549. package/vendor/hyperframes/dist/studio/player.js +10 -0
  550. package/vendor/hyperframes/dist/studio/player.js.map +1 -0
  551. package/vendor/hyperframes/dist/studio/styles/tailwind-preset.d.ts +39 -0
  552. package/vendor/hyperframes/dist/studio/styles/tailwind-preset.js +50 -0
  553. package/vendor/hyperframes/dist/studio/styles/tailwind-preset.js.map +1 -0
  554. package/vendor/hyperframes/dist/studio/styles.css +1 -0
  555. package/vendor/hyperframes/dist/studio/ui.d.ts +296 -0
  556. package/vendor/hyperframes/dist/studio/ui.js +66 -0
  557. package/vendor/hyperframes/dist/studio/ui.js.map +1 -0
  558. package/vendor/hyperframes/dist/studio-api-PNQZRPX5.js +136 -0
  559. package/vendor/hyperframes/dist/studioSelectionClient-IUUPKUHZ.js +25 -0
  560. package/vendor/hyperframes/dist/studioServer-UWRBPIOJ.js +1457 -0
  561. package/vendor/hyperframes/dist/synthesize-K62TIZWI.js +182 -0
  562. package/vendor/hyperframes/dist/system-EZYZNUFD.js +44 -0
  563. package/vendor/hyperframes/dist/telemetry-2YC4SGQU.js +144 -0
  564. package/vendor/hyperframes/dist/telemetry-QMYM4WME.js +95 -0
  565. package/vendor/hyperframes/dist/templates/_shared/AGENTS.md +107 -0
  566. package/vendor/hyperframes/dist/templates/_shared/CLAUDE.md +107 -0
  567. package/vendor/hyperframes/dist/templates/blank/index.html +55 -0
  568. package/vendor/hyperframes/dist/templates/from-file/index.html +75 -0
  569. package/vendor/hyperframes/dist/templates/warm-grain/compositions/captions.html +154 -0
  570. package/vendor/hyperframes/dist/templates/warm-grain/compositions/graphics.html +162 -0
  571. package/vendor/hyperframes/dist/templates/warm-grain/compositions/intro.html +87 -0
  572. package/vendor/hyperframes/dist/templates/warm-grain/index.html +264 -0
  573. package/vendor/hyperframes/dist/templates/warm-grain/registry-item.json +34 -0
  574. package/vendor/hyperframes/dist/timeline-77Z3BBQM.js +1377 -0
  575. package/vendor/hyperframes/dist/tokens-OBGTYE4Z.js +92 -0
  576. package/vendor/hyperframes/dist/transcribe-7NVFHCGA.js +387 -0
  577. package/vendor/hyperframes/dist/transcribe-BNSJRR4M.js +62 -0
  578. package/vendor/hyperframes/dist/tts-P3LIPIL5.js +234 -0
  579. package/vendor/hyperframes/dist/updateCheck-UDWIJ4ZQ.js +39 -0
  580. package/vendor/hyperframes/dist/upgrade-CT3CPO3E.js +231 -0
  581. package/vendor/hyperframes/dist/urlDownloader-H6WRI2UE.js +39 -0
  582. package/vendor/hyperframes/dist/usage-EC3KFUIJ.js +2139 -0
  583. package/vendor/hyperframes/dist/validate-65QDZJWZ.js +70 -0
  584. package/vendor/hyperframes/dist/video-FGSGKRSV.js +261 -0
  585. package/vendor/hyperframes/dist/workspaceBuildCheck-TOLGAI4T.js +133 -0
  586. package/vendor/hyperframes/package.json +80 -0
package/src/audio.mjs ADDED
@@ -0,0 +1,31 @@
1
+ // Volumen final a −14 LUFS (lo que reproduce Instagram), en dos pasadas de loudnorm.
2
+ // El mezclador del motor no normaliza: en la cata 2 la edición salió a −16,1 y el reel a −15,0.
3
+ import { spawnSync } from 'node:child_process';
4
+
5
+ function ffmpegRun(ffmpeg, args) {
6
+ const r = spawnSync(ffmpeg, ['-nostdin', '-hide_banner', ...args], { encoding: 'utf8', maxBuffer: 64 * 1024 * 1024 });
7
+ if (r.status !== 0) throw new Error(`ffmpeg falló: ${(r.stderr || r.error?.message || '').slice(-400)}`);
8
+ return r.stderr; // ffmpeg informa por stderr
9
+ }
10
+
11
+ export function hasAudio(ffprobe, input) {
12
+ const r = spawnSync(ffprobe, ['-v', 'error', '-select_streams', 'a', '-show_entries', 'stream=index', '-of', 'csv=p=0', input], { encoding: 'utf8' });
13
+ return r.status === 0 && r.stdout.trim().length > 0;
14
+ }
15
+
16
+ /** Sonoridad integrada (LUFS) de un fichero. */
17
+ export function loudness(ffmpeg, input) {
18
+ const text = ffmpegRun(ffmpeg, ['-i', input, '-af', 'ebur128', '-f', 'null', '-']);
19
+ const m = text.slice(text.lastIndexOf('Summary:')).match(/I:\s+(-?[\d.]+) LUFS/);
20
+ return m ? Number(m[1]) : null;
21
+ }
22
+
23
+ /** Copia `input` en `output` con el audio normalizado; el vídeo no se recodifica. */
24
+ export function normalizeLoudness(ffmpeg, input, output, { lufs = -14, tp = -1, lra = 11 } = {}) {
25
+ const base = `loudnorm=I=${lufs}:TP=${tp}:LRA=${lra}`;
26
+ const report = ffmpegRun(ffmpeg, ['-i', input, '-af', `${base}:print_format=json`, '-f', 'null', '-']);
27
+ const s = JSON.parse(report.slice(report.lastIndexOf('{'), report.lastIndexOf('}') + 1));
28
+ const filter = `${base}:measured_I=${s.input_i}:measured_TP=${s.input_tp}:measured_LRA=${s.input_lra}:measured_thresh=${s.input_thresh}:offset=${s.target_offset}:linear=true`;
29
+ ffmpegRun(ffmpeg, ['-y', '-i', input, '-c:v', 'copy', '-af', filter, '-ar', '48000', '-c:a', 'aac', '-b:a', '192k', '-movflags', '+faststart', output]);
30
+ return { before: Number(s.input_i), after: lufs };
31
+ }
@@ -0,0 +1,46 @@
1
+ {
2
+ "version": "1",
3
+ "baseUrl": "https://media.ignix.social/editor/bin",
4
+ "platforms": {
5
+ "darwin-x64": {
6
+ "ffmpeg": {
7
+ "file": "ffmpeg",
8
+ "size": 25060568,
9
+ "sha256": "d4d01b1c196a4c6e3000be608f906991fe41914840a1ce0dcdf66256c3ee4c40",
10
+ "build": "ffmpeg 7.1.2 LGPL + VideoToolbox, scripts/build-ffmpeg-macos.sh"
11
+ },
12
+ "ffprobe": {
13
+ "file": "ffprobe",
14
+ "size": 24973512,
15
+ "sha256": "dd9f843f01a934c8358c9a235d8e44349fe50692418dd79ba328be7f4fecbd85",
16
+ "build": "ffmpeg 7.1.2 LGPL, scripts/build-ffmpeg-macos.sh"
17
+ },
18
+ "whisper": {
19
+ "file": "whisper-cli",
20
+ "size": 2912480,
21
+ "sha256": "73fc58436c1e1a9d2cc3ea08bddf18bf78270d8c6940c5fd89a3c9cb31535efe",
22
+ "build": "whisper.cpp v1.7.6, scripts/build-whisper-macos.sh"
23
+ }
24
+ },
25
+ "darwin-arm64": {
26
+ "ffmpeg": {
27
+ "file": "ffmpeg",
28
+ "size": 20858536,
29
+ "sha256": "ba5d9f9e59dd9588b88c97a526d971d07ccc60d1f101f47e2f9fac3c03ff2846",
30
+ "build": "ffmpeg 7.1.2 LGPL + VideoToolbox, CI binaries.yml (macos-15, run 37322341901)"
31
+ },
32
+ "ffprobe": {
33
+ "file": "ffprobe",
34
+ "size": 20799752,
35
+ "sha256": "5c7c6da2f0a7c14ac7aaf934afdfd6e0efa232955226a287b986fcb37e5992b9",
36
+ "build": "ffmpeg 7.1.2 LGPL, CI binaries.yml (macos-15, run 37322341901)"
37
+ },
38
+ "whisper": {
39
+ "file": "whisper-cli",
40
+ "size": 2573144,
41
+ "sha256": "215d93a2edc77f8929311f127f368727859e13833e925652315ca5ea774595ee",
42
+ "build": "whisper.cpp v1.7.6, CI binaries.yml (macos-15, run 37322341901)"
43
+ }
44
+ }
45
+ }
46
+ }
@@ -0,0 +1,83 @@
1
+ // Binarios nativos que Ignix Editor necesita (ffmpeg, ffprobe, whisper-cli) por sistema.
2
+ // Orden de búsqueda: variable de entorno → caché (~/.ignix-editor/bin/<plataforma>) →
3
+ // descarga desde media.ignix.social con su sha256 comprobado. Chrome lo gestiona el motor
4
+ // (descarga oficial de Google la primera vez).
5
+ import { createHash } from 'node:crypto';
6
+ import { chmodSync, createWriteStream, existsSync, mkdirSync, readFileSync, renameSync, writeFileSync } from 'node:fs';
7
+ import { Readable } from 'node:stream';
8
+ import { pipeline } from 'node:stream/promises';
9
+ import { homedir } from 'node:os';
10
+ import { dirname, join } from 'node:path';
11
+ import { fileURLToPath } from 'node:url';
12
+
13
+ export const HOME = process.env.IGNIX_EDITOR_HOME || join(homedir(), '.ignix-editor');
14
+ export const PLATFORM = `${process.platform}-${process.arch}`; // darwin-x64, darwin-arm64, win32-x64…
15
+ const EXE = process.platform === 'win32' ? '.exe' : '';
16
+
17
+ const manifest = JSON.parse(readFileSync(join(dirname(fileURLToPath(import.meta.url)), 'binaries.json'), 'utf8'));
18
+
19
+ export const TOOLS = {
20
+ ffmpeg: { env: 'IGNIX_EDITOR_FFMPEG', file: `ffmpeg${EXE}` },
21
+ ffprobe: { env: 'IGNIX_EDITOR_FFPROBE', file: `ffprobe${EXE}` },
22
+ whisper: { env: 'IGNIX_EDITOR_WHISPER', file: `whisper-cli${EXE}` },
23
+ };
24
+
25
+ const binDir = () => join(HOME, 'bin', PLATFORM, manifest.version);
26
+
27
+ /** Ruta del binario si ya está disponible, sin descargar nada. */
28
+ export function findTool(name) {
29
+ const t = TOOLS[name];
30
+ const fromEnv = process.env[t.env];
31
+ if (fromEnv) return existsSync(fromEnv) ? { path: fromEnv, source: 'env' } : { path: null, source: 'env', error: `${t.env} apunta a ${fromEnv}, que no existe` };
32
+ const cached = join(binDir(), t.file);
33
+ if (existsSync(cached)) return { path: cached, source: 'cache' };
34
+ const entry = manifest.platforms[PLATFORM]?.[name];
35
+ return { path: null, source: entry ? 'download' : 'unavailable' };
36
+ }
37
+
38
+ /** Ruta del binario, descargándolo la primera vez. */
39
+ export async function ensureTool(name, log = () => {}) {
40
+ const found = findTool(name);
41
+ if (found.path) return found.path;
42
+ if (found.error) throw new Error(found.error);
43
+ const entry = manifest.platforms[PLATFORM]?.[name];
44
+ if (!entry) {
45
+ throw new Error(`${name} todavía no está publicado para ${PLATFORM}. Mientras tanto, apunta ${TOOLS[name].env} a un ${TOOLS[name].file} local.`);
46
+ }
47
+ const url = `${manifest.baseUrl}/${manifest.version}/${PLATFORM}/${entry.file}`;
48
+ log(`Descargando ${name} (${(entry.size / 1e6).toFixed(0)} MB)…`);
49
+ const res = await fetch(url);
50
+ if (!res.ok) throw new Error(`No se pudo descargar ${name}: ${res.status} ${url}`);
51
+ const buf = Buffer.from(await res.arrayBuffer());
52
+ const sha = createHash('sha256').update(buf).digest('hex');
53
+ if (sha !== entry.sha256) throw new Error(`El ${name} descargado no coincide con su huella (sha256). No se usa.`);
54
+ const dir = binDir();
55
+ mkdirSync(dir, { recursive: true });
56
+ const dest = join(dir, TOOLS[name].file);
57
+ writeFileSync(`${dest}.part`, buf);
58
+ chmodSync(`${dest}.part`, 0o755);
59
+ renameSync(`${dest}.part`, dest);
60
+ return dest;
61
+ }
62
+
63
+ /** Modelos de whisper (ggml, MIT), en ~/.ignix-editor/models. */
64
+ export const WHISPER_MODELS = {
65
+ medium: { file: 'ggml-medium.bin', size: 1533763059 },
66
+ small: { file: 'ggml-small.bin', size: 487601967 },
67
+ base: { file: 'ggml-base.bin', size: 147951465 },
68
+ };
69
+
70
+ export async function ensureWhisperModel(model = 'medium', log = () => {}) {
71
+ const m = WHISPER_MODELS[model];
72
+ if (!m) throw new Error(`Modelo desconocido: ${model}. Opciones: ${Object.keys(WHISPER_MODELS).join(', ')}`);
73
+ const dir = join(HOME, 'models');
74
+ const dest = join(dir, m.file);
75
+ if (existsSync(dest)) return dest;
76
+ mkdirSync(dir, { recursive: true });
77
+ log(`Descargando el modelo de transcripción ${model} (${(m.size / 1e9).toFixed(1)} GB, solo la primera vez)…`);
78
+ const res = await fetch(`https://huggingface.co/ggerganov/whisper.cpp/resolve/main/${m.file}`);
79
+ if (!res.ok) throw new Error(`No se pudo descargar el modelo ${model}: ${res.status}`);
80
+ await pipeline(Readable.fromWeb(res.body), createWriteStream(`${dest}.part`));
81
+ renameSync(`${dest}.part`, dest);
82
+ return dest;
83
+ }
package/src/cli.mjs ADDED
@@ -0,0 +1,254 @@
1
+ // ignix-editor — CLI de Ignix Editor. El motor (HyperFrames, en vendor/) corre siempre por
2
+ // debajo con nuestro entorno: sin telemetría, sin actualizaciones solas, con nuestros binarios.
3
+ import { spawnSync } from 'node:child_process';
4
+ import { cpSync, existsSync, mkdirSync, readFileSync, rmSync, symlinkSync, writeFileSync } from 'node:fs';
5
+ import { homedir } from 'node:os';
6
+ import { basename, dirname, join, resolve } from 'node:path';
7
+ import { fileURLToPath } from 'node:url';
8
+ import { HOME, PLATFORM, TOOLS, ensureTool, ensureWhisperModel, findTool } from './binaries.mjs';
9
+ import { prepare, projectHtml } from './prepare.mjs';
10
+ import { validateHtml } from './validate.mjs';
11
+ import { loudness, hasAudio, normalizeLoudness } from './audio.mjs';
12
+ import { alignToScript, transcribe } from './transcribe.mjs';
13
+
14
+ const PKG_DIR = join(dirname(fileURLToPath(import.meta.url)), '..');
15
+ const PKG = JSON.parse(readFileSync(join(PKG_DIR, 'package.json'), 'utf8'));
16
+ const ENGINE = join(PKG_DIR, 'vendor', 'hyperframes', 'bin', 'hyperframes.mjs');
17
+ const UPSTREAM = JSON.parse(readFileSync(join(PKG_DIR, 'vendor', 'hyperframes', 'UPSTREAM.json'), 'utf8'));
18
+ export const VIDEOS_DIR = join(homedir(), 'ignix-videos');
19
+
20
+ const log = (...a) => console.error(...a);
21
+ const fail = (msg) => {
22
+ log(`✗ ${msg}`);
23
+ process.exit(1);
24
+ };
25
+
26
+ // ── argumentos: posicionales, nuestras opciones y el resto pasa al motor tal cual
27
+ function parseArgs(argv, ours) {
28
+ const pos = [];
29
+ const opts = {};
30
+ const rest = [];
31
+ for (let i = 0; i < argv.length; i++) {
32
+ const a = argv[i];
33
+ const m = a.match(/^--([^=]+)(?:=(.*))?$/);
34
+ const key = m?.[1] ?? (a === '-o' ? 'output' : null);
35
+ if (key && key in ours) {
36
+ if (ours[key] === 'bool') opts[key] = m?.[2] !== 'false';
37
+ else opts[key] = m?.[2] ?? argv[++i];
38
+ } else if (key && key.startsWith('no-') && key.slice(3) in ours && ours[key.slice(3)] === 'bool') opts[key.slice(3)] = false;
39
+ else if (a.startsWith('-')) rest.push(a);
40
+ else if (rest.length && rest[rest.length - 1].startsWith('-') && !rest[rest.length - 1].includes('=') && pos.length >= 1) rest.push(a);
41
+ else pos.push(a);
42
+ }
43
+ return { pos, opts, rest };
44
+ }
45
+
46
+ // ── el motor
47
+ async function engineEnv() {
48
+ const env = {
49
+ ...process.env,
50
+ HYPERFRAMES_NO_TELEMETRY: '1',
51
+ DO_NOT_TRACK: '1',
52
+ HYPERFRAMES_NO_UPDATE_CHECK: '1',
53
+ HYPERFRAMES_NO_AUTO_INSTALL: '1',
54
+ HYPERFRAMES_SKIP_SKILLS: '1',
55
+ HYPERFRAMES_FONT_CACHE_DIR: join(HOME, 'cache', 'fonts'),
56
+ };
57
+ const ffmpeg = await ensureTool('ffmpeg', log);
58
+ const ffprobe = await ensureTool('ffprobe', log);
59
+ env.HYPERFRAMES_FFMPEG_PATH = ffmpeg;
60
+ env.HYPERFRAMES_FFPROBE_PATH = ffprobe;
61
+ const whisper = findTool('whisper');
62
+ if (whisper.path) env.HYPERFRAMES_WHISPER_PATH = whisper.path;
63
+ // Por si alguna parte del motor llama a «ffmpeg» por su nombre: los nuestros van primero en el PATH.
64
+ const shim = join(HOME, 'shim', PLATFORM);
65
+ rmSync(shim, { recursive: true, force: true });
66
+ mkdirSync(shim, { recursive: true });
67
+ symlinkSync(ffmpeg, join(shim, TOOLS.ffmpeg.file));
68
+ symlinkSync(ffprobe, join(shim, TOOLS.ffprobe.file));
69
+ env.PATH = `${shim}${process.platform === 'win32' ? ';' : ':'}${env.PATH ?? ''}`;
70
+ return { env, ffmpeg, ffprobe };
71
+ }
72
+
73
+ function runEngine(args, env, cwd) {
74
+ const r = spawnSync(process.execPath, [ENGINE, ...args], { stdio: 'inherit', env, cwd });
75
+ return r.status ?? 1;
76
+ }
77
+
78
+ // ── comprobaciones propias
79
+ function validateProject(dir) {
80
+ const issues = projectHtml(dir).flatMap(validateHtml);
81
+ for (const i of issues) log(`${i.level === 'error' ? '✗' : '⚠'} ${i.rule} ${i.file.replace(dir + '/', '')}:${i.line} — ${i.msg}`);
82
+ const errors = issues.filter((i) => i.level === 'error').length;
83
+ log(errors ? `✗ ${errors} error(es) de Ignix Editor` : `✓ Ignix Editor: HTML y recursos correctos${issues.length ? ` (${issues.length} aviso(s))` : ''}`);
84
+ return errors;
85
+ }
86
+
87
+ const projectDir = (p) => {
88
+ const dir = resolve(p ?? '.');
89
+ if (!existsSync(join(dir, 'index.html'))) fail(`No hay index.html en ${dir}. ¿Es la carpeta del proyecto? (créala con: ignix-editor init <nombre>)`);
90
+ return dir;
91
+ };
92
+
93
+ // ── comandos
94
+ const commands = {
95
+ async doctor() {
96
+ const major = Number(process.versions.node.split('.')[0]);
97
+ log(`${major >= 22 ? '✓' : '✗'} Node ${process.versions.node}${major >= 22 ? '' : ' — hace falta Node 22 o superior'}`);
98
+ log(`✓ Ignix Editor ${PKG.version} · motor HyperFrames ${UPSTREAM.version} (parches: ${UPSTREAM.patches.join(', ')})`);
99
+ log(` Plataforma ${PLATFORM} · datos en ${HOME}`);
100
+ let ok = major >= 22;
101
+ for (const name of Object.keys(TOOLS)) {
102
+ const f = findTool(name);
103
+ const line = f.path ? `✓ ${name}: ${f.path}${f.source === 'env' ? ' (variable de entorno)' : ''}` : f.error ? `✗ ${name}: ${f.error}` : f.source === 'download' ? `• ${name}: se descargará la primera vez` : `✗ ${name}: aún no publicado para ${PLATFORM} (apunta ${TOOLS[name].env} a uno local)`;
104
+ log(line);
105
+ if (!f.path && f.source !== 'download' && name !== 'whisper') ok = false;
106
+ }
107
+ if (findTool('ffmpeg').path) {
108
+ const enc = spawnSync(findTool('ffmpeg').path, ['-hide_banner', '-encoders'], { encoding: 'utf8' }).stdout ?? '';
109
+ const h264 = /\blibx264\b/.test(enc) ? 'libx264' : /\bh264_videotoolbox\b/.test(enc) ? 'VideoToolbox' : null;
110
+ log(`${h264 ? '✓' : '✗'} codificador H.264: ${h264 ?? 'ninguno (hace falta libx264 o VideoToolbox)'}`);
111
+ if (!h264) ok = false;
112
+ }
113
+ process.exit(ok ? 0 : 1);
114
+ },
115
+
116
+ async init(argv) {
117
+ const { pos, opts } = parseArgs(argv, { dir: 'str' });
118
+ const name = pos[0];
119
+ if (!name || !/^[\w.-]+$/.test(name)) fail('Uso: ignix-editor init <nombre> [--dir carpeta] (nombre sin espacios)');
120
+ const dir = resolve(opts.dir ?? join(VIDEOS_DIR, name));
121
+ if (existsSync(dir)) fail(`${dir} ya existe. Elige otro nombre o trabaja dentro de ese proyecto.`);
122
+ cpSync(join(PKG_DIR, 'templates', 'blank'), dir, { recursive: true });
123
+ mkdirSync(join(dir, 'assets', 'fonts'), { recursive: true });
124
+ cpSync(join(PKG_DIR, 'node_modules', 'gsap', 'dist', 'gsap.min.js'), join(dir, 'assets', 'gsap.min.js'));
125
+ for (const w of [700, 800, 900]) {
126
+ for (const sub of ['latin', 'latin-ext']) {
127
+ const f = `montserrat-${sub}-${w}-normal.woff2`;
128
+ cpSync(join(PKG_DIR, 'node_modules', '@fontsource', 'montserrat', 'files', f), join(dir, 'assets', 'fonts', f));
129
+ }
130
+ }
131
+ cpSync(join(PKG_DIR, 'src', 'runtime', 'ignix-frame.js'), join(dir, 'ignix-frame.js'));
132
+ const html = readFileSync(join(dir, 'index.html'), 'utf8').replaceAll('__ID__', name.toLowerCase().replace(/[^a-z0-9]+/g, '-'));
133
+ writeFileSync(join(dir, 'index.html'), html);
134
+ console.log(dir);
135
+ },
136
+
137
+ async check(argv) {
138
+ const { pos, rest } = parseArgs(argv, {});
139
+ const dir = projectDir(pos[0]);
140
+ const errors = validateProject(dir);
141
+ const { build, snapped } = prepare(dir);
142
+ if (snapped) log(`• ${snapped} tiempo(s) ajustado(s) al fotograma`);
143
+ const { env } = await engineEnv();
144
+ const code = runEngine(['check', build, ...rest], env, dir);
145
+ process.exit(errors ? 1 : code);
146
+ },
147
+
148
+ async snapshot(argv) {
149
+ const { pos, rest } = parseArgs(argv, { output: 'str' });
150
+ const dir = projectDir(pos[0]);
151
+ const { build } = prepare(dir);
152
+ const { env } = await engineEnv();
153
+ const out = resolve(dir, 'snapshots');
154
+ rmSync(out, { recursive: true, force: true });
155
+ process.exit(runEngine(['snapshot', build, '-o', out, '--describe', 'false', ...rest], env, dir));
156
+ },
157
+
158
+ async render(argv) {
159
+ const { pos, opts, rest } = parseArgs(argv, { output: 'str', lufs: 'str', normalize: 'bool', force: 'bool' });
160
+ const dir = projectDir(pos[0]);
161
+ if (validateProject(dir) && !opts.force) fail('Arregla los errores de arriba antes de renderizar (o --force si sabes lo que haces).');
162
+ const { build, snapped } = prepare(dir);
163
+ if (snapped) log(`• ${snapped} tiempo(s) ajustado(s) al fotograma`);
164
+ const { env, ffmpeg, ffprobe } = await engineEnv();
165
+ const output = resolve(opts.output ?? join(dir, 'renders', `${basename(dir)}.mp4`));
166
+ mkdirSync(dirname(output), { recursive: true });
167
+ const raw = join(build, 'raw.mp4');
168
+ const code = runEngine(['render', build, '-o', raw, ...rest], env, dir);
169
+ if (code !== 0 || !existsSync(raw)) fail('El render falló (mira los mensajes de arriba).');
170
+ if (opts.normalize !== false && hasAudio(ffprobe, raw)) {
171
+ const lufs = Number(opts.lufs ?? -14);
172
+ const r = normalizeLoudness(ffmpeg, raw, output, { lufs });
173
+ log(`✓ Volumen: ${r.before.toFixed(1)} → ${loudness(ffmpeg, output)?.toFixed(1)} LUFS`);
174
+ } else cpSync(raw, output);
175
+ console.log(output);
176
+ },
177
+
178
+ async preview(argv) {
179
+ const { pos, rest } = parseArgs(argv, {});
180
+ const dir = projectDir(pos[0]);
181
+ const { build } = prepare(dir);
182
+ const { env } = await engineEnv();
183
+ log('Vista previa de la copia de trabajo: si cambias el proyecto, vuelve a lanzar este comando.');
184
+ process.exit(runEngine(['preview', build, ...rest], env, dir));
185
+ },
186
+
187
+ async transcribe(argv) {
188
+ const { pos, opts } = parseArgs(argv, { lang: 'str', model: 'str', script: 'str', output: 'str', threads: 'str' });
189
+ const input = pos[0] && resolve(pos[0]);
190
+ if (!input || !existsSync(input)) fail('Uso: ignix-editor transcribe <audio|vídeo> [--lang es] [--model medium] [--script "texto dicho"] [-o palabras.json]');
191
+ const ffmpeg = await ensureTool('ffmpeg', log);
192
+ const ffprobe = await ensureTool('ffprobe', log);
193
+ const whisper = await ensureTool('whisper', log);
194
+ const model = await ensureWhisperModel(opts.model ?? 'medium', log);
195
+ let words = transcribe({ ffmpeg, whisper, model, input, language: opts.lang ?? 'es', threads: Number(opts.threads ?? 8) });
196
+ if (opts.script) {
197
+ const dur = Number(spawnSync(ffprobe, ['-v', 'error', '-show_entries', 'format=duration', '-of', 'csv=p=0', input], { encoding: 'utf8' }).stdout.trim());
198
+ words = alignToScript(opts.script, words, dur);
199
+ }
200
+ const json = JSON.stringify({ language: opts.lang ?? 'es', words }, null, 1);
201
+ if (opts.output) writeFileSync(resolve(opts.output), json);
202
+ else console.log(json);
203
+ },
204
+
205
+ async ffmpeg(argv) {
206
+ const r = spawnSync(await ensureTool('ffmpeg', log), argv, { stdio: 'inherit' });
207
+ process.exit(r.status ?? 1);
208
+ },
209
+
210
+ async ffprobe(argv) {
211
+ const r = spawnSync(await ensureTool('ffprobe', log), argv, { stdio: 'inherit' });
212
+ process.exit(r.status ?? 1);
213
+ },
214
+
215
+ async skills(argv) {
216
+ const { pos, opts } = parseArgs(argv, { dir: 'str' });
217
+ if (pos[0] !== 'add') fail('Uso: ignix-editor skills add [--dir ~/.claude/skills]');
218
+ const target = resolve(opts.dir ?? join(homedir(), '.claude', 'skills'), 'ignix-editor');
219
+ rmSync(target, { recursive: true, force: true });
220
+ cpSync(join(PKG_DIR, 'skills', 'ignix-editor'), target, { recursive: true });
221
+ log(`✓ Skill instalada en ${target}`);
222
+ },
223
+
224
+ async version() {
225
+ console.log(`ignix-editor ${PKG.version} (motor HyperFrames ${UPSTREAM.version})`);
226
+ },
227
+
228
+ async help() {
229
+ console.log(`Ignix Editor ${PKG.version} — vídeo con HTML, renderizado en tu ordenador.
230
+
231
+ ignix-editor doctor comprueba Node, ffmpeg, whisper y el codificador
232
+ ignix-editor init <nombre> crea ~/ignix-videos/<nombre> listo para trabajar
233
+ ignix-editor check [carpeta] HTML, recursos, maqueta, movimiento y contraste
234
+ ignix-editor snapshot [carpeta] --at 0,2.5,5 fotogramas sueltos para revisar
235
+ ignix-editor render [carpeta] [-o salida.mp4] [--lufs -14] [--no-normalize]
236
+ ignix-editor preview [carpeta] vista previa en el navegador
237
+ ignix-editor transcribe <fichero> [--lang es] [--script "texto"] [-o palabras.json]
238
+ ignix-editor ffmpeg|ffprobe <args> el ffmpeg de Ignix Editor
239
+ ignix-editor skills add instala la skill para Claude
240
+
241
+ Basado en HyperFrames (Apache-2.0) de HeyGen, Inc. Ver NOTICE.`);
242
+ },
243
+ };
244
+
245
+ export async function main(argv) {
246
+ const [cmd = 'help', ...rest] = argv;
247
+ const fn = commands[cmd === '--version' || cmd === '-v' ? 'version' : cmd === '--help' || cmd === '-h' ? 'help' : cmd];
248
+ if (!fn) fail(`Comando desconocido: ${cmd}. Usa: ignix-editor help`);
249
+ try {
250
+ await fn(rest);
251
+ } catch (e) {
252
+ fail(e.message);
253
+ }
254
+ }
@@ -0,0 +1,74 @@
1
+ // Copia de trabajo del proyecto para el motor (.ignix-build/), con los arreglos de las catas:
2
+ // · tiempos de los clips ajustados al fotograma más cercano (el motor TRUNCA data-media-start × fps:
3
+ // con 4 decimales, 97/30 = 3.2333 daba el fotograma 96 en vez del 97);
4
+ // · ignix-frame.js de esta versión del editor, siempre al día.
5
+ // El proyecto del usuario no se toca.
6
+ import { copyFileSync, cpSync, existsSync, mkdirSync, readFileSync, readdirSync, realpathSync, rmSync, statSync, symlinkSync, writeFileSync } from 'node:fs';
7
+ import { dirname, join } from 'node:path';
8
+ import { fileURLToPath } from 'node:url';
9
+
10
+ const RUNTIME = join(dirname(fileURLToPath(import.meta.url)), 'runtime', 'ignix-frame.js');
11
+ const SKIP = new Set(['.ignix-build', 'renders', 'snapshots', 'node_modules', '.git', '.DS_Store']);
12
+ // Vídeo y audio no se copian (pueden pesar gigas): enlace a la ruta absoluta del original.
13
+ const MEDIA = /\.(mp4|mov|m4v|webm|mkv|avi|wav|mp3|m4a|aac|ogg|flac)$/i;
14
+
15
+ function mirror(src, dest) {
16
+ mkdirSync(dest, { recursive: true });
17
+ for (const name of readdirSync(src)) {
18
+ if (SKIP.has(name)) continue;
19
+ const from = join(src, name);
20
+ const to = join(dest, name);
21
+ const st = statSync(from);
22
+ if (st.isDirectory()) mirror(from, to);
23
+ else if (MEDIA.test(name)) symlinkSync(realpathSync(from), to);
24
+ else copyFileSync(from, to);
25
+ }
26
+ }
27
+
28
+ function htmlFiles(dir) {
29
+ const out = [];
30
+ for (const name of readdirSync(dir)) {
31
+ if (SKIP.has(name)) continue;
32
+ const p = join(dir, name);
33
+ if (statSync(p).isDirectory()) out.push(...htmlFiles(p));
34
+ else if (name.endsWith('.html')) out.push(p);
35
+ }
36
+ return out;
37
+ }
38
+
39
+ export function projectHtml(dir) {
40
+ return htmlFiles(dir);
41
+ }
42
+
43
+ /** Ajusta data-start / data-duration / data-media-start al fotograma más cercano. */
44
+ export function snapTimes(html, fps) {
45
+ let changes = 0;
46
+ const out = html.replace(/\b(data-(?:start|duration|media-start))="(-?\d+(?:\.\d+)?)"/g, (m, attr, raw) => {
47
+ const n = Math.round(Number(raw) * fps);
48
+ // media-start: el motor hace floor(t × fps); un pelo por encima del fotograma lo deja exacto.
49
+ const v = attr === 'data-media-start' ? (n + 1e-4) / fps : n / fps;
50
+ const s = Number(v.toFixed(9)).toString();
51
+ if (s !== raw) changes++;
52
+ return `${attr}="${s}"`;
53
+ });
54
+ return { html: out, changes };
55
+ }
56
+
57
+ export function prepare(projectDir) {
58
+ const build = join(projectDir, '.ignix-build');
59
+ rmSync(build, { recursive: true, force: true });
60
+ mirror(projectDir, build);
61
+
62
+ const root = join(build, 'index.html');
63
+ if (!existsSync(root)) throw new Error(`No hay index.html en ${projectDir}`);
64
+ const fps = Number(readFileSync(root, 'utf8').match(/data-fps="(\d+(?:\.\d+)?)"/)?.[1] ?? 30);
65
+
66
+ let snapped = 0;
67
+ for (const f of htmlFiles(build)) {
68
+ const { html, changes } = snapTimes(readFileSync(f, 'utf8'), fps);
69
+ if (changes) writeFileSync(f, html);
70
+ snapped += changes;
71
+ }
72
+ cpSync(RUNTIME, join(build, 'ignix-frame.js'));
73
+ return { build, fps, snapped };
74
+ }
@@ -0,0 +1,92 @@
1
+ /*
2
+ * ignix-frame.js — animación como función pura del tiempo (Ignix Editor).
3
+ *
4
+ * El render pide cada fotograma por separado y en cualquier orden. Si lo que se ve en el
5
+ * segundo t depende SOLO de t (nada de estado acumulado, nada medido en la página mientras
6
+ * corre), lo que se escribe es lo que sale. Uso:
7
+ *
8
+ * IgnixFrame.run({ id: 'reel', duration: 18.9, fps: 30 }, (t, f) => {
9
+ * el.style.opacity = IgnixFrame.lerp(t, [0, 0.4], [0, 1], IgnixFrame.ease.out);
10
+ * });
11
+ *
12
+ * `id` es el data-composition-id del nodo raíz. Necesita GSAP cargado antes.
13
+ */
14
+ (function () {
15
+ const clamp01 = (x) => Math.min(1, Math.max(0, x));
16
+
17
+ // Curva cúbica de Bézier como en CSS (x1, y1, x2, y2).
18
+ function bezier(x1, y1, x2, y2) {
19
+ return (t) => {
20
+ let u = t;
21
+ for (let i = 0; i < 8; i++) {
22
+ const x = 3 * (1 - u) ** 2 * u * x1 + 3 * (1 - u) * u * u * x2 + u ** 3 - t;
23
+ const dx = 3 * (1 - u) ** 2 * x1 + 6 * (1 - u) * u * (x2 - x1) + 3 * u * u * (1 - x2);
24
+ if (Math.abs(dx) < 1e-6) break;
25
+ u = clamp01(u - x / dx);
26
+ }
27
+ return 3 * (1 - u) ** 2 * u * y1 + 3 * (1 - u) * u * u * y2 + u ** 3;
28
+ };
29
+ }
30
+
31
+ const ease = {
32
+ linear: (t) => t,
33
+ out: bezier(0.22, 1, 0.36, 1), // entrada rápida que se posa (por defecto)
34
+ inOut: bezier(0.65, 0, 0.35, 1), // movimientos de cámara
35
+ in: (t) => t * t * t,
36
+ outCubic: (t) => 1 - (1 - t) ** 3, // = Easing.out(Easing.cubic) de Remotion = power2.out de GSAP
37
+ inOutSine: (t) => -(Math.cos(Math.PI * t) - 1) / 2,
38
+ };
39
+
40
+ // Valor entre dos puntos en el tiempo: lerp(t, [t0, t1], [v0, v1], ease). Fuera del tramo, se queda en el extremo.
41
+ function lerp(t, range, values, e = ease.linear) {
42
+ const [a, b] = range;
43
+ const [y0, y1] = values;
44
+ return y0 + (y1 - y0) * e(clamp01((t - a) / (b - a)));
45
+ }
46
+
47
+ // Muelle amortiguado en forma cerrada (masa 1): de 0 a 1 empezando en t=0 (segundos).
48
+ // stiffness/damping como en Remotion. Sin estado: se puede pedir cualquier t.
49
+ function spring(t, { stiffness = 220, damping = 14 } = {}) {
50
+ if (t <= 0) return 0;
51
+ const w0 = Math.sqrt(stiffness);
52
+ const z = damping / (2 * w0);
53
+ if (z < 1) {
54
+ const wd = w0 * Math.sqrt(1 - z * z);
55
+ return 1 - Math.exp(-z * w0 * t) * (Math.cos(wd * t) + ((z * w0) / wd) * Math.sin(wd * t));
56
+ }
57
+ return 1 - Math.exp(-w0 * t) * (1 + w0 * t);
58
+ }
59
+
60
+ // Valor por tramos: keys = [[t, valor], ...]; en cada t pasa al nuevo valor en `dur` segundos.
61
+ // El valor puede ser un número o una lista de números (posiciones, rectángulos).
62
+ function keyed(t, keys, dur = 0.5, e = ease.out) {
63
+ let v = keys[0][1];
64
+ for (let i = 1; i < keys.length; i++) {
65
+ const [tk, val] = keys[i];
66
+ if (t < tk) break;
67
+ const p = e(clamp01((t - tk) / dur));
68
+ v = Array.isArray(val) ? val.map((x, j) => v[j] + (x - v[j]) * p) : v + (val - v) * p;
69
+ }
70
+ return v;
71
+ }
72
+
73
+ // Registra la línea de tiempo: un único reloj que llama a render(t, fotograma).
74
+ function run({ id, duration, fps = 30 }, render) {
75
+ if (!window.gsap) throw new Error('ignix-frame: carga GSAP antes que este fichero');
76
+ if (!id) throw new Error('ignix-frame: falta id (el data-composition-id del nodo raíz)');
77
+ const last = Math.max(0, Math.round(duration * fps) - 1);
78
+ const draw = (sec) => {
79
+ const f = Math.min(last, Math.max(0, Math.round(sec * fps)));
80
+ render(f / fps, f);
81
+ };
82
+ const clock = { t: 0 };
83
+ const tl = window.gsap.timeline({ paused: true });
84
+ tl.to(clock, { t: duration, duration, ease: 'none', onUpdate: () => draw(clock.t) }, 0);
85
+ draw(0);
86
+ window.__timelines = window.__timelines || {};
87
+ window.__timelines[id] = tl;
88
+ return tl;
89
+ }
90
+
91
+ window.IgnixFrame = { run, lerp, spring, keyed, bezier, ease, clamp01 };
92
+ })();
@@ -0,0 +1,71 @@
1
+ // Transcripción en el ordenador del usuario con whisper.cpp: cada palabra con su inicio y fin
2
+ // en segundos. Con `script` (el texto que se sabe que se dijo, p. ej. una voz generada) manda
3
+ // el guion en las palabras y whisper en los tiempos: whisper confunde palabras («ADM», «tiene»)
4
+ // y a veces se come el final de una frase.
5
+ import { spawnSync } from 'node:child_process';
6
+ import { mkdtempSync, readFileSync, rmSync } from 'node:fs';
7
+ import { tmpdir } from 'node:os';
8
+ import { join } from 'node:path';
9
+
10
+ const norm = (s) => s.toLowerCase().normalize('NFD').replace(/[̀-ͯ]/g, '').replace(/[^\p{L}\p{N}]/gu, '');
11
+
12
+ export function transcribe({ ffmpeg, whisper, model, input, language = 'es', threads = 8 }) {
13
+ const tmp = mkdtempSync(join(tmpdir(), 'ignix-editor-asr-'));
14
+ try {
15
+ const wav = join(tmp, 'audio.wav');
16
+ const a = spawnSync(ffmpeg, ['-nostdin', '-hide_banner', '-loglevel', 'error', '-y', '-i', input, '-vn', '-ar', '16000', '-ac', '1', '-c:a', 'pcm_s16le', wav], { encoding: 'utf8' });
17
+ if (a.status !== 0) throw new Error(`No se pudo leer el audio de ${input}: ${a.stderr.slice(-300)}`);
18
+ const out = join(tmp, 'out');
19
+ const args = ['-m', model, '-l', language, '-ml', '1', '-sow', '-oj', '-of', out, '-t', String(threads), '-f', wav];
20
+ const run = (extra) => spawnSync(whisper, [...extra, ...args], { encoding: 'utf8', maxBuffer: 64 * 1024 * 1024 });
21
+ // En Mac Intel la GPU (Metal) se cuelga con whisper: CPU directamente. En el resto, GPU y,
22
+ // si falla, otra vez por CPU.
23
+ const intelMac = process.platform === 'darwin' && process.arch === 'x64';
24
+ let w = run(intelMac ? ['-ng'] : []);
25
+ if (w.status !== 0 && !intelMac) w = run(['-ng']);
26
+ if (w.status !== 0) throw new Error(`whisper falló: ${(w.stderr || '').slice(-400)}`);
27
+ const j = JSON.parse(readFileSync(`${out}.json`, 'utf8'));
28
+ const words = [];
29
+ for (const seg of j.transcription ?? []) {
30
+ const t = seg.text.trim();
31
+ if (!t || /^\[.*\]$/.test(t)) continue; // [MÚSICA], [MUSIC]…
32
+ words.push({ t, s: seg.offsets.from / 1000, e: seg.offsets.to / 1000 });
33
+ }
34
+ return words;
35
+ } finally {
36
+ rmSync(tmp, { recursive: true, force: true });
37
+ }
38
+ }
39
+
40
+ /** Palabras del guion con los tiempos de whisper. `end` = duración del audio. */
41
+ export function alignToScript(script, tokens, end) {
42
+ const sw = script.split(/\s+/).filter(Boolean);
43
+ const out = [];
44
+ let i = 0;
45
+ for (let j = 0; j < tokens.length && i < sw.length; j++) {
46
+ const tk = tokens[j];
47
+ const tEnd = j + 1 < tokens.length ? tokens[j + 1].s : Math.max(tk.e, end);
48
+ // whisper juntó dos palabras en una («a DM» → «ADM»)
49
+ if (i + 1 < sw.length && norm(sw[i] + sw[i + 1]) === norm(tk.t) && norm(sw[i]) !== norm(tk.t)) {
50
+ const mid = tk.s + (tEnd - tk.s) * (sw[i].length / (sw[i].length + sw[i + 1].length));
51
+ out.push({ t: sw[i], s: tk.s, e: mid }, { t: sw[i + 1], s: mid, e: tEnd });
52
+ i += 2;
53
+ } else {
54
+ out.push({ t: sw[i], s: tk.s, e: tEnd });
55
+ i += 1;
56
+ }
57
+ }
58
+ // Palabras que whisper no devolvió: reparte el último tramo entre la última palabra y las que faltan.
59
+ if (i < sw.length && out.length) {
60
+ const last = out.pop();
61
+ const rest = [last.t, ...sw.slice(i)];
62
+ const total = rest.reduce((n, w) => n + w.length, 0);
63
+ let s = last.s;
64
+ for (const w of rest) {
65
+ const e = s + (end - last.s) * (w.length / total);
66
+ out.push({ t: w, s, e });
67
+ s = e;
68
+ }
69
+ }
70
+ return out.map((w) => ({ t: w.t, s: +w.s.toFixed(3), e: +w.e.toFixed(3) }));
71
+ }