@adminide-stack/yantra-mobile 12.0.129-alpha.0 → 12.0.129-alpha.1

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 (360) hide show
  1. package/lib/compute.js +57 -1
  2. package/lib/compute.js.map +1 -1
  3. package/lib/features/agent-chat/NativeAgentChat.js +3 -2
  4. package/lib/features/agent-chat/NativeAgentChat.js.map +1 -1
  5. package/lib/features/apps/AppsCatalog.js +10 -0
  6. package/lib/features/apps/AppsCatalog.js.map +1 -1
  7. package/lib/features/apps/mobileAppCatalog.js +11 -0
  8. package/lib/features/apps/mobileAppCatalog.js.map +1 -1
  9. package/lib/features/canvas/AudioEditorExperience.js +448 -105
  10. package/lib/features/canvas/AudioEditorExperience.js.map +1 -1
  11. package/lib/features/canvas/CanvasAgentChatPane.js +33 -14
  12. package/lib/features/canvas/CanvasAgentChatPane.js.map +1 -1
  13. package/lib/features/canvas/CanvasBoardsGrid.js +493 -41
  14. package/lib/features/canvas/CanvasBoardsGrid.js.map +1 -1
  15. package/lib/features/canvas/CanvasChatResultCard.js.map +1 -1
  16. package/lib/features/canvas/CanvasEditToolsPanel.js +37 -1
  17. package/lib/features/canvas/CanvasEditToolsPanel.js.map +1 -1
  18. package/lib/features/canvas/CanvasExperience.js +237 -22
  19. package/lib/features/canvas/CanvasExperience.js.map +1 -1
  20. package/lib/features/canvas/CanvasGeneratePanel.js +119 -26
  21. package/lib/features/canvas/CanvasGeneratePanel.js.map +1 -1
  22. package/lib/features/canvas/CanvasLooksPanel.js +17 -6
  23. package/lib/features/canvas/CanvasLooksPanel.js.map +1 -1
  24. package/lib/features/canvas/CanvasTasksPanel.js +18 -1
  25. package/lib/features/canvas/CanvasTasksPanel.js.map +1 -1
  26. package/lib/features/canvas/DesignCategoryGallery.js +423 -0
  27. package/lib/features/canvas/DesignCategoryGallery.js.map +1 -0
  28. package/lib/features/canvas/ImageEditorExperience.js +763 -187
  29. package/lib/features/canvas/ImageEditorExperience.js.map +1 -1
  30. package/lib/features/canvas/SetStudioExperience.js +199 -11
  31. package/lib/features/canvas/SetStudioExperience.js.map +1 -1
  32. package/lib/features/canvas/VideoEditorExperience.js +59 -40
  33. package/lib/features/canvas/VideoEditorExperience.js.map +1 -1
  34. package/lib/features/canvas/VideoGeneratorExperience.js +134 -34
  35. package/lib/features/canvas/VideoGeneratorExperience.js.map +1 -1
  36. package/lib/features/canvas/aiEdit.js +4 -2
  37. package/lib/features/canvas/aiEdit.js.map +1 -1
  38. package/lib/features/canvas/audioEditor/AudioWaveform.js +96 -0
  39. package/lib/features/canvas/audioEditor/AudioWaveform.js.map +1 -0
  40. package/lib/features/canvas/audioEditor/audioPeaks.js +93 -0
  41. package/lib/features/canvas/audioEditor/audioPeaks.js.map +1 -0
  42. package/lib/features/canvas/canvasTaskSync.js +34 -7
  43. package/lib/features/canvas/canvasTaskSync.js.map +1 -1
  44. package/lib/features/canvas/canvasTasks.js +23 -3
  45. package/lib/features/canvas/canvasTasks.js.map +1 -1
  46. package/lib/features/canvas/canvasTheme.js +10 -24
  47. package/lib/features/canvas/canvasTheme.js.map +1 -1
  48. package/lib/features/canvas/canvasUi.js +1 -1
  49. package/lib/features/canvas/canvasUi.js.map +1 -1
  50. package/lib/features/canvas/createTiles.js +17 -9
  51. package/lib/features/canvas/createTiles.js.map +1 -1
  52. package/lib/features/canvas/deepLinks.js +35 -5
  53. package/lib/features/canvas/deepLinks.js.map +1 -1
  54. package/lib/features/canvas/designCatalog.js +165 -0
  55. package/lib/features/canvas/designCatalog.js.map +1 -0
  56. package/lib/features/canvas/designCategories.js +262 -0
  57. package/lib/features/canvas/designCategories.js.map +1 -0
  58. package/lib/features/canvas/editorControls.js +406 -0
  59. package/lib/features/canvas/editorControls.js.map +1 -0
  60. package/lib/features/canvas/generationModels.js +5 -3
  61. package/lib/features/canvas/generationModels.js.map +1 -1
  62. package/lib/features/canvas/generationTasks.js +162 -0
  63. package/lib/features/canvas/generationTasks.js.map +1 -0
  64. package/lib/features/canvas/generator/BottomSheet.js +167 -0
  65. package/lib/features/canvas/generator/BottomSheet.js.map +1 -0
  66. package/lib/features/canvas/generator/BusinessCardChatCard.js +155 -0
  67. package/lib/features/canvas/generator/BusinessCardChatCard.js.map +1 -0
  68. package/lib/features/canvas/generator/DirectorSheet.js +163 -0
  69. package/lib/features/canvas/generator/DirectorSheet.js.map +1 -0
  70. package/lib/features/canvas/generator/ReframePreview.js +122 -0
  71. package/lib/features/canvas/generator/ReframePreview.js.map +1 -0
  72. package/lib/features/canvas/generator/RunLogCard.js +119 -0
  73. package/lib/features/canvas/generator/RunLogCard.js.map +1 -0
  74. package/lib/features/canvas/generator/ShotPanel.js +261 -0
  75. package/lib/features/canvas/generator/ShotPanel.js.map +1 -0
  76. package/lib/features/canvas/generator/businessCardWidget.js +117 -0
  77. package/lib/features/canvas/generator/businessCardWidget.js.map +1 -0
  78. package/lib/features/canvas/generator/cameraVocabulary.js +142 -0
  79. package/lib/features/canvas/generator/cameraVocabulary.js.map +1 -0
  80. package/lib/features/canvas/generator/cinematicVocabulary.js +416 -0
  81. package/lib/features/canvas/generator/cinematicVocabulary.js.map +1 -0
  82. package/lib/features/canvas/generator/direction.js +41 -0
  83. package/lib/features/canvas/generator/direction.js.map +1 -0
  84. package/lib/features/canvas/generator/reframeGeometry.js +108 -0
  85. package/lib/features/canvas/generator/reframeGeometry.js.map +1 -0
  86. package/lib/features/canvas/generator/runLog.js +71 -0
  87. package/lib/features/canvas/generator/runLog.js.map +1 -0
  88. package/lib/features/canvas/generator/shot.js +133 -0
  89. package/lib/features/canvas/generator/shot.js.map +1 -0
  90. package/lib/features/canvas/generator/useShotSpec.js +87 -0
  91. package/lib/features/canvas/generator/useShotSpec.js.map +1 -0
  92. package/lib/features/canvas/home/HeroComposer.js +214 -0
  93. package/lib/features/canvas/home/HeroComposer.js.map +1 -0
  94. package/lib/features/canvas/home/HeroMonitor.js +225 -0
  95. package/lib/features/canvas/home/HeroMonitor.js.map +1 -0
  96. package/lib/features/canvas/home/LookDetail.js +185 -0
  97. package/lib/features/canvas/home/LookDetail.js.map +1 -0
  98. package/lib/features/canvas/home/LoopingVideo.js +37 -0
  99. package/lib/features/canvas/home/LoopingVideo.js.map +1 -0
  100. package/lib/features/canvas/home/TemplatesGallery.js +253 -0
  101. package/lib/features/canvas/home/TemplatesGallery.js.map +1 -0
  102. package/lib/features/canvas/home/heroShots.js +100 -0
  103. package/lib/features/canvas/home/heroShots.js.map +1 -0
  104. package/lib/features/canvas/homeWork.js +62 -3
  105. package/lib/features/canvas/homeWork.js.map +1 -1
  106. package/lib/features/canvas/imageEditor/ImageMarkup.js +195 -0
  107. package/lib/features/canvas/imageEditor/ImageMarkup.js.map +1 -0
  108. package/lib/features/canvas/imageEditor/imageEditOps.js +367 -0
  109. package/lib/features/canvas/imageEditor/imageEditOps.js.map +1 -0
  110. package/lib/features/canvas/nativeViewerRegistry.js.map +1 -1
  111. package/lib/features/canvas/rankedCatalogSearch.js +375 -0
  112. package/lib/features/canvas/rankedCatalogSearch.js.map +1 -0
  113. package/lib/features/canvas/recorder/CameraRecorderExperience.js +68 -20
  114. package/lib/features/canvas/recorder/CameraRecorderExperience.js.map +1 -1
  115. package/lib/features/canvas/recorder/RecordingReview.js +272 -0
  116. package/lib/features/canvas/recorder/RecordingReview.js.map +1 -0
  117. package/lib/features/canvas/recorder/RecordingsList.js +179 -0
  118. package/lib/features/canvas/recorder/RecordingsList.js.map +1 -0
  119. package/lib/features/canvas/recorder/recorderOps.js +99 -0
  120. package/lib/features/canvas/recorder/recorderOps.js.map +1 -0
  121. package/lib/features/canvas/seedanceShowcase.js +314 -0
  122. package/lib/features/canvas/seedanceShowcase.js.map +1 -0
  123. package/lib/features/canvas/serverTasks.js +149 -15
  124. package/lib/features/canvas/serverTasks.js.map +1 -1
  125. package/lib/features/canvas/sessionRenewal.js +114 -0
  126. package/lib/features/canvas/sessionRenewal.js.map +1 -0
  127. package/lib/features/canvas/set/SetViewportWebView.js +34 -1
  128. package/lib/features/canvas/set/SetViewportWebView.js.map +1 -1
  129. package/lib/features/canvas/set/agent/setTurn.js +4 -2
  130. package/lib/features/canvas/set/agent/setTurn.js.map +1 -1
  131. package/lib/features/canvas/set/setPresets.js +85 -0
  132. package/lib/features/canvas/set/setPresets.js.map +1 -0
  133. package/lib/features/canvas/set/setProject.js +4 -1
  134. package/lib/features/canvas/set/setProject.js.map +1 -1
  135. package/lib/features/canvas/studioCatalog.js +59 -4
  136. package/lib/features/canvas/studioCatalog.js.map +1 -1
  137. package/lib/features/canvas/studioLooks.js +31 -4
  138. package/lib/features/canvas/studioLooks.js.map +1 -1
  139. package/lib/features/canvas/surfaceIndex.js +1 -14
  140. package/lib/features/canvas/surfaceIndex.js.map +1 -1
  141. package/lib/features/canvas/templateSearch.js +489 -0
  142. package/lib/features/canvas/templateSearch.js.map +1 -0
  143. package/lib/features/canvas/useCanvasSession.js +28 -6
  144. package/lib/features/canvas/useCanvasSession.js.map +1 -1
  145. package/lib/features/canvas/useStudioCatalogTemplates.js +41 -5
  146. package/lib/features/canvas/useStudioCatalogTemplates.js.map +1 -1
  147. package/lib/features/canvas/videoEditor/EditorPanels.js +531 -0
  148. package/lib/features/canvas/videoEditor/EditorPanels.js.map +1 -0
  149. package/lib/features/canvas/videoEditor/agent/AgentCutPane.js +48 -4
  150. package/lib/features/canvas/videoEditor/agent/AgentCutPane.js.map +1 -1
  151. package/lib/features/canvas/videoEditor/agent/agentLoop.js +2 -0
  152. package/lib/features/canvas/videoEditor/agent/agentLoop.js.map +1 -1
  153. package/lib/features/canvas/videoEditor/agent/brainClient.js +97 -27
  154. package/lib/features/canvas/videoEditor/agent/brainClient.js.map +1 -1
  155. package/lib/features/canvas/videoEditor/agent/cutTools.js +707 -3
  156. package/lib/features/canvas/videoEditor/agent/cutTools.js.map +1 -1
  157. package/lib/features/canvas/videoEditor/audioServices.js +165 -0
  158. package/lib/features/canvas/videoEditor/audioServices.js.map +1 -0
  159. package/lib/features/canvas/videoEditor/captions.js +144 -0
  160. package/lib/features/canvas/videoEditor/captions.js.map +1 -0
  161. package/lib/features/canvas/videoEditor/compileTimeline.js +24 -16
  162. package/lib/features/canvas/videoEditor/compileTimeline.js.map +1 -1
  163. package/lib/features/canvas/videoEditor/editorModel.js +12 -2
  164. package/lib/features/canvas/videoEditor/editorModel.js.map +1 -1
  165. package/lib/features/canvas/videoEditor/exportTask.js +89 -7
  166. package/lib/features/canvas/videoEditor/exportTask.js.map +1 -1
  167. package/lib/features/canvas/videoEditor/layers.js +117 -0
  168. package/lib/features/canvas/videoEditor/layers.js.map +1 -0
  169. package/lib/features/canvas/videoEditor/remoteMediaClient.js +45 -18
  170. package/lib/features/canvas/videoEditor/remoteMediaClient.js.map +1 -1
  171. package/lib/features/canvas/videoEditor/renderTimeline.js +18 -6
  172. package/lib/features/canvas/videoEditor/renderTimeline.js.map +1 -1
  173. package/lib/features/canvas/videoEditor/revoice.js +138 -0
  174. package/lib/features/canvas/videoEditor/revoice.js.map +1 -0
  175. package/lib/features/canvas/videoEditor/storageUpload.js +34 -0
  176. package/lib/features/canvas/videoEditor/storageUpload.js.map +1 -0
  177. package/lib/features/canvas/videoEditor/textMotion.js +109 -0
  178. package/lib/features/canvas/videoEditor/textMotion.js.map +1 -0
  179. package/lib/features/canvas/videoEditor/transitions.js +31 -0
  180. package/lib/features/canvas/videoEditor/transitions.js.map +1 -0
  181. package/lib/features/chat/TemplatesChatCards.js +8 -3
  182. package/lib/features/chat/TemplatesChatCards.js.map +1 -1
  183. package/lib/features/design/DesignEditorExperience.js +674 -644
  184. package/lib/features/design/DesignEditorExperience.js.map +1 -1
  185. package/lib/features/design/DesignExperience.js +285 -538
  186. package/lib/features/design/DesignExperience.js.map +1 -1
  187. package/lib/features/design/designCore.js +2 -212
  188. package/lib/features/design/designCore.js.map +1 -1
  189. package/lib/features/design/designIndex.js +1 -50
  190. package/lib/features/design/designIndex.js.map +1 -1
  191. package/lib/features/design/doc/aiDesign.js +247 -0
  192. package/lib/features/design/doc/aiDesign.js.map +1 -0
  193. package/lib/features/design/doc/artifacts.js +280 -0
  194. package/lib/features/design/doc/artifacts.js.map +1 -0
  195. package/lib/features/design/doc/chart.js +98 -0
  196. package/lib/features/design/doc/chart.js.map +1 -0
  197. package/lib/features/design/doc/crop.js +104 -0
  198. package/lib/features/design/doc/crop.js.map +1 -0
  199. package/lib/features/design/doc/curve.js +49 -0
  200. package/lib/features/design/doc/curve.js.map +1 -0
  201. package/lib/features/design/doc/docOps.js +397 -0
  202. package/lib/features/design/doc/docOps.js.map +1 -0
  203. package/lib/features/design/doc/findReplace.js +112 -0
  204. package/lib/features/design/doc/findReplace.js.map +1 -0
  205. package/lib/features/design/doc/fonts.js +79 -0
  206. package/lib/features/design/doc/fonts.js.map +1 -0
  207. package/lib/features/design/doc/frames.js +17 -0
  208. package/lib/features/design/doc/frames.js.map +1 -0
  209. package/lib/features/design/doc/geometry.js +133 -0
  210. package/lib/features/design/doc/geometry.js.map +1 -0
  211. package/lib/features/design/doc/imageAdjust.js +203 -0
  212. package/lib/features/design/doc/imageAdjust.js.map +1 -0
  213. package/lib/features/design/doc/legacyDoc.js +107 -0
  214. package/lib/features/design/doc/legacyDoc.js.map +1 -0
  215. package/lib/features/design/doc/newDoc.js +335 -0
  216. package/lib/features/design/doc/newDoc.js.map +1 -0
  217. package/lib/features/design/doc/pageRange.js +17 -0
  218. package/lib/features/design/doc/pageRange.js.map +1 -0
  219. package/lib/features/design/doc/pathScale.js +68 -0
  220. package/lib/features/design/doc/pathScale.js.map +1 -0
  221. package/lib/features/design/doc/qr.js +62 -0
  222. package/lib/features/design/doc/qr.js.map +1 -0
  223. package/lib/features/design/doc/shapes.js +366 -0
  224. package/lib/features/design/doc/shapes.js.map +1 -0
  225. package/lib/features/design/doc/sizes.js +230 -0
  226. package/lib/features/design/doc/sizes.js.map +1 -0
  227. package/lib/features/design/doc/textEffects.js +134 -0
  228. package/lib/features/design/doc/textEffects.js.map +1 -0
  229. package/lib/features/design/doc/textLayout.js +182 -0
  230. package/lib/features/design/doc/textLayout.js.map +1 -0
  231. package/lib/features/design/doc/types.js +30 -0
  232. package/lib/features/design/doc/types.js.map +1 -0
  233. package/lib/features/design/editor/AiPanel.js +194 -0
  234. package/lib/features/design/editor/AiPanel.js.map +1 -0
  235. package/lib/features/design/editor/ChartDataPanel.js +182 -0
  236. package/lib/features/design/editor/ChartDataPanel.js.map +1 -0
  237. package/lib/features/design/editor/CropOverlay.js +199 -0
  238. package/lib/features/design/editor/CropOverlay.js.map +1 -0
  239. package/lib/features/design/editor/DesignCanvas.js +363 -0
  240. package/lib/features/design/editor/DesignCanvas.js.map +1 -0
  241. package/lib/features/design/editor/ExportSheet.js +123 -0
  242. package/lib/features/design/editor/ExportSheet.js.map +1 -0
  243. package/lib/features/design/editor/FindReplacePanel.js +93 -0
  244. package/lib/features/design/editor/FindReplacePanel.js.map +1 -0
  245. package/lib/features/design/editor/ImageTools.js +188 -0
  246. package/lib/features/design/editor/ImageTools.js.map +1 -0
  247. package/lib/features/design/editor/LayerTools.js +485 -0
  248. package/lib/features/design/editor/LayerTools.js.map +1 -0
  249. package/lib/features/design/editor/PageStrip.js +203 -0
  250. package/lib/features/design/editor/PageStrip.js.map +1 -0
  251. package/lib/features/design/editor/Slideshow.js +97 -0
  252. package/lib/features/design/editor/Slideshow.js.map +1 -0
  253. package/lib/features/design/editor/ToolPanels.js +695 -0
  254. package/lib/features/design/editor/ToolPanels.js.map +1 -0
  255. package/lib/features/design/editor/controls.js +630 -0
  256. package/lib/features/design/editor/controls.js.map +1 -0
  257. package/lib/features/design/editor/useDesignSave.js +91 -0
  258. package/lib/features/design/editor/useDesignSave.js.map +1 -0
  259. package/lib/features/design/export/exportDesign.js +170 -0
  260. package/lib/features/design/export/exportDesign.js.map +1 -0
  261. package/lib/features/design/export/pdf.js +143 -0
  262. package/lib/features/design/export/pdf.js.map +1 -0
  263. package/lib/features/design/home/DesignHome.js +688 -0
  264. package/lib/features/design/home/DesignHome.js.map +1 -0
  265. package/lib/features/design/home/studioHome.js +61 -0
  266. package/lib/features/design/home/studioHome.js.map +1 -0
  267. package/lib/features/design/pickDesignImage.js +60 -0
  268. package/lib/features/design/pickDesignImage.js.map +1 -0
  269. package/lib/features/design/render/DesignPageView.js +69 -0
  270. package/lib/features/design/render/DesignPageView.js.map +1 -0
  271. package/lib/features/design/render/PageCapture.js +288 -0
  272. package/lib/features/design/render/PageCapture.js.map +1 -0
  273. package/lib/features/design/render/TextMeasure.js +115 -0
  274. package/lib/features/design/render/TextMeasure.js.map +1 -0
  275. package/lib/features/design/render/fontRegistry.js +110 -0
  276. package/lib/features/design/render/fontRegistry.js.map +1 -0
  277. package/lib/features/design/render/layers.js +392 -0
  278. package/lib/features/design/render/layers.js.map +1 -0
  279. package/lib/features/design/render/svg.js +35 -0
  280. package/lib/features/design/render/svg.js.map +1 -0
  281. package/lib/features/design/render/svgParts.js +435 -0
  282. package/lib/features/design/render/svgParts.js.map +1 -0
  283. package/lib/features/design/surface/BoardScreen.js +529 -0
  284. package/lib/features/design/surface/BoardScreen.js.map +1 -0
  285. package/lib/features/design/surface/CompareView.js +138 -0
  286. package/lib/features/design/surface/CompareView.js.map +1 -0
  287. package/lib/features/design/surface/CreationScreen.js +294 -0
  288. package/lib/features/design/surface/CreationScreen.js.map +1 -0
  289. package/lib/features/design/surface/DesignAgentChatPane.js +444 -0
  290. package/lib/features/design/surface/DesignAgentChatPane.js.map +1 -0
  291. package/lib/features/design/surface/DesignBoards.js +441 -0
  292. package/lib/features/design/surface/DesignBoards.js.map +1 -0
  293. package/lib/features/design/surface/DesignPreview.js +159 -0
  294. package/lib/features/design/surface/DesignPreview.js.map +1 -0
  295. package/lib/features/design/surface/DesignSurfaceExperience.js +80 -0
  296. package/lib/features/design/surface/DesignSurfaceExperience.js.map +1 -0
  297. package/lib/features/design/surface/FullScreenPreview.js +59 -0
  298. package/lib/features/design/surface/FullScreenPreview.js.map +1 -0
  299. package/lib/features/design/surface/NewSystemDialog.js +122 -0
  300. package/lib/features/design/surface/NewSystemDialog.js.map +1 -0
  301. package/lib/features/design/surface/PickerSheet.js +175 -0
  302. package/lib/features/design/surface/PickerSheet.js.map +1 -0
  303. package/lib/features/design/surface/TemplatesGallery.js +156 -0
  304. package/lib/features/design/surface/TemplatesGallery.js.map +1 -0
  305. package/lib/features/design/surface/WetPaint.js +140 -0
  306. package/lib/features/design/surface/WetPaint.js.map +1 -0
  307. package/lib/features/design/surface/agentTurn.js +229 -0
  308. package/lib/features/design/surface/agentTurn.js.map +1 -0
  309. package/lib/features/design/surface/designBoard.js +218 -0
  310. package/lib/features/design/surface/designBoard.js.map +1 -0
  311. package/lib/features/design/surface/designChannel.js +186 -0
  312. package/lib/features/design/surface/designChannel.js.map +1 -0
  313. package/lib/features/design/surface/designChat.js +141 -0
  314. package/lib/features/design/surface/designChat.js.map +1 -0
  315. package/lib/features/design/surface/designConnector.js +266 -0
  316. package/lib/features/design/surface/designConnector.js.map +1 -0
  317. package/lib/features/design/surface/designDocument.js +40 -0
  318. package/lib/features/design/surface/designDocument.js.map +1 -0
  319. package/lib/features/design/surface/designExport.js +55 -0
  320. package/lib/features/design/surface/designExport.js.map +1 -0
  321. package/lib/features/design/surface/designLinks.js +64 -0
  322. package/lib/features/design/surface/designLinks.js.map +1 -0
  323. package/lib/features/design/surface/designPalette.js +24 -0
  324. package/lib/features/design/surface/designPalette.js.map +1 -0
  325. package/lib/features/design/surface/designRun.js +161 -0
  326. package/lib/features/design/surface/designRun.js.map +1 -0
  327. package/lib/features/design/surface/designTheme.js +119 -0
  328. package/lib/features/design/surface/designTheme.js.map +1 -0
  329. package/lib/features/design/surface/execStream.js +206 -0
  330. package/lib/features/design/surface/execStream.js.map +1 -0
  331. package/lib/features/design/surface/metaball.js +48 -0
  332. package/lib/features/design/surface/metaball.js.map +1 -0
  333. package/lib/features/design/surface/pickReferenceFiles.js +35 -0
  334. package/lib/features/design/surface/pickReferenceFiles.js.map +1 -0
  335. package/lib/features/design/surface/useDesignSurface.js +379 -0
  336. package/lib/features/design/surface/useDesignSurface.js.map +1 -0
  337. package/lib/features/docs/DocBlockRow.js +336 -0
  338. package/lib/features/docs/DocBlockRow.js.map +1 -0
  339. package/lib/features/docs/DocsEditorExperience.js +949 -0
  340. package/lib/features/docs/DocsEditorExperience.js.map +1 -0
  341. package/lib/features/docs/DocsToolbar.js +247 -0
  342. package/lib/features/docs/DocsToolbar.js.map +1 -0
  343. package/lib/features/docs/blocks.js +560 -0
  344. package/lib/features/docs/blocks.js.map +1 -0
  345. package/lib/features/docs/docArtifacts.js +129 -0
  346. package/lib/features/docs/docArtifacts.js.map +1 -0
  347. package/lib/features/docs/docEdits.js +201 -0
  348. package/lib/features/docs/docEdits.js.map +1 -0
  349. package/lib/features/docs/docExport.js +235 -0
  350. package/lib/features/docs/docExport.js.map +1 -0
  351. package/lib/features/docs/docShare.js +62 -0
  352. package/lib/features/docs/docShare.js.map +1 -0
  353. package/lib/features/links/openInApp.js +38 -2
  354. package/lib/features/links/openInApp.js.map +1 -1
  355. package/lib/routes.json +54 -0
  356. package/lib/screens/DesignNative/index.js +35 -0
  357. package/lib/screens/DesignNative/index.js.map +1 -0
  358. package/package.json +3 -3
  359. package/lib/features/design/exportDesign.js +0 -133
  360. package/lib/features/design/exportDesign.js.map +0 -1
