stillmade-sdk 0.1.47 → 0.1.48

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 (73) hide show
  1. package/AGENTS.md +6 -2
  2. package/FRAME_VIEWS.md +71 -5
  3. package/INTERFACE_DESIGN.md +65 -2
  4. package/MODULES.md +26 -3
  5. package/PASTE_TO_LLM.md +25 -10
  6. package/README.md +15 -0
  7. package/SDK.md +349 -51
  8. package/blocks/native/sm.board-editor/versions/3.0.0/package.js +921 -0
  9. package/blocks/native/sm.editor/versions/3.0.0/package.js +751 -0
  10. package/blocks/native/sm.panel-strip/versions/3.0.0/package.js +350 -0
  11. package/blocks/native/sm.photo-editor/versions/1.0.0/package.js +6693 -0
  12. package/blocks/native/sm.voiceover/versions/3.0.0/package.js +513 -0
  13. package/docs/build/block-builder-contract.md +2 -2
  14. package/docs/build/custom-interface.md +23 -3
  15. package/docs/build/frame-views.md +71 -5
  16. package/docs/build/hosted-text.md +8 -3
  17. package/docs/build/interface-design.md +65 -2
  18. package/docs/build/media-analysis.md +18 -1
  19. package/docs/build/modules.md +26 -3
  20. package/docs/build/with-your-ai.md +14 -0
  21. package/docs/build/workspaces.md +42 -0
  22. package/docs/reference/authoring-guide.md +4 -4
  23. package/docs/reference/cli.md +8 -3
  24. package/docs/reference/execution.md +13 -5
  25. package/docs/reference/first-party-blocks.md +5 -4
  26. package/docs/reference/generation-models.md +4 -0
  27. package/docs/reference/limits.md +9 -2
  28. package/docs/reference/permissions.md +4 -0
  29. package/docs/reference/view-bridge.md +6 -3
  30. package/docs/reference/view-rules.md +1 -1
  31. package/docs/tools/llm.md +25 -10
  32. package/package.json +1 -1
  33. package/packages/block-cli/cli.js +124 -12
  34. package/packages/block-cli/dev-host/assets/host.js +55 -30
  35. package/packages/block-cli/dev-host/assets/index.css +1 -1
  36. package/packages/block-cli/dev-server.js +74 -23
  37. package/packages/block-cli/format.js +20 -1
  38. package/packages/block-cli/ready-gate.js +34 -2
  39. package/packages/block-cli/templates.js +61 -0
  40. package/packages/block-cli/type-packages.js +7 -4
  41. package/packages/block-cli/workspace-dev.js +124 -0
  42. package/packages/block-cli/workspace-pack.js +62 -0
  43. package/packages/block-cli/workspace.js +304 -0
  44. package/packages/block-platform/block-readiness.js +5 -4
  45. package/packages/block-platform/catalog.js +5 -3
  46. package/packages/block-platform/node-defaults.js +2 -2
  47. package/packages/block-platform/plain-descriptions.js +1 -0
  48. package/packages/block-platform/type-workspace.js +8 -0
  49. package/packages/block-sdk/admission.js +2 -2
  50. package/packages/block-sdk/builder-contract.js +3 -3
  51. package/packages/block-sdk/capabilities.js +32 -12
  52. package/packages/block-sdk/contracts.js +11 -2
  53. package/packages/block-sdk/first-party-identities.js +9 -0
  54. package/packages/block-sdk/first-party-packages.js +9 -1
  55. package/packages/block-sdk/folder-package.js +34 -2
  56. package/packages/block-sdk/generation-catalog.js +7 -0
  57. package/packages/block-sdk/index.d.ts +13 -5
  58. package/packages/block-sdk/index.js +1 -1
  59. package/packages/block-sdk/mock-host.js +7 -0
  60. package/packages/block-sdk/module-hosted.js +11 -1
  61. package/packages/block-sdk/module-media-access.js +5 -3
  62. package/packages/block-sdk/permission-summary.js +1 -1
  63. package/packages/block-sdk/portable-media-actions.d.ts +4 -1
  64. package/packages/block-sdk/portable-media-actions.js +16 -1
  65. package/packages/block-sdk/remix-policy.js +2 -2
  66. package/packages/block-sdk/staged-releases.js +5 -0
  67. package/packages/block-sdk/stillmade-pack.js +64 -0
  68. package/packages/block-sdk/testing.js +2 -2
  69. package/packages/block-sdk/view-bridge.js +6 -3
  70. package/packages/block-sdk/view-design.js +59 -12
  71. package/packages/block-sdk/view.js +47 -9
  72. package/packages/design-system/block-kit.css +6 -0
  73. package/packages/design-system/theme.css +2 -0
@@ -0,0 +1,350 @@
1
+ // Generated by frame/build-package.mjs from the original Image Panels screen. Edit the screen or frame/, then rebuild.
2
+ export default {
3
+ "manifest": {
4
+ "schemaVersion": 1,
5
+ "sdkVersion": "0.1.0",
6
+ "id": "sm.panel-strip",
7
+ "version": "3.0.0",
8
+ "name": "Image Panels",
9
+ "description": "Turn your narration into a timed sequence of consistent pictures: plan the panels, make and edit each one, add zooms, canvases and GIFs, and hand the cut to the Editor.",
10
+ "kind": "workspace",
11
+ "runtime": "module",
12
+ "license": "MIT",
13
+ "inputs": {
14
+ "narrationTiming": {
15
+ "type": "transcript",
16
+ "primary": true,
17
+ "required": false,
18
+ "semantic": "timed_transcript",
19
+ "description": "Timed narration words from an earlier Step. The panels are cut to these timings."
20
+ },
21
+ "narrationAudio": {
22
+ "type": "audio",
23
+ "required": false,
24
+ "semantic": "narration_audio",
25
+ "description": "The narration audio that goes with those timings."
26
+ },
27
+ "narrationScript": {
28
+ "type": "script",
29
+ "required": false,
30
+ "semantic": "narration_script",
31
+ "description": "Narration script from an earlier Step, used for the story when no timed words are connected."
32
+ },
33
+ "panels": {
34
+ "type": "panel-document",
35
+ "required": false,
36
+ "semantic": "image_panel_document",
37
+ "description": "The panels on this screen."
38
+ },
39
+ "make": {
40
+ "type": "text",
41
+ "required": false,
42
+ "semantic": "panel_action",
43
+ "description": "What a run makes: a plan, a picture, a clip, a check or the result."
44
+ },
45
+ "request": {
46
+ "type": "json",
47
+ "schema": "json",
48
+ "required": false,
49
+ "semantic": "panel_request",
50
+ "description": "The details of what to make."
51
+ },
52
+ "pictures": {
53
+ "type": "asset[]",
54
+ "required": false,
55
+ "semantic": "panel_media",
56
+ "description": "The saved pictures, clips and GIFs the panel document uses, as StillMade gave them."
57
+ },
58
+ "references": {
59
+ "type": "image[]",
60
+ "required": false,
61
+ "semantic": "reference_image",
62
+ "description": "Saved pictures a new picture keeps, or that a check looks at."
63
+ },
64
+ "image": {
65
+ "type": "image",
66
+ "required": false,
67
+ "semantic": "panel_image",
68
+ "description": "The saved picture a placement, zoom or crop looks at."
69
+ },
70
+ "firstFrame": {
71
+ "type": "image",
72
+ "required": false,
73
+ "semantic": "first_frame",
74
+ "description": "The picture a clip starts on."
75
+ },
76
+ "lastFrame": {
77
+ "type": "image",
78
+ "required": false,
79
+ "semantic": "last_frame",
80
+ "description": "The picture a clip ends on."
81
+ },
82
+ "dataUrl": {
83
+ "type": "text",
84
+ "required": false,
85
+ "semantic": "picture_data",
86
+ "description": "A picture the screen saves, such as a GIF or a reference."
87
+ },
88
+ "key": {
89
+ "type": "text",
90
+ "required": false,
91
+ "semantic": "storage_key",
92
+ "description": "A saved setting of this Block."
93
+ },
94
+ "value": {
95
+ "type": "json",
96
+ "schema": "json",
97
+ "required": false,
98
+ "semantic": "storage_value",
99
+ "description": "The value of that setting."
100
+ }
101
+ },
102
+ "outputs": {
103
+ "panels": {
104
+ "type": "panel-document",
105
+ "primary": true,
106
+ "required": false,
107
+ "role": "image_panel_document",
108
+ "semantic": "image_panel_document",
109
+ "description": "The complete Image Panels document for the next Step."
110
+ },
111
+ "images": {
112
+ "type": "asset[]",
113
+ "required": false,
114
+ "semantic": "panel_images",
115
+ "description": "Each panel's current picture, in story order."
116
+ },
117
+ "made": {
118
+ "type": "asset[]",
119
+ "required": false,
120
+ "semantic": "made_media",
121
+ "description": "The pictures or clips a run made."
122
+ },
123
+ "result": {
124
+ "type": "json",
125
+ "schema": "json",
126
+ "required": false,
127
+ "semantic": "panel_answer",
128
+ "description": "What the screen asked for: a plan, a placement, a check."
129
+ }
130
+ },
131
+ "permissions": {
132
+ "project": [],
133
+ "capabilities": [
134
+ "text.generate",
135
+ "media.analyze",
136
+ "image.generate",
137
+ "video.generate"
138
+ ],
139
+ "actions": [
140
+ "stock.search",
141
+ "stock.select",
142
+ "stock.auto",
143
+ "gif.search",
144
+ "gif.save",
145
+ "presenter.generate"
146
+ ],
147
+ "network": [],
148
+ "filesystem": [],
149
+ "secrets": []
150
+ },
151
+ "platforms": {
152
+ "phone": {
153
+ "supported": true
154
+ },
155
+ "browser": {
156
+ "supported": true
157
+ },
158
+ "desktop": {
159
+ "supported": true
160
+ }
161
+ },
162
+ "provenance": {
163
+ "notice": "MIT License\n\nCopyright (c) <year> <copyright holders>\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and \nassociated documentation files (the \"Software\"), to deal in the Software without restriction, including \nwithout limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell \ncopies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the \nfollowing conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial \nportions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT \nLIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO \nEVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER \nIN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE \nUSE OR OTHER DEALINGS IN THE SOFTWARE.\n"
164
+ }
165
+ },
166
+ "module": {
167
+ "schemaVersion": 1,
168
+ "entry": "main.js",
169
+ "files": {
170
+ "main.js": {
171
+ "sha256": "88daa01379f7d8424f0cee4b93b48739036b05cbd9311f20be2a835593635d74",
172
+ "bytes": 138416,
173
+ "mediaType": "text/javascript"
174
+ }
175
+ }
176
+ },
177
+ "view": {
178
+ "html": "<div id=\"root\"></div>\n",
179
+ "css": "/* ============================================================\n StillMade AI — Foundations applied to the AI Video Workflow app.\n Two surfaces only: cream (#F7F0DB) and ink (#0A0A0A).\n Everything else is a tonal shift of one of those two.\n Dark is the default; [data-mode=\"light\"] flips the surface.\n ============================================================ */\n/* When the licensed Balgin Skinny Italic files are available, drop\n them into client/public/fonts and uncomment this block — the\n display face points at \"Balgin\" first and switches automatically. */\n/*\n@font-face {\n font-family: \"Balgin\";\n src: url(\"/fonts/Balgin-SkinnyItalic.woff2\") format(\"woff2\");\n font-weight: 100;\n font-style: italic;\n font-display: swap;\n}\n*/\n\n*, *::before, *::after {\n box-sizing: border-box;\n margin: 0;\n padding: 0;\n}\n\n/* ============================================================\n Animated Studio — fixed slate theme (ignores light/dark).\n :root[...] specificity beats [data-mode], so it wins in both modes.\n ============================================================ */\n:root[data-anim-theme=\"1\"]:not([data-mode=\"white\"]) {\n color-scheme: dark;\n --bg: #0A0D13;\n --bg-elev-1: #0F141C;\n --bg-elev-2: #1A2230;\n --bg-inset: #0F141C;\n --fg: #D8DEE8;\n --fg-muted: #8B98AC;\n --fg-subtle: #64748B;\n --fg-on-accent: #0A0D13;\n --border-tok: #232D3D;\n --border-strong: #303D50;\n --divider: #1A2230;\n --hover-wash: rgba(139, 152, 172, 0.08);\n --press-wash: rgba(139, 152, 172, 0.16);\n --selection-bg: #303D50;\n --selection-fg: #D8DEE8;\n\n --bg-primary: #0A0D13;\n --bg-secondary: #0F141C;\n --bg-tertiary: #1A2230;\n --bg-elevated: #1A2230;\n --bg-hover: #232D3D;\n --border: #232D3D;\n --border-light: #303D50;\n --accent: #8B98AC;\n --accent-hover: #B6C0CE;\n --accent-dim: rgba(139, 152, 172, 0.12);\n --accent-glow: rgba(139, 152, 172, 0.25);\n --accent-contrast: #0A0D13;\n --editor-standout-bg: #D8DEE8;\n --editor-standout-fg: #0A0D13;\n --text-primary: #D8DEE8;\n --text-secondary: #8B98AC;\n --text-muted: #64748B;\n --success: #8B98AC;\n --warning: #B6C0CE;\n --danger: #B6C0CE;\n}\n\nhtml, body {\n height: 100%;\n width: 100%;\n overflow: hidden;\n background: var(--bg);\n color: var(--fg);\n font-family: var(--font-body);\n font-size: 14px;\n line-height: 1.6;\n letter-spacing: var(--tr-body);\n -webkit-font-smoothing: antialiased;\n text-rendering: optimizeLegibility;\n}\n\n#root {\n height: 100%;\n width: 100%;\n overflow: hidden;\n}\n\n/* App shell fills the dynamically-visible viewport. 100dvh (not 100vh) so the\n mobile browser's collapsing toolbar doesn't push the inner scroll container —\n and its last row of content — below the visible area where it can't be\n reached. vh fallback first for browsers without dvh. */\n.sm-app-shell { height: 100vh; height: 100dvh; }\n\n/* Full-screen mobile nav menu enters with a composited fade+slide (rule 6). */\n@keyframes sm-navmenu-in { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }\n.mobile-nav-menu { animation: sm-navmenu-in 200ms cubic-bezier(0.22, 1, 0.36, 1); }\n\n::selection { background: var(--selection-bg); color: var(--selection-fg); }\n\n/* Display lockups — always italic, always thin. This is the brand. */\n.display, h1, h2 {\n font-family: var(--font-display);\n font-style: italic;\n font-weight: 200;\n line-height: var(--lh-tight);\n letter-spacing: var(--tr-display);\n margin: 0;\n}\n.display { line-height: var(--lh-display); }\nh3, h4 {\n font-family: var(--font-body);\n font-weight: 500;\n line-height: var(--lh-tight);\n letter-spacing: -0.01em;\n margin: 0;\n}\n\n.eyebrow {font-size: 11px;\n color: var(--fg-muted);\n font-weight: 500;}\n\ncode, pre, .mono {\n font-family: var(--font-mono);\n font-size: 0.92em;\n}\n/* Listing IDs are interface text, not code. */\n.listing-identity code { font-family: inherit; font-size: inherit; }\n\nbutton {\n font-family: var(--font-body);\n cursor: pointer;\n border: none;\n outline: none;\n letter-spacing: var(--tr-body);\n}\n\ntextarea, input, select {\n font-family: var(--font-body);\n outline: none;\n}\n\n/* ─── Native <select> → app theme, applied GLOBALLY to every select (now + future),\n so individual call sites never need touching. This themes the CLOSED control via the\n theme tokens while keeping the browser's NATIVE open/close + selection behavior fully\n intact (so picking an option always works). The OPEN popup is drawn by the OS —\n macOS/Safari can't be CSS-themed — and `option` colors below theme it only where the\n browser honors them (Chrome/Firefox on Win/Linux). A truly themed popup everywhere\n needs a custom dropdown component, not native <select>. ─── */\nselect {\n background-color: var(--bg-elev-1);\n color: var(--text-primary);\n border: 1px solid var(--border);\n border-radius: var(--r-2);\n}\nselect option,\nselect optgroup {\n background-color: var(--bg-elevated);\n color: var(--text-primary);\n}\nselect option:checked { font-weight: 600; }\n\n/* ─── ThemedSelect — a custom dropdown whose OPEN popup is themed too (the one thing a\n native <select> can't do on macOS). The trigger mirrors the native `select` look above,\n so a converted call site is visually identical when closed; the popup + options are ours,\n including per-option disabled state and an \"ⓘ\" info tooltip (e.g. Coming Soon). ─── */\n.tsel-trigger {\n display: inline-flex; align-items: center; justify-content: space-between; gap: 8px;\n background-color: var(--bg-elev-1); color: var(--text-primary);\n border: 1px solid var(--border); border-radius: var(--r-2);\n font-family: var(--font-body); font-size: inherit; padding: 6px 10px;\n cursor: pointer; text-align: left;\n}\n.tsel-trigger:hover { border-color: var(--border-strong); }\n.tsel-trigger:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }\n.tsel-trigger:disabled { opacity: 0.5; cursor: default; }\n.tsel-label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n.tsel-caret { flex: none; font-size: 10px; opacity: 0.7; }\n.tsel-pop {\n /* Above EVERY overlay that can contain a select, not just app dialogs (100000):\n the mobile BottomSheet is 100050, TemplateStudio 100090 and the PreviewGrid\n lightbox 100095. At the old 100010 the popup painted UNDERNEATH the sheet\n that opened it, so every dropdown inside a mobile sheet (motion easing,\n font, position, word-reveal swap/emphasis/trail layout) and the Whoosh\n transition's Direction slot in TemplateStudio silently did nothing. */\n z-index: 100100;\n max-height: 260px; overflow-y: auto;\n background: var(--bg-elevated); border: 1px solid var(--border); border-radius: var(--r-2);\n box-shadow: 0 8px 28px rgba(0, 0, 0, 0.28); padding: 4px;\n}\n.tsel-opt {\n display: flex; align-items: center; gap: 6px; padding: 6px 8px; border-radius: 6px;\n color: var(--text-primary); cursor: pointer; font-size: 13px; white-space: nowrap;\n}\n.tsel-opt[data-active=\"true\"] { background: var(--bg-elev-1); }\n.tsel-opt[aria-selected=\"true\"] { font-weight: 600; }\n.tsel-opt[aria-disabled=\"true\"] { color: var(--text-muted); cursor: default; }\n.tsel-opt[aria-disabled=\"true\"][data-active=\"true\"] { background: transparent; }\n.tsel-check { flex: none; width: 12px; font-size: 11px; opacity: 0.8; }\n.tsel-opt-label { flex: 1 1 auto; overflow: hidden; text-overflow: ellipsis; }\n.tsel-note {\n position: relative;\n flex: none; width: 16px; height: 16px; font-size: 11px; cursor: help;\n color: var(--text-muted); border: 1px solid var(--border); border-radius: 999px;\n display: inline-flex; align-items: center; justify-content: center;\n}\n.tsel-note:hover { color: var(--text-primary); border-color: var(--border-strong); }\n/* Info tooltip (e.g. \"Coming Soon\"). Portaled to <body> and positioned to the RIGHT of the ⓘ\n so the popup's overflow can never clip it. */\n.tsel-tip {\n z-index: 100110; /* one step above .tsel-pop — it annotates an option inside it */\n background: var(--text-primary); color: var(--bg-elevated);\n padding: 4px 8px; border-radius: 5px; font-size: 11px; font-weight: 600;\n max-width: min(260px, calc(100vw - 16px)); box-sizing: border-box;\n white-space: normal; pointer-events: none;\n box-shadow: 0 2px 10px rgba(0, 0, 0, 0.3);\n}\n@media (max-width: 767.98px), (max-height: 480px) and (pointer: coarse) {\n .tsel-opt { min-height: 44px; box-sizing: border-box; font-size: 14px; }\n .tsel-note { width: 44px; height: 44px; flex: 0 0 44px; font-size: 14px; }\n}\n\n.video-editor input,\n.video-editor select,\n.video-editor textarea {\n width: 100%;\n min-width: 0;\n background: var(--bg-inset);\n color: var(--fg);\n border: var(--bw-1) solid var(--border-strong);\n border-radius: var(--r-2);\n padding: 7px 8px;\n font-family: var(--font-body);\n font-size: 12px;\n accent-color: var(--signal);\n}\n\n.video-editor,\n.mobile-editor-root {\n user-select: none;\n -webkit-user-select: none;\n /* Kill the iOS long-press callout (Copy / Search) and the selection\n magnifier so a touch drag/trim/long-press on the timeline, labels, or\n buttons can't accidentally select UI text. Inputs re-enable both below. */\n -webkit-touch-callout: none;\n}\n\n.video-editor input,\n.video-editor select,\n.video-editor textarea,\n.video-editor [contenteditable=\"true\"],\n.mobile-editor-root input,\n.mobile-editor-root select,\n.mobile-editor-root textarea,\n.mobile-editor-root [contenteditable=\"true\"] {\n user-select: text;\n -webkit-user-select: text;\n -webkit-touch-callout: default;\n}\n\n.video-editor input[type=\"range\"] {\n padding: 0;\n border: 0;\n background: transparent;\n}\n\n.video-editor input[type=\"checkbox\"] {\n width: auto;\n min-width: auto;\n}\n\n.video-editor select:focus,\n.video-editor input:focus,\n.video-editor textarea:focus {\n border-color: var(--signal);\n box-shadow: 0 0 0 1px var(--signal-dim);\n}\n\n/* Focus — always visible, always the signal color */\n:focus-visible {\n outline: 2px solid var(--signal);\n outline-offset: 2px;\n}\n\n::-webkit-scrollbar {\n width: 6px;\n height: 6px;\n}\n::-webkit-scrollbar-track { background: transparent; }\n::-webkit-scrollbar-thumb {\n background: var(--border-strong);\n border-radius: var(--r-pill);\n}\n::-webkit-scrollbar-thumb:hover { background: var(--fg-subtle); }\n\n/* Hide the scrollbar chrome while keeping the element scrollable (wheel /\n trackpad). Used on the editor's left panel + tab rail for a clean column. */\n.sm-hide-scrollbar { scrollbar-width: none; -ms-overflow-style: none; }\n.sm-hide-scrollbar::-webkit-scrollbar { width: 0; height: 0; display: none; }\n\n/* ============================================================\n Buttons — primary is fg/bg inversion, not a color.\n Sharp by default; pill is a deliberate touch affordance.\n ============================================================ */\n.btn {\n display: inline-flex;\n align-items: center;\n gap: var(--s-2);\n padding: var(--s-2) var(--s-4);\n border-radius: var(--r-pill);\n font-size: 13px;\n font-weight: 500;\n letter-spacing: var(--tr-body);\n transition: transform var(--dur-fast) var(--ease-out),\n background-color var(--dur-fast) var(--ease-out),\n border-color var(--dur-fast) var(--ease-out),\n color var(--dur-fast) var(--ease-out),\n opacity var(--dur-fast) var(--ease-out);\n}\n.btn:active { transform: scale(0.98); }\n\n.btn-primary {\n background: var(--fg);\n color: var(--bg);\n}\n.btn-primary:hover { background: var(--fg); opacity: 0.86; }\n.btn-primary:disabled { opacity: 0.4; cursor: not-allowed; }\n\n.btn-secondary {\n background: transparent;\n color: var(--fg);\n border: var(--bw-1) solid var(--border-strong);\n}\n.btn-secondary:hover { background: var(--hover-wash); border-color: var(--fg); }\n\n.btn-ghost {\n background: transparent;\n color: var(--fg-muted);\n padding: 6px 10px;\n}\n.btn-ghost:hover { background: var(--hover-wash); color: var(--fg); }\n\n.btn-icon {\n background: transparent;\n color: var(--fg-muted);\n padding: 5px;\n border-radius: var(--r-2);\n display: inline-flex;\n align-items: center;\n justify-content: center;\n transition: background-color var(--dur-fast) var(--ease-out),\n color var(--dur-fast) var(--ease-out),\n transform var(--dur-fast) var(--ease-out);\n}\n.btn-icon:hover { background: var(--hover-wash); color: var(--fg); }\n.btn-icon:active { transform: scale(0.98); }\n.btn-icon:disabled { opacity: 0.4; cursor: not-allowed; }\n\n.typing-indicator {\n display: flex;\n gap: 4px;\n align-items: center;\n padding: 4px 0;\n}\n.typing-indicator span {\n width: 6px;\n height: 6px;\n border-radius: var(--r-pill);\n background: var(--fg-subtle);\n animation: bounce 1.2s infinite;\n}\n.typing-indicator span:nth-child(2) { animation-delay: 0.2s; }\n.typing-indicator span:nth-child(3) { animation-delay: 0.4s; }\n\n@keyframes bounce {\n 0%, 60%, 100% { transform: translateY(0); opacity: 0.4; }\n 30% { transform: translateY(-5px); opacity: 1; }\n}\n\n@keyframes fadeIn {\n from { opacity: 0; transform: translateY(6px); }\n to { opacity: 1; transform: translateY(0); }\n}\n\n@keyframes spin {\n to { transform: rotate(360deg); }\n}\n\n@keyframes pulse {\n 0%, 100% { opacity: 0.4; transform: scale(0.9); }\n 50% { opacity: 1; transform: scale(1.1); }\n}\n\n/* Toast slide-in for ToastHost (services/toast.js) */\n@keyframes toastIn {\n from { opacity: 0; transform: translateY(8px); }\n to { opacity: 1; transform: translateY(0); }\n}\n\n/* Q3 — keyboard focus rings (focus-visible only, so mouse users don't see them) */\nbutton:focus-visible,\n[role=\"button\"]:focus-visible,\na:focus-visible,\ninput:focus-visible,\nselect:focus-visible,\ntextarea:focus-visible {\n outline: 2px solid var(--accent);\n outline-offset: 2px;\n border-radius: 4px;\n}\n\n/* Typing fields never show a focus outline or ring (docs/UI_AESTHETIC.md):\n the caret marks focus. Buttons, links, switches and checkboxes keep theirs.\n !important so component focus-visible rules cannot bring the ring back. */\ninput:not([type=\"checkbox\"]):not([type=\"radio\"]):not([type=\"range\"]):not([type=\"color\"]):not([type=\"file\"]):not([type=\"button\"]):not([type=\"submit\"]):not([type=\"reset\"]):is(:focus, :focus-visible),\ntextarea:is(:focus, :focus-visible),\nselect:is(:focus, :focus-visible),\n[contenteditable]:not([contenteditable=\"false\"]):is(:focus, :focus-visible) {\n outline: none !important;\n}\n\n/* Skeleton shimmer for P2 loaders */\n@keyframes skeletonShimmer {\n 0% { background-position: -200% 0; }\n 100% { background-position: 200% 0; }\n}\n.skeleton {\n background: linear-gradient(90deg,\n rgba(255,255,255,0.03) 0%,\n rgba(255,255,255,0.10) 50%,\n rgba(255,255,255,0.03) 100%);\n background-size: 200% 100%;\n animation: skeletonShimmer 1.4s ease-in-out infinite;\n border-radius: 6px;\n}\n\n/* Node-state visuals (E1) — applied to NodeShell wrapper.\n States: empty (dashed ghost) / generating (shimmer ring) / failed (red stripe) / complete */\n/* opacity:0.78 removed — CSS opacity cascades to children and faded the\n image too. Dashed border alone is the \"pending\" signal now. */\n.node-state-empty { border-style: dashed !important; }\n/* The pulsing glow animates OPACITY on a pseudo-element (compositor-only)\n instead of keyframing box-shadow, which repainted the node's full shadow\n region on the main thread every frame for the whole generation — with\n batch generation pulsing many nodes at once. Same look: constant 2px\n accent ring + a breathing 18px glow. */\n.node-state-generating { box-shadow: 0 0 0 2px var(--accent); position: relative; }\n.node-state-generating::after {\n content: '';\n position: absolute;\n inset: -2px;\n border-radius: inherit;\n box-shadow: 0 0 18px rgba(247, 200, 50, 0.55);\n animation: nodePulse 1.6s ease-in-out infinite;\n pointer-events: none;\n will-change: opacity;\n}\n@keyframes nodePulse {\n 0%, 100% { opacity: 0.36; }\n 50% { opacity: 1; }\n}\n.node-state-warning { position: relative; border-color: var(--attention-warning) !important; }\n.node-state-warning::after {\n content: ''; position: absolute; inset: -2px; border-radius: inherit; pointer-events: none;\n box-shadow: 0 0 0 1px var(--attention-warning), 0 0 14px color-mix(in srgb, var(--attention-warning) 40%, transparent);\n}\n.node-state-failed { border-top: 4px solid #d04848 !important; }\n.node-state-failed::before {\n content: '⚠ '; color: #d04848; font-weight: 800;\n position: absolute; top: 6px; left: 8px; font-size: 12px; z-index: 2;\n pointer-events: none;\n}\n\n/* React Flow overrides */\n.react-flow__node { cursor: default; }\n/* Promote layers only WHILE a gesture is live (xyflow toggles these classes\n automatically at drag start/end) — the dragged card and the panning\n viewport move on the compositor instead of repainting their 8-layer\n shadows every frame. No idle memory cost: the hint drops with the class. */\n.react-flow__node.dragging { will-change: transform; }\n.react-flow__pane.dragging .react-flow__viewport { will-change: transform; }\n\n/* ── 3D node extrusion (StillMade design bundle) ────────────────────\n Stacked box-shadow that follows the corner radius, plus an ambient\n cast. Compositor-only: no per-frame JS, no extra DOM. Capped at 6\n solid layers so paint cost stays bounded on large scenes (147 nodes).\n Excludes layout-only node types (scene groups, shot labels, sticky\n notes) which aren't cards. */\n.react-flow__node:not(.react-flow__node-sceneGroupNode):not(.react-flow__node-shotLabelNode):not(.react-flow__node-stickyNoteNode):not(.react-flow__node-transitionNode) {\n border-radius: 10px;\n box-shadow:\n 1px 1px 0 var(--node-side, #d8cfb3),\n 2px 2px 0 var(--node-side, #d8cfb3),\n 3px 3px 0 var(--node-side, #d8cfb3),\n 4px 4px 0 var(--node-side, #d8cfb3),\n 5px 5px 0 var(--node-side, #d8cfb3),\n 6px 6px 0 var(--node-side, #d8cfb3),\n 7px 7px 0 var(--node-edge, rgba(10,10,10,0.18)),\n 14px 16px 18px -4px rgba(10,10,10,0.18);\n /* No transition / hover-lift / drag-lift — animating transform on\n react-flow's already-transformed wrapper compounds onto its pan\n matrix and makes pans/drags feel laggy. Static shadow only. */\n}\n[data-mode=\"dark\"] .react-flow__node:not(.react-flow__node-sceneGroupNode):not(.react-flow__node-shotLabelNode):not(.react-flow__node-stickyNoteNode):not(.react-flow__node-transitionNode) {\n --node-side: #1f1d18;\n --node-edge: rgba(247, 240, 219, 0.18);\n}\n/* Zoom controls laid out as a 2×2 square (positioned above the Feedback pill\n in JS). Overrides React Flow v12's default flex-column. */\n.react-flow__controls {\n display: grid !important;\n grid-template-columns: repeat(2, 1fr) !important;\n}\n.react-flow__controls button {\n background: var(--bg-elev-2) !important;\n border-color: var(--border-tok) !important;\n color: var(--fg-muted) !important;\n fill: var(--fg-muted) !important;\n}\n.react-flow__controls button:hover {\n background: var(--ink-300) !important;\n}\n.react-flow__edge-path {\n stroke: var(--border-strong);\n}\n\n/* While actively panning a large graph, skip painting the edge layer (the main\n big-graph pan cost). Edges stay mounted — only paint is suppressed — so they\n reappear instantly with no remount when motion stops. See WorkflowCanvas\n markPanning / EDGE_PAN_HIDE_MIN. */\n.react-flow.rf-edges-panning .react-flow__edges {\n display: none;\n}\n\n.react-flow__node.node-controls-locked input,\n.react-flow__node.node-controls-locked textarea,\n.react-flow__node.node-controls-locked select,\n.react-flow__node.node-controls-locked button,\n.react-flow__node.node-controls-locked [role=\"button\"] {\n pointer-events: none !important;\n}\n\n.react-flow__node.node-controls-locked {\n cursor: grab;\n}\n\n.react-flow__node.node-controls-locked:active {\n cursor: grabbing;\n}\n\n.react-flow__node.scene-add-available-node {\n filter: drop-shadow(0 0 10px rgba(247,240,219,0.22));\n}\n\n.react-flow__node.scene-add-available-node > div {\n outline: 1px solid var(--border-strong);\n outline-offset: 4px;\n border-radius: var(--r-3);\n}\n\n.react-flow__node.scene-add-available-node::after {\n content: \"\";\n position: absolute;\n inset: -8px;\n border: 1px dashed var(--border-strong);\n border-radius: var(--r-3);\n pointer-events: none;\n}\n.react-flow__node.node-replace-available {\n filter: drop-shadow(0 0 10px rgba(247,240,219,0.22));\n}\n\n.react-flow__node.node-replace-available > div {\n outline: 1px solid var(--border-strong);\n outline-offset: 4px;\n border-radius: var(--r-3);\n}\n\n.react-flow__node.node-replace-available::after {\n content: \"\";\n position: absolute;\n inset: -8px;\n border: 1px dashed var(--border-strong);\n border-radius: var(--r-3);\n pointer-events: none;\n}\n\nselect option {\n background: var(--bg-elev-2);\n color: var(--fg);\n}\n\n.spinner {\n width: 16px;\n height: 16px;\n border: 2px solid var(--border-tok);\n border-top-color: var(--fg);\n border-radius: var(--r-pill);\n animation: spin 0.7s linear infinite;\n}\n\n.media-upload-preview:hover .media-upload-overlay {\n opacity: 1 !important;\n}\n\n/* Reduced motion — respect it everywhere */\n@media (prefers-reduced-motion: reduce) {\n *, *::before, *::after {\n animation-duration: 1ms !important;\n transition-duration: 1ms !important;\n }\n}\n\n/* All Assets grid: overlay shows on hover via CSS so the parent\n doesn't need a hoveredId state that re-renders the whole list. */\n.assets-card .assets-card-overlay { opacity: 0; transition: opacity 0.15s; }\n.assets-card:hover .assets-card-overlay { opacity: 1; }\n\n/* YouTube hub — Video performance rows: soft accent glow on hover so the rows\n feel clickable. Inset (not outer) shadow because the table clips overflow. */\n.yt-video-row { transition: background 0.12s ease, box-shadow 0.12s ease, color 0.12s ease; }\n.yt-video-row:hover {\n background: var(--hover-wash) !important;\n box-shadow: inset 2px 0 0 var(--accent), inset 0 0 14px var(--accent-glow);\n color: var(--text-primary);\n}\n\n/* Chat bubble text selection — the global ::selection token (which uses\n ink-600 in light mode) collides with the user bubble's dark accent\n background, making highlights invisible. Force the signal/amber color\n here so highlights pop on both user (dark bubble) and assistant\n (cream bubble) regardless of theme. */\n.chat-bubble *::selection { background: var(--signal); color: #0A0A0A; }\n.chat-bubble *::-moz-selection { background: var(--signal); color: #0A0A0A; }\n\n/* Chat bubble copy button — visible on hover/focus, and stays visible\n while the cursor is over the button itself (otherwise moving from\n bubble onto button would hide it before you could click). */\n.chat-bubble:hover .chat-bubble-copy,\n.chat-bubble:focus-within .chat-bubble-copy,\n.chat-bubble-copy:hover,\n.chat-bubble-copy:focus { opacity: 1 !important; }\n/* Subtle hover/active feedback so the user knows it's clickable. */\n.chat-bubble-copy:hover { background: var(--bg-elevated-2, var(--bg-elevated)); color: var(--text-primary) !important; }\n.chat-bubble-copy:active { transform: scale(0.94); }\n\n/* ── StillMade logo lockup — hover animation ──────────────────────────────\n Hovering the top-left lockup turns the isometric cube left-to-right around its\n vertical axis (a 3D rotateY) with a soft currentColor glow; it turns back on\n leave. Reduced-motion users get just a gentle scale + glow, no rotation. */\n.sm-brand .sm-brandmark {\n transform-origin: 50% 50%;\n transition: transform 760ms cubic-bezier(0.2, 0.8, 0.2, 1), filter 280ms ease;\n}\n.sm-brand:hover .sm-brandmark {\n transform: perspective(340px) rotateY(360deg) scale(1.06);\n filter: drop-shadow(0 0 7px color-mix(in srgb, currentColor 45%, transparent));\n will-change: transform, filter;\n}\n/* Wordmark resting position + a subtle lift on hover (a small nudge — gentler\n than the design's). Resting transform lives here (not inline) so :hover can\n override it. */\n.sm-brand .sm-word {\n transform: translate(-4px, 0px);\n transition: transform 300ms cubic-bezier(0.2, 0.8, 0.2, 1);\n}\n.sm-brand:hover .sm-word { transform: translate(-4px, -1px); will-change: transform; }\n@media (prefers-reduced-motion: reduce) {\n .sm-brand .sm-brandmark { transition: transform 240ms ease, filter 240ms ease; }\n .sm-brand:hover .sm-brandmark { transform: scale(1.06); }\n .sm-brand:hover .sm-word { transform: translate(-4px, 0px); }\n}\n\n/* ── Mobile UI ergonomics ───────────────────────────────────────────────────\n Scoped to body.sm-mobile-ui, which App.jsx adds ONLY when the user chose the\n mobile site on a small screen, including a rotated touch phone. Ordinary\n desktop windows and the continue-anyway mode are unaffected.\n\n The app is inline-styled, so these few universal touch fixes are applied here\n once instead of edited into every input across every screen:\n - 16px text fields stop iOS from zooming the page on focus (needs !important\n to beat the inline font sizes).\n - comfortable minimum tap target on buttons/selects. */\nbody.sm-mobile-ui input,\nbody.sm-mobile-ui textarea,\nbody.sm-mobile-ui select {\n font-size: 16px !important;\n}\nbody.sm-mobile-ui button,\nbody.sm-mobile-ui select,\nbody.sm-mobile-ui [role=\"button\"] {\n min-height: 44px;\n}\n/* WebKit can ignore min-height on its native one-line select. Keep the\n physical control touch-sized and let enlarged text make it taller. */\nbody.sm-mobile-ui select:not([multiple]):not([size]) {\n height: max(44px, 2.75em);\n}\n/* Icon-only / chip-sized controls opt out of the min height so dense toolbars\n (timeline, inspector) don't balloon. */\nbody.sm-mobile-ui button.btn-icon,\nbody.sm-mobile-ui button[data-compact],\nbody.sm-mobile-ui .no-min-tap {\n min-height: 0;\n}\n/* YouTube hub analytics rows are dense multi-column grids; keep their columns\n readable and let the table scroll horizontally instead of squishing on a\n phone (the table container is overflow-x:auto). */\nbody.sm-mobile-ui .yt-video-row {\n min-width: 560px;\n}\n\n/* Frame view: the page grows with the screen; StillMade sizes the frame to it. */\nhtml, body, #root { height: auto; overflow: visible; }\n\n/* Stylesheets the screen's components import. */\n/* StillMade media player, photo button and full-screen viewer: option A \"Cream blocks\" (owner, November 2, 2026). Solid cream\n rounded squares with ink icons, a thick cream timeline, the time in the thin italic display face. The chrome sits on the\n picture, so it is the same in Light, Dark and White; the letterbox is ink. Rounded squares only, never circles\n (UI_AESTHETIC \"Icon preference\"). Everything that moves per frame moves by transform; nothing uses backdrop-filter.\n Built by media-player.js (attachMediaPlayer, openMediaViewer, attachPhotoExpand). */\n:where(.sm-player,.sm-viewer,.sm-expand-btn){--sm-cream:var(--cream-100,#F7F0DB);--sm-ink:var(--ink-600,#0A0A0A);--sm-gold:var(--signal,#E8B23A);--sm-out:var(--dur-fast,160ms);--sm-in:var(--dur-base,240ms);--sm-ease:var(--ease-out,cubic-bezier(.22,1,.36,1));--sm-spring:var(--ease-spring,cubic-bezier(.34,1.56,.64,1));--sm-display:var(--font-display,\"Balgin\",\"Hanken Grotesk\",ui-sans-serif,sans-serif)}\n\n/* ---------- The player box: shrinks to the video like a bare <video>; data-fill fills a box the caller sizes ---------- */\n.sm-player{position:relative;display:inline-block;vertical-align:top;max-width:100%;box-sizing:border-box;overflow:hidden;background:var(--sm-ink);color:var(--sm-cream);line-height:1;font-family:var(--font-body,\"Hanken Grotesk\",ui-sans-serif,system-ui,sans-serif);user-select:none;-webkit-user-select:none;-webkit-tap-highlight-color:transparent;touch-action:manipulation;outline:none}\n.sm-player:focus-visible{outline:2px solid var(--sm-gold);outline-offset:2px}\n.sm-player>video{display:block;width:auto;max-width:100%;height:auto;max-height:inherit;margin:0 auto;object-fit:contain;background:transparent}\n.sm-player[data-fill]>video,.sm-player:fullscreen>video,.sm-player[data-stage]>video{width:100%;height:100%;max-width:none;max-height:none}\n.sm-player[data-fill]{display:block}\n.sm-player[data-idle]{cursor:none}\n:where(.sm-stage)>.sm-player{max-width:100%;max-height:100%;border-radius:var(--r-2,4px)}\n\n/* The controls layer covers the picture; only the bar takes the pointer, so a click on the picture reaches the box. */\n.sm-player-ui{position:absolute;inset:0;z-index:1;pointer-events:none}\n.sm-player-shade{position:absolute;left:0;right:0;bottom:0;height:120px;max-height:100%;background:linear-gradient(to top,rgba(10,10,10,.55),rgba(10,10,10,0))}\n.sm-player-bar{position:absolute;left:12px;right:12px;bottom:12px;display:flex;align-items:center;gap:10px;pointer-events:auto}\n.sm-player-shade,.sm-player-bar{transition:opacity var(--sm-in) var(--sm-ease)}\n/* November 2, 2026 (owner): hover only. data-away (no pointer over it, no keyboard focus in it, no recent tap) and data-idle\n (the mouse resting on a playing video) hide them; hidden controls take no pointer, so a tap reaches the picture. */\n.sm-player[data-away] .sm-player-shade,.sm-player[data-away] .sm-player-bar,.sm-player[data-idle] .sm-player-shade,.sm-player[data-idle] .sm-player-bar{opacity:0;pointer-events:none;transition-duration:var(--sm-out)}\n\n/* ---------- Cream squares (player, viewer) ---------- */\n:where(.sm-player,.sm-viewer) .sm-media-btn{appearance:none;-webkit-appearance:none;box-sizing:border-box;flex:none;display:grid;place-items:center;width:44px;height:44px;min-width:0;min-height:0;margin:0;padding:0;border:0;border-radius:var(--r-3,8px);background:var(--sm-cream);color:var(--sm-ink);box-shadow:none;font:inherit;line-height:1;text-decoration:none;cursor:pointer;transition:transform var(--sm-out) var(--sm-spring)}\n:where(.sm-player,.sm-viewer) .sm-media-btn svg{display:block;width:20px;height:20px}\n:is(.sm-player,.sm-viewer) .sm-media-btn.sm-media-btn.sm-media-btn-text{width:auto;padding:0 14px;font-size:14px;font-weight:600}\n/* November 2, 2026: the hover rules restate the cream, so a page's own button:hover (the listing pages, a Block's CSS) never\n washes the squares out. */\n@media (hover:hover){:where(.sm-player,.sm-viewer) .sm-media-btn:hover{transform:translateY(-1px);background:var(--sm-cream);color:var(--sm-ink)}}\n:where(.sm-player,.sm-viewer) .sm-media-btn:active{transform:scale(.94)}\n:is(.sm-player,.sm-viewer) .sm-media-btn.sm-media-btn:focus-visible{outline:2px solid var(--sm-gold);outline-offset:2px;border-radius:var(--r-3,8px)}\n/* November 2, 2026: a container's own button rule outranked the squares and drew them as outlined pills on a Step\n (.bs-step-workspace button:not(.btn-primary) is 0,2,1 and 0,3,1 on hover; .block-playground and .bs-shell buttons). The\n look is restated at 0,3,0, and the cream at 0,4,0 on any hover (a tap leaves :hover on touch); size, place and display\n stay in the rules above, so the narrow-player and viewer rules keep working. */\n:is(.sm-player,.sm-viewer) .sm-media-btn.sm-media-btn{min-width:0;min-height:0;padding:0;border:0;border-radius:var(--r-3,8px);background:var(--sm-cream);color:var(--sm-ink);box-shadow:none;font:inherit;line-height:1;text-decoration:none;cursor:pointer}\n:is(.sm-player,.sm-viewer) .sm-media-btn.sm-media-btn:hover{background:var(--sm-cream);color:var(--sm-ink)}\n.sm-player .sm-player-bar [data-control=\"fullscreen\"]{margin-left:auto}\n\n/* ---------- Volume (owner, November 2, 2026): a vertical cream line above the sound button, shown while the button or the line\n is hovered or focused, or while it is dragged; the same track, fill and square knob as the timeline. Mouse only. ---------- */\n.sm-player-sound{position:relative;display:flex;flex:none}\n.sm-player-volume{position:absolute;left:50%;bottom:100%;padding-bottom:10px;opacity:0;pointer-events:none;transform:translate(-50%,6px);transition:opacity var(--sm-out) var(--sm-ease),transform var(--sm-out) var(--sm-ease)}\n.sm-player-sound:hover .sm-player-volume,.sm-player-sound:focus-within .sm-player-volume,.sm-player-volume[data-drag]{opacity:1;pointer-events:auto;transform:translate(-50%,0);transition-duration:var(--sm-in)}\n.sm-player-volume-rail{position:relative;box-sizing:border-box;width:44px;height:128px;padding:14px 0;border-radius:var(--r-3,8px);background:rgba(10,10,10,.64);cursor:pointer;touch-action:none;outline:none}\n.sm-player-volume-rail:focus-visible{outline:2px solid var(--sm-gold);outline-offset:2px}\n.sm-player-volume-track{position:relative;width:6px;height:100%;margin:0 auto;border-radius:3px;background:rgba(247,240,219,.28);overflow:visible}\n.sm-player-volume-level{position:absolute;inset:0;border-radius:3px;background:var(--sm-cream);transform-origin:center bottom;transform:scaleY(1)}\n.sm-player-volume-head{position:absolute;inset:0;pointer-events:none;transform:translateY(-100%)}\n.sm-player-volume-knob{position:absolute;left:50%;bottom:0;width:16px;height:16px;margin:0 0 -8px -8px;border-radius:4px;background:var(--sm-cream);box-shadow:0 0 0 3px rgba(10,10,10,.35)}\n.sm-player-volume[data-drag] .sm-player-volume-head{will-change:transform}\n/* The player box clips, and the line opens 194 px above its bottom: under 200 px tall it is shorter, under 150 px it stays\n closed and the button only mutes (data-volume-room, measured by the player's ResizeObserver). */\n.sm-player[data-volume-room=\"short\"] .sm-player-volume-rail{height:84px;padding:12px 0}\n.sm-player[data-volume-room=\"none\"] .sm-player-volume{display:none}\n@media (hover:none){.sm-player-volume{display:none}}\n\n/* ---------- Timeline: 24 px to point at, a 6 px track that grows, a cream square knob, the time under the pointer ---------- */\n.sm-player-rail{position:relative;flex:1 1 auto;min-width:48px;height:24px;cursor:pointer;touch-action:none;outline:none}\n.sm-player-rail:focus-visible{outline:2px solid var(--sm-gold);outline-offset:2px;border-radius:var(--r-2,4px)}\n.sm-player-track{position:absolute;left:0;right:0;top:50%;height:6px;margin-top:-3px;border-radius:3px;background:rgba(247,240,219,.28);overflow:hidden;transition:transform var(--sm-out) var(--sm-ease)}\n.sm-player-buffered,.sm-player-played{position:absolute;inset:0;transform-origin:left center;transform:scaleX(0)}\n.sm-player-buffered{background:rgba(247,240,219,.18)}\n.sm-player-played{background:var(--sm-cream)}\n.sm-player-head{position:absolute;inset:0;pointer-events:none;transform:translateX(0)}\n.sm-player[data-playing] .sm-player-head,.sm-player[data-playing] .sm-player-played,.sm-player-rail[data-drag] .sm-player-head{will-change:transform}\n.sm-player-knob{position:absolute;top:50%;left:0;width:16px;height:16px;margin:-8px 0 0 -8px;border-radius:4px;background:var(--sm-cream);box-shadow:0 0 0 3px rgba(10,10,10,.35);transform:scale(0);transition:transform var(--sm-out) var(--sm-spring)}\n.sm-player-rail:hover .sm-player-knob,.sm-player-rail[data-drag] .sm-player-knob,.sm-player-rail:focus-visible .sm-player-knob{transform:scale(1)}\n.sm-player-rail:hover .sm-player-track,.sm-player-rail[data-drag] .sm-player-track{transform:scaleY(1.34)}\n.sm-player-tip{position:absolute;bottom:calc(100% + 4px);left:0;padding:3px 7px;border-radius:var(--r-2,4px);background:var(--sm-ink);border:1px solid rgba(247,240,219,.14);color:var(--sm-cream);font-size:12px;font-weight:500;font-variant-numeric:tabular-nums;white-space:nowrap;opacity:0;pointer-events:none;transition:opacity var(--sm-out) var(--sm-ease)}\n.sm-player-rail:hover .sm-player-tip,.sm-player-rail[data-drag] .sm-player-tip{opacity:1}\n\n/* ---------- Time: \"0:12 / 0:34\", the total at 55% ---------- */\n.sm-player-time{flex:none;font-family:var(--sm-display);font-style:italic;font-weight:200;font-size:22px;line-height:1;letter-spacing:-.01em;font-variant-numeric:tabular-nums;white-space:nowrap;color:var(--sm-cream);text-shadow:0 1px 8px rgba(10,10,10,.6)}\n:where(.sm-player,.sm-viewer) .sm-media-of{opacity:.55}\n\n/* ---------- Narrow players step down by measured width so the bar never overflows (November 2, 2026: a 320 px vertical\n result clipped full screen): under 400 px no total and a smaller clock, under 300 px no clock, under 240 px no sound,\n under 180 px only play and full screen. The timeline keeps at least 48 px. ---------- */\n.sm-player[data-size] .sm-player-bar{gap:8px}\n.sm-player[data-size] .sm-player-total{display:none}\n.sm-player[data-size] .sm-player-time{font-size:18px}\n.sm-player:is([data-size=\"compact\"],[data-size=\"tiny\"],[data-size=\"micro\"]) .sm-player-time{display:none}\n.sm-player:is([data-size=\"tiny\"],[data-size=\"micro\"]) [data-control=\"volume\"]{display:none}\n.sm-player[data-size=\"micro\"] .sm-player-bar>:not([data-control=\"play\"]):not([data-control=\"fullscreen\"]){display:none}\n\n/* ---------- Touch: 44 px targets ---------- */\n@media (hover:none){.sm-player-rail{height:44px}}\n\n/* ---------- Full screen, and theater mode where the page may not go full screen (top layer, safe areas) ---------- */\n.sm-player:fullscreen{width:100%;height:100%;max-width:none;max-height:none;border-radius:0}\n.sm-player[data-stage=\"theater\"]{position:fixed;inset:0;z-index:2147483000;display:block;width:auto;height:auto;max-width:none;max-height:none;margin:0;border:0;border-radius:0;padding:env(safe-area-inset-top,0px) env(safe-area-inset-right,0px) env(safe-area-inset-bottom,0px) env(safe-area-inset-left,0px);overflow:hidden;color:var(--sm-cream);background:var(--sm-ink)}\n.sm-player[data-stage=\"theater\"]::backdrop{background:var(--sm-ink)}\n.sm-player:fullscreen .sm-player-bar,.sm-player[data-stage] .sm-player-bar{left:max(12px,env(safe-area-inset-left,0px));right:max(12px,env(safe-area-inset-right,0px));bottom:max(12px,env(safe-area-inset-bottom,0px))}\n\n/* ---------- Photo button: the video's full-screen square in the same corner, bottom right. 44 px on photos at least 240 px\n wide, 32 px under that (data-size=\"small\"). Shown only while the photo is hovered or the button has keyboard focus, and for\n 3 s after a tap on touch (data-show); hidden, it takes no pointer, so the first tap lands on the photo. ---------- */\n.sm-expand-host{position:relative}\n.sm-expand-btn{position:absolute;right:12px;bottom:12px;z-index:2;box-sizing:border-box;display:grid;place-items:center;width:44px;height:44px;min-width:0;min-height:0;margin:0;padding:0;border:0;border-radius:var(--r-3,8px);background:var(--sm-cream);color:var(--sm-ink);box-shadow:none;line-height:1;cursor:pointer;opacity:0;pointer-events:none;transition:opacity var(--sm-out) var(--sm-ease),transform var(--sm-out) var(--sm-spring)}\n.sm-expand-btn svg{display:block;width:20px;height:20px}\n.sm-expand-btn[data-size=\"small\"]{right:6px;bottom:6px;width:32px;height:32px;border-radius:6px}\n.sm-expand-btn[data-size=\"small\"] svg{width:16px;height:16px}\n.sm-expand-btn[data-size=\"small\"]::before{content:\"\";position:absolute;inset:-6px}\n@media (hover:hover){:hover>.sm-expand-btn{opacity:1;pointer-events:auto}.sm-expand-btn:hover{transform:translateY(-1px);background:var(--sm-cream);color:var(--sm-ink)}}\n.sm-expand-btn:focus-visible,.sm-expand-btn[data-show]{opacity:1;pointer-events:auto}\n.sm-expand-btn:active{transform:scale(.94)}\n.sm-expand-btn.sm-expand-btn.sm-expand-btn:focus-visible{outline:2px solid var(--sm-gold);outline-offset:2px}\n/* The same guard as the squares above (November 2, 2026): the look at 0,3,0 and 0,4,0, never position, size or display. */\n.sm-expand-btn.sm-expand-btn.sm-expand-btn{min-width:0;min-height:0;padding:0;border:0;border-radius:var(--r-3,8px);background:var(--sm-cream);color:var(--sm-ink);box-shadow:none;font:inherit;line-height:1;cursor:pointer}\n.sm-expand-btn.sm-expand-btn.sm-expand-btn[data-size=\"small\"]{border-radius:6px}\n.sm-expand-btn.sm-expand-btn.sm-expand-btn:hover{background:var(--sm-cream);color:var(--sm-ink)}\n\n/* ---------- Viewer: a modal dialog on ink, the photo contained, cream squares to close and move ---------- */\n.sm-viewer{position:fixed;inset:0;box-sizing:border-box;width:100%;height:100%;max-width:none;max-height:none;margin:0;padding:0;border:0;overflow:hidden;background:var(--sm-ink);color:var(--sm-cream);font-family:var(--font-body,\"Hanken Grotesk\",ui-sans-serif,system-ui,sans-serif)}\n.sm-viewer[open]{display:grid;grid-template-rows:minmax(0,1fr) auto;animation:sm-viewer-in var(--sm-in) var(--sm-ease) both}\n.sm-viewer::backdrop{background:var(--ink-600,#0A0A0A)}\n@keyframes sm-viewer-in{from{opacity:0}}\n.sm-viewer [hidden],.sm-viewer .sm-media-btn[hidden]{display:none}\n.sm-viewer-stage{position:relative;display:grid;grid-template:minmax(0,1fr)/minmax(0,1fr);place-items:center;min-width:0;min-height:0;overflow:hidden;padding:max(12px,env(safe-area-inset-top,0px)) max(12px,env(safe-area-inset-right,0px)) 12px max(12px,env(safe-area-inset-left,0px))}\n/* The stage is one 1fr cell, so the photo is held to the screen in both directions (November 2, 2026: it ran off the bottom). */\n.sm-viewer-media{display:block;width:100%;height:100%;min-width:0;min-height:0;object-fit:contain}\n.sm-viewer-stage>.sm-player{width:100%;height:100%;max-width:100%;max-height:100%}\n/* What cannot open here (a file kept on another device) is a quiet tile with no words (November 2, 2026: \"notices, not\n prose\"); the app's single toast says why. */\n.sm-viewer-off,.sm-player-off{display:inline-grid;place-items:center;box-sizing:border-box;border:1px solid var(--border-tok,#58534D);border-radius:var(--r-2,4px);background:var(--bg-inset,#171716);color:var(--fg-muted,#BBB2A7)}\n.sm-viewer-off{width:min(60vw,320px);aspect-ratio:4/3}\n.sm-player-off{width:min(100%,320px);max-width:100%;aspect-ratio:16/9;vertical-align:top}\n.sm-viewer-off svg,.sm-player-off svg{display:block;width:24px;height:24px}\n.sm-viewer-top{position:absolute;top:max(12px,env(safe-area-inset-top,0px));right:max(12px,env(safe-area-inset-right,0px));z-index:2;display:flex;gap:10px}\n.sm-viewer .sm-viewer-nav{position:absolute;top:50%;margin-top:-22px;z-index:2}\n.sm-viewer .sm-viewer-previous{left:max(12px,env(safe-area-inset-left,0px))}\n.sm-viewer .sm-viewer-next{right:max(12px,env(safe-area-inset-right,0px))}\n.sm-viewer-foot{display:flex;align-items:baseline;justify-content:center;gap:12px;min-width:0;padding:12px max(12px,env(safe-area-inset-right,0px)) max(14px,env(safe-area-inset-bottom,0px)) max(12px,env(safe-area-inset-left,0px))}\n.sm-viewer-count{flex:none;font-family:var(--sm-display);font-style:italic;font-weight:200;font-size:24px;line-height:1;letter-spacing:-.01em;font-variant-numeric:tabular-nums;white-space:nowrap}\n.sm-viewer-name{min-width:0;font-size:13px;color:var(--fg-muted,#BBB2A7);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}\n\n@media (prefers-reduced-motion:reduce){\n .sm-player *,.sm-viewer,.sm-viewer *,.sm-expand-btn{transition:none!important;animation:none!important}\n}\n",
180
+ "javascript": "(function(){var e=Object.create,t=Object.defineProperty,n=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,i=Object.getPrototypeOf,a=Object.prototype.hasOwnProperty,o=(e,t,n)=>()=>{if(n)throw n[0];try{return e&&(t=e(e=0)),t}catch(e){throw n=[e],e}},s=(e,t)=>()=>(t||(e((t={exports:{}}).exports,t),e=null),t.exports),c=(e,n)=>{let r={};for(var i in e)t(r,i,{get:e[i],enumerable:!0});return n||t(r,Symbol.toStringTag,{value:`Module`}),r},l=(e,i,o,s)=>{if(i&&typeof i==`object`||typeof i==`function`)for(var c=r(i),l=0,u=c.length,d;l<u;l++)d=c[l],!a.call(e,d)&&d!==o&&t(e,d,{get:(e=>i[e]).bind(null,d),enumerable:!(s=n(i,d))||s.enumerable});return e},u=(n,r,o)=>(o=n==null?{}:e(i(n)),l(r||!n||!n.__esModule||!a.call(n,`default`)?t(o,`default`,{value:n,enumerable:!0}):o,n)),d=s((e=>{var t=Symbol.for(`react.element`),n=Symbol.for(`react.portal`),r=Symbol.for(`react.fragment`),i=Symbol.for(`react.strict_mode`),a=Symbol.for(`react.profiler`),o=Symbol.for(`react.provider`),s=Symbol.for(`react.context`),c=Symbol.for(`react.forward_ref`),l=Symbol.for(`react.suspense`),u=Symbol.for(`react.memo`),d=Symbol.for(`react.lazy`),f=Symbol.iterator;function p(e){return typeof e!=`object`||!e?null:(e=f&&e[f]||e[`@@iterator`],typeof e==`function`?e:null)}var m={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},h=Object.assign,g={};function _(e,t,n){this.props=e,this.context=t,this.refs=g,this.updater=n||m}_.prototype.isReactComponent={},_.prototype.setState=function(e,t){if(typeof e!=`object`&&typeof e!=`function`&&e!=null)throw Error(`setState(...): takes an object of state variables to update or a function which returns an object of state variables.`);this.updater.enqueueSetState(this,e,t,`setState`)},_.prototype.forceUpdate=function(e){this.updater.enqueueForceUpdate(this,e,`forceUpdate`)};function v(){}v.prototype=_.prototype;function y(e,t,n){this.props=e,this.context=t,this.refs=g,this.updater=n||m}var b=y.prototype=new v;b.constructor=y,h(b,_.prototype),b.isPureReactComponent=!0;var x=Array.isArray,S=Object.prototype.hasOwnProperty,C={current:null},w={key:!0,ref:!0,__self:!0,__source:!0};function T(e,n,r){var i,a={},o=null,s=null;if(n!=null)for(i in n.ref!==void 0&&(s=n.ref),n.key!==void 0&&(o=``+n.key),n)S.call(n,i)&&!w.hasOwnProperty(i)&&(a[i]=n[i]);var c=arguments.length-2;if(c===1)a.children=r;else if(1<c){for(var l=Array(c),u=0;u<c;u++)l[u]=arguments[u+2];a.children=l}if(e&&e.defaultProps)for(i in c=e.defaultProps,c)a[i]===void 0&&(a[i]=c[i]);return{$$typeof:t,type:e,key:o,ref:s,props:a,_owner:C.current}}function E(e,n){return{$$typeof:t,type:e.type,key:n,ref:e.ref,props:e.props,_owner:e._owner}}function D(e){return typeof e==`object`&&!!e&&e.$$typeof===t}function O(e){var t={\"=\":`=0`,\":\":`=2`};return`$`+e.replace(/[=:]/g,function(e){return t[e]})}var k=/\\/+/g;function A(e,t){return typeof e==`object`&&e&&e.key!=null?O(``+e.key):t.toString(36)}function j(e,r,i,a,o){var s=typeof e;(s===`undefined`||s===`boolean`)&&(e=null);var c=!1;if(e===null)c=!0;else switch(s){case`string`:case`number`:c=!0;break;case`object`:switch(e.$$typeof){case t:case n:c=!0}}if(c)return c=e,o=o(c),e=a===``?`.`+A(c,0):a,x(o)?(i=``,e!=null&&(i=e.replace(k,`$&/`)+`/`),j(o,r,i,``,function(e){return e})):o!=null&&(D(o)&&(o=E(o,i+(!o.key||c&&c.key===o.key?``:(``+o.key).replace(k,`$&/`)+`/`)+e)),r.push(o)),1;if(c=0,a=a===``?`.`:a+`:`,x(e))for(var l=0;l<e.length;l++){s=e[l];var u=a+A(s,l);c+=j(s,r,i,u,o)}else if(u=p(e),typeof u==`function`)for(e=u.call(e),l=0;!(s=e.next()).done;)s=s.value,u=a+A(s,l++),c+=j(s,r,i,u,o);else if(s===`object`)throw r=String(e),Error(`Objects are not valid as a React child (found: `+(r===`[object Object]`?`object with keys {`+Object.keys(e).join(`, `)+`}`:r)+`). If you meant to render a collection of children, use an array instead.`);return c}function M(e,t,n){if(e==null)return e;var r=[],i=0;return j(e,r,``,``,function(e){return t.call(n,e,i++)}),r}function ee(e){if(e._status===-1){var t=e._result;t=t(),t.then(function(t){(e._status===0||e._status===-1)&&(e._status=1,e._result=t)},function(t){(e._status===0||e._status===-1)&&(e._status=2,e._result=t)}),e._status===-1&&(e._status=0,e._result=t)}if(e._status===1)return e._result.default;throw e._result}var N={current:null},P={transition:null},te={ReactCurrentDispatcher:N,ReactCurrentBatchConfig:P,ReactCurrentOwner:C};function ne(){throw Error(`act(...) is not supported in production builds of React.`)}e.Children={map:M,forEach:function(e,t,n){M(e,function(){t.apply(this,arguments)},n)},count:function(e){var t=0;return M(e,function(){t++}),t},toArray:function(e){return M(e,function(e){return e})||[]},only:function(e){if(!D(e))throw Error(`React.Children.only expected to receive a single React element child.`);return e}},e.Component=_,e.Fragment=r,e.Profiler=a,e.PureComponent=y,e.StrictMode=i,e.Suspense=l,e.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED=te,e.act=ne,e.cloneElement=function(e,n,r){if(e==null)throw Error(`React.cloneElement(...): The argument must be a React element, but you passed `+e+`.`);var i=h({},e.props),a=e.key,o=e.ref,s=e._owner;if(n!=null){if(n.ref!==void 0&&(o=n.ref,s=C.current),n.key!==void 0&&(a=``+n.key),e.type&&e.type.defaultProps)var c=e.type.defaultProps;for(l in n)S.call(n,l)&&!w.hasOwnProperty(l)&&(i[l]=n[l]===void 0&&c!==void 0?c[l]:n[l])}var l=arguments.length-2;if(l===1)i.children=r;else if(1<l){c=Array(l);for(var u=0;u<l;u++)c[u]=arguments[u+2];i.children=c}return{$$typeof:t,type:e.type,key:a,ref:o,props:i,_owner:s}},e.createContext=function(e){return e={$$typeof:s,_currentValue:e,_currentValue2:e,_threadCount:0,Provider:null,Consumer:null,_defaultValue:null,_globalName:null},e.Provider={$$typeof:o,_context:e},e.Consumer=e},e.createElement=T,e.createFactory=function(e){var t=T.bind(null,e);return t.type=e,t},e.createRef=function(){return{current:null}},e.forwardRef=function(e){return{$$typeof:c,render:e}},e.isValidElement=D,e.lazy=function(e){return{$$typeof:d,_payload:{_status:-1,_result:e},_init:ee}},e.memo=function(e,t){return{$$typeof:u,type:e,compare:t===void 0?null:t}},e.startTransition=function(e){var t=P.transition;P.transition={};try{e()}finally{P.transition=t}},e.unstable_act=ne,e.useCallback=function(e,t){return N.current.useCallback(e,t)},e.useContext=function(e){return N.current.useContext(e)},e.useDebugValue=function(){},e.useDeferredValue=function(e){return N.current.useDeferredValue(e)},e.useEffect=function(e,t){return N.current.useEffect(e,t)},e.useId=function(){return N.current.useId()},e.useImperativeHandle=function(e,t,n){return N.current.useImperativeHandle(e,t,n)},e.useInsertionEffect=function(e,t){return N.current.useInsertionEffect(e,t)},e.useLayoutEffect=function(e,t){return N.current.useLayoutEffect(e,t)},e.useMemo=function(e,t){return N.current.useMemo(e,t)},e.useReducer=function(e,t,n){return N.current.useReducer(e,t,n)},e.useRef=function(e){return N.current.useRef(e)},e.useState=function(e){return N.current.useState(e)},e.useSyncExternalStore=function(e,t,n){return N.current.useSyncExternalStore(e,t,n)},e.useTransition=function(){return N.current.useTransition()},e.version=`18.3.1`})),f=s(((e,t)=>{t.exports=d()})),p=s((e=>{function t(e,t){var n=e.length;e.push(t);a:for(;0<n;){var r=n-1>>>1,a=e[r];if(0<i(a,t))e[r]=t,e[n]=a,n=r;else break a}}function n(e){return e.length===0?null:e[0]}function r(e){if(e.length===0)return null;var t=e[0],n=e.pop();if(n!==t){e[0]=n;a:for(var r=0,a=e.length,o=a>>>1;r<o;){var s=2*(r+1)-1,c=e[s],l=s+1,u=e[l];if(0>i(c,n))l<a&&0>i(u,c)?(e[r]=u,e[l]=n,r=l):(e[r]=c,e[s]=n,r=s);else if(l<a&&0>i(u,n))e[r]=u,e[l]=n,r=l;else break a}}return t}function i(e,t){var n=e.sortIndex-t.sortIndex;return n===0?e.id-t.id:n}if(typeof performance==`object`&&typeof performance.now==`function`){var a=performance;e.unstable_now=function(){return a.now()}}else{var o=Date,s=o.now();e.unstable_now=function(){return o.now()-s}}var c=[],l=[],u=1,d=null,f=3,p=!1,m=!1,h=!1,g=typeof setTimeout==`function`?setTimeout:null,_=typeof clearTimeout==`function`?clearTimeout:null,v=typeof setImmediate<`u`?setImmediate:null;typeof navigator<`u`&&navigator.scheduling!==void 0&&navigator.scheduling.isInputPending!==void 0&&navigator.scheduling.isInputPending.bind(navigator.scheduling);function y(e){for(var i=n(l);i!==null;){if(i.callback===null)r(l);else if(i.startTime<=e)r(l),i.sortIndex=i.expirationTime,t(c,i);else break;i=n(l)}}function b(e){if(h=!1,y(e),!m){if(n(c)!==null)m=!0,M(x);else{var t=n(l);t!==null&&ee(b,t.startTime-e)}}}function x(t,i){m=!1,h&&(h=!1,_(w),w=-1),p=!0;var a=f;try{for(y(i),d=n(c);d!==null&&(!(d.expirationTime>i)||t&&!D());){var o=d.callback;if(typeof o==`function`){d.callback=null,f=d.priorityLevel;var s=o(d.expirationTime<=i);i=e.unstable_now(),typeof s==`function`?d.callback=s:d===n(c)&&r(c),y(i)}else r(c);d=n(c)}if(d!==null)var u=!0;else{var g=n(l);g!==null&&ee(b,g.startTime-i),u=!1}return u}finally{d=null,f=a,p=!1}}var S=!1,C=null,w=-1,T=5,E=-1;function D(){return!(e.unstable_now()-E<T)}function O(){if(C!==null){var t=e.unstable_now();E=t;var n=!0;try{n=C(!0,t)}finally{n?k():(S=!1,C=null)}}else S=!1}var k;if(typeof v==`function`)k=function(){v(O)};else if(typeof MessageChannel<`u`){var A=new MessageChannel,j=A.port2;A.port1.onmessage=O,k=function(){j.postMessage(null)}}else k=function(){g(O,0)};function M(e){C=e,S||(S=!0,k())}function ee(t,n){w=g(function(){t(e.unstable_now())},n)}e.unstable_IdlePriority=5,e.unstable_ImmediatePriority=1,e.unstable_LowPriority=4,e.unstable_NormalPriority=3,e.unstable_Profiling=null,e.unstable_UserBlockingPriority=2,e.unstable_cancelCallback=function(e){e.callback=null},e.unstable_continueExecution=function(){m||p||(m=!0,M(x))},e.unstable_forceFrameRate=function(e){0>e||125<e?console.error(`forceFrameRate takes a positive int between 0 and 125, forcing frame rates higher than 125 fps is not supported`):T=0<e?Math.floor(1e3/e):5},e.unstable_getCurrentPriorityLevel=function(){return f},e.unstable_getFirstCallbackNode=function(){return n(c)},e.unstable_next=function(e){switch(f){case 1:case 2:case 3:var t=3;break;default:t=f}var n=f;f=t;try{return e()}finally{f=n}},e.unstable_pauseExecution=function(){},e.unstable_requestPaint=function(){},e.unstable_runWithPriority=function(e,t){switch(e){case 1:case 2:case 3:case 4:case 5:break;default:e=3}var n=f;f=e;try{return t()}finally{f=n}},e.unstable_scheduleCallback=function(r,i,a){var o=e.unstable_now();switch(typeof a==`object`&&a?(a=a.delay,a=typeof a==`number`&&0<a?o+a:o):a=o,r){case 1:var s=-1;break;case 2:s=250;break;case 5:s=1073741823;break;case 4:s=1e4;break;default:s=5e3}return s=a+s,r={id:u++,callback:i,priorityLevel:r,startTime:a,expirationTime:s,sortIndex:-1},a>o?(r.sortIndex=a,t(l,r),n(c)===null&&r===n(l)&&(h?(_(w),w=-1):h=!0,ee(b,a-o))):(r.sortIndex=s,t(c,r),m||p||(m=!0,M(x))),r},e.unstable_shouldYield=D,e.unstable_wrapCallback=function(e){var t=f;return function(){var n=f;f=t;try{return e.apply(this,arguments)}finally{f=n}}}})),m=s(((e,t)=>{t.exports=p()})),h=s((e=>{var t=f(),n=m();function r(e){for(var t=`https://reactjs.org/docs/error-decoder.html?invariant=`+e,n=1;n<arguments.length;n++)t+=`&args[]=`+encodeURIComponent(arguments[n]);return`Minified React error #`+e+`; visit `+t+` for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`}var i=new Set,a={};function o(e,t){s(e,t),s(e+`Capture`,t)}function s(e,t){for(a[e]=t,e=0;e<t.length;e++)i.add(t[e])}var c=!(typeof window>`u`||window.document===void 0||window.document.createElement===void 0),l=Object.prototype.hasOwnProperty,u=/^[:A-Z_a-z\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02FF\\u0370-\\u037D\\u037F-\\u1FFF\\u200C-\\u200D\\u2070-\\u218F\\u2C00-\\u2FEF\\u3001-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFFD][:A-Z_a-z\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02FF\\u0370-\\u037D\\u037F-\\u1FFF\\u200C-\\u200D\\u2070-\\u218F\\u2C00-\\u2FEF\\u3001-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFFD\\-.0-9\\u00B7\\u0300-\\u036F\\u203F-\\u2040]*$/,d={},p={};function h(e){return l.call(p,e)?!0:l.call(d,e)?!1:u.test(e)?p[e]=!0:(d[e]=!0,!1)}function g(e,t,n,r){if(n!==null&&n.type===0)return!1;switch(typeof t){case`function`:case`symbol`:return!0;case`boolean`:return r?!1:n===null?(e=e.toLowerCase().slice(0,5),e!==`data-`&&e!==`aria-`):!n.acceptsBooleans;default:return!1}}function _(e,t,n,r){if(t==null||g(e,t,n,r))return!0;if(r)return!1;if(n!==null)switch(n.type){case 3:return!t;case 4:return!1===t;case 5:return isNaN(t);case 6:return isNaN(t)||1>t}return!1}function v(e,t,n,r,i,a,o){this.acceptsBooleans=t===2||t===3||t===4,this.attributeName=r,this.attributeNamespace=i,this.mustUseProperty=n,this.propertyName=e,this.type=t,this.sanitizeURL=a,this.removeEmptyString=o}var y={};`children dangerouslySetInnerHTML defaultValue defaultChecked innerHTML suppressContentEditableWarning suppressHydrationWarning style`.split(` `).forEach(function(e){y[e]=new v(e,0,!1,e,null,!1,!1)}),[[`acceptCharset`,`accept-charset`],[`className`,`class`],[`htmlFor`,`for`],[`httpEquiv`,`http-equiv`]].forEach(function(e){var t=e[0];y[t]=new v(t,1,!1,e[1],null,!1,!1)}),[`contentEditable`,`draggable`,`spellCheck`,`value`].forEach(function(e){y[e]=new v(e,2,!1,e.toLowerCase(),null,!1,!1)}),[`autoReverse`,`externalResourcesRequired`,`focusable`,`preserveAlpha`].forEach(function(e){y[e]=new v(e,2,!1,e,null,!1,!1)}),`allowFullScreen async autoFocus autoPlay controls default defer disabled disablePictureInPicture disableRemotePlayback formNoValidate hidden loop noModule noValidate open playsInline readOnly required reversed scoped seamless itemScope`.split(` `).forEach(function(e){y[e]=new v(e,3,!1,e.toLowerCase(),null,!1,!1)}),[`checked`,`multiple`,`muted`,`selected`].forEach(function(e){y[e]=new v(e,3,!0,e,null,!1,!1)}),[`capture`,`download`].forEach(function(e){y[e]=new v(e,4,!1,e,null,!1,!1)}),[`cols`,`rows`,`size`,`span`].forEach(function(e){y[e]=new v(e,6,!1,e,null,!1,!1)}),[`rowSpan`,`start`].forEach(function(e){y[e]=new v(e,5,!1,e.toLowerCase(),null,!1,!1)});var b=/[\\-:]([a-z])/g;function x(e){return e[1].toUpperCase()}`accent-height alignment-baseline arabic-form baseline-shift cap-height clip-path clip-rule color-interpolation color-interpolation-filters color-profile color-rendering dominant-baseline enable-background fill-opacity fill-rule flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-name glyph-orientation-horizontal glyph-orientation-vertical horiz-adv-x horiz-origin-x image-rendering letter-spacing lighting-color marker-end marker-mid marker-start overline-position overline-thickness paint-order panose-1 pointer-events rendering-intent shape-rendering stop-color stop-opacity strikethrough-position strikethrough-thickness stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width text-anchor text-decoration text-rendering underline-position underline-thickness unicode-bidi unicode-range units-per-em v-alphabetic v-hanging v-ideographic v-mathematical vector-effect vert-adv-y vert-origin-x vert-origin-y word-spacing writing-mode xmlns:xlink x-height`.split(` `).forEach(function(e){var t=e.replace(b,x);y[t]=new v(t,1,!1,e,null,!1,!1)}),`xlink:actuate xlink:arcrole xlink:role xlink:show xlink:title xlink:type`.split(` `).forEach(function(e){var t=e.replace(b,x);y[t]=new v(t,1,!1,e,`http://www.w3.org/1999/xlink`,!1,!1)}),[`xml:base`,`xml:lang`,`xml:space`].forEach(function(e){var t=e.replace(b,x);y[t]=new v(t,1,!1,e,`http://www.w3.org/XML/1998/namespace`,!1,!1)}),[`tabIndex`,`crossOrigin`].forEach(function(e){y[e]=new v(e,1,!1,e.toLowerCase(),null,!1,!1)}),y.xlinkHref=new v(`xlinkHref`,1,!1,`xlink:href`,`http://www.w3.org/1999/xlink`,!0,!1),[`src`,`href`,`action`,`formAction`].forEach(function(e){y[e]=new v(e,1,!1,e.toLowerCase(),null,!0,!0)});function S(e,t,n,r){var i=y.hasOwnProperty(t)?y[t]:null;(i===null?r||!(2<t.length)||t[0]!==`o`&&t[0]!==`O`||t[1]!==`n`&&t[1]!==`N`:i.type!==0)&&(_(t,n,i,r)&&(n=null),r||i===null?h(t)&&(n===null?e.removeAttribute(t):e.setAttribute(t,``+n)):i.mustUseProperty?e[i.propertyName]=n===null?i.type!==3&&``:n:(t=i.attributeName,r=i.attributeNamespace,n===null?e.removeAttribute(t):(i=i.type,n=i===3||i===4&&!0===n?``:``+n,r?e.setAttributeNS(r,t,n):e.setAttribute(t,n))))}var C=t.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED,w=Symbol.for(`react.element`),T=Symbol.for(`react.portal`),E=Symbol.for(`react.fragment`),D=Symbol.for(`react.strict_mode`),O=Symbol.for(`react.profiler`),k=Symbol.for(`react.provider`),A=Symbol.for(`react.context`),j=Symbol.for(`react.forward_ref`),M=Symbol.for(`react.suspense`),ee=Symbol.for(`react.suspense_list`),N=Symbol.for(`react.memo`),P=Symbol.for(`react.lazy`),te=Symbol.for(`react.offscreen`),ne=Symbol.iterator;function re(e){return typeof e!=`object`||!e?null:(e=ne&&e[ne]||e[`@@iterator`],typeof e==`function`?e:null)}var F=Object.assign,I;function L(e){if(I===void 0)try{throw Error()}catch(e){var t=e.stack.trim().match(/\\n( *(at )?)/);I=t&&t[1]||``}return`\n`+I+e}var R=!1;function z(e,t){if(!e||R)return``;R=!0;var n=Error.prepareStackTrace;Error.prepareStackTrace=void 0;try{if(t){if(t=function(){throw Error()},Object.defineProperty(t.prototype,\"props\",{set:function(){throw Error()}}),typeof Reflect==`object`&&Reflect.construct){try{Reflect.construct(t,[])}catch(e){var r=e}Reflect.construct(e,[],t)}else{try{t.call()}catch(e){r=e}e.call(t.prototype)}}else{try{throw Error()}catch(e){r=e}e()}}catch(t){if(t&&r&&typeof t.stack==`string`){for(var i=t.stack.split(`\n`),a=r.stack.split(`\n`),o=i.length-1,s=a.length-1;1<=o&&0<=s&&i[o]!==a[s];)s--;for(;1<=o&&0<=s;o--,s--)if(i[o]!==a[s]){if(o!==1||s!==1)do if(o--,s--,0>s||i[o]!==a[s]){var c=`\n`+i[o].replace(` at new `,` at `);return e.displayName&&c.includes(`<anonymous>`)&&(c=c.replace(`<anonymous>`,e.displayName)),c}while(1<=o&&0<=s);break}}}finally{R=!1,Error.prepareStackTrace=n}return(e=e?e.displayName||e.name:``)?L(e):``}function ie(e){switch(e.tag){case 5:return L(e.type);case 16:return L(`Lazy`);case 13:return L(`Suspense`);case 19:return L(`SuspenseList`);case 0:case 2:case 15:return e=z(e.type,!1),e;case 11:return e=z(e.type.render,!1),e;case 1:return e=z(e.type,!0),e;default:return``}}function ae(e){if(e==null)return null;if(typeof e==`function`)return e.displayName||e.name||null;if(typeof e==`string`)return e;switch(e){case E:return`Fragment`;case T:return`Portal`;case O:return`Profiler`;case D:return`StrictMode`;case M:return`Suspense`;case ee:return`SuspenseList`}if(typeof e==`object`)switch(e.$$typeof){case A:return(e.displayName||`Context`)+`.Consumer`;case k:return(e._context.displayName||`Context`)+`.Provider`;case j:var t=e.render;return e=e.displayName,e||=(e=t.displayName||t.name||``,e===``?`ForwardRef`:`ForwardRef(`+e+`)`),e;case N:return t=e.displayName||null,t===null?ae(e.type)||`Memo`:t;case P:t=e._payload,e=e._init;try{return ae(e(t))}catch{}}return null}function oe(e){var t=e.type;switch(e.tag){case 24:return`Cache`;case 9:return(t.displayName||`Context`)+`.Consumer`;case 10:return(t._context.displayName||`Context`)+`.Provider`;case 18:return`DehydratedFragment`;case 11:return e=t.render,e=e.displayName||e.name||``,t.displayName||(e===``?`ForwardRef`:`ForwardRef(`+e+`)`);case 7:return`Fragment`;case 5:return t;case 4:return`Portal`;case 3:return`Root`;case 6:return`Text`;case 16:return ae(t);case 8:return t===D?`StrictMode`:`Mode`;case 22:return`Offscreen`;case 12:return`Profiler`;case 21:return`Scope`;case 13:return`Suspense`;case 19:return`SuspenseList`;case 25:return`TracingMarker`;case 1:case 0:case 17:case 2:case 14:case 15:if(typeof t==`function`)return t.displayName||t.name||null;if(typeof t==`string`)return t}return null}function B(e){switch(typeof e){case`boolean`:case`number`:case`string`:case`undefined`:return e;case`object`:return e;default:return``}}function V(e){var t=e.type;return(e=e.nodeName)&&e.toLowerCase()===`input`&&(t===`checkbox`||t===`radio`)}function se(e){var t=V(e)?`checked`:`value`,n=Object.getOwnPropertyDescriptor(e.constructor.prototype,t),r=``+e[t];if(!e.hasOwnProperty(t)&&n!==void 0&&typeof n.get==`function`&&typeof n.set==`function`){var i=n.get,a=n.set;return Object.defineProperty(e,t,{configurable:!0,get:function(){return i.call(this)},set:function(e){r=``+e,a.call(this,e)}}),Object.defineProperty(e,t,{enumerable:n.enumerable}),{getValue:function(){return r},setValue:function(e){r=``+e},stopTracking:function(){e._valueTracker=null,delete e[t]}}}}function ce(e){e._valueTracker||=se(e)}function le(e){if(!e)return!1;var t=e._valueTracker;if(!t)return!0;var n=t.getValue(),r=``;return e&&(r=V(e)?e.checked?`true`:`false`:e.value),e=r,e!==n&&(t.setValue(e),!0)}function ue(e){if(e||=typeof document<`u`?document:void 0,e===void 0)return null;try{return e.activeElement||e.body}catch{return e.body}}function de(e,t){var n=t.checked;return F({},t,{defaultChecked:void 0,defaultValue:void 0,value:void 0,checked:n??e._wrapperState.initialChecked})}function fe(e,t){var n=t.defaultValue==null?``:t.defaultValue,r=t.checked==null?t.defaultChecked:t.checked;n=B(t.value==null?n:t.value),e._wrapperState={initialChecked:r,initialValue:n,controlled:t.type===`checkbox`||t.type===`radio`?t.checked!=null:t.value!=null}}function pe(e,t){t=t.checked,t!=null&&S(e,`checked`,t,!1)}function H(e,t){pe(e,t);var n=B(t.value),r=t.type;if(n!=null)r===`number`?(n===0&&e.value===``||e.value!=n)&&(e.value=``+n):e.value!==``+n&&(e.value=``+n);else if(r===`submit`||r===`reset`){e.removeAttribute(`value`);return}t.hasOwnProperty(`value`)?he(e,t.type,n):t.hasOwnProperty(`defaultValue`)&&he(e,t.type,B(t.defaultValue)),t.checked==null&&t.defaultChecked!=null&&(e.defaultChecked=!!t.defaultChecked)}function me(e,t,n){if(t.hasOwnProperty(`value`)||t.hasOwnProperty(`defaultValue`)){var r=t.type;if(!(r!==`submit`&&r!==`reset`||t.value!==void 0&&t.value!==null))return;t=``+e._wrapperState.initialValue,n||t===e.value||(e.value=t),e.defaultValue=t}n=e.name,n!==``&&(e.name=``),e.defaultChecked=!!e._wrapperState.initialChecked,n!==``&&(e.name=n)}function he(e,t,n){(t!==`number`||ue(e.ownerDocument)!==e)&&(n==null?e.defaultValue=``+e._wrapperState.initialValue:e.defaultValue!==``+n&&(e.defaultValue=``+n))}var ge=Array.isArray;function _e(e,t,n,r){if(e=e.options,t){t={};for(var i=0;i<n.length;i++)t[`$`+n[i]]=!0;for(n=0;n<e.length;n++)i=t.hasOwnProperty(`$`+e[n].value),e[n].selected!==i&&(e[n].selected=i),i&&r&&(e[n].defaultSelected=!0)}else{for(n=``+B(n),t=null,i=0;i<e.length;i++){if(e[i].value===n){e[i].selected=!0,r&&(e[i].defaultSelected=!0);return}t!==null||e[i].disabled||(t=e[i])}t!==null&&(t.selected=!0)}}function ve(e,t){if(t.dangerouslySetInnerHTML!=null)throw Error(r(91));return F({},t,{value:void 0,defaultValue:void 0,children:``+e._wrapperState.initialValue})}function ye(e,t){var n=t.value;if(n==null){if(n=t.children,t=t.defaultValue,n!=null){if(t!=null)throw Error(r(92));if(ge(n)){if(1<n.length)throw Error(r(93));n=n[0]}t=n}t??=``,n=t}e._wrapperState={initialValue:B(n)}}function be(e,t){var n=B(t.value),r=B(t.defaultValue);n!=null&&(n=``+n,n!==e.value&&(e.value=n),t.defaultValue==null&&e.defaultValue!==n&&(e.defaultValue=n)),r!=null&&(e.defaultValue=``+r)}function xe(e){var t=e.textContent;t===e._wrapperState.initialValue&&t!==``&&t!==null&&(e.value=t)}function Se(e){switch(e){case`svg`:return`http://www.w3.org/2000/svg`;case`math`:return`http://www.w3.org/1998/Math/MathML`;default:return`http://www.w3.org/1999/xhtml`}}function Ce(e,t){return e==null||e===`http://www.w3.org/1999/xhtml`?Se(t):e===`http://www.w3.org/2000/svg`&&t===`foreignObject`?`http://www.w3.org/1999/xhtml`:e}var U,we=function(e){return typeof MSApp<`u`&&MSApp.execUnsafeLocalFunction?function(t,n,r,i){MSApp.execUnsafeLocalFunction(function(){return e(t,n,r,i)})}:e}(function(e,t){if(e.namespaceURI!==`http://www.w3.org/2000/svg`||`innerHTML`in e)e.innerHTML=t;else{for(U||=document.createElement(`div`),U.innerHTML=`<svg>`+t.valueOf().toString()+`</svg>`,t=U.firstChild;e.firstChild;)e.removeChild(e.firstChild);for(;t.firstChild;)e.appendChild(t.firstChild)}});function W(e,t){if(t){var n=e.firstChild;if(n&&n===e.lastChild&&n.nodeType===3){n.nodeValue=t;return}}e.textContent=t}var Te={animationIterationCount:!0,aspectRatio:!0,borderImageOutset:!0,borderImageSlice:!0,borderImageWidth:!0,boxFlex:!0,boxFlexGroup:!0,boxOrdinalGroup:!0,columnCount:!0,columns:!0,flex:!0,flexGrow:!0,flexPositive:!0,flexShrink:!0,flexNegative:!0,flexOrder:!0,gridArea:!0,gridRow:!0,gridRowEnd:!0,gridRowSpan:!0,gridRowStart:!0,gridColumn:!0,gridColumnEnd:!0,gridColumnSpan:!0,gridColumnStart:!0,fontWeight:!0,lineClamp:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,tabSize:!0,widows:!0,zIndex:!0,zoom:!0,fillOpacity:!0,floodOpacity:!0,stopOpacity:!0,strokeDasharray:!0,strokeDashoffset:!0,strokeMiterlimit:!0,strokeOpacity:!0,strokeWidth:!0},Ee=[`Webkit`,`ms`,`Moz`,`O`];Object.keys(Te).forEach(function(e){Ee.forEach(function(t){t=t+e.charAt(0).toUpperCase()+e.substring(1),Te[t]=Te[e]})});function G(e,t,n){return t==null||typeof t==`boolean`||t===``?``:n||typeof t!=`number`||t===0||Te.hasOwnProperty(e)&&Te[e]?(``+t).trim():t+`px`}function De(e,t){for(var n in e=e.style,t)if(t.hasOwnProperty(n)){var r=n.indexOf(`--`)===0,i=G(n,t[n],r);n===`float`&&(n=`cssFloat`),r?e.setProperty(n,i):e[n]=i}}var Oe=F({menuitem:!0},{area:!0,base:!0,br:!0,col:!0,embed:!0,hr:!0,img:!0,input:!0,keygen:!0,link:!0,meta:!0,param:!0,source:!0,track:!0,wbr:!0});function ke(e,t){if(t){if(Oe[e]&&(t.children!=null||t.dangerouslySetInnerHTML!=null))throw Error(r(137,e));if(t.dangerouslySetInnerHTML!=null){if(t.children!=null)throw Error(r(60));if(typeof t.dangerouslySetInnerHTML!=`object`||!(`__html`in t.dangerouslySetInnerHTML))throw Error(r(61))}if(t.style!=null&&typeof t.style!=`object`)throw Error(r(62))}}function Ae(e,t){if(e.indexOf(`-`)===-1)return typeof t.is==`string`;switch(e){case`annotation-xml`:case`color-profile`:case`font-face`:case`font-face-src`:case`font-face-uri`:case`font-face-format`:case`font-face-name`:case`missing-glyph`:return!1;default:return!0}}var je=null;function Me(e){return e=e.target||e.srcElement||window,e.correspondingUseElement&&(e=e.correspondingUseElement),e.nodeType===3?e.parentNode:e}var Ne=null,Pe=null,Fe=null;function Ie(e){if(e=Pi(e)){if(typeof Ne!=`function`)throw Error(r(280));var t=e.stateNode;t&&(t=Ii(t),Ne(e.stateNode,e.type,t))}}function Le(e){Pe?Fe?Fe.push(e):Fe=[e]:Pe=e}function Re(){if(Pe){var e=Pe,t=Fe;if(Fe=Pe=null,Ie(e),t)for(e=0;e<t.length;e++)Ie(t[e])}}function ze(e,t){return e(t)}function Be(){}var Ve=!1;function He(e,t,n){if(Ve)return e(t,n);Ve=!0;try{return ze(e,t,n)}finally{Ve=!1,(Pe!==null||Fe!==null)&&(Be(),Re())}}function Ue(e,t){var n=e.stateNode;if(n===null)return null;var i=Ii(n);if(i===null)return null;n=i[t];a:switch(t){case`onClick`:case`onClickCapture`:case`onDoubleClick`:case`onDoubleClickCapture`:case`onMouseDown`:case`onMouseDownCapture`:case`onMouseMove`:case`onMouseMoveCapture`:case`onMouseUp`:case`onMouseUpCapture`:case`onMouseEnter`:(i=!i.disabled)||(e=e.type,i=e!==`button`&&e!==`input`&&e!==`select`&&e!==`textarea`),e=!i;break a;default:e=!1}if(e)return null;if(n&&typeof n!=`function`)throw Error(r(231,t,typeof n));return n}var We=!1;if(c)try{var Ge={};Object.defineProperty(Ge,\"passive\",{get:function(){We=!0}}),window.addEventListener(`test`,Ge,Ge),window.removeEventListener(`test`,Ge,Ge)}catch{We=!1}function Ke(e,t,n,r,i,a,o,s,c){var l=Array.prototype.slice.call(arguments,3);try{t.apply(n,l)}catch(e){this.onError(e)}}var qe=!1,Je=null,Ye=!1,Xe=null,Ze={onError:function(e){qe=!0,Je=e}};function K(e,t,n,r,i,a,o,s,c){qe=!1,Je=null,Ke.apply(Ze,arguments)}function Qe(e,t,n,i,a,o,s,c,l){if(K.apply(this,arguments),qe){if(qe){var u=Je;qe=!1,Je=null}else throw Error(r(198));Ye||(Ye=!0,Xe=u)}}function $e(e){var t=e,n=e;if(e.alternate)for(;t.return;)t=t.return;else{e=t;do t=e,t.flags&4098&&(n=t.return),e=t.return;while(e)}return t.tag===3?n:null}function et(e){if(e.tag===13){var t=e.memoizedState;if(t===null&&(e=e.alternate,e!==null&&(t=e.memoizedState)),t!==null)return t.dehydrated}return null}function tt(e){if($e(e)!==e)throw Error(r(188))}function nt(e){var t=e.alternate;if(!t){if(t=$e(e),t===null)throw Error(r(188));return t===e?e:null}for(var n=e,i=t;;){var a=n.return;if(a===null)break;var o=a.alternate;if(o===null){if(i=a.return,i!==null){n=i;continue}break}if(a.child===o.child){for(o=a.child;o;){if(o===n)return tt(a),e;if(o===i)return tt(a),t;o=o.sibling}throw Error(r(188))}if(n.return!==i.return)n=a,i=o;else{for(var s=!1,c=a.child;c;){if(c===n){s=!0,n=a,i=o;break}if(c===i){s=!0,i=a,n=o;break}c=c.sibling}if(!s){for(c=o.child;c;){if(c===n){s=!0,n=o,i=a;break}if(c===i){s=!0,i=o,n=a;break}c=c.sibling}if(!s)throw Error(r(189))}}if(n.alternate!==i)throw Error(r(190))}if(n.tag!==3)throw Error(r(188));return n.stateNode.current===n?e:t}function rt(e){return e=nt(e),e===null?null:it(e)}function it(e){if(e.tag===5||e.tag===6)return e;for(e=e.child;e!==null;){var t=it(e);if(t!==null)return t;e=e.sibling}return null}var at=n.unstable_scheduleCallback,ot=n.unstable_cancelCallback,st=n.unstable_shouldYield,ct=n.unstable_requestPaint,lt=n.unstable_now,ut=n.unstable_getCurrentPriorityLevel,dt=n.unstable_ImmediatePriority,ft=n.unstable_UserBlockingPriority,pt=n.unstable_NormalPriority,mt=n.unstable_LowPriority,ht=n.unstable_IdlePriority,gt=null,_t=null;function vt(e){if(_t&&typeof _t.onCommitFiberRoot==`function`)try{_t.onCommitFiberRoot(gt,e,void 0,(e.current.flags&128)==128)}catch{}}var yt=Math.clz32?Math.clz32:St,bt=Math.log,xt=Math.LN2;function St(e){return e>>>=0,e===0?32:31-(bt(e)/xt|0)|0}var Ct=64,wt=4194304;function Tt(e){switch(e&-e){case 1:return 1;case 2:return 2;case 4:return 4;case 8:return 8;case 16:return 16;case 32:return 32;case 64:case 128:case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:return e&4194240;case 4194304:case 8388608:case 16777216:case 33554432:case 67108864:return e&130023424;case 134217728:return 134217728;case 268435456:return 268435456;case 536870912:return 536870912;case 1073741824:return 1073741824;default:return e}}function Et(e,t){var n=e.pendingLanes;if(n===0)return 0;var r=0,i=e.suspendedLanes,a=e.pingedLanes,o=n&268435455;if(o!==0){var s=o&~i;s===0?(a&=o,a!==0&&(r=Tt(a))):r=Tt(s)}else o=n&~i,o===0?a!==0&&(r=Tt(a)):r=Tt(o);if(r===0)return 0;if(t!==0&&t!==r&&(t&i)===0&&(i=r&-r,a=t&-t,i>=a||i===16&&a&4194240))return t;if(r&4&&(r|=n&16),t=e.entangledLanes,t!==0)for(e=e.entanglements,t&=r;0<t;)n=31-yt(t),i=1<<n,r|=e[n],t&=~i;return r}function Dt(e,t){switch(e){case 1:case 2:case 4:return t+250;case 8:case 16:case 32:case 64:case 128:case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:return t+5e3;case 4194304:case 8388608:case 16777216:case 33554432:case 67108864:return-1;case 134217728:case 268435456:case 536870912:case 1073741824:return-1;default:return-1}}function Ot(e,t){for(var n=e.suspendedLanes,r=e.pingedLanes,i=e.expirationTimes,a=e.pendingLanes;0<a;){var o=31-yt(a),s=1<<o,c=i[o];c===-1?((s&n)===0||(s&r)!==0)&&(i[o]=Dt(s,t)):c<=t&&(e.expiredLanes|=s),a&=~s}}function kt(e){return e=e.pendingLanes&-1073741825,e===0?e&1073741824?1073741824:0:e}function At(){var e=Ct;return Ct<<=1,!(Ct&4194240)&&(Ct=64),e}function jt(e){for(var t=[],n=0;31>n;n++)t.push(e);return t}function Mt(e,t,n){e.pendingLanes|=t,t!==536870912&&(e.suspendedLanes=0,e.pingedLanes=0),e=e.eventTimes,t=31-yt(t),e[t]=n}function Nt(e,t){var n=e.pendingLanes&~t;e.pendingLanes=t,e.suspendedLanes=0,e.pingedLanes=0,e.expiredLanes&=t,e.mutableReadLanes&=t,e.entangledLanes&=t,t=e.entanglements;var r=e.eventTimes;for(e=e.expirationTimes;0<n;){var i=31-yt(n),a=1<<i;t[i]=0,r[i]=-1,e[i]=-1,n&=~a}}function Pt(e,t){var n=e.entangledLanes|=t;for(e=e.entanglements;n;){var r=31-yt(n),i=1<<r;i&t|e[r]&t&&(e[r]|=t),n&=~i}}var Ft=0;function It(e){return e&=-e,1<e?4<e?e&268435455?16:536870912:4:1}var Lt,Rt,zt,Bt,Vt,Ht=!1,Ut=[],Wt=null,Gt=null,Kt=null,qt=new Map,Jt=new Map,Yt=[],Xt=`mousedown mouseup touchcancel touchend touchstart auxclick dblclick pointercancel pointerdown pointerup dragend dragstart drop compositionend compositionstart keydown keypress keyup input textInput copy cut paste click change contextmenu reset submit`.split(` `);function Zt(e,t){switch(e){case`focusin`:case`focusout`:Wt=null;break;case`dragenter`:case`dragleave`:Gt=null;break;case`mouseover`:case`mouseout`:Kt=null;break;case`pointerover`:case`pointerout`:qt.delete(t.pointerId);break;case`gotpointercapture`:case`lostpointercapture`:Jt.delete(t.pointerId)}}function Qt(e,t,n,r,i,a){return e===null||e.nativeEvent!==a?(e={blockedOn:t,domEventName:n,eventSystemFlags:r,nativeEvent:a,targetContainers:[i]},t!==null&&(t=Pi(t),t!==null&&Rt(t)),e):(e.eventSystemFlags|=r,t=e.targetContainers,i!==null&&t.indexOf(i)===-1&&t.push(i),e)}function $t(e,t,n,r,i){switch(t){case`focusin`:return Wt=Qt(Wt,e,t,n,r,i),!0;case`dragenter`:return Gt=Qt(Gt,e,t,n,r,i),!0;case`mouseover`:return Kt=Qt(Kt,e,t,n,r,i),!0;case`pointerover`:var a=i.pointerId;return qt.set(a,Qt(qt.get(a)||null,e,t,n,r,i)),!0;case`gotpointercapture`:return a=i.pointerId,Jt.set(a,Qt(Jt.get(a)||null,e,t,n,r,i)),!0}return!1}function en(e){var t=Ni(e.target);if(t!==null){var n=$e(t);if(n!==null){if(t=n.tag,t===13){if(t=et(n),t!==null){e.blockedOn=t,Vt(e.priority,function(){zt(n)});return}}else if(t===3&&n.stateNode.current.memoizedState.isDehydrated){e.blockedOn=n.tag===3?n.stateNode.containerInfo:null;return}}}e.blockedOn=null}function tn(e){if(e.blockedOn!==null)return!1;for(var t=e.targetContainers;0<t.length;){var n=pn(e.domEventName,e.eventSystemFlags,t[0],e.nativeEvent);if(n===null){n=e.nativeEvent;var r=new n.constructor(n.type,n);je=r,n.target.dispatchEvent(r),je=null}else return t=Pi(n),t!==null&&Rt(t),e.blockedOn=n,!1;t.shift()}return!0}function nn(e,t,n){tn(e)&&n.delete(t)}function rn(){Ht=!1,Wt!==null&&tn(Wt)&&(Wt=null),Gt!==null&&tn(Gt)&&(Gt=null),Kt!==null&&tn(Kt)&&(Kt=null),qt.forEach(nn),Jt.forEach(nn)}function an(e,t){e.blockedOn===t&&(e.blockedOn=null,Ht||(Ht=!0,n.unstable_scheduleCallback(n.unstable_NormalPriority,rn)))}function on(e){function t(t){return an(t,e)}if(0<Ut.length){an(Ut[0],e);for(var n=1;n<Ut.length;n++){var r=Ut[n];r.blockedOn===e&&(r.blockedOn=null)}}for(Wt!==null&&an(Wt,e),Gt!==null&&an(Gt,e),Kt!==null&&an(Kt,e),qt.forEach(t),Jt.forEach(t),n=0;n<Yt.length;n++)r=Yt[n],r.blockedOn===e&&(r.blockedOn=null);for(;0<Yt.length&&(n=Yt[0],n.blockedOn===null);)en(n),n.blockedOn===null&&Yt.shift()}var sn=C.ReactCurrentBatchConfig,cn=!0;function ln(e,t,n,r){var i=Ft,a=sn.transition;sn.transition=null;try{Ft=1,dn(e,t,n,r)}finally{Ft=i,sn.transition=a}}function un(e,t,n,r){var i=Ft,a=sn.transition;sn.transition=null;try{Ft=4,dn(e,t,n,r)}finally{Ft=i,sn.transition=a}}function dn(e,t,n,r){if(cn){var i=pn(e,t,n,r);if(i===null)oi(e,t,r,fn,n),Zt(e,r);else if($t(i,e,t,n,r))r.stopPropagation();else if(Zt(e,r),t&4&&-1<Xt.indexOf(e)){for(;i!==null;){var a=Pi(i);if(a!==null&&Lt(a),a=pn(e,t,n,r),a===null&&oi(e,t,r,fn,n),a===i)break;i=a}i!==null&&r.stopPropagation()}else oi(e,t,r,null,n)}}var fn=null;function pn(e,t,n,r){if(fn=null,e=Me(r),e=Ni(e),e!==null){if(t=$e(e),t===null)e=null;else if(n=t.tag,n===13){if(e=et(t),e!==null)return e;e=null}else if(n===3){if(t.stateNode.current.memoizedState.isDehydrated)return t.tag===3?t.stateNode.containerInfo:null;e=null}else t!==e&&(e=null)}return fn=e,null}function mn(e){switch(e){case`cancel`:case`click`:case`close`:case`contextmenu`:case`copy`:case`cut`:case`auxclick`:case`dblclick`:case`dragend`:case`dragstart`:case`drop`:case`focusin`:case`focusout`:case`input`:case`invalid`:case`keydown`:case`keypress`:case`keyup`:case`mousedown`:case`mouseup`:case`paste`:case`pause`:case`play`:case`pointercancel`:case`pointerdown`:case`pointerup`:case`ratechange`:case`reset`:case`resize`:case`seeked`:case`submit`:case`touchcancel`:case`touchend`:case`touchstart`:case`volumechange`:case`change`:case`selectionchange`:case`textInput`:case`compositionstart`:case`compositionend`:case`compositionupdate`:case`beforeblur`:case`afterblur`:case`beforeinput`:case`blur`:case`fullscreenchange`:case`focus`:case`hashchange`:case`popstate`:case`select`:case`selectstart`:return 1;case`drag`:case`dragenter`:case`dragexit`:case`dragleave`:case`dragover`:case`mousemove`:case`mouseout`:case`mouseover`:case`pointermove`:case`pointerout`:case`pointerover`:case`scroll`:case`toggle`:case`touchmove`:case`wheel`:case`mouseenter`:case`mouseleave`:case`pointerenter`:case`pointerleave`:return 4;case`message`:switch(ut()){case dt:return 1;case ft:return 4;case pt:case mt:return 16;case ht:return 536870912;default:return 16}default:return 16}}var hn=null,gn=null,_n=null;function vn(){if(_n)return _n;var e,t=gn,n=t.length,r,i=`value`in hn?hn.value:hn.textContent,a=i.length;for(e=0;e<n&&t[e]===i[e];e++);var o=n-e;for(r=1;r<=o&&t[n-r]===i[a-r];r++);return _n=i.slice(e,1<r?1-r:void 0)}function yn(e){var t=e.keyCode;return`charCode`in e?(e=e.charCode,e===0&&t===13&&(e=13)):e=t,e===10&&(e=13),32<=e||e===13?e:0}function bn(){return!0}function xn(){return!1}function Sn(e){function t(t,n,r,i,a){for(var o in this._reactName=t,this._targetInst=r,this.type=n,this.nativeEvent=i,this.target=a,this.currentTarget=null,e)e.hasOwnProperty(o)&&(t=e[o],this[o]=t?t(i):i[o]);return this.isDefaultPrevented=(i.defaultPrevented==null?!1===i.returnValue:i.defaultPrevented)?bn:xn,this.isPropagationStopped=xn,this}return F(t.prototype,{preventDefault:function(){this.defaultPrevented=!0;var e=this.nativeEvent;e&&(e.preventDefault?e.preventDefault():typeof e.returnValue!=`unknown`&&(e.returnValue=!1),this.isDefaultPrevented=bn)},stopPropagation:function(){var e=this.nativeEvent;e&&(e.stopPropagation?e.stopPropagation():typeof e.cancelBubble!=`unknown`&&(e.cancelBubble=!0),this.isPropagationStopped=bn)},persist:function(){},isPersistent:bn}),t}var Cn={eventPhase:0,bubbles:0,cancelable:0,timeStamp:function(e){return e.timeStamp||Date.now()},defaultPrevented:0,isTrusted:0},wn=Sn(Cn),Tn=F({},Cn,{view:0,detail:0}),En=Sn(Tn),Dn,On,kn,An=F({},Tn,{screenX:0,screenY:0,clientX:0,clientY:0,pageX:0,pageY:0,ctrlKey:0,shiftKey:0,altKey:0,metaKey:0,getModifierState:Vn,button:0,buttons:0,relatedTarget:function(e){return e.relatedTarget===void 0?e.fromElement===e.srcElement?e.toElement:e.fromElement:e.relatedTarget},movementX:function(e){return`movementX`in e?e.movementX:(e!==kn&&(kn&&e.type===`mousemove`?(Dn=e.screenX-kn.screenX,On=e.screenY-kn.screenY):On=Dn=0,kn=e),Dn)},movementY:function(e){return`movementY`in e?e.movementY:On}}),jn=Sn(An),Mn=Sn(F({},An,{dataTransfer:0})),Nn=Sn(F({},Tn,{relatedTarget:0})),Pn=Sn(F({},Cn,{animationName:0,elapsedTime:0,pseudoElement:0})),Fn=Sn(F({},Cn,{clipboardData:function(e){return`clipboardData`in e?e.clipboardData:window.clipboardData}})),In=Sn(F({},Cn,{data:0})),Ln={Esc:`Escape`,Spacebar:` `,Left:`ArrowLeft`,Up:`ArrowUp`,Right:`ArrowRight`,Down:`ArrowDown`,Del:`Delete`,Win:`OS`,Menu:`ContextMenu`,Apps:`ContextMenu`,Scroll:`ScrollLock`,MozPrintableKey:`Unidentified`},Rn={8:`Backspace`,9:`Tab`,12:`Clear`,13:`Enter`,16:`Shift`,17:`Control`,18:`Alt`,19:`Pause`,20:`CapsLock`,27:`Escape`,32:` `,33:`PageUp`,34:`PageDown`,35:`End`,36:`Home`,37:`ArrowLeft`,38:`ArrowUp`,39:`ArrowRight`,40:`ArrowDown`,45:`Insert`,46:`Delete`,112:`F1`,113:`F2`,114:`F3`,115:`F4`,116:`F5`,117:`F6`,118:`F7`,119:`F8`,120:`F9`,121:`F10`,122:`F11`,123:`F12`,144:`NumLock`,145:`ScrollLock`,224:`Meta`},zn={Alt:`altKey`,Control:`ctrlKey`,Meta:`metaKey`,Shift:`shiftKey`};function Bn(e){var t=this.nativeEvent;return t.getModifierState?t.getModifierState(e):(e=zn[e])?!!t[e]:!1}function Vn(){return Bn}var Hn=Sn(F({},Tn,{key:function(e){if(e.key){var t=Ln[e.key]||e.key;if(t!==`Unidentified`)return t}return e.type===`keypress`?(e=yn(e),e===13?`Enter`:String.fromCharCode(e)):e.type===`keydown`||e.type===`keyup`?Rn[e.keyCode]||`Unidentified`:``},code:0,location:0,ctrlKey:0,shiftKey:0,altKey:0,metaKey:0,repeat:0,locale:0,getModifierState:Vn,charCode:function(e){return e.type===`keypress`?yn(e):0},keyCode:function(e){return e.type===`keydown`||e.type===`keyup`?e.keyCode:0},which:function(e){return e.type===`keypress`?yn(e):e.type===`keydown`||e.type===`keyup`?e.keyCode:0}})),Un=Sn(F({},An,{pointerId:0,width:0,height:0,pressure:0,tangentialPressure:0,tiltX:0,tiltY:0,twist:0,pointerType:0,isPrimary:0})),Wn=Sn(F({},Tn,{touches:0,targetTouches:0,changedTouches:0,altKey:0,metaKey:0,ctrlKey:0,shiftKey:0,getModifierState:Vn})),Gn=Sn(F({},Cn,{propertyName:0,elapsedTime:0,pseudoElement:0})),Kn=Sn(F({},An,{deltaX:function(e){return`deltaX`in e?e.deltaX:`wheelDeltaX`in e?-e.wheelDeltaX:0},deltaY:function(e){return`deltaY`in e?e.deltaY:`wheelDeltaY`in e?-e.wheelDeltaY:`wheelDelta`in e?-e.wheelDelta:0},deltaZ:0,deltaMode:0})),qn=[9,13,27,32],Jn=c&&`CompositionEvent`in window,Yn=null;c&&`documentMode`in document&&(Yn=document.documentMode);var q=c&&`TextEvent`in window&&!Yn,Xn=c&&(!Jn||Yn&&8<Yn&&11>=Yn),Zn=` `,Qn=!1;function $n(e,t){switch(e){case`keyup`:return qn.indexOf(t.keyCode)!==-1;case`keydown`:return t.keyCode!==229;case`keypress`:case`mousedown`:case`focusout`:return!0;default:return!1}}function er(e){return e=e.detail,typeof e==`object`&&`data`in e?e.data:null}var tr=!1;function nr(e,t){switch(e){case`compositionend`:return er(t);case`keypress`:return t.which===32?(Qn=!0,Zn):null;case`textInput`:return e=t.data,e===Zn&&Qn?null:e;default:return null}}function rr(e,t){if(tr)return e===`compositionend`||!Jn&&$n(e,t)?(e=vn(),_n=gn=hn=null,tr=!1,e):null;switch(e){case`paste`:return null;case`keypress`:if(!(t.ctrlKey||t.altKey||t.metaKey)||t.ctrlKey&&t.altKey){if(t.char&&1<t.char.length)return t.char;if(t.which)return String.fromCharCode(t.which)}return null;case`compositionend`:return Xn&&t.locale!==`ko`?null:t.data;default:return null}}var ir={color:!0,date:!0,datetime:!0,\"datetime-local\":!0,email:!0,month:!0,number:!0,password:!0,range:!0,search:!0,tel:!0,text:!0,time:!0,url:!0,week:!0};function ar(e){var t=e&&e.nodeName&&e.nodeName.toLowerCase();return t===`input`?!!ir[e.type]:t===`textarea`}function or(e,t,n,r){Le(r),t=ci(t,`onChange`),0<t.length&&(n=new wn(`onChange`,`change`,null,n,r),e.push({event:n,listeners:t}))}var sr=null,cr=null;function lr(e){ei(e,0)}function ur(e){if(le(Fi(e)))return e}function dr(e,t){if(e===`change`)return t}var fr=!1;if(c){var pr;if(c){var mr=`oninput`in document;if(!mr){var hr=document.createElement(`div`);hr.setAttribute(`oninput`,`return;`),mr=typeof hr.oninput==`function`}pr=mr}else pr=!1;fr=pr&&(!document.documentMode||9<document.documentMode)}function gr(){sr&&(sr.detachEvent(`onpropertychange`,_r),cr=sr=null)}function _r(e){if(e.propertyName===`value`&&ur(cr)){var t=[];or(t,cr,e,Me(e)),He(lr,t)}}function vr(e,t,n){e===`focusin`?(gr(),sr=t,cr=n,sr.attachEvent(`onpropertychange`,_r)):e===`focusout`&&gr()}function yr(e){if(e===`selectionchange`||e===`keyup`||e===`keydown`)return ur(cr)}function br(e,t){if(e===`click`)return ur(t)}function xr(e,t){if(e===`input`||e===`change`)return ur(t)}function Sr(e,t){return e===t&&(e!==0||1/e==1/t)||e!==e&&t!==t}var Cr=typeof Object.is==`function`?Object.is:Sr;function wr(e,t){if(Cr(e,t))return!0;if(typeof e!=`object`||!e||typeof t!=`object`||!t)return!1;var n=Object.keys(e),r=Object.keys(t);if(n.length!==r.length)return!1;for(r=0;r<n.length;r++){var i=n[r];if(!l.call(t,i)||!Cr(e[i],t[i]))return!1}return!0}function Tr(e){for(;e&&e.firstChild;)e=e.firstChild;return e}function Er(e,t){var n=Tr(e);e=0;for(var r;n;){if(n.nodeType===3){if(r=e+n.textContent.length,e<=t&&r>=t)return{node:n,offset:t-e};e=r}a:{for(;n;){if(n.nextSibling){n=n.nextSibling;break a}n=n.parentNode}n=void 0}n=Tr(n)}}function Dr(e,t){return e&&t?e===t?!0:e&&e.nodeType===3?!1:t&&t.nodeType===3?Dr(e,t.parentNode):`contains`in e?e.contains(t):e.compareDocumentPosition?!!(e.compareDocumentPosition(t)&16):!1:!1}function Or(){for(var e=window,t=ue();t instanceof e.HTMLIFrameElement;){try{var n=typeof t.contentWindow.location.href==`string`}catch{n=!1}if(n)e=t.contentWindow;else break;t=ue(e.document)}return t}function kr(e){var t=e&&e.nodeName&&e.nodeName.toLowerCase();return t&&(t===`input`&&(e.type===`text`||e.type===`search`||e.type===`tel`||e.type===`url`||e.type===`password`)||t===`textarea`||e.contentEditable===`true`)}function Ar(e){var t=Or(),n=e.focusedElem,r=e.selectionRange;if(t!==n&&n&&n.ownerDocument&&Dr(n.ownerDocument.documentElement,n)){if(r!==null&&kr(n)){if(t=r.start,e=r.end,e===void 0&&(e=t),`selectionStart`in n)n.selectionStart=t,n.selectionEnd=Math.min(e,n.value.length);else if(e=(t=n.ownerDocument||document)&&t.defaultView||window,e.getSelection){e=e.getSelection();var i=n.textContent.length,a=Math.min(r.start,i);r=r.end===void 0?a:Math.min(r.end,i),!e.extend&&a>r&&(i=r,r=a,a=i),i=Er(n,a);var o=Er(n,r);i&&o&&(e.rangeCount!==1||e.anchorNode!==i.node||e.anchorOffset!==i.offset||e.focusNode!==o.node||e.focusOffset!==o.offset)&&(t=t.createRange(),t.setStart(i.node,i.offset),e.removeAllRanges(),a>r?(e.addRange(t),e.extend(o.node,o.offset)):(t.setEnd(o.node,o.offset),e.addRange(t)))}}for(t=[],e=n;e=e.parentNode;)e.nodeType===1&&t.push({element:e,left:e.scrollLeft,top:e.scrollTop});for(typeof n.focus==`function`&&n.focus(),n=0;n<t.length;n++)e=t[n],e.element.scrollLeft=e.left,e.element.scrollTop=e.top}}var jr=c&&`documentMode`in document&&11>=document.documentMode,Mr=null,Nr=null,Pr=null,Fr=!1;function Ir(e,t,n){var r=n.window===n?n.document:n.nodeType===9?n:n.ownerDocument;Fr||Mr==null||Mr!==ue(r)||(r=Mr,`selectionStart`in r&&kr(r)?r={start:r.selectionStart,end:r.selectionEnd}:(r=(r.ownerDocument&&r.ownerDocument.defaultView||window).getSelection(),r={anchorNode:r.anchorNode,anchorOffset:r.anchorOffset,focusNode:r.focusNode,focusOffset:r.focusOffset}),Pr&&wr(Pr,r)||(Pr=r,r=ci(Nr,`onSelect`),0<r.length&&(t=new wn(`onSelect`,`select`,null,t,n),e.push({event:t,listeners:r}),t.target=Mr)))}function Lr(e,t){var n={};return n[e.toLowerCase()]=t.toLowerCase(),n[`Webkit`+e]=`webkit`+t,n[`Moz`+e]=`moz`+t,n}var Rr={animationend:Lr(`Animation`,`AnimationEnd`),animationiteration:Lr(`Animation`,`AnimationIteration`),animationstart:Lr(`Animation`,`AnimationStart`),transitionend:Lr(`Transition`,`TransitionEnd`)},zr={},Br={};c&&(Br=document.createElement(`div`).style,`AnimationEvent`in window||(delete Rr.animationend.animation,delete Rr.animationiteration.animation,delete Rr.animationstart.animation),`TransitionEvent`in window||delete Rr.transitionend.transition);function Vr(e){if(zr[e])return zr[e];if(!Rr[e])return e;var t=Rr[e],n;for(n in t)if(t.hasOwnProperty(n)&&n in Br)return zr[e]=t[n];return e}var Hr=Vr(`animationend`),Ur=Vr(`animationiteration`),Wr=Vr(`animationstart`),Gr=Vr(`transitionend`),Kr=new Map,qr=`abort auxClick cancel canPlay canPlayThrough click close contextMenu copy cut drag dragEnd dragEnter dragExit dragLeave dragOver dragStart drop durationChange emptied encrypted ended error gotPointerCapture input invalid keyDown keyPress keyUp load loadedData loadedMetadata loadStart lostPointerCapture mouseDown mouseMove mouseOut mouseOver mouseUp paste pause play playing pointerCancel pointerDown pointerMove pointerOut pointerOver pointerUp progress rateChange reset resize seeked seeking stalled submit suspend timeUpdate touchCancel touchEnd touchStart volumeChange scroll toggle touchMove waiting wheel`.split(` `);function Jr(e,t){Kr.set(e,t),o(t,[e])}for(var Yr=0;Yr<qr.length;Yr++){var Xr=qr[Yr];Jr(Xr.toLowerCase(),`on`+(Xr[0].toUpperCase()+Xr.slice(1)))}Jr(Hr,`onAnimationEnd`),Jr(Ur,`onAnimationIteration`),Jr(Wr,`onAnimationStart`),Jr(`dblclick`,`onDoubleClick`),Jr(`focusin`,`onFocus`),Jr(`focusout`,`onBlur`),Jr(Gr,`onTransitionEnd`),s(`onMouseEnter`,[`mouseout`,`mouseover`]),s(`onMouseLeave`,[`mouseout`,`mouseover`]),s(`onPointerEnter`,[`pointerout`,`pointerover`]),s(`onPointerLeave`,[`pointerout`,`pointerover`]),o(`onChange`,`change click focusin focusout input keydown keyup selectionchange`.split(` `)),o(`onSelect`,`focusout contextmenu dragend focusin keydown keyup mousedown mouseup selectionchange`.split(` `)),o(`onBeforeInput`,[`compositionend`,`keypress`,`textInput`,`paste`]),o(`onCompositionEnd`,`compositionend focusout keydown keypress keyup mousedown`.split(` `)),o(`onCompositionStart`,`compositionstart focusout keydown keypress keyup mousedown`.split(` `)),o(`onCompositionUpdate`,`compositionupdate focusout keydown keypress keyup mousedown`.split(` `));var Zr=`abort canplay canplaythrough durationchange emptied encrypted ended error loadeddata loadedmetadata loadstart pause play playing progress ratechange resize seeked seeking stalled suspend timeupdate volumechange waiting`.split(` `),Qr=new Set(`cancel close invalid load scroll toggle`.split(` `).concat(Zr));function $r(e,t,n){var r=e.type||`unknown-event`;e.currentTarget=n,Qe(r,t,void 0,e),e.currentTarget=null}function ei(e,t){t=!!(t&4);for(var n=0;n<e.length;n++){var r=e[n],i=r.event;r=r.listeners;a:{var a=void 0;if(t)for(var o=r.length-1;0<=o;o--){var s=r[o],c=s.instance,l=s.currentTarget;if(s=s.listener,c!==a&&i.isPropagationStopped())break a;$r(i,s,l),a=c}else for(o=0;o<r.length;o++){if(s=r[o],c=s.instance,l=s.currentTarget,s=s.listener,c!==a&&i.isPropagationStopped())break a;$r(i,s,l),a=c}}}if(Ye)throw e=Xe,Ye=!1,Xe=null,e}function ti(e,t){var n=t[Ai];n===void 0&&(n=t[Ai]=new Set);var r=e+`__bubble`;n.has(r)||(ai(t,e,2,!1),n.add(r))}function ni(e,t,n){var r=0;t&&(r|=4),ai(n,e,r,t)}var ri=`_reactListening`+Math.random().toString(36).slice(2);function ii(e){if(!e[ri]){e[ri]=!0,i.forEach(function(t){t!==`selectionchange`&&(Qr.has(t)||ni(t,!1,e),ni(t,!0,e))});var t=e.nodeType===9?e:e.ownerDocument;t===null||t[ri]||(t[ri]=!0,ni(`selectionchange`,!1,t))}}function ai(e,t,n,r){switch(mn(t)){case 1:var i=ln;break;case 4:i=un;break;default:i=dn}n=i.bind(null,t,n,e),i=void 0,!We||t!==`touchstart`&&t!==`touchmove`&&t!==`wheel`||(i=!0),r?i===void 0?e.addEventListener(t,n,!0):e.addEventListener(t,n,{capture:!0,passive:i}):i===void 0?e.addEventListener(t,n,!1):e.addEventListener(t,n,{passive:i})}function oi(e,t,n,r,i){var a=r;if(!(t&1)&&!(t&2)&&r!==null)a:for(;;){if(r===null)return;var o=r.tag;if(o===3||o===4){var s=r.stateNode.containerInfo;if(s===i||s.nodeType===8&&s.parentNode===i)break;if(o===4)for(o=r.return;o!==null;){var c=o.tag;if((c===3||c===4)&&(c=o.stateNode.containerInfo,c===i||c.nodeType===8&&c.parentNode===i))return;o=o.return}for(;s!==null;){if(o=Ni(s),o===null)return;if(c=o.tag,c===5||c===6){r=a=o;continue a}s=s.parentNode}}r=r.return}He(function(){var r=a,i=Me(n),o=[];a:{var s=Kr.get(e);if(s!==void 0){var c=wn,l=e;switch(e){case`keypress`:if(yn(n)===0)break a;case`keydown`:case`keyup`:c=Hn;break;case`focusin`:l=`focus`,c=Nn;break;case`focusout`:l=`blur`,c=Nn;break;case`beforeblur`:case`afterblur`:c=Nn;break;case`click`:if(n.button===2)break a;case`auxclick`:case`dblclick`:case`mousedown`:case`mousemove`:case`mouseup`:case`mouseout`:case`mouseover`:case`contextmenu`:c=jn;break;case`drag`:case`dragend`:case`dragenter`:case`dragexit`:case`dragleave`:case`dragover`:case`dragstart`:case`drop`:c=Mn;break;case`touchcancel`:case`touchend`:case`touchmove`:case`touchstart`:c=Wn;break;case Hr:case Ur:case Wr:c=Pn;break;case Gr:c=Gn;break;case`scroll`:c=En;break;case`wheel`:c=Kn;break;case`copy`:case`cut`:case`paste`:c=Fn;break;case`gotpointercapture`:case`lostpointercapture`:case`pointercancel`:case`pointerdown`:case`pointermove`:case`pointerout`:case`pointerover`:case`pointerup`:c=Un}var u=!!(t&4),d=!u&&e===`scroll`,f=u?s===null?null:s+`Capture`:s;u=[];for(var p=r,m;p!==null;){m=p;var h=m.stateNode;if(m.tag===5&&h!==null&&(m=h,f!==null&&(h=Ue(p,f),h!=null&&u.push(si(p,h,m)))),d)break;p=p.return}0<u.length&&(s=new c(s,l,null,n,i),o.push({event:s,listeners:u}))}}if(!(t&7)){a:{if(s=e===`mouseover`||e===`pointerover`,c=e===`mouseout`||e===`pointerout`,s&&n!==je&&(l=n.relatedTarget||n.fromElement)&&(Ni(l)||l[ki]))break a;if((c||s)&&(s=i.window===i?i:(s=i.ownerDocument)?s.defaultView||s.parentWindow:window,c?(l=n.relatedTarget||n.toElement,c=r,l=l?Ni(l):null,l!==null&&(d=$e(l),l!==d||l.tag!==5&&l.tag!==6)&&(l=null)):(c=null,l=r),c!==l)){if(u=jn,h=`onMouseLeave`,f=`onMouseEnter`,p=`mouse`,(e===`pointerout`||e===`pointerover`)&&(u=Un,h=`onPointerLeave`,f=`onPointerEnter`,p=`pointer`),d=c==null?s:Fi(c),m=l==null?s:Fi(l),s=new u(h,p+`leave`,c,n,i),s.target=d,s.relatedTarget=m,h=null,Ni(i)===r&&(u=new u(f,p+`enter`,l,n,i),u.target=m,u.relatedTarget=d,h=u),d=h,c&&l)b:{for(u=c,f=l,p=0,m=u;m;m=li(m))p++;for(m=0,h=f;h;h=li(h))m++;for(;0<p-m;)u=li(u),p--;for(;0<m-p;)f=li(f),m--;for(;p--;){if(u===f||f!==null&&u===f.alternate)break b;u=li(u),f=li(f)}u=null}else u=null;c!==null&&ui(o,s,c,u,!1),l!==null&&d!==null&&ui(o,d,l,u,!0)}}a:{if(s=r?Fi(r):window,c=s.nodeName&&s.nodeName.toLowerCase(),c===`select`||c===`input`&&s.type===`file`)var g=dr;else if(ar(s)){if(fr)g=xr;else{g=yr;var _=vr}}else(c=s.nodeName)&&c.toLowerCase()===`input`&&(s.type===`checkbox`||s.type===`radio`)&&(g=br);if(g&&=g(e,r)){or(o,g,n,i);break a}_&&_(e,s,r),e===`focusout`&&(_=s._wrapperState)&&_.controlled&&s.type===`number`&&he(s,`number`,s.value)}switch(_=r?Fi(r):window,e){case`focusin`:(ar(_)||_.contentEditable===`true`)&&(Mr=_,Nr=r,Pr=null);break;case`focusout`:Pr=Nr=Mr=null;break;case`mousedown`:Fr=!0;break;case`contextmenu`:case`mouseup`:case`dragend`:Fr=!1,Ir(o,n,i);break;case`selectionchange`:if(jr)break;case`keydown`:case`keyup`:Ir(o,n,i)}var v;if(Jn)b:{switch(e){case`compositionstart`:var y=`onCompositionStart`;break b;case`compositionend`:y=`onCompositionEnd`;break b;case`compositionupdate`:y=`onCompositionUpdate`;break b}y=void 0}else tr?$n(e,n)&&(y=`onCompositionEnd`):e===`keydown`&&n.keyCode===229&&(y=`onCompositionStart`);y&&(Xn&&n.locale!==`ko`&&(tr||y!==`onCompositionStart`?y===`onCompositionEnd`&&tr&&(v=vn()):(hn=i,gn=`value`in hn?hn.value:hn.textContent,tr=!0)),_=ci(r,y),0<_.length&&(y=new In(y,e,null,n,i),o.push({event:y,listeners:_}),v?y.data=v:(v=er(n),v!==null&&(y.data=v)))),(v=q?nr(e,n):rr(e,n))&&(r=ci(r,`onBeforeInput`),0<r.length&&(i=new In(`onBeforeInput`,`beforeinput`,null,n,i),o.push({event:i,listeners:r}),i.data=v))}ei(o,t)})}function si(e,t,n){return{instance:e,listener:t,currentTarget:n}}function ci(e,t){for(var n=t+`Capture`,r=[];e!==null;){var i=e,a=i.stateNode;i.tag===5&&a!==null&&(i=a,a=Ue(e,n),a!=null&&r.unshift(si(e,a,i)),a=Ue(e,t),a!=null&&r.push(si(e,a,i))),e=e.return}return r}function li(e){if(e===null)return null;do e=e.return;while(e&&e.tag!==5);return e||null}function ui(e,t,n,r,i){for(var a=t._reactName,o=[];n!==null&&n!==r;){var s=n,c=s.alternate,l=s.stateNode;if(c!==null&&c===r)break;s.tag===5&&l!==null&&(s=l,i?(c=Ue(n,a),c!=null&&o.unshift(si(n,c,s))):i||(c=Ue(n,a),c!=null&&o.push(si(n,c,s)))),n=n.return}o.length!==0&&e.push({event:t,listeners:o})}var di=/\\r\\n?/g,fi=/\\u0000|\\uFFFD/g;function pi(e){return(typeof e==`string`?e:``+e).replace(di,`\n`).replace(fi,``)}function mi(e,t,n){if(t=pi(t),pi(e)!==t&&n)throw Error(r(425))}function hi(){}var gi=null,_i=null;function vi(e,t){return e===`textarea`||e===`noscript`||typeof t.children==`string`||typeof t.children==`number`||typeof t.dangerouslySetInnerHTML==`object`&&t.dangerouslySetInnerHTML!==null&&t.dangerouslySetInnerHTML.__html!=null}var yi=typeof setTimeout==`function`?setTimeout:void 0,bi=typeof clearTimeout==`function`?clearTimeout:void 0,xi=typeof Promise==`function`?Promise:void 0,J=typeof queueMicrotask==`function`?queueMicrotask:xi===void 0?yi:function(e){return xi.resolve(null).then(e).catch(Si)};function Si(e){setTimeout(function(){throw e})}function Ci(e,t){var n=t,r=0;do{var i=n.nextSibling;if(e.removeChild(n),i&&i.nodeType===8){if(n=i.data,n===`/$`){if(r===0){e.removeChild(i),on(t);return}r--}else n!==`$`&&n!==`$?`&&n!==`$!`||r++}n=i}while(n);on(t)}function wi(e){for(;e!=null;e=e.nextSibling){var t=e.nodeType;if(t===1||t===3)break;if(t===8){if(t=e.data,t===`$`||t===`$!`||t===`$?`)break;if(t===`/$`)return null}}return e}function Ti(e){e=e.previousSibling;for(var t=0;e;){if(e.nodeType===8){var n=e.data;if(n===`$`||n===`$!`||n===`$?`){if(t===0)return e;t--}else n===`/$`&&t++}e=e.previousSibling}return null}var Ei=Math.random().toString(36).slice(2),Di=`__reactFiber$`+Ei,Oi=`__reactProps$`+Ei,ki=`__reactContainer$`+Ei,Ai=`__reactEvents$`+Ei,ji=`__reactListeners$`+Ei,Mi=`__reactHandles$`+Ei;function Ni(e){var t=e[Di];if(t)return t;for(var n=e.parentNode;n;){if(t=n[ki]||n[Di]){if(n=t.alternate,t.child!==null||n!==null&&n.child!==null)for(e=Ti(e);e!==null;){if(n=e[Di])return n;e=Ti(e)}return t}e=n,n=e.parentNode}return null}function Pi(e){return e=e[Di]||e[ki],!e||e.tag!==5&&e.tag!==6&&e.tag!==13&&e.tag!==3?null:e}function Fi(e){if(e.tag===5||e.tag===6)return e.stateNode;throw Error(r(33))}function Ii(e){return e[Oi]||null}var Li=[],Ri=-1;function zi(e){return{current:e}}function Bi(e){0>Ri||(e.current=Li[Ri],Li[Ri]=null,Ri--)}function Y(e,t){Ri++,Li[Ri]=e.current,e.current=t}var Vi={},Hi=zi(Vi),Ui=zi(!1),Wi=Vi;function Gi(e,t){var n=e.type.contextTypes;if(!n)return Vi;var r=e.stateNode;if(r&&r.__reactInternalMemoizedUnmaskedChildContext===t)return r.__reactInternalMemoizedMaskedChildContext;var i={},a;for(a in n)i[a]=t[a];return r&&(e=e.stateNode,e.__reactInternalMemoizedUnmaskedChildContext=t,e.__reactInternalMemoizedMaskedChildContext=i),i}function Ki(e){return e=e.childContextTypes,e!=null}function qi(){Bi(Ui),Bi(Hi)}function Ji(e,t,n){if(Hi.current!==Vi)throw Error(r(168));Y(Hi,t),Y(Ui,n)}function Yi(e,t,n){var i=e.stateNode;if(t=t.childContextTypes,typeof i.getChildContext!=`function`)return n;for(var a in i=i.getChildContext(),i)if(!(a in t))throw Error(r(108,oe(e)||`Unknown`,a));return F({},n,i)}function Xi(e){return e=(e=e.stateNode)&&e.__reactInternalMemoizedMergedChildContext||Vi,Wi=Hi.current,Y(Hi,e),Y(Ui,Ui.current),!0}function Zi(e,t,n){var i=e.stateNode;if(!i)throw Error(r(169));n?(e=Yi(e,t,Wi),i.__reactInternalMemoizedMergedChildContext=e,Bi(Ui),Bi(Hi),Y(Hi,e)):Bi(Ui),Y(Ui,n)}var Qi=null,$i=!1,ea=!1;function ta(e){Qi===null?Qi=[e]:Qi.push(e)}function na(e){$i=!0,ta(e)}function ra(){if(!ea&&Qi!==null){ea=!0;var e=0,t=Ft;try{var n=Qi;for(Ft=1;e<n.length;e++){var r=n[e];do r=r(!0);while(r!==null)}Qi=null,$i=!1}catch(t){throw Qi!==null&&(Qi=Qi.slice(e+1)),at(dt,ra),t}finally{Ft=t,ea=!1}}return null}var ia=[],aa=0,oa=null,sa=0,ca=[],la=0,ua=null,da=1,fa=``;function pa(e,t){ia[aa++]=sa,ia[aa++]=oa,oa=e,sa=t}function ma(e,t,n){ca[la++]=da,ca[la++]=fa,ca[la++]=ua,ua=e;var r=da;e=fa;var i=32-yt(r)-1;r&=~(1<<i),n+=1;var a=32-yt(t)+i;if(30<a){var o=i-i%5;a=(r&(1<<o)-1).toString(32),r>>=o,i-=o,da=1<<32-yt(t)+i|n<<i|r,fa=a+e}else da=1<<a|n<<i|r,fa=e}function ha(e){e.return!==null&&(pa(e,1),ma(e,1,0))}function ga(e){for(;e===oa;)oa=ia[--aa],ia[aa]=null,sa=ia[--aa],ia[aa]=null;for(;e===ua;)ua=ca[--la],ca[la]=null,fa=ca[--la],ca[la]=null,da=ca[--la],ca[la]=null}var _a=null,va=null,ya=!1,ba=null;function xa(e,t){var n=ql(5,null,null,0);n.elementType=`DELETED`,n.stateNode=t,n.return=e,t=e.deletions,t===null?(e.deletions=[n],e.flags|=16):t.push(n)}function Sa(e,t){switch(e.tag){case 5:var n=e.type;return t=t.nodeType!==1||n.toLowerCase()!==t.nodeName.toLowerCase()?null:t,t!==null&&(e.stateNode=t,_a=e,va=wi(t.firstChild),!0);case 6:return t=e.pendingProps===``||t.nodeType!==3?null:t,t!==null&&(e.stateNode=t,_a=e,va=null,!0);case 13:return t=t.nodeType===8?t:null,t!==null&&(n=ua===null?null:{id:da,overflow:fa},e.memoizedState={dehydrated:t,treeContext:n,retryLane:1073741824},n=ql(18,null,null,0),n.stateNode=t,n.return=e,e.child=n,_a=e,va=null,!0);default:return!1}}function Ca(e){return!!(e.mode&1)&&!(e.flags&128)}function wa(e){if(ya){var t=va;if(t){var n=t;if(!Sa(e,t)){if(Ca(e))throw Error(r(418));t=wi(n.nextSibling);var i=_a;t&&Sa(e,t)?xa(i,n):(e.flags=e.flags&-4097|2,ya=!1,_a=e)}}else{if(Ca(e))throw Error(r(418));e.flags=e.flags&-4097|2,ya=!1,_a=e}}}function Ta(e){for(e=e.return;e!==null&&e.tag!==5&&e.tag!==3&&e.tag!==13;)e=e.return;_a=e}function Ea(e){if(e!==_a)return!1;if(!ya)return Ta(e),ya=!0,!1;var t;if((t=e.tag!==3)&&!(t=e.tag!==5)&&(t=e.type,t=t!==`head`&&t!==`body`&&!vi(e.type,e.memoizedProps)),t&&=va){if(Ca(e))throw Da(),Error(r(418));for(;t;)xa(e,t),t=wi(t.nextSibling)}if(Ta(e),e.tag===13){if(e=e.memoizedState,e=e===null?null:e.dehydrated,!e)throw Error(r(317));a:{for(e=e.nextSibling,t=0;e;){if(e.nodeType===8){var n=e.data;if(n===`/$`){if(t===0){va=wi(e.nextSibling);break a}t--}else n!==`$`&&n!==`$!`&&n!==`$?`||t++}e=e.nextSibling}va=null}}else va=_a?wi(e.stateNode.nextSibling):null;return!0}function Da(){for(var e=va;e;)e=wi(e.nextSibling)}function Oa(){va=_a=null,ya=!1}function ka(e){ba===null?ba=[e]:ba.push(e)}var Aa=C.ReactCurrentBatchConfig;function ja(e,t,n){if(e=n.ref,e!==null&&typeof e!=`function`&&typeof e!=`object`){if(n._owner){if(n=n._owner,n){if(n.tag!==1)throw Error(r(309));var i=n.stateNode}if(!i)throw Error(r(147,e));var a=i,o=``+e;return t!==null&&t.ref!==null&&typeof t.ref==`function`&&t.ref._stringRef===o?t.ref:(t=function(e){var t=a.refs;e===null?delete t[o]:t[o]=e},t._stringRef=o,t)}if(typeof e!=`string`)throw Error(r(284));if(!n._owner)throw Error(r(290,e))}return e}function Ma(e,t){throw e=Object.prototype.toString.call(t),Error(r(31,e===`[object Object]`?`object with keys {`+Object.keys(t).join(`, `)+`}`:e))}function Na(e){var t=e._init;return t(e._payload)}function Pa(e){function t(t,n){if(e){var r=t.deletions;r===null?(t.deletions=[n],t.flags|=16):r.push(n)}}function n(n,r){if(!e)return null;for(;r!==null;)t(n,r),r=r.sibling;return null}function i(e,t){for(e=new Map;t!==null;)t.key===null?e.set(t.index,t):e.set(t.key,t),t=t.sibling;return e}function a(e,t){return e=Xl(e,t),e.index=0,e.sibling=null,e}function o(t,n,r){return t.index=r,e?(r=t.alternate,r===null?(t.flags|=2,n):(r=r.index,r<n?(t.flags|=2,n):r)):(t.flags|=1048576,n)}function s(t){return e&&t.alternate===null&&(t.flags|=2),t}function c(e,t,n,r){return t===null||t.tag!==6?(t=eu(n,e.mode,r),t.return=e,t):(t=a(t,n),t.return=e,t)}function l(e,t,n,r){var i=n.type;return i===E?d(e,t,n.props.children,r,n.key):t!==null&&(t.elementType===i||typeof i==`object`&&i&&i.$$typeof===P&&Na(i)===t.type)?(r=a(t,n.props),r.ref=ja(e,t,n),r.return=e,r):(r=Zl(n.type,n.key,n.props,null,e.mode,r),r.ref=ja(e,t,n),r.return=e,r)}function u(e,t,n,r){return t===null||t.tag!==4||t.stateNode.containerInfo!==n.containerInfo||t.stateNode.implementation!==n.implementation?(t=tu(n,e.mode,r),t.return=e,t):(t=a(t,n.children||[]),t.return=e,t)}function d(e,t,n,r,i){return t===null||t.tag!==7?(t=Ql(n,e.mode,r,i),t.return=e,t):(t=a(t,n),t.return=e,t)}function f(e,t,n){if(typeof t==`string`&&t!==``||typeof t==`number`)return t=eu(``+t,e.mode,n),t.return=e,t;if(typeof t==`object`&&t){switch(t.$$typeof){case w:return n=Zl(t.type,t.key,t.props,null,e.mode,n),n.ref=ja(e,null,t),n.return=e,n;case T:return t=tu(t,e.mode,n),t.return=e,t;case P:var r=t._init;return f(e,r(t._payload),n)}if(ge(t)||re(t))return t=Ql(t,e.mode,n,null),t.return=e,t;Ma(e,t)}return null}function p(e,t,n,r){var i=t===null?null:t.key;if(typeof n==`string`&&n!==``||typeof n==`number`)return i===null?c(e,t,``+n,r):null;if(typeof n==`object`&&n){switch(n.$$typeof){case w:return n.key===i?l(e,t,n,r):null;case T:return n.key===i?u(e,t,n,r):null;case P:return i=n._init,p(e,t,i(n._payload),r)}if(ge(n)||re(n))return i===null?d(e,t,n,r,null):null;Ma(e,n)}return null}function m(e,t,n,r,i){if(typeof r==`string`&&r!==``||typeof r==`number`)return e=e.get(n)||null,c(t,e,``+r,i);if(typeof r==`object`&&r){switch(r.$$typeof){case w:return e=e.get(r.key===null?n:r.key)||null,l(t,e,r,i);case T:return e=e.get(r.key===null?n:r.key)||null,u(t,e,r,i);case P:var a=r._init;return m(e,t,n,a(r._payload),i)}if(ge(r)||re(r))return e=e.get(n)||null,d(t,e,r,i,null);Ma(t,r)}return null}function h(r,a,s,c){for(var l=null,u=null,d=a,h=a=0,g=null;d!==null&&h<s.length;h++){d.index>h?(g=d,d=null):g=d.sibling;var _=p(r,d,s[h],c);if(_===null){d===null&&(d=g);break}e&&d&&_.alternate===null&&t(r,d),a=o(_,a,h),u===null?l=_:u.sibling=_,u=_,d=g}if(h===s.length)return n(r,d),ya&&pa(r,h),l;if(d===null){for(;h<s.length;h++)d=f(r,s[h],c),d!==null&&(a=o(d,a,h),u===null?l=d:u.sibling=d,u=d);return ya&&pa(r,h),l}for(d=i(r,d);h<s.length;h++)g=m(d,r,h,s[h],c),g!==null&&(e&&g.alternate!==null&&d.delete(g.key===null?h:g.key),a=o(g,a,h),u===null?l=g:u.sibling=g,u=g);return e&&d.forEach(function(e){return t(r,e)}),ya&&pa(r,h),l}function g(a,s,c,l){var u=re(c);if(typeof u!=`function`)throw Error(r(150));if(c=u.call(c),c==null)throw Error(r(151));for(var d=u=null,h=s,g=s=0,_=null,v=c.next();h!==null&&!v.done;g++,v=c.next()){h.index>g?(_=h,h=null):_=h.sibling;var y=p(a,h,v.value,l);if(y===null){h===null&&(h=_);break}e&&h&&y.alternate===null&&t(a,h),s=o(y,s,g),d===null?u=y:d.sibling=y,d=y,h=_}if(v.done)return n(a,h),ya&&pa(a,g),u;if(h===null){for(;!v.done;g++,v=c.next())v=f(a,v.value,l),v!==null&&(s=o(v,s,g),d===null?u=v:d.sibling=v,d=v);return ya&&pa(a,g),u}for(h=i(a,h);!v.done;g++,v=c.next())v=m(h,a,g,v.value,l),v!==null&&(e&&v.alternate!==null&&h.delete(v.key===null?g:v.key),s=o(v,s,g),d===null?u=v:d.sibling=v,d=v);return e&&h.forEach(function(e){return t(a,e)}),ya&&pa(a,g),u}function _(e,r,i,o){if(typeof i==`object`&&i&&i.type===E&&i.key===null&&(i=i.props.children),typeof i==`object`&&i){switch(i.$$typeof){case w:a:{for(var c=i.key,l=r;l!==null;){if(l.key===c){if(c=i.type,c===E){if(l.tag===7){n(e,l.sibling),r=a(l,i.props.children),r.return=e,e=r;break a}}else if(l.elementType===c||typeof c==`object`&&c&&c.$$typeof===P&&Na(c)===l.type){n(e,l.sibling),r=a(l,i.props),r.ref=ja(e,l,i),r.return=e,e=r;break a}n(e,l);break}t(e,l),l=l.sibling}i.type===E?(r=Ql(i.props.children,e.mode,o,i.key),r.return=e,e=r):(o=Zl(i.type,i.key,i.props,null,e.mode,o),o.ref=ja(e,r,i),o.return=e,e=o)}return s(e);case T:a:{for(l=i.key;r!==null;){if(r.key===l){if(r.tag===4&&r.stateNode.containerInfo===i.containerInfo&&r.stateNode.implementation===i.implementation){n(e,r.sibling),r=a(r,i.children||[]),r.return=e,e=r;break a}n(e,r);break}t(e,r),r=r.sibling}r=tu(i,e.mode,o),r.return=e,e=r}return s(e);case P:return l=i._init,_(e,r,l(i._payload),o)}if(ge(i))return h(e,r,i,o);if(re(i))return g(e,r,i,o);Ma(e,i)}return typeof i==`string`&&i!==``||typeof i==`number`?(i=``+i,r!==null&&r.tag===6?(n(e,r.sibling),r=a(r,i),r.return=e,e=r):(n(e,r),r=eu(i,e.mode,o),r.return=e,e=r),s(e)):n(e,r)}return _}var Fa=Pa(!0),Ia=Pa(!1),La=zi(null),Ra=null,za=null,Ba=null;function Va(){Ba=za=Ra=null}function Ha(e){var t=La.current;Bi(La),e._currentValue=t}function Ua(e,t,n){for(;e!==null;){var r=e.alternate;if((e.childLanes&t)===t?r!==null&&(r.childLanes&t)!==t&&(r.childLanes|=t):(e.childLanes|=t,r!==null&&(r.childLanes|=t)),e===n)break;e=e.return}}function Wa(e,t){Ra=e,Ba=za=null,e=e.dependencies,e!==null&&e.firstContext!==null&&((e.lanes&t)!==0&&(Ns=!0),e.firstContext=null)}function Ga(e){var t=e._currentValue;if(Ba!==e){if(e={context:e,memoizedValue:t,next:null},za===null){if(Ra===null)throw Error(r(308));za=e,Ra.dependencies={lanes:0,firstContext:e}}else za=za.next=e}return t}var Ka=null;function qa(e){Ka===null?Ka=[e]:Ka.push(e)}function Ja(e,t,n,r){var i=t.interleaved;return i===null?(n.next=n,qa(t)):(n.next=i.next,i.next=n),t.interleaved=n,Ya(e,r)}function Ya(e,t){e.lanes|=t;var n=e.alternate;for(n!==null&&(n.lanes|=t),n=e,e=e.return;e!==null;)e.childLanes|=t,n=e.alternate,n!==null&&(n.childLanes|=t),n=e,e=e.return;return n.tag===3?n.stateNode:null}var Xa=!1;function Za(e){e.updateQueue={baseState:e.memoizedState,firstBaseUpdate:null,lastBaseUpdate:null,shared:{pending:null,interleaved:null,lanes:0},effects:null}}function Qa(e,t){e=e.updateQueue,t.updateQueue===e&&(t.updateQueue={baseState:e.baseState,firstBaseUpdate:e.firstBaseUpdate,lastBaseUpdate:e.lastBaseUpdate,shared:e.shared,effects:e.effects})}function $a(e,t){return{eventTime:e,lane:t,tag:0,payload:null,callback:null,next:null}}function eo(e,t,n){var r=e.updateQueue;if(r===null)return null;if(r=r.shared,Hc&2){var i=r.pending;return i===null?t.next=t:(t.next=i.next,i.next=t),r.pending=t,Ya(e,n)}return i=r.interleaved,i===null?(t.next=t,qa(r)):(t.next=i.next,i.next=t),r.interleaved=t,Ya(e,n)}function to(e,t,n){if(t=t.updateQueue,t!==null&&(t=t.shared,n&4194240)){var r=t.lanes;r&=e.pendingLanes,n|=r,t.lanes=n,Pt(e,n)}}function no(e,t){var n=e.updateQueue,r=e.alternate;if(r!==null&&(r=r.updateQueue,n===r)){var i=null,a=null;if(n=n.firstBaseUpdate,n!==null){do{var o={eventTime:n.eventTime,lane:n.lane,tag:n.tag,payload:n.payload,callback:n.callback,next:null};a===null?i=a=o:a=a.next=o,n=n.next}while(n!==null);a===null?i=a=t:a=a.next=t}else i=a=t;n={baseState:r.baseState,firstBaseUpdate:i,lastBaseUpdate:a,shared:r.shared,effects:r.effects},e.updateQueue=n;return}e=n.lastBaseUpdate,e===null?n.firstBaseUpdate=t:e.next=t,n.lastBaseUpdate=t}function ro(e,t,n,r){var i=e.updateQueue;Xa=!1;var a=i.firstBaseUpdate,o=i.lastBaseUpdate,s=i.shared.pending;if(s!==null){i.shared.pending=null;var c=s,l=c.next;c.next=null,o===null?a=l:o.next=l,o=c;var u=e.alternate;u!==null&&(u=u.updateQueue,s=u.lastBaseUpdate,s!==o&&(s===null?u.firstBaseUpdate=l:s.next=l,u.lastBaseUpdate=c))}if(a!==null){var d=i.baseState;o=0,u=l=c=null,s=a;do{var f=s.lane,p=s.eventTime;if((r&f)===f){u!==null&&(u=u.next={eventTime:p,lane:0,tag:s.tag,payload:s.payload,callback:s.callback,next:null});a:{var m=e,h=s;switch(f=t,p=n,h.tag){case 1:if(m=h.payload,typeof m==`function`){d=m.call(p,d,f);break a}d=m;break a;case 3:m.flags=m.flags&-65537|128;case 0:if(m=h.payload,f=typeof m==`function`?m.call(p,d,f):m,f==null)break a;d=F({},d,f);break a;case 2:Xa=!0}}s.callback!==null&&s.lane!==0&&(e.flags|=64,f=i.effects,f===null?i.effects=[s]:f.push(s))}else p={eventTime:p,lane:f,tag:s.tag,payload:s.payload,callback:s.callback,next:null},u===null?(l=u=p,c=d):u=u.next=p,o|=f;if(s=s.next,s===null){if(s=i.shared.pending,s===null)break;f=s,s=f.next,f.next=null,i.lastBaseUpdate=f,i.shared.pending=null}}while(1);if(u===null&&(c=d),i.baseState=c,i.firstBaseUpdate=l,i.lastBaseUpdate=u,t=i.shared.interleaved,t!==null){i=t;do o|=i.lane,i=i.next;while(i!==t)}else a===null&&(i.shared.lanes=0);Xc|=o,e.lanes=o,e.memoizedState=d}}function io(e,t,n){if(e=t.effects,t.effects=null,e!==null)for(t=0;t<e.length;t++){var i=e[t],a=i.callback;if(a!==null){if(i.callback=null,i=n,typeof a!=`function`)throw Error(r(191,a));a.call(i)}}}var ao={},oo=zi(ao),so=zi(ao),co=zi(ao);function lo(e){if(e===ao)throw Error(r(174));return e}function uo(e,t){switch(Y(co,t),Y(so,e),Y(oo,ao),e=t.nodeType,e){case 9:case 11:t=(t=t.documentElement)?t.namespaceURI:Ce(null,``);break;default:e=e===8?t.parentNode:t,t=e.namespaceURI||null,e=e.tagName,t=Ce(t,e)}Bi(oo),Y(oo,t)}function fo(){Bi(oo),Bi(so),Bi(co)}function po(e){lo(co.current);var t=lo(oo.current),n=Ce(t,e.type);t!==n&&(Y(so,e),Y(oo,n))}function mo(e){so.current===e&&(Bi(oo),Bi(so))}var ho=zi(0);function go(e){for(var t=e;t!==null;){if(t.tag===13){var n=t.memoizedState;if(n!==null&&(n=n.dehydrated,n===null||n.data===`$?`||n.data===`$!`))return t}else if(t.tag===19&&t.memoizedProps.revealOrder!==void 0){if(t.flags&128)return t}else if(t.child!==null){t.child.return=t,t=t.child;continue}if(t===e)break;for(;t.sibling===null;){if(t.return===null||t.return===e)return null;t=t.return}t.sibling.return=t.return,t=t.sibling}return null}var _o=[];function vo(){for(var e=0;e<_o.length;e++)_o[e]._workInProgressVersionPrimary=null;_o.length=0}var yo=C.ReactCurrentDispatcher,bo=C.ReactCurrentBatchConfig,xo=0,So=null,Co=null,wo=null,To=!1,Eo=!1,Do=0,Oo=0;function ko(){throw Error(r(321))}function Ao(e,t){if(t===null)return!1;for(var n=0;n<t.length&&n<e.length;n++)if(!Cr(e[n],t[n]))return!1;return!0}function jo(e,t,n,i,a,o){if(xo=o,So=t,t.memoizedState=null,t.updateQueue=null,t.lanes=0,yo.current=e===null||e.memoizedState===null?ps:ms,e=n(i,a),Eo){o=0;do{if(Eo=!1,Do=0,25<=o)throw Error(r(301));o+=1,wo=Co=null,t.updateQueue=null,yo.current=hs,e=n(i,a)}while(Eo)}if(yo.current=fs,t=Co!==null&&Co.next!==null,xo=0,wo=Co=So=null,To=!1,t)throw Error(r(300));return e}function Mo(){var e=Do!==0;return Do=0,e}function No(){var e={memoizedState:null,baseState:null,baseQueue:null,queue:null,next:null};return wo===null?So.memoizedState=wo=e:wo=wo.next=e,wo}function Po(){if(Co===null){var e=So.alternate;e=e===null?null:e.memoizedState}else e=Co.next;var t=wo===null?So.memoizedState:wo.next;if(t!==null)wo=t,Co=e;else{if(e===null)throw Error(r(310));Co=e,e={memoizedState:Co.memoizedState,baseState:Co.baseState,baseQueue:Co.baseQueue,queue:Co.queue,next:null},wo===null?So.memoizedState=wo=e:wo=wo.next=e}return wo}function Fo(e,t){return typeof t==`function`?t(e):t}function Io(e){var t=Po(),n=t.queue;if(n===null)throw Error(r(311));n.lastRenderedReducer=e;var i=Co,a=i.baseQueue,o=n.pending;if(o!==null){if(a!==null){var s=a.next;a.next=o.next,o.next=s}i.baseQueue=a=o,n.pending=null}if(a!==null){o=a.next,i=i.baseState;var c=s=null,l=null,u=o;do{var d=u.lane;if((xo&d)===d)l!==null&&(l=l.next={lane:0,action:u.action,hasEagerState:u.hasEagerState,eagerState:u.eagerState,next:null}),i=u.hasEagerState?u.eagerState:e(i,u.action);else{var f={lane:d,action:u.action,hasEagerState:u.hasEagerState,eagerState:u.eagerState,next:null};l===null?(c=l=f,s=i):l=l.next=f,So.lanes|=d,Xc|=d}u=u.next}while(u!==null&&u!==o);l===null?s=i:l.next=c,Cr(i,t.memoizedState)||(Ns=!0),t.memoizedState=i,t.baseState=s,t.baseQueue=l,n.lastRenderedState=i}if(e=n.interleaved,e!==null){a=e;do o=a.lane,So.lanes|=o,Xc|=o,a=a.next;while(a!==e)}else a===null&&(n.lanes=0);return[t.memoizedState,n.dispatch]}function Lo(e){var t=Po(),n=t.queue;if(n===null)throw Error(r(311));n.lastRenderedReducer=e;var i=n.dispatch,a=n.pending,o=t.memoizedState;if(a!==null){n.pending=null;var s=a=a.next;do o=e(o,s.action),s=s.next;while(s!==a);Cr(o,t.memoizedState)||(Ns=!0),t.memoizedState=o,t.baseQueue===null&&(t.baseState=o),n.lastRenderedState=o}return[o,i]}function Ro(){}function zo(e,t){var n=So,i=Po(),a=t(),o=!Cr(i.memoizedState,a);if(o&&(i.memoizedState=a,Ns=!0),i=i.queue,Xo(Ho.bind(null,n,i,e),[e]),i.getSnapshot!==t||o||wo!==null&&wo.memoizedState.tag&1){if(n.flags|=2048,Ko(9,Vo.bind(null,n,i,a,t),void 0,null),Uc===null)throw Error(r(349));xo&30||Bo(n,t,a)}return a}function Bo(e,t,n){e.flags|=16384,e={getSnapshot:t,value:n},t=So.updateQueue,t===null?(t={lastEffect:null,stores:null},So.updateQueue=t,t.stores=[e]):(n=t.stores,n===null?t.stores=[e]:n.push(e))}function Vo(e,t,n,r){t.value=n,t.getSnapshot=r,Uo(t)&&Wo(e)}function Ho(e,t,n){return n(function(){Uo(t)&&Wo(e)})}function Uo(e){var t=e.getSnapshot;e=e.value;try{var n=t();return!Cr(e,n)}catch{return!0}}function Wo(e){var t=Ya(e,1);t!==null&&hl(t,e,1,-1)}function Go(e){var t=No();return typeof e==`function`&&(e=e()),t.memoizedState=t.baseState=e,e={pending:null,interleaved:null,lanes:0,dispatch:null,lastRenderedReducer:Fo,lastRenderedState:e},t.queue=e,e=e.dispatch=cs.bind(null,So,e),[t.memoizedState,e]}function Ko(e,t,n,r){return e={tag:e,create:t,destroy:n,deps:r,next:null},t=So.updateQueue,t===null?(t={lastEffect:null,stores:null},So.updateQueue=t,t.lastEffect=e.next=e):(n=t.lastEffect,n===null?t.lastEffect=e.next=e:(r=n.next,n.next=e,e.next=r,t.lastEffect=e)),e}function qo(){return Po().memoizedState}function Jo(e,t,n,r){var i=No();So.flags|=e,i.memoizedState=Ko(1|t,n,void 0,r===void 0?null:r)}function Yo(e,t,n,r){var i=Po();r=r===void 0?null:r;var a=void 0;if(Co!==null){var o=Co.memoizedState;if(a=o.destroy,r!==null&&Ao(r,o.deps)){i.memoizedState=Ko(t,n,a,r);return}}So.flags|=e,i.memoizedState=Ko(1|t,n,a,r)}function X(e,t){return Jo(8390656,8,e,t)}function Xo(e,t){return Yo(2048,8,e,t)}function Zo(e,t){return Yo(4,2,e,t)}function Qo(e,t){return Yo(4,4,e,t)}function $o(e,t){if(typeof t==`function`)return e=e(),t(e),function(){t(null)};if(t!=null)return e=e(),t.current=e,function(){t.current=null}}function es(e,t,n){return n=n==null?null:n.concat([e]),Yo(4,4,$o.bind(null,t,e),n)}function ts(){}function ns(e,t){var n=Po();t=t===void 0?null:t;var r=n.memoizedState;return r!==null&&t!==null&&Ao(t,r[1])?r[0]:(n.memoizedState=[e,t],e)}function rs(e,t){var n=Po();t=t===void 0?null:t;var r=n.memoizedState;return r!==null&&t!==null&&Ao(t,r[1])?r[0]:(e=e(),n.memoizedState=[e,t],e)}function is(e,t,n){return xo&21?(Cr(n,t)||(n=At(),So.lanes|=n,Xc|=n,e.baseState=!0),t):(e.baseState&&(e.baseState=!1,Ns=!0),e.memoizedState=n)}function as(e,t){var n=Ft;Ft=n!==0&&4>n?n:4,e(!0);var r=bo.transition;bo.transition={};try{e(!1),t()}finally{Ft=n,bo.transition=r}}function os(){return Po().memoizedState}function ss(e,t,n){var r=ml(e);if(n={lane:r,action:n,hasEagerState:!1,eagerState:null,next:null},ls(e))us(t,n);else if(n=Ja(e,t,n,r),n!==null){var i=pl();hl(n,e,r,i),ds(n,t,r)}}function cs(e,t,n){var r=ml(e),i={lane:r,action:n,hasEagerState:!1,eagerState:null,next:null};if(ls(e))us(t,i);else{var a=e.alternate;if(e.lanes===0&&(a===null||a.lanes===0)&&(a=t.lastRenderedReducer,a!==null))try{var o=t.lastRenderedState,s=a(o,n);if(i.hasEagerState=!0,i.eagerState=s,Cr(s,o)){var c=t.interleaved;c===null?(i.next=i,qa(t)):(i.next=c.next,c.next=i),t.interleaved=i;return}}catch{}n=Ja(e,t,i,r),n!==null&&(i=pl(),hl(n,e,r,i),ds(n,t,r))}}function ls(e){var t=e.alternate;return e===So||t!==null&&t===So}function us(e,t){Eo=To=!0;var n=e.pending;n===null?t.next=t:(t.next=n.next,n.next=t),e.pending=t}function ds(e,t,n){if(n&4194240){var r=t.lanes;r&=e.pendingLanes,n|=r,t.lanes=n,Pt(e,n)}}var fs={readContext:Ga,useCallback:ko,useContext:ko,useEffect:ko,useImperativeHandle:ko,useInsertionEffect:ko,useLayoutEffect:ko,useMemo:ko,useReducer:ko,useRef:ko,useState:ko,useDebugValue:ko,useDeferredValue:ko,useTransition:ko,useMutableSource:ko,useSyncExternalStore:ko,useId:ko,unstable_isNewReconciler:!1},ps={readContext:Ga,useCallback:function(e,t){return No().memoizedState=[e,t===void 0?null:t],e},useContext:Ga,useEffect:X,useImperativeHandle:function(e,t,n){return n=n==null?null:n.concat([e]),Jo(4194308,4,$o.bind(null,t,e),n)},useLayoutEffect:function(e,t){return Jo(4194308,4,e,t)},useInsertionEffect:function(e,t){return Jo(4,2,e,t)},useMemo:function(e,t){var n=No();return t=t===void 0?null:t,e=e(),n.memoizedState=[e,t],e},useReducer:function(e,t,n){var r=No();return t=n===void 0?t:n(t),r.memoizedState=r.baseState=t,e={pending:null,interleaved:null,lanes:0,dispatch:null,lastRenderedReducer:e,lastRenderedState:t},r.queue=e,e=e.dispatch=ss.bind(null,So,e),[r.memoizedState,e]},useRef:function(e){var t=No();return e={current:e},t.memoizedState=e},useState:Go,useDebugValue:ts,useDeferredValue:function(e){return No().memoizedState=e},useTransition:function(){var e=Go(!1),t=e[0];return e=as.bind(null,e[1]),No().memoizedState=e,[t,e]},useMutableSource:function(){},useSyncExternalStore:function(e,t,n){var i=So,a=No();if(ya){if(n===void 0)throw Error(r(407));n=n()}else{if(n=t(),Uc===null)throw Error(r(349));xo&30||Bo(i,t,n)}a.memoizedState=n;var o={value:n,getSnapshot:t};return a.queue=o,X(Ho.bind(null,i,o,e),[e]),i.flags|=2048,Ko(9,Vo.bind(null,i,o,n,t),void 0,null),n},useId:function(){var e=No(),t=Uc.identifierPrefix;if(ya){var n=fa,r=da;n=(r&~(1<<32-yt(r)-1)).toString(32)+n,t=`:`+t+`R`+n,n=Do++,0<n&&(t+=`H`+n.toString(32)),t+=`:`}else n=Oo++,t=`:`+t+`r`+n.toString(32)+`:`;return e.memoizedState=t},unstable_isNewReconciler:!1},ms={readContext:Ga,useCallback:ns,useContext:Ga,useEffect:Xo,useImperativeHandle:es,useInsertionEffect:Zo,useLayoutEffect:Qo,useMemo:rs,useReducer:Io,useRef:qo,useState:function(){return Io(Fo)},useDebugValue:ts,useDeferredValue:function(e){return is(Po(),Co.memoizedState,e)},useTransition:function(){return[Io(Fo)[0],Po().memoizedState]},useMutableSource:Ro,useSyncExternalStore:zo,useId:os,unstable_isNewReconciler:!1},hs={readContext:Ga,useCallback:ns,useContext:Ga,useEffect:Xo,useImperativeHandle:es,useInsertionEffect:Zo,useLayoutEffect:Qo,useMemo:rs,useReducer:Lo,useRef:qo,useState:function(){return Lo(Fo)},useDebugValue:ts,useDeferredValue:function(e){var t=Po();return Co===null?t.memoizedState=e:is(t,Co.memoizedState,e)},useTransition:function(){return[Lo(Fo)[0],Po().memoizedState]},useMutableSource:Ro,useSyncExternalStore:zo,useId:os,unstable_isNewReconciler:!1};function gs(e,t){if(e&&e.defaultProps){for(var n in t=F({},t),e=e.defaultProps,e)t[n]===void 0&&(t[n]=e[n]);return t}return t}function _s(e,t,n,r){t=e.memoizedState,n=n(r,t),n=n==null?t:F({},t,n),e.memoizedState=n,e.lanes===0&&(e.updateQueue.baseState=n)}var vs={isMounted:function(e){return(e=e._reactInternals)?$e(e)===e:!1},enqueueSetState:function(e,t,n){e=e._reactInternals;var r=pl(),i=ml(e),a=$a(r,i);a.payload=t,n!=null&&(a.callback=n),t=eo(e,a,i),t!==null&&(hl(t,e,i,r),to(t,e,i))},enqueueReplaceState:function(e,t,n){e=e._reactInternals;var r=pl(),i=ml(e),a=$a(r,i);a.tag=1,a.payload=t,n!=null&&(a.callback=n),t=eo(e,a,i),t!==null&&(hl(t,e,i,r),to(t,e,i))},enqueueForceUpdate:function(e,t){e=e._reactInternals;var n=pl(),r=ml(e),i=$a(n,r);i.tag=2,t!=null&&(i.callback=t),t=eo(e,i,r),t!==null&&(hl(t,e,r,n),to(t,e,r))}};function ys(e,t,n,r,i,a,o){return e=e.stateNode,typeof e.shouldComponentUpdate==`function`?e.shouldComponentUpdate(r,a,o):t.prototype&&t.prototype.isPureReactComponent?!wr(n,r)||!wr(i,a):!0}function bs(e,t,n){var r=!1,i=Vi,a=t.contextType;return typeof a==`object`&&a?a=Ga(a):(i=Ki(t)?Wi:Hi.current,r=t.contextTypes,a=(r=r!=null)?Gi(e,i):Vi),t=new t(n,a),e.memoizedState=t.state!==null&&t.state!==void 0?t.state:null,t.updater=vs,e.stateNode=t,t._reactInternals=e,r&&(e=e.stateNode,e.__reactInternalMemoizedUnmaskedChildContext=i,e.__reactInternalMemoizedMaskedChildContext=a),t}function xs(e,t,n,r){e=t.state,typeof t.componentWillReceiveProps==`function`&&t.componentWillReceiveProps(n,r),typeof t.UNSAFE_componentWillReceiveProps==`function`&&t.UNSAFE_componentWillReceiveProps(n,r),t.state!==e&&vs.enqueueReplaceState(t,t.state,null)}function Ss(e,t,n,r){var i=e.stateNode;i.props=n,i.state=e.memoizedState,i.refs={},Za(e);var a=t.contextType;typeof a==`object`&&a?i.context=Ga(a):(a=Ki(t)?Wi:Hi.current,i.context=Gi(e,a)),i.state=e.memoizedState,a=t.getDerivedStateFromProps,typeof a==`function`&&(_s(e,t,a,n),i.state=e.memoizedState),typeof t.getDerivedStateFromProps==`function`||typeof i.getSnapshotBeforeUpdate==`function`||typeof i.UNSAFE_componentWillMount!=`function`&&typeof i.componentWillMount!=`function`||(t=i.state,typeof i.componentWillMount==`function`&&i.componentWillMount(),typeof i.UNSAFE_componentWillMount==`function`&&i.UNSAFE_componentWillMount(),t!==i.state&&vs.enqueueReplaceState(i,i.state,null),ro(e,n,i,r),i.state=e.memoizedState),typeof i.componentDidMount==`function`&&(e.flags|=4194308)}function Cs(e,t){try{var n=``,r=t;do n+=ie(r),r=r.return;while(r);var i=n}catch(e){i=`\nError generating stack: `+e.message+`\n`+e.stack}return{value:e,source:t,stack:i,digest:null}}function ws(e,t,n){return{value:e,source:null,stack:n??null,digest:t??null}}function Ts(e,t){try{console.error(t.value)}catch(e){setTimeout(function(){throw e})}}var Es=typeof WeakMap==`function`?WeakMap:Map;function Ds(e,t,n){n=$a(-1,n),n.tag=3,n.payload={element:null};var r=t.value;return n.callback=function(){rl||(rl=!0,il=r),Ts(e,t)},n}function Os(e,t,n){n=$a(-1,n),n.tag=3;var r=e.type.getDerivedStateFromError;if(typeof r==`function`){var i=t.value;n.payload=function(){return r(i)},n.callback=function(){Ts(e,t)}}var a=e.stateNode;return a!==null&&typeof a.componentDidCatch==`function`&&(n.callback=function(){Ts(e,t),typeof r!=`function`&&(al===null?al=new Set([this]):al.add(this));var n=t.stack;this.componentDidCatch(t.value,{componentStack:n===null?``:n})}),n}function ks(e,t,n){var r=e.pingCache;if(r===null){r=e.pingCache=new Es;var i=new Set;r.set(t,i)}else i=r.get(t),i===void 0&&(i=new Set,r.set(t,i));i.has(n)||(i.add(n),e=Bl.bind(null,e,t,n),t.then(e,e))}function As(e){do{var t;if((t=e.tag===13)&&(t=e.memoizedState,t=t===null||t.dehydrated!==null),t)return e;e=e.return}while(e!==null);return null}function js(e,t,n,r,i){return e.mode&1?(e.flags|=65536,e.lanes=i,e):(e===t?e.flags|=65536:(e.flags|=128,n.flags|=131072,n.flags&=-52805,n.tag===1&&(n.alternate===null?n.tag=17:(t=$a(-1,1),t.tag=2,eo(n,t,1))),n.lanes|=1),e)}var Ms=C.ReactCurrentOwner,Ns=!1;function Ps(e,t,n,r){t.child=e===null?Ia(t,null,n,r):Fa(t,e.child,n,r)}function Fs(e,t,n,r,i){n=n.render;var a=t.ref;return Wa(t,i),r=jo(e,t,n,r,a,i),n=Mo(),e!==null&&!Ns?(t.updateQueue=e.updateQueue,t.flags&=-2053,e.lanes&=~i,tc(e,t,i)):(ya&&n&&ha(t),t.flags|=1,Ps(e,t,r,i),t.child)}function Is(e,t,n,r,i){if(e===null){var a=n.type;return typeof a==`function`&&!Jl(a)&&a.defaultProps===void 0&&n.compare===null&&n.defaultProps===void 0?(t.tag=15,t.type=a,Ls(e,t,a,r,i)):(e=Zl(n.type,null,r,t,t.mode,i),e.ref=t.ref,e.return=t,t.child=e)}if(a=e.child,(e.lanes&i)===0){var o=a.memoizedProps;if(n=n.compare,n=n===null?wr:n,n(o,r)&&e.ref===t.ref)return tc(e,t,i)}return t.flags|=1,e=Xl(a,r),e.ref=t.ref,e.return=t,t.child=e}function Ls(e,t,n,r,i){if(e!==null){var a=e.memoizedProps;if(wr(a,r)&&e.ref===t.ref){if(Ns=!1,t.pendingProps=r=a,(e.lanes&i)!==0)e.flags&131072&&(Ns=!0);else return t.lanes=e.lanes,tc(e,t,i)}}return Bs(e,t,n,r,i)}function Rs(e,t,n){var r=t.pendingProps,i=r.children,a=e===null?null:e.memoizedState;if(r.mode===`hidden`){if(!(t.mode&1))t.memoizedState={baseLanes:0,cachePool:null,transitions:null},Y(qc,Kc),Kc|=n;else{if(!(n&1073741824))return e=a===null?n:a.baseLanes|n,t.lanes=t.childLanes=1073741824,t.memoizedState={baseLanes:e,cachePool:null,transitions:null},t.updateQueue=null,Y(qc,Kc),Kc|=e,null;t.memoizedState={baseLanes:0,cachePool:null,transitions:null},r=a===null?n:a.baseLanes,Y(qc,Kc),Kc|=r}}else a===null?r=n:(r=a.baseLanes|n,t.memoizedState=null),Y(qc,Kc),Kc|=r;return Ps(e,t,i,n),t.child}function zs(e,t){var n=t.ref;(e===null&&n!==null||e!==null&&e.ref!==n)&&(t.flags|=512,t.flags|=2097152)}function Bs(e,t,n,r,i){var a=Ki(n)?Wi:Hi.current;return a=Gi(t,a),Wa(t,i),n=jo(e,t,n,r,a,i),r=Mo(),e!==null&&!Ns?(t.updateQueue=e.updateQueue,t.flags&=-2053,e.lanes&=~i,tc(e,t,i)):(ya&&r&&ha(t),t.flags|=1,Ps(e,t,n,i),t.child)}function Vs(e,t,n,r,i){if(Ki(n)){var a=!0;Xi(t)}else a=!1;if(Wa(t,i),t.stateNode===null)ec(e,t),bs(t,n,r),Ss(t,n,r,i),r=!0;else if(e===null){var o=t.stateNode,s=t.memoizedProps;o.props=s;var c=o.context,l=n.contextType;typeof l==`object`&&l?l=Ga(l):(l=Ki(n)?Wi:Hi.current,l=Gi(t,l));var u=n.getDerivedStateFromProps,d=typeof u==`function`||typeof o.getSnapshotBeforeUpdate==`function`;d||typeof o.UNSAFE_componentWillReceiveProps!=`function`&&typeof o.componentWillReceiveProps!=`function`||(s!==r||c!==l)&&xs(t,o,r,l),Xa=!1;var f=t.memoizedState;o.state=f,ro(t,r,o,i),c=t.memoizedState,s!==r||f!==c||Ui.current||Xa?(typeof u==`function`&&(_s(t,n,u,r),c=t.memoizedState),(s=Xa||ys(t,n,s,r,f,c,l))?(d||typeof o.UNSAFE_componentWillMount!=`function`&&typeof o.componentWillMount!=`function`||(typeof o.componentWillMount==`function`&&o.componentWillMount(),typeof o.UNSAFE_componentWillMount==`function`&&o.UNSAFE_componentWillMount()),typeof o.componentDidMount==`function`&&(t.flags|=4194308)):(typeof o.componentDidMount==`function`&&(t.flags|=4194308),t.memoizedProps=r,t.memoizedState=c),o.props=r,o.state=c,o.context=l,r=s):(typeof o.componentDidMount==`function`&&(t.flags|=4194308),r=!1)}else{o=t.stateNode,Qa(e,t),s=t.memoizedProps,l=t.type===t.elementType?s:gs(t.type,s),o.props=l,d=t.pendingProps,f=o.context,c=n.contextType,typeof c==`object`&&c?c=Ga(c):(c=Ki(n)?Wi:Hi.current,c=Gi(t,c));var p=n.getDerivedStateFromProps;(u=typeof p==`function`||typeof o.getSnapshotBeforeUpdate==`function`)||typeof o.UNSAFE_componentWillReceiveProps!=`function`&&typeof o.componentWillReceiveProps!=`function`||(s!==d||f!==c)&&xs(t,o,r,c),Xa=!1,f=t.memoizedState,o.state=f,ro(t,r,o,i);var m=t.memoizedState;s!==d||f!==m||Ui.current||Xa?(typeof p==`function`&&(_s(t,n,p,r),m=t.memoizedState),(l=Xa||ys(t,n,l,r,f,m,c)||!1)?(u||typeof o.UNSAFE_componentWillUpdate!=`function`&&typeof o.componentWillUpdate!=`function`||(typeof o.componentWillUpdate==`function`&&o.componentWillUpdate(r,m,c),typeof o.UNSAFE_componentWillUpdate==`function`&&o.UNSAFE_componentWillUpdate(r,m,c)),typeof o.componentDidUpdate==`function`&&(t.flags|=4),typeof o.getSnapshotBeforeUpdate==`function`&&(t.flags|=1024)):(typeof o.componentDidUpdate!=`function`||s===e.memoizedProps&&f===e.memoizedState||(t.flags|=4),typeof o.getSnapshotBeforeUpdate!=`function`||s===e.memoizedProps&&f===e.memoizedState||(t.flags|=1024),t.memoizedProps=r,t.memoizedState=m),o.props=r,o.state=m,o.context=c,r=l):(typeof o.componentDidUpdate!=`function`||s===e.memoizedProps&&f===e.memoizedState||(t.flags|=4),typeof o.getSnapshotBeforeUpdate!=`function`||s===e.memoizedProps&&f===e.memoizedState||(t.flags|=1024),r=!1)}return Hs(e,t,n,r,a,i)}function Hs(e,t,n,r,i,a){zs(e,t);var o=!!(t.flags&128);if(!r&&!o)return i&&Zi(t,n,!1),tc(e,t,a);r=t.stateNode,Ms.current=t;var s=o&&typeof n.getDerivedStateFromError!=`function`?null:r.render();return t.flags|=1,e!==null&&o?(t.child=Fa(t,e.child,null,a),t.child=Fa(t,null,s,a)):Ps(e,t,s,a),t.memoizedState=r.state,i&&Zi(t,n,!0),t.child}function Us(e){var t=e.stateNode;t.pendingContext?Ji(e,t.pendingContext,t.pendingContext!==t.context):t.context&&Ji(e,t.context,!1),uo(e,t.containerInfo)}function Ws(e,t,n,r,i){return Oa(),ka(i),t.flags|=256,Ps(e,t,n,r),t.child}var Gs={dehydrated:null,treeContext:null,retryLane:0};function Ks(e){return{baseLanes:e,cachePool:null,transitions:null}}function qs(e,t,n){var r=t.pendingProps,i=ho.current,a=!1,o=!!(t.flags&128),s;if((s=o)||(s=e!==null&&e.memoizedState===null?!1:!!(i&2)),s?(a=!0,t.flags&=-129):(e===null||e.memoizedState!==null)&&(i|=1),Y(ho,i&1),e===null)return wa(t),e=t.memoizedState,e!==null&&(e=e.dehydrated,e!==null)?(t.lanes=t.mode&1?e.data===`$!`?8:1073741824:1,null):(o=r.children,e=r.fallback,a?(r=t.mode,a=t.child,o={mode:`hidden`,children:o},!(r&1)&&a!==null?(a.childLanes=0,a.pendingProps=o):a=$l(o,r,0,null),e=Ql(e,r,n,null),a.return=t,e.return=t,a.sibling=e,t.child=a,t.child.memoizedState=Ks(n),t.memoizedState=Gs,e):Js(t,o));if(i=e.memoizedState,i!==null&&(s=i.dehydrated,s!==null))return Xs(e,t,o,r,s,i,n);if(a){a=r.fallback,o=t.mode,i=e.child,s=i.sibling;var c={mode:`hidden`,children:r.children};return!(o&1)&&t.child!==i?(r=t.child,r.childLanes=0,r.pendingProps=c,t.deletions=null):(r=Xl(i,c),r.subtreeFlags=i.subtreeFlags&14680064),s===null?(a=Ql(a,o,n,null),a.flags|=2):a=Xl(s,a),a.return=t,r.return=t,r.sibling=a,t.child=r,r=a,a=t.child,o=e.child.memoizedState,o=o===null?Ks(n):{baseLanes:o.baseLanes|n,cachePool:null,transitions:o.transitions},a.memoizedState=o,a.childLanes=e.childLanes&~n,t.memoizedState=Gs,r}return a=e.child,e=a.sibling,r=Xl(a,{mode:`visible`,children:r.children}),!(t.mode&1)&&(r.lanes=n),r.return=t,r.sibling=null,e!==null&&(n=t.deletions,n===null?(t.deletions=[e],t.flags|=16):n.push(e)),t.child=r,t.memoizedState=null,r}function Js(e,t){return t=$l({mode:`visible`,children:t},e.mode,0,null),t.return=e,e.child=t}function Ys(e,t,n,r){return r!==null&&ka(r),Fa(t,e.child,null,n),e=Js(t,t.pendingProps.children),e.flags|=2,t.memoizedState=null,e}function Xs(e,t,n,i,a,o,s){if(n)return t.flags&256?(t.flags&=-257,i=ws(Error(r(422))),Ys(e,t,s,i)):t.memoizedState===null?(o=i.fallback,a=t.mode,i=$l({mode:`visible`,children:i.children},a,0,null),o=Ql(o,a,s,null),o.flags|=2,i.return=t,o.return=t,i.sibling=o,t.child=i,t.mode&1&&Fa(t,e.child,null,s),t.child.memoizedState=Ks(s),t.memoizedState=Gs,o):(t.child=e.child,t.flags|=128,null);if(!(t.mode&1))return Ys(e,t,s,null);if(a.data===`$!`){if(i=a.nextSibling&&a.nextSibling.dataset,i)var c=i.dgst;return i=c,o=Error(r(419)),i=ws(o,i,void 0),Ys(e,t,s,i)}if(c=(s&e.childLanes)!==0,Ns||c){if(i=Uc,i!==null){switch(s&-s){case 4:a=2;break;case 16:a=8;break;case 64:case 128:case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:case 4194304:case 8388608:case 16777216:case 33554432:case 67108864:a=32;break;case 536870912:a=268435456;break;default:a=0}a=(a&(i.suspendedLanes|s))===0?a:0,a!==0&&a!==o.retryLane&&(o.retryLane=a,Ya(e,a),hl(i,e,a,-1))}return kl(),i=ws(Error(r(421))),Ys(e,t,s,i)}return a.data===`$?`?(t.flags|=128,t.child=e.child,t=Hl.bind(null,e),a._reactRetry=t,null):(e=o.treeContext,va=wi(a.nextSibling),_a=t,ya=!0,ba=null,e!==null&&(ca[la++]=da,ca[la++]=fa,ca[la++]=ua,da=e.id,fa=e.overflow,ua=t),t=Js(t,i.children),t.flags|=4096,t)}function Zs(e,t,n){e.lanes|=t;var r=e.alternate;r!==null&&(r.lanes|=t),Ua(e.return,t,n)}function Qs(e,t,n,r,i){var a=e.memoizedState;a===null?e.memoizedState={isBackwards:t,rendering:null,renderingStartTime:0,last:r,tail:n,tailMode:i}:(a.isBackwards=t,a.rendering=null,a.renderingStartTime=0,a.last=r,a.tail=n,a.tailMode=i)}function $s(e,t,n){var r=t.pendingProps,i=r.revealOrder,a=r.tail;if(Ps(e,t,r.children,n),r=ho.current,r&2)r=r&1|2,t.flags|=128;else{if(e!==null&&e.flags&128)a:for(e=t.child;e!==null;){if(e.tag===13)e.memoizedState!==null&&Zs(e,n,t);else if(e.tag===19)Zs(e,n,t);else if(e.child!==null){e.child.return=e,e=e.child;continue}if(e===t)break a;for(;e.sibling===null;){if(e.return===null||e.return===t)break a;e=e.return}e.sibling.return=e.return,e=e.sibling}r&=1}if(Y(ho,r),!(t.mode&1))t.memoizedState=null;else switch(i){case`forwards`:for(n=t.child,i=null;n!==null;)e=n.alternate,e!==null&&go(e)===null&&(i=n),n=n.sibling;n=i,n===null?(i=t.child,t.child=null):(i=n.sibling,n.sibling=null),Qs(t,!1,i,n,a);break;case`backwards`:for(n=null,i=t.child,t.child=null;i!==null;){if(e=i.alternate,e!==null&&go(e)===null){t.child=i;break}e=i.sibling,i.sibling=n,n=i,i=e}Qs(t,!0,n,null,a);break;case`together`:Qs(t,!1,null,null,void 0);break;default:t.memoizedState=null}return t.child}function ec(e,t){!(t.mode&1)&&e!==null&&(e.alternate=null,t.alternate=null,t.flags|=2)}function tc(e,t,n){if(e!==null&&(t.dependencies=e.dependencies),Xc|=t.lanes,(n&t.childLanes)===0)return null;if(e!==null&&t.child!==e.child)throw Error(r(153));if(t.child!==null){for(e=t.child,n=Xl(e,e.pendingProps),t.child=n,n.return=t;e.sibling!==null;)e=e.sibling,n=n.sibling=Xl(e,e.pendingProps),n.return=t;n.sibling=null}return t.child}function nc(e,t,n){switch(t.tag){case 3:Us(t),Oa();break;case 5:po(t);break;case 1:Ki(t.type)&&Xi(t);break;case 4:uo(t,t.stateNode.containerInfo);break;case 10:var r=t.type._context,i=t.memoizedProps.value;Y(La,r._currentValue),r._currentValue=i;break;case 13:if(r=t.memoizedState,r!==null)return r.dehydrated===null?(n&t.child.childLanes)===0?(Y(ho,ho.current&1),e=tc(e,t,n),e===null?null:e.sibling):qs(e,t,n):(Y(ho,ho.current&1),t.flags|=128,null);Y(ho,ho.current&1);break;case 19:if(r=(n&t.childLanes)!==0,e.flags&128){if(r)return $s(e,t,n);t.flags|=128}if(i=t.memoizedState,i!==null&&(i.rendering=null,i.tail=null,i.lastEffect=null),Y(ho,ho.current),r)break;return null;case 22:case 23:return t.lanes=0,Rs(e,t,n)}return tc(e,t,n)}var rc=function(e,t){for(var n=t.child;n!==null;){if(n.tag===5||n.tag===6)e.appendChild(n.stateNode);else if(n.tag!==4&&n.child!==null){n.child.return=n,n=n.child;continue}if(n===t)break;for(;n.sibling===null;){if(n.return===null||n.return===t)return;n=n.return}n.sibling.return=n.return,n=n.sibling}},ic=function(e,t,n,r){var i=e.memoizedProps;if(i!==r){e=t.stateNode,lo(oo.current);var o=null;switch(n){case`input`:i=de(e,i),r=de(e,r),o=[];break;case`select`:i=F({},i,{value:void 0}),r=F({},r,{value:void 0}),o=[];break;case`textarea`:i=ve(e,i),r=ve(e,r),o=[];break;default:typeof i.onClick!=`function`&&typeof r.onClick==`function`&&(e.onclick=hi)}ke(n,r);var s;for(u in n=null,i)if(!r.hasOwnProperty(u)&&i.hasOwnProperty(u)&&i[u]!=null){if(u===`style`){var c=i[u];for(s in c)c.hasOwnProperty(s)&&(n||={},n[s]=``)}else u!==`dangerouslySetInnerHTML`&&u!==`children`&&u!==`suppressContentEditableWarning`&&u!==`suppressHydrationWarning`&&u!==`autoFocus`&&(a.hasOwnProperty(u)?o||=[]:(o||=[]).push(u,null))}for(u in r){var l=r[u];if(c=i?.[u],r.hasOwnProperty(u)&&l!==c&&(l!=null||c!=null)){if(u===`style`){if(c){for(s in c)!c.hasOwnProperty(s)||l&&l.hasOwnProperty(s)||(n||={},n[s]=``);for(s in l)l.hasOwnProperty(s)&&c[s]!==l[s]&&(n||={},n[s]=l[s])}else n||(o||=[],o.push(u,n)),n=l}else u===`dangerouslySetInnerHTML`?(l=l?l.__html:void 0,c=c?c.__html:void 0,l!=null&&c!==l&&(o||=[]).push(u,l)):u===`children`?typeof l!=`string`&&typeof l!=`number`||(o||=[]).push(u,``+l):u!==`suppressContentEditableWarning`&&u!==`suppressHydrationWarning`&&(a.hasOwnProperty(u)?(l!=null&&u===`onScroll`&&ti(`scroll`,e),o||c===l||(o=[])):(o||=[]).push(u,l))}}n&&(o||=[]).push(`style`,n);var u=o;(t.updateQueue=u)&&(t.flags|=4)}},ac=function(e,t,n,r){n!==r&&(t.flags|=4)};function oc(e,t){if(!ya)switch(e.tailMode){case`hidden`:t=e.tail;for(var n=null;t!==null;)t.alternate!==null&&(n=t),t=t.sibling;n===null?e.tail=null:n.sibling=null;break;case`collapsed`:n=e.tail;for(var r=null;n!==null;)n.alternate!==null&&(r=n),n=n.sibling;r===null?t||e.tail===null?e.tail=null:e.tail.sibling=null:r.sibling=null}}function sc(e){var t=e.alternate!==null&&e.alternate.child===e.child,n=0,r=0;if(t)for(var i=e.child;i!==null;)n|=i.lanes|i.childLanes,r|=i.subtreeFlags&14680064,r|=i.flags&14680064,i.return=e,i=i.sibling;else for(i=e.child;i!==null;)n|=i.lanes|i.childLanes,r|=i.subtreeFlags,r|=i.flags,i.return=e,i=i.sibling;return e.subtreeFlags|=r,e.childLanes=n,t}function cc(e,t,n){var i=t.pendingProps;switch(ga(t),t.tag){case 2:case 16:case 15:case 0:case 11:case 7:case 8:case 12:case 9:case 14:return sc(t),null;case 1:return Ki(t.type)&&qi(),sc(t),null;case 3:return i=t.stateNode,fo(),Bi(Ui),Bi(Hi),vo(),i.pendingContext&&(i.context=i.pendingContext,i.pendingContext=null),(e===null||e.child===null)&&(Ea(t)?t.flags|=4:e===null||e.memoizedState.isDehydrated&&!(t.flags&256)||(t.flags|=1024,ba!==null&&(yl(ba),ba=null))),sc(t),null;case 5:mo(t);var o=lo(co.current);if(n=t.type,e!==null&&t.stateNode!=null)ic(e,t,n,i,o),e.ref!==t.ref&&(t.flags|=512,t.flags|=2097152);else{if(!i){if(t.stateNode===null)throw Error(r(166));return sc(t),null}if(e=lo(oo.current),Ea(t)){i=t.stateNode,n=t.type;var s=t.memoizedProps;switch(i[Di]=t,i[Oi]=s,e=!!(t.mode&1),n){case`dialog`:ti(`cancel`,i),ti(`close`,i);break;case`iframe`:case`object`:case`embed`:ti(`load`,i);break;case`video`:case`audio`:for(o=0;o<Zr.length;o++)ti(Zr[o],i);break;case`source`:ti(`error`,i);break;case`img`:case`image`:case`link`:ti(`error`,i),ti(`load`,i);break;case`details`:ti(`toggle`,i);break;case`input`:fe(i,s),ti(`invalid`,i);break;case`select`:i._wrapperState={wasMultiple:!!s.multiple},ti(`invalid`,i);break;case`textarea`:ye(i,s),ti(`invalid`,i)}for(var c in ke(n,s),o=null,s)if(s.hasOwnProperty(c)){var l=s[c];c===`children`?typeof l==`string`?i.textContent!==l&&(!0!==s.suppressHydrationWarning&&mi(i.textContent,l,e),o=[`children`,l]):typeof l==`number`&&i.textContent!==``+l&&(!0!==s.suppressHydrationWarning&&mi(i.textContent,l,e),o=[`children`,``+l]):a.hasOwnProperty(c)&&l!=null&&c===`onScroll`&&ti(`scroll`,i)}switch(n){case`input`:ce(i),me(i,s,!0);break;case`textarea`:ce(i),xe(i);break;case`select`:case`option`:break;default:typeof s.onClick==`function`&&(i.onclick=hi)}i=o,t.updateQueue=i,i!==null&&(t.flags|=4)}else{c=o.nodeType===9?o:o.ownerDocument,e===`http://www.w3.org/1999/xhtml`&&(e=Se(n)),e===`http://www.w3.org/1999/xhtml`?n===`script`?(e=c.createElement(`div`),e.innerHTML=`<script><\\/script>`,e=e.removeChild(e.firstChild)):typeof i.is==`string`?e=c.createElement(n,{is:i.is}):(e=c.createElement(n),n===`select`&&(c=e,i.multiple?c.multiple=!0:i.size&&(c.size=i.size))):e=c.createElementNS(e,n),e[Di]=t,e[Oi]=i,rc(e,t,!1,!1),t.stateNode=e;a:{switch(c=Ae(n,i),n){case`dialog`:ti(`cancel`,e),ti(`close`,e),o=i;break;case`iframe`:case`object`:case`embed`:ti(`load`,e),o=i;break;case`video`:case`audio`:for(o=0;o<Zr.length;o++)ti(Zr[o],e);o=i;break;case`source`:ti(`error`,e),o=i;break;case`img`:case`image`:case`link`:ti(`error`,e),ti(`load`,e),o=i;break;case`details`:ti(`toggle`,e),o=i;break;case`input`:fe(e,i),o=de(e,i),ti(`invalid`,e);break;case`option`:o=i;break;case`select`:e._wrapperState={wasMultiple:!!i.multiple},o=F({},i,{value:void 0}),ti(`invalid`,e);break;case`textarea`:ye(e,i),o=ve(e,i),ti(`invalid`,e);break;default:o=i}for(s in ke(n,o),l=o,l)if(l.hasOwnProperty(s)){var u=l[s];s===`style`?De(e,u):s===`dangerouslySetInnerHTML`?(u=u?u.__html:void 0,u!=null&&we(e,u)):s===`children`?typeof u==`string`?(n!==`textarea`||u!==``)&&W(e,u):typeof u==`number`&&W(e,``+u):s!==`suppressContentEditableWarning`&&s!==`suppressHydrationWarning`&&s!==`autoFocus`&&(a.hasOwnProperty(s)?u!=null&&s===`onScroll`&&ti(`scroll`,e):u!=null&&S(e,s,u,c))}switch(n){case`input`:ce(e),me(e,i,!1);break;case`textarea`:ce(e),xe(e);break;case`option`:i.value!=null&&e.setAttribute(`value`,``+B(i.value));break;case`select`:e.multiple=!!i.multiple,s=i.value,s==null?i.defaultValue!=null&&_e(e,!!i.multiple,i.defaultValue,!0):_e(e,!!i.multiple,s,!1);break;default:typeof o.onClick==`function`&&(e.onclick=hi)}switch(n){case`button`:case`input`:case`select`:case`textarea`:i=!!i.autoFocus;break a;case`img`:i=!0;break a;default:i=!1}}i&&(t.flags|=4)}t.ref!==null&&(t.flags|=512,t.flags|=2097152)}return sc(t),null;case 6:if(e&&t.stateNode!=null)ac(e,t,e.memoizedProps,i);else{if(typeof i!=`string`&&t.stateNode===null)throw Error(r(166));if(n=lo(co.current),lo(oo.current),Ea(t)){if(i=t.stateNode,n=t.memoizedProps,i[Di]=t,(s=i.nodeValue!==n)&&(e=_a,e!==null))switch(e.tag){case 3:mi(i.nodeValue,n,!!(e.mode&1));break;case 5:!0!==e.memoizedProps.suppressHydrationWarning&&mi(i.nodeValue,n,!!(e.mode&1))}s&&(t.flags|=4)}else i=(n.nodeType===9?n:n.ownerDocument).createTextNode(i),i[Di]=t,t.stateNode=i}return sc(t),null;case 13:if(Bi(ho),i=t.memoizedState,e===null||e.memoizedState!==null&&e.memoizedState.dehydrated!==null){if(ya&&va!==null&&t.mode&1&&!(t.flags&128))Da(),Oa(),t.flags|=98560,s=!1;else if(s=Ea(t),i!==null&&i.dehydrated!==null){if(e===null){if(!s)throw Error(r(318));if(s=t.memoizedState,s=s===null?null:s.dehydrated,!s)throw Error(r(317));s[Di]=t}else Oa(),!(t.flags&128)&&(t.memoizedState=null),t.flags|=4;sc(t),s=!1}else ba!==null&&(yl(ba),ba=null),s=!0;if(!s)return t.flags&65536?t:null}return t.flags&128?(t.lanes=n,t):(i=i!==null,i!==(e!==null&&e.memoizedState!==null)&&i&&(t.child.flags|=8192,t.mode&1&&(e===null||ho.current&1?Jc===0&&(Jc=3):kl())),t.updateQueue!==null&&(t.flags|=4),sc(t),null);case 4:return fo(),e===null&&ii(t.stateNode.containerInfo),sc(t),null;case 10:return Ha(t.type._context),sc(t),null;case 17:return Ki(t.type)&&qi(),sc(t),null;case 19:if(Bi(ho),s=t.memoizedState,s===null)return sc(t),null;if(i=!!(t.flags&128),c=s.rendering,c===null){if(i)oc(s,!1);else{if(Jc!==0||e!==null&&e.flags&128)for(e=t.child;e!==null;){if(c=go(e),c!==null){for(t.flags|=128,oc(s,!1),i=c.updateQueue,i!==null&&(t.updateQueue=i,t.flags|=4),t.subtreeFlags=0,i=n,n=t.child;n!==null;)s=n,e=i,s.flags&=14680066,c=s.alternate,c===null?(s.childLanes=0,s.lanes=e,s.child=null,s.subtreeFlags=0,s.memoizedProps=null,s.memoizedState=null,s.updateQueue=null,s.dependencies=null,s.stateNode=null):(s.childLanes=c.childLanes,s.lanes=c.lanes,s.child=c.child,s.subtreeFlags=0,s.deletions=null,s.memoizedProps=c.memoizedProps,s.memoizedState=c.memoizedState,s.updateQueue=c.updateQueue,s.type=c.type,e=c.dependencies,s.dependencies=e===null?null:{lanes:e.lanes,firstContext:e.firstContext}),n=n.sibling;return Y(ho,ho.current&1|2),t.child}e=e.sibling}s.tail!==null&&lt()>tl&&(t.flags|=128,i=!0,oc(s,!1),t.lanes=4194304)}}else{if(!i){if(e=go(c),e!==null){if(t.flags|=128,i=!0,n=e.updateQueue,n!==null&&(t.updateQueue=n,t.flags|=4),oc(s,!0),s.tail===null&&s.tailMode===`hidden`&&!c.alternate&&!ya)return sc(t),null}else 2*lt()-s.renderingStartTime>tl&&n!==1073741824&&(t.flags|=128,i=!0,oc(s,!1),t.lanes=4194304)}s.isBackwards?(c.sibling=t.child,t.child=c):(n=s.last,n===null?t.child=c:n.sibling=c,s.last=c)}return s.tail===null?(sc(t),null):(t=s.tail,s.rendering=t,s.tail=t.sibling,s.renderingStartTime=lt(),t.sibling=null,n=ho.current,Y(ho,i?n&1|2:n&1),t);case 22:case 23:return Tl(),i=t.memoizedState!==null,e!==null&&e.memoizedState!==null!==i&&(t.flags|=8192),i&&t.mode&1?Kc&1073741824&&(sc(t),t.subtreeFlags&6&&(t.flags|=8192)):sc(t),null;case 24:return null;case 25:return null}throw Error(r(156,t.tag))}function lc(e,t){switch(ga(t),t.tag){case 1:return Ki(t.type)&&qi(),e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 3:return fo(),Bi(Ui),Bi(Hi),vo(),e=t.flags,e&65536&&!(e&128)?(t.flags=e&-65537|128,t):null;case 5:return mo(t),null;case 13:if(Bi(ho),e=t.memoizedState,e!==null&&e.dehydrated!==null){if(t.alternate===null)throw Error(r(340));Oa()}return e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 19:return Bi(ho),null;case 4:return fo(),null;case 10:return Ha(t.type._context),null;case 22:case 23:return Tl(),null;case 24:return null;default:return null}}var uc=!1,dc=!1,fc=typeof WeakSet==`function`?WeakSet:Set,Z=null;function pc(e,t){var n=e.ref;if(n!==null){if(typeof n==`function`)try{n(null)}catch(n){zl(e,t,n)}else n.current=null}}function mc(e,t,n){try{n()}catch(n){zl(e,t,n)}}var hc=!1;function gc(e,t){if(gi=cn,e=Or(),kr(e)){if(`selectionStart`in e)var n={start:e.selectionStart,end:e.selectionEnd};else a:{n=(n=e.ownerDocument)&&n.defaultView||window;var i=n.getSelection&&n.getSelection();if(i&&i.rangeCount!==0){n=i.anchorNode;var a=i.anchorOffset,o=i.focusNode;i=i.focusOffset;try{n.nodeType,o.nodeType}catch{n=null;break a}var s=0,c=-1,l=-1,u=0,d=0,f=e,p=null;b:for(;;){for(var m;f!==n||a!==0&&f.nodeType!==3||(c=s+a),f!==o||i!==0&&f.nodeType!==3||(l=s+i),f.nodeType===3&&(s+=f.nodeValue.length),(m=f.firstChild)!==null;)p=f,f=m;for(;;){if(f===e)break b;if(p===n&&++u===a&&(c=s),p===o&&++d===i&&(l=s),(m=f.nextSibling)!==null)break;f=p,p=f.parentNode}f=m}n=c===-1||l===-1?null:{start:c,end:l}}else n=null}n||={start:0,end:0}}else n=null;for(_i={focusedElem:e,selectionRange:n},cn=!1,Z=t;Z!==null;)if(t=Z,e=t.child,t.subtreeFlags&1028&&e!==null)e.return=t,Z=e;else for(;Z!==null;){t=Z;try{var h=t.alternate;if(t.flags&1024)switch(t.tag){case 0:case 11:case 15:break;case 1:if(h!==null){var g=h.memoizedProps,_=h.memoizedState,v=t.stateNode;v.__reactInternalSnapshotBeforeUpdate=v.getSnapshotBeforeUpdate(t.elementType===t.type?g:gs(t.type,g),_)}break;case 3:var y=t.stateNode.containerInfo;y.nodeType===1?y.textContent=``:y.nodeType===9&&y.documentElement&&y.removeChild(y.documentElement);break;case 5:case 6:case 4:case 17:break;default:throw Error(r(163))}}catch(e){zl(t,t.return,e)}if(e=t.sibling,e!==null){e.return=t.return,Z=e;break}Z=t.return}return h=hc,hc=!1,h}function _c(e,t,n){var r=t.updateQueue;if(r=r===null?null:r.lastEffect,r!==null){var i=r=r.next;do{if((i.tag&e)===e){var a=i.destroy;i.destroy=void 0,a!==void 0&&mc(t,n,a)}i=i.next}while(i!==r)}}function vc(e,t){if(t=t.updateQueue,t=t===null?null:t.lastEffect,t!==null){var n=t=t.next;do{if((n.tag&e)===e){var r=n.create;n.destroy=r()}n=n.next}while(n!==t)}}function yc(e){var t=e.ref;if(t!==null){var n=e.stateNode;switch(e.tag){case 5:e=n;break;default:e=n}typeof t==`function`?t(e):t.current=e}}function bc(e){var t=e.alternate;t!==null&&(e.alternate=null,bc(t)),e.child=null,e.deletions=null,e.sibling=null,e.tag===5&&(t=e.stateNode,t!==null&&(delete t[Di],delete t[Oi],delete t[Ai],delete t[ji],delete t[Mi])),e.stateNode=null,e.return=null,e.dependencies=null,e.memoizedProps=null,e.memoizedState=null,e.pendingProps=null,e.stateNode=null,e.updateQueue=null}function xc(e){return e.tag===5||e.tag===3||e.tag===4}function Sc(e){a:for(;;){for(;e.sibling===null;){if(e.return===null||xc(e.return))return null;e=e.return}for(e.sibling.return=e.return,e=e.sibling;e.tag!==5&&e.tag!==6&&e.tag!==18;){if(e.flags&2||e.child===null||e.tag===4)continue a;e.child.return=e,e=e.child}if(!(e.flags&2))return e.stateNode}}function Cc(e,t,n){var r=e.tag;if(r===5||r===6)e=e.stateNode,t?n.nodeType===8?n.parentNode.insertBefore(e,t):n.insertBefore(e,t):(n.nodeType===8?(t=n.parentNode,t.insertBefore(e,n)):(t=n,t.appendChild(e)),n=n._reactRootContainer,n!=null||t.onclick!==null||(t.onclick=hi));else if(r!==4&&(e=e.child,e!==null))for(Cc(e,t,n),e=e.sibling;e!==null;)Cc(e,t,n),e=e.sibling}function wc(e,t,n){var r=e.tag;if(r===5||r===6)e=e.stateNode,t?n.insertBefore(e,t):n.appendChild(e);else if(r!==4&&(e=e.child,e!==null))for(wc(e,t,n),e=e.sibling;e!==null;)wc(e,t,n),e=e.sibling}var Tc=null,Ec=!1;function Dc(e,t,n){for(n=n.child;n!==null;)Oc(e,t,n),n=n.sibling}function Oc(e,t,n){if(_t&&typeof _t.onCommitFiberUnmount==`function`)try{_t.onCommitFiberUnmount(gt,n)}catch{}switch(n.tag){case 5:dc||pc(n,t);case 6:var r=Tc,i=Ec;Tc=null,Dc(e,t,n),Tc=r,Ec=i,Tc!==null&&(Ec?(e=Tc,n=n.stateNode,e.nodeType===8?e.parentNode.removeChild(n):e.removeChild(n)):Tc.removeChild(n.stateNode));break;case 18:Tc!==null&&(Ec?(e=Tc,n=n.stateNode,e.nodeType===8?Ci(e.parentNode,n):e.nodeType===1&&Ci(e,n),on(e)):Ci(Tc,n.stateNode));break;case 4:r=Tc,i=Ec,Tc=n.stateNode.containerInfo,Ec=!0,Dc(e,t,n),Tc=r,Ec=i;break;case 0:case 11:case 14:case 15:if(!dc&&(r=n.updateQueue,r!==null&&(r=r.lastEffect,r!==null))){i=r=r.next;do{var a=i,o=a.destroy;a=a.tag,o!==void 0&&(a&2||a&4)&&mc(n,t,o),i=i.next}while(i!==r)}Dc(e,t,n);break;case 1:if(!dc&&(pc(n,t),r=n.stateNode,typeof r.componentWillUnmount==`function`))try{r.props=n.memoizedProps,r.state=n.memoizedState,r.componentWillUnmount()}catch(e){zl(n,t,e)}Dc(e,t,n);break;case 21:Dc(e,t,n);break;case 22:n.mode&1?(dc=(r=dc)||n.memoizedState!==null,Dc(e,t,n),dc=r):Dc(e,t,n);break;default:Dc(e,t,n)}}function kc(e){var t=e.updateQueue;if(t!==null){e.updateQueue=null;var n=e.stateNode;n===null&&(n=e.stateNode=new fc),t.forEach(function(t){var r=Ul.bind(null,e,t);n.has(t)||(n.add(t),t.then(r,r))})}}function Ac(e,t){var n=t.deletions;if(n!==null)for(var i=0;i<n.length;i++){var a=n[i];try{var o=e,s=t,c=s;a:for(;c!==null;){switch(c.tag){case 5:Tc=c.stateNode,Ec=!1;break a;case 3:Tc=c.stateNode.containerInfo,Ec=!0;break a;case 4:Tc=c.stateNode.containerInfo,Ec=!0;break a}c=c.return}if(Tc===null)throw Error(r(160));Oc(o,s,a),Tc=null,Ec=!1;var l=a.alternate;l!==null&&(l.return=null),a.return=null}catch(e){zl(a,t,e)}}if(t.subtreeFlags&12854)for(t=t.child;t!==null;)jc(t,e),t=t.sibling}function jc(e,t){var n=e.alternate,i=e.flags;switch(e.tag){case 0:case 11:case 14:case 15:if(Ac(t,e),Mc(e),i&4){try{_c(3,e,e.return),vc(3,e)}catch(t){zl(e,e.return,t)}try{_c(5,e,e.return)}catch(t){zl(e,e.return,t)}}break;case 1:Ac(t,e),Mc(e),i&512&&n!==null&&pc(n,n.return);break;case 5:if(Ac(t,e),Mc(e),i&512&&n!==null&&pc(n,n.return),e.flags&32){var a=e.stateNode;try{W(a,``)}catch(t){zl(e,e.return,t)}}if(i&4&&(a=e.stateNode,a!=null)){var o=e.memoizedProps,s=n===null?o:n.memoizedProps,c=e.type,l=e.updateQueue;if(e.updateQueue=null,l!==null)try{c===`input`&&o.type===`radio`&&o.name!=null&&pe(a,o),Ae(c,s);var u=Ae(c,o);for(s=0;s<l.length;s+=2){var d=l[s],f=l[s+1];d===`style`?De(a,f):d===`dangerouslySetInnerHTML`?we(a,f):d===`children`?W(a,f):S(a,d,f,u)}switch(c){case`input`:H(a,o);break;case`textarea`:be(a,o);break;case`select`:var p=a._wrapperState.wasMultiple;a._wrapperState.wasMultiple=!!o.multiple;var m=o.value;m==null?p!==!!o.multiple&&(o.defaultValue==null?_e(a,!!o.multiple,o.multiple?[]:``,!1):_e(a,!!o.multiple,o.defaultValue,!0)):_e(a,!!o.multiple,m,!1)}a[Oi]=o}catch(t){zl(e,e.return,t)}}break;case 6:if(Ac(t,e),Mc(e),i&4){if(e.stateNode===null)throw Error(r(162));a=e.stateNode,o=e.memoizedProps;try{a.nodeValue=o}catch(t){zl(e,e.return,t)}}break;case 3:if(Ac(t,e),Mc(e),i&4&&n!==null&&n.memoizedState.isDehydrated)try{on(t.containerInfo)}catch(t){zl(e,e.return,t)}break;case 4:Ac(t,e),Mc(e);break;case 13:Ac(t,e),Mc(e),a=e.child,a.flags&8192&&(o=a.memoizedState!==null,a.stateNode.isHidden=o,!o||a.alternate!==null&&a.alternate.memoizedState!==null||(el=lt())),i&4&&kc(e);break;case 22:if(d=n!==null&&n.memoizedState!==null,e.mode&1?(dc=(u=dc)||d,Ac(t,e),dc=u):Ac(t,e),Mc(e),i&8192){if(u=e.memoizedState!==null,(e.stateNode.isHidden=u)&&!d&&e.mode&1)for(Z=e,d=e.child;d!==null;){for(f=Z=d;Z!==null;){switch(p=Z,m=p.child,p.tag){case 0:case 11:case 14:case 15:_c(4,p,p.return);break;case 1:pc(p,p.return);var h=p.stateNode;if(typeof h.componentWillUnmount==`function`){i=p,n=p.return;try{t=i,h.props=t.memoizedProps,h.state=t.memoizedState,h.componentWillUnmount()}catch(e){zl(i,n,e)}}break;case 5:pc(p,p.return);break;case 22:if(p.memoizedState!==null){Ic(f);continue}}m===null?Ic(f):(m.return=p,Z=m)}d=d.sibling}a:for(d=null,f=e;;){if(f.tag===5){if(d===null){d=f;try{a=f.stateNode,u?(o=a.style,typeof o.setProperty==`function`?o.setProperty(`display`,`none`,`important`):o.display=`none`):(c=f.stateNode,l=f.memoizedProps.style,s=l!=null&&l.hasOwnProperty(`display`)?l.display:null,c.style.display=G(`display`,s))}catch(t){zl(e,e.return,t)}}}else if(f.tag===6){if(d===null)try{f.stateNode.nodeValue=u?``:f.memoizedProps}catch(t){zl(e,e.return,t)}}else if((f.tag!==22&&f.tag!==23||f.memoizedState===null||f===e)&&f.child!==null){f.child.return=f,f=f.child;continue}if(f===e)break a;for(;f.sibling===null;){if(f.return===null||f.return===e)break a;d===f&&(d=null),f=f.return}d===f&&(d=null),f.sibling.return=f.return,f=f.sibling}}break;case 19:Ac(t,e),Mc(e),i&4&&kc(e);break;case 21:break;default:Ac(t,e),Mc(e)}}function Mc(e){var t=e.flags;if(t&2){try{a:{for(var n=e.return;n!==null;){if(xc(n)){var i=n;break a}n=n.return}throw Error(r(160))}switch(i.tag){case 5:var a=i.stateNode;i.flags&32&&(W(a,``),i.flags&=-33),wc(e,Sc(e),a);break;case 3:case 4:var o=i.stateNode.containerInfo;Cc(e,Sc(e),o);break;default:throw Error(r(161))}}catch(t){zl(e,e.return,t)}e.flags&=-3}t&4096&&(e.flags&=-4097)}function Nc(e,t,n){Z=e,Pc(e,t,n)}function Pc(e,t,n){for(var r=!!(e.mode&1);Z!==null;){var i=Z,a=i.child;if(i.tag===22&&r){var o=i.memoizedState!==null||uc;if(!o){var s=i.alternate,c=s!==null&&s.memoizedState!==null||dc;s=uc;var l=dc;if(uc=o,(dc=c)&&!l)for(Z=i;Z!==null;)o=Z,c=o.child,o.tag===22&&o.memoizedState!==null||c===null?Lc(i):(c.return=o,Z=c);for(;a!==null;)Z=a,Pc(a,t,n),a=a.sibling;Z=i,uc=s,dc=l}Fc(e,t,n)}else i.subtreeFlags&8772&&a!==null?(a.return=i,Z=a):Fc(e,t,n)}}function Fc(e){for(;Z!==null;){var t=Z;if(t.flags&8772){var n=t.alternate;try{if(t.flags&8772)switch(t.tag){case 0:case 11:case 15:dc||vc(5,t);break;case 1:var i=t.stateNode;if(t.flags&4&&!dc){if(n===null)i.componentDidMount();else{var a=t.elementType===t.type?n.memoizedProps:gs(t.type,n.memoizedProps);i.componentDidUpdate(a,n.memoizedState,i.__reactInternalSnapshotBeforeUpdate)}}var o=t.updateQueue;o!==null&&io(t,o,i);break;case 3:var s=t.updateQueue;if(s!==null){if(n=null,t.child!==null)switch(t.child.tag){case 5:n=t.child.stateNode;break;case 1:n=t.child.stateNode}io(t,s,n)}break;case 5:var c=t.stateNode;if(n===null&&t.flags&4){n=c;var l=t.memoizedProps;switch(t.type){case`button`:case`input`:case`select`:case`textarea`:l.autoFocus&&n.focus();break;case`img`:l.src&&(n.src=l.src)}}break;case 6:break;case 4:break;case 12:break;case 13:if(t.memoizedState===null){var u=t.alternate;if(u!==null){var d=u.memoizedState;if(d!==null){var f=d.dehydrated;f!==null&&on(f)}}}break;case 19:case 17:case 21:case 22:case 23:case 25:break;default:throw Error(r(163))}dc||t.flags&512&&yc(t)}catch(e){zl(t,t.return,e)}}if(t===e){Z=null;break}if(n=t.sibling,n!==null){n.return=t.return,Z=n;break}Z=t.return}}function Ic(e){for(;Z!==null;){var t=Z;if(t===e){Z=null;break}var n=t.sibling;if(n!==null){n.return=t.return,Z=n;break}Z=t.return}}function Lc(e){for(;Z!==null;){var t=Z;try{switch(t.tag){case 0:case 11:case 15:var n=t.return;try{vc(4,t)}catch(e){zl(t,n,e)}break;case 1:var r=t.stateNode;if(typeof r.componentDidMount==`function`){var i=t.return;try{r.componentDidMount()}catch(e){zl(t,i,e)}}var a=t.return;try{yc(t)}catch(e){zl(t,a,e)}break;case 5:var o=t.return;try{yc(t)}catch(e){zl(t,o,e)}}}catch(e){zl(t,t.return,e)}if(t===e){Z=null;break}var s=t.sibling;if(s!==null){s.return=t.return,Z=s;break}Z=t.return}}var Rc=Math.ceil,zc=C.ReactCurrentDispatcher,Bc=C.ReactCurrentOwner,Vc=C.ReactCurrentBatchConfig,Hc=0,Uc=null,Wc=null,Gc=0,Kc=0,qc=zi(0),Jc=0,Yc=null,Xc=0,Zc=0,Qc=0,$c=null,Q=null,el=0,tl=1/0,nl=null,rl=!1,il=null,al=null,ol=!1,sl=null,cl=0,ll=0,ul=null,dl=-1,fl=0;function pl(){return Hc&6?lt():dl===-1?dl=lt():dl}function ml(e){return e.mode&1?Hc&2&&Gc!==0?Gc&-Gc:Aa.transition===null?(e=Ft,e===0?(e=window.event,e=e===void 0?16:mn(e.type),e):e):(fl===0&&(fl=At()),fl):1}function hl(e,t,n,i){if(50<ll)throw ll=0,ul=null,Error(r(185));Mt(e,n,i),(!(Hc&2)||e!==Uc)&&(e===Uc&&(!(Hc&2)&&(Zc|=n),Jc===4&&xl(e,Gc)),gl(e,i),n===1&&Hc===0&&!(t.mode&1)&&(tl=lt()+500,$i&&ra()))}function gl(e,t){var n=e.callbackNode;Ot(e,t);var r=Et(e,e===Uc?Gc:0);if(r===0)n!==null&&ot(n),e.callbackNode=null,e.callbackPriority=0;else if(t=r&-r,e.callbackPriority!==t){if(n!=null&&ot(n),t===1)e.tag===0?na(Sl.bind(null,e)):ta(Sl.bind(null,e)),J(function(){!(Hc&6)&&ra()}),n=null;else{switch(It(r)){case 1:n=dt;break;case 4:n=ft;break;case 16:n=pt;break;case 536870912:n=ht;break;default:n=pt}n=Gl(n,_l.bind(null,e))}e.callbackPriority=t,e.callbackNode=n}}function _l(e,t){if(dl=-1,fl=0,Hc&6)throw Error(r(327));var n=e.callbackNode;if(Ll()&&e.callbackNode!==n)return null;var i=Et(e,e===Uc?Gc:0);if(i===0)return null;if(i&30||(i&e.expiredLanes)!==0||t)t=Al(e,i);else{t=i;var a=Hc;Hc|=2;var o=Ol();(Uc!==e||Gc!==t)&&(nl=null,tl=lt()+500,El(e,t));do try{Ml();break}catch(t){Dl(e,t)}while(1);Va(),zc.current=o,Hc=a,Wc===null?(Uc=null,Gc=0,t=Jc):t=0}if(t!==0){if(t===2&&(a=kt(e),a!==0&&(i=a,t=vl(e,a))),t===1)throw n=Yc,El(e,0),xl(e,i),gl(e,lt()),n;if(t===6)xl(e,i);else{if(a=e.current.alternate,!(i&30)&&!bl(a)&&(t=Al(e,i),t===2&&(o=kt(e),o!==0&&(i=o,t=vl(e,o))),t===1))throw n=Yc,El(e,0),xl(e,i),gl(e,lt()),n;switch(e.finishedWork=a,e.finishedLanes=i,t){case 0:case 1:throw Error(r(345));case 2:Fl(e,Q,nl);break;case 3:if(xl(e,i),(i&130023424)===i&&(t=el+500-lt(),10<t)){if(Et(e,0)!==0)break;if(a=e.suspendedLanes,(a&i)!==i){pl(),e.pingedLanes|=e.suspendedLanes&a;break}e.timeoutHandle=yi(Fl.bind(null,e,Q,nl),t);break}Fl(e,Q,nl);break;case 4:if(xl(e,i),(i&4194240)===i)break;for(t=e.eventTimes,a=-1;0<i;){var s=31-yt(i);o=1<<s,s=t[s],s>a&&(a=s),i&=~o}if(i=a,i=lt()-i,i=(120>i?120:480>i?480:1080>i?1080:1920>i?1920:3e3>i?3e3:4320>i?4320:1960*Rc(i/1960))-i,10<i){e.timeoutHandle=yi(Fl.bind(null,e,Q,nl),i);break}Fl(e,Q,nl);break;case 5:Fl(e,Q,nl);break;default:throw Error(r(329))}}}return gl(e,lt()),e.callbackNode===n?_l.bind(null,e):null}function vl(e,t){var n=$c;return e.current.memoizedState.isDehydrated&&(El(e,t).flags|=256),e=Al(e,t),e!==2&&(t=Q,Q=n,t!==null&&yl(t)),e}function yl(e){Q===null?Q=e:Q.push.apply(Q,e)}function bl(e){for(var t=e;;){if(t.flags&16384){var n=t.updateQueue;if(n!==null&&(n=n.stores,n!==null))for(var r=0;r<n.length;r++){var i=n[r],a=i.getSnapshot;i=i.value;try{if(!Cr(a(),i))return!1}catch{return!1}}}if(n=t.child,t.subtreeFlags&16384&&n!==null)n.return=t,t=n;else{if(t===e)break;for(;t.sibling===null;){if(t.return===null||t.return===e)return!0;t=t.return}t.sibling.return=t.return,t=t.sibling}}return!0}function xl(e,t){for(t&=~Qc,t&=~Zc,e.suspendedLanes|=t,e.pingedLanes&=~t,e=e.expirationTimes;0<t;){var n=31-yt(t),r=1<<n;e[n]=-1,t&=~r}}function Sl(e){if(Hc&6)throw Error(r(327));Ll();var t=Et(e,0);if(!(t&1))return gl(e,lt()),null;var n=Al(e,t);if(e.tag!==0&&n===2){var i=kt(e);i!==0&&(t=i,n=vl(e,i))}if(n===1)throw n=Yc,El(e,0),xl(e,t),gl(e,lt()),n;if(n===6)throw Error(r(345));return e.finishedWork=e.current.alternate,e.finishedLanes=t,Fl(e,Q,nl),gl(e,lt()),null}function Cl(e,t){var n=Hc;Hc|=1;try{return e(t)}finally{Hc=n,Hc===0&&(tl=lt()+500,$i&&ra())}}function wl(e){sl!==null&&sl.tag===0&&!(Hc&6)&&Ll();var t=Hc;Hc|=1;var n=Vc.transition,r=Ft;try{if(Vc.transition=null,Ft=1,e)return e()}finally{Ft=r,Vc.transition=n,Hc=t,!(Hc&6)&&ra()}}function Tl(){Kc=qc.current,Bi(qc)}function El(e,t){e.finishedWork=null,e.finishedLanes=0;var n=e.timeoutHandle;if(n!==-1&&(e.timeoutHandle=-1,bi(n)),Wc!==null)for(n=Wc.return;n!==null;){var r=n;switch(ga(r),r.tag){case 1:r=r.type.childContextTypes,r!=null&&qi();break;case 3:fo(),Bi(Ui),Bi(Hi),vo();break;case 5:mo(r);break;case 4:fo();break;case 13:Bi(ho);break;case 19:Bi(ho);break;case 10:Ha(r.type._context);break;case 22:case 23:Tl()}n=n.return}if(Uc=e,Wc=e=Xl(e.current,null),Gc=Kc=t,Jc=0,Yc=null,Qc=Zc=Xc=0,Q=$c=null,Ka!==null){for(t=0;t<Ka.length;t++)if(n=Ka[t],r=n.interleaved,r!==null){n.interleaved=null;var i=r.next,a=n.pending;if(a!==null){var o=a.next;a.next=i,r.next=o}n.pending=r}Ka=null}return e}function Dl(e,t){do{var n=Wc;try{if(Va(),yo.current=fs,To){for(var i=So.memoizedState;i!==null;){var a=i.queue;a!==null&&(a.pending=null),i=i.next}To=!1}if(xo=0,wo=Co=So=null,Eo=!1,Do=0,Bc.current=null,n===null||n.return===null){Jc=1,Yc=t,Wc=null;break}a:{var o=e,s=n.return,c=n,l=t;if(t=Gc,c.flags|=32768,typeof l==`object`&&l&&typeof l.then==`function`){var u=l,d=c,f=d.tag;if(!(d.mode&1)&&(f===0||f===11||f===15)){var p=d.alternate;p?(d.updateQueue=p.updateQueue,d.memoizedState=p.memoizedState,d.lanes=p.lanes):(d.updateQueue=null,d.memoizedState=null)}var m=As(s);if(m!==null){m.flags&=-257,js(m,s,c,o,t),m.mode&1&&ks(o,u,t),t=m,l=u;var h=t.updateQueue;if(h===null){var g=new Set;g.add(l),t.updateQueue=g}else h.add(l);break a}if(!(t&1)){ks(o,u,t),kl();break a}l=Error(r(426))}else if(ya&&c.mode&1){var _=As(s);if(_!==null){!(_.flags&65536)&&(_.flags|=256),js(_,s,c,o,t),ka(Cs(l,c));break a}}o=l=Cs(l,c),Jc!==4&&(Jc=2),$c===null?$c=[o]:$c.push(o),o=s;do{switch(o.tag){case 3:o.flags|=65536,t&=-t,o.lanes|=t;var v=Ds(o,l,t);no(o,v);break a;case 1:c=l;var y=o.type,b=o.stateNode;if(!(o.flags&128)&&(typeof y.getDerivedStateFromError==`function`||b!==null&&typeof b.componentDidCatch==`function`&&(al===null||!al.has(b)))){o.flags|=65536,t&=-t,o.lanes|=t;var x=Os(o,c,t);no(o,x);break a}}o=o.return}while(o!==null)}Pl(n)}catch(e){t=e,Wc===n&&n!==null&&(Wc=n=n.return);continue}break}while(1)}function Ol(){var e=zc.current;return zc.current=fs,e===null?fs:e}function kl(){(Jc===0||Jc===3||Jc===2)&&(Jc=4),Uc===null||!(Xc&268435455)&&!(Zc&268435455)||xl(Uc,Gc)}function Al(e,t){var n=Hc;Hc|=2;var i=Ol();(Uc!==e||Gc!==t)&&(nl=null,El(e,t));do try{jl();break}catch(t){Dl(e,t)}while(1);if(Va(),Hc=n,zc.current=i,Wc!==null)throw Error(r(261));return Uc=null,Gc=0,Jc}function jl(){for(;Wc!==null;)Nl(Wc)}function Ml(){for(;Wc!==null&&!st();)Nl(Wc)}function Nl(e){var t=Wl(e.alternate,e,Kc);e.memoizedProps=e.pendingProps,t===null?Pl(e):Wc=t,Bc.current=null}function Pl(e){var t=e;do{var n=t.alternate;if(e=t.return,t.flags&32768){if(n=lc(n,t),n!==null){n.flags&=32767,Wc=n;return}if(e!==null)e.flags|=32768,e.subtreeFlags=0,e.deletions=null;else{Jc=6,Wc=null;return}}else if(n=cc(n,t,Kc),n!==null){Wc=n;return}if(t=t.sibling,t!==null){Wc=t;return}Wc=t=e}while(t!==null);Jc===0&&(Jc=5)}function Fl(e,t,n){var r=Ft,i=Vc.transition;try{Vc.transition=null,Ft=1,Il(e,t,n,r)}finally{Vc.transition=i,Ft=r}return null}function Il(e,t,n,i){do Ll();while(sl!==null);if(Hc&6)throw Error(r(327));n=e.finishedWork;var a=e.finishedLanes;if(n===null)return null;if(e.finishedWork=null,e.finishedLanes=0,n===e.current)throw Error(r(177));e.callbackNode=null,e.callbackPriority=0;var o=n.lanes|n.childLanes;if(Nt(e,o),e===Uc&&(Wc=Uc=null,Gc=0),!(n.subtreeFlags&2064)&&!(n.flags&2064)||ol||(ol=!0,Gl(pt,function(){return Ll(),null})),o=!!(n.flags&15990),n.subtreeFlags&15990||o){o=Vc.transition,Vc.transition=null;var s=Ft;Ft=1;var c=Hc;Hc|=4,Bc.current=null,gc(e,n),jc(n,e),Ar(_i),cn=!!gi,_i=gi=null,e.current=n,Nc(n,e,a),ct(),Hc=c,Ft=s,Vc.transition=o}else e.current=n;if(ol&&(ol=!1,sl=e,cl=a),o=e.pendingLanes,o===0&&(al=null),vt(n.stateNode,i),gl(e,lt()),t!==null)for(i=e.onRecoverableError,n=0;n<t.length;n++)a=t[n],i(a.value,{componentStack:a.stack,digest:a.digest});if(rl)throw rl=!1,e=il,il=null,e;return cl&1&&e.tag!==0&&Ll(),o=e.pendingLanes,o&1?e===ul?ll++:(ll=0,ul=e):ll=0,ra(),null}function Ll(){if(sl!==null){var e=It(cl),t=Vc.transition,n=Ft;try{if(Vc.transition=null,Ft=16>e?16:e,sl===null)var i=!1;else{if(e=sl,sl=null,cl=0,Hc&6)throw Error(r(331));var a=Hc;for(Hc|=4,Z=e.current;Z!==null;){var o=Z,s=o.child;if(Z.flags&16){var c=o.deletions;if(c!==null){for(var l=0;l<c.length;l++){var u=c[l];for(Z=u;Z!==null;){var d=Z;switch(d.tag){case 0:case 11:case 15:_c(8,d,o)}var f=d.child;if(f!==null)f.return=d,Z=f;else for(;Z!==null;){d=Z;var p=d.sibling,m=d.return;if(bc(d),d===u){Z=null;break}if(p!==null){p.return=m,Z=p;break}Z=m}}}var h=o.alternate;if(h!==null){var g=h.child;if(g!==null){h.child=null;do{var _=g.sibling;g.sibling=null,g=_}while(g!==null)}}Z=o}}if(o.subtreeFlags&2064&&s!==null)s.return=o,Z=s;else b:for(;Z!==null;){if(o=Z,o.flags&2048)switch(o.tag){case 0:case 11:case 15:_c(9,o,o.return)}var v=o.sibling;if(v!==null){v.return=o.return,Z=v;break b}Z=o.return}}var y=e.current;for(Z=y;Z!==null;){s=Z;var b=s.child;if(s.subtreeFlags&2064&&b!==null)b.return=s,Z=b;else b:for(s=y;Z!==null;){if(c=Z,c.flags&2048)try{switch(c.tag){case 0:case 11:case 15:vc(9,c)}}catch(e){zl(c,c.return,e)}if(c===s){Z=null;break b}var x=c.sibling;if(x!==null){x.return=c.return,Z=x;break b}Z=c.return}}if(Hc=a,ra(),_t&&typeof _t.onPostCommitFiberRoot==`function`)try{_t.onPostCommitFiberRoot(gt,e)}catch{}i=!0}return i}finally{Ft=n,Vc.transition=t}}return!1}function Rl(e,t,n){t=Cs(n,t),t=Ds(e,t,1),e=eo(e,t,1),t=pl(),e!==null&&(Mt(e,1,t),gl(e,t))}function zl(e,t,n){if(e.tag===3)Rl(e,e,n);else for(;t!==null;){if(t.tag===3){Rl(t,e,n);break}if(t.tag===1){var r=t.stateNode;if(typeof t.type.getDerivedStateFromError==`function`||typeof r.componentDidCatch==`function`&&(al===null||!al.has(r))){e=Cs(n,e),e=Os(t,e,1),t=eo(t,e,1),e=pl(),t!==null&&(Mt(t,1,e),gl(t,e));break}}t=t.return}}function Bl(e,t,n){var r=e.pingCache;r!==null&&r.delete(t),t=pl(),e.pingedLanes|=e.suspendedLanes&n,Uc===e&&(Gc&n)===n&&(Jc===4||Jc===3&&(Gc&130023424)===Gc&&500>lt()-el?El(e,0):Qc|=n),gl(e,t)}function Vl(e,t){t===0&&(e.mode&1?(t=wt,wt<<=1,!(wt&130023424)&&(wt=4194304)):t=1);var n=pl();e=Ya(e,t),e!==null&&(Mt(e,t,n),gl(e,n))}function Hl(e){var t=e.memoizedState,n=0;t!==null&&(n=t.retryLane),Vl(e,n)}function Ul(e,t){var n=0;switch(e.tag){case 13:var i=e.stateNode,a=e.memoizedState;a!==null&&(n=a.retryLane);break;case 19:i=e.stateNode;break;default:throw Error(r(314))}i!==null&&i.delete(t),Vl(e,n)}var Wl=function(e,t,n){if(e!==null){if(e.memoizedProps!==t.pendingProps||Ui.current)Ns=!0;else{if((e.lanes&n)===0&&!(t.flags&128))return Ns=!1,nc(e,t,n);Ns=!!(e.flags&131072)}}else Ns=!1,ya&&t.flags&1048576&&ma(t,sa,t.index);switch(t.lanes=0,t.tag){case 2:var i=t.type;ec(e,t),e=t.pendingProps;var a=Gi(t,Hi.current);Wa(t,n),a=jo(null,t,i,e,a,n);var o=Mo();return t.flags|=1,typeof a==`object`&&a&&typeof a.render==`function`&&a.$$typeof===void 0?(t.tag=1,t.memoizedState=null,t.updateQueue=null,Ki(i)?(o=!0,Xi(t)):o=!1,t.memoizedState=a.state!==null&&a.state!==void 0?a.state:null,Za(t),a.updater=vs,t.stateNode=a,a._reactInternals=t,Ss(t,i,e,n),t=Hs(null,t,i,!0,o,n)):(t.tag=0,ya&&o&&ha(t),Ps(null,t,a,n),t=t.child),t;case 16:i=t.elementType;a:{switch(ec(e,t),e=t.pendingProps,a=i._init,i=a(i._payload),t.type=i,a=t.tag=Yl(i),e=gs(i,e),a){case 0:t=Bs(null,t,i,e,n);break a;case 1:t=Vs(null,t,i,e,n);break a;case 11:t=Fs(null,t,i,e,n);break a;case 14:t=Is(null,t,i,gs(i.type,e),n);break a}throw Error(r(306,i,``))}return t;case 0:return i=t.type,a=t.pendingProps,a=t.elementType===i?a:gs(i,a),Bs(e,t,i,a,n);case 1:return i=t.type,a=t.pendingProps,a=t.elementType===i?a:gs(i,a),Vs(e,t,i,a,n);case 3:a:{if(Us(t),e===null)throw Error(r(387));i=t.pendingProps,o=t.memoizedState,a=o.element,Qa(e,t),ro(t,i,null,n);var s=t.memoizedState;if(i=s.element,o.isDehydrated){if(o={element:i,isDehydrated:!1,cache:s.cache,pendingSuspenseBoundaries:s.pendingSuspenseBoundaries,transitions:s.transitions},t.updateQueue.baseState=o,t.memoizedState=o,t.flags&256){a=Cs(Error(r(423)),t),t=Ws(e,t,i,n,a);break a}if(i!==a){a=Cs(Error(r(424)),t),t=Ws(e,t,i,n,a);break a}for(va=wi(t.stateNode.containerInfo.firstChild),_a=t,ya=!0,ba=null,n=Ia(t,null,i,n),t.child=n;n;)n.flags=n.flags&-3|4096,n=n.sibling}else{if(Oa(),i===a){t=tc(e,t,n);break a}Ps(e,t,i,n)}t=t.child}return t;case 5:return po(t),e===null&&wa(t),i=t.type,a=t.pendingProps,o=e===null?null:e.memoizedProps,s=a.children,vi(i,a)?s=null:o!==null&&vi(i,o)&&(t.flags|=32),zs(e,t),Ps(e,t,s,n),t.child;case 6:return e===null&&wa(t),null;case 13:return qs(e,t,n);case 4:return uo(t,t.stateNode.containerInfo),i=t.pendingProps,e===null?t.child=Fa(t,null,i,n):Ps(e,t,i,n),t.child;case 11:return i=t.type,a=t.pendingProps,a=t.elementType===i?a:gs(i,a),Fs(e,t,i,a,n);case 7:return Ps(e,t,t.pendingProps,n),t.child;case 8:return Ps(e,t,t.pendingProps.children,n),t.child;case 12:return Ps(e,t,t.pendingProps.children,n),t.child;case 10:a:{if(i=t.type._context,a=t.pendingProps,o=t.memoizedProps,s=a.value,Y(La,i._currentValue),i._currentValue=s,o!==null){if(Cr(o.value,s)){if(o.children===a.children&&!Ui.current){t=tc(e,t,n);break a}}else for(o=t.child,o!==null&&(o.return=t);o!==null;){var c=o.dependencies;if(c!==null){s=o.child;for(var l=c.firstContext;l!==null;){if(l.context===i){if(o.tag===1){l=$a(-1,n&-n),l.tag=2;var u=o.updateQueue;if(u!==null){u=u.shared;var d=u.pending;d===null?l.next=l:(l.next=d.next,d.next=l),u.pending=l}}o.lanes|=n,l=o.alternate,l!==null&&(l.lanes|=n),Ua(o.return,n,t),c.lanes|=n;break}l=l.next}}else if(o.tag===10)s=o.type===t.type?null:o.child;else if(o.tag===18){if(s=o.return,s===null)throw Error(r(341));s.lanes|=n,c=s.alternate,c!==null&&(c.lanes|=n),Ua(s,n,t),s=o.sibling}else s=o.child;if(s!==null)s.return=o;else for(s=o;s!==null;){if(s===t){s=null;break}if(o=s.sibling,o!==null){o.return=s.return,s=o;break}s=s.return}o=s}}Ps(e,t,a.children,n),t=t.child}return t;case 9:return a=t.type,i=t.pendingProps.children,Wa(t,n),a=Ga(a),i=i(a),t.flags|=1,Ps(e,t,i,n),t.child;case 14:return i=t.type,a=gs(i,t.pendingProps),a=gs(i.type,a),Is(e,t,i,a,n);case 15:return Ls(e,t,t.type,t.pendingProps,n);case 17:return i=t.type,a=t.pendingProps,a=t.elementType===i?a:gs(i,a),ec(e,t),t.tag=1,Ki(i)?(e=!0,Xi(t)):e=!1,Wa(t,n),bs(t,i,a),Ss(t,i,a,n),Hs(null,t,i,!0,e,n);case 19:return $s(e,t,n);case 22:return Rs(e,t,n)}throw Error(r(156,t.tag))};function Gl(e,t){return at(e,t)}function Kl(e,t,n,r){this.tag=e,this.key=n,this.sibling=this.child=this.return=this.stateNode=this.type=this.elementType=null,this.index=0,this.ref=null,this.pendingProps=t,this.dependencies=this.memoizedState=this.updateQueue=this.memoizedProps=null,this.mode=r,this.subtreeFlags=this.flags=0,this.deletions=null,this.childLanes=this.lanes=0,this.alternate=null}function ql(e,t,n,r){return new Kl(e,t,n,r)}function Jl(e){return e=e.prototype,!(!e||!e.isReactComponent)}function Yl(e){if(typeof e==`function`)return+!!Jl(e);if(e!=null){if(e=e.$$typeof,e===j)return 11;if(e===N)return 14}return 2}function Xl(e,t){var n=e.alternate;return n===null?(n=ql(e.tag,t,e.key,e.mode),n.elementType=e.elementType,n.type=e.type,n.stateNode=e.stateNode,n.alternate=e,e.alternate=n):(n.pendingProps=t,n.type=e.type,n.flags=0,n.subtreeFlags=0,n.deletions=null),n.flags=e.flags&14680064,n.childLanes=e.childLanes,n.lanes=e.lanes,n.child=e.child,n.memoizedProps=e.memoizedProps,n.memoizedState=e.memoizedState,n.updateQueue=e.updateQueue,t=e.dependencies,n.dependencies=t===null?null:{lanes:t.lanes,firstContext:t.firstContext},n.sibling=e.sibling,n.index=e.index,n.ref=e.ref,n}function Zl(e,t,n,i,a,o){var s=2;if(i=e,typeof e==`function`)Jl(e)&&(s=1);else if(typeof e==`string`)s=5;else a:switch(e){case E:return Ql(n.children,a,o,t);case D:s=8,a|=8;break;case O:return e=ql(12,n,t,a|2),e.elementType=O,e.lanes=o,e;case M:return e=ql(13,n,t,a),e.elementType=M,e.lanes=o,e;case ee:return e=ql(19,n,t,a),e.elementType=ee,e.lanes=o,e;case te:return $l(n,a,o,t);default:if(typeof e==`object`&&e)switch(e.$$typeof){case k:s=10;break a;case A:s=9;break a;case j:s=11;break a;case N:s=14;break a;case P:s=16,i=null;break a}throw Error(r(130,e==null?e:typeof e,``))}return t=ql(s,n,t,a),t.elementType=e,t.type=i,t.lanes=o,t}function Ql(e,t,n,r){return e=ql(7,e,r,t),e.lanes=n,e}function $l(e,t,n,r){return e=ql(22,e,r,t),e.elementType=te,e.lanes=n,e.stateNode={isHidden:!1},e}function eu(e,t,n){return e=ql(6,e,null,t),e.lanes=n,e}function tu(e,t,n){return t=ql(4,e.children===null?[]:e.children,e.key,t),t.lanes=n,t.stateNode={containerInfo:e.containerInfo,pendingChildren:null,implementation:e.implementation},t}function nu(e,t,n,r,i){this.tag=t,this.containerInfo=e,this.finishedWork=this.pingCache=this.current=this.pendingChildren=null,this.timeoutHandle=-1,this.callbackNode=this.pendingContext=this.context=null,this.callbackPriority=0,this.eventTimes=jt(0),this.expirationTimes=jt(-1),this.entangledLanes=this.finishedLanes=this.mutableReadLanes=this.expiredLanes=this.pingedLanes=this.suspendedLanes=this.pendingLanes=0,this.entanglements=jt(0),this.identifierPrefix=r,this.onRecoverableError=i,this.mutableSourceEagerHydrationData=null}function ru(e,t,n,r,i,a,o,s,c){return e=new nu(e,t,n,s,c),t===1?(t=1,!0===a&&(t|=8)):t=0,a=ql(3,null,null,t),e.current=a,a.stateNode=e,a.memoizedState={element:r,isDehydrated:n,cache:null,transitions:null,pendingSuspenseBoundaries:null},Za(a),e}function iu(e,t,n){var r=3<arguments.length&&arguments[3]!==void 0?arguments[3]:null;return{$$typeof:T,key:r==null?null:``+r,children:e,containerInfo:t,implementation:n}}function au(e){if(!e)return Vi;e=e._reactInternals;a:{if($e(e)!==e||e.tag!==1)throw Error(r(170));var t=e;do{switch(t.tag){case 3:t=t.stateNode.context;break a;case 1:if(Ki(t.type)){t=t.stateNode.__reactInternalMemoizedMergedChildContext;break a}}t=t.return}while(t!==null);throw Error(r(171))}if(e.tag===1){var n=e.type;if(Ki(n))return Yi(e,n,t)}return t}function ou(e,t,n,r,i,a,o,s,c){return e=ru(n,r,!0,e,i,a,o,s,c),e.context=au(null),n=e.current,r=pl(),i=ml(n),a=$a(r,i),a.callback=t??null,eo(n,a,i),e.current.lanes=i,Mt(e,i,r),gl(e,r),e}function su(e,t,n,r){var i=t.current,a=pl(),o=ml(i);return n=au(n),t.context===null?t.context=n:t.pendingContext=n,t=$a(a,o),t.payload={element:e},r=r===void 0?null:r,r!==null&&(t.callback=r),e=eo(i,t,o),e!==null&&(hl(e,i,o,a),to(e,i,o)),o}function cu(e){if(e=e.current,!e.child)return null;switch(e.child.tag){case 5:return e.child.stateNode;default:return e.child.stateNode}}function lu(e,t){if(e=e.memoizedState,e!==null&&e.dehydrated!==null){var n=e.retryLane;e.retryLane=n!==0&&n<t?n:t}}function uu(e,t){lu(e,t),(e=e.alternate)&&lu(e,t)}function du(){return null}var fu=typeof reportError==`function`?reportError:function(e){console.error(e)};function pu(e){this._internalRoot=e}mu.prototype.render=pu.prototype.render=function(e){var t=this._internalRoot;if(t===null)throw Error(r(409));su(e,t,null,null)},mu.prototype.unmount=pu.prototype.unmount=function(){var e=this._internalRoot;if(e!==null){this._internalRoot=null;var t=e.containerInfo;wl(function(){su(null,e,null,null)}),t[ki]=null}};function mu(e){this._internalRoot=e}mu.prototype.unstable_scheduleHydration=function(e){if(e){var t=Bt();e={blockedOn:null,target:e,priority:t};for(var n=0;n<Yt.length&&t!==0&&t<Yt[n].priority;n++);Yt.splice(n,0,e),n===0&&en(e)}};function hu(e){return!(!e||e.nodeType!==1&&e.nodeType!==9&&e.nodeType!==11)}function gu(e){return!(!e||e.nodeType!==1&&e.nodeType!==9&&e.nodeType!==11&&(e.nodeType!==8||e.nodeValue!==` react-mount-point-unstable `))}function _u(){}function vu(e,t,n,r,i){if(i){if(typeof r==`function`){var a=r;r=function(){var e=cu(o);a.call(e)}}var o=ou(t,r,e,0,null,!1,!1,``,_u);return e._reactRootContainer=o,e[ki]=o.current,ii(e.nodeType===8?e.parentNode:e),wl(),o}for(;i=e.lastChild;)e.removeChild(i);if(typeof r==`function`){var s=r;r=function(){var e=cu(c);s.call(e)}}var c=ru(e,0,!1,null,null,!1,!1,``,_u);return e._reactRootContainer=c,e[ki]=c.current,ii(e.nodeType===8?e.parentNode:e),wl(function(){su(t,c,n,r)}),c}function yu(e,t,n,r,i){var a=n._reactRootContainer;if(a){var o=a;if(typeof i==`function`){var s=i;i=function(){var e=cu(o);s.call(e)}}su(t,o,e,i)}else o=vu(n,t,e,i,r);return cu(o)}Lt=function(e){switch(e.tag){case 3:var t=e.stateNode;if(t.current.memoizedState.isDehydrated){var n=Tt(t.pendingLanes);n!==0&&(Pt(t,n|1),gl(t,lt()),!(Hc&6)&&(tl=lt()+500,ra()))}break;case 13:wl(function(){var t=Ya(e,1);t!==null&&hl(t,e,1,pl())}),uu(e,1)}},Rt=function(e){if(e.tag===13){var t=Ya(e,134217728);t!==null&&hl(t,e,134217728,pl()),uu(e,134217728)}},zt=function(e){if(e.tag===13){var t=ml(e),n=Ya(e,t);n!==null&&hl(n,e,t,pl()),uu(e,t)}},Bt=function(){return Ft},Vt=function(e,t){var n=Ft;try{return Ft=e,t()}finally{Ft=n}},Ne=function(e,t,n){switch(t){case`input`:if(H(e,n),t=n.name,n.type===`radio`&&t!=null){for(n=e;n.parentNode;)n=n.parentNode;for(n=n.querySelectorAll(`input[name=`+JSON.stringify(``+t)+`][type=\"radio\"]`),t=0;t<n.length;t++){var i=n[t];if(i!==e&&i.form===e.form){var a=Ii(i);if(!a)throw Error(r(90));le(i),H(i,a)}}}break;case`textarea`:be(e,n);break;case`select`:t=n.value,t!=null&&_e(e,!!n.multiple,t,!1)}},ze=Cl,Be=wl;var bu={usingClientEntryPoint:!1,Events:[Pi,Fi,Ii,Le,Re,Cl]},xu={findFiberByHostInstance:Ni,bundleType:0,version:`18.3.1`,rendererPackageName:`react-dom`},Su={bundleType:xu.bundleType,version:xu.version,rendererPackageName:xu.rendererPackageName,rendererConfig:xu.rendererConfig,overrideHookState:null,overrideHookStateDeletePath:null,overrideHookStateRenamePath:null,overrideProps:null,overridePropsDeletePath:null,overridePropsRenamePath:null,setErrorHandler:null,setSuspenseHandler:null,scheduleUpdate:null,currentDispatcherRef:C.ReactCurrentDispatcher,findHostInstanceByFiber:function(e){return e=rt(e),e===null?null:e.stateNode},findFiberByHostInstance:xu.findFiberByHostInstance||du,findHostInstancesForRefresh:null,scheduleRefresh:null,scheduleRoot:null,setRefreshHandler:null,getCurrentFiber:null,reconcilerVersion:`18.3.1-next-f1338f8080-20240426`};if(typeof __REACT_DEVTOOLS_GLOBAL_HOOK__<`u`){var Cu=__REACT_DEVTOOLS_GLOBAL_HOOK__;if(!Cu.isDisabled&&Cu.supportsFiber)try{gt=Cu.inject(Su),_t=Cu}catch{}}e.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED=bu,e.createPortal=function(e,t){var n=2<arguments.length&&arguments[2]!==void 0?arguments[2]:null;if(!hu(t))throw Error(r(200));return iu(e,t,null,n)},e.createRoot=function(e,t){if(!hu(e))throw Error(r(299));var n=!1,i=``,a=fu;return t!=null&&(!0===t.unstable_strictMode&&(n=!0),t.identifierPrefix!==void 0&&(i=t.identifierPrefix),t.onRecoverableError!==void 0&&(a=t.onRecoverableError)),t=ru(e,1,!1,null,null,n,!1,i,a),e[ki]=t.current,ii(e.nodeType===8?e.parentNode:e),new pu(t)},e.findDOMNode=function(e){if(e==null)return null;if(e.nodeType===1)return e;var t=e._reactInternals;if(t===void 0)throw typeof e.render==`function`?Error(r(188)):(e=Object.keys(e).join(`,`),Error(r(268,e)));return e=rt(t),e=e===null?null:e.stateNode,e},e.flushSync=function(e){return wl(e)},e.hydrate=function(e,t,n){if(!gu(t))throw Error(r(200));return yu(null,e,t,!0,n)},e.hydrateRoot=function(e,t,n){if(!hu(e))throw Error(r(405));var i=n!=null&&n.hydratedSources||null,a=!1,o=``,s=fu;if(n!=null&&(!0===n.unstable_strictMode&&(a=!0),n.identifierPrefix!==void 0&&(o=n.identifierPrefix),n.onRecoverableError!==void 0&&(s=n.onRecoverableError)),t=ou(t,null,e,1,n??null,a,!1,o,s),e[ki]=t.current,ii(e),i)for(e=0;e<i.length;e++)n=i[e],a=n._getVersion,a=a(n._source),t.mutableSourceEagerHydrationData==null?t.mutableSourceEagerHydrationData=[n,a]:t.mutableSourceEagerHydrationData.push(n,a);return new mu(t)},e.render=function(e,t,n){if(!gu(t))throw Error(r(200));return yu(null,e,t,!1,n)},e.unmountComponentAtNode=function(e){if(!gu(e))throw Error(r(40));return e._reactRootContainer?(wl(function(){yu(null,null,e,!1,function(){e._reactRootContainer=null,e[ki]=null})}),!0):!1},e.unstable_batchedUpdates=Cl,e.unstable_renderSubtreeIntoContainer=function(e,t,n,i){if(!gu(n))throw Error(r(200));if(e==null||e._reactInternals===void 0)throw Error(r(38));return yu(e,t,n,!1,i)},e.version=`18.3.1-next-f1338f8080-20240426`})),g=s(((e,t)=>{function n(){if(!(typeof __REACT_DEVTOOLS_GLOBAL_HOOK__>`u`||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!=`function`))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(n)}catch(e){console.error(e)}}n(),t.exports=h()})),_=s((e=>{var t=g();e.createRoot=t.createRoot,e.hydrateRoot=t.hydrateRoot}))(),v=u(f(),1);let y=(0,v.createContext)(null);function b({actions:e,dependencies:t=[],handoff:n,summary:r}){let i=(0,v.useContext)(y),a=(0,v.useRef)(null),o=(0,v.useRef)([]),s=(0,v.useRef)(0);(t.some((e,t)=>e!==o.current[t])||t.length!==o.current.length)&&(s.current++,o.current=t);let c=t;a.current={revision:String(s.current),actions:e,...typeof r==`function`?{summary:r}:{},handoff:typeof n==`function`?n:()=>({kind:`native-control-signals`,signals:c.map((e,t)=>({index:t,value:e}))})},(0,v.useLayoutEffect)(()=>i?.register(()=>a.current),[i])}function x({doc:e,busy:t,canEdit:n,methods:r,change:i,cancel:a}){let o=(e?.strip||[]).filter(e=>e.kind!==`repeat`&&!e.repeatOf).slice(0,50),s={type:`string`,enum:o.map(e=>e.panelId),description:o.map(e=>`${e.panelId}: ${e.kind} at ${e.startMs/1e3}s`).join(`; `)},c=(e,r,c,l,u)=>({id:e,label:r,effect:`edit`,available:()=>!t&&n&&o.length>0,parameters:{type:`object`,additionalProperties:!1,required:[`panelId`,c],properties:{panelId:s,[c]:l}},parse:e=>{if(!n||t||!e||Array.isArray(e)||Object.keys(e).length!==2||!Object.hasOwn(e,c)||!o.some(t=>t.panelId===e.panelId))throw Error(`Choose an editable panel while the workspace is idle.`);if(typeof e[c]!=`string`||e[c].length>(l.maxLength||200)||l.enum&&!l.enum.includes(e[c]))throw Error(`Use a supported panel value.`);return e},run:async(e,{signal:t}={})=>{if(t?.aborted)throw Error(`Panel edit stopped.`);let n=()=>a?.();t?.addEventListener(`abort`,n,{once:!0});try{if(await i(e.panelId,u,u===`method`?e[c]||null:e[c])===!1)throw Error(t?.aborted?`Panel edit stopped. Inspect the panel before trying again.`:`The panel update was not accepted. Inspect the current panel before trying again.`);return{status:`applied-locally`,message:`${r}: updated in Image Panels. No image was generated.`}}finally{t?.removeEventListener(`abort`,n)}}});return[c(`edit_panel_prompt`,`Change panel prompt`,`text`,{type:`string`,maxLength:12e3},`prompt`),c(`set_panel_method`,`Change panel method`,`method`,{type:`string`,enum:[``,...r]},`method`)]}let S=[`M3 8V5a2 2 0 0 1 2-2h3M16 3h3a2 2 0 0 1 2 2v3M21 16v3a2 2 0 0 1-2 2h-3M8 21H5a2 2 0 0 1-2-2v-3`,`M6.5 12s2.2-3.8 5.5-3.8 5.5 3.8 5.5 3.8-2.2 3.8-5.5 3.8S6.5 12 6.5 12Z`],C={cx:12,cy:12,r:1.8},w=[`M10.3 17.5H4.5a2 2 0 0 1-2-2v-10a2 2 0 0 1 2-2h13a2 2 0 0 1 2 2v7.7`,`M2.5 7h17M6 5.25h10`,`M6 9.5h4a1 1 0 0 1 1 1v3a1 1 0 0 1-1 1H6a1 1 0 0 1-1-1v-3a1 1 0 0 1 1-1Z`,`M5.3 14.2l2.2-2.4 1.6 1.5 1.1-1M13.5 10h3.5M13.5 12.3h2`,`M12 18s2-3.2 5.5-3.2S23 18 23 18s-2 3.2-5.5 3.2S12 18 12 18Z`],T={cx:17.5,cy:18,r:1.3};var E=s((e=>{var t=f(),n=Symbol.for(`react.element`),r=Symbol.for(`react.fragment`),i=Object.prototype.hasOwnProperty,a=t.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,o={key:!0,ref:!0,__self:!0,__source:!0};function s(e,t,r){var s,c={},l=null,u=null;for(s in r!==void 0&&(l=``+r),t.key!==void 0&&(l=``+t.key),t.ref!==void 0&&(u=t.ref),t)i.call(t,s)&&!o.hasOwnProperty(s)&&(c[s]=t[s]);if(e&&e.defaultProps)for(s in t=e.defaultProps,t)c[s]===void 0&&(c[s]=t[s]);return{$$typeof:n,type:e,key:l,ref:u,props:c,_owner:a.current}}e.Fragment=r,e.jsx=s,e.jsxs=s})),D=s(((e,t)=>{t.exports=E()}))();function O(e){switch(e){case`minus`:return(0,D.jsx)(`path`,{d:`M5 12h14`});case`messageCircle`:return(0,D.jsx)(`path`,{d:`M21 11.5a8.4 8.4 0 0 1-.9 3.8 8.5 8.5 0 0 1-7.6 4.7 8.4 8.4 0 0 1-3.8-.9L3 21l1.9-5.7a8.4 8.4 0 0 1-.9-3.8 8.5 8.5 0 0 1 4.7-7.6 8.4 8.4 0 0 1 3.8-.9h.5a8.5 8.5 0 0 1 8 8z`});case`arrowLeft`:return(0,D.jsx)(`path`,{d:`M20 12H4M11 5l-7 7 7 7`});case`link`:return(0,D.jsxs)(D.Fragment,{children:[(0,D.jsx)(`path`,{d:`M10 13a5 5 0 0 0 7 .5l3-3a5 5 0 0 0-7-7l-2 2`}),(0,D.jsx)(`path`,{d:`M14 11a5 5 0 0 0-7-.5l-3 3a5 5 0 0 0 7 7l2-2`})]});case`unlink`:return(0,D.jsxs)(D.Fragment,{children:[(0,D.jsx)(`path`,{d:`m18.8 12.3 1.7-1.7a5 5 0 0 0-7.1-7.1l-1.7 1.7`}),(0,D.jsx)(`path`,{d:`m5.2 11.7-1.7 1.7a5 5 0 0 0 7.1 7.1l1.7-1.7`}),(0,D.jsx)(`path`,{d:`M8 2v3M2 8h3M16 19v3M19 16h3`})]});case`copy`:return(0,D.jsxs)(D.Fragment,{children:[(0,D.jsx)(`rect`,{x:`9`,y:`9`,width:`12`,height:`12`,rx:`2`}),(0,D.jsx)(`path`,{d:`M15 9V5a2 2 0 0 0-2-2H5a2 2 0 0 0-2 2v8a2 2 0 0 0 2 2h4`})]});case`arrowUp`:return(0,D.jsx)(`path`,{d:`M12 20V4M5 11l7-7 7 7`});case`star`:return(0,D.jsx)(`path`,{d:`M12 3.5l2.6 5.3 5.9.9-4.25 4.15 1 5.85L12 16.95 6.75 19.7l1-5.85L3.5 9.7l5.9-.9z`});case`arrowUpRight`:return(0,D.jsx)(`path`,{d:`M7 17 17 7M8 7h9v9`});case`arrowDown`:return(0,D.jsx)(`path`,{d:`M12 4v16M5 13l7 7 7-7`});case`thumbsUp`:return(0,D.jsxs)(D.Fragment,{children:[(0,D.jsx)(`path`,{d:`M7 10v11H3V10Z`}),(0,D.jsx)(`path`,{d:`M7 18c2 0 3 3 7 3h2.5a2 2 0 0 0 1.9-1.4l2.4-7A2 2 0 0 0 18.9 10H14l.7-3.5A3 3 0 0 0 11.8 3L7 10Z`})]});case`thumbsDown`:return(0,D.jsxs)(D.Fragment,{children:[(0,D.jsx)(`path`,{d:`M7 14V3H3v11Z`}),(0,D.jsx)(`path`,{d:`M7 6c2 0 3-3 7-3h2.5a2 2 0 0 1 1.9 1.4l2.4 7a2 2 0 0 1-1.9 2.6H14l.7 3.5a3 3 0 0 1-2.9 3.5L7 14Z`})]});case`undo`:return(0,D.jsx)(`path`,{d:`M3 10h11a7 7 0 0 1 0 14M3 10l5-5M3 10l5 5`,transform:`translate(0 -3)`});case`redo`:return(0,D.jsx)(`path`,{d:`M21 7H10a7 7 0 0 0 0 14M21 7l-5-5M21 7l-5 5`});case`remix`:return(0,D.jsxs)(D.Fragment,{children:[(0,D.jsx)(`path`,{d:`M5 5h5a5 5 0 0 1 5 5v9`}),(0,D.jsx)(`path`,{d:`m11 15 4 4 4-4`}),(0,D.jsx)(`path`,{d:`M5 19h2`}),(0,D.jsx)(`circle`,{cx:`5`,cy:`5`,r:`2`}),(0,D.jsx)(`circle`,{cx:`5`,cy:`19`,r:`2`})]});case`more`:return(0,D.jsxs)(D.Fragment,{children:[(0,D.jsx)(`circle`,{cx:`5`,cy:`12`,r:`1`}),(0,D.jsx)(`circle`,{cx:`12`,cy:`12`,r:`1`}),(0,D.jsx)(`circle`,{cx:`19`,cy:`12`,r:`1`})]});case`palette`:return(0,D.jsxs)(D.Fragment,{children:[(0,D.jsx)(`circle`,{cx:`13.5`,cy:`6.5`,r:`.6`,fill:`currentColor`,stroke:`none`}),(0,D.jsx)(`circle`,{cx:`17`,cy:`11`,r:`.6`,fill:`currentColor`,stroke:`none`}),(0,D.jsx)(`circle`,{cx:`8.5`,cy:`7.5`,r:`.6`,fill:`currentColor`,stroke:`none`}),(0,D.jsx)(`circle`,{cx:`6.5`,cy:`12.5`,r:`.6`,fill:`currentColor`,stroke:`none`}),(0,D.jsx)(`path`,{d:`M12 3a9 9 0 0 0 0 18c1 0 1.6-.8 1.6-1.6 0-.5-.2-.8-.4-1.1-.3-.3-.4-.6-.4-1.1A1.6 1.6 0 0 1 14.3 15h1.9A4.8 4.8 0 0 0 21 10.2C21 6 16.9 3 12 3Z`})]});case`lock`:return(0,D.jsxs)(D.Fragment,{children:[(0,D.jsx)(`rect`,{x:`5`,y:`11`,width:`14`,height:`10`,rx:`2`}),(0,D.jsx)(`path`,{d:`M8 11V7a4 4 0 0 1 8 0v4`})]});case`unlock`:return(0,D.jsxs)(D.Fragment,{children:[(0,D.jsx)(`rect`,{x:`5`,y:`11`,width:`14`,height:`10`,rx:`2`}),(0,D.jsx)(`path`,{d:`M8 11V7a4 4 0 0 1 7.9-1`})]});case`pushpin`:return(0,D.jsxs)(`g`,{transform:`rotate(35 12 12)`,children:[(0,D.jsx)(`path`,{d:`M8 3h8l-1 6 3 3v2H6v-2l3-3Z`}),(0,D.jsx)(`path`,{d:`M12 14v7`})]});case`pushpinFilled`:return(0,D.jsxs)(D.Fragment,{children:[(0,D.jsx)(`path`,{d:`M8 3h8l-1 6 3 3v2H6v-2l3-3Z`,fill:`currentColor`}),(0,D.jsx)(`path`,{d:`M12 14v7`})]});case`pin`:return(0,D.jsxs)(D.Fragment,{children:[(0,D.jsx)(`path`,{d:`M12 21s7-5.7 7-11a7 7 0 0 0-14 0c0 5.3 7 11 7 11Z`}),(0,D.jsx)(`circle`,{cx:`12`,cy:`10`,r:`2.5`})]});case`user`:return(0,D.jsxs)(D.Fragment,{children:[(0,D.jsx)(`circle`,{cx:`12`,cy:`8`,r:`4`}),(0,D.jsx)(`path`,{d:`M5 21a7 7 0 0 1 14 0`})]});case`image`:return(0,D.jsxs)(D.Fragment,{children:[(0,D.jsx)(`rect`,{x:`3`,y:`3`,width:`18`,height:`18`,rx:`2`}),(0,D.jsx)(`circle`,{cx:`8.5`,cy:`8.5`,r:`1.5`}),(0,D.jsx)(`path`,{d:`m21 15-5-5L5 21`})]});case`imageOff`:return(0,D.jsxs)(D.Fragment,{children:[(0,D.jsx)(`path`,{d:`M2 2l20 20`}),(0,D.jsx)(`path`,{d:`M10.41 10.41a2 2 0 1 1-2.83-2.83`}),(0,D.jsx)(`path`,{d:`M13.5 13.5 6 21`}),(0,D.jsx)(`path`,{d:`m18 12 3 3`}),(0,D.jsx)(`path`,{d:`M3.59 3.59A1.99 1.99 0 0 0 3 5v14a2 2 0 0 0 2 2h14c.55 0 1.052-.22 1.41-.59`}),(0,D.jsx)(`path`,{d:`M21 15V5a2 2 0 0 0-2-2H9`})]});case`film`:return(0,D.jsxs)(D.Fragment,{children:[(0,D.jsx)(`rect`,{x:`3`,y:`3`,width:`18`,height:`18`,rx:`2`}),(0,D.jsx)(`path`,{d:`M7 3v18M17 3v18M3 8h4M3 16h4M17 8h4M17 16h4`})]});case`folder`:return(0,D.jsx)(`path`,{d:`M3 7a2 2 0 0 1 2-2h4l2 2h8a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2Z`});case`list`:return(0,D.jsx)(`path`,{d:`M9 6h12M9 12h12M9 18h12M4 6h.01M4 12h.01M4 18h.01`});case`grid`:return(0,D.jsxs)(D.Fragment,{children:[(0,D.jsx)(`rect`,{x:`3`,y:`3`,width:`7`,height:`7`,rx:`1.5`}),(0,D.jsx)(`rect`,{x:`14`,y:`3`,width:`7`,height:`7`,rx:`1.5`}),(0,D.jsx)(`rect`,{x:`3`,y:`14`,width:`7`,height:`7`,rx:`1.5`}),(0,D.jsx)(`rect`,{x:`14`,y:`14`,width:`7`,height:`7`,rx:`1.5`})]});case`zap`:return(0,D.jsx)(`path`,{d:`M13 2 4 14h7l-1 8 9-12h-7Z`});case`plug`:return(0,D.jsxs)(D.Fragment,{children:[(0,D.jsx)(`path`,{d:`M12 22v-5M9 8V2M15 8V2`}),(0,D.jsx)(`path`,{d:`M18 8v5a4 4 0 0 1-4 4h-4a4 4 0 0 1-4-4V8Z`})]});case`book`:return(0,D.jsxs)(D.Fragment,{children:[(0,D.jsx)(`path`,{d:`M4 19.5A2.5 2.5 0 0 1 6.5 17H20`}),(0,D.jsx)(`path`,{d:`M6.5 2H20v20H6.5A2.5 2.5 0 0 1 4 19.5v-15A2.5 2.5 0 0 1 6.5 2Z`})]});case`bookOpen`:return(0,D.jsxs)(D.Fragment,{children:[(0,D.jsx)(`path`,{d:`M12 7v14`}),(0,D.jsx)(`path`,{d:`M3 5v14h6a3 3 0 0 1 3 3 3 3 0 0 1 3-3h6V5h-6a3 3 0 0 0-3 3 3 3 0 0 0-3-3Z`})]});case`input`:return(0,D.jsxs)(D.Fragment,{children:[(0,D.jsx)(`path`,{d:`M15 3h4a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2h-4`}),(0,D.jsx)(`path`,{d:`m10 17 5-5-5-5`}),(0,D.jsx)(`path`,{d:`M15 12H3`})]});case`upload`:return(0,D.jsxs)(D.Fragment,{children:[(0,D.jsx)(`path`,{d:`M12 16V4M7 9l5-5 5 5`}),(0,D.jsx)(`path`,{d:`M5 20h14`})]});case`download`:return(0,D.jsxs)(D.Fragment,{children:[(0,D.jsx)(`path`,{d:`M12 4v12M7 11l5 5 5-5`}),(0,D.jsx)(`path`,{d:`M5 20h14`})]});case`save`:return(0,D.jsxs)(D.Fragment,{children:[(0,D.jsx)(`path`,{d:`M5 3h11l3 3v15H5Z`}),(0,D.jsx)(`path`,{d:`M8 3v5h7M8 21v-7h8v7`})]});case`search`:return(0,D.jsxs)(D.Fragment,{children:[(0,D.jsx)(`circle`,{cx:`11`,cy:`11`,r:`7`}),(0,D.jsx)(`path`,{d:`m20 20-3.5-3.5`})]});case`magnet`:return(0,D.jsxs)(D.Fragment,{children:[(0,D.jsx)(`path`,{d:`M6 4h4v8a2 2 0 0 0 4 0V4h4v8a6 6 0 0 1-12 0Z`}),(0,D.jsx)(`path`,{d:`M6 8h4M14 8h4`})]});case`bot`:return(0,D.jsxs)(D.Fragment,{children:[(0,D.jsx)(`rect`,{x:`4`,y:`8`,width:`16`,height:`11`,rx:`2`}),(0,D.jsx)(`path`,{d:`M12 8V4M9 13h.01M15 13h.01M9 16h6`})]});case`note`:return(0,D.jsxs)(D.Fragment,{children:[(0,D.jsx)(`rect`,{x:`4`,y:`3`,width:`16`,height:`18`,rx:`2`}),(0,D.jsx)(`path`,{d:`M8 8h8M8 12h8M8 16h5`})]});case`clock`:return(0,D.jsxs)(D.Fragment,{children:[(0,D.jsx)(`circle`,{cx:`12`,cy:`12`,r:`9`}),(0,D.jsx)(`path`,{d:`M12 7v5l3 2`})]});case`calendar`:return(0,D.jsxs)(D.Fragment,{children:[(0,D.jsx)(`rect`,{x:`3`,y:`5`,width:`18`,height:`16`,rx:`2`}),(0,D.jsx)(`path`,{d:`M16 3v4M8 3v4M3 10h18`})]});case`hourglass`:return(0,D.jsx)(`path`,{d:`M6 3h12M6 21h12M7 3c0 5 5 6 5 9s-5 4-5 9M17 3c0 5-5 6-5 9s5 4 5 9`});case`edit`:return(0,D.jsxs)(D.Fragment,{children:[(0,D.jsx)(`path`,{d:`M12 20h9`}),(0,D.jsx)(`path`,{d:`M16.5 3.5a2.1 2.1 0 0 1 3 3L7 19l-4 1 1-4Z`})]});case`music`:return(0,D.jsxs)(D.Fragment,{children:[(0,D.jsx)(`path`,{d:`M9 18V5l12-2v13`}),(0,D.jsx)(`circle`,{cx:`6`,cy:`18`,r:`3`}),(0,D.jsx)(`circle`,{cx:`18`,cy:`16`,r:`3`})]});case`mic`:return(0,D.jsxs)(D.Fragment,{children:[(0,D.jsx)(`rect`,{x:`9`,y:`2`,width:`6`,height:`13`,rx:`3`}),(0,D.jsx)(`path`,{d:`M19 10v2a7 7 0 0 1-14 0v-2`}),(0,D.jsx)(`path`,{d:`M12 19v3`})]});case`target`:return(0,D.jsxs)(D.Fragment,{children:[(0,D.jsx)(`circle`,{cx:`12`,cy:`12`,r:`9`}),(0,D.jsx)(`circle`,{cx:`12`,cy:`12`,r:`5`}),(0,D.jsx)(`circle`,{cx:`12`,cy:`12`,r:`1`,fill:`currentColor`,stroke:`none`})]});case`pointer`:return(0,D.jsx)(`path`,{d:`M4.5 3.5 20 10.4l-6.5 1.9a1.9 1.9 0 0 0-1.3 1.3L10.3 20z`,strokeLinejoin:`round`});case`sprout`:return(0,D.jsxs)(D.Fragment,{children:[(0,D.jsx)(`path`,{d:`M12 21V9`}),(0,D.jsx)(`path`,{d:`M12 9C9 9 6 7 6 4c3 0 6 2 6 5ZM12 12c3 0 6-2 6-5-3 0-6 2-6 5Z`})]});case`hand`:return(0,D.jsx)(`path`,{d:`M8 13V5a1.5 1.5 0 0 1 3 0v6M11 11V4a1.5 1.5 0 0 1 3 0v7M14 11V6a1.5 1.5 0 0 1 3 0v8a6 6 0 0 1-6 6h-1a6 6 0 0 1-5.2-3l-2-3.5a1.5 1.5 0 0 1 2.6-1.5L8 14`});case`scissors`:return(0,D.jsxs)(D.Fragment,{children:[(0,D.jsx)(`circle`,{cx:`6`,cy:`6`,r:`2.5`}),(0,D.jsx)(`circle`,{cx:`6`,cy:`18`,r:`2.5`}),(0,D.jsx)(`path`,{d:`M8 8l12 8M8 16 20 8`})]});case`maximize`:return(0,D.jsx)(`path`,{d:`M8 3H5a2 2 0 0 0-2 2v3M16 3h3a2 2 0 0 1 2 2v3M21 16v3a2 2 0 0 1-2 2h-3M3 16v3a2 2 0 0 0 2 2h3`});case`settings`:return(0,D.jsxs)(D.Fragment,{children:[(0,D.jsx)(`circle`,{cx:`12`,cy:`12`,r:`3`}),(0,D.jsx)(`path`,{d:`M19.4 15a1.6 1.6 0 0 0 .3 1.8 2 2 0 1 1-2.8 2.8 1.6 1.6 0 0 0-1.8-.3 1.6 1.6 0 0 0-1 1.5 2 2 0 1 1-4 0 1.6 1.6 0 0 0-1-1.5 1.6 1.6 0 0 0-1.8.3 2 2 0 1 1-2.8-2.8 1.6 1.6 0 0 0 .3-1.8 1.6 1.6 0 0 0-1.5-1 2 2 0 1 1 0-4 1.6 1.6 0 0 0 1.5-1 1.6 1.6 0 0 0-.3-1.8 2 2 0 1 1 2.8-2.8 1.6 1.6 0 0 0 1.8.3H9a1.6 1.6 0 0 0 1-1.5 2 2 0 1 1 4 0 1.6 1.6 0 0 0 1 1.5 1.6 1.6 0 0 0 1.8-.3 2 2 0 1 1 2.8 2.8 1.6 1.6 0 0 0-.3 1.8V9a1.6 1.6 0 0 0 1.5 1 2 2 0 1 1 0 4 1.6 1.6 0 0 0-1.5 1Z`})]});case`scale`:return(0,D.jsx)(`path`,{d:`M12 3v18M7 21h10M6 7h12M6 7 3 14h6ZM18 7l-3 7h6ZM3 14a3 3 0 0 0 6 0M15 14a3 3 0 0 0 6 0`});case`checkbox`:return(0,D.jsxs)(D.Fragment,{children:[(0,D.jsx)(`rect`,{x:`3`,y:`3`,width:`18`,height:`18`,rx:`2`}),(0,D.jsx)(`path`,{d:`m8 12 3 3 5-6`})]});case`warning`:return(0,D.jsxs)(D.Fragment,{children:[(0,D.jsx)(`path`,{d:`M10.3 4 2.6 17a2 2 0 0 0 1.7 3h15.4a2 2 0 0 0 1.7-3L13.7 4a2 2 0 0 0-3.4 0Z`}),(0,D.jsx)(`path`,{d:`M12 9v4M12 17h.01`})]});case`sparkle`:return(0,D.jsx)(`path`,{d:`M12 3l1.8 5.2L19 10l-5.2 1.8L12 17l-1.8-5.2L5 10l5.2-1.8Z`});case`check`:return(0,D.jsx)(`path`,{d:`m5 12 5 5 9-10`});case`x`:return(0,D.jsx)(`path`,{d:`M6 6 18 18M18 6 6 18`});case`plus`:return(0,D.jsx)(`path`,{d:`M12 5v14M5 12h14`});case`refresh`:return(0,D.jsx)(`path`,{d:`M3 12a9 9 0 0 1 15-6.7L21 8M21 3v5h-5M21 12a9 9 0 0 1-15 6.7L3 16M3 21v-5h5`});case`play`:return(0,D.jsx)(`path`,{d:`M7 4v16l13-8Z`});case`preview`:return(0,D.jsxs)(D.Fragment,{children:[S.map(e=>(0,D.jsx)(`path`,{d:e},e)),(0,D.jsx)(`circle`,{...C})]});case`listingPreview`:return(0,D.jsxs)(D.Fragment,{children:[w.map(e=>(0,D.jsx)(`path`,{d:e},e)),(0,D.jsx)(`circle`,{...T})]});case`pause`:return(0,D.jsx)(`path`,{d:`M9 5v14M15 5v14`});case`playFilled`:return(0,D.jsx)(`path`,{d:`M7 4.6v14.8c0 .8.9 1.2 1.5.8l11.4-7.4a1 1 0 0 0 0-1.6L8.5 3.8C7.9 3.4 7 3.8 7 4.6Z`,fill:`currentColor`,stroke:`none`});case`pauseFilled`:return(0,D.jsxs)(D.Fragment,{children:[(0,D.jsx)(`rect`,{x:`6`,y:`4.5`,width:`4`,height:`15`,rx:`1`,fill:`currentColor`,stroke:`none`}),(0,D.jsx)(`rect`,{x:`14`,y:`4.5`,width:`4`,height:`15`,rx:`1`,fill:`currentColor`,stroke:`none`})]});case`volume2`:return(0,D.jsxs)(D.Fragment,{children:[(0,D.jsx)(`path`,{d:`M11 5 6 9H2v6h4l5 4V5Z`,fill:`currentColor`}),(0,D.jsx)(`path`,{d:`M15.5 8.5a5 5 0 0 1 0 7M19 5a10 10 0 0 1 0 14`})]});case`volumeX`:return(0,D.jsxs)(D.Fragment,{children:[(0,D.jsx)(`path`,{d:`M11 5 6 9H2v6h4l5 4V5Z`,fill:`currentColor`}),(0,D.jsx)(`path`,{d:`m22 9-6 6M16 9l6 6`})]});case`minimize`:return(0,D.jsx)(`path`,{d:`M8 3v3a2 2 0 0 1-2 2H3M21 8h-3a2 2 0 0 1-2-2V3M3 16h3a2 2 0 0 1 2 2v3M16 21v-3a2 2 0 0 1 2-2h3`});case`stop`:return(0,D.jsx)(`rect`,{x:`6`,y:`6`,width:`12`,height:`12`,rx:`2`});case`chevronRight`:return(0,D.jsx)(`path`,{d:`m9 6 6 6-6 6`});case`chevronLeft`:return(0,D.jsx)(`path`,{d:`m15 6-6 6 6 6`});case`chevronDown`:return(0,D.jsx)(`path`,{d:`m6 9 6 6 6-6`});case`trash`:return(0,D.jsx)(`path`,{d:`M4 7h16M9 7V5a1 1 0 0 1 1-1h4a1 1 0 0 1 1 1v2M6 7l1 13a2 2 0 0 0 2 2h6a2 2 0 0 0 2-2l1-13`});case`layers`:return(0,D.jsx)(`path`,{d:`m12 3 9 5-9 5-9-5Zm9 9-9 5-9-5m18 4-9 5-9-5`});case`type`:return(0,D.jsx)(`path`,{d:`M4 6V4h16v2M12 4v16M9 20h6`});case`home`:return(0,D.jsxs)(D.Fragment,{children:[(0,D.jsx)(`path`,{d:`M3 10.5 12 3l9 7.5`}),(0,D.jsx)(`path`,{d:`M5 9.5V20a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1V9.5`}),(0,D.jsx)(`path`,{d:`M9 21v-6h6v6`})]});case`menu`:return(0,D.jsx)(`path`,{d:`M4 6h16M4 12h16M4 18h16`});case`logout`:return(0,D.jsxs)(D.Fragment,{children:[(0,D.jsx)(`path`,{d:`M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4`}),(0,D.jsx)(`path`,{d:`M16 17l5-5-5-5`}),(0,D.jsx)(`path`,{d:`M21 12H9`})]});case`help`:return(0,D.jsxs)(D.Fragment,{children:[(0,D.jsx)(`circle`,{cx:`12`,cy:`12`,r:`9`}),(0,D.jsx)(`path`,{d:`M9.1 9a3 3 0 0 1 5.8 1c0 2-3 3-3 3`}),(0,D.jsx)(`path`,{d:`M12 17h.01`})]});case`bug`:return(0,D.jsxs)(D.Fragment,{children:[(0,D.jsx)(`path`,{d:`m8 2 1.9 1.9M14.1 3.9 16 2`}),(0,D.jsx)(`path`,{d:`M9 7.1v-1a3 3 0 1 1 6 0v1`}),(0,D.jsx)(`path`,{d:`M12 20c-3.3 0-6-2.7-6-6v-3a4 4 0 0 1 4-4h4a4 4 0 0 1 4 4v3c0 3.3-2.7 6-6 6`}),(0,D.jsx)(`path`,{d:`M12 20v-9`}),(0,D.jsx)(`path`,{d:`M6.5 9C4.6 8.8 3 7.1 3 5M6 13H2M3 21c0-2.1 1.7-3.9 3.8-4M21 5c0 2.1-1.6 3.8-3.5 4M22 13h-4M17.2 17c2.1.1 3.8 1.9 3.8 4`})]});default:return null}}function k({name:e,size:t=`1em`,style:n,className:r,strokeWidth:i=1.5}){let a=O(e);return a?(0,D.jsx)(`svg`,{viewBox:`0 0 24 24`,width:t,height:t,fill:`none`,stroke:`currentColor`,strokeWidth:i,strokeLinecap:`round`,strokeLinejoin:`round`,className:r,style:{display:`inline-block`,verticalAlign:`-0.14em`,flexShrink:0,...n||{}},\"aria-hidden\":`true`,children:a}):null}Object.freeze([`list`,`accounts`,`grants`,`create`,`bind`,`read`,`update`,`creatives`,`contribute`,`grant`,`revoke`,`unlink`]),Object.freeze({files:256,textBytes:3e6,pathLength:180});var A=class extends Error{constructor(e,t,n=[]){super(t),this.name=`BlockError`,this.code=e,this.details=n}};function j(e,t,n){if(!e)throw new A(t,n)}function M(e){return!!e&&typeof e==`object`&&!Array.isArray(e)&&[Object.prototype,null].includes(Object.getPrototypeOf(e))}function ee(){let e=e=>typeof e==`object`&&!!e&&!Array.isArray(e)&&[Object.prototype,null].includes(Object.getPrototypeOf(e)),t=/^(string|text|number|integer|boolean|object|json)(\\[\\])?\\??$/,n=new Set([`__proto__`,`prototype`,`constructor`]);function r(i,a=0){return a>40?!1:typeof i==`string`?t.test(i):Array.isArray(i)?i.length===1&&r(i[0],a+1):e(i)&&Object.entries(i).every(([e,t])=>!n.has(e)&&r(t,a+1))}function i(t,r,o=0){return o>40?!1:r==null?!0:Array.isArray(r)?r.length===1&&Array.isArray(t)&&t.every(e=>i(e,r[0],o+1)):typeof r==`string`?r.endsWith(`?`)?t===void 0||i(t,r.slice(0,-1),o+1):r.endsWith(`[]`)?Array.isArray(t)&&t.every(e=>i(e,r.slice(0,-2),o+1)):r===`string`||r===`text`?typeof t==`string`:r===`object`?e(t):r===`json`?a(t,o+1):r===`integer`?Number.isSafeInteger(t):r===`number`?typeof t==`number`&&Number.isFinite(t):r===`boolean`&&typeof t==`boolean`:e(r)&&e(t)&&Object.entries(r).every(([e,r])=>!n.has(e)&&i(Object.hasOwn(t,e)?t[e]:void 0,r,o+1))}function a(t,r){return r>40?!1:t===null||typeof t==`string`||typeof t==`boolean`?!0:typeof t==`number`?Number.isFinite(t):(e(t)||Array.isArray(t))&&Object.entries(t).every(([e,t])=>!n.has(e)&&a(t,r+1))}return{semanticSchemaValid:r,schemaMatches:i,validate:(e,t)=>{try{return r(t)&&a(e,0)&&i(e,t)}catch{return!1}}}}let{semanticSchemaValid:N,schemaMatches:P}=ee();Object.freeze([`upstream`,`project`,`adapter`,`chat`,`default`,`user`,`external`]);let te=Object.freeze([`key`,`semantic`,`accepts`,`schema`,`sources`,`sensitivity`,`freshnessPolicy`,`cardinality`,`batchable`]),ne=Object.freeze([Object.freeze({name:`narration_script`,parents:Object.freeze([`script`])}),Object.freeze({name:`sales_script`,parents:Object.freeze([`script`])}),Object.freeze({name:`timed_transcript`,parents:Object.freeze([`transcript`])}),Object.freeze({name:`product_image`,parents:Object.freeze([`image`])}),Object.freeze({name:`reference_image`,parents:Object.freeze([`image`])}),Object.freeze({name:`generated_image`,parents:Object.freeze([`image`,`source_image`])}),Object.freeze({name:`processed_image`,parents:Object.freeze([`image`,`source_image`])}),Object.freeze({name:`visual_description`,parents:Object.freeze([`plain_text`])}),Object.freeze({name:`transcript_text`,parents:Object.freeze([`plain_text`])}),Object.freeze({name:`editor_timeline`,parents:Object.freeze([`timeline`])}),Object.freeze({name:`legacy.timeline.updatededitor`,parents:Object.freeze([`timeline`])}),Object.freeze({name:`narration_audio`,parents:Object.freeze([`source_audio`])}),Object.freeze({name:`generated_video`,parents:Object.freeze([`source_video`])}),Object.freeze({name:`edited_video`,parents:Object.freeze([`source_video`])}),Object.freeze({name:`rendered_video`,parents:Object.freeze([`source_video`])}),Object.freeze({name:`rendered_audio`,parents:Object.freeze([`source_audio`])})]);new Map(ne.map(e=>[e.name,e.parents])),Object.freeze(new Set(`sm.ai-decide@1.0.0,sm.ai-write@1.0.0,sm.board-editor.hosted@3.0.0,sm.board-editor@2.0.0,sm.board-editor@2.1.0,sm.board-editor@2.2.0,sm.board-editor@2.2.1,sm.board-editor@2.2.10,sm.board-editor@2.2.11,sm.board-editor@2.2.2,sm.board-editor@2.2.3,sm.board-editor@2.2.4,sm.board-editor@2.2.5,sm.board-editor@2.2.6,sm.board-editor@2.2.7,sm.board-editor@2.2.8,sm.board-editor@2.2.9,sm.board-editor@3.0.0,sm.captions@2.0.0,sm.character@2.0.0,sm.character@2.0.1,sm.compare@2.0.0,sm.compare@2.0.1,sm.compare@2.0.2,sm.connect-app@1.0.0,sm.contact-fields@1.0.0,sm.edit-assistant@2.0.0,sm.edit-assistant@2.0.1,sm.edit-assistant@2.0.2,sm.editor.hosted@3.0.0,sm.editor@2.0.0,sm.editor@2.1.0,sm.editor@2.2.0,sm.editor@2.2.1,sm.editor@2.2.10,sm.editor@2.2.11,sm.editor@2.2.12,sm.editor@2.2.2,sm.editor@2.2.3,sm.editor@2.2.4,sm.editor@2.2.5,sm.editor@2.2.6,sm.editor@2.2.7,sm.editor@2.2.8,sm.editor@2.2.9,sm.editor@3.0.0,sm.export-audio@2.0.0,sm.export-timeline@2.0.0,sm.export-video@2.0.0,sm.export-video@2.1.0,sm.final-edit@2.0.0,sm.final-edit@2.0.1,sm.final-edit@2.0.2,sm.generate-image@2.0.0,sm.generate-image@2.1.0,sm.generate-video@2.0.0,sm.generate-video@2.0.1,sm.grade@2.0.0,sm.grade@2.0.1,sm.grade@2.0.2,sm.import-media@2.0.0,sm.import-media@2.0.1,sm.import-media@2.0.2,sm.location@2.0.0,sm.location@2.0.1,sm.meta-creative@1.0.0,sm.motion-graphics@2.0.0,sm.panel-strip.hosted@3.0.0,sm.panel-strip@2.0.0,sm.panel-strip@2.1.0,sm.panel-strip@2.2.0,sm.panel-strip@2.3.0,sm.panel-strip@2.3.1,sm.panel-strip@2.3.2,sm.panel-strip@2.3.3,sm.panel-strip@2.3.4,sm.panel-strip@2.3.5,sm.panel-strip@2.3.6,sm.panel-strip@2.3.7,sm.panel-strip@2.4.0,sm.panel-strip@2.4.1,sm.panel-strip@2.4.2,sm.panel-strip@3.0.0,sm.photo-editor@1.0.0,sm.photo-notes@1.0.0,sm.photo-notes@1.1.0,sm.pipeline@2.0.0,sm.pipeline@2.1.0,sm.pipeline@2.2.0,sm.pipeline@2.2.1,sm.pipeline@2.2.2,sm.pipeline@2.2.3,sm.pipeline@2.2.4,sm.pipeline@2.2.5,sm.pipeline@2.2.6,sm.rough-cut@2.0.0,sm.rough-cut@2.0.1,sm.rough-cut@2.0.2,sm.score@2.0.0,sm.style@2.0.0,sm.style@2.0.1,sm.transition@2.0.0,sm.transition@2.0.1,sm.transition@2.0.2,sm.video-assets@2.0.0,sm.video-assets@2.1.0,sm.video-assets@2.1.1,sm.video-assets@2.1.2,sm.video-assets@2.1.3,sm.video-assets@2.1.4,sm.voiceover.hosted@3.0.0,sm.voiceover@2.0.0,sm.voiceover@2.1.0,sm.voiceover@2.1.1,sm.voiceover@2.1.2,sm.voiceover@2.1.3,sm.voiceover@2.1.4,sm.voiceover@2.1.5,sm.voiceover@2.1.6,sm.voiceover@3.0.0,sm.when@1.0.0,sm.when@1.1.0,sm.write-summary@1.0.0,stillmade.generate@1.0.0`.split(`,`))),Object.freeze({routes:16,operations:64,keyLength:80,declarationBytes:65536});let re=`(0|[1-9][0-9]{0,5})\\\\.(0|[1-9][0-9]{0,5})\\\\.(0|[1-9][0-9]{0,5})`;RegExp(`^`+re+`$`),RegExp(`^(>=|<=|>|<|=)?`+re+`$`),Object.freeze([`blueprint`,`shotPlan`,`panels`,`board`,`canvas`,`animation`,`editor`]),Object.freeze([{type:`Cut`,sounds:[]},{type:`Fade`,sounds:[]},{type:`Cross dissolve`,sounds:[]},{type:`Shape wipe`,sounds:[`shape_sweep`,`shape_pop`]},{type:`Iris`,sounds:[`shape_sweep`,`shape_pop`]},{type:`Ink splat`,sounds:[`shape_sweep`,`shape_pop`]},{type:`Swirl`,sounds:[`whoosh`,`swirl_wind`]},{type:`Whip left`,sounds:[`whip_crack`,`whip_zip`]},{type:`Whip right`,sounds:[`whip_crack`,`whip_zip`]},{type:`Whip up`,sounds:[`whip_crack`,`whip_zip`]},{type:`Whip down`,sounds:[`whip_crack`,`whip_zip`]},{type:`Whip pan`,sounds:[`whip_crack`,`whip_zip`]},{type:`Slash`,sounds:[`shape_sweep`,`shape_pop`]},{type:`Shred`,sounds:[`shape_sweep`,`shape_pop`]},{type:`Morph`,sounds:[`morph_warp`,`morph_bloom`]},{type:`Dip to black`,sounds:[]},{type:`Dip to white`,sounds:[]},{type:`Push left`,sounds:[`push_slide`,`push_thump`]},{type:`Push right`,sounds:[`push_slide`,`push_thump`]},{type:`Push up`,sounds:[`push_slide`,`push_thump`]},{type:`Push down`,sounds:[`push_slide`,`push_thump`]},{type:`Zoom left`,sounds:[]},{type:`Zoom right`,sounds:[]},{type:`Zoom up`,sounds:[]},{type:`Zoom down`,sounds:[]}].map(e=>Object.freeze({...e,sounds:Object.freeze(e.sounds)}))),Object.freeze([`screen.capture`,`cursor.track`,`camera.capture`,`microphone.capture`,`clipboard.read`,`clipboard.write`,`media.pick`,`notifications.show`,`power.keep-awake`,`native.tools`,`folder.read`,`folder.write`]),Object.freeze({\"org.stillmade.PythonAdapter\":Object.freeze({id:`org.stillmade.PythonAdapter`,adapterVersion:1,label:`Python connection`,actions:Object.freeze([`adapter.import`,`adapter.inspect`,`adapter.execute`,`adapter.describe`,`adapter.call`]),projectExtensions:Object.freeze([`py`])}),\"org.natron.Natron\":Object.freeze({id:`org.natron.Natron`,adapterVersion:1,label:`Natron`,actions:Object.freeze([`launch`,`project.import`,`project.open`,`project.render`]),projectExtensions:Object.freeze([`ntp`])})}),Object.freeze({fileName:255,documentText:1e6,documentTitle:300,tableColumns:500,tableRows:1e5,tableCells:5e5,columnName:160,cellText:1e5,url:8192});let F=Object.freeze({pdf:`application/pdf`,txt:`text/plain`,csv:`text/csv`,md:`text/markdown`,json:`application/json`,zip:`application/zip`});Object.freeze([...new Set(Object.values(F))]),Object.freeze([`markdown`,`plain`]),Object.freeze({origins:8,requestBytes:4194304,responseBytes:8388608,timeoutMs:3e4,redirects:3,headers:32,headerBytes:16384,urlLength:8192,requestsPerMinute:120,originRequestsPerMinute:3e3,keyLength:4096}),Object.freeze([`GET`,`HEAD`,`POST`,`PUT`,`PATCH`,`DELETE`]),Object.freeze([`bearer`,`header`,`query`,`oauth2`]),Object.freeze({sockets:4,messageBytes:1048576,runBytes:268435456,protocols:8}),Object.freeze([`media.saved`,`schedule`,`webhook`,`project.completed`,`provider`]),Object.freeze({triggers:4,labelLength:120,minEverySeconds:60,maxEverySeconds:31536e3}),Object.freeze([`recipe`,`javascript`,`capability`]),Object.freeze({features:24,id:48,label:40,does:160,asks:8,ask:80});let I=j,L=M;Object.freeze([`type`,`required`,`default`,`min`,`max`,`description`,`role`,`primary`,`context`,`imageMode`,...te]),Object.freeze(`text.number.integer.boolean.json.object.image.video.audio.asset.script.transcript.brief.bible.shot-plan.panel-document.board-document.scene-document.timeline.timeline-edit.file-bundle.workspace-edit.timeline-range.research.character.location.style.pipeline.approval.scene.shot.mask.depth.pose.metadata.project-context.file.document.table.url.date.color`.split(`.`)),Object.freeze([`final.render`,`stock.search`,`stock.select`,`stock.auto`,`gif.search`,`gif.save`,`presenter.generate`,`quality.analyze`,`image.generate`,`image.generate.batch`,`media.generate`,`youtube.upload`]),Object.freeze([`text`,`number`,`slider`,`checkbox`,`asset`,`select`,`multiselect`,`file`,`date`,`color`,`url`,`richtext`,`list`,`grid`]),Object.freeze([`gallery`,`before-after`,`table`,`document`,`chart`,`code`,`player`,`download`]),Object.freeze({file:[`file`,`file[]`],date:[`date`],color:[`color`],url:[`url`],richtext:[`document`,`text`],list:[`text[]`,`number[]`,`integer[]`,`url[]`,`date[]`,`color[]`],grid:[`table`]}),Object.freeze({gallery:[`image[]`],\"before-after\":[`image`],table:[`table`],document:[`document`,`text`],chart:[`table`,`number[]`,`integer[]`],code:[`text`,`json`,`object`],player:[`audio`,`video`,`audio[]`,`video[]`],download:[`file`,`file[]`,`file-bundle`]});let R=Object.freeze({script:`script`,transcript:`transcript`,shots:`shot[]`,shotPlan:`shot-plan`,scenes:`scene[]`,characters:`character[]`,locations:`location[]`,styles:`style[]`,assets:`asset[]`,files:`file[]`,generations:`metadata[]`,versions:`metadata[]`,timeline:`timeline`,editor:`timeline`,canvas:`pipeline`,blueprint:`bible`,panels:`panel-document`,board:`board-document`,animation:`scene-document`,metadata:`metadata`}),z=(e,t,n,r)=>Object.freeze({executor:e,mode:t,byok:n,summary:r}),ie=Object.freeze({\"text.generate\":z(`capability-run`,`sync`,!0,`Exact model, account BYOK or credits, and explicit run review`),\"audio.speech\":z(`capability-run`,`sync`,!0,`One short text/script input to measured audio in any StillMade catalog voice (Deepgram, ElevenLabs, OpenAI, Kokoro) with credits, or OpenAI with your key; playback review; accepted project recordings can be explicitly added to Editor audio`),\"audio.transcribe\":z(`capability-run`,`sync`,!0,`One owner-scoped stored audio asset to reviewed text and ordered word timings with StillMade transcription on credits, or OpenAI Whisper with your key`),\"audio.music\":z(`capability-run`,`sync`,!1,`One prompt to generated music (5–240 seconds) with StillMade credits and playback review`),\"audio.sfx\":z(`capability-run`,`sync`,!1,`One prompt to a generated sound effect (0.5–22 seconds) with StillMade credits and playback review`),\"image.generate\":z(`capability-run`,`sync`,!0,`One prompt and optional reference images to a stored PNG with any catalog image model and its settings; StillMade credits or account key, and actual image review`),\"video.generate\":z(`capability-run`,`async`,!0,`One prompt and optional first/last frames to a measured stored video clip with any catalog video model and its settings; StillMade credits and actual video review`),\"image.describe\":z(`capability-run`,`sync`,!0,`One to four owned images to bounded production notes; host-selected model/payment and actual description review`),\"media.analyze\":z(`capability-run`,`sync`,!1,`One owned video (optionally one time range), image or up to four images to structured visual evidence: summary, timeline, observations, on-screen text and issues, with StillMade credits; detail \"check\" gives one to four photos a short answer each at one price per call`),\"web.fetch\":z(`capability-run`,`sync`,!1,`One public web page read by the host and answered against the Block's instruction, with StillMade credits; no cookies, keys or private addresses`),\"web.research\":z(`capability-run`,`sync`,!1,`One topic searched on the web and summarized with cited sources, with StillMade credits`),\"timeline.propose\":z(`capability-run`,`sync`,!0,`Bounded typed context to strict timeline-edit JSON; host-selected model/payment, stale-before checks, preview and Apply`),\"workspace.propose\":z(`capability-run`,`sync`,!0,`Bounded typed context to a strict workspace-edit proposal for one permitted workspace; preview and explicit Apply`),\"connection.execute\":z(`connection`,`sync`,!1,`One reviewed action on a connected third-party app account through the host connection service; the Block never receives account credentials`)}),ae=e=>Object.freeze(Object.entries(ie).filter(([,t])=>e(t)).map(([e])=>e));ae(()=>!0),ae(e=>e.executor===`capability-run`),ae(e=>e.executor===`capability-run`&&e.mode===`sync`),ae(e=>e.byok),[...Object.keys(R).map(e=>`context.${e}.read`)];let oe=new Set([`__proto__`,`prototype`,`constructor`]);function B(e,t=0,n={nodes:0}){if(I(t<=40&&++n.nodes<=5e5,`LIMIT`,`Document exceeds complexity limit`),!(e===null||[`string`,`boolean`].includes(typeof e))){if(typeof e==`number`){I(Number.isFinite(e),`SCHEMA`,`Numbers must be finite`);return}I(Array.isArray(e)||L(e),`SCHEMA`,`Only JSON data is accepted`);for(let[r,i]of Object.entries(e))I(!oe.has(r),`SCHEMA`,`Forbidden field: ${r}`),B(i,t+1,n)}}function V(e){B(e);let t=e=>Array.isArray(e)?e.map(t):L(e)?Object.fromEntries(Object.keys(e).sort().map(n=>[n,t(e[n])])):e;return JSON.stringify(t(e))}async function se(e){let t=new TextEncoder().encode(V(e)),n=await globalThis.crypto.subtle.digest(`SHA-256`,t);return Array.from(new Uint8Array(n),e=>e.toString(16).padStart(2,`0`)).join(``)}let ce=Object.freeze(Object.fromEntries(Object.entries({planImagePanelStrip:[`messages`,`words`,`title`,`aspect`,`modelTier`,`projectType`,`projectTypeNote`,`frameDensity`,`frameTarget`,`prevPanelCount`],planGifBeats:[`words`,`strip`,`tone`,`modelTier`],planCanvasBeats:[`words`,`strip`,`spans`,`lean`,`modelTier`],nameRevealElements:[`imageUrl`,`blobs`,`narration`,`modelTier`],placePanelText:[`imageUrl`,`texts`,`modelTier`],stockAutoFind:[`queries`,`description`,`kind`,`excludeUrls`],checkStripConsistency:[`anchorUrl`,`panels`,`styleText`],generateVideo:[`model`,`readablePrompt`,`negativePrompt`,`sceneNumber`,`firstFrameUrl`,`lastFrameUrl`,`duration`,`seed`,`toggles`,`quality`,`resolution`,`aspectRatio`,`generateAudio`]}).map(([e,t])=>[e,Object.freeze(t)])));function le(e){return I(e?.version===1&&[...Object.keys(ce),`uploadReferenceImage`,`searchGiphyGifs`].every(t=>typeof e[t]==`function`),`HOST_SERVICES`,`Image Panels requires its declared version 1 workflow host services.`),e}function ue(e){return I(e?.version===1&&typeof e.generateImage==`function`&&typeof e.notifyAccessDenied==`function`,`HOST_SERVICES`,`Panel generation requires its declared version 1 host service.`),e}function de(e){I(L(e),`HOST_SERVICES`,`Panel generation needs a request object.`);let t=Object.fromEntries(Object.entries(e).filter(([,e])=>e!==void 0));return B(t),I(Object.keys(t).every(e=>[`model`,`readablePrompt`,`referenceImages`,`aspectRatio`,`quality`,`resolution`,`contextMode`].includes(e))&&typeof t.model==`string`&&typeof t.readablePrompt==`string`,`HOST_SERVICES`,`Invalid panel image generation request.`),structuredClone(t)}function fe(e,t=`nano-banana-2`,{quality:n=`low`,resolution:r=`1K`}={}){let i=ue(e);return async({prompt:e,referenceImages:a,aspectRatio:o,contextMode:s=`context`})=>{let c;try{c=await i.generateImage(de({model:t,readablePrompt:e,referenceImages:a,aspectRatio:o,quality:n,resolution:r,contextMode:s}))}catch(e){throw e?.status===403&&i.notifyAccessDenied(),e}if(!c||c.failed||!c.url||!/^(https?:|\\/api\\/)/.test(c.url))throw Error(c?.error||`panel generation failed`);return{url:c.url}}}let pe={manifest:{schemaVersion:1,sdkVersion:`0.1.0`,id:`stillmade-internal.gif-cache-acceptance`,version:`1.0.0`,name:`GIF cache selection and receipt application`,description:`Collect selected GIF sources and apply exact trusted mirror receipts.`,kind:`task`,runtime:`javascript`,inputs:{action:{type:`text`},doc:{type:`json`},remap:{type:`json`}},outputs:{edit:{type:`json`}},permissions:{project:[],network:[],filesystem:[],secrets:[]}},code:`// Original GIF reference collection and exact mirror rewrite operation.\nfunction collectGifRefs(doc){\n const refs=[];\n for(const p of doc?.strip||[]){\n if(p?.type==='giphy'&&String(p.gif||'').trim())refs.push({url:p.gif,term:p.gifQuery||''});\n const ov=p?.overlayLayer;\n if(ov&&typeof ov==='object'&&String(ov.gifUrl||'').trim())refs.push({url:ov.gifUrl,term:ov.gifQuery||''});\n }\n return refs;\n}\nfunction rewrite(doc,remap){\n let changed=false;\n const strip=doc.strip.map(p=>{\n let next=p;\n if(p?.type==='giphy'&&remap.has(p.gif))next={...next,gif:remap.get(p.gif)};\n const ov=next?.overlayLayer;\n if(ov&&typeof ov==='object'&&remap.has(ov.gifUrl))next={...next,overlayLayer:{...ov,gifUrl:remap.get(ov.gifUrl)}};\n if(next!==p)changed=true;return next;\n });\n return changed?{...doc,strip}:doc;\n}\nreturn {edit:input.action==='collect'?collectGifRefs(input.doc):rewrite(input.doc,new Map(input.remap))};\n`,tests:[]};function H(e){return I(e?.version===1&&typeof e.run==`function`&&typeof e.actor==`function`,`HOST_SERVICES`,`Block editing requires version 1 local sandbox and identity services.`),e}function me(e){I(Array.isArray(e?.strip)&&e.strip.length<=4096,`GIF_CACHE`,`The GIF document exceeds this cache boundary.`);let t=new Map,n=new Map,r=e=>{if(!n.has(e)){let r=`source-${t.size}`;n.set(e,r),t.set(r,e)}return n.get(e)};return{doc:{strip:e.strip.map((e,t)=>{let n={index:t,type:e.type===`giphy`?`giphy`:`other`,gif:e.gif?r(e.gif):``,gifQuery:e.gifQuery?r(e.gifQuery):``},i=e.overlayLayer;return i&&typeof i==`object`&&(n.overlayLayer={gifUrl:i.gifUrl?r(i.gifUrl):``,gifQuery:i.gifQuery?r(i.gifQuery):``}),n})},values:t,reverse:n}}async function he(e,t,{signal:n,check:r,host:i}){let a=H(i),o=a.actor(),s=()=>{r(),I(o&&a.actor()===o&&!n?.aborted,`STALE`,`The account or GIF cache request changed.`)};s(),B(e),B(t);let c=await a.run(pe,{kind:`run`,input:e,signal:n,timeoutMs:15e3});s(),B(c.outputs?.edit),I(V(c.outputs.edit)===V(t),`GIF_CACHE`,`The sandbox changed an unrelated GIF source or field.`)}async function ge(e,t){let n=me(e),r=[];return e.strip.forEach((e,t)=>{let i=n.doc.strip[t];e.type===`giphy`&&String(e.gif||``).trim()&&r.push({url:i.gif,term:i.gifQuery||``});let a=e.overlayLayer;a&&typeof a==`object`&&String(a.gifUrl||``).trim()&&r.push({url:i.overlayLayer.gifUrl,term:i.overlayLayer.gifQuery||``})}),n.doc.strip.forEach((t,n)=>{String(e.strip[n].gif||``).trim()||(t.gif=``),t.overlayLayer&&!String(e.strip[n].overlayLayer.gifUrl||``).trim()&&(t.overlayLayer.gifUrl=``)}),await he({action:`collect`,doc:n.doc,remap:[]},r,t),r.map(e=>({url:n.values.get(e.url),term:e.term?n.values.get(e.term):``}))}async function _e(e,t,n){n.check();let r=me(e);I(t instanceof Map&&t.size<=8192,`GIF_CACHE`,`The mirror receipts are invalid.`);let i=new Map,a=[];for(let[e,n]of t){I(r.reverse.has(e)&&typeof n==`string`&&n.length>0&&n.length<=16384,`GIF_CACHE`,`A mirror receipt has no selected source.`);let t=r.reverse.get(e),o=`mirror-${a.length}`;a.push([t,o]),i.set(t,o)}let o={strip:r.doc.strip.map(e=>({...e,...e.type===`giphy`&&i.has(e.gif)?{gif:i.get(e.gif)}:{},...e.overlayLayer&&i.has(e.overlayLayer.gifUrl)?{overlayLayer:{...e.overlayLayer,gifUrl:i.get(e.overlayLayer.gifUrl)}}:{}}))};await he({action:`apply`,doc:r.doc,remap:a},o,n);let s=!1,c=e.strip.map(e=>{let n=e.type===`giphy`&&t.has(e.gif)?t.get(e.gif):e.gif,r=e.overlayLayer,i=r&&typeof r==`object`&&t.has(r.gifUrl)&&t.get(r.gifUrl)!==r.gifUrl?{...r,gifUrl:t.get(r.gifUrl)}:r;return n===e.gif&&i===r?e:(s=!0,{...e,...n===e.gif?{}:{gif:n},...i===r?{}:{overlayLayer:i}})});return n.check(),s?{...e,strip:c}:e}let ve={manifest:{schemaVersion:1,sdkVersion:`0.1.0`,id:`stillmade-internal.plan-finalization`,version:`1.0.0`,name:`Panel plan finalization`,description:`Apply the default panel style and admitted planned GIF overlays.`,kind:`task`,runtime:`javascript`,inputs:{kind:{type:`text`},doc:{type:`json`},style:{type:`json`},aspect:{type:`text`},overlays:{type:`json`},allowed:{type:`json`}},outputs:{edit:{type:`json`}},permissions:{project:[],network:[],filesystem:[],secrets:[]}},code:`// Original style construction and post-assembly operations. Media are host tokens.\nfunction buildStyleBlock({aspect='16:9',styleNotes='',styleText}={}){\n const extra=styleNotes?\\` \\${String(styleNotes).trim()}\\`:'';\n return \\`\\${styleText}\\${extra} \\${aspect} framing.\\`;\n}\nfunction updatePanel(doc,panelId,patch){return {...doc,strip:doc.strip.map(p=>p.panelId===panelId?{...p,...patch,provenance:patch.provenance||'user'}:p)};}\nlet next=input.doc;\nif(input.kind==='style'){\n const st=input.style;\n next={...next,styleBlock:buildStyleBlock({aspect:input.aspect,styleText:st.text}),meta:{...next.meta,styleRef:st.refs?.[0]??null,...(st.refs?.length?{styleRefs:[...st.refs]}:{}),styleRefsHidden:!!st.builtin},scenes:(next.scenes||[]).map(sc=>({...sc,styleBlock:null}))};\n}else{\n for(let i=0;i<input.overlays.length;i++){\n const {targetPanelId,overlay}=input.overlays[i];\n if(input.allowed[i]&&next.strip.some(p=>p.panelId===targetPanelId&&p.type==='panel'))next=updatePanel(next,targetPanelId,{overlayLayer:overlay});\n }\n}\nreturn {edit:next};\n`,tests:[]},ye=e=>Object.fromEntries(Object.keys(e||{}).map((e,t)=>[e,{preserved:t}]));async function be(e,t,{signal:n,check:r,services:i}){r(),B(e),B(t),I(JSON.stringify(e).length<=1048576,`PLAN_FINALIZATION`,`The planned style or overlays exceed the supported size.`);let a=await i.run(ve,{kind:`run`,input:e,signal:n,timeoutMs:15e3});r(),B(a.outputs?.edit),I(V(a.outputs.edit)===V(t),`PLAN_FINALIZATION`,`The sandbox changed unrelated planned content.`)}async function xe(e,t,n,{aspect:r,signal:i,check:a,validateDocument:o,host:s}){let c=H(s),l=c.actor(),u=V({doc:e,style:t,overlays:n,aspect:r}),d=()=>{a(),I(!i?.aborted&&l&&c.actor()===l&&V({doc:e,style:t,overlays:n,aspect:r})===u,`STALE`,`The account, plan or style changed before finalization.`)};d(),I(e&&Array.isArray(e.strip)&&e.strip.length<=4096&&Array.isArray(e.scenes)&&Array.isArray(n)&&n.length<=512&&typeof t?.text==`string`&&Array.isArray(t.refs)&&t.refs.length<=64,`PLAN_FINALIZATION`,`The planned style or overlay list is unavailable.`);let f={text:t.text,refs:t.refs.slice(),builtin:!!t.builtin},p=e.meta?.aspect||r,m={kind:`style`,doc:{styleBlock:{original:!0},meta:ye(e.meta),scenes:e.scenes.map(ye),strip:{original:!0}},style:{...f,refs:f.refs.map((e,t)=>({reference:t}))},aspect:p,overlays:[],allowed:[]},h={...m.doc,styleBlock:`${f.text} ${p} framing.`,meta:{...m.doc.meta,styleRef:m.style.refs[0]??null,...m.style.refs.length?{styleRefs:m.style.refs.slice()}:{},styleRefsHidden:f.builtin},scenes:m.doc.scenes.map(e=>({...e,styleBlock:null}))};await be(m,h,{signal:i,check:d,services:c});let g=o({...e,styleBlock:h.styleBlock,meta:{...e.meta,styleRef:f.refs[0]??null,...f.refs.length?{styleRefs:f.refs.slice()}:{},styleRefsHidden:f.builtin},scenes:e.scenes.map(e=>e.styleBlock===null?e:{...e,styleBlock:null})});if(d(),!n.length)return g;let _=g.strip.map((e,t)=>({index:t,panelId:e.panelId,type:e.type,overlayLayer:{original:t},provenance:{original:t}})),v=[],y=[],b=_.slice();for(let e of n){d();let t=e.targetPanelId,n=structuredClone(e.overlay),r=!1;try{B(n),g.strip.some(e=>e.panelId===t&&e.type===`panel`)&&(g=o({...g,strip:g.strip.map(e=>e.panelId===t?{...e,overlayLayer:n,provenance:`user`}:e)}),r=!0)}catch{}let i={receipt:v.length};v.push({targetPanelId:t,overlay:i}),y.push(r),r&&(b=b.map(e=>e.panelId===t?{...e,overlayLayer:i,provenance:`user`}:e))}return await be({kind:`overlays`,doc:{strip:_},style:{},aspect:p,overlays:v,allowed:y},{strip:b},{signal:i,check:d,services:c}),d(),g}let Se={manifest:{schemaVersion:1,sdkVersion:`0.1.0`,id:`stillmade-internal.panel-lineage`,version:`1.0.0`,name:`Image Panels lineage edits`,description:`Change lineage persistence or convert a repeated frame to an edit.`,kind:`task`,runtime:`javascript`,inputs:{document:{type:`json`},action:{type:`text`},id:{type:`text`},persistent:{type:`boolean`}},outputs:{edit:{type:`json`}},permissions:{project:[],network:[],filesystem:[],secrets:[]}},code:`function loadPanelDoc(doc){return doc;}\nconst CONTINUATION_PROMPTS = [\n 'Same scene, same moment, same characters, same art style; REDRAW this as a tight close-up on the single most important subject or detail in the frame — a genuinely different, much closer composition, not a slight zoom.',\n 'Same scene, same moment, same characters, same art style; REDRAW this from a clearly different camera angle — shifted to the side or over a shoulder — same staging, visibly re-framed.',\n 'Same scene, same moment, same characters, same art style; REDRAW this as a wider shot pulled back to reveal more of the surroundings — same staging, clearly different framing.',\n];\nfunction continuationPrompt(k = 1) {\n return CONTINUATION_PROMPTS[(Math.max(1, k | 0) - 1) % CONTINUATION_PROMPTS.length];\n}\nfunction setLineagePersistent(doc, lineageId, persistent) {\n if (!doc.lineages[lineageId]) throw new Error(\\`setLineagePersistent: unknown lineage \"\\${lineageId}\"\\`);\n const lineages = { ...doc.lineages, [lineageId]: { ...doc.lineages[lineageId], persistent: !!persistent } };\n return loadPanelDoc({ ...doc, lineages });\n}\nfunction convertRepeatToEdit(doc, panelId, changePrompt = continuationPrompt(1)) {\n const panel = doc.strip.find((p) => p.panelId === panelId);\n if (!panel) throw new Error(\\`convertRepeatToEdit: unknown panel \"\\${panelId}\"\\`);\n if (panel.kind !== 'repeat') throw new Error(\\`convertRepeatToEdit: \\${panelId} is not a repeat\\`);\n const strip = doc.strip.map((p) => {\n if (p.panelId !== panelId) return p;\n const { repeatOf, ...rest } = p;\n return { ...rest, kind: 'edit', sourcePanelId: repeatOf, prompt: String(changePrompt), image: null, needsRefresh: false, provenance: 'user' };\n });\n return loadPanelDoc({ ...doc, strip });\n}\nif(!['persistent','convert'].includes(input.action))throw new Error('Unknown action');const next=input.action==='persistent'?setLineagePersistent(input.document,input.id,input.persistent):convertRepeatToEdit(input.document,input.id);return {edit:{schemaVersion:1,strip:next.strip,lineages:next.lineages}};`,tests:[]},Ce=`Same scene, same moment, same characters, same art style; REDRAW this as a tight close-up on the single most important subject or detail in the frame — a genuinely different, much closer composition, not a slight zoom.`,U=(e,t)=>JSON.stringify(e)===JSON.stringify(t);function we(e,t,n,r){return{action:t,id:n,persistent:!!r,document:{schemaVersion:1,strip:e.strip.map(e=>Object.fromEntries([`panelId`,`kind`,`repeatOf`,`sourcePanelId`,`needsRefresh`,`provenance`].filter(t=>e[t]!==void 0).map(t=>[t,e[t]]))),lineages:Object.fromEntries(Object.entries(e.lineages).map(([e,t])=>[e,t.persistent===void 0?{}:{persistent:t.persistent}]))}}}function W(e,t,n){I([`persistent`,`convert`].includes(t.action)&&n&&Object.keys(n).length===3&&n.schemaVersion===1&&Array.isArray(n.strip)&&n.strip.length===e.strip.length,`PANEL_LINEAGE`,`The sandbox returned an invalid lineage edit.`);let r=t.action===`convert`,i=r?e.strip.find(e=>e.panelId===t.id):null;I(r?i?.kind===`repeat`:!!e.lineages[t.id],`PANEL_LINEAGE`,`The selected repeat or lineage is unavailable.`);let a=r?t.document.lineages:{...t.document.lineages,[t.id]:{...t.document.lineages[t.id],persistent:t.persistent}};I(U(n.lineages,a),`PANEL_LINEAGE`,`The sandbox changed unrelated lineages.`);let o=e.strip.map((e,r)=>{let a={...t.document.strip[r]};e===i&&(delete a.repeatOf,Object.assign(a,{kind:`edit`,sourcePanelId:e.repeatOf,prompt:Ce,image:null,needsRefresh:!1,provenance:`user`}));let o=n.strip[r];if(I(o&&Object.keys(o).length===Object.keys(a).length&&Object.keys(o).every(e=>U(o[e],a[e])),`PANEL_LINEAGE`,`The sandbox changed an unrelated panel field.`),e!==i)return e;let{repeatOf:s,...c}=e;return{...c,kind:`edit`,sourcePanelId:s,prompt:Ce,image:null,needsRefresh:!1,provenance:`user`}});return r?{...e,strip:o}:e.lineages[t.id].persistent===t.persistent?e:{...e,lineages:{...e.lineages,[t.id]:{...e.lineages[t.id],persistent:t.persistent}}}}async function Te(e,t,{signal:n,assertCurrent:r,validateDocument:i,host:a}){let o=H(a),s=o.actor(),c=JSON.stringify(e),l=()=>{r(),I(!n?.aborted&&o.actor()===s&&JSON.stringify(e)===c,`STALE`,`The repeat conversion scope changed.`)};l(),I(Array.isArray(e?.strip)&&e.strip.length<=4096,`PANEL_LINEAGE`,`The repeat conversion scope is too large.`);let u=we(e,`convert`,t,!1);I(JSON.stringify(u).length<=1048576,`PANEL_LINEAGE`,`The repeat conversion metadata exceeds 1 MiB.`);let d=await o.run(Se,{kind:`run`,input:u,signal:n,timeoutMs:15e3});l();let f=W(e,u,d.outputs?.edit),p=f===e?e:i(f);return l(),p}function Ee({doc:e,projectId:t,canEdit:n,onDocChange:r,validateDocument:i,editLease:a,host:o}){let s=H(o),c=()=>s.actor(),[l,u]=(0,v.useState)(null),[d,f]=(0,v.useState)(``),p=(0,v.useRef)(null),m=(0,v.useRef)(!0),h=(0,v.useRef)(0),g=(0,v.useRef)(null),_=c();g.current={doc:e,projectId:t,canEdit:n,onDocChange:r,validateDocument:i,actor:_,services:s};let y=(0,v.useCallback)(()=>{h.current++,a?.current===p.current&&(a.current=null),p.current?.abort(),p.current=null,u(null)},[a]);return(0,v.useEffect)(()=>(m.current=!0,()=>{m.current=!1,h.current++,a?.current===p.current&&(a.current=null),p.current?.abort(),p.current=null}),[]),(0,v.useEffect)(()=>{y()},[e,t,n,_,s,y]),{change:(0,v.useCallback)(async(e,t,n=!1,r)=>{let i=g.current;if(i.services!==s||!i.canEdit||!i.doc||p.current||a?.current)return;let o=++h.current,l=new AbortController;p.current=l,a&&(a.current=l),u(t),f(``);let d,_=()=>{let e=g.current;I(m.current&&p.current===l&&!l.signal.aborted&&e.doc===i.doc&&e.projectId===i.projectId&&e.canEdit&&e.services===i.services&&e.actor===i.actor&&c()===i.actor&&JSON.stringify(i.doc)===d,`STALE`,`The panels changed. Review the current lineage before editing again.`)};try{d=JSON.stringify(i.doc);let f=we(i.doc,e,t,n);_();let v=await s.run(Se,{kind:`run`,input:f,signal:l.signal,timeoutMs:15e3});_();let y=W(i.doc,f,v.outputs?.edit),b=y===i.doc?i.doc:i.validateDocument(y);if(_(),r){let e=JSON.stringify(b);a?.current===l&&(a.current=null),p.current=null,u(null),await r(b,()=>{let t=g.current;I(m.current&&t.projectId===i.projectId&&t.canEdit&&t.services===i.services&&t.actor===i.actor&&c()===i.actor&&(t.doc===i.doc&&JSON.stringify(i.doc)===d||t.doc===b&&JSON.stringify(b)===e),`STALE`,`The panels changed while the converted shot was generating.`)})}else b!==i.doc&&i.onDocChange(e=>{let t=g.current;try{return I(m.current&&!l.signal.aborted&&h.current===o&&t.services===i.services&&t.actor===i.actor&&c()===i.actor&&t.projectId===i.projectId&&t.canEdit&&JSON.stringify(e)===d&&JSON.stringify(i.doc)===d,`STALE`,`The project changed before saving the lineage.`),b}catch{return e}})}catch(e){m.current&&c()===i.actor&&g.current.projectId===i.projectId&&!l.signal.aborted&&f(e.message||`The lineage edit could not be applied.`)}finally{p.current===l&&(a?.current===l&&(a.current=null),p.current=null,m.current&&u(null))}},[s]),pending:l,error:d,cancel:y}}let G={manifest:{schemaVersion:1,sdkVersion:`0.1.0`,id:`stillmade-internal.plan-assembly`,version:`1.0.0`,name:`Image panel plan assembly`,description:`Assemble the complete planner strip and narration timing into a panel document.`,kind:`task`,runtime:`javascript`,inputs:{plan:{type:`json`},words:{type:`json`},title:{type:`text`},aspect:{type:`text`},voPath:{type:`json`}},outputs:{edit:{type:`json`}},permissions:{project:[],network:[],filesystem:[],secrets:[]}},code:`const METHOD_IDS = [\n 'cycle', // 2–5 near-identical frames oscillated (1→2→1→3) to fake motion; ≤1.5s each\n 'accumulation', // base frame; each beat ADDS an element on its VO phrase\n 'reveal', // inverse: start full, remove/cross-out/hide per beat\n 'expressionSequence', // same frame, expression swaps on the beat; one-way\n 'zoomProgression', // same scene redrawn closer each beat (wide→mid→close)\n 'poseProgression', // sequential poses reading as one action; one-way\n 'comparison', // side-by-side or A-then-B swap to contrast\n 'moodShift', // whole frame recolors on a beat (grayscale, red tint, night)\n 'insertCutaway', // cut to one illustrative panel, then back (lineage interleave)\n 'matchSwap', // one image becomes a related one in place (phone→ambulance)\n 'progressiveReveal', // corrections spec Part B: solid-bg explainer build-up — the\n // FINISHED diagram generates ONCE; each step uncovers one more\n // element (cover rects in the exact sampled bg color). One\n // generation, zero drift, every reveal step free.\n];\nconst METHOD_SET = new Set(METHOD_IDS);\n\n// ── B1: hard timing rules (system-authored panels only) ──────────────────────\n// The orchestrator NEVER authors a panel longer than the ceiling; only a manual\n// user edit in the editor may exceed it. Cycle members oscillate fast.\nconst HARD_PANEL_CAP_MS = 2500;\nconst CYCLE_PANEL_CAP_MS = 1500;\nfunction methodCapMs(method) {\n return method === 'cycle' ? CYCLE_PANEL_CAP_MS : HARD_PANEL_CAP_MS;\n}\n\n// When an over-cap beat is split (or a hold-repeat is converted), the tail must\n// show a MEANINGFULLY different frame — the ceiling exists so something visibly\n// changes. \"Camera pushes in slightly\" proved too weak: edit models render it\n// as a near-identical ~5% crop. The rule (unless the beat is a deliberate\n// pseudo-animation like cycle oscillation): a continuation is a real REFRAME —\n// \"REDRAW as <a different framing>\" forces recomposition, the same proven verb\n// the zoomProgression method template uses. Rotation, so back-to-back\n// continuations of one beat also differ from each other.\n// Mirrored in server/services/imagePanelPrompts.js (the planner-side defense).\nconst CONTINUATION_PROMPTS = [\n 'Same scene, same moment, same characters, same art style; REDRAW this as a tight close-up on the single most important subject or detail in the frame — a genuinely different, much closer composition, not a slight zoom.',\n 'Same scene, same moment, same characters, same art style; REDRAW this from a clearly different camera angle — shifted to the side or over a shoulder — same staging, visibly re-framed.',\n 'Same scene, same moment, same characters, same art style; REDRAW this as a wider shot pulled back to reveal more of the surroundings — same staging, clearly different framing.',\n];\n// k is the 1-based continuation index within a split beat (p14c1 → 1, c2 → 2 …).\nfunction continuationPrompt(k = 1) {\n return CONTINUATION_PROMPTS[(Math.max(1, k | 0) - 1) % CONTINUATION_PROMPTS.length];\n}\n\n// Throws when a SYSTEM-authored panel exceeds its method cap — the B1 \"logic\n// error\" validator. User-authored durations (provenance 'user') are exempt:\n// the editor is the one place a longer hold is allowed.\nfunction validateSystemTiming(strip) {\n for (const p of (strip || [])) {\n if (p.type === 'titleScreen') continue; // the cap governs PANELS\n // COLLAGE CANVAS is the deliberate exception (spec S2): the cap exists so\n // something always happens on screen, and a canvas satisfies that\n // INTERNALLY (elements keep popping on the beat) — its liveliness is\n // linted inside collageCanvas.canvasLivelinessGaps instead.\n if (p.type === 'canvas') continue;\n if (p.provenance === 'user') continue; // manual edits may exceed\n const cap = methodCapMs(p.method);\n if (Number(p.durationMs) > cap) {\n throw new Error(\\`timing: system-authored panel \\${p.panelId} is \\${p.durationMs}ms — over the \\${cap}ms \\${p.method === 'cycle' ? 'cycle' : 'hard'} cap\\`);\n }\n }\n return true;\n}\n\n// ── B3: genre palettes (per SCENE, not per video) ────────────────────────────\n// LEAN, not law (mode-selector spec A3): the palette is each genre's center of\n// gravity — the default technique pull. ANY method may be used in ANY scene\n// when the beat calls for it; a great explainer often needs story beats and a\n// great story often needs an explainer diagram. The old off-genre lint that\n// flagged cross-genre methods is REMOVED — it produced worse videos.\nconst GENRES = ['story', 'explainer'];\nconst GENRE_PALETTES = {\n story: ['expressionSequence', 'poseProgression', 'reveal', 'moodShift', 'zoomProgression', 'insertCutaway', 'matchSwap'],\n explainer: ['progressiveReveal', 'accumulation', 'cycle', 'comparison', 'reveal', 'matchSwap', 'insertCutaway', 'zoomProgression'],\n};\n\n// ── Mode-selector spec Part A: the project type (MANUAL, sets the LEAN) ──────\n// Picked by the user at creation (never auto-selected), changeable later. It\n// steers the chat's probing and the planner's center of gravity — it NEVER\n// gates which techniques are available.\nconst PROJECT_TYPES = ['story', 'explainer', 'both', 'neither'];\n\n\nconst VISUAL_LEAD_MS=75;\nconst PANEL_MIN_MS=350;\nconst GIF_MODES=['replace','overlay'];\nfunction normStyleRefs(v) {\n if (Array.isArray(v)) return v.filter((u) => typeof u === 'string' && u);\n return typeof v === 'string' && v ? [v] : [];\n}\nfunction retimeAfterReorder(strip) {\n let t = strip.length ? Math.min(...strip.map((p) => Number(p.startMs) || 0)) : 0;\n return strip.map((p) => {\n const out = { ...p, startMs: t };\n t += Math.max(1, Number(p.durationMs) || 1);\n return out;\n });\n}\nfunction assignStripTiming(planStrip, words, { leadMs = VISUAL_LEAD_MS } = {}) {\n const w = (Array.isArray(words) ? words : []).map((x) => ({\n startMs: Math.round(Number(x.startMs ?? (x.start * 1000)) || 0),\n endMs: Math.round(Number(x.endMs ?? (x.end * 1000)) || 0),\n }));\n if (!w.length) throw new Error('assignStripTiming: no words');\n const entries = (planStrip || []).filter((p) => p && typeof p === 'object');\n const wordAt = (v, lo = 0) => Math.max(lo, Math.min(Number(v) || 0, w.length - 1));\n // Anchor pre-pass (VISUAL LEADS AUDIO): each beat APPEARS leadMs before its\n // first word starts. The first beat clamps to t=0 (can't lead before the\n // video exists); when words are so tight that a lead would collide with the\n // previous beat's appearance, order is KEPT and the anchor clamps forward —\n // beats are never reordered.\n const anchors = [];\n for (let i = 0; i < entries.length; i++) {\n let a = Math.max(0, w[wordAt(entries[i].wordStart)].startMs - leadMs);\n if (i > 0) a = Math.max(a, anchors[i - 1] + 1);\n anchors.push(a);\n }\n const out = [];\n for (let i = 0; i < entries.length; i++) {\n const p = entries[i];\n const ws = wordAt(p.wordStart);\n const we = wordAt(p.wordEnd, ws);\n const startMs = out.length ? out[out.length - 1].startMs + out[out.length - 1].durationMs : anchors[0];\n // A beat holds until the NEXT beat's lead-shifted appearance; the last\n // beat runs to its final word's end (the video ends with the audio).\n const rawEnd = i + 1 < entries.length ? anchors[i + 1] : Math.max(w[we].endMs, anchors[i] + 1);\n const endMs = Math.max(rawEnd, startMs + 1);\n const durationMs = endMs - startMs;\n const isTitle = p.type === 'titleScreen';\n const isGiphy = p.type === 'giphy';\n const isCanvas = p.type === 'canvas';\n // progressiveReveal: the base (the complete diagram, the group's final\n // beat) must never be absorbed — its steps reference it.\n const isRevealBase = p.kind === 'base' && p.method === 'progressiveReveal';\n if (out.length && durationMs < PANEL_MIN_MS && !isTitle && !isGiphy && !isCanvas && !isRevealBase && out[out.length - 1].type !== 'titleScreen' && out[out.length - 1].type !== 'giphy' && out[out.length - 1].type !== 'canvas') {\n // too-short beat: absorb into the previous panel (never a flash frame)\n out[out.length - 1].durationMs += durationMs;\n out[out.length - 1].absorbed = (out[out.length - 1].absorbed || 0) + 1;\n continue;\n }\n // B1 hard ceiling: a system beat longer than its method cap SPLITS — the\n // panel keeps the head, each tail part becomes a CONTINUATION EDIT chained\n // off the part before it. Never a same-frame repeat, and never a faint\n // push-in: each continuation is a MEANINGFUL REFRAME (rotating close-up /\n // new angle / wider — continuationPrompt(k)), so the frame visibly changes\n // — that is the whole point of the ceiling. Title screens are not panels\n // and are exempt.\n // COLLAGE CANVAS (spec S2): exempt from the per-panel ceiling — the\n // \"something always happens\" rule is satisfied INSIDE it (elements keep\n // popping on the beat; canvasLivelinessGaps lints static stretches).\n const cap = isTitle || isCanvas ? Infinity : methodCapMs(p.method);\n if (durationMs > cap) {\n const parts = Math.ceil(durationMs / cap);\n const step = Math.floor(durationMs / parts);\n let t = startMs;\n let prevId = p.panelId;\n for (let k = 0; k < parts; k++) {\n const d = k === parts - 1 ? startMs + durationMs - t : step;\n if (k === 0) {\n out.push({ ...p, startMs: t, durationMs: d });\n } else if (p.type === 'giphy') {\n // A reaction GIF loops — a longer hold repeats the SAME cached gif\n // (pixel-identical, free), never a paid continuation edit.\n out.push({ ...p, panelId: \\`\\${p.panelId}h\\${k}\\`, startMs: t, durationMs: d });\n } else if (p.type === 'diagram') {\n // A diagram beat's persistence is pixel-identical BY DESIGN (cached\n // elements) — split parts show the same composited state; never a\n // generative continuation edit.\n out.push({ ...p, panelId: \\`\\${p.panelId}h\\${k}\\`, startMs: t, durationMs: d });\n } else if (p.kind === 'revealStep' || (p.kind === 'base' && p.method === 'progressiveReveal')) {\n // A reveal group's frames are deterministic states of ONE image — a\n // longer hold repeats the frame (pixel-identical, free), never a\n // paid continuation edit (which would reframe the diagram).\n out.push({ ...p, panelId: \\`\\${p.panelId}h\\${k}\\`, kind: 'repeat', repeatOf: p.panelId, scene: null, revealOf: undefined, revealIndex: undefined, startMs: t, durationMs: d });\n } else {\n const id = \\`\\${p.panelId}c\\${k}\\`;\n out.push({ ...p, panelId: id, kind: 'edit', repeatOf: null, scene: null, changePrompt: continuationPrompt(k), sourcePanelId: prevId, startMs: t, durationMs: d });\n prevId = id;\n }\n t += d;\n }\n continue;\n }\n out.push({ ...p, startMs, durationMs });\n }\n return out;\n}\n\n// ── Connector beats (owner rule): a diagram panel whose ONLY new element is a\n// minor connector (an arrow, a line, a pointer) must FLASH, not hold — nobody\n// needs 2 seconds of arrow. Its word-span time is reclaimed and cascaded into\n// the FOLLOWING panels of the same scene (respecting their caps), so the major\n// reveal lands sooner and holds longer. Holds/re-layouts (no new elements) and\n// user-timed panels are untouched.\nconst CONNECTOR_BEAT_MS = 300;\nconst MINOR_ELEMENT_RE = /arrow|line|connector|pointer|divider|underline|dash|tick|dot/i;\nfunction tightenConnectorBeats(strip, scenes) {\n const elsByScene = new Map((scenes || []).filter((s) => s.renderer === 'diagram').map((s) => [s.sceneId, s.elements || {}]));\n if (!elsByScene.size) return strip;\n const out = strip.map((p) => ({ ...p }));\n const prevVisible = new Map(); // sceneId -> Set of shown element ids\n for (let i = 0; i < out.length; i++) {\n const p = out[i];\n if (p.type !== 'diagram') continue;\n const els = elsByScene.get(p.sceneId);\n if (!els) continue;\n const prev = prevVisible.get(p.sceneId) || new Set();\n const newly = (p.visibleElements || []).filter((id) => !prev.has(id));\n prevVisible.set(p.sceneId, new Set(p.visibleElements || []));\n if (!newly.length) continue; // hold / re-layout: not a reveal beat\n const allMinor = newly.every((id) => MINOR_ELEMENT_RE.test(id) || MINOR_ELEMENT_RE.test(els[id]?.prompt || ''));\n if (!allMinor || p.provenance === 'user' || p.durationMs <= CONNECTOR_BEAT_MS) continue;\n let steal = p.durationMs - CONNECTOR_BEAT_MS;\n p.durationMs = CONNECTOR_BEAT_MS;\n for (let j = i + 1; j < out.length && steal > 0; j++) {\n const n = out[j];\n if (n.type === 'titleScreen' || n.sceneId !== p.sceneId) break; // stay in the scene\n const cap = n.provenance === 'user' ? Infinity : methodCapMs(n.method);\n const add = Math.min(Math.max(0, cap - n.durationMs), steal);\n n.durationMs += add;\n steal -= add;\n }\n if (steal > 0) p.durationMs += steal; // nowhere to cascade — keep the timeline contiguous\n }\n return retimeAfterReorder(out);\n}\n\n// ── §12.1 assembly: planner output + VO words → the full panel doc ───────────\n// Accepts both planner shapes: legacy flat (no scenes → migrated to one scene\n// by the loader) and the scene-grouped addon shape (plan.scenes + sceneId +\n// method/methodGroup + type:'titleScreen' entries). Validates the B1 system\n// timing ceiling on the way out.\nfunction assemblePanelDoc({ plan, words, title = '', aspect = '16:9', styleRef = null, styleRefs = null, voPath = null } = {}) {\n const metaRefs = normStyleRefs(styleRefs).length ? normStyleRefs(styleRefs) : normStyleRefs(styleRef);\n if (!plan || !Array.isArray(plan.strip) || !plan.strip.length) throw new Error('assemblePanelDoc: plan has no strip');\n const timed = assignStripTiming(plan.strip, words);\n // Re-point edit sources at the surviving panels: if a panel was absorbed by\n // the timing merge, later edits that sourced it re-source the last surviving\n // panel of the same lineage (its visual state — the lineage's latest frame).\n const surviving = new Set(timed.map((p) => p.panelId));\n const lastOf = new Map(); // \\`\\${sceneId}:\\${lineageId}\\` -> last surviving panelId (scene-scoped, A2)\n const lastAnywhere = new Map(); // lineageId -> last surviving panelId (persistent lineages, A3)\n const lineages = { ...(plan.lineages || {}) };\n const strip = timed.map((p) => {\n if (p.type === 'titleScreen') {\n return { panelId: p.panelId, type: 'titleScreen', sceneId: p.sceneId, startMs: p.startMs, durationMs: p.durationMs, provenance: 'auto' };\n }\n // COLLAGE CANVAS (spec S4): a planner-authored canvas beat. Carries the\n // planner's word-indexed EVENTS through assembly; buildPlannedCanvasElements\n // converts them to ms-stamped elements once real timing exists (then the\n // events payload is dropped). Auto canvases self-arrange (S10).\n if (p.type === 'canvas') {\n return {\n panelId: p.panelId, type: 'canvas', sceneId: p.sceneId,\n background: typeof p.background === 'string' ? p.background : '#ffffff',\n autoArrange: p.autoArrange !== false, planned: true,\n elements: Array.isArray(p.elements) ? p.elements : [],\n ...(p.mode === 'typewriter' ? { mode: 'typewriter' } : {}),\n ...(Array.isArray(p.events) && p.events.length ? { events: p.events } : {}),\n ...(p.hint ? { hint: String(p.hint).slice(0, 200) } : {}),\n ...(p.template ? { template: String(p.template) } : {}),\n startMs: p.startMs, durationMs: p.durationMs,\n transitionIn: p.transitionIn === 'fade' ? 'fade' : 'cut', provenance: 'auto',\n ...(Number.isFinite(Number(p.wordStart)) ? { wordStart: p.wordStart, wordEnd: p.wordEnd } : {}),\n };\n }\n // GIF-retention (REPLACE mode): a reaction GIF beat — a clean allow-listed\n // row. Never generated; its cached gif resolves as the frame. Carries the\n // Giphy search intent + alternates so the review modal can swap.\n if (p.type === 'giphy') {\n return {\n panelId: p.panelId, type: 'giphy', sceneId: p.sceneId,\n mode: GIF_MODES.includes(p.mode) ? p.mode : 'replace',\n gif: String(p.gif || ''),\n ...(p.gifQuery ? { gifQuery: String(p.gifQuery) } : {}),\n ...(Array.isArray(p.candidates) && p.candidates.length ? { candidates: p.candidates.map(String) } : {}),\n ...(p.tone ? { tone: String(p.tone) } : {}),\n startMs: p.startMs, durationMs: p.durationMs,\n transitionIn: p.transitionIn === 'fade' ? 'fade' : 'cut',\n provenance: 'auto',\n };\n }\n // Dual renderer (spec B3): a diagram entry is a composited state of its\n // scene's cached elements — visibleElements + optional text overlays; no\n // lineage, no generation prompt.\n if (p.type === 'diagram') {\n return {\n panelId: p.panelId, type: 'diagram', sceneId: p.sceneId,\n visibleElements: Array.isArray(p.visibleElements) ? p.visibleElements.map(String) : [],\n ...(Array.isArray(p.textOverlays) && p.textOverlays.length ? { textOverlays: p.textOverlays } : {}),\n ...(String(p.sfx || '').trim() ? { sfx: String(p.sfx).trim() } : {}),\n ...(p.layout && typeof p.layout === 'object' ? { layout: p.layout } : {}),\n image: null, startMs: p.startMs, durationMs: p.durationMs,\n transitionIn: p.transitionIn === 'fade' ? 'fade' : 'cut', provenance: 'auto',\n method: METHOD_SET.has(p.method) ? p.method : null,\n methodGroup: p.methodGroup != null ? String(p.methodGroup) : null,\n };\n }\n const persistent = !!lineages[p.lineageId]?.persistent;\n const key = \\`\\${p.sceneId ?? 's1'}:\\${p.lineageId}\\`;\n // ZOOM PANEL (planner-authored): a free coded push-in beat. Its source\n // re-points like an edit's if the original was absorbed by the timing\n // merge, and the zoom itself becomes the lineage's latest visual state\n // (later edits chain from the zoomed frame).\n if (p.type === 'zoom') {\n let zsrc = p.sourcePanelId;\n if (!zsrc || !surviving.has(zsrc)) zsrc = lastOf.get(key) || (persistent ? lastAnywhere.get(p.lineageId) : null) || null;\n if (!zsrc) return null; // a zoom with nothing to push into is dropped\n const entry = {\n panelId: p.panelId, type: 'zoom', sceneId: p.sceneId, lineageId: p.lineageId,\n sourcePanelId: zsrc, zoom: null, image: null,\n startMs: p.startMs, durationMs: p.durationMs, transitionIn: 'cut', provenance: 'auto',\n ...(Number.isFinite(Number(p.wordStart)) ? { wordStart: p.wordStart, wordEnd: p.wordEnd } : {}),\n };\n lastOf.set(key, p.panelId);\n lastAnywhere.set(p.lineageId, p.panelId);\n return entry;\n }\n if (p.kind === 'repeat') {\n const entry = {\n panelId: p.panelId, type: 'panel', sceneId: p.sceneId, lineageId: p.lineageId,\n kind: 'repeat', repeatOf: p.repeatOf, prompt: '', sourcePanelId: null, image: null,\n startMs: p.startMs, durationMs: p.durationMs, transitionIn: 'cut', overlayLayer: null,\n provenance: 'auto', method: p.method ?? null, methodGroup: p.methodGroup ?? null,\n // A re-shown frame can carry a NEW label on its beat — keep the overlays\n // (the entry literal otherwise drops them, like the base/edit branch did).\n ...(Array.isArray(p.textOverlays) && p.textOverlays.length ? { textOverlays: p.textOverlays } : {}),\n ...(String(p.sfx || '').trim() ? { sfx: String(p.sfx).trim() } : {}),\n };\n return entry;\n }\n // progressiveReveal (corrections spec Part B): a revealStep carries only\n // its base reference + order — no prompts (its frame renders from the\n // base's finished image). The base itself can never be absorbed (guarded\n // in assignStripTiming), so revealOf always survives.\n if (p.kind === 'revealStep') {\n return {\n panelId: p.panelId, type: 'panel', sceneId: p.sceneId, lineageId: p.lineageId,\n kind: 'revealStep', revealOf: p.revealOf, revealIndex: Math.max(0, Number(p.revealIndex) || 0),\n prompt: '', sourcePanelId: null, image: null,\n startMs: p.startMs, durationMs: p.durationMs, transitionIn: 'cut', overlayLayer: null,\n provenance: 'auto', method: null, methodGroup: p.methodGroup != null ? String(p.methodGroup) : null,\n // A label/arrow can be the beat a revealStep IS — carry its overlays.\n ...(Array.isArray(p.textOverlays) && p.textOverlays.length ? { textOverlays: p.textOverlays } : {}),\n ...(String(p.sfx || '').trim() ? { sfx: String(p.sfx).trim() } : {}),\n };\n }\n let sourcePanelId = p.kind === 'edit' ? p.sourcePanelId : null;\n if (p.kind === 'edit' && (!sourcePanelId || !surviving.has(sourcePanelId))) {\n sourcePanelId = lastOf.get(key) || (persistent ? lastAnywhere.get(p.lineageId) : null) || null;\n }\n const kind = sourcePanelId == null && p.kind === 'edit' ? 'base' : p.kind; // an orphaned first edit becomes the lineage base\n const entry = {\n panelId: p.panelId,\n type: 'panel',\n sceneId: p.sceneId,\n lineageId: p.lineageId,\n kind,\n // An edit MUST carry a change (an empty one fails validation and, worse,\n // used to throw away the ENTIRE plan). If the planner emitted an edit with\n // no change, repair it into a subtle continuation instead of discarding the\n // whole strip — one salvaged panel beats a full re-plan.\n prompt: kind === 'base'\n ? String(p.scene || p.prompt || '')\n : (String(p.changePrompt || p.prompt || '').trim() || continuationPrompt(1)),\n sourcePanelId: kind === 'base' ? null : sourcePanelId,\n image: null,\n startMs: p.startMs,\n durationMs: p.durationMs,\n transitionIn: p.transitionIn === 'fade' ? 'fade' : 'cut',\n overlayLayer: null, // §4 seam: reserved for future coded overlays\n provenance: 'auto',\n method: METHOD_SET.has(p.method) ? p.method : null,\n methodGroup: p.methodGroup != null ? String(p.methodGroup) : null,\n // On-image labels (spec B4): carry planner-emitted overlays through assembly\n // — the entry literal otherwise drops them (only the diagram branch kept them).\n ...(Array.isArray(p.textOverlays) && p.textOverlays.length ? { textOverlays: p.textOverlays } : {}),\n ...(String(p.sfx || '').trim() ? { sfx: String(p.sfx).trim() } : {}),\n // Per-beat cast (the characters actually IN this beat) → gates the cast\n // reference so non-character beats stay free to be re-imagined.\n ...(Array.isArray(p.cast) ? { cast: p.cast.map(String) } : {}),\n };\n lastOf.set(key, p.panelId);\n lastAnywhere.set(p.lineageId, p.panelId);\n return entry;\n }).filter(Boolean);\n // Lineages must cover every lineage used (planner defense already shapes them).\n for (const p of strip) {\n if (p.type === 'panel' && !lineages[p.lineageId]) lineages[p.lineageId] = { sheetIds: [], place: '' };\n }\n const hasScenes = Array.isArray(plan.scenes) && plan.scenes.length > 0;\n const scenes = hasScenes ? plan.scenes.map((s) => ({\n sceneId: String(s.sceneId),\n title: String(s.title || ''),\n genre: GENRES.includes(s.genre) ? s.genre : null,\n styleBlock: s.styleBlock ? String(s.styleBlock) : null,\n styleRef: s.styleRef || null,\n ...(normStyleRefs(s.styleRefs).length ? { styleRefs: normStyleRefs(s.styleRefs) } : {}),\n sheets: { ...(s.sheets || {}) },\n titleScreen: s.titleScreen && typeof s.titleScreen === 'object' ? { ...s.titleScreen } : null,\n // Dual renderer: the scene declares how its beats are made (default 'scene').\n ...(s.renderer === 'diagram' ? {\n renderer: 'diagram',\n canvas: s.canvas && typeof s.canvas === 'object' ? { ...s.canvas } : {},\n elements: Object.fromEntries(Object.entries(s.elements || {}).map(([id, el]) => [id, {\n prompt: String(el?.prompt || ''),\n asset: el?.asset || null,\n pos: { x: Number(el?.pos?.x) || 0.5, y: Number(el?.pos?.y) || 0.5 },\n scale: Number.isFinite(Number(el?.scale)) ? Number(el.scale) : 1,\n }])),\n } : {}),\n })) : null;\n const finalStrip = scenes ? tightenConnectorBeats(strip, scenes) : strip;\n const projectType = PROJECT_TYPES.includes(plan.projectType) ? plan.projectType : null;\n const doc = {\n mode: 'imagePanel',\n ...(projectType ? { projectType } : {}),\n ...(plan.projectTypeNote ? { projectTypeNote: String(plan.projectTypeNote).slice(0, 500) } : {}),\n meta: { title, aspect, styleRef: metaRefs[0] ?? null, ...(metaRefs.length ? { styleRefs: metaRefs } : {}), ...(plan.sfxAuthored ? { sfxAuthored: true } : {}) },\n audio: { voPath, words: (words || []).map((x) => ({ text: String(x.text ?? x.word ?? ''), startMs: Math.round(Number(x.startMs ?? (x.start * 1000)) || 0), endMs: Math.round(Number(x.endMs ?? (x.end * 1000)) || 0) })) },\n styleBlock: String(plan.styleBlock || ''),\n sheets: { ...(plan.sheets || {}) },\n lineages,\n ...(scenes ? { scenes } : {}), // legacy plans migrate to one scene in the loader\n strip: finalStrip, // legacy entries lack sceneId — migration stamps s1\n };\n const out = loadPanelDoc(doc); // assembly must always produce a valid doc\n // B1: the orchestrator can NEVER author over the ceiling — enforced, not\n // hoped. The pacing rules hold across BOTH renderers (spec Part E).\n for (const p of out.strip) {\n if ((p.type !== 'panel' && p.type !== 'diagram') || p.provenance === 'user') continue;\n if (p.durationMs > methodCapMs(p.method)) throw new Error(\\`assemblePanelDoc: \\${p.panelId} is \\${p.durationMs}ms — over the system ceiling\\`);\n }\n return out;\n}\n\n\n// Strict document loading is performed by the host after exact admission.\nconst loadPanelDoc=value=>value;\n\nreturn {edit:assemblePanelDoc(input)};\n`,tests:[]},De=[`cycle`,`accumulation`,`reveal`,`expressionSequence`,`zoomProgression`,`poseProgression`,`comparison`,`moodShift`,`insertCutaway`,`matchSwap`,`progressiveReveal`],Oe=new Set(De),ke=[`Same scene, same moment, same characters, same art style; REDRAW this as a tight close-up on the single most important subject or detail in the frame — a genuinely different, much closer composition, not a slight zoom.`,`Same scene, same moment, same characters, same art style; REDRAW this from a clearly different camera angle — shifted to the side or over a shoulder — same staging, visibly re-framed.`,`Same scene, same moment, same characters, same art style; REDRAW this as a wider shot pulled back to reveal more of the surroundings — same staging, clearly different framing.`],Ae=[`story`,`explainer`],je=[`story`,`explainer`,`both`,`neither`];function Me(e){let t=new Map((e?.scenes||[]).map(e=>[e.sceneId,e.genre])),n=0,r=0;for(let i of e?.strip||[]){if(i.type===`titleScreen`)continue;let e=t.get(i.sceneId);e===`story`?n+=Number(i.durationMs)||0:e===`explainer`&&(r+=Number(i.durationMs)||0)}let i=n+r,a=i>0?r/i:0,o=i>0?n/i:0,s=null;return e?.projectType===`story`&&i>0&&a>=.55&&(s=`This project is labeled a story but ${Math.round(a*100)}% of its screen time is explainer — it reads more like an explainer. Is the label right?`),{storyMs:n,explainerMs:r,storyShare:o,explainerShare:a,advisory:s}}let Ne=e=>e.method===`cycle`?1500:2500,Pe=e=>ke[(Math.max(1,e|0)-1)%ke.length],Fe=e=>({startMs:Math.round(Number(e.startMs??e.start*1e3)||0),endMs:Math.round(Number(e.endMs??e.end*1e3)||0)}),Ie=e=>Array.isArray(e)?e.filter(e=>typeof e==`string`&&e):typeof e==`string`&&e?[e]:[];function Le(e,t){let n=t.map(Fe);if(!n.length)throw Error(`Plan assembly requires narration timings.`);let r=(e,t=0)=>Math.max(t,Math.min(Number(e)||0,n.length-1)),i=[];e.forEach((e,t)=>i.push(Math.max(0,n[r(e.wordStart)].startMs-75,t?i[t-1]+1:0)));let a=[];if(e.forEach((t,o)=>{let s=a.length?a.at(-1).startMs+a.at(-1).durationMs:i[0],c=o+1<e.length?i[o+1]:Math.max(n[r(t.wordEnd,r(t.wordStart))].endMs,i[o]+1),l=Math.max(c,s+1)-s,u=e=>[`titleScreen`,`giphy`,`canvas`].includes(e);if(a.length&&l<350&&!u(t.type)&&(t.kind!==`base`||t.method!==`progressiveReveal`)&&!u(a.at(-1).type)){a.at(-1).durationMs+=l,a.at(-1).absorbed=(a.at(-1).absorbed||0)+1;return}let d=[`titleScreen`,`canvas`].includes(t.type)?1/0:Ne(t);if(l<=d){a.push({...t,startMs:s,durationMs:l});return}let f=Math.ceil(l/d);if(!Number.isFinite(f)||a.length+f>4096)throw Error(`The assembled plan exceeds the supported output size.`);let p=Math.floor(l/f),m=s,h=t.panelId;for(let e=0;e<f;e++){let n=e===f-1?s+l-m:p,r={...t,startMs:m,durationMs:n};e&&([`giphy`,`diagram`].includes(t.type)?r.panelId=t.panelId+`h`+e:t.kind===`revealStep`||t.kind===`base`&&t.method===`progressiveReveal`?r={...r,panelId:t.panelId+`h`+e,kind:`repeat`,repeatOf:t.panelId,scene:null,revealOf:void 0,revealIndex:void 0}:(r={...r,panelId:t.panelId+`c`+e,kind:`edit`,repeatOf:null,scene:null,changePrompt:Pe(e),sourcePanelId:h},h=r.panelId)),a.push(r),m+=n}}),a.length>4096)throw Error(`The assembled plan exceeds the supported output size.`);return a}function Re(e,t){let n=new Map(t.filter(e=>e.renderer===`diagram`).map(e=>[e.sceneId,e.elements||{}]));if(!n.size)return e;let r=e.map(e=>({...e})),i=new Map,a=/arrow|line|connector|pointer|divider|underline|dash|tick|dot/i;r.forEach((e,t)=>{if(e.type!==`diagram`||!n.has(e.sceneId))return;let o=i.get(e.sceneId)||new Set,s=(e.visibleElements||[]).filter(e=>!o.has(e));if(i.set(e.sceneId,new Set(e.visibleElements||[])),!s.length||!s.every(t=>a.test(t)||a.test(n.get(e.sceneId)[t]?.prompt||``))||e.provenance===`user`||e.durationMs<=300)return;let c=e.durationMs-300;e.durationMs=300;for(let n=t+1;n<r.length&&c>0;n++){let t=r[n];if(t.type===`titleScreen`||t.sceneId!==e.sceneId)break;let i=t.provenance===`user`?1/0:Ne(t),a=Math.min(Math.max(0,i-t.durationMs),c);t.durationMs+=a,c-=a}c>0&&(e.durationMs+=c)});let o=r.length?Math.min(...r.map(e=>Number(e.startMs)||0)):0;return r.map(e=>{let t={...e,startMs:o};return o+=Math.max(1,Number(e.durationMs)||1),t})}function ze({plan:e,words:t,title:n=``,aspect:r=`16:9`,voPath:i=null}){if(!Array.isArray(e?.strip)||!e.strip.length)throw Error(`The planner returned no strip.`);let a=Le(e.strip.filter(e=>e&&typeof e==`object`),t),o=new Set(a.map(e=>e.panelId)),s=new Map,c=new Map,l={...e.lineages||{}},u=[];for(let e of a){let t={panelId:e.panelId,type:e.type,sceneId:e.sceneId,startMs:e.startMs,durationMs:e.durationMs,provenance:`auto`},n={transitionIn:e.transitionIn===`fade`?`fade`:`cut`},r={...Array.isArray(e.textOverlays)&&e.textOverlays.length?{textOverlays:e.textOverlays}:{},...String(e.sfx||``).trim()?{sfx:String(e.sfx).trim()}:{}},i=Number.isFinite(Number(e.wordStart))?{wordStart:e.wordStart,wordEnd:e.wordEnd}:{},a;if(e.type===`titleScreen`)a=t;else if(e.type===`canvas`)a={...t,background:typeof e.background==`string`?e.background:`#ffffff`,autoArrange:e.autoArrange!==!1,planned:!0,elements:Array.isArray(e.elements)?e.elements:[],...e.mode===`typewriter`?{mode:`typewriter`}:{},...Array.isArray(e.events)&&e.events.length?{events:e.events}:{},...e.hint?{hint:String(e.hint).slice(0,200)}:{},...e.template?{template:String(e.template)}:{},...n,...i};else if(e.type===`giphy`)a={...t,mode:[`replace`,`overlay`].includes(e.mode)?e.mode:`replace`,gif:String(e.gif||``),...e.gifQuery?{gifQuery:String(e.gifQuery)}:{},...Array.isArray(e.candidates)&&e.candidates.length?{candidates:e.candidates.map(String)}:{},...e.tone?{tone:String(e.tone)}:{},...n};else if(e.type===`diagram`)a={...t,visibleElements:Array.isArray(e.visibleElements)?e.visibleElements.map(String):[],...r,...e.layout&&typeof e.layout==`object`?{layout:e.layout}:{},image:null,...n,method:Oe.has(e.method)?e.method:null,methodGroup:e.methodGroup==null?null:String(e.methodGroup)};else{let u=`${e.sceneId??`s1`}:${e.lineageId}`,d=!!l[e.lineageId]?.persistent;if(e.type===`zoom`){let n=e.sourcePanelId;if((!n||!o.has(n))&&(n=s.get(u)||(d?c.get(e.lineageId):null)||null),!n)continue;a={...t,lineageId:e.lineageId,sourcePanelId:n,zoom:null,image:null,transitionIn:`cut`,...i},s.set(u,e.panelId),c.set(e.lineageId,e.panelId)}else if(e.kind===`repeat`)a={...t,type:`panel`,lineageId:e.lineageId,kind:`repeat`,repeatOf:e.repeatOf,prompt:``,sourcePanelId:null,image:null,transitionIn:`cut`,overlayLayer:null,method:e.method??null,methodGroup:e.methodGroup??null,...r};else if(e.kind===`revealStep`)a={...t,type:`panel`,lineageId:e.lineageId,kind:`revealStep`,revealOf:e.revealOf,revealIndex:Math.max(0,Number(e.revealIndex)||0),prompt:``,sourcePanelId:null,image:null,transitionIn:`cut`,overlayLayer:null,method:null,methodGroup:e.methodGroup==null?null:String(e.methodGroup),...r};else{let i=e.kind===`edit`?e.sourcePanelId:null;e.kind===`edit`&&(!i||!o.has(i))&&(i=s.get(u)||(d?c.get(e.lineageId):null)||null);let l=i==null&&e.kind===`edit`?`base`:e.kind;a={...t,type:`panel`,lineageId:e.lineageId,kind:l,prompt:l===`base`?String(e.scene||e.prompt||``):String(e.changePrompt||e.prompt||``).trim()||Pe(1),sourcePanelId:l===`base`?null:i,image:null,...n,overlayLayer:null,method:Oe.has(e.method)?e.method:null,methodGroup:e.methodGroup==null?null:String(e.methodGroup),...r,...Array.isArray(e.cast)?{cast:e.cast.map(String)}:{}},s.set(u,e.panelId),c.set(e.lineageId,e.panelId)}}u.push(a)}for(let e of u)e.type===`panel`&&!l[e.lineageId]&&(l[e.lineageId]={sheetIds:[],place:``});let d=Array.isArray(e.scenes)&&e.scenes.length?e.scenes.map(e=>({sceneId:String(e.sceneId),title:String(e.title||``),genre:Ae.includes(e.genre)?e.genre:null,styleBlock:e.styleBlock?String(e.styleBlock):null,styleRef:e.styleRef||null,...Ie(e.styleRefs).length?{styleRefs:Ie(e.styleRefs)}:{},sheets:{...e.sheets||{}},titleScreen:e.titleScreen&&typeof e.titleScreen==`object`?{...e.titleScreen}:null,...e.renderer===`diagram`?{renderer:`diagram`,canvas:e.canvas&&typeof e.canvas==`object`?{...e.canvas}:{},elements:Object.fromEntries(Object.entries(e.elements||{}).map(([e,t])=>[e,{prompt:String(t?.prompt||``),asset:t?.asset||null,pos:{x:Number(t?.pos?.x)||.5,y:Number(t?.pos?.y)||.5},scale:Number.isFinite(Number(t?.scale))?Number(t.scale):1}]))}:{}})):null,f={mode:`imagePanel`,...je.includes(e.projectType)?{projectType:e.projectType}:{},...e.projectTypeNote?{projectTypeNote:String(e.projectTypeNote).slice(0,500)}:{},meta:{title:n,aspect:r,styleRef:null,...e.sfxAuthored?{sfxAuthored:!0}:{}},audio:{voPath:i,words:t.map(e=>({text:String(e.text??e.word??``),...Fe(e)}))},styleBlock:String(e.styleBlock||``),sheets:{...e.sheets||{}},lineages:l,...d?{scenes:d}:{},strip:d?Re(u,d):u};for(let e of f.strip)if([`panel`,`diagram`].includes(e.type)&&e.provenance!==`user`&&e.durationMs>Ne(e))throw Error(`The assembled plan exceeds its method timing ceiling.`);return f}let Be=`panelId.type.sceneId.lineageId.kind.sourcePanelId.repeatOf.revealOf.revealIndex.method.methodGroup.wordStart.wordEnd.scene.prompt.changePrompt.transitionIn.background.autoArrange.mode.hint.template.gifQuery.tone.visibleElements.sfx.cast`.split(`.`);function Ve({plan:e,words:t,title:n=``,aspect:r=`16:9`,voPath:i=null}){I(L(e)&&Array.isArray(e.strip)&&e.strip.length>0&&e.strip.length<=2048&&Array.isArray(t)&&t.length>0&&t.length<=4e4,`PLAN_ASSEMBLY`,`The plan or narration exceeds this assembly boundary.`);let a=new Map,o=e=>{let t=`host-content-${a.size}`;return a.set(t,e),t},s=e=>(I(a.has(e),`PLAN_ASSEMBLY`,`An assembled media value has no captured source.`),a.get(e)),c=e=>Array.isArray(e)?e.filter(e=>typeof e==`string`&&e).map(o):typeof e==`string`&&e?o(e):[],l={};for(let t of[`projectType`,`projectTypeNote`,`sfxAuthored`,`styleBlock`])e[t]!==void 0&&(l[t]=e[t]);l.sheets=Object.fromEntries(Object.entries(e.sheets||{}).map(([e,t])=>[e,o(t)])),l.lineages=Object.fromEntries(Object.entries(e.lineages||{}).map(([e,t])=>[e,t&&{persistent:!!t.persistent,receipt:o(t)}])),l.strip=e.strip.map(e=>{I(L(e),`PLAN_ASSEMBLY`,`A planned row is invalid.`);let t={};for(let n of Be)e[n]!==void 0&&(t[n]=e[n]);e.gif!==void 0&&(t.gif=e.gif?o(String(e.gif)):``),Array.isArray(e.candidates)&&(t.candidates=e.candidates.map(e=>o(String(e))));for(let n of[`elements`,`events`,`textOverlays`])Array.isArray(e[n])&&(t[n]=e[n].map(o));return e.layout&&typeof e.layout==`object`&&(t.layout={receipt:o(e.layout)}),t}),Array.isArray(e.scenes)&&(l.scenes=e.scenes.map(e=>{I(L(e),`PLAN_ASSEMBLY`,`A planned scene is invalid.`);let t={};for(let n of[`sceneId`,`title`,`genre`,`styleBlock`,`renderer`])e[n]!==void 0&&(t[n]=e[n]);return t.styleRef=e.styleRef?o(e.styleRef):null,e.styleRefs!==void 0&&(t.styleRefs=c(e.styleRefs)),t.sheets=Object.fromEntries(Object.entries(e.sheets||{}).map(([e,t])=>[e,o(t)])),e.titleScreen&&typeof e.titleScreen==`object`&&(t.titleScreen={receipt:o({...e.titleScreen})}),e.renderer===`diagram`&&(t.canvas=e.canvas&&typeof e.canvas==`object`?{receipt:o({...e.canvas})}:{},t.elements=Object.fromEntries(Object.entries(e.elements||{}).map(([e,t])=>[e,{prompt:String(t?.prompt||``),asset:t?.asset?o(t.asset):null,pos:{x:Number(t?.pos?.x)||.5,y:Number(t?.pos?.y)||.5},scale:Number.isFinite(Number(t?.scale))?Number(t.scale):1}]))),t}));let u={plan:l,words:t.map(e=>({text:String(e.text??e.word??``),startMs:Math.round(Number(e.startMs??e.start*1e3)||0),endMs:Math.round(Number(e.endMs??e.end*1e3)||0)})),title:n,aspect:r,voPath:i==null?null:o(i)};return B(u),I(JSON.stringify(u).length<=2e6,`PLAN_ASSEMBLY`,`The plan is too large for sandbox assembly.`),{input:u,restore:s}}async function He(e,{signal:t,check:n,validateDocument:r,host:i}){let a=H(i),o=a.actor(),s=V(e),c=()=>{n(),I(!t?.aborted&&o&&a.actor()===o&&V(e)===s,`STALE`,`The account, plan or narration changed during assembly.`)};c();let{input:l,restore:u}=Ve(e),d=ze(l),f=e=>{typeof e==`number`?I(Number.isFinite(e),`PLAN_ASSEMBLY`,`The assembly returned a nonfinite value.`):e&&typeof e==`object`&&Object.values(e).forEach(f)};f(d);let p=JSON.parse(JSON.stringify(d));B(p);let m=await a.run(G,{kind:`run`,input:l,signal:t,timeoutMs:15e3});c(),B(m.outputs?.edit),I(V(m.outputs.edit)===V(p),`PLAN_ASSEMBLY`,`The sandbox changed the planned timing, source or content contract.`);let h={...d,audio:{...d.audio,voPath:d.audio.voPath?u(d.audio.voPath):null},sheets:Object.fromEntries(Object.entries(d.sheets).map(([e,t])=>[e,u(t)])),lineages:Object.fromEntries(Object.entries(d.lineages).map(([e,t])=>[e,t&&t===l.plan.lineages[e]?u(t.receipt):t])),strip:d.strip.map(e=>{let t={...e};t.type===`giphy`&&(t.gif&&=u(t.gif),t.candidates&&=t.candidates.map(u));for(let e of[`elements`,`events`,`textOverlays`])Array.isArray(t[e])&&(t[e]=t[e].map(u));return t.layout&&=u(t.layout.receipt),t})};d.scenes&&(h.scenes=d.scenes.map(e=>({...e,styleRef:e.styleRef?u(e.styleRef):null,...e.styleRefs?{styleRefs:e.styleRefs.map(u)}:{},sheets:Object.fromEntries(Object.entries(e.sheets).map(([e,t])=>[e,u(t)])),titleScreen:e.titleScreen?u(e.titleScreen.receipt):null,...e.renderer===`diagram`?{canvas:e.canvas.receipt?u(e.canvas.receipt):{},elements:Object.fromEntries(Object.entries(e.elements).map(([e,t])=>[e,{...t,asset:t.asset?u(t.asset):null}]))}:{}})));let g=r(h);return c(),g}let Ue={manifest:{schemaVersion:1,sdkVersion:`0.1.0`,id:`stillmade-internal.automatic-zoom`,version:`1.0.0`,name:`Automatic zoom pass`,description:`Choose pending source-backed zooms and prepare their exact existing or vision-fallback framing.`,kind:`task`,runtime:`javascript`,inputs:{operation:{type:`json`},data:{type:`json`}},outputs:{plan:{type:`json`}},permissions:{project:[],network:[],filesystem:[],secrets:[]}},code:`function automaticZoom(input){\n if(input.operation==='pending')return {pending:input.data.rows.filter(p=>p.type==='zoom'&&p.sourceReady&&(!p.hasTarget||!p.hasImage)).map(p=>p.origin)};\n const t=input.data.target;\n const zoom=input.data.reuse?t:{fx:Number.isFinite(Number(t?.fx))?Number(t.fx):50,fy:Number.isFinite(Number(t?.fy))?Number(t.fy):50,scale:Number.isFinite(Number(t?.scale))?Number(t.scale):1.8,pickedBy:'vision'};\n const {fx=50,fy=50,scale=1.8}=zoom;\n const s=Math.max(1.2,Math.min(3,Number(scale)||1.8)),ox=Math.max(0,Math.min(100,Number(fx)||0))/100,oy=Math.max(0,Math.min(100,Number(fy)||0))/100,w=1/s;\n return {zoom,rect:{x:ox*(1-w),y:oy*(1-w),w,h:w}};\n}\n\nreturn {plan:automaticZoom(input)};`,tests:[]},We=e=>e<0?0:e>1?1:e;function Ge(e,t){switch(t){case`linear`:return e;case`ease-in`:return e*e;case`ease-out`:return 1-(1-e)*(1-e);default:return e<.5?2*e*e:1-(-2*e+2)**2/2}}let Ke=e=>Math.max(38,Math.min(62,Number(e)||50));function qe(e,t,n,r,i,a,o=.4){let s=e=>a===`ST`?[r*(1-e)+e*t,i*(1-e)+e*n]:[50*(1-e)+t,50*(1-e)+n],c=e=>{let[t,n]=s(e),r=-100*(e-1);return t<=-o&&t>=r+o&&n<=-o&&n>=r+o},l=Math.max(1.02,Number(e)||1);for(let e=0;e<400&&!c(l);e++)l+=.005;return Math.min(3,Math.round(l*1e3)/1e3)}function Je(e){let t=e.type,n=(e.intensity||60)/100,r={scale:1,tx:0,ty:0,rot:0,blur:0,ox:50,oy:50};if(t===`pan`){let t=(e.panAmount||15)*n,i=e.panDirection||`left-right`,a=i===`left-right`?-t/2:i===`right-left`?t/2:0,o=i===`left-right`?t/2:i===`right-left`?-t/2:0,s=i===`up-down`?-t/2:i===`down-up`?t/2:0,c=i===`up-down`?t/2:i===`down-up`?-t/2:0,l=qe(1+t/100,Math.max(Math.abs(a),Math.abs(o)),Math.max(Math.abs(s),Math.abs(c)),50,50,`TS`);return[{...r,scale:l,tx:a,ty:s},{...r,scale:l,tx:o,ty:c}]}if(t===`zoom`){let t=1+((e.zoomAmount||1.15)-1)*n,[i,a]=Number.isFinite(e.zoomFocalX)&&Number.isFinite(e.zoomFocalY)?[Math.max(0,Math.min(100,e.zoomFocalX)),Math.max(0,Math.min(100,e.zoomFocalY))]:{center:[50,50],\"top-left\":[20,20],\"top-right\":[80,20],\"bottom-left\":[20,80],\"bottom-right\":[80,80]}[e.zoomAnchor||`center`]||[50,50],[o,s]=e.zoomDirection===`out`?[t,1]:[1,t];return[{...r,scale:o,ox:i,oy:a},{...r,scale:s,ox:i,oy:a}]}if(t===`ken-burns`){let t=Ke(e.kbStartX??50),i=Ke(e.kbStartY??50),a=Ke(e.kbEndX??60),o=Ke(e.kbEndY??40),s=e.kbStartScale||1,c=e.kbEndScale||1.2,l=qe(Math.max(1.06,1+(s-1)*n),50-t,50-i,t,i,`ST`),u=qe(Math.max(1.06,1+(c-1)*n),50-a,50-o,a,o,`ST`);return[{...r,scale:l,tx:50-t,ty:50-i,ox:t,oy:i},{...r,scale:u,tx:50-a,ty:50-o,ox:a,oy:o}]}if(t===`drift`){let t=(e.driftAngle||45)*Math.PI/180,i={barely:2,subtle:5,moderate:10}[e.driftSpeed||`subtle`]*n,a=Math.cos(t)*i,o=Math.sin(t)*i,s=1+(Math.abs(a)+Math.abs(o))/100*2+.04;return[{...r,scale:s,tx:0,ty:0},{...r,scale:s,tx:a,ty:o}]}if(t===`wobble`){let t=Math.max(.01,(e.wobbleAmount||8)/100*n),i={slow:1.5,normal:3,fast:6}[e.wobbleSpeed||`normal`]||3,a=Math.max(10,Math.round(i*8)),o=[];for(let e=0;e<=a;e++){let n=e/a;o.push({...r,offset:n,scale:1+t*(.5-.5*Math.cos(2*Math.PI*i*n))})}return o}if(t===`handheld`){let t=(e.handIntensity||50)/100*n*1.5,i=1+t/100*2+.03;return{slow:[0,25,50,75,100],normal:[0,16,33,50,66,83,100],fast:[0,10,20,30,40,50,60,70,80,90,100]}[e.handFrequency||`normal`].map(e=>({...r,offset:e/100,scale:i,tx:Math.sin(e*.37+1.1)*t,ty:Math.cos(e*.29+.7)*t}))}if(t===`impact-shake`){let t=(e.shakeIntensity||70)/100*n*2,i=1+t/100*2+.03;return e.shakeTrigger===`end`?[{...r,offset:0,scale:i},{...r,offset:.7,scale:i},{...r,offset:.75,scale:i,tx:t,ty:-t/2},{...r,offset:.8,scale:i,tx:-t,ty:t/2},{...r,offset:.85,scale:i,tx:t/2,ty:t},{...r,offset:.9,scale:i},{...r,offset:1,scale:i}]:[{...r,offset:0,scale:i,tx:t,ty:-t/2},{...r,offset:.05,scale:i,tx:-t,ty:t/2},{...r,offset:.1,scale:i,tx:t/2,ty:t},{...r,offset:.15,scale:i},{...r,offset:1,scale:i}]}if(t===`rotation-drift`){let t=(e.rotDegrees||3)*n*(e.rotDirection===`ccw`?-1:1),i=1+Math.abs(t)*.016;return[{...r,scale:i,rot:0},{...r,scale:i,rot:t}]}if(t===`focus-pull`){let t={subtle:4,moderate:10,strong:20}[e.focusAmount||`moderate`]*n;return e.focusDirection===`in`?[{...r,blur:t},{...r,blur:0}]:[{...r,blur:0},{...r,blur:t}]}return null}let Ye=(e,t,n)=>e+(t-e)*n;function Xe(e,t,n){if(!e||e.type===`none`)return null;let r=Je(e);if(!r||r.length<2)return r?r[0]:null;let i=e.loop?e.range||[0,100]:e.window||[0,100],a=i[0]/100*n,o=Math.max(1e-4,(i[1]-i[0])/100*n),s=We((t-a)/o);s=Ge(s,e.easing);let c=r.map((e,t)=>({...e,offset:e.offset??t/(r.length-1)})),l=c[0],u=c[c.length-1];for(let e=0;e<c.length-1;e++)if(s>=c[e].offset&&s<=c[e+1].offset){l=c[e],u=c[e+1];break}let d=u.offset-l.offset,f=d<=0?0:(s-l.offset)/d;return{scale:Ye(l.scale,u.scale,f),tx:Ye(l.tx,u.tx,f),ty:Ye(l.ty,u.ty,f),rot:Ye(l.rot,u.rot,f),blur:Ye(l.blur,u.blur,f),ox:Ye(l.ox,u.ox,f),oy:Ye(l.oy,u.oy,f)}}function Ze(e,t,n,r,i){let a=e.createLinearGradient(0,0,0,n);a.addColorStop(0,r),a.addColorStop(1,i),e.fillStyle=a,e.fillRect(0,0,t,n)}function K(e){let t=Math.sin(e*127.1+311.7)*43758.5453;return t-Math.floor(t)}function Qe(e){let t=/^#?([0-9a-f]{6})$/i.exec(String(e||``).trim());if(!t)return null;let n=parseInt(t[1],16);return{r:n>>16&255,g:n>>8&255,b:n&255}}function $e(e,t,n){let r=Qe(e),i=Qe(t);if(!r||!i)return e;let a=e=>Math.round(r[e]+(i[e]-r[e])*n);return`rgb(${a(`r`)},${a(`g`)},${a(`b`)})`}function et(e,t){let n=Qe(e);return n?`rgba(${n.r},${n.g},${n.b},${t})`:`rgba(0,0,0,${t})`}let tt=e=>Array.isArray(e)&&e.length>0;function nt(e,t,n,r,i){let a,o,s,c,l;if(tt(i)){let e=i[0]||ct[0],t=i[1]||ct[1];a=e,o=$e(e,t,.4),s=et(t,.28),c=et(t,.35),l=et(t,0)}else a=`#0a1a3f`,o=`#123a8a`,s=`rgba(120,170,255,0.28)`,c=`rgba(80,140,255,0.35)`,l=`rgba(80,140,255,0)`;Ze(e,t,n,a,o);let u=Math.max(28,Math.min(t,n)*.09),d=r*u*.35%u;e.lineWidth=Math.max(1,Math.min(t,n)*.0022),e.strokeStyle=s,e.beginPath();for(let r=-u+d%u;r<=t+u;r+=u)e.moveTo(r,0),e.lineTo(r,n);for(let r=-u+d;r<=n+u;r+=u)e.moveTo(0,r),e.lineTo(t,r);e.stroke();let f=e.createRadialGradient(t/2,n*.45,0,t/2,n*.45,Math.max(t,n)*.6);f.addColorStop(0,c),f.addColorStop(1,l),e.fillStyle=f,e.fillRect(0,0,t,n)}function rt(e,t,n,r){Ze(e,t,n,`#050716`,`#0b1030`);let i=[{c:`rgba(90,220,200,0.55)`,fx:.07,fy:.05,px:.3,py:.35,r:.55},{c:`rgba(140,90,240,0.5)`,fx:.05,fy:.08,px:.7,py:.5,r:.6},{c:`rgba(60,140,255,0.5)`,fx:.09,fy:.06,px:.5,py:.7,r:.5},{c:`rgba(240,120,190,0.4)`,fx:.06,fy:.09,px:.4,py:.2,r:.45}];e.globalCompositeOperation=`lighter`;for(let a=0;a<i.length;a++){let o=i[a],s=t*(o.px+.18*Math.sin(r*o.fx*Math.PI*2+a)),c=n*(o.py+.16*Math.cos(r*o.fy*Math.PI*2+a*1.7)),l=Math.max(t,n)*o.r,u=e.createRadialGradient(s,c,0,s,c,l);u.addColorStop(0,o.c),u.addColorStop(1,`rgba(0,0,0,0)`),e.fillStyle=u,e.fillRect(0,0,t,n)}e.globalCompositeOperation=`source-over`}function it(e,t,n,r){Ze(e,t,n,`#1a1130`,`#2a0f3a`);let i=[{c:`rgba(255,120,80,0.55)`,bx:.25,by:.3},{c:`rgba(255,80,160,0.5)`,bx:.75,by:.28},{c:`rgba(120,90,255,0.5)`,bx:.7,by:.75},{c:`rgba(80,200,255,0.45)`,bx:.28,by:.72}];e.globalCompositeOperation=`lighter`;for(let a=0;a<i.length;a++){let o=i[a],s=t*(o.bx+.1*Math.sin(r*.15*Math.PI+a*1.3)),c=n*(o.by+.1*Math.cos(r*.13*Math.PI+a*.9)),l=Math.max(t,n)*(.5+.06*Math.sin(r*.2+a)),u=e.createRadialGradient(s,c,0,s,c,l);u.addColorStop(0,o.c),u.addColorStop(1,`rgba(0,0,0,0)`),e.fillStyle=u,e.fillRect(0,0,t,n)}e.globalCompositeOperation=`source-over`}function at(e,t,n,r,i){let a;if(tt(i)){let r=i[0]||lt[0],o=i[1]||lt[1];Ze(e,t,n,r,$e(r,o,.18)),a=e=>et(o,e)}else Ze(e,t,n,`#0b1226`,`#152244`),a=e=>`rgba(150,190,255,${e})`;let o=n*1.25;e.globalCompositeOperation=`lighter`;for(let i=0;i<46;i++){let s=.4+K(i)*.9,c=(.01+K(i+99)*.04)*Math.min(t,n),l=(K(i+7)+.05*Math.sin(r*.3+i))*t,u=n+c-(r*s*n*.06+K(i+31)*o)%o,d=.15+K(i+53)*.4,f=e.createRadialGradient(l,u,0,l,u,c);f.addColorStop(0,a(d)),f.addColorStop(1,a(0)),e.fillStyle=f,e.beginPath(),e.arc(l,u,c,0,Math.PI*2),e.fill()}e.globalCompositeOperation=`source-over`}function ot(e,t,n,r){Ze(e,t,n,`#04122a`,`#0a2e4a`);for(let i of[{c:`rgba(30,140,200,0.5)`,amp:.05,base:.62,k:1.3,spd:.5},{c:`rgba(40,190,180,0.5)`,amp:.06,base:.72,k:1,spd:-.7},{c:`rgba(80,110,230,0.55)`,amp:.07,base:.82,k:.8,spd:.9}]){e.beginPath(),e.moveTo(0,n);let a=Math.max(6,t/120);for(let o=0;o<=t;o+=a){let a=o/t*Math.PI*2*i.k+r*i.spd,s=n*i.base+Math.sin(a)*n*i.amp;e.lineTo(o,s)}e.lineTo(t,n),e.closePath(),e.fillStyle=i.c,e.fill()}}function st(e,t,n,r,i){let a=tt(i),o=a?i[0]||ut[0]:`#e8e4da`,s=a?i[1]||ut[1]:`#57503f`,c=Math.floor(Math.max(0,Number(r)||0)/.17)%8*977,l=Math.min(t,n)/360;Ze(e,t,n,o,$e(o,s,.08));let u=e.createRadialGradient(t/2,n/2,Math.min(t,n)*.35,t/2,n/2,Math.max(t,n)*.75);u.addColorStop(0,et(s,0)),u.addColorStop(1,et(s,.1)),e.fillStyle=u,e.fillRect(0,0,t,n);for(let r=0;r<6;r++){let i=K(c+11+r)*t,a=K(c+23+r)*n,o=Math.max(t,n)*(.1+.16*K(c+37+r)),l=e.createRadialGradient(i,a,0,i,a,o);l.addColorStop(0,et(s,.055)),l.addColorStop(1,et(s,0)),e.fillStyle=l,e.fillRect(0,0,t,n)}let d=Math.max(24,Math.min(t,n)*.075),f=(K(c+3)-.5)*3*l,p=(K(c+4)-.5)*3*l;e.lineWidth=Math.max(1,l*1.1),e.strokeStyle=et(s,.16),e.beginPath();for(let r=-d+f;r<=t+d;r+=d)e.moveTo(r,0),e.lineTo(r,n);for(let r=-d+p;r<=n+d;r+=d)e.moveTo(0,r),e.lineTo(t,r);e.stroke(),e.fillStyle=et(s,.5);for(let r=0;r<42;r++){let i=K(c+101+r)*t,a=K(c+211+r)*n,o=(.8+1.8*K(c+307+r))*l;e.globalAlpha=.22+.38*K(c+401+r),e.fillRect(i,a,o,o)}e.strokeStyle=et(s,.3),e.lineWidth=Math.max(.6,l*.7);for(let r=0;r<14;r++){let i=K(c+503+r)*t,a=K(c+601+r)*n,o=K(c+701+r)*Math.PI*2,s=(4+6*K(c+809+r))*l;e.globalAlpha=.15+.2*K(c+907+r),e.beginPath(),e.moveTo(i,a),e.lineTo(i+Math.cos(o)*s,a+Math.sin(o)*s),e.stroke()}for(let r=0;r<160;r++){let i=K(c+1103+r)*t,a=K(c+1301+r)*n,o=r%2==0;e.fillStyle=o?et(s,1):`#ffffff`,e.globalAlpha=o?.04+.05*K(c+1409+r):.05+.07*K(c+1511+r),e.fillRect(i,a,l,l)}e.globalAlpha=1}let ct=[`#0a1a3f`,`#3b7dff`],lt=[`#0b1226`,`#96beff`],ut=[`#e8e4da`,`#57503f`],dt={grid:{label:`Blue Grid`,draw:nt,css:`linear-gradient(180deg, #0a1a3f, #123a8a)`,tunable:[{key:`base`,label:`Background`,default:ct[0]},{key:`accent`,label:`Grid & glow`,default:ct[1]}]},aurora:{label:`Aurora`,draw:rt,css:`radial-gradient(circle at 35% 40%, rgba(90,220,200,0.7), rgba(140,90,240,0.5) 45%, #0b1030 80%)`},mesh:{label:`Mesh`,draw:it,css:`radial-gradient(circle at 30% 30%, rgba(255,120,80,0.7), rgba(120,90,255,0.5) 55%, #2a0f3a 85%)`},bokeh:{label:`Bokeh`,draw:at,css:`radial-gradient(circle at 60% 70%, rgba(150,190,255,0.5), #152244 70%)`,tunable:[{key:`base`,label:`Background`,default:lt[0]},{key:`accent`,label:`Dots`,default:lt[1]}]},waves:{label:`Waves`,draw:ot,css:`linear-gradient(180deg, #0a2e4a 40%, rgba(40,190,180,0.6) 70%, #04122a)`},paper:{label:`Paper`,draw:st,css:`linear-gradient(180deg, #e8e4da, #ded9cd)`,tunable:[{key:`base`,label:`Paper`,default:ut[0]},{key:`accent`,label:`Grid & flecks`,default:ut[1]}]}};function ft(e){if(typeof e!=`string`||!e.startsWith(`anim|`))return null;let[,t,...n]=e.split(`|`);return dt[t]?{key:t,colors:n}:null}function pt(e){return ft(e)!=null}function mt(e){let t=ft(e);return t&&dt[t.key].tunable||null}function ht(e,t){let n=ft(e),r=n&&dt[n.key].tunable;return!r||!r[t]?null:n.colors[t]||r[t].default}function gt(e,t,n){let r=ft(e),i=r&&dt[r.key].tunable;if(!i)return e;let a=i.map((e,i)=>i===t?n:r.colors[i]||e.default);return`anim|${r.key}|${a.join(`|`)}`}function _t(e){let t=ft(e);if(!t)return null;let n=dt[t.key];return n.tunable&&t.colors.length?`linear-gradient(180deg, ${t.colors[0]||n.tunable[0].default}, ${t.colors[1]||n.tunable[1].default})`:n.css}function vt(e,t,n,r,i){let a=ft(t);return a?(dt[a.key].draw(e,n,r,Number(i)||0,a.colors),!0):!1}let yt=[`pop`,`fade`,`rise`,`scale`],bt=[`pop`,`fade`,`rise`,`typewriter`,`pop-word`,`scale`];function xt(e,t,n,r,i){let a=typeof t==`string`?t:``;if(!vt(e,a,n,r,(Number(i)||0)/1e3)){if(a.startsWith(`radial|`)||a.startsWith(`linear|`)){let t=a.split(`|`),i;if(t[0]===`radial`){let a=t.slice(1);i=e.createRadialGradient(n/2,r*.42,Math.min(n,r)*.05,n/2,r*.5,Math.max(n,r)*.72),St(i,a)}else{let a=Number(t[1])||90,o=t.slice(2),s=(a-90)*Math.PI/180,c=Math.max(n,r)/2,l=Math.cos(s)*c,u=Math.sin(s)*c;i=e.createLinearGradient(n/2-l,r/2-u,n/2+l,r/2+u),St(i,o)}e.fillStyle=i}else e.fillStyle=a||`#ffffff`;e.fillRect(0,0,n,r)}}function St(e,t){let n=t.length;t.forEach((t,r)=>e.addColorStop(n===1?0:r/(n-1),t))}function Ct(e){if(typeof e!=`string`||!e)return`#ffffff`;if(pt(e))return _t(e);if(e.startsWith(`radial|`)){let[,...t]=e.split(`|`);return`radial-gradient(circle at 50% 42%, ${t.join(`, `)})`}if(e.startsWith(`linear|`)){let[,t,...n]=e.split(`|`);return`linear-gradient(${Number(t)||90}deg, ${n.join(`, `)})`}return e}let wt=[{key:`white`,label:`White`,value:`#ffffff`},{key:`black`,label:`Black`,value:`#0a0a0a`},{key:`studio`,label:`Studio`,value:`radial|#f4f4f4|#8d8d8d`},{key:`spotlight`,label:`Spotlight`,value:`radial|#ffffff|#c9c9c9`},{key:`charcoal`,label:`Charcoal`,value:`radial|#3a3a3a|#0c0c0c`},{key:`midnight`,label:`Midnight`,value:`radial|#1b2a44|#070b14`},{key:`ocean`,label:`Ocean`,value:`linear|135|#1e3a5f|#0a1a2f`},{key:`sunset`,label:`Sunset`,value:`linear|135|#f7b267|#c0392b`},...Object.entries(dt).map(([e,t])=>({key:`anim-${e}`,label:t.label,value:`anim|${e}`,animated:!0}))],Tt=e=>{let t=5381,n=String(e||``);for(let e=0;e<n.length;e++)t=(t<<5)+t+n.charCodeAt(e)>>>0;return t},Et=(e,t)=>Tt(`${e}|${t}`)%2e3/1e3-1;function Dt(e,t=16/9){let n=.08+.4*Math.sqrt((e+.5)/48),r=e*2.399963229728653;return{x:.5+n*Math.cos(r),y:.5+n*Math.sin(r)*(t>1?.9:1.1)}}let Ot=(e,t,n)=>Math.max(t,Math.min(n,e));function kt(e,{aspect:t=16/9}={}){let n=(e?.elements||[]).slice().sort((e,t)=>(e.appearMs||0)-(t.appearMs||0)),r=[],i=new Map;for(let a of n){let n=(a.kind===`image`?a.size||.28:.18)/2;if(a.pinned||!e.autoArrange){a.pos&&(r.push({...a.pos,size:a.size||.28,appearMs:a.appearMs,leaveMs:a.leaveMs}),i.set(a.id,a.pos));continue}let o=r.filter(e=>e.leaveMs==null||e.leaveMs>a.appearMs),s=null,c=-1/0;for(let e=0;e<48;e++){let r=Dt((e+Tt(a.id)%48)%48,t),i=Ot(r.x,n+.03,1-n-.03),l=Ot(r.y,n+.05,1-n-.05),u=1/0;for(let e of o)u=Math.min(u,Math.hypot(i-e.x,l-e.y)-(e.size||.28)/2-n);let d=-.12*Math.hypot(i-.5,l-.5),f=(o.length?Math.min(u,.5):.3)+d;f>c&&(c=f,s={x:i,y:l})}let l=s||{x:.5,y:.5};l.x=Ot(l.x+Et(a.id,`x`)*.015,n,1-n),l.y=Ot(l.y+Et(a.id,`y`)*.015,n,1-n),r.push({...l,size:a.size||.28,appearMs:a.appearMs,leaveMs:a.leaveMs}),i.set(a.id,l)}return i}function At(e,t){if(!e.autoArrange)return e;let n=kt(e,t);return{...e,elements:(e.elements||[]).map(e=>!e.pinned&&n.has(e.id)?{...e,pos:n.get(e.id)}:e)}}function jt(e){let t=Number(e?.videoWidth||e?.width||e?.naturalWidth||e?.displayWidth)||0,n=Number(e?.videoHeight||e?.height||e?.naturalHeight||e?.displayHeight)||0;return{w:Math.max(1,t),h:Math.max(1,n)}}function Mt(e,t){let n=Math.max(0,(t-(e.appearMs||0))/1e3),r=Number(e.speed)>0?Number(e.speed):1,i=Math.max(0,Number(e.trimStartSec)||0),a=i+n*r,o=Number(e.durationSec)||0;if(o>0){let t=Math.max(.05,o-i);a=e.loop===!1?Math.min(a,o-.05):i+(a-i)%t}return a}let Nt=[`word-pop`,`sentence-build`,`line`,`typewriter`,`highlight`],Pt=[`pop`,`fade`,`slide`,`rise`,`scale`];function Ft(e,t){if(Array.isArray(e.wordTimes)&&Number.isFinite(Number(e.wordTimes[t])))return Number(e.wordTimes[t]);let n=e.anim?.speedMs||180;return(e.appearMs||0)+t*n}function It(e,t){return String(e.text||``).split(/\\s+/).filter(Boolean).map((n,r)=>{let i=Ft(e,r),a=t-i;return{text:n,start:i,local:a,p:Ot(a/320,0,1),spoken:a>=0}})}function Lt(e,t){let n=It(e,t),r=0;for(let t=0;t<n.length;t++){let i=n[t];if(!i.spoken)break;let a=t+1<n.length?Math.max(40,n[t+1].start-i.start):(e.anim?.speedMs||180)*2,o=Ot(i.local/a,0,1);r+=Math.round(o*(i.text.length+1))}return r}function Rt(e,t,n){if(!e.motion||e.motion.type===`none`||t<(e.appearMs||0))return null;let r=e.leaveMs==null?n||0:e.leaveMs,i=Math.max(.1,(r-(e.appearMs||0))/1e3),a=(t-(e.appearMs||0))/1e3;return Xe(e.motion,a,i)}function zt(e,t,n){return e+(t-e)*n}function Bt(e,t){let n=Math.max(0,Math.min(1,e));return t===`linear`?n:t===`ease-in`?n*n:t===`ease-out`?1-(1-n)*(1-n):n<.5?2*n*n:1-(-2*n+2)**2/2}function Vt(e,t){let n={x:e.pos?.x??.5,y:e.pos?.y??.5,size:e.size},r=Array.isArray(e.moves)?e.moves.filter(e=>e&&typeof e==`object`).slice().sort((e,t)=>(e.atMs||0)-(t.atMs||0)):[],i=n;for(let e=0;e<r.length;e++){let n=r[e],a=Number(n.atMs)||0;if(t<a)break;let o=Number(n.durMs),s=Number.isFinite(o)&&o>=0?o:500,c=e+1<r.length?Number(r[e+1].atMs)||0:1/0,l=Math.max(0,Math.min(s,c-a)),u={x:n.pos?.x==null?i.x:n.pos.x,y:n.pos?.y==null?i.y:n.pos.y,size:n.size==null?i.size:n.size};if(l<=0||t>=a+l){i=u;continue}let d=Bt((t-a)/l,n.ease);return{pos:{x:zt(i.x,u.x,d),y:zt(i.y,u.y,d)},size:i.size!=null&&u.size!=null?zt(i.size,u.size,d):u.size??i.size}}return{pos:{x:i.x,y:i.y},size:i.size}}function Ht(e,t,n){let r=t.shadow==null?.18:Math.max(0,Math.min(1,Number(t.shadow)));if(r<=.001){e.shadowColor=`transparent`,e.shadowBlur=0,e.shadowOffsetY=0;return}e.shadowColor=`rgba(0,0,0,${r})`,e.shadowBlur=n*(.03+r*.14),e.shadowOffsetY=n*(.008+r*.05)}function Ut(e,t,n,r,i){if(!e)return null;let a=e.pos||{x:.5,y:.5},o=a.x*t,s=a.y*n,c,l;if(e.kind===`image`||e.kind===`video`){if(e.box)c=Math.max(1,e.box.w*t),l=Math.max(1,e.box.h*n);else{c=(e.size||.28)*t;let n=e.src?r?.(e.src,e):e.poster?r?.(e.poster,e):null;if(n){let e=jt(n);l=c*(e.h/e.w)}else l=c*.66}}else{let t=Math.max(10,(e.size||.07)*n);i?(i.font=`${e.weight||700} ${t}px ${e.font||`Hanken Grotesk`}, Arial, sans-serif`,c=Math.max(24,i.measureText(String(e.text||` `)).width)):c=Math.max(24,String(e.text||` `).length*t*.55),l=t*1.3}return{cx:o,cy:s,w:c,h:l,rot:Number(e.tilt)||0}}function Wt({dir:e,dx:t,dy:n,wpx:r,hpx:i,rotRad:a=0,stageW:o,stageH:s}){let c=Math.cos(a),l=Math.sin(a),u=t*c+n*l,d=-t*l+n*c,f=r,p=i;e===`e`?f=r+2*u:e===`w`?f=r-2*u:e===`s`?p=i+2*d:e===`n`&&(p=i-2*d);let m=e=>Math.max(.05,Math.min(1,e));return{w:m(f/o),h:m(p/s)}}function Gt(e,t){return(e?.elements||[]).filter(e=>t>=(e.appearMs||0)&&(e.leaveMs==null||t<e.leaveMs))}function Kt(e,t,n=`pop`){let r=t-(e.appearMs||0),i=Ot(r/320,0,1),a=1-(1-i)*(1-i);switch(e.kind===`text`?e.anim?.type||`pop`:e.entrance||n||`pop`){case`fade`:return{alpha:a,scale:1,dy:0,p:i};case`rise`:return{alpha:a,scale:1,dy:(1-a)*.06,p:i};case`scale`:return{alpha:1,scale:.4+.6*a,dy:0,p:i};case`typewriter`:case`pop-word`:case`word-pop`:case`sentence-build`:case`highlight`:return{alpha:1,scale:1,dy:0,p:i};case`line`:{let e=i<.7?i/.7*1.12:1.12-.12*((i-.7)/.3);return{alpha:Math.min(1,i*2.5),scale:e,dy:0,p:i}}default:{let e=i<.7?i/.7*1.12:1.12-.12*((i-.7)/.3);return{alpha:Math.min(1,i*2.5),scale:e,dy:0,p:i}}}}function qt(e){let t=Number(e?.durationMs)||0,n=new Set([0]);for(let r of e?.elements||[])n.add(Ot(Number(r.appearMs)||0,0,t)),r.leaveMs!=null&&n.add(Ot(Number(r.leaveMs),0,t));let r=[...n].sort((e,t)=>e-t);r.push(t);let i=[];for(let e=1;e<r.length;e++)r[e]-r[e-1]>2600&&i.push({fromMs:r[e-1],toMs:r[e]});return i}function Jt(e){let t=(e?.elements||[]).slice().sort((e,t)=>(e.appearMs||0)-(t.appearMs||0)),n=[],r=0,i=Number(e?.durationMs)||1/0;for(let e=0;e<t.length;e++){let a=t[e];if(a.sfx===`none`||(a.appearMs||0)>=i)continue;if(a.kind===`text`&&a.anim?.type===`typewriter`&&Array.isArray(a.wordTimes)&&a.wordTimes.length){let e=a.wordTimes.map(Number).filter(e=>Number.isFinite(e)&&e<i).sort((e,t)=>e-t);for(let t=0;t<e.length;t++){let r=t+1<e.length?e[t+1]:null;n.push({elementId:`${a.id}:k${t}`,atMs:e[t],kind:`type`,variant:0,beatMs:r==null?null:Math.max(40,r-e[t]),volume:Number.isFinite(Number(a.sfxVolume))?Number(a.sfxVolume):void 0})}continue}let o=(a.kind===`image`||a.kind===`video`)&&(a.box?a.box.w*a.box.h>=.22:(a.size||.28)>=.42),s=a.sfx===`pop`||a.sfx===`swoosh`?a.sfx:o?`swoosh`:`pop`,c=t[e+1];n.push({elementId:a.id,atMs:a.appearMs||0,kind:s,variant:s===`pop`?r++:0,beatMs:c?Math.max(50,(c.appearMs||0)-(a.appearMs||0)):null,volume:Number.isFinite(Number(a.sfxVolume))?Number(a.sfxVolume):void 0})}return n}function Yt(e,t,n){return!Array.isArray(e)||!(n>t)?[]:e.filter(e=>e.atMs>t&&e.atMs<=n)}function Xt(e,t,n,r,i,a){e.save(),xt(e,t.background,i,a,n);let o=t.handoff?.arrive===`fade`?`fade`:`pop`;for(let s of Gt(t,n)){let c=Kt(s,n,o),l=Vt(s,n),u=l.pos,d=l.size==null?s.size:l.size,f=u.x*i,p=(u.y+(c.dy||0))*a;e.save(),e.globalAlpha=c.alpha,e.translate(f,p);let m=Rt(s,n,t.durationMs);if(m&&(e.translate(m.tx/100*i,m.ty/100*a),m.rot&&e.rotate(m.rot*Math.PI/180),m.scale!==1&&e.scale(m.scale,m.scale),m.blur>.01&&(e.filter=`blur(${(m.blur*(a/1080)).toFixed(2)}px)`)),s.tilt&&e.rotate(s.tilt*Math.PI/180),c.scale!==1&&e.scale(c.scale,c.scale),s.kind===`image`||s.kind===`video`){let t=s.src?r(s.src,s):null;!t&&s.kind===`video`&&s.poster&&(t=r(s.poster,s));let n=(d||.28)*i,o=s.box?Math.max(1,s.box.h*a):null,c=s.box?Math.max(1,s.box.w*i):null;if(t&&c){let{w:n,h:r}=jt(t),i=Math.max(c/n,o/r),a=c/i,l=o/i,u=(n-a)/2,d=(r-l)/2;Ht(e,s,c),s.cutout||(e.fillStyle=`#fff`,e.fillRect(-c/2-c*.02,-o/2-c*.02,c+c*.04,o+c*.04),e.shadowColor=`transparent`),e.drawImage(t,u,d,a,l,-c/2,-o/2,c,o),s.cutout&&(e.shadowColor=`transparent`)}else if(t){let{w:r,h:i}=jt(t),a=i/r*n;Ht(e,s,n),s.cutout||(e.fillStyle=`#fff`,e.fillRect(-n/2-n*.02,-a/2-n*.02,n+n*.04,a+n*.04),e.shadowColor=`transparent`),e.drawImage(t,-n/2,-a/2,n,a),s.cutout&&(e.shadowColor=`transparent`)}else{let t=c||n,r=o||n*.66;e.strokeStyle=`rgba(0,0,0,0.25)`,e.setLineDash([6,5]),e.lineWidth=2,e.strokeRect(-t/2,-r/2,t,r),e.setLineDash([]),e.fillStyle=`rgba(0,0,0,0.4)`,e.font=`${Math.round(a*.028)}px Hanken Grotesk, Arial, sans-serif`,e.textAlign=`center`,e.textBaseline=`middle`,e.fillText(String(s.query||(s.kind===`video`?`video`:`image`)).slice(0,28),0,0)}}else{let t=Math.max(10,(d||.07)*a);e.font=`${s.weight||700} ${t}px ${s.font||`Hanken Grotesk`}, Arial, sans-serif`,e.fillStyle=s.color||`#111111`,e.textAlign=`center`,e.textBaseline=`middle`;let r=s.anim?.type||`pop`,i=String(s.text||``);if(r===`typewriter`){if(Array.isArray(s.wordTimes)&&s.wordTimes.length){let t=Lt(s,n);e.fillText(i.slice(0,t),0,0)}else{let t=s.anim?.speedMs||45,r=Math.max(0,Math.floor((n-(s.appearMs||0))/t));e.fillText(i.slice(0,r),0,0)}}else if(r===`pop-word`||r===`word-pop`||r===`sentence-build`||r===`highlight`){let i=It(s,n),a=i.map(t=>e.measureText(`${t.text} `).width),o=-a.reduce((e,t)=>e+t,0)/2,l=s.anim?.entrance||`pop`;for(let n=0;n<i.length;n++){let s=i[n];if(r===`highlight`)e.save(),e.translate(o+a[n]/2,0),e.globalAlpha=c.alpha*(s.spoken?1:.3),e.fillText(s.text,0,0),e.restore();else if(s.spoken){let i=s.p;e.save();let u=1,d=0,f=0,p=Math.min(1,i*2.5);if(r===`sentence-build`){let e=1-(1-i)*(1-i);l===`fade`?p=e:l===`slide`?(d=(1-e)*-t*.8,p=e):l===`rise`?(f=(1-e)*t*.6,p=e):l===`scale`?(u=.4+.6*e,p=1):u=i<.7?i/.7*1.12:1.12-.12*((i-.7)/.3)}else u=i<.7?i/.7*1.12:1.12-.12*((i-.7)/.3);e.translate(o+a[n]/2+d,f),e.scale(u,u),e.globalAlpha=c.alpha*p,e.fillText(s.text,0,0),e.restore()}o+=a[n]}}else e.fillText(i,0,0)}e.restore()}e.restore()}let Zt=(e,t,n,r,i,a,o,s)=>({id:e,name:t,scenario:n,minImages:r,slots:i,textSlots:a,pSlots:o,pTextSlots:s}),Qt=[Zt(`hero-headline`,`Hero + headline`,`one subject, one line`,1,[{x:.5,y:.58,w:.5,h:.62}],[{role:`headline`,x:.5,y:.14,size:.09,weight:900}],[{x:.5,y:.55,w:.78,h:.5}],[{role:`headline`,x:.5,y:.13,size:.055,weight:900}]),Zt(`hero-supporting`,`Hero + 2 supporting`,`main subject with two details`,3,[{x:.34,y:.55,w:.42,h:.58},{x:.78,y:.33,w:.28,h:.32},{x:.78,y:.73,w:.28,h:.32}],[{role:`headline`,x:.34,y:.13,size:.08,weight:900}],[{x:.5,y:.38,w:.78,h:.32},{x:.28,y:.72,w:.4,h:.2},{x:.72,y:.72,w:.4,h:.2}],[{role:`headline`,x:.5,y:.12,size:.05,weight:900}]),Zt(`compare-2`,`Side-by-side compare`,`A vs B`,2,[{x:.27,y:.5,w:.38,h:.5},{x:.73,y:.5,w:.38,h:.5}],[{role:`headline`,x:.5,y:.12,size:.08,weight:900},{role:`label`,x:.27,y:.84,size:.05,weight:800},{role:`label`,x:.73,y:.84,size:.05,weight:800}],[{x:.5,y:.35,w:.72,h:.24},{x:.5,y:.72,w:.72,h:.24}],[{role:`headline`,x:.5,y:.11,size:.05,weight:900},{role:`label`,x:.5,y:.51,size:.032,weight:800},{role:`label`,x:.5,y:.88,size:.032,weight:800}]),Zt(`three-across`,`Three across`,`three items`,3,[{x:.2,y:.5,w:.26,h:.46},{x:.5,y:.5,w:.26,h:.46},{x:.8,y:.5,w:.26,h:.46}],[{role:`headline`,x:.5,y:.13,size:.08,weight:900},{role:`caption`,x:.5,y:.86,size:.045,weight:600}],[{x:.5,y:.32,w:.64,h:.2},{x:.5,y:.57,w:.64,h:.2},{x:.5,y:.82,w:.64,h:.2}],[{role:`headline`,x:.5,y:.1,size:.05,weight:900},{role:`caption`,x:.5,y:.96,size:.028,weight:600}]),Zt(`grid-2x2`,`Grid of four`,`four items`,4,[{x:.3,y:.36,w:.32,h:.34},{x:.7,y:.36,w:.32,h:.34},{x:.3,y:.74,w:.32,h:.34},{x:.7,y:.74,w:.32,h:.34}],[{role:`headline`,x:.5,y:.09,size:.07,weight:900}],[{x:.28,y:.38,w:.4,h:.24},{x:.72,y:.38,w:.4,h:.24},{x:.28,y:.68,w:.4,h:.24},{x:.72,y:.68,w:.4,h:.24}],[{role:`headline`,x:.5,y:.12,size:.05,weight:900}]),Zt(`grid-3x3`,`Many small (3x3)`,`lots of items`,6,[.22,.5,.78].flatMap(e=>[.3,.56,.82].map(t=>({x:e,y:t,w:.24,h:.22}))),[{role:`headline`,x:.5,y:.08,size:.065,weight:900}],[.2,.5,.8].flatMap(e=>[.34,.58,.82].map(t=>({x:e,y:t,w:.27,h:.18}))),[{role:`headline`,x:.5,y:.1,size:.045,weight:900}]),Zt(`big-left-stack-right`,`Big lead + stack`,`one lead, several follow-ups`,3,[{x:.32,y:.54,w:.5,h:.62},{x:.79,y:.3,w:.3,h:.22},{x:.79,y:.56,w:.3,h:.22},{x:.79,y:.82,w:.3,h:.22}],[{role:`headline`,x:.32,y:.13,size:.075,weight:900}],[{x:.5,y:.4,w:.84,h:.34},{x:.2,y:.74,w:.26,h:.16},{x:.5,y:.74,w:.26,h:.16},{x:.8,y:.74,w:.26,h:.16}],[{role:`headline`,x:.5,y:.12,size:.05,weight:900}]),Zt(`vertical-stack`,`Vertical stack`,`ordered top to bottom`,2,[{x:.55,y:.29,w:.36,h:.22},{x:.55,y:.55,w:.36,h:.22},{x:.55,y:.81,w:.36,h:.22}],[{role:`headline`,x:.55,y:.08,size:.065,weight:900},{role:`label`,x:.16,y:.55,size:.055,weight:800}],[{x:.5,y:.3,w:.66,h:.2},{x:.5,y:.56,w:.66,h:.2},{x:.5,y:.82,w:.66,h:.2}],[{role:`headline`,x:.5,y:.09,size:.05,weight:900},{role:`label`,x:.24,y:.17,size:.032,weight:800}]),Zt(`scatter`,`Scattered collage`,`loose, hand-thrown feel`,3,[{x:.26,y:.36,w:.28,h:.32,tilt:-6},{x:.68,y:.3,w:.26,h:.3,tilt:4},{x:.44,y:.66,w:.27,h:.31,tilt:3},{x:.8,y:.62,w:.25,h:.29,tilt:-5},{x:.58,y:.46,w:.24,h:.28,tilt:2}],[{role:`headline`,x:.5,y:.1,size:.075,weight:900}],[{x:.32,y:.3,w:.46,h:.2,tilt:-6},{x:.7,y:.26,w:.42,h:.18,tilt:4},{x:.4,y:.56,w:.44,h:.2,tilt:3},{x:.74,y:.6,w:.4,h:.18,tilt:-5},{x:.5,y:.82,w:.44,h:.19,tilt:2}],[{role:`headline`,x:.5,y:.09,size:.045,weight:900}]),Zt(`timeline-row`,`Row / timeline`,`steps in order`,3,[{x:.14,y:.52,w:.2,h:.38},{x:.38,y:.52,w:.2,h:.38},{x:.62,y:.52,w:.2,h:.38},{x:.86,y:.52,w:.2,h:.38}],[{role:`headline`,x:.5,y:.15,size:.075,weight:900},{role:`caption`,x:.5,y:.85,size:.045,weight:600}],[{x:.35,y:.28,w:.5,h:.15},{x:.65,y:.47,w:.5,h:.15},{x:.35,y:.66,w:.5,h:.15},{x:.65,y:.85,w:.5,h:.15}],[{role:`headline`,x:.5,y:.12,size:.05,weight:900}]),Zt(`center-satellites`,`Center + satellites`,`one core idea, orbiting parts`,3,[{x:.5,y:.52,w:.34,h:.42},{x:.17,y:.3,w:.2,h:.26},{x:.83,y:.3,w:.2,h:.26},{x:.17,y:.77,w:.2,h:.26},{x:.83,y:.77,w:.2,h:.26}],[{role:`headline`,x:.5,y:.09,size:.065,weight:900}],[{x:.5,y:.52,w:.56,h:.28},{x:.2,y:.28,w:.32,h:.16},{x:.8,y:.28,w:.32,h:.16},{x:.2,y:.78,w:.32,h:.16},{x:.8,y:.78,w:.32,h:.16}],[{role:`headline`,x:.5,y:.1,size:.045,weight:900}]),Zt(`corner-big-text`,`Corner images, big text`,`statement first, proof beside it`,2,[{x:.72,y:.4,w:.32,h:.38},{x:.52,y:.72,w:.28,h:.34},{x:.85,y:.76,w:.24,h:.3}],[{role:`headline`,x:.26,y:.26,size:.105,weight:900},{role:`label`,x:.26,y:.42,size:.05,weight:600}],[{x:.36,y:.56,w:.5,h:.22},{x:.7,y:.7,w:.44,h:.2},{x:.4,y:.84,w:.4,h:.18}],[{role:`headline`,x:.5,y:.19,size:.065,weight:900},{role:`label`,x:.5,y:.31,size:.034,weight:600}]),Zt(`title-top-row`,`Title top, images below`,`title screen with evidence`,2,[{x:.22,y:.62,w:.28,h:.44},{x:.5,y:.62,w:.28,h:.44},{x:.78,y:.62,w:.28,h:.44}],[{role:`headline`,x:.5,y:.17,size:.1,weight:900}],[{x:.5,y:.4,w:.7,h:.2},{x:.5,y:.64,w:.7,h:.2},{x:.5,y:.86,w:.7,h:.16}],[{role:`headline`,x:.5,y:.15,size:.06,weight:900}]),Zt(`large-caption`,`One large + caption`,`let the image speak`,1,[{x:.5,y:.47,w:.56,h:.6}],[{role:`label`,x:.15,y:.1,size:.045,weight:800},{role:`caption`,x:.5,y:.85,size:.055,weight:600}],[{x:.5,y:.47,w:.82,h:.44}],[{role:`label`,x:.24,y:.12,size:.032,weight:800},{role:`caption`,x:.5,y:.78,size:.034,weight:600}]),Zt(`staggered-diagonal`,`Staggered diagonal`,`progression with motion`,3,[{x:.18,y:.26,w:.24,h:.3,tilt:-3},{x:.42,y:.45,w:.24,h:.3,tilt:3},{x:.64,y:.62,w:.24,h:.3,tilt:-3},{x:.86,y:.79,w:.24,h:.3,tilt:3}],[{role:`headline`,x:.74,y:.16,size:.075,weight:900}],[{x:.28,y:.3,w:.42,h:.18,tilt:-3},{x:.62,y:.46,w:.42,h:.18,tilt:3},{x:.36,y:.62,w:.42,h:.18,tilt:-3},{x:.68,y:.78,w:.42,h:.18,tilt:3}],[{role:`headline`,x:.5,y:.12,size:.05,weight:900}]),Zt(`overlap-stack`,`Overlapping stack`,`a deliberate pile`,2,[{x:.42,y:.5,w:.36,h:.46,tilt:-5},{x:.54,y:.56,w:.36,h:.46,tilt:3},{x:.63,y:.46,w:.36,h:.46,tilt:-2}],[{role:`headline`,x:.5,y:.12,size:.08,weight:900},{role:`caption`,x:.5,y:.89,size:.045,weight:600}],[{x:.44,y:.42,w:.58,h:.26,tilt:-5},{x:.58,y:.53,w:.58,h:.26,tilt:3},{x:.46,y:.64,w:.58,h:.26,tilt:-2}],[{role:`headline`,x:.5,y:.12,size:.05,weight:900},{role:`caption`,x:.5,y:.86,size:.032,weight:600}]),Zt(`banner-row`,`Wide banner + small row`,`one wide scene, details under`,2,[{x:.5,y:.36,w:.84,h:.36},{x:.25,y:.77,w:.24,h:.26},{x:.5,y:.77,w:.24,h:.26},{x:.75,y:.77,w:.24,h:.26}],[{role:`headline`,x:.5,y:.09,size:.065,weight:900}],[{x:.5,y:.36,w:.86,h:.26},{x:.22,y:.66,w:.28,h:.16},{x:.5,y:.66,w:.28,h:.16},{x:.78,y:.66,w:.28,h:.16}],[{role:`headline`,x:.5,y:.13,size:.05,weight:900},{role:`caption`,x:.5,y:.82,size:.032,weight:600}]),Zt(`quadrant-labels`,`Quadrants with labels`,`four named things`,4,[{x:.28,y:.3,w:.3,h:.3},{x:.72,y:.3,w:.3,h:.3},{x:.28,y:.71,w:.3,h:.3},{x:.72,y:.71,w:.3,h:.3}],[{role:`headline`,x:.5,y:.07,size:.06,weight:900},{role:`label`,x:.28,y:.49,size:.042,weight:800},{role:`label`,x:.72,y:.49,size:.042,weight:800},{role:`label`,x:.28,y:.9,size:.042,weight:800},{role:`label`,x:.72,y:.9,size:.042,weight:800}],[{x:.28,y:.32,w:.38,h:.2},{x:.72,y:.32,w:.38,h:.2},{x:.28,y:.64,w:.38,h:.2},{x:.72,y:.64,w:.38,h:.2}],[{role:`headline`,x:.5,y:.1,size:.045,weight:900},{role:`label`,x:.28,y:.45,size:.028,weight:800},{role:`label`,x:.72,y:.45,size:.028,weight:800},{role:`label`,x:.28,y:.77,size:.028,weight:800},{role:`label`,x:.72,y:.77,size:.028,weight:800}]),Zt(`pyramid-3`,`Pyramid of three`,`one above two`,3,[{x:.5,y:.32,w:.3,h:.32},{x:.32,y:.71,w:.3,h:.32},{x:.68,y:.71,w:.3,h:.32}],[{role:`headline`,x:.5,y:.08,size:.065,weight:900},{role:`caption`,x:.5,y:.92,size:.04,weight:600}],[{x:.5,y:.34,w:.5,h:.22},{x:.27,y:.62,w:.42,h:.18},{x:.73,y:.62,w:.42,h:.18}],[{role:`headline`,x:.5,y:.1,size:.05,weight:900},{role:`caption`,x:.5,y:.79,size:.032,weight:600}]),Zt(`mosaic-dense`,`Dense mosaic`,`everything at once`,5,[{x:.3,y:.4,w:.34,h:.42},{x:.62,y:.29,w:.24,h:.26},{x:.86,y:.33,w:.2,h:.28},{x:.19,y:.78,w:.24,h:.26},{x:.47,y:.77,w:.26,h:.28},{x:.73,y:.73,w:.22,h:.24},{x:.91,y:.76,w:.14,h:.18}],[{role:`headline`,x:.5,y:.09,size:.06,weight:900}],[{x:.32,y:.3,w:.5,h:.2},{x:.78,y:.26,w:.36,h:.16},{x:.24,y:.52,w:.4,h:.16},{x:.68,y:.5,w:.44,h:.18},{x:.3,y:.74,w:.42,h:.16},{x:.74,y:.73,w:.4,h:.16},{x:.5,y:.89,w:.5,h:.1}],[{role:`headline`,x:.5,y:.1,size:.045,weight:900}])],$t=new Map(Qt.map(e=>[e.id,e])),en=e=>$t.get(e)||null;function tn(e,t=16/9){return e?t<1?{slots:e.pSlots,textSlots:e.pTextSlots}:{slots:e.slots,textSlots:e.textSlots}:null}function nn(e,t,{aspect:n=16/9}={}){if(!t)return(e||[]).map(e=>{if(e.pinned||e.kind!==`image`||!e.box)return e;let{box:t,...n}=e;return n});let r=tn(t,n),i=(e,t)=>(e.appearMs||0)-(t.appearMs||0),a=(e||[]).filter(e=>e.kind===`image`&&!e.pinned).sort(i),o=(e||[]).filter(e=>e.kind===`text`&&!e.pinned).sort(i),s=new Map;a.forEach((e,t)=>{t<r.slots.length&&s.set(e.id,r.slots[t])});let c=new Map;return o.forEach((e,t)=>{t<r.textSlots.length&&c.set(e.id,r.textSlots[t])}),(e||[]).map(e=>{if(e.pinned)return e;if(e.kind===`image`){let t=s.get(e.id);if(!t){let{box:t,...n}=e;return{...n,pos:null}}return{...e,pos:{x:t.x,y:t.y},box:{w:t.w,h:t.h},size:t.w,tilt:t.tilt||0}}let t=c.get(e.id);return t?{...e,pos:{x:t.x,y:t.y},size:t.size,weight:t.weight||e.weight||800}:e})}function rn({imageCount:e=0,textCount:t=0,hint:n=``}={}){if(!e)return null;let r=String(n||``).toLowerCase();return e===2&&/\\bvs\\b|versus|compar|before.*after|either/.test(r)?`compare-2`:e>=3&&/step|order|sequence|timeline|process|journey|stages/.test(r)?`timeline-row`:e>=3&&/list|lists|enumerat|items|examples|types|kinds/.test(r)?e>=5?`mosaic-dense`:`three-across`:e===1?t>1?`large-caption`:`hero-headline`:e===2?`compare-2`:e===3?`three-across`:e===4?`grid-2x2`:e===5?`center-satellites`:e<=7?`mosaic-dense`:`grid-3x3`}let an=new Set([`mode`,`meta`,`audio`,`styleBlock`,`sheets`,`lineages`,`scenes`,`strip`,`projectType`,`projectTypeNote`]),on=new Set([`sceneId`,`title`,`genre`,`styleBlock`,`styleRef`,`styleRefs`,`sheets`,`titleScreen`,`renderer`,`canvas`,`elements`]),sn=new Set(`panelId.type.sceneId.lineageId.kind.prompt.scene.changePrompt.sourcePanelId.image.startMs.durationMs.transitionIn.overlayLayer.provenance.wordStart.wordEnd.needsRefresh.versions.method.methodGroup.repeatOf.textOverlays.sfx.cast.promptOverride.refBlocklist.styleWarning.styleStrict.revealOf.revealIndex.revealPlan.animateNext`.split(`.`)),cn=new Set([`panelId`,`type`,`sceneId`,`startMs`,`durationMs`,`wordStart`,`wordEnd`,`provenance`]),ln=new Set([`panelId`,`type`,`sceneId`,`mode`,`gif`,`gifQuery`,`candidates`,`tone`,`startMs`,`durationMs`,`transitionIn`,`wordStart`,`wordEnd`,`provenance`]),un=[`replace`,`overlay`],dn=new Set([`gifUrl`,`mode`,`gifQuery`,`box`,`wordStart`,`wordEnd`]);function fn(e,t){if(e!=null){if(typeof e!=`object`||Array.isArray(e))throw Error(`${t}: overlayLayer must be an object`);for(let n of Object.keys(e))if(!dn.has(n))throw Error(`${t}: overlayLayer unknown field \"${n}\"`);if(!String(e.gifUrl||``).trim())throw Error(`${t}: overlayLayer requires a gifUrl`);if(e.mode!==`overlay`)throw Error(`${t}: overlayLayer mode must be \"overlay\"`);if(e.box!=null&&(typeof e.box!=`object`||Array.isArray(e.box)))throw Error(`${t}: overlayLayer box must be an object`)}}let pn=[{id:`vidu-q3-turbo`,label:`Vidu Q3 Turbo`,durations:[2,3,4],minSec:1,maxSec:16,resolution:`1080p`,resolutions:[`540p`,`720p`,`1080p`],default:!0},{id:`wan-2.7`,label:`Wan 2.7`,durations:[2,3,4],minSec:2,maxSec:15,resolution:`1080p`,resolutions:[`720p`,`1080p`]},{id:`veo-3.1-lite`,label:`Veo 3.1 Lite`,durations:[4],durList:[4,6,8],resolution:`720p`,resolutions:[`720p`,`1080p`],aspects:[`16:9`,`9:16`]}],mn=pn.find(e=>e.default)?.id||pn[0].id;function hn(e,t){let n=pn.find(t=>t.id===e)||pn[0],r=Number(t)||n.durations[0];return n.durList?n.durList.reduce((e,t)=>Math.abs(t-r)<Math.abs(e-r)?t:e,n.durList[0]):Math.max(n.minSec??1,Math.min(n.maxSec??16,Math.round(r)))}function gn(e,t){let n=e?.strip||[],r=n.findIndex(e=>e.panelId===t),i=n[r],a=n[r+1];return!i||!a?0:((Number(i.durationMs)||0)+(Number(a.durationMs)||0))/1e3}function _n(e,t,n){let r=gn(e,t);return r?hn(n,Math.max(1,Math.round(r))):hn(n,3)}let vn=.04;function yn(e,t){return Math.max(0,(Number(e)||0)-vn)+Math.max(0,(Number(t)||0)-vn)}let bn=[`seedance-2.0`,`seedance-2.0-fast`,`seedance-2.0-mini`];function xn(e){return(pn.find(t=>t.id===e)||{}).durations||[2,3,4]}function Sn(e,t,n,r){let i=`${e||``}|${t||``}|${n||``}|${r||0}`,a=5381;for(let e=0;e<i.length;e++)a=(a<<5)+a+i.charCodeAt(e)>>>0;return`a${a.toString(36)}`}let Cn=new Set([`panelId`,`type`,`sceneId`,`lineageId`,`sourcePanelId`,`zoom`,`image`,`versions`,`styleWarning`,`styleStrict`,`startMs`,`durationMs`,`transitionIn`,`provenance`,`wordStart`,`wordEnd`,`needsRefresh`,`says`]),wn=1.8;function Tn(e,t){if(e==null)return;if(typeof e!=`object`||Array.isArray(e))throw Error(`${t}: zoom must be an object`);for(let n of Object.keys(e))if(![`fx`,`fy`,`scale`,`pickedBy`].includes(n))throw Error(`${t}: zoom unknown field \"${n}\"`);let n=Number(e.fx),r=Number(e.fy),i=Number(e.scale);if(!Number.isFinite(n)||n<0||n>100||!Number.isFinite(r)||r<0||r>100)throw Error(`${t}: zoom fx/fy must be 0-100 frame percentages`);if(!Number.isFinite(i)||i<=1)throw Error(`${t}: zoom scale must be > 1 — zoom is IN-only (pulling back out is a scene change, not a zoom-out)`);if(i>3)throw Error(`${t}: zoom scale must be <= 3`);if(e.pickedBy!=null&&e.pickedBy!==`vision`&&e.pickedBy!==`user`)throw Error(`${t}: zoom pickedBy must be vision|user`)}function En({fx:e=50,fy:t=50,scale:n=wn}={}){let r=Math.max(1.2,Math.min(3,Number(n)||1.8)),i=Math.max(0,Math.min(100,Number(e)||0))/100,a=Math.max(0,Math.min(100,Number(t)||0))/100,o=1/r;return{x:i*(1-o),y:a*(1-o),w:o,h:o}}let Dn=new Set(`panelId.type.sceneId.background.autoArrange.planned.elements.events.startMs.durationMs.transitionIn.provenance.wordStart.wordEnd.needsRefresh.says.versions.styleWarning.styleStrict.template.hint.builtBy.mode.revert.handoff.transitionMs`.split(`.`)),On=[`swipe-up`,`swipe-down`,`swipe-left`,`swipe-right`,`cut`],kn=[`pop`,`fade`],An=new Set(`id.kind.src.query.source.appearMs.leaveMs.pos.size.tilt.entrance.sfx.sfxVolume.pinned.emphasis.box.text.font.color.weight.anim.loop.muted.trimStartSec.speed.poster.durationSec.wordTimes.motion.moves.shadow.descriptor.assetId.sourceInMs.sourceOutMs.cutout.pose`.split(`.`));function jn(e,t){if(!Array.isArray(e))throw Error(`${t}: canvas elements must be an array`);let n=new Set;for(let r of e){if(!r||typeof r!=`object`)throw Error(`${t}: canvas element must be an object`);for(let e of Object.keys(r))if(!An.has(e))throw Error(`${t}: canvas element unknown field \"${e}\"`);if(!r.id||n.has(r.id))throw Error(`${t}: canvas element needs a unique id`);if(n.add(r.id),r.kind!==`image`&&r.kind!==`text`&&r.kind!==`video`)throw Error(`${t}: canvas element kind must be image|video|text`);if(!Number.isFinite(Number(r.appearMs))||Number(r.appearMs)<0)throw Error(`${t}: canvas element ${r.id} needs appearMs >= 0`);if(r.leaveMs!=null&&Number(r.leaveMs)<=Number(r.appearMs))throw Error(`${t}: canvas element ${r.id} leaveMs must be after appearMs`);if(r.pos!=null&&(!Number.isFinite(Number(r.pos.x))||!Number.isFinite(Number(r.pos.y))))throw Error(`${t}: canvas element ${r.id} pos must be { x, y } numbers`);if(r.box!=null&&(!Number.isFinite(Number(r.box.w))||!Number.isFinite(Number(r.box.h))||r.box.w<=0||r.box.h<=0))throw Error(`${t}: canvas element ${r.id} box must be { w, h } positive numbers`);if(r.kind===`text`&&!String(r.text||``).trim())throw Error(`${t}: canvas text element ${r.id} needs text`);if(r.sfx!=null&&![`auto`,`pop`,`swoosh`,`none`].includes(r.sfx))throw Error(`${t}: canvas element ${r.id} sfx must be auto|pop|swoosh|none`);if(r.kind===`video`){if(r.speed!=null&&(!Number.isFinite(Number(r.speed))||Number(r.speed)<=0))throw Error(`${t}: canvas video ${r.id} speed must be > 0`);if(r.trimStartSec!=null&&(!Number.isFinite(Number(r.trimStartSec))||Number(r.trimStartSec)<0))throw Error(`${t}: canvas video ${r.id} trimStartSec must be >= 0`)}if(r.wordTimes!=null&&(!Array.isArray(r.wordTimes)||r.wordTimes.some(e=>!Number.isFinite(Number(e)))))throw Error(`${t}: canvas element ${r.id} wordTimes must be an array of ms numbers`);if(r.moves!=null){if(!Array.isArray(r.moves))throw Error(`${t}: canvas element ${r.id} moves must be an array`);for(let e of r.moves){if(!e||typeof e!=`object`)throw Error(`${t}: canvas element ${r.id} move must be an object`);if(!Number.isFinite(Number(e.atMs))||Number(e.atMs)<0)throw Error(`${t}: canvas element ${r.id} move needs atMs >= 0`);if(e.pos!=null&&(!Number.isFinite(Number(e.pos.x))||!Number.isFinite(Number(e.pos.y))))throw Error(`${t}: canvas element ${r.id} move pos must be { x, y } numbers`);if(e.size!=null&&!Number.isFinite(Number(e.size)))throw Error(`${t}: canvas element ${r.id} move size must be a number`)}}}}function Mn(e,t){let n=new Set(t),r=(e||[]).filter(e=>n.has(e.panelId)),i=[];for(let e of r)e.type===`titleScreen`?i.push({panelId:e.panelId,reason:`a title screen is not a beat a canvas can absorb`}):e.type===`canvas`?i.push({panelId:e.panelId,reason:`already a canvas`}):(e.kind===`revealStep`||e.method===`progressiveReveal`)&&i.push({panelId:e.panelId,reason:`part of a progressive-reveal group`});for(let t of e||[])n.has(t.panelId)||(t.repeatOf&&n.has(t.repeatOf)&&i.push({panelId:t.repeatOf,reason:`${t.panelId} re-shows it`}),t.revealOf&&n.has(t.revealOf)&&i.push({panelId:t.revealOf,reason:`${t.panelId} reveals it`}),t.type===`zoom`&&t.sourcePanelId&&n.has(t.sourcePanelId)&&i.push({panelId:t.sourcePanelId,reason:`zoom ${t.panelId} pushes into it`}));return i}function Nn(e,t,n){let r=(e||[]).findIndex(e=>e.panelId===t),i=(e||[]).findIndex(e=>e.panelId===(n||t));if(r<0||i<0)throw Error(`canvasRange: unknown panel`);let[a,o]=r<=i?[r,i]:[i,r],s=e.slice(a,o+1),c=s[0].sceneId;if(s.some(e=>e.sceneId!==c))throw Error(`canvasRange: a canvas stays inside one scene`);return s.map(e=>e.panelId)}function Pn(e,t){let n=e=>{let n=(Number(e.startMs)+Number(e.endMs))/2;return n>=t.startMs&&n<t.startMs+t.durationMs},r=(e?.audio?.words||[]).filter(e=>e&&String(e.text||``).trim()&&n(e)),i=[],a=[];for(let e=0;e<r.length;e++){a.push(r[e]);let t=e+1<r.length?Number(r[e+1].startMs)-Number(r[e].endMs):1/0;(/[.!?;:]$/.test(String(r[e].text))||t>600||a.length>=8)&&(i.push(a),a=[])}a.length&&i.push(a);let o=e=>Math.max(0,Math.min(t.durationMs-150,Math.round(e)-75-t.startMs));return i.map(e=>({text:e.map(e=>String(e.text).trim()).join(` `),wordTimes:e.map(e=>o(Number(e.startMs)))})).filter(e=>e.text)}function Fn(e){let t=e?.meta?.aspect||`16:9`;return t===`9:16`?9/16:t===`1:1`?1:16/9}function In(e,t){let n=en(t.template);if(n){let r=nn(t.elements||[],n,{aspect:Fn(e)}),i=kt({...t,autoArrange:!0,elements:r.map(e=>e.pos?{...e,pinned:!0}:e)},{aspect:Fn(e)});return{...t,elements:r.map(e=>!e.pinned&&!e.pos&&i.has(e.id)?{...e,pos:i.get(e.id)}:e)}}return t.autoArrange?At(t,{aspect:Fn(e)}):t}function Ln(e,t,n,r,{freezeLayout:i=!1}={}){let a=e.strip.find(e=>e.panelId===t);if(!a||a.type!==`canvas`)throw Error(`patchCanvasElement: ${t} is not a canvas panel`);let o=e.strip.map(a=>{if(a.panelId!==t)return a;let o={...a,elements:(a.elements||[]).map(e=>e.id===n?{...e,...r}:e)};return i?o:In(e,o)});return q({...e,strip:o})}let Rn=new Set([`model`,`durationSec`,`video`,`srcKey`,`genSeconds`,`generatedAt`,`prompt`,`fit`]);function zn(e,t){if(e==null)return;if(typeof e!=`object`||Array.isArray(e))throw Error(`${t}: animateNext must be an object`);for(let n of Object.keys(e))if(!Rn.has(n))throw Error(`${t}: animateNext unknown field \"${n}\"`);if(`fit`in e&&typeof e.fit!=`boolean`)throw Error(`${t}: animateNext fit must be a boolean`);if(!pn.some(t=>t.id===e.model)&&!bn.includes(e.model))throw Error(`${t}: animateNext model must be one of ${pn.map(e=>e.id).join(`, `)}`);let n=Number(e.durationSec);if(!Number.isFinite(n)||n<=0||n>16)throw Error(`${t}: animateNext durationSec must be 0-16s`)}let Bn=new Set([`panelId`,`type`,`sceneId`,`visibleElements`,`textOverlays`,`layout`,`image`,`versions`,`startMs`,`durationMs`,`transitionIn`,`provenance`,`wordStart`,`wordEnd`,`method`,`methodGroup`,`needsRefresh`]),Vn=[`scene`,`diagram`],Hn=[`story`,`explainer`,`both`,`neither`];function Un(e){return e?.renderer===`diagram`?`diagram`:`scene`}let Wn=[`small`,`medium`,`large`];function Gn(e){return e===`large`?.13:e===`small`?.04:.07}function Kn(e,t){if(e!=null){if(!Array.isArray(e))throw Error(`${t}: textOverlays must be an array`);e.forEach((e,n)=>{if(!e||typeof e!=`object`)throw Error(`${t}: textOverlays[${n}] not an object`);if(!String(e.text||``).trim())throw Error(`${t}: textOverlays[${n}] needs text`);if(e.pos!=null&&(!Number.isFinite(Number(e.pos.x))||!Number.isFinite(Number(e.pos.y))))throw Error(`${t}: textOverlays[${n}].pos must be { x, y } numbers`);if(e.size!=null&&!Number.isFinite(Number(e.size)))throw Error(`${t}: textOverlays[${n}].size must be a number`);if(e.placedBy!=null&&![`vision`,`user`,`pending`,`auto`].includes(e.placedBy))throw Error(`${t}: textOverlays[${n}].placedBy must be vision|user|pending`);if(e.role!=null&&!Wn.includes(e.role))throw Error(`${t}: textOverlays[${n}].role must be small|medium|large`);if(e.arrow!=null){if(typeof e.arrow!=`object`)throw Error(`${t}: textOverlays[${n}].arrow must be an object`);if(e.arrow.to!=null&&(!Number.isFinite(Number(e.arrow.to.x))||!Number.isFinite(Number(e.arrow.to.y))))throw Error(`${t}: textOverlays[${n}].arrow.to must be { x, y } numbers`)}if(e.atWord!=null&&!Number.isFinite(Number(e.atWord)))throw Error(`${t}: textOverlays[${n}].atWord must be a number (word index)`)})}}function qn(e){return Array.isArray(e.scenes)?e:{...e,scenes:[{sceneId:`s1`,title:String(e.meta?.title||``),genre:null,styleBlock:null,styleRef:e.meta?.styleRef??null,...Array.isArray(e.meta?.styleRefs)?{styleRefs:[...e.meta.styleRefs]}:{},sheets:{...e.sheets||{}},titleScreen:null}],strip:(e.strip||[]).map(e=>e.sceneId?e:{...e,type:e.type||`panel`,sceneId:`s1`})}}let Jn=/\\s*A persistent dark title bar across the very top of the frame(?: with bold white text reading \"[^\"]*\")?\\.?/gi,Yn=e=>{let t=String(e||``),n=t.replace(Jn,``);return n===t?e:n.replace(/[ \\t]{2,}/g,` `).trim()};function q(e){let t=typeof e==`string`?JSON.parse(e):e;if(!t||typeof t!=`object`)throw Error(`panel doc: not an object`);for(let e of Object.keys(t))if(!an.has(e))throw Error(`panel doc: unknown field \"${e}\"`);if(t.mode!==`imagePanel`)throw Error(`panel doc: mode must be \"imagePanel\" (got \"${t.mode}\")`);if(t.projectType!=null&&!Hn.includes(t.projectType))throw Error(`panel doc: projectType must be story|explainer|both|neither (got \"${t.projectType}\")`);let n=[`image`,`versions`,`needsRefresh`,`styleWarning`,`styleStrict`],r=Array.isArray(t.scenes)&&t.scenes[0]?.sceneId?t.scenes[0].sceneId:null,i=new Set(Array.isArray(t.scenes)?t.scenes.map(e=>e?.sceneId):[]),a=e=>r&&(!e.sceneId||!i.has(e.sceneId)),o=qn(Array.isArray(t.strip)&&t.strip.some(e=>e?.type===`canvas`&&(n.some(t=>t in e&&!Dn.has(t))||a(e)))?{...t,strip:t.strip.map(e=>{if(e?.type!==`canvas`)return e;let t=e,i=n.filter(t=>t in e&&!Dn.has(t));if(i.length){t={...t};for(let e of i)delete t[e]}return a(t)&&(t={...t,sceneId:r}),t})}:t),s=o.meta&&typeof o.meta==`object`?o.meta:{},c=o.sheets&&typeof o.sheets==`object`?o.sheets:{},l=o.lineages&&typeof o.lineages==`object`?o.lineages:{};if(!Array.isArray(o.scenes)||o.scenes.length===0)throw Error(`panel doc: scenes must be a non-empty array`);if(!Array.isArray(o.strip)||o.strip.length===0)throw Error(`panel doc: strip must be a non-empty array`);let u=new Set;o.scenes.forEach((e,t)=>{let n=`scenes[${t}]`;if(!e||typeof e!=`object`)throw Error(`${n}: not an object`);for(let t of Object.keys(e))if(!on.has(t))throw Error(`${n}: unknown field \"${t}\"`);if(!e.sceneId||typeof e.sceneId!=`string`)throw Error(`${n}: missing sceneId`);if(u.has(e.sceneId))throw Error(`${n}: duplicate sceneId \"${e.sceneId}\"`);if(e.genre!=null&&!Ae.includes(e.genre))throw Error(`${n} (${e.sceneId}): genre must be story|explainer|null`);if(e.titleScreen!=null&&typeof e.titleScreen!=`object`)throw Error(`${n} (${e.sceneId}): titleScreen must be an object`);if(e.renderer!=null&&!Vn.includes(e.renderer))throw Error(`${n} (${e.sceneId}): renderer must be scene|diagram`);if(e.canvas!=null&&typeof e.canvas!=`object`)throw Error(`${n} (${e.sceneId}): canvas must be an object`);if(e.elements!=null){if(typeof e.elements!=`object`||Array.isArray(e.elements))throw Error(`${n} (${e.sceneId}): elements must be an object map`);for(let[t,r]of Object.entries(e.elements)){if(!r||typeof r!=`object`)throw Error(`${n} (${e.sceneId}): element \"${t}\" not an object`);if(r.pos!=null&&(!Number.isFinite(Number(r.pos.x))||!Number.isFinite(Number(r.pos.y))))throw Error(`${n} (${e.sceneId}): element \"${t}\" pos must be { x, y } numbers`);if(r.scale!=null&&!Number.isFinite(Number(r.scale)))throw Error(`${n} (${e.sceneId}): element \"${t}\" scale must be a number`)}}if(Un(e)===`diagram`&&!e.elements)throw Error(`${n} (${e.sceneId}): a diagram scene needs an elements map`);u.add(e.sceneId)});let d=new Map(o.scenes.map(e=>[e.sceneId,e])),f=new Set,p=new Map,m=new Map,h=new Set,g=new Set,_=null;o.strip.forEach((e,t)=>{let n=`strip[${t}]`;if(!e||typeof e!=`object`)throw Error(`${n}: not an object`);if(!e.panelId||typeof e.panelId!=`string`)throw Error(`${n}: missing panelId`);if(f.has(e.panelId))throw Error(`${n}: duplicate panelId \"${e.panelId}\"`);if(!e.sceneId||!u.has(e.sceneId))throw Error(`${n} (${e.panelId}): sceneId \"${e.sceneId}\" not in scenes`);if(e.sceneId!==_){if(h.has(e.sceneId))throw Error(`${n} (${e.panelId}): scene \"${e.sceneId}\" reappears after ending — scenes must be contiguous`);_&&h.add(_),_=e.sceneId}if(!Number.isFinite(Number(e.startMs))||!Number.isFinite(Number(e.durationMs))||Number(e.durationMs)<=0)throw Error(`${n} (${e.panelId}): startMs/durationMs must be finite (durationMs > 0)`);if(e.type===`titleScreen`){for(let t of Object.keys(e))if(!cn.has(t))throw Error(`${n} (${e.panelId}): unknown title-screen field \"${t}\"`);f.add(e.panelId);return}if(e.type===`canvas`){for(let t of Object.keys(e))if(!Dn.has(t))throw Error(`${n} (${e.panelId}): unknown canvas field \"${t}\"`);if(e.events!=null&&!Array.isArray(e.events))throw Error(`${n} (${e.panelId}): canvas events must be an array`);if(e.template!=null&&typeof e.template!=`string`)throw Error(`${n} (${e.panelId}): canvas template must be a string id`);if(e.revert!=null&&(!Array.isArray(e.revert.rows)||!Array.isArray(e.revert.repointed)))throw Error(`${n} (${e.panelId}): canvas revert must be { rows: [], repointed: [] }`);if(e.handoff!=null){if(typeof e.handoff!=`object`)throw Error(`${n} (${e.panelId}): canvas handoff must be an object`);if(e.handoff.exit!=null&&!On.includes(e.handoff.exit))throw Error(`${n} (${e.panelId}): handoff exit must be ${On.join(`|`)}`);if(e.handoff.arrive!=null&&!kn.includes(e.handoff.arrive))throw Error(`${n} (${e.panelId}): handoff arrive must be ${kn.join(`|`)}`)}if(Un(d.get(e.sceneId))===`diagram`)throw Error(`${n} (${e.panelId}): canvas panels live in generative scenes only`);jn(e.elements||[],`${n} (${e.panelId})`),f.add(e.panelId),p.set(e.panelId,e),m.set(e.panelId,e.sceneId);return}if(e.type===`zoom`){for(let t of Object.keys(e))if(!Cn.has(t))throw Error(`${n} (${e.panelId}): unknown zoom field \"${t}\"`);if(Un(d.get(e.sceneId))===`diagram`)throw Error(`${n} (${e.panelId}): zoom panels live in generative scenes only`);if(!e.lineageId||!l[e.lineageId])throw Error(`${n} (${e.panelId}): lineageId \"${e.lineageId}\" not in lineages`);if(!e.sourcePanelId)throw Error(`${n} (${e.panelId}): zoom panel requires sourcePanelId (the frame it pushes into)`);if(!f.has(e.sourcePanelId))throw Error(`${n} (${e.panelId}): sourcePanelId \"${e.sourcePanelId}\" is not an EARLIER panel`);let t=p.get(e.sourcePanelId);if(t?.lineageId!==e.lineageId)throw Error(`${n} (${e.panelId}): cross-lineage zoom source (\"${e.sourcePanelId}\" is in \"${t?.lineageId}\")`);if(m.get(e.sourcePanelId)!==e.sceneId)throw Error(`${n} (${e.panelId}): zoom source must be in the same scene`);Tn(e.zoom,`${n} (${e.panelId})`),f.add(e.panelId),p.set(e.panelId,e),m.set(e.panelId,e.sceneId);return}if(e.type===`giphy`){for(let t of Object.keys(e))if(!ln.has(t))throw Error(`${n} (${e.panelId}): unknown giphy field \"${t}\"`);if(!un.includes(e.mode))throw Error(`${n} (${e.panelId}): giphy panel mode must be ${un.join(`|`)}`);if(!String(e.gif||``).trim())throw Error(`${n} (${e.panelId}): giphy panel requires a cached gif url`);if(e.candidates!=null&&(!Array.isArray(e.candidates)||e.candidates.some(e=>typeof e!=`string`)))throw Error(`${n} (${e.panelId}): giphy candidates must be an array of urls`);if(e.transitionIn!=null&&e.transitionIn!==`cut`&&e.transitionIn!==`fade`)throw Error(`${n} (${e.panelId}): transitionIn must be cut|fade`);f.add(e.panelId);return}let r=Un(d.get(e.sceneId));if(e.type===`diagram`){if(r!==`diagram`)throw Error(`${n} (${e.panelId}): diagram panel inside a \"${r}\"-renderer scene — set the scene's renderer to \"diagram\"`);for(let t of Object.keys(e))if(!Bn.has(t))throw Error(`${n} (${e.panelId}): unknown diagram field \"${t}\"`);if(!Array.isArray(e.visibleElements))throw Error(`${n} (${e.panelId}): diagram panel needs visibleElements (array of element ids)`);let t=d.get(e.sceneId)?.elements||{};for(let r of e.visibleElements)if(!t[r])throw Error(`${n} (${e.panelId}): visible element \"${r}\" is not in scene \"${e.sceneId}\" elements`);if(e.layout!=null){if(typeof e.layout!=`object`||Array.isArray(e.layout))throw Error(`${n} (${e.panelId}): layout must be an object map`);for(let[r,i]of Object.entries(e.layout)){if(!t[r])throw Error(`${n} (${e.panelId}): layout element \"${r}\" is not in scene \"${e.sceneId}\" elements`);if(i?.pos!=null&&(!Number.isFinite(Number(i.pos.x))||!Number.isFinite(Number(i.pos.y))))throw Error(`${n} (${e.panelId}): layout \"${r}\" pos must be { x, y } numbers`);if(i?.scale!=null&&!Number.isFinite(Number(i.scale)))throw Error(`${n} (${e.panelId}): layout \"${r}\" scale must be a number`)}}Kn(e.textOverlays,`${n} (${e.panelId})`),f.add(e.panelId);return}if(r===`diagram`)throw Error(`${n} (${e.panelId}): generative panel inside a diagram scene — diagram scenes contain composited diagram entries only`);for(let t of Object.keys(e))if(!sn.has(t))throw Error(`${n}: unknown field \"${t}\"`);if(Kn(e.textOverlays,`${n} (${e.panelId})`),fn(e.overlayLayer,`${n} (${e.panelId})`),zn(e.animateNext,`${n} (${e.panelId})`),!e.lineageId||!l[e.lineageId])throw Error(`${n} (${e.panelId}): lineageId \"${e.lineageId}\" not in lineages`);if(e.kind!==`base`&&e.kind!==`edit`&&e.kind!==`repeat`&&e.kind!==`revealStep`)throw Error(`${n} (${e.panelId}): kind must be base|edit|repeat|revealStep`);if(e.method!=null&&!Oe.has(e.method))throw Error(`${n} (${e.panelId}): unknown method \"${e.method}\"`);let i=!!l[e.lineageId]?.persistent;if(e.kind===`edit`){if(!e.sourcePanelId)throw Error(`${n} (${e.panelId}): edit panel requires sourcePanelId`);if(!f.has(e.sourcePanelId))throw Error(`${n} (${e.panelId}): sourcePanelId \"${e.sourcePanelId}\" is not an EARLIER panel`);let t=p.get(e.sourcePanelId);if(t?.lineageId!==e.lineageId)throw Error(`${n} (${e.panelId}): cross-lineage source (\"${e.sourcePanelId}\" is in \"${t?.lineageId}\")`);if(m.get(e.sourcePanelId)!==e.sceneId&&!i)throw Error(`${n} (${e.panelId}): cross-scene source \"${e.sourcePanelId}\" — edit-chains reset at scene boundaries (flag the lineage persistent to carry it)`);if(!String(e.prompt??e.changePrompt??``).trim())throw Error(`${n} (${e.panelId}): edit panel needs a change prompt (a shown panel is never a static repeat)`)}else if(e.kind===`repeat`){if(!e.repeatOf)throw Error(`${n} (${e.panelId}): repeat panel requires repeatOf`);if(!f.has(e.repeatOf))throw Error(`${n} (${e.panelId}): repeatOf \"${e.repeatOf}\" is not an EARLIER panel`);let t=p.get(e.repeatOf);if(!t||t.kind===`repeat`)throw Error(`${n} (${e.panelId}): repeatOf must reference a real (non-repeat) panel`);if(t.lineageId!==e.lineageId||m.get(e.repeatOf)!==e.sceneId)throw Error(`${n} (${e.panelId}): repeatOf must stay in the same lineage and scene`);if(e.sourcePanelId!=null)throw Error(`${n} (${e.panelId}): repeat panel must have sourcePanelId null`)}else if(e.kind===`revealStep`){if(!e.revealOf)throw Error(`${n} (${e.panelId}): revealStep requires revealOf (its base panel)`);if(!Number.isFinite(Number(e.revealIndex))||Number(e.revealIndex)<0)throw Error(`${n} (${e.panelId}): revealStep requires a revealIndex >= 0`);if(e.sourcePanelId!=null)throw Error(`${n} (${e.panelId}): revealStep must have sourcePanelId null`);if(String(e.scene||``).trim()||String(e.changePrompt||``).trim())throw Error(`${n} (${e.panelId}): revealStep carries no prompts — its frame renders from the base image`)}else if(e.sourcePanelId!=null)throw Error(`${n} (${e.panelId}): base panel must have sourcePanelId null`);if(!g.has(e.sceneId)&&e.kind!==`base`&&e.kind!==`revealStep`&&!i)throw Error(`${n} (${e.panelId}): the first panel of scene \"${e.sceneId}\" must be a base (edit-chaining restarts at scene boundaries)`);if(e.transitionIn!=null&&e.transitionIn!==`cut`&&e.transitionIn!==`fade`)throw Error(`${n} (${e.panelId}): transitionIn must be cut|fade`);if(e.versions!=null&&(!Array.isArray(e.versions)||e.versions.some(e=>typeof e!=`string`)))throw Error(`${n} (${e.panelId}): versions must be an array of image URLs`);f.add(e.panelId),p.set(e.panelId,e),m.set(e.panelId,e.sceneId),g.add(e.sceneId)});for(let e of o.strip){if(e?.kind!==`revealStep`)continue;let t=p.get(e.revealOf);if(!t)throw Error(`strip (${e.panelId}): revealOf \"${e.revealOf}\" is not a panel in the strip`);if(t.kind!==`base`||t.method!==`progressiveReveal`)throw Error(`strip (${e.panelId}): revealOf \"${e.revealOf}\" must be a base panel with method \"progressiveReveal\"`);if(t.lineageId!==e.lineageId||t.sceneId!==e.sceneId)throw Error(`strip (${e.panelId}): revealOf must stay in the same lineage and scene`)}let v=typeof o.styleBlock==`string`&&o.styleBlock?Yn(o.styleBlock):o.styleBlock,y=!1,b=o.scenes.map(e=>{if(typeof e.styleBlock!=`string`||!e.styleBlock)return e;let t=Yn(e.styleBlock);return t===e.styleBlock?e:(y=!0,{...e,styleBlock:t})});return{...o,meta:s,sheets:c,lineages:l,styleBlock:v,scenes:y?b:o.scenes}}function Xn(e,t){return(e?.scenes||[]).find(e=>e.sceneId===t)||null}function Zn(e){return Array.isArray(e)?e.filter(e=>typeof e==`string`&&e):typeof e==`string`&&e?[e]:[]}function Qn(e,t){let n=Xn(e,t),r=Zn(n?.styleRefs).length?Zn(n?.styleRefs):n?.styleRef?[n.styleRef]:Zn(e?.meta?.styleRefs).length?Zn(e?.meta?.styleRefs):Zn(e?.meta?.styleRef);return{styleBlock:n?.styleBlock||e?.styleBlock||``,styleRef:r[0]??null,styleRefs:r,sheets:n&&Object.keys(n.sheets||{}).length?n.sheets:e?.sheets||{}}}function $n(e,t){if(t?.type===`giphy`)return t.gif??t.image??null;if(t?.type===`zoom`){if(t.image)return t.image;let n=(e||[]).find(e=>e.panelId===t.sourcePanelId);return n?$n(e,n):null}return t?.kind===`repeat`?(e||[]).find(e=>e.panelId===t.repeatOf)?.image??null:t?.image??null}function er(e,t){let n=Xn(e,t),r=Zn(n?.styleRefs).length?Zn(n?.styleRefs):n?.styleRef?[n.styleRef]:[];if(!r.length)return!0;let i=Zn(e?.meta?.styleRefs).length?Zn(e?.meta?.styleRefs):e?.meta?.styleRef?[e.meta.styleRef]:[];if(r.length!==i.length)return!1;let a=new Set(i);return r.every(e=>a.has(e))}function tr(e,t){return t&&t.kind===`base`&&t.type!==`titleScreen`&&t.type!==`giphy`&&t.type!==`diagram`&&t.method!==`progressiveReveal`&&er(e,t.sceneId)}function nr(e){let t=e?.strip||[],n=e?.meta?.anchorPanelId?t.find(t=>t.panelId===e.meta.anchorPanelId):null;return n&&tr(e,n)?n:t.find(t=>tr(e,t))||t.find(t=>t.kind===`base`&&t.type!==`titleScreen`&&t.type!==`giphy`&&t.type!==`diagram`&&er(e,t.sceneId))||null}function rr({audioUrl:e=null,words:t=null}={}){return e?!Array.isArray(t)||!t.length?{ready:!1,reason:`The voiceover timing analysis has not run — the strip is cut to the word timings.`}:{ready:!0,reason:null}:{ready:!1,reason:`The voiceover has not been generated or uploaded yet.`}}function ir(e){let t=rr(e);if(!t.ready)throw Error(`Continue Strip is locked: ${t.reason}`);return!0}function ar(e,t,n){if(!e.strip.find(e=>e.panelId===t))throw Error(`setPanelTextOverlays: unknown panel \"${t}\"`);let r=e.strip.map(e=>e.panelId===t?{...e,textOverlays:n}:e);return q({...e,strip:r})}function or(e,t){let n=new Set([t]),r=[];for(let t of e||[])t.kind===`edit`&&t.sourcePanelId&&n.has(t.sourcePanelId)&&(n.add(t.panelId),r.push(t.panelId));return r}function sr(e,t){let n=e?.audio?.words||[],r=t.startMs,i=t.startMs+t.durationMs;return n.filter(e=>{let t=(e.startMs+e.endMs)/2;return t>=r&&t<i}).map(e=>e.text).join(` `).trim()}function cr(e){return e.versions?.length?e.versions:e.image?[e.image]:[]}function lr(e,t){return[...cr(e).filter(e=>e!==t),t].slice(-8)}function ur(e,t,n){let r=e.strip.map(e=>e.panelId===t?{...e,...n,provenance:n.provenance||`user`}:e);return q({...e,strip:r})}function dr(e,t){let n=e.strip.findIndex(e=>e.panelId===t);if(n<0||n+1>=e.strip.length)return!1;let r=e.strip[n],i=e.strip[n+1],a=t=>t.type===`panel`&&!!$n(e.strip,t);return a(r)&&a(i)&&r.sceneId===i.sceneId}function fr(e,t){let n=e.strip.findIndex(e=>e.panelId===t);if(n<0)return!1;let r=e.strip[n].animateNext;return!r||!r.video?!1:!dr(e,t)||Sn($n(e.strip,e.strip[n]),$n(e.strip,e.strip[n+1]),r.model,r.genSeconds||r.durationSec)!==r.srcKey}async function pr(e,t,{signal:n,assertCurrent:r,host:i}){let a=H(i);r(),B(e),B(t),I(JSON.stringify(e).length<=1048576,`AUTOMATIC_ZOOM`,`The zoom metadata exceeds 1 MiB.`);let o=await a.run(Ue,{kind:`run`,input:e,signal:n,timeoutMs:15e3});return r(),B(o.outputs?.plan),I(V(o.outputs.plan)===V(t),`AUTOMATIC_ZOOM`,`The sandbox changed the pending zoom scope or framing.`),o.outputs.plan}function mr(e,t){let n=H(t.host),r=n.actor(),i=V(e),a=t.assertCurrent;return{...t,assertCurrent:()=>{a(),I(r&&n.actor()===r&&!t.signal?.aborted&&V(e)===i,`STALE`,`The account or zoom document changed.`)}}}async function hr(e,t){t=mr(e,t),t.assertCurrent(),I(Array.isArray(e?.strip)&&e.strip.length<=4096,`AUTOMATIC_ZOOM`,`The zoom worklist is too large.`);let n=e.strip.map((t,n)=>({origin:n,...t.type===void 0?{}:{type:t.type},hasTarget:!!t.zoom,hasImage:!!t.image,sourceReady:t.type===`zoom`&&!!$n(e.strip,e.strip.find(e=>e.panelId===t.sourcePanelId))})),r=n.filter(e=>e.type===`zoom`&&e.sourceReady&&(!e.hasTarget||!e.hasImage)).map(e=>e.origin);return I(r.length<=512,`AUTOMATIC_ZOOM`,`This pass exceeds 512 zoom crops.`),(await pr({operation:`pending`,data:{rows:n}},{pending:r},t)).pending.map(t=>e.strip[t])}async function gr(e,t,n,{reuse:r=!1,...i}){i=mr(e,i),i.assertCurrent();let a=e.strip.find(e=>e.panelId===t);I(a?.type===`zoom`,`AUTOMATIC_ZOOM`,`The selected zoom is unavailable.`);let o=r?a.zoom:null,s=r?o:n,c=s==null?null:Object.fromEntries((r?[`fx`,`fy`,`scale`,`pickedBy`]:[`fx`,`fy`,`scale`]).filter(e=>s[e]!==void 0).map(e=>[e,typeof s[e]==`number`&&!Number.isFinite(s[e])?String(s[e]):s[e]])),l=r?c:{fx:Number.isFinite(Number(c?.fx))?Number(c.fx):50,fy:Number.isFinite(Number(c?.fy))?Number(c.fy):50,scale:Number.isFinite(Number(c?.scale))?Number(c.scale):1.8,pickedBy:`vision`},u=await pr({operation:`target`,data:{reuse:r,target:c}},{zoom:l,rect:En(l)},i),d=r?o:u.zoom,f=V({zoom:d,rect:u.rect});return{zoom:d,rect:u.rect,apply:n=>(i.assertCurrent(),I(V({zoom:d,rect:u.rect})===f,`STALE`,`The approved zoom framing changed.`),I(typeof n==`string`&&n,`AUTOMATIC_ZOOM`,`The crop upload returned no image.`),ur(e,t,{zoom:d,image:n}))}}let _r={manifest:{schemaVersion:1,sdkVersion:`0.1.0`,id:`stillmade-internal.canvas-patch-element`,version:`1.0.0`,name:`Canvas element editing`,description:`Apply an explicit element patch with frozen or reflowed layout.`,kind:`task`,runtime:`javascript`,inputs:{doc:{type:`json`},panelId:{type:`text`},elementId:{type:`text`},patch:{type:`json`},freezeLayout:{type:`boolean`}},outputs:{edit:{type:`json`}},permissions:{project:[],network:[],filesystem:[],secrets:[]}},code:`// COLLAGE CANVAS TEMPLATES — 20 bundled, versioned slot layouts (panel-image\n// only), each authored TWICE: a landscape layout and a portrait (9:16) layout\n// for the same scenario. A template is a LAYOUT DEFINITION, not a static\n// design: image SLOTS (center pos, target box, draw order = array order\n// back→front, optional tilt) and explicit TEXT SLOTS (role + deliberate\n// position), which the canvas system reads to place elements.\n//\n// Coordinates are normalized to the canvas frame (x/w = width fractions,\n// y/h = height fractions). An image FITS its slot box cover-cropped\n// (drawCollage's \\`box\\` rendering — aspect preserved, never distorted); fine\n// adjustment stays manual (drag pins, per spec S10). Image slots keep a\n// bottom safety margin (y + h/2 ≤ 0.95) so nothing crowds the frame edge.\n//\n// EVERY SLOT IS OPTIONAL — image and text alike. A template defines where\n// things GO if present; nothing is required. A canvas can use 2 of 7 image\n// slots, no text at all, or text with fewer images; unused slots are simply\n// empty (no placeholder, no gap artifact). And templates place, they never\n// time: each element still appears on ITS OWN voiceover beat (appearMs is\n// untouched by template application), so a canvas builds up slot by slot.\n//\n// Ownership contract (post-approval spec):\n// - AUTO canvases: the generator PICKS a template (pickTemplateForCanvas) from\n// image count + the beat's scenario hint; S10 self-arranging handles the\n// OVERFLOW beyond the slots (spiral around the slotted ones). Shown +\n// changeable afterward.\n// - MANUAL canvases: no template by default; opt-in from the picker.\n// - Switching is non-destructive: same elements, new positions; PINNED\n// elements are never moved (the pin IS the manual override).\n// - No fit / no pick → template null → the plain self-arranging layout.\n//\n// APPROVED by the owner 2026-07-22 (v2 sheet: both orientations, bottom\n// margins fixed). Bundled static definitions — versioned, never regenerated.\nconst CANVAS_TEMPLATE_VERSION = 2;\n\n// slot: { x, y, w, h, tilt? } — image slot (center + target box)\n// textSlot: { role, x, y, size, weight? } — role: headline | label | caption\n// Each template: landscape layout in \\`slots\\`/\\`textSlots\\`, portrait layout in\n// \\`pSlots\\`/\\`pTextSlots\\` (same scenario re-authored for a tall frame).\nconst T = (id, name, scenario, minImages, slots, textSlots, pSlots, pTextSlots) => (\n { id, name, scenario, minImages, slots, textSlots, pSlots, pTextSlots }\n);\n\nconst CANVAS_TEMPLATES = [\n T('hero-headline', 'Hero + headline', 'one subject, one line', 1,\n [{ x: 0.5, y: 0.58, w: 0.5, h: 0.62 }],\n [{ role: 'headline', x: 0.5, y: 0.14, size: 0.09, weight: 900 }],\n [{ x: 0.5, y: 0.55, w: 0.78, h: 0.5 }],\n [{ role: 'headline', x: 0.5, y: 0.13, size: 0.055, weight: 900 }]),\n\n T('hero-supporting', 'Hero + 2 supporting', 'main subject with two details', 3,\n [{ x: 0.34, y: 0.55, w: 0.42, h: 0.58 }, { x: 0.78, y: 0.33, w: 0.28, h: 0.32 }, { x: 0.78, y: 0.73, w: 0.28, h: 0.32 }],\n [{ role: 'headline', x: 0.34, y: 0.13, size: 0.08, weight: 900 }],\n [{ x: 0.5, y: 0.38, w: 0.78, h: 0.32 }, { x: 0.28, y: 0.72, w: 0.4, h: 0.2 }, { x: 0.72, y: 0.72, w: 0.4, h: 0.2 }],\n [{ role: 'headline', x: 0.5, y: 0.12, size: 0.05, weight: 900 }]),\n\n T('compare-2', 'Side-by-side compare', 'A vs B', 2,\n [{ x: 0.27, y: 0.5, w: 0.38, h: 0.5 }, { x: 0.73, y: 0.5, w: 0.38, h: 0.5 }],\n [{ role: 'headline', x: 0.5, y: 0.12, size: 0.08, weight: 900 },\n { role: 'label', x: 0.27, y: 0.84, size: 0.05, weight: 800 },\n { role: 'label', x: 0.73, y: 0.84, size: 0.05, weight: 800 }],\n [{ x: 0.5, y: 0.35, w: 0.72, h: 0.24 }, { x: 0.5, y: 0.72, w: 0.72, h: 0.24 }],\n [{ role: 'headline', x: 0.5, y: 0.11, size: 0.05, weight: 900 },\n { role: 'label', x: 0.5, y: 0.51, size: 0.032, weight: 800 },\n { role: 'label', x: 0.5, y: 0.88, size: 0.032, weight: 800 }]),\n\n T('three-across', 'Three across', 'three items', 3,\n [{ x: 0.2, y: 0.5, w: 0.26, h: 0.46 }, { x: 0.5, y: 0.5, w: 0.26, h: 0.46 }, { x: 0.8, y: 0.5, w: 0.26, h: 0.46 }],\n [{ role: 'headline', x: 0.5, y: 0.13, size: 0.08, weight: 900 },\n { role: 'caption', x: 0.5, y: 0.86, size: 0.045, weight: 600 }],\n [{ x: 0.5, y: 0.32, w: 0.64, h: 0.2 }, { x: 0.5, y: 0.57, w: 0.64, h: 0.2 }, { x: 0.5, y: 0.82, w: 0.64, h: 0.2 }],\n [{ role: 'headline', x: 0.5, y: 0.1, size: 0.05, weight: 900 },\n { role: 'caption', x: 0.5, y: 0.96, size: 0.028, weight: 600 }]),\n\n T('grid-2x2', 'Grid of four', 'four items', 4,\n [{ x: 0.3, y: 0.36, w: 0.32, h: 0.34 }, { x: 0.7, y: 0.36, w: 0.32, h: 0.34 },\n { x: 0.3, y: 0.74, w: 0.32, h: 0.34 }, { x: 0.7, y: 0.74, w: 0.32, h: 0.34 }],\n [{ role: 'headline', x: 0.5, y: 0.09, size: 0.07, weight: 900 }],\n [{ x: 0.28, y: 0.38, w: 0.4, h: 0.24 }, { x: 0.72, y: 0.38, w: 0.4, h: 0.24 },\n { x: 0.28, y: 0.68, w: 0.4, h: 0.24 }, { x: 0.72, y: 0.68, w: 0.4, h: 0.24 }],\n [{ role: 'headline', x: 0.5, y: 0.12, size: 0.05, weight: 900 }]),\n\n T('grid-3x3', 'Many small (3x3)', 'lots of items', 6,\n [0.22, 0.5, 0.78].flatMap((x) => [0.3, 0.56, 0.82].map((y) => ({ x, y, w: 0.24, h: 0.22 }))),\n [{ role: 'headline', x: 0.5, y: 0.08, size: 0.065, weight: 900 }],\n [0.2, 0.5, 0.8].flatMap((x) => [0.34, 0.58, 0.82].map((y) => ({ x, y, w: 0.27, h: 0.18 }))),\n [{ role: 'headline', x: 0.5, y: 0.1, size: 0.045, weight: 900 }]),\n\n T('big-left-stack-right', 'Big lead + stack', 'one lead, several follow-ups', 3,\n [{ x: 0.32, y: 0.54, w: 0.5, h: 0.62 }, { x: 0.79, y: 0.3, w: 0.3, h: 0.22 },\n { x: 0.79, y: 0.56, w: 0.3, h: 0.22 }, { x: 0.79, y: 0.82, w: 0.3, h: 0.22 }],\n [{ role: 'headline', x: 0.32, y: 0.13, size: 0.075, weight: 900 }],\n [{ x: 0.5, y: 0.4, w: 0.84, h: 0.34 }, { x: 0.2, y: 0.74, w: 0.26, h: 0.16 },\n { x: 0.5, y: 0.74, w: 0.26, h: 0.16 }, { x: 0.8, y: 0.74, w: 0.26, h: 0.16 }],\n [{ role: 'headline', x: 0.5, y: 0.12, size: 0.05, weight: 900 }]),\n\n T('vertical-stack', 'Vertical stack', 'ordered top to bottom', 2,\n [{ x: 0.55, y: 0.29, w: 0.36, h: 0.22 }, { x: 0.55, y: 0.55, w: 0.36, h: 0.22 }, { x: 0.55, y: 0.81, w: 0.36, h: 0.22 }],\n [{ role: 'headline', x: 0.55, y: 0.08, size: 0.065, weight: 900 },\n { role: 'label', x: 0.16, y: 0.55, size: 0.055, weight: 800 }],\n [{ x: 0.5, y: 0.3, w: 0.66, h: 0.2 }, { x: 0.5, y: 0.56, w: 0.66, h: 0.2 }, { x: 0.5, y: 0.82, w: 0.66, h: 0.2 }],\n [{ role: 'headline', x: 0.5, y: 0.09, size: 0.05, weight: 900 },\n { role: 'label', x: 0.24, y: 0.17, size: 0.032, weight: 800 }]),\n\n T('scatter', 'Scattered collage', 'loose, hand-thrown feel', 3,\n [{ x: 0.26, y: 0.36, w: 0.28, h: 0.32, tilt: -6 }, { x: 0.68, y: 0.3, w: 0.26, h: 0.3, tilt: 4 },\n { x: 0.44, y: 0.66, w: 0.27, h: 0.31, tilt: 3 }, { x: 0.8, y: 0.62, w: 0.25, h: 0.29, tilt: -5 },\n { x: 0.58, y: 0.46, w: 0.24, h: 0.28, tilt: 2 }],\n [{ role: 'headline', x: 0.5, y: 0.1, size: 0.075, weight: 900 }],\n [{ x: 0.32, y: 0.3, w: 0.46, h: 0.2, tilt: -6 }, { x: 0.7, y: 0.26, w: 0.42, h: 0.18, tilt: 4 },\n { x: 0.4, y: 0.56, w: 0.44, h: 0.2, tilt: 3 }, { x: 0.74, y: 0.6, w: 0.4, h: 0.18, tilt: -5 },\n { x: 0.5, y: 0.82, w: 0.44, h: 0.19, tilt: 2 }],\n [{ role: 'headline', x: 0.5, y: 0.09, size: 0.045, weight: 900 }]),\n\n T('timeline-row', 'Row / timeline', 'steps in order', 3,\n [{ x: 0.14, y: 0.52, w: 0.2, h: 0.38 }, { x: 0.38, y: 0.52, w: 0.2, h: 0.38 },\n { x: 0.62, y: 0.52, w: 0.2, h: 0.38 }, { x: 0.86, y: 0.52, w: 0.2, h: 0.38 }],\n [{ role: 'headline', x: 0.5, y: 0.15, size: 0.075, weight: 900 },\n { role: 'caption', x: 0.5, y: 0.85, size: 0.045, weight: 600 }],\n [{ x: 0.35, y: 0.28, w: 0.5, h: 0.15 }, { x: 0.65, y: 0.47, w: 0.5, h: 0.15 },\n { x: 0.35, y: 0.66, w: 0.5, h: 0.15 }, { x: 0.65, y: 0.85, w: 0.5, h: 0.15 }],\n [{ role: 'headline', x: 0.5, y: 0.12, size: 0.05, weight: 900 }]),\n\n T('center-satellites', 'Center + satellites', 'one core idea, orbiting parts', 3,\n [{ x: 0.5, y: 0.52, w: 0.34, h: 0.42 }, { x: 0.17, y: 0.3, w: 0.2, h: 0.26 }, { x: 0.83, y: 0.3, w: 0.2, h: 0.26 },\n { x: 0.17, y: 0.77, w: 0.2, h: 0.26 }, { x: 0.83, y: 0.77, w: 0.2, h: 0.26 }],\n [{ role: 'headline', x: 0.5, y: 0.09, size: 0.065, weight: 900 }],\n [{ x: 0.5, y: 0.52, w: 0.56, h: 0.28 }, { x: 0.2, y: 0.28, w: 0.32, h: 0.16 }, { x: 0.8, y: 0.28, w: 0.32, h: 0.16 },\n { x: 0.2, y: 0.78, w: 0.32, h: 0.16 }, { x: 0.8, y: 0.78, w: 0.32, h: 0.16 }],\n [{ role: 'headline', x: 0.5, y: 0.1, size: 0.045, weight: 900 }]),\n\n T('corner-big-text', 'Corner images, big text', 'statement first, proof beside it', 2,\n [{ x: 0.72, y: 0.4, w: 0.32, h: 0.38 }, { x: 0.52, y: 0.72, w: 0.28, h: 0.34 }, { x: 0.85, y: 0.76, w: 0.24, h: 0.3 }],\n [{ role: 'headline', x: 0.26, y: 0.26, size: 0.105, weight: 900 },\n { role: 'label', x: 0.26, y: 0.42, size: 0.05, weight: 600 }],\n [{ x: 0.36, y: 0.56, w: 0.5, h: 0.22 }, { x: 0.7, y: 0.7, w: 0.44, h: 0.2 }, { x: 0.4, y: 0.84, w: 0.4, h: 0.18 }],\n [{ role: 'headline', x: 0.5, y: 0.19, size: 0.065, weight: 900 },\n { role: 'label', x: 0.5, y: 0.31, size: 0.034, weight: 600 }]),\n\n T('title-top-row', 'Title top, images below', 'title screen with evidence', 2,\n [{ x: 0.22, y: 0.62, w: 0.28, h: 0.44 }, { x: 0.5, y: 0.62, w: 0.28, h: 0.44 }, { x: 0.78, y: 0.62, w: 0.28, h: 0.44 }],\n [{ role: 'headline', x: 0.5, y: 0.17, size: 0.1, weight: 900 }],\n [{ x: 0.5, y: 0.4, w: 0.7, h: 0.2 }, { x: 0.5, y: 0.64, w: 0.7, h: 0.2 }, { x: 0.5, y: 0.86, w: 0.7, h: 0.16 }],\n [{ role: 'headline', x: 0.5, y: 0.15, size: 0.06, weight: 900 }]),\n\n T('large-caption', 'One large + caption', 'let the image speak', 1,\n [{ x: 0.5, y: 0.47, w: 0.56, h: 0.6 }],\n [{ role: 'label', x: 0.15, y: 0.1, size: 0.045, weight: 800 },\n { role: 'caption', x: 0.5, y: 0.85, size: 0.055, weight: 600 }],\n [{ x: 0.5, y: 0.47, w: 0.82, h: 0.44 }],\n [{ role: 'label', x: 0.24, y: 0.12, size: 0.032, weight: 800 },\n { role: 'caption', x: 0.5, y: 0.78, size: 0.034, weight: 600 }]),\n\n T('staggered-diagonal', 'Staggered diagonal', 'progression with motion', 3,\n [{ x: 0.18, y: 0.26, w: 0.24, h: 0.3, tilt: -3 }, { x: 0.42, y: 0.45, w: 0.24, h: 0.3, tilt: 3 },\n { x: 0.64, y: 0.62, w: 0.24, h: 0.3, tilt: -3 }, { x: 0.86, y: 0.79, w: 0.24, h: 0.3, tilt: 3 }],\n [{ role: 'headline', x: 0.74, y: 0.16, size: 0.075, weight: 900 }],\n [{ x: 0.28, y: 0.3, w: 0.42, h: 0.18, tilt: -3 }, { x: 0.62, y: 0.46, w: 0.42, h: 0.18, tilt: 3 },\n { x: 0.36, y: 0.62, w: 0.42, h: 0.18, tilt: -3 }, { x: 0.68, y: 0.78, w: 0.42, h: 0.18, tilt: 3 }],\n [{ role: 'headline', x: 0.5, y: 0.12, size: 0.05, weight: 900 }]),\n\n T('overlap-stack', 'Overlapping stack', 'a deliberate pile', 2,\n [{ x: 0.42, y: 0.5, w: 0.36, h: 0.46, tilt: -5 }, { x: 0.54, y: 0.56, w: 0.36, h: 0.46, tilt: 3 },\n { x: 0.63, y: 0.46, w: 0.36, h: 0.46, tilt: -2 }],\n [{ role: 'headline', x: 0.5, y: 0.12, size: 0.08, weight: 900 },\n { role: 'caption', x: 0.5, y: 0.89, size: 0.045, weight: 600 }],\n [{ x: 0.44, y: 0.42, w: 0.58, h: 0.26, tilt: -5 }, { x: 0.58, y: 0.53, w: 0.58, h: 0.26, tilt: 3 },\n { x: 0.46, y: 0.64, w: 0.58, h: 0.26, tilt: -2 }],\n [{ role: 'headline', x: 0.5, y: 0.12, size: 0.05, weight: 900 },\n { role: 'caption', x: 0.5, y: 0.86, size: 0.032, weight: 600 }]),\n\n T('banner-row', 'Wide banner + small row', 'one wide scene, details under', 2,\n [{ x: 0.5, y: 0.36, w: 0.84, h: 0.36 }, { x: 0.25, y: 0.77, w: 0.24, h: 0.26 },\n { x: 0.5, y: 0.77, w: 0.24, h: 0.26 }, { x: 0.75, y: 0.77, w: 0.24, h: 0.26 }],\n [{ role: 'headline', x: 0.5, y: 0.09, size: 0.065, weight: 900 }],\n [{ x: 0.5, y: 0.36, w: 0.86, h: 0.26 }, { x: 0.22, y: 0.66, w: 0.28, h: 0.16 },\n { x: 0.5, y: 0.66, w: 0.28, h: 0.16 }, { x: 0.78, y: 0.66, w: 0.28, h: 0.16 }],\n [{ role: 'headline', x: 0.5, y: 0.13, size: 0.05, weight: 900 },\n { role: 'caption', x: 0.5, y: 0.82, size: 0.032, weight: 600 }]),\n\n T('quadrant-labels', 'Quadrants with labels', 'four named things', 4,\n [{ x: 0.28, y: 0.3, w: 0.3, h: 0.3 }, { x: 0.72, y: 0.3, w: 0.3, h: 0.3 },\n { x: 0.28, y: 0.71, w: 0.3, h: 0.3 }, { x: 0.72, y: 0.71, w: 0.3, h: 0.3 }],\n [{ role: 'headline', x: 0.5, y: 0.07, size: 0.06, weight: 900 },\n { role: 'label', x: 0.28, y: 0.49, size: 0.042, weight: 800 },\n { role: 'label', x: 0.72, y: 0.49, size: 0.042, weight: 800 },\n { role: 'label', x: 0.28, y: 0.9, size: 0.042, weight: 800 },\n { role: 'label', x: 0.72, y: 0.9, size: 0.042, weight: 800 }],\n [{ x: 0.28, y: 0.32, w: 0.38, h: 0.2 }, { x: 0.72, y: 0.32, w: 0.38, h: 0.2 },\n { x: 0.28, y: 0.64, w: 0.38, h: 0.2 }, { x: 0.72, y: 0.64, w: 0.38, h: 0.2 }],\n [{ role: 'headline', x: 0.5, y: 0.1, size: 0.045, weight: 900 },\n { role: 'label', x: 0.28, y: 0.45, size: 0.028, weight: 800 },\n { role: 'label', x: 0.72, y: 0.45, size: 0.028, weight: 800 },\n { role: 'label', x: 0.28, y: 0.77, size: 0.028, weight: 800 },\n { role: 'label', x: 0.72, y: 0.77, size: 0.028, weight: 800 }]),\n\n T('pyramid-3', 'Pyramid of three', 'one above two', 3,\n [{ x: 0.5, y: 0.32, w: 0.3, h: 0.32 }, { x: 0.32, y: 0.71, w: 0.3, h: 0.32 }, { x: 0.68, y: 0.71, w: 0.3, h: 0.32 }],\n [{ role: 'headline', x: 0.5, y: 0.08, size: 0.065, weight: 900 },\n { role: 'caption', x: 0.5, y: 0.92, size: 0.04, weight: 600 }],\n [{ x: 0.5, y: 0.34, w: 0.5, h: 0.22 }, { x: 0.27, y: 0.62, w: 0.42, h: 0.18 }, { x: 0.73, y: 0.62, w: 0.42, h: 0.18 }],\n [{ role: 'headline', x: 0.5, y: 0.1, size: 0.05, weight: 900 },\n { role: 'caption', x: 0.5, y: 0.79, size: 0.032, weight: 600 }]),\n\n T('mosaic-dense', 'Dense mosaic', 'everything at once', 5,\n [{ x: 0.3, y: 0.4, w: 0.34, h: 0.42 }, { x: 0.62, y: 0.29, w: 0.24, h: 0.26 }, { x: 0.86, y: 0.33, w: 0.2, h: 0.28 },\n { x: 0.19, y: 0.78, w: 0.24, h: 0.26 }, { x: 0.47, y: 0.77, w: 0.26, h: 0.28 }, { x: 0.73, y: 0.73, w: 0.22, h: 0.24 },\n { x: 0.91, y: 0.76, w: 0.14, h: 0.18 }],\n [{ role: 'headline', x: 0.5, y: 0.09, size: 0.06, weight: 900 }],\n [{ x: 0.32, y: 0.3, w: 0.5, h: 0.2 }, { x: 0.78, y: 0.26, w: 0.36, h: 0.16 }, { x: 0.24, y: 0.52, w: 0.4, h: 0.16 },\n { x: 0.68, y: 0.5, w: 0.44, h: 0.18 }, { x: 0.3, y: 0.74, w: 0.42, h: 0.16 }, { x: 0.74, y: 0.73, w: 0.4, h: 0.16 },\n { x: 0.5, y: 0.89, w: 0.5, h: 0.1 }],\n [{ role: 'headline', x: 0.5, y: 0.1, size: 0.045, weight: 900 }]),\n];\n\nconst byId = new Map(CANVAS_TEMPLATES.map((t) => [t.id, t]));\nconst getCanvasTemplate = (id) => byId.get(id) || null; // unknown/renamed id → no template (never a load failure)\n\n// The layout for a given canvas aspect: tall frames (ratio < 1) use the\n// portrait variant, everything else the landscape one.\nfunction templateLayout(template, aspect = 16 / 9) {\n if (!template) return null;\n return aspect < 1\n ? { slots: template.pSlots, textSlots: template.pTextSlots }\n : { slots: template.slots, textSlots: template.textSlots };\n}\n\n// ── Reflow: elements → a template's slots (pure, non-destructive) ───────────\n// Unpinned IMAGES fill image slots in appear order; unpinned TEXTS fill text\n// slots in slot order (headline first, as authored). EVERY SLOT IS OPTIONAL:\n// fewer elements than slots just leaves the extra slots empty. Elements\n// beyond the slots OVERFLOW: images lose their box (back to natural-aspect\n// sizing) and get pos:null so the S10 spiral places them around the slotted\n// ones; extra texts keep their position. PINNED elements are never touched —\n// the pin IS the manual override, and it survives every template switch.\n// TIMING IS NEVER TOUCHED: appearMs/leaveMs pass through untouched, so each\n// element still pops on its own voiceover beat.\nfunction applyTemplateToElements(elements, template, { aspect = 16 / 9 } = {}) {\n if (!template) {\n // Clearing a template touches ONLY slot-derived elements (the ones with a\n // box): the box comes off, the position STAYS — on an auto canvas the\n // spiral re-places unpinned elements anyway, and on a manual canvas the\n // old slot spot is a sane resting place (never a pos:null pile at\n // center, never a wipe of hand placements that were never slotted).\n return (elements || []).map((el) => {\n if (el.pinned || el.kind !== 'image' || !el.box) return el;\n const { box, ...rest } = el;\n return rest;\n });\n }\n const layout = templateLayout(template, aspect);\n const byAppear = (a, b) => (a.appearMs || 0) - (b.appearMs || 0);\n const images = (elements || []).filter((el) => el.kind === 'image' && !el.pinned).sort(byAppear);\n const texts = (elements || []).filter((el) => el.kind === 'text' && !el.pinned).sort(byAppear);\n const imgSlot = new Map();\n images.forEach((el, i) => { if (i < layout.slots.length) imgSlot.set(el.id, layout.slots[i]); });\n const textSlot = new Map();\n texts.forEach((el, i) => { if (i < layout.textSlots.length) textSlot.set(el.id, layout.textSlots[i]); });\n return (elements || []).map((el) => {\n if (el.pinned) return el;\n if (el.kind === 'image') {\n const s = imgSlot.get(el.id);\n if (!s) { const { box, ...rest } = el; return { ...rest, pos: null }; } // overflow → spiral\n return { ...el, pos: { x: s.x, y: s.y }, box: { w: s.w, h: s.h }, size: s.w, tilt: s.tilt || 0 };\n }\n const s = textSlot.get(el.id);\n if (!s) return el; // extra text keeps its place\n return { ...el, pos: { x: s.x, y: s.y }, size: s.size, weight: s.weight || el.weight || 800 };\n });\n}\n\n// ── Auto-pick (post-approval spec): image count + scenario hint ─────────────\n// The hint is the planner's free-text reason for the beat; keyword classes\n// beat pure counts (compare → side-by-side, steps/list → row, many → mosaic).\n// Returns a template id or null (no fit → the plain self-arranging layout).\nfunction pickTemplateForCanvas({ imageCount = 0, textCount = 0, hint = '' } = {}) {\n if (!imageCount) return null;\n const h = String(hint || '').toLowerCase();\n if (imageCount === 2 && /\\\\bvs\\\\b|versus|compar|before.*after|either/.test(h)) return 'compare-2';\n if (imageCount >= 3 && /step|order|sequence|timeline|process|journey|stages/.test(h)) return 'timeline-row';\n if (imageCount >= 3 && /list|lists|enumerat|items|examples|types|kinds/.test(h)) return imageCount >= 5 ? 'mosaic-dense' : 'three-across';\n if (imageCount === 1) return textCount > 1 ? 'large-caption' : 'hero-headline';\n if (imageCount === 2) return 'compare-2';\n if (imageCount === 3) return 'three-across';\n if (imageCount === 4) return 'grid-2x2';\n if (imageCount === 5) return 'center-satellites';\n if (imageCount <= 7) return 'mosaic-dense';\n return 'grid-3x3';\n}\n\nconst hash = (s) => {\n let h = 5381;\n const str = String(s || '');\n for (let i = 0; i < str.length; i++) h = ((h << 5) + h + str.charCodeAt(i)) >>> 0;\n return h;\n};\n// Deterministic pseudo-jitter in [-1, 1] from an id + salt.\nconst jitter = (id, salt) => ((hash(\\`\\${id}|\\${salt}\\`) % 2000) / 1000) - 1;\n\n// ── Self-arranging layout (S10) ──────────────────────────────────────────────\n// Applies to AUTO-ARRANGED canvases only (panel.autoArrange). Deterministic\n// greedy placement in APPEAR ORDER: each unpinned image takes the best slot on\n// a golden-angle spiral around the canvas center — maximizing distance from\n// every element already visible when it appears — so the composition stays\n// balanced as it accumulates without ever moving an already-placed element\n// (tidy-by-construction; nothing jumps). PINNED elements (user overrides) and\n// manual canvases keep their positions exactly; auto elements arrange AROUND\n// pinned ones (they're obstacles in the distance test).\nconst SPIRAL_SLOTS = 48;\nconst GOLDEN = 2.399963229728653; // golden angle (rad)\nfunction spiralSlot(k, aspect = 16 / 9) {\n // Slots sweep outward from the center, filling the frame evenly; x spread is\n // wider than y for landscape canvases.\n const r = 0.08 + 0.40 * Math.sqrt((k + 0.5) / SPIRAL_SLOTS);\n const a = k * GOLDEN;\n return { x: 0.5 + r * Math.cos(a), y: 0.5 + r * Math.sin(a) * (aspect > 1 ? 0.9 : 1.1) };\n}\nconst clamp01 = (v, lo, hi) => Math.max(lo, Math.min(hi, v));\n\nfunction arrangeCanvas(panel, { aspect = 16 / 9 } = {}) {\n const els = (panel?.elements || []).slice().sort((a, b) => (a.appearMs || 0) - (b.appearMs || 0));\n const placed = []; // { x, y, size, appearMs, leaveMs }\n const out = new Map();\n for (const el of els) {\n const half = (el.kind === 'image' ? (el.size || 0.28) : 0.18) / 2;\n if (el.pinned || !panel.autoArrange) {\n if (el.pos) { placed.push({ ...el.pos, size: el.size || 0.28, appearMs: el.appearMs, leaveMs: el.leaveMs }); out.set(el.id, el.pos); }\n continue;\n }\n // Distance test only against elements VISIBLE when this one appears —\n // an element that already LEFT frees its space.\n const visible = placed.filter((p) => (p.leaveMs == null || p.leaveMs > el.appearMs));\n let best = null; let bestScore = -Infinity;\n for (let k = 0; k < SPIRAL_SLOTS; k++) {\n // Slot order is salted per-element id so different canvases don't all\n // start identically, while staying fully deterministic.\n const slot = spiralSlot((k + (hash(el.id) % SPIRAL_SLOTS)) % SPIRAL_SLOTS, aspect);\n const x = clamp01(slot.x, half + 0.03, 1 - half - 0.03);\n const y = clamp01(slot.y, half + 0.05, 1 - half - 0.05);\n let minD = Infinity;\n for (const p of visible) minD = Math.min(minD, Math.hypot(x - p.x, y - p.y) - (p.size || 0.28) / 2 - half);\n const centerPull = -0.12 * Math.hypot(x - 0.5, y - 0.5); // gentle balance toward center\n const score = (visible.length ? Math.min(minD, 0.5) : 0.3) + centerPull;\n if (score > bestScore) { bestScore = score; best = { x, y }; }\n }\n const pos = best || { x: 0.5, y: 0.5 };\n // A hair of deterministic scatter so the collage reads hand-placed.\n pos.x = clamp01(pos.x + jitter(el.id, 'x') * 0.015, half, 1 - half);\n pos.y = clamp01(pos.y + jitter(el.id, 'y') * 0.015, half, 1 - half);\n placed.push({ ...pos, size: el.size || 0.28, appearMs: el.appearMs, leaveMs: el.leaveMs });\n out.set(el.id, pos);\n }\n return out; // elementId -> {x, y}\n}\n// Stamp arranged positions onto the elements (unpinned only) — the STORED\n// positions are what every renderer reads, so preview == export.\nfunction withArrangedPositions(panel, opts) {\n if (!panel.autoArrange) return panel;\n const posMap = arrangeCanvas(panel, opts);\n return {\n ...panel,\n elements: (panel.elements || []).map((el) => (\n !el.pinned && posMap.has(el.id) ? { ...el, pos: posMap.get(el.id) } : el\n )),\n };\n}\n\n\nfunction docAspectRatio(doc) {\n const a = doc?.meta?.aspect || '16:9';\n if (a === '9:16') return 9 / 16;\n if (a === '1:1') return 1;\n return 16 / 9;\n}\nfunction rearranged(doc, panel) {\n // TEMPLATE (bundled slot layout): the template sets the STRUCTURE — slotted\n // elements go to their slots; the S10 spiral only places the OVERFLOW,\n // treating slotted elements as obstacles. Applies to auto AND templated\n // manual canvases (opting into a template IS asking for arrangement); a\n // plain manual canvas stays untouched. Pinned elements never move.\n const template = getCanvasTemplate(panel.template);\n if (template) {\n const slotted = applyTemplateToElements(panel.elements || [], template, { aspect: docAspectRatio(doc) });\n const overflowPanel = {\n ...panel,\n autoArrange: true,\n elements: slotted.map((el) => (el.pos ? { ...el, pinned: true } : el)), // slots+pins = obstacles for the spiral\n };\n const posMap = arrangeCanvas(overflowPanel, { aspect: docAspectRatio(doc) });\n return {\n ...panel,\n elements: slotted.map((el) => (!el.pinned && !el.pos && posMap.has(el.id) ? { ...el, pos: posMap.get(el.id) } : el)),\n };\n }\n return panel.autoArrange ? withArrangedPositions(panel, { aspect: docAspectRatio(doc) }) : panel;\n}\n\nfunction patchCanvasElement(doc, panelId, elementId, patch, { freezeLayout = false } = {}) {\n const panel = doc.strip.find((p) => p.panelId === panelId);\n if (!panel || panel.type !== 'canvas') throw new Error(\\`patchCanvasElement: \\${panelId} is not a canvas panel\\`);\n const strip = doc.strip.map((p) => {\n if (p.panelId !== panelId) return p;\n const next = {\n ...p,\n elements: (p.elements || []).map((el) => (el.id === elementId ? { ...el, ...patch } : el)),\n };\n return freezeLayout ? next : rearranged(doc, next);\n });\n return loadPanelDoc({ ...doc, strip });\n}\n\n\nconst loadPanelDoc=doc=>doc;return {edit:patchCanvasElement(input.doc,input.panelId,input.elementId,input.patch,{freezeLayout:input.freezeLayout})};`,tests:[]},vr=(e,t)=>V(e)===V(t),yr=[`pos`,`box`,`size`,`tilt`,`weight`],br=[`id`,`kind`,`pinned`,`appearMs`,`leaveMs`,...yr],xr=new Set([`src`,`poster`,`source`,`query`,`text`,`pose`,`cutout`,`durationSec`,`sfx`,`entrance`,`shadow`,`font`,`color`,`anim`,`loop`,`muted`,`trimStartSec`,`speed`,`motion`,`pinned`,`appearMs`,`leaveMs`,...yr]),Sr=(e,t)=>e===`pos`&&L(t)?{x:t.x,y:t.y}:e===`box`&&L(t)?{w:t.w,h:t.h}:t;function Cr(e,t,n,r,i){let a=e.strip.find(e=>e.panelId===t);I(a?.type===`canvas`&&Array.isArray(a.elements)&&typeof n==`string`&&L(r)&&Object.keys(r).every(e=>xr.has(e)),`CANVAS_PATCH`,`Choose a supported edit on the current canvas.`);let o=structuredClone(r),s={};B(o);for(let[e,t]of Object.entries(o))s[e]=br.includes(e)?Sr(e,t):{patchToken:e};let c={panelId:t,type:`canvas`,elements:a.elements.map((e,t)=>{let n={origin:t};for(let t of br)e[t]!==void 0&&(n[t]=Sr(t,e[t]));return n})};for(let e of[`template`,`autoArrange`])a[e]!==void 0&&(c[e]=a[e]);let l={doc:{meta:{aspect:e.meta?.aspect||`16:9`},strip:[c]},panelId:t,elementId:n,patch:s,freezeLayout:!!i};return B(l),{panel:a,input:l,captured:o}}function wr(e){let t=e.doc.strip[0],n={...t,elements:t.elements.map(t=>t.id===e.elementId?{...t,...e.patch}:t)};if(!e.freezeLayout){let r=e.doc.meta.aspect===`9:16`?9/16:e.doc.meta.aspect===`1:1`?1:16/9,i=en(t.template);if(i){let e=nn(n.elements,i,{aspect:r}),t=kt({...n,autoArrange:!0,elements:e.map(e=>e.pos?{...e,pinned:!0}:e)},{aspect:r});n={...n,elements:e.map(e=>!e.pinned&&!e.pos&&t.has(e.id)?{...e,pos:t.get(e.id)}:e)}}else n.autoArrange&&(n=At(n,{aspect:r}))}return{...e.doc,strip:[n]}}function Tr(e,{panel:t,input:n,captured:r},i){let a=wr(n);B(a),B(i),I(vr(i,a),`CANVAS_PATCH`,`The sandbox changed an unrequested element or layout.`);let o=!1,s=i.strip[0].elements.map((e,i)=>{let s=t.elements[i],c=n.doc.strip[0].elements[i],l=a.strip[0].elements[i],u=s.id===n.elementId,d=s;for(let t of new Set([...yr,...u?Object.keys(r):[]])){let i=Object.hasOwn(l,t),a=e[t];u&&Object.hasOwn(r,t)&&!yr.includes(t)?(i=!0,a=r[t]):i&&l[t]!==null&&typeof l[t]==`object`&&(u&&Object.hasOwn(r,t)&&l[t]===n.patch[t]?a=r[t]:l[t]===c[t]&&(a=s[t])),(Object.hasOwn(s,t)!==i||i&&!vr(s[t],a))&&(d===s&&(d={...s}),i?d[t]=a:delete d[t])}return d!==s&&(o=!0),d});return o?{...e,strip:e.strip.map(e=>e===t?{...t,elements:s}:e)}:e}function Er(e,t,n){let r=e?.strip?.find(e=>e.panelId===t);I(Array.isArray(e?.strip)&&e.strip.length<=4096&&r?.elements?.length<=512,`CANVAS_STOCK`,`The canvas exceeds supported stock-sourcing bounds.`),I(e.strip.filter(e=>e.panelId===t).length===1,`CANVAS_STOCK`,`This canvas has an ambiguous panel ID. Resolve it before sourcing stock.`),I(r.elements.filter(e=>e.id===n).length===1,`CANVAS_STOCK`,`Choose one existing canvas element before sourcing stock.`);let i=Cr(e,t,n,{src:null,source:`stock`},!1);I(JSON.stringify(i.input).length<=1048576,`CANVAS_STOCK`,`The canvas metadata exceeds 1 MiB.`)}async function Dr(e,t,n,r,{signal:i,assertCurrent:a,validateDocument:o,host:s}){let c=H(s),l=c.actor(),u=V(e),d=()=>{a(),I(l&&c.actor()===l&&!i?.aborted&&V(e)===u,`STALE`,`The account or stock target changed.`)};d(),Er(e,t,n),I(typeof r==`string`&&r,`CANVAS_STOCK`,`The stock result has no image.`);let f=Cr(e,t,n,{src:r,source:`stock`},!1),p=await c.run(_r,{kind:`run`,input:f.input,signal:i,timeoutMs:15e3});d();let m=Tr(e,f,p.outputs?.edit);return m===e?e:o(m)}function Or({doc:e,projectId:t,panelId:n,canEdit:r,onDocChange:i,validateDocument:a,editLease:o,host:s}){let c=H(s),l=()=>c.actor(),[u,d]=(0,v.useState)(null),[f,p]=(0,v.useState)(``),m=(0,v.useRef)(null),h=(0,v.useRef)(!0),g=(0,v.useRef)(0),_=(0,v.useRef)(null),y=l();_.current={doc:e,projectId:t,panelId:n,canEdit:r,onDocChange:i,validateDocument:a,actor:y,services:c};let b=(0,v.useCallback)(()=>{g.current++,o?.current===m.current&&(o.current=null),m.current?.abort(),m.current=null,d(null)},[o]);return(0,v.useEffect)(()=>(h.current=!0,()=>{h.current=!1,g.current++,o?.current===m.current&&(o.current=null),m.current?.abort(),m.current=null}),[]),(0,v.useEffect)(()=>{b()},[e,t,n,r,y,c,b]),{change:(0,v.useCallback)(async(r,i,a=!1)=>{let s=_.current;if(!s.doc||!s.canEdit||m.current||o?.current)return;if(s.services!==c||s.doc!==e||s.projectId!==t||s.panelId!==n||s.actor!==y||l()!==y){p(`The canvas changed before this edit was ready. Review the current element again.`);return}let u=++g.current,f=new AbortController;m.current=f,o&&(o.current=f),d(r),p(``);let v,b=()=>{let e=_.current;I(h.current&&m.current===f&&!f.signal.aborted&&e.doc===s.doc&&e.projectId===s.projectId&&e.panelId===s.panelId&&e.canEdit&&e.services===c&&e.actor===s.actor&&l()===s.actor&&JSON.stringify(s.doc)===v,`STALE`,`The canvas changed. Review the current element settings again.`)};try{v=JSON.stringify(s.doc);let e=Cr(s.doc,s.panelId,r,i,a);b();let t=await c.run(_r,{kind:`run`,input:e.input,signal:f.signal,timeoutMs:15e3});b();let n=Tr(s.doc,e,t.outputs?.edit),o=n===s.doc?s.doc:s.validateDocument(n);if(b(),o!==s.doc){let e=JSON.stringify(o),t=!1;s.onDocChange(n=>{let r=_.current,i=!1;try{i=h.current&&g.current===u&&!f.signal.aborted&&r.doc===s.doc&&r.projectId===s.projectId&&r.panelId===s.panelId&&r.canEdit&&r.services===c&&r.actor===s.actor&&l()===s.actor&&JSON.stringify(o)===e&&JSON.stringify(n)===v&&JSON.stringify(s.doc)===v}catch{}return i?o:(t||(t=!0,queueMicrotask(()=>{h.current&&l()===s.actor&&_.current.projectId===s.projectId&&p(`The canvas changed before the element edit could be saved. Review the current element settings again.`)})),n)})}return o}catch(e){h.current&&!f.signal.aborted&&l()===s.actor&&_.current.projectId===s.projectId&&p(e.message||`The element edit could not be applied.`)}finally{m.current===f&&(o?.current===f&&(o.current=null),m.current=null,h.current&&d(null))}},[e,t,n,y,c]),pending:u,error:f,cancel:b}}let kr={manifest:{schemaVersion:1,sdkVersion:`0.1.0`,id:`stillmade-internal.planning-beat-merge`,version:`1.0.0`,name:`Panel planning beat merge`,description:`Merge the existing GIF and canvas planner beats before timing assembly.`,kind:`task`,runtime:`javascript`,inputs:{action:{type:`text`},strip:{type:`json`},beats:{type:`json`}},outputs:{edit:{type:`json`}},permissions:{project:[],network:[],filesystem:[],secrets:[]}},code:`function mergeGifBeatsIntoPlan(planStrip, beats) {\n const strip = Array.isArray(planStrip) ? planStrip.slice() : [];\n const overlays = [];\n if (!Array.isArray(beats) || !beats.length) return { strip, overlays };\n const used = new Set(strip.map((p) => String(p?.panelId || '')));\n let n = 0;\n const nextId = () => { let id; do { id = \\`gif\\${++n}\\`; } while (used.has(id)); used.add(id); return id; };\n for (const b of beats) {\n if (!b || typeof b !== 'object') continue;\n const ws = Math.max(0, Math.round(Number(b.wordStart) || 0));\n const we = Math.max(ws, Math.round(Number(b.wordEnd) || ws));\n const gifUrl = String(b.gifUrl || '').trim();\n if (b.mode === 'overlay') {\n const target = String(b.targetPanelId || '').trim();\n if (!target || !gifUrl) continue;\n overlays.push({\n targetPanelId: target,\n overlay: {\n gifUrl, mode: 'overlay',\n ...(b.gifQuery ? { gifQuery: String(b.gifQuery) } : {}),\n wordStart: ws, wordEnd: we,\n },\n });\n continue;\n }\n if (!gifUrl) continue;\n // Insert after the last entry that starts at or before this beat's first\n // word (never before the strip's first entry, so a scene never opens on a\n // GIF). Scanning the live strip each time keeps the splice index valid.\n let idx = 0;\n for (let i = 0; i < strip.length; i++) {\n if ((Number(strip[i]?.wordStart) || 0) <= ws) idx = i;\n }\n const anchor = strip[idx];\n if (!anchor) continue;\n strip.splice(idx + 1, 0, {\n panelId: nextId(), type: 'giphy', sceneId: anchor.sceneId, mode: 'replace',\n gif: gifUrl,\n ...(b.gifQuery ? { gifQuery: String(b.gifQuery) } : {}),\n ...(Array.isArray(b.candidates) && b.candidates.length\n ? { candidates: b.candidates.map((c) => String(c?.gifUrl || c || '')).filter(Boolean) } : {}),\n ...(b.tone ? { tone: String(b.tone) } : {}),\n wordStart: ws, wordEnd: we, transitionIn: 'cut',\n });\n }\n return { strip, overlays };\n}\n\n// ── COLLAGE CANVAS auto-insertion (spec S6, toggle ON) ───────────────────────\n// Fold the canvas planner's spans into the PLANNER strip before assembly: the\n// canvas REPLACES the planned panels its word span fully covers (it IS that\n// stretch's visual — several sourced photos instead of generated illustrations)\n// and rides the same word-index → ms timing pass as every other beat. Entries\n// only partially overlapping stay. Safety: title screens, reveal groups,\n// repeats, and anything a surviving entry still references by id are never\n// removed (assembly re-points orphaned edit sources on its own).\nfunction mergeCanvasBeatsIntoPlan(planStrip, canvases) {\n const strip = Array.isArray(planStrip) ? planStrip.slice() : [];\n if (!Array.isArray(canvases) || !canvases.length) return { strip };\n const used = new Set(strip.map((p) => String(p?.panelId || '')));\n let n = 0;\n const nextId = () => { let id; do { id = \\`cv\\${++n}\\`; } while (used.has(id)); used.add(id); return id; };\n for (const c of canvases) {\n // A typewriter beat carries no events (its text is filled from the VO later),\n // so only require events for the normal photo-collage kind.\n const isTypewriter = c && c.mode === 'typewriter';\n if (!c || typeof c !== 'object' || (!isTypewriter && (!Array.isArray(c.events) || !c.events.length))) continue;\n const ws = Math.max(0, Math.round(Number(c.wordStart) || 0));\n const we = Math.max(ws, Math.round(Number(c.wordEnd) || ws));\n const inside = (p) => (Number(p.wordStart) || 0) >= ws && (Number(p.wordEnd) || 0) <= we;\n const removable = (p, i) => {\n if (!p || p.type === 'titleScreen' || p.type === 'canvas') return false;\n if (p.kind === 'revealStep' || p.method === 'progressiveReveal') return false;\n if (!inside(p)) return false;\n // referenced by an entry that will SURVIVE (outside the span)?\n return !strip.some((q, j) => j !== i && !inside(q) && (q.repeatOf === p.panelId || q.revealOf === p.panelId));\n };\n const removeIdx = strip.map((p, i) => (removable(p, i) ? i : -1)).filter((i) => i >= 0);\n // Insert at the first removed slot, else after the last entry starting ≤ ws\n // (never before the strip's first entry).\n let at = removeIdx.length ? removeIdx[0] : 0;\n if (!removeIdx.length) {\n for (let i = 0; i < strip.length; i++) if ((Number(strip[i]?.wordStart) || 0) <= ws) at = i + 1;\n }\n const anchorEntry = strip[Math.min(Math.max(0, at - (removeIdx.length ? 0 : 1)), strip.length - 1)];\n const row = {\n panelId: nextId(), type: 'canvas', sceneId: anchorEntry?.sceneId,\n // Typewriter beats are a hand-laid paragraph (pinned lines) → not\n // self-arranging; photo collages self-arrange as images accumulate.\n background: '#ffffff', autoArrange: !isTypewriter, planned: true, elements: [],\n ...(isTypewriter ? { mode: 'typewriter' } : { events: c.events }),\n ...(c.reason ? { hint: String(c.reason).slice(0, 200) } : {}),\n wordStart: ws, wordEnd: we, transitionIn: 'cut',\n };\n for (let k = removeIdx.length - 1; k >= 0; k--) strip.splice(removeIdx[k], 1);\n strip.splice(Math.min(at, strip.length), 0, row);\n }\n return { strip };\n}\n\n\nreturn {edit:input.action==='gif'?mergeGifBeatsIntoPlan(input.strip,input.beats):mergeCanvasBeatsIntoPlan(input.strip,input.beats)};\n`,tests:[]},Ar=new Set([`panelId`,`sceneId`,`wordStart`,`wordEnd`,`type`,`kind`,`method`,`repeatOf`,`revealOf`]);function jr(e,t,n){I(Array.isArray(e)&&e.length<=2048&&Array.isArray(t)&&t.length<=512&&[`gif`,`canvas`].includes(n),`PLAN_MERGE`,`The planner returned an unsupported beat list.`);let r=new Map,i=0,a=e=>{let t=`host-value-${i++}`;return r.set(t,e),t},o=e.map(e=>(I(L(e),`PLAN_MERGE`,`A planned row is invalid.`),Object.fromEntries(Object.entries(e).filter(([,e])=>e!==void 0).map(([e,t])=>[e,Ar.has(e)?t:a(t)])))),s={action:n,strip:o,beats:t.map(e=>{if(!L(e))return null;let t={wordStart:Math.max(0,Math.round(Number(e.wordStart)||0))};if(t.wordEnd=Math.max(t.wordStart,Math.round(Number(e.wordEnd)||t.wordStart)),n===`gif`){t.mode=e.mode===`overlay`?`overlay`:`replace`;let n=String(e.gifUrl||``).trim();t.gifUrl=n?a(n):``,e.targetPanelId&&(t.targetPanelId=String(e.targetPanelId).trim()),e.gifQuery&&(t.gifQuery=a(String(e.gifQuery))),e.tone&&(t.tone=a(String(e.tone))),Array.isArray(e.candidates)&&e.candidates.length&&(t.candidates=e.candidates.map(e=>String(e?.gifUrl||e||``)).map(e=>e?a(e):``))}else t.mode=e.mode===`typewriter`?`typewriter`:null,Array.isArray(e.events)&&(t.events=e.events.map(a)),e.reason&&(t.reason=a(String(e.reason).slice(0,200)));return t})};return B(s),{input:s,tokenValues:r,rows:o}}function Mr({strip:e,beats:t,action:n}){let r=e.slice(),i=[],a=new Set(r.map(e=>String(e?.panelId||``))),o=0,s=e=>{let t;do t=e+ ++o;while(a.has(t));return a.add(t),t};for(let e of t){if(!e)continue;let t=e.wordStart,a=e.wordEnd;if(n===`gif`){if(e.mode===`overlay`){e.targetPanelId&&e.gifUrl&&i.push({targetPanelId:e.targetPanelId,overlay:{gifUrl:e.gifUrl,mode:`overlay`,...e.gifQuery?{gifQuery:e.gifQuery}:{},wordStart:t,wordEnd:a}});continue}if(!e.gifUrl)continue;let n=0;r.forEach((e,r)=>{(Number(e.wordStart)||0)<=t&&(n=r)});let o=r[n];if(!o)continue;r.splice(n+1,0,{panelId:s(`gif`),type:`giphy`,sceneId:o.sceneId,mode:`replace`,gif:e.gifUrl,...e.gifQuery?{gifQuery:e.gifQuery}:{},...e.candidates?.length?{candidates:e.candidates.filter(Boolean)}:{},...e.tone?{tone:e.tone}:{},wordStart:t,wordEnd:a,transitionIn:`cut`})}else{let n=e.mode===`typewriter`;if(!n&&!e.events?.length)continue;let i=e=>(Number(e.wordStart)||0)>=t&&(Number(e.wordEnd)||0)<=a,o=[];r.forEach((e,t)=>{e.type!==`titleScreen`&&e.type!==`canvas`&&e.kind!==`revealStep`&&e.method!==`progressiveReveal`&&i(e)&&(r.some((n,r)=>r!==t&&!i(n)&&(n.repeatOf===e.panelId||n.revealOf===e.panelId))||o.push(t))});let c=o.length?o[0]:0;o.length||r.forEach((e,n)=>{(Number(e.wordStart)||0)<=t&&(c=n+1)});let l=r[Math.min(Math.max(0,c-+!o.length),r.length-1)],u={panelId:s(`cv`),type:`canvas`,sceneId:l?.sceneId,background:`#ffffff`,autoArrange:!n,planned:!0,elements:[],...n?{mode:`typewriter`}:{events:e.events},...e.reason?{hint:e.reason}:{},wordStart:t,wordEnd:a,transitionIn:`cut`};for(let e=o.length-1;e>=0;e--)r.splice(o[e],1);r.splice(Math.min(c,r.length),0,u)}}return n===`gif`?{strip:r,overlays:i}:{strip:r}}async function Nr(e,t,n,{signal:r,check:i,host:a}){let o=H(a),s=o.actor(),c=()=>{i(),I(!r?.aborted&&s&&o.actor()===s,`STALE`,`The account or planning request changed. Review the current plan again.`)};c();let l=V({strip:t,beats:n}),u=jr(t,n,e),d=Mr(u.input),f=JSON.parse(JSON.stringify(d));B(f);let p=await o.run(kr,{kind:`run`,input:u.input,signal:r,timeoutMs:15e3});c(),I(V({strip:t,beats:n})===l,`STALE`,`The planned rows or beats changed while the sandbox was running.`),B(p.outputs?.edit),I(V(p.outputs.edit)===V(f),`PLAN_MERGE`,`The sandbox changed an unrelated planned beat.`);let m=e=>(I(u.tokenValues.has(e),`PLAN_MERGE`,`An inserted value lost its host receipt.`),u.tokenValues.get(e)),h=d.strip.map(e=>{let n=u.rows.indexOf(e);if(n>=0)return t[n];let r={...e};if(e.type===`giphy`){r.gif=m(e.gif);for(let t of[`gifQuery`,`tone`])e[t]&&(r[t]=m(e[t]));e.candidates&&(r.candidates=e.candidates.map(m))}else e.events&&(r.events=e.events.map(m)),e.hint&&(r.hint=m(e.hint));return r}),g=d.overlays?.map(e=>({...e,overlay:{...e.overlay,gifUrl:m(e.overlay.gifUrl),...e.overlay.gifQuery?{gifQuery:m(e.overlay.gifQuery)}:{}}}));return e===`gif`?{strip:h,overlays:g}:{strip:h}}let Pr={manifest:{schemaVersion:1,sdkVersion:`0.1.0`,id:`stillmade-internal.consistency-result`,version:`1.0.0`,name:`Panel consistency result`,description:`Apply captured style warnings and flag chains whose base was regenerated.`,kind:`task`,runtime:`javascript`,inputs:{rows:{type:`json`},offenders:{type:`json`},mode:{type:`json`}},outputs:{edit:{type:`json`}},permissions:{project:[],network:[],filesystem:[],secrets:[]}},code:`function applyConsistency(input){\n let rows=input.rows.map(p=>({...p}));\n if(input.mode==='warnings'){\n for(const o of input.offenders){const first=rows.find(p=>p.panelId===o.panelId);if(!first)continue;const patch={styleStrict:true,styleWarning:o.issue||'style differs from the anchor',provenance:first.provenance||'auto'};rows=rows.map(p=>p.panelId===o.panelId?{...p,...patch}:p);}\n }else{\n for(const o of input.offenders){const base=rows.find(p=>p.panelId===o.panelId);if(base?.kind!=='base'||base.styleWarning)continue;const affected=new Set([base.panelId]),ids=[];for(const p of rows)if(p.kind==='edit'&&p.sourcePanelId&&affected.has(p.sourcePanelId)){affected.add(p.panelId);ids.push(p.panelId);}for(const id of ids){const first=rows.find(p=>p.panelId===id);rows=rows.map(p=>p.panelId===id?{...p,needsRefresh:true,provenance:first?.provenance||'auto'}:p);}}\n }\n return {rows};\n}\n\nreturn {edit:applyConsistency(input)};`,tests:[]};async function Fr(e,t,n,{mode:r,signal:i,assertCurrent:a,host:o}){let s=H(o),c=s.actor(),l=()=>V({doc:e,offenders:t,eligible:n instanceof Set?[...n]:null}),u=l(),d=()=>{a(),I(c&&s.actor()===c&&!i?.aborted&&l()===u,`STALE`,`The account or style-check evidence changed.`)};d(),I([`warnings`,`refresh`].includes(r)&&Array.isArray(e?.strip)&&e.strip.length<=4096&&Array.isArray(t)&&t.length<=1024&&n instanceof Set,`CONSISTENCY`,`The consistency result is unavailable.`),I(t.every(e=>e&&n.has(e.panelId)&&(!e.issue||typeof e.issue==`string`)),`CONSISTENCY`,`The style check returned a panel outside its captured request.`);let f=[`panelId`,`kind`,`sourcePanelId`,`styleStrict`,`styleWarning`,`provenance`,`needsRefresh`],p={mode:r,rows:e.strip.map((e,t)=>({origin:t,...Object.fromEntries(f.filter(t=>e[t]!==void 0).map(t=>[t,e[t]]))})),offenders:t.map(e=>({panelId:e.panelId,...e.issue===void 0?{}:{issue:e.issue}}))};B(p),I(JSON.stringify(p).length<=1048576,`CONSISTENCY`,`The style result is too large.`);let m=p.rows.map(e=>({...e}));if(r===`warnings`)for(let e of p.offenders){let t=m.find(t=>t.panelId===e.panelId);if(t){let n={styleStrict:!0,styleWarning:e.issue||`style differs from the anchor`,provenance:t.provenance||`auto`};m=m.map(t=>t.panelId===e.panelId?{...t,...n}:t)}}else for(let e of p.offenders){let t=m.find(t=>t.panelId===e.panelId);if(t?.kind!==`base`||t.styleWarning)continue;let n=new Set([t.panelId]),r=[];for(let e of m)e.kind===`edit`&&e.sourcePanelId&&n.has(e.sourcePanelId)&&(n.add(e.panelId),r.push(e.panelId));for(let e of r){let t=m.find(t=>t.panelId===e);m=m.map(n=>n.panelId===e?{...n,needsRefresh:!0,provenance:t?.provenance||`auto`}:n)}}let h=await s.run(Pr,{kind:`run`,input:p,signal:i,timeoutMs:15e3});d(),B(h.outputs?.edit),I(V(h.outputs.edit)===V({rows:m}),`CONSISTENCY`,`The sandbox changed unrelated style or source fields.`);let g=h.outputs.edit.rows.map((t,n)=>{let r=e.strip[n];return V(t)===V(p.rows[n])?r:{...r,...Object.fromEntries([`styleStrict`,`styleWarning`,`provenance`,`needsRefresh`].filter(e=>t[e]!==void 0).map(e=>[e,t[e]]))}});return g.every((t,n)=>t===e.strip[n])?e:q({...e,strip:g})}let Ir={manifest:{schemaVersion:1,sdkVersion:`0.1.0`,id:`stillmade-internal.cast-reference-acceptance`,version:`1.0.0`,name:`Cast reference acceptance`,description:`Apply a generated cast reference and flag the existing built bases that use it.`,kind:`task`,runtime:`javascript`,inputs:{doc:{type:`json`},sheetId:{type:`text`},url:{type:`text`}},outputs:{edit:{type:`json`}},permissions:{project:[],network:[],filesystem:[],secrets:[]}},code:`// Original reference receipt merge and built-base refresh loop, on an opaque document.\nfunction updatePanel(doc,panelId,patch){return {...doc,strip:doc.strip.map(p=>p.panelId===panelId?{...p,...patch,provenance:patch.provenance||'user'}:p)};}\nfunction acceptReference(doc,sheetId,url){\n let next={...doc,meta:{...(doc.meta||{}),castRefs:{...(doc.meta?.castRefs||{}),[sheetId]:url}}};\n for(const p of next.strip){\n if(p.kind==='base'&&p.image&&(next.lineages?.[p.lineageId]?.sheetIds||[]).includes(sheetId)){\n next=updatePanel(next,p.panelId,{needsRefresh:true,provenance:p.provenance||'auto'});\n }\n }\n return next;\n}\nreturn {edit:acceptReference(input.doc,input.sheetId,input.url)};\n`,tests:[]};async function Lr(e,t,n,{signal:r,check:i,validateDocument:a,host:o}){let s=H(o),c=s.actor(),l=V(e),u=()=>{i(),I(c&&s.actor()===c&&!r?.aborted&&V(e)===l,`STALE`,`The account or character-reference document changed before acceptance.`)};u(),I(e&&Array.isArray(e.strip)&&e.strip.length<=2048&&typeof t==`string`&&t.length>0&&t.length<=512&&typeof n==`string`&&n.length>0&&n.length<=16384,`CAST_REFERENCE`,`The reference result or project is unavailable.`);let d=new Map,f=e=>(d.has(e)||d.set(e,`lineage-${d.size}`),d.get(e)),p=e.strip.map((e,t)=>({panelId:e.panelId,kind:e.kind===`base`?`base`:`other`,image:e.image?`host-image`:null,lineageId:f(e.lineageId),needsRefresh:{old:t},provenance:e.provenance?`provenance-${t}`:null})),m=Object.fromEntries([...d].map(([n,r])=>[r,{sheetIds:(e.lineages?.[n]?.sheetIds||[]).includes(t)?[`selected-sheet`]:[]}])),h={doc:{meta:{castRefs:{previous:`host-references`}},strip:p,lineages:m},sheetId:`selected-sheet`,url:`generated-reference`};B(h);let g={...h.doc,meta:{...h.doc.meta,castRefs:{...h.doc.meta.castRefs,[h.sheetId]:h.url}},strip:p.slice()};for(let e of p)e.kind===`base`&&e.image&&m[e.lineageId].sheetIds.includes(h.sheetId)&&(g.strip=g.strip.map(t=>t.panelId===e.panelId?{...t,needsRefresh:!0,provenance:e.provenance||`auto`}:t));let _=await s.run(Ir,{kind:`run`,input:h,signal:r,timeoutMs:15e3});u(),B(_.outputs?.edit),B(g),I(V(_.outputs.edit)===V(g),`CAST_REFERENCE`,`The sandbox changed unrelated reference or panel data.`);let v=e.strip.map((t,n)=>{let r=g.strip[n];if(r.needsRefresh!==!0)return t;let i=r.provenance===`auto`?`auto`:e.strip[Number(r.provenance.slice(11))].provenance;return t.needsRefresh===!0&&t.provenance===i?t:{...t,needsRefresh:!0,provenance:i}}),y=e.meta?.castRefs?.[t]===n&&v.every((t,n)=>t===e.strip[n])?e:a({...e,meta:{...e.meta||{},castRefs:{...e.meta?.castRefs||{},[t]:n}},strip:v});return u(),y}let Rr=[{id:`stickman`,name:`Stickman Paint`,builtin:!0,text:`Stickman meme-comic animation style: simple stick-figure characters with thin black stick limbs and large round heads, exaggerated rage-comic facial expressions with bold black outlines (gritted bared teeth, wide beady or bloodshot eyes, heavy angry brows), flat cel-shaded color fills with soft directional shading, plain simple environments, thick consistent black outlines throughout, no photorealism.`,refs:[`/api/media/anon/c9975d4f-e8e0-4b5d-9ac0-810d028eaefc.png`,`/api/media/anon/d348cd9d-7f5e-455d-b1bb-910151b6f465.png`,`/api/media/anon/666048dd-d666-490e-aca9-d87323f1b5b7.png`,`/api/media/anon/ab136bfb-db5a-4c1e-9d24-3920a0ca07a8.png`,`/api/media/anon/621f7192-dac0-4b58-8057-4bccf9732579.png`]}],zr=/\\s*A persistent dark title bar across the very top of the frame(?: with bold white text reading \"[^\"]*\")?\\.?/gi;function Br(e){return String(e||``).replace(zr,``).replace(/[ \\t]{2,}/g,` `).trim()}let Vr=`The reference images are STYLE ONLY — copy their look (linework, shading, palette, proportions), never their content: none of their subjects, panels, layout, or edge bars appear here. Draw ONLY the scene described, as ONE full-frame illustration filling the frame edge to edge — no title/caption bar, no letterbox, not a multi-panel strip, grid, or comic page.`,Hr=`The previous attempt drifted off-style; match the attached STYLE reference images and the stated ART STYLE exactly — this overrides everything else.`;function Ur(e,t){let n=t.sceneId?(e.scenes||[]).find(e=>e.sceneId===t.sceneId):null,r=n?.styleBlock||e.styleBlock||``,i=n&&Object.keys(n.sheets||{}).length?n.sheets:e.sheets||{},a=Object.entries(i).map(([e,t])=>`${e.toUpperCase()}: ${t}`).join(`\n`),o=(Array.isArray(t.cast)?t.cast:e.lineages?.[t.lineageId]?.sheetIds||[]).filter(t=>e.meta?.castRefs?.[t]),s=o.length?`CAST REFERENCE IMAGES (the exception to the style-only reference rule): the attached reference sheet image(s) show ${o.map(e=>e.toUpperCase()).join(`, `)} — these characters DO appear in this scene. Match their IDENTITY and DESIGN — same face structure, hair, outfit and colors — so they're recognizably the same character. But the EXPRESSION, POSE and FRAMING must follow THIS beat's description (react to what's being said); do not copy the reference sheet's neutral expression, pose, or background.`:``,c=nr(e),l=!!(c&&c.panelId!==t.panelId&&er(e,t.sceneId)),u=Qn(e,t.sceneId).styleRefs.length>0||l||o.length>0;return[r,a?`CHARACTER & STAGE SHEET (keep these EXACT in every frame):\\n${a}`:``,s,`THE SCENE: ${t.prompt}`,u?Vr:``,t.styleStrict?Hr:``,`The \"CHARACTER & STAGE SHEET\" and \"THE SCENE\" headings above are directions, not text to draw — don't letter them onto the image. Do draw any sign, label, or important number the scene itself calls for.`].filter(Boolean).join(`\n\n`)}let Wr=/^(keep|same|retain|preserve|everything (identical|the same))/i;function Gr(e,t){let n=String(t.prompt||``).trim(),r=Wr.test(n)?n:`Keep everything in this image exactly identical; the only change: ${n}`,i=Br((t.sceneId?(e?.scenes||[]).find(e=>e.sceneId===t.sceneId):null)?.styleBlock||e?.styleBlock||``),a=[r,i?`ART STYLE (unchanged, non-negotiable): ${i}`:``,`CRITICAL — keep the exact same art style as the input frame: match its medium, line quality, outline weight, palette, shading/rendering technique, and level of detail. Do NOT DRIFT the style in ANY direction — no shift toward or away from realism, painterly, semi-realistic, 3D, photoreal, or more/less detail than the input. Whatever the input frame is, THAT is the style; hold it.`,Qn(e,t.sceneId).styleRefs.length>0||Array.isArray(t.cast)&&t.cast.some(t=>e?.meta?.castRefs?.[t])?`The FIRST attached image is the frame to edit — the scene continues from it. Every OTHER attached image is a STYLE/CHARACTER reference ONLY: match its art style (linework, shading, palette) and character designs exactly, but NEVER copy its content, subjects, panels, or layout into the frame.`:``,`Don't letter the edit directions onto the image; keep the source frame's text, and add new text only if the change asks for it.`].filter(Boolean).join(` `);return t.styleStrict?`${a} ${Hr}`:a}function Kr(e,t){return typeof t?.promptOverride==`string`&&t.promptOverride.trim()?t.promptOverride:t.kind===`base`?Ur(e,t):Gr(e,t)}function qr(e,t){let n=Jr(e,t),r=Array.isArray(t?.refBlocklist)?new Set(t.refBlocklist):null;return!r||!r.size||!Array.isArray(n.referenceImages)?n:{...n,referenceImages:n.referenceImages.filter(e=>!r.has(e.source))}}function Jr(e,t){if(t.type===`titleScreen`)return{prompt:null,referenceImages:[],note:`Title screen — coded typography, never generated. Edit its template, font, and animation on the Strip step.`};if(t.type===`diagram`){let n=Xn(e,t.sceneId)?.elements||{};return{prompt:null,referenceImages:(t.visibleElements||[]).filter(e=>n[e]?.asset).map(e=>({url:n[e].asset,source:`Cached element · ${e}`})),note:`Diagram panel — COMPOSITED from the scene's cached elements at their coordinates; the frame itself is never generated (that is why persistence is pixel-identical). Regenerate an individual element to change its artwork.`}}if(t.type===`giphy`)return{prompt:null,referenceImages:[{url:t.gif,source:`Giphy asset`}],note:`Reaction GIF — sourced from Giphy and cached; never generated.`};if(t.kind===`repeat`){let n=$n(e.strip,t);return{prompt:null,referenceImages:n?[{url:n,source:`Re-shows · ${t.repeatOf}`}]:[],note:`Repeat — re-shows ${t.repeatOf}'s frame (cycle oscillation / capped hold), never generates.`}}if(t.kind===`revealStep`){let n=e.strip.find(e=>e.panelId===t.revealOf);return{prompt:null,referenceImages:n?.image?[{url:n.image,source:`Base image · ${t.revealOf}`}]:[],note:`progressiveReveal step ${Number(t.revealIndex)+1} — the base's finished diagram with the not-yet-revealed elements covered in the exact background color. Renders free from ${t.revealOf}'s image; never generates.`}}let n=Kr(e,t),r=nr(e),i=r&&r.panelId!==t.panelId&&er(e,t.sceneId)?$n(e.strip,r):null;if(t.kind===`edit`){let r=e.strip.find(e=>e.panelId===t.sourcePanelId),i=r?$n(e.strip,r):null,a=(er(e,t.sceneId)&&Array.isArray(t.cast)?t.cast:[]).filter(t=>e.meta?.castRefs?.[t]).slice(0,2).map(t=>({url:e.meta.castRefs[t],source:`Cast reference · ${t.toUpperCase()}`})),o=Qn(e,t.sceneId).styleRefs.slice(0,2);return{prompt:n,referenceImages:[...i?[{url:i,source:`Source frame · ${t.sourcePanelId}`}]:[],...a,...o.map((e,t)=>({url:e,source:o.length>1?`Style reference ${t+1}`:`Style reference`}))],note:null}}let a=Qn(e,t.sceneId).styleRefs.slice(0,6),o=(Array.isArray(t.cast)?t.cast:e.lineages?.[t.lineageId]?.sheetIds||[]).filter(t=>e.meta?.castRefs?.[t]).slice(0,2).map(t=>({url:e.meta.castRefs[t],source:`Cast reference · ${t.toUpperCase()}`}));return{prompt:n,referenceImages:[...i?[{url:i,source:`Style anchor · ${r.panelId}`}]:[],...o,...a.map((e,t)=>({url:e,source:a.length>1?`Style reference ${t+1}`:`Style reference`}))].slice(0,6),note:null}}function Yr(e,t,n){return[e.styleBlock||``,`REFERENCE SHEET for ${String(t).toUpperCase()}: ${n}. If this is a character: a front-view bust and a full-body standing pose side by side, neutral expression. If it is a place or object: one clear establishing view. Plain flat neutral background, generous margins.`,`EXCEPTION for this reference sheet only: NO title bar and NO text anywhere in the image.`,Vr].filter(Boolean).join(`\n\n`)}async function Xr(e,{generate:t,onProgress:n,onPanelDone:r=null,onSheetDone:i=null,only:a=null,force:o=!1,concurrency:s=5,shouldCancel:c=null,applyResults:l=null}={}){if(typeof t!=`function`)throw Error(`generateStrip: a generate function is required`);let u=a?new Set(a):null,d=[],f=new Map,p=0,m=nr(e),h=Math.max(1,s|0),g=0,_=[],v=()=>new Promise(e=>{let t=()=>{g<h?(g++,e()):_.push(t)};t()}),y=()=>{g--;let e=_.shift();e&&e()},b=new Map,x=new Map,S=!u,C=t=>$r(e,t),w=n=>{let r=x.get(n);return r||(r=(async()=>{let r=e.meta?.castRefs?.[n];if(r)return r;if(!S)return null;let a=C(n);if(!a||c?.())return null;let o=Qn(e,m?.sceneId).styleRefs.slice(0,6);try{if(await v(),c?.())return y(),null;let r;try{({url:r}=await t({prompt:Yr(e,n,a),referenceImages:o,aspectRatio:`1:1`,contextMode:`styleReference`,panel:null,sheet:{sheetId:n}}))}finally{y()}if(!r||!/^(https?:|\\/api\\/)/.test(r))throw Error(`no hosted image returned`);b.set(n,r);try{i?.(n,r)}catch{}return r}catch(e){return d.push({panelId:`sheet:${n}`,error:e?.message||String(e)}),null}})(),x.set(n,r),r)},T=new Map,E=i=>{let a=T.get(i.panelId);return a||(a=(async()=>{if(i.type===`titleScreen`||i.type===`diagram`||i.type===`canvas`||i.type===`giphy`||i.kind===`revealStep`)return null;if(i.kind===`repeat`){let t=e.strip.find(e=>e.panelId===i.repeatOf);return t?await E(t):null}if(i.type===`zoom`){if(i.image)return i.image;let t=e.strip.find(e=>e.panelId===i.sourcePanelId);return t?await E(t):null}if(u&&!u.has(i.panelId)||i.image&&!o)return i.image||null;let a=qr(b.size?{...e,meta:{...e.meta||{},castRefs:{...e.meta?.castRefs||{},...Object.fromEntries(b)}}}:e,i),s=a.referenceImages.map(e=>e.url);if(i.kind===`edit`){let t=e.strip.find(e=>e.panelId===i.sourcePanelId),n=(Array.isArray(i.refBlocklist)?new Set(i.refBlocklist):null)?.has(`Source frame · ${i.sourcePanelId}`),r=t?await E(t):null;if(!r&&!n)return c?.()||d.push({panelId:i.panelId,error:`source panel ${i.sourcePanelId} has no image`}),null;s=[...n||!r?[]:[r],...a.referenceImages.filter(e=>!/^Source frame/.test(e.source||``)).map(e=>e.url)]}let l=Array.isArray(i.refBlocklist)?new Set(i.refBlocklist):null;if(i.kind===`base`&&m&&i.panelId!==m.panelId&&er(e,i.sceneId)){let t=l?.has(`Style anchor · ${m.panelId}`)?null:await E(m),n=(Array.isArray(i.cast)?i.cast:e.lineages?.[i.lineageId]?.sheetIds||[]).filter(e=>!l?.has(`Cast reference · ${String(e).toUpperCase()}`)),r=(await Promise.all(n.map(e=>w(e)))).filter(Boolean).slice(0,2);if(t||r.length){let e=a.referenceImages.filter(e=>!/^(Style anchor|Cast reference)/.test(e.source||``)).map(e=>e.url);s=[...t?[t]:[],...r,...e].slice(0,6)}}if(i.kind===`base`&&m&&i.panelId===m.panelId){let t=(Array.isArray(i.cast)?i.cast:e.lineages?.[i.lineageId]?.sheetIds||[]).filter(e=>!l?.has(`Cast reference · ${String(e).toUpperCase()}`)),n=(await Promise.all(t.map(e=>w(e)))).filter(Boolean).slice(0,2);if(n.length){let e=a.referenceImages.filter(e=>!/^(Style anchor|Cast reference)/.test(e.source||``)).map(e=>e.url);s=[...n,...e].slice(0,6)}}if(c?.())return i.image||null;try{let n=m&&i.panelId===m.panelId,o=e=>/429|rate.?limit|too many|concurren|timeout|timed out|network|fetch/i.test(e?.message||``),l=null,u=null;for(let r=0;r<2&&!l&&!(r>0&&!(n&&o(u)));r++){if(c?.())return i.image||null;if(await v(),c?.())return y(),i.image||null;try{({url:l}=await t({prompt:a.prompt,referenceImages:s,aspectRatio:e.meta?.aspect||`16:9`,contextMode:i.kind===`edit`?`panelEdit`:`context`,panel:i}))}catch(e){u=e}finally{y()}}if(!l&&u)throw u;if(!l||!/^(https?:|\\/api\\/)/.test(l))throw Error(`no hosted image returned`);f.set(i.panelId,l);try{r?.(i.panelId,l)}catch{}return l}catch(e){return d.push({panelId:i.panelId,error:e?.message||String(e)}),null}finally{p++,n?.({done:p,total:e.strip.length,panelId:i.panelId})}})(),T.set(i.panelId,a),a)};if(S&&await Promise.all([...ei(e,{force:o})].map(e=>w(e))),await Promise.all(e.strip.map(E)),typeof l==`function`){let t=new Map(e.strip.map((e,t)=>[e.panelId,t]));return d.sort((e,n)=>(t.get(e.panelId)??-1)-(t.get(n.panelId)??-1)),{doc:await l({doc:e,results:new Map(f),anchorPanelId:m?.panelId||null,castRefs:Object.fromEntries(b),errors:d.slice()}),errors:d}}let D=e.strip.map(e=>f.has(e.panelId)?{...e,image:f.get(e.panelId),versions:lr(e,f.get(e.panelId)),needsRefresh:!1,styleWarning:null,styleStrict:!1}:e),O=new Map(e.strip.map((e,t)=>[e.panelId,t]));d.sort((e,t)=>(O.get(e.panelId)??-1)-(O.get(t.panelId)??-1));let k={...e.meta||{},...m?{anchorPanelId:m.panelId}:{},...b.size?{castRefs:{...e.meta?.castRefs||{},...Object.fromEntries(b)}}:{}};return{doc:{...e,meta:k,strip:D},errors:d}}async function Zr(e,t,{generate:n}={}){let r=e.strip.find(e=>e.panelId===t);if(!r)throw Error(`regeneratePanel: unknown panel \"${t}\"`);if(r.type===`titleScreen`)throw Error(`regeneratePanel: title screens are coded typography — edit them, they never generate`);if(r.kind===`repeat`)throw Error(`regeneratePanel: ${t} re-shows ${r.repeatOf} — regenerate that panel instead`);if(r.kind===`edit`&&!e.strip.find(e=>e.panelId===r.sourcePanelId)?.image)throw Error(`regeneratePanel: source panel ${r.sourcePanelId} has no image yet`);let{doc:i,errors:a}=await Xr(e,{generate:n,only:[t],force:!0});if(a.length)throw Error(a[0].error);let o=or(i.strip,t),s=i;for(let t of o)s=ur(s,t,{needsRefresh:!0,provenance:e.strip.find(e=>e.panelId===t)?.provenance||`auto`});let c=nr(s);if(c&&c.panelId===t)for(let e of s.strip)e.panelId!==t&&e.kind===`base`&&e.image&&e.type!==`titleScreen`&&e.type!==`giphy`&&e.type!==`diagram`&&er(s,e.sceneId)&&(o.includes(e.panelId)||o.push(e.panelId),s=ur(s,e.panelId,{needsRefresh:!0,provenance:e.provenance||`auto`}));return{doc:s,flagged:o}}async function Qr(e,t,{generate:n,generateFor:r,onProgress:i,shouldCancel:a}={}){let o=e,s=[],c=0;for(let e of t){if(a?.())break;try{let t=r?r(e):n,{doc:i}=await Zr(o,e,{generate:t});o=ur(i,e,{needsRefresh:!1})}catch(t){s.push({panelId:e,error:t?.message||String(t)})}i?.({done:++c,total:t.length})}return{doc:o,errors:s}}function $r(e,t){if(e?.sheets?.[t])return e.sheets[t];for(let n of e?.scenes||[])if(n.sheets?.[t])return n.sheets[t];return null}function ei(e,{force:t=!1}={}){let n=new Set;for(let r of e?.strip||[]){if(r.type!==`panel`||r.kind!==`base`&&r.kind!==`edit`||r.image&&!t||!er(e,r.sceneId))continue;let i=r.kind===`edit`?Array.isArray(r.cast)?r.cast:[]:Array.isArray(r.cast)?r.cast:e.lineages?.[r.lineageId]?.sheetIds||[];for(let t of i.slice(0,2))$r(e,t)&&n.add(t)}return n}function ti(e,{force:t=!1}={}){let n=0;for(let r of ei(e,{force:t}))e.meta?.castRefs?.[r]||n++;return n}function ni(e){return(e?.strip||[]).filter(e=>e.type!==`titleScreen`&&e.type!==`diagram`&&e.type!==`giphy`&&e.type!==`canvas`&&e.type!==`zoom`&&e.kind!==`repeat`&&e.kind!==`revealStep`&&!e.image).length}function ri(e){return(e?.strip||[]).filter(e=>e.type!==`titleScreen`&&e.type!==`diagram`&&e.type!==`giphy`&&e.type!==`canvas`&&e.type!==`zoom`&&e.kind!==`repeat`&&e.kind!==`revealStep`&&!!e.image).length}function ii(e){return(e?.strip||[]).filter(e=>e.kind===`revealStep`&&!e.image).length}let ai={manifest:{schemaVersion:1,sdkVersion:`0.1.0`,id:`stillmade-internal.single-regeneration`,version:`1.0.0`,name:`Panel regeneration result`,description:`Apply an exact generated image version and flag its dependent or anchored panels.`,kind:`task`,runtime:`javascript`,inputs:{rows:{type:`json`},results:{type:`json`},panelId:{type:`json`},anchorPanelId:{type:`json`}},outputs:{edit:{type:`json`}},permissions:{project:[],network:[],filesystem:[],secrets:[]}},code:`function applySingleRegeneration(input){\n const results=new Map(input.results);\n const rows=input.rows.map(p=>results.has(p.panelId)?{...p,image:results.get(p.panelId),versions:[...(p.versions?.length?p.versions:p.image?[p.image]:[]).filter(v=>v!==results.get(p.panelId)),results.get(p.panelId)].slice(-8),needsRefresh:false,styleWarning:null,styleStrict:false}:p);\n const affected=new Set([input.panelId]),flagged=[];\n for(const p of rows)if(p.kind==='edit'&&p.sourcePanelId&&affected.has(p.sourcePanelId)){affected.add(p.panelId);flagged.push(p.panelId);}\n let out=rows.map(p=>flagged.includes(p.panelId)?{...p,needsRefresh:true,provenance:input.rows.find(x=>x.panelId===p.panelId)?.provenance||'auto'}:p);\n if(input.anchorPanelId===input.panelId){\n out=out.map(p=>{\n if(p.panelId===input.panelId||p.kind!=='base'||!p.image||['titleScreen','giphy','diagram'].includes(p.type)||!p.docStyle)return p;\n if(!flagged.includes(p.panelId))flagged.push(p.panelId);\n return {...p,needsRefresh:true,provenance:p.provenance||'auto'};\n });\n }\n return {rows:out,flagged,anchorPanelId:input.anchorPanelId};\n}\n\nreturn {edit:applySingleRegeneration(input)};`,tests:[]};async function oi({doc:e,results:t,anchorPanelId:n,castRefs:r},i,{signal:a,assertCurrent:o,host:s}){let c=H(s),l=c.actor(),u=()=>V({doc:e,results:t instanceof Map?[...t]:null,anchorPanelId:n??null,castRefs:r||{}}),d=u(),f=()=>{o(),I(l&&c.actor()===l&&!a?.aborted&&u()===d,`STALE`,`The account or panel regeneration evidence changed.`)};f(),I(Array.isArray(e?.strip)&&e.strip.length<=4096&&t instanceof Map&&t.size===1&&t.has(i)&&Object.keys(r||{}).length===0,`PANEL_REGENERATION`,`The exact single-panel result is unavailable.`);let p=new Map,m=new Map,h=e=>{if(!e)return e;if(!p.has(e)){let t=`image-${p.size}`;p.set(e,t),m.set(t,e)}return p.get(e)},g=[`panelId`,`type`,`kind`,`sourcePanelId`,`needsRefresh`,`styleWarning`,`styleStrict`,`provenance`],_=e.strip.map((t,n)=>({...Object.fromEntries(g.filter(e=>t[e]!==void 0).map(e=>[e,t[e]])),origin:n,docStyle:er(e,t.sceneId),...t.image===void 0?{}:{image:h(t.image)},...t.versions===void 0?{}:{versions:t.versions===null?null:t.versions.map(h)}})),v={rows:_,results:[...t].map(([e,t])=>(I(typeof t==`string`&&t,`PANEL_REGENERATION`,`The generated image is unavailable.`),[e,h(t)])),panelId:i,anchorPanelId:n||null};B(v),I(JSON.stringify(v).length<=1048576,`PANEL_REGENERATION`,`The panel history exceeds the supported metadata size.`);let y=new Map(v.results),b=_.map(e=>{if(!y.has(e.panelId))return e;let t=y.get(e.panelId),n=e.versions?.length?e.versions:e.image?[e.image]:[];return{...e,image:t,versions:[...n.filter(e=>e!==t),t].slice(-8),needsRefresh:!1,styleWarning:null,styleStrict:!1}}),x=new Set([i]),S=[];for(let e of b)e.kind===`edit`&&e.sourcePanelId&&x.has(e.sourcePanelId)&&(x.add(e.panelId),S.push(e.panelId));let C=b.map(e=>S.includes(e.panelId)?{...e,needsRefresh:!0,provenance:_.find(t=>t.panelId===e.panelId)?.provenance||`auto`}:e);v.anchorPanelId===i&&(C=C.map(e=>e.panelId===i||e.kind!==`base`||!e.image||[`titleScreen`,`giphy`,`diagram`].includes(e.type)||!e.docStyle?e:(S.includes(e.panelId)||S.push(e.panelId),{...e,needsRefresh:!0,provenance:e.provenance||`auto`})));let w={rows:C,flagged:S,anchorPanelId:v.anchorPanelId};B(w);let T=await c.run(ai,{kind:`run`,input:v,signal:a,timeoutMs:15e3});f(),B(T.outputs?.edit),I(V(T.outputs.edit)===V(w),`PANEL_REGENERATION`,`The sandbox changed unrelated image versions or refresh flags.`);let E=e=>(I(!e||m.has(e),`PANEL_REGENERATION`,`The sandbox returned an unknown image.`),e&&m.get(e)),D=T.outputs.edit.rows.map((t,n)=>{let r=e.strip[n];if(V(t)===V(_[n]))return r;let i={...r};for(let e of[`needsRefresh`,`styleWarning`,`styleStrict`,`provenance`])t[e]!==void 0&&(i[e]=t[e]);return t.image!==void 0&&(i.image=E(t.image)),t.versions!==void 0&&(i.versions=t.versions===null?null:t.versions.map(E)),i}),O={...e,meta:{...e.meta||{},...v.anchorPanelId?{anchorPanelId:v.anchorPanelId}:{}},strip:D};return{doc:S.length?q(O):O,flagged:S}}async function si(e,t,{generate:n,signal:r,assertCurrent:i,host:a}){let o=H(a),s=o.actor(),c=V(e),l=()=>{i(),I(s&&o.actor()===s&&!r?.aborted&&V(e)===c,`STALE`,`The account or panel document changed during regeneration.`)};l();let u=e.strip.find(e=>e.panelId===t);if(!u)throw Error(`Unknown panel ${t}.`);if(u.type===`titleScreen`)throw Error(`Title screens are coded typography — edit them instead.`);if(u.kind===`repeat`)throw Error(`${t} re-shows ${u.repeatOf} — regenerate that panel instead.`);if(u.kind===`edit`&&!e.strip.find(e=>e.panelId===u.sourcePanelId)?.image)throw Error(`Its source (${u.sourcePanelId}) has no image yet — build the image panels first.`);let d=[],f=await Xr(e,{only:[t],force:!0,shouldCancel:()=>(l(),!1),generate:async(...e)=>{l();let t=await n(...e);return l(),t},applyResults:async e=>{if(l(),e.errors.length)throw Error(e.errors[0].error);let n=await oi(e,t,{signal:r,assertCurrent:l,host:a});return l(),d=n.flagged,n.doc}});if(l(),f.errors.length)throw Error(f.errors[0].error);return{doc:f.doc,flagged:d}}let ci={manifest:{schemaVersion:1,sdkVersion:`0.1.0`,id:`stillmade-internal.reveal-frames`,version:`1.0.0`,name:`Reveal frame sequence`,description:`Normalize the reveal plan, order new labels by narration, and construct every cumulative covered frame.`,kind:`task`,runtime:`javascript`,inputs:{plan:{type:`json`},detected:{type:`json`},named:{type:`json`},narration:{type:`json`},bg:{type:`json`},stepCount:{type:`json`}},outputs:{sequence:{type:`json`}},permissions:{project:[],network:[],filesystem:[],secrets:[]}},code:`function normalizeRevealPlan(raw) {\n const els = Array.isArray(raw?.elements) ? raw.elements : [];\n const elements = els\n .filter((e) => e && e.id && e.box)\n .map((e) => ({\n id: String(e.id).slice(0, 40),\n name: String(e.name || e.id).slice(0, 120),\n box: {\n x: Math.max(0, Math.round(Number(e.box.x) || 0)),\n y: Math.max(0, Math.round(Number(e.box.y) || 0)),\n w: Math.max(1, Math.round(Number(e.box.w) || 1)),\n h: Math.max(1, Math.round(Number(e.box.h) || 1)),\n },\n alwaysVisible: e.alwaysVisible === true,\n }));\n const known = new Set(elements.map((e) => e.id));\n const order = (Array.isArray(raw?.order) ? raw.order : []).map((id) => String(id)).filter((id) => known.has(id));\n // Unordered elements append in detection order so every element reveals.\n for (const e of elements) if (!order.includes(e.id) && !e.alwaysVisible) order.push(e.id);\n const bg = Array.isArray(raw?.bg) && raw.bg.length === 3 ? raw.bg.map((c) => Math.max(0, Math.min(255, Math.round(Number(c) || 0)))) : [0, 0, 0];\n return { bg, elements, order };\n}\n\nfunction coverBoxesForCount(elements, order, revealedCount, { alwaysVisible = [] } = {}) {\n const revealed = new Set([...order.slice(0, Math.max(0, revealedCount)), ...alwaysVisible]);\n return elements.filter((e) => !revealed.has(e.id)).map((e) => e.box);\n}\n\nfunction revealedCountForStep(stepIndex, stepCount, elementCount) {\n const beats = Math.max(1, stepCount + 1);\n return Math.min(elementCount, Math.max(1, Math.ceil(((stepIndex + 1) * elementCount) / beats)));\n}\n\nconst ORDER_STOP = new Set(['the', 'a', 'an', 'to', 'of', 'and', 'or', 'in', 'on', 'for', 'with', 'into']);\nfunction orderByNarration(elements, order, narration) {\n const byId = new Map((Array.isArray(elements) ? elements : []).map((e) => [e.id, e]));\n const ids = (Array.isArray(order) ? order : []).filter((id) => byId.has(id));\n const hay = String(narration || '').toLowerCase();\n if (!hay) return ids.slice();\n // Earliest character index at which this element's name (whole phrase, or any\n // significant word of it) is mentioned; -1 when the narration never names it.\n const mentionAt = (id) => {\n const name = String(byId.get(id)?.name || '').toLowerCase();\n let best = -1;\n const whole = name.trim();\n if (whole) { const i = hay.indexOf(whole); if (i !== -1) best = i; }\n for (const w of name.split(/[^a-z0-9]+/)) {\n if (w.length < 3 || ORDER_STOP.has(w)) continue;\n const i = hay.indexOf(w);\n if (i !== -1 && (best === -1 || i < best)) best = i;\n }\n return best;\n };\n // Stable sort: mentioned ids by earliest mention ascending; unmentioned ids\n // keep their baseline order and sink below every mentioned id.\n return ids\n .map((id, i) => ({ id, at: mentionAt(id), i }))\n .sort((a, b) => {\n if (a.at >= 0 && b.at >= 0) return a.at - b.at || a.i - b.i;\n if (a.at >= 0) return -1;\n if (b.at >= 0) return 1;\n return a.i - b.i;\n })\n .map((o) => o.id);\n}\n\nfunction prepareRevealFrames(input){\n let plan=input.plan?normalizeRevealPlan(input.plan):null;\n if(!plan||!plan.elements.length){\n const names=new Map((input.named?.elements||[]).map(e=>[e.id,e.name]));\n plan=normalizeRevealPlan({bg:input.bg,elements:input.detected.map(e=>({id:e.id,name:names.get(e.id)||e.id,box:e.box})),order:Array.isArray(input.named?.order)&&input.named.order.length?input.named.order:input.detected.map(e=>e.id)});\n plan={...plan,order:orderByNarration(plan.elements,plan.order,input.narration)};\n }\n const revealable=plan.elements.filter(e=>!e.alwaysVisible).length,alwaysVisible=plan.elements.filter(e=>e.alwaysVisible).map(e=>e.id);\n const frames=Array.from({length:input.stepCount},(_,index)=>coverBoxesForCount(plan.elements,plan.order,revealedCountForStep(index,input.stepCount,revealable),{alwaysVisible}));\n return {plan,frames};\n}\n\nreturn {sequence:prepareRevealFrames(input)};`,tests:[]},li=new Set([`the`,`a`,`an`,`to`,`of`,`and`,`or`,`in`,`on`,`for`,`with`,`into`]);function ui(e){let t=(Array.isArray(e?.elements)?e.elements:[]).filter(e=>e&&e.id&&e.box).map(e=>({id:String(e.id).slice(0,40),name:String(e.name||e.id).slice(0,120),box:{x:Math.max(0,Math.round(Number(e.box.x)||0)),y:Math.max(0,Math.round(Number(e.box.y)||0)),w:Math.max(1,Math.round(Number(e.box.w)||1)),h:Math.max(1,Math.round(Number(e.box.h)||1))},alwaysVisible:e.alwaysVisible===!0})),n=new Set(t.map(e=>e.id)),r=(Array.isArray(e?.order)?e.order:[]).map(String).filter(e=>n.has(e));for(let e of t)!r.includes(e.id)&&!e.alwaysVisible&&r.push(e.id);return{bg:Array.isArray(e?.bg)&&e.bg.length===3?e.bg.map(e=>Math.max(0,Math.min(255,Math.round(Number(e)||0)))):[0,0,0],elements:t,order:r}}function di(e){let t=e.plan?ui(e.plan):null;if(!t||!t.elements.length){let n=new Map((e.named?.elements||[]).map(e=>[e.id,e.name]));t=ui({bg:e.bg,elements:e.detected.map(e=>({id:e.id,name:n.get(e.id)||e.id,box:e.box})),order:Array.isArray(e.named?.order)&&e.named.order.length?e.named.order:e.detected.map(e=>e.id)});let r=new Map(t.elements.map(e=>[e.id,e])),i=String(e.narration||``).toLowerCase(),a=e=>{let t=String(r.get(e)?.name||``).toLowerCase(),n=[];t.trim()&&n.push(i.indexOf(t.trim()));for(let e of t.split(/[^a-z0-9]+/))e.length>=3&&!li.has(e)&&n.push(i.indexOf(e));let a=n.filter(e=>e>=0);return a.length?Math.min(...a):-1},o=t.order.filter(e=>r.has(e));t={...t,order:i?o.map((e,t)=>({id:e,index:t,at:a(e)})).sort((e,t)=>e.at>=0&&t.at>=0?e.at-t.at||e.index-t.index:e.at>=0?-1:t.at>=0?1:e.index-t.index).map(e=>e.id):o}}let n=t.elements.filter(e=>!e.alwaysVisible).length,r=t.elements.filter(e=>e.alwaysVisible).map(e=>e.id),i=Array.from({length:e.stepCount},(i,a)=>{let o=Math.min(n,Math.max(1,Math.ceil((a+1)*n/Math.max(1,e.stepCount+1)))),s=new Set([...t.order.slice(0,Math.max(0,o)),...r]);return t.elements.filter(e=>!s.has(e.id)).map(e=>e.box)});return{plan:t,frames:i}}async function fi(e,{signal:t,assertCurrent:n,host:r}){let i=H(r),a=i.actor(),o=V(e),s=()=>{n(),I(a&&i.actor()===a&&!t?.aborted&&V(e)===o,`STALE`,`The account, reveal plan or narration changed during frame preparation.`)};s(),B(e),I(Number.isInteger(e.stepCount)&&e.stepCount>=0&&e.stepCount<=256&&Array.isArray(e.detected)&&e.detected.length<=1024&&(e.plan?.elements?.length||0)<=1024&&(e.named?.elements?.length||0)<=1024&&JSON.stringify(e).length<=1048576,`REVEAL_FRAMES`,`The reveal sequence exceeds its supported size.`);let c=structuredClone(e),l=di(c);B(l);let u=await i.run(ci,{kind:`run`,input:c,signal:t,timeoutMs:15e3});return s(),B(u.outputs?.sequence),I(V(u.outputs.sequence)===V(l),`REVEAL_FRAMES`,`The sandbox changed the reveal boxes, labels, or sequence.`),u.outputs.sequence}function pi({doc:e,projectId:t,canEdit:n,onDocChange:r,editLease:i,settings:a,host:o,operationName:s=`Reveal rendering`}){let c=H(o),l=()=>c.actor(),u=()=>Object.assign(Error(`${s} cancelled or its source changed.`),{name:`AbortError`}),d=l(),f=(0,v.useRef)(null),p=(0,v.useRef)(null),m=(0,v.useRef)(!0),h=(0,v.useRef)(0),g=(0,v.useRef)(new Set),[_,y]=(0,v.useState)(null),[b,x]=(0,v.useState)(!1),[S,C]=(0,v.useState)(``);f.current={doc:e,projectId:t,canEdit:n,onDocChange:r,actor:d,settings:a,services:c};let w=()=>{for(let e of[...g.current])e()},T=()=>{p.current&&(h.current++,p.current.abort(),x(!0),w())};return(0,v.useEffect)(()=>(m.current=!0,()=>{m.current=!1,h.current++,p.current?.abort(),w()}),[]),(0,v.useEffect)(w,[e,t,n,d,a,c]),(0,v.useEffect)(()=>{T()},[t,n,d,c,JSON.stringify(a)]),{run:async(e,t,n,r)=>{if(f.current.services!==c||p.current||i.current)throw u();let a=new AbortController,o=++h.current;p.current=a,i.current=a,y(t),x(!1),C(``);try{let t=JSON.stringify(e),i=t,d=new Set([t]),p=()=>{let e=f.current;if(!m.current||a.signal.aborted||h.current!==o||!n.actor||e.actor!==n.actor||l()!==n.actor||e.projectId!==n.projectId||!e.canEdit||e.services!==c||JSON.stringify(e.settings)!==n.settings)throw u()},_=async(e,t,n,r)=>{let i=Date.now()+t;for(;;){if(n(),JSON.stringify(f.current.doc)===e)return;if(Date.now()>=i)throw Object.assign(Error(r),{code:`PHASE_DELIVERY_TIMEOUT`});await new Promise(e=>{let t,n=()=>{clearTimeout(t),g.current.delete(n),e()};g.current.add(n),t=setTimeout(n,Math.max(1,i-Date.now()))})}};await _(t,1e3,p,`${s} could not start because the latest document changes have not appeared. Review the current project before trying again.`);let v=()=>{if(p(),JSON.stringify(e)!==t||!d.has(JSON.stringify(f.current.doc)))throw u()},y=async e=>{v();let t=i,n=JSON.stringify(e),r=!1;d.add(n),i=n;let a=()=>{if(v(),r||JSON.stringify(e)!==n)throw u()};f.current.onDocChange(i=>{try{if(a(),JSON.stringify(i)!==t&&JSON.stringify(i)!==n)throw u();return n===t?i:e}catch{return r=!0,i}}),await _(n,5e3,a,`${s} finished, but its changes could not be saved. Review the current project before trying again.`),d.clear(),d.add(n)};v();let b=await r({check:v,commit:y,signal:a.signal});return v(),await y(b),b}catch(e){throw a.abort(),m.current&&p.current===a&&f.current.services===c&&l()===n.actor&&f.current.projectId===n.projectId&&C(e.message||`${s} failed.`),e}finally{p.current===a&&(i.current===a&&(i.current=null),p.current=null,m.current&&(y(null),x(!1)))}},capture:()=>({actor:d,projectId:t,settings:JSON.stringify(a)}),cancel:T,pending:_,canceling:b,error:S}}let mi={manifest:{schemaVersion:1,sdkVersion:`0.1.0`,id:`stillmade-internal.panel-prompt-edit`,version:`1.0.0`,name:`Panel generation controls`,description:`Edit the generation method, prompt or reference exclusions.`,kind:`task`,runtime:`javascript`,inputs:{doc:{type:`json`},action:{type:`json`},value:{type:`json`}},outputs:{edit:{type:`json`}},permissions:{project:[],network:[],filesystem:[],secrets:[]}},code:`function updatePanel(doc, panelId, patch) {\n const strip = doc.strip.map((p) => (p.panelId === panelId ? { ...p, ...patch, provenance: patch.provenance || 'user' } : p));\n return loadPanelDoc({ ...doc, strip });\n}\n\n\nconst loadPanelDoc=doc=>doc;const panel=input.doc.strip[0];let patch;\nif(input.action==='method')patch={method:input.value};\nelse if(input.action==='prompt')patch=panel.promptOverride?{prompt:input.value,promptOverride:''}:{prompt:input.value};\nelse if(input.action==='send')patch={promptOverride:''};\nelse if(input.action==='override')patch={promptOverride:input.value};\nelse if(input.action==='reset')patch={promptOverride:'',refBlocklist:[]};\nelse {const current=Array.isArray(panel.refBlocklist)?panel.refBlocklist:[];if(current.includes(input.value))return {edit:input.doc};patch={refBlocklist:[...current,input.value]};}\nreturn {edit:updatePanel(input.doc,panel.panelId,patch)};`,tests:[]};function hi(e){return I(e?.version===1&&typeof e.run==`function`&&typeof e.actor==`function`&&Array.isArray(e.methods)&&e.methods.length>0&&e.methods.length<=128&&new Set(e.methods).size===e.methods.length&&e.methods.every(e=>typeof e==`string`&&/^[A-Za-z][A-Za-z0-9_-]{0,63}$/.test(e)),`HOST_SERVICES`,`Image Panels prompt editing requires its version 1 local sandbox and identity services.`),e}let gi=(e,t)=>e===void 0||t===void 0?e===t:V(e)===V(t);function _i(e,t,n,r,i){let a=e.strip.find(e=>e.panelId===t);I(a&&[`method`,`prompt`,`send`,`override`,`reset`,`exclude`].includes(n),`PROMPT_EDIT`,`Choose a current panel generation control.`),n===`method`&&I(r===null||i.includes(r),`PROMPT_EDIT`,`Choose an available panel method.`),[`prompt`,`override`,`exclude`].includes(n)&&I(typeof r==`string`&&r.length<=131072,`PROMPT_EDIT`,`Use a supported text value.`);let o=Array.isArray(a.refBlocklist)?a.refBlocklist:[];I(o.length<=1024,`PROMPT_EDIT`,`The reference exclusion list is too large.`);let s=new Map,c=e=>(s.has(e)||s.set(e,`source-${s.size}`),s.get(e)),l={panelId:t};a.promptOverride!==void 0&&(l.promptOverride=a.promptOverride?`prior-override`:``),a.refBlocklist!==void 0&&(l.refBlocklist=o.map(c));let u={doc:{strip:[l]},action:n,value:n===`exclude`?c(r):[`prompt`,`override`].includes(n)?`captured-text`:r??null};B(u);let d,f;if(n===`method`)d={method:r},f={method:u.value};else if(n===`prompt`)d=a.promptOverride?{prompt:r,promptOverride:``}:{prompt:r},f=a.promptOverride?{prompt:u.value,promptOverride:``}:{prompt:u.value};else if(n===`send`)d=f={promptOverride:``};else if(n===`override`)d={promptOverride:r},f={promptOverride:u.value};else if(n===`reset`)d=f={promptOverride:``,refBlocklist:[]};else if(o.includes(r))return{panel:a,input:u,patch:null,expected:u.doc};else d={refBlocklist:[...o,r]},f={refBlocklist:[...o.map(c),u.value]};return{panel:a,input:u,patch:d,expected:{strip:[{...l,...f,provenance:`user`}]}}}function vi(e,{panel:t,patch:n,expected:r},i){return B(i),I(gi(i,r),`PROMPT_EDIT`,`The sandbox changed an unrequested prompt, reference or panel.`),!n||t.provenance===`user`&&Object.keys(n).every(e=>gi(t[e],n[e]))?e:{...e,strip:e.strip.map(e=>e===t?{...e,...n,provenance:`user`}:e)}}function yi({doc:e,projectId:t,canEdit:n,onDocChange:r,validateDocument:i,editLease:a,host:o}){let s=hi(o),c=()=>s.actor(),[l,u]=(0,v.useState)(null),[d,f]=(0,v.useState)(``),p=(0,v.useRef)(null),m=(0,v.useRef)(null),h=(0,v.useRef)(!0),g=(0,v.useRef)(0),_=(0,v.useRef)(null),y=c();_.current={doc:e,projectId:t,canEdit:n,onDocChange:r,validateDocument:i,actor:y,services:s};let b=(0,v.useCallback)(()=>{g.current++,a?.current===p.current&&(a.current=null),p.current?.abort(),p.current=null,u(null)},[a]);return(0,v.useEffect)(()=>(h.current=!0,()=>{h.current=!1,g.current++,a?.current===p.current&&(a.current=null),p.current?.abort(),p.current=null}),[]),(0,v.useEffect)(()=>{let e=m.current;if(e)try{let t=_.current;if(t.services===e.services&&t.actor===e.actor&&c()===e.actor&&t.projectId===e.projectId&&t.canEdit&&JSON.stringify(t.doc)===e.expected){e.resolve();return}}catch{}b()},[e,t,n,y,s,b]),{change:(0,v.useCallback)(async(n,r,i)=>{let o=_.current;if(!o.doc||!o.canEdit||p.current||a?.current)return!1;if(o.services!==s||o.doc!==e||o.projectId!==t||o.actor!==y||c()!==y)return f(`The panel changed. Review the panel generation settings again.`),!1;let l=++g.current,d=new AbortController;p.current=d,a&&(a.current=d),u(n),f(``);let v,b=()=>{let e=_.current;I(h.current&&p.current===d&&!d.signal.aborted&&e.doc===o.doc&&e.projectId===o.projectId&&e.canEdit&&e.services===o.services&&e.actor===o.actor&&c()===o.actor&&JSON.stringify(o.doc)===v,`STALE`,`The panel changed. Review the current panel generation settings again.`)};try{v=JSON.stringify(o.doc);let e=_i(o.doc,n,r,i,s.methods);b();let t=await s.run(mi,{kind:`run`,input:e.input,signal:d.signal,timeoutMs:15e3});b();let a=vi(o.doc,e,t.outputs?.edit),u=a===o.doc?o.doc:o.validateDocument(a);b();let p=Promise.resolve();if(u!==o.doc){p=new Promise((e,t)=>{let n=()=>{clearTimeout(a),d.signal.removeEventListener(`abort`,i),m.current===r&&(m.current=null)},r={controller:d,services:o.services,actor:o.actor,projectId:o.projectId,expected:JSON.stringify(u),resolve:()=>{n(),e()},reject:(e,r=!1)=>{n(),!r&&h.current&&c()===o.actor&&_.current.projectId===o.projectId&&f(e.message||`The panel settings update was not accepted.`),d.abort(),t(e)}},i=()=>r.reject(Error(`The panel settings update was canceled.`),!0),a=setTimeout(()=>r.reject(Error(`The project did not acknowledge the panel settings update.`)),2e3);m.current=r,d.signal.addEventListener(`abort`,i,{once:!0})}),p.catch(()=>{});let e=!1;o.onDocChange(t=>{let n=_.current,r=!1;try{r=h.current&&g.current===l&&!d.signal.aborted&&n.doc===o.doc&&n.projectId===o.projectId&&n.canEdit&&n.services===o.services&&n.actor===o.actor&&c()===o.actor&&JSON.stringify(t)===v&&JSON.stringify(o.doc)===v}catch{}return r?u:(e||(e=!0,queueMicrotask(()=>{h.current&&c()===o.actor&&_.current.projectId===o.projectId&&f(`The panel changed before the panel generation settings could be saved. Review the current panel generation settings again.`),m.current?.controller===d&&m.current.reject(Error(`The project rejected the panel settings update`))})),t)})}return await p,I(h.current&&!d.signal.aborted&&g.current===l&&c()===o.actor&&_.current.projectId===o.projectId&&_.current.canEdit&&_.current.services===o.services,`STALE`,`The panel settings update scope changed.`),u}catch(e){return m.current?.controller===d&&m.current.reject(e),h.current&&!d.signal.aborted&&c()===o.actor&&_.current.projectId===o.projectId&&f(e.message||`The panel generation settings could not be applied.`),!1}finally{p.current===d&&(a?.current===d&&(a.current=null),p.current=null,h.current&&u(null))}},[e,t,y,s]),pending:l,error:d,cancel:b}}function bi(e){return I(e?.version===1&&typeof e.crop==`function`,`HOST_SERVICES`,`Panel cropping requires its version 1 host service.`),e}let xi={manifest:{schemaVersion:1,sdkVersion:`0.1.0`,id:`stillmade-internal.zoom-override`,version:`1.0.0`,name:`Zoom approval`,description:`Prepare the approved crop and its downstream refresh scope.`,kind:`task`,runtime:`javascript`,inputs:{rows:{type:`json`},panelId:{type:`json`},mode:{type:`json`},target:{type:`json`}},outputs:{plan:{type:`json`}},permissions:{project:[],network:[],filesystem:[],secrets:[]}},code:`function zoomOverridePlan(input){\n const selected=input.rows.find(p=>p.panelId===input.panelId);\n if(!selected||selected.type!=='zoom')throw new Error('Choose a current zoom panel.');\n const affected=new Set([input.panelId]),downstream=[];\n for(const p of input.rows)if(p.kind==='edit'&&p.sourcePanelId&&affected.has(p.sourcePanelId)){affected.add(p.panelId);downstream.push(p.panelId);}\n if(input.mode==='stale')return {downstream};\n const zoom={fx:Math.max(0,Math.min(100,Number(input.target.fx))),fy:Math.max(0,Math.min(100,Number(input.target.fy))),scale:Math.max(1.1,Math.min(3,Number(input.target.scale)||1.8)),pickedBy:'user'};\n const s=Math.max(1.2,Math.min(3,Number(zoom.scale)||1.8)),ox=Math.max(0,Math.min(100,Number(zoom.fx)||0))/100,oy=Math.max(0,Math.min(100,Number(zoom.fy)||0))/100,w=1/s;\n return {zoom,rect:{x:ox*(1-w),y:oy*(1-w),w,h:w},downstream,immediate:input.rows.filter(p=>p.kind==='edit'&&p.sourcePanelId===input.panelId).map(p=>p.panelId)};\n}\n\nreturn {plan:zoomOverridePlan(input)};`,tests:[]};async function J(e,t,n,{mode:r=`crop`,signal:i,assertCurrent:a,host:o}){let s=H(o),c=s.actor(),l=V(e),u=()=>{a(),I(c&&s.actor()===c&&!i?.aborted&&V(e)===l,`STALE`,`The account or zoom source changed.`)};u(),I(Array.isArray(e?.strip)&&e.strip.length<=4096&&[`crop`,`stale`].includes(r),`ZOOM_OVERRIDE`,`The zoom scope is unavailable.`);let d=e.strip.map(e=>Object.fromEntries([`panelId`,`type`,`kind`,`sourcePanelId`].filter(t=>e[t]!==void 0).map(t=>[t,e[t]]))),f={rows:d,panelId:t,mode:r,target:r===`stale`?{}:{fx:Number(n.fx),fy:Number(n.fy),scale:Number(n.scale)||1.8}};B(f),I(JSON.stringify(f).length<=1048576,`ZOOM_OVERRIDE`,`The zoom metadata is too large.`);let p=e.strip.find(e=>e.panelId===t);I(p?.type===`zoom`,`ZOOM_OVERRIDE`,`Choose a current zoom panel.`);let m=or(d,t),h={downstream:m};if(r===`crop`){let e={fx:Math.max(0,Math.min(100,f.target.fx)),fy:Math.max(0,Math.min(100,f.target.fy)),scale:Math.max(1.1,Math.min(3,f.target.scale)),pickedBy:`user`};h={zoom:e,rect:En(e),downstream:m,immediate:d.filter(e=>e.kind===`edit`&&e.sourcePanelId===t).map(e=>e.panelId)}}B(h);let g=await s.run(xi,{kind:`run`,input:f,signal:i,timeoutMs:15e3});u(),B(g.outputs?.plan),I(V(g.outputs.plan)===V(h),`ZOOM_OVERRIDE`,`The sandbox changed the approved zoom or downstream scope.`);let _=V(g.outputs.plan),v=V(m);return{...g.outputs.plan,apply:n=>{if(u(),I(V(g.outputs.plan)===_&&V(m)===v,`STALE`,`The approved zoom plan changed.`),r===`stale`){let t=e;for(let e of m)t=ur(t,e,{needsRefresh:!0});return t}I(typeof n==`string`&&n.length>0,`ZOOM_OVERRIDE`,`The approved crop is unavailable.`);let i=new Set(g.outputs.plan.immediate),a=e.strip.map(e=>e.panelId===t?{...e,zoom:g.outputs.plan.zoom,image:null}:i.has(e.panelId)?{...e,needsRefresh:!0}:e);return ur(q({...e,strip:a}),t,{image:n})}}}let Si=()=>Object.assign(Error(`Zoom approval cancelled or its source changed.`),{name:`AbortError`});function Ci({doc:e,projectId:t,canEdit:n,onDocChange:r,editLease:i,settings:a,host:o,cropHost:s}){let c=H(o),l=bi(s),u=()=>c.actor(),d=u(),f=(0,v.useRef)(null),p=(0,v.useRef)(null),m=(0,v.useRef)(!0),h=(0,v.useRef)(0),g=(0,v.useRef)(new Set),[_,y]=(0,v.useState)(!1),[b,x]=(0,v.useState)(``),[S,C]=(0,v.useState)(null),[w,T]=(0,v.useState)(!1);f.current={doc:e,projectId:t,canEdit:n,onDocChange:r,actor:d,settings:a,services:c,cropService:l};let E=()=>{for(let e of[...g.current])e()},D=()=>{p.current&&(h.current++,p.current.abort(),T(!0),E())};return(0,v.useEffect)(()=>(m.current=!0,()=>{m.current=!1,h.current++,p.current?.abort(),E()}),[]),(0,v.useEffect)(E,[e,t,n,d,a,c,l]),(0,v.useEffect)(()=>{D()},[t,n,d,c,l,JSON.stringify(a)]),{run:async(n,r,o)=>{if(p.current||i.current)return;let s=f.current;if(s.services!==c||s.cropService!==l||s.actor!==d||u()!==d||s.doc!==e||s.projectId!==t||!s.canEdit)return;let _=new AbortController,v=++h.current;p.current=_,i.current=_,y(!0),T(!1),x(``),C(null);try{let i=JSON.stringify(e),p=JSON.stringify(a),y=i,b=new Set([i]),x=()=>{let e=f.current;if(!m.current||_.signal.aborted||h.current!==v||!d||e.actor!==d||u()!==d||e.projectId!==t||!e.canEdit||e.services!==c||e.cropService!==l||JSON.stringify(e.settings)!==p)throw Si()},S=()=>{if(x(),JSON.stringify(e)!==i||!b.has(JSON.stringify(f.current.doc)))throw Si()},w=async e=>{S();let t=y,n=JSON.stringify(e),r=!1;b.add(n),y=n,s.onDocChange(i=>{try{if(x(),JSON.stringify(e)!==n||JSON.stringify(i)!==t)throw Si();return e}catch{return r=!0,i}});let i=Date.now()+5e3;for(;;){if(S(),r||JSON.stringify(e)!==n)throw Si();if(JSON.stringify(f.current.doc)===n){b.clear(),b.add(n);return}if(Date.now()>=i)throw Si();await new Promise(e=>{let t,n=()=>{clearTimeout(t),g.current.delete(n),e()};g.current.add(n),t=setTimeout(n,Math.max(1,i-Date.now()))})}};S();let T=e.strip.find(e=>e.panelId===n),E=e.strip.find(e=>e.panelId===T?.sourcePanelId),D=E?$n(e.strip,E):null;if(!D)throw Error(`The zoom source has no image yet — build the strip first.`);let O=await J(e,n,r,{host:c,signal:_.signal,assertCurrent:S});S();let k=await l.crop(D,O.rect,{signal:_.signal,assertCurrent:S});S();let A=O.apply(k);await w(A),S(),await o({doc:A,downstream:O.downstream,check:S,commit:w,report:e=>{S(),C(e)},signal:_.signal,markStale:async()=>{S();let e=await J(A,n,{},{host:c,mode:`stale`,signal:_.signal,assertCurrent:S});return S(),A=e.apply(),await w(A),A}}),S()}catch(e){_.abort(),m.current&&p.current===_&&u()===d&&f.current.projectId===t&&x(e.message||`Zoom approval failed.`)}finally{p.current===_&&(i.current===_&&(i.current=null),p.current=null,m.current&&(y(!1),T(!1),C(null)))}},cancel:D,pending:_,error:b,progress:S,canceling:w}}let wi={manifest:{schemaVersion:1,sdkVersion:`0.1.0`,id:`stillmade-internal.panel-animation-edit`,version:`1.0.0`,name:`Panel animation editing`,description:`Accept a generated transition or change its playback settings.`,kind:`task`,runtime:`javascript`,inputs:{doc:{type:`json`},panelId:{type:`json`},action:{type:`json`},value:{type:`json`}},outputs:{edit:{type:`json`}},permissions:{project:[],network:[],filesystem:[],secrets:[]}},code:`function resolvePanelImage(strip, panel) {\n if (panel?.type === 'giphy') return panel.gif ?? panel.image ?? null;\n if (panel?.type === 'zoom') {\n // The stamped CROP is the zoom's frame (and the next edit's source). Until\n // the build crops it, fall back to the source's full frame so chains and\n // previews never break.\n if (panel.image) return panel.image;\n const zsrc = (strip || []).find((p) => p.panelId === panel.sourcePanelId);\n return zsrc ? resolvePanelImage(strip, zsrc) : null;\n }\n if (panel?.kind !== 'repeat') return panel?.image ?? null;\n const target = (strip || []).find((p) => p.panelId === panel.repeatOf);\n return target?.image ?? null;\n}\n\nfunction canAnimateGap(doc, panelId) {\n const i = doc.strip.findIndex((p) => p.panelId === panelId);\n if (i < 0 || i + 1 >= doc.strip.length) return false;\n const a = doc.strip[i];\n const b = doc.strip[i + 1];\n const imagePanel = (p) => p.type === 'panel' && !!resolvePanelImage(doc.strip, p);\n return imagePanel(a) && imagePanel(b) && a.sceneId === b.sceneId;\n}\n\n// Stamp (or clear, anim=null → the two panels cut directly again) the\n// animate-between block on the leading panel of an eligible gap.\nfunction setPanelAnimation(doc, panelId, anim) {\n if (anim != null && !canAnimateGap(doc, panelId)) {\n throw new Error(\\`setPanelAnimation: no animatable gap after \\${panelId}\\`);\n }\n const strip = doc.strip.map((p) => (p.panelId === panelId ? { ...p, animateNext: anim ?? null } : p));\n // Normalize: a cleared animation drops the field entirely.\n const cleaned = strip.map((p) => {\n if (p.panelId !== panelId || p.animateNext != null) return p;\n const { animateNext, ...rest } = p;\n return rest;\n });\n return loadPanelDoc({ ...doc, strip: cleaned });\n}\n\nfunction updatePanel(doc, panelId, patch) {\n const strip = doc.strip.map((p) => (p.panelId === panelId ? { ...p, ...patch, provenance: patch.provenance || 'user' } : p));\n return loadPanelDoc({ ...doc, strip });\n}\n\n\nconst loadPanelDoc=doc=>doc;const panel=input.doc.strip.find(row=>row.panelId===input.panelId);\nreturn {edit:input.action==='playback'?updatePanel(input.doc,input.panelId,{animateNext:{...panel.animateNext,...input.value}}):setPanelAnimation(input.doc,input.panelId,input.action==='remove'?null:input.value)};`,tests:[]},Ti=(e,t)=>e===void 0||t===void 0?e===t:V(e)===V(t);function Ei(e,t,n,r){let i=e.strip.find(e=>e.panelId===t);I(i&&e.strip.length<=2048&&[`generated`,`remove`,`playback`].includes(n),`ANIMATION_EDIT`,`Choose a current animation control.`);let a=n===`remove`?null:structuredClone(r);a!==null&&B(a),n===`playback`&&I(L(i.animateNext)&&L(a)&&Object.keys(a).length===1&&(Object.hasOwn(a,`fit`)&&typeof a.fit==`boolean`||Object.hasOwn(a,`durationSec`)&&[2,3,4].includes(a.durationSec)),`ANIMATION_EDIT`,`Choose fit or a supported playback window.`),n===`generated`&&I(dr(e,t)&&L(a)&&Object.keys(a).every(e=>[`model`,`durationSec`,`video`,`srcKey`,`genSeconds`,`fit`,`generatedAt`].includes(e))&&typeof a.video==`string`&&a.video.length>0,`ANIMATION_EDIT`,`The generated animation is unavailable.`);let o=new Map,s=e=>e&&(I(typeof e==`string`,`ANIMATION_EDIT`,`A source image is invalid.`),o.has(e)||o.set(e,`image-${o.size}`),o.get(e)),c={doc:{strip:e.strip.map(e=>{let t={};for(let n of[`panelId`,`type`,`kind`,`repeatOf`,`sourcePanelId`,`sceneId`])e[n]!==void 0&&(t[n]=e[n]);for(let n of[`image`,`gif`])e[n]!==void 0&&(t[n]=s(e[n]));return e===i&&e.animateNext!=null&&(t.animateNext=Object.fromEntries(Object.keys(e.animateNext).map(e=>[e,{old:e}]))),t})},panelId:t,action:n,value:n===`generated`?Object.fromEntries(Object.keys(a).map(e=>[e,{generated:e}])):a};return B(c),{panel:i,input:c,captured:a}}function Di(e,{panel:t,input:n,captured:r},i){let a={strip:n.doc.strip.map(e=>{if(e.panelId!==n.panelId)return e;let t={...e};return n.action===`remove`?delete t.animateNext:n.action===`generated`?t.animateNext=n.value:(t.animateNext={...e.animateNext,...n.value},t.provenance=`user`),t})};B(a),B(i),I(Ti(i,a),`ANIMATION_EDIT`,`The sandbox changed an unrequested animation or panel.`);let o=n.action===`playback`?{...t.animateNext,...r}:r;if(n.action===`remove`&&!Object.hasOwn(t,`animateNext`)||n.action!==`remove`&&Ti(t.animateNext,o)&&(n.action!==`playback`||t.provenance===`user`))return e;let s={...t};return n.action===`remove`?delete s.animateNext:s.animateNext=o,n.action===`playback`&&(s.provenance=`user`),{...e,strip:e.strip.map(e=>e===t?s:e)}}function Oi({doc:e,projectId:t,canEdit:n,onDocChange:r,validateDocument:i,editLease:a,host:o}){let s=H(o),c=()=>s.actor(),[l,u]=(0,v.useState)(null),[d,f]=(0,v.useState)(``),p=(0,v.useRef)(null),m=(0,v.useRef)(null),h=(0,v.useRef)(null),g=(0,v.useRef)(!0),_=(0,v.useRef)(0),y=(0,v.useRef)(null),b=c();y.current={doc:e,projectId:t,canEdit:n,onDocChange:r,validateDocument:i,actor:b,services:s};let x=(0,v.useCallback)(()=>{if(_.current++,h.current===p.current&&p.current){p.current.abort();return}a?.current===p.current&&(a.current=null),p.current?.abort(),p.current=null,u(null)},[a]);return(0,v.useEffect)(()=>(g.current=!0,()=>{g.current=!1,_.current++,a?.current===p.current&&(a.current=null),p.current?.abort(),p.current=null}),[]),(0,v.useEffect)(()=>{let e=m.current;if(e)try{let t=y.current;if(t.services===e.services&&t.actor===e.actor&&c()===e.actor&&t.projectId===e.projectId&&t.canEdit&&JSON.stringify(t.doc)===e.expected){e.resolve();return}}catch{}x()},[e,t,n,b,s,x]),{change:(0,v.useCallback)(async(n,r,i,o)=>{let l=y.current;if(!l.doc||!l.canEdit||p.current||a?.current)return;if(l.services!==s||l.doc!==e||l.projectId!==t||l.actor!==b||c()!==b){f(`The animation changed. Review the animation settings again.`);return}let d=++_.current,v=new AbortController;p.current=v,a&&(a.current=v),u(n),f(``);let x,S=()=>{let e=y.current;I(g.current&&p.current===v&&!v.signal.aborted&&e.doc===l.doc&&e.projectId===l.projectId&&e.canEdit&&e.services===l.services&&e.actor===l.actor&&c()===l.actor&&JSON.stringify(l.doc)===x,`STALE`,`The animation changed. Review the current animation settings again.`)};try{x=JSON.stringify(l.doc),S();let e=i;r===`generated`&&(I(dr(l.doc,n),`ANIMATION_EDIT`,`Both adjacent panels must have images in the same scene.`),h.current=v,e=await o(S),h.current=null,S());let t=Ei(l.doc,n,r,e);S();let a=await s.run(wi,{kind:`run`,input:t.input,signal:v.signal,timeoutMs:15e3});S();let u=Di(l.doc,t,a.outputs?.edit),p=u===l.doc?l.doc:l.validateDocument(u);S();let b=Promise.resolve();if(p!==l.doc){b=new Promise((e,t)=>{let n=()=>{clearTimeout(a),v.signal.removeEventListener(`abort`,i),m.current===r&&(m.current=null)},r={controller:v,services:l.services,actor:l.actor,projectId:l.projectId,expected:JSON.stringify(p),resolve:()=>{n(),e()},reject:(e,r=!1)=>{n(),!r&&g.current&&c()===l.actor&&y.current.projectId===l.projectId&&f(e.message||`The animation update was not accepted.`),v.abort(),t(e)}},i=()=>r.reject(Error(`The animation update was canceled.`),!0),a=setTimeout(()=>r.reject(Error(`The project did not acknowledge the animation update.`)),2e3);m.current=r,v.signal.addEventListener(`abort`,i,{once:!0})}),b.catch(()=>{});let e=!1;l.onDocChange(t=>{let n=y.current,r=!1;try{r=g.current&&_.current===d&&!v.signal.aborted&&n.doc===l.doc&&n.projectId===l.projectId&&n.canEdit&&n.services===l.services&&n.actor===l.actor&&c()===l.actor&&JSON.stringify(t)===x&&JSON.stringify(l.doc)===x}catch{}return r?p:(e||(e=!0,queueMicrotask(()=>{g.current&&c()===l.actor&&y.current.projectId===l.projectId&&f(`The animation changed before the animation settings could be saved. Review the current animation settings again.`),m.current?.controller===v&&m.current.reject(Error(`The project rejected the animation update`))})),t)})}return await b,I(g.current&&!v.signal.aborted&&_.current===d&&c()===l.actor&&y.current.projectId===l.projectId&&y.current.canEdit&&y.current.services===l.services,`STALE`,`The animation update scope changed.`),p}catch(e){m.current?.controller===v&&m.current.reject(e),g.current&&!v.signal.aborted&&c()===l.actor&&y.current.projectId===l.projectId&&f(e.message||`The animation settings could not be applied.`)}finally{h.current===v&&(h.current=null),p.current===v&&(a?.current===v&&(a.current=null),p.current=null,g.current&&u(null))}},[e,t,b,s]),pending:l,error:d,cancel:x}}let ki={manifest:{schemaVersion:1,sdkVersion:`0.1.0`,id:`stillmade-internal.text-placement`,version:`1.0.0`,name:`Panel label placement`,description:`Apply trusted indexed label placements while preserving existing positions and scene reuse.`,kind:`task`,runtime:`javascript`,inputs:{overlays:{type:`json`},indices:{type:`json`},placements:{type:`json`},seen:{type:`json`},mode:{type:`json`}},outputs:{overlays:{type:`json`}},permissions:{project:[],network:[],filesystem:[],secrets:[]}},code:`function sizeForRole(role){return role==='large'?0.13:role==='small'?0.04:0.07;}\nfunction applyPlacement(o,pl){return {...o,pos:pl.pos,size:o.size!=null?o.size:(o.role?sizeForRole(o.role):pl.size),...(pl.arrow?.to?{arrow:{...o.arrow,to:pl.arrow.to}}:{}),placedBy:'vision',editable:true};}\n// Original-index mapping preserves duplicate-text labels. Batch mode retains\n// existing positions and the original per-scene plain-label fallback behavior.\nfunction mergeTextPlacements(input){\n const placementByIdx=new Map(input.indices.map((idx,i)=>[idx,input.placements[i]]).filter(([,pl])=>pl));\n const seen=new Map(input.seen);\n return input.overlays.map((o,idx)=>{\n if(input.mode==='batch'&&o.pos)return o;\n const pl=placementByIdx.get(idx);if(pl)return applyPlacement(o,pl);\n const prior=input.mode==='batch'?seen.get(o.text):null;\n if(prior)return {...o,pos:prior.pos,size:o.size!=null?o.size:(o.role?sizeForRole(o.role):prior.size),placedBy:'vision',editable:true};\n return o;\n });\n}\n\nreturn {overlays:JSON.parse(JSON.stringify(mergeTextPlacements(input)))};`,tests:[]},Ai=(e,t)=>Object.fromEntries(t.filter(t=>e?.[t]!==void 0).map(t=>[t,e[t]])),ji=e=>JSON.parse(JSON.stringify(e,(e,t)=>(I(typeof t!=`number`||Number.isFinite(t),`TEXT_PLACEMENT`,`Label placement must remain finite.`),t))),Mi=e=>e==null?e:Ai(e,[`x`,`y`]);async function Ni(e,t,n,r,{mode:i=`batch`,signal:a,assertCurrent:o,host:s}){let c=H(s),l=c.actor(),u=()=>{o(),I(!a?.aborted&&l&&c.actor()===l,`STALE`,`The account or label placement changed. Review the current labels again.`)};u();let d=V(e);I(Array.isArray(e)&&e.length<=4096&&Array.isArray(t)&&Array.isArray(n)&&n.length<=4096&&r instanceof Map&&r.size<=4096,`TEXT_PLACEMENT`,`This label placement is too large.`),I([`batch`,`single`].includes(i)&&new Set(t).size===t.length&&t.every(t=>Number.isInteger(t)&&t>=0&&t<e.length),`TEXT_PLACEMENT`,`Label indices changed.`);let f=new Map,p=e=>(f.has(e)||f.set(e,`label-${f.size}`),f.get(e)),m=e=>({...Ai(e,[`size`,`role`]),...e.pos===void 0?{}:{pos:Mi(e.pos)},...e.arrow?{arrow:{...e.arrow.pointsAt?{pointsAt:!0}:{},...e.arrow.to===void 0?{}:{to:Mi(e.arrow.to)}}}:{}}),h=n.map(e=>e?structuredClone(e):null),g=new Map([...r].map(([e,t])=>[e,structuredClone(t)])),_=ji({mode:i,overlays:e.map((e,t)=>(I(L(e),`TEXT_PLACEMENT`,`A label is invalid.`),{origin:t,text:p(e.text),...m(e)})),indices:t,placements:h.map(e=>e?m(e):null),seen:[...g].map(([e,t])=>[p(e),m(t)])});B(_),I(JSON.stringify(_).length<=1048576,`TEXT_PLACEMENT`,`Label metadata exceeds 1 MiB.`);let v=new Map(t.map((e,t)=>[e,_.placements[t]]).filter(([,e])=>e)),y=new Map(_.seen),b=ji(_.overlays.map((e,t)=>{if(i===`batch`&&e.pos)return e;let n=v.get(t),r=i===`batch`?y.get(e.text):null,a=n||r;return a?{...e,pos:a.pos,size:e.size==null?e.role?e.role===`large`?.13:e.role===`small`?.04:.07:a.size:e.size,...n?.arrow?.to?{arrow:{...e.arrow,to:n.arrow.to}}:{},placedBy:`vision`,editable:!0}:e}));B(b);let x=await c.run(ki,{kind:`run`,input:_,signal:a,timeoutMs:15e3});u(),I(V(e)===d,`STALE`,`The labels changed while placement was running.`),B(x.outputs?.overlays),I(V(x.outputs.overlays)===V(b),`TEXT_PLACEMENT`,`The sandbox changed an unrequested label placement.`);let S=new Map(t.map((e,t)=>[e,h[t]]).filter(([,e])=>e));return e.map((e,t)=>{if(V(b[t])===V(_.overlays[t]))return e;let n=S.get(t),r=i===`batch`?g.get(e.text):null,a=n||r;return I(a,`TEXT_PLACEMENT`,`The approved placement is unavailable.`),{...e,pos:a.pos,size:b[t].size,...n?.arrow?.to?{arrow:{...e.arrow,to:n.arrow.to}}:{},placedBy:`vision`,editable:!0}})}let Pi=()=>Object.assign(Error(`Text placement cancelled or its document changed.`),{name:`AbortError`});function Fi({doc:e,projectId:t,canEdit:n,onDocChange:r,editLease:i,host:a}){let o=H(a),s=()=>o.actor(),c=s(),l=(0,v.useRef)(null),u=(0,v.useRef)(null),d=(0,v.useRef)(!0),f=(0,v.useRef)(0),p=(0,v.useRef)(new Set);l.current={doc:e,projectId:t,canEdit:n,onDocChange:r,actor:c,services:o};let m=()=>{for(let e of[...p.current])e()},h=()=>{f.current++,u.current?.abort(),i.current===u.current&&(i.current=null),u.current=null,m()};return(0,v.useEffect)(()=>(d.current=!0,()=>{d.current=!1,h()}),[]),(0,v.useEffect)(m,[e,t,n,c,o]),(0,v.useEffect)(()=>{h()},[t,n,c,o]),{run:async(e,t,n)=>{if(l.current.services!==o)throw Pi();if(u.current||i.current)return null;let r=new AbortController,a=++f.current;u.current=r,i.current=r;let c=()=>{};try{let i=JSON.stringify(e),u=()=>{let e=l.current;if(!d.current||r.signal.aborted||f.current!==a||!e.canEdit||e.services!==o||!t.actor||s()!==t.actor||e.actor!==t.actor||e.projectId!==t.projectId)throw Pi()},m=Date.now()+1e3;for(;u(),JSON.stringify(l.current.doc)!==i;){if(Date.now()>=m)throw Pi();await new Promise(e=>{let t,n=()=>{clearTimeout(t),p.current.delete(n),e()};p.current.add(n),t=setTimeout(n,Math.max(1,m-Date.now()))})}let h=()=>{if(u(),JSON.stringify(l.current.doc)!==i||JSON.stringify(e)!==i)throw Pi()};c=h,h();let g=await n({signal:r.signal,check:h});if(h(),g?.doc&&g.doc!==e){let e=l.current,t=JSON.stringify(g.doc),n=!1;c=()=>{u();let e=JSON.stringify(l.current.doc);if(n||JSON.stringify(g.doc)!==t||e!==i&&e!==t)throw Pi()},e.onDocChange(e=>{try{return u(),JSON.stringify(g.doc)!==t||JSON.stringify(e)!==i?(n=!0,e):g.doc}catch{return n=!0,e}});let r=Date.now()+5e3;for(;c(),JSON.stringify(l.current.doc)!==t;){if(Date.now()>=r)throw Pi();await new Promise(e=>{let t,n=()=>{clearTimeout(t),p.current.delete(n),e()};p.current.add(n),t=setTimeout(n,Math.max(1,r-Date.now()))})}}return g}catch(e){let n=e;try{c()}catch(e){n=e}let i=l.current.services!==o||r.signal.aborted||f.current!==a||s()!==t.actor||l.current.projectId!==t.projectId;throw r.abort(),i?Pi():n}finally{u.current===r&&(i.current===r&&(i.current=null),u.current=null)}},cancel:h,capture:()=>({actor:c,projectId:t})}}let Ii={manifest:{schemaVersion:1,sdkVersion:`0.1.0`,id:`stillmade-internal.edited-panel-image`,version:`1.0.0`,name:`Edited panel image acceptance`,description:`Save an edited image as the active version and flag downstream edits.`,kind:`task`,runtime:`javascript`,inputs:{doc:{type:`json`},panelId:{type:`text`},image:{type:`text`}},outputs:{edit:{type:`json`}},permissions:{project:[],network:[],filesystem:[],secrets:[]}},code:`function downstreamOf(strip, panelId) {\n const affected = new Set([panelId]);\n const out = [];\n for (const p of (strip || [])) {\n if (p.kind === 'edit' && p.sourcePanelId && affected.has(p.sourcePanelId)) {\n affected.add(p.panelId);\n out.push(p.panelId);\n }\n }\n return out;\n}\n\nfunction panelVersions(panel) {\n return panel.versions?.length ? panel.versions : (panel.image ? [panel.image] : []);\n}\n// Append a freshly generated/edited frame as the newest ACTIVE version.\nconst VERSION_CAP = 8;\nfunction pushPanelVersion(panel, url) {\n return [...panelVersions(panel).filter((v) => v !== url), url].slice(-VERSION_CAP);\n}\nfunction updatePanel(doc, panelId, patch) {\n const strip = doc.strip.map((p) => (p.panelId === panelId ? { ...p, ...patch, provenance: patch.provenance || 'user' } : p));\n return loadPanelDoc({ ...doc, strip });\n}\n\n\nconst loadPanelDoc=doc=>doc;const panel=input.doc.strip.find(row=>row.panelId===input.panelId);\nconst next=updatePanel(input.doc,input.panelId,{image:input.image,versions:pushPanelVersion(panel,input.image)});\nconst flagged=new Set(downstreamOf(next.strip,input.panelId));\nreturn {edit:flagged.size?{...next,strip:next.strip.map(row=>flagged.has(row.panelId)?{...row,needsRefresh:true}:row)}:next};`,tests:[]},Li=(e,t)=>e===void 0||t===void 0?e===t:V(e)===V(t);function Ri(e,t,n){let r=e.strip.find(e=>e.panelId===t);I(r&&typeof n==`string`&&n.length>0&&n.length<=16384&&e.strip.length<=2048,`EDITED_IMAGE`,`The edited image cannot be applied to this panel.`);let i=new Map,a=e=>e&&(I(typeof e==`string`,`EDITED_IMAGE`,`A saved image reference is invalid.`),i.has(e)||i.set(e,`image-${i.size}`),i.get(e)),o={doc:{strip:e.strip.map(e=>{let t={};for(let n of[`panelId`,`kind`,`sourcePanelId`,`needsRefresh`,`provenance`])e[n]!==void 0&&(t[n]=e[n]);return e===r&&(e.image!==void 0&&(t.image=a(e.image)),e.versions!==void 0&&(I(Array.isArray(e.versions)&&e.versions.length<=1024,`EDITED_IMAGE`,`The image history is too large.`),t.versions=e.versions.map(a))),t})},panelId:t,image:a(n)};return B(o),{panel:r,input:o,url:n}}function zi(e,{panel:t,input:n,url:r},i){let a=n.doc.strip.find(e=>e.panelId===n.panelId),o=[...(a.versions?.length?a.versions:a.image?[a.image]:[]).filter(e=>e!==n.image),n.image].slice(-8),s=new Set([n.panelId]),c=new Set;for(let e of n.doc.strip)e.kind===`edit`&&e.sourcePanelId&&s.has(e.sourcePanelId)&&(s.add(e.panelId),c.add(e.panelId));let l={strip:n.doc.strip.map(e=>({...e,...e===a?{image:n.image,versions:o,provenance:`user`}:{},...c.has(e.panelId)?{needsRefresh:!0}:{}}))};B(i),B(l),I(Li(i,l),`EDITED_IMAGE`,`The sandbox changed an unrequested image, history or dependency.`);let u=[...(t.versions?.length?t.versions:t.image?[t.image]:[]).filter(e=>e!==r),r].slice(-8),d=!1,f=e.strip.map(e=>{let n={};return e===t&&(n={image:r,versions:Li(e.versions,u)?e.versions:u,provenance:`user`}),c.has(e.panelId)&&(n.needsRefresh=!0),Object.keys(n).every(t=>Li(e[t],n[t]))?e:(d=!0,{...e,...n})});return{doc:d?{...e,strip:f}:e,flagged:c.size}}function Bi({doc:e,projectId:t,editing:n,canEdit:r,onDocChange:i,validateDocument:a,editLease:o,host:s}){let c=H(s),l=()=>c.actor(),u=l(),d=(0,v.useRef)(null),f=(0,v.useRef)(null),p=(0,v.useRef)(null),m=(0,v.useRef)(0),h=(0,v.useRef)(!0),[g,_]=(0,v.useState)(null),[y,b]=(0,v.useState)(``);d.current={doc:e,projectId:t,editing:n,canEdit:r,onDocChange:i,validateDocument:a,actor:u,services:c},(0,v.useEffect)(()=>{let e=f.current;if(e)try{let t=d.current;I(h.current&&t.services===e.services&&t.editing===e.editing&&t.actor===e.actor&&l()===e.actor&&t.projectId===e.projectId&&t.canEdit,`STALE`,`The image-save scope changed.`);let n=JSON.stringify(t.doc);n===e.expected?e.resolve():n!==e.before&&e.reject(Error(`The project changed before accepting the edited image.`))}catch(t){e.reject(t)}},[e,t,n,r,u,c]);let x=()=>{m.current++,p.current?.abort(),o.current===p.current&&(o.current=null),p.current=null,_(null)};return(0,v.useEffect)(()=>(h.current=!0,()=>{h.current=!1,m.current++,p.current?.abort(),o.current===p.current&&(o.current=null),p.current=null}),[o]),(0,v.useEffect)(()=>{x()},[c]),{begin:r=>{let i=d.current;I(i.services===c&&i.doc===e&&i.projectId===t&&i.actor===u&&l()===u&&i.editing===n&&n===r&&i.canEdit&&!p.current&&!o.current,`STALE`,`Review the current panel before saving its edited image.`);let a=JSON.stringify(i.doc),s=new AbortController,g=++m.current;p.current=s,o.current=s,_(r),b(``);let v=()=>{let e=d.current;I(h.current&&!s.signal.aborted&&m.current===g&&e.services===i.services&&e.actor===i.actor&&l()===i.actor&&e.projectId===i.projectId&&e.canEdit&&e.doc===i.doc&&JSON.stringify(i.doc)===a&&e.editing===i.editing,`STALE`,`The panel changed before its edited image was saved.`)},y=()=>{p.current===s&&(o.current===s&&(o.current=null),p.current=null,h.current&&_(null))};return{check:v,finish:y,cancel:()=>{s.abort(),y()},save:async e=>{v();try{let t=Ri(i.doc,r,e),n=await c.run(Ii,{kind:`run`,input:t.input,signal:s.signal,timeoutMs:15e3});v();let o=zi(i.doc,t,n.outputs?.edit),u=o.doc===i.doc?i.doc:i.validateDocument(o.doc);v();let p=Promise.resolve();return u!==i.doc&&(p=new Promise((e,t)=>{let n=()=>{clearTimeout(c),s.signal.removeEventListener(`abort`,o),f.current===r&&(f.current=null)},r={controller:s,services:i.services,editing:i.editing,actor:i.actor,projectId:i.projectId,before:a,expected:JSON.stringify(u),resolve:()=>{n(),e()},reject:e=>{n(),s.abort(),t(e)}},o=()=>r.reject(Error(`The edited image save was canceled.`)),c=setTimeout(()=>{r.reject(Error(`The edited image was not acknowledged by the project. Review its current version before saving again.`)),s.abort()},2e3);f.current=r,s.signal.addEventListener(`abort`,o,{once:!0})}),p.catch(()=>{}),i.onDocChange(e=>{try{let t=d.current;return I(h.current&&!s.signal.aborted&&m.current===g&&t.services===i.services&&t.actor===i.actor&&l()===i.actor&&t.projectId===i.projectId&&t.canEdit&&t.editing===i.editing&&JSON.stringify(e)===a&&JSON.stringify(i.doc)===a,`STALE`,`The project changed before saving.`),u}catch{return queueMicrotask(()=>{h.current&&l()===i.actor&&d.current.projectId===i.projectId&&b(`The project changed before the edited image could be saved.`),f.current?.controller===s&&f.current.reject(Error(`The project rejected the edited image update.`))}),e}})),await p,I(h.current&&!s.signal.aborted&&m.current===g&&l()===i.actor&&d.current.projectId===i.projectId&&d.current.canEdit&&d.current.services===i.services&&d.current.editing===i.editing,`STALE`,`The image-save scope changed.`),{flagged:o.flagged}}catch(e){throw f.current?.controller===s&&f.current.reject(e),h.current&&!s.signal.aborted&&l()===i.actor&&d.current.projectId===i.projectId&&b(e.message||`The edited image could not be saved.`),e}}}},pending:g,error:y,cancel:x}}let Y={manifest:{schemaVersion:1,sdkVersion:`0.1.0`,id:`stillmade-internal.gif-search-edit`,version:`1.0.0`,name:`GIF search selection`,description:`Apply a captured GIF search result or remove a GIF overlay.`,kind:`task`,runtime:`javascript`,inputs:{doc:{type:`json`},action:{type:`json`},query:{type:`json`},results:{type:`json`}},outputs:{edit:{type:`json`}},permissions:{project:[],network:[],filesystem:[],secrets:[]}},code:`function updatePanel(doc, panelId, patch) {\n const strip = doc.strip.map((p) => (p.panelId === panelId ? { ...p, ...patch, provenance: patch.provenance || 'user' } : p));\n return loadPanelDoc({ ...doc, strip });\n}\n\n\nconst loadPanelDoc=doc=>doc;const panel=input.doc.strip[0];let patch;\nif(input.action==='remove')patch={overlayLayer:null};\nelse if(input.action==='overlay')patch={overlayLayer:{...(panel.overlayLayer||{mode:'overlay'}),gifUrl:input.results[0],gifQuery:input.query}};\nelse patch={gif:input.results[0],gifQuery:input.query,candidates:input.results.slice(0,6)};\nreturn {edit:updatePanel(input.doc,panel.panelId,patch)};`,tests:[]},Vi=(e,t)=>e===void 0||t===void 0?e===t:V(e)===V(t);function Hi(e,t,n,r,i){let a=e.strip.find(e=>e.panelId===t);I(a,`GIF_SEARCH`,`The GIF target is no longer available.`);let o=i.map(e=>e?.url);I(n===`remove`||o.length&&o.every(e=>typeof e==`string`&&e.length>0&&e.length<=8192),`GIF_SEARCH`,`The GIF search returned an invalid result.`);let s={panelId:t,type:a.type};a.overlayLayer!=null&&(I(L(a.overlayLayer),`GIF_SEARCH`,`This overlay cannot be edited.`),s.overlayLayer=Object.fromEntries(Object.keys(a.overlayLayer).map(e=>[e,{previous:e}])));let c={doc:{strip:[s]},action:n,query:{query:!0},results:o.map((e,t)=>({result:t}))};B(c);let l,u;return n===`remove`?(l={overlayLayer:null},u=l):n===`overlay`?(l={overlayLayer:{...a.overlayLayer||{mode:`overlay`},gifUrl:o[0],gifQuery:r}},u={overlayLayer:{...s.overlayLayer||{mode:`overlay`},gifUrl:c.results[0],gifQuery:c.query}}):(l={gif:o[0],gifQuery:r,candidates:o},u={gif:c.results[0],gifQuery:c.query,candidates:c.results}),{panel:a,input:c,patch:l,expected:{strip:[{...s,...u,provenance:`user`}]}}}function Ui(e,{panel:t,patch:n,expected:r},i){return B(i),I(Vi(i,r),`GIF_SEARCH`,`The sandbox changed an unrelated GIF or field.`),t.provenance===`user`&&Object.keys(n).every(e=>Vi(t[e],n[e]))?e:{...e,strip:e.strip.map(e=>e===t?{...e,...n,provenance:`user`}:e)}}function Wi({doc:e,projectId:t,canEdit:n,onDocChange:r,validateDocument:i,editLease:a,host:o}){let s=H(o),c=()=>s.actor(),[l,u]=(0,v.useState)(null),[d,f]=(0,v.useState)(``),p=(0,v.useRef)(null),m=(0,v.useRef)(!0),h=(0,v.useRef)(0),g=(0,v.useRef)(null),_=c();g.current={doc:e,projectId:t,canEdit:n,onDocChange:r,validateDocument:i,actor:_,services:s};let y=(0,v.useCallback)(()=>{h.current++,a?.current===p.current&&(a.current=null),p.current?.abort(),p.current=null,u(null)},[a]);return(0,v.useEffect)(()=>(m.current=!0,()=>{m.current=!1,h.current++,a?.current===p.current&&(a.current=null),p.current?.abort(),p.current=null}),[]),(0,v.useEffect)(()=>{y()},[e,t,n,_,s,y]),{change:(0,v.useCallback)(async(n,r,i,o,l)=>{let d=g.current;if(!d.doc||!d.canEdit||p.current||a?.current)return;if(d.services!==s||d.doc!==e||d.projectId!==t||d.actor!==_||c()!==_){f(`The GIF changed. Review the GIF selection again.`);return}let v=++h.current,y=new AbortController;p.current=y,a&&(a.current=y),u(n),f(``);let b,x=()=>{let e=g.current;I(m.current&&p.current===y&&!y.signal.aborted&&e.doc===d.doc&&e.projectId===d.projectId&&e.canEdit&&e.services===d.services&&e.actor===d.actor&&c()===d.actor&&JSON.stringify(d.doc)===b,`STALE`,`The GIF changed. Review the current GIF selection again.`)};try{b=JSON.stringify(d.doc),x();let e=d.doc.strip.find(e=>e.panelId===n);I(e&&(r===`remove`||r===`overlay`||r===`replace`&&e.type===`giphy`),`GIF_SEARCH`,`Choose a current GIF target.`);let t=[],a=String(i||``).trim();if(r!==`remove`){if(!a)return;I(a.length<=1024,`GIF_SEARCH`,`Use a shorter GIF query.`);let e=await o(a);if(x(),e?.enabled===!1){l?.(`Giphy is unavailable right now.`);return}if(t=Array.isArray(e?.results)?e.results.slice(0,r===`overlay`?1:6):[],!t.length){l?.(`No GIFs matched that search.`);return}}let u=Hi(d.doc,n,r,a,t);x();let p=await s.run(Y,{kind:`run`,input:u.input,signal:y.signal,timeoutMs:15e3});x();let _=Ui(d.doc,u,p.outputs?.edit),S=_===d.doc?d.doc:d.validateDocument(_);if(x(),S!==d.doc){let e=!1;d.onDocChange(t=>{let n=g.current,r=!1;try{r=m.current&&h.current===v&&!y.signal.aborted&&n.doc===d.doc&&n.projectId===d.projectId&&n.canEdit&&n.services===d.services&&n.actor===d.actor&&c()===d.actor&&JSON.stringify(t)===b&&JSON.stringify(d.doc)===b}catch{}return r?S:(e||(e=!0,queueMicrotask(()=>{m.current&&c()===d.actor&&g.current.projectId===d.projectId&&f(`The GIF changed before the GIF selection could be saved. Review the current GIF selection again.`)})),t)})}return S}catch(e){m.current&&!y.signal.aborted&&c()===d.actor&&g.current.projectId===d.projectId&&f(e.message||`The GIF selection could not be applied.`)}finally{p.current===y&&(a?.current===y&&(a.current=null),p.current=null,m.current&&u(null))}},[e,t,_,s]),pending:l,error:d,cancel:y}}let Gi={manifest:{schemaVersion:1,sdkVersion:`0.1.0`,id:`stillmade-internal.panel-document-settings`,version:`1.1.0`,name:`Image panel document settings`,description:`Change the existing frame shape, quality checks or video type metadata without changing built panels.`,kind:`task`,runtime:`javascript`,inputs:{kind:{type:`text`},value:{type:`json`},meta:{type:`json`}},outputs:{edit:{type:`json`}},permissions:{project:[],network:[],filesystem:[],secrets:[]}},code:`// Full original metadata transformations from Strip's document settings controls.\nfunction panelDocumentSetting(input){\n if(input.kind==='aspect')return {meta:{...input.meta,aspect:input.value}};\n if(input.kind==='quality')return {meta:{...input.meta,qaConsistency:input.value}};\n if(input.kind==='type')return {projectType:input.value.type,projectTypeNote:input.value.note};\n throw new Error('Unsupported panel document setting');\n}\n\nreturn {edit:panelDocumentSetting(input)};`,tests:[]};function Ki(e){return H(e),I(typeof e.confirm==`function`&&typeof e.prompt==`function`,`HOST_SERVICES`,`Image Panels settings require confirmation and text-entry services.`),e}let qi=e=>JSON.stringify(e),Ji=()=>Object.assign(Error(`The project changed. Review its settings again.`),{name:`AbortError`});function Yi({doc:e,projectId:t,aspect:n,projectType:r,projectTypeNote:i,projectTypes:a,onProjectTypeChange:o,canEdit:s,onDocChange:c,onAspectChange:l,validateDocument:u,editLease:d,host:f}){let p=Ki(f),m=()=>p.actor(),h=m(),g=(0,v.useRef)(null),_=(0,v.useRef)(null),y=(0,v.useRef)(!0),b=(0,v.useRef)(0),[x,S]=(0,v.useState)(null),[C,w]=(0,v.useState)(``);g.current={doc:e,projectId:t,aspect:n,projectType:r,projectTypeNote:i,projectTypes:a,onProjectTypeChange:o,canEdit:s,onDocChange:c,onAspectChange:l,validateDocument:u,actor:h,services:p};let T=e=>{clearTimeout(e.timer),_.current===e&&(_.current=null,d.current===e.controller&&(d.current=null),y.current&&S(null))};return(0,v.useEffect)(()=>(y.current=!0,()=>{y.current=!1,b.current++;let e=_.current;e&&(e.controller.abort(),clearTimeout(e.timer),d.current===e.controller&&(d.current=null),_.current=null)}),[]),(0,v.useEffect)(()=>{let e=_.current;e&&e.scope.services!==p&&(b.current++,e.controller.abort(),T(e))},[p]),(0,v.useEffect)(()=>{let e=_.current;if(e&&e.phase===`applying`)try{e.identity();let t=qi(g.current.doc);if(t===e.expectedSignature)e.acceptHeader(),T(e);else if(t!==e.originalSignature)throw Ji()}catch(t){e.controller.abort(),y.current&&m()===e.scope.actor&&w(t.message),T(e)}},[e,t,n,r,i,s,h,p,x]),{change:async(a,o)=>{let s=g.current;if(!s.canEdit||_.current||d.current||s.services!==p||s.doc!==e||s.projectId!==t||s.aspect!==n||s.projectType!==r||s.projectTypeNote!==i||s.actor!==h||m()!==h)return;let c=s.doc?.meta?.aspect||s.aspect;if(a===`aspect`&&o===c||a===`quality`&&s.doc?.meta?.qaConsistency===o)return;let l={scope:s,kind:a,value:o,controller:new AbortController,generation:++b.current,phase:`preparing`};_.current=l,d.current=l.controller,S(a),w(``);try{l.originalSignature=qi(s.doc),l.identity=()=>{let e=g.current;if(!y.current||l.controller.signal.aborted||b.current!==l.generation||!e.canEdit||e.services!==s.services||!s.actor||e.actor!==s.actor||m()!==s.actor||e.projectId!==s.projectId||e.aspect!==s.aspect||e.projectType!==s.projectType||e.projectTypeNote!==s.projectTypeNote)throw Ji()};let e=()=>{if(l.identity(),qi(g.current.doc)!==l.originalSignature||qi(s.doc)!==l.originalSignature)throw Ji()};if(e(),I(a===`aspect`&&[`16:9`,`9:16`,`1:1`,`4:3`,`3:4`].includes(o)||a===`quality`&&typeof o==`boolean`||a===`type`&&(o===null||Array.isArray(s.projectTypes)&&s.projectTypes.includes(o)),`PANEL_SETTINGS`,`Choose a supported document setting.`),a===`aspect`){if(!await p.confirm(`Switch the whole video to ${o}? This is the project's frame shape — already-built panels keep their current shape until you regenerate them.`,{title:`Change aspect ratio`,confirmText:`Switch to ${o}`})){T(l);return}e()}let t=s.projectTypeNote;a===`type`&&o===`neither`&&(t=await p.prompt(`Describe what this video is:`,s.projectTypeNote||``,{title:`Project type`})??s.projectTypeNote,e());let n={kind:a,value:a===`type`?{type:o,note:o===`neither`&&t?`host-note`:null}:o,meta:{preserved:`host-metadata`}},r=a===`type`?{projectType:o,projectTypeNote:n.value.note}:{meta:{...n.meta,...a===`aspect`?{aspect:o}:{qaConsistency:o}}};l.acceptHeader=()=>{l.kind===`aspect`?l.scope.onAspectChange?.(l.value):l.kind===`type`&&l.scope.onProjectTypeChange?.(l.value,l.value===`neither`?t:``)};let i=await p.run(Gi,{kind:`run`,input:n,signal:l.controller.signal,timeoutMs:15e3});if(e(),B(i.outputs?.edit),I(V(i.outputs.edit)===V(r),`PANEL_SETTINGS`,`The sandbox changed an unrequested setting.`),!s.doc){I(a===`aspect`||a===`type`,`PANEL_SETTINGS`,`Create a document before changing quality checks.`),e(),l.acceptHeader(),T(l);return}let c=a===`type`?null:a===`aspect`?{aspect:i.outputs.edit.meta.aspect}:{qaConsistency:i.outputs.edit.meta.qaConsistency},u=s.validateDocument(a===`type`?{...s.doc,projectType:i.outputs.edit.projectType||void 0,projectTypeNote:i.outputs.edit.projectTypeNote?t:void 0}:{...s.doc,meta:{...s.doc.meta||{},...c}});e(),l.expectedSignature=qi(u),l.phase=`applying`,l.timer=setTimeout(()=>{if(_.current===l){try{if(l.identity(),qi(g.current.doc)===l.expectedSignature){l.acceptHeader(),T(l);return}}catch{}l.controller.abort(),y.current&&w(`The settings change was not accepted. Review the current project and try again.`),T(l)}},5e3),s.onDocChange(e=>{try{return l.identity(),qi(e)===l.originalSignature?l.expectedSignature===l.originalSignature?e:u:e}catch{return e}}),S(a+`-applying`)}catch(e){l.controller.abort(),y.current&&m()===s.actor&&g.current.projectId===s.projectId&&e?.name!==`AbortError`&&w(e.message||`The setting could not be changed.`),T(l)}},pending:x,error:C,cancel:()=>{let e=_.current;e?.phase!==`applying`&&(b.current++,e&&(e.controller.abort(),T(e)))}}}let Xi={manifest:{schemaVersion:1,sdkVersion:`0.1.0`,id:`stillmade-internal.scene-edit`,version:`1.0.0`,name:`Scene editing`,description:`Apply the reviewed scene title, genre or title-screen appearance edit.`,kind:`task`,runtime:`javascript`,inputs:{doc:{type:`json`},sceneId:{type:`text`},patch:{type:`json`}},outputs:{edit:{type:`json`}},permissions:{project:[],network:[],filesystem:[],secrets:[]}},code:`function updateScene(doc, sceneId, patch) {\n const scenes = (doc.scenes || []).map((s) => (s.sceneId === sceneId ? { ...s, ...patch } : s));\n return loadPanelDoc({ ...doc, scenes });\n}\n\nconst loadPanelDoc=doc=>doc;return {edit:updateScene(input.doc,input.sceneId,input.patch)};`,tests:[]},Zi=(e,t)=>e===void 0||t===void 0?e===t:V(e)===V(t);function Qi(e,t,n){let r=e.scenes?.find(e=>e.sceneId===t);I(r&&L(n)&&Object.keys(n).length===1&&Object.keys(n).every(e=>[`title`,`genre`,`titleScreen`].includes(e)),`SCENE_EDIT`,`Choose a supported scene control.`);let i=structuredClone(n);if(B(i),Object.hasOwn(i,`title`)&&I(typeof i.title==`string`,`SCENE_EDIT`,`The scene title must be text.`),Object.hasOwn(i,`genre`)&&I([null,`story`,`explainer`].includes(i.genre),`SCENE_EDIT`,`Choose an available scene genre.`),Object.hasOwn(i,`titleScreen`)){let e=i.titleScreen,t=r.titleScreen||{};I(L(e),`SCENE_EDIT`,`Title-screen settings must be an object.`);for(let n of new Set([...Object.keys(t),...Object.keys(e)]))[`template`,`text`,`font`,`animation`].includes(n)||I(Zi(t[n],e[n]),`SCENE_EDIT`,`An unrelated title-screen setting changed.`);if(e.font!==void 0){I(L(e.font),`SCENE_EDIT`,`Font settings must be an object.`);for(let n of new Set([...Object.keys(t.font||{}),...Object.keys(e.font)]))[`family`,`size`,`color`,`weight`].includes(n)||I(Zi(t.font?.[n],e.font[n]),`SCENE_EDIT`,`An unrelated font setting changed.`)}}I(JSON.stringify(i).length<=65536,`SCENE_EDIT`,`These scene settings are too large.`);let a={doc:{scenes:[{sceneId:t}]},sceneId:t,patch:Object.fromEntries(Object.keys(i).map(e=>[e,{field:e}]))};return B(a),{scene:r,captured:i,input:a}}function $i(e,{scene:t,captured:n,input:r},i){B(i);let a={scenes:[{sceneId:t.sceneId,...r.patch}]};if(I(Zi(i,a),`SCENE_EDIT`,`The sandbox changed an unrequested scene or setting.`),Object.keys(n).every(e=>Zi(t[e],n[e])))return e;let o={...t,...n};return{...e,scenes:e.scenes.map(e=>e===t?o:e)}}function ea({doc:e,projectId:t,canEdit:n,onDocChange:r,validateDocument:i,editLease:a,host:o}){let s=H(o),c=()=>s.actor(),[l,u]=(0,v.useState)(null),[d,f]=(0,v.useState)(``),p=(0,v.useRef)(null),m=(0,v.useRef)(!0),h=(0,v.useRef)(0),g=(0,v.useRef)(null),_=c();g.current={doc:e,projectId:t,canEdit:n,onDocChange:r,validateDocument:i,actor:_,services:s};let y=(0,v.useCallback)(()=>{h.current++,a?.current===p.current&&(a.current=null),p.current?.abort(),p.current=null,u(null)},[a]);return(0,v.useEffect)(()=>(m.current=!0,()=>{m.current=!1,h.current++,a?.current===p.current&&(a.current=null),p.current?.abort(),p.current=null}),[]),(0,v.useEffect)(()=>{y()},[e,t,n,_,s,y]),{change:(0,v.useCallback)(async(n,r)=>{let i=g.current;if(!i.doc||!i.canEdit||p.current||a?.current)return;if(i.services!==s||i.doc!==e||i.projectId!==t||i.actor!==_||c()!==_){f(`The scene changed. Review the scene settings again.`);return}let o=++h.current,l=new AbortController;p.current=l,a&&(a.current=l),u(n),f(``);let d,v=()=>{let e=g.current;I(m.current&&p.current===l&&!l.signal.aborted&&e.doc===i.doc&&e.projectId===i.projectId&&e.canEdit&&e.services===i.services&&e.actor===i.actor&&c()===i.actor&&JSON.stringify(i.doc)===d,`STALE`,`The scene changed. Review the current scene settings again.`)};try{d=JSON.stringify(i.doc);let e=Qi(i.doc,n,r);v();let t=await s.run(Xi,{kind:`run`,input:e.input,signal:l.signal,timeoutMs:15e3});v();let a=$i(i.doc,e,t.outputs?.edit),u=a===i.doc?i.doc:i.validateDocument(a);if(v(),u!==i.doc){let e=!1;i.onDocChange(t=>{let n=g.current,r=!1;try{r=m.current&&h.current===o&&!l.signal.aborted&&n.doc===i.doc&&n.projectId===i.projectId&&n.canEdit&&n.services===i.services&&n.actor===i.actor&&c()===i.actor&&JSON.stringify(t)===d&&JSON.stringify(i.doc)===d}catch{}return r?u:(e||(e=!0,queueMicrotask(()=>{m.current&&c()===i.actor&&g.current.projectId===i.projectId&&f(`The scene changed before the scene settings could be saved. Review the current scene settings again.`)})),t)})}return u}catch(e){m.current&&!l.signal.aborted&&c()===i.actor&&g.current.projectId===i.projectId&&f(e.message||`The scene settings could not be applied.`)}finally{p.current===l&&(a?.current===l&&(a.current=null),p.current=null,m.current&&u(null))}},[e,t,_,s]),pending:l,error:d,cancel:y}}function ta({value:e,onChange:t,type:n,...r}){let[i,a]=(0,v.useState)(e),o=(0,v.useRef)({value:e,onChange:t}),s=(0,v.useRef)(e),c=(0,v.useRef)(String(e));o.current={value:e,onChange:t},(0,v.useEffect)(()=>{a(e),s.current=e,c.current=String(e)},[e]);let l=()=>{let e=o.current.value;a(e),s.current=e,c.current=String(e)},u=async()=>{let e=s.current;if(String(e)!==c.current){c.current=String(e);try{await o.current.onChange({target:{value:e}})||l()}catch{l()}}};return(0,D.jsx)(`input`,{...r,type:n,value:i,onChange:e=>{s.current=e.target.value,a(e.target.value)},onBlur:u,onPointerUp:()=>{(n===`range`||n===`color`)&&u()},onPointerCancel:l,onKeyDown:e=>{e.key===`Enter`&&(e.preventDefault(),u()),e.key===`Escape`&&(e.preventDefault(),l())},onKeyUp:e=>{n===`range`&&[`ArrowLeft`,`ArrowRight`,`ArrowUp`,`ArrowDown`,`Home`,`End`,`PageUp`,`PageDown`].includes(e.key)&&u()}})}let na={manifest:{schemaVersion:1,sdkVersion:`0.1.0`,id:`stillmade-internal.panel-style`,version:`1.0.0`,name:`Panel style application`,description:`Apply a reviewed style and optionally clear existing panel images.`,kind:`task`,runtime:`javascript`,inputs:{mode:{type:`json`},rows:{type:`json`},refs:{type:`json`},text:{type:`json`},aspect:{type:`json`},oldStyle:{type:`json`},builtin:{type:`json`}},outputs:{edit:{type:`json`}},permissions:{project:[],network:[],filesystem:[],secrets:[]}},code:`const DEFAULT_PANEL_STYLES=[{\"text\": \"Stickman meme-comic animation style: simple stick-figure characters with thin black stick limbs and large round heads, exaggerated rage-comic facial expressions with bold black outlines (gritted bared teeth, wide beady or bloodshot eyes, heavy angry brows), flat cel-shaded color fills with soft directional shading, plain simple environments, thick consistent black outlines throughout, no photorealism.\"}];\nfunction buildStyleBlock({ aspect = '16:9', styleNotes = '', styleText = DEFAULT_PANEL_STYLES[0].text } = {}) {\n const extra = styleNotes ? \\` \\${String(styleNotes).trim()}\\` : '';\n return \\`\\${styleText}\\${extra} \\${aspect} framing.\\`;\n}\n\n\nif(input.mode==='clear')return {edit:input.rows.map(row=>({...row,image:null,needsRefresh:false}))};\nconst refs=input.refs;\nreturn {edit:{styleBlock:input.text?buildStyleBlock({aspect:input.aspect,styleText:input.text}):input.oldStyle,styleRef:refs[0]||null,styleRefs:refs,styleRefsHidden:input.builtin}};\n`,tests:[]},ra=(e,t)=>e===void 0||t===void 0?e===t:V(e)===V(t),ia=()=>Object.assign(Error(`The project changed. Review the current style again.`),{name:`AbortError`});async function aa(e,t,n,{signal:r,check:i,services:a}){let o=t.refs.map((e,t)=>({reference:t})),s={mode:n,rows:n===`clear`?e.strip.map((e,t)=>({index:t})):[],refs:o,text:t.text,aspect:t.aspect,oldStyle:{existingStyle:!0},builtin:t.builtin};B(s),I(e.strip.length<=2048&&JSON.stringify(s).length<=1048576,`PANEL_STYLE`,`This style change is too large.`);let c=n===`clear`?s.rows.map(e=>({...e,image:null,needsRefresh:!1})):{styleBlock:t.text?`${t.text} ${t.aspect} framing.`:s.oldStyle,styleRef:o[0]||null,styleRefs:o,styleRefsHidden:t.builtin};i();let l=await a.run(na,{kind:`run`,input:s,signal:r,timeoutMs:15e3});if(i(),B(l.outputs?.edit),B(c),I(ra(l.outputs.edit,c),`PANEL_STYLE`,`The sandbox changed an unrequested style, reference or panel.`),n===`clear`){let t=!1,n=e.strip.map(e=>e.image===null&&e.needsRefresh===!1?e:(t=!0,{...e,image:null,needsRefresh:!1}));return t?{...e,strip:n}:e}let u=t.text?l.outputs.edit.styleBlock:e.styleBlock,d=e.meta?.styleRefs,f=Array.isArray(d)&&ra(d,t.refs)?d:t.refs,p={...e.meta,styleRef:f[0]||null,styleRefs:f,styleRefsHidden:t.builtin};return ra(u,e.styleBlock)&&ra(p,e.meta)?e:{...e,styleBlock:u,meta:p}}function oa({doc:e,projectId:t,aspect:n,canEdit:r,onDocChange:i,validateDocument:a,editLease:o,host:s}){let c=H(s),l=()=>c.actor(),u=l(),d=(0,v.useRef)(null),f=(0,v.useRef)(null),p=(0,v.useRef)(0),m=(0,v.useRef)(!0),[h,g]=(0,v.useState)(!1),[_,y]=(0,v.useState)(``);d.current={doc:e,projectId:t,aspect:n,canEdit:r,onDocChange:i,validateDocument:a,actor:u,services:c};let b=(0,v.useCallback)(()=>{p.current++,f.current?.abort(),o.current===f.current&&(o.current=null),f.current=null,g(!1)},[o]);return(0,v.useEffect)(()=>(m.current=!0,()=>{m.current=!1,p.current++,f.current?.abort(),o.current===f.current&&(o.current=null),f.current=null}),[o]),(0,v.useEffect)(()=>{b()},[c,b]),{apply:async({text:r=null,styleRef:i=null,styleRefs:a=null,name:s=`Style`,builtin:h=!1}={},_,v)=>{let b=d.current;if(!b.doc||!b.canEdit||f.current||o.current)return;if(b.services!==c||b.doc!==e||b.projectId!==t||b.aspect!==n||b.actor!==u||l()!==u){y(`The project changed. Review its current style.`);return}let x=new AbortController,S=++p.current;f.current=x,o.current=x,g(!0),y(``);try{I(r===null||typeof r==`string`,`PANEL_STYLE`,`Style text must be text.`);let e=structuredClone(Array.isArray(a)?a.filter(Boolean):i?[i]:[]),t={text:r,refs:e,builtin:!!h,aspect:b.doc.meta?.aspect||b.aspect};I(typeof t.aspect==`string`&&t.aspect.length<=32&&e.length<=128,`PANEL_STYLE`,`Choose a supported style reference set.`);let n=JSON.stringify(b.doc),o=new Set([n]),u=n,f=()=>{let e=d.current;if(!m.current||x.signal.aborted||p.current!==S||!e.canEdit||e.services!==b.services||e.actor!==b.actor||l()!==b.actor||e.projectId!==b.projectId||e.aspect!==b.aspect)throw ia()},g=()=>{if(f(),!o.has(JSON.stringify(d.current.doc))||JSON.stringify(b.doc)!==n)throw ia()},C=e=>{g();let t=b.validateDocument(e),n=u;return u=JSON.stringify(t),o.add(u),b.onDocChange(e=>{try{if(f(),JSON.stringify(e)!==n)throw ia();return t}catch{return queueMicrotask(()=>{m.current&&p.current===S&&l()===b.actor&&d.current.projectId===b.projectId&&y(`The project changed before the reviewed style update could be saved.`)}),e}}),t};if(g(),!await _(`Replace the project's style with \"${s}\"? Already-built panels keep their images until you rebuild.`,{title:`Change style`,confirmText:`Apply style`}))return;g();let w=await aa(b.doc,t,`apply`,{signal:x.signal,check:g,services:c});if(w=C(w),g(),v?.(),w.strip.some(e=>e.image)){let e=await _(`${s} applied. Also clear the built panels so the next Build regenerates everything in the new style? No credits are spent until you press Build.`,{title:`Style updated`,confirmText:`Clear panels`,cancelText:`Keep images`});g(),e&&(w=await aa(w,t,`clear`,{signal:x.signal,check:g,services:c}),C(w))}}catch(e){m.current&&!x.signal.aborted&&p.current===S&&l()===b.actor&&d.current.projectId===b.projectId&&y(e.message||`The style could not be applied.`)}finally{f.current===x&&(o.current===x&&(o.current=null),f.current=null,m.current&&g(!1))}},cancel:b,pending:h,error:_}}let sa={manifest:{schemaVersion:1,sdkVersion:`0.1.0`,id:`stillmade-internal.planned-canvas`,version:`1.0.0`,name:`Planned canvas assembly`,description:`Assemble planned canvas events and narration into timed elements and layouts.`,kind:`task`,runtime:`javascript`,inputs:{doc:{type:`json`},words:{type:`json`}},outputs:{edit:{type:`json`}},permissions:{project:[],network:[],filesystem:[],secrets:[]}},code:`// COLLAGE CANVAS TEMPLATES — 20 bundled, versioned slot layouts (panel-image\n// only), each authored TWICE: a landscape layout and a portrait (9:16) layout\n// for the same scenario. A template is a LAYOUT DEFINITION, not a static\n// design: image SLOTS (center pos, target box, draw order = array order\n// back→front, optional tilt) and explicit TEXT SLOTS (role + deliberate\n// position), which the canvas system reads to place elements.\n//\n// Coordinates are normalized to the canvas frame (x/w = width fractions,\n// y/h = height fractions). An image FITS its slot box cover-cropped\n// (drawCollage's \\`box\\` rendering — aspect preserved, never distorted); fine\n// adjustment stays manual (drag pins, per spec S10). Image slots keep a\n// bottom safety margin (y + h/2 ≤ 0.95) so nothing crowds the frame edge.\n//\n// EVERY SLOT IS OPTIONAL — image and text alike. A template defines where\n// things GO if present; nothing is required. A canvas can use 2 of 7 image\n// slots, no text at all, or text with fewer images; unused slots are simply\n// empty (no placeholder, no gap artifact). And templates place, they never\n// time: each element still appears on ITS OWN voiceover beat (appearMs is\n// untouched by template application), so a canvas builds up slot by slot.\n//\n// Ownership contract (post-approval spec):\n// - AUTO canvases: the generator PICKS a template (pickTemplateForCanvas) from\n// image count + the beat's scenario hint; S10 self-arranging handles the\n// OVERFLOW beyond the slots (spiral around the slotted ones). Shown +\n// changeable afterward.\n// - MANUAL canvases: no template by default; opt-in from the picker.\n// - Switching is non-destructive: same elements, new positions; PINNED\n// elements are never moved (the pin IS the manual override).\n// - No fit / no pick → template null → the plain self-arranging layout.\n//\n// APPROVED by the owner 2026-07-22 (v2 sheet: both orientations, bottom\n// margins fixed). Bundled static definitions — versioned, never regenerated.\nconst CANVAS_TEMPLATE_VERSION = 2;\n\n// slot: { x, y, w, h, tilt? } — image slot (center + target box)\n// textSlot: { role, x, y, size, weight? } — role: headline | label | caption\n// Each template: landscape layout in \\`slots\\`/\\`textSlots\\`, portrait layout in\n// \\`pSlots\\`/\\`pTextSlots\\` (same scenario re-authored for a tall frame).\nconst T = (id, name, scenario, minImages, slots, textSlots, pSlots, pTextSlots) => (\n { id, name, scenario, minImages, slots, textSlots, pSlots, pTextSlots }\n);\n\nconst CANVAS_TEMPLATES = [\n T('hero-headline', 'Hero + headline', 'one subject, one line', 1,\n [{ x: 0.5, y: 0.58, w: 0.5, h: 0.62 }],\n [{ role: 'headline', x: 0.5, y: 0.14, size: 0.09, weight: 900 }],\n [{ x: 0.5, y: 0.55, w: 0.78, h: 0.5 }],\n [{ role: 'headline', x: 0.5, y: 0.13, size: 0.055, weight: 900 }]),\n\n T('hero-supporting', 'Hero + 2 supporting', 'main subject with two details', 3,\n [{ x: 0.34, y: 0.55, w: 0.42, h: 0.58 }, { x: 0.78, y: 0.33, w: 0.28, h: 0.32 }, { x: 0.78, y: 0.73, w: 0.28, h: 0.32 }],\n [{ role: 'headline', x: 0.34, y: 0.13, size: 0.08, weight: 900 }],\n [{ x: 0.5, y: 0.38, w: 0.78, h: 0.32 }, { x: 0.28, y: 0.72, w: 0.4, h: 0.2 }, { x: 0.72, y: 0.72, w: 0.4, h: 0.2 }],\n [{ role: 'headline', x: 0.5, y: 0.12, size: 0.05, weight: 900 }]),\n\n T('compare-2', 'Side-by-side compare', 'A vs B', 2,\n [{ x: 0.27, y: 0.5, w: 0.38, h: 0.5 }, { x: 0.73, y: 0.5, w: 0.38, h: 0.5 }],\n [{ role: 'headline', x: 0.5, y: 0.12, size: 0.08, weight: 900 },\n { role: 'label', x: 0.27, y: 0.84, size: 0.05, weight: 800 },\n { role: 'label', x: 0.73, y: 0.84, size: 0.05, weight: 800 }],\n [{ x: 0.5, y: 0.35, w: 0.72, h: 0.24 }, { x: 0.5, y: 0.72, w: 0.72, h: 0.24 }],\n [{ role: 'headline', x: 0.5, y: 0.11, size: 0.05, weight: 900 },\n { role: 'label', x: 0.5, y: 0.51, size: 0.032, weight: 800 },\n { role: 'label', x: 0.5, y: 0.88, size: 0.032, weight: 800 }]),\n\n T('three-across', 'Three across', 'three items', 3,\n [{ x: 0.2, y: 0.5, w: 0.26, h: 0.46 }, { x: 0.5, y: 0.5, w: 0.26, h: 0.46 }, { x: 0.8, y: 0.5, w: 0.26, h: 0.46 }],\n [{ role: 'headline', x: 0.5, y: 0.13, size: 0.08, weight: 900 },\n { role: 'caption', x: 0.5, y: 0.86, size: 0.045, weight: 600 }],\n [{ x: 0.5, y: 0.32, w: 0.64, h: 0.2 }, { x: 0.5, y: 0.57, w: 0.64, h: 0.2 }, { x: 0.5, y: 0.82, w: 0.64, h: 0.2 }],\n [{ role: 'headline', x: 0.5, y: 0.1, size: 0.05, weight: 900 },\n { role: 'caption', x: 0.5, y: 0.96, size: 0.028, weight: 600 }]),\n\n T('grid-2x2', 'Grid of four', 'four items', 4,\n [{ x: 0.3, y: 0.36, w: 0.32, h: 0.34 }, { x: 0.7, y: 0.36, w: 0.32, h: 0.34 },\n { x: 0.3, y: 0.74, w: 0.32, h: 0.34 }, { x: 0.7, y: 0.74, w: 0.32, h: 0.34 }],\n [{ role: 'headline', x: 0.5, y: 0.09, size: 0.07, weight: 900 }],\n [{ x: 0.28, y: 0.38, w: 0.4, h: 0.24 }, { x: 0.72, y: 0.38, w: 0.4, h: 0.24 },\n { x: 0.28, y: 0.68, w: 0.4, h: 0.24 }, { x: 0.72, y: 0.68, w: 0.4, h: 0.24 }],\n [{ role: 'headline', x: 0.5, y: 0.12, size: 0.05, weight: 900 }]),\n\n T('grid-3x3', 'Many small (3x3)', 'lots of items', 6,\n [0.22, 0.5, 0.78].flatMap((x) => [0.3, 0.56, 0.82].map((y) => ({ x, y, w: 0.24, h: 0.22 }))),\n [{ role: 'headline', x: 0.5, y: 0.08, size: 0.065, weight: 900 }],\n [0.2, 0.5, 0.8].flatMap((x) => [0.34, 0.58, 0.82].map((y) => ({ x, y, w: 0.27, h: 0.18 }))),\n [{ role: 'headline', x: 0.5, y: 0.1, size: 0.045, weight: 900 }]),\n\n T('big-left-stack-right', 'Big lead + stack', 'one lead, several follow-ups', 3,\n [{ x: 0.32, y: 0.54, w: 0.5, h: 0.62 }, { x: 0.79, y: 0.3, w: 0.3, h: 0.22 },\n { x: 0.79, y: 0.56, w: 0.3, h: 0.22 }, { x: 0.79, y: 0.82, w: 0.3, h: 0.22 }],\n [{ role: 'headline', x: 0.32, y: 0.13, size: 0.075, weight: 900 }],\n [{ x: 0.5, y: 0.4, w: 0.84, h: 0.34 }, { x: 0.2, y: 0.74, w: 0.26, h: 0.16 },\n { x: 0.5, y: 0.74, w: 0.26, h: 0.16 }, { x: 0.8, y: 0.74, w: 0.26, h: 0.16 }],\n [{ role: 'headline', x: 0.5, y: 0.12, size: 0.05, weight: 900 }]),\n\n T('vertical-stack', 'Vertical stack', 'ordered top to bottom', 2,\n [{ x: 0.55, y: 0.29, w: 0.36, h: 0.22 }, { x: 0.55, y: 0.55, w: 0.36, h: 0.22 }, { x: 0.55, y: 0.81, w: 0.36, h: 0.22 }],\n [{ role: 'headline', x: 0.55, y: 0.08, size: 0.065, weight: 900 },\n { role: 'label', x: 0.16, y: 0.55, size: 0.055, weight: 800 }],\n [{ x: 0.5, y: 0.3, w: 0.66, h: 0.2 }, { x: 0.5, y: 0.56, w: 0.66, h: 0.2 }, { x: 0.5, y: 0.82, w: 0.66, h: 0.2 }],\n [{ role: 'headline', x: 0.5, y: 0.09, size: 0.05, weight: 900 },\n { role: 'label', x: 0.24, y: 0.17, size: 0.032, weight: 800 }]),\n\n T('scatter', 'Scattered collage', 'loose, hand-thrown feel', 3,\n [{ x: 0.26, y: 0.36, w: 0.28, h: 0.32, tilt: -6 }, { x: 0.68, y: 0.3, w: 0.26, h: 0.3, tilt: 4 },\n { x: 0.44, y: 0.66, w: 0.27, h: 0.31, tilt: 3 }, { x: 0.8, y: 0.62, w: 0.25, h: 0.29, tilt: -5 },\n { x: 0.58, y: 0.46, w: 0.24, h: 0.28, tilt: 2 }],\n [{ role: 'headline', x: 0.5, y: 0.1, size: 0.075, weight: 900 }],\n [{ x: 0.32, y: 0.3, w: 0.46, h: 0.2, tilt: -6 }, { x: 0.7, y: 0.26, w: 0.42, h: 0.18, tilt: 4 },\n { x: 0.4, y: 0.56, w: 0.44, h: 0.2, tilt: 3 }, { x: 0.74, y: 0.6, w: 0.4, h: 0.18, tilt: -5 },\n { x: 0.5, y: 0.82, w: 0.44, h: 0.19, tilt: 2 }],\n [{ role: 'headline', x: 0.5, y: 0.09, size: 0.045, weight: 900 }]),\n\n T('timeline-row', 'Row / timeline', 'steps in order', 3,\n [{ x: 0.14, y: 0.52, w: 0.2, h: 0.38 }, { x: 0.38, y: 0.52, w: 0.2, h: 0.38 },\n { x: 0.62, y: 0.52, w: 0.2, h: 0.38 }, { x: 0.86, y: 0.52, w: 0.2, h: 0.38 }],\n [{ role: 'headline', x: 0.5, y: 0.15, size: 0.075, weight: 900 },\n { role: 'caption', x: 0.5, y: 0.85, size: 0.045, weight: 600 }],\n [{ x: 0.35, y: 0.28, w: 0.5, h: 0.15 }, { x: 0.65, y: 0.47, w: 0.5, h: 0.15 },\n { x: 0.35, y: 0.66, w: 0.5, h: 0.15 }, { x: 0.65, y: 0.85, w: 0.5, h: 0.15 }],\n [{ role: 'headline', x: 0.5, y: 0.12, size: 0.05, weight: 900 }]),\n\n T('center-satellites', 'Center + satellites', 'one core idea, orbiting parts', 3,\n [{ x: 0.5, y: 0.52, w: 0.34, h: 0.42 }, { x: 0.17, y: 0.3, w: 0.2, h: 0.26 }, { x: 0.83, y: 0.3, w: 0.2, h: 0.26 },\n { x: 0.17, y: 0.77, w: 0.2, h: 0.26 }, { x: 0.83, y: 0.77, w: 0.2, h: 0.26 }],\n [{ role: 'headline', x: 0.5, y: 0.09, size: 0.065, weight: 900 }],\n [{ x: 0.5, y: 0.52, w: 0.56, h: 0.28 }, { x: 0.2, y: 0.28, w: 0.32, h: 0.16 }, { x: 0.8, y: 0.28, w: 0.32, h: 0.16 },\n { x: 0.2, y: 0.78, w: 0.32, h: 0.16 }, { x: 0.8, y: 0.78, w: 0.32, h: 0.16 }],\n [{ role: 'headline', x: 0.5, y: 0.1, size: 0.045, weight: 900 }]),\n\n T('corner-big-text', 'Corner images, big text', 'statement first, proof beside it', 2,\n [{ x: 0.72, y: 0.4, w: 0.32, h: 0.38 }, { x: 0.52, y: 0.72, w: 0.28, h: 0.34 }, { x: 0.85, y: 0.76, w: 0.24, h: 0.3 }],\n [{ role: 'headline', x: 0.26, y: 0.26, size: 0.105, weight: 900 },\n { role: 'label', x: 0.26, y: 0.42, size: 0.05, weight: 600 }],\n [{ x: 0.36, y: 0.56, w: 0.5, h: 0.22 }, { x: 0.7, y: 0.7, w: 0.44, h: 0.2 }, { x: 0.4, y: 0.84, w: 0.4, h: 0.18 }],\n [{ role: 'headline', x: 0.5, y: 0.19, size: 0.065, weight: 900 },\n { role: 'label', x: 0.5, y: 0.31, size: 0.034, weight: 600 }]),\n\n T('title-top-row', 'Title top, images below', 'title screen with evidence', 2,\n [{ x: 0.22, y: 0.62, w: 0.28, h: 0.44 }, { x: 0.5, y: 0.62, w: 0.28, h: 0.44 }, { x: 0.78, y: 0.62, w: 0.28, h: 0.44 }],\n [{ role: 'headline', x: 0.5, y: 0.17, size: 0.1, weight: 900 }],\n [{ x: 0.5, y: 0.4, w: 0.7, h: 0.2 }, { x: 0.5, y: 0.64, w: 0.7, h: 0.2 }, { x: 0.5, y: 0.86, w: 0.7, h: 0.16 }],\n [{ role: 'headline', x: 0.5, y: 0.15, size: 0.06, weight: 900 }]),\n\n T('large-caption', 'One large + caption', 'let the image speak', 1,\n [{ x: 0.5, y: 0.47, w: 0.56, h: 0.6 }],\n [{ role: 'label', x: 0.15, y: 0.1, size: 0.045, weight: 800 },\n { role: 'caption', x: 0.5, y: 0.85, size: 0.055, weight: 600 }],\n [{ x: 0.5, y: 0.47, w: 0.82, h: 0.44 }],\n [{ role: 'label', x: 0.24, y: 0.12, size: 0.032, weight: 800 },\n { role: 'caption', x: 0.5, y: 0.78, size: 0.034, weight: 600 }]),\n\n T('staggered-diagonal', 'Staggered diagonal', 'progression with motion', 3,\n [{ x: 0.18, y: 0.26, w: 0.24, h: 0.3, tilt: -3 }, { x: 0.42, y: 0.45, w: 0.24, h: 0.3, tilt: 3 },\n { x: 0.64, y: 0.62, w: 0.24, h: 0.3, tilt: -3 }, { x: 0.86, y: 0.79, w: 0.24, h: 0.3, tilt: 3 }],\n [{ role: 'headline', x: 0.74, y: 0.16, size: 0.075, weight: 900 }],\n [{ x: 0.28, y: 0.3, w: 0.42, h: 0.18, tilt: -3 }, { x: 0.62, y: 0.46, w: 0.42, h: 0.18, tilt: 3 },\n { x: 0.36, y: 0.62, w: 0.42, h: 0.18, tilt: -3 }, { x: 0.68, y: 0.78, w: 0.42, h: 0.18, tilt: 3 }],\n [{ role: 'headline', x: 0.5, y: 0.12, size: 0.05, weight: 900 }]),\n\n T('overlap-stack', 'Overlapping stack', 'a deliberate pile', 2,\n [{ x: 0.42, y: 0.5, w: 0.36, h: 0.46, tilt: -5 }, { x: 0.54, y: 0.56, w: 0.36, h: 0.46, tilt: 3 },\n { x: 0.63, y: 0.46, w: 0.36, h: 0.46, tilt: -2 }],\n [{ role: 'headline', x: 0.5, y: 0.12, size: 0.08, weight: 900 },\n { role: 'caption', x: 0.5, y: 0.89, size: 0.045, weight: 600 }],\n [{ x: 0.44, y: 0.42, w: 0.58, h: 0.26, tilt: -5 }, { x: 0.58, y: 0.53, w: 0.58, h: 0.26, tilt: 3 },\n { x: 0.46, y: 0.64, w: 0.58, h: 0.26, tilt: -2 }],\n [{ role: 'headline', x: 0.5, y: 0.12, size: 0.05, weight: 900 },\n { role: 'caption', x: 0.5, y: 0.86, size: 0.032, weight: 600 }]),\n\n T('banner-row', 'Wide banner + small row', 'one wide scene, details under', 2,\n [{ x: 0.5, y: 0.36, w: 0.84, h: 0.36 }, { x: 0.25, y: 0.77, w: 0.24, h: 0.26 },\n { x: 0.5, y: 0.77, w: 0.24, h: 0.26 }, { x: 0.75, y: 0.77, w: 0.24, h: 0.26 }],\n [{ role: 'headline', x: 0.5, y: 0.09, size: 0.065, weight: 900 }],\n [{ x: 0.5, y: 0.36, w: 0.86, h: 0.26 }, { x: 0.22, y: 0.66, w: 0.28, h: 0.16 },\n { x: 0.5, y: 0.66, w: 0.28, h: 0.16 }, { x: 0.78, y: 0.66, w: 0.28, h: 0.16 }],\n [{ role: 'headline', x: 0.5, y: 0.13, size: 0.05, weight: 900 },\n { role: 'caption', x: 0.5, y: 0.82, size: 0.032, weight: 600 }]),\n\n T('quadrant-labels', 'Quadrants with labels', 'four named things', 4,\n [{ x: 0.28, y: 0.3, w: 0.3, h: 0.3 }, { x: 0.72, y: 0.3, w: 0.3, h: 0.3 },\n { x: 0.28, y: 0.71, w: 0.3, h: 0.3 }, { x: 0.72, y: 0.71, w: 0.3, h: 0.3 }],\n [{ role: 'headline', x: 0.5, y: 0.07, size: 0.06, weight: 900 },\n { role: 'label', x: 0.28, y: 0.49, size: 0.042, weight: 800 },\n { role: 'label', x: 0.72, y: 0.49, size: 0.042, weight: 800 },\n { role: 'label', x: 0.28, y: 0.9, size: 0.042, weight: 800 },\n { role: 'label', x: 0.72, y: 0.9, size: 0.042, weight: 800 }],\n [{ x: 0.28, y: 0.32, w: 0.38, h: 0.2 }, { x: 0.72, y: 0.32, w: 0.38, h: 0.2 },\n { x: 0.28, y: 0.64, w: 0.38, h: 0.2 }, { x: 0.72, y: 0.64, w: 0.38, h: 0.2 }],\n [{ role: 'headline', x: 0.5, y: 0.1, size: 0.045, weight: 900 },\n { role: 'label', x: 0.28, y: 0.45, size: 0.028, weight: 800 },\n { role: 'label', x: 0.72, y: 0.45, size: 0.028, weight: 800 },\n { role: 'label', x: 0.28, y: 0.77, size: 0.028, weight: 800 },\n { role: 'label', x: 0.72, y: 0.77, size: 0.028, weight: 800 }]),\n\n T('pyramid-3', 'Pyramid of three', 'one above two', 3,\n [{ x: 0.5, y: 0.32, w: 0.3, h: 0.32 }, { x: 0.32, y: 0.71, w: 0.3, h: 0.32 }, { x: 0.68, y: 0.71, w: 0.3, h: 0.32 }],\n [{ role: 'headline', x: 0.5, y: 0.08, size: 0.065, weight: 900 },\n { role: 'caption', x: 0.5, y: 0.92, size: 0.04, weight: 600 }],\n [{ x: 0.5, y: 0.34, w: 0.5, h: 0.22 }, { x: 0.27, y: 0.62, w: 0.42, h: 0.18 }, { x: 0.73, y: 0.62, w: 0.42, h: 0.18 }],\n [{ role: 'headline', x: 0.5, y: 0.1, size: 0.05, weight: 900 },\n { role: 'caption', x: 0.5, y: 0.79, size: 0.032, weight: 600 }]),\n\n T('mosaic-dense', 'Dense mosaic', 'everything at once', 5,\n [{ x: 0.3, y: 0.4, w: 0.34, h: 0.42 }, { x: 0.62, y: 0.29, w: 0.24, h: 0.26 }, { x: 0.86, y: 0.33, w: 0.2, h: 0.28 },\n { x: 0.19, y: 0.78, w: 0.24, h: 0.26 }, { x: 0.47, y: 0.77, w: 0.26, h: 0.28 }, { x: 0.73, y: 0.73, w: 0.22, h: 0.24 },\n { x: 0.91, y: 0.76, w: 0.14, h: 0.18 }],\n [{ role: 'headline', x: 0.5, y: 0.09, size: 0.06, weight: 900 }],\n [{ x: 0.32, y: 0.3, w: 0.5, h: 0.2 }, { x: 0.78, y: 0.26, w: 0.36, h: 0.16 }, { x: 0.24, y: 0.52, w: 0.4, h: 0.16 },\n { x: 0.68, y: 0.5, w: 0.44, h: 0.18 }, { x: 0.3, y: 0.74, w: 0.42, h: 0.16 }, { x: 0.74, y: 0.73, w: 0.4, h: 0.16 },\n { x: 0.5, y: 0.89, w: 0.5, h: 0.1 }],\n [{ role: 'headline', x: 0.5, y: 0.1, size: 0.045, weight: 900 }]),\n];\n\nconst byId = new Map(CANVAS_TEMPLATES.map((t) => [t.id, t]));\nconst getCanvasTemplate = (id) => byId.get(id) || null; // unknown/renamed id → no template (never a load failure)\n\n// The layout for a given canvas aspect: tall frames (ratio < 1) use the\n// portrait variant, everything else the landscape one.\nfunction templateLayout(template, aspect = 16 / 9) {\n if (!template) return null;\n return aspect < 1\n ? { slots: template.pSlots, textSlots: template.pTextSlots }\n : { slots: template.slots, textSlots: template.textSlots };\n}\n\n// ── Reflow: elements → a template's slots (pure, non-destructive) ───────────\n// Unpinned IMAGES fill image slots in appear order; unpinned TEXTS fill text\n// slots in slot order (headline first, as authored). EVERY SLOT IS OPTIONAL:\n// fewer elements than slots just leaves the extra slots empty. Elements\n// beyond the slots OVERFLOW: images lose their box (back to natural-aspect\n// sizing) and get pos:null so the S10 spiral places them around the slotted\n// ones; extra texts keep their position. PINNED elements are never touched —\n// the pin IS the manual override, and it survives every template switch.\n// TIMING IS NEVER TOUCHED: appearMs/leaveMs pass through untouched, so each\n// element still pops on its own voiceover beat.\nfunction applyTemplateToElements(elements, template, { aspect = 16 / 9 } = {}) {\n if (!template) {\n // Clearing a template touches ONLY slot-derived elements (the ones with a\n // box): the box comes off, the position STAYS — on an auto canvas the\n // spiral re-places unpinned elements anyway, and on a manual canvas the\n // old slot spot is a sane resting place (never a pos:null pile at\n // center, never a wipe of hand placements that were never slotted).\n return (elements || []).map((el) => {\n if (el.pinned || el.kind !== 'image' || !el.box) return el;\n const { box, ...rest } = el;\n return rest;\n });\n }\n const layout = templateLayout(template, aspect);\n const byAppear = (a, b) => (a.appearMs || 0) - (b.appearMs || 0);\n const images = (elements || []).filter((el) => el.kind === 'image' && !el.pinned).sort(byAppear);\n const texts = (elements || []).filter((el) => el.kind === 'text' && !el.pinned).sort(byAppear);\n const imgSlot = new Map();\n images.forEach((el, i) => { if (i < layout.slots.length) imgSlot.set(el.id, layout.slots[i]); });\n const textSlot = new Map();\n texts.forEach((el, i) => { if (i < layout.textSlots.length) textSlot.set(el.id, layout.textSlots[i]); });\n return (elements || []).map((el) => {\n if (el.pinned) return el;\n if (el.kind === 'image') {\n const s = imgSlot.get(el.id);\n if (!s) { const { box, ...rest } = el; return { ...rest, pos: null }; } // overflow → spiral\n return { ...el, pos: { x: s.x, y: s.y }, box: { w: s.w, h: s.h }, size: s.w, tilt: s.tilt || 0 };\n }\n const s = textSlot.get(el.id);\n if (!s) return el; // extra text keeps its place\n return { ...el, pos: { x: s.x, y: s.y }, size: s.size, weight: s.weight || el.weight || 800 };\n });\n}\n\n// ── Auto-pick (post-approval spec): image count + scenario hint ─────────────\n// The hint is the planner's free-text reason for the beat; keyword classes\n// beat pure counts (compare → side-by-side, steps/list → row, many → mosaic).\n// Returns a template id or null (no fit → the plain self-arranging layout).\nfunction pickTemplateForCanvas({ imageCount = 0, textCount = 0, hint = '' } = {}) {\n if (!imageCount) return null;\n const h = String(hint || '').toLowerCase();\n if (imageCount === 2 && /\\\\bvs\\\\b|versus|compar|before.*after|either/.test(h)) return 'compare-2';\n if (imageCount >= 3 && /step|order|sequence|timeline|process|journey|stages/.test(h)) return 'timeline-row';\n if (imageCount >= 3 && /list|lists|enumerat|items|examples|types|kinds/.test(h)) return imageCount >= 5 ? 'mosaic-dense' : 'three-across';\n if (imageCount === 1) return textCount > 1 ? 'large-caption' : 'hero-headline';\n if (imageCount === 2) return 'compare-2';\n if (imageCount === 3) return 'three-across';\n if (imageCount === 4) return 'grid-2x2';\n if (imageCount === 5) return 'center-satellites';\n if (imageCount <= 7) return 'mosaic-dense';\n return 'grid-3x3';\n}\n\nconst hash = (s) => {\n let h = 5381;\n const str = String(s || '');\n for (let i = 0; i < str.length; i++) h = ((h << 5) + h + str.charCodeAt(i)) >>> 0;\n return h;\n};\n// Deterministic pseudo-jitter in [-1, 1] from an id + salt.\nconst jitter = (id, salt) => ((hash(\\`\\${id}|\\${salt}\\`) % 2000) / 1000) - 1;\n\n// ── Self-arranging layout (S10) ──────────────────────────────────────────────\n// Applies to AUTO-ARRANGED canvases only (panel.autoArrange). Deterministic\n// greedy placement in APPEAR ORDER: each unpinned image takes the best slot on\n// a golden-angle spiral around the canvas center — maximizing distance from\n// every element already visible when it appears — so the composition stays\n// balanced as it accumulates without ever moving an already-placed element\n// (tidy-by-construction; nothing jumps). PINNED elements (user overrides) and\n// manual canvases keep their positions exactly; auto elements arrange AROUND\n// pinned ones (they're obstacles in the distance test).\nconst SPIRAL_SLOTS = 48;\nconst GOLDEN = 2.399963229728653; // golden angle (rad)\nfunction spiralSlot(k, aspect = 16 / 9) {\n // Slots sweep outward from the center, filling the frame evenly; x spread is\n // wider than y for landscape canvases.\n const r = 0.08 + 0.40 * Math.sqrt((k + 0.5) / SPIRAL_SLOTS);\n const a = k * GOLDEN;\n return { x: 0.5 + r * Math.cos(a), y: 0.5 + r * Math.sin(a) * (aspect > 1 ? 0.9 : 1.1) };\n}\nconst clamp01 = (v, lo, hi) => Math.max(lo, Math.min(hi, v));\n\nfunction arrangeCanvas(panel, { aspect = 16 / 9 } = {}) {\n const els = (panel?.elements || []).slice().sort((a, b) => (a.appearMs || 0) - (b.appearMs || 0));\n const placed = []; // { x, y, size, appearMs, leaveMs }\n const out = new Map();\n for (const el of els) {\n const half = (el.kind === 'image' ? (el.size || 0.28) : 0.18) / 2;\n if (el.pinned || !panel.autoArrange) {\n if (el.pos) { placed.push({ ...el.pos, size: el.size || 0.28, appearMs: el.appearMs, leaveMs: el.leaveMs }); out.set(el.id, el.pos); }\n continue;\n }\n // Distance test only against elements VISIBLE when this one appears —\n // an element that already LEFT frees its space.\n const visible = placed.filter((p) => (p.leaveMs == null || p.leaveMs > el.appearMs));\n let best = null; let bestScore = -Infinity;\n for (let k = 0; k < SPIRAL_SLOTS; k++) {\n // Slot order is salted per-element id so different canvases don't all\n // start identically, while staying fully deterministic.\n const slot = spiralSlot((k + (hash(el.id) % SPIRAL_SLOTS)) % SPIRAL_SLOTS, aspect);\n const x = clamp01(slot.x, half + 0.03, 1 - half - 0.03);\n const y = clamp01(slot.y, half + 0.05, 1 - half - 0.05);\n let minD = Infinity;\n for (const p of visible) minD = Math.min(minD, Math.hypot(x - p.x, y - p.y) - (p.size || 0.28) / 2 - half);\n const centerPull = -0.12 * Math.hypot(x - 0.5, y - 0.5); // gentle balance toward center\n const score = (visible.length ? Math.min(minD, 0.5) : 0.3) + centerPull;\n if (score > bestScore) { bestScore = score; best = { x, y }; }\n }\n const pos = best || { x: 0.5, y: 0.5 };\n // A hair of deterministic scatter so the collage reads hand-placed.\n pos.x = clamp01(pos.x + jitter(el.id, 'x') * 0.015, half, 1 - half);\n pos.y = clamp01(pos.y + jitter(el.id, 'y') * 0.015, half, 1 - half);\n placed.push({ ...pos, size: el.size || 0.28, appearMs: el.appearMs, leaveMs: el.leaveMs });\n out.set(el.id, pos);\n }\n return out; // elementId -> {x, y}\n}\n// Stamp arranged positions onto the elements (unpinned only) — the STORED\n// positions are what every renderer reads, so preview == export.\nfunction withArrangedPositions(panel, opts) {\n if (!panel.autoArrange) return panel;\n const posMap = arrangeCanvas(panel, opts);\n return {\n ...panel,\n elements: (panel.elements || []).map((el) => (\n !el.pinned && posMap.has(el.id) ? { ...el, pos: posMap.get(el.id) } : el\n )),\n };\n}\n\n\nfunction docAspectRatio(doc) {\n const a = doc?.meta?.aspect || '16:9';\n if (a === '9:16') return 9 / 16;\n if (a === '1:1') return 1;\n return 16 / 9;\n}\nfunction rearranged(doc, panel) {\n // TEMPLATE (bundled slot layout): the template sets the STRUCTURE — slotted\n // elements go to their slots; the S10 spiral only places the OVERFLOW,\n // treating slotted elements as obstacles. Applies to auto AND templated\n // manual canvases (opting into a template IS asking for arrangement); a\n // plain manual canvas stays untouched. Pinned elements never move.\n const template = getCanvasTemplate(panel.template);\n if (template) {\n const slotted = applyTemplateToElements(panel.elements || [], template, { aspect: docAspectRatio(doc) });\n const overflowPanel = {\n ...panel,\n autoArrange: true,\n elements: slotted.map((el) => (el.pos ? { ...el, pinned: true } : el)), // slots+pins = obstacles for the spiral\n };\n const posMap = arrangeCanvas(overflowPanel, { aspect: docAspectRatio(doc) });\n return {\n ...panel,\n elements: slotted.map((el) => (!el.pinned && !el.pos && posMap.has(el.id) ? { ...el, pos: posMap.get(el.id) } : el)),\n };\n }\n return panel.autoArrange ? withArrangedPositions(panel, { aspect: docAspectRatio(doc) }) : panel;\n}\n\n\nfunction buildPlannedCanvasElements(doc, words) {\n const w = Array.isArray(words) ? words : [];\n const wordStartMs = (i) => {\n const x = w[Math.max(0, Math.min(Math.round(Number(i) || 0), w.length - 1))];\n return x ? Math.round(Number(x.startMs ?? (x.start * 1000)) || 0) : NaN;\n };\n let changed = false;\n const strip = doc.strip.map((p) => {\n if (p.type !== 'canvas') return p;\n // TYPEWRITER beat: fill its lines from the span's VO words (once). Its own\n // pinned positions are kept — no self-arrange.\n if (p.mode === 'typewriter' && !(Array.isArray(p.elements) && p.elements.length)) {\n const elements = typewriterLineElements(w, {\n wordStart: p.wordStart, wordEnd: p.wordEnd, panelStartMs: p.startMs, panelDurationMs: p.durationMs,\n });\n if (!elements.length) return p;\n changed = true;\n return { ...p, autoArrange: false, elements };\n }\n if (!Array.isArray(p.events) || !p.events.length) return p;\n changed = true;\n const { events, ...rest } = p;\n const elements = elementsFromPlan(events, { panelStartMs: p.startMs, panelDurationMs: p.durationMs, wordStartMs });\n // AUTO canvases pick their template here (image count + the planner's\n // scenario hint); null = no fit → the plain self-arranging layout.\n const template = pickTemplateForCanvas({\n imageCount: elements.filter((el) => el.kind === 'image').length,\n textCount: elements.filter((el) => el.kind === 'text').length,\n hint: p.hint || '',\n });\n return rearranged(doc, { ...rest, ...(template ? { template } : {}), elements });\n });\n return changed ? loadPanelDoc({ ...doc, strip }) : doc;\n}\n\nfunction elementsFromPlan(events, { panelStartMs, panelDurationMs, wordStartMs, leadMs = 75 } = {}) {\n const els = [];\n let n = 0;\n for (const ev of (events || [])) {\n const wMs = wordStartMs(ev.at ?? ev.wordStart);\n if (!Number.isFinite(wMs)) continue;\n const appearMs = clamp01(wMs - leadMs - panelStartMs, 0, Math.max(0, panelDurationMs - 200));\n const id = \\`ce\\${++n}\\`;\n if (ev.kind === 'text') {\n els.push({\n id, kind: 'text', text: String(ev.text || '').slice(0, 80), appearMs, leaveMs: null,\n pos: null, size: ev.emphasis === 'primary' ? 0.085 : 0.06, font: 'Hanken Grotesk', color: '#111111', weight: 800,\n anim: { type: 'pop', perWord: false, speedMs: 180 }, sfx: 'auto', pinned: false,\n });\n } else {\n els.push({\n id, kind: 'image', src: null, query: String(ev.query || '').slice(0, 120), source: 'stock',\n appearMs, leaveMs: null, pos: null,\n size: ev.emphasis === 'primary' ? 0.46 : 0.28, tilt: Math.round(jitter(id, 'tilt') * 6),\n entrance: 'pop', sfx: 'auto', pinned: false,\n });\n }\n }\n return els;\n}\n\n// TYPEWRITER BEAT: build a text-only canvas's elements from the VO words in a\n// span — the EXACT narration, wrapped into lines, one pinned typewriter text\n// element per line. Each line reuses the single-line typewriter render (VO-timed\n// by wordTimes → types \"as spoken\"); canvasSfxPlan adds a keystroke per word.\n// Pure + deterministic. \\`words\\` are the FULL VO words; ws/we are inclusive word\n// indexes (word.startMs in ms, or word.start in seconds).\nfunction typewriterLineElements(words, {\n wordStart, wordEnd, panelStartMs = 0, panelDurationMs = 0,\n leadMs = 60, size = 0.06, maxCharsPerLine = 30, maxWordsPerLine = 6,\n} = {}) {\n const all = Array.isArray(words) ? words : [];\n if (!all.length) return [];\n const lo = Math.max(0, Math.min(Math.round(Number(wordStart) || 0), all.length - 1));\n const hi = Math.max(lo, Math.min(Math.round(Number(wordEnd) || lo), all.length - 1));\n const span = [];\n for (let i = lo; i <= hi; i++) {\n const wd = all[i];\n const text = String(wd?.text ?? wd?.word ?? '').trim();\n if (!text) continue;\n const startMs = Math.round(Number(wd?.startMs ?? (wd?.start * 1000)) || 0);\n const rel = clamp01(startMs - leadMs - panelStartMs, 0, Math.max(0, panelDurationMs - 150));\n span.push({ text, rel });\n }\n return typewriterElementsFromSpan(span, { size, maxCharsPerLine, maxWordsPerLine });\n}\n\n// Shared core: turn a span of { text, rel } (word text + canvas-relative start\n// ms) into pinned typewriter text lines. Fed by the planner (typewriterLineElements)\n// AND the White Board Motion \"Typewriter\" template (from voPhrasesForPanel).\nfunction typewriterElementsFromSpan(span, { size = 0.06, maxCharsPerLine = 30, maxWordsPerLine = 6 } = {}) {\n const items = (Array.isArray(span) ? span : [])\n .map((s) => ({ text: String(s?.text ?? '').trim(), rel: Math.max(0, Math.round(Number(s?.rel) || 0)) }))\n .filter((s) => s.text);\n if (!items.length) return [];\n // Greedy-wrap into lines (char budget or word count, whichever hits first) so\n // the layout is fixed up front and never reflows as it types.\n const lines = [];\n let cur = [];\n let curChars = 0;\n for (const wd of items) {\n const add = wd.text.length + (cur.length ? 1 : 0);\n if (cur.length && (curChars + add > maxCharsPerLine || cur.length >= maxWordsPerLine)) {\n lines.push(cur); cur = []; curChars = 0;\n }\n cur.push(wd); curChars += add;\n }\n if (cur.length) lines.push(cur);\n const lineH = size * 1.4; // normalized-H line height\n const startY = 0.5 - (lines.length * lineH) / 2 + lineH / 2;\n return lines.map((ln, i) => ({\n id: \\`tw\\${i + 1}\\`, kind: 'text', text: ln.map((w) => w.text).join(' '),\n appearMs: ln[0].rel, leaveMs: null,\n pos: { x: 0.5, y: clamp01(startY + i * lineH, 0.04, 0.96) },\n size, font: 'Hanken Grotesk', color: '#111111', weight: 800,\n wordTimes: ln.map((w) => w.rel),\n anim: { type: 'typewriter', perWord: false, speedMs: 45 },\n sfx: 'auto', pinned: true,\n }));\n}\n\nconst loadPanelDoc=doc=>JSON.parse(JSON.stringify(doc));return {edit:buildPlannedCanvasElements(input.doc,input.words)};\n`,tests:[]},ca=(e,t,n)=>Math.max(t,Math.min(n,e)),la=(e,t)=>Object.fromEntries(t.filter(t=>e[t]!==void 0).map(t=>[t,e[t]])),ua=e=>JSON.parse(JSON.stringify(e,(e,t)=>(I(typeof t!=`number`||Number.isFinite(t),`PLANNED_CANVAS`,`Canvas timing must remain finite.`),t)));function da(e,t){I(L(e)&&Array.isArray(e.strip)&&e.strip.length<=2048&&Array.isArray(t)&&t.length<=12e3,`PLANNED_CANVAS`,`This canvas plan is too large.`);let n=new Set,r=e.strip.map((e,t)=>{if(e.type!==`canvas`||(e.mode!==`typewriter`||e.elements?.length)&&!e.events?.length)return{panelId:e.panelId,type:`other`};n.add(t),I(n.size<=128,`PLANNED_CANVAS`,`Use at most 128 planned canvases.`);let r={...la(e,[`panelId`,`type`,`mode`,`wordStart`,`wordEnd`,`startMs`,`durationMs`,`autoArrange`,`template`,`hint`]),elements:e.elements?.length?[{id:`existing`}]:[]};return Array.isArray(e.events)&&(I(e.events.length<=1024,`PLANNED_CANVAS`,`Use at most 1024 events per canvas.`),r.events=e.events.map(e=>(I(L(e),`PLANNED_CANVAS`,`A planned event is invalid.`),{...la(e,[`kind`,`at`,`wordStart`,`emphasis`]),text:String(e.text||``).slice(0,80),query:String(e.query||``).slice(0,120)}))),r}),i=ua({doc:{meta:{aspect:e.meta?.aspect||`16:9`},strip:r},words:t.map(e=>e?{...la(e,[`startMs`,`start`]),text:String(e.text??e.word??``)}:null)});return B(i),I(JSON.stringify(i).length<=1048576,`PLANNED_CANVAS`,`The planned canvas input exceeds 1 MiB.`),{input:i,active:n}}function fa(e){let t=e.words,n=e=>{let n=t[ca(Math.round(Number(e)||0),0,t.length-1)];return n?Math.round(Number(n.startMs??n.start*1e3)||0):NaN},r=e.doc.meta.aspect===`9:16`?9/16:e.doc.meta.aspect===`1:1`?1:16/9,i=e.doc.strip.map(e=>{if(e.type!==`canvas`)return e;if(e.mode===`typewriter`&&!e.elements.length){if(!t.length)return e;let n=ca(Math.round(Number(e.wordStart)||0),0,t.length-1),r=ca(Math.round(Number(e.wordEnd)||n),n,t.length-1),i=[],a=[],o=0;for(let s=n;s<=r;s++){let n=t[s],r=String(n?.text??``).trim();if(!r)continue;let c={text:r,rel:Math.max(0,Math.round(ca((n?Math.round(Number(n.startMs??n.start*1e3)||0):0)-60-e.startMs,0,Math.max(0,e.durationMs-150))))},l=r.length+ +!!a.length;a.length&&(o+l>30||a.length>=6)&&(i.push(a),a=[],o=0),a.push(c),o+=l}if(a.length&&i.push(a),!i.length)return e;let s=.06*1.4,c=.5-i.length*s/2+s/2,l=i.map((e,t)=>({id:`tw${t+1}`,kind:`text`,text:e.map(e=>e.text).join(` `),appearMs:e[0].rel,leaveMs:null,pos:{x:.5,y:ca(c+t*s,.04,.96)},size:.06,font:`Hanken Grotesk`,color:`#111111`,weight:800,wordTimes:e.map(e=>e.rel),anim:{type:`typewriter`,perWord:!1,speedMs:45},sfx:`auto`,pinned:!0}));return{...e,autoArrange:!1,elements:l}}if(!e.events?.length)return e;let i=0,a=[];for(let t of e.events){let r=n(t.at??t.wordStart);if(!Number.isFinite(r))continue;let o=`ce${++i}`,s=ca(r-75-e.startMs,0,Math.max(0,e.durationMs-200));if(t.kind===`text`)a.push({id:o,kind:`text`,text:String(t.text||``).slice(0,80),appearMs:s,leaveMs:null,pos:null,size:t.emphasis===`primary`?.085:.06,font:`Hanken Grotesk`,color:`#111111`,weight:800,anim:{type:`pop`,perWord:!1,speedMs:180},sfx:`auto`,pinned:!1});else{let e=5381;for(let t of`${o}|tilt`)e=(e<<5)+e+t.charCodeAt(0)>>>0;a.push({id:o,kind:`image`,src:null,query:String(t.query||``).slice(0,120),source:`stock`,appearMs:s,leaveMs:null,pos:null,size:t.emphasis===`primary`?.46:.28,tilt:Math.round((e%2e3/1e3-1)*6),entrance:`pop`,sfx:`auto`,pinned:!1})}}let{events:o,...s}=e,c=rn({imageCount:a.filter(e=>e.kind===`image`).length,textCount:a.filter(e=>e.kind===`text`).length,hint:e.hint||``}),l={...s,...c?{template:c}:{},elements:a},u=en(l.template);if(u){let e=nn(a,u,{aspect:r}),t=kt({...l,autoArrange:!0,elements:e.map(e=>e.pos?{...e,pinned:!0}:e)},{aspect:r});l={...l,elements:e.map(e=>!e.pinned&&!e.pos&&t.has(e.id)?{...e,pos:t.get(e.id)}:e)}}else l.autoArrange&&(l=At(l,{aspect:r}));return l});return ua({...e.doc,strip:i})}async function pa(e,t,{signal:n,assertCurrent:r,host:i}){let a=H(i),o=a.actor(),s=V({doc:e,words:t}),c=()=>{r(),I(o&&a.actor()===o&&!n?.aborted&&V({doc:e,words:t})===s,`STALE`,`The account, canvas plan or narration changed.`)};c();let{input:l,active:u}=da(e,t),d=fa(l);B(d);let f=await a.run(sa,{kind:`run`,input:l,signal:n,timeoutMs:15e3});c();let p=f.outputs?.edit;B(p),I(V(p)===V(d),`PLANNED_CANVAS`,`The sandbox changed planned content, timing or layout.`);let m=!1,h=e.strip.map((e,t)=>{if(!u.has(t)||V(p.strip[t])===V(l.doc.strip[t]))return e;let n=p.strip[t],r={...e,elements:n.elements};Object.hasOwn(n,`events`)||delete r.events;for(let e of[`autoArrange`,`template`])Object.hasOwn(n,e)&&(r[e]=n[e]);return m=!0,r});return c(),m?{...e,strip:h}:e}let ma=()=>Object.assign(Error(`Canvas build cancelled or its source changed.`),{name:`AbortError`});function ha({doc:e,words:t,projectId:n,projectType:r,canEdit:i,onDocChange:a,editLease:o,host:s}){let c=H(s),l=()=>c.actor(),u=l(),[d,f]=(0,v.useState)(!1),p=(0,v.useRef)(new Set),m=()=>{for(let e of[...p.current])e()},h=(0,v.useRef)(null),g=(0,v.useRef)(null),_=(0,v.useRef)(0),y=(0,v.useRef)(!0);h.current={doc:e,words:t,projectId:n,projectType:r,canEdit:i,onDocChange:a,actor:u,services:c};let b=(0,v.useCallback)(()=>{g.current&&(_.current++,g.current.abort(),f(!0),m())},[]);return(0,v.useEffect)(()=>(y.current=!0,()=>{y.current=!1,_.current++,g.current?.abort(),m()}),[]),(0,v.useEffect)(m,[e,t,n,r,i,u,c]),(0,v.useEffect)(()=>{b()},[n,r,i,u,c,JSON.stringify(t)]),{run:async(i,a)=>{let s=h.current;if(!s.canEdit||g.current||o.current)return null;if(s.services!==c||s.doc!==e||s.projectId!==n||s.words!==t||s.actor!==u||l()!==u||s.projectType!==r)throw ma();let d=new AbortController,m=++_.current;g.current=d,o.current=d,f(!1);try{let e=JSON.stringify(s.doc),t=JSON.stringify(s.words),n=e,r=new Set([e]),i=()=>{let e=h.current;if(!y.current||d.signal.aborted||_.current!==m||!e.canEdit||e.services!==c||!s.actor||l()!==s.actor||e.actor!==s.actor||e.projectId!==s.projectId||e.projectType!==s.projectType||JSON.stringify(e.words)!==t)throw ma()},o=()=>{i();let t=JSON.stringify(h.current.doc);if(g||u&&JSON.stringify(u)!==f||!r.has(t)||JSON.stringify(s.doc)!==e)throw ma()},u=null,f=null,g=!1,v=e=>{o();let t=n,a=JSON.stringify(e);n=a,r.add(a),u=e,f=a,s.onDocChange(n=>{try{if(i(),JSON.stringify(e)!==a||JSON.stringify(n)!==t)throw ma();return a===t?n:e}catch{return g=!0,n}})},b=async e=>{v(e);let t=JSON.stringify(e),n=Date.now()+5e3;try{for(;;){if(o(),JSON.stringify(h.current.doc)===t){r.clear(),r.add(t);return}if(Date.now()>=n)throw Object.assign(Error(`Canvas changes could not be saved. Review the current canvas before trying again.`),{code:`CANVAS_SAVE_FAILED`});await new Promise(e=>{let t,r=()=>{clearTimeout(t),p.current.delete(r),e()};p.current.add(r),t=setTimeout(r,Math.max(1,n-Date.now()))})}}catch(e){throw d.abort(),e}};o();let x=await a({doc:s.doc,words:structuredClone(s.words),signal:d.signal,check:o,commit:v,commitAndWait:b});return o(),x}catch(e){let t=h.current,n=!y.current||d.signal.aborted||_.current!==m||t.projectId!==s.projectId||t.actor!==s.actor||l()!==s.actor;throw d.abort(),e?.code===`CANVAS_SAVE_FAILED`&&y.current&&t.projectId===s.projectId&&t.actor===s.actor&&l()===s.actor?e:n?ma():e}finally{g.current===d&&(o.current===d&&(o.current=null),g.current=null,y.current&&f(!1))}},cancel:b,canceling:d}}function ga(e){return I(e?.version===1&&typeof e.provision==`function`,`HOST_SERVICES`,`Presenter provisioning requires its version 1 broker.`),e}let _a=()=>Object.assign(Error(`Presenter build cancelled or its project changed.`),{name:`AbortError`}),va=e=>JSON.stringify(e);function ya({doc:e,voiceover:t,projectId:n,canEdit:r,hostEnabled:i,onDocChange:a,editLease:o,host:s,provisioner:c}){let l=H(s),u=ga(c),d=()=>l.actor(),f=(0,v.useRef)(null);f.current={doc:e,voiceover:t,projectId:n,canEdit:r,hostEnabled:i,onDocChange:a,actor:d(),services:l,presenterProvisionBroker:u};let p=(0,v.useRef)(!0),m=(0,v.useRef)(null),h=(0,v.useRef)(0),g=(0,v.useRef)(new Set),_=()=>{for(let e of[...g.current])e()},y=(0,v.useCallback)(()=>{h.current++,m.current?.abort(),o.current===m.current&&(o.current=null),m.current=null;for(let e of[...g.current])e()},[o]);return(0,v.useEffect)(()=>(p.current=!0,()=>{p.current=!1,y()}),[y]),(0,v.useEffect)(_,[e,t,n,r,i,l,u]),(0,v.useEffect)(()=>{y()},[n,r,i,l,u,f.current.actor,va(t),y]),{capture:()=>{let e=f.current;return{epoch:h.current,services:e.services,presenterProvisionBroker:e.presenterProvisionBroker,actor:e.actor,projectId:e.projectId,voiceover:e.voiceover,voiceSignature:va(e.voiceover),hostEnabled:e.hostEnabled}},begin:async(e,t,n)=>{if(t?.epoch!==h.current||m.current||o.current)throw _a();let r=new AbortController,i=++h.current;m.current=r,o.current=r;let a=()=>{o.current===r&&(o.current=null),m.current===r&&(m.current=null)};try{let o=va(e),s=o,c=e,m=new Set([o]),_=!1,v=()=>{let e=f.current;if(!p.current||r.signal.aborted||h.current!==i||n()||!e.canEdit||e.services!==t.services||e.presenterProvisionBroker!==t.presenterProvisionBroker||l!==t.services||u!==t.presenterProvisionBroker||!e.actor||d()!==t.actor||e.actor!==t.actor||e.projectId!==t.projectId||e.hostEnabled!==t.hostEnabled||e.voiceover!==t.voiceover||va(e.voiceover)!==t.voiceSignature)throw _a()},y=()=>{v();let e=va(f.current.doc);if(_||va(c)!==s||!m.has(e))throw _a()},b=Date.now()+1e3;for(;v(),va(f.current.doc)!==o;){if(Date.now()>=b)throw _a();await new Promise(e=>{let t,n=()=>{clearTimeout(t),g.current.delete(n),e()};g.current.add(n),t=setTimeout(n,Math.max(1,b-Date.now()))})}let x=f.current,S=e=>{y();let t=s,n=va(e);s=n,c=e,m.add(n),x.onDocChange(r=>{try{if(v(),va(e)!==n||va(r)!==t)throw _a();return e}catch{return _=!0,r}})},C=async e=>{try{S(e);let t=va(e),n=Date.now()+5e3;for(;;){if(y(),va(f.current.doc)===t){m.clear(),m.add(t);return}if(Date.now()>=n)throw _a();await new Promise(e=>{let t,r=()=>{clearTimeout(t),g.current.delete(r),e()};g.current.add(r),t=setTimeout(r,Math.max(1,n-Date.now()))})}}catch(e){throw r.abort(),e}},w=structuredClone(x.voiceover);try{let t=await u.provision(e,{voiceover:w,signal:r.signal,assertCurrent:y});y();let n=t;return S(n),{doc:n,check:y,commit:S,commitAndWait:C,finish:a,signal:r.signal}}catch(t){if(t?.name!==`AbortError`)return y(),{doc:e,error:t,check:y,commit:S,commitAndWait:C,finish:a,signal:r.signal};throw t}}catch(e){throw r.abort(),a(),e}},cancel:y}}let ba={manifest:{schemaVersion:1,sdkVersion:`0.1.0`,id:`stillmade-internal.panel-canvas-absorb`,version:`1.0.0`,name:`Image Panels canvas absorption`,description:`Absorb a contiguous panel range into an arranged, reversible canvas.`,kind:`task`,runtime:`javascript`,inputs:{doc:{type:`json`},from:{type:`text`},through:{type:`text`}},outputs:{edit:{type:`json`}},permissions:{project:[],network:[],filesystem:[],secrets:[]}},code:`// COLLAGE CANVAS TEMPLATES — 20 bundled, versioned slot layouts (panel-image\n// only), each authored TWICE: a landscape layout and a portrait (9:16) layout\n// for the same scenario. A template is a LAYOUT DEFINITION, not a static\n// design: image SLOTS (center pos, target box, draw order = array order\n// back→front, optional tilt) and explicit TEXT SLOTS (role + deliberate\n// position), which the canvas system reads to place elements.\n//\n// Coordinates are normalized to the canvas frame (x/w = width fractions,\n// y/h = height fractions). An image FITS its slot box cover-cropped\n// (drawCollage's \\`box\\` rendering — aspect preserved, never distorted); fine\n// adjustment stays manual (drag pins, per spec S10). Image slots keep a\n// bottom safety margin (y + h/2 ≤ 0.95) so nothing crowds the frame edge.\n//\n// EVERY SLOT IS OPTIONAL — image and text alike. A template defines where\n// things GO if present; nothing is required. A canvas can use 2 of 7 image\n// slots, no text at all, or text with fewer images; unused slots are simply\n// empty (no placeholder, no gap artifact). And templates place, they never\n// time: each element still appears on ITS OWN voiceover beat (appearMs is\n// untouched by template application), so a canvas builds up slot by slot.\n//\n// Ownership contract (post-approval spec):\n// - AUTO canvases: the generator PICKS a template (pickTemplateForCanvas) from\n// image count + the beat's scenario hint; S10 self-arranging handles the\n// OVERFLOW beyond the slots (spiral around the slotted ones). Shown +\n// changeable afterward.\n// - MANUAL canvases: no template by default; opt-in from the picker.\n// - Switching is non-destructive: same elements, new positions; PINNED\n// elements are never moved (the pin IS the manual override).\n// - No fit / no pick → template null → the plain self-arranging layout.\n//\n// APPROVED by the owner 2026-07-22 (v2 sheet: both orientations, bottom\n// margins fixed). Bundled static definitions — versioned, never regenerated.\nconst CANVAS_TEMPLATE_VERSION = 2;\n\n// slot: { x, y, w, h, tilt? } — image slot (center + target box)\n// textSlot: { role, x, y, size, weight? } — role: headline | label | caption\n// Each template: landscape layout in \\`slots\\`/\\`textSlots\\`, portrait layout in\n// \\`pSlots\\`/\\`pTextSlots\\` (same scenario re-authored for a tall frame).\nconst T = (id, name, scenario, minImages, slots, textSlots, pSlots, pTextSlots) => (\n { id, name, scenario, minImages, slots, textSlots, pSlots, pTextSlots }\n);\n\nconst CANVAS_TEMPLATES = [\n T('hero-headline', 'Hero + headline', 'one subject, one line', 1,\n [{ x: 0.5, y: 0.58, w: 0.5, h: 0.62 }],\n [{ role: 'headline', x: 0.5, y: 0.14, size: 0.09, weight: 900 }],\n [{ x: 0.5, y: 0.55, w: 0.78, h: 0.5 }],\n [{ role: 'headline', x: 0.5, y: 0.13, size: 0.055, weight: 900 }]),\n\n T('hero-supporting', 'Hero + 2 supporting', 'main subject with two details', 3,\n [{ x: 0.34, y: 0.55, w: 0.42, h: 0.58 }, { x: 0.78, y: 0.33, w: 0.28, h: 0.32 }, { x: 0.78, y: 0.73, w: 0.28, h: 0.32 }],\n [{ role: 'headline', x: 0.34, y: 0.13, size: 0.08, weight: 900 }],\n [{ x: 0.5, y: 0.38, w: 0.78, h: 0.32 }, { x: 0.28, y: 0.72, w: 0.4, h: 0.2 }, { x: 0.72, y: 0.72, w: 0.4, h: 0.2 }],\n [{ role: 'headline', x: 0.5, y: 0.12, size: 0.05, weight: 900 }]),\n\n T('compare-2', 'Side-by-side compare', 'A vs B', 2,\n [{ x: 0.27, y: 0.5, w: 0.38, h: 0.5 }, { x: 0.73, y: 0.5, w: 0.38, h: 0.5 }],\n [{ role: 'headline', x: 0.5, y: 0.12, size: 0.08, weight: 900 },\n { role: 'label', x: 0.27, y: 0.84, size: 0.05, weight: 800 },\n { role: 'label', x: 0.73, y: 0.84, size: 0.05, weight: 800 }],\n [{ x: 0.5, y: 0.35, w: 0.72, h: 0.24 }, { x: 0.5, y: 0.72, w: 0.72, h: 0.24 }],\n [{ role: 'headline', x: 0.5, y: 0.11, size: 0.05, weight: 900 },\n { role: 'label', x: 0.5, y: 0.51, size: 0.032, weight: 800 },\n { role: 'label', x: 0.5, y: 0.88, size: 0.032, weight: 800 }]),\n\n T('three-across', 'Three across', 'three items', 3,\n [{ x: 0.2, y: 0.5, w: 0.26, h: 0.46 }, { x: 0.5, y: 0.5, w: 0.26, h: 0.46 }, { x: 0.8, y: 0.5, w: 0.26, h: 0.46 }],\n [{ role: 'headline', x: 0.5, y: 0.13, size: 0.08, weight: 900 },\n { role: 'caption', x: 0.5, y: 0.86, size: 0.045, weight: 600 }],\n [{ x: 0.5, y: 0.32, w: 0.64, h: 0.2 }, { x: 0.5, y: 0.57, w: 0.64, h: 0.2 }, { x: 0.5, y: 0.82, w: 0.64, h: 0.2 }],\n [{ role: 'headline', x: 0.5, y: 0.1, size: 0.05, weight: 900 },\n { role: 'caption', x: 0.5, y: 0.96, size: 0.028, weight: 600 }]),\n\n T('grid-2x2', 'Grid of four', 'four items', 4,\n [{ x: 0.3, y: 0.36, w: 0.32, h: 0.34 }, { x: 0.7, y: 0.36, w: 0.32, h: 0.34 },\n { x: 0.3, y: 0.74, w: 0.32, h: 0.34 }, { x: 0.7, y: 0.74, w: 0.32, h: 0.34 }],\n [{ role: 'headline', x: 0.5, y: 0.09, size: 0.07, weight: 900 }],\n [{ x: 0.28, y: 0.38, w: 0.4, h: 0.24 }, { x: 0.72, y: 0.38, w: 0.4, h: 0.24 },\n { x: 0.28, y: 0.68, w: 0.4, h: 0.24 }, { x: 0.72, y: 0.68, w: 0.4, h: 0.24 }],\n [{ role: 'headline', x: 0.5, y: 0.12, size: 0.05, weight: 900 }]),\n\n T('grid-3x3', 'Many small (3x3)', 'lots of items', 6,\n [0.22, 0.5, 0.78].flatMap((x) => [0.3, 0.56, 0.82].map((y) => ({ x, y, w: 0.24, h: 0.22 }))),\n [{ role: 'headline', x: 0.5, y: 0.08, size: 0.065, weight: 900 }],\n [0.2, 0.5, 0.8].flatMap((x) => [0.34, 0.58, 0.82].map((y) => ({ x, y, w: 0.27, h: 0.18 }))),\n [{ role: 'headline', x: 0.5, y: 0.1, size: 0.045, weight: 900 }]),\n\n T('big-left-stack-right', 'Big lead + stack', 'one lead, several follow-ups', 3,\n [{ x: 0.32, y: 0.54, w: 0.5, h: 0.62 }, { x: 0.79, y: 0.3, w: 0.3, h: 0.22 },\n { x: 0.79, y: 0.56, w: 0.3, h: 0.22 }, { x: 0.79, y: 0.82, w: 0.3, h: 0.22 }],\n [{ role: 'headline', x: 0.32, y: 0.13, size: 0.075, weight: 900 }],\n [{ x: 0.5, y: 0.4, w: 0.84, h: 0.34 }, { x: 0.2, y: 0.74, w: 0.26, h: 0.16 },\n { x: 0.5, y: 0.74, w: 0.26, h: 0.16 }, { x: 0.8, y: 0.74, w: 0.26, h: 0.16 }],\n [{ role: 'headline', x: 0.5, y: 0.12, size: 0.05, weight: 900 }]),\n\n T('vertical-stack', 'Vertical stack', 'ordered top to bottom', 2,\n [{ x: 0.55, y: 0.29, w: 0.36, h: 0.22 }, { x: 0.55, y: 0.55, w: 0.36, h: 0.22 }, { x: 0.55, y: 0.81, w: 0.36, h: 0.22 }],\n [{ role: 'headline', x: 0.55, y: 0.08, size: 0.065, weight: 900 },\n { role: 'label', x: 0.16, y: 0.55, size: 0.055, weight: 800 }],\n [{ x: 0.5, y: 0.3, w: 0.66, h: 0.2 }, { x: 0.5, y: 0.56, w: 0.66, h: 0.2 }, { x: 0.5, y: 0.82, w: 0.66, h: 0.2 }],\n [{ role: 'headline', x: 0.5, y: 0.09, size: 0.05, weight: 900 },\n { role: 'label', x: 0.24, y: 0.17, size: 0.032, weight: 800 }]),\n\n T('scatter', 'Scattered collage', 'loose, hand-thrown feel', 3,\n [{ x: 0.26, y: 0.36, w: 0.28, h: 0.32, tilt: -6 }, { x: 0.68, y: 0.3, w: 0.26, h: 0.3, tilt: 4 },\n { x: 0.44, y: 0.66, w: 0.27, h: 0.31, tilt: 3 }, { x: 0.8, y: 0.62, w: 0.25, h: 0.29, tilt: -5 },\n { x: 0.58, y: 0.46, w: 0.24, h: 0.28, tilt: 2 }],\n [{ role: 'headline', x: 0.5, y: 0.1, size: 0.075, weight: 900 }],\n [{ x: 0.32, y: 0.3, w: 0.46, h: 0.2, tilt: -6 }, { x: 0.7, y: 0.26, w: 0.42, h: 0.18, tilt: 4 },\n { x: 0.4, y: 0.56, w: 0.44, h: 0.2, tilt: 3 }, { x: 0.74, y: 0.6, w: 0.4, h: 0.18, tilt: -5 },\n { x: 0.5, y: 0.82, w: 0.44, h: 0.19, tilt: 2 }],\n [{ role: 'headline', x: 0.5, y: 0.09, size: 0.045, weight: 900 }]),\n\n T('timeline-row', 'Row / timeline', 'steps in order', 3,\n [{ x: 0.14, y: 0.52, w: 0.2, h: 0.38 }, { x: 0.38, y: 0.52, w: 0.2, h: 0.38 },\n { x: 0.62, y: 0.52, w: 0.2, h: 0.38 }, { x: 0.86, y: 0.52, w: 0.2, h: 0.38 }],\n [{ role: 'headline', x: 0.5, y: 0.15, size: 0.075, weight: 900 },\n { role: 'caption', x: 0.5, y: 0.85, size: 0.045, weight: 600 }],\n [{ x: 0.35, y: 0.28, w: 0.5, h: 0.15 }, { x: 0.65, y: 0.47, w: 0.5, h: 0.15 },\n { x: 0.35, y: 0.66, w: 0.5, h: 0.15 }, { x: 0.65, y: 0.85, w: 0.5, h: 0.15 }],\n [{ role: 'headline', x: 0.5, y: 0.12, size: 0.05, weight: 900 }]),\n\n T('center-satellites', 'Center + satellites', 'one core idea, orbiting parts', 3,\n [{ x: 0.5, y: 0.52, w: 0.34, h: 0.42 }, { x: 0.17, y: 0.3, w: 0.2, h: 0.26 }, { x: 0.83, y: 0.3, w: 0.2, h: 0.26 },\n { x: 0.17, y: 0.77, w: 0.2, h: 0.26 }, { x: 0.83, y: 0.77, w: 0.2, h: 0.26 }],\n [{ role: 'headline', x: 0.5, y: 0.09, size: 0.065, weight: 900 }],\n [{ x: 0.5, y: 0.52, w: 0.56, h: 0.28 }, { x: 0.2, y: 0.28, w: 0.32, h: 0.16 }, { x: 0.8, y: 0.28, w: 0.32, h: 0.16 },\n { x: 0.2, y: 0.78, w: 0.32, h: 0.16 }, { x: 0.8, y: 0.78, w: 0.32, h: 0.16 }],\n [{ role: 'headline', x: 0.5, y: 0.1, size: 0.045, weight: 900 }]),\n\n T('corner-big-text', 'Corner images, big text', 'statement first, proof beside it', 2,\n [{ x: 0.72, y: 0.4, w: 0.32, h: 0.38 }, { x: 0.52, y: 0.72, w: 0.28, h: 0.34 }, { x: 0.85, y: 0.76, w: 0.24, h: 0.3 }],\n [{ role: 'headline', x: 0.26, y: 0.26, size: 0.105, weight: 900 },\n { role: 'label', x: 0.26, y: 0.42, size: 0.05, weight: 600 }],\n [{ x: 0.36, y: 0.56, w: 0.5, h: 0.22 }, { x: 0.7, y: 0.7, w: 0.44, h: 0.2 }, { x: 0.4, y: 0.84, w: 0.4, h: 0.18 }],\n [{ role: 'headline', x: 0.5, y: 0.19, size: 0.065, weight: 900 },\n { role: 'label', x: 0.5, y: 0.31, size: 0.034, weight: 600 }]),\n\n T('title-top-row', 'Title top, images below', 'title screen with evidence', 2,\n [{ x: 0.22, y: 0.62, w: 0.28, h: 0.44 }, { x: 0.5, y: 0.62, w: 0.28, h: 0.44 }, { x: 0.78, y: 0.62, w: 0.28, h: 0.44 }],\n [{ role: 'headline', x: 0.5, y: 0.17, size: 0.1, weight: 900 }],\n [{ x: 0.5, y: 0.4, w: 0.7, h: 0.2 }, { x: 0.5, y: 0.64, w: 0.7, h: 0.2 }, { x: 0.5, y: 0.86, w: 0.7, h: 0.16 }],\n [{ role: 'headline', x: 0.5, y: 0.15, size: 0.06, weight: 900 }]),\n\n T('large-caption', 'One large + caption', 'let the image speak', 1,\n [{ x: 0.5, y: 0.47, w: 0.56, h: 0.6 }],\n [{ role: 'label', x: 0.15, y: 0.1, size: 0.045, weight: 800 },\n { role: 'caption', x: 0.5, y: 0.85, size: 0.055, weight: 600 }],\n [{ x: 0.5, y: 0.47, w: 0.82, h: 0.44 }],\n [{ role: 'label', x: 0.24, y: 0.12, size: 0.032, weight: 800 },\n { role: 'caption', x: 0.5, y: 0.78, size: 0.034, weight: 600 }]),\n\n T('staggered-diagonal', 'Staggered diagonal', 'progression with motion', 3,\n [{ x: 0.18, y: 0.26, w: 0.24, h: 0.3, tilt: -3 }, { x: 0.42, y: 0.45, w: 0.24, h: 0.3, tilt: 3 },\n { x: 0.64, y: 0.62, w: 0.24, h: 0.3, tilt: -3 }, { x: 0.86, y: 0.79, w: 0.24, h: 0.3, tilt: 3 }],\n [{ role: 'headline', x: 0.74, y: 0.16, size: 0.075, weight: 900 }],\n [{ x: 0.28, y: 0.3, w: 0.42, h: 0.18, tilt: -3 }, { x: 0.62, y: 0.46, w: 0.42, h: 0.18, tilt: 3 },\n { x: 0.36, y: 0.62, w: 0.42, h: 0.18, tilt: -3 }, { x: 0.68, y: 0.78, w: 0.42, h: 0.18, tilt: 3 }],\n [{ role: 'headline', x: 0.5, y: 0.12, size: 0.05, weight: 900 }]),\n\n T('overlap-stack', 'Overlapping stack', 'a deliberate pile', 2,\n [{ x: 0.42, y: 0.5, w: 0.36, h: 0.46, tilt: -5 }, { x: 0.54, y: 0.56, w: 0.36, h: 0.46, tilt: 3 },\n { x: 0.63, y: 0.46, w: 0.36, h: 0.46, tilt: -2 }],\n [{ role: 'headline', x: 0.5, y: 0.12, size: 0.08, weight: 900 },\n { role: 'caption', x: 0.5, y: 0.89, size: 0.045, weight: 600 }],\n [{ x: 0.44, y: 0.42, w: 0.58, h: 0.26, tilt: -5 }, { x: 0.58, y: 0.53, w: 0.58, h: 0.26, tilt: 3 },\n { x: 0.46, y: 0.64, w: 0.58, h: 0.26, tilt: -2 }],\n [{ role: 'headline', x: 0.5, y: 0.12, size: 0.05, weight: 900 },\n { role: 'caption', x: 0.5, y: 0.86, size: 0.032, weight: 600 }]),\n\n T('banner-row', 'Wide banner + small row', 'one wide scene, details under', 2,\n [{ x: 0.5, y: 0.36, w: 0.84, h: 0.36 }, { x: 0.25, y: 0.77, w: 0.24, h: 0.26 },\n { x: 0.5, y: 0.77, w: 0.24, h: 0.26 }, { x: 0.75, y: 0.77, w: 0.24, h: 0.26 }],\n [{ role: 'headline', x: 0.5, y: 0.09, size: 0.065, weight: 900 }],\n [{ x: 0.5, y: 0.36, w: 0.86, h: 0.26 }, { x: 0.22, y: 0.66, w: 0.28, h: 0.16 },\n { x: 0.5, y: 0.66, w: 0.28, h: 0.16 }, { x: 0.78, y: 0.66, w: 0.28, h: 0.16 }],\n [{ role: 'headline', x: 0.5, y: 0.13, size: 0.05, weight: 900 },\n { role: 'caption', x: 0.5, y: 0.82, size: 0.032, weight: 600 }]),\n\n T('quadrant-labels', 'Quadrants with labels', 'four named things', 4,\n [{ x: 0.28, y: 0.3, w: 0.3, h: 0.3 }, { x: 0.72, y: 0.3, w: 0.3, h: 0.3 },\n { x: 0.28, y: 0.71, w: 0.3, h: 0.3 }, { x: 0.72, y: 0.71, w: 0.3, h: 0.3 }],\n [{ role: 'headline', x: 0.5, y: 0.07, size: 0.06, weight: 900 },\n { role: 'label', x: 0.28, y: 0.49, size: 0.042, weight: 800 },\n { role: 'label', x: 0.72, y: 0.49, size: 0.042, weight: 800 },\n { role: 'label', x: 0.28, y: 0.9, size: 0.042, weight: 800 },\n { role: 'label', x: 0.72, y: 0.9, size: 0.042, weight: 800 }],\n [{ x: 0.28, y: 0.32, w: 0.38, h: 0.2 }, { x: 0.72, y: 0.32, w: 0.38, h: 0.2 },\n { x: 0.28, y: 0.64, w: 0.38, h: 0.2 }, { x: 0.72, y: 0.64, w: 0.38, h: 0.2 }],\n [{ role: 'headline', x: 0.5, y: 0.1, size: 0.045, weight: 900 },\n { role: 'label', x: 0.28, y: 0.45, size: 0.028, weight: 800 },\n { role: 'label', x: 0.72, y: 0.45, size: 0.028, weight: 800 },\n { role: 'label', x: 0.28, y: 0.77, size: 0.028, weight: 800 },\n { role: 'label', x: 0.72, y: 0.77, size: 0.028, weight: 800 }]),\n\n T('pyramid-3', 'Pyramid of three', 'one above two', 3,\n [{ x: 0.5, y: 0.32, w: 0.3, h: 0.32 }, { x: 0.32, y: 0.71, w: 0.3, h: 0.32 }, { x: 0.68, y: 0.71, w: 0.3, h: 0.32 }],\n [{ role: 'headline', x: 0.5, y: 0.08, size: 0.065, weight: 900 },\n { role: 'caption', x: 0.5, y: 0.92, size: 0.04, weight: 600 }],\n [{ x: 0.5, y: 0.34, w: 0.5, h: 0.22 }, { x: 0.27, y: 0.62, w: 0.42, h: 0.18 }, { x: 0.73, y: 0.62, w: 0.42, h: 0.18 }],\n [{ role: 'headline', x: 0.5, y: 0.1, size: 0.05, weight: 900 },\n { role: 'caption', x: 0.5, y: 0.79, size: 0.032, weight: 600 }]),\n\n T('mosaic-dense', 'Dense mosaic', 'everything at once', 5,\n [{ x: 0.3, y: 0.4, w: 0.34, h: 0.42 }, { x: 0.62, y: 0.29, w: 0.24, h: 0.26 }, { x: 0.86, y: 0.33, w: 0.2, h: 0.28 },\n { x: 0.19, y: 0.78, w: 0.24, h: 0.26 }, { x: 0.47, y: 0.77, w: 0.26, h: 0.28 }, { x: 0.73, y: 0.73, w: 0.22, h: 0.24 },\n { x: 0.91, y: 0.76, w: 0.14, h: 0.18 }],\n [{ role: 'headline', x: 0.5, y: 0.09, size: 0.06, weight: 900 }],\n [{ x: 0.32, y: 0.3, w: 0.5, h: 0.2 }, { x: 0.78, y: 0.26, w: 0.36, h: 0.16 }, { x: 0.24, y: 0.52, w: 0.4, h: 0.16 },\n { x: 0.68, y: 0.5, w: 0.44, h: 0.18 }, { x: 0.3, y: 0.74, w: 0.42, h: 0.16 }, { x: 0.74, y: 0.73, w: 0.4, h: 0.16 },\n { x: 0.5, y: 0.89, w: 0.5, h: 0.1 }],\n [{ role: 'headline', x: 0.5, y: 0.1, size: 0.045, weight: 900 }]),\n];\n\nconst byId = new Map(CANVAS_TEMPLATES.map((t) => [t.id, t]));\nconst getCanvasTemplate = (id) => byId.get(id) || null; // unknown/renamed id → no template (never a load failure)\n\n// The layout for a given canvas aspect: tall frames (ratio < 1) use the\n// portrait variant, everything else the landscape one.\nfunction templateLayout(template, aspect = 16 / 9) {\n if (!template) return null;\n return aspect < 1\n ? { slots: template.pSlots, textSlots: template.pTextSlots }\n : { slots: template.slots, textSlots: template.textSlots };\n}\n\n// ── Reflow: elements → a template's slots (pure, non-destructive) ───────────\n// Unpinned IMAGES fill image slots in appear order; unpinned TEXTS fill text\n// slots in slot order (headline first, as authored). EVERY SLOT IS OPTIONAL:\n// fewer elements than slots just leaves the extra slots empty. Elements\n// beyond the slots OVERFLOW: images lose their box (back to natural-aspect\n// sizing) and get pos:null so the S10 spiral places them around the slotted\n// ones; extra texts keep their position. PINNED elements are never touched —\n// the pin IS the manual override, and it survives every template switch.\n// TIMING IS NEVER TOUCHED: appearMs/leaveMs pass through untouched, so each\n// element still pops on its own voiceover beat.\nfunction applyTemplateToElements(elements, template, { aspect = 16 / 9 } = {}) {\n if (!template) {\n // Clearing a template touches ONLY slot-derived elements (the ones with a\n // box): the box comes off, the position STAYS — on an auto canvas the\n // spiral re-places unpinned elements anyway, and on a manual canvas the\n // old slot spot is a sane resting place (never a pos:null pile at\n // center, never a wipe of hand placements that were never slotted).\n return (elements || []).map((el) => {\n if (el.pinned || el.kind !== 'image' || !el.box) return el;\n const { box, ...rest } = el;\n return rest;\n });\n }\n const layout = templateLayout(template, aspect);\n const byAppear = (a, b) => (a.appearMs || 0) - (b.appearMs || 0);\n const images = (elements || []).filter((el) => el.kind === 'image' && !el.pinned).sort(byAppear);\n const texts = (elements || []).filter((el) => el.kind === 'text' && !el.pinned).sort(byAppear);\n const imgSlot = new Map();\n images.forEach((el, i) => { if (i < layout.slots.length) imgSlot.set(el.id, layout.slots[i]); });\n const textSlot = new Map();\n texts.forEach((el, i) => { if (i < layout.textSlots.length) textSlot.set(el.id, layout.textSlots[i]); });\n return (elements || []).map((el) => {\n if (el.pinned) return el;\n if (el.kind === 'image') {\n const s = imgSlot.get(el.id);\n if (!s) { const { box, ...rest } = el; return { ...rest, pos: null }; } // overflow → spiral\n return { ...el, pos: { x: s.x, y: s.y }, box: { w: s.w, h: s.h }, size: s.w, tilt: s.tilt || 0 };\n }\n const s = textSlot.get(el.id);\n if (!s) return el; // extra text keeps its place\n return { ...el, pos: { x: s.x, y: s.y }, size: s.size, weight: s.weight || el.weight || 800 };\n });\n}\n\n// ── Auto-pick (post-approval spec): image count + scenario hint ─────────────\n// The hint is the planner's free-text reason for the beat; keyword classes\n// beat pure counts (compare → side-by-side, steps/list → row, many → mosaic).\n// Returns a template id or null (no fit → the plain self-arranging layout).\nfunction pickTemplateForCanvas({ imageCount = 0, textCount = 0, hint = '' } = {}) {\n if (!imageCount) return null;\n const h = String(hint || '').toLowerCase();\n if (imageCount === 2 && /\\\\bvs\\\\b|versus|compar|before.*after|either/.test(h)) return 'compare-2';\n if (imageCount >= 3 && /step|order|sequence|timeline|process|journey|stages/.test(h)) return 'timeline-row';\n if (imageCount >= 3 && /list|lists|enumerat|items|examples|types|kinds/.test(h)) return imageCount >= 5 ? 'mosaic-dense' : 'three-across';\n if (imageCount === 1) return textCount > 1 ? 'large-caption' : 'hero-headline';\n if (imageCount === 2) return 'compare-2';\n if (imageCount === 3) return 'three-across';\n if (imageCount === 4) return 'grid-2x2';\n if (imageCount === 5) return 'center-satellites';\n if (imageCount <= 7) return 'mosaic-dense';\n return 'grid-3x3';\n}\n\nconst hash = (s) => {\n let h = 5381;\n const str = String(s || '');\n for (let i = 0; i < str.length; i++) h = ((h << 5) + h + str.charCodeAt(i)) >>> 0;\n return h;\n};\n// Deterministic pseudo-jitter in [-1, 1] from an id + salt.\nconst jitter = (id, salt) => ((hash(\\`\\${id}|\\${salt}\\`) % 2000) / 1000) - 1;\n\n// ── Self-arranging layout (S10) ──────────────────────────────────────────────\n// Applies to AUTO-ARRANGED canvases only (panel.autoArrange). Deterministic\n// greedy placement in APPEAR ORDER: each unpinned image takes the best slot on\n// a golden-angle spiral around the canvas center — maximizing distance from\n// every element already visible when it appears — so the composition stays\n// balanced as it accumulates without ever moving an already-placed element\n// (tidy-by-construction; nothing jumps). PINNED elements (user overrides) and\n// manual canvases keep their positions exactly; auto elements arrange AROUND\n// pinned ones (they're obstacles in the distance test).\nconst SPIRAL_SLOTS = 48;\nconst GOLDEN = 2.399963229728653; // golden angle (rad)\nfunction spiralSlot(k, aspect = 16 / 9) {\n // Slots sweep outward from the center, filling the frame evenly; x spread is\n // wider than y for landscape canvases.\n const r = 0.08 + 0.40 * Math.sqrt((k + 0.5) / SPIRAL_SLOTS);\n const a = k * GOLDEN;\n return { x: 0.5 + r * Math.cos(a), y: 0.5 + r * Math.sin(a) * (aspect > 1 ? 0.9 : 1.1) };\n}\nconst clamp01 = (v, lo, hi) => Math.max(lo, Math.min(hi, v));\n\nfunction arrangeCanvas(panel, { aspect = 16 / 9 } = {}) {\n const els = (panel?.elements || []).slice().sort((a, b) => (a.appearMs || 0) - (b.appearMs || 0));\n const placed = []; // { x, y, size, appearMs, leaveMs }\n const out = new Map();\n for (const el of els) {\n const half = (el.kind === 'image' ? (el.size || 0.28) : 0.18) / 2;\n if (el.pinned || !panel.autoArrange) {\n if (el.pos) { placed.push({ ...el.pos, size: el.size || 0.28, appearMs: el.appearMs, leaveMs: el.leaveMs }); out.set(el.id, el.pos); }\n continue;\n }\n // Distance test only against elements VISIBLE when this one appears —\n // an element that already LEFT frees its space.\n const visible = placed.filter((p) => (p.leaveMs == null || p.leaveMs > el.appearMs));\n let best = null; let bestScore = -Infinity;\n for (let k = 0; k < SPIRAL_SLOTS; k++) {\n // Slot order is salted per-element id so different canvases don't all\n // start identically, while staying fully deterministic.\n const slot = spiralSlot((k + (hash(el.id) % SPIRAL_SLOTS)) % SPIRAL_SLOTS, aspect);\n const x = clamp01(slot.x, half + 0.03, 1 - half - 0.03);\n const y = clamp01(slot.y, half + 0.05, 1 - half - 0.05);\n let minD = Infinity;\n for (const p of visible) minD = Math.min(minD, Math.hypot(x - p.x, y - p.y) - (p.size || 0.28) / 2 - half);\n const centerPull = -0.12 * Math.hypot(x - 0.5, y - 0.5); // gentle balance toward center\n const score = (visible.length ? Math.min(minD, 0.5) : 0.3) + centerPull;\n if (score > bestScore) { bestScore = score; best = { x, y }; }\n }\n const pos = best || { x: 0.5, y: 0.5 };\n // A hair of deterministic scatter so the collage reads hand-placed.\n pos.x = clamp01(pos.x + jitter(el.id, 'x') * 0.015, half, 1 - half);\n pos.y = clamp01(pos.y + jitter(el.id, 'y') * 0.015, half, 1 - half);\n placed.push({ ...pos, size: el.size || 0.28, appearMs: el.appearMs, leaveMs: el.leaveMs });\n out.set(el.id, pos);\n }\n return out; // elementId -> {x, y}\n}\n// Stamp arranged positions onto the elements (unpinned only) — the STORED\n// positions are what every renderer reads, so preview == export.\nfunction withArrangedPositions(panel, opts) {\n if (!panel.autoArrange) return panel;\n const posMap = arrangeCanvas(panel, opts);\n return {\n ...panel,\n elements: (panel.elements || []).map((el) => (\n !el.pinned && posMap.has(el.id) ? { ...el, pos: posMap.get(el.id) } : el\n )),\n };\n}\n\n\nfunction canvasRangeBlockers(strip, panelIds) {\n const ids = new Set(panelIds);\n const rows = (strip || []).filter((p) => ids.has(p.panelId));\n const out = [];\n for (const p of rows) {\n if (p.type === 'titleScreen') out.push({ panelId: p.panelId, reason: 'a title screen is not a beat a canvas can absorb' });\n else if (p.type === 'canvas') out.push({ panelId: p.panelId, reason: 'already a canvas' });\n else if (p.kind === 'revealStep' || p.method === 'progressiveReveal') out.push({ panelId: p.panelId, reason: 'part of a progressive-reveal group' });\n }\n for (const q of (strip || [])) {\n if (ids.has(q.panelId)) continue;\n if (q.repeatOf && ids.has(q.repeatOf)) out.push({ panelId: q.repeatOf, reason: \\`\\${q.panelId} re-shows it\\` });\n if (q.revealOf && ids.has(q.revealOf)) out.push({ panelId: q.revealOf, reason: \\`\\${q.panelId} reveals it\\` });\n if (q.type === 'zoom' && q.sourcePanelId && ids.has(q.sourcePanelId)) out.push({ panelId: q.sourcePanelId, reason: \\`zoom \\${q.panelId} pushes into it\\` });\n }\n return out;\n}\n\n// The contiguous run [fromPanelId .. toPanelId] (inclusive) in strip order.\n// Same scene only — a canvas rides inside one scene like any other beat.\nfunction canvasRangeIds(strip, fromPanelId, toPanelId) {\n const a = (strip || []).findIndex((p) => p.panelId === fromPanelId);\n const b = (strip || []).findIndex((p) => p.panelId === (toPanelId || fromPanelId));\n if (a < 0 || b < 0) throw new Error('canvasRange: unknown panel');\n const [lo, hi] = a <= b ? [a, b] : [b, a];\n const run = strip.slice(lo, hi + 1);\n const sceneId = run[0].sceneId;\n if (run.some((p) => p.sceneId !== sceneId)) throw new Error('canvasRange: a canvas stays inside one scene');\n return run.map((p) => p.panelId);\n}\n\n// Replace a run with ONE canvas. Total video length never changes (the canvas\n// inherits the run's combined window); later beats keep their exact starts.\nfunction insertCanvasOverRange(doc, fromPanelId, toPanelId) {\n const ids = canvasRangeIds(doc.strip, fromPanelId, toPanelId);\n const blockers = canvasRangeBlockers(doc.strip, ids);\n if (blockers.length) throw new Error(\\`insertCanvasOverRange: can't absorb \\${blockers[0].panelId} — \\${blockers[0].reason}\\`);\n const idSet = new Set(ids);\n const rows = doc.strip.filter((p) => idSet.has(p.panelId));\n const startMs = Math.min(...rows.map((p) => Number(p.startMs)));\n const durationMs = rows.reduce((sum, p) => sum + Number(p.durationMs), 0);\n const id = \\`\\${rows[0].panelId}c\\${doc.strip.filter((p) => p.type === 'canvas').length + 1}\\`;\n\n // Absorbed frames become elements, each popping when its panel would have.\n let n = 0;\n const elements = rows\n .map((p) => ({ p, url: resolvePanelImage(doc.strip, p) }))\n .filter(({ url }) => !!url)\n .map(({ p, url }) => ({\n id: \\`ab\\${++n}\\`, kind: 'image', src: url, query: String(p.prompt || p.gifQuery || p.panelId).slice(0, 120),\n source: 'generated', appearMs: Math.max(0, Number(p.startMs) - startMs), leaveMs: null,\n pos: null, size: 0.34, tilt: 0, entrance: 'pop', sfx: 'auto', pinned: false,\n }));\n\n // A reaction GIF riding an absorbed panel would vanish with its row — move\n // it to the nearest EARLIER surviving panel that has no overlay, exactly as\n // deletePanel does, so the user's GIF is never silently lost.\n const firstIdx = doc.strip.findIndex((x) => x.panelId === ids[0]);\n const survivorsBefore = doc.strip.filter((p, i) => !idSet.has(p.panelId) && i < firstIdx);\n const strayOverlay = rows.map((r) => r.overlayLayer).find((o) => o && typeof o === 'object') || null;\n const overlayHost = strayOverlay\n ? [...survivorsBefore].reverse().find((q) => q.type === 'panel' && q.sceneId === rows[0].sceneId && q.overlayLayer == null)?.panelId\n : null;\n\n // Edits that sourced an absorbed panel re-point to the last surviving frame\n // of their lineage before the canvas (assembly's rule) and are flagged; the\n // pre-absorb state (source, flag, IMAGE) is recorded so revert restores it\n // honestly — a panel regenerated meanwhile must not come back \"clean\".\n const repointed = [];\n const strip = [];\n let inserted = false;\n for (const p of doc.strip) {\n if (idSet.has(p.panelId)) {\n if (!inserted) {\n inserted = true;\n strip.push({\n panelId: id, type: 'canvas', sceneId: rows[0].sceneId,\n background: '#ffffff', autoArrange: elements.length > 0, planned: true,\n ...(elements.length ? { template: pickTemplateForCanvas({ imageCount: elements.length }) || undefined } : {}),\n elements, startMs, durationMs, transitionIn: rows[0].transitionIn === 'fade' ? 'fade' : 'cut',\n provenance: 'user',\n revert: { rows: rows.map((r) => ({ ...r })), repointed: [] },\n });\n }\n continue;\n }\n if ((p.kind === 'edit' || p.type === 'zoom') && p.sourcePanelId && idSet.has(p.sourcePanelId)) {\n const fallback = [...survivorsBefore].reverse().find((q) => q.lineageId === p.lineageId && q.sceneId === p.sceneId && (q.type === 'panel' || q.type === 'zoom'));\n repointed.push({ panelId: p.panelId, sourcePanelId: p.sourcePanelId, needsRefresh: !!p.needsRefresh, image: p.image ?? null });\n strip.push(fallback\n ? { ...p, sourcePanelId: fallback.panelId, needsRefresh: true }\n : { ...p, kind: 'base', sourcePanelId: null, prompt: baseFallbackPrompt(doc.strip, p), needsRefresh: true });\n continue;\n }\n strip.push(overlayHost && p.panelId === overlayHost ? { ...p, overlayLayer: strayOverlay } : p);\n }\n // Stamp the repoint record AND lay the carried frames out (template slots /\n // the S10 spiral) — without this every element keeps pos:null and the\n // painter piles them all at frame centre.\n const withRepoints = strip.map((p) => (p.panelId === id ? rearranged(doc, { ...p, revert: { ...p.revert, repointed } }) : p));\n return loadPanelDoc({ ...doc, strip: withRepoints });\n}\n\n\nfunction docAspectRatio(doc) {\n const a = doc?.meta?.aspect || '16:9';\n if (a === '9:16') return 9 / 16;\n if (a === '1:1') return 1;\n return 16 / 9;\n}\nfunction rearranged(doc, panel) {\n // TEMPLATE (bundled slot layout): the template sets the STRUCTURE — slotted\n // elements go to their slots; the S10 spiral only places the OVERFLOW,\n // treating slotted elements as obstacles. Applies to auto AND templated\n // manual canvases (opting into a template IS asking for arrangement); a\n // plain manual canvas stays untouched. Pinned elements never move.\n const template = getCanvasTemplate(panel.template);\n if (template) {\n const slotted = applyTemplateToElements(panel.elements || [], template, { aspect: docAspectRatio(doc) });\n const overflowPanel = {\n ...panel,\n autoArrange: true,\n elements: slotted.map((el) => (el.pos ? { ...el, pinned: true } : el)), // slots+pins = obstacles for the spiral\n };\n const posMap = arrangeCanvas(overflowPanel, { aspect: docAspectRatio(doc) });\n return {\n ...panel,\n elements: slotted.map((el) => (!el.pinned && !el.pos && posMap.has(el.id) ? { ...el, pos: posMap.get(el.id) } : el)),\n };\n }\n return panel.autoArrange ? withArrangedPositions(panel, { aspect: docAspectRatio(doc) }) : panel;\n}\n\nfunction resolvePanelImage(strip, panel) {\n if (panel?.type === 'giphy') return panel.gif ?? panel.image ?? null;\n if (panel?.type === 'zoom') {\n // The stamped CROP is the zoom's frame (and the next edit's source). Until\n // the build crops it, fall back to the source's full frame so chains and\n // previews never break.\n if (panel.image) return panel.image;\n const zsrc = (strip || []).find((p) => p.panelId === panel.sourcePanelId);\n return zsrc ? resolvePanelImage(strip, zsrc) : null;\n }\n if (panel?.kind !== 'repeat') return panel?.image ?? null;\n const target = (strip || []).find((p) => p.panelId === panel.repeatOf);\n return target?.image ?? null;\n}\n\n\nfunction baseFallbackPrompt(strip, panel) {\n const pool = [];\n for (const p of (strip || [])) {\n pool.push(p);\n for (const r of (p.revert?.rows || [])) pool.push(r);\n }\n const lineageBase = pool.find((p) => p.kind === 'base' && p.lineageId === panel.lineageId && p.sceneId === panel.sceneId && String(p.prompt || '').trim());\n if (lineageBase) return lineageBase.prompt;\n return String(panel.prompt || '').replace(/^\\\\s*keep\\\\s+(everything\\\\s+)?identical\\\\s*;\\\\s*/i, '').trim() || 'the scene';\n}\n\n\nconst loadPanelDoc=doc=>doc; return {edit:insertCanvasOverRange(input.doc,input.from,input.through)};`,tests:[]},xa=(e,t)=>V(e)===V(t),Sa=[`panelId`,`type`,`sceneId`,`lineageId`,`kind`,`method`,`sourcePanelId`,`repeatOf`,`revealOf`,`startMs`,`durationMs`,`transitionIn`,`prompt`,`gifQuery`,`needsRefresh`];function Ca(e,t,n){let r=new Map,i=new Map,a=new Map,o=e=>{if(e==null)return e;if(!a.has(e)){let t=`m${a.size}`;a.set(e,t),i.set(t,e)}return a.get(e)},s=e=>{let t={};for(let n of Sa)e[n]!==void 0&&(t[n]=e[n]);for(let n of[`image`,`gif`])e[n]!==void 0&&(t[n]=e[n]?o(e[n]):e[n]);return e.overlayLayer!==void 0&&(t.overlayLayer=e.overlayLayer&&typeof e.overlayLayer==`object`?{token:o(e.overlayLayer)}:e.overlayLayer!=null||e.overlayLayer),e.revert?.rows&&(t.revert={rows:e.revert.rows.map(e=>{let t={};for(let n of[`kind`,`lineageId`,`sceneId`,`prompt`])e[n]!==void 0&&(t[n]=e[n]);return t})}),t};for(let t of e.strip)I(!r.has(t.panelId),`CANVAS_ABSORB`,`Panel identities must be unique.`),r.set(t.panelId,t);let c={strip:e.strip.map(s),meta:{aspect:e.meta?.aspect||`16:9`}};return B(c),{input:{doc:c,from:t,through:n||t},originals:r,tokens:i}}function wa({doc:e,from:t,through:n}){let r=e.strip.findIndex(e=>e.panelId===t),i=e.strip.findIndex(e=>e.panelId===n);I(r>=0&&i>=0,`CANVAS_ABSORB`,`The selected range is no longer available.`);let a=Math.min(r,i),o=e.strip.slice(a,Math.max(r,i)+1),s=new Set(o.map(e=>e.panelId)),c=o[0].sceneId;I(o.every(e=>e.sceneId===c),`CANVAS_ABSORB`,`A canvas stays inside one scene.`),I(o.every(e=>![`titleScreen`,`canvas`].includes(e.type)&&e.kind!==`revealStep`&&e.method!==`progressiveReveal`),`CANVAS_ABSORB`,`This range contains a panel that cannot be absorbed.`);let l=e.strip.filter(e=>!s.has(e.panelId));I(l.every(e=>!s.has(e.repeatOf)&&!s.has(e.revealOf)&&!(e.type===`zoom`&&s.has(e.sourcePanelId))),`CANVAS_ABSORB`,`A surviving panel still references this range.`);let u=e.strip.slice(0,a),d=Math.min(...o.map(e=>Number(e.startMs))),f=o.reduce((e,t)=>e+Number(t.durationMs),0),p=`${o[0].panelId}c${e.strip.filter(e=>e.type===`canvas`).length+1}`;I(!e.strip.some(e=>e.panelId===p),`CANVAS_ABSORB`,`The canvas identity is already in use.`);let m=(t,n=new Set)=>{if(I(!n.has(t.panelId),`CANVAS_ABSORB`,`A panel image reference is circular.`),n.add(t.panelId),t.type===`giphy`)return t.gif??t.image??null;if(t.type===`zoom`){if(t.image)return t.image;let r=e.strip.find(e=>e.panelId===t.sourcePanelId);return r?m(r,n):null}return t.kind===`repeat`?e.strip.find(e=>e.panelId===t.repeatOf)?.image??null:t.image??null},h=[];for(let e of o){let t=m(e);t&&h.push({id:`ab${h.length+1}`,kind:`image`,src:t,query:String(e.prompt||e.gifQuery||e.panelId).slice(0,120),source:`generated`,appearMs:Math.max(0,Number(e.startMs)-d),leaveMs:null,pos:null,size:.34,tilt:0,entrance:`pop`,sfx:`auto`,pinned:!1})}let g={panelId:p,type:`canvas`,sceneId:c,background:`#ffffff`,autoArrange:h.length>0,planned:!0,...h.length?{template:rn({imageCount:h.length})||void 0}:{},elements:h,startMs:d,durationMs:f,transitionIn:o[0].transitionIn===`fade`?`fade`:`cut`,provenance:`user`,revert:{rows:o.map(e=>({...e})),repointed:[]}},_=o.map(e=>e.overlayLayer).find(e=>e&&typeof e==`object`)||null,v=_?[...u].reverse().find(e=>e.type===`panel`&&e.sceneId===c&&e.overlayLayer==null)?.panelId:null,y=e.strip.flatMap(e=>[e,...e.revert?.rows||[]]),b=new Map;for(let e of l)if((e.kind===`edit`||e.type===`zoom`)&&e.sourcePanelId&&s.has(e.sourcePanelId)){let t=[...u].reverse().find(t=>t.lineageId===e.lineageId&&t.sceneId===e.sceneId&&(t.type===`panel`||t.type===`zoom`));g.revert.repointed.push({panelId:e.panelId,sourcePanelId:e.sourcePanelId,needsRefresh:!!e.needsRefresh,image:e.image??null});let n=y.find(t=>t.kind===`base`&&t.lineageId===e.lineageId&&t.sceneId===e.sceneId&&String(t.prompt||``).trim());b.set(e.panelId,t?{...e,sourcePanelId:t.panelId,needsRefresh:!0}:{...e,kind:`base`,sourcePanelId:null,prompt:n?n.prompt:String(e.prompt||``).replace(/^\\s*keep\\s+(everything\\s+)?identical\\s*;\\s*/i,``).trim()||`the scene`,needsRefresh:!0})}else v&&e.panelId===v&&b.set(e.panelId,{...e,overlayLayer:_});let x=e.meta.aspect===`9:16`?9/16:e.meta.aspect===`1:1`?1:16/9,S=en(g.template),C=g;if(S){let e=nn(h,S,{aspect:x}),t=kt({...g,autoArrange:!0,elements:e.map(e=>e.pos?{...e,pinned:!0}:e)},{aspect:x});C={...g,elements:e.map(e=>!e.pinned&&!e.pos&&t.has(e.id)?{...e,pos:t.get(e.id)}:e)}}else g.autoArrange&&(C=At(g,{aspect:x}));let w=[];for(let t of e.strip)s.has(t.panelId)?t===o[0]&&w.push(C):w.push(b.get(t.panelId)||t);return{...e,strip:w}}function Ta(e,t,n){let r=wa(t.input);B(r),B(n),I(xa(n,r),`CANVAS_ABSORB`,`The sandbox changed an unrequested panel, layout, or saved original.`);let{originals:i,tokens:a}=t,o=new Map(t.input.doc.strip.map(e=>[e.panelId,e])),s=e=>(I(a.has(e),`CANVAS_ABSORB`,`A carried media reference is unavailable.`),a.get(e)),c=n.strip.map(e=>{let t=i.get(e.panelId);if(!t)return{...e,elements:e.elements.map(e=>({...e,src:s(e.src)})),revert:{rows:e.revert.rows.map(e=>({...i.get(e.panelId)})),repointed:e.revert.repointed.map(e=>({...e,image:i.get(e.panelId).image??null}))}};let n=o.get(e.panelId);if(xa(e,n))return t;let r={...t};for(let t of[`sourcePanelId`,`needsRefresh`,`kind`,`prompt`])xa(e[t]??null,n[t]??null)||(r[t]=e[t]);return xa(e.overlayLayer??null,n.overlayLayer??null)||(r.overlayLayer=s(e.overlayLayer.token)),r});return{...e,strip:c}}function Ea({doc:e,projectId:t,canEdit:n,onDocChange:r,validateDocument:i,editLease:a,host:o}){let s=H(o),c=()=>s.actor(),[l,u]=(0,v.useState)(null),[d,f]=(0,v.useState)(``),p=(0,v.useRef)(null),m=(0,v.useRef)(!0),h=(0,v.useRef)(0),g=(0,v.useRef)(null),_=c();g.current={doc:e,projectId:t,canEdit:n,onDocChange:r,validateDocument:i,actor:_,services:s};let y=(0,v.useCallback)(()=>{h.current++,a?.current===p.current&&(a.current=null),p.current?.abort(),p.current=null,u(null)},[a]);return(0,v.useEffect)(()=>(m.current=!0,()=>{m.current=!1,h.current++,a?.current===p.current&&(a.current=null),p.current?.abort(),p.current=null}),[]),(0,v.useEffect)(()=>{y()},[e,t,n,_,s,y]),{change:(0,v.useCallback)(async(e,t)=>{let n=g.current;if(n.services!==s||!n.doc||!n.canEdit||p.current||a?.current)return;let r=++h.current,i=new AbortController;p.current=i,a&&(a.current=i),u(e),f(``);let o,l=()=>{let e=g.current;I(m.current&&p.current===i&&!i.signal.aborted&&e.doc===n.doc&&e.projectId===n.projectId&&e.canEdit&&e.services===n.services&&e.actor===n.actor&&c()===n.actor&&JSON.stringify(n.doc)===o,`STALE`,`The panels changed. Review the current canvas range again.`)};try{o=JSON.stringify(n.doc);let a=Ca(n.doc,e,t),u=a.input;l();let d=await s.run(ba,{kind:`run`,input:u,signal:i.signal,timeoutMs:15e3});l();let f=Ta(n.doc,a,d.outputs?.edit),p=f===n.doc?n.doc:n.validateDocument(f);return l(),p!==n.doc&&n.onDocChange(e=>{let t=g.current;try{return I(m.current&&!i.signal.aborted&&h.current===r&&t.services===n.services&&t.actor===n.actor&&c()===n.actor&&t.projectId===n.projectId&&t.canEdit&&JSON.stringify(e)===o&&JSON.stringify(n.doc)===o,`STALE`,`The project changed before saving the canvas range.`),p}catch{return e}}),p}catch(e){m.current&&!i.signal.aborted&&c()===n.actor&&g.current.projectId===n.projectId&&f(e.message||`The canvas range could not be updated.`)}finally{p.current===i&&(a?.current===i&&(a.current=null),p.current=null,m.current&&u(null))}},[s]),pending:l,error:d,cancel:y}}let Da={manifest:{schemaVersion:1,sdkVersion:`0.1.0`,id:`stillmade-internal.panel-cast-edit`,version:`1.0.0`,name:`Image Panels cast sheet editing`,description:`Update scene cast descriptions and invalidate changed generated references.`,kind:`task`,runtime:`javascript`,inputs:{effective:{type:`json`},sheets:{type:`json`},referenceIds:{type:`text[]`}},outputs:{edit:{type:`json`}},permissions:{project:[],network:[],filesystem:[],secrets:[]}},code:`const stale=input.referenceIds.filter(id=>(id in input.effective)&&input.sheets[id]!==input.effective[id]);return {edit:{sheets:input.sheets,stale}};`,tests:[]},Oa=(e,t)=>V(e)===V(t);function ka(e,t,n,r){let i=e.scenes?.find(e=>e.sceneId===t);I(i,`CAST_EDIT`,`This scene is no longer available.`);let a=Object.keys(i.sheets||{}).length?i.sheets:e.sheets||{};for(let e of[a,n,r])I(L(e)&&Object.values(e).every(e=>typeof e==`string`),`CAST_EDIT`,`Cast sheets must contain named descriptions.`);return I(Oa(a,r),`STALE`,`The cast descriptions changed. Review the current sheets again.`),{scene:i,input:{effective:structuredClone(a),sheets:structuredClone(n),referenceIds:Object.keys(e.meta?.castRefs||{})}}}function Aa(e,{scene:t,input:n},r){B(r);let i=n.referenceIds.filter(e=>e in n.effective&&n.sheets[e]!==n.effective[e]);I(L(r)&&Object.keys(r).length===2&&Oa(r.sheets,n.sheets)&&Oa(r.stale,i),`CAST_EDIT`,`The sandbox changed an unrequested sheet or reference.`);let a=L(t.sheets)&&Oa(t.sheets,r.sheets),o=a?t:{...t,sheets:r.sheets};if(a&&!i.length)return e;let s={...e,scenes:o===t?e.scenes:e.scenes.map(e=>e===t?o:e)};if(i.length){let t={...e.meta?.castRefs};for(let e of i)delete t[e];s.meta={...e.meta,castRefs:t}}return s}function ja({doc:e,projectId:t,canEdit:n,onDocChange:r,validateDocument:i,editLease:a,host:o}){let s=H(o),c=()=>s.actor(),[l,u]=(0,v.useState)(null),[d,f]=(0,v.useState)(``),p=(0,v.useRef)(null),m=(0,v.useRef)(!0),h=(0,v.useRef)(0),g=(0,v.useRef)(null),_=c();g.current={doc:e,projectId:t,canEdit:n,onDocChange:r,validateDocument:i,actor:_,services:s};let y=(0,v.useCallback)(()=>{h.current++,a?.current===p.current&&(a.current=null),p.current?.abort(),p.current=null,u(null)},[a]);return(0,v.useEffect)(()=>(m.current=!0,()=>{m.current=!1,h.current++,a?.current===p.current&&(a.current=null),p.current?.abort(),p.current=null}),[]),(0,v.useEffect)(()=>{y()},[e,t,n,_,s,y]),{change:(0,v.useCallback)(async(e,t,n)=>{let r=g.current;if(r.services!==s||!r.doc||!r.canEdit||p.current||a?.current)return;let i=++h.current,o=new AbortController;p.current=o,a&&(a.current=o),u(e),f(``);let l,d=()=>{let e=g.current;I(m.current&&p.current===o&&!o.signal.aborted&&e.doc===r.doc&&e.projectId===r.projectId&&e.canEdit&&e.services===r.services&&e.actor===r.actor&&c()===r.actor&&JSON.stringify(r.doc)===l,`STALE`,`The panels changed. Review the current cast descriptions again.`)};try{l=JSON.stringify(r.doc);let a=ka(r.doc,e,t,n),u=a.input;d();let f=await s.run(Da,{kind:`run`,input:u,signal:o.signal,timeoutMs:15e3});d();let p=Aa(r.doc,a,f.outputs?.edit),_=p===r.doc?r.doc:r.validateDocument(p);d(),_!==r.doc&&r.onDocChange(e=>{let t=g.current;try{return I(m.current&&!o.signal.aborted&&h.current===i&&t.services===r.services&&t.actor===r.actor&&c()===r.actor&&t.projectId===r.projectId&&t.canEdit&&JSON.stringify(e)===l&&JSON.stringify(r.doc)===l,`STALE`,`The project changed before saving the cast descriptions.`),_}catch{return e}})}catch(e){m.current&&!o.signal.aborted&&c()===r.actor&&g.current.projectId===r.projectId&&f(e.message||`The cast descriptions could not be updated.`)}finally{p.current===o&&(a?.current===o&&(a.current=null),p.current=null,m.current&&u(null))}},[s]),pending:l,error:d,cancel:y}}let Ma={manifest:{schemaVersion:1,sdkVersion:`0.1.0`,id:`stillmade-internal.panel-reveal-edit`,version:`1.0.0`,name:`Image Panels reveal plan editing`,description:`Edit pixel boxes, labels and ordering in the existing reveal plan.`,kind:`task`,runtime:`javascript`,inputs:{plan:{type:`json`},action:{type:`text`},id:{type:`text`},patch:{type:`json`},direction:{type:`integer`}},outputs:{edit:{type:`json`}},permissions:{project:[],network:[],filesystem:[],secrets:[]}},code:`function normalizeRevealPlan(raw) {\n const els = Array.isArray(raw?.elements) ? raw.elements : [];\n const elements = els\n .filter((e) => e && e.id && e.box)\n .map((e) => ({\n id: String(e.id).slice(0, 40),\n name: String(e.name || e.id).slice(0, 120),\n box: {\n x: Math.max(0, Math.round(Number(e.box.x) || 0)),\n y: Math.max(0, Math.round(Number(e.box.y) || 0)),\n w: Math.max(1, Math.round(Number(e.box.w) || 1)),\n h: Math.max(1, Math.round(Number(e.box.h) || 1)),\n },\n alwaysVisible: e.alwaysVisible === true,\n }));\n const known = new Set(elements.map((e) => e.id));\n const order = (Array.isArray(raw?.order) ? raw.order : []).map((id) => String(id)).filter((id) => known.has(id));\n // Unordered elements append in detection order so every element reveals.\n for (const e of elements) if (!order.includes(e.id) && !e.alwaysVisible) order.push(e.id);\n const bg = Array.isArray(raw?.bg) && raw.bg.length === 3 ? raw.bg.map((c) => Math.max(0, Math.min(255, Math.round(Number(c) || 0)))) : [0, 0, 0];\n return { bg, elements, order };\n}\n\nlet plan=normalizeRevealPlan(input.plan);const {action,id,patch,direction}=input;\nif(action==='clear')return {edit:{cleared:true}};\nif(action==='patch')plan={...plan,elements:plan.elements.map(e=>e.id===id?{...e,...patch,box:{...e.box,...(patch.box||{})}}:e)};\nelse if(action==='move'){const i=plan.order.indexOf(id),j=i+direction;if(i>=0&&j>=0&&j<plan.order.length){const order=[...plan.order];[order[i],order[j]]=[order[j],order[i]];plan={...plan,order};}}\nelse if(action==='remove')plan={...plan,elements:plan.elements.filter(e=>e.id!==id),order:plan.order.filter(x=>x!==id)};\nelse if(action==='merge'){const i=plan.order.indexOf(id),prev=plan.elements.find(e=>e.id===plan.order[i-1]),cur=plan.elements.find(e=>e.id===id);if(i>0&&prev&&cur){const x=Math.min(prev.box.x,cur.box.x),y=Math.min(prev.box.y,cur.box.y),box={x,y,w:Math.max(prev.box.x+prev.box.w,cur.box.x+cur.box.w)-x,h:Math.max(prev.box.y+prev.box.h,cur.box.y+cur.box.h)-y};plan={...plan,elements:plan.elements.filter(e=>e.id!==id).map(e=>e.id===prev.id?{...e,box}:e),order:plan.order.filter(x=>x!==id)};}}\nelse throw new Error('Unknown reveal operation');\nreturn {edit:{cleared:false,plan:normalizeRevealPlan(plan)}};\n`,tests:[]},Na=(e,t)=>JSON.stringify(e)===JSON.stringify(t),Pa=(e,t)=>Object.fromEntries(t.filter(t=>e?.[t]!==void 0).map(t=>[t,e[t]]));function Fa(e,t,n,r,i,a){let o=e.strip.find(e=>e.panelId===t);I(o&&[`patch`,`move`,`remove`,`merge`,`clear`].includes(n),`REVEAL_EDIT`,`Choose a current reveal edit.`);let s=o.revealPlan||{},c={...Pa(s,[`bg`,`order`]),elements:(Array.isArray(s.elements)?s.elements:[]).map(e=>({...Pa(e,[`id`,`name`,`alwaysVisible`]),...e?.box?{box:Pa(e.box,[`x`,`y`,`w`,`h`])}:{}}))};return I(L(i)&&Object.keys(i).every(e=>[`name`,`box`,`alwaysVisible`].includes(e)),`REVEAL_EDIT`,`Unsupported reveal changes.`),{selected:o,input:{plan:c,action:n,id:r,patch:{...Pa(i,[`name`,`alwaysVisible`]),...i.box?{box:Pa(i.box,[`x`,`y`,`w`,`h`])}:{}},direction:a}}}function Ia(e){let t=(Array.isArray(e.elements)?e.elements:[]).filter(e=>e&&e.id&&e.box).map(e=>({id:String(e.id).slice(0,40),name:String(e.name||e.id).slice(0,120),box:Object.fromEntries([`x`,`y`,`w`,`h`].map(t=>[t,Math.max(+(t===`w`||t===`h`),Math.round(Number(e.box[t])||+(t===`w`||t===`h`)))])),alwaysVisible:e.alwaysVisible===!0})),n=new Set(t.map(e=>e.id)),r=(Array.isArray(e.order)?e.order:[]).map(String).filter(e=>n.has(e));for(let e of t)!r.includes(e.id)&&!e.alwaysVisible&&r.push(e.id);return{bg:Array.isArray(e.bg)&&e.bg.length===3?e.bg.map(e=>Math.max(0,Math.min(255,Math.round(Number(e)||0)))):[0,0,0],elements:t,order:r}}function La(e,{selected:t,input:n},r){B(r);let i=Ia(n.plan),{action:a,id:o,patch:s,direction:c}=n;if(a!==`clear`&&I(i.elements.some(e=>e.id===o),`REVEAL_EDIT`,`This reveal element is no longer available.`),a===`patch`&&(i={...i,elements:i.elements.map(e=>e.id===o?{...e,...s,box:{...e.box,...s.box}}:e)}),a===`move`){I(c===1||c===-1,`REVEAL_EDIT`,`Choose an adjacent reveal position.`);let e=i.order.indexOf(o),t=e+c;e>=0&&t>=0&&t<i.order.length&&([i.order[e],i.order[t]]=[i.order[t],i.order[e]])}if(a===`remove`&&(i={...i,elements:i.elements.filter(e=>e.id!==o),order:i.order.filter(e=>e!==o)}),a===`merge`){let e=i.order.indexOf(o),t=i.elements.find(t=>t.id===i.order[e-1]),n=i.elements.find(e=>e.id===o);if(e>0&&t&&n){let e=Math.min(t.box.x,n.box.x),r=Math.min(t.box.y,n.box.y),a={x:e,y:r,w:Math.max(t.box.x+t.box.w,n.box.x+n.box.w)-e,h:Math.max(t.box.y+t.box.h,n.box.y+n.box.h)-r};i={...i,elements:i.elements.filter(e=>e.id!==o).map(e=>e.id===t.id?{...e,box:a}:e),order:i.order.filter(e=>e!==o)}}}let l=a===`clear`?{cleared:!0}:{cleared:!1,plan:Ia(i)};if(B(l),I(Na(r,l),`REVEAL_EDIT`,`The sandbox changed an unrequested reveal field.`),a!==`clear`&&Na(t.revealPlan,r.plan)&&t.provenance===`user`)return e;let u={...t,provenance:`user`};if(r.cleared)delete u.revealPlan;else{let e=t.revealPlan;u.revealPlan={...r.plan,bg:Na(e?.bg,r.plan.bg)?e.bg:r.plan.bg,order:Na(e?.order,r.plan.order)?e.order:r.plan.order,elements:r.plan.elements.map(t=>e?.elements?.find(e=>e.id===t.id&&Na(e,t))||t)}}return{...e,strip:e.strip.map(e=>e===t?u:e)}}function Ra({doc:e,projectId:t,canEdit:n,onDocChange:r,validateDocument:i,editLease:a,host:o}){let s=H(o),c=()=>s.actor(),[l,u]=(0,v.useState)(null),[d,f]=(0,v.useState)(``),p=(0,v.useRef)(null),m=(0,v.useRef)(!0),h=(0,v.useRef)(0),g=(0,v.useRef)(null),_=c();g.current={doc:e,projectId:t,canEdit:n,onDocChange:r,validateDocument:i,actor:_,services:s};let y=(0,v.useCallback)(()=>{h.current++,a?.current===p.current&&(a.current=null),p.current?.abort(),p.current=null,u(null)},[a]);return(0,v.useEffect)(()=>(m.current=!0,()=>{m.current=!1,h.current++,a?.current===p.current&&(a.current=null),p.current?.abort(),p.current=null}),[]),(0,v.useEffect)(()=>{y()},[e,t,n,_,s,y]),{change:(0,v.useCallback)(async(e,t,n=``,r={},i=0)=>{let o=g.current;if(o.services!==s||!o.doc||!o.canEdit||p.current||a?.current)return;let l=++h.current,d=new AbortController;p.current=d,a&&(a.current=d),u(e),f(``);let _,v=()=>{let e=g.current;I(m.current&&p.current===d&&!d.signal.aborted&&e.doc===o.doc&&e.projectId===o.projectId&&e.canEdit&&e.services===o.services&&e.actor===o.actor&&c()===o.actor&&JSON.stringify(o.doc)===_,`STALE`,`The panels changed. Review the current reveal plan before editing again.`)};try{_=JSON.stringify(o.doc);let a=Fa(o.doc,e,t,n,r,i),u=a.input;v();let f=await s.run(Ma,{kind:`run`,input:u,signal:d.signal,timeoutMs:15e3});v();let p=La(o.doc,a,f.outputs?.edit),y=p===o.doc?o.doc:o.validateDocument(p);return v(),y!==o.doc&&o.onDocChange(e=>{let t=g.current;try{return I(m.current&&!d.signal.aborted&&h.current===l&&t.services===o.services&&t.actor===o.actor&&c()===o.actor&&t.projectId===o.projectId&&t.canEdit&&JSON.stringify(e)===_&&JSON.stringify(o.doc)===_,`STALE`,`The project changed before saving the reveal plan.`),y}catch{return e}}),!0}catch(e){m.current&&!d.signal.aborted&&c()===o.actor&&g.current.projectId===o.projectId&&f(e.message||`The reveal plan could not be updated.`)}finally{p.current===d&&(a?.current===d&&(a.current=null),p.current=null,m.current&&u(null))}},[s]),pending:l,error:d,cancel:y}}let za={manifest:{schemaVersion:1,sdkVersion:`0.1.0`,id:`stillmade-internal.panel-text-overlay`,version:`1.0.0`,name:`Image Panels text overlay editing`,description:`Edit labels, placement and arrows or add and remove labels.`,kind:`task`,runtime:`javascript`,inputs:{overlays:{type:`json`},action:{type:`text`},index:{type:`integer`},patch:{type:`json`}},outputs:{overlays:{type:`json`}},permissions:{project:[],network:[],filesystem:[],secrets:[]}},code:`function loadPanelDoc(doc){return doc;}\nfunction setPanelTextOverlays(doc, panelId, overlays) {\n const panel = doc.strip.find((p) => p.panelId === panelId);\n if (!panel) throw new Error(\\`setPanelTextOverlays: unknown panel \"\\${panelId}\"\\`);\n const strip = doc.strip.map((p) => (p.panelId === panelId ? { ...p, textOverlays: overlays } : p));\n return loadPanelDoc({ ...doc, strip });\n}\nfunction updateTextOverlay(doc, panelId, index, patch) {\n const panel = doc.strip.find((p) => p.panelId === panelId);\n const list = panel?.textOverlays || [];\n if (!list[index]) throw new Error(\\`updateTextOverlay: \\${panelId} has no overlay \\${index}\\`);\n const overlays = list.map((o, i) => (i === index\n ? {\n ...o, ...patch,\n ...(patch.pos ? { pos: { ...o.pos, ...patch.pos } } : {}),\n // Deep-merge the arrow so editing the tip target keeps the pointsAt label.\n ...(patch.arrow ? { arrow: { ...o.arrow, ...patch.arrow, ...(patch.arrow.to ? { to: { ...o.arrow?.to, ...patch.arrow.to } } : {}) } } : {}),\n placedBy: patch.placedBy || 'user', editable: true,\n }\n : o));\n return setPanelTextOverlays(doc, panelId, overlays);\n}\nconst doc={strip:[{panelId:'selected',textOverlays:input.overlays}]};let next;\nif(input.action==='update')next=updateTextOverlay(doc,'selected',input.index,input.patch);\nelse{let overlays;if(input.action==='remove')overlays=input.overlays.filter((_,i)=>i!==input.index);else if(input.action==='removeArrow')overlays=input.overlays.map((o,i)=>i===input.index?(({arrow,...rest})=>({...rest,placedBy:'user'}))(o):o);else if(input.action==='add')overlays=[...input.overlays,{text:'TEXT',pos:{x:0.5,y:0.15},size:0.05,placedBy:'user',editable:true}];else throw new Error('Unknown overlay action');next=setPanelTextOverlays(doc,'selected',overlays);}\nreturn {overlays:next.strip[0].textOverlays};`,tests:[]},Ba=(e,t)=>JSON.stringify(e)===JSON.stringify(t),Va=(e,t)=>Object.fromEntries(t.filter(t=>e[t]!==void 0).map(t=>[t,e[t]]));function Ha(e){let t=Va(e,[`text`,`size`,`placedBy`,`editable`,`role`,`atWord`]);return e.pos!==void 0&&(t.pos=e.pos===null?null:Va(e.pos,[`x`,`y`])),e.arrow!==void 0&&(t.arrow=e.arrow===null?null:{...Va(e.arrow,[`pointsAt`]),...e.arrow.to===void 0?{}:{to:Va(e.arrow.to,[`x`,`y`])}}),t}function Ua(e,t,n,r,i){let a=e.strip.find(e=>e.panelId===t);I(a&&[`update`,`remove`,`removeArrow`,`add`].includes(n),`TEXT_OVERLAY`,`Choose a current label action.`);let o=a.textOverlays||[];I(n===`add`||Number.isInteger(r)&&r>=0&&r<o.length,`TEXT_OVERLAY`,`This label is no longer available.`),I(L(i)&&Object.keys(i).every(e=>[`text`,`size`,`role`,`pos`,`arrow`].includes(e)),`TEXT_OVERLAY`,`Unsupported label changes.`);let s=Ha(i);return B(s),{selected:a,input:{overlays:o.map(Ha),action:n,index:r,patch:s}}}function Wa(e,t){return{...e,...t,...t.pos?{pos:{...e.pos,...t.pos}}:{},...t.arrow?{arrow:{...e.arrow,...t.arrow,...t.arrow.to?{to:{...e.arrow?.to,...t.arrow.to}}:{}}}:{},placedBy:t.placedBy||`user`,editable:!0}}function Ga(e,t,n){let{selected:r,input:i}=t,{action:a,index:o,patch:s}=i,c=r.textOverlays||[],l={text:`TEXT`,pos:{x:.5,y:.15},size:.05,placedBy:`user`,editable:!0},u=e=>a===`add`?[...e,l]:a===`remove`?e.filter((e,t)=>t!==o):e.map((e,t)=>t===o?a===`update`?Wa(e,s):(({arrow:e,...t})=>({...t,placedBy:`user`}))(e):e),d=u(i.overlays);B(d),I(Ba(n,d),`TEXT_OVERLAY`,`The sandbox changed fields outside the selected label edit.`);let f=u(c),p=Ba(f,c)?r:{...r,textOverlays:f};return p===r?e:{...e,strip:e.strip.map(e=>e===r?p:e)}}function Ka({doc:e,projectId:t,canEdit:n,onDocChange:r,validateDocument:i,editLease:a,host:o}){let s=H(o),c=()=>s.actor(),[l,u]=(0,v.useState)(null),[d,f]=(0,v.useState)(``),p=(0,v.useRef)(null),m=(0,v.useRef)(!0),h=(0,v.useRef)(0),g=(0,v.useRef)(null),_=c();g.current={doc:e,projectId:t,canEdit:n,onDocChange:r,validateDocument:i,actor:_,services:s};let y=(0,v.useCallback)(()=>{h.current++,a?.current===p.current&&(a.current=null),p.current?.abort(),p.current=null,u(null)},[a]);return(0,v.useEffect)(()=>(m.current=!0,()=>{m.current=!1,h.current++,a?.current===p.current&&(a.current=null),p.current?.abort(),p.current=null}),[]),(0,v.useEffect)(()=>{y()},[e,t,n,_,s,y]),{change:(0,v.useCallback)(async(e,t,n=0,r={})=>{let i=g.current;if(i.services!==s||!i.doc||!i.canEdit||p.current||a?.current)return;let o=++h.current,l=new AbortController;p.current=l,a&&(a.current=l),u(e),f(``);let d,_=()=>{let e=g.current;I(m.current&&p.current===l&&!l.signal.aborted&&e.doc===i.doc&&e.projectId===i.projectId&&e.canEdit&&e.services===i.services&&e.actor===i.actor&&c()===i.actor&&JSON.stringify(i.doc)===d,`STALE`,`The panels changed. Review the current label before editing again.`)};try{d=JSON.stringify(i.doc);let a=Ua(i.doc,e,t,n,r),u=a.input;_();let f=await s.run(za,{kind:`run`,input:u,signal:l.signal,timeoutMs:15e3});_();let p=Ga(i.doc,a,f.outputs?.overlays),v=p===i.doc?i.doc:i.validateDocument(p);_(),v!==i.doc&&i.onDocChange(e=>{let t=g.current;try{return I(m.current&&!l.signal.aborted&&h.current===o&&t.services===i.services&&t.actor===i.actor&&c()===i.actor&&t.projectId===i.projectId&&t.canEdit&&JSON.stringify(e)===d&&JSON.stringify(i.doc)===d,`STALE`,`The project changed before saving the text overlay.`),v}catch{return e}})}catch(e){m.current&&!l.signal.aborted&&c()===i.actor&&g.current.projectId===i.projectId&&f(e.message||`The text overlay could not be updated.`)}finally{p.current===l&&(a?.current===l&&(a.current=null),p.current=null,m.current&&u(null))}},[s]),pending:l,error:d,cancel:y}}let qa={manifest:{schemaVersion:1,sdkVersion:`0.1.0`,id:`stillmade-internal.panel-zoom-target`,version:`1.0.0`,name:`Image Panels zoom target`,description:`Adjust zoom target and strength and flag direct downstream edits.`,kind:`task`,runtime:`javascript`,inputs:{document:{type:`json`},panelId:{type:`text`},target:{type:`json`}},outputs:{edit:{type:`json`}},permissions:{project:[],network:[],filesystem:[],secrets:[]}},code:`const ZOOM_DEFAULT_SCALE=1.8;function loadPanelDoc(doc){return doc;}\nfunction setZoomTarget(doc, panelId, { fx, fy, scale, pickedBy = 'user' } = {}) {\n const panel = doc.strip.find((p) => p.panelId === panelId);\n if (!panel || panel.type !== 'zoom') throw new Error(\\`setZoomTarget: \\${panelId} is not a zoom panel\\`);\n const downstream = new Set(doc.strip.filter((p) => p.kind === 'edit' && p.sourcePanelId === panelId).map((p) => p.panelId));\n const strip = doc.strip.map((p) => {\n if (p.panelId === panelId) return { ...p, zoom: { fx: Number(fx), fy: Number(fy), scale: Number(scale) || panel.zoom?.scale || ZOOM_DEFAULT_SCALE, pickedBy }, image: null };\n if (downstream.has(p.panelId)) return { ...p, needsRefresh: true };\n return p;\n });\n return loadPanelDoc({ ...doc, strip });\n}\nreturn {edit:{schemaVersion:1,strip:setZoomTarget(input.document,input.panelId,input.target).strip}};`,tests:[]},Ja=(e,t)=>JSON.stringify(e)===JSON.stringify(t);function Ya(e,t,n){let r=e.strip.map(e=>Object.fromEntries([`panelId`,`type`,`kind`,`sourcePanelId`,`needsRefresh`,`zoom`].filter(t=>e[t]!==void 0).map(t=>[t,t===`zoom`&&e.zoom?Object.fromEntries([`fx`,`fy`,`scale`,`pickedBy`].filter(t=>e.zoom[t]!==void 0).map(t=>[t,e.zoom[t]])):e[t]])));return{panelId:t,target:Object.fromEntries([`fx`,`fy`,`scale`,`pickedBy`].filter(e=>n[e]!==void 0).map(e=>[e,n[e]])),document:{schemaVersion:1,strip:r}}}function Xa(e,t,n){let r=e.strip.find(e=>e.panelId===t.panelId);I(r?.type===`zoom`,`ZOOM_TARGET`,`Choose a current zoom panel.`);let i={fx:Number(t.target.fx),fy:Number(t.target.fy),scale:Number(t.target.scale)||r.zoom?.scale||1.8,pickedBy:t.target.pickedBy===void 0?`user`:t.target.pickedBy};I(n&&Object.keys(n).length===2&&n.schemaVersion===1&&Array.isArray(n.strip)&&n.strip.length===e.strip.length,`ZOOM_TARGET`,`The sandbox returned an invalid zoom target.`);let a=e.strip.map((e,a)=>{let o=e===r,s=e.kind===`edit`&&e.sourcePanelId===t.panelId,c={...t.document.strip[a],...o?{zoom:i,image:null}:s?{needsRefresh:!0}:{}},l=n.strip[a];I(l&&Object.keys(l).length===Object.keys(c).length&&Object.keys(l).every(e=>Ja(l[e],c[e])),`ZOOM_TARGET`,`The sandbox changed unrelated zoom fields or sources.`);let u=o&&e.image===null&&e.zoom&&Object.keys(e.zoom).length===Object.keys(i).length&&Object.keys(i).every(t=>e.zoom[t]===i[t]);return o?u?e:{...e,zoom:i,image:null}:s&&e.needsRefresh!==!0?{...e,needsRefresh:!0}:e});return a.every((t,n)=>t===e.strip[n])?e:{...e,strip:a}}function Za({doc:e,projectId:t,canEdit:n,onDocChange:r,validateDocument:i,editLease:a,host:o}){let s=H(o),c=()=>s.actor(),[l,u]=(0,v.useState)(null),[d,f]=(0,v.useState)(``),p=(0,v.useRef)(null),m=(0,v.useRef)(!0),h=(0,v.useRef)(0),g=(0,v.useRef)(null),_=c();g.current={doc:e,projectId:t,canEdit:n,onDocChange:r,validateDocument:i,actor:_,services:s};let y=(0,v.useCallback)(()=>{h.current++,a?.current===p.current&&(a.current=null),p.current?.abort(),p.current=null,u(null)},[a]);return(0,v.useEffect)(()=>(m.current=!0,()=>{m.current=!1,h.current++,a?.current===p.current&&(a.current=null),p.current?.abort(),p.current=null}),[]),(0,v.useEffect)(()=>{y()},[e,t,n,_,s,y]),{change:(0,v.useCallback)(async(e,t)=>{let n=g.current;if(n.services!==s||!n.doc||!n.canEdit||p.current||a?.current)return;let r=++h.current,i=new AbortController;p.current=i,a&&(a.current=i),u(e),f(``);let o,l=()=>{let e=g.current;I(m.current&&p.current===i&&!i.signal.aborted&&e.doc===n.doc&&e.projectId===n.projectId&&e.canEdit&&e.services===n.services&&e.actor===n.actor&&c()===n.actor&&JSON.stringify(n.doc)===o,`STALE`,`The panels changed. Choose the current zoom target again.`)};try{o=JSON.stringify(n.doc);let a=Ya(n.doc,e,t);l();let u=await s.run(qa,{kind:`run`,input:a,signal:i.signal,timeoutMs:15e3});l();let d=Xa(n.doc,a,u.outputs?.edit),f=d===n.doc?n.doc:n.validateDocument(d);l(),f!==n.doc&&n.onDocChange(e=>{let t=g.current;try{return I(m.current&&!i.signal.aborted&&h.current===r&&t.services===n.services&&t.actor===n.actor&&c()===n.actor&&t.projectId===n.projectId&&t.canEdit&&JSON.stringify(e)===o&&JSON.stringify(n.doc)===o,`STALE`,`The project changed before saving the zoom target.`),f}catch{return e}})}catch(e){m.current&&!i.signal.aborted&&c()===n.actor&&g.current.projectId===n.projectId&&f(e.message||`The zoom target could not be updated.`)}finally{p.current===i&&(a?.current===i&&(a.current=null),p.current=null,m.current&&u(null))}},[s]),pending:l,error:d,cancel:y}}let Qa={manifest:{schemaVersion:1,sdkVersion:`0.1.0`,id:`stillmade-internal.panel-gif-choice`,version:`1.0.0`,name:`Image Panels GIF choices`,description:`Change a GIF mode or select an existing alternate.`,kind:`task`,runtime:`javascript`,inputs:{document:{type:`json`},panelId:{type:`text`},action:{type:`text`},value:{type:`text`}},outputs:{edit:{type:`json`}},permissions:{project:[],network:[],filesystem:[],secrets:[]}},code:`const GIF_MODES=['replace','overlay'];function loadPanelDoc(doc){return doc;}\nfunction giphyPanelOr(doc, panelId, op) {\n const panel = doc.strip.find((p) => p.panelId === panelId);\n if (!panel) throw new Error(\\`\\${op}: unknown panel \"\\${panelId}\"\\`);\n if (panel.type !== 'giphy') throw new Error(\\`\\${op}: \\${panelId} is not a giphy panel\\`);\n return panel;\n}\nfunction setGifMode(doc, panelId, mode) {\n if (!GIF_MODES.includes(mode)) throw new Error(\\`setGifMode: mode must be \\${GIF_MODES.join('|')}\\`);\n const panel = giphyPanelOr(doc, panelId, 'setGifMode');\n if (panel.mode === mode) return doc;\n const strip = doc.strip.map((p) => (p.panelId === panelId ? { ...p, mode, provenance: 'user' } : p));\n return loadPanelDoc({ ...doc, strip });\n}\nfunction setPanelGif(doc, panelId, gifUrl) {\n const panel = giphyPanelOr(doc, panelId, 'setPanelGif');\n const url = String(gifUrl || '').trim();\n if (!url) throw new Error('setPanelGif: a gif url is required');\n if (panel.gif === url) return doc;\n const strip = doc.strip.map((p) => (p.panelId === panelId ? { ...p, gif: url, provenance: 'user' } : p));\n return loadPanelDoc({ ...doc, strip });\n}\nfunction swapGif(doc, panelId, candidateUrl) {\n giphyPanelOr(doc, panelId, 'swapGif');\n const url = String(candidateUrl || '').trim();\n if (!url) throw new Error('swapGif: a candidate url is required');\n return setPanelGif(doc, panelId, url);\n}\nif(!['mode','candidate'].includes(input.action))throw new Error('Unknown GIF action');const next=input.action==='mode'?setGifMode(input.document,input.panelId,input.value):swapGif(input.document,input.panelId,input.value);return {edit:{schemaVersion:1,changed:next!==input.document,strip:next.strip}};`,tests:[]};function $a(e,t,n,r){let i=e.strip.find(e=>e.panelId===t);I(i?.type===`giphy`,`GIF_CHOICE`,`Choose a current GIF beat.`),I(n===`mode`||n===`candidate`,`GIF_CHOICE`,`Choose a supported GIF action.`);let a=n===`candidate`?String(r||``).trim():null;n===`candidate`?I(a&&(i.gif===a||(i.candidates||[]).some(e=>String(e||``).trim()===a)),`GIF_CHOICE`,`Choose an alternate from the current GIF candidates.`):I([`replace`,`overlay`].includes(r),`GIF_CHOICE`,`Choose replace or overlay.`);let o=new Map,s=e=>e&&(o.has(e)||o.set(e,`gif-${o.size}`),o.get(e)),c=e.strip.map(e=>({...Object.fromEntries([`panelId`,`type`,`mode`,`provenance`].filter(t=>e[t]!==void 0).map(t=>[t,e[t]])),...e.gif===void 0?{}:{gif:s(e.gif)}}));return{input:{panelId:t,action:n,value:n===`candidate`?s(a):r,document:{schemaVersion:1,strip:c}},candidate:a}}function eo(e,t,n){let{input:r,candidate:i}=t,a=e.strip.find(e=>e.panelId===r.panelId),o=r.action===`mode`?`mode`:`gif`,s=r.action===`mode`?r.value:i,c=a[o]!==s;I(n&&Object.keys(n).length===3&&n.schemaVersion===1&&n.changed===c&&Array.isArray(n.strip)&&n.strip.length===e.strip.length,`GIF_CHOICE`,`The sandbox returned an invalid GIF choice.`);let l=e.strip.map((e,t)=>{let i={...r.document.strip[t],...c&&e===a?{[o]:r.value,provenance:`user`}:{}},l=n.strip[t];return I(l&&Object.keys(l).length===Object.keys(i).length&&Object.keys(l).every(e=>l[e]===i[e]),`GIF_CHOICE`,`The sandbox changed an unrelated GIF field.`),c&&e===a?{...e,[o]:s,provenance:`user`}:e});return c?{...e,strip:l}:e}function to({doc:e,projectId:t,canEdit:n,onDocChange:r,validateDocument:i,editLease:a,host:o}){let s=H(o),c=()=>s.actor(),[l,u]=(0,v.useState)(null),[d,f]=(0,v.useState)(``),p=(0,v.useRef)(null),m=(0,v.useRef)(!0),h=(0,v.useRef)(0),g=(0,v.useRef)(null),_=c();g.current={doc:e,projectId:t,canEdit:n,onDocChange:r,validateDocument:i,actor:_,services:s};let y=(0,v.useCallback)(()=>{h.current++,a?.current===p.current&&(a.current=null),p.current?.abort(),p.current=null,u(null)},[a]);return(0,v.useEffect)(()=>(m.current=!0,()=>{m.current=!1,h.current++,a?.current===p.current&&(a.current=null),p.current?.abort(),p.current=null}),[]),(0,v.useEffect)(()=>{y()},[e,t,n,_,s,y]),{choose:(0,v.useCallback)(async(n,r,i)=>{let o=g.current;if(!o.doc||!o.canEdit||p.current||a?.current)return;if(o.services!==s||o.doc!==e||o.projectId!==t||o.actor!==_||c()!==_){f(`The GIF changed. Review the GIF choice again.`);return}let l=++h.current,d=new AbortController;p.current=d,a&&(a.current=d),u(n),f(``);let v,y=()=>{let e=g.current;I(m.current&&p.current===d&&!d.signal.aborted&&e.doc===o.doc&&e.projectId===o.projectId&&e.canEdit&&e.services===o.services&&e.actor===o.actor&&c()===o.actor&&JSON.stringify(o.doc)===v,`STALE`,`The GIF changed. Review the current GIF choice again.`)};try{v=JSON.stringify(o.doc);let e=$a(o.doc,n,r,i);y();let t=await s.run(Qa,{kind:`run`,input:e.input,signal:d.signal,timeoutMs:15e3});y();let a=eo(o.doc,e,t.outputs?.edit),u=a===o.doc?o.doc:o.validateDocument(a);if(y(),u!==o.doc){let e=!1;o.onDocChange(t=>{let n=g.current,r=!1;try{r=m.current&&h.current===l&&!d.signal.aborted&&n.doc===o.doc&&n.projectId===o.projectId&&n.canEdit&&n.services===o.services&&n.actor===o.actor&&c()===o.actor&&JSON.stringify(t)===v&&JSON.stringify(o.doc)===v}catch{}return r?u:(e||(e=!0,queueMicrotask(()=>{m.current&&c()===o.actor&&g.current.projectId===o.projectId&&f(`The GIF changed before the GIF choice could be saved. Review the current GIF choice again.`)})),t)})}return u}catch(e){m.current&&!d.signal.aborted&&c()===o.actor&&g.current.projectId===o.projectId&&f(e.message||`The GIF choice could not be applied.`)}finally{p.current===d&&(a?.current===d&&(a.current=null),p.current=null,m.current&&u(null))}},[e,t,_,s]),pending:l,error:d,cancel:y}}let no={manifest:{schemaVersion:1,sdkVersion:`0.1.0`,id:`stillmade-internal.panel-move-gif`,version:`1.0.0`,name:`Image Panels GIF reorder`,description:`Move a GIF beat one position and keep the strip timeline contiguous.`,kind:`task`,runtime:`javascript`,inputs:{document:{type:`json`},panelId:{type:`text`},direction:{type:`integer`}},outputs:{edit:{type:`json`}},permissions:{project:[],network:[],filesystem:[],secrets:[]}},code:`function loadPanelDoc(doc){return doc;}\nfunction giphyPanelOr(doc, panelId, op) {\n const panel = doc.strip.find((p) => p.panelId === panelId);\n if (!panel) throw new Error(\\`\\${op}: unknown panel \"\\${panelId}\"\\`);\n if (panel.type !== 'giphy') throw new Error(\\`\\${op}: \\${panelId} is not a giphy panel\\`);\n return panel;\n}\nfunction retimeAfterReorder(strip) {\n let t = strip.length ? Math.min(...strip.map((p) => Number(p.startMs) || 0)) : 0;\n return strip.map((p) => {\n const out = { ...p, startMs: t };\n t += Math.max(1, Number(p.durationMs) || 1);\n return out;\n });\n}\nfunction movePanel(doc, panelId, dir) {\n const i = doc.strip.findIndex((p) => p.panelId === panelId);\n const j = i + (dir < 0 ? -1 : 1);\n if (i < 0 || j < 0 || j >= doc.strip.length) return doc;\n const strip = [...doc.strip];\n [strip[i], strip[j]] = [strip[j], strip[i]];\n return loadPanelDoc({ ...doc, strip: retimeAfterReorder(strip) });\n}\nfunction moveGif(doc, panelId, dir) {\n giphyPanelOr(doc, panelId, 'moveGif');\n return movePanel(doc, panelId, dir);\n}\nconst next=moveGif(input.document,input.panelId,input.direction);return {edit:{schemaVersion:1,changed:next!==input.document,strip:next.strip}};`,tests:[]},ro=[`panelId`,`type`,`startMs`,`durationMs`];function io(e,t,n){return{panelId:t,direction:n,document:{schemaVersion:1,strip:e.strip.map(e=>Object.fromEntries(ro.map(t=>[t,e[t]])))}}}function ao(e,t,n){let r=e.strip.findIndex(e=>e.panelId===t.panelId),i=r+(t.direction<0?-1:1);I(r>=0&&e.strip[r].type===`giphy`&&Number.isInteger(t.direction),`PANEL_MOVE`,`Choose a current GIF beat to move.`);let a=i>=0&&i<e.strip.length;I(n&&Object.keys(n).length===3&&n.schemaVersion===1&&n.changed===a&&Array.isArray(n.strip)&&n.strip.length===e.strip.length,`PANEL_MOVE`,`The sandbox returned an invalid GIF move.`);let o=e.strip.map((e,t)=>t);a&&([o[r],o[i]]=[o[i],o[r]]);let s=Math.min(...e.strip.map(e=>Number(e.startMs)||0)),c=o.map((r,i)=>{let o=e.strip[r],c={...t.document.strip[r],...a?{startMs:s}:{}},l=n.strip[i];return I(l&&Object.keys(l).length===ro.length&&ro.every(e=>l[e]===c[e]),`PANEL_MOVE`,`The sandbox changed a panel outside the adjacent move.`),s+=Math.max(1,Number(o.durationMs)||1),c.startMs===o.startMs?o:{...o,startMs:c.startMs}});return a?{...e,strip:c}:e}function oo({doc:e,projectId:t,canEdit:n,onDocChange:r,validateDocument:i,editLease:a,host:o}){let s=H(o),c=()=>s.actor(),[l,u]=(0,v.useState)(null),[d,f]=(0,v.useState)(``),p=(0,v.useRef)(null),m=(0,v.useRef)(!0),h=(0,v.useRef)(0),g=(0,v.useRef)(null),_=c();g.current={doc:e,projectId:t,canEdit:n,onDocChange:r,validateDocument:i,actor:_,services:s};let y=(0,v.useCallback)(()=>{h.current++,a?.current===p.current&&(a.current=null),p.current?.abort(),p.current=null,u(null)},[a]);return(0,v.useEffect)(()=>(m.current=!0,()=>{m.current=!1,h.current++,a?.current===p.current&&(a.current=null),p.current?.abort(),p.current=null}),[]),(0,v.useEffect)(()=>{y()},[e,t,n,_,s,y]),{move:(0,v.useCallback)(async(e,t)=>{let n=g.current;if(n.services!==s||!n.doc||!n.canEdit||p.current||a?.current)return;let r=++h.current,i=new AbortController;p.current=i,a&&(a.current=i),u(e),f(``);let o,l=()=>{let e=g.current;I(m.current&&p.current===i&&!i.signal.aborted&&e.doc===n.doc&&e.projectId===n.projectId&&e.canEdit&&e.services===n.services&&e.actor===n.actor&&c()===n.actor&&JSON.stringify(n.doc)===o,`STALE`,`The panels changed. Choose the current GIF beat again.`)};try{o=JSON.stringify(n.doc);let a=io(n.doc,e,t);l();let u=await s.run(no,{kind:`run`,input:a,signal:i.signal,timeoutMs:15e3});l();let d=ao(n.doc,a,u.outputs?.edit),f=d===n.doc?n.doc:n.validateDocument(d);l(),f!==n.doc&&n.onDocChange(e=>{let t=g.current;try{return I(m.current&&!i.signal.aborted&&h.current===r&&t.services===n.services&&t.actor===n.actor&&c()===n.actor&&t.projectId===n.projectId&&t.canEdit&&JSON.stringify(e)===o&&JSON.stringify(n.doc)===o,`STALE`,`The project changed before moving the GIF beat.`),f}catch{return e}})}catch(e){m.current&&!i.signal.aborted&&c()===n.actor&&g.current.projectId===n.projectId&&f(e.message||`The GIF beat could not be moved.`)}finally{p.current===i&&(a?.current===i&&(a.current=null),p.current=null,m.current&&u(null))}},[s]),pending:l,error:d,cancel:y}}let so={manifest:{schemaVersion:1,sdkVersion:`0.1.0`,id:`stillmade-internal.panel-version`,version:`1.0.0`,name:`Image Panels saved version selection`,description:`Select a saved panel frame and flag its downstream edit chain.`,kind:`task`,runtime:`javascript`,inputs:{document:{type:`json`},panelId:{type:`text`},index:{type:`integer`}},outputs:{edit:{type:`json`}},permissions:{project:[],network:[],filesystem:[],secrets:[]}},code:`function loadPanelDoc(doc){return doc;}\nfunction panelVersions(panel) {\n return panel.versions?.length ? panel.versions : (panel.image ? [panel.image] : []);\n}\nfunction downstreamOf(strip, panelId) {\n const affected = new Set([panelId]);\n const out = [];\n for (const p of (strip || [])) {\n if (p.kind === 'edit' && p.sourcePanelId && affected.has(p.sourcePanelId)) {\n affected.add(p.panelId);\n out.push(p.panelId);\n }\n }\n return out;\n}\nfunction setPanelVersion(doc, panelId, index) {\n const panel = doc.strip.find((p) => p.panelId === panelId);\n if (!panel) throw new Error(\\`setPanelVersion: unknown panel \"\\${panelId}\"\\`);\n const versions = panelVersions(panel);\n if (index < 0 || index >= versions.length) throw new Error(\\`setPanelVersion: version \\${index + 1} of \\${versions.length} doesn't exist\\`);\n const url = versions[index];\n if (url === panel.image) return doc; // no change — same state object\n const flagged = new Set(downstreamOf(doc.strip, panelId));\n const strip = doc.strip.map((p) => (p.panelId === panelId\n ? { ...p, image: url, versions, needsRefresh: false }\n : flagged.has(p.panelId) ? { ...p, needsRefresh: true } : p));\n return loadPanelDoc({ ...doc, strip });\n}\nconst next=setPanelVersion(input.document,input.panelId,input.index);return {edit:{schemaVersion:1,changed:next!==input.document,strip:next.strip}};`,tests:[]},co=(e,t)=>JSON.stringify(e)===JSON.stringify(t);function lo(e,t,n){let r=new Map,i=e=>e&&(r.has(e)||r.set(e,`image-${r.size}`),r.get(e));return{panelId:t,index:n,document:{schemaVersion:1,strip:e.strip.map(e=>({...Object.fromEntries([`panelId`,`kind`,`sourcePanelId`,`needsRefresh`].filter(t=>e[t]!==void 0).map(t=>[t,e[t]])),...e.image===void 0?{}:{image:i(e.image)},...e.versions===void 0?{}:{versions:e.versions.map(i)}}))}}}function uo(e,t,n){let r=e.strip.find(e=>e.panelId===t.panelId);I(r,`PANEL_VERSION`,`The selected panel is no longer available.`);let i=r.versions?.length?r.versions:r.image?[r.image]:[];I(Number.isInteger(t.index)&&t.index>=0&&t.index<i.length,`PANEL_VERSION`,`The saved version is no longer available.`);let a=i[t.index]!==r.image;I(n&&Object.keys(n).length===3&&n.schemaVersion===1&&n.changed===a&&Array.isArray(n.strip)&&n.strip.length===e.strip.length,`PANEL_VERSION`,`The sandbox returned an invalid version selection.`);let o=new Set([t.panelId]),s=e.strip.map((e,s)=>{let c={...t.document.strip[s]},l=e,u=e.kind===`edit`&&e.sourcePanelId&&o.has(e.sourcePanelId);if(u&&o.add(e.panelId),a&&e===r){let n=c.versions?.length?c.versions:c.image?[c.image]:[];c.image=n[t.index],c.versions=n,c.needsRefresh=!1,l={...e,image:i[t.index],versions:i,needsRefresh:!1}}else a&&u&&(c.needsRefresh=!0,l=e.needsRefresh===!0?e:{...e,needsRefresh:!0});let d=n.strip[s];return I(d&&Object.keys(d).length===Object.keys(c).length&&Object.keys(d).every(e=>co(d[e],c[e])),`PANEL_VERSION`,`The sandbox changed an unrelated frame or source chain.`),l});return a?{...e,strip:s}:e}function fo({doc:e,projectId:t,canEdit:n,onDocChange:r,validateDocument:i,editLease:a,host:o}){let s=H(o),c=()=>s.actor(),[l,u]=(0,v.useState)(null),[d,f]=(0,v.useState)(``),p=(0,v.useRef)(null),m=(0,v.useRef)(!0),h=(0,v.useRef)(0),g=(0,v.useRef)(null),_=c();g.current={doc:e,projectId:t,canEdit:n,onDocChange:r,validateDocument:i,actor:_,services:s};let y=(0,v.useCallback)(()=>{h.current++,a?.current===p.current&&(a.current=null),p.current?.abort(),p.current=null,u(null)},[a]);return(0,v.useEffect)(()=>(m.current=!0,()=>{m.current=!1,h.current++,a?.current===p.current&&(a.current=null),p.current?.abort(),p.current=null}),[]),(0,v.useEffect)(()=>{y()},[e,t,n,_,s,y]),{select:(0,v.useCallback)(async(e,t)=>{let n=g.current;if(n.services!==s||!n.doc||!n.canEdit||p.current||a?.current)return;let r=++h.current,i=new AbortController;p.current=i,a&&(a.current=i),u(e),f(``);let o,l=()=>{let e=g.current;I(m.current&&p.current===i&&!i.signal.aborted&&e.doc===n.doc&&e.projectId===n.projectId&&e.canEdit&&e.services===n.services&&e.actor===n.actor&&c()===n.actor&&JSON.stringify(n.doc)===o,`STALE`,`The panels changed. Choose the saved version again.`)};try{o=JSON.stringify(n.doc);let a=lo(n.doc,e,t);l();let u=await s.run(so,{kind:`run`,input:a,signal:i.signal,timeoutMs:15e3});l();let d=uo(n.doc,a,u.outputs?.edit),f=d===n.doc?n.doc:n.validateDocument(d);l(),f!==n.doc&&n.onDocChange(e=>{let t=g.current;try{return I(m.current&&!i.signal.aborted&&h.current===r&&t.services===n.services&&t.actor===n.actor&&c()===n.actor&&t.projectId===n.projectId&&t.canEdit&&JSON.stringify(e)===o&&JSON.stringify(n.doc)===o,`STALE`,`The project changed before selecting the saved version.`),f}catch{return e}})}catch(e){m.current&&!i.signal.aborted&&c()===n.actor&&g.current.projectId===n.projectId&&f(e.message||`The saved version could not be selected.`)}finally{p.current===i&&(a?.current===i&&(a.current=null),p.current=null,m.current&&u(null))}},[s]),pending:l,error:d,cancel:y}}let po={manifest:{schemaVersion:1,sdkVersion:`0.1.0`,id:`stillmade-internal.panel-insert-zoom`,version:`1.0.0`,name:`Image Panels zoom insertion`,description:`Carve source timing into a zoom and hand off dependent framing.`,kind:`task`,runtime:`javascript`,inputs:{document:{type:`json`},panelId:{type:`text`}},outputs:{edit:{type:`json`}},permissions:{project:[],network:[],filesystem:[],secrets:[]}},code:`const PANEL_MIN_MS=350;function loadPanelDoc(doc){return doc;}\nfunction reservedPanelIds(strip) {\n const ids = new Set();\n for (const p of (strip || [])) {\n ids.add(p.panelId);\n for (const r of (p.revert?.rows || [])) ids.add(r.panelId);\n }\n return ids;\n}\nfunction insertZoomAfter(doc, panelId) {\n const idx = doc.strip.findIndex((p) => p.panelId === panelId);\n const src = doc.strip[idx];\n if (!src || src.type !== 'panel') throw new Error('insertZoomAfter: zooms push into generative panels');\n const take = Math.max(600, Math.min(Number(src.durationMs) / 2, 1500));\n if (Number(src.durationMs) - take < PANEL_MIN_MS) throw new Error('insertZoomAfter: the beat is too short to carve a zoom out of');\n const reserved = reservedPanelIds(doc.strip);\n let zn = doc.strip.filter((p) => p.type === 'zoom').length + 1;\n while (reserved.has(\\`\\${src.panelId}z\\${zn}\\`)) zn++;\n const zoomId = \\`\\${src.panelId}z\\${zn}\\`;\n const zoom = {\n panelId: zoomId, type: 'zoom', sceneId: src.sceneId, lineageId: src.lineageId,\n sourcePanelId: src.panelId, zoom: null, image: null,\n startMs: Number(src.startMs) + Number(src.durationMs) - take, durationMs: take,\n transitionIn: 'cut', provenance: 'user',\n };\n // The AUTOMATIC hand-off: the next edit that built on the source now builds\n // on the ZOOMED frame instead (flagged for regen — its framing changed).\n let handedOff = false;\n const strip = doc.strip.flatMap((p) => {\n if (p.panelId === src.panelId) return [{ ...p, durationMs: Number(p.durationMs) - take }, zoom];\n if (!handedOff && p.kind === 'edit' && p.sourcePanelId === src.panelId && p.sceneId === src.sceneId) {\n handedOff = true;\n return [{ ...p, sourcePanelId: zoomId, needsRefresh: true }];\n }\n return [p];\n });\n return loadPanelDoc({ ...doc, strip });\n}\nreturn {edit:{schemaVersion:1,strip:insertZoomAfter(input.document,input.panelId).strip}};`,tests:[]},mo=[`panelId`,`type`,`kind`,`startMs`,`durationMs`,`sceneId`,`lineageId`,`sourcePanelId`,`needsRefresh`],ho=(e,t)=>JSON.stringify(e)===JSON.stringify(t);function go(e,t){return{panelId:t,document:{schemaVersion:1,strip:e.strip.map(e=>({...Object.fromEntries(mo.filter(t=>e[t]!==void 0).map(t=>[t,e[t]])),...e.revert?.rows?{revert:{rows:e.revert.rows.map(e=>({panelId:e.panelId}))}}:{}}))}}}function _o(e,t,n){let r=e.strip.findIndex(e=>e.panelId===t.panelId),i=e.strip[r];I(i?.type===`panel`,`PANEL_ZOOM`,`Zooms require a generative source panel.`);let a=Math.max(600,Math.min(Number(i.durationMs)/2,1500));I(Number(i.durationMs)-a>=350,`PANEL_ZOOM`,`This beat is too short to carve a zoom out of.`);let o=new Set(e.strip.flatMap(e=>[e.panelId,...(e.revert?.rows||[]).map(e=>e.panelId)])),s=e.strip.filter(e=>e.type===`zoom`).length+1;for(;o.has(`${i.panelId}z${s}`);)s++;let c=`${i.panelId}z${s}`,l={panelId:c,type:`zoom`,sceneId:i.sceneId,lineageId:i.lineageId,sourcePanelId:i.panelId,zoom:null,image:null,startMs:Number(i.startMs)+Number(i.durationMs)-a,durationMs:a,transitionIn:`cut`,provenance:`user`};I(n&&Object.keys(n).length===2&&n.schemaVersion===1&&Array.isArray(n.strip)&&n.strip.length===e.strip.length+1,`PANEL_ZOOM`,`The sandbox returned an invalid zoom insertion.`);let u=(e,t)=>e&&Object.keys(e).length===Object.keys(t).filter(e=>t[e]!==void 0).length&&Object.keys(e).every(n=>ho(e[n],t[n]));I(u(n.strip[r+1],l),`PANEL_ZOOM`,`The sandbox changed the new zoom contract.`);let d=!1;return n.strip.map((n,o)=>{if(o===r+1)return{...l};let s=o>r+1?o-1:o,f=e.strip[s],p={...t.document.strip[s]},m={...f};return s===r?(p.durationMs=Number(i.durationMs)-a,m.durationMs=p.durationMs):!d&&f.kind===`edit`&&f.sourcePanelId===i.panelId&&f.sceneId===i.sceneId&&(d=!0,p.sourcePanelId=c,p.needsRefresh=!0,m.sourcePanelId=c,m.needsRefresh=!0),I(u(n,p),`PANEL_ZOOM`,`The sandbox changed an unrelated panel or its timing.`),ho(f,m)?f:m})}function vo({doc:e,projectId:t,canEdit:n,onDocChange:r,validateDocument:i,editLease:a,host:o}){let s=H(o),c=()=>s.actor(),[l,u]=(0,v.useState)(null),[d,f]=(0,v.useState)(``),p=(0,v.useRef)(null),m=(0,v.useRef)(!0),h=(0,v.useRef)(0),g=(0,v.useRef)(null),_=c();g.current={doc:e,projectId:t,canEdit:n,onDocChange:r,validateDocument:i,actor:_,services:s};let y=(0,v.useCallback)(()=>{h.current++,a?.current===p.current&&(a.current=null),p.current?.abort(),p.current=null,u(null)},[a]);return(0,v.useEffect)(()=>(m.current=!0,()=>{m.current=!1,h.current++,a?.current===p.current&&(a.current=null),p.current?.abort(),p.current=null}),[]),(0,v.useEffect)(()=>{y()},[e,t,n,_,s,y]),{insert:(0,v.useCallback)(async e=>{let t=g.current;if(t.services!==s||!t.doc||!t.canEdit||p.current||a?.current)return;let n=++h.current,r=new AbortController;p.current=r,a&&(a.current=r),u(e),f(``);let i,o=()=>{let e=g.current;I(m.current&&p.current===r&&!r.signal.aborted&&e.doc===t.doc&&e.projectId===t.projectId&&e.canEdit&&e.services===t.services&&e.actor===t.actor&&c()===t.actor&&JSON.stringify(t.doc)===i,`STALE`,`The panels changed. Choose the current zoom source again.`)};try{i=JSON.stringify(t.doc);let a=go(t.doc,e);o();let l=await s.run(po,{kind:`run`,input:a,signal:r.signal,timeoutMs:15e3});o();let u=t.validateDocument({...t.doc,strip:_o(t.doc,a,l.outputs?.edit)});o(),t.onDocChange(e=>{let a=g.current;try{return I(m.current&&!r.signal.aborted&&h.current===n&&a.services===t.services&&a.actor===t.actor&&c()===t.actor&&a.projectId===t.projectId&&a.canEdit&&JSON.stringify(e)===i&&JSON.stringify(t.doc)===i,`STALE`,`The project changed before inserting the zoom.`),u}catch{return e}})}catch(e){m.current&&!r.signal.aborted&&c()===t.actor&&g.current.projectId===t.projectId&&f(e.message||`The zoom could not be inserted.`)}finally{p.current===r&&(a?.current===r&&(a.current=null),p.current=null,m.current&&u(null))}},[s]),pending:l,error:d,cancel:y}}let yo={manifest:{schemaVersion:1,sdkVersion:`0.1.0`,id:`stillmade-internal.panel-revert-canvas`,version:`1.0.0`,name:`Image Panels canvas reversion`,description:`Restore absorbed panels and repair their source references and timeline.`,kind:`task`,runtime:`javascript`,inputs:{document:{type:`json`},panelId:{type:`text`}},outputs:{edit:{type:`json`}},permissions:{project:[],network:[],filesystem:[],secrets:[]}},code:`function loadPanelDoc(doc){return doc;}\nfunction baseFallbackPrompt(strip, panel) {\n const pool = [];\n for (const p of (strip || [])) {\n pool.push(p);\n for (const r of (p.revert?.rows || [])) pool.push(r);\n }\n const lineageBase = pool.find((p) => p.kind === 'base' && p.lineageId === panel.lineageId && p.sceneId === panel.sceneId && String(p.prompt || '').trim());\n if (lineageBase) return lineageBase.prompt;\n return String(panel.prompt || '').replace(/^\\\\s*keep\\\\s+(everything\\\\s+)?identical\\\\s*;\\\\s*/i, '').trim() || 'the scene';\n}\nfunction retimeAfterReorder(strip) {\n let t = strip.length ? Math.min(...strip.map((p) => Number(p.startMs) || 0)) : 0;\n return strip.map((p) => {\n const out = { ...p, startMs: t };\n t += Math.max(1, Number(p.durationMs) || 1);\n return out;\n });\n}\nfunction revertCanvas(doc, panelId) {\n const panel = doc.strip.find((p) => p.panelId === panelId);\n if (!panel || panel.type !== 'canvas') throw new Error(\\`revertCanvas: \\${panelId} is not a canvas panel\\`);\n const rows = panel.revert?.rows;\n if (!Array.isArray(rows) || !rows.length) throw new Error('revertCanvas: this canvas has no panels to restore');\n const back = new Map((panel.revert.repointed || []).map((r) => [r.panelId, r]));\n // Re-base the stored rows onto the canvas's CURRENT window — the strip may\n // have been retimed while the canvas existed, and restoring absolute\n // absorb-time starts would overlap the previous beat and gap the next one.\n const shift = Number(panel.startMs) - Number(rows[0].startMs);\n const strip = doc.strip.flatMap((p) => {\n if (p.panelId === panelId) return rows.map((r) => ({ ...r, startMs: Number(r.startMs) + shift }));\n const r = back.get(p.panelId);\n if (!r) return [p];\n // Honest staleness: a panel REGENERATED while it pointed at the fallback\n // frame is not clean just because it was clean before the absorb.\n const regenerated = (p.image ?? null) !== (r.image ?? null);\n const restored = { ...p, sourcePanelId: r.sourcePanelId, needsRefresh: !!r.needsRefresh || regenerated };\n if (r.sourcePanelId) restored.kind = 'edit';\n if (!restored.needsRefresh) delete restored.needsRefresh;\n return [restored];\n });\n // A stored row can reference a panel deleted while the canvas existed (the\n // frozen snapshot never saw that delete). Repair instead of throwing — a\n // revert that can never run would strand the originals forever.\n const live = new Set(strip.map((p) => p.panelId));\n const repaired = strip.map((p, i) => {\n const before = strip.slice(0, i);\n const fallbackFor = (q) => [...before].reverse().find((x) => x.lineageId === q.lineageId && x.sceneId === q.sceneId && (x.type === 'panel' || x.type === 'zoom') && x.kind !== 'repeat');\n if ((p.kind === 'edit' || p.type === 'zoom') && p.sourcePanelId && !live.has(p.sourcePanelId)) {\n const f = fallbackFor(p);\n return f\n ? { ...p, sourcePanelId: f.panelId, needsRefresh: true }\n : { ...p, kind: 'base', sourcePanelId: null, prompt: baseFallbackPrompt(doc.strip, p), needsRefresh: true };\n }\n if (p.kind === 'repeat' && p.repeatOf && !live.has(p.repeatOf)) {\n const f = fallbackFor(p);\n return f\n ? { ...p, kind: 'repeat', repeatOf: f.panelId }\n : { ...p, kind: 'base', repeatOf: null, prompt: baseFallbackPrompt(doc.strip, p), needsRefresh: true };\n }\n if (p.kind === 'revealStep' && p.revealOf && !live.has(p.revealOf)) {\n const f = fallbackFor(p);\n return f\n ? { ...p, kind: 'edit', revealOf: undefined, revealIndex: undefined, sourcePanelId: f.panelId, needsRefresh: true }\n : { ...p, kind: 'base', revealOf: undefined, revealIndex: undefined, sourcePanelId: null, prompt: baseFallbackPrompt(doc.strip, p), needsRefresh: true };\n }\n return p;\n });\n return loadPanelDoc({ ...doc, strip: retimeAfterReorder(repaired) });\n}\nconst next=revertCanvas(input.document,input.panelId);return {edit:{schemaVersion:1,strip:next.strip}};`,tests:[]},bo=[`panelId`,`type`,`kind`,`startMs`,`durationMs`,`sceneId`,`lineageId`,`sourcePanelId`,`repeatOf`,`revealOf`,`revealIndex`,`prompt`,`needsRefresh`],xo=(e,t)=>JSON.stringify(e)===JSON.stringify(t);function So(e,t){let n=new Map,r=e=>e==null?null:(n.has(e)||n.set(e,`image-${n.size}`),n.get(e)),i=e=>({...Object.fromEntries(bo.filter(t=>e[t]!==void 0).map(t=>[t,e[t]])),image:r(e.image)});return{panelId:t,document:{schemaVersion:1,strip:e.strip.map(e=>({...i(e),...e.revert?{revert:{rows:(e.revert.rows||[]).map(i),repointed:(e.revert.repointed||[]).map(i)}}:{}}))}}}function Co(e,t,n){let r=e.strip.find(e=>e.panelId===t.panelId),i=r?.revert?.rows;I(r?.type===`canvas`&&Array.isArray(i)&&i.length,`PANEL_REVERT`,`This canvas has no panels to restore.`);let a=new Map((r.revert.repointed||[]).map(e=>[e.panelId,e])),o=e.strip.flatMap(e=>e===r?i:[e]),s=t.document.strip.flatMap(e=>e.panelId===t.panelId?e.revert.rows:[e]),c=new Set(o.map(e=>e.panelId));I(c.size===o.length&&n&&Object.keys(n).length===2&&n.schemaVersion===1&&Array.isArray(n.strip)&&n.strip.length===o.length,`PANEL_REVERT`,`The sandbox returned an invalid restoration.`);let l=Number(r.startMs)-Number(i[0].startMs),u=Math.min(...o.map(e=>Number(i.includes(e)?Number(e.startMs)+l:e.startMs)||0)),d=e.strip.flatMap(e=>[e,...e.revert?.rows||[]]);return o.map((e,t)=>{let r={...s[t]},l=i.includes(e)?null:a.get(e.panelId);l&&(r.sourcePanelId=l.sourcePanelId,r.needsRefresh=!!l.needsRefresh||(e.image??null)!==(l.image??null),l.sourcePanelId&&(r.kind=`edit`),r.needsRefresh||delete r.needsRefresh);let f=(r.kind===`edit`||r.type===`zoom`)&&r.sourcePanelId&&!c.has(r.sourcePanelId),p=r.kind===`repeat`&&r.repeatOf&&!c.has(r.repeatOf),m=r.kind===`revealStep`&&r.revealOf&&!c.has(r.revealOf);if(f||p||m){let e=o.slice(0,t).map(e=>(i.includes(e)?null:a.get(e.panelId))?.sourcePanelId?{...e,kind:`edit`}:e).reverse().find(e=>e.lineageId===r.lineageId&&e.sceneId===r.sceneId&&(e.type===`panel`||e.type===`zoom`)&&e.kind!==`repeat`),n=d.find(e=>e.kind===`base`&&e.lineageId===r.lineageId&&e.sceneId===r.sceneId&&String(e.prompt||``).trim()),s=n?n.prompt:String(r.prompt||``).replace(/^\\s*keep\\s+(everything\\s+)?identical\\s*;\\s*/i,``).trim()||`the scene`;f?(r.sourcePanelId=e?.panelId??null,r.needsRefresh=!0,e||(r.kind=`base`,r.prompt=s)):p?(r.repeatOf=e?.panelId??null,e||(r.kind=`base`,r.prompt=s,r.needsRefresh=!0)):(delete r.revealOf,delete r.revealIndex,r.kind=e?`edit`:`base`,r.sourcePanelId=e?.panelId??null,r.needsRefresh=!0,e||(r.prompt=s))}r.startMs=u;let h=n.strip[t];I(h&&Object.keys(h).length===Object.keys(r).filter(e=>r[e]!==void 0).length&&Object.keys(h).every(e=>xo(h[e],r[e])),`PANEL_REVERT`,`The sandbox changed fields outside this canvas restoration.`);let g={...e};for(let e of[`startMs`,`sourcePanelId`,`needsRefresh`,`kind`,`prompt`,`repeatOf`,`revealOf`,`revealIndex`])Object.hasOwn(h,e)?g[e]=h[e]:delete g[e];return u+=Math.max(1,Number(e.durationMs)||1),xo(e,g)?e:g})}function wo({doc:e,projectId:t,canEdit:n,onDocChange:r,validateDocument:i,editLease:a,host:o}){let s=H(o),c=()=>s.actor(),[l,u]=(0,v.useState)(null),[d,f]=(0,v.useState)(``),p=(0,v.useRef)(null),m=(0,v.useRef)(!0),h=(0,v.useRef)(0),g=(0,v.useRef)(null),_=c();g.current={doc:e,projectId:t,canEdit:n,onDocChange:r,validateDocument:i,actor:_,services:s};let y=(0,v.useCallback)(()=>{h.current++,a?.current===p.current&&(a.current=null),p.current?.abort(),p.current=null,u(null)},[a]);return(0,v.useEffect)(()=>(m.current=!0,()=>{m.current=!1,h.current++,a?.current===p.current&&(a.current=null),p.current?.abort(),p.current=null}),[]),(0,v.useEffect)(()=>{y()},[e,t,n,_,s,y]),{revert:(0,v.useCallback)(async(e,t)=>{let n=g.current;if(n.services!==s||!n.doc||!n.canEdit||p.current||a?.current)return;let r=++h.current,i=new AbortController;p.current=i,a&&(a.current=i),u(e),f(``);let o,l=()=>{let e=g.current;I(m.current&&p.current===i&&!i.signal.aborted&&e.doc===n.doc&&e.projectId===n.projectId&&e.canEdit&&e.services===n.services&&e.actor===n.actor&&c()===n.actor&&JSON.stringify(n.doc)===o,`STALE`,`The panels changed. Review the current canvas before reverting again.`)};try{if(o=JSON.stringify(n.doc),l(),t&&!await t())return;l();let a=So(n.doc,e);l();let u=await s.run(yo,{kind:`run`,input:a,signal:i.signal,timeoutMs:15e3});l();let d=n.validateDocument({...n.doc,strip:Co(n.doc,a,u.outputs?.edit)});return l(),n.onDocChange(e=>{let t=g.current;try{return I(m.current&&!i.signal.aborted&&h.current===r&&t.services===n.services&&t.actor===n.actor&&c()===n.actor&&t.projectId===n.projectId&&t.canEdit&&JSON.stringify(e)===o&&JSON.stringify(n.doc)===o,`STALE`,`The project changed before restoring the canvas panels.`),d}catch{return e}}),!0}catch(e){m.current&&!i.signal.aborted&&c()===n.actor&&g.current.projectId===n.projectId&&f(e.message||`The canvas could not be reverted.`)}finally{p.current===i&&(a?.current===i&&(a.current=null),p.current=null,m.current&&u(null))}},[s]),pending:l,error:d,cancel:y}}let To={manifest:{schemaVersion:1,sdkVersion:`0.1.0`,id:`stillmade-internal.panel-insert`,version:`1.0.0`,name:`Image Panels insertion`,description:`Insert a blank panel with lineage source resolution, reserved identity and contiguous timing.`,kind:`task`,runtime:`javascript`,inputs:{document:{type:`json`},afterId:{type:`text`}},outputs:{edit:{type:`json`}},permissions:{project:[],network:[],filesystem:[],secrets:[]}},code:`const PANEL_MIN_MS=350;\nfunction loadPanelDoc(doc){return doc;}\nfunction lineageSourceBefore(strip, lineageId, index) {\n for (let i = Math.min(index, strip.length) - 1; i >= 0; i--) {\n // repeats re-show an earlier frame and revealSteps are covered states of\n // their base — the chainable source is always the real generated panel\n if (strip[i].lineageId === lineageId && strip[i].kind !== 'repeat' && strip[i].kind !== 'revealStep') return strip[i];\n }\n return null;\n}\n\n\nfunction insertPanelAfter(doc, afterId, { kind = 'edit', prompt = '', lineageId = null, durationMs = 1200 } = {}) {\n const i = doc.strip.findIndex((p) => p.panelId === afterId);\n if (i < 0) return doc;\n const anchor = doc.strip[i];\n const lid = lineageId || anchor.lineageId;\n const id = nextPanelId(doc.strip);\n const source = kind === 'edit' ? (lineageSourceBefore([...doc.strip.slice(0, i + 1)], lid, i + 1)?.panelId ?? null) : null;\n const panel = {\n panelId: id, type: 'panel', sceneId: anchor.sceneId, lineageId: lid,\n kind: kind === 'edit' && source ? 'edit' : 'base',\n prompt: prompt || (kind === 'edit' ? 'keep everything identical; ' : ''),\n sourcePanelId: kind === 'edit' && source ? source : null,\n // Start at the anchor's end — retimeAfterReorder bases the strip on the\n // MINIMUM start, so a 0-start insert would rebase every panel off its VO\n // alignment (starts and word windows all shift earlier).\n image: null, startMs: anchor.startMs + anchor.durationMs, durationMs: Math.max(PANEL_MIN_MS, durationMs),\n transitionIn: 'cut', overlayLayer: null, provenance: 'user',\n method: null, methodGroup: null,\n };\n const strip = [...doc.strip.slice(0, i + 1), panel, ...doc.strip.slice(i + 1)];\n const lineages = doc.lineages[lid] ? doc.lineages : { ...doc.lineages, [lid]: { sheetIds: [], place: '' } };\n return loadPanelDoc({ ...doc, lineages, strip: retimeAfterReorder(strip) });\n}\n\n\nfunction reservedPanelIds(strip) {\n const ids = new Set();\n for (const p of (strip || [])) {\n ids.add(p.panelId);\n for (const r of (p.revert?.rows || [])) ids.add(r.panelId);\n }\n return ids;\n}\nfunction nextPanelId(strip) {\n const ids = reservedPanelIds(strip);\n let n = strip.length + 1;\n while (ids.has(\\`p\\${n}\\`)) n++;\n return \\`p\\${n}\\`;\n}\n\nfunction retimeAfterReorder(strip) {\n let t = strip.length ? Math.min(...strip.map((p) => Number(p.startMs) || 0)) : 0;\n return strip.map((p) => {\n const out = { ...p, startMs: t };\n t += Math.max(1, Number(p.durationMs) || 1);\n return out;\n });\n}\nconst next=insertPanelAfter(input.document,input.afterId,{});return {edit:{schemaVersion:1,strip:next.strip,lineages:next.lineages}};`,tests:[{name:`Continue the current lineage`,input:{document:{schemaVersion:1,strip:[{panelId:`a`,type:`panel`,kind:`base`,startMs:0,durationMs:1e3,sceneId:`s`,lineageId:`l`}],lineages:{l:{}}},afterId:`a`},expected:{edit:{schemaVersion:1,strip:[{panelId:`a`,type:`panel`,kind:`base`,startMs:0,durationMs:1e3,sceneId:`s`,lineageId:`l`},{panelId:`p2`,type:`panel`,sceneId:`s`,lineageId:`l`,kind:`edit`,prompt:`keep everything identical; `,sourcePanelId:`a`,image:null,startMs:1e3,durationMs:1200,transitionIn:`cut`,overlayLayer:null,provenance:`user`,method:null,methodGroup:null}],lineages:{l:{}}}}}]},Eo=[`panelId`,`type`,`kind`,`startMs`,`durationMs`,`sceneId`,`lineageId`],Do=(e,t)=>JSON.stringify(e)===JSON.stringify(t);function Oo(e,t){return{afterId:t,document:{schemaVersion:1,strip:e.strip.map(e=>({...Object.fromEntries(Eo.filter(t=>e[t]!==void 0).map(t=>[t,e[t]])),...e.revert?.rows?{revert:{rows:e.revert.rows.map(e=>({panelId:e.panelId}))}}:{}})),lineages:Object.fromEntries(Object.keys(e.lineages).map(e=>[e,{}]))}}}function ko(e,t,n){let r=e.strip.findIndex(e=>e.panelId===t.afterId),i=e.strip[r];I(i,`PANEL_INSERT`,`The insertion anchor is unavailable.`);let a=new Set(e.strip.flatMap(e=>[e.panelId,...(e.revert?.rows||[]).map(e=>e.panelId)])),o=e.strip.length+1;for(;a.has(`p${o}`);)o++;let s=e.strip.slice(0,r+1).reverse().find(e=>e.lineageId===i.lineageId&&e.kind!==`repeat`&&e.kind!==`revealStep`),c={panelId:`p${o}`,type:`panel`,sceneId:i.sceneId,lineageId:i.lineageId,kind:s?`edit`:`base`,prompt:`keep everything identical; `,sourcePanelId:s?.panelId??null,image:null,durationMs:1200,transitionIn:`cut`,overlayLayer:null,provenance:`user`,method:null,methodGroup:null};I(n&&Object.keys(n).length===3&&n.schemaVersion===1&&Array.isArray(n.strip)&&n.strip.length===e.strip.length+1,`PANEL_INSERT`,`The sandbox returned an invalid insertion.`);let l=n.strip[r+1],u=e=>Object.fromEntries(Object.entries(e).filter(([e])=>e!==`startMs`));I(l&&Do(u(l),c),`PANEL_INSERT`,`The sandbox changed the new panel contract.`);let d=Object.hasOwn(t.document.lineages,i.lineageId)?t.document.lineages:{...t.document.lineages,[i.lineageId]:{sheetIds:[],place:``}};I(Do(n.lineages,d),`PANEL_INSERT`,`The sandbox changed unrelated lineages.`);let f=Math.min(...e.strip.map(e=>Number(e.startMs)||0),Number(i.startMs+i.durationMs)||0),p=n.strip.map((n,i)=>{I(n.startMs===f,`PANEL_INSERT`,`The sandbox changed the strip timing origin or continuity.`);let a;if(i===r+1)a={...l};else{let o=i>r+1?i-1:i,s=e.strip[o];I(Do(u(n),u(t.document.strip[o])),`PANEL_INSERT`,`The sandbox changed an existing panel.`),a=s.startMs===n.startMs?s:{...s,startMs:n.startMs}}return f+=Math.max(1,Number(a.durationMs)||1),a});return{...e,strip:p,lineages:Object.hasOwn(e.lineages,i.lineageId)?e.lineages:{...e.lineages,[i.lineageId]:{sheetIds:[],place:``}}}}function Ao({doc:e,projectId:t,canEdit:n,onDocChange:r,validateDocument:i,editLease:a,host:o}){let s=H(o),c=()=>s.actor(),[l,u]=(0,v.useState)(null),[d,f]=(0,v.useState)(``),p=(0,v.useRef)(null),m=(0,v.useRef)(!0),h=(0,v.useRef)(0),g=(0,v.useRef)(null),_=c();g.current={doc:e,projectId:t,canEdit:n,onDocChange:r,validateDocument:i,actor:_,services:s};let y=(0,v.useCallback)(()=>{h.current++,a?.current===p.current&&(a.current=null),p.current?.abort(),p.current=null,u(null)},[a]);return(0,v.useEffect)(()=>(m.current=!0,()=>{m.current=!1,h.current++,a?.current===p.current&&(a.current=null),p.current?.abort(),p.current=null}),[]),(0,v.useEffect)(()=>{y()},[e,t,n,_,s,y]),{insert:(0,v.useCallback)(async e=>{let t=g.current;if(t.services!==s||!t.doc||!t.canEdit||p.current||a?.current)return;let n=++h.current,r=new AbortController;p.current=r,a&&(a.current=r),u(e),f(``);let i,o=()=>{let e=g.current;I(m.current&&p.current===r&&!r.signal.aborted&&e.doc===t.doc&&e.projectId===t.projectId&&e.canEdit&&e.services===t.services&&e.actor===t.actor&&c()===t.actor&&JSON.stringify(t.doc)===i,`STALE`,`The panels changed. Choose the current insertion point again.`)};try{i=JSON.stringify(t.doc);let a=Oo(t.doc,e);o();let l=await s.run(To,{kind:`run`,input:a,signal:r.signal,timeoutMs:15e3});o();let u=t.validateDocument(ko(t.doc,a,l.outputs?.edit));o(),t.onDocChange(e=>{let a=g.current;try{return I(m.current&&!r.signal.aborted&&h.current===n&&a.services===t.services&&a.actor===t.actor&&c()===t.actor&&a.projectId===t.projectId&&a.canEdit&&JSON.stringify(e)===i&&JSON.stringify(t.doc)===i,`STALE`,`The project changed before inserting the panel.`),u}catch{return e}})}catch(e){m.current&&!r.signal.aborted&&c()===t.actor&&g.current.projectId===t.projectId&&f(e.message||`The panel could not be inserted.`)}finally{p.current===r&&(a?.current===r&&(a.current=null),p.current=null,m.current&&u(null))}},[s]),pending:l,error:d,cancel:y}}let jo={manifest:{schemaVersion:1,sdkVersion:`0.1.0`,id:`stillmade-internal.panel-delete`,version:`1.0.0`,name:`Image Panels deletion`,description:`Remove a panel and repair dependent panels, overlays and timing.`,kind:`task`,runtime:`javascript`,inputs:{document:{type:`json`},panelId:{type:`text`}},outputs:{edit:{type:`json`}},permissions:{project:[],network:[],filesystem:[],secrets:[]}},code:`function loadPanelDoc(doc){return doc;}\nfunction baseFallbackPrompt(strip, panel) {\n const pool = [];\n for (const p of (strip || [])) {\n pool.push(p);\n for (const r of (p.revert?.rows || [])) pool.push(r);\n }\n const lineageBase = pool.find((p) => p.kind === 'base' && p.lineageId === panel.lineageId && p.sceneId === panel.sceneId && String(p.prompt || '').trim());\n if (lineageBase) return lineageBase.prompt;\n return String(panel.prompt || '').replace(/^\\\\s*keep\\\\s+(everything\\\\s+)?identical\\\\s*;\\\\s*/i, '').trim() || 'the scene';\n}\n\nfunction retimeAfterReorder(strip) {\n let t = strip.length ? Math.min(...strip.map((p) => Number(p.startMs) || 0)) : 0;\n return strip.map((p) => {\n const out = { ...p, startMs: t };\n t += Math.max(1, Number(p.durationMs) || 1);\n return out;\n });\n}\nfunction deletePanel(doc, panelId) {\n const idx = doc.strip.findIndex((p) => p.panelId === panelId);\n if (idx < 0) return doc;\n const victim = doc.strip[idx];\n // GIF-retention: an OVERLAY reaction GIF rides on its panel's overlayLayer.\n // Deleting that panel would silently lose the user's GIF, so relocate it onto\n // the nearest EARLIER generative panel in the same scene that has no overlay;\n // with no such neighbour it simply clears with the panel.\n const overlay = victim.overlayLayer && typeof victim.overlayLayer === 'object' ? victim.overlayLayer : null;\n let relocateTo = null;\n if (overlay) {\n for (let i = idx - 1; i >= 0; i--) {\n const c = doc.strip[i];\n if (c.type === 'panel' && c.sceneId === victim.sceneId && c.overlayLayer == null) { relocateTo = c.panelId; break; }\n }\n }\n // A repeat is a shadow of its target — deleting the target deletes its\n // repeats too (they'd have nothing to show). A zoom whose SOURCE was a\n // deleted plain BASE is likewise dropped (nothing left to push into);\n // zooms sourcing a deleted edit/zoom re-chain like edits do.\n const victimChains = victim.kind === 'edit' || victim.type === 'zoom';\n const dropped = new Set([panelId]);\n for (const p of doc.strip) {\n if (p.kind === 'repeat' && p.repeatOf === panelId) dropped.add(p.panelId);\n if (p.type === 'zoom' && p.sourcePanelId === panelId && !victimChains) dropped.add(p.panelId);\n }\n const survivors = doc.strip.filter((p) => !dropped.has(p.panelId));\n const canvasHeirId = victim.type === 'canvas'\n ? (survivors[Math.max(0, Math.min(idx - 1, survivors.length - 1))]?.panelId ?? null)\n : null;\n const strip = survivors\n .map((p) => {\n if (relocateTo && p.panelId === relocateTo) return { ...p, overlayLayer: overlay };\n // Deleting a ZOOM returns the screen time it carved to its source —\n // the beat plays exactly as it did before the zoom existed.\n if (victim.type === 'zoom' && p.panelId === victim.sourcePanelId) {\n return { ...p, durationMs: Number(p.durationMs) + Number(victim.durationMs) };\n }\n // Deleting a CANVAS returns its screen time to the previous beat (or the\n // next when it opened the strip) — total length and VO sync never move.\n if (victim.type === 'canvas' && p.panelId === canvasHeirId) {\n return { ...p, durationMs: Number(p.durationMs) + Number(victim.durationMs) };\n }\n if ((p.kind === 'edit' || p.type === 'zoom') && p.sourcePanelId != null && dropped.has(p.sourcePanelId)) {\n // re-chain past what was deleted: source what IT sourced (or become a\n // fresh base). Deleting a ZOOM this way REVERTS its downstream to the\n // pre-zoom frame — the progression continues un-zoomed.\n if (p.sourcePanelId === panelId && victimChains) {\n return { ...p, sourcePanelId: victim.sourcePanelId, needsRefresh: true };\n }\n // Sourced the victim base directly, or a zoom that fell with it.\n return p.type === 'zoom'\n ? p // unreachable for base victims (dropped above); zoom-on-zoom re-chains via the branch before\n : { ...p, kind: 'base', sourcePanelId: null, prompt: baseFallbackPrompt(doc.strip, p), needsRefresh: true };\n }\n return p;\n });\n if (!strip.length) throw new Error('deletePanel: a strip needs at least one panel');\n return loadPanelDoc({ ...doc, strip: retimeAfterReorder(strip) });\n}\n\n\nreturn {edit:{schemaVersion:1,strip:deletePanel(input.document,input.panelId).strip}};`,tests:[{name:`Keep survivor timing origin`,input:{document:{schemaVersion:1,strip:[{panelId:`a`,type:`panel`,kind:`base`,startMs:0,durationMs:100},{panelId:`b`,type:`panel`,kind:`base`,startMs:100,durationMs:100}]},panelId:`a`},expected:{edit:{schemaVersion:1,strip:[{panelId:`b`,type:`panel`,kind:`base`,startMs:100,durationMs:100}]}}}]},Mo=[`panelId`,`type`,`kind`,`startMs`,`durationMs`,`sceneId`,`lineageId`,`sourcePanelId`,`repeatOf`,`prompt`,`needsRefresh`];function No(e){let t=Object.fromEntries(Mo.filter(t=>e[t]!==void 0).map(t=>[t,e[t]]));return e.overlayLayer&&typeof e.overlayLayer==`object`?t.overlayLayer={fromPanel:e.panelId}:e.overlayLayer!==void 0&&(t.overlayLayer=e.overlayLayer),e.revert?.rows&&(t.revert={rows:e.revert.rows.map(e=>Object.fromEntries([`kind`,`lineageId`,`sceneId`,`prompt`].filter(t=>e[t]!==void 0).map(t=>[t,e[t]])))}),t}let Po=(e,t)=>JSON.stringify(e)===JSON.stringify(t);function Fo(e,t,n){let r=e.strip.find(e=>e.panelId===t);I(r,`PANEL_DELETE`,`The selected panel is no longer present.`);let i=r.kind===`edit`||r.type===`zoom`,a=new Set([t]);for(let n of e.strip)(n.kind===`repeat`&&n.repeatOf===t||n.type===`zoom`&&n.sourcePanelId===t&&!i)&&a.add(n.panelId);let o=e.strip.filter(e=>!a.has(e.panelId)),s=e.strip.indexOf(r),c=r.type===`canvas`?o[Math.max(0,Math.min(s-1,o.length-1))]?.panelId:null,l=null;if(r.overlayLayer&&typeof r.overlayLayer==`object`)for(let t=s-1;t>=0;t--){let n=e.strip[t];if(n.type===`panel`&&n.sceneId===r.sceneId&&n.overlayLayer==null){l=n.panelId;break}}I(n&&Object.keys(n).length===2&&n.schemaVersion===1&&Array.isArray(n.strip)&&o.length>0&&n.strip.length===o.length,`PANEL_DELETE`,`The sandbox returned an invalid panel deletion.`);let u=Math.min(...o.map(e=>Number(e.startMs)||0));return o.map((o,s)=>{let d=n.strip[s],f=No(o),p=[`startMs`];I(d?.panelId===o.panelId,`PANEL_DELETE`,`The sandbox changed an unrelated panel or its order.`),o.panelId===l?p.push(`overlayLayer`):r.type===`zoom`&&o.panelId===r.sourcePanelId||r.type===`canvas`&&o.panelId===c?p.push(`durationMs`):(o.kind===`edit`||o.type===`zoom`)&&o.sourcePanelId!=null&&a.has(o.sourcePanelId)&&(o.sourcePanelId===t&&i?p.push(`sourcePanelId`,`needsRefresh`):o.type!==`zoom`&&p.push(`kind`,`sourcePanelId`,`prompt`,`needsRefresh`));let m=e=>Object.fromEntries(Object.entries(e).filter(([e])=>!p.includes(e)));if(I(Po(m(f),m(d)),`PANEL_DELETE`,`The sandbox changed fields outside this deletion.`),I(d.startMs===u&&Number.isFinite(d.durationMs)&&d.durationMs>0,`PANEL_DELETE`,`The sandbox returned invalid panel timing.`),p.includes(`durationMs`)&&I(d.durationMs===Number(o.durationMs)+Number(r.durationMs),`PANEL_DELETE`,`Deleted screen time was not returned to its source.`),p.includes(`overlayLayer`)&&I(Po(d.overlayLayer,{fromPanel:t}),`PANEL_DELETE`,`The sandbox returned an unrelated overlay.`),p.includes(`needsRefresh`)){if(I(d.needsRefresh===!0,`PANEL_DELETE`,`Dependent panels must be marked for refresh.`),p.includes(`kind`)){let t=e.strip.flatMap(e=>[e,...e.revert?.rows||[]]).find(e=>e.kind===`base`&&e.lineageId===o.lineageId&&e.sceneId===o.sceneId&&String(e.prompt||``).trim()),n=t?t.prompt:String(o.prompt||``).replace(/^\\s*keep\\s+(everything\\s+)?identical\\s*;\\s*/i,``).trim()||`the scene`;I(d.kind===`base`&&d.sourcePanelId===null&&d.prompt===n,`PANEL_DELETE`,`The sandbox returned an unrelated source or prompt.`)}else I(d.sourcePanelId===r.sourcePanelId,`PANEL_DELETE`,`The sandbox changed the approved source chain.`)}let h={...o};for(let e of p)e===`overlayLayer`?h.overlayLayer=r.overlayLayer:Object.hasOwn(d,e)?h[e]=d[e]:delete h[e];return u+=Math.max(1,Number(h.durationMs)||1),Po(o,h)?o:h})}function Io({doc:e,projectId:t,canEdit:n,onDocChange:r,validateDocument:i,editLease:a,host:o}){let s=H(o),c=()=>s.actor(),[l,u]=(0,v.useState)(null),[d,f]=(0,v.useState)(``),p=(0,v.useRef)(null),m=(0,v.useRef)(!0),h=(0,v.useRef)(0),g=(0,v.useRef)(null),_=c();g.current={doc:e,projectId:t,canEdit:n,onDocChange:r,validateDocument:i,actor:_,services:s};let y=(0,v.useCallback)(()=>{h.current++,a?.current===p.current&&(a.current=null),p.current?.abort(),p.current=null,u(null)},[a]);return(0,v.useEffect)(()=>(m.current=!0,()=>{m.current=!1,h.current++,a?.current===p.current&&(a.current=null),p.current?.abort(),p.current=null}),[]),(0,v.useEffect)(()=>{y()},[e,t,n,_,s,y]),{remove:(0,v.useCallback)(async e=>{let t=g.current;if(t.services!==s||!t.doc||!t.canEdit||p.current||a?.current)return;let n=++h.current,r=new AbortController;p.current=r,a&&(a.current=r),u(e),f(``);let i,o=()=>{let e=g.current;I(m.current&&p.current===r&&!r.signal.aborted&&e.doc===t.doc&&e.projectId===t.projectId&&e.canEdit&&e.services===t.services&&e.actor===t.actor&&c()===t.actor&&JSON.stringify(t.doc)===i,`STALE`,`The panels changed. Review the current strip before deleting again.`)};try{i=JSON.stringify(t.doc);let a={document:{schemaVersion:1,strip:t.doc.strip.map(No)},panelId:e};o();let l=await s.run(jo,{kind:`run`,input:a,signal:r.signal,timeoutMs:15e3});o();let u=Fo(t.doc,e,l.outputs?.edit),d=t.validateDocument({...t.doc,strip:u});o(),t.onDocChange(e=>{let a=g.current;try{return I(m.current&&!r.signal.aborted&&h.current===n&&a.services===t.services&&a.actor===t.actor&&c()===t.actor&&a.projectId===t.projectId&&a.canEdit&&JSON.stringify(e)===i&&JSON.stringify(t.doc)===i,`STALE`,`The project changed before deleting the panel.`),d}catch{return e}})}catch(e){m.current&&!r.signal.aborted&&c()===t.actor&&g.current.projectId===t.projectId&&f(e.message||`The panel could not be deleted.`)}finally{p.current===r&&(a?.current===r&&(a.current=null),p.current=null,m.current&&u(null))}},[s]),pending:l,error:d,cancel:y}}let Lo={manifest:{schemaVersion:1,sdkVersion:`0.1.0`,id:`stillmade-internal.panel-narration`,version:`1.0.0`,name:`Image Panels narration edit`,description:`Retiming the edited transcript within the selected panel without changing recorded audio.`,kind:`task`,runtime:`javascript`,inputs:{edit:{type:`json`}},outputs:{splice:{type:`json`}},permissions:{project:[],network:[],filesystem:[],secrets:[]}},code:`const {panel,words,text}=input.edit;\nconst tokens=String(text||'').trim().split(/\\\\s+/).filter(Boolean);\nif(!tokens.length)throw new Error('narration text is empty');\nconst t0=panel.startMs,t1=panel.startMs+panel.durationMs;\nconst inWin=w=>{const mid=(w.startMs+w.endMs)/2;return mid>=t0&&mid<t1;};\nlet start=t0,end=t1,insertAt,removeCount=0;\nconst first=words.findIndex(inWin);\nif(first>=0){let last=first;while(last+1<words.length&&inWin(words[last+1]))last++;start=words[first].startMs;end=words[last].endMs;insertAt=first;removeCount=last-first+1;}\nelse{insertAt=words.findIndex(w=>(w.startMs+w.endMs)/2>=t1);if(insertAt<0)insertAt=words.length;}\nconst step=(end-start)/tokens.length;\nconst fresh=tokens.map((tok,i)=>({text:tok,startMs:Math.round(start+i*step),endMs:Math.round(start+(i+1)*step)}));\nreturn {splice:{schemaVersion:1,insertAt,removeCount,words:fresh}};`,tests:[{name:`Retain original narration span`,input:{edit:{schemaVersion:1,panel:{startMs:0,durationMs:100},words:[{text:`before`,startMs:0,endMs:100}],text:`two words`}},expected:{splice:{schemaVersion:1,insertAt:0,removeCount:1,words:[{text:`two`,startMs:0,endMs:50},{text:`words`,startMs:50,endMs:100}]}}}]};function Ro(e,t){let{panel:n,words:r,text:i}=e,a=e=>{let t=(e.startMs+e.endMs)/2;return t>=n.startMs&&t<n.startMs+n.durationMs},o=r.findIndex(a),s=o;if(o<0)o=r.findIndex(e=>(e.startMs+e.endMs)/2>=n.startMs+n.durationMs),o<0&&(o=r.length),s=o;else for(s=o+1;s<r.length&&a(r[s]);)s++;let c=s>o?r[o].startMs:n.startMs,l=s>o?r[s-1].endMs:n.startMs+n.durationMs,u=String(i||``).trim().split(/\\s+/).filter(Boolean);return I(t&&Object.keys(t).length===4&&t.schemaVersion===1&&t.insertAt===o&&t.removeCount===s-o&&Array.isArray(t.words)&&t.words.length===u.length,`PANEL_NARRATION`,`The sandbox returned an invalid narration edit.`),I(t.words.every((e,n)=>e&&Object.keys(e).length===3&&e.text===u[n]&&Number.isSafeInteger(e.startMs)&&Number.isSafeInteger(e.endMs)&&e.startMs>=Math.round(c)&&e.endMs<=Math.round(l)&&e.endMs>=e.startMs&&(n===0?e.startMs===Math.round(c):e.startMs===t.words[n-1].endMs))&&t.words.at(-1)?.endMs===Math.round(l),`PANEL_NARRATION`,`The sandbox narration edit changed its allowed time span.`),t}function zo({doc:e,projectId:t,canEdit:n,onDocChange:r,validateDocument:i,editLease:a,host:o}){let s=H(o),c=()=>s.actor(),[l,u]=(0,v.useState)(null),[d,f]=(0,v.useState)(``),p=(0,v.useRef)(null),m=(0,v.useRef)(!0),h=(0,v.useRef)(0),g=(0,v.useRef)(null),_=c();g.current={doc:e,projectId:t,canEdit:n,onDocChange:r,validateDocument:i,actor:_,services:s};let y=(0,v.useCallback)(()=>{h.current++,a?.current===p.current&&(a.current=null),p.current?.abort(),p.current=null,u(null)},[a]);return(0,v.useEffect)(()=>(m.current=!0,()=>{m.current=!1,h.current++,a?.current===p.current&&(a.current=null),p.current?.abort(),p.current=null}),[]),(0,v.useEffect)(()=>{y()},[e,t,n,_,s,y]),{edit:(0,v.useCallback)(async(e,t)=>{let n=g.current;if(n.services!==s||!n.canEdit||!n.doc||p.current||a?.current)return;let r=++h.current,i=new AbortController;p.current=i,a&&(a.current=i),u(e),f(``);let o,l=()=>{let e=g.current;I(m.current&&!i.signal.aborted&&p.current===i&&e.doc===n.doc&&e.projectId===n.projectId&&e.canEdit&&e.services===n.services&&e.actor===n.actor&&c()===n.actor&&JSON.stringify(n.doc)===o,`STALE`,`The panels changed. Review the current narration before editing again.`)};try{o=JSON.stringify(n.doc);let a=n.doc.strip.find(t=>t.panelId===e);I(a,`PANEL_NARRATION`,`This panel is unavailable.`);let u={schemaVersion:1,panel:{startMs:a.startMs,durationMs:a.durationMs},words:(n.doc.audio?.words||[]).map(e=>({text:e.text,startMs:e.startMs,endMs:e.endMs})),text:t};l();let d=await s.run(Lo,{kind:`run`,input:{edit:u},signal:i.signal,timeoutMs:15e3});l();let f=Ro(u,d.outputs?.splice),p=n.doc.audio?.words||[],_=n.validateDocument({...n.doc,audio:{...n.doc.audio,words:[...p.slice(0,f.insertAt),...f.words,...p.slice(f.insertAt+f.removeCount)]}});l(),n.onDocChange(e=>{let t=g.current;try{return I(m.current&&!i.signal.aborted&&h.current===r&&t.services===n.services&&t.actor===n.actor&&c()===n.actor&&t.projectId===n.projectId&&t.canEdit&&JSON.stringify(e)===o&&JSON.stringify(n.doc)===o,`STALE`,`The project changed before saving narration.`),_}catch{return e}})}catch(e){m.current&&c()===n.actor&&g.current.projectId===n.projectId&&!i.signal.aborted&&f(e.message||`Narration could not be updated.`)}finally{p.current===i&&(a?.current===i&&(a.current=null),p.current=null,m.current&&u(null))}},[s]),pending:l,error:d,cancel:y}}function Bo(e){return I(e?.version===1&&typeof e.useLiveEditor==`function`&&typeof e.LiveEditorBadge==`function`&&typeof e.useIsMobileUI==`function`&&typeof e.cacheStripGifs==`function`&&typeof e.pendingGifCacheCount==`function`&&[`alert`,`confirm`,`prompt`,`choose`].every(t=>typeof e.ui?.[t]==`function`)&&[`success`,`error`,`info`].every(t=>typeof e.toast?.[t]==`function`),`HOST_SERVICES`,`Image Panels requires its declared version 1 native runtime host.`),e}let Vo=null;function Ho(e){return Vo=Bo(e),Vo}let Uo=()=>{if(!Vo)throw Error(`Image Panels runtime host is unavailable.`);return Vo},Wo=(...e)=>Uo().useLiveEditor(...e),Go=e=>Uo().LiveEditorBadge(e),Ko=()=>Uo().useIsMobileUI(),qo=(...e)=>Uo().cacheStripGifs(...e),Jo=(...e)=>Uo().pendingGifCacheCount(...e),Yo=Object.freeze(Object.fromEntries([`alert`,`confirm`,`prompt`,`choose`].map(e=>[e,(...t)=>Uo().ui[e](...t)]))),X=Object.freeze(Object.fromEntries([`success`,`error`,`info`,`warn`].map(e=>[e,(...t)=>Uo().toast[e]?.(...t)])));function Xo({rootMargin:e}){let t=(0,v.useRef)(null),[n,r]=(0,v.useState)(typeof IntersectionObserver>`u`);return(0,v.useEffect)(()=>{if(typeof IntersectionObserver>`u`){r(!0);return}let n=new IntersectionObserver(e=>r(e.some(e=>e.isIntersecting)),{rootMargin:e});return t.current&&n.observe(t.current),()=>n.disconnect()},[e]),[t,n]}function Zo({children:e,estimateHeight:t=220,rootMargin:n=`900px`,style:r}){let[i,a]=Xo({rootMargin:n}),o=(0,v.useRef)(null),[s,c]=(0,v.useState)(0);return(0,v.useLayoutEffect)(()=>{if(a&&o.current){let e=o.current.offsetHeight;e>0&&Math.abs(e-s)>2&&c(e)}}),(0,D.jsx)(`div`,{ref:i,style:a?r:{...r,height:s||t},children:a?(0,D.jsx)(`div`,{ref:o,children:e()}):null})}var Qo=g();function $o(e){let t=e.props.children;return typeof t==`string`||typeof t==`number`?String(t):v.Children.toArray(t).filter(e=>typeof e==`string`||typeof e==`number`).join(``)}function es(e){let t=[];return v.Children.forEach(e,e=>{e&&typeof e==`object`&&(e.type===`optgroup`?v.Children.forEach(e.props.children,n=>{n&&n.type===`option`&&t.push({value:n.props.value??$o(n),label:$o(n),disabled:!!n.props.disabled,group:e.props.label})}):e.type===`option`&&t.push({value:e.props.value??$o(e),label:$o(e),disabled:!!e.props.disabled}))}),t}function ts(e,t,n){let r=t;for(let t=0;t<e.length;t++)if(r+=n,r<0&&(r=e.length-1),r>=e.length&&(r=0),!e[r]?.disabled)return r;return t}function ns({value:e,defaultValue:t,onChange:n,disabled:r=!1,style:i,className:a=``,title:o,children:s,options:c,\"aria-label\":l,...u}){let d=(0,v.useMemo)(()=>c||es(s),[c,s]),f=e!==void 0,[p,m]=(0,v.useState)(t??d[0]?.value),h=f?e:p,g=d.findIndex(e=>String(e.value)===String(h)),_=d[g],[y,b]=(0,v.useState)(!1),[x,S]=(0,v.useState)(-1),[C,w]=(0,v.useState)(null),[T,E]=(0,v.useState)(null),O=(0,v.useRef)(null),k=(0,v.useRef)(null),A=(0,v.useRef)({str:``,t:0}),j=(0,v.useCallback)(e=>{f||m(e),n?.({target:{value:e}}),b(!1),O.current?.focus()},[f,n]),M=(0,v.useCallback)(()=>{if(r)return;let e=O.current?.getBoundingClientRect();e&&w({left:e.left,top:e.bottom,width:e.width,topY:e.top,bottomSpace:window.innerHeight-e.bottom}),S(g>=0?g:ts(d,-1,1)),b(!0)},[r,g,d]);(0,v.useEffect)(()=>{if(!y)return;let e=e=>{!k.current?.contains(e.target)&&!O.current?.contains(e.target)&&b(!1)};document.addEventListener(`mousedown`,e,!0);let t,n=null,r=()=>{let e=O.current?.getBoundingClientRect();if(!e){b(!1);return}if(e.bottom<0||e.top>window.innerHeight||e.right<0||e.left>window.innerWidth){b(!1);return}(!n||n.left!==e.left||n.top!==e.bottom||n.width!==e.width||n.topY!==e.top)&&(n={left:e.left,top:e.bottom,width:e.width,topY:e.top,bottomSpace:window.innerHeight-e.bottom},w(n)),t=requestAnimationFrame(r)};return t=requestAnimationFrame(r),()=>{document.removeEventListener(`mousedown`,e,!0),cancelAnimationFrame(t)}},[y]),(0,v.useEffect)(()=>{y&&k.current&&k.current.querySelector(`[data-i=\"${x}\"]`)?.scrollIntoView({block:`nearest`})},[y,x]),(0,v.useEffect)(()=>{y||E(null)},[y]);let ee=(0,v.useCallback)(e=>{if(!r){if(!y){[`ArrowDown`,`ArrowUp`,`Enter`,` `].includes(e.key)&&(e.preventDefault(),M());return}if(e.key===`Escape`)e.preventDefault(),b(!1),O.current?.focus();else if(e.key===`ArrowDown`)e.preventDefault(),S(e=>ts(d,e,1));else if(e.key===`ArrowUp`)e.preventDefault(),S(e=>ts(d,e,-1));else if(e.key===`Home`)e.preventDefault(),S(ts(d,-1,1));else if(e.key===`End`)e.preventDefault(),S(ts(d,d.length,-1));else if(e.key===`Enter`||e.key===` `)e.preventDefault(),d[x]&&!d[x].disabled&&j(d[x].value);else if(e.key===`Tab`)b(!1);else if(e.key.length===1){let t=Date.now(),n=t-A.current.t<700?A.current.str+e.key:e.key;A.current={str:n,t};let r=d.findIndex(e=>e.label.toLowerCase().startsWith(n.toLowerCase()));r>=0&&S(r)}}},[y,r,d,x,j,M]),N=C&&C.bottomSpace<260&&C.topY>C.bottomSpace;return(0,D.jsxs)(D.Fragment,{children:[(0,D.jsxs)(`button`,{ref:O,type:`button`,disabled:r,title:o,\"aria-label\":l,\"aria-haspopup\":`listbox`,\"aria-expanded\":y,className:`tsel-trigger ${a}`,style:i,onClick:()=>y?b(!1):M(),onKeyDown:ee,...u,children:[(0,D.jsx)(`span`,{className:`tsel-label`,children:_?_.label:``}),(0,D.jsx)(`span`,{className:`tsel-caret`,\"aria-hidden\":!0,children:`▾`})]}),y&&C&&(0,Qo.createPortal)((0,D.jsx)(`div`,{ref:k,role:`listbox`,className:`tsel-pop`,style:{position:`fixed`,left:C.left,minWidth:C.width,maxWidth:Math.max(C.width,320),...N?{bottom:window.innerHeight-C.topY+4}:{top:C.top+4}},children:d.map((e,t)=>(0,D.jsxs)(`div`,{role:`option`,\"data-i\":t,\"aria-selected\":t===g,\"aria-disabled\":e.disabled||void 0,\"data-active\":t===x,className:`tsel-opt`,onMouseEnter:()=>S(t),onMouseDown:t=>{t.preventDefault(),e.disabled||j(e.value)},children:[(0,D.jsx)(`span`,{className:`tsel-check`,\"aria-hidden\":!0,children:t===g?`✓`:``}),(0,D.jsx)(`span`,{className:`tsel-opt-label`,children:e.label}),e.note&&(0,D.jsx)(`span`,{className:`tsel-note`,tabIndex:-1,title:e.note,\"aria-label\":e.note,onMouseDown:e=>{e.preventDefault(),e.stopPropagation()},onMouseEnter:t=>{let n=t.currentTarget.getBoundingClientRect();E({text:e.note,x:n.right+8,y:n.top+n.height/2})},onMouseLeave:()=>E(null),children:`ⓘ`})]},t))}),document.body),T&&(0,Qo.createPortal)((0,D.jsx)(`div`,{className:`tsel-tip`,style:{position:`fixed`,left:T.x,top:T.y,transform:`translateY(-50%)`},children:T.text}),document.body)]})}function rs(e){return I(e?.version===1&&typeof e.apply==`function`,`HOST_SERVICES`,`Presenter placement requires its version 1 sandbox broker.`),e}let is=()=>Object.assign(Error(`Presenter setup was cancelled or its project changed.`),{name:`AbortError`});function as(e,t,n){let r=(0,v.useRef)(null),i=(0,v.useRef)(0),a=(0,v.useRef)(!0),o=(0,v.useRef)(null),s=(0,v.useRef)(n);s.current=n;let c=e.currentActor?.()??null;o.current={...t,actor:c};let l=()=>{let e=r.current;e&&(e.cancelled=!0,e.controller.abort(),r.current=null,s.current?.())};return(0,v.useEffect)(()=>{r.current&&!r.current.scopeCurrent()&&l()}),(0,v.useEffect)(()=>(a.current=!0,()=>{a.current=!1,i.current++,r.current&&=(r.current.cancelled=!0,r.current.controller.abort(),null)}),[]),{begin:()=>{if(r.current)return null;let t=o.current;if(t.canEdit===!1||e.currentActor&&(!t.actor||e.currentActor()!==t.actor))throw is();let n;try{n=JSON.stringify(t.doc)}catch{throw is()}let c=++i.current,l={cancelled:!1,controller:new AbortController};return l.signal=l.controller.signal,l.scopeCurrent=()=>{let n=o.current;return!(!a.current||l.cancelled||r.current!==l||!n||n.canEdit===!1||Object.keys(t).some(e=>n[e]!==t[e])||e.currentActor&&e.currentActor()!==t.actor)},l.current=()=>{if(!l.scopeCurrent())return!1;try{return JSON.stringify(o.current.doc)===n}catch{return!1}},l.admission=()=>(l.check(),r=>{let s=o.current;if(!a.current||i.current!==c||l.cancelled||!s||s.canEdit===!1||[`actor`,`projectId`,`doc`,`panelId`].some(e=>s[e]!==t[e])||e.currentActor&&e.currentActor()!==t.actor||JSON.stringify(r===void 0?s.doc:r)!==n)throw is()}),l.check=()=>{if(!l.current())throw is()},l.finish=()=>{r.current===l&&(r.current=null,s.current?.())},r.current=l,l},cancel:l,current:()=>r.current}}function os(e){return I((e?.version===1||e?.version===2&&typeof e.currentActor==`function`)&&[`planPresenterPoses`,`generateImage`,`getDefaultImageModel`,`getDefaultImageQuality`,`getDefaultImageResolution`,`browserSliceDeps`,`addLibraryItem`,`getLibraryItems`,`imageCost`,`getModelCapabilities`,`loadPanelDoc`,`addCanvasElement`,`removeCanvasElement`].every(t=>typeof e[t]==`function`)&&Array.isArray(e.QUALITY_OPTIONS)&&typeof e.ui?.alert==`function`&&[`error`,`success`].every(t=>typeof e.toast?.[t]==`function`),`HOST_SERVICES`,`Presenter requires supported host services.`),e}function ss(e){return I([`loadPanelDoc`,`addCanvasElement`,`removeCanvasElement`].every(t=>typeof e?.[t]==`function`),`HOST_SERVICES`,`Presenter requires document model operations.`),e}let cs=[`point-left`,`point-right`,`point-up`,`point-down`,`present`,`explain`,`think`,`surprised`,`wave`,`idle`,`count`,`shrug`,`celebrate`,`write`,`thumbs-up`,`welcome`];function ls(e){return String(e||``).replace(/-/g,` `).trim()}function us(e){return String(e||``).toLowerCase().replace(/[^a-z0-9]+/g,`-`).replace(/^-+|-+$/g,``).slice(0,40)}function ds(e){let{addCanvasElement:t,removeCanvasElement:n}=ss(e);function r(e){let t=String(e||``);return/(^|-)right/.test(t)?{x:.2,y:.64}:(/(^|-)left/.test(t),{x:.8,y:.64})}function i(e,{size:t=.3,pos:n=null}={}){let i=us(e?.label);return{kind:`image`,src:e?.url||null,source:`pose`,pose:i,cutout:!0,entrance:`pop`,pinned:!0,appearMs:0,leaveMs:null,pos:n||r(i),size:t,query:i}}let a={size:.52,pos:{x:.5,y:.62}};function o({poses:e=[],plan:t={},boards:n=[],size:r=.3}={}){let o=Array.isArray(e)?e.filter(e=>e&&e.url):[];if(!o.length)return[];let s=new Map(o.map(e=>[us(e.label),e])),c=Array.isArray(t?.poses)?t.poses:[],l=[],u=0;return(Array.isArray(n)?n:[]).forEach(e=>{if(!e?.panelId)return;let t=null;for(let n of c){if(n?.atWord==null||e.wordStart==null)continue;let r=e.wordEnd==null?1/0:e.wordEnd;if(n.atWord>=e.wordStart&&n.atWord<=r&&s.has(us(n.label))){t=s.get(us(n.label));break}}t||(t=o[u%o.length],u++),l.push({panelId:e.panelId,element:i(t,e.solo?a:{size:r})})}),l}function s(e,n=[]){let r=e;for(let{panelId:e,element:i}of n||[])e&&i&&(r=t(r,e,i));return r}function c(e,t){let n=0;for(let r=0;r<(e?.length||0);r++){let i=e[r],a=Number.isFinite(Number(i?.startMs))?Number(i.startMs):Number.isFinite(Number(i?.start))?Number(i.start)*1e3:null;if(a!=null){if(a<=t)n=r;else break}}return n}function l(e,t=[],n=[]){let r=u(e),i=(r.strip||[]).filter(e=>e.type===`canvas`).map(e=>({panelId:e.panelId,wordStart:e.wordStart==null?c(n,e.startMs||0):e.wordStart,wordEnd:e.wordEnd==null?c(n,(e.startMs||0)+(e.durationMs||0)):e.wordEnd,solo:!(e.elements||[]).length}));return s(r,o({poses:t,plan:{poses:t.map(e=>({label:e.label,atWord:e.atWord})).filter(e=>e.atWord!=null)},boards:i}))}function u(e){if(!e?.strip)return e;let t=e;for(let r of e.strip)if(r?.type===`canvas`&&Array.isArray(r.elements))for(let e of r.elements)e?.source===`pose`&&(t=n(t,r.panelId,e.id));return t}return{poseSpot:r,poseElement:i,SOLO_POSE:a,planPresenterPlacement:o,applyPresenterPlacement:s,placePosesOnDoc:l,clearPresenterPoses:u}}function fs(e=8,{cols:t=4,margin:n=.06}={}){let r=Math.max(1,Math.round(e)),i=Math.max(1,Math.min(t,r)),a=Math.ceil(r/i),o=[];for(let e=0;e<r;e++){let t=e%i,r=Math.floor(e/i),s=1/i,c=1/a,l=s*n,u=c*n;o.push({index:e,col:t,row:r,bbox:{x:t*s+l,y:r*c+u,w:s-2*l,h:c-2*u}})}return{cols:i,rows:a,count:r,cells:o}}function ps(e,t=8){let n=Array.isArray(e)?e:[],r=[];for(let e=0;e<n.length;e+=t)r.push(n.slice(e,e+t));return r}function ms({characterDef:e=``,style:t=``,poses:n=[],sheetIndex:r=0,cols:i=4}={}){let a=(Array.isArray(n)?n:[]).slice(0,8),o=Math.max(1,Math.ceil(a.length/i)),s=a.map((e,t)=>` - Cell (row ${Math.floor(t/i)+1}, col ${t%i+1}): the presenter ${e.description||ls(e.label)}.`).join(`\n`),c=t?`\\nArt style (identical across every pose): ${t}`:``;return`A single 16:9 reference SHEET of ONE 2D presenter/host character in ${a.length} different poses, arranged in a clean ${i}-column x ${o}-row grid.\n\nTHE CHARACTER (identical in every cell — same face, hair, body, clothing, colors): ${e}${c}\n\nEach pose is a full-body standing presenter doing one clear gesture:\n${s}\n\nSTRICT LAYOUT: the ${a.length} poses are CLEARLY SEPARATED with generous empty space between them — none overlapping, none touching, each fully inside its own grid cell. Plain solid pure-white (#FFFFFF) background behind everything, flat even lighting, no shadows on the background, no scenery, no props except what a gesture requires. NO text, captions, labels or numbers anywhere — each cell is a clean cutout of just the character. Consistent line weight and coloring across all poses. Sheet ${r+1}.`}function hs({characterDef:e=``,style:t=``,poses:n=[]}={}){return ps(n).map((n,r)=>({sheetIndex:r,poses:n,prompt:ms({characterDef:e,style:t,poses:n,sheetIndex:r})}))}async function gs({sheetUrl:e,poses:t=[],layout:n}={},r={}){let{cropCell:i,processPose:a,upload:o}=r;if(typeof i!=`function`||typeof a!=`function`||typeof o!=`function`)throw Error(`slicePoseSheet: cropCell, processPose and upload deps are required`);let s=n||fs(t.length),c=[];for(let n=0;n<t.length&&n<s.cells.length;n++){let r=t[n],{rasterDataUrl:l,svg:u,w:d,h:f}=await a(await i(e,s.cells[n].bbox)),p=await o(l,`png`),m=await o(u,`svg`);c.push({label:us(r.label),description:r.description||``,url:p,vectorUrl:m,w:d||0,h:f||0})}return c}function _s({name:e,definition:t=``,style:n=``,poses:r=[]}={}){let i=vs(r);return{name:e||`Host`,kind:`presenter`,isHost:!0,description:t,style:n,poses:i,images:i.map(e=>({url:e.url,vectorUrl:e.vectorUrl,label:e.label,source:`pose`})),selectedImageUrl:i[0]?.url||null}}function vs(e=[]){let t=new Set,n=[];for(let r of e||[]){let e=us(r?.label);e&&!t.has(e)&&(t.add(e),n.push({...r,label:e}))}return n}function ys(e){let t=Array.isArray(e?.poses)?e.poses:Array.isArray(e)?e:[];return[...new Set(t.map(e=>us(e?.label)).filter(Boolean))]}function bs(e){let t=Array.isArray(e?.poses)?e.poses:Array.isArray(e?.images)?e.images:[];return new Set(t.map(e=>us(e?.label)).filter(Boolean))}function xs(e,t){let n=bs(e);return(Array.isArray(t)?t:ys(t)).filter(e=>!n.has(us(e)))}function Ss(e,t=[]){let n=vs([...e?.poses||[],...t]);return{...e,poses:n,images:n.map(e=>({url:e.url,vectorUrl:e.vectorUrl,label:e.label,source:`pose`})),selectedImageUrl:e?.selectedImageUrl||n[0]?.url||null}}function Cs(e,t=16){let n=vs(e).map(e=>({label:e.label,description:e.description||ls(e.label),atWord:e.atWord??null})),r=new Set(n.map(e=>e.label));for(let e of cs){if(n.length>=t)break;r.has(e)||(r.add(e),n.push({label:e,description:`presenter ${ls(e)}`,atWord:null}))}return n.slice(0,Math.max(t,n.length))}async function ws({sheets:e,style:t},n){let{generateSheet:r,sliceDeps:i,onProgress:a}=n,o=[];for(let t=0;t<e.length;t++){a?.({phase:`generate`,done:t,total:e.length});let n=t>0&&o[0]?[o[0]]:[];o.push(await r(e[t].prompt,{referenceImages:n,aspectRatio:`16:9`}))}let s=[];for(let t=0;t<e.length;t++){a?.({phase:`slice`,done:t,total:e.length});let n=await gs({sheetUrl:o[t],poses:e[t].poses},i);s.push(...n)}return s}async function Ts({content:e=``,words:t=[],name:n=``,style:r=``,definition:i=``}={},a={}){let{planPoses:o,saveCharacter:s,onProgress:c}=a;c?.({phase:`plan`});let l=await o({content:e,words:t}),u=Cs(l?.poses||[]),d=i||l?.character?.definition||``,f=await ws({sheets:hs({characterDef:d,style:r,poses:u}),style:r},a),p=new Map(u.map(e=>[e.label,e.atWord??null]));for(let e of f)p.has(e.label)&&(e.atWord=p.get(e.label));let m=_s({name:n||l?.character?.name||`Host`,definition:d,style:r,poses:f});return c?.({phase:`save`}),(s?await s(m):m)||m}async function Es({character:e,content:t=``,words:n=[]}={},r={}){let{planPoses:i,saveCharacter:a,onProgress:o}=r;o?.({phase:`plan`});let s=await i({content:t,words:n}),c=xs(e,ys(s));if(!c.length)return{character:e,generated:[],ready:!0};let l=new Map((s?.poses||[]).map(e=>[us(e.label),e])),u=c.map(e=>{let t=l.get(e);return{label:e,description:t?.description||``,atWord:t?.atWord??null}}),d=await ws({sheets:hs({characterDef:e?.description||``,style:e?.style||``,poses:u}),style:e?.style||``},r),f=new Map(u.map(e=>[e.label,e.atWord??null]));for(let e of d)f.has(e.label)&&(e.atWord=f.get(e.label));let p=Ss(e,d);return o?.({phase:`save`}),{character:(a?await a(p):p)||p,generated:d,ready:!0}}function Ds(e,{onProgress:t,model:n,quality:r,resolution:i,assertCurrent:a}={}){let{planPresenterPoses:o,generateImage:s,getDefaultImageModel:c,getDefaultImageQuality:l,getDefaultImageResolution:u,browserSliceDeps:d,addLibraryItem:f}=os(e),p=e.currentActor?.(),m=()=>{if(a?.(),e.currentActor&&(!p||e.currentActor()!==p))throw Object.assign(Error(`Presenter account changed.`),{name:`AbortError`})},h=async(e,...t)=>{m();let n=await e(...t);return m(),n};m();let g=n||c(),_=r||l(),v=i||u();return{planPoses:({content:e,words:t})=>h(o,{content:e,words:t}),generateSheet:async(e,t)=>{let n=n=>h(s,{model:n,readablePrompt:e,aspectRatio:`16:9`,quality:_,resolution:v,referenceImages:t?.referenceImages||[]},{assertCurrent:m});try{return(await n(g))?.url||null}catch(e){if(m(),e?.name===`AbortError`||e?.code===`CANCELLED`||g===`gpt-image-2`)throw e;return(await n(`gpt-image-2`))?.url||null}},sliceDeps:Object.fromEntries(Object.entries(d({assertCurrent:m})).map(([e,t])=>[e,typeof t==`function`?(...e)=>h(t,...e):t])),saveCharacter:e=>h(f,`character`,e),onProgress:e=>{m(),t?.(e),m()}}}let Os={wrap:{border:`1px solid var(--border)`,borderRadius:10,padding:`10px 12px`,background:`var(--bg-secondary)`,fontFamily:`var(--font)`},row:{display:`flex`,alignItems:`center`,gap:8},title:{fontSize:12.5,fontWeight:700,color:`var(--text-primary)`},beta:{fontSize:9,fontWeight:800,letterSpacing:`0.06em`,padding:`1px 6px`,borderRadius:999,background:`var(--accent)`,color:`var(--accent-contrast, #0A0A0A)`},sub:{fontSize:11,color:`var(--text-secondary)`,marginTop:4,lineHeight:1.4},switch:e=>({position:`relative`,width:34,height:18,flexShrink:0,borderRadius:999,background:e?`var(--accent)`:`var(--bg-elevated)`,border:`1px solid ${e?`var(--accent)`:`var(--border)`}`,cursor:`pointer`,padding:0,marginLeft:`auto`}),knob:e=>({position:`absolute`,top:1,left:1,width:14,height:14,borderRadius:`50%`,background:e?`var(--bg-primary, #fff)`:`var(--text-muted)`,transform:e?`translateX(16px)`:`none`,transition:`transform 0.15s`}),btn:{fontSize:11.5,padding:`5px 10px`,borderRadius:7,border:`1px solid var(--border)`,background:`var(--bg-elevated)`,color:`var(--text-primary)`,cursor:`pointer`},pickItem:{display:`flex`,alignItems:`center`,gap:8,padding:`5px 6px`,borderRadius:6,cursor:`pointer`,border:`1px solid transparent`},thumb:{width:26,height:26,borderRadius:5,objectFit:`cover`,background:`var(--bg-elevated)`,flexShrink:0}},ks=Object.freeze([]);function As({hostServices:e,externalBusy:t=!1,projectId:n,doc:r,panelId:i,canEdit:a=!0,enabled:o=!1,onToggle:s,activeHost:c=null,content:l=``,words:u=ks,onHostReady:d}){let{getLibraryItems:f,ui:p}=os(e),[m,h]=(0,v.useState)(null),[g,_]=(0,v.useState)(!1),[y,b]=(0,v.useState)(``),[x,S]=(0,v.useState)(``),[C,w]=(0,v.useState)(``),T=as(e,{projectId:n,doc:r,panelId:i,canEdit:a,content:l,words:u,enabled:o,activeHostId:c?.id,defName:y,defStyle:x,defDesc:C},()=>h(null)),E=async n=>{if(t)return;let r;try{r=T.begin()}catch{return}if(r){_(!1),h({phase:`plan`});try{let t=await n(Ds(e,{assertCurrent:r.check,onProgress:e=>{r.check(),h(e)}}));r.check(),await d?.(t,{assertCurrent:r.admission(),signal:r.signal,assertPending:r.check})}catch(e){r.current()&&e?.name!==`AbortError`&&p.alert(`Couldn't set up the host: ${e?.message||e}`)}finally{r.finish()}}},O=()=>E(e=>Ts({content:l,words:u,name:y.trim()||void 0,style:x.trim()||void 0,definition:C.trim()||void 0},e)),k=e=>E(async t=>(await Es({character:e,content:l,words:u},t)).character),A=()=>E(async e=>(await Es({character:c,content:l,words:u},e)).character),j=f(`character`)||[],M=m?m.phase===`plan`?`Planning poses…`:m.phase===`generate`?`Generating pose sheet ${(m.done??0)+1}/${m.total||1}…`:m.phase===`slice`?`Cutting out poses ${(m.done??0)+1}/${m.total||1}…`:`Saving host…`:null;return(0,D.jsxs)(`div`,{style:Os.wrap,children:[(0,D.jsxs)(`div`,{style:Os.row,children:[(0,D.jsx)(`span`,{style:Os.title,children:`Presenter / Host`}),(0,D.jsx)(`span`,{style:Os.beta,children:`BETA`}),(0,D.jsx)(`button`,{type:`button`,role:`switch`,\"aria-checked\":o,\"aria-label\":`Enable auto presenter/host`,style:Os.switch(o),onClick:()=>s?.(!o),disabled:!!m||t||!a,children:(0,D.jsx)(`span`,{style:Os.knob(o)})})]}),(0,D.jsx)(`div`,{style:Os.sub,children:`An AI presenter that points, presents and reacts on your boards — a set of poses matched to what you're explaining, placed per beat.`}),!a&&(0,D.jsx)(`div`,{style:Os.sub,children:`This project is read-only. Presenter setup is unavailable.`}),o&&(0,D.jsx)(`div`,{style:{marginTop:9},children:M?(0,D.jsxs)(`div`,{style:{fontSize:11.5},children:[M,` `,(0,D.jsx)(`button`,{type:`button`,style:Os.btn,onClick:T.cancel,children:`Cancel setup`}),(0,D.jsx)(`div`,{style:Os.sub,children:`Stops later steps. Requests already sent may still be charged.`})]}):c?(0,D.jsxs)(`div`,{style:Os.row,children:[(0,D.jsxs)(`span`,{style:{fontSize:11.5,color:`var(--text-primary)`},children:[`Active host: `,(0,D.jsx)(`strong`,{children:c.name||`Host`}),` · `,(c.poses||c.images||[]).length,` poses`]}),(0,D.jsx)(`button`,{type:`button`,style:{...Os.btn,marginLeft:`auto`},onClick:A,title:`Generate any poses the content now needs that this host lacks`,children:`Add poses`}),(0,D.jsx)(`button`,{type:`button`,style:Os.btn,onClick:O,title:`Regenerate the whole host from scratch`,children:`Regenerate`})]}):g?(0,D.jsxs)(`div`,{children:[(0,D.jsx)(`div`,{style:{fontSize:11,color:`var(--text-secondary)`,marginBottom:6},children:`Pick a character to use as the host (missing poses are generated):`}),j.length===0&&(0,D.jsx)(`div`,{style:{fontSize:11,color:`var(--text-muted)`},children:`No saved characters yet — create one instead.`}),(0,D.jsx)(`div`,{style:{maxHeight:160,overflowY:`auto`,display:`flex`,flexDirection:`column`,gap:2},children:j.map(e=>(0,D.jsxs)(`div`,{style:Os.pickItem,onClick:()=>k(e),onMouseEnter:e=>{e.currentTarget.style.borderColor=`var(--border)`,e.currentTarget.style.background=`var(--bg-elevated)`},onMouseLeave:e=>{e.currentTarget.style.borderColor=`transparent`,e.currentTarget.style.background=`transparent`},children:[(e.selectedImageUrl||e.imageUrl)&&(0,D.jsx)(`img`,{src:e.selectedImageUrl||e.imageUrl,alt:``,style:Os.thumb}),(0,D.jsx)(`span`,{style:{fontSize:12,color:`var(--text-primary)`},children:e.name||`Character`})]},e.id))}),(0,D.jsx)(`button`,{type:`button`,style:{...Os.btn,marginTop:6},onClick:()=>_(!1),children:`Cancel`})]}):(0,D.jsxs)(`div`,{style:{display:`flex`,flexDirection:`column`,gap:6},children:[(0,D.jsx)(`input`,{value:y,onChange:e=>b(e.target.value),placeholder:`Host name (optional)`,style:{fontSize:11.5,padding:`5px 8px`,borderRadius:6,border:`1px solid var(--border)`,background:`var(--bg-elevated)`,color:`var(--text-primary)`,fontFamily:`var(--font)`}}),(0,D.jsx)(`input`,{value:x,onChange:e=>S(e.target.value),placeholder:`Art style (optional) — e.g. flat vector, chibi, hand-drawn, 3D clay`,style:{fontSize:11.5,padding:`5px 8px`,borderRadius:6,border:`1px solid var(--border)`,background:`var(--bg-elevated)`,color:`var(--text-primary)`,fontFamily:`var(--font)`}}),(0,D.jsx)(`textarea`,{value:C,onChange:e=>w(e.target.value),rows:2,placeholder:`Describe your host (optional) — e.g. a friendly woman in her 30s, glasses, casual blazer. Leave blank to design from your narration.`,style:{fontSize:11.5,padding:`5px 8px`,borderRadius:6,border:`1px solid var(--border)`,background:`var(--bg-elevated)`,color:`var(--text-primary)`,fontFamily:`var(--font)`,resize:`vertical`}}),(0,D.jsxs)(`div`,{style:{display:`flex`,gap:8},children:[(0,D.jsx)(`button`,{type:`button`,style:{...Os.btn,background:`var(--accent)`,color:`var(--accent-contrast, #0A0A0A)`,borderColor:`var(--accent)`},onClick:O,children:C.trim()||x.trim()?`Create my host`:`Create one for me`}),(0,D.jsx)(`button`,{type:`button`,style:Os.btn,onClick:()=>_(!0),children:`Use a saved character`})]})]})})]})}let js=Object.freeze([]);function Ms({hostServices:e,placementBroker:t,projectId:n,canEdit:r=!0,doc:i,onDocChange:a,voiceover:o,autoEnable:s=!1}){let{loadPanelDoc:c,toast:l}=os(e),{placePosesOnDoc:u,clearPresenterPoses:d}=ds(e),f=i?.meta?.host||{},p=o?.words||i?.audio?.words||js,m=t||e.placementBroker;m&&rs(m);let[h,g]=(0,v.useState)(!1),_=as(e,{projectId:n,doc:i,canEdit:r,words:p},()=>g(!1)),y=(i?.meta?.canvasChat?.intent||p.map(e=>typeof e==`string`?e:e?.text||``).join(` `)).slice(0,4e3);(0,v.useEffect)(()=>{r&&s&&i&&!i.meta?.host&&a(e=>c({...e,meta:{...e.meta||{},host:{enabled:!0}}}))},[s]);let b=(e,t)=>u(e,t,p),x=async e=>{if(!r)return;let t;try{if(t=_.begin(),!t)return;g(!0);let n=e?i:m?await m.apply(i,{mode:`clear`},{signal:t.signal,assertCurrent:t.check}):d(i);t.check();let r=c({...n,meta:{...n.meta||{},host:{...n.meta?.host||{},enabled:e}}}),o=t.admission();a(e=>{try{o(e)}catch{return e}return r})}catch(e){t?.current()&&e?.name!==`AbortError`&&l.error?.(e?.message||`Presenter placement failed.`)}finally{t?.finish()}},S=async(e,{assertCurrent:t,signal:n,assertPending:r}={})=>{let o=()=>{r?.(),t?.()};o();let s=(e?.poses||e?.images||[]).map(e=>({label:e.label,url:e.url,vectorUrl:e.vectorUrl,atWord:e.atWord??null})).filter(e=>e.url);if(!s.length){l.error?.(`The host has no usable poses.`);return}let u=c({...i,meta:{...i.meta||{},host:{enabled:!0,id:e.id,name:e.name,description:e.description||``,style:e.style||``,poses:s}}}),d=m?await m.apply(u,{mode:`place`,poses:s,words:p},{signal:n,assertCurrent:o}):b(u,s);o(),a(e=>{try{t?.(e)}catch{return e}return d}),l.success?.(`Presenter \"${e.name||`Host`}\" submitted to your boards`)},C=f.enabled&&f.poses?.length?{id:f.id,name:f.name,description:f.description||``,style:f.style||``,poses:f.poses,images:f.poses}:null;return(0,D.jsxs)(D.Fragment,{children:[h&&(0,D.jsxs)(`div`,{role:`status`,style:{fontSize:12},children:[`Updating presenter placement… `,(0,D.jsx)(`button`,{type:`button`,className:`btn btn-secondary`,onClick:_.cancel,children:`Cancel placement`})]}),(0,D.jsx)(As,{externalBusy:h,projectId:n,doc:i,canEdit:r,hostServices:e,enabled:!!f.enabled,onToggle:x,activeHost:C,content:y,words:p,onHostReady:S})]})}let Ns=Object.freeze(`loadMediaBlob.loadMediaArrayBuffer.resolveDesktopMediaUrl.isMissing.runFinalEdit.runStructureEdit.runMotionGraphics.transcribeAudio.useTier.requestUpgrade.upgradeReasons.confirm.alert.toast.HelpHint.downloadUrlLocally.extensionFromUrl.safeDownloadName.proxiedMediaUrl.uploadReferenceImage.getAllAssets.addAsset.recordAssets.listProjects.loadProject.stockGrid.stockSelect.useIsMobileUI.desktopBridge.authHeaders.useCanvas.useCanvasWriteAccess.generateReference.fetchStyleOptions.fetchStyleFromUploads.generateReferenceSheet.useReferenceExtraction.findExtractedViews.addLibraryItem.getLibraryItems.useThumb.planAllows.tagAsset.runLlmText.CanvasCommitInput.cachedObjectUrlIfPresent.presenterHost`.split(`.`));function Ps(e){return I(e?.version===1&&Ns.every(t=>e[t]!==void 0&&(typeof e[t]==`function`||[`toast`,`presenterHost`,`upgradeReasons`].includes(t))),`HOST_SERVICES`,`Shared native UI requires version 1 of its declared runtime host.`),e}let Fs=null;function Is(e){return Fs=Object.freeze(Ps(e)),Fs}function Ls(){if(!Fs)throw Object.assign(Error(`Shared native runtime host is unavailable.`),{code:`HOST_SERVICES`});return Fs}function Rs(e){return(0,D.jsx)(Ms,{...e,hostServices:e.hostServices||Ls().presenterHost})}Object.freeze({clips:500,audioItems:500,overlays:1e3,durationSeconds:21600,fps:[24,30,60],resolution:[720,1080,2160]}),Object.freeze([`photo`,`video`,`audio`]),Object.freeze({Pexels:{id:`pexels`,url:`https://www.pexels.com/license/`,attributionRequired:!1},Pixabay:{id:`pixabay`,url:`https://pixabay.com/service/license-summary/`,attributionRequired:!1},Coverr:{id:`coverr`,url:`https://coverr.co/license`,attributionRequired:!1},Unsplash:{id:`unsplash`,url:`https://unsplash.com/license`,attributionRequired:!0},Freesound:{id:`cc0-1.0`,url:`https://creativecommons.org/publicdomain/zero/1.0/`,attributionRequired:!1}});let zs=(e,t)=>typeof e==`string`&&e.trim()&&e.length<=t?e.trim():null,Bs=(e,t)=>L(e)&&Object.keys(e).every(e=>t.includes(e)),Vs=e=>L(e)&&zs(e.assetId,160)&&zs(e.versionId,160);function Hs(e){return B(e),I(Bs(e,[`schemaVersion`,`presenterId`,`sourceBlock`,`poseSheet`,`poses`,`createdAt`])&&e.schemaVersion===1&&zs(e.presenterId,160)&&Vs(e.sourceBlock)&&Vs(e.poseSheet)&&Array.isArray(e.poses)&&e.poses.length>=1&&e.poses.length<=64&&e.poses.every(e=>Bs(e,[`name`,`assetId`,`versionId`,`crop`])&&zs(e.name,120)&&Vs(e)&&L(e.crop)&&[`x`,`y`,`width`,`height`].every(t=>Number.isFinite(e.crop[t])&&e.crop[t]>=0&&e.crop[t]<=1))&&Number.isFinite(+new Date(e.createdAt)),`PRESENTER_RECEIPT`,`Presenter pose assets require exact source, sheet, slice, and version receipts.`),Object.freeze(structuredClone(e))}async function Us(e,{sourceBlock:t={assetId:`sm.board-editor`,versionId:`1.0.0`},createdAt:n=new Date().toISOString()}={}){let r=zs(e?.id,160)||`presenter`,i=Array.isArray(e?.poses)?e.poses:[];I(i.length&&i.length<=64&&i.every(e=>zs(e?.label,120)&&zs(e?.url,16384)),`PRESENTER_RECEIPT`,`Generated presenter poses require labels and retained asset URLs.`);let a=[];for(let e of i)a.push({name:e.label,assetId:`${r}:${e.label}`,versionId:await se({url:e.url,vectorUrl:e.vectorUrl||null}),crop:{x:0,y:0,width:1,height:1}});return Hs({schemaVersion:1,presenterId:r,sourceBlock:t,poseSheet:{assetId:`${r}:pose-set`,versionId:await se(a)},poses:a,createdAt:n})}function Ws(e,t,n=5e3){let r=Number(e)||0,i=Math.max(r,Number(t)||r),a=i-r;if(a<=0)return[{startMs:r,endMs:r,durationMs:0}];let o=Math.max(1,Math.round(a/n)),s=a/o,c=[];for(let e=0;e<o;e++){let t=Math.round(r+s*e),n=e===o-1?i:Math.round(r+s*(e+1));c.push({startMs:t,endMs:n,durationMs:n-t})}return c}function Gs(e){let{loadPanelDoc:t}=os(e),{placePosesOnDoc:n}=ds(e),r=(e,t)=>(e?.meta?.canvasChat?.intent||t.map(e=>typeof e==`string`?e:e?.text||``).join(` `)).slice(0,4e3),i=e=>(e?.poses||e?.images||[]).map(e=>({label:e.label,url:e.url,vectorUrl:e.vectorUrl,atWord:e.atWord??null})).filter(e=>e.url);async function a({content:t=``,words:n=[],deps:r,onProgress:a,assertCurrent:o}={}){let s=await Ts({content:t,words:n},r||Ds(e,{onProgress:a,assertCurrent:o})),c=i(s);if(!c.length)return null;let l={enabled:!0,id:s.id,name:s.name,description:s.description||``,style:s.style||``,poses:c},u=await Us({...s,poses:c});return{meta:{...l,presenterReceipt:u},poses:c,presenterReceipt:u}}function o(e,{words:t=[],minGapMs:n=2e3,targetMs:r=5e3}={}){let i=t[t.length-1],a=i?Math.round(Number(i.endMs??i.startMs??0)):0;if(!a)return e;let o=(e?.strip||[]).filter(e=>e.type===`canvas`);if(!o.length)return e;let s=o.map(e=>[Number(e.startMs)||0,(Number(e.startMs)||0)+(Number(e.durationMs)||0)]).sort((e,t)=>e[0]-t[0]),c=[];for(let[e,t]of s){let n=c[c.length-1];n&&e<=n[1]?n[1]=Math.max(n[1],t):c.push([e,t])}let l=[],u=0;for(let[e,t]of c)e-u>=n&&l.push([u,e]),u=Math.max(u,t);if(a-u>=n&&l.push([u,a]),!l.length)return e;let d=o[0].sceneId||e?.scenes?.[0]?.sceneId||`s1`,f=(e.strip||[]).length,p=[];for(let[e,t]of l)for(let n of Ws(e,t,r))n.durationMs&&p.push({panelId:`hostg${f}_${p.length+1}`,type:`canvas`,sceneId:d,background:`#ffffff`,autoArrange:!0,planned:!0,builtBy:`host-gap`,startMs:n.startMs,durationMs:n.durationMs,transitionIn:`cut`,elements:[]});return p.length?{...e,strip:[...e.strip,...p]}:e}function s(e,{meta:r=null,poses:i=[],words:a=[],presenterReceipt:o=null}={}){if(!i.length)return e;let s=r?t({...e,meta:{...e.meta||{},host:o?{...r,presenterReceipt:o}:r}}):e;return n(s,i,a)}async function c(e,{voiceover:t,deps:n,onProgress:i}={}){let o=e?.meta?.host;if(!o?.enabled)return e;let c=t?.words||e?.audio?.words||[];if(o.poses?.length)return s(e,{poses:o.poses,words:c});let l=await a({content:r(e,c),words:c,deps:n,onProgress:i});return l?s(e,{...l,words:c}):e}function l(e){let t=e?.meta?.host;return!(!t?.enabled||t.poses?.length)}return{litePoses:i,generateHostPoses:a,appendHostGapBoards:o,applyHostToDoc:s,provisionHostOnDoc:c,hostBuildPending:l}}let Ks=()=>Gs(Ls().presenterHost),qs=(...e)=>Ks().hostBuildPending(...e);function Js({text:e,placement:t=`bottom`,width:n=260,glyph:r=`?`,color:i,borderColor:a}){let o=(0,v.useRef)(null),s=(0,v.useRef)(`mouse`),[c,l]=(0,v.useState)(null),u=(0,v.useCallback)(()=>{let e=o.current;if(!e)return null;let r=e.getBoundingClientRect(),i=typeof window<`u`?window.innerWidth:1024,a=r.left+r.width/2-n/2;return a=Math.max(8,Math.min(a,i-n-8)),{top:t===`top`?r.top-6:r.bottom+6,left:a}},[t,n]),d=(0,v.useCallback)(()=>{let e=u();e&&l(e)},[u]),f=(0,v.useCallback)(()=>l(null),[]),p=(0,v.useCallback)(e=>{s.current===`touch`&&(e.preventDefault(),e.stopPropagation(),l(e=>e?null:u()))},[u]);return(0,v.useEffect)(()=>{if(!c)return;let e=e=>{o.current?.contains(e.target)||f()};return document.addEventListener(`pointerdown`,e,!0),window.addEventListener(`scroll`,f,!0),()=>{document.removeEventListener(`pointerdown`,e,!0),window.removeEventListener(`scroll`,f,!0)}},[c,f]),(0,D.jsxs)(D.Fragment,{children:[(0,D.jsx)(`span`,{ref:o,onPointerDown:e=>{s.current=e.pointerType||`mouse`},onMouseEnter:d,onMouseLeave:f,onFocus:d,onBlur:f,onClick:p,tabIndex:0,role:`button`,\"aria-label\":`More info`,style:{...Ys,...i?{color:i}:null,...a?{borderColor:a}:null},children:r}),c&&(0,D.jsx)(`span`,{role:`tooltip`,style:{position:`fixed`,top:c.top,left:c.left,transform:t===`top`?`translateY(-100%)`:`none`,width:n,maxWidth:`calc(100vw - 16px)`,boxSizing:`border-box`,background:`var(--bg-elevated)`,color:`var(--text-primary)`,border:`1px solid var(--border)`,borderRadius:6,padding:`8px 10px`,fontSize:11.5,lineHeight:1.45,fontFamily:`var(--font)`,boxShadow:`0 6px 24px rgba(0,0,0,0.25)`,zIndex:100060,pointerEvents:`none`,whiteSpace:`normal`},children:e})]})}let Ys={display:`inline-flex`,alignItems:`center`,justifyContent:`center`,width:14,height:14,borderRadius:`50%`,background:`var(--bg-elevated)`,border:`1px solid var(--border)`,color:`var(--text-secondary)`,fontSize:9,fontWeight:700,fontFamily:`var(--font)`,cursor:`help`,userSelect:`none`,outline:`none`},Xs=e=>(...t)=>Ls()[e](...t),Zs=((e,t)=>(...n)=>{let r=Ls();return typeof r[e]==`function`?r[e](...n):t(...n)})(`resolveDeviceMediaUrl`,async()=>null),Qs=Xs(`uploadReferenceImage`),$s=Xs(`downloadUrlLocally`),ec=Xs(`extensionFromUrl`),tc=Xs(`safeDownloadName`),nc=Xs(`proxiedMediaUrl`),rc=Xs(`getAllAssets`),ic=Xs(`addAsset`),ac=Object.freeze({confirm:Xs(`confirm`),alert:Xs(`alert`)}),oc=Object.freeze(Object.fromEntries([`success`,`error`,`info`,`warning`].map(e=>[e,(...t)=>Ls().toast[e]?.(...t)])));new Proxy({},{get:(e,t)=>typeof t==`symbol`||Reflect.has(e,t)?Reflect.get(e,t):Ls().upgradeReasons[t]});function sc(e){let t=Ls().CanvasCommitInput;return(0,D.jsx)(t,{...e})}let cc=(e,t=`image`)=>n=>[{label:`Download`,icon:`download`,onClick:()=>$s(n.url,`${tc(e||t)}.${ec(n.url,t)||(t===`video`?`mp4`:`jpg`)}`)}];function lc(){let e={playFilled:`<path d=\"M7 4.6v14.8c0 .8.9 1.2 1.5.8l11.4-7.4a1 1 0 0 0 0-1.6L8.5 3.8C7.9 3.4 7 3.8 7 4.6Z\" fill=\"currentColor\" stroke=\"none\"></path>`,pauseFilled:`<rect x=\"6\" y=\"4.5\" width=\"4\" height=\"15\" rx=\"1\" fill=\"currentColor\" stroke=\"none\"></rect><rect x=\"14\" y=\"4.5\" width=\"4\" height=\"15\" rx=\"1\" fill=\"currentColor\" stroke=\"none\"></rect>`,volume2:`<path d=\"M11 5 6 9H2v6h4l5 4V5Z\" fill=\"currentColor\"></path><path d=\"M15.5 8.5a5 5 0 0 1 0 7M19 5a10 10 0 0 1 0 14\"></path>`,volumeX:`<path d=\"M11 5 6 9H2v6h4l5 4V5Z\" fill=\"currentColor\"></path><path d=\"m22 9-6 6M16 9l6 6\"></path>`,maximize:`<path d=\"M8 3H5a2 2 0 0 0-2 2v3M16 3h3a2 2 0 0 1 2 2v3M21 16v3a2 2 0 0 1-2 2h-3M3 16v3a2 2 0 0 0 2 2h3\"></path>`,minimize:`<path d=\"M8 3v3a2 2 0 0 1-2 2H3M21 8h-3a2 2 0 0 1-2-2V3M3 16h3a2 2 0 0 1 2 2v3M16 21v-3a2 2 0 0 1 2-2h3\"></path>`,x:`<path d=\"M6 6 18 18M18 6 6 18\"></path>`,chevronLeft:`<path d=\"m15 6-6 6 6 6\"></path>`,chevronRight:`<path d=\"m9 6 6 6-6 6\"></path>`,download:`<path d=\"M12 4v12M7 11l5 5 5-5\"></path><path d=\"M5 20h14\"></path>`,edit:`<path d=\"M12 20h9\"></path><path d=\"M16.5 3.5a2.1 2.1 0 0 1 3 3L7 19l-4 1 1-4Z\"></path>`,imageOff:`<path d=\"M2 2l20 20\"></path><path d=\"M10.41 10.41a2 2 0 1 1-2.83-2.83\"></path><path d=\"M13.5 13.5 6 21\"></path><path d=\"m18 12 3 3\"></path><path d=\"M3.59 3.59A1.99 1.99 0 0 0 3 5v14a2 2 0 0 0 2 2h14c.55 0 1.052-.22 1.41-.59\"></path><path d=\"M21 15V5a2 2 0 0 0-2-2H9\"></path>`},t=2e3,n=3e3,r=3e3,i=new WeakMap,a=t=>`<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\">`+e[t]+`</svg>`,o=e=>{let t=Math.max(0,Math.floor(Number.isFinite(e)?e:0)),n=Math.floor(t/3600),r=Math.floor(t/60)%60,i=String(t%60).padStart(2,`0`);return n?n+`:`+String(r).padStart(2,`0`)+`:`+i:r+`:`+i},s=e=>typeof e==`string`&&e.startsWith(`sm-media://device/`),c=(e,t,n)=>{let r=e.createElement(t);return n&&(r.className=n),r},l=(e,t,n,r=t)=>{e.setAttribute(`aria-label`,t),e.title=r,e.dataset.icon!==n&&(e.dataset.icon=n,e.innerHTML=a(n))},u=(e,t,n,r)=>{let i=c(e,`button`,`sm-media-btn`);return i.type=`button`,t&&(i.dataset.control=t),l(i,n,r),i},d=(e,t)=>{let n=c(e,`span`,t);return n.setAttribute(`role`,`img`),n.setAttribute(`aria-label`,`On another device`),n.title=`On another device`,n.innerHTML=a(`imageOff`),n},f=(e,t)=>{t.width&&(t.width<240||t.height<160?e.setAttribute(`data-size`,`small`):e.removeAttribute(`data-size`))},p=e=>(t,n,r,i)=>{t.addEventListener(n,r,i),e.push([t,n,r,i])};function m(e,a={}){if(!e)return null;let s=i.get(e);if(s)return s;let d=e.ownerDocument,f=d.defaultView||window,m=[],h=p(m),g=e=>f.requestAnimationFrame?f.requestAnimationFrame(e):f.setTimeout(e,16),_=e=>f.cancelAnimationFrame?f.cancelAnimationFrame(e):f.clearTimeout(e),v=a.root,y=a.ui,b=!v,x=!y,S=[];b&&(v=c(d,`div`),e.before(v),v.append(e));let C=a.keys||v;x&&(y=c(d,`div`),v.append(y)),v.classList.add(`sm-player`),y.classList.add(`sm-player-ui`);let w=(e,t)=>{v.hasAttribute(e)||(v.setAttribute(e,t),S.push(e))};w(`data-mode`,`dark`),w(`tabindex`,`0`),w(`role`,`group`),w(`aria-label`,a.label||`Video`);let T=e.hasAttribute(`controls`);e.controls=!1,e.removeAttribute(`controls`),e.playsInline=!0,e.setAttribute(`playsinline`,``),e.setAttribute(`data-stillmade-player`,`on`);let E=c(d,`div`,`sm-player-shade`),D=c(d,`div`,`sm-player-bar nodrag nopan`),O=u(d,`play`,`Play`,`playFilled`),k=u(d,`sound`,`Mute`,`volume2`),A=u(d,`fullscreen`,`Full screen`,`maximize`),j=c(d,`div`,`sm-player-rail`),M=c(d,`div`,`sm-player-track`),ee=c(d,`div`,`sm-player-buffered`),N=c(d,`div`,`sm-player-played`),P=c(d,`div`,`sm-player-head`),te=c(d,`div`,`sm-player-knob`),ne=c(d,`div`,`sm-player-tip`),re=c(d,`span`,`sm-player-time`),F=c(d,`span`,`sm-player-now`),I=c(d,`span`,`sm-media-of sm-player-total`);M.append(ee,N),P.append(te),j.append(M,P,ne),re.append(F,I),j.dataset.control=`timeline`,j.tabIndex=0,j.setAttribute(`role`,`slider`),j.setAttribute(`aria-label`,`Seek`),j.setAttribute(`aria-valuemin`,`0`),re.dataset.control=`time`,re.setAttribute(`aria-hidden`,`true`),ne.setAttribute(`aria-hidden`,`true`),E.setAttribute(`aria-hidden`,`true`);let L=c(d,`div`,`sm-player-sound`),R=c(d,`div`,`sm-player-volume`),z=c(d,`div`,`sm-player-volume-rail`),ie=c(d,`div`,`sm-player-volume-track`),ae=c(d,`div`,`sm-player-volume-level`),oe=c(d,`div`,`sm-player-volume-head`),B=c(d,`div`,`sm-player-volume-knob`);ie.append(ae,oe),oe.append(B),z.append(ie),R.append(z),L.append(R,k),L.dataset.control=`volume`,z.tabIndex=0,z.setAttribute(`role`,`slider`),z.setAttribute(`aria-label`,`Volume`),z.setAttribute(`aria-orientation`,`vertical`),z.setAttribute(`aria-valuemin`,`0`),z.setAttribute(`aria-valuemax`,`100`),D.append(O,j,re,L,A),y.append(E,D);let V=!1,se=!1,ce=0,le=Date.now(),ue=!1,de=0,fe=0,pe=0,H=!0,me=``,he=``,ge=``,_e=``,ve=!1,ye=!1,be=!1,xe=!1,Se=null,Ce=!1,U=0,we=!1,W=0,Te=!1,Ee=0,G=0,De=-1,Oe=-1,ke=-1,Ae=0,je=0,Me=!1,Ne=0,Pe=0,Fe=()=>Number.isFinite(e.duration)&&e.duration>0?e.duration:0,Ie=(e,t)=>{t?v.setAttribute(e,``):v.removeAttribute(e)},Le=()=>{let t=Fe(),n=ue?de*t:e.currentTime||0,r=t?Math.min(1,Math.max(0,n/t)):0;r!==De&&(De=r,N.style.transform=`scaleX(`+r+`)`,P.style.transform=`translateX(`+r*100+`%)`);let i=Math.floor(n);(i!==Oe||t!==ke)&&(Oe=i,ke=t,F.textContent=o(n),I.textContent=` / `+o(t),j.setAttribute(`aria-valuemax`,String(Math.round(t))),j.setAttribute(`aria-valuenow`,String(Math.min(i,Math.round(t)))),j.setAttribute(`aria-valuetext`,o(n)+` of `+o(t)))},Re=()=>{fe=0,!V&&(Le(),!e.paused&&!e.ended&&H&&(fe=g(Re)))},ze=()=>{!fe&&!V&&(fe=g(Re))},Be=()=>{let t=Fe(),n=e.buffered;t&&n&&n.length&&(ee.style.transform=`scaleX(`+Math.min(1,n.end(n.length-1)/t)+`)`)},Ve=()=>!!f.matchMedia?.(`(hover: none)`)?.matches,He=e=>e.pointerType?e.pointerType===`mouse`:!Ve(),Ue=e=>{try{return e.matches(`:focus-visible`)}catch{return!0}},We=()=>!V&&!e.paused&&!e.ended&&!ue&&!Me&&!Ce&&!we&&!Se,Ge=e=>{se!==e&&(se=e,Ie(`data-idle`,e))},Ke=()=>{if(ce=0,!We())return;let e=t-(Date.now()-le);if(e>10){ce=f.setTimeout(Ke,e);return}Ge(!0)},qe=()=>{if(!We()){ce&&=(f.clearTimeout(ce),0),Ge(!1);return}!ce&&!se&&(ce=f.setTimeout(Ke,Math.max(10,t-(Date.now()-le))))},Je=()=>{le=Date.now(),Ge(!1),qe()},Ye=()=>{let e=!V&&!(ye||xe||ue||Me||Ce||we);e!==be&&(be=e,Ie(`data-away`,e))},Xe=()=>{W&&=(f.clearTimeout(W),0),we=!1},Ze=()=>{Te||V||(Te=!0,we=!0,W=f.setTimeout(()=>{W=0,we=!1,Ye(),qe()},r),Ye(),qe())},K=()=>{Ce=!0,U&&f.clearTimeout(U),U=f.setTimeout(()=>{U=0,Ce=!1,Ye(),qe()},n),Ye(),Je()},Qe=()=>{if(e.paused||e.ended){let t=e.play();t&&typeof t.catch==`function`&&t.catch(()=>{})}else e.pause()},$e=t=>{let n=Fe();n&&(e.currentTime=Math.min(n,Math.max(0,t)),ze())},et=t=>$e((e.currentTime||0)+t),tt=t=>{t>0&&e.muted&&(e.muted=!1),e.volume=Math.min(1,Math.max(0,Math.round(((e.volume||0)+t)*10)/10))},nt=()=>{let t=!e.paused&&!e.ended;l(O,t?`Pause`:`Play`,t?`pauseFilled`:`playFilled`),Ie(`data-playing`,t),Je(),ze()},rt=()=>{let t=e.muted||e.volume===0,n=t?0:Math.min(1,Math.max(0,e.volume)),r=Math.round(n*100);ae.style.transform=`scaleY(`+n+`)`,oe.style.transform=`translateY(`+-n*100+`%)`,z.setAttribute(`aria-valuenow`,String(r)),z.setAttribute(`aria-valuetext`,t?`Muted`:r+`%`),k.setAttribute(`aria-pressed`,String(!!e.muted)),l(k,`Mute`,t?`volumeX`:`volume2`,e.muted?`Unmute`:`Mute`)},it=()=>me===`theater`||d.fullscreenElement===v,at=()=>{let e=it();l(A,e?`Exit full screen`:`Full screen`,e?`minimize`:`maximize`)},ot=()=>{if(me=`theater`,v.setAttribute(`data-stage`,`theater`),typeof v.showPopover==`function`)try{v.setAttribute(`popover`,`manual`),v.showPopover()}catch{v.removeAttribute(`popover`)}at(),a.onStage?.(!0)},st=()=>{if(me===`theater`){if(me=``,v.hasAttribute(`popover`)){try{v.hidePopover()}catch{}v.removeAttribute(`popover`)}v.removeAttribute(`data-stage`),at(),a.onStage?.(!1)}},ct=()=>{let e=v.requestFullscreen;if(a.theater||typeof e!=`function`||d.fullscreenEnabled===!1){ot();return}let t;try{t=e.call(v)}catch{ot();return}t&&typeof t.then==`function`?t.then(at,ot):at()},lt=()=>{if(me===`theater`)st();else if(d.fullscreenElement===v){let e=d.exitFullscreen?.();e&&typeof e.catch==`function`&&e.catch(()=>{})}},ut=()=>{it()?lt():ct()},dt=()=>{let e=j.getBoundingClientRect();Ee=e.left,G=e.width},ft=e=>G>0?Math.min(1,Math.max(0,(e-Ee)/G)):0,pt=e=>{let t=Math.min(Math.max(e-Ee,22),Math.max(22,G-22)),n=o(Fe()*ft(e));ne.style.transform=`translateX(`+t+`px) translateX(-50%)`,ne.textContent!==n&&(ne.textContent=n)},mt=()=>{let t=Fe();t&&(e.currentTime=de*t),Le()},ht=()=>{pe||=g(()=>{pe=0,V||mt()})},gt=()=>{ue&&(pe&&=(_(pe),0),mt(),ue=!1,j.removeAttribute(`data-drag`),_e===`touch`?K():(Ye(),qe()))};h(j,`pointerenter`,dt),h(j,`pointerdown`,e=>{if(!(e.button>0)){dt(),ue=!0,Ye(),j.setAttribute(`data-drag`,``);try{j.setPointerCapture?.(e.pointerId)}catch{}de=ft(e.clientX),ht(),pt(e.clientX),Je()}}),h(j,`pointermove`,e=>{pt(e.clientX),ue&&(de=ft(e.clientX),ht())}),h(j,`pointerup`,gt),h(j,`pointercancel`,gt),h(j,`lostpointercapture`,gt);let _t=()=>{let e=ie.getBoundingClientRect();Ae=e.top,je=e.height},vt=e=>je>0?Math.min(1,Math.max(0,1-(e-Ae)/je)):0,yt=()=>{Pe=0,!V&&(e.volume=Math.round(Ne*100)/100,e.muted=Ne===0)},bt=()=>{Pe||=g(yt)},xt=()=>{Me&&(Pe&&(_(Pe),yt()),Me=!1,R.removeAttribute(`data-drag`),Ye(),qe())};h(z,`pointerdown`,e=>{if(!(e.button>0)){e.stopPropagation(),_t(),Me=!0,R.setAttribute(`data-drag`,``),Ye();try{z.setPointerCapture?.(e.pointerId)}catch{}Ne=vt(e.clientY),bt(),Je()}}),h(z,`pointermove`,e=>{Me&&(Ne=vt(e.clientY),bt())}),h(z,`pointerup`,xt),h(z,`pointercancel`,xt),h(z,`lostpointercapture`,xt),h(O,`click`,Qe),h(k,`click`,()=>{e.muted||e.volume===0?(e.muted=!1,e.volume===0&&(e.volume=1)):e.muted=!0}),h(A,`click`,ut),h(v,`pointerdown`,e=>{_e=He(e)?`mouse`:`touch`,ve=be||se,_e===`touch`&&!ve&&K()}),h(v,`click`,e=>{let t=_e?_e===`touch`:Ve(),n=_e?ve:be||se;if(_e=``,!D.contains(e.target)){if(!t){Qe(),Je();return}n||Qe(),K()}}),h(v,`dblclick`,e=>{D.contains(e.target)||(e.preventDefault(),ut())}),h(v,`pointerenter`,e=>{He(e)&&(Xe(),ye=!0,Ye(),Je())}),h(v,`pointermove`,e=>{He(e)&&(le=Date.now(),ye||(Xe(),ye=!0,Ye()),se&&Ge(!1),ce||qe())}),h(v,`pointerleave`,e=>{He(e)&&(ye=!1,Ye())});let St=e=>!!e&&(v.contains(e)||C.contains(e)),Ct=e=>{let t=Ue(e.target);t&&(xe=!0),Se=t&&e.target!==v&&e.target!==C?e.target:null,Ye(),Je()},wt=e=>{Se=null,St(e.relatedTarget)||(xe=!1,Ye()),qe()};for(let e of C===v?[v]:[v,C])h(e,`focusin`,Ct),h(e,`focusout`,wt);let Tt=t=>{if(t.defaultPrevented||t.ctrlKey||t.metaKey||t.altKey)return;xe||(xe=!0,Ye());let n=t.key,r=n&&n.length===1?n.toLowerCase():n,i=Fe();if((n===` `||n===`Enter`)&&t.target?.closest?.(`button`))return;let a=!0;n===` `||r===`k`?Qe():t.target===z&&/^Arrow(Up|Down|Left|Right)$/.test(n||``)?tt(n===`ArrowUp`||n===`ArrowRight`?.1:-.1):t.target===z&&(n===`Home`||n===`End`)?(e.volume=+(n===`End`),e.muted=n===`Home`):n===`ArrowRight`||n===`ArrowLeft`?et((n===`ArrowRight`?1:-1)*(t.shiftKey?10:5)):r===`l`||r===`j`?et(r===`l`?10:-10):n===`ArrowUp`||n===`ArrowDown`?tt(n===`ArrowUp`?.1:-.1):r===`m`?e.muted=!e.muted:r===`f`?ut():n===`Home`?$e(0):n===`End`?$e(i):n===`PageUp`||n===`PageDown`?et((n===`PageUp`?1:-1)*i/10):/^[0-9]$/.test(n||``)?$e(i*Number(n)/10):n===`Escape`&&me===`theater`?(st(),t.stopPropagation()):a=!1,a&&t.preventDefault(),Je()};for(let e of C===v?[v]:[v,C])h(e,`keydown`,Tt);h(e,`play`,nt),h(e,`pause`,nt),h(e,`ended`,nt),h(e,`seeked`,ze),h(e,`durationchange`,ze),h(e,`loadedmetadata`,ze),h(e,`progress`,Be),h(e,`volumechange`,rt),h(e,`emptied`,()=>{De=-1,Oe=-1,ee.style.transform=`scaleX(0)`,ze()}),h(d,`fullscreenchange`,at);let Et=typeof f.ResizeObserver==`function`?new f.ResizeObserver(e=>{let t=e[e.length-1].contentRect,n=t.width;if(!n)return;let r=n<180?`micro`:n<240?`tiny`:n<300?`compact`:n<400?`narrow`:``;r!==he&&(he=r,he?v.setAttribute(`data-size`,he):v.removeAttribute(`data-size`));let i=!(t.height>0)||t.height>=200?``:t.height<150?`none`:`short`;i!==ge&&(ge=i,ge?v.setAttribute(`data-volume-room`,ge):v.removeAttribute(`data-volume-room`))}):null,Dt=typeof f.IntersectionObserver==`function`?new f.IntersectionObserver(e=>{H=e[e.length-1].isIntersecting,H&&(ze(),Ze())}):null;Et?.observe(v),Dt?.observe(v);let Ot=()=>{if(!V){lt(),V=!0,i.delete(e);for(let[e,t,n,r]of m)e.removeEventListener(t,n,r);Et?.disconnect(),Dt?.disconnect(),fe&&_(fe),pe&&_(pe),ce&&f.clearTimeout(ce),U&&f.clearTimeout(U),W&&f.clearTimeout(W),E.remove(),D.remove(),x&&y.remove();for(let e of[`data-away`,`data-idle`,`data-size`,`data-volume-room`,`data-stage`,`data-playing`,...S])v.removeAttribute(e);e.removeAttribute(`data-stillmade-player`),T&&e.setAttribute(`controls`,``),b&&v.replaceWith(e)}};try{ye=v.matches(`:hover`)}catch{}let kt=d.activeElement;St(kt)&&Ue(kt)&&(xe=!0,Se=kt!==v&&kt!==C?kt:null),Ye(),nt(),rt(),at(),Le(),Be();let At={root:v,video:e,destroy:Ot,toggleFullscreen:ut,isFullscreen:it};return i.set(e,At),At}function h(t,n={}){let r=n.document||document,i=[],o=p(i),l=(Array.isArray(t)?t:[t]).filter(e=>e&&typeof e.url==`string`&&e.url);if(!l.length)return null;let f=n.opener||r.activeElement,h=c(r,`dialog`,`sm-viewer`),g=c(r,`div`,`sm-viewer-stage`),_=c(r,`div`,`sm-viewer-top`),v=c(r,`div`,`sm-viewer-foot`),y=c(r,`span`,`sm-viewer-count`),b=c(r,`span`,`sm-viewer-name`),x=u(r,`close`,`Close`,`x`),S=u(r,`previous`,`Previous`,`chevronLeft`),C=u(r,`next`,`Next`,`chevronRight`);h.setAttribute(`data-mode`,`dark`),h.setAttribute(`data-stillmade-host`,``),h.setAttribute(`aria-label`,n.label||`Full screen view`),y.setAttribute(`aria-live`,`polite`),S.classList.add(`sm-viewer-nav`,`sm-viewer-previous`),C.classList.add(`sm-viewer-nav`,`sm-viewer-next`),_.append(x),v.append(y,b),h.append(g,_,S,C,v);let w=0,T=null,E=0,D=!1,O=t=>{for(let e of[..._.children])e!==x&&e.remove();let i=typeof n.actions==`function`?n.actions(t,w):n.actions;for(let n of Array.isArray(i)?i:[]){if(!n||!n.label)continue;let i=c(r,n.href?`a`:`button`,`sm-media-btn`);if(i.setAttribute(`aria-label`,n.label),i.title=n.label,e[n.icon]?i.innerHTML=a(n.icon):(i.textContent=n.label,i.classList.add(`sm-media-btn-text`)),n.href?(i.href=n.href,i.rel=`noopener noreferrer`,n.download!=null&&n.download!==!1&&i.setAttribute(`download`,n.download===!0?``:String(n.download))):i.type=`button`,typeof n.onClick==`function`){let e=w;i.addEventListener(`click`,r=>n.onClick(t,e,r))}_.insertBefore(i,x)}},k=e=>{let t=l.length;w=((Math.trunc(e)||0)%t+t)%t;let i=l[w],a=++E;T?.destroy(),T=null,g.replaceChildren(),S.hidden=C.hidden=y.hidden=t<2,b.hidden=!i.name,v.hidden=t<2&&!i.name;let o=c(r,`span`,`sm-media-of`);o.textContent=` of `+t,y.replaceChildren(String(w+1),o),b.textContent=i.name||``,O(i);let u=e=>{if(D||a!==E)return;if(!e){g.replaceChildren(d(r,`sm-viewer-off`));return}if(i.kind===`video`){let t=c(r,`div`,`sm-player`),a=c(r,`video`);t.setAttribute(`data-fill`,``),a.preload=`metadata`,a.autoplay=!0,a.src=e,i.poster&&!s(i.poster)&&(a.poster=i.poster),t.append(a),g.replaceChildren(t),T=m(a,{root:t,label:i.name||`Video`}),n.onShow?.(a,i,w);return}let t=c(r,`img`,`sm-viewer-media`);t.alt=i.alt??i.name??``,t.decoding=`async`,t.src=e,g.replaceChildren(t),n.onShow?.(t,i,w)};s(i.url)?typeof n.resolve==`function`?Promise.resolve().then(()=>n.resolve(i.url)).then(e=>u(e||null),()=>u(null)):u(null):u(i.url)},A=e=>{k(w+e),n.onIndexChange?.(w)},j=({silent:e=!1}={})=>{if(!D){D=!0,E++,T?.destroy(),T=null;for(let[e,t,n,r]of i)e.removeEventListener(t,n,r);try{h.open&&h.close()}catch{}h.remove(),f&&f.isConnected&&typeof f.focus==`function`&&f.focus({preventScroll:!0}),e||n.onClose?.()}};o(x,`click`,()=>j()),o(S,`click`,()=>A(-1)),o(C,`click`,()=>A(1)),o(h,`keydown`,e=>{if(e.stopPropagation(),e.key===`Escape`){e.preventDefault(),j();return}e.defaultPrevented||e.ctrlKey||e.metaKey||e.altKey||l.length<2||(e.key===`ArrowRight`||e.key===`ArrowLeft`)&&(e.preventDefault(),A(e.key===`ArrowRight`?1:-1))}),o(h,`cancel`,e=>{e.preventDefault(),j()});let M=!1,ee=null;return o(g,`pointerdown`,e=>{M=e.target===g}),o(g,`click`,e=>{M&&e.target===g&&j(),M=!1}),o(g,`touchstart`,e=>{ee=e.touches?.length===1&&!e.target?.closest?.(`.sm-player-bar`)?e.touches[0].clientX:null},{passive:!0}),o(g,`touchend`,e=>{if(ee==null||l.length<2)return;let t=e.changedTouches[0].clientX-ee;ee=null,Math.abs(t)>50&&A(t<0?1:-1)},{passive:!0}),(n.container||r.body).append(h),typeof h.showModal==`function`?h.showModal():h.setAttribute(`open`,``),k(n.index||0),x.focus({preventScroll:!0}),{dialog:h,show:k,close:j,update(e,t=w){let n=(Array.isArray(e)?e:[e]).filter(e=>e&&typeof e.url==`string`&&e.url);n.length&&(l=n,k(t))},get index(){return w}}}function g(e,t={}){let i=e.ownerDocument,o=i.defaultView||window,s=e.tagName===`IMG`?e:e.querySelector(`img`),l=e.tagName===`IMG`?e.parentElement:e,u=()=>s&&(s.currentSrc||s.getAttribute(`src`))?[{url:s.currentSrc||s.src,name:s.alt||``}]:[],d=typeof t.items==`function`?t.items():t.items||u();if(!l||!d.length)return null;let p=t.label||`View full screen`,m=c(i,`button`,`sm-expand-btn nodrag nopan`);m.type=`button`,m.setAttribute(`aria-label`,p),m.title=p,m.innerHTML=a(`maximize`);let g=e=>{if(e.preventDefault(),e.stopPropagation(),typeof t.onOpen==`function`){t.onOpen(e);return}h(typeof t.items==`function`?t.items():t.items||u(),{document:i,index:t.index||0,opener:m,actions:t.actions,resolve:t.resolve,onClose:t.onClose})},_=0,v=e=>{e.pointerType&&e.pointerType!==`mouse`&&!m.contains(e.target)&&(m.setAttribute(`data-show`,``),o.clearTimeout(_),_=o.setTimeout(()=>m.removeAttribute(`data-show`),n))},y=typeof o.ResizeObserver==`function`?new o.ResizeObserver(e=>f(m,e[e.length-1].contentRect)):null,b=typeof o.IntersectionObserver==`function`?new o.IntersectionObserver(e=>{let t=e[e.length-1];if(!t.isIntersecting)return;b.disconnect();let n=t.boundingClientRect;n.width<240||n.height<160||(m.setAttribute(`data-show`,``),o.clearTimeout(_),_=o.setTimeout(()=>m.removeAttribute(`data-show`),r))}):null,x=e=>{e.pointerType&&e.pointerType!==`mouse`||(o.clearTimeout(_),m.removeAttribute(`data-show`))};return m.addEventListener(`click`,g),l.addEventListener(`pointerdown`,v),l.addEventListener(`pointerenter`,x),l.classList.add(`sm-expand-host`),l.append(m),y?.observe(s||l),b?.observe(s||l),{button:m,destroy(){m.removeEventListener(`click`,g),l.removeEventListener(`pointerdown`,v),l.removeEventListener(`pointerenter`,x),y?.disconnect(),b?.disconnect(),o.clearTimeout(_),m.remove()}}}function _(e=document){let t=[],n=[];for(let n of e.querySelectorAll(`video[controls]:not([data-stillmade-player])`))t.push(m(n,{label:n.getAttribute(`aria-label`)||void 0}));let r=[...e.querySelectorAll(`[data-stillmade-expand]:not([data-stillmade-expand=\"off\"])`)].filter(e=>{let t=e.tagName===`IMG`?e:e.querySelector(`img`),n=e.tagName===`IMG`?e.parentElement:e;return t&&t.getAttribute(`src`)&&n&&!n.querySelector(`:scope > .sm-expand-btn`)}),i=e=>{let t=e.tagName===`IMG`?e:e.querySelector(`img`);return{url:t.currentSrc||t.src,name:t.alt||``}};for(let e of r){let t=e.getAttribute(`data-stillmade-expand`),a=t&&t!==`on`?r.filter(e=>e.getAttribute(`data-stillmade-expand`)===t):[e],o=g(e,{items:()=>a.map(i),index:a.indexOf(e)});o&&n.push(o)}return{players:t,buttons:n}}return{ICONS:e,svg:a,formatTime:o,isDeviceMediaUrl:s,photoSize:f,attachMediaPlayer:m,openMediaViewer:h,attachPhotoExpand:g,enhance:_}}var uc,dc,fc,Z,pc,mc,hc,gc,_c,vc=o((()=>{uc=lc(),{ICONS:dc,formatTime:fc,isDeviceMediaUrl:Z,photoSize:pc,attachMediaPlayer:mc,openMediaViewer:hc,attachPhotoExpand:gc,enhance:_c}=uc})),yc=c({default:()=>bc});function bc({items:e,index:t=0,onClose:n,onIndexChange:r,resolveUrl:i,actions:a,opener:o,label:s}){let c=(0,xc.useRef)(null),l=(0,xc.useRef)(null),u=(0,xc.useRef)(null);l.current={onClose:n,onIndexChange:r,resolveUrl:i,actions:a};let d=(Array.isArray(e)?e:[]).map(e=>e?.url||``).join(`\n`)+`\n`+t;return(0,xc.useEffect)(()=>{let n=hc(e,{index:t,opener:o,label:s,resolve:e=>l.current.resolveUrl?.(e),actions:(e,t)=>{let n=l.current.actions;return typeof n==`function`?n(e,t):n},onIndexChange:e=>l.current.onIndexChange?.(e),onClose:()=>l.current.onClose?.()});return c.current=n,u.current=d,n||l.current.onClose?.(),()=>{c.current=null,n?.close({silent:!0})}},[]),(0,xc.useEffect)(()=>{u.current!==d&&(u.current=d,c.current?.update(e,t))},[d]),null}var xc,Sc=o((()=>{xc=u(f(),1),vc()}));let Cc=(0,v.lazy)(()=>Promise.resolve().then(()=>(Sc(),yc)));function wc({url:e,title:t=`image`,onClose:n,onEdit:r,versions:i=[],currentVersion:a=0,onVersionChange:o}){if(!e)return null;let s=typeof o==`function`&&i.length>1,c=s?i.map((t,n)=>[n,n===a?e:typeof t==`string`?t:t?.url]).filter(([,e])=>typeof e==`string`&&e):[],l=c.some(([e])=>e===a)?c:[[a,e]],u=l.map(([,e])=>({url:e,name:t}));return(0,D.jsx)(v.Suspense,{fallback:null,children:(0,D.jsx)(Cc,{items:u,index:l.findIndex(([e])=>e===a),label:t,resolveUrl:Zs,actions:e=>[...r?[{label:`Edit image`,icon:`edit`,onClick:r}]:[],...cc(t,`image`)(e)],onClose:n,onIndexChange:s&&l.length>1?e=>o(l[e][0]):void 0})})}vc();function Tc(e,t){let n=(0,v.useRef)(t),r=Z(e),[i,a]=(0,v.useState)(null);return n.current=t,(0,v.useEffect)(()=>{if(!r)return;let t=!0;return Promise.resolve().then(()=>n.current?.(e)).then(n=>{t&&a({src:e,url:n||null})},()=>{t&&a({src:e,url:null})}),()=>{t=!1}},[e,r]),r?i?.src===e?{url:i.url,missing:!i.url}:{url:null,missing:!1}:{url:e||null,missing:!1}}function Ec({src:e,resolveUrl:t,label:n,\"aria-label\":r,fill:i=!1,className:a,style:o,onMissing:s,controls:c,playsInline:l,preload:u=`metadata`,...d}){let{url:f,missing:p}=Tc(e,t),m=(0,v.useRef)(null),h=(0,v.useRef)(null),g=(0,v.useRef)(null),_=(0,v.useRef)(s);return _.current=s,(0,v.useEffect)(()=>{if(p){_.current?.(e);return}let t=mc(g.current,{root:m.current,ui:h.current});return()=>t?.destroy()},[p]),p?(0,D.jsx)(`span`,{role:`img`,className:a?`sm-player-off ${a}`:`sm-player-off`,\"aria-label\":`On another device`,title:`On another device`,children:(0,D.jsx)(k,{name:`imageOff`,size:24})}):(0,D.jsxs)(`div`,{ref:m,className:a?`sm-player ${a}`:`sm-player`,style:o,\"data-mode\":`dark`,\"data-fill\":i?``:void 0,tabIndex:0,role:`group`,\"aria-label\":n||r||`Video`,children:[(0,D.jsx)(`video`,{ref:g,src:f||void 0,preload:u,playsInline:!0,...d}),(0,D.jsx)(`div`,{ref:h,className:`sm-player-ui`})]})}let Dc=(0,v.lazy)(()=>Promise.resolve().then(()=>(Sc(),yc)));function Oc({src:e,name:t,items:n,index:r=0,resolveUrl:i,actions:a,onOpen:o,label:s=`View full screen`,className:c}){let[l,u]=(0,v.useState)(!1),d=(0,v.useRef)(null),f=n||(e?[{url:e,name:t}]:[]),p=f[r]?.url,m=typeof p==`string`&&!!p&&!(p.startsWith(`sm-media://device/`)&&!i);return(0,v.useEffect)(()=>{let e=d.current,t=e?.parentElement;if(!t)return;let n=t.ownerDocument.defaultView||window,r=0,i=t=>{t.pointerType&&t.pointerType!==`mouse`&&!e.contains(t.target)&&(e.setAttribute(`data-show`,``),n.clearTimeout(r),r=n.setTimeout(()=>e.removeAttribute(`data-show`),3e3))},a=typeof n.ResizeObserver==`function`?new n.ResizeObserver(t=>{let{width:n,height:r}=t[t.length-1].contentRect;n&&(n<240||r<160?e.setAttribute(`data-size`,`small`):e.removeAttribute(`data-size`))}):null,o=typeof n.IntersectionObserver==`function`?new n.IntersectionObserver(t=>{let i=t[t.length-1];if(!i.isIntersecting)return;o.disconnect();let a=i.boundingClientRect;a.width<240||a.height<160||(e.setAttribute(`data-show`,``),n.clearTimeout(r),r=n.setTimeout(()=>e.removeAttribute(`data-show`),3e3))}):null,s=t=>{t.pointerType&&t.pointerType!==`mouse`||(n.clearTimeout(r),e.removeAttribute(`data-show`))},c=t.querySelector(`:scope > img`)||t;return t.addEventListener(`pointerdown`,i),t.addEventListener(`pointerenter`,s),a?.observe(c),o?.observe(c),()=>{t.removeEventListener(`pointerdown`,i),t.removeEventListener(`pointerenter`,s),a?.disconnect(),o?.disconnect(),n.clearTimeout(r)}},[m]),m?(0,D.jsxs)(D.Fragment,{children:[(0,D.jsx)(`button`,{ref:d,type:`button`,className:`sm-expand-btn nodrag nopan`+(c?` `+c:``),\"aria-label\":s,title:s,onClick:e=>{e.preventDefault(),e.stopPropagation(),o?o(e):u(!0)},children:(0,D.jsx)(k,{name:`maximize`,size:20,strokeWidth:2})}),l&&(0,D.jsx)(v.Suspense,{fallback:null,children:(0,D.jsx)(Dc,{items:f,index:r,resolveUrl:i,actions:a,opener:d.current,onClose:()=>u(!1)})})]}):null}function kc(e){let t=e.props.children;return typeof t==`string`||typeof t==`number`?String(t):v.Children.toArray(t).filter(e=>typeof e==`string`||typeof e==`number`).join(``)}function Ac(e){let t=[];return v.Children.forEach(e,e=>{e&&typeof e==`object`&&(e.type===`optgroup`?v.Children.forEach(e.props.children,n=>{n&&n.type===`option`&&t.push({value:n.props.value??kc(n),label:kc(n),disabled:!!n.props.disabled,group:e.props.label})}):e.type===`option`&&t.push({value:e.props.value??kc(e),label:kc(e),disabled:!!e.props.disabled}))}),t}function jc(e,t,n){let r=t;for(let t=0;t<e.length;t++)if(r+=n,r<0&&(r=e.length-1),r>=e.length&&(r=0),!e[r]?.disabled)return r;return t}function Mc({value:e,defaultValue:t,onChange:n,disabled:r=!1,style:i,className:a=``,title:o,children:s,options:c,\"aria-label\":l,...u}){let d=(0,v.useMemo)(()=>c||Ac(s),[c,s]),f=e!==void 0,[p,m]=(0,v.useState)(t??d[0]?.value),h=f?e:p,g=d.findIndex(e=>String(e.value)===String(h)),_=d[g],[y,b]=(0,v.useState)(!1),[x,S]=(0,v.useState)(-1),[C,w]=(0,v.useState)(null),[T,E]=(0,v.useState)(null),O=(0,v.useRef)(null),k=(0,v.useRef)(null),A=(0,v.useRef)({str:``,t:0}),j=(0,v.useCallback)(e=>{f||m(e),n?.({target:{value:e}}),b(!1),O.current?.focus()},[f,n]),M=(0,v.useCallback)(()=>{if(r)return;let e=O.current?.getBoundingClientRect();e&&w({left:e.left,top:e.bottom,width:e.width,topY:e.top,bottomSpace:window.innerHeight-e.bottom}),S(g>=0?g:jc(d,-1,1)),b(!0)},[r,g,d]);(0,v.useEffect)(()=>{if(!y)return;let e=e=>{!k.current?.contains(e.target)&&!O.current?.contains(e.target)&&b(!1)};document.addEventListener(`mousedown`,e,!0);let t,n=null,r=()=>{let e=O.current?.getBoundingClientRect();if(!e){b(!1);return}if(e.bottom<0||e.top>window.innerHeight||e.right<0||e.left>window.innerWidth){b(!1);return}(!n||n.left!==e.left||n.top!==e.bottom||n.width!==e.width||n.topY!==e.top)&&(n={left:e.left,top:e.bottom,width:e.width,topY:e.top,bottomSpace:window.innerHeight-e.bottom},w(n)),t=requestAnimationFrame(r)};return t=requestAnimationFrame(r),()=>{document.removeEventListener(`mousedown`,e,!0),cancelAnimationFrame(t)}},[y]),(0,v.useEffect)(()=>{y&&k.current&&k.current.querySelector(`[data-i=\"${x}\"]`)?.scrollIntoView({block:`nearest`})},[y,x]),(0,v.useEffect)(()=>{y||E(null)},[y]);let ee=(0,v.useCallback)(e=>{if(!r){if(!y){[`ArrowDown`,`ArrowUp`,`Enter`,` `].includes(e.key)&&(e.preventDefault(),M());return}if(e.key===`Escape`)e.preventDefault(),b(!1),O.current?.focus();else if(e.key===`ArrowDown`)e.preventDefault(),S(e=>jc(d,e,1));else if(e.key===`ArrowUp`)e.preventDefault(),S(e=>jc(d,e,-1));else if(e.key===`Home`)e.preventDefault(),S(jc(d,-1,1));else if(e.key===`End`)e.preventDefault(),S(jc(d,d.length,-1));else if(e.key===`Enter`||e.key===` `)e.preventDefault(),d[x]&&!d[x].disabled&&j(d[x].value);else if(e.key===`Tab`)b(!1);else if(e.key.length===1){let t=Date.now(),n=t-A.current.t<700?A.current.str+e.key:e.key;A.current={str:n,t};let r=d.findIndex(e=>e.label.toLowerCase().startsWith(n.toLowerCase()));r>=0&&S(r)}}},[y,r,d,x,j,M]),N=C&&C.bottomSpace<260&&C.topY>C.bottomSpace;return(0,D.jsxs)(D.Fragment,{children:[(0,D.jsxs)(`button`,{ref:O,type:`button`,disabled:r,title:o,\"aria-label\":l,\"aria-haspopup\":`listbox`,\"aria-expanded\":y,className:`tsel-trigger ${a}`,style:i,onClick:()=>y?b(!1):M(),onKeyDown:ee,...u,children:[(0,D.jsx)(`span`,{className:`tsel-label`,children:_?_.label:``}),(0,D.jsx)(`span`,{className:`tsel-caret`,\"aria-hidden\":!0,children:`▾`})]}),y&&C&&(0,Qo.createPortal)((0,D.jsx)(`div`,{ref:k,role:`listbox`,className:`tsel-pop`,style:{position:`fixed`,left:C.left,minWidth:C.width,maxWidth:Math.max(C.width,320),...N?{bottom:window.innerHeight-C.topY+4}:{top:C.top+4}},children:d.map((e,t)=>(0,D.jsxs)(`div`,{role:`option`,\"data-i\":t,\"aria-selected\":t===g,\"aria-disabled\":e.disabled||void 0,\"data-active\":t===x,className:`tsel-opt`,onMouseEnter:()=>S(t),onMouseDown:t=>{t.preventDefault(),e.disabled||j(e.value)},children:[(0,D.jsx)(`span`,{className:`tsel-check`,\"aria-hidden\":!0,children:t===g?`✓`:``}),(0,D.jsx)(`span`,{className:`tsel-opt-label`,children:e.label}),e.note&&(0,D.jsx)(`span`,{className:`tsel-note`,tabIndex:-1,title:e.note,\"aria-label\":e.note,onMouseDown:e=>{e.preventDefault(),e.stopPropagation()},onMouseEnter:t=>{let n=t.currentTarget.getBoundingClientRect();E({text:e.note,x:n.right+8,y:n.top+n.height/2})},onMouseLeave:()=>E(null),children:`ⓘ`})]},t))}),document.body),T&&(0,Qo.createPortal)((0,D.jsx)(`div`,{className:`tsel-tip`,style:{position:`fixed`,left:T.x,top:T.y,transform:`translateY(-50%)`},children:T.text}),document.body)]})}let Nc=[`Ken Burns`,`Pan Left`,`Pan Right`,`Push In`,`Pull Out`,`Tilt Up`,`Tilt Down`,`Drift`,`Locked Frame`],Pc=[`Slow`,`Medium`,`Fast`],Fc={Slow:8,Medium:5,Fast:3},Ic={\"Ken Burns\":`avp-kenburns`,\"Pan Left\":`avp-panleft`,\"Pan Right\":`avp-panright`,\"Push In\":`avp-pushin`,\"Pull Out\":`avp-pullout`,\"Tilt Up\":`avp-tiltup`,\"Tilt Down\":`avp-tiltdown`,Drift:`avp-kenburns`,\"Locked Frame\":null},Lc={brightness:0,contrast:0,saturation:0,exposure:0,highlights:0,shadows:0,temperature:0,tint:0,sharpen:0,blur:0},Rc={none:{},bw:{saturation:-100,contrast:12},vintage:{saturation:-28,temperature:26,contrast:-8,exposure:6,shadows:14},warm:{temperature:38,exposure:4},cool:{temperature:-38,exposure:3},highcontrast:{contrast:40,saturation:12},faded:{contrast:-24,exposure:14,saturation:-14,shadows:18},punch:{contrast:22,saturation:32,sharpen:25}},zc={none:`Original`,bw:`B&W`,vintage:`Vintage`,warm:`Warm`,cool:`Cool`,highcontrast:`High contrast`,faded:`Faded`,punch:`Punch`},Bc=[[`exposure`,`Exposure`],[`brightness`,`Brightness`],[`contrast`,`Contrast`],[`highlights`,`Highlights`],[`shadows`,`Shadows`],[`saturation`,`Saturation`],[`temperature`,`Temperature`],[`tint`,`Tint`],[`sharpen`,`Sharpen`],[`blur`,`Blur`]],Vc=[`Hanken Grotesk`,`Arial`,`Helvetica`,`Verdana`,`Tahoma`,`Trebuchet MS`,`Gill Sans`,`Georgia`,`Times New Roman`,`Garamond`,`Palatino Linotype`,`Baskerville`,`Courier New`,`Lucida Console`,`Impact`,`Arial Black`,`Bebas Neue`,`Oswald`,`Comic Sans MS`,`Brush Script MT`],Hc=[[`adjust`,`Adjust`],[`crop`,`Crop`],[`filters`,`Filters`],[`text`,`Text`],[`images`,`Images`]],Uc=(e,t,n)=>Math.min(n,Math.max(t,e)),Wc=e=>e<0?0:e>255?255:e,Gc=()=>`${Date.now()}-${Math.random().toString(36).slice(2,7)}`;function Kc(e,t,n,r){if(!(t<=0||n<=0)){if(r.brightness||r.contrast||r.saturation||r.exposure||r.highlights||r.shadows||r.temperature||r.tint){let i=e.getImageData(0,0,t,n),a=i.data,o=(1+r.brightness/100)*2**(r.exposure/120),s=1+r.contrast/100,c=1+r.saturation/100,l=r.temperature,u=r.tint,d=r.highlights,f=r.shadows;for(let e=0;e<a.length;e+=4){let t=a[e]*o,n=a[e+1]*o,r=a[e+2]*o;t=(t-128)*s+128,n=(n-128)*s+128,r=(r-128)*s+128;let i=.299*t+.587*n+.114*r;if(t=i+(t-i)*c,n=i+(n-i)*c,r=i+(r-i)*c,l&&(t+=l*.6,r-=l*.6),u&&(n-=u*.6,t+=u*.3,r+=u*.3),d||f){let e=.299*t+.587*n+.114*r;if(d&&e>128){let i=(e-128)/127;t+=d*i,n+=d*i,r+=d*i}if(f&&e<128){let i=(128-e)/128;t+=f*i,n+=f*i,r+=f*i}}a[e]=Wc(t),a[e+1]=Wc(n),a[e+2]=Wc(r)}e.putImageData(i,0,0)}r.sharpen>0&&qc(e,t,n,r.sharpen/100)}}function qc(e,t,n,r){let i=e.getImageData(0,0,t,n),a=e.createImageData(t,n),o=i.data,s=a.data,c=r,l=1+4*c,u=-c;for(let e=0;e<n;e++)for(let r=0;r<t;r++){let i=(e*t+r)*4;for(let a=0;a<3;a++){let c=i+a;if(r===0||e===0||r===t-1||e===n-1){s[c]=o[c];continue}let d=o[c]*l+o[c-4]*u+o[c+4]*u+o[c-t*4]*u+o[c+t*4]*u;s[c]=Wc(d)}s[i+3]=o[i+3]}e.putImageData(a,0,0)}function Jc(e){let t=Math.abs(e)*Math.PI/180;return Math.cos(t)+Math.sin(t)*1.9}function Yc(e,t,n,r,i){let a=n.adj||Lc,o=n.crop||{x:0,y:0,w:t.naturalWidth,h:t.naturalHeight};if(e.clearRect(0,0,r,i),e.save(),e.translate(r/2,i/2),e.rotate(n.rotation*Math.PI/180+n.straighten*Math.PI/180),e.scale(n.flipH?-1:1,n.flipV?-1:1),n.straighten){let t=Jc(n.straighten);e.scale(t,t)}let s=n.rotation%180!=0,c=s?i:r,l=s?r:i;a.blur>0&&(e.filter=`blur(${a.blur*c/o.w}px)`),e.drawImage(t,o.x,o.y,o.w,o.h,-c/2,-l/2,c,l),e.filter=`none`,e.restore(),Kc(e,r,i,a)}function Xc({url:e,title:t=`image`,projectAspect:n,projectId:r,onClose:i,onSaveVersion:a,beginVersionSave:o=null,motion:s=null,onMotionChange:c=null}){let l=typeof c==`function`,u=s?.effect||`Ken Burns`,d=s?.speed||`Slow`,[f,p]=(0,v.useState)(l?`motion`:`adjust`),[m,h]=(0,v.useState)(Lc),[g,_]=(0,v.useState)(`none`),[y,b]=(0,v.useState)(0),[x,S]=(0,v.useState)(0),[C,w]=(0,v.useState)(!1),[T,E]=(0,v.useState)(!1),[O,A]=(0,v.useState)(null),[j,M]=(0,v.useState)(null),[ee,N]=(0,v.useState)(`free`),[P,te]=(0,v.useState)([]),[ne,re]=(0,v.useState)([]),[F,I]=(0,v.useState)(null),[L,R]=(0,v.useState)(``),z=(0,v.useRef)(null);(0,v.useEffect)(()=>()=>{z.current?.ticket?.cancel(),z.current=null},[]),(0,v.useEffect)(()=>{let t=z.current;t&&e!==t.sourceUrl&&e!==t.expectedUrl&&(t.ticket?.cancel(),z.current=null,R(``))},[e]);let ie=(0,v.useRef)(null),[ae,oe]=(0,v.useState)(!1),B=(0,v.useRef)(null),V=(0,v.useRef)(null),se=(0,v.useRef)(new Map),ce=(0,v.useRef)(null),le=(0,v.useMemo)(()=>rc().filter(e=>e.type===`image`&&e.url),[]);(0,v.useEffect)(()=>{oe(!1);let t=new Image;t.crossOrigin=`anonymous`,t.onload=()=>{ie.current=t,oe(!0)},t.onerror=()=>{ac.alert(`Could not load this image for editing (it may be unavailable).`),i?.()},t.src=nc(e)},[e]);let ue=(0,v.useCallback)(()=>{let e=ie.current;if(!e)return{w:1,h:1};let t=O||{w:e.naturalWidth,h:e.naturalHeight};return Zc(y)?{w:t.h,h:t.w}:{w:t.w,h:t.h}},[O,y]),de=(0,v.useMemo)(()=>{let{w:e,h:t}=ue(),n=Math.min(1,880/Math.max(e,t));return{w:Math.max(1,Math.round(e*n)),h:Math.max(1,Math.round(t*n))}},[ue,ae]);(0,v.useEffect)(()=>{if(!ae||!B.current)return;let e=B.current;e.width=de.w,e.height=de.h,Yc(e.getContext(`2d`,{willReadFrequently:!0}),ie.current,{adj:m,rotation:y,straighten:x,flipH:C,flipV:T,crop:O,blur:m.blur},de.w,de.h)},[ae,de,m,y,x,C,T,O]);let fe=(e,t)=>{h(n=>({...n,[e]:t})),_(`none`)},pe=e=>{_(e),h({...Lc,...Rc[e]})},H=()=>{h(Lc),_(`none`),b(0),S(0),w(!1),E(!1),A(null),M(null)},me=(0,v.useMemo)(()=>{let e=[[`free`,`Free`],[1,`1:1`],[16/9,`16:9`],[9/16,`9:16`],[4/3,`4:3`],[3/2,`3:2`]],t=Qc(n);return t&&!e.some(([e])=>typeof e==`number`&&Math.abs(e-t)<.001)&&e.splice(1,0,[t,`Project (${n})`]),e},[n]),he=()=>{let e=ie.current;if(!e||!j){p(`adjust`);return}let t=O||{x:0,y:0,w:e.naturalWidth,h:e.naturalHeight},n=t.x+j.x*t.w,r=t.y+j.y*t.h;A({x:Math.round(n),y:Math.round(r),w:Math.round(j.w*t.w),h:Math.round(j.h*t.h)}),M(null),p(`adjust`)},ge=()=>{let e={id:Gc(),text:`Your text`,xf:.5,yf:.5,sizeF:.08,color:`#ffffff`,font:Vc[0],bold:!0,align:`center`};te(t=>[...t,e]),I({kind:`text`,id:e.id}),p(`text`)},_e=(e,t)=>te(n=>n.map(n=>n.id===e?{...n,...t}:n)),ve=e=>{te(t=>t.filter(t=>t.id!==e)),I(null)},ye=(0,v.useCallback)(e=>se.current.has(e)?Promise.resolve(se.current.get(e)):new Promise((t,n)=>{let r=new Image;r.crossOrigin=`anonymous`,r.onload=()=>{se.current.set(e,r),t(r)},r.onerror=n,r.src=nc(e)}),[]),be=async e=>{try{let t=await ye(e),n={id:Gc(),url:e,xf:.5,yf:.5,wf:.4,aspect:t.naturalWidth/t.naturalHeight,rotation:0,opacity:1,z:ne.length};re(e=>[...e,n]),I({kind:`overlay`,id:n.id})}catch{oc.error?.(`Could not load that image.`)}},xe=(e,t)=>re(n=>n.map(n=>n.id===e?{...n,...t}:n)),Se=e=>{re(t=>t.filter(t=>t.id!==e)),I(null)},Ce=(e,t)=>re(n=>{let r=[...n].sort((e,t)=>e.z-t.z),i=r.findIndex(t=>t.id===e),a=i+t;if(a<0||a>=r.length)return n;let o=r[i].z;return r[i].z=r[a].z,r[a].z=o,n.map(e=>e.id===r[i].id?{...e,z:r[i].z}:e.id===r[a].id?{...e,z:r[a].z}:e)}),U=e=>{let t=e.target.files?.[0];if(!t)return;let n=new FileReader;n.onload=()=>be(String(n.result)),n.readAsDataURL(t),e.target.value=``},we=(e,t,n)=>{e.stopPropagation(),I({kind:t,id:n});let r=V.current.getBoundingClientRect();ce.current={kind:t,id:n,rect:r},e.currentTarget.setPointerCapture?.(e.pointerId)},W=e=>{let t=ce.current;if(!t)return;let n=Uc((e.clientX-t.rect.left)/t.rect.width,0,1),r=Uc((e.clientY-t.rect.top)/t.rect.height,0,1);t.kind===`text`?_e(t.id,{xf:n,yf:r}):xe(t.id,{xf:n,yf:r})},Te=()=>{ce.current=null},Ee=(0,v.useRef)(null),G=e=>{if(f!==`crop`)return;let t=V.current.getBoundingClientRect(),n=Uc((e.clientX-t.left)/t.width,0,1),r=Uc((e.clientY-t.top)/t.height,0,1);Ee.current={rect:t,x0:n,y0:r},M({x:n,y:r,w:0,h:0})},De=e=>{let t=Ee.current;if(!t)return;let n=Uc((e.clientX-t.rect.left)/t.rect.width,0,1),r=Uc((e.clientY-t.rect.top)/t.rect.height,0,1),i=Math.min(t.x0,n),a=Math.min(t.y0,r),o=Math.abs(n-t.x0),s=Math.abs(r-t.y0),c=ee===`free`?null:Number(ee);c&&(s=o*(de.w/de.h)/c,a=t.y0<=r?t.y0:t.y0-s,a=Uc(a,0,1-s)),M({x:i,y:a,w:o,h:s})},Oe=()=>{Ee.current=null};async function ke(e=`image/png`){let t=ie.current,{w:n,h:r}=ue(),i=document.createElement(`canvas`);i.width=n,i.height=r;let a=i.getContext(`2d`,{willReadFrequently:!0});Yc(a,t,{adj:m,rotation:y,straighten:x,flipH:C,flipV:T,crop:O,blur:m.blur},n,r);let o=[...ne].sort((e,t)=>e.z-t.z);for(let e of o){let t=await ye(e.url),i=e.wf*n,o=i/(e.aspect||1);a.save(),a.globalAlpha=e.opacity,a.translate(e.xf*n,e.yf*r),a.rotate((e.rotation||0)*Math.PI/180),a.drawImage(t,-i/2,-o/2,i,o),a.restore()}for(let e of P){let t=e.sizeF*r;a.save(),a.font=`${e.bold?`bold `:``}${t}px \"${e.font}\", sans-serif`,a.fillStyle=e.color,a.textAlign=e.align,a.textBaseline=`middle`,a.shadowColor=`rgba(0,0,0,0.55)`,a.shadowBlur=t*.12,a.shadowOffsetY=t*.04;let i=String(e.text).split(`\n`);i.forEach((o,s)=>a.fillText(o,e.xf*n,e.yf*r+(s-(i.length-1)/2)*t*1.2)),a.restore()}return i.toDataURL(e,.92)}let Ae=async()=>{if(!a||z.current)return;let t={ticket:null,sourceUrl:e,expectedUrl:null};z.current=t,R(`Saving new version…`);try{t.ticket=o?.()||null,t.ticket?.check();let e=await ke(`image/png`);t.ticket?.check();let n=await Qs(e,t.ticket?{assertCurrent:t.ticket.check}:void 0);if(t.ticket?.check(),t.expectedUrl=n,await a(n,t.ticket),t.ticket?.finish(),z.current!==t)return;z.current=null,R(``),oc.success?.(`Saved as a new version. The original is still in the carousel.`),i?.()}catch(e){z.current===t&&ac.alert(`Save failed: ${String(e?.message||e)}`)}finally{t.ticket?.finish(),z.current===t&&(z.current=null,R(``))}},je=async e=>{R(`Exporting…`);try{let n=await ke(e),i=document.createElement(`a`);i.href=n,i.download=`${tc(t||`image`)}-edited.${e===`image/jpeg`?`jpg`:`png`}`,document.body.appendChild(i),i.click(),i.remove();try{let e=await Qs(n);ic({type:`image`,url:e,name:`${t} (edited)`,projectId:r,edited:!0}),oc.success?.(`Exported — downloaded and saved to project assets.`)}catch{oc.success?.(`Exported and downloaded.`)}}catch(e){ac.alert(`Export failed: ${String(e?.message||e)}`)}finally{R(``)}},Me=F?.kind===`text`?P.find(e=>e.id===F.id):null,Ne=F?.kind===`overlay`?ne.find(e=>e.id===F.id):null;return(0,Qo.createPortal)((0,D.jsx)(`div`,{style:Q.backdrop,children:(0,D.jsxs)(`div`,{style:Q.frame,children:[(0,D.jsxs)(`div`,{style:Q.top,children:[(0,D.jsxs)(`div`,{style:Q.brand,children:[`Image editor `,(0,D.jsx)(`span`,{style:Q.sub,children:t})]}),(0,D.jsxs)(`div`,{style:Q.topActions,children:[(0,D.jsx)(`button`,{type:`button`,className:`btn btn-secondary`,onClick:H,disabled:!!L,children:`Reset`}),a&&(0,D.jsx)(`button`,{type:`button`,className:`btn btn-primary`,onClick:Ae,disabled:!!L,children:`Save as new version`}),(0,D.jsx)(`button`,{type:`button`,className:`btn btn-secondary`,onClick:()=>je(`image/png`),disabled:!!L,children:`Export PNG`}),(0,D.jsx)(`button`,{type:`button`,className:`btn btn-secondary`,onClick:()=>je(`image/jpeg`),disabled:!!L,children:`Export JPG`}),(0,D.jsx)(`button`,{type:`button`,className:`btn-icon`,onClick:i,\"aria-label\":`Close`,\"data-icon-action\":`true`,title:`Close`,children:(0,D.jsx)(k,{name:`x`,size:14})})]})]}),(0,D.jsxs)(`div`,{style:Q.body,children:[(0,D.jsx)(`div`,{style:Q.tabs,children:(l?[[`motion`,`Motion`],...Hc]:Hc).map(([e,t])=>(0,D.jsx)(`button`,{style:{...Q.tab,...f===e?Q.tabActive:{}},onClick:()=>{p(e),e===`crop`&&!j&&M({x:.1,y:.1,w:.8,h:.8})},children:t},e))}),(0,D.jsx)(`div`,{style:Q.stageWrap,children:ae?(0,D.jsxs)(`div`,{ref:V,style:{...Q.stage,width:de.w,height:de.h},onPointerDown:f===`crop`?G:e=>{e.target===e.currentTarget&&I(null)},onPointerMove:e=>{W(e),De(e)},onPointerUp:()=>{Te(),Oe()},onPointerLeave:()=>{Te(),Oe()},children:[(0,D.jsx)(`canvas`,{ref:B,style:Q.canvas}),[...ne].sort((e,t)=>e.z-t.z).map(e=>(0,D.jsx)(`img`,{src:nc(e.url),alt:``,draggable:!1,onPointerDown:t=>we(t,`overlay`,e.id),style:{position:`absolute`,left:`${e.xf*100}%`,top:`${e.yf*100}%`,width:`${e.wf*100}%`,transform:`translate(-50%,-50%) rotate(${e.rotation}deg)`,opacity:e.opacity,cursor:`move`,userSelect:`none`,outline:F?.id===e.id?`2px solid var(--accent)`:`none`}},e.id)),P.map(e=>(0,D.jsx)(`div`,{onPointerDown:t=>we(t,`text`,e.id),style:{position:`absolute`,left:`${e.xf*100}%`,top:`${e.yf*100}%`,transform:`translate(-50%,-50%)`,cursor:`move`,userSelect:`none`,color:e.color,fontFamily:`\"${e.font}\", sans-serif`,fontWeight:e.bold?800:400,fontSize:e.sizeF*de.h,textAlign:e.align,whiteSpace:`pre`,lineHeight:1.2,textShadow:`0 2px 8px rgba(0,0,0,0.55)`,outline:F?.id===e.id?`2px solid var(--accent)`:`none`,padding:2},children:e.text},e.id)),f===`crop`&&j&&(0,D.jsx)(`div`,{style:{position:`absolute`,left:`${j.x*100}%`,top:`${j.y*100}%`,width:`${j.w*100}%`,height:`${j.h*100}%`,border:`2px solid var(--accent)`,boxShadow:`0 0 0 9999px rgba(0,0,0,0.45)`,pointerEvents:`none`}})]}):(0,D.jsx)(`div`,{style:Q.loading,children:(0,D.jsx)(`div`,{className:`spinner`,style:{width:28,height:28}})})}),(0,D.jsxs)(`div`,{style:Q.panel,children:[f===`motion`&&l&&(0,D.jsxs)(`div`,{style:Q.panelInner,children:[(0,D.jsx)(`style`,{children:`\n@keyframes avp-kenburns { 0%{transform:scale(1) translate(0,0)} 100%{transform:scale(1.18) translate(-3%,-2%)} }\n@keyframes avp-panleft { 0%{transform:scale(1.15) translate(4%,0)} 100%{transform:scale(1.15) translate(-4%,0)} }\n@keyframes avp-panright { 0%{transform:scale(1.15) translate(-4%,0)} 100%{transform:scale(1.15) translate(4%,0)} }\n@keyframes avp-pushin { 0%{transform:scale(1)} 100%{transform:scale(1.25)} }\n@keyframes avp-pullout { 0%{transform:scale(1.25)} 100%{transform:scale(1)} }\n@keyframes avp-tiltup { 0%{transform:scale(1.15) translate(0,4%)} 100%{transform:scale(1.15) translate(0,-4%)} }\n@keyframes avp-tiltdown { 0%{transform:scale(1.15) translate(0,-4%)} 100%{transform:scale(1.15) translate(0,4%)} }\n`}),(0,D.jsx)(`div`,{style:Q.panelTitle,children:`Motion`}),(0,D.jsx)(`div`,{style:Q.hint,children:`A still image with a pan or zoom — no video clip is generated. The motion plays in the final render.`}),(0,D.jsx)(`div`,{style:{overflow:`hidden`,borderRadius:8,border:`1px solid var(--border)`,aspectRatio:`16 / 9`,background:`#000`,margin:`8px 0`},children:(0,D.jsx)(`img`,{src:nc(e),alt:``,style:{width:`100%`,height:`100%`,objectFit:`cover`,...Ic[u]&&u!==`Locked Frame`?{animation:`${Ic[u]} ${Fc[d]||6}s ease-in-out infinite alternate`}:{}}})}),(0,D.jsx)(`div`,{style:{fontSize:11,opacity:.7,margin:`8px 0 4px`},children:`Effect`}),(0,D.jsx)(`div`,{style:Q.row2,children:Nc.map(e=>(0,D.jsx)(`button`,{style:{...Q.chip,...u===e?Q.chipActive:{}},onClick:()=>c({motionEffect:e}),children:e},e))}),(0,D.jsx)(`div`,{style:{fontSize:11,opacity:.7,margin:`12px 0 4px`},children:`Speed`}),(0,D.jsx)(`div`,{style:Q.row2,children:Pc.map(e=>(0,D.jsx)(`button`,{style:{...Q.chip,...d===e?Q.chipActive:{}},onClick:()=>c({motionSpeed:e}),children:e},e))})]}),f===`adjust`&&(0,D.jsxs)(`div`,{style:Q.panelInner,children:[(0,D.jsx)(`div`,{style:Q.panelTitle,children:`Adjustments`}),Bc.map(([e,t])=>(0,D.jsx)($c,{label:t,value:m[e],min:e===`blur`||e===`sharpen`?0:-100,max:100,onChange:t=>fe(e,t)},e))]}),f===`crop`&&(0,D.jsxs)(`div`,{style:Q.panelInner,children:[(0,D.jsx)(`div`,{style:Q.panelTitle,children:`Crop & transform`}),(0,D.jsx)(`div`,{style:Q.hint,children:`Drag on the image to set the crop.`}),(0,D.jsx)(`div`,{style:Q.row2,children:me.map(([e,t])=>(0,D.jsx)(`button`,{style:{...Q.chip,...String(ee)===String(e)?Q.chipActive:{}},onClick:()=>N(e),children:t},String(e)))}),(0,D.jsxs)(`div`,{style:Q.row2,children:[(0,D.jsx)(`button`,{style:Q.btn,onClick:he,children:`Apply crop`}),(0,D.jsx)(`button`,{style:Q.btn,onClick:()=>{A(null),M({x:.1,y:.1,w:.8,h:.8})},children:`Reset crop`})]}),(0,D.jsx)(`div`,{style:Q.divider}),(0,D.jsxs)(`div`,{style:Q.row2,children:[(0,D.jsx)(`button`,{style:Q.btn,onClick:()=>b(e=>(e+270)%360),children:`Rotate left`}),(0,D.jsx)(`button`,{style:Q.btn,onClick:()=>b(e=>(e+90)%360),children:`Rotate right`})]}),(0,D.jsxs)(`div`,{style:Q.row2,children:[(0,D.jsx)(`button`,{style:{...Q.btn,...C?Q.chipActive:{}},onClick:()=>w(e=>!e),children:`Flip H`}),(0,D.jsx)(`button`,{style:{...Q.btn,...T?Q.chipActive:{}},onClick:()=>E(e=>!e),children:`Flip V`})]}),(0,D.jsx)($c,{label:`Straighten`,value:x,min:-15,max:15,onChange:S})]}),f===`filters`&&(0,D.jsxs)(`div`,{style:Q.panelInner,children:[(0,D.jsx)(`div`,{style:Q.panelTitle,children:`Filters`}),(0,D.jsx)(`div`,{style:Q.row2,children:Object.keys(Rc).map(e=>(0,D.jsx)(`button`,{style:{...Q.chip,...g===e?Q.chipActive:{}},onClick:()=>pe(e),children:zc[e]},e))}),(0,D.jsx)(`div`,{style:Q.hint,children:`Filters set the adjustment sliders — fine-tune them in the Adjust tab.`})]}),f===`text`&&(0,D.jsxs)(`div`,{style:Q.panelInner,children:[(0,D.jsx)(`div`,{style:Q.panelTitle,children:`Text`}),(0,D.jsx)(`button`,{style:Q.btn,onClick:ge,children:`Add text`}),Me?(0,D.jsxs)(D.Fragment,{children:[(0,D.jsx)(`div`,{style:Q.divider}),(0,D.jsx)(`textarea`,{value:Me.text,onChange:e=>_e(Me.id,{text:e.target.value}),style:Q.textarea,rows:2}),(0,D.jsx)($c,{label:`Size`,value:Math.round(Me.sizeF*1e3),min:20,max:300,onChange:e=>_e(Me.id,{sizeF:e/1e3})}),(0,D.jsxs)(`label`,{style:Q.field,children:[`Color`,(0,D.jsx)(`input`,{type:`color`,value:Me.color,onChange:e=>_e(Me.id,{color:e.target.value})})]}),(0,D.jsxs)(`label`,{style:Q.field,children:[`Font`,(0,D.jsx)(Mc,{value:Me.font,onChange:e=>_e(Me.id,{font:e.target.value}),style:Q.select,children:Vc.map(e=>(0,D.jsx)(`option`,{value:e,children:e},e))})]}),(0,D.jsxs)(`div`,{style:Q.row2,children:[(0,D.jsx)(`button`,{style:{...Q.btn,...Me.bold?Q.chipActive:{}},onClick:()=>_e(Me.id,{bold:!Me.bold}),children:`Bold`}),[`left`,`center`,`right`].map(e=>(0,D.jsx)(`button`,{style:{...Q.btn,...Me.align===e?Q.chipActive:{}},onClick:()=>_e(Me.id,{align:e}),children:e[0].toUpperCase()},e))]}),(0,D.jsx)(`button`,{style:{...Q.btn,...Q.danger},onClick:()=>ve(Me.id),children:`Delete text`})]}):(0,D.jsx)(`div`,{style:Q.hint,children:`Add text, then drag it on the image. Select it to style.`})]}),f===`images`&&(0,D.jsxs)(`div`,{style:Q.panelInner,children:[(0,D.jsx)(`div`,{style:Q.panelTitle,children:`Add images`}),(0,D.jsxs)(`label`,{style:Q.btn,children:[`Upload from device`,(0,D.jsx)(`input`,{type:`file`,accept:`image/*`,onChange:U,style:{display:`none`}})]}),le.length>0&&(0,D.jsxs)(D.Fragment,{children:[(0,D.jsx)(`div`,{style:Q.hint,children:`From project assets`}),(0,D.jsx)(`div`,{style:Q.assetGrid,children:le.slice(0,24).map(e=>(0,D.jsx)(`img`,{src:nc(e.url),alt:``,style:Q.assetThumb,onClick:()=>be(e.url)},e.id||e.url))})]}),Ne?(0,D.jsxs)(D.Fragment,{children:[(0,D.jsx)(`div`,{style:Q.divider}),(0,D.jsx)($c,{label:`Size`,value:Math.round(Ne.wf*100),min:5,max:100,onChange:e=>xe(Ne.id,{wf:e/100})}),(0,D.jsx)($c,{label:`Rotate`,value:Ne.rotation,min:-180,max:180,onChange:e=>xe(Ne.id,{rotation:e})}),(0,D.jsx)($c,{label:`Opacity`,value:Math.round(Ne.opacity*100),min:0,max:100,onChange:e=>xe(Ne.id,{opacity:e/100})}),(0,D.jsxs)(`div`,{style:Q.row2,children:[(0,D.jsx)(`button`,{style:Q.btn,onClick:()=>Ce(Ne.id,1),children:`Bring forward`}),(0,D.jsx)(`button`,{style:Q.btn,onClick:()=>Ce(Ne.id,-1),children:`Send back`})]}),(0,D.jsx)(`button`,{style:{...Q.btn,...Q.danger},onClick:()=>Se(Ne.id),children:`Remove image`})]}):(0,D.jsx)(`div`,{style:Q.hint,children:`Add an image, then drag it on the canvas. Select it to resize, rotate, layer.`})]})]})]}),L&&(0,D.jsxs)(`div`,{style:Q.busy,children:[(0,D.jsx)(`div`,{className:`spinner`,style:{width:22,height:22}}),(0,D.jsx)(`span`,{children:L})]})]})}),document.body)}function Zc(e){return e%180!=0}function Qc(e){if(!e)return null;let t=String(e).match(/^(\\d+(?:\\.\\d+)?)\\s*:\\s*(\\d+(?:\\.\\d+)?)$/);if(t)return Number(t[1])/Number(t[2]);let n=Number(e);return Number.isFinite(n)&&n>0?n:null}function $c({label:e,value:t,min:n,max:r,onChange:i}){return(0,D.jsxs)(`label`,{style:Q.sliderRow,children:[(0,D.jsxs)(`span`,{style:Q.sliderLabel,children:[e,(0,D.jsx)(`span`,{style:Q.sliderVal,children:t})]}),(0,D.jsx)(`input`,{type:`range`,min:n,max:r,value:t,onChange:e=>i(Number(e.target.value)),style:Q.range})]})}let Q={backdrop:{position:`fixed`,inset:0,zIndex:10001,background:`rgba(0,0,0,0.9)`,display:`flex`,alignItems:`center`,justifyContent:`center`,padding:16},frame:{width:`100%`,height:`100%`,maxWidth:1400,maxHeight:`95vh`,background:`var(--bg-secondary, #161616)`,border:`1px solid var(--border, #2a2a2a)`,borderRadius:12,display:`flex`,flexDirection:`column`,overflow:`hidden`,position:`relative`},top:{display:`flex`,alignItems:`center`,justifyContent:`space-between`,padding:`10px 14px`,borderBottom:`1px solid var(--border, #2a2a2a)`},brand:{fontSize:14,fontWeight:800,color:`var(--text-primary, #f0f0f0)`},sub:{fontSize:12,fontWeight:400,color:`var(--text-muted, #888)`,marginLeft:8},topActions:{display:`flex`,gap:8,alignItems:`center`},body:{flex:1,display:`flex`,minHeight:0},tabs:{width:96,borderRight:`1px solid var(--border,#2a2a2a)`,display:`flex`,flexDirection:`column`,padding:8,gap:4},tab:{background:`transparent`,border:`none`,color:`var(--text-muted,#999)`,padding:`10px 8px`,borderRadius:7,fontSize:13,cursor:`pointer`,textAlign:`left`},tabActive:{background:`rgba(255,255,255,0.08)`,color:`var(--text-primary,#fff)`,fontWeight:700},stageWrap:{flex:1,display:`flex`,alignItems:`center`,justifyContent:`center`,padding:16,minWidth:0,overflow:`hidden`,background:`var(--bg-primary,#0e0e0e)`},stage:{position:`relative`,touchAction:`none`,boxShadow:`0 8px 40px rgba(0,0,0,0.6)`},canvas:{display:`block`,width:`100%`,height:`100%`,borderRadius:4},loading:{display:`flex`,alignItems:`center`,justifyContent:`center`,width:`100%`,height:`100%`},panel:{width:280,borderLeft:`1px solid var(--border,#2a2a2a)`,overflow:`auto`},panelInner:{padding:14,display:`flex`,flexDirection:`column`,gap:10},panelTitle:{fontSize:13,fontWeight:800,color:`var(--text-primary,#f0f0f0)`},hint:{fontSize:11,color:`var(--text-muted,#888)`,lineHeight:1.5},divider:{height:1,background:`var(--border,#2a2a2a)`,margin:`4px 0`},row2:{display:`flex`,flexWrap:`wrap`,gap:6},btn:{flex:1,minWidth:70,background:`rgba(255,255,255,0.07)`,color:`var(--text-primary,#eee)`,border:`1px solid var(--border,#2a2a2a)`,borderRadius:7,padding:`8px 10px`,fontSize:12,cursor:`pointer`,textAlign:`center`},chip:{background:`rgba(255,255,255,0.07)`,color:`var(--text-secondary,#ccc)`,border:`1px solid var(--border,#2a2a2a)`,borderRadius:14,padding:`6px 12px`,fontSize:12,cursor:`pointer`},chipActive:{background:`var(--accent,#c33)`,color:`var(--accent-contrast,#fff)`,borderColor:`transparent`},danger:{color:`#ff7a7a`,borderColor:`rgba(255,80,80,0.4)`},sliderRow:{display:`flex`,flexDirection:`column`,gap:4},sliderLabel:{display:`flex`,justifyContent:`space-between`,fontSize:12,color:`var(--text-secondary,#bbb)`},sliderVal:{color:`var(--text-muted,#888)`},range:{width:`100%`},field:{display:`flex`,justifyContent:`space-between`,alignItems:`center`,fontSize:12,color:`var(--text-secondary,#bbb)`,gap:8},select:{background:`var(--bg-primary,#111)`,color:`var(--text-primary,#eee)`,border:`1px solid var(--border,#2a2a2a)`,borderRadius:6,padding:`4px 6px`,fontSize:12},textarea:{background:`var(--bg-primary,#111)`,color:`var(--text-primary,#eee)`,border:`1px solid var(--border,#2a2a2a)`,borderRadius:6,padding:6,fontSize:12,resize:`vertical`,fontFamily:`inherit`},assetGrid:{display:`grid`,gridTemplateColumns:`repeat(3,1fr)`,gap:6},assetThumb:{width:`100%`,aspectRatio:`1`,objectFit:`cover`,borderRadius:6,cursor:`pointer`,border:`1px solid var(--border,#2a2a2a)`},busy:{position:`absolute`,inset:0,background:`rgba(0,0,0,0.6)`,display:`flex`,alignItems:`center`,justifyContent:`center`,gap:10,color:`#fff`,fontSize:14,zIndex:5}};Object.freeze([`vectorize`,`upscale`,`off`]);function el(e){return I(e?.version===1&&typeof e.process==`function`,`HOST_SERVICES`,`Image Panels requires version 1 of its image processing service.`),e}let tl={chapterCard:{label:`Chapter card`,font:{family:`Georgia`,size:64,color:`#ffffff`,weight:700},animation:`fade`},minimal:{label:`Minimal`,font:{family:`Hanken Grotesk`,size:44,color:`#ffffff`,weight:400},animation:`none`},boldPunch:{label:`Bold punch`,font:{family:`Arial`,size:84,color:`#ffffff`,weight:800},animation:`rise`}},nl=Object.keys(tl),rl=[`fade`,`rise`,`none`];function il(e={}){let t=tl[e.template]||tl.chapterCard;return{template:tl[e.template]?e.template:`chapterCard`,text:e.text||null,font:{...t.font,...e.font||{}},animation:rl.includes(e.animation)?e.animation:t.animation,durationMs:Number(e.durationMs)>0?Number(e.durationMs):1500}}let al=null;function ol(e){al=e}let sl=new Map,cl=new Set;function ll(e){return cl.add(e),()=>{cl.delete(e)}}let ul=!1;function dl(){ul||(ul=!0,Promise.resolve().then(()=>{ul=!1;for(let e of cl)e()}))}function fl(e){return e&&sl.get(e)||null}function pl(e){let t=sl.get(e);return!!t&&(t.status===`planning`||t.status===`building`)}function ml(e){return!!sl.get(e)?.cancelled}let hl=()=>al&&al.epochRef?al.epochRef.current:0;function gl(e,t){al&&(al.projectIdRef&&al.projectIdRef.current!==e.projectId||al.epochRef&&al.epochRef.current!==e.epoch||t())}function _l(e,t,{save:n=!0,expectedJob:r=null}={}){let i=sl.get(e);!i||r&&i!==r||gl(i,()=>{al.setDoc(t),n&&al.scheduleSave&&al.scheduleSave()})}function vl(e,t,n=null,r=null){let i=sl.get(e);!i||r&&i!==r||(i.result=t,i.resultAdmission=n,gl(i,()=>{if(n){if(!n.canApply())return;al.setDoc(r=>sl.get(e)===i&&!i.cancelled&&(!al.epochRef||al.epochRef.current===i.epoch)&&n.canApply()&&JSON.stringify(r)===n.sourceFingerprint?t:r)}else al.setDoc(t);al.scheduleSave&&al.scheduleSave()}),dl())}function yl(e,t=null){let n=e&&sl.get(e);if(!n||!n.result)return null;let r=n.result;return n.resultAdmission?!t?.canEdit||t.actorId!==n.resultAdmission.actorId||n.resultAdmission.currentActor()!==t.actorId||!(t.document===r||JSON.stringify(t.document)===n.resultAdmission.sourceFingerprint&&t.inputFingerprint===n.resultAdmission.inputFingerprint)&&!t.reviewedResult||t.reviewedResult&&t.reviewedResult!==r?null:r:(n.result=null,dl(),r)}function bl(e){let t=sl.get(e);t&&(t.cancelled=!0,t.controller?.abort(),dl())}function xl(e,t){if(!t)return t;let n=e&&e.step===t.step&&e.startedAt!=null;return{...t,startedAt:n?e.startedAt:performance.now()}}function Sl(e,t,n=null){let r=sl.get(e);r&&(!n||r===n)&&(r.progress=xl(r.progress,t),dl())}function Cl(e,t=null,n=null){let r=sl.get(e);r&&(!n||r===n)&&(r.status=`idle`,r.progress=null,r.error=t||null,dl())}function wl(e,t,n,r={}){if(!e)return null;if(pl(e))return sl.get(e);let i={projectId:e,actorId:r.actorId||null,controller:r.controller||null,epoch:hl(),status:t,progress:null,cancelled:!1,error:null};sl.set(e,i),dl();let a={commitDoc:(t,n)=>_l(e,t,{...n,expectedJob:i}),shouldCancel:()=>sl.get(e)!==i||i.cancelled,setProgress:t=>Sl(e,t,i)};return Promise.resolve().then(()=>n(a)).then(()=>Cl(e,null,i)).catch(t=>Cl(e,t&&t.message?t.message:String(t),i)),i}let Tl=new WeakMap,El=[`status`,`progress`,`cancelled`,`error`,`result`,`resultAdmission`];function Dl(e){let t=fl(e);if(!t)return null;let n=Tl.get(t);if(n&&El.every(e=>n[e]===t[e]))return n;let r={...t};return Tl.set(t,r),r}function Ol(e){return(0,v.useSyncExternalStore)(ll,()=>Dl(e),()=>null)}function kl(e,t){let n=e&&sl.get(e),r=n?.resultAdmission;return n?.result&&r&&r.actorId===t&&r.currentActor()===t?n.result:null}function Al(e,t,n){let r=e&&sl.get(e),i=r?.resultAdmission;r?.result===t&&i?.actorId===n&&i.currentActor()===n&&(r.result=null,r.resultAdmission=null,dl())}function jl(e){return I(e?.version===1&&typeof e.list==`function`&&typeof e.save==`function`,`HOST_SERVICES`,`Styles require version 1 of the scoped library service.`),e}let Ml=(e,t,n)=>{let r=(n*e.width+t)*4;return[e.data[r],e.data[r+1],e.data[r+2]]},Nl=(e,t,n)=>Math.abs(e[0]-t[0])<=n&&Math.abs(e[1]-t[1])<=n&&Math.abs(e[2]-t[2])<=n;function Pl(e,{tolerance:t=14,minUniform:n=.97,topExclude:r=.16}={}){let{width:i,height:a}=e;if(!i||!a)return{color:[0,0,0],uniform:0,ok:!1};let o=Math.min(a-2,Math.round(a*r)),s=[];for(let t=0;t<i;t++)s.push(Ml(e,t,a-1));for(let t=Math.max(1,o);t<a-1;t++)s.push(Ml(e,0,t),Ml(e,i-1,t));let c=new Map;for(let e of s){let t=`${e[0]>>4},${e[1]>>4},${e[2]>>4}`,n=c.get(t)||{n:0,r:0,g:0,b:0};n.n++,n.r+=e[0],n.g+=e[1],n.b+=e[2],c.set(t,n)}let l=null;for(let e of c.values())(!l||e.n>l.n)&&(l=e);let u=[Math.round(l.r/l.n),Math.round(l.g/l.n),Math.round(l.b/l.n)],d=0;for(let e of s)Nl(e,u,t)&&d++;let f=d/s.length;return{color:u,uniform:f,ok:f>=n}}function Fl(e,{bg:t=null,tolerance:n=14,minArea:r=24,mergeGap:i=null}={}){let{width:a,height:o}=e,s=t||Pl(e,{tolerance:n}).color,c=i??Math.max(6,Math.round(Math.min(a,o)*.015)),l=new Uint8Array(a*o);for(let t=0;t<o;t++)for(let r=0;r<a;r++)Nl(Ml(e,r,t),s,n)||(l[t*a+r]=1);let u=new Uint8Array(a*o),d=[],f=new Int32Array(a*o),p=new Int32Array(a*o);for(let e=0;e<o;e++)for(let t=0;t<a;t++){let n=e*a+t;if(!l[n]||u[n])continue;let i=0,s=0;f[s]=t,p[s]=e,s++,u[n]=1;let c=t,m=t,h=e,g=e,_=0;for(;i<s;){let e=f[i],t=p[i];i++,_++,e<c&&(c=e),e>m&&(m=e),t<h&&(h=t),t>g&&(g=t);for(let n=-1;n<=1;n++)for(let r=-1;r<=1;r++){if(!r&&!n)continue;let i=e+r,c=t+n;if(i<0||c<0||i>=a||c>=o)continue;let d=c*a+i;l[d]&&!u[d]&&(u[d]=1,f[s]=i,p[s]=c,s++)}}_>=r&&d.push({x:c,y:h,w:m-c+1,h:g-h+1,area:_})}let m=(e,t)=>({dx:Math.max(0,Math.max(e.x,t.x)-Math.min(e.x+e.w,t.x+t.w)),dy:Math.max(0,Math.max(e.y,t.y)-Math.min(e.y+e.h,t.y+t.h))}),h=!0,g=d;for(;h;){h=!1;let e=[],t=Array(g.length).fill(!1);for(let n=0;n<g.length;n++){if(t[n])continue;let r={...g[n]};t[n]=!0;let i=!0;for(;i;){i=!1;for(let e=0;e<g.length;e++){if(t[e])continue;let n=m(r,g[e]);if(n.dx<=c&&n.dy<=c){let n=Math.max(r.x+r.w,g[e].x+g[e].w),a=Math.max(r.y+r.h,g[e].y+g[e].h);r.x=Math.min(r.x,g[e].x),r.y=Math.min(r.y,g[e].y),r.w=n-r.x,r.h=a-r.y,r.area+=g[e].area,t[e]=!0,i=!0,h=!0}}}e.push(r)}g=e}g=g.filter(e=>!(e.y<=2&&e.w>=a*.7));let _=Math.max(16,Math.round(o*.06));return g.sort((e,t)=>{let n=Math.round((e.y+e.h/2)/_),r=Math.round((t.y+t.h/2)/_);return n===r?e.x+e.w/2-(t.x+t.w/2):n-r}),g.map((e,t)=>({id:`e${t+1}`,box:{x:e.x,y:e.y,w:e.w,h:e.h},area:e.area}))}function Il(e,{expectedCount:t=null}={}){return e.length?t!=null&&e.length<t?{ok:!1,reason:`merged elements: detected ${e.length} blobs but the plan expects ${t} — elements are touching/overlapping (prompt failure; regenerate the base with stricter separation)`}:{ok:!0,reason:null}:{ok:!1,reason:`no elements detected — background sampling or generation failed`}}function Ll(e){return/not a flat solid color|no elements detected|merged elements/.test(String(e||``))}function Rl(e,t,n,{alwaysVisible:r=[]}={}){let i=new Set([...t.slice(0,Math.max(0,n)),...r]);return e.filter(e=>!i.has(e.id)).map(e=>e.box)}function zl(e,t,n){let r=Math.max(1,t+1);return Math.min(n,Math.max(1,Math.ceil((e+1)*n/r)))}function Bl(e,t,n,{pad:r=3}={}){let{width:i,height:a}=e,o={width:i,height:a,data:new Uint8ClampedArray(e.data)};for(let e of t){let t=Math.max(0,e.x-r),s=Math.max(0,e.y-r),c=Math.min(i-1,e.x+e.w-1+r),l=Math.min(a-1,e.y+e.h-1+r);for(let e=s;e<=l;e++)for(let r=t;r<=c;r++){let t=(e*i+r)*4;o.data[t]=n[0],o.data[t+1]=n[1],o.data[t+2]=n[2],o.data[t+3]=255}}return o}function Vl(e){let t=(Array.isArray(e?.elements)?e.elements:[]).filter(e=>e&&e.id&&e.box).map(e=>({id:String(e.id).slice(0,40),name:String(e.name||e.id).slice(0,120),box:{x:Math.max(0,Math.round(Number(e.box.x)||0)),y:Math.max(0,Math.round(Number(e.box.y)||0)),w:Math.max(1,Math.round(Number(e.box.w)||1)),h:Math.max(1,Math.round(Number(e.box.h)||1))},alwaysVisible:e.alwaysVisible===!0})),n=new Set(t.map(e=>e.id)),r=(Array.isArray(e?.order)?e.order:[]).map(e=>String(e)).filter(e=>n.has(e));for(let e of t)!r.includes(e.id)&&!e.alwaysVisible&&r.push(e.id);return{bg:Array.isArray(e?.bg)&&e.bg.length===3?e.bg.map(e=>Math.max(0,Math.min(255,Math.round(Number(e)||0)))):[0,0,0],elements:t,order:r}}let Hl=new Set([`the`,`a`,`an`,`to`,`of`,`and`,`or`,`in`,`on`,`for`,`with`,`into`]);function Ul(e,t,n){let r=new Map((Array.isArray(e)?e:[]).map(e=>[e.id,e])),i=(Array.isArray(t)?t:[]).filter(e=>r.has(e)),a=String(n||``).toLowerCase();if(!a)return i.slice();let o=e=>{let t=String(r.get(e)?.name||``).toLowerCase(),n=-1,i=t.trim();if(i){let e=a.indexOf(i);e!==-1&&(n=e)}for(let e of t.split(/[^a-z0-9]+/)){if(e.length<3||Hl.has(e))continue;let t=a.indexOf(e);t!==-1&&(n===-1||t<n)&&(n=t)}return n};return i.map((e,t)=>({id:e,at:o(e),i:t})).sort((e,t)=>e.at>=0&&t.at>=0?e.at-t.at||e.i-t.i:e.at>=0?-1:t.at>=0?1:e.i-t.i).map(e=>e.id)}async function Wl(e){let t=await new Promise((t,n)=>{let r=new Image;r.crossOrigin=`anonymous`,r.onload=()=>t(r),r.onerror=()=>n(Error(`could not load the base image`)),r.src=e}),n=document.createElement(`canvas`);n.width=t.naturalWidth,n.height=t.naturalHeight;let r=n.getContext(`2d`,{willReadFrequently:!0});return r.drawImage(t,0,0),r.getImageData(0,0,n.width,n.height)}function Gl(e){let t=document.createElement(`canvas`);return t.width=e.width,t.height=e.height,t.getContext(`2d`).putImageData(e instanceof ImageData?e:new ImageData(e.data,e.width,e.height),0,0),t.toDataURL(`image/png`)}async function Kl(e,t,{nameElements:n,upload:r,onProgress:i,prepareFrames:a,assertCurrent:o=()=>{},signal:s}={}){if(o(),typeof r!=`function`)throw Error(`buildRevealGroup: an upload function is required`);let c=e.strip.find(e=>e.panelId===t);if(!c||c.method!==`progressiveReveal`)return{doc:e,error:`no progressiveReveal base \"${t}\"`};if(!c.image)return{doc:e,error:`${t} has no image yet — build the strip first`};let l=e.strip.filter(e=>e.kind===`revealStep`&&e.revealOf===t).sort((e,t)=>Number(e.revealIndex)-Number(t.revealIndex));if(!l.length)return{doc:e,error:null};let u=await Wl(c.image);o();let d=Pl(u);if(!d.ok)return{doc:e,error:`the base image background is not a flat solid color — progressiveReveal needs one (regenerate the base, or switch this beat to edit-chain accumulation)`};let f=c.revealPlan||null,p=Array.isArray(f?.elements)&&f.elements.some(e=>e&&e.id&&e.box),m=[],h=null,g=``;if(!p){m=Fl(u,{bg:d.color});let t=Il(m,{expectedCount:l.length+1});if(!t.ok)return{doc:e,error:t.reason};if(g=[c,...l].map(t=>sr(e,t)).filter(Boolean).join(` `),typeof n==`function`)try{o(),h=await n({imageUrl:c.image,blobs:m.map(e=>({id:e.id,box:e.box})),narration:g}),o()}catch(e){if(o(),e?.name===`AbortError`)throw e;h=null}}let _,v;if(typeof a==`function`)o(),{plan:_,frames:v}=await a({plan:f,detected:m,named:h??null,narration:g,bg:d.color,stepCount:l.length},{signal:s,assertCurrent:o}),o();else{if(_=f?Vl(f):null,!_||!_.elements.length){let e=new Map((h?.elements||[]).map(e=>[e.id,e.name]));_=Vl({bg:d.color,elements:m.map(t=>({id:t.id,name:e.get(t.id)||t.id,box:t.box})),order:Array.isArray(h?.order)&&h.order.length?h.order:m.map(e=>e.id)}),_={..._,order:Ul(_.elements,_.order,g)}}let e=_.elements.filter(e=>!e.alwaysVisible).length;v=l.map((t,n)=>Rl(_.elements,_.order,zl(n,l.length,e),{alwaysVisible:_.elements.filter(e=>e.alwaysVisible).map(e=>e.id)}))}let y=ur(e,t,{revealPlan:_});for(let e=0;e<l.length;e++){o();let t=v[e],n=Bl(u,t,_.bg);o();let a=await r(Gl(n));o();let s=y.strip.find(t=>t.panelId===l[e].panelId);y=ur(y,l[e].panelId,{image:a,versions:lr(s,a)}),i?.({done:e+1,total:l.length})}return{doc:y,error:null}}function ql(e,t){let n=e.strip.find(e=>e.panelId===t);if(!n)return e;let r=String(n.prompt||``);return ur(e,t,{prompt:r.includes(`CRITICAL LAYOUT: draw each labeled element as its own fully SEPARATE piece with clear background gaps on all sides — no touching, no overlapping, and no lines, arrows, or connectors joining elements.`)?r:r+` CRITICAL LAYOUT: draw each labeled element as its own fully SEPARATE piece with clear background gaps on all sides — no touching, no overlapping, and no lines, arrows, or connectors joining elements.`,revealPlan:void 0})}function Jl(e){let t=new Set;for(let n of e?.strip||[])n.kind!==`revealStep`||n.image||t.add(n.revealOf);return[...t]}function Yl(e){return(e?.strip||[]).filter(t=>{if(t.type!==`zoom`)return!1;let n=e.strip.find(e=>e.panelId===t.sourcePanelId);return n&&$n(e.strip,n)?!t.zoom||!t.image:!1})}function Xl(e){return Yl(e).filter(e=>!e.zoom).length}async function Zl(e,{deps:t}={}){I(typeof t?.pickTarget==`function`&&typeof t?.cropUpload==`function`,`HOST_SERVICES`,`Zoom processing requires explicit target and crop services.`);let n={assertCurrent:()=>{},...t},r=e,i=0,a=0,o=[];n.assertCurrent();let s=n.preparePending?await n.preparePending(e):Yl(e);n.assertCurrent();for(let e of s)try{n.assertCurrent();let t=r.strip.find(t=>t.panelId===e.panelId),o=r.strip.find(e=>e.panelId===t.sourcePanelId),s=$n(r.strip,o),c=t.zoom,l=null,u=!!c;if(!c){let e=null;try{n.assertCurrent(),e=await n.pickTarget({imageUrl:s,voText:sr(r,t),panelText:String(o?.scene??o?.prompt??o?.changePrompt??``).slice(0,400)}),n.assertCurrent(),i++}catch(e){if(n.assertCurrent(),e?.name===`AbortError`)throw e}l=e,n.prepareTarget||(c={fx:Number.isFinite(Number(e?.fx))?Number(e.fx):50,fy:Number.isFinite(Number(e?.fy))?Number(e.fy):50,scale:Number.isFinite(Number(e?.scale))?Number(e.scale):wn,pickedBy:`vision`})}let d=n.prepareTarget?await n.prepareTarget(r,t.panelId,u?c:l,u):null;n.assertCurrent();let f=await n.cropUpload(s,d?d.rect:En(c),{assertCurrent:n.assertCurrent});if(n.assertCurrent(),!f)throw Error(`crop upload returned no url`);a++,r=d?d.apply(f):ur(r,t.panelId,{zoom:c,image:f})}catch(t){if(n.assertCurrent(),t?.name===`AbortError`)throw t;o.push({panelId:e.panelId,error:t?.message||String(t)})}return{doc:r,visionCalls:i,crops:a,failed:o}}function Ql({srcImage:e,initial:t,onApprove:n,onClose:r,busy:i=!1}){let[a,o]=(0,v.useState)(Number(t?.fx)||50),[s,c]=(0,v.useState)(Number(t?.fy)||50),[l,u]=(0,v.useState)(Number(t?.scale)||1.8),d=(0,v.useRef)(null),f=(0,v.useRef)(null),[p,m]=(0,v.useState)(!1);(0,v.useEffect)(()=>{let t=new Image;t.crossOrigin=`anonymous`,t.onload=()=>{f.current=t,m(!0)},t.src=e},[e]),(0,v.useEffect)(()=>{let e=d.current,t=f.current;if(!e||!t)return;let n=En({fx:a,fy:s,scale:l}),r=n.x*t.naturalWidth,i=n.y*t.naturalHeight,o=Math.max(1,n.w*t.naturalWidth),c=Math.max(1,n.h*t.naturalHeight),u=e.getContext(`2d`);u.clearRect(0,0,e.width,e.height),u.drawImage(t,r,i,o,c,0,0,e.width,e.height)},[a,s,l,p]);let h=En({fx:a,fy:s,scale:l});return(0,Qo.createPortal)((0,D.jsx)(`div`,{style:{position:`fixed`,inset:0,zIndex:1e3,background:`rgba(0,0,0,0.55)`,display:`flex`,alignItems:`center`,justifyContent:`center`,padding:16},onClick:i?void 0:r,children:(0,D.jsxs)(`div`,{style:{background:`var(--bg-primary)`,border:`1px solid var(--border)`,borderRadius:14,padding:14,width:`min(860px, 96vw)`,maxHeight:`92vh`,overflowY:`auto`,display:`flex`,flexDirection:`column`,gap:10},onClick:e=>e.stopPropagation(),children:[(0,D.jsxs)(`div`,{style:{display:`flex`,alignItems:`baseline`,gap:8,flexWrap:`wrap`},children:[(0,D.jsx)(`strong`,{style:{fontSize:13},children:`Override zoom`}),(0,D.jsx)(`span`,{style:{fontSize:11,color:`var(--text-secondary)`},children:`Click the frame to re-aim, set the amount, then approve the final framing.`})]}),(0,D.jsxs)(`div`,{style:{display:`flex`,gap:12,flexWrap:`wrap`},children:[(0,D.jsxs)(`div`,{style:{flex:`1 1 340px`,minWidth:280},children:[(0,D.jsx)(`div`,{style:{fontSize:10.5,fontWeight:700,color:`var(--text-secondary)`,marginBottom:4},children:`SOURCE — click where the zoom should land`}),(0,D.jsxs)(`div`,{style:{position:`relative`,cursor:`crosshair`},onClick:e=>{let t=e.currentTarget.getBoundingClientRect();o(Math.round((e.clientX-t.left)/t.width*100)),c(Math.round((e.clientY-t.top)/t.height*100))},children:[(0,D.jsx)(`img`,{src:e,alt:`zoom source`,style:{width:`100%`,borderRadius:8,display:`block`}}),(0,D.jsx)(`div`,{style:{position:`absolute`,left:`${h.x*100}%`,top:`${h.y*100}%`,width:`${h.w*100}%`,height:`${h.h*100}%`,border:`2px solid var(--accent)`,borderRadius:4,pointerEvents:`none`,boxShadow:`0 0 0 2000px rgba(0,0,0,0.35)`}}),(0,D.jsx)(`div`,{style:{position:`absolute`,left:`${a}%`,top:`${s}%`,width:8,height:8,marginLeft:-4,marginTop:-4,borderRadius:`50%`,background:`var(--accent)`,pointerEvents:`none`}})]}),(0,D.jsxs)(`label`,{style:{display:`flex`,alignItems:`center`,gap:8,fontSize:11,color:`var(--text-secondary)`,marginTop:8},children:[`Zoom amount`,(0,D.jsx)(`input`,{type:`range`,min:`1.2`,max:`3`,step:`0.05`,value:l,onChange:e=>u(Number(e.target.value)),style:{flex:1,accentColor:`var(--accent)`},disabled:i}),(0,D.jsxs)(`span`,{style:{fontVariantNumeric:`tabular-nums`,color:`var(--text-primary)`,width:40},children:[l.toFixed(2),`×`]})]})]}),(0,D.jsxs)(`div`,{style:{flex:`1 1 300px`,minWidth:260},children:[(0,D.jsx)(`div`,{style:{fontSize:10.5,fontWeight:700,color:`var(--text-secondary)`,marginBottom:4},children:`FINAL FRAMING — what the next edit builds on`}),(0,D.jsx)(`canvas`,{ref:d,width:640,height:360,style:{width:`100%`,borderRadius:8,border:`1px solid var(--border)`,display:`block`,background:`#000`}}),(0,D.jsx)(`div`,{style:{fontSize:10.5,color:`var(--text-secondary)`,marginTop:6,lineHeight:1.5},children:`Approving replaces the vision-picked zoom with this framing and re-cuts the hand-off frame. You'll then choose whether the rest of the progression regenerates from it.`})]})]}),(0,D.jsxs)(`div`,{style:{display:`flex`,gap:8,justifyContent:`flex-end`},children:[(0,D.jsx)(`button`,{className:`btn btn-secondary`,\"data-compact\":!0,style:{fontSize:11.5},onClick:r,disabled:i,children:`Cancel`}),(0,D.jsx)(`button`,{className:`btn btn-primary`,\"data-compact\":!0,style:{fontSize:11.5},onClick:()=>n({fx:a,fy:s,scale:l}),disabled:i||!p,children:i?`Applying…`:`Approve this framing`})]})]})}),document.body)}let $l=e=>`${(Number(e)/1e3).toFixed(2)}s`;function eu({doc:e,fromPanelId:t,onConfirm:n,onClose:r,pending:i=!1,error:a=``}){let o=e.strip,s=o.findIndex(e=>e.panelId===t),c=(0,v.useMemo)(()=>{let e=o[s]?.sceneId,t=[];for(let n=s;n<o.length&&t.length<12&&o[n].sceneId===e;n++)t.push(o[n]);return t},[o,s]),[l,u]=(0,v.useState)(t),d=c.findIndex(e=>e.panelId===l),f=c.slice(0,Math.max(0,d)+1),p=f.map(e=>e.panelId),m=(0,v.useMemo)(()=>{try{return Mn(o,Nn(o,t,l))}catch{return[{reason:`invalid range`}]}},[o,t,l]),h=f.reduce((e,t)=>e+Number(t.durationMs),0),g=f.filter(e=>!!$n(o,e)).length,_=m.length>0;return(0,Qo.createPortal)((0,D.jsx)(`div`,{style:{position:`fixed`,inset:0,zIndex:1e3,background:`rgba(0,0,0,0.55)`,display:`flex`,alignItems:`center`,justifyContent:`center`,padding:16},onClick:r,children:(0,D.jsxs)(`div`,{style:{background:`var(--bg-primary)`,border:`1px solid var(--border)`,borderRadius:14,padding:14,width:`min(720px, 96vw)`,maxHeight:`92vh`,overflowY:`auto`,display:`flex`,flexDirection:`column`,gap:10},onClick:e=>e.stopPropagation(),children:[(0,D.jsxs)(`div`,{children:[(0,D.jsx)(`strong`,{style:{fontSize:13},children:`Add a collage canvas`}),(0,D.jsx)(`div`,{style:{fontSize:11,color:`var(--text-secondary)`,marginTop:3,lineHeight:1.5},children:`Pick how far it runs — the canvas takes over these beats and their combined time. Frames you've already generated come in as canvas images at their own moments, and you can revert to these panels any time.`})]}),(0,D.jsx)(`div`,{style:{display:`flex`,flexDirection:`column`,gap:4},children:c.map((e,t)=>{let n=t<=Math.max(0,d),r=$n(o,e),a=m.find(t=>t.panelId===e.panelId);return(0,D.jsxs)(`button`,{type:`button`,disabled:i,onClick:()=>u(e.panelId),title:a?a.reason:`Run the canvas through ${e.panelId}`,style:{display:`flex`,alignItems:`center`,gap:8,padding:`5px 8px`,borderRadius:7,textAlign:`left`,border:n?`1px solid var(--accent)`:`1px solid var(--border)`,background:n?`color-mix(in oklab, var(--accent) 12%, var(--bg-secondary))`:`var(--bg-secondary)`,cursor:`pointer`,opacity:n&&a?.65:1},children:[r?(0,D.jsx)(`img`,{src:r,alt:``,style:{width:40,height:24,objectFit:`cover`,borderRadius:3,flexShrink:0}}):(0,D.jsx)(`span`,{style:{width:40,height:24,borderRadius:3,border:`1px dashed var(--border)`,flexShrink:0}}),(0,D.jsx)(`strong`,{style:{fontSize:11.5,minWidth:46},children:e.panelId}),(0,D.jsxs)(`span`,{style:{fontSize:10.5,color:`var(--text-secondary)`},children:[e.type===`giphy`?`GIF`:e.type===`zoom`?`zoom`:e.kind||e.type,` · `,$l(e.durationMs)]}),(0,D.jsx)(`span`,{style:{flex:1}}),a&&(0,D.jsxs)(`span`,{style:{fontSize:10,color:`#d97706`},children:[`can't absorb — `,a.reason]}),n&&!a&&(0,D.jsx)(`span`,{style:{fontSize:10,color:`var(--accent)`,fontWeight:700},children:`in canvas`})]},e.panelId)})}),(0,D.jsxs)(`div`,{style:{fontSize:11.5,color:`var(--text-primary)`,background:`var(--bg-secondary)`,border:`1px solid var(--border)`,borderRadius:8,padding:`7px 10px`},children:[`Canvas: `,(0,D.jsxs)(`strong`,{children:[p.length,` beat`,p.length===1?``:`s`,` · `,$l(h)]}),g>0&&(0,D.jsxs)(D.Fragment,{children:[` · `,(0,D.jsxs)(`strong`,{children:[g,` image`,g===1?``:`s`]}),` carried in`]}),_&&(()=>{let e=m[0];c.findIndex(t=>t.panelId===e.panelId);let n=/re-shows|reveals|pushes into/.test(e.reason||``),r=e.panelId===t&&!n?`Start the canvas on a different beat`:n?`Extend the range to include what points at it`:`Stop before ${e.panelId}`;return(0,D.jsxs)(`div`,{style:{color:`#d97706`,marginTop:3},children:[r,` — `,e.panelId?`${e.panelId}: `:``,e.reason,`.`]})})()]}),i&&(0,D.jsx)(`p`,{role:`status`,children:`Creating the canvas and arranging its carried images…`}),a&&(0,D.jsx)(`p`,{role:`alert`,children:a}),(0,D.jsxs)(`div`,{style:{display:`flex`,gap:8,justifyContent:`flex-end`},children:[(0,D.jsx)(`button`,{className:`btn btn-secondary`,\"data-compact\":!0,style:{fontSize:11.5},onClick:r,children:`Cancel`}),(0,D.jsxs)(`button`,{className:`btn btn-primary`,\"data-compact\":!0,style:{fontSize:11.5},disabled:i||_||!p.length,onClick:()=>n(t,l),children:[`Add canvas over `,p.length,` beat`,p.length===1?``:`s`]})]})]})}),document.body)}function tu(e){let t=[];for(let n of e?.strip||[])if(n.type===`canvas`)for(let e of n.elements||[])e.kind===`image`&&!e.src&&String(e.query||``).trim()&&e.source!==`generated`&&t.push({panelId:n.panelId,elementId:e.id,query:String(e.query).trim()});return t}async function nu(e,{deps:t}={}){I(typeof t?.autoFind==`function`,`HOST_SERVICES`,`Canvas stock sourcing requires an explicitly supplied host service.`);let n={assertCurrent:()=>{},...t};n.assertCurrent();let r=e,i=0,a=[],o=new Map;for(let e of r.strip||[])e.type===`canvas`&&o.set(e.panelId,(e.elements||[]).map(e=>e.src).filter(Boolean));let s=tu(e);if(n.applyElement&&s.length>1024)throw Error(`This canvas stock pass exceeds 1,024 pending elements.`);for(let e of s)try{n.assertCurrent(),n.checkElement?.(r,e.panelId,e.elementId);let t=o.get(e.panelId)||[],s=await n.autoFind({queries:[e.query],description:e.query,kind:`photo`,excludeUrls:t});n.assertCurrent();let c=s?.result?.url||null;if(!c){a.push({...e,reason:s?.noMatch?`no match`:s?.transient?`sources busy`:`unavailable`});continue}t.push(c),o.set(e.panelId,t),r=n.applyElement?await n.applyElement(r,e.panelId,e.elementId,c):Ln(r,e.panelId,e.elementId,{src:c,source:`stock`}),n.assertCurrent(),i++}catch(t){if(n.assertCurrent(),t?.name===`AbortError`)throw t;a.push({...e,reason:t?.message||String(t)})}return{doc:r,sourced:i,failed:a}}function ru(e){return I(e?.version===1&&[`actor`,`stockStatus`,`stockGrid`,`stockSelect`,`upload`,`generateImage`,`generateVideo`,`imageCost`,`videoCost`].every(t=>typeof e[t]==`function`),`HOST_SERVICES`,`Canvas media requires version 1 of its declared host services.`),e}let iu=()=>Object.assign(Error(`The Canvas or account changed. Choose media again.`),{name:`AbortError`});function au({host:e,doc:t,projectId:n,panelId:r,canEdit:i}){let a=ru(e),o=a.actor(),s=(0,v.useRef)(null),c=(0,v.useRef)(null),l=(0,v.useRef)(!0);return s.current={services:a,actor:o,doc:t,projectId:n,panelId:r,canEdit:i},(0,v.useEffect)(()=>(l.current=!0,()=>{l.current=!1,c.current?.abort()}),[]),(0,v.useEffect)(()=>{c.current?.abort()},[a,o,t,n,r,i]),{services:a,run:async e=>{let i=s.current;if(i.services!==a||i.doc!==t||i.actor!==o||i.projectId!==n||i.panelId!==r)throw iu();if(c.current)throw Error(`Wait for the current media request to finish.`);let u=new AbortController,d=JSON.stringify(i.doc),f=()=>{let e=s.current;if(!l.current||u.signal.aborted||!i.canEdit||!e.canEdit||!i.actor||a.actor()!==i.actor||e.actor!==i.actor||e.services!==i.services||e.projectId!==i.projectId||e.panelId!==i.panelId||JSON.stringify(e.doc)!==d||JSON.stringify(i.doc)!==d)throw iu()};f(),c.current=u;try{return await e({signal:u.signal,assertCurrent:f})}finally{c.current===u&&(c.current=null)}},actor:o}}let ou={manifest:{schemaVersion:1,sdkVersion:`0.1.0`,id:`stillmade-internal.canvas-background`,version:`1.0.0`,name:`Canvas background`,description:`Apply a background preset or edit one animated palette colour.`,kind:`task`,runtime:`javascript`,inputs:{doc:{type:`json`},command:{type:`json`}},outputs:{edit:{type:`json`}},permissions:{project:[],network:[],filesystem:[],secrets:[]}},code:`const GRID_DEF = ['#0a1a3f', '#3b7dff'];\nconst BOKEH_DEF = ['#0b1226', '#96beff'];\nconst PAPER_DEF = ['#e8e4da', '#57503f'];\n\n// Registry: key → { label, draw, css, tunable? }. \\`css\\` is a static approximation\n// for the picker swatch (a CSS background can't animate); the canvas paints the\n// real thing. \\`tunable\\` (Grid, Bokeh) declares the editable colour slots the\n// picker exposes. Order here is the order they appear in the background picker.\nconst ANIMATED_BACKGROUNDS = {\n grid: { label: 'Blue Grid', css: 'linear-gradient(180deg, #0a1a3f, #123a8a)',\n tunable: [{ key: 'base', label: 'Background', default: GRID_DEF[0] }, { key: 'accent', label: 'Grid & glow', default: GRID_DEF[1] }] },\n aurora: { label: 'Aurora', css: 'radial-gradient(circle at 35% 40%, rgba(90,220,200,0.7), rgba(140,90,240,0.5) 45%, #0b1030 80%)' },\n mesh: { label: 'Mesh', css: 'radial-gradient(circle at 30% 30%, rgba(255,120,80,0.7), rgba(120,90,255,0.5) 55%, #2a0f3a 85%)' },\n bokeh: { label: 'Bokeh', css: 'radial-gradient(circle at 60% 70%, rgba(150,190,255,0.5), #152244 70%)',\n tunable: [{ key: 'base', label: 'Background', default: BOKEH_DEF[0] }, { key: 'accent', label: 'Dots', default: BOKEH_DEF[1] }] },\n waves: { label: 'Waves', css: 'linear-gradient(180deg, #0a2e4a 40%, rgba(40,190,180,0.6) 70%, #04122a)' },\n paper: { label: 'Paper', css: 'linear-gradient(180deg, #e8e4da, #ded9cd)',\n tunable: [{ key: 'base', label: 'Paper', default: PAPER_DEF[0] }, { key: 'accent', label: 'Grid & flecks', default: PAPER_DEF[1] }] },\n};\n\nfunction parseAnimatedBackground(val) {\n if (typeof val !== 'string' || !val.startsWith('anim|')) return null;\n const [, key, ...colors] = val.split('|');\n if (!ANIMATED_BACKGROUNDS[key]) return null;\n return { key, colors };\n}\n\nfunction withAnimatedColor(val, slotIndex, hex) {\n const parsed = parseAnimatedBackground(val);\n const tunable = parsed && ANIMATED_BACKGROUNDS[parsed.key].tunable;\n if (!tunable) return val;\n const colors = tunable.map((slot, i) => (i === slotIndex ? hex : (parsed.colors[i] || slot.default)));\n return \\`anim|\\${parsed.key}|\\${colors.join('|')}\\`;\n}\n\nfunction updatePanel(doc, panelId, patch) {\n const strip = doc.strip.map((p) => (p.panelId === panelId ? { ...p, ...patch, provenance: patch.provenance || 'user' } : p));\n return loadPanelDoc({ ...doc, strip });\n}\nconst loadPanelDoc=doc=>doc;\nconst panel=input.doc.strip[0];\nconst background=input.command.kind==='color'?withAnimatedColor(panel.background,input.command.slot,input.command.value):input.command.value;\nreturn {edit:updatePanel(input.doc,panel.panelId,{background})};\n`,tests:[]};function su(e,t,n){let r=e.strip.find(e=>e.panelId===t);I(r?.type===`canvas`&&L(n)&&[`set`,`color`].includes(n.kind)&&typeof n.value==`string`&&n.value.length<=512,`CANVAS_BACKGROUND`,`Choose a supported canvas background.`);let i=/^#[0-9a-f]{6}$/i.test(n.value);n.kind===`set`?I(Object.keys(n).length===2&&(i||wt.some(e=>e.value===n.value)),`CANVAS_BACKGROUND`,`Choose a background preset or colour.`):I(Object.keys(n).length===3&&i&&Number.isSafeInteger(n.slot)&&n.slot>=0&&mt(r.background)?.[n.slot],`CANVAS_BACKGROUND`,`Choose an editable background colour slot.`);let a={doc:{strip:[{panelId:t,type:`canvas`,...r.background===void 0?{}:{background:r.background}}]},command:{...n}};return B(a),I(JSON.stringify(a).length<=4096,`CANVAS_BACKGROUND`,`The saved background is too large.`),{panel:r,input:a}}function cu(e,{panel:t,input:n},r){let i=n.command,a=i.kind===`color`?gt(t.background,i.slot,i.value):i.value,o={strip:[{...n.doc.strip[0],background:a,provenance:`user`}]};if(B(r),I(V(r)===V(o),`CANVAS_BACKGROUND`,`The sandbox changed unrequested background settings.`),t.background===a&&t.provenance===`user`)return e;let s={...t,background:a,provenance:`user`};return{...e,strip:e.strip.map(e=>e===t?s:e)}}function lu({doc:e,projectId:t,panelId:n,canEdit:r,onDocChange:i,validateDocument:a,editLease:o,host:s}){let c=H(s),l=()=>c.actor(),[u,d]=(0,v.useState)(null),[f,p]=(0,v.useState)(``),m=(0,v.useRef)(null),h=(0,v.useRef)(!0),g=(0,v.useRef)(0),_=(0,v.useRef)(null),y=l();_.current={doc:e,projectId:t,panelId:n,canEdit:r,onDocChange:i,validateDocument:a,actor:y,services:c};let b=(0,v.useCallback)(()=>{g.current++,o?.current===m.current&&(o.current=null),m.current?.abort(),m.current=null,d(null)},[o]);return(0,v.useEffect)(()=>(h.current=!0,()=>{h.current=!1,g.current++,o?.current===m.current&&(o.current=null),m.current?.abort(),m.current=null}),[]),(0,v.useEffect)(()=>{b()},[e,t,n,r,y,c,b]),{change:(0,v.useCallback)(async r=>{let i=_.current;if(!i.doc||!i.canEdit||m.current||o?.current)return;if(i.services!==c||i.doc!==e||i.projectId!==t||i.panelId!==n||i.actor!==y||l()!==y){p(`The canvas changed. Review the canvas background again.`);return}let a=++g.current,s=new AbortController;m.current=s,o&&(o.current=s),d(i.panelId),p(``);let u,f=()=>{let e=_.current;I(h.current&&m.current===s&&!s.signal.aborted&&e.doc===i.doc&&e.projectId===i.projectId&&e.panelId===i.panelId&&e.canEdit&&e.services===c&&e.actor===i.actor&&l()===i.actor&&JSON.stringify(i.doc)===u,`STALE`,`The canvas changed. Review the current background settings again.`)};try{u=JSON.stringify(i.doc);let e=su(i.doc,i.panelId,r);f();let t=await c.run(ou,{kind:`run`,input:e.input,signal:s.signal,timeoutMs:15e3});f();let n=cu(i.doc,e,t.outputs?.edit),o=n===i.doc?i.doc:i.validateDocument(n);if(f(),o!==i.doc){let e=JSON.stringify(o),t=!1;i.onDocChange(n=>{let r=_.current,d=!1;try{d=h.current&&g.current===a&&!s.signal.aborted&&r.doc===i.doc&&r.projectId===i.projectId&&r.panelId===i.panelId&&r.canEdit&&r.services===c&&r.actor===i.actor&&l()===i.actor&&JSON.stringify(o)===e&&JSON.stringify(n)===u&&JSON.stringify(i.doc)===u}catch{}return d?o:(t||(t=!0,queueMicrotask(()=>{h.current&&l()===i.actor&&_.current.projectId===i.projectId&&p(`The canvas changed before the canvas background could be saved. Review the current background settings again.`)})),n)})}return o}catch(e){h.current&&!s.signal.aborted&&l()===i.actor&&_.current.projectId===i.projectId&&p(e.message||`The canvas background could not be applied.`)}finally{m.current===s&&(o?.current===s&&(o.current=null),m.current=null,h.current&&d(null))}},[e,t,n,y,c]),pending:u,error:f,cancel:b}}let uu={manifest:{schemaVersion:1,sdkVersion:`0.1.0`,id:`stillmade-internal.canvas-tidy`,version:`1.0.0`,name:`Canvas Tidy`,description:`Arrange a manual canvas once, preserving its pins and timing.`,kind:`task`,runtime:`javascript`,inputs:{panel:{type:`json`},aspect:{type:`number`}},outputs:{edit:{type:`json`}},permissions:{project:[],network:[],filesystem:[],secrets:[]}},code:`const hash = (s) => {\n let h = 5381;\n const str = String(s || '');\n for (let i = 0; i < str.length; i++) h = ((h << 5) + h + str.charCodeAt(i)) >>> 0;\n return h;\n};\n// Deterministic pseudo-jitter in [-1, 1] from an id + salt.\nconst jitter = (id, salt) => ((hash(\\`\\${id}|\\${salt}\\`) % 2000) / 1000) - 1;\n\n// ── Self-arranging layout (S10) ──────────────────────────────────────────────\n// Applies to AUTO-ARRANGED canvases only (panel.autoArrange). Deterministic\n// greedy placement in APPEAR ORDER: each unpinned image takes the best slot on\n// a golden-angle spiral around the canvas center — maximizing distance from\n// every element already visible when it appears — so the composition stays\n// balanced as it accumulates without ever moving an already-placed element\n// (tidy-by-construction; nothing jumps). PINNED elements (user overrides) and\n// manual canvases keep their positions exactly; auto elements arrange AROUND\n// pinned ones (they're obstacles in the distance test).\nconst SPIRAL_SLOTS = 48;\nconst GOLDEN = 2.399963229728653; // golden angle (rad)\nfunction spiralSlot(k, aspect = 16 / 9) {\n // Slots sweep outward from the center, filling the frame evenly; x spread is\n // wider than y for landscape canvases.\n const r = 0.08 + 0.40 * Math.sqrt((k + 0.5) / SPIRAL_SLOTS);\n const a = k * GOLDEN;\n return { x: 0.5 + r * Math.cos(a), y: 0.5 + r * Math.sin(a) * (aspect > 1 ? 0.9 : 1.1) };\n}\nconst clamp01 = (v, lo, hi) => Math.max(lo, Math.min(hi, v));\n\nfunction arrangeCanvas(panel, { aspect = 16 / 9 } = {}) {\n const els = (panel?.elements || []).slice().sort((a, b) => (a.appearMs || 0) - (b.appearMs || 0));\n const placed = []; // { x, y, size, appearMs, leaveMs }\n const out = new Map();\n for (const el of els) {\n const half = (el.kind === 'image' ? (el.size || 0.28) : 0.18) / 2;\n if (el.pinned || !panel.autoArrange) {\n if (el.pos) { placed.push({ ...el.pos, size: el.size || 0.28, appearMs: el.appearMs, leaveMs: el.leaveMs }); out.set(el.id, el.pos); }\n continue;\n }\n // Distance test only against elements VISIBLE when this one appears —\n // an element that already LEFT frees its space.\n const visible = placed.filter((p) => (p.leaveMs == null || p.leaveMs > el.appearMs));\n let best = null; let bestScore = -Infinity;\n for (let k = 0; k < SPIRAL_SLOTS; k++) {\n // Slot order is salted per-element id so different canvases don't all\n // start identically, while staying fully deterministic.\n const slot = spiralSlot((k + (hash(el.id) % SPIRAL_SLOTS)) % SPIRAL_SLOTS, aspect);\n const x = clamp01(slot.x, half + 0.03, 1 - half - 0.03);\n const y = clamp01(slot.y, half + 0.05, 1 - half - 0.05);\n let minD = Infinity;\n for (const p of visible) minD = Math.min(minD, Math.hypot(x - p.x, y - p.y) - (p.size || 0.28) / 2 - half);\n const centerPull = -0.12 * Math.hypot(x - 0.5, y - 0.5); // gentle balance toward center\n const score = (visible.length ? Math.min(minD, 0.5) : 0.3) + centerPull;\n if (score > bestScore) { bestScore = score; best = { x, y }; }\n }\n const pos = best || { x: 0.5, y: 0.5 };\n // A hair of deterministic scatter so the collage reads hand-placed.\n pos.x = clamp01(pos.x + jitter(el.id, 'x') * 0.015, half, 1 - half);\n pos.y = clamp01(pos.y + jitter(el.id, 'y') * 0.015, half, 1 - half);\n placed.push({ ...pos, size: el.size || 0.28, appearMs: el.appearMs, leaveMs: el.leaveMs });\n out.set(el.id, pos);\n }\n return out; // elementId -> {x, y}\n}\n// Stamp arranged positions onto the elements (unpinned only) — the STORED\n// positions are what every renderer reads, so preview == export.\nfunction withArrangedPositions(panel, opts) {\n if (!panel.autoArrange) return panel;\n const posMap = arrangeCanvas(panel, opts);\n return {\n ...panel,\n elements: (panel.elements || []).map((el) => (\n !el.pinned && posMap.has(el.id) ? { ...el, pos: posMap.get(el.id) } : el\n )),\n };\n}\n\n\nconst panel=input.panel;const tidied=withArrangedPositions({...panel,autoArrange:true},{aspect:input.aspect});return {edit:{...panel,elements:tidied.elements,provenance:\"user\"}};`,tests:[]},du=(e,t)=>e===void 0||t===void 0?e===t:V(e)===V(t);function fu(e,t,n){let r=e.strip.find(e=>e.panelId===t);I(r?.type===`canvas`&&!r.autoArrange&&!r.template&&Array.isArray(r.elements)&&r.elements.length<=1024,`CANVAS_TIDY`,`Choose a manual canvas without a template (up to 1024 elements).`),I(Number.isFinite(n)&&n>0&&n<=100,`CANVAS_TIDY`,`The canvas dimensions are unavailable.`);let i={panel:{elements:r.elements.map((e,t)=>{let n={origin:t};for(let t of[`id`,`kind`,`pinned`,`appearMs`,`leaveMs`,`size`])e[t]!==void 0&&(n[t]=e[t]);return e.pos!==void 0&&(n.pos=L(e.pos)?{x:e.pos.x,y:e.pos.y}:e.pos),n})},aspect:n};return B(i),I(JSON.stringify(i).length<=1048576,`CANVAS_TIDY`,`This layout is too large to arrange.`),{panel:r,input:i}}function pu(e,{panel:t,input:n},r){let i=At({...n.panel,autoArrange:!0},{aspect:n.aspect}),a={...n.panel,elements:i.elements,provenance:`user`};B(a),B(r),I(du(r,a),`CANVAS_TIDY`,`The sandbox changed an unrequested element, position or timing.`);let o=t.provenance!==`user`,s=r.elements.map((e,r)=>{let i=t.elements[r],s=n.panel.elements[r];return a.elements[r]===s||du(i.pos,e.pos)?i:(o=!0,{...i,pos:e.pos})});if(!o)return e;let c={...t,elements:s.every((e,n)=>e===t.elements[n])?t.elements:s,provenance:`user`};return{...e,strip:e.strip.map(e=>e===t?c:e)}}function mu({doc:e,projectId:t,panelId:n,canEdit:r,onDocChange:i,validateDocument:a,editLease:o,host:s}){let c=H(s),l=()=>c.actor(),[u,d]=(0,v.useState)(null),[f,p]=(0,v.useState)(``),m=(0,v.useRef)(null),h=(0,v.useRef)(!0),g=(0,v.useRef)(0),_=(0,v.useRef)(null),y=l();_.current={doc:e,projectId:t,panelId:n,canEdit:r,onDocChange:i,validateDocument:a,actor:y,services:c};let b=(0,v.useCallback)(()=>{g.current++,o?.current===m.current&&(o.current=null),m.current?.abort(),m.current=null,d(null)},[o]);return(0,v.useEffect)(()=>(h.current=!0,()=>{h.current=!1,g.current++,o?.current===m.current&&(o.current=null),m.current?.abort(),m.current=null}),[]),(0,v.useEffect)(()=>{b()},[e,t,n,r,y,c,b]),{change:(0,v.useCallback)(async r=>{let i=_.current;if(!i.doc||!i.canEdit||m.current||o?.current)return;if(i.services!==c||i.doc!==e||i.projectId!==t||i.panelId!==n||i.actor!==y||l()!==y){p(`The canvas changed. Review the canvas arrangement again.`);return}let a=++g.current,s=new AbortController;m.current=s,o&&(o.current=s),d(i.panelId),p(``);let u,f=()=>{let e=_.current;I(h.current&&m.current===s&&!s.signal.aborted&&e.doc===i.doc&&e.projectId===i.projectId&&e.panelId===i.panelId&&e.canEdit&&e.services===c&&e.actor===i.actor&&l()===i.actor&&JSON.stringify(i.doc)===u,`STALE`,`The canvas changed. Review the current canvas elements again.`)};try{u=JSON.stringify(i.doc);let e=fu(i.doc,i.panelId,r);f();let t=await c.run(uu,{kind:`run`,input:e.input,signal:s.signal,timeoutMs:15e3});f();let n=pu(i.doc,e,t.outputs?.edit),o=n===i.doc?i.doc:i.validateDocument(n);if(f(),o!==i.doc){let e=JSON.stringify(o),t=!1;i.onDocChange(n=>{let r=_.current,d=!1;try{d=h.current&&g.current===a&&!s.signal.aborted&&r.doc===i.doc&&r.projectId===i.projectId&&r.panelId===i.panelId&&r.canEdit&&r.services===c&&r.actor===i.actor&&l()===i.actor&&JSON.stringify(o)===e&&JSON.stringify(n)===u&&JSON.stringify(i.doc)===u}catch{}return d?o:(t||(t=!0,queueMicrotask(()=>{h.current&&l()===i.actor&&_.current.projectId===i.projectId&&p(`The canvas changed before the canvas arrangement could be saved. Review the current canvas elements again.`)})),n)})}return o}catch(e){h.current&&!s.signal.aborted&&l()===i.actor&&_.current.projectId===i.projectId&&p(e.message||`The canvas arrangement could not be applied.`)}finally{m.current===s&&(o?.current===s&&(o.current=null),m.current=null,h.current&&d(null))}},[e,t,n,y,c]),pending:u,error:f,cancel:b}}let hu={manifest:{schemaVersion:1,sdkVersion:`0.1.0`,id:`stillmade-internal.canvas-continuation`,version:`1.0.1`,name:`Canvas continuation`,description:`Continue a canvas at the captured time or change its handoff settings.`,kind:`task`,runtime:`javascript`,inputs:{doc:{type:`json`},panelId:{type:`json`},atMs:{type:`json`},options:{type:`json`},mode:{type:`json`}},outputs:{edit:{type:`json`}},permissions:{project:[],network:[],filesystem:[],secrets:[]}},code:`const CANVAS_HANDOFF_EXITS=['swipe-up','swipe-down','swipe-left','swipe-right','cut'];const CANVAS_ARRIVALS=['pop','fade'];\nconst loadPanelDoc=doc=>JSON.parse(JSON.stringify(doc));\nfunction continueCanvasAt(doc, panelId, atMs, { exit = 'swipe-up', arrive = 'pop' } = {}) {\n const panel = doc.strip.find((p) => p.panelId === panelId);\n if (!panel || panel.type !== 'canvas') throw new Error(\\`continueCanvasAt: \\${panelId} is not a canvas panel\\`);\n if (!CANVAS_HANDOFF_EXITS.includes(exit)) throw new Error(\\`continueCanvasAt: exit must be \\${CANVAS_HANDOFF_EXITS.join('|')}\\`);\n if (!CANVAS_ARRIVALS.includes(arrive)) throw new Error(\\`continueCanvasAt: arrive must be \\${CANVAS_ARRIVALS.join('|')}\\`);\n const cut = Math.round(Number(atMs));\n const MIN_SIDE = 400; // each side keeps a usable window\n if (!Number.isFinite(cut) || cut < MIN_SIDE || cut > panel.durationMs - MIN_SIDE) {\n throw new Error('Pick a point with at least 0.4s on each side to continue on a new canvas');\n }\n const reserved = reservedPanelIds(doc.strip);\n let cn = doc.strip.filter((p) => p.type === 'canvas').length + 1;\n while (reserved.has(\\`\\${panelId}c\\${cn}\\`)) cn++;\n const newId = \\`\\${panelId}c\\${cn}\\`;\n // Elements from the cut onward migrate, rebased to the new canvas's clock.\n const stays = [];\n const moves = [];\n for (const el of (panel.elements || [])) {\n if ((el.appearMs || 0) >= cut) {\n moves.push({\n ...el,\n appearMs: Math.max(0, (el.appearMs || 0) - cut),\n leaveMs: el.leaveMs != null ? Math.max(100, el.leaveMs - cut) : null,\n entrance: el.kind === 'text' ? el.entrance : (arrive === 'fade' ? 'fade' : (el.entrance || 'pop')),\n ...(el.kind === 'text' && Array.isArray(el.wordTimes) ? { wordTimes: el.wordTimes.map((w) => Math.max(0, w - cut)) } : {}),\n });\n } else {\n // An element straddling the cut ends with this canvas (its leave clamps\n // to the window; null still means \"stays to the end\", now the cut).\n stays.push(el.leaveMs != null && el.leaveMs > cut ? { ...el, leaveMs: cut } : el);\n }\n }\n const strip = doc.strip.flatMap((p) => {\n if (p.panelId !== panelId) return [p];\n return [\n { ...p, durationMs: cut, elements: stays },\n {\n panelId: newId, type: 'canvas', sceneId: p.sceneId,\n background: '#ffffff', autoArrange: p.autoArrange, planned: false,\n elements: moves, startMs: p.startMs + cut, durationMs: p.durationMs - cut,\n transitionIn: 'cut', provenance: 'user',\n handoff: { exit, arrive },\n },\n ];\n });\n return loadPanelDoc({ ...doc, strip });\n}\n\n// Change or remove the hand-off on a continued canvas afterward.\nfunction setCanvasHandoff(doc, panelId, handoff) {\n const panel = doc.strip.find((p) => p.panelId === panelId);\n if (!panel || panel.type !== 'canvas') throw new Error(\\`setCanvasHandoff: \\${panelId} is not a canvas panel\\`);\n const strip = doc.strip.map((p) => {\n if (p.panelId !== panelId) return p;\n const next = { ...p };\n if (handoff == null) delete next.handoff;\n else next.handoff = { ...(p.handoff || {}), ...handoff };\n return next;\n });\n return loadPanelDoc({ ...doc, strip });\n}\n\nfunction reservedPanelIds(strip) {\n const ids = new Set();\n for (const p of (strip || [])) {\n ids.add(p.panelId);\n for (const r of (p.revert?.rows || [])) ids.add(r.panelId);\n }\n return ids;\n}\n\nreturn {edit:input.mode==='continue'?continueCanvasAt(input.doc,input.panelId,input.atMs,input.options??{}):setCanvasHandoff(input.doc,input.panelId,input.options)};\n`,tests:[]},gu=(e,t)=>e===void 0||t===void 0?e===t:V(e)===V(t),_u=[`kind`,`appearMs`,`leaveMs`,`entrance`,`wordTimes`],vu=e=>JSON.parse(JSON.stringify(e,(e,t)=>(I(typeof t!=`number`||Number.isFinite(t),`CANVAS_CONTINUATION`,`Timing must remain finite.`),t)));function yu(e,t,n){let r=e.strip.find(e=>e.panelId===t);I(r?.type===`canvas`&&Array.isArray(r.elements)&&e.strip.length<=2048&&r.elements.length<=4096,`CANVAS_CONTINUATION`,`Choose a supported canvas.`);let i=e.strip.map(e=>({panelId:e.panelId,type:e.type,revert:{rows:(e.revert?.rows||[]).map(e=>({panelId:e.panelId}))},...e===r?{startMs:e.startMs,durationMs:e.durationMs,sceneId:`scene`,autoArrange:e.autoArrange??!1,handoff:e.handoff?Object.fromEntries([`exit`,`arrive`].filter(t=>e.handoff[t]!==void 0).map(t=>[t,e.handoff[t]])):void 0,elements:r.elements.map((e,t)=>({origin:t,...Object.fromEntries(_u.filter(t=>e[t]!==void 0).map(t=>[t,e[t]]))}))}:{}})),a=vu({doc:{strip:i},panelId:t,mode:n.mode,atMs:n.atMs??null,options:n.options??null});B(a),I([`continue`,`handoff`].includes(a.mode)&&JSON.stringify(a).length<=1048576,`CANVAS_CONTINUATION`,`This continuation is too large.`),a.options!==null&&I(L(a.options)&&Object.keys(a.options).every(e=>[`exit`,`arrive`].includes(e)),`CANVAS_CONTINUATION`,`Choose handoff settings.`);let o=a.options||{};return I((o.exit===void 0||[`swipe-up`,`swipe-down`,`swipe-left`,`swipe-right`,`cut`].includes(o.exit))&&(o.arrive===void 0||[`pop`,`fade`].includes(o.arrive)),`CANVAS_CONTINUATION`,`Choose supported exit and arrival settings.`),{panel:r,input:a}}function bu(e){let t=e.doc.strip.findIndex(t=>t.panelId===e.panelId),n=e.doc.strip[t];if(e.mode===`handoff`){let r={...n};return e.options===null?delete r.handoff:r.handoff={...n.handoff||{},...e.options},{...e.doc,strip:e.doc.strip.map((e,n)=>n===t?r:e)}}let r=Math.round(Number(e.atMs)),i=e.options?.exit??`swipe-up`,a=e.options?.arrive??`pop`;I(Number.isFinite(r)&&r>=400&&r<=n.durationMs-400,`CANVAS_CONTINUATION`,`Keep at least 0.4 seconds on each side.`);let o=new Set(e.doc.strip.flatMap(e=>[e.panelId,...e.revert.rows.map(e=>e.panelId)])),s=e.doc.strip.filter(e=>e.type===`canvas`).length+1;for(;o.has(`${e.panelId}c${s}`);)s++;let c=[],l=[];for(let e of n.elements){if((e.appearMs||0)<r){c.push(e.leaveMs!=null&&e.leaveMs>r?{...e,leaveMs:r}:e);continue}let t={...e,appearMs:Math.max(0,(e.appearMs||0)-r),leaveMs:e.leaveMs==null?null:Math.max(100,e.leaveMs-r),entrance:e.kind===`text`?e.entrance:a===`fade`?`fade`:e.entrance||`pop`};e.kind===`text`&&Array.isArray(e.wordTimes)&&(t.wordTimes=e.wordTimes.map(e=>Math.max(0,e-r))),l.push(t)}let u={panelId:`${e.panelId}c${s}`,type:`canvas`,sceneId:n.sceneId,background:`#ffffff`,autoArrange:n.autoArrange,planned:!1,elements:l,startMs:n.startMs+r,durationMs:n.durationMs-r,transitionIn:`cut`,provenance:`user`,handoff:{exit:i,arrive:a}};return vu({...e.doc,strip:e.doc.strip.flatMap((e,i)=>i===t?[{...n,durationMs:r,elements:c},u]:[e])})}function xu(e,{panel:t,input:n},r){let i=bu(n);if(B(i),B(r),I(gu(r,i),`CANVAS_CONTINUATION`,`The sandbox changed continuation timing, elements or handoff metadata.`),n.mode===`handoff`){let r={...t};return n.options===null?delete r.handoff:r.handoff={...t.handoff||{},...n.options},gu(r,t)?e:{...e,strip:e.strip.map(e=>e===t?r:e)}}let a=n.doc.strip.findIndex(e=>e.panelId===t.panelId),o=r.strip[a],s=r.strip[a+1],c=e=>{let n=t.elements[e.origin],r=n;for(let t of[`appearMs`,`leaveMs`,`entrance`,`wordTimes`])Object.hasOwn(e,t)&&(gu(n[t],e[t])||(r===n&&(r={...n}),r[t]=e[t]));return r},l={...t,durationMs:o.durationMs,elements:o.elements.map(c)},u={...s,sceneId:t.sceneId,autoArrange:t.autoArrange,elements:s.elements.map(c)};return{...e,strip:e.strip.flatMap(e=>e===t?[l,u]:[e])}}function Su({doc:e,projectId:t,panelId:n,canEdit:r,onDocChange:i,validateDocument:a,editLease:o,host:s}){let c=H(s),l=()=>c.actor(),[u,d]=(0,v.useState)(null),[f,p]=(0,v.useState)(``),m=(0,v.useRef)(null),h=(0,v.useRef)(!0),g=(0,v.useRef)(0),_=(0,v.useRef)(null),y=l();_.current={doc:e,projectId:t,panelId:n,canEdit:r,onDocChange:i,validateDocument:a,actor:y,services:c};let b=(0,v.useCallback)(()=>{g.current++,o?.current===m.current&&(o.current=null),m.current?.abort(),m.current=null,d(null)},[o]);return(0,v.useEffect)(()=>(h.current=!0,()=>{h.current=!1,g.current++,o?.current===m.current&&(o.current=null),m.current?.abort(),m.current=null}),[]),(0,v.useEffect)(()=>{b()},[e,t,n,r,y,c,b]),{change:(0,v.useCallback)(async r=>{let i=_.current;if(!i.doc||!i.canEdit||m.current||o?.current)return;if(i.services!==c||i.doc!==e||i.projectId!==t||i.panelId!==n||i.actor!==y||l()!==y){p(`The canvas changed before this edit was ready. Review the current canvas again.`);return}let a=++g.current,s=new AbortController;m.current=s,o&&(o.current=s),d(r.mode),p(``);let u,f=()=>{let e=_.current;I(h.current&&m.current===s&&!s.signal.aborted&&e.doc===i.doc&&e.projectId===i.projectId&&e.panelId===i.panelId&&e.canEdit&&e.services===c&&e.actor===i.actor&&l()===i.actor&&JSON.stringify(i.doc)===u,`STALE`,`The canvas changed. Review the current continuation settings again.`)};try{u=JSON.stringify(i.doc);let e=yu(i.doc,i.panelId,r);f();let t=await c.run(hu,{kind:`run`,input:e.input,signal:s.signal,timeoutMs:15e3});f();let n=xu(i.doc,e,t.outputs?.edit),o=n===i.doc?i.doc:i.validateDocument(n);if(f(),o!==i.doc){let e=JSON.stringify(o),t=!1;i.onDocChange(n=>{let r=_.current,d=!1;try{d=h.current&&g.current===a&&!s.signal.aborted&&r.doc===i.doc&&r.projectId===i.projectId&&r.panelId===i.panelId&&r.canEdit&&r.services===c&&r.actor===i.actor&&l()===i.actor&&JSON.stringify(o)===e&&JSON.stringify(n)===u&&JSON.stringify(i.doc)===u}catch{}return d?o:(t||(t=!0,queueMicrotask(()=>{h.current&&l()===i.actor&&_.current.projectId===i.projectId&&p(`The canvas changed before the continuation could be saved. Review the current continuation settings again.`)})),n)})}return o}catch(e){h.current&&!s.signal.aborted&&l()===i.actor&&_.current.projectId===i.projectId&&p(e.message||`The continuation could not be applied.`)}finally{m.current===s&&(o?.current===s&&(o.current=null),m.current=null,h.current&&d(null))}},[e,t,n,y,c]),pending:u,error:f,cancel:b}}let Cu={manifest:{schemaVersion:1,sdkVersion:`0.1.0`,id:`stillmade-internal.canvas-add-element`,version:`1.0.1`,name:`Canvas element creation`,description:`Add a captured element and reflow its template and layout.`,kind:`task`,runtime:`javascript`,inputs:{doc:{type:`json`},panelId:{type:`text`},element:{type:`json`},newId:{type:`text`}},outputs:{edit:{type:`json`}},permissions:{project:[],network:[],filesystem:[],secrets:[]}},code:`// COLLAGE CANVAS TEMPLATES — 20 bundled, versioned slot layouts (panel-image\n// only), each authored TWICE: a landscape layout and a portrait (9:16) layout\n// for the same scenario. A template is a LAYOUT DEFINITION, not a static\n// design: image SLOTS (center pos, target box, draw order = array order\n// back→front, optional tilt) and explicit TEXT SLOTS (role + deliberate\n// position), which the canvas system reads to place elements.\n//\n// Coordinates are normalized to the canvas frame (x/w = width fractions,\n// y/h = height fractions). An image FITS its slot box cover-cropped\n// (drawCollage's \\`box\\` rendering — aspect preserved, never distorted); fine\n// adjustment stays manual (drag pins, per spec S10). Image slots keep a\n// bottom safety margin (y + h/2 ≤ 0.95) so nothing crowds the frame edge.\n//\n// EVERY SLOT IS OPTIONAL — image and text alike. A template defines where\n// things GO if present; nothing is required. A canvas can use 2 of 7 image\n// slots, no text at all, or text with fewer images; unused slots are simply\n// empty (no placeholder, no gap artifact). And templates place, they never\n// time: each element still appears on ITS OWN voiceover beat (appearMs is\n// untouched by template application), so a canvas builds up slot by slot.\n//\n// Ownership contract (post-approval spec):\n// - AUTO canvases: the generator PICKS a template (pickTemplateForCanvas) from\n// image count + the beat's scenario hint; S10 self-arranging handles the\n// OVERFLOW beyond the slots (spiral around the slotted ones). Shown +\n// changeable afterward.\n// - MANUAL canvases: no template by default; opt-in from the picker.\n// - Switching is non-destructive: same elements, new positions; PINNED\n// elements are never moved (the pin IS the manual override).\n// - No fit / no pick → template null → the plain self-arranging layout.\n//\n// APPROVED by the owner 2026-07-22 (v2 sheet: both orientations, bottom\n// margins fixed). Bundled static definitions — versioned, never regenerated.\nconst CANVAS_TEMPLATE_VERSION = 2;\n\n// slot: { x, y, w, h, tilt? } — image slot (center + target box)\n// textSlot: { role, x, y, size, weight? } — role: headline | label | caption\n// Each template: landscape layout in \\`slots\\`/\\`textSlots\\`, portrait layout in\n// \\`pSlots\\`/\\`pTextSlots\\` (same scenario re-authored for a tall frame).\nconst T = (id, name, scenario, minImages, slots, textSlots, pSlots, pTextSlots) => (\n { id, name, scenario, minImages, slots, textSlots, pSlots, pTextSlots }\n);\n\nconst CANVAS_TEMPLATES = [\n T('hero-headline', 'Hero + headline', 'one subject, one line', 1,\n [{ x: 0.5, y: 0.58, w: 0.5, h: 0.62 }],\n [{ role: 'headline', x: 0.5, y: 0.14, size: 0.09, weight: 900 }],\n [{ x: 0.5, y: 0.55, w: 0.78, h: 0.5 }],\n [{ role: 'headline', x: 0.5, y: 0.13, size: 0.055, weight: 900 }]),\n\n T('hero-supporting', 'Hero + 2 supporting', 'main subject with two details', 3,\n [{ x: 0.34, y: 0.55, w: 0.42, h: 0.58 }, { x: 0.78, y: 0.33, w: 0.28, h: 0.32 }, { x: 0.78, y: 0.73, w: 0.28, h: 0.32 }],\n [{ role: 'headline', x: 0.34, y: 0.13, size: 0.08, weight: 900 }],\n [{ x: 0.5, y: 0.38, w: 0.78, h: 0.32 }, { x: 0.28, y: 0.72, w: 0.4, h: 0.2 }, { x: 0.72, y: 0.72, w: 0.4, h: 0.2 }],\n [{ role: 'headline', x: 0.5, y: 0.12, size: 0.05, weight: 900 }]),\n\n T('compare-2', 'Side-by-side compare', 'A vs B', 2,\n [{ x: 0.27, y: 0.5, w: 0.38, h: 0.5 }, { x: 0.73, y: 0.5, w: 0.38, h: 0.5 }],\n [{ role: 'headline', x: 0.5, y: 0.12, size: 0.08, weight: 900 },\n { role: 'label', x: 0.27, y: 0.84, size: 0.05, weight: 800 },\n { role: 'label', x: 0.73, y: 0.84, size: 0.05, weight: 800 }],\n [{ x: 0.5, y: 0.35, w: 0.72, h: 0.24 }, { x: 0.5, y: 0.72, w: 0.72, h: 0.24 }],\n [{ role: 'headline', x: 0.5, y: 0.11, size: 0.05, weight: 900 },\n { role: 'label', x: 0.5, y: 0.51, size: 0.032, weight: 800 },\n { role: 'label', x: 0.5, y: 0.88, size: 0.032, weight: 800 }]),\n\n T('three-across', 'Three across', 'three items', 3,\n [{ x: 0.2, y: 0.5, w: 0.26, h: 0.46 }, { x: 0.5, y: 0.5, w: 0.26, h: 0.46 }, { x: 0.8, y: 0.5, w: 0.26, h: 0.46 }],\n [{ role: 'headline', x: 0.5, y: 0.13, size: 0.08, weight: 900 },\n { role: 'caption', x: 0.5, y: 0.86, size: 0.045, weight: 600 }],\n [{ x: 0.5, y: 0.32, w: 0.64, h: 0.2 }, { x: 0.5, y: 0.57, w: 0.64, h: 0.2 }, { x: 0.5, y: 0.82, w: 0.64, h: 0.2 }],\n [{ role: 'headline', x: 0.5, y: 0.1, size: 0.05, weight: 900 },\n { role: 'caption', x: 0.5, y: 0.96, size: 0.028, weight: 600 }]),\n\n T('grid-2x2', 'Grid of four', 'four items', 4,\n [{ x: 0.3, y: 0.36, w: 0.32, h: 0.34 }, { x: 0.7, y: 0.36, w: 0.32, h: 0.34 },\n { x: 0.3, y: 0.74, w: 0.32, h: 0.34 }, { x: 0.7, y: 0.74, w: 0.32, h: 0.34 }],\n [{ role: 'headline', x: 0.5, y: 0.09, size: 0.07, weight: 900 }],\n [{ x: 0.28, y: 0.38, w: 0.4, h: 0.24 }, { x: 0.72, y: 0.38, w: 0.4, h: 0.24 },\n { x: 0.28, y: 0.68, w: 0.4, h: 0.24 }, { x: 0.72, y: 0.68, w: 0.4, h: 0.24 }],\n [{ role: 'headline', x: 0.5, y: 0.12, size: 0.05, weight: 900 }]),\n\n T('grid-3x3', 'Many small (3x3)', 'lots of items', 6,\n [0.22, 0.5, 0.78].flatMap((x) => [0.3, 0.56, 0.82].map((y) => ({ x, y, w: 0.24, h: 0.22 }))),\n [{ role: 'headline', x: 0.5, y: 0.08, size: 0.065, weight: 900 }],\n [0.2, 0.5, 0.8].flatMap((x) => [0.34, 0.58, 0.82].map((y) => ({ x, y, w: 0.27, h: 0.18 }))),\n [{ role: 'headline', x: 0.5, y: 0.1, size: 0.045, weight: 900 }]),\n\n T('big-left-stack-right', 'Big lead + stack', 'one lead, several follow-ups', 3,\n [{ x: 0.32, y: 0.54, w: 0.5, h: 0.62 }, { x: 0.79, y: 0.3, w: 0.3, h: 0.22 },\n { x: 0.79, y: 0.56, w: 0.3, h: 0.22 }, { x: 0.79, y: 0.82, w: 0.3, h: 0.22 }],\n [{ role: 'headline', x: 0.32, y: 0.13, size: 0.075, weight: 900 }],\n [{ x: 0.5, y: 0.4, w: 0.84, h: 0.34 }, { x: 0.2, y: 0.74, w: 0.26, h: 0.16 },\n { x: 0.5, y: 0.74, w: 0.26, h: 0.16 }, { x: 0.8, y: 0.74, w: 0.26, h: 0.16 }],\n [{ role: 'headline', x: 0.5, y: 0.12, size: 0.05, weight: 900 }]),\n\n T('vertical-stack', 'Vertical stack', 'ordered top to bottom', 2,\n [{ x: 0.55, y: 0.29, w: 0.36, h: 0.22 }, { x: 0.55, y: 0.55, w: 0.36, h: 0.22 }, { x: 0.55, y: 0.81, w: 0.36, h: 0.22 }],\n [{ role: 'headline', x: 0.55, y: 0.08, size: 0.065, weight: 900 },\n { role: 'label', x: 0.16, y: 0.55, size: 0.055, weight: 800 }],\n [{ x: 0.5, y: 0.3, w: 0.66, h: 0.2 }, { x: 0.5, y: 0.56, w: 0.66, h: 0.2 }, { x: 0.5, y: 0.82, w: 0.66, h: 0.2 }],\n [{ role: 'headline', x: 0.5, y: 0.09, size: 0.05, weight: 900 },\n { role: 'label', x: 0.24, y: 0.17, size: 0.032, weight: 800 }]),\n\n T('scatter', 'Scattered collage', 'loose, hand-thrown feel', 3,\n [{ x: 0.26, y: 0.36, w: 0.28, h: 0.32, tilt: -6 }, { x: 0.68, y: 0.3, w: 0.26, h: 0.3, tilt: 4 },\n { x: 0.44, y: 0.66, w: 0.27, h: 0.31, tilt: 3 }, { x: 0.8, y: 0.62, w: 0.25, h: 0.29, tilt: -5 },\n { x: 0.58, y: 0.46, w: 0.24, h: 0.28, tilt: 2 }],\n [{ role: 'headline', x: 0.5, y: 0.1, size: 0.075, weight: 900 }],\n [{ x: 0.32, y: 0.3, w: 0.46, h: 0.2, tilt: -6 }, { x: 0.7, y: 0.26, w: 0.42, h: 0.18, tilt: 4 },\n { x: 0.4, y: 0.56, w: 0.44, h: 0.2, tilt: 3 }, { x: 0.74, y: 0.6, w: 0.4, h: 0.18, tilt: -5 },\n { x: 0.5, y: 0.82, w: 0.44, h: 0.19, tilt: 2 }],\n [{ role: 'headline', x: 0.5, y: 0.09, size: 0.045, weight: 900 }]),\n\n T('timeline-row', 'Row / timeline', 'steps in order', 3,\n [{ x: 0.14, y: 0.52, w: 0.2, h: 0.38 }, { x: 0.38, y: 0.52, w: 0.2, h: 0.38 },\n { x: 0.62, y: 0.52, w: 0.2, h: 0.38 }, { x: 0.86, y: 0.52, w: 0.2, h: 0.38 }],\n [{ role: 'headline', x: 0.5, y: 0.15, size: 0.075, weight: 900 },\n { role: 'caption', x: 0.5, y: 0.85, size: 0.045, weight: 600 }],\n [{ x: 0.35, y: 0.28, w: 0.5, h: 0.15 }, { x: 0.65, y: 0.47, w: 0.5, h: 0.15 },\n { x: 0.35, y: 0.66, w: 0.5, h: 0.15 }, { x: 0.65, y: 0.85, w: 0.5, h: 0.15 }],\n [{ role: 'headline', x: 0.5, y: 0.12, size: 0.05, weight: 900 }]),\n\n T('center-satellites', 'Center + satellites', 'one core idea, orbiting parts', 3,\n [{ x: 0.5, y: 0.52, w: 0.34, h: 0.42 }, { x: 0.17, y: 0.3, w: 0.2, h: 0.26 }, { x: 0.83, y: 0.3, w: 0.2, h: 0.26 },\n { x: 0.17, y: 0.77, w: 0.2, h: 0.26 }, { x: 0.83, y: 0.77, w: 0.2, h: 0.26 }],\n [{ role: 'headline', x: 0.5, y: 0.09, size: 0.065, weight: 900 }],\n [{ x: 0.5, y: 0.52, w: 0.56, h: 0.28 }, { x: 0.2, y: 0.28, w: 0.32, h: 0.16 }, { x: 0.8, y: 0.28, w: 0.32, h: 0.16 },\n { x: 0.2, y: 0.78, w: 0.32, h: 0.16 }, { x: 0.8, y: 0.78, w: 0.32, h: 0.16 }],\n [{ role: 'headline', x: 0.5, y: 0.1, size: 0.045, weight: 900 }]),\n\n T('corner-big-text', 'Corner images, big text', 'statement first, proof beside it', 2,\n [{ x: 0.72, y: 0.4, w: 0.32, h: 0.38 }, { x: 0.52, y: 0.72, w: 0.28, h: 0.34 }, { x: 0.85, y: 0.76, w: 0.24, h: 0.3 }],\n [{ role: 'headline', x: 0.26, y: 0.26, size: 0.105, weight: 900 },\n { role: 'label', x: 0.26, y: 0.42, size: 0.05, weight: 600 }],\n [{ x: 0.36, y: 0.56, w: 0.5, h: 0.22 }, { x: 0.7, y: 0.7, w: 0.44, h: 0.2 }, { x: 0.4, y: 0.84, w: 0.4, h: 0.18 }],\n [{ role: 'headline', x: 0.5, y: 0.19, size: 0.065, weight: 900 },\n { role: 'label', x: 0.5, y: 0.31, size: 0.034, weight: 600 }]),\n\n T('title-top-row', 'Title top, images below', 'title screen with evidence', 2,\n [{ x: 0.22, y: 0.62, w: 0.28, h: 0.44 }, { x: 0.5, y: 0.62, w: 0.28, h: 0.44 }, { x: 0.78, y: 0.62, w: 0.28, h: 0.44 }],\n [{ role: 'headline', x: 0.5, y: 0.17, size: 0.1, weight: 900 }],\n [{ x: 0.5, y: 0.4, w: 0.7, h: 0.2 }, { x: 0.5, y: 0.64, w: 0.7, h: 0.2 }, { x: 0.5, y: 0.86, w: 0.7, h: 0.16 }],\n [{ role: 'headline', x: 0.5, y: 0.15, size: 0.06, weight: 900 }]),\n\n T('large-caption', 'One large + caption', 'let the image speak', 1,\n [{ x: 0.5, y: 0.47, w: 0.56, h: 0.6 }],\n [{ role: 'label', x: 0.15, y: 0.1, size: 0.045, weight: 800 },\n { role: 'caption', x: 0.5, y: 0.85, size: 0.055, weight: 600 }],\n [{ x: 0.5, y: 0.47, w: 0.82, h: 0.44 }],\n [{ role: 'label', x: 0.24, y: 0.12, size: 0.032, weight: 800 },\n { role: 'caption', x: 0.5, y: 0.78, size: 0.034, weight: 600 }]),\n\n T('staggered-diagonal', 'Staggered diagonal', 'progression with motion', 3,\n [{ x: 0.18, y: 0.26, w: 0.24, h: 0.3, tilt: -3 }, { x: 0.42, y: 0.45, w: 0.24, h: 0.3, tilt: 3 },\n { x: 0.64, y: 0.62, w: 0.24, h: 0.3, tilt: -3 }, { x: 0.86, y: 0.79, w: 0.24, h: 0.3, tilt: 3 }],\n [{ role: 'headline', x: 0.74, y: 0.16, size: 0.075, weight: 900 }],\n [{ x: 0.28, y: 0.3, w: 0.42, h: 0.18, tilt: -3 }, { x: 0.62, y: 0.46, w: 0.42, h: 0.18, tilt: 3 },\n { x: 0.36, y: 0.62, w: 0.42, h: 0.18, tilt: -3 }, { x: 0.68, y: 0.78, w: 0.42, h: 0.18, tilt: 3 }],\n [{ role: 'headline', x: 0.5, y: 0.12, size: 0.05, weight: 900 }]),\n\n T('overlap-stack', 'Overlapping stack', 'a deliberate pile', 2,\n [{ x: 0.42, y: 0.5, w: 0.36, h: 0.46, tilt: -5 }, { x: 0.54, y: 0.56, w: 0.36, h: 0.46, tilt: 3 },\n { x: 0.63, y: 0.46, w: 0.36, h: 0.46, tilt: -2 }],\n [{ role: 'headline', x: 0.5, y: 0.12, size: 0.08, weight: 900 },\n { role: 'caption', x: 0.5, y: 0.89, size: 0.045, weight: 600 }],\n [{ x: 0.44, y: 0.42, w: 0.58, h: 0.26, tilt: -5 }, { x: 0.58, y: 0.53, w: 0.58, h: 0.26, tilt: 3 },\n { x: 0.46, y: 0.64, w: 0.58, h: 0.26, tilt: -2 }],\n [{ role: 'headline', x: 0.5, y: 0.12, size: 0.05, weight: 900 },\n { role: 'caption', x: 0.5, y: 0.86, size: 0.032, weight: 600 }]),\n\n T('banner-row', 'Wide banner + small row', 'one wide scene, details under', 2,\n [{ x: 0.5, y: 0.36, w: 0.84, h: 0.36 }, { x: 0.25, y: 0.77, w: 0.24, h: 0.26 },\n { x: 0.5, y: 0.77, w: 0.24, h: 0.26 }, { x: 0.75, y: 0.77, w: 0.24, h: 0.26 }],\n [{ role: 'headline', x: 0.5, y: 0.09, size: 0.065, weight: 900 }],\n [{ x: 0.5, y: 0.36, w: 0.86, h: 0.26 }, { x: 0.22, y: 0.66, w: 0.28, h: 0.16 },\n { x: 0.5, y: 0.66, w: 0.28, h: 0.16 }, { x: 0.78, y: 0.66, w: 0.28, h: 0.16 }],\n [{ role: 'headline', x: 0.5, y: 0.13, size: 0.05, weight: 900 },\n { role: 'caption', x: 0.5, y: 0.82, size: 0.032, weight: 600 }]),\n\n T('quadrant-labels', 'Quadrants with labels', 'four named things', 4,\n [{ x: 0.28, y: 0.3, w: 0.3, h: 0.3 }, { x: 0.72, y: 0.3, w: 0.3, h: 0.3 },\n { x: 0.28, y: 0.71, w: 0.3, h: 0.3 }, { x: 0.72, y: 0.71, w: 0.3, h: 0.3 }],\n [{ role: 'headline', x: 0.5, y: 0.07, size: 0.06, weight: 900 },\n { role: 'label', x: 0.28, y: 0.49, size: 0.042, weight: 800 },\n { role: 'label', x: 0.72, y: 0.49, size: 0.042, weight: 800 },\n { role: 'label', x: 0.28, y: 0.9, size: 0.042, weight: 800 },\n { role: 'label', x: 0.72, y: 0.9, size: 0.042, weight: 800 }],\n [{ x: 0.28, y: 0.32, w: 0.38, h: 0.2 }, { x: 0.72, y: 0.32, w: 0.38, h: 0.2 },\n { x: 0.28, y: 0.64, w: 0.38, h: 0.2 }, { x: 0.72, y: 0.64, w: 0.38, h: 0.2 }],\n [{ role: 'headline', x: 0.5, y: 0.1, size: 0.045, weight: 900 },\n { role: 'label', x: 0.28, y: 0.45, size: 0.028, weight: 800 },\n { role: 'label', x: 0.72, y: 0.45, size: 0.028, weight: 800 },\n { role: 'label', x: 0.28, y: 0.77, size: 0.028, weight: 800 },\n { role: 'label', x: 0.72, y: 0.77, size: 0.028, weight: 800 }]),\n\n T('pyramid-3', 'Pyramid of three', 'one above two', 3,\n [{ x: 0.5, y: 0.32, w: 0.3, h: 0.32 }, { x: 0.32, y: 0.71, w: 0.3, h: 0.32 }, { x: 0.68, y: 0.71, w: 0.3, h: 0.32 }],\n [{ role: 'headline', x: 0.5, y: 0.08, size: 0.065, weight: 900 },\n { role: 'caption', x: 0.5, y: 0.92, size: 0.04, weight: 600 }],\n [{ x: 0.5, y: 0.34, w: 0.5, h: 0.22 }, { x: 0.27, y: 0.62, w: 0.42, h: 0.18 }, { x: 0.73, y: 0.62, w: 0.42, h: 0.18 }],\n [{ role: 'headline', x: 0.5, y: 0.1, size: 0.05, weight: 900 },\n { role: 'caption', x: 0.5, y: 0.79, size: 0.032, weight: 600 }]),\n\n T('mosaic-dense', 'Dense mosaic', 'everything at once', 5,\n [{ x: 0.3, y: 0.4, w: 0.34, h: 0.42 }, { x: 0.62, y: 0.29, w: 0.24, h: 0.26 }, { x: 0.86, y: 0.33, w: 0.2, h: 0.28 },\n { x: 0.19, y: 0.78, w: 0.24, h: 0.26 }, { x: 0.47, y: 0.77, w: 0.26, h: 0.28 }, { x: 0.73, y: 0.73, w: 0.22, h: 0.24 },\n { x: 0.91, y: 0.76, w: 0.14, h: 0.18 }],\n [{ role: 'headline', x: 0.5, y: 0.09, size: 0.06, weight: 900 }],\n [{ x: 0.32, y: 0.3, w: 0.5, h: 0.2 }, { x: 0.78, y: 0.26, w: 0.36, h: 0.16 }, { x: 0.24, y: 0.52, w: 0.4, h: 0.16 },\n { x: 0.68, y: 0.5, w: 0.44, h: 0.18 }, { x: 0.3, y: 0.74, w: 0.42, h: 0.16 }, { x: 0.74, y: 0.73, w: 0.4, h: 0.16 },\n { x: 0.5, y: 0.89, w: 0.5, h: 0.1 }],\n [{ role: 'headline', x: 0.5, y: 0.1, size: 0.045, weight: 900 }]),\n];\n\nconst byId = new Map(CANVAS_TEMPLATES.map((t) => [t.id, t]));\nconst getCanvasTemplate = (id) => byId.get(id) || null; // unknown/renamed id → no template (never a load failure)\n\n// The layout for a given canvas aspect: tall frames (ratio < 1) use the\n// portrait variant, everything else the landscape one.\nfunction templateLayout(template, aspect = 16 / 9) {\n if (!template) return null;\n return aspect < 1\n ? { slots: template.pSlots, textSlots: template.pTextSlots }\n : { slots: template.slots, textSlots: template.textSlots };\n}\n\n// ── Reflow: elements → a template's slots (pure, non-destructive) ───────────\n// Unpinned IMAGES fill image slots in appear order; unpinned TEXTS fill text\n// slots in slot order (headline first, as authored). EVERY SLOT IS OPTIONAL:\n// fewer elements than slots just leaves the extra slots empty. Elements\n// beyond the slots OVERFLOW: images lose their box (back to natural-aspect\n// sizing) and get pos:null so the S10 spiral places them around the slotted\n// ones; extra texts keep their position. PINNED elements are never touched —\n// the pin IS the manual override, and it survives every template switch.\n// TIMING IS NEVER TOUCHED: appearMs/leaveMs pass through untouched, so each\n// element still pops on its own voiceover beat.\nfunction applyTemplateToElements(elements, template, { aspect = 16 / 9 } = {}) {\n if (!template) {\n // Clearing a template touches ONLY slot-derived elements (the ones with a\n // box): the box comes off, the position STAYS — on an auto canvas the\n // spiral re-places unpinned elements anyway, and on a manual canvas the\n // old slot spot is a sane resting place (never a pos:null pile at\n // center, never a wipe of hand placements that were never slotted).\n return (elements || []).map((el) => {\n if (el.pinned || el.kind !== 'image' || !el.box) return el;\n const { box, ...rest } = el;\n return rest;\n });\n }\n const layout = templateLayout(template, aspect);\n const byAppear = (a, b) => (a.appearMs || 0) - (b.appearMs || 0);\n const images = (elements || []).filter((el) => el.kind === 'image' && !el.pinned).sort(byAppear);\n const texts = (elements || []).filter((el) => el.kind === 'text' && !el.pinned).sort(byAppear);\n const imgSlot = new Map();\n images.forEach((el, i) => { if (i < layout.slots.length) imgSlot.set(el.id, layout.slots[i]); });\n const textSlot = new Map();\n texts.forEach((el, i) => { if (i < layout.textSlots.length) textSlot.set(el.id, layout.textSlots[i]); });\n return (elements || []).map((el) => {\n if (el.pinned) return el;\n if (el.kind === 'image') {\n const s = imgSlot.get(el.id);\n if (!s) { const { box, ...rest } = el; return { ...rest, pos: null }; } // overflow → spiral\n return { ...el, pos: { x: s.x, y: s.y }, box: { w: s.w, h: s.h }, size: s.w, tilt: s.tilt || 0 };\n }\n const s = textSlot.get(el.id);\n if (!s) return el; // extra text keeps its place\n return { ...el, pos: { x: s.x, y: s.y }, size: s.size, weight: s.weight || el.weight || 800 };\n });\n}\n\n// ── Auto-pick (post-approval spec): image count + scenario hint ─────────────\n// The hint is the planner's free-text reason for the beat; keyword classes\n// beat pure counts (compare → side-by-side, steps/list → row, many → mosaic).\n// Returns a template id or null (no fit → the plain self-arranging layout).\nfunction pickTemplateForCanvas({ imageCount = 0, textCount = 0, hint = '' } = {}) {\n if (!imageCount) return null;\n const h = String(hint || '').toLowerCase();\n if (imageCount === 2 && /\\\\bvs\\\\b|versus|compar|before.*after|either/.test(h)) return 'compare-2';\n if (imageCount >= 3 && /step|order|sequence|timeline|process|journey|stages/.test(h)) return 'timeline-row';\n if (imageCount >= 3 && /list|lists|enumerat|items|examples|types|kinds/.test(h)) return imageCount >= 5 ? 'mosaic-dense' : 'three-across';\n if (imageCount === 1) return textCount > 1 ? 'large-caption' : 'hero-headline';\n if (imageCount === 2) return 'compare-2';\n if (imageCount === 3) return 'three-across';\n if (imageCount === 4) return 'grid-2x2';\n if (imageCount === 5) return 'center-satellites';\n if (imageCount <= 7) return 'mosaic-dense';\n return 'grid-3x3';\n}\n\nconst hash = (s) => {\n let h = 5381;\n const str = String(s || '');\n for (let i = 0; i < str.length; i++) h = ((h << 5) + h + str.charCodeAt(i)) >>> 0;\n return h;\n};\n// Deterministic pseudo-jitter in [-1, 1] from an id + salt.\nconst jitter = (id, salt) => ((hash(\\`\\${id}|\\${salt}\\`) % 2000) / 1000) - 1;\n\n// ── Self-arranging layout (S10) ──────────────────────────────────────────────\n// Applies to AUTO-ARRANGED canvases only (panel.autoArrange). Deterministic\n// greedy placement in APPEAR ORDER: each unpinned image takes the best slot on\n// a golden-angle spiral around the canvas center — maximizing distance from\n// every element already visible when it appears — so the composition stays\n// balanced as it accumulates without ever moving an already-placed element\n// (tidy-by-construction; nothing jumps). PINNED elements (user overrides) and\n// manual canvases keep their positions exactly; auto elements arrange AROUND\n// pinned ones (they're obstacles in the distance test).\nconst SPIRAL_SLOTS = 48;\nconst GOLDEN = 2.399963229728653; // golden angle (rad)\nfunction spiralSlot(k, aspect = 16 / 9) {\n // Slots sweep outward from the center, filling the frame evenly; x spread is\n // wider than y for landscape canvases.\n const r = 0.08 + 0.40 * Math.sqrt((k + 0.5) / SPIRAL_SLOTS);\n const a = k * GOLDEN;\n return { x: 0.5 + r * Math.cos(a), y: 0.5 + r * Math.sin(a) * (aspect > 1 ? 0.9 : 1.1) };\n}\nconst clamp01 = (v, lo, hi) => Math.max(lo, Math.min(hi, v));\n\nfunction arrangeCanvas(panel, { aspect = 16 / 9 } = {}) {\n const els = (panel?.elements || []).slice().sort((a, b) => (a.appearMs || 0) - (b.appearMs || 0));\n const placed = []; // { x, y, size, appearMs, leaveMs }\n const out = new Map();\n for (const el of els) {\n const half = (el.kind === 'image' ? (el.size || 0.28) : 0.18) / 2;\n if (el.pinned || !panel.autoArrange) {\n if (el.pos) { placed.push({ ...el.pos, size: el.size || 0.28, appearMs: el.appearMs, leaveMs: el.leaveMs }); out.set(el.id, el.pos); }\n continue;\n }\n // Distance test only against elements VISIBLE when this one appears —\n // an element that already LEFT frees its space.\n const visible = placed.filter((p) => (p.leaveMs == null || p.leaveMs > el.appearMs));\n let best = null; let bestScore = -Infinity;\n for (let k = 0; k < SPIRAL_SLOTS; k++) {\n // Slot order is salted per-element id so different canvases don't all\n // start identically, while staying fully deterministic.\n const slot = spiralSlot((k + (hash(el.id) % SPIRAL_SLOTS)) % SPIRAL_SLOTS, aspect);\n const x = clamp01(slot.x, half + 0.03, 1 - half - 0.03);\n const y = clamp01(slot.y, half + 0.05, 1 - half - 0.05);\n let minD = Infinity;\n for (const p of visible) minD = Math.min(minD, Math.hypot(x - p.x, y - p.y) - (p.size || 0.28) / 2 - half);\n const centerPull = -0.12 * Math.hypot(x - 0.5, y - 0.5); // gentle balance toward center\n const score = (visible.length ? Math.min(minD, 0.5) : 0.3) + centerPull;\n if (score > bestScore) { bestScore = score; best = { x, y }; }\n }\n const pos = best || { x: 0.5, y: 0.5 };\n // A hair of deterministic scatter so the collage reads hand-placed.\n pos.x = clamp01(pos.x + jitter(el.id, 'x') * 0.015, half, 1 - half);\n pos.y = clamp01(pos.y + jitter(el.id, 'y') * 0.015, half, 1 - half);\n placed.push({ ...pos, size: el.size || 0.28, appearMs: el.appearMs, leaveMs: el.leaveMs });\n out.set(el.id, pos);\n }\n return out; // elementId -> {x, y}\n}\n// Stamp arranged positions onto the elements (unpinned only) — the STORED\n// positions are what every renderer reads, so preview == export.\nfunction withArrangedPositions(panel, opts) {\n if (!panel.autoArrange) return panel;\n const posMap = arrangeCanvas(panel, opts);\n return {\n ...panel,\n elements: (panel.elements || []).map((el) => (\n !el.pinned && posMap.has(el.id) ? { ...el, pos: posMap.get(el.id) } : el\n )),\n };\n}\n\n\nfunction docAspectRatio(doc) {\n const a = doc?.meta?.aspect || '16:9';\n if (a === '9:16') return 9 / 16;\n if (a === '1:1') return 1;\n return 16 / 9;\n}\nfunction rearranged(doc, panel) {\n // TEMPLATE (bundled slot layout): the template sets the STRUCTURE — slotted\n // elements go to their slots; the S10 spiral only places the OVERFLOW,\n // treating slotted elements as obstacles. Applies to auto AND templated\n // manual canvases (opting into a template IS asking for arrangement); a\n // plain manual canvas stays untouched. Pinned elements never move.\n const template = getCanvasTemplate(panel.template);\n if (template) {\n const slotted = applyTemplateToElements(panel.elements || [], template, { aspect: docAspectRatio(doc) });\n const overflowPanel = {\n ...panel,\n autoArrange: true,\n elements: slotted.map((el) => (el.pos ? { ...el, pinned: true } : el)), // slots+pins = obstacles for the spiral\n };\n const posMap = arrangeCanvas(overflowPanel, { aspect: docAspectRatio(doc) });\n return {\n ...panel,\n elements: slotted.map((el) => (!el.pinned && !el.pos && posMap.has(el.id) ? { ...el, pos: posMap.get(el.id) } : el)),\n };\n }\n return panel.autoArrange ? withArrangedPositions(panel, { aspect: docAspectRatio(doc) }) : panel;\n}\n\n\nfunction reflowedTemplateFor(panel, elements) {\n if (!panel.autoArrange || !panel.template) return panel.template;\n const tpl = getCanvasTemplate(panel.template);\n if (!tpl) return panel.template;\n const media = elements.filter((el) => el.kind === 'image' || el.kind === 'video').length;\n const texts = elements.filter((el) => el.kind === 'text').length;\n if (media > 0 && media <= tpl.slots.length) return panel.template; // still fits — slots are optional downward\n const next = pickTemplateForCanvas({ imageCount: media, textCount: texts, hint: \\`\\${tpl.scenario || ''} \\${panel.hint || ''}\\` });\n return next || panel.template;\n}\nfunction addCanvasElement(doc, panelId, element) {\n const panel = doc.strip.find((p) => p.panelId === panelId);\n if (!panel || panel.type !== 'canvas') throw new Error(\\`addCanvasElement: \\${panelId} is not a canvas panel\\`);\n const n = (panel.elements || []).length + 1;\n const el = { id: input.newId, ...element };\n const strip = doc.strip.map((p) => {\n if (p.panelId !== panelId) return p;\n const elements = [...(p.elements || []), el];\n return rearranged(doc, { ...p, template: reflowedTemplateFor(p, elements), elements });\n });\n return loadPanelDoc({ ...doc, strip });\n}\n\nconst loadPanelDoc=doc=>JSON.parse(JSON.stringify(doc));return {edit:addCanvasElement(input.doc,input.panelId,input.element)};\n`,tests:[]},wu=(e,t)=>V(e)===V(t),Tu=[`id`,`kind`,`pinned`,`appearMs`,`leaveMs`,`pos`,`box`,`size`,`tilt`,`weight`],Eu=[`pos`,`box`,`size`,`tilt`,`weight`],Du=new Set([`kind`,`src`,`query`,`source`,`pose`,`cutout`,`text`,`font`,`color`,`anim`,`wordTimes`,`sfx`,`entrance`,`muted`,`loop`,`speed`,`trimStartSec`,`pinned`,`appearMs`,`leaveMs`,...Eu]);function Ou(e,t,n){let r=e.strip.find(e=>e.panelId===t);I(r?.type===`canvas`&&Array.isArray(r.elements)&&L(n)&&[`image`,`video`,`text`].includes(n.kind)&&Object.keys(n).every(e=>Du.has(e)),`CANVAS_ADD`,`Choose a supported element on the current canvas.`);let i=structuredClone(n);B(i);let a=(e,t)=>{let n={origin:t};for(let t of Tu)if(e[t]!==void 0){let r=e[t];n[t]=t===`pos`&&L(r)?{x:r.x,y:r.y}:t===`box`&&L(r)?{w:r.w,h:r.h}:r}return n},o={panelId:t,type:`canvas`,elements:r.elements.map(a)};for(let e of[`template`,`autoArrange`,`hint`])r[e]!==void 0&&(o[e]=r[e]);let s=`u${r.elements.length+1}${Date.now().toString(36).slice(-4)}`;I(!r.elements.some(e=>e.id===s),`CANVAS_ADD`,`The new element identity is already in use. Try again.`);let c=a(i,`new`);for(let e of Object.keys(i))Tu.includes(e)||(c[e]={elementToken:e});let l={doc:{meta:{aspect:e.meta?.aspect||`16:9`},strip:[o]},panelId:t,element:c,newId:s};return B(l),{panel:r,input:l,captured:i}}function ku(e){let t=e.doc.strip[0],n=[...t.elements,{id:e.newId,...e.element}],r=t.template,i=en(r);if(t.autoArrange&&r&&i){let e=n.filter(e=>[`image`,`video`].includes(e.kind)).length,a=n.filter(e=>e.kind===`text`).length;e>0&&e<=i.slots.length||(r=rn({imageCount:e,textCount:a,hint:`${i.scenario||``} ${t.hint||``}`})||r)}let a={...t,...r===void 0?{}:{template:r},elements:n},o=e.doc.meta.aspect===`9:16`?9/16:e.doc.meta.aspect===`1:1`?1:16/9,s=en(r);if(s){let e=nn(n,s,{aspect:o}),t=kt({...a,autoArrange:!0,elements:e.map(e=>e.pos?{...e,pinned:!0}:e)},{aspect:o});a={...a,elements:e.map(e=>!e.pinned&&!e.pos&&t.has(e.id)?{...e,pos:t.get(e.id)}:e)}}else a.autoArrange&&(a=At(a,{aspect:o}));return{...e.doc,strip:[a]}}function Au(e,{panel:t,input:n,captured:r},i){let a=ku(n);B(a),B(i),I(wu(i,a),`CANVAS_ADD`,`The sandbox changed the requested element or another layout.`);let o=n.doc.strip[0],s=a.strip[0],c=i.strip[0],l=c.elements.map((e,i)=>{let a=i===t.elements.length,c=a?{id:n.newId,...r}:t.elements[i],l=a?n.element:o.elements[i],u=s.elements[i],d=c;for(let t of Eu){let n=Object.hasOwn(l,t),r=Object.hasOwn(u,t),i=r&&typeof u[t]==`object`&&u[t]!==null&&u[t]===l[t]?c[t]:e[t];(n!==r||r&&!wu(c[t],i))&&(d===c&&(d={...c}),r?d[t]=i:delete d[t])}return d}),u={...t,elements:l};return s.template!==void 0&&(u.template=c.template),{...e,strip:e.strip.map(e=>e===t?u:e)}}async function ju(e,t,n,{host:r,signal:i,assertCurrent:a,validateDocument:o}){let s=H(r),c=s.actor(),l=JSON.stringify({doc:e,element:n}),u=()=>{a(),I(c&&s.actor()===c&&!i?.aborted&&JSON.stringify({doc:e,element:n})===l,`STALE`,`The account or canvas addition changed.`)};u();let d=Ou(e,t,n),f=await s.run(Cu,{kind:`run`,input:d.input,signal:i,timeoutMs:15e3});u();let p=Au(e,d,f.outputs?.edit),m=p===e?e:o(p);return u(),m}function Mu({doc:e,projectId:t,panelId:n,canEdit:r,onDocChange:i,validateDocument:a,editLease:o,host:s}){let c=H(s),l=()=>c.actor(),[u,d]=(0,v.useState)(null),[f,p]=(0,v.useState)(``),m=(0,v.useRef)(null),h=(0,v.useRef)(!0),g=(0,v.useRef)(0),_=(0,v.useRef)(null),y=l();_.current={doc:e,projectId:t,panelId:n,canEdit:r,onDocChange:i,validateDocument:a,actor:y,services:c};let b=(0,v.useCallback)(()=>{g.current++,o?.current===m.current&&(o.current=null),m.current?.abort(),m.current=null,d(null)},[o]);return(0,v.useEffect)(()=>(h.current=!0,()=>{h.current=!1,g.current++,o?.current===m.current&&(o.current=null),m.current?.abort(),m.current=null}),[]),(0,v.useEffect)(()=>{b()},[e,t,n,r,y,c,b]),{change:(0,v.useCallback)(async r=>{let i=_.current;if(!i.doc||!i.canEdit||m.current||o?.current)return;if(i.services!==c||i.doc!==e||i.projectId!==t||i.panelId!==n||i.actor!==y||l()!==y){p(`The canvas changed. Review the new element again.`);return}let a=++g.current,s=new AbortController;m.current=s,o&&(o.current=s),d(i.panelId),p(``);let u,f=()=>{let e=_.current;I(h.current&&m.current===s&&!s.signal.aborted&&e.doc===i.doc&&e.projectId===i.projectId&&e.panelId===i.panelId&&e.canEdit&&e.services===c&&e.actor===i.actor&&l()===i.actor&&JSON.stringify(i.doc)===u,`STALE`,`The canvas changed. Review the current canvas elements again.`)};try{u=JSON.stringify(i.doc),f();let e=await ju(i.doc,i.panelId,r,{host:c,signal:s.signal,assertCurrent:f,validateDocument:i.validateDocument});if(f(),e!==i.doc){let t=JSON.stringify(e),n=!1;i.onDocChange(r=>{let o=_.current,d=!1;try{d=h.current&&g.current===a&&!s.signal.aborted&&o.doc===i.doc&&o.projectId===i.projectId&&o.panelId===i.panelId&&o.canEdit&&o.services===c&&o.actor===i.actor&&l()===i.actor&&JSON.stringify(e)===t&&JSON.stringify(r)===u&&JSON.stringify(i.doc)===u}catch{}return d?e:(n||(n=!0,queueMicrotask(()=>{h.current&&l()===i.actor&&_.current.projectId===i.projectId&&p(`The canvas changed before the element creation could be saved. Review the current canvas elements again.`)})),r)})}return e}catch(e){h.current&&!s.signal.aborted&&l()===i.actor&&_.current.projectId===i.projectId&&p(e.message||`The element creation could not be applied.`)}finally{m.current===s&&(o?.current===s&&(o.current=null),m.current=null,h.current&&d(null))}},[e,t,n,y,c]),pending:u,error:f,cancel:b}}let Nu={manifest:{schemaVersion:1,sdkVersion:`0.1.0`,id:`stillmade-internal.canvas-remove-element`,version:`1.0.0`,name:`Canvas element removal`,description:`Remove a canvas element and reflow its remaining template and layout.`,kind:`task`,runtime:`javascript`,inputs:{doc:{type:`json`},panelId:{type:`text`},elementId:{type:`text`}},outputs:{edit:{type:`json`}},permissions:{project:[],network:[],filesystem:[],secrets:[]}},code:`// COLLAGE CANVAS TEMPLATES — 20 bundled, versioned slot layouts (panel-image\n// only), each authored TWICE: a landscape layout and a portrait (9:16) layout\n// for the same scenario. A template is a LAYOUT DEFINITION, not a static\n// design: image SLOTS (center pos, target box, draw order = array order\n// back→front, optional tilt) and explicit TEXT SLOTS (role + deliberate\n// position), which the canvas system reads to place elements.\n//\n// Coordinates are normalized to the canvas frame (x/w = width fractions,\n// y/h = height fractions). An image FITS its slot box cover-cropped\n// (drawCollage's \\`box\\` rendering — aspect preserved, never distorted); fine\n// adjustment stays manual (drag pins, per spec S10). Image slots keep a\n// bottom safety margin (y + h/2 ≤ 0.95) so nothing crowds the frame edge.\n//\n// EVERY SLOT IS OPTIONAL — image and text alike. A template defines where\n// things GO if present; nothing is required. A canvas can use 2 of 7 image\n// slots, no text at all, or text with fewer images; unused slots are simply\n// empty (no placeholder, no gap artifact). And templates place, they never\n// time: each element still appears on ITS OWN voiceover beat (appearMs is\n// untouched by template application), so a canvas builds up slot by slot.\n//\n// Ownership contract (post-approval spec):\n// - AUTO canvases: the generator PICKS a template (pickTemplateForCanvas) from\n// image count + the beat's scenario hint; S10 self-arranging handles the\n// OVERFLOW beyond the slots (spiral around the slotted ones). Shown +\n// changeable afterward.\n// - MANUAL canvases: no template by default; opt-in from the picker.\n// - Switching is non-destructive: same elements, new positions; PINNED\n// elements are never moved (the pin IS the manual override).\n// - No fit / no pick → template null → the plain self-arranging layout.\n//\n// APPROVED by the owner 2026-07-22 (v2 sheet: both orientations, bottom\n// margins fixed). Bundled static definitions — versioned, never regenerated.\nconst CANVAS_TEMPLATE_VERSION = 2;\n\n// slot: { x, y, w, h, tilt? } — image slot (center + target box)\n// textSlot: { role, x, y, size, weight? } — role: headline | label | caption\n// Each template: landscape layout in \\`slots\\`/\\`textSlots\\`, portrait layout in\n// \\`pSlots\\`/\\`pTextSlots\\` (same scenario re-authored for a tall frame).\nconst T = (id, name, scenario, minImages, slots, textSlots, pSlots, pTextSlots) => (\n { id, name, scenario, minImages, slots, textSlots, pSlots, pTextSlots }\n);\n\nconst CANVAS_TEMPLATES = [\n T('hero-headline', 'Hero + headline', 'one subject, one line', 1,\n [{ x: 0.5, y: 0.58, w: 0.5, h: 0.62 }],\n [{ role: 'headline', x: 0.5, y: 0.14, size: 0.09, weight: 900 }],\n [{ x: 0.5, y: 0.55, w: 0.78, h: 0.5 }],\n [{ role: 'headline', x: 0.5, y: 0.13, size: 0.055, weight: 900 }]),\n\n T('hero-supporting', 'Hero + 2 supporting', 'main subject with two details', 3,\n [{ x: 0.34, y: 0.55, w: 0.42, h: 0.58 }, { x: 0.78, y: 0.33, w: 0.28, h: 0.32 }, { x: 0.78, y: 0.73, w: 0.28, h: 0.32 }],\n [{ role: 'headline', x: 0.34, y: 0.13, size: 0.08, weight: 900 }],\n [{ x: 0.5, y: 0.38, w: 0.78, h: 0.32 }, { x: 0.28, y: 0.72, w: 0.4, h: 0.2 }, { x: 0.72, y: 0.72, w: 0.4, h: 0.2 }],\n [{ role: 'headline', x: 0.5, y: 0.12, size: 0.05, weight: 900 }]),\n\n T('compare-2', 'Side-by-side compare', 'A vs B', 2,\n [{ x: 0.27, y: 0.5, w: 0.38, h: 0.5 }, { x: 0.73, y: 0.5, w: 0.38, h: 0.5 }],\n [{ role: 'headline', x: 0.5, y: 0.12, size: 0.08, weight: 900 },\n { role: 'label', x: 0.27, y: 0.84, size: 0.05, weight: 800 },\n { role: 'label', x: 0.73, y: 0.84, size: 0.05, weight: 800 }],\n [{ x: 0.5, y: 0.35, w: 0.72, h: 0.24 }, { x: 0.5, y: 0.72, w: 0.72, h: 0.24 }],\n [{ role: 'headline', x: 0.5, y: 0.11, size: 0.05, weight: 900 },\n { role: 'label', x: 0.5, y: 0.51, size: 0.032, weight: 800 },\n { role: 'label', x: 0.5, y: 0.88, size: 0.032, weight: 800 }]),\n\n T('three-across', 'Three across', 'three items', 3,\n [{ x: 0.2, y: 0.5, w: 0.26, h: 0.46 }, { x: 0.5, y: 0.5, w: 0.26, h: 0.46 }, { x: 0.8, y: 0.5, w: 0.26, h: 0.46 }],\n [{ role: 'headline', x: 0.5, y: 0.13, size: 0.08, weight: 900 },\n { role: 'caption', x: 0.5, y: 0.86, size: 0.045, weight: 600 }],\n [{ x: 0.5, y: 0.32, w: 0.64, h: 0.2 }, { x: 0.5, y: 0.57, w: 0.64, h: 0.2 }, { x: 0.5, y: 0.82, w: 0.64, h: 0.2 }],\n [{ role: 'headline', x: 0.5, y: 0.1, size: 0.05, weight: 900 },\n { role: 'caption', x: 0.5, y: 0.96, size: 0.028, weight: 600 }]),\n\n T('grid-2x2', 'Grid of four', 'four items', 4,\n [{ x: 0.3, y: 0.36, w: 0.32, h: 0.34 }, { x: 0.7, y: 0.36, w: 0.32, h: 0.34 },\n { x: 0.3, y: 0.74, w: 0.32, h: 0.34 }, { x: 0.7, y: 0.74, w: 0.32, h: 0.34 }],\n [{ role: 'headline', x: 0.5, y: 0.09, size: 0.07, weight: 900 }],\n [{ x: 0.28, y: 0.38, w: 0.4, h: 0.24 }, { x: 0.72, y: 0.38, w: 0.4, h: 0.24 },\n { x: 0.28, y: 0.68, w: 0.4, h: 0.24 }, { x: 0.72, y: 0.68, w: 0.4, h: 0.24 }],\n [{ role: 'headline', x: 0.5, y: 0.12, size: 0.05, weight: 900 }]),\n\n T('grid-3x3', 'Many small (3x3)', 'lots of items', 6,\n [0.22, 0.5, 0.78].flatMap((x) => [0.3, 0.56, 0.82].map((y) => ({ x, y, w: 0.24, h: 0.22 }))),\n [{ role: 'headline', x: 0.5, y: 0.08, size: 0.065, weight: 900 }],\n [0.2, 0.5, 0.8].flatMap((x) => [0.34, 0.58, 0.82].map((y) => ({ x, y, w: 0.27, h: 0.18 }))),\n [{ role: 'headline', x: 0.5, y: 0.1, size: 0.045, weight: 900 }]),\n\n T('big-left-stack-right', 'Big lead + stack', 'one lead, several follow-ups', 3,\n [{ x: 0.32, y: 0.54, w: 0.5, h: 0.62 }, { x: 0.79, y: 0.3, w: 0.3, h: 0.22 },\n { x: 0.79, y: 0.56, w: 0.3, h: 0.22 }, { x: 0.79, y: 0.82, w: 0.3, h: 0.22 }],\n [{ role: 'headline', x: 0.32, y: 0.13, size: 0.075, weight: 900 }],\n [{ x: 0.5, y: 0.4, w: 0.84, h: 0.34 }, { x: 0.2, y: 0.74, w: 0.26, h: 0.16 },\n { x: 0.5, y: 0.74, w: 0.26, h: 0.16 }, { x: 0.8, y: 0.74, w: 0.26, h: 0.16 }],\n [{ role: 'headline', x: 0.5, y: 0.12, size: 0.05, weight: 900 }]),\n\n T('vertical-stack', 'Vertical stack', 'ordered top to bottom', 2,\n [{ x: 0.55, y: 0.29, w: 0.36, h: 0.22 }, { x: 0.55, y: 0.55, w: 0.36, h: 0.22 }, { x: 0.55, y: 0.81, w: 0.36, h: 0.22 }],\n [{ role: 'headline', x: 0.55, y: 0.08, size: 0.065, weight: 900 },\n { role: 'label', x: 0.16, y: 0.55, size: 0.055, weight: 800 }],\n [{ x: 0.5, y: 0.3, w: 0.66, h: 0.2 }, { x: 0.5, y: 0.56, w: 0.66, h: 0.2 }, { x: 0.5, y: 0.82, w: 0.66, h: 0.2 }],\n [{ role: 'headline', x: 0.5, y: 0.09, size: 0.05, weight: 900 },\n { role: 'label', x: 0.24, y: 0.17, size: 0.032, weight: 800 }]),\n\n T('scatter', 'Scattered collage', 'loose, hand-thrown feel', 3,\n [{ x: 0.26, y: 0.36, w: 0.28, h: 0.32, tilt: -6 }, { x: 0.68, y: 0.3, w: 0.26, h: 0.3, tilt: 4 },\n { x: 0.44, y: 0.66, w: 0.27, h: 0.31, tilt: 3 }, { x: 0.8, y: 0.62, w: 0.25, h: 0.29, tilt: -5 },\n { x: 0.58, y: 0.46, w: 0.24, h: 0.28, tilt: 2 }],\n [{ role: 'headline', x: 0.5, y: 0.1, size: 0.075, weight: 900 }],\n [{ x: 0.32, y: 0.3, w: 0.46, h: 0.2, tilt: -6 }, { x: 0.7, y: 0.26, w: 0.42, h: 0.18, tilt: 4 },\n { x: 0.4, y: 0.56, w: 0.44, h: 0.2, tilt: 3 }, { x: 0.74, y: 0.6, w: 0.4, h: 0.18, tilt: -5 },\n { x: 0.5, y: 0.82, w: 0.44, h: 0.19, tilt: 2 }],\n [{ role: 'headline', x: 0.5, y: 0.09, size: 0.045, weight: 900 }]),\n\n T('timeline-row', 'Row / timeline', 'steps in order', 3,\n [{ x: 0.14, y: 0.52, w: 0.2, h: 0.38 }, { x: 0.38, y: 0.52, w: 0.2, h: 0.38 },\n { x: 0.62, y: 0.52, w: 0.2, h: 0.38 }, { x: 0.86, y: 0.52, w: 0.2, h: 0.38 }],\n [{ role: 'headline', x: 0.5, y: 0.15, size: 0.075, weight: 900 },\n { role: 'caption', x: 0.5, y: 0.85, size: 0.045, weight: 600 }],\n [{ x: 0.35, y: 0.28, w: 0.5, h: 0.15 }, { x: 0.65, y: 0.47, w: 0.5, h: 0.15 },\n { x: 0.35, y: 0.66, w: 0.5, h: 0.15 }, { x: 0.65, y: 0.85, w: 0.5, h: 0.15 }],\n [{ role: 'headline', x: 0.5, y: 0.12, size: 0.05, weight: 900 }]),\n\n T('center-satellites', 'Center + satellites', 'one core idea, orbiting parts', 3,\n [{ x: 0.5, y: 0.52, w: 0.34, h: 0.42 }, { x: 0.17, y: 0.3, w: 0.2, h: 0.26 }, { x: 0.83, y: 0.3, w: 0.2, h: 0.26 },\n { x: 0.17, y: 0.77, w: 0.2, h: 0.26 }, { x: 0.83, y: 0.77, w: 0.2, h: 0.26 }],\n [{ role: 'headline', x: 0.5, y: 0.09, size: 0.065, weight: 900 }],\n [{ x: 0.5, y: 0.52, w: 0.56, h: 0.28 }, { x: 0.2, y: 0.28, w: 0.32, h: 0.16 }, { x: 0.8, y: 0.28, w: 0.32, h: 0.16 },\n { x: 0.2, y: 0.78, w: 0.32, h: 0.16 }, { x: 0.8, y: 0.78, w: 0.32, h: 0.16 }],\n [{ role: 'headline', x: 0.5, y: 0.1, size: 0.045, weight: 900 }]),\n\n T('corner-big-text', 'Corner images, big text', 'statement first, proof beside it', 2,\n [{ x: 0.72, y: 0.4, w: 0.32, h: 0.38 }, { x: 0.52, y: 0.72, w: 0.28, h: 0.34 }, { x: 0.85, y: 0.76, w: 0.24, h: 0.3 }],\n [{ role: 'headline', x: 0.26, y: 0.26, size: 0.105, weight: 900 },\n { role: 'label', x: 0.26, y: 0.42, size: 0.05, weight: 600 }],\n [{ x: 0.36, y: 0.56, w: 0.5, h: 0.22 }, { x: 0.7, y: 0.7, w: 0.44, h: 0.2 }, { x: 0.4, y: 0.84, w: 0.4, h: 0.18 }],\n [{ role: 'headline', x: 0.5, y: 0.19, size: 0.065, weight: 900 },\n { role: 'label', x: 0.5, y: 0.31, size: 0.034, weight: 600 }]),\n\n T('title-top-row', 'Title top, images below', 'title screen with evidence', 2,\n [{ x: 0.22, y: 0.62, w: 0.28, h: 0.44 }, { x: 0.5, y: 0.62, w: 0.28, h: 0.44 }, { x: 0.78, y: 0.62, w: 0.28, h: 0.44 }],\n [{ role: 'headline', x: 0.5, y: 0.17, size: 0.1, weight: 900 }],\n [{ x: 0.5, y: 0.4, w: 0.7, h: 0.2 }, { x: 0.5, y: 0.64, w: 0.7, h: 0.2 }, { x: 0.5, y: 0.86, w: 0.7, h: 0.16 }],\n [{ role: 'headline', x: 0.5, y: 0.15, size: 0.06, weight: 900 }]),\n\n T('large-caption', 'One large + caption', 'let the image speak', 1,\n [{ x: 0.5, y: 0.47, w: 0.56, h: 0.6 }],\n [{ role: 'label', x: 0.15, y: 0.1, size: 0.045, weight: 800 },\n { role: 'caption', x: 0.5, y: 0.85, size: 0.055, weight: 600 }],\n [{ x: 0.5, y: 0.47, w: 0.82, h: 0.44 }],\n [{ role: 'label', x: 0.24, y: 0.12, size: 0.032, weight: 800 },\n { role: 'caption', x: 0.5, y: 0.78, size: 0.034, weight: 600 }]),\n\n T('staggered-diagonal', 'Staggered diagonal', 'progression with motion', 3,\n [{ x: 0.18, y: 0.26, w: 0.24, h: 0.3, tilt: -3 }, { x: 0.42, y: 0.45, w: 0.24, h: 0.3, tilt: 3 },\n { x: 0.64, y: 0.62, w: 0.24, h: 0.3, tilt: -3 }, { x: 0.86, y: 0.79, w: 0.24, h: 0.3, tilt: 3 }],\n [{ role: 'headline', x: 0.74, y: 0.16, size: 0.075, weight: 900 }],\n [{ x: 0.28, y: 0.3, w: 0.42, h: 0.18, tilt: -3 }, { x: 0.62, y: 0.46, w: 0.42, h: 0.18, tilt: 3 },\n { x: 0.36, y: 0.62, w: 0.42, h: 0.18, tilt: -3 }, { x: 0.68, y: 0.78, w: 0.42, h: 0.18, tilt: 3 }],\n [{ role: 'headline', x: 0.5, y: 0.12, size: 0.05, weight: 900 }]),\n\n T('overlap-stack', 'Overlapping stack', 'a deliberate pile', 2,\n [{ x: 0.42, y: 0.5, w: 0.36, h: 0.46, tilt: -5 }, { x: 0.54, y: 0.56, w: 0.36, h: 0.46, tilt: 3 },\n { x: 0.63, y: 0.46, w: 0.36, h: 0.46, tilt: -2 }],\n [{ role: 'headline', x: 0.5, y: 0.12, size: 0.08, weight: 900 },\n { role: 'caption', x: 0.5, y: 0.89, size: 0.045, weight: 600 }],\n [{ x: 0.44, y: 0.42, w: 0.58, h: 0.26, tilt: -5 }, { x: 0.58, y: 0.53, w: 0.58, h: 0.26, tilt: 3 },\n { x: 0.46, y: 0.64, w: 0.58, h: 0.26, tilt: -2 }],\n [{ role: 'headline', x: 0.5, y: 0.12, size: 0.05, weight: 900 },\n { role: 'caption', x: 0.5, y: 0.86, size: 0.032, weight: 600 }]),\n\n T('banner-row', 'Wide banner + small row', 'one wide scene, details under', 2,\n [{ x: 0.5, y: 0.36, w: 0.84, h: 0.36 }, { x: 0.25, y: 0.77, w: 0.24, h: 0.26 },\n { x: 0.5, y: 0.77, w: 0.24, h: 0.26 }, { x: 0.75, y: 0.77, w: 0.24, h: 0.26 }],\n [{ role: 'headline', x: 0.5, y: 0.09, size: 0.065, weight: 900 }],\n [{ x: 0.5, y: 0.36, w: 0.86, h: 0.26 }, { x: 0.22, y: 0.66, w: 0.28, h: 0.16 },\n { x: 0.5, y: 0.66, w: 0.28, h: 0.16 }, { x: 0.78, y: 0.66, w: 0.28, h: 0.16 }],\n [{ role: 'headline', x: 0.5, y: 0.13, size: 0.05, weight: 900 },\n { role: 'caption', x: 0.5, y: 0.82, size: 0.032, weight: 600 }]),\n\n T('quadrant-labels', 'Quadrants with labels', 'four named things', 4,\n [{ x: 0.28, y: 0.3, w: 0.3, h: 0.3 }, { x: 0.72, y: 0.3, w: 0.3, h: 0.3 },\n { x: 0.28, y: 0.71, w: 0.3, h: 0.3 }, { x: 0.72, y: 0.71, w: 0.3, h: 0.3 }],\n [{ role: 'headline', x: 0.5, y: 0.07, size: 0.06, weight: 900 },\n { role: 'label', x: 0.28, y: 0.49, size: 0.042, weight: 800 },\n { role: 'label', x: 0.72, y: 0.49, size: 0.042, weight: 800 },\n { role: 'label', x: 0.28, y: 0.9, size: 0.042, weight: 800 },\n { role: 'label', x: 0.72, y: 0.9, size: 0.042, weight: 800 }],\n [{ x: 0.28, y: 0.32, w: 0.38, h: 0.2 }, { x: 0.72, y: 0.32, w: 0.38, h: 0.2 },\n { x: 0.28, y: 0.64, w: 0.38, h: 0.2 }, { x: 0.72, y: 0.64, w: 0.38, h: 0.2 }],\n [{ role: 'headline', x: 0.5, y: 0.1, size: 0.045, weight: 900 },\n { role: 'label', x: 0.28, y: 0.45, size: 0.028, weight: 800 },\n { role: 'label', x: 0.72, y: 0.45, size: 0.028, weight: 800 },\n { role: 'label', x: 0.28, y: 0.77, size: 0.028, weight: 800 },\n { role: 'label', x: 0.72, y: 0.77, size: 0.028, weight: 800 }]),\n\n T('pyramid-3', 'Pyramid of three', 'one above two', 3,\n [{ x: 0.5, y: 0.32, w: 0.3, h: 0.32 }, { x: 0.32, y: 0.71, w: 0.3, h: 0.32 }, { x: 0.68, y: 0.71, w: 0.3, h: 0.32 }],\n [{ role: 'headline', x: 0.5, y: 0.08, size: 0.065, weight: 900 },\n { role: 'caption', x: 0.5, y: 0.92, size: 0.04, weight: 600 }],\n [{ x: 0.5, y: 0.34, w: 0.5, h: 0.22 }, { x: 0.27, y: 0.62, w: 0.42, h: 0.18 }, { x: 0.73, y: 0.62, w: 0.42, h: 0.18 }],\n [{ role: 'headline', x: 0.5, y: 0.1, size: 0.05, weight: 900 },\n { role: 'caption', x: 0.5, y: 0.79, size: 0.032, weight: 600 }]),\n\n T('mosaic-dense', 'Dense mosaic', 'everything at once', 5,\n [{ x: 0.3, y: 0.4, w: 0.34, h: 0.42 }, { x: 0.62, y: 0.29, w: 0.24, h: 0.26 }, { x: 0.86, y: 0.33, w: 0.2, h: 0.28 },\n { x: 0.19, y: 0.78, w: 0.24, h: 0.26 }, { x: 0.47, y: 0.77, w: 0.26, h: 0.28 }, { x: 0.73, y: 0.73, w: 0.22, h: 0.24 },\n { x: 0.91, y: 0.76, w: 0.14, h: 0.18 }],\n [{ role: 'headline', x: 0.5, y: 0.09, size: 0.06, weight: 900 }],\n [{ x: 0.32, y: 0.3, w: 0.5, h: 0.2 }, { x: 0.78, y: 0.26, w: 0.36, h: 0.16 }, { x: 0.24, y: 0.52, w: 0.4, h: 0.16 },\n { x: 0.68, y: 0.5, w: 0.44, h: 0.18 }, { x: 0.3, y: 0.74, w: 0.42, h: 0.16 }, { x: 0.74, y: 0.73, w: 0.4, h: 0.16 },\n { x: 0.5, y: 0.89, w: 0.5, h: 0.1 }],\n [{ role: 'headline', x: 0.5, y: 0.1, size: 0.045, weight: 900 }]),\n];\n\nconst byId = new Map(CANVAS_TEMPLATES.map((t) => [t.id, t]));\nconst getCanvasTemplate = (id) => byId.get(id) || null; // unknown/renamed id → no template (never a load failure)\n\n// The layout for a given canvas aspect: tall frames (ratio < 1) use the\n// portrait variant, everything else the landscape one.\nfunction templateLayout(template, aspect = 16 / 9) {\n if (!template) return null;\n return aspect < 1\n ? { slots: template.pSlots, textSlots: template.pTextSlots }\n : { slots: template.slots, textSlots: template.textSlots };\n}\n\n// ── Reflow: elements → a template's slots (pure, non-destructive) ───────────\n// Unpinned IMAGES fill image slots in appear order; unpinned TEXTS fill text\n// slots in slot order (headline first, as authored). EVERY SLOT IS OPTIONAL:\n// fewer elements than slots just leaves the extra slots empty. Elements\n// beyond the slots OVERFLOW: images lose their box (back to natural-aspect\n// sizing) and get pos:null so the S10 spiral places them around the slotted\n// ones; extra texts keep their position. PINNED elements are never touched —\n// the pin IS the manual override, and it survives every template switch.\n// TIMING IS NEVER TOUCHED: appearMs/leaveMs pass through untouched, so each\n// element still pops on its own voiceover beat.\nfunction applyTemplateToElements(elements, template, { aspect = 16 / 9 } = {}) {\n if (!template) {\n // Clearing a template touches ONLY slot-derived elements (the ones with a\n // box): the box comes off, the position STAYS — on an auto canvas the\n // spiral re-places unpinned elements anyway, and on a manual canvas the\n // old slot spot is a sane resting place (never a pos:null pile at\n // center, never a wipe of hand placements that were never slotted).\n return (elements || []).map((el) => {\n if (el.pinned || el.kind !== 'image' || !el.box) return el;\n const { box, ...rest } = el;\n return rest;\n });\n }\n const layout = templateLayout(template, aspect);\n const byAppear = (a, b) => (a.appearMs || 0) - (b.appearMs || 0);\n const images = (elements || []).filter((el) => el.kind === 'image' && !el.pinned).sort(byAppear);\n const texts = (elements || []).filter((el) => el.kind === 'text' && !el.pinned).sort(byAppear);\n const imgSlot = new Map();\n images.forEach((el, i) => { if (i < layout.slots.length) imgSlot.set(el.id, layout.slots[i]); });\n const textSlot = new Map();\n texts.forEach((el, i) => { if (i < layout.textSlots.length) textSlot.set(el.id, layout.textSlots[i]); });\n return (elements || []).map((el) => {\n if (el.pinned) return el;\n if (el.kind === 'image') {\n const s = imgSlot.get(el.id);\n if (!s) { const { box, ...rest } = el; return { ...rest, pos: null }; } // overflow → spiral\n return { ...el, pos: { x: s.x, y: s.y }, box: { w: s.w, h: s.h }, size: s.w, tilt: s.tilt || 0 };\n }\n const s = textSlot.get(el.id);\n if (!s) return el; // extra text keeps its place\n return { ...el, pos: { x: s.x, y: s.y }, size: s.size, weight: s.weight || el.weight || 800 };\n });\n}\n\n// ── Auto-pick (post-approval spec): image count + scenario hint ─────────────\n// The hint is the planner's free-text reason for the beat; keyword classes\n// beat pure counts (compare → side-by-side, steps/list → row, many → mosaic).\n// Returns a template id or null (no fit → the plain self-arranging layout).\nfunction pickTemplateForCanvas({ imageCount = 0, textCount = 0, hint = '' } = {}) {\n if (!imageCount) return null;\n const h = String(hint || '').toLowerCase();\n if (imageCount === 2 && /\\\\bvs\\\\b|versus|compar|before.*after|either/.test(h)) return 'compare-2';\n if (imageCount >= 3 && /step|order|sequence|timeline|process|journey|stages/.test(h)) return 'timeline-row';\n if (imageCount >= 3 && /list|lists|enumerat|items|examples|types|kinds/.test(h)) return imageCount >= 5 ? 'mosaic-dense' : 'three-across';\n if (imageCount === 1) return textCount > 1 ? 'large-caption' : 'hero-headline';\n if (imageCount === 2) return 'compare-2';\n if (imageCount === 3) return 'three-across';\n if (imageCount === 4) return 'grid-2x2';\n if (imageCount === 5) return 'center-satellites';\n if (imageCount <= 7) return 'mosaic-dense';\n return 'grid-3x3';\n}\n\nconst hash = (s) => {\n let h = 5381;\n const str = String(s || '');\n for (let i = 0; i < str.length; i++) h = ((h << 5) + h + str.charCodeAt(i)) >>> 0;\n return h;\n};\n// Deterministic pseudo-jitter in [-1, 1] from an id + salt.\nconst jitter = (id, salt) => ((hash(\\`\\${id}|\\${salt}\\`) % 2000) / 1000) - 1;\n\n// ── Self-arranging layout (S10) ──────────────────────────────────────────────\n// Applies to AUTO-ARRANGED canvases only (panel.autoArrange). Deterministic\n// greedy placement in APPEAR ORDER: each unpinned image takes the best slot on\n// a golden-angle spiral around the canvas center — maximizing distance from\n// every element already visible when it appears — so the composition stays\n// balanced as it accumulates without ever moving an already-placed element\n// (tidy-by-construction; nothing jumps). PINNED elements (user overrides) and\n// manual canvases keep their positions exactly; auto elements arrange AROUND\n// pinned ones (they're obstacles in the distance test).\nconst SPIRAL_SLOTS = 48;\nconst GOLDEN = 2.399963229728653; // golden angle (rad)\nfunction spiralSlot(k, aspect = 16 / 9) {\n // Slots sweep outward from the center, filling the frame evenly; x spread is\n // wider than y for landscape canvases.\n const r = 0.08 + 0.40 * Math.sqrt((k + 0.5) / SPIRAL_SLOTS);\n const a = k * GOLDEN;\n return { x: 0.5 + r * Math.cos(a), y: 0.5 + r * Math.sin(a) * (aspect > 1 ? 0.9 : 1.1) };\n}\nconst clamp01 = (v, lo, hi) => Math.max(lo, Math.min(hi, v));\n\nfunction arrangeCanvas(panel, { aspect = 16 / 9 } = {}) {\n const els = (panel?.elements || []).slice().sort((a, b) => (a.appearMs || 0) - (b.appearMs || 0));\n const placed = []; // { x, y, size, appearMs, leaveMs }\n const out = new Map();\n for (const el of els) {\n const half = (el.kind === 'image' ? (el.size || 0.28) : 0.18) / 2;\n if (el.pinned || !panel.autoArrange) {\n if (el.pos) { placed.push({ ...el.pos, size: el.size || 0.28, appearMs: el.appearMs, leaveMs: el.leaveMs }); out.set(el.id, el.pos); }\n continue;\n }\n // Distance test only against elements VISIBLE when this one appears —\n // an element that already LEFT frees its space.\n const visible = placed.filter((p) => (p.leaveMs == null || p.leaveMs > el.appearMs));\n let best = null; let bestScore = -Infinity;\n for (let k = 0; k < SPIRAL_SLOTS; k++) {\n // Slot order is salted per-element id so different canvases don't all\n // start identically, while staying fully deterministic.\n const slot = spiralSlot((k + (hash(el.id) % SPIRAL_SLOTS)) % SPIRAL_SLOTS, aspect);\n const x = clamp01(slot.x, half + 0.03, 1 - half - 0.03);\n const y = clamp01(slot.y, half + 0.05, 1 - half - 0.05);\n let minD = Infinity;\n for (const p of visible) minD = Math.min(minD, Math.hypot(x - p.x, y - p.y) - (p.size || 0.28) / 2 - half);\n const centerPull = -0.12 * Math.hypot(x - 0.5, y - 0.5); // gentle balance toward center\n const score = (visible.length ? Math.min(minD, 0.5) : 0.3) + centerPull;\n if (score > bestScore) { bestScore = score; best = { x, y }; }\n }\n const pos = best || { x: 0.5, y: 0.5 };\n // A hair of deterministic scatter so the collage reads hand-placed.\n pos.x = clamp01(pos.x + jitter(el.id, 'x') * 0.015, half, 1 - half);\n pos.y = clamp01(pos.y + jitter(el.id, 'y') * 0.015, half, 1 - half);\n placed.push({ ...pos, size: el.size || 0.28, appearMs: el.appearMs, leaveMs: el.leaveMs });\n out.set(el.id, pos);\n }\n return out; // elementId -> {x, y}\n}\n// Stamp arranged positions onto the elements (unpinned only) — the STORED\n// positions are what every renderer reads, so preview == export.\nfunction withArrangedPositions(panel, opts) {\n if (!panel.autoArrange) return panel;\n const posMap = arrangeCanvas(panel, opts);\n return {\n ...panel,\n elements: (panel.elements || []).map((el) => (\n !el.pinned && posMap.has(el.id) ? { ...el, pos: posMap.get(el.id) } : el\n )),\n };\n}\n\n\nfunction docAspectRatio(doc) {\n const a = doc?.meta?.aspect || '16:9';\n if (a === '9:16') return 9 / 16;\n if (a === '1:1') return 1;\n return 16 / 9;\n}\nfunction rearranged(doc, panel) {\n // TEMPLATE (bundled slot layout): the template sets the STRUCTURE — slotted\n // elements go to their slots; the S10 spiral only places the OVERFLOW,\n // treating slotted elements as obstacles. Applies to auto AND templated\n // manual canvases (opting into a template IS asking for arrangement); a\n // plain manual canvas stays untouched. Pinned elements never move.\n const template = getCanvasTemplate(panel.template);\n if (template) {\n const slotted = applyTemplateToElements(panel.elements || [], template, { aspect: docAspectRatio(doc) });\n const overflowPanel = {\n ...panel,\n autoArrange: true,\n elements: slotted.map((el) => (el.pos ? { ...el, pinned: true } : el)), // slots+pins = obstacles for the spiral\n };\n const posMap = arrangeCanvas(overflowPanel, { aspect: docAspectRatio(doc) });\n return {\n ...panel,\n elements: slotted.map((el) => (!el.pinned && !el.pos && posMap.has(el.id) ? { ...el, pos: posMap.get(el.id) } : el)),\n };\n }\n return panel.autoArrange ? withArrangedPositions(panel, { aspect: docAspectRatio(doc) }) : panel;\n}\n\nfunction reflowedTemplateFor(panel, elements) {\n if (!panel.autoArrange || !panel.template) return panel.template;\n const tpl = getCanvasTemplate(panel.template);\n if (!tpl) return panel.template;\n const media = elements.filter((el) => el.kind === 'image' || el.kind === 'video').length;\n const texts = elements.filter((el) => el.kind === 'text').length;\n if (media > 0 && media <= tpl.slots.length) return panel.template; // still fits — slots are optional downward\n const next = pickTemplateForCanvas({ imageCount: media, textCount: texts, hint: \\`\\${tpl.scenario || ''} \\${panel.hint || ''}\\` });\n return next || panel.template;\n}\n\nfunction removeCanvasElementMove(doc, panelId, elementId, index) {\n const strip = doc.strip.map((p) => {\n if (p.panelId !== panelId) return p;\n return {\n ...p,\n elements: (p.elements || []).map((el) => {\n if (el.id !== elementId || !Array.isArray(el.moves)) return el;\n // Delete by the index into the TIME-SORTED view — that's the order the\n // inspector renders and passes back. Also leaves the stored array sorted.\n const moves = el.moves.slice().sort((a, b) => (a.atMs || 0) - (b.atMs || 0)).filter((_, i) => i !== index);\n return { ...el, moves };\n }),\n };\n });\n return loadPanelDoc({ ...doc, strip });\n}\n// SLOT COUNTS ARE RANGES (addon Part 2): when an AUTO canvas's media count\n// outgrows its template's slots, swap to the best-fitting template for the new\n// count (same scenario hint) before arranging — a single-slot hero grows into\n// a two-up, then a grid, and collapses back. Manual canvases never auto-swap\n// (S10 — reflow only when the user asks); pinned placements survive either way\n// because arrangement never moves pinned elements.\nfunction reflowedTemplateFor(panel, elements) {\n if (!panel.autoArrange || !panel.template) return panel.template;\n const tpl = getCanvasTemplate(panel.template);\n if (!tpl) return panel.template;\n const media = elements.filter((el) => el.kind === 'image' || el.kind === 'video').length;\n const texts = elements.filter((el) => el.kind === 'text').length;\n if (media > 0 && media <= tpl.slots.length) return panel.template; // still fits — slots are optional downward\n const next = pickTemplateForCanvas({ imageCount: media, textCount: texts, hint: \\`\\${tpl.scenario || ''} \\${panel.hint || ''}\\` });\n return next || panel.template;\n}\nfunction addCanvasElement(doc, panelId, element) {\n const panel = doc.strip.find((p) => p.panelId === panelId);\n if (!panel || panel.type !== 'canvas') throw new Error(\\`addCanvasElement: \\${panelId} is not a canvas panel\\`);\n const n = (panel.elements || []).length + 1;\n const el = { id: \\`u\\${n}\\${Date.now().toString(36).slice(-4)}\\`, ...element };\n const strip = doc.strip.map((p) => {\n if (p.panelId !== panelId) return p;\n const elements = [...(p.elements || []), el];\n return rearranged(doc, { ...p, template: reflowedTemplateFor(p, elements), elements });\n });\n return loadPanelDoc({ ...doc, strip });\n}\nfunction removeCanvasElement(doc, panelId, elementId) {\n const strip = doc.strip.map((p) => {\n if (p.panelId !== panelId) return p;\n const elements = (p.elements || []).filter((el) => el.id !== elementId);\n return rearranged(doc, { ...p, template: reflowedTemplateFor(p, elements), elements });\n });\n return loadPanelDoc({ ...doc, strip });\n}\n\n\nconst loadPanelDoc=doc=>doc;return {edit:removeCanvasElement(input.doc,input.panelId,input.elementId)};`,tests:[]},Pu=(e,t)=>V(e)===V(t),Fu=[`id`,`kind`,`pinned`,`appearMs`,`leaveMs`,`pos`,`box`,`size`,`tilt`,`weight`],Iu=[`pos`,`box`,`size`,`tilt`,`weight`];function Lu(e,t,n){let r=e.strip.find(e=>e.panelId===t);I(r?.type===`canvas`&&Array.isArray(r.elements)&&typeof n==`string`,`CANVAS_REMOVE`,`Choose an element on the current canvas.`);let i={panelId:t,type:`canvas`,elements:(r.elements||[]).map((e,t)=>{let n={origin:t};for(let t of Fu)if(e[t]!==void 0){let r=e[t];n[t]=t===`pos`&&L(r)?{x:r.x,y:r.y}:t===`box`&&L(r)?{w:r.w,h:r.h}:r}return n})};for(let e of[`template`,`autoArrange`,`hint`])r[e]!==void 0&&(i[e]=r[e]);let a={doc:{meta:{aspect:e.meta?.aspect||`16:9`},strip:[i]},panelId:t,elementId:n};return B(a),{panel:r,input:a}}function Ru(e){let t=e.doc.strip[0],n=t.elements.filter(t=>t.id!==e.elementId),r=t.template,i=en(r);if(t.autoArrange&&r&&i){let e=n.filter(e=>[`image`,`video`].includes(e.kind)).length,a=n.filter(e=>e.kind===`text`).length;e>0&&e<=i.slots.length||(r=rn({imageCount:e,textCount:a,hint:`${i.scenario||``} ${t.hint||``}`})||r)}let a={...t,...r===void 0?{}:{template:r},elements:n},o=e.doc.meta.aspect===`9:16`?9/16:e.doc.meta.aspect===`1:1`?1:16/9,s=en(r);if(s){let e=nn(n,s,{aspect:o}),t=kt({...a,autoArrange:!0,elements:e.map(e=>e.pos?{...e,pinned:!0}:e)},{aspect:o});a={...a,elements:e.map(e=>!e.pinned&&!e.pos&&t.has(e.id)?{...e,pos:t.get(e.id)}:e)}}else a.autoArrange&&(a=At(a,{aspect:o}));return{...e.doc,strip:[a]}}function zu(e,{panel:t,input:n},r){let i=Ru(n);B(i),B(r),I(Pu(r,i),`CANVAS_REMOVE`,`The sandbox changed a different element or layout.`);let a=n.doc.strip[0],o=i.strip[0],s=r.strip[0],c=s.elements.length!==t.elements.length||!Pu(t.template??null,o.template??null),l=s.elements.map((e,n)=>{let r=t.elements[e.origin],i=a.elements[e.origin],s=o.elements[n],l=r;for(let t of Iu){let n=Object.hasOwn(i,t),a=Object.hasOwn(s,t),o=a&&typeof s[t]==`object`&&s[t]!==null&&s[t]===i[t]?r[t]:e[t];(n!==a||a&&!Pu(r[t],o))&&(l===r&&(l={...r}),a?l[t]=o:delete l[t])}return l!==r&&(c=!0),l});if(!c)return e;let u={...t,elements:l};return o.template!==void 0&&(u.template=s.template),{...e,strip:e.strip.map(e=>e===t?u:e)}}async function Bu(e,t,n,{host:r,signal:i,assertCurrent:a,validateDocument:o}){let s=H(r),c=s.actor(),l=V(e),u=()=>{a?.(),I(c&&s.actor()===c&&!i?.aborted&&V(e)===l,`STALE`,`Canvas removal cancelled or its document changed.`)};u();let d=Lu(e,t,n);u();let f=await s.run(Nu,{kind:`run`,input:d.input,signal:i,timeoutMs:15e3});u();let p=zu(e,d,f.outputs?.edit),m=p===e?e:o(p);return u(),m}function Vu({doc:e,projectId:t,panelId:n,canEdit:r,onDocChange:i,validateDocument:a,editLease:o,host:s}){let c=H(s),l=()=>c.actor(),[u,d]=(0,v.useState)(null),[f,p]=(0,v.useState)(``),m=(0,v.useRef)(null),h=(0,v.useRef)(!0),g=(0,v.useRef)(0),_=(0,v.useRef)(null),y=l();_.current={doc:e,projectId:t,panelId:n,canEdit:r,onDocChange:i,validateDocument:a,actor:y,services:c};let b=(0,v.useCallback)(()=>{g.current++,o?.current===m.current&&(o.current=null),m.current?.abort(),m.current=null,d(null)},[o]);return(0,v.useEffect)(()=>(h.current=!0,()=>{h.current=!1,g.current++,o?.current===m.current&&(o.current=null),m.current?.abort(),m.current=null}),[]),(0,v.useEffect)(()=>{b()},[e,t,n,r,y,c,b]),{change:(0,v.useCallback)(async e=>{let t=_.current;if(!t.doc||!t.canEdit||m.current||o?.current||t.services!==c)return;let n=++g.current,r=new AbortController;m.current=r,o&&(o.current=r),d(e),p(``);let i,a=()=>{let e=_.current;I(h.current&&m.current===r&&!r.signal.aborted&&e.doc===t.doc&&e.projectId===t.projectId&&e.panelId===t.panelId&&e.canEdit&&e.services===c&&e.actor===t.actor&&l()===t.actor&&JSON.stringify(t.doc)===i,`STALE`,`The canvas changed. Review the current remaining elements again.`)};try{i=JSON.stringify(t.doc),a();let o=await Bu(t.doc,t.panelId,e,{host:c,signal:r.signal,assertCurrent:a,validateDocument:t.validateDocument});if(a(),o!==t.doc){let e=JSON.stringify(o),a=!1;t.onDocChange(s=>{let u=_.current,d=!1;try{d=h.current&&g.current===n&&!r.signal.aborted&&u.doc===t.doc&&u.projectId===t.projectId&&u.panelId===t.panelId&&u.canEdit&&u.services===c&&u.actor===t.actor&&l()===t.actor&&JSON.stringify(o)===e&&JSON.stringify(s)===i&&JSON.stringify(t.doc)===i}catch{}return d?o:(a||(a=!0,queueMicrotask(()=>{h.current&&l()===t.actor&&_.current.projectId===t.projectId&&p(`The canvas changed before the element deletion could be saved. Review the current remaining elements again.`)})),s)})}return o}catch(e){h.current&&!r.signal.aborted&&l()===t.actor&&_.current.projectId===t.projectId&&p(e.message||`The element deletion could not be applied.`)}finally{m.current===r&&(o?.current===r&&(o.current=null),m.current=null,h.current&&d(null))}},[c]),pending:u,error:f,cancel:b}}let Hu={manifest:{schemaVersion:1,sdkVersion:`0.1.0`,id:`stillmade-internal.canvas-typewriter`,version:`1.0.0`,name:`Canvas narration typewriter`,description:`Replace a canvas with voiceover-synchronized typewriter lines.`,kind:`task`,runtime:`javascript`,inputs:{doc:{type:`json`},panelId:{type:`text`}},outputs:{edit:{type:`json`}},permissions:{project:[],network:[],filesystem:[],secrets:[]}},code:`// Shared existing visual lead for strip timing and Board assembly. Milliseconds.\nconst VISUAL_LEAD_MS = 75;\n\nfunction voPhrasesForPanel(doc, panel) {\n const inWin = (w) => {\n const mid = (Number(w.startMs) + Number(w.endMs)) / 2;\n return mid >= panel.startMs && mid < panel.startMs + panel.durationMs;\n };\n const words = (doc?.audio?.words || []).filter((w) => w && String(w.text || '').trim() && inWin(w));\n const groups = [];\n let cur = [];\n for (let i = 0; i < words.length; i++) {\n cur.push(words[i]);\n const gap = i + 1 < words.length ? Number(words[i + 1].startMs) - Number(words[i].endMs) : Infinity;\n const punct = /[.!?;:]$/.test(String(words[i].text));\n if (punct || gap > 600 || cur.length >= 8) { groups.push(cur); cur = []; }\n }\n if (cur.length) groups.push(cur);\n const rel = (ms) => Math.max(0, Math.min(panel.durationMs - 150, Math.round(ms) - VISUAL_LEAD_MS - panel.startMs));\n return groups.map((ws) => ({\n text: ws.map((w) => String(w.text).trim()).join(' '),\n wordTimes: ws.map((w) => rel(Number(w.startMs))),\n })).filter((ph) => ph.text);\n}\n\n\nfunction applyCanvasTypewriter(doc, panelId) {\n const panel = doc.strip.find((p) => p.panelId === panelId);\n if (!panel || panel.type !== 'canvas') throw new Error(\\`applyCanvasTypewriter: \\${panelId} is not a canvas panel\\`);\n // Flatten the board's VO phrases into a word span (text + canvas-relative ms).\n const span = [];\n for (const ph of voPhrasesForPanel(doc, panel)) {\n const words = String(ph.text || '').split(/\\\\s+/).filter(Boolean);\n words.forEach((text, i) => span.push({ text, rel: Number(ph.wordTimes?.[i]) || 0 }));\n }\n const elements = typewriterElementsFromSpan(span, {});\n if (!elements.length) return doc; // no narration on this board — nothing to type\n const strip = doc.strip.map((p) => (p.panelId === panelId\n ? { ...p, mode: 'typewriter', autoArrange: false, template: null, elements }\n : p));\n return loadPanelDoc({ ...doc, strip });\n}\n\n\nfunction typewriterElementsFromSpan(span, { size = 0.06, maxCharsPerLine = 30, maxWordsPerLine = 6 } = {}) {\n const items = (Array.isArray(span) ? span : [])\n .map((s) => ({ text: String(s?.text ?? '').trim(), rel: Math.max(0, Math.round(Number(s?.rel) || 0)) }))\n .filter((s) => s.text);\n if (!items.length) return [];\n // Greedy-wrap into lines (char budget or word count, whichever hits first) so\n // the layout is fixed up front and never reflows as it types.\n const lines = [];\n let cur = [];\n let curChars = 0;\n for (const wd of items) {\n const add = wd.text.length + (cur.length ? 1 : 0);\n if (cur.length && (curChars + add > maxCharsPerLine || cur.length >= maxWordsPerLine)) {\n lines.push(cur); cur = []; curChars = 0;\n }\n cur.push(wd); curChars += add;\n }\n if (cur.length) lines.push(cur);\n const lineH = size * 1.4; // normalized-H line height\n const startY = 0.5 - (lines.length * lineH) / 2 + lineH / 2;\n return lines.map((ln, i) => ({\n id: \\`tw\\${i + 1}\\`, kind: 'text', text: ln.map((w) => w.text).join(' '),\n appearMs: ln[0].rel, leaveMs: null,\n pos: { x: 0.5, y: clamp01(startY + i * lineH, 0.04, 0.96) },\n size, font: 'Hanken Grotesk', color: '#111111', weight: 800,\n wordTimes: ln.map((w) => w.rel),\n anim: { type: 'typewriter', perWord: false, speedMs: 45 },\n sfx: 'auto', pinned: true,\n }));\n}\n\nconst clamp01=(v,lo,hi)=>Math.max(lo,Math.min(hi,v));const loadPanelDoc=doc=>doc;return {edit:applyCanvasTypewriter(input.doc,input.panelId)};`,tests:[]},Uu=(e,t)=>V(e)===V(t);function Wu(e,t){let n=e.strip.find(e=>e.panelId===t);I(n?.type===`canvas`,`TYPEWRITER`,`This canvas is no longer available.`);let r={panelId:t,type:`canvas`,startMs:n.startMs,durationMs:n.durationMs,elements:[]},i=(e.audio?.words||[]).map(e=>{if(!e)return null;let t={};for(let n of[`text`,`startMs`,`endMs`])e[n]!==void 0&&(t[n]=e[n]);return t});I(i.every(e=>!e||Object.values(e).every(e=>e===null||[`string`,`number`,`boolean`].includes(typeof e))),`TYPEWRITER`,`Narration words must contain text and timing values.`);let a={doc:{strip:[r],audio:{words:i}},panelId:t};return B(a),{panel:n,input:a}}function Gu(e){let t=e.doc.strip[0],n=e.doc.audio.words.filter(e=>{if(!e||!String(e.text||``).trim())return!1;let n=(Number(e.startMs)+Number(e.endMs))/2;return n>=t.startMs&&n<t.startMs+t.durationMs}),r=[],i=[];for(let e=0;e<n.length;e++){i.push(n[e]);let t=e+1<n.length?Number(n[e+1].startMs)-Number(n[e].endMs):1/0;(/[.!?;:]$/.test(String(n[e].text))||t>600||i.length>=8)&&(r.push(i),i=[])}i.length&&r.push(i);let a=[];for(let e of r){let n=e.map(e=>String(e.text).trim()).join(` `),r=e.map(e=>Math.max(0,Math.min(t.durationMs-150,Math.round(Number(e.startMs))-75-t.startMs)));String(n||``).split(/\\s+/).filter(Boolean).forEach((e,t)=>a.push({text:e,rel:Number(r[t])||0}))}let o=a.map(e=>({text:String(e.text??``).trim(),rel:Math.max(0,Math.round(Number(e.rel)||0))})).filter(e=>e.text);if(!o.length)return e.doc;let s=[],c=[],l=0;for(let e of o){let t=e.text.length+ +!!c.length;c.length&&(l+t>30||c.length>=6)&&(s.push(c),c=[],l=0),c.push(e),l+=t}c.length&&s.push(c);let u=.06*1.4,d=.5-s.length*u/2+u/2,f=s.map((e,t)=>({id:`tw${t+1}`,kind:`text`,text:e.map(e=>e.text).join(` `),appearMs:e[0].rel,leaveMs:null,pos:{x:.5,y:Math.max(.04,Math.min(.96,d+t*u))},size:.06,font:`Hanken Grotesk`,color:`#111111`,weight:800,wordTimes:e.map(e=>e.rel),anim:{type:`typewriter`,perWord:!1,speedMs:45},sfx:`auto`,pinned:!0}));return{...e.doc,strip:[{...t,mode:`typewriter`,autoArrange:!1,template:null,elements:f}]}}function Ku(e,{panel:t,input:n},r){let i=Gu(n);if(B(i),B(r),I(Uu(r,i),`TYPEWRITER`,`The sandbox changed narration, timing, or the typewriter layout.`),i===n.doc)return e;let a=r.strip[0].elements;if(t.mode===`typewriter`&&t.autoArrange===!1&&t.template===null&&Uu(t.elements,a))return e;let o={...t,mode:`typewriter`,autoArrange:!1,template:null,elements:a};return{...e,strip:e.strip.map(e=>e===t?o:e)}}function qu({doc:e,projectId:t,panelId:n,canEdit:r,onDocChange:i,validateDocument:a,editLease:o,host:s}){let c=H(s),l=()=>c.actor(),[u,d]=(0,v.useState)(null),[f,p]=(0,v.useState)(``),m=(0,v.useRef)(null),h=(0,v.useRef)(!0),g=(0,v.useRef)(0),_=(0,v.useRef)(null),y=l();_.current={doc:e,projectId:t,panelId:n,canEdit:r,onDocChange:i,validateDocument:a,actor:y,services:c};let b=(0,v.useCallback)(()=>{g.current++,o?.current===m.current&&(o.current=null),m.current?.abort(),m.current=null,d(null)},[o]);return(0,v.useEffect)(()=>(h.current=!0,()=>{h.current=!1,g.current++,o?.current===m.current&&(o.current=null),m.current?.abort(),m.current=null}),[]),(0,v.useEffect)(()=>{b()},[e,t,n,r,y,c,b]),{change:(0,v.useCallback)(async()=>{let e=_.current;if(!e.doc||!e.canEdit||m.current||o?.current||e.services!==c)return;let t=++g.current,n=new AbortController;m.current=n,o&&(o.current=n),d(e.panelId),p(``);let r,i=()=>{let t=_.current;I(h.current&&m.current===n&&!n.signal.aborted&&t.doc===e.doc&&t.projectId===e.projectId&&t.panelId===e.panelId&&t.canEdit&&t.services===c&&t.actor===e.actor&&l()===e.actor&&JSON.stringify(e.doc)===r,`STALE`,`The canvas changed. Review the current typewriter narration again.`)};try{r=JSON.stringify(e.doc);let a=Wu(e.doc,e.panelId);i();let o=await c.run(Hu,{kind:`run`,input:a.input,signal:n.signal,timeoutMs:15e3});i();let s=Ku(e.doc,a,o.outputs?.edit),u=s===e.doc?e.doc:e.validateDocument(s);if(i(),u!==e.doc){let i=JSON.stringify(u),a=!1;e.onDocChange(o=>{let s=_.current,d=!1;try{d=h.current&&g.current===t&&!n.signal.aborted&&s.doc===e.doc&&s.projectId===e.projectId&&s.panelId===e.panelId&&s.canEdit&&s.services===c&&s.actor===e.actor&&l()===e.actor&&JSON.stringify(u)===i&&JSON.stringify(o)===r&&JSON.stringify(e.doc)===r}catch{}return d?u:(a||(a=!0,queueMicrotask(()=>{h.current&&l()===e.actor&&_.current.projectId===e.projectId&&p(`The canvas changed before the typewriter edit could be saved. Review the current typewriter narration again.`)})),o)})}return u}catch(t){h.current&&!n.signal.aborted&&l()===e.actor&&_.current.projectId===e.projectId&&p(t.message||`The typewriter edit could not be applied.`)}finally{m.current===n&&(o?.current===n&&(o.current=null),m.current=null,h.current&&d(null))}},[c]),pending:u,error:f,cancel:b}}let Ju={manifest:{schemaVersion:1,sdkVersion:`0.1.0`,id:`stillmade-internal.canvas-template`,version:`1.0.0`,name:`Canvas template layout`,description:`Apply or clear bundled canvas templates while preserving pins and timing.`,kind:`task`,runtime:`javascript`,inputs:{doc:{type:`json`},panelId:{type:`text`},templateId:{type:`text`}},outputs:{edit:{type:`json`}},permissions:{project:[],network:[],filesystem:[],secrets:[]}},code:`// COLLAGE CANVAS TEMPLATES — 20 bundled, versioned slot layouts (panel-image\n// only), each authored TWICE: a landscape layout and a portrait (9:16) layout\n// for the same scenario. A template is a LAYOUT DEFINITION, not a static\n// design: image SLOTS (center pos, target box, draw order = array order\n// back→front, optional tilt) and explicit TEXT SLOTS (role + deliberate\n// position), which the canvas system reads to place elements.\n//\n// Coordinates are normalized to the canvas frame (x/w = width fractions,\n// y/h = height fractions). An image FITS its slot box cover-cropped\n// (drawCollage's \\`box\\` rendering — aspect preserved, never distorted); fine\n// adjustment stays manual (drag pins, per spec S10). Image slots keep a\n// bottom safety margin (y + h/2 ≤ 0.95) so nothing crowds the frame edge.\n//\n// EVERY SLOT IS OPTIONAL — image and text alike. A template defines where\n// things GO if present; nothing is required. A canvas can use 2 of 7 image\n// slots, no text at all, or text with fewer images; unused slots are simply\n// empty (no placeholder, no gap artifact). And templates place, they never\n// time: each element still appears on ITS OWN voiceover beat (appearMs is\n// untouched by template application), so a canvas builds up slot by slot.\n//\n// Ownership contract (post-approval spec):\n// - AUTO canvases: the generator PICKS a template (pickTemplateForCanvas) from\n// image count + the beat's scenario hint; S10 self-arranging handles the\n// OVERFLOW beyond the slots (spiral around the slotted ones). Shown +\n// changeable afterward.\n// - MANUAL canvases: no template by default; opt-in from the picker.\n// - Switching is non-destructive: same elements, new positions; PINNED\n// elements are never moved (the pin IS the manual override).\n// - No fit / no pick → template null → the plain self-arranging layout.\n//\n// APPROVED by the owner 2026-07-22 (v2 sheet: both orientations, bottom\n// margins fixed). Bundled static definitions — versioned, never regenerated.\nconst CANVAS_TEMPLATE_VERSION = 2;\n\n// slot: { x, y, w, h, tilt? } — image slot (center + target box)\n// textSlot: { role, x, y, size, weight? } — role: headline | label | caption\n// Each template: landscape layout in \\`slots\\`/\\`textSlots\\`, portrait layout in\n// \\`pSlots\\`/\\`pTextSlots\\` (same scenario re-authored for a tall frame).\nconst T = (id, name, scenario, minImages, slots, textSlots, pSlots, pTextSlots) => (\n { id, name, scenario, minImages, slots, textSlots, pSlots, pTextSlots }\n);\n\nconst CANVAS_TEMPLATES = [\n T('hero-headline', 'Hero + headline', 'one subject, one line', 1,\n [{ x: 0.5, y: 0.58, w: 0.5, h: 0.62 }],\n [{ role: 'headline', x: 0.5, y: 0.14, size: 0.09, weight: 900 }],\n [{ x: 0.5, y: 0.55, w: 0.78, h: 0.5 }],\n [{ role: 'headline', x: 0.5, y: 0.13, size: 0.055, weight: 900 }]),\n\n T('hero-supporting', 'Hero + 2 supporting', 'main subject with two details', 3,\n [{ x: 0.34, y: 0.55, w: 0.42, h: 0.58 }, { x: 0.78, y: 0.33, w: 0.28, h: 0.32 }, { x: 0.78, y: 0.73, w: 0.28, h: 0.32 }],\n [{ role: 'headline', x: 0.34, y: 0.13, size: 0.08, weight: 900 }],\n [{ x: 0.5, y: 0.38, w: 0.78, h: 0.32 }, { x: 0.28, y: 0.72, w: 0.4, h: 0.2 }, { x: 0.72, y: 0.72, w: 0.4, h: 0.2 }],\n [{ role: 'headline', x: 0.5, y: 0.12, size: 0.05, weight: 900 }]),\n\n T('compare-2', 'Side-by-side compare', 'A vs B', 2,\n [{ x: 0.27, y: 0.5, w: 0.38, h: 0.5 }, { x: 0.73, y: 0.5, w: 0.38, h: 0.5 }],\n [{ role: 'headline', x: 0.5, y: 0.12, size: 0.08, weight: 900 },\n { role: 'label', x: 0.27, y: 0.84, size: 0.05, weight: 800 },\n { role: 'label', x: 0.73, y: 0.84, size: 0.05, weight: 800 }],\n [{ x: 0.5, y: 0.35, w: 0.72, h: 0.24 }, { x: 0.5, y: 0.72, w: 0.72, h: 0.24 }],\n [{ role: 'headline', x: 0.5, y: 0.11, size: 0.05, weight: 900 },\n { role: 'label', x: 0.5, y: 0.51, size: 0.032, weight: 800 },\n { role: 'label', x: 0.5, y: 0.88, size: 0.032, weight: 800 }]),\n\n T('three-across', 'Three across', 'three items', 3,\n [{ x: 0.2, y: 0.5, w: 0.26, h: 0.46 }, { x: 0.5, y: 0.5, w: 0.26, h: 0.46 }, { x: 0.8, y: 0.5, w: 0.26, h: 0.46 }],\n [{ role: 'headline', x: 0.5, y: 0.13, size: 0.08, weight: 900 },\n { role: 'caption', x: 0.5, y: 0.86, size: 0.045, weight: 600 }],\n [{ x: 0.5, y: 0.32, w: 0.64, h: 0.2 }, { x: 0.5, y: 0.57, w: 0.64, h: 0.2 }, { x: 0.5, y: 0.82, w: 0.64, h: 0.2 }],\n [{ role: 'headline', x: 0.5, y: 0.1, size: 0.05, weight: 900 },\n { role: 'caption', x: 0.5, y: 0.96, size: 0.028, weight: 600 }]),\n\n T('grid-2x2', 'Grid of four', 'four items', 4,\n [{ x: 0.3, y: 0.36, w: 0.32, h: 0.34 }, { x: 0.7, y: 0.36, w: 0.32, h: 0.34 },\n { x: 0.3, y: 0.74, w: 0.32, h: 0.34 }, { x: 0.7, y: 0.74, w: 0.32, h: 0.34 }],\n [{ role: 'headline', x: 0.5, y: 0.09, size: 0.07, weight: 900 }],\n [{ x: 0.28, y: 0.38, w: 0.4, h: 0.24 }, { x: 0.72, y: 0.38, w: 0.4, h: 0.24 },\n { x: 0.28, y: 0.68, w: 0.4, h: 0.24 }, { x: 0.72, y: 0.68, w: 0.4, h: 0.24 }],\n [{ role: 'headline', x: 0.5, y: 0.12, size: 0.05, weight: 900 }]),\n\n T('grid-3x3', 'Many small (3x3)', 'lots of items', 6,\n [0.22, 0.5, 0.78].flatMap((x) => [0.3, 0.56, 0.82].map((y) => ({ x, y, w: 0.24, h: 0.22 }))),\n [{ role: 'headline', x: 0.5, y: 0.08, size: 0.065, weight: 900 }],\n [0.2, 0.5, 0.8].flatMap((x) => [0.34, 0.58, 0.82].map((y) => ({ x, y, w: 0.27, h: 0.18 }))),\n [{ role: 'headline', x: 0.5, y: 0.1, size: 0.045, weight: 900 }]),\n\n T('big-left-stack-right', 'Big lead + stack', 'one lead, several follow-ups', 3,\n [{ x: 0.32, y: 0.54, w: 0.5, h: 0.62 }, { x: 0.79, y: 0.3, w: 0.3, h: 0.22 },\n { x: 0.79, y: 0.56, w: 0.3, h: 0.22 }, { x: 0.79, y: 0.82, w: 0.3, h: 0.22 }],\n [{ role: 'headline', x: 0.32, y: 0.13, size: 0.075, weight: 900 }],\n [{ x: 0.5, y: 0.4, w: 0.84, h: 0.34 }, { x: 0.2, y: 0.74, w: 0.26, h: 0.16 },\n { x: 0.5, y: 0.74, w: 0.26, h: 0.16 }, { x: 0.8, y: 0.74, w: 0.26, h: 0.16 }],\n [{ role: 'headline', x: 0.5, y: 0.12, size: 0.05, weight: 900 }]),\n\n T('vertical-stack', 'Vertical stack', 'ordered top to bottom', 2,\n [{ x: 0.55, y: 0.29, w: 0.36, h: 0.22 }, { x: 0.55, y: 0.55, w: 0.36, h: 0.22 }, { x: 0.55, y: 0.81, w: 0.36, h: 0.22 }],\n [{ role: 'headline', x: 0.55, y: 0.08, size: 0.065, weight: 900 },\n { role: 'label', x: 0.16, y: 0.55, size: 0.055, weight: 800 }],\n [{ x: 0.5, y: 0.3, w: 0.66, h: 0.2 }, { x: 0.5, y: 0.56, w: 0.66, h: 0.2 }, { x: 0.5, y: 0.82, w: 0.66, h: 0.2 }],\n [{ role: 'headline', x: 0.5, y: 0.09, size: 0.05, weight: 900 },\n { role: 'label', x: 0.24, y: 0.17, size: 0.032, weight: 800 }]),\n\n T('scatter', 'Scattered collage', 'loose, hand-thrown feel', 3,\n [{ x: 0.26, y: 0.36, w: 0.28, h: 0.32, tilt: -6 }, { x: 0.68, y: 0.3, w: 0.26, h: 0.3, tilt: 4 },\n { x: 0.44, y: 0.66, w: 0.27, h: 0.31, tilt: 3 }, { x: 0.8, y: 0.62, w: 0.25, h: 0.29, tilt: -5 },\n { x: 0.58, y: 0.46, w: 0.24, h: 0.28, tilt: 2 }],\n [{ role: 'headline', x: 0.5, y: 0.1, size: 0.075, weight: 900 }],\n [{ x: 0.32, y: 0.3, w: 0.46, h: 0.2, tilt: -6 }, { x: 0.7, y: 0.26, w: 0.42, h: 0.18, tilt: 4 },\n { x: 0.4, y: 0.56, w: 0.44, h: 0.2, tilt: 3 }, { x: 0.74, y: 0.6, w: 0.4, h: 0.18, tilt: -5 },\n { x: 0.5, y: 0.82, w: 0.44, h: 0.19, tilt: 2 }],\n [{ role: 'headline', x: 0.5, y: 0.09, size: 0.045, weight: 900 }]),\n\n T('timeline-row', 'Row / timeline', 'steps in order', 3,\n [{ x: 0.14, y: 0.52, w: 0.2, h: 0.38 }, { x: 0.38, y: 0.52, w: 0.2, h: 0.38 },\n { x: 0.62, y: 0.52, w: 0.2, h: 0.38 }, { x: 0.86, y: 0.52, w: 0.2, h: 0.38 }],\n [{ role: 'headline', x: 0.5, y: 0.15, size: 0.075, weight: 900 },\n { role: 'caption', x: 0.5, y: 0.85, size: 0.045, weight: 600 }],\n [{ x: 0.35, y: 0.28, w: 0.5, h: 0.15 }, { x: 0.65, y: 0.47, w: 0.5, h: 0.15 },\n { x: 0.35, y: 0.66, w: 0.5, h: 0.15 }, { x: 0.65, y: 0.85, w: 0.5, h: 0.15 }],\n [{ role: 'headline', x: 0.5, y: 0.12, size: 0.05, weight: 900 }]),\n\n T('center-satellites', 'Center + satellites', 'one core idea, orbiting parts', 3,\n [{ x: 0.5, y: 0.52, w: 0.34, h: 0.42 }, { x: 0.17, y: 0.3, w: 0.2, h: 0.26 }, { x: 0.83, y: 0.3, w: 0.2, h: 0.26 },\n { x: 0.17, y: 0.77, w: 0.2, h: 0.26 }, { x: 0.83, y: 0.77, w: 0.2, h: 0.26 }],\n [{ role: 'headline', x: 0.5, y: 0.09, size: 0.065, weight: 900 }],\n [{ x: 0.5, y: 0.52, w: 0.56, h: 0.28 }, { x: 0.2, y: 0.28, w: 0.32, h: 0.16 }, { x: 0.8, y: 0.28, w: 0.32, h: 0.16 },\n { x: 0.2, y: 0.78, w: 0.32, h: 0.16 }, { x: 0.8, y: 0.78, w: 0.32, h: 0.16 }],\n [{ role: 'headline', x: 0.5, y: 0.1, size: 0.045, weight: 900 }]),\n\n T('corner-big-text', 'Corner images, big text', 'statement first, proof beside it', 2,\n [{ x: 0.72, y: 0.4, w: 0.32, h: 0.38 }, { x: 0.52, y: 0.72, w: 0.28, h: 0.34 }, { x: 0.85, y: 0.76, w: 0.24, h: 0.3 }],\n [{ role: 'headline', x: 0.26, y: 0.26, size: 0.105, weight: 900 },\n { role: 'label', x: 0.26, y: 0.42, size: 0.05, weight: 600 }],\n [{ x: 0.36, y: 0.56, w: 0.5, h: 0.22 }, { x: 0.7, y: 0.7, w: 0.44, h: 0.2 }, { x: 0.4, y: 0.84, w: 0.4, h: 0.18 }],\n [{ role: 'headline', x: 0.5, y: 0.19, size: 0.065, weight: 900 },\n { role: 'label', x: 0.5, y: 0.31, size: 0.034, weight: 600 }]),\n\n T('title-top-row', 'Title top, images below', 'title screen with evidence', 2,\n [{ x: 0.22, y: 0.62, w: 0.28, h: 0.44 }, { x: 0.5, y: 0.62, w: 0.28, h: 0.44 }, { x: 0.78, y: 0.62, w: 0.28, h: 0.44 }],\n [{ role: 'headline', x: 0.5, y: 0.17, size: 0.1, weight: 900 }],\n [{ x: 0.5, y: 0.4, w: 0.7, h: 0.2 }, { x: 0.5, y: 0.64, w: 0.7, h: 0.2 }, { x: 0.5, y: 0.86, w: 0.7, h: 0.16 }],\n [{ role: 'headline', x: 0.5, y: 0.15, size: 0.06, weight: 900 }]),\n\n T('large-caption', 'One large + caption', 'let the image speak', 1,\n [{ x: 0.5, y: 0.47, w: 0.56, h: 0.6 }],\n [{ role: 'label', x: 0.15, y: 0.1, size: 0.045, weight: 800 },\n { role: 'caption', x: 0.5, y: 0.85, size: 0.055, weight: 600 }],\n [{ x: 0.5, y: 0.47, w: 0.82, h: 0.44 }],\n [{ role: 'label', x: 0.24, y: 0.12, size: 0.032, weight: 800 },\n { role: 'caption', x: 0.5, y: 0.78, size: 0.034, weight: 600 }]),\n\n T('staggered-diagonal', 'Staggered diagonal', 'progression with motion', 3,\n [{ x: 0.18, y: 0.26, w: 0.24, h: 0.3, tilt: -3 }, { x: 0.42, y: 0.45, w: 0.24, h: 0.3, tilt: 3 },\n { x: 0.64, y: 0.62, w: 0.24, h: 0.3, tilt: -3 }, { x: 0.86, y: 0.79, w: 0.24, h: 0.3, tilt: 3 }],\n [{ role: 'headline', x: 0.74, y: 0.16, size: 0.075, weight: 900 }],\n [{ x: 0.28, y: 0.3, w: 0.42, h: 0.18, tilt: -3 }, { x: 0.62, y: 0.46, w: 0.42, h: 0.18, tilt: 3 },\n { x: 0.36, y: 0.62, w: 0.42, h: 0.18, tilt: -3 }, { x: 0.68, y: 0.78, w: 0.42, h: 0.18, tilt: 3 }],\n [{ role: 'headline', x: 0.5, y: 0.12, size: 0.05, weight: 900 }]),\n\n T('overlap-stack', 'Overlapping stack', 'a deliberate pile', 2,\n [{ x: 0.42, y: 0.5, w: 0.36, h: 0.46, tilt: -5 }, { x: 0.54, y: 0.56, w: 0.36, h: 0.46, tilt: 3 },\n { x: 0.63, y: 0.46, w: 0.36, h: 0.46, tilt: -2 }],\n [{ role: 'headline', x: 0.5, y: 0.12, size: 0.08, weight: 900 },\n { role: 'caption', x: 0.5, y: 0.89, size: 0.045, weight: 600 }],\n [{ x: 0.44, y: 0.42, w: 0.58, h: 0.26, tilt: -5 }, { x: 0.58, y: 0.53, w: 0.58, h: 0.26, tilt: 3 },\n { x: 0.46, y: 0.64, w: 0.58, h: 0.26, tilt: -2 }],\n [{ role: 'headline', x: 0.5, y: 0.12, size: 0.05, weight: 900 },\n { role: 'caption', x: 0.5, y: 0.86, size: 0.032, weight: 600 }]),\n\n T('banner-row', 'Wide banner + small row', 'one wide scene, details under', 2,\n [{ x: 0.5, y: 0.36, w: 0.84, h: 0.36 }, { x: 0.25, y: 0.77, w: 0.24, h: 0.26 },\n { x: 0.5, y: 0.77, w: 0.24, h: 0.26 }, { x: 0.75, y: 0.77, w: 0.24, h: 0.26 }],\n [{ role: 'headline', x: 0.5, y: 0.09, size: 0.065, weight: 900 }],\n [{ x: 0.5, y: 0.36, w: 0.86, h: 0.26 }, { x: 0.22, y: 0.66, w: 0.28, h: 0.16 },\n { x: 0.5, y: 0.66, w: 0.28, h: 0.16 }, { x: 0.78, y: 0.66, w: 0.28, h: 0.16 }],\n [{ role: 'headline', x: 0.5, y: 0.13, size: 0.05, weight: 900 },\n { role: 'caption', x: 0.5, y: 0.82, size: 0.032, weight: 600 }]),\n\n T('quadrant-labels', 'Quadrants with labels', 'four named things', 4,\n [{ x: 0.28, y: 0.3, w: 0.3, h: 0.3 }, { x: 0.72, y: 0.3, w: 0.3, h: 0.3 },\n { x: 0.28, y: 0.71, w: 0.3, h: 0.3 }, { x: 0.72, y: 0.71, w: 0.3, h: 0.3 }],\n [{ role: 'headline', x: 0.5, y: 0.07, size: 0.06, weight: 900 },\n { role: 'label', x: 0.28, y: 0.49, size: 0.042, weight: 800 },\n { role: 'label', x: 0.72, y: 0.49, size: 0.042, weight: 800 },\n { role: 'label', x: 0.28, y: 0.9, size: 0.042, weight: 800 },\n { role: 'label', x: 0.72, y: 0.9, size: 0.042, weight: 800 }],\n [{ x: 0.28, y: 0.32, w: 0.38, h: 0.2 }, { x: 0.72, y: 0.32, w: 0.38, h: 0.2 },\n { x: 0.28, y: 0.64, w: 0.38, h: 0.2 }, { x: 0.72, y: 0.64, w: 0.38, h: 0.2 }],\n [{ role: 'headline', x: 0.5, y: 0.1, size: 0.045, weight: 900 },\n { role: 'label', x: 0.28, y: 0.45, size: 0.028, weight: 800 },\n { role: 'label', x: 0.72, y: 0.45, size: 0.028, weight: 800 },\n { role: 'label', x: 0.28, y: 0.77, size: 0.028, weight: 800 },\n { role: 'label', x: 0.72, y: 0.77, size: 0.028, weight: 800 }]),\n\n T('pyramid-3', 'Pyramid of three', 'one above two', 3,\n [{ x: 0.5, y: 0.32, w: 0.3, h: 0.32 }, { x: 0.32, y: 0.71, w: 0.3, h: 0.32 }, { x: 0.68, y: 0.71, w: 0.3, h: 0.32 }],\n [{ role: 'headline', x: 0.5, y: 0.08, size: 0.065, weight: 900 },\n { role: 'caption', x: 0.5, y: 0.92, size: 0.04, weight: 600 }],\n [{ x: 0.5, y: 0.34, w: 0.5, h: 0.22 }, { x: 0.27, y: 0.62, w: 0.42, h: 0.18 }, { x: 0.73, y: 0.62, w: 0.42, h: 0.18 }],\n [{ role: 'headline', x: 0.5, y: 0.1, size: 0.05, weight: 900 },\n { role: 'caption', x: 0.5, y: 0.79, size: 0.032, weight: 600 }]),\n\n T('mosaic-dense', 'Dense mosaic', 'everything at once', 5,\n [{ x: 0.3, y: 0.4, w: 0.34, h: 0.42 }, { x: 0.62, y: 0.29, w: 0.24, h: 0.26 }, { x: 0.86, y: 0.33, w: 0.2, h: 0.28 },\n { x: 0.19, y: 0.78, w: 0.24, h: 0.26 }, { x: 0.47, y: 0.77, w: 0.26, h: 0.28 }, { x: 0.73, y: 0.73, w: 0.22, h: 0.24 },\n { x: 0.91, y: 0.76, w: 0.14, h: 0.18 }],\n [{ role: 'headline', x: 0.5, y: 0.09, size: 0.06, weight: 900 }],\n [{ x: 0.32, y: 0.3, w: 0.5, h: 0.2 }, { x: 0.78, y: 0.26, w: 0.36, h: 0.16 }, { x: 0.24, y: 0.52, w: 0.4, h: 0.16 },\n { x: 0.68, y: 0.5, w: 0.44, h: 0.18 }, { x: 0.3, y: 0.74, w: 0.42, h: 0.16 }, { x: 0.74, y: 0.73, w: 0.4, h: 0.16 },\n { x: 0.5, y: 0.89, w: 0.5, h: 0.1 }],\n [{ role: 'headline', x: 0.5, y: 0.1, size: 0.045, weight: 900 }]),\n];\n\nconst byId = new Map(CANVAS_TEMPLATES.map((t) => [t.id, t]));\nconst getCanvasTemplate = (id) => byId.get(id) || null; // unknown/renamed id → no template (never a load failure)\n\n// The layout for a given canvas aspect: tall frames (ratio < 1) use the\n// portrait variant, everything else the landscape one.\nfunction templateLayout(template, aspect = 16 / 9) {\n if (!template) return null;\n return aspect < 1\n ? { slots: template.pSlots, textSlots: template.pTextSlots }\n : { slots: template.slots, textSlots: template.textSlots };\n}\n\n// ── Reflow: elements → a template's slots (pure, non-destructive) ───────────\n// Unpinned IMAGES fill image slots in appear order; unpinned TEXTS fill text\n// slots in slot order (headline first, as authored). EVERY SLOT IS OPTIONAL:\n// fewer elements than slots just leaves the extra slots empty. Elements\n// beyond the slots OVERFLOW: images lose their box (back to natural-aspect\n// sizing) and get pos:null so the S10 spiral places them around the slotted\n// ones; extra texts keep their position. PINNED elements are never touched —\n// the pin IS the manual override, and it survives every template switch.\n// TIMING IS NEVER TOUCHED: appearMs/leaveMs pass through untouched, so each\n// element still pops on its own voiceover beat.\nfunction applyTemplateToElements(elements, template, { aspect = 16 / 9 } = {}) {\n if (!template) {\n // Clearing a template touches ONLY slot-derived elements (the ones with a\n // box): the box comes off, the position STAYS — on an auto canvas the\n // spiral re-places unpinned elements anyway, and on a manual canvas the\n // old slot spot is a sane resting place (never a pos:null pile at\n // center, never a wipe of hand placements that were never slotted).\n return (elements || []).map((el) => {\n if (el.pinned || el.kind !== 'image' || !el.box) return el;\n const { box, ...rest } = el;\n return rest;\n });\n }\n const layout = templateLayout(template, aspect);\n const byAppear = (a, b) => (a.appearMs || 0) - (b.appearMs || 0);\n const images = (elements || []).filter((el) => el.kind === 'image' && !el.pinned).sort(byAppear);\n const texts = (elements || []).filter((el) => el.kind === 'text' && !el.pinned).sort(byAppear);\n const imgSlot = new Map();\n images.forEach((el, i) => { if (i < layout.slots.length) imgSlot.set(el.id, layout.slots[i]); });\n const textSlot = new Map();\n texts.forEach((el, i) => { if (i < layout.textSlots.length) textSlot.set(el.id, layout.textSlots[i]); });\n return (elements || []).map((el) => {\n if (el.pinned) return el;\n if (el.kind === 'image') {\n const s = imgSlot.get(el.id);\n if (!s) { const { box, ...rest } = el; return { ...rest, pos: null }; } // overflow → spiral\n return { ...el, pos: { x: s.x, y: s.y }, box: { w: s.w, h: s.h }, size: s.w, tilt: s.tilt || 0 };\n }\n const s = textSlot.get(el.id);\n if (!s) return el; // extra text keeps its place\n return { ...el, pos: { x: s.x, y: s.y }, size: s.size, weight: s.weight || el.weight || 800 };\n });\n}\n\n// ── Auto-pick (post-approval spec): image count + scenario hint ─────────────\n// The hint is the planner's free-text reason for the beat; keyword classes\n// beat pure counts (compare → side-by-side, steps/list → row, many → mosaic).\n// Returns a template id or null (no fit → the plain self-arranging layout).\nfunction pickTemplateForCanvas({ imageCount = 0, textCount = 0, hint = '' } = {}) {\n if (!imageCount) return null;\n const h = String(hint || '').toLowerCase();\n if (imageCount === 2 && /\\\\bvs\\\\b|versus|compar|before.*after|either/.test(h)) return 'compare-2';\n if (imageCount >= 3 && /step|order|sequence|timeline|process|journey|stages/.test(h)) return 'timeline-row';\n if (imageCount >= 3 && /list|lists|enumerat|items|examples|types|kinds/.test(h)) return imageCount >= 5 ? 'mosaic-dense' : 'three-across';\n if (imageCount === 1) return textCount > 1 ? 'large-caption' : 'hero-headline';\n if (imageCount === 2) return 'compare-2';\n if (imageCount === 3) return 'three-across';\n if (imageCount === 4) return 'grid-2x2';\n if (imageCount === 5) return 'center-satellites';\n if (imageCount <= 7) return 'mosaic-dense';\n return 'grid-3x3';\n}\n\nconst hash = (s) => {\n let h = 5381;\n const str = String(s || '');\n for (let i = 0; i < str.length; i++) h = ((h << 5) + h + str.charCodeAt(i)) >>> 0;\n return h;\n};\n// Deterministic pseudo-jitter in [-1, 1] from an id + salt.\nconst jitter = (id, salt) => ((hash(\\`\\${id}|\\${salt}\\`) % 2000) / 1000) - 1;\n\n// ── Self-arranging layout (S10) ──────────────────────────────────────────────\n// Applies to AUTO-ARRANGED canvases only (panel.autoArrange). Deterministic\n// greedy placement in APPEAR ORDER: each unpinned image takes the best slot on\n// a golden-angle spiral around the canvas center — maximizing distance from\n// every element already visible when it appears — so the composition stays\n// balanced as it accumulates without ever moving an already-placed element\n// (tidy-by-construction; nothing jumps). PINNED elements (user overrides) and\n// manual canvases keep their positions exactly; auto elements arrange AROUND\n// pinned ones (they're obstacles in the distance test).\nconst SPIRAL_SLOTS = 48;\nconst GOLDEN = 2.399963229728653; // golden angle (rad)\nfunction spiralSlot(k, aspect = 16 / 9) {\n // Slots sweep outward from the center, filling the frame evenly; x spread is\n // wider than y for landscape canvases.\n const r = 0.08 + 0.40 * Math.sqrt((k + 0.5) / SPIRAL_SLOTS);\n const a = k * GOLDEN;\n return { x: 0.5 + r * Math.cos(a), y: 0.5 + r * Math.sin(a) * (aspect > 1 ? 0.9 : 1.1) };\n}\nconst clamp01 = (v, lo, hi) => Math.max(lo, Math.min(hi, v));\n\nfunction arrangeCanvas(panel, { aspect = 16 / 9 } = {}) {\n const els = (panel?.elements || []).slice().sort((a, b) => (a.appearMs || 0) - (b.appearMs || 0));\n const placed = []; // { x, y, size, appearMs, leaveMs }\n const out = new Map();\n for (const el of els) {\n const half = (el.kind === 'image' ? (el.size || 0.28) : 0.18) / 2;\n if (el.pinned || !panel.autoArrange) {\n if (el.pos) { placed.push({ ...el.pos, size: el.size || 0.28, appearMs: el.appearMs, leaveMs: el.leaveMs }); out.set(el.id, el.pos); }\n continue;\n }\n // Distance test only against elements VISIBLE when this one appears —\n // an element that already LEFT frees its space.\n const visible = placed.filter((p) => (p.leaveMs == null || p.leaveMs > el.appearMs));\n let best = null; let bestScore = -Infinity;\n for (let k = 0; k < SPIRAL_SLOTS; k++) {\n // Slot order is salted per-element id so different canvases don't all\n // start identically, while staying fully deterministic.\n const slot = spiralSlot((k + (hash(el.id) % SPIRAL_SLOTS)) % SPIRAL_SLOTS, aspect);\n const x = clamp01(slot.x, half + 0.03, 1 - half - 0.03);\n const y = clamp01(slot.y, half + 0.05, 1 - half - 0.05);\n let minD = Infinity;\n for (const p of visible) minD = Math.min(minD, Math.hypot(x - p.x, y - p.y) - (p.size || 0.28) / 2 - half);\n const centerPull = -0.12 * Math.hypot(x - 0.5, y - 0.5); // gentle balance toward center\n const score = (visible.length ? Math.min(minD, 0.5) : 0.3) + centerPull;\n if (score > bestScore) { bestScore = score; best = { x, y }; }\n }\n const pos = best || { x: 0.5, y: 0.5 };\n // A hair of deterministic scatter so the collage reads hand-placed.\n pos.x = clamp01(pos.x + jitter(el.id, 'x') * 0.015, half, 1 - half);\n pos.y = clamp01(pos.y + jitter(el.id, 'y') * 0.015, half, 1 - half);\n placed.push({ ...pos, size: el.size || 0.28, appearMs: el.appearMs, leaveMs: el.leaveMs });\n out.set(el.id, pos);\n }\n return out; // elementId -> {x, y}\n}\n// Stamp arranged positions onto the elements (unpinned only) — the STORED\n// positions are what every renderer reads, so preview == export.\nfunction withArrangedPositions(panel, opts) {\n if (!panel.autoArrange) return panel;\n const posMap = arrangeCanvas(panel, opts);\n return {\n ...panel,\n elements: (panel.elements || []).map((el) => (\n !el.pinned && posMap.has(el.id) ? { ...el, pos: posMap.get(el.id) } : el\n )),\n };\n}\n\n\nfunction docAspectRatio(doc) {\n const a = doc?.meta?.aspect || '16:9';\n if (a === '9:16') return 9 / 16;\n if (a === '1:1') return 1;\n return 16 / 9;\n}\nfunction rearranged(doc, panel) {\n // TEMPLATE (bundled slot layout): the template sets the STRUCTURE — slotted\n // elements go to their slots; the S10 spiral only places the OVERFLOW,\n // treating slotted elements as obstacles. Applies to auto AND templated\n // manual canvases (opting into a template IS asking for arrangement); a\n // plain manual canvas stays untouched. Pinned elements never move.\n const template = getCanvasTemplate(panel.template);\n if (template) {\n const slotted = applyTemplateToElements(panel.elements || [], template, { aspect: docAspectRatio(doc) });\n const overflowPanel = {\n ...panel,\n autoArrange: true,\n elements: slotted.map((el) => (el.pos ? { ...el, pinned: true } : el)), // slots+pins = obstacles for the spiral\n };\n const posMap = arrangeCanvas(overflowPanel, { aspect: docAspectRatio(doc) });\n return {\n ...panel,\n elements: slotted.map((el) => (!el.pinned && !el.pos && posMap.has(el.id) ? { ...el, pos: posMap.get(el.id) } : el)),\n };\n }\n return panel.autoArrange ? withArrangedPositions(panel, { aspect: docAspectRatio(doc) }) : panel;\n}\n// Apply / switch / clear a canvas template — always NON-DESTRUCTIVE: same\n// elements, new positions. Works on manual canvases too (explicit opt-in via\n// the picker); clearing releases unpinned elements back to their layout\n// (spiral on auto, free placement on manual).\nfunction setCanvasTemplate(doc, panelId, templateId) {\n const panel = doc.strip.find((p) => p.panelId === panelId);\n if (!panel || panel.type !== 'canvas') throw new Error(\\`setCanvasTemplate: \\${panelId} is not a canvas panel\\`);\n if (templateId != null && !getCanvasTemplate(templateId)) throw new Error(\\`setCanvasTemplate: unknown template \"\\${templateId}\"\\`);\n if ((panel.template || null) === (templateId || null) && panel.mode !== 'typewriter') return doc; // picking the active tile is a true no-op\n const strip = doc.strip.map((p) => {\n if (p.panelId !== panelId) return p;\n // Picking any slot layout (or None) also exits typewriter mode.\n const { mode, ...restP } = p;\n const next = { ...restP, template: templateId || null };\n if (!templateId) next.elements = applyTemplateToElements(p.elements || [], null);\n return rearranged(doc, next);\n });\n return loadPanelDoc({ ...doc, strip });\n}\n\n\nconst loadPanelDoc=doc=>doc;return {edit:setCanvasTemplate(input.doc,input.panelId,input.templateId||null)};`,tests:[]},Yu=(e,t)=>V(e)===V(t),Xu=[`id`,`kind`,`pinned`,`appearMs`,`leaveMs`,`pos`,`box`,`size`,`tilt`,`weight`],Zu=[`pos`,`box`,`size`,`tilt`,`weight`];function Qu(e,t,n){let r=e.strip.find(e=>e.panelId===t);I(r?.type===`canvas`,`CANVAS_TEMPLATE`,`This canvas is no longer available.`),I(typeof n==`string`&&(!n||en(n)),`CANVAS_TEMPLATE`,`Choose an available canvas template.`);let i={panelId:t,elements:(r.elements||[]).map(e=>{let t={};for(let n of Xu)if(e[n]!==void 0){let r=e[n];t[n]=n===`pos`&&L(r)?{x:r.x,y:r.y}:n===`box`&&L(r)?{w:r.w,h:r.h}:r}return t})};for(let e of[`type`,`template`,`mode`,`autoArrange`])r[e]!==void 0&&(i[e]=r[e]);let a={doc:{meta:{aspect:e.meta?.aspect||`16:9`},strip:[i]},panelId:t,templateId:n};return B(a),{panel:r,input:a}}function $u(e){let t=e.doc.strip[0],n=e.templateId||null;if((t.template||null)===n&&t.mode!==`typewriter`)return e.doc;let{mode:r,...i}=t,a={...i,template:n};n||(a.elements=nn(t.elements,null));let o=e.doc.meta.aspect===`9:16`?9/16:e.doc.meta.aspect===`1:1`?1:16/9,s=en(n);if(s){let e=nn(a.elements,s,{aspect:o}),t=kt({...a,autoArrange:!0,elements:e.map(e=>e.pos?{...e,pinned:!0}:e)},{aspect:o});a={...a,elements:e.map(e=>!e.pinned&&!e.pos&&t.has(e.id)?{...e,pos:t.get(e.id)}:e)}}else a.autoArrange&&(a=At(a,{aspect:o}));return{...e.doc,strip:[a]}}function ed(e,{panel:t,input:n},r){let i=$u(n);if(B(i),B(r),I(Yu(r,i),`CANVAS_TEMPLATE`,`The sandbox changed an unrequested layout, pin, or element.`),i===n.doc)return e;let a=n.doc.strip[0],o=i.strip[0],s=r.strip[0],c=Object.hasOwn(t,`mode`)||!Yu(t.template??null,o.template??null)||!Object.hasOwn(t,`template`),l=s.elements.map((e,n)=>{let r=t.elements[n],i=a.elements[n],s=o.elements[n],l=r;for(let t of Zu){let n=Object.hasOwn(i,t),a=Object.hasOwn(s,t),o=a&&typeof s[t]==`object`&&s[t]!==null&&s[t]===i[t]?r[t]:e[t];(n!==a||a&&!Yu(r[t],o))&&(l===r&&(l={...r}),a?l[t]=o:delete l[t])}return l!==r&&(c=!0),l});if(!c)return e;let{mode:u,...d}=t,f={...d,template:s.template,elements:l.every((e,n)=>e===t.elements[n])?t.elements:l};return{...e,strip:e.strip.map(e=>e===t?f:e)}}function td({doc:e,projectId:t,panelId:n,canEdit:r,onDocChange:i,validateDocument:a,editLease:o,host:s}){let c=H(s),l=()=>c.actor(),[u,d]=(0,v.useState)(null),[f,p]=(0,v.useState)(``),m=(0,v.useRef)(null),h=(0,v.useRef)(!0),g=(0,v.useRef)(0),_=(0,v.useRef)(null),y=l();_.current={doc:e,projectId:t,panelId:n,canEdit:r,onDocChange:i,validateDocument:a,actor:y,services:c};let b=(0,v.useCallback)(()=>{g.current++,o?.current===m.current&&(o.current=null),m.current?.abort(),m.current=null,d(null)},[o]);return(0,v.useEffect)(()=>(h.current=!0,()=>{h.current=!1,g.current++,o?.current===m.current&&(o.current=null),m.current?.abort(),m.current=null}),[]),(0,v.useEffect)(()=>{b()},[e,t,n,r,y,c,b]),{change:(0,v.useCallback)(async e=>{let t=_.current;if(!t.doc||!t.canEdit||m.current||o?.current||t.services!==c)return;let n=++g.current,r=new AbortController;m.current=r,o&&(o.current=r),d(e||`none`),p(``);let i,a=()=>{let e=_.current;I(h.current&&m.current===r&&!r.signal.aborted&&e.doc===t.doc&&e.projectId===t.projectId&&e.panelId===t.panelId&&e.canEdit&&e.services===c&&e.actor===t.actor&&l()===t.actor&&JSON.stringify(t.doc)===i,`STALE`,`The canvas changed. Review the current template layout again.`)};try{i=JSON.stringify(t.doc);let o=Qu(t.doc,t.panelId,e||``);a();let s=await c.run(Ju,{kind:`run`,input:o.input,signal:r.signal,timeoutMs:15e3});a();let u=ed(t.doc,o,s.outputs?.edit),d=u===t.doc?t.doc:t.validateDocument(u);if(a(),d!==t.doc){let e=JSON.stringify(d),a=!1;t.onDocChange(o=>{let s=_.current,u=!1;try{u=h.current&&g.current===n&&!r.signal.aborted&&s.doc===t.doc&&s.projectId===t.projectId&&s.panelId===t.panelId&&s.canEdit&&s.services===c&&s.actor===t.actor&&l()===t.actor&&JSON.stringify(d)===e&&JSON.stringify(o)===i&&JSON.stringify(t.doc)===i}catch{}return u?d:(a||(a=!0,queueMicrotask(()=>{h.current&&l()===t.actor&&_.current.projectId===t.projectId&&p(`The canvas changed before the template edit could be saved. Review the current template layout again.`)})),o)})}return d}catch(e){h.current&&!r.signal.aborted&&l()===t.actor&&_.current.projectId===t.projectId&&p(e.message||`The template edit could not be applied.`)}finally{m.current===r&&(o?.current===r&&(o.current=null),m.current=null,h.current&&d(null))}},[c]),pending:u,error:f,cancel:b}}let nd={manifest:{schemaVersion:1,sdkVersion:`0.1.0`,id:`stillmade-internal.presenter-insertion`,version:`1.0.0`,name:`Presenter pose insertion`,description:`Place one captured presenter pose at the selected board time.`,kind:`task`,runtime:`javascript`,inputs:{pose:{type:`json`},atMs:{type:`number`}},outputs:{element:{type:`json`}},permissions:{project:[],network:[],filesystem:[],secrets:[]}},code:`// Presenter / Host character (spec: presenter-host-character-spec.md) — BETA.\n//\n// An AI-generated 2D presenter that lives ON whiteboard-motion canvases and helps\n// explain the content (points, presents, reacts). Poses are generated as labeled\n// 8-per-16:9 sheets, sliced, background-removed, auto-vectorized once, and saved as\n// ONE reusable character in the library. Used ONLY inside whiteboard-motion canvases\n// (never the edit-chain panels — S9 isolation).\n//\n// BETA GATE: the whole feature is opt-in. UI entry points (the voiceover-step host\n// sub-toggle + the canvas-chat host toggle) render only when this is true, and each\n// carries a visible \"Beta\" badge. Flip to false to hide it everywhere; the pure\n// pipeline + tests stay intact regardless.\nconst PRESENTER_HOST_BETA = true;\n\n// Sheet shape (S2): 8 poses per 16:9 sheet, at least 2 sheets (>= 16 poses). More\n// sheets when the content needs more poses.\nconst POSES_PER_SHEET = 8;\nconst MIN_POSE_SHEETS = 2;\nconst MIN_POSES = POSES_PER_SHEET * MIN_POSE_SHEETS; // 16\n\n// Canonical presenter pose vocabulary — the labels the planner is nudged toward and\n// the fills used to pad a thin plan up to MIN_POSES. Labels are slugs so the\n// library \"what do I have vs. still need\" check (S5 top-up) is a clean set-compare.\nconst PRESENTER_POSE_VOCAB = [\n 'point-left', 'point-right', 'point-up', 'point-down',\n 'present', 'explain', 'think', 'surprised',\n 'wave', 'idle', 'count', 'shrug', 'celebrate', 'write', 'thumbs-up', 'welcome',\n];\n\n// A human label for a pose slug (\"point-left\" -> \"point left\"), for the library UI.\nfunction poseLabelText(slug) {\n return String(slug || '').replace(/-/g, ' ').trim();\n}\n\n// Normalize any free-text pose label to a stable slug so plan/library/top-up all\n// speak the same vocabulary. \"Pointing to the Left!\" -> \"pointing-to-the-left\".\nfunction poseSlug(label) {\n return String(label || '')\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-+|-+$/g, '')\n .slice(0, 40);\n}\n\n// Presenter PLACEMENT + beat-aligned pose swaps (S7) — the director. Pure.\n//\n// The LLM already decided what the presenter DOES per beat (S2). This picks the\n// fitting pose for each canvas board and builds the on-canvas pose element:\n// a background-removed CUTOUT, HARD-CUT on the board's beat (entrance 'pop', no\n// interpolation), pinned to a presenter spot. Auto is the first draft — the element\n// is an ordinary image element, so swap/move/resize/retime in the mini-editor all\n// work already. No DOM, no network.\n\n\nfunction createPresenterPlacement(hostServices) {\n const {addCanvasElement,removeCanvasElement}=hostServices;\n// Where a presenter stands + faces for a gesture: a \"point right\" reads best from the\n// LEFT (arm reaches toward the content on the right), and vice-versa. Default: the\n// bottom-right presenter corner.\nfunction poseSpot(label) {\n const l = String(label || '');\n if (/(^|-)right/.test(l)) return { x: 0.2, y: 0.64 }; // gesturing right -> stand left\n if (/(^|-)left/.test(l)) return { x: 0.8, y: 0.64 }; // gesturing left -> stand right\n return { x: 0.8, y: 0.64 };\n}\n\n// Build the canvas element for one placed pose (hard-cut cutout). \\`pos\\` overrides\n// the gesture-derived spot (used when the host has a board to itself).\nfunction poseElement(pose, { size = 0.3, pos = null } = {}) {\n const label = poseSlug(pose?.label);\n return {\n kind: 'image',\n src: pose?.url || null,\n source: 'pose',\n pose: label,\n cutout: true, // no white backing card — floats on the board\n entrance: 'pop', // HARD CUT on the beat (S7) — no interpolation\n pinned: true, // deliberate placement, not part of the auto-collage arrange\n appearMs: 0, // aligned to the board's own start (its beat)\n leaveMs: null, // stays for the whole board\n pos: pos || poseSpot(label),\n size,\n query: label,\n };\n}\n\n// When the host is ALONE on a board (a \"nothing to show\" narration stretch), a\n// corner-sized cutout looks lost — center it and size it up so the presenter\n// carries the beat.\nconst SOLO_POSE = { size: 0.52, pos: { x: 0.5, y: 0.62 } };\n\n// Decide ONE pose per board. Prefer the plan pose whose \\`atWord\\` lands inside the\n// board's word window (so the presenter's action matches what's being said/shown);\n// otherwise cycle the available poses so every board still gets a varied presenter.\n// Only poses the character actually HAS are used (missing ones were topped up first).\nfunction planPresenterPlacement({ poses = [], plan = {}, boards = [], size = 0.3 } = {}) {\n const available = Array.isArray(poses) ? poses.filter((p) => p && p.url) : [];\n if (!available.length) return [];\n const byLabel = new Map(available.map((p) => [poseSlug(p.label), p]));\n const planPoses = Array.isArray(plan?.poses) ? plan.poses : [];\n const out = [];\n let cycle = 0;\n (Array.isArray(boards) ? boards : []).forEach((board) => {\n if (!board?.panelId) return;\n let chosen = null;\n // 1) a planned pose whose beat falls in this board, and that we actually have\n for (const pp of planPoses) {\n if (pp?.atWord == null || board.wordStart == null) continue;\n const end = board.wordEnd == null ? Infinity : board.wordEnd;\n if (pp.atWord >= board.wordStart && pp.atWord <= end && byLabel.has(poseSlug(pp.label))) {\n chosen = byLabel.get(poseSlug(pp.label));\n break;\n }\n }\n // 2) fallback: next available pose (varied per board)\n if (!chosen) { chosen = available[cycle % available.length]; cycle++; }\n // A board the host has to itself (no other content) gets the solo treatment.\n out.push({ panelId: board.panelId, element: poseElement(chosen, board.solo ? SOLO_POSE : { size }) });\n });\n return out;\n}\n\n// Apply the placement to a panel doc — one pose element added per targeted board.\n// Uses the same addCanvasElement primitive as every other canvas add (validated,\n// identity-preserving), so the poses are immediately editable in the mini-editor.\nfunction applyPresenterPlacement(doc, placements = []) {\n let next = doc;\n for (const { panelId, element } of placements || []) {\n if (!panelId || !element) continue;\n next = addCanvasElement(next, panelId, element);\n }\n return next;\n}\n\n// Word index active at a given ms — maps a board's time window to VO word indices when\n// the board doesn't already carry wordStart/wordEnd (so the plan's atWord beats match).\nfunction wordIndexAtMs(words, ms) {\n let idx = 0;\n for (let i = 0; i < (words?.length || 0); i++) {\n const w = words[i];\n const s = Number.isFinite(Number(w?.startMs)) ? Number(w.startMs) : (Number.isFinite(Number(w?.start)) ? Number(w.start) * 1000 : null);\n if (s == null) continue;\n if (s <= ms) idx = i; else break;\n }\n return idx;\n}\n\n// Place the host's poses on the doc's canvas boards, honoring the LLM plan (each pose's\n// atWord matched to the board whose word window contains it, else cycled). Clears prior\n// poses first. Returns the new doc. Shared by the interactive path + the panel build batch.\nfunction placePosesOnDoc(doc, posesLite = [], words = []) {\n const cleared = clearPresenterPoses(doc);\n const boards = (cleared.strip || []).filter((p) => p.type === 'canvas').map((b) => ({\n panelId: b.panelId,\n wordStart: b.wordStart != null ? b.wordStart : wordIndexAtMs(words, b.startMs || 0),\n wordEnd: b.wordEnd != null ? b.wordEnd : wordIndexAtMs(words, (b.startMs || 0) + (b.durationMs || 0)),\n solo: !(b.elements || []).length, // empty board -> the host carries it alone\n }));\n const plan = { poses: posesLite.map((p) => ({ label: p.label, atWord: p.atWord })).filter((p) => p.atWord != null) };\n return applyPresenterPlacement(cleared, planPresenterPlacement({ poses: posesLite, plan, boards }));\n}\n\n// Remove every auto-placed presenter pose (source 'pose') from all canvas boards —\n// run before re-placing (host regenerated) or when the host toggle goes off, so poses\n// never stack up. Only touches source:'pose' elements; user content is untouched.\nfunction clearPresenterPoses(doc) {\n if (!doc?.strip) return doc;\n let next = doc;\n for (const panel of doc.strip) {\n if (panel?.type !== 'canvas' || !Array.isArray(panel.elements)) continue;\n for (const el of panel.elements) {\n if (el?.source === 'pose') next = removeCanvasElement(next, panel.panelId, el.id);\n }\n }\n return next;\n}\n\n return {poseSpot,poseElement,SOLO_POSE,planPresenterPlacement,applyPresenterPlacement,placePosesOnDoc,clearPresenterPoses};\n}\n\nconst operation=createPresenterPlacement({});\nreturn {element:{...operation.poseElement(input.pose,{pos:operation.poseSpot(input.pose.label)}),appearMs:Math.round(input.atMs)}};\n`,tests:[{name:`Captured right pose`,input:{pose:{label:`point-right`,url:`pose`},atMs:100},expected:{element:{kind:`image`,src:`pose`,source:`pose`,pose:`point-right`,cutout:!0,entrance:`pop`,pinned:!0,appearMs:100,leaveMs:null,pos:{x:.2,y:.64},size:.3,query:`point-right`}}}]};function rd(e){return I(e?.version===1&&typeof e.insert==`function`,`HOST_SERVICES`,`Presenter insertion requires its version 1 broker.`),e}function id(e){let t=H(e),n=()=>t.actor();return Object.freeze(rd({version:1,async insert(e,r,i,a,{signal:o,assertCurrent:s}={}){let c=V({doc:e,pose:i}),l=n(),u=()=>{s?.(),I(l&&n()===l&&!o?.aborted&&V({doc:e,pose:i})===c,`STALE`,`Pose insertion was cancelled or the account, document or pose changed.`)};u();let d=e?.strip?.filter(e=>e.panelId===r);I(d?.length===1&&d[0].type===`canvas`&&Array.isArray(d[0].elements)&&d[0].elements.length<=4096&&L(i)&&Number.isFinite(a),`PRESENTER_INSERTION`,`Choose a valid canvas pose and time.`),I(i.url==null||typeof i.url==`string`,`PRESENTER_INSERTION`,`The selected pose media is unavailable.`);let f=i.url||null,p=structuredClone({pose:{...i.label===void 0?{}:{label:i.label},url:f?`pose`:null},atMs:a});B(p),I(JSON.stringify(p).length<=16384,`PRESENTER_INSERTION`,`Pose metadata is too large.`);let m=await t.run(nd,{kind:`run`,input:p,signal:o,timeoutMs:15e3});u();let h=String(p.pose.label||``).toLowerCase().replace(/[^a-z0-9]+/g,`-`).replace(/^-+|-+$/g,``).slice(0,40),g=String(p.pose.label||``),_={kind:`image`,src:p.pose.url,source:`pose`,pose:h,cutout:!0,entrance:`pop`,pinned:!0,appearMs:Math.round(a),leaveMs:null,pos:{x:/(^|-)right/.test(g)?.2:.8,y:.64},size:.3,query:h},v=m.outputs?.element;return B(_),B(v),I(V(v)===V(_),`PRESENTER_INSERTION`,`The sandbox changed the selected pose, timing or placement.`),u(),await ju(e,r,{...v,src:f},{host:t,signal:o,assertCurrent:u,validateDocument:q})}}))}let ad={manifest:{schemaVersion:1,sdkVersion:`0.1.0`,id:`stillmade-internal.canvas-keyframes`,version:`1.0.0`,name:`Canvas element keyframes`,description:`Edit and remove sorted position and size keyframes with nearest-time snapping.`,kind:`task`,runtime:`javascript`,inputs:{doc:{type:`json`},operation:{type:`text`},panelId:{type:`text`},elementId:{type:`text`},atMs:{type:`number`},patch:{type:`json`},index:{type:`integer`}},outputs:{edit:{type:`json`}},permissions:{project:[],network:[],filesystem:[],secrets:[]}},code:`const MOVE_SNAP_MS = 140;\nfunction setCanvasElementMove(doc, panelId, elementId, atMs, patch = {}) {\n const at = Math.round(Number(atMs) || 0);\n const strip = doc.strip.map((p) => {\n if (p.panelId !== panelId) return p;\n return {\n ...p,\n elements: (p.elements || []).map((el) => {\n if (el.id !== elementId) return el;\n const moves = Array.isArray(el.moves) ? el.moves.slice() : [];\n // Snap onto the NEAREST existing keyframe within the window (not the\n // first — \\`moves\\` is time-sorted, so findIndex would bias to the\n // earlier of two adjacent keyframes and edit the wrong one).\n let idx = -1; let best = MOVE_SNAP_MS + 1;\n moves.forEach((m, i) => {\n const gap = Math.abs((Number(m.atMs) || 0) - at);\n if (gap <= MOVE_SNAP_MS && gap < best) { best = gap; idx = i; }\n });\n if (idx >= 0) {\n moves[idx] = { ...moves[idx], ...(patch.pos ? { pos: patch.pos } : {}), ...(patch.size != null ? { size: patch.size } : {}) };\n } else {\n moves.push({ atMs: at, durMs: 500, ease: 'ease-in-out', ...(patch.pos ? { pos: patch.pos } : {}), ...(patch.size != null ? { size: patch.size } : {}) });\n }\n moves.sort((a, b) => (a.atMs || 0) - (b.atMs || 0));\n return { ...el, moves };\n }),\n };\n });\n return loadPanelDoc({ ...doc, strip });\n}\nfunction removeCanvasElementMove(doc, panelId, elementId, index) {\n const strip = doc.strip.map((p) => {\n if (p.panelId !== panelId) return p;\n return {\n ...p,\n elements: (p.elements || []).map((el) => {\n if (el.id !== elementId || !Array.isArray(el.moves)) return el;\n // Delete by the index into the TIME-SORTED view — that's the order the\n // inspector renders and passes back. Also leaves the stored array sorted.\n const moves = el.moves.slice().sort((a, b) => (a.atMs || 0) - (b.atMs || 0)).filter((_, i) => i !== index);\n return { ...el, moves };\n }),\n };\n });\n return loadPanelDoc({ ...doc, strip });\n}\n\nconst loadPanelDoc=doc=>doc;return {edit:input.operation==='set'?setCanvasElementMove(input.doc,input.panelId,input.elementId,input.atMs,input.patch):removeCanvasElementMove(input.doc,input.panelId,input.elementId,input.index)};`,tests:[]},od=(e,t)=>V(e)===V(t),sd=[`atMs`,`durMs`,`ease`,`pos`,`size`];function cd(e,t,n,r,i,a,o){let s=e.strip.find(e=>e.panelId===t);I(s?.type===`canvas`,`KEYFRAME`,`This canvas is no longer available.`),I([`set`,`remove`].includes(r)&&Number.isFinite(i)&&Number.isInteger(o)&&L(a)&&Object.keys(a).every(e=>[`pos`,`size`].includes(e)),`KEYFRAME`,`The requested keyframe edit is invalid.`),a.pos!==void 0&&I(L(a.pos)&&Object.keys(a.pos).every(e=>[`x`,`y`].includes(e))&&Number.isFinite(a.pos.x)&&Number.isFinite(a.pos.y),`KEYFRAME`,`Keyframe position must contain finite coordinates.`),a.size!==void 0&&I(Number.isFinite(a.size),`KEYFRAME`,`Keyframe size must be finite.`);let c={doc:{strip:[{panelId:t,elements:(s.elements||[]).map(e=>({id:e.id,...Array.isArray(e.moves)?{moves:e.moves.map((e,t)=>{let n={origin:t};for(let t of sd)e[t]!==void 0&&(n[t]=t===`pos`&&L(e.pos)?{x:e.pos.x,y:e.pos.y}:e[t]);return n})}:{}}))}]},panelId:t,elementId:n,operation:r,atMs:i,patch:a,index:o};return B(c),{panel:s,input:c}}function ld(e){let t=Math.round(Number(e.atMs)||0),n=e.doc.strip[0].elements.map(n=>{if(n.id!==e.elementId||e.operation===`remove`&&!Array.isArray(n.moves))return n;let r=(n.moves||[]).map(e=>({...e}));if(e.operation===`remove`)r=r.sort((e,t)=>(e.atMs||0)-(t.atMs||0)).filter((t,n)=>n!==e.index);else{let n=-1,i=141;for(let e=0;e<r.length;e++){let a=Math.abs((Number(r[e].atMs)||0)-t);a<=140&&a<i&&(n=e,i=a)}let a={...e.patch.pos?{pos:e.patch.pos}:{},...e.patch.size==null?{}:{size:e.patch.size}};n>=0?r[n]={...r[n],...a}:r.push({atMs:t,durMs:500,ease:`ease-in-out`,...a}),r.sort((e,t)=>(e.atMs||0)-(t.atMs||0))}return{...n,moves:r}});return{strip:[{panelId:e.panelId,elements:n}]}}function ud(e,{panel:t,input:n},r){let i=ld(n);B(i),B(r),I(od(r,i),`KEYFRAME`,`The sandbox returned a different keyframe edit.`);let a=!1,o=r.strip[0].elements.map((e,r)=>{let i=t.elements[r],o=n.doc.strip[0].elements[r],s=n.operation===`set`&&e.id===n.elementId&&!!n.patch.pos;if(od(e,o)&&!s)return i;let c=-1,l=141;if(s)for(let e of o.moves||[]){let t=Math.abs((Number(e.atMs)||0)-Math.round(Number(n.atMs)||0));t<=140&&t<l&&(l=t,c=e.origin)}let u=e.moves.map(e=>{if(e.origin===void 0)return e;let t=i.moves[e.origin],r=o.moves.find(t=>t.origin===e.origin),a={...t},l=!1;for(let t of sd)od(e[t]??null,r[t]??null)||(a[t]=e[t],l=!0);return s&&e.origin===c&&!od(t.pos,n.patch.pos)&&(a.pos=n.patch.pos,l=!0),l?a:t});return Array.isArray(i.moves)&&u.length===i.moves.length&&u.every((e,t)=>e===i.moves[t])?i:(a=!0,{...i,moves:u})});return a?{...e,strip:e.strip.map(e=>e===t?{...t,elements:o}:e)}:e}function dd({doc:e,projectId:t,panelId:n,canEdit:r,onDocChange:i,validateDocument:a,editLease:o,host:s}){let c=H(s),l=()=>c.actor(),[u,d]=(0,v.useState)(null),[f,p]=(0,v.useState)(``),m=(0,v.useRef)(null),h=(0,v.useRef)(!0),g=(0,v.useRef)(0),_=(0,v.useRef)(null),y=l();_.current={doc:e,projectId:t,panelId:n,canEdit:r,onDocChange:i,validateDocument:a,actor:y,services:c};let b=(0,v.useCallback)(()=>{g.current++,o?.current===m.current&&(o.current=null),m.current?.abort(),m.current=null,d(null)},[o]);return(0,v.useEffect)(()=>(h.current=!0,()=>{h.current=!1,g.current++,o?.current===m.current&&(o.current=null),m.current?.abort(),m.current=null}),[]),(0,v.useEffect)(()=>{b()},[e,t,n,r,y,c,b]),{change:(0,v.useCallback)(async(e,t,n=0,r={},i=-1)=>{let a=_.current;if(!a.doc||!a.canEdit||m.current||o?.current||a.services!==c)return;let s=++g.current,u=new AbortController;m.current=u,o&&(o.current=u),d(e),p(``);let f,v=()=>{let e=_.current;I(h.current&&m.current===u&&!u.signal.aborted&&e.doc===a.doc&&e.projectId===a.projectId&&e.panelId===a.panelId&&e.canEdit&&e.services===c&&e.actor===a.actor&&l()===a.actor&&JSON.stringify(a.doc)===f,`STALE`,`The canvas changed. Review the current keyframes again.`)};try{f=JSON.stringify(a.doc);let o=cd(a.doc,a.panelId,e,t,n,r,i);v();let d=await c.run(ad,{kind:`run`,input:o.input,signal:u.signal,timeoutMs:15e3});v();let m=ud(a.doc,o,d.outputs?.edit),y=m===a.doc?a.doc:a.validateDocument(m);if(v(),y!==a.doc){let e=JSON.stringify(y),t=!1;a.onDocChange(n=>{let r=_.current,i=!1;try{i=h.current&&g.current===s&&!u.signal.aborted&&r.doc===a.doc&&r.projectId===a.projectId&&r.panelId===a.panelId&&r.canEdit&&r.services===c&&r.actor===a.actor&&l()===a.actor&&JSON.stringify(y)===e&&JSON.stringify(n)===f&&JSON.stringify(a.doc)===f}catch{}return i?y:(t||(t=!0,queueMicrotask(()=>{h.current&&l()===a.actor&&_.current.projectId===a.projectId&&p(`The canvas changed before the keyframe edit could be saved. Review the current keyframes again.`)})),n)})}return y}catch(e){h.current&&!u.signal.aborted&&l()===a.actor&&_.current.projectId===a.projectId&&p(e.message||`The keyframe edit could not be applied.`)}finally{m.current===u&&(o?.current===u&&(o.current=null),m.current=null,h.current&&d(null))}},[c]),pending:u,error:f,cancel:b}}function fd(e,t,n={}){let r=vd(e,t);return n.color&&r.in&&r.in.shape!=null&&(r.in.color=n.color,r.in.colorAlpha=1-Math.min(1,Math.max(0,(t-.35)/.4))),r}let pd=.5,md=.34,hd=.66;function gd(e,t){let n=Math.max(0,Math.min(1,e)),r,i;return n<md?(r=1-n/md*.5,i=.5):n<hd?(r=pd,i=.5+t*((n-md)/.32)):(r=pd+.5*((n-hd)/.33999999999999997),i=.5+t),{outScale:r,outOff:r*(.5-i)*100,outA:1,inScale:r,inOff:r*(.5+t-i)*100,inA:1}}let _d={\"Zoom left\":[`tx`,1],\"Zoom right\":[`tx`,-1],\"Zoom up\":[`ty`,1],\"Zoom down\":[`ty`,-1]};function vd(e,t){if(_d[e]){let[n,r]=_d[e],i=gd(t,r);return{out:{alpha:i.outA,scale:i.outScale,[n]:i.outOff},in:{alpha:i.inA,scale:i.inScale,clip:null,[n]:i.inOff},overlay:null}}switch(e){case`Dip to black`:case`Dip to white`:case`flash`:{let n=e===`Dip to black`?`#000`:`#fff`;return{out:{alpha:t<.5?1-t*2:0,tx:0},in:{alpha:t>=.5?(t-.5)*2:0,tx:0,clip:null},overlay:{color:n,alpha:Math.sin(t*Math.PI)}}}case`whoosh`:{let e=Math.min(1,t*1.6);return{out:{alpha:1,tx:-e*100},in:{alpha:1,tx:(1-e)*100,clip:null},overlay:null}}case`Push left`:return{out:{alpha:1,tx:-t*100},in:{alpha:1,tx:(1-t)*100,clip:null},overlay:null};case`Push right`:return{out:{alpha:1,tx:t*100},in:{alpha:1,tx:-(1-t)*100,clip:null},overlay:null};case`Push up`:return{out:{alpha:1,ty:-t*100},in:{alpha:1,ty:(1-t)*100,clip:null},overlay:null};case`Push down`:return{out:{alpha:1,ty:t*100},in:{alpha:1,ty:-(1-t)*100,clip:null},overlay:null};case`Wipe left`:return{out:{alpha:1,tx:0},in:{alpha:1,tx:0,clip:[0,(1-t)*100,0,0]},overlay:null};case`Wipe right`:return{out:{alpha:1,tx:0},in:{alpha:1,tx:0,clip:[0,0,0,(1-t)*100]},overlay:null};case`Wipe up`:return{out:{alpha:1,tx:0},in:{alpha:1,tx:0,clip:[(1-t)*100,0,0,0]},overlay:null};case`Wipe down`:return{out:{alpha:1,tx:0},in:{alpha:1,tx:0,clip:[0,0,(1-t)*100,0]},overlay:null};case`Shape wipe`:return{out:{alpha:1,tx:0},in:{alpha:1,tx:0,clip:null,shape:t},overlay:null};case`Iris`:return{out:{alpha:1,tx:0},in:{alpha:1,tx:0,clip:null,shape:t,shapeKind:`circle`},overlay:null};case`Ink splat`:return{out:{alpha:1,tx:0},in:{alpha:1,tx:0,clip:null,shape:t,shapeKind:`blobs`},overlay:null};case`Swirl`:{let e=t*t*(3-2*t);return{out:{alpha:1-e,tx:0,rot:-e*160,scale:Math.max(.2,1-e*.6)},in:{alpha:e,tx:0,clip:null,rot:(1-e)*160,scale:.35+e*.65},overlay:null}}case`Whip left`:case`Whip right`:case`Whip up`:case`Whip down`:{let n=Math.min(1,t*1.25),r=e===`Whip up`||e===`Whip down`?`ty`:`tx`,i=e===`Whip right`||e===`Whip down`?1:-1;return{out:{alpha:1,tx:0,[r]:i*n*100},in:{alpha:1,tx:0,clip:null,[r]:i*-(1-n)*100},overlay:{color:`#ffffff`,alpha:Math.sin(t*Math.PI)*.35}}}case`Whip pan`:{let e=Math.min(1,t*1.25);return{out:{alpha:1,tx:-e*100},in:{alpha:1,tx:(1-e)*100,clip:null},overlay:{color:`#ffffff`,alpha:Math.sin(t*Math.PI)*.35}}}case`Morph`:{let e=t*t*(3-2*t);return{out:{alpha:1-Math.max(0,(t-.55)/.45),tx:0,scale:1+e*1.4},in:{alpha:1,tx:0,clip:null,shape:t,shapeKind:`circle`},overlay:null}}case`Slash`:return{out:{alpha:1,tx:0},in:{alpha:1,tx:0,clip:null,shape:t,shapeKind:`slash`},overlay:null};case`Shred`:return{out:{alpha:1,tx:0},in:{alpha:1,tx:0,clip:null,shape:t,shapeKind:`shreds`},overlay:null};default:return{out:{alpha:1-t,tx:0},in:{alpha:t,tx:0,clip:null},overlay:null}}}function yd(e,t,n,r){if(!t||t.shape==null)return;let i=Math.max(0,Math.min(1,t.shape));if(e.beginPath(),t.shapeKind===`circle`)e.arc(n/2,r/2,i*Math.hypot(n,r)*.55,0,Math.PI*2);else if(t.shapeKind===`blobs`){let t=Math.hypot(n,r)*.62;e.arc(n/2,r/2,Math.max(.01,i*i)*t,0,Math.PI*2);for(let a=0;a<7;a++){let o=a/7*Math.PI*2+.9,s=.72+.28*Math.sin(a*12.9898),c=Math.max(0,Math.min(1,(i-.08-a*.02)/.9));if(c<=0)continue;let l=(.18+.3*s)*Math.min(n,r)+c*t*.24,u=n/2+Math.cos(o)*l,d=r/2+Math.sin(o)*l;e.moveTo(u,d),e.arc(u,d,c*c*t*(.3+.18*s),0,Math.PI*2)}}else if(t.shapeKind===`slash`){let t=Math.hypot(n,r),a=-.44,o=Math.cos(a),s=Math.sin(a);for(let a=0;a<3;a++){let c=Math.max(0,Math.min(1,(i-a*.12)/.76));if(c<=0)continue;let l=n*(.25+a*.25),u=c*n*.42/2,d=t;e.moveTo(l-u*o+d*s,r/2-u*s-d*o),e.lineTo(l+u*o+d*s,r/2+u*s-d*o),e.lineTo(l+u*o-d*s,r/2+u*s+d*o),e.lineTo(l-u*o-d*s,r/2-u*s+d*o),e.closePath()}}else if(t.shapeKind===`shreds`){let t=r*.35;for(let a=0;a<6;a++){let o=Math.max(0,Math.min(1,(i-a*.07)/.6));if(o<=0)continue;let s=a/6*(n+t)-t,c=(n+t)/6*o;e.moveTo(s,0),e.lineTo(s+c,0),e.lineTo(s+c-t,r),e.lineTo(s-t,r),e.closePath()}}else{let t=i*n*1.4,a=i*r*1.4,o=Math.min(t,a)*.28,s=(n-t)/2,c=(r-a)/2;e.moveTo(s+o,c),e.arcTo(s+t,c,s+t,c+a,o),e.arcTo(s+t,c+a,s,c+a,o),e.arcTo(s,c+a,s,c,o),e.arcTo(s,c,s+t,c,o),e.closePath()}e.clip()}let bd={impact:{url:`/sounds/fx/impact.wav`,duration:.5,loop:!1,label:`Impact`},boom:{url:`/sounds/fx/boom.wav`,duration:.9,loop:!1,label:`Boom`},whoosh:{url:`/sounds/fx/whoosh.wav`,duration:.8,loop:!1,label:`Whoosh`},whoosh_short:{url:`/sounds/fx/whoosh_short.wav`,duration:.35,loop:!1,label:`Whoosh (short)`},glitch:{url:`/sounds/fx/glitch.wav`,duration:.45,loop:!1,label:`Glitch`},keystroke:{url:`/sounds/fx/keystroke.wav`,duration:.07,loop:!1,label:`Keystroke`},tick:{url:`/sounds/fx/tick.wav`,duration:.06,loop:!1,label:`Tick`},click:{url:`/sounds/fx/click.mp3`,duration:.37,loop:!1,label:`Click`},camera:{url:`/sounds/fx/camera.mp3`,duration:.5,loop:!1,label:`Camera shutter`},stinger:{url:`/sounds/fx/stinger.wav`,duration:1.2,loop:!1,label:`Stinger`},riser:{url:`/sounds/fx/riser.wav`,duration:1.5,loop:!1,label:`Riser`},strobe_pulse:{url:`/sounds/fx/strobe_pulse.wav`,duration:.22,loop:!1,label:`Strobe pulse`},shimmer:{url:`/sounds/fx/shimmer.wav`,duration:1,loop:!1,label:`Shimmer`},negative_hit:{url:`/sounds/fx/negative_hit.wav`,duration:.35,loop:!1,label:`Negative hit`},static_loop:{url:`/sounds/fx/static_loop.wav`,duration:3,loop:!0,label:`Static (loop)`},crt_hum_loop:{url:`/sounds/fx/crt_hum_loop.wav`,duration:3,loop:!0,label:`CRT hum (loop)`},vhs_hum_loop:{url:`/sounds/fx/vhs_hum_loop.wav`,duration:3,loop:!0,label:`VHS hum (loop)`},rain_loop:{url:`/sounds/fx/rain_loop.wav`,duration:4,loop:!0,label:`Rain (loop)`},wind_loop:{url:`/sounds/fx/wind_loop.wav`,duration:4,loop:!0,label:`Wind (loop)`},hologram_loop:{url:`/sounds/fx/hologram_loop.wav`,duration:3,loop:!0,label:`Hologram (loop)`},swirl_wind:{url:`/sounds/fx/swirl_wind.wav`,duration:.9,loop:!1,label:`Cyclone`},morph_warp:{url:`/sounds/fx/morph_warp.wav`,duration:.7,loop:!1,label:`Warp`},morph_bloom:{url:`/sounds/fx/morph_bloom.wav`,duration:.8,loop:!1,label:`Bloom`},shape_sweep:{url:`/sounds/fx/shape_sweep.wav`,duration:.45,loop:!1,label:`Sweep`},shape_pop:{url:`/sounds/fx/shape_pop.wav`,duration:.4,loop:!1,label:`Pop`},whip_crack:{url:`/sounds/fx/whip_crack.wav`,duration:.4,loop:!1,label:`Whip crack`},whip_zip:{url:`/sounds/fx/whip_zip.wav`,duration:.35,loop:!1,label:`Zip`},push_slide:{url:`/sounds/fx/push_slide.wav`,duration:.6,loop:!1,label:`Slide`},push_thump:{url:`/sounds/fx/push_thump.wav`,duration:.6,loop:!1,label:`Slide + thump`}},xd=[`shape_sweep`,`shape_pop`],Sd=[`whip_crack`,`whip_zip`],Cd=[`push_slide`,`push_thump`];Object.fromEntries(Object.entries({Swirl:[`whoosh`,`swirl_wind`],Morph:[`morph_warp`,`morph_bloom`],\"Shape wipe\":xd,Iris:xd,\"Ink splat\":xd,Slash:xd,Shred:xd,\"Whip pan\":Sd,\"Whip left\":Sd,\"Whip right\":Sd,\"Whip up\":Sd,\"Whip down\":Sd,\"Push left\":Cd,\"Push right\":Cd,\"Push up\":Cd,\"Push down\":Cd}).map(([e,t])=>[e,t[0]]));function wd(e){return Array.isArray(e)&&e.length>0&&e.every(e=>e&&e.url&&e.license&&e.source&&e.approvedAt&&Number(e.durationSec)>0)}function Td(e){return Array.isArray(e)&&e.length>0&&e.every(e=>e&&e.url&&e.license&&e.source&&e.approvedAt&&Number(e.durationSec)>0)}let Ed=e=>Math.round((Number(e)||0)*100)/100,Dd=[`Cut`,`Fade`,`Cross dissolve`,`Shape wipe`,`Iris`,`Ink splat`,`Whip pan`,`Slash`,`Shred`,`Dip to black`,`Dip to white`,`Push left`,`Push right`,`Push up`,`Push down`,`Zoom left`,`Zoom right`,`Zoom up`,`Zoom down`];({...Od()}),{...Od()},{...Od()},{...Od()},{...Od()},{...Od()},{...Od()},{...Od()},{...Od()},{...Od()};function Od(){return{brightness:0,contrast:0,saturation:0,temperature:0,sharpness:0,vignette:0}}Ed(.47),Object.entries(bd);let kd=[{value:`none`,label:`None`},{value:`pan`,label:`Pan`},{value:`zoom`,label:`Zoom`},{value:`ken-burns`,label:`Ken Burns`},{value:`drift`,label:`Drift`},{value:`wobble`,label:`In/Out Wobble`},{value:`handheld`,label:`Handheld Shake`},{value:`impact-shake`,label:`Impact Shake`},{value:`rotation-drift`,label:`Rotation Drift`},{value:`focus-pull`,label:`Focus Pull`}];function Ad(){return{type:`none`,intensity:60,easing:`ease-in-out`,range:[0,100],window:[0,100],loop:!1,panDirection:`left-right`,panAmount:15,zoomDirection:`in`,zoomAmount:1.15,zoomAnchor:`center`,kbStartX:50,kbStartY:50,kbEndX:60,kbEndY:40,kbStartScale:1,kbEndScale:1.2,driftAngle:45,driftSpeed:`subtle`,wobbleAmount:8,wobbleSpeed:`normal`,handIntensity:50,handFrequency:`normal`,shakeIntensity:70,shakeTrigger:`start`,rotDirection:`cw`,rotDegrees:3,focusDirection:`in`,focusAmount:`moderate`,rampStart:.5,rampEnd:2,rampCurve:`ease-out`}}function jd(e){let t=(0,v.useRef)(!1);return{onMouseDown:e=>{t.current=e.target===e.currentTarget},onMouseUp:n=>{t.current&&n.target===n.currentTarget&&e?.(n),t.current=!1}}}let Md=`aivw_fav_assets`;function Nd(){try{return new Set(JSON.parse(localStorage.getItem(Md)||`[]`))}catch{return new Set}}function Pd(e){try{localStorage.setItem(Md,JSON.stringify([...e]))}catch{}}function Fd({item:e,rootRef:t,onPick:n,favorable:r,isFav:i,onToggleFav:a,multi:o,isSelected:s}){let c=(0,v.useRef)(null),[l,u]=(0,v.useState)(!1);return(0,v.useEffect)(()=>{if(l)return;let e=c.current;if(!e)return;let n=new IntersectionObserver(e=>{e.some(e=>e.isIntersecting)&&(u(!0),n.disconnect())},{root:t.current||null,rootMargin:`120px`});return n.observe(e),()=>n.disconnect()},[l,t]),(0,D.jsxs)(`div`,{ref:c,style:{...Rd.cell,...o&&s?Rd.cellSelected:{}},title:`${e.name||`Asset`}${e.sub?` · ${e.sub}`:``}`,onClick:()=>n(e),children:[l&&e.url?(0,D.jsx)(`img`,{src:e.url,alt:``,style:Rd.thumb,loading:`lazy`}):(0,D.jsx)(`div`,{style:Rd.ph}),o&&(0,D.jsx)(`div`,{style:{...Rd.checkbox,...s?Rd.checkboxOn:{}},children:s?`✓`:``}),r&&(0,D.jsx)(`button`,{type:`button`,title:i?`Unfavorite`:`Favorite`,onClick:t=>{t.stopPropagation(),a(e)},style:{...Rd.star,color:i?`var(--signal)`:`var(--fg)`,opacity:i?1:.55},children:i?`★`:`☆`}),e.name&&(0,D.jsx)(`div`,{style:Rd.cap,children:e.name})]})}function Id({onChange:e}){let[t,n]=(0,v.useState)(``);return(0,v.useEffect)(()=>{let n=setTimeout(()=>e(t.trim().toLowerCase()),120);return()=>clearTimeout(n)},[t,e]),(0,D.jsx)(`input`,{type:`text`,value:t,onChange:e=>n(e.target.value),placeholder:`Search prompts, names…`,\"aria-label\":`Search assets`,style:Rd.search})}function Ld({title:e=`Select`,items:t=[],onPick:n,onClose:r,loading:i=!1,emptyText:a=`Nothing here yet.`,favorites:o=!1,multi:s=!1}){let c=(0,v.useRef)(null),[l,u]=(0,v.useState)(()=>Nd()),[d,f]=(0,v.useState)(!1),[p,m]=(0,v.useState)(``),[h,g]=(0,v.useState)(()=>new Set),_=e=>e.url||e.id,y=jd(r);(0,v.useEffect)(()=>{let e=e=>{e.key===`Escape`&&r?.()};return window.addEventListener(`keydown`,e),()=>window.removeEventListener(`keydown`,e)},[r]);let b=e=>{let t=e.url||e.id;u(e=>{let n=new Set(e);return n.has(t)?n.delete(t):n.add(t),Pd(n),n})},x=t.filter(e=>!(o&&d&&!l.has(e.url||e.id)||p&&!`${e.prompt||``} ${e.name||``} ${e.title||``} ${e.sub||``}`.toLowerCase().includes(p)));return(0,Qo.createPortal)((0,D.jsx)(`div`,{style:Rd.overlay,className:`nodrag nopan nowheel`,...y,children:(0,D.jsxs)(`div`,{style:Rd.panel,onClick:e=>e.stopPropagation(),children:[(0,D.jsxs)(`div`,{style:Rd.head,children:[(0,D.jsxs)(`span`,{style:Rd.title,children:[e,i?` · loading…`:``,` `,x.length?`(${x.length})`:``]}),(0,D.jsxs)(`div`,{style:{display:`flex`,alignItems:`center`,gap:8},children:[(0,D.jsx)(Id,{onChange:m}),o&&(0,D.jsx)(`button`,{type:`button`,onClick:()=>f(e=>!e),style:{...Rd.favToggle,...d?Rd.favToggleOn:{}},children:d?`★ Favorites`:`☆ Favorites`}),(0,D.jsx)(`button`,{type:`button`,style:Rd.close,onClick:r,\"aria-label\":`Close`,\"data-icon-action\":`true`,title:`Close`,children:(0,D.jsx)(k,{name:`x`,size:18})})]})]}),(0,D.jsx)(`div`,{ref:c,style:Rd.body,children:x.length===0?(0,D.jsx)(`div`,{style:Rd.empty,children:i?`Loading…`:o&&d?`No favorites yet — tap the star on any asset.`:a}):(0,D.jsx)(`div`,{style:Rd.grid,children:x.map(e=>(0,D.jsx)(Fd,{item:e,rootRef:c,multi:s,isSelected:s&&h.has(_(e)),onPick:e=>{s?g(t=>{let n=new Set(t),r=_(e);return n.has(r)?n.delete(r):n.add(r),n}):(n?.(e),r?.())},favorable:o,isFav:l.has(e.url||e.id),onToggleFav:b},e.id))})}),s&&(0,D.jsxs)(`div`,{style:Rd.footer,children:[(0,D.jsxs)(`span`,{style:Rd.footerCount,children:[h.size,` selected`]}),(0,D.jsxs)(`button`,{type:`button`,style:{...Rd.addBtn,...h.size?{}:Rd.addBtnDisabled},disabled:!h.size,onClick:()=>{n?.(x.filter(e=>h.has(_(e)))),r?.()},children:[`Add `,h.size||``]})]})]})}),document.body)}let Rd={overlay:{position:`fixed`,inset:0,zIndex:100060,background:`rgba(0,0,0,0.6)`,display:`flex`,alignItems:`center`,justifyContent:`center`,padding:24},panel:{width:`min(92vw, 760px)`,maxHeight:`82vh`,display:`flex`,flexDirection:`column`,background:`var(--bg-secondary)`,color:`var(--text-primary)`,border:`1px solid var(--border)`,borderRadius:`var(--r-3, 8px)`,boxShadow:`var(--shadow-lg, 0 16px 48px rgba(0,0,0,0.6))`,overflow:`hidden`,fontFamily:`var(--font-body)`},head:{display:`flex`,alignItems:`center`,justifyContent:`space-between`,padding:`12px 16px`,borderBottom:`1px solid var(--border)`,flexShrink:0},title:{fontSize:13,fontWeight:700,letterSpacing:`0.04em`,textTransform:`uppercase`,color:`var(--text-muted)`},close:{background:`var(--bg-elevated)`,border:`1px solid var(--border-light)`,color:`var(--text-primary)`,fontSize:14,lineHeight:1,cursor:`pointer`,width:26,height:26,borderRadius:6,display:`inline-flex`,alignItems:`center`,justifyContent:`center`,fontFamily:`var(--font-body)`},favToggle:{background:`transparent`,border:`1px solid var(--border-light)`,color:`var(--text-secondary)`,fontSize:11,fontWeight:600,padding:`4px 10px`,borderRadius:999,cursor:`pointer`,fontFamily:`var(--font-body)`},favToggleOn:{color:`var(--signal)`,borderColor:`var(--signal)`},search:{padding:`5px 10px`,borderRadius:999,fontSize:11,minWidth:150,background:`var(--bg-elevated)`,border:`1px solid var(--border-light)`,color:`var(--text-primary)`,fontFamily:`var(--font-body)`,outline:`none`},body:{overflowY:`auto`,padding:14,flex:1},grid:{display:`grid`,gridTemplateColumns:`repeat(auto-fill, minmax(120px, 1fr))`,gap:8},cell:{position:`relative`,cursor:`pointer`,borderRadius:`var(--r-2, 4px)`,overflow:`hidden`,border:`1px solid var(--border)`,background:`var(--bg-primary)`},thumb:{width:`100%`,aspectRatio:`1`,objectFit:`cover`,display:`block`},ph:{width:`100%`,aspectRatio:`1`,background:`var(--bg-inset, var(--bg-tertiary))`},star:{position:`absolute`,top:4,right:4,width:22,height:22,borderRadius:5,border:`none`,background:`rgba(0,0,0,0.45)`,fontSize:13,lineHeight:1,cursor:`pointer`,padding:0,display:`inline-flex`,alignItems:`center`,justifyContent:`center`},cap:{fontSize:10,color:`var(--text-secondary)`,padding:`4px 6px`,whiteSpace:`nowrap`,overflow:`hidden`,textOverflow:`ellipsis`},empty:{fontSize:12,color:`var(--text-muted)`,padding:24,textAlign:`center`},cellSelected:{outline:`2px solid var(--accent)`,outlineOffset:-2},checkbox:{position:`absolute`,top:4,left:4,width:20,height:20,borderRadius:`50%`,border:`1px solid var(--accent)`,background:`rgba(0,0,0,0.5)`,color:`var(--accent-contrast)`,fontSize:12,fontWeight:800,display:`flex`,alignItems:`center`,justifyContent:`center`},checkboxOn:{background:`var(--accent)`,color:`var(--accent-contrast)`},footer:{display:`flex`,alignItems:`center`,justifyContent:`space-between`,gap:12,padding:`12px 16px`,borderTop:`1px solid var(--border)`,flexShrink:0},footerCount:{fontSize:12,color:`var(--text-secondary)`},addBtn:{background:`var(--accent)`,color:`var(--accent-contrast)`,border:`none`,fontSize:13,fontWeight:700,padding:`8px 20px`,borderRadius:7,cursor:`pointer`,fontFamily:`var(--font-body)`},addBtnDisabled:{opacity:.4,cursor:`not-allowed`}};function zd(...e){let t=new Set,n=[];return e.flat().filter(Boolean).forEach(e=>{if(!e?.url||e.type!==`image`||t.has(e.url))return;t.add(e.url);let r=e.sub||e.projectName||null;n.push(e.id?{...e,sub:r,name:e.name||e.title||`Asset`}:{...e,sub:r,id:`image:${e.url}`,name:e.title||`Asset`})}),n}function Bd({onPick:e,label:t=`All Assets`,multi:n=!1,style:r}){let[i,a]=(0,v.useState)(!1),[o,s]=(0,v.useState)([]);return(0,v.useEffect)(()=>{if(!i)return;s(zd(rc()));let e=()=>s(zd(rc()));return window.addEventListener(`aivw-assets-changed`,e),()=>window.removeEventListener(`aivw-assets-changed`,e)},[i]),(0,D.jsxs)(D.Fragment,{children:[(0,D.jsx)(`button`,{type:`button`,style:r||Vd,className:`nodrag nopan`,onClick:()=>a(!0),children:t}),i&&(0,D.jsx)(Ld,{title:`All Assets`,items:[...o].sort((e,t)=>(t.timestamp||0)-(e.timestamp||0)),favorites:!0,multi:n,emptyText:`No assets found across your projects yet.`,onPick:t=>e?.(t),onClose:()=>a(!1)})]})}let Vd={width:`100%`,padding:`6px 8px`,fontSize:11,fontWeight:600,borderRadius:`var(--r-2, 4px)`,border:`1px solid var(--border)`,background:`transparent`,color:`var(--text-secondary)`,cursor:`pointer`,fontFamily:`var(--font-body)`,marginTop:4},Hd=new Map,Ud=e=>`${e.id||``}|${e.src}`;function Wd(e){let t=new Map,n=[],r=r=>{let i=Ud(r),a=t.get(i);if(a)return a;let o=Hd.get(i);if(!o){let e=document.createElement(`video`);e.crossOrigin=`anonymous`,e.muted=!0,e.playsInline=!0,e.preload=`metadata`,e.src=r.src,o={v:e,refs:0},Hd.set(i,o)}if(o.refs+=1,t.set(i,o.v),e&&o.v.readyState<2){let t=()=>e();o.v.addEventListener(`loadeddata`,t,{once:!0}),n.push([o.v,t])}return o.v};return{ensure:r,sync:(e,t)=>{for(let n of e?.elements||[]){if(n.kind!==`video`||!n.src||!(t>=(n.appearMs||0)&&(n.leaveMs==null||t<n.leaveMs)))continue;let e=r(n);if(e.readyState<1)continue;let i=Number(n.durationSec)||e.duration||0,a=Mt({...n,durationSec:i},t);if(Math.abs((e.currentTime||0)-a)>.08)try{e.currentTime=a}catch{}}},lookup:(e,n)=>{let r=n&&n.src===e?t.get(Ud(n)):null;if(!r){for(let[n,i]of t)if(n.endsWith(`|${e}`)){r=i;break}}return r&&r.readyState>=2?r:null},dispose:()=>{for(let[e,t]of n)e.removeEventListener(`loadeddata`,t);n.length=0;for(let e of t.keys()){let t=Hd.get(e);if(t&&(--t.refs,t.refs<=0)){try{t.v.pause(),t.v.removeAttribute(`src`),t.v.load()}catch{}Hd.delete(e)}}t.clear()}}}let Gd=`AI-generated via fal.ai (ElevenLabs SFX) — commercial use permitted`,Kd=`fal:fal-ai/elevenlabs/sound-effects/v2`,qd=[{id:`pop-snappy`,variant:`snappy`,name:`Snappy pop`,character:`clean, snappy, precise — the first pop of every scene`,url:`/sfx/pops/pop-snappy.wav`,durationSec:.092,source:Kd,license:Gd,generatedAt:`2026-07-20T23:47:40.581Z`,approvedBy:`owner`,approvedAt:`2026-07-21T00:00:00Z`},{id:`pop-cheek`,variant:`cheek`,name:`Cheek pop`,character:`hollow cheek pop, round mid-low — the scene’s second pop`,url:`/sfx/pops/pop-cheek.wav`,durationSec:.138,source:Kd,license:Gd,generatedAt:`2026-07-21T22:39:00Z`,approvedBy:`owner`,approvedAt:`2026-07-21T22:50:00Z`},{id:`pop-cheek2`,variant:`cheek2`,name:`Cheek pop 2`,character:`the second hit of the cheek pop generation — the scene’s third pop`,url:`/sfx/pops/pop-cheek2.wav`,durationSec:.15,source:Kd,license:Gd,generatedAt:`2026-07-21T22:39:00Z`,approvedBy:`owner`,approvedAt:`2026-07-21T22:50:00Z`},{id:`pop-bright`,variant:`bright`,name:`Bright pop`,character:`bright, light, airy — every pop after the third in a scene`,url:`/sfx/pops/pop-bright.wav`,durationSec:.148,source:Kd,license:Gd,generatedAt:`2026-07-20T23:47:43.702Z`,approvedBy:`owner`,approvedAt:`2026-07-21T00:00:00Z`}],Jd=[{id:`swoosh-swish`,variant:`swish`,name:`Swoosh`,character:`one fast air swish — the weighty-arrival sound`,url:`/sfx/pops/swish.wav`,durationSec:.247,source:Kd,license:Gd,generatedAt:`2026-07-21T17:19:16.426Z`,approvedBy:`owner`,approvedAt:`2026-07-21T23:30:00Z`}],Yd=[{value:`gpt-image-2.5-sunburst`,label:`GPT Image 2.5 Sunburst`},{value:`gpt-image-2.5-flare`,label:`GPT Image 2.5 Flare`},{value:`gpt-image-2`,label:`GPT Image 2`},{value:`nano-banana-2`,label:`Nano Banana 2`},{value:`nano-banana-2-lite`,label:`Nano Banana 2 Lite`},{value:`nano-banana-pro`,label:`Nano Banana Pro`},{value:`seedream-4.5`,label:`Seedream 4.5`}],Xd={backdrop:{position:`fixed`,inset:0,zIndex:5e3,background:`rgba(0,0,0,0.55)`,display:`flex`,alignItems:`center`,justifyContent:`center`,padding:20},modal:{width:`min(440px, 94vw)`,maxHeight:`86vh`,overflowY:`auto`,background:`var(--bg-primary)`,border:`1px solid var(--border)`,borderRadius:14,padding:16,boxShadow:`0 24px 70px rgba(0,0,0,0.5)`,fontFamily:`var(--font)`},titleRow:{display:`flex`,alignItems:`center`,gap:8,marginBottom:4},title:{fontSize:15,fontWeight:700,color:`var(--text-primary)`},beta:{fontSize:9,fontWeight:800,letterSpacing:`0.06em`,padding:`1px 6px`,borderRadius:999,background:`var(--accent)`,color:`var(--accent-contrast, #0A0A0A)`},close:{marginLeft:`auto`,width:28,height:28,borderRadius:7,border:`1px solid var(--border)`,background:`var(--bg-elevated)`,color:`var(--text-secondary)`,fontSize:16,lineHeight:1,cursor:`pointer`},head:{fontSize:11.5,color:`var(--text-secondary)`,margin:`2px 0 8px`},grid:{display:`grid`,gridTemplateColumns:`repeat(4, 1fr)`,gap:8,maxHeight:320,overflowY:`auto`},poseBtn:{display:`flex`,flexDirection:`column`,alignItems:`center`,gap:3,padding:5,borderRadius:8,border:`1px solid var(--border)`,background:`var(--bg-elevated)`,cursor:`pointer`},poseImg:{width:`100%`,height:40,objectFit:`contain`},poseLabel:{fontSize:9,color:`var(--text-muted)`,textAlign:`center`,lineHeight:1.1,maxWidth:`100%`,overflow:`hidden`,textOverflow:`ellipsis`,whiteSpace:`nowrap`},btn:{fontSize:12,padding:`7px 12px`,borderRadius:8,border:`1px solid var(--border)`,background:`var(--bg-elevated)`,color:`var(--text-primary)`,cursor:`pointer`},primary:{background:`var(--accent)`,color:`var(--accent-contrast, #0A0A0A)`,borderColor:`var(--accent)`},label:{fontSize:10.5,fontWeight:600,color:`var(--text-secondary)`,margin:`2px 0 -2px`},linkBtn:{fontSize:10.5,fontWeight:600,padding:`2px 6px`,borderRadius:6,border:`1px solid var(--border)`,background:`var(--bg-elevated)`,color:`var(--text-secondary)`,cursor:`pointer`},styleMenu:{display:`flex`,flexDirection:`column`,gap:2,maxHeight:150,overflowY:`auto`,border:`1px solid var(--border)`,borderRadius:8,padding:4,background:`var(--bg-secondary)`},input:{fontSize:12,padding:`7px 9px`,borderRadius:7,border:`1px solid var(--border)`,background:`var(--bg-elevated)`,color:`var(--text-primary)`,fontFamily:`var(--font)`,width:`100%`,boxSizing:`border-box`},cost:{fontSize:10.5,color:`var(--text-muted)`,marginTop:2},pickItem:{display:`flex`,alignItems:`center`,gap:8,padding:`6px 6px`,borderRadius:6,cursor:`pointer`},thumb:{width:26,height:26,borderRadius:5,objectFit:`cover`,background:`var(--bg-elevated)`,flexShrink:0}},Zd=Object.freeze([]);function Qd({hostServices:e,projectId:t,doc:n,panelId:r,canEdit:i=!0,host:a=null,content:o=``,words:s=Zd,onPick:c,onHostReady:l}){let{getLibraryItems:u,imageCost:d,getDefaultImageModel:f,getDefaultImageQuality:p,getDefaultImageResolution:m,getModelCapabilities:h,QUALITY_OPTIONS:g,ui:_}=os(e),{litePoses:y}=Gs(e),[b,x]=(0,v.useState)(!1),[S,C]=(0,v.useState)(null),[w,T]=(0,v.useState)(!1),[E,O]=(0,v.useState)(``),[A,j]=(0,v.useState)(``),[M,ee]=(0,v.useState)(``),[N,P]=(0,v.useState)(()=>f()),[te,ne]=(0,v.useState)(()=>{let e=h(`image`,f()),t=p();return e.quality?.includes(t)?t:e.quality?.[0]||t}),[re,F]=(0,v.useState)(!1),I=as(e,{projectId:t,doc:n,panelId:r,canEdit:i,content:o,words:s,open:b,host:a,defName:E,defStyle:A,defDesc:M,defModel:N,defQuality:te},()=>C(null)),L=a?.poses||[],R=h(`image`,N),z=g.filter(e=>(R.quality||[]).includes(e.value)),ie=(R.quality||[]).includes(te)?te:R.quality?.[0]||te,ae=(R.resolution||[]).includes(m())?m():R.resolution?.[0]||`1K`,oe=d(N,2,{quality:ie,resolution:ae}),B=S?S.phase===`insert`?`Placing pose…`:S.phase===`plan`?`Planning poses…`:S.phase===`generate`?`Generating pose sheet ${(S.done??0)+1}/${S.total||1}…`:S.phase===`slice`?`Cutting out poses ${(S.done??0)+1}/${S.total||1}…`:`Saving host…`:null,V=async t=>{let n;try{n=I.begin()}catch{return}if(n){T(!1),C({phase:`plan`});try{let r=await t(Ds(e,{assertCurrent:n.check,onProgress:e=>{n.check(),C(e)},model:N,quality:ie,resolution:ae}));n.check();let i=y(r);if(!i.length){_.alert(`The host has no usable poses.`);return}n.check(),l?.({enabled:!0,id:r.id,name:r.name,description:r.description||``,style:r.style||``,poses:i},{assertCurrent:n.admission()})}catch(e){n.current()&&e?.name!==`AbortError`&&_.alert(`Couldn't set up the host: ${e?.message||e}`)}finally{n.finish()}}},se=()=>V(e=>Ts({content:o,words:s,name:E.trim()||void 0,style:A.trim()||void 0,definition:M.trim()||void 0},e)),ce=e=>V(async t=>(await Es({character:e,content:o,words:s},t)).character),le=async e=>{let t;try{if(t=I.begin(),!t)return;C({phase:`insert`}),t.check(),await c?.(e,{assertCurrent:t.admission(),assertPending:t.check,signal:t.signal,onPrepared:()=>{t.check(),t.finish(),x(!1)}}),t.current()&&x(!1)}catch(e){t?.current()&&e?.name!==`AbortError`&&_.alert(e?.message||`The pose could not be placed.`)}finally{t?.finish()}},ue=u(`character`)||[],de=u(`style`)||[],fe=B?(0,D.jsxs)(`div`,{style:{fontSize:12.5,padding:`10px 2px`},children:[B,` `,(0,D.jsx)(`button`,{type:`button`,onClick:I.cancel,children:S?.phase===`insert`?`Cancel placement`:`Cancel setup`}),S?.phase!==`insert`&&(0,D.jsx)(`div`,{style:Xd.head,children:`Stops later steps. Requests already sent may still be charged.`})]}):L.length?(0,D.jsxs)(D.Fragment,{children:[(0,D.jsx)(`div`,{style:Xd.head,children:`Pick a pose for this board — swap or move it after.`}),(0,D.jsx)(`div`,{style:Xd.grid,children:L.map(e=>(0,D.jsxs)(`button`,{type:`button`,style:Xd.poseBtn,title:String(e.label).replace(/-/g,` `),onClick:()=>le(e),children:[e.url&&(0,D.jsx)(`img`,{src:e.url,alt:``,style:Xd.poseImg,loading:`lazy`}),(0,D.jsx)(`span`,{style:Xd.poseLabel,children:String(e.label).replace(/-/g,` `)})]},e.label))})]}):w?(0,D.jsxs)(`div`,{children:[(0,D.jsx)(`div`,{style:Xd.head,children:`Use a saved character as the host (missing poses are generated):`}),ue.length===0&&(0,D.jsx)(`div`,{style:{fontSize:11,color:`var(--text-muted)`},children:`No saved characters yet — create one instead.`}),(0,D.jsx)(`div`,{style:{maxHeight:220,overflowY:`auto`,display:`flex`,flexDirection:`column`,gap:2},children:ue.map(e=>(0,D.jsxs)(`div`,{style:Xd.pickItem,onClick:()=>ce(e),onMouseEnter:e=>{e.currentTarget.style.background=`var(--bg-elevated)`},onMouseLeave:e=>{e.currentTarget.style.background=`transparent`},children:[(e.selectedImageUrl||e.imageUrl)&&(0,D.jsx)(`img`,{src:e.selectedImageUrl||e.imageUrl,alt:``,style:Xd.thumb}),(0,D.jsx)(`span`,{style:{fontSize:12.5,color:`var(--text-primary)`},children:e.name||`Character`})]},e.id))}),(0,D.jsx)(`button`,{type:`button`,style:{...Xd.btn,marginTop:8},onClick:()=>T(!1),children:`Back`})]}):(0,D.jsxs)(`div`,{style:{display:`flex`,flexDirection:`column`,gap:7},children:[(0,D.jsx)(`div`,{style:Xd.head,children:`No presenter yet — create one, then drop its poses on any board. Left blank, it's designed from your narration.`}),(0,D.jsx)(`span`,{style:Xd.label,children:`Name`}),(0,D.jsx)(`input`,{value:E,onChange:e=>O(e.target.value),placeholder:`Host name (optional)`,style:Xd.input}),(0,D.jsxs)(`div`,{style:{display:`flex`,alignItems:`center`,gap:8},children:[(0,D.jsx)(`span`,{style:Xd.label,children:`Art style`}),de.length>0&&(0,D.jsx)(`button`,{type:`button`,style:Xd.linkBtn,\"aria-expanded\":re,onClick:()=>F(e=>!e),children:`Import from library`})]}),(0,D.jsx)(`input`,{value:A,onChange:e=>j(e.target.value),placeholder:`Art style (optional) — e.g. flat vector, chibi, hand-drawn, 3D clay`,style:Xd.input}),re&&(0,D.jsx)(`div`,{style:Xd.styleMenu,children:de.map(e=>(0,D.jsxs)(`div`,{style:Xd.pickItem,title:e.stylePrompt||e.name,onClick:()=>{j((e.stylePrompt||e.name||``).trim()),F(!1)},onMouseEnter:e=>{e.currentTarget.style.background=`var(--bg-elevated)`},onMouseLeave:e=>{e.currentTarget.style.background=`transparent`},children:[(e.selectedImageUrl||e.previewUrl||e.imageUrl)&&(0,D.jsx)(`img`,{src:e.selectedImageUrl||e.previewUrl||e.imageUrl,alt:``,style:Xd.thumb}),(0,D.jsx)(`span`,{style:{fontSize:12,color:`var(--text-primary)`,overflow:`hidden`,textOverflow:`ellipsis`,whiteSpace:`nowrap`},children:e.name||`Style`})]},e.id))}),(0,D.jsx)(`span`,{style:Xd.label,children:`Describe your host`}),(0,D.jsx)(`textarea`,{value:M,onChange:e=>ee(e.target.value),rows:2,placeholder:`Describe your host (optional) — e.g. a friendly woman in her 30s, glasses, casual blazer.`,style:{...Xd.input,resize:`vertical`}}),(0,D.jsx)(`span`,{style:Xd.label,children:`Model`}),(0,D.jsx)(`select`,{value:N,style:Xd.input,title:`Image model — defaults to your default in Settings`,onChange:e=>{let t=e.target.value;P(t);let n=h(`image`,t);ne(e=>n.quality?.length?n.quality.includes(e)?e:n.quality[0]:e)},children:Yd.map(e=>(0,D.jsxs)(`option`,{value:e.value,children:[e.label,e.value===f()?` (default)`:``]},e.value))}),z.length>0&&(0,D.jsxs)(D.Fragment,{children:[(0,D.jsx)(`span`,{style:Xd.label,children:`Quality`}),(0,D.jsx)(`select`,{value:ie,onChange:e=>ne(e.target.value),style:Xd.input,title:`Output quality for this model`,children:z.map(e=>(0,D.jsxs)(`option`,{value:e.value,children:[e.label,e.value===p()?` (default)`:``]},e.value))})]}),(0,D.jsxs)(`div`,{style:{display:`flex`,gap:8,marginTop:2},children:[(0,D.jsx)(`button`,{type:`button`,style:{...Xd.btn,...Xd.primary},onClick:se,children:M.trim()||A.trim()?`Create my host`:`Create one for me`}),(0,D.jsx)(`button`,{type:`button`,style:Xd.btn,onClick:()=>T(!0),children:`Use a saved character`})]}),(0,D.jsxs)(`div`,{style:Xd.cost,children:[`Generates `,2,` pose sheets — about `,oe,` credits.`]})]});return(0,D.jsxs)(D.Fragment,{children:[(0,D.jsx)(`button`,{className:`btn btn-secondary`,\"data-compact\":!0,style:{fontSize:11},\"aria-expanded\":b,title:`Add a presenter pose to this board — pick from your host, or create one`,disabled:!i,onClick:()=>x(!0),children:`+ Character Pose`}),b&&(0,Qo.createPortal)((0,D.jsx)(`div`,{style:Xd.backdrop,children:(0,D.jsxs)(`div`,{style:Xd.modal,role:`dialog`,\"aria-modal\":`true`,\"aria-label\":`Character pose`,children:[(0,D.jsxs)(`div`,{style:Xd.titleRow,children:[(0,D.jsx)(`span`,{style:Xd.title,children:`Character Pose`}),(0,D.jsx)(`span`,{style:Xd.beta,children:`BETA`}),(0,D.jsx)(`button`,{type:`button`,style:Xd.close,\"aria-label\":`Close`,onClick:()=>{I.cancel(),x(!1)},\"data-icon-action\":`true`,title:`Close`,children:(0,D.jsx)(k,{name:`x`,size:18})})]}),fe]})}),document.body)]})}function $d(e){return(0,D.jsx)(Qd,{...e,hostServices:e.hostServices||Ls().presenterHost})}let ef=[`Hanken Grotesk`,`Georgia`,`Arial`,`Times New Roman`,`Courier New`,`Verdana`],tf={display:`inline-flex`,alignItems:`center`,width:`auto`,marginTop:0,fontSize:10,fontWeight:500,padding:`4px 12px`,whiteSpace:`nowrap`,borderRadius:`var(--r-pill)`,border:`var(--bw-1) solid var(--border-strong)`,background:`transparent`,color:`var(--fg)`,cursor:`pointer`,fontFamily:`var(--font-body)`};function nf({label:e,value:t,onCommit:n,disabled:r}){let[i,a]=(0,v.useState)(String(((t??0)/1e3).toFixed(2)));return(0,v.useEffect)(()=>{a(String(((t??0)/1e3).toFixed(2)))},[t]),(0,D.jsxs)(`label`,{style:{display:`flex`,gap:4,alignItems:`center`,fontSize:10.5,color:`var(--text-secondary)`},children:[e,(0,D.jsx)(`input`,{type:`number`,inputMode:`decimal`,step:`0.1`,min:`0`,value:i,disabled:r,onChange:e=>a(e.target.value),onBlur:()=>n(Math.max(0,Math.round(Number(i)*1e3)||0)),style:{width:56,fontSize:11}}),`s`]})}function rf({value:e,onCommit:t,disabled:n,placeholder:r,style:i}){let[a,o]=(0,v.useState)(e||``);(0,v.useEffect)(()=>{o(e||``)},[e]);let s=()=>{a.trim()&&a!==e&&t(a)};return(0,D.jsx)(`input`,{type:`text`,value:a,disabled:n,placeholder:r,style:{flex:1,minWidth:120,fontSize:12,...i},onChange:e=>o(e.target.value),onBlur:s,onKeyDown:e=>{e.key===`Enter`&&(e.preventDefault(),e.currentTarget.blur())}})}function af({name:e,template:t=null,active:n=!1,disabled:r=!1,onPick:i,aspect:a=16/9}){let o=a<1,s=o?54:96,c=o?96:54,l=t?o?{slots:t.pSlots,textSlots:t.pTextSlots}:{slots:t.slots,textSlots:t.textSlots}:null;return(0,D.jsxs)(`button`,{type:`button`,onClick:i,disabled:r,title:t?`${e} — ${t.scenario}`:`No template — free placement`,style:{display:`flex`,flexDirection:`column`,gap:3,alignItems:`center`,padding:4,borderRadius:7,border:n?`2px solid var(--accent)`:`1px solid var(--border)`,background:`var(--bg-primary)`,cursor:`pointer`},children:[(0,D.jsx)(`svg`,{width:s,height:c,style:{display:`block`,borderRadius:4,background:`#fff`},children:l?(0,D.jsxs)(D.Fragment,{children:[l.slots.map((e,t)=>(0,D.jsx)(`rect`,{x:(e.x-e.w/2)*s,y:(e.y-e.h/2)*c,width:e.w*s,height:e.h*c,fill:`#d9d2c2`,stroke:`#9c937f`,strokeWidth:`1`,transform:e.tilt?`rotate(${e.tilt} ${e.x*s} ${e.y*c})`:void 0},`s${t}`)),l.textSlots.map((e,t)=>(0,D.jsx)(`rect`,{x:e.x*s-Math.min(.36,e.size*3.4)*s,y:(e.y-e.size/2)*c,width:Math.min(.72,e.size*6.8)*s,height:Math.max(2,e.size*c),rx:`1.5`,fill:e.role===`headline`?`#2b2a26`:`#7a7264`},`t${t}`))]}):(0,D.jsxs)(`g`,{stroke:`#b9b09c`,strokeWidth:`1.2`,fill:`none`,children:[(0,D.jsx)(`line`,{x1:s*.15,y1:c*.26,x2:s*.85,y2:c*.74}),(0,D.jsx)(`line`,{x1:s*.85,y1:c*.26,x2:s*.15,y2:c*.74})]})}),(0,D.jsx)(`span`,{style:{fontSize:9.5,fontWeight:700,color:n?`var(--accent)`:`var(--text-secondary)`,maxWidth:96,overflow:`hidden`,textOverflow:`ellipsis`,whiteSpace:`nowrap`},children:e})]})}function of({active:e=!1,disabled:t=!1,onPick:n,aspect:r=16/9}){let i=r<1,a=i?54:96,o=i?96:54,s=a*.16,c=o*.34,l=o*.16,u=o*.05;return(0,D.jsxs)(`button`,{type:`button`,onClick:n,disabled:t,title:`Typewriter — types this board's voiceover on the plain background, word-by-word, with a typing sound`,style:{display:`flex`,flexDirection:`column`,gap:3,alignItems:`center`,padding:4,borderRadius:7,border:e?`2px solid var(--accent)`:`1px solid var(--border)`,background:`var(--bg-primary)`,cursor:`pointer`},children:[(0,D.jsxs)(`svg`,{width:a,height:o,style:{display:`block`,borderRadius:4,background:`#fff`},children:[(0,D.jsx)(`rect`,{x:s,y:c,width:a*.6,height:u,rx:`1.5`,fill:`#2b2a26`}),(0,D.jsx)(`rect`,{x:s,y:c+l,width:a*.68,height:u,rx:`1.5`,fill:`#2b2a26`}),(0,D.jsx)(`rect`,{x:s,y:c+2*l,width:a*.3,height:u,rx:`1.5`,fill:`#2b2a26`}),(0,D.jsx)(`rect`,{x:s+a*.33,y:c+2*l-o*.02,width:a*.02,height:o*.09,fill:`#9c937f`})]}),(0,D.jsx)(`span`,{style:{fontSize:9.5,fontWeight:700,color:e?`var(--accent)`:`var(--text-secondary)`,maxWidth:96,overflow:`hidden`,textOverflow:`ellipsis`,whiteSpace:`nowrap`},children:`Typewriter`})]})}function sf(){let[e,t]=v.useState(()=>typeof window<`u`?window.innerWidth:1280);return v.useEffect(()=>{let e=()=>t(window.innerWidth);return window.addEventListener(`resize`,e),()=>window.removeEventListener(`resize`,e)},[]),e}let cf=Math.min(2,typeof window<`u`&&window.devicePixelRatio||1),lf=typeof window<`u`&&!!window.matchMedia?.(`(pointer: coarse)`).matches;function uf({panel:e,tMs:t,width:n,playing:r,selected:i,plan:a,onSeek:o,onSelect:s,onCommitTiming:c}){let l=Math.max(1,e.durationMs||1),u=Math.max(60,n-92),d=(0,v.useRef)(null),f=(0,v.useRef)(null),p=(e.elements||[]).slice().sort((e,t)=>(e.appearMs||0)-(t.appearMs||0)),m=new Map((a||[]).map(e=>[e.elementId,e])),h=e=>e/l*u,g=e=>Math.max(0,Math.min(l,e/u*l)),_=(0,v.useRef)(null),y=e=>{let t=_.current;t&&o(Math.round(g(e-t.rect.left)))},b=(e,t,n)=>{e.stopPropagation(),s(t.id);let r=e.currentTarget.closest(`[data-bar]`);r.setPointerCapture?.(e.pointerId),n===`move`&&(r.style.willChange=`transform`),f.current={id:t.id,mode:n,startPx:e.clientX,in0:t.appearMs||0,out0:t.leaveMs??l,node:r,next:null}},x=e=>{let t=f.current;if(!t)return;let n=(e.clientX-t.startPx)/u*l,r=t.in0,i=t.out0;if(t.mode===`move`){let e=t.out0-t.in0;r=Math.max(0,Math.min(l-100,t.in0+n)),i=Math.min(l,r+e),r=i-e}else t.mode===`in`?r=Math.max(0,Math.min(t.out0-100,t.in0+n)):i=Math.max(t.in0+100,Math.min(l,t.out0+n));t.next={in:Math.round(r),out:Math.round(i)},t.mode===`move`?t.node.style.transform=`translateX(${h(t.next.in)-h(t.in0)}px)`:(t.node.style.left=`${h(t.next.in)}px`,t.node.style.width=`${Math.max(6,h(t.next.out)-h(t.next.in))}px`)},S=()=>{let e=f.current;f.current=null,e&&(e.node.style.willChange=``,e.node.style.transform=``,e.next&&c(e.id,{appearMs:Math.min(e.next.in,l-100),leaveMs:e.next.out>=l?null:e.next.out}))},C=()=>{let e=f.current;f.current=null,e&&(e.node.style.willChange=``,e.node.style.transform=``,e.node.style.left=`${h(e.in0)}px`,e.node.style.width=`${Math.max(6,h(e.out0)-h(e.in0))}px`)};return(0,D.jsxs)(`div`,{style:{width:n,border:`1px solid var(--border)`,borderRadius:8,background:`var(--bg-secondary)`,overflow:`hidden`,userSelect:`none`},children:[(0,D.jsxs)(`div`,{style:{display:`flex`},children:[(0,D.jsx)(`div`,{style:{width:92,flexShrink:0,fontSize:9,color:`var(--text-muted)`,display:`flex`,alignItems:`center`,paddingLeft:8},children:`TIMELINE`}),(0,D.jsx)(`div`,{style:{position:`relative`,height:18,flex:1,cursor:`col-resize`,touchAction:`none`},onPointerDown:e=>{e.currentTarget.setPointerCapture?.(e.pointerId),_.current={rect:e.currentTarget.getBoundingClientRect(),raf:0,x:e.clientX},y(e.clientX)},onPointerMove:e=>{let t=_.current;t&&e.buttons&1&&(t.x=e.clientX,t.raf||=requestAnimationFrame(()=>{t.raf=0,y(t.x)}))},onPointerUp:()=>{let e=_.current;e?.raf&&cancelAnimationFrame(e.raf),_.current=null},onPointerCancel:()=>{let e=_.current;e?.raf&&cancelAnimationFrame(e.raf),_.current=null},children:Array.from({length:Math.floor(l/1e3)+1},(e,t)=>(0,D.jsx)(`div`,{style:{position:`absolute`,left:h(t*1e3),top:0,bottom:0,width:1,background:`var(--border)`},children:(0,D.jsxs)(`span`,{style:{position:`absolute`,top:1,left:3,fontSize:8.5,color:`var(--text-muted)`},children:[t,`s`]})},t))})]}),(0,D.jsxs)(`div`,{ref:d,style:{position:`relative`,maxHeight:148,overflowY:`auto`},children:[p.map(e=>{let t=e.appearMs||0,n=e.leaveMs??l,r=m.get(e.id),a=r?r.kind===`swoosh`?`#4a7fd4`:`var(--accent)`:null;return(0,D.jsxs)(`div`,{style:{display:`flex`,height:24,alignItems:`center`,borderTop:`1px solid var(--border)`},children:[(0,D.jsxs)(`div`,{style:{width:92,flexShrink:0,display:`flex`,gap:4,alignItems:`center`,paddingLeft:6,cursor:`pointer`,overflow:`hidden`},onClick:()=>s(e.id),title:e.kind===`text`?String(e.text||``):e.query||e.kind,children:[e.kind===`image`&&e.src?(0,D.jsx)(`img`,{src:e.src,alt:``,style:{width:22,height:15,objectFit:`cover`,borderRadius:2,flexShrink:0}}):(0,D.jsx)(`span`,{style:{fontSize:9,color:`var(--text-muted)`,flexShrink:0},children:`Aa`}),(0,D.jsx)(`span`,{style:{fontSize:9.5,color:i===e.id?`var(--accent)`:`var(--text-secondary)`,whiteSpace:`nowrap`,overflow:`hidden`,textOverflow:`ellipsis`},children:e.kind===`text`?String(e.text||``).slice(0,14):e.query||e.kind})]}),(0,D.jsx)(`div`,{style:{position:`relative`,flex:1,height:`100%`},children:(0,D.jsxs)(`div`,{\"data-bar\":!0,style:{position:`absolute`,top:4,bottom:4,left:h(t),width:Math.max(6,h(n)-h(t)),background:i===e.id?`var(--accent-dim)`:`var(--bg-elevated)`,border:`1px solid ${i===e.id?`var(--accent)`:`var(--border-strong, var(--border))`}`,borderRadius:4,cursor:`grab`,touchAction:`none`},onPointerDown:t=>b(t,e,`move`),onPointerMove:x,onPointerUp:S,onPointerCancel:C,children:[a&&(0,D.jsx)(`span`,{title:`plays a ${m.get(e.id).kind} when it appears`,style:{position:`absolute`,left:2,top:`50%`,transform:`translateY(-50%)`,width:6,height:6,borderRadius:`50%`,background:a}}),(!lf||i===e.id)&&(0,D.jsxs)(D.Fragment,{children:[(0,D.jsx)(`span`,{style:{position:`absolute`,left:lf?-5:-3,top:0,bottom:0,width:lf?14:8,cursor:`ew-resize`},onPointerDown:t=>b(t,e,`in`)}),(0,D.jsx)(`span`,{style:{position:`absolute`,right:lf?-5:-3,top:0,bottom:0,width:lf?14:8,cursor:`ew-resize`},onPointerDown:t=>b(t,e,`out`)})]})]})})]},e.id)}),(0,D.jsx)(`div`,{style:{position:`absolute`,top:0,bottom:0,left:92,width:1.5,background:`var(--accent)`,pointerEvents:`none`,transform:`translateX(${h(Math.min(t,l))}px)`,willChange:r?`transform`:void 0}})]})]})}let df=null;function ff(){return typeof document>`u`?null:(df||=document.createElement(`canvas`),df.getContext(`2d`))}let pf=(e,t,n)=>Math.max(t,Math.min(n,e));function mf({el:e,tMs:t,stageW:n,stageH:r,imgLookup:i,onPreview:a,onCommit:o}){let s=(0,v.useRef)(null),c=(0,v.useRef)(null),l=(0,v.useRef)(null),[,u]=v.useReducer(e=>e+1,0),d=Vt(e,t),f={...e,pos:d.pos,...d.size==null?{}:{size:d.size}},p=Ut(l.current?{...f,...l.current}:f,n,r,i,ff());if(!p)return null;let{cx:m,cy:h,w:g,h:_,rot:y}=p,b=e.kind===`text`,x=(t,n)=>{n.stopPropagation();try{n.currentTarget.setPointerCapture?.(n.pointerId)}catch{}let r=s.current.getBoundingClientRect();c.current={mode:t,rect:r,startX:n.clientX,startY:n.clientY,origPos:f.pos||{x:.5,y:.5},origSize:e.box?null:f.size||(b?.07:.28),origBox:e.box||null,origTilt:Number(e.tilt)||0,cx:m,cy:h,halfDiag:Math.max(1,Math.hypot(g/2,_/2)),origWpx:g,origHpx:_,rotRad:(Number(e.tilt)||0)*Math.PI/180}},S=e=>{let t=c.current;if(!t)return;let i=e.clientX-t.rect.left,o=e.clientY-t.rect.top;if(t.mode===`move`){let i=(e.clientX-t.startX)/n,a=(e.clientY-t.startY)/r;l.current={pos:{x:pf(t.origPos.x+i,.02,.98),y:pf(t.origPos.y+a,.02,.98)}}}else if(t.mode===`rotate`){let e=Math.atan2(o-t.cy,i-t.cx)*180/Math.PI,n=Math.round(e+90);Math.abs(n)<4&&(n=0),l.current={tilt:n}}else if(t.mode.startsWith(`edge-`))l.current={box:Wt({dir:t.mode.slice(5),dx:e.clientX-t.startX,dy:e.clientY-t.startY,wpx:t.origWpx,hpx:t.origHpx,rotRad:t.rotRad,stageW:n,stageH:r})};else{let e=pf(Math.hypot(i-t.cx,o-t.cy)/t.halfDiag,.12,8);if(t.origBox)l.current={box:{w:pf(t.origBox.w*e,.05,1),h:pf(t.origBox.h*e,.05,1)}};else{let n=b?.02:.05,r=b?.4:.95;l.current={size:pf(t.origSize*e,n,r)}}}t.raf||=requestAnimationFrame(()=>{let e=c.current;e&&(e.raf=0,a({...f,...l.current,moves:[]}),u())})},C=()=>{let e=c.current;c.current=null,e?.raf&&cancelAnimationFrame(e.raf);let n=l.current;l.current=null,e&&n&&o(n,t),u()},w={position:`absolute`,width:12,height:12,background:`#fff`,border:`1.5px solid var(--accent)`,borderRadius:2,boxShadow:`0 1px 3px rgba(0,0,0,0.3)`,touchAction:`none`,pointerEvents:`auto`},T=[{k:`nw`,x:0,y:0,cursor:`nwse-resize`},{k:`ne`,x:g,y:0,cursor:`nesw-resize`},{k:`se`,x:g,y:_,cursor:`nwse-resize`},{k:`sw`,x:0,y:_,cursor:`nesw-resize`}],E=b?[]:[{k:`n`,x:g/2,y:0,cursor:`ns-resize`,bw:20,bh:7},{k:`s`,x:g/2,y:_,cursor:`ns-resize`,bw:20,bh:7},{k:`w`,x:0,y:_/2,cursor:`ew-resize`,bw:7,bh:20},{k:`e`,x:g,y:_/2,cursor:`ew-resize`,bw:7,bh:20}];return(0,D.jsx)(`div`,{ref:s,\"data-selbox-root\":!0,style:{position:`absolute`,inset:0,pointerEvents:`none`,overflow:`visible`},children:(0,D.jsxs)(`div`,{style:{position:`absolute`,left:m,top:h,width:g,height:_,transform:`translate(-50%, -50%) rotate(${y}deg)`,border:`1.5px solid var(--accent)`,boxSizing:`border-box`},children:[(0,D.jsx)(`div`,{style:{position:`absolute`,inset:0,cursor:`move`,touchAction:`none`,pointerEvents:`auto`},onPointerDown:e=>x(`move`,e),onPointerMove:S,onPointerUp:C,onPointerCancel:C}),E.map(e=>(0,D.jsx)(`div`,{style:{...w,width:e.bw,height:e.bh,borderRadius:4,left:e.x,top:e.y,transform:`translate(-50%, -50%)`,cursor:e.cursor},onPointerDown:t=>x(`edge-${e.k}`,t),onPointerMove:S,onPointerUp:C,onPointerCancel:C},e.k)),T.map(e=>(0,D.jsx)(`div`,{style:{...w,left:e.x,top:e.y,transform:`translate(-50%, -50%)`,cursor:e.cursor},onPointerDown:t=>x(`resize-${e.k}`,t),onPointerMove:S,onPointerUp:C,onPointerCancel:C},e.k)),(0,D.jsx)(`div`,{style:{position:`absolute`,left:`50%`,top:-26,width:1.5,height:26,background:`var(--accent)`,transform:`translateX(-50%)`,pointerEvents:`none`}}),(0,D.jsx)(`div`,{style:{...w,left:`50%`,top:-30,borderRadius:`50%`,transform:`translate(-50%, -50%)`,cursor:`grab`},onPointerDown:e=>x(`rotate`,e),onPointerMove:S,onPointerUp:C,onPointerCancel:C})]})})}function hf(e,t,n,r,i){if(!(!n||n.alpha!=null&&n.alpha<=.001)){if(e.save(),e.globalAlpha=n.alpha==null?1:n.alpha,n.tx&&e.translate(n.tx/100*r,0),n.ty&&e.translate(0,n.ty/100*i),(n.scale&&n.scale!==1||n.rot)&&(e.translate(r/2,i/2),n.rot&&e.rotate(n.rot*Math.PI/180),n.scale&&n.scale!==1&&e.scale(n.scale,n.scale),e.translate(-r/2,-i/2)),n.shape!=null)yd(e,n,r,i);else if(n.clip){let[t,a,o,s]=n.clip;e.beginPath(),e.rect(s/100*r,t/100*i,r-(s+a)/100*r,i-(t+o)/100*i),e.clip()}e.drawImage(t,0,0,r,i),e.restore()}}let gf=e=>e&&e!==`cut`&&e!==`Cut`&&(Dd.includes(e)||e===`fade`),_f=new Map;function vf(e,t){if(_f.size>240){let e=_f.keys().next().value;_f.delete(e)}_f.set(e,t)}let yf=Object.freeze([]);function bf({mediaHost:e,panelEditHost:t,projectId:n,editLease:r,canEdit:i=!0,doc:a,panelId:o,onDocChange:s,onClose:c,aspect:l=`16:9`,variant:u=`modal`,autoPlay:d=!1,onEnded:f,prevPanel:p=null,transName:m=null,transMs:h=500,onRestartAll:g=null}){let _=au({host:e,doc:a,projectId:n,panelId:o,canEdit:i}),{imageCost:y,videoCost:b}=_.services,x=(0,v.useMemo)(()=>id(t),[t]),S=a.strip.find(e=>e.panelId===o),C=(0,v.useRef)(null),w=r||C,T=Su({host:t,doc:a,projectId:n,panelId:o,canEdit:i,onDocChange:s,validateDocument:q,editLease:w}),E=dd({host:t,doc:a,projectId:n,panelId:o,canEdit:i,onDocChange:s,validateDocument:q,editLease:w}),O=td({host:t,doc:a,projectId:n,panelId:o,canEdit:i,onDocChange:s,validateDocument:q,editLease:w}),A=qu({host:t,doc:a,projectId:n,panelId:o,canEdit:i,onDocChange:s,validateDocument:q,editLease:w}),j=Vu({host:t,doc:a,projectId:n,panelId:o,canEdit:i,onDocChange:s,validateDocument:q,editLease:w}),M=Or({host:t,doc:a,projectId:n,panelId:o,canEdit:i,onDocChange:s,validateDocument:q,editLease:w}),ee=Mu({host:t,doc:a,projectId:n,panelId:o,canEdit:i,onDocChange:s,validateDocument:q,editLease:w}),N=lu({host:t,doc:a,projectId:n,panelId:o,canEdit:i,onDocChange:s,validateDocument:q,editLease:w}),P=mu({host:t,doc:a,projectId:n,panelId:o,canEdit:i,onDocChange:s,validateDocument:q,editLease:w}),te=(0,v.useRef)(null),ne=(0,v.useRef)(_f),re=(0,v.useRef)(null),[F,I]=(0,v.useState)(0),[L,R]=(0,v.useState)(!1),z=(0,v.useRef)(null),ie=(0,v.useRef)(null);(0,v.useEffect)(()=>{d&&(I(0),R(!0))},[d]);let[ae,oe]=(0,v.useState)(null),B=(0,v.useMemo)(()=>Jt(S),[S]),V=(0,v.useRef)(new Map),[se,ce]=(0,v.useState)({open:!1,query:``,results:[],busy:!1,configured:null,forId:null});(0,v.useEffect)(()=>{ce(e=>e.open||e.busy?{open:!1,query:``,results:[],busy:!1,configured:null,forId:null}:e)},[a,n,o,i,e,_.actor]);let[le,ue]=(0,v.useState)(!1),[de,fe]=(0,v.useState)(!1),[pe,H]=v.useReducer(e=>e+1,0),[me,he]=l===`9:16`?[304,540]:l===`1:1`?[460,460]:[720,405],ge=sf(),_e=Math.min(me,Math.max(240,ge-64)),ve=Math.round(_e/me*he),ye=Math.round(_e*cf),be=Math.round(ve*cf),xe=(0,v.useRef)(null);if(xe.current||=Wd(()=>H()),(0,v.useEffect)(()=>()=>xe.current?.dispose(),[]),(0,v.useEffect)(()=>{let e=ne.current,t=[...S?.elements||[],...p?.elements||[]];for(let n of t){let t=[];n.kind===`image`&&n.src&&t.push(n.src),n.kind===`video`&&n.poster&&t.push(n.poster);for(let n of t){if(e.has(n))continue;let t=new Image;t.crossOrigin=`anonymous`,t.onload=()=>{vf(n,t),H()},t.onerror=()=>{let e=new Image;e.onload=()=>{vf(n,e),H()},e.src=n},t.src=n}n.kind===`video`&&n.src&&xe.current.ensure(n)}},[S?.elements,p]),(0,v.useEffect)(()=>{if(!L)return;let e=performance.now()-F,t=F-1,n=setInterval(()=>{let n=performance.now()-e;for(let e of Yt(B,t,n)){if(e.kind===`type`){let t=bd.keystroke.url,n=V.current.get(t);n||(n=new Audio(t),V.current.set(t,n)),n.volume=Math.max(0,Math.min(1,(e.volume??55)/100));try{n.currentTime=0}catch{}n.play().catch(()=>{});continue}let t=e.kind===`swoosh`?Jd:qd;if(!(e.kind===`swoosh`?Td(Jd):wd(qd)))continue;let n=t[Math.min(Math.max(0,e.variant||0),t.length-1)],r=V.current.get(n.url);r||(r=new Audio(n.url),V.current.set(n.url,r)),r.volume=Math.max(0,Math.min(1,(e.volume??55)/100));try{r.currentTime=0}catch{}r.play().catch(()=>{})}t=n,n>=(S?.durationMs||0)?(R(!1),I(S?.durationMs||0),f?.()):I(n)},33);return()=>clearInterval(n)},[L]),(0,v.useEffect)(()=>{let e=te.current;if(!e||!S)return;xe.current.sync(S,F);let t=e.getContext(`2d`),n=(e,t)=>ne.current.get(e)||xe.current.lookup(e,t),r=Number(h)>0?Number(h):500;if(p&&gf(m)&&F<r){let e=Math.max(0,Math.min(1,F/r)),i=fd(m===`fade`?`Fade`:m,e);z.current||(z.current=document.createElement(`canvas`),ie.current=document.createElement(`canvas`));for(let e of[z.current,ie.current])e.width=ye,e.height=be;let a=z.current.getContext(`2d`);a.clearRect(0,0,ye,be),Xt(a,p,p.durationMs||5e3,n,ye,be);let o=ie.current.getContext(`2d`);o.clearRect(0,0,ye,be),Xt(o,S,F,n,ye,be),t.clearRect(0,0,ye,be),t.fillStyle=typeof S.background==`string`&&/^#([0-9a-f]{3}|[0-9a-f]{6})$/i.test(S.background)?S.background:`#ffffff`,t.fillRect(0,0,ye,be),hf(t,z.current,i.out,ye,be),hf(t,ie.current,i.in,ye,be),i.overlay&&i.overlay.alpha>.001&&(t.save(),t.globalAlpha=i.overlay.alpha,t.fillStyle=i.overlay.color,t.fillRect(0,0,ye,be),t.restore());return}Xt(t,S,F,n,ye,be)},[S,F,ye,be,pe,p,m,h]),!S)return null;let Se=(e,t)=>M.change(e,t),Ce=S.autoArrange||!!S.template,U=(e,t)=>M.change(e,{...t,...Ce?{pinned:!0}:{}},!0),we=qt(S),W=(S.elements||[]).find(e=>e.id===ae)||null,Te=e=>{re.current=null;let t=te.current.getBoundingClientRect(),n=(e.clientX-t.left)/t.width,r=(e.clientY-t.top)/t.height,i=[...(S.elements||[]).filter(e=>F>=(e.appearMs||0)&&(e.leaveMs==null||F<e.leaveMs))].reverse().find(e=>{let t=e.pos||{x:.5,y:.5},i=e.kind===`image`||e.kind===`video`,a=(i?e.box?.w||e.size||.28:.18)/2,o=i&&e.box?e.box.h/2:a+.03;return Math.abs(n-t.x)<a&&Math.abs(r-t.y)<o});if(!i){oe(null);return}oe(i.id),re.current={id:i.id,startX:n,startY:r,orig:i.pos||{x:.5,y:.5},rect:t,raf:0}},Ee=e=>{let t=re.current;if(!t)return;let n=(e.clientX-t.rect.left)/t.rect.width,r=(e.clientY-t.rect.top)/t.rect.height;t.next={x:Math.max(.03,Math.min(.97,t.orig.x+(n-t.startX))),y:Math.max(.05,Math.min(.95,t.orig.y+(r-t.startY)))},t.raf||=requestAnimationFrame(()=>{let e=re.current;if(!e)return;e.raf=0;let t=te.current;if(!t)return;let n={...S,elements:S.elements.map(t=>t.id===e.id?{...t,pos:e.next}:t)};Xt(t.getContext(`2d`),n,F,(e,t)=>ne.current.get(e)||xe.current.lookup(e,t),ye,be)})},G=()=>{let e=re.current;re.current=null,e?.raf&&cancelAnimationFrame(e.raf),e?.next&&U(e.id,{pos:e.next})},De=e=>{let t=te.current;t&&S&&(xe.current.sync(S,e),Xt(t.getContext(`2d`),S,e,(e,t)=>ne.current.get(e)||xe.current.lookup(e,t),ye,be))},Oe=()=>{let e=re.current;re.current=null,e?.raf&&cancelAnimationFrame(e.raf),e&&De(F)},ke=()=>I(e=>Math.min(Math.round(e)+320,S.durationMs)),Ae=async()=>{await ee.change({kind:`text`,text:`New text`,appearMs:Math.round(F),leaveMs:null,pos:{x:.5,y:.22},size:.07,font:ef[0],color:`#111111`,weight:800,anim:{type:`pop`,perWord:!1,speedMs:180},sfx:`none`,pinned:!!S.autoArrange})&&ke()},je=async()=>{await ee.change({kind:`image`,src:null,query:``,source:`stock`,appearMs:Math.round(F),leaveMs:null,pos:{x:.5,y:.55},size:.28,tilt:0,entrance:S.handoff?.arrive===`fade`?`fade`:`pop`,sfx:`auto`,pinned:!!S.autoArrange})&&ke()},Me=async()=>{await ee.change({kind:`video`,src:null,query:``,source:`stock`,appearMs:Math.round(F),leaveMs:null,pos:{x:.5,y:.55},size:.34,tilt:0,entrance:S.handoff?.arrive===`fade`?`fade`:`pop`,sfx:`auto`,muted:!0,loop:!0,speed:1,trimStartSec:0,pinned:!!S.autoArrange})&&ke()},Ne=async(e,{assertCurrent:t,assertPending:n,signal:r,onPrepared:c}={})=>{let l=()=>{if(n?.(),t?.(),!i||r?.aborted)throw Object.assign(Error(`Pose insertion was cancelled.`),{name:`AbortError`})};if(l(),w.current)throw Error(`Wait for the current canvas edit before placing a pose.`);let u=new AbortController;w.current=u;let d=()=>u.abort();r?.addEventListener(`abort`,d,{once:!0});try{let n=await x.insert(a,o,e,Math.round(F),{signal:u.signal,assertCurrent:l});l(),c?.(),s(e=>{try{if(t?.(e),u.signal.aborted)return e}catch{return e}return n}),ke()}finally{r?.removeEventListener(`abort`,d),w.current===u&&(w.current=null)}},Pe=(e,{assertCurrent:t}={})=>{t?.(),s(n=>{try{t?.(n)}catch{return n}return{...n,meta:{...n.meta||{},host:e}}})},Fe=(a?.meta?.canvasChat?.intent||(a?.audio?.words||[]).map(e=>typeof e==`string`?e:e?.text||``).join(` `)).slice(0,4e3),[Ie,Le]=(0,v.useState)(!1),Re=a?.audio?.words?.length?Pn(a,S):[],ze=async e=>{await ee.change({kind:`text`,text:e.text,appearMs:e.wordTimes[0]||0,leaveMs:null,pos:S.autoArrange?null:{x:.5,y:.2},size:.065,font:ef[0],color:`#111111`,weight:800,wordTimes:e.wordTimes,anim:{type:`word-pop`,entrance:`pop`,perWord:!0,speedMs:180},sfx:`none`,pinned:!1})&&(Le(!1),I(Math.min((e.wordTimes[0]||0)+320,S.durationMs)))},[Be,Ve]=(0,v.useState)(!1),[He,Ue]=(0,v.useState)(`swipe-up`),[We,Ge]=(0,v.useState)(`pop`),Ke=async()=>{await T.change({mode:`continue`,atMs:Math.round(F),options:{exit:He,arrive:We}})&&(Ve(!1),oc.success?.(`New canvas added — the voiceover continues on a clean slate`))},qe=async(e,t=``,n=`photo`)=>{try{await _.run(async r=>{ce({open:!0,query:t,results:[],busy:!1,configured:null,forId:e,mediaType:n});let i=await _.services.stockStatus(r);r.assertCurrent(),ce(e=>({...e,configured:!!i.configured}))})}catch(e){e?.name!==`AbortError`&&oc.error?.(e?.message||`Stock is unavailable`)}},Je=async e=>{ce(t=>({...t,busy:!0,query:e}));try{await _.run(async t=>{let n=await _.services.stockGrid({query:e,type:se.mediaType||`photo`},t);t.assertCurrent(),ce(e=>({...e,busy:!1,results:n}))})}catch(e){if(e?.name===`AbortError`)return;ce(e=>({...e,busy:!1,results:[]})),e?.name!==`AbortError`&&oc.error?.(e?.message||`Stock search failed`)}},Ye=async e=>{try{await _.run(async t=>{let n=se.mediaType||`photo`;if(await _.services.stockSelect({type:n,id:String(e.id||``),source:e.source,downloadLocation:e.downloadLocation},t),t.assertCurrent(),n===`video`){if(!await Se(se.forId,{src:e.url,poster:e.previewUrl||e.thumb||null,source:`stock`,query:se.query,...Number(e.durationSec)>0?{durationSec:Number(e.durationSec)}:{}}))return}else if(!await Se(se.forId,{src:e.url||e.thumb,source:`stock`,query:se.query}))return;ce({open:!1,query:``,results:[],busy:!1,configured:null,forId:null})})}catch(e){e?.name!==`AbortError`&&oc.error?.(e?.message||`Could not select image`)}},Xe=(0,v.useRef)(null),Ze=(0,v.useRef)(null),K=(0,v.useRef)(null),Qe=async e=>{let t=e.target.files?.[0];e.target.value=``;let n=K.current;if(t&&n)try{await _.run(async e=>{let r=(t.name.split(`.`).pop()||`mp4`).toLowerCase(),i=await _.services.upload(t,r,e);e.assertCurrent(),await Se(n,{src:i,source:`upload`,poster:null})&&oc.success?.(`Clip uploaded`)})}catch(e){e?.name!==`AbortError`&&oc.error?.(e?.message||`Upload failed`)}},$e=async e=>{let t=e.target.files?.[0];e.target.value=``;let n=K.current;if(t&&n)try{await _.run(async e=>{let r=(t.name.split(`.`).pop()||`png`).toLowerCase(),i=await _.services.upload(t,r,e);e.assertCurrent(),await Se(n,{src:i,source:`upload`})&&oc.success?.(`Image uploaded`)})}catch(e){e?.name!==`AbortError`&&oc.error?.(e?.message||`Upload failed`)}},et=(e,t)=>{t?.url&&Se(e,{src:t.url,source:`library`})},tt=async e=>{let t=String(e.query||``).trim();if(!t){oc.error?.(`Give the video a description/search first.`);return}try{await _.run(async n=>{let r=await _.services.generateVideo({model:`wan-2.6-flash`,readablePrompt:t,duration:3,aspectRatio:`1:1`,generateAudio:!1},n);if(n.assertCurrent(),!r?.url)throw Error(r?.error||`no clip returned`);await Se(e.id,{src:r.url,source:`generated`,poster:null,durationSec:3})})}catch(e){e?.name!==`AbortError`&&oc.error?.(e?.message||`Clip generation failed`)}},nt=async e=>{let t=String(e.query||se.query||``).trim();if(!t){oc.error?.(`Give the image a description/search first.`);return}try{await _.run(async n=>{let r=await _.services.generateImage({model:`gpt-image-2`,readablePrompt:`${t}. Clean single subject on a plain background, collage cut-out ready.`,quality:`low`,resolution:`1K`,aspectRatio:`1:1`},n);if(n.assertCurrent(),!r?.url)throw Error(r?.error||`no image returned`);await Se(e.id,{src:r.url,source:`generated`})})}catch(e){e?.name!==`AbortError`&&oc.error?.(e?.message||`Generation failed`)}};return(0,D.jsxs)(`div`,{style:u===`page`?{background:`var(--bg-primary)`,border:`1px solid var(--border)`,borderRadius:14,padding:14,width:`100%`,minWidth:0,display:`flex`,gap:14,flexWrap:`wrap`}:{background:`var(--bg-primary)`,border:`1px solid var(--border)`,borderRadius:14,padding:14,width:`min(1060px, 96vw)`,maxHeight:`92vh`,overflow:`auto`,display:`flex`,gap:14,flexWrap:`wrap`},onClick:e=>e.stopPropagation(),children:[E.pending&&(0,D.jsxs)(`div`,{role:`status`,style:{width:`100%`},children:[`Updating element keyframes… `,(0,D.jsx)(`button`,{type:`button`,className:`btn btn-secondary`,onClick:E.cancel,children:`Cancel keyframe edit`})]}),E.error&&(0,D.jsx)(`div`,{role:`alert`,style:{width:`100%`},children:E.error}),O.pending&&(0,D.jsxs)(`div`,{role:`status`,style:{width:`100%`},children:[`Arranging the canvas template… `,(0,D.jsx)(`button`,{type:`button`,className:`btn btn-secondary`,onClick:O.cancel,children:`Cancel template change`})]}),O.error&&(0,D.jsx)(`div`,{role:`alert`,style:{width:`100%`},children:O.error}),A.pending&&(0,D.jsxs)(`div`,{role:`status`,style:{width:`100%`},children:[`Laying out typewriter narration… `,(0,D.jsx)(`button`,{type:`button`,className:`btn btn-secondary`,onClick:A.cancel,children:`Cancel typewriter change`})]}),A.error&&(0,D.jsx)(`div`,{role:`alert`,style:{width:`100%`},children:A.error}),j.pending&&(0,D.jsxs)(`div`,{role:`status`,style:{width:`100%`},children:[`Removing the element and arranging the canvas… `,(0,D.jsx)(`button`,{type:`button`,className:`btn btn-secondary`,onClick:j.cancel,children:`Cancel element deletion`})]}),j.error&&(0,D.jsx)(`div`,{role:`alert`,style:{width:`100%`},children:j.error}),T.pending&&(0,D.jsxs)(`div`,{role:`status`,style:{width:`100%`},children:[`Updating canvas continuation… `,(0,D.jsx)(`button`,{type:`button`,className:`btn btn-secondary`,onClick:T.cancel,children:`Cancel continuation`})]}),T.error&&(0,D.jsx)(`div`,{role:`alert`,style:{width:`100%`},children:T.error}),M.pending&&(0,D.jsxs)(`div`,{role:`status`,style:{width:`100%`},children:[`Applying element settings… `,(0,D.jsx)(`button`,{type:`button`,className:`btn btn-secondary`,onClick:M.cancel,children:`Cancel element edit`})]}),M.error&&(0,D.jsx)(`div`,{role:`alert`,style:{width:`100%`},children:M.error}),ee.pending&&(0,D.jsxs)(`div`,{role:`status`,style:{width:`100%`},children:[`Adding the element and arranging the canvas… `,(0,D.jsx)(`button`,{type:`button`,className:`btn btn-secondary`,onClick:ee.cancel,children:`Cancel element creation`})]}),ee.error&&(0,D.jsx)(`div`,{role:`alert`,style:{width:`100%`},children:ee.error}),N.pending&&(0,D.jsxs)(`div`,{role:`status`,style:{width:`100%`},children:[`Updating background… `,(0,D.jsx)(`button`,{type:`button`,className:`btn btn-secondary`,onClick:N.cancel,children:`Cancel background edit`})]}),N.error&&(0,D.jsx)(`div`,{role:`alert`,style:{width:`100%`},children:N.error}),P.pending&&(0,D.jsxs)(`div`,{role:`status`,style:{width:`100%`},children:[`Arranging canvas elements… `,(0,D.jsx)(`button`,{type:`button`,className:`btn btn-secondary`,onClick:P.cancel,children:`Cancel arrangement`})]}),P.error&&(0,D.jsx)(`div`,{role:`alert`,style:{width:`100%`},children:P.error}),(0,D.jsxs)(`div`,{style:{display:`flex`,flexDirection:`column`,gap:8,minWidth:0,maxWidth:`100%`},children:[(0,D.jsxs)(`div`,{style:{display:`flex`,gap:8,alignItems:`center`,flexWrap:`wrap`},children:[(0,D.jsxs)(`strong`,{style:{fontSize:13},children:[u===`page`?`Board`:`Collage canvas`,` · `,S.panelId]}),(0,D.jsxs)(`span`,{style:{fontSize:10.5,color:`var(--text-secondary)`},children:[(S.durationMs/1e3).toFixed(2),`s · `,S.autoArrange?`self-arranging (drag an element to pin it)`:`hand-built — nothing moves unless you move it`]})]}),(0,D.jsxs)(`div`,{style:{position:`relative`,width:_e,height:ve,maxWidth:`100%`},children:[(0,D.jsx)(`canvas`,{ref:te,width:ye,height:be,style:{display:`block`,borderRadius:10,border:`1px solid var(--border)`,cursor:`grab`,touchAction:ae?`none`:`pan-y`,width:_e,height:ve},onPointerDown:e=>{e.currentTarget.setPointerCapture?.(e.pointerId),Te(e)},onPointerMove:Ee,onPointerUp:G,onPointerCancel:Oe}),W&&!L&&(0,D.jsx)(mf,{el:W,tMs:F,stageW:_e,stageH:ve,imgLookup:(e,t)=>ne.current.get(e)||xe.current.lookup(e,t),onPreview:e=>{let t=te.current;if(!t)return;let n={...S,elements:S.elements.map(t=>t.id===e.id?e:t)};Xt(t.getContext(`2d`),n,F,(e,t)=>ne.current.get(e)||xe.current.lookup(e,t),ye,be)},onCommit:(e,t)=>{let n=Array.isArray(W.moves)&&W.moves.length>0,r=e&&(`pos`in e||`size`in e)&&!(`tilt`in e)&&!(`box`in e);if(n&&r&&t>(W.appearMs||0)+150){let n={};e.pos&&(n.pos=e.pos),`size`in e&&(n.size=e.size),E.change(W.id,`set`,Math.round(t),n)}else U(W.id,e)}})]}),(0,D.jsxs)(`div`,{style:{display:`flex`,gap:8,alignItems:`center`},children:[(0,D.jsx)(`button`,{className:`btn btn-secondary`,\"data-compact\":!0,\"aria-label\":L?`Pause`:`Play`,title:L?`Pause`:`Play`,style:{width:36,height:30,padding:0,display:`inline-flex`,alignItems:`center`,justifyContent:`center`},onClick:()=>{!L&&F>=S.durationMs&&I(0),R(e=>!e)},children:L?(0,D.jsxs)(`svg`,{width:`12`,height:`13`,viewBox:`0 0 12 13`,\"aria-hidden\":`true`,children:[(0,D.jsx)(`rect`,{x:`1.5`,y:`1`,width:`3`,height:`11`,rx:`0.6`,fill:`currentColor`}),(0,D.jsx)(`rect`,{x:`7.5`,y:`1`,width:`3`,height:`11`,rx:`0.6`,fill:`currentColor`})]}):(0,D.jsx)(`svg`,{width:`12`,height:`13`,viewBox:`0 0 12 13`,\"aria-hidden\":`true`,children:(0,D.jsx)(`path`,{d:`M2 1.2 L11 6.5 L2 11.8 Z`,fill:`currentColor`})})}),g&&(0,D.jsx)(`button`,{className:`btn btn-secondary`,\"data-compact\":!0,\"aria-label\":`Restart from the first board`,title:`Restart from the first board`,style:{width:36,height:30,padding:0,display:`inline-flex`,alignItems:`center`,justifyContent:`center`},onClick:()=>{R(!1),I(0),g()},\"data-icon-action\":`true`,children:(0,D.jsxs)(`svg`,{width:`15`,height:`15`,viewBox:`0 0 24 24`,fill:`none`,stroke:`currentColor`,strokeWidth:`2.2`,strokeLinecap:`round`,strokeLinejoin:`round`,\"aria-hidden\":`true`,children:[(0,D.jsx)(`path`,{d:`M3 12 a9 9 0 1 0 3-6.7`}),(0,D.jsx)(`path`,{d:`M3 4 v4 h4`})]})}),(0,D.jsx)(`input`,{type:`range`,min:0,max:S.durationMs,value:Math.min(F,S.durationMs),style:{flex:1,accentColor:`var(--accent)`,touchAction:`none`},onChange:e=>{R(!1),I(Number(e.target.value))}}),(0,D.jsxs)(`span`,{style:{fontSize:11,fontVariantNumeric:`tabular-nums`,width:74,textAlign:`right`},children:[(F/1e3).toFixed(2),` / `,(S.durationMs/1e3).toFixed(2),`s`]})]}),(0,D.jsx)(`input`,{ref:Xe,type:`file`,accept:`video/mp4,video/webm,video/quicktime`,style:{display:`none`},onChange:Qe}),(0,D.jsx)(`input`,{ref:Ze,type:`file`,accept:`image/png,image/jpeg,image/webp,image/gif`,style:{display:`none`},onChange:$e}),(0,D.jsx)(`div`,{style:{maxWidth:`100%`,overflowX:`auto`},children:(0,D.jsx)(uf,{panel:S,tMs:F,width:_e,playing:L,selected:ae,plan:B,onSeek:e=>{R(!1),I(e)},onSelect:oe,onCommitTiming:(e,t)=>Se(e,t)})}),(0,D.jsxs)(`div`,{style:{display:`flex`,gap:6,alignItems:`center`,flexWrap:`wrap`},children:[(0,D.jsx)(`button`,{className:`btn btn-secondary`,\"data-compact\":!0,style:{fontSize:11},onClick:je,children:`+ Image`}),(0,D.jsx)(`button`,{className:`btn btn-secondary`,\"data-compact\":!0,style:{fontSize:11},onClick:Me,children:`+ Video`}),(0,D.jsx)(`button`,{className:`btn btn-secondary`,\"data-compact\":!0,style:{fontSize:11},onClick:Ae,children:`+ Text`}),(0,D.jsx)($d,{projectId:n,doc:a,panelId:o,canEdit:i,host:a?.meta?.host,content:Fe,words:a?.audio?.words||yf,onPick:Ne,onHostReady:Pe}),Re.length>0&&(0,D.jsx)(`button`,{className:`btn btn-secondary`,\"data-compact\":!0,style:{fontSize:11},title:`Turn a line of the voiceover into on-canvas text that appears word-by-word as it's said`,onClick:()=>Le(e=>!e),children:`+ VO text`}),(0,D.jsx)(`button`,{className:`btn btn-secondary`,\"data-compact\":!0,style:{fontSize:11},title:u===`page`?`Add a new blank board that continues from this point — the current content swipes away or cuts`:`Add a new blank white canvas that continues the voiceover from this point — the current content swipes away or cuts`,onClick:()=>Ve(e=>!e),children:u===`page`?`Continue on new board`:`Continue on new canvas`}),(0,D.jsxs)(`div`,{style:{position:`relative`},children:[(0,D.jsxs)(`button`,{className:`btn btn-secondary`,\"data-compact\":!0,style:{fontSize:11,display:`flex`,gap:6,alignItems:`center`},\"aria-expanded\":de,title:`Canvas background — solid colours or gradient looks`,onClick:()=>fe(e=>!e),children:[`Background`,(0,D.jsx)(`span`,{style:{width:18,height:12,borderRadius:3,border:`1px solid var(--border)`,background:Ct(S.background||`#ffffff`)}})]}),de&&(0,D.jsxs)(`div`,{style:{position:`absolute`,top:`100%`,left:0,marginTop:4,zIndex:60,background:`var(--bg-primary)`,border:`1px solid var(--border)`,borderRadius:10,padding:10,boxShadow:`0 12px 34px rgba(0,0,0,0.35)`,width:224},onClick:e=>e.stopPropagation(),children:[(()=>{let e=ft(S.background);return(0,D.jsx)(`div`,{style:{display:`grid`,gridTemplateColumns:`repeat(4, 1fr)`,gap:6},children:wt.map(t=>{let n=ft(t.value),r=n&&e?n.key===e.key:S.background===t.value;return(0,D.jsx)(`button`,{type:`button`,title:t.label,disabled:!i||!!N.pending,onClick:()=>N.change({kind:`set`,value:t.value}),style:{height:38,borderRadius:6,cursor:`pointer`,background:Ct(t.value),border:r?`2px solid var(--accent)`:`1px solid var(--border)`}},t.key)})})})(),(()=>{let e=mt(S.background);return e?(0,D.jsx)(`div`,{style:{display:`flex`,flexDirection:`column`,gap:6,marginTop:8},children:e.map((e,t)=>(0,D.jsxs)(`label`,{style:{display:`flex`,gap:8,alignItems:`center`,fontSize:10.5,color:`var(--text-secondary)`},children:[(0,D.jsx)(sc,{type:`color`,value:ht(S.background,t)||e.default,disabled:!i||!!N.pending,onChange:e=>N.change({kind:`color`,slot:t,value:e.target.value})}),e.label]},e.key))}):null})(),(0,D.jsxs)(`label`,{style:{display:`flex`,gap:6,alignItems:`center`,marginTop:8,fontSize:10.5,color:`var(--text-secondary)`},children:[`Custom colour`,(0,D.jsx)(sc,{type:`color`,value:(S.background||`#ffffff`).startsWith(`#`)?S.background:`#ffffff`,disabled:!i||!!N.pending,onChange:e=>N.change({kind:`set`,value:e.target.value})})]})]})]}),(0,D.jsx)(`button`,{className:`btn btn-secondary`,\"data-compact\":!0,style:{fontSize:11},\"aria-expanded\":le,title:`Pick a slot layout — existing images reflow into its slots (your pinned moves stay put)`,onClick:()=>ue(e=>!e),children:S.mode===`typewriter`?`Template: Typewriter`:en(S.template)?`Template: ${en(S.template).name}`:`Templates`}),!S.autoArrange&&!S.template&&(0,D.jsx)(`button`,{className:`btn btn-secondary`,\"data-compact\":!0,style:{fontSize:11},title:`One-time auto-arrange of the current elements — only runs when you press it`,disabled:!i||!!P.pending,onClick:()=>P.change(me/he),children:`Tidy`}),we.length>0&&(0,D.jsxs)(`button`,{type:`button`,style:{fontSize:10,color:`#d97706`,border:`1px solid #d97706`,background:`none`,borderRadius:999,padding:`1px 8px`,cursor:`pointer`,fontFamily:`inherit`},title:we.map(e=>`${(e.fromMs/1e3).toFixed(1)}s → ${(e.toMs/1e3).toFixed(1)}s`).join(` · `),onClick:()=>oc.info?.(`Static stretches: ${we.map(e=>`${(e.fromMs/1e3).toFixed(1)}s → ${(e.toMs/1e3).toFixed(1)}s`).join(` · `)}`),children:[we.length,` static stretch`,we.length===1?``:`es`,` over 2.5s — add a beat (advisory)`]}),(0,D.jsx)(`span`,{style:{flex:1}}),c&&(0,D.jsx)(`button`,{className:`btn btn-primary`,\"data-compact\":!0,style:{fontSize:11},onClick:c,children:`Done`})]}),Ie&&(0,D.jsxs)(`div`,{style:{display:`flex`,flexDirection:`column`,gap:4,padding:8,border:`1px solid var(--border)`,borderRadius:8,background:`var(--bg-secondary)`,maxHeight:200,overflowY:`auto`},children:[(0,D.jsx)(`span`,{style:{fontSize:10,color:`var(--text-muted)`,textTransform:`uppercase`,letterSpacing:.5},children:`Narration in this canvas — click a line to place it, synced to speech`}),Re.map((e,t)=>(0,D.jsxs)(`button`,{type:`button`,className:`btn btn-secondary`,\"data-compact\":!0,style:{fontSize:11,textAlign:`left`,justifyContent:`flex-start`},onClick:()=>ze(e),children:[(e.wordTimes[0]/1e3).toFixed(1),`s · `,e.text.slice(0,70)]},t))]}),Be&&(0,D.jsxs)(`div`,{style:{display:`flex`,gap:8,alignItems:`center`,flexWrap:`wrap`,padding:8,border:`1px solid var(--border)`,borderRadius:8,background:`var(--bg-secondary)`},children:[(0,D.jsxs)(`span`,{style:{fontSize:11,color:`var(--text-secondary)`},children:[`Split at `,(F/1e3).toFixed(2),`s:`]}),(0,D.jsx)(`select`,{value:He,style:{fontSize:10.5},onChange:e=>Ue(e.target.value),children:On.map(e=>(0,D.jsxs)(`option`,{value:e,children:[`exit: `,e.replace(`-`,` `)]},e))}),(0,D.jsx)(`select`,{value:We,style:{fontSize:10.5},onChange:e=>Ge(e.target.value),children:kn.map(e=>(0,D.jsxs)(`option`,{value:e,children:[`arrive: `,e===`fade`?`fade in`:e]},e))}),(0,D.jsx)(`button`,{className:`btn btn-primary`,\"data-compact\":!0,style:{fontSize:11},onClick:Ke,children:`Add canvas`}),(0,D.jsxs)(`span`,{style:{fontSize:10,color:`var(--text-muted)`},children:[`Everything on screen `,He===`cut`?`cuts`:`slides off together`,`; the new canvas starts blank.`]})]}),S.handoff&&(0,D.jsxs)(`div`,{style:{display:`flex`,gap:8,alignItems:`center`,flexWrap:`wrap`,padding:`6px 8px`,border:`1px solid var(--border)`,borderRadius:8,background:`var(--bg-secondary)`},children:[(0,D.jsx)(`span`,{style:{fontSize:10.5,color:`var(--text-secondary)`},children:`Hand-off into this canvas:`}),(0,D.jsx)(`select`,{value:S.handoff.exit||`swipe-up`,style:{fontSize:10.5},onChange:e=>T.change({mode:`handoff`,options:{exit:e.target.value}}),children:On.map(e=>(0,D.jsx)(`option`,{value:e,children:e.replace(`-`,` `)},e))}),(0,D.jsx)(`select`,{value:S.handoff.arrive||`pop`,style:{fontSize:10.5},onChange:e=>T.change({mode:`handoff`,options:{arrive:e.target.value}}),children:kn.map(e=>(0,D.jsx)(`option`,{value:e,children:e===`fade`?`fade in`:e},e))}),(0,D.jsx)(`button`,{className:`btn btn-secondary`,\"data-compact\":!0,style:{fontSize:10},title:`Remove the hand-off — the canvases just cut`,onClick:()=>T.change({mode:`handoff`,options:null}),\"data-icon-action\":`true`,\"aria-label\":`Remove the hand-off — the canvases just cut`,children:(0,D.jsx)(k,{name:`trash`,size:18})})]}),le&&(0,D.jsxs)(`div`,{style:{display:`flex`,flexWrap:`wrap`,gap:8,padding:8,border:`1px solid var(--border)`,borderRadius:8,background:`var(--bg-secondary)`,maxHeight:240,overflowY:`auto`},children:[(0,D.jsx)(af,{name:`None`,active:!S.template,aspect:me/he,disabled:!i||!!A.pending||!!O.pending||!!E.pending,onPick:async()=>{await O.change(null)&&ue(!1)}},`none`),Qt.map(e=>(0,D.jsx)(af,{name:e.name,template:e,active:S.template===e.id&&S.mode!==`typewriter`,aspect:me/he,disabled:!i||!!A.pending||!!O.pending||!!E.pending,onPick:async()=>{await O.change(e.id)&&ue(!1)}},e.id)),(0,D.jsx)(of,{active:S.mode===`typewriter`,aspect:me/he,disabled:!i||!!A.pending||!!O.pending||!!E.pending,onPick:async()=>{if(!Re.length){oc.error?.(`This board has no voiceover to type — add a voiceover first.`);return}await A.change()&&ue(!1)}},`typewriter`)]})]}),(0,D.jsxs)(`div`,{style:{flex:1,minWidth:260,display:`flex`,flexDirection:`column`,gap:6},children:[(S.elements||[]).slice().sort((e,t)=>(e.appearMs||0)-(t.appearMs||0)).map(e=>(0,D.jsxs)(`div`,{style:{border:`1px solid ${ae===e.id?`var(--accent)`:`var(--border)`}`,borderRadius:8,padding:8,display:`flex`,flexDirection:`column`,gap:6,background:`var(--bg-secondary)`},onClick:()=>oe(e.id),children:[(0,D.jsxs)(`div`,{style:{display:`flex`,gap:6,alignItems:`center`,flexWrap:`wrap`},children:[e.kind===`image`&&e.src?(0,D.jsx)(`img`,{src:e.src,alt:``,style:{width:34,height:24,objectFit:`cover`,borderRadius:4}}):null,e.kind===`text`?(0,D.jsx)(rf,{value:e.text,placeholder:`Text…`,style:{fontWeight:700},onCommit:t=>Se(e.id,{text:t})}):(0,D.jsxs)(D.Fragment,{children:[(0,D.jsx)(`strong`,{style:{fontSize:11},children:e.query||e.kind}),(0,D.jsx)(`span`,{style:{flex:1}})]}),e.pinned&&S.autoArrange&&(0,D.jsx)(`span`,{style:{fontSize:9,border:`1px solid var(--border)`,borderRadius:999,padding:`0 6px`,color:`var(--text-secondary)`},children:`pinned`}),(0,D.jsx)(`button`,{className:`btn btn-secondary`,\"data-compact\":!0,style:{fontSize:10,padding:`1px 7px`},disabled:!i||!!w.current,onClick:t=>{t.stopPropagation(),j.change(e.id)},\"data-icon-action\":`true`,\"aria-label\":`Delete`,title:`Delete`,children:(0,D.jsx)(k,{name:`trash`,size:18})})]}),(0,D.jsxs)(`div`,{style:{display:`flex`,gap:8,alignItems:`center`,flexWrap:`wrap`},children:[(0,D.jsx)(nf,{label:`in`,value:e.appearMs,onCommit:t=>Se(e.id,{appearMs:Math.min(t,S.durationMs-100)})}),(0,D.jsx)(nf,{label:`out`,value:e.leaveMs??S.durationMs,onCommit:t=>Se(e.id,{leaveMs:t>=S.durationMs?null:Math.max(t,(e.appearMs||0)+100)})}),(0,D.jsxs)(`label`,{style:{display:`flex`,gap:4,alignItems:`center`,fontSize:10.5,color:`var(--text-secondary)`},children:[`size`,(0,D.jsx)(sc,{disabled:!i||!!w.current,type:`range`,min:e.kind===`image`?.1:.03,max:e.kind===`image`?.8:.16,step:`0.01`,value:e.size||.28,style:{width:70,accentColor:`var(--accent)`},onChange:t=>U(e.id,{size:Number(t.target.value)})})]}),(0,D.jsx)(`select`,{value:e.sfx||`auto`,style:{fontSize:10.5},onChange:t=>Se(e.id,{sfx:t.target.value}),children:[`auto`,`pop`,`swoosh`,`none`].map(e=>(0,D.jsxs)(`option`,{value:e,children:[`sfx: `,e]},e))})]}),e.kind===`image`||e.kind===`video`?(0,D.jsxs)(`div`,{style:{display:`flex`,gap:6,alignItems:`center`,flexWrap:`wrap`},children:[(0,D.jsx)(`select`,{value:e.entrance||`pop`,style:{fontSize:10.5},onChange:t=>Se(e.id,{entrance:t.target.value}),children:yt.map(e=>(0,D.jsxs)(`option`,{value:e,children:[`in: `,e]},e))}),e.source===`pose`&&a?.meta?.host?.poses?.length>0&&(0,D.jsx)(`select`,{value:e.pose||``,style:{fontSize:10.5},title:`Swap the presenter pose`,onChange:t=>{let n=a.meta.host.poses.find(e=>e.label===t.target.value);n&&Se(e.id,{src:n.url,pose:n.label,query:n.label,source:`pose`,cutout:!0})},children:a.meta.host.poses.map(e=>(0,D.jsxs)(`option`,{value:e.label,children:[`pose: `,String(e.label).replace(/-/g,` `)]},e.label))}),(0,D.jsx)(`button`,{className:`btn btn-secondary`,\"data-compact\":!0,style:{fontSize:10},onClick:t=>{t.stopPropagation(),qe(e.id,e.query,e.kind===`video`?`video`:`photo`)},children:e.src?`Swap (stock)`:`Find (stock)`}),e.kind===`image`?(0,D.jsxs)(D.Fragment,{children:[(0,D.jsx)(Bd,{label:`All Assets`,style:tf,onPick:t=>et(e.id,t)}),(0,D.jsx)(`button`,{className:`btn btn-secondary`,\"data-compact\":!0,style:{fontSize:10},onClick:t=>{t.stopPropagation(),K.current=e.id,Ze.current?.click()},children:e.src?`Upload`:`Upload local`}),(0,D.jsxs)(`button`,{className:`btn btn-secondary`,\"data-compact\":!0,style:{fontSize:10},onClick:t=>{t.stopPropagation(),nt(e)},children:[`Generate · `,y(`gpt-image-2`,1,{quality:`low`,resolution:`1K`}),` cr`]})]}):(0,D.jsxs)(D.Fragment,{children:[(0,D.jsx)(`button`,{className:`btn btn-secondary`,\"data-compact\":!0,style:{fontSize:10},onClick:t=>{t.stopPropagation(),K.current=e.id,Xe.current?.click()},children:`Upload clip`}),(0,D.jsxs)(`button`,{className:`btn btn-secondary`,\"data-compact\":!0,style:{fontSize:10},onClick:t=>{t.stopPropagation(),tt(e)},children:[`Generate · `,b(`wan-2.6-flash`,3),` cr`]})]}),(0,D.jsx)(rf,{value:e.query,onCommit:t=>Se(e.id,{query:t})}),e.kind===`image`&&(0,D.jsxs)(`label`,{style:{display:`flex`,gap:4,alignItems:`center`,fontSize:10.5,color:`var(--text-secondary)`},title:`Drop shadow depth — 0 turns it off, higher lifts the image off the background`,children:[`shadow`,(0,D.jsx)(sc,{disabled:!i||!!w.current,type:`range`,min:0,max:1,step:.05,value:e.shadow==null?.18:Number(e.shadow),style:{width:64,accentColor:`var(--accent)`},onChange:t=>U(e.id,{shadow:Number(t.target.value)})})]})]}):(0,D.jsxs)(`div`,{style:{display:`flex`,gap:6,alignItems:`center`,flexWrap:`wrap`},children:[(0,D.jsx)(`select`,{value:e.font||ef[0],style:{fontSize:10.5},onChange:t=>Se(e.id,{font:t.target.value}),children:ef.map(e=>(0,D.jsx)(`option`,{value:e,children:e},e))}),(0,D.jsx)(sc,{disabled:!i||!!w.current,type:`color`,value:e.color||`#111111`,onChange:t=>Se(e.id,{color:t.target.value})}),(0,D.jsx)(`select`,{value:e.anim?.type||`pop`,style:{fontSize:10.5},title:`How the text arrives — word-pop / sentence-build / typewriter / highlight time each word to the voiceover when the text came from it`,onChange:t=>Se(e.id,{anim:{...e.anim||{},type:t.target.value}}),children:[...Nt,...bt.filter(e=>!Nt.includes(e))].map(e=>(0,D.jsxs)(`option`,{value:e,children:[`arrive: `,e]},e))}),e.anim?.type===`sentence-build`&&(0,D.jsx)(`select`,{value:e.anim?.entrance||`pop`,style:{fontSize:10.5},onChange:t=>Se(e.id,{anim:{...e.anim||{},entrance:t.target.value}}),children:Pt.map(e=>(0,D.jsxs)(`option`,{value:e,children:[`word: `,e]},e))}),(e.anim?.type===`typewriter`||e.anim?.type===`pop-word`||e.anim?.type===`word-pop`||e.anim?.type===`sentence-build`)&&!e.wordTimes?.length&&(0,D.jsxs)(`label`,{style:{display:`flex`,gap:4,alignItems:`center`,fontSize:10.5,color:`var(--text-secondary)`},children:[`speed`,(0,D.jsx)(sc,{disabled:!i||!!w.current,type:`range`,min:20,max:400,step:10,value:e.anim?.speedMs||180,style:{width:60,accentColor:`var(--accent)`},onChange:t=>Se(e.id,{anim:{...e.anim||{},speedMs:Number(t.target.value)}})})]})]}),e.kind===`video`&&(0,D.jsxs)(`div`,{style:{display:`flex`,gap:8,alignItems:`center`,flexWrap:`wrap`},children:[(0,D.jsxs)(`select`,{value:e.loop===!1?`once`:`loop`,style:{fontSize:10.5},onChange:t=>Se(e.id,{loop:t.target.value===`loop`}),children:[(0,D.jsx)(`option`,{value:`loop`,children:`play: loop`}),(0,D.jsx)(`option`,{value:`once`,children:`play: once`})]}),(0,D.jsxs)(`label`,{style:{display:`flex`,gap:4,alignItems:`center`,fontSize:10.5,color:`var(--text-secondary)`},title:`Muted by default — the voiceover leads. Unmute to bring the clip's own audio onto the timeline.`,children:[(0,D.jsx)(`input`,{type:`checkbox`,checked:e.muted!==!1,onChange:t=>Se(e.id,{muted:t.target.checked})}),`muted`]}),(0,D.jsxs)(`label`,{style:{display:`flex`,gap:4,alignItems:`center`,fontSize:10.5,color:`var(--text-secondary)`},children:[`trim in`,(0,D.jsx)(sc,{disabled:!i||!!w.current,type:`number`,inputMode:`decimal`,step:`0.1`,min:`0`,value:Number(e.trimStartSec)||0,style:{width:52,fontSize:11},onChange:t=>Se(e.id,{trimStartSec:Math.max(0,Number(t.target.value)||0)})}),`s`]}),(0,D.jsxs)(`label`,{style:{display:`flex`,gap:4,alignItems:`center`,fontSize:10.5,color:`var(--text-secondary)`},children:[`speed`,(0,D.jsx)(sc,{disabled:!i||!!w.current,type:`range`,min:.5,max:2,step:.05,value:Number(e.speed)>0?Number(e.speed):1,style:{width:70,accentColor:`var(--accent)`},onChange:t=>Se(e.id,{speed:Number(t.target.value)})}),(0,D.jsxs)(`span`,{style:{fontVariantNumeric:`tabular-nums`,fontSize:10},children:[(Number(e.speed)>0?Number(e.speed):1).toFixed(2),`x`]})]})]}),(0,D.jsxs)(`div`,{style:{display:`flex`,gap:6,alignItems:`center`,flexWrap:`wrap`},children:[(0,D.jsx)(`select`,{value:e.motion?.type||`none`,style:{fontSize:10.5},title:`Keyframe motion — the editor's existing motion system, timed from this element's beat`,onChange:t=>{let n=t.target.value;Se(e.id,{motion:n===`none`?null:{...Ad(),...e.motion||{},type:n}})},children:kd.map(e=>(0,D.jsxs)(`option`,{value:e.value,children:[`motion: `,e.label]},e.value))}),e.motion?.type&&e.motion.type!==`none`&&(0,D.jsxs)(D.Fragment,{children:[(0,D.jsxs)(`label`,{style:{display:`flex`,gap:4,alignItems:`center`,fontSize:10.5,color:`var(--text-secondary)`},children:[`intensity`,(0,D.jsx)(sc,{disabled:!i||!!w.current,type:`range`,min:0,max:100,step:5,value:Number(e.motion.intensity)||60,style:{width:64,accentColor:`var(--accent)`},onChange:t=>Se(e.id,{motion:{...e.motion,intensity:Number(t.target.value)}})})]}),(0,D.jsx)(`select`,{value:e.motion.easing||`ease-in-out`,style:{fontSize:10.5},onChange:t=>Se(e.id,{motion:{...e.motion,easing:t.target.value}}),children:[`linear`,`ease-in`,`ease-out`,`ease-in-out`].map(e=>(0,D.jsx)(`option`,{value:e,children:e},e))}),(0,D.jsxs)(`label`,{style:{display:`flex`,gap:4,alignItems:`center`,fontSize:10.5,color:`var(--text-secondary)`},children:[(0,D.jsx)(`input`,{type:`checkbox`,checked:!!e.motion.loop,onChange:t=>Se(e.id,{motion:{...e.motion,loop:t.target.checked}})}),`loop`]})]})]}),ae===e.id&&(0,D.jsxs)(`div`,{style:{borderTop:`1px dashed var(--border)`,paddingTop:6,display:`flex`,flexDirection:`column`,gap:5},children:[(0,D.jsxs)(`div`,{style:{display:`flex`,gap:6,alignItems:`center`,flexWrap:`wrap`},children:[(0,D.jsx)(`span`,{style:{fontSize:10,color:`var(--text-secondary)`,fontWeight:600},title:`Relocate this element over time — it eases to a new spot at the playhead and stays on screen. Chain moves to park one focus aside and bring the next in.`,children:`path`}),(0,D.jsxs)(`button`,{className:`btn btn-secondary`,\"data-compact\":!0,style:{fontSize:10},disabled:!i||!!E.pending,title:`Add a move keyframe at the playhead — then drag the element on the canvas to set where it travels to`,onClick:t=>{t.stopPropagation();let n=Math.max(Math.round(F),Math.round(e.appearMs||0)),r=Vt(e,n);E.change(e.id,`set`,n,{pos:r.pos,...r.size==null?{}:{size:r.size}})},children:[`+ Move at `,(Math.max(F,e.appearMs||0)/1e3).toFixed(1),`s`]}),(0,D.jsx)(`button`,{className:`btn btn-secondary`,\"data-compact\":!0,style:{fontSize:10},disabled:!i||!!E.pending,title:`Slide this element toward the left edge and shrink it — out of the way, still on screen`,onClick:t=>{t.stopPropagation();let n=Math.max(Math.round(F),Math.round(e.appearMs||0)),r=Vt(e,n),i=r.size==null?e.size:r.size;E.change(e.id,`set`,n,{pos:{x:.16,y:r.pos.y},...i==null?{}:{size:i*.72}})},children:`Park left`}),(0,D.jsx)(`button`,{className:`btn btn-secondary`,\"data-compact\":!0,style:{fontSize:10},disabled:!i||!!E.pending,title:`Slide this element toward the right edge and shrink it — out of the way, still on screen`,onClick:t=>{t.stopPropagation();let n=Math.max(Math.round(F),Math.round(e.appearMs||0)),r=Vt(e,n),i=r.size==null?e.size:r.size;E.change(e.id,`set`,n,{pos:{x:.84,y:r.pos.y},...i==null?{}:{size:i*.72}})},children:`Park right`})]}),Array.isArray(e.moves)&&e.moves.length>0&&(0,D.jsx)(`div`,{style:{display:`flex`,flexWrap:`wrap`,gap:5},children:e.moves.slice().sort((e,t)=>(e.atMs||0)-(t.atMs||0)).map((t,n)=>(0,D.jsxs)(`span`,{style:{display:`inline-flex`,gap:5,alignItems:`center`,fontSize:10,border:`1px solid var(--border)`,borderRadius:999,padding:`1px 3px 1px 8px`,color:`var(--text-secondary)`},title:`Eases to (${(t.pos?.x??.5).toFixed(2)}, ${(t.pos?.y??.5).toFixed(2)})${t.size==null?``:` · size `+Number(t.size).toFixed(2)}`,children:[(Number(t.atMs||0)/1e3).toFixed(1),`s`,(0,D.jsx)(`button`,{className:`btn btn-secondary`,\"data-compact\":!0,style:{fontSize:9,padding:`0 5px`,lineHeight:1.6},disabled:!i||!!E.pending,title:`Delete this move`,onClick:t=>{t.stopPropagation(),E.change(e.id,`remove`,0,{},n)},\"data-icon-action\":`true`,\"aria-label\":`Delete this move`,children:(0,D.jsx)(k,{name:`x`,size:18})})]},n))})]})]},e.id)),(S.elements||[]).length===0&&(0,D.jsxs)(`div`,{style:{fontSize:11.5,color:`var(--text-secondary)`,border:`1px dashed var(--border)`,borderRadius:8,padding:12},children:[`Empty `,u===`page`?`board`:`canvas`,` — add images and text with the buttons below, or `,u===`page`?`use \"Build from my assets\" above to hand it your images/videos and let it draft the boards.`:`use Auto-build on the image panel card to let the system draft it from the narration.`]})]}),se.open&&(0,D.jsx)(`div`,{style:{position:`fixed`,inset:0,zIndex:1001,background:`rgba(0,0,0,0.5)`,display:`flex`,alignItems:`center`,justifyContent:`center`},onClick:()=>ce(e=>({...e,open:!1})),children:(0,D.jsxs)(`div`,{style:{background:`var(--bg-primary)`,border:`1px solid var(--border)`,borderRadius:12,padding:12,width:`min(720px, 92vw)`,maxHeight:`80vh`,overflow:`auto`},onClick:e=>e.stopPropagation(),children:[(0,D.jsxs)(`div`,{style:{display:`flex`,gap:6,alignItems:`center`,marginBottom:6,flexWrap:`wrap`},children:[(0,D.jsxs)(`strong`,{style:{fontSize:12},children:[`Stock `,se.mediaType===`video`?`video`:`photos`]}),(0,D.jsx)(rf,{value:se.query,onCommit:e=>Je(e)}),(0,D.jsx)(`button`,{className:`btn btn-primary`,\"data-compact\":!0,style:{fontSize:11},disabled:se.busy,onClick:()=>Je(se.query),children:se.busy?`Searching…`:`Search`})]}),(0,D.jsx)(`div`,{style:{fontSize:10.5,color:`var(--text-secondary)`,marginBottom:8},children:`Tap one to use it — 1 credit on first pull, then free.`}),se.configured===!1&&(0,D.jsx)(`div`,{style:{fontSize:11.5,color:`var(--text-secondary)`},children:`Stock media is not configured on this server — use Generate instead, or add provider keys.`}),(0,D.jsx)(`div`,{style:{display:`grid`,gridTemplateColumns:`repeat(auto-fill, minmax(120px, 1fr))`,gap:8},children:se.results.map((e,t)=>(0,D.jsx)(`img`,{src:e.thumb||e.previewUrl||e.url,alt:e.title||`stock`,title:`${e.source||`stock`} — click to use (1 cr on first pulls)`,style:{width:`100%`,borderRadius:6,cursor:`pointer`,display:`block`},onClick:()=>Ye(e)},e.id||t))})]})})]})}function xf(e){return(0,Qo.createPortal)((0,D.jsx)(`div`,{style:{position:`fixed`,inset:0,zIndex:1e3,background:`rgba(0,0,0,0.55)`,display:`flex`,alignItems:`center`,justifyContent:`center`},onClick:e.onClose,children:(0,D.jsx)(bf,{...e,variant:`modal`})}),document.body)}let Sf=(0,v.lazy)(()=>Promise.resolve().then(()=>(Sc(),yc)));function Cf({value:e,onCommit:t,saveRef:n,disabled:r}){let[i,a]=(0,v.useState)(e||``),o=(0,v.useRef)(i);(0,v.useEffect)(()=>{o.current=i},[i]),(0,v.useEffect)(()=>{a(e||``),o.current=e||``},[e]);let s=(0,v.useRef)(null),c=()=>{if(s.current)return s.current;if(r)return Promise.resolve(!1);if((o.current||``)===(e||``))return Promise.resolve(!0);let n=o.current||``,i=Promise.resolve().then(()=>t(n)).then(e=>e!==!1&&e!==null);return s.current=i,i.finally(()=>{s.current===i&&(s.current=null)}).catch(()=>{}),i};return(0,v.useEffect)(()=>(n&&(n.current=c),()=>{n&&(n.current=null)})),(0,D.jsx)(`textarea`,{value:i,disabled:r,onChange:e=>a(e.target.value),onBlur:c,onKeyDown:e=>{(e.metaKey||e.ctrlKey)&&e.key===`Enter`&&e.currentTarget.blur()},spellCheck:!1,style:Ef.promptEdit,rows:8})}function wf({open:e,onClose:t,title:n,model:r,settings:i,prompt:a,negativePrompt:o,refs:s=[],editable:c=!1,onRemoveRef:l,onAddRefImage:u,onPromptChange:d=null,onResetPrompt:f=null,promptOverridden:p=!1,disabled:m=!1}){let h=(0,v.useRef)(null),g=(0,v.useRef)(!1),[_,y]=(0,v.useState)(!1),[b,x]=(0,v.useState)(null),S=(0,v.useRef)(null),[C,w]=(0,v.useState)(!1),T=(0,v.useRef)({open:e,title:n}),E=(0,v.useRef)(!0);T.current={open:e,title:n},(0,v.useEffect)(()=>(E.current=!0,()=>{E.current=!1}),[]);let O=async()=>{let e=T.current;if(!m)try{if(await S.current?.()===!1||!E.current||!T.current.open||T.current.title!==e.title)return;w(!0),setTimeout(()=>{E.current&&w(!1)},1400)}catch{}},A=!m&&c&&(l||u);if(!e)return null;let j=e=>e.startsWith(`Character`)?`Characters`:e.startsWith(`Location`)?`Locations`:e,M={};s.forEach(e=>{let t=j(e.source);M[t]=(M[t]||0)+1});let ee=s.map(e=>({url:nc(e.url),name:e.source})),N=async e=>{if(!l)return;let t=e.kind===`attached`?`Remove this added image? It will be detached from this shot.`:`Remove \"${e.source}\" from this generation? It won't be sent as a reference next time this panel generates. Use \"Restore original\" to bring it back.`;await ac.confirm(t,{danger:!0,confirmText:`Remove`})&&l(e)},P=async()=>{if(g.current)return!0;let e=await ac.confirm(`Heads up: an image you add here attaches to THIS shot only. It won't appear as a node on the canvas — it shows up just here (and in Video Assets / on mobile). Add it anyway?`,{confirmText:`Got it, add`});return e&&(g.current=!0),e},te=e=>e.filter(Boolean).forEach(e=>u?.(e)),ne=async e=>{await P()&&te((Array.isArray(e)?e:[e]).map(e=>e?.url))},re=async e=>{let t=e.target.files?.[0];if(e.target.value=``,t&&await P()){y(!0);try{let e=await new Promise((e,n)=>{let r=new FileReader;r.onload=()=>e(r.result),r.onerror=n,r.readAsDataURL(t)}),n=await Qs(e);n&&u?.(n)}catch(e){ac.alert(`Could not add that image: ${e?.message||e}`)}finally{y(!1)}}};return(0,D.jsxs)(D.Fragment,{children:[(0,Qo.createPortal)((0,D.jsx)(`div`,{style:Ef.backdrop,onMouseDown:t,children:(0,D.jsxs)(`div`,{style:Ef.panel,onMouseDown:e=>e.stopPropagation(),children:[(0,D.jsxs)(`div`,{style:Ef.head,children:[(0,D.jsxs)(`span`,{style:Ef.headTitle,children:[`What gets sent · `,n]}),(0,D.jsx)(`button`,{style:Ef.close,onClick:t,\"aria-label\":`Close`,\"data-icon-action\":`true`,title:`Close`,children:(0,D.jsx)(k,{name:`x`,size:18})})]}),(0,D.jsxs)(`div`,{style:Ef.body,children:[(r||i)&&(0,D.jsx)(`div`,{style:Ef.meta,children:[r,i].filter(Boolean).join(` · `)}),(0,D.jsxs)(`div`,{style:{...Ef.label,display:`flex`,alignItems:`center`,gap:8},children:[(0,D.jsxs)(`span`,{children:[`Prompt`,d&&a?` · editable — this exact text is what gets sent`:``]}),(0,D.jsx)(`span`,{style:{flex:1}}),d&&a!=null&&(0,D.jsx)(`button`,{type:`button`,style:{...Ef.resetBtn,...C?{color:`#8fe17d`,borderColor:`rgba(143,225,125,0.5)`}:{}},disabled:m,onClick:O,title:`Commit the current prompt (and any ref changes are already committed) — the next generation uses exactly what's here`,children:C?`Saved ✓`:`Save`}),d&&p&&f&&(0,D.jsx)(`button`,{type:`button`,style:Ef.resetBtn,disabled:m,onClick:f,title:`Discard your edits — restore the ORIGINAL system-generated prompt and reference images for this panel`,children:`Restore original`})]}),d&&a!=null?(0,D.jsx)(Cf,{disabled:m,value:a,onCommit:d,saveRef:S}):(0,D.jsx)(`div`,{style:Ef.prompt,children:a||(0,D.jsx)(`em`,{style:Ef.muted,children:`none`})}),o?(0,D.jsxs)(D.Fragment,{children:[(0,D.jsx)(`div`,{style:Ef.label,children:`Negative prompt`}),(0,D.jsx)(`div`,{style:Ef.prompt,children:o})]}):null,(0,D.jsxs)(`div`,{style:Ef.label,children:[`Reference images · `,s.length]}),s.length===0?(0,D.jsx)(`div`,{style:Ef.muted,children:`None — this generates from the prompt only (no style or character/location conditioning).`}):(0,D.jsxs)(D.Fragment,{children:[(0,D.jsx)(`div`,{style:Ef.summary,children:Object.entries(M).map(([e,t])=>(0,D.jsxs)(`span`,{style:Ef.countChip,children:[e,` ×`,t]},e))}),(0,D.jsx)(`div`,{style:Ef.grid,children:s.map((e,t)=>(0,D.jsxs)(`div`,{style:Ef.cell,children:[(0,D.jsxs)(`div`,{style:Ef.thumbWrap,className:`sm-expand-host`,children:[(0,D.jsx)(`img`,{src:nc(e.url),alt:``,loading:`lazy`,decoding:`async`,style:Ef.thumb,onClick:()=>x(e.url),title:`Click to view full size`}),(0,D.jsx)(Oc,{items:ee,index:t,onOpen:()=>x(e.url)}),A&&l&&e.removable!==!1&&(0,D.jsx)(`button`,{style:Ef.del,onClick:t=>{t.stopPropagation(),N(e)},title:`Remove from this shot`,\"aria-label\":`Remove`,\"data-icon-action\":`true`,children:(0,D.jsx)(k,{name:`x`,size:18})})]}),(0,D.jsx)(`span`,{style:Ef.cellLabel,title:e.source,children:e.source})]},t))})]}),A&&u&&(0,D.jsxs)(`div`,{style:Ef.addBox,children:[(0,D.jsxs)(`div`,{style:Ef.addRow,children:[(0,D.jsx)(`button`,{type:`button`,style:Ef.addBtn,disabled:_,onClick:()=>h.current?.click(),children:_?`Uploading…`:`+ Upload image`}),(0,D.jsx)(Bd,{multi:!0,label:`+ All Assets`,style:Ef.addBtn,onPick:ne}),(0,D.jsx)(`input`,{ref:h,type:`file`,accept:`image/*`,onChange:re,style:{display:`none`}})]}),(0,D.jsx)(`div`,{style:Ef.addNote,children:`Added images attach to this shot only — they won't appear on the canvas, just here and in Video Assets.`})]})]})]})}),document.body),b&&(0,D.jsx)(v.Suspense,{fallback:null,children:(0,D.jsx)(Sf,{items:ee,index:Math.max(0,s.findIndex(e=>e.url===b)),onClose:()=>x(null)})})]})}let Tf=`247,240,219`,Ef={backdrop:{position:`fixed`,inset:0,background:`rgba(0,0,0,0.6)`,zIndex:1e5,display:`flex`,alignItems:`center`,justifyContent:`center`,padding:20},panel:{width:`min(560px, 94vw)`,maxHeight:`86vh`,display:`flex`,flexDirection:`column`,background:`#201f1c`,color:`rgb(${Tf})`,border:`1px solid rgba(${Tf},0.18)`,borderRadius:12,overflow:`hidden`,boxShadow:`0 20px 60px rgba(0,0,0,0.5)`},head:{display:`flex`,alignItems:`center`,justifyContent:`space-between`,padding:`12px 14px`,borderBottom:`1px solid rgba(${Tf},0.14)`},headTitle:{fontSize:13,fontWeight:700,letterSpacing:.2,color:`rgb(${Tf})`},close:{background:`none`,border:`none`,color:`rgb(${Tf})`,fontSize:15,cursor:`pointer`,lineHeight:1,padding:4},body:{padding:14,overflowY:`auto`},meta:{fontSize:11,color:`rgba(${Tf},0.7)`,marginBottom:12},label:{fontSize:10,fontWeight:700,textTransform:`uppercase`,letterSpacing:.6,color:`rgba(${Tf},0.85)`,margin:`12px 0 5px`},prompt:{fontSize:12,lineHeight:1.5,whiteSpace:`pre-wrap`,color:`rgb(${Tf})`,background:`rgba(${Tf},0.07)`,border:`1px solid rgba(${Tf},0.14)`,borderRadius:8,padding:`8px 10px`,maxHeight:160,overflowY:`auto`},promptEdit:{width:`100%`,boxSizing:`border-box`,fontSize:12,lineHeight:1.5,color:`rgb(${Tf})`,background:`rgba(${Tf},0.07)`,border:`1px solid rgba(${Tf},0.28)`,borderRadius:8,padding:`8px 10px`,resize:`vertical`,fontFamily:`inherit`,outline:`none`},resetBtn:{fontSize:10,fontWeight:600,color:`rgb(${Tf})`,background:`rgba(${Tf},0.1)`,border:`1px solid rgba(${Tf},0.24)`,borderRadius:6,padding:`2px 8px`,cursor:`pointer`},muted:{fontSize:12,color:`rgba(${Tf},0.6)`},summary:{display:`flex`,flexWrap:`wrap`,gap:6,marginBottom:10},countChip:{fontSize:11,fontWeight:600,color:`rgb(${Tf})`,padding:`2px 8px`,borderRadius:999,background:`rgba(${Tf},0.12)`,border:`1px solid rgba(${Tf},0.18)`},grid:{display:`grid`,gridTemplateColumns:`repeat(auto-fill, minmax(96px, 1fr))`,gap:8},cell:{display:`flex`,flexDirection:`column`,gap:4},thumbWrap:{position:`relative`},thumb:{width:`100%`,aspectRatio:`1`,objectFit:`cover`,borderRadius:6,background:`rgba(${Tf},0.06)`,border:`1px solid rgba(${Tf},0.12)`,display:`block`,cursor:`zoom-in`},del:{position:`absolute`,top:3,right:3,width:22,height:22,borderRadius:6,background:`rgba(20,18,16,0.78)`,color:`#fff`,border:`1px solid rgba(255,255,255,0.25)`,fontSize:11,lineHeight:1,cursor:`pointer`,display:`flex`,alignItems:`center`,justifyContent:`center`},cellLabel:{fontSize:9.5,color:`rgba(${Tf},0.72)`,whiteSpace:`nowrap`,overflow:`hidden`,textOverflow:`ellipsis`},addBox:{marginTop:14,paddingTop:12,borderTop:`1px solid rgba(${Tf},0.14)`},addRow:{display:`flex`,flexWrap:`wrap`,gap:8},addBtn:{fontSize:11.5,fontWeight:600,color:`rgb(${Tf})`,padding:`7px 12px`,borderRadius:8,cursor:`pointer`,background:`rgba(${Tf},0.1)`,border:`1px solid rgba(${Tf},0.22)`},addNote:{fontSize:10.5,lineHeight:1.45,color:`rgba(${Tf},0.6)`,marginTop:7}};function Df(e){return I(e?.version===1&&[`prepareUpload`,`analyze`,`generate`].every(t=>typeof e[t]==`function`),`HOST_SERVICES`,`Style creation requires version 1 of the trusted authoring service.`),e}function Of(e){let t=(0,v.useRef)(!1);return{onMouseDown:e=>{t.current=e.target===e.currentTarget},onMouseUp:n=>{t.current&&n.target===n.currentTarget&&e?.(n),t.current=!1}}}function kf(e){return I(e?.version===1&&Array.isArray(e.imageModels)&&e.imageModels.length>0&&e.imageModels.every(e=>L(e)&&typeof e.value==`string`&&typeof e.label==`string`&&L(e.supports)&&Object.values(e.supports).every(e=>Array.isArray(e)&&e.every(e=>typeof e==`string`)))&&L(e.creditCosts)&&Object.values(e.creditCosts).every(e=>Number.isFinite(e)&&e>=0)&&[`imageCost`,`videoCost`,`formatCostLabel`].every(t=>typeof e[t]==`function`),`HOST_SERVICES`,`Generation choices require version 1 of the display catalog service.`),e}let Af=e=>new Promise((t,n)=>{let r=new FileReader;r.onload=()=>t(r.result),r.onerror=()=>n(Error(`could not read the file`)),r.readAsDataURL(e)});function jf({styleAuthoringHost:e,generationCatalogHost:t,styleLibraryHost:n,actor:r,onClose:i,onCreated:a,aspect:o=`1:1`}){let{prepareUpload:s,analyze:c,generate:l}=Df(e),{imageModels:u,imageCost:d,formatCostLabel:f}=kf(t),{save:p}=jl(n),[m,h]=(0,v.useState)([]),[g,_]=(0,v.useState)(``),[y,b]=(0,v.useState)(``),[x,S]=(0,v.useState)(``),[C,w]=(0,v.useState)(()=>u.some(e=>e.value===`gpt-image-2.5-sunburst`)?`gpt-image-2.5-sunburst`:u[0].value),[T,E]=(0,v.useState)(`medium`),[O,A]=(0,v.useState)(`1K`),j=(0,v.useRef)(null),M=Of(()=>{x||i()}),ee=u.find(e=>e.value===C)?.supports||{},N=e=>({value:e,label:e===`low`?`Low`:e===`medium`?`Medium`:e===`high`?`High`:e}),P=(ee.quality||[]).map(N),te=(ee.resolution||[]).map(N),ne=async e=>{let t=Array.from(e||[]).filter(Boolean).slice(0,10-m.length);if(t.length){S(`uploading`);try{let e=[];for(let n of t){let t=await Af(n),i=await s(t,{actor:r});i.url&&e.push(i)}h(t=>[...t,...e].slice(0,10))}catch(e){X.error?.(e?.message||`Upload failed`)}finally{S(``),j.current&&(j.current.value=``)}}},re=async()=>{let e=y.trim()||g.trim();if(!e){X.error?.(`Add a style prompt (or a name) to generate a sample`);return}if(m.length>=10){X.error?.(`Up to 10 images`);return}S(`generating`);try{let t=await l({model:C,readablePrompt:e,aspectRatio:o,quality:T,resolution:O},{actor:r});t&&h(e=>[...e,{thumb:t,url:t}].slice(0,10))}catch(e){X.error?.(e?.message||`Generation failed`)}finally{S(``)}},F=async()=>{if(m.length){S(`analyzing`);try{let e=await c(m.map(e=>e.url),{actor:r});b(e||``)}catch(e){X.error?.(e?.message||`Analyze failed`)}finally{S(``)}}},I=async()=>{if(!m.length){X.error?.(`Add at least one reference image`);return}S(`saving`);try{let e=m.map(e=>e.url),t=p({name:g.trim()||`My style`,stylePrompt:y.trim(),description:`Created from reference images`,images:e.map(e=>({url:e})),previewUrl:e[0],selectedImageUrl:e[0]},{actor:r});a?.({name:t.name,stylePrompt:t.stylePrompt||null,styleRefs:e}),i()}catch(e){X.error?.(e?.message||`Save failed`),S(``)}},L=d(C);return(0,D.jsxs)(D.Fragment,{children:[(0,D.jsx)(`div`,{style:Mf.backdrop,...M}),(0,D.jsxs)(`div`,{style:Mf.panel,role:`dialog`,\"aria-label\":`Create style`,children:[(0,D.jsxs)(`div`,{style:Mf.header,children:[(0,D.jsx)(`div`,{style:{fontWeight:700,fontSize:15,color:`var(--text-primary)`},children:`Create style`}),(0,D.jsx)(`button`,{className:`btn btn-secondary`,\"data-compact\":!0,disabled:!!x,onClick:i,style:{fontSize:12},\"data-icon-action\":`true`,\"aria-label\":`Close`,title:`Close`,children:(0,D.jsx)(k,{name:`x`,size:18})})]}),(0,D.jsxs)(`div`,{style:Mf.body,children:[(0,D.jsx)(`p`,{style:{fontSize:13,color:`var(--text-secondary)`,margin:0,lineHeight:1.6},children:`Upload up to 10 reference images, or generate sample images from a style prompt. They become this style's reference set.`}),(0,D.jsxs)(`div`,{style:{display:`flex`,gap:6,alignItems:`center`,flexWrap:`wrap`},children:[(0,D.jsx)(`span`,{style:Mf.fieldLabel,children:`Images`}),(0,D.jsx)(`div`,{style:{flex:1}}),(0,D.jsx)(ns,{value:C,onChange:e=>w(e.target.value),disabled:!!x,style:{fontSize:11},children:u.map(e=>(0,D.jsx)(`option`,{value:e.value,children:e.label},e.value))}),P.length>0&&(0,D.jsx)(ns,{value:T,onChange:e=>E(e.target.value),disabled:!!x,style:{fontSize:11},children:P.map(e=>(0,D.jsx)(`option`,{value:e.value,children:e.label},e.value))}),te.length>1&&(0,D.jsx)(ns,{value:O,onChange:e=>A(e.target.value),disabled:!!x,style:{fontSize:11},children:te.map(e=>(0,D.jsx)(`option`,{value:e.value,children:e.label},e.value))}),(0,D.jsx)(`button`,{className:`btn btn-secondary`,\"data-compact\":!0,disabled:!!x||m.length>=10,onClick:re,style:{fontSize:11,padding:`3px 10px`},children:x===`generating`?`Generating…`:`Generate sample ${f(L)}`}),(0,D.jsx)(`button`,{className:`btn btn-secondary`,\"data-compact\":!0,disabled:!!x||m.length>=10,onClick:()=>j.current?.click(),style:{fontSize:11,padding:`3px 10px`},children:x===`uploading`?`Uploading…`:`↑ Upload`}),(0,D.jsx)(`input`,{ref:j,type:`file`,accept:`image/*`,multiple:!0,style:{display:`none`},onChange:e=>ne(e.target.files)})]}),(0,D.jsx)(`div`,{style:Mf.uploadZone,onClick:()=>!x&&m.length<10&&j.current?.click(),children:m.length===0?(0,D.jsx)(`div`,{style:{display:`flex`,flexDirection:`column`,alignItems:`center`,gap:6,color:`var(--text-secondary)`,fontSize:13},children:`No images yet — upload files or generate some above.`}):(0,D.jsxs)(`div`,{style:{display:`flex`,flexWrap:`wrap`,gap:8},children:[m.map((e,t)=>(0,D.jsxs)(`div`,{style:{position:`relative`},children:[(0,D.jsx)(`img`,{src:e.thumb,alt:`ref ${t+1}`,style:{width:68,height:68,objectFit:`cover`,borderRadius:6,display:`block`}}),(0,D.jsx)(`button`,{\"aria-label\":`remove`,onClick:e=>{e.stopPropagation(),h(e=>e.filter((e,n)=>n!==t))},style:Mf.removeBtn,\"data-icon-action\":`true`,title:`remove`,children:(0,D.jsx)(k,{name:`x`,size:18})})]},e.url+t)),m.length<10&&(0,D.jsx)(`div`,{style:Mf.addMore,children:x===`uploading`||x===`generating`?`…`:`+ Add`})]})}),(0,D.jsxs)(`label`,{style:{display:`flex`,flexDirection:`column`,gap:4},children:[(0,D.jsx)(`span`,{style:Mf.fieldLabel,children:`Name`}),(0,D.jsx)(`input`,{value:g,onChange:e=>_(e.target.value),placeholder:`My style`,disabled:!!x,style:Mf.input})]}),(0,D.jsxs)(`div`,{style:{display:`flex`,flexDirection:`column`,gap:4},children:[(0,D.jsxs)(`div`,{style:{display:`flex`,alignItems:`center`,gap:8},children:[(0,D.jsxs)(`span`,{style:Mf.fieldLabel,children:[`Style prompt `,(0,D.jsx)(`span`,{style:{textTransform:`none`,fontWeight:400,opacity:.7},children:`(optional)`})]}),(0,D.jsx)(`div`,{style:{flex:1}}),(0,D.jsx)(`button`,{className:`btn btn-secondary`,\"data-compact\":!0,disabled:!m.length||!!x,onClick:F,style:{fontSize:11,padding:`2px 8px`},children:x===`analyzing`?`Analysing…`:y?`Re-analyse images`:`Analyse images`})]}),(0,D.jsx)(`textarea`,{value:y,onChange:e=>b(e.target.value),rows:4,disabled:!!x,placeholder:`Extract the visual language from your images, generate a sample from it, or write your own.`,style:Mf.textarea})]})]}),(0,D.jsxs)(`div`,{style:Mf.footer,children:[(0,D.jsx)(`button`,{className:`btn btn-secondary`,disabled:!!x,onClick:i,children:`Cancel`}),(0,D.jsx)(`button`,{className:`btn btn-primary`,disabled:!m.length||!!x,onClick:I,children:x===`saving`?`Saving…`:`Save & apply style`})]})]})]})}let Mf={backdrop:{position:`fixed`,inset:0,zIndex:200,background:`rgba(0,0,0,0.6)`},panel:{position:`fixed`,top:`50%`,left:`50%`,transform:`translate(-50%,-50%)`,zIndex:201,width:580,maxWidth:`calc(100vw - 40px)`,maxHeight:`calc(100vh - 60px)`,display:`flex`,flexDirection:`column`,background:`var(--bg-elevated)`,border:`1px solid var(--border-light)`,borderRadius:12,boxShadow:`var(--shadow-lg)`,overflow:`hidden`},header:{display:`flex`,alignItems:`center`,justifyContent:`space-between`,padding:`14px 18px`,borderBottom:`1px solid var(--border)`},body:{flex:1,overflowY:`auto`,padding:18,display:`flex`,flexDirection:`column`,gap:14},uploadZone:{border:`2px dashed var(--border)`,borderRadius:8,padding:16,cursor:`pointer`,minHeight:96,display:`flex`,alignItems:`center`,justifyContent:`center`},addMore:{width:68,height:68,border:`2px dashed var(--border)`,borderRadius:6,display:`flex`,alignItems:`center`,justifyContent:`center`,fontSize:11,color:`var(--text-secondary)`},removeBtn:{position:`absolute`,top:-6,right:-6,width:18,height:18,borderRadius:`50%`,border:`none`,background:`var(--bg-elevated)`,color:`var(--text-primary)`,boxShadow:`var(--shadow-sm)`,cursor:`pointer`,fontSize:12,lineHeight:`16px`,padding:0},fieldLabel:{fontSize:10,fontWeight:700,textTransform:`uppercase`,letterSpacing:`0.05em`,color:`var(--text-secondary)`},input:{background:`var(--bg-tertiary)`,border:`1px solid var(--border)`,borderRadius:6,color:`var(--text-primary)`,fontSize:13,padding:`7px 10px`,fontFamily:`var(--font)`},textarea:{background:`var(--bg-tertiary)`,border:`1px solid var(--border)`,borderRadius:6,color:`var(--text-primary)`,fontSize:12,lineHeight:1.6,padding:`9px 11px`,resize:`vertical`,fontFamily:`var(--font)`,width:`100%`,boxSizing:`border-box`},footer:{display:`flex`,justifyContent:`flex-end`,gap:8,padding:`12px 18px`,borderTop:`1px solid var(--border)`}};function Nf(e){return I(e?.version===1&&typeof e.openCanvas==`function`,`HOST_SERVICES`,`Image Panels requires version 1 of its account access service.`),e}let Pf=new Set([`nano-banana-2`,`nano-banana-2-lite`,`nano-banana-pro`,`gpt-image-2`,`gpt-image-2.5-flare`,`gpt-image-2.5-sunburst`]);function Ff(e){let{imageModels:t,imageCost:n}=kf(e),r=t.filter(e=>Pf.has(e.value));function i(){let e=null;for(let t of r){let r=t.supports||{};for(let i of r.quality?.length?r.quality:[`low`])for(let a of r.resolution?.length?r.resolution:[`1K`]){let r=n(t.value,1,{quality:i,resolution:a});(!e||r<e.cost)&&(e={model:t.value,quality:i,resolution:a,cost:r})}}return e}function a({model:e,quality:t,resolution:n}={}){let a=r.find(t=>t.value===e);if(!a)return i();let o=a.supports||{},s=o.quality?.length?o.quality:[`low`],c=o.resolution?.length?o.resolution:[`1K`];return{model:e,quality:s.includes(t)?t:s[0],resolution:c.includes(n)?n:c[0]}}return Object.freeze({PANEL_MODEL_OPTIONS:r,lowestPanelGen:i,panelGenFromDefaults:a})}function If(e){return I(e?.version===1&&[`defaultImageModel`,`read`,`write`].every(t=>typeof e[t]==`function`),`HOST_SERVICES`,`Image Panels requires version 1 of its saved generation preferences.`),e}let Lf=new Set(Rr.flatMap(e=>e.builtin&&e.refs||[]));function Rf(e){return(e?.strip||[]).some(e=>e?.type===`giphy`||e?.overlayLayer&&typeof e.overlayLayer==`object`)}function zf({value:e,onCommit:t,disabled:n}){let[r,i]=(0,v.useState)(e);return(0,D.jsx)(`textarea`,{value:r,disabled:n,onChange:e=>i(e.target.value),onBlur:()=>{r.trim()&&r!==e&&t(r.trim())},rows:3,style:{width:`100%`,boxSizing:`border-box`,background:`var(--bg-primary)`,color:`var(--text-primary)`,border:`1px solid var(--border)`,borderRadius:7,padding:`7px 9px`,fontSize:12,resize:`vertical`,fontFamily:`inherit`,lineHeight:1.45}})}function Bf({value:e,onCommit:t,disabled:n}){let[r,i]=(0,v.useState)(e||``),a=v.useRef({value:e,onCommit:t});return a.current={value:e,onCommit:t},(0,v.useEffect)(()=>i(e||``),[e]),(0,D.jsx)(`textarea`,{value:r,disabled:n,onChange:e=>i(e.target.value),onBlur:async()=>{let n=r.trim();n&&n!==(e||``)&&(await t(n)||i(a.current.value||``))},rows:3,onKeyDown:e=>{e.key===`Escape`&&(e.preventDefault(),i(a.current.value||``))},style:{width:`100%`,boxSizing:`border-box`,background:`var(--bg-primary)`,color:`var(--text-primary)`,border:`1px solid var(--border)`,borderRadius:7,padding:`7px 9px`,fontSize:12,resize:`vertical`,fontFamily:`inherit`,lineHeight:1.45}})}function Vf({value:e,onCommit:t,disabled:n}){let[r,i]=(0,v.useState)(e);return(0,D.jsxs)(`div`,{style:{display:`flex`,alignItems:`baseline`,gap:6,background:`var(--bg-primary)`,border:`1px solid var(--border)`,borderRadius:7,padding:`6px 9px`},title:`Edit the narration text for this panel. Transcript only — the recorded voiceover audio doesn't change.`,children:[(0,D.jsx)(`span`,{style:{fontSize:10,fontWeight:700,textTransform:`uppercase`,letterSpacing:`0.05em`,color:`var(--text-secondary)`},children:`Says`}),(0,D.jsx)(`textarea`,{value:r,rows:1,disabled:n,onChange:e=>i(e.target.value),onBlur:()=>{let n=r.trim();n&&n!==e?t(n):i(e)},placeholder:`add narration text…`,style:{flex:1,minWidth:0,background:`transparent`,color:`var(--text-primary)`,border:`none`,outline:`none`,resize:`none`,fontFamily:`inherit`,fontSize:12.5,fontStyle:`italic`,lineHeight:1.4,padding:0,fieldSizing:`content`}})]})}function Hf({policy:e,imageCost:t,panelId:n,value:r,isOverridden:i,onApply:a,onClose:o,title:s=null,applyLabel:c=null}){let{PANEL_MODEL_OPTIONS:l}=e,[u,d]=(0,v.useState)(r.model),[f,p]=(0,v.useState)(r.quality),[m,h]=(0,v.useState)(r.resolution),g=l.find(e=>e.value===u)?.supports||{},_=g.quality||[],y=g.resolution||[`1K`],b=_.includes(f)?f:_[0]||`low`,x=y.includes(m)?m:y[0],S=t(u,1,{quality:b,resolution:x}),C={display:`flex`,alignItems:`center`,justifyContent:`space-between`,gap:10,fontSize:12,color:`var(--text-secondary)`};return(0,D.jsx)(`div`,{style:{position:`fixed`,inset:0,zIndex:99e3,background:`rgba(0,0,0,0.45)`,display:`flex`,alignItems:`center`,justifyContent:`center`},onMouseDown:o,children:(0,D.jsxs)(`div`,{style:{background:`var(--bg-secondary)`,border:`1px solid var(--border)`,borderRadius:12,padding:16,width:340,maxWidth:`calc(100vw - 24px)`,display:`flex`,flexDirection:`column`,gap:10,fontFamily:`var(--font)`},onMouseDown:e=>e.stopPropagation(),children:[(0,D.jsx)(`strong`,{style:{fontSize:13,color:`var(--text-primary)`},children:s||`${n} · generation settings`}),(0,D.jsxs)(`div`,{style:C,children:[`Model`,(0,D.jsx)(ns,{value:u,onChange:e=>d(e.target.value),style:{fontSize:12},children:l.map(e=>(0,D.jsx)(`option`,{value:e.value,children:e.label},e.value))})]}),_.length>0&&(0,D.jsxs)(`div`,{style:C,children:[`Quality`,(0,D.jsx)(ns,{value:b,onChange:e=>p(e.target.value),style:{fontSize:12},children:_.map(e=>(0,D.jsx)(`option`,{value:e,children:e[0].toUpperCase()+e.slice(1)},e))})]}),(0,D.jsxs)(`div`,{style:C,children:[`Resolution`,(0,D.jsx)(ns,{value:x,onChange:e=>h(e.target.value),style:{fontSize:12},children:y.map(e=>(0,D.jsx)(`option`,{value:e,children:e},e))})]}),(0,D.jsxs)(`div`,{style:{fontSize:11.5,color:`var(--text-secondary)`},children:[`Regenerating this panel costs `,S,` cr with these settings.`]}),(0,D.jsxs)(`div`,{style:{display:`flex`,gap:8,justifyContent:`flex-end`},children:[i&&(0,D.jsx)(`button`,{className:`btn btn-secondary`,\"data-compact\":!0,style:{fontSize:11.5},onClick:()=>a(null),children:`Use bulk defaults`}),(0,D.jsx)(`button`,{className:`btn btn-secondary`,\"data-compact\":!0,style:{fontSize:11.5},onClick:o,children:`Cancel`}),(0,D.jsx)(`button`,{className:`btn btn-primary`,\"data-compact\":!0,style:{fontSize:11.5},onClick:()=>a({model:u,quality:b,resolution:x}),children:c||`Apply to ${n}`})]})]})})}let Uf=[`#6ea8ff`,`#e0b84a`,`#7ad1c0`,`#d98f6a`,`#b58ad9`,`#7ee787`],$={fontSize:10.5,fontWeight:700,padding:`2px 8px`,borderRadius:999,border:`1px solid var(--border)`,color:`var(--text-secondary)`,whiteSpace:`nowrap`},Wf={display:`block`,width:`100%`,padding:`8px 12px`,textAlign:`left`,background:`transparent`,border:0,color:`var(--text-primary)`,fontSize:12,cursor:`pointer`,fontFamily:`var(--font)`};function Gf({doc:e,sceneId:t,sceneLineages:n,disabled:r,onSheetsChange:i,onRegenSheet:a=null,onRegenAllSheets:o=null,busySheet:s=null}){let[c,l]=(0,v.useState)(!0),[u,d]=(0,v.useState)(``),[f,p]=(0,v.useState)(null),m=Qn(e,t).sheets,h=Object.keys(m),g=e.meta?.castRefs||{},_=e=>i(t,e,m),y={fontSize:10,fontWeight:700,textTransform:`uppercase`,letterSpacing:`0.05em`,color:`var(--text-secondary)`};return(0,D.jsxs)(`div`,{style:{border:`1px solid var(--border)`,borderRadius:12,padding:`10px 12px`,background:`var(--bg-secondary)`,display:`flex`,flexDirection:`column`,gap:8},children:[(0,D.jsxs)(`div`,{style:{display:`flex`,alignItems:`center`,gap:8},children:[(0,D.jsx)(`span`,{style:y,children:`Cast & stage`}),(0,D.jsxs)(`span`,{style:$,children:[h.length,` sheet`,h.length===1?``:`s`]}),(0,D.jsx)(`span`,{style:{fontSize:11,color:`var(--text-secondary)`},children:`injected into every base prompt so characters and places never drift`}),(0,D.jsx)(`span`,{style:{flex:1}}),o&&h.some(e=>!g[e])&&(0,D.jsx)(`button`,{className:`btn btn-secondary`,\"data-compact\":!0,style:{fontSize:11,padding:`2px 8px`},disabled:r||!!s,title:`Generates every missing reference sheet from your style references + its description — review the cast before building panels`,onClick:()=>o(h.filter(e=>!g[e])),children:s?`Generating refs…`:`Generate all refs (${h.filter(e=>!g[e]).length})`}),(0,D.jsx)(`button`,{className:`btn btn-secondary`,\"data-compact\":!0,style:{fontSize:11,padding:`2px 8px`},onClick:()=>l(e=>!e),children:c?`Hide`:`Show`})]}),c&&(0,D.jsxs)(D.Fragment,{children:[h.map(e=>(0,D.jsxs)(`div`,{style:{display:`flex`,gap:8,alignItems:`flex-start`},children:[g[e]?(0,D.jsx)(`img`,{src:g[e],alt:`${e} reference sheet`,loading:`lazy`,style:{width:54,height:54,objectFit:`cover`,borderRadius:8,background:`#000`,marginTop:4,flexShrink:0,cursor:`zoom-in`},title:`Reference sheet — click to view fullscreen`,onClick:()=>p({url:g[e],id:e})}):null,(0,D.jsx)(`span`,{style:{...$,marginTop:6,textTransform:`uppercase`},children:e}),(0,D.jsx)(`div`,{style:{flex:1,minWidth:0},children:(0,D.jsx)(zf,{value:m[e],disabled:r,onCommit:t=>_({...m,[e]:t})})}),a&&(0,D.jsx)(`button`,{className:`btn btn-secondary`,\"data-compact\":!0,style:{fontSize:10.5,padding:`2px 8px`,marginTop:6},disabled:r||!!s,title:`Makes a reference-sheet image for this sheet from your STYLE references + its description — no panels needed first; every panel that uses this sheet then locks to it.`,onClick:()=>a(e,t),children:s===e?`Generating…`:g[e]?`New ref`:`Make ref`}),(0,D.jsx)(`button`,{className:`btn btn-secondary`,\"data-compact\":!0,style:{fontSize:10.5,padding:`2px 8px`,marginTop:6},disabled:r,onClick:async()=>{if(!await Yo.confirm(`Delete the \"${e}\" sheet? Base prompts stop describing it on the next regenerate.`,{danger:!0,confirmText:`Delete`}))return;let t={...m};delete t[e],_(t)},children:`Delete`})]},e)),(0,D.jsxs)(`div`,{style:{display:`flex`,gap:8,alignItems:`center`},children:[(0,D.jsx)(qf,{value:u,placeholder:`new sheet name (e.g. NURSE)`,disabled:r,onCommit:e=>d(e),style:{width:220}}),(0,D.jsx)(`button`,{className:`btn btn-secondary`,\"data-compact\":!0,style:{fontSize:11},disabled:r,onClick:()=>{let e=u.trim().replace(/\\s+/g,`_`).toLowerCase();if(!e){X.error?.(`Name the sheet first.`);return}if(m[e]){X.error?.(`\"${e}\" already exists.`);return}_({...m,[e]:`describe this character or place fully — age, hair, clothing, colors, distinctive features`}),d(``)},children:`+ Sheet`})]}),n.length>0&&(0,D.jsxs)(`div`,{style:{display:`flex`,gap:6,alignItems:`center`,flexWrap:`wrap`,fontSize:11,color:`var(--text-secondary)`},children:[(0,D.jsx)(`span`,{style:y,children:`Chains`}),n.map(t=>{let n=e.lineages[t]||{};return(0,D.jsxs)(`span`,{style:{...$,whiteSpace:`normal`,maxWidth:`100%`,overflowWrap:`anywhere`},title:`Which sheets and place this edit-chain is built around`,children:[t,n.place?` — ${n.place}`:``,n.sheetIds?.length?` · uses ${n.sheetIds.join(`, `)}`:``]},t)})]}),(0,D.jsx)(`div`,{style:{fontSize:11,color:`var(--text-secondary)`},children:`Sheet edits apply to newly generated panels — regenerate a base (its chain follows) to see them.`})]}),f&&(0,D.jsx)(wc,{url:f.url,title:`${f.id} reference sheet`,onClose:()=>p(null)})]})}let Kf=[`Georgia`,`Hanken Grotesk`,`Arial`,`Times New Roman`,`Courier New`,`Verdana`];function qf({value:e,placeholder:t,onCommit:n,disabled:r,style:i}){let[a,o]=(0,v.useState)(e||``);return(0,D.jsx)(`input`,{type:`text`,value:a,placeholder:t,disabled:r,onChange:e=>o(e.target.value),onBlur:()=>{let t=a.trim();t!==(e||``)&&n(t)},style:{background:`var(--bg-primary)`,color:`var(--text-primary)`,border:`1px solid var(--border)`,borderRadius:6,padding:`3px 8px`,fontSize:12,fontFamily:`inherit`,...i}})}function Jf({value:e,onCommit:t,...n}){let[r,i]=(0,v.useState)(e||``),a=v.useRef(e);a.current=e,(0,v.useEffect)(()=>{i(e||``)},[e]);let o=async()=>{let n=r.trim();n!==(e||``)&&(await t(n)||i(a.current||``))};return(0,D.jsx)(`input`,{...n,type:`text`,value:r,onChange:e=>i(e.target.value),onBlur:o,onKeyDown:t=>{t.key===`Enter`&&(t.preventDefault(),t.currentTarget.blur()),t.key===`Escape`&&(t.preventDefault(),i(e||``))},style:{background:`var(--bg-primary)`,color:`var(--text-primary)`,border:`1px solid var(--border)`,borderRadius:6,padding:`3px 8px`,fontSize:12,fontFamily:`inherit`,...n.style}})}function Yf({entry:e,scene:t,disabled:n,onSceneChange:r,onDelete:i}){let a=il(t?.titleScreen||{}),o=e=>r({titleScreen:{...t?.titleScreen||{},...e}}),s=e=>o({font:{...a.font,...e}}),c={display:`inline-flex`,alignItems:`center`,gap:5,fontSize:11,color:`var(--text-secondary)`};return(0,D.jsxs)(`div`,{style:{display:`flex`,flexDirection:`column`,gap:8,border:`1px dashed var(--border)`,borderRadius:12,padding:12,background:`var(--bg-primary)`},children:[(0,D.jsxs)(`div`,{style:{display:`flex`,gap:6,alignItems:`center`,flexWrap:`wrap`},children:[(0,D.jsx)(`span`,{style:{...$,textTransform:`uppercase`},children:`Title screen`}),(0,D.jsxs)(`span`,{style:$,children:[(e.startMs/1e3).toFixed(2),`s → `,((e.startMs+e.durationMs)/1e3).toFixed(2),`s`]}),(0,D.jsx)(`span`,{style:{flex:1}}),(0,D.jsx)(`button`,{className:`btn btn-secondary`,\"data-compact\":!0,style:{fontSize:10.5,padding:`2px 8px`},disabled:n,onClick:i,\"data-icon-action\":`true`,\"aria-label\":`Delete`,title:`Delete`,children:(0,D.jsx)(k,{name:`trash`,size:18})})]}),(0,D.jsx)(`div`,{style:{fontFamily:a.font.family,fontWeight:a.font.weight,color:a.font.color,background:`#000`,borderRadius:8,padding:`18px 12px`,textAlign:`center`,fontSize:Math.min(34,a.font.size/2)},children:a.text||t?.title||`Chapter`}),(0,D.jsxs)(`div`,{style:{display:`flex`,gap:10,alignItems:`center`,flexWrap:`wrap`},children:[(0,D.jsxs)(`label`,{style:c,children:[`Template`,(0,D.jsx)(ns,{value:a.template,disabled:n,onChange:e=>o({template:e.target.value}),style:{fontSize:11},children:nl.map(e=>(0,D.jsx)(`option`,{value:e,children:tl[e].label},e))})]}),(0,D.jsxs)(`label`,{style:c,children:[`Text`,(0,D.jsx)(Jf,{value:a.text||``,placeholder:t?.title||`scene title`,disabled:n,onCommit:e=>o({text:e||null}),style:{width:160}})]}),(0,D.jsxs)(`label`,{style:c,children:[`Font`,(0,D.jsx)(ns,{value:a.font.family,disabled:n,onChange:e=>s({family:e.target.value}),style:{fontSize:11},children:Kf.map(e=>(0,D.jsx)(`option`,{value:e,children:e},e))})]}),(0,D.jsxs)(`label`,{style:c,children:[`Size`,(0,D.jsx)(ta,{type:`number`,min:`12`,max:`200`,value:a.font.size,disabled:n,onChange:e=>s({size:Math.max(12,Math.min(200,Number(e.target.value)||64))}),style:{width:54,background:`var(--bg-secondary)`,color:`var(--text-primary)`,border:`1px solid var(--border)`,borderRadius:5,padding:`2px 4px`,fontSize:11}})]}),(0,D.jsxs)(`label`,{style:c,children:[`Color`,(0,D.jsx)(ta,{type:`color`,value:a.font.color,disabled:n,onChange:e=>s({color:e.target.value})})]}),(0,D.jsxs)(`label`,{style:c,children:[`Weight`,(0,D.jsx)(ns,{value:String(a.font.weight),disabled:n,onChange:e=>s({weight:Number(e.target.value)}),style:{fontSize:11},children:[`400`,`600`,`700`,`800`].map(e=>(0,D.jsx)(`option`,{value:e,children:e},e))})]}),(0,D.jsxs)(`label`,{style:c,children:[`Animation`,(0,D.jsx)(ns,{value:a.animation,disabled:n,onChange:e=>o({animation:e.target.value}),style:{fontSize:11},children:rl.map(e=>(0,D.jsx)(`option`,{value:e,children:e},e))})]})]})]})}function Xf({doc:e,panel:t,disabled:n,onOverlayEdit:r,onPlaceText:i,busy:a}){let o=t.textOverlays||[],s=o.filter(e=>!e.pos).length,c=(e,n)=>r(t.panelId,`update`,e,n),l=e=>r(t.panelId,`remove`,e),u=e=>r(t.panelId,`removeArrow`,e),d=()=>r(t.panelId,`add`),f={width:52,background:`var(--bg-primary)`,color:`var(--text-primary)`,border:`1px solid var(--border)`,borderRadius:5,padding:`2px 5px`,fontSize:11};return(0,D.jsxs)(`div`,{style:{display:`flex`,flexDirection:`column`,gap:5,border:`1px dashed var(--border)`,borderRadius:8,padding:`6px 8px`},children:[(0,D.jsxs)(`div`,{style:{display:`flex`,alignItems:`center`,gap:6},children:[(0,D.jsx)(`span`,{style:{fontSize:10,fontWeight:700,textTransform:`uppercase`,letterSpacing:`0.05em`,color:`var(--text-secondary)`},children:`Text overlays`}),(0,D.jsx)(`span`,{style:{fontSize:10,color:`var(--text-secondary)`},children:`coded text placed OVER the frame — always editable`}),(0,D.jsx)(`span`,{style:{flex:1}}),s>0&&(0,D.jsx)(`button`,{className:`btn btn-secondary`,\"data-compact\":!0,style:{fontSize:10.5,padding:`2px 8px`},disabled:n||!t.image,title:t.image?`A vision model looks at the finished frame and places the pending text (position + size, avoiding the artwork)`:`Build the frame first — placement looks at the finished image`,onClick:()=>i(t.panelId),children:a?`Placing…`:`Place ${s} with vision`}),(0,D.jsx)(`button`,{className:`btn btn-secondary`,\"data-compact\":!0,style:{fontSize:10.5,padding:`2px 8px`},disabled:n,onClick:d,children:`+ Text`})]}),o.map((e,t)=>(0,D.jsxs)(`div`,{style:{display:`flex`,gap:6,alignItems:`center`,flexWrap:`wrap`,fontSize:11,color:`var(--text-secondary)`},children:[(0,D.jsx)(qf,{value:e.text,disabled:n,onCommit:e=>c(t,{text:e}),style:{flex:1,minWidth:120}}),(0,D.jsx)(`select`,{style:{...f,width:74},disabled:n,value:e.role||`medium`,title:`Importance tier — sets how big the label is by default (you can still fine-tune size)`,onChange:e=>c(t,{role:e.target.value,size:Gn(e.target.value)}),children:Wn.map(e=>(0,D.jsx)(`option`,{value:e,children:e},e))}),e.pos?(0,D.jsxs)(D.Fragment,{children:[`x`,(0,D.jsx)(`input`,{type:`number`,min:`0`,max:`1`,step:`0.01`,style:f,disabled:n,defaultValue:Number(e.pos.x).toFixed(2),onBlur:e=>c(t,{pos:{x:Math.max(0,Math.min(1,Number(e.target.value)||0))}})},`x${Number(e.pos.x)}`),`y`,(0,D.jsx)(`input`,{type:`number`,min:`0`,max:`1`,step:`0.01`,style:f,disabled:n,defaultValue:Number(e.pos.y).toFixed(2),onBlur:e=>c(t,{pos:{y:Math.max(0,Math.min(1,Number(e.target.value)||0))}})},`y${Number(e.pos.y)}`),`size`,(0,D.jsx)(`input`,{type:`number`,min:`0.02`,max:`0.3`,step:`0.01`,style:f,disabled:n,defaultValue:Number(e.size||.05).toFixed(2),onBlur:e=>c(t,{size:Math.max(.02,Math.min(.3,Number(e.target.value)||.05))})},`s${Number(e.size||.05)}`)]}):(0,D.jsx)(`span`,{style:{...$},children:`awaiting vision placement`}),e.arrow?.to?(0,D.jsxs)(D.Fragment,{children:[(0,D.jsx)(`span`,{style:{fontSize:10.5},title:e.arrow.pointsAt?`arrow → ${e.arrow.pointsAt}`:`arrow tip`,children:`→`}),`x`,(0,D.jsx)(`input`,{type:`number`,min:`0`,max:`1`,step:`0.01`,style:f,disabled:n,defaultValue:Number(e.arrow.to.x).toFixed(2),onBlur:e=>c(t,{arrow:{to:{x:Math.max(0,Math.min(1,Number(e.target.value)||0))}}})},`ax${Number(e.arrow.to.x)}`),`y`,(0,D.jsx)(`input`,{type:`number`,min:`0`,max:`1`,step:`0.01`,style:f,disabled:n,defaultValue:Number(e.arrow.to.y).toFixed(2),onBlur:e=>c(t,{arrow:{to:{y:Math.max(0,Math.min(1,Number(e.target.value)||0))}}})},`ay${Number(e.arrow.to.y)}`),(0,D.jsx)(`button`,{className:`btn btn-secondary`,\"data-compact\":!0,style:{fontSize:10,padding:`1px 6px`},disabled:n,onClick:()=>u(t),children:`No arrow`})]}):(0,D.jsx)(`button`,{className:`btn btn-secondary`,\"data-compact\":!0,style:{fontSize:10,padding:`1px 7px`},disabled:n,title:`Add an arrow that points from this label at a spot in the frame`,onClick:()=>c(t,{arrow:{to:{x:Math.max(0,Math.min(1,(e.pos?.x??.5)+.18)),y:e.pos?.y??.5}}}),children:`+ Arrow`}),(0,D.jsx)(`span`,{style:{...$,fontSize:9.5},children:e.placedBy||`user`}),(0,D.jsx)(`button`,{className:`btn btn-secondary`,\"data-compact\":!0,style:{fontSize:10,padding:`1px 7px`},disabled:n,onClick:()=>l(t),\"data-icon-action\":`true`,\"aria-label\":`Delete`,title:`Delete`,children:(0,D.jsx)(k,{name:`trash`,size:18})})]},t))]})}function Zf({doc:e,panel:t,disabled:n,onRevealEdit:r,onRerender:i,busy:a}){let o=Vl(t.revealPlan),s=(e,n)=>r(t.panelId,`patch`,e,n),c=(e,n)=>{let i=o.order.indexOf(e);if(!(i<0||i+n<0||i+n>=o.order.length))return r(t.panelId,`move`,e,{},n)},l=e=>r(t.panelId,`remove`,e),u=e=>{if(!(o.order.indexOf(e)<=0))return r(t.panelId,`merge`,e)},d={width:56,background:`var(--bg-primary)`,color:`var(--text-primary)`,border:`1px solid var(--border)`,borderRadius:5,padding:`2px 5px`,fontSize:11},f=new Map(o.elements.map(e=>[e.id,e])),p=[...o.order,...o.elements.filter(e=>e.alwaysVisible&&!o.order.includes(e.id)).map(e=>e.id)];return(0,D.jsxs)(`div`,{style:{display:`flex`,flexDirection:`column`,gap:5,border:`1px dashed var(--border)`,borderRadius:8,padding:`6px 8px`},children:[(0,D.jsxs)(`div`,{style:{display:`flex`,alignItems:`center`,gap:6,flexWrap:`wrap`},children:[(0,D.jsx)(`span`,{style:{fontSize:10,fontWeight:700,textTransform:`uppercase`,letterSpacing:`0.05em`,color:`var(--text-secondary)`},children:`Reveal elements`}),(0,D.jsx)(`span`,{style:{fontSize:10,color:`var(--text-secondary)`},children:`pixel-exact boxes from detection; edit names, boxes, order — no regeneration`}),(0,D.jsx)(`span`,{style:{flex:1}}),(0,D.jsx)(`button`,{className:`btn btn-secondary`,\"data-compact\":!0,style:{fontSize:10.5,padding:`2px 8px`},disabled:n,title:`Repaint every reveal step from the base image with the current elements/order — free`,onClick:()=>i(t.panelId),children:a?`Rendering…`:`Re-render steps · free`}),(0,D.jsx)(`button`,{className:`btn btn-secondary`,\"data-compact\":!0,style:{fontSize:10.5,padding:`2px 8px`},disabled:n,title:`Throw the plan away and re-detect from the base image (fresh boxes + vision naming)`,onClick:()=>r(t.panelId,`clear`).then(e=>{e&&X.info?.(`Plan cleared — Re-render to re-detect.`)}),children:`Re-detect`})]}),p.map((e,t)=>{let r=f.get(e);return r?(0,D.jsxs)(`div`,{style:{display:`flex`,gap:6,alignItems:`center`,flexWrap:`wrap`,fontSize:11,color:`var(--text-secondary)`},children:[(0,D.jsx)(`span`,{style:{...$,fontWeight:700},children:r.alwaysVisible?`∞`:t+1}),(0,D.jsx)(qf,{value:r.name,disabled:n,onCommit:t=>s(e,{name:t}),style:{flex:1,minWidth:110}}),`x`,(0,D.jsx)(`input`,{type:`number`,style:d,disabled:n,defaultValue:r.box.x,onBlur:t=>s(e,{box:{x:Math.max(0,Math.round(Number(t.target.value)||0))}})},`x${r.box.x}`),`y`,(0,D.jsx)(`input`,{type:`number`,style:d,disabled:n,defaultValue:r.box.y,onBlur:t=>s(e,{box:{y:Math.max(0,Math.round(Number(t.target.value)||0))}})},`y${r.box.y}`),`w`,(0,D.jsx)(`input`,{type:`number`,style:d,disabled:n,defaultValue:r.box.w,onBlur:t=>s(e,{box:{w:Math.max(1,Math.round(Number(t.target.value)||1))}})},`w${r.box.w}`),`h`,(0,D.jsx)(`input`,{type:`number`,style:d,disabled:n,defaultValue:r.box.h,onBlur:t=>s(e,{box:{h:Math.max(1,Math.round(Number(t.target.value)||1))}})},`h${r.box.h}`),(0,D.jsx)(`button`,{className:`btn btn-secondary`,\"data-compact\":!0,style:{fontSize:10,padding:`1px 6px`},disabled:n||r.alwaysVisible,onClick:()=>c(e,-1),children:`↑`}),(0,D.jsx)(`button`,{className:`btn btn-secondary`,\"data-compact\":!0,style:{fontSize:10,padding:`1px 6px`},disabled:n||r.alwaysVisible,onClick:()=>c(e,1),children:`↓`}),(0,D.jsxs)(`label`,{style:{display:`inline-flex`,alignItems:`center`,gap:3,fontSize:10},title:`Never covered — visible from the first step`,children:[(0,D.jsx)(`input`,{type:`checkbox`,checked:r.alwaysVisible,disabled:n,onChange:t=>s(e,{alwaysVisible:t.target.checked})}),`always`]}),(0,D.jsx)(`button`,{className:`btn btn-secondary`,\"data-compact\":!0,style:{fontSize:10,padding:`1px 7px`},disabled:n||o.order.indexOf(e)<=0,title:`Union this box into the previous element (they reveal together)`,onClick:()=>u(e),children:`Merge ↑`}),(0,D.jsx)(`button`,{className:`btn btn-secondary`,\"data-compact\":!0,style:{fontSize:10,padding:`1px 7px`},disabled:n,onClick:()=>l(e),\"data-icon-action\":`true`,\"aria-label\":`Delete`,title:`Delete`,children:(0,D.jsx)(k,{name:`trash`,size:18})})]},e):null}),!p.length&&(0,D.jsx)(`div`,{style:{fontSize:11,color:`var(--text-secondary)`},children:`No elements yet — build the base image, then the steps detect + render automatically.`})]})}let Qf={fontSize:9,fontWeight:700,letterSpacing:`0.06em`,textTransform:`uppercase`,color:`var(--text-secondary)`,opacity:.75};function $f({url:e,alt:t,size:n=200,onClick:r}){return e?(0,D.jsx)(`img`,{src:e,alt:t,loading:`lazy`,onClick:r,style:{width:n,borderRadius:8,display:`block`,background:`#000`,...r?{cursor:`zoom-in`}:{}}}):(0,D.jsx)(`div`,{style:{width:n,height:Math.round(n*.56),borderRadius:8,border:`1px dashed var(--border)`,display:`flex`,alignItems:`center`,justifyContent:`center`,fontSize:11,color:`var(--text-secondary)`},children:`no gif`})}function ep({value:e,onSearch:t,disabled:n,busy:r}){let[i,a]=(0,v.useState)(e||``),o=()=>{let e=i.trim();e&&t(e)};return(0,D.jsxs)(`div`,{style:{display:`flex`,gap:6,alignItems:`center`},children:[(0,D.jsx)(`input`,{type:`text`,value:i,placeholder:`search Giphy for a different reaction…`,disabled:n,onChange:e=>a(e.target.value),onKeyDown:e=>{e.key===`Enter`&&(e.preventDefault(),o())},style:{flex:1,minWidth:0,background:`var(--bg-primary)`,color:`var(--text-primary)`,border:`1px solid var(--border)`,borderRadius:6,padding:`3px 8px`,fontSize:12,fontFamily:`inherit`}}),(0,D.jsx)(`button`,{className:`btn btn-secondary`,\"data-compact\":!0,style:{fontSize:10.5,padding:`2px 8px`},disabled:n||r,onClick:o,children:r?`Searching…`:`Swap`})]})}function tp({mode:e,disabled:t,onSetMode:n}){return(0,D.jsx)(`div`,{style:{display:`inline-flex`,gap:4,alignItems:`center`,fontSize:10.5,color:`var(--text-secondary)`},title:`Replace = the GIF IS this beat (no panel generated, free). Overlay = a generated panel plays under the GIF.`,children:un.map(r=>(0,D.jsx)(`button`,{className:`btn btn-secondary`,\"data-compact\":!0,disabled:t||e===r,style:{fontSize:10.5,padding:`2px 9px`,...e===r?{color:`var(--text-primary)`,borderColor:`var(--accent, var(--text-primary))`}:{}},onClick:()=>n(r),children:r},r))})}function np({p:e,says:t,disabled:n,busy:r,canDelete:i,onSaysCommit:a,onSetMode:o,onSwapCandidate:s,onSearchSwap:c,onMove:l,onDelete:u,onView:d}){let f=(e.candidates||[]).filter(t=>t&&t!==e.gif).slice(0,6);return(0,D.jsxs)(`div`,{style:{display:`flex`,gap:12,alignItems:`stretch`,border:`1px solid var(--border)`,borderRadius:12,padding:12,background:`var(--bg-secondary)`},children:[(0,D.jsxs)(`div`,{style:{width:200,minWidth:200,display:`flex`,flexDirection:`column`,gap:6},children:[(0,D.jsx)($f,{url:e.gif,alt:e.panelId,onClick:e.gif?d:void 0}),(0,D.jsx)(`div`,{style:Qf,children:`Powered by GIPHY`})]}),(0,D.jsxs)(`div`,{style:{flex:1,minWidth:0,display:`flex`,flexDirection:`column`,gap:7},children:[(0,D.jsxs)(`div`,{style:{display:`flex`,gap:6,alignItems:`center`,flexWrap:`wrap`},children:[(0,D.jsx)(`strong`,{style:{color:`var(--text-primary)`,fontSize:13},children:e.panelId}),(0,D.jsx)(`span`,{style:{...$,textTransform:`uppercase`},children:`reaction gif`}),(0,D.jsxs)(`span`,{style:$,children:[(e.startMs/1e3).toFixed(2),`s → `,((e.startMs+e.durationMs)/1e3).toFixed(2),`s · `,(e.durationMs/1e3).toFixed(2),`s`]}),e.tone&&(0,D.jsxs)(`span`,{style:$,children:[`tone: `,e.tone]}),(0,D.jsx)(tp,{mode:e.mode,disabled:n,onSetMode:o}),(0,D.jsx)(`span`,{style:{flex:1}}),(0,D.jsx)(`button`,{className:`btn btn-secondary`,\"data-compact\":!0,style:{fontSize:10,padding:`1px 7px`},disabled:n,title:`Move this GIF one beat earlier`,onClick:()=>l(-1),children:`↑`}),(0,D.jsx)(`button`,{className:`btn btn-secondary`,\"data-compact\":!0,style:{fontSize:10,padding:`1px 7px`},disabled:n,title:`Move this GIF one beat later`,onClick:()=>l(1),children:`↓`}),(0,D.jsx)(`button`,{className:`btn btn-secondary`,\"data-compact\":!0,style:{fontSize:10.5,padding:`2px 8px`},disabled:n||!i,onClick:u,\"data-icon-action\":`true`,\"aria-label\":`Delete`,title:`Delete`,children:(0,D.jsx)(k,{name:`trash`,size:18})})]}),(0,D.jsx)(Vf,{value:t,disabled:n,onCommit:a},`${e.panelId}-says-${t}`),e.gifQuery&&(0,D.jsxs)(`div`,{style:{fontSize:11,color:`var(--text-secondary)`},children:[`Search intent: `,(0,D.jsx)(`span`,{style:{fontStyle:`italic`},children:e.gifQuery})]}),(0,D.jsx)(ep,{value:e.gifQuery||``,onSearch:c,disabled:n,busy:r}),f.length>0&&(0,D.jsxs)(`div`,{style:{display:`flex`,gap:6,alignItems:`center`,flexWrap:`wrap`},children:[(0,D.jsx)(`span`,{style:{fontSize:10,fontWeight:700,textTransform:`uppercase`,letterSpacing:`0.05em`,color:`var(--text-secondary)`},children:`Alternates`}),f.map(e=>(0,D.jsx)(`img`,{src:e,alt:`alternate`,loading:`lazy`,onClick:()=>!n&&s(e),style:{height:48,borderRadius:6,cursor:n?`default`:`pointer`,background:`#000`,opacity:n?.6:1}},e))]})]})]})}function rp({doc:e,ops:t,busyGif:n,editPending:r,editStatus:i,onClose:a,onConfirm:o}){let s=(e?.strip||[]).filter(e=>e.type===`giphy`),c=(e?.strip||[]).filter(e=>e.overlayLayer&&typeof e.overlayLayer==`object`),l=s.length+c.length,u={display:`flex`,gap:12,alignItems:`flex-start`,border:`1px solid var(--border)`,borderRadius:10,padding:10,background:`var(--bg-primary)`};return(0,D.jsx)(`div`,{style:{position:`fixed`,inset:0,zIndex:99e3,background:`rgba(0,0,0,0.45)`,display:`flex`,alignItems:`center`,justifyContent:`center`,padding:20},onMouseDown:a,children:(0,D.jsxs)(`div`,{style:{background:`var(--bg-secondary)`,border:`1px solid var(--border)`,borderRadius:12,padding:16,width:620,maxWidth:`100%`,maxHeight:`86vh`,overflowY:`auto`,display:`flex`,flexDirection:`column`,gap:12,fontFamily:`var(--font)`},onMouseDown:e=>e.stopPropagation(),children:[(0,D.jsxs)(`div`,{style:{display:`flex`,alignItems:`baseline`,gap:8,flexWrap:`wrap`},children:[(0,D.jsx)(`strong`,{style:{fontSize:14,color:`var(--text-primary)`},children:`Reaction GIF plan`}),(0,D.jsxs)(`span`,{style:{...$},children:[l,` placement`,l===1?``:`s`]}),(0,D.jsx)(`span`,{style:{flex:1}}),(0,D.jsx)(`span`,{style:Qf,children:`Powered by GIPHY`})]}),(0,D.jsx)(`div`,{style:{fontSize:12,color:`var(--text-secondary)`},children:`Every place a reaction GIF lands, in order. Swap, move, delete, or toggle replace/overlay before the image panels build — replace beats generate no panel; overlay beats play the GIF over a generated one. Nothing is locked; you can keep editing the image panels afterward.`}),i,l===0&&(0,D.jsx)(`div`,{style:{fontSize:12,color:`var(--text-secondary)`},children:`No reaction GIFs were placed.`}),s.map(r=>{let i=(r.candidates||[]).filter(e=>e&&e!==r.gif).slice(0,6);return(0,D.jsxs)(`div`,{style:u,children:[(0,D.jsx)($f,{url:r.gif,alt:r.panelId,size:150}),(0,D.jsxs)(`div`,{style:{flex:1,minWidth:0,display:`flex`,flexDirection:`column`,gap:6},children:[(0,D.jsxs)(`div`,{style:{display:`flex`,gap:6,alignItems:`center`,flexWrap:`wrap`},children:[(0,D.jsx)(`strong`,{style:{color:`var(--text-primary)`,fontSize:12.5},children:r.panelId}),(0,D.jsx)(`span`,{style:{...$,textTransform:`uppercase`},children:`replace`}),(0,D.jsxs)(`span`,{style:$,children:[(r.startMs/1e3).toFixed(2),`s`]}),r.tone&&(0,D.jsxs)(`span`,{style:$,children:[`tone: `,r.tone]}),(0,D.jsx)(tp,{mode:r.mode,disabled:!1,onSetMode:e=>t.setMode(r.panelId,e)}),(0,D.jsx)(`span`,{style:{flex:1}}),(0,D.jsx)(`button`,{className:`btn btn-secondary`,\"data-compact\":!0,style:{fontSize:10,padding:`1px 7px`},onClick:()=>t.move(r.panelId,-1),children:`↑`}),(0,D.jsx)(`button`,{className:`btn btn-secondary`,\"data-compact\":!0,style:{fontSize:10,padding:`1px 7px`},onClick:()=>t.move(r.panelId,1),children:`↓`}),(0,D.jsx)(`button`,{className:`btn btn-secondary`,\"data-compact\":!0,style:{fontSize:10.5,padding:`2px 8px`},disabled:e.strip.length<=1,onClick:()=>t.del(r.panelId),\"data-icon-action\":`true`,\"aria-label\":`Delete`,title:`Delete`,children:(0,D.jsx)(k,{name:`trash`,size:18})})]}),r.gifQuery&&(0,D.jsx)(`div`,{style:{fontSize:11,color:`var(--text-secondary)`,fontStyle:`italic`},children:r.gifQuery}),(0,D.jsx)(ep,{value:r.gifQuery||``,onSearch:e=>t.searchSwap(r.panelId,e),disabled:!1,busy:n===r.panelId}),i.length>0&&(0,D.jsx)(`div`,{style:{display:`flex`,gap:5,flexWrap:`wrap`},children:i.map(e=>(0,D.jsx)(`img`,{src:e,alt:`alternate`,loading:`lazy`,onClick:()=>t.swapCandidate(r.panelId,e),style:{height:42,borderRadius:5,cursor:`pointer`,background:`#000`}},e))})]})]},r.panelId)}),c.map(e=>{let r=e.overlayLayer;return(0,D.jsxs)(`div`,{style:u,children:[(0,D.jsx)($f,{url:r.gifUrl,alt:`${e.panelId} overlay`,size:150}),(0,D.jsxs)(`div`,{style:{flex:1,minWidth:0,display:`flex`,flexDirection:`column`,gap:6},children:[(0,D.jsxs)(`div`,{style:{display:`flex`,gap:6,alignItems:`center`,flexWrap:`wrap`},children:[(0,D.jsx)(`strong`,{style:{color:`var(--text-primary)`,fontSize:12.5},children:e.panelId}),(0,D.jsx)(`span`,{style:{...$,textTransform:`uppercase`},children:`overlay`}),(0,D.jsx)(`span`,{style:$,children:`covers a generated panel`}),(0,D.jsx)(`span`,{style:{flex:1}}),(0,D.jsx)(`button`,{className:`btn btn-secondary`,\"data-compact\":!0,style:{fontSize:10.5,padding:`2px 8px`},onClick:()=>t.removeOverlay(e.panelId),children:`Remove GIF`})]}),r.gifQuery&&(0,D.jsx)(`div`,{style:{fontSize:11,color:`var(--text-secondary)`,fontStyle:`italic`},children:r.gifQuery}),(0,D.jsx)(ep,{value:r.gifQuery||``,onSearch:n=>t.searchSwap(e.panelId,n,{overlay:!0}),disabled:!1,busy:n===e.panelId})]})]},`ov-${e.panelId}`)}),(0,D.jsxs)(`div`,{style:{display:`flex`,gap:8,justifyContent:`flex-end`,position:`sticky`,bottom:0,background:`var(--bg-secondary)`,paddingTop:8},children:[(0,D.jsx)(`button`,{className:`btn btn-secondary`,\"data-compact\":!0,onClick:a,children:`Cancel`}),(0,D.jsx)(`button`,{className:`btn btn-primary`,\"data-compact\":!0,disabled:r,onClick:o,children:`Confirm plan & build`})]})]})})}function ip({panel:e,width:t=200,onClick:n}){let r=v.useRef(null),i=v.useRef(new Map),[a,o]=(0,v.useState)(0),s=Math.round(t*9/16);return(0,v.useEffect)(()=>{let t=new Map;i.current=t;let n=[...new Set((e.elements||[]).flatMap(e=>e.kind===`image`&&e.src?[e.src]:e.kind===`video`&&e.poster?[e.poster]:[]))];for(let e of n){let n=new Image;n.crossOrigin=`anonymous`,n.onload=()=>{i.current===t&&(t.set(e,n),o(e=>e+1))},n.src=e}},[e.elements]),(0,v.useEffect)(()=>{let n=r.current;n&&Xt(n.getContext(`2d`),e,Number(e.durationMs)||0,e=>i.current.get(e)||null,t,s)},[e,a,t,s]),(0,D.jsx)(`canvas`,{ref:r,width:t,height:s,onClick:n,style:{width:`100%`,borderRadius:8,display:`block`,border:`1px solid var(--border)`,...n?{cursor:`pointer`}:{}}})}function ap({step:e,milestones:t,startedAt:n=null}){let r=()=>{let r=t[e]??0,i=t[e+1]??100;if(r>=100||i<=r)return r;let a=e===0?7e3:3500,o=n==null?0:performance.now()-n;return Math.min(i-.5,Math.max(r,r+(i-r)*(1-Math.exp(-o/a))))},[i,a]=v.useState(r);return v.useEffect(()=>{a(r());let n=t[e]??0,i=t[e+1]??100;if(n>=100||i<=n)return;let o=setInterval(()=>a(r()),200);return()=>clearInterval(o)},[e,t,n]),(0,D.jsxs)(`span`,{style:{display:`inline-flex`,alignItems:`center`,gap:8},children:[(0,D.jsx)(`span`,{children:`Planning image panels from your conversation and narration timing…`}),(0,D.jsx)(`span`,{style:{position:`relative`,width:64,height:5,borderRadius:999,background:`var(--border)`,overflow:`hidden`,flexShrink:0},children:(0,D.jsx)(`span`,{style:{position:`absolute`,left:0,top:0,bottom:0,width:`${i}%`,background:`var(--accent)`,borderRadius:999,transition:`width 220ms linear`}})}),(0,D.jsxs)(`span`,{style:{fontVariantNumeric:`tabular-nums`,fontWeight:600,minWidth:32,textAlign:`right`,color:`var(--text-primary)`},children:[Math.round(i),`%`]})]})}function op({panelAccessHost:e,styleAuthoringHost:t,panelImageProcessHost:n,styleLibraryHost:r,panelPreferencesHost:i,generationCatalogHost:a,panelZoomHost:o,presenterProvisionHost:s,panelCropHost:c,mediaHost:l,panelEditHost:u,panelPromptHost:d,panelSettingsHost:f,panelWorkflowHost:p,panelGenerationHost:m,doc:h,onDocChange:g,chatMessages:_=[],voiceover:y=null,projectTitle:S=``,aspect:C=`16:9`,onAspectChange:w=null,onContinueToEditor:T,nextStepLabel:E=`Editor`,projectType:O=null,projectTypeNote:A=``,onProjectTypeChange:j=null,gifsEnabled:M=!1,canvasesEnabled:ee=!1,hostEnabled:N=!1,projectId:P=null}){let{openCanvas:te}=Nf(e),{process:ne}=el(n),{list:re}=jl(r),{defaultImageModel:F,read:I,write:L}=If(i),R=H(u).actor,z=(0,v.useMemo)(()=>Ff(a),[a]),{PANEL_MODEL_OPTIONS:ie,panelGenFromDefaults:ae}=z,{imageCost:oe,videoCost:B,creditCosts:V,formatCostLabel:se}=a,{planImagePanelStrip:ce,stockAutoFind:ue,uploadReferenceImage:de,placePanelText:pe,nameRevealElements:me,planGifBeats:he,planCanvasBeats:ve,searchGiphyGifs:ye,checkStripConsistency:be,generateVideo:Se}=le(p),Ce=(e,t)=>fe(m,e,t),U=Wo(P,h||{strip:[]},g,`panels`),we=v.useRef(!0);we.current=U.canEdit!==!1;let W=(0,v.useCallback)((...e)=>{U.canEdit!==!1&&g(...e)},[g,U.canEdit]),G=v.useRef(null),Oe=yi({host:d,doc:h,projectId:P,canEdit:U.canEdit!==!1,onDocChange:W,validateDocument:q,editLease:G}),ke=Oi({host:u,doc:h,projectId:P,canEdit:U.canEdit!==!1,onDocChange:W,validateDocument:q,editLease:G}),Ae=Wi({host:u,doc:h,projectId:P,canEdit:U.canEdit!==!1,onDocChange:W,validateDocument:q,editLease:G}),Ne=Yi({host:f,doc:h,projectId:P,aspect:C,projectType:O,projectTypeNote:A,projectTypes:je,onProjectTypeChange:j,canEdit:U.canEdit!==!1,onDocChange:W,onAspectChange:w,validateDocument:q,editLease:G}),Pe=ea({host:u,doc:h,projectId:P,canEdit:U.canEdit!==!1,onDocChange:W,validateDocument:q,editLease:G}),Fe=v.useRef(null),Ie=v.useRef(!0),Le=R();Fe.current={doc:h,projectId:P,canEdit:U.canEdit!==!1,actor:Le,source:()=>JSON.stringify({words:(y?.words?.length?y.words:h?.audio?.words)||[],chatMessages:_,voiceover:y,projectTitle:S,aspect:C,projectType:O,projectTypeNote:A,gifsEnabled:M,canvasesEnabled:ee})},(0,v.useEffect)(()=>(Ie.current=!0,()=>{Ie.current=!1}),[]);let Re=oa({host:u,doc:h,projectId:P,aspect:C,canEdit:U.canEdit!==!1,onDocChange:W,validateDocument:q,editLease:G}),ze=ya({host:u,provisioner:s,doc:h,voiceover:y,projectId:P,canEdit:U.canEdit!==!1,hostEnabled:N,onDocChange:W,editLease:G}),Be=Fi({host:u,doc:h,projectId:P,canEdit:U.canEdit!==!1,onDocChange:W,editLease:G}),Ve=(0,v.useRef)(null),Ue=()=>{Ve.current=null,Be.cancel(),xt(null)},We=zo({host:u,doc:h,projectId:P,canEdit:U.canEdit!==!1,onDocChange:W,validateDocument:q,editLease:G}),Ge=Io({host:u,doc:h,projectId:P,canEdit:U.canEdit!==!1,onDocChange:W,validateDocument:q,editLease:G}),Ke=Ao({host:u,doc:h,projectId:P,canEdit:U.canEdit!==!1,onDocChange:W,validateDocument:q,editLease:G}),qe=wo({host:u,doc:h,projectId:P,canEdit:U.canEdit!==!1,onDocChange:W,validateDocument:q,editLease:G}),Je=vo({host:u,doc:h,projectId:P,canEdit:U.canEdit!==!1,onDocChange:W,validateDocument:q,editLease:G}),Ye=fo({host:u,doc:h,projectId:P,canEdit:U.canEdit!==!1,onDocChange:W,validateDocument:q,editLease:G}),Xe=oo({host:u,doc:h,projectId:P,canEdit:U.canEdit!==!1,onDocChange:W,validateDocument:q,editLease:G}),Ze=to({host:u,doc:h,projectId:P,canEdit:U.canEdit!==!1,onDocChange:W,validateDocument:q,editLease:G}),K=Za({host:u,doc:h,projectId:P,canEdit:U.canEdit!==!1,onDocChange:W,validateDocument:q,editLease:G}),Qe=Ee({host:u,doc:h,projectId:P,canEdit:U.canEdit!==!1,onDocChange:W,validateDocument:q,editLease:G}),$e=Ka({host:u,doc:h,projectId:P,canEdit:U.canEdit!==!1,onDocChange:W,validateDocument:q,editLease:G}),et=Ra({host:u,doc:h,projectId:P,canEdit:U.canEdit!==!1,onDocChange:W,validateDocument:q,editLease:G}),tt=ja({host:u,doc:h,projectId:P,canEdit:U.canEdit!==!1,onDocChange:W,validateDocument:q,editLease:G}),nt=Ea({host:u,doc:h,projectId:P,canEdit:U.canEdit!==!1,onDocChange:W,validateDocument:q,editLease:G}),rt=Ol(P),[it,at]=(0,v.useState)(!1),[ot,st]=(0,v.useState)(null),ct=it||(P?rt?.status===`planning`:!1),lt=(P?rt?.progress:ot)||null,ut=lt?.step??0,dt=lt?.milestones??[0,100],ft=lt?.startedAt??null;(0,v.useEffect)(()=>{let e=R();if(!P||U.canEdit===!1)return;let t=yl(P,{actorId:e,document:h,canEdit:!0,inputFingerprint:Fe.current.source()});if(t===h){Al(P,t,e);return}if(t){let n=JSON.stringify(h),r=Fe.current.source();W(i=>{let a=Fe.current;return Ie.current&&a.actor===e&&R()===e&&a.projectId===P&&a.canEdit&&a.source()===r&&JSON.stringify(i)===n?t:i})}},[P,h,rt?.status,U.canEdit]);let pt=async()=>{let e=Fe.current,t=R(),n=kl(P,t);if(!n||!e.canEdit||t!==Le||e.actor!==Le)return;let r=JSON.stringify(e.doc),i=e.source();if(!await Yo.confirm(`Replace the current image panel plan with the completed plan? It was made from the earlier narration and settings. Current panels and their generated images will be replaced.`,{title:`Use completed plan`,confirmText:`Use completed plan`}))return;let a=Fe.current;if(!Ie.current||R()!==t||a.projectId!==P||!a.canEdit||a.source()!==i||JSON.stringify(a.doc)!==r)return;let o=yl(P,{actorId:t,document:a.doc,canEdit:!0,reviewedResult:n});o&&W(e=>{let n=Fe.current;return Ie.current&&R()===t&&n.projectId===P&&n.canEdit&&n.source()===i&&JSON.stringify(e)===r?o:e})},[mt,ht]=(0,v.useState)(!1),gt=v.useRef(!1),[_t,vt]=(0,v.useState)(!1),yt=v.useRef(!1),[bt,xt]=(0,v.useState)(null),[St,Ct]=(0,v.useState)(null),[wt,Tt]=(0,v.useState)(null),Et=async e=>{await te({actor:Le})&&Tt(e)},[Dt,Ot]=(0,v.useState)(null),[kt,At]=(0,v.useState)(null),[jt,Mt]=(0,v.useState)(null),[Nt,Pt]=(0,v.useState)(null),Ft=ke.pending,It=(0,v.useMemo)(()=>{let e=I();return ae(e||{model:F(),quality:`low`,resolution:`1K`})},[]),[Lt,Rt]=(0,v.useState)(It.model),[zt,Bt]=(0,v.useState)(It.quality),[Vt,Ht]=(0,v.useState)(It.resolution),[Ut,Wt]=(0,v.useState)(!1),[Gt,Kt]=(0,v.useState)(!1),Jt=Ko(),[Yt,Xt]=(0,v.useState)(!1),[Zt,Qt]=(0,v.useState)(null),[$t,en]=(0,v.useState)(null),[tn,nn]=(0,v.useState)(null),rn=Bi({host:u,doc:h,projectId:P,editing:tn,canEdit:U.canEdit!==!1,onDocChange:W,validateDocument:q,editLease:G}),[an,on]=(0,v.useState)(!1),[sn,cn]=(0,v.useState)([]),[ln,un]=(0,v.useState)(!1),[dn,fn]=(0,v.useState)(!1),vn=v.useRef(null),bn=(y?.words?.length?y.words:h?.audio?.words)||[],Cn=v.useRef(null),wn=ha({host:u,doc:h,words:bn,projectId:P,projectType:O,canEdit:U.canEdit!==!1,onDocChange:W,editLease:G}),Tn=(0,v.useMemo)(()=>{let e=Object.keys(h?.lineages||{});return Object.fromEntries(e.map((e,t)=>[e,Uf[t%Uf.length]]))},[h?.lineages]),Dn=e=>{let t=ie.find(t=>t.value===e)?.supports||{};return{quality:(t.quality||[]).includes(zt)?zt:(t.quality||[])[0]||`low`,resolution:(t.resolution||[`1K`]).includes(Vt)?Vt:(t.resolution||[`1K`])[0]}},On=ie.find(e=>e.value===Lt)?.supports||{},kn=On.quality||[];On.resolution;let{quality:An,resolution:jn}=Dn(Lt),Mn=Dn(Lt),Nn=pi({host:u,doc:h,projectId:P,canEdit:U.canEdit!==!1,onDocChange:W,editLease:G,settings:{},operationName:`GIF caching`}),[Pn,Fn]=(0,v.useState)(!1),In=pi({host:u,doc:h,projectId:P,canEdit:U.canEdit!==!1,onDocChange:W,editLease:G,settings:{model:Lt,genOpts:Mn},operationName:`Zoom processing`}),Ln=pi({host:u,doc:h,projectId:P,canEdit:U.canEdit!==!1,onDocChange:W,editLease:G,settings:{model:Lt,genOpts:Mn},operationName:`Canvas stock sourcing`}),Rn=pi({host:u,doc:h,projectId:P,canEdit:U.canEdit!==!1,onDocChange:W,editLease:G,settings:{model:Lt,genOpts:Mn},operationName:`Style consistency`}),zn=pi({host:u,doc:h,projectId:P,canEdit:U.canEdit!==!1,onDocChange:W,editLease:G,settings:{model:Lt,genOpts:Mn},operationName:`Reference generation`}),Bn=pi({host:u,doc:h,projectId:P,canEdit:U.canEdit!==!1,onDocChange:W,editLease:G,settings:{model:Lt,genOpts:Mn},operationName:`Panel regeneration`}),Vn=pi({host:u,doc:h,projectId:P,canEdit:U.canEdit!==!1,onDocChange:W,editLease:G,settings:{model:Lt,genOpts:Mn}}),Hn=Ci({host:u,cropHost:c,doc:h,projectId:P,canEdit:U.canEdit!==!1,onDocChange:W,editLease:G,settings:{model:Lt,genOpts:Mn}}),Un=Hn.pending,Wn=oe(Lt,1,Mn),[Gn,Kn]=(0,v.useState)({}),[qn,Jn]=(0,v.useState)(null),Yn=e=>{let t=Gn[e]||{},n=t.model||Lt,r=ie.find(e=>e.value===n)?.supports||{},i=t.quality??zt,a=t.resolution??Vt;return{model:n,quality:(r.quality||[]).includes(i)?i:(r.quality||[])[0]||`low`,resolution:(r.resolution||[`1K`]).includes(a)?a:(r.resolution||[`1K`])[0]}},Zn=h?.meta?.aspect||C,tr=[`16:9`,`9:16`,`1:1`,`4:3`,`3:4`].filter(e=>(On.aspectRatio||[]).includes(e)),or=e=>Ne.change(`aspect`,e),lr=rr({audioUrl:y?.audioUrl||h?.audio?.voPath||null,words:bn});v.useRef(!1);let pr=async(e=!1,t=`same`)=>{if(!we.current)return;let n=structuredClone({words:bn,chatMessages:_,voiceover:y,projectTitle:S,aspect:C,projectType:O,projectTypeNote:A,gifsEnabled:M,canvasesEnabled:ee}),r=Le,i=JSON.stringify(h),a=JSON.stringify(n);if(!r||R()!==r||Fe.current.actor!==r)return;if(kl(P,r)&&kl(P,r)!==h){X.info?.(`Review the completed plan before starting another paid plan.`);return}if(!lr.ready){await Yo.alert(lr.reason,{title:`Continue is locked`});return}if(ir({audioUrl:y?.audioUrl||h?.audio?.voPath||null,words:bn}),ct||P&&pl(P)){X.info?.(`Image panel planning is already running — it keeps going even if you leave this step.`);return}let o=e&&h?h.strip.filter(e=>e.type!==`titleScreen`).length:0,s=o&&t!==`same`?t===`more`?Math.max(o+3,Math.round(o*1.35)):Math.max(4,Math.min(o-3,Math.round(o*.7))):null;if(e&&h&&!await Yo.confirm(`Re-plan the image panels from the conversation${s?` with ${t} frames (about ${s} panels instead of ${o})`:``}? The current panels (and any generated images) will be replaced. ~${V[`strip:plan`]} credits.`,{confirmText:`Re-plan`}))return;let c=Fe.current;if(R()!==r||c.projectId!==P||!c.canEdit||c.source()!==a||JSON.stringify(c.doc)!==i)return;let l=new AbortController,d=null,f=()=>{if(R()!==r||l.signal.aborted||P&&(ml(P)||d&&fl(P)!==d))throw Object.assign(Error(`Planning cancelled or its account changed.`),{name:`AbortError`})},p=()=>{let e=Fe.current;return Ie.current&&R()===r&&e.actor===r&&e.projectId===P&&e.canEdit&&e.source()===a&&JSON.stringify(e.doc)===i},m=[`plan`,M&&`gif`,ee&&`canvas`].filter(Boolean),g={plan:.7,gif:.16,canvas:.14},v=m.reduce((e,t)=>e+g[t],0),b=0,x=[0];for(let e of m)b+=g[e]/v,x.push(Math.round(b*90));x.push(100);let w=async({onProgress:e,commit:r})=>{let{words:i,chatMessages:a,voiceover:c,projectTitle:d,aspect:m,projectType:h,projectTypeNote:g,gifsEnabled:_,canvasesEnabled:v}=n,y=0,b=()=>e({step:++y,milestones:x});e({step:0,milestones:x});try{f();let n=a.filter(e=>e&&e.content!==`__READY__`).map(e=>({role:e.role,content:e.content})),y=null;for(let e=0;e<2&&!y;e++)try{f(),y=await ce({messages:n,words:i,title:d,aspect:m,modelTier:`standard`,projectType:h||void 0,projectTypeNote:g||void 0,...s?{frameDensity:t,frameTarget:s,prevPanelCount:o}:{}})}catch(t){if(f(),e===1)throw t;X.info?.(`Planning is taking a moment — retrying automatically…`)}f(),b();let S=y,C=[];if(_){try{f();let e=await he({words:i,strip:y.strip,tone:c?.reactionGifs?.tone||void 0,modelTier:`standard`});f();let t=await Nr(`gif`,y.strip,e,{signal:l.signal,check:f,host:u});f(),S={...y,strip:t.strip},C=t.overlays}catch(e){f(),e?.status===503?X.info?.(`Reaction GIFs are unavailable right now — planned the image panels without them.`):X.error?.(`GIF planning skipped: ${e?.message||e}`)}b()}if(v){try{f();let e=await ve({words:i,strip:S.strip,lean:h||void 0,modelTier:`standard`});f(),e.length&&(S={...S,strip:(await Nr(`canvas`,S.strip,e,{signal:l.signal,check:f,host:u})).strip})}catch(e){f(),X.error?.(`Canvas planning skipped: ${e?.message||e}`)}b()}f();let w=await He({plan:S,words:i,title:d,aspect:m,voPath:c?.audioUrl||null},{signal:l.signal,check:f,validateDocument:q,host:u});f(),f();let T=await xe(w,Rr[0],C,{aspect:m,signal:l.signal,check:f,validateDocument:q,host:u});f(),f(),T=q(await pa(T,i,{host:u,signal:l.signal,assertCurrent:f})),f(),yt.current=!1,e({step:x.length-1,milestones:x}),r(T),X.success?.(p()?`Strip planned — ${T.strip.length} panels across ${Object.keys(T.lineages).length} lineages`:`Completed plan retained — review it when you return to these image panels.`)}catch(e){let t=!0;try{f()}catch{t=!1}t&&e?.name!==`AbortError`&&X.error?.(`Planning didn't finish (${e?.message||e}). Nothing was changed — press Re-plan to try again.`)}};if(P)d=wl(P,`planning`,()=>w({onProgress:e=>Sl(P,e,d),commit:e=>{f(),vl(P,e,{actorId:r,sourceFingerprint:i,inputFingerprint:a,currentActor:R,canApply:p},d)}}),{actorId:r,controller:l});else{at(!0);try{await w({onProgress:e=>st(t=>xl(t,e)),commit:e=>{f(),p()&&W(t=>p()&&JSON.stringify(t)===i?e:t)}})}finally{at(!1)}}},mr=async(e,{signal:t,check:n})=>{if(n(),!we.current)return;let r=e.strip.filter(e=>e.type===`panel`&&e.image&&(e.textOverlays||[]).some(e=>!e.pos)),i=e,a=new Map;for(let e of i.strip){let t=a.get(e.sceneId)||new Map;for(let n of e.textOverlays||[])n.pos&&!n.arrow?.pointsAt&&!t.has(n.text)&&t.set(n.text,{pos:n.pos,size:n.size});a.set(e.sceneId,t)}for(let e of r)try{let r=e.textOverlays||[],o=a.get(e.sceneId)||new Map,s=r.map((e,t)=>({o:e,idx:t})).filter(({o:e})=>!e.pos&&(e.arrow?.pointsAt||!o.has(e.text))),c=s.map(({o:e})=>e.arrow?.pointsAt?{text:e.text,pointsAt:e.arrow.pointsAt}:e.text);n();let l=c.length?await pe({imageUrl:$n(i.strip,e)||e.image,texts:c}):[];n();let d=await Ni(r,s.map(({idx:e})=>e),l,o,{mode:`batch`,signal:t,assertCurrent:n,host:u});n();for(let e of d)e.pos&&!e.arrow?.pointsAt&&!o.has(e.text)&&o.set(e.text,{pos:e.pos,size:e.size});a.set(e.sceneId,o),i=ar(i,e.panelId,d)}catch(t){if(n(),t?.name===`AbortError`)throw t;X.error?.(`Text placement failed on ${e.panelId}: ${t?.message||t}`)}return{doc:i,placed:r.length}},_r=async(e,t,n=Vn.capture())=>{if(we.current)return Vn.run(e,t,n,async n=>{let r={prepareFrames:(e,t)=>fi(e,{...t,host:u}),assertCurrent:n.check,signal:n.signal,nameElements:async e=>{n.check();let t=await me(e);return n.check(),t},upload:async e=>{n.check();let t=await de(e,{assertCurrent:n.check});return n.check(),t}},i=e;for(let e=0;;e++){n.check();let{doc:a,error:o}=await Kl(i,t,r);if(n.check(),i=a,!o)return i;if(!Ll(o)||e>=2)return n.check(),await Yo.alert(`${t} reveal frames were not rendered: ${o}`,{title:`Reveal failed`}),n.check(),i;let s=Yn(t),c=oe(s.model,1,s);n.check();let l=await Yo.confirm(`${t}: ${o}\\n\\nRegenerate the base with a stricter separation instruction (~${c} credits) and retry the reveal?`,{title:`Reveal needs a cleaner base`,confirmText:`Regenerate & retry`});if(n.check(),!l)return i;i=ql(i,t),await n.commit(i);let u=Ce(s.model,s);n.check();let{doc:d}=await Zr(i,t,{generate:async(...e)=>{n.check();let t=await u(...e);return n.check(),t}});n.check(),i=d,await n.commit(i)}})},vr=async e=>{if(we.current){Mt(e);try{await _r(h,e)}catch(e){X.error?.(e?.message||String(e))}finally{Mt(null)}}},yr=async(e,t)=>{let n;return await In.run(e,`zoom crops`,t,async t=>(n=await Zl(e,{deps:{assertCurrent:t.check,pickTarget:e=>o.pickTarget(e,{signal:t.signal,assertCurrent:t.check}),cropUpload:(e,n)=>c.crop(e,n,{signal:t.signal,assertCurrent:t.check}),preparePending:e=>hr(e,{host:u,signal:t.signal,assertCurrent:t.check}),prepareTarget:(e,n,r,i)=>gr(e,n,r,{host:u,reuse:i,signal:t.signal,assertCurrent:t.check})}}),t.check(),n.doc)),n},br=async(e,t=null,n=Ln.capture())=>{let r=async t=>nu(e,{deps:{assertCurrent:t.check,checkElement:Er,autoFind:async e=>{t.check();let n=await ue(e);return t.check(),n},applyElement:(e,n,r,i)=>Dr(e,n,r,i,{host:u,signal:t.signal,assertCurrent:t.check,validateDocument:q})}});if(t)return r(t);let i;return await Ln.run(e,`canvas images`,n,async e=>(i=await r(e),e.check(),i.doc)),i},xr=async(e,t=Rn.capture())=>{if(we.current)return e.meta?.qaConsistency===!1||gt.current?e:Rn.run(e,`style check`,t,async t=>{t.check();let n=nr(e),r=n?$n(e.strip,n):null;if(!r)return e;let i=e.strip.filter(t=>(t.kind===`base`||t.kind===`edit`)&&t.type!==`titleScreen`&&t.type!==`giphy`&&t.type!==`diagram`&&t.method!==`progressiveReveal`&&!t.revealOf&&t.image&&t.panelId!==n.panelId&&er(e,t.sceneId));if(!i.length)return e;let a;try{t.check(),{results:a}=await be({anchorUrl:r,panels:i.map(e=>({panelId:e.panelId,url:e.image})),styleText:Qn(e,n.sceneId).styleBlock}),t.check()}catch(n){if(t.check(),n?.name===`AbortError`)throw n;return X.error?.(`Style check failed (build kept): ${n?.message||n}`),e}if(a&&!Array.isArray(a))return X.error?.(`Style check returned an invalid result (build kept).`),e;let o=(a||[]).filter(e=>e&&e.consistent===!1);if(!o.length)return e;let s=new Set(i.map(e=>e.panelId)),c;try{c=await Fr(e,o,s,{host:u,mode:`warnings`,signal:t.signal,assertCurrent:t.check})}catch(n){return t.check(),X.error?.(`Style check failed (build kept): ${n.message||n}`),e}t.check(),await t.commit(c),X.success?.(`${o.length} off-style panel(s) — regenerating once with the style anchor`);let l=Ce(Lt,Mn);t.check();let{doc:d,errors:f}=await Xr(c,{generate:async(...e)=>{t.check();let n=await l(...e);return t.check(),n},only:o.map(e=>e.panelId),force:!0,shouldCancel:()=>(t.check(),!1)});return t.check(),c=await Fr(d,o,s,{host:u,mode:`refresh`,signal:t.signal,assertCurrent:t.check}),t.check(),f.length&&X.error?.(`${f.length} style regen(s) failed — those panels keep their style warning.`),c})},[Sr,Cr]=(0,v.useState)(null),wr=v.useRef(null),Tr=async(e,t,n,r)=>{r.check();let i=nr(e),a=n??i?.sceneId,o=Qn(e,a).sheets[t]||$r(e,t);if(!o)throw Error(`No description for \"${t}\".`);let s=Qn(e,a).styleRefs.slice(0,6),c=Ce(Lt,Mn);r.check();let l;try{({url:l}=await c({prompt:Yr(e,t,o),referenceImages:s,aspectRatio:`1:1`}))}catch(e){throw r.check(),Object.assign(Error(e?.message||`Reference generation failed.`),{referenceProviderFailure:!0})}return r.check(),await Lr(e,t,l,{host:u,signal:r.signal,check:r.check,validateDocument:q})},Or=async(e,t=null)=>{if(!we.current||wr.current)return;let n=Symbol(`reference-sheet`);wr.current=n;try{await zn.run(h,e,zn.capture(),async n=>{n.check();let r=await Yo.confirm(`Generate a ${e.toUpperCase()} reference sheet (~${Wn} cr)? It's drawn from your style references + its description, and attached to every panel whose beat uses this sheet; built bases that use it get flagged to refresh.`,{title:`Reference sheet`,confirmText:`Generate`});if(n.check(),!r)return h;Cr(e);let i=await Tr(h,e,t,n);return await n.commit(i),n.check(),X.success?.(`${e.toUpperCase()} reference sheet updated`),i})}catch(e){e?.name!==`AbortError`&&X.error?.(e?.message||`Reference sheet generation failed`)}finally{wr.current===n&&(wr.current=null,Cr(null))}},kr=async({ids:e=null,confirmed:t=!1}={})=>{if(!we.current||wr.current)return!1;let n=Symbol(`reference-sheets`);wr.current=n;let r=!1;try{return await zn.run(h,`*`,zn.capture(),async n=>{n.check();let i=h.meta?.castRefs||{},a=(e||[...ei(h,{force:!0})]).filter(e=>!i[e]&&$r(h,e));if(!a.length)return X.info?.(`All reference sheets are already built.`),r=!0,h;if(!t){let e=await Yo.confirm(`Generate ${a.length} reference sheet${a.length===1?``:`s`} (${a.map(e=>e.toUpperCase()).join(`, `)}) — ~${Wn*a.length} cr? Each is drawn from your style references + its description, so you can review the cast before building any panels.`,{title:`Generate all refs`,confirmText:`Generate`});if(n.check(),!e)return h}let o=h,s=0,c=0;for(let e of a){if(n.check(),gt.current)break;Cr(e);let t;try{t=await Tr(o,e,null,n)}catch(e){if(n.check(),!e?.referenceProviderFailure)throw e;s++;continue}await n.commit(t),n.check(),o=t,c++}return s?X.error?.(`${s} reference sheet(s) failed — Make ref on them individually to retry.`):c===a.length&&X.success?.(`${c} reference sheet${c===1?``:`s`} built — review them, then Build the image panels.`),r=s===0&&c===a.length,o}),r}catch(e){return e?.name!==`AbortError`&&X.error?.(e?.message||`Reference sheet generation failed`),!1}finally{wr.current===n&&(wr.current=null,Cr(null))}},Ar=async(e={})=>{if(!we.current)return;let t=ze.capture(),n=Nn.capture(),r=Vn.capture(),i=Rn.capture(),a=Ln.capture(),o=In.capture(),s=null;if(M&&!yt.current&&!e.gifsReviewed&&Rf(h)){vt(!0);return}let c=ni(h),l=ri(h),d=ii(h),f=Jo(h),p=Yl(h).length,m=tu(h).length;if(!c&&!l&&!d&&!f&&!p&&!m)return;let g=ti(h),_=ti(h,{force:!0}),v=!1;if(l>0){let e=(e,t)=>Wn*(e+t)+(h.meta?.qaConsistency!==!1&&e>0&&h.strip.length>1?V[`panel:qa`]:0),t=c+l,n=[];c>0&&n.push({label:`Build missing — ${c} panel${c===1?``:`s`} · ~${e(c,g)} cr`,value:`missing`,tone:`warning`}),n.push({label:`Rebuild all — ${t} panel${t===1?``:`s`} · ~${e(t,_)} cr`,value:`all`});let r=await Yo.choose(`${l} panel${l===1?` is`:`s are`} already built${c?`, ${c} still need an image`:``}. Rebuild every panel from scratch, or only generate the missing ones? Rebuilding regenerates finished panels and charges for them again.`,n,{title:`Build image panels`});if(!r)return;v=r===`all`}let y=v?c+l:c,b=v?_:g;if(b>0&&y>0){let e=await Yo.choose(`${b} reference sheet${b===1?` isn't`:`s aren't`} built yet. Build the refs first so you can review the cast before the panels generate, or build everything together?`,[{label:`Generate refs first — ${b} sheet${b===1?``:`s`} · ~${Wn*b} cr`,value:`refs`},{label:`Build refs + panels together`,value:`together`}],{title:`Reference sheets first?`});if(!e)return;if(e===`refs`){gt.current=!1,await kr({ids:[...ei(h,{force:v})],confirmed:!0});return}}let x=h.meta?.qaConsistency!==!1&&y>0&&h.strip.length>1,S=Wn*(y+b)+(x?V[`panel:qa`]:0),C=[y?`${y} panel${y===1?``:`s`}`:null,b?`${b} reference sheet${b===1?``:`s`} (identity lock for the cast)`:null,d?`${d} reveal frame${d===1?``:`s`} (rendered free from their base image)`:null,f?`${f} reaction GIF${f===1?``:`s`} (cached to your project, free)`:null].filter(Boolean).join(` + `),w=x?` A style-consistency check runs after the build (${V[`panel:qa`]} cr; off-style panels regenerate once at ${Wn} cr each).`:``,T=N&&qs(h),E=T?` A presenter host also generates with this batch (about 2 pose sheets · ~${Wn*2} cr).`:``;if(!(l>0||!y&&!d&&!f&&!T||await Yo.confirm(`Build ${C||`the presenter host`} with ${ie.find(e=>e.value===Lt)?.label||Lt} (~${S} credits)? The first base panel generates first and anchors the art style for every other panel; each lineage then builds in order while separate lineages generate in parallel. Labels are placed by a vision pass after their frames finish.${w}${E}`,{title:`Build image panels`,confirmText:`Build`})))return;gt.current=!1,ht(!0),window.__smBusy=!0,Qt({done:0,total:y});let D=0;try{let e=h;if(y){let{doc:t,errors:n}=await Xr(e,{generate:Ce(Lt,Mn),force:v,onProgress:()=>Qt({done:++D,total:y}),onPanelDone:(e,t)=>W(n=>n&&n.strip?{...n,strip:n.strip.map(n=>n.panelId===e?{...n,image:t,needsRefresh:!1}:n)}:n),onSheetDone:(e,t)=>W(n=>n&&{...n,meta:{...n.meta||{},castRefs:{...n.meta?.castRefs||{},[e]:t}}}),shouldCancel:()=>gt.current});if(e=t,W(e),gt.current){X.success?.(`Build cancelled — finished panels were kept.`);return}n.length&&X.error?.(`${n.length} panel(s) failed — fix their prompts and build again (only missing panels regenerate).`)}if(f&&(Fn(!1),e=await Nn.run(e,`mirrors`,n,async t=>(t.check(),await qo(e,{actor:n.actor,assertCurrent:t.check,shouldCancel:()=>gt.current,deps:{collectRefs:e=>ge(e,{...t,host:u}),applyRemap:(e,n)=>_e(e,n,{...t,host:u})}}))),gt.current)){X.success?.(`Build cancelled — finished panels were kept.`);return}for(let t of Jl(e)){if(gt.current)break;e=await _r(e,t,r)}if(gt.current){X.success?.(`Build cancelled — finished panels were kept.`);return}if(y&&h.meta?.qaConsistency!==!1&&!gt.current&&(e=await xr(e,i)),gt.current){X.success?.(`Build cancelled — finished panels were kept.`);return}if(Yl(e).length&&!gt.current){let t=await yr(e,o);e=t.doc,t.failed.length&&X.error?.(`${t.failed.length} zoom panel(s) could not process — they play as their source frame for now.`)}if(gt.current){X.success?.(`Build cancelled — finished panels were kept.`);return}if(tu(e).length&&!gt.current){let t=await br(e,null,a);e=t.doc,t.failed.length&&X.error?.(`${t.failed.length} canvas image(s) could not be sourced — open the canvas editor to pick or generate them.`)}if(gt.current){X.success?.(`Build cancelled — finished panels were kept.`);return}if(N&&!gt.current)try{if(qs(e)&&X.info?.(`Generating the presenter host…`),s=await ze.begin(e,t,()=>gt.current),e=s.doc,s.error)throw s.error}catch(e){if(e?.name===`AbortError`)throw e;X.error?.(`Presenter host couldn't generate — set it up on this step and rebuild. (${e?.message||e})`)}if(gt.current){X.success?.(`Build cancelled — finished panels were kept.`);return}s?.check();let c=s?await mr(e,s):await Be.run(e,t,t=>mr(e,t));if(!c)throw Object.assign(Error(`Text placement is busy.`),{name:`AbortError`});let{doc:l,placed:d}=c;s?.check(),d&&s&&await s.commitAndWait(l),X.success?.(`Image panels built`)}catch(e){e?.name!==`AbortError`&&await Yo.alert(`Build failed: ${e?.message||e}`,{title:`Build failed`})}finally{s?.finish(),ht(!1),Qt(null),gt.current=!1,window.__smBusy=!1}},jr=async e=>{if(!we.current)return;let t=h.strip.find(t=>t.panelId===e);if(!t||t.type!==`canvas`)return;if(!bn.length){X.error?.(`Canvas auto-build needs the voiceover word timings.`);return}if(Cn.current)return;let n=Symbol(`canvas-plan`);Cn.current=n,At(e);try{await wn.run(e,async n=>{n.check();let r=n.words,i=e=>Math.round(Number(e.startMs??e.start*1e3)||0),a=Number.isFinite(Number(t.wordStart))?Number(t.wordStart):null,o=Number.isFinite(Number(t.wordEnd))?Number(t.wordEnd):null;if(a==null||o==null){let e=t.startMs+t.durationMs;a=r.findIndex(e=>i(e)>=t.startMs),a<0&&(a=Math.max(0,r.length-1)),o=a;for(let t=a;t<r.length&&i(r[t])<e;t++)o=t}let s=await ve({words:r,spans:[{wordStart:a,wordEnd:o}],strip:h.strip.filter(e=>e.type===`panel`).map(e=>({panelId:e.panelId,wordStart:e.wordStart,wordEnd:e.wordEnd,brief:e.prompt})),lean:O||void 0,modelTier:`standard`});n.check();let c=s[0]?.events||[];if(!c.length){X.error?.(`The planner found nothing to place on this stretch — add elements by hand in the canvas editor.`);return}let l=ur(h,e,{autoArrange:!0,events:c});l=q(await pa(l,n.words,{host:u,signal:n.signal,assertCurrent:n.check})),await n.commitAndWait(l);let d=await br(l,n);n.check(),await n.commitAndWait(d.doc),d.failed.length&&X.error?.(`${d.failed.length} image(s) could not be sourced — pick or generate them in the canvas editor.`),n.check(),Ct(e)})}catch(e){Cn.current===n&&e?.name!==`AbortError`&&X.error?.(e?.message||`Canvas auto-build failed`)}finally{Cn.current===n&&(Cn.current=null,At(null))}},Mr=async({fx:e,fy:t,scale:n})=>{let r=Dt?.panelId;r&&await Hn.run(r,{fx:e,fy:t,scale:n},async e=>{e.check();let t=e.doc;Ot(null);let n=e.downstream;if(!n.length){X.success?.(`Zoom updated — nothing builds on it yet.`);return}let r=n.reduce((e,t)=>{let n=Yn(t);return e+oe(n.model,1,n)},0);e.check();let i=await Yo.choose(`The new framing is what the rest of this progression builds on. Regenerate the ${n.length} downstream panel${n.length===1?``:`s`} from it?`,[{label:`Regenerate ${n.length} panel${n.length===1?``:`s`} · ~${r} cr`,value:`regen`},{label:`Leave them (mark stale)`,value:`stale`}],{title:`Zoom changed`});if(e.check(),i===`regen`){e.report({done:0,total:n.length});{let{doc:r,errors:i}=await Qr(t,n,{generateFor:t=>{e.check();let n=Yn(t),r=Ce(n.model,n);return async(...t)=>{e.check();let n=await r(...t);return e.check(),n}},onProgress:e.report,shouldCancel:()=>(e.check(),!1)});e.check(),await e.commit(r),e.check(),i.length?X.error?.(`${i.length} panel(s) failed to regenerate — they stay flagged; fix and regenerate individually.`):X.success?.(`Progression regenerated from the new framing.`)}}else await e.markStale(),e.check(),X.success?.(`${n.length} downstream panel${n.length===1?``:`s`} marked \"may need refresh\".`)})},Pr=async(e,{strict:t=!1}={})=>{if(!we.current||G.current)return;let n=Bn.capture();xt(e);let r=[];try{await Bn.run(h,e,n,async n=>{n.check();let i=Yn(e),a=Ce(i.model,i),o=await si(t?ur(h,e,{styleStrict:!0}):h,e,{host:u,generate:a,signal:n.signal,assertCurrent:n.check});return n.check(),r=o.flagged,o.doc}),X.success?.(r.length?`${e} regenerated — ${r.length} downstream panel(s) may need refresh`:`${e} regenerated`)}catch{}finally{xt(null)}},Ir=async e=>{if(!we.current||Ve.current)return;let t=Symbol(`text-placement`);Ve.current=t,xt(e);try{(await Be.run(h,Be.capture(),async({signal:t,check:n})=>{n();let r=h.strip.find(t=>t.panelId===e);if(!r?.image)throw Error(`Build this frame first — the text pass waits for the finished image.`);let i=r.textOverlays||[],a=i.map((e,t)=>({o:e,idx:t})).filter(({o:e})=>!e.pos),o=a.map(({o:e})=>e.arrow?.pointsAt?{text:e.text,pointsAt:e.arrow.pointsAt}:e.text);if(!o.length)return{doc:h,placed:0};n();let s=await pe({imageUrl:$n(h.strip,r)||r.image,texts:o});n();let c=await Ni(i,a.map(({idx:e})=>e),s,new Map,{mode:`single`,signal:t,assertCurrent:n,host:u});return n(),{doc:ar(h,e,c),placed:1}}))?.placed&&Ve.current===t&&X.success?.(`${e}: text placement prepared`)}catch(e){Ve.current===t&&(e?.name===`AbortError`?X.info?.(`Text placement was not applied because its document or account changed.`):X.error?.(e?.message||`Text placement failed`))}finally{Ve.current===t&&(Ve.current=null,xt(null))}},zr=async e=>{if(!we.current||G.current)return;let t=Bn.capture();xt(e);try{await Bn.run(h,e,t,async t=>{t.check();let n=await Te(h,e,{host:u,signal:t.signal,assertCurrent:t.check,validateDocument:q});t.check(),await t.commit(n),t.check();let r=Yn(e),i=await si(n,e,{host:u,generate:Ce(r.model,r),signal:t.signal,assertCurrent:t.check});return t.check(),i.doc}),X.success?.(`${e} is now a real shot — edit its prompt like any panel`)}catch{}finally{xt(null)}},Br=()=>{an||cn(re({actor:R()})),on(e=>!e)},Vr=e=>Re.apply(e,(e,t)=>Yo.confirm(e,t),()=>on(!1)),Hr=async e=>{if(!we.current)return;let t=Array.from(e||[]).filter(Boolean);if(t.length){un(!0);try{let e=e=>new Promise((t,n)=>{let r=new FileReader;r.onload=()=>t(r.result),r.onerror=()=>n(Error(`could not read the file`)),r.readAsDataURL(e)}),n=[];for(let r of t){let t=await de(await e(r));t&&n.push(t)}n.length&&await Vr({styleRefs:n,name:t.length>1?`${n.length} style images`:`Style image`,builtin:!1})}catch(e){X.error?.(e?.message||`Upload failed`)}finally{un(!1),vn.current&&(vn.current.value=``)}}},Ur=e=>Ke.insert(e),Wr=async(e,t,n,r={})=>{if(!we.current)return;let i=h.strip.findIndex(t=>t.panelId===e),a=h.strip[i+1],o=$n(h.strip,h.strip[i]),s=a?$n(h.strip,a):null;if(!o||!s){X.error?.(`Both panels need images first`);return}let c=pn.find(e=>e.id===t)||pn[0],l=(c.resolutions||[c.resolution]).includes(r.resolution)?r.resolution:c.resolution,u=c.id===`veo-3.1-lite`&&l===`1080p`?8:hn(c.id,n),d=r.fit!==!1,f=(c.aspects||[]).includes(r.aspect)?r.aspect:h.meta?.aspect||`16:9`;await ke.change(e,`generated`,null,async e=>{e();let{map:t}=await ne([o,s],`upscale`,{actor:Le,assertCurrent:e}).catch(()=>({map:new Map}));e();let n=await Se({model:c.id,readablePrompt:`Seamless in-scene transition: animate smoothly and continuously from the first frame to the last frame. Same scene, same characters, natural motion, no cuts, no camera shake.`,firstFrameUrl:t.get(o)||o,lastFrameUrl:t.get(s)||s,duration:u,resolution:l,aspectRatio:f,generateAudio:!1});return e(),{model:c.id,durationSec:u,video:n.url,srcKey:Sn(o,s,c.id,u),genSeconds:u,fit:d,generatedAt:new Date().toISOString()}})&&(Pt(null),X.success?.(`Animated transition generated — it plays across the cut`))},Gr=async(e,t)=>{let n=await t.save(e);return n.flagged&&X.success?.(`${tn} updated — ${n.flagged} downstream panel(s) may need refresh`),n},Kr=(e,t)=>{try{let n=h.strip.find(t=>t.panelId===e),r=cr(n).lastIndexOf(n.image);Ye.select(e,r+t)}catch(e){X.error?.(e?.message||String(e))}},Jr=Ae.pending,ai=(e,t)=>Ze.choose(e,`mode`,t),oi=(e,t)=>Ze.choose(e,`candidate`,t),ci=(e,t)=>Xe.move(e,t),li=e=>Ge.remove(e),ui=e=>Ae.change(e,`remove`),di=(e,t,{overlay:n=!1}={})=>Ae.change(e,n?`overlay`:`replace`,t,ye,e=>X.info?.(e)),mi={setMode:ai,swapCandidate:oi,searchSwap:di,del:li,move:ci,removeOverlay:ui},hi=h?ni(h):0,gi=h?ri(h):0,_i=h?ii(h):0,vi=h?Jo(h):0,bi=h?ti(h):0,xi=h&&hi===0,J=!we.current||!!Nn.pending||!!In.pending||wn.canceling||!!Ln.pending||!!Rn.pending||!!zn.pending||!!Bn.pending||!!Vn.pending||!!Oe.pending||Hn.pending||!!ke.pending||!!rn.pending||!!Ae.pending||!!Pe.pending||!!Re.pending||mt||!!bt||!!We.pending||!!Ge.pending||!!Ke.pending||!!qe.pending||!!Je.pending||!!Ye.pending||!!Xe.pending||!!Ze.pending||!!K.pending||!!Qe.pending||!!$e.pending||!!et.pending||!!tt.pending||!!nt.pending,Si=$t?.panelId?h?.strip.find(e=>e.panelId===$t.panelId):null;b({dependencies:[h,J,U.canEdit,lr.ready,ct],actions:[{id:`plan_panels`,label:`Plan image panels`,effect:`run`,available:()=>!h&&lr.ready&&!ct&&!J&&U.canEdit===!0,parameters:{type:`object`,additionalProperties:!1,properties:{}},parse:e=>{if(h||!lr.ready||ct||J||U.canEdit!==!0||!e||Object.keys(e).length)throw Error(lr.ready?`Image panels are already planned or planning.`:lr.reason||`Make the voiceover and its timing first.`);return{}},review:()=>({description:`Plan the whole run of image panels from the narration and its timing.`,confirmLabel:`Plan panels`,notes:[`About ${V[`strip:plan`]} credits`]}),run:async()=>(await pr(!1),{status:`completed`,message:`Started planning the image panels; they appear in Image Panels when the plan is ready.`})},...x({doc:h,busy:J,canEdit:U.canEdit===!0,methods:De,change:Oe.change,cancel:Oe.cancel})]});let wi=$t?.styleRef?typeof $t.styleRef==`string`?$t.styleRef:Ri[0]||h?.meta?.styleRef:Si?$n(h.strip,Si):null,Ti=tn?h?.strip.find(e=>e.panelId===tn):null,[Ei,Di]=(0,v.useState)({}),ki=(0,v.useMemo)(()=>{if(!h)return[];let e=[];for(let t of h.strip){let n=e[e.length-1];!n||n.sceneId!==t.sceneId?e.push({sceneId:t.sceneId,entries:[t]}):n.entries.push(t)}return e},[h]),Ai=(0,v.useMemo)(()=>Me(h?{...h,projectType:O}:null),[h,O]),ji=Pe.change,[Mi,Pi]=(0,v.useState)(null),Ii=Mi?h?.strip.find(e=>e.panelId===Mi):null,Li=Ii?qr(h,Ii):null,Ri=h?h.meta?.styleRefs?.length?h.meta.styleRefs:h.meta?.styleRef?[h.meta.styleRef]:[]:[],zi=!!h?.meta?.styleRefsHidden||Ri.length>0&&Ri.every(e=>Lf.has(e)),Y=zi?[]:Ri;return(0,D.jsxs)(`div`,{style:{flex:1,overflowY:`auto`},children:[(0,D.jsx)(Go,{live:{...U,owner:U.owner&&!!h}}),We.pending&&(0,D.jsxs)(`p`,{role:`status`,children:[`Updating panel narration… `,(0,D.jsx)(`button`,{type:`button`,onClick:We.cancel,children:`Cancel edit`})]}),We.error&&(0,D.jsx)(`p`,{role:`alert`,children:We.error}),Ge.pending&&(0,D.jsxs)(`p`,{role:`status`,children:[`Deleting panel and repairing the strip… `,(0,D.jsx)(`button`,{type:`button`,onClick:Ge.cancel,children:`Cancel deletion`})]}),Ge.error&&(0,D.jsx)(`p`,{role:`alert`,children:Ge.error}),Ke.pending&&(0,D.jsxs)(`p`,{role:`status`,children:[`Inserting panel and updating strip timing… `,(0,D.jsx)(`button`,{type:`button`,onClick:Ke.cancel,children:`Cancel insertion`})]}),Ke.error&&(0,D.jsx)(`p`,{role:`alert`,children:Ke.error}),qe.pending&&(0,D.jsxs)(`p`,{role:`status`,children:[`Restoring panels and repairing their references… `,(0,D.jsx)(`button`,{type:`button`,onClick:qe.cancel,children:`Cancel restoration`})]}),qe.error&&(0,D.jsx)(`p`,{role:`alert`,children:qe.error}),Je.pending&&(0,D.jsxs)(`p`,{role:`status`,children:[`Inserting zoom and updating its source chain… `,(0,D.jsx)(`button`,{type:`button`,onClick:Je.cancel,children:`Cancel zoom insertion`})]}),Je.error&&(0,D.jsx)(`p`,{role:`alert`,children:Je.error}),Ye.pending&&(0,D.jsxs)(`p`,{role:`status`,children:[`Selecting saved frame and updating its source chain… `,(0,D.jsx)(`button`,{type:`button`,onClick:Ye.cancel,children:`Cancel version change`})]}),Ye.error&&(0,D.jsx)(`p`,{role:`alert`,children:Ye.error}),Xe.pending&&(0,D.jsxs)(`p`,{role:`status`,children:[`Moving GIF beat and updating strip timing… `,(0,D.jsx)(`button`,{type:`button`,onClick:Xe.cancel,children:`Cancel move`})]}),Xe.error&&(0,D.jsx)(`p`,{role:`alert`,children:Xe.error}),Ze.pending&&(0,D.jsxs)(`p`,{role:`status`,children:[`Updating GIF choice… `,(0,D.jsx)(`button`,{type:`button`,onClick:Ze.cancel,children:`Cancel choice`})]}),Ze.error&&(0,D.jsx)(`p`,{role:`alert`,children:Ze.error}),K.pending&&(0,D.jsxs)(`p`,{role:`status`,children:[`Updating zoom target… `,(0,D.jsx)(`button`,{type:`button`,onClick:K.cancel,children:`Cancel target change`})]}),K.error&&(0,D.jsx)(`p`,{role:`alert`,children:K.error}),Qe.pending&&(0,D.jsxs)(`p`,{role:`status`,children:[`Updating panel lineage… `,(0,D.jsx)(`button`,{type:`button`,onClick:Qe.cancel,children:`Cancel lineage edit`})]}),Qe.error&&(0,D.jsx)(`p`,{role:`alert`,children:Qe.error}),$e.pending&&(0,D.jsxs)(`p`,{role:`status`,children:[`Updating text overlay… `,(0,D.jsx)(`button`,{type:`button`,onClick:$e.cancel,children:`Cancel text edit`})]}),$e.error&&(0,D.jsx)(`p`,{role:`alert`,children:$e.error}),et.pending&&(0,D.jsxs)(`p`,{role:`status`,children:[`Updating reveal plan… `,(0,D.jsx)(`button`,{type:`button`,onClick:et.cancel,children:`Cancel reveal edit`})]}),et.error&&(0,D.jsx)(`p`,{role:`alert`,children:et.error}),tt.pending&&(0,D.jsxs)(`p`,{role:`status`,children:[`Updating cast descriptions… `,(0,D.jsx)(`button`,{type:`button`,onClick:tt.cancel,children:`Cancel cast edit`})]}),tt.error&&(0,D.jsx)(`p`,{role:`alert`,children:tt.error}),rn.pending&&(0,D.jsxs)(`p`,{role:`status`,children:[`Saving edited panel image… `,(0,D.jsx)(`button`,{type:`button`,className:`btn btn-secondary`,onClick:rn.cancel,children:`Cancel image save`})]}),rn.error&&(0,D.jsx)(`p`,{role:`alert`,children:rn.error}),ke.pending&&(0,D.jsxs)(`p`,{role:`status`,children:[`Updating panel animation… `,(0,D.jsx)(`button`,{type:`button`,className:`btn btn-secondary`,onClick:ke.cancel,children:`Cancel animation update`})]}),ke.error&&(0,D.jsx)(`p`,{role:`alert`,children:ke.error}),Oe.pending&&(0,D.jsxs)(`p`,{role:`status`,children:[`Updating generation settings… `,(0,D.jsx)(`button`,{type:`button`,className:`btn btn-secondary`,onClick:Oe.cancel,children:`Cancel settings edit`})]}),Oe.error&&(0,D.jsx)(`p`,{role:`alert`,children:Oe.error}),Ae.pending&&(0,D.jsxs)(`p`,{role:`status`,children:[`Updating GIF… `,(0,D.jsx)(`button`,{type:`button`,className:`btn btn-secondary`,onClick:Ae.cancel,children:`Cancel GIF update`})]}),Ae.error&&(0,D.jsx)(`p`,{role:`alert`,children:Ae.error}),Pe.pending&&(0,D.jsxs)(`p`,{role:`status`,children:[`Updating scene settings… `,(0,D.jsx)(`button`,{type:`button`,className:`btn btn-secondary`,onClick:Pe.cancel,children:`Cancel scene edit`})]}),Pe.error&&(0,D.jsx)(`p`,{role:`alert`,children:Pe.error}),Re.pending&&(0,D.jsxs)(`p`,{role:`status`,children:[`Updating project style… `,(0,D.jsx)(`button`,{type:`button`,className:`btn btn-secondary`,onClick:Re.cancel,children:`Cancel style update`})]}),Re.error&&(0,D.jsx)(`p`,{role:`alert`,children:Re.error}),zn.pending&&(0,D.jsxs)(`p`,{role:`status`,children:[zn.canceling?`Canceling reference generation; waiting for the current request to finish…`:`Generating reference sheets…`,` `,(0,D.jsx)(`button`,{type:`button`,disabled:zn.canceling,onClick:zn.cancel,children:`Cancel references`})]}),zn.error&&(0,D.jsx)(`p`,{role:`alert`,children:zn.error}),Nn.pending&&(0,D.jsxs)(`p`,{role:`status`,children:[Pn?`Finishing the current GIF mirror…`:`Caching GIF assets…`,` `,(0,D.jsx)(`button`,{type:`button`,disabled:Pn,onClick:()=>{gt.current=!0,Fn(!0)},children:`Stop after this GIF`})]}),Nn.error&&(0,D.jsx)(`p`,{role:`alert`,children:Nn.error}),Ne.pending&&(0,D.jsxs)(`p`,{role:`status`,children:[`Updating document settings… `,!Ne.pending.endsWith(`-applying`)&&(0,D.jsx)(`button`,{type:`button`,onClick:Ne.cancel,children:`Cancel settings change`})]}),Ne.error&&(0,D.jsx)(`p`,{role:`alert`,children:Ne.error}),rt?.status===`planning`&&rt.actorId===R()&&(0,D.jsxs)(`p`,{role:`status`,children:[`Planning image panels… `,(0,D.jsx)(`button`,{type:`button`,onClick:()=>bl(P),children:`Cancel planning`})]}),kl(P,R())&&kl(P,R())!==h&&(0,D.jsxs)(`p`,{role:`status`,children:[`A completed image panel plan is retained. `,(0,D.jsx)(`button`,{type:`button`,onClick:pt,disabled:U.canEdit===!1,children:`Review completed plan`})]}),kt&&(0,D.jsxs)(`p`,{role:`status`,children:[`Building canvas… `,(0,D.jsx)(`button`,{type:`button`,onClick:()=>{Cn.current=null,wn.cancel(),At(null)},children:`Cancel canvas build`})]}),nt.pending&&(0,D.jsxs)(`p`,{role:`status`,children:[`Creating canvas… `,(0,D.jsx)(`button`,{type:`button`,onClick:nt.cancel,children:`Cancel canvas creation`})]}),nt.error&&(0,D.jsx)(`p`,{role:`alert`,children:nt.error}),(0,D.jsxs)(`div`,{style:{maxWidth:940,margin:`0 auto`,padding:Jt?`16px 12px 80px`:`24px 20px 80px`,fontFamily:`var(--font)`},children:[(0,D.jsx)(`h2`,{style:{margin:`0 0 4px`,color:`var(--text-primary)`},children:`Image Panels`}),(0,D.jsx)(`p`,{style:{margin:`0 0 16px`,fontSize:13,color:`var(--text-secondary)`},children:`Your video as a sequence of still panels cut to the narration. Most panels EDIT the previous frame of their lineage (color chip) so characters and places stay identical; a base panel starts a new scene. Durations come from your voiceover timing.`}),h?.meta?.host?.enabled&&h.meta.host.poses?.length>0&&(0,D.jsxs)(`div`,{style:{display:`inline-flex`,alignItems:`center`,gap:7,padding:`4px 11px 4px 5px`,borderRadius:999,border:`1px solid var(--accent)`,background:`var(--bg-secondary)`,marginBottom:12,fontSize:12},children:[h.meta.host.poses[0]?.url&&(0,D.jsx)(`img`,{src:h.meta.host.poses[0].url,alt:``,style:{width:22,height:22,borderRadius:`50%`,objectFit:`cover`,background:`var(--bg-elevated)`}}),(0,D.jsx)(`span`,{style:{color:`var(--text-secondary)`},children:`Active host:`}),(0,D.jsx)(`strong`,{style:{color:`var(--text-primary)`},children:h.meta.host.name||`Host`}),(0,D.jsxs)(`span`,{style:{color:`var(--text-muted)`},children:[`· `,h.meta.host.poses.length,` poses`]})]}),N&&h&&(0,D.jsx)(`div`,{style:{marginBottom:14},children:(0,D.jsx)(Rs,{doc:h,onDocChange:W,voiceover:y,autoEnable:N,projectId:P,canEdit:U.canEdit!==!1})}),h?(0,D.jsxs)(D.Fragment,{children:[(0,D.jsxs)(`div`,{style:{display:`flex`,gap:8,alignItems:`center`,marginBottom:14,flexWrap:`wrap`},children:[(0,D.jsxs)(`span`,{style:{display:`inline-flex`,alignItems:`center`,gap:6,fontSize:12,color:`var(--text-secondary)`},children:[`Model`,(0,D.jsx)(`span`,{style:{...$,fontSize:11.5},children:[ie.find(e=>e.value===Lt)?.label||Lt,...kn.length?[An]:[],jn,`${Wn} cr/panel`].join(` · `)}),(0,D.jsx)(`button`,{className:`btn btn-secondary`,\"data-compact\":!0,style:{fontSize:11},disabled:J,onClick:()=>Wt(!0),\"data-icon-action\":`true`,\"aria-label\":`Edit`,title:`Edit`,children:(0,D.jsx)(k,{name:`edit`,size:18})}),(0,D.jsx)(`button`,{className:`btn btn-secondary`,\"data-compact\":!0,style:{fontSize:11,padding:`1px 7px`},\"aria-label\":`About the panel image model`,onClick:()=>Kt(e=>!e),children:`i`})]}),tr.length>0&&(0,D.jsxs)(`label`,{style:{display:`inline-flex`,alignItems:`center`,gap:6,fontSize:12,color:`var(--text-secondary)`},title:`The whole video's frame shape — changing it applies to newly generated panels`,children:[`Aspect`,(0,D.jsx)(ns,{value:Zn,onChange:e=>or(e.target.value),disabled:J||!!Ne.pending,style:{fontSize:12},children:[...new Set([Zn,...tr])].map(e=>(0,D.jsx)(`option`,{value:e,children:e},e))})]}),(0,D.jsxs)(`label`,{style:{display:`inline-flex`,alignItems:`center`,gap:6,fontSize:12,color:`var(--text-secondary)`},title:`Your project-type pick — sets the video's lean (chat + planner). Every technique stays available regardless.`,children:[`Type`,(0,D.jsxs)(ns,{value:O||``,disabled:J||!!Ne.pending,style:{fontSize:12},onChange:e=>Ne.change(`type`,e.target.value||null),children:[(0,D.jsx)(`option`,{value:``,children:`unset`}),je.map(e=>(0,D.jsx)(`option`,{value:e,children:e},e))]})]}),Ai.advisory&&(0,D.jsx)(Js,{glyph:`!`,color:`#d97706`,borderColor:`#d97706`,width:320,text:`Balance — ${Ai.advisory} (Advisory only — nothing is blocked.)`}),(0,D.jsxs)(`label`,{style:{display:`inline-flex`,alignItems:`center`,gap:5,fontSize:12,color:`var(--text-secondary)`},title:`After every build, one vision pass compares each panel to the anchor base's art style (${V[`panel:qa`]} cr); off-style panels regenerate once with the anchor attached.`,children:[(0,D.jsx)(`input`,{type:`checkbox`,checked:h.meta?.qaConsistency!==!1,disabled:J,onChange:e=>Ne.change(`quality`,e.target.checked)}),`Style check`]}),(0,D.jsx)(`button`,{className:`btn btn-primary`,disabled:J||!hi&&!gi&&!_i&&!vi&&!Yl(h).length,onClick:()=>Ar(),children:mt&&Zt?gt.current?`Cancelling…`:`Building ${Zt.done}/${Zt.total}…`:hi?`Build ${hi} panel${hi===1?``:`s`}${bi?` +${bi} ref${bi===1?``:`s`}`:``}${_i?` +${_i} free`:``}${vi?` +${vi} GIF${vi===1?``:`s`}`:``}${Xl(h)?` +${Xl(h)} zoom target${Xl(h)===1?``:`s`}`:``} · ~${Wn*(hi+bi)+(h.meta?.qaConsistency!==!1&&h.strip.length>1?V[`panel:qa`]:0)+Xl(h)*V.VISION_AUTO_ANALYZE_PER_IMAGE} cr`:_i?`Render ${_i} reveal frame${_i===1?``:`s`}${vi?` + cache ${vi} GIF${vi===1?``:`s`}`:``} · free`:vi?`Cache ${vi} reaction GIF${vi===1?``:`s`} · free`:Yl(h).length?`Process ${Yl(h).length} zoom${Yl(h).length===1?``:`s`} · ~${Xl(h)*V.VISION_AUTO_ANALYZE_PER_IMAGE} cr`:gi?`Rebuild ${gi} panel${gi===1?``:`s`}`:`All panels built`}),mt&&(0,D.jsx)(`button`,{type:`button`,className:`btn btn-secondary`,title:`Cancel the build — panels already generating finish and are kept; the rest are skipped (not charged)`,\"aria-label\":`Cancel build`,onClick:()=>{gt.current=!0,ze.cancel(),Be.cancel(),Vn.cancel(),Rn.cancel(),Ln.cancel(),In.cancel(),Qt(e=>e&&{...e})},\"data-icon-action\":`true`,children:(0,D.jsx)(k,{name:`x`,size:18})}),(0,D.jsxs)(`div`,{style:{position:`relative`,display:`inline-flex`},children:[(0,D.jsx)(`button`,{className:`btn btn-secondary`,disabled:ct||J,onClick:()=>Xt(e=>!e),children:ct?`Planning…`:`↺ Re-plan image panels ▾`}),Yt&&!ct&&(0,D.jsxs)(D.Fragment,{children:[(0,D.jsx)(`div`,{style:{position:`fixed`,inset:0,zIndex:50},onClick:()=>Xt(!1)}),(0,D.jsxs)(`div`,{style:{position:`absolute`,top:`calc(100% + 4px)`,left:0,zIndex:51,minWidth:Jt?0:240,background:`var(--bg-elev-2, var(--bg-secondary))`,border:`1px solid var(--border-strong, var(--border))`,borderRadius:8,boxShadow:`0 12px 36px rgba(0,0,0,0.45)`,overflow:`hidden`,...Jt?{maxWidth:`calc(100vw - 24px)`,whiteSpace:`normal`}:{whiteSpace:`nowrap`}},children:[(0,D.jsx)(`button`,{type:`button`,style:Wf,onClick:()=>{Xt(!1),pr(!0,`same`)},children:`↺ Re-plan (same density)`}),(0,D.jsx)(`button`,{type:`button`,style:Wf,onClick:()=>{Xt(!1),pr(!0,`more`)},children:`↑ More panels (~+35%)`}),(0,D.jsx)(`button`,{type:`button`,style:Wf,onClick:()=>{Xt(!1),pr(!0,`fewer`)},children:`↓ Fewer panels (~−30%)`})]})]})]}),(0,D.jsx)(`div`,{style:{flex:1}}),(0,D.jsx)(`button`,{className:`btn btn-primary`,disabled:J,onClick:async()=>{(xi||await Yo.confirm(`${hi} panel(s) have no image yet — they'll show as empty slots in the editor. Continue anyway?`,{confirmText:`Continue`}))&&(!vi||await Yo.confirm(`${vi} reaction GIF${vi===1?``:`s`} ${vi===1?`is`:`are`} not cached to your project yet — press Build first so ${vi===1?`it survives`:`they survive`} export. Continue anyway?`,{confirmText:`Continue`}))&&T?.()},children:`Update editor timeline`})]}),Gt&&(0,D.jsx)(`div`,{style:{fontSize:12,color:`var(--text-secondary)`,border:`1px solid var(--border)`,borderRadius:10,padding:`8px 12px`,background:`var(--bg-secondary)`,marginBottom:14,lineHeight:1.5},children:`This uses your account default image model. Tip: every panel is vectorized for free when you export, so cheaper settings often reach the same final look — use Edit to drop it lower and save credits, or raise it if a specific panel needs stronger settings.`}),Ut&&(0,D.jsx)(Hf,{policy:z,imageCost:oe,title:`Bulk generation settings — all panels`,applyLabel:`Apply to all panels`,panelId:`bulk`,value:{model:Lt,quality:An,resolution:jn},isOverridden:!1,onClose:()=>Wt(!1),onApply:e=>{if(e){try{L(e,{actor:Le})}catch(e){X.error(e.message||`Could not save generation settings.`);return}Rt(e.model),Bt(e.quality),Ht(e.resolution)}Wt(!1)}}),(0,D.jsxs)(`div`,{style:{display:`flex`,gap:12,border:`1px solid var(--border)`,borderRadius:12,padding:12,background:`var(--bg-secondary)`,marginBottom:14},children:[Y.length>0&&(0,D.jsxs)(`div`,{style:{display:`flex`,flexDirection:`column`,gap:4,alignSelf:`flex-start`},children:[(0,D.jsx)(`div`,{style:{display:`flex`,gap:4,flexWrap:`wrap`,width:124},children:Y.slice(0,4).map((e,t)=>(0,D.jsx)(`img`,{src:e,alt:`style reference ${t+1}`,onClick:()=>en({styleRef:e}),style:{width:Y.length>1?58:120,height:Y.length>1?58:`auto`,objectFit:`cover`,borderRadius:6,cursor:`zoom-in`}},e))}),Y.length>4&&(0,D.jsxs)(`div`,{style:{fontSize:10,color:`var(--text-secondary)`},children:[`+`,Y.length-4,` more reference`,Y.length-4>1?`s`:``]})]}),(0,D.jsxs)(`div`,{style:{flex:1,minWidth:0},children:[(0,D.jsxs)(`div`,{style:{display:`flex`,alignItems:`center`,gap:8,marginBottom:4},children:[(0,D.jsx)(`div`,{style:{fontSize:10,fontWeight:700,textTransform:`uppercase`,letterSpacing:`0.05em`,color:`var(--text-secondary)`},children:`Style reference`}),(0,D.jsx)(`div`,{style:{flex:1}}),(0,D.jsx)(`button`,{className:`btn btn-secondary`,\"data-compact\":!0,style:{fontSize:10.5,padding:`2px 8px`},disabled:J,onClick:Br,children:an?`Close`:`Change style`})]}),(0,D.jsx)(`div`,{style:{fontSize:12,color:`var(--text-primary)`,whiteSpace:`pre-wrap`,lineHeight:1.5},children:h.styleBlock}),(0,D.jsxs)(`div`,{style:{fontSize:11,color:`var(--text-secondary)`,marginTop:6},children:[`Base panels are generated from this locked style block`,Y.length?Y.length>6?` plus up to 6 of your ${Y.length} reference images`:` plus ${Y.length} reference image${Y.length>1?`s`:``}`:``,`; edit panels reference their source frame plus the style references every step, so the look re-anchors down each lineage instead of drifting.`]}),an&&(0,D.jsxs)(`div`,{style:{marginTop:10,borderTop:`1px solid var(--border)`,paddingTop:10,display:`flex`,flexDirection:`column`,gap:8},children:[(0,D.jsxs)(`div`,{style:{display:`flex`,gap:6,alignItems:`center`,flexWrap:`wrap`},children:[(0,D.jsx)(`span`,{style:{fontSize:10,fontWeight:700,textTransform:`uppercase`,letterSpacing:`0.05em`,color:`var(--text-secondary)`},children:`Defaults`}),Rr.map(e=>{let t=!e.builtin&&e.refs?.length;return(0,D.jsxs)(`button`,{className:`btn btn-secondary`,\"data-compact\":!0,style:{fontSize:11,padding:`3px 10px`,display:`inline-flex`,alignItems:`center`,gap:6},disabled:J,title:e.text,onClick:()=>Vr({text:e.text,styleRefs:e.refs||null,name:e.name,builtin:!!e.builtin}),children:[t?(0,D.jsx)(`img`,{src:e.refs[0],alt:``,style:{width:22,height:22,borderRadius:4,objectFit:`cover`}}):null,e.name]},e.id)}),(0,D.jsx)(`button`,{className:`btn btn-secondary`,\"data-compact\":!0,style:{fontSize:11,padding:`3px 10px`},disabled:J||ln,onClick:()=>vn.current?.click(),children:ln?`Uploading…`:`Use images…`}),(0,D.jsx)(`input`,{ref:vn,type:`file`,accept:`image/*`,multiple:!0,style:{display:`none`},onChange:e=>Hr(e.target.files)})]}),(0,D.jsxs)(`div`,{style:{display:`flex`,gap:6,alignItems:`center`,flexWrap:`wrap`},children:[(0,D.jsx)(`span`,{style:{fontSize:10,fontWeight:700,textTransform:`uppercase`,letterSpacing:`0.05em`,color:`var(--text-secondary)`},children:`Your styles`}),(0,D.jsx)(`button`,{className:`btn btn-secondary`,\"data-compact\":!0,style:{fontSize:11,padding:`3px 10px`},disabled:J,onClick:()=>fn(!0),children:`+ Create style…`}),sn.map(e=>{let t=e.selectedImageUrl||e.previewUrl||null,n=[t,...(e.images||[]).map(e=>e.url)].filter((e,t,n)=>e&&n.indexOf(e)===t);return(0,D.jsxs)(`button`,{className:`btn btn-secondary`,\"data-compact\":!0,disabled:J,title:`${e.stylePrompt||e.name}${n.length?`\\n\\n${n.length} reference image(s)`:``}`,style:{fontSize:11,padding:`3px 10px 3px 3px`,display:`inline-flex`,alignItems:`center`,gap:6},onClick:()=>Vr({text:e.stylePrompt||null,styleRefs:n.length?n:null,styleRef:t,name:e.name||`Saved style`}),children:[t&&(0,D.jsx)(`img`,{src:t,alt:``,style:{width:22,height:22,borderRadius:4,objectFit:`cover`}}),e.name||`Untitled`]},e.id)})]})]})]})]}),(0,D.jsx)(`div`,{style:{display:`flex`,flexDirection:`column`,gap:12},children:ki.map(e=>{let t=Xn(h,e.sceneId),n=(h.scenes||[]).length>1,r=!!Ei[e.sceneId],i=[...new Set(e.entries.filter(e=>e.lineageId).map(e=>e.lineageId))],a=e.entries.filter(e=>e.type!==`titleScreen`).length;return(0,D.jsxs)(`div`,{style:{display:`flex`,flexDirection:`column`,gap:10},children:[n&&(0,D.jsxs)(`div`,{style:{display:`flex`,gap:8,alignItems:`center`,flexWrap:`wrap`,border:`1px solid var(--border)`,borderRadius:12,padding:`8px 12px`,background:`var(--bg-secondary)`},children:[(0,D.jsx)(`button`,{className:`btn btn-secondary`,\"data-compact\":!0,style:{fontSize:11,padding:`2px 8px`},onClick:()=>Di(t=>({...t,[e.sceneId]:!r})),\"aria-label\":r?`Expand scene`:`Collapse scene`,children:r?`▸`:`▾`}),(0,D.jsx)(`span`,{style:{...$,textTransform:`uppercase`},children:e.sceneId}),(0,D.jsx)(Jf,{value:t?.title||``,placeholder:`scene title`,disabled:J,onCommit:t=>ji(e.sceneId,{title:t}),style:{fontWeight:700,width:220}}),(0,D.jsxs)(`label`,{style:{display:`inline-flex`,alignItems:`center`,gap:5,fontSize:11,color:`var(--text-secondary)`},children:[`Genre`,(0,D.jsxs)(ns,{value:t?.genre||``,disabled:J,style:{fontSize:11},onChange:t=>ji(e.sceneId,{genre:t.target.value||null}),children:[(0,D.jsx)(`option`,{value:``,children:`unset`}),(0,D.jsx)(`option`,{value:`story`,children:`story`}),(0,D.jsx)(`option`,{value:`explainer`,children:`explainer`})]})]}),(0,D.jsxs)(`span`,{style:$,children:[a,` panel`,a===1?``:`s`]}),(0,D.jsx)(`span`,{style:{flex:1}}),i.map(e=>(0,D.jsxs)(`label`,{style:{display:`inline-flex`,alignItems:`center`,gap:4,fontSize:10.5,color:`var(--text-secondary)`},title:`Persistent lineages carry their edit-chain (visual consistency) ACROSS scene boundaries — for a recurring narrator/host`,children:[(0,D.jsx)(`input`,{type:`checkbox`,checked:!!h.lineages[e]?.persistent,disabled:J,onChange:t=>Qe.change(`persistent`,e,t.target.checked)}),e,` persistent`]},e))]}),!r&&(0,D.jsx)(Gf,{doc:h,sceneId:e.sceneId,sceneLineages:i,disabled:J,onSheetsChange:tt.change,onRegenSheet:Or,onRegenAllSheets:e=>kr({ids:e}),busySheet:Sr}),!r&&e.entries.map(n=>(0,D.jsx)(Zo,{estimateHeight:260,rootMargin:`1200px`,children:()=>{if(n.type===`titleScreen`)return(0,D.jsx)(Yf,{entry:n,scene:t,disabled:J,onSceneChange:t=>ji(e.sceneId,t),onDelete:()=>Ge.remove(n.panelId)},n.panelId);let r=sr(h,n);if(n.type===`diagram`)return(0,D.jsxs)(`div`,{style:{display:`flex`,gap:12,alignItems:`center`,border:`1px dashed var(--border)`,borderRadius:12,padding:12,background:`var(--bg-secondary)`},children:[n.image?(0,D.jsxs)(`span`,{className:`sm-expand-host`,style:{display:`block`,flexShrink:0},children:[(0,D.jsx)(`img`,{src:n.image,alt:n.panelId,onClick:()=>en({panelId:n.panelId}),style:{width:200,borderRadius:8,display:`block`,cursor:`zoom-in`}}),(0,D.jsx)(Oc,{src:n.image,name:n.panelId,onOpen:()=>en({panelId:n.panelId})})]}):(0,D.jsx)(`div`,{style:{width:200,height:112,borderRadius:8,border:`1px dashed var(--border)`,display:`flex`,alignItems:`center`,justifyContent:`center`,fontSize:11,color:`var(--text-secondary)`},children:`legacy frame`}),(0,D.jsxs)(`div`,{style:{flex:1,minWidth:0,display:`flex`,flexDirection:`column`,gap:6},children:[(0,D.jsxs)(`div`,{style:{display:`flex`,gap:6,alignItems:`center`,flexWrap:`wrap`},children:[(0,D.jsx)(`strong`,{style:{color:`var(--text-primary)`,fontSize:13},children:n.panelId}),(0,D.jsx)(`span`,{style:{...$,textTransform:`uppercase`},children:`legacy composited frame`}),(0,D.jsxs)(`span`,{style:$,children:[(n.startMs/1e3).toFixed(2),`s → `,((n.startMs+n.durationMs)/1e3).toFixed(2),`s`]}),(0,D.jsx)(`span`,{style:{flex:1}}),(0,D.jsx)(`button`,{className:`btn btn-secondary`,\"data-compact\":!0,style:{fontSize:10.5,padding:`2px 8px`},disabled:J,onClick:()=>Ge.remove(n.panelId),\"data-icon-action\":`true`,\"aria-label\":`Delete`,title:`Delete`,children:(0,D.jsx)(k,{name:`trash`,size:18})})]}),r&&(0,D.jsxs)(`div`,{style:{fontSize:12,color:`var(--text-secondary)`,fontStyle:`italic`},children:[`SAYS `,r]}),(0,D.jsx)(`div`,{style:{fontSize:11,color:`var(--text-secondary)`},children:`Made with the retired element compositor — new diagram beats are fully generated images.`})]})]},n.panelId);if(n.kind===`revealStep`)return(0,D.jsxs)(`div`,{style:{display:`flex`,gap:12,alignItems:`center`,border:`1px solid var(--border)`,borderRadius:12,padding:12,background:`var(--bg-secondary)`,opacity:.94},children:[n.image?(0,D.jsxs)(`span`,{className:`sm-expand-host`,style:{display:`block`,flexShrink:0},children:[(0,D.jsx)(`img`,{src:n.image,alt:n.panelId,onClick:()=>en({panelId:n.panelId}),style:{width:200,borderRadius:8,display:`block`,cursor:`zoom-in`}}),(0,D.jsx)(Oc,{src:n.image,name:n.panelId,onOpen:()=>en({panelId:n.panelId})})]}):(0,D.jsxs)(`div`,{style:{width:200,height:112,borderRadius:8,border:`1px dashed var(--border)`,display:`flex`,alignItems:`center`,justifyContent:`center`,fontSize:11,color:`var(--text-secondary)`,textAlign:`center`,padding:`0 8px`},children:[`renders from `,n.revealOf]}),(0,D.jsxs)(`div`,{style:{flex:1,minWidth:0,display:`flex`,flexDirection:`column`,gap:7},children:[(0,D.jsxs)(`div`,{style:{display:`flex`,gap:6,alignItems:`center`,flexWrap:`wrap`},children:[(0,D.jsx)(`strong`,{style:{color:`var(--text-primary)`,fontSize:13},children:n.panelId}),(0,D.jsxs)(`span`,{style:{...$,display:`inline-flex`,alignItems:`center`,gap:5},children:[(0,D.jsx)(`span`,{style:{width:8,height:8,borderRadius:99,background:Tn[n.lineageId]}}),n.lineageId]}),(0,D.jsxs)(`span`,{style:{...$,textTransform:`uppercase`},children:[`reveal step `,Number(n.revealIndex)+1]}),(0,D.jsxs)(`span`,{style:$,children:[`reveals `,n.revealOf]}),(0,D.jsxs)(`span`,{style:$,children:[(n.startMs/1e3).toFixed(2),`s → `,((n.startMs+n.durationMs)/1e3).toFixed(2),`s · `,(n.durationMs/1e3).toFixed(2),`s`]}),(0,D.jsx)(`span`,{style:{flex:1}}),(0,D.jsx)(`button`,{className:`btn btn-secondary`,\"data-compact\":!0,style:{fontSize:10.5,padding:`2px 8px`},disabled:J||h.strip.length<=1,onClick:()=>Ge.remove(n.panelId),\"data-icon-action\":`true`,\"aria-label\":`Delete`,title:`Delete`,children:(0,D.jsx)(k,{name:`trash`,size:18})})]}),(0,D.jsx)(Vf,{value:r,disabled:J,onCommit:e=>We.edit(n.panelId,e)},`${n.panelId}-says-${r}`),(0,D.jsxs)(`div`,{style:{fontSize:11,color:`var(--text-secondary)`},children:[`Rendered free from `,n.revealOf,`'s finished diagram — not-yet-revealed elements are covered with the exact background color. Edit names/boxes/order on `,n.revealOf,` and Re-render.`]})]})]},n.panelId);if(n.type===`giphy`)return(0,D.jsx)(np,{p:n,says:r,disabled:J,busy:Jr===n.panelId,canDelete:h.strip.length>1,onSaysCommit:e=>We.edit(n.panelId,e),onSetMode:e=>ai(n.panelId,e),onSwapCandidate:e=>oi(n.panelId,e),onSearchSwap:e=>di(n.panelId,e),onMove:e=>ci(n.panelId,e),onDelete:()=>li(n.panelId),onView:()=>en({panelId:n.panelId})},n.panelId);if(n.type===`canvas`){let e=(n.elements||[]).filter(e=>e.kind===`image`).length,t=(n.elements||[]).filter(e=>e.kind===`text`).length,r=(n.elements||[]).filter(e=>e.kind===`image`&&!e.src).length,i=qt(n);return(0,D.jsxs)(`div`,{style:{display:`flex`,flexDirection:Jt?`column`:`row`,gap:12,alignItems:`stretch`,border:`1px dashed var(--border)`,borderRadius:12,padding:12,background:`var(--bg-secondary)`},children:[(0,D.jsx)(`div`,{style:{width:Jt?`100%`:200,minWidth:Jt?0:200},children:(0,D.jsx)(ip,{panel:n,onClick:()=>Ct(n.panelId)})}),(0,D.jsxs)(`div`,{style:{flex:1,minWidth:0,display:`flex`,flexDirection:`column`,gap:6},children:[(0,D.jsxs)(`div`,{style:{display:`flex`,gap:6,alignItems:`center`,flexWrap:`wrap`},children:[(0,D.jsx)(`strong`,{style:{fontSize:13},children:n.panelId}),(0,D.jsx)(`span`,{style:$,children:`CANVAS`}),(0,D.jsxs)(`span`,{style:$,children:[(n.startMs/1e3).toFixed(2),`s → `,((n.startMs+n.durationMs)/1e3).toFixed(2),`s · `,(n.durationMs/1e3).toFixed(2),`s`]}),(0,D.jsxs)(`span`,{style:$,children:[e,` image`,e===1?``:`s`,t?` · ${t} text`:``]}),(0,D.jsx)(`span`,{style:$,children:n.autoArrange?`self-arranging`:`hand-built`}),r>0&&(0,D.jsxs)(`span`,{style:{...$,color:`#d97706`,borderColor:`#d97706`},children:[r,` image`,r===1?``:`s`,` to source`]}),i.length>0&&(0,D.jsxs)(`span`,{style:{...$,color:`#d97706`,borderColor:`#d97706`},title:`A collage stretch with nothing appearing for over 2.5s — add a beat in the canvas editor (advisory)`,children:[i.length,` static stretch`,i.length===1?``:`es`]}),(0,D.jsx)(`span`,{style:{flex:1}}),(0,D.jsx)(`button`,{className:`btn btn-secondary`,\"data-compact\":!0,style:{fontSize:10.5,padding:`2px 8px`},disabled:J,onClick:()=>Ct(n.panelId),children:`Open canvas editor`}),(n.elements||[]).length===0&&(0,D.jsx)(`button`,{className:`btn btn-secondary`,\"data-compact\":!0,style:{fontSize:10.5,padding:`2px 8px`},disabled:J||kt===n.panelId,title:`The system drafts the collage from this stretch's narration — images pop in when their words are said, then stock photos fill them at build`,onClick:()=>jr(n.panelId),children:kt===n.panelId?`Drafting…`:`Auto-build ${se(V[`canvas:plan`])}`}),n.revert?.rows?.length>0&&(0,D.jsx)(`button`,{className:`btn btn-secondary`,\"data-compact\":!0,style:{fontSize:10.5,padding:`2px 8px`},disabled:J,title:`Turn this canvas back into the ${n.revert.rows.length} panel${n.revert.rows.length===1?``:`s`} it replaced — their frames and timings come back exactly`,onClick:async()=>{await qe.revert(n.panelId,()=>Yo.confirm(`Turn this canvas back into ${n.revert.rows.length} panel${n.revert.rows.length===1?``:`s`}? The canvas layout and any elements you added to it are discarded.`,{title:`Revert to panels`,confirmText:`Revert`}))&&X.success?.(`Reverted to the original panels`)},children:`Revert to panels`}),(0,D.jsx)(`button`,{className:`btn btn-secondary`,\"data-compact\":!0,style:{fontSize:10.5,padding:`2px 8px`},disabled:J||h.strip.length<=1,title:`Remove the canvas — its screen time returns to the previous beat`,onClick:()=>Ge.remove(n.panelId),\"data-icon-action\":`true`,\"aria-label\":`Remove the canvas — its screen time returns to the previous beat`,children:(0,D.jsx)(k,{name:`trash`,size:18})})]}),(0,D.jsxs)(`div`,{style:{fontSize:11,color:`var(--text-secondary)`},children:[`Collage canvas — images pop onto a `,n.background===`#ffffff`?`white`:`solid`,` background exactly when the narration names them, each with its own sound; text lands on emphasized words. `,n.autoArrange?`It keeps itself tidy as things appear; drag an element in the editor to pin it.`:`Your placements are exact — nothing moves unless you move it.`]})]})]},n.panelId)}if(n.type===`zoom`){let e=h.strip.find(e=>e.panelId===n.sourcePanelId),t=e?$n(h.strip,e):null,r=n.zoom,i=r?En(r):null;return(0,D.jsxs)(`div`,{style:{display:`flex`,flexDirection:Jt?`column`:`row`,gap:12,alignItems:`stretch`,border:`1px dashed var(--border)`,borderRadius:12,padding:12,background:`var(--bg-secondary)`},children:[(0,D.jsx)(`div`,{style:{width:Jt?`100%`:200,minWidth:Jt?0:200},children:t?(0,D.jsxs)(`div`,{style:{position:`relative`,cursor:`crosshair`},title:`Click where the zoom should land — the camera pushes into that spot`,onClick:e=>{let t=e.currentTarget.getBoundingClientRect(),i=Math.round((e.clientX-t.left)/t.width*100),a=Math.round((e.clientY-t.top)/t.height*100);K.change(n.panelId,{fx:i,fy:a,scale:r?.scale||1.8})},children:[(0,D.jsx)(`img`,{src:t,alt:`${n.panelId} source`,style:{width:`100%`,borderRadius:8,display:`block`}}),i&&(0,D.jsx)(`div`,{style:{position:`absolute`,left:`${i.x*100}%`,top:`${i.y*100}%`,width:`${i.w*100}%`,height:`${i.h*100}%`,border:`2px solid #d97706`,borderRadius:4,pointerEvents:`none`}}),r&&(0,D.jsx)(`div`,{style:{position:`absolute`,left:`${r.fx}%`,top:`${r.fy}%`,width:8,height:8,marginLeft:-4,marginTop:-4,borderRadius:`50%`,background:`#d97706`,pointerEvents:`none`}})]}):(0,D.jsx)(`div`,{style:{height:112,borderRadius:8,border:`1px dashed var(--border)`,display:`flex`,alignItems:`center`,justifyContent:`center`,fontSize:11,color:`var(--text-secondary)`},children:`source not built yet`})}),(0,D.jsxs)(`div`,{style:{flex:1,minWidth:0,display:`flex`,flexDirection:`column`,gap:6},children:[(0,D.jsxs)(`div`,{style:{display:`flex`,gap:6,alignItems:`center`,flexWrap:`wrap`},children:[(0,D.jsx)(`strong`,{style:{fontSize:13},children:n.panelId}),(0,D.jsx)(`span`,{style:$,children:`ZOOM`}),(0,D.jsxs)(`span`,{style:$,children:[`into `,n.sourcePanelId]}),(0,D.jsxs)(`span`,{style:$,children:[(n.startMs/1e3).toFixed(2),`s → `,((n.startMs+n.durationMs)/1e3).toFixed(2),`s · `,(n.durationMs/1e3).toFixed(2),`s`]}),r?(0,D.jsx)(`span`,{style:$,children:r.pickedBy===`user`?`target: yours`:`target: vision`}):(0,D.jsx)(`span`,{style:$,children:`target: vision picks at build`}),(0,D.jsx)(`span`,{style:{flex:1}}),(0,D.jsx)(`button`,{className:`btn btn-secondary`,\"data-compact\":!0,style:{fontSize:10.5},disabled:J||!t,title:`Re-aim the zoom yourself — pick a different target and amount, preview the final framing, and approve it before it applies`,onClick:()=>Ot({panelId:n.panelId}),children:`Override`}),(0,D.jsx)(`button`,{className:`btn btn-secondary`,\"data-compact\":!0,style:{fontSize:10.5},disabled:J,title:`Remove the zoom — the progression continues from the un-zoomed frame again`,onClick:()=>Ge.remove(n.panelId),\"data-icon-action\":`true`,\"aria-label\":`Remove the zoom — the progression continues from the un-zoomed frame again`,children:(0,D.jsx)(k,{name:`trash`,size:18})})]}),(0,D.jsx)(`div`,{style:{fontSize:11,color:`var(--text-secondary)`},children:`Free coded camera push-in over this beat (a swoosh plays with it). The zoomed-in frame automatically becomes what the next panel builds on. Click the image to move the target.`}),(0,D.jsxs)(`div`,{style:{display:`flex`,gap:4,alignItems:`center`,flexWrap:`wrap`},children:[(0,D.jsx)(`span`,{style:{fontSize:10.5,color:`var(--text-secondary)`},children:`Strength`}),[1.5,1.8,2.2,3].map(e=>(0,D.jsxs)(`button`,{className:(r?.scale||1.8)===e?`btn btn-primary`:`btn btn-secondary`,\"data-compact\":!0,style:{fontSize:10,padding:`2px 8px`},disabled:J||!r,onClick:()=>K.change(n.panelId,{fx:r.fx,fy:r.fy,scale:e,pickedBy:r.pickedBy}),children:[e,`x`]},e)),n.image?(0,D.jsx)(`span`,{style:{fontSize:10,color:`var(--text-secondary)`},children:`zoomed frame ready — the next edit builds on it`}):(0,D.jsxs)(`span`,{style:{fontSize:10,color:`var(--text-secondary)`},children:[`Build crops the zoomed frame`,r?``:` (vision target · 2 cr)`]})]})]})]},n.panelId)}let i=n.kind===`repeat`,a=$n(h.strip,n);return(0,D.jsxs)(`div`,{style:{display:`flex`,flexDirection:Jt?`column`:`row`,gap:12,alignItems:`stretch`,border:`1px solid var(--border)`,borderRadius:12,padding:12,background:`var(--bg-secondary)`,...i?{opacity:.88}:{}},children:[(0,D.jsxs)(`div`,{style:{width:Jt?`100%`:200,minWidth:Jt?0:200,display:`flex`,flexDirection:`column`,gap:6},children:[a?(0,D.jsxs)(`span`,{className:`sm-expand-host`,style:{display:`block`,maxWidth:Jt?`100%`:200},children:[(0,D.jsx)(`img`,{src:a,alt:n.panelId,onClick:()=>en({panelId:n.panelId}),style:{width:`100%`,maxWidth:Jt?`100%`:200,borderRadius:8,display:`block`,cursor:`zoom-in`}}),(0,D.jsx)(Oc,{src:a,name:n.panelId,onOpen:()=>en({panelId:n.panelId})})]}):(0,D.jsx)(`div`,{style:{width:`100%`,maxWidth:Jt?`100%`:200,height:112,borderRadius:8,border:`1px dashed var(--border)`,display:`flex`,alignItems:`center`,justifyContent:`center`,fontSize:11,color:`var(--text-secondary)`},children:i?`shows ${n.repeatOf}`:`not built`}),!i&&(()=>{let e=cr(n);if(e.length<2)return null;let t=e.lastIndexOf(n.image);return(0,D.jsxs)(`div`,{style:{display:`flex`,alignItems:`center`,justifyContent:`center`,gap:8,fontSize:11,color:`var(--text-secondary)`},title:`Flip between this panel's generations — the one showing is what the editor (and downstream edits) use`,children:[(0,D.jsx)(`button`,{className:`btn btn-secondary`,\"data-compact\":!0,style:{fontSize:11,padding:`0 8px`},disabled:J||t<=0,onClick:()=>Kr(n.panelId,-1),children:`‹`}),`v`,t+1,`/`,e.length,(0,D.jsx)(`button`,{className:`btn btn-secondary`,\"data-compact\":!0,style:{fontSize:11,padding:`0 8px`},disabled:J||t>=e.length-1,onClick:()=>Kr(n.panelId,1),children:`›`})]})})(),!i&&(()=>{let e=Yn(n.panelId),t=ie.find(t=>t.value===e.model),r=(t?.supports?.quality||[]).length>0,i=[t?.label||e.model,...r?[e.quality]:[],e.resolution].join(` · `),a=oe(e.model,1,e);return(0,D.jsxs)(D.Fragment,{children:[(0,D.jsxs)(`button`,{className:`btn btn-secondary`,\"data-compact\":!0,style:{fontSize:10.5,justifyContent:`space-between`,width:`100%`,color:Gn[n.panelId]?`var(--text-primary)`:`var(--text-secondary)`},disabled:J,onClick:()=>Jn(n.panelId),title:`Generation settings for THIS panel — model, quality, resolution (the top row is the bulk default)`,children:[(0,D.jsx)(`span`,{style:{overflow:`hidden`,textOverflow:`ellipsis`,whiteSpace:`nowrap`},children:i}),(0,D.jsx)(`span`,{style:{fontWeight:700},children:`Edit`})]}),(0,D.jsx)(`button`,{className:`btn btn-secondary`,\"data-compact\":!0,style:{fontSize:11,justifyContent:`center`},disabled:J,onClick:()=>Pr(n.panelId),children:bt===n.panelId?`Generating…`:n.image?`Regenerate · ${a} cr`:`Generate · ${a} cr`})]})})(),i&&(()=>{let e=Yn(n.panelId),t=oe(e.model,1,e);return(0,D.jsx)(`button`,{className:`btn btn-secondary`,\"data-compact\":!0,style:{fontSize:11,justifyContent:`center`},disabled:J,title:`This card re-shows ${n.repeatOf}'s frame unchanged. Make it a real shot: a new frame continuing the moment (camera push-in) that you can then re-prompt like any panel.`,onClick:()=>zr(n.panelId),children:bt===n.panelId?`Generating…`:`Make real shot · ${t} cr`})})()]}),(0,D.jsxs)(`div`,{style:{flex:1,minWidth:0,display:`flex`,flexDirection:`column`,gap:7},children:[(0,D.jsxs)(`div`,{style:{display:`flex`,gap:6,alignItems:`center`,flexWrap:`wrap`},children:[(0,D.jsx)(`strong`,{style:{color:`var(--text-primary)`,fontSize:13},children:n.panelId}),(0,D.jsxs)(`span`,{style:{...$,display:`inline-flex`,alignItems:`center`,gap:5},children:[(0,D.jsx)(`span`,{style:{width:8,height:8,borderRadius:99,background:Tn[n.lineageId]}}),n.lineageId]}),(0,D.jsx)(`span`,{style:{...$,textTransform:`uppercase`,...a?{cursor:`zoom-in`}:{}},title:a?`Open fullscreen preview`:void 0,onClick:a?()=>en({panelId:n.panelId}):void 0,children:n.kind}),n.kind===`edit`&&(0,D.jsxs)(`span`,{style:$,children:[`edits `,n.sourcePanelId]}),i&&(0,D.jsxs)(`span`,{style:$,children:[`shows `,n.repeatOf]}),(0,D.jsxs)(`span`,{style:$,children:[(n.startMs/1e3).toFixed(2),`s → `,((n.startMs+n.durationMs)/1e3).toFixed(2),`s · `,(n.durationMs/1e3).toFixed(2),`s`]}),(0,D.jsx)(`label`,{style:{display:`inline-flex`,alignItems:`center`,gap:4,fontSize:10.5,color:`var(--text-secondary)`},title:`This beat's storytelling method — picking one yourself always wins over the auto choice`,children:(0,D.jsxs)(ns,{value:n.method||``,disabled:J||i,style:{fontSize:10.5},onChange:e=>Oe.change(n.panelId,`method`,e.target.value||null),children:[(0,D.jsx)(`option`,{value:``,children:`no method`}),De.map(e=>(0,D.jsxs)(`option`,{value:e,children:[e,n.methodGroup&&n.method===e?` · ${n.methodGroup}`:``]},e))]})}),n.needsRefresh&&(0,D.jsx)(`span`,{style:{...$,color:`#d97706`,borderColor:`#d97706`},children:`may need refresh`}),n.styleWarning&&(0,D.jsx)(`button`,{type:`button`,style:{...$,color:`#d97706`,borderColor:`#d97706`,background:`none`,cursor:`pointer`,fontFamily:`inherit`},disabled:!!bt||mt,title:`${n.styleWarning} — click to fix: regenerates STRICT with the style references enforced (${oe(Yn(n.panelId).model,1,Yn(n.panelId))} cr)`,onClick:()=>Pr(n.panelId,{strict:!0}),children:bt===n.panelId?`fixing style…`:`style differs — fix`}),(0,D.jsx)(`span`,{style:{flex:1}}),(0,D.jsx)(`button`,{className:`btn btn-secondary`,\"data-compact\":!0,style:{fontSize:10.5,padding:`2px 8px`},title:`What gets sent — the exact prompt and reference images this panel generates from`,onClick:()=>Pi(n.panelId),children:`Info`}),(0,D.jsx)(`button`,{className:`btn btn-secondary`,\"data-compact\":!0,style:{fontSize:10.5,padding:`2px 8px`},disabled:J,title:`Insert a new panel after this one, continuing its lineage`,onClick:()=>Ur(n.panelId),children:`+ Panel`}),n.type===`panel`&&n.kind!==`repeat`&&(0,D.jsx)(`button`,{className:`btn btn-secondary`,\"data-compact\":!0,style:{fontSize:10.5,padding:`2px 8px`},disabled:J,title:`Insert a FREE camera push-in after this panel — vision picks the target, a swoosh plays, and the zoomed frame becomes what the next panel builds on`,onClick:()=>Je.insert(n.panelId),children:`+ Zoom`}),n.type===`panel`&&n.kind!==`repeat`&&n.kind!==`revealStep`&&n.method!==`progressiveReveal`&&(0,D.jsx)(`button`,{className:`btn btn-secondary`,\"data-compact\":!0,style:{fontSize:10.5,padding:`2px 8px`},disabled:J,title:`Turn this beat (and as many after it as you pick) into a collage canvas — a solid background where images and text pop in with the narration. Frames you've already generated come along, and you can revert.`,onClick:()=>Et(n.panelId),children:`+ Canvas`}),(0,D.jsx)(`button`,{className:`btn btn-secondary`,\"data-compact\":!0,style:{fontSize:10.5,padding:`2px 8px`},disabled:J||h.strip.length<=1,onClick:()=>Ge.remove(n.panelId),\"data-icon-action\":`true`,\"aria-label\":`Delete`,title:`Delete`,children:(0,D.jsx)(k,{name:`trash`,size:18})})]}),(0,D.jsx)(Vf,{value:r,disabled:J,onCommit:e=>We.edit(n.panelId,e)},`${n.panelId}-says-${r}`),!i&&(0,D.jsx)(Bf,{value:n.prompt,disabled:J,onCommit:e=>Oe.change(n.panelId,`prompt`,e)}),!i&&n.promptOverride&&String(n.promptOverride).trim()&&(0,D.jsxs)(`div`,{style:{display:`flex`,alignItems:`center`,gap:8,flexWrap:`wrap`,fontSize:11,color:`var(--text-secondary)`,marginTop:2},children:[(0,D.jsx)(`span`,{children:`A manually edited prompt is being sent instead of this change.`}),(0,D.jsx)(`button`,{className:`btn btn-secondary`,\"data-compact\":!0,style:{fontSize:10.5,padding:`2px 8px`},disabled:J,onClick:()=>Oe.change(n.panelId,`send`),children:`Send this instead`})]}),n.textOverlays?.length>0&&(0,D.jsxs)(D.Fragment,{children:[Ve.current&&bt===n.panelId&&(0,D.jsx)(`button`,{type:`button`,onClick:Ue,children:`Cancel text placement`}),(0,D.jsx)(Xf,{doc:h,panel:n,disabled:J,onOverlayEdit:$e.change,onPlaceText:Ir,busy:bt===n.panelId})]}),n.kind===`base`&&n.method===`progressiveReveal`&&(0,D.jsx)(Zf,{doc:h,panel:n,disabled:J||jt===n.panelId,onRevealEdit:et.change,onRerender:vr,busy:jt===n.panelId}),dr(h,n.panelId)&&!n.animateNext&&(Nt?.panelId===n.panelId?(()=>{let e=pn.find(e=>e.id===Nt.model)||pn[0],t=(e.resolutions||[e.resolution]).includes(Nt.resolution)?Nt.resolution:e.resolution,r=e.id===`veo-3.1-lite`&&t===`1080p`,i=r?8:hn(e.id,Nt.durationSec),a=t=>{if(!r){if(e.durList){let n=e.durList.indexOf(i),r=e.durList[Math.max(0,Math.min(e.durList.length-1,n+t))];Pt({...Nt,durationSec:r})}else Pt({...Nt,durationSec:hn(e.id,i+t)})}},o=h.strip[h.strip.findIndex(e=>e.panelId===n.panelId)+1],s=$n(h.strip,n),c=o?$n(h.strip,o):null;return(0,D.jsxs)(`div`,{style:{border:`1px dashed var(--border)`,borderRadius:8,padding:8,display:`flex`,flexDirection:`column`,gap:6},children:[(0,D.jsx)(`div`,{style:{fontSize:11,fontWeight:700,color:`var(--text-primary)`},children:`Animate into the next panel`}),(0,D.jsx)(`div`,{style:{fontSize:10.5,color:`var(--text-secondary)`},children:`Generates a real video from this frame to the next (first→last frame). It plays across the cut by borrowing time from both panels — total length and narration sync stay exactly the same.`}),(0,D.jsxs)(`div`,{style:{display:`flex`,gap:8,alignItems:`center`},children:[(0,D.jsxs)(`div`,{style:{display:`flex`,flexDirection:`column`,gap:2,alignItems:`center`},children:[s?(0,D.jsx)(`img`,{src:s,alt:`Start frame`,style:{height:96,maxWidth:180,objectFit:`contain`,borderRadius:6,background:`#000`}}):null,(0,D.jsx)(`span`,{style:{fontSize:9.5,color:`var(--text-secondary)`,textTransform:`uppercase`,letterSpacing:`0.05em`},children:`Start frame`})]}),(0,D.jsx)(`span`,{style:{fontSize:14,color:`var(--text-secondary)`},children:`→`}),(0,D.jsxs)(`div`,{style:{display:`flex`,flexDirection:`column`,gap:2,alignItems:`center`},children:[c?(0,D.jsx)(`img`,{src:c,alt:`End frame`,style:{height:96,maxWidth:180,objectFit:`contain`,borderRadius:6,background:`#000`}}):null,(0,D.jsx)(`span`,{style:{fontSize:9.5,color:`var(--text-secondary)`,textTransform:`uppercase`,letterSpacing:`0.05em`},children:`End frame`})]})]}),(0,D.jsx)(`div`,{style:{display:`flex`,gap:4,flexWrap:`wrap`},children:pn.map(e=>(0,D.jsx)(`button`,{className:Nt.model===e.id?`btn btn-primary`:`btn btn-secondary`,\"data-compact\":!0,style:{fontSize:10,padding:`2px 8px`},onClick:()=>Pt({...Nt,model:e.id,resolution:e.resolution,durationSec:hn(e.id,Nt.durationSec)}),children:e.label},e.id))}),(0,D.jsxs)(`div`,{style:{display:`flex`,gap:4,alignItems:`center`,flexWrap:`wrap`},children:[(0,D.jsx)(`span`,{style:{fontSize:10.5,color:`var(--text-secondary)`},children:`Quality`}),(e.resolutions||[e.resolution]).map(e=>(0,D.jsx)(`button`,{className:t===e?`btn btn-primary`:`btn btn-secondary`,\"data-compact\":!0,style:{fontSize:10,padding:`2px 8px`},onClick:()=>Pt({...Nt,resolution:e}),children:e},e)),r&&(0,D.jsx)(`span`,{style:{fontSize:10,color:`var(--text-secondary)`},children:`1080p runs 8s on this model`})]}),e.aspects&&(0,D.jsxs)(`div`,{style:{display:`flex`,gap:4,alignItems:`center`},children:[(0,D.jsx)(`span`,{style:{fontSize:10.5,color:`var(--text-secondary)`},children:`Ratio`}),e.aspects.map(e=>(0,D.jsx)(`button`,{className:(Nt.aspect||h.meta?.aspect||`16:9`)===e?`btn btn-primary`:`btn btn-secondary`,\"data-compact\":!0,style:{fontSize:10,padding:`2px 8px`},onClick:()=>Pt({...Nt,aspect:e}),children:e},e))]}),(0,D.jsxs)(`div`,{style:{display:`flex`,gap:4,alignItems:`center`,flexWrap:`wrap`},children:[(0,D.jsx)(`span`,{style:{fontSize:10.5,color:`var(--text-secondary)`},children:`Duration`}),(0,D.jsx)(`button`,{className:`btn btn-secondary`,\"data-compact\":!0,style:{fontSize:10,padding:`2px 8px`},disabled:r,onClick:()=>a(-1),children:`−`}),(0,D.jsxs)(`span`,{style:{fontSize:11,fontWeight:700,minWidth:24,textAlign:`center`},children:[i,`s`]}),(0,D.jsx)(`button`,{className:`btn btn-secondary`,\"data-compact\":!0,style:{fontSize:10,padding:`2px 8px`},disabled:r,onClick:()=>a(1),children:`+`}),(0,D.jsxs)(`span`,{style:{fontSize:10,color:`var(--text-secondary)`},children:[e.durList?`this model generates ${e.durList.join(`/`)}s`:`${e.minSec}-${e.maxSec}s on this model`,` · recommended `,_n(h,n.panelId,e.id),`s (these two panels really run `,gn(h,n.panelId).toFixed(2),`s)`]})]}),(0,D.jsxs)(`label`,{style:{display:`flex`,gap:6,alignItems:`center`,fontSize:10.5,color:`var(--text-primary)`,cursor:`pointer`},children:[(0,D.jsx)(`input`,{type:`checkbox`,style:{accentColor:`var(--accent)`},checked:Nt.fit!==!1,onChange:e=>Pt({...Nt,fit:e.target.checked})}),`Fit to narration timing`,(0,D.jsx)(`span`,{style:{fontSize:10,color:`var(--text-secondary)`},children:Nt.fit!==!1&&o?`the clip fills both panels' ${gn(h,n.panelId).toFixed(2)}s — plays at ${(i/Math.max(.4,yn((n.durationMs||0)/1e3,(o.durationMs||0)/1e3))).toFixed(2)}× automatically`:`off — plays exactly ${i}s, borrowing half from each panel`})]}),(0,D.jsxs)(`div`,{style:{display:`flex`,gap:6},children:[(0,D.jsx)(`button`,{className:`btn btn-primary`,\"data-compact\":!0,style:{fontSize:10.5},disabled:J||Ft===n.panelId,onClick:()=>Wr(n.panelId,e.id,i,{resolution:t,aspect:Nt.aspect,fit:Nt.fit!==!1}),children:Ft===n.panelId?`Generating…`:`Generate (${B(e.id,i,1,{resolution:t})} cr)`}),(0,D.jsx)(`button`,{className:`btn btn-secondary`,\"data-compact\":!0,style:{fontSize:10.5},onClick:()=>Pt(null),children:`Cancel`})]})]})})():(0,D.jsx)(`button`,{className:`btn btn-secondary`,\"data-compact\":!0,style:{fontSize:10.5,alignSelf:`flex-start`},disabled:J,title:`Generate a real video clip that animates from this panel into the next one (start and end frames are the two panels)`,onClick:()=>Pt({panelId:n.panelId,model:mn,durationSec:_n(h,n.panelId,mn),resolution:(pn[0]||{}).resolution,fit:!0}),children:`Generate video into next panel`})),n.animateNext&&(0,D.jsxs)(`div`,{style:{border:`1px solid var(--border)`,borderRadius:8,padding:8,display:`flex`,gap:8,alignItems:`center`},children:[n.animateNext.video?(0,D.jsx)(Ec,{fill:!0,src:n.animateNext.video,muted:!0,loop:!0,label:`Animated into next panel`,style:{width:150,flexShrink:0,borderRadius:6}}):(0,D.jsx)(`span`,{style:{fontSize:10.5,color:`var(--text-muted)`},children:`pending`}),(0,D.jsxs)(`div`,{style:{flex:1,minWidth:0,display:`flex`,flexDirection:`column`,gap:4},children:[(0,D.jsx)(`div`,{style:{fontSize:11,fontWeight:700,color:`var(--text-primary)`},children:`Animated into next panel`}),(0,D.jsxs)(`div`,{style:{display:`flex`,gap:4,flexWrap:`wrap`,alignItems:`center`},children:[(0,D.jsx)(`span`,{style:{fontSize:10,color:`var(--text-secondary)`},children:(pn.find(e=>e.id===n.animateNext.model)||{}).label||n.animateNext.model}),(0,D.jsxs)(`label`,{style:{display:`flex`,gap:4,alignItems:`center`,fontSize:10,color:`var(--text-primary)`,cursor:`pointer`},title:`Fill both panels' exact narration window, auto-adjusting playback speed. Off = play exactly the generated length, borrowing half from each panel.`,children:[(0,D.jsx)(`input`,{type:`checkbox`,style:{accentColor:`var(--accent)`},checked:n.animateNext.fit===!0,disabled:J,onChange:e=>ke.change(n.panelId,`playback`,{fit:e.target.checked})}),`Fit to timing`]}),n.animateNext.fit===!0?(0,D.jsxs)(`span`,{style:{fontSize:9.5,color:`var(--text-secondary)`},children:[`fills `,gn(h,n.panelId).toFixed(2),`s · plays at `,((Number(n.animateNext.genSeconds)||n.animateNext.durationSec||1)/Math.max(.4,yn((n.durationMs||0)/1e3,((h.strip[h.strip.findIndex(e=>e.panelId===n.panelId)+1]||{}).durationMs||0)/1e3))).toFixed(2),`×`]}):[2,3,4].map(e=>(0,D.jsxs)(`button`,{className:n.animateNext.durationSec===e?`btn btn-primary`:`btn btn-secondary`,\"data-compact\":!0,style:{fontSize:9.5,padding:`1px 7px`},disabled:J,title:`Play window at the cut — the clip's speed adjusts to land the end frame (no regeneration)`,onClick:()=>ke.change(n.panelId,`playback`,{durationSec:e}),children:[e,`s`]},e)),fr(h,n.panelId)&&(0,D.jsx)(`span`,{style:{fontSize:9.5,fontWeight:700,color:`#d97706`,border:`1px solid #d97706`,borderRadius:999,padding:`1px 7px`},title:`A source panel changed since this was generated — regenerate to match the new frames`,children:`stale`})]}),(0,D.jsxs)(`div`,{style:{display:`flex`,gap:6},children:[(0,D.jsx)(`button`,{className:`btn btn-secondary`,\"data-compact\":!0,style:{fontSize:10},disabled:J||Ft===n.panelId,onClick:()=>Wr(n.panelId,n.animateNext.model,n.animateNext.durationSec),title:pn.some(e=>e.id===n.animateNext.model)?void 0:`This block used a retired model — regenerates on ${(pn[0]||{}).label}`,children:Ft===n.panelId?`Generating…`:(()=>{let e=pn.find(e=>e.id===n.animateNext.model)||pn[0],t=xn(e.id),r=t.includes(n.animateNext.durationSec)?n.animateNext.durationSec:t.reduce((e,t)=>Math.abs(t-n.animateNext.durationSec)<Math.abs(e-n.animateNext.durationSec)?t:e,t[0]);return`Regenerate (${B(e.id,r,1,{resolution:e.resolution})} cr)`})()}),(0,D.jsx)(`button`,{className:`btn btn-secondary`,\"data-compact\":!0,style:{fontSize:10},disabled:J,title:`Remove the animation — the two panels cut directly again`,onClick:()=>ke.change(n.panelId,`remove`),\"data-icon-action\":`true`,\"aria-label\":`Remove the animation — the two panels cut directly again`,children:(0,D.jsx)(k,{name:`trash`,size:18})})]})]})]})]})]},n.panelId)}},n.panelId))]},e.sceneId)})}),(0,D.jsxs)(`p`,{style:{marginTop:10,fontSize:11.5,color:`var(--text-secondary)`},children:[`Editing a prompt keeps the current image — hit Regenerate on that panel to apply it. Every generation is kept as a version: flip with ‹ › and whichever is showing is what the editor (and downstream edits) use. Regenerating or switching a version flags its downstream chain instead of rebuilding it automatically. Panels shorter than `,(350/1e3).toFixed(2),`s were merged into their neighbour during planning.`]})]}):(0,D.jsx)(`div`,{style:{display:`flex`,alignItems:`center`,gap:10,flexWrap:`wrap`},children:ct?(0,D.jsx)(`span`,{style:{display:`inline-flex`,alignItems:`center`,gap:8,fontSize:13,color:`var(--text-secondary)`,border:`1px solid var(--border)`,borderRadius:999,padding:`8px 16px`,background:`var(--bg-secondary)`},children:(0,D.jsx)(ap,{step:ut,milestones:dt,startedAt:ft})}):lr.ready?(0,D.jsxs)(`button`,{className:`btn btn-primary`,onClick:()=>pr(!1),title:`Plans the whole sequence of image panels from your conversation + narration timing (reasoning model).`,children:[`Plan image panels (`,V[`strip:plan`],` credits)`]}):(0,D.jsx)(`span`,{style:{fontSize:12,color:`var(--text-secondary)`},children:lr.reason})}),wt&&h?.strip.some(e=>e.panelId===wt)&&(0,D.jsx)(eu,{pending:!!nt.pending,error:nt.error,doc:h,fromPanelId:wt,onClose:()=>{nt.cancel(),Tt(null)},onConfirm:async(e,t)=>{try{let n=await nt.change(e,t);if(!n)return;Tt(null);let r=n.strip.find(e=>e.type===`canvas`&&!h.strip.some(t=>t.panelId===e.panelId));r&&Ct(r.panelId)}catch(e){X.error?.(e.message)}}}),In.pending&&(0,D.jsxs)(`div`,{role:`status`,children:[In.canceling?`Canceling zoom processing — waiting for the current request`:`Preparing zoom crops`,` `,(0,D.jsx)(`button`,{type:`button`,className:`btn btn-secondary`,disabled:In.canceling,onClick:In.cancel,children:`Cancel zoom processing`})]}),In.error&&(0,D.jsx)(`div`,{role:`alert`,children:In.error}),Ln.pending&&(0,D.jsxs)(`div`,{role:`status`,children:[Ln.canceling?`Canceling stock sourcing — waiting for current requests`:`Finding canvas images`,` `,(0,D.jsx)(`button`,{type:`button`,className:`btn btn-secondary`,disabled:Ln.canceling,onClick:Ln.cancel,children:`Cancel stock sourcing`})]}),Ln.error&&(0,D.jsx)(`div`,{role:`alert`,children:Ln.error}),wn.canceling&&(0,D.jsx)(`div`,{role:`status`,children:`Canceling canvas build — waiting for the current request.`}),Rn.pending&&(0,D.jsxs)(`div`,{role:`status`,children:[Rn.canceling?`Canceling style check — waiting for current requests`:`Checking and correcting style`,` `,(0,D.jsx)(`button`,{type:`button`,className:`btn btn-secondary`,disabled:Rn.canceling,onClick:Rn.cancel,children:`Cancel style check`})]}),Rn.error&&(0,D.jsx)(`div`,{role:`alert`,children:Rn.error}),Bn.pending&&(0,D.jsxs)(`div`,{role:`status`,children:[Bn.canceling?`Canceling regeneration — waiting for the current request`:`Regenerating ${Bn.pending}`,` `,(0,D.jsx)(`button`,{type:`button`,className:`btn btn-secondary`,disabled:Bn.canceling,onClick:Bn.cancel,children:`Cancel regeneration`})]}),Bn.error&&(0,D.jsx)(`div`,{role:`alert`,children:Bn.error}),Vn.pending&&(0,D.jsxs)(`div`,{role:`status`,children:[Vn.canceling?`Canceling reveal — waiting for the current request`:`Rendering reveal ${Vn.pending}`,` `,(0,D.jsx)(`button`,{type:`button`,className:`btn btn-secondary`,disabled:Vn.canceling,onClick:Vn.cancel,children:`Cancel reveal`})]}),Vn.error&&(0,D.jsx)(`div`,{role:`alert`,children:Vn.error}),Hn.pending&&(0,D.jsxs)(`div`,{role:`status`,children:[Hn.canceling?`Canceling zoom update — waiting for the current request`:`Updating zoom`,Hn.progress?` · ${Hn.progress.done}/${Hn.progress.total}`:``,` `,(0,D.jsx)(`button`,{type:`button`,className:`btn btn-secondary`,disabled:Hn.canceling,onClick:Hn.cancel,children:`Cancel zoom update`})]}),Hn.error&&(0,D.jsx)(`div`,{role:`alert`,children:Hn.error}),Dt&&h&&(()=>{let e=h.strip.find(e=>e.panelId===Dt.panelId),t=e&&h.strip.find(t=>t.panelId===e.sourcePanelId),n=t?$n(h.strip,t):null;return!e||!n?null:(0,D.jsx)(Ql,{srcImage:n,initial:e.zoom||{fx:50,fy:50,scale:1.8},busy:Un,onApprove:Mr,onClose:()=>!Un&&Ot(null)})})(),St&&h?.strip.some(e=>e.panelId===St)&&(0,D.jsx)(xf,{mediaHost:l,panelEditHost:u,editLease:G,projectId:P,canEdit:U.canEdit!==!1,doc:h,panelId:St,aspect:Zn,onDocChange:W,onClose:()=>Ct(null)}),$t&&wi&&(0,D.jsx)(wc,{url:wi,title:$t.styleRef?`Style reference`:$t.panelId,onClose:()=>en(null),onEdit:Si?.image?()=>{nn($t.panelId),en(null)}:void 0,...Si&&cr(Si).length>1?{versions:cr(Si),currentVersion:cr(Si).lastIndexOf(Si.image),onVersionChange:e=>Ye.select(Si.panelId,e)}:{}}),Ii&&(0,D.jsx)(wf,{disabled:J,open:!0,onClose:()=>Pi(null),title:Ii.panelId,model:Ii.type!==`titleScreen`&&Ii.kind!==`repeat`?ie.find(e=>e.value===Yn(Ii.panelId).model)?.label:null,settings:(()=>{let e=h.lineages[Ii.lineageId]||{},t=Ii.type!==`titleScreen`&&Ii.kind!==`repeat`?Yn(Ii.panelId):null;return[t&&(t.quality!==`low`||(ie.find(e=>e.value===t.model)?.supports?.quality||[]).length)?t.quality:null,t?t.resolution:null,Ii.lineageId?`lineage ${Ii.lineageId}`:null,e.sheetIds?.length?`sheets: ${e.sheetIds.join(`, `)}`:null].filter(Boolean).join(` · `)})(),prompt:Li.prompt||Li.note,refs:Li.referenceImages.filter(e=>!(zi&&e.source===`Style reference`)).map(e=>({url:e.url,source:e.source,kind:e.source===`Style reference`?`style`:`source`,removable:Li.prompt!=null})),editable:Li.prompt!=null,onRemoveRef:Li.prompt==null?null:e=>Oe.change(Ii.panelId,`exclude`,e.source),onPromptChange:Li.prompt==null?null:e=>Oe.change(Ii.panelId,`override`,e),promptOverridden:!!(Ii.promptOverride&&String(Ii.promptOverride).trim())||Array.isArray(Ii.refBlocklist)&&Ii.refBlocklist.length>0,onResetPrompt:()=>Oe.change(Ii.panelId,`reset`)},`${P}:${Ii.panelId}:${R()}`),qn&&(0,D.jsx)(Hf,{policy:z,imageCost:oe,panelId:qn,value:Yn(qn),isOverridden:!!Gn[qn],onClose:()=>Jn(null),onApply:e=>{Kn(t=>{let n={...t};return e?n[qn]=e:delete n[qn],n}),Jn(null)}}),Ti?.image&&(0,D.jsx)(Xc,{url:Ti.image,title:`Panel ${tn}`,projectAspect:h?.meta?.aspect||C,onClose:()=>nn(null),beginVersionSave:()=>rn.begin(tn),onSaveVersion:Gr}),_t&&h&&(0,D.jsx)(rp,{doc:h,ops:mi,busyGif:Jr,editPending:!!G.current,editStatus:(0,D.jsx)(D.Fragment,{children:[We,Ge,Ke,qe,Je,Ye,Xe,Ze,K,Qe,$e,et,tt,nt].map((e,t)=>(0,D.jsxs)(v.Fragment,{children:[e.pending&&(0,D.jsxs)(`p`,{role:`status`,children:[`Applying panel edit… `,(0,D.jsx)(`button`,{type:`button`,onClick:e.cancel,children:`Cancel edit`})]}),e.error&&(0,D.jsx)(`p`,{role:`alert`,children:e.error})]},t))}),onClose:()=>vt(!1),onConfirm:()=>{G.current||(yt.current=!0,vt(!1),Ar({gifsReviewed:!0}))}}),dn&&(0,D.jsx)(jf,{styleAuthoringHost:t,generationCatalogHost:a,styleLibraryHost:r,actor:Le,aspect:h?.meta?.aspect||C,onClose:()=>fn(!1),onCreated:e=>{cn(re({actor:R()})),Vr({text:e.stylePrompt,styleRefs:e.styleRefs,name:e.name,builtin:!1})}})]})]})}function sp({narrationTiming:e,narrationAudio:t,narrationScript:n}={},r=null){let i=Array.isArray(e?.words)?e.words:[],a=typeof n?.text==`string`?n.text:``;if(!i.length&&!a.trim())return r;let{script:o,words:s,transcriptText:c,audioUrl:l,duration:u,versions:d,...f}=L(r)?r:{};return{...f,enabled:!0,...a?{script:a}:{},...i.length?{words:i.map(({text:e,start:t,end:n})=>({text:e,start:t,end:n})),transcriptText:typeof e.text==`string`?e.text:i.map(e=>e.text).join(` `)}:{},...typeof t?.url==`string`&&t.url?{audioUrl:t.url,...Number(t.duration)>0?{duration:Number(t.duration)}:{}}:{}}}let cp={ready:`saved`,dirty:`saving`,pending:`saving`,closed:`offline`},lp=e=>e.sourceConflict||e.error?`conflict`:cp[e.phase]||(e.pending||e.dirty?`saving`:`saved`);function up(e,{shared:t=e=>e,merge:n=(e,t)=>t,debounceMs:r=0,maxWaitMs:i=1500}={}){let a=new Map,o=(e,n)=>{clearTimeout(e.timer),e.timer=null,e.first=0;let r=t(e.screen,n),i=JSON.stringify(r);e.text===null&&(e.text=JSON.stringify(e.document)),i!==e.text&&(e.document=r,e.text=i,e.binding.changed())},s=(e,t)=>{if(!(r>0))return o(e,t);let n=Date.now();e.first||=n,clearTimeout(e.timer),e.timer=setTimeout(()=>o(e,t),Math.max(0,Math.min(r,e.first+i-n)))};function c(r,i,c,l=`document`){let u=(0,v.useRef)({document:i,receive:c});u.current.receive=c;let[d,f]=(0,v.useState)(()=>({canEdit:e.getShared?.().canEdit!==!1,phase:`ready`}));return(0,v.useEffect)(()=>{let r=a.get(l);if(!r){let n={binding:null,listeners:new Set,screen:u.current.document,document:t(u.current.document,l),text:null,timer:null,first:0};r=n,a.set(l,n),n.binding=e.connectDocument({key:l,source:n.document,read:()=>n.document,replace:e=>{n.document=e,n.text=null;for(let t of n.listeners)t(e)}})}let i=e=>{let t=n(u.current.document,e,l);u.current.document=t,r.screen=t,u.current.receive?.(t)};r.listeners.add(i);let s=r.binding.onStatus(e=>f({...e,canEdit:e.canEdit!==!1}));return JSON.stringify(r.document)!==JSON.stringify(t(u.current.document,l))&&i(r.document),()=>{r.listeners.delete(i),s?.(),r.timer&&o(r,l)}},[l]),(0,v.useEffect)(()=>{let e=a.get(l);u.current.document=i,e&&e.screen!==i&&(e.screen=i,s(e,l))},[i,l]),(0,v.useMemo)(()=>({enabled:!1,canEdit:d.canEdit,status:lp(d),actorId:`frame`,adoptDocument(e){let t=a.get(l);t&&(t.screen=e,u.current.document=e,o(t,l))},async persistDocument(e){let t=a.get(l);return t?(t.screen=e,u.current.document=e,o(t,l),await t.binding.flush(),{saved:!0}):{saved:!1}},getSharedBase:()=>null,pauseWorkflow:async()=>()=>{}}),[d,l])}return c.change=(e,t)=>{let n=a.get(e);if(!n||!n.listeners.size)return!1;let r=t(n.screen);if(!r||r===n.screen)return!1;for(let e of n.listeners)e(r);return n.screen=r,o(n,e),!0},c}let dp=/~?\\s*(\\d{1,4}(?:,\\d{3})*)\\s*(?:cr|credits?)\\b/gi;function fp(e){let t=0;for(let n of String(e||``).matchAll(dp))t=Math.max(t,Number(n[1].replace(/,/g,``)));return t}function pp({bridge:e=null}={}){let t=[],n=null,r=e=>new Promise(r=>{t.push({...e,resolve:r}),n?.()}),i=e=>typeof e==`string`?e:String(e?.message||e||``),a=(t,n)=>e.allowSpending({credits:t,label:n.replace(/\\s+/g,` `).trim().slice(0,120)}),o=[],s=0,c=e=>t=>{let r=i(t).trim();if(!r)return;let a=++s;o.push({id:a,tone:e,text:r}),o.length>3&&o.shift(),n?.(),e!==`error`&&setTimeout(()=>l(a),6e3)},l=e=>{let t=o.findIndex(t=>t.id===e);t>=0&&(o.splice(t,1),n?.())},u=Object.freeze({success:c(`success`),error:c(`error`),info:c(`info`),warn:c(`warn`)}),d=Object.freeze({alert:(e,t={})=>r({kind:`alert`,message:i(e),title:t.title||``,confirmLabel:t.confirmLabel||`OK`}).then(()=>void 0),async confirm(t,n={}){let o=i(t),s=typeof e?.allowSpending==`function`?fp(o):0;if(s>0)try{return(await a(s,o)).allowed}catch{}return r({kind:`confirm`,message:o,title:n.title||``,confirmLabel:n.confirmLabel||`Continue`,cancelLabel:n.cancelLabel||`Cancel`,credits:s})}});function f(){let[,e]=(0,v.useState)(0);(0,v.useEffect)(()=>(n=()=>e(e=>e+1),()=>{n=null}),[]);let r=t[0];(0,v.useEffect)(()=>{if(!r)return;let e=e=>{e.key===`Escape`&&(e.stopPropagation(),s(r.kind===`alert`))};return addEventListener(`keydown`,e,!0),()=>removeEventListener(`keydown`,e,!0)});let i=o.length>0&&(0,D.jsx)(`div`,{role:`status`,\"aria-live\":`polite`,style:mp.notices,children:o.map(e=>(0,D.jsxs)(`div`,{style:{...mp.notice,...e.tone===`error`?mp.noticeError:{}},children:[e.text,e.tone===`error`&&(0,D.jsx)(`button`,{type:`button`,\"aria-label\":`Close`,style:mp.noticeClose,onClick:()=>l(e.id),children:`×`})]},e.id))});if(!r)return i||null;let s=n=>{t.shift(),e(e=>e+1),n===!0&&r.credits>0?a(r.credits,r.message).then(e=>r.resolve(e.allowed),()=>r.resolve(!0)):r.resolve(n)};return(0,D.jsxs)(D.Fragment,{children:[i,(0,D.jsx)(`div`,{role:`presentation`,style:mp.backdrop,onClick:e=>{e.target===e.currentTarget&&s(r.kind===`alert`)},children:(0,D.jsxs)(`div`,{role:`dialog`,\"aria-modal\":`true`,\"aria-label\":r.title||`Message`,style:mp.box,children:[r.title&&(0,D.jsx)(`strong`,{style:mp.title,children:r.title}),(0,D.jsx)(`p`,{style:mp.message,children:r.message}),(0,D.jsxs)(`div`,{style:mp.actions,children:[r.kind===`confirm`&&(0,D.jsx)(`button`,{type:`button`,className:`btn btn-secondary`,onClick:()=>s(!1),children:r.cancelLabel}),(0,D.jsx)(`button`,{type:`button`,className:`btn btn-primary`,autoFocus:!0,onClick:()=>s(!0),children:r.confirmLabel})]})]})})]})}return{ui:d,toast:u,DialogHost:f}}let mp={backdrop:{position:`fixed`,inset:0,background:`var(--scrim)`,display:`grid`,placeItems:`center`,padding:16,zIndex:1e3},box:{background:`var(--bg-elev-1)`,color:`var(--fg)`,border:`1px solid var(--border-tok)`,borderRadius:`var(--r-3)`,padding:20,maxWidth:420,width:`100%`,display:`grid`,gap:12},title:{fontSize:16},message:{margin:0,lineHeight:1.5,whiteSpace:`pre-wrap`},actions:{display:`flex`,gap:8,justifyContent:`flex-end`,flexWrap:`wrap`},notices:{position:`fixed`,left:16,right:16,bottom:16,display:`grid`,justifyItems:`center`,gap:8,zIndex:1001,pointerEvents:`none`},notice:{background:`var(--fg)`,color:`var(--bg)`,borderRadius:`var(--r-3)`,padding:`10px 14px`,maxWidth:480,lineHeight:1.4,display:`flex`,gap:10,alignItems:`flex-start`,pointerEvents:`auto`},noticeClose:{background:`none`,border:0,color:`inherit`,font:`inherit`,cursor:`pointer`,padding:0,lineHeight:1},noticeError:{background:`var(--danger)`,color:`var(--bg)`}},hp=new Set([`image`,`video`,`audio`]),gp=e=>!!e&&typeof e==`object`&&hp.has(e.kind)&&typeof e.url==`string`&&typeof e.assetId==`string`&&typeof e.versionId==`string`;function _p(e,t=new Map,n=0){if(!e||typeof e!=`object`||n>12)return t;if(gp(e))return t.set(e.url,{kind:e.kind,assetId:e.assetId,versionId:e.versionId,url:e.url,...e.role?{role:e.role}:{}}),t;for(let r of Array.isArray(e)?e:Object.values(e))_p(r,t,n+1);return t}function vp(e){let t=/^data:([^;,]+)(;base64)?,(.*)$/s.exec(String(e||``));if(!t)throw Error(`This media can only be shown here, not read.`);let n=t[2]?atob(t[3]):decodeURIComponent(t[3]),r=new Uint8Array(n.length);for(let e=0;e<n.length;e++)r[e]=n.charCodeAt(e);return new Blob([r],{type:t[1]})}function yp(e,{root:t=document.documentElement,scripts:n=!1}={}){let r=new Map,i=new Map,a=new Set,o=new Map,s=new Map,c=new Map,l=new Map,u=e=>{for(let n of t.querySelectorAll(`img,video,audio,source,image`))if(n.getAttribute(`src`)===e||n.getAttribute(`href`)===e)return!0;for(let n of t.querySelectorAll(`[style*=\"url(\"]`))if(n.style.backgroundImage.includes(e))return!0;return!1},d=()=>{if(!(a.size<20))for(let t of[...a]){if(u(t))continue;a.delete(t),e.releaseMedia(t),c.delete(t);let n=l.get(t);if(i.delete(n),o.delete(n),l.delete(t),a.size<20)return}},f=e=>{for(let[t,n]of _p(e))r.set(t,n)},p=e=>{if(typeof e!=`string`||!e||/^(data|blob):/.test(e))return null;let t=/^https?:\\/\\/[^/]+(\\/.*)$/.exec(e)?.[1];for(let n of[e,t]){if(!n)continue;let e=n.split(`?`)[0],t=e.replace(/^\\/api\\/media\\/prev\\//,`/api/media/`);for(let i of[n,e,t])if(r.has(i))return i}return null},m=e=>{let t=p(e);return t?r.get(t):null},h=t=>{let n=p(t)||t;if(i.has(n))return i.get(n);let r=m(n);if(!r)return Promise.reject(Error(`This media is not one StillMade gave this Block.`));d();let s=e.previewMedia(r).then(e=>(a.add(e.url),l.set(e.url,n),e.blob&&c.set(e.url,e.blob),e.url)),u=r.kind===`image`?s.catch(()=>e.previewImage(r).then(e=>e.url)):s;return i.set(n,u),u.then(e=>o.set(n,e),()=>i.delete(n)),u},g=e=>{let t=p(e)||e;if(!s.has(t)){let e=h(t).then(e=>c.get(e)||(m(t)?.kind===`image`?vp(e):Promise.reject(Error(`This media can only be played here, not read.`))));s.set(t,e),e.catch(()=>s.delete(t))}return s.get(t)},_=(e,t,n)=>{m(n)&&h(n).then(r=>{e.getAttribute(t)===n&&(e.dataset.stillmadeSource=n,e.setAttribute(t,r))},()=>{})},v=`img[src],video[src],audio[src],source[src],image[href]`,y=e=>{for(let t of[`src`,`href`]){let n=e.getAttribute?.(t);n&&/^(https?:|\\/api\\/)/.test(n)&&_(e,t,n)}let t=e.style?.backgroundImage,n=t&&/url\\([\"']?([^\"')]+)[\"']?\\)/.exec(t);n&&/^(https?:|\\/api\\/)/.test(n[1])&&m(n[1])&&h(n[1]).then(n=>{e.style.backgroundImage===t&&(e.style.backgroundImage=`url(\"${n}\")`)},()=>{})},b=e=>{if(e?.querySelectorAll){(e.matches?.(v)||e.style?.backgroundImage)&&y(e);for(let t of e.querySelectorAll(v))y(t);for(let t of e.querySelectorAll(`[style*=\"url(\"]`))y(t)}},x=new MutationObserver(e=>{for(let t of e)if(t.type===`attributes`)y(t.target);else for(let e of t.addedNodes)b(e)});x.observe(t,{subtree:!0,childList:!0,attributes:!0,attributeFilter:[`src`,`href`,`style`]});let S=[];if(n){let e=new WeakMap,t=(t,n,r)=>{let i=o.get(n);if(i){e.delete(t),t.dataset.stillmadeSource=n,r(i);return}e.set(t,n),h(n).then(i=>{e.get(t)===n&&(e.delete(t),t.dataset.stillmadeSource=n,r(i))},()=>{e.get(t)===n&&e.delete(t)})};for(let n of[globalThis.HTMLImageElement,globalThis.HTMLMediaElement,globalThis.HTMLSourceElement]){let r=n&&Object.getOwnPropertyDescriptor(n.prototype,`src`);r?.set&&r.get&&(Object.defineProperty(n.prototype,\"src\",{...r,get(){let e=r.get.call(this),t=this.dataset?.stillmadeSource;return t&&o.get(t)===e?t:e},set(n){let i=p(String(n));if(!i)return e.delete(this),delete this.dataset.stillmadeSource,r.set.call(this,n);(this.dataset.stillmadeSource!==i||r.get.call(this)!==o.get(i))&&t(this,i,e=>r.set.call(this,e))}}),S.push(()=>Object.defineProperty(n.prototype,\"src\",r)))}let n=Element.prototype.setAttribute;Element.prototype.setAttribute=function(e,r){let i=String(e).toLowerCase()===`src`&&(this instanceof HTMLImageElement||this instanceof HTMLMediaElement||this instanceof HTMLSourceElement)?p(String(r)):null;if(!i)return n.call(this,e,r);(this.dataset.stillmadeSource!==i||this.getAttribute(`src`)!==o.get(i))&&t(this,i,e=>n.call(this,`src`,e))},S.push(()=>{Element.prototype.setAttribute=n});let r=globalThis.Audio;if(r){let e=function(e){let t=new r;return e!==void 0&&(t.src=e),t};e.prototype=r.prototype,globalThis.Audio=e,S.push(()=>{globalThis.Audio=r})}let i=globalThis.fetch;i&&(globalThis.fetch=function(e,t){let n=p(typeof e==`string`?e:e?.url);return n?g(n).then(e=>new Response(e,{status:200,headers:{\"Content-Type\":e.type||`application/octet-stream`}})):i.call(globalThis,e,t)},S.push(()=>{globalThis.fetch=i}))}return e.onInput(e=>{f(e),b(t)}),e.onShared(e=>{f(e?.outputs),b(t)}),Object.freeze({remember:f,refFor:m,load:h,blob:g,dispose(){x.disconnect();for(let e of S.splice(0))e();for(let t of a)e.releaseMedia(t);a.clear(),i.clear(),o.clear(),s.clear(),c.clear()}})}let bp=Object.freeze([`auto`,`21:9`,`16:9`,`3:2`,`4:3`,`1:1`,`4:5`,`3:4`,`2:3`,`9:16`]),xp=Object.freeze([`auto`,`21:9`,`16:9`,`4:3`,`1:1`,`3:4`,`9:16`]),Sp=Object.freeze([4,5,6,7,8,9,10,11,12,13,14,15]),Cp=(e,{aspectRatios:t,resolutions:n=[],qualities:r=[],references:i=0,seed:a=!1})=>Object.freeze({label:e,aspectRatios:Object.freeze(t),resolutions:Object.freeze(n),qualities:Object.freeze(r),references:i,seed:a}),wp=(e,{aspectRatios:t=[],resolutions:n=[],durations:r,firstFrame:i=!0,lastFrame:a=!1,requiresFirstFrame:o=!1,seed:s=!1,nativeAudio:c=!1})=>Object.freeze({label:e,aspectRatios:Object.freeze(t),resolutions:Object.freeze(n),durations:Object.freeze(r),firstFrame:i,lastFrame:a,requiresFirstFrame:o,seed:s,nativeAudio:c}),Tp=Object.freeze({\"nano-banana-2\":Cp(`Nano Banana 2`,{aspectRatios:bp,resolutions:[`1K`,`2K`,`4K`],references:8,seed:!0}),\"nano-banana-2-lite\":Cp(`Nano Banana 2 Lite`,{aspectRatios:bp,resolutions:[`1K`,`2K`,`4K`],references:8,seed:!0}),\"nano-banana-pro\":Cp(`Nano Banana Pro`,{aspectRatios:bp,resolutions:[`1K`,`2K`,`4K`],references:8,seed:!0}),\"gpt-image-2\":Cp(`GPT Image 2`,{aspectRatios:[`auto`,`16:9`,`9:16`,`1:1`,`4:3`,`3:4`],resolutions:[`1K`,`2K`,`4K`],qualities:[`low`,`medium`,`high`],references:8}),\"gpt-image-2.5-flare\":Cp(`GPT Image 2.5 Flare`,{aspectRatios:[`auto`,`16:9`,`9:16`,`1:1`,`4:3`,`3:4`],resolutions:[`1K`,`2K`,`4K`],qualities:[`low`,`medium`,`high`],references:8}),\"gpt-image-2.5-sunburst\":Cp(`GPT Image 2.5 Sunburst`,{aspectRatios:[`auto`,`16:9`,`9:16`,`1:1`,`4:3`,`3:4`],resolutions:[`1K`,`2K`,`4K`],qualities:[`low`,`medium`,`high`],references:8}),\"gpt-image-2.6-flare\":Cp(`GPT Image 2.6 Flare`,{aspectRatios:[`auto`,`16:9`,`9:16`,`1:1`,`4:3`,`3:4`],resolutions:[`1K`,`2K`,`4K`],qualities:[`low`,`medium`,`high`],references:8}),\"gpt-image-2.6-sunburst\":Cp(`GPT Image 2.6 Sunburst`,{aspectRatios:[`auto`,`16:9`,`9:16`,`1:1`,`4:3`,`3:4`],resolutions:[`1K`,`2K`,`4K`],qualities:[`low`,`medium`,`high`],references:8}),\"gpt-image-1.5\":Cp(`GPT-Image 1.5`,{aspectRatios:[`16:9`,`9:16`,`1:1`],qualities:[`low`,`medium`,`high`]}),\"kling-image-v3\":Cp(`Kling Image V3`,{aspectRatios:[`21:9`,`16:9`,`9:16`,`1:1`,`4:3`,`3:4`,`3:2`,`2:3`],resolutions:[`1K`,`2K`]}),\"seedream-v4.5\":Cp(`Seedream 4.5`,{aspectRatios:[`16:9`,`9:16`,`1:1`,`4:3`,`3:4`],resolutions:[`2K`,`4K`],seed:!0})}),Ep=Object.freeze({\"seedance-2.0\":wp(`Seedance 2.0`,{aspectRatios:xp,resolutions:[`480p`,`720p`,`1080p`,`4k`],durations:Sp,lastFrame:!0,seed:!0,nativeAudio:!0}),\"seedance-2.0-fast\":wp(`Seedance 2.0 Fast`,{aspectRatios:xp,resolutions:[`480p`,`720p`],durations:Sp,lastFrame:!0,seed:!0,nativeAudio:!0}),\"seedance-2.0-mini\":wp(`Seedance 2.0 Mini`,{aspectRatios:xp,resolutions:[`480p`,`720p`],durations:Sp,lastFrame:!0,seed:!0,nativeAudio:!0}),\"kling-v3-turbo\":wp(`Kling 3.0 Turbo`,{aspectRatios:[`16:9`,`9:16`,`1:1`],durations:[5,10]}),\"wan-2.6-flash\":wp(`Wan 2.6 Flash`,{aspectRatios:[`16:9`,`9:16`,`1:1`],durations:[3,4,5],requiresFirstFrame:!0}),\"veo-3.1-lite\":wp(`Veo 3.1 Lite`,{aspectRatios:[`16:9`,`9:16`],resolutions:[`720p`,`1080p`],durations:[4,6,8],lastFrame:!0,nativeAudio:!0}),\"vidu-q3-turbo\":wp(`Vidu Q3 Turbo`,{durations:[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16],lastFrame:!0,nativeAudio:!0}),\"wan-2.7\":wp(`Wan 2.7`,{resolutions:[`720p`,`1080p`],durations:[2,3,4,5,6,7,8,9,10,11,12,13,14,15],lastFrame:!0,requiresFirstFrame:!0,seed:!0})});Object.freeze([`model`,`aspectRatio`,`resolution`,`quality`]),Object.freeze([`model`,`duration`,`resolution`,`aspectRatio`,`generateAudio`]),Object.freeze({references:8,negativePrompt:2e3,seed:2147483647}),Object.freeze([`wan-2.6-flash`,`veo-3.1-lite`,`seedance-2.0-mini`,`kling-v3-turbo`,`seedance-2.0-fast`,`seedance-2.0`]),Object.freeze({speech:Object.freeze({text:3800,defaultVoice:`asteria`,speed:Object.freeze({min:.25,max:4,default:1})}),music:Object.freeze({min:5,max:240,default:30}),sfx:Object.freeze({min:.5,max:22,default:4})});let Dp=e=>{let t=Tp[e];return{value:e,label:t.label,supports:{aspectRatio:[...t.aspectRatios],resolution:[...t.resolutions],quality:[...t.qualities]}}},Op=e=>{let t=Ep[e];return{value:e,label:t.label,supports:{aspectRatio:[...t.aspectRatios],resolution:[...t.resolutions],quality:[],duration:[...t.durations]}}},kp=[`nano-banana-2`,`nano-banana-2-lite`,`nano-banana-pro`,`gpt-image-1.5`,`gpt-image-2`,`gpt-image-2.5-flare`,`gpt-image-2.5-sunburst`,`gpt-image-2.6-flare`,`gpt-image-2.6-sunburst`,`kling-image-v3`,`seedream-v4.5`].map(Dp);[...[`seedance-2.0`,`seedance-2.0-fast`,`seedance-2.0-mini`,`kling-v3-turbo`,`wan-2.6-flash`,`veo-3.1-lite`,`vidu-q3-turbo`].map(Op)];var Ap=c({APP_AI_BUDGET_USD:()=>om,BLOCK_BUILD_BUDGET_USD:()=>nm,CHAT_REPLY_BUDGET_USD:()=>rm,CHAT_WEB_SEARCH_USD:()=>im,CREDIT_VALUE_USD:()=>jp,FLAT:()=>tm,IMAGE:()=>Vp,LARGEST_TEXT_CALL:()=>Yp,MARKUP:()=>Mp,MUSIC:()=>Up,SFX:()=>Wp,SPEECH:()=>Hp,TEXT_MODELS:()=>Gp,TEXT_MODELS_CHECKED:()=>Kp,TYPICAL_TEXT_CALL:()=>Jp,UNREPORTED_CALL_USD:()=>am,VIDEO:()=>zp,VIDEO_ALIASES:()=>Bp,exactCredits:()=>Np,imageUsd:()=>lm,largestTextCallUsd:()=>$p,milliCredits:()=>Fp,musicUsd:()=>fm,sfxUsd:()=>pm,sizedTextCallCredits:()=>Zp,speechUsd:()=>dm,textCallCredits:()=>Xp,typicalTextCallUsd:()=>Qp,usdCoveredBy:()=>Ip,videoModelId:()=>cm,videoUsd:()=>um,wholeCredits:()=>Pp});let jp=2399/11e4,Mp=Object.freeze({video:3,build:3,media:4.5,other:3,chat:2}),Np=(e,t)=>Math.max(0,Number(e)||0)*Mp[t]/jp,Pp=(e,t)=>Math.max(1,Math.ceil(Np(e,t)-1e-9)),Fp=(e,t=`chat`)=>Math.ceil(Np(e,t)*1e3-1e-6),Ip=(e,t)=>Math.max(0,Number(e)||0)*jp/Mp[t],Lp=`2026-11-05`,Rp=`carried`,zp=Object.freeze({\"veo-3.1-lite\":{usd:.05,resolution:{\"720p\":1,\"1080p\":1.6},provider:`Atlas`,checked:Lp,source:`Atlas catalog list price $0.05/s; 1080p at $0.08/s, Google's Veo 3.1 Lite step`},\"vidu-q3-turbo\":{usd:.04,provider:`Atlas`,checked:Lp,source:`Atlas catalog list price (we pay $0.034)`},\"wan-2.6-flash\":{usd:.025,provider:`Atlas`,checked:Lp,source:`Atlas catalog list price (we pay $0.018)`},\"wan-2.7\":{usd:.17,provider:`Higgsfield, then Atlas`,checked:Rp,source:`Atlas $0.10/s at 720p (checked); the 1.7x step to the 1080p we generate is carried from the old table`},\"kling-v3-turbo\":{usd:.112,provider:`Higgsfield, then Atlas`,checked:Lp,source:`Atlas catalog list price (we pay $0.095); Higgsfield $0.056/s on promotion`},\"seedance-2.0\":{usd:.2,resolution:{\"480p\":1,\"720p\":1.3,\"1080p\":3.2,\"4k\":7.5},provider:`BytePlus Ark`,checked:Rp,source:`Ark is priced per token and its price page does not load without an account; carried from the old table (verify against an Ark invoice)`},\"seedance-2.0-fast\":{usd:.09,resolution:{\"480p\":1,\"720p\":1.3},provider:`BytePlus Ark`,checked:Rp,source:`carried from the old table (Atlas lists $0.09/s)`},\"seedance-2.0-mini\":{usd:.09,resolution:{\"480p\":1,\"720p\":1.3},provider:`BytePlus Ark`,checked:Rp,source:`priced as Fast, carried from the old table (Atlas lists $0.056/s)`}}),Bp=Object.freeze({\"seedance-2\":`seedance-2.0`,\"kling-3\":`kling-v3-turbo`,\"kling-v3-pro\":`kling-v3-turbo`,\"kling-v3-std\":`kling-v3-turbo`,\"kling-o3-std\":`kling-v3-turbo`}),Vp=Object.freeze({\"gpt-image-2\":{quality:{low:{\"1K\":.006,\"2K\":.007,\"4K\":.012},medium:{\"1K\":.053,\"2K\":.056,\"4K\":.101},high:{\"1K\":.211,\"2K\":.222,\"4K\":.401}},referenceUsd:.02,provider:`OpenAI for square, fal then Atlas for other shapes`,checked:Lp,source:`fal gpt-image-2 price table (dearest size in each class); OpenAI direct is $30 per million output tokens`},\"gpt-image-2.5-flare\":{quality:{low:{\"1K\":.00588,\"2K\":.00615,\"4K\":.01113},medium:{\"1K\":.01317,\"2K\":.01434,\"4K\":.02595},high:{\"1K\":.05268,\"2K\":.05529,\"4K\":.10008}},referenceUsd:.02,provider:`OpenAI for square, fal for other shapes`,checked:`2026-11-06`,source:`fal openai/gpt-image-2.5/flare price table; OpenAI rate card $30 per million output tokens`},\"gpt-image-2.5-sunburst\":{quality:{low:{\"1K\":.00588,\"2K\":.00615,\"4K\":.01113},medium:{\"1K\":.01317,\"2K\":.01434,\"4K\":.02595},high:{\"1K\":.05268,\"2K\":.05529,\"4K\":.10008}},referenceUsd:.02,provider:`OpenAI for square, fal for other shapes`,checked:`2026-11-06`,source:`fal openai/gpt-image-2.5/sunburst price table; OpenAI rate card $30 per million output tokens`},\"gpt-image-2.6-flare\":{quality:{low:{\"1K\":.00588,\"2K\":.00615,\"4K\":.01113},medium:{\"1K\":.01317,\"2K\":.01434,\"4K\":.02595},high:{\"1K\":.05268,\"2K\":.05529,\"4K\":.10008}},referenceUsd:.02,provider:`OpenAI for square, fal for other shapes`,checked:`2026-11-07`,source:`OpenAI and fal gpt-image-2.6 token rates ($30 per million output tokens); per-image price taken from 2.5 until published`},\"gpt-image-2.6-sunburst\":{quality:{low:{\"1K\":.00588,\"2K\":.00615,\"4K\":.01113},medium:{\"1K\":.01317,\"2K\":.01434,\"4K\":.02595},high:{\"1K\":.05268,\"2K\":.05529,\"4K\":.10008}},referenceUsd:.02,provider:`OpenAI for square, fal for other shapes`,checked:`2026-11-07`,source:`OpenAI and fal gpt-image-2.6 token rates ($30 per million output tokens); per-image price taken from 2.5 until published`},\"gpt-image-1.5\":{quality:{low:{\"1K\":.013},medium:{\"1K\":.051},high:{\"1K\":.2}},provider:`fal`,checked:Lp,source:`fal price for a non-square image`},\"nano-banana-2\":{usd:.08,resolution:{\"1K\":1,\"2K\":1.5,\"4K\":2},provider:`fal`,checked:Lp,source:`fal: $0.08 at 1K, 1.5x at 2K, 2x at 4K`},\"nano-banana-2-lite\":{usd:.048,provider:`fal`,checked:Lp,source:`fal: $37.50 per million output tokens, one 1K image (about 1,290 tokens)`},\"nano-banana-pro\":{usd:.15,resolution:{\"1K\":1,\"2K\":1,\"4K\":2},provider:`fal`,checked:Lp,source:`fal: $0.15, 4K at double`},\"kling-image-v3\":{usd:.028,provider:`fal`,checked:Lp,source:`fal: $0.028 per image`},\"seedream-v4.5\":{usd:.04,provider:`fal`,checked:Lp,source:`fal: $0.04 per image`},\"flux-step\":{usd:.02,provider:`fal`,checked:Rp,source:`carried from the old table`},flux:{usd:.04,provider:`fal`,checked:Rp,source:`carried from the old table`},ideogram:{usd:.08,provider:`fal`,checked:Rp,source:`carried from the old table`},gemini:{usd:.08,resolution:{\"1K\":1,\"2K\":1.5,\"4K\":2},provider:`fal`,checked:Lp,source:`served as Nano Banana 2`}}),Hp=Object.freeze({deepgram:{usdPer1kChars:.03,checked:Lp,source:`Deepgram Aura-2 pay as you go`},openai:{usdPer1kChars:.015,checked:Lp,source:`OpenAI tts-1, $15 per million characters`},elevenlabs:{usdPer1kChars:.04,checked:Lp,source:`ElevenLabs API, Flash / Turbo`},kokoro:{usdPer1kChars:.02,checked:Lp,source:`fal Kokoro`}}),Up=Object.freeze({usdPerSecond:2e-4,checked:Lp,source:`fal ACE-Step, per second of audio`}),Wp=Object.freeze({usdPerSecond:.002,checked:Lp,source:`fal ElevenLabs sound effects v2, per second`}),Gp=Object.freeze({\"openai/gpt-5-mini\":{input:.25,output:2},\"google/gemini-2.5-flash\":{input:.3,output:2.5},\"anthropic/claude-haiku-5.5\":{input:.1,output:.5},\"anthropic/claude-sonnet-4\":{input:3,output:15},\"anthropic/claude-sonnet-4.5\":{input:3,output:15},\"anthropic/claude-sonnet-5.5\":{input:2,output:10},\"openai/gpt-5.4\":{input:2.5,output:15},\"google/gemini-2.5-pro\":{input:1.25,output:10},\"x-ai/grok-4.5\":{input:2,output:6},\"x-ai/grok-4.20\":{input:1.25,output:2.5},\"anthropic/claude-opus-4.1\":{input:15,output:75},\"anthropic/claude-opus-4.5\":{input:5,output:25},\"anthropic/claude-opus-4.8\":{input:5,output:25},\"openai/gpt-5.5\":{input:5,output:30}}),Kp=Lp,qp=(e,t,n)=>{let r=Gp[e];return r?(t*r.input+n*r.output)/1e6:null},Jp=Object.freeze({input:2e3,output:1e3}),Yp=Object.freeze({input:1e4,output:4096});function Xp(e){let t=qp(e,Jp.input,Jp.output),n=qp(e,Yp.input,Yp.output);return t===null?null:Math.max(Pp(t,`media`),Math.ceil(n/jp-1e-9))}function Zp(e,{inputBytes:t=0,maxTokens:n=0}={}){let r=Xp(e);if(r===null)return null;if(t<=4e4&&n<=Yp.output)return r;let i=qp(e,Math.ceil(t/4),Math.min(n,Math.max(Jp.output,Math.ceil(n/3)))),a=qp(e,t+64,n);return Math.max(r,Pp(i,`media`),Math.ceil(a/jp-1e-9))}let Qp=e=>qp(e,Jp.input,Jp.output),$p=e=>qp(e,Yp.input,Yp.output),em=(e,t,n,r,i={})=>Object.freeze({usd:e,tier:t,unit:n,source:r,checked:i.checked||Rp,...i}),tm=Object.freeze({\"media:analyze\":em(.02,`media`,`call`,`the vision provider caps a call at $0.02 (VISION_MAX_INITIAL_COST)`,{checked:Lp}),\"media:check\":em(.005,`media`,`call`,`four photos at most, $0.00125 each (MEDIA_CHECK_IMAGE_USD)`,{checked:Lp}),\"research:search\":em(.008,`media`,`search`,`Tavily basic search`,{checked:Lp}),\"research:summarize\":em(.01,`media`,`call`,`one Gemini Flash read of fetched pages`,{estimate:!0}),\"transcribe:timestamp\":em(.01,`media`,`run`,`fal Whisper word timing`,{estimate:!0}),\"transcribe:upload\":em(.01,`media`,`run`,`fal Whisper word timing`,{estimate:!0}),\"transcribe:captions\":em(.01,`media`,`run`,`fal Whisper word timing`,{estimate:!0}),\"connection:action\":em(.012,`other`,`action`,`a premium Composio tool call at the overage rate`,{checked:Lp}),\"automation:app-event\":em(.003,`other`,`event`,`Composio, per trigger event`,{checked:Lp}),\"automation:app-check\":em(3e-4,`other`,`check`,`Composio, per tool call`,{checked:Lp}),llm:em(.01,`other`,`call`,`a Standard model call`,{estimate:!0}),vision:em(.01,`other`,`image`,`one vision read`,{estimate:!0}),\"narrative:compile\":em(.06,`other`,`script`,`about ten Gemini Flash calls`,{estimate:!0}),\"narrative:compile-research\":em(.1,`other`,`script`,`the compile plus three Tavily searches and a dossier`,{estimate:!0}),\"narrative:learn-voice\":em(.01,`other`,`call`,`one extraction call`,{estimate:!0}),\"roughcut:base\":em(.05,`other`,`run`,`segmentation and matching`,{estimate:!0}),\"roughcut:per-min\":em(.015,`other`,`footage minute`,`Gemini Flash frame reads`,{estimate:!0}),\"finaledit:base\":em(.06,`other`,`run`,`polish decisions`,{estimate:!0}),\"finaledit:per-min\":em(.02,`other`,`video minute`,`Gemini Flash scan`,{estimate:!0}),\"aomotion:base\":em(.06,`other`,`run`,`motion graphics pass`,{estimate:!0}),\"aomotion:per-min\":em(.02,`other`,`video minute`,`motion graphics pass`,{estimate:!0}),\"aomotion:base:opus\":em(.12,`other`,`run`,`motion graphics pass on Opus`,{estimate:!0}),\"aomotion:per-min:opus\":em(.04,`other`,`video minute`,`motion graphics pass on Opus`,{estimate:!0}),motiongraphic:em(.015,`other`,`graphic`,`one small call`,{estimate:!0}),\"transcript:parse\":em(.005,`other`,`1,000 characters`,`Gemini Flash word timing`,{estimate:!0}),\"vibe-edit\":em(.02,`other`,`turn`,`Flash region scan and decision`,{estimate:!0}),\"canvas:context-connect\":em(.01,`other`,`run`,`one canvas read`,{estimate:!0}),\"anim2:plan\":em(.03,`other`,`video`,`shot planning`,{estimate:!0}),\"anim2:vibe\":em(.03,`other`,`turn`,`scene vibe turn`,{estimate:!0}),\"anim2:qa\":em(.03,`other`,`frame`,`vision QA`,{estimate:!0}),\"anim2:trigger\":em(.01,`other`,`scene`,`one Haiku call`,{estimate:!0}),\"gif:plan\":em(.03,`other`,`pass`,`GIF planning`,{estimate:!0}),\"canvas:plan\":em(.03,`other`,`pass`,`collage planning`,{estimate:!0}),\"canvasChat:build\":em(.03,`other`,`build`,`canvas chat orchestration`,{estimate:!0}),\"strip:plan\":em(.05,`other`,`pass`,`strip planning`,{estimate:!0}),\"panel:qa\":em(.03,`other`,`pass`,`style-consistency vision pass`,{estimate:!0})}),nm=Object.freeze({standard:.4,balanced:.85,reasoning:.5,premium:1.4}),rm=.06,im=.008,am=Object.freeze({build:.1,chat:.005,other:.05}),om=.25,sm=(e,t,n)=>e&&Object.hasOwn(e,t)?t:n,cm=e=>{let t=String(e||``).toLowerCase();return zp[t]?t:Bp[t]||(t.includes(`kling`)?`kling-v3-turbo`:t.includes(`seedance`)?`seedance-2.0`:`wan-2.6-flash`)};function lm({model:e=`gpt-image-2`,quality:t,resolution:n,references:r}={}){let i=Vp[e]||Vp[`gpt-image-2`],a=String(n||``).toUpperCase(),o=r===void 0||Number(r)>0;if(i.quality){let e=i.quality[sm(i.quality,String(t||``).toLowerCase(),`low`)];return e[sm(e,a,`1K`)]+(o&&i.referenceUsd||0)}return i.usd*(i.resolution?.[sm(i.resolution,a,`1K`)]??1)}function um({model:e,seconds:t=6,resolution:n}={}){let r=zp[cm(e)],i=r.resolution||{},a=sm(i,String(n||``).toLowerCase(),Object.hasOwn(i,`720p`)?`720p`:Object.keys(i)[0]);return r.usd*(i[a]??1)*Math.max(1,Math.ceil(Number(t)||6))}function dm({chars:e,seconds:t,provider:n=`deepgram`}={}){return(Hp[n]||Hp.elevenlabs).usdPer1kChars*(Number(e)>0?Number(e):Math.max(1,Number(t)||30)*12.5)/1e3}let fm=e=>Up.usdPerSecond*e,pm=e=>Wp.usdPerSecond*e;Object.freeze(Object.fromEntries([`openai/gpt-5-mini`,`google/gemini-2.5-flash`,`anthropic/claude-sonnet-4`,`anthropic/claude-sonnet-4.5`,`openai/gpt-5.4`,`google/gemini-2.5-pro`,`x-ai/grok-4.5`,`x-ai/grok-4.20`,`anthropic/claude-opus-4.1`,`anthropic/claude-opus-4.5`,`anthropic/claude-opus-4.8`,`openai/gpt-5.5`].map(e=>[e,Xp(e)])))[`anthropic/claude-sonnet-4.5`],Object.fromEntries([{value:`openai/gpt-5-mini`,label:`GPT-5 mini`},{value:`google/gemini-2.5-flash`,label:`Gemini 2.5 Flash`},{value:`anthropic/claude-opus-4.8`,label:`Claude Opus 4.8`},{value:`anthropic/claude-opus-4.5`,label:`Claude Opus 4.5`},{value:`anthropic/claude-opus-4.1`,label:`Claude Opus 4.1`},{value:`anthropic/claude-sonnet-4.5`,label:`Claude Sonnet 4.5`},{value:`anthropic/claude-sonnet-4`,label:`Claude Sonnet 4`},{value:`openai/gpt-5.5`,label:`GPT-5.5`},{value:`openai/gpt-5.4`,label:`GPT-5.4`},{value:`google/gemini-2.5-pro`,label:`Gemini 2.5 Pro`},{value:`x-ai/grok-4.20`,label:`Grok 4.20`},{value:`x-ai/grok-4.5`,label:`Grok 4.5`}].map(e=>[e.value,e.label])),Object.fromEntries([{slug:`standard`,label:`Standard`,blurb:`Fast everyday — free on a plan`,model:`google/gemini-2.5-flash`},{slug:`balanced`,label:`Balanced`,blurb:`Stronger & quick`,model:`anthropic/claude-sonnet-4.5`},{slug:`reasoning`,label:`Reasoning`,blurb:`Deepest, most careful`,model:`google/gemini-2.5-pro`},{slug:`premium`,label:`Premium`,blurb:`Best writing`,model:`anthropic/claude-opus-4.8`}].map(e=>[e.slug,e]));let{wholeCredits:mm,exactCredits:hm,FLAT:gm}=Ap,_m=e=>mm(gm[e].usd,gm[e].tier),vm=e=>mm(e,`other`),ym=Object.freeze({LLM_CHAT_MESSAGE:vm(.01),LLM_BIBLE_GENERATION:vm(.05),LLM_CANVAS_GENERATION:vm(.03),LLM_VOICEOVER_SHOT_ANALYSIS:vm(.01),LLM_MOOD_MAP_GENERATION:vm(.01),LLM_MUSIC_PROMPT_GENERATION:vm(.01),LLM_AUTO_EDIT_ANALYSIS:vm(.01),LLM_GENERIC:vm(.01),\"project:assistant\":Math.ceil(hm(rm,`chat`)-1e-9),\"chat:web-search\":hm(im,`chat`),\"narrative:compile\":_m(`narrative:compile`),\"narrative:compile-research\":_m(`narrative:compile-research`),\"narrative:learn-voice\":_m(`narrative:learn-voice`),VISION_EXTERNAL_VIDEO_ANALYSIS:vm(.02),VISION_AUTO_ANALYZE_PER_IMAGE:_m(`vision`),...Object.fromEntries(Object.keys(Vp).map(e=>[`IMAGE_${e}`,mm(lm({model:e}),`media`)])),...Object.fromEntries(Object.keys(zp).map(e=>[`VIDEO_${e}`,hm(um({model:e,seconds:1}),`video`)])),VOICEOVER_PER_MINUTE:mm(dm({seconds:60}),`media`),\"transcribe:timestamp\":_m(`transcribe:timestamp`),\"transcribe:upload\":_m(`transcribe:upload`),\"transcribe:captions\":_m(`transcribe:captions`),MUSIC_PER_MINUTE:mm(fm(60),`media`),SFX_PER_GENERATION:mm(pm(4),`media`),ROUGHCUT_BASE:_m(`roughcut:base`),ROUGHCUT_PER_MINUTE:_m(`roughcut:per-min`),FINALEDIT_BASE:_m(`finaledit:base`),FINALEDIT_PER_MINUTE:_m(`finaledit:per-min`),AOMOTION_BASE:_m(`aomotion:base`),AOMOTION_PER_MINUTE:_m(`aomotion:per-min`),AOMOTION_BASE_OPUS:_m(`aomotion:base:opus`),AOMOTION_PER_MINUTE_OPUS:_m(`aomotion:per-min:opus`),MOTIONGRAPHIC:_m(`motiongraphic`),\"transcript:parse\":_m(`transcript:parse`),VIBE_EDIT:_m(`vibe-edit`),RESEARCH_SEARCH:_m(`research:search`),RESEARCH_SUMMARIZE:_m(`research:summarize`),MEDIA_ANALYZE:_m(`media:analyze`),MEDIA_CHECK:_m(`media:check`),CONNECTION_ACTION:_m(`connection:action`),\"automation:app-events\":1,\"automation:app-checks\":1,CONTEXT_CONNECT:_m(`canvas:context-connect`),\"anim2:plan\":_m(`anim2:plan`),\"anim2:vibe\":_m(`anim2:vibe`),\"anim2:qa\":_m(`anim2:qa`),\"anim2:trigger\":_m(`anim2:trigger`),\"gif:plan\":_m(`gif:plan`),\"canvas:plan\":_m(`canvas:plan`),\"canvasChat:build\":_m(`canvasChat:build`),\"strip:plan\":_m(`strip:plan`),\"panel:qa\":_m(`panel:qa`),IMAGE_MOTION_EFFECT:0});ym.RESEARCH_SEARCH+ym.RESEARCH_SUMMARIZE,ym.RESEARCH_SUMMARIZE,ym.CONTEXT_CONNECT,ym[`project:assistant`],ym[`chat:web-search`],Object.freeze(Object.fromEntries(Object.entries(nm).map(([e,t])=>[e,mm(t,`build`)])));function bm(e,t=1,n={}){return mm(lm({model:e||`gpt-image-2.5-sunburst`,quality:n.quality,resolution:n.resolution,references:n.references})*Math.max(1,t||1),`media`)}function xm(e,t=6,n=1,r={}){return mm(um({model:e,seconds:t||6,resolution:r.resolution}),`video`)*Math.max(1,n||1)}hm(5e-4,`other`),Object.freeze({providerUsd:`0.000300`,readCredits:1,writeCredits:2}),Math.floor(jp/(gm[`automation:app-event`].usd*Mp.other)),Math.floor(jp/(gm[`automation:app-check`].usd*Mp.other));function Sm(e,t={}){let{approx:n=!1,suffix:r=``}=t;return`(${n?`~`:``}${Math.max(0,Math.round(e||0))} cr${r?` + ${r}`:``})`}let Cm=Object.freeze({\"stillmade-internal.automatic-zoom@1.0.0\":function(e){function t(e){if(e.operation===`pending`)return{pending:e.data.rows.filter(e=>e.type===`zoom`&&e.sourceReady&&(!e.hasTarget||!e.hasImage)).map(e=>e.origin)};let t=e.data.target,n=e.data.reuse?t:{fx:Number.isFinite(Number(t?.fx))?Number(t.fx):50,fy:Number.isFinite(Number(t?.fy))?Number(t.fy):50,scale:Number.isFinite(Number(t?.scale))?Number(t.scale):1.8,pickedBy:`vision`},{fx:r=50,fy:i=50,scale:a=1.8}=n,o=Math.max(1.2,Math.min(3,Number(a)||1.8)),s=Math.max(0,Math.min(100,Number(r)||0))/100,c=Math.max(0,Math.min(100,Number(i)||0))/100,l=1/o;return{zoom:n,rect:{x:s*(1-l),y:c*(1-l),w:l,h:l}}}return{plan:t(e)}},\"stillmade-internal.panel-canvas-absorb@1.0.0\":function(e){let t=(e,t,n,r,i,a,o,s)=>({id:e,name:t,scenario:n,minImages:r,slots:i,textSlots:a,pSlots:o,pTextSlots:s}),n=[t(`hero-headline`,`Hero + headline`,`one subject, one line`,1,[{x:.5,y:.58,w:.5,h:.62}],[{role:`headline`,x:.5,y:.14,size:.09,weight:900}],[{x:.5,y:.55,w:.78,h:.5}],[{role:`headline`,x:.5,y:.13,size:.055,weight:900}]),t(`hero-supporting`,`Hero + 2 supporting`,`main subject with two details`,3,[{x:.34,y:.55,w:.42,h:.58},{x:.78,y:.33,w:.28,h:.32},{x:.78,y:.73,w:.28,h:.32}],[{role:`headline`,x:.34,y:.13,size:.08,weight:900}],[{x:.5,y:.38,w:.78,h:.32},{x:.28,y:.72,w:.4,h:.2},{x:.72,y:.72,w:.4,h:.2}],[{role:`headline`,x:.5,y:.12,size:.05,weight:900}]),t(`compare-2`,`Side-by-side compare`,`A vs B`,2,[{x:.27,y:.5,w:.38,h:.5},{x:.73,y:.5,w:.38,h:.5}],[{role:`headline`,x:.5,y:.12,size:.08,weight:900},{role:`label`,x:.27,y:.84,size:.05,weight:800},{role:`label`,x:.73,y:.84,size:.05,weight:800}],[{x:.5,y:.35,w:.72,h:.24},{x:.5,y:.72,w:.72,h:.24}],[{role:`headline`,x:.5,y:.11,size:.05,weight:900},{role:`label`,x:.5,y:.51,size:.032,weight:800},{role:`label`,x:.5,y:.88,size:.032,weight:800}]),t(`three-across`,`Three across`,`three items`,3,[{x:.2,y:.5,w:.26,h:.46},{x:.5,y:.5,w:.26,h:.46},{x:.8,y:.5,w:.26,h:.46}],[{role:`headline`,x:.5,y:.13,size:.08,weight:900},{role:`caption`,x:.5,y:.86,size:.045,weight:600}],[{x:.5,y:.32,w:.64,h:.2},{x:.5,y:.57,w:.64,h:.2},{x:.5,y:.82,w:.64,h:.2}],[{role:`headline`,x:.5,y:.1,size:.05,weight:900},{role:`caption`,x:.5,y:.96,size:.028,weight:600}]),t(`grid-2x2`,`Grid of four`,`four items`,4,[{x:.3,y:.36,w:.32,h:.34},{x:.7,y:.36,w:.32,h:.34},{x:.3,y:.74,w:.32,h:.34},{x:.7,y:.74,w:.32,h:.34}],[{role:`headline`,x:.5,y:.09,size:.07,weight:900}],[{x:.28,y:.38,w:.4,h:.24},{x:.72,y:.38,w:.4,h:.24},{x:.28,y:.68,w:.4,h:.24},{x:.72,y:.68,w:.4,h:.24}],[{role:`headline`,x:.5,y:.12,size:.05,weight:900}]),t(`grid-3x3`,`Many small (3x3)`,`lots of items`,6,[.22,.5,.78].flatMap(e=>[.3,.56,.82].map(t=>({x:e,y:t,w:.24,h:.22}))),[{role:`headline`,x:.5,y:.08,size:.065,weight:900}],[.2,.5,.8].flatMap(e=>[.34,.58,.82].map(t=>({x:e,y:t,w:.27,h:.18}))),[{role:`headline`,x:.5,y:.1,size:.045,weight:900}]),t(`big-left-stack-right`,`Big lead + stack`,`one lead, several follow-ups`,3,[{x:.32,y:.54,w:.5,h:.62},{x:.79,y:.3,w:.3,h:.22},{x:.79,y:.56,w:.3,h:.22},{x:.79,y:.82,w:.3,h:.22}],[{role:`headline`,x:.32,y:.13,size:.075,weight:900}],[{x:.5,y:.4,w:.84,h:.34},{x:.2,y:.74,w:.26,h:.16},{x:.5,y:.74,w:.26,h:.16},{x:.8,y:.74,w:.26,h:.16}],[{role:`headline`,x:.5,y:.12,size:.05,weight:900}]),t(`vertical-stack`,`Vertical stack`,`ordered top to bottom`,2,[{x:.55,y:.29,w:.36,h:.22},{x:.55,y:.55,w:.36,h:.22},{x:.55,y:.81,w:.36,h:.22}],[{role:`headline`,x:.55,y:.08,size:.065,weight:900},{role:`label`,x:.16,y:.55,size:.055,weight:800}],[{x:.5,y:.3,w:.66,h:.2},{x:.5,y:.56,w:.66,h:.2},{x:.5,y:.82,w:.66,h:.2}],[{role:`headline`,x:.5,y:.09,size:.05,weight:900},{role:`label`,x:.24,y:.17,size:.032,weight:800}]),t(`scatter`,`Scattered collage`,`loose, hand-thrown feel`,3,[{x:.26,y:.36,w:.28,h:.32,tilt:-6},{x:.68,y:.3,w:.26,h:.3,tilt:4},{x:.44,y:.66,w:.27,h:.31,tilt:3},{x:.8,y:.62,w:.25,h:.29,tilt:-5},{x:.58,y:.46,w:.24,h:.28,tilt:2}],[{role:`headline`,x:.5,y:.1,size:.075,weight:900}],[{x:.32,y:.3,w:.46,h:.2,tilt:-6},{x:.7,y:.26,w:.42,h:.18,tilt:4},{x:.4,y:.56,w:.44,h:.2,tilt:3},{x:.74,y:.6,w:.4,h:.18,tilt:-5},{x:.5,y:.82,w:.44,h:.19,tilt:2}],[{role:`headline`,x:.5,y:.09,size:.045,weight:900}]),t(`timeline-row`,`Row / timeline`,`steps in order`,3,[{x:.14,y:.52,w:.2,h:.38},{x:.38,y:.52,w:.2,h:.38},{x:.62,y:.52,w:.2,h:.38},{x:.86,y:.52,w:.2,h:.38}],[{role:`headline`,x:.5,y:.15,size:.075,weight:900},{role:`caption`,x:.5,y:.85,size:.045,weight:600}],[{x:.35,y:.28,w:.5,h:.15},{x:.65,y:.47,w:.5,h:.15},{x:.35,y:.66,w:.5,h:.15},{x:.65,y:.85,w:.5,h:.15}],[{role:`headline`,x:.5,y:.12,size:.05,weight:900}]),t(`center-satellites`,`Center + satellites`,`one core idea, orbiting parts`,3,[{x:.5,y:.52,w:.34,h:.42},{x:.17,y:.3,w:.2,h:.26},{x:.83,y:.3,w:.2,h:.26},{x:.17,y:.77,w:.2,h:.26},{x:.83,y:.77,w:.2,h:.26}],[{role:`headline`,x:.5,y:.09,size:.065,weight:900}],[{x:.5,y:.52,w:.56,h:.28},{x:.2,y:.28,w:.32,h:.16},{x:.8,y:.28,w:.32,h:.16},{x:.2,y:.78,w:.32,h:.16},{x:.8,y:.78,w:.32,h:.16}],[{role:`headline`,x:.5,y:.1,size:.045,weight:900}]),t(`corner-big-text`,`Corner images, big text`,`statement first, proof beside it`,2,[{x:.72,y:.4,w:.32,h:.38},{x:.52,y:.72,w:.28,h:.34},{x:.85,y:.76,w:.24,h:.3}],[{role:`headline`,x:.26,y:.26,size:.105,weight:900},{role:`label`,x:.26,y:.42,size:.05,weight:600}],[{x:.36,y:.56,w:.5,h:.22},{x:.7,y:.7,w:.44,h:.2},{x:.4,y:.84,w:.4,h:.18}],[{role:`headline`,x:.5,y:.19,size:.065,weight:900},{role:`label`,x:.5,y:.31,size:.034,weight:600}]),t(`title-top-row`,`Title top, images below`,`title screen with evidence`,2,[{x:.22,y:.62,w:.28,h:.44},{x:.5,y:.62,w:.28,h:.44},{x:.78,y:.62,w:.28,h:.44}],[{role:`headline`,x:.5,y:.17,size:.1,weight:900}],[{x:.5,y:.4,w:.7,h:.2},{x:.5,y:.64,w:.7,h:.2},{x:.5,y:.86,w:.7,h:.16}],[{role:`headline`,x:.5,y:.15,size:.06,weight:900}]),t(`large-caption`,`One large + caption`,`let the image speak`,1,[{x:.5,y:.47,w:.56,h:.6}],[{role:`label`,x:.15,y:.1,size:.045,weight:800},{role:`caption`,x:.5,y:.85,size:.055,weight:600}],[{x:.5,y:.47,w:.82,h:.44}],[{role:`label`,x:.24,y:.12,size:.032,weight:800},{role:`caption`,x:.5,y:.78,size:.034,weight:600}]),t(`staggered-diagonal`,`Staggered diagonal`,`progression with motion`,3,[{x:.18,y:.26,w:.24,h:.3,tilt:-3},{x:.42,y:.45,w:.24,h:.3,tilt:3},{x:.64,y:.62,w:.24,h:.3,tilt:-3},{x:.86,y:.79,w:.24,h:.3,tilt:3}],[{role:`headline`,x:.74,y:.16,size:.075,weight:900}],[{x:.28,y:.3,w:.42,h:.18,tilt:-3},{x:.62,y:.46,w:.42,h:.18,tilt:3},{x:.36,y:.62,w:.42,h:.18,tilt:-3},{x:.68,y:.78,w:.42,h:.18,tilt:3}],[{role:`headline`,x:.5,y:.12,size:.05,weight:900}]),t(`overlap-stack`,`Overlapping stack`,`a deliberate pile`,2,[{x:.42,y:.5,w:.36,h:.46,tilt:-5},{x:.54,y:.56,w:.36,h:.46,tilt:3},{x:.63,y:.46,w:.36,h:.46,tilt:-2}],[{role:`headline`,x:.5,y:.12,size:.08,weight:900},{role:`caption`,x:.5,y:.89,size:.045,weight:600}],[{x:.44,y:.42,w:.58,h:.26,tilt:-5},{x:.58,y:.53,w:.58,h:.26,tilt:3},{x:.46,y:.64,w:.58,h:.26,tilt:-2}],[{role:`headline`,x:.5,y:.12,size:.05,weight:900},{role:`caption`,x:.5,y:.86,size:.032,weight:600}]),t(`banner-row`,`Wide banner + small row`,`one wide scene, details under`,2,[{x:.5,y:.36,w:.84,h:.36},{x:.25,y:.77,w:.24,h:.26},{x:.5,y:.77,w:.24,h:.26},{x:.75,y:.77,w:.24,h:.26}],[{role:`headline`,x:.5,y:.09,size:.065,weight:900}],[{x:.5,y:.36,w:.86,h:.26},{x:.22,y:.66,w:.28,h:.16},{x:.5,y:.66,w:.28,h:.16},{x:.78,y:.66,w:.28,h:.16}],[{role:`headline`,x:.5,y:.13,size:.05,weight:900},{role:`caption`,x:.5,y:.82,size:.032,weight:600}]),t(`quadrant-labels`,`Quadrants with labels`,`four named things`,4,[{x:.28,y:.3,w:.3,h:.3},{x:.72,y:.3,w:.3,h:.3},{x:.28,y:.71,w:.3,h:.3},{x:.72,y:.71,w:.3,h:.3}],[{role:`headline`,x:.5,y:.07,size:.06,weight:900},{role:`label`,x:.28,y:.49,size:.042,weight:800},{role:`label`,x:.72,y:.49,size:.042,weight:800},{role:`label`,x:.28,y:.9,size:.042,weight:800},{role:`label`,x:.72,y:.9,size:.042,weight:800}],[{x:.28,y:.32,w:.38,h:.2},{x:.72,y:.32,w:.38,h:.2},{x:.28,y:.64,w:.38,h:.2},{x:.72,y:.64,w:.38,h:.2}],[{role:`headline`,x:.5,y:.1,size:.045,weight:900},{role:`label`,x:.28,y:.45,size:.028,weight:800},{role:`label`,x:.72,y:.45,size:.028,weight:800},{role:`label`,x:.28,y:.77,size:.028,weight:800},{role:`label`,x:.72,y:.77,size:.028,weight:800}]),t(`pyramid-3`,`Pyramid of three`,`one above two`,3,[{x:.5,y:.32,w:.3,h:.32},{x:.32,y:.71,w:.3,h:.32},{x:.68,y:.71,w:.3,h:.32}],[{role:`headline`,x:.5,y:.08,size:.065,weight:900},{role:`caption`,x:.5,y:.92,size:.04,weight:600}],[{x:.5,y:.34,w:.5,h:.22},{x:.27,y:.62,w:.42,h:.18},{x:.73,y:.62,w:.42,h:.18}],[{role:`headline`,x:.5,y:.1,size:.05,weight:900},{role:`caption`,x:.5,y:.79,size:.032,weight:600}]),t(`mosaic-dense`,`Dense mosaic`,`everything at once`,5,[{x:.3,y:.4,w:.34,h:.42},{x:.62,y:.29,w:.24,h:.26},{x:.86,y:.33,w:.2,h:.28},{x:.19,y:.78,w:.24,h:.26},{x:.47,y:.77,w:.26,h:.28},{x:.73,y:.73,w:.22,h:.24},{x:.91,y:.76,w:.14,h:.18}],[{role:`headline`,x:.5,y:.09,size:.06,weight:900}],[{x:.32,y:.3,w:.5,h:.2},{x:.78,y:.26,w:.36,h:.16},{x:.24,y:.52,w:.4,h:.16},{x:.68,y:.5,w:.44,h:.18},{x:.3,y:.74,w:.42,h:.16},{x:.74,y:.73,w:.4,h:.16},{x:.5,y:.89,w:.5,h:.1}],[{role:`headline`,x:.5,y:.1,size:.045,weight:900}])],r=new Map(n.map(e=>[e.id,e])),i=e=>r.get(e)||null;function a(e,t=16/9){return e?t<1?{slots:e.pSlots,textSlots:e.pTextSlots}:{slots:e.slots,textSlots:e.textSlots}:null}function o(e,t,{aspect:n=16/9}={}){if(!t)return(e||[]).map(e=>{if(e.pinned||e.kind!==`image`||!e.box)return e;let{box:t,...n}=e;return n});let r=a(t,n),i=(e,t)=>(e.appearMs||0)-(t.appearMs||0),o=(e||[]).filter(e=>e.kind===`image`&&!e.pinned).sort(i),s=(e||[]).filter(e=>e.kind===`text`&&!e.pinned).sort(i),c=new Map;o.forEach((e,t)=>{t<r.slots.length&&c.set(e.id,r.slots[t])});let l=new Map;return s.forEach((e,t)=>{t<r.textSlots.length&&l.set(e.id,r.textSlots[t])}),(e||[]).map(e=>{if(e.pinned)return e;if(e.kind===`image`){let t=c.get(e.id);if(!t){let{box:t,...n}=e;return{...n,pos:null}}return{...e,pos:{x:t.x,y:t.y},box:{w:t.w,h:t.h},size:t.w,tilt:t.tilt||0}}let t=l.get(e.id);return t?{...e,pos:{x:t.x,y:t.y},size:t.size,weight:t.weight||e.weight||800}:e})}function s({imageCount:e=0,textCount:t=0,hint:n=``}={}){if(!e)return null;let r=String(n||``).toLowerCase();return e===2&&/\\bvs\\b|versus|compar|before.*after|either/.test(r)?`compare-2`:e>=3&&/step|order|sequence|timeline|process|journey|stages/.test(r)?`timeline-row`:e>=3&&/list|lists|enumerat|items|examples|types|kinds/.test(r)?e>=5?`mosaic-dense`:`three-across`:e===1?t>1?`large-caption`:`hero-headline`:e===2?`compare-2`:e===3?`three-across`:e===4?`grid-2x2`:e===5?`center-satellites`:e<=7?`mosaic-dense`:`grid-3x3`}let c=e=>{let t=5381,n=String(e||``);for(let e=0;e<n.length;e++)t=(t<<5)+t+n.charCodeAt(e)>>>0;return t},l=(e,t)=>c(`${e}|${t}`)%2e3/1e3-1;function u(e,t=16/9){let n=.08+.4*Math.sqrt((e+.5)/48),r=e*2.399963229728653;return{x:.5+n*Math.cos(r),y:.5+n*Math.sin(r)*(t>1?.9:1.1)}}let d=(e,t,n)=>Math.max(t,Math.min(n,e));function f(e,{aspect:t=16/9}={}){let n=(e?.elements||[]).slice().sort((e,t)=>(e.appearMs||0)-(t.appearMs||0)),r=[],i=new Map;for(let a of n){let n=(a.kind===`image`?a.size||.28:.18)/2;if(a.pinned||!e.autoArrange){a.pos&&(r.push({...a.pos,size:a.size||.28,appearMs:a.appearMs,leaveMs:a.leaveMs}),i.set(a.id,a.pos));continue}let o=r.filter(e=>e.leaveMs==null||e.leaveMs>a.appearMs),s=null,f=-1/0;for(let e=0;e<48;e++){let r=u((e+c(a.id)%48)%48,t),i=d(r.x,n+.03,1-n-.03),l=d(r.y,n+.05,1-n-.05),p=1/0;for(let e of o)p=Math.min(p,Math.hypot(i-e.x,l-e.y)-(e.size||.28)/2-n);let m=-.12*Math.hypot(i-.5,l-.5),h=(o.length?Math.min(p,.5):.3)+m;h>f&&(f=h,s={x:i,y:l})}let p=s||{x:.5,y:.5};p.x=d(p.x+l(a.id,`x`)*.015,n,1-n),p.y=d(p.y+l(a.id,`y`)*.015,n,1-n),r.push({...p,size:a.size||.28,appearMs:a.appearMs,leaveMs:a.leaveMs}),i.set(a.id,p)}return i}function p(e,t){if(!e.autoArrange)return e;let n=f(e,t);return{...e,elements:(e.elements||[]).map(e=>!e.pinned&&n.has(e.id)?{...e,pos:n.get(e.id)}:e)}}function m(e,t){let n=new Set(t),r=(e||[]).filter(e=>n.has(e.panelId)),i=[];for(let e of r)e.type===`titleScreen`?i.push({panelId:e.panelId,reason:`a title screen is not a beat a canvas can absorb`}):e.type===`canvas`?i.push({panelId:e.panelId,reason:`already a canvas`}):(e.kind===`revealStep`||e.method===`progressiveReveal`)&&i.push({panelId:e.panelId,reason:`part of a progressive-reveal group`});for(let t of e||[])n.has(t.panelId)||(t.repeatOf&&n.has(t.repeatOf)&&i.push({panelId:t.repeatOf,reason:`${t.panelId} re-shows it`}),t.revealOf&&n.has(t.revealOf)&&i.push({panelId:t.revealOf,reason:`${t.panelId} reveals it`}),t.type===`zoom`&&t.sourcePanelId&&n.has(t.sourcePanelId)&&i.push({panelId:t.sourcePanelId,reason:`zoom ${t.panelId} pushes into it`}));return i}function h(e,t,n){let r=(e||[]).findIndex(e=>e.panelId===t),i=(e||[]).findIndex(e=>e.panelId===(n||t));if(r<0||i<0)throw Error(`canvasRange: unknown panel`);let[a,o]=r<=i?[r,i]:[i,r],s=e.slice(a,o+1),c=s[0].sceneId;if(s.some(e=>e.sceneId!==c))throw Error(`canvasRange: a canvas stays inside one scene`);return s.map(e=>e.panelId)}function g(e,t,n){let r=h(e.strip,t,n),i=m(e.strip,r);if(i.length)throw Error(`insertCanvasOverRange: can't absorb ${i[0].panelId} — ${i[0].reason}`);let a=new Set(r),o=e.strip.filter(e=>a.has(e.panelId)),c=Math.min(...o.map(e=>Number(e.startMs))),l=o.reduce((e,t)=>e+Number(t.durationMs),0),u=`${o[0].panelId}c${e.strip.filter(e=>e.type===`canvas`).length+1}`,d=0,f=o.map(t=>({p:t,url:y(e.strip,t)})).filter(({url:e})=>!!e).map(({p:e,url:t})=>({id:`ab${++d}`,kind:`image`,src:t,query:String(e.prompt||e.gifQuery||e.panelId).slice(0,120),source:`generated`,appearMs:Math.max(0,Number(e.startMs)-c),leaveMs:null,pos:null,size:.34,tilt:0,entrance:`pop`,sfx:`auto`,pinned:!1})),p=e.strip.findIndex(e=>e.panelId===r[0]),g=e.strip.filter((e,t)=>!a.has(e.panelId)&&t<p),_=o.map(e=>e.overlayLayer).find(e=>e&&typeof e==`object`)||null,S=_?[...g].reverse().find(e=>e.type===`panel`&&e.sceneId===o[0].sceneId&&e.overlayLayer==null)?.panelId:null,C=[],w=[],T=!1;for(let t of e.strip){if(a.has(t.panelId)){T||(T=!0,w.push({panelId:u,type:`canvas`,sceneId:o[0].sceneId,background:`#ffffff`,autoArrange:f.length>0,planned:!0,...f.length?{template:s({imageCount:f.length})||void 0}:{},elements:f,startMs:c,durationMs:l,transitionIn:o[0].transitionIn===`fade`?`fade`:`cut`,provenance:`user`,revert:{rows:o.map(e=>({...e})),repointed:[]}}));continue}if((t.kind===`edit`||t.type===`zoom`)&&t.sourcePanelId&&a.has(t.sourcePanelId)){let n=[...g].reverse().find(e=>e.lineageId===t.lineageId&&e.sceneId===t.sceneId&&(e.type===`panel`||e.type===`zoom`));C.push({panelId:t.panelId,sourcePanelId:t.sourcePanelId,needsRefresh:!!t.needsRefresh,image:t.image??null}),w.push(n?{...t,sourcePanelId:n.panelId,needsRefresh:!0}:{...t,kind:`base`,sourcePanelId:null,prompt:b(e.strip,t),needsRefresh:!0});continue}w.push(S&&t.panelId===S?{...t,overlayLayer:_}:t)}let E=w.map(t=>t.panelId===u?v(e,{...t,revert:{...t.revert,repointed:C}}):t);return x({...e,strip:E})}function _(e){let t=e?.meta?.aspect||`16:9`;return t===`9:16`?9/16:t===`1:1`?1:16/9}function v(e,t){let n=i(t.template);if(n){let r=o(t.elements||[],n,{aspect:_(e)}),i=f({...t,autoArrange:!0,elements:r.map(e=>e.pos?{...e,pinned:!0}:e)},{aspect:_(e)});return{...t,elements:r.map(e=>!e.pinned&&!e.pos&&i.has(e.id)?{...e,pos:i.get(e.id)}:e)}}return t.autoArrange?p(t,{aspect:_(e)}):t}function y(e,t){if(t?.type===`giphy`)return t.gif??t.image??null;if(t?.type===`zoom`){if(t.image)return t.image;let n=(e||[]).find(e=>e.panelId===t.sourcePanelId);return n?y(e,n):null}return t?.kind===`repeat`?(e||[]).find(e=>e.panelId===t.repeatOf)?.image??null:t?.image??null}function b(e,t){let n=[];for(let t of e||[]){n.push(t);for(let e of t.revert?.rows||[])n.push(e)}let r=n.find(e=>e.kind===`base`&&e.lineageId===t.lineageId&&e.sceneId===t.sceneId&&String(e.prompt||``).trim());return r?r.prompt:String(t.prompt||``).replace(/^\\s*keep\\s+(everything\\s+)?identical\\s*;\\s*/i,``).trim()||`the scene`}let x=e=>e;return{edit:g(e.doc,e.from,e.through)}},\"stillmade-internal.canvas-add-element@1.0.0\":function(e){let t=(e,t,n,r,i,a,o,s)=>({id:e,name:t,scenario:n,minImages:r,slots:i,textSlots:a,pSlots:o,pTextSlots:s}),n=[t(`hero-headline`,`Hero + headline`,`one subject, one line`,1,[{x:.5,y:.58,w:.5,h:.62}],[{role:`headline`,x:.5,y:.14,size:.09,weight:900}],[{x:.5,y:.55,w:.78,h:.5}],[{role:`headline`,x:.5,y:.13,size:.055,weight:900}]),t(`hero-supporting`,`Hero + 2 supporting`,`main subject with two details`,3,[{x:.34,y:.55,w:.42,h:.58},{x:.78,y:.33,w:.28,h:.32},{x:.78,y:.73,w:.28,h:.32}],[{role:`headline`,x:.34,y:.13,size:.08,weight:900}],[{x:.5,y:.38,w:.78,h:.32},{x:.28,y:.72,w:.4,h:.2},{x:.72,y:.72,w:.4,h:.2}],[{role:`headline`,x:.5,y:.12,size:.05,weight:900}]),t(`compare-2`,`Side-by-side compare`,`A vs B`,2,[{x:.27,y:.5,w:.38,h:.5},{x:.73,y:.5,w:.38,h:.5}],[{role:`headline`,x:.5,y:.12,size:.08,weight:900},{role:`label`,x:.27,y:.84,size:.05,weight:800},{role:`label`,x:.73,y:.84,size:.05,weight:800}],[{x:.5,y:.35,w:.72,h:.24},{x:.5,y:.72,w:.72,h:.24}],[{role:`headline`,x:.5,y:.11,size:.05,weight:900},{role:`label`,x:.5,y:.51,size:.032,weight:800},{role:`label`,x:.5,y:.88,size:.032,weight:800}]),t(`three-across`,`Three across`,`three items`,3,[{x:.2,y:.5,w:.26,h:.46},{x:.5,y:.5,w:.26,h:.46},{x:.8,y:.5,w:.26,h:.46}],[{role:`headline`,x:.5,y:.13,size:.08,weight:900},{role:`caption`,x:.5,y:.86,size:.045,weight:600}],[{x:.5,y:.32,w:.64,h:.2},{x:.5,y:.57,w:.64,h:.2},{x:.5,y:.82,w:.64,h:.2}],[{role:`headline`,x:.5,y:.1,size:.05,weight:900},{role:`caption`,x:.5,y:.96,size:.028,weight:600}]),t(`grid-2x2`,`Grid of four`,`four items`,4,[{x:.3,y:.36,w:.32,h:.34},{x:.7,y:.36,w:.32,h:.34},{x:.3,y:.74,w:.32,h:.34},{x:.7,y:.74,w:.32,h:.34}],[{role:`headline`,x:.5,y:.09,size:.07,weight:900}],[{x:.28,y:.38,w:.4,h:.24},{x:.72,y:.38,w:.4,h:.24},{x:.28,y:.68,w:.4,h:.24},{x:.72,y:.68,w:.4,h:.24}],[{role:`headline`,x:.5,y:.12,size:.05,weight:900}]),t(`grid-3x3`,`Many small (3x3)`,`lots of items`,6,[.22,.5,.78].flatMap(e=>[.3,.56,.82].map(t=>({x:e,y:t,w:.24,h:.22}))),[{role:`headline`,x:.5,y:.08,size:.065,weight:900}],[.2,.5,.8].flatMap(e=>[.34,.58,.82].map(t=>({x:e,y:t,w:.27,h:.18}))),[{role:`headline`,x:.5,y:.1,size:.045,weight:900}]),t(`big-left-stack-right`,`Big lead + stack`,`one lead, several follow-ups`,3,[{x:.32,y:.54,w:.5,h:.62},{x:.79,y:.3,w:.3,h:.22},{x:.79,y:.56,w:.3,h:.22},{x:.79,y:.82,w:.3,h:.22}],[{role:`headline`,x:.32,y:.13,size:.075,weight:900}],[{x:.5,y:.4,w:.84,h:.34},{x:.2,y:.74,w:.26,h:.16},{x:.5,y:.74,w:.26,h:.16},{x:.8,y:.74,w:.26,h:.16}],[{role:`headline`,x:.5,y:.12,size:.05,weight:900}]),t(`vertical-stack`,`Vertical stack`,`ordered top to bottom`,2,[{x:.55,y:.29,w:.36,h:.22},{x:.55,y:.55,w:.36,h:.22},{x:.55,y:.81,w:.36,h:.22}],[{role:`headline`,x:.55,y:.08,size:.065,weight:900},{role:`label`,x:.16,y:.55,size:.055,weight:800}],[{x:.5,y:.3,w:.66,h:.2},{x:.5,y:.56,w:.66,h:.2},{x:.5,y:.82,w:.66,h:.2}],[{role:`headline`,x:.5,y:.09,size:.05,weight:900},{role:`label`,x:.24,y:.17,size:.032,weight:800}]),t(`scatter`,`Scattered collage`,`loose, hand-thrown feel`,3,[{x:.26,y:.36,w:.28,h:.32,tilt:-6},{x:.68,y:.3,w:.26,h:.3,tilt:4},{x:.44,y:.66,w:.27,h:.31,tilt:3},{x:.8,y:.62,w:.25,h:.29,tilt:-5},{x:.58,y:.46,w:.24,h:.28,tilt:2}],[{role:`headline`,x:.5,y:.1,size:.075,weight:900}],[{x:.32,y:.3,w:.46,h:.2,tilt:-6},{x:.7,y:.26,w:.42,h:.18,tilt:4},{x:.4,y:.56,w:.44,h:.2,tilt:3},{x:.74,y:.6,w:.4,h:.18,tilt:-5},{x:.5,y:.82,w:.44,h:.19,tilt:2}],[{role:`headline`,x:.5,y:.09,size:.045,weight:900}]),t(`timeline-row`,`Row / timeline`,`steps in order`,3,[{x:.14,y:.52,w:.2,h:.38},{x:.38,y:.52,w:.2,h:.38},{x:.62,y:.52,w:.2,h:.38},{x:.86,y:.52,w:.2,h:.38}],[{role:`headline`,x:.5,y:.15,size:.075,weight:900},{role:`caption`,x:.5,y:.85,size:.045,weight:600}],[{x:.35,y:.28,w:.5,h:.15},{x:.65,y:.47,w:.5,h:.15},{x:.35,y:.66,w:.5,h:.15},{x:.65,y:.85,w:.5,h:.15}],[{role:`headline`,x:.5,y:.12,size:.05,weight:900}]),t(`center-satellites`,`Center + satellites`,`one core idea, orbiting parts`,3,[{x:.5,y:.52,w:.34,h:.42},{x:.17,y:.3,w:.2,h:.26},{x:.83,y:.3,w:.2,h:.26},{x:.17,y:.77,w:.2,h:.26},{x:.83,y:.77,w:.2,h:.26}],[{role:`headline`,x:.5,y:.09,size:.065,weight:900}],[{x:.5,y:.52,w:.56,h:.28},{x:.2,y:.28,w:.32,h:.16},{x:.8,y:.28,w:.32,h:.16},{x:.2,y:.78,w:.32,h:.16},{x:.8,y:.78,w:.32,h:.16}],[{role:`headline`,x:.5,y:.1,size:.045,weight:900}]),t(`corner-big-text`,`Corner images, big text`,`statement first, proof beside it`,2,[{x:.72,y:.4,w:.32,h:.38},{x:.52,y:.72,w:.28,h:.34},{x:.85,y:.76,w:.24,h:.3}],[{role:`headline`,x:.26,y:.26,size:.105,weight:900},{role:`label`,x:.26,y:.42,size:.05,weight:600}],[{x:.36,y:.56,w:.5,h:.22},{x:.7,y:.7,w:.44,h:.2},{x:.4,y:.84,w:.4,h:.18}],[{role:`headline`,x:.5,y:.19,size:.065,weight:900},{role:`label`,x:.5,y:.31,size:.034,weight:600}]),t(`title-top-row`,`Title top, images below`,`title screen with evidence`,2,[{x:.22,y:.62,w:.28,h:.44},{x:.5,y:.62,w:.28,h:.44},{x:.78,y:.62,w:.28,h:.44}],[{role:`headline`,x:.5,y:.17,size:.1,weight:900}],[{x:.5,y:.4,w:.7,h:.2},{x:.5,y:.64,w:.7,h:.2},{x:.5,y:.86,w:.7,h:.16}],[{role:`headline`,x:.5,y:.15,size:.06,weight:900}]),t(`large-caption`,`One large + caption`,`let the image speak`,1,[{x:.5,y:.47,w:.56,h:.6}],[{role:`label`,x:.15,y:.1,size:.045,weight:800},{role:`caption`,x:.5,y:.85,size:.055,weight:600}],[{x:.5,y:.47,w:.82,h:.44}],[{role:`label`,x:.24,y:.12,size:.032,weight:800},{role:`caption`,x:.5,y:.78,size:.034,weight:600}]),t(`staggered-diagonal`,`Staggered diagonal`,`progression with motion`,3,[{x:.18,y:.26,w:.24,h:.3,tilt:-3},{x:.42,y:.45,w:.24,h:.3,tilt:3},{x:.64,y:.62,w:.24,h:.3,tilt:-3},{x:.86,y:.79,w:.24,h:.3,tilt:3}],[{role:`headline`,x:.74,y:.16,size:.075,weight:900}],[{x:.28,y:.3,w:.42,h:.18,tilt:-3},{x:.62,y:.46,w:.42,h:.18,tilt:3},{x:.36,y:.62,w:.42,h:.18,tilt:-3},{x:.68,y:.78,w:.42,h:.18,tilt:3}],[{role:`headline`,x:.5,y:.12,size:.05,weight:900}]),t(`overlap-stack`,`Overlapping stack`,`a deliberate pile`,2,[{x:.42,y:.5,w:.36,h:.46,tilt:-5},{x:.54,y:.56,w:.36,h:.46,tilt:3},{x:.63,y:.46,w:.36,h:.46,tilt:-2}],[{role:`headline`,x:.5,y:.12,size:.08,weight:900},{role:`caption`,x:.5,y:.89,size:.045,weight:600}],[{x:.44,y:.42,w:.58,h:.26,tilt:-5},{x:.58,y:.53,w:.58,h:.26,tilt:3},{x:.46,y:.64,w:.58,h:.26,tilt:-2}],[{role:`headline`,x:.5,y:.12,size:.05,weight:900},{role:`caption`,x:.5,y:.86,size:.032,weight:600}]),t(`banner-row`,`Wide banner + small row`,`one wide scene, details under`,2,[{x:.5,y:.36,w:.84,h:.36},{x:.25,y:.77,w:.24,h:.26},{x:.5,y:.77,w:.24,h:.26},{x:.75,y:.77,w:.24,h:.26}],[{role:`headline`,x:.5,y:.09,size:.065,weight:900}],[{x:.5,y:.36,w:.86,h:.26},{x:.22,y:.66,w:.28,h:.16},{x:.5,y:.66,w:.28,h:.16},{x:.78,y:.66,w:.28,h:.16}],[{role:`headline`,x:.5,y:.13,size:.05,weight:900},{role:`caption`,x:.5,y:.82,size:.032,weight:600}]),t(`quadrant-labels`,`Quadrants with labels`,`four named things`,4,[{x:.28,y:.3,w:.3,h:.3},{x:.72,y:.3,w:.3,h:.3},{x:.28,y:.71,w:.3,h:.3},{x:.72,y:.71,w:.3,h:.3}],[{role:`headline`,x:.5,y:.07,size:.06,weight:900},{role:`label`,x:.28,y:.49,size:.042,weight:800},{role:`label`,x:.72,y:.49,size:.042,weight:800},{role:`label`,x:.28,y:.9,size:.042,weight:800},{role:`label`,x:.72,y:.9,size:.042,weight:800}],[{x:.28,y:.32,w:.38,h:.2},{x:.72,y:.32,w:.38,h:.2},{x:.28,y:.64,w:.38,h:.2},{x:.72,y:.64,w:.38,h:.2}],[{role:`headline`,x:.5,y:.1,size:.045,weight:900},{role:`label`,x:.28,y:.45,size:.028,weight:800},{role:`label`,x:.72,y:.45,size:.028,weight:800},{role:`label`,x:.28,y:.77,size:.028,weight:800},{role:`label`,x:.72,y:.77,size:.028,weight:800}]),t(`pyramid-3`,`Pyramid of three`,`one above two`,3,[{x:.5,y:.32,w:.3,h:.32},{x:.32,y:.71,w:.3,h:.32},{x:.68,y:.71,w:.3,h:.32}],[{role:`headline`,x:.5,y:.08,size:.065,weight:900},{role:`caption`,x:.5,y:.92,size:.04,weight:600}],[{x:.5,y:.34,w:.5,h:.22},{x:.27,y:.62,w:.42,h:.18},{x:.73,y:.62,w:.42,h:.18}],[{role:`headline`,x:.5,y:.1,size:.05,weight:900},{role:`caption`,x:.5,y:.79,size:.032,weight:600}]),t(`mosaic-dense`,`Dense mosaic`,`everything at once`,5,[{x:.3,y:.4,w:.34,h:.42},{x:.62,y:.29,w:.24,h:.26},{x:.86,y:.33,w:.2,h:.28},{x:.19,y:.78,w:.24,h:.26},{x:.47,y:.77,w:.26,h:.28},{x:.73,y:.73,w:.22,h:.24},{x:.91,y:.76,w:.14,h:.18}],[{role:`headline`,x:.5,y:.09,size:.06,weight:900}],[{x:.32,y:.3,w:.5,h:.2},{x:.78,y:.26,w:.36,h:.16},{x:.24,y:.52,w:.4,h:.16},{x:.68,y:.5,w:.44,h:.18},{x:.3,y:.74,w:.42,h:.16},{x:.74,y:.73,w:.4,h:.16},{x:.5,y:.89,w:.5,h:.1}],[{role:`headline`,x:.5,y:.1,size:.045,weight:900}])];return new Map(n.map(e=>[e.id,e])),{edit:addCanvasElement(e.doc,e.panelId,e.element)}},\"stillmade-internal.canvas-add-element@1.0.1\":function(e){let t=(e,t,n,r,i,a,o,s)=>({id:e,name:t,scenario:n,minImages:r,slots:i,textSlots:a,pSlots:o,pTextSlots:s}),n=[t(`hero-headline`,`Hero + headline`,`one subject, one line`,1,[{x:.5,y:.58,w:.5,h:.62}],[{role:`headline`,x:.5,y:.14,size:.09,weight:900}],[{x:.5,y:.55,w:.78,h:.5}],[{role:`headline`,x:.5,y:.13,size:.055,weight:900}]),t(`hero-supporting`,`Hero + 2 supporting`,`main subject with two details`,3,[{x:.34,y:.55,w:.42,h:.58},{x:.78,y:.33,w:.28,h:.32},{x:.78,y:.73,w:.28,h:.32}],[{role:`headline`,x:.34,y:.13,size:.08,weight:900}],[{x:.5,y:.38,w:.78,h:.32},{x:.28,y:.72,w:.4,h:.2},{x:.72,y:.72,w:.4,h:.2}],[{role:`headline`,x:.5,y:.12,size:.05,weight:900}]),t(`compare-2`,`Side-by-side compare`,`A vs B`,2,[{x:.27,y:.5,w:.38,h:.5},{x:.73,y:.5,w:.38,h:.5}],[{role:`headline`,x:.5,y:.12,size:.08,weight:900},{role:`label`,x:.27,y:.84,size:.05,weight:800},{role:`label`,x:.73,y:.84,size:.05,weight:800}],[{x:.5,y:.35,w:.72,h:.24},{x:.5,y:.72,w:.72,h:.24}],[{role:`headline`,x:.5,y:.11,size:.05,weight:900},{role:`label`,x:.5,y:.51,size:.032,weight:800},{role:`label`,x:.5,y:.88,size:.032,weight:800}]),t(`three-across`,`Three across`,`three items`,3,[{x:.2,y:.5,w:.26,h:.46},{x:.5,y:.5,w:.26,h:.46},{x:.8,y:.5,w:.26,h:.46}],[{role:`headline`,x:.5,y:.13,size:.08,weight:900},{role:`caption`,x:.5,y:.86,size:.045,weight:600}],[{x:.5,y:.32,w:.64,h:.2},{x:.5,y:.57,w:.64,h:.2},{x:.5,y:.82,w:.64,h:.2}],[{role:`headline`,x:.5,y:.1,size:.05,weight:900},{role:`caption`,x:.5,y:.96,size:.028,weight:600}]),t(`grid-2x2`,`Grid of four`,`four items`,4,[{x:.3,y:.36,w:.32,h:.34},{x:.7,y:.36,w:.32,h:.34},{x:.3,y:.74,w:.32,h:.34},{x:.7,y:.74,w:.32,h:.34}],[{role:`headline`,x:.5,y:.09,size:.07,weight:900}],[{x:.28,y:.38,w:.4,h:.24},{x:.72,y:.38,w:.4,h:.24},{x:.28,y:.68,w:.4,h:.24},{x:.72,y:.68,w:.4,h:.24}],[{role:`headline`,x:.5,y:.12,size:.05,weight:900}]),t(`grid-3x3`,`Many small (3x3)`,`lots of items`,6,[.22,.5,.78].flatMap(e=>[.3,.56,.82].map(t=>({x:e,y:t,w:.24,h:.22}))),[{role:`headline`,x:.5,y:.08,size:.065,weight:900}],[.2,.5,.8].flatMap(e=>[.34,.58,.82].map(t=>({x:e,y:t,w:.27,h:.18}))),[{role:`headline`,x:.5,y:.1,size:.045,weight:900}]),t(`big-left-stack-right`,`Big lead + stack`,`one lead, several follow-ups`,3,[{x:.32,y:.54,w:.5,h:.62},{x:.79,y:.3,w:.3,h:.22},{x:.79,y:.56,w:.3,h:.22},{x:.79,y:.82,w:.3,h:.22}],[{role:`headline`,x:.32,y:.13,size:.075,weight:900}],[{x:.5,y:.4,w:.84,h:.34},{x:.2,y:.74,w:.26,h:.16},{x:.5,y:.74,w:.26,h:.16},{x:.8,y:.74,w:.26,h:.16}],[{role:`headline`,x:.5,y:.12,size:.05,weight:900}]),t(`vertical-stack`,`Vertical stack`,`ordered top to bottom`,2,[{x:.55,y:.29,w:.36,h:.22},{x:.55,y:.55,w:.36,h:.22},{x:.55,y:.81,w:.36,h:.22}],[{role:`headline`,x:.55,y:.08,size:.065,weight:900},{role:`label`,x:.16,y:.55,size:.055,weight:800}],[{x:.5,y:.3,w:.66,h:.2},{x:.5,y:.56,w:.66,h:.2},{x:.5,y:.82,w:.66,h:.2}],[{role:`headline`,x:.5,y:.09,size:.05,weight:900},{role:`label`,x:.24,y:.17,size:.032,weight:800}]),t(`scatter`,`Scattered collage`,`loose, hand-thrown feel`,3,[{x:.26,y:.36,w:.28,h:.32,tilt:-6},{x:.68,y:.3,w:.26,h:.3,tilt:4},{x:.44,y:.66,w:.27,h:.31,tilt:3},{x:.8,y:.62,w:.25,h:.29,tilt:-5},{x:.58,y:.46,w:.24,h:.28,tilt:2}],[{role:`headline`,x:.5,y:.1,size:.075,weight:900}],[{x:.32,y:.3,w:.46,h:.2,tilt:-6},{x:.7,y:.26,w:.42,h:.18,tilt:4},{x:.4,y:.56,w:.44,h:.2,tilt:3},{x:.74,y:.6,w:.4,h:.18,tilt:-5},{x:.5,y:.82,w:.44,h:.19,tilt:2}],[{role:`headline`,x:.5,y:.09,size:.045,weight:900}]),t(`timeline-row`,`Row / timeline`,`steps in order`,3,[{x:.14,y:.52,w:.2,h:.38},{x:.38,y:.52,w:.2,h:.38},{x:.62,y:.52,w:.2,h:.38},{x:.86,y:.52,w:.2,h:.38}],[{role:`headline`,x:.5,y:.15,size:.075,weight:900},{role:`caption`,x:.5,y:.85,size:.045,weight:600}],[{x:.35,y:.28,w:.5,h:.15},{x:.65,y:.47,w:.5,h:.15},{x:.35,y:.66,w:.5,h:.15},{x:.65,y:.85,w:.5,h:.15}],[{role:`headline`,x:.5,y:.12,size:.05,weight:900}]),t(`center-satellites`,`Center + satellites`,`one core idea, orbiting parts`,3,[{x:.5,y:.52,w:.34,h:.42},{x:.17,y:.3,w:.2,h:.26},{x:.83,y:.3,w:.2,h:.26},{x:.17,y:.77,w:.2,h:.26},{x:.83,y:.77,w:.2,h:.26}],[{role:`headline`,x:.5,y:.09,size:.065,weight:900}],[{x:.5,y:.52,w:.56,h:.28},{x:.2,y:.28,w:.32,h:.16},{x:.8,y:.28,w:.32,h:.16},{x:.2,y:.78,w:.32,h:.16},{x:.8,y:.78,w:.32,h:.16}],[{role:`headline`,x:.5,y:.1,size:.045,weight:900}]),t(`corner-big-text`,`Corner images, big text`,`statement first, proof beside it`,2,[{x:.72,y:.4,w:.32,h:.38},{x:.52,y:.72,w:.28,h:.34},{x:.85,y:.76,w:.24,h:.3}],[{role:`headline`,x:.26,y:.26,size:.105,weight:900},{role:`label`,x:.26,y:.42,size:.05,weight:600}],[{x:.36,y:.56,w:.5,h:.22},{x:.7,y:.7,w:.44,h:.2},{x:.4,y:.84,w:.4,h:.18}],[{role:`headline`,x:.5,y:.19,size:.065,weight:900},{role:`label`,x:.5,y:.31,size:.034,weight:600}]),t(`title-top-row`,`Title top, images below`,`title screen with evidence`,2,[{x:.22,y:.62,w:.28,h:.44},{x:.5,y:.62,w:.28,h:.44},{x:.78,y:.62,w:.28,h:.44}],[{role:`headline`,x:.5,y:.17,size:.1,weight:900}],[{x:.5,y:.4,w:.7,h:.2},{x:.5,y:.64,w:.7,h:.2},{x:.5,y:.86,w:.7,h:.16}],[{role:`headline`,x:.5,y:.15,size:.06,weight:900}]),t(`large-caption`,`One large + caption`,`let the image speak`,1,[{x:.5,y:.47,w:.56,h:.6}],[{role:`label`,x:.15,y:.1,size:.045,weight:800},{role:`caption`,x:.5,y:.85,size:.055,weight:600}],[{x:.5,y:.47,w:.82,h:.44}],[{role:`label`,x:.24,y:.12,size:.032,weight:800},{role:`caption`,x:.5,y:.78,size:.034,weight:600}]),t(`staggered-diagonal`,`Staggered diagonal`,`progression with motion`,3,[{x:.18,y:.26,w:.24,h:.3,tilt:-3},{x:.42,y:.45,w:.24,h:.3,tilt:3},{x:.64,y:.62,w:.24,h:.3,tilt:-3},{x:.86,y:.79,w:.24,h:.3,tilt:3}],[{role:`headline`,x:.74,y:.16,size:.075,weight:900}],[{x:.28,y:.3,w:.42,h:.18,tilt:-3},{x:.62,y:.46,w:.42,h:.18,tilt:3},{x:.36,y:.62,w:.42,h:.18,tilt:-3},{x:.68,y:.78,w:.42,h:.18,tilt:3}],[{role:`headline`,x:.5,y:.12,size:.05,weight:900}]),t(`overlap-stack`,`Overlapping stack`,`a deliberate pile`,2,[{x:.42,y:.5,w:.36,h:.46,tilt:-5},{x:.54,y:.56,w:.36,h:.46,tilt:3},{x:.63,y:.46,w:.36,h:.46,tilt:-2}],[{role:`headline`,x:.5,y:.12,size:.08,weight:900},{role:`caption`,x:.5,y:.89,size:.045,weight:600}],[{x:.44,y:.42,w:.58,h:.26,tilt:-5},{x:.58,y:.53,w:.58,h:.26,tilt:3},{x:.46,y:.64,w:.58,h:.26,tilt:-2}],[{role:`headline`,x:.5,y:.12,size:.05,weight:900},{role:`caption`,x:.5,y:.86,size:.032,weight:600}]),t(`banner-row`,`Wide banner + small row`,`one wide scene, details under`,2,[{x:.5,y:.36,w:.84,h:.36},{x:.25,y:.77,w:.24,h:.26},{x:.5,y:.77,w:.24,h:.26},{x:.75,y:.77,w:.24,h:.26}],[{role:`headline`,x:.5,y:.09,size:.065,weight:900}],[{x:.5,y:.36,w:.86,h:.26},{x:.22,y:.66,w:.28,h:.16},{x:.5,y:.66,w:.28,h:.16},{x:.78,y:.66,w:.28,h:.16}],[{role:`headline`,x:.5,y:.13,size:.05,weight:900},{role:`caption`,x:.5,y:.82,size:.032,weight:600}]),t(`quadrant-labels`,`Quadrants with labels`,`four named things`,4,[{x:.28,y:.3,w:.3,h:.3},{x:.72,y:.3,w:.3,h:.3},{x:.28,y:.71,w:.3,h:.3},{x:.72,y:.71,w:.3,h:.3}],[{role:`headline`,x:.5,y:.07,size:.06,weight:900},{role:`label`,x:.28,y:.49,size:.042,weight:800},{role:`label`,x:.72,y:.49,size:.042,weight:800},{role:`label`,x:.28,y:.9,size:.042,weight:800},{role:`label`,x:.72,y:.9,size:.042,weight:800}],[{x:.28,y:.32,w:.38,h:.2},{x:.72,y:.32,w:.38,h:.2},{x:.28,y:.64,w:.38,h:.2},{x:.72,y:.64,w:.38,h:.2}],[{role:`headline`,x:.5,y:.1,size:.045,weight:900},{role:`label`,x:.28,y:.45,size:.028,weight:800},{role:`label`,x:.72,y:.45,size:.028,weight:800},{role:`label`,x:.28,y:.77,size:.028,weight:800},{role:`label`,x:.72,y:.77,size:.028,weight:800}]),t(`pyramid-3`,`Pyramid of three`,`one above two`,3,[{x:.5,y:.32,w:.3,h:.32},{x:.32,y:.71,w:.3,h:.32},{x:.68,y:.71,w:.3,h:.32}],[{role:`headline`,x:.5,y:.08,size:.065,weight:900},{role:`caption`,x:.5,y:.92,size:.04,weight:600}],[{x:.5,y:.34,w:.5,h:.22},{x:.27,y:.62,w:.42,h:.18},{x:.73,y:.62,w:.42,h:.18}],[{role:`headline`,x:.5,y:.1,size:.05,weight:900},{role:`caption`,x:.5,y:.79,size:.032,weight:600}]),t(`mosaic-dense`,`Dense mosaic`,`everything at once`,5,[{x:.3,y:.4,w:.34,h:.42},{x:.62,y:.29,w:.24,h:.26},{x:.86,y:.33,w:.2,h:.28},{x:.19,y:.78,w:.24,h:.26},{x:.47,y:.77,w:.26,h:.28},{x:.73,y:.73,w:.22,h:.24},{x:.91,y:.76,w:.14,h:.18}],[{role:`headline`,x:.5,y:.09,size:.06,weight:900}],[{x:.32,y:.3,w:.5,h:.2},{x:.78,y:.26,w:.36,h:.16},{x:.24,y:.52,w:.4,h:.16},{x:.68,y:.5,w:.44,h:.18},{x:.3,y:.74,w:.42,h:.16},{x:.74,y:.73,w:.4,h:.16},{x:.5,y:.89,w:.5,h:.1}],[{role:`headline`,x:.5,y:.1,size:.045,weight:900}])],r=new Map(n.map(e=>[e.id,e])),i=e=>r.get(e)||null;function a(e,t=16/9){return e?t<1?{slots:e.pSlots,textSlots:e.pTextSlots}:{slots:e.slots,textSlots:e.textSlots}:null}function o(e,t,{aspect:n=16/9}={}){if(!t)return(e||[]).map(e=>{if(e.pinned||e.kind!==`image`||!e.box)return e;let{box:t,...n}=e;return n});let r=a(t,n),i=(e,t)=>(e.appearMs||0)-(t.appearMs||0),o=(e||[]).filter(e=>e.kind===`image`&&!e.pinned).sort(i),s=(e||[]).filter(e=>e.kind===`text`&&!e.pinned).sort(i),c=new Map;o.forEach((e,t)=>{t<r.slots.length&&c.set(e.id,r.slots[t])});let l=new Map;return s.forEach((e,t)=>{t<r.textSlots.length&&l.set(e.id,r.textSlots[t])}),(e||[]).map(e=>{if(e.pinned)return e;if(e.kind===`image`){let t=c.get(e.id);if(!t){let{box:t,...n}=e;return{...n,pos:null}}return{...e,pos:{x:t.x,y:t.y},box:{w:t.w,h:t.h},size:t.w,tilt:t.tilt||0}}let t=l.get(e.id);return t?{...e,pos:{x:t.x,y:t.y},size:t.size,weight:t.weight||e.weight||800}:e})}function s({imageCount:e=0,textCount:t=0,hint:n=``}={}){if(!e)return null;let r=String(n||``).toLowerCase();return e===2&&/\\bvs\\b|versus|compar|before.*after|either/.test(r)?`compare-2`:e>=3&&/step|order|sequence|timeline|process|journey|stages/.test(r)?`timeline-row`:e>=3&&/list|lists|enumerat|items|examples|types|kinds/.test(r)?e>=5?`mosaic-dense`:`three-across`:e===1?t>1?`large-caption`:`hero-headline`:e===2?`compare-2`:e===3?`three-across`:e===4?`grid-2x2`:e===5?`center-satellites`:e<=7?`mosaic-dense`:`grid-3x3`}let c=e=>{let t=5381,n=String(e||``);for(let e=0;e<n.length;e++)t=(t<<5)+t+n.charCodeAt(e)>>>0;return t},l=(e,t)=>c(`${e}|${t}`)%2e3/1e3-1;function u(e,t=16/9){let n=.08+.4*Math.sqrt((e+.5)/48),r=e*2.399963229728653;return{x:.5+n*Math.cos(r),y:.5+n*Math.sin(r)*(t>1?.9:1.1)}}let d=(e,t,n)=>Math.max(t,Math.min(n,e));function f(e,{aspect:t=16/9}={}){let n=(e?.elements||[]).slice().sort((e,t)=>(e.appearMs||0)-(t.appearMs||0)),r=[],i=new Map;for(let a of n){let n=(a.kind===`image`?a.size||.28:.18)/2;if(a.pinned||!e.autoArrange){a.pos&&(r.push({...a.pos,size:a.size||.28,appearMs:a.appearMs,leaveMs:a.leaveMs}),i.set(a.id,a.pos));continue}let o=r.filter(e=>e.leaveMs==null||e.leaveMs>a.appearMs),s=null,f=-1/0;for(let e=0;e<48;e++){let r=u((e+c(a.id)%48)%48,t),i=d(r.x,n+.03,1-n-.03),l=d(r.y,n+.05,1-n-.05),p=1/0;for(let e of o)p=Math.min(p,Math.hypot(i-e.x,l-e.y)-(e.size||.28)/2-n);let m=-.12*Math.hypot(i-.5,l-.5),h=(o.length?Math.min(p,.5):.3)+m;h>f&&(f=h,s={x:i,y:l})}let p=s||{x:.5,y:.5};p.x=d(p.x+l(a.id,`x`)*.015,n,1-n),p.y=d(p.y+l(a.id,`y`)*.015,n,1-n),r.push({...p,size:a.size||.28,appearMs:a.appearMs,leaveMs:a.leaveMs}),i.set(a.id,p)}return i}function p(e,t){if(!e.autoArrange)return e;let n=f(e,t);return{...e,elements:(e.elements||[]).map(e=>!e.pinned&&n.has(e.id)?{...e,pos:n.get(e.id)}:e)}}function m(e){let t=e?.meta?.aspect||`16:9`;return t===`9:16`?9/16:t===`1:1`?1:16/9}function h(e,t){let n=i(t.template);if(n){let r=o(t.elements||[],n,{aspect:m(e)}),i=f({...t,autoArrange:!0,elements:r.map(e=>e.pos?{...e,pinned:!0}:e)},{aspect:m(e)});return{...t,elements:r.map(e=>!e.pinned&&!e.pos&&i.has(e.id)?{...e,pos:i.get(e.id)}:e)}}return t.autoArrange?p(t,{aspect:m(e)}):t}function g(e,t){if(!e.autoArrange||!e.template)return e.template;let n=i(e.template);if(!n)return e.template;let r=t.filter(e=>e.kind===`image`||e.kind===`video`).length,a=t.filter(e=>e.kind===`text`).length;return r>0&&r<=n.slots.length?e.template:s({imageCount:r,textCount:a,hint:`${n.scenario||``} ${e.hint||``}`})||e.template}function _(t,n,r){let i=t.strip.find(e=>e.panelId===n);if(!i||i.type!==`canvas`)throw Error(`addCanvasElement: ${n} is not a canvas panel`);(i.elements||[]).length+1;let a={id:e.newId,...r},o=t.strip.map(e=>{if(e.panelId!==n)return e;let r=[...e.elements||[],a];return h(t,{...e,template:g(e,r),elements:r})});return v({...t,strip:o})}let v=e=>JSON.parse(JSON.stringify(e));return{edit:_(e.doc,e.panelId,e.element)}},\"stillmade-internal.canvas-background@1.0.0\":function(e){let t=[`#0a1a3f`,`#3b7dff`],n=[`#0b1226`,`#96beff`],r=[`#e8e4da`,`#57503f`],i={grid:{label:`Blue Grid`,css:`linear-gradient(180deg, #0a1a3f, #123a8a)`,tunable:[{key:`base`,label:`Background`,default:t[0]},{key:`accent`,label:`Grid & glow`,default:t[1]}]},aurora:{label:`Aurora`,css:`radial-gradient(circle at 35% 40%, rgba(90,220,200,0.7), rgba(140,90,240,0.5) 45%, #0b1030 80%)`},mesh:{label:`Mesh`,css:`radial-gradient(circle at 30% 30%, rgba(255,120,80,0.7), rgba(120,90,255,0.5) 55%, #2a0f3a 85%)`},bokeh:{label:`Bokeh`,css:`radial-gradient(circle at 60% 70%, rgba(150,190,255,0.5), #152244 70%)`,tunable:[{key:`base`,label:`Background`,default:n[0]},{key:`accent`,label:`Dots`,default:n[1]}]},waves:{label:`Waves`,css:`linear-gradient(180deg, #0a2e4a 40%, rgba(40,190,180,0.6) 70%, #04122a)`},paper:{label:`Paper`,css:`linear-gradient(180deg, #e8e4da, #ded9cd)`,tunable:[{key:`base`,label:`Paper`,default:r[0]},{key:`accent`,label:`Grid & flecks`,default:r[1]}]}};function a(e){if(typeof e!=`string`||!e.startsWith(`anim|`))return null;let[,t,...n]=e.split(`|`);return i[t]?{key:t,colors:n}:null}function o(e,t,n){let r=a(e),o=r&&i[r.key].tunable;if(!o)return e;let s=o.map((e,i)=>i===t?n:r.colors[i]||e.default);return`anim|${r.key}|${s.join(`|`)}`}function s(e,t,n){let r=e.strip.map(e=>e.panelId===t?{...e,...n,provenance:n.provenance||`user`}:e);return c({...e,strip:r})}let c=e=>e,l=e.doc.strip[0],u=e.command.kind===`color`?o(l.background,e.command.slot,e.command.value):e.command.value;return{edit:s(e.doc,l.panelId,{background:u})}},\"stillmade-internal.canvas-continuation@1.0.0\":function(e){let t=[`swipe-up`,`swipe-down`,`swipe-left`,`swipe-right`,`cut`],n=[`pop`,`fade`],r=e=>JSON.parse(JSON.stringify(e));function i(e,i,a,{exit:s=`swipe-up`,arrive:c=`pop`}={}){let l=e.strip.find(e=>e.panelId===i);if(!l||l.type!==`canvas`)throw Error(`continueCanvasAt: ${i} is not a canvas panel`);if(!t.includes(s))throw Error(`continueCanvasAt: exit must be ${t.join(`|`)}`);if(!n.includes(c))throw Error(`continueCanvasAt: arrive must be ${n.join(`|`)}`);let u=Math.round(Number(a));if(!Number.isFinite(u)||u<400||u>l.durationMs-400)throw Error(`Pick a point with at least 0.4s on each side to continue on a new canvas`);let d=o(e.strip),f=e.strip.filter(e=>e.type===`canvas`).length+1;for(;d.has(`${i}c${f}`);)f++;let p=`${i}c${f}`,m=[],h=[];for(let e of l.elements||[])(e.appearMs||0)>=u?h.push({...e,appearMs:Math.max(0,(e.appearMs||0)-u),leaveMs:e.leaveMs==null?null:Math.max(100,e.leaveMs-u),entrance:e.kind===`text`?e.entrance:c===`fade`?`fade`:e.entrance||`pop`,...e.kind===`text`&&Array.isArray(e.wordTimes)?{wordTimes:e.wordTimes.map(e=>Math.max(0,e-u))}:{}}):m.push(e.leaveMs!=null&&e.leaveMs>u?{...e,leaveMs:u}:e);let g=e.strip.flatMap(e=>e.panelId===i?[{...e,durationMs:u,elements:m},{panelId:p,type:`canvas`,sceneId:e.sceneId,background:`#ffffff`,autoArrange:e.autoArrange,planned:!1,elements:h,startMs:e.startMs+u,durationMs:e.durationMs-u,transitionIn:`cut`,provenance:`user`,handoff:{exit:s,arrive:c}}]:[e]);return r({...e,strip:g})}function a(e,t,n){let i=e.strip.find(e=>e.panelId===t);if(!i||i.type!==`canvas`)throw Error(`setCanvasHandoff: ${t} is not a canvas panel`);let a=e.strip.map(e=>{if(e.panelId!==t)return e;let r={...e};return n==null?delete r.handoff:r.handoff={...e.handoff||{},...n},r});return r({...e,strip:a})}function o(e){let t=new Set;for(let n of e||[]){t.add(n.panelId);for(let e of n.revert?.rows||[])t.add(e.panelId)}return t}return{edit:e.mode===`continue`?i(e.doc,e.panelId,e.atMs,e.options):a(e.doc,e.panelId,e.options)}},\"stillmade-internal.canvas-continuation@1.0.1\":function(e){let t=[`swipe-up`,`swipe-down`,`swipe-left`,`swipe-right`,`cut`],n=[`pop`,`fade`],r=e=>JSON.parse(JSON.stringify(e));function i(e,i,a,{exit:s=`swipe-up`,arrive:c=`pop`}={}){let l=e.strip.find(e=>e.panelId===i);if(!l||l.type!==`canvas`)throw Error(`continueCanvasAt: ${i} is not a canvas panel`);if(!t.includes(s))throw Error(`continueCanvasAt: exit must be ${t.join(`|`)}`);if(!n.includes(c))throw Error(`continueCanvasAt: arrive must be ${n.join(`|`)}`);let u=Math.round(Number(a));if(!Number.isFinite(u)||u<400||u>l.durationMs-400)throw Error(`Pick a point with at least 0.4s on each side to continue on a new canvas`);let d=o(e.strip),f=e.strip.filter(e=>e.type===`canvas`).length+1;for(;d.has(`${i}c${f}`);)f++;let p=`${i}c${f}`,m=[],h=[];for(let e of l.elements||[])(e.appearMs||0)>=u?h.push({...e,appearMs:Math.max(0,(e.appearMs||0)-u),leaveMs:e.leaveMs==null?null:Math.max(100,e.leaveMs-u),entrance:e.kind===`text`?e.entrance:c===`fade`?`fade`:e.entrance||`pop`,...e.kind===`text`&&Array.isArray(e.wordTimes)?{wordTimes:e.wordTimes.map(e=>Math.max(0,e-u))}:{}}):m.push(e.leaveMs!=null&&e.leaveMs>u?{...e,leaveMs:u}:e);let g=e.strip.flatMap(e=>e.panelId===i?[{...e,durationMs:u,elements:m},{panelId:p,type:`canvas`,sceneId:e.sceneId,background:`#ffffff`,autoArrange:e.autoArrange,planned:!1,elements:h,startMs:e.startMs+u,durationMs:e.durationMs-u,transitionIn:`cut`,provenance:`user`,handoff:{exit:s,arrive:c}}]:[e]);return r({...e,strip:g})}function a(e,t,n){let i=e.strip.find(e=>e.panelId===t);if(!i||i.type!==`canvas`)throw Error(`setCanvasHandoff: ${t} is not a canvas panel`);let a=e.strip.map(e=>{if(e.panelId!==t)return e;let r={...e};return n==null?delete r.handoff:r.handoff={...e.handoff||{},...n},r});return r({...e,strip:a})}function o(e){let t=new Set;for(let n of e||[]){t.add(n.panelId);for(let e of n.revert?.rows||[])t.add(e.panelId)}return t}return{edit:e.mode===`continue`?i(e.doc,e.panelId,e.atMs,e.options??{}):a(e.doc,e.panelId,e.options)}},\"stillmade-internal.canvas-keyframes@1.0.0\":function(e){function t(e,t,n,i,a={}){let o=Math.round(Number(i)||0),s=e.strip.map(e=>e.panelId===t?{...e,elements:(e.elements||[]).map(e=>{if(e.id!==n)return e;let t=Array.isArray(e.moves)?e.moves.slice():[],r=-1,i=141;return t.forEach((e,t)=>{let n=Math.abs((Number(e.atMs)||0)-o);n<=140&&n<i&&(i=n,r=t)}),r>=0?t[r]={...t[r],...a.pos?{pos:a.pos}:{},...a.size==null?{}:{size:a.size}}:t.push({atMs:o,durMs:500,ease:`ease-in-out`,...a.pos?{pos:a.pos}:{},...a.size==null?{}:{size:a.size}}),t.sort((e,t)=>(e.atMs||0)-(t.atMs||0)),{...e,moves:t}})}:e);return r({...e,strip:s})}function n(e,t,n,i){let a=e.strip.map(e=>e.panelId===t?{...e,elements:(e.elements||[]).map(e=>{if(e.id!==n||!Array.isArray(e.moves))return e;let t=e.moves.slice().sort((e,t)=>(e.atMs||0)-(t.atMs||0)).filter((e,t)=>t!==i);return{...e,moves:t}})}:e);return r({...e,strip:a})}let r=e=>e;return{edit:e.operation===`set`?t(e.doc,e.panelId,e.elementId,e.atMs,e.patch):n(e.doc,e.panelId,e.elementId,e.index)}},\"stillmade-internal.canvas-patch-element@1.0.0\":function(e){let t=(e,t,n,r,i,a,o,s)=>({id:e,name:t,scenario:n,minImages:r,slots:i,textSlots:a,pSlots:o,pTextSlots:s}),n=[t(`hero-headline`,`Hero + headline`,`one subject, one line`,1,[{x:.5,y:.58,w:.5,h:.62}],[{role:`headline`,x:.5,y:.14,size:.09,weight:900}],[{x:.5,y:.55,w:.78,h:.5}],[{role:`headline`,x:.5,y:.13,size:.055,weight:900}]),t(`hero-supporting`,`Hero + 2 supporting`,`main subject with two details`,3,[{x:.34,y:.55,w:.42,h:.58},{x:.78,y:.33,w:.28,h:.32},{x:.78,y:.73,w:.28,h:.32}],[{role:`headline`,x:.34,y:.13,size:.08,weight:900}],[{x:.5,y:.38,w:.78,h:.32},{x:.28,y:.72,w:.4,h:.2},{x:.72,y:.72,w:.4,h:.2}],[{role:`headline`,x:.5,y:.12,size:.05,weight:900}]),t(`compare-2`,`Side-by-side compare`,`A vs B`,2,[{x:.27,y:.5,w:.38,h:.5},{x:.73,y:.5,w:.38,h:.5}],[{role:`headline`,x:.5,y:.12,size:.08,weight:900},{role:`label`,x:.27,y:.84,size:.05,weight:800},{role:`label`,x:.73,y:.84,size:.05,weight:800}],[{x:.5,y:.35,w:.72,h:.24},{x:.5,y:.72,w:.72,h:.24}],[{role:`headline`,x:.5,y:.11,size:.05,weight:900},{role:`label`,x:.5,y:.51,size:.032,weight:800},{role:`label`,x:.5,y:.88,size:.032,weight:800}]),t(`three-across`,`Three across`,`three items`,3,[{x:.2,y:.5,w:.26,h:.46},{x:.5,y:.5,w:.26,h:.46},{x:.8,y:.5,w:.26,h:.46}],[{role:`headline`,x:.5,y:.13,size:.08,weight:900},{role:`caption`,x:.5,y:.86,size:.045,weight:600}],[{x:.5,y:.32,w:.64,h:.2},{x:.5,y:.57,w:.64,h:.2},{x:.5,y:.82,w:.64,h:.2}],[{role:`headline`,x:.5,y:.1,size:.05,weight:900},{role:`caption`,x:.5,y:.96,size:.028,weight:600}]),t(`grid-2x2`,`Grid of four`,`four items`,4,[{x:.3,y:.36,w:.32,h:.34},{x:.7,y:.36,w:.32,h:.34},{x:.3,y:.74,w:.32,h:.34},{x:.7,y:.74,w:.32,h:.34}],[{role:`headline`,x:.5,y:.09,size:.07,weight:900}],[{x:.28,y:.38,w:.4,h:.24},{x:.72,y:.38,w:.4,h:.24},{x:.28,y:.68,w:.4,h:.24},{x:.72,y:.68,w:.4,h:.24}],[{role:`headline`,x:.5,y:.12,size:.05,weight:900}]),t(`grid-3x3`,`Many small (3x3)`,`lots of items`,6,[.22,.5,.78].flatMap(e=>[.3,.56,.82].map(t=>({x:e,y:t,w:.24,h:.22}))),[{role:`headline`,x:.5,y:.08,size:.065,weight:900}],[.2,.5,.8].flatMap(e=>[.34,.58,.82].map(t=>({x:e,y:t,w:.27,h:.18}))),[{role:`headline`,x:.5,y:.1,size:.045,weight:900}]),t(`big-left-stack-right`,`Big lead + stack`,`one lead, several follow-ups`,3,[{x:.32,y:.54,w:.5,h:.62},{x:.79,y:.3,w:.3,h:.22},{x:.79,y:.56,w:.3,h:.22},{x:.79,y:.82,w:.3,h:.22}],[{role:`headline`,x:.32,y:.13,size:.075,weight:900}],[{x:.5,y:.4,w:.84,h:.34},{x:.2,y:.74,w:.26,h:.16},{x:.5,y:.74,w:.26,h:.16},{x:.8,y:.74,w:.26,h:.16}],[{role:`headline`,x:.5,y:.12,size:.05,weight:900}]),t(`vertical-stack`,`Vertical stack`,`ordered top to bottom`,2,[{x:.55,y:.29,w:.36,h:.22},{x:.55,y:.55,w:.36,h:.22},{x:.55,y:.81,w:.36,h:.22}],[{role:`headline`,x:.55,y:.08,size:.065,weight:900},{role:`label`,x:.16,y:.55,size:.055,weight:800}],[{x:.5,y:.3,w:.66,h:.2},{x:.5,y:.56,w:.66,h:.2},{x:.5,y:.82,w:.66,h:.2}],[{role:`headline`,x:.5,y:.09,size:.05,weight:900},{role:`label`,x:.24,y:.17,size:.032,weight:800}]),t(`scatter`,`Scattered collage`,`loose, hand-thrown feel`,3,[{x:.26,y:.36,w:.28,h:.32,tilt:-6},{x:.68,y:.3,w:.26,h:.3,tilt:4},{x:.44,y:.66,w:.27,h:.31,tilt:3},{x:.8,y:.62,w:.25,h:.29,tilt:-5},{x:.58,y:.46,w:.24,h:.28,tilt:2}],[{role:`headline`,x:.5,y:.1,size:.075,weight:900}],[{x:.32,y:.3,w:.46,h:.2,tilt:-6},{x:.7,y:.26,w:.42,h:.18,tilt:4},{x:.4,y:.56,w:.44,h:.2,tilt:3},{x:.74,y:.6,w:.4,h:.18,tilt:-5},{x:.5,y:.82,w:.44,h:.19,tilt:2}],[{role:`headline`,x:.5,y:.09,size:.045,weight:900}]),t(`timeline-row`,`Row / timeline`,`steps in order`,3,[{x:.14,y:.52,w:.2,h:.38},{x:.38,y:.52,w:.2,h:.38},{x:.62,y:.52,w:.2,h:.38},{x:.86,y:.52,w:.2,h:.38}],[{role:`headline`,x:.5,y:.15,size:.075,weight:900},{role:`caption`,x:.5,y:.85,size:.045,weight:600}],[{x:.35,y:.28,w:.5,h:.15},{x:.65,y:.47,w:.5,h:.15},{x:.35,y:.66,w:.5,h:.15},{x:.65,y:.85,w:.5,h:.15}],[{role:`headline`,x:.5,y:.12,size:.05,weight:900}]),t(`center-satellites`,`Center + satellites`,`one core idea, orbiting parts`,3,[{x:.5,y:.52,w:.34,h:.42},{x:.17,y:.3,w:.2,h:.26},{x:.83,y:.3,w:.2,h:.26},{x:.17,y:.77,w:.2,h:.26},{x:.83,y:.77,w:.2,h:.26}],[{role:`headline`,x:.5,y:.09,size:.065,weight:900}],[{x:.5,y:.52,w:.56,h:.28},{x:.2,y:.28,w:.32,h:.16},{x:.8,y:.28,w:.32,h:.16},{x:.2,y:.78,w:.32,h:.16},{x:.8,y:.78,w:.32,h:.16}],[{role:`headline`,x:.5,y:.1,size:.045,weight:900}]),t(`corner-big-text`,`Corner images, big text`,`statement first, proof beside it`,2,[{x:.72,y:.4,w:.32,h:.38},{x:.52,y:.72,w:.28,h:.34},{x:.85,y:.76,w:.24,h:.3}],[{role:`headline`,x:.26,y:.26,size:.105,weight:900},{role:`label`,x:.26,y:.42,size:.05,weight:600}],[{x:.36,y:.56,w:.5,h:.22},{x:.7,y:.7,w:.44,h:.2},{x:.4,y:.84,w:.4,h:.18}],[{role:`headline`,x:.5,y:.19,size:.065,weight:900},{role:`label`,x:.5,y:.31,size:.034,weight:600}]),t(`title-top-row`,`Title top, images below`,`title screen with evidence`,2,[{x:.22,y:.62,w:.28,h:.44},{x:.5,y:.62,w:.28,h:.44},{x:.78,y:.62,w:.28,h:.44}],[{role:`headline`,x:.5,y:.17,size:.1,weight:900}],[{x:.5,y:.4,w:.7,h:.2},{x:.5,y:.64,w:.7,h:.2},{x:.5,y:.86,w:.7,h:.16}],[{role:`headline`,x:.5,y:.15,size:.06,weight:900}]),t(`large-caption`,`One large + caption`,`let the image speak`,1,[{x:.5,y:.47,w:.56,h:.6}],[{role:`label`,x:.15,y:.1,size:.045,weight:800},{role:`caption`,x:.5,y:.85,size:.055,weight:600}],[{x:.5,y:.47,w:.82,h:.44}],[{role:`label`,x:.24,y:.12,size:.032,weight:800},{role:`caption`,x:.5,y:.78,size:.034,weight:600}]),t(`staggered-diagonal`,`Staggered diagonal`,`progression with motion`,3,[{x:.18,y:.26,w:.24,h:.3,tilt:-3},{x:.42,y:.45,w:.24,h:.3,tilt:3},{x:.64,y:.62,w:.24,h:.3,tilt:-3},{x:.86,y:.79,w:.24,h:.3,tilt:3}],[{role:`headline`,x:.74,y:.16,size:.075,weight:900}],[{x:.28,y:.3,w:.42,h:.18,tilt:-3},{x:.62,y:.46,w:.42,h:.18,tilt:3},{x:.36,y:.62,w:.42,h:.18,tilt:-3},{x:.68,y:.78,w:.42,h:.18,tilt:3}],[{role:`headline`,x:.5,y:.12,size:.05,weight:900}]),t(`overlap-stack`,`Overlapping stack`,`a deliberate pile`,2,[{x:.42,y:.5,w:.36,h:.46,tilt:-5},{x:.54,y:.56,w:.36,h:.46,tilt:3},{x:.63,y:.46,w:.36,h:.46,tilt:-2}],[{role:`headline`,x:.5,y:.12,size:.08,weight:900},{role:`caption`,x:.5,y:.89,size:.045,weight:600}],[{x:.44,y:.42,w:.58,h:.26,tilt:-5},{x:.58,y:.53,w:.58,h:.26,tilt:3},{x:.46,y:.64,w:.58,h:.26,tilt:-2}],[{role:`headline`,x:.5,y:.12,size:.05,weight:900},{role:`caption`,x:.5,y:.86,size:.032,weight:600}]),t(`banner-row`,`Wide banner + small row`,`one wide scene, details under`,2,[{x:.5,y:.36,w:.84,h:.36},{x:.25,y:.77,w:.24,h:.26},{x:.5,y:.77,w:.24,h:.26},{x:.75,y:.77,w:.24,h:.26}],[{role:`headline`,x:.5,y:.09,size:.065,weight:900}],[{x:.5,y:.36,w:.86,h:.26},{x:.22,y:.66,w:.28,h:.16},{x:.5,y:.66,w:.28,h:.16},{x:.78,y:.66,w:.28,h:.16}],[{role:`headline`,x:.5,y:.13,size:.05,weight:900},{role:`caption`,x:.5,y:.82,size:.032,weight:600}]),t(`quadrant-labels`,`Quadrants with labels`,`four named things`,4,[{x:.28,y:.3,w:.3,h:.3},{x:.72,y:.3,w:.3,h:.3},{x:.28,y:.71,w:.3,h:.3},{x:.72,y:.71,w:.3,h:.3}],[{role:`headline`,x:.5,y:.07,size:.06,weight:900},{role:`label`,x:.28,y:.49,size:.042,weight:800},{role:`label`,x:.72,y:.49,size:.042,weight:800},{role:`label`,x:.28,y:.9,size:.042,weight:800},{role:`label`,x:.72,y:.9,size:.042,weight:800}],[{x:.28,y:.32,w:.38,h:.2},{x:.72,y:.32,w:.38,h:.2},{x:.28,y:.64,w:.38,h:.2},{x:.72,y:.64,w:.38,h:.2}],[{role:`headline`,x:.5,y:.1,size:.045,weight:900},{role:`label`,x:.28,y:.45,size:.028,weight:800},{role:`label`,x:.72,y:.45,size:.028,weight:800},{role:`label`,x:.28,y:.77,size:.028,weight:800},{role:`label`,x:.72,y:.77,size:.028,weight:800}]),t(`pyramid-3`,`Pyramid of three`,`one above two`,3,[{x:.5,y:.32,w:.3,h:.32},{x:.32,y:.71,w:.3,h:.32},{x:.68,y:.71,w:.3,h:.32}],[{role:`headline`,x:.5,y:.08,size:.065,weight:900},{role:`caption`,x:.5,y:.92,size:.04,weight:600}],[{x:.5,y:.34,w:.5,h:.22},{x:.27,y:.62,w:.42,h:.18},{x:.73,y:.62,w:.42,h:.18}],[{role:`headline`,x:.5,y:.1,size:.05,weight:900},{role:`caption`,x:.5,y:.79,size:.032,weight:600}]),t(`mosaic-dense`,`Dense mosaic`,`everything at once`,5,[{x:.3,y:.4,w:.34,h:.42},{x:.62,y:.29,w:.24,h:.26},{x:.86,y:.33,w:.2,h:.28},{x:.19,y:.78,w:.24,h:.26},{x:.47,y:.77,w:.26,h:.28},{x:.73,y:.73,w:.22,h:.24},{x:.91,y:.76,w:.14,h:.18}],[{role:`headline`,x:.5,y:.09,size:.06,weight:900}],[{x:.32,y:.3,w:.5,h:.2},{x:.78,y:.26,w:.36,h:.16},{x:.24,y:.52,w:.4,h:.16},{x:.68,y:.5,w:.44,h:.18},{x:.3,y:.74,w:.42,h:.16},{x:.74,y:.73,w:.4,h:.16},{x:.5,y:.89,w:.5,h:.1}],[{role:`headline`,x:.5,y:.1,size:.045,weight:900}])],r=new Map(n.map(e=>[e.id,e])),i=e=>r.get(e)||null;function a(e,t=16/9){return e?t<1?{slots:e.pSlots,textSlots:e.pTextSlots}:{slots:e.slots,textSlots:e.textSlots}:null}function o(e,t,{aspect:n=16/9}={}){if(!t)return(e||[]).map(e=>{if(e.pinned||e.kind!==`image`||!e.box)return e;let{box:t,...n}=e;return n});let r=a(t,n),i=(e,t)=>(e.appearMs||0)-(t.appearMs||0),o=(e||[]).filter(e=>e.kind===`image`&&!e.pinned).sort(i),s=(e||[]).filter(e=>e.kind===`text`&&!e.pinned).sort(i),c=new Map;o.forEach((e,t)=>{t<r.slots.length&&c.set(e.id,r.slots[t])});let l=new Map;return s.forEach((e,t)=>{t<r.textSlots.length&&l.set(e.id,r.textSlots[t])}),(e||[]).map(e=>{if(e.pinned)return e;if(e.kind===`image`){let t=c.get(e.id);if(!t){let{box:t,...n}=e;return{...n,pos:null}}return{...e,pos:{x:t.x,y:t.y},box:{w:t.w,h:t.h},size:t.w,tilt:t.tilt||0}}let t=l.get(e.id);return t?{...e,pos:{x:t.x,y:t.y},size:t.size,weight:t.weight||e.weight||800}:e})}let s=e=>{let t=5381,n=String(e||``);for(let e=0;e<n.length;e++)t=(t<<5)+t+n.charCodeAt(e)>>>0;return t},c=(e,t)=>s(`${e}|${t}`)%2e3/1e3-1;function l(e,t=16/9){let n=.08+.4*Math.sqrt((e+.5)/48),r=e*2.399963229728653;return{x:.5+n*Math.cos(r),y:.5+n*Math.sin(r)*(t>1?.9:1.1)}}let u=(e,t,n)=>Math.max(t,Math.min(n,e));function d(e,{aspect:t=16/9}={}){let n=(e?.elements||[]).slice().sort((e,t)=>(e.appearMs||0)-(t.appearMs||0)),r=[],i=new Map;for(let a of n){let n=(a.kind===`image`?a.size||.28:.18)/2;if(a.pinned||!e.autoArrange){a.pos&&(r.push({...a.pos,size:a.size||.28,appearMs:a.appearMs,leaveMs:a.leaveMs}),i.set(a.id,a.pos));continue}let o=r.filter(e=>e.leaveMs==null||e.leaveMs>a.appearMs),d=null,f=-1/0;for(let e=0;e<48;e++){let r=l((e+s(a.id)%48)%48,t),i=u(r.x,n+.03,1-n-.03),c=u(r.y,n+.05,1-n-.05),p=1/0;for(let e of o)p=Math.min(p,Math.hypot(i-e.x,c-e.y)-(e.size||.28)/2-n);let m=-.12*Math.hypot(i-.5,c-.5),h=(o.length?Math.min(p,.5):.3)+m;h>f&&(f=h,d={x:i,y:c})}let p=d||{x:.5,y:.5};p.x=u(p.x+c(a.id,`x`)*.015,n,1-n),p.y=u(p.y+c(a.id,`y`)*.015,n,1-n),r.push({...p,size:a.size||.28,appearMs:a.appearMs,leaveMs:a.leaveMs}),i.set(a.id,p)}return i}function f(e,t){if(!e.autoArrange)return e;let n=d(e,t);return{...e,elements:(e.elements||[]).map(e=>!e.pinned&&n.has(e.id)?{...e,pos:n.get(e.id)}:e)}}function p(e){let t=e?.meta?.aspect||`16:9`;return t===`9:16`?9/16:t===`1:1`?1:16/9}function m(e,t){let n=i(t.template);if(n){let r=o(t.elements||[],n,{aspect:p(e)}),i=d({...t,autoArrange:!0,elements:r.map(e=>e.pos?{...e,pinned:!0}:e)},{aspect:p(e)});return{...t,elements:r.map(e=>!e.pinned&&!e.pos&&i.has(e.id)?{...e,pos:i.get(e.id)}:e)}}return t.autoArrange?f(t,{aspect:p(e)}):t}function h(e,t,n,r,{freezeLayout:i=!1}={}){let a=e.strip.find(e=>e.panelId===t);if(!a||a.type!==`canvas`)throw Error(`patchCanvasElement: ${t} is not a canvas panel`);let o=e.strip.map(a=>{if(a.panelId!==t)return a;let o={...a,elements:(a.elements||[]).map(e=>e.id===n?{...e,...r}:e)};return i?o:m(e,o)});return g({...e,strip:o})}let g=e=>e;return{edit:h(e.doc,e.panelId,e.elementId,e.patch,{freezeLayout:e.freezeLayout})}},\"stillmade-internal.canvas-remove-element@1.0.0\":function(e){let t=(e,t,n,r,i,a,o,s)=>({id:e,name:t,scenario:n,minImages:r,slots:i,textSlots:a,pSlots:o,pTextSlots:s}),n=[t(`hero-headline`,`Hero + headline`,`one subject, one line`,1,[{x:.5,y:.58,w:.5,h:.62}],[{role:`headline`,x:.5,y:.14,size:.09,weight:900}],[{x:.5,y:.55,w:.78,h:.5}],[{role:`headline`,x:.5,y:.13,size:.055,weight:900}]),t(`hero-supporting`,`Hero + 2 supporting`,`main subject with two details`,3,[{x:.34,y:.55,w:.42,h:.58},{x:.78,y:.33,w:.28,h:.32},{x:.78,y:.73,w:.28,h:.32}],[{role:`headline`,x:.34,y:.13,size:.08,weight:900}],[{x:.5,y:.38,w:.78,h:.32},{x:.28,y:.72,w:.4,h:.2},{x:.72,y:.72,w:.4,h:.2}],[{role:`headline`,x:.5,y:.12,size:.05,weight:900}]),t(`compare-2`,`Side-by-side compare`,`A vs B`,2,[{x:.27,y:.5,w:.38,h:.5},{x:.73,y:.5,w:.38,h:.5}],[{role:`headline`,x:.5,y:.12,size:.08,weight:900},{role:`label`,x:.27,y:.84,size:.05,weight:800},{role:`label`,x:.73,y:.84,size:.05,weight:800}],[{x:.5,y:.35,w:.72,h:.24},{x:.5,y:.72,w:.72,h:.24}],[{role:`headline`,x:.5,y:.11,size:.05,weight:900},{role:`label`,x:.5,y:.51,size:.032,weight:800},{role:`label`,x:.5,y:.88,size:.032,weight:800}]),t(`three-across`,`Three across`,`three items`,3,[{x:.2,y:.5,w:.26,h:.46},{x:.5,y:.5,w:.26,h:.46},{x:.8,y:.5,w:.26,h:.46}],[{role:`headline`,x:.5,y:.13,size:.08,weight:900},{role:`caption`,x:.5,y:.86,size:.045,weight:600}],[{x:.5,y:.32,w:.64,h:.2},{x:.5,y:.57,w:.64,h:.2},{x:.5,y:.82,w:.64,h:.2}],[{role:`headline`,x:.5,y:.1,size:.05,weight:900},{role:`caption`,x:.5,y:.96,size:.028,weight:600}]),t(`grid-2x2`,`Grid of four`,`four items`,4,[{x:.3,y:.36,w:.32,h:.34},{x:.7,y:.36,w:.32,h:.34},{x:.3,y:.74,w:.32,h:.34},{x:.7,y:.74,w:.32,h:.34}],[{role:`headline`,x:.5,y:.09,size:.07,weight:900}],[{x:.28,y:.38,w:.4,h:.24},{x:.72,y:.38,w:.4,h:.24},{x:.28,y:.68,w:.4,h:.24},{x:.72,y:.68,w:.4,h:.24}],[{role:`headline`,x:.5,y:.12,size:.05,weight:900}]),t(`grid-3x3`,`Many small (3x3)`,`lots of items`,6,[.22,.5,.78].flatMap(e=>[.3,.56,.82].map(t=>({x:e,y:t,w:.24,h:.22}))),[{role:`headline`,x:.5,y:.08,size:.065,weight:900}],[.2,.5,.8].flatMap(e=>[.34,.58,.82].map(t=>({x:e,y:t,w:.27,h:.18}))),[{role:`headline`,x:.5,y:.1,size:.045,weight:900}]),t(`big-left-stack-right`,`Big lead + stack`,`one lead, several follow-ups`,3,[{x:.32,y:.54,w:.5,h:.62},{x:.79,y:.3,w:.3,h:.22},{x:.79,y:.56,w:.3,h:.22},{x:.79,y:.82,w:.3,h:.22}],[{role:`headline`,x:.32,y:.13,size:.075,weight:900}],[{x:.5,y:.4,w:.84,h:.34},{x:.2,y:.74,w:.26,h:.16},{x:.5,y:.74,w:.26,h:.16},{x:.8,y:.74,w:.26,h:.16}],[{role:`headline`,x:.5,y:.12,size:.05,weight:900}]),t(`vertical-stack`,`Vertical stack`,`ordered top to bottom`,2,[{x:.55,y:.29,w:.36,h:.22},{x:.55,y:.55,w:.36,h:.22},{x:.55,y:.81,w:.36,h:.22}],[{role:`headline`,x:.55,y:.08,size:.065,weight:900},{role:`label`,x:.16,y:.55,size:.055,weight:800}],[{x:.5,y:.3,w:.66,h:.2},{x:.5,y:.56,w:.66,h:.2},{x:.5,y:.82,w:.66,h:.2}],[{role:`headline`,x:.5,y:.09,size:.05,weight:900},{role:`label`,x:.24,y:.17,size:.032,weight:800}]),t(`scatter`,`Scattered collage`,`loose, hand-thrown feel`,3,[{x:.26,y:.36,w:.28,h:.32,tilt:-6},{x:.68,y:.3,w:.26,h:.3,tilt:4},{x:.44,y:.66,w:.27,h:.31,tilt:3},{x:.8,y:.62,w:.25,h:.29,tilt:-5},{x:.58,y:.46,w:.24,h:.28,tilt:2}],[{role:`headline`,x:.5,y:.1,size:.075,weight:900}],[{x:.32,y:.3,w:.46,h:.2,tilt:-6},{x:.7,y:.26,w:.42,h:.18,tilt:4},{x:.4,y:.56,w:.44,h:.2,tilt:3},{x:.74,y:.6,w:.4,h:.18,tilt:-5},{x:.5,y:.82,w:.44,h:.19,tilt:2}],[{role:`headline`,x:.5,y:.09,size:.045,weight:900}]),t(`timeline-row`,`Row / timeline`,`steps in order`,3,[{x:.14,y:.52,w:.2,h:.38},{x:.38,y:.52,w:.2,h:.38},{x:.62,y:.52,w:.2,h:.38},{x:.86,y:.52,w:.2,h:.38}],[{role:`headline`,x:.5,y:.15,size:.075,weight:900},{role:`caption`,x:.5,y:.85,size:.045,weight:600}],[{x:.35,y:.28,w:.5,h:.15},{x:.65,y:.47,w:.5,h:.15},{x:.35,y:.66,w:.5,h:.15},{x:.65,y:.85,w:.5,h:.15}],[{role:`headline`,x:.5,y:.12,size:.05,weight:900}]),t(`center-satellites`,`Center + satellites`,`one core idea, orbiting parts`,3,[{x:.5,y:.52,w:.34,h:.42},{x:.17,y:.3,w:.2,h:.26},{x:.83,y:.3,w:.2,h:.26},{x:.17,y:.77,w:.2,h:.26},{x:.83,y:.77,w:.2,h:.26}],[{role:`headline`,x:.5,y:.09,size:.065,weight:900}],[{x:.5,y:.52,w:.56,h:.28},{x:.2,y:.28,w:.32,h:.16},{x:.8,y:.28,w:.32,h:.16},{x:.2,y:.78,w:.32,h:.16},{x:.8,y:.78,w:.32,h:.16}],[{role:`headline`,x:.5,y:.1,size:.045,weight:900}]),t(`corner-big-text`,`Corner images, big text`,`statement first, proof beside it`,2,[{x:.72,y:.4,w:.32,h:.38},{x:.52,y:.72,w:.28,h:.34},{x:.85,y:.76,w:.24,h:.3}],[{role:`headline`,x:.26,y:.26,size:.105,weight:900},{role:`label`,x:.26,y:.42,size:.05,weight:600}],[{x:.36,y:.56,w:.5,h:.22},{x:.7,y:.7,w:.44,h:.2},{x:.4,y:.84,w:.4,h:.18}],[{role:`headline`,x:.5,y:.19,size:.065,weight:900},{role:`label`,x:.5,y:.31,size:.034,weight:600}]),t(`title-top-row`,`Title top, images below`,`title screen with evidence`,2,[{x:.22,y:.62,w:.28,h:.44},{x:.5,y:.62,w:.28,h:.44},{x:.78,y:.62,w:.28,h:.44}],[{role:`headline`,x:.5,y:.17,size:.1,weight:900}],[{x:.5,y:.4,w:.7,h:.2},{x:.5,y:.64,w:.7,h:.2},{x:.5,y:.86,w:.7,h:.16}],[{role:`headline`,x:.5,y:.15,size:.06,weight:900}]),t(`large-caption`,`One large + caption`,`let the image speak`,1,[{x:.5,y:.47,w:.56,h:.6}],[{role:`label`,x:.15,y:.1,size:.045,weight:800},{role:`caption`,x:.5,y:.85,size:.055,weight:600}],[{x:.5,y:.47,w:.82,h:.44}],[{role:`label`,x:.24,y:.12,size:.032,weight:800},{role:`caption`,x:.5,y:.78,size:.034,weight:600}]),t(`staggered-diagonal`,`Staggered diagonal`,`progression with motion`,3,[{x:.18,y:.26,w:.24,h:.3,tilt:-3},{x:.42,y:.45,w:.24,h:.3,tilt:3},{x:.64,y:.62,w:.24,h:.3,tilt:-3},{x:.86,y:.79,w:.24,h:.3,tilt:3}],[{role:`headline`,x:.74,y:.16,size:.075,weight:900}],[{x:.28,y:.3,w:.42,h:.18,tilt:-3},{x:.62,y:.46,w:.42,h:.18,tilt:3},{x:.36,y:.62,w:.42,h:.18,tilt:-3},{x:.68,y:.78,w:.42,h:.18,tilt:3}],[{role:`headline`,x:.5,y:.12,size:.05,weight:900}]),t(`overlap-stack`,`Overlapping stack`,`a deliberate pile`,2,[{x:.42,y:.5,w:.36,h:.46,tilt:-5},{x:.54,y:.56,w:.36,h:.46,tilt:3},{x:.63,y:.46,w:.36,h:.46,tilt:-2}],[{role:`headline`,x:.5,y:.12,size:.08,weight:900},{role:`caption`,x:.5,y:.89,size:.045,weight:600}],[{x:.44,y:.42,w:.58,h:.26,tilt:-5},{x:.58,y:.53,w:.58,h:.26,tilt:3},{x:.46,y:.64,w:.58,h:.26,tilt:-2}],[{role:`headline`,x:.5,y:.12,size:.05,weight:900},{role:`caption`,x:.5,y:.86,size:.032,weight:600}]),t(`banner-row`,`Wide banner + small row`,`one wide scene, details under`,2,[{x:.5,y:.36,w:.84,h:.36},{x:.25,y:.77,w:.24,h:.26},{x:.5,y:.77,w:.24,h:.26},{x:.75,y:.77,w:.24,h:.26}],[{role:`headline`,x:.5,y:.09,size:.065,weight:900}],[{x:.5,y:.36,w:.86,h:.26},{x:.22,y:.66,w:.28,h:.16},{x:.5,y:.66,w:.28,h:.16},{x:.78,y:.66,w:.28,h:.16}],[{role:`headline`,x:.5,y:.13,size:.05,weight:900},{role:`caption`,x:.5,y:.82,size:.032,weight:600}]),t(`quadrant-labels`,`Quadrants with labels`,`four named things`,4,[{x:.28,y:.3,w:.3,h:.3},{x:.72,y:.3,w:.3,h:.3},{x:.28,y:.71,w:.3,h:.3},{x:.72,y:.71,w:.3,h:.3}],[{role:`headline`,x:.5,y:.07,size:.06,weight:900},{role:`label`,x:.28,y:.49,size:.042,weight:800},{role:`label`,x:.72,y:.49,size:.042,weight:800},{role:`label`,x:.28,y:.9,size:.042,weight:800},{role:`label`,x:.72,y:.9,size:.042,weight:800}],[{x:.28,y:.32,w:.38,h:.2},{x:.72,y:.32,w:.38,h:.2},{x:.28,y:.64,w:.38,h:.2},{x:.72,y:.64,w:.38,h:.2}],[{role:`headline`,x:.5,y:.1,size:.045,weight:900},{role:`label`,x:.28,y:.45,size:.028,weight:800},{role:`label`,x:.72,y:.45,size:.028,weight:800},{role:`label`,x:.28,y:.77,size:.028,weight:800},{role:`label`,x:.72,y:.77,size:.028,weight:800}]),t(`pyramid-3`,`Pyramid of three`,`one above two`,3,[{x:.5,y:.32,w:.3,h:.32},{x:.32,y:.71,w:.3,h:.32},{x:.68,y:.71,w:.3,h:.32}],[{role:`headline`,x:.5,y:.08,size:.065,weight:900},{role:`caption`,x:.5,y:.92,size:.04,weight:600}],[{x:.5,y:.34,w:.5,h:.22},{x:.27,y:.62,w:.42,h:.18},{x:.73,y:.62,w:.42,h:.18}],[{role:`headline`,x:.5,y:.1,size:.05,weight:900},{role:`caption`,x:.5,y:.79,size:.032,weight:600}]),t(`mosaic-dense`,`Dense mosaic`,`everything at once`,5,[{x:.3,y:.4,w:.34,h:.42},{x:.62,y:.29,w:.24,h:.26},{x:.86,y:.33,w:.2,h:.28},{x:.19,y:.78,w:.24,h:.26},{x:.47,y:.77,w:.26,h:.28},{x:.73,y:.73,w:.22,h:.24},{x:.91,y:.76,w:.14,h:.18}],[{role:`headline`,x:.5,y:.09,size:.06,weight:900}],[{x:.32,y:.3,w:.5,h:.2},{x:.78,y:.26,w:.36,h:.16},{x:.24,y:.52,w:.4,h:.16},{x:.68,y:.5,w:.44,h:.18},{x:.3,y:.74,w:.42,h:.16},{x:.74,y:.73,w:.4,h:.16},{x:.5,y:.89,w:.5,h:.1}],[{role:`headline`,x:.5,y:.1,size:.045,weight:900}])],r=new Map(n.map(e=>[e.id,e])),i=e=>r.get(e)||null;function a(e,t=16/9){return e?t<1?{slots:e.pSlots,textSlots:e.pTextSlots}:{slots:e.slots,textSlots:e.textSlots}:null}function o(e,t,{aspect:n=16/9}={}){if(!t)return(e||[]).map(e=>{if(e.pinned||e.kind!==`image`||!e.box)return e;let{box:t,...n}=e;return n});let r=a(t,n),i=(e,t)=>(e.appearMs||0)-(t.appearMs||0),o=(e||[]).filter(e=>e.kind===`image`&&!e.pinned).sort(i),s=(e||[]).filter(e=>e.kind===`text`&&!e.pinned).sort(i),c=new Map;o.forEach((e,t)=>{t<r.slots.length&&c.set(e.id,r.slots[t])});let l=new Map;return s.forEach((e,t)=>{t<r.textSlots.length&&l.set(e.id,r.textSlots[t])}),(e||[]).map(e=>{if(e.pinned)return e;if(e.kind===`image`){let t=c.get(e.id);if(!t){let{box:t,...n}=e;return{...n,pos:null}}return{...e,pos:{x:t.x,y:t.y},box:{w:t.w,h:t.h},size:t.w,tilt:t.tilt||0}}let t=l.get(e.id);return t?{...e,pos:{x:t.x,y:t.y},size:t.size,weight:t.weight||e.weight||800}:e})}function s({imageCount:e=0,textCount:t=0,hint:n=``}={}){if(!e)return null;let r=String(n||``).toLowerCase();return e===2&&/\\bvs\\b|versus|compar|before.*after|either/.test(r)?`compare-2`:e>=3&&/step|order|sequence|timeline|process|journey|stages/.test(r)?`timeline-row`:e>=3&&/list|lists|enumerat|items|examples|types|kinds/.test(r)?e>=5?`mosaic-dense`:`three-across`:e===1?t>1?`large-caption`:`hero-headline`:e===2?`compare-2`:e===3?`three-across`:e===4?`grid-2x2`:e===5?`center-satellites`:e<=7?`mosaic-dense`:`grid-3x3`}let c=e=>{let t=5381,n=String(e||``);for(let e=0;e<n.length;e++)t=(t<<5)+t+n.charCodeAt(e)>>>0;return t},l=(e,t)=>c(`${e}|${t}`)%2e3/1e3-1;function u(e,t=16/9){let n=.08+.4*Math.sqrt((e+.5)/48),r=e*2.399963229728653;return{x:.5+n*Math.cos(r),y:.5+n*Math.sin(r)*(t>1?.9:1.1)}}let d=(e,t,n)=>Math.max(t,Math.min(n,e));function f(e,{aspect:t=16/9}={}){let n=(e?.elements||[]).slice().sort((e,t)=>(e.appearMs||0)-(t.appearMs||0)),r=[],i=new Map;for(let a of n){let n=(a.kind===`image`?a.size||.28:.18)/2;if(a.pinned||!e.autoArrange){a.pos&&(r.push({...a.pos,size:a.size||.28,appearMs:a.appearMs,leaveMs:a.leaveMs}),i.set(a.id,a.pos));continue}let o=r.filter(e=>e.leaveMs==null||e.leaveMs>a.appearMs),s=null,f=-1/0;for(let e=0;e<48;e++){let r=u((e+c(a.id)%48)%48,t),i=d(r.x,n+.03,1-n-.03),l=d(r.y,n+.05,1-n-.05),p=1/0;for(let e of o)p=Math.min(p,Math.hypot(i-e.x,l-e.y)-(e.size||.28)/2-n);let m=-.12*Math.hypot(i-.5,l-.5),h=(o.length?Math.min(p,.5):.3)+m;h>f&&(f=h,s={x:i,y:l})}let p=s||{x:.5,y:.5};p.x=d(p.x+l(a.id,`x`)*.015,n,1-n),p.y=d(p.y+l(a.id,`y`)*.015,n,1-n),r.push({...p,size:a.size||.28,appearMs:a.appearMs,leaveMs:a.leaveMs}),i.set(a.id,p)}return i}function p(e,t){if(!e.autoArrange)return e;let n=f(e,t);return{...e,elements:(e.elements||[]).map(e=>!e.pinned&&n.has(e.id)?{...e,pos:n.get(e.id)}:e)}}function m(e){let t=e?.meta?.aspect||`16:9`;return t===`9:16`?9/16:t===`1:1`?1:16/9}function h(e,t){let n=i(t.template);if(n){let r=o(t.elements||[],n,{aspect:m(e)}),i=f({...t,autoArrange:!0,elements:r.map(e=>e.pos?{...e,pinned:!0}:e)},{aspect:m(e)});return{...t,elements:r.map(e=>!e.pinned&&!e.pos&&i.has(e.id)?{...e,pos:i.get(e.id)}:e)}}return t.autoArrange?p(t,{aspect:m(e)}):t}function g(e,t){if(!e.autoArrange||!e.template)return e.template;let n=i(e.template);if(!n)return e.template;let r=t.filter(e=>e.kind===`image`||e.kind===`video`).length,a=t.filter(e=>e.kind===`text`).length;return r>0&&r<=n.slots.length?e.template:s({imageCount:r,textCount:a,hint:`${n.scenario||``} ${e.hint||``}`})||e.template}function g(e,t){if(!e.autoArrange||!e.template)return e.template;let n=i(e.template);if(!n)return e.template;let r=t.filter(e=>e.kind===`image`||e.kind===`video`).length,a=t.filter(e=>e.kind===`text`).length;return r>0&&r<=n.slots.length?e.template:s({imageCount:r,textCount:a,hint:`${n.scenario||``} ${e.hint||``}`})||e.template}function _(e,t,n){let r=e.strip.map(r=>{if(r.panelId!==t)return r;let i=(r.elements||[]).filter(e=>e.id!==n);return h(e,{...r,template:g(r,i),elements:i})});return v({...e,strip:r})}let v=e=>e;return{edit:_(e.doc,e.panelId,e.elementId)}},\"stillmade-internal.canvas-template@1.0.0\":function(e){let t=(e,t,n,r,i,a,o,s)=>({id:e,name:t,scenario:n,minImages:r,slots:i,textSlots:a,pSlots:o,pTextSlots:s}),n=[t(`hero-headline`,`Hero + headline`,`one subject, one line`,1,[{x:.5,y:.58,w:.5,h:.62}],[{role:`headline`,x:.5,y:.14,size:.09,weight:900}],[{x:.5,y:.55,w:.78,h:.5}],[{role:`headline`,x:.5,y:.13,size:.055,weight:900}]),t(`hero-supporting`,`Hero + 2 supporting`,`main subject with two details`,3,[{x:.34,y:.55,w:.42,h:.58},{x:.78,y:.33,w:.28,h:.32},{x:.78,y:.73,w:.28,h:.32}],[{role:`headline`,x:.34,y:.13,size:.08,weight:900}],[{x:.5,y:.38,w:.78,h:.32},{x:.28,y:.72,w:.4,h:.2},{x:.72,y:.72,w:.4,h:.2}],[{role:`headline`,x:.5,y:.12,size:.05,weight:900}]),t(`compare-2`,`Side-by-side compare`,`A vs B`,2,[{x:.27,y:.5,w:.38,h:.5},{x:.73,y:.5,w:.38,h:.5}],[{role:`headline`,x:.5,y:.12,size:.08,weight:900},{role:`label`,x:.27,y:.84,size:.05,weight:800},{role:`label`,x:.73,y:.84,size:.05,weight:800}],[{x:.5,y:.35,w:.72,h:.24},{x:.5,y:.72,w:.72,h:.24}],[{role:`headline`,x:.5,y:.11,size:.05,weight:900},{role:`label`,x:.5,y:.51,size:.032,weight:800},{role:`label`,x:.5,y:.88,size:.032,weight:800}]),t(`three-across`,`Three across`,`three items`,3,[{x:.2,y:.5,w:.26,h:.46},{x:.5,y:.5,w:.26,h:.46},{x:.8,y:.5,w:.26,h:.46}],[{role:`headline`,x:.5,y:.13,size:.08,weight:900},{role:`caption`,x:.5,y:.86,size:.045,weight:600}],[{x:.5,y:.32,w:.64,h:.2},{x:.5,y:.57,w:.64,h:.2},{x:.5,y:.82,w:.64,h:.2}],[{role:`headline`,x:.5,y:.1,size:.05,weight:900},{role:`caption`,x:.5,y:.96,size:.028,weight:600}]),t(`grid-2x2`,`Grid of four`,`four items`,4,[{x:.3,y:.36,w:.32,h:.34},{x:.7,y:.36,w:.32,h:.34},{x:.3,y:.74,w:.32,h:.34},{x:.7,y:.74,w:.32,h:.34}],[{role:`headline`,x:.5,y:.09,size:.07,weight:900}],[{x:.28,y:.38,w:.4,h:.24},{x:.72,y:.38,w:.4,h:.24},{x:.28,y:.68,w:.4,h:.24},{x:.72,y:.68,w:.4,h:.24}],[{role:`headline`,x:.5,y:.12,size:.05,weight:900}]),t(`grid-3x3`,`Many small (3x3)`,`lots of items`,6,[.22,.5,.78].flatMap(e=>[.3,.56,.82].map(t=>({x:e,y:t,w:.24,h:.22}))),[{role:`headline`,x:.5,y:.08,size:.065,weight:900}],[.2,.5,.8].flatMap(e=>[.34,.58,.82].map(t=>({x:e,y:t,w:.27,h:.18}))),[{role:`headline`,x:.5,y:.1,size:.045,weight:900}]),t(`big-left-stack-right`,`Big lead + stack`,`one lead, several follow-ups`,3,[{x:.32,y:.54,w:.5,h:.62},{x:.79,y:.3,w:.3,h:.22},{x:.79,y:.56,w:.3,h:.22},{x:.79,y:.82,w:.3,h:.22}],[{role:`headline`,x:.32,y:.13,size:.075,weight:900}],[{x:.5,y:.4,w:.84,h:.34},{x:.2,y:.74,w:.26,h:.16},{x:.5,y:.74,w:.26,h:.16},{x:.8,y:.74,w:.26,h:.16}],[{role:`headline`,x:.5,y:.12,size:.05,weight:900}]),t(`vertical-stack`,`Vertical stack`,`ordered top to bottom`,2,[{x:.55,y:.29,w:.36,h:.22},{x:.55,y:.55,w:.36,h:.22},{x:.55,y:.81,w:.36,h:.22}],[{role:`headline`,x:.55,y:.08,size:.065,weight:900},{role:`label`,x:.16,y:.55,size:.055,weight:800}],[{x:.5,y:.3,w:.66,h:.2},{x:.5,y:.56,w:.66,h:.2},{x:.5,y:.82,w:.66,h:.2}],[{role:`headline`,x:.5,y:.09,size:.05,weight:900},{role:`label`,x:.24,y:.17,size:.032,weight:800}]),t(`scatter`,`Scattered collage`,`loose, hand-thrown feel`,3,[{x:.26,y:.36,w:.28,h:.32,tilt:-6},{x:.68,y:.3,w:.26,h:.3,tilt:4},{x:.44,y:.66,w:.27,h:.31,tilt:3},{x:.8,y:.62,w:.25,h:.29,tilt:-5},{x:.58,y:.46,w:.24,h:.28,tilt:2}],[{role:`headline`,x:.5,y:.1,size:.075,weight:900}],[{x:.32,y:.3,w:.46,h:.2,tilt:-6},{x:.7,y:.26,w:.42,h:.18,tilt:4},{x:.4,y:.56,w:.44,h:.2,tilt:3},{x:.74,y:.6,w:.4,h:.18,tilt:-5},{x:.5,y:.82,w:.44,h:.19,tilt:2}],[{role:`headline`,x:.5,y:.09,size:.045,weight:900}]),t(`timeline-row`,`Row / timeline`,`steps in order`,3,[{x:.14,y:.52,w:.2,h:.38},{x:.38,y:.52,w:.2,h:.38},{x:.62,y:.52,w:.2,h:.38},{x:.86,y:.52,w:.2,h:.38}],[{role:`headline`,x:.5,y:.15,size:.075,weight:900},{role:`caption`,x:.5,y:.85,size:.045,weight:600}],[{x:.35,y:.28,w:.5,h:.15},{x:.65,y:.47,w:.5,h:.15},{x:.35,y:.66,w:.5,h:.15},{x:.65,y:.85,w:.5,h:.15}],[{role:`headline`,x:.5,y:.12,size:.05,weight:900}]),t(`center-satellites`,`Center + satellites`,`one core idea, orbiting parts`,3,[{x:.5,y:.52,w:.34,h:.42},{x:.17,y:.3,w:.2,h:.26},{x:.83,y:.3,w:.2,h:.26},{x:.17,y:.77,w:.2,h:.26},{x:.83,y:.77,w:.2,h:.26}],[{role:`headline`,x:.5,y:.09,size:.065,weight:900}],[{x:.5,y:.52,w:.56,h:.28},{x:.2,y:.28,w:.32,h:.16},{x:.8,y:.28,w:.32,h:.16},{x:.2,y:.78,w:.32,h:.16},{x:.8,y:.78,w:.32,h:.16}],[{role:`headline`,x:.5,y:.1,size:.045,weight:900}]),t(`corner-big-text`,`Corner images, big text`,`statement first, proof beside it`,2,[{x:.72,y:.4,w:.32,h:.38},{x:.52,y:.72,w:.28,h:.34},{x:.85,y:.76,w:.24,h:.3}],[{role:`headline`,x:.26,y:.26,size:.105,weight:900},{role:`label`,x:.26,y:.42,size:.05,weight:600}],[{x:.36,y:.56,w:.5,h:.22},{x:.7,y:.7,w:.44,h:.2},{x:.4,y:.84,w:.4,h:.18}],[{role:`headline`,x:.5,y:.19,size:.065,weight:900},{role:`label`,x:.5,y:.31,size:.034,weight:600}]),t(`title-top-row`,`Title top, images below`,`title screen with evidence`,2,[{x:.22,y:.62,w:.28,h:.44},{x:.5,y:.62,w:.28,h:.44},{x:.78,y:.62,w:.28,h:.44}],[{role:`headline`,x:.5,y:.17,size:.1,weight:900}],[{x:.5,y:.4,w:.7,h:.2},{x:.5,y:.64,w:.7,h:.2},{x:.5,y:.86,w:.7,h:.16}],[{role:`headline`,x:.5,y:.15,size:.06,weight:900}]),t(`large-caption`,`One large + caption`,`let the image speak`,1,[{x:.5,y:.47,w:.56,h:.6}],[{role:`label`,x:.15,y:.1,size:.045,weight:800},{role:`caption`,x:.5,y:.85,size:.055,weight:600}],[{x:.5,y:.47,w:.82,h:.44}],[{role:`label`,x:.24,y:.12,size:.032,weight:800},{role:`caption`,x:.5,y:.78,size:.034,weight:600}]),t(`staggered-diagonal`,`Staggered diagonal`,`progression with motion`,3,[{x:.18,y:.26,w:.24,h:.3,tilt:-3},{x:.42,y:.45,w:.24,h:.3,tilt:3},{x:.64,y:.62,w:.24,h:.3,tilt:-3},{x:.86,y:.79,w:.24,h:.3,tilt:3}],[{role:`headline`,x:.74,y:.16,size:.075,weight:900}],[{x:.28,y:.3,w:.42,h:.18,tilt:-3},{x:.62,y:.46,w:.42,h:.18,tilt:3},{x:.36,y:.62,w:.42,h:.18,tilt:-3},{x:.68,y:.78,w:.42,h:.18,tilt:3}],[{role:`headline`,x:.5,y:.12,size:.05,weight:900}]),t(`overlap-stack`,`Overlapping stack`,`a deliberate pile`,2,[{x:.42,y:.5,w:.36,h:.46,tilt:-5},{x:.54,y:.56,w:.36,h:.46,tilt:3},{x:.63,y:.46,w:.36,h:.46,tilt:-2}],[{role:`headline`,x:.5,y:.12,size:.08,weight:900},{role:`caption`,x:.5,y:.89,size:.045,weight:600}],[{x:.44,y:.42,w:.58,h:.26,tilt:-5},{x:.58,y:.53,w:.58,h:.26,tilt:3},{x:.46,y:.64,w:.58,h:.26,tilt:-2}],[{role:`headline`,x:.5,y:.12,size:.05,weight:900},{role:`caption`,x:.5,y:.86,size:.032,weight:600}]),t(`banner-row`,`Wide banner + small row`,`one wide scene, details under`,2,[{x:.5,y:.36,w:.84,h:.36},{x:.25,y:.77,w:.24,h:.26},{x:.5,y:.77,w:.24,h:.26},{x:.75,y:.77,w:.24,h:.26}],[{role:`headline`,x:.5,y:.09,size:.065,weight:900}],[{x:.5,y:.36,w:.86,h:.26},{x:.22,y:.66,w:.28,h:.16},{x:.5,y:.66,w:.28,h:.16},{x:.78,y:.66,w:.28,h:.16}],[{role:`headline`,x:.5,y:.13,size:.05,weight:900},{role:`caption`,x:.5,y:.82,size:.032,weight:600}]),t(`quadrant-labels`,`Quadrants with labels`,`four named things`,4,[{x:.28,y:.3,w:.3,h:.3},{x:.72,y:.3,w:.3,h:.3},{x:.28,y:.71,w:.3,h:.3},{x:.72,y:.71,w:.3,h:.3}],[{role:`headline`,x:.5,y:.07,size:.06,weight:900},{role:`label`,x:.28,y:.49,size:.042,weight:800},{role:`label`,x:.72,y:.49,size:.042,weight:800},{role:`label`,x:.28,y:.9,size:.042,weight:800},{role:`label`,x:.72,y:.9,size:.042,weight:800}],[{x:.28,y:.32,w:.38,h:.2},{x:.72,y:.32,w:.38,h:.2},{x:.28,y:.64,w:.38,h:.2},{x:.72,y:.64,w:.38,h:.2}],[{role:`headline`,x:.5,y:.1,size:.045,weight:900},{role:`label`,x:.28,y:.45,size:.028,weight:800},{role:`label`,x:.72,y:.45,size:.028,weight:800},{role:`label`,x:.28,y:.77,size:.028,weight:800},{role:`label`,x:.72,y:.77,size:.028,weight:800}]),t(`pyramid-3`,`Pyramid of three`,`one above two`,3,[{x:.5,y:.32,w:.3,h:.32},{x:.32,y:.71,w:.3,h:.32},{x:.68,y:.71,w:.3,h:.32}],[{role:`headline`,x:.5,y:.08,size:.065,weight:900},{role:`caption`,x:.5,y:.92,size:.04,weight:600}],[{x:.5,y:.34,w:.5,h:.22},{x:.27,y:.62,w:.42,h:.18},{x:.73,y:.62,w:.42,h:.18}],[{role:`headline`,x:.5,y:.1,size:.05,weight:900},{role:`caption`,x:.5,y:.79,size:.032,weight:600}]),t(`mosaic-dense`,`Dense mosaic`,`everything at once`,5,[{x:.3,y:.4,w:.34,h:.42},{x:.62,y:.29,w:.24,h:.26},{x:.86,y:.33,w:.2,h:.28},{x:.19,y:.78,w:.24,h:.26},{x:.47,y:.77,w:.26,h:.28},{x:.73,y:.73,w:.22,h:.24},{x:.91,y:.76,w:.14,h:.18}],[{role:`headline`,x:.5,y:.09,size:.06,weight:900}],[{x:.32,y:.3,w:.5,h:.2},{x:.78,y:.26,w:.36,h:.16},{x:.24,y:.52,w:.4,h:.16},{x:.68,y:.5,w:.44,h:.18},{x:.3,y:.74,w:.42,h:.16},{x:.74,y:.73,w:.4,h:.16},{x:.5,y:.89,w:.5,h:.1}],[{role:`headline`,x:.5,y:.1,size:.045,weight:900}])],r=new Map(n.map(e=>[e.id,e])),i=e=>r.get(e)||null;function a(e,t=16/9){return e?t<1?{slots:e.pSlots,textSlots:e.pTextSlots}:{slots:e.slots,textSlots:e.textSlots}:null}function o(e,t,{aspect:n=16/9}={}){if(!t)return(e||[]).map(e=>{if(e.pinned||e.kind!==`image`||!e.box)return e;let{box:t,...n}=e;return n});let r=a(t,n),i=(e,t)=>(e.appearMs||0)-(t.appearMs||0),o=(e||[]).filter(e=>e.kind===`image`&&!e.pinned).sort(i),s=(e||[]).filter(e=>e.kind===`text`&&!e.pinned).sort(i),c=new Map;o.forEach((e,t)=>{t<r.slots.length&&c.set(e.id,r.slots[t])});let l=new Map;return s.forEach((e,t)=>{t<r.textSlots.length&&l.set(e.id,r.textSlots[t])}),(e||[]).map(e=>{if(e.pinned)return e;if(e.kind===`image`){let t=c.get(e.id);if(!t){let{box:t,...n}=e;return{...n,pos:null}}return{...e,pos:{x:t.x,y:t.y},box:{w:t.w,h:t.h},size:t.w,tilt:t.tilt||0}}let t=l.get(e.id);return t?{...e,pos:{x:t.x,y:t.y},size:t.size,weight:t.weight||e.weight||800}:e})}let s=e=>{let t=5381,n=String(e||``);for(let e=0;e<n.length;e++)t=(t<<5)+t+n.charCodeAt(e)>>>0;return t},c=(e,t)=>s(`${e}|${t}`)%2e3/1e3-1;function l(e,t=16/9){let n=.08+.4*Math.sqrt((e+.5)/48),r=e*2.399963229728653;return{x:.5+n*Math.cos(r),y:.5+n*Math.sin(r)*(t>1?.9:1.1)}}let u=(e,t,n)=>Math.max(t,Math.min(n,e));function d(e,{aspect:t=16/9}={}){let n=(e?.elements||[]).slice().sort((e,t)=>(e.appearMs||0)-(t.appearMs||0)),r=[],i=new Map;for(let a of n){let n=(a.kind===`image`?a.size||.28:.18)/2;if(a.pinned||!e.autoArrange){a.pos&&(r.push({...a.pos,size:a.size||.28,appearMs:a.appearMs,leaveMs:a.leaveMs}),i.set(a.id,a.pos));continue}let o=r.filter(e=>e.leaveMs==null||e.leaveMs>a.appearMs),d=null,f=-1/0;for(let e=0;e<48;e++){let r=l((e+s(a.id)%48)%48,t),i=u(r.x,n+.03,1-n-.03),c=u(r.y,n+.05,1-n-.05),p=1/0;for(let e of o)p=Math.min(p,Math.hypot(i-e.x,c-e.y)-(e.size||.28)/2-n);let m=-.12*Math.hypot(i-.5,c-.5),h=(o.length?Math.min(p,.5):.3)+m;h>f&&(f=h,d={x:i,y:c})}let p=d||{x:.5,y:.5};p.x=u(p.x+c(a.id,`x`)*.015,n,1-n),p.y=u(p.y+c(a.id,`y`)*.015,n,1-n),r.push({...p,size:a.size||.28,appearMs:a.appearMs,leaveMs:a.leaveMs}),i.set(a.id,p)}return i}function f(e,t){if(!e.autoArrange)return e;let n=d(e,t);return{...e,elements:(e.elements||[]).map(e=>!e.pinned&&n.has(e.id)?{...e,pos:n.get(e.id)}:e)}}function p(e){let t=e?.meta?.aspect||`16:9`;return t===`9:16`?9/16:t===`1:1`?1:16/9}function m(e,t){let n=i(t.template);if(n){let r=o(t.elements||[],n,{aspect:p(e)}),i=d({...t,autoArrange:!0,elements:r.map(e=>e.pos?{...e,pinned:!0}:e)},{aspect:p(e)});return{...t,elements:r.map(e=>!e.pinned&&!e.pos&&i.has(e.id)?{...e,pos:i.get(e.id)}:e)}}return t.autoArrange?f(t,{aspect:p(e)}):t}function h(e,t,n){let r=e.strip.find(e=>e.panelId===t);if(!r||r.type!==`canvas`)throw Error(`setCanvasTemplate: ${t} is not a canvas panel`);if(n!=null&&!i(n))throw Error(`setCanvasTemplate: unknown template \"${n}\"`);if((r.template||null)===(n||null)&&r.mode!==`typewriter`)return e;let a=e.strip.map(r=>{if(r.panelId!==t)return r;let{mode:i,...a}=r,s={...a,template:n||null};return n||(s.elements=o(r.elements||[],null)),m(e,s)});return g({...e,strip:a})}let g=e=>e;return{edit:h(e.doc,e.panelId,e.templateId||null)}},\"stillmade-internal.canvas-tidy@1.0.0\":function(e){let t=e=>{let t=5381,n=String(e||``);for(let e=0;e<n.length;e++)t=(t<<5)+t+n.charCodeAt(e)>>>0;return t},n=(e,n)=>t(`${e}|${n}`)%2e3/1e3-1;function r(e,t=16/9){let n=.08+.4*Math.sqrt((e+.5)/48),r=e*2.399963229728653;return{x:.5+n*Math.cos(r),y:.5+n*Math.sin(r)*(t>1?.9:1.1)}}let i=(e,t,n)=>Math.max(t,Math.min(n,e));function a(e,{aspect:a=16/9}={}){let o=(e?.elements||[]).slice().sort((e,t)=>(e.appearMs||0)-(t.appearMs||0)),s=[],c=new Map;for(let l of o){let o=(l.kind===`image`?l.size||.28:.18)/2;if(l.pinned||!e.autoArrange){l.pos&&(s.push({...l.pos,size:l.size||.28,appearMs:l.appearMs,leaveMs:l.leaveMs}),c.set(l.id,l.pos));continue}let u=s.filter(e=>e.leaveMs==null||e.leaveMs>l.appearMs),d=null,f=-1/0;for(let e=0;e<48;e++){let n=r((e+t(l.id)%48)%48,a),s=i(n.x,o+.03,1-o-.03),c=i(n.y,o+.05,1-o-.05),p=1/0;for(let e of u)p=Math.min(p,Math.hypot(s-e.x,c-e.y)-(e.size||.28)/2-o);let m=-.12*Math.hypot(s-.5,c-.5),h=(u.length?Math.min(p,.5):.3)+m;h>f&&(f=h,d={x:s,y:c})}let p=d||{x:.5,y:.5};p.x=i(p.x+n(l.id,`x`)*.015,o,1-o),p.y=i(p.y+n(l.id,`y`)*.015,o,1-o),s.push({...p,size:l.size||.28,appearMs:l.appearMs,leaveMs:l.leaveMs}),c.set(l.id,p)}return c}function o(e,t){if(!e.autoArrange)return e;let n=a(e,t);return{...e,elements:(e.elements||[]).map(e=>!e.pinned&&n.has(e.id)?{...e,pos:n.get(e.id)}:e)}}let s=e.panel,c=o({...s,autoArrange:!0},{aspect:e.aspect});return{edit:{...s,elements:c.elements,provenance:`user`}}},\"stillmade-internal.canvas-typewriter@1.0.0\":function(e){function t(e,t){let n=e=>{let n=(Number(e.startMs)+Number(e.endMs))/2;return n>=t.startMs&&n<t.startMs+t.durationMs},r=(e?.audio?.words||[]).filter(e=>e&&String(e.text||``).trim()&&n(e)),i=[],a=[];for(let e=0;e<r.length;e++){a.push(r[e]);let t=e+1<r.length?Number(r[e+1].startMs)-Number(r[e].endMs):1/0;(/[.!?;:]$/.test(String(r[e].text))||t>600||a.length>=8)&&(i.push(a),a=[])}a.length&&i.push(a);let o=e=>Math.max(0,Math.min(t.durationMs-150,Math.round(e)-75-t.startMs));return i.map(e=>({text:e.map(e=>String(e.text).trim()).join(` `),wordTimes:e.map(e=>o(Number(e.startMs)))})).filter(e=>e.text)}function n(e,n){let i=e.strip.find(e=>e.panelId===n);if(!i||i.type!==`canvas`)throw Error(`applyCanvasTypewriter: ${n} is not a canvas panel`);let o=[];for(let n of t(e,i))String(n.text||``).split(/\\s+/).filter(Boolean).forEach((e,t)=>o.push({text:e,rel:Number(n.wordTimes?.[t])||0}));let s=r(o,{});if(!s.length)return e;let c=e.strip.map(e=>e.panelId===n?{...e,mode:`typewriter`,autoArrange:!1,template:null,elements:s}:e);return a({...e,strip:c})}function r(e,{size:t=.06,maxCharsPerLine:n=30,maxWordsPerLine:r=6}={}){let a=(Array.isArray(e)?e:[]).map(e=>({text:String(e?.text??``).trim(),rel:Math.max(0,Math.round(Number(e?.rel)||0))})).filter(e=>e.text);if(!a.length)return[];let o=[],s=[],c=0;for(let e of a){let t=e.text.length+ +!!s.length;s.length&&(c+t>n||s.length>=r)&&(o.push(s),s=[],c=0),s.push(e),c+=t}s.length&&o.push(s);let l=t*1.4,u=.5-o.length*l/2+l/2;return o.map((e,n)=>({id:`tw${n+1}`,kind:`text`,text:e.map(e=>e.text).join(` `),appearMs:e[0].rel,leaveMs:null,pos:{x:.5,y:i(u+n*l,.04,.96)},size:t,font:`Hanken Grotesk`,color:`#111111`,weight:800,wordTimes:e.map(e=>e.rel),anim:{type:`typewriter`,perWord:!1,speedMs:45},sfx:`auto`,pinned:!0}))}let i=(e,t,n)=>Math.max(t,Math.min(n,e)),a=e=>e;return{edit:n(e.doc,e.panelId)}},\"stillmade-internal.panel-cast-edit@1.0.0\":function(e){let t=e.referenceIds.filter(t=>t in e.effective&&e.sheets[t]!==e.effective[t]);return{edit:{sheets:e.sheets,stale:t}}},\"stillmade-internal.cast-reference-acceptance@1.0.0\":function(e){function t(e,t,n){return{...e,strip:e.strip.map(e=>e.panelId===t?{...e,...n,provenance:n.provenance||`user`}:e)}}function n(e,n,r){let i={...e,meta:{...e.meta||{},castRefs:{...e.meta?.castRefs||{},[n]:r}}};for(let e of i.strip)e.kind===`base`&&e.image&&(i.lineages?.[e.lineageId]?.sheetIds||[]).includes(n)&&(i=t(i,e.panelId,{needsRefresh:!0,provenance:e.provenance||`auto`}));return i}return{edit:n(e.doc,e.sheetId,e.url)}},\"stillmade-internal.consistency-result@1.0.0\":function(e){function t(e){let t=e.rows.map(e=>({...e}));if(e.mode===`warnings`)for(let n of e.offenders){let e=t.find(e=>e.panelId===n.panelId);if(!e)continue;let r={styleStrict:!0,styleWarning:n.issue||`style differs from the anchor`,provenance:e.provenance||`auto`};t=t.map(e=>e.panelId===n.panelId?{...e,...r}:e)}else for(let n of e.offenders){let e=t.find(e=>e.panelId===n.panelId);if(e?.kind!==`base`||e.styleWarning)continue;let r=new Set([e.panelId]),i=[];for(let e of t)e.kind===`edit`&&e.sourcePanelId&&r.has(e.sourcePanelId)&&(r.add(e.panelId),i.push(e.panelId));for(let e of i){let n=t.find(t=>t.panelId===e);t=t.map(t=>t.panelId===e?{...t,needsRefresh:!0,provenance:n?.provenance||`auto`}:t)}}return{rows:t}}return{edit:t(e)}},\"stillmade-internal.panel-delete@1.0.0\":function(e){function t(e){return e}function n(e,t){let n=[];for(let t of e||[]){n.push(t);for(let e of t.revert?.rows||[])n.push(e)}let r=n.find(e=>e.kind===`base`&&e.lineageId===t.lineageId&&e.sceneId===t.sceneId&&String(e.prompt||``).trim());return r?r.prompt:String(t.prompt||``).replace(/^\\s*keep\\s+(everything\\s+)?identical\\s*;\\s*/i,``).trim()||`the scene`}function r(e){let t=e.length?Math.min(...e.map(e=>Number(e.startMs)||0)):0;return e.map(e=>{let n={...e,startMs:t};return t+=Math.max(1,Number(e.durationMs)||1),n})}function i(e,i){let a=e.strip.findIndex(e=>e.panelId===i);if(a<0)return e;let o=e.strip[a],s=o.overlayLayer&&typeof o.overlayLayer==`object`?o.overlayLayer:null,c=null;if(s)for(let t=a-1;t>=0;t--){let n=e.strip[t];if(n.type===`panel`&&n.sceneId===o.sceneId&&n.overlayLayer==null){c=n.panelId;break}}let l=o.kind===`edit`||o.type===`zoom`,u=new Set([i]);for(let t of e.strip)t.kind===`repeat`&&t.repeatOf===i&&u.add(t.panelId),t.type===`zoom`&&t.sourcePanelId===i&&!l&&u.add(t.panelId);let d=e.strip.filter(e=>!u.has(e.panelId)),f=o.type===`canvas`?d[Math.max(0,Math.min(a-1,d.length-1))]?.panelId??null:null,p=d.map(t=>c&&t.panelId===c?{...t,overlayLayer:s}:o.type===`zoom`&&t.panelId===o.sourcePanelId||o.type===`canvas`&&t.panelId===f?{...t,durationMs:Number(t.durationMs)+Number(o.durationMs)}:(t.kind===`edit`||t.type===`zoom`)&&t.sourcePanelId!=null&&u.has(t.sourcePanelId)?t.sourcePanelId===i&&l?{...t,sourcePanelId:o.sourcePanelId,needsRefresh:!0}:t.type===`zoom`?t:{...t,kind:`base`,sourcePanelId:null,prompt:n(e.strip,t),needsRefresh:!0}:t);if(!p.length)throw Error(`deletePanel: a strip needs at least one panel`);return t({...e,strip:r(p)})}return{edit:{schemaVersion:1,strip:i(e.document,e.panelId).strip}}},\"stillmade-internal.edited-panel-image@1.0.0\":function(e){function t(e,t){let n=new Set([t]),r=[];for(let t of e||[])t.kind===`edit`&&t.sourcePanelId&&n.has(t.sourcePanelId)&&(n.add(t.panelId),r.push(t.panelId));return r}function n(e){return e.versions?.length?e.versions:e.image?[e.image]:[]}function r(e,t){return[...n(e).filter(e=>e!==t),t].slice(-8)}function i(e,t,n){let r=e.strip.map(e=>e.panelId===t?{...e,...n,provenance:n.provenance||`user`}:e);return a({...e,strip:r})}let a=e=>e,o=e.doc.strip.find(t=>t.panelId===e.panelId),s=i(e.doc,e.panelId,{image:e.image,versions:r(o,e.image)}),c=new Set(t(s.strip,e.panelId));return{edit:c.size?{...s,strip:s.strip.map(e=>c.has(e.panelId)?{...e,needsRefresh:!0}:e)}:s}},\"stillmade-internal.gif-cache-acceptance@1.0.0\":function(e){function t(e){let t=[];for(let n of e?.strip||[]){n?.type===`giphy`&&String(n.gif||``).trim()&&t.push({url:n.gif,term:n.gifQuery||``});let e=n?.overlayLayer;e&&typeof e==`object`&&String(e.gifUrl||``).trim()&&t.push({url:e.gifUrl,term:e.gifQuery||``})}return t}function n(e,t){let n=!1,r=e.strip.map(e=>{let r=e;e?.type===`giphy`&&t.has(e.gif)&&(r={...r,gif:t.get(e.gif)});let i=r?.overlayLayer;return i&&typeof i==`object`&&t.has(i.gifUrl)&&(r={...r,overlayLayer:{...i,gifUrl:t.get(i.gifUrl)}}),r!==e&&(n=!0),r});return n?{...e,strip:r}:e}return{edit:e.action===`collect`?t(e.doc):n(e.doc,new Map(e.remap))}},\"stillmade-internal.panel-gif-choice@1.0.0\":function(e){let t=[`replace`,`overlay`];function n(e){return e}function r(e,t,n){let r=e.strip.find(e=>e.panelId===t);if(!r)throw Error(`${n}: unknown panel \"${t}\"`);if(r.type!==`giphy`)throw Error(`${n}: ${t} is not a giphy panel`);return r}function i(e,i,a){if(!t.includes(a))throw Error(`setGifMode: mode must be ${t.join(`|`)}`);if(r(e,i,`setGifMode`).mode===a)return e;let o=e.strip.map(e=>e.panelId===i?{...e,mode:a,provenance:`user`}:e);return n({...e,strip:o})}function a(e,t,i){let a=r(e,t,`setPanelGif`),o=String(i||``).trim();if(!o)throw Error(`setPanelGif: a gif url is required`);if(a.gif===o)return e;let s=e.strip.map(e=>e.panelId===t?{...e,gif:o,provenance:`user`}:e);return n({...e,strip:s})}function o(e,t,n){r(e,t,`swapGif`);let i=String(n||``).trim();if(!i)throw Error(`swapGif: a candidate url is required`);return a(e,t,i)}if(![`mode`,`candidate`].includes(e.action))throw Error(`Unknown GIF action`);let s=e.action===`mode`?i(e.document,e.panelId,e.value):o(e.document,e.panelId,e.value);return{edit:{schemaVersion:1,changed:s!==e.document,strip:s.strip}}},\"stillmade-internal.gif-search-edit@1.0.0\":function(e){function t(e,t,r){let i=e.strip.map(e=>e.panelId===t?{...e,...r,provenance:r.provenance||`user`}:e);return n({...e,strip:i})}let n=e=>e,r=e.doc.strip[0],i;return i=e.action===`remove`?{overlayLayer:null}:e.action===`overlay`?{overlayLayer:{...r.overlayLayer||{mode:`overlay`},gifUrl:e.results[0],gifQuery:e.query}}:{gif:e.results[0],gifQuery:e.query,candidates:e.results.slice(0,6)},{edit:t(e.doc,r.panelId,i)}},\"stillmade-internal.panel-insert@1.0.0\":function(e){function t(e){return e}function n(e,t,n){for(let r=Math.min(n,e.length)-1;r>=0;r--)if(e[r].lineageId===t&&e[r].kind!==`repeat`&&e[r].kind!==`revealStep`)return e[r];return null}function r(e,r,{kind:i=`edit`,prompt:s=``,lineageId:c=null,durationMs:l=1200}={}){let u=e.strip.findIndex(e=>e.panelId===r);if(u<0)return e;let d=e.strip[u],f=c||d.lineageId,p=a(e.strip),m=i===`edit`?n([...e.strip.slice(0,u+1)],f,u+1)?.panelId??null:null,h={panelId:p,type:`panel`,sceneId:d.sceneId,lineageId:f,kind:i===`edit`&&m?`edit`:`base`,prompt:s||(i===`edit`?`keep everything identical; `:``),sourcePanelId:i===`edit`&&m?m:null,image:null,startMs:d.startMs+d.durationMs,durationMs:Math.max(350,l),transitionIn:`cut`,overlayLayer:null,provenance:`user`,method:null,methodGroup:null},g=[...e.strip.slice(0,u+1),h,...e.strip.slice(u+1)],_=e.lineages[f]?e.lineages:{...e.lineages,[f]:{sheetIds:[],place:``}};return t({...e,lineages:_,strip:o(g)})}function i(e){let t=new Set;for(let n of e||[]){t.add(n.panelId);for(let e of n.revert?.rows||[])t.add(e.panelId)}return t}function a(e){let t=i(e),n=e.length+1;for(;t.has(`p${n}`);)n++;return`p${n}`}function o(e){let t=e.length?Math.min(...e.map(e=>Number(e.startMs)||0)):0;return e.map(e=>{let n={...e,startMs:t};return t+=Math.max(1,Number(e.durationMs)||1),n})}let s=r(e.document,e.afterId,{});return{edit:{schemaVersion:1,strip:s.strip,lineages:s.lineages}}},\"stillmade-internal.panel-insert-zoom@1.0.0\":function(e){function t(e){return e}function n(e){let t=new Set;for(let n of e||[]){t.add(n.panelId);for(let e of n.revert?.rows||[])t.add(e.panelId)}return t}function r(e,r){let i=e.strip.findIndex(e=>e.panelId===r),a=e.strip[i];if(!a||a.type!==`panel`)throw Error(`insertZoomAfter: zooms push into generative panels`);let o=Math.max(600,Math.min(Number(a.durationMs)/2,1500));if(Number(a.durationMs)-o<350)throw Error(`insertZoomAfter: the beat is too short to carve a zoom out of`);let s=n(e.strip),c=e.strip.filter(e=>e.type===`zoom`).length+1;for(;s.has(`${a.panelId}z${c}`);)c++;let l=`${a.panelId}z${c}`,u={panelId:l,type:`zoom`,sceneId:a.sceneId,lineageId:a.lineageId,sourcePanelId:a.panelId,zoom:null,image:null,startMs:Number(a.startMs)+Number(a.durationMs)-o,durationMs:o,transitionIn:`cut`,provenance:`user`},d=!1,f=e.strip.flatMap(e=>e.panelId===a.panelId?[{...e,durationMs:Number(e.durationMs)-o},u]:!d&&e.kind===`edit`&&e.sourcePanelId===a.panelId&&e.sceneId===a.sceneId?(d=!0,[{...e,sourcePanelId:l,needsRefresh:!0}]):[e]);return t({...e,strip:f})}return{edit:{schemaVersion:1,strip:r(e.document,e.panelId).strip}}},\"stillmade-internal.panel-lineage@1.0.0\":function(e){function t(e){return e}let n=[`Same scene, same moment, same characters, same art style; REDRAW this as a tight close-up on the single most important subject or detail in the frame — a genuinely different, much closer composition, not a slight zoom.`,`Same scene, same moment, same characters, same art style; REDRAW this from a clearly different camera angle — shifted to the side or over a shoulder — same staging, visibly re-framed.`,`Same scene, same moment, same characters, same art style; REDRAW this as a wider shot pulled back to reveal more of the surroundings — same staging, clearly different framing.`];function r(e=1){return n[(Math.max(1,e|0)-1)%n.length]}function i(e,n,r){if(!e.lineages[n])throw Error(`setLineagePersistent: unknown lineage \"${n}\"`);let i={...e.lineages,[n]:{...e.lineages[n],persistent:!!r}};return t({...e,lineages:i})}function a(e,n,i=r(1)){let a=e.strip.find(e=>e.panelId===n);if(!a)throw Error(`convertRepeatToEdit: unknown panel \"${n}\"`);if(a.kind!==`repeat`)throw Error(`convertRepeatToEdit: ${n} is not a repeat`);let o=e.strip.map(e=>{if(e.panelId!==n)return e;let{repeatOf:t,...r}=e;return{...r,kind:`edit`,sourcePanelId:t,prompt:String(i),image:null,needsRefresh:!1,provenance:`user`}});return t({...e,strip:o})}if(![`persistent`,`convert`].includes(e.action))throw Error(`Unknown action`);let o=e.action===`persistent`?i(e.document,e.id,e.persistent):a(e.document,e.id);return{edit:{schemaVersion:1,strip:o.strip,lineages:o.lineages}}},\"stillmade-internal.panel-move-gif@1.0.0\":function(e){function t(e){return e}function n(e,t,n){let r=e.strip.find(e=>e.panelId===t);if(!r)throw Error(`${n}: unknown panel \"${t}\"`);if(r.type!==`giphy`)throw Error(`${n}: ${t} is not a giphy panel`);return r}function r(e){let t=e.length?Math.min(...e.map(e=>Number(e.startMs)||0)):0;return e.map(e=>{let n={...e,startMs:t};return t+=Math.max(1,Number(e.durationMs)||1),n})}function i(e,n,i){let a=e.strip.findIndex(e=>e.panelId===n),o=a+(i<0?-1:1);if(a<0||o<0||o>=e.strip.length)return e;let s=[...e.strip];return[s[a],s[o]]=[s[o],s[a]],t({...e,strip:r(s)})}function a(e,t,r){return n(e,t,`moveGif`),i(e,t,r)}let o=a(e.document,e.panelId,e.direction);return{edit:{schemaVersion:1,changed:o!==e.document,strip:o.strip}}},\"stillmade-internal.panel-narration@1.0.0\":function(e){let{panel:t,words:n,text:r}=e.edit,i=String(r||``).trim().split(/\\s+/).filter(Boolean);if(!i.length)throw Error(`narration text is empty`);let a=t.startMs,o=t.startMs+t.durationMs,s=e=>{let t=(e.startMs+e.endMs)/2;return t>=a&&t<o},c=a,l=o,u,d=0,f=n.findIndex(s);if(f>=0){let e=f;for(;e+1<n.length&&s(n[e+1]);)e++;c=n[f].startMs,l=n[e].endMs,u=f,d=e-f+1}else u=n.findIndex(e=>(e.startMs+e.endMs)/2>=o),u<0&&(u=n.length);let p=(l-c)/i.length,m=i.map((e,t)=>({text:e,startMs:Math.round(c+t*p),endMs:Math.round(c+(t+1)*p)}));return{splice:{schemaVersion:1,insertAt:u,removeCount:d,words:m}}},\"stillmade-internal.panel-animation-edit@1.0.0\":function(e){function t(e,n){if(n?.type===`giphy`)return n.gif??n.image??null;if(n?.type===`zoom`){if(n.image)return n.image;let r=(e||[]).find(e=>e.panelId===n.sourcePanelId);return r?t(e,r):null}return n?.kind===`repeat`?(e||[]).find(e=>e.panelId===n.repeatOf)?.image??null:n?.image??null}function n(e,n){let r=e.strip.findIndex(e=>e.panelId===n);if(r<0||r+1>=e.strip.length)return!1;let i=e.strip[r],a=e.strip[r+1],o=n=>n.type===`panel`&&!!t(e.strip,n);return o(i)&&o(a)&&i.sceneId===a.sceneId}function r(e,t,r){if(r!=null&&!n(e,t))throw Error(`setPanelAnimation: no animatable gap after ${t}`);let i=e.strip.map(e=>e.panelId===t?{...e,animateNext:r??null}:e).map(e=>{if(e.panelId!==t||e.animateNext!=null)return e;let{animateNext:n,...r}=e;return r});return a({...e,strip:i})}function i(e,t,n){let r=e.strip.map(e=>e.panelId===t?{...e,...n,provenance:n.provenance||`user`}:e);return a({...e,strip:r})}let a=e=>e,o=e.doc.strip.find(t=>t.panelId===e.panelId);return{edit:e.action===`playback`?i(e.doc,e.panelId,{animateNext:{...o.animateNext,...e.value}}):r(e.doc,e.panelId,e.action===`remove`?null:e.value)}},\"stillmade-internal.panel-batch-result@1.0.0\":function(e){function t(e){let t=new Map(e.results);return{rows:e.rows.map(e=>t.has(e.panelId)?{...e,image:t.get(e.panelId),versions:[...(e.versions?.length?e.versions:e.image?[e.image]:[]).filter(n=>n!==t.get(e.panelId)),t.get(e.panelId)].slice(-8),needsRefresh:!1,styleWarning:null,styleStrict:!1}:e),meta:{...e.meta,...e.anchorPanelId?{anchorPanelId:e.anchorPanelId}:{},...Object.keys(e.sheets).length?{castRefs:{...e.meta.castRefs||{},...e.sheets}}:{}}}}return{edit:t(e)}},\"stillmade-internal.panel-document-settings@1.1.0\":function(e){function t(e){if(e.kind===`aspect`)return{meta:{...e.meta,aspect:e.value}};if(e.kind===`quality`)return{meta:{...e.meta,qaConsistency:e.value}};if(e.kind===`type`)return{projectType:e.value.type,projectTypeNote:e.value.note};throw Error(`Unsupported panel document setting`)}return{edit:t(e)}},\"stillmade-internal.panel-prompt-edit@1.0.0\":function(e){function t(e,t,r){let i=e.strip.map(e=>e.panelId===t?{...e,...r,provenance:r.provenance||`user`}:e);return n({...e,strip:i})}let n=e=>e,r=e.doc.strip[0],i;if(e.action===`method`)i={method:e.value};else if(e.action===`prompt`)i=r.promptOverride?{prompt:e.value,promptOverride:``}:{prompt:e.value};else if(e.action===`send`)i={promptOverride:``};else if(e.action===`override`)i={promptOverride:e.value};else if(e.action===`reset`)i={promptOverride:``,refBlocklist:[]};else{let t=Array.isArray(r.refBlocklist)?r.refBlocklist:[];if(t.includes(e.value))return{edit:e.doc};i={refBlocklist:[...t,e.value]}}return{edit:t(e.doc,r.panelId,i)}},\"stillmade-internal.plan-assembly@1.0.0\":function(e){let t=new Set([`cycle`,`accumulation`,`reveal`,`expressionSequence`,`zoomProgression`,`poseProgression`,`comparison`,`moodShift`,`insertCutaway`,`matchSwap`,`progressiveReveal`]);function n(e){return e===`cycle`?1500:2500}let r=[`Same scene, same moment, same characters, same art style; REDRAW this as a tight close-up on the single most important subject or detail in the frame — a genuinely different, much closer composition, not a slight zoom.`,`Same scene, same moment, same characters, same art style; REDRAW this from a clearly different camera angle — shifted to the side or over a shoulder — same staging, visibly re-framed.`,`Same scene, same moment, same characters, same art style; REDRAW this as a wider shot pulled back to reveal more of the surroundings — same staging, clearly different framing.`];function i(e=1){return r[(Math.max(1,e|0)-1)%r.length]}let a=[`story`,`explainer`],o=[`story`,`explainer`,`both`,`neither`],s=[`replace`,`overlay`];function c(e){return Array.isArray(e)?e.filter(e=>typeof e==`string`&&e):typeof e==`string`&&e?[e]:[]}function l(e){let t=e.length?Math.min(...e.map(e=>Number(e.startMs)||0)):0;return e.map(e=>{let n={...e,startMs:t};return t+=Math.max(1,Number(e.durationMs)||1),n})}function u(e,t,{leadMs:r=75}={}){let a=(Array.isArray(t)?t:[]).map(e=>({startMs:Math.round(Number(e.startMs??e.start*1e3)||0),endMs:Math.round(Number(e.endMs??e.end*1e3)||0)}));if(!a.length)throw Error(`assignStripTiming: no words`);let o=(e||[]).filter(e=>e&&typeof e==`object`),s=(e,t=0)=>Math.max(t,Math.min(Number(e)||0,a.length-1)),c=[];for(let e=0;e<o.length;e++){let t=Math.max(0,a[s(o[e].wordStart)].startMs-r);e>0&&(t=Math.max(t,c[e-1]+1)),c.push(t)}let l=[];for(let e=0;e<o.length;e++){let t=o[e],r=s(t.wordStart),u=s(t.wordEnd,r),d=l.length?l[l.length-1].startMs+l[l.length-1].durationMs:c[0],f=e+1<o.length?c[e+1]:Math.max(a[u].endMs,c[e]+1),p=Math.max(f,d+1)-d,m=t.type===`titleScreen`,h=t.type===`giphy`,g=t.type===`canvas`,_=t.kind===`base`&&t.method===`progressiveReveal`;if(l.length&&p<350&&!m&&!h&&!g&&!_&&l[l.length-1].type!==`titleScreen`&&l[l.length-1].type!==`giphy`&&l[l.length-1].type!==`canvas`){l[l.length-1].durationMs+=p,l[l.length-1].absorbed=(l[l.length-1].absorbed||0)+1;continue}let v=m||g?1/0:n(t.method);if(p>v){let e=Math.ceil(p/v),n=Math.floor(p/e),r=d,a=t.panelId;for(let o=0;o<e;o++){let s=o===e-1?d+p-r:n;if(o===0)l.push({...t,startMs:r,durationMs:s});else if(t.type===`giphy`)l.push({...t,panelId:`${t.panelId}h${o}`,startMs:r,durationMs:s});else if(t.type===`diagram`)l.push({...t,panelId:`${t.panelId}h${o}`,startMs:r,durationMs:s});else if(t.kind===`revealStep`||t.kind===`base`&&t.method===`progressiveReveal`)l.push({...t,panelId:`${t.panelId}h${o}`,kind:`repeat`,repeatOf:t.panelId,scene:null,revealOf:void 0,revealIndex:void 0,startMs:r,durationMs:s});else{let e=`${t.panelId}c${o}`;l.push({...t,panelId:e,kind:`edit`,repeatOf:null,scene:null,changePrompt:i(o),sourcePanelId:a,startMs:r,durationMs:s}),a=e}r+=s}continue}l.push({...t,startMs:d,durationMs:p})}return l}let d=/arrow|line|connector|pointer|divider|underline|dash|tick|dot/i;function f(e,t){let r=new Map((t||[]).filter(e=>e.renderer===`diagram`).map(e=>[e.sceneId,e.elements||{}]));if(!r.size)return e;let i=e.map(e=>({...e})),a=new Map;for(let e=0;e<i.length;e++){let t=i[e];if(t.type!==`diagram`)continue;let o=r.get(t.sceneId);if(!o)continue;let s=a.get(t.sceneId)||new Set,c=(t.visibleElements||[]).filter(e=>!s.has(e));if(a.set(t.sceneId,new Set(t.visibleElements||[])),!c.length||!c.every(e=>d.test(e)||d.test(o[e]?.prompt||``))||t.provenance===`user`||t.durationMs<=300)continue;let l=t.durationMs-300;t.durationMs=300;for(let r=e+1;r<i.length&&l>0;r++){let e=i[r];if(e.type===`titleScreen`||e.sceneId!==t.sceneId)break;let a=e.provenance===`user`?1/0:n(e.method),o=Math.min(Math.max(0,a-e.durationMs),l);e.durationMs+=o,l-=o}l>0&&(t.durationMs+=l)}return l(i)}function p({plan:e,words:r,title:l=``,aspect:d=`16:9`,styleRef:p=null,styleRefs:h=null,voPath:g=null}={}){let _=c(h).length?c(h):c(p);if(!e||!Array.isArray(e.strip)||!e.strip.length)throw Error(`assemblePanelDoc: plan has no strip`);let v=u(e.strip,r),y=new Set(v.map(e=>e.panelId)),b=new Map,x=new Map,S={...e.lineages||{}},C=v.map(e=>{if(e.type===`titleScreen`)return{panelId:e.panelId,type:`titleScreen`,sceneId:e.sceneId,startMs:e.startMs,durationMs:e.durationMs,provenance:`auto`};if(e.type===`canvas`)return{panelId:e.panelId,type:`canvas`,sceneId:e.sceneId,background:typeof e.background==`string`?e.background:`#ffffff`,autoArrange:e.autoArrange!==!1,planned:!0,elements:Array.isArray(e.elements)?e.elements:[],...e.mode===`typewriter`?{mode:`typewriter`}:{},...Array.isArray(e.events)&&e.events.length?{events:e.events}:{},...e.hint?{hint:String(e.hint).slice(0,200)}:{},...e.template?{template:String(e.template)}:{},startMs:e.startMs,durationMs:e.durationMs,transitionIn:e.transitionIn===`fade`?`fade`:`cut`,provenance:`auto`,...Number.isFinite(Number(e.wordStart))?{wordStart:e.wordStart,wordEnd:e.wordEnd}:{}};if(e.type===`giphy`)return{panelId:e.panelId,type:`giphy`,sceneId:e.sceneId,mode:s.includes(e.mode)?e.mode:`replace`,gif:String(e.gif||``),...e.gifQuery?{gifQuery:String(e.gifQuery)}:{},...Array.isArray(e.candidates)&&e.candidates.length?{candidates:e.candidates.map(String)}:{},...e.tone?{tone:String(e.tone)}:{},startMs:e.startMs,durationMs:e.durationMs,transitionIn:e.transitionIn===`fade`?`fade`:`cut`,provenance:`auto`};if(e.type===`diagram`)return{panelId:e.panelId,type:`diagram`,sceneId:e.sceneId,visibleElements:Array.isArray(e.visibleElements)?e.visibleElements.map(String):[],...Array.isArray(e.textOverlays)&&e.textOverlays.length?{textOverlays:e.textOverlays}:{},...String(e.sfx||``).trim()?{sfx:String(e.sfx).trim()}:{},...e.layout&&typeof e.layout==`object`?{layout:e.layout}:{},image:null,startMs:e.startMs,durationMs:e.durationMs,transitionIn:e.transitionIn===`fade`?`fade`:`cut`,provenance:`auto`,method:t.has(e.method)?e.method:null,methodGroup:e.methodGroup==null?null:String(e.methodGroup)};let n=!!S[e.lineageId]?.persistent,r=`${e.sceneId??`s1`}:${e.lineageId}`;if(e.type===`zoom`){let t=e.sourcePanelId;if((!t||!y.has(t))&&(t=b.get(r)||(n?x.get(e.lineageId):null)||null),!t)return null;let i={panelId:e.panelId,type:`zoom`,sceneId:e.sceneId,lineageId:e.lineageId,sourcePanelId:t,zoom:null,image:null,startMs:e.startMs,durationMs:e.durationMs,transitionIn:`cut`,provenance:`auto`,...Number.isFinite(Number(e.wordStart))?{wordStart:e.wordStart,wordEnd:e.wordEnd}:{}};return b.set(r,e.panelId),x.set(e.lineageId,e.panelId),i}if(e.kind===`repeat`)return{panelId:e.panelId,type:`panel`,sceneId:e.sceneId,lineageId:e.lineageId,kind:`repeat`,repeatOf:e.repeatOf,prompt:``,sourcePanelId:null,image:null,startMs:e.startMs,durationMs:e.durationMs,transitionIn:`cut`,overlayLayer:null,provenance:`auto`,method:e.method??null,methodGroup:e.methodGroup??null,...Array.isArray(e.textOverlays)&&e.textOverlays.length?{textOverlays:e.textOverlays}:{},...String(e.sfx||``).trim()?{sfx:String(e.sfx).trim()}:{}};if(e.kind===`revealStep`)return{panelId:e.panelId,type:`panel`,sceneId:e.sceneId,lineageId:e.lineageId,kind:`revealStep`,revealOf:e.revealOf,revealIndex:Math.max(0,Number(e.revealIndex)||0),prompt:``,sourcePanelId:null,image:null,startMs:e.startMs,durationMs:e.durationMs,transitionIn:`cut`,overlayLayer:null,provenance:`auto`,method:null,methodGroup:e.methodGroup==null?null:String(e.methodGroup),...Array.isArray(e.textOverlays)&&e.textOverlays.length?{textOverlays:e.textOverlays}:{},...String(e.sfx||``).trim()?{sfx:String(e.sfx).trim()}:{}};let a=e.kind===`edit`?e.sourcePanelId:null;e.kind===`edit`&&(!a||!y.has(a))&&(a=b.get(r)||(n?x.get(e.lineageId):null)||null);let o=a==null&&e.kind===`edit`?`base`:e.kind,c={panelId:e.panelId,type:`panel`,sceneId:e.sceneId,lineageId:e.lineageId,kind:o,prompt:o===`base`?String(e.scene||e.prompt||``):String(e.changePrompt||e.prompt||``).trim()||i(1),sourcePanelId:o===`base`?null:a,image:null,startMs:e.startMs,durationMs:e.durationMs,transitionIn:e.transitionIn===`fade`?`fade`:`cut`,overlayLayer:null,provenance:`auto`,method:t.has(e.method)?e.method:null,methodGroup:e.methodGroup==null?null:String(e.methodGroup),...Array.isArray(e.textOverlays)&&e.textOverlays.length?{textOverlays:e.textOverlays}:{},...String(e.sfx||``).trim()?{sfx:String(e.sfx).trim()}:{},...Array.isArray(e.cast)?{cast:e.cast.map(String)}:{}};return b.set(r,e.panelId),x.set(e.lineageId,e.panelId),c}).filter(Boolean);for(let e of C)e.type===`panel`&&!S[e.lineageId]&&(S[e.lineageId]={sheetIds:[],place:``});let w=Array.isArray(e.scenes)&&e.scenes.length>0?e.scenes.map(e=>({sceneId:String(e.sceneId),title:String(e.title||``),genre:a.includes(e.genre)?e.genre:null,styleBlock:e.styleBlock?String(e.styleBlock):null,styleRef:e.styleRef||null,...c(e.styleRefs).length?{styleRefs:c(e.styleRefs)}:{},sheets:{...e.sheets||{}},titleScreen:e.titleScreen&&typeof e.titleScreen==`object`?{...e.titleScreen}:null,...e.renderer===`diagram`?{renderer:`diagram`,canvas:e.canvas&&typeof e.canvas==`object`?{...e.canvas}:{},elements:Object.fromEntries(Object.entries(e.elements||{}).map(([e,t])=>[e,{prompt:String(t?.prompt||``),asset:t?.asset||null,pos:{x:Number(t?.pos?.x)||.5,y:Number(t?.pos?.y)||.5},scale:Number.isFinite(Number(t?.scale))?Number(t.scale):1}]))}:{}})):null,T=w?f(C,w):C,E=o.includes(e.projectType)?e.projectType:null,D={mode:`imagePanel`,...E?{projectType:E}:{},...e.projectTypeNote?{projectTypeNote:String(e.projectTypeNote).slice(0,500)}:{},meta:{title:l,aspect:d,styleRef:_[0]??null,..._.length?{styleRefs:_}:{},...e.sfxAuthored?{sfxAuthored:!0}:{}},audio:{voPath:g,words:(r||[]).map(e=>({text:String(e.text??e.word??``),startMs:Math.round(Number(e.startMs??e.start*1e3)||0),endMs:Math.round(Number(e.endMs??e.end*1e3)||0)}))},styleBlock:String(e.styleBlock||``),sheets:{...e.sheets||{}},lineages:S,...w?{scenes:w}:{},strip:T},O=m(D);for(let e of O.strip)if(!(e.type!==`panel`&&e.type!==`diagram`||e.provenance===`user`)&&e.durationMs>n(e.method))throw Error(`assemblePanelDoc: ${e.panelId} is ${e.durationMs}ms — over the system ceiling`);return O}let m=e=>e;return{edit:p(e)}},\"stillmade-internal.plan-finalization@1.0.0\":function(e){function t({aspect:e=`16:9`,styleNotes:t=``,styleText:n}={}){return`${n}${t?` ${String(t).trim()}`:``} ${e} framing.`}function n(e,t,n){return{...e,strip:e.strip.map(e=>e.panelId===t?{...e,...n,provenance:n.provenance||`user`}:e)}}let r=e.doc;if(e.kind===`style`){let n=e.style;r={...r,styleBlock:t({aspect:e.aspect,styleText:n.text}),meta:{...r.meta,styleRef:n.refs?.[0]??null,...n.refs?.length?{styleRefs:[...n.refs]}:{},styleRefsHidden:!!n.builtin},scenes:(r.scenes||[]).map(e=>({...e,styleBlock:null}))}}else for(let t=0;t<e.overlays.length;t++){let{targetPanelId:i,overlay:a}=e.overlays[t];e.allowed[t]&&r.strip.some(e=>e.panelId===i&&e.type===`panel`)&&(r=n(r,i,{overlayLayer:a}))}return{edit:r}},\"stillmade-internal.planned-canvas@1.0.0\":function(e){let t=(e,t,n,r,i,a,o,s)=>({id:e,name:t,scenario:n,minImages:r,slots:i,textSlots:a,pSlots:o,pTextSlots:s}),n=[t(`hero-headline`,`Hero + headline`,`one subject, one line`,1,[{x:.5,y:.58,w:.5,h:.62}],[{role:`headline`,x:.5,y:.14,size:.09,weight:900}],[{x:.5,y:.55,w:.78,h:.5}],[{role:`headline`,x:.5,y:.13,size:.055,weight:900}]),t(`hero-supporting`,`Hero + 2 supporting`,`main subject with two details`,3,[{x:.34,y:.55,w:.42,h:.58},{x:.78,y:.33,w:.28,h:.32},{x:.78,y:.73,w:.28,h:.32}],[{role:`headline`,x:.34,y:.13,size:.08,weight:900}],[{x:.5,y:.38,w:.78,h:.32},{x:.28,y:.72,w:.4,h:.2},{x:.72,y:.72,w:.4,h:.2}],[{role:`headline`,x:.5,y:.12,size:.05,weight:900}]),t(`compare-2`,`Side-by-side compare`,`A vs B`,2,[{x:.27,y:.5,w:.38,h:.5},{x:.73,y:.5,w:.38,h:.5}],[{role:`headline`,x:.5,y:.12,size:.08,weight:900},{role:`label`,x:.27,y:.84,size:.05,weight:800},{role:`label`,x:.73,y:.84,size:.05,weight:800}],[{x:.5,y:.35,w:.72,h:.24},{x:.5,y:.72,w:.72,h:.24}],[{role:`headline`,x:.5,y:.11,size:.05,weight:900},{role:`label`,x:.5,y:.51,size:.032,weight:800},{role:`label`,x:.5,y:.88,size:.032,weight:800}]),t(`three-across`,`Three across`,`three items`,3,[{x:.2,y:.5,w:.26,h:.46},{x:.5,y:.5,w:.26,h:.46},{x:.8,y:.5,w:.26,h:.46}],[{role:`headline`,x:.5,y:.13,size:.08,weight:900},{role:`caption`,x:.5,y:.86,size:.045,weight:600}],[{x:.5,y:.32,w:.64,h:.2},{x:.5,y:.57,w:.64,h:.2},{x:.5,y:.82,w:.64,h:.2}],[{role:`headline`,x:.5,y:.1,size:.05,weight:900},{role:`caption`,x:.5,y:.96,size:.028,weight:600}]),t(`grid-2x2`,`Grid of four`,`four items`,4,[{x:.3,y:.36,w:.32,h:.34},{x:.7,y:.36,w:.32,h:.34},{x:.3,y:.74,w:.32,h:.34},{x:.7,y:.74,w:.32,h:.34}],[{role:`headline`,x:.5,y:.09,size:.07,weight:900}],[{x:.28,y:.38,w:.4,h:.24},{x:.72,y:.38,w:.4,h:.24},{x:.28,y:.68,w:.4,h:.24},{x:.72,y:.68,w:.4,h:.24}],[{role:`headline`,x:.5,y:.12,size:.05,weight:900}]),t(`grid-3x3`,`Many small (3x3)`,`lots of items`,6,[.22,.5,.78].flatMap(e=>[.3,.56,.82].map(t=>({x:e,y:t,w:.24,h:.22}))),[{role:`headline`,x:.5,y:.08,size:.065,weight:900}],[.2,.5,.8].flatMap(e=>[.34,.58,.82].map(t=>({x:e,y:t,w:.27,h:.18}))),[{role:`headline`,x:.5,y:.1,size:.045,weight:900}]),t(`big-left-stack-right`,`Big lead + stack`,`one lead, several follow-ups`,3,[{x:.32,y:.54,w:.5,h:.62},{x:.79,y:.3,w:.3,h:.22},{x:.79,y:.56,w:.3,h:.22},{x:.79,y:.82,w:.3,h:.22}],[{role:`headline`,x:.32,y:.13,size:.075,weight:900}],[{x:.5,y:.4,w:.84,h:.34},{x:.2,y:.74,w:.26,h:.16},{x:.5,y:.74,w:.26,h:.16},{x:.8,y:.74,w:.26,h:.16}],[{role:`headline`,x:.5,y:.12,size:.05,weight:900}]),t(`vertical-stack`,`Vertical stack`,`ordered top to bottom`,2,[{x:.55,y:.29,w:.36,h:.22},{x:.55,y:.55,w:.36,h:.22},{x:.55,y:.81,w:.36,h:.22}],[{role:`headline`,x:.55,y:.08,size:.065,weight:900},{role:`label`,x:.16,y:.55,size:.055,weight:800}],[{x:.5,y:.3,w:.66,h:.2},{x:.5,y:.56,w:.66,h:.2},{x:.5,y:.82,w:.66,h:.2}],[{role:`headline`,x:.5,y:.09,size:.05,weight:900},{role:`label`,x:.24,y:.17,size:.032,weight:800}]),t(`scatter`,`Scattered collage`,`loose, hand-thrown feel`,3,[{x:.26,y:.36,w:.28,h:.32,tilt:-6},{x:.68,y:.3,w:.26,h:.3,tilt:4},{x:.44,y:.66,w:.27,h:.31,tilt:3},{x:.8,y:.62,w:.25,h:.29,tilt:-5},{x:.58,y:.46,w:.24,h:.28,tilt:2}],[{role:`headline`,x:.5,y:.1,size:.075,weight:900}],[{x:.32,y:.3,w:.46,h:.2,tilt:-6},{x:.7,y:.26,w:.42,h:.18,tilt:4},{x:.4,y:.56,w:.44,h:.2,tilt:3},{x:.74,y:.6,w:.4,h:.18,tilt:-5},{x:.5,y:.82,w:.44,h:.19,tilt:2}],[{role:`headline`,x:.5,y:.09,size:.045,weight:900}]),t(`timeline-row`,`Row / timeline`,`steps in order`,3,[{x:.14,y:.52,w:.2,h:.38},{x:.38,y:.52,w:.2,h:.38},{x:.62,y:.52,w:.2,h:.38},{x:.86,y:.52,w:.2,h:.38}],[{role:`headline`,x:.5,y:.15,size:.075,weight:900},{role:`caption`,x:.5,y:.85,size:.045,weight:600}],[{x:.35,y:.28,w:.5,h:.15},{x:.65,y:.47,w:.5,h:.15},{x:.35,y:.66,w:.5,h:.15},{x:.65,y:.85,w:.5,h:.15}],[{role:`headline`,x:.5,y:.12,size:.05,weight:900}]),t(`center-satellites`,`Center + satellites`,`one core idea, orbiting parts`,3,[{x:.5,y:.52,w:.34,h:.42},{x:.17,y:.3,w:.2,h:.26},{x:.83,y:.3,w:.2,h:.26},{x:.17,y:.77,w:.2,h:.26},{x:.83,y:.77,w:.2,h:.26}],[{role:`headline`,x:.5,y:.09,size:.065,weight:900}],[{x:.5,y:.52,w:.56,h:.28},{x:.2,y:.28,w:.32,h:.16},{x:.8,y:.28,w:.32,h:.16},{x:.2,y:.78,w:.32,h:.16},{x:.8,y:.78,w:.32,h:.16}],[{role:`headline`,x:.5,y:.1,size:.045,weight:900}]),t(`corner-big-text`,`Corner images, big text`,`statement first, proof beside it`,2,[{x:.72,y:.4,w:.32,h:.38},{x:.52,y:.72,w:.28,h:.34},{x:.85,y:.76,w:.24,h:.3}],[{role:`headline`,x:.26,y:.26,size:.105,weight:900},{role:`label`,x:.26,y:.42,size:.05,weight:600}],[{x:.36,y:.56,w:.5,h:.22},{x:.7,y:.7,w:.44,h:.2},{x:.4,y:.84,w:.4,h:.18}],[{role:`headline`,x:.5,y:.19,size:.065,weight:900},{role:`label`,x:.5,y:.31,size:.034,weight:600}]),t(`title-top-row`,`Title top, images below`,`title screen with evidence`,2,[{x:.22,y:.62,w:.28,h:.44},{x:.5,y:.62,w:.28,h:.44},{x:.78,y:.62,w:.28,h:.44}],[{role:`headline`,x:.5,y:.17,size:.1,weight:900}],[{x:.5,y:.4,w:.7,h:.2},{x:.5,y:.64,w:.7,h:.2},{x:.5,y:.86,w:.7,h:.16}],[{role:`headline`,x:.5,y:.15,size:.06,weight:900}]),t(`large-caption`,`One large + caption`,`let the image speak`,1,[{x:.5,y:.47,w:.56,h:.6}],[{role:`label`,x:.15,y:.1,size:.045,weight:800},{role:`caption`,x:.5,y:.85,size:.055,weight:600}],[{x:.5,y:.47,w:.82,h:.44}],[{role:`label`,x:.24,y:.12,size:.032,weight:800},{role:`caption`,x:.5,y:.78,size:.034,weight:600}]),t(`staggered-diagonal`,`Staggered diagonal`,`progression with motion`,3,[{x:.18,y:.26,w:.24,h:.3,tilt:-3},{x:.42,y:.45,w:.24,h:.3,tilt:3},{x:.64,y:.62,w:.24,h:.3,tilt:-3},{x:.86,y:.79,w:.24,h:.3,tilt:3}],[{role:`headline`,x:.74,y:.16,size:.075,weight:900}],[{x:.28,y:.3,w:.42,h:.18,tilt:-3},{x:.62,y:.46,w:.42,h:.18,tilt:3},{x:.36,y:.62,w:.42,h:.18,tilt:-3},{x:.68,y:.78,w:.42,h:.18,tilt:3}],[{role:`headline`,x:.5,y:.12,size:.05,weight:900}]),t(`overlap-stack`,`Overlapping stack`,`a deliberate pile`,2,[{x:.42,y:.5,w:.36,h:.46,tilt:-5},{x:.54,y:.56,w:.36,h:.46,tilt:3},{x:.63,y:.46,w:.36,h:.46,tilt:-2}],[{role:`headline`,x:.5,y:.12,size:.08,weight:900},{role:`caption`,x:.5,y:.89,size:.045,weight:600}],[{x:.44,y:.42,w:.58,h:.26,tilt:-5},{x:.58,y:.53,w:.58,h:.26,tilt:3},{x:.46,y:.64,w:.58,h:.26,tilt:-2}],[{role:`headline`,x:.5,y:.12,size:.05,weight:900},{role:`caption`,x:.5,y:.86,size:.032,weight:600}]),t(`banner-row`,`Wide banner + small row`,`one wide scene, details under`,2,[{x:.5,y:.36,w:.84,h:.36},{x:.25,y:.77,w:.24,h:.26},{x:.5,y:.77,w:.24,h:.26},{x:.75,y:.77,w:.24,h:.26}],[{role:`headline`,x:.5,y:.09,size:.065,weight:900}],[{x:.5,y:.36,w:.86,h:.26},{x:.22,y:.66,w:.28,h:.16},{x:.5,y:.66,w:.28,h:.16},{x:.78,y:.66,w:.28,h:.16}],[{role:`headline`,x:.5,y:.13,size:.05,weight:900},{role:`caption`,x:.5,y:.82,size:.032,weight:600}]),t(`quadrant-labels`,`Quadrants with labels`,`four named things`,4,[{x:.28,y:.3,w:.3,h:.3},{x:.72,y:.3,w:.3,h:.3},{x:.28,y:.71,w:.3,h:.3},{x:.72,y:.71,w:.3,h:.3}],[{role:`headline`,x:.5,y:.07,size:.06,weight:900},{role:`label`,x:.28,y:.49,size:.042,weight:800},{role:`label`,x:.72,y:.49,size:.042,weight:800},{role:`label`,x:.28,y:.9,size:.042,weight:800},{role:`label`,x:.72,y:.9,size:.042,weight:800}],[{x:.28,y:.32,w:.38,h:.2},{x:.72,y:.32,w:.38,h:.2},{x:.28,y:.64,w:.38,h:.2},{x:.72,y:.64,w:.38,h:.2}],[{role:`headline`,x:.5,y:.1,size:.045,weight:900},{role:`label`,x:.28,y:.45,size:.028,weight:800},{role:`label`,x:.72,y:.45,size:.028,weight:800},{role:`label`,x:.28,y:.77,size:.028,weight:800},{role:`label`,x:.72,y:.77,size:.028,weight:800}]),t(`pyramid-3`,`Pyramid of three`,`one above two`,3,[{x:.5,y:.32,w:.3,h:.32},{x:.32,y:.71,w:.3,h:.32},{x:.68,y:.71,w:.3,h:.32}],[{role:`headline`,x:.5,y:.08,size:.065,weight:900},{role:`caption`,x:.5,y:.92,size:.04,weight:600}],[{x:.5,y:.34,w:.5,h:.22},{x:.27,y:.62,w:.42,h:.18},{x:.73,y:.62,w:.42,h:.18}],[{role:`headline`,x:.5,y:.1,size:.05,weight:900},{role:`caption`,x:.5,y:.79,size:.032,weight:600}]),t(`mosaic-dense`,`Dense mosaic`,`everything at once`,5,[{x:.3,y:.4,w:.34,h:.42},{x:.62,y:.29,w:.24,h:.26},{x:.86,y:.33,w:.2,h:.28},{x:.19,y:.78,w:.24,h:.26},{x:.47,y:.77,w:.26,h:.28},{x:.73,y:.73,w:.22,h:.24},{x:.91,y:.76,w:.14,h:.18}],[{role:`headline`,x:.5,y:.09,size:.06,weight:900}],[{x:.32,y:.3,w:.5,h:.2},{x:.78,y:.26,w:.36,h:.16},{x:.24,y:.52,w:.4,h:.16},{x:.68,y:.5,w:.44,h:.18},{x:.3,y:.74,w:.42,h:.16},{x:.74,y:.73,w:.4,h:.16},{x:.5,y:.89,w:.5,h:.1}],[{role:`headline`,x:.5,y:.1,size:.045,weight:900}])],r=new Map(n.map(e=>[e.id,e])),i=e=>r.get(e)||null;function a(e,t=16/9){return e?t<1?{slots:e.pSlots,textSlots:e.pTextSlots}:{slots:e.slots,textSlots:e.textSlots}:null}function o(e,t,{aspect:n=16/9}={}){if(!t)return(e||[]).map(e=>{if(e.pinned||e.kind!==`image`||!e.box)return e;let{box:t,...n}=e;return n});let r=a(t,n),i=(e,t)=>(e.appearMs||0)-(t.appearMs||0),o=(e||[]).filter(e=>e.kind===`image`&&!e.pinned).sort(i),s=(e||[]).filter(e=>e.kind===`text`&&!e.pinned).sort(i),c=new Map;o.forEach((e,t)=>{t<r.slots.length&&c.set(e.id,r.slots[t])});let l=new Map;return s.forEach((e,t)=>{t<r.textSlots.length&&l.set(e.id,r.textSlots[t])}),(e||[]).map(e=>{if(e.pinned)return e;if(e.kind===`image`){let t=c.get(e.id);if(!t){let{box:t,...n}=e;return{...n,pos:null}}return{...e,pos:{x:t.x,y:t.y},box:{w:t.w,h:t.h},size:t.w,tilt:t.tilt||0}}let t=l.get(e.id);return t?{...e,pos:{x:t.x,y:t.y},size:t.size,weight:t.weight||e.weight||800}:e})}function s({imageCount:e=0,textCount:t=0,hint:n=``}={}){if(!e)return null;let r=String(n||``).toLowerCase();return e===2&&/\\bvs\\b|versus|compar|before.*after|either/.test(r)?`compare-2`:e>=3&&/step|order|sequence|timeline|process|journey|stages/.test(r)?`timeline-row`:e>=3&&/list|lists|enumerat|items|examples|types|kinds/.test(r)?e>=5?`mosaic-dense`:`three-across`:e===1?t>1?`large-caption`:`hero-headline`:e===2?`compare-2`:e===3?`three-across`:e===4?`grid-2x2`:e===5?`center-satellites`:e<=7?`mosaic-dense`:`grid-3x3`}let c=e=>{let t=5381,n=String(e||``);for(let e=0;e<n.length;e++)t=(t<<5)+t+n.charCodeAt(e)>>>0;return t},l=(e,t)=>c(`${e}|${t}`)%2e3/1e3-1;function u(e,t=16/9){let n=.08+.4*Math.sqrt((e+.5)/48),r=e*2.399963229728653;return{x:.5+n*Math.cos(r),y:.5+n*Math.sin(r)*(t>1?.9:1.1)}}let d=(e,t,n)=>Math.max(t,Math.min(n,e));function f(e,{aspect:t=16/9}={}){let n=(e?.elements||[]).slice().sort((e,t)=>(e.appearMs||0)-(t.appearMs||0)),r=[],i=new Map;for(let a of n){let n=(a.kind===`image`?a.size||.28:.18)/2;if(a.pinned||!e.autoArrange){a.pos&&(r.push({...a.pos,size:a.size||.28,appearMs:a.appearMs,leaveMs:a.leaveMs}),i.set(a.id,a.pos));continue}let o=r.filter(e=>e.leaveMs==null||e.leaveMs>a.appearMs),s=null,f=-1/0;for(let e=0;e<48;e++){let r=u((e+c(a.id)%48)%48,t),i=d(r.x,n+.03,1-n-.03),l=d(r.y,n+.05,1-n-.05),p=1/0;for(let e of o)p=Math.min(p,Math.hypot(i-e.x,l-e.y)-(e.size||.28)/2-n);let m=-.12*Math.hypot(i-.5,l-.5),h=(o.length?Math.min(p,.5):.3)+m;h>f&&(f=h,s={x:i,y:l})}let p=s||{x:.5,y:.5};p.x=d(p.x+l(a.id,`x`)*.015,n,1-n),p.y=d(p.y+l(a.id,`y`)*.015,n,1-n),r.push({...p,size:a.size||.28,appearMs:a.appearMs,leaveMs:a.leaveMs}),i.set(a.id,p)}return i}function p(e,t){if(!e.autoArrange)return e;let n=f(e,t);return{...e,elements:(e.elements||[]).map(e=>!e.pinned&&n.has(e.id)?{...e,pos:n.get(e.id)}:e)}}function m(e){let t=e?.meta?.aspect||`16:9`;return t===`9:16`?9/16:t===`1:1`?1:16/9}function h(e,t){let n=i(t.template);if(n){let r=o(t.elements||[],n,{aspect:m(e)}),i=f({...t,autoArrange:!0,elements:r.map(e=>e.pos?{...e,pinned:!0}:e)},{aspect:m(e)});return{...t,elements:r.map(e=>!e.pinned&&!e.pos&&i.has(e.id)?{...e,pos:i.get(e.id)}:e)}}return t.autoArrange?p(t,{aspect:m(e)}):t}function g(e,t){let n=Array.isArray(t)?t:[],r=e=>{let t=n[Math.max(0,Math.min(Math.round(Number(e)||0),n.length-1))];return t?Math.round(Number(t.startMs??t.start*1e3)||0):NaN},i=!1,a=e.strip.map(t=>{if(t.type!==`canvas`)return t;if(t.mode===`typewriter`&&!(Array.isArray(t.elements)&&t.elements.length)){let e=v(n,{wordStart:t.wordStart,wordEnd:t.wordEnd,panelStartMs:t.startMs,panelDurationMs:t.durationMs});return e.length?(i=!0,{...t,autoArrange:!1,elements:e}):t}if(!Array.isArray(t.events)||!t.events.length)return t;i=!0;let{events:a,...o}=t,c=_(a,{panelStartMs:t.startMs,panelDurationMs:t.durationMs,wordStartMs:r}),l=s({imageCount:c.filter(e=>e.kind===`image`).length,textCount:c.filter(e=>e.kind===`text`).length,hint:t.hint||``});return h(e,{...o,...l?{template:l}:{},elements:c})});return i?b({...e,strip:a}):e}function _(e,{panelStartMs:t,panelDurationMs:n,wordStartMs:r,leadMs:i=75}={}){let a=[],o=0;for(let s of e||[]){let e=r(s.at??s.wordStart);if(!Number.isFinite(e))continue;let c=d(e-i-t,0,Math.max(0,n-200)),u=`ce${++o}`;s.kind===`text`?a.push({id:u,kind:`text`,text:String(s.text||``).slice(0,80),appearMs:c,leaveMs:null,pos:null,size:s.emphasis===`primary`?.085:.06,font:`Hanken Grotesk`,color:`#111111`,weight:800,anim:{type:`pop`,perWord:!1,speedMs:180},sfx:`auto`,pinned:!1}):a.push({id:u,kind:`image`,src:null,query:String(s.query||``).slice(0,120),source:`stock`,appearMs:c,leaveMs:null,pos:null,size:s.emphasis===`primary`?.46:.28,tilt:Math.round(l(u,`tilt`)*6),entrance:`pop`,sfx:`auto`,pinned:!1})}return a}function v(e,{wordStart:t,wordEnd:n,panelStartMs:r=0,panelDurationMs:i=0,leadMs:a=60,size:o=.06,maxCharsPerLine:s=30,maxWordsPerLine:c=6}={}){let l=Array.isArray(e)?e:[];if(!l.length)return[];let u=Math.max(0,Math.min(Math.round(Number(t)||0),l.length-1)),f=Math.max(u,Math.min(Math.round(Number(n)||u),l.length-1)),p=[];for(let e=u;e<=f;e++){let t=l[e],n=String(t?.text??t?.word??``).trim();if(!n)continue;let o=Math.round(Number(t?.startMs??t?.start*1e3)||0),s=d(o-a-r,0,Math.max(0,i-150));p.push({text:n,rel:s})}return y(p,{size:o,maxCharsPerLine:s,maxWordsPerLine:c})}function y(e,{size:t=.06,maxCharsPerLine:n=30,maxWordsPerLine:r=6}={}){let i=(Array.isArray(e)?e:[]).map(e=>({text:String(e?.text??``).trim(),rel:Math.max(0,Math.round(Number(e?.rel)||0))})).filter(e=>e.text);if(!i.length)return[];let a=[],o=[],s=0;for(let e of i){let t=e.text.length+ +!!o.length;o.length&&(s+t>n||o.length>=r)&&(a.push(o),o=[],s=0),o.push(e),s+=t}o.length&&a.push(o);let c=t*1.4,l=.5-a.length*c/2+c/2;return a.map((e,n)=>({id:`tw${n+1}`,kind:`text`,text:e.map(e=>e.text).join(` `),appearMs:e[0].rel,leaveMs:null,pos:{x:.5,y:d(l+n*c,.04,.96)},size:t,font:`Hanken Grotesk`,color:`#111111`,weight:800,wordTimes:e.map(e=>e.rel),anim:{type:`typewriter`,perWord:!1,speedMs:45},sfx:`auto`,pinned:!0}))}let b=e=>JSON.parse(JSON.stringify(e));return{edit:g(e.doc,e.words)}},\"stillmade-internal.planning-beat-merge@1.0.0\":function(e){function t(e,t){let n=Array.isArray(e)?e.slice():[],r=[];if(!Array.isArray(t)||!t.length)return{strip:n,overlays:r};let i=new Set(n.map(e=>String(e?.panelId||``))),a=0,o=()=>{let e;do e=`gif${++a}`;while(i.has(e));return i.add(e),e};for(let e of t){if(!e||typeof e!=`object`)continue;let t=Math.max(0,Math.round(Number(e.wordStart)||0)),i=Math.max(t,Math.round(Number(e.wordEnd)||t)),a=String(e.gifUrl||``).trim();if(e.mode===`overlay`){let n=String(e.targetPanelId||``).trim();if(!n||!a)continue;r.push({targetPanelId:n,overlay:{gifUrl:a,mode:`overlay`,...e.gifQuery?{gifQuery:String(e.gifQuery)}:{},wordStart:t,wordEnd:i}});continue}if(!a)continue;let s=0;for(let e=0;e<n.length;e++)(Number(n[e]?.wordStart)||0)<=t&&(s=e);let c=n[s];c&&n.splice(s+1,0,{panelId:o(),type:`giphy`,sceneId:c.sceneId,mode:`replace`,gif:a,...e.gifQuery?{gifQuery:String(e.gifQuery)}:{},...Array.isArray(e.candidates)&&e.candidates.length?{candidates:e.candidates.map(e=>String(e?.gifUrl||e||``)).filter(Boolean)}:{},...e.tone?{tone:String(e.tone)}:{},wordStart:t,wordEnd:i,transitionIn:`cut`})}return{strip:n,overlays:r}}function n(e,t){let n=Array.isArray(e)?e.slice():[];if(!Array.isArray(t)||!t.length)return{strip:n};let r=new Set(n.map(e=>String(e?.panelId||``))),i=0,a=()=>{let e;do e=`cv${++i}`;while(r.has(e));return r.add(e),e};for(let e of t){let t=e&&e.mode===`typewriter`;if(!e||typeof e!=`object`||!t&&(!Array.isArray(e.events)||!e.events.length))continue;let r=Math.max(0,Math.round(Number(e.wordStart)||0)),i=Math.max(r,Math.round(Number(e.wordEnd)||r)),o=e=>(Number(e.wordStart)||0)>=r&&(Number(e.wordEnd)||0)<=i,s=(e,t)=>!e||e.type===`titleScreen`||e.type===`canvas`||e.kind===`revealStep`||e.method===`progressiveReveal`||!o(e)?!1:!n.some((n,r)=>r!==t&&!o(n)&&(n.repeatOf===e.panelId||n.revealOf===e.panelId)),c=n.map((e,t)=>s(e,t)?t:-1).filter(e=>e>=0),l=c.length?c[0]:0;if(!c.length)for(let e=0;e<n.length;e++)(Number(n[e]?.wordStart)||0)<=r&&(l=e+1);let u=n[Math.min(Math.max(0,l-+!c.length),n.length-1)],d={panelId:a(),type:`canvas`,sceneId:u?.sceneId,background:`#ffffff`,autoArrange:!t,planned:!0,elements:[],...t?{mode:`typewriter`}:{events:e.events},...e.reason?{hint:String(e.reason).slice(0,200)}:{},wordStart:r,wordEnd:i,transitionIn:`cut`};for(let e=c.length-1;e>=0;e--)n.splice(c[e],1);n.splice(Math.min(l,n.length),0,d)}return{strip:n}}return{edit:e.action===`gif`?t(e.strip,e.beats):n(e.strip,e.beats)}},\"stillmade-internal.panel-reveal-edit@1.0.0\":function(e){function t(e){let t=(Array.isArray(e?.elements)?e.elements:[]).filter(e=>e&&e.id&&e.box).map(e=>({id:String(e.id).slice(0,40),name:String(e.name||e.id).slice(0,120),box:{x:Math.max(0,Math.round(Number(e.box.x)||0)),y:Math.max(0,Math.round(Number(e.box.y)||0)),w:Math.max(1,Math.round(Number(e.box.w)||1)),h:Math.max(1,Math.round(Number(e.box.h)||1))},alwaysVisible:e.alwaysVisible===!0})),n=new Set(t.map(e=>e.id)),r=(Array.isArray(e?.order)?e.order:[]).map(e=>String(e)).filter(e=>n.has(e));for(let e of t)!r.includes(e.id)&&!e.alwaysVisible&&r.push(e.id);return{bg:Array.isArray(e?.bg)&&e.bg.length===3?e.bg.map(e=>Math.max(0,Math.min(255,Math.round(Number(e)||0)))):[0,0,0],elements:t,order:r}}let n=t(e.plan),{action:r,id:i,patch:a,direction:o}=e;if(r===`clear`)return{edit:{cleared:!0}};if(r===`patch`)n={...n,elements:n.elements.map(e=>e.id===i?{...e,...a,box:{...e.box,...a.box||{}}}:e)};else if(r===`move`){let e=n.order.indexOf(i),t=e+o;if(e>=0&&t>=0&&t<n.order.length){let r=[...n.order];[r[e],r[t]]=[r[t],r[e]],n={...n,order:r}}}else if(r===`remove`)n={...n,elements:n.elements.filter(e=>e.id!==i),order:n.order.filter(e=>e!==i)};else if(r===`merge`){let e=n.order.indexOf(i),t=n.elements.find(t=>t.id===n.order[e-1]),r=n.elements.find(e=>e.id===i);if(e>0&&t&&r){let e=Math.min(t.box.x,r.box.x),a=Math.min(t.box.y,r.box.y),o={x:e,y:a,w:Math.max(t.box.x+t.box.w,r.box.x+r.box.w)-e,h:Math.max(t.box.y+t.box.h,r.box.y+r.box.h)-a};n={...n,elements:n.elements.filter(e=>e.id!==i).map(e=>e.id===t.id?{...e,box:o}:e),order:n.order.filter(e=>e!==i)}}}else throw Error(`Unknown reveal operation`);return{edit:{cleared:!1,plan:t(n)}}},\"stillmade-internal.reveal-frames@1.0.0\":function(e){function t(e){let t=(Array.isArray(e?.elements)?e.elements:[]).filter(e=>e&&e.id&&e.box).map(e=>({id:String(e.id).slice(0,40),name:String(e.name||e.id).slice(0,120),box:{x:Math.max(0,Math.round(Number(e.box.x)||0)),y:Math.max(0,Math.round(Number(e.box.y)||0)),w:Math.max(1,Math.round(Number(e.box.w)||1)),h:Math.max(1,Math.round(Number(e.box.h)||1))},alwaysVisible:e.alwaysVisible===!0})),n=new Set(t.map(e=>e.id)),r=(Array.isArray(e?.order)?e.order:[]).map(e=>String(e)).filter(e=>n.has(e));for(let e of t)!r.includes(e.id)&&!e.alwaysVisible&&r.push(e.id);return{bg:Array.isArray(e?.bg)&&e.bg.length===3?e.bg.map(e=>Math.max(0,Math.min(255,Math.round(Number(e)||0)))):[0,0,0],elements:t,order:r}}function n(e,t,n,{alwaysVisible:r=[]}={}){let i=new Set([...t.slice(0,Math.max(0,n)),...r]);return e.filter(e=>!i.has(e.id)).map(e=>e.box)}function r(e,t,n){let r=Math.max(1,t+1);return Math.min(n,Math.max(1,Math.ceil((e+1)*n/r)))}let i=new Set([`the`,`a`,`an`,`to`,`of`,`and`,`or`,`in`,`on`,`for`,`with`,`into`]);function a(e,t,n){let r=new Map((Array.isArray(e)?e:[]).map(e=>[e.id,e])),a=(Array.isArray(t)?t:[]).filter(e=>r.has(e)),o=String(n||``).toLowerCase();if(!o)return a.slice();let s=e=>{let t=String(r.get(e)?.name||``).toLowerCase(),n=-1,a=t.trim();if(a){let e=o.indexOf(a);e!==-1&&(n=e)}for(let e of t.split(/[^a-z0-9]+/)){if(e.length<3||i.has(e))continue;let t=o.indexOf(e);t!==-1&&(n===-1||t<n)&&(n=t)}return n};return a.map((e,t)=>({id:e,at:s(e),i:t})).sort((e,t)=>e.at>=0&&t.at>=0?e.at-t.at||e.i-t.i:e.at>=0?-1:t.at>=0?1:e.i-t.i).map(e=>e.id)}function o(e){let i=e.plan?t(e.plan):null;if(!i||!i.elements.length){let n=new Map((e.named?.elements||[]).map(e=>[e.id,e.name]));i=t({bg:e.bg,elements:e.detected.map(e=>({id:e.id,name:n.get(e.id)||e.id,box:e.box})),order:Array.isArray(e.named?.order)&&e.named.order.length?e.named.order:e.detected.map(e=>e.id)}),i={...i,order:a(i.elements,i.order,e.narration)}}let o=i.elements.filter(e=>!e.alwaysVisible).length,s=i.elements.filter(e=>e.alwaysVisible).map(e=>e.id),c=Array.from({length:e.stepCount},(t,a)=>n(i.elements,i.order,r(a,e.stepCount,o),{alwaysVisible:s}));return{plan:i,frames:c}}return{sequence:o(e)}},\"stillmade-internal.panel-revert-canvas@1.0.0\":function(e){function t(e){return e}function n(e,t){let n=[];for(let t of e||[]){n.push(t);for(let e of t.revert?.rows||[])n.push(e)}let r=n.find(e=>e.kind===`base`&&e.lineageId===t.lineageId&&e.sceneId===t.sceneId&&String(e.prompt||``).trim());return r?r.prompt:String(t.prompt||``).replace(/^\\s*keep\\s+(everything\\s+)?identical\\s*;\\s*/i,``).trim()||`the scene`}function r(e){let t=e.length?Math.min(...e.map(e=>Number(e.startMs)||0)):0;return e.map(e=>{let n={...e,startMs:t};return t+=Math.max(1,Number(e.durationMs)||1),n})}function i(e,i){let a=e.strip.find(e=>e.panelId===i);if(!a||a.type!==`canvas`)throw Error(`revertCanvas: ${i} is not a canvas panel`);let o=a.revert?.rows;if(!Array.isArray(o)||!o.length)throw Error(`revertCanvas: this canvas has no panels to restore`);let s=new Map((a.revert.repointed||[]).map(e=>[e.panelId,e])),c=Number(a.startMs)-Number(o[0].startMs),l=e.strip.flatMap(e=>{if(e.panelId===i)return o.map(e=>({...e,startMs:Number(e.startMs)+c}));let t=s.get(e.panelId);if(!t)return[e];let n=(e.image??null)!==(t.image??null),r={...e,sourcePanelId:t.sourcePanelId,needsRefresh:!!t.needsRefresh||n};return t.sourcePanelId&&(r.kind=`edit`),r.needsRefresh||delete r.needsRefresh,[r]}),u=new Set(l.map(e=>e.panelId)),d=l.map((t,r)=>{let i=l.slice(0,r),a=e=>[...i].reverse().find(t=>t.lineageId===e.lineageId&&t.sceneId===e.sceneId&&(t.type===`panel`||t.type===`zoom`)&&t.kind!==`repeat`);if((t.kind===`edit`||t.type===`zoom`)&&t.sourcePanelId&&!u.has(t.sourcePanelId)){let r=a(t);return r?{...t,sourcePanelId:r.panelId,needsRefresh:!0}:{...t,kind:`base`,sourcePanelId:null,prompt:n(e.strip,t),needsRefresh:!0}}if(t.kind===`repeat`&&t.repeatOf&&!u.has(t.repeatOf)){let r=a(t);return r?{...t,kind:`repeat`,repeatOf:r.panelId}:{...t,kind:`base`,repeatOf:null,prompt:n(e.strip,t),needsRefresh:!0}}if(t.kind===`revealStep`&&t.revealOf&&!u.has(t.revealOf)){let r=a(t);return r?{...t,kind:`edit`,revealOf:void 0,revealIndex:void 0,sourcePanelId:r.panelId,needsRefresh:!0}:{...t,kind:`base`,revealOf:void 0,revealIndex:void 0,sourcePanelId:null,prompt:n(e.strip,t),needsRefresh:!0}}return t});return t({...e,strip:r(d)})}return{edit:{schemaVersion:1,strip:i(e.document,e.panelId).strip}}},\"stillmade-internal.scene-edit@1.0.0\":function(e){function t(e,t,r){let i=(e.scenes||[]).map(e=>e.sceneId===t?{...e,...r}:e);return n({...e,scenes:i})}let n=e=>e;return{edit:t(e.doc,e.sceneId,e.patch)}},\"stillmade-internal.panel-version@1.0.0\":function(e){function t(e){return e}function n(e){return e.versions?.length?e.versions:e.image?[e.image]:[]}function r(e,t){let n=new Set([t]),r=[];for(let t of e||[])t.kind===`edit`&&t.sourcePanelId&&n.has(t.sourcePanelId)&&(n.add(t.panelId),r.push(t.panelId));return r}function i(e,i,a){let o=e.strip.find(e=>e.panelId===i);if(!o)throw Error(`setPanelVersion: unknown panel \"${i}\"`);let s=n(o);if(a<0||a>=s.length)throw Error(`setPanelVersion: version ${a+1} of ${s.length} doesn't exist`);let c=s[a];if(c===o.image)return e;let l=new Set(r(e.strip,i)),u=e.strip.map(e=>e.panelId===i?{...e,image:c,versions:s,needsRefresh:!1}:l.has(e.panelId)?{...e,needsRefresh:!0}:e);return t({...e,strip:u})}let a=i(e.document,e.panelId,e.index);return{edit:{schemaVersion:1,changed:a!==e.document,strip:a.strip}}},\"stillmade-internal.single-regeneration@1.0.0\":function(e){function t(e){let t=new Map(e.results),n=e.rows.map(e=>t.has(e.panelId)?{...e,image:t.get(e.panelId),versions:[...(e.versions?.length?e.versions:e.image?[e.image]:[]).filter(n=>n!==t.get(e.panelId)),t.get(e.panelId)].slice(-8),needsRefresh:!1,styleWarning:null,styleStrict:!1}:e),r=new Set([e.panelId]),i=[];for(let e of n)e.kind===`edit`&&e.sourcePanelId&&r.has(e.sourcePanelId)&&(r.add(e.panelId),i.push(e.panelId));let a=n.map(t=>i.includes(t.panelId)?{...t,needsRefresh:!0,provenance:e.rows.find(e=>e.panelId===t.panelId)?.provenance||`auto`}:t);return e.anchorPanelId===e.panelId&&(a=a.map(t=>t.panelId===e.panelId||t.kind!==`base`||!t.image||[`titleScreen`,`giphy`,`diagram`].includes(t.type)||!t.docStyle?t:(i.includes(t.panelId)||i.push(t.panelId),{...t,needsRefresh:!0,provenance:t.provenance||`auto`}))),{rows:a,flagged:i,anchorPanelId:e.anchorPanelId}}return{edit:t(e)}},\"stillmade-internal.panel-style@1.0.0\":function(e){let t=[{text:`Stickman meme-comic animation style: simple stick-figure characters with thin black stick limbs and large round heads, exaggerated rage-comic facial expressions with bold black outlines (gritted bared teeth, wide beady or bloodshot eyes, heavy angry brows), flat cel-shaded color fills with soft directional shading, plain simple environments, thick consistent black outlines throughout, no photorealism.`}];function n({aspect:e=`16:9`,styleNotes:n=``,styleText:r=t[0].text}={}){return`${r}${n?` ${String(n).trim()}`:``} ${e} framing.`}if(e.mode===`clear`)return{edit:e.rows.map(e=>({...e,image:null,needsRefresh:!1}))};let r=e.refs;return{edit:{styleBlock:e.text?n({aspect:e.aspect,styleText:e.text}):e.oldStyle,styleRef:r[0]||null,styleRefs:r,styleRefsHidden:e.builtin}}},\"stillmade-internal.panel-text-overlay@1.0.0\":function(e){function t(e){return e}function n(e,n,r){if(!e.strip.find(e=>e.panelId===n))throw Error(`setPanelTextOverlays: unknown panel \"${n}\"`);let i=e.strip.map(e=>e.panelId===n?{...e,textOverlays:r}:e);return t({...e,strip:i})}function r(e,t,r,i){let a=e.strip.find(e=>e.panelId===t)?.textOverlays||[];if(!a[r])throw Error(`updateTextOverlay: ${t} has no overlay ${r}`);return n(e,t,a.map((e,t)=>t===r?{...e,...i,...i.pos?{pos:{...e.pos,...i.pos}}:{},...i.arrow?{arrow:{...e.arrow,...i.arrow,...i.arrow.to?{to:{...e.arrow?.to,...i.arrow.to}}:{}}}:{},placedBy:i.placedBy||`user`,editable:!0}:e))}let i={strip:[{panelId:`selected`,textOverlays:e.overlays}]},a;if(e.action===`update`)a=r(i,`selected`,e.index,e.patch);else{let t;if(e.action===`remove`)t=e.overlays.filter((t,n)=>n!==e.index);else if(e.action===`removeArrow`)t=e.overlays.map((t,n)=>n===e.index?(({arrow:e,...t})=>({...t,placedBy:`user`}))(t):t);else if(e.action===`add`)t=[...e.overlays,{text:`TEXT`,pos:{x:.5,y:.15},size:.05,placedBy:`user`,editable:!0}];else throw Error(`Unknown overlay action`);a=n(i,`selected`,t)}return{overlays:a.strip[0].textOverlays}},\"stillmade-internal.text-placement@1.0.0\":function(e){function t(e){return e===`large`?.13:e===`small`?.04:.07}function n(e,n){return{...e,pos:n.pos,size:e.size==null?e.role?t(e.role):n.size:e.size,...n.arrow?.to?{arrow:{...e.arrow,to:n.arrow.to}}:{},placedBy:`vision`,editable:!0}}function r(e){let r=new Map(e.indices.map((t,n)=>[t,e.placements[n]]).filter(([,e])=>e)),i=new Map(e.seen);return e.overlays.map((a,o)=>{if(e.mode===`batch`&&a.pos)return a;let s=r.get(o);if(s)return n(a,s);let c=e.mode===`batch`?i.get(a.text):null;return c?{...a,pos:c.pos,size:a.size==null?a.role?t(a.role):c.size:a.size,placedBy:`vision`,editable:!0}:a})}return{overlays:JSON.parse(JSON.stringify(r(e)))}},\"stillmade-internal.zoom-override@1.0.0\":function(e){function t(e){let t=e.rows.find(t=>t.panelId===e.panelId);if(!t||t.type!==`zoom`)throw Error(`Choose a current zoom panel.`);let n=new Set([e.panelId]),r=[];for(let t of e.rows)t.kind===`edit`&&t.sourcePanelId&&n.has(t.sourcePanelId)&&(n.add(t.panelId),r.push(t.panelId));if(e.mode===`stale`)return{downstream:r};let i={fx:Math.max(0,Math.min(100,Number(e.target.fx))),fy:Math.max(0,Math.min(100,Number(e.target.fy))),scale:Math.max(1.1,Math.min(3,Number(e.target.scale)||1.8)),pickedBy:`user`},a=Math.max(1.2,Math.min(3,Number(i.scale)||1.8)),o=Math.max(0,Math.min(100,Number(i.fx)||0))/100,s=Math.max(0,Math.min(100,Number(i.fy)||0))/100,c=1/a;return{zoom:i,rect:{x:o*(1-c),y:s*(1-c),w:c,h:c},downstream:r,immediate:e.rows.filter(t=>t.kind===`edit`&&t.sourcePanelId===e.panelId).map(e=>e.panelId)}}return{plan:t(e)}},\"stillmade-internal.panel-zoom-target@1.0.0\":function(e){function t(e){return e}function n(e,n,{fx:r,fy:i,scale:a,pickedBy:o=`user`}={}){let s=e.strip.find(e=>e.panelId===n);if(!s||s.type!==`zoom`)throw Error(`setZoomTarget: ${n} is not a zoom panel`);let c=new Set(e.strip.filter(e=>e.kind===`edit`&&e.sourcePanelId===n).map(e=>e.panelId)),l=e.strip.map(e=>e.panelId===n?{...e,zoom:{fx:Number(r),fy:Number(i),scale:Number(a)||s.zoom?.scale||1.8,pickedBy:o},image:null}:c.has(e.panelId)?{...e,needsRefresh:!0}:e);return t({...e,strip:l})}return{edit:{schemaVersion:1,strip:n(e.document,e.panelId,e.target).strip}}}});function wm({value:e,onChange:t,type:n,...r}){let[i,a]=(0,v.useState)(e),o=(0,v.useRef)({value:e,onChange:t}),s=(0,v.useRef)(e),c=(0,v.useRef)(String(e));o.current={value:e,onChange:t},(0,v.useEffect)(()=>{a(e),s.current=e,c.current=String(e)},[e]);let l=()=>{let e=o.current.value;a(e),s.current=e,c.current=String(e)},u=async()=>{let e=s.current;if(String(e)!==c.current){c.current=String(e);try{await o.current.onChange({target:{value:e}})||l()}catch{l()}}};return(0,D.jsx)(`input`,{...r,type:n,value:i,onChange:e=>{s.current=e.target.value,a(e.target.value)},onBlur:u,onPointerUp:()=>{(n===`range`||n===`color`)&&u()},onPointerCancel:l,onKeyDown:e=>{e.key===`Enter`&&(e.preventDefault(),u()),e.key===`Escape`&&(e.preventDefault(),l())},onKeyUp:e=>{n===`range`&&[`ArrowLeft`,`ArrowRight`,`ArrowUp`,`ArrowDown`,`Home`,`End`,`PageUp`,`PageDown`].includes(e.key)&&u()}})}let Tm=e=>async()=>{throw Error(`${e} is not available in this Block.`)};function Em({HelpHint:e=()=>null,CanvasCommitInput:t=wm,ui:n,toast:r,media:i,run:a,upload:o,generateImage:s,stockGrid:c=async()=>[],stockSelect:l=async()=>{throw Error(`Stock media is not part of this screen.`)},useIsMobileUI:u}){let d=async e=>{let t=i.refFor(e)?await i.load(e):e,n=/^data:([^;,]+)(;base64)?,(.*)$/s.exec(String(t||``));if(!n)throw Error(`This media can only be shown here, not read.`);let r=n[2]?atob(n[3]):decodeURIComponent(n[3]),a=new Uint8Array(r.length);for(let e=0;e<r.length;e++)a[e]=r.charCodeAt(e);return new Blob([a],{type:n[1]})};return{version:1,loadMediaBlob:d,loadMediaArrayBuffer:async e=>(await d(e)).arrayBuffer(),resolveDesktopMediaUrl:async e=>e,isMissing:()=>!1,runFinalEdit:Tm(`Final Edit`),runStructureEdit:Tm(`Structure edits`),runMotionGraphics:Tm(`Motion graphics`),transcribeAudio:Tm(`Transcription`),useTier:()=>`pro`,requestUpgrade:()=>{},upgradeReasons:{},planAllows:()=>!0,confirm:(e,t)=>n.confirm(e,t),alert:(e,t)=>n.alert(e,t),toast:r,HelpHint:e,CanvasCommitInput:t,downloadUrlLocally:Tm(`Downloading from this screen`),extensionFromUrl:e=>(/\\.([a-z0-9]{2,5})(?:\\?|#|$)/i.exec(String(e||``))?.[1]||``).toLowerCase(),safeDownloadName:e=>String(e||`download`).replace(/[^\\w.-]+/g,`-`).slice(0,120),proxiedMediaUrl:e=>e,uploadReferenceImage:e=>o(e),getAllAssets:()=>[],addAsset:()=>null,recordAssets:()=>{},tagAsset:()=>{},listProjects:async()=>[],loadProject:async()=>null,stockGrid:async(e,t)=>({results:await c(e,t)}),stockSelect:l,useIsMobileUI:u,desktopBridge:()=>null,authHeaders:()=>({}),useCanvas:()=>null,useCanvasWriteAccess:()=>!1,generateReference:async e=>s(e),fetchStyleOptions:async()=>[],fetchStyleFromUploads:Tm(`Style from uploads`),generateReferenceSheet:async e=>s(e),useReferenceExtraction:()=>(0,v.useMemo)(()=>({status:`idle`,extract:Tm(`Reference extraction`)}),[]),findExtractedViews:()=>[],addLibraryItem:(e,t)=>t,getLibraryItems:()=>[],useThumb:e=>e,cachedObjectUrlIfPresent:()=>null,runLlmText:Tm(`Free text generation`),presenterHost:Object.freeze({available:!1})}}let Dm=globalThis.StillMade,Om=up(Dm),{ui:km,toast:Am,DialogHost:jm}=pp({bridge:Dm}),Mm=yp(Dm),Nm={input:{},shared:{canEdit:!1,outputs:{},state:{},made:[]}},Pm=new Set,Fm=()=>{for(let e of Pm)e()};Dm.onInput(e=>{Nm.input=e,Fm()}),Dm.onShared(e=>{Nm.shared=e,Mm.remember(e?.made),Fm()});function Im(){let[,e]=(0,v.useState)(0);return(0,v.useEffect)(()=>{let t=()=>e(e=>e+1);return Pm.add(t),()=>Pm.delete(t)},[]),Nm}let Lm={doc:null},Rm=Promise.resolve(),zm=(e,t={})=>{let n=Rm.then(async()=>{let n=Lm.doc?Um([...Hm(Lm.doc)]):[],r=await Dm.run({make:e,...Lm.doc?{panels:{...Lm.doc,schemaVersion:Lm.doc.schemaVersion??1}}:{},...n.length?{pictures:n}:{},...t});return Mm.remember(r),r});return Rm=n.catch(()=>{}),n},Bm=e=>e===void 0?void 0:JSON.parse(JSON.stringify(e)),Vm=e=>Bm(e?.result);function Hm(e,t=new Set,n=0){if(n>16||!e||typeof e!=`object`)return t;for(let r of Array.isArray(e)?e:Object.values(e))typeof r==`string`?/^(https?:|\\/api\\/)/.test(r)&&t.add(r):Hm(r,t,n+1);return t}let Um=e=>(Array.isArray(e)?e:[e]).filter(Boolean).map(e=>Mm.refFor(e)).filter(Boolean),Wm=Am,Gm=e=>/^https:\\/\\/(media[0-9]?|i)\\.giphy\\.com\\//.test(String(e||``));function Km(e){let t=[];for(let n of Array.isArray(e?.strip)?e.strip:[])n?.type===`giphy`&&Gm(n.gif)&&t.push(n.gif),Gm(n?.overlayLayer?.gifUrl)&&t.push(n.overlayLayer.gifUrl);return[...new Set(t)]}function qm(e){return Km(e).length}async function Jm(e,{deps:t,shouldCancel:n,assertCurrent:r=()=>{}}={}){r();let i=t?.collectRefs?await t.collectRefs(e):Km(e).map(e=>({url:e}));r();let a=[...new Set(i.map(e=>e?.url).filter(Gm))];if(!a.length||n?.())return e;let{map:o={}}=Vm(await zm(`gif-save`,{request:{urls:a}}))||{};r();let s=new Map(Object.entries(o).filter(([e,t])=>a.includes(e)&&typeof t==`string`&&t));if(!s.size)return e;if(t?.applyRemap){let n=await t.applyRemap(e,s);return r(),n}let c=!1,l=e.strip.map(e=>{let t=e;e?.type===`giphy`&&s.has(e.gif)&&(t={...t,gif:s.get(e.gif)});let n=t?.overlayLayer;return n&&s.has(n.gifUrl)&&(t={...t,overlayLayer:{...n,gifUrl:s.get(n.gifUrl)}}),t!==e&&(c=!0),t});return c?{...e,strip:l}:e}let Ym=Object.freeze({version:1,useLiveEditor:Om,LiveEditorBadge:()=>null,useIsMobileUI:()=>globalThis.innerWidth<768,cacheStripGifs:Jm,pendingGifCacheCount:qm,ui:{...km,prompt:async(e,t=``)=>t,choose:async(e,t=[])=>t[0]?.value??null},toast:Wm}),Xm=Object.freeze({version:1,actor:()=>`frame`,async run(e,t){let n=Cm[`${e?.manifest?.id}@${e?.manifest?.version}`];if(!n)throw Error(`${e?.manifest?.name||`This edit`} is not part of this Block.`);if(t?.signal?.aborted)throw Object.assign(Error(`Cancelled`),{code:`CANCELLED`});return{outputs:Bm(n(Bm(t.input)))}}}),Zm=kp.filter(e=>!e.disabled).map(e=>({value:e.value,label:e.label,supports:Object.fromEntries(Object.entries(e.supports||{}).map(([e,t])=>[e,[...t]]))})),Qm=Object.freeze({version:1,imageModels:Zm,creditCosts:{...ym},imageCost:bm,videoCost:xm,formatCostLabel:Sm}),$m=new Map,eh={async read(e){return $m.has(e)||$m.set(e,zm(`storage-get`,{key:e}).then(Vm).catch(()=>null)),$m.get(e)},async write(e,t){$m.set(e,Promise.resolve(t)),await zm(`storage-set`,{key:e,value:t})}},th=null;eh.read(`panel-generation`).then(e=>{th=e});let nh=Object.freeze({version:1,defaultImageModel:()=>Zm[0]?.value||`nano-banana-2`,read:()=>th,write:e=>{th=e,eh.write(`panel-generation`,e).catch(()=>{})}}),rh=[];eh.read(`styles`).then(e=>{rh=Array.isArray(e)?e:[]});let ih=Object.freeze({version:1,list:()=>rh,save:e=>{let t={...e,id:e.id||`style-${crypto.randomUUID()}`,updatedAt:Date.now()};return rh=[t,...rh.filter(e=>e.id!==t.id)].slice(0,100),eh.write(`styles`,rh).catch(()=>{}),t}}),ah=e=>{let t=Vm(e);if(!t?.url)throw Error(`No picture came back. Try again.`);return{url:t.url,...t}},oh=async e=>ah(await zm(`image`,{request:{...e,referenceImages:void 0},references:Um(e.referenceImages||[])})),sh=async e=>{let t=await zm(`video`,{request:{...e,firstFrameUrl:void 0,lastFrameUrl:void 0},...e.firstFrameUrl?{firstFrame:Um(e.firstFrameUrl)[0]}:{},...e.lastFrameUrl?{lastFrame:Um(e.lastFrameUrl)[0]}:{}}),n=Vm(t);if(!n?.url)throw Error(`No clip came back. Try again.`);return{url:n.url,...n}},ch=async e=>{let t=Vm(await zm(`upload`,{dataUrl:e}));if(!t?.url)throw Error(`The picture could not be saved.`);return t.url},lh=new Map,uh=e=>`${e?.source}:${e?.id}`,dh=async(e,t)=>{let n=Vm(await zm(`stock-grid`,{request:{query:e,type:t}}))||[];for(let e of n)lh.set(uh(e),e);return n},fh=async e=>{let t=lh.get(uh(e));if(!t)throw Error(`Search again and pick this result.`);return Vm(await zm(`stock-select`,{request:{result:t}}))},ph=Object.freeze({version:1,generateImage:oh,notifyAccessDenied:()=>{}}),mh=Object.freeze({version:1,actor:()=>`frame`,imageCost:bm,videoCost:xm,stockStatus:async()=>Vm(await zm(`stock-status`)),stockGrid:e=>dh(e?.query,e?.type),stockSelect:e=>fh(e),upload:async e=>{let t=await new Promise((t,n)=>{let r=new FileReader;r.onload=()=>t(r.result),r.onerror=n,r.readAsDataURL(e)});return{url:await ch(t)}},generateImage:oh,generateVideo:sh}),hh=Object.freeze({version:1,planImagePanelStrip:async e=>Vm(await zm(`plan`,{request:e})),planGifBeats:async e=>Vm(await zm(`plan-gifs`,{request:e})),planCanvasBeats:async e=>Vm(await zm(`plan-canvas`,{request:e})),nameRevealElements:async e=>Vm(await zm(`name-elements`,{request:{...e,imageUrl:void 0},image:Um(e.imageUrl)[0]})),placePanelText:async e=>Vm(await zm(`place-text`,{request:{...e,imageUrl:void 0},image:Um(e.imageUrl)[0]})),stockAutoFind:async e=>Vm(await zm(`stock-auto`,{request:e})),checkStripConsistency:async e=>Vm(await zm(`consistency`,{request:{...e,anchorUrl:void 0,panels:e.panels?.map(({url:e,...t})=>t)},references:Um([e.anchorUrl,...(e.panels||[]).map(e=>e.url)])})),generateVideo:sh,uploadReferenceImage:e=>ch(e),searchGiphyGifs:async(e,t)=>Vm(await zm(`gif-search`,{request:{query:e,...t||{}}}))}),gh=Object.freeze({version:1,pickTarget:async e=>Vm(await zm(`zoom-target`,{request:{...e,imageUrl:void 0},image:Um(e.imageUrl)[0]}))}),_h=Object.freeze({version:1,crop:async(e,t)=>{let n=Vm(await zm(`crop`,{image:Um(e)[0],request:{rect:t}}));if(!n?.url)throw Error(`The crop could not be saved.`);return n.url}}),vh=Object.freeze({version:1,async prepareUpload(e){return{thumb:e,url:await ch(e)}},analyze:async e=>Vm(await zm(`style-analyze`,{references:Um(e)})),generate:async e=>(await oh(e)).url}),yh=Object.freeze({version:1,process:async(e,t)=>{if(t===`off`)return{map:new Map(e.map(e=>[e,e]))};let n=Vm(await zm(`process-images`,{request:{mode:t},references:Um(e)}))||{};return{map:new Map(Object.entries(n.map||{}))}}}),bh=Object.freeze({version:1,openCanvas:async()=>!0}),xh=Object.freeze({...Xm,confirm:(e,t)=>km.confirm(e,t),prompt:async(e,t=``)=>t}),Sh=Object.freeze({...Xm,methods:Object.freeze([...De])}),Ch=Object.freeze({version:1,async provision(e,{voiceover:t,assertCurrent:n=()=>{}}={}){if(!e?.meta?.host?.enabled)return e;let r=Vm(await zm(`presenter`,{panels:{...e,schemaVersion:e.schemaVersion??1},request:{voiceover:t||{}}}));return n(),r?.doc||e}}),wh={set:null},Th=null;ol({setDoc:e=>wh.set?.(e),scheduleSave:()=>{clearTimeout(Th),Th=setTimeout(()=>{zm(`use`).catch(()=>{})},4e3)},projectIdRef:{current:`block`},epochRef:{current:0}}),Is(Em({HelpHint:Js,CanvasCommitInput:ta,ui:km,toast:Wm,media:Mm,run:zm,upload:ch,generateImage:oh,stockGrid:dh,stockSelect:fh,useIsMobileUI:Ym.useIsMobileUI})),Ho(Ym);function Eh(){let{input:e,shared:t}=Im(),[n,r]=(0,v.useState)(null);wh.set=r;let[i,a]=(0,v.useState)(`16:9`);Lm.doc=n;let o=JSON.stringify([e.narrationTiming??null,e.narrationAudio??null,e.narrationScript??null]),s=(0,v.useMemo)(()=>sp({narrationTiming:e.narrationTiming,narrationAudio:e.narrationAudio,narrationScript:e.narrationScript},null),[o]),[c,l]=(0,v.useState)(!1);return(0,v.useEffect)(()=>{!c&&Object.keys(Nm.input).length+Object.keys(Nm.shared).length&&l(!0)},[e,t,c]),c?(0,D.jsxs)(D.Fragment,{children:[(0,D.jsx)(op,{panelAccessHost:bh,styleAuthoringHost:vh,panelImageProcessHost:yh,styleLibraryHost:ih,panelPreferencesHost:nh,generationCatalogHost:Qm,panelZoomHost:gh,presenterProvisionHost:Ch,panelCropHost:_h,mediaHost:mh,panelEditHost:Xm,panelPromptHost:Sh,panelSettingsHost:xh,panelWorkflowHost:hh,panelGenerationHost:ph,doc:n,onDocChange:e=>r(t=>typeof e==`function`?e(t):e),voiceover:s,aspect:i,onAspectChange:a,projectId:`block`,onContinueToEditor:async()=>{try{await zm(`use`)}catch(e){await km.alert(e.message||`The panels could not be saved.`,{title:`Not saved`})}},nextStepLabel:`Editor`}),(0,D.jsx)(jm,{})]}):null}(0,_.createRoot)(document.getElementById(`root`)).render((0,D.jsx)(Eh,{}))})();",
181
+ "runtime": "frame"
182
+ },
183
+ "tests": [
184
+ {
185
+ "name": "Makes a panel picture that keeps its reference",
186
+ "input": {
187
+ "make": "image",
188
+ "panels": {
189
+ "schemaVersion": 1,
190
+ "strip": [
191
+ {
192
+ "panelId": "panel1",
193
+ "kind": "base",
194
+ "prompt": "Sunlight falls across a mountain ridge.",
195
+ "image": "https://media.example/picture-1.png"
196
+ }
197
+ ]
198
+ },
199
+ "pictures": [
200
+ {
201
+ "kind": "image",
202
+ "assetId": "picture-1",
203
+ "versionId": "picture-1-v1",
204
+ "url": "https://media.example/picture-1.png",
205
+ "mimeType": "image/png",
206
+ "width": 1024,
207
+ "height": 1024,
208
+ "bytes": 200000
209
+ }
210
+ ],
211
+ "request": {
212
+ "model": "nano-banana-pro",
213
+ "readablePrompt": "The ridge at dusk",
214
+ "aspectRatio": "16:9"
215
+ },
216
+ "references": [
217
+ {
218
+ "kind": "image",
219
+ "assetId": "picture-1",
220
+ "versionId": "picture-1-v1",
221
+ "url": "https://media.example/picture-1.png",
222
+ "mimeType": "image/png",
223
+ "width": 1024,
224
+ "height": 1024,
225
+ "bytes": 200000
226
+ }
227
+ ]
228
+ },
229
+ "mocks": {
230
+ "hosted": {
231
+ "image.generate": {
232
+ "kind": "image",
233
+ "assetId": "picture-2",
234
+ "versionId": "picture-2-v1",
235
+ "url": "https://media.example/picture-2.png",
236
+ "mimeType": "image/png",
237
+ "width": 1024,
238
+ "height": 1024,
239
+ "bytes": 200000
240
+ }
241
+ }
242
+ },
243
+ "expected": {
244
+ "panels": {
245
+ "schemaVersion": 1,
246
+ "strip": [
247
+ {
248
+ "panelId": "panel1",
249
+ "kind": "base",
250
+ "prompt": "Sunlight falls across a mountain ridge.",
251
+ "image": "https://media.example/picture-1.png"
252
+ }
253
+ ]
254
+ },
255
+ "images": [
256
+ {
257
+ "kind": "image",
258
+ "assetId": "picture-1",
259
+ "versionId": "picture-1-v1",
260
+ "url": "https://media.example/picture-1.png",
261
+ "mimeType": "image/png",
262
+ "width": 1024,
263
+ "height": 1024,
264
+ "bytes": 200000
265
+ }
266
+ ],
267
+ "made": [
268
+ {
269
+ "kind": "image",
270
+ "assetId": "picture-2",
271
+ "versionId": "picture-2-v1",
272
+ "url": "https://media.example/picture-2.png",
273
+ "mimeType": "image/png",
274
+ "width": 1024,
275
+ "height": 1024,
276
+ "bytes": 200000
277
+ }
278
+ ],
279
+ "result": {
280
+ "kind": "image",
281
+ "assetId": "picture-2",
282
+ "versionId": "picture-2-v1",
283
+ "url": "https://media.example/picture-2.png",
284
+ "mimeType": "image/png",
285
+ "width": 1024,
286
+ "height": 1024,
287
+ "bytes": 200000
288
+ }
289
+ }
290
+ },
291
+ {
292
+ "name": "Gives the panels and their pictures to the next Step",
293
+ "input": {
294
+ "make": "use",
295
+ "panels": {
296
+ "schemaVersion": 1,
297
+ "strip": [
298
+ {
299
+ "panelId": "panel1",
300
+ "kind": "base",
301
+ "prompt": "Sunlight falls across a mountain ridge.",
302
+ "image": "https://media.example/picture-1.png"
303
+ }
304
+ ]
305
+ },
306
+ "pictures": [
307
+ {
308
+ "kind": "image",
309
+ "assetId": "picture-1",
310
+ "versionId": "picture-1-v1",
311
+ "url": "https://media.example/picture-1.png",
312
+ "mimeType": "image/png",
313
+ "width": 1024,
314
+ "height": 1024,
315
+ "bytes": 200000
316
+ }
317
+ ]
318
+ },
319
+ "expected": {
320
+ "panels": {
321
+ "schemaVersion": 1,
322
+ "strip": [
323
+ {
324
+ "panelId": "panel1",
325
+ "kind": "base",
326
+ "prompt": "Sunlight falls across a mountain ridge.",
327
+ "image": "https://media.example/picture-1.png"
328
+ }
329
+ ]
330
+ },
331
+ "images": [
332
+ {
333
+ "kind": "image",
334
+ "assetId": "picture-1",
335
+ "versionId": "picture-1-v1",
336
+ "url": "https://media.example/picture-1.png",
337
+ "mimeType": "image/png",
338
+ "width": 1024,
339
+ "height": 1024,
340
+ "bytes": 200000
341
+ }
342
+ ],
343
+ "result": null
344
+ }
345
+ }
346
+ ],
347
+ "moduleSource": {
348
+ "main.js": "//#region \\0rolldown/runtime.js\nvar __create = Object.create;\nvar __defProp = Object.defineProperty;\nvar __getOwnPropDesc = Object.getOwnPropertyDescriptor;\nvar __getOwnPropNames = Object.getOwnPropertyNames;\nvar __getProtoOf = Object.getPrototypeOf;\nvar __hasOwnProp = Object.prototype.hasOwnProperty;\nvar __esmMin = (fn, res, err) => () => {\n\tif (err) throw err[0];\n\ttry {\n\t\treturn fn && (res = fn(fn = 0)), res;\n\t} catch (e) {\n\t\tthrow err = [e], e;\n\t}\n};\nvar __commonJSMin = (cb, mod) => () => (mod || (cb((mod = { exports: {} }).exports, mod), cb = null), mod.exports);\nvar __exportAll = (all, no_symbols) => {\n\tlet target = {};\n\tfor (var name in all) {\n\t\t__defProp(target, name, {\n\t\t\tget: all[name],\n\t\t\tenumerable: true\n\t\t});\n\t}\n\tif (!no_symbols) {\n\t\t__defProp(target, Symbol.toStringTag, { value: \"Module\" });\n\t}\n\treturn target;\n};\nvar __copyProps = (to, from, except, desc) => {\n\tif (from && typeof from === \"object\" || typeof from === \"function\") {\n\t\tfor (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {\n\t\t\tkey = keys[i];\n\t\t\tif (!__hasOwnProp.call(to, key) && key !== except) {\n\t\t\t\t__defProp(to, key, {\n\t\t\t\t\tget: ((k) => from[k]).bind(null, key),\n\t\t\t\t\tenumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}\n\treturn to;\n};\nvar __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule || !__hasOwnProp.call(mod, \"default\") ? __defProp(target, \"default\", {\n\tvalue: mod,\n\tenumerable: true\n}) : target, mod));\n\n//#endregion\n//#region packages/block-platform/image-panel-prompts.js\nlet chatCollect = async () => {\n\tthrow new Error(\"No text model is connected for Image Panels.\");\n};\nlet streamToResponse = async () => {\n\tthrow new Error(\"No streaming text model is connected for Image Panels.\");\n};\nlet workflowChatInstructions = () => \"\";\nlet providerReady = () => true;\nlet DEFAULT_MODEL = \"google/gemini-2.5-flash\";\nfunction useImagePanelTextModel(model = {}) {\n\tif (typeof model.chatCollect === \"function\") chatCollect = model.chatCollect;\n\tif (typeof model.streamToResponse === \"function\") streamToResponse = model.streamToResponse;\n\tif (typeof model.workflowChatInstructions === \"function\") workflowChatInstructions = model.workflowChatInstructions;\n\tif (typeof model.ready === \"function\") providerReady = model.ready;\n\tif (typeof model.defaultModel === \"string\" && model.defaultModel) DEFAULT_MODEL = model.defaultModel;\n}\nconst STRIP_PLAN_SYSTEM = `You are the strip planner for IMAGE PANEL MODE: you turn a locked video concept + the real voiceover word timings into a STRIP — the ordered sequence of still image PANELS that IS the video. Consistency comes from EDIT-CHAINING: most panels are an image EDIT of the previous panel in their LINEAGE (change only what differs); a new BASE panel (fresh generation from a style reference) is used only for a genuinely new scene/location/subject.\n\nYou are given:\n- \"conversation\": the chat that locked the concept and narration script.\n- \"words\": the voiceover's real word timings [{ i, text, startMs, endMs }] — GROUND TRUTH. The narration defines the beats.\n- \"meta\": { title, aspect, projectType, projectTypeNote }. projectType is the user's own label (story | explainer | both | neither) — it sets the video's CENTER OF GRAVITY, never a restriction.\n\nOutput ONLY this JSON (no prose, no code fences):\n{\n \"styleBlock\": \"<the global default art style>\",\n \"sheets\": { \"<sheetId>\": \"<full visual description>\", ... },\n \"scenes\": [\n { \"sceneId\": \"s1\", \"title\": \"<chapter/story title>\", \"genre\": \"story\" | \"explainer\",\n \"styleBlock\": null | \"<scene-specific style override>\",\n \"sheets\": { \"<sheetId>\": \"...\" },\n \"titleScreen\": { \"template\": \"chapterCard\" } | null }\n ],\n \"lineages\": { \"<lineageId>\": { \"sheetIds\": [\"...\"], \"place\": \"...\", \"persistent\": false }, ... },\n \"strip\": [\n { \"panelId\": \"t1\", \"type\": \"titleScreen\", \"sceneId\": \"s1\", \"wordStart\": 0, \"wordEnd\": 1 },\n { \"panelId\": \"p1\", \"type\": \"panel\", \"sceneId\": \"s1\", \"lineageId\": \"<lineageId>\", \"kind\": \"base\",\n \"scene\": \"<FULL scene description for a base panel — everything visible, plus any baked text VERBATIM in quotes>\",\n \"changePrompt\": null, \"sourcePanelId\": null, \"method\": null, \"methodGroup\": null, \"sfx\": null,\n \"cast\": [\"<sheetId of each character actually IN this beat>\"],\n \"wordStart\": 2, \"wordEnd\": 5, \"transitionIn\": \"cut\" },\n { \"panelId\": \"p2\", \"type\": \"panel\", \"sceneId\": \"s1\", \"lineageId\": \"<same>\", \"kind\": \"edit\",\n \"scene\": null,\n \"changePrompt\": \"keep identity/design; <the ONE precise change, incl. the new expression/pose for this beat>\",\n \"sourcePanelId\": \"p1\", \"method\": \"poseProgression\", \"methodGroup\": \"mg1\", \"sfx\": null,\n \"cast\": [\"<sheetId>\"],\n \"wordStart\": 6, \"wordEnd\": 9, \"transitionIn\": \"cut\" },\n { \"panelId\": \"p2b\", \"type\": \"panel\", \"sceneId\": \"s1\", \"lineageId\": \"<same>\", \"kind\": \"repeat\",\n \"repeatOf\": \"p1\", \"method\": \"cycle\", \"methodGroup\": \"mg2\", \"wordStart\": 10, \"wordEnd\": 11 },\n { \"panelId\": \"p5a\", \"type\": \"panel\", \"sceneId\": \"s1\", \"lineageId\": \"<diagramLineage>\", \"kind\": \"revealStep\",\n \"revealOf\": \"p5\", \"revealIndex\": 0, \"method\": \"progressiveReveal\", \"methodGroup\": \"mg4\", \"wordStart\": 12, \"wordEnd\": 13 },\n { \"panelId\": \"p5b\", \"type\": \"panel\", \"sceneId\": \"s1\", \"lineageId\": \"<diagramLineage>\", \"kind\": \"revealStep\",\n \"revealOf\": \"p5\", \"revealIndex\": 1, \"method\": \"progressiveReveal\", \"methodGroup\": \"mg4\", \"wordStart\": 14, \"wordEnd\": 15 },\n { \"panelId\": \"p5\", \"type\": \"panel\", \"sceneId\": \"s1\", \"lineageId\": \"<diagramLineage>\", \"kind\": \"base\",\n \"scene\": \"<the COMPLETE finished diagram, every element present and described>\",\n \"method\": \"progressiveReveal\", \"methodGroup\": \"mg4\", \"wordStart\": 16, \"wordEnd\": 18 }\n ]\n}\n\nEVERY PANEL IS A FULLY GENERATED IMAGE — including explainer/diagram beats:\n- A diagram beat (a brain with arrows and labels, a mechanism, parts-and-relationships) is generated as ONE complete image; the whole composition (every element, its placement, the flat background) is DESCRIBED in the panel's scene/changePrompt — never assembled from pieces by the system.\n- Diagram beats that change over time use the SAME edit-chain as scenes: give the diagram its own lineage; each step is an edit of the previous frame (\"keep everything identical; add a bold arrow pointing down-left from the brain to a mood icon\"). Accumulations add one element per beat; reveals remove/cross-out one per beat.\n- A connector addition (an arrow/line/pointer as the only change) is a FLASH: give it the shortest possible word span (one connecting word) — never its own long phrase.\n\nSCENES (decide from the ACTUAL voiceover + chat intent — never assume):\n- A scene = one self-contained story/topic/chapter with its own place, cast sheets, and lineages. Split ONLY on real cues in the words: explicit markers the narrator says (\"chapter two\", \"next story\", \"moving on\", \"now let's talk about\", \"part three\") or a clear topic/subject change aligned with the chat. A single continuous story = EXACTLY ONE scene, even if long — never invent splits.\n- Edit-chains RESET at scene boundaries: the first panel of every scene is a fresh \"base\" with that scene's sheets. A lineage may be \"persistent\": true ONLY when the same character/host genuinely recurs across scenes (a narrator across topics) — then its later-scene panels may edit from its earlier-scene frames.\n- When there is MORE THAN ONE scene, put a { \"type\": \"titleScreen\" } entry at each scene's start, its wordStart/wordEnd covering the spoken transition phrase (\"chapter two…\") so the title card shows while it is said. A single-scene video needs no title screen.\n- Each scene gets its own \"genre\": \"story\" (a narrative with people/events) or \"explainer\" (concepts/how-things-work). One video can mix (a story scene then an explainer scene).\n\nMETHODS (per-beat storytelling patterns; tag members with \"method\" + a shared \"methodGroup\" id):\n- cycle: 2–5 near-identical panels with ONE changing element played back and forth to fake motion (1→2→1→3): author the unique frames as edits, then re-showings as { \"kind\": \"repeat\", \"repeatOf\": \"<panelId>\" } entries. Each cycle beat ≤1.5s of words.\n- accumulation: a simple base frame, then each beat ADDS one element (a label, an object popping in), each addition on its VO phrase.\n- reveal: start full, REMOVE/cross-out/hide one element per beat (red X, vanish, cover).\n- expressionSequence: same frame, the character's expression changes on each beat (calm→shocked→angry); one-way, never cycled.\n- zoomProgression: the same scene redrawn closer each beat (wide→mid→close-up→extreme); a discrete camera push.\n- poseProgression: same character, sequential poses reading as one action (stand→raise phone→phone at ear); one-way.\n- comparison: two subjects contrasted — side-by-side frame or A-then-B swap.\n- moodShift: the WHOLE existing frame recolors on a beat (→grayscale, →red tint, →night); a full-frame edit.\n- insertCutaway: cut to ONE illustrative panel (object close-up, location, concept) then back to the main lineage.\n- matchSwap: one image becomes a related one in place (phone→ambulance, coin→house).\n- progressiveReveal: THE method for a SOLID-BACKGROUND diagram/explainer build-up (a brain + arrows + labels appearing piece by piece). ONE generation for the whole sequence: author the group as N \"revealStep\" entries followed by ONE \"base\" entry (all in their own lineage, shared methodGroup). The base's \"scene\" describes the COMPLETE finished diagram — every element present, ON A PERFECTLY FLAT SOLID SINGLE-COLOR BACKGROUND, every element clearly separated (none touching or overlapping, generous space between them). Each revealStep carries \"revealOf\": \"<the base's panelId>\" and \"revealIndex\" 0,1,2… (the uncover order, one element per step) with its own word span; revealSteps have NO prompts — the system renders them by covering not-yet-revealed elements with the exact background color. Order the group so the revealSteps come FIRST and the base LAST (the finished diagram is the sequence's final beat). Use ONLY when the beat is a diagram on a flat solid background; character/scene beats keep edit-chains.\n\nGENRE LEAN (center of gravity, NOT a restriction — any technique is allowed anywhere when the beat calls for it):\n- \"story\" scenes lean on expressionSequence, poseProgression, reveal, moodShift, zoomProgression, insertCutaway, matchSwap — but a story is often BETTER with an explainer beat (a quick diagram showing WHY something happened).\n- \"explainer\" scenes lean on accumulation, cycle, comparison (plus reveal/matchSwap/insertCutaway) — but an explainer is often BETTER with story beats (a character reacting, an emotional moment); 60% explainer / 40% story frequently lands harder than pure explainer.\n- meta.projectType sets the video's backbone the same way: story ≈ 80/20 story-heavy, explainer ≈ 60–80% explainer, both = weave, neither = read projectTypeNote. Use the lean + each beat's actual need; no hard ratios.\n\nZOOM PANEL (free camera push-in — use OCCASIONALLY, not every scene):\n- An entry { \"type\": \"zoom\", \"panelId\", \"sceneId\", \"lineageId\", \"sourcePanelId\": \"<the immediately previous panel of this lineage>\", \"wordStart\", \"wordEnd\" } is a CODED push-in on that panel's frame: the camera zooms into the meaningful subject over the beat (the system picks the exact target by looking at the image). Costs nothing to render.\n- AFTER a zoom, the ZOOMED (tighter) framing IS the lineage's new current image: the next edit's sourcePanelId should be the ZOOM entry's panelId, and its changePrompt describes a change ON the zoomed-in framing. The zoom permanently tightens the frame for the rest of the scene.\n- Great for: pushing into a face before an expression beat, into an object as the narration focuses on it, tightening mid-scene tension.\n- Zoom is IN-only. NEVER plan a zoom-out — when the content wants to pull back to a wider view, that is the cue to start the NEXT SCENE (a fresh base) instead.\n\nPROGRESSION LEAN (the default instinct, NOT a hard rule):\n- PREFER progression: sequences of 2+ consecutive edited panels in ONE lineage where the subject/scene visibly EVOLVES step by step — expressionSequence (emotions shift), poseProgression (an action unfolds), accumulation (elements build up), progressiveReveal (a diagram uncovers piece by piece), zoomProgression (the push-in continues the beat). Actively look for the chance to turn \"show a thing\" into \"show the thing EVOLVING\" across the voiceover stretch.\n- Targets: at least ONE progression sequence in every scene, and roughly 65% of the video's beats inside progression sequences overall. These are soft leans — the system measures them and advises, it never blocks.\n- Do NOT force it: a quick one-off cut, a single illustrative cutaway, or a scene change is allowed to stay a standalone panel when the words genuinely don't support an evolution. A progression the content doesn't earn is worse than a clean one-off.\n\nVISUAL VARIETY (fight sameness — the #1 failure is every beat being the same character at the same framing):\n- Actively VARY THE KIND of beat. Consecutive beats should rarely be the same kind. Draw from this menu and pick whichever fits the words:\n 1) character reaction (expression beat) 2) character action / pose 3) wide establishing shot 4) tight close-up on an object or detail 5) two-up comparison / split screen 6) big-number or stat card (bold number + short label) 7) concept / title card (a key phrase AS the image) 8) labeled diagram 9) metaphor illustration (an abstract idea drawn literally) 10) data viz — a chart, a crowd, a map 11) timeline / sequence strip 12) object insert / cutaway 13) location / environment 14) before→after swap 15) silhouette or symbolic frame 16) hands / POV detail 17) big text-on-screen emphasis 18) scale shot (one vs a crowd) 19) icon grid 20) empty / negative-space beat.\n- A recurring character does NOT belong in every beat. When the narration describes a THING, an idea, a number, a place — CUT AWAY to that thing; don't just show the character again. The character earns the frame on reactions, actions, and moments that are about them.\n- Expression + pose must change with the words even when the same character returns — never the same neutral face twice in a row.\n\nTIMING (hard):\n- Every strip entry maps to a WORD SPAN: wordStart/wordEnd are inclusive indexes into \"words\". Spans are contiguous (next wordStart = previous wordEnd + 1), start at 0, and end at the last word.\n- SYNC — anchor each panel to WHEN ITS SUBJECT IS SPOKEN, not to the start of the lead-in clause. A panel's wordStart is the index of the word where THIS panel's subject/content is first NAMED in the narration. Narration names the thing mid- or late-clause (\"…and that's when the VOLCANO erupted\") — the volcano panel's wordStart is \"volcano\", NOT \"and\". The PREVIOUS panel simply holds through that lead-in (contiguity still holds: previous wordEnd = this wordStart − 1). The image lands EXACTLY as its word is said — never a clause, and never a whole beat, early. This is the single most important timing rule: getting it wrong makes every illustration play ahead of the voice.\n- NO panel may span more than 2.5 SECONDS of speech — the system enforces this ceiling; plan real new beats instead of long holds. Default rhythm: a change roughly every 2 seconds (the 2–2.5s band). cycle-method panels: ≤1.5 seconds each. accumulation additions land exactly on their VO phrase (often <2s).\n\nRULES (all hard):\n- styleBlock: the locked art style, identical for every panel of its scope — e.g. flat bold black-outline cartoon, solid fills, simple shapes, thick consistent line weight, the aspect framing. Describe the ART STYLE only — no title bar or caption bar. Write it once, complete, self-contained. Scene styleBlock overrides only when a scene truly needs a different look; otherwise null.\n- sheets: every recurring character/place fully described (age, hair, clothing, colors, distinctive features; for places: walls, windows, doors, layout). Scene sheets for scene-local cast; global sheets for shared cast.\n- cast: on every panel, the sheetIds of the characters ACTUALLY VISIBLE in THAT beat. Empty [] when the beat has NO character (an object, a number/stat card, a diagram, a map, a location, a metaphor). The system attaches a character's locked reference ONLY to beats that list them — so cutaway/concept/diagram beats are free to be fully re-imagined (this is what keeps the video varied). Do NOT list a character on a beat just because their lineage recurs; list them only when they are on screen. A pure diagram/card beat is [].\n- kind \"edit\": changePrompt describes ONLY the delta, starting with a keep-clause (\"keep everything identical; ...\" / \"same framing; ...\"). sourcePanelId = the LAST panel of the SAME lineage IN THE SAME SCENE (unless the lineage is persistent). scene = null.\n- kind \"base\": scene = the full description (style/sheets are injected separately — do not repeat them; DO include composition, framing, what every subject is doing, and any baked text verbatim). changePrompt = null, sourcePanelId = null. Use a base for the first panel of a scene and for a genuinely new location/subject within it.\n- ACCUMULATION CONTRACT (hard): every accumulation methodGroup is one dependent image sequence. Its FIRST real panel is the only base; EVERY later member is kind \"edit\" and sourcePanelId is the immediately previous real member of that SAME methodGroup. Never start a new base for a later label/object/arrow, even if other lineages are interleaved between beats. The build waits for that source frame, then adds exactly the next narrated element; this is how the diagram/scene remains one stable image rather than several style-matched guesses. Use progressiveReveal instead when the whole group is a flat-solid-background diagram that can be rendered deterministically.\n- kind \"repeat\": ONLY for cycle re-showings; repeatOf = an earlier real panel in the same lineage+scene; no prompts.\n- Interleaving: cutting to another lineage and RETURNING is good storytelling; a returning panel is ALWAYS an edit from ITS lineage's last panel, with a real visible change. Never a static repeat (use kind \"repeat\" only inside cycle groups).\n- STORY STRUCTURE (retention — treat as hard): each scene is a FILM, not a slideshow of one room. Within a scene expect 2–5 interleaved lineages per ~60s (establish → develop → cut away → RETURN): the main subject, cutaway inserts, visual metaphors (\"energy\" → a battery filling; \"crash\" → a graph plunging), location/time shifts. A single-lineage scene is acceptable only when its script never leaves one moment.\n- TEXT (two channels — spec B4):\n · SPEECH BUBBLES from a character are GENERATED INTO the image: describe them in the scene/changePrompt with the EXACT text in quotes (\"add a white speech bubble ... reading \\\\\"...\\\\\"\").\n · ALL OTHER TEXT (labels, headings, callouts, emphasis words) is NOT baked into the image. Put it on the panel as \"textOverlays\": [{ \"text\": \"<exact text>\" }] — the app's vision pass places it on the finished frame and renders it as editable coded text. Never describe labels/headings inside the scene/changePrompt.\n · IMPORTANT NUMBERS (strong default): when the narration states a striking number, statistic, or quantity — \"100 quintillion\", \"120 billion humans\", \"1 in 8\", a year, a percentage — SHOW that number as a big textOverlay ({ \"text\": \"100 quintillion\" }) so it actually lands on screen. A number-driven beat should almost always carry its key number as a bold on-screen textOverlay — do NOT leave a striking number living only in the voiceover with unrelated artwork behind it.\n · LABEL DETAILS (each textOverlay may carry):\n - \"role\": \"small\" (a tag next to a thing, \"adenosine\", \"MOOD\"), \"medium\" (a name/term/callout), or \"large\" (the emphasis word or number that IS the shot's focal point, e.g. a huge \"$4,000\"). Size by importance. Default medium.\n - \"arrow\": { \"pointsAt\": \"<the thing in the frame it points at>\" } — use when the beat is POINTING OUT a specific element/region (\"the amygdala\", \"the crack in the beam\"). The app aims the arrow; you only name the target.\n - \"atWord\": <a word index from \"words\"> — set when the label should ARRIVE on its own beat (word-synced), e.g. a diagram builds and then an arrow+label points to a part on the NEXT word. Omit for a label that's present from the panel's start. This is how a label becomes a progression/accumulation/progressiveReveal step.\n Stay SPARSE: labels are for key terms, names, numbers, and things worth pointing at — most panels have none, never full sentences.\n- SFX (per panel, \"sfx\"): a SHORT concrete diegetic sound this beat genuinely MAKES — a match striking, glass shattering, a coin dropping, a door slamming, a phone ringing, a sword unsheathing — or null. Be SPARSE: MOST beats are silent (null). Judge by the REAL event, NEVER a figure of speech: \"branches explode into dots\", \"the scroll spills off screen\", \"grain pours from a funnel\", \"numbers flood in\" are VISUAL METAPHORS with no real sound → null. A purely visual change (something appears, a colour/mood/size/lighting shift, a glow, a shadow) is silent → null. You wrote the scene and you have the narration — use both, but flag ONLY sound the beat literally produces. Never invent one to fill a beat.\n- panelIds unique in strip order; every lineageId used exists in \"lineages\"; every sceneId used exists in \"scenes\"; each scene's entries contiguous in the strip.\n- NEVER return to an earlier sceneId later in the strip — once the strip leaves a scene, that sceneId is done. A callback to an earlier scene's visuals is a NEW scene (same sheets, new sceneId) that re-establishes with its own base panel.\nReturn STRICT JSON only.`;\nconst METHOD_IDS = /* @__PURE__ */ new Set([\n\t\"cycle\",\n\t\"accumulation\",\n\t\"reveal\",\n\t\"expressionSequence\",\n\t\"zoomProgression\",\n\t\"poseProgression\",\n\t\"comparison\",\n\t\"moodShift\",\n\t\"insertCutaway\",\n\t\"matchSwap\",\n\t\"progressiveReveal\"\n]);\nconst PROJECT_TYPES = /* @__PURE__ */ new Set([\n\t\"story\",\n\t\"explainer\",\n\t\"both\",\n\t\"neither\"\n]);\nconst clamp01 = (v, dflt) => Number.isFinite(Number(v)) ? Math.max(0, Math.min(1, Number(v))) : dflt;\nfunction normalizeStripPlan(raw, { wordCount = 0, projectType = null, projectTypeNote = \"\" } = {}) {\n\tconst doc = raw && typeof raw === \"object\" ? raw : {};\n\tconst out = {\n\t\tstyleBlock: String(doc.styleBlock || \"\").slice(0, 4e3),\n\t\tsheets: {},\n\t\tlineages: {},\n\t\tstrip: [],\n\t\tsfxAuthored: true,\n\t\t...PROJECT_TYPES.has(projectType) ? { projectType } : {},\n\t\t...projectTypeNote ? { projectTypeNote: String(projectTypeNote).slice(0, 500) } : {}\n\t};\n\tif (doc.sheets && typeof doc.sheets === \"object\") for (const [k, v] of Object.entries(doc.sheets).slice(0, 40)) out.sheets[String(k).slice(0, 80)] = String(v || \"\").slice(0, 1200);\n\tif (doc.lineages && typeof doc.lineages === \"object\") for (const [k, v] of Object.entries(doc.lineages).slice(0, 24)) out.lineages[String(k).slice(0, 80)] = {\n\t\tsheetIds: Array.isArray(v?.sheetIds) ? v.sheetIds.slice(0, 12).map((s) => String(s).slice(0, 80)) : [],\n\t\tplace: String(v?.place || \"\").slice(0, 300),\n\t\tpersistent: v?.persistent === true\n\t};\n\tconst sceneIds = /* @__PURE__ */ new Set();\n\tif (Array.isArray(doc.scenes) && doc.scenes.length) {\n\t\tout.scenes = [];\n\t\tfor (const s of doc.scenes.slice(0, 24)) {\n\t\t\tif (!s || typeof s !== \"object\") continue;\n\t\t\tconst sceneId = String(s.sceneId || \"\").slice(0, 40);\n\t\t\tif (!sceneId || sceneIds.has(sceneId)) continue;\n\t\t\tsceneIds.add(sceneId);\n\t\t\tconst sheets = {};\n\t\t\tif (s.sheets && typeof s.sheets === \"object\") for (const [k, v] of Object.entries(s.sheets).slice(0, 40)) sheets[String(k).slice(0, 80)] = String(v || \"\").slice(0, 1200);\n\t\t\tout.scenes.push({\n\t\t\t\tsceneId,\n\t\t\t\ttitle: String(s.title || \"\").slice(0, 200),\n\t\t\t\tgenre: s.genre === \"story\" || s.genre === \"explainer\" ? s.genre : null,\n\t\t\t\tstyleBlock: s.styleBlock ? String(s.styleBlock).slice(0, 4e3) : null,\n\t\t\t\tstyleRef: null,\n\t\t\t\tsheets,\n\t\t\t\ttitleScreen: s.titleScreen && typeof s.titleScreen === \"object\" ? { template: String(s.titleScreen.template || \"chapterCard\").slice(0, 40) } : null\n\t\t\t});\n\t\t}\n\t\tif (!out.scenes.length) delete out.scenes;\n\t}\n\tconst clampSpan = (entry) => {\n\t\tentry.wordStart = Math.max(0, Math.round(Number(entry.wordStart) || 0));\n\t\tentry.wordEnd = Math.max(entry.wordStart, Math.round(Number(entry.wordEnd) || entry.wordStart));\n\t\tif (wordCount > 0) {\n\t\t\tentry.wordStart = Math.min(entry.wordStart, wordCount - 1);\n\t\t\tentry.wordEnd = Math.min(Math.max(entry.wordEnd, entry.wordStart), wordCount - 1);\n\t\t}\n\t\treturn entry;\n\t};\n\tconst normOverlays = (list) => {\n\t\tif (!Array.isArray(list)) return void 0;\n\t\tconst overlays = list.slice(0, 8).filter((o) => o && String(o.text || \"\").trim()).map((o) => {\n\t\t\tconst arrow = o.arrow && typeof o.arrow === \"object\" ? {\n\t\t\t\t...String(o.arrow.pointsAt || \"\").trim() ? { pointsAt: String(o.arrow.pointsAt).slice(0, 200) } : {},\n\t\t\t\t...Number.isFinite(Number(o.arrow?.to?.x)) && Number.isFinite(Number(o.arrow?.to?.y)) ? { to: {\n\t\t\t\t\tx: clamp01(o.arrow.to.x, .5),\n\t\t\t\t\ty: clamp01(o.arrow.to.y, .5)\n\t\t\t\t} } : {}\n\t\t\t} : null;\n\t\t\treturn {\n\t\t\t\ttext: String(o.text).slice(0, 200),\n\t\t\t\t...Number.isFinite(Number(o?.pos?.x)) && Number.isFinite(Number(o?.pos?.y)) ? { pos: {\n\t\t\t\t\tx: clamp01(o.pos.x, .5),\n\t\t\t\t\ty: clamp01(o.pos.y, .5)\n\t\t\t\t} } : {},\n\t\t\t\t...Number.isFinite(Number(o.size)) ? { size: Math.max(.01, Math.min(.3, Number(o.size))) } : {},\n\t\t\t\t...[\n\t\t\t\t\t\"small\",\n\t\t\t\t\t\"medium\",\n\t\t\t\t\t\"large\"\n\t\t\t\t].includes(o.role) ? { role: o.role } : {},\n\t\t\t\t...arrow && (arrow.pointsAt || arrow.to) ? { arrow } : {},\n\t\t\t\t...Number.isFinite(Number(o.atWord)) ? { atWord: Math.max(0, Math.round(Number(o.atWord))) } : {},\n\t\t\t\tplacedBy: \"pending\",\n\t\t\t\teditable: true\n\t\t\t};\n\t\t});\n\t\treturn overlays.length ? overlays : void 0;\n\t};\n\tconst strip = Array.isArray(doc.strip) ? doc.strip : [];\n\tfor (const p of strip.slice(0, 400)) {\n\t\tif (!p || typeof p !== \"object\") continue;\n\t\tconst sceneId = out.scenes ? String(p.sceneId || \"\").slice(0, 40) : void 0;\n\t\tif (out.scenes && !sceneIds.has(sceneId)) continue;\n\t\tif (p.type === \"diagram\") continue;\n\t\tif (p.type === \"zoom\") {\n\t\t\tif (!out.scenes) continue;\n\t\t\tconst entry = clampSpan({\n\t\t\t\tpanelId: String(p.panelId || \"\").slice(0, 40),\n\t\t\t\ttype: \"zoom\",\n\t\t\t\tsceneId,\n\t\t\t\tlineageId: String(p.lineageId || \"\").slice(0, 80),\n\t\t\t\tsourcePanelId: String(p.sourcePanelId || \"\").slice(0, 40),\n\t\t\t\twordStart: p.wordStart,\n\t\t\t\twordEnd: p.wordEnd,\n\t\t\t\ttransitionIn: \"cut\"\n\t\t\t});\n\t\t\tif (entry.panelId && entry.lineageId && entry.sourcePanelId) out.strip.push(entry);\n\t\t\tcontinue;\n\t\t}\n\t\tif (p.type === \"titleScreen\") {\n\t\t\tif (!out.scenes) continue;\n\t\t\tconst entry = clampSpan({\n\t\t\t\tpanelId: String(p.panelId || \"\").slice(0, 40),\n\t\t\t\ttype: \"titleScreen\",\n\t\t\t\tsceneId,\n\t\t\t\twordStart: p.wordStart,\n\t\t\t\twordEnd: p.wordEnd\n\t\t\t});\n\t\t\tif (entry.panelId) out.strip.push(entry);\n\t\t\tcontinue;\n\t\t}\n\t\tconst kind = p.kind === \"base\" ? \"base\" : p.kind === \"repeat\" ? \"repeat\" : p.kind === \"revealStep\" ? \"revealStep\" : \"edit\";\n\t\tconst entry = clampSpan({\n\t\t\tpanelId: String(p.panelId || \"\").slice(0, 40),\n\t\t\t...out.scenes ? {\n\t\t\t\ttype: \"panel\",\n\t\t\t\tsceneId\n\t\t\t} : {},\n\t\t\tlineageId: String(p.lineageId || \"\").slice(0, 80),\n\t\t\tkind,\n\t\t\tscene: kind === \"base\" ? String(p.scene || \"\").slice(0, 3e3) : null,\n\t\t\tchangePrompt: kind === \"edit\" ? String(p.changePrompt || \"\").trim() ? String(p.changePrompt).slice(0, 1500) : continuationPrompt(1) : null,\n\t\t\tsourcePanelId: kind === \"edit\" ? String(p.sourcePanelId || \"\").slice(0, 40) : null,\n\t\t\t...kind === \"repeat\" ? { repeatOf: String(p.repeatOf || \"\").slice(0, 40) } : {},\n\t\t\t...kind === \"revealStep\" ? {\n\t\t\t\trevealOf: String(p.revealOf || \"\").slice(0, 40),\n\t\t\t\trevealIndex: Math.max(0, Math.round(Number(p.revealIndex) || 0))\n\t\t\t} : {},\n\t\t\tmethod: METHOD_IDS.has(p.method) ? p.method : null,\n\t\t\tmethodGroup: p.methodGroup != null ? String(p.methodGroup).slice(0, 40) : null,\n\t\t\t...normOverlays(p.textOverlays) ? { textOverlays: normOverlays(p.textOverlays) } : {},\n\t\t\t...String(p.sfx || \"\").trim() ? { sfx: String(p.sfx).trim().slice(0, 160) } : {},\n\t\t\twordStart: p.wordStart,\n\t\t\twordEnd: p.wordEnd,\n\t\t\ttransitionIn: p.transitionIn === \"fade\" ? \"fade\" : \"cut\"\n\t\t});\n\t\tif (!entry.panelId || !entry.lineageId) continue;\n\t\tif (kind === \"repeat\" && !entry.repeatOf) continue;\n\t\tif (kind === \"revealStep\" && !entry.revealOf) continue;\n\t\tout.strip.push(entry);\n\t}\n\tif (out.scenes) {\n\t\tconst sceneById = new Map(out.scenes.map((s) => [s.sceneId, s]));\n\t\tconst finalSceneOf = /* @__PURE__ */ new Map();\n\t\tconst closed = /* @__PURE__ */ new Set();\n\t\tconst returnCount = /* @__PURE__ */ new Map();\n\t\tlet openOrig = null;\n\t\tlet openFinal = null;\n\t\tfor (const e of out.strip) {\n\t\t\tif (e.sceneId !== openOrig) {\n\t\t\t\tif (openOrig != null) closed.add(openOrig);\n\t\t\t\topenOrig = e.sceneId;\n\t\t\t\topenFinal = e.sceneId;\n\t\t\t\tif (closed.has(e.sceneId)) {\n\t\t\t\t\tconst n = (returnCount.get(e.sceneId) || 0) + 1;\n\t\t\t\t\treturnCount.set(e.sceneId, n);\n\t\t\t\t\tlet cloneId = `${e.sceneId}r${n}`.slice(0, 40);\n\t\t\t\t\twhile (sceneById.has(cloneId)) cloneId = `${cloneId}x`.slice(0, 40);\n\t\t\t\t\tconst orig = sceneById.get(e.sceneId);\n\t\t\t\t\tconst clone = {\n\t\t\t\t\t\t...orig,\n\t\t\t\t\t\tsceneId: cloneId,\n\t\t\t\t\t\tsheets: { ...orig?.sheets || {} },\n\t\t\t\t\t\ttitleScreen: null\n\t\t\t\t\t};\n\t\t\t\t\tout.scenes.push(clone);\n\t\t\t\t\tsceneById.set(cloneId, clone);\n\t\t\t\t\topenFinal = cloneId;\n\t\t\t\t}\n\t\t\t}\n\t\t\te.sceneId = openFinal;\n\t\t\tif (e.type !== \"titleScreen\") {\n\t\t\t\tif (e.kind === \"edit\" && e.sourcePanelId && finalSceneOf.has(e.sourcePanelId) && finalSceneOf.get(e.sourcePanelId) !== e.sceneId) {\n\t\t\t\t\tif (out.lineages[e.lineageId]) out.lineages[e.lineageId].persistent = true;\n\t\t\t\t}\n\t\t\t\tif (e.kind === \"repeat\" && finalSceneOf.has(e.repeatOf) && finalSceneOf.get(e.repeatOf) !== e.sceneId) {\n\t\t\t\t\te.kind = \"edit\";\n\t\t\t\t\te.sourcePanelId = e.repeatOf;\n\t\t\t\t\te.changePrompt = continuationPrompt(1);\n\t\t\t\t\tdelete e.repeatOf;\n\t\t\t\t\tif (out.lineages[e.lineageId]) out.lineages[e.lineageId].persistent = true;\n\t\t\t\t}\n\t\t\t\tif (e.type === \"zoom\" && finalSceneOf.has(e.sourcePanelId) && finalSceneOf.get(e.sourcePanelId) !== e.sceneId) e.__dropZoom = true;\n\t\t\t\tfinalSceneOf.set(e.panelId, e.sceneId);\n\t\t\t}\n\t\t}\n\t\tout.strip = out.strip.filter((e) => !e.__dropZoom);\n\t}\n\t{\n\t\tconst previous = /* @__PURE__ */ new Map();\n\t\tfor (const e of out.strip) {\n\t\t\tif (e.type === \"titleScreen\" || e.type === \"zoom\" || e.kind === \"revealStep\" || e.method !== \"accumulation\" || !e.methodGroup || e.kind === \"repeat\") continue;\n\t\t\tconst key = `${e.sceneId || \"__legacy__\"}\\u0000${e.lineageId}\\u0000${e.methodGroup}`;\n\t\t\tconst priorId = previous.get(key);\n\t\t\tif (priorId) {\n\t\t\t\tif (e.kind !== \"edit\") {\n\t\t\t\t\tconst describedStep = String(e.changePrompt || e.scene || \"add the next narrated accumulation element\").trim().slice(0, 1500);\n\t\t\t\t\te.kind = \"edit\";\n\t\t\t\t\te.scene = null;\n\t\t\t\t\te.changePrompt = /^\\s*(keep|same|retain|preserve|everything)/i.test(describedStep) ? describedStep : `Keep everything in the source frame exactly identical; the ONLY change is this next accumulation step: ${describedStep}`;\n\t\t\t\t}\n\t\t\t\te.sourcePanelId = priorId;\n\t\t\t}\n\t\t\tprevious.set(key, e.panelId);\n\t\t}\n\t}\n\t{\n\t\tconst baseById = new Map(out.strip.filter((e) => e.kind === \"base\").map((e) => [e.panelId, e]));\n\t\tout.strip = out.strip.filter((e) => {\n\t\t\tif (e.kind !== \"revealStep\") return true;\n\t\t\tconst base = baseById.get(e.revealOf);\n\t\t\treturn !!base && base.method === \"progressiveReveal\" && base.lineageId === e.lineageId && (!out.scenes || base.sceneId === e.sceneId);\n\t\t});\n\t}\n\tlet shownId = null;\n\tlet heldFrom = null;\n\tlet runIdx = 0;\n\tout.strip = out.strip.map((e) => {\n\t\tif (e.type === \"titleScreen\") {\n\t\t\tshownId = null;\n\t\t\theldFrom = null;\n\t\t\trunIdx = 0;\n\t\t\treturn e;\n\t\t}\n\t\tif (e.kind === \"repeat\" && shownId && (e.repeatOf === shownId || e.repeatOf === heldFrom)) {\n\t\t\tconst src = shownId;\n\t\t\theldFrom = heldFrom || e.repeatOf;\n\t\t\tshownId = e.panelId;\n\t\t\trunIdx += 1;\n\t\t\tconst { repeatOf, ...rest } = e;\n\t\t\treturn {\n\t\t\t\t...rest,\n\t\t\t\tkind: \"edit\",\n\t\t\t\tscene: null,\n\t\t\t\tchangePrompt: continuationPrompt(runIdx),\n\t\t\t\tsourcePanelId: src\n\t\t\t};\n\t\t}\n\t\theldFrom = null;\n\t\trunIdx = 0;\n\t\tshownId = e.kind === \"repeat\" ? e.repeatOf : e.panelId;\n\t\treturn e;\n\t});\n\treturn out;\n}\nconst CONTINUATION_PROMPTS = [\n\t\"Same scene, same moment, same characters, same art style; REDRAW this as a tight close-up on the single most important subject or detail in the frame — a genuinely different, much closer composition, not a slight zoom.\",\n\t\"Same scene, same moment, same characters, same art style; REDRAW this from a clearly different camera angle — shifted to the side or over a shoulder — same staging, visibly re-framed.\",\n\t\"Same scene, same moment, same characters, same art style; REDRAW this as a wider shot pulled back to reveal more of the surroundings — same staging, clearly different framing.\"\n];\nfunction continuationPrompt(k = 1) {\n\treturn CONTINUATION_PROMPTS[(Math.max(1, k | 0) - 1) % CONTINUATION_PROMPTS.length];\n}\nfunction repairJsonish(s) {\n\treturn String(s).replace(/\\/\\/[^\\n\\r]*/g, \"\").replace(/\\/\\*[\\s\\S]*?\\*\\//g, \"\").replace(/,(\\s*[}\\]])/g, \"$1\").replace(/[“”]/g, \"\\\"\").replace(/[‘’]/g, \"'\");\n}\nfunction outerObject(s) {\n\tconst start = s.indexOf(\"{\");\n\tif (start < 0) return null;\n\tlet depth = 0, inStr = false, esc = false;\n\tfor (let i = start; i < s.length; i++) {\n\t\tconst c = s[i];\n\t\tif (inStr) {\n\t\t\tif (esc) esc = false;\n\t\t\telse if (c === \"\\\\\") esc = true;\n\t\t\telse if (c === \"\\\"\") inStr = false;\n\t\t\tcontinue;\n\t\t}\n\t\tif (c === \"\\\"\") inStr = true;\n\t\telse if (c === \"{\") depth++;\n\t\telse if (c === \"}\") {\n\t\t\tdepth--;\n\t\t\tif (depth === 0) return s.slice(start, i + 1);\n\t\t}\n\t}\n\treturn null;\n}\nfunction parseJson(text) {\n\tconst t = String(text || \"\").replace(/```(?:json)?/gi, \"\").trim();\n\tconst candidates = [t, repairJsonish(t)];\n\tconst obj = outerObject(t);\n\tif (obj) candidates.push(obj, repairJsonish(obj));\n\tfor (const c of candidates) try {\n\t\treturn JSON.parse(c);\n\t} catch {}\n\treturn null;\n}\nfunction frameDensityDirective({ frameDensity, frameTarget, prevPanelCount } = {}) {\n\tconst target = Math.round(Number(frameTarget));\n\tif (!Number.isFinite(target) || target < 1 || ![\"more\", \"fewer\"].includes(frameDensity)) return null;\n\tconst prev = Number.isFinite(Number(prevPanelCount)) && prevPanelCount > 0 ? ` (the previous plan had ${prevPanelCount})` : \"\";\n\tconst how = frameDensity === \"more\" ? \"Add frames by splitting beats into finer moments and inserting meaningful new shots — never by cloning near-identical frames.\" : \"Remove frames by merging adjacent beats into single stronger shots — keep every distinct story moment covered.\";\n\treturn `FRAME-COUNT DIRECTIVE: the user asked for ${frameDensity.toUpperCase()} frames${prev}. Produce close to ${target} panels (within 2, not counting title screens). ${how}`;\n}\nasync function planStrip({ messages, words, title = \"\", aspect = \"16:9\", model, projectType = null, projectTypeNote = \"\", frameDensity = null, frameTarget = null, prevPanelCount = null } = {}) {\n\tconst w = (Array.isArray(words) ? words : []).map((x, i) => ({\n\t\ti,\n\t\ttext: String(x.text ?? x.word ?? \"\"),\n\t\tstartMs: Math.round(Number(x.startMs ?? x.start * 1e3) || 0),\n\t\tendMs: Math.round(Number(x.endMs ?? x.end * 1e3) || 0)\n\t})).filter((x) => x.text);\n\tif (!w.length) throw new Error(\"Strip planning needs the voiceover word timings — run the timing analysis first.\");\n\tconst convo = (Array.isArray(messages) ? messages : []).filter((m) => m && (m.role === \"user\" || m.role === \"assistant\") && typeof m.content === \"string\").map((m) => ({\n\t\trole: m.role,\n\t\tcontent: m.content.slice(0, 6e3)\n\t}));\n\tconst directive = frameDensityDirective({\n\t\tframeDensity,\n\t\tframeTarget,\n\t\tprevPanelCount\n\t});\n\tconst userPayload = JSON.stringify({\n\t\tconversation: convo,\n\t\twords: w,\n\t\tmeta: {\n\t\t\ttitle,\n\t\t\taspect,\n\t\t\tprojectType,\n\t\t\tprojectTypeNote\n\t\t}\n\t});\n\tconst PLAN_BUDGET_MS = 23e4;\n\tconst startedAt = Date.now();\n\tconst left = () => PLAN_BUDGET_MS - (Date.now() - startedAt);\n\tconst STRICT = \"\\n\\nCRITICAL: Return ONLY the raw JSON object. No prose, no markdown fences, no comments, no trailing commas. The response must start with { and end with }.\";\n\tconst rungs = [\n\t\t{\n\t\t\tmodel,\n\t\t\tstrict: false,\n\t\t\ttimeoutMs: 15e4\n\t\t},\n\t\t{\n\t\t\tmodel,\n\t\t\tstrict: true,\n\t\t\ttimeoutMs: 9e4\n\t\t},\n\t\t...model !== DEFAULT_MODEL ? [{\n\t\t\tmodel: DEFAULT_MODEL,\n\t\t\tstrict: true,\n\t\t\ttimeoutMs: 6e4\n\t\t}] : []\n\t];\n\tlet parsed = null;\n\tlet lastErr = null;\n\tfor (const rung of rungs) {\n\t\tif (parsed) break;\n\t\tif (left() < 2e4) break;\n\t\ttry {\n\t\t\tparsed = parseJson(await chatCollect({\n\t\t\t\tmodel: rung.model,\n\t\t\t\tsystem: (directive ? `${STRIP_PLAN_SYSTEM}\\n\\n${directive}` : STRIP_PLAN_SYSTEM) + (rung.strict ? STRICT : \"\"),\n\t\t\t\tmax_tokens: Math.min(24e3, 8e3 + w.length * 40),\n\t\t\t\ttimeoutMs: rung.timeoutMs,\n\t\t\t\tbudgetMs: left(),\n\t\t\t\tmessages: [{\n\t\t\t\t\trole: \"user\",\n\t\t\t\t\tcontent: userPayload\n\t\t\t\t}]\n\t\t\t}));\n\t\t} catch (e) {\n\t\t\tlastErr = e;\n\t\t}\n\t}\n\tif (!parsed) throw new Error(lastErr?.message || \"The planner did not return a usable plan.\");\n\tconst plan = normalizeStripPlan(parsed, {\n\t\twordCount: w.length,\n\t\tprojectType,\n\t\tprojectTypeNote\n\t});\n\tif (!plan.strip.length) throw new Error(\"Strip planner produced no panels — try again.\");\n\treturn plan;\n}\nconst PLACE_TEXT_SYSTEM = `You place TEXT LABELS on a finished video frame. You are given the frame image and a list of texts (each is { \"text\", and optionally \"pointsAt\" — a description of the thing in the image this label points AT). For each text, choose a position (normalized 0..1 coordinates of the text's CENTER; x rightward, y downward) and a size (text height as a fraction of frame height, 0.03–0.12) so that:\n- the text is legible and does NOT cover faces, characters, or the important artwork;\n- labels sit NEAR what they label; headings prefer upper thirds; callouts prefer clear empty areas;\n- multiple texts never overlap each other.\n- If a text has \"pointsAt\", ALSO return \"arrow\": { \"to\": { \"x\", \"y\" } } — the normalized coordinate of the thing it points at (the arrow TIP) — and place the label a short gap away from that point, not on top of it.\nReturn ONLY JSON: { \"placements\": [{ \"text\": \"<verbatim>\", \"pos\": { \"x\": 0.5, \"y\": 0.2 }, \"size\": 0.05, \"arrow\": { \"to\": { \"x\": 0.6, \"y\": 0.4 } } }] } — one entry per input text, same order; omit \"arrow\" for texts without pointsAt.`;\nfunction normalizePlacements(raw, items) {\n\tconst list = Array.isArray(raw?.placements) ? raw.placements : [];\n\treturn items.map((item, i) => {\n\t\tconst t = typeof item === \"string\" ? item : String(item?.text || \"\");\n\t\tconst pointsAt = typeof item === \"object\" ? item?.pointsAt : null;\n\t\tconst p = list[i] || list.find((x) => String(x?.text || \"\") === t) || {};\n\t\tconst to = pointsAt && Number.isFinite(Number(p?.arrow?.to?.x)) && Number.isFinite(Number(p?.arrow?.to?.y)) ? {\n\t\t\tx: clamp01(p.arrow.to.x, .5),\n\t\t\ty: clamp01(p.arrow.to.y, .5)\n\t\t} : null;\n\t\treturn {\n\t\t\ttext: t,\n\t\t\tpos: {\n\t\t\t\tx: clamp01(p?.pos?.x, .5),\n\t\t\t\ty: clamp01(p?.pos?.y, i === 0 ? .18 : .8)\n\t\t\t},\n\t\t\tsize: Number.isFinite(Number(p?.size)) ? Math.max(.03, Math.min(.12, Number(p.size))) : .05,\n\t\t\t...to ? { arrow: { to } } : {},\n\t\t\tplacedBy: \"vision\",\n\t\t\teditable: true\n\t\t};\n\t});\n}\nconst NAME_ELEMENTS_SYSTEM = `You look at a finished explainer diagram plus a list of detected element bounding boxes (id + pixel box), and you NAME each element and give the best REVEAL ORDER for narrating the diagram.\n\nReturn STRICT JSON ONLY — no prose, no code fences:\n{\"elements\":[{\"id\":\"e1\",\"name\":\"the brain\"},...],\"order\":[\"e1\",\"e3\",\"e2\",...]}\n\nRules:\n- Use ONLY the given ids. Never invent, drop, split, or merge ids.\n- name: 2-6 words, what that region of the image IS (\"the brain\", \"MOOD label\", \"arrow to memory icon\").\n- order: every id exactly once — the sequence the elements should appear in while the narration builds the diagram (main subject first, then connections/labels in narration order; use the provided narration text as the guide).\n- NEVER output coordinates. The boxes are ground truth from pixel analysis.`;\nasync function nameRevealElements({ imageUrl, blobs, narration = \"\", model } = {}) {\n\tconst clean = (Array.isArray(blobs) ? blobs : []).filter((b) => b && b.id && b.box).slice(0, 40).map((b) => ({\n\t\tid: String(b.id).slice(0, 40),\n\t\tbox: {\n\t\t\tx: b.box.x | 0,\n\t\t\ty: b.box.y | 0,\n\t\t\tw: b.box.w | 0,\n\t\t\th: b.box.h | 0\n\t\t}\n\t}));\n\tif (!clean.length) throw new Error(\"nameRevealElements: no blobs\");\n\tif (!imageUrl || typeof imageUrl !== \"string\") throw new Error(\"nameRevealElements: no image\");\n\treturn normalizeElementNames(parseJson(await chatCollect({\n\t\tmodel,\n\t\tsystem: NAME_ELEMENTS_SYSTEM,\n\t\tmax_tokens: 1500,\n\t\tmessages: [{\n\t\t\trole: \"user\",\n\t\t\tcontent: [{\n\t\t\t\ttype: \"text\",\n\t\t\t\ttext: JSON.stringify({\n\t\t\t\t\tblobs: clean,\n\t\t\t\t\tnarration: String(narration || \"\").slice(0, 2e3)\n\t\t\t\t})\n\t\t\t}, {\n\t\t\t\ttype: \"image_url\",\n\t\t\t\timage_url: { url: imageUrl }\n\t\t\t}]\n\t\t}]\n\t})), clean);\n}\nfunction normalizeElementNames(raw, blobs) {\n\tconst ids = blobs.map((b) => b.id);\n\tconst known = new Set(ids);\n\tconst nameById = /* @__PURE__ */ new Map();\n\tfor (const e of Array.isArray(raw?.elements) ? raw.elements : []) {\n\t\tconst id = String(e?.id || \"\");\n\t\tif (known.has(id) && !nameById.has(id)) nameById.set(id, String(e?.name || id).slice(0, 120));\n\t}\n\tconst order = [];\n\tfor (const id of Array.isArray(raw?.order) ? raw.order : []) {\n\t\tconst s = String(id);\n\t\tif (known.has(s) && !order.includes(s)) order.push(s);\n\t}\n\tfor (const id of ids) if (!order.includes(id)) order.push(id);\n\treturn {\n\t\telements: ids.map((id) => ({\n\t\t\tid,\n\t\t\tname: nameById.get(id) || id\n\t\t})),\n\t\torder\n\t};\n}\nasync function placeTextOverlays({ imageUrl, texts, model } = {}) {\n\tconst items = (Array.isArray(texts) ? texts : []).map((t) => typeof t === \"string\" ? { text: t.trim() } : {\n\t\ttext: String(t?.text || \"\").trim(),\n\t\t...String(t?.pointsAt || \"\").trim() ? { pointsAt: String(t.pointsAt).trim().slice(0, 200) } : {}\n\t}).filter((it) => it.text).slice(0, 8);\n\tif (!items.length) throw new Error(\"placeTextOverlays: no texts\");\n\tif (!imageUrl || typeof imageUrl !== \"string\") throw new Error(\"placeTextOverlays: no image\");\n\treturn normalizePlacements(parseJson(await chatCollect({\n\t\tmodel,\n\t\tsystem: PLACE_TEXT_SYSTEM,\n\t\tmax_tokens: 1500,\n\t\tmessages: [{\n\t\t\trole: \"user\",\n\t\t\tcontent: [{\n\t\t\t\ttype: \"text\",\n\t\t\t\ttext: JSON.stringify({ texts: items })\n\t\t\t}, {\n\t\t\t\ttype: \"image_url\",\n\t\t\t\timage_url: { url: imageUrl }\n\t\t\t}]\n\t\t}]\n\t})), items);\n}\nconst ZOOM_TARGET_SYSTEM = `You pick the ZOOM TARGET for a camera push-in on a still cartoon/illustration frame in a voiceover-timed video.\nYou are given the frame image and the narration words spoken over this beat (plus what the panel depicts). Return the ONE region the zoom should push INTO: the subject the narration is about — a character's face, the object being discussed, the detail that matters for this beat. Never default to the center unless the subject truly is centered.\nReturn STRICT JSON only: { \"fx\": <0-100 horizontal % of the target's center>, \"fy\": <0-100 vertical %>, \"scale\": <1.4-3 push strength — 1.8 for a normal subject, higher for a small detail>, \"why\": \"<8 words max>\" }.`;\nfunction normalizeZoomTarget(raw) {\n\tconst clamp = (v, lo, hi, dflt) => Number.isFinite(Number(v)) ? Math.max(lo, Math.min(hi, Number(v))) : dflt;\n\tif (!raw || typeof raw !== \"object\") return {\n\t\tfx: 50,\n\t\tfy: 50,\n\t\tscale: 1.8,\n\t\tfallback: true\n\t};\n\treturn {\n\t\tfx: clamp(raw.fx, 0, 100, 50),\n\t\tfy: clamp(raw.fy, 0, 100, 50),\n\t\tscale: clamp(raw.scale, 1.4, 3, 1.8),\n\t\t...raw.why ? { why: String(raw.why).slice(0, 120) } : {}\n\t};\n}\nasync function pickZoomTarget({ imageUrl, voText, panelText, model } = {}) {\n\tif (!imageUrl || typeof imageUrl !== \"string\") throw new Error(\"pickZoomTarget: no image\");\n\treturn normalizeZoomTarget(parseJson(await chatCollect({\n\t\tmodel,\n\t\tsystem: ZOOM_TARGET_SYSTEM,\n\t\tmax_tokens: 300,\n\t\tmessages: [{\n\t\t\trole: \"user\",\n\t\t\tcontent: [{\n\t\t\t\ttype: \"text\",\n\t\t\t\ttext: JSON.stringify({\n\t\t\t\t\tnarrationForThisBeat: String(voText || \"\").slice(0, 400),\n\t\t\t\t\tpanelDepicts: String(panelText || \"\").slice(0, 400)\n\t\t\t\t})\n\t\t\t}, {\n\t\t\t\ttype: \"image_url\",\n\t\t\t\timage_url: { url: imageUrl }\n\t\t\t}]\n\t\t}]\n\t})));\n}\nconst GIF_MODES = [\"replace\", \"overlay\"];\nconst GIF_PLAN_SYSTEM = `You place REACTION GIFS into a voiceover-timed video made of still image panels (Image Panel Mode). Reaction GIFs are a retention device: a quick, funny GIF dropped on a punchy beat. Your job is to read the narration + its word timing and choose a FEW beats where a reaction GIF genuinely lands.\n\nYou are given:\n- \"words\": the voiceover word timings [{ i, text, startMs, endMs }] — GROUND TRUTH. i is the word index.\n- \"strip\": the planned panels [{ panelId, wordStart, wordEnd, brief }] so you can target a panel to cover.\n- \"tone\": the content tone the user confirmed (e.g. casual, playful, heavy, off).\n\nBE CONSERVATIVE AND SPARSE — a few great GIFs beat many random ones. Good triggers ONLY: punchlines, comedic shock, relatable frustration, absurd facts, shared-emotion beats, meme-able references. NEVER place a GIF on: sincere emotion, serious stakes, factual/educational delivery, or a story's dramatic arc. When in doubt, DON'T place one. On a \"heavy\"/\"off\" tone, return few or zero beats.\n\nTwo placement MODES per beat:\n- \"replace\" (default, FREE): the GIF IS that beat's visual — no panel is generated for it. Prefer this for a standalone reaction moment.\n- \"overlay\": the GIF sits ON TOP of a generated panel, covering it for the beat (funnier when covering a real image). Set \"targetPanelId\" to the panel it covers (a real panelId from \"strip\" whose word span overlaps the beat).\n\nFor each beat pick a Giphy search INTENT (the vibe, not the literal word): e.g. narration \"I completely lost it\" → \"freaking out\", not \"lost it\". 1-4 words.\n\nOutput ONLY this JSON (no prose, no fences):\n{ \"beats\": [\n { \"mode\": \"replace\", \"targetPanelId\": null, \"gifQuery\": \"mind blown\", \"reason\": \"the absurd stat lands\", \"wordStart\": 12, \"wordEnd\": 13 },\n { \"mode\": \"overlay\", \"targetPanelId\": \"p7\", \"gifQuery\": \"awkward smile\", \"reason\": \"covers the earnest face for the joke\", \"wordStart\": 40, \"wordEnd\": 41 }\n] }\n\nTIMING: each beat maps to a short WORD-INDEX span (wordStart/wordEnd inclusive indexes into \"words\"), ideally 1-3 words on the trigger. NEVER output milliseconds. Beats must not overlap each other. Return STRICT JSON only.`;\nfunction normalizeGifBeats(raw, { wordCount = 0, strip = [], tone = null } = {}) {\n\tconst panelIds = new Set((Array.isArray(strip) ? strip : []).map((p) => String(p?.panelId || \"\")).filter(Boolean));\n\tconst beats = Array.isArray(raw?.beats) ? raw.beats : [];\n\tconst out = [];\n\tfor (const b of beats.slice(0, 40)) {\n\t\tif (!b || typeof b !== \"object\") continue;\n\t\tconst mode = GIF_MODES.includes(b.mode) ? b.mode : \"replace\";\n\t\tconst gifQuery = String(b.gifQuery || \"\").trim().slice(0, 120);\n\t\tif (!gifQuery) continue;\n\t\tlet wordStart = Math.max(0, Math.round(Number(b.wordStart) || 0));\n\t\tlet wordEnd = Math.max(wordStart, Math.round(Number(b.wordEnd) || wordStart));\n\t\tif (wordCount > 0) {\n\t\t\twordStart = Math.min(wordStart, wordCount - 1);\n\t\t\twordEnd = Math.min(Math.max(wordEnd, wordStart), wordCount - 1);\n\t\t}\n\t\tlet targetPanelId = null;\n\t\tif (mode === \"overlay\") {\n\t\t\tconst t = String(b.targetPanelId || \"\").slice(0, 40);\n\t\t\tif (!t || !panelIds.has(t)) continue;\n\t\t\ttargetPanelId = t;\n\t\t}\n\t\tout.push({\n\t\t\tmode,\n\t\t\ttargetPanelId,\n\t\t\tgifQuery,\n\t\t\treason: String(b.reason || \"\").slice(0, 200),\n\t\t\ttone: tone ? String(tone).slice(0, 40) : null,\n\t\t\twordStart,\n\t\t\twordEnd\n\t\t});\n\t}\n\tout.sort((a, b) => a.wordStart - b.wordStart || a.wordEnd - b.wordEnd);\n\tconst kept = [];\n\tlet lastEnd = -1;\n\tfor (const b of out) {\n\t\tif (b.wordStart <= lastEnd) continue;\n\t\tkept.push(b);\n\t\tlastEnd = b.wordEnd;\n\t}\n\treturn kept;\n}\nconst CANVAS_PLAN_SYSTEM = `You plan COLLAGE CANVAS panels for a voiceover-timed video (Image Panel Mode). A canvas panel is a solid background where SOURCED PHOTOS pop in one-by-one exactly when the narration names them, plus occasional short TEXT on emphasized words — the visual-essay/explainer collage format. Things keep appearing on the beat; images accumulate.\n\nYou are given:\n- \"words\": the voiceover word timings [{ i, text, startMs, endMs }] — GROUND TRUTH. i is the word index.\n- \"strip\": the planned panels [{ panelId, wordStart, wordEnd, brief }] for context.\n- \"lean\": the project's story/explainer center of gravity.\n- \"spans\": OPTIONAL. If present, plan events for EXACTLY these word spans (one canvas each — do not invent other spans). If absent, FIRST decide where canvases fit, then fill them.\n\nWHERE A CANVAS FITS (only when \"spans\" is absent): a stretch where the narration NAMES OR ENUMERATES several real-world things — people, places, products, examples, list items (\"X, Y, and Z\", \"from A to B to C\"). Several real photos beat one generated illustration there. This is an EXPLAINER device: on a story-leaning project return few or zero canvases; never break a dramatic or emotional stretch. A canvas span should cover at least ~6 words and contain at least 2 nameable things. Canvases must not overlap each other. BE SELECTIVE — zero is a fine answer.\n\nEVENTS inside a canvas:\n- image events: one per named thing, \"at\" = the word index where the narration SAYS it. \"query\": a 1-4 word stock-photo search for the LITERAL thing (a real photo of it), not a vibe. \"emphasis\": \"primary\" for the subject the stretch is about (bigger), \"support\" for the rest.\n- text events: ONLY on genuinely emphasized words/short phrases (a number, a name, a punchline word) — \"text\" is the exact word(s) said, \"at\" = the word index. At most 1-2 per canvas; zero is fine.\n- Events stay INSIDE the canvas's word span, in speaking order. Every ~2.5s of the span should have an event (that is the point of the format).\n\nTYPEWRITER BEAT (optional, use SPARINGLY — zero or one across the whole video): instead of photos, a canvas can be mode \"typewriter\" — a plain background where the EXACT narration of the span is TYPED out word-by-word with a typing sound, in sync with the voice. Reach for it ONCE for a single punchy line: a definition, a thesis sentence, a rule, a quote, a mission statement — a short stretch (~6-16 words) where seeing the words land beats any photo. NOT for lists of nameable things (those are photo canvases). A typewriter canvas has NO events (the app fills the text from the voiceover automatically): just { \"wordStart\", \"wordEnd\", \"mode\": \"typewriter\", \"reason\" }. Most videos have zero.\n\nOutput ONLY this JSON (no prose, no fences):\n{ \"canvases\": [\n { \"wordStart\": 40, \"wordEnd\": 62, \"reason\": \"narration lists four exports\",\n \"events\": [\n { \"kind\": \"image\", \"query\": \"coffee beans\", \"at\": 43, \"emphasis\": \"primary\" },\n { \"kind\": \"image\", \"query\": \"bananas\", \"at\": 48, \"emphasis\": \"support\" },\n { \"kind\": \"text\", \"text\": \"40%\", \"at\": 55 }\n ] },\n { \"wordStart\": 88, \"wordEnd\": 99, \"mode\": \"typewriter\", \"reason\": \"types the one-line thesis as it is spoken\" }\n] }\n\nTIMING: word indexes only (\"at\", \"wordStart\", \"wordEnd\" inclusive, into \"words\"). NEVER output milliseconds, positions, or coordinates. Return STRICT JSON only.`;\nfunction normalizeCanvasPlan(raw, { wordCount = 0, fixedSpans = null } = {}) {\n\tconst list = Array.isArray(raw?.canvases) ? raw.canvases : [];\n\tconst clampW = (v, lo = 0) => {\n\t\tlet n = Math.max(lo, Math.round(Number(v) || 0));\n\t\tif (wordCount > 0) n = Math.min(n, wordCount - 1);\n\t\treturn n;\n\t};\n\tconst out = [];\n\tfor (let ci = 0; ci < Math.min(list.length, 12); ci++) {\n\t\tconst c = list[ci];\n\t\tif (!c || typeof c !== \"object\") continue;\n\t\tlet wordStart = clampW(c.wordStart);\n\t\tlet wordEnd = Math.max(wordStart, clampW(c.wordEnd));\n\t\tif (Array.isArray(fixedSpans)) {\n\t\t\tconst span = fixedSpans[ci];\n\t\t\tif (!span) continue;\n\t\t\twordStart = clampW(span.wordStart);\n\t\t\twordEnd = Math.max(wordStart, clampW(span.wordEnd));\n\t\t}\n\t\tif (c.mode === \"typewriter\") {\n\t\t\tout.push({\n\t\t\t\twordStart,\n\t\t\t\twordEnd,\n\t\t\t\tmode: \"typewriter\",\n\t\t\t\treason: String(c.reason || \"\").slice(0, 200),\n\t\t\t\tevents: []\n\t\t\t});\n\t\t\tcontinue;\n\t\t}\n\t\tconst events = [];\n\t\tfor (const e of (Array.isArray(c.events) ? c.events : []).slice(0, 24)) {\n\t\t\tif (!e || typeof e !== \"object\") continue;\n\t\t\tconst at = Math.min(Math.max(clampW(e.at), wordStart), wordEnd);\n\t\t\tif (e.kind === \"image\") {\n\t\t\t\tconst query = String(e.query || \"\").trim().slice(0, 120);\n\t\t\t\tif (!query) continue;\n\t\t\t\tevents.push({\n\t\t\t\t\tkind: \"image\",\n\t\t\t\t\tquery,\n\t\t\t\t\tat,\n\t\t\t\t\temphasis: e.emphasis === \"primary\" ? \"primary\" : \"support\"\n\t\t\t\t});\n\t\t\t} else if (e.kind === \"text\") {\n\t\t\t\tconst text = String(e.text || \"\").trim().slice(0, 80);\n\t\t\t\tif (!text) continue;\n\t\t\t\tevents.push({\n\t\t\t\t\tkind: \"text\",\n\t\t\t\t\ttext,\n\t\t\t\t\tat\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t\tif (!events.some((e) => e.kind === \"image\")) continue;\n\t\tevents.sort((a, b) => a.at - b.at);\n\t\tout.push({\n\t\t\twordStart,\n\t\t\twordEnd,\n\t\t\treason: String(c.reason || \"\").slice(0, 200),\n\t\t\tevents\n\t\t});\n\t}\n\tout.sort((a, b) => a.wordStart - b.wordStart || a.wordEnd - b.wordEnd);\n\tconst kept = [];\n\tlet lastEnd = -1;\n\tfor (const c of out) {\n\t\tif (c.wordStart <= lastEnd) continue;\n\t\tkept.push(c);\n\t\tlastEnd = c.wordEnd;\n\t}\n\treturn kept;\n}\nasync function planCanvasCollages({ words, strip = [], lean = null, spans = null, model } = {}) {\n\tconst w = (Array.isArray(words) ? words : []).map((x, i) => ({\n\t\ti,\n\t\ttext: String(x.text ?? x.word ?? \"\"),\n\t\tstartMs: Math.round(Number(x.startMs ?? x.start * 1e3) || 0),\n\t\tendMs: Math.round(Number(x.endMs ?? x.end * 1e3) || 0)\n\t})).filter((x) => x.text);\n\tif (!w.length) throw new Error(\"Canvas planning needs the voiceover word timings — run the timing analysis first.\");\n\tconst stripBrief = (Array.isArray(strip) ? strip : []).slice(0, 400).map((p) => ({\n\t\tpanelId: String(p?.panelId || \"\").slice(0, 40),\n\t\twordStart: Number(p?.wordStart) || 0,\n\t\twordEnd: Number(p?.wordEnd) || 0,\n\t\tbrief: String(p?.brief || p?.scene || p?.changePrompt || \"\").slice(0, 160)\n\t})).filter((p) => p.panelId);\n\tconst fixedSpans = Array.isArray(spans) && spans.length ? spans.slice(0, 12).map((s) => ({\n\t\twordStart: Math.max(0, Math.round(Number(s?.wordStart) || 0)),\n\t\twordEnd: Math.max(0, Math.round(Number(s?.wordEnd) || 0))\n\t})) : null;\n\tconst userPayload = JSON.stringify({\n\t\twords: w,\n\t\tstrip: stripBrief,\n\t\tlean: lean || \"unspecified\",\n\t\t...fixedSpans ? { spans: fixedSpans } : {}\n\t});\n\tconst parsed = parseJson(await chatCollect({\n\t\tmodel,\n\t\tsystem: CANVAS_PLAN_SYSTEM,\n\t\tmax_tokens: 4e3,\n\t\ttimeoutMs: 9e4,\n\t\tbudgetMs: 15e4,\n\t\tmessages: [{\n\t\t\trole: \"user\",\n\t\t\tcontent: userPayload\n\t\t}]\n\t}));\n\tif (!parsed && model !== DEFAULT_MODEL) return normalizeCanvasPlan(parseJson(await chatCollect({\n\t\tmodel: DEFAULT_MODEL,\n\t\tsystem: CANVAS_PLAN_SYSTEM,\n\t\tmax_tokens: 4e3,\n\t\ttimeoutMs: 45e3,\n\t\tbudgetMs: 45e3,\n\t\tmessages: [{\n\t\t\trole: \"user\",\n\t\t\tcontent: userPayload\n\t\t}]\n\t})), {\n\t\twordCount: w.length,\n\t\tfixedSpans\n\t});\n\treturn normalizeCanvasPlan(parsed, {\n\t\twordCount: w.length,\n\t\tfixedSpans\n\t});\n}\nasync function planGifRetention({ words, strip = [], tone = null, model } = {}) {\n\tconst w = (Array.isArray(words) ? words : []).map((x, i) => ({\n\t\ti,\n\t\ttext: String(x.text ?? x.word ?? \"\"),\n\t\tstartMs: Math.round(Number(x.startMs ?? x.start * 1e3) || 0),\n\t\tendMs: Math.round(Number(x.endMs ?? x.end * 1e3) || 0)\n\t})).filter((x) => x.text);\n\tif (!w.length) throw new Error(\"GIF planning needs the voiceover word timings — run the timing analysis first.\");\n\tconst stripBrief = (Array.isArray(strip) ? strip : []).slice(0, 400).map((p) => ({\n\t\tpanelId: String(p?.panelId || \"\").slice(0, 40),\n\t\twordStart: Number(p?.wordStart) || 0,\n\t\twordEnd: Number(p?.wordEnd) || 0,\n\t\tbrief: String(p?.brief || p?.scene || p?.changePrompt || \"\").slice(0, 160)\n\t})).filter((p) => p.panelId);\n\tconst userPayload = JSON.stringify({\n\t\twords: w,\n\t\tstrip: stripBrief,\n\t\ttone: tone || \"unspecified\"\n\t});\n\treturn normalizeGifBeats(parseJson(await chatCollect({\n\t\tmodel,\n\t\tsystem: GIF_PLAN_SYSTEM,\n\t\tmax_tokens: 4e3,\n\t\tmessages: [{\n\t\t\trole: \"user\",\n\t\t\tcontent: userPayload\n\t\t}]\n\t})), {\n\t\twordCount: w.length,\n\t\tstrip: stripBrief,\n\t\ttone\n\t});\n}\nconst CONSISTENCY_FLASH = \"google/gemini-2.5-flash\";\nconst CONSISTENCY_CHUNK = 9;\nconst CONSISTENCY_SYSTEM = `You check ART-STYLE CONSISTENCY across still panels of one video. The FIRST image is the ANCHOR — the canonical art style — and the \"style\" field states the intended style in words. Judge every following image against the anchor on STYLE ONLY: line weight and outline treatment, shading/rendering technique, palette treatment, level of detail, character proportion/anatomy simplification. If the ANCHOR ITSELF clearly contradicts the stated style, judge against the STATED style instead (an off-style anchor must not bless matching drift). Different subjects, scenes, compositions, and camera angles are FINE and expected — ask only: could the same artist have drawn this? Flag ONLY clear style breaks (photorealistic vs cartoon, painterly vs flat, 3D vs 2D, radically different line or detail treatment). Return STRICT JSON only: {\"results\":[{\"panelId\":\"...\",\"consistent\":true,\"issue\":\"\"}]} — one entry per panel, in the given order, issue a short phrase only when consistent is false. No prose, no fences.`;\nfunction normalizeConsistencyResults(raw, panelIds) {\n\tconst byId = /* @__PURE__ */ new Map();\n\tfor (const r of Array.isArray(raw?.results) ? raw.results : []) {\n\t\tconst id = String(r?.panelId || \"\");\n\t\tif (!panelIds.includes(id) || byId.has(id)) continue;\n\t\tbyId.set(id, {\n\t\t\tpanelId: id,\n\t\t\tconsistent: r?.consistent !== false,\n\t\t\tissue: r?.consistent === false ? String(r?.issue || \"style differs from the anchor\").slice(0, 200) : \"\"\n\t\t});\n\t}\n\treturn panelIds.map((id) => byId.get(id) || {\n\t\tpanelId: id,\n\t\tconsistent: true,\n\t\tissue: \"\"\n\t});\n}\nasync function checkPanelConsistency({ anchorUrl, panels, styleText = \"\" } = {}) {\n\tconst list = (Array.isArray(panels) ? panels : []).filter((p) => p?.panelId && p?.url);\n\tif (!anchorUrl || !list.length) return {\n\t\tresults: [],\n\t\tskipped: true\n\t};\n\tif (!providerReady()) return {\n\t\tresults: list.map((p) => ({\n\t\t\tpanelId: p.panelId,\n\t\t\tconsistent: true,\n\t\t\tissue: \"\"\n\t\t})),\n\t\tskipped: true\n\t};\n\tconst out = [];\n\tfor (let i = 0; i < list.length; i += CONSISTENCY_CHUNK) {\n\t\tconst chunk = list.slice(i, i + CONSISTENCY_CHUNK);\n\t\tconst ids = chunk.map((p) => p.panelId);\n\t\ttry {\n\t\t\tconst text = await chatCollect({\n\t\t\t\tmodel: CONSISTENCY_FLASH,\n\t\t\t\tsystem: CONSISTENCY_SYSTEM,\n\t\t\t\tmax_tokens: 900,\n\t\t\t\tmessages: [{\n\t\t\t\t\trole: \"user\",\n\t\t\t\t\tcontent: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\t\ttext: JSON.stringify({\n\t\t\t\t\t\t\t\tstyle: String(styleText || \"\").slice(0, 600),\n\t\t\t\t\t\t\t\tpanelIdsInImageOrder: ids\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttype: \"image_url\",\n\t\t\t\t\t\t\timage_url: { url: anchorUrl }\n\t\t\t\t\t\t},\n\t\t\t\t\t\t...chunk.map((p) => ({\n\t\t\t\t\t\t\ttype: \"image_url\",\n\t\t\t\t\t\t\timage_url: { url: p.url }\n\t\t\t\t\t\t}))\n\t\t\t\t\t]\n\t\t\t\t}]\n\t\t\t});\n\t\t\tout.push(...normalizeConsistencyResults(parseJson(text), ids));\n\t\t} catch (e) {\n\t\t\tconsole.error(\"[image-panel] consistency chunk error:\", e?.message || e);\n\t\t\tout.push(...ids.map((id) => ({\n\t\t\t\tpanelId: id,\n\t\t\t\tconsistent: true,\n\t\t\t\tissue: \"\"\n\t\t\t})));\n\t\t}\n\t}\n\treturn {\n\t\tresults: out,\n\t\tskipped: false\n\t};\n}\n\n//#endregion\n//#region packages/block-platform/style-prompts.js\nconst ANALYZE_UPLOADS_PROMPT = `You are a visual development artist analyzing reference images to extract a visual style.\n\nLook at the provided images and extract:\n- Color palette and grading approach\n- Lighting philosophy (hard/soft, natural/artificial, direction)\n- Texture and grain quality\n- Depth of field and lens character\n- Overall mood and atmosphere\n- Any specific visual references or cinematic language\n\nReturn a dense style prompt (80-120 words) that captures this aesthetic precisely for use in AI image generation. Output only the style prompt, nothing else.`;\n\n//#endregion\n//#region ../../../client/node_modules/imagetracerjs/imagetracer_v1.2.6.js\nvar require_imagetracer_v1_2_6 = /* @__PURE__ */ __commonJSMin(((exports, module) => {\n\t(function() {\n\t\t\"use strict\";\n\t\tfunction ImageTracer() {\n\t\t\tvar _this = this;\n\t\t\tthis.versionnumber = \"1.2.6\", this.imageToSVG = function(url, callback, options) {\n\t\t\t\toptions = _this.checkoptions(options);\n\t\t\t\t_this.loadImage(url, function(canvas) {\n\t\t\t\t\tcallback(_this.imagedataToSVG(_this.getImgdata(canvas), options));\n\t\t\t\t}, options);\n\t\t\t}, this.imagedataToSVG = function(imgd, options) {\n\t\t\t\toptions = _this.checkoptions(options);\n\t\t\t\tvar td = _this.imagedataToTracedata(imgd, options);\n\t\t\t\treturn _this.getsvgstring(td, options);\n\t\t\t}, this.imageToTracedata = function(url, callback, options) {\n\t\t\t\toptions = _this.checkoptions(options);\n\t\t\t\t_this.loadImage(url, function(canvas) {\n\t\t\t\t\tcallback(_this.imagedataToTracedata(_this.getImgdata(canvas), options));\n\t\t\t\t}, options);\n\t\t\t}, this.imagedataToTracedata = function(imgd, options) {\n\t\t\t\toptions = _this.checkoptions(options);\n\t\t\t\tvar ii = _this.colorquantization(imgd, options);\n\t\t\t\tif (options.layering === 0) {\n\t\t\t\t\tvar tracedata = {\n\t\t\t\t\t\tlayers: [],\n\t\t\t\t\t\tpalette: ii.palette,\n\t\t\t\t\t\twidth: ii.array[0].length - 2,\n\t\t\t\t\t\theight: ii.array.length - 2\n\t\t\t\t\t};\n\t\t\t\t\tfor (var colornum = 0; colornum < ii.palette.length; colornum++) {\n\t\t\t\t\t\tvar tracedlayer = _this.batchtracepaths(_this.internodes(_this.pathscan(_this.layeringstep(ii, colornum), options.pathomit), options), options.ltres, options.qtres);\n\t\t\t\t\t\ttracedata.layers.push(tracedlayer);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tvar ls = _this.layering(ii);\n\t\t\t\t\tif (options.layercontainerid) _this.drawLayers(ls, _this.specpalette, options.scale, options.layercontainerid);\n\t\t\t\t\tvar bps = _this.batchpathscan(ls, options.pathomit);\n\t\t\t\t\tvar bis = _this.batchinternodes(bps, options);\n\t\t\t\t\tvar tracedata = {\n\t\t\t\t\t\tlayers: _this.batchtracelayers(bis, options.ltres, options.qtres),\n\t\t\t\t\t\tpalette: ii.palette,\n\t\t\t\t\t\twidth: imgd.width,\n\t\t\t\t\t\theight: imgd.height\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t\treturn tracedata;\n\t\t\t}, this.optionpresets = {\n\t\t\t\t\"default\": {\n\t\t\t\t\tcorsenabled: false,\n\t\t\t\t\tltres: 1,\n\t\t\t\t\tqtres: 1,\n\t\t\t\t\tpathomit: 8,\n\t\t\t\t\trightangleenhance: true,\n\t\t\t\t\tcolorsampling: 2,\n\t\t\t\t\tnumberofcolors: 16,\n\t\t\t\t\tmincolorratio: 0,\n\t\t\t\t\tcolorquantcycles: 3,\n\t\t\t\t\tlayering: 0,\n\t\t\t\t\tstrokewidth: 1,\n\t\t\t\t\tlinefilter: false,\n\t\t\t\t\tscale: 1,\n\t\t\t\t\troundcoords: 1,\n\t\t\t\t\tviewbox: false,\n\t\t\t\t\tdesc: false,\n\t\t\t\t\tlcpr: 0,\n\t\t\t\t\tqcpr: 0,\n\t\t\t\t\tblurradius: 0,\n\t\t\t\t\tblurdelta: 20\n\t\t\t\t},\n\t\t\t\t\"posterized1\": {\n\t\t\t\t\tcolorsampling: 0,\n\t\t\t\t\tnumberofcolors: 2\n\t\t\t\t},\n\t\t\t\t\"posterized2\": {\n\t\t\t\t\tnumberofcolors: 4,\n\t\t\t\t\tblurradius: 5\n\t\t\t\t},\n\t\t\t\t\"curvy\": {\n\t\t\t\t\tltres: .01,\n\t\t\t\t\tlinefilter: true,\n\t\t\t\t\trightangleenhance: false\n\t\t\t\t},\n\t\t\t\t\"sharp\": {\n\t\t\t\t\tqtres: .01,\n\t\t\t\t\tlinefilter: false\n\t\t\t\t},\n\t\t\t\t\"detailed\": {\n\t\t\t\t\tpathomit: 0,\n\t\t\t\t\troundcoords: 2,\n\t\t\t\t\tltres: .5,\n\t\t\t\t\tqtres: .5,\n\t\t\t\t\tnumberofcolors: 64\n\t\t\t\t},\n\t\t\t\t\"smoothed\": {\n\t\t\t\t\tblurradius: 5,\n\t\t\t\t\tblurdelta: 64\n\t\t\t\t},\n\t\t\t\t\"grayscale\": {\n\t\t\t\t\tcolorsampling: 0,\n\t\t\t\t\tcolorquantcycles: 1,\n\t\t\t\t\tnumberofcolors: 7\n\t\t\t\t},\n\t\t\t\t\"fixedpalette\": {\n\t\t\t\t\tcolorsampling: 0,\n\t\t\t\t\tcolorquantcycles: 1,\n\t\t\t\t\tnumberofcolors: 27\n\t\t\t\t},\n\t\t\t\t\"randomsampling1\": {\n\t\t\t\t\tcolorsampling: 1,\n\t\t\t\t\tnumberofcolors: 8\n\t\t\t\t},\n\t\t\t\t\"randomsampling2\": {\n\t\t\t\t\tcolorsampling: 1,\n\t\t\t\t\tnumberofcolors: 64\n\t\t\t\t},\n\t\t\t\t\"artistic1\": {\n\t\t\t\t\tcolorsampling: 0,\n\t\t\t\t\tcolorquantcycles: 1,\n\t\t\t\t\tpathomit: 0,\n\t\t\t\t\tblurradius: 5,\n\t\t\t\t\tblurdelta: 64,\n\t\t\t\t\tltres: .01,\n\t\t\t\t\tlinefilter: true,\n\t\t\t\t\tnumberofcolors: 16,\n\t\t\t\t\tstrokewidth: 2\n\t\t\t\t},\n\t\t\t\t\"artistic2\": {\n\t\t\t\t\tqtres: .01,\n\t\t\t\t\tcolorsampling: 0,\n\t\t\t\t\tcolorquantcycles: 1,\n\t\t\t\t\tnumberofcolors: 4,\n\t\t\t\t\tstrokewidth: 0\n\t\t\t\t},\n\t\t\t\t\"artistic3\": {\n\t\t\t\t\tqtres: 10,\n\t\t\t\t\tltres: 10,\n\t\t\t\t\tnumberofcolors: 8\n\t\t\t\t},\n\t\t\t\t\"artistic4\": {\n\t\t\t\t\tqtres: 10,\n\t\t\t\t\tltres: 10,\n\t\t\t\t\tnumberofcolors: 64,\n\t\t\t\t\tblurradius: 5,\n\t\t\t\t\tblurdelta: 256,\n\t\t\t\t\tstrokewidth: 2\n\t\t\t\t},\n\t\t\t\t\"posterized3\": {\n\t\t\t\t\tltres: 1,\n\t\t\t\t\tqtres: 1,\n\t\t\t\t\tpathomit: 20,\n\t\t\t\t\trightangleenhance: true,\n\t\t\t\t\tcolorsampling: 0,\n\t\t\t\t\tnumberofcolors: 3,\n\t\t\t\t\tmincolorratio: 0,\n\t\t\t\t\tcolorquantcycles: 3,\n\t\t\t\t\tblurradius: 3,\n\t\t\t\t\tblurdelta: 20,\n\t\t\t\t\tstrokewidth: 0,\n\t\t\t\t\tlinefilter: false,\n\t\t\t\t\troundcoords: 1,\n\t\t\t\t\tpal: [{\n\t\t\t\t\t\tr: 0,\n\t\t\t\t\t\tg: 0,\n\t\t\t\t\t\tb: 100,\n\t\t\t\t\t\ta: 255\n\t\t\t\t\t}, {\n\t\t\t\t\t\tr: 255,\n\t\t\t\t\t\tg: 255,\n\t\t\t\t\t\tb: 255,\n\t\t\t\t\t\ta: 255\n\t\t\t\t\t}]\n\t\t\t\t}\n\t\t\t}, this.checkoptions = function(options) {\n\t\t\t\toptions = options || {};\n\t\t\t\tif (typeof options === \"string\") {\n\t\t\t\t\toptions = options.toLowerCase();\n\t\t\t\t\tif (_this.optionpresets[options]) options = _this.optionpresets[options];\n\t\t\t\t\telse options = {};\n\t\t\t\t}\n\t\t\t\tvar ok = Object.keys(_this.optionpresets[\"default\"]);\n\t\t\t\tfor (var k = 0; k < ok.length; k++) if (!options.hasOwnProperty(ok[k])) options[ok[k]] = _this.optionpresets[\"default\"][ok[k]];\n\t\t\t\treturn options;\n\t\t\t}, this.colorquantization = function(imgd, options) {\n\t\t\t\tvar arr = [], idx = 0, cd, cdl, ci, paletteacc = [], pixelnum = imgd.width * imgd.height, i, j, k, cnt, palette;\n\t\t\t\tif (imgd.data.length < pixelnum * 4) {\n\t\t\t\t\tvar newimgddata = new Uint8ClampedArray(pixelnum * 4);\n\t\t\t\t\tfor (var pxcnt = 0; pxcnt < pixelnum; pxcnt++) {\n\t\t\t\t\t\tnewimgddata[pxcnt * 4] = imgd.data[pxcnt * 3];\n\t\t\t\t\t\tnewimgddata[pxcnt * 4 + 1] = imgd.data[pxcnt * 3 + 1];\n\t\t\t\t\t\tnewimgddata[pxcnt * 4 + 2] = imgd.data[pxcnt * 3 + 2];\n\t\t\t\t\t\tnewimgddata[pxcnt * 4 + 3] = 255;\n\t\t\t\t\t}\n\t\t\t\t\timgd.data = newimgddata;\n\t\t\t\t}\n\t\t\t\tfor (j = 0; j < imgd.height + 2; j++) {\n\t\t\t\t\tarr[j] = [];\n\t\t\t\t\tfor (i = 0; i < imgd.width + 2; i++) arr[j][i] = -1;\n\t\t\t\t}\n\t\t\t\tif (options.pal) palette = options.pal;\n\t\t\t\telse if (options.colorsampling === 0) palette = _this.generatepalette(options.numberofcolors);\n\t\t\t\telse if (options.colorsampling === 1) palette = _this.samplepalette(options.numberofcolors, imgd);\n\t\t\t\telse palette = _this.samplepalette2(options.numberofcolors, imgd);\n\t\t\t\tif (options.blurradius > 0) imgd = _this.blur(imgd, options.blurradius, options.blurdelta);\n\t\t\t\tfor (cnt = 0; cnt < options.colorquantcycles; cnt++) {\n\t\t\t\t\tif (cnt > 0) for (k = 0; k < palette.length; k++) {\n\t\t\t\t\t\tif (paletteacc[k].n > 0) palette[k] = {\n\t\t\t\t\t\t\tr: Math.floor(paletteacc[k].r / paletteacc[k].n),\n\t\t\t\t\t\t\tg: Math.floor(paletteacc[k].g / paletteacc[k].n),\n\t\t\t\t\t\t\tb: Math.floor(paletteacc[k].b / paletteacc[k].n),\n\t\t\t\t\t\t\ta: Math.floor(paletteacc[k].a / paletteacc[k].n)\n\t\t\t\t\t\t};\n\t\t\t\t\t\tif (paletteacc[k].n / pixelnum < options.mincolorratio && cnt < options.colorquantcycles - 1) palette[k] = {\n\t\t\t\t\t\t\tr: Math.floor(Math.random() * 255),\n\t\t\t\t\t\t\tg: Math.floor(Math.random() * 255),\n\t\t\t\t\t\t\tb: Math.floor(Math.random() * 255),\n\t\t\t\t\t\t\ta: Math.floor(Math.random() * 255)\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\t\t\t\t\tfor (i = 0; i < palette.length; i++) paletteacc[i] = {\n\t\t\t\t\t\tr: 0,\n\t\t\t\t\t\tg: 0,\n\t\t\t\t\t\tb: 0,\n\t\t\t\t\t\ta: 0,\n\t\t\t\t\t\tn: 0\n\t\t\t\t\t};\n\t\t\t\t\tfor (j = 0; j < imgd.height; j++) for (i = 0; i < imgd.width; i++) {\n\t\t\t\t\t\tidx = (j * imgd.width + i) * 4;\n\t\t\t\t\t\tci = 0;\n\t\t\t\t\t\tcdl = 1024;\n\t\t\t\t\t\tfor (k = 0; k < palette.length; k++) {\n\t\t\t\t\t\t\tcd = Math.abs(palette[k].r - imgd.data[idx]) + Math.abs(palette[k].g - imgd.data[idx + 1]) + Math.abs(palette[k].b - imgd.data[idx + 2]) + Math.abs(palette[k].a - imgd.data[idx + 3]);\n\t\t\t\t\t\t\tif (cd < cdl) {\n\t\t\t\t\t\t\t\tcdl = cd;\n\t\t\t\t\t\t\t\tci = k;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tpaletteacc[ci].r += imgd.data[idx];\n\t\t\t\t\t\tpaletteacc[ci].g += imgd.data[idx + 1];\n\t\t\t\t\t\tpaletteacc[ci].b += imgd.data[idx + 2];\n\t\t\t\t\t\tpaletteacc[ci].a += imgd.data[idx + 3];\n\t\t\t\t\t\tpaletteacc[ci].n++;\n\t\t\t\t\t\tarr[j + 1][i + 1] = ci;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn {\n\t\t\t\t\tarray: arr,\n\t\t\t\t\tpalette\n\t\t\t\t};\n\t\t\t}, this.samplepalette = function(numberofcolors, imgd) {\n\t\t\t\tvar idx, palette = [];\n\t\t\t\tfor (var i = 0; i < numberofcolors; i++) {\n\t\t\t\t\tidx = Math.floor(Math.random() * imgd.data.length / 4) * 4;\n\t\t\t\t\tpalette.push({\n\t\t\t\t\t\tr: imgd.data[idx],\n\t\t\t\t\t\tg: imgd.data[idx + 1],\n\t\t\t\t\t\tb: imgd.data[idx + 2],\n\t\t\t\t\t\ta: imgd.data[idx + 3]\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\treturn palette;\n\t\t\t}, this.samplepalette2 = function(numberofcolors, imgd) {\n\t\t\t\tvar idx, palette = [], ni = Math.ceil(Math.sqrt(numberofcolors)), nj = Math.ceil(numberofcolors / ni), vx = imgd.width / (ni + 1), vy = imgd.height / (nj + 1);\n\t\t\t\tfor (var j = 0; j < nj; j++) for (var i = 0; i < ni; i++) if (palette.length === numberofcolors) break;\n\t\t\t\telse {\n\t\t\t\t\tidx = Math.floor((j + 1) * vy * imgd.width + (i + 1) * vx) * 4;\n\t\t\t\t\tpalette.push({\n\t\t\t\t\t\tr: imgd.data[idx],\n\t\t\t\t\t\tg: imgd.data[idx + 1],\n\t\t\t\t\t\tb: imgd.data[idx + 2],\n\t\t\t\t\t\ta: imgd.data[idx + 3]\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\treturn palette;\n\t\t\t}, this.generatepalette = function(numberofcolors) {\n\t\t\t\tvar palette = [], rcnt, gcnt, bcnt;\n\t\t\t\tif (numberofcolors < 8) {\n\t\t\t\t\tvar graystep = Math.floor(255 / (numberofcolors - 1));\n\t\t\t\t\tfor (var i = 0; i < numberofcolors; i++) palette.push({\n\t\t\t\t\t\tr: i * graystep,\n\t\t\t\t\t\tg: i * graystep,\n\t\t\t\t\t\tb: i * graystep,\n\t\t\t\t\t\ta: 255\n\t\t\t\t\t});\n\t\t\t\t} else {\n\t\t\t\t\tvar colorqnum = Math.floor(Math.pow(numberofcolors, 1 / 3)), colorstep = Math.floor(255 / (colorqnum - 1)), rndnum = numberofcolors - colorqnum * colorqnum * colorqnum;\n\t\t\t\t\tfor (rcnt = 0; rcnt < colorqnum; rcnt++) for (gcnt = 0; gcnt < colorqnum; gcnt++) for (bcnt = 0; bcnt < colorqnum; bcnt++) palette.push({\n\t\t\t\t\t\tr: rcnt * colorstep,\n\t\t\t\t\t\tg: gcnt * colorstep,\n\t\t\t\t\t\tb: bcnt * colorstep,\n\t\t\t\t\t\ta: 255\n\t\t\t\t\t});\n\t\t\t\t\tfor (rcnt = 0; rcnt < rndnum; rcnt++) palette.push({\n\t\t\t\t\t\tr: Math.floor(Math.random() * 255),\n\t\t\t\t\t\tg: Math.floor(Math.random() * 255),\n\t\t\t\t\t\tb: Math.floor(Math.random() * 255),\n\t\t\t\t\t\ta: Math.floor(Math.random() * 255)\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\treturn palette;\n\t\t\t}, this.layering = function(ii) {\n\t\t\t\tvar layers = [], val = 0, ah = ii.array.length, aw = ii.array[0].length, n1, n2, n3, n4, n5, n6, n7, n8, i, j, k = 0;\n\t\t\t\tfor (; k < ii.palette.length; k++) {\n\t\t\t\t\tlayers[k] = [];\n\t\t\t\t\tfor (j = 0; j < ah; j++) {\n\t\t\t\t\t\tlayers[k][j] = [];\n\t\t\t\t\t\tfor (i = 0; i < aw; i++) layers[k][j][i] = 0;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tfor (j = 1; j < ah - 1; j++) for (i = 1; i < aw - 1; i++) {\n\t\t\t\t\tval = ii.array[j][i];\n\t\t\t\t\tn1 = ii.array[j - 1][i - 1] === val ? 1 : 0;\n\t\t\t\t\tn2 = ii.array[j - 1][i] === val ? 1 : 0;\n\t\t\t\t\tn3 = ii.array[j - 1][i + 1] === val ? 1 : 0;\n\t\t\t\t\tn4 = ii.array[j][i - 1] === val ? 1 : 0;\n\t\t\t\t\tn5 = ii.array[j][i + 1] === val ? 1 : 0;\n\t\t\t\t\tn6 = ii.array[j + 1][i - 1] === val ? 1 : 0;\n\t\t\t\t\tn7 = ii.array[j + 1][i] === val ? 1 : 0;\n\t\t\t\t\tn8 = ii.array[j + 1][i + 1] === val ? 1 : 0;\n\t\t\t\t\tlayers[val][j + 1][i + 1] = 1 + n5 * 2 + n8 * 4 + n7 * 8;\n\t\t\t\t\tif (!n4) layers[val][j + 1][i] = 2 + n7 * 4 + n6 * 8;\n\t\t\t\t\tif (!n2) layers[val][j][i + 1] = 0 + n3 * 2 + n5 * 4 + 8;\n\t\t\t\t\tif (!n1) layers[val][j][i] = 0 + n2 * 2 + 4 + n4 * 8;\n\t\t\t\t}\n\t\t\t\treturn layers;\n\t\t\t}, this.layeringstep = function(ii, cnum) {\n\t\t\t\tvar layer = [], ah = ii.array.length, aw = ii.array[0].length, i, j = 0;\n\t\t\t\tfor (; j < ah; j++) {\n\t\t\t\t\tlayer[j] = [];\n\t\t\t\t\tfor (i = 0; i < aw; i++) layer[j][i] = 0;\n\t\t\t\t}\n\t\t\t\tfor (j = 1; j < ah; j++) for (i = 1; i < aw; i++) layer[j][i] = (ii.array[j - 1][i - 1] === cnum ? 1 : 0) + (ii.array[j - 1][i] === cnum ? 2 : 0) + (ii.array[j][i - 1] === cnum ? 8 : 0) + (ii.array[j][i] === cnum ? 4 : 0);\n\t\t\t\treturn layer;\n\t\t\t}, this.pointinpoly = function(p, pa) {\n\t\t\t\tvar isin = false;\n\t\t\t\tfor (var i = 0, j = pa.length - 1; i < pa.length; j = i++) isin = pa[i].y > p.y !== pa[j].y > p.y && p.x < (pa[j].x - pa[i].x) * (p.y - pa[i].y) / (pa[j].y - pa[i].y) + pa[i].x ? !isin : isin;\n\t\t\t\treturn isin;\n\t\t\t}, this.pathscan_combined_lookup = [\n\t\t\t\t[\n\t\t\t\t\t[\n\t\t\t\t\t\t-1,\n\t\t\t\t\t\t-1,\n\t\t\t\t\t\t-1,\n\t\t\t\t\t\t-1\n\t\t\t\t\t],\n\t\t\t\t\t[\n\t\t\t\t\t\t-1,\n\t\t\t\t\t\t-1,\n\t\t\t\t\t\t-1,\n\t\t\t\t\t\t-1\n\t\t\t\t\t],\n\t\t\t\t\t[\n\t\t\t\t\t\t-1,\n\t\t\t\t\t\t-1,\n\t\t\t\t\t\t-1,\n\t\t\t\t\t\t-1\n\t\t\t\t\t],\n\t\t\t\t\t[\n\t\t\t\t\t\t-1,\n\t\t\t\t\t\t-1,\n\t\t\t\t\t\t-1,\n\t\t\t\t\t\t-1\n\t\t\t\t\t]\n\t\t\t\t],\n\t\t\t\t[\n\t\t\t\t\t[\n\t\t\t\t\t\t0,\n\t\t\t\t\t\t1,\n\t\t\t\t\t\t0,\n\t\t\t\t\t\t-1\n\t\t\t\t\t],\n\t\t\t\t\t[\n\t\t\t\t\t\t-1,\n\t\t\t\t\t\t-1,\n\t\t\t\t\t\t-1,\n\t\t\t\t\t\t-1\n\t\t\t\t\t],\n\t\t\t\t\t[\n\t\t\t\t\t\t-1,\n\t\t\t\t\t\t-1,\n\t\t\t\t\t\t-1,\n\t\t\t\t\t\t-1\n\t\t\t\t\t],\n\t\t\t\t\t[\n\t\t\t\t\t\t0,\n\t\t\t\t\t\t2,\n\t\t\t\t\t\t-1,\n\t\t\t\t\t\t0\n\t\t\t\t\t]\n\t\t\t\t],\n\t\t\t\t[\n\t\t\t\t\t[\n\t\t\t\t\t\t-1,\n\t\t\t\t\t\t-1,\n\t\t\t\t\t\t-1,\n\t\t\t\t\t\t-1\n\t\t\t\t\t],\n\t\t\t\t\t[\n\t\t\t\t\t\t-1,\n\t\t\t\t\t\t-1,\n\t\t\t\t\t\t-1,\n\t\t\t\t\t\t-1\n\t\t\t\t\t],\n\t\t\t\t\t[\n\t\t\t\t\t\t0,\n\t\t\t\t\t\t1,\n\t\t\t\t\t\t0,\n\t\t\t\t\t\t-1\n\t\t\t\t\t],\n\t\t\t\t\t[\n\t\t\t\t\t\t0,\n\t\t\t\t\t\t0,\n\t\t\t\t\t\t1,\n\t\t\t\t\t\t0\n\t\t\t\t\t]\n\t\t\t\t],\n\t\t\t\t[\n\t\t\t\t\t[\n\t\t\t\t\t\t0,\n\t\t\t\t\t\t0,\n\t\t\t\t\t\t1,\n\t\t\t\t\t\t0\n\t\t\t\t\t],\n\t\t\t\t\t[\n\t\t\t\t\t\t-1,\n\t\t\t\t\t\t-1,\n\t\t\t\t\t\t-1,\n\t\t\t\t\t\t-1\n\t\t\t\t\t],\n\t\t\t\t\t[\n\t\t\t\t\t\t0,\n\t\t\t\t\t\t2,\n\t\t\t\t\t\t-1,\n\t\t\t\t\t\t0\n\t\t\t\t\t],\n\t\t\t\t\t[\n\t\t\t\t\t\t-1,\n\t\t\t\t\t\t-1,\n\t\t\t\t\t\t-1,\n\t\t\t\t\t\t-1\n\t\t\t\t\t]\n\t\t\t\t],\n\t\t\t\t[\n\t\t\t\t\t[\n\t\t\t\t\t\t-1,\n\t\t\t\t\t\t-1,\n\t\t\t\t\t\t-1,\n\t\t\t\t\t\t-1\n\t\t\t\t\t],\n\t\t\t\t\t[\n\t\t\t\t\t\t0,\n\t\t\t\t\t\t0,\n\t\t\t\t\t\t1,\n\t\t\t\t\t\t0\n\t\t\t\t\t],\n\t\t\t\t\t[\n\t\t\t\t\t\t0,\n\t\t\t\t\t\t3,\n\t\t\t\t\t\t0,\n\t\t\t\t\t\t1\n\t\t\t\t\t],\n\t\t\t\t\t[\n\t\t\t\t\t\t-1,\n\t\t\t\t\t\t-1,\n\t\t\t\t\t\t-1,\n\t\t\t\t\t\t-1\n\t\t\t\t\t]\n\t\t\t\t],\n\t\t\t\t[\n\t\t\t\t\t[\n\t\t\t\t\t\t13,\n\t\t\t\t\t\t3,\n\t\t\t\t\t\t0,\n\t\t\t\t\t\t1\n\t\t\t\t\t],\n\t\t\t\t\t[\n\t\t\t\t\t\t13,\n\t\t\t\t\t\t2,\n\t\t\t\t\t\t-1,\n\t\t\t\t\t\t0\n\t\t\t\t\t],\n\t\t\t\t\t[\n\t\t\t\t\t\t7,\n\t\t\t\t\t\t1,\n\t\t\t\t\t\t0,\n\t\t\t\t\t\t-1\n\t\t\t\t\t],\n\t\t\t\t\t[\n\t\t\t\t\t\t7,\n\t\t\t\t\t\t0,\n\t\t\t\t\t\t1,\n\t\t\t\t\t\t0\n\t\t\t\t\t]\n\t\t\t\t],\n\t\t\t\t[\n\t\t\t\t\t[\n\t\t\t\t\t\t-1,\n\t\t\t\t\t\t-1,\n\t\t\t\t\t\t-1,\n\t\t\t\t\t\t-1\n\t\t\t\t\t],\n\t\t\t\t\t[\n\t\t\t\t\t\t0,\n\t\t\t\t\t\t1,\n\t\t\t\t\t\t0,\n\t\t\t\t\t\t-1\n\t\t\t\t\t],\n\t\t\t\t\t[\n\t\t\t\t\t\t-1,\n\t\t\t\t\t\t-1,\n\t\t\t\t\t\t-1,\n\t\t\t\t\t\t-1\n\t\t\t\t\t],\n\t\t\t\t\t[\n\t\t\t\t\t\t0,\n\t\t\t\t\t\t3,\n\t\t\t\t\t\t0,\n\t\t\t\t\t\t1\n\t\t\t\t\t]\n\t\t\t\t],\n\t\t\t\t[\n\t\t\t\t\t[\n\t\t\t\t\t\t0,\n\t\t\t\t\t\t3,\n\t\t\t\t\t\t0,\n\t\t\t\t\t\t1\n\t\t\t\t\t],\n\t\t\t\t\t[\n\t\t\t\t\t\t0,\n\t\t\t\t\t\t2,\n\t\t\t\t\t\t-1,\n\t\t\t\t\t\t0\n\t\t\t\t\t],\n\t\t\t\t\t[\n\t\t\t\t\t\t-1,\n\t\t\t\t\t\t-1,\n\t\t\t\t\t\t-1,\n\t\t\t\t\t\t-1\n\t\t\t\t\t],\n\t\t\t\t\t[\n\t\t\t\t\t\t-1,\n\t\t\t\t\t\t-1,\n\t\t\t\t\t\t-1,\n\t\t\t\t\t\t-1\n\t\t\t\t\t]\n\t\t\t\t],\n\t\t\t\t[\n\t\t\t\t\t[\n\t\t\t\t\t\t0,\n\t\t\t\t\t\t3,\n\t\t\t\t\t\t0,\n\t\t\t\t\t\t1\n\t\t\t\t\t],\n\t\t\t\t\t[\n\t\t\t\t\t\t0,\n\t\t\t\t\t\t2,\n\t\t\t\t\t\t-1,\n\t\t\t\t\t\t0\n\t\t\t\t\t],\n\t\t\t\t\t[\n\t\t\t\t\t\t-1,\n\t\t\t\t\t\t-1,\n\t\t\t\t\t\t-1,\n\t\t\t\t\t\t-1\n\t\t\t\t\t],\n\t\t\t\t\t[\n\t\t\t\t\t\t-1,\n\t\t\t\t\t\t-1,\n\t\t\t\t\t\t-1,\n\t\t\t\t\t\t-1\n\t\t\t\t\t]\n\t\t\t\t],\n\t\t\t\t[\n\t\t\t\t\t[\n\t\t\t\t\t\t-1,\n\t\t\t\t\t\t-1,\n\t\t\t\t\t\t-1,\n\t\t\t\t\t\t-1\n\t\t\t\t\t],\n\t\t\t\t\t[\n\t\t\t\t\t\t0,\n\t\t\t\t\t\t1,\n\t\t\t\t\t\t0,\n\t\t\t\t\t\t-1\n\t\t\t\t\t],\n\t\t\t\t\t[\n\t\t\t\t\t\t-1,\n\t\t\t\t\t\t-1,\n\t\t\t\t\t\t-1,\n\t\t\t\t\t\t-1\n\t\t\t\t\t],\n\t\t\t\t\t[\n\t\t\t\t\t\t0,\n\t\t\t\t\t\t3,\n\t\t\t\t\t\t0,\n\t\t\t\t\t\t1\n\t\t\t\t\t]\n\t\t\t\t],\n\t\t\t\t[\n\t\t\t\t\t[\n\t\t\t\t\t\t11,\n\t\t\t\t\t\t1,\n\t\t\t\t\t\t0,\n\t\t\t\t\t\t-1\n\t\t\t\t\t],\n\t\t\t\t\t[\n\t\t\t\t\t\t14,\n\t\t\t\t\t\t0,\n\t\t\t\t\t\t1,\n\t\t\t\t\t\t0\n\t\t\t\t\t],\n\t\t\t\t\t[\n\t\t\t\t\t\t14,\n\t\t\t\t\t\t3,\n\t\t\t\t\t\t0,\n\t\t\t\t\t\t1\n\t\t\t\t\t],\n\t\t\t\t\t[\n\t\t\t\t\t\t11,\n\t\t\t\t\t\t2,\n\t\t\t\t\t\t-1,\n\t\t\t\t\t\t0\n\t\t\t\t\t]\n\t\t\t\t],\n\t\t\t\t[\n\t\t\t\t\t[\n\t\t\t\t\t\t-1,\n\t\t\t\t\t\t-1,\n\t\t\t\t\t\t-1,\n\t\t\t\t\t\t-1\n\t\t\t\t\t],\n\t\t\t\t\t[\n\t\t\t\t\t\t0,\n\t\t\t\t\t\t0,\n\t\t\t\t\t\t1,\n\t\t\t\t\t\t0\n\t\t\t\t\t],\n\t\t\t\t\t[\n\t\t\t\t\t\t0,\n\t\t\t\t\t\t3,\n\t\t\t\t\t\t0,\n\t\t\t\t\t\t1\n\t\t\t\t\t],\n\t\t\t\t\t[\n\t\t\t\t\t\t-1,\n\t\t\t\t\t\t-1,\n\t\t\t\t\t\t-1,\n\t\t\t\t\t\t-1\n\t\t\t\t\t]\n\t\t\t\t],\n\t\t\t\t[\n\t\t\t\t\t[\n\t\t\t\t\t\t0,\n\t\t\t\t\t\t0,\n\t\t\t\t\t\t1,\n\t\t\t\t\t\t0\n\t\t\t\t\t],\n\t\t\t\t\t[\n\t\t\t\t\t\t-1,\n\t\t\t\t\t\t-1,\n\t\t\t\t\t\t-1,\n\t\t\t\t\t\t-1\n\t\t\t\t\t],\n\t\t\t\t\t[\n\t\t\t\t\t\t0,\n\t\t\t\t\t\t2,\n\t\t\t\t\t\t-1,\n\t\t\t\t\t\t0\n\t\t\t\t\t],\n\t\t\t\t\t[\n\t\t\t\t\t\t-1,\n\t\t\t\t\t\t-1,\n\t\t\t\t\t\t-1,\n\t\t\t\t\t\t-1\n\t\t\t\t\t]\n\t\t\t\t],\n\t\t\t\t[\n\t\t\t\t\t[\n\t\t\t\t\t\t-1,\n\t\t\t\t\t\t-1,\n\t\t\t\t\t\t-1,\n\t\t\t\t\t\t-1\n\t\t\t\t\t],\n\t\t\t\t\t[\n\t\t\t\t\t\t-1,\n\t\t\t\t\t\t-1,\n\t\t\t\t\t\t-1,\n\t\t\t\t\t\t-1\n\t\t\t\t\t],\n\t\t\t\t\t[\n\t\t\t\t\t\t0,\n\t\t\t\t\t\t1,\n\t\t\t\t\t\t0,\n\t\t\t\t\t\t-1\n\t\t\t\t\t],\n\t\t\t\t\t[\n\t\t\t\t\t\t0,\n\t\t\t\t\t\t0,\n\t\t\t\t\t\t1,\n\t\t\t\t\t\t0\n\t\t\t\t\t]\n\t\t\t\t],\n\t\t\t\t[\n\t\t\t\t\t[\n\t\t\t\t\t\t0,\n\t\t\t\t\t\t1,\n\t\t\t\t\t\t0,\n\t\t\t\t\t\t-1\n\t\t\t\t\t],\n\t\t\t\t\t[\n\t\t\t\t\t\t-1,\n\t\t\t\t\t\t-1,\n\t\t\t\t\t\t-1,\n\t\t\t\t\t\t-1\n\t\t\t\t\t],\n\t\t\t\t\t[\n\t\t\t\t\t\t-1,\n\t\t\t\t\t\t-1,\n\t\t\t\t\t\t-1,\n\t\t\t\t\t\t-1\n\t\t\t\t\t],\n\t\t\t\t\t[\n\t\t\t\t\t\t0,\n\t\t\t\t\t\t2,\n\t\t\t\t\t\t-1,\n\t\t\t\t\t\t0\n\t\t\t\t\t]\n\t\t\t\t],\n\t\t\t\t[\n\t\t\t\t\t[\n\t\t\t\t\t\t-1,\n\t\t\t\t\t\t-1,\n\t\t\t\t\t\t-1,\n\t\t\t\t\t\t-1\n\t\t\t\t\t],\n\t\t\t\t\t[\n\t\t\t\t\t\t-1,\n\t\t\t\t\t\t-1,\n\t\t\t\t\t\t-1,\n\t\t\t\t\t\t-1\n\t\t\t\t\t],\n\t\t\t\t\t[\n\t\t\t\t\t\t-1,\n\t\t\t\t\t\t-1,\n\t\t\t\t\t\t-1,\n\t\t\t\t\t\t-1\n\t\t\t\t\t],\n\t\t\t\t\t[\n\t\t\t\t\t\t-1,\n\t\t\t\t\t\t-1,\n\t\t\t\t\t\t-1,\n\t\t\t\t\t\t-1\n\t\t\t\t\t]\n\t\t\t\t]\n\t\t\t], this.pathscan = function(arr, pathomit) {\n\t\t\t\tvar paths = [], pacnt = 0, pcnt = 0, px = 0, py = 0, w = arr[0].length, h = arr.length, dir = 0, pathfinished = true, holepath = false, lookuprow;\n\t\t\t\tfor (var j = 0; j < h; j++) for (var i = 0; i < w; i++) if (arr[j][i] == 4 || arr[j][i] == 11) {\n\t\t\t\t\tpx = i;\n\t\t\t\t\tpy = j;\n\t\t\t\t\tpaths[pacnt] = {};\n\t\t\t\t\tpaths[pacnt].points = [];\n\t\t\t\t\tpaths[pacnt].boundingbox = [\n\t\t\t\t\t\tpx,\n\t\t\t\t\t\tpy,\n\t\t\t\t\t\tpx,\n\t\t\t\t\t\tpy\n\t\t\t\t\t];\n\t\t\t\t\tpaths[pacnt].holechildren = [];\n\t\t\t\t\tpathfinished = false;\n\t\t\t\t\tpcnt = 0;\n\t\t\t\t\tholepath = arr[j][i] == 11;\n\t\t\t\t\tdir = 1;\n\t\t\t\t\twhile (!pathfinished) {\n\t\t\t\t\t\tpaths[pacnt].points[pcnt] = {};\n\t\t\t\t\t\tpaths[pacnt].points[pcnt].x = px - 1;\n\t\t\t\t\t\tpaths[pacnt].points[pcnt].y = py - 1;\n\t\t\t\t\t\tpaths[pacnt].points[pcnt].t = arr[py][px];\n\t\t\t\t\t\tif (px - 1 < paths[pacnt].boundingbox[0]) paths[pacnt].boundingbox[0] = px - 1;\n\t\t\t\t\t\tif (px - 1 > paths[pacnt].boundingbox[2]) paths[pacnt].boundingbox[2] = px - 1;\n\t\t\t\t\t\tif (py - 1 < paths[pacnt].boundingbox[1]) paths[pacnt].boundingbox[1] = py - 1;\n\t\t\t\t\t\tif (py - 1 > paths[pacnt].boundingbox[3]) paths[pacnt].boundingbox[3] = py - 1;\n\t\t\t\t\t\tlookuprow = _this.pathscan_combined_lookup[arr[py][px]][dir];\n\t\t\t\t\t\tarr[py][px] = lookuprow[0];\n\t\t\t\t\t\tdir = lookuprow[1];\n\t\t\t\t\t\tpx += lookuprow[2];\n\t\t\t\t\t\tpy += lookuprow[3];\n\t\t\t\t\t\tif (px - 1 === paths[pacnt].points[0].x && py - 1 === paths[pacnt].points[0].y) {\n\t\t\t\t\t\t\tpathfinished = true;\n\t\t\t\t\t\t\tif (paths[pacnt].points.length < pathomit) paths.pop();\n\t\t\t\t\t\t\telse {\n\t\t\t\t\t\t\t\tpaths[pacnt].isholepath = holepath ? true : false;\n\t\t\t\t\t\t\t\tif (holepath) {\n\t\t\t\t\t\t\t\t\tvar parentidx = 0, parentbbox = [\n\t\t\t\t\t\t\t\t\t\t-1,\n\t\t\t\t\t\t\t\t\t\t-1,\n\t\t\t\t\t\t\t\t\t\tw + 1,\n\t\t\t\t\t\t\t\t\t\th + 1\n\t\t\t\t\t\t\t\t\t];\n\t\t\t\t\t\t\t\t\tfor (var parentcnt = 0; parentcnt < pacnt; parentcnt++) if (!paths[parentcnt].isholepath && _this.boundingboxincludes(paths[parentcnt].boundingbox, paths[pacnt].boundingbox) && _this.boundingboxincludes(parentbbox, paths[parentcnt].boundingbox) && _this.pointinpoly(paths[pacnt].points[0], paths[parentcnt].points)) {\n\t\t\t\t\t\t\t\t\t\tparentidx = parentcnt;\n\t\t\t\t\t\t\t\t\t\tparentbbox = paths[parentcnt].boundingbox;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tpaths[parentidx].holechildren.push(pacnt);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tpacnt++;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tpcnt++;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn paths;\n\t\t\t}, this.boundingboxincludes = function(parentbbox, childbbox) {\n\t\t\t\treturn parentbbox[0] < childbbox[0] && parentbbox[1] < childbbox[1] && parentbbox[2] > childbbox[2] && parentbbox[3] > childbbox[3];\n\t\t\t}, this.batchpathscan = function(layers, pathomit) {\n\t\t\t\tvar bpaths = [];\n\t\t\t\tfor (var k in layers) {\n\t\t\t\t\tif (!layers.hasOwnProperty(k)) continue;\n\t\t\t\t\tbpaths[k] = _this.pathscan(layers[k], pathomit);\n\t\t\t\t}\n\t\t\t\treturn bpaths;\n\t\t\t}, this.internodes = function(paths, options) {\n\t\t\t\tvar ins = [], palen = 0, nextidx = 0, nextidx2 = 0, previdx = 0, previdx2 = 0, pacnt = 0, pcnt;\n\t\t\t\tfor (; pacnt < paths.length; pacnt++) {\n\t\t\t\t\tins[pacnt] = {};\n\t\t\t\t\tins[pacnt].points = [];\n\t\t\t\t\tins[pacnt].boundingbox = paths[pacnt].boundingbox;\n\t\t\t\t\tins[pacnt].holechildren = paths[pacnt].holechildren;\n\t\t\t\t\tins[pacnt].isholepath = paths[pacnt].isholepath;\n\t\t\t\t\tpalen = paths[pacnt].points.length;\n\t\t\t\t\tfor (pcnt = 0; pcnt < palen; pcnt++) {\n\t\t\t\t\t\tnextidx = (pcnt + 1) % palen;\n\t\t\t\t\t\tnextidx2 = (pcnt + 2) % palen;\n\t\t\t\t\t\tprevidx = (pcnt - 1 + palen) % palen;\n\t\t\t\t\t\tprevidx2 = (pcnt - 2 + palen) % palen;\n\t\t\t\t\t\tif (options.rightangleenhance && _this.testrightangle(paths[pacnt], previdx2, previdx, pcnt, nextidx, nextidx2)) {\n\t\t\t\t\t\t\tif (ins[pacnt].points.length > 0) ins[pacnt].points[ins[pacnt].points.length - 1].linesegment = _this.getdirection(ins[pacnt].points[ins[pacnt].points.length - 1].x, ins[pacnt].points[ins[pacnt].points.length - 1].y, paths[pacnt].points[pcnt].x, paths[pacnt].points[pcnt].y);\n\t\t\t\t\t\t\tins[pacnt].points.push({\n\t\t\t\t\t\t\t\tx: paths[pacnt].points[pcnt].x,\n\t\t\t\t\t\t\t\ty: paths[pacnt].points[pcnt].y,\n\t\t\t\t\t\t\t\tlinesegment: _this.getdirection(paths[pacnt].points[pcnt].x, paths[pacnt].points[pcnt].y, (paths[pacnt].points[pcnt].x + paths[pacnt].points[nextidx].x) / 2, (paths[pacnt].points[pcnt].y + paths[pacnt].points[nextidx].y) / 2)\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t\tins[pacnt].points.push({\n\t\t\t\t\t\t\tx: (paths[pacnt].points[pcnt].x + paths[pacnt].points[nextidx].x) / 2,\n\t\t\t\t\t\t\ty: (paths[pacnt].points[pcnt].y + paths[pacnt].points[nextidx].y) / 2,\n\t\t\t\t\t\t\tlinesegment: _this.getdirection((paths[pacnt].points[pcnt].x + paths[pacnt].points[nextidx].x) / 2, (paths[pacnt].points[pcnt].y + paths[pacnt].points[nextidx].y) / 2, (paths[pacnt].points[nextidx].x + paths[pacnt].points[nextidx2].x) / 2, (paths[pacnt].points[nextidx].y + paths[pacnt].points[nextidx2].y) / 2)\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn ins;\n\t\t\t}, this.testrightangle = function(path, idx1, idx2, idx3, idx4, idx5) {\n\t\t\t\treturn path.points[idx3].x === path.points[idx1].x && path.points[idx3].x === path.points[idx2].x && path.points[idx3].y === path.points[idx4].y && path.points[idx3].y === path.points[idx5].y || path.points[idx3].y === path.points[idx1].y && path.points[idx3].y === path.points[idx2].y && path.points[idx3].x === path.points[idx4].x && path.points[idx3].x === path.points[idx5].x;\n\t\t\t}, this.getdirection = function(x1, y1, x2, y2) {\n\t\t\t\tvar val = 8;\n\t\t\t\tif (x1 < x2) {\n\t\t\t\t\tif (y1 < y2) val = 1;\n\t\t\t\t\telse if (y1 > y2) val = 7;\n\t\t\t\t\telse val = 0;\n\t\t\t\t} else if (x1 > x2) {\n\t\t\t\t\tif (y1 < y2) val = 3;\n\t\t\t\t\telse if (y1 > y2) val = 5;\n\t\t\t\t\telse val = 4;\n\t\t\t\t} else if (y1 < y2) val = 2;\n\t\t\t\telse if (y1 > y2) val = 6;\n\t\t\t\telse val = 8;\n\t\t\t\treturn val;\n\t\t\t}, this.batchinternodes = function(bpaths, options) {\n\t\t\t\tvar binternodes = [];\n\t\t\t\tfor (var k in bpaths) {\n\t\t\t\t\tif (!bpaths.hasOwnProperty(k)) continue;\n\t\t\t\t\tbinternodes[k] = _this.internodes(bpaths[k], options);\n\t\t\t\t}\n\t\t\t\treturn binternodes;\n\t\t\t}, this.tracepath = function(path, ltres, qtres) {\n\t\t\t\tvar pcnt = 0, segtype1, segtype2, seqend, smp = {};\n\t\t\t\tsmp.segments = [];\n\t\t\t\tsmp.boundingbox = path.boundingbox;\n\t\t\t\tsmp.holechildren = path.holechildren;\n\t\t\t\tsmp.isholepath = path.isholepath;\n\t\t\t\twhile (pcnt < path.points.length) {\n\t\t\t\t\tsegtype1 = path.points[pcnt].linesegment;\n\t\t\t\t\tsegtype2 = -1;\n\t\t\t\t\tseqend = pcnt + 1;\n\t\t\t\t\twhile ((path.points[seqend].linesegment === segtype1 || path.points[seqend].linesegment === segtype2 || segtype2 === -1) && seqend < path.points.length - 1) {\n\t\t\t\t\t\tif (path.points[seqend].linesegment !== segtype1 && segtype2 === -1) segtype2 = path.points[seqend].linesegment;\n\t\t\t\t\t\tseqend++;\n\t\t\t\t\t}\n\t\t\t\t\tif (seqend === path.points.length - 1) seqend = 0;\n\t\t\t\t\tsmp.segments = smp.segments.concat(_this.fitseq(path, ltres, qtres, pcnt, seqend));\n\t\t\t\t\tif (seqend > 0) pcnt = seqend;\n\t\t\t\t\telse pcnt = path.points.length;\n\t\t\t\t}\n\t\t\t\treturn smp;\n\t\t\t}, this.fitseq = function(path, ltres, qtres, seqstart, seqend) {\n\t\t\t\tif (seqend > path.points.length || seqend < 0) return [];\n\t\t\t\tvar errorpoint = seqstart, errorval = 0, curvepass = true, px, py, dist2;\n\t\t\t\tvar tl = seqend - seqstart;\n\t\t\t\tif (tl < 0) tl += path.points.length;\n\t\t\t\tvar vx = (path.points[seqend].x - path.points[seqstart].x) / tl, vy = (path.points[seqend].y - path.points[seqstart].y) / tl;\n\t\t\t\tvar pcnt = (seqstart + 1) % path.points.length, pl;\n\t\t\t\twhile (pcnt != seqend) {\n\t\t\t\t\tpl = pcnt - seqstart;\n\t\t\t\t\tif (pl < 0) pl += path.points.length;\n\t\t\t\t\tpx = path.points[seqstart].x + vx * pl;\n\t\t\t\t\tpy = path.points[seqstart].y + vy * pl;\n\t\t\t\t\tdist2 = (path.points[pcnt].x - px) * (path.points[pcnt].x - px) + (path.points[pcnt].y - py) * (path.points[pcnt].y - py);\n\t\t\t\t\tif (dist2 > ltres) curvepass = false;\n\t\t\t\t\tif (dist2 > errorval) {\n\t\t\t\t\t\terrorpoint = pcnt;\n\t\t\t\t\t\terrorval = dist2;\n\t\t\t\t\t}\n\t\t\t\t\tpcnt = (pcnt + 1) % path.points.length;\n\t\t\t\t}\n\t\t\t\tif (curvepass) return [{\n\t\t\t\t\ttype: \"L\",\n\t\t\t\t\tx1: path.points[seqstart].x,\n\t\t\t\t\ty1: path.points[seqstart].y,\n\t\t\t\t\tx2: path.points[seqend].x,\n\t\t\t\t\ty2: path.points[seqend].y\n\t\t\t\t}];\n\t\t\t\tvar fitpoint = errorpoint;\n\t\t\t\tcurvepass = true;\n\t\t\t\terrorval = 0;\n\t\t\t\tvar t = (fitpoint - seqstart) / tl, t1 = (1 - t) * (1 - t), t2 = 2 * (1 - t) * t, t3 = t * t;\n\t\t\t\tvar cpx = (t1 * path.points[seqstart].x + t3 * path.points[seqend].x - path.points[fitpoint].x) / -t2, cpy = (t1 * path.points[seqstart].y + t3 * path.points[seqend].y - path.points[fitpoint].y) / -t2;\n\t\t\t\tpcnt = seqstart + 1;\n\t\t\t\twhile (pcnt != seqend) {\n\t\t\t\t\tt = (pcnt - seqstart) / tl;\n\t\t\t\t\tt1 = (1 - t) * (1 - t);\n\t\t\t\t\tt2 = 2 * (1 - t) * t;\n\t\t\t\t\tt3 = t * t;\n\t\t\t\t\tpx = t1 * path.points[seqstart].x + t2 * cpx + t3 * path.points[seqend].x;\n\t\t\t\t\tpy = t1 * path.points[seqstart].y + t2 * cpy + t3 * path.points[seqend].y;\n\t\t\t\t\tdist2 = (path.points[pcnt].x - px) * (path.points[pcnt].x - px) + (path.points[pcnt].y - py) * (path.points[pcnt].y - py);\n\t\t\t\t\tif (dist2 > qtres) curvepass = false;\n\t\t\t\t\tif (dist2 > errorval) {\n\t\t\t\t\t\terrorpoint = pcnt;\n\t\t\t\t\t\terrorval = dist2;\n\t\t\t\t\t}\n\t\t\t\t\tpcnt = (pcnt + 1) % path.points.length;\n\t\t\t\t}\n\t\t\t\tif (curvepass) return [{\n\t\t\t\t\ttype: \"Q\",\n\t\t\t\t\tx1: path.points[seqstart].x,\n\t\t\t\t\ty1: path.points[seqstart].y,\n\t\t\t\t\tx2: cpx,\n\t\t\t\t\ty2: cpy,\n\t\t\t\t\tx3: path.points[seqend].x,\n\t\t\t\t\ty3: path.points[seqend].y\n\t\t\t\t}];\n\t\t\t\tvar splitpoint = fitpoint;\n\t\t\t\treturn _this.fitseq(path, ltres, qtres, seqstart, splitpoint).concat(_this.fitseq(path, ltres, qtres, splitpoint, seqend));\n\t\t\t}, this.batchtracepaths = function(internodepaths, ltres, qtres) {\n\t\t\t\tvar btracedpaths = [];\n\t\t\t\tfor (var k in internodepaths) {\n\t\t\t\t\tif (!internodepaths.hasOwnProperty(k)) continue;\n\t\t\t\t\tbtracedpaths.push(_this.tracepath(internodepaths[k], ltres, qtres));\n\t\t\t\t}\n\t\t\t\treturn btracedpaths;\n\t\t\t}, this.batchtracelayers = function(binternodes, ltres, qtres) {\n\t\t\t\tvar btbis = [];\n\t\t\t\tfor (var k in binternodes) {\n\t\t\t\t\tif (!binternodes.hasOwnProperty(k)) continue;\n\t\t\t\t\tbtbis[k] = _this.batchtracepaths(binternodes[k], ltres, qtres);\n\t\t\t\t}\n\t\t\t\treturn btbis;\n\t\t\t}, this.roundtodec = function(val, places) {\n\t\t\t\treturn +val.toFixed(places);\n\t\t\t}, this.svgpathstring = function(tracedata, lnum, pathnum, options) {\n\t\t\t\tvar layer = tracedata.layers[lnum], smp = layer[pathnum], str = \"\", pcnt;\n\t\t\t\tif (options.linefilter && smp.segments.length < 3) return str;\n\t\t\t\tstr = \"<path \" + (options.desc ? \"desc=\\\"l \" + lnum + \" p \" + pathnum + \"\\\" \" : \"\") + _this.tosvgcolorstr(tracedata.palette[lnum], options) + \"d=\\\"\";\n\t\t\t\tif (options.roundcoords === -1) {\n\t\t\t\t\tstr += \"M \" + smp.segments[0].x1 * options.scale + \" \" + smp.segments[0].y1 * options.scale + \" \";\n\t\t\t\t\tfor (pcnt = 0; pcnt < smp.segments.length; pcnt++) {\n\t\t\t\t\t\tstr += smp.segments[pcnt].type + \" \" + smp.segments[pcnt].x2 * options.scale + \" \" + smp.segments[pcnt].y2 * options.scale + \" \";\n\t\t\t\t\t\tif (smp.segments[pcnt].hasOwnProperty(\"x3\")) str += smp.segments[pcnt].x3 * options.scale + \" \" + smp.segments[pcnt].y3 * options.scale + \" \";\n\t\t\t\t\t}\n\t\t\t\t\tstr += \"Z \";\n\t\t\t\t} else {\n\t\t\t\t\tstr += \"M \" + _this.roundtodec(smp.segments[0].x1 * options.scale, options.roundcoords) + \" \" + _this.roundtodec(smp.segments[0].y1 * options.scale, options.roundcoords) + \" \";\n\t\t\t\t\tfor (pcnt = 0; pcnt < smp.segments.length; pcnt++) {\n\t\t\t\t\t\tstr += smp.segments[pcnt].type + \" \" + _this.roundtodec(smp.segments[pcnt].x2 * options.scale, options.roundcoords) + \" \" + _this.roundtodec(smp.segments[pcnt].y2 * options.scale, options.roundcoords) + \" \";\n\t\t\t\t\t\tif (smp.segments[pcnt].hasOwnProperty(\"x3\")) str += _this.roundtodec(smp.segments[pcnt].x3 * options.scale, options.roundcoords) + \" \" + _this.roundtodec(smp.segments[pcnt].y3 * options.scale, options.roundcoords) + \" \";\n\t\t\t\t\t}\n\t\t\t\t\tstr += \"Z \";\n\t\t\t\t}\n\t\t\t\tfor (var hcnt = 0; hcnt < smp.holechildren.length; hcnt++) {\n\t\t\t\t\tvar hsmp = layer[smp.holechildren[hcnt]];\n\t\t\t\t\tif (options.roundcoords === -1) {\n\t\t\t\t\t\tif (hsmp.segments[hsmp.segments.length - 1].hasOwnProperty(\"x3\")) str += \"M \" + hsmp.segments[hsmp.segments.length - 1].x3 * options.scale + \" \" + hsmp.segments[hsmp.segments.length - 1].y3 * options.scale + \" \";\n\t\t\t\t\t\telse str += \"M \" + hsmp.segments[hsmp.segments.length - 1].x2 * options.scale + \" \" + hsmp.segments[hsmp.segments.length - 1].y2 * options.scale + \" \";\n\t\t\t\t\t\tfor (pcnt = hsmp.segments.length - 1; pcnt >= 0; pcnt--) {\n\t\t\t\t\t\t\tstr += hsmp.segments[pcnt].type + \" \";\n\t\t\t\t\t\t\tif (hsmp.segments[pcnt].hasOwnProperty(\"x3\")) str += hsmp.segments[pcnt].x2 * options.scale + \" \" + hsmp.segments[pcnt].y2 * options.scale + \" \";\n\t\t\t\t\t\t\tstr += hsmp.segments[pcnt].x1 * options.scale + \" \" + hsmp.segments[pcnt].y1 * options.scale + \" \";\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tif (hsmp.segments[hsmp.segments.length - 1].hasOwnProperty(\"x3\")) str += \"M \" + _this.roundtodec(hsmp.segments[hsmp.segments.length - 1].x3 * options.scale) + \" \" + _this.roundtodec(hsmp.segments[hsmp.segments.length - 1].y3 * options.scale) + \" \";\n\t\t\t\t\t\telse str += \"M \" + _this.roundtodec(hsmp.segments[hsmp.segments.length - 1].x2 * options.scale) + \" \" + _this.roundtodec(hsmp.segments[hsmp.segments.length - 1].y2 * options.scale) + \" \";\n\t\t\t\t\t\tfor (pcnt = hsmp.segments.length - 1; pcnt >= 0; pcnt--) {\n\t\t\t\t\t\t\tstr += hsmp.segments[pcnt].type + \" \";\n\t\t\t\t\t\t\tif (hsmp.segments[pcnt].hasOwnProperty(\"x3\")) str += _this.roundtodec(hsmp.segments[pcnt].x2 * options.scale) + \" \" + _this.roundtodec(hsmp.segments[pcnt].y2 * options.scale) + \" \";\n\t\t\t\t\t\t\tstr += _this.roundtodec(hsmp.segments[pcnt].x1 * options.scale) + \" \" + _this.roundtodec(hsmp.segments[pcnt].y1 * options.scale) + \" \";\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tstr += \"Z \";\n\t\t\t\t}\n\t\t\t\tstr += \"\\\" />\";\n\t\t\t\tif (options.lcpr || options.qcpr) {\n\t\t\t\t\tfor (pcnt = 0; pcnt < smp.segments.length; pcnt++) {\n\t\t\t\t\t\tif (smp.segments[pcnt].hasOwnProperty(\"x3\") && options.qcpr) {\n\t\t\t\t\t\t\tstr += \"<circle cx=\\\"\" + smp.segments[pcnt].x2 * options.scale + \"\\\" cy=\\\"\" + smp.segments[pcnt].y2 * options.scale + \"\\\" r=\\\"\" + options.qcpr + \"\\\" fill=\\\"cyan\\\" stroke-width=\\\"\" + options.qcpr * .2 + \"\\\" stroke=\\\"black\\\" />\";\n\t\t\t\t\t\t\tstr += \"<circle cx=\\\"\" + smp.segments[pcnt].x3 * options.scale + \"\\\" cy=\\\"\" + smp.segments[pcnt].y3 * options.scale + \"\\\" r=\\\"\" + options.qcpr + \"\\\" fill=\\\"white\\\" stroke-width=\\\"\" + options.qcpr * .2 + \"\\\" stroke=\\\"black\\\" />\";\n\t\t\t\t\t\t\tstr += \"<line x1=\\\"\" + smp.segments[pcnt].x1 * options.scale + \"\\\" y1=\\\"\" + smp.segments[pcnt].y1 * options.scale + \"\\\" x2=\\\"\" + smp.segments[pcnt].x2 * options.scale + \"\\\" y2=\\\"\" + smp.segments[pcnt].y2 * options.scale + \"\\\" stroke-width=\\\"\" + options.qcpr * .2 + \"\\\" stroke=\\\"cyan\\\" />\";\n\t\t\t\t\t\t\tstr += \"<line x1=\\\"\" + smp.segments[pcnt].x2 * options.scale + \"\\\" y1=\\\"\" + smp.segments[pcnt].y2 * options.scale + \"\\\" x2=\\\"\" + smp.segments[pcnt].x3 * options.scale + \"\\\" y2=\\\"\" + smp.segments[pcnt].y3 * options.scale + \"\\\" stroke-width=\\\"\" + options.qcpr * .2 + \"\\\" stroke=\\\"cyan\\\" />\";\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (!smp.segments[pcnt].hasOwnProperty(\"x3\") && options.lcpr) str += \"<circle cx=\\\"\" + smp.segments[pcnt].x2 * options.scale + \"\\\" cy=\\\"\" + smp.segments[pcnt].y2 * options.scale + \"\\\" r=\\\"\" + options.lcpr + \"\\\" fill=\\\"white\\\" stroke-width=\\\"\" + options.lcpr * .2 + \"\\\" stroke=\\\"black\\\" />\";\n\t\t\t\t\t}\n\t\t\t\t\tfor (var hcnt = 0; hcnt < smp.holechildren.length; hcnt++) {\n\t\t\t\t\t\tvar hsmp = layer[smp.holechildren[hcnt]];\n\t\t\t\t\t\tfor (pcnt = 0; pcnt < hsmp.segments.length; pcnt++) {\n\t\t\t\t\t\t\tif (hsmp.segments[pcnt].hasOwnProperty(\"x3\") && options.qcpr) {\n\t\t\t\t\t\t\t\tstr += \"<circle cx=\\\"\" + hsmp.segments[pcnt].x2 * options.scale + \"\\\" cy=\\\"\" + hsmp.segments[pcnt].y2 * options.scale + \"\\\" r=\\\"\" + options.qcpr + \"\\\" fill=\\\"cyan\\\" stroke-width=\\\"\" + options.qcpr * .2 + \"\\\" stroke=\\\"black\\\" />\";\n\t\t\t\t\t\t\t\tstr += \"<circle cx=\\\"\" + hsmp.segments[pcnt].x3 * options.scale + \"\\\" cy=\\\"\" + hsmp.segments[pcnt].y3 * options.scale + \"\\\" r=\\\"\" + options.qcpr + \"\\\" fill=\\\"white\\\" stroke-width=\\\"\" + options.qcpr * .2 + \"\\\" stroke=\\\"black\\\" />\";\n\t\t\t\t\t\t\t\tstr += \"<line x1=\\\"\" + hsmp.segments[pcnt].x1 * options.scale + \"\\\" y1=\\\"\" + hsmp.segments[pcnt].y1 * options.scale + \"\\\" x2=\\\"\" + hsmp.segments[pcnt].x2 * options.scale + \"\\\" y2=\\\"\" + hsmp.segments[pcnt].y2 * options.scale + \"\\\" stroke-width=\\\"\" + options.qcpr * .2 + \"\\\" stroke=\\\"cyan\\\" />\";\n\t\t\t\t\t\t\t\tstr += \"<line x1=\\\"\" + hsmp.segments[pcnt].x2 * options.scale + \"\\\" y1=\\\"\" + hsmp.segments[pcnt].y2 * options.scale + \"\\\" x2=\\\"\" + hsmp.segments[pcnt].x3 * options.scale + \"\\\" y2=\\\"\" + hsmp.segments[pcnt].y3 * options.scale + \"\\\" stroke-width=\\\"\" + options.qcpr * .2 + \"\\\" stroke=\\\"cyan\\\" />\";\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (!hsmp.segments[pcnt].hasOwnProperty(\"x3\") && options.lcpr) str += \"<circle cx=\\\"\" + hsmp.segments[pcnt].x2 * options.scale + \"\\\" cy=\\\"\" + hsmp.segments[pcnt].y2 * options.scale + \"\\\" r=\\\"\" + options.lcpr + \"\\\" fill=\\\"white\\\" stroke-width=\\\"\" + options.lcpr * .2 + \"\\\" stroke=\\\"black\\\" />\";\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn str;\n\t\t\t}, this.getsvgstring = function(tracedata, options) {\n\t\t\t\toptions = _this.checkoptions(options);\n\t\t\t\tvar w = tracedata.width * options.scale, h = tracedata.height * options.scale;\n\t\t\t\tvar svgstr = \"<svg \" + (options.viewbox ? \"viewBox=\\\"0 0 \" + w + \" \" + h + \"\\\" \" : \"width=\\\"\" + w + \"\\\" height=\\\"\" + h + \"\\\" \") + \"version=\\\"1.1\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\" desc=\\\"Created with imagetracer.js version \" + _this.versionnumber + \"\\\" >\";\n\t\t\t\tfor (var lcnt = 0; lcnt < tracedata.layers.length; lcnt++) for (var pcnt = 0; pcnt < tracedata.layers[lcnt].length; pcnt++) if (!tracedata.layers[lcnt][pcnt].isholepath) svgstr += _this.svgpathstring(tracedata, lcnt, pcnt, options);\n\t\t\t\tsvgstr += \"</svg>\";\n\t\t\t\treturn svgstr;\n\t\t\t}, this.compareNumbers = function(a, b) {\n\t\t\t\treturn a - b;\n\t\t\t}, this.torgbastr = function(c) {\n\t\t\t\treturn \"rgba(\" + c.r + \",\" + c.g + \",\" + c.b + \",\" + c.a + \")\";\n\t\t\t}, this.tosvgcolorstr = function(c, options) {\n\t\t\t\treturn \"fill=\\\"rgb(\" + c.r + \",\" + c.g + \",\" + c.b + \")\\\" stroke=\\\"rgb(\" + c.r + \",\" + c.g + \",\" + c.b + \")\\\" stroke-width=\\\"\" + options.strokewidth + \"\\\" opacity=\\\"\" + c.a / 255 + \"\\\" \";\n\t\t\t}, this.appendSVGString = function(svgstr, parentid) {\n\t\t\t\tvar div;\n\t\t\t\tif (parentid) {\n\t\t\t\t\tdiv = document.getElementById(parentid);\n\t\t\t\t\tif (!div) {\n\t\t\t\t\t\tdiv = document.createElement(\"div\");\n\t\t\t\t\t\tdiv.id = parentid;\n\t\t\t\t\t\tdocument.body.appendChild(div);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tdiv = document.createElement(\"div\");\n\t\t\t\t\tdocument.body.appendChild(div);\n\t\t\t\t}\n\t\t\t\tdiv.innerHTML += svgstr;\n\t\t\t}, this.gks = [\n\t\t\t\t[\n\t\t\t\t\t.27901,\n\t\t\t\t\t.44198,\n\t\t\t\t\t.27901\n\t\t\t\t],\n\t\t\t\t[\n\t\t\t\t\t.135336,\n\t\t\t\t\t.228569,\n\t\t\t\t\t.272192,\n\t\t\t\t\t.228569,\n\t\t\t\t\t.135336\n\t\t\t\t],\n\t\t\t\t[\n\t\t\t\t\t.086776,\n\t\t\t\t\t.136394,\n\t\t\t\t\t.178908,\n\t\t\t\t\t.195843,\n\t\t\t\t\t.178908,\n\t\t\t\t\t.136394,\n\t\t\t\t\t.086776\n\t\t\t\t],\n\t\t\t\t[\n\t\t\t\t\t.063327,\n\t\t\t\t\t.093095,\n\t\t\t\t\t.122589,\n\t\t\t\t\t.144599,\n\t\t\t\t\t.152781,\n\t\t\t\t\t.144599,\n\t\t\t\t\t.122589,\n\t\t\t\t\t.093095,\n\t\t\t\t\t.063327\n\t\t\t\t],\n\t\t\t\t[\n\t\t\t\t\t.049692,\n\t\t\t\t\t.069304,\n\t\t\t\t\t.089767,\n\t\t\t\t\t.107988,\n\t\t\t\t\t.120651,\n\t\t\t\t\t.125194,\n\t\t\t\t\t.120651,\n\t\t\t\t\t.107988,\n\t\t\t\t\t.089767,\n\t\t\t\t\t.069304,\n\t\t\t\t\t.049692\n\t\t\t\t]\n\t\t\t], this.blur = function(imgd, radius, delta) {\n\t\t\t\tvar i, j, k, d, idx, racc, gacc, bacc, aacc, wacc;\n\t\t\t\tvar imgd2 = {\n\t\t\t\t\twidth: imgd.width,\n\t\t\t\t\theight: imgd.height,\n\t\t\t\t\tdata: []\n\t\t\t\t};\n\t\t\t\tradius = Math.floor(radius);\n\t\t\t\tif (radius < 1) return imgd;\n\t\t\t\tif (radius > 5) radius = 5;\n\t\t\t\tdelta = Math.abs(delta);\n\t\t\t\tif (delta > 1024) delta = 1024;\n\t\t\t\tvar thisgk = _this.gks[radius - 1];\n\t\t\t\tfor (j = 0; j < imgd.height; j++) for (i = 0; i < imgd.width; i++) {\n\t\t\t\t\tracc = 0;\n\t\t\t\t\tgacc = 0;\n\t\t\t\t\tbacc = 0;\n\t\t\t\t\taacc = 0;\n\t\t\t\t\twacc = 0;\n\t\t\t\t\tfor (k = -radius; k < radius + 1; k++) if (i + k > 0 && i + k < imgd.width) {\n\t\t\t\t\t\tidx = (j * imgd.width + i + k) * 4;\n\t\t\t\t\t\tracc += imgd.data[idx] * thisgk[k + radius];\n\t\t\t\t\t\tgacc += imgd.data[idx + 1] * thisgk[k + radius];\n\t\t\t\t\t\tbacc += imgd.data[idx + 2] * thisgk[k + radius];\n\t\t\t\t\t\taacc += imgd.data[idx + 3] * thisgk[k + radius];\n\t\t\t\t\t\twacc += thisgk[k + radius];\n\t\t\t\t\t}\n\t\t\t\t\tidx = (j * imgd.width + i) * 4;\n\t\t\t\t\timgd2.data[idx] = Math.floor(racc / wacc);\n\t\t\t\t\timgd2.data[idx + 1] = Math.floor(gacc / wacc);\n\t\t\t\t\timgd2.data[idx + 2] = Math.floor(bacc / wacc);\n\t\t\t\t\timgd2.data[idx + 3] = Math.floor(aacc / wacc);\n\t\t\t\t}\n\t\t\t\tvar himgd = new Uint8ClampedArray(imgd2.data);\n\t\t\t\tfor (j = 0; j < imgd.height; j++) for (i = 0; i < imgd.width; i++) {\n\t\t\t\t\tracc = 0;\n\t\t\t\t\tgacc = 0;\n\t\t\t\t\tbacc = 0;\n\t\t\t\t\taacc = 0;\n\t\t\t\t\twacc = 0;\n\t\t\t\t\tfor (k = -radius; k < radius + 1; k++) if (j + k > 0 && j + k < imgd.height) {\n\t\t\t\t\t\tidx = ((j + k) * imgd.width + i) * 4;\n\t\t\t\t\t\tracc += himgd[idx] * thisgk[k + radius];\n\t\t\t\t\t\tgacc += himgd[idx + 1] * thisgk[k + radius];\n\t\t\t\t\t\tbacc += himgd[idx + 2] * thisgk[k + radius];\n\t\t\t\t\t\taacc += himgd[idx + 3] * thisgk[k + radius];\n\t\t\t\t\t\twacc += thisgk[k + radius];\n\t\t\t\t\t}\n\t\t\t\t\tidx = (j * imgd.width + i) * 4;\n\t\t\t\t\timgd2.data[idx] = Math.floor(racc / wacc);\n\t\t\t\t\timgd2.data[idx + 1] = Math.floor(gacc / wacc);\n\t\t\t\t\timgd2.data[idx + 2] = Math.floor(bacc / wacc);\n\t\t\t\t\timgd2.data[idx + 3] = Math.floor(aacc / wacc);\n\t\t\t\t}\n\t\t\t\tfor (j = 0; j < imgd.height; j++) for (i = 0; i < imgd.width; i++) {\n\t\t\t\t\tidx = (j * imgd.width + i) * 4;\n\t\t\t\t\td = Math.abs(imgd2.data[idx] - imgd.data[idx]) + Math.abs(imgd2.data[idx + 1] - imgd.data[idx + 1]) + Math.abs(imgd2.data[idx + 2] - imgd.data[idx + 2]) + Math.abs(imgd2.data[idx + 3] - imgd.data[idx + 3]);\n\t\t\t\t\tif (d > delta) {\n\t\t\t\t\t\timgd2.data[idx] = imgd.data[idx];\n\t\t\t\t\t\timgd2.data[idx + 1] = imgd.data[idx + 1];\n\t\t\t\t\t\timgd2.data[idx + 2] = imgd.data[idx + 2];\n\t\t\t\t\t\timgd2.data[idx + 3] = imgd.data[idx + 3];\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn imgd2;\n\t\t\t}, this.loadImage = function(url, callback, options) {\n\t\t\t\tvar img = new Image();\n\t\t\t\tif (options && options.corsenabled) img.crossOrigin = \"Anonymous\";\n\t\t\t\timg.onload = function() {\n\t\t\t\t\tvar canvas = document.createElement(\"canvas\");\n\t\t\t\t\tcanvas.width = img.width;\n\t\t\t\t\tcanvas.height = img.height;\n\t\t\t\t\tcanvas.getContext(\"2d\").drawImage(img, 0, 0);\n\t\t\t\t\tcallback(canvas);\n\t\t\t\t};\n\t\t\t\timg.src = url;\n\t\t\t}, this.getImgdata = function(canvas) {\n\t\t\t\treturn canvas.getContext(\"2d\").getImageData(0, 0, canvas.width, canvas.height);\n\t\t\t}, this.specpalette = [\n\t\t\t\t{\n\t\t\t\t\tr: 0,\n\t\t\t\t\tg: 0,\n\t\t\t\t\tb: 0,\n\t\t\t\t\ta: 255\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tr: 128,\n\t\t\t\t\tg: 128,\n\t\t\t\t\tb: 128,\n\t\t\t\t\ta: 255\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tr: 0,\n\t\t\t\t\tg: 0,\n\t\t\t\t\tb: 128,\n\t\t\t\t\ta: 255\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tr: 64,\n\t\t\t\t\tg: 64,\n\t\t\t\t\tb: 128,\n\t\t\t\t\ta: 255\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tr: 192,\n\t\t\t\t\tg: 192,\n\t\t\t\t\tb: 192,\n\t\t\t\t\ta: 255\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tr: 255,\n\t\t\t\t\tg: 255,\n\t\t\t\t\tb: 255,\n\t\t\t\t\ta: 255\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tr: 128,\n\t\t\t\t\tg: 128,\n\t\t\t\t\tb: 192,\n\t\t\t\t\ta: 255\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tr: 0,\n\t\t\t\t\tg: 0,\n\t\t\t\t\tb: 192,\n\t\t\t\t\ta: 255\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tr: 128,\n\t\t\t\t\tg: 0,\n\t\t\t\t\tb: 0,\n\t\t\t\t\ta: 255\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tr: 128,\n\t\t\t\t\tg: 64,\n\t\t\t\t\tb: 64,\n\t\t\t\t\ta: 255\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tr: 128,\n\t\t\t\t\tg: 0,\n\t\t\t\t\tb: 128,\n\t\t\t\t\ta: 255\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tr: 168,\n\t\t\t\t\tg: 168,\n\t\t\t\t\tb: 168,\n\t\t\t\t\ta: 255\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tr: 192,\n\t\t\t\t\tg: 128,\n\t\t\t\t\tb: 128,\n\t\t\t\t\ta: 255\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tr: 192,\n\t\t\t\t\tg: 0,\n\t\t\t\t\tb: 0,\n\t\t\t\t\ta: 255\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tr: 255,\n\t\t\t\t\tg: 255,\n\t\t\t\t\tb: 255,\n\t\t\t\t\ta: 255\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tr: 0,\n\t\t\t\t\tg: 128,\n\t\t\t\t\tb: 0,\n\t\t\t\t\ta: 255\n\t\t\t\t}\n\t\t\t], this.drawLayers = function(layers, palette, scale, parentid) {\n\t\t\t\tscale = scale || 1;\n\t\t\t\tvar w, h, i, j, k;\n\t\t\t\tvar div;\n\t\t\t\tif (parentid) {\n\t\t\t\t\tdiv = document.getElementById(parentid);\n\t\t\t\t\tif (!div) {\n\t\t\t\t\t\tdiv = document.createElement(\"div\");\n\t\t\t\t\t\tdiv.id = parentid;\n\t\t\t\t\t\tdocument.body.appendChild(div);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tdiv = document.createElement(\"div\");\n\t\t\t\t\tdocument.body.appendChild(div);\n\t\t\t\t}\n\t\t\t\tfor (k in layers) {\n\t\t\t\t\tif (!layers.hasOwnProperty(k)) continue;\n\t\t\t\t\tw = layers[k][0].length;\n\t\t\t\t\th = layers[k].length;\n\t\t\t\t\tvar canvas = document.createElement(\"canvas\");\n\t\t\t\t\tcanvas.width = w * scale;\n\t\t\t\t\tcanvas.height = h * scale;\n\t\t\t\t\tvar context = canvas.getContext(\"2d\");\n\t\t\t\t\tfor (j = 0; j < h; j++) for (i = 0; i < w; i++) {\n\t\t\t\t\t\tcontext.fillStyle = _this.torgbastr(palette[layers[k][j][i] % palette.length]);\n\t\t\t\t\t\tcontext.fillRect(i * scale, j * scale, scale, scale);\n\t\t\t\t\t}\n\t\t\t\t\tdiv.appendChild(canvas);\n\t\t\t\t}\n\t\t\t};\n\t\t}\n\t\tif (typeof define === \"function\" && define.amd) define(function() {\n\t\t\treturn new ImageTracer();\n\t\t});\n\t\telse if (typeof module !== \"undefined\") module.exports = new ImageTracer();\n\t\telse if (typeof self !== \"undefined\") self.ImageTracer = new ImageTracer();\n\t\telse window.ImageTracer = new ImageTracer();\n\t})();\n}));\n\n//#endregion\n//#region ../../../client/node_modules/wasm_vtracer/wasm_vtracer_bg.js\nvar wasm_vtracer_bg_exports = /* @__PURE__ */ __exportAll({\n\tColorMode: () => ColorMode,\n\tHierarchical: () => Hierarchical,\n\tPathSimplifyMode: () => PathSimplifyMode,\n\tTracerConfig: () => TracerConfig,\n\t__wbg_Error_52673b7de5a0ca89: () => __wbg_Error_52673b7de5a0ca89,\n\t__wbg___wbindgen_throw_dd24417ed36fc46e: () => __wbg___wbindgen_throw_dd24417ed36fc46e,\n\t__wbg_error_7534b8e9a36f1ab4: () => __wbg_error_7534b8e9a36f1ab4,\n\t__wbg_new_8a6f238a6ece86ea: () => __wbg_new_8a6f238a6ece86ea,\n\t__wbg_set_wasm: () => __wbg_set_wasm,\n\t__wbg_stack_0ed75d68575b0f3c: () => __wbg_stack_0ed75d68575b0f3c,\n\t__wbindgen_object_drop_ref: () => __wbindgen_object_drop_ref,\n\tconvertImageToSvg: () => convertImageToSvg,\n\tconvertImageToSvgDefault: () => convertImageToSvgDefault,\n\tconvertPixelArtToSvg: () => convertPixelArtToSvg,\n\tgetVersion: () => getVersion,\n\tinit: () => init,\n\tisReady: () => isReady\n});\nfunction __wbg_set_wasm(val) {\n\twasm = val;\n}\nfunction addHeapObject(obj) {\n\tif (heap_next === heap.length) heap.push(heap.length + 1);\n\tconst idx = heap_next;\n\theap_next = heap[idx];\n\theap[idx] = obj;\n\treturn idx;\n}\nfunction _assertClass(instance, klass) {\n\tif (!(instance instanceof klass)) throw new Error(`expected instance of ${klass.name}`);\n}\nfunction dropObject(idx) {\n\tif (idx < 132) return;\n\theap[idx] = heap_next;\n\theap_next = idx;\n}\nfunction getDataViewMemory0() {\n\tif (cachedDataViewMemory0 === null || cachedDataViewMemory0.buffer.detached === true || cachedDataViewMemory0.buffer.detached === void 0 && cachedDataViewMemory0.buffer !== wasm.memory.buffer) cachedDataViewMemory0 = new DataView(wasm.memory.buffer);\n\treturn cachedDataViewMemory0;\n}\nfunction getStringFromWasm0(ptr, len) {\n\tptr = ptr >>> 0;\n\treturn decodeText(ptr, len);\n}\nfunction getUint8ArrayMemory0() {\n\tif (cachedUint8ArrayMemory0 === null || cachedUint8ArrayMemory0.byteLength === 0) cachedUint8ArrayMemory0 = new Uint8Array(wasm.memory.buffer);\n\treturn cachedUint8ArrayMemory0;\n}\nfunction getObject(idx) {\n\treturn heap[idx];\n}\nfunction passArray8ToWasm0(arg, malloc) {\n\tconst ptr = malloc(arg.length * 1, 1) >>> 0;\n\tgetUint8ArrayMemory0().set(arg, ptr / 1);\n\tWASM_VECTOR_LEN = arg.length;\n\treturn ptr;\n}\nfunction passStringToWasm0(arg, malloc, realloc) {\n\tif (realloc === void 0) {\n\t\tconst buf = cachedTextEncoder.encode(arg);\n\t\tconst ptr = malloc(buf.length, 1) >>> 0;\n\t\tgetUint8ArrayMemory0().subarray(ptr, ptr + buf.length).set(buf);\n\t\tWASM_VECTOR_LEN = buf.length;\n\t\treturn ptr;\n\t}\n\tlet len = arg.length;\n\tlet ptr = malloc(len, 1) >>> 0;\n\tconst mem = getUint8ArrayMemory0();\n\tlet offset = 0;\n\tfor (; offset < len; offset++) {\n\t\tconst code = arg.charCodeAt(offset);\n\t\tif (code > 127) break;\n\t\tmem[ptr + offset] = code;\n\t}\n\tif (offset !== len) {\n\t\tif (offset !== 0) arg = arg.slice(offset);\n\t\tptr = realloc(ptr, len, len = offset + arg.length * 3, 1) >>> 0;\n\t\tconst view = getUint8ArrayMemory0().subarray(ptr + offset, ptr + len);\n\t\tconst ret = cachedTextEncoder.encodeInto(arg, view);\n\t\toffset += ret.written;\n\t\tptr = realloc(ptr, len, offset, 1) >>> 0;\n\t}\n\tWASM_VECTOR_LEN = offset;\n\treturn ptr;\n}\nfunction takeObject(idx) {\n\tconst ret = getObject(idx);\n\tdropObject(idx);\n\treturn ret;\n}\nfunction decodeText(ptr, len) {\n\tnumBytesDecoded += len;\n\tif (numBytesDecoded >= MAX_SAFARI_DECODE_BYTES) {\n\t\tcachedTextDecoder = new TextDecoder(\"utf-8\", {\n\t\t\tignoreBOM: true,\n\t\t\tfatal: true\n\t\t});\n\t\tcachedTextDecoder.decode();\n\t\tnumBytesDecoded = len;\n\t}\n\treturn cachedTextDecoder.decode(getUint8ArrayMemory0().subarray(ptr, ptr + len));\n}\n/**\n* Convert RGBA image data to SVG string.\n*\n* # Arguments\n* * `image_data` - Raw RGBA pixel data (4 bytes per pixel)\n* * `width` - Image width in pixels\n* * `height` - Image height in pixels\n* * `config` - Tracer configuration\n*\n* # Returns\n* SVG string on success, or error message on failure.\n*\n* # Example (JavaScript)\n* ```js\n* const config = new TracerConfig();\n* config.presetPixelArt();\n* const svg = convertImageToSvg(imageData, 64, 64, config);\n* ```\n* @param {Uint8Array} image_data\n* @param {number} width\n* @param {number} height\n* @param {TracerConfig} config\n* @returns {string}\n*/\nfunction convertImageToSvg(image_data, width, height, config) {\n\tlet deferred3_0;\n\tlet deferred3_1;\n\ttry {\n\t\tconst retptr = wasm.__wbindgen_add_to_stack_pointer(-16);\n\t\tconst ptr0 = passArray8ToWasm0(image_data, wasm.__wbindgen_export2);\n\t\tconst len0 = WASM_VECTOR_LEN;\n\t\t_assertClass(config, TracerConfig);\n\t\twasm.convertImageToSvg(retptr, ptr0, len0, width, height, config.__wbg_ptr);\n\t\tvar r0 = getDataViewMemory0().getInt32(retptr + 0, true);\n\t\tvar r1 = getDataViewMemory0().getInt32(retptr + 4, true);\n\t\tvar r2 = getDataViewMemory0().getInt32(retptr + 8, true);\n\t\tvar r3 = getDataViewMemory0().getInt32(retptr + 12, true);\n\t\tvar ptr2 = r0;\n\t\tvar len2 = r1;\n\t\tif (r3) {\n\t\t\tptr2 = 0;\n\t\t\tlen2 = 0;\n\t\t\tthrow takeObject(r2);\n\t\t}\n\t\tdeferred3_0 = ptr2;\n\t\tdeferred3_1 = len2;\n\t\treturn getStringFromWasm0(ptr2, len2);\n\t} finally {\n\t\twasm.__wbindgen_add_to_stack_pointer(16);\n\t\twasm.__wbindgen_export(deferred3_0, deferred3_1, 1);\n\t}\n}\n/**\n* Convert RGBA image data to SVG with default configuration.\n*\n* Convenience function using default settings.\n* @param {Uint8Array} image_data\n* @param {number} width\n* @param {number} height\n* @returns {string}\n*/\nfunction convertImageToSvgDefault(image_data, width, height) {\n\tlet deferred3_0;\n\tlet deferred3_1;\n\ttry {\n\t\tconst retptr = wasm.__wbindgen_add_to_stack_pointer(-16);\n\t\tconst ptr0 = passArray8ToWasm0(image_data, wasm.__wbindgen_export2);\n\t\tconst len0 = WASM_VECTOR_LEN;\n\t\twasm.convertImageToSvgDefault(retptr, ptr0, len0, width, height);\n\t\tvar r0 = getDataViewMemory0().getInt32(retptr + 0, true);\n\t\tvar r1 = getDataViewMemory0().getInt32(retptr + 4, true);\n\t\tvar r2 = getDataViewMemory0().getInt32(retptr + 8, true);\n\t\tvar r3 = getDataViewMemory0().getInt32(retptr + 12, true);\n\t\tvar ptr2 = r0;\n\t\tvar len2 = r1;\n\t\tif (r3) {\n\t\t\tptr2 = 0;\n\t\t\tlen2 = 0;\n\t\t\tthrow takeObject(r2);\n\t\t}\n\t\tdeferred3_0 = ptr2;\n\t\tdeferred3_1 = len2;\n\t\treturn getStringFromWasm0(ptr2, len2);\n\t} finally {\n\t\twasm.__wbindgen_add_to_stack_pointer(16);\n\t\twasm.__wbindgen_export(deferred3_0, deferred3_1, 1);\n\t}\n}\n/**\n* Convert RGBA image data to SVG optimized for pixel art.\n*\n* Uses polygon paths (no curves) and preserves sharp edges.\n* @param {Uint8Array} image_data\n* @param {number} width\n* @param {number} height\n* @returns {string}\n*/\nfunction convertPixelArtToSvg(image_data, width, height) {\n\tlet deferred3_0;\n\tlet deferred3_1;\n\ttry {\n\t\tconst retptr = wasm.__wbindgen_add_to_stack_pointer(-16);\n\t\tconst ptr0 = passArray8ToWasm0(image_data, wasm.__wbindgen_export2);\n\t\tconst len0 = WASM_VECTOR_LEN;\n\t\twasm.convertPixelArtToSvg(retptr, ptr0, len0, width, height);\n\t\tvar r0 = getDataViewMemory0().getInt32(retptr + 0, true);\n\t\tvar r1 = getDataViewMemory0().getInt32(retptr + 4, true);\n\t\tvar r2 = getDataViewMemory0().getInt32(retptr + 8, true);\n\t\tvar r3 = getDataViewMemory0().getInt32(retptr + 12, true);\n\t\tvar ptr2 = r0;\n\t\tvar len2 = r1;\n\t\tif (r3) {\n\t\t\tptr2 = 0;\n\t\t\tlen2 = 0;\n\t\t\tthrow takeObject(r2);\n\t\t}\n\t\tdeferred3_0 = ptr2;\n\t\tdeferred3_1 = len2;\n\t\treturn getStringFromWasm0(ptr2, len2);\n\t} finally {\n\t\twasm.__wbindgen_add_to_stack_pointer(16);\n\t\twasm.__wbindgen_export(deferred3_0, deferred3_1, 1);\n\t}\n}\n/**\n* Get the library version.\n* @returns {string}\n*/\nfunction getVersion() {\n\tlet deferred1_0;\n\tlet deferred1_1;\n\ttry {\n\t\tconst retptr = wasm.__wbindgen_add_to_stack_pointer(-16);\n\t\twasm.getVersion(retptr);\n\t\tvar r0 = getDataViewMemory0().getInt32(retptr + 0, true);\n\t\tvar r1 = getDataViewMemory0().getInt32(retptr + 4, true);\n\t\tdeferred1_0 = r0;\n\t\tdeferred1_1 = r1;\n\t\treturn getStringFromWasm0(r0, r1);\n\t} finally {\n\t\twasm.__wbindgen_add_to_stack_pointer(16);\n\t\twasm.__wbindgen_export(deferred1_0, deferred1_1, 1);\n\t}\n}\n/**\n* Initialize the WASM module. Call this once before using other functions.\n* Sets up panic hook for better error messages in browser console.\n*/\nfunction init() {\n\twasm.init();\n}\n/**\n* Check if the WASM module is ready.\n* @returns {boolean}\n*/\nfunction isReady() {\n\treturn wasm.isReady() !== 0;\n}\nfunction __wbg_Error_52673b7de5a0ca89(arg0, arg1) {\n\treturn addHeapObject(Error(getStringFromWasm0(arg0, arg1)));\n}\nfunction __wbg___wbindgen_throw_dd24417ed36fc46e(arg0, arg1) {\n\tthrow new Error(getStringFromWasm0(arg0, arg1));\n}\nfunction __wbg_error_7534b8e9a36f1ab4(arg0, arg1) {\n\tlet deferred0_0;\n\tlet deferred0_1;\n\ttry {\n\t\tdeferred0_0 = arg0;\n\t\tdeferred0_1 = arg1;\n\t\tconsole.error(getStringFromWasm0(arg0, arg1));\n\t} finally {\n\t\twasm.__wbindgen_export(deferred0_0, deferred0_1, 1);\n\t}\n}\nfunction __wbg_new_8a6f238a6ece86ea() {\n\treturn addHeapObject(/* @__PURE__ */ new Error());\n}\nfunction __wbg_stack_0ed75d68575b0f3c(arg0, arg1) {\n\tconst ret = getObject(arg1).stack;\n\tconst ptr1 = passStringToWasm0(ret, wasm.__wbindgen_export2, wasm.__wbindgen_export3);\n\tconst len1 = WASM_VECTOR_LEN;\n\tgetDataViewMemory0().setInt32(arg0 + 4, len1, true);\n\tgetDataViewMemory0().setInt32(arg0 + 0, ptr1, true);\n}\nfunction __wbindgen_object_drop_ref(arg0) {\n\ttakeObject(arg0);\n}\nvar wasm, cachedDataViewMemory0, cachedUint8ArrayMemory0, heap, heap_next, cachedTextDecoder, MAX_SAFARI_DECODE_BYTES, numBytesDecoded, cachedTextEncoder, WASM_VECTOR_LEN, TracerConfigFinalization, ColorMode, Hierarchical, PathSimplifyMode, TracerConfig;\nvar init_wasm_vtracer_bg = __esmMin((() => {\n\t;\n\tcachedDataViewMemory0 = null;\n\tcachedUint8ArrayMemory0 = null;\n\theap = new Array(128).fill(void 0);\n\theap.push(void 0, null, true, false);\n\theap_next = heap.length;\n\tcachedTextDecoder = new TextDecoder(\"utf-8\", {\n\t\tignoreBOM: true,\n\t\tfatal: true\n\t});\n\tcachedTextDecoder.decode();\n\tMAX_SAFARI_DECODE_BYTES = 2146435072;\n\tnumBytesDecoded = 0;\n\tcachedTextEncoder = new TextEncoder();\n\tif (!(\"encodeInto\" in cachedTextEncoder)) cachedTextEncoder.encodeInto = function(arg, view) {\n\t\tconst buf = cachedTextEncoder.encode(arg);\n\t\tview.set(buf);\n\t\treturn {\n\t\t\tread: arg.length,\n\t\t\twritten: buf.length\n\t\t};\n\t};\n\tWASM_VECTOR_LEN = 0;\n\tTracerConfigFinalization = typeof FinalizationRegistry === \"undefined\" ? {\n\t\tregister: () => {},\n\t\tunregister: () => {}\n\t} : new FinalizationRegistry((ptr) => wasm.__wbg_tracerconfig_free(ptr >>> 0, 1));\n\tColorMode = Object.freeze({\n\t\t/**\n\t\t* Full color tracing\n\t\t*/\n\t\tColor: 0,\n\t\t\"0\": \"Color\",\n\t\t/**\n\t\t* Binary (black/white) tracing\n\t\t*/\n\t\tBinary: 1,\n\t\t\"1\": \"Binary\"\n\t});\n\tHierarchical = Object.freeze({\n\t\t/**\n\t\t* Stacked layers (shapes can overlap)\n\t\t*/\n\t\tStacked: 0,\n\t\t\"0\": \"Stacked\",\n\t\t/**\n\t\t* Cutout mode (shapes cut holes in layers below)\n\t\t*/\n\t\tCutout: 1,\n\t\t\"1\": \"Cutout\"\n\t});\n\tPathSimplifyMode = Object.freeze({\n\t\t/**\n\t\t* Polygon paths (straight lines only)\n\t\t*/\n\t\tPolygon: 0,\n\t\t\"0\": \"Polygon\",\n\t\t/**\n\t\t* Spline curves (smooth Bezier curves)\n\t\t*/\n\t\tSpline: 1,\n\t\t\"1\": \"Spline\",\n\t\t/**\n\t\t* No simplification (raw pixel edges)\n\t\t*/\n\t\tNone: 2,\n\t\t\"2\": \"None\"\n\t});\n\tTracerConfig = class {\n\t\t__destroy_into_raw() {\n\t\t\tconst ptr = this.__wbg_ptr;\n\t\t\tthis.__wbg_ptr = 0;\n\t\t\tTracerConfigFinalization.unregister(this);\n\t\t\treturn ptr;\n\t\t}\n\t\tfree() {\n\t\t\tconst ptr = this.__destroy_into_raw();\n\t\t\twasm.__wbg_tracerconfig_free(ptr, 0);\n\t\t}\n\t\t/**\n\t\t* Create a new TracerConfig with default values optimized for pixel art.\n\t\t*/\n\t\tconstructor() {\n\t\t\tconst ret = wasm.tracerconfig_new();\n\t\t\tthis.__wbg_ptr = ret >>> 0;\n\t\t\tTracerConfigFinalization.register(this, this.__wbg_ptr, this);\n\t\t\treturn this;\n\t\t}\n\t\t/**\n\t\t* Set the color mode (Color = 0, Binary = 1)\n\t\t* @param {ColorMode} mode\n\t\t*/\n\t\tsetColorMode(mode) {\n\t\t\twasm.tracerconfig_setColorMode(this.__wbg_ptr, mode);\n\t\t}\n\t\t/**\n\t\t* Set the hierarchical mode (Stacked = 0, Cutout = 1)\n\t\t* @param {Hierarchical} mode\n\t\t*/\n\t\tsetHierarchical(mode) {\n\t\t\twasm.tracerconfig_setHierarchical(this.__wbg_ptr, mode);\n\t\t}\n\t\t/**\n\t\t* Set the path simplification mode (Polygon = 0, Spline = 1, None = 2)\n\t\t* @param {PathSimplifyMode} mode\n\t\t*/\n\t\tsetPathSimplifyMode(mode) {\n\t\t\twasm.tracerconfig_setPathSimplifyMode(this.__wbg_ptr, mode);\n\t\t}\n\t\t/**\n\t\t* Filter out speckles smaller than this many pixels.\n\t\t* Default: 4. Range: 0+\n\t\t* @param {number} val\n\t\t*/\n\t\tsetFilterSpeckle(val) {\n\t\t\twasm.tracerconfig_setFilterSpeckle(this.__wbg_ptr, val);\n\t\t}\n\t\t/**\n\t\t* Color precision for quantization (bits per channel).\n\t\t* Default: 6. Range: 1-8\n\t\t* @param {number} val\n\t\t*/\n\t\tsetColorPrecision(val) {\n\t\t\ttry {\n\t\t\t\tconst retptr = wasm.__wbindgen_add_to_stack_pointer(-16);\n\t\t\t\twasm.tracerconfig_setColorPrecision(retptr, this.__wbg_ptr, val);\n\t\t\t\tvar r0 = getDataViewMemory0().getInt32(retptr + 0, true);\n\t\t\t\tif (getDataViewMemory0().getInt32(retptr + 4, true)) throw takeObject(r0);\n\t\t\t} finally {\n\t\t\t\twasm.__wbindgen_add_to_stack_pointer(16);\n\t\t\t}\n\t\t}\n\t\t/**\n\t\t* Color difference threshold for layer separation.\n\t\t* Default: 16. Range: 0-255\n\t\t* @param {number} val\n\t\t*/\n\t\tsetLayerDifference(val) {\n\t\t\ttry {\n\t\t\t\tconst retptr = wasm.__wbindgen_add_to_stack_pointer(-16);\n\t\t\t\twasm.tracerconfig_setLayerDifference(retptr, this.__wbg_ptr, val);\n\t\t\t\tvar r0 = getDataViewMemory0().getInt32(retptr + 0, true);\n\t\t\t\tif (getDataViewMemory0().getInt32(retptr + 4, true)) throw takeObject(r0);\n\t\t\t} finally {\n\t\t\t\twasm.__wbindgen_add_to_stack_pointer(16);\n\t\t\t}\n\t\t}\n\t\t/**\n\t\t* Corner detection threshold in degrees.\n\t\t* Default: 60. Range: 0-180\n\t\t* @param {number} val\n\t\t*/\n\t\tsetCornerThreshold(val) {\n\t\t\ttry {\n\t\t\t\tconst retptr = wasm.__wbindgen_add_to_stack_pointer(-16);\n\t\t\t\twasm.tracerconfig_setCornerThreshold(retptr, this.__wbg_ptr, val);\n\t\t\t\tvar r0 = getDataViewMemory0().getInt32(retptr + 0, true);\n\t\t\t\tif (getDataViewMemory0().getInt32(retptr + 4, true)) throw takeObject(r0);\n\t\t\t} finally {\n\t\t\t\twasm.__wbindgen_add_to_stack_pointer(16);\n\t\t\t}\n\t\t}\n\t\t/**\n\t\t* Minimum length for path segments.\n\t\t* Default: 4.0. Range: 3.5-10.0\n\t\t* @param {number} val\n\t\t*/\n\t\tsetLengthThreshold(val) {\n\t\t\ttry {\n\t\t\t\tconst retptr = wasm.__wbindgen_add_to_stack_pointer(-16);\n\t\t\t\twasm.tracerconfig_setLengthThreshold(retptr, this.__wbg_ptr, val);\n\t\t\t\tvar r0 = getDataViewMemory0().getInt32(retptr + 0, true);\n\t\t\t\tif (getDataViewMemory0().getInt32(retptr + 4, true)) throw takeObject(r0);\n\t\t\t} finally {\n\t\t\t\twasm.__wbindgen_add_to_stack_pointer(16);\n\t\t\t}\n\t\t}\n\t\t/**\n\t\t* Maximum iterations for curve fitting.\n\t\t* Default: 10. Range: 1+\n\t\t* @param {number} val\n\t\t*/\n\t\tsetMaxIterations(val) {\n\t\t\twasm.tracerconfig_setMaxIterations(this.__wbg_ptr, val);\n\t\t}\n\t\t/**\n\t\t* Splice threshold in degrees for curve joining.\n\t\t* Default: 45. Range: 0-180\n\t\t* @param {number} val\n\t\t*/\n\t\tsetSpliceThreshold(val) {\n\t\t\ttry {\n\t\t\t\tconst retptr = wasm.__wbindgen_add_to_stack_pointer(-16);\n\t\t\t\twasm.tracerconfig_setSpliceThreshold(retptr, this.__wbg_ptr, val);\n\t\t\t\tvar r0 = getDataViewMemory0().getInt32(retptr + 0, true);\n\t\t\t\tif (getDataViewMemory0().getInt32(retptr + 4, true)) throw takeObject(r0);\n\t\t\t} finally {\n\t\t\t\twasm.__wbindgen_add_to_stack_pointer(16);\n\t\t\t}\n\t\t}\n\t\t/**\n\t\t* Decimal precision for path coordinates in SVG output.\n\t\t* Default: 2. Range: 0-8\n\t\t* @param {number} val\n\t\t*/\n\t\tsetPathPrecision(val) {\n\t\t\ttry {\n\t\t\t\tconst retptr = wasm.__wbindgen_add_to_stack_pointer(-16);\n\t\t\t\twasm.tracerconfig_setPathPrecision(retptr, this.__wbg_ptr, val);\n\t\t\t\tvar r0 = getDataViewMemory0().getInt32(retptr + 0, true);\n\t\t\t\tif (getDataViewMemory0().getInt32(retptr + 4, true)) throw takeObject(r0);\n\t\t\t} finally {\n\t\t\t\twasm.__wbindgen_add_to_stack_pointer(16);\n\t\t\t}\n\t\t}\n\t\t/**\n\t\t* Preset for pixel art: sharp edges, no curve smoothing\n\t\t*/\n\t\tpresetPixelArt() {\n\t\t\twasm.tracerconfig_presetPixelArt(this.__wbg_ptr);\n\t\t}\n\t\t/**\n\t\t* Preset for photos: smooth curves, speckle filtering\n\t\t*/\n\t\tpresetPhoto() {\n\t\t\twasm.tracerconfig_presetPhoto(this.__wbg_ptr);\n\t\t}\n\t\t/**\n\t\t* Preset for line art: binary mode, high contrast\n\t\t*/\n\t\tpresetLineArt() {\n\t\t\twasm.tracerconfig_presetLineArt(this.__wbg_ptr);\n\t\t}\n\t};\n\tif (Symbol.dispose) TracerConfig.prototype[Symbol.dispose] = TracerConfig.prototype.free;\n}));\n\n//#endregion\n//#region \\0frame-empty:wasm_vtracer_wasm_vtracer_bg_wasm_url\nvar _frame_empty_wasm_vtracer_wasm_vtracer_bg_wasm_url_exports = /* @__PURE__ */ __exportAll({ default: () => \"\" });\nvar _frame_empty_wasm_vtracer_wasm_vtracer_bg_wasm_url_default;\nvar init__frame_empty_wasm_vtracer_wasm_vtracer_bg_wasm_url = __esmMin((() => {\n\t_frame_empty_wasm_vtracer_wasm_vtracer_bg_wasm_url_default = \"\";\n}));\n\n//#endregion\n//#region blocks/native/shared/src/animated/vectorizeClient.js\nlet _tracer = null;\nasync function tracer() {\n\tif (!_tracer) _tracer = (await Promise.resolve().then(() => /* @__PURE__ */ __toESM(require_imagetracer_v1_2_6(), 1))).default;\n\treturn _tracer;\n}\nfunction vtracer() {\n\tif (!globalThis.__vtracerInitPromise) globalThis.__vtracerInitPromise = (async () => {\n\t\tconst [glue, { default: wasmUrl }] = await Promise.all([Promise.resolve().then(() => (init_wasm_vtracer_bg(), wasm_vtracer_bg_exports)), Promise.resolve().then(() => (init__frame_empty_wasm_vtracer_wasm_vtracer_bg_wasm_url(), _frame_empty_wasm_vtracer_wasm_vtracer_bg_wasm_url_exports))]);\n\t\tconst { instance } = await WebAssembly.instantiateStreaming(fetch(wasmUrl), { \"./wasm_vtracer_bg.js\": glue });\n\t\tglue.__wbg_set_wasm(instance.exports);\n\t\tinstance.exports.__wbindgen_start();\n\t\treturn glue;\n\t})().catch((err) => {\n\t\tconsole.warn(\"[trace] VTracer wasm unavailable — falling back to imagetracerjs:\", err?.message || err);\n\t\treturn null;\n\t});\n\treturn globalThis.__vtracerInitPromise;\n}\nfunction bboxOfD(d) {\n\tlet minx = Infinity, miny = Infinity, maxx = -Infinity, maxy = -Infinity;\n\tconst nums = d.match(/-?\\d+(?:\\.\\d+)?/g) || [];\n\tfor (let i = 0; i + 1 < nums.length; i += 2) {\n\t\tconst x = Number(nums[i]), y = Number(nums[i + 1]);\n\t\tminx = Math.min(minx, x);\n\t\tminy = Math.min(miny, y);\n\t\tmaxx = Math.max(maxx, x);\n\t\tmaxy = Math.max(maxy, y);\n\t}\n\treturn Number.isFinite(minx) ? {\n\t\tx: minx,\n\t\ty: miny,\n\t\tw: maxx - minx,\n\t\th: maxy - miny\n\t} : null;\n}\nfunction dTranslate(d, tx, ty) {\n\tif (!tx && !ty) return d;\n\tlet absolute = true;\n\tlet axis = 0;\n\treturn d.replace(/([A-Za-z])|(-?\\d*\\.?\\d+)/g, (tok, cmd) => {\n\t\tif (cmd) {\n\t\t\tabsolute = cmd === cmd.toUpperCase();\n\t\t\taxis = 0;\n\t\t\treturn cmd;\n\t\t}\n\t\tconst n = Number(tok);\n\t\tconst shifted = absolute ? axis === 0 ? n + tx : n + ty : n;\n\t\taxis ^= 1;\n\t\treturn String(Math.round(shifted * 100) / 100);\n\t});\n}\nfunction parseVtracerSvg(svgText, { minArea, dropWhite, canvasSize = 0 }) {\n\tconst doc = new DOMParser().parseFromString(svgText, \"image/svg+xml\");\n\tconst out = [];\n\tconst edgeM = canvasSize * .02;\n\tfor (const el of doc.querySelectorAll(\"path\")) {\n\t\tlet d = el.getAttribute(\"d\");\n\t\tif (!d) continue;\n\t\tconst tr = /translate\\((-?\\d*\\.?\\d+)[ ,]+(-?\\d*\\.?\\d+)\\)/.exec(el.getAttribute(\"transform\") || \"\");\n\t\tif (tr) d = dTranslate(d, Number(tr[1]), Number(tr[2]));\n\t\tconst rawFill = el.getAttribute(\"fill\") || \"#000000\";\n\t\tconst m = /rgba?\\((\\d+),\\s*(\\d+),\\s*(\\d+)/.exec(rawFill) || (/^#[\\da-f]{6}$/i.test(rawFill) ? [\n\t\t\tnull,\n\t\t\tparseInt(rawFill.slice(1, 3), 16),\n\t\t\tparseInt(rawFill.slice(3, 5), 16),\n\t\t\tparseInt(rawFill.slice(5, 7), 16)\n\t\t] : null);\n\t\tif (!m) continue;\n\t\tconst bbox = bboxOfD(d);\n\t\tif (!bbox || bbox.w * bbox.h < minArea) continue;\n\t\tif (dropWhite && +m[1] > 232 && +m[2] > 232 && +m[3] > 232) {\n\t\t\tif (!canvasSize || bbox.x <= edgeM || bbox.y <= edgeM || bbox.x + bbox.w >= canvasSize - edgeM || bbox.y + bbox.h >= canvasSize - edgeM) continue;\n\t\t}\n\t\tout.push({\n\t\t\td,\n\t\t\tbbox,\n\t\t\tfill: `rgb(${m[1]},${m[2]},${m[3]})`\n\t\t});\n\t}\n\treturn out;\n}\nconst pts = (s) => s.type === \"Q\" ? [\n\t[s.x1, s.y1],\n\t[s.x2, s.y2],\n\t[s.x3, s.y3]\n] : [[s.x1, s.y1], [s.x2, s.y2]];\nfunction segmentsToD(segs) {\n\tif (!segs.length) return \"\";\n\tlet d = `M ${segs[0].x1.toFixed(1)} ${segs[0].y1.toFixed(1)} `;\n\tfor (const s of segs) d += s.type === \"Q\" ? `Q ${s.x2.toFixed(1)} ${s.y2.toFixed(1)} ${s.x3.toFixed(1)} ${s.y3.toFixed(1)} ` : `L ${s.x2.toFixed(1)} ${s.y2.toFixed(1)} `;\n\treturn d + \"Z\";\n}\nfunction bboxOfSegments(segs) {\n\tlet minx = Infinity, miny = Infinity, maxx = -Infinity, maxy = -Infinity;\n\tfor (const s of segs) for (const [x, y] of pts(s)) {\n\t\tminx = Math.min(minx, x);\n\t\tminy = Math.min(miny, y);\n\t\tmaxx = Math.max(maxx, x);\n\t\tmaxy = Math.max(maxy, y);\n\t}\n\treturn {\n\t\tx: minx,\n\t\ty: miny,\n\t\tw: maxx - minx,\n\t\th: maxy - miny\n\t};\n}\nfunction unionBounds(paths) {\n\tlet minx = Infinity, miny = Infinity, maxx = -Infinity, maxy = -Infinity;\n\tfor (const p of paths) {\n\t\tminx = Math.min(minx, p.bbox.x);\n\t\tminy = Math.min(miny, p.bbox.y);\n\t\tmaxx = Math.max(maxx, p.bbox.x + p.bbox.w);\n\t\tmaxy = Math.max(maxy, p.bbox.y + p.bbox.h);\n\t}\n\treturn Number.isFinite(minx) ? {\n\t\tx: minx,\n\t\ty: miny,\n\t\tw: maxx - minx,\n\t\th: maxy - miny\n\t} : {\n\t\tx: 0,\n\t\ty: 0,\n\t\tw: 1,\n\t\th: 1\n\t};\n}\nfunction paletteFromImageData(imgd, n = 14) {\n\tconst buckets = /* @__PURE__ */ new Map();\n\tconst d = imgd.data;\n\tfor (let i = 0; i < d.length; i += 8) {\n\t\tif (d[i + 3] < 128) continue;\n\t\tconst r = d[i], g = d[i + 1], b = d[i + 2];\n\t\tconst key = r >> 4 << 8 | g >> 4 << 4 | b >> 4;\n\t\tlet e = buckets.get(key);\n\t\tif (!e) {\n\t\t\te = {\n\t\t\t\tcount: 0,\n\t\t\t\tr: 0,\n\t\t\t\tg: 0,\n\t\t\t\tb: 0\n\t\t\t};\n\t\t\tbuckets.set(key, e);\n\t\t}\n\t\te.count += 1;\n\t\te.r += r;\n\t\te.g += g;\n\t\te.b += b;\n\t}\n\treturn [...buckets.values()].sort((a, b) => b.count - a.count).slice(0, n).map((e) => ({\n\t\tr: Math.round(e.r / e.count),\n\t\tg: Math.round(e.g / e.count),\n\t\tb: Math.round(e.b / e.count),\n\t\ta: 255\n\t}));\n}\nasync function traceCanvasToPaths(canvas, opts = {}) {\n\tif (opts.engine !== \"imagetracer\") try {\n\t\tconst vt = await vtracer();\n\t\tif (vt) {\n\t\t\tconst imgd2 = canvas.getContext(\"2d\").getImageData(0, 0, canvas.width, canvas.height);\n\t\t\tconst config = new vt.TracerConfig();\n\t\t\tconfig.setColorMode(0);\n\t\t\tconfig.setHierarchical(0);\n\t\t\tconfig.setPathSimplifyMode(1);\n\t\t\tconfig.setFilterSpeckle(Math.max(2, Math.round(Math.sqrt(opts.minArea ?? 24) / 2)));\n\t\t\tconfig.setColorPrecision(6);\n\t\t\tconfig.setLayerDifference((opts.numberofcolors || 14) >= 18 ? 10 : 16);\n\t\t\tconst paths = parseVtracerSvg(vt.convertImageToSvg(new Uint8Array(imgd2.data.buffer), canvas.width, canvas.height, config), {\n\t\t\t\tminArea: opts.minArea ?? 24,\n\t\t\t\tdropWhite: opts.dropWhite !== false,\n\t\t\t\tcanvasSize: canvas.width\n\t\t\t});\n\t\t\tif (paths.length) return {\n\t\t\t\tpaths,\n\t\t\t\tbounds: unionBounds(paths),\n\t\t\t\tengine: \"vtracer\"\n\t\t\t};\n\t\t}\n\t} catch (err) {\n\t\tconsole.warn(\"[trace] VTracer failed — using imagetracerjs:\", err?.message || err);\n\t}\n\tconst ImageTracer = await tracer();\n\tconst imgd = canvas.getContext(\"2d\").getImageData(0, 0, canvas.width, canvas.height);\n\tconst td = ImageTracer.imagedataToTracedata(imgd, {\n\t\tltres: 1,\n\t\tqtres: 1,\n\t\tpathomit: 8,\n\t\trightangleenhance: true,\n\t\tnumberofcolors: opts.numberofcolors || 14,\n\t\tmincolorratio: 0,\n\t\tblurradius: 0,\n\t\tpal: opts.pal || paletteFromImageData(imgd, opts.numberofcolors || 14)\n\t});\n\tconst minArea = opts.minArea ?? 24;\n\tconst paths = [];\n\tconst dropWhite = opts.dropWhite !== false;\n\tconst edgeM = canvas.width * .02;\n\tconst touchesEdge = (bbox) => bbox.x <= edgeM || bbox.y <= edgeM || bbox.x + bbox.w >= canvas.width - edgeM || bbox.y + bbox.h >= canvas.height - edgeM;\n\ttd.layers.forEach((layer, li) => {\n\t\tconst col = td.palette[li];\n\t\tif (!col || col.a < 32) return;\n\t\tconst isWhite = col.r > 232 && col.g > 232 && col.b > 232;\n\t\tconst fill = `rgb(${col.r},${col.g},${col.b})`;\n\t\tfor (const p of layer) {\n\t\t\tconst segs = p.segments || [];\n\t\t\tif (!segs.length) continue;\n\t\t\tconst bbox = bboxOfSegments(segs);\n\t\t\tif (bbox.w * bbox.h < minArea) continue;\n\t\t\tif (dropWhite && isWhite && touchesEdge(bbox)) continue;\n\t\t\tpaths.push({\n\t\t\t\td: segmentsToD(segs),\n\t\t\t\tbbox,\n\t\t\t\tfill\n\t\t\t});\n\t\t}\n\t});\n\tpaths.sort((a, b) => b.bbox.w * b.bbox.h - a.bbox.w * a.bbox.h);\n\treturn {\n\t\tpaths,\n\t\tbounds: unionBounds(paths),\n\t\tengine: \"imagetracer\"\n\t};\n}\n\n//#endregion\n//#region blocks/native/sm.panel-strip/frame/main.js\nconst fail = (message) => {\n\tthrow Error(message);\n};\nconst plain = (value) => !!value && typeof value === \"object\" && !Array.isArray(value);\nconst isImage = (value) => plain(value) && value.kind === \"image\" && typeof value.url === \"string\";\nfunction panelResult(doc, pictures) {\n\tif (!plain(doc) || !Array.isArray(doc.strip)) return {};\n\tconst seen = /* @__PURE__ */ new Set(), images = (Array.isArray(pictures) ? pictures : []).filter((ref) => plain(ref) && [\"image\", \"video\"].includes(ref.kind) && typeof ref.url === \"string\" && !seen.has(ref.url) && seen.add(ref.url));\n\treturn {\n\t\tpanels: doc,\n\t\t...images.length ? { images } : {}\n\t};\n}\nlet current = null;\nuseImagePanelTextModel({\n\tready: () => true,\n\tchatCollect: async ({ system = \"\", max_tokens, messages = [] }) => {\n\t\tconst { stillmade, images } = current || fail(\"Image Panels is not running.\");\n\t\tconst words = [], shown = [];\n\t\tfor (const message of messages) for (const part of Array.isArray(message.content) ? message.content : [{\n\t\t\ttype: \"text\",\n\t\t\ttext: String(message.content || \"\")\n\t\t}]) if (part.type === \"image_url\") {\n\t\t\tconst ref = images.get(part.image_url?.url);\n\t\t\tif (!ref) fail(\"A picture this needs is not saved in the Step.\");\n\t\t\tshown.push(ref);\n\t\t} else if (typeof part.text === \"string\") words.push(part.text);\n\t\tconst prompt = words.join(\"\\n\\n\") || \"Answer.\";\n\t\tconst answer = shown.length ? await stillmade.hosted.run(\"media.analyze\", {\n\t\t\tmedia: shown.length === 1 ? shown[0] : shown.slice(0, 10),\n\t\t\tquestion: prompt.slice(0, 8e3),\n\t\t\treply: \"text\",\n\t\t\t...system ? { instructions: system.slice(0, 8e3) } : {},\n\t\t\tmaxTokens: Math.max(1, Math.min(Number(max_tokens) || 1200, 4e3))\n\t\t}) : await stillmade.hosted.run(\"text.generate\", {\n\t\t\tsystem,\n\t\t\tprompt,\n\t\t\tmaxTokens: Math.max(1, Math.min(Number(max_tokens) || 1200, 24e3))\n\t\t});\n\t\treturn typeof answer === \"string\" ? answer : JSON.stringify(answer);\n\t}\n});\nconst dataUrlBytes = (dataUrl) => {\n\tconst match = /^data:([a-z]+\\/[a-z0-9.+-]+);base64,(.+)$/i.exec(String(dataUrl || \"\"));\n\tif (!match) fail(\"Choose a picture to save.\");\n\tconst text = atob(match[2]), bytes = new Uint8Array(text.length);\n\tfor (let index = 0; index < text.length; index++) bytes[index] = text.charCodeAt(index);\n\treturn {\n\t\tmediaType: match[1].toLowerCase(),\n\t\tbuffer: bytes.buffer\n\t};\n};\nconst EXTENSIONS = {\n\t\"image/png\": \"png\",\n\t\"image/jpeg\": \"jpg\",\n\t\"image/webp\": \"webp\",\n\t\"image/gif\": \"gif\"\n};\nasync function crop(stillmade, image, rect) {\n\tconst bitmap = await createImageBitmap(new Blob([await stillmade.files.read(image)]));\n\tconst x = Math.round(rect.x * bitmap.width), y = Math.round(rect.y * bitmap.height), width = Math.max(1, Math.round(rect.w * bitmap.width)), height = Math.max(1, Math.round(rect.h * bitmap.height));\n\tconst canvas = new OffscreenCanvas(width, height);\n\tcanvas.getContext(\"2d\").drawImage(bitmap, x, y, width, height, 0, 0, width, height);\n\tbitmap.close?.();\n\treturn stillmade.files.write(await (await canvas.convertToBlob({ type: \"image/png\" })).arrayBuffer(), {\n\t\tmediaType: \"image/png\",\n\t\tname: \"crop.png\"\n\t});\n}\nasync function upscale(stillmade, image) {\n\tconst bitmap = await createImageBitmap(new Blob([await stillmade.files.read(image)]));\n\tconst scale = Math.max(1, 1080 / Math.min(bitmap.width, bitmap.height)), width = Math.round(bitmap.width * scale), height = Math.round(bitmap.height * scale);\n\tconst canvas = new OffscreenCanvas(width, height), context = canvas.getContext(\"2d\");\n\tcontext.imageSmoothingQuality = \"high\";\n\tcontext.drawImage(bitmap, 0, 0, width, height);\n\tbitmap.close?.();\n\treturn stillmade.files.write(await (await canvas.convertToBlob({ type: \"image/png\" })).arrayBuffer(), {\n\t\tmediaType: \"image/png\",\n\t\tname: \"upscaled.png\"\n\t});\n}\nasync function vectorize(stillmade, image) {\n\tconst bitmap = await createImageBitmap(new Blob([await stillmade.files.read(image)]));\n\tconst source = new OffscreenCanvas(bitmap.width, bitmap.height);\n\tsource.getContext(\"2d\").drawImage(bitmap, 0, 0);\n\tconst { paths } = await traceCanvasToPaths(source, {\n\t\tengine: \"imagetracer\",\n\t\tdropWhite: false,\n\t\tnumberofcolors: 16\n\t});\n\tif (!paths.length) fail(\"The picture could not be traced.\");\n\tconst scale = Math.max(1, 1080 / Math.min(bitmap.width, bitmap.height)), width = Math.round(bitmap.width * scale), height = Math.round(bitmap.height * scale);\n\tbitmap.close?.();\n\tconst canvas = new OffscreenCanvas(width, height), context = canvas.getContext(\"2d\");\n\tcontext.fillStyle = \"#ffffff\";\n\tcontext.fillRect(0, 0, width, height);\n\tcontext.scale(scale, scale);\n\tfor (const path of paths) {\n\t\tcontext.fillStyle = path.fill;\n\t\tcontext.fill(new Path2D(path.d));\n\t}\n\treturn stillmade.files.write(await (await canvas.convertToBlob({ type: \"image/png\" })).arrayBuffer(), {\n\t\tmediaType: \"image/png\",\n\t\tname: \"vectorized.png\"\n\t});\n}\nconst action = (stillmade, operation, request) => stillmade.actions.run({\n\tschemaVersion: 1,\n\tkind: \"stillmade.media-action\",\n\toperation,\n\tresultPort: null,\n\trequest\n});\nconst mediaRef = (asset) => ({\n\tkind: asset.kind,\n\tassetId: asset.assetId,\n\tversionId: asset.versionId,\n\turl: asset.url,\n\t...asset.name ? { name: asset.name } : {}\n});\nasync function searchGifs(stillmade, query, limit = 24) {\n\tconst found = await action(stillmade, \"gif.search\", {\n\t\tquery: String(query || \"\").slice(0, 200),\n\t\tlimit: Math.max(1, Math.min(24, Number.isInteger(limit) ? limit : 24))\n\t});\n\treturn {\n\t\tenabled: found?.enabled !== false,\n\t\tresults: Array.isArray(found?.results) ? found.results : []\n\t};\n}\nasync function saveGif(stillmade, url) {\n\tconst { asset } = await action(stillmade, \"gif.save\", { url });\n\tif (!asset?.url) fail(\"The GIF could not be kept.\");\n\treturn mediaRef(asset);\n}\nasync function run(input, stillmade) {\n\tconst make = typeof input.make === \"string\" ? input.make : \"use\";\n\tconst request = plain(input.request) ? input.request : {};\n\tconst references = (Array.isArray(input.references) ? input.references : []).filter(isImage);\n\tcurrent = {\n\t\tstillmade,\n\t\timages: new Map([...references, ...isImage(input.image) ? [input.image] : []].map((ref) => [ref.url, ref]))\n\t};\n\tconst done = (result, made = []) => ({\n\t\t...panelResult(input.panels, input.pictures),\n\t\t...made.length ? { made } : {},\n\t\tresult: result === void 0 ? null : result\n\t});\n\ttry {\n\t\tswitch (make) {\n\t\t\tcase \"use\": return done(null);\n\t\t\tcase \"plan\":\n\t\t\t\tstillmade.progress(.1, \"Planning the panels\");\n\t\t\t\treturn done(await planStrip({ ...request }));\n\t\t\tcase \"plan-gifs\": {\n\t\t\t\tconst planned = await planGifRetention({ ...request }), beats = [], made = [];\n\t\t\t\tfor (const beat of Array.isArray(planned) ? planned : []) {\n\t\t\t\t\tlet found;\n\t\t\t\t\ttry {\n\t\t\t\t\t\tfound = await searchGifs(stillmade, beat.gifQuery, 6);\n\t\t\t\t\t} catch {\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tif (!found.enabled) return done([]);\n\t\t\t\t\tif (!found.results.length) continue;\n\t\t\t\t\tconst [top] = found.results;\n\t\t\t\t\tlet kept = null;\n\t\t\t\t\ttry {\n\t\t\t\t\t\tkept = await saveGif(stillmade, top.url);\n\t\t\t\t\t\tmade.push(kept);\n\t\t\t\t\t} catch {}\n\t\t\t\t\tbeats.push({\n\t\t\t\t\t\t...beat,\n\t\t\t\t\t\tgiphyId: top.id,\n\t\t\t\t\t\tgifUrl: kept?.url || top.url,\n\t\t\t\t\t\tcandidates: found.results.slice(0, 6).map((gif, index) => ({\n\t\t\t\t\t\t\tgiphyId: gif.id,\n\t\t\t\t\t\t\tgifUrl: index === 0 && kept ? kept.url : gif.url,\n\t\t\t\t\t\t\tpreviewUrl: index === 0 && kept ? kept.url : gif.previewUrl,\n\t\t\t\t\t\t\t...gif.preview ? { preview: gif.preview } : {},\n\t\t\t\t\t\t\t...gif.original ? { original: gif.original } : {},\n\t\t\t\t\t\t\twidth: gif.width,\n\t\t\t\t\t\t\theight: gif.height\n\t\t\t\t\t\t}))\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\treturn done(beats, made);\n\t\t\t}\n\t\t\tcase \"plan-canvas\": return done(await planCanvasCollages({ ...request }));\n\t\t\tcase \"name-elements\": return done(await nameRevealElements({\n\t\t\t\t...request,\n\t\t\t\timageUrl: input.image?.url\n\t\t\t}));\n\t\t\tcase \"place-text\": return done(await placeTextOverlays({\n\t\t\t\t...request,\n\t\t\t\timageUrl: input.image?.url\n\t\t\t}));\n\t\t\tcase \"zoom-target\": return done(await pickZoomTarget({\n\t\t\t\t...request,\n\t\t\t\timageUrl: input.image?.url\n\t\t\t}));\n\t\t\tcase \"consistency\": {\n\t\t\t\tconst [anchor, ...rest] = references;\n\t\t\t\tconst panels = (Array.isArray(request.panels) ? request.panels : []).map((panel, index) => ({\n\t\t\t\t\t...panel,\n\t\t\t\t\turl: rest[index]?.url\n\t\t\t\t})).filter((panel) => panel.url);\n\t\t\t\treturn done(await checkPanelConsistency({\n\t\t\t\t\t...request,\n\t\t\t\t\tanchorUrl: anchor?.url,\n\t\t\t\t\tpanels\n\t\t\t\t}));\n\t\t\t}\n\t\t\tcase \"style-analyze\": {\n\t\t\t\tif (!references.length) fail(\"Add pictures of the style first.\");\n\t\t\t\tconst prompt = await stillmade.hosted.run(\"media.analyze\", {\n\t\t\t\t\tmedia: references.length === 1 ? references[0] : references.slice(0, 8),\n\t\t\t\t\tquestion: ANALYZE_UPLOADS_PROMPT,\n\t\t\t\t\treply: \"text\",\n\t\t\t\t\tmaxTokens: 512\n\t\t\t\t});\n\t\t\t\treturn done(String(prompt || \"\").trim());\n\t\t\t}\n\t\t\tcase \"image\": {\n\t\t\t\tif (typeof request.readablePrompt !== \"string\" || !request.readablePrompt.trim()) fail(\"Write what the picture shows first.\");\n\t\t\t\tstillmade.progress(.2, \"Making the picture\");\n\t\t\t\tconst settings = Object.fromEntries(Object.entries({\n\t\t\t\t\tmodel: request.model,\n\t\t\t\t\taspectRatio: request.aspectRatio,\n\t\t\t\t\tquality: request.quality,\n\t\t\t\t\tresolution: request.resolution\n\t\t\t\t}).filter(([, value]) => typeof value === \"string\" && value));\n\t\t\t\tconst made = await stillmade.hosted.run(\"image.generate\", {\n\t\t\t\t\tprompt: request.readablePrompt,\n\t\t\t\t\t...references.length ? { references: references.slice(0, 8) } : {},\n\t\t\t\t\t...Object.keys(settings).length ? { settings } : {}\n\t\t\t\t});\n\t\t\t\treturn done(made, [made]);\n\t\t\t}\n\t\t\tcase \"video\": {\n\t\t\t\tstillmade.progress(.1, \"Making the clip\");\n\t\t\t\tconst settings = Object.fromEntries(Object.entries({\n\t\t\t\t\tmodel: request.model,\n\t\t\t\t\taspectRatio: request.aspectRatio,\n\t\t\t\t\tquality: request.quality,\n\t\t\t\t\tresolution: request.resolution,\n\t\t\t\t\tduration: request.duration,\n\t\t\t\t\tseed: request.seed,\n\t\t\t\t\tgenerateAudio: request.generateAudio\n\t\t\t\t}).filter(([, value]) => value !== void 0 && value !== null && value !== \"\"));\n\t\t\t\tconst made = await stillmade.hosted.run(\"video.generate\", {\n\t\t\t\t\tprompt: request.readablePrompt || \"\",\n\t\t\t\t\t...isImage(input.firstFrame) ? { firstFrame: input.firstFrame } : {},\n\t\t\t\t\t...isImage(input.lastFrame) ? { lastFrame: input.lastFrame } : {},\n\t\t\t\t\t...request.negativePrompt ? { negativePrompt: request.negativePrompt } : {},\n\t\t\t\t\t...Object.keys(settings).length ? { settings } : {}\n\t\t\t\t});\n\t\t\t\treturn done(made, [made]);\n\t\t\t}\n\t\t\tcase \"upload\": {\n\t\t\t\tconst { mediaType, buffer } = dataUrlBytes(input.dataUrl);\n\t\t\t\tif (!EXTENSIONS[mediaType]) fail(\"Save a PNG, JPEG, WebP or GIF picture.\");\n\t\t\t\tconst saved = await stillmade.files.write(buffer, {\n\t\t\t\t\tmediaType,\n\t\t\t\t\tname: `upload.${EXTENSIONS[mediaType]}`\n\t\t\t\t});\n\t\t\t\treturn done(saved, [saved]);\n\t\t\t}\n\t\t\tcase \"crop\": {\n\t\t\t\tif (!isImage(input.image)) fail(\"Choose the picture to crop.\");\n\t\t\t\tconst saved = await crop(stillmade, input.image, request.rect || {});\n\t\t\t\treturn done(saved, [saved]);\n\t\t\t}\n\t\t\tcase \"process-images\": {\n\t\t\t\tconst map = {}, made = [];\n\t\t\t\tfor (const [index, image] of references.entries()) {\n\t\t\t\t\tstillmade.progress((index + .5) / Math.max(1, references.length), request.mode === \"vectorize\" ? \"Vectorizing the pictures\" : \"Upscaling the pictures\");\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst saved = request.mode === \"vectorize\" ? await vectorize(stillmade, image) : request.mode === \"upscale\" ? await upscale(stillmade, image) : null;\n\t\t\t\t\t\tmap[image.url] = saved?.url || image.url;\n\t\t\t\t\t\tif (saved) made.push(saved);\n\t\t\t\t\t} catch {\n\t\t\t\t\t\tmap[image.url] = image.url;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn done({ map }, made);\n\t\t\t}\n\t\t\tcase \"stock-status\": return done({ available: true });\n\t\t\tcase \"stock-grid\": {\n\t\t\t\tconst { results } = await stillmade.actions.run({\n\t\t\t\t\tschemaVersion: 1,\n\t\t\t\t\tkind: \"stillmade.media-action\",\n\t\t\t\t\toperation: \"stock.search\",\n\t\t\t\t\tresultPort: null,\n\t\t\t\t\trequest: {\n\t\t\t\t\t\tquery: String(request.query || request.q || \"\").slice(0, 500) || \"scene\",\n\t\t\t\t\t\ttype: [\"video\", \"audio\"].includes(request.type) ? request.type : \"photo\"\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\treturn done(results || []);\n\t\t\t}\n\t\t\tcase \"stock-select\": {\n\t\t\t\tconst { preview, original, ...result } = plain(request.result) ? request.result : fail(\"Choose a stock result first.\");\n\t\t\t\tconst { asset } = await action(stillmade, \"stock.select\", { result });\n\t\t\t\treturn done({\n\t\t\t\t\tok: true,\n\t\t\t\t\tcharged: asset?.acquisitionReceipt?.chargedCredits ?? 0,\n\t\t\t\t\treceipt: asset?.acquisitionReceipt ?? null,\n\t\t\t\t\turl: asset?.url\n\t\t\t\t}, asset ? [mediaRef(asset)] : []);\n\t\t\t}\n\t\t\tcase \"stock-auto\": {\n\t\t\t\tconst queries = (Array.isArray(request.queries) ? request.queries : [request.queries]).filter((query) => typeof query === \"string\" && query.trim()).map((query) => query.slice(0, 400)).slice(0, 10);\n\t\t\t\tif (!queries.length && typeof request.description === \"string\" && request.description.trim()) queries.push(request.description.slice(0, 400));\n\t\t\t\tif (!queries.length) return done({ noMatch: true });\n\t\t\t\tconst found = await action(stillmade, \"stock.auto\", {\n\t\t\t\t\tqueries,\n\t\t\t\t\tkind: request.kind === \"video\" ? \"video\" : \"photo\",\n\t\t\t\t\texcludeUrls: (Array.isArray(request.excludeUrls) ? request.excludeUrls : []).filter((url) => typeof url === \"string\" && url).slice(0, 300)\n\t\t\t\t});\n\t\t\t\tif (!found.asset) return done(found.transient ? {\n\t\t\t\t\ttransient: true,\n\t\t\t\t\tnote: \"Stock sources are busy right now. Try again in a moment.\"\n\t\t\t\t} : { noMatch: true });\n\t\t\t\treturn done({\n\t\t\t\t\tresult: found.result,\n\t\t\t\t\tcharged: found.asset.acquisitionReceipt?.chargedCredits ?? 0,\n\t\t\t\t\treceipt: found.asset.acquisitionReceipt ?? null\n\t\t\t\t}, [mediaRef(found.asset)]);\n\t\t\t}\n\t\t\tcase \"gif-search\": {\n\t\t\t\tconst found = await searchGifs(stillmade, request.query, request.limit);\n\t\t\t\tif (!found.enabled || !found.results.length) return done({\n\t\t\t\t\tenabled: found.enabled,\n\t\t\t\t\tresults: [],\n\t\t\t\t\tpoweredBy: \"giphy\"\n\t\t\t\t});\n\t\t\t\tconst [first, ...rest] = found.results, saved = await saveGif(stillmade, first.url);\n\t\t\t\treturn done({\n\t\t\t\t\tenabled: true,\n\t\t\t\t\tresults: [{\n\t\t\t\t\t\t...first,\n\t\t\t\t\t\turl: saved.url,\n\t\t\t\t\t\tpreviewUrl: saved.url\n\t\t\t\t\t}, ...rest],\n\t\t\t\t\tpoweredBy: \"giphy\"\n\t\t\t\t}, [saved]);\n\t\t\t}\n\t\t\tcase \"gif-save\": {\n\t\t\t\tconst map = {}, made = [];\n\t\t\t\tfor (const url of (Array.isArray(request.urls) ? request.urls : []).filter((url) => typeof url === \"string\").slice(0, 48)) try {\n\t\t\t\t\tconst saved = await saveGif(stillmade, url);\n\t\t\t\t\tmap[url] = saved.url;\n\t\t\t\t\tmade.push(saved);\n\t\t\t\t} catch {}\n\t\t\t\treturn done({ map }, made);\n\t\t\t}\n\t\t\tcase \"presenter\": {\n\t\t\t\tconst doc = plain(input.panels) ? input.panels : fail(\"Plan the panels first.\");\n\t\t\t\tconst words = (Array.isArray(request.voiceover?.words) ? request.voiceover.words : []).map((word) => typeof word === \"string\" ? word : word?.text || \"\").join(\" \");\n\t\t\t\tconst prompt = (String(doc.meta?.canvasChat?.intent || \"\") || words || \"A presenter who explains the story\").slice(0, 4e3);\n\t\t\t\tconst { edit } = await action(stillmade, \"presenter.generate\", {\n\t\t\t\t\tboard: doc,\n\t\t\t\t\tprompt,\n\t\t\t\t\tvoiceover: plain(request.voiceover) ? request.voiceover : {}\n\t\t\t\t});\n\t\t\t\tconst after = plain(edit?.after) ? {\n\t\t\t\t\t...edit.after,\n\t\t\t\t\tmeta: {\n\t\t\t\t\t\t...edit.after.meta || {},\n\t\t\t\t\t\t...doc.meta && Object.hasOwn(doc.meta, \"canvasChat\") ? { canvasChat: doc.meta.canvasChat } : {}\n\t\t\t\t\t}\n\t\t\t\t} : doc;\n\t\t\t\tif (after.meta && !Object.hasOwn(doc.meta || {}, \"canvasChat\")) delete after.meta.canvasChat;\n\t\t\t\treturn {\n\t\t\t\t\t...panelResult(after, input.pictures),\n\t\t\t\t\tresult: { doc: after }\n\t\t\t\t};\n\t\t\t}\n\t\t\tcase \"storage-get\": return done(await stillmade.storage.get(String(input.key || \"\")));\n\t\t\tcase \"storage-set\":\n\t\t\t\tawait stillmade.storage.set(String(input.key || \"\"), input.value ?? null);\n\t\t\t\treturn done(true);\n\t\t}\n\t\tfail(`${make} is not something Image Panels makes yet.`);\n\t} finally {\n\t\tcurrent = null;\n\t}\n}\n\n//#endregion\nexport { run as default };"
349
+ }
350
+ };