@adminide-stack/yantra-mobile 12.0.128 → 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 +4 -4
  359. package/lib/features/design/exportDesign.js +0 -133
  360. package/lib/features/design/exportDesign.js.map +0 -1
@@ -1,4 +1,4 @@
1
- import {jsxs,jsx}from'react/jsx-runtime';import React__default,{useMemo,useState,useCallback}from'react';import {Image,View,Text,Linking,StyleSheet,ActivityIndicator,ScrollView,TextInput}from'react-native';import {MaterialCommunityIcons}from'@expo/vector-icons';import {Image as Image$1}from'expo-image';import {generationImageUrl,friendlyMediaError,resultUrl}from'./videoEditor/mediaActions.js';import {markedEditPrompt,editRequest,settleVariants,EDIT_ASPECTS,EDIT_SIZES,VARIANT_COUNTS}from'./aiEdit.js';import {unwrapProxyUrl}from'./videoEditor/remoteMediaClient.js';import {useCanvasTheme,themedStyles}from'./canvasTheme.js';import {Pressable,pressedStyle,RADIUS,SPACE,HIT,TYPE}from'./canvasUi.js';var __defProp = Object.defineProperty;
1
+ import {jsxs,jsx,Fragment}from'react/jsx-runtime';import React__default,{useMemo,useState,useCallback}from'react';import {Image,View,Linking,Text,ScrollView,TextInput,StyleSheet,ActivityIndicator}from'react-native';import {MaterialCommunityIcons}from'@expo/vector-icons';import {Image as Image$1}from'expo-image';import {resultUrl,friendlyMediaError,generationImageUrl}from'./videoEditor/mediaActions.js';import {markedEditPrompt,editRequest,settleVariants,EDIT_ASPECTS,EDIT_SIZES,VARIANT_COUNTS,MARKER_COLOR}from'./aiEdit.js';import {unwrapProxyUrl}from'./videoEditor/remoteMediaClient.js';import {useCanvasTheme,themedStyles}from'./canvasTheme.js';import {Pressable,pressedStyle,RADIUS,SPACE,HIT,TYPE}from'./canvasUi.js';import {SWATCHES,ChoiceRow,SliderRow,ApplyButton,ToggleRow,MediaUrlPicker,NumberField,TextField,SwatchRow}from'./editorControls.js';import {IMAGE_EDIT_ACTIONS,strokesToAnnotateOps,centeredAspectRect,EXPORT_FORMATS,convertParams,COLORSPACE_TARGETS,LOGO_POSITIONS,SHADOW_PRESETS,shadowParams,annotateOp,RESIZE_SUGGESTIONS,CROP_ASPECTS,logoComposeParams}from'./imageEditor/imageEditOps.js';import {ImageMarkup}from'./imageEditor/ImageMarkup.js';var __defProp = Object.defineProperty;
2
2
  var __defProps = Object.defineProperties;
3
3
  var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
4
4
  var __getOwnPropSymbols = Object.getOwnPropertySymbols;
@@ -21,18 +21,58 @@ const HSCROLL = {
21
21
  flexGrow: 0
22
22
  };
23
23
  const FILTER_NAMES = ["grayscale", "sepia", "chrome", "cold", "warm", "vintage", "fade", "posterize", "vivid", "invert"];