@@ -1,4 +1,4 @@
1
- var __defProp = Object.defineProperty;
1
+ import {runActionAcceptsJob}from'./remoteMediaClient.js';var __defProp = Object.defineProperty;
2
2
  var __defProps = Object.defineProperties;
3
3
  var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
4
4
  var __getOwnPropSymbols = Object.getOwnPropertySymbols;
@@ -68,17 +68,29 @@ function parseRenderPoll(d) {
68
68
  error: str(d.error)
69
69
  } : {});
70
70
  }
71
- async function submitRenderTimeline(run, timeline) {
72
- const raw = await run(VIDEO_EDIT_CONNECTOR, RENDER_SUBMIT_ACTION, {
71
+ async function submitRenderTimelineWithJob(run, timeline, {
72
+ ephemeral = false,
73
+ job
74
+ } = {}) {
75
+ const params = __spreadValues({
73
76
  timeline: {
74
77
  steps: timeline.steps,
75
78
  finalRef: timeline.finalRef
76
79
  }
77
- });
80
+ }, ephemeral ? {
81
+ ephemeral: true
82
+ } : {});
83
+ const handed = Boolean(job) && runActionAcceptsJob(run);
84
+ const raw = handed ? await run(VIDEO_EDIT_CONNECTOR, RENDER_SUBMIT_ACTION, params, {
85
+ job
86
+ }) : await run(VIDEO_EDIT_CONNECTOR, RENDER_SUBMIT_ACTION, params);
78
87
  if (raw.successful === false) throw new Error(str(raw.error) || "Could not start the render");
79
88
  const handle = parseRenderHandle(payload(raw));
80
89
  if (!handle) throw new Error("Could not start the render (no handle returned)");
81
- return handle;
90
+ return {
91
+ handle,
92
+ handed
93
+ };
82
94
  }
83
95
  async function pollRenderTimeline(run, handle) {
84
96
  const raw = await run(VIDEO_EDIT_CONNECTOR, RENDER_STATUS_ACTION, {
@@ -204,4 +216,4 @@ async function probeSpecSources(spec, run, {
204
216
  });
205
217
  })
206
218
  });
