@adminide-stack/yantra-mobile 12.0.121 → 12.0.123-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (175) hide show
  1. package/lib/features/apps/appArt.js +1 -1
  2. package/lib/features/apps/appArt.js.map +1 -1
  3. package/lib/features/apps/mobileAppCatalog.js +15 -11
  4. package/lib/features/apps/mobileAppCatalog.js.map +1 -1
  5. package/lib/features/canvas/CanvasAgentChatPane.js +82 -20
  6. package/lib/features/canvas/CanvasAgentChatPane.js.map +1 -1
  7. package/lib/features/canvas/CanvasBoardsGrid.js +291 -100
  8. package/lib/features/canvas/CanvasBoardsGrid.js.map +1 -1
  9. package/lib/features/canvas/CanvasEditToolsPanel.js +105 -12
  10. package/lib/features/canvas/CanvasEditToolsPanel.js.map +1 -1
  11. package/lib/features/canvas/CanvasExperience.js +266 -68
  12. package/lib/features/canvas/CanvasExperience.js.map +1 -1
  13. package/lib/features/canvas/CanvasGeneratePanel.js +204 -66
  14. package/lib/features/canvas/CanvasGeneratePanel.js.map +1 -1
  15. package/lib/features/canvas/CanvasLibrarySheet.js +31 -13
  16. package/lib/features/canvas/CanvasLibrarySheet.js.map +1 -1
  17. package/lib/features/canvas/CanvasModelPicker.js +176 -0
  18. package/lib/features/canvas/CanvasModelPicker.js.map +1 -0
  19. package/lib/features/canvas/CanvasTasksPanel.js +325 -29
  20. package/lib/features/canvas/CanvasTasksPanel.js.map +1 -1
  21. package/lib/features/canvas/CanvasTemplatesPanel.js +5 -4
  22. package/lib/features/canvas/CanvasTemplatesPanel.js.map +1 -1
  23. package/lib/features/canvas/CanvasToolDock.js +137 -61
  24. package/lib/features/canvas/CanvasToolDock.js.map +1 -1
  25. package/lib/features/canvas/FrameExtractorExperience.js +33 -2
  26. package/lib/features/canvas/FrameExtractorExperience.js.map +1 -1
  27. package/lib/features/canvas/GeneratorReferenceSlots.js +197 -0
  28. package/lib/features/canvas/GeneratorReferenceSlots.js.map +1 -0
  29. package/lib/features/canvas/NativeCanvasViewer.js +89 -11
  30. package/lib/features/canvas/NativeCanvasViewer.js.map +1 -1
  31. package/lib/features/canvas/PromoContextFields.js +55 -2
  32. package/lib/features/canvas/PromoContextFields.js.map +1 -1
  33. package/lib/features/canvas/SetStudioExperience.js +323 -13
  34. package/lib/features/canvas/SetStudioExperience.js.map +1 -1
  35. package/lib/features/canvas/VideoEditExperience.js +1 -53
  36. package/lib/features/canvas/VideoEditExperience.js.map +1 -1
  37. package/lib/features/canvas/VideoEditorExperience.js +697 -506
  38. package/lib/features/canvas/VideoEditorExperience.js.map +1 -1
  39. package/lib/features/canvas/VideoGeneratorExperience.js +22 -5
  40. package/lib/features/canvas/VideoGeneratorExperience.js.map +1 -1
  41. package/lib/features/canvas/canvasAgentChat.js +125 -11
  42. package/lib/features/canvas/canvasAgentChat.js.map +1 -1
  43. package/lib/features/canvas/canvasCore.js +117 -12
  44. package/lib/features/canvas/canvasCore.js.map +1 -1
  45. package/lib/features/canvas/canvasEditOps.js +148 -111
  46. package/lib/features/canvas/canvasEditOps.js.map +1 -1
  47. package/lib/features/canvas/canvasTaskSync.js +235 -0
  48. package/lib/features/canvas/canvasTaskSync.js.map +1 -0
  49. package/lib/features/canvas/canvasTasks.js +98 -11
  50. package/lib/features/canvas/canvasTasks.js.map +1 -1
  51. package/lib/features/canvas/createTiles.js +247 -0
  52. package/lib/features/canvas/createTiles.js.map +1 -0
  53. package/lib/features/canvas/deepLinks.js +83 -0
  54. package/lib/features/canvas/deepLinks.js.map +1 -0
  55. package/lib/features/canvas/frameExtract.js +13 -1
  56. package/lib/features/canvas/frameExtract.js.map +1 -1
  57. package/lib/features/canvas/generationModels.js +36 -8
  58. package/lib/features/canvas/generationModels.js.map +1 -1
  59. package/lib/features/canvas/generatorCommands.js +106 -0
  60. package/lib/features/canvas/generatorCommands.js.map +1 -0
  61. package/lib/features/canvas/generatorReferences.js +82 -0
  62. package/lib/features/canvas/generatorReferences.js.map +1 -0
  63. package/lib/features/canvas/homeWork.js +74 -0
  64. package/lib/features/canvas/homeWork.js.map +1 -0
  65. package/lib/features/canvas/linksRpc.js +130 -0
  66. package/lib/features/canvas/linksRpc.js.map +1 -0
  67. package/lib/features/canvas/mediaRecheck.js +176 -0
  68. package/lib/features/canvas/mediaRecheck.js.map +1 -0
  69. package/lib/features/canvas/mediaUrls.js +258 -0
  70. package/lib/features/canvas/mediaUrls.js.map +1 -0
  71. package/lib/features/canvas/nativeViewerRegistry.js.map +1 -1
  72. package/lib/features/canvas/promoProjectImport.js +80 -13
  73. package/lib/features/canvas/promoProjectImport.js.map +1 -1
  74. package/lib/features/canvas/promoVideo.js +106 -15
  75. package/lib/features/canvas/promoVideo.js.map +1 -1
  76. package/lib/features/canvas/reframe.js +228 -0
  77. package/lib/features/canvas/reframe.js.map +1 -0
  78. package/lib/features/canvas/serverTasks.js +697 -0
  79. package/lib/features/canvas/serverTasks.js.map +1 -0
  80. package/lib/features/canvas/set/SetViewportWebView.js +207 -28
  81. package/lib/features/canvas/set/SetViewportWebView.js.map +1 -1
  82. package/lib/features/canvas/set/agent/prompt.js +66 -0
  83. package/lib/features/canvas/set/agent/prompt.js.map +1 -0
  84. package/lib/features/canvas/set/agent/setOps.js +203 -0
  85. package/lib/features/canvas/set/agent/setOps.js.map +1 -0
  86. package/lib/features/canvas/set/agent/setTurn.js +128 -0
  87. package/lib/features/canvas/set/agent/setTurn.js.map +1 -0
  88. package/lib/features/canvas/set/agent/snapshot.js +43 -0
  89. package/lib/features/canvas/set/agent/snapshot.js.map +1 -0
  90. package/lib/features/canvas/set/agent/tools.js +580 -0
  91. package/lib/features/canvas/set/agent/tools.js.map +1 -0
  92. package/lib/features/canvas/set/setProject.js +43 -4
  93. package/lib/features/canvas/set/setProject.js.map +1 -1
  94. package/lib/features/canvas/set/supplyLibrary.js +397 -0
  95. package/lib/features/canvas/set/supplyLibrary.js.map +1 -0
  96. package/lib/features/canvas/storageLibrary.js +113 -52
  97. package/lib/features/canvas/storageLibrary.js.map +1 -1
  98. package/lib/features/canvas/studioCatalog.js +15 -2
  99. package/lib/features/canvas/studioCatalog.js.map +1 -1
  100. package/lib/features/canvas/studioLooks.js +1 -8
  101. package/lib/features/canvas/studioLooks.js.map +1 -1
  102. package/lib/features/canvas/useBoardMediaRefresh.js +66 -0
  103. package/lib/features/canvas/useBoardMediaRefresh.js.map +1 -0
  104. package/lib/features/canvas/useMediaSource.js +84 -0
  105. package/lib/features/canvas/useMediaSource.js.map +1 -0
  106. package/lib/features/canvas/video3d.js +11 -10
  107. package/lib/features/canvas/video3d.js.map +1 -1
  108. package/lib/features/canvas/videoEditor/BlurBoxOverlay.js +46 -0
  109. package/lib/features/canvas/videoEditor/BlurBoxOverlay.js.map +1 -0
  110. package/lib/features/canvas/videoEditor/ExportTaskCard.js +134 -0
  111. package/lib/features/canvas/videoEditor/ExportTaskCard.js.map +1 -0
  112. package/lib/features/canvas/videoEditor/agent/AgentCutPane.js +45 -7
  113. package/lib/features/canvas/videoEditor/agent/AgentCutPane.js.map +1 -1
  114. package/lib/features/canvas/videoEditor/agent/agentLoop.js +4 -2
  115. package/lib/features/canvas/videoEditor/agent/agentLoop.js.map +1 -1
  116. package/lib/features/canvas/videoEditor/agent/attachments.js +304 -0
  117. package/lib/features/canvas/videoEditor/agent/attachments.js.map +1 -0
  118. package/lib/features/canvas/videoEditor/agent/brainClient.js +3 -2
  119. package/lib/features/canvas/videoEditor/agent/brainClient.js.map +1 -1
  120. package/lib/features/canvas/videoEditor/agent/cutTools.js +207 -7
  121. package/lib/features/canvas/videoEditor/agent/cutTools.js.map +1 -1
  122. package/lib/features/canvas/videoEditor/blurBox.js +34 -0
  123. package/lib/features/canvas/videoEditor/blurBox.js.map +1 -0
  124. package/lib/features/canvas/videoEditor/compileTimeline.js +668 -0
  125. package/lib/features/canvas/videoEditor/compileTimeline.js.map +1 -0
  126. package/lib/features/canvas/videoEditor/editorModel.js +56 -22
  127. package/lib/features/canvas/videoEditor/editorModel.js.map +1 -1
  128. package/lib/features/canvas/videoEditor/exportPipeline.js +77 -0
  129. package/lib/features/canvas/videoEditor/exportPipeline.js.map +1 -0
  130. package/lib/features/canvas/videoEditor/exportRenderer.js +19 -12
  131. package/lib/features/canvas/videoEditor/exportRenderer.js.map +1 -1
  132. package/lib/features/canvas/videoEditor/exportTask.js +216 -0
  133. package/lib/features/canvas/videoEditor/exportTask.js.map +1 -0
  134. package/lib/features/canvas/videoEditor/formWidgets.js +142 -0
  135. package/lib/features/canvas/videoEditor/formWidgets.js.map +1 -0
  136. package/lib/features/canvas/videoEditor/produce/ProduceVideoSheet.js +195 -0
  137. package/lib/features/canvas/videoEditor/produce/ProduceVideoSheet.js.map +1 -0
  138. package/lib/features/canvas/videoEditor/produce/produceScenes.js +158 -0
  139. package/lib/features/canvas/videoEditor/produce/produceScenes.js.map +1 -0
  140. package/lib/features/canvas/videoEditor/remoteMediaClient.js +17 -5
  141. package/lib/features/canvas/videoEditor/remoteMediaClient.js.map +1 -1
  142. package/lib/features/canvas/videoEditor/renderTimeline.js +207 -0
  143. package/lib/features/canvas/videoEditor/renderTimeline.js.map +1 -0
  144. package/lib/features/canvas/videoEditor/renewLinks.js +64 -0
  145. package/lib/features/canvas/videoEditor/renewLinks.js.map +1 -0
  146. package/lib/features/canvas/videoEditor/sceneLayers.js +101 -0
  147. package/lib/features/canvas/videoEditor/sceneLayers.js.map +1 -0
  148. package/lib/features/canvas/videoEditor/tools/ToolsDrawer.js +283 -0
  149. package/lib/features/canvas/videoEditor/tools/ToolsDrawer.js.map +1 -0
  150. package/lib/features/canvas/videoEditor/tools/catalog.js +576 -0
  151. package/lib/features/canvas/videoEditor/tools/catalog.js.map +1 -0
  152. package/lib/features/canvas/videoEditor/videoProjectsStore.js +27 -3
  153. package/lib/features/canvas/videoEditor/videoProjectsStore.js.map +1 -1
  154. package/lib/features/webbuilder/WebBuilderExperience.js +29 -1
  155. package/lib/features/webbuilder/WebBuilderExperience.js.map +1 -1
  156. package/lib/features/webbuilder/buildFragments.js +8 -4
  157. package/lib/features/webbuilder/buildFragments.js.map +1 -1
  158. package/lib/features/webbuilder/codezenHandoff.js +108 -0
  159. package/lib/features/webbuilder/codezenHandoff.js.map +1 -0
  160. package/lib/features/webbuilder/workflow.js.map +1 -1
  161. package/lib/hooks/useChatApi.js +1 -2
  162. package/lib/hooks/useChatApi.js.map +1 -1
  163. package/lib/screens/CanvasBoard/index.js +12 -1
  164. package/lib/screens/CanvasBoard/index.js.map +1 -1
  165. package/lib/screens/Home/HomeScreen.js.map +1 -1
  166. package/lib/screens/Home/components/HomeSuggestions.js +3 -3
  167. package/lib/screens/Home/components/HomeSuggestions.js.map +1 -1
  168. package/lib/screens/WebBuilder/index.js +4 -2
  169. package/lib/screens/WebBuilder/index.js.map +1 -1
  170. package/lib/screens/WebBuilderNative/index.js +29 -2
  171. package/lib/screens/WebBuilderNative/index.js.map +1 -1
  172. package/lib/screens/WebBuilderNative/useWebBuilderHost.js +30 -6
  173. package/lib/screens/WebBuilderNative/useWebBuilderHost.js.map +1 -1
  174. package/package.json +4 -4
  175. /package/lib/assets/apps/{paper2poster.webp → poster.webp} +0 -0