24
- const CROP_ASPECTS = [{
25
- label: "1:1",
26
- ratio: 1
24
+ const TABS = [{
25
+ id: "aiedit",
26
+ icon: "marker",
27
+ label: "Mark"
27
28
  }, {
28
- label: "4:3",
29
- ratio: 4 / 3
29
+ id: "filters",
30
+ icon: "blur",
31
+ label: "Filters"
30
32
  }, {
31
- label: "16:9",
32
- ratio: 16 / 9
33
+ id: "adjust",
34
+ icon: "tune-variant",
35
+ label: "Adjust"
33
36
  }, {
34
- label: "9:16",
35
- ratio: 9 / 16
37
+ id: "crop",
38
+ icon: "crop-rotate",
39
+ label: "Crop"
40
+ }, {
41
+ id: "resize",
42
+ icon: "resize",
43
+ label: "Resize"
44
+ }, {
45
+ id: "draw",
46
+ icon: "draw",
47
+ label: "Draw"
48
+ }, {
49
+ id: "redact",
50
+ icon: "eye-off-outline",
51
+ label: "Redact"
52
+ }, {
53
+ id: "effects",
54
+ icon: "creation",
55
+ label: "Effects"
56
+ }, {
57
+ id: "background",
58
+ icon: "image-filter-hdr",
59
+ label: "Backdrop"
60
+ }, {
61
+ id: "brand",
62
+ icon: "watermark",
63
+ label: "Brand"
64
+ }, {
65
+ id: "layers",
66
+ icon: "layers-outline",
67
+ label: "Layers"
68
+ }, {
69
+ id: "levels",
70
+ icon: "chart-bell-curve",
71
+ label: "Levels"
72
+ }, {
73
+ id: "export",
74
+ icon: "file-export-outline",
75
+ label: "Export"
36
76
  }];
37
77
  function ImageEditorExperience({
38
78
  src,
@@ -40,34 +80,140 @@ function ImageEditorExperience({
40
80
  runAction,
41
81
  onClose,
42
82
  onSave,
43
- initialTab
83
+ initialTab,
84
+ libraryItems
44
85
  }) {
45
86
  var _a;
46
87
  const theme = useCanvasTheme();
47
88
  const styles = useMemo(() => makeStyles(theme), [theme]);
48
89
  const [history, setHistory] = useState([src]);
49
90
  const [busy, setBusy] = useState(null);
50
- const [tab, setTab] = useState(initialTab === "aiedit" ? "aiedit" : "filters");
91
+ const [tab, setTab] = useState(initialTab === "transform" ? "crop" : initialTab != null ? initialTab : "filters");
51
92
  const [notice, setNotice] = useState(null);
52
93
  const [adjust, setAdjust] = useState({
53
94
  brightness: 0,
54
95
  contrast: 1,
55
96
  saturation: 1
56
97
  });
98
+ const [natural, setNatural] = useState(null);
99
+ const [resizeBase, setResizeBase] = useState(null);
100
+ const current = history[history.length - 1];
101
+ const edited = history.length > 1;
57
102
  const [editInstruction, setEditInstruction] = useState("");
58
103
  const [editAspect, setEditAspect] = useState("original");
59
104
  const [editSize, setEditSize] = useState("1K");
60
105
  const [variantCount, setVariantCount] = useState(2);
61
106
  const [variants, setVariants] = useState([]);
62
- const [natural, setNatural] = useState(null);
63
- const current = history[history.length - 1];
64
- const edited = history.length > 1;
107
+ const [before, setBefore] = useState(null);
108
+ const [markStrokes, setMarkStrokes] = useState([]);
109
+ const [markSize, setMarkSize] = useState(24);
110
+ const [drawTool, setDrawTool] = useState("pen");
111
+ const [drawColor, setDrawColor] = useState(SWATCHES[0]);
112
+ const [drawSize, setDrawSize] = useState(12);
113
+ const [drawStrokes, setDrawStrokes] = useState([]);
114
+ const [shapes, setShapes] = useState([]);
115
+ const [shapeFill, setShapeFill] = useState(false);
116
+ const [shapeText, setShapeText] = useState("");
117
+ const [cropAspect, setCropAspect] = useState("free");
118
+ const [cropRect, setCropRect] = useState(null);
119
+ const [redact, setRedact] = useState([]);
120
+ const [redactMethod, setRedactMethod] = useState("blur");
121
+ const [redactRadius, setRedactRadius] = useState(12);
122
+ const [redactColor, setRedactColor] = useState("#000000");
123
+ const [size, setSize] = useState({
124
+ w: 0,
125
+ h: 0
126
+ });
127
+ const [fit, setFit] = useState("fill");
128
+ const [lockAspect, setLockAspect] = useState(true);
129
+ const [pad, setPad] = useState({
130
+ w: 0,
131
+ h: 0,
132
+ color: "#000000"
133
+ });
134
+ const [bgUrl, setBgUrl] = useState("");
135
+ const [bgFit, setBgFit] = useState("cover");
136
+ const [wmText, setWmText] = useState("");
137
+ const [wmPosition, setWmPosition] = useState("bottom-right");
138
+ const [wmSize, setWmSize] = useState(24);
139
+ const [wmColor, setWmColor] = useState("#ffffff");
140
+ const [wmOpacity, setWmOpacity] = useState(0.7);
141
+ const [wmPadding, setWmPadding] = useState(10);
142
+ const [logoUrl, setLogoUrl] = useState("");
143
+ const [logoPosition, setLogoPosition] = useState("bottom-right");
144
+ const [logoPercent, setLogoPercent] = useState(20);
145
+ const [logoOpacity, setLogoOpacity] = useState(1);
146
+ const [overlay, setOverlay] = useState({
147
+ url: "",
148
+ x: 0,
149
+ y: 0,
150
+ scale: "",
151
+ opacity: 1
152
+ });
153
+ const [mask, setMask] = useState({
154
+ url: "",
155
+ invert: false
156
+ });
157
+ const [levels, setLevels] = useState({
158
+ inBlack: 0,
159
+ inWhite: 1,
160
+ outBlack: 0,
161
+ outWhite: 1,
162
+ gamma: 1
163
+ });
164
+ const [csTo, setCsTo] = useState("srgb");
165
+ const [csRange, setCsRange] = useState("");
166
+ const [csZscale, setCsZscale] = useState(false);
167
+ const [format, setFormat] = useState("png");
168
+ const [quality, setQuality] = useState(90);
169
+ const images = useMemo(() => (libraryItems != null ? libraryItems : []).filter((item) => item.type === "image" && item.src !== current).map((item) => ({
170
+ id: item.id,
171
+ src: unwrapProxyUrl(item.src),
172
+ label: item.generatedAssetName,
173
+ kind: "image"
174
+ })), [current, libraryItems]);
65
175
  React__default.useEffect(() => {
66
- Image.getSize(current, (w, h) => setNatural({
67
- width: w,
68
- height: h
69
- }), () => setNatural(null));
176
+ Image.getSize(current, (w, h) => {
177
+ setNatural({
178
+ width: w,
179
+ height: h
180
+ });
181
+ setSize((s) => s.w ? s : {
182
+ w,
183
+ h
184
+ });
185
+ setPad((p) => p.w ? p : __spreadProps(__spreadValues({}, p), {
186
+ w,
187
+ h
188
+ }));
189
+ }, () => setNatural(null));
70
190
  }, [current]);
191
+ const op = useCallback(async (kind, input, params) => {
192
+ if (!runAction) throw new Error("Editing needs the host connector - not wired in this host.");
193
+ const action = IMAGE_EDIT_ACTIONS[kind];
194
+ const result = await runAction("yantra-image-editing", action, __spreadValues({
195
+ input_url: unwrapProxyUrl(input)
196
+ }, params));
197
+ return resultUrl(result, action);
198
+ }, [runAction]);
199
+ const runEdit = useCallback((label, fn, opts) => {
200
+ if (!runAction) {
201
+ setNotice("Editing needs the host connector - not wired in this host.");
202
+ return;
203
+ }
204
+ if (busy) return;
205
+ setBusy(label);
206
+ fn().then((url) => {
207
+ var _a2, _b;
208
+ setHistory((h) => [...h, url]);
209
+ setResizeBase((_a2 = opts == null ? void 0 : opts.resizeBase) != null ? _a2 : null);
210
+ setNotice(null);
211
+ (_b = opts == null ? void 0 : opts.after) == null ? void 0 : _b.call(opts);
212
+ }).catch((err) => setNotice(friendlyMediaError(err, "image edit"))).finally(() => setBusy(null));
213
+ }, [busy, runAction]);
214
+ const apply = useCallback((label, kind, params, after) => runEdit(label, () => op(kind, current, params), {
215
+ after
216
+ }), [current, op, runEdit]);
71
217
  const runMarkEdit = useCallback(async () => {
72
218
  if (!runAction) {
73
219
  setNotice("Mark & edit needs the host connector.");
@@ -75,12 +221,16 @@ function ImageEditorExperience({
75
221
  }
76
222
  const ask = editInstruction.trim();
77
223
  if (!ask || busy) return;
78
- setBusy(`Generating ${variantCount} variant${variantCount === 1 ? "" : "s"}`);
224
+ const marked = markStrokes.length > 0;
79
225
  setVariants([]);
80
226
  try {
81
- const prompt = markedEditPrompt(ask, false);
227
+ setBusy(marked ? "Preparing the marked-up picture" : `Generating ${variantCount} variants`);
228
+ const reference = marked ? await op("annotate", current, {
229
+ ops: strokesToAnnotateOps(markStrokes)
230
+ }) : unwrapProxyUrl(current);
231
+ setBusy(`Generating ${variantCount} variant${variantCount === 1 ? "" : "s"}`);
232
+ const prompt = markedEditPrompt(ask, marked);
82
233
  const request = editRequest(editAspect, editSize, natural);
83
- const reference = unwrapProxyUrl(current);
84
234
  const settled = await Promise.allSettled(Array.from({
85
235
  length: variantCount
86
236
  }, async () => {
@@ -90,14 +240,22 @@ function ImageEditorExperience({
90
240
  url: reference
91
241
  }]
92
242
  }, request));
93
- return generationImageUrl(result);
243
+ const url = generationImageUrl(result);
244
+ if (editAspect !== "original" || !natural) return url;
245
+ return op("resize", url, {
246
+ width: natural.width,
247
+ height: natural.height,
248
+ fit: "cover"
249
+ }).catch(() => url);
94
250
  }));
95
251
  const {
96
252
  urls,
97
253
  failed
98
254
  } = settleVariants(settled);
99
255
  if (!urls.length) throw new Error("No variant came back");
256
+ setBefore(current);
100
257
  setVariants(urls);
258
+ setEditInstruction("");
101
259
  if (failed) setNotice(`${failed} variant${failed === 1 ? "" : "s"} failed. The rest are below.`);
102
260
  else setNotice(null);
103
261
  } catch (err) {
@@ -105,59 +263,522 @@ function ImageEditorExperience({
105
263
  } finally {
106
264
  setBusy(null);
107
265
  }
108
- }, [busy, current, editAspect, editInstruction, editSize, natural, runAction, variantCount]);
109
- const apply = useCallback((label, action, params) => {
110
- if (!runAction) {
111
- setNotice("Editing needs the host connector - not wired in this host.");
112
- return;
266
+ }, [busy, current, editAspect, editInstruction, editSize, markStrokes, natural, op, runAction, variantCount]);
267
+ const applyAspectCrop = useCallback((ratio, label) => {
268
+ if (!natural) return setNotice("Could not read the image size for cropping.");
269
+ const r = centeredAspectRect(natural, ratio);
270
+ apply(label, "crop", {
271
+ width: r.width,
272
+ height: r.height,
273
+ x: r.x,
274
+ y: r.y
275
+ });
276
+ }, [apply, natural]);
277
+ const markupMode = busy !== null ? "none" : tab === "aiedit" ? "stroke" : tab === "draw" ? drawTool === "pen" ? "stroke" : "rect" : tab === "crop" && cropAspect === "free" || tab === "redact" ? "rect" : "none";
278
+ const markupStrokes = tab === "aiedit" ? markStrokes : tab === "draw" ? drawStrokes : [];
279
+ const markupBoxes = tab === "crop" && cropRect ? [{
280
+ id: "crop",
281
+ x1: cropRect.x,
282
+ y1: cropRect.y,
283
+ x2: cropRect.x + cropRect.width,
284
+ y2: cropRect.y + cropRect.height,
285
+ kind: "crop",
286
+ color: "#ffffff"
287
+ }] : tab === "redact" ? redact.map((r) => ({
288
+ id: r.id,
289
+ x1: r.x,
290
+ y1: r.y,
291
+ x2: r.x + r.width,
292
+ y2: r.y + r.height,
293
+ kind: "redact",
294
+ color: "#ffffff"
295
+ })) : tab === "draw" ? shapes.map((sh) => ({
296
+ id: sh.id,
297
+ x1: sh.x1,
298
+ y1: sh.y1,
299
+ x2: sh.x2,
300
+ y2: sh.y2,
301
+ kind: sh.kind === "ellipse" ? "ellipse" : sh.kind === "arrow" ? "arrow" : "rect",
302
+ color: sh.color
303
+ })) : [];
304
+ const onStroke = (stroke) => {
305
+ if (tab === "aiedit") setMarkStrokes((list) => [...list, stroke]);
306
+ else setDrawStrokes((list) => [...list, stroke]);
307
+ };
308
+ const onBox = (box, rect) => {
309
+ if (tab === "crop") setCropRect(rect);
310
+ else if (tab === "redact") setRedact((list) => [...list, __spreadProps(__spreadValues({}, rect), {
311
+ id: box.id
312
+ })]);
313
+ else if (tab === "draw" && drawTool !== "pen") setShapes((list) => [...list, __spreadValues({
314
+ id: box.id,
315
+ kind: drawTool,
316
+ x1: box.x1,
317
+ y1: box.y1,
318
+ x2: box.x2,
319
+ y2: box.y2,
320
+ color: drawColor,
321
+ thickness: Math.max(2, Math.round(drawSize / 3)),
322
+ fill: shapeFill
323
+ }, drawTool === "text" ? {
324
+ text: shapeText.trim() || "Text",
325
+ fontSize: Math.max(12, drawSize * 2)
326
+ } : {})]);
327
+ };
328
+ const setWidth = (w) => {
329
+ setSize((s) => ({
330
+ w,
331
+ h: lockAspect && natural ? Math.max(1, Math.round(w * (natural.height / natural.width))) : s.h
332
+ }));
333
+ };
334
+ const setHeight = (h) => {
335
+ setSize((s) => ({
336
+ h,
337
+ w: lockAspect && natural ? Math.max(1, Math.round(h * (natural.width / natural.height))) : s.w
338
+ }));
339
+ };
340
+ const placeLogo = () => {
341
+ const url = logoUrl.trim();
342
+ if (!url || !natural) return;
343
+ runEdit("Placing logo", async () => {
344
+ const aspect = await new Promise((resolve) => Image.getSize(url, (w, h) => resolve(w / Math.max(1, h)), () => resolve(1)));
345
+ return op("compose", current, logoComposeParams({
346
+ logoUrl: unwrapProxyUrl(url),
347
+ logoAspect: aspect,
348
+ natural,
349
+ percent: logoPercent,
350
+ position: logoPosition,
351
+ opacity: logoOpacity
352
+ }));
353
+ });
354
+ };
355
+ const variantOptions = before ? [{
356
+ src: before,
357
+ label: "Before"
358
+ }, ...variants.map((url, i) => ({
359
+ src: url,
360
+ label: `Variant ${i + 1}`
361
+ }))] : [];
362
+ const panel = (() => {
363
+ switch (tab) {
364
+ case "aiedit":
365
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
366
+ /* @__PURE__ */ jsx(Text, { style: styles.aiHint, children: "Scribble over what should change, then say what. Leave the picture unmarked to change all of it." }),
367
+ /* @__PURE__ */ jsx(SliderRow, { label: "Marker size", value: markSize, min: 4, max: 120, onChange: setMarkSize, format: (v) => `${v}px` }),
368
+ /* @__PURE__ */ jsxs(View, { style: styles.countRow, children: [
369
+ /* @__PURE__ */ jsxs(Text, { style: styles.countLabel, children: [
370
+ markStrokes.length,
371
+ " mark",
372
+ markStrokes.length === 1 ? "" : "s"
373
+ ] }),
374
+ /* @__PURE__ */ jsx(Pressable, { onPress: () => setMarkStrokes((m) => m.slice(0, -1)), disabled: !markStrokes.length, hitSlop: 8, children: /* @__PURE__ */ jsx(Text, { style: [styles.linkLabel, !markStrokes.length && styles.disabled], children: "Undo mark" }) }),
375
+ /* @__PURE__ */ jsx(Pressable, { onPress: () => setMarkStrokes([]), disabled: !markStrokes.length, hitSlop: 8, children: /* @__PURE__ */ jsx(Text, { style: [styles.linkLabel, !markStrokes.length && styles.disabled], children: "Clear" }) })
376
+ ] }),
377
+ /* @__PURE__ */ jsx(TextInput, { value: editInstruction, onChangeText: setEditInstruction, placeholder: "Add a top hat and monocle", placeholderTextColor: theme.edInk3, style: styles.aiInput, multiline: true, accessibilityLabel: "What to change" }),
378
+ /* @__PURE__ */ jsxs(View, { style: styles.row, children: [
379
+ EDIT_ASPECTS.map((a) => /* @__PURE__ */ jsx(Pressable, { onPress: () => setEditAspect(a.id), style: [styles.chip, editAspect === a.id && styles.chipOn], children: /* @__PURE__ */ jsx(Text, { style: styles.chipLabel, children: a.label }) }, a.id)),
380
+ EDIT_SIZES.map((s) => /* @__PURE__ */ jsx(Pressable, { onPress: () => setEditSize(s), style: [styles.chip, editSize === s && styles.chipOn], children: /* @__PURE__ */ jsx(Text, { style: styles.chipLabel, children: s }) }, s)),
381
+ VARIANT_COUNTS.map((n) => /* @__PURE__ */ jsx(Pressable, { onPress: () => setVariantCount(n), style: [styles.chip, variantCount === n && styles.chipOn], children: /* @__PURE__ */ jsxs(Text, { style: styles.chipLabel, children: [
382
+ n,
383
+ "\xD7"
384
+ ] }) }, n))
385
+ ] }),
386
+ /* @__PURE__ */ jsx(Pressable, { onPress: () => void runMarkEdit(), disabled: !editInstruction.trim() || Boolean(busy), style: ({
387
+ pressed
388
+ }) => [styles.aiCta, (!editInstruction.trim() || busy) && styles.disabled, pressedStyle(pressed)], children: /* @__PURE__ */ jsx(Text, { style: styles.aiCtaLabel, children: markStrokes.length ? "Edit the marked area" : "Generate variants" }) }),
389
+ variantOptions.length ? /* @__PURE__ */ jsx(ScrollView, { style: HSCROLL, horizontal: true, contentContainerStyle: styles.row, children: variantOptions.map((o) => {
390
+ const showing = o.src === current;
391
+ return /* @__PURE__ */ jsxs(Pressable, { disabled: showing, onPress: () => {
392
+ setHistory((h) => [...h, o.src]);
393
+ setMarkStrokes([]);
394
+ setNotice("Applied. Pick another, or Before to go back.");
395
+ }, accessibilityLabel: `Use ${o.label}`, style: [styles.variantThumb, showing && styles.variantOn], children: [
396
+ /* @__PURE__ */ jsx(Image$1, { source: {
397
+ uri: o.src
398
+ }, style: styles.variantImg, contentFit: "cover" }),
399
+ /* @__PURE__ */ jsx(Text, { style: styles.variantLabel, children: o.label })
400
+ ] }, o.label);
401
+ }) }) : null
402
+ ] });
403
+ case "filters":
404
+ return /* @__PURE__ */ jsx(ScrollView, { style: HSCROLL, horizontal: true, showsHorizontalScrollIndicator: false, contentContainerStyle: styles.row, children: FILTER_NAMES.map((filter) => /* @__PURE__ */ jsx(Pressable, { onPress: () => apply(`Filter ${filter}`, "filter", {
405
+ name: filter
406
+ }), style: ({
407
+ pressed
408
+ }) => [styles.chip, pressedStyle(pressed)], accessibilityRole: "button", children: /* @__PURE__ */ jsx(Text, { style: styles.chipLabel, children: filter }) }, filter)) });
409
+ case "adjust":
410
+ return /* @__PURE__ */ jsxs(View, { children: [
411
+ /* @__PURE__ */ jsx(SliderRow, { label: "Brightness", value: adjust.brightness, min: -1, max: 1, step: 0.01, format: (v) => v.toFixed(2), onChange: (brightness) => setAdjust((a) => __spreadProps(__spreadValues({}, a), {
412
+ brightness
413
+ })) }),
414
+ /* @__PURE__ */ jsx(SliderRow, { label: "Contrast", value: adjust.contrast, min: 0.2, max: 3, step: 0.01, format: (v) => v.toFixed(2), onChange: (contrast) => setAdjust((a) => __spreadProps(__spreadValues({}, a), {
415
+ contrast
416
+ })) }),
417
+ /* @__PURE__ */ jsx(SliderRow, { label: "Saturation", value: adjust.saturation, min: 0, max: 3, step: 0.01, format: (v) => v.toFixed(2), onChange: (saturation) => setAdjust((a) => __spreadProps(__spreadValues({}, a), {
418
+ saturation
419
+ })) }),
420
+ /* @__PURE__ */ jsx(ApplyButton, { label: "Apply adjustments", disabled: Boolean(busy), onPress: () => apply("Adjusting", "finetune", {
421
+ brightness: adjust.brightness,
422
+ contrast: adjust.contrast,
423
+ saturation: adjust.saturation
424
+ }) })
425
+ ] });
426
+ case "crop":
427
+ return /* @__PURE__ */ jsxs(View, { children: [
428
+ /* @__PURE__ */ jsxs(View, { style: styles.row, children: [
429
+ /* @__PURE__ */ jsxs(Pressable, { onPress: () => apply("Rotating", "rotate", {
430
+ degrees: 90
431
+ }), style: ({
432
+ pressed
433
+ }) => [styles.chip, pressedStyle(pressed)], accessibilityLabel: "Rotate right", children: [
434
+ /* @__PURE__ */ jsx(MaterialCommunityIcons, { name: "rotate-right", size: 14, color: theme.edInk }),
435
+ /* @__PURE__ */ jsx(Text, { style: styles.chipLabel, children: "90\xB0" })
436
+ ] }),
437
+ /* @__PURE__ */ jsx(Pressable, { onPress: () => apply("Flipping", "flip", {
438
+ horizontal: true
439
+ }), style: ({
440
+ pressed
441
+ }) => [styles.chip, pressedStyle(pressed)], accessibilityLabel: "Flip horizontal", children: /* @__PURE__ */ jsx(MaterialCommunityIcons, { name: "flip-horizontal", size: 14, color: theme.edInk }) }),
442
+ /* @__PURE__ */ jsx(Pressable, { onPress: () => apply("Flipping", "flip", {
443
+ vertical: true
444
+ }), style: ({
445
+ pressed
446
+ }) => [styles.chip, pressedStyle(pressed)], accessibilityLabel: "Flip vertical", children: /* @__PURE__ */ jsx(MaterialCommunityIcons, { name: "flip-vertical", size: 14, color: theme.edInk }) })
447
+ ] }),
448
+ /* @__PURE__ */ jsx(ChoiceRow, { label: "Crop", options: CROP_ASPECTS.map((a) => ({
449
+ value: a.id,
450
+ label: a.label
451
+ })), value: cropAspect, onChange: (id) => {
452
+ var _a2;
453
+ setCropAspect(id);
454
+ setCropRect(null);
455
+ const ratio = (_a2 = CROP_ASPECTS.find((a) => a.id === id)) == null ? void 0 : _a2.ratio;
456
+ if (ratio) applyAspectCrop(ratio, `Cropping ${id}`);
457
+ } }),
458
+ cropAspect === "free" ? /* @__PURE__ */ jsxs(Fragment, { children: [
459
+ /* @__PURE__ */ jsx(Text, { style: styles.aiHint, children: cropRect ? `${cropRect.width} \xD7 ${cropRect.height} at ${cropRect.x}, ${cropRect.y}` : "Drag a box on the picture to crop to it." }),
460
+ /* @__PURE__ */ jsx(ApplyButton, { label: "Apply crop", disabled: !cropRect || Boolean(busy), onPress: () => cropRect && apply("Cropping", "crop", {
461
+ width: cropRect.width,
462
+ height: cropRect.height,
463
+ x: cropRect.x,
464
+ y: cropRect.y
465
+ }, () => setCropRect(null)) })
466
+ ] }) : null
467
+ ] });
468
+ case "resize":
469
+ return /* @__PURE__ */ jsxs(View, { children: [
470
+ /* @__PURE__ */ jsx(Text, { style: styles.sectionLabel, children: "Suggested sizes" }),
471
+ /* @__PURE__ */ jsx(ScrollView, { style: HSCROLL, horizontal: true, showsHorizontalScrollIndicator: false, contentContainerStyle: styles.row, children: RESIZE_SUGGESTIONS.map((s) => {
472
+ const on = size.w === s.width && size.h === s.height;
473
+ return /* @__PURE__ */ jsxs(Pressable, { onPress: () => {
474
+ setSize({
475
+ w: s.width,
476
+ h: s.height
477
+ });
478
+ setFit("cover");
479
+ }, style: ({
480
+ pressed
481
+ }) => [styles.sizeCard, on && styles.chipOn, pressedStyle(pressed)], children: [
482
+ /* @__PURE__ */ jsx(Text, { style: styles.sizeTitle, numberOfLines: 1, children: s.label }),
483
+ /* @__PURE__ */ jsxs(Text, { style: styles.sizeMeta, children: [
484
+ s.hint,
485
+ " \xB7 ",
486
+ s.width,
487
+ "\xD7",
488
+ s.height
489
+ ] })
490
+ ] }, `${s.width}x${s.height}`);
491
+ }) }),
492
+ /* @__PURE__ */ jsxs(View, { style: styles.fieldRow, children: [
493
+ /* @__PURE__ */ jsx(NumberField, { label: "Width", value: size.w, onChange: (v) => setWidth(Math.max(1, Math.round(v))) }),
494
+ /* @__PURE__ */ jsx(NumberField, { label: "Height", value: size.h, onChange: (v) => setHeight(Math.max(1, Math.round(v))) })
495
+ ] }),
496
+ /* @__PURE__ */ jsx(ToggleRow, { label: "Lock aspect ratio", value: lockAspect, onChange: setLockAspect }),
497
+ /* @__PURE__ */ jsx(ChoiceRow, { label: "Fit", options: [{
498
+ value: "fill",
499
+ label: "Stretch"
500
+ }, {
501
+ value: "contain",
502
+ label: "Contain"
503
+ }, {
504
+ value: "cover",
505
+ label: "Cover"
506
+ }], value: fit, onChange: setFit }),
507
+ /* @__PURE__ */ jsx(ApplyButton, { label: "Resize", disabled: Boolean(busy) || size.w < 1 || size.h < 1, onPress: () => {
508
+ const base = resizeBase != null ? resizeBase : current;
509
+ runEdit("Resizing", () => op("resize", base, {
510
+ width: size.w,
511
+ height: size.h,
512
+ fit
513
+ }), {
514
+ resizeBase: base
515
+ });
516
+ } }),
517
+ /* @__PURE__ */ jsx(Text, { style: styles.sectionLabel, children: "Pad" }),
518
+ /* @__PURE__ */ jsxs(View, { style: styles.fieldRow, children: [
519
+ /* @__PURE__ */ jsx(NumberField, { label: "Pad width", value: pad.w, onChange: (v) => setPad((p) => __spreadProps(__spreadValues({}, p), {
520
+ w: Math.round(v)
521
+ })) }),
522
+ /* @__PURE__ */ jsx(NumberField, { label: "Pad height", value: pad.h, onChange: (v) => setPad((p) => __spreadProps(__spreadValues({}, p), {
523
+ h: Math.round(v)
524
+ })) })
525
+ ] }),
526
+ /* @__PURE__ */ jsx(SwatchRow, { label: "Pad colour", colors: SWATCHES, value: pad.color, onChange: (color) => setPad((p) => __spreadProps(__spreadValues({}, p), {
527
+ color
528
+ })) }),
529
+ /* @__PURE__ */ jsx(ApplyButton, { label: "Pad", tone: "soft", disabled: Boolean(busy) || pad.w < 1 || pad.h < 1, onPress: () => apply("Padding", "pad", {
530
+ width: String(pad.w),
531
+ height: String(pad.h),
532
+ color: pad.color
533
+ }) })
534
+ ] });
535
+ case "draw":
536
+ return /* @__PURE__ */ jsxs(View, { children: [
537
+ /* @__PURE__ */ jsx(ChoiceRow, { options: [{
538
+ value: "pen",
539
+ label: "Pen"
540
+ }, {
541
+ value: "box",
542
+ label: "Box"
543
+ }, {
544
+ value: "ellipse",
545
+ label: "Ellipse"
546
+ }, {
547
+ value: "arrow",
548
+ label: "Arrow"
549
+ }, {
550
+ value: "text",
551
+ label: "Text"
552
+ }], value: drawTool, onChange: setDrawTool }),
553
+ /* @__PURE__ */ jsx(SwatchRow, { colors: SWATCHES, value: drawColor, onChange: setDrawColor }),
554
+ /* @__PURE__ */ jsx(SliderRow, { label: drawTool === "text" ? "Text size" : "Brush size", value: drawSize, min: 1, max: 100, onChange: setDrawSize, format: (v) => `${v}px` }),
555
+ drawTool === "box" || drawTool === "ellipse" ? /* @__PURE__ */ jsx(ToggleRow, { label: "Filled", value: shapeFill, onChange: setShapeFill }) : null,
556
+ drawTool === "text" ? /* @__PURE__ */ jsx(TextField, { value: shapeText, onChange: setShapeText, placeholder: "Text, then drag where it goes" }) : null,
557
+ /* @__PURE__ */ jsxs(View, { style: styles.countRow, children: [
558
+ /* @__PURE__ */ jsxs(Text, { style: styles.countLabel, children: [
559
+ drawStrokes.length,
560
+ " stroke",
561
+ drawStrokes.length === 1 ? "" : "s",
562
+ " \xB7 ",
563
+ shapes.length,
564
+ " shape",
565
+ shapes.length === 1 ? "" : "s"
566
+ ] }),
567
+ /* @__PURE__ */ jsx(Pressable, { onPress: () => {
568
+ setDrawStrokes([]);
569
+ setShapes([]);
570
+ }, disabled: !drawStrokes.length && !shapes.length, hitSlop: 8, children: /* @__PURE__ */ jsx(Text, { style: [styles.linkLabel, !drawStrokes.length && !shapes.length && styles.disabled], children: "Clear" }) })
571
+ ] }),
572
+ /* @__PURE__ */ jsx(ApplyButton, { label: "Apply drawing", disabled: Boolean(busy) || !drawStrokes.length && !shapes.length, onPress: () => apply("Drawing", "annotate", {
573
+ ops: [...strokesToAnnotateOps(drawStrokes), ...shapes.map(annotateOp)]
574
+ }, () => {
575
+ setDrawStrokes([]);
576
+ setShapes([]);
577
+ }) })
578
+ ] });
579
+ case "redact":
580
+ return /* @__PURE__ */ jsxs(View, { children: [
581
+ /* @__PURE__ */ jsx(Text, { style: styles.aiHint, children: "Drag on the picture to mark regions to redact." }),
582
+ /* @__PURE__ */ jsx(ChoiceRow, { label: "Method", options: [{
583
+ value: "blur",
584
+ label: "Blur"
585
+ }, {
586
+ value: "pixelate",
587
+ label: "Pixelate"
588
+ }, {
589
+ value: "solid",
590
+ label: "Solid fill"
591
+ }], value: redactMethod, onChange: setRedactMethod }),
592
+ redactMethod === "solid" ? /* @__PURE__ */ jsx(SwatchRow, { label: "Fill colour", colors: SWATCHES, value: redactColor, onChange: setRedactColor }) : /* @__PURE__ */ jsx(SliderRow, { label: redactMethod === "blur" ? "Blur strength" : "Pixel size", value: redactRadius, min: 2, max: 50, onChange: setRedactRadius }),
593
+ /* @__PURE__ */ jsxs(View, { style: styles.countRow, children: [
594
+ /* @__PURE__ */ jsxs(Text, { style: styles.countLabel, children: [
595
+ redact.length,
596
+ " region",
597
+ redact.length === 1 ? "" : "s"
598
+ ] }),
599
+ /* @__PURE__ */ jsx(Pressable, { onPress: () => setRedact((r) => r.slice(0, -1)), disabled: !redact.length, hitSlop: 8, children: /* @__PURE__ */ jsx(Text, { style: [styles.linkLabel, !redact.length && styles.disabled], children: "Undo" }) }),
600
+ /* @__PURE__ */ jsx(Pressable, { onPress: () => setRedact([]), disabled: !redact.length, hitSlop: 8, children: /* @__PURE__ */ jsx(Text, { style: [styles.linkLabel, !redact.length && styles.disabled], children: "Clear" }) })
601
+ ] }),
602
+ /* @__PURE__ */ jsx(ApplyButton, { label: "Redact", disabled: Boolean(busy) || !redact.length, onPress: () => apply("Redacting", "redact", {
603
+ regions: redact.map(({
604
+ x,
605
+ y,
606
+ width,
607
+ height
608
+ }) => ({
609
+ x,
610
+ y,
611
+ width,
612
+ height
613
+ })),
614
+ method: redactMethod,
615
+ radius: redactRadius,
616
+ color: redactColor
617
+ }, () => setRedact([])) })
618
+ ] });
619
+ case "effects":
620
+ return /* @__PURE__ */ jsxs(View, { children: [
621
+ /* @__PURE__ */ jsxs(View, { style: styles.row, children: [
622
+ /* @__PURE__ */ jsx(Pressable, { onPress: () => apply("Vignette", "vignette", {}), style: ({
623
+ pressed
624
+ }) => [styles.chip, pressedStyle(pressed)], children: /* @__PURE__ */ jsx(Text, { style: styles.chipLabel, children: "Vignette" }) }),
625
+ /* @__PURE__ */ jsx(Pressable, { onPress: () => apply("Framing", "frame", {
626
+ thickness: 24,
627
+ color: "white"
628
+ }), style: ({
629
+ pressed
630
+ }) => [styles.chip, pressedStyle(pressed)], children: /* @__PURE__ */ jsx(Text, { style: styles.chipLabel, children: "Frame" }) }),
631
+ /* @__PURE__ */ jsx(Pressable, { onPress: () => apply("Removing background", "remove_background", {}), style: ({
632
+ pressed
633
+ }) => [styles.chip, pressedStyle(pressed)], children: /* @__PURE__ */ jsx(Text, { style: styles.chipLabel, children: "Cut out" }) })
634
+ ] }),
635
+ /* @__PURE__ */ jsx(Text, { style: styles.sectionLabel, children: "Shadow" }),
636
+ /* @__PURE__ */ jsx(View, { style: styles.row, children: SHADOW_PRESETS.map((preset) => /* @__PURE__ */ jsx(Pressable, { onPress: () => apply(`Shadow ${preset.label}`, "drop_shadow", shadowParams(preset.params)), style: ({
637
+ pressed
638
+ }) => [styles.chip, pressedStyle(pressed)], children: /* @__PURE__ */ jsx(Text, { style: styles.chipLabel, children: preset.label }) }, preset.id)) })
639
+ ] });
640
+ case "background":
641
+ return /* @__PURE__ */ jsxs(View, { children: [
642
+ /* @__PURE__ */ jsx(Text, { style: styles.aiHint, children: "Keys the subject out and puts it on a background you choose. Exact and instant, but the light will not match." }),
643
+ /* @__PURE__ */ jsx(MediaUrlPicker, { label: "New background", items: images, value: bgUrl, onChange: setBgUrl }),
644
+ /* @__PURE__ */ jsx(ChoiceRow, { label: "Fit", options: [{
645
+ value: "cover",
646
+ label: "Fill the frame"
647
+ }, {
648
+ value: "contain",
649
+ label: "Fit inside"
650
+ }], value: bgFit, onChange: setBgFit }),
651
+ /* @__PURE__ */ jsx(ApplyButton, { label: "Cut and place", disabled: Boolean(busy) || !bgUrl.trim(), onPress: () => runEdit("Cutting out and placing", async () => {
652
+ const cut = await op("remove_background", current, {});
653
+ return op("compose", bgUrl.trim(), {
654
+ overlay_url: cut,
655
+ x: "0",
656
+ y: "0",
657
+ scale: bgFit === "cover" ? "W:H" : "W:-1",
658
+ opacity: 1
659
+ });
660
+ }) })
661
+ ] });
662
+ case "brand":
663
+ return /* @__PURE__ */ jsxs(View, { children: [
664
+ /* @__PURE__ */ jsx(Text, { style: styles.sectionLabel, children: "Watermark" }),
665
+ /* @__PURE__ */ jsx(TextField, { value: wmText, onChange: setWmText, placeholder: "\xA9 Yantra" }),
666
+ /* @__PURE__ */ jsx(ChoiceRow, { options: LOGO_POSITIONS.map((p) => ({
667
+ value: p,
668
+ label: p.replace("-", " ")
669
+ })), value: wmPosition, onChange: setWmPosition }),
670
+ /* @__PURE__ */ jsx(SliderRow, { label: "Font size", value: wmSize, min: 6, max: 160, onChange: setWmSize }),
671
+ /* @__PURE__ */ jsx(SwatchRow, { colors: SWATCHES, value: wmColor, onChange: setWmColor }),
672
+ /* @__PURE__ */ jsx(SliderRow, { label: "Opacity", value: wmOpacity, min: 0, max: 1, step: 0.05, format: (v) => `${Math.round(v * 100)}%`, onChange: setWmOpacity }),
673
+ /* @__PURE__ */ jsx(SliderRow, { label: "Padding", value: wmPadding, min: 0, max: 120, onChange: setWmPadding }),
674
+ /* @__PURE__ */ jsx(ApplyButton, { label: "Apply watermark", disabled: Boolean(busy) || !wmText.trim(), onPress: () => apply("Watermarking", "watermark", {
675
+ text: wmText,
676
+ position: wmPosition,
677
+ font_size: wmSize,
678
+ font_color: wmColor,
679
+ opacity: wmOpacity,
680
+ padding: wmPadding
681
+ }) }),
682
+ /* @__PURE__ */ jsx(Text, { style: styles.sectionLabel, children: "Logo" }),
683
+ /* @__PURE__ */ jsx(MediaUrlPicker, { items: images, value: logoUrl, onChange: setLogoUrl }),
684
+ /* @__PURE__ */ jsx(ChoiceRow, { options: LOGO_POSITIONS.map((p) => ({
685
+ value: p,
686
+ label: p.replace("-", " ")
687
+ })), value: logoPosition, onChange: setLogoPosition }),
688
+ /* @__PURE__ */ jsx(SliderRow, { label: "Size", value: logoPercent, min: 4, max: 80, format: (v) => `${v}% of width`, onChange: setLogoPercent }),
689
+ /* @__PURE__ */ jsx(SliderRow, { label: "Opacity", value: logoOpacity, min: 0, max: 1, step: 0.05, format: (v) => `${Math.round(v * 100)}%`, onChange: setLogoOpacity }),
690
+ /* @__PURE__ */ jsx(ApplyButton, { label: "Apply logo", tone: "soft", disabled: Boolean(busy) || !logoUrl.trim() || !natural, onPress: placeLogo })
691
+ ] });
692
+ case "layers":
693
+ return /* @__PURE__ */ jsxs(View, { children: [
694
+ /* @__PURE__ */ jsx(Text, { style: styles.sectionLabel, children: "Overlay" }),
695
+ /* @__PURE__ */ jsx(MediaUrlPicker, { items: images, value: overlay.url, onChange: (url) => setOverlay((o) => __spreadProps(__spreadValues({}, o), {
696
+ url
697
+ })) }),
698
+ /* @__PURE__ */ jsxs(View, { style: styles.fieldRow, children: [
699
+ /* @__PURE__ */ jsx(NumberField, { label: "X", value: overlay.x, onChange: (x) => setOverlay((o) => __spreadProps(__spreadValues({}, o), {
700
+ x
701
+ })) }),
702
+ /* @__PURE__ */ jsx(NumberField, { label: "Y", value: overlay.y, onChange: (y) => setOverlay((o) => __spreadProps(__spreadValues({}, o), {
703
+ y
704
+ })) })
705
+ ] }),
706
+ /* @__PURE__ */ jsx(TextField, { label: "Scale (0.5 or 200:-1)", value: overlay.scale, onChange: (scale) => setOverlay((o) => __spreadProps(__spreadValues({}, o), {
707
+ scale
708
+ })), placeholder: "optional" }),
709
+ /* @__PURE__ */ jsx(SliderRow, { label: "Opacity", value: overlay.opacity, min: 0, max: 1, step: 0.05, format: (v) => `${Math.round(v * 100)}%`, onChange: (opacity) => setOverlay((o) => __spreadProps(__spreadValues({}, o), {
710
+ opacity
711
+ })) }),
712
+ /* @__PURE__ */ jsx(ApplyButton, { label: "Compose overlay", disabled: Boolean(busy) || !overlay.url.trim(), onPress: () => apply("Compositing", "compose", __spreadProps(__spreadValues({
713
+ overlay_url: unwrapProxyUrl(overlay.url.trim()),
714
+ x: String(Math.round(overlay.x)),
715
+ y: String(Math.round(overlay.y))
716
+ }, overlay.scale.trim() ? {
717
+ scale: overlay.scale.trim()
718
+ } : {}), {
719
+ opacity: overlay.opacity
720
+ })) }),
721
+ /* @__PURE__ */ jsx(Text, { style: styles.sectionLabel, children: "Mask" }),
722
+ /* @__PURE__ */ jsx(MediaUrlPicker, { items: images, value: mask.url, onChange: (url) => setMask((m) => __spreadProps(__spreadValues({}, m), {
723
+ url
724
+ })), placeholder: "A greyscale mask image" }),
725
+ /* @__PURE__ */ jsx(ToggleRow, { label: "Invert mask", value: mask.invert, onChange: (invert) => setMask((m) => __spreadProps(__spreadValues({}, m), {
726
+ invert
727
+ })) }),
728
+ /* @__PURE__ */ jsx(ApplyButton, { label: "Apply mask", tone: "soft", disabled: Boolean(busy) || !mask.url.trim(), onPress: () => apply("Masking", "mask", {
729
+ mask_url: unwrapProxyUrl(mask.url.trim()),
730
+ invert: mask.invert
731
+ }) })
732
+ ] });
733
+ case "levels":
734
+ return /* @__PURE__ */ jsxs(View, { children: [
735
+ [["inBlack", "Input black", 0, 1], ["inWhite", "Input white", 0, 1], ["outBlack", "Output black", 0, 1], ["outWhite", "Output white", 0, 1], ["gamma", "Gamma", 0.1, 3]].map(([key, label, min, max]) => /* @__PURE__ */ jsx(SliderRow, { label, value: levels[key], min, max, step: 0.01, format: (v) => v.toFixed(2), onChange: (v) => setLevels((l) => __spreadProps(__spreadValues({}, l), {
736
+ [key]: v
737
+ })) }, key)),
738
+ /* @__PURE__ */ jsx(ApplyButton, { label: "Apply levels", disabled: Boolean(busy), onPress: () => apply("Applying levels", "levels", {
739
+ in_black: levels.inBlack,
740
+ in_white: levels.inWhite,
741
+ out_black: levels.outBlack,
742
+ out_white: levels.outWhite,
743
+ gamma: levels.gamma
744
+ }) }),
745
+ /* @__PURE__ */ jsx(Text, { style: styles.sectionLabel, children: "Colorspace" }),
746
+ /* @__PURE__ */ jsx(ChoiceRow, { options: COLORSPACE_TARGETS.map((v) => ({
747
+ value: v,
748
+ label: v
749
+ })), value: csTo, onChange: setCsTo }),
750
+ /* @__PURE__ */ jsx(ChoiceRow, { label: "Range", options: [{
751
+ value: "",
752
+ label: "Auto"
753
+ }, {
754
+ value: "tv",
755
+ label: "Limited (tv)"
756
+ }, {
757
+ value: "pc",
758
+ label: "Full (pc)"
759
+ }], value: csRange, onChange: setCsRange }),
760
+ /* @__PURE__ */ jsx(ToggleRow, { label: "High quality (zscale)", value: csZscale, onChange: setCsZscale }),
761
+ /* @__PURE__ */ jsx(ApplyButton, { label: "Convert colorspace", tone: "soft", disabled: Boolean(busy), onPress: () => apply("Converting colorspace", "colorspace", __spreadProps(__spreadValues({
762
+ to: csTo
763
+ }, csRange ? {
764
+ range: csRange
765
+ } : {}), {
766
+ use_zscale: csZscale
767
+ })) })
768
+ ] });
769
+ case "export":
770
+ default:
771
+ return /* @__PURE__ */ jsxs(View, { children: [
772
+ /* @__PURE__ */ jsx(ChoiceRow, { label: "Format", options: EXPORT_FORMATS.map((v) => ({
773
+ value: v,
774
+ label: v.toUpperCase()
775
+ })), value: format, onChange: setFormat }),
776
+ format !== "png" ? /* @__PURE__ */ jsx(SliderRow, { label: "Quality", value: quality, min: 1, max: 100, onChange: setQuality }) : null,
777
+ /* @__PURE__ */ jsx(ApplyButton, { label: `Convert to ${format.toUpperCase()}`, disabled: Boolean(busy), onPress: () => apply(`Converting to ${format}`, "convert", convertParams(format, quality)) }),
778
+ /* @__PURE__ */ jsx(ApplyButton, { label: "Open current image", tone: "soft", onPress: () => void Linking.openURL(current) })
779
+ ] });
113
780
  }
114
- if (busy) return;
115
- setBusy(label);
116
- runAction("yantra-image-editing", action, __spreadValues({
117
- input_url: current
118
- }, params)).then((result) => {
119
- setHistory((h) => [...h, resultUrl(result, action)]);
120
- setNotice(null);
121
- }).catch((err) => setNotice(friendlyMediaError(err, "image edit"))).finally(() => setBusy(null));
122
- }, [busy, current, runAction]);
123
- const applyCrop = useCallback((ratio, label) => {
124
- if (ratio === null) return;
125
- Image.getSize(current, (w, h) => {
126
- let cw = w;
127
- let ch = Math.round(w / ratio);
128
- if (ch > h) {
129
- ch = h;
130
- cw = Math.round(h * ratio);
131
- }
132
- apply(label, "YANTRA_IMAGE_EDIT_CROP", {
133
- width: cw,
134
- height: ch,
135
- x: Math.round((w - cw) / 2),
136
- y: Math.round((h - ch) / 2)
137
- });
138
- }, () => setNotice("Could not read the image size for cropping."));
139
- }, [apply, current]);
140
- const tabs = useMemo(() => [{
141
- id: "aiedit",
142
- icon: "marker",
143
- label: "Mark"
144
- }, {
145
- id: "filters",
146
- icon: "blur",
147
- label: "Filters"
148
- }, {
149
- id: "adjust",
150
- icon: "tune-variant",
151
- label: "Adjust"
152
- }, {
153
- id: "transform",
154
- icon: "crop-rotate",
155
- label: "Transform"
156
- }, {
157
- id: "effects",
158
- icon: "creation",
159
- label: "Effects"
160
- }], []);
781
+ })();
161
782
  return /* @__PURE__ */ jsxs(View, { style: styles.root, testID: "image-editor", children: [
162
783
  /* @__PURE__ */ jsxs(View, { style: styles.header, children: [
163
784
  /* @__PURE__ */ jsx(Pressable, { onPress: onClose, hitSlop: 10, accessibilityRole: "button", accessibilityLabel: "Close editor", style: ({
@@ -183,6 +804,7 @@ function ImageEditorExperience({
183
804
  /* @__PURE__ */ jsx(Image$1, { source: {
184
805
  uri: current
185
806
  }, style: StyleSheet.absoluteFill, contentFit: "contain", transition: 150 }),
807
+ /* @__PURE__ */ jsx(ImageMarkup, { natural, mode: markupMode, strokes: markupStrokes, strokeColor: tab === "aiedit" ? MARKER_COLOR : drawColor, strokeSize: tab === "aiedit" ? markSize : drawSize, onStroke, boxes: markupBoxes, boxKind: tab === "crop" ? "crop" : tab === "redact" ? "redact" : drawTool === "ellipse" ? "ellipse" : drawTool === "arrow" ? "arrow" : "rect", boxColor: tab === "draw" ? drawColor : "#ffffff", onBox }),
186
808
  busy ? /* @__PURE__ */ jsxs(View, { style: styles.busyVeil, children: [
187
809
  /* @__PURE__ */ jsx(ActivityIndicator, { color: "#F7F7FA" }),
188
810
  /* @__PURE__ */ jsxs(Text, { style: styles.busyLabel, children: [
@@ -190,105 +812,17 @@ function ImageEditorExperience({
190
812
  "\u2026"
191
813
  ] })
192
814
  ] }) : null,
193
- edited && !busy ? /* @__PURE__ */ jsx(View, { style: styles.editedBadge, children: /* @__PURE__ */ jsxs(Text, { style: styles.editedBadgeLabel, children: [
815
+ edited && !busy ? /* @__PURE__ */ jsx(View, { style: styles.editedBadge, pointerEvents: "none", children: /* @__PURE__ */ jsxs(Text, { style: styles.editedBadgeLabel, children: [
194
816
  "edit ",
195
817
  history.length - 1
196
818
  ] }) }) : null
197
819
  ] }),
198
820
  /* @__PURE__ */ jsxs(View, { style: styles.dock, children: [
199
- /* @__PURE__ */ jsxs(View, { style: styles.panel, children: [
200
- /* @__PURE__ */ jsx(Text, { style: styles.sheetTitle, children: (_a = tabs.find((entry) => entry.id === tab)) == null ? void 0 : _a.label }),
201
- tab === "aiedit" ? /* @__PURE__ */ jsxs(ScrollView, { style: {
202
- maxHeight: 220
203
- }, contentContainerStyle: {
204
- paddingBottom: 8
205
- }, children: [
206
- /* @__PURE__ */ jsx(Text, { style: styles.aiHint, children: "Say what should change. Phone Mark & edit sends the whole picture (scribble bake is web/Konva); Original framing keeps the photo's own ratio." }),
207
- /* @__PURE__ */ jsx(TextInput, { value: editInstruction, onChangeText: setEditInstruction, placeholder: "Add a top hat and monocle", placeholderTextColor: theme.edInk3, style: styles.aiInput, multiline: true }),
208
- /* @__PURE__ */ jsxs(View, { style: styles.row, children: [
209
- EDIT_ASPECTS.map((a) => /* @__PURE__ */ jsx(Pressable, { onPress: () => setEditAspect(a.id), style: [styles.chip, editAspect === a.id && styles.chipOn], children: /* @__PURE__ */ jsx(Text, { style: styles.chipLabel, children: a.label }) }, a.id)),
210
- EDIT_SIZES.map((s) => /* @__PURE__ */ jsx(Pressable, { onPress: () => setEditSize(s), style: [styles.chip, editSize === s && styles.chipOn], children: /* @__PURE__ */ jsx(Text, { style: styles.chipLabel, children: s }) }, s)),
211
- VARIANT_COUNTS.map((n) => /* @__PURE__ */ jsx(Pressable, { onPress: () => setVariantCount(n), style: [styles.chip, variantCount === n && styles.chipOn], children: /* @__PURE__ */ jsxs(Text, { style: styles.chipLabel, children: [
212
- n,
213
- "\xD7"
214
- ] }) }, n))
215
- ] }),
216
- /* @__PURE__ */ jsx(Pressable, { onPress: () => void runMarkEdit(), disabled: !editInstruction.trim() || Boolean(busy), style: ({
217
- pressed
218
- }) => [styles.aiCta, (!editInstruction.trim() || busy) && styles.disabled, pressedStyle(pressed)], children: /* @__PURE__ */ jsx(Text, { style: styles.aiCtaLabel, children: "Generate variants" }) }),
219
- variants.length ? /* @__PURE__ */ jsx(ScrollView, { style: HSCROLL, horizontal: true, contentContainerStyle: styles.row, children: variants.map((url) => /* @__PURE__ */ jsx(Pressable, { onPress: () => {
220
- setHistory((h) => [...h, url]);
221
- setVariants([]);
222
- setNotice("Applied. Undo brings the original back.");
223
- }, style: styles.variantThumb, children: /* @__PURE__ */ jsx(Image$1, { source: {
224
- uri: url
225
- }, style: styles.variantImg, contentFit: "cover" }) }, url)) }) : null
226
- ] }) : tab === "filters" ? /* @__PURE__ */ jsx(ScrollView, { style: HSCROLL, horizontal: true, showsHorizontalScrollIndicator: false, contentContainerStyle: styles.row, children: FILTER_NAMES.map((filter) => /* @__PURE__ */ jsx(Pressable, { onPress: () => apply(`Filter ${filter}`, "YANTRA_IMAGE_EDIT_FILTER", {
227
- name: filter
228
- }), style: ({
229
- pressed
230
- }) => [styles.chip, pressedStyle(pressed)], accessibilityRole: "button", children: /* @__PURE__ */ jsx(Text, { style: styles.chipLabel, children: filter }) }, filter)) }) : tab === "adjust" ? /* @__PURE__ */ jsxs(View, { children: [
231
- /* @__PURE__ */ jsx(AdjustRow, { label: "Brightness", value: adjust.brightness, format: (v) => v.toFixed(2), onChange: (d) => setAdjust((a) => __spreadProps(__spreadValues({}, a), {
232
- brightness: Math.min(1, Math.max(-1, a.brightness + d * 0.1))
233
- })) }),
234
- /* @__PURE__ */ jsx(AdjustRow, { label: "Contrast", value: adjust.contrast, format: (v) => v.toFixed(2), onChange: (d) => setAdjust((a) => __spreadProps(__spreadValues({}, a), {
235
- contrast: Math.min(3, Math.max(0.2, a.contrast + d * 0.1))
236
- })) }),
237
- /* @__PURE__ */ jsx(AdjustRow, { label: "Saturation", value: adjust.saturation, format: (v) => v.toFixed(2), onChange: (d) => setAdjust((a) => __spreadProps(__spreadValues({}, a), {
238
- saturation: Math.min(3, Math.max(0, a.saturation + d * 0.1))
239
- })) }),
240
- /* @__PURE__ */ jsx(Pressable, { onPress: () => apply("Adjusting", "YANTRA_IMAGE_EDIT_FINETUNE", {
241
- brightness: adjust.brightness,
242
- contrast: adjust.contrast,
243
- saturation: adjust.saturation
244
- }), style: ({
245
- pressed
246
- }) => [styles.chip, styles.chipAccent, styles.applyBtn, pressedStyle(pressed)], accessibilityRole: "button", children: /* @__PURE__ */ jsx(Text, { style: [styles.chipLabel, styles.chipLabelDark], children: "Apply adjustments" }) })
247
- ] }) : tab === "transform" ? /* @__PURE__ */ jsxs(View, { style: styles.row, children: [
248
- /* @__PURE__ */ jsxs(Pressable, { onPress: () => apply("Rotating", "YANTRA_IMAGE_EDIT_ROTATE", {
249
- degrees: 90
250
- }), style: ({
251
- pressed
252
- }) => [styles.chip, pressedStyle(pressed)], accessibilityRole: "button", children: [
253
- /* @__PURE__ */ jsx(MaterialCommunityIcons, { name: "rotate-right", size: 14, color: theme.edInk }),
254
- /* @__PURE__ */ jsx(Text, { style: styles.chipLabel, children: "90\xB0" })
255
- ] }),
256
- /* @__PURE__ */ jsx(Pressable, { onPress: () => apply("Flipping", "YANTRA_IMAGE_EDIT_FLIP", {
257
- horizontal: true
258
- }), style: ({
259
- pressed
260
- }) => [styles.chip, pressedStyle(pressed)], accessibilityRole: "button", children: /* @__PURE__ */ jsx(MaterialCommunityIcons, { name: "flip-horizontal", size: 14, color: theme.edInk }) }),
261
- /* @__PURE__ */ jsx(Pressable, { onPress: () => apply("Flipping", "YANTRA_IMAGE_EDIT_FLIP", {
262
- vertical: true
263
- }), style: ({
264
- pressed
265
- }) => [styles.chip, pressedStyle(pressed)], accessibilityRole: "button", children: /* @__PURE__ */ jsx(MaterialCommunityIcons, { name: "flip-vertical", size: 14, color: theme.edInk }) }),
266
- CROP_ASPECTS.map((aspect) => /* @__PURE__ */ jsx(Pressable, { onPress: () => applyCrop(aspect.ratio, `Cropping ${aspect.label}`), style: ({
267
- pressed
268
- }) => [styles.chip, pressedStyle(pressed)], accessibilityRole: "button", children: /* @__PURE__ */ jsx(Text, { style: styles.chipLabel, children: aspect.label }) }, aspect.label))
269
- ] }) : /* @__PURE__ */ jsxs(View, { style: styles.row, children: [
270
- /* @__PURE__ */ jsx(Pressable, { onPress: () => apply("Vignette", "YANTRA_IMAGE_EDIT_VIGNETTE", {}), style: ({
271
- pressed
272
- }) => [styles.chip, pressedStyle(pressed)], accessibilityRole: "button", children: /* @__PURE__ */ jsx(Text, { style: styles.chipLabel, children: "Vignette" }) }),
273
- /* @__PURE__ */ jsx(Pressable, { onPress: () => apply("Framing", "YANTRA_IMAGE_EDIT_FRAME", {
274
- thickness: 24,
275
- color: "white"
276
- }), style: ({
277
- pressed
278
- }) => [styles.chip, pressedStyle(pressed)], accessibilityRole: "button", children: /* @__PURE__ */ jsx(Text, { style: styles.chipLabel, children: "Frame" }) }),
279
- /* @__PURE__ */ jsx(Pressable, { onPress: () => apply("Shadow", "YANTRA_IMAGE_EDIT_DROP_SHADOW", {
280
- offset_x: 12,
281
- offset_y: 12,
282
- blur: 18
283
- }), style: ({
284
- pressed
285
- }) => [styles.chip, pressedStyle(pressed)], accessibilityRole: "button", children: /* @__PURE__ */ jsx(Text, { style: styles.chipLabel, children: "Shadow" }) }),
286
- /* @__PURE__ */ jsx(Pressable, { onPress: () => apply("Removing background", "YANTRA_IMAGE_EDIT_REMOVE_BACKGROUND", {}), style: ({
287
- pressed
288
- }) => [styles.chip, pressedStyle(pressed)], accessibilityRole: "button", children: /* @__PURE__ */ jsx(Text, { style: styles.chipLabel, children: "Cut out" }) })
289
- ] })
821
+ /* @__PURE__ */ jsxs(ScrollView, { style: styles.panelScroll, contentContainerStyle: styles.panel, keyboardShouldPersistTaps: "handled", children: [
822
+ /* @__PURE__ */ jsx(Text, { style: styles.sheetTitle, children: (_a = TABS.find((entry) => entry.id === tab)) == null ? void 0 : _a.label }),
823
+ panel
290
824
  ] }),
291
- /* @__PURE__ */ jsx(View, { style: styles.toolbar, children: tabs.map((entry) => {
825
+ /* @__PURE__ */ jsx(ScrollView, { horizontal: true, style: HSCROLL, showsHorizontalScrollIndicator: false, contentContainerStyle: styles.toolbar, children: TABS.map((entry) => {
292
826
  const active = tab === entry.id;
293
827
  return /* @__PURE__ */ jsxs(Pressable, { onPress: () => setTab(entry.id), style: ({
294
828
  pressed
@@ -306,21 +840,6 @@ function ImageEditorExperience({
306
840
  ] }) : null
307
841
  ] });
308
842
  }
309
- function AdjustRow({
310
- label,
311
- value,
312
- format,
313
- onChange
314
- }) {
315
- const theme = useCanvasTheme();
316
- const styles = useMemo(() => makeStyles(theme), [theme]);
317
- return /* @__PURE__ */ jsxs(View, { style: styles.adjustRow, children: [
318
- /* @__PURE__ */ jsx(Text, { style: styles.adjustLabel, children: label }),
319
- /* @__PURE__ */ jsx(Pressable, { onPress: () => onChange(-1), hitSlop: 8, accessibilityRole: "button", accessibilityLabel: `${label} less`, children: /* @__PURE__ */ jsx(MaterialCommunityIcons, { name: "minus", size: 16, color: theme.edInk }) }),
320
- /* @__PURE__ */ jsx(Text, { style: styles.adjustValue, children: format(value) }),
321
- /* @__PURE__ */ jsx(Pressable, { onPress: () => onChange(1), hitSlop: 8, accessibilityRole: "button", accessibilityLabel: `${label} more`, children: /* @__PURE__ */ jsx(MaterialCommunityIcons, { name: "plus", size: 16, color: theme.edInk }) })
322
- ] });
323
- }
324
843
  const makeStyles = themedStyles((theme) => StyleSheet.create({
325
844
  root: {
326
845
  flex: 1,
@@ -437,8 +956,8 @@ const makeStyles = themedStyles((theme) => StyleSheet.create({
437
956
  color: theme.edOnInk
438
957
  }),
439
958
  variantThumb: {
440
- width: 64,
441
- height: 64,
959
+ width: 72,
960
+ height: 72,
442
961
  borderRadius: RADIUS.sm,
443
962
  overflow: "hidden",
444
963
  marginRight: SPACE.sm,
@@ -448,13 +967,70 @@ const makeStyles = themedStyles((theme) => StyleSheet.create({
448
967
  width: "100%",
449
968
  height: "100%"
450
969
  },
970
+ panelScroll: {
971
+ maxHeight: 300
972
+ },
451
973
  panel: {
452
974
  minHeight: 104,
453
- justifyContent: "center",
454
975
  paddingHorizontal: SPACE.lg,
455
976
  paddingTop: SPACE.lg,
456
977
  paddingBottom: SPACE.sm
457
978
  },
979
+ sectionLabel: __spreadProps(__spreadValues({}, TYPE.label), {
980
+ color: theme.edInk,
981
+ marginTop: SPACE.md,
982
+ marginBottom: SPACE.sm
983
+ }),
984
+ countRow: {
985
+ flexDirection: "row",
986
+ alignItems: "center",
987
+ gap: SPACE.lg,
988
+ minHeight: 32,
989
+ marginBottom: SPACE.xs
990
+ },
991
+ countLabel: __spreadProps(__spreadValues({}, TYPE.caption), {
992
+ color: theme.edInk2,
993
+ flex: 1
994
+ }),
995
+ linkLabel: __spreadProps(__spreadValues({}, TYPE.label), {
996
+ color: theme.edInk2
997
+ }),
998
+ fieldRow: {
999
+ flexDirection: "row",
1000
+ gap: SPACE.sm,
1001
+ marginBottom: SPACE.sm
1002
+ },
1003
+ sizeCard: {
1004
+ width: 150,
1005
+ paddingHorizontal: SPACE.md,
1006
+ paddingVertical: SPACE.sm,
1007
+ borderRadius: RADIUS.md,
1008
+ backgroundColor: theme.edRaised,
1009
+ borderWidth: 1,
1010
+ borderColor: "transparent"
1011
+ },
1012
+ sizeTitle: __spreadProps(__spreadValues({}, TYPE.label), {
1013
+ color: theme.edInk
1014
+ }),
1015
+ sizeMeta: __spreadProps(__spreadValues({}, TYPE.caption), {
1016
+ fontWeight: "400",
1017
+ color: theme.edInk3
1018
+ }),
1019
+ variantOn: {
1020
+ borderWidth: 2,
1021
+ borderColor: theme.edAccent
1022
+ },
1023
+ variantLabel: {
1024
+ position: "absolute",
1025
+ left: 0,
1026
+ right: 0,
1027
+ bottom: 0,
1028
+ textAlign: "center",
1029
+ fontSize: 10,
1030
+ lineHeight: 14,
1031
+ color: "#FFFFFF",
1032
+ backgroundColor: "rgba(0,0,0,0.55)"
1033
+ },
458
1034
  row: {
459
1035
  flexDirection: "row",
460
1036
  alignItems: "center",
@@ -505,7 +1081,7 @@ const makeStyles = themedStyles((theme) => StyleSheet.create({
505
1081
  }),
506
1082
  toolbar: {
507
1083
  flexDirection: "row",
508
- justifyContent: "space-around",
1084
+ gap: SPACE.xs,
509
1085
  paddingHorizontal: SPACE.sm,
510
1086
  paddingTop: SPACE.xs,
511
1087
  paddingBottom: SPACE.md