207
- }export{LEASE_GRACE_MS,MAX_POLL_ERRORS,RENDER_POLL_EVERY_MS,RENDER_POLL_MAX_MS,RENDER_STATUS_ACTION,RENDER_SUBMIT_ACTION,VIDEO_EDIT_CONNECTOR,isLocalOnlyUrl,materializeTimelineInputs,parseRenderHandle,parseRenderPoll,pollRenderTimeline,probeDuration,probeHasAudio,probeSpecSources,renderDeadline,renderProgressPct,renderTimeLeft,submitRenderTimeline};//# sourceMappingURL=renderTimeline.js.map
219
+ }export{LEASE_GRACE_MS,MAX_POLL_ERRORS,RENDER_POLL_EVERY_MS,RENDER_POLL_MAX_MS,RENDER_STATUS_ACTION,RENDER_SUBMIT_ACTION,VIDEO_EDIT_CONNECTOR,isLocalOnlyUrl,materializeTimelineInputs,parseRenderHandle,parseRenderPoll,pollRenderTimeline,probeDuration,probeHasAudio,probeSpecSources,renderDeadline,renderProgressPct,renderTimeLeft,submitRenderTimelineWithJob};//# sourceMappingURL=renderTimeline.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"renderTimeline.js","sources":["../../../../src/features/canvas/videoEditor/renderTimeline.ts"],"sourcesContent":["/**\n * Detached timeline render - native twin of web rpc/renderTimelineRpc.ts.\n *\n * SUBMIT stages the compiled timeline in the video connector's own sandbox\n * and answers with a handle in seconds; STATUS reads how it is going. The\n * render uploads its own output, so nothing holds a request open and the\n * phone can sleep, close the editor or relaunch and pick it back up from the\n * stored handle (canvasTasks kind 'export').\n *\n * Transport-agnostic like exportRenderer: everything goes through a\n * RunMediaAction.\n */\nimport type { CompiledTimeline, InputSource } from './compileTimeline';\nimport type { VideoExportSpec } from './editorModel';\nimport type { RunMediaAction } from './mediaActions';\n\nexport const VIDEO_EDIT_CONNECTOR = 'yantra-video-editing' as const;\nexport const RENDER_SUBMIT_ACTION = 'YANTRA_VIDEO_EDIT_RENDER_TIMELINE_SUBMIT';\nexport const RENDER_STATUS_ACTION = 'YANTRA_VIDEO_EDIT_RENDER_TIMELINE_STATUS';\nexport const RENDER_POLL_EVERY_MS = 10_000;\n/** Follow a render whose handle names no lease for the plan's hour and a bit. */\nexport const RENDER_POLL_MAX_MS = 65 * 60_000;\n/** Past its lease a render is gone; this covers the last poll in flight. */\nexport const LEASE_GRACE_MS = 2 * 60_000;\n/** A poll can blip; this many failures in a row is a lost render. */\nexport const MAX_POLL_ERRORS = 4;\n\n/** The wire timeline: warnings stay on the phone. */\nexport type RenderTimeline = Pick<CompiledTimeline, 'steps' | 'finalRef'>;\n\nexport interface RenderHandle {\n sandboxId: string;\n runId: string;\n /** Where the finished file will be; fetchable once a poll reports `succeeded`. */\n outputUrl: string;\n /** The connector's projection of the render time, for \"time left\". */\n projectedMs?: number;\n /** How long the render may run from launch; polling stops past it. */\n leaseMs?: number;\n /** The connector's word for the person (close to / past the render time limit). */\n notice?: string;\n}\n\nexport interface RenderPoll {\n state: 'running' | 'succeeded' | 'failed';\n step?: { index: number; total: number; label: string };\n label?: string;\n url?: string;\n error?: string;\n}\n\nconst str = (v: unknown): string => (typeof v === 'string' ? v : '');\nconst positiveMs = (v: unknown): number | undefined => {\n const n = Number(v);\n return Number.isFinite(n) && n > 0 ? n : undefined;\n};\n\n/** The runner can hand back the connector JSON with or without its `{ successful, data }` envelope. */\nconst payload = (raw: Record<string, unknown>): Record<string, unknown> =>\n (raw.data && typeof raw.data === 'object' ? raw.data : raw) as Record<string, unknown>;\n\n/** Read one SUBMIT answer; undefined without a handle to poll. Pure. */\nexport function parseRenderHandle(d: Record<string, unknown>): RenderHandle | undefined {\n const [sandboxId, runId, outputUrl] = [str(d.sandbox_id), str(d.run_id), str(d.output_url)];\n if (!sandboxId || !runId || !outputUrl) return undefined;\n const projectedMs = positiveMs(d.projected_ms);\n const leaseMs = positiveMs(d.lease_ms);\n const notice = str(d.notice).trim();\n return {\n sandboxId,\n runId,\n outputUrl,\n ...(projectedMs ? { projectedMs } : {}),\n ...(leaseMs ? { leaseMs } : {}),\n ...(notice ? { notice } : {}),\n };\n}\n\n/** Read one STATUS answer. Pure. */\nexport function parseRenderPoll(d: Record<string, unknown>): RenderPoll {\n const state = d.state === 'succeeded' || d.state === 'failed' ? d.state : 'running';\n const total = Number(d.total);\n const step =\n Number.isFinite(total) && total > 0 ? { index: Number(d.step) || 0, total, label: str(d.label) } : undefined;\n return {\n state,\n ...(step ? { step } : {}),\n ...(str(d.label) ? { label: str(d.label) } : {}),\n ...(str(d.output_url) ? { url: str(d.output_url) } : {}),\n ...(str(d.error) ? { error: str(d.error) } : {}),\n };\n}\n\n/** Submit sends no time budget: the connector projects the render from its sources. */\nexport async function submitRenderTimeline(run: RunMediaAction, timeline: RenderTimeline): Promise<RenderHandle> {\n const raw = await run(VIDEO_EDIT_CONNECTOR, RENDER_SUBMIT_ACTION, {\n timeline: { steps: timeline.steps, finalRef: timeline.finalRef },\n });\n if (raw.successful === false) throw new Error(str(raw.error) || 'Could not start the render');\n const handle = parseRenderHandle(payload(raw));\n if (!handle) throw new Error('Could not start the render (no handle returned)');\n return handle;\n}\n\n/** One status poll. Throws on a transport failure; a failed render is a `failed` poll. */\nexport async function pollRenderTimeline(run: RunMediaAction, handle: RenderHandle): Promise<RenderPoll> {\n const raw = await run(VIDEO_EDIT_CONNECTOR, RENDER_STATUS_ACTION, {\n sandbox_id: handle.sandboxId,\n run_id: handle.runId,\n });\n if (raw.successful === false) throw new Error(str(raw.error) || 'Render status poll failed');\n return parseRenderPoll(payload(raw));\n}\n\n/** When to stop following a render: its lease (+grace) when named, else the plan's hour. Pure. */\nexport function renderDeadline(startedAt: number, handle: Pick<RenderHandle, 'leaseMs'> | undefined): number {\n return startedAt + (handle?.leaseMs ? handle.leaseMs + LEASE_GRACE_MS : RENDER_POLL_MAX_MS);\n}\n\n/** What is left by the connector's projection, in words (web renderTimeLeft). Pure. */\nexport function renderTimeLeft(projectedMs: number, elapsedMs: number): string {\n const left = projectedMs - elapsedMs;\n if (left <= 0) return 'Taking longer than estimated';\n if (left < 60_000) return 'Less than a minute left';\n return `About ${Math.max(1, Math.round(left / 60_000))} min left`;\n}\n\n/** How full a progress bar is: steps done, or time against the projection (never claims 100% on time alone). Pure. */\nexport function renderProgressPct(\n step: RenderPoll['step'],\n projectedMs: number | undefined,\n elapsedMs: number,\n): number {\n const byStep = step && step.total > 0 ? Math.min(100, ((step.index - 1) / step.total) * 100) : 0;\n const byTime = projectedMs ? Math.min(95, (elapsedMs / projectedMs) * 100) : 0;\n return Math.max(0, byStep, byTime);\n}\n\n/** Phone-local or inline URIs the connector cannot fetch. */\nexport function isLocalOnlyUrl(url: string): boolean {\n return /^(file|ph|assets-library|content|data|blob):/i.test(url);\n}\n\n/**\n * Make every input of a compiled timeline fetchable by the connector,\n * rewriting it in place: phone-local / data: sources are uploaded once each,\n * and `refresh` (optional) re-signs stored links that may have lapsed. Walks\n * primary inputs, cross-step refs and string params alike (web\n * materializeTimelineInputs). Returns how many distinct URLs were rewritten.\n */\nexport async function materializeTimelineInputs(\n compiled: RenderTimeline,\n {\n upload,\n refresh,\n onProgress,\n }: {\n upload?: (localUri: string) => Promise<string>;\n refresh?: (url: string) => Promise<string>;\n onProgress?: (label: string) => void;\n } = {},\n): Promise<number> {\n const cache = new Map<string, string>();\n const lift = async (url: string): Promise<string> => {\n if (!url) return url;\n const cached = cache.get(url);\n if (cached) return cached;\n let next = url;\n if (isLocalOnlyUrl(url)) {\n if (!upload) throw new Error('A clip is on this phone and no uploader is available');\n onProgress?.(`Uploading media ${cache.size + 1}…`);\n next = await upload(url);\n } else if (refresh) {\n next = await refresh(url);\n }\n if (next !== url) cache.set(url, next);\n return next;\n };\n const liftRef = async (ref: InputSource) => {\n if (ref.kind === 'url') ref.url = await lift(ref.url);\n };\n for (const step of compiled.steps) {\n await liftRef(step.primaryInput);\n for (const value of Object.values(step.inputRefs ?? {})) {\n for (const ref of Array.isArray(value) ? value : [value]) await liftRef(ref);\n }\n for (const [key, value] of Object.entries(step.params)) {\n if (typeof value === 'string' && /^(https?|file|ph|assets-library|content|data|blob):/i.test(value)) {\n step.params[key] = await lift(value);\n }\n }\n }\n await liftRef(compiled.finalRef);\n return cache.size;\n}\n\n// ── Probing (open trims + sound-less videos) ────────────────────────────────\n\n/** Seconds from a PROBE answer (several connector shapes). */\nexport function probeDuration(raw: Record<string, unknown>): number | undefined {\n const d = payload(raw);\n const format = d.format as Record<string, unknown> | undefined;\n const n = Number(d.duration_secs ?? d.duration ?? format?.duration);\n return Number.isFinite(n) && n > 0 ? n : undefined;\n}\n\n/** Whether a PROBE answer shows an audio stream; undefined when it cannot tell. */\nexport function probeHasAudio(raw: Record<string, unknown>): boolean | undefined {\n const d = payload(raw);\n if (typeof d.has_audio === 'boolean') return d.has_audio;\n if (typeof d.hasAudio === 'boolean') return d.hasAudio;\n if (Array.isArray(d.streams)) {\n return (d.streams as Array<Record<string, unknown>>).some(\n (s) => s?.codec_type === 'audio' || s?.type === 'audio',\n );\n }\n if ('audio_codec' in d) return Boolean(d.audio_codec);\n if (d.audio && typeof d.audio === 'object') return true;\n if (d.audio === null || d.audio === false) return false;\n return undefined;\n}\n\n/**\n * Fill what the compiler needs to know about video sources before it runs:\n * the length of an open-ended trim (so the trim and a transition hold are\n * exact), and - only when the compiled lane mixes audio - whether each video\n * carries sound, so a silent one stays out of the lane. One PROBE per\n * distinct source; a failed probe leaves the clip as it was.\n */\nexport async function probeSpecSources(\n spec: VideoExportSpec,\n run: RunMediaAction,\n { needAudio }: { needAudio: boolean },\n): Promise<VideoExportSpec> {\n const holdsAfter = (i: number) => Boolean(spec.clips[i + 1]?.transitionIn);\n const wants = spec.clips\n .map((c, i) => ({ c, i }))\n .filter(\n ({ c, i }) =>\n c.type === 'video' &&\n !isLocalOnlyUrl(c.src) &&\n ((c.sourceDurationSec == null && (c.trimEndSec === null || holdsAfter(i))) ||\n (needAudio && c.hasAudio === undefined && !c.muted)),\n );\n if (!wants.length) return spec;\n const answers = new Map<string, Record<string, unknown> | null>();\n await Promise.all(\n [...new Set(wants.map(({ c }) => c.src))].map(async (src) => {\n try {\n answers.set(src, await run(VIDEO_EDIT_CONNECTOR, 'YANTRA_VIDEO_EDIT_PROBE', { input_url: src }));\n } catch {\n answers.set(src, null);\n }\n }),\n );\n return {\n ...spec,\n clips: spec.clips.map((c) => {\n const a = c.type === 'video' ? answers.get(c.src) : null;\n if (!a) return c;\n const duration = c.sourceDurationSec ?? probeDuration(a);\n const hasAudio = c.hasAudio ?? (needAudio ? probeHasAudio(a) : undefined);\n return {\n ...c,\n ...(duration ? { sourceDurationSec: duration } : {}),\n ...(hasAudio === undefined ? {} : { hasAudio }),\n };\n }),\n };\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"renderTimeline.js","sources":["../../../../src/features/canvas/videoEditor/renderTimeline.ts"],"sourcesContent":["/**\n * Detached timeline render - native twin of web rpc/renderTimelineRpc.ts.\n *\n * SUBMIT stages the compiled timeline in the video connector's own sandbox\n * and answers with a handle in seconds; STATUS reads how it is going. The\n * render uploads its own output, so nothing holds a request open and the\n * phone can sleep, close the editor or relaunch and pick it back up from the\n * stored handle (canvasTasks kind 'export').\n *\n * Transport-agnostic like exportRenderer: everything goes through a\n * RunMediaAction.\n */\nimport type { CompiledTimeline, InputSource } from './compileTimeline';\nimport type { VideoExportSpec } from './editorModel';\nimport type { RunMediaAction } from './mediaActions';\nimport { runActionAcceptsJob, type RunMediaActionWithBody } from './remoteMediaClient';\n\nexport const VIDEO_EDIT_CONNECTOR = 'yantra-video-editing' as const;\nexport const RENDER_SUBMIT_ACTION = 'YANTRA_VIDEO_EDIT_RENDER_TIMELINE_SUBMIT';\nexport const RENDER_STATUS_ACTION = 'YANTRA_VIDEO_EDIT_RENDER_TIMELINE_STATUS';\nexport const RENDER_POLL_EVERY_MS = 10_000;\n/** Follow a render whose handle names no lease for the plan's hour and a bit. */\nexport const RENDER_POLL_MAX_MS = 65 * 60_000;\n/** Past its lease a render is gone; this covers the last poll in flight. */\nexport const LEASE_GRACE_MS = 2 * 60_000;\n/** A poll can blip; this many failures in a row is a lost render. */\nexport const MAX_POLL_ERRORS = 4;\n\n/** The wire timeline: warnings stay on the phone. */\nexport type RenderTimeline = Pick<CompiledTimeline, 'steps' | 'finalRef'>;\n\nexport interface RenderHandle {\n sandboxId: string;\n runId: string;\n /** Where the finished file will be; fetchable once a poll reports `succeeded`. */\n outputUrl: string;\n /** The connector's projection of the render time, for \"time left\". */\n projectedMs?: number;\n /** How long the render may run from launch; polling stops past it. */\n leaseMs?: number;\n /** The connector's word for the person (close to / past the render time limit). */\n notice?: string;\n}\n\nexport interface RenderPoll {\n state: 'running' | 'succeeded' | 'failed';\n step?: { index: number; total: number; label: string };\n label?: string;\n url?: string;\n error?: string;\n}\n\nconst str = (v: unknown): string => (typeof v === 'string' ? v : '');\nconst positiveMs = (v: unknown): number | undefined => {\n const n = Number(v);\n return Number.isFinite(n) && n > 0 ? n : undefined;\n};\n\n/** The runner can hand back the connector JSON with or without its `{ successful, data }` envelope. */\nconst payload = (raw: Record<string, unknown>): Record<string, unknown> =>\n (raw.data && typeof raw.data === 'object' ? raw.data : raw) as Record<string, unknown>;\n\n/** Read one SUBMIT answer; undefined without a handle to poll. Pure. */\nexport function parseRenderHandle(d: Record<string, unknown>): RenderHandle | undefined {\n const [sandboxId, runId, outputUrl] = [str(d.sandbox_id), str(d.run_id), str(d.output_url)];\n if (!sandboxId || !runId || !outputUrl) return undefined;\n const projectedMs = positiveMs(d.projected_ms);\n const leaseMs = positiveMs(d.lease_ms);\n const notice = str(d.notice).trim();\n return {\n sandboxId,\n runId,\n outputUrl,\n ...(projectedMs ? { projectedMs } : {}),\n ...(leaseMs ? { leaseMs } : {}),\n ...(notice ? { notice } : {}),\n };\n}\n\n/** Read one STATUS answer. Pure. */\nexport function parseRenderPoll(d: Record<string, unknown>): RenderPoll {\n const state = d.state === 'succeeded' || d.state === 'failed' ? d.state : 'running';\n const total = Number(d.total);\n const step =\n Number.isFinite(total) && total > 0 ? { index: Number(d.step) || 0, total, label: str(d.label) } : undefined;\n return {\n state,\n ...(step ? { step } : {}),\n ...(str(d.label) ? { label: str(d.label) } : {}),\n ...(str(d.output_url) ? { url: str(d.output_url) } : {}),\n ...(str(d.error) ? { error: str(d.error) } : {}),\n };\n}\n\n/** What a SUBMIT may carry besides the timeline (web renderTimelineRpc :78-95). */\nexport interface RenderSubmitOptions {\n /** A throwaway render (a preview): the connector keeps no copy past the session. */\n ephemeral?: boolean;\n /**\n * The export's server job with RENDER_FOLLOW (../serverTasks): the agent\n * then follows the render itself and reports to the job's row. Only a\n * runner that puts `job` on the exec body can carry it.\n */\n job?: unknown;\n}\n\n/**\n * SUBMIT, answering whether the job went out with it (`handed`) - a host seam\n * that predates the field cannot carry it, and then nobody reports on the job.\n */\nexport async function submitRenderTimelineWithJob(\n run: RunMediaAction,\n timeline: RenderTimeline,\n { ephemeral = false, job }: RenderSubmitOptions = {},\n): Promise<{ handle: RenderHandle; handed: boolean }> {\n const params = {\n timeline: { steps: timeline.steps, finalRef: timeline.finalRef },\n ...(ephemeral ? { ephemeral: true } : {}),\n };\n const handed = Boolean(job) && runActionAcceptsJob(run);\n const raw = handed\n ? await (run as RunMediaActionWithBody)(VIDEO_EDIT_CONNECTOR, RENDER_SUBMIT_ACTION, params, { job })\n : await run(VIDEO_EDIT_CONNECTOR, RENDER_SUBMIT_ACTION, params);\n if (raw.successful === false) throw new Error(str(raw.error) || 'Could not start the render');\n const handle = parseRenderHandle(payload(raw));\n if (!handle) throw new Error('Could not start the render (no handle returned)');\n return { handle, handed };\n}\n\n/** Submit sends no time budget: the connector projects the render from its sources. */\nexport async function submitRenderTimeline(\n run: RunMediaAction,\n timeline: RenderTimeline,\n options: RenderSubmitOptions = {},\n): Promise<RenderHandle> {\n return (await submitRenderTimelineWithJob(run, timeline, options)).handle;\n}\n\n/** One status poll. Throws on a transport failure; a failed render is a `failed` poll. */\nexport async function pollRenderTimeline(run: RunMediaAction, handle: RenderHandle): Promise<RenderPoll> {\n const raw = await run(VIDEO_EDIT_CONNECTOR, RENDER_STATUS_ACTION, {\n sandbox_id: handle.sandboxId,\n run_id: handle.runId,\n });\n if (raw.successful === false) throw new Error(str(raw.error) || 'Render status poll failed');\n return parseRenderPoll(payload(raw));\n}\n\n/** When to stop following a render: its lease (+grace) when named, else the plan's hour. Pure. */\nexport function renderDeadline(startedAt: number, handle: Pick<RenderHandle, 'leaseMs'> | undefined): number {\n return startedAt + (handle?.leaseMs ? handle.leaseMs + LEASE_GRACE_MS : RENDER_POLL_MAX_MS);\n}\n\n/** What is left by the connector's projection, in words (web renderTimeLeft). Pure. */\nexport function renderTimeLeft(projectedMs: number, elapsedMs: number): string {\n const left = projectedMs - elapsedMs;\n if (left <= 0) return 'Taking longer than estimated';\n if (left < 60_000) return 'Less than a minute left';\n return `About ${Math.max(1, Math.round(left / 60_000))} min left`;\n}\n\n/** How full a progress bar is: steps done, or time against the projection (never claims 100% on time alone). Pure. */\nexport function renderProgressPct(\n step: RenderPoll['step'],\n projectedMs: number | undefined,\n elapsedMs: number,\n): number {\n const byStep = step && step.total > 0 ? Math.min(100, ((step.index - 1) / step.total) * 100) : 0;\n const byTime = projectedMs ? Math.min(95, (elapsedMs / projectedMs) * 100) : 0;\n return Math.max(0, byStep, byTime);\n}\n\n/** Phone-local or inline URIs the connector cannot fetch. */\nexport function isLocalOnlyUrl(url: string): boolean {\n return /^(file|ph|assets-library|content|data|blob):/i.test(url);\n}\n\n/**\n * Make every input of a compiled timeline fetchable by the connector,\n * rewriting it in place: phone-local / data: sources are uploaded once each,\n * and `refresh` (optional) re-signs stored links that may have lapsed. Walks\n * primary inputs, cross-step refs and string params alike (web\n * materializeTimelineInputs). Returns how many distinct URLs were rewritten.\n */\nexport async function materializeTimelineInputs(\n compiled: RenderTimeline,\n {\n upload,\n refresh,\n onProgress,\n }: {\n upload?: (localUri: string) => Promise<string>;\n refresh?: (url: string) => Promise<string>;\n onProgress?: (label: string) => void;\n } = {},\n): Promise<number> {\n const cache = new Map<string, string>();\n const lift = async (url: string): Promise<string> => {\n if (!url) return url;\n const cached = cache.get(url);\n if (cached) return cached;\n let next = url;\n if (isLocalOnlyUrl(url)) {\n if (!upload) throw new Error('A clip is on this phone and no uploader is available');\n onProgress?.(`Uploading media ${cache.size + 1}…`);\n next = await upload(url);\n } else if (refresh) {\n next = await refresh(url);\n }\n if (next !== url) cache.set(url, next);\n return next;\n };\n const liftRef = async (ref: InputSource) => {\n if (ref.kind === 'url') ref.url = await lift(ref.url);\n };\n for (const step of compiled.steps) {\n await liftRef(step.primaryInput);\n for (const value of Object.values(step.inputRefs ?? {})) {\n for (const ref of Array.isArray(value) ? value : [value]) await liftRef(ref);\n }\n for (const [key, value] of Object.entries(step.params)) {\n if (typeof value === 'string' && /^(https?|file|ph|assets-library|content|data|blob):/i.test(value)) {\n step.params[key] = await lift(value);\n }\n }\n }\n await liftRef(compiled.finalRef);\n return cache.size;\n}\n\n// ── Probing (open trims + sound-less videos) ────────────────────────────────\n\n/** Seconds from a PROBE answer (several connector shapes). */\nexport function probeDuration(raw: Record<string, unknown>): number | undefined {\n const d = payload(raw);\n const format = d.format as Record<string, unknown> | undefined;\n const n = Number(d.duration_secs ?? d.duration ?? format?.duration);\n return Number.isFinite(n) && n > 0 ? n : undefined;\n}\n\n/** Whether a PROBE answer shows an audio stream; undefined when it cannot tell. */\nexport function probeHasAudio(raw: Record<string, unknown>): boolean | undefined {\n const d = payload(raw);\n if (typeof d.has_audio === 'boolean') return d.has_audio;\n if (typeof d.hasAudio === 'boolean') return d.hasAudio;\n if (Array.isArray(d.streams)) {\n return (d.streams as Array<Record<string, unknown>>).some(\n (s) => s?.codec_type === 'audio' || s?.type === 'audio',\n );\n }\n if ('audio_codec' in d) return Boolean(d.audio_codec);\n if (d.audio && typeof d.audio === 'object') return true;\n if (d.audio === null || d.audio === false) return false;\n return undefined;\n}\n\n/**\n * Fill what the compiler needs to know about video sources before it runs:\n * the length of an open-ended trim (so the trim and a transition hold are\n * exact), and - only when the compiled lane mixes audio - whether each video\n * carries sound, so a silent one stays out of the lane. One PROBE per\n * distinct source; a failed probe leaves the clip as it was.\n */\nexport async function probeSpecSources(\n spec: VideoExportSpec,\n run: RunMediaAction,\n { needAudio }: { needAudio: boolean },\n): Promise<VideoExportSpec> {\n const holdsAfter = (i: number) => Boolean(spec.clips[i + 1]?.transitionIn);\n const wants = spec.clips\n .map((c, i) => ({ c, i }))\n .filter(\n ({ c, i }) =>\n c.type === 'video' &&\n !isLocalOnlyUrl(c.src) &&\n ((c.sourceDurationSec == null && (c.trimEndSec === null || holdsAfter(i))) ||\n (needAudio && c.hasAudio === undefined && !c.muted)),\n );\n if (!wants.length) return spec;\n const answers = new Map<string, Record<string, unknown> | null>();\n await Promise.all(\n [...new Set(wants.map(({ c }) => c.src))].map(async (src) => {\n try {\n answers.set(src, await run(VIDEO_EDIT_CONNECTOR, 'YANTRA_VIDEO_EDIT_PROBE', { input_url: src }));\n } catch {\n answers.set(src, null);\n }\n }),\n );\n return {\n ...spec,\n clips: spec.clips.map((c) => {\n const a = c.type === 'video' ? answers.get(c.src) : null;\n if (!a) return c;\n const duration = c.sourceDurationSec ?? probeDuration(a);\n const hasAudio = c.hasAudio ?? (needAudio ? probeHasAudio(a) : undefined);\n return {\n ...c,\n ...(duration ? { sourceDurationSec: duration } : {}),\n ...(hasAudio === undefined ? {} : { hasAudio }),\n };\n }),\n };\n}\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,138 @@
1
+ import {updateClip}from'./editorModel.js';import {resultUrl}from'./mediaActions.js';import {sceneSpans}from'./sceneLayers.js';import {transcribeMedia,placeCaptions,captionsForClip}from'./captions.js';import {speakLine}from'./audioServices.js';var __defProp = Object.defineProperty;
2
+ var __defProps = Object.defineProperties;
3
+ var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
4
+ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __propIsEnum = Object.prototype.propertyIsEnumerable;
7
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
8
+ var __spreadValues = (a, b) => {
9
+ for (var prop in b || (b = {}))
10
+ if (__hasOwnProp.call(b, prop))
11
+ __defNormalProp(a, prop, b[prop]);
12
+ if (__getOwnPropSymbols)
13
+ for (var prop of __getOwnPropSymbols(b)) {
14
+ if (__propIsEnum.call(b, prop))
15
+ __defNormalProp(a, prop, b[prop]);
16
+ }
17
+ return a;
18
+ };
19
+ var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
20
+ const FIT_TOLERANCE = 1.02;
21
+ const MAX_FIT_FACTOR = 1.35;
22
+ function cuesInWindow(cues, clip) {
23
+ var _a;
24
+ const from = clip.trimStartSec;
25
+ const to = (_a = clip.trimEndSec) != null ? _a : Infinity;
26
+ return cues.filter((c) => c.start >= from && c.start < to);
27
+ }
28
+ function roomFor(cues, i, endSec) {
29
+ var _a, _b;
30
+ const next = (_b = (_a = cues[i + 1]) == null ? void 0 : _a.start) != null ? _b : endSec;
31
+ return Math.max(0, next - cues[i].start);
32
+ }
33
+ function fitFactor(takeSec, roomSec) {
34
+ if (roomSec <= 0 || takeSec <= roomSec * FIT_TOLERANCE) return 1;
35
+ return Math.min(MAX_FIT_FACTOR, Math.round(takeSec / roomSec * 100) / 100);
36
+ }
37
+ function looksEnglish(cues) {
38
+ var _a;
39
+ const text = cues.map((c) => c.text).join(" ");
40
+ if (!text.trim()) return true;
41
+ const nonAscii = ((_a = text.match(/[^\x00-\x7F]/g)) != null ? _a : []).length;
42
+ return nonAscii / text.length < 0.3;
43
+ }
44
+ let takeCounter = 0;
45
+ function placeRevoiceTakes(timeline, clipId, cues, takes, opts, sourceSec) {
46
+ var _a;
47
+ const clip = timeline.clips.find((c) => c.id === clipId);
48
+ const span = sceneSpans(timeline.clips, sourceSec).find((s) => s.id === clipId);
49
+ if (!clip || !span) return timeline;
50
+ const audio = takes.map((take) => {
51
+ takeCounter += 1;
52
+ const cue = cues[take.index];
53
+ const startSec = span.startSec + (cue.start - clip.trimStartSec) / clip.speed;
54
+ const room = span.endSec > span.startSec ? Math.max(0.1, span.endSec - startSec) : null;
55
+ return {
56
+ id: `revoice-${Date.now().toString(36)}-${takeCounter}`,
57
+ audioUrl: take.url,
58
+ startSec: Math.round(startSec * 1e3) / 1e3,
59
+ durationSec: room !== null && take.durationSec > room ? Math.round(room * 1e3) / 1e3 : null,
60
+ volume: 1,
61
+ label: `AI voice \xB7 ${cue.text.trim().slice(0, 24)}`,
62
+ sceneId: clip.id
63
+ };
64
+ });
65
+ let next = __spreadProps(__spreadValues({}, timeline), {
66
+ sceneAudio: [...(_a = timeline.sceneAudio) != null ? _a : [], ...audio]
67
+ });
68
+ if (opts.muteOriginal) next = updateClip(next, clip.id, {
69
+ muted: true
70
+ });
71
+ if (opts.captions) next = placeCaptions(next, captionsForClip(next, clip.id, cues, sourceSec));
72
+ return next;
73
+ }
74
+ async function probeAudioSec(run, url) {
75
+ var _a;
76
+ try {
77
+ const r = await run("yantra-audio-editing", "YANTRA_AUDIO_EDIT_PROBE", {
78
+ input_url: url
79
+ });
80
+ const root = r.data && typeof r.data === "object" ? r.data : r;
81
+ const secs = Number((_a = root.duration_secs) != null ? _a : root.duration);
82
+ return Number.isFinite(secs) && secs > 0 ? secs : 0;
83
+ } catch (e) {
84
+ return 0;
85
+ }
86
+ }
87
+ async function revoiceClip(run, clip, voice, onProgress, isCancelled) {
88
+ var _a;
89
+ onProgress == null ? void 0 : onProgress({
90
+ phase: "transcribing",
91
+ done: 0,
92
+ total: 0
93
+ });
94
+ const cues = cuesInWindow(await transcribeMedia(run, clip.src), clip);
95
+ if (!cues.length) throw new Error("No speech was found in this clip.");
96
+ if (!looksEnglish(cues)) throw new Error("English speech only for now - the stock voices are English.");
97
+ const endSec = (_a = clip.trimEndSec) != null ? _a : cues[cues.length - 1].end;
98
+ const takes = [];
99
+ const failed = [];
100
+ for (let i = 0; i < cues.length; i += 1) {
101
+ if (isCancelled == null ? void 0 : isCancelled()) break;
102
+ onProgress == null ? void 0 : onProgress({
103
+ phase: "speaking",
104
+ done: i,
105
+ total: cues.length
106
+ });
107
+ try {
108
+ let url = await speakLine(run, cues[i].text, voice);
109
+ let durationSec = await probeAudioSec(run, url);
110
+ const factor = durationSec > 0 ? fitFactor(durationSec, roomFor(cues, i, endSec)) : 1;
111
+ if (factor > 1) {
112
+ url = resultUrl(await run("yantra-audio-editing", "YANTRA_AUDIO_EDIT_SPEED", {
113
+ input_url: url,
114
+ factor
115
+ }), "SPEED");
116
+ durationSec /= factor;
117
+ }
118
+ takes.push({
119
+ index: i,
120
+ url,
121
+ durationSec,
122
+ factor
123
+ });
124
+ } catch (e) {
125
+ failed.push(i);
126
+ }
127
+ }
128
+ onProgress == null ? void 0 : onProgress({
129
+ phase: "speaking",
130
+ done: cues.length,
131
+ total: cues.length
132
+ });
133
+ return {
134
+ cues,
135
+ takes,
136
+ failed
137
+ };
138
+ }export{FIT_TOLERANCE,MAX_FIT_FACTOR,cuesInWindow,fitFactor,looksEnglish,placeRevoiceTakes,probeAudioSec,revoiceClip,roomFor};//# sourceMappingURL=revoice.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"revoice.js","sources":["../../../../src/features/canvas/videoEditor/revoice.ts"],"sourcesContent":["/**\n * Re-voice a video clip with a stock AI voice (web utils/revoice +\n * RevoiceSection): transcribe it, speak each cue, speed a take that outruns\n * its room (never past 1.35x), and lay the takes as scene audio at their\n * cue's time. Optional: mute the original, caption the new lines.\n */\nimport type { EditorClip, EditorTimeline, SceneAudio } from './editorModel';\nimport { updateClip } from './editorModel';\nimport { resultUrl, type RunMediaAction } from './mediaActions';\nimport { sceneSpans } from './sceneLayers';\nimport { captionsForClip, placeCaptions, transcribeMedia, type TranscriptCue } from './captions';\nimport { speakLine } from './audioServices';\n\n/** A take within 2% of its room needs no fitting. */\nexport const FIT_TOLERANCE = 1.02;\n/** atempo above this sounds rushed; past it the take just runs long. */\nexport const MAX_FIT_FACTOR = 1.35;\n\nexport interface RevoiceTake {\n index: number;\n url: string;\n /** Seconds, after any speed fit. */\n durationSec: number;\n factor: number;\n}\n\n/** Cues that start inside the clip's trim; speech cut away must not be spoken. */\nexport function cuesInWindow(\n cues: readonly TranscriptCue[],\n clip: Pick<EditorClip, 'trimStartSec' | 'trimEndSec'>,\n): TranscriptCue[] {\n const from = clip.trimStartSec;\n const to = clip.trimEndSec ?? Infinity;\n return cues.filter((c) => c.start >= from && c.start < to);\n}\n\n/** Seconds a take may occupy: its cue's start up to the next cue's start, or `endSec` for the last. */\nexport function roomFor(cues: readonly TranscriptCue[], i: number, endSec: number): number {\n const next = cues[i + 1]?.start ?? endSec;\n return Math.max(0, next - cues[i].start);\n}\n\n/** Speed-up that fits a take into its room; never slows down, capped so speech stays clear. */\nexport function fitFactor(takeSec: number, roomSec: number): number {\n if (roomSec <= 0 || takeSec <= roomSec * FIT_TOLERANCE) return 1;\n return Math.min(MAX_FIT_FACTOR, Math.round((takeSec / roomSec) * 100) / 100);\n}\n\n/** Non-ASCII share as the language test; the stock voices are English. */\nexport function looksEnglish(cues: readonly TranscriptCue[]): boolean {\n const text = cues.map((c) => c.text).join(' ');\n if (!text.trim()) return true;\n const nonAscii = (text.match(/[^\\x00-\\x7F]/g) ?? []).length;\n return nonAscii / text.length < 0.3;\n}\n\nlet takeCounter = 0;\n\n/** Takes as scene audio at their cue's timeline second, owned by the clip's scene. */\nexport function placeRevoiceTakes(\n timeline: EditorTimeline,\n clipId: string,\n cues: readonly TranscriptCue[],\n takes: readonly RevoiceTake[],\n opts: { muteOriginal: boolean; captions: boolean },\n sourceSec?: Readonly<Record<string, number>>,\n): EditorTimeline {\n const clip = timeline.clips.find((c) => c.id === clipId);\n const span = sceneSpans(timeline.clips, sourceSec).find((s) => s.id === clipId);\n if (!clip || !span) return timeline;\n const audio: SceneAudio[] = takes.map((take) => {\n takeCounter += 1;\n const cue = cues[take.index];\n const startSec = span.startSec + (cue.start - clip.trimStartSec) / clip.speed;\n const room = span.endSec > span.startSec ? Math.max(0.1, span.endSec - startSec) : null;\n return {\n id: `revoice-${Date.now().toString(36)}-${takeCounter}`,\n audioUrl: take.url,\n startSec: Math.round(startSec * 1000) / 1000,\n durationSec: room !== null && take.durationSec > room ? Math.round(room * 1000) / 1000 : null,\n volume: 1,\n label: `AI voice · ${cue.text.trim().slice(0, 24)}`,\n sceneId: clip.id,\n };\n });\n let next: EditorTimeline = { ...timeline, sceneAudio: [...(timeline.sceneAudio ?? []), ...audio] };\n if (opts.muteOriginal) next = updateClip(next, clip.id, { muted: true });\n if (opts.captions) next = placeCaptions(next, captionsForClip(next, clip.id, cues, sourceSec));\n return next;\n}\n\nexport interface RevoiceProgress {\n phase: 'transcribing' | 'speaking';\n done: number;\n total: number;\n}\n\n/** Probe an audio URL's length in seconds; 0 when unreadable. */\nexport async function probeAudioSec(run: RunMediaAction, url: string): Promise<number> {\n try {\n const r = await run('yantra-audio-editing', 'YANTRA_AUDIO_EDIT_PROBE', { input_url: url });\n const root = (r.data && typeof r.data === 'object' ? r.data : r) as Record<string, unknown>;\n const secs = Number(root.duration_secs ?? root.duration);\n return Number.isFinite(secs) && secs > 0 ? secs : 0;\n } catch {\n return 0;\n }\n}\n\n/**\n * Run the whole re-voice for one clip. Returns the cues in its window and\n * the takes that landed; a failed line is skipped (its index in `failed`).\n */\nexport async function revoiceClip(\n run: RunMediaAction,\n clip: EditorClip,\n voice: string,\n onProgress?: (p: RevoiceProgress) => void,\n isCancelled?: () => boolean,\n): Promise<{ cues: TranscriptCue[]; takes: RevoiceTake[]; failed: number[] }> {\n onProgress?.({ phase: 'transcribing', done: 0, total: 0 });\n const cues = cuesInWindow(await transcribeMedia(run, clip.src), clip);\n if (!cues.length) throw new Error('No speech was found in this clip.');\n if (!looksEnglish(cues)) throw new Error('English speech only for now - the stock voices are English.');\n const endSec = clip.trimEndSec ?? cues[cues.length - 1].end;\n const takes: RevoiceTake[] = [];\n const failed: number[] = [];\n for (let i = 0; i < cues.length; i += 1) {\n if (isCancelled?.()) break;\n onProgress?.({ phase: 'speaking', done: i, total: cues.length });\n try {\n let url = await speakLine(run, cues[i].text, voice);\n let durationSec = await probeAudioSec(run, url);\n const factor = durationSec > 0 ? fitFactor(durationSec, roomFor(cues, i, endSec)) : 1;\n if (factor > 1) {\n url = resultUrl(\n await run('yantra-audio-editing', 'YANTRA_AUDIO_EDIT_SPEED', { input_url: url, factor }),\n 'SPEED',\n );\n durationSec /= factor;\n }\n takes.push({ index: i, url, durationSec, factor });\n } catch {\n failed.push(i);\n }\n }\n onProgress?.({ phase: 'speaking', done: cues.length, total: cues.length });\n return { cues, takes, failed };\n}\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,34 @@
1
+ import {downloadLinkParams,downloadUrlFromResult}from'../mediaUrls.js';const errorOf = (result, fallback) => typeof result.error === "string" && result.error ? result.error : fallback;
2
+ function uploadUrlFromResult(result) {
3
+ var _a;
4
+ const data = result.data && typeof result.data === "object" ? result.data : result;
5
+ const nested = (_a = data.createUploadLink) != null ? _a : {};
6
+ const url = [nested.uploadUrl, data.uploadUrl].find((v) => typeof v === "string" && v.length > 0);
7
+ return url != null ? url : null;
8
+ }
9
+ async function uploadViaYantraStorage(media, filename, exec, fetchImpl = fetch) {
10
+ const link = await exec("YANTRA_STORAGE_CREATE_UPLOAD_LINK", {
11
+ filename
12
+ });
13
+ const uploadUrl = uploadUrlFromResult(link);
14
+ if (link.successful === false || !uploadUrl) throw new Error(errorOf(link, "yantra-storage returned no upload URL"));
15
+ const put = await fetchImpl(uploadUrl, {
16
+ method: "PUT",
17
+ body: media
18
+ });
19
+ if (!put.ok) throw new Error(`Storage PUT failed (${put.status})`);
20
+ const objectUrl = uploadUrl.split("?")[0];
21
+ const mimeType = media.type || "application/octet-stream";
22
+ await exec("YANTRA_STORAGE_SAVE_UPLOADED_FILE", {
23
+ file: {
24
+ name: filename,
25
+ url: objectUrl,
26
+ mimeType,
27
+ size: media.size
28
+ }
29
+ }).catch(() => void 0);
30
+ const dl = await exec("YANTRA_STORAGE_CREATE_DOWNLOAD_LINK", downloadLinkParams(objectUrl));
31
+ const downloadUrl = downloadUrlFromResult(dl);
32
+ if (dl.successful === false || !downloadUrl) throw new Error(errorOf(dl, "yantra-storage returned no download URL"));
33
+ return downloadUrl;
34
+ }export{uploadUrlFromResult,uploadViaYantraStorage};//# sourceMappingURL=storageUpload.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"storageUpload.js","sources":["../../../../src/features/canvas/videoEditor/storageUpload.ts"],"sourcesContent":["/**\n * Upload through the `yantra-storage` connector - native twin of surface-kit\n * `agentExec.uploadViaYantraStorage`: presigned PUT link -> direct PUT of the\n * bytes to the bucket (never through the agent) -> FileInfo save (so the file\n * shows in the platform's storage; non-fatal) -> long-lived presigned GET link.\n *\n * Transport-free: the connector calls go through `exec`, the PUT through\n * `fetchImpl`, so the flow is testable with fakes.\n */\nimport { downloadLinkParams, downloadUrlFromResult } from '../mediaUrls';\n\nexport type StorageExec = (action: string, params: Record<string, unknown>) => Promise<Record<string, unknown>>;\n\nconst errorOf = (result: Record<string, unknown>, fallback: string): string =>\n typeof result.error === 'string' && result.error ? result.error : fallback;\n\n/** The presigned PUT URL from a CREATE_UPLOAD_LINK answer: enveloped or bare, nested or flat. Pure. */\nexport function uploadUrlFromResult(result: Record<string, unknown>): string | null {\n const data = (result.data && typeof result.data === 'object' ? result.data : result) as Record<string, unknown>;\n const nested = (data.createUploadLink ?? {}) as Record<string, unknown>;\n const url = [nested.uploadUrl, data.uploadUrl].find((v): v is string => typeof v === 'string' && v.length > 0);\n return url ?? null;\n}\n\nexport async function uploadViaYantraStorage(\n media: Blob,\n filename: string,\n exec: StorageExec,\n fetchImpl: typeof fetch = fetch,\n): Promise<string> {\n const link = await exec('YANTRA_STORAGE_CREATE_UPLOAD_LINK', { filename });\n const uploadUrl = uploadUrlFromResult(link);\n if (link.successful === false || !uploadUrl)\n throw new Error(errorOf(link, 'yantra-storage returned no upload URL'));\n\n const put = await fetchImpl(uploadUrl, { method: 'PUT', body: media });\n if (!put.ok) throw new Error(`Storage PUT failed (${put.status})`);\n\n const objectUrl = uploadUrl.split('?')[0];\n const mimeType = media.type || 'application/octet-stream';\n\n // Persist FileInfo so the upload shows in the platform's storage. Non-fatal.\n await exec('YANTRA_STORAGE_SAVE_UPLOADED_FILE', {\n file: { name: filename, url: objectUrl, mimeType, size: media.size },\n }).catch(() => undefined);\n\n // The longest link the signer allows, named by `s3://bucket/key` (see mediaUrls.storageObjectRef).\n const dl = await exec('YANTRA_STORAGE_CREATE_DOWNLOAD_LINK', downloadLinkParams(objectUrl));\n const downloadUrl = downloadUrlFromResult(dl);\n if (dl.successful === false || !downloadUrl)\n throw new Error(errorOf(dl, 'yantra-storage returned no download URL'));\n return downloadUrl;\n}\n"],"names":[],"mappings":"uEAWA,MAAM,OAAA,GAAU,CAAC,MAAA,EAAiC,QAA6B,KAAA,OAAO,MAAO,CAAA,KAAA,KAAU,QAAY,IAAA,MAAA,CAAO,KAAQ,GAAA,MAAA,CAAO,KAAQ,GAAA,QAAA;AAG1I,SAAS,oBAAoB,MAAgD,EAAA;AAdpF,EAAA,IAAA,EAAA;AAeE,EAAM,MAAA,IAAA,GAAQ,OAAO,IAAQ,IAAA,OAAO,OAAO,IAAS,KAAA,QAAA,GAAW,OAAO,IAAO,GAAA,MAAA;AAC7E,EAAA,MAAM,MAAU,GAAA,CAAA,EAAA,GAAA,IAAA,CAAK,gBAAL,KAAA,IAAA,GAAA,EAAA,GAAyB,EAAC;AAC1C,EAAA,MAAM,GAAM,GAAA,CAAC,MAAO,CAAA,SAAA,EAAW,KAAK,SAAS,CAAA,CAAE,IAAK,CAAA,CAAC,MAAmB,OAAO,CAAA,KAAM,QAAY,IAAA,CAAA,CAAE,SAAS,CAAC,CAAA;AAC7G,EAAA,OAAO,GAAO,IAAA,IAAA,GAAA,GAAA,GAAA,IAAA;AAChB;AACA,eAAsB,sBAAuB,CAAA,KAAA,EAAa,QAAkB,EAAA,IAAA,EAAmB,YAA0B,KAAwB,EAAA;AAC/I,EAAM,MAAA,IAAA,GAAO,MAAM,IAAA,CAAK,mCAAqC,EAAA;AAAA,IAC3D;AAAA,GACD,CAAA;AACD,EAAM,MAAA,SAAA,GAAY,oBAAoB,IAAI,CAAA;AAC1C,EAAI,IAAA,IAAA,CAAK,UAAe,KAAA,KAAA,IAAS,CAAC,SAAA,EAAiB,MAAA,IAAI,KAAM,CAAA,OAAA,CAAQ,IAAM,EAAA,uCAAuC,CAAC,CAAA;AACnH,EAAM,MAAA,GAAA,GAAM,MAAM,SAAA,CAAU,SAAW,EAAA;AAAA,IACrC,MAAQ,EAAA,KAAA;AAAA,IACR,IAAM,EAAA;AAAA,GACP,CAAA;AACD,EAAI,IAAA,CAAC,IAAI,EAAI,EAAA,MAAM,IAAI,KAAM,CAAA,CAAA,oBAAA,EAAuB,GAAI,CAAA,MAAM,CAAG,CAAA,CAAA,CAAA;AACjE,EAAA,MAAM,SAAY,GAAA,SAAA,CAAU,KAAM,CAAA,GAAG,EAAE,CAAC,CAAA;AACxC,EAAM,MAAA,QAAA,GAAW,MAAM,IAAQ,IAAA,0BAAA;AAG/B,EAAA,MAAM,KAAK,mCAAqC,EAAA;AAAA,IAC9C,IAAM,EAAA;AAAA,MACJ,IAAM,EAAA,QAAA;AAAA,MACN,GAAK,EAAA,SAAA;AAAA,MACL,QAAA;AAAA,MACA,MAAM,KAAM,CAAA;AAAA;AACd,GACD,CAAA,CAAE,KAAM,CAAA,MAAM,MAAS,CAAA;AAGxB,EAAA,MAAM,KAAK,MAAM,IAAA,CAAK,qCAAuC,EAAA,kBAAA,CAAmB,SAAS,CAAC,CAAA;AAC1F,EAAM,MAAA,WAAA,GAAc,sBAAsB,EAAE,CAAA;AAC5C,EAAI,IAAA,EAAA,CAAG,UAAe,KAAA,KAAA,IAAS,CAAC,WAAA,EAAmB,MAAA,IAAI,KAAM,CAAA,OAAA,CAAQ,EAAI,EAAA,yCAAyC,CAAC,CAAA;AACnH,EAAO,OAAA,WAAA;AACT"}
@@ -0,0 +1,109 @@
1
+ const TEXT_ANIMATION_EFFECTS = [{
2
+ id: "fade",
3
+ label: "Fade"
4
+ }, {
5
+ id: "shift-up",
6
+ label: "Shift up"
7
+ }, {
8
+ id: "shift-down",
9
+ label: "Shift down"
10
+ }, {
11
+ id: "shift-left",
12
+ label: "Shift left"
13
+ }, {
14
+ id: "shift-right",
15
+ label: "Shift right"
16
+ }, {
17
+ id: "slide-up",
18
+ label: "Slide up"
19
+ }, {
20
+ id: "slide-down",
21
+ label: "Slide down"
22
+ }, {
23
+ id: "slide-left",
24
+ label: "Slide left"
25
+ }, {
26
+ id: "slide-right",
27
+ label: "Slide right"
28
+ }, {
29
+ id: "zoom-in",
30
+ label: "Zoom in"
31
+ }, {
32
+ id: "bounce",
33
+ label: "Bounce"
34
+ }];
35
+ const DEFAULT_TEXT_ANIMATION_MS = 500;
36
+ function motionOffset(effect) {
37
+ switch (effect) {
38
+ case "shift-up":
39
+ return {
40
+ dx: 0,
41
+ dy: 0.3
42
+ };
43
+ case "shift-down":
44
+ return {
45
+ dx: 0,
46
+ dy: -0.3
47
+ };
48
+ case "shift-left":
49
+ return {
50
+ dx: 0.3,
51
+ dy: 0
52
+ };
53
+ case "shift-right":
54
+ return {
55
+ dx: -0.3,
56
+ dy: 0
57
+ };
58
+ case "slide-up":
59
+ return {
60
+ dx: 0,
61
+ dy: 1.5
62
+ };
63
+ case "slide-down":
64
+ return {
65
+ dx: 0,
66
+ dy: -1.5
67
+ };
68
+ case "slide-left":
69
+ return {
70
+ dx: 1.5,
71
+ dy: 0
72
+ };
73
+ case "slide-right":
74
+ return {
75
+ dx: -1.5,
76
+ dy: 0
77
+ };
78
+ default:
79
+ return null;
80
+ }
81
+ }
82
+ function exportsAsMotion(anim) {
83
+ return Boolean(anim && anim.durationMs > 0 && motionOffset(anim.effect));
84
+ }
85
+ const f = (n) => (Math.round(n * 1e3) / 1e3).toString();
86
+ function cubedPositive(u) {
87
+ const pos = `((${u})+abs(${u}))/2`;
88
+ return `(${pos})*(${pos})*(${pos})`;
89
+ }
90
+ function textPositionExpr(t, fromSec, toSec) {
91
+ let x = `(w-text_w)*${t.x.toFixed(3)}`;
92
+ let y = `(h-text_h)*${t.y.toFixed(3)}`;
93
+ const span = Math.max(0.05, toSec - fromSec);
94
+ const add = (anim, phase) => {
95
+ if (!anim || !exportsAsMotion(anim)) return;
96
+ const off = motionOffset(anim.effect);
97
+ const d = Math.min(span, anim.durationMs / 1e3);
98
+ const u = phase === "in" ? `(${f(fromSec + d)}-t)/${f(d)}` : `(t-${f(toSec - d)})/${f(d)}`;
99
+ const k = cubedPositive(u);
100
+ if (off.dx) x += `+text_w*${f(off.dx)}*${k}`;
101
+ if (off.dy) y += `+text_h*${f(off.dy)}*${k}`;
102
+ };
103
+ add(t.animationIn, "in");
104
+ add(t.animationOut, "out");
105
+ return {
106
+ x,
107
+ y
108
+ };
109
+ }export{DEFAULT_TEXT_ANIMATION_MS,TEXT_ANIMATION_EFFECTS,exportsAsMotion,motionOffset,textPositionExpr};//# sourceMappingURL=textMotion.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"textMotion.js","sources":["../../../../src/features/canvas/videoEditor/textMotion.ts"],"sourcesContent":["/**\n * Text layer entrance / exit motion (web utils/animation.ts), as data the\n * export can render. The connector's overlay_text takes x/y as ffmpeg\n * expressions evaluated every frame, so Shift and Slide compile into a\n * position that eases from its offset to rest (in) and back out (out).\n * Fade, Zoom and Bounce change opacity or size, which overlay_text cannot\n * carry: they preview on the stage and the export lands them as a cut.\n *\n * Expressions avoid commas (ffmpeg filtergraph separators): max(u, 0) is\n * written (u+abs(u))/2 and the cubic ease as a product.\n */\nimport type { TextAnimation, TextAnimationEffect, TextClip } from './editorModel';\n\nexport const TEXT_ANIMATION_EFFECTS: ReadonlyArray<{ id: TextAnimationEffect; label: string }> = [\n { id: 'fade', label: 'Fade' },\n { id: 'shift-up', label: 'Shift up' },\n { id: 'shift-down', label: 'Shift down' },\n { id: 'shift-left', label: 'Shift left' },\n { id: 'shift-right', label: 'Shift right' },\n { id: 'slide-up', label: 'Slide up' },\n { id: 'slide-down', label: 'Slide down' },\n { id: 'slide-left', label: 'Slide left' },\n { id: 'slide-right', label: 'Slide right' },\n { id: 'zoom-in', label: 'Zoom in' },\n { id: 'bounce', label: 'Bounce' },\n];\n\nexport const DEFAULT_TEXT_ANIMATION_MS = 500;\n\n/** Offset at progress 0, in multiples of the text box (x by text_w, y by text_h). */\nexport function motionOffset(effect: TextAnimationEffect): { dx: number; dy: number } | null {\n switch (effect) {\n case 'shift-up':\n return { dx: 0, dy: 0.3 };\n case 'shift-down':\n return { dx: 0, dy: -0.3 };\n case 'shift-left':\n return { dx: 0.3, dy: 0 };\n case 'shift-right':\n return { dx: -0.3, dy: 0 };\n case 'slide-up':\n return { dx: 0, dy: 1.5 };\n case 'slide-down':\n return { dx: 0, dy: -1.5 };\n case 'slide-left':\n return { dx: 1.5, dy: 0 };\n case 'slide-right':\n return { dx: -1.5, dy: 0 };\n default:\n return null;\n }\n}\n\n/** True when the export can render this effect as motion. */\nexport function exportsAsMotion(anim: TextAnimation | null | undefined): boolean {\n return Boolean(anim && anim.durationMs > 0 && motionOffset(anim.effect));\n}\n\nconst f = (n: number): string => (Math.round(n * 1000) / 1000).toString();\n\n/** `max(u, 0)` cubed, comma-free. */\nfunction cubedPositive(u: string): string {\n const pos = `((${u})+abs(${u}))/2`;\n return `(${pos})*(${pos})*(${pos})`;\n}\n\n/**\n * The x / y expressions for a text drawn over [fromSec, toSec] on the step's\n * clock. Static layers keep the classic centre-anchored expression.\n */\nexport function textPositionExpr(\n t: Pick<TextClip, 'x' | 'y' | 'animationIn' | 'animationOut'>,\n fromSec: number,\n toSec: number,\n): { x: string; y: string } {\n let x = `(w-text_w)*${t.x.toFixed(3)}`;\n let y = `(h-text_h)*${t.y.toFixed(3)}`;\n const span = Math.max(0.05, toSec - fromSec);\n const add = (anim: TextAnimation | null | undefined, phase: 'in' | 'out') => {\n if (!anim || !exportsAsMotion(anim)) return;\n const off = motionOffset(anim.effect)!;\n const d = Math.min(span, anim.durationMs / 1000);\n // in: 1 at fromSec falling to 0 at fromSec+d; out: 0 until toSec-d rising to 1 at toSec.\n const u = phase === 'in' ? `(${f(fromSec + d)}-t)/${f(d)}` : `(t-${f(toSec - d)})/${f(d)}`;\n const k = cubedPositive(u);\n if (off.dx) x += `+text_w*${f(off.dx)}*${k}`;\n if (off.dy) y += `+text_h*${f(off.dy)}*${k}`;\n };\n add(t.animationIn, 'in');\n add(t.animationOut, 'out');\n return { x, y };\n}\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,31 @@
1
+ const TRANSITION_SPEEDS = [{
2
+ id: "fast",
3
+ label: "Fast",
4
+ durationMs: 500
5
+ }, {
6
+ id: "normal",
7
+ label: "Normal",
8
+ durationMs: 1e3
9
+ }, {
10
+ id: "slow",
11
+ label: "Slow",
12
+ durationMs: 2e3
13
+ }];
14
+ const DEFAULT_TRANSITION_MS = 1e3;
15
+ const LABELS = {
16
+ fade: "Fade",
17
+ dissolve: "Dissolve",
18
+ wipeleft: "Wipe left",
19
+ wiperight: "Wipe right",
20
+ slideup: "Slide up",
21
+ slidedown: "Slide down",
22
+ circleopen: "Circle"
23
+ };
24
+ function transitionLabel(effect) {
25
+ var _a;
26
+ return (_a = LABELS[effect]) != null ? _a : effect;
27
+ }
28
+ function transitionSpeedId(durationMs) {
29
+ const ms = durationMs != null ? durationMs : DEFAULT_TRANSITION_MS;
30
+ return TRANSITION_SPEEDS.reduce((best, s) => Math.abs(s.durationMs - ms) < Math.abs(best.durationMs - ms) ? s : best).id;
31
+ }export{DEFAULT_TRANSITION_MS,TRANSITION_SPEEDS,transitionLabel,transitionSpeedId};//# sourceMappingURL=transitions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transitions.js","sources":["../../../../src/features/canvas/videoEditor/transitions.ts"],"sourcesContent":["/**\n * Transition speed grammar (web TransitionMenu): Fast / Normal / Slow mapped\n * onto the xfade duration the export renders.\n */\nexport const TRANSITION_SPEEDS = [\n { id: 'fast', label: 'Fast', durationMs: 500 },\n { id: 'normal', label: 'Normal', durationMs: 1000 },\n { id: 'slow', label: 'Slow', durationMs: 2000 },\n] as const;\n\nexport type TransitionSpeedId = (typeof TRANSITION_SPEEDS)[number]['id'];\n\nexport const DEFAULT_TRANSITION_MS = 1000;\n\nconst LABELS: Record<string, string> = {\n fade: 'Fade',\n dissolve: 'Dissolve',\n wipeleft: 'Wipe left',\n wiperight: 'Wipe right',\n slideup: 'Slide up',\n slidedown: 'Slide down',\n circleopen: 'Circle',\n};\n\nexport function transitionLabel(effect: string): string {\n return LABELS[effect] ?? effect;\n}\n\n/** The speed a duration reads as: the nearest of the three. */\nexport function transitionSpeedId(durationMs: number | undefined): TransitionSpeedId {\n const ms = durationMs ?? DEFAULT_TRANSITION_MS;\n return TRANSITION_SPEEDS.reduce((best, s) =>\n Math.abs(s.durationMs - ms) < Math.abs(best.durationMs - ms) ? s : best,\n ).id;\n}\n\nexport function transitionMs(speed: TransitionSpeedId): number {\n return TRANSITION_SPEEDS.find((s) => s.id === speed)?.durationMs ?? DEFAULT_TRANSITION_MS;\n}\n"],"names":[],"mappings":"AAIO,MAAM,oBAAoB,CAAC;AAAA,EAChC,EAAI,EAAA,MAAA;AAAA,EACJ,KAAO,EAAA,MAAA;AAAA,EACP,UAAY,EAAA;AACd,CAAG,EAAA;AAAA,EACD,EAAI,EAAA,QAAA;AAAA,EACJ,KAAO,EAAA,QAAA;AAAA,EACP,UAAY,EAAA;AACd,CAAG,EAAA;AAAA,EACD,EAAI,EAAA,MAAA;AAAA,EACJ,KAAO,EAAA,MAAA;AAAA,EACP,UAAY,EAAA;AACd,CAAC;AAEM,MAAM,qBAAwB,GAAA;AACrC,MAAM,MAAiC,GAAA;AAAA,EACrC,IAAM,EAAA,MAAA;AAAA,EACN,QAAU,EAAA,UAAA;AAAA,EACV,QAAU,EAAA,WAAA;AAAA,EACV,SAAW,EAAA,YAAA;AAAA,EACX,OAAS,EAAA,UAAA;AAAA,EACT,SAAW,EAAA,YAAA;AAAA,EACX,UAAY,EAAA;AACd,CAAA;AACO,SAAS,gBAAgB,MAAwB,EAAA;AA5BxD,EAAA,IAAA,EAAA;AA6BE,EAAO,OAAA,CAAA,EAAA,GAAA,MAAA,CAAO,MAAM,CAAA,KAAb,IAAkB,GAAA,EAAA,GAAA,MAAA;AAC3B;AAGO,SAAS,kBAAkB,UAAmD,EAAA;AACnF,EAAA,MAAM,KAAK,UAAc,IAAA,IAAA,GAAA,UAAA,GAAA,qBAAA;AACzB,EAAA,OAAO,kBAAkB,MAAO,CAAA,CAAC,MAAM,CAAM,KAAA,IAAA,CAAK,IAAI,CAAE,CAAA,UAAA,GAAa,EAAE,CAAI,GAAA,IAAA,CAAK,IAAI,IAAK,CAAA,UAAA,GAAa,EAAE,CAAI,GAAA,CAAA,GAAI,IAAI,CAAE,CAAA,EAAA;AACxH"}
@@ -1,4 +1,4 @@
1
- import {jsx,jsxs}from'react/jsx-runtime';import {memo,useMemo,useCallback,useState}from'react';import {Pressable,StyleSheet,View,Text,ScrollView,Image}from'react-native';import {MaterialCommunityIcons}from'@expo/vector-icons';import {useNavigation}from'@react-navigation/native';import {templatesOpeningTitle,canvasDesignKindLabel,isTemplatesSurfaceUrl,templatesSurfaceLinkWithOpening,templatesSurfaceUrl}from'common';import {config}from'../../config/env-config.js';import {useChatLinkOpener}from'../links/chatLinkOpener.js';import {openSurfaceInApp}from'../links/openInApp.js';const ACCENT = "#2563eb";
1
+ import {jsx,jsxs}from'react/jsx-runtime';import {memo,useMemo,useCallback,useState}from'react';import {Pressable,StyleSheet,View,Text,ScrollView,Image}from'react-native';import {MaterialCommunityIcons}from'@expo/vector-icons';import {useNavigation}from'@react-navigation/native';import {templatesOpeningTitle,canvasDesignKindLabel,isTemplatesSurfaceUrl,templatesSurfaceLinkWithOpening,templatesSurfaceUrl}from'common';import {config}from'../../config/env-config.js';import {useChatLinkOpener}from'../links/chatLinkOpener.js';import {openDesignNative,openSurfaceInApp}from'../links/openInApp.js';import {designOpeningFromCard}from'../design/surface/designLinks.js';const ACCENT = "#2563eb";
2
2
  const TEMPLATES_SURFACE_SLUG = "templates";