@@ -1 +1 @@
1
- {"version":3,"file":"canvasTasks.js","sources":["../../../src/features/canvas/canvasTasks.ts"],"sourcesContent":["/**\n * Background canvas tasks — native twin of canvas-surface `tasks/taskStore` + `promoTask`.\n * Promo productions outlive the generate sheet; More → Tasks shows progress.\n */\nimport AsyncStorage from '@react-native-async-storage/async-storage';\nimport {\n PRODUCE_STATUS_ACTION,\n PRODUCE_SUBMIT_ACTION,\n PROMO_CONNECTOR,\n PROMO_POLL_EVERY_MS,\n PROMO_POLL_MAX_MS,\n buildPromoRunParams,\n parsePollResult,\n parseSubmitResult,\n type PromoRunOptions,\n type PromoRunResult,\n type PromoSubmitHandle,\n} from './promoVideo';\nimport type { RunMediaAction } from './videoEditor/mediaActions';\n\nexport type TaskState = 'submitting' | 'running' | 'succeeded' | 'failed';\n\nexport interface CanvasTask {\n id: string;\n kind: 'promo';\n title: string;\n brief: string;\n boardId: string;\n state: TaskState;\n createdAt: number;\n startedAt?: number;\n endedAt?: number;\n handle?: PromoSubmitHandle;\n lastLine?: string;\n request: PromoRunOptions;\n result?: PromoRunResult;\n error?: string;\n delivered?: boolean;\n}\n\nconst STORAGE_KEY = 'canvas.tasks.v1';\nconst MAX_FINISHED = 20;\nconst listeners = new Set<() => void>();\nlet tasks: CanvasTask[] = [];\nlet hydrated = false;\nconst pollers = new Map<string, Promise<void>>();\n\nexport const isTerminal = (state: TaskState): boolean => state === 'succeeded' || state === 'failed';\n\nfunction emit() {\n listeners.forEach((l) => l());\n}\n\nfunction persist() {\n void AsyncStorage.setItem(STORAGE_KEY, JSON.stringify(tasks)).catch(() => undefined);\n}\n\nexport function coerceTask(value: unknown): CanvasTask | null {\n if (!value || typeof value !== 'object') return null;\n const t = value as Record<string, unknown>;\n if (typeof t.id !== 'string' || !t.id || t.kind !== 'promo') return null;\n if (typeof t.state !== 'string') return null;\n if (!['submitting', 'running', 'succeeded', 'failed'].includes(t.state)) return null;\n if (!t.request || typeof t.request !== 'object' || typeof t.boardId !== 'string') return null;\n return {\n ...(t as unknown as CanvasTask),\n title: typeof t.title === 'string' ? t.title : 'Marketing video',\n brief: typeof t.brief === 'string' ? t.brief : '',\n createdAt: typeof t.createdAt === 'number' ? t.createdAt : 0,\n };\n}\n\nexport async function hydrateCanvasTasks(): Promise<void> {\n if (hydrated) return;\n hydrated = true;\n try {\n const raw = await AsyncStorage.getItem(STORAGE_KEY);\n if (!raw) return;\n const parsed = JSON.parse(raw);\n tasks = Array.isArray(parsed) ? parsed.map(coerceTask).filter((t): t is CanvasTask => t !== null) : [];\n emit();\n } catch {\n tasks = [];\n }\n}\n\nexport function listCanvasTasks(): CanvasTask[] {\n return tasks;\n}\n\nexport function subscribeCanvasTasks(listener: () => void): () => void {\n listeners.add(listener);\n return () => listeners.delete(listener);\n}\n\nexport function runningTaskCount(): number {\n return tasks.filter((t) => t.state === 'submitting' || t.state === 'running').length;\n}\n\nfunction pruneFinished(list: CanvasTask[]): CanvasTask[] {\n const finished = list.filter((t) => isTerminal(t.state)).sort((a, b) => b.createdAt - a.createdAt);\n const keep = new Set(finished.slice(0, MAX_FINISHED).map((t) => t.id));\n return list.filter((t) => !isTerminal(t.state) || keep.has(t.id));\n}\n\nfunction patchTask(id: string, patch: Partial<CanvasTask>) {\n tasks = pruneFinished(tasks.map((t) => (t.id === id ? { ...t, ...patch } : t)));\n persist();\n emit();\n}\n\nexport function dismissTask(id: string) {\n tasks = tasks.filter((t) => t.id !== id);\n persist();\n emit();\n}\n\nexport function markTaskDelivered(id: string) {\n patchTask(id, { delivered: true });\n}\n\nlet seq = 0;\nconst newId = () => `task-${Date.now().toString(36)}-${(seq++).toString(36)}`;\n\nasync function pollTask(run: RunMediaAction, id: string) {\n const started = Date.now();\n while (Date.now() - started < PROMO_POLL_MAX_MS) {\n const task = tasks.find((t) => t.id === id);\n if (!task?.handle) return;\n try {\n const raw = await run(PROMO_CONNECTOR, PRODUCE_STATUS_ACTION, {\n projectId: task.handle.projectId,\n sandboxId: task.handle.sandboxId,\n });\n const poll = parsePollResult(raw);\n if (poll.state === 'succeeded' && poll.result) {\n patchTask(id, {\n state: 'succeeded',\n endedAt: Date.now(),\n result: poll.result,\n lastLine: poll.progress.at(-1) || 'Done',\n });\n return;\n }\n if (poll.state === 'failed') {\n patchTask(id, {\n state: 'failed',\n endedAt: Date.now(),\n error: poll.error || 'Production failed',\n lastLine: poll.error || 'Failed',\n });\n return;\n }\n patchTask(id, {\n state: 'running',\n lastLine: poll.progress.at(-1) || 'Working…',\n });\n } catch (err: unknown) {\n patchTask(id, {\n lastLine: err instanceof Error ? err.message : 'Poll error — retrying',\n });\n }\n await new Promise((r) => setTimeout(r, PROMO_POLL_EVERY_MS));\n }\n patchTask(id, {\n state: 'failed',\n endedAt: Date.now(),\n error: 'Timed out waiting for the marketing video',\n });\n}\n\n/** Submit promo and poll in the background (does not block the UI). */\nexport async function startPromoTask(\n run: RunMediaAction,\n input: { request: PromoRunOptions; boardId: string; brief: string },\n): Promise<CanvasTask> {\n await hydrateCanvasTasks();\n const id = newId();\n const task: CanvasTask = {\n id,\n kind: 'promo',\n title: 'Marketing video',\n brief: input.brief,\n boardId: input.boardId,\n state: 'submitting',\n createdAt: Date.now(),\n request: input.request,\n lastLine: 'Submitting…',\n };\n tasks = [task, ...tasks];\n persist();\n emit();\n\n try {\n const raw = await run(PROMO_CONNECTOR, PRODUCE_SUBMIT_ACTION, buildPromoRunParams(input.request));\n const handle = parseSubmitResult(raw);\n if (!handle) throw new Error('No production handle returned');\n patchTask(id, {\n state: 'running',\n handle,\n startedAt: Date.now(),\n lastLine: 'Queued',\n });\n if (!pollers.has(id)) {\n const job = pollTask(run, id).finally(() => pollers.delete(id));\n pollers.set(id, job);\n }\n } catch (err: unknown) {\n patchTask(id, {\n state: 'failed',\n endedAt: Date.now(),\n error: err instanceof Error ? err.message : String(err),\n lastLine: 'Submit failed',\n });\n }\n return tasks.find((t) => t.id === id)!;\n}\n\n/** Resume any incomplete tasks after app open. */\nexport function resumePromoTasks(run: RunMediaAction) {\n void hydrateCanvasTasks().then(() => {\n for (const task of tasks) {\n if ((task.state === 'running' || task.state === 'submitting') && task.handle && !pollers.has(task.id)) {\n const job = pollTask(run, task.id).finally(() => pollers.delete(task.id));\n pollers.set(task.id, job);\n }\n }\n });\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"canvasTasks.js","sources":["../../../src/features/canvas/canvasTasks.ts"],"sourcesContent":["/**\n * Background canvas tasks — native twin of canvas-surface `tasks/taskStore` + `promoTask`.\n * Promo productions outlive the generate sheet; More → Tasks shows progress.\n */\nimport AsyncStorage from '@react-native-async-storage/async-storage';\nimport {\n PRODUCE_STATUS_ACTION,\n PRODUCE_SUBMIT_ACTION,\n PROMO_CONNECTOR,\n PROMO_POLL_EVERY_MS,\n buildPromoRunParams,\n promoPollMaxMs,\n promoRunTimeoutMs,\n parsePollResult,\n parseSubmitResult,\n type PromoRunOptions,\n type PromoRunResult,\n type PromoSubmitHandle,\n} from './promoVideo';\nimport type { RunMediaAction } from './videoEditor/mediaActions';\nimport type { RenderHandle, RenderPoll } from './videoEditor/renderTimeline';\n// Cycle by design: exportTask drives tasks through this store's public API.\nimport { resumeExportTasks } from './videoEditor/exportTask';\nimport {\n PROMO_FOLLOW_SLACK_MS,\n awaitAgentVerdict,\n canvasJobKey,\n forgetServerJob,\n jobDeadlineAt,\n lookupRemoteJobId,\n promoVideoFromVerdict,\n registerPromoJob,\n runWithJob,\n serverJobId,\n serverProgressLine,\n} from './serverTasks';\n\nexport type TaskState = 'submitting' | 'running' | 'succeeded' | 'failed';\n\n/**\n * 'promo' - marketing production (PRODUCE_SUBMIT/STATUS): `handle` + `request`.\n * 'export' - the video editor's detached timeline render (videoEditor/exportTask,\n * RENDER_TIMELINE_SUBMIT/STATUS): `render`, `step`, `notice`,\n * `warnings`, `local`, and `result.url` = the finished mp4. Its\n * `request` is a descriptive stub (preset 'export') - never\n * resubmit it as a promo.\n */\nexport type CanvasTaskKind = 'promo' | 'export';\n\nexport interface CanvasTask {\n id: string;\n kind: CanvasTaskKind;\n title: string;\n brief: string;\n boardId: string;\n state: TaskState;\n createdAt: number;\n startedAt?: number;\n endedAt?: number;\n handle?: PromoSubmitHandle;\n lastLine?: string;\n request: PromoRunOptions;\n result?: PromoRunResult;\n error?: string;\n delivered?: boolean;\n /** Past this a task still running has stopped responding (its budget + the follow slack + grace). */\n deadlineAt?: number;\n /** The SUBMIT carried the server job: the agent follows the run and reports to its row (./serverTasks). */\n agentReports?: boolean;\n /** Who gave the terminal state, when it came from the server row. */\n verdictBy?: 'agent' | 'browser' | 'deadline';\n // ── kind 'export' only (optional; promo tasks never carry them) ──\n /** The detached render's handle (sandbox/run ids, output url, projected time, lease). */\n render?: RenderHandle;\n /** Latest render progress from STATUS. */\n step?: RenderPoll['step'];\n /** The connector's word on the render time limit, shown to the person. */\n notice?: string;\n /** Compile warnings (a transition that overlaps footage, ...). */\n warnings?: string[];\n /** Rendering through the in-app client chain (SUBMIT unavailable): dies with the app. */\n local?: boolean;\n}\n\nconst STORAGE_KEY = 'canvas.tasks.v1';\nconst MAX_FINISHED = 20;\nconst listeners = new Set<() => void>();\nlet tasks: CanvasTask[] = [];\nlet hydrated = false;\nconst pollers = new Map<string, Promise<void>>();\n\nexport const isTerminal = (state: TaskState): boolean => state === 'succeeded' || state === 'failed';\n\nfunction emit() {\n listeners.forEach((l) => l());\n}\n\nfunction persist() {\n void AsyncStorage.setItem(STORAGE_KEY, JSON.stringify(tasks)).catch(() => undefined);\n}\n\nexport function coerceTask(value: unknown): CanvasTask | null {\n if (!value || typeof value !== 'object') return null;\n const t = value as Record<string, unknown>;\n if (typeof t.id !== 'string' || !t.id || (t.kind !== 'promo' && t.kind !== 'export')) return null;\n if (typeof t.state !== 'string') return null;\n if (!['submitting', 'running', 'succeeded', 'failed'].includes(t.state)) return null;\n if (!t.request || typeof t.request !== 'object' || typeof t.boardId !== 'string') return null;\n return {\n ...(t as unknown as CanvasTask),\n title: typeof t.title === 'string' ? t.title : t.kind === 'export' ? 'Video export' : 'Marketing video',\n brief: typeof t.brief === 'string' ? t.brief : '',\n createdAt: typeof t.createdAt === 'number' ? t.createdAt : 0,\n };\n}\n\nexport async function hydrateCanvasTasks(): Promise<void> {\n if (hydrated) return;\n hydrated = true;\n try {\n const raw = await AsyncStorage.getItem(STORAGE_KEY);\n if (!raw) return;\n const parsed = JSON.parse(raw);\n tasks = Array.isArray(parsed) ? parsed.map(coerceTask).filter((t): t is CanvasTask => t !== null) : [];\n emit();\n } catch {\n tasks = [];\n }\n}\n\nexport function getCanvasTask(id: string): CanvasTask | undefined {\n return tasks.find((t) => t.id === id);\n}\n\n/** Patch one task (no-op for an unknown id) - used by the export runner. */\nexport function patchCanvasTask(id: string, patch: Partial<CanvasTask>) {\n if (!tasks.some((t) => t.id === id)) return;\n patchTask(id, patch);\n}\n\n/** Register a new task (newest first) - used by the export runner. */\nexport function addCanvasTask(task: CanvasTask) {\n tasks = [task, ...tasks.filter((t) => t.id !== task.id)];\n persist();\n emit();\n}\n\nexport function listCanvasTasks(): CanvasTask[] {\n return tasks;\n}\n\nexport function subscribeCanvasTasks(listener: () => void): () => void {\n listeners.add(listener);\n return () => listeners.delete(listener);\n}\n\nexport function runningTaskCount(): number {\n return tasks.filter((t) => t.state === 'submitting' || t.state === 'running').length;\n}\n\nfunction pruneFinished(list: CanvasTask[]): CanvasTask[] {\n const finished = list.filter((t) => isTerminal(t.state)).sort((a, b) => b.createdAt - a.createdAt);\n const keep = new Set(finished.slice(0, MAX_FINISHED).map((t) => t.id));\n return list.filter((t) => !isTerminal(t.state) || keep.has(t.id));\n}\n\nfunction patchTask(id: string, patch: Partial<CanvasTask>) {\n tasks = pruneFinished(tasks.map((t) => (t.id === id ? { ...t, ...patch } : t)));\n persist();\n emit();\n}\n\nexport function dismissTask(id: string) {\n tasks = tasks.filter((t) => t.id !== id);\n persist();\n emit();\n}\n\nexport function markTaskDelivered(id: string) {\n patchTask(id, { delivered: true });\n}\n\n/** A patch from the task's server row (./canvasTaskSync reconcile). No-op for an unknown id. */\nexport function applyServerPatch(id: string, patch: Partial<CanvasTask>) {\n if (!tasks.some((t) => t.id === id)) return;\n patchTask(id, patch);\n}\n\nlet seq = 0;\nconst newId = () => `task-${Date.now().toString(36)}-${(seq++).toString(36)}`;\n\n/**\n * Wait on the agent's verdict for a run it was handed, instead of polling\n * STATUS beside it (a promo sandbox dies on the first terminal answer, so two\n * pollers race). True when the row settled the task; false to poll as before.\n */\nasync function awaitAgentFor(id: string): Promise<boolean> {\n const task = tasks.find((t) => t.id === id);\n if (!task?.agentReports) return false;\n // After a restart the token is gone (memory only) but the row is not: find it in the listing.\n const remoteId = serverJobId(canvasJobKey(id)) ?? (await lookupRemoteJobId(id).catch(() => undefined));\n if (!remoteId) return false;\n try {\n const verdict = await awaitAgentVerdict(remoteId, {\n submittedAt: task.startedAt ?? task.createdAt,\n deadlineAt: task.deadlineAt ?? Date.now() + promoPollMaxMs(task.request),\n onProgress: (row) => {\n const line = serverProgressLine(row);\n if (line) patchTask(id, { state: 'running', lastLine: line });\n },\n });\n if (!verdict) {\n patchTask(id, { agentReports: false });\n return false;\n }\n const video = verdict.state === 'succeeded' ? promoVideoFromVerdict(verdict) : undefined;\n patchTask(id, {\n ...(video\n ? {\n state: 'succeeded' as const,\n result: {\n url: video.url,\n title: video.title || 'Marketing video',\n projectId: task.handle?.projectId ?? '',\n preset: task.request.preset,\n pipeline: '',\n },\n lastLine: 'Ready',\n }\n : {\n state: 'failed' as const,\n error:\n verdict.error ||\n (verdict.state === 'succeeded'\n ? 'Production finished but returned no video'\n : 'Production failed'),\n }),\n endedAt: verdict.endedAt ?? Date.now(),\n ...(verdict.verdictBy ? { verdictBy: verdict.verdictBy } : {}),\n });\n forgetServerJob(canvasJobKey(id));\n return true;\n } catch (err: unknown) {\n patchTask(id, {\n state: 'failed',\n endedAt: Date.now(),\n error: err instanceof Error ? err.message : String(err),\n });\n return true;\n }\n}\n\nasync function pollTask(run: RunMediaAction, id: string) {\n if (await awaitAgentFor(id)) return;\n const started = Date.now();\n // A studio production runs ~100 min; its wait has to outlast that.\n const request = tasks.find((t) => t.id === id)?.request;\n const pollMax = request ? promoPollMaxMs(request) : promoPollMaxMs({ preset: '' });\n while (Date.now() - started < pollMax) {\n const task = tasks.find((t) => t.id === id);\n if (!task?.handle) return;\n try {\n const raw = await run(PROMO_CONNECTOR, PRODUCE_STATUS_ACTION, {\n projectId: task.handle.projectId,\n sandboxId: task.handle.sandboxId,\n });\n const poll = parsePollResult(raw);\n if (poll.state === 'succeeded' && poll.result) {\n patchTask(id, {\n state: 'succeeded',\n endedAt: Date.now(),\n result: poll.result,\n lastLine: poll.progress.at(-1) || 'Done',\n });\n return;\n }\n if (poll.state === 'failed') {\n patchTask(id, {\n state: 'failed',\n endedAt: Date.now(),\n error: poll.error || 'Production failed',\n lastLine: poll.error || 'Failed',\n });\n return;\n }\n patchTask(id, {\n state: 'running',\n lastLine: poll.progress.at(-1) || 'Working…',\n });\n } catch (err: unknown) {\n patchTask(id, {\n lastLine: err instanceof Error ? err.message : 'Poll error — retrying',\n });\n }\n await new Promise((r) => setTimeout(r, PROMO_POLL_EVERY_MS));\n }\n patchTask(id, {\n state: 'failed',\n endedAt: Date.now(),\n error: 'Timed out waiting for the marketing video',\n });\n}\n\n/** Submit promo and poll in the background (does not block the UI). */\nexport async function startPromoTask(\n run: RunMediaAction,\n input: { request: PromoRunOptions; boardId: string; brief: string },\n): Promise<CanvasTask> {\n await hydrateCanvasTasks();\n const id = newId();\n const createdAt = Date.now();\n const task: CanvasTask = {\n id,\n kind: 'promo',\n title: 'Marketing video',\n brief: input.brief,\n boardId: input.boardId,\n state: 'submitting',\n createdAt,\n // The run's own budget, the follow's slack past it, then the grace.\n deadlineAt: jobDeadlineAt(createdAt, promoRunTimeoutMs(input.request) + PROMO_FOLLOW_SLACK_MS),\n request: input.request,\n lastLine: 'Submitting…',\n };\n tasks = [task, ...tasks];\n persist();\n emit();\n\n try {\n // Recorded before the submit (two seconds at most), so the SUBMIT can hand the agent the job.\n const job = await registerPromoJob(task, () => tasks.some((t) => t.id === id)).catch(() => undefined);\n const { result: raw, handed } = await runWithJob(\n run,\n PROMO_CONNECTOR,\n PRODUCE_SUBMIT_ACTION,\n buildPromoRunParams(input.request),\n job,\n );\n const handle = parseSubmitResult(raw);\n if (!handle) throw new Error('No production handle returned');\n patchTask(id, {\n state: 'running',\n handle,\n startedAt: Date.now(),\n lastLine: 'Queued',\n ...(handed ? { agentReports: true } : {}),\n });\n if (!pollers.has(id)) {\n const job = pollTask(run, id).finally(() => pollers.delete(id));\n pollers.set(id, job);\n }\n } catch (err: unknown) {\n patchTask(id, {\n state: 'failed',\n endedAt: Date.now(),\n error: err instanceof Error ? err.message : String(err),\n lastLine: 'Submit failed',\n });\n }\n return tasks.find((t) => t.id === id)!;\n}\n\n/** Resume any incomplete tasks after app open (promo productions and video exports). */\nexport function resumePromoTasks(run: RunMediaAction) {\n void hydrateCanvasTasks().then(() => {\n resumeExportTasks(run);\n for (const task of tasks) {\n if (task.kind !== 'promo') continue;\n if ((task.state === 'running' || task.state === 'submitting') && task.handle && !pollers.has(task.id)) {\n const job = pollTask(run, task.id).finally(() => pollers.delete(task.id));\n pollers.set(task.id, job);\n }\n }\n });\n}\n"],"names":["job"],"mappings":"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"}
@@ -0,0 +1,247 @@
1
+ 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 design = (kind) => ({
21
+ type: "design",
22
+ kind
23
+ });
24
+ const generate = (mode) => ({
25
+ type: "generate",
26
+ mode
27
+ });
28
+ const studio = (s) => ({
29
+ type: "studio",
30
+ studio: s
31
+ });
32
+ const CREATE_GROUPS = [{
33
+ id: "generate",
34
+ title: "Generate with AI",
35
+ accent: {
36
+ fg: "#b91c1c",
37
+ bg: "rgba(239,68,68,0.10)"
38
+ },
39
+ tiles: [{
40
+ id: "image",
41
+ label: "Image",
42
+ hint: "From a prompt or reference",
43
+ icon: "image-outline",
44
+ action: generate("image")
45
+ }, {
46
+ id: "video",
47
+ label: "Video",
48
+ hint: "From text or an image",
49
+ icon: "video-outline",
50
+ action: generate("video")
51
+ }, {
52
+ id: "audio",
53
+ label: "Music & voice",
54
+ hint: "Music, speech, sound",
55
+ icon: "microphone-outline",
56
+ action: generate("audio")
57
+ }, {
58
+ id: "slides",
59
+ label: "Slides",
60
+ hint: "A presentation from a topic",
61
+ icon: "view-grid-outline",
62
+ action: generate("slides")
63
+ }, {
64
+ id: "clips",
65
+ label: "Short clips",
66
+ hint: "Turn long videos into shorts",
67
+ icon: "movie-open-outline",
68
+ action: generate("clips")
69
+ }, {
70
+ id: "promo",
71
+ label: "Product video",
72
+ hint: "Promote a product with AI",
73
+ icon: "bullhorn-outline",
74
+ action: generate("promo")
75
+ }]
76
+ }, {
77
+ id: "edit",
78
+ title: "Edit & produce",
79
+ accent: {
80
+ fg: "#6d28d9",
81
+ bg: "rgba(139,92,246,0.10)"
82
+ },
83
+ tiles: [{
84
+ id: "video-editor",
85
+ label: "Video editor",
86
+ hint: "Timeline, captions, music",
87
+ icon: "filmstrip",
88
+ action: studio("video")
89
+ }, {
90
+ id: "ai-cut",
91
+ label: "AI cut",
92
+ hint: "Edit footage with a script",
93
+ icon: "movie-open-edit-outline",
94
+ action: studio("ai-cut")
95
+ }, {
96
+ id: "photo-editor",
97
+ label: "Photo editor",
98
+ hint: "Crop, filters, background",
99
+ icon: "tune-variant",
100
+ action: studio("image")
101
+ }, {
102
+ id: "audio-editor",
103
+ label: "Audio editor",
104
+ hint: "Trim, fade, mix",
105
+ icon: "waveform",
106
+ action: studio("audio")
107
+ }, {
108
+ id: "frames",
109
+ label: "Extract frames",
110
+ hint: "Save stills from a video",
111
+ icon: "content-cut",
112
+ action: studio("frames")
113
+ }, {
114
+ id: "influencer",
115
+ label: "AI presenter",
116
+ hint: "Create an on-camera host",
117
+ icon: "account-outline",
118
+ action: studio("influencer")
119
+ }, {
120
+ id: "3d-set",
121
+ label: "3D scene",
122
+ hint: "Arrange a scene, then render",
123
+ icon: "cube-outline",
124
+ action: studio("set")
125
+ }, {
126
+ id: "moodboard",
127
+ label: "Mood board",
128
+ hint: "Build a palette from references",
129
+ icon: "palette-outline",
130
+ action: studio("moodboard")
131
+ }, {
132
+ id: "record",
133
+ label: "Screen recording",
134
+ hint: "Record and polish your screen",
135
+ icon: "record-circle-outline",
136
+ action: studio("record")
137
+ }]
138
+ }, {
139
+ id: "design",
140
+ title: "Design & write",
141
+ accent: {
142
+ fg: "#047857",
143
+ bg: "rgba(16,185,129,0.10)"
144
+ },
145
+ tiles: [
146
+ // Native's design studio has four kinds (design, t-shirt, postcard, carousel);
147
+ // each web category maps to the nearest one or stays hidden.
148
+ {
149
+ id: "presentation",
150
+ label: "Presentation",
151
+ hint: "Blank slides, 16:9",
152
+ icon: "presentation",
153
+ action: null
154
+ },
155
+ {
156
+ id: "social",
157
+ label: "Social post",
158
+ hint: "Instagram, LinkedIn, X",
159
+ icon: "view-grid-outline",
160
+ action: design("design")
161
+ },
162
+ {
163
+ id: "carousel",
164
+ label: "Carousel",
165
+ hint: "Swipeable posts",
166
+ icon: "view-carousel-outline",
167
+ action: design("carousel")
168
+ },
169
+ {
170
+ id: "flyer",
171
+ label: "Flyer",
172
+ hint: "Postcards and print",
173
+ icon: "bullhorn-outline",
174
+ action: design("postcard")
175
+ },
176
+ {
177
+ id: "business-card",
178
+ label: "Business card",
179
+ hint: "Two sides, print-ready",
180
+ icon: "card-account-details-outline",
181
+ action: null
182
+ },
183
+ {
184
+ id: "logo",
185
+ label: "Logo",
186
+ hint: "A square brand mark",
187
+ icon: "shape-outline",
188
+ action: design("design")
189
+ },
190
+ {
191
+ id: "banner",
192
+ label: "Banner",
193
+ hint: "Printed, web, social",
194
+ icon: "flag-outline",
195
+ action: null
196
+ },
197
+ {
198
+ id: "brochure",
199
+ label: "Brochure",
200
+ hint: "Folded, inside and out",
201
+ icon: "book-open-outline",
202
+ action: null
203
+ },
204
+ {
205
+ id: "branding",
206
+ label: "Branding",
207
+ hint: "Letterheads, envelopes",
208
+ icon: "email-outline",
209
+ action: null
210
+ },
211
+ {
212
+ id: "doc",
213
+ label: "Document",
214
+ hint: "Write, format, export",
215
+ icon: "file-document-outline",
216
+ action: null
217
+ },
218
+ {
219
+ id: "custom",
220
+ label: "Custom size",
221
+ hint: "Any width and height",
222
+ icon: "resize",
223
+ action: null
224
+ },
225
+ // Native-only kind (no web tile): the apparel print the studio already ships.
226
+ {
227
+ id: "tshirt",
228
+ label: "T-shirt",
229
+ hint: "Front and back print",
230
+ icon: "tshirt-crew-outline",
231
+ action: design("tshirt")
232
+ }
233
+ ]
234
+ }];
235
+ function createActionFor(id) {
236
+ const key = id.trim().toLowerCase();
237
+ for (const group of CREATE_GROUPS) {
238
+ const tile = group.tiles.find((t) => t.id === key);
239
+ if (tile) return tile.action;
240
+ }
241
+ return null;
242
+ }
243
+ function visibleCreateGroups(canRun = () => true) {
244
+ return CREATE_GROUPS.map((group) => __spreadProps(__spreadValues({}, group), {
245
+ tiles: group.tiles.filter((tile) => tile.action !== null && canRun(tile.action))
246
+ })).filter((group) => group.tiles.length > 0);
247
+ }export{CREATE_GROUPS,createActionFor,visibleCreateGroups};//# sourceMappingURL=createTiles.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createTiles.js","sources":["../../../src/features/canvas/createTiles.ts"],"sourcesContent":["/**\n * Screen one's grouped Create rows - native twin of canvas-surface\n * `components/home/CreateStrip.tsx` (GROUPS + createActionFor).\n *\n * The tile ids are the web's (and the Templates surface's `TEMPLATE_TOOLS`),\n * so a `createTile` deep link names the same tool on both. A tile whose studio\n * native lacks (banner, brochure, docs...) keeps its id with a null action:\n * `createActionFor` answers null for it and the home grid hides it.\n *\n * Pure data: no RN imports, so it runs under jest as-is.\n */\nimport type { DesignKind } from '../design/designCore';\n\nexport type CreateGroupId = 'generate' | 'edit' | 'design';\n\n/** Generator lanes a tile opens (web GeneratorMode; slides/clips route to their native screens). */\nexport type CreateGenerateMode = 'image' | 'video' | 'audio' | 'promo' | 'clips' | 'slides';\n\nexport type CreateStudio =\n | 'video'\n | 'ai-cut'\n | 'image'\n | 'audio'\n | 'frames'\n | 'influencer'\n | 'set'\n | 'moodboard'\n | 'record';\n\nexport type CreateAction =\n | { type: 'design'; kind: DesignKind }\n | { type: 'generate'; mode: CreateGenerateMode }\n | { type: 'studio'; studio: CreateStudio };\n\nexport interface CreateTile {\n id: string;\n label: string;\n hint: string;\n /** MaterialCommunityIcons glyph. */\n icon: string;\n /** Null: the web tile has no native studio yet - hidden on home, ignored by links. */\n action: CreateAction | null;\n}\n\nexport interface CreateGroup {\n id: CreateGroupId;\n title: string;\n /** Icon well + heading accent (web's red / violet / emerald themes). */\n accent: { fg: string; bg: string };\n tiles: CreateTile[];\n}\n\nconst design = (kind: DesignKind): CreateAction => ({ type: 'design', kind });\nconst generate = (mode: CreateGenerateMode): CreateAction => ({ type: 'generate', mode });\nconst studio = (s: CreateStudio): CreateAction => ({ type: 'studio', studio: s });\n\nexport const CREATE_GROUPS: readonly CreateGroup[] = [\n {\n id: 'generate',\n title: 'Generate with AI',\n accent: { fg: '#b91c1c', bg: 'rgba(239,68,68,0.10)' },\n tiles: [\n {\n id: 'image',\n label: 'Image',\n hint: 'From a prompt or reference',\n icon: 'image-outline',\n action: generate('image'),\n },\n {\n id: 'video',\n label: 'Video',\n hint: 'From text or an image',\n icon: 'video-outline',\n action: generate('video'),\n },\n {\n id: 'audio',\n label: 'Music & voice',\n hint: 'Music, speech, sound',\n icon: 'microphone-outline',\n action: generate('audio'),\n },\n {\n id: 'slides',\n label: 'Slides',\n hint: 'A presentation from a topic',\n icon: 'view-grid-outline',\n action: generate('slides'),\n },\n {\n id: 'clips',\n label: 'Short clips',\n hint: 'Turn long videos into shorts',\n icon: 'movie-open-outline',\n action: generate('clips'),\n },\n {\n id: 'promo',\n label: 'Product video',\n hint: 'Promote a product with AI',\n icon: 'bullhorn-outline',\n action: generate('promo'),\n },\n ],\n },\n {\n id: 'edit',\n title: 'Edit & produce',\n accent: { fg: '#6d28d9', bg: 'rgba(139,92,246,0.10)' },\n tiles: [\n {\n id: 'video-editor',\n label: 'Video editor',\n hint: 'Timeline, captions, music',\n icon: 'filmstrip',\n action: studio('video'),\n },\n {\n id: 'ai-cut',\n label: 'AI cut',\n hint: 'Edit footage with a script',\n icon: 'movie-open-edit-outline',\n action: studio('ai-cut'),\n },\n {\n id: 'photo-editor',\n label: 'Photo editor',\n hint: 'Crop, filters, background',\n icon: 'tune-variant',\n action: studio('image'),\n },\n {\n id: 'audio-editor',\n label: 'Audio editor',\n hint: 'Trim, fade, mix',\n icon: 'waveform',\n action: studio('audio'),\n },\n {\n id: 'frames',\n label: 'Extract frames',\n hint: 'Save stills from a video',\n icon: 'content-cut',\n action: studio('frames'),\n },\n {\n id: 'influencer',\n label: 'AI presenter',\n hint: 'Create an on-camera host',\n icon: 'account-outline',\n action: studio('influencer'),\n },\n {\n id: '3d-set',\n label: '3D scene',\n hint: 'Arrange a scene, then render',\n icon: 'cube-outline',\n action: studio('set'),\n },\n {\n id: 'moodboard',\n label: 'Mood board',\n hint: 'Build a palette from references',\n icon: 'palette-outline',\n action: studio('moodboard'),\n },\n {\n id: 'record',\n label: 'Screen recording',\n hint: 'Record and polish your screen',\n icon: 'record-circle-outline',\n action: studio('record'),\n },\n ],\n },\n {\n id: 'design',\n title: 'Design & write',\n accent: { fg: '#047857', bg: 'rgba(16,185,129,0.10)' },\n tiles: [\n // Native's design studio has four kinds (design, t-shirt, postcard, carousel);\n // each web category maps to the nearest one or stays hidden.\n {\n id: 'presentation',\n label: 'Presentation',\n hint: 'Blank slides, 16:9',\n icon: 'presentation',\n action: null,\n },\n {\n id: 'social',\n label: 'Social post',\n hint: 'Instagram, LinkedIn, X',\n icon: 'view-grid-outline',\n action: design('design'),\n },\n {\n id: 'carousel',\n label: 'Carousel',\n hint: 'Swipeable posts',\n icon: 'view-carousel-outline',\n action: design('carousel'),\n },\n {\n id: 'flyer',\n label: 'Flyer',\n hint: 'Postcards and print',\n icon: 'bullhorn-outline',\n action: design('postcard'),\n },\n {\n id: 'business-card',\n label: 'Business card',\n hint: 'Two sides, print-ready',\n icon: 'card-account-details-outline',\n action: null,\n },\n { id: 'logo', label: 'Logo', hint: 'A square brand mark', icon: 'shape-outline', action: design('design') },\n { id: 'banner', label: 'Banner', hint: 'Printed, web, social', icon: 'flag-outline', action: null },\n {\n id: 'brochure',\n label: 'Brochure',\n hint: 'Folded, inside and out',\n icon: 'book-open-outline',\n action: null,\n },\n { id: 'branding', label: 'Branding', hint: 'Letterheads, envelopes', icon: 'email-outline', action: null },\n {\n id: 'doc',\n label: 'Document',\n hint: 'Write, format, export',\n icon: 'file-document-outline',\n action: null,\n },\n { id: 'custom', label: 'Custom size', hint: 'Any width and height', icon: 'resize', action: null },\n // Native-only kind (no web tile): the apparel print the studio already ships.\n {\n id: 'tshirt',\n label: 'T-shirt',\n hint: 'Front and back print',\n icon: 'tshirt-crew-outline',\n action: design('tshirt'),\n },\n ],\n },\n];\n\n/**\n * The action a Create tile runs, by the tile's id (`video-editor`, `clips`,\n * `logo`), or null for an id no tile has - or a tile native cannot run yet.\n */\nexport function createActionFor(id: string): CreateAction | null {\n const key = id.trim().toLowerCase();\n for (const group of CREATE_GROUPS) {\n const tile = group.tiles.find((t) => t.id === key);\n if (tile) return tile.action;\n }\n return null;\n}\n\n/**\n * The groups home shows: tiles with an action this host can run. `canRun`\n * lets the experience drop tiles whose seam is missing (no media picker ->\n * no photo editor). Empty groups drop.\n */\nexport function visibleCreateGroups(\n canRun: (action: CreateAction) => boolean = () => true,\n): Array<CreateGroup & { tiles: Array<CreateTile & { action: CreateAction }> }> {\n return CREATE_GROUPS.map((group) => ({\n ...group,\n tiles: group.tiles.filter(\n (tile): tile is CreateTile & { action: CreateAction } => tile.action !== null && canRun(tile.action),\n ),\n })).filter((group) => group.tiles.length > 0);\n}\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,83 @@
1
+ import {createActionFor}from'./createTiles.js';var __defProp = Object.defineProperty;
2
+ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
3
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
4
+ var __propIsEnum = Object.prototype.propertyIsEnumerable;
5
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
6
+ var __spreadValues = (a, b) => {
7
+ for (var prop in b || (b = {}))
8
+ if (__hasOwnProp.call(b, prop))
9
+ __defNormalProp(a, prop, b[prop]);
10
+ if (__getOwnPropSymbols)
11
+ for (var prop of __getOwnPropSymbols(b)) {
12
+ if (__propIsEnum.call(b, prop))
13
+ __defNormalProp(a, prop, b[prop]);
14
+ }
15
+ return a;
16
+ };
17
+ function parseCreateTileLink(raw) {
18
+ if (typeof raw !== "string") return null;
19
+ const id = raw.trim().toLowerCase();
20
+ return /^[a-z0-9][a-z0-9-]{0,39}$/.test(id) ? createActionFor(id) : null;
21
+ }
22
+ const MAX_URL_LENGTH = 8192;
23
+ const MAX_NAME_LENGTH = 120;
24
+ const IMAGE_EXTENSION = /\.(png|jpe?g|gif|webp|avif|bmp)$/i;
25
+ const VIDEO_EXTENSION = /\.(mp4|m4v|mov|webm)$/i;
26
+ const HTTP_URL = /^(https?):\/\/([^/?#\s]+)([^?#\s]*)(\?[^#\s]*)?(#\S*)?$/i;
27
+ function tidyLabel(value) {
28
+ if (typeof value !== "string") return void 0;
29
+ const label = value.replace(/[\u0000-\u001f\u007f-\u009f\s]+/g, " ").trim().slice(0, MAX_NAME_LENGTH).trim();
30
+ return label || void 0;
31
+ }
32
+ function mediaKindFromPath(path) {
33
+ if (IMAGE_EXTENSION.test(path)) return "image";
34
+ if (VIDEO_EXTENSION.test(path)) return "video";
35
+ return null;
36
+ }
37
+ function parseMediaLink(raw) {
38
+ if (!raw || typeof raw !== "object") return null;
39
+ const {
40
+ src,
41
+ kind,
42
+ name
43
+ } = raw;
44
+ if (typeof src !== "string") return null;
45
+ const href = src.trim();
46
+ if (!href || href.length > MAX_URL_LENGTH) return null;
47
+ const match = HTTP_URL.exec(href);
48
+ if (!match) return null;
49
+ const authority = match[2];
50
+ if (authority.includes("@")) return null;
51
+ const path = match[3] || "/";
52
+ const asked = typeof kind === "string" ? kind.trim().toLowerCase() : "";
53
+ const resolved = asked ? asked === "image" || asked === "video" ? asked : null : mediaKindFromPath(path);
54
+ if (!resolved) return null;
55
+ const label = tidyLabel(name);
56
+ let fileName;
57
+ const segment = path.slice(path.lastIndexOf("/") + 1);
58
+ try {
59
+ fileName = tidyLabel(decodeURIComponent(segment));
60
+ } catch (e) {
61
+ fileName = tidyLabel(segment);
62
+ }
63
+ return __spreadValues(__spreadValues({
64
+ src: href,
65
+ kind: resolved
66
+ }, label ? {
67
+ name: label
68
+ } : {}), fileName ? {
69
+ fileName
70
+ } : {});
71
+ }
72
+ const DESIGN_ID_RE = /^[0-9A-Za-z][0-9A-Za-z:_-]{3,127}$/;
73
+ function parseDesignLink(raw) {
74
+ for (const value of [raw.designId, raw.artifactId]) {
75
+ if (typeof value === "string" && DESIGN_ID_RE.test(value.trim())) return {
76
+ channelId: value.trim()
77
+ };
78
+ }
79
+ if (typeof raw.designTemplateId === "string" && raw.designTemplateId.trim()) return {
80
+ kind: "design"
81
+ };
82
+ return null;
83
+ }export{mediaKindFromPath,parseCreateTileLink,parseDesignLink,parseMediaLink};//# sourceMappingURL=deepLinks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deepLinks.js","sources":["../../../src/features/canvas/deepLinks.ts"],"sourcesContent":["/**\n * Deep links into the canvas - native twins of canvas-surface\n * `utils/createDeepLink.ts`, `utils/mediaDeepLink.ts` and the `?design=` /\n * `?artifact=` openings in CanvasPage. On web they arrive as query params; on\n * native they arrive as CanvasExperience props (route params from the host).\n * Each runs once on mount; every value is someone else's input, so nothing is\n * fetched or opened until it passes.\n *\n * Pure: no `URL` (RN's polyfill throws on most getters), no RN imports.\n */\nimport type { DesignKind } from '../design/designCore';\nimport { createActionFor, type CreateAction } from './createTiles';\n\n/** The Create action a `createTile` link names, or null (unknown id, hidden tile, junk). */\nexport function parseCreateTileLink(raw: unknown): CreateAction | null {\n if (typeof raw !== 'string') return null;\n const id = raw.trim().toLowerCase();\n return /^[a-z0-9][a-z0-9-]{0,39}$/.test(id) ? createActionFor(id) : null;\n}\n\nexport type MediaLinkKind = 'image' | 'video';\n\nexport interface MediaLink {\n src: string;\n kind: MediaLinkKind;\n /** Display name for the board item; absent when the link carried none. */\n name?: string;\n /** The file's own name off the URL's path. */\n fileName?: string;\n}\n\n/** Longer than any signed storage URL; past it the \"URL\" is not one a surface wrote. */\nconst MAX_URL_LENGTH = 8192;\nconst MAX_NAME_LENGTH = 120;\nconst IMAGE_EXTENSION = /\\.(png|jpe?g|gif|webp|avif|bmp)$/i;\nconst VIDEO_EXTENSION = /\\.(mp4|m4v|mov|webm)$/i;\n/** scheme://authority/path?query#hash with no whitespace anywhere. */\nconst HTTP_URL = /^(https?):\\/\\/([^/?#\\s]+)([^?#\\s]*)(\\?[^#\\s]*)?(#\\S*)?$/i;\n\n/** Control characters and runs of whitespace fold to one space; capped; blank is none. */\nfunction tidyLabel(value: unknown): string | undefined {\n if (typeof value !== 'string') return undefined;\n const label = value\n // eslint-disable-next-line no-control-regex\n .replace(/[\\u0000-\\u001f\\u007f-\\u009f\\s]+/g, ' ')\n .trim()\n .slice(0, MAX_NAME_LENGTH)\n .trim();\n return label || undefined;\n}\n\n/** The kind a path's extension names, or null. */\nexport function mediaKindFromPath(path: string): MediaLinkKind | null {\n if (IMAGE_EXTENSION.test(path)) return 'image';\n if (VIDEO_EXTENSION.test(path)) return 'video';\n return null;\n}\n\n/**\n * A `media` link that passes web's rules, or null: an absolute http(s) URL\n * without credentials, and a kind the editors take. A given kind decides; only\n * a missing one is read off the extension.\n */\nexport function parseMediaLink(raw: unknown): MediaLink | null {\n if (!raw || typeof raw !== 'object') return null;\n const { src, kind, name } = raw as { src?: unknown; kind?: unknown; name?: unknown };\n if (typeof src !== 'string') return null;\n const href = src.trim();\n if (!href || href.length > MAX_URL_LENGTH) return null;\n const match = HTTP_URL.exec(href);\n if (!match) return null;\n const authority = match[2];\n // A surface never hands over a URL with credentials in it.\n if (authority.includes('@')) return null;\n const path = match[3] || '/';\n const asked = typeof kind === 'string' ? kind.trim().toLowerCase() : '';\n const resolved: MediaLinkKind | null = asked\n ? asked === 'image' || asked === 'video'\n ? asked\n : null\n : mediaKindFromPath(path);\n if (!resolved) return null;\n const label = tidyLabel(name);\n let fileName: string | undefined;\n const segment = path.slice(path.lastIndexOf('/') + 1);\n try {\n fileName = tidyLabel(decodeURIComponent(segment));\n } catch {\n fileName = tidyLabel(segment);\n }\n return { src: href, kind: resolved, ...(label ? { name: label } : {}), ...(fileName ? { fileName } : {}) };\n}\n\n/** Ids the design index or web Studio mint: no spaces, no path tricks. */\nconst DESIGN_ID_RE = /^[0-9A-Za-z][0-9A-Za-z:_-]{3,127}$/;\n\nexport type DesignLinkEntry = { channelId: string } | { kind: DesignKind };\n\n/**\n * Where a design link opens the native studio: a saved design by id\n * (`designId`, or a chat card's `artifactId`), else a template link opens the\n * studio on a blank design (native has no design template catalog yet), else\n * null. DesignExperience falls back to its own list when the id is not one of\n * the person's designs, so a stale or foreign id lands in the studio, not on\n * someone else's work.\n */\nexport function parseDesignLink(raw: {\n designId?: unknown;\n designTemplateId?: unknown;\n artifactId?: unknown;\n}): DesignLinkEntry | null {\n for (const value of [raw.designId, raw.artifactId]) {\n if (typeof value === 'string' && DESIGN_ID_RE.test(value.trim())) return { channelId: value.trim() };\n }\n if (typeof raw.designTemplateId === 'string' && raw.designTemplateId.trim()) return { kind: 'design' };\n return null;\n}\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAcO,SAAS,oBAAoB,GAAmC,EAAA;AACrE,EAAI,IAAA,OAAO,GAAQ,KAAA,QAAA,EAAiB,OAAA,IAAA;AACpC,EAAA,MAAM,EAAK,GAAA,GAAA,CAAI,IAAK,EAAA,CAAE,WAAY,EAAA;AAClC,EAAA,OAAO,4BAA4B,IAAK,CAAA,EAAE,CAAI,GAAA,eAAA,CAAgB,EAAE,CAAI,GAAA,IAAA;AACtE;AAYA,MAAM,cAAiB,GAAA,IAAA;AACvB,MAAM,eAAkB,GAAA,GAAA;AACxB,MAAM,eAAkB,GAAA,mCAAA;AACxB,MAAM,eAAkB,GAAA,wBAAA;AAExB,MAAM,QAAW,GAAA,0DAAA;AAGjB,SAAS,UAAU,KAAoC,EAAA;AACrD,EAAI,IAAA,OAAO,KAAU,KAAA,QAAA,EAAiB,OAAA,MAAA;AACtC,EAAA,MAAM,KAAQ,GAAA,KAAA,CAEb,OAAQ,CAAA,kCAAA,EAAoC,GAAG,CAAA,CAAE,IAAK,EAAA,CAAE,KAAM,CAAA,CAAA,EAAG,eAAe,CAAA,CAAE,IAAK,EAAA;AACxF,EAAA,OAAO,KAAS,IAAA,MAAA;AAClB;AAGO,SAAS,kBAAkB,IAAoC,EAAA;AACpE,EAAA,IAAI,eAAgB,CAAA,IAAA,CAAK,IAAI,CAAA,EAAU,OAAA,OAAA;AACvC,EAAA,IAAI,eAAgB,CAAA,IAAA,CAAK,IAAI,CAAA,EAAU,OAAA,OAAA;AACvC,EAAO,OAAA,IAAA;AACT;AAOO,SAAS,eAAe,GAAgC,EAAA;AAC7D,EAAA,IAAI,CAAC,GAAA,IAAO,OAAO,GAAA,KAAQ,UAAiB,OAAA,IAAA;AAC5C,EAAM,MAAA;AAAA,IACJ,GAAA;AAAA,IACA,IAAA;AAAA,IACA;AAAA,GACE,GAAA,GAAA;AAKJ,EAAI,IAAA,OAAO,GAAQ,KAAA,QAAA,EAAiB,OAAA,IAAA;AACpC,EAAM,MAAA,IAAA,GAAO,IAAI,IAAK,EAAA;AACtB,EAAA,IAAI,CAAC,IAAA,IAAQ,IAAK,CAAA,MAAA,GAAS,gBAAuB,OAAA,IAAA;AAClD,EAAM,MAAA,KAAA,GAAQ,QAAS,CAAA,IAAA,CAAK,IAAI,CAAA;AAChC,EAAI,IAAA,CAAC,OAAc,OAAA,IAAA;AACnB,EAAM,MAAA,SAAA,GAAY,MAAM,CAAC,CAAA;AAEzB,EAAA,IAAI,SAAU,CAAA,QAAA,CAAS,GAAG,CAAA,EAAU,OAAA,IAAA;AACpC,EAAM,MAAA,IAAA,GAAO,KAAM,CAAA,CAAC,CAAK,IAAA,GAAA;AACzB,EAAM,MAAA,KAAA,GAAQ,OAAO,IAAS,KAAA,QAAA,GAAW,KAAK,IAAK,EAAA,CAAE,aAAgB,GAAA,EAAA;AACrE,EAAM,MAAA,QAAA,GAAiC,QAAQ,KAAU,KAAA,OAAA,IAAW,UAAU,OAAU,GAAA,KAAA,GAAQ,IAAO,GAAA,iBAAA,CAAkB,IAAI,CAAA;AAC7H,EAAI,IAAA,CAAC,UAAiB,OAAA,IAAA;AACtB,EAAM,MAAA,KAAA,GAAQ,UAAU,IAAI,CAAA;AAC5B,EAAI,IAAA,QAAA;AACJ,EAAA,MAAM,UAAU,IAAK,CAAA,KAAA,CAAM,KAAK,WAAY,CAAA,GAAG,IAAI,CAAC,CAAA;AACpD,EAAI,IAAA;AACF,IAAW,QAAA,GAAA,SAAA,CAAU,kBAAmB,CAAA,OAAO,CAAC,CAAA;AAAA,GAC1C,CAAA,OAAA,CAAA,EAAA;AACN,IAAA,QAAA,GAAW,UAAU,OAAO,CAAA;AAAA;AAE9B,EAAO,OAAA,cAAA,CAAA,cAAA,CAAA;AAAA,IACL,GAAK,EAAA,IAAA;AAAA,IACL,IAAM,EAAA;AAAA,GAAA,EACF,KAAQ,GAAA;AAAA,IACV,IAAM,EAAA;AAAA,GACR,GAAI,EAAC,CAAA,EACD,QAAW,GAAA;AAAA,IACb;AAAA,MACE,EAAC,CAAA;AAET;AAGA,MAAM,YAAe,GAAA,oCAAA;AAed,SAAS,gBAAgB,GAIL,EAAA;AACzB,EAAA,KAAA,MAAW,SAAS,CAAC,GAAA,CAAI,QAAU,EAAA,GAAA,CAAI,UAAU,CAAG,EAAA;AAClD,IAAI,IAAA,OAAO,UAAU,QAAY,IAAA,YAAA,CAAa,KAAK,KAAM,CAAA,IAAA,EAAM,CAAA,EAAU,OAAA;AAAA,MACvE,SAAA,EAAW,MAAM,IAAK;AAAA,KACxB;AAAA;AAEF,EAAI,IAAA,OAAO,IAAI,gBAAqB,KAAA,QAAA,IAAY,IAAI,gBAAiB,CAAA,IAAA,IAAe,OAAA;AAAA,IAClF,IAAM,EAAA;AAAA,GACR;AACA,EAAO,OAAA,IAAA;AACT"}
@@ -30,4 +30,16 @@ async function extractFramesViaRpc(run, inputUrl, options = {}) {
30
30
  const single = resultUrl(result, EXTRACT);
31
31
  if (single) return [single];
32
32
  throw new Error("The extractor returned no frames");
33
- }export{extractFramesViaRpc};//# sourceMappingURL=frameExtract.js.map
33
+ }
34
+ function frameShareContent(urls, sourceName = "video") {
35
+ const title = `${urls.length} frame${urls.length === 1 ? "" : "s"} from ${sourceName}`;
36
+ if (urls.length === 1) return {
37
+ url: urls[0],
38
+ message: urls[0],
39
+ title
40
+ };
41
+ return {
42
+ message: urls.map((u, i) => `${i + 1}. ${u}`).join("\n"),
43
+ title
44
+ };
45
+ }export{extractFramesViaRpc,frameShareContent};//# sourceMappingURL=frameExtract.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"frameExtract.js","sources":["../../../src/features/canvas/frameExtract.ts"],"sourcesContent":["/**\n * Native twin of canvas-surface `extractFramesViaRpc` — server-side stills\n * from a clip (phone cannot taint-read video pixels like the web canvas).\n */\nimport { resultUrl, type RunMediaAction } from './videoEditor/mediaActions';\n\nconst VIDEO = 'yantra-video-editing';\nconst EXTRACT = 'YANTRA_VIDEO_EDIT_EXTRACT_FRAMES';\n\nexport async function extractFramesViaRpc(\n run: RunMediaAction,\n inputUrl: string,\n options: { fps?: number; maxFrames?: number } = {},\n): Promise<string[]> {\n const result = await run(VIDEO, EXTRACT, {\n input_url: inputUrl,\n ...(options.fps !== undefined ? { fps: options.fps } : {}),\n ...(options.maxFrames !== undefined ? { max_frames: options.maxFrames } : {}),\n });\n const data = (result.data && typeof result.data === 'object' ? result.data : result) as Record<string, unknown>;\n const frames = Array.isArray(data.frames)\n ? data.frames.filter((url): url is string => typeof url === 'string' && url.length > 0)\n : [];\n if (frames.length > 0) return frames;\n const single = resultUrl(result, EXTRACT);\n if (single) return [single];\n throw new Error('The extractor returned no frames');\n}\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAKA,MAAM,KAAQ,GAAA,sBAAA;AACd,MAAM,OAAU,GAAA,kCAAA;AAChB,eAAsB,mBAAoB,CAAA,GAAA,EAAqB,QAAkB,EAAA,OAAA,GAG7E,EAAuB,EAAA;AACzB,EAAA,MAAM,MAAS,GAAA,MAAM,GAAI,CAAA,KAAA,EAAO,OAAS,EAAA,cAAA,CAAA,cAAA,CAAA;AAAA,IACvC,SAAW,EAAA;AAAA,GACP,EAAA,OAAA,CAAQ,QAAQ,MAAY,GAAA;AAAA,IAC9B,KAAK,OAAQ,CAAA;AAAA,GACX,GAAA,EACA,CAAA,EAAA,OAAA,CAAQ,cAAc,MAAY,GAAA;AAAA,IACpC,YAAY,OAAQ,CAAA;AAAA,GACtB,GAAI,EACL,CAAA,CAAA;AACD,EAAM,MAAA,IAAA,GAAQ,OAAO,IAAQ,IAAA,OAAO,OAAO,IAAS,KAAA,QAAA,GAAW,OAAO,IAAO,GAAA,MAAA;AAC7E,EAAA,MAAM,SAAS,KAAM,CAAA,OAAA,CAAQ,KAAK,MAAM,CAAA,GAAI,KAAK,MAAO,CAAA,MAAA,CAAO,CAAC,GAAA,KAAuB,OAAO,GAAQ,KAAA,QAAA,IAAY,IAAI,MAAS,GAAA,CAAC,IAAI,EAAC;AACrI,EAAI,IAAA,MAAA,CAAO,MAAS,GAAA,CAAA,EAAU,OAAA,MAAA;AAC9B,EAAM,MAAA,MAAA,GAAS,SAAU,CAAA,MAAA,EAAQ,OAAO,CAAA;AACxC,EAAI,IAAA,MAAA,EAAe,OAAA,CAAC,MAAM,CAAA;AAC1B,EAAM,MAAA,IAAI,MAAM,kCAAkC,CAAA;AACpD"}
1
+ {"version":3,"file":"frameExtract.js","sources":["../../../src/features/canvas/frameExtract.ts"],"sourcesContent":["/**\n * Native twin of canvas-surface `extractFramesViaRpc` — server-side stills\n * from a clip (phone cannot taint-read video pixels like the web canvas).\n */\nimport { resultUrl, type RunMediaAction } from './videoEditor/mediaActions';\n\nconst VIDEO = 'yantra-video-editing';\nconst EXTRACT = 'YANTRA_VIDEO_EDIT_EXTRACT_FRAMES';\n\nexport async function extractFramesViaRpc(\n run: RunMediaAction,\n inputUrl: string,\n options: { fps?: number; maxFrames?: number } = {},\n): Promise<string[]> {\n const result = await run(VIDEO, EXTRACT, {\n input_url: inputUrl,\n ...(options.fps !== undefined ? { fps: options.fps } : {}),\n ...(options.maxFrames !== undefined ? { max_frames: options.maxFrames } : {}),\n });\n const data = (result.data && typeof result.data === 'object' ? result.data : result) as Record<string, unknown>;\n const frames = Array.isArray(data.frames)\n ? data.frames.filter((url): url is string => typeof url === 'string' && url.length > 0)\n : [];\n if (frames.length > 0) return frames;\n const single = resultUrl(result, EXTRACT);\n if (single) return [single];\n throw new Error('The extractor returned no frames');\n}\n\n/**\n * What the share sheet gets for the chosen frames. One frame shares as the\n * image URL itself (iOS previews and saves it); several go as a numbered\n * list of links, since RN's Share takes a single url. Pure.\n */\nexport function frameShareContent(\n urls: readonly string[],\n sourceName = 'video',\n): { url?: string; message: string; title: string } {\n const title = `${urls.length} frame${urls.length === 1 ? '' : 's'} from ${sourceName}`;\n if (urls.length === 1) return { url: urls[0], message: urls[0], title };\n return { message: urls.map((u, i) => `${i + 1}. ${u}`).join('\\n'), title };\n}\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAKA,MAAM,KAAQ,GAAA,sBAAA;AACd,MAAM,OAAU,GAAA,kCAAA;AAChB,eAAsB,mBAAoB,CAAA,GAAA,EAAqB,QAAkB,EAAA,OAAA,GAG7E,EAAuB,EAAA;AACzB,EAAA,MAAM,MAAS,GAAA,MAAM,GAAI,CAAA,KAAA,EAAO,OAAS,EAAA,cAAA,CAAA,cAAA,CAAA;AAAA,IACvC,SAAW,EAAA;AAAA,GACP,EAAA,OAAA,CAAQ,QAAQ,MAAY,GAAA;AAAA,IAC9B,KAAK,OAAQ,CAAA;AAAA,GACX,GAAA,EACA,CAAA,EAAA,OAAA,CAAQ,cAAc,MAAY,GAAA;AAAA,IACpC,YAAY,OAAQ,CAAA;AAAA,GACtB,GAAI,EACL,CAAA,CAAA;AACD,EAAM,MAAA,IAAA,GAAQ,OAAO,IAAQ,IAAA,OAAO,OAAO,IAAS,KAAA,QAAA,GAAW,OAAO,IAAO,GAAA,MAAA;AAC7E,EAAA,MAAM,SAAS,KAAM,CAAA,OAAA,CAAQ,KAAK,MAAM,CAAA,GAAI,KAAK,MAAO,CAAA,MAAA,CAAO,CAAC,GAAA,KAAuB,OAAO,GAAQ,KAAA,QAAA,IAAY,IAAI,MAAS,GAAA,CAAC,IAAI,EAAC;AACrI,EAAI,IAAA,MAAA,CAAO,MAAS,GAAA,CAAA,EAAU,OAAA,MAAA;AAC9B,EAAM,MAAA,MAAA,GAAS,SAAU,CAAA,MAAA,EAAQ,OAAO,CAAA;AACxC,EAAI,IAAA,MAAA,EAAe,OAAA,CAAC,MAAM,CAAA;AAC1B,EAAM,MAAA,IAAI,MAAM,kCAAkC,CAAA;AACpD;AAOgB,SAAA,iBAAA,CAAkB,IAAyB,EAAA,UAAA,GAAa,OAItE,EAAA;AACA,EAAM,MAAA,KAAA,GAAQ,CAAG,EAAA,IAAA,CAAK,MAAM,CAAA,MAAA,EAAS,IAAK,CAAA,MAAA,KAAW,CAAI,GAAA,EAAA,GAAK,GAAG,CAAA,MAAA,EAAS,UAAU,CAAA,CAAA;AACpF,EAAI,IAAA,IAAA,CAAK,MAAW,KAAA,CAAA,EAAU,OAAA;AAAA,IAC5B,GAAA,EAAK,KAAK,CAAC,CAAA;AAAA,IACX,OAAA,EAAS,KAAK,CAAC,CAAA;AAAA,IACf;AAAA,GACF;AACA,EAAO,OAAA;AAAA,IACL,OAAS,EAAA,IAAA,CAAK,GAAI,CAAA,CAAC,GAAG,CAAM,KAAA,CAAA,EAAG,CAAI,GAAA,CAAC,CAAK,EAAA,EAAA,CAAC,CAAE,CAAA,CAAA,CAAE,KAAK,IAAI,CAAA;AAAA,IACvD;AAAA,GACF;AACF"}
@@ -37,6 +37,8 @@ const STATIC_VIDEO_MODELS = [{
37
37
  supportsImageToVideo: true,
38
38
  supportsEndFrame: true,
39
39
  supportsAudio: true,
40
+ supportsReferenceImages: true,
41
+ maxReferenceImages: 3,
40
42
  aspectRatios: VEO_ASPECTS,
41
43
  resolutions: VEO_RESOLUTIONS
42
44
  }, {
@@ -50,6 +52,8 @@ const STATIC_VIDEO_MODELS = [{
50
52
  supportsImageToVideo: true,
51
53
  supportsEndFrame: true,
52
54
  isFast: true,
55
+ supportsReferenceImages: true,
56
+ maxReferenceImages: 3,
53
57
  aspectRatios: VEO_ASPECTS,
54
58
  resolutions: VEO_RESOLUTIONS
55
59
  }, {
@@ -94,7 +98,9 @@ const STATIC_VIDEO_MODELS = [{
94
98
  supportedDurationsSeconds: [4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15],
95
99
  defaultDurationSeconds: 5,
96
100
  maxDurationSeconds: 15,
97
- supportsImageToVideo: true
101
+ supportsImageToVideo: true,
102
+ supportsReferenceImages: true,
103
+ maxReferenceImages: 9
98
104
  }, {
99
105
  id: "bytedance/seedance-2.0-fast",
100
106
  label: "Seedance 2.0 Fast",
@@ -104,6 +110,8 @@ const STATIC_VIDEO_MODELS = [{
104
110
  defaultDurationSeconds: 5,
105
111
  maxDurationSeconds: 15,
106
112
  supportsImageToVideo: true,
113
+ supportsReferenceImages: true,
114
+ maxReferenceImages: 9,
107
115
  isFast: true
108
116
  }];
109
117
  const AUDIO_PROMPT_TYPES = /* @__PURE__ */ new Set(["tts", "sfx", "music"]);
@@ -135,7 +143,7 @@ function normalizeModels(raw) {
135
143
  const list = Array.isArray(payload) ? payload : Array.isArray(nested.models) ? nested.models : Array.isArray(nested.data) ? nested.data : Array.isArray(record.models) ? record.models : [];
136
144
  return list.map((m) => {
137
145
  var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k;
138
- return __spreadValues(__spreadValues(__spreadProps(__spreadValues(__spreadValues(__spreadValues(__spreadValues(__spreadValues(__spreadValues(__spreadValues(__spreadValues({
146
+ return __spreadValues(__spreadValues(__spreadProps(__spreadValues(__spreadValues(__spreadValues(__spreadValues(__spreadValues(__spreadValues(__spreadValues(__spreadValues(__spreadValues(__spreadValues({
139
147
  id: String((_c = (_b = (_a = m.id) != null ? _a : m.modelId) != null ? _b : m.name) != null ? _c : ""),
140
148
  label: String((_h = (_g = (_f = (_e = (_d = m.displayName) != null ? _d : m.label) != null ? _e : m.title) != null ? _f : m.name) != null ? _g : m.id) != null ? _h : ""),
141
149
  provider: String((_j = (_i = m.provider) != null ? _i : m.source) != null ? _j : ""),
@@ -148,6 +156,10 @@ function normalizeModels(raw) {
148
156
  supportsImageToVideo: m.supportsImageToVideo
149
157
  } : {}), typeof m.supportsEndFrame === "boolean" ? {
150
158
  supportsEndFrame: m.supportsEndFrame
159
+ } : {}), typeof m.supportsReferenceImages === "boolean" ? {
160
+ supportsReferenceImages: m.supportsReferenceImages
161
+ } : {}), typeof m.maxReferenceImages === "number" && Number.isFinite(m.maxReferenceImages) ? {
162
+ maxReferenceImages: Math.max(0, Math.round(m.maxReferenceImages))
151
163
  } : {}), typeof m.supportsAudio === "boolean" ? {
152
164
  supportsAudio: m.supportsAudio
153
165
  } : {}), Array.isArray(m.aspectRatios) ? {
@@ -166,7 +178,8 @@ function normalizeModels(raw) {
166
178
  }).filter((m) => Boolean(m.id));
167
179
  }
168
180
  function buildVideoGenerateParams(opts) {
169
- return __spreadValues(__spreadValues(__spreadValues(__spreadValues(__spreadValues(__spreadValues(__spreadValues(__spreadValues({
181
+ var _a;
182
+ return __spreadValues(__spreadValues(__spreadValues(__spreadValues(__spreadValues(__spreadValues(__spreadValues(__spreadValues(__spreadValues({
170
183
  prompt: opts.prompt,
171
184
  aspectRatio: opts.aspectRatio
172
185
  }, opts.model ? {
@@ -177,16 +190,31 @@ function buildVideoGenerateParams(opts) {
177
190
  referenceImageUrl: opts.referenceImageUrl
178
191
  } : {}), opts.referenceVideoUrl ? {
179
192
  referenceVideoUrl: opts.referenceVideoUrl
180
- } : {}), opts.lastFrameUrl ? {
181
- lastFrameUrl: opts.lastFrameUrl
193
+ } : {}), opts.referenceEndImageUrl ? {
194
+ referenceEndImageUrl: opts.referenceEndImageUrl
195
+ } : {}), ((_a = opts.styleReferenceUrls) == null ? void 0 : _a.length) ? {
196
+ styleReferenceUrls: opts.styleReferenceUrls
182
197
  } : {}), opts.resolution ? {
183
198
  resolution: opts.resolution
184
- } : {}), opts.generateAudio ? {
185
- generateAudio: true
199
+ } : {}), opts.generateAudio !== void 0 ? {
200
+ generateAudio: opts.generateAudio
186
201
  } : {}), opts.negativePrompt ? {
187
202
  negativePrompt: opts.negativePrompt
188
203
  } : {});
189
204
  }
205
+ const DEFAULT_VIDEO_REFERENCE_CAP = 3;
206
+ function videoReferenceCap(models, selectedId) {
207
+ const current = models.find((m) => m.id === selectedId);
208
+ if (!current) return DEFAULT_VIDEO_REFERENCE_CAP;
209
+ if (typeof current.maxReferenceImages === "number") return current.maxReferenceImages;
210
+ return current.supportsReferenceImages === false ? 0 : DEFAULT_VIDEO_REFERENCE_CAP;
211
+ }
212
+ function modelThatReadsImages(models, selectedId) {
213
+ var _a, _b;
214
+ const current = models.find((m) => m.id === selectedId);
215
+ if (!current || current.supportsImageInput !== false) return null;
216
+ return (_b = (_a = models.find((m) => m.supportsImageInput)) == null ? void 0 : _a.id) != null ? _b : null;
217
+ }
190
218
  function generationCapabilities(model) {
191
219
  var _a, _b, _c;
192
220
  (model == null ? void 0 : model.provider) === "google";
@@ -198,4 +226,4 @@ function generationCapabilities(model) {
198
226
  canEndFrame: Boolean(model == null ? void 0 : model.supportsEndFrame),
199
227
  canVideoInput: Boolean(model == null ? void 0 : model.supportsVideoInput)
200
228
  };
201
- }export{AUDIO_PROMPT_TYPES,STATIC_IMAGE_MODELS,STATIC_VIDEO_MODELS,buildVideoGenerateParams,generationCapabilities,normalizeModels,promptAudioModels,videoDurationOptions};//# sourceMappingURL=generationModels.js.map
229
+ }export{AUDIO_PROMPT_TYPES,DEFAULT_VIDEO_REFERENCE_CAP,STATIC_IMAGE_MODELS,STATIC_VIDEO_MODELS,buildVideoGenerateParams,generationCapabilities,modelThatReadsImages,normalizeModels,promptAudioModels,videoDurationOptions,videoReferenceCap};//# sourceMappingURL=generationModels.js.map