3
3
  function templatesSurfaceLink(surfaceUrlTemplate, opening) {
4
4
  const template = surfaceUrlTemplate == null ? void 0 : surfaceUrlTemplate.trim();
@@ -106,15 +106,20 @@ const TemplatesWidgetCard = memo(function TemplatesWidgetCard2({
106
106
  const colors = palette(isDark);
107
107
  const target = useMemo(() => templatesRowTarget(config.SURFACE_URL_TEMPLATE, opening, link), [opening, link]);
108
108
  const title = templatesOpeningTitle(opening);
109
+ const design = useMemo(() => designOpeningFromCard(opening), [opening]);
109
110
  const open = useCallback(() => {
111
+ if (design) {
112
+ openDesignNative(navigation, design);
113
+ return;
114
+ }
110
115
  if (!target) return;
111
116
  if (target.kind === "reply") openChatLink(target.url);
112
117
  else openSurfaceInApp(navigation, {
113
118
  surface: TEMPLATES_SURFACE_SLUG,
114
119
  url: target.url
115
120
  });
116
- }, [navigation, openChatLink, target]);
117
- if (!target) return null;
121
+ }, [navigation, openChatLink, target, design]);
122
+ if (!target && !design) return null;
118
123
  return /* @__PURE__ */ jsx(Pressable, { onPress: open, accessibilityRole: "button", accessibilityLabel: `Browse ${title.charAt(0).toLowerCase()}${title.slice(1)}`, style: ({
119
124
  pressed
120
125
  }) => [styles.card, {