stillmade-sdk 0.1.46 → 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.
- package/.stillmade/sdk-baseline.json +1 -1
- package/AGENTS.md +6 -2
- package/FRAME_VIEWS.md +71 -5
- package/INTERFACE_DESIGN.md +105 -15
- package/MODULES.md +26 -3
- package/PASTE_TO_LLM.md +27 -10
- package/README.md +15 -0
- package/SDK.md +393 -64
- package/UI_AESTHETIC.md +13 -0
- package/blocks/native/sm.board-editor/versions/3.0.0/package.js +921 -0
- package/blocks/native/sm.editor/versions/3.0.0/package.js +751 -0
- package/blocks/native/sm.panel-strip/versions/3.0.0/package.js +350 -0
- package/blocks/native/sm.photo-editor/versions/1.0.0/package.js +6693 -0
- package/blocks/native/sm.voiceover/versions/3.0.0/package.js +513 -0
- package/docs/build/block-builder-contract.md +2 -2
- package/docs/build/custom-interface.md +23 -3
- package/docs/build/frame-views.md +71 -5
- package/docs/build/hosted-text.md +8 -3
- package/docs/build/interface-design.md +105 -15
- package/docs/build/media-analysis.md +18 -1
- package/docs/build/modules.md +26 -3
- package/docs/build/with-your-ai.md +14 -0
- package/docs/build/workspaces.md +42 -0
- package/docs/reference/authoring-guide.md +5 -4
- package/docs/reference/cli.md +8 -3
- package/docs/reference/execution.md +13 -5
- package/docs/reference/first-party-blocks.md +5 -4
- package/docs/reference/generation-models.md +4 -0
- package/docs/reference/limits.md +9 -2
- package/docs/reference/permissions.md +4 -0
- package/docs/reference/view-bridge.md +6 -3
- package/docs/reference/view-rules.md +2 -1
- package/docs/tools/llm.md +27 -10
- package/examples/custom-interface.stillmade.json +2 -2
- package/package.json +1 -1
- package/packages/block-cli/cli.js +124 -12
- package/packages/block-cli/dev-host/assets/host.js +63 -37
- package/packages/block-cli/dev-host/assets/index.css +1 -1
- package/packages/block-cli/dev-server.js +74 -23
- package/packages/block-cli/format.js +20 -1
- package/packages/block-cli/ready-gate.js +34 -2
- package/packages/block-cli/templates.js +61 -0
- package/packages/block-cli/type-packages.js +7 -4
- package/packages/block-cli/workspace-dev.js +124 -0
- package/packages/block-cli/workspace-pack.js +62 -0
- package/packages/block-cli/workspace.js +304 -0
- package/packages/block-platform/block-readiness.js +5 -4
- package/packages/block-platform/catalog.js +5 -3
- package/packages/block-platform/node-defaults.js +2 -2
- package/packages/block-platform/plain-descriptions.js +1 -0
- package/packages/block-platform/type-workspace.js +8 -0
- package/packages/block-sdk/admission.js +2 -2
- package/packages/block-sdk/builder-contract.js +3 -3
- package/packages/block-sdk/capabilities.js +32 -12
- package/packages/block-sdk/contracts.js +11 -2
- package/packages/block-sdk/examples.js +2 -2
- package/packages/block-sdk/first-party-identities.js +9 -0
- package/packages/block-sdk/first-party-packages.js +9 -1
- package/packages/block-sdk/folder-package.js +34 -2
- package/packages/block-sdk/generation-catalog.js +7 -0
- package/packages/block-sdk/index.d.ts +13 -5
- package/packages/block-sdk/index.js +1 -1
- package/packages/block-sdk/mock-host.js +7 -0
- package/packages/block-sdk/module-hosted.js +11 -1
- package/packages/block-sdk/module-media-access.js +5 -3
- package/packages/block-sdk/permission-summary.js +1 -1
- package/packages/block-sdk/portable-media-actions.d.ts +4 -1
- package/packages/block-sdk/portable-media-actions.js +16 -1
- package/packages/block-sdk/remix-policy.js +2 -2
- package/packages/block-sdk/staged-releases.js +5 -0
- package/packages/block-sdk/stillmade-pack.js +64 -0
- package/packages/block-sdk/testing.js +2 -2
- package/packages/block-sdk/view-bridge.js +6 -3
- package/packages/block-sdk/view-design.js +65 -17
- package/packages/block-sdk/view-renderer.js +17 -1
- package/packages/block-sdk/view.js +47 -9
- package/packages/design-system/block-kit.css +23 -0
- package/packages/design-system/theme.css +10 -7
|
@@ -0,0 +1,921 @@
|
|
|
1
|
+
// Generated by frame/build-package.mjs from the original White Board Motion screen. Edit the screen or frame/, then rebuild.
|
|
2
|
+
export default {
|
|
3
|
+
"manifest": {
|
|
4
|
+
"schemaVersion": 1,
|
|
5
|
+
"sdkVersion": "0.1.0",
|
|
6
|
+
"id": "sm.board-editor",
|
|
7
|
+
"version": "3.0.0",
|
|
8
|
+
"name": "White Board Motion",
|
|
9
|
+
"description": "Make text, pictures and clips pop in and move on white boards in time with your narration: build boards from a chat, arrange and animate each element, add a presenter, 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. Text and media pop in on these words."
|
|
20
|
+
},
|
|
21
|
+
"narrationAudio": {
|
|
22
|
+
"type": "audio",
|
|
23
|
+
"required": false,
|
|
24
|
+
"semantic": "narration_audio",
|
|
25
|
+
"description": "The narration audio that plays under the boards."
|
|
26
|
+
},
|
|
27
|
+
"board": {
|
|
28
|
+
"type": "board-document",
|
|
29
|
+
"required": false,
|
|
30
|
+
"semantic": "whiteboard_document",
|
|
31
|
+
"description": "The boards on this screen."
|
|
32
|
+
},
|
|
33
|
+
"files": {
|
|
34
|
+
"type": "asset[]",
|
|
35
|
+
"required": false,
|
|
36
|
+
"semantic": "export_media",
|
|
37
|
+
"description": "The saved pictures, clips and sound the boards use, for an export."
|
|
38
|
+
},
|
|
39
|
+
"make": {
|
|
40
|
+
"type": "text",
|
|
41
|
+
"required": false,
|
|
42
|
+
"semantic": "board_action",
|
|
43
|
+
"description": "What a run makes: a board plan, a description, a picture, a clip, a presenter pose or the result."
|
|
44
|
+
},
|
|
45
|
+
"request": {
|
|
46
|
+
"type": "json",
|
|
47
|
+
"schema": "json",
|
|
48
|
+
"required": false,
|
|
49
|
+
"semantic": "board_request",
|
|
50
|
+
"description": "The details of what to make."
|
|
51
|
+
},
|
|
52
|
+
"references": {
|
|
53
|
+
"type": "image[]",
|
|
54
|
+
"required": false,
|
|
55
|
+
"semantic": "reference_image",
|
|
56
|
+
"description": "Saved pictures a new picture keeps."
|
|
57
|
+
},
|
|
58
|
+
"image": {
|
|
59
|
+
"type": "image",
|
|
60
|
+
"required": false,
|
|
61
|
+
"semantic": "board_image",
|
|
62
|
+
"description": "The saved picture a description looks at."
|
|
63
|
+
},
|
|
64
|
+
"firstFrame": {
|
|
65
|
+
"type": "image",
|
|
66
|
+
"required": false,
|
|
67
|
+
"semantic": "first_frame",
|
|
68
|
+
"description": "The picture a clip starts on."
|
|
69
|
+
},
|
|
70
|
+
"lastFrame": {
|
|
71
|
+
"type": "image",
|
|
72
|
+
"required": false,
|
|
73
|
+
"semantic": "last_frame",
|
|
74
|
+
"description": "The picture a clip ends on."
|
|
75
|
+
},
|
|
76
|
+
"dataUrl": {
|
|
77
|
+
"type": "text",
|
|
78
|
+
"required": false,
|
|
79
|
+
"semantic": "file_data",
|
|
80
|
+
"description": "A picture or clip the screen saves, such as an upload or a presenter pose."
|
|
81
|
+
},
|
|
82
|
+
"key": {
|
|
83
|
+
"type": "text",
|
|
84
|
+
"required": false,
|
|
85
|
+
"semantic": "storage_key",
|
|
86
|
+
"description": "A saved setting of this Block."
|
|
87
|
+
},
|
|
88
|
+
"value": {
|
|
89
|
+
"type": "json",
|
|
90
|
+
"schema": "json",
|
|
91
|
+
"required": false,
|
|
92
|
+
"semantic": "storage_value",
|
|
93
|
+
"description": "The value of that setting."
|
|
94
|
+
}
|
|
95
|
+
},
|
|
96
|
+
"outputs": {
|
|
97
|
+
"output": {
|
|
98
|
+
"type": "board-document",
|
|
99
|
+
"primary": true,
|
|
100
|
+
"role": "whiteboard_document",
|
|
101
|
+
"semantic": "whiteboard_document",
|
|
102
|
+
"description": "The complete White Board Motion document for the next Step."
|
|
103
|
+
},
|
|
104
|
+
"editorTimeline": {
|
|
105
|
+
"type": "timeline",
|
|
106
|
+
"required": false,
|
|
107
|
+
"role": "editor_handoff",
|
|
108
|
+
"semantic": "editor_handoff",
|
|
109
|
+
"description": "The Editor cut of every board: one clip per board with its transitions, the narration and the board sounds."
|
|
110
|
+
},
|
|
111
|
+
"export": {
|
|
112
|
+
"type": "asset",
|
|
113
|
+
"required": false,
|
|
114
|
+
"semantic": "exported_video",
|
|
115
|
+
"description": "The exported video of the boards, to download or pass on."
|
|
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": "board_answer",
|
|
128
|
+
"description": "What the screen asked for: a board plan, edits, a description."
|
|
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
|
+
"final.render"
|
|
142
|
+
],
|
|
143
|
+
"network": [],
|
|
144
|
+
"filesystem": [],
|
|
145
|
+
"secrets": []
|
|
146
|
+
},
|
|
147
|
+
"platforms": {
|
|
148
|
+
"phone": {
|
|
149
|
+
"supported": true
|
|
150
|
+
},
|
|
151
|
+
"browser": {
|
|
152
|
+
"supported": true
|
|
153
|
+
},
|
|
154
|
+
"desktop": {
|
|
155
|
+
"supported": true
|
|
156
|
+
}
|
|
157
|
+
},
|
|
158
|
+
"provenance": {
|
|
159
|
+
"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"
|
|
160
|
+
}
|
|
161
|
+
},
|
|
162
|
+
"module": {
|
|
163
|
+
"schemaVersion": 1,
|
|
164
|
+
"entry": "main.js",
|
|
165
|
+
"files": {
|
|
166
|
+
"main.js": {
|
|
167
|
+
"sha256": "e44dfdccb7948f5ae9e7918da2b15ebf308adc246fd581d293facf2711d65861",
|
|
168
|
+
"bytes": 115377,
|
|
169
|
+
"mediaType": "text/javascript"
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
},
|
|
173
|
+
"view": {
|
|
174
|
+
"html": "<div id=\"root\"></div>\n",
|
|
175
|
+
"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",
|
|
176
|
+
"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 N(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 P={current:null},F={transition:null},I={ReactCurrentDispatcher:P,ReactCurrentBatchConfig:F,ReactCurrentOwner:C};function L(){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=I,e.act=L,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:N}},e.memo=function(e,t){return{$$typeof:u,type:e,compare:t===void 0?null:t}},e.startTransition=function(e){var t=F.transition;F.transition={};try{e()}finally{F.transition=t}},e.unstable_act=L,e.useCallback=function(e,t){return P.current.useCallback(e,t)},e.useContext=function(e){return P.current.useContext(e)},e.useDebugValue=function(){},e.useDeferredValue=function(e){return P.current.useDeferredValue(e)},e.useEffect=function(e,t){return P.current.useEffect(e,t)},e.useId=function(){return P.current.useId()},e.useImperativeHandle=function(e,t,n){return P.current.useImperativeHandle(e,t,n)},e.useInsertionEffect=function(e,t){return P.current.useInsertionEffect(e,t)},e.useLayoutEffect=function(e,t){return P.current.useLayoutEffect(e,t)},e.useMemo=function(e,t){return P.current.useMemo(e,t)},e.useReducer=function(e,t,n){return P.current.useReducer(e,t,n)},e.useRef=function(e){return P.current.useRef(e)},e.useState=function(e){return P.current.useState(e)},e.useSyncExternalStore=function(e,t,n){return P.current.useSyncExternalStore(e,t,n)},e.useTransition=function(){return P.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&&N(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&&N(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 N(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,N(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`),N=Symbol.for(`react.suspense_list`),P=Symbol.for(`react.memo`),F=Symbol.for(`react.lazy`),I=Symbol.for(`react.offscreen`),L=Symbol.iterator;function R(e){return typeof e!=`object`||!e?null:(e=L&&e[L]||e[`@@iterator`],typeof e==`function`?e:null)}var z=Object.assign,B;function V(e){if(B===void 0)try{throw Error()}catch(e){var t=e.stack.trim().match(/\\n( *(at )?)/);B=t&&t[1]||``}return`\n`+B+e}var ee=!1;function H(e,t){if(!e||ee)return``;ee=!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{ee=!1,Error.prepareStackTrace=n}return(e=e?e.displayName||e.name:``)?V(e):``}function te(e){switch(e.tag){case 5:return V(e.type);case 16:return V(`Lazy`);case 13:return V(`Suspense`);case 19:return V(`SuspenseList`);case 0:case 2:case 15:return e=H(e.type,!1),e;case 11:return e=H(e.type.render,!1),e;case 1:return e=H(e.type,!0),e;default:return``}}function ne(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 N: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 P:return t=e.displayName||null,t===null?ne(e.type)||`Memo`:t;case F:t=e._payload,e=e._init;try{return ne(e(t))}catch{}}return null}function re(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 ne(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 ie(e){switch(typeof e){case`boolean`:case`number`:case`string`:case`undefined`:return e;case`object`:return e;default:return``}}function ae(e){var t=e.type;return(e=e.nodeName)&&e.toLowerCase()===`input`&&(t===`checkbox`||t===`radio`)}function oe(e){var t=ae(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 se(e){e._valueTracker||=oe(e)}function ce(e){if(!e)return!1;var t=e._valueTracker;if(!t)return!0;var n=t.getValue(),r=``;return e&&(r=ae(e)?e.checked?`true`:`false`:e.value),e=r,e!==n&&(t.setValue(e),!0)}function le(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 ue(e,t){var n=t.checked;return z({},t,{defaultChecked:void 0,defaultValue:void 0,value:void 0,checked:n??e._wrapperState.initialChecked})}function U(e,t){var n=t.defaultValue==null?``:t.defaultValue,r=t.checked==null?t.defaultChecked:t.checked;n=ie(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 de(e,t){t=t.checked,t!=null&&S(e,`checked`,t,!1)}function fe(e,t){de(e,t);var n=ie(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`)?pe(e,t.type,n):t.hasOwnProperty(`defaultValue`)&&pe(e,t.type,ie(t.defaultValue)),t.checked==null&&t.defaultChecked!=null&&(e.defaultChecked=!!t.defaultChecked)}function W(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 pe(e,t,n){(t!==`number`||le(e.ownerDocument)!==e)&&(n==null?e.defaultValue=``+e._wrapperState.initialValue:e.defaultValue!==``+n&&(e.defaultValue=``+n))}var me=Array.isArray;function G(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=``+ie(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 he(e,t){if(t.dangerouslySetInnerHTML!=null)throw Error(r(91));return z({},t,{value:void 0,defaultValue:void 0,children:``+e._wrapperState.initialValue})}function ge(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(me(n)){if(1<n.length)throw Error(r(93));n=n[0]}t=n}t??=``,n=t}e._wrapperState={initialValue:ie(n)}}function K(e,t){var n=ie(t.value),r=ie(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 _e(e){var t=e.textContent;t===e._wrapperState.initialValue&&t!==``&&t!==null&&(e.value=t)}function ve(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 ye(e,t){return e==null||e===`http://www.w3.org/1999/xhtml`?ve(t):e===`http://www.w3.org/2000/svg`&&t===`foreignObject`?`http://www.w3.org/1999/xhtml`:e}var be,xe=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(be||=document.createElement(`div`),be.innerHTML=`<svg>`+t.valueOf().toString()+`</svg>`,t=be.firstChild;e.firstChild;)e.removeChild(e.firstChild);for(;t.firstChild;)e.appendChild(t.firstChild)}});function Se(e,t){if(t){var n=e.firstChild;if(n&&n===e.lastChild&&n.nodeType===3){n.nodeValue=t;return}}e.textContent=t}var Ce={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},we=[`Webkit`,`ms`,`Moz`,`O`];Object.keys(Ce).forEach(function(e){we.forEach(function(t){t=t+e.charAt(0).toUpperCase()+e.substring(1),Ce[t]=Ce[e]})});function Te(e,t,n){return t==null||typeof t==`boolean`||t===``?``:n||typeof t!=`number`||t===0||Ce.hasOwnProperty(e)&&Ce[e]?(``+t).trim():t+`px`}function Ee(e,t){for(var n in e=e.style,t)if(t.hasOwnProperty(n)){var r=n.indexOf(`--`)===0,i=Te(n,t[n],r);n===`float`&&(n=`cssFloat`),r?e.setProperty(n,i):e[n]=i}}var De=z({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 Oe(e,t){if(t){if(De[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 ke(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 Ae=null;function je(e){return e=e.target||e.srcElement||window,e.correspondingUseElement&&(e=e.correspondingUseElement),e.nodeType===3?e.parentNode:e}var Me=null,Ne=null,Pe=null;function Fe(e){if(e=Fi(e)){if(typeof Me!=`function`)throw Error(r(280));var t=e.stateNode;t&&(t=Li(t),Me(e.stateNode,e.type,t))}}function Ie(e){Ne?Pe?Pe.push(e):Pe=[e]:Ne=e}function Le(){if(Ne){var e=Ne,t=Pe;if(Pe=Ne=null,Fe(e),t)for(e=0;e<t.length;e++)Fe(t[e])}}function Re(e,t){return e(t)}function ze(){}var Be=!1;function Ve(e,t,n){if(Be)return e(t,n);Be=!0;try{return Re(e,t,n)}finally{Be=!1,(Ne!==null||Pe!==null)&&(ze(),Le())}}function He(e,t){var n=e.stateNode;if(n===null)return null;var i=Li(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 Ue=!1;if(c)try{var We={};Object.defineProperty(We,\"passive\",{get:function(){Ue=!0}}),window.addEventListener(`test`,We,We),window.removeEventListener(`test`,We,We)}catch{Ue=!1}function Ge(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 Ke=!1,qe=null,Je=!1,Ye=null,Xe={onError:function(e){Ke=!0,qe=e}};function Ze(e,t,n,r,i,a,o,s,c){Ke=!1,qe=null,Ge.apply(Xe,arguments)}function Qe(e,t,n,i,a,o,s,c,l){if(Ze.apply(this,arguments),Ke){if(Ke){var u=qe;Ke=!1,qe=null}else throw Error(r(198));Je||(Je=!0,Ye=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=Fi(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=Pi(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);Ae=r,n.target.dispatchEvent(r),Ae=null}else return t=Fi(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=Fi(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=je(r),e=Pi(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 z(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=z({},Cn,{view:0,detail:0}),En=Sn(Tn),Dn,On,q,kn=z({},Tn,{screenX:0,screenY:0,clientX:0,clientY:0,pageX:0,pageY:0,ctrlKey:0,shiftKey:0,altKey:0,metaKey:0,getModifierState:Bn,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!==q&&(q&&e.type===`mousemove`?(Dn=e.screenX-q.screenX,On=e.screenY-q.screenY):On=Dn=0,q=e),Dn)},movementY:function(e){return`movementY`in e?e.movementY:On}}),An=Sn(kn),jn=Sn(z({},kn,{dataTransfer:0})),Mn=Sn(z({},Tn,{relatedTarget:0})),Nn=Sn(z({},Cn,{animationName:0,elapsedTime:0,pseudoElement:0})),Pn=Sn(z({},Cn,{clipboardData:function(e){return`clipboardData`in e?e.clipboardData:window.clipboardData}})),Fn=Sn(z({},Cn,{data:0})),In={Esc:`Escape`,Spacebar:` `,Left:`ArrowLeft`,Up:`ArrowUp`,Right:`ArrowRight`,Down:`ArrowDown`,Del:`Delete`,Win:`OS`,Menu:`ContextMenu`,Apps:`ContextMenu`,Scroll:`ScrollLock`,MozPrintableKey:`Unidentified`},Ln={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`},Rn={Alt:`altKey`,Control:`ctrlKey`,Meta:`metaKey`,Shift:`shiftKey`};function zn(e){var t=this.nativeEvent;return t.getModifierState?t.getModifierState(e):(e=Rn[e])?!!t[e]:!1}function Bn(){return zn}var Vn=Sn(z({},Tn,{key:function(e){if(e.key){var t=In[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`?Ln[e.keyCode]||`Unidentified`:``},code:0,location:0,ctrlKey:0,shiftKey:0,altKey:0,metaKey:0,repeat:0,locale:0,getModifierState:Bn,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}})),Hn=Sn(z({},kn,{pointerId:0,width:0,height:0,pressure:0,tangentialPressure:0,tiltX:0,tiltY:0,twist:0,pointerType:0,isPrimary:0})),Un=Sn(z({},Tn,{touches:0,targetTouches:0,changedTouches:0,altKey:0,metaKey:0,ctrlKey:0,shiftKey:0,getModifierState:Bn})),Wn=Sn(z({},Cn,{propertyName:0,elapsedTime:0,pseudoElement:0})),Gn=Sn(z({},kn,{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})),Kn=[9,13,27,32],qn=c&&`CompositionEvent`in window,Jn=null;c&&`documentMode`in document&&(Jn=document.documentMode);var Yn=c&&`TextEvent`in window&&!Jn,Xn=c&&(!qn||Jn&&8<Jn&&11>=Jn),Zn=` `,Qn=!1;function $n(e,t){switch(e){case`keyup`:return Kn.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`||!qn&&$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){Ie(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(ce(Ii(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,je(e)),Ve(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=le();t instanceof e.HTMLIFrameElement;){try{var n=typeof t.contentWindow.location.href==`string`}catch{n=!1}if(n)e=t.contentWindow;else break;t=le(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!==le(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(Je)throw e=Ye,Je=!1,Ye=null,e}function ti(e,t){var n=t[ji];n===void 0&&(n=t[ji]=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,!Ue||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=Pi(s),o===null)return;if(c=o.tag,c===5||c===6){r=a=o;continue a}s=s.parentNode}}r=r.return}Ve(function(){var r=a,i=je(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=Vn;break;case`focusin`:l=`focus`,c=Mn;break;case`focusout`:l=`blur`,c=Mn;break;case`beforeblur`:case`afterblur`:c=Mn;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=An;break;case`drag`:case`dragend`:case`dragenter`:case`dragexit`:case`dragleave`:case`dragover`:case`dragstart`:case`drop`:c=jn;break;case`touchcancel`:case`touchend`:case`touchmove`:case`touchstart`:c=Un;break;case Hr:case Ur:case Wr:c=Nn;break;case Gr:c=Wn;break;case`scroll`:c=En;break;case`wheel`:c=Gn;break;case`copy`:case`cut`:case`paste`:c=Pn;break;case`gotpointercapture`:case`lostpointercapture`:case`pointercancel`:case`pointerdown`:case`pointermove`:case`pointerout`:case`pointerover`:case`pointerup`:c=Hn}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=He(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!==Ae&&(l=n.relatedTarget||n.fromElement)&&(Pi(l)||l[Ai]))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?Pi(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=An,h=`onMouseLeave`,f=`onMouseEnter`,p=`mouse`,(e===`pointerout`||e===`pointerover`)&&(u=Hn,h=`onPointerLeave`,f=`onPointerEnter`,p=`pointer`),d=c==null?s:Ii(c),m=l==null?s:Ii(l),s=new u(h,p+`leave`,c,n,i),s.target=d,s.relatedTarget=m,h=null,Pi(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?Ii(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`&&pe(s,`number`,s.value)}switch(_=r?Ii(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(qn)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 Fn(y,e,null,n,i),o.push({event:y,listeners:_}),v?y.data=v:(v=er(n),v!==null&&(y.data=v)))),(v=Yn?nr(e,n):rr(e,n))&&(r=ci(r,`onBeforeInput`),0<r.length&&(i=new Fn(`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=He(e,n),a!=null&&r.unshift(si(e,a,i)),a=He(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=He(n,a),c!=null&&o.unshift(si(n,c,s))):i||(c=He(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,Si=typeof queueMicrotask==`function`?queueMicrotask:xi===void 0?yi:function(e){return xi.resolve(null).then(e).catch(Ci)};function Ci(e){setTimeout(function(){throw e})}function wi(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 Ti(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 Ei(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 Di=Math.random().toString(36).slice(2),Oi=`__reactFiber$`+Di,ki=`__reactProps$`+Di,Ai=`__reactContainer$`+Di,ji=`__reactEvents$`+Di,Mi=`__reactListeners$`+Di,Ni=`__reactHandles$`+Di;function Pi(e){var t=e[Oi];if(t)return t;for(var n=e.parentNode;n;){if(t=n[Ai]||n[Oi]){if(n=t.alternate,t.child!==null||n!==null&&n.child!==null)for(e=Ei(e);e!==null;){if(n=e[Oi])return n;e=Ei(e)}return t}e=n,n=e.parentNode}return null}function Fi(e){return e=e[Oi]||e[Ai],!e||e.tag!==5&&e.tag!==6&&e.tag!==13&&e.tag!==3?null:e}function Ii(e){if(e.tag===5||e.tag===6)return e.stateNode;throw Error(r(33))}function Li(e){return e[ki]||null}var Ri=[],zi=-1;function Bi(e){return{current:e}}function Vi(e){0>zi||(e.current=Ri[zi],Ri[zi]=null,zi--)}function Hi(e,t){zi++,Ri[zi]=e.current,e.current=t}var Ui={},Wi=Bi(Ui),Gi=Bi(!1),Ki=Ui;function qi(e,t){var n=e.type.contextTypes;if(!n)return Ui;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 Ji(e){return e=e.childContextTypes,e!=null}function Yi(){Vi(Gi),Vi(Wi)}function Xi(e,t,n){if(Wi.current!==Ui)throw Error(r(168));Hi(Wi,t),Hi(Gi,n)}function Zi(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,re(e)||`Unknown`,a));return z({},n,i)}function Qi(e){return e=(e=e.stateNode)&&e.__reactInternalMemoizedMergedChildContext||Ui,Ki=Wi.current,Hi(Wi,e),Hi(Gi,Gi.current),!0}function $i(e,t,n){var i=e.stateNode;if(!i)throw Error(r(169));n?(e=Zi(e,t,Ki),i.__reactInternalMemoizedMergedChildContext=e,Vi(Gi),Vi(Wi),Hi(Wi,e)):Vi(Gi),Hi(Gi,n)}var J=null,ea=!1,ta=!1;function na(e){J===null?J=[e]:J.push(e)}function ra(e){ea=!0,na(e)}function ia(){if(!ta&&J!==null){ta=!0;var e=0,t=Ft;try{var n=J;for(Ft=1;e<n.length;e++){var r=n[e];do r=r(!0);while(r!==null)}J=null,ea=!1}catch(t){throw J!==null&&(J=J.slice(e+1)),at(dt,ia),t}finally{Ft=t,ta=!1}}return null}var aa=[],oa=0,sa=null,ca=0,la=[],ua=0,da=null,fa=1,pa=``;function ma(e,t){aa[oa++]=ca,aa[oa++]=sa,sa=e,ca=t}function ha(e,t,n){la[ua++]=fa,la[ua++]=pa,la[ua++]=da,da=e;var r=fa;e=pa;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,fa=1<<32-yt(t)+i|n<<i|r,pa=a+e}else fa=1<<a|n<<i|r,pa=e}function ga(e){e.return!==null&&(ma(e,1),ha(e,1,0))}function _a(e){for(;e===sa;)sa=aa[--oa],aa[oa]=null,ca=aa[--oa],aa[oa]=null;for(;e===da;)da=la[--ua],la[ua]=null,pa=la[--ua],la[ua]=null,fa=la[--ua],la[ua]=null}var va=null,ya=null,ba=!1,xa=null;function Sa(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 Ca(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,va=e,ya=Ti(t.firstChild),!0);case 6:return t=e.pendingProps===``||t.nodeType!==3?null:t,t!==null&&(e.stateNode=t,va=e,ya=null,!0);case 13:return t=t.nodeType===8?t:null,t!==null&&(n=da===null?null:{id:fa,overflow:pa},e.memoizedState={dehydrated:t,treeContext:n,retryLane:1073741824},n=ql(18,null,null,0),n.stateNode=t,n.return=e,e.child=n,va=e,ya=null,!0);default:return!1}}function wa(e){return!!(e.mode&1)&&!(e.flags&128)}function Ta(e){if(ba){var t=ya;if(t){var n=t;if(!Ca(e,t)){if(wa(e))throw Error(r(418));t=Ti(n.nextSibling);var i=va;t&&Ca(e,t)?Sa(i,n):(e.flags=e.flags&-4097|2,ba=!1,va=e)}}else{if(wa(e))throw Error(r(418));e.flags=e.flags&-4097|2,ba=!1,va=e}}}function Ea(e){for(e=e.return;e!==null&&e.tag!==5&&e.tag!==3&&e.tag!==13;)e=e.return;va=e}function Da(e){if(e!==va)return!1;if(!ba)return Ea(e),ba=!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&&=ya){if(wa(e))throw Oa(),Error(r(418));for(;t;)Sa(e,t),t=Ti(t.nextSibling)}if(Ea(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){ya=Ti(e.nextSibling);break a}t--}else n!==`$`&&n!==`$!`&&n!==`$?`||t++}e=e.nextSibling}ya=null}}else ya=va?Ti(e.stateNode.nextSibling):null;return!0}function Oa(){for(var e=ya;e;)e=Ti(e.nextSibling)}function ka(){ya=va=null,ba=!1}function Aa(e){xa===null?xa=[e]:xa.push(e)}var ja=C.ReactCurrentBatchConfig;function Ma(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 Na(e,t){throw e=Object.prototype.toString.call(t),Error(r(31,e===`[object Object]`?`object with keys {`+Object.keys(t).join(`, `)+`}`:e))}function Pa(e){var t=e._init;return t(e._payload)}function Fa(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===F&&Pa(i)===t.type)?(r=a(t,n.props),r.ref=Ma(e,t,n),r.return=e,r):(r=Zl(n.type,n.key,n.props,null,e.mode,r),r.ref=Ma(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=Ma(e,null,t),n.return=e,n;case T:return t=tu(t,e.mode,n),t.return=e,t;case F:var r=t._init;return f(e,r(t._payload),n)}if(me(t)||R(t))return t=Ql(t,e.mode,n,null),t.return=e,t;Na(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 F:return i=n._init,p(e,t,i(n._payload),r)}if(me(n)||R(n))return i===null?d(e,t,n,r,null):null;Na(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 F:var a=r._init;return m(e,t,n,a(r._payload),i)}if(me(r)||R(r))return e=e.get(n)||null,d(t,e,r,i,null);Na(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),ba&&ma(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 ba&&ma(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)}),ba&&ma(r,h),l}function g(a,s,c,l){var u=R(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),ba&&ma(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 ba&&ma(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)}),ba&&ma(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===F&&Pa(c)===l.type){n(e,l.sibling),r=a(l,i.props),r.ref=Ma(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=Ma(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 F:return l=i._init,_(e,r,l(i._payload),o)}if(me(i))return h(e,r,i,o);if(R(i))return g(e,r,i,o);Na(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 Ia=Fa(!0),La=Fa(!1),Ra=Bi(null),za=null,Ba=null,Va=null;function Ha(){Va=Ba=za=null}function Ua(e){var t=Ra.current;Vi(Ra),e._currentValue=t}function Wa(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 Ga(e,t){za=e,Va=Ba=null,e=e.dependencies,e!==null&&e.firstContext!==null&&((e.lanes&t)!==0&&(Ps=!0),e.firstContext=null)}function Ka(e){var t=e._currentValue;if(Va!==e){if(e={context:e,memoizedValue:t,next:null},Ba===null){if(za===null)throw Error(r(308));Ba=e,za.dependencies={lanes:0,firstContext:e}}else Ba=Ba.next=e}return t}var qa=null;function Ja(e){qa===null?qa=[e]:qa.push(e)}function Ya(e,t,n,r){var i=t.interleaved;return i===null?(n.next=n,Ja(t)):(n.next=i.next,i.next=n),t.interleaved=n,Xa(e,r)}function Xa(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 Za=!1;function Qa(e){e.updateQueue={baseState:e.memoizedState,firstBaseUpdate:null,lastBaseUpdate:null,shared:{pending:null,interleaved:null,lanes:0},effects:null}}function $a(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 eo(e,t){return{eventTime:e,lane:t,tag:0,payload:null,callback:null,next:null}}function to(e,t,n){var r=e.updateQueue;if(r===null)return null;if(r=r.shared,Q&2){var i=r.pending;return i===null?t.next=t:(t.next=i.next,i.next=t),r.pending=t,Xa(e,n)}return i=r.interleaved,i===null?(t.next=t,Ja(r)):(t.next=i.next,i.next=t),r.interleaved=t,Xa(e,n)}function no(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 ro(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 io(e,t,n,r){var i=e.updateQueue;Za=!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=z({},d,f);break a;case 2:Za=!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);Yc|=o,e.lanes=o,e.memoizedState=d}}function ao(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 oo={},so=Bi(oo),co=Bi(oo),lo=Bi(oo);function uo(e){if(e===oo)throw Error(r(174));return e}function fo(e,t){switch(Hi(lo,t),Hi(co,e),Hi(so,oo),e=t.nodeType,e){case 9:case 11:t=(t=t.documentElement)?t.namespaceURI:ye(null,``);break;default:e=e===8?t.parentNode:t,t=e.namespaceURI||null,e=e.tagName,t=ye(t,e)}Vi(so),Hi(so,t)}function po(){Vi(so),Vi(co),Vi(lo)}function mo(e){uo(lo.current);var t=uo(so.current),n=ye(t,e.type);t!==n&&(Hi(co,e),Hi(so,n))}function ho(e){co.current===e&&(Vi(so),Vi(co))}var go=Bi(0);function _o(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 vo=[];function yo(){for(var e=0;e<vo.length;e++)vo[e]._workInProgressVersionPrimary=null;vo.length=0}var bo=C.ReactCurrentDispatcher,xo=C.ReactCurrentBatchConfig,So=0,Co=null,wo=null,To=null,Eo=!1,Do=!1,Oo=0,ko=0;function Ao(){throw Error(r(321))}function jo(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 Mo(e,t,n,i,a,o){if(So=o,Co=t,t.memoizedState=null,t.updateQueue=null,t.lanes=0,bo.current=e===null||e.memoizedState===null?ms:hs,e=n(i,a),Do){o=0;do{if(Do=!1,Oo=0,25<=o)throw Error(r(301));o+=1,To=wo=null,t.updateQueue=null,bo.current=gs,e=n(i,a)}while(Do)}if(bo.current=ps,t=wo!==null&&wo.next!==null,So=0,To=wo=Co=null,Eo=!1,t)throw Error(r(300));return e}function No(){var e=Oo!==0;return Oo=0,e}function Po(){var e={memoizedState:null,baseState:null,baseQueue:null,queue:null,next:null};return To===null?Co.memoizedState=To=e:To=To.next=e,To}function Fo(){if(wo===null){var e=Co.alternate;e=e===null?null:e.memoizedState}else e=wo.next;var t=To===null?Co.memoizedState:To.next;if(t!==null)To=t,wo=e;else{if(e===null)throw Error(r(310));wo=e,e={memoizedState:wo.memoizedState,baseState:wo.baseState,baseQueue:wo.baseQueue,queue:wo.queue,next:null},To===null?Co.memoizedState=To=e:To=To.next=e}return To}function Io(e,t){return typeof t==`function`?t(e):t}function Lo(e){var t=Fo(),n=t.queue;if(n===null)throw Error(r(311));n.lastRenderedReducer=e;var i=wo,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((So&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,Co.lanes|=d,Yc|=d}u=u.next}while(u!==null&&u!==o);l===null?s=i:l.next=c,Cr(i,t.memoizedState)||(Ps=!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,Co.lanes|=o,Yc|=o,a=a.next;while(a!==e)}else a===null&&(n.lanes=0);return[t.memoizedState,n.dispatch]}function Ro(e){var t=Fo(),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)||(Ps=!0),t.memoizedState=o,t.baseQueue===null&&(t.baseState=o),n.lastRenderedState=o}return[o,i]}function zo(){}function Bo(e,t){var n=Co,i=Fo(),a=t(),o=!Cr(i.memoizedState,a);if(o&&(i.memoizedState=a,Ps=!0),i=i.queue,Zo(Ho.bind(null,n,i,e),[e]),i.getSnapshot!==t||o||To!==null&&To.memoizedState.tag&1){if(n.flags|=2048,Ko(9,Vo.bind(null,n,i,a,t),void 0,null),Hc===null)throw Error(r(349));So&30||Y(n,t,a)}return a}function Y(e,t,n){e.flags|=16384,e={getSnapshot:t,value:n},t=Co.updateQueue,t===null?(t={lastEffect:null,stores:null},Co.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=Xa(e,1);t!==null&&hl(t,e,1,-1)}function Go(e){var t=Po();return typeof e==`function`&&(e=e()),t.memoizedState=t.baseState=e,e={pending:null,interleaved:null,lanes:0,dispatch:null,lastRenderedReducer:Io,lastRenderedState:e},t.queue=e,e=e.dispatch=ls.bind(null,Co,e),[t.memoizedState,e]}function Ko(e,t,n,r){return e={tag:e,create:t,destroy:n,deps:r,next:null},t=Co.updateQueue,t===null?(t={lastEffect:null,stores:null},Co.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 Fo().memoizedState}function Jo(e,t,n,r){var i=Po();Co.flags|=e,i.memoizedState=Ko(1|t,n,void 0,r===void 0?null:r)}function Yo(e,t,n,r){var i=Fo();r=r===void 0?null:r;var a=void 0;if(wo!==null){var o=wo.memoizedState;if(a=o.destroy,r!==null&&jo(r,o.deps)){i.memoizedState=Ko(t,n,a,r);return}}Co.flags|=e,i.memoizedState=Ko(1|t,n,a,r)}function Xo(e,t){return Jo(8390656,8,e,t)}function Zo(e,t){return Yo(2048,8,e,t)}function Qo(e,t){return Yo(4,2,e,t)}function $o(e,t){return Yo(4,4,e,t)}function es(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 ts(e,t,n){return n=n==null?null:n.concat([e]),Yo(4,4,es.bind(null,t,e),n)}function ns(){}function rs(e,t){var n=Fo();t=t===void 0?null:t;var r=n.memoizedState;return r!==null&&t!==null&&jo(t,r[1])?r[0]:(n.memoizedState=[e,t],e)}function is(e,t){var n=Fo();t=t===void 0?null:t;var r=n.memoizedState;return r!==null&&t!==null&&jo(t,r[1])?r[0]:(e=e(),n.memoizedState=[e,t],e)}function as(e,t,n){return So&21?(Cr(n,t)||(n=At(),Co.lanes|=n,Yc|=n,e.baseState=!0),t):(e.baseState&&(e.baseState=!1,Ps=!0),e.memoizedState=n)}function os(e,t){var n=Ft;Ft=n!==0&&4>n?n:4,e(!0);var r=xo.transition;xo.transition={};try{e(!1),t()}finally{Ft=n,xo.transition=r}}function ss(){return Fo().memoizedState}function cs(e,t,n){var r=ml(e);if(n={lane:r,action:n,hasEagerState:!1,eagerState:null,next:null},us(e))ds(t,n);else if(n=Ya(e,t,n,r),n!==null){var i=pl();hl(n,e,r,i),fs(n,t,r)}}function ls(e,t,n){var r=ml(e),i={lane:r,action:n,hasEagerState:!1,eagerState:null,next:null};if(us(e))ds(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,Ja(t)):(i.next=c.next,c.next=i),t.interleaved=i;return}}catch{}n=Ya(e,t,i,r),n!==null&&(i=pl(),hl(n,e,r,i),fs(n,t,r))}}function us(e){var t=e.alternate;return e===Co||t!==null&&t===Co}function ds(e,t){Do=Eo=!0;var n=e.pending;n===null?t.next=t:(t.next=n.next,n.next=t),e.pending=t}function fs(e,t,n){if(n&4194240){var r=t.lanes;r&=e.pendingLanes,n|=r,t.lanes=n,Pt(e,n)}}var ps={readContext:Ka,useCallback:Ao,useContext:Ao,useEffect:Ao,useImperativeHandle:Ao,useInsertionEffect:Ao,useLayoutEffect:Ao,useMemo:Ao,useReducer:Ao,useRef:Ao,useState:Ao,useDebugValue:Ao,useDeferredValue:Ao,useTransition:Ao,useMutableSource:Ao,useSyncExternalStore:Ao,useId:Ao,unstable_isNewReconciler:!1},ms={readContext:Ka,useCallback:function(e,t){return Po().memoizedState=[e,t===void 0?null:t],e},useContext:Ka,useEffect:Xo,useImperativeHandle:function(e,t,n){return n=n==null?null:n.concat([e]),Jo(4194308,4,es.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=Po();return t=t===void 0?null:t,e=e(),n.memoizedState=[e,t],e},useReducer:function(e,t,n){var r=Po();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=cs.bind(null,Co,e),[r.memoizedState,e]},useRef:function(e){var t=Po();return e={current:e},t.memoizedState=e},useState:Go,useDebugValue:ns,useDeferredValue:function(e){return Po().memoizedState=e},useTransition:function(){var e=Go(!1),t=e[0];return e=os.bind(null,e[1]),Po().memoizedState=e,[t,e]},useMutableSource:function(){},useSyncExternalStore:function(e,t,n){var i=Co,a=Po();if(ba){if(n===void 0)throw Error(r(407));n=n()}else{if(n=t(),Hc===null)throw Error(r(349));So&30||Y(i,t,n)}a.memoizedState=n;var o={value:n,getSnapshot:t};return a.queue=o,Xo(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=Po(),t=Hc.identifierPrefix;if(ba){var n=pa,r=fa;n=(r&~(1<<32-yt(r)-1)).toString(32)+n,t=`:`+t+`R`+n,n=Oo++,0<n&&(t+=`H`+n.toString(32)),t+=`:`}else n=ko++,t=`:`+t+`r`+n.toString(32)+`:`;return e.memoizedState=t},unstable_isNewReconciler:!1},hs={readContext:Ka,useCallback:rs,useContext:Ka,useEffect:Zo,useImperativeHandle:ts,useInsertionEffect:Qo,useLayoutEffect:$o,useMemo:is,useReducer:Lo,useRef:qo,useState:function(){return Lo(Io)},useDebugValue:ns,useDeferredValue:function(e){return as(Fo(),wo.memoizedState,e)},useTransition:function(){return[Lo(Io)[0],Fo().memoizedState]},useMutableSource:zo,useSyncExternalStore:Bo,useId:ss,unstable_isNewReconciler:!1},gs={readContext:Ka,useCallback:rs,useContext:Ka,useEffect:Zo,useImperativeHandle:ts,useInsertionEffect:Qo,useLayoutEffect:$o,useMemo:is,useReducer:Ro,useRef:qo,useState:function(){return Ro(Io)},useDebugValue:ns,useDeferredValue:function(e){var t=Fo();return wo===null?t.memoizedState=e:as(t,wo.memoizedState,e)},useTransition:function(){return[Ro(Io)[0],Fo().memoizedState]},useMutableSource:zo,useSyncExternalStore:Bo,useId:ss,unstable_isNewReconciler:!1};function _s(e,t){if(e&&e.defaultProps){for(var n in t=z({},t),e=e.defaultProps,e)t[n]===void 0&&(t[n]=e[n]);return t}return t}function vs(e,t,n,r){t=e.memoizedState,n=n(r,t),n=n==null?t:z({},t,n),e.memoizedState=n,e.lanes===0&&(e.updateQueue.baseState=n)}var ys={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=eo(r,i);a.payload=t,n!=null&&(a.callback=n),t=to(e,a,i),t!==null&&(hl(t,e,i,r),no(t,e,i))},enqueueReplaceState:function(e,t,n){e=e._reactInternals;var r=pl(),i=ml(e),a=eo(r,i);a.tag=1,a.payload=t,n!=null&&(a.callback=n),t=to(e,a,i),t!==null&&(hl(t,e,i,r),no(t,e,i))},enqueueForceUpdate:function(e,t){e=e._reactInternals;var n=pl(),r=ml(e),i=eo(n,r);i.tag=2,t!=null&&(i.callback=t),t=to(e,i,r),t!==null&&(hl(t,e,r,n),no(t,e,r))}};function bs(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 xs(e,t,n){var r=!1,i=Ui,a=t.contextType;return typeof a==`object`&&a?a=Ka(a):(i=Ji(t)?Ki:Wi.current,r=t.contextTypes,a=(r=r!=null)?qi(e,i):Ui),t=new t(n,a),e.memoizedState=t.state!==null&&t.state!==void 0?t.state:null,t.updater=ys,e.stateNode=t,t._reactInternals=e,r&&(e=e.stateNode,e.__reactInternalMemoizedUnmaskedChildContext=i,e.__reactInternalMemoizedMaskedChildContext=a),t}function Ss(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&&ys.enqueueReplaceState(t,t.state,null)}function Cs(e,t,n,r){var i=e.stateNode;i.props=n,i.state=e.memoizedState,i.refs={},Qa(e);var a=t.contextType;typeof a==`object`&&a?i.context=Ka(a):(a=Ji(t)?Ki:Wi.current,i.context=qi(e,a)),i.state=e.memoizedState,a=t.getDerivedStateFromProps,typeof a==`function`&&(vs(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&&ys.enqueueReplaceState(i,i.state,null),io(e,n,i,r),i.state=e.memoizedState),typeof i.componentDidMount==`function`&&(e.flags|=4194308)}function ws(e,t){try{var n=``,r=t;do n+=te(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 Ts(e,t,n){return{value:e,source:null,stack:n??null,digest:t??null}}function Es(e,t){try{console.error(t.value)}catch(e){setTimeout(function(){throw e})}}var Ds=typeof WeakMap==`function`?WeakMap:Map;function Os(e,t,n){n=eo(-1,n),n.tag=3,n.payload={element:null};var r=t.value;return n.callback=function(){rl||(rl=!0,il=r),Es(e,t)},n}function ks(e,t,n){n=eo(-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(){Es(e,t)}}var a=e.stateNode;return a!==null&&typeof a.componentDidCatch==`function`&&(n.callback=function(){Es(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 As(e,t,n){var r=e.pingCache;if(r===null){r=e.pingCache=new Ds;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 js(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 Ms(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=eo(-1,1),t.tag=2,to(n,t,1))),n.lanes|=1),e)}var Ns=C.ReactCurrentOwner,Ps=!1;function Fs(e,t,n,r){t.child=e===null?La(t,null,n,r):Ia(t,e.child,n,r)}function Is(e,t,n,r,i){n=n.render;var a=t.ref;return Ga(t,i),r=Mo(e,t,n,r,a,i),n=No(),e!==null&&!Ps?(t.updateQueue=e.updateQueue,t.flags&=-2053,e.lanes&=~i,nc(e,t,i)):(ba&&n&&ga(t),t.flags|=1,Fs(e,t,r,i),t.child)}function Ls(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,Rs(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 nc(e,t,i)}return t.flags|=1,e=Xl(a,r),e.ref=t.ref,e.return=t,t.child=e}function Rs(e,t,n,r,i){if(e!==null){var a=e.memoizedProps;if(wr(a,r)&&e.ref===t.ref){if(Ps=!1,t.pendingProps=r=a,(e.lanes&i)!==0)e.flags&131072&&(Ps=!0);else return t.lanes=e.lanes,nc(e,t,i)}}return Vs(e,t,n,r,i)}function zs(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},Hi(Kc,Gc),Gc|=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,Hi(Kc,Gc),Gc|=e,null;t.memoizedState={baseLanes:0,cachePool:null,transitions:null},r=a===null?n:a.baseLanes,Hi(Kc,Gc),Gc|=r}}else a===null?r=n:(r=a.baseLanes|n,t.memoizedState=null),Hi(Kc,Gc),Gc|=r;return Fs(e,t,i,n),t.child}function Bs(e,t){var n=t.ref;(e===null&&n!==null||e!==null&&e.ref!==n)&&(t.flags|=512,t.flags|=2097152)}function Vs(e,t,n,r,i){var a=Ji(n)?Ki:Wi.current;return a=qi(t,a),Ga(t,i),n=Mo(e,t,n,r,a,i),r=No(),e!==null&&!Ps?(t.updateQueue=e.updateQueue,t.flags&=-2053,e.lanes&=~i,nc(e,t,i)):(ba&&r&&ga(t),t.flags|=1,Fs(e,t,n,i),t.child)}function Hs(e,t,n,r,i){if(Ji(n)){var a=!0;Qi(t)}else a=!1;if(Ga(t,i),t.stateNode===null)tc(e,t),xs(t,n,r),Cs(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=Ka(l):(l=Ji(n)?Ki:Wi.current,l=qi(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)&&Ss(t,o,r,l),Za=!1;var f=t.memoizedState;o.state=f,io(t,r,o,i),c=t.memoizedState,s!==r||f!==c||Gi.current||Za?(typeof u==`function`&&(vs(t,n,u,r),c=t.memoizedState),(s=Za||bs(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,$a(e,t),s=t.memoizedProps,l=t.type===t.elementType?s:_s(t.type,s),o.props=l,d=t.pendingProps,f=o.context,c=n.contextType,typeof c==`object`&&c?c=Ka(c):(c=Ji(n)?Ki:Wi.current,c=qi(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)&&Ss(t,o,r,c),Za=!1,f=t.memoizedState,o.state=f,io(t,r,o,i);var m=t.memoizedState;s!==d||f!==m||Gi.current||Za?(typeof p==`function`&&(vs(t,n,p,r),m=t.memoizedState),(l=Za||bs(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 Us(e,t,n,r,a,i)}function Us(e,t,n,r,i,a){Bs(e,t);var o=!!(t.flags&128);if(!r&&!o)return i&&$i(t,n,!1),nc(e,t,a);r=t.stateNode,Ns.current=t;var s=o&&typeof n.getDerivedStateFromError!=`function`?null:r.render();return t.flags|=1,e!==null&&o?(t.child=Ia(t,e.child,null,a),t.child=Ia(t,null,s,a)):Fs(e,t,s,a),t.memoizedState=r.state,i&&$i(t,n,!0),t.child}function Ws(e){var t=e.stateNode;t.pendingContext?Xi(e,t.pendingContext,t.pendingContext!==t.context):t.context&&Xi(e,t.context,!1),fo(e,t.containerInfo)}function Gs(e,t,n,r,i){return ka(),Aa(i),t.flags|=256,Fs(e,t,n,r),t.child}var Ks={dehydrated:null,treeContext:null,retryLane:0};function qs(e){return{baseLanes:e,cachePool:null,transitions:null}}function Js(e,t,n){var r=t.pendingProps,i=go.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),Hi(go,i&1),e===null)return Ta(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=qs(n),t.memoizedState=Ks,e):Ys(t,o));if(i=e.memoizedState,i!==null&&(s=i.dehydrated,s!==null))return Zs(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?qs(n):{baseLanes:o.baseLanes|n,cachePool:null,transitions:o.transitions},a.memoizedState=o,a.childLanes=e.childLanes&~n,t.memoizedState=Ks,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 Ys(e,t){return t=$l({mode:`visible`,children:t},e.mode,0,null),t.return=e,e.child=t}function Xs(e,t,n,r){return r!==null&&Aa(r),Ia(t,e.child,null,n),e=Ys(t,t.pendingProps.children),e.flags|=2,t.memoizedState=null,e}function Zs(e,t,n,i,a,o,s){if(n)return t.flags&256?(t.flags&=-257,i=Ts(Error(r(422))),Xs(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&&Ia(t,e.child,null,s),t.child.memoizedState=qs(s),t.memoizedState=Ks,o):(t.child=e.child,t.flags|=128,null);if(!(t.mode&1))return Xs(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=Ts(o,i,void 0),Xs(e,t,s,i)}if(c=(s&e.childLanes)!==0,Ps||c){if(i=Hc,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,Xa(e,a),hl(i,e,a,-1))}return kl(),i=Ts(Error(r(421))),Xs(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,ya=Ti(a.nextSibling),va=t,ba=!0,xa=null,e!==null&&(la[ua++]=fa,la[ua++]=pa,la[ua++]=da,fa=e.id,pa=e.overflow,da=t),t=Ys(t,i.children),t.flags|=4096,t)}function Qs(e,t,n){e.lanes|=t;var r=e.alternate;r!==null&&(r.lanes|=t),Wa(e.return,t,n)}function $s(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 ec(e,t,n){var r=t.pendingProps,i=r.revealOrder,a=r.tail;if(Fs(e,t,r.children,n),r=go.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&&Qs(e,n,t);else if(e.tag===19)Qs(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(Hi(go,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&&_o(e)===null&&(i=n),n=n.sibling;n=i,n===null?(i=t.child,t.child=null):(i=n.sibling,n.sibling=null),$s(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&&_o(e)===null){t.child=i;break}e=i.sibling,i.sibling=n,n=i,i=e}$s(t,!0,n,null,a);break;case`together`:$s(t,!1,null,null,void 0);break;default:t.memoizedState=null}return t.child}function tc(e,t){!(t.mode&1)&&e!==null&&(e.alternate=null,t.alternate=null,t.flags|=2)}function nc(e,t,n){if(e!==null&&(t.dependencies=e.dependencies),Yc|=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 rc(e,t,n){switch(t.tag){case 3:Ws(t),ka();break;case 5:mo(t);break;case 1:Ji(t.type)&&Qi(t);break;case 4:fo(t,t.stateNode.containerInfo);break;case 10:var r=t.type._context,i=t.memoizedProps.value;Hi(Ra,r._currentValue),r._currentValue=i;break;case 13:if(r=t.memoizedState,r!==null)return r.dehydrated===null?(n&t.child.childLanes)===0?(Hi(go,go.current&1),e=nc(e,t,n),e===null?null:e.sibling):Js(e,t,n):(Hi(go,go.current&1),t.flags|=128,null);Hi(go,go.current&1);break;case 19:if(r=(n&t.childLanes)!==0,e.flags&128){if(r)return ec(e,t,n);t.flags|=128}if(i=t.memoizedState,i!==null&&(i.rendering=null,i.tail=null,i.lastEffect=null),Hi(go,go.current),r)break;return null;case 22:case 23:return t.lanes=0,zs(e,t,n)}return nc(e,t,n)}var ic=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}},ac=function(e,t,n,r){var i=e.memoizedProps;if(i!==r){e=t.stateNode,uo(so.current);var o=null;switch(n){case`input`:i=ue(e,i),r=ue(e,r),o=[];break;case`select`:i=z({},i,{value:void 0}),r=z({},r,{value:void 0}),o=[];break;case`textarea`:i=he(e,i),r=he(e,r),o=[];break;default:typeof i.onClick!=`function`&&typeof r.onClick==`function`&&(e.onclick=hi)}Oe(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)}},oc=function(e,t,n,r){n!==r&&(t.flags|=4)};function X(e,t){if(!ba)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(_a(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 Ji(t.type)&&Yi(),sc(t),null;case 3:return i=t.stateNode,po(),Vi(Gi),Vi(Wi),yo(),i.pendingContext&&(i.context=i.pendingContext,i.pendingContext=null),(e===null||e.child===null)&&(Da(t)?t.flags|=4:e===null||e.memoizedState.isDehydrated&&!(t.flags&256)||(t.flags|=1024,xa!==null&&(yl(xa),xa=null))),sc(t),null;case 5:ho(t);var o=uo(lo.current);if(n=t.type,e!==null&&t.stateNode!=null)ac(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=uo(so.current),Da(t)){i=t.stateNode,n=t.type;var s=t.memoizedProps;switch(i[Oi]=t,i[ki]=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`:U(i,s),ti(`invalid`,i);break;case`select`:i._wrapperState={wasMultiple:!!s.multiple},ti(`invalid`,i);break;case`textarea`:ge(i,s),ti(`invalid`,i)}for(var c in Oe(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`:se(i),W(i,s,!0);break;case`textarea`:se(i),_e(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=ve(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[Oi]=t,e[ki]=i,ic(e,t,!1,!1),t.stateNode=e;a:{switch(c=ke(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`:U(e,i),o=ue(e,i),ti(`invalid`,e);break;case`option`:o=i;break;case`select`:e._wrapperState={wasMultiple:!!i.multiple},o=z({},i,{value:void 0}),ti(`invalid`,e);break;case`textarea`:ge(e,i),o=he(e,i),ti(`invalid`,e);break;default:o=i}for(s in Oe(n,o),l=o,l)if(l.hasOwnProperty(s)){var u=l[s];s===`style`?Ee(e,u):s===`dangerouslySetInnerHTML`?(u=u?u.__html:void 0,u!=null&&xe(e,u)):s===`children`?typeof u==`string`?(n!==`textarea`||u!==``)&&Se(e,u):typeof u==`number`&&Se(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`:se(e),W(e,i,!1);break;case`textarea`:se(e),_e(e);break;case`option`:i.value!=null&&e.setAttribute(`value`,``+ie(i.value));break;case`select`:e.multiple=!!i.multiple,s=i.value,s==null?i.defaultValue!=null&&G(e,!!i.multiple,i.defaultValue,!0):G(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)oc(e,t,e.memoizedProps,i);else{if(typeof i!=`string`&&t.stateNode===null)throw Error(r(166));if(n=uo(lo.current),uo(so.current),Da(t)){if(i=t.stateNode,n=t.memoizedProps,i[Oi]=t,(s=i.nodeValue!==n)&&(e=va,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[Oi]=t,t.stateNode=i}return sc(t),null;case 13:if(Vi(go),i=t.memoizedState,e===null||e.memoizedState!==null&&e.memoizedState.dehydrated!==null){if(ba&&ya!==null&&t.mode&1&&!(t.flags&128))Oa(),ka(),t.flags|=98560,s=!1;else if(s=Da(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[Oi]=t}else ka(),!(t.flags&128)&&(t.memoizedState=null),t.flags|=4;sc(t),s=!1}else xa!==null&&(yl(xa),xa=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||go.current&1?qc===0&&(qc=3):kl())),t.updateQueue!==null&&(t.flags|=4),sc(t),null);case 4:return po(),e===null&&ii(t.stateNode.containerInfo),sc(t),null;case 10:return Ua(t.type._context),sc(t),null;case 17:return Ji(t.type)&&Yi(),sc(t),null;case 19:if(Vi(go),s=t.memoizedState,s===null)return sc(t),null;if(i=!!(t.flags&128),c=s.rendering,c===null){if(i)X(s,!1);else{if(qc!==0||e!==null&&e.flags&128)for(e=t.child;e!==null;){if(c=_o(e),c!==null){for(t.flags|=128,X(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 Hi(go,go.current&1|2),t.child}e=e.sibling}s.tail!==null&<()>tl&&(t.flags|=128,i=!0,X(s,!1),t.lanes=4194304)}}else{if(!i){if(e=_o(c),e!==null){if(t.flags|=128,i=!0,n=e.updateQueue,n!==null&&(t.updateQueue=n,t.flags|=4),X(s,!0),s.tail===null&&s.tailMode===`hidden`&&!c.alternate&&!ba)return sc(t),null}else 2*lt()-s.renderingStartTime>tl&&n!==1073741824&&(t.flags|=128,i=!0,X(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=go.current,Hi(go,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?Gc&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(_a(t),t.tag){case 1:return Ji(t.type)&&Yi(),e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 3:return po(),Vi(Gi),Vi(Wi),yo(),e=t.flags,e&65536&&!(e&128)?(t.flags=e&-65537|128,t):null;case 5:return ho(t),null;case 13:if(Vi(go),e=t.memoizedState,e!==null&&e.dehydrated!==null){if(t.alternate===null)throw Error(r(340));ka()}return e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 19:return Vi(go),null;case 4:return po(),null;case 10:return Ua(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:_s(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[Oi],delete t[ki],delete t[ji],delete t[Mi],delete t[Ni])),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?wi(e.parentNode,n):e.nodeType===1&&wi(e,n),on(e)):wi(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{Se(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&&de(a,o),ke(c,s);var u=ke(c,o);for(s=0;s<l.length;s+=2){var d=l[s],f=l[s+1];d===`style`?Ee(a,f):d===`dangerouslySetInnerHTML`?xe(a,f):d===`children`?Se(a,f):S(a,d,f,u)}switch(c){case`input`:fe(a,o);break;case`textarea`:K(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?G(a,!!o.multiple,o.multiple?[]:``,!1):G(a,!!o.multiple,o.defaultValue,!0)):G(a,!!o.multiple,m,!1)}a[ki]=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=Te(`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&&(Se(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:_s(t.type,n.memoizedProps);i.componentDidUpdate(a,n.memoizedState,i.__reactInternalSnapshotBeforeUpdate)}}var o=t.updateQueue;o!==null&&ao(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}ao(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,Q=0,Hc=null,Uc=null,Wc=0,Gc=0,Kc=Bi(0),qc=0,Jc=null,Yc=0,Xc=0,Zc=0,Qc=null,$c=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 Q&6?lt():dl===-1?dl=lt():dl}function ml(e){return e.mode&1?Q&2&&Wc!==0?Wc&-Wc:ja.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),(!(Q&2)||e!==Hc)&&(e===Hc&&(!(Q&2)&&(Xc|=n),qc===4&&xl(e,Wc)),gl(e,i),n===1&&Q===0&&!(t.mode&1)&&(tl=lt()+500,ea&&ia()))}function gl(e,t){var n=e.callbackNode;Ot(e,t);var r=Et(e,e===Hc?Wc: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?ra(Sl.bind(null,e)):na(Sl.bind(null,e)),Si(function(){!(Q&6)&&ia()}),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,Q&6)throw Error(r(327));var n=e.callbackNode;if(Ll()&&e.callbackNode!==n)return null;var i=Et(e,e===Hc?Wc:0);if(i===0)return null;if(i&30||(i&e.expiredLanes)!==0||t)t=Al(e,i);else{t=i;var a=Q;Q|=2;var o=Ol();(Hc!==e||Wc!==t)&&(nl=null,tl=lt()+500,El(e,t));do try{Ml();break}catch(t){Dl(e,t)}while(1);Ha(),zc.current=o,Q=a,Uc===null?(Hc=null,Wc=0,t=qc):t=0}if(t!==0){if(t===2&&(a=kt(e),a!==0&&(i=a,t=vl(e,a))),t===1)throw n=Jc,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=Jc,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,$c,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,$c,nl),t);break}Fl(e,$c,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,$c,nl),i);break}Fl(e,$c,nl);break;case 5:Fl(e,$c,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=Qc;return e.current.memoizedState.isDehydrated&&(El(e,t).flags|=256),e=Al(e,t),e!==2&&(t=$c,$c=n,t!==null&&yl(t)),e}function yl(e){$c===null?$c=e:$c.push.apply($c,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&=~Zc,t&=~Xc,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(Q&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=Jc,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,$c,nl),gl(e,lt()),null}function Cl(e,t){var n=Q;Q|=1;try{return e(t)}finally{Q=n,Q===0&&(tl=lt()+500,ea&&ia())}}function wl(e){sl!==null&&sl.tag===0&&!(Q&6)&&Ll();var t=Q;Q|=1;var n=Vc.transition,r=Ft;try{if(Vc.transition=null,Ft=1,e)return e()}finally{Ft=r,Vc.transition=n,Q=t,!(Q&6)&&ia()}}function Tl(){Gc=Kc.current,Vi(Kc)}function El(e,t){e.finishedWork=null,e.finishedLanes=0;var n=e.timeoutHandle;if(n!==-1&&(e.timeoutHandle=-1,bi(n)),Uc!==null)for(n=Uc.return;n!==null;){var r=n;switch(_a(r),r.tag){case 1:r=r.type.childContextTypes,r!=null&&Yi();break;case 3:po(),Vi(Gi),Vi(Wi),yo();break;case 5:ho(r);break;case 4:po();break;case 13:Vi(go);break;case 19:Vi(go);break;case 10:Ua(r.type._context);break;case 22:case 23:Tl()}n=n.return}if(Hc=e,Uc=e=Xl(e.current,null),Wc=Gc=t,qc=0,Jc=null,Zc=Xc=Yc=0,$c=Qc=null,qa!==null){for(t=0;t<qa.length;t++)if(n=qa[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}qa=null}return e}function Dl(e,t){do{var n=Uc;try{if(Ha(),bo.current=ps,Eo){for(var i=Co.memoizedState;i!==null;){var a=i.queue;a!==null&&(a.pending=null),i=i.next}Eo=!1}if(So=0,To=wo=Co=null,Do=!1,Oo=0,Bc.current=null,n===null||n.return===null){qc=1,Jc=t,Uc=null;break}a:{var o=e,s=n.return,c=n,l=t;if(t=Wc,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=js(s);if(m!==null){m.flags&=-257,Ms(m,s,c,o,t),m.mode&1&&As(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)){As(o,u,t),kl();break a}l=Error(r(426))}else if(ba&&c.mode&1){var _=js(s);if(_!==null){!(_.flags&65536)&&(_.flags|=256),Ms(_,s,c,o,t),Aa(ws(l,c));break a}}o=l=ws(l,c),qc!==4&&(qc=2),Qc===null?Qc=[o]:Qc.push(o),o=s;do{switch(o.tag){case 3:o.flags|=65536,t&=-t,o.lanes|=t;var v=Os(o,l,t);ro(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=ks(o,c,t);ro(o,x);break a}}o=o.return}while(o!==null)}Pl(n)}catch(e){t=e,Uc===n&&n!==null&&(Uc=n=n.return);continue}break}while(1)}function Ol(){var e=zc.current;return zc.current=ps,e===null?ps:e}function kl(){(qc===0||qc===3||qc===2)&&(qc=4),Hc===null||!(Yc&268435455)&&!(Xc&268435455)||xl(Hc,Wc)}function Al(e,t){var n=Q;Q|=2;var i=Ol();(Hc!==e||Wc!==t)&&(nl=null,El(e,t));do try{jl();break}catch(t){Dl(e,t)}while(1);if(Ha(),Q=n,zc.current=i,Uc!==null)throw Error(r(261));return Hc=null,Wc=0,qc}function jl(){for(;Uc!==null;)Nl(Uc)}function Ml(){for(;Uc!==null&&!st();)Nl(Uc)}function Nl(e){var t=Wl(e.alternate,e,Gc);e.memoizedProps=e.pendingProps,t===null?Pl(e):Uc=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,Uc=n;return}if(e!==null)e.flags|=32768,e.subtreeFlags=0,e.deletions=null;else{qc=6,Uc=null;return}}else if(n=cc(n,t,Gc),n!==null){Uc=n;return}if(t=t.sibling,t!==null){Uc=t;return}Uc=t=e}while(t!==null);qc===0&&(qc=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(Q&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===Hc&&(Uc=Hc=null,Wc=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=Q;Q|=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(),Q=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,ia(),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,Q&6)throw Error(r(331));var a=Q;for(Q|=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(Q=a,ia(),_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=ws(n,t),t=Os(e,t,1),e=to(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=ws(n,e),e=ks(t,e,1),t=to(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,Hc===e&&(Wc&n)===n&&(qc===4||qc===3&&(Wc&130023424)===Wc&&500>lt()-el?El(e,0):Zc|=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=Xa(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||Gi.current)Ps=!0;else{if((e.lanes&n)===0&&!(t.flags&128))return Ps=!1,rc(e,t,n);Ps=!!(e.flags&131072)}}else Ps=!1,ba&&t.flags&1048576&&ha(t,ca,t.index);switch(t.lanes=0,t.tag){case 2:var i=t.type;tc(e,t),e=t.pendingProps;var a=qi(t,Wi.current);Ga(t,n),a=Mo(null,t,i,e,a,n);var o=No();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,Ji(i)?(o=!0,Qi(t)):o=!1,t.memoizedState=a.state!==null&&a.state!==void 0?a.state:null,Qa(t),a.updater=ys,t.stateNode=a,a._reactInternals=t,Cs(t,i,e,n),t=Us(null,t,i,!0,o,n)):(t.tag=0,ba&&o&&ga(t),Fs(null,t,a,n),t=t.child),t;case 16:i=t.elementType;a:{switch(tc(e,t),e=t.pendingProps,a=i._init,i=a(i._payload),t.type=i,a=t.tag=Yl(i),e=_s(i,e),a){case 0:t=Vs(null,t,i,e,n);break a;case 1:t=Hs(null,t,i,e,n);break a;case 11:t=Is(null,t,i,e,n);break a;case 14:t=Ls(null,t,i,_s(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:_s(i,a),Vs(e,t,i,a,n);case 1:return i=t.type,a=t.pendingProps,a=t.elementType===i?a:_s(i,a),Hs(e,t,i,a,n);case 3:a:{if(Ws(t),e===null)throw Error(r(387));i=t.pendingProps,o=t.memoizedState,a=o.element,$a(e,t),io(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=ws(Error(r(423)),t),t=Gs(e,t,i,n,a);break a}if(i!==a){a=ws(Error(r(424)),t),t=Gs(e,t,i,n,a);break a}for(ya=Ti(t.stateNode.containerInfo.firstChild),va=t,ba=!0,xa=null,n=La(t,null,i,n),t.child=n;n;)n.flags=n.flags&-3|4096,n=n.sibling}else{if(ka(),i===a){t=nc(e,t,n);break a}Fs(e,t,i,n)}t=t.child}return t;case 5:return mo(t),e===null&&Ta(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),Bs(e,t),Fs(e,t,s,n),t.child;case 6:return e===null&&Ta(t),null;case 13:return Js(e,t,n);case 4:return fo(t,t.stateNode.containerInfo),i=t.pendingProps,e===null?t.child=Ia(t,null,i,n):Fs(e,t,i,n),t.child;case 11:return i=t.type,a=t.pendingProps,a=t.elementType===i?a:_s(i,a),Is(e,t,i,a,n);case 7:return Fs(e,t,t.pendingProps,n),t.child;case 8:return Fs(e,t,t.pendingProps.children,n),t.child;case 12:return Fs(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,Hi(Ra,i._currentValue),i._currentValue=s,o!==null){if(Cr(o.value,s)){if(o.children===a.children&&!Gi.current){t=nc(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=eo(-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),Wa(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),Wa(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}}Fs(e,t,a.children,n),t=t.child}return t;case 9:return a=t.type,i=t.pendingProps.children,Ga(t,n),a=Ka(a),i=i(a),t.flags|=1,Fs(e,t,i,n),t.child;case 14:return i=t.type,a=_s(i,t.pendingProps),a=_s(i.type,a),Ls(e,t,i,a,n);case 15:return Rs(e,t,t.type,t.pendingProps,n);case 17:return i=t.type,a=t.pendingProps,a=t.elementType===i?a:_s(i,a),tc(e,t),t.tag=1,Ji(i)?(e=!0,Qi(t)):e=!1,Ga(t,n),xs(t,i,a),Cs(t,i,a,n),Us(null,t,i,!0,e,n);case 19:return ec(e,t,n);case 22:return zs(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===P)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 N:return e=ql(19,n,t,a),e.elementType=N,e.lanes=o,e;case I: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 P:s=14;break a;case F: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=I,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},Qa(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 Ui;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(Ji(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(Ji(n))return Zi(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=eo(r,i),a.callback=t??null,to(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=eo(a,o),t.payload={element:e},r=r===void 0?null:r,r!==null&&(t.callback=r),e=to(i,t,o),e!==null&&(hl(e,i,o,a),no(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[Ai]=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[Ai]=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[Ai]=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()),!(Q&6)&&(tl=lt()+500,ia()))}break;case 13:wl(function(){var t=Xa(e,1);t!==null&&hl(t,e,1,pl())}),uu(e,1)}},Rt=function(e){if(e.tag===13){var t=Xa(e,134217728);t!==null&&hl(t,e,134217728,pl()),uu(e,134217728)}},zt=function(e){if(e.tag===13){var t=ml(e),n=Xa(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}},Me=function(e,t,n){switch(t){case`input`:if(fe(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=Li(i);if(!a)throw Error(r(90));ce(i),fe(i,a)}}}break;case`textarea`:K(e,n);break;case`select`:t=n.value,t!=null&&G(e,!!n.multiple,t,!1)}},Re=Cl,ze=wl;var bu={usingClientEntryPoint:!1,Events:[Fi,Ii,Li,Ie,Le,Cl]},xu={findFiberByHostInstance:Pi,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[Ai]=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[Ai]=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[Ai]=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])}let x={manifest:{schemaVersion:1,sdkVersion:`0.1.0`,id:`stillmade-internal.board-duration`,version:`1.0.0`,name:`Board duration`,description:`Resize the final Board and trim its elements to the approved duration.`,kind:`task`,runtime:`javascript`,inputs:{doc:{type:`json`},durationMs:{type:`number`}},outputs:{edit:{type:`json`}},permissions:{project:[],network:[],filesystem:[],secrets:[]}},code:`const loadPanelDoc=doc=>doc;\nfunction setCanvasEditorDuration(doc, durationMs) {\n const want = Math.max(1000, Math.round(Number(durationMs) || 0));\n const canvases = doc.strip.filter((p) => p.type === 'canvas');\n if (!canvases.length) return doc;\n const last = canvases[canvases.length - 1];\n const newLastDur = Math.max(500, want - last.startMs);\n if (newLastDur === last.durationMs) return doc;\n const strip = doc.strip.map((p) => {\n if (p.panelId !== last.panelId) return p;\n let elements = p.elements;\n // Shrinking: drop elements that now start past the end (they'd be\n // invisible but still emit sounds) and let ones that outlive the new end\n // run to it (leaveMs null = to-end).\n if (newLastDur < p.durationMs) {\n elements = (p.elements || [])\n .filter((el) => (el.appearMs || 0) < newLastDur)\n .map((el) => (el.leaveMs != null && el.leaveMs > newLastDur ? { ...el, leaveMs: null } : el));\n }\n return { ...p, durationMs: newLastDur, elements };\n });\n return loadPanelDoc({ ...doc, strip });\n}\n\nreturn {edit:setCanvasEditorDuration(input.doc,input.durationMs)};`,tests:[]};Object.freeze([`list`,`accounts`,`grants`,`create`,`bind`,`read`,`update`,`creatives`,`contribute`,`grant`,`revoke`,`unlink`]);function S(e){if(typeof e!=`string`||e.length>4194304)return!1;if(/^\\/api\\/media\\/[A-Za-z0-9_-]+\\/[A-Za-z0-9_-][A-Za-z0-9._-]*$/.test(e)||/^data:image\\/(png|jpeg|webp|gif);base64,[a-z0-9+/=]+$/i.test(e))return!0;try{let t=new URL(e);return[`https:`,`blob:`,`sm-media:`].includes(t.protocol)&&!t.username&&!t.password}catch{return!1}}Object.freeze({files:256,textBytes:3e6,pathLength:180});var C=class extends Error{constructor(e,t,n=[]){super(t),this.name=`BlockError`,this.code=e,this.details=n}};function w(e,t,n){if(!e)throw new C(t,n)}function T(e){return!!e&&typeof e==`object`&&!Array.isArray(e)&&[Object.prototype,null].includes(Object.getPrototypeOf(e))}function E(){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:D,schemaMatches:O}=E();Object.freeze([`upstream`,`project`,`adapter`,`chat`,`default`,`user`,`external`]);let k=Object.freeze([`key`,`semantic`,`accepts`,`schema`,`sources`,`sensitivity`,`freshnessPolicy`,`cardinality`,`batchable`]),A=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(A.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 j=`(0|[1-9][0-9]{0,5})\\\\.(0|[1-9][0-9]{0,5})\\\\.(0|[1-9][0-9]{0,5})`;RegExp(`^`+j+`$`),RegExp(`^(>=|<=|>|<|=)?`+j+`$`),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 M=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(M))]),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 N=w,P=T;Object.freeze([`type`,`required`,`default`,`min`,`max`,`description`,`role`,`primary`,`context`,`imageMode`,...k]),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 F=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`}),I=(e,t,n,r)=>Object.freeze({executor:e,mode:t,byok:n,summary:r}),L=Object.freeze({\"text.generate\":I(`capability-run`,`sync`,!0,`Exact model, account BYOK or credits, and explicit run review`),\"audio.speech\":I(`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\":I(`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\":I(`capability-run`,`sync`,!1,`One prompt to generated music (5–240 seconds) with StillMade credits and playback review`),\"audio.sfx\":I(`capability-run`,`sync`,!1,`One prompt to a generated sound effect (0.5–22 seconds) with StillMade credits and playback review`),\"image.generate\":I(`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\":I(`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\":I(`capability-run`,`sync`,!0,`One to four owned images to bounded production notes; host-selected model/payment and actual description review`),\"media.analyze\":I(`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\":I(`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\":I(`capability-run`,`sync`,!1,`One topic searched on the web and summarized with cited sources, with StillMade credits`),\"timeline.propose\":I(`capability-run`,`sync`,!0,`Bounded typed context to strict timeline-edit JSON; host-selected model/payment, stale-before checks, preview and Apply`),\"workspace.propose\":I(`capability-run`,`sync`,!0,`Bounded typed context to a strict workspace-edit proposal for one permitted workspace; preview and explicit Apply`),\"connection.execute\":I(`connection`,`sync`,!1,`One reviewed action on a connected third-party app account through the host connection service; the Block never receives account credentials`)}),R=e=>Object.freeze(Object.entries(L).filter(([,t])=>e(t)).map(([e])=>e));R(()=>!0),R(e=>e.executor===`capability-run`),R(e=>e.executor===`capability-run`&&e.mode===`sync`),R(e=>e.byok),[...Object.keys(F).map(e=>`context.${e}.read`)];let z=new Set([`__proto__`,`prototype`,`constructor`]);function B(e,t=0,n={nodes:0}){if(N(t<=40&&++n.nodes<=5e5,`LIMIT`,`Document exceeds complexity limit`),!(e===null||[`string`,`boolean`].includes(typeof e))){if(typeof e==`number`){N(Number.isFinite(e),`SCHEMA`,`Numbers must be finite`);return}N(Array.isArray(e)||P(e),`SCHEMA`,`Only JSON data is accepted`);for(let[r,i]of Object.entries(e))N(!z.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):P(e)?Object.fromEntries(Object.keys(e).sort().map(n=>[n,t(e[n])])):e;return JSON.stringify(t(e))}async function ee(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(``)}function H(e){return N(e?.version===1&&typeof e.run==`function`&&typeof e.actor==`function`,`HOST_SERVICES`,`Block editing requires version 1 local sandbox and identity services.`),e}let te=new Set([`cycle`,`accumulation`,`reveal`,`expressionSequence`,`zoomProgression`,`poseProgression`,`comparison`,`moodShift`,`insertCutaway`,`matchSwap`,`progressiveReveal`]),ne=[`story`,`explainer`],re=e=>e<0?0:e>1?1:e;function ie(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 ae=e=>Math.max(38,Math.min(62,Number(e)||50));function oe(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 se(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=oe(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=ae(e.kbStartX??50),i=ae(e.kbStartY??50),a=ae(e.kbEndX??60),o=ae(e.kbEndY??40),s=e.kbStartScale||1,c=e.kbEndScale||1.2,l=oe(Math.max(1.06,1+(s-1)*n),50-t,50-i,t,i,`ST`),u=oe(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 ce=(e,t,n)=>e+(t-e)*n;function le(e,t,n){if(!e||e.type===`none`)return null;let r=se(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=re((t-a)/o);s=ie(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:ce(l.scale,u.scale,f),tx:ce(l.tx,u.tx,f),ty:ce(l.ty,u.ty,f),rot:ce(l.rot,u.rot,f),blur:ce(l.blur,u.blur,f),ox:ce(l.ox,u.ox,f),oy:ce(l.oy,u.oy,f)}}function ue(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 U(e){let t=Math.sin(e*127.1+311.7)*43758.5453;return t-Math.floor(t)}function de(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 fe(e,t,n){let r=de(e),i=de(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 W(e,t){let n=de(e);return n?`rgba(${n.r},${n.g},${n.b},${t})`:`rgba(0,0,0,${t})`}let pe=e=>Array.isArray(e)&&e.length>0;function me(e,t,n,r,i){let a,o,s,c,l;if(pe(i)){let e=i[0]||ve[0],t=i[1]||ve[1];a=e,o=fe(e,t,.4),s=W(t,.28),c=W(t,.35),l=W(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)`;ue(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 G(e,t,n,r){ue(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 he(e,t,n,r){ue(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 ge(e,t,n,r,i){let a;if(pe(i)){let r=i[0]||ye[0],o=i[1]||ye[1];ue(e,t,n,r,fe(r,o,.18)),a=e=>W(o,e)}else ue(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+U(i)*.9,c=(.01+U(i+99)*.04)*Math.min(t,n),l=(U(i+7)+.05*Math.sin(r*.3+i))*t,u=n+c-(r*s*n*.06+U(i+31)*o)%o,d=.15+U(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 K(e,t,n,r){ue(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 _e(e,t,n,r,i){let a=pe(i),o=a?i[0]||be[0]:`#e8e4da`,s=a?i[1]||be[1]:`#57503f`,c=Math.floor(Math.max(0,Number(r)||0)/.17)%8*977,l=Math.min(t,n)/360;ue(e,t,n,o,fe(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,W(s,0)),u.addColorStop(1,W(s,.1)),e.fillStyle=u,e.fillRect(0,0,t,n);for(let r=0;r<6;r++){let i=U(c+11+r)*t,a=U(c+23+r)*n,o=Math.max(t,n)*(.1+.16*U(c+37+r)),l=e.createRadialGradient(i,a,0,i,a,o);l.addColorStop(0,W(s,.055)),l.addColorStop(1,W(s,0)),e.fillStyle=l,e.fillRect(0,0,t,n)}let d=Math.max(24,Math.min(t,n)*.075),f=(U(c+3)-.5)*3*l,p=(U(c+4)-.5)*3*l;e.lineWidth=Math.max(1,l*1.1),e.strokeStyle=W(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=W(s,.5);for(let r=0;r<42;r++){let i=U(c+101+r)*t,a=U(c+211+r)*n,o=(.8+1.8*U(c+307+r))*l;e.globalAlpha=.22+.38*U(c+401+r),e.fillRect(i,a,o,o)}e.strokeStyle=W(s,.3),e.lineWidth=Math.max(.6,l*.7);for(let r=0;r<14;r++){let i=U(c+503+r)*t,a=U(c+601+r)*n,o=U(c+701+r)*Math.PI*2,s=(4+6*U(c+809+r))*l;e.globalAlpha=.15+.2*U(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=U(c+1103+r)*t,a=U(c+1301+r)*n,o=r%2==0;e.fillStyle=o?W(s,1):`#ffffff`,e.globalAlpha=o?.04+.05*U(c+1409+r):.05+.07*U(c+1511+r),e.fillRect(i,a,l,l)}e.globalAlpha=1}let ve=[`#0a1a3f`,`#3b7dff`],ye=[`#0b1226`,`#96beff`],be=[`#e8e4da`,`#57503f`],xe={grid:{label:`Blue Grid`,draw:me,css:`linear-gradient(180deg, #0a1a3f, #123a8a)`,tunable:[{key:`base`,label:`Background`,default:ve[0]},{key:`accent`,label:`Grid & glow`,default:ve[1]}]},aurora:{label:`Aurora`,draw:G,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:he,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:ge,css:`radial-gradient(circle at 60% 70%, rgba(150,190,255,0.5), #152244 70%)`,tunable:[{key:`base`,label:`Background`,default:ye[0]},{key:`accent`,label:`Dots`,default:ye[1]}]},waves:{label:`Waves`,draw:K,css:`linear-gradient(180deg, #0a2e4a 40%, rgba(40,190,180,0.6) 70%, #04122a)`},paper:{label:`Paper`,draw:_e,css:`linear-gradient(180deg, #e8e4da, #ded9cd)`,tunable:[{key:`base`,label:`Paper`,default:be[0]},{key:`accent`,label:`Grid & flecks`,default:be[1]}]}};function Se(e){if(typeof e!=`string`||!e.startsWith(`anim|`))return null;let[,t,...n]=e.split(`|`);return xe[t]?{key:t,colors:n}:null}function Ce(e){return Se(e)!=null}function we(e){let t=Se(e);return t&&xe[t.key].tunable||null}function Te(e,t){let n=Se(e),r=n&&xe[n.key].tunable;return!r||!r[t]?null:n.colors[t]||r[t].default}function Ee(e,t,n){let r=Se(e),i=r&&xe[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 De(e){let t=Se(e);if(!t)return null;let n=xe[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 Oe(e,t,n,r,i){let a=Se(t);return a?(xe[a.key].draw(e,n,r,Number(i)||0,a.colors),!0):!1}let ke=[`pop`,`fade`,`rise`,`scale`],Ae=[`pop`,`fade`,`rise`,`typewriter`,`pop-word`,`scale`];function je(e,t,n,r,i){let a=typeof t==`string`?t:``;if(!Oe(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),Me(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),Me(i,o)}e.fillStyle=i}else e.fillStyle=a||`#ffffff`;e.fillRect(0,0,n,r)}}function Me(e,t){let n=t.length;t.forEach((t,r)=>e.addColorStop(n===1?0:r/(n-1),t))}function Ne(e){if(typeof e!=`string`||!e)return`#ffffff`;if(Ce(e))return De(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 Pe=[{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(xe).map(([e,t])=>({key:`anim-${e}`,label:t.label,value:`anim|${e}`,animated:!0}))],Fe=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},Ie=(e,t)=>Fe(`${e}|${t}`)%2e3/1e3-1;function Le(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 Re=(e,t,n)=>Math.max(t,Math.min(n,e));function ze(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=Le((e+Fe(a.id)%48)%48,t),i=Re(r.x,n+.03,1-n-.03),l=Re(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=Re(l.x+Ie(a.id,`x`)*.015,n,1-n),l.y=Re(l.y+Ie(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 Be(e,t){if(!e.autoArrange)return e;let n=ze(e,t);return{...e,elements:(e.elements||[]).map(e=>!e.pinned&&n.has(e.id)?{...e,pos:n.get(e.id)}:e)}}function Ve(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 He(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 Ue=[`word-pop`,`sentence-build`,`line`,`typewriter`,`highlight`],We=[`pop`,`fade`,`slide`,`rise`,`scale`];function Ge(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 Ke(e,t){return String(e.text||``).split(/\\s+/).filter(Boolean).map((n,r)=>{let i=Ge(e,r),a=t-i;return{text:n,start:i,local:a,p:Re(a/320,0,1),spoken:a>=0}})}function qe(e,t){let n=Ke(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=Re(i.local/a,0,1);r+=Math.round(o*(i.text.length+1))}return r}function Je(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 le(e.motion,a,i)}function Ye(e,t,n){return e+(t-e)*n}function Xe(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 Ze(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=Xe((t-a)/l,n.ease);return{pos:{x:Ye(i.x,u.x,d),y:Ye(i.y,u.y,d)},size:i.size!=null&&u.size!=null?Ye(i.size,u.size,d):u.size??i.size}}return{pos:{x:i.x,y:i.y},size:i.size}}function Qe(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 $e(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=Ve(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 et({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 tt(e,t){return(e?.elements||[]).filter(e=>t>=(e.appearMs||0)&&(e.leaveMs==null||t<e.leaveMs))}function nt(e,t,n=`pop`){let r=t-(e.appearMs||0),i=Re(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 rt(e){let t=Number(e?.durationMs)||0,n=new Set([0]);for(let r of e?.elements||[])n.add(Re(Number(r.appearMs)||0,0,t)),r.leaveMs!=null&&n.add(Re(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 it(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 at(e,t,n){return!Array.isArray(e)||!(n>t)?[]:e.filter(e=>e.atMs>t&&e.atMs<=n)}function ot(e,t,n,r,i,a){e.save(),je(e,t.background,i,a,n);let o=t.handoff?.arrive===`fade`?`fade`:`pop`;for(let s of tt(t,n)){let c=nt(s,n,o),l=Ze(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=Je(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}=Ve(t),i=Math.max(c/n,o/r),a=c/i,l=o/i,u=(n-a)/2,d=(r-l)/2;Qe(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}=Ve(t),a=i/r*n;Qe(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=qe(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=Ke(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 st=(e,t,n,r,i,a,o,s)=>({id:e,name:t,scenario:n,minImages:r,slots:i,textSlots:a,pSlots:o,pTextSlots:s}),ct=[st(`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}]),st(`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}]),st(`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}]),st(`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}]),st(`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}]),st(`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}]),st(`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}]),st(`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}]),st(`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}]),st(`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}]),st(`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}]),st(`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}]),st(`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}]),st(`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}]),st(`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}]),st(`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}]),st(`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}]),st(`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}]),st(`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}]),st(`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}])],lt=new Map(ct.map(e=>[e.id,e])),ut=e=>lt.get(e)||null;function dt(e,t=16/9){return e?t<1?{slots:e.pSlots,textSlots:e.pTextSlots}:{slots:e.slots,textSlots:e.textSlots}:null}function ft(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=dt(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 pt({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 mt=new Set([`mode`,`meta`,`audio`,`styleBlock`,`sheets`,`lineages`,`scenes`,`strip`,`projectType`,`projectTypeNote`]),ht=new Set([`sceneId`,`title`,`genre`,`styleBlock`,`styleRef`,`styleRefs`,`sheets`,`titleScreen`,`renderer`,`canvas`,`elements`]),gt=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(`.`)),_t=new Set([`panelId`,`type`,`sceneId`,`startMs`,`durationMs`,`wordStart`,`wordEnd`,`provenance`]),vt=new Set([`panelId`,`type`,`sceneId`,`mode`,`gif`,`gifQuery`,`candidates`,`tone`,`startMs`,`durationMs`,`transitionIn`,`wordStart`,`wordEnd`,`provenance`]),yt=[`replace`,`overlay`],bt=new Set([`gifUrl`,`mode`,`gifQuery`,`box`,`wordStart`,`wordEnd`]);function xt(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(!bt.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 St=[{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`]}];St.find(e=>e.default)?.id||St[0].id;let Ct=[`seedance-2.0`,`seedance-2.0-fast`,`seedance-2.0-mini`],wt=new Set([`panelId`,`type`,`sceneId`,`lineageId`,`sourcePanelId`,`zoom`,`image`,`versions`,`styleWarning`,`styleStrict`,`startMs`,`durationMs`,`transitionIn`,`provenance`,`wordStart`,`wordEnd`,`needsRefresh`,`says`]);function Tt(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`)}let Et=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(`.`)),Dt=[`swipe-up`,`swipe-down`,`swipe-left`,`swipe-right`,`cut`],Ot=[`pop`,`fade`],kt=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 At(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(!kt.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 jt(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 Mt({aspect:e=`16:9`,durationMs:t=1e4,words:n=[],voPath:r=null}={}){return Zt({mode:`imagePanel`,meta:{title:`Canvas`,aspect:e},audio:{voPath:r,words:Array.isArray(n)?n:[]},styleBlock:`canvas editor`,sheets:{},lineages:{},scenes:[{sceneId:`s1`,title:`Canvas`,genre:null}],strip:[{panelId:`cv1`,type:`canvas`,sceneId:`s1`,background:`#ffffff`,autoArrange:!0,planned:!1,elements:[],startMs:0,durationMs:Math.max(1e3,Math.round(Number(t)||1e4)),transitionIn:`cut`,provenance:`user`}]})}function Nt(e,t){let n=Math.max(1e3,Math.round(Number(t)||0)),r=e.strip.filter(e=>e.type===`canvas`);if(!r.length)return e;let i=r[r.length-1],a=Math.max(500,n-i.startMs);if(a===i.durationMs)return e;let o=e.strip.map(e=>{if(e.panelId!==i.panelId)return e;let t=e.elements;return a<e.durationMs&&(t=(e.elements||[]).filter(e=>(e.appearMs||0)<a).map(e=>e.leaveMs!=null&&e.leaveMs>a?{...e,leaveMs:null}:e)),{...e,durationMs:a,elements:t}});return Zt({...e,strip:o})}function Pt(e,{words:t=[],voPath:n=null}={}){let r=(Array.isArray(t)?t:[]).map(e=>({text:String(e.text||``),startMs:Math.round(Number(e.startMs)||0),endMs:Math.round(Number(e.endMs)||0)})).filter(e=>e.text),i=e?.audio||{},a=i.words||[];if(a.length===r.length&&r.every((e,t)=>e.text===a[t].text&&e.startMs===a[t].startMs&&e.endMs===a[t].endMs)&&(i.voPath||null)===(n||null))return e;let o=Zt({...e,audio:{...i,voPath:n||null,words:r}}),s=r.length?r[r.length-1].endMs:0,c=o.strip.reduce((e,t)=>Math.max(e,t.startMs+t.durationMs),0);return s+400>c&&(o=Nt(o,s+400)),o}function Ft(e){let t=e?.meta?.aspect||`16:9`;return t===`9:16`?9/16:t===`1:1`?1:16/9}function It(e,t){let n=ut(t.template);if(n){let r=ft(t.elements||[],n,{aspect:Ft(e)}),i=ze({...t,autoArrange:!0,elements:r.map(e=>e.pos?{...e,pinned:!0}:e)},{aspect:Ft(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?Be(t,{aspect:Ft(e)}):t}function Lt(e,t){if(!e.autoArrange||!e.template)return e.template;let n=ut(e.template);if(!n)return e.template;let r=t.filter(e=>e.kind===`image`||e.kind===`video`).length,i=t.filter(e=>e.kind===`text`).length;return r>0&&r<=n.slots.length?e.template:pt({imageCount:r,textCount:i,hint:`${n.scenario||``} ${e.hint||``}`})||e.template}function Rt(e,t,n){let r=e.strip.find(e=>e.panelId===t);if(!r||r.type!==`canvas`)throw Error(`addCanvasElement: ${t} is not a canvas panel`);let i={id:`u${(r.elements||[]).length+1}${Date.now().toString(36).slice(-4)}`,...n},a=e.strip.map(n=>{if(n.panelId!==t)return n;let r=[...n.elements||[],i];return It(e,{...n,template:Lt(n,r),elements:r})});return Zt({...e,strip:a})}function zt(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 It(e,{...r,template:Lt(r,i),elements:i})});return Zt({...e,strip:r})}let Bt=new Set([`model`,`durationSec`,`video`,`srcKey`,`genSeconds`,`generatedAt`,`prompt`,`fit`]);function Vt(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(!Bt.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(!St.some(t=>t.id===e.model)&&!Ct.includes(e.model))throw Error(`${t}: animateNext model must be one of ${St.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 Ht=new Set([`panelId`,`type`,`sceneId`,`visibleElements`,`textOverlays`,`layout`,`image`,`versions`,`startMs`,`durationMs`,`transitionIn`,`provenance`,`wordStart`,`wordEnd`,`method`,`methodGroup`,`needsRefresh`]),Ut=[`scene`,`diagram`],Wt=[`story`,`explainer`,`both`,`neither`];function Gt(e){return e?.renderer===`diagram`?`diagram`:`scene`}let Kt=[`small`,`medium`,`large`];function qt(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&&!Kt.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 Jt(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 Yt=/\\s*A persistent dark title bar across the very top of the frame(?: with bold white text reading \"[^\"]*\")?\\.?/gi,Xt=e=>{let t=String(e||``),n=t.replace(Yt,``);return n===t?e:n.replace(/[ \\t]{2,}/g,` `).trim()};function Zt(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(!mt.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&&!Wt.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=Jt(Array.isArray(t.strip)&&t.strip.some(e=>e?.type===`canvas`&&(n.some(t=>t in e&&!Et.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&&!Et.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(!ht.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&&!ne.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&&!Ut.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(Gt(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(!_t.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(!Et.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&&!Dt.includes(e.handoff.exit))throw Error(`${n} (${e.panelId}): handoff exit must be ${Dt.join(`|`)}`);if(e.handoff.arrive!=null&&!Ot.includes(e.handoff.arrive))throw Error(`${n} (${e.panelId}): handoff arrive must be ${Ot.join(`|`)}`)}if(Gt(d.get(e.sceneId))===`diagram`)throw Error(`${n} (${e.panelId}): canvas panels live in generative scenes only`);At(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(!wt.has(t))throw Error(`${n} (${e.panelId}): unknown zoom field \"${t}\"`);if(Gt(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`);Tt(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(!vt.has(t))throw Error(`${n} (${e.panelId}): unknown giphy field \"${t}\"`);if(!yt.includes(e.mode))throw Error(`${n} (${e.panelId}): giphy panel mode must be ${yt.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=Gt(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(!Ht.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`)}}qt(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(!gt.has(t))throw Error(`${n}: unknown field \"${t}\"`);if(qt(e.textOverlays,`${n} (${e.panelId})`),xt(e.overlayLayer,`${n} (${e.panelId})`),Vt(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&&!te.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?Xt(o.styleBlock):o.styleBlock,y=!1,b=o.scenes.map(e=>{if(typeof e.styleBlock!=`string`||!e.styleBlock)return e;let t=Xt(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}}async function Qt(e,t,{host:n,signal:r,assertCurrent:i=()=>{}}){let a=H(n),o=a.actor(),s=JSON.stringify(e),c=()=>{i(),N(o&&a.actor()===o&&!r?.aborted&&JSON.stringify(e)===s,`STALE`,`The Board changed before its duration could be applied.`)};c(),N(P(e)&&Array.isArray(e.strip)&&e.strip.length<=2048&&Number.isFinite(t)&&t>0&&t<=2**53-1,`BOARD_DURATION`,`Choose a valid Board duration.`);let l=e.strip.filter(e=>e.type===`canvas`),u=l.at(-1);if(!u)return e;N(new Set(e.strip.map(e=>e.panelId)).size===e.strip.length&&l.every(e=>typeof e.panelId==`string`&&Number.isFinite(e.startMs)&&Number.isFinite(e.durationMs)&&Array.isArray(e.elements)),`BOARD_DURATION`,`Choose valid uniquely identified Boards.`);let d={durationMs:t,doc:{strip:e.strip.map(e=>e.type===`canvas`?{panelId:e.panelId,type:`canvas`,startMs:e.startMs,durationMs:e.durationMs,elements:e.elements.map((e,t)=>({origin:t,...e.appearMs===void 0?{}:{appearMs:e.appearMs},...e.leaveMs===void 0?{}:{leaveMs:e.leaveMs}}))}:{type:`other`})}};B(d),N(JSON.stringify(d).length<=1e6,`BOARD_DURATION`,`The Board timing data is too large.`);let f=structuredClone(d.doc),p=f.strip.filter(e=>e.type===`canvas`).at(-1),m=Math.max(500,Math.max(1e3,Math.round(t))-u.startMs);m!==u.durationMs&&(p.durationMs=m,m<u.durationMs&&(p.elements=p.elements.filter(e=>(e.appearMs||0)<m).map(e=>e.leaveMs!=null&&e.leaveMs>m?{...e,leaveMs:null}:e)));let h=await a.run(x,{kind:`run`,input:d,signal:r,timeoutMs:15e3});if(c(),B(h.outputs?.edit),N(V(h.outputs.edit)===V(f),`BOARD_DURATION`,`The sandbox changed unrelated Board timing or elements.`),m===u.durationMs)return e;let g={...u,durationMs:m,elements:p.elements.map(e=>{let t=u.elements[e.origin];return e.leaveMs===t.leaveMs?t:{...t,leaveMs:e.leaveMs}})},_=Zt({...e,strip:e.strip.map(e=>e===u?g:e)});return c(),_}let $t={manifest:{schemaVersion:1,sdkVersion:`0.1.0`,id:`stillmade-internal.board-chat-edits`,version:`1.0.0`,name:`Board chat edits`,description:`Apply bounded proposed edits to opaque board data.`,kind:`task`,runtime:`javascript`,inputs:{panels:{type:`json`},edits:{type:`json`}},outputs:{result:{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\n// Canvas Chat Builder — the DETERMINISTIC core (spec S4 / S5 / S6).\n//\n// The chat layer (LLM) decides intent, descriptors and which words matter; this\n// module does the part that must be exact and repeatable, matching how the rest\n// of Image Panel Mode splits \"planner = LLM\" from \"assembly = deterministic\":\n//\n// S4 match each asset to the voiceover moment that talks about it, using its\n// descriptor vs the transcript, and place it ON the beat with the same\n// visual-lead offset every other panel uses.\n// S5 a video is fit TO its beat (trim), muted — the clip's own length never\n// drives the timing.\n// S6 a NEW canvas roughly every ~5s rather than one endless canvas, with a\n// transition between them and self-arranging layout inside each.\n//\n// Pure functions — no network, no store, no paid calls.\n\nconst CANVAS_TARGET_MS = 5000; // S6: ~5s per new canvas\nconst MIN_BEAT_GAP_MS = 450; // two assets never land on the same instant\nconst WINDOW_WORDS = 8; // transcript window an asset is matched against\n\n// Words that carry no matching signal. Kept small and obvious on purpose: an\n// over-aggressive list silently destroys matches that a user can't debug.\nconst STOP = new Set([\n 'a', 'an', 'the', 'and', 'or', 'but', 'if', 'so', 'of', 'to', 'in', 'on', 'at', 'for', 'with',\n 'from', 'by', 'is', 'are', 'was', 'were', 'be', 'been', 'it', 'its', 'this', 'that', 'these',\n 'those', 'as', 'you', 'your', 'we', 'our', 'i', 'my', 'they', 'them', 'their', 'he', 'she',\n 'his', 'her', 'not', 'no', 'do', 'does', 'did', 'can', 'will', 'just', 'about', 'into', 'over',\n]);\n\nfunction tokenize(text) {\n return String(text || '')\n .toLowerCase()\n .replace(/[^a-z0-9$%\\\\s]/g, ' ')\n .split(/\\\\s+/)\n .filter((t) => t && t.length > 1 && !STOP.has(t));\n}\n\n// Overlap score between an asset descriptor and a transcript window. Weighted so\n// a rare, longer token (e.g. \"dopamine\", \"$5k\") counts for more than a common\n// short one — that is what makes \"channels earning $5k/month\" land on the words\n// where the narration actually says it.\nfunction scoreMatch(descTokens, windowTokens) {\n if (!descTokens.length || !windowTokens.length) return 0;\n const win = new Set(windowTokens);\n let hit = 0;\n for (const t of new Set(descTokens)) {\n if (win.has(t)) hit += Math.min(3, 1 + Math.floor(t.length / 4));\n }\n return hit / descTokens.length;\n}\n\nconst wordMs = (w) => Number(w?.startMs ?? w?.start ?? 0) || 0;\n\n// Words inside the user's chosen coverage range (S4: \"how much of the voiceover\n// should these assets cover\"). Returns the words plus their absolute index so\n// placement can report a word index as well as ms.\nfunction wordsInRange(words, fromMs, toMs) {\n const list = Array.isArray(words) ? words : [];\n const lo = Number.isFinite(fromMs) ? fromMs : -Infinity;\n const hi = Number.isFinite(toMs) ? toMs : Infinity;\n return list\n .map((w, i) => ({ w, i, ms: wordMs(w) }))\n .filter(({ ms }) => ms >= lo && ms <= hi);\n}\n\n// S4 — place each asset at the moment the narration talks about its content.\n// Greedy by confidence: the strongest descriptor↔transcript match claims its\n// beat first, so a confident asset is never displaced by a vague one. Assets\n// that match nothing are SPREAD across the remaining gaps rather than dropped —\n// the user gave us that asset on purpose.\nfunction matchAssetsToRange({ assets = [], words = [], fromMs = 0, toMs = null, leadMs = VISUAL_LEAD_MS } = {}) {\n const scoped = wordsInRange(words, fromMs, toMs);\n const rangeStart = scoped.length ? scoped[0].ms : (Number(fromMs) || 0);\n const rangeEnd = scoped.length ? scoped[scoped.length - 1].ms : (Number(toMs) || rangeStart);\n const list = Array.isArray(assets) ? assets : [];\n if (!list.length) return { placements: [], rangeStart, rangeEnd };\n\n // Candidate windows across the range. A window gives CONTEXT for scoring, but\n // the placement must land on the word that actually matched — attributing it\n // to the window's start would drop the visual up to WINDOW_WORDS too early.\n const windows = scoped.map((entry, k) => {\n const slice = scoped.slice(k, k + WINDOW_WORDS);\n return { entries: slice, tokens: tokenize(slice.map(({ w }) => w?.word ?? w?.text ?? '').join(' ')) };\n });\n\n const scored = list.map((a, idx) => {\n const desc = tokenize(a?.descriptor || a?.text || '');\n const descSet = new Set(desc);\n let best = null;\n for (const win of windows) {\n const s = scoreMatch(desc, win.tokens);\n if (s > 0 && (!best || s > best.score)) {\n // the first word inside this window that the descriptor actually mentions\n const hit = win.entries.find((e) => tokenize(e.w?.word ?? e.w?.text ?? '').some((t) => descSet.has(t)))\n || win.entries[0];\n best = { score: s, ms: hit.ms, wordIndex: hit.i };\n }\n }\n return { asset: a, idx, best };\n });\n\n const taken = [];\n const fits = (ms) => taken.every((t) => Math.abs(t - ms) >= MIN_BEAT_GAP_MS);\n const placements = [];\n\n // 1) confident matches claim their beat first\n for (const s of scored.filter((x) => x.best).sort((a, b) => b.best.score - a.best.score)) {\n if (!fits(s.best.ms)) continue;\n taken.push(s.best.ms);\n placements.push({ asset: s.asset, idx: s.idx, atMs: s.best.ms, wordIndex: s.best.wordIndex, matched: true, score: s.best.score });\n }\n // 2) everything else spreads evenly through the range, avoiding claimed beats\n const rest = scored.filter((s) => !placements.some((p) => p.idx === s.idx));\n if (rest.length) {\n const span = Math.max(0, rangeEnd - rangeStart);\n const step = rest.length > 1 ? span / rest.length : 0;\n rest.forEach((s, k) => {\n let ms = Math.round(rangeStart + step * k + (step ? step / 2 : 0));\n let guard = 0;\n while (!fits(ms) && guard++ < 40) ms += MIN_BEAT_GAP_MS;\n taken.push(ms);\n placements.push({ asset: s.asset, idx: s.idx, atMs: ms, wordIndex: null, matched: false, score: 0 });\n });\n }\n\n // Chronological, with the visual-lead offset applied (appear just BEFORE the word).\n placements.sort((a, b) => a.atMs - b.atMs);\n return {\n placements: placements.map((p) => ({ ...p, appearMs: Math.max(rangeStart, p.atMs - leadMs) })),\n rangeStart,\n rangeEnd,\n };\n}\n\n// S6 — split the covered range into ~5s canvases. The last slice is merged back\n// when it would be a sliver, so a 5.4s range is ONE canvas, not a 5s + 0.4s stub.\nfunction splitRangeIntoCanvases(fromMs, toMs, targetMs = CANVAS_TARGET_MS) {\n const start = Number(fromMs) || 0;\n const end = Math.max(start, Number(toMs) || start);\n const span = end - start;\n if (span <= 0) return [{ startMs: start, endMs: start, durationMs: 0 }];\n const n = Math.max(1, Math.round(span / targetMs));\n const slice = span / n;\n const out = [];\n for (let i = 0; i < n; i++) {\n const s = Math.round(start + slice * i);\n const e = i === n - 1 ? end : Math.round(start + slice * (i + 1));\n out.push({ startMs: s, endMs: e, durationMs: e - s });\n }\n return out;\n}\n\n// S5 — a video is fit to its beat: it plays the portion that fits, muted, and\n// never stretches the canvas to its own length. Returns the source-in/out the\n// element should use.\nfunction fitVideoToBeat({ sourceDurationMs = 0, beatMs = 0, sourceInMs = 0 } = {}) {\n const beat = Math.max(0, Number(beatMs) || 0);\n const src = Math.max(0, Number(sourceDurationMs) || 0);\n if (!src || !beat) return { sourceInMs: 0, sourceOutMs: beat, loop: false, muted: true };\n const start = Math.max(0, Math.min(Number(sourceInMs) || 0, Math.max(0, src - 1)));\n const available = src - start;\n if (available >= beat) return { sourceInMs: start, sourceOutMs: start + beat, loop: false, muted: true };\n // Clip shorter than its beat → loop it rather than freeze or stretch the beat.\n return { sourceInMs: start, sourceOutMs: src, loop: true, muted: true };\n}\n\n// Assemble the placed assets (+ any timed text the chat chose) into real canvas\n// panel rows — the same shape the strip and the canvas mini-editor already use,\n// so the build is a first draft the user can hand-edit afterward (S8).\nfunction buildCanvasPanels({\n assets = [], words = [], fromMs = 0, toMs = null, texts = [],\n targetMs = CANVAS_TARGET_MS, sceneId = null, idPrefix = 'cvb', leadMs = VISUAL_LEAD_MS,\n} = {}) {\n const { placements, rangeStart, rangeEnd } = matchAssetsToRange({ assets, words, fromMs, toMs, leadMs });\n const slices = splitRangeIntoCanvases(rangeStart, toMs ?? rangeEnd, targetMs);\n\n // Timed text rides the same lead offset; the chat supplies WHICH words matter\n // (selective key phrases — never captions, per S4).\n const textPlacements = (Array.isArray(texts) ? texts : [])\n .map((t) => ({\n text: String(t?.text || '').slice(0, 80),\n atMs: Number(t?.atMs) || 0,\n emphasis: t?.emphasis === 'primary' ? 'primary' : 'secondary',\n perWord: !!t?.perWord, // word-by-word reveal (the no-VO \"animated words\")\n }))\n .filter((t) => t.text)\n .map((t) => ({ ...t, appearMs: Math.max(rangeStart, t.atMs - leadMs) }));\n\n const inSlice = (ms, s, isLast) => ms >= s.startMs && (isLast ? ms <= s.endMs : ms < s.endMs);\n\n return slices.map((s, i) => {\n const isLast = i === slices.length - 1;\n let n = 0;\n const elements = [];\n\n for (const p of placements.filter((x) => inSlice(x.appearMs, s, isLast))) {\n const a = p.asset || {};\n const isVideo = a.type === 'video' || a.kind === 'video';\n const appearMs = Math.max(0, p.appearMs - s.startMs);\n const base = {\n id: \\`\\${idPrefix}\\${i + 1}e\\${++n}\\`,\n appearMs,\n leaveMs: null,\n pos: null, // self-arranging (S6) — arrangeCanvas lays it out\n pinned: false, // a manual move later makes it sticky\n entrance: 'pop',\n sfx: 'auto',\n size: p.matched && p.score >= 0.5 ? 0.46 : 0.3,\n descriptor: a.descriptor || '',\n assetId: a.id || null,\n };\n if (isVideo) {\n const beat = Math.max(600, s.endMs - (s.startMs + appearMs));\n const fit = fitVideoToBeat({ sourceDurationMs: a.durationMs, beatMs: beat, sourceInMs: a.sourceInMs });\n elements.push({ ...base, kind: 'video', src: a.url || null, ...fit });\n } else {\n elements.push({ ...base, kind: 'image', src: a.url || null, source: a.source || 'user' });\n }\n }\n\n for (const t of textPlacements.filter((x) => inSlice(x.appearMs, s, isLast))) {\n elements.push({\n id: \\`\\${idPrefix}\\${i + 1}t\\${++n}\\`,\n kind: 'text',\n text: t.text,\n appearMs: Math.max(0, t.appearMs - s.startMs),\n leaveMs: null,\n pos: null,\n size: t.emphasis === 'primary' ? 0.085 : 0.06,\n font: 'Hanken Grotesk',\n color: '#111111',\n weight: 800,\n anim: { type: 'pop', perWord: !!t.perWord, speedMs: 180 },\n sfx: 'auto',\n pinned: false,\n });\n }\n\n elements.sort((a, b) => a.appearMs - b.appearMs);\n return {\n panelId: \\`\\${idPrefix}\\${i + 1}\\`,\n type: 'canvas',\n sceneId,\n background: '#ffffff',\n autoArrange: true, // S6 self-arranging; a manual drag pins it\n planned: true,\n builtBy: 'canvas-chat',\n startMs: s.startMs,\n durationMs: s.durationMs,\n transitionIn: i === 0 ? 'cut' : 'swirl', // S6: transitions between canvases\n elements,\n };\n });\n}\n\n// Canvas Chat Builder — FOLLOW-UP EDITS (spec S7).\n//\n// After the build, the user refines conversationally: \"make this one bigger\",\n// \"move the intro text\", \"swap that image\", \"use less of that video\", \"spread\n// these out more\", \"change the transition\". The chat parses intent; THIS module\n// applies it — deterministically, so an edit is repeatable and testable.\n//\n// Two rules carried from the canvas spec + CLAUDE.md:\n// - a manual move PINS the element (autoArrange must stop fighting the user);\n// - untouched panels/elements keep their object identity, so memoized rows\n// don't re-render (responsiveness invariant 3).\n//\n// Pure functions — no network, no paid calls.\n\nconst EDIT_KINDS = ['resize', 'move', 'swap', 'addText', 'retrim', 'spread', 'transition', 'remove'];\n\nconst SIZE_MIN = 0.06;\nconst SIZE_MAX = 0.9;\nconst clampSize = (v) => Math.max(SIZE_MIN, Math.min(SIZE_MAX, Number(v) || SIZE_MIN));\n\n// Map an element edit over one panel, preserving identity when nothing changed.\nfunction mapElements(panel, fn) {\n let changed = false;\n const elements = panel.elements.map((el) => {\n const next = fn(el);\n if (next && next !== el) { changed = true; return next; }\n return el;\n });\n return changed ? { ...panel, elements } : panel;\n}\n\n// Apply ONE parsed edit to the built panels. Returns { panels, changed, reason }.\n// \\`edit\\` shape (what the chat's parse produces):\n// { kind, panelId?, elementId?, ...kind-specific fields }\nfunction applyCanvasEdit(panels, edit) {\n const list = Array.isArray(panels) ? panels : [];\n if (!edit || !EDIT_KINDS.includes(edit.kind)) {\n return { panels: list, changed: false, reason: \\`unknown edit: \\${edit?.kind ?? 'none'}\\` };\n }\n const targetsPanel = (p) => !edit.panelId || p.panelId === edit.panelId;\n const targetsEl = (el) => !edit.elementId || el.id === edit.elementId;\n\n let changed = false;\n const mark = (v) => { changed = true; return v; };\n\n const next = list.map((panel) => {\n if (!targetsPanel(panel)) return panel;\n\n switch (edit.kind) {\n case 'resize': {\n // \"make this one bigger/smaller\" — factor, or an explicit size.\n const factor = Number(edit.factor) || (edit.direction === 'smaller' ? 0.7 : 1.4);\n return mapElements(panel, (el) => {\n if (!targetsEl(el)) return el;\n const size = clampSize(edit.size != null ? edit.size : (el.size ?? 0.3) * factor);\n return size === el.size ? el : mark({ ...el, size });\n });\n }\n case 'move': {\n // A manual move is STICKY: pin it so auto-arrange leaves it alone.\n return mapElements(panel, (el) => {\n if (!targetsEl(el)) return el;\n const pos = { x: Number(edit.x) || 0, y: Number(edit.y) || 0 };\n return mark({ ...el, pos, pinned: true });\n });\n }\n case 'swap': {\n // \"swap that image\" — new src, descriptor follows so later matching stays true.\n return mapElements(panel, (el) => {\n if (!targetsEl(el)) return el;\n if (!edit.url) return el;\n return mark({\n ...el,\n src: edit.url,\n ...(edit.descriptor ? { descriptor: edit.descriptor } : {}),\n ...(edit.assetId ? { assetId: edit.assetId } : {}),\n });\n });\n }\n case 'retrim': {\n // \"use less of that video\" — re-fit within its beat; never un-mutes.\n return mapElements(panel, (el) => {\n if (!targetsEl(el) || el.kind !== 'video') return el;\n const beat = Math.max(200, Number(edit.beatMs) || (panel.durationMs - (el.appearMs || 0)));\n const fit = fitVideoToBeat({\n sourceDurationMs: Number(edit.sourceDurationMs) || (el.sourceOutMs ?? 0),\n beatMs: beat,\n sourceInMs: edit.sourceInMs != null ? edit.sourceInMs : el.sourceInMs,\n });\n return mark({ ...el, ...fit });\n });\n }\n case 'addText': {\n const text = String(edit.text || '').slice(0, 80);\n if (!text) return panel;\n const el = {\n id: edit.elementId || \\`\\${panel.panelId}t\\${panel.elements.length + 1}\\`,\n kind: 'text', text,\n appearMs: Math.max(0, Math.min(Number(edit.appearMs) || 0, panel.durationMs)),\n leaveMs: null,\n pos: edit.x != null && edit.y != null ? { x: Number(edit.x), y: Number(edit.y) } : null,\n pinned: edit.x != null && edit.y != null,\n size: edit.emphasis === 'primary' ? 0.085 : 0.06,\n font: 'Hanken Grotesk', color: '#111111', weight: 800,\n anim: { type: 'pop', perWord: false, speedMs: 180 }, sfx: 'auto',\n };\n return mark({ ...panel, elements: [...panel.elements, el].sort((a, b) => a.appearMs - b.appearMs) });\n }\n case 'remove': {\n const kept = panel.elements.filter((el) => !targetsEl(el));\n return kept.length === panel.elements.length ? panel : mark({ ...panel, elements: kept });\n }\n case 'spread': {\n // \"spread these out more\" — redistribute appear times across the canvas,\n // keeping order and the minimum gap. Pinned POSITIONS are untouched;\n // this is a timing edit.\n const n = panel.elements.length;\n if (n < 2) return panel;\n const span = Math.max(0, panel.durationMs - 200);\n const step = Math.max(MIN_BEAT_GAP_MS, span / n);\n const ordered = [...panel.elements].sort((a, b) => a.appearMs - b.appearMs);\n const elements = ordered.map((el, i) => {\n const appearMs = Math.round(Math.min(span, i * step));\n return appearMs === el.appearMs ? el : { ...el, appearMs };\n });\n return elements.some((el, i) => el !== ordered[i]) ? mark({ ...panel, elements }) : panel;\n }\n case 'transition': {\n const t = String(edit.transition || '').trim();\n if (!t || t === panel.transitionIn) return panel;\n return mark({ ...panel, transitionIn: t });\n }\n default:\n return panel;\n }\n });\n\n return { panels: changed ? next : list, changed, reason: changed ? '' : 'nothing matched that edit' };\n}\n\n// Apply a sequence of edits (the chat can emit several from one message).\nfunction applyCanvasEdits(panels, edits) {\n let out = Array.isArray(panels) ? panels : [];\n const applied = [];\n const skipped = [];\n for (const e of (Array.isArray(edits) ? edits : [])) {\n const r = applyCanvasEdit(out, e);\n out = r.panels;\n (r.changed ? applied : skipped).push(e);\n }\n return { panels: out, applied, skipped };\n}\n\nreturn {result:applyCanvasEdits(input.panels,input.edits)};`,tests:[{name:`Empty edit list`,input:{panels:[],edits:[]},expected:{result:{panels:[],applied:[],skipped:[]}}}]},en=(e,t)=>JSON.stringify(e)===JSON.stringify(t),tn=[`id`,`kind`,`size`,`pos`,`pinned`,`src`,`descriptor`,`assetId`,`sourceOutMs`,`sourceInMs`,`appearMs`,`leaveMs`,`loop`,`muted`,`text`,`font`,`color`,`weight`,`anim`,`sfx`],nn=[`panelId`,`durationMs`,`transitionIn`],rn=(e,t)=>Object.fromEntries(t.filter(t=>e[t]!==void 0).map(t=>[t,e[t]])),an={resize:[`size`],move:[`pos`,`pinned`],swap:[`src`,`descriptor`,`assetId`],retrim:[`sourceInMs`,`sourceOutMs`,`loop`,`muted`],spread:[`appearMs`],transition:[],remove:[],addText:[]};function on(e,t){N(Array.isArray(e)&&e.length<=128&&e.every(e=>P(e)&&typeof e.panelId==`string`&&Array.isArray(e.elements))&&e.reduce((e,t)=>e+t.elements.length,0)<=2048,`BOARD_EDIT`,`Choose a smaller set of boards to edit.`),N(new Set(e.map(e=>e.panelId)).size===e.length&&e.every(e=>e.elements.every(e=>P(e)&&typeof e.id==`string`)&&new Set(e.elements.map(e=>e.id)).size===e.elements.length),`BOARD_EDIT`,`Board identities are invalid.`),N(Array.isArray(t)&&t.length<=32&&t.every(e=>P(e)&&Object.hasOwn(an,e.kind)),`BOARD_EDIT`,`This edit proposal is unsupported.`);let n=new Map,r=new Map,i=e=>{if(!r.has(e)){let t=`media-`+crypto.randomUUID();r.set(e,t),n.set(t,e)}return r.get(e)},a={panels:e.map(e=>({...rn(e,nn),elements:e.elements.map(e=>{let t=rn(e,tn);for(let e of[`src`,`assetId`])t[e]!==void 0&&(t[e]=i(t[e]));return t})})),edits:t.map(e=>{let t=rn(e,[`kind`,`panelId`,`elementId`,`factor`,`size`,`direction`,`x`,`y`,`url`,`descriptor`,`assetId`,`beatMs`,`sourceDurationMs`,`sourceInMs`,`text`,`appearMs`,`emphasis`,`transition`]);return t.kind===`swap`&&(t.url!==void 0&&(N(typeof t.url==`string`&&S(t.url),`BOARD_EDIT`,`Choose supported media for this replacement.`),t.url=i(t.url)),t.assetId!==void 0&&(N(typeof t.assetId==`string`&&t.assetId.length<=1024,`BOARD_EDIT`,`Choose a valid replacement asset.`),t.assetId=i(t.assetId))),t})};return B(a),N(JSON.stringify(a).length<=2e6,`BOARD_EDIT`,`This board edit is too large.`),{input:a,media:n}}let sn=Symbol(`host-element-origin`);function cn(e){let t=structuredClone(e.panels),n=[],r=[];t.forEach(e=>e.elements.forEach((e,t)=>{e[sn]=t}));for(let i of e.edits){let e=!1;t=t.map(t=>{if(i.panelId&&i.panelId!==t.panelId)return t;let n=e=>!i.elementId||i.elementId===e.id;if(i.kind===`transition`){let n=String(i.transition||``).trim();return!n||n===t.transitionIn?t:(e=!0,{...t,transitionIn:n})}if(i.kind===`remove`){let r=t.elements.filter(e=>!n(e));return r.length===t.elements.length?t:(e=!0,{...t,elements:r})}if(i.kind===`addText`){let n=String(i.text||``).slice(0,80);if(!n)return t;e=!0;let r=i.x!=null&&i.y!=null,a={id:i.elementId||`${t.panelId}t${t.elements.length+1}`,kind:`text`,text:n,appearMs:Math.max(0,Math.min(Number(i.appearMs)||0,t.durationMs)),leaveMs:null,pos:r?{x:Number(i.x),y:Number(i.y)}:null,pinned:r,size:i.emphasis===`primary`?.085:.06,font:`Hanken Grotesk`,color:`#111111`,weight:800,anim:{type:`pop`,perWord:!1,speedMs:180},sfx:`auto`};return{...t,elements:[...t.elements,a].sort((e,t)=>e.appearMs-t.appearMs)}}if(i.kind===`spread`){if(t.elements.length<2)return t;let n=Math.max(0,t.durationMs-200),r=Math.max(450,n/t.elements.length),i=[...t.elements].sort((e,t)=>e.appearMs-t.appearMs),a=!1,o=i.map((e,t)=>{let i=Math.round(Math.min(n,t*r));return i===e.appearMs?e:(a=!0,{...e,appearMs:i})});return a?(e=!0,{...t,elements:o}):t}let r=!1,a=t.elements.map(e=>{if(!n(e))return e;let a;if(i.kind===`resize`){let t=Number(i.factor)||(i.direction===`smaller`?.7:1.4),n=i.size==null?(e.size??.3)*t:i.size,r=Math.max(.06,Math.min(.9,Number(n)||.06));if(r===e.size)return e;a={size:r}}else if(i.kind===`move`)a={pos:{x:Number(i.x)||0,y:Number(i.y)||0},pinned:!0};else if(i.kind===`swap`){if(!i.url)return e;a={src:i.url,...i.descriptor?{descriptor:i.descriptor}:{},...i.assetId?{assetId:i.assetId}:{}}}else if(i.kind===`retrim`){if(e.kind!==`video`)return e;let n=Math.max(0,Math.max(200,Number(i.beatMs)||t.durationMs-(e.appearMs||0))),r=Math.max(0,Number(Number(i.sourceDurationMs)||(e.sourceOutMs??0))||0),o=Math.max(0,Math.min(Number(i.sourceInMs==null?e.sourceInMs:i.sourceInMs)||0,Math.max(0,r-1)));a=!r||!n?{sourceInMs:0,sourceOutMs:n,loop:!1,muted:!0}:{sourceInMs:o,sourceOutMs:r-o>=n?o+n:r,loop:r-o<n,muted:!0}}else return e;return r=!0,{...e,...a}});return r?(e=!0,{...t,elements:a}):t}),(e?n:r).push(i)}return{panels:t,applied:n,skipped:r}}function ln(e,{input:t,media:n},r){B(r);let i=cn(t);return B(i),N(en(r,i),`BOARD_EDIT`,`The sandbox result does not match the exact requested edit sequence.`),{panels:r.panels.map((r,a)=>{let o=e[a],s=t.panels[a],c=r.elements.map((e,t)=>{let r=i.panels[a].elements[t][sn],c={...e};for(let e of[`src`,`assetId`])c[e]!==void 0&&(N(n.has(c[e]),`BOARD_EDIT`,`The sandbox returned unknown media.`),c[e]=n.get(c[e]));return r===void 0?c:en(s.elements[r],e)?o.elements[r]:{...o.elements[r],...c}});return en(s,r)&&c.every((e,t)=>e===o.elements[t])?o:{...o,...r.transitionIn===void 0?{}:{transitionIn:r.transitionIn},elements:c}}),applied:r.applied}}function un(e){let t=H(e),n=()=>t.actor();return Object.freeze({version:1,actor:n,async apply(e,r,{signal:i}){let a=V({panels:e,edits:r}),o=n(),s=on(e,r);N(o&&!i.aborted,`STALE`,`This board edit was cancelled.`);let c=await t.run($t,{kind:`run`,input:s.input,signal:i,timeoutMs:15e3});return N(!i.aborted&&n()===o&&V({panels:e,edits:r})===a,`STALE`,`The account or reviewed boards changed.`),ln(e,s,c.outputs?.result)}})}let dn={manifest:{schemaVersion:1,sdkVersion:`0.1.0`,id:`stillmade-internal.board-settings`,version:`1.0.0`,name:`Board settings`,description:`Change Board orientation or transitions while preserving its content.`,kind:`task`,runtime:`javascript`,inputs:{doc:{type:`json`},request:{type:`json`}},outputs:{edit:{type:`json`}},permissions:{project:[],network:[],filesystem:[],secrets:[]}},code:`// These edits preserve the existing document representation and media references.\nfunction setBoardSettings(doc, request) {\n if (request.kind === 'aspect') return {...doc, meta: {...doc.meta, aspect: request.value}};\n return {...doc, strip: doc.strip.map(board => board.panelId === request.panelId ? {...board, [request.kind]: request.value} : board)};\n}\n\nreturn {edit:setBoardSettings(input.doc,input.request)};`,tests:[]};async function fn(e,t,{host:n,signal:r,assertCurrent:i=()=>{},transitions:a=[]}){let o=H(n),s=o.actor(),c=JSON.stringify(e),l=structuredClone(t),u=()=>{i(),N(s&&o.actor()===s&&!r?.aborted&&JSON.stringify(e)===c&&V(t)===V(l),`STALE`,`The Board changed before its settings could be applied.`)};u(),N(P(e)&&P(l)&&Array.isArray(e.strip)&&e.strip.length<=2048,`BOARD_SETTINGS`,`Choose a valid Board setting.`);let d=l.kind===`aspect`;N(Object.keys(l).length===(d?2:3)&&(d?[`16:9`,`9:16`,`1:1`].includes(l.value):typeof l.panelId==`string`&&(l.kind===`transitionIn`?[`cut`,`fade`,...a].includes(l.value):l.kind===`transitionMs`&&Number.isInteger(l.value)&&l.value>=100&&l.value<=1500)),`BOARD_SETTINGS`,`Choose a supported Board setting.`),N(e.strip.every(e=>P(e)&&typeof e.panelId==`string`)&&new Set(e.strip.map(e=>e.panelId)).size===e.strip.length,`BOARD_SETTINGS`,`Boards need unique identities.`);let f=e.strip.findIndex(e=>e.panelId===l.panelId);N(d||f>=0&&e.strip[f].type===`canvas`,`BOARD_SETTINGS`,`Choose an existing Board.`);let p={meta:{},strip:e.strip.map(e=>({panelId:e.panelId}))},m=d?{...p,meta:{aspect:l.value}}:{...p,strip:p.strip.map((e,t)=>t===f?{...e,[l.kind]:l.value}:e)},h={doc:p,request:l};B(h),N(JSON.stringify(h).length<=1e6,`BOARD_SETTINGS`,`Board settings exceed their size limit.`);let g=await o.run(dn,{kind:`run`,input:h,signal:r,timeoutMs:15e3});return u(),B(g.outputs?.edit),N(V(g.outputs.edit)===V(m),`BOARD_SETTINGS`,`The sandbox changed unrelated Board settings.`),d?e.meta?.aspect===l.value?e:{...e,meta:{...e.meta,aspect:l.value}}:e.strip[f][l.kind]===l.value?e:{...e,strip:e.strip.map((e,t)=>t===f?{...e,[l.kind]:l.value}:e)}}let pn={manifest:{schemaVersion:1,sdkVersion:`0.1.0`,id:`stillmade-internal.board-sequence`,version:`1.0.0`,name:`Board sequence`,description:`Move or remove a Board and preserve the existing Canvas timing behavior.`,kind:`task`,runtime:`javascript`,inputs:{doc:{type:`json`},request:{type:`json`}},outputs:{edit:{type:`json`}},permissions:{project:[],network:[],filesystem:[],secrets:[]}},code:`// Extracted from the existing Board workspace. Non-Canvas rows keep their\n// placement; only Canvas rows participate in ordering and timing.\nfunction renormalizeBoards(strip) {\n let t=0;\n return (strip||[]).map(p=>{if(p.type!=='canvas')return p;const next={...p,startMs:t};t+=Number(p.durationMs)||0;return next;});\n}\nfunction moveBoard(doc,panelId,dir) {\n const strip=doc?.strip||[],idxs=strip.map((p,i)=>p.type==='canvas'?i:-1).filter(i=>i>=0),pos=strip.findIndex(p=>p.panelId===panelId),among=idxs.indexOf(pos),target=among+dir;\n if(among<0||target<0||target>=idxs.length)return doc;\n const next=strip.slice(),swap=idxs[target];[next[pos],next[swap]]=[next[swap],next[pos]];\n return {...doc,strip:renormalizeBoards(next)};\n}\nfunction removeBoard(doc,panelId) {\n return {...doc,strip:renormalizeBoards((doc?.strip||[]).filter(p=>p.panelId!==panelId))};\n}\n\nreturn {edit:input.request.action===\"move\"?moveBoard(input.doc,input.request.panelId,input.request.direction):removeBoard(input.doc,input.request.panelId)};`,tests:[]};async function mn(e,t,{host:n,signal:r,assertCurrent:i=()=>{}}){let a=H(n),o=a.actor(),s=JSON.stringify(e),c=structuredClone(t),l=()=>{i(),N(o&&a.actor()===o&&!r?.aborted&&JSON.stringify(e)===s&&V(t)===V(c),`STALE`,`The Board changed before its sequence edit could be applied.`)};l(),N(P(e)&&Array.isArray(e.strip)&&e.strip.length<=2048&&P(c)&&[`move`,`remove`].includes(c.action)&&Object.keys(c).length===(c.action===`move`?3:2)&&typeof c.panelId==`string`&&(c.action!==`move`||[-1,1].includes(c.direction)),`BOARD_SEQUENCE`,`Choose a valid Board sequence edit.`);let u=e.strip;N(u.every(e=>P(e)&&typeof e.panelId==`string`)&&new Set(u.map(e=>e.panelId)).size===u.length,`BOARD_SEQUENCE`,`Boards need unique identities.`);let d=u.map((e,t)=>e.type===`canvas`?t:-1).filter(e=>e>=0),f=d.findIndex(e=>u[e].panelId===c.panelId);N(f>=0&&(c.action!==`remove`||d.length>1)&&d.every(e=>Number.isFinite(u[e].startMs)&&u[e].startMs>=0&&Number.isFinite(u[e].durationMs)&&u[e].durationMs>0),`BOARD_SEQUENCE`,`Keep at least one valid Board.`);let p=u.map((e,t)=>({origin:t,panelId:e.panelId,type:e.type,...e.type===`canvas`?{startMs:e.startMs,durationMs:e.durationMs}:{}})),m={doc:{strip:p},request:c};B(m),N(JSON.stringify(m).length<=1e6,`BOARD_SEQUENCE`,`Board sequence exceeds its size limit.`);let h=p.map((e,t)=>t),g=f+c.direction,_=c.action===`move`&&g>=0&&g<d.length;_&&([h[d[f]],h[d[g]]]=[h[d[g]],h[d[f]]]),c.action===`remove`&&h.splice(d[f],1);let v=0,y=h.map(e=>{let t=p[e];if(t.type!==`canvas`||c.action===`move`&&!_)return t;let n={...t,startMs:v};return v+=t.durationMs,N(Number.isFinite(v)&&v<=2**53-1,`BOARD_SEQUENCE`,`Board timing exceeds its limit.`),n}),b=await a.run(pn,{kind:`run`,input:m,signal:r,timeoutMs:15e3});return l(),B(b.outputs?.edit),N(V(b.outputs.edit)===V({strip:y}),`BOARD_SEQUENCE`,`The sandbox changed unrelated Board content or timing.`),V(y)===V(p)?e:{...e,strip:y.map(e=>{let t=u[e.origin];return e.type!==`canvas`||e.startMs===t.startMs?t:{...t,startMs:e.startMs}})}}function hn({doc:e,canEdit:t,busy:n,phase:r,lease:i,host:a,transitions:o,onAspectChange:s,setPending:c,page:l=0,setPage:u,onFocus:d,activeId:f,elementPage:p=0,setElementPage:m,canUndo:h=!1,canRedo:g=!1,onHistory:_}){let v=(e?.strip||[]).filter(e=>e.type===`canvas`),y=Math.max(1,Math.ceil(v.length/30)),b=Math.min(Math.max(0,l),y-1),x=v.slice(b*30,(b+1)*30),S={type:`string`,enum:x.map(e=>e.panelId),description:`Existing board IDs in order, page ${b+1} of ${y}. ${v.length} boards total.`,oneOf:x.map((e,t)=>({const:e.panelId,title:`Board ${b*30+t+1}`,description:`Duration ${e.durationMs} ms; transition ${e.transitionIn||`cut`}; ${e.elements?.length||0} elements.`}))},C=v.find(e=>e.panelId===f)||v[0],w=C?.elements||[],T=Math.max(1,Math.ceil(w.length/30)),E=Math.min(Math.max(0,p),T-1),D=w.slice(E*30,(E+1)*30),O={type:`string`,enum:D.map(e=>e.id),description:`Elements on active board ${C?.panelId||`none`}, page ${E+1} of ${T}.`,oneOf:D.map((e,t)=>({const:e.id,title:`${e.kind} ${E*30+t+1}`,description:`Appears at ${e.appearMs||0} ms. Text ${typeof e.text==`string`&&e.text.length?`filled`:`empty`}.`}))},k=e=>D.some(t=>t.id===e.elementId),A={type:`number`,minimum:0,maximum:1,description:`Normalized coordinate from 0 to 1; 0.5 is the center.`},j=(e,t,n)=>typeof e==`number`&&Number.isFinite(e)&&e>=t&&e<=n,M=()=>!!e&&!n&&!i.current,N=(e,t,n,r,i)=>({id:e,label:t,effect:`navigate`,available:M,parameters:{type:`object`,additionalProperties:!1,required:Object.keys(n),properties:n},parse:e=>{if(!M()||!e||Array.isArray(e)||Object.keys(e).length!==Object.keys(n).length||Object.keys(e).some(e=>!Object.hasOwn(n,e))||!r(e))throw Error(`Choose an available board or discovery page.`);return e},run:(e,{signal:n}={})=>{if(!M()||n?.aborted)throw Error(`Board navigation stopped.`);return i(e),{status:`navigation-requested`,message:`${t} requested.`}}}),P=()=>!!e&&t&&!n&&!i.current,F=(e,t,n,l,u)=>({id:e,label:t,effect:`edit`,available:P,parameters:{type:`object`,additionalProperties:!1,required:Object.keys(n),properties:n},parse:e=>{if(!P()||!e||Array.isArray(e)||Object.keys(e).length!==Object.keys(n).length||Object.keys(e).some(e=>!Object.hasOwn(n,e))||!l(e))throw Error(`Choose an available Board setting while the workspace is idle.`);return e},run:async(e,{signal:n}={})=>{if(!P()||n?.aborted)throw Error(`The Board edit is no longer available.`);c(!0);let l,f=()=>{l&&i.current===l&&r.cancel()};try{let c=r.run(`assistant`,async({doc:n,signal:r,check:i,commitAndWait:c})=>{let l=u(e),f={host:a,signal:r,assertCurrent:i,transitions:o},p;if(l.elementEdit){let e=n.strip.find(e=>e.panelId===C?.panelId&&e.type===`canvas`);if(!e)throw Error(`The selected board changed.`);let t={...l.elementEdit,panelId:e.panelId};t.kind===`addText`&&(t.elementId=`agent-text-${crypto.randomUUID()}`);let o=await un(a).apply([e],[t],{signal:r});i(),p=o.applied.length?{...n,strip:n.strip.map(t=>t===e?o.panels[0]:t)}:n}else p=l.kind===`duration`?await Qt(n,l.value,f):l.action?await mn(n,l,f):await fn(n,l,f);return i(),p!==n&&await c(p),i(),l.kind===`aspect`&&s?.(l.value),l.action===`remove`&&C?.panelId===l.panelId&&d(p.strip.find(e=>e.type===`canvas`)?.panelId),{status:`applied-locally`,saved:!1,message:`${t}: accepted in White Board Motion. No media was generated.`}});l=i.current,n?.addEventListener(`abort`,f,{once:!0}),n?.aborted&&f();let p=await c;if(!p)throw Error(`Another Board edit is active. Inspect the workspace before trying again.`);return p}finally{n?.removeEventListener(`abort`,f),c(!1)}}}),I=e=>({id:`${e}_board_edit`,label:`${e===`undo`?`Undo`:`Redo`} my Board change`,effect:`edit`,available:()=>P()&&(e===`undo`?h:g),parameters:{type:`object`,additionalProperties:!1,properties:{},description:`Use the editor history for your last change; shared history preserves teammate edits.`},parse:t=>{if(!P()||!(e===`undo`?h:g)||!t||Array.isArray(t)||Object.keys(t).length)throw Error(`This history action is unavailable.`);return{}},run:(t,{signal:n}={})=>_(e,{signal:n})});return[I(`undo`),I(`redo`),N(`browse_boards`,`Browse Board pages`,{page:{type:`integer`,minimum:1,maximum:y,description:`Current page ${b+1}. Each page contains up to thirty boards.`}},e=>Number.isInteger(e.page)&&e.page>=1&&e.page<=y,e=>u(e.page-1)),N(`browse_board_elements`,`Browse Board elements`,{page:{type:`integer`,minimum:1,maximum:T,description:`Active board ${C?.panelId||`none`}; ${w.length} elements; current page ${E+1}.`}},e=>Number.isInteger(e.page)&&e.page>=1&&e.page<=T,e=>m(e.page-1)),N(`focus_board`,`Open Board`,{panelId:S},e=>x.some(t=>t.panelId===e.panelId),e=>d(e.panelId)),F(`remove_board_element`,`Remove element from active Board`,{elementId:O},k,e=>({elementEdit:{kind:`remove`,elementId:e.elementId}})),F(`remove_board`,`Remove Board and its contents`,{panelId:S},e=>v.length>1&&x.some(t=>t.panelId===e.panelId),e=>({action:`remove`,panelId:e.panelId})),F(`set_board_total_duration`,`Change total Board duration`,{durationMs:{type:`integer`,minimum:Math.max(1e3,(v.at(-1)?.startMs||0)+500),maximum:2**53-1,description:`Total timeline length in milliseconds. Adjusts the final board. Shortening removes elements that begin after its new end and clears later exit times; use Undo to reverse.`}},e=>!!v.length&&Number.isSafeInteger(e.durationMs)&&e.durationMs>=Math.max(1e3,(v.at(-1)?.startMs||0)+500),e=>({kind:`duration`,value:e.durationMs})),F(`move_board_element`,`Move Board element`,{elementId:O,x:A,y:A},e=>k(e)&&j(e.x,0,1)&&j(e.y,0,1),e=>({elementEdit:{kind:`move`,...e}})),F(`resize_board_element`,`Resize Board element`,{elementId:O,size:{type:`number`,minimum:.06,maximum:.9,description:`Relative element size.`}},e=>k(e)&&j(e.size,.06,.9),e=>({elementEdit:{kind:`resize`,...e}})),F(`add_board_text`,`Add text to active Board`,{text:{type:`string`,minLength:1,maxLength:80},appearMs:{type:`integer`,minimum:0,maximum:Math.max(0,C?.durationMs||0)},x:A,y:A},e=>!!C&&typeof e.text==`string`&&e.text.trim().length>0&&e.text.length<=80&&Number.isInteger(e.appearMs)&&j(e.appearMs,0,C.durationMs)&&j(e.x,0,1)&&j(e.y,0,1),e=>({elementEdit:{kind:`addText`,...e}})),F(`spread_board_elements`,`Space active Board element appearances`,{},()=>!!C&&w.length>1,()=>({elementEdit:{kind:`spread`}})),F(`set_board_aspect`,`Change Board layout`,{aspect:{type:`string`,enum:[`16:9`,`9:16`,`1:1`]}},e=>[`16:9`,`9:16`,`1:1`].includes(e.aspect),e=>({kind:`aspect`,value:e.aspect})),F(`set_board_transition`,`Change Board transition`,{panelId:S,transition:{type:`string`,enum:[...new Set([`cut`,`fade`,...o])]}},e=>x.some(t=>t.panelId===e.panelId)&&[`cut`,`fade`,...o].includes(e.transition),e=>({kind:`transitionIn`,panelId:e.panelId,value:e.transition})),F(`set_board_transition_duration`,`Change Board transition duration`,{panelId:S,durationMs:{type:`integer`,minimum:100,maximum:1500,description:`Transition duration in milliseconds.`}},e=>x.some(t=>t.panelId===e.panelId)&&Number.isInteger(e.durationMs)&&e.durationMs>=100&&e.durationMs<=1500,e=>({kind:`transitionMs`,panelId:e.panelId,value:e.durationMs})),F(`move_board`,`Move Board`,{panelId:S,direction:{type:`integer`,enum:[-1,1],description:`-1 moves earlier; 1 moves later.`}},e=>x.some(t=>t.panelId===e.panelId)&&[-1,1].includes(e.direction),e=>({action:`move`,panelId:e.panelId,direction:e.direction}))]}let gn=()=>Object.assign(Error(`Canvas build cancelled or its source changed.`),{name:`AbortError`});function _n({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 gn();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 gn()},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 gn()},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 gn();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?gn():e}finally{g.current===d&&(o.current===d&&(o.current=null),g.current=null,y.current&&f(!1))}},cancel:b,canceling:d}}let vn={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:[]},yn=(e,t)=>V(e)===V(t),bn=[`id`,`kind`,`pinned`,`appearMs`,`leaveMs`,`pos`,`box`,`size`,`tilt`,`weight`],xn=[`pos`,`box`,`size`,`tilt`,`weight`],Sn=new Set([`kind`,`src`,`query`,`source`,`pose`,`cutout`,`text`,`font`,`color`,`anim`,`wordTimes`,`sfx`,`entrance`,`muted`,`loop`,`speed`,`trimStartSec`,`pinned`,`appearMs`,`leaveMs`,...xn]);function Cn(e,t,n){let r=e.strip.find(e=>e.panelId===t);N(r?.type===`canvas`&&Array.isArray(r.elements)&&P(n)&&[`image`,`video`,`text`].includes(n.kind)&&Object.keys(n).every(e=>Sn.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 bn)if(e[t]!==void 0){let r=e[t];n[t]=t===`pos`&&P(r)?{x:r.x,y:r.y}:t===`box`&&P(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)}`;N(!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))bn.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 wn(e){let t=e.doc.strip[0],n=[...t.elements,{id:e.newId,...e.element}],r=t.template,i=ut(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=pt({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=ut(r);if(s){let e=ft(n,s,{aspect:o}),t=ze({...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=Be(a,{aspect:o}));return{...e.doc,strip:[a]}}function Tn(e,{panel:t,input:n,captured:r},i){let a=wn(n);B(a),B(i),N(yn(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 xn){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&&!yn(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 En(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(),N(c&&s.actor()===c&&!i?.aborted&&JSON.stringify({doc:e,element:n})===l,`STALE`,`The account or canvas addition changed.`)};u();let d=Cn(e,t,n),f=await s.run(vn,{kind:`run`,input:d.input,signal:i,timeoutMs:15e3});u();let p=Tn(e,d,f.outputs?.edit),m=p===e?e:o(p);return u(),m}function Dn({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;N(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 En(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}}var On=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})),q=s(((e,t)=>{t.exports=On()}))();function kn(e,t){let n=new Map;for(let r of e?.strip||[])if(r.type===`canvas`)for(let e of r.elements||[]){if(e.kind!==`image`&&e.kind!==`video`||!e.src)continue;let i=n.get(e.src),a=r.panelId===t;if(i){a&&(i.on=!0);continue}n.set(e.src,{src:e.src,kind:e.kind,query:e.query||``,source:e.source||`stock`,size:e.size,muted:e.muted,loop:e.loop,speed:e.speed,trimStartSec:e.trimStartSec,on:a})}return[...n.values()]}function An({doc:e,active:t,onDocChange:n,projectId:r,canEdit:i,host:a}){let o=(0,v.useRef)(null),s=Dn({doc:e,projectId:r,panelId:t?.panelId,canEdit:i,onDocChange:n,validateDocument:Zt,editLease:o,host:a}),c=kn(e,t?.panelId);if(!t||c.length===0)return null;let l=e=>{let n=t.elements||[],r=n.reduce((e,t)=>Math.max(e,t.appearMs||0),0),i=Math.max(0,Math.min(r+500,(t.durationMs||6e3)-400)),a=n.length%5,o={x:Math.min(.88,.42+a*.05),y:Math.min(.86,.46+a*.05)},c={kind:e.kind,src:e.src,query:e.query,source:e.source,appearMs:i,leaveMs:null,pos:o,size:e.size==null?e.kind===`video`?.34:.28:e.size,tilt:0,entrance:t.handoff?.arrive===`fade`?`fade`:`pop`,sfx:`auto`,pinned:!!t.autoArrange};e.kind===`video`&&Object.assign(c,{muted:e.muted!==!1,loop:e.loop!==!1,speed:Number(e.speed)>0?e.speed:1,trimStartSec:Number(e.trimStartSec)||0}),s.change(c)};return(0,q.jsxs)(`div`,{style:{border:`1px solid var(--border)`,borderRadius:10,padding:10,display:`flex`,flexDirection:`column`,gap:8,background:`var(--bg-secondary)`},children:[(0,q.jsxs)(`div`,{style:{display:`flex`,alignItems:`baseline`,gap:8},children:[(0,q.jsx)(`strong`,{style:{fontSize:12.5,color:`var(--text-primary)`},children:`Media`}),(0,q.jsxs)(`span`,{style:{fontSize:11,color:`var(--text-secondary)`},children:[c.length,` item`,c.length===1?``:`s`,` · click to drop a copy onto this canvas`]})]}),(0,q.jsx)(`div`,{style:{display:`flex`,gap:8,overflowX:`auto`,paddingBottom:2,WebkitOverflowScrolling:`touch`},children:c.map(e=>(0,q.jsxs)(`button`,{type:`button`,disabled:!i||!!s.pending,onClick:()=>l(e),title:`${e.query||e.kind} — add to this canvas`,style:{position:`relative`,flex:`0 0 auto`,width:88,padding:0,border:`1px solid ${e.on?`var(--accent)`:`var(--border)`}`,borderRadius:8,overflow:`hidden`,background:`var(--bg-tertiary)`,cursor:`pointer`},children:[e.kind===`video`?(0,q.jsx)(`video`,{src:e.src,muted:!0,playsInline:!0,preload:`metadata`,style:{width:`100%`,height:60,objectFit:`cover`,display:`block`,pointerEvents:`none`}}):(0,q.jsx)(`img`,{src:e.src,alt:``,style:{width:`100%`,height:60,objectFit:`cover`,display:`block`}}),e.kind===`video`&&(0,q.jsx)(`span`,{style:{position:`absolute`,top:3,right:4,fontSize:8.5,background:`rgba(0,0,0,0.6)`,color:`#fff`,borderRadius:3,padding:`0 3px`,letterSpacing:.3},children:`VIDEO`}),(0,q.jsx)(`span`,{style:{display:`block`,fontSize:9.5,color:`var(--text-secondary)`,padding:`3px 5px`,whiteSpace:`nowrap`,overflow:`hidden`,textOverflow:`ellipsis`},children:e.query||(e.on?`on this canvas`:e.kind)})]},e.src))}),s.error&&(0,q.jsx)(`div`,{role:`alert`,style:{fontSize:12,color:`var(--text-secondary)`},children:s.error})]})}var jn=g();let Mn=e=>typeof e==`function`||!!e&&typeof e==`object`&&typeof e.$$typeof==`symbol`;function Nn(e){return N(e?.version===1&&[`useLiveEditor`,`setCanvasEditorDuration`,`addCanvasElement`,`getAllAssets`].every(t=>typeof e[t]==`function`)&&[`LiveEditorBadge`,`CanvasEditorCore`,`CanvasChatPanel`,`HostSection`,`ItemPreview`].every(t=>Mn(e[t]))&&Array.isArray(e.TRANSITIONS)&&e.TRANSITIONS.every(e=>typeof e==`string`)&&typeof e.ui?.confirm==`function`&&[`error`,`info`].every(t=>typeof e.toast?.[t]==`function`),`HOST_SERVICES`,`White Board Motion requires version 1 of its editor host dependencies.`),e}function Pn(e){return N(e?.version===1&&typeof e.apply==`function`,`HOST_SERVICES`,`Presenter placement requires its version 1 sandbox broker.`),e}let Fn=()=>Object.assign(Error(`Presenter setup was cancelled or its project changed.`),{name:`AbortError`});function In(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 Fn();let n;try{n=JSON.stringify(t.doc)}catch{throw Fn()}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 Fn()}),l.check=()=>{if(!l.current())throw Fn()},l.finish=()=>{r.current===l&&(r.current=null,s.current?.())},r.current=l,l},cancel:l,current:()=>r.current}}function Ln(e){return N((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 Rn(e){return N([`loadPanelDoc`,`addCanvasElement`,`removeCanvasElement`].every(t=>typeof e?.[t]==`function`),`HOST_SERVICES`,`Presenter requires document model operations.`),e}let zn=[`point-left`,`point-right`,`point-up`,`point-down`,`present`,`explain`,`think`,`surprised`,`wave`,`idle`,`count`,`shrug`,`celebrate`,`write`,`thumbs-up`,`welcome`];function Bn(e){return String(e||``).replace(/-/g,` `).trim()}function Vn(e){return String(e||``).toLowerCase().replace(/[^a-z0-9]+/g,`-`).replace(/^-+|-+$/g,``).slice(0,40)}function Hn(e){let{addCanvasElement:t,removeCanvasElement:n}=Rn(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=Vn(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=>[Vn(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(Vn(n.label))){t=s.get(Vn(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 Un(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 Wn(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 Gn({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||Bn(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 Kn({characterDef:e=``,style:t=``,poses:n=[]}={}){return Wn(n).map((n,r)=>({sheetIndex:r,poses:n,prompt:Gn({characterDef:e,style:t,poses:n,sheetIndex:r})}))}async function qn({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||Un(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:Vn(r.label),description:r.description||``,url:p,vectorUrl:m,w:d||0,h:f||0})}return c}function Jn({name:e,definition:t=``,style:n=``,poses:r=[]}={}){let i=Yn(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 Yn(e=[]){let t=new Set,n=[];for(let r of e||[]){let e=Vn(r?.label);e&&!t.has(e)&&(t.add(e),n.push({...r,label:e}))}return n}function Xn(e){let t=Array.isArray(e?.poses)?e.poses:Array.isArray(e)?e:[];return[...new Set(t.map(e=>Vn(e?.label)).filter(Boolean))]}function Zn(e){let t=Array.isArray(e?.poses)?e.poses:Array.isArray(e?.images)?e.images:[];return new Set(t.map(e=>Vn(e?.label)).filter(Boolean))}function Qn(e,t){let n=Zn(e);return(Array.isArray(t)?t:Xn(t)).filter(e=>!n.has(Vn(e)))}function $n(e,t=[]){let n=Yn([...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 er(e,t=16){let n=Yn(e).map(e=>({label:e.label,description:e.description||Bn(e.label),atWord:e.atWord??null})),r=new Set(n.map(e=>e.label));for(let e of zn){if(n.length>=t)break;r.has(e)||(r.add(e),n.push({label:e,description:`presenter ${Bn(e)}`,atWord:null}))}return n.slice(0,Math.max(t,n.length))}async function tr({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 qn({sheetUrl:o[t],poses:e[t].poses},i);s.push(...n)}return s}async function nr({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=er(l?.poses||[]),d=i||l?.character?.definition||``,f=await tr({sheets:Kn({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=Jn({name:n||l?.character?.name||`Host`,definition:d,style:r,poses:f});return c?.({phase:`save`}),(s?await s(m):m)||m}async function rr({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=Qn(e,Xn(s));if(!c.length)return{character:e,generated:[],ready:!0};let l=new Map((s?.poses||[]).map(e=>[Vn(e.label),e])),u=c.map(e=>{let t=l.get(e);return{label:e,description:t?.description||``,atWord:t?.atWord??null}}),d=await tr({sheets:Kn({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=$n(e,d);return o?.({phase:`save`}),{character:(a?await a(p):p)||p,generated:d,ready:!0}}function ir(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}=Ln(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 ar={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}},or=Object.freeze([]);function sr({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=or,onHostReady:d}){let{getLibraryItems:f,ui:p}=Ln(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=In(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(ir(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()}}},D=()=>E(e=>nr({content:l,words:u,name:y.trim()||void 0,style:x.trim()||void 0,definition:C.trim()||void 0},e)),O=e=>E(async t=>(await rr({character:e,content:l,words:u},t)).character),k=()=>E(async e=>(await rr({character:c,content:l,words:u},e)).character),A=f(`character`)||[],j=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,q.jsxs)(`div`,{style:ar.wrap,children:[(0,q.jsxs)(`div`,{style:ar.row,children:[(0,q.jsx)(`span`,{style:ar.title,children:`Presenter / Host`}),(0,q.jsx)(`span`,{style:ar.beta,children:`BETA`}),(0,q.jsx)(`button`,{type:`button`,role:`switch`,\"aria-checked\":o,\"aria-label\":`Enable auto presenter/host`,style:ar.switch(o),onClick:()=>s?.(!o),disabled:!!m||t||!a,children:(0,q.jsx)(`span`,{style:ar.knob(o)})})]}),(0,q.jsx)(`div`,{style:ar.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,q.jsx)(`div`,{style:ar.sub,children:`This project is read-only. Presenter setup is unavailable.`}),o&&(0,q.jsx)(`div`,{style:{marginTop:9},children:j?(0,q.jsxs)(`div`,{style:{fontSize:11.5},children:[j,` `,(0,q.jsx)(`button`,{type:`button`,style:ar.btn,onClick:T.cancel,children:`Cancel setup`}),(0,q.jsx)(`div`,{style:ar.sub,children:`Stops later steps. Requests already sent may still be charged.`})]}):c?(0,q.jsxs)(`div`,{style:ar.row,children:[(0,q.jsxs)(`span`,{style:{fontSize:11.5,color:`var(--text-primary)`},children:[`Active host: `,(0,q.jsx)(`strong`,{children:c.name||`Host`}),` · `,(c.poses||c.images||[]).length,` poses`]}),(0,q.jsx)(`button`,{type:`button`,style:{...ar.btn,marginLeft:`auto`},onClick:k,title:`Generate any poses the content now needs that this host lacks`,children:`Add poses`}),(0,q.jsx)(`button`,{type:`button`,style:ar.btn,onClick:D,title:`Regenerate the whole host from scratch`,children:`Regenerate`})]}):g?(0,q.jsxs)(`div`,{children:[(0,q.jsx)(`div`,{style:{fontSize:11,color:`var(--text-secondary)`,marginBottom:6},children:`Pick a character to use as the host (missing poses are generated):`}),A.length===0&&(0,q.jsx)(`div`,{style:{fontSize:11,color:`var(--text-muted)`},children:`No saved characters yet — create one instead.`}),(0,q.jsx)(`div`,{style:{maxHeight:160,overflowY:`auto`,display:`flex`,flexDirection:`column`,gap:2},children:A.map(e=>(0,q.jsxs)(`div`,{style:ar.pickItem,onClick:()=>O(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,q.jsx)(`img`,{src:e.selectedImageUrl||e.imageUrl,alt:``,style:ar.thumb}),(0,q.jsx)(`span`,{style:{fontSize:12,color:`var(--text-primary)`},children:e.name||`Character`})]},e.id))}),(0,q.jsx)(`button`,{type:`button`,style:{...ar.btn,marginTop:6},onClick:()=>_(!1),children:`Cancel`})]}):(0,q.jsxs)(`div`,{style:{display:`flex`,flexDirection:`column`,gap:6},children:[(0,q.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,q.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,q.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,q.jsxs)(`div`,{style:{display:`flex`,gap:8},children:[(0,q.jsx)(`button`,{type:`button`,style:{...ar.btn,background:`var(--accent)`,color:`var(--accent-contrast, #0A0A0A)`,borderColor:`var(--accent)`},onClick:D,children:C.trim()||x.trim()?`Create my host`:`Create one for me`}),(0,q.jsx)(`button`,{type:`button`,style:ar.btn,onClick:()=>_(!0),children:`Use a saved character`})]})]})})]})}let cr=Object.freeze([]);function lr({hostServices:e,placementBroker:t,projectId:n,canEdit:r=!0,doc:i,onDocChange:a,voiceover:o,autoEnable:s=!1}){let{loadPanelDoc:c,toast:l}=Ln(e),{placePosesOnDoc:u,clearPresenterPoses:d}=Hn(e),f=i?.meta?.host||{},p=o?.words||i?.audio?.words||cr,m=t||e.placementBroker;m&&Pn(m);let[h,g]=(0,v.useState)(!1),_=In(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,q.jsxs)(q.Fragment,{children:[h&&(0,q.jsxs)(`div`,{role:`status`,style:{fontSize:12},children:[`Updating presenter placement… `,(0,q.jsx)(`button`,{type:`button`,className:`btn btn-secondary`,onClick:_.cancel,children:`Cancel placement`})]}),(0,q.jsx)(sr,{externalBusy:h,projectId:n,doc:i,canEdit:r,hostServices:e,enabled:!!f.enabled,onToggle:x,activeHost:C,content:y,words:p,onHostReady:S})]})}let ur=v.createContext(null),dr=v.createContext(null),fr=v.createContext(null),pr=()=>v.useContext(fr),mr=e=>({fontSize:15,lineHeight:1,width:34,height:28,padding:0,display:`flex`,alignItems:`center`,justifyContent:`center`,background:`var(--bg-secondary)`,border:`none`,color:`var(--text-primary)`,cursor:e?`pointer`:`default`,opacity:e?1:.35,fontFamily:`var(--font)`}),hr={fontSize:10,lineHeight:1,minWidth:26,height:28,padding:`0 6px`,borderTop:0,borderBottom:0,borderLeft:`1px solid var(--border)`,borderRight:`1px solid var(--border)`,background:`var(--bg-tertiary)`,color:`var(--text-muted)`,cursor:`pointer`,fontFamily:`var(--font)`,whiteSpace:`nowrap`},gr={background:`var(--accent-dim, rgba(247,240,219,0.14))`,color:`var(--accent)`,fontWeight:700},_r={position:`fixed`,transform:`translateX(-50%)`,zIndex:5001,width:250,padding:6,background:`var(--bg-elevated)`,border:`1px solid var(--border-strong, var(--border))`,borderRadius:10,boxShadow:`0 12px 36px rgba(0,0,0,0.45)`},vr={fontSize:11,fontWeight:700,color:`var(--text-secondary)`,padding:`4px 8px 6px`},yr={display:`flex`,alignItems:`center`,gap:9,width:`100%`,textAlign:`left`,fontSize:12,padding:`5px 8px`,borderRadius:6,border:`none`,background:`none`,color:`var(--text-primary)`,cursor:`pointer`,fontFamily:`var(--font)`},br={width:46,height:28,flexShrink:0,borderRadius:4,overflow:`hidden`,border:`1px solid var(--border)`,display:`block`},xr={background:`var(--accent-dim, rgba(247,240,219,0.14))`,color:`var(--accent)`,fontWeight:700},Sr={display:`flex`,alignItems:`center`,gap:8,fontSize:11,color:`var(--text-secondary)`,padding:`8px 8px 4px`,borderTop:`1px solid var(--border)`,marginTop:4};function Cr({valueMs:e,onCommit:t,disabled:n}){let[r,i]=(0,v.useState)(String((e/1e3).toFixed(1)));return v.useEffect(()=>{i(String((e/1e3).toFixed(1)))},[e]),(0,q.jsxs)(`label`,{style:{display:`flex`,gap:5,alignItems:`center`,fontSize:11.5,color:`var(--text-secondary)`},children:[`Length`,(0,q.jsx)(`input`,{type:`number`,disabled:n,min:`1`,step:`0.5`,value:r,onChange:e=>i(e.target.value),onBlur:()=>{let n=Math.round(Number(r)*1e3);if(!Number.isFinite(n)||n<=0){i(String((e/1e3).toFixed(1)));return}t(Math.max(1e3,n))},style:{width:64,fontSize:12,padding:`4px 6px`,background:`var(--bg-tertiary)`,border:`1px solid var(--border)`,borderRadius:6,color:`var(--text-primary)`}}),`s`]})}function wr({doc:e,onDocChange:t,voiceover:n,projectId:r,canEdit:i}){let{getAllAssets:a,CanvasChatPanel:o,HostSection:s}=pr(),c=v.useContext(ur),l=v.useContext(dr),[u,d]=(0,v.useState)(!1),f=n?.words?.length?n.words:e?.audio?.words||[],p=v.useMemo(()=>u?{user:[],library:(a()||[]).filter(e=>!e.deleted&&(e.type===`image`||e.type===`video`)&&e.url).slice(0,60).map(e=>({id:e.id||e.url,url:e.url,type:e.type,prompt:e.prompt||``,descriptor:e.descriptor||``})),stock:[]}:{user:[],library:[],stock:[]},[u]);return(0,q.jsxs)(`div`,{style:{display:`flex`,flexDirection:`column`,gap:8},children:[(0,q.jsxs)(`button`,{type:`button`,onClick:()=>d(e=>!e),style:{alignSelf:`flex-start`,background:`none`,borderWidth:0,color:`var(--text-secondary)`,fontSize:12.5,fontWeight:600,cursor:`pointer`,padding:`2px 0`,fontFamily:`var(--font)`},children:[u?`▾`:`▸`,` Build from my assets (chat)`]}),u&&(0,q.jsx)(o,{projectId:r,canEdit:i,doc:e,onDocChange:t,words:f,availableAssets:p,hostSlot:c?(0,q.jsx)(lr,{placementBroker:l,projectId:r,canEdit:i,hostServices:c,doc:e,onDocChange:t,voiceover:n}):(0,q.jsx)(s,{projectId:r,canEdit:i,doc:e,onDocChange:t,voiceover:n})})]})}function Tr(e,t){let n=e?.transitionIn;return!n||n===`cut`?`Cut`:n===`fade`?`Fade`:t.includes(n)?n:`Cut`}function Er({board:e,valueMs:t,disabled:n,onCommit:r}){let[i,a]=(0,v.useState)(t),o=(0,v.useRef)(!1);(0,v.useEffect)(()=>{a(t),o.current=!1},[e,t,n]);let s=()=>{!n&&o.current&&(o.current=!1,i!==t&&r(i))};return(0,q.jsxs)(q.Fragment,{children:[(0,q.jsx)(`input`,{\"aria-label\":`Transition duration`,type:`range`,disabled:n,min:`0.1`,max:`1.5`,step:`0.05`,value:i/1e3,onChange:e=>{o.current=!0,a(Math.round(Number(e.target.value)*1e3))},onPointerUp:s,onKeyUp:s,onBlur:s,onPointerCancel:()=>{o.current=!1,a(t)},style:{flex:1}}),(0,q.jsxs)(`span`,{style:{minWidth:34,textAlign:`right`},children:[(i/1e3).toFixed(2),`s`]})]})}function Dr({board:e,onSet:t,disabled:n}){let{TRANSITIONS:r,ItemPreview:i}=pr(),[a,o]=(0,v.useState)(!1),[s,c]=(0,v.useState)({left:0,top:0}),l=(0,v.useRef)(null),u=Tr(e,r),d=u===`Cut`,f=Number(e?.transitionMs)>0?Number(e.transitionMs):500;return(0,q.jsxs)(q.Fragment,{children:[(0,q.jsx)(`button`,{ref:l,type:`button`,disabled:n,onClick:()=>{let e=l.current?.getBoundingClientRect();e&&c({left:e.left+e.width/2,top:e.bottom+6}),o(!0)},title:d?`No transition — click to add one`:`${u} transition — click to change`,style:{...hr,...d?{}:gr},children:d?`—`:u}),a&&(0,jn.createPortal)((0,q.jsxs)(q.Fragment,{children:[(0,q.jsx)(`div`,{style:{position:`fixed`,inset:0,zIndex:5e3},onClick:()=>o(!1)}),(0,q.jsxs)(`div`,{style:{..._r,left:s.left,top:s.top},children:[(0,q.jsx)(`div`,{style:vr,children:`Transition into this board`}),(0,q.jsxs)(`div`,{style:{maxHeight:260,overflowY:`auto`},children:[(0,q.jsxs)(`button`,{type:`button`,disabled:n,style:{...yr,...d?xr:{}},onClick:()=>{t({transitionIn:`cut`}),o(!1)},children:[(0,q.jsx)(`span`,{style:{...br,background:`var(--bg-tertiary)`}}),`None (hard cut)`]}),r.filter(e=>e!==`Cut`).map(e=>(0,q.jsxs)(`button`,{type:`button`,disabled:n,style:{...yr,...e===u?xr:{}},onClick:()=>{t({transitionIn:e}),o(!1)},children:[(0,q.jsx)(`span`,{style:br,children:a?(0,q.jsx)(i,{kind:`transition`,item:{type:e},inView:!0,style:{width:`100%`,height:`100%`}}):null}),e]},e))]}),!d&&(0,q.jsxs)(`div`,{style:Sr,children:[(0,q.jsx)(`span`,{children:`Duration`}),(0,q.jsx)(Er,{board:e,valueMs:f,disabled:n,onCommit:e=>t({transitionMs:e})})]})]})]}),document.body)]})}function Or({editHost:e,projectId:t,doc:n,onDocChange:r,aspect:i=`16:9`,onAspectChange:a,onContinue:o,onExport:s,voiceover:c=null}){let{useLiveEditor:l,LiveEditorBadge:u,CanvasEditorCore:d,toast:f,ui:p,TRANSITIONS:m}=pr(),h=l(t,n,r,`board`),g=(0,v.useCallback)(e=>{h.canEdit!==!1&&r(e)},[h.canEdit,r]),_=(0,v.useRef)(null),[y,x]=(0,v.useState)(!1),S=_n({doc:n,words:n?.audio?.words,projectId:t,projectType:`board`,canEdit:h.canEdit!==!1,onDocChange:g,editLease:_,host:e}),C=(n?.strip||[]).filter(e=>e.type===`canvas`),w=n?.meta?.aspect||i,T=async t=>{if(n&&!y&&h.canEdit!==!1){x(!0);try{await S.run(`settings`,async({doc:n,signal:r,check:i,commitAndWait:o})=>{let s=await fn(n,t,{host:e,signal:r,assertCurrent:i,transitions:m});i(),s!==n&&await o(s),i(),t.kind===`aspect`&&a?.(t.value)})}catch(e){e?.name!==`AbortError`&&f.error?.(e?.message||String(e))}finally{x(!1)}}},E=e=>{if(e!==w)return T({kind:`aspect`,value:e})},D=C.find(e=>(e.elements||[]).length>0),[O,k]=(0,v.useState)((D||C[0])?.panelId||null),A=C.find(e=>e.panelId===O)||C[0],j=C.map(e=>e.panelId).join(`,`),M=(0,v.useRef)(j);(0,v.useEffect)(()=>{let e=new Set(M.current.split(`,`).filter(Boolean)),t=C.filter(t=>!e.has(t.panelId));t.length&&k(t[0].panelId),M.current=j},[j]);let N=async(t,n=!1)=>{if(!(y||h.canEdit===!1)){x(!0);try{await S.run(`sequence`,async({doc:r,signal:i,check:a,commitAndWait:o})=>{if(n&&!await p.confirm(`Delete this board and everything on it? You can undo this.`,{danger:!0,confirmText:`Delete board`}))return;a();let s=await mn(r,t,{host:e,signal:i,assertCurrent:a});a(),s!==r&&await o(s),t.action===`remove`&&O===t.panelId&&k(s.strip.find(e=>e.type===`canvas`)?.panelId||null)})}catch(e){e?.name!==`AbortError`&&f.error?.(e?.message||String(e))}finally{x(!1)}}},P=(e,t)=>N({action:`move`,panelId:e,direction:t}),F=(e,t)=>{let[n,r]=Object.entries(t)[0];return T({kind:n,value:r,panelId:e})},[I,L]=(0,v.useState)(!1),[R,z]=(0,v.useState)(null),B=C.findIndex(e=>e.panelId===O),V=I&&A&&A.panelId===R&&B>0,ee=()=>{if(!I)return;let e=C[B+1];e&&(z(e.panelId),k(e.panelId))},H=e=>{if(C.length<=1){f.info?.(`Keep at least one board.`);return}return N({action:`remove`,panelId:e},!0)},te=(0,v.useRef)([]),ne=(0,v.useRef)([]),re=(0,v.useRef)(!1),ie=(0,v.useRef)(n),[,ae]=(0,v.useState)(0);(0,v.useEffect)(()=>{if(re.current){re.current=!1,ie.current=n;return}n!==ie.current&&(te.current.push(ie.current),te.current.length>60&&te.current.shift(),ne.current=[],ie.current=n,ae(e=>e+1))},[n]);let oe=(0,v.useCallback)(()=>{if(h.enabled)return h.undo();if(!te.current.length)return;ne.current.push(n);let e=te.current.pop();re.current=!0,g(e),ae(e=>e+1)},[n,g,h.enabled,h.undo]),se=(0,v.useCallback)(()=>{if(h.enabled)return h.redo();if(!ne.current.length)return;te.current.push(n);let e=ne.current.pop();re.current=!0,g(e),ae(e=>e+1)},[n,g,h.enabled,h.redo]),ce=h.enabled?h.canUndo&&h.status===`synced`:te.current.length>0,le=h.enabled?h.canRedo&&h.status===`synced`:ne.current.length>0;(0,v.useEffect)(()=>{let e=e=>{if(!(e.metaKey||e.ctrlKey))return;let t=(e.key||``).toLowerCase();if(t!==`z`&&t!==`y`)return;let n=e.target,r=(n?.tagName||``).toLowerCase();r===`input`||r===`textarea`||n?.isContentEditable||(e.preventDefault(),t===`y`||t===`z`&&e.shiftKey?se():oe())};return window.addEventListener(`keydown`,e),()=>window.removeEventListener(`keydown`,e)},[oe,se]);let ue=async(e,{signal:t}={})=>{if(t?.aborted||y||_.current||h.canEdit===!1||!(e===`undo`?ce:le))throw Error(`Wait for an available history action.`);x(!0);try{if(h.enabled)return await(e===`undo`?h.undo:h.redo)({agentReceipt:!0,signal:t});let n=e===`undo`?te:ne,r=e===`undo`?ne:te,i=n.current.at(-1),a,o=()=>{a&&_.current===a&&S.cancel()};try{let s=S.run(`assistant-history`,async({doc:a,check:o,commitAndWait:s})=>{if(o(),t?.aborted||n.current.at(-1)!==i)throw Error(`History changed before application.`);re.current=!0;try{await s(i)}finally{ie.current===i&&n.current.at(-1)===i&&(n.current.pop(),r.current.push(a),ae(e=>e+1))}return o(),{status:`applied-locally`,saved:!1,message:`${e===`undo`?`Undo`:`Redo`} accepted in White Board Motion. Save the project to keep it.`}});a=_.current,t?.addEventListener(`abort`,o,{once:!0}),t?.aborted&&o();let c=await s;if(!c)throw Error(`History was not applied.`);return c}finally{t?.removeEventListener(`abort`,o),re.current=!1}}finally{x(!1)}},[U,de]=(0,v.useState)(0),[fe,W]=(0,v.useState)(0);if(b({actions:hn({doc:n,canEdit:h.canEdit!==!1,busy:y,phase:S,lease:_,host:e,transitions:m,onAspectChange:a,setPending:x,page:U,setPage:de,activeId:A?.panelId,elementPage:fe,setElementPage:W,canUndo:ce,canRedo:le,onHistory:ue,onFocus:e=>{W(0),L(!1),z(null),k(e)}}),dependencies:[n,h.canEdit,y,U,O,fe,ce,le,h.enabled,h.status]}),!n||!A)return null;let pe=n.strip.reduce((e,t)=>Math.max(e,t.startMs+t.durationMs),0),me=async t=>{if(!(y||h.canEdit===!1)){x(!0);try{await S.run(`duration`,async({doc:n,signal:r,check:i,commitAndWait:a})=>{let o=await Qt(n,t,{host:e,signal:r,assertCurrent:i});i(),o!==n&&await a(o)})}catch(e){e?.name!==`AbortError`&&f.error?.(e?.message||String(e))}finally{x(!1)}}};return(0,q.jsxs)(`div`,{style:{flex:1,minHeight:0,overflowY:`auto`,WebkitOverflowScrolling:`touch`,paddingBottom:`env(safe-area-inset-bottom)`},children:[(0,q.jsx)(u,{live:h}),(0,q.jsxs)(`div`,{style:{maxWidth:1240,margin:`0 auto`,padding:`18px 16px 40px`,display:`flex`,flexDirection:`column`,gap:12,fontFamily:`var(--font)`},children:[(0,q.jsxs)(`div`,{style:{display:`flex`,alignItems:`center`,gap:12,flexWrap:`wrap`},children:[(0,q.jsxs)(`div`,{children:[(0,q.jsx)(`h2`,{style:{margin:0,fontSize:22,color:`var(--text-primary)`},children:`White Board Motion`}),(0,q.jsx)(`div`,{style:{fontSize:12,color:`var(--text-secondary)`,marginTop:2},children:`A white board where images, video, and text pop in and move over time. Build it here, then continue to the editor — it lands as a clip on your timeline.`})]}),(0,q.jsx)(`span`,{style:{flex:1}}),(0,q.jsxs)(`div`,{style:{display:`flex`,gap:0,borderRadius:7,overflow:`hidden`,border:`1px solid var(--border)`},children:[(0,q.jsx)(`button`,{type:`button`,\"aria-label\":`Undo`,title:`Undo (Cmd/Ctrl+Z)`,onClick:oe,disabled:!ce,style:mr(ce),children:`↶`}),(0,q.jsx)(`button`,{type:`button`,\"aria-label\":`Redo`,title:`Redo (Cmd/Ctrl+Shift+Z)`,onClick:se,disabled:!le,style:{...mr(le),borderLeft:`1px solid var(--border)`},children:`↷`})]}),(0,q.jsx)(`div`,{style:{display:`flex`,gap:0,borderRadius:7,overflow:`hidden`,border:`1px solid var(--border)`},title:`Board orientation — Landscape, Portrait, or Square`,children:[[`16:9`,`Landscape`],[`9:16`,`Portrait`],[`1:1`,`Square`]].map(([e,t],n)=>(0,q.jsx)(`button`,{type:`button`,disabled:y||h.canEdit===!1,title:t,className:w===e?`btn btn-primary`:`btn btn-secondary`,\"data-compact\":!0,style:{fontSize:11,borderRadius:0,...n?{borderLeft:`1px solid var(--border)`}:{}},onClick:()=>E(e),children:e},e))}),C.length>1&&(0,q.jsxs)(`div`,{style:{display:`flex`,alignItems:`center`,gap:6},children:[(0,q.jsx)(`div`,{style:{display:`flex`,alignItems:`center`,gap:0,borderRadius:7,overflow:`visible`,border:`1px solid var(--border)`},children:C.map((e,t)=>(0,q.jsxs)(v.Fragment,{children:[t>0&&(0,q.jsx)(Dr,{board:e,disabled:y||h.canEdit===!1,onSet:t=>F(e.panelId,t)}),(0,q.jsxs)(`button`,{type:`button`,className:A.panelId===e.panelId?`btn btn-primary`:`btn btn-secondary`,\"data-compact\":!0,style:{fontSize:11,borderRadius:0},onClick:()=>k(e.panelId),children:[`Board `,t+1]})]},e.panelId))}),(0,q.jsxs)(`div`,{style:{display:`flex`,gap:0,borderRadius:7,overflow:`hidden`,border:`1px solid var(--border)`},title:`Reorder or delete this board`,children:[(0,q.jsx)(`button`,{type:`button`,className:`btn btn-secondary`,\"data-compact\":!0,style:{fontSize:12,borderRadius:0},title:`Move this board earlier`,disabled:y||h.canEdit===!1||C[0]?.panelId===A.panelId,onClick:()=>P(A.panelId,-1),children:`‹`}),(0,q.jsx)(`button`,{type:`button`,className:`btn btn-secondary`,\"data-compact\":!0,style:{fontSize:12,borderRadius:0,borderLeft:`1px solid var(--border)`},title:`Move this board later`,disabled:y||h.canEdit===!1||C[C.length-1]?.panelId===A.panelId,onClick:()=>P(A.panelId,1),children:`›`}),(0,q.jsx)(`button`,{type:`button`,className:`btn btn-secondary`,\"data-compact\":!0,style:{fontSize:11,borderRadius:0,borderLeft:`1px solid var(--border)`,color:`var(--danger, #c0392b)`},title:`Delete this board`,disabled:y||h.canEdit===!1,onClick:()=>H(A.panelId),children:`Delete`})]})]}),C.length>1&&(0,q.jsxs)(`label`,{style:{display:`flex`,alignItems:`center`,gap:7,cursor:`pointer`,fontSize:12,color:I?`var(--accent)`:`var(--text-secondary)`,userSelect:`none`},title:`Preview all boards together, with the transitions`,children:[(0,q.jsx)(`span`,{style:{fontWeight:I?700:500},children:`Play all`}),(0,q.jsx)(`button`,{type:`button`,role:`switch`,\"aria-checked\":I,\"aria-label\":`Play all boards`,onClick:()=>L(e=>!e),style:{position:`relative`,width:34,height:18,flexShrink:0,borderRadius:999,background:I?`var(--accent)`:`var(--bg-elevated)`,borderWidth:1,borderStyle:`solid`,borderColor:I?`var(--accent)`:`var(--border)`,cursor:`pointer`,padding:0,transition:`background 0.15s, border-color 0.15s`},children:(0,q.jsx)(`span`,{style:{position:`absolute`,top:1,left:1,width:14,height:14,borderRadius:`50%`,background:I?`var(--bg-primary, #fff)`:`var(--text-muted)`,transform:I?`translateX(16px)`:`none`,transition:`transform 0.15s, background 0.15s`}})})]}),(0,q.jsx)(Cr,{disabled:y||h.canEdit===!1,valueMs:pe,onCommit:me}),(0,q.jsx)(`button`,{className:`btn btn-primary`,\"data-compact\":!0,style:{fontSize:12},onClick:o,children:`Update editor cut`}),s&&(0,q.jsx)(`button`,{className:`btn btn-secondary`,\"data-compact\":!0,style:{fontSize:12},onClick:s,title:`Compile these boards and open the export dialog`,children:`Export`})]}),(0,q.jsx)(wr,{projectId:t,canEdit:h.canEdit!==!1,doc:n,onDocChange:g,voiceover:c}),(0,q.jsx)(An,{host:e,projectId:t,canEdit:h.canEdit!==!1,doc:n,active:A,onDocChange:g}),(0,q.jsx)(d,{panelEditHost:e,projectId:t,canEdit:h.canEdit!==!1,doc:n,panelId:A.panelId,onDocChange:g,aspect:w,variant:`page`,autoPlay:I&&A.panelId===R,onEnded:ee,prevPanel:V?C[B-1]:null,transName:V?A.transitionIn:null,transMs:A.transitionMs,onRestartAll:C.length>1?()=>{let e=C[0];e&&(I&&z(e.panelId),k(e.panelId))}:null},A.panelId)]})]})}function kr({hostServices:e,editHost:t,presenterHostServices:n,presenterPlacementBroker:r,...i}){let a=Nn(e);return(0,q.jsx)(dr.Provider,{value:r,children:(0,q.jsx)(ur.Provider,{value:n===void 0?null:Ln(n),children:(0,q.jsx)(fr.Provider,{value:a,children:(0,q.jsx)(Or,{...i,editHost:H(t)})})})})}let Ar={manifest:{schemaVersion:1,sdkVersion:`0.1.0`,id:`stillmade-internal.presenter-gaps`,version:`1.0.0`,name:`Presenter narration gaps`,description:`Append the original narration gap boards and preserve existing coverage.`,kind:`task`,runtime:`javascript`,inputs:{doc:{type:`json`},words:{type:`json`}},outputs:{doc:{type:`json`}},permissions:{project:[],network:[],filesystem:[],secrets:[]}},code:`const CANVAS_TARGET_MS=5000;\nfunction splitRangeIntoCanvases(fromMs, toMs, targetMs = CANVAS_TARGET_MS) {\n const start = Number(fromMs) || 0;\n const end = Math.max(start, Number(toMs) || start);\n const span = end - start;\n if (span <= 0) return [{ startMs: start, endMs: start, durationMs: 0 }];\n const n = Math.max(1, Math.round(span / targetMs));\n const slice = span / n;\n const out = [];\n for (let i = 0; i < n; i++) {\n const s = Math.round(start + slice * i);\n const e = i === n - 1 ? end : Math.round(start + slice * (i + 1));\n out.push({ startMs: s, endMs: e, durationMs: e - s });\n }\n return out;\n}\n\nfunction appendHostGapBoards(doc, { words = [], minGapMs = 2000, targetMs = 5000 } = {}) {\n const last = words[words.length - 1];\n const narrationEnd = last ? Math.round(Number(last.endMs ?? last.startMs ?? 0)) : 0;\n if (!narrationEnd) return doc;\n const canvases = (doc?.strip || []).filter((p) => p.type === 'canvas');\n if (!canvases.length) return doc; // nothing built yet — gaps are meaningless\n // Merge the covered intervals, then walk them for uncovered stretches.\n const iv = canvases\n .map((p) => [Number(p.startMs) || 0, (Number(p.startMs) || 0) + (Number(p.durationMs) || 0)])\n .sort((a, b) => a[0] - b[0]);\n const merged = [];\n for (const [s, e] of iv) {\n const m = merged[merged.length - 1];\n if (m && s <= m[1]) m[1] = Math.max(m[1], e); else merged.push([s, e]);\n }\n const gaps = [];\n let cursor = 0;\n for (const [s, e] of merged) {\n if (s - cursor >= minGapMs) gaps.push([cursor, s]);\n cursor = Math.max(cursor, e);\n }\n if (narrationEnd - cursor >= minGapMs) gaps.push([cursor, narrationEnd]);\n if (!gaps.length) return doc;\n const sceneId = canvases[0].sceneId || doc?.scenes?.[0]?.sceneId || 's1';\n const stamp = (doc.strip || []).length;\n const boards = [];\n for (const [s, e] of gaps) {\n for (const seg of splitRangeIntoCanvases(s, e, targetMs)) {\n if (!seg.durationMs) continue;\n boards.push({\n panelId: \\`hostg\\${stamp}_\\${boards.length + 1}\\`,\n type: 'canvas', sceneId, background: '#ffffff', autoArrange: true,\n planned: true, builtBy: 'host-gap', startMs: seg.startMs, durationMs: seg.durationMs,\n transitionIn: 'cut', elements: [],\n });\n }\n }\n if (!boards.length) return doc;\n return { ...doc, strip: [...doc.strip, ...boards] };\n}\n\nreturn {doc:appendHostGapBoards(input.doc,{words:input.words})};\n`,tests:[{name:`No narration`,input:{doc:{strip:[]},words:[]},expected:{doc:{strip:[]}}}]};function jr(e){return N(e?.version===1&&typeof e.append==`function`,`HOST_SERVICES`,`Narration gaps require their version 1 sandbox broker.`),e}let Mr=(e,t)=>Object.fromEntries(t.filter(t=>e[t]!==void 0).map(t=>[t,e[t]]));function Nr(e,t){N(P(e)&&Array.isArray(e.strip)&&e.strip.length<=2048&&Array.isArray(t),`PRESENTER_GAPS`,`Choose a supported narration document.`);let n=new Map,r=new Map,i=e=>{if(!e)return e;if(N(typeof e==`string`,`PRESENTER_GAPS`,`A scene identity is invalid.`),!r.has(e)){let t=`scene-${r.size}`;r.set(e,t),n.set(t,e)}return r.get(e)},a=e.strip.map(e=>{if(N(P(e),`PRESENTER_GAPS`,`A board is invalid.`),e.type!==`canvas`)return{type:`other`};let t=Mr(e,[`type`,`startMs`,`durationMs`]);return e.sceneId!==void 0&&(t.sceneId=i(e.sceneId)),t}),o=t[t.length-1],s=P(o)?Mr(o,[`endMs`,`startMs`]):null,c={doc:{strip:a,...e.scenes?.[0]?.sceneId===void 0?{}:{scenes:[{sceneId:i(e.scenes[0].sceneId)}]}},words:t.length?[s]:[]};B(c);let l=a.filter(e=>e.type===`canvas`).flatMap(e=>[e.startMs,e.durationMs]);return s&&l.push(s.endMs??s.startMs??0),N(l.every(e=>e===void 0||Number.isFinite(Number(e))&&Math.abs(Number(e))<=18e5)&&a.filter(e=>e.type===`canvas`).length<=128&&JSON.stringify(c).length<=262144,`PRESENTER_GAPS`,`Use at most 128 boards with timing within 30 minutes.`),{input:c,scenes:n}}function Pr(e){let t=e.doc,n=e.words[e.words.length-1],r=n?Math.round(Number(n.endMs??n.startMs??0)):0,i=t.strip.filter(e=>e.type===`canvas`);if(!r||!i.length)return t;let a=i.map(e=>[Number(e.startMs)||0,(Number(e.startMs)||0)+(Number(e.durationMs)||0)]).sort((e,t)=>e[0]-t[0]),o=[];for(let e of a){let t=o[o.length-1];t&&e[0]<=t[1]?t[1]=Math.max(t[1],e[1]):o.push(e)}let s=[],c=0;for(let[e,t]of o)e-c>=2e3&&s.push([c,e]),c=Math.max(c,t);r-c>=2e3&&s.push([c,r]);let l=[],u=i[0].sceneId||t.scenes?.[0]?.sceneId||`s1`,d=t.strip.length;for(let[e,t]of s){let n=Number(e)||0,r=Math.max(n,Number(t)||n),i=r-n;if(i<=0)continue;let a=Math.max(1,Math.round(i/5e3));for(let e=0;e<a;e++){let t=Math.round(n+i/a*e),o=e===a-1?r:Math.round(n+i/a*(e+1));o!==t&&l.push({panelId:`hostg${d}_${l.length+1}`,type:`canvas`,sceneId:u,background:`#ffffff`,autoArrange:!0,planned:!0,builtBy:`host-gap`,startMs:t,durationMs:o-t,transitionIn:`cut`,elements:[]})}}return N(i.length+l.length<=128,`PRESENTER_GAPS`,`These narration gaps exceed the 128-board presenter limit.`),l.length?{...t,strip:[...t.strip,...l]}:t}function Fr(e){let t=H(e),n=()=>t.actor();return Object.freeze(jr({version:1,async append(e,r,{signal:i,assertCurrent:a}){let o=V({doc:e,words:r}),s=n(),c=()=>{a(),N(s&&n()===s&&!i.aborted&&V({doc:e,words:r})===o,`STALE`,`Narration gap construction was cancelled or the account changed.`)};c();let l=Nr(e,r),u=Pr(l.input);B(u);let d=await t.run(Ar,{kind:`run`,input:l.input,signal:i,timeoutMs:15e3});c();let f=d.outputs?.doc;if(B(f),N(V(f)===V(u),`PRESENTER_GAPS`,`The sandbox changed narration coverage, scene identity or board metadata.`),f.strip.length===e.strip.length)return e;let p=new Set(e.strip.map(e=>e.panelId)),m=f.strip.slice(e.strip.length).map(e=>(N(!p.has(e.panelId),`PRESENTER_GAPS`,`A generated gap-board identity already exists.`),p.add(e.panelId),N(e.sceneId===`s1`||l.scenes.has(e.sceneId),`PRESENTER_GAPS`,`A scene identity is unavailable.`),{...e,sceneId:l.scenes.get(e.sceneId)||`s1`}));return c(),{...e,strip:[...e.strip,...m]}}}))}function Ir(e){return N(e?.version===1&&typeof e.place==`function`,`HOST_SERVICES`,`Presenter builds require their version 1 placement broker.`),e}let Lr={manifest:{schemaVersion:1,sdkVersion:`0.1.0`,id:`stillmade-internal.presenter-placement`,version:`1.0.0`,name:`Presenter placement`,description:`Clear and replace presenter poses in narration order.`,kind:`task`,runtime:`javascript`,inputs:{doc:{type:`json`},mode:{type:`json`},poses:{type:`json`},words:{type:`json`}},outputs:{commands:{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 commands=[];\nconst model={\n removeCanvasElement:(doc,panelId,elementId)=>{commands.push({kind:'remove',panelId,elementId});return {...doc,strip:doc.strip.map(p=>p.panelId===panelId?{...p,elements:p.elements.filter(e=>e.id!==elementId)}:p)};},\n addCanvasElement:(doc,panelId,element)=>{commands.push({kind:'add',panelId,element});return doc;},\n};\nconst operation=createPresenterPlacement(model);\nif(input.mode==='clear')operation.clearPresenterPoses(input.doc);\nelse operation.placePosesOnDoc(input.doc,input.poses,input.words);\nreturn {commands};\n`,tests:[{name:`Empty boards`,input:{doc:{strip:[]},mode:`place`,poses:[],words:[]},expected:{commands:[]}}]},Rr={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:[]},zr=(e,t)=>V(e)===V(t),Br=[`id`,`kind`,`pinned`,`appearMs`,`leaveMs`,`pos`,`box`,`size`,`tilt`,`weight`],Vr=[`pos`,`box`,`size`,`tilt`,`weight`];function Hr(e,t,n){let r=e.strip.find(e=>e.panelId===t);N(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 Br)if(e[t]!==void 0){let r=e[t];n[t]=t===`pos`&&P(r)?{x:r.x,y:r.y}:t===`box`&&P(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 Ur(e){let t=e.doc.strip[0],n=t.elements.filter(t=>t.id!==e.elementId),r=t.template,i=ut(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=pt({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=ut(r);if(s){let e=ft(n,s,{aspect:o}),t=ze({...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=Be(a,{aspect:o}));return{...e.doc,strip:[a]}}function Wr(e,{panel:t,input:n},r){let i=Ur(n);B(i),B(r),N(zr(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||!zr(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 Vr){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&&!zr(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 Gr(e,t,n,{host:r,signal:i,assertCurrent:a,validateDocument:o}){let s=H(r),c=s.actor(),l=V(e),u=()=>{a?.(),N(c&&s.actor()===c&&!i?.aborted&&V(e)===l,`STALE`,`Canvas removal cancelled or its document changed.`)};u();let d=Hr(e,t,n);u();let f=await s.run(Rr,{kind:`run`,input:d.input,signal:i,timeoutMs:15e3});u();let p=Wr(e,d,f.outputs?.edit),m=p===e?e:o(p);return u(),m}function Kr({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;N(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 Gr(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 qr=(e,t)=>Object.fromEntries(t.filter(t=>e[t]!==void 0).map(t=>[t,e[t]]));function Jr(e,{mode:t,poses:n=[],words:r=[]}){N(P(e)&&Array.isArray(e.strip)&&e.strip.length<=2048&&[`place`,`clear`].includes(t),`PRESENTER_PLACEMENT`,`Choose a supported presenter document.`);let i=e.strip.filter(e=>e?.type===`canvas`);N(i.length<=128&&i.every(e=>P(e)&&typeof e.panelId==`string`&&Array.isArray(e.elements))&&new Set(e.strip.map(e=>e.panelId)).size===e.strip.length&&i.reduce((e,t)=>e+t.elements.length,0)<=4096,`PRESENTER_PLACEMENT`,`Choose at most 128 boards and 4,096 elements.`),N(i.every(e=>e.elements.every(e=>P(e)&&typeof e.id==`string`)&&new Set(e.elements.map(e=>e.id)).size===e.elements.length),`PRESENTER_PLACEMENT`,`Presenter element identities are invalid.`),N(Array.isArray(n)&&n.length<=128&&n.every(e=>P(e)&&typeof e.url==`string`)&&Array.isArray(r)&&r.length<=4096,`PRESENTER_PLACEMENT`,`Choose at most 128 poses and 4,096 narration words.`);let a=new Map,o=n.map((e,t)=>{let n=qr(e,[`label`,`atWord`]),r=`pose-${t}`;return a.set(r,e.url),n.url=e.url?r:``,n}),s={mode:t,doc:{strip:i.map(e=>({...qr(e,[`panelId`,`type`,`wordStart`,`wordEnd`,`startMs`,`durationMs`]),elements:e.elements.map(e=>({id:e.id,...e.source===`pose`?{source:`pose`}:{}}))}))},poses:o,words:r.map(e=>P(e)?qr(e,[`startMs`,`start`]):null)};return B(s),N(JSON.stringify(s).length<=1e6,`PRESENTER_PLACEMENT`,`Presenter timing metadata is too large.`),{input:s,media:a}}function Yr(e){let t=[],n=e=>String(e||``).toLowerCase().replace(/[^a-z0-9]+/g,`-`).replace(/^-+|-+$/g,``).slice(0,40),r=e.doc.strip.map(e=>{for(let n of e.elements)n.source===`pose`&&t.push({kind:`remove`,panelId:e.panelId,elementId:n.id});return{...e,elements:e.elements.filter(e=>e.source!==`pose`)}});if(e.mode===`clear`)return t;let i=e.poses.filter(e=>e.url);if(!i.length)return t;let a=new Map(i.map(e=>[n(e.label),e])),o=0,s=t=>{let n=0;for(let r=0;r<e.words.length;r++){let i=e.words[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};for(let c of r){if(!c.panelId)continue;let r=c.wordStart==null?s(c.startMs||0):c.wordStart,l=c.wordEnd==null?s((c.startMs||0)+(c.durationMs||0)):c.wordEnd,u;for(let t of e.poses)if(t.atWord!=null&&t.atWord>=r&&t.atWord<=l&&a.has(n(t.label))){u=a.get(n(t.label));break}u||(u=i[o%i.length],o++);let d=n(u.label),f=!c.elements.length;t.push({kind:`add`,panelId:c.panelId,element:{kind:`image`,src:u.url||null,source:`pose`,pose:d,cutout:!0,entrance:`pop`,pinned:!0,appearMs:0,leaveMs:null,pos:f?{x:.5,y:.62}:{x:/(^|-)right/.test(d)?.2:.8,y:.64},size:f?.52:.3,query:d}})}return t}function Xr(e){let t=H(e),n=()=>t.actor();return Object.freeze(Pn({version:1,async apply(e,r,{signal:i,assertCurrent:a}={}){let o=V({doc:e,request:r}),s=n(),c=()=>{a?.(),N(!i?.aborted&&s&&n()===s&&V({doc:e,request:r})===o,`STALE`,`Presenter placement was cancelled or the account changed.`)};c();let l=Jr(e,r),u=await t.run(Lr,{kind:`run`,input:l.input,signal:i,timeoutMs:15e3});c();let d=u.outputs?.commands,f=Yr(l.input);B(d),B(f),N(V(d)===V(f),`PRESENTER_PLACEMENT`,`The sandbox changed presenter placement or another element.`);let p=e;for(let e of d)c(),e.kind===`remove`?p=await Gr(p,e.panelId,e.elementId,{host:t,signal:i,assertCurrent:c,validateDocument:Zt}):(N(l.media.has(e.element.src),`PRESENTER_PLACEMENT`,`The selected pose is unavailable.`),p=await En(p,e.panelId,{...e.element,src:l.media.get(e.element.src)},{host:t,signal:i,assertCurrent:c,validateDocument:Zt}));return c(),p}}))}function Zr(e){let t=Xr(e);return Object.freeze(Ir({version:1,async place(e,{meta:n=null,poses:r=[],words:i=[]},{signal:a,assertCurrent:o}){let s=V({doc:e,meta:n,poses:r,words:i}),c=()=>{o(),N(!a?.aborted&&V({doc:e,meta:n,poses:r,words:i})===s,`STALE`,`Presenter build source changed.`)};if(c(),!r.length)return e;let l=n?Zt({...e,meta:{...e.meta||{},host:n}}):e,u=await t.apply(l,{mode:`place`,poses:r,words:i},{signal:a,assertCurrent:c});return c(),u}}))}let Qr={manifest:{schemaVersion:1,sdkVersion:`0.1.0`,id:`stillmade-internal.board-descriptors`,version:`1.0.0`,name:`Board descriptor resolution`,description:`Resolve captured asset metadata in the existing priority order.`,kind:`task`,runtime:`javascript`,inputs:{assets:{type:`json`},manuals:{type:`json`},contexts:{type:`json`}},outputs:{result:{type:`json`}},permissions:{project:[],network:[],filesystem:[],secrets:[]}},code:`// Canvas Chat Builder — asset DESCRIPTORS (spec S2.3 / S2.4 / S3).\n//\n// Every asset must end up with a descriptor (what it shows) so the builder can\n// match it to the right voiceover moment. Vision costs credits per asset, so the\n// resolution order is deliberately cheapest-first and vision is the LAST resort:\n//\n// 1. generated prompt — the prompt that MADE the asset already describes it\n// (saved at creation by api.js; free, no call)\n// 2. manual descriptor — what the user typed. Often BEST for uploads: their\n// REASON for the asset (\"a channel earning $5k/month\")\n// is usually not what vision literally sees (\"a YouTube\n// page with a subscriber count\"). Free.\n// 3. context/intent — inferred from the chat + voiceover: if the user said\n// \"make an intro showing channels earning $5k/month\"\n// and dropped 5 screenshots, their role is already\n// known. Free (it rides the build's own LLM pass).\n// 4. vision — only when the above can't resolve it AND the content\n// matters for placement. CHARGED per asset.\n//\n// Pure functions — no network, no store access — so the ordering is unit\n// testable with zero paid calls.\n\nconst DESCRIPTOR_SOURCES = ['generated', 'manual', 'context', 'vision'];\n\nconst clean = (s) => String(s == null ? '' : s).replace(/\\\\s+/g, ' ').trim();\n\n// A descriptor is only usable if it actually says something. Guards against a\n// stored empty string / whitespace prompt counting as \"resolved\" and silently\n// producing a bad match.\nfunction isUsableDescriptor(text) {\n return clean(text).length >= 3;\n}\n\n// Shorten a generation prompt into a matching-friendly summary. Generation\n// prompts carry style/camera boilerplate that hurts descriptor↔transcript\n// matching, so keep the leading subject clause.\nfunction summarizePrompt(prompt, maxLen = 180) {\n const t = clean(prompt);\n if (!t) return '';\n const firstClause = t.split(/[.;\\\\n]/)[0] || t;\n const base = firstClause.length >= 12 ? firstClause : t;\n return base.length <= maxLen ? base : \\`\\${base.slice(0, maxLen - 1).trimEnd()}…\\`;\n}\n\n// Resolve ONE asset's descriptor. Returns the text, which rung produced it, and\n// whether a paid vision call is still required.\n// asset — { prompt?, descriptor?, title?, name?, tags?, isStock? }\n// manual — the user's typed descriptor for this asset (wins over prompt:\n// it is the more intent-accurate answer and equally free)\n// context — descriptor inferred from chat intent + voiceover for this batch\nfunction resolveDescriptor(asset = {}, { manual = '', context = '' } = {}) {\n const manualText = clean(manual) || clean(asset.descriptor);\n if (isUsableDescriptor(manualText)) {\n return { text: manualText, source: 'manual', needsVision: false };\n }\n const promptText = summarizePrompt(asset.prompt);\n if (isUsableDescriptor(promptText)) {\n return { text: promptText, source: 'generated', needsVision: false };\n }\n const contextText = clean(context);\n if (isUsableDescriptor(contextText)) {\n return { text: contextText, source: 'context', needsVision: false };\n }\n // Stock often arrives with provider tags/title — free metadata beats a paid call.\n const stockText = clean(Array.isArray(asset.tags) ? asset.tags.join(', ') : '') || clean(asset.title || asset.name);\n if (asset.isStock && isUsableDescriptor(stockText)) {\n return { text: stockText, source: 'context', needsVision: false };\n }\n return { text: '', source: 'vision', needsVision: true };\n}\n\n// Resolve a whole batch and report exactly which assets will incur a vision\n// charge, so the chat can surface the cheap path (\"add descriptors and this\n// build drops to N credits\") BEFORE spending anything.\n// assets — [{ id, ...assetRecord }]\n// manuals — { [assetId]: 'typed descriptor' }\n// contexts— { [assetId]: 'inferred from intent' }\nfunction resolveBatch(assets = [], { manuals = {}, contexts = {} } = {}) {\n const resolved = (Array.isArray(assets) ? assets : []).map((a) => {\n const key = a?.id ?? a?.url;\n const r = resolveDescriptor(a, { manual: manuals[key], context: contexts[key] });\n return { asset: a, key, ...r };\n });\n const needingVision = resolved.filter((r) => r.needsVision);\n return {\n resolved,\n needingVision,\n visionCount: needingVision.length,\n freeCount: resolved.length - needingVision.length,\n bySource: DESCRIPTOR_SOURCES.reduce((acc, s) => {\n acc[s] = resolved.filter((r) => r.source === s).length;\n return acc;\n }, {}),\n };\n}\n\nreturn {result:resolveBatch(input.assets,{manuals:input.manuals,contexts:input.contexts})};`,tests:[{name:`Empty metadata batch`,input:{assets:[],manuals:{},contexts:{}},expected:{result:{resolved:[],needingVision:[],visionCount:0,freeCount:0,bySource:{generated:0,manual:0,context:0,vision:0}}}}]},$r=(e,t)=>Object.fromEntries(t.filter(t=>e[t]!==void 0).map(t=>[t,e[t]])),ei=e=>String(e??``).replace(/\\s+/g,` `).trim(),ti=[`generated`,`manual`,`context`,`vision`];function ni({assets:e,manuals:t,contexts:n}){let r=e.map(e=>{let r=e.id??e.url,i=ei(t[r])||ei(e.descriptor),a=ei(e.prompt),o=a.split(/[.;\\n]/)[0]||a,s=o.length>=12?o:a,c=s.length<=180?s:s.slice(0,179).trimEnd()+`…`,l=ei(n[r]),u=ei(Array.isArray(e.tags)?e.tags.join(`, `):``)||ei(e.title||e.name),d=``,f=`vision`;return i.length>=3?(d=i,f=`manual`):c.length>=3?(d=c,f=`generated`):l.length>=3?(d=l,f=`context`):e.isStock&&u.length>=3&&(d=u,f=`context`),{asset:e,key:r,text:d,source:f,needsVision:f===`vision`}}),i=r.filter(e=>e.needsVision);return{resolved:r,needingVision:i,visionCount:i.length,freeCount:r.length-i.length,bySource:Object.fromEntries(ti.map(e=>[e,r.filter(t=>t.source===e).length]))}}function ri(e){let t=H(e),n=()=>t.actor();return Object.freeze({version:1,actor:n,async resolve(e,{manuals:r={},contexts:i={},signal:a}){N(Array.isArray(e)&&e.length<=128&&e.every(P)&&P(r)&&P(i),`BOARD_DESCRIPTORS`,`Choose a supported batch of up to 128 assets.`);let o=V({assets:e,manuals:r,contexts:i}),s=n(),c=[],l=new Map,u={assets:e.map(e=>{let t=e.id??e.url;N(typeof t==`string`,`BOARD_DESCRIPTORS`,`Choose assets with stable identities.`),c.push(t),l.has(t)||l.set(t,crypto.randomUUID());let n=$r(e,[`prompt`,`descriptor`,`title`,`name`,`tags`,`isStock`]);return n.id=l.get(t),n}),manuals:Object.fromEntries([...l].map(([e,t])=>[t,r[e]??null])),contexts:Object.fromEntries([...l].map(([e,t])=>[t,i[e]??null]))};B(u),N(JSON.stringify(u).length<=1e6,`BOARD_DESCRIPTORS`,`Descriptor metadata is too large.`),N(s&&!a.aborted,`STALE`,`This descriptor request was cancelled.`);let d=await t.run(Qr,{kind:`run`,input:u,signal:a,timeoutMs:15e3});N(!a.aborted&&n()===s&&V({assets:e,manuals:r,contexts:i})===o,`STALE`,`The account or reviewed source changed.`);let f=d.outputs?.result,p=ni(u);B(f),B(p),N(V(f)===V(p),`BOARD_DESCRIPTORS`,`The sandbox changed descriptor priorities or batch identities.`);let m=f.resolved.map((t,n)=>({...t,asset:e[n],key:c[n]}));return{...f,resolved:m,needingVision:m.filter(e=>e.needsVision)}}})}let ii={manifest:{schemaVersion:1,sdkVersion:`0.1.0`,id:`stillmade-internal.board-chat-build`,version:`1.0.0`,name:`Board canvas assembly`,description:`Match reviewed assets and narration into timed boards.`,kind:`task`,runtime:`javascript`,inputs:{assembly:{type:`json`}},outputs:{panels:{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\n// Canvas Chat Builder — the DETERMINISTIC core (spec S4 / S5 / S6).\n//\n// The chat layer (LLM) decides intent, descriptors and which words matter; this\n// module does the part that must be exact and repeatable, matching how the rest\n// of Image Panel Mode splits \"planner = LLM\" from \"assembly = deterministic\":\n//\n// S4 match each asset to the voiceover moment that talks about it, using its\n// descriptor vs the transcript, and place it ON the beat with the same\n// visual-lead offset every other panel uses.\n// S5 a video is fit TO its beat (trim), muted — the clip's own length never\n// drives the timing.\n// S6 a NEW canvas roughly every ~5s rather than one endless canvas, with a\n// transition between them and self-arranging layout inside each.\n//\n// Pure functions — no network, no store, no paid calls.\n\nconst CANVAS_TARGET_MS = 5000; // S6: ~5s per new canvas\nconst MIN_BEAT_GAP_MS = 450; // two assets never land on the same instant\nconst WINDOW_WORDS = 8; // transcript window an asset is matched against\n\n// Words that carry no matching signal. Kept small and obvious on purpose: an\n// over-aggressive list silently destroys matches that a user can't debug.\nconst STOP = new Set([\n 'a', 'an', 'the', 'and', 'or', 'but', 'if', 'so', 'of', 'to', 'in', 'on', 'at', 'for', 'with',\n 'from', 'by', 'is', 'are', 'was', 'were', 'be', 'been', 'it', 'its', 'this', 'that', 'these',\n 'those', 'as', 'you', 'your', 'we', 'our', 'i', 'my', 'they', 'them', 'their', 'he', 'she',\n 'his', 'her', 'not', 'no', 'do', 'does', 'did', 'can', 'will', 'just', 'about', 'into', 'over',\n]);\n\nfunction tokenize(text) {\n return String(text || '')\n .toLowerCase()\n .replace(/[^a-z0-9$%\\\\s]/g, ' ')\n .split(/\\\\s+/)\n .filter((t) => t && t.length > 1 && !STOP.has(t));\n}\n\n// Overlap score between an asset descriptor and a transcript window. Weighted so\n// a rare, longer token (e.g. \"dopamine\", \"$5k\") counts for more than a common\n// short one — that is what makes \"channels earning $5k/month\" land on the words\n// where the narration actually says it.\nfunction scoreMatch(descTokens, windowTokens) {\n if (!descTokens.length || !windowTokens.length) return 0;\n const win = new Set(windowTokens);\n let hit = 0;\n for (const t of new Set(descTokens)) {\n if (win.has(t)) hit += Math.min(3, 1 + Math.floor(t.length / 4));\n }\n return hit / descTokens.length;\n}\n\nconst wordMs = (w) => Number(w?.startMs ?? w?.start ?? 0) || 0;\n\n// Words inside the user's chosen coverage range (S4: \"how much of the voiceover\n// should these assets cover\"). Returns the words plus their absolute index so\n// placement can report a word index as well as ms.\nfunction wordsInRange(words, fromMs, toMs) {\n const list = Array.isArray(words) ? words : [];\n const lo = Number.isFinite(fromMs) ? fromMs : -Infinity;\n const hi = Number.isFinite(toMs) ? toMs : Infinity;\n return list\n .map((w, i) => ({ w, i, ms: wordMs(w) }))\n .filter(({ ms }) => ms >= lo && ms <= hi);\n}\n\n// S4 — place each asset at the moment the narration talks about its content.\n// Greedy by confidence: the strongest descriptor↔transcript match claims its\n// beat first, so a confident asset is never displaced by a vague one. Assets\n// that match nothing are SPREAD across the remaining gaps rather than dropped —\n// the user gave us that asset on purpose.\nfunction matchAssetsToRange({ assets = [], words = [], fromMs = 0, toMs = null, leadMs = VISUAL_LEAD_MS } = {}) {\n const scoped = wordsInRange(words, fromMs, toMs);\n const rangeStart = scoped.length ? scoped[0].ms : (Number(fromMs) || 0);\n const rangeEnd = scoped.length ? scoped[scoped.length - 1].ms : (Number(toMs) || rangeStart);\n const list = Array.isArray(assets) ? assets : [];\n if (!list.length) return { placements: [], rangeStart, rangeEnd };\n\n // Candidate windows across the range. A window gives CONTEXT for scoring, but\n // the placement must land on the word that actually matched — attributing it\n // to the window's start would drop the visual up to WINDOW_WORDS too early.\n const windows = scoped.map((entry, k) => {\n const slice = scoped.slice(k, k + WINDOW_WORDS);\n return { entries: slice, tokens: tokenize(slice.map(({ w }) => w?.word ?? w?.text ?? '').join(' ')) };\n });\n\n const scored = list.map((a, idx) => {\n const desc = tokenize(a?.descriptor || a?.text || '');\n const descSet = new Set(desc);\n let best = null;\n for (const win of windows) {\n const s = scoreMatch(desc, win.tokens);\n if (s > 0 && (!best || s > best.score)) {\n // the first word inside this window that the descriptor actually mentions\n const hit = win.entries.find((e) => tokenize(e.w?.word ?? e.w?.text ?? '').some((t) => descSet.has(t)))\n || win.entries[0];\n best = { score: s, ms: hit.ms, wordIndex: hit.i };\n }\n }\n return { asset: a, idx, best };\n });\n\n const taken = [];\n const fits = (ms) => taken.every((t) => Math.abs(t - ms) >= MIN_BEAT_GAP_MS);\n const placements = [];\n\n // 1) confident matches claim their beat first\n for (const s of scored.filter((x) => x.best).sort((a, b) => b.best.score - a.best.score)) {\n if (!fits(s.best.ms)) continue;\n taken.push(s.best.ms);\n placements.push({ asset: s.asset, idx: s.idx, atMs: s.best.ms, wordIndex: s.best.wordIndex, matched: true, score: s.best.score });\n }\n // 2) everything else spreads evenly through the range, avoiding claimed beats\n const rest = scored.filter((s) => !placements.some((p) => p.idx === s.idx));\n if (rest.length) {\n const span = Math.max(0, rangeEnd - rangeStart);\n const step = rest.length > 1 ? span / rest.length : 0;\n rest.forEach((s, k) => {\n let ms = Math.round(rangeStart + step * k + (step ? step / 2 : 0));\n let guard = 0;\n while (!fits(ms) && guard++ < 40) ms += MIN_BEAT_GAP_MS;\n taken.push(ms);\n placements.push({ asset: s.asset, idx: s.idx, atMs: ms, wordIndex: null, matched: false, score: 0 });\n });\n }\n\n // Chronological, with the visual-lead offset applied (appear just BEFORE the word).\n placements.sort((a, b) => a.atMs - b.atMs);\n return {\n placements: placements.map((p) => ({ ...p, appearMs: Math.max(rangeStart, p.atMs - leadMs) })),\n rangeStart,\n rangeEnd,\n };\n}\n\n// S6 — split the covered range into ~5s canvases. The last slice is merged back\n// when it would be a sliver, so a 5.4s range is ONE canvas, not a 5s + 0.4s stub.\nfunction splitRangeIntoCanvases(fromMs, toMs, targetMs = CANVAS_TARGET_MS) {\n const start = Number(fromMs) || 0;\n const end = Math.max(start, Number(toMs) || start);\n const span = end - start;\n if (span <= 0) return [{ startMs: start, endMs: start, durationMs: 0 }];\n const n = Math.max(1, Math.round(span / targetMs));\n const slice = span / n;\n const out = [];\n for (let i = 0; i < n; i++) {\n const s = Math.round(start + slice * i);\n const e = i === n - 1 ? end : Math.round(start + slice * (i + 1));\n out.push({ startMs: s, endMs: e, durationMs: e - s });\n }\n return out;\n}\n\n// S5 — a video is fit to its beat: it plays the portion that fits, muted, and\n// never stretches the canvas to its own length. Returns the source-in/out the\n// element should use.\nfunction fitVideoToBeat({ sourceDurationMs = 0, beatMs = 0, sourceInMs = 0 } = {}) {\n const beat = Math.max(0, Number(beatMs) || 0);\n const src = Math.max(0, Number(sourceDurationMs) || 0);\n if (!src || !beat) return { sourceInMs: 0, sourceOutMs: beat, loop: false, muted: true };\n const start = Math.max(0, Math.min(Number(sourceInMs) || 0, Math.max(0, src - 1)));\n const available = src - start;\n if (available >= beat) return { sourceInMs: start, sourceOutMs: start + beat, loop: false, muted: true };\n // Clip shorter than its beat → loop it rather than freeze or stretch the beat.\n return { sourceInMs: start, sourceOutMs: src, loop: true, muted: true };\n}\n\n// Assemble the placed assets (+ any timed text the chat chose) into real canvas\n// panel rows — the same shape the strip and the canvas mini-editor already use,\n// so the build is a first draft the user can hand-edit afterward (S8).\nfunction buildCanvasPanels({\n assets = [], words = [], fromMs = 0, toMs = null, texts = [],\n targetMs = CANVAS_TARGET_MS, sceneId = null, idPrefix = 'cvb', leadMs = VISUAL_LEAD_MS,\n} = {}) {\n const { placements, rangeStart, rangeEnd } = matchAssetsToRange({ assets, words, fromMs, toMs, leadMs });\n const slices = splitRangeIntoCanvases(rangeStart, toMs ?? rangeEnd, targetMs);\n\n // Timed text rides the same lead offset; the chat supplies WHICH words matter\n // (selective key phrases — never captions, per S4).\n const textPlacements = (Array.isArray(texts) ? texts : [])\n .map((t) => ({\n text: String(t?.text || '').slice(0, 80),\n atMs: Number(t?.atMs) || 0,\n emphasis: t?.emphasis === 'primary' ? 'primary' : 'secondary',\n perWord: !!t?.perWord, // word-by-word reveal (the no-VO \"animated words\")\n }))\n .filter((t) => t.text)\n .map((t) => ({ ...t, appearMs: Math.max(rangeStart, t.atMs - leadMs) }));\n\n const inSlice = (ms, s, isLast) => ms >= s.startMs && (isLast ? ms <= s.endMs : ms < s.endMs);\n\n return slices.map((s, i) => {\n const isLast = i === slices.length - 1;\n let n = 0;\n const elements = [];\n\n for (const p of placements.filter((x) => inSlice(x.appearMs, s, isLast))) {\n const a = p.asset || {};\n const isVideo = a.type === 'video' || a.kind === 'video';\n const appearMs = Math.max(0, p.appearMs - s.startMs);\n const base = {\n id: \\`\\${idPrefix}\\${i + 1}e\\${++n}\\`,\n appearMs,\n leaveMs: null,\n pos: null, // self-arranging (S6) — arrangeCanvas lays it out\n pinned: false, // a manual move later makes it sticky\n entrance: 'pop',\n sfx: 'auto',\n size: p.matched && p.score >= 0.5 ? 0.46 : 0.3,\n descriptor: a.descriptor || '',\n assetId: a.id || null,\n };\n if (isVideo) {\n const beat = Math.max(600, s.endMs - (s.startMs + appearMs));\n const fit = fitVideoToBeat({ sourceDurationMs: a.durationMs, beatMs: beat, sourceInMs: a.sourceInMs });\n elements.push({ ...base, kind: 'video', src: a.url || null, ...fit });\n } else {\n elements.push({ ...base, kind: 'image', src: a.url || null, source: a.source || 'user' });\n }\n }\n\n for (const t of textPlacements.filter((x) => inSlice(x.appearMs, s, isLast))) {\n elements.push({\n id: \\`\\${idPrefix}\\${i + 1}t\\${++n}\\`,\n kind: 'text',\n text: t.text,\n appearMs: Math.max(0, t.appearMs - s.startMs),\n leaveMs: null,\n pos: null,\n size: t.emphasis === 'primary' ? 0.085 : 0.06,\n font: 'Hanken Grotesk',\n color: '#111111',\n weight: 800,\n anim: { type: 'pop', perWord: !!t.perWord, speedMs: 180 },\n sfx: 'auto',\n pinned: false,\n });\n }\n\n elements.sort((a, b) => a.appearMs - b.appearMs);\n return {\n panelId: \\`\\${idPrefix}\\${i + 1}\\`,\n type: 'canvas',\n sceneId,\n background: '#ffffff',\n autoArrange: true, // S6 self-arranging; a manual drag pins it\n planned: true,\n builtBy: 'canvas-chat',\n startMs: s.startMs,\n durationMs: s.durationMs,\n transitionIn: i === 0 ? 'cut' : 'swirl', // S6: transitions between canvases\n elements,\n };\n });\n}\n\nreturn {panels:buildCanvasPanels(input.assembly)};`,tests:[{name:`Empty five-second board`,input:{assembly:{assets:[],words:[],texts:[],fromMs:0,toMs:5e3}},expected:{panels:[{panelId:`cvb1`,type:`canvas`,sceneId:null,background:`#ffffff`,autoArrange:!0,planned:!0,builtBy:`canvas-chat`,startMs:0,durationMs:5e3,transitionIn:`cut`,elements:[]}]}}]},ai=new Set(`a an the and or but if so of to in on at for with from by is are was were be been it its this that these those as you your we our i my they them their he she his her not no do does did can will just about into over`.split(` `)),oi=e=>String(e||``).toLowerCase().replace(/[^a-z0-9$%\\s]/g,` `).split(/\\s+/).filter(e=>e.length>1&&!ai.has(e)),si=e=>Number(e?.startMs??e?.start??0)||0,ci=(e,t)=>{if(!e.length||!t.length)return 0;let n=new Set(t),r=0;for(let t of new Set(e))n.has(t)&&(r+=Math.min(3,1+Math.floor(t.length/4)));return r/e.length};function li({assets:e=[],words:t=[],fromMs:n=0,toMs:r=null,texts:i=[],targetMs:a=5e3,sceneId:o=null,idPrefix:s=`cvb`,leadMs:c=75}={}){let l=Number.isFinite(n)?n:-1/0,u=Number.isFinite(r)?r:1/0,d=(Array.isArray(t)?t:[]).map((e,t)=>({word:e,index:t,ms:si(e)})).filter(e=>e.ms>=l&&e.ms<=u),f=d.length?d[0].ms:Number(n)||0,p=d.length?d[d.length-1].ms:Number(r)||f,m=d.map((e,t)=>{let n=d.slice(t,t+8);return{entries:n,tokens:oi(n.map(e=>e.word?.word??e.word?.text??``).join(` `))}}),h=(Array.isArray(e)?e:[]).map((e,t)=>{let n=oi(e?.descriptor||e?.text||``),r=new Set(n),i=null;for(let e of m){let t=ci(n,e.tokens);t>0&&(!i||t>i.confidence)&&(i={confidence:t,ms:(e.entries.find(e=>oi(e.word?.word??e.word?.text??``).some(e=>r.has(e)))||e.entries[0]).ms})}return{asset:e,index:t,match:i}}),g=[],_=[],v=e=>g.every(t=>Math.abs(t-e)>=450);for(let e of h.filter(e=>e.match).sort((e,t)=>t.match.confidence-e.match.confidence))v(e.match.ms)&&(g.push(e.match.ms),_.push({...e,ms:e.match.ms,matched:!0,score:e.match.confidence}));let y=h.filter(e=>!_.some(t=>t.index===e.index)),b=y.length>1?Math.max(0,p-f)/y.length:0;y.forEach((e,t)=>{let n=Math.round(f+b*t+(b?b/2:0)),r=0;for(;!v(n)&&r++<40;)n+=450;g.push(n),_.push({...e,ms:n,matched:!1,score:0})}),_.sort((e,t)=>e.ms-t.ms);let x=_.map(e=>({...e,appear:Math.max(f,e.ms-c)})),S=Number(f)||0,C=Math.max(S,Number(r??p)||S),w=C-S,T=w<=0?1:Math.max(1,Math.round(w/a)),E=w/T;N(Number.isSafeInteger(T)&&T>=1&&T<=1e4,`BOARD_BUILD`,`The reviewed assembly has too many boards.`);let D=(Array.isArray(i)?i:[]).map(e=>({text:String(e?.text||``).slice(0,80),at:Number(e?.atMs)||0,primary:e?.emphasis===`primary`,perWord:!!e?.perWord})).filter(e=>e.text).map(e=>({...e,appear:Math.max(f,e.at-c)}));return Array.from({length:T},(e,t)=>{let n=w<=0?S:Math.round(S+E*t),r=t===T-1?C:Math.round(S+E*(t+1)),i=e=>e>=n&&(t===T-1?e<=r:e<r),a=0,c=[];for(let e of x.filter(e=>i(e.appear))){let i=e.asset||{},o=Math.max(0,e.appear-n),l={id:`${s}${t+1}e${++a}`,appearMs:o,leaveMs:null,pos:null,pinned:!1,entrance:`pop`,sfx:`auto`,size:e.matched&&e.score>=.5?.46:.3,descriptor:i.descriptor||``,assetId:i.id||null};if(i.type===`video`||i.kind===`video`){let e=Math.max(600,r-(n+o)),t=Math.max(0,Number(i.durationMs)||0),a=Math.max(0,Math.min(Number(i.sourceInMs)||0,Math.max(0,t-1))),s=!t||!e?{sourceInMs:0,sourceOutMs:e,loop:!1,muted:!0}:{sourceInMs:a,sourceOutMs:t-a>=e?a+e:t,loop:t-a<e,muted:!0};c.push({...l,kind:`video`,src:i.url||null,...s})}else c.push({...l,kind:`image`,src:i.url||null,source:i.source||`user`})}for(let e of D.filter(e=>i(e.appear)))c.push({id:`${s}${t+1}t${++a}`,kind:`text`,text:e.text,appearMs:Math.max(0,e.appear-n),leaveMs:null,pos:null,size:e.primary?.085:.06,font:`Hanken Grotesk`,color:`#111111`,weight:800,anim:{type:`pop`,perWord:e.perWord,speedMs:180},sfx:`auto`,pinned:!1});return c.sort((e,t)=>e.appearMs-t.appearMs),{panelId:`${s}${t+1}`,type:`canvas`,sceneId:o,background:`#ffffff`,autoArrange:!0,planned:!0,builtBy:`canvas-chat`,startMs:n,durationMs:r-n,transitionIn:t===0?`cut`:`swirl`,elements:c}})}function ui(e,t){B(e),B(t);let n=li(e);return B(n),N(V(t)===V(n),`BOARD_BUILD`,`The sandbox assembly does not match the reviewed assets, timing and text.`),t}let di=(e,t)=>Object.fromEntries(t.filter(t=>e?.[t]!==void 0).map(t=>[t,e[t]]));function fi(e){N(P(e)&&Array.isArray(e.assets)&&e.assets.length<=128&&Array.isArray(e.words)&&e.words.length<=4096&&Array.isArray(e.texts)&&e.texts.length<=128,`BOARD_BUILD`,`Use at most 128 assets, 4096 narration words and 128 text phrases.`);let t=new Map,n=new Map,r=(e,t)=>{let n=crypto.randomUUID();return e.set(n,t),n},i={...di(e,[`fromMs`,`toMs`,`targetMs`,`sceneId`,`idPrefix`,`leadMs`]),assets:e.assets.map(e=>{N(P(e),`BOARD_BUILD`,`Choose valid build assets.`);let i=di(e,[`type`,`kind`,`descriptor`,`text`,`durationMs`,`sourceInMs`,`source`]);return e.url!==void 0&&(N(e.url===null||typeof e.url==`string`,`BOARD_BUILD`,`Choose supported asset media.`),i.url=e.url?r(t,e.url):e.url),e.id!==void 0&&(N(e.id===null||typeof e.id==`string`,`BOARD_BUILD`,`Choose valid asset identities.`),i.id=e.id?r(n,e.id):e.id),i}),words:e.words.map(e=>di(e,[`word`,`text`,`startMs`,`start`])),texts:e.texts.map(e=>di(e,[`text`,`atMs`,`emphasis`,`perWord`]))};B(i);let a=e=>typeof e==`number`&&Number.isFinite(e)&&Math.abs(e)<=18e5;return N((i.fromMs===void 0||a(i.fromMs))&&(i.toMs==null||a(i.toMs))&&(i.targetMs===void 0||a(i.targetMs)&&i.targetMs>=1e3)&&(i.leadMs===void 0||a(i.leadMs)),`BOARD_BUILD`,`Choose a supported coverage range of up to 30 minutes.`),N(i.words.every(e=>a(Number(e.startMs??e.start??0)||0))&&i.texts.every(e=>a(Number(e.atMs)||0)),`BOARD_BUILD`,`Narration timing is outside the supported range.`),N((i.sceneId==null||typeof i.sceneId==`string`)&&(i.idPrefix===void 0||typeof i.idPrefix==`string`&&i.idPrefix.length<=100)&&JSON.stringify(i).length<=2e6,`BOARD_BUILD`,`This build document is too large or malformed.`),{assembly:i,media:t,identity:n}}function pi(e){let t=H(e),n=()=>t.actor();return Object.freeze({version:1,actor:n,async build(e,{signal:r}){let i=V(e),a=n(),{assembly:o,media:s,identity:c}=fi(e);N(a&&!r.aborted,`STALE`,`This build was cancelled.`);let l=await t.run(ii,{kind:`run`,input:{assembly:o},signal:r,timeoutMs:15e3});return N(!r.aborted&&n()===a&&V(e)===i,`STALE`,`The account or reviewed source changed.`),ui(o,l.outputs?.panels).map(e=>({...e,elements:e.elements.map(e=>{let t={...e};return t.src!==void 0&&t.src!==null&&(N(s.has(t.src),`BOARD_BUILD`,`The sandbox returned unknown media.`),t.src=s.get(t.src)),t.assetId!==void 0&&t.assetId!==null&&(N(c.has(t.assetId),`BOARD_BUILD`,`The sandbox returned an unknown asset identity.`),t.assetId=c.get(t.assetId)),t})}))}})}let mi=[`planCanvasChatBuild`,`describeImage`,`parseCanvasChatEdit`,`uploadGifBlob`,`captureClipFrame`,`imageCost`,`stockGrid`,`generateHostPoses`,`applyHostToDoc`,`appendHostGapBoards`,`getDefaultImageModel`,`buildCanvasPanels`,`applyCanvasEdits`],hi=mi.filter(e=>![`buildCanvasPanels`,`applyCanvasEdits`].includes(e)),gi=hi.filter(e=>![`applyHostToDoc`,`appendHostGapBoards`].includes(e));function _i(e){return N([1,2,3].includes(e?.version)&&(e.version===1?mi:e.version===2?hi:gi).every(t=>typeof e[t]==`function`)&&[`error`,`info`,`success`].every(t=>typeof e.toast?.[t]==`function`)&&typeof e.ui?.confirm==`function`&&e.CREDIT_COSTS&&typeof e.CREDIT_COSTS==`object`&&typeof e.PRESENTER_HOST_BETA==`boolean`&&Number.isSafeInteger(e.MIN_POSE_SHEETS)&&e.MIN_POSE_SHEETS>0,`HOST_SERVICES`,`Canvas chat requires version 1, 2 or 3 of its host operations.`),e}let vi=[`generated`,`manual`,`context`,`vision`],yi=e=>String(e??``).replace(/\\s+/g,` `).trim();function bi(e){return yi(e).length>=3}function xi(e,t=180){let n=yi(e);if(!n)return``;let r=n.split(/[.;\\n]/)[0]||n,i=r.length>=12?r:n;return i.length<=t?i:`${i.slice(0,t-1).trimEnd()}…`}function Si(e={},{manual:t=``,context:n=``}={}){let r=yi(t)||yi(e.descriptor);if(bi(r))return{text:r,source:`manual`,needsVision:!1};let i=xi(e.prompt);if(bi(i))return{text:i,source:`generated`,needsVision:!1};let a=yi(n);if(bi(a))return{text:a,source:`context`,needsVision:!1};let o=yi(Array.isArray(e.tags)?e.tags.join(`, `):``)||yi(e.title||e.name);return e.isStock&&bi(o)?{text:o,source:`context`,needsVision:!1}:{text:``,source:`vision`,needsVision:!0}}function Ci(e=[],{manuals:t={},contexts:n={}}={}){let r=(Array.isArray(e)?e:[]).map(e=>{let r=e?.id??e?.url;return{asset:e,key:r,...Si(e,{manual:t[r],context:n[r]})}}),i=r.filter(e=>e.needsVision);return{resolved:r,needingVision:i,visionCount:i.length,freeCount:r.length-i.length,bySource:vi.reduce((e,t)=>(e[t]=r.filter(e=>e.source===t).length,e),{})}}let wi=[`user`,`library`,`stock`],Ti=e=>String(e?.url||e?.id||``).trim().toLowerCase();function Ei({pools:e={},enabled:t=[`user`]}={}){let n=new Set([`user`,...(Array.isArray(t)?t:[]).filter(e=>wi.includes(e))]),r=new Set,i=[],a=[],o=[];for(let t of wi){let s=Array.isArray(e[t])?e[t]:[];for(let e of s){if(!n.has(t)){a.push({asset:e,source:t,reason:`source not chosen by the user`});continue}let s=Ti(e);if(s){if(r.has(s)){o.push({asset:e,source:t});continue}r.add(s),i.push({...e,source:t})}}}return{assets:i,refused:a,duplicates:o,sourcesUsed:[...n].filter(e=>i.some(t=>t.source===e))}}function Di({assets:e=[],manuals:t={},contexts:n={},coveredMs:r=0,perCanvasMs:i=5e3}={}){let{visionCount:a,freeCount:o,needingVision:s}=Ci(e,{manuals:t,contexts:n}),c=r>0?Math.max(1,Math.round(r/i)):0,l=Math.max(0,c-e.length),u=[];return e.length?l>0&&u.push({kind:`too-few`,shortBy:l,message:`That covers ${c} canvas${c===1?``:`es`} but you gave ${e.length} asset${e.length===1?``:`s`} — want me to pull ${l} more from your library, find stock, or generate them?`}):u.push({kind:`need-assets`,message:`No assets yet — add some, or ask me to pull from your library or find stock.`}),a>0&&u.push({kind:`cost`,visionCount:a,message:`${a} asset${a===1?` needs`:`s need`} a vision descriptor (charged). Describe ${a===1?`it`:`them`} yourself and that cost goes away.`}),{ready:e.length>0,canvases:c,shortBy:l,visionCount:a,freeCount:o,needingVision:s.map(e=>e.key),suggestions:u}}function Oi(e){return e===`library`?`Nothing in your library matched that — want me to search stock instead, or generate something?`:e===`stock`?`Stock had no good match for that — want to use one of your own assets, or generate it?`:`No assets found for that.`}var ki=c({MEDIA_ICONS:()=>Mi,attachMediaPlayer:()=>Ii,attachPhotoExpand:()=>Ri,enhanceMedia:()=>zi,formatMediaTime:()=>Ni,isDeviceMediaUrl:()=>Pi,mediaPlayerCore:()=>Ai,openMediaViewer:()=>Li,photoSize:()=>Fi});function Ai(){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`),N=c(d,`div`,`sm-player-buffered`),P=c(d,`div`,`sm-player-played`),F=c(d,`div`,`sm-player-head`),I=c(d,`div`,`sm-player-knob`),L=c(d,`div`,`sm-player-tip`),R=c(d,`span`,`sm-player-time`),z=c(d,`span`,`sm-player-now`),B=c(d,`span`,`sm-media-of sm-player-total`);M.append(N,P),F.append(I),j.append(M,F,L),R.append(z,B),j.dataset.control=`timeline`,j.tabIndex=0,j.setAttribute(`role`,`slider`),j.setAttribute(`aria-label`,`Seek`),j.setAttribute(`aria-valuemin`,`0`),R.dataset.control=`time`,R.setAttribute(`aria-hidden`,`true`),L.setAttribute(`aria-hidden`,`true`),E.setAttribute(`aria-hidden`,`true`);let V=c(d,`div`,`sm-player-sound`),ee=c(d,`div`,`sm-player-volume`),H=c(d,`div`,`sm-player-volume-rail`),te=c(d,`div`,`sm-player-volume-track`),ne=c(d,`div`,`sm-player-volume-level`),re=c(d,`div`,`sm-player-volume-head`),ie=c(d,`div`,`sm-player-volume-knob`);te.append(ne,re),re.append(ie),H.append(te),ee.append(H),V.append(ee,k),V.dataset.control=`volume`,H.tabIndex=0,H.setAttribute(`role`,`slider`),H.setAttribute(`aria-label`,`Volume`),H.setAttribute(`aria-orientation`,`vertical`),H.setAttribute(`aria-valuemin`,`0`),H.setAttribute(`aria-valuemax`,`100`),D.append(O,j,R,V,A),y.append(E,D);let ae=!1,oe=!1,se=0,ce=Date.now(),le=!1,ue=0,U=0,de=0,fe=!0,W=``,pe=``,me=``,G=``,he=!1,ge=!1,K=!1,_e=!1,ve=null,ye=!1,be=0,xe=!1,Se=0,Ce=!1,we=0,Te=0,Ee=-1,De=-1,Oe=-1,ke=0,Ae=0,je=!1,Me=0,Ne=0,Pe=()=>Number.isFinite(e.duration)&&e.duration>0?e.duration:0,Fe=(e,t)=>{t?v.setAttribute(e,``):v.removeAttribute(e)},Ie=()=>{let t=Pe(),n=le?ue*t:e.currentTime||0,r=t?Math.min(1,Math.max(0,n/t)):0;r!==Ee&&(Ee=r,P.style.transform=`scaleX(`+r+`)`,F.style.transform=`translateX(`+r*100+`%)`);let i=Math.floor(n);(i!==De||t!==Oe)&&(De=i,Oe=t,z.textContent=o(n),B.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)))},Le=()=>{U=0,!ae&&(Ie(),!e.paused&&!e.ended&&fe&&(U=g(Le)))},Re=()=>{!U&&!ae&&(U=g(Le))},ze=()=>{let t=Pe(),n=e.buffered;t&&n&&n.length&&(N.style.transform=`scaleX(`+Math.min(1,n.end(n.length-1)/t)+`)`)},Be=()=>!!f.matchMedia?.(`(hover: none)`)?.matches,Ve=e=>e.pointerType?e.pointerType===`mouse`:!Be(),He=e=>{try{return e.matches(`:focus-visible`)}catch{return!0}},Ue=()=>!ae&&!e.paused&&!e.ended&&!le&&!je&&!ye&&!xe&&!ve,We=e=>{oe!==e&&(oe=e,Fe(`data-idle`,e))},Ge=()=>{if(se=0,!Ue())return;let e=t-(Date.now()-ce);if(e>10){se=f.setTimeout(Ge,e);return}We(!0)},Ke=()=>{if(!Ue()){se&&=(f.clearTimeout(se),0),We(!1);return}!se&&!oe&&(se=f.setTimeout(Ge,Math.max(10,t-(Date.now()-ce))))},qe=()=>{ce=Date.now(),We(!1),Ke()},Je=()=>{let e=!ae&&!(ge||_e||le||je||ye||xe);e!==K&&(K=e,Fe(`data-away`,e))},Ye=()=>{Se&&=(f.clearTimeout(Se),0),xe=!1},Xe=()=>{Ce||ae||(Ce=!0,xe=!0,Se=f.setTimeout(()=>{Se=0,xe=!1,Je(),Ke()},r),Je(),Ke())},Ze=()=>{ye=!0,be&&f.clearTimeout(be),be=f.setTimeout(()=>{be=0,ye=!1,Je(),Ke()},n),Je(),qe()},Qe=()=>{if(e.paused||e.ended){let t=e.play();t&&typeof t.catch==`function`&&t.catch(()=>{})}else e.pause()},$e=t=>{let n=Pe();n&&(e.currentTime=Math.min(n,Math.max(0,t)),Re())},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`),Fe(`data-playing`,t),qe(),Re()},rt=()=>{let t=e.muted||e.volume===0,n=t?0:Math.min(1,Math.max(0,e.volume)),r=Math.round(n*100);ne.style.transform=`scaleY(`+n+`)`,re.style.transform=`translateY(`+-n*100+`%)`,H.setAttribute(`aria-valuenow`,String(r)),H.setAttribute(`aria-valuetext`,t?`Muted`:r+`%`),k.setAttribute(`aria-pressed`,String(!!e.muted)),l(k,`Mute`,t?`volumeX`:`volume2`,e.muted?`Unmute`:`Mute`)},it=()=>W===`theater`||d.fullscreenElement===v,at=()=>{let e=it();l(A,e?`Exit full screen`:`Full screen`,e?`minimize`:`maximize`)},ot=()=>{if(W=`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(W===`theater`){if(W=``,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(W===`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();we=e.left,Te=e.width},ft=e=>Te>0?Math.min(1,Math.max(0,(e-we)/Te)):0,pt=e=>{let t=Math.min(Math.max(e-we,22),Math.max(22,Te-22)),n=o(Pe()*ft(e));L.style.transform=`translateX(`+t+`px) translateX(-50%)`,L.textContent!==n&&(L.textContent=n)},mt=()=>{let t=Pe();t&&(e.currentTime=ue*t),Ie()},ht=()=>{de||=g(()=>{de=0,ae||mt()})},gt=()=>{le&&(de&&=(_(de),0),mt(),le=!1,j.removeAttribute(`data-drag`),G===`touch`?Ze():(Je(),Ke()))};h(j,`pointerenter`,dt),h(j,`pointerdown`,e=>{if(!(e.button>0)){dt(),le=!0,Je(),j.setAttribute(`data-drag`,``);try{j.setPointerCapture?.(e.pointerId)}catch{}ue=ft(e.clientX),ht(),pt(e.clientX),qe()}}),h(j,`pointermove`,e=>{pt(e.clientX),le&&(ue=ft(e.clientX),ht())}),h(j,`pointerup`,gt),h(j,`pointercancel`,gt),h(j,`lostpointercapture`,gt);let _t=()=>{let e=te.getBoundingClientRect();ke=e.top,Ae=e.height},vt=e=>Ae>0?Math.min(1,Math.max(0,1-(e-ke)/Ae)):0,yt=()=>{Ne=0,!ae&&(e.volume=Math.round(Me*100)/100,e.muted=Me===0)},bt=()=>{Ne||=g(yt)},xt=()=>{je&&(Ne&&(_(Ne),yt()),je=!1,ee.removeAttribute(`data-drag`),Je(),Ke())};h(H,`pointerdown`,e=>{if(!(e.button>0)){e.stopPropagation(),_t(),je=!0,ee.setAttribute(`data-drag`,``),Je();try{H.setPointerCapture?.(e.pointerId)}catch{}Me=vt(e.clientY),bt(),qe()}}),h(H,`pointermove`,e=>{je&&(Me=vt(e.clientY),bt())}),h(H,`pointerup`,xt),h(H,`pointercancel`,xt),h(H,`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=>{G=Ve(e)?`mouse`:`touch`,he=K||oe,G===`touch`&&!he&&Ze()}),h(v,`click`,e=>{let t=G?G===`touch`:Be(),n=G?he:K||oe;if(G=``,!D.contains(e.target)){if(!t){Qe(),qe();return}n||Qe(),Ze()}}),h(v,`dblclick`,e=>{D.contains(e.target)||(e.preventDefault(),ut())}),h(v,`pointerenter`,e=>{Ve(e)&&(Ye(),ge=!0,Je(),qe())}),h(v,`pointermove`,e=>{Ve(e)&&(ce=Date.now(),ge||(Ye(),ge=!0,Je()),oe&&We(!1),se||Ke())}),h(v,`pointerleave`,e=>{Ve(e)&&(ge=!1,Je())});let St=e=>!!e&&(v.contains(e)||C.contains(e)),Ct=e=>{let t=He(e.target);t&&(_e=!0),ve=t&&e.target!==v&&e.target!==C?e.target:null,Je(),qe()},wt=e=>{ve=null,St(e.relatedTarget)||(_e=!1,Je()),Ke()};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;_e||(_e=!0,Je());let n=t.key,r=n&&n.length===1?n.toLowerCase():n,i=Pe();if((n===` `||n===`Enter`)&&t.target?.closest?.(`button`))return;let a=!0;n===` `||r===`k`?Qe():t.target===H&&/^Arrow(Up|Down|Left|Right)$/.test(n||``)?tt(n===`ArrowUp`||n===`ArrowRight`?.1:-.1):t.target===H&&(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`&&W===`theater`?(st(),t.stopPropagation()):a=!1,a&&t.preventDefault(),qe()};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`,Re),h(e,`durationchange`,Re),h(e,`loadedmetadata`,Re),h(e,`progress`,ze),h(e,`volumechange`,rt),h(e,`emptied`,()=>{Ee=-1,De=-1,N.style.transform=`scaleX(0)`,Re()}),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!==pe&&(pe=r,pe?v.setAttribute(`data-size`,pe):v.removeAttribute(`data-size`));let i=!(t.height>0)||t.height>=200?``:t.height<150?`none`:`short`;i!==me&&(me=i,me?v.setAttribute(`data-volume-room`,me):v.removeAttribute(`data-volume-room`))}):null,Dt=typeof f.IntersectionObserver==`function`?new f.IntersectionObserver(e=>{fe=e[e.length-1].isIntersecting,fe&&(Re(),Xe())}):null;Et?.observe(v),Dt?.observe(v);let Ot=()=>{if(!ae){lt(),ae=!0,i.delete(e);for(let[e,t,n,r]of m)e.removeEventListener(t,n,r);Et?.disconnect(),Dt?.disconnect(),U&&_(U),de&&_(de),se&&f.clearTimeout(se),be&&f.clearTimeout(be),Se&&f.clearTimeout(Se),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{ge=v.matches(`:hover`)}catch{}let kt=d.activeElement;St(kt)&&He(kt)&&(_e=!0,ve=kt!==v&&kt!==C?kt:null),Je(),nt(),rt(),at(),Ie(),ze();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,N=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=>{N=e.touches?.length===1&&!e.target?.closest?.(`.sm-player-bar`)?e.touches[0].clientX:null},{passive:!0}),o(g,`touchend`,e=>{if(N==null||l.length<2)return;let t=e.changedTouches[0].clientX-N;N=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 ji,Mi,Ni,Pi,Fi,Ii,Li,Ri,zi,Bi=o((()=>{ji=Ai(),{ICONS:Mi,formatTime:Ni,isDeviceMediaUrl:Pi,photoSize:Fi,attachMediaPlayer:Ii,openMediaViewer:Li,attachPhotoExpand:Ri,enhance:zi}=ji}));function Vi(e){return new Promise(t=>{try{let n=document.createElement(`video`);n.preload=`metadata`;let r=e=>{n.onloadedmetadata=null,n.onerror=null,t(e)};n.onloadedmetadata=()=>r(Math.round((Number(n.duration)||0)*1e3)),n.onerror=()=>r(0),n.src=e}catch{t(0)}})}function Hi(e){return new Promise((t,n)=>{let r=new Image;r.crossOrigin=`anonymous`,r.onload=()=>{try{let e=r.naturalWidth||1,n=r.naturalHeight||1,i=Math.min(1,1024/Math.max(e,n)),a=document.createElement(`canvas`);a.width=Math.max(1,Math.round(e*i)),a.height=Math.max(1,Math.round(n*i)),a.getContext(`2d`).drawImage(r,0,0,a.width,a.height),t(a.toDataURL(`image/jpeg`,.82))}catch(e){n(e)}},r.onerror=()=>n(Error(`image load failed`)),r.src=e})}async function Ui(e,t,n=``,r=3){let i;for(let a=0;a<r;a++)try{return await e(t,n)}catch(e){if(i=e,!/\\b(429|500|502|503|504)\\b/.test(String(e?.message||``))||a===r-1)throw e;await new Promise(e=>setTimeout(e,500*(a+1)*(a+1)))}throw i}async function Wi(e,t,n){let r=0,i=Array.from({length:Math.max(1,Math.min(t,e.length))},async()=>{for(;r<e.length;){let t=r++;await n(e[t],t)}});await Promise.all(i)}function Gi(e){let t=String(e||``).toLowerCase(),n=t.match(/(\\d{1,3}(?:\\.\\d+)?)\\s*(?:s\\b|sec\\b|secs\\b|second|seconds)/),r=t.match(/(\\d{1,2}(?:\\.\\d+)?)\\s*(?:m\\b|min\\b|mins\\b|minute|minutes)/),i=0;return r&&(i+=Number(r[1])*6e4),n&&(i+=Number(n[1])*1e3),i?Math.max(1e3,Math.min(6e5,Math.round(i))):null}function Ki(e){return e?.phase===`generate`?`Generating pose sheet ${(e.done??0)+1}/${e.total}…`:e?.phase===`slice`?`Cutting out poses ${(e.done??0)+1}/${e.total}…`:e?.phase===`save`?`Saving host…`:`Planning poses…`}function qi(e){return String(e||``).replace(/\\.[a-z0-9]{1,5}$/i,``).replace(/[_\\-]+/g,` `).replace(/\\s+/g,` `).trim()}function Ji({asset:e,onClose:t}){let n=(0,v.useRef)(t);return n.current=t,(0,v.useEffect)(()=>{if(!e?.url)return;let t=null,r=!0;return Promise.resolve().then(()=>(Bi(),ki)).then(({openMediaViewer:i})=>{r&&(t=i([{url:e.url,kind:e.type===`video`?`video`:`image`,name:e.name||e.title||``}],{label:`Asset preview`,onClose:()=>n.current?.(),onShow:e=>{e.tagName===`VIDEO`?e.loop=!0:e.style.background=`#fff`}}))}),()=>{r=!1,t?.close({silent:!0})}},[e]),null}function Yi(){let[e,t]=(0,v.useState)(!1);return(0,q.jsxs)(`span`,{style:{position:`relative`,display:`inline-flex`},onMouseEnter:()=>t(!0),onMouseLeave:()=>t(!1),children:[(0,q.jsx)(`button`,{type:`button`,\"aria-label\":`What does AI vision do?`,style:J.infoGlyph,onFocus:()=>t(!0),onBlur:()=>t(!1),children:`i`}),e&&(0,q.jsx)(`span`,{role:`tooltip`,style:J.infoTip,children:`AI vision is on by default and free. When on, AI looks at the asset and writes its descriptor, using whatever is in the text box as a hint — that hint might be a meaningless filename, or a real description you typed; either way AI still looks at the image. Turn it off for an asset to skip AI and just use the text in the box as its descriptor.`})]})}function Xi({on:e,onChange:t}){return(0,q.jsx)(`button`,{type:`button`,role:`switch`,\"aria-checked\":e,\"aria-label\":`AI vision`,title:e?`AI vision on — AI describes this (free)`:`AI vision off — uses the text box only`,style:{...J.switch,...e?J.switchOn:{}},onClick:t,children:(0,q.jsx)(`span`,{style:{...J.knob,...e?J.knobOn:{}}})})}function Zi({asset:e,value:t,onCommit:n,onPreview:r,visionOn:i,onToggleVision:a}){let[o,s]=(0,v.useState)(t||``);return(0,q.jsxs)(`div`,{style:J.assetRow,children:[(0,q.jsx)(Xi,{on:i,onChange:a}),(0,q.jsx)(`button`,{type:`button`,style:J.assetThumb,title:`Click to view full size`,onClick:()=>r?.(e),children:e.type===`video`?(0,q.jsx)(`span`,{style:J.thumbPlay,\"aria-hidden\":`true`}):(0,q.jsx)(`img`,{src:e.thumbUrl||e.url,alt:``,loading:`lazy`,style:J.thumbImg,onError:e=>{e.currentTarget.style.visibility=`hidden`}})}),(0,q.jsx)(`input`,{style:J.descInput,placeholder:i?`Optional hint for AI vision`:`Describe it`,value:o,onChange:e=>s(e.target.value),onBlur:()=>n(o),onKeyDown:e=>{e.key===`Enter`&&e.currentTarget.blur()}})]})}function Qi({hostServices:e,editHost:t,projectId:n=null,canEdit:r=!0,doc:i,onDocChange:a,words:o=[],availableAssets:s={user:[],library:[],stock:[]},hostSlot:c=null}){let{planCanvasChatBuild:l,describeImage:u,parseCanvasChatEdit:d,uploadGifBlob:f,captureClipFrame:p,imageCost:m,stockGrid:h,generateHostPoses:g,getDefaultImageModel:_,toast:y,ui:b,CREDIT_COSTS:x,PRESENTER_HOST_BETA:S,MIN_POSE_SHEETS:C}=_i(e),{gapRuntime:w,presenterRuntime:T,descriptorRuntime:E,assemblyBroker:D,sandboxBroker:O}=(0,v.useMemo)(()=>({gapRuntime:Fr(t),presenterRuntime:Zr(t),descriptorRuntime:ri(t),assemblyBroker:pi(t),sandboxBroker:un(t)}),[t]),k=(0,v.useRef)(null),A=(0,v.useRef)(null),j=(0,v.useRef)(null),M=(0,v.useRef)(!0);A.current={doc:i,projectId:n,canEdit:r,onDocChange:a,editHost:t,hostServices:e,actor:O.actor()},(0,v.useEffect)(()=>(M.current=!0,()=>{M.current=!1,k.current?.abort(),k.current=null,j.current?.abort(),j.current=null}),[]),(0,v.useEffect)(()=>{j.current&&(j.current.abort(),j.current=null,V(!1),H(``))},[i,n,r,e,O,O.actor()]),(0,v.useEffect)(()=>{k.current&&(k.current.abort(),k.current=null,V(!1),H(``))},[i,n,r,e,D,D.actor()]);let[N,P]=(0,v.useState)(()=>i?.meta?.canvasChat?.intent||``),F=e=>a(t=>t&&{...t,meta:{...t.meta||{},canvasChat:{...t.meta?.canvasChat||{},...e}}}),[I,L]=(0,v.useState)([`user`]),[R,z]=(0,v.useState)({}),[B,V]=(0,v.useState)(!1),[ee,H]=(0,v.useState)(``),[te,ne]=(0,v.useState)(null),[re,ie]=(0,v.useState)(``),[ae,oe]=(0,v.useState)([]),se=(0,v.useRef)([]),[ce,le]=(0,v.useState)([]),[ue,U]=(0,v.useState)(``),[de,fe]=(0,v.useState)(!1),[W,pe]=(0,v.useState)({from:``,to:``}),[me,G]=(0,v.useState)(null),[he,ge]=(0,v.useState)({}),K=e=>e?.id??e?.url,_e=e=>!he[K(e)],ve=(0,v.useMemo)(()=>({...s,user:[...s.user||[],...ae],stock:[...s.stock||[],...ce]}),[s,ae,ce]),{assets:ye}=(0,v.useMemo)(()=>Ei({pools:ve,enabled:I}),[ve,I]),be=async e=>{let t=[...e||[]].filter(e=>/^(image|video)\\//.test(e.type));if(!t.length){y.info?.(`Only images and videos can be added.`);return}let n=await Promise.all(t.map(async(e,t)=>{let n=URL.createObjectURL(e),r={id:`up_${Date.now()}_${t}`,url:n,thumbUrl:n,type:e.type.startsWith(`video`)?`video`:`image`,name:e.name,descriptor:qi(e.name),source:`user`,uploading:!0};return r.type===`video`&&(r.durationMs=await Vi(n)),{a:r,file:e}}));oe(e=>[...e,...n.map(e=>e.a)]);for(let{a:e,file:t}of n){let n=(async()=>{try{let n=(t.name.split(`.`).pop()||(e.type===`video`?`mp4`:`png`)).toLowerCase(),r=await f(t,n);return oe(t=>t.map(t=>t.id===e.id?{...t,url:r,thumbUrl:r,uploading:!1}:t)),{id:e.id,url:r}}catch(t){return oe(t=>t.map(t=>t.id===e.id?{...t,uploading:!1}:t)),y.error?.(`Couldn't save \"${e.name}\" to your project — it may not survive a refresh (${t?.message||t}).`),{id:e.id,url:e.url}}})();se.current.push(n)}},xe=async e=>{let t=ue.trim();if(!t){y.info?.(`Type what to search stock for.`);return}fe(!0);try{let n=((await h(t,e))?.results||[]).slice(0,8).map((n,r)=>({id:`stk_${n.source||`s`}_${n.id??r}`,url:n.url||n.previewUrl,type:e===`video`?`video`:`image`,isStock:!0,tags:n.tags||[],title:n.name||n.title||t,descriptor:n.tags&&n.tags.length?n.tags.join(`, `):n.name||t,source:`stock`})).filter(e=>e.url);if(!n.length){y.info?.(Oi(`stock`));return}le(e=>[...e,...n]),I.includes(`stock`)||L(e=>[...e,`stock`]),y.success?.(`Added ${n.length} stock ${e===`video`?`clips`:`images`}.`)}catch(e){y.error?.(`Stock search failed (${e?.message||e}).`)}finally{fe(!1)}},Se=(0,v.useMemo)(()=>{let e=o[o.length-1];return e?Math.round(Number(e.endMs??e.startMs??0)):0},[o]),Ce=(0,v.useMemo)(()=>{let e=W.from===``?0:Math.max(0,Number(W.from)*1e3),t=W.to===``?Se:Number(W.to)*1e3;return Math.max(0,(Number.isFinite(t)?t:Se)-e)},[W,Se]),we=(0,v.useMemo)(()=>Di({assets:ye,manuals:R,coveredMs:Ce}),[ye,R,Ce]),Te=e=>L(t=>t.includes(e)?t.filter(t=>t!==e):[...t,e]),Ee=async()=>{if(B||!r||j.current||k.current)return;if(!ye.length){y.info?.(`Add some assets first.`);return}let n=A.current,a=D.actor();if(n.actor!==a)return;let s=new AbortController,c=JSON.stringify(n.doc),d=[...se.current];k.current=s,V(!0),H(`Reviewing build…`);let f=()=>{let r=A.current;if(!M.current||s.signal.aborted||k.current!==s||D.actor()!==a||r.actor!==a||r.editHost!==t||r.hostServices!==e||r.projectId!==n.projectId||r.doc!==n.doc||!r.canEdit||JSON.stringify(n.doc)!==c)throw Error(`The board changed. Review this build again.`)};try{if(f(),!o.length){let e=await b.confirm(`There is no voiceover for this project yet. Build the canvases without narration timing? Assets will be spread evenly instead of matched to spoken moments.`,{confirmText:`Build anyway`});if(f(),!e)return}let r=x[`canvasChat:build`],h=ye.filter(e=>_e(e)).length,v=h?` AI vision will describe ${h} asset${h===1?``:`s`} (free); toggle any off to skip it.`:``,O=S&&!!i?.meta?.host?.enabled,j=O&&!i?.meta?.host?.poses?.length,P=m(_(),C,{quality:`high`,resolution:`1K`}),F=j?` A presenter host also generates with this build (about ${C} pose sheets · ~${P} cr).`:``;if(!await b.confirm(`Build the canvases from these ${ye.length} asset${ye.length===1?``:`s`}? ~${r} credits.${v}${F}`,{confirmText:`Build`}))return;f();let I=ye;if(d.length){H(`Saving your uploads…`);let e=await Promise.all(d);f(),se.current=se.current.filter(e=>!d.includes(e)),H(``);let t=new Map(e.filter(Boolean).map(e=>[e.id,e.url]));I=ye.map(e=>t.has(e.id)?{...e,url:t.get(e.id)}:e)}f();let L=await l({message:N,assets:I.map(e=>({id:e.id,type:e.type,descriptor:R[e.id]||e.descriptor||``,prompt:e.prompt||``})),words:o,modelTier:`standard`});f(),f(),H(`Resolving asset descriptions…`);let{resolved:z}=await E.resolve(I,{manuals:R,contexts:L?.descriptors||{},signal:s.signal});f(),H(``);let B={},V=z.filter(e=>_e(e.asset)&&e.asset?.url);V.length&&(H(`Describing ${V.length} asset${V.length===1?``:`s`}…`),await Wi(V,2,async e=>{try{f();let t=e.asset.url;if(e.asset.type===`video`||e.asset.kind===`video`){let n=Math.max(0,(Number(e.asset.durationMs)||0)/1e3*.35),r=await p({kind:`video`,url:e.asset.url},n);r&&(t=r)}else if(!/^data:/i.test(String(t)))try{t=await Hi(t)}catch{}let n=String(R[e.key]??e.asset.descriptor??``).trim();f();let r=await Ui((...e)=>(f(),u(...e)),t,n);f();let i=String(r?.description||``).trim();i&&(B[e.key]=i)}catch(e){f(),y.info?.(`Couldn't describe one asset (${e?.message||e}) — placing it by position instead.`)}}),H(``));let ee=z.map(e=>({...e.asset,descriptor:B[e.key]||e.text||``})),te=W.from===``?0:Math.max(0,Math.round(Number(W.from)*1e3)),re=(i?.strip||[]).filter(e=>e.type===`canvas`).reduce((e,t)=>e+(Number(t.durationMs)||0),0)||1e4,ie=Gi(N),ae=W.to===``?o.length?null:ie||re:Math.round(Number(W.to)*1e3),oe=!o.length,ce=(ae??re)-te,le=L?.texts||[],ue=le.map((e,t)=>{let n;return n=o.length&&e.wordIndex!=null?Number(o[e.wordIndex]?.startMs??0)||0:e.atFraction==null?Math.round(te+(t+.5)/Math.max(1,le.length)*ce):Math.round(te+e.atFraction*ce),{text:e.text,atMs:n,emphasis:e.emphasis,perWord:oe}});f(),H(`Assembling canvases…`);let U=await D.build({assets:ee,words:o,texts:ue,fromMs:te,toMs:ae,sceneId:(i?.strip||[]).find(e=>e.type===`canvas`)?.sceneId||i?.scenes?.[0]?.sceneId||`s1`,idPrefix:`cvb${(i?.strip||[]).length+1}_`},{signal:s.signal});if(f(),!U.length){y.error?.(`Nothing to build from those assets.`);return}let de=null;if(O&&j)try{H(`Planning poses…`);let e=(N.trim()||i?.meta?.canvasChat?.intent||o.map(e=>typeof e==`string`?e:e?.text||``).join(` `)).slice(0,4e3);f(),de=await g({content:e,words:o,onProgress:e=>{k.current===s&&!s.signal.aborted&&D.actor()===a&&H(Ki(e))}}),f()}catch(e){f(),y.error?.(`The presenter host couldn't generate (${e?.message||e}) — the canvases still built; try the host again below.`)}finally{k.current===s&&H(``)}f();let fe=n.doc||{},pe=fe.meta?.canvasChat?.log||[],me=N.trim()?[...pe,{role:`user`,text:N.trim()}]:pe,G={...fe,strip:[...fe.strip||[],...U],meta:{...fe.meta||{},canvasChat:{...fe.meta?.canvasChat||{},intent:N,log:me}}};if(O){let e=de?.poses||fe.meta?.host?.poses||[];e.length&&(G=await w.append(G,o,{signal:s.signal,assertCurrent:f}),f(),H(`Placing presenter…`),G=await T.place(G,{meta:de?.meta||null,poses:e,words:o},{signal:s.signal,assertCurrent:f}),f())}f();let he=JSON.stringify(G);n.onDocChange(r=>{let i=A.current;if(!M.current||s.signal.aborted||D.actor()!==a||i.actor!==a||i.editHost!==t||i.hostServices!==e||i.projectId!==n.projectId||!i.canEdit||JSON.stringify(r)!==c||JSON.stringify(G)!==he)throw Error(`The board changed before this build could be saved.`);return G}),ne(U.map(e=>e.panelId));let ge=O&&!!(de?.poses?.length||i?.meta?.host?.poses?.length);y.success?.(`Submitted ${U.length} canvas${U.length===1?``:`es`}${ge?` with your presenter placed`:``} — edit them here or ask me to change something.`)}catch(e){M.current&&!s.signal.aborted&&D.actor()===a&&A.current.projectId===n.projectId&&y.error?.(`Build didn't finish (${e?.message||e}).`)}finally{k.current===s&&(k.current=null,M.current&&(V(!1),H(``)))}},De=async()=>{let n=re.trim();if(!n||!te?.length||B||!r||j.current)return;let i=A.current,a=O.actor();if(i.actor!==a)return;let o=new AbortController;j.current=o;let s=(i.doc?.strip||[]).filter(e=>te.includes(e.panelId)),c=JSON.stringify(s),l=()=>{let n=A.current;if(!M.current||o.signal.aborted||j.current!==o||O.actor()!==a||n.actor!==a||n.editHost!==t||n.hostServices!==e||n.projectId!==i.projectId||n.doc!==i.doc||!n.canEdit)throw Error(`The board changed. Review this edit again.`)};V(!0),H(`Applying your edit…`);try{l();let r=$i(n,te);if(r.length||(H(`Working out that change…`),r=await d({message:n,canvases:s.map(e=>({panelId:e.panelId,durationMs:e.durationMs,transitionIn:e.transitionIn,elements:(e.elements||[]).map(e=>({id:e.id,kind:e.kind,text:e.text,descriptor:e.descriptor}))})),modelTier:`standard`}),l()),!r.length){y.info?.(`I couldn’t map that to a change. Try naming what to change.`);return}let{panels:u,applied:f}=await O.apply(s,r,{signal:o.signal});if(l(),!f.length){y.info?.(`That didn’t match anything on the built canvases.`);return}let p=JSON.stringify(u),m=new Map(u.map(e=>[e.panelId,e]));i.onDocChange(r=>{let s=A.current;if(!M.current||o.signal.aborted||O.actor()!==a||s.actor!==a||s.editHost!==t||s.hostServices!==e||s.projectId!==i.projectId||!s.canEdit||JSON.stringify((r?.strip||[]).filter(e=>te.includes(e.panelId)))!==c||JSON.stringify(u)!==p)throw Error(`The edited boards changed before this update could be saved.`);let l=r||{},d=[...l.meta?.canvasChat?.log||[],{role:`user`,text:n}];return{...l,strip:(l.strip||[]).map(e=>m.get(e.panelId)||e),meta:{...l.meta||{},canvasChat:{...l.meta?.canvasChat||{},log:d}}}}),ie(``)}catch(e){M.current&&!o.signal.aborted&&O.actor()===a&&A.current.projectId===i.projectId&&y.error?.(e.message||`This edit could not be applied.`)}finally{j.current===o&&(j.current=null,M.current&&(V(!1),H(``)))}};return(0,q.jsxs)(`div`,{style:J.wrap,children:[(0,q.jsx)(`div`,{style:J.head,children:`Build from your assets`}),(0,q.jsx)(`textarea`,{style:J.intent,placeholder:`What are you making? e.g. “make an intro with these showing channels earning $5k/month”`,value:N,onChange:e=>P(e.target.value),onBlur:()=>F({intent:N})}),(0,q.jsxs)(`label`,{style:J.drop,onDragOver:e=>{e.preventDefault()},onDrop:e=>{e.preventDefault(),be(e.dataTransfer?.files)},children:[(0,q.jsx)(`input`,{type:`file`,accept:`image/*,video/*`,multiple:!0,style:{display:`none`},onChange:e=>{be(e.target.files),e.target.value=``}}),`Drop images or videos here, or click to choose`]}),(0,q.jsxs)(`div`,{style:J.sources,children:[(0,q.jsx)(`span`,{style:J.sourceLabel,children:`Assets from`}),(0,q.jsx)(`span`,{style:{...J.chip,...J.chipOn},title:`Always included`,children:`Mine`}),[`library`,`stock`].map(e=>(0,q.jsx)(`button`,{type:`button`,onClick:()=>Te(e),style:{...J.chip,...I.includes(e)?J.chipOn:{}},title:`Only added when you choose it — nothing is pulled automatically`,children:e===`library`?`My library`:`Stock`},e))]}),I.includes(`stock`)&&(0,q.jsxs)(`div`,{style:J.refine,children:[(0,q.jsx)(`input`,{style:J.editInput,placeholder:`Search stock for… (nothing is pulled until you search)`,value:ue,onChange:e=>U(e.target.value),onKeyDown:e=>{e.key===`Enter`&&xe(`image`)}}),(0,q.jsx)(`button`,{type:`button`,className:`btn btn-secondary`,\"data-compact\":!0,disabled:de,onClick:()=>xe(`image`),children:de?`…`:`Images`}),(0,q.jsx)(`button`,{type:`button`,className:`btn btn-secondary`,\"data-compact\":!0,disabled:de,onClick:()=>xe(`video`),children:de?`…`:`Clips`})]}),c,o.length>0&&(0,q.jsxs)(`div`,{style:J.sources,children:[(0,q.jsx)(`span`,{style:J.sourceLabel,children:`Cover`}),(0,q.jsx)(`input`,{style:J.numInput,type:`number`,min:`0`,step:`0.5`,placeholder:`start`,value:W.from,onChange:e=>pe(t=>({...t,from:e.target.value}))}),(0,q.jsx)(`span`,{style:J.sourceLabel,children:`to`}),(0,q.jsx)(`input`,{style:J.numInput,type:`number`,min:`0`,step:`0.5`,placeholder:`end`,value:W.to,onChange:e=>pe(t=>({...t,to:e.target.value}))}),(0,q.jsxs)(`span`,{style:J.sourceLabel,children:[`s `,W.from===``&&W.to===``?`(whole narration — ${Math.round(Se/1e3)}s)`:`(${Math.round(Ce/1e3)}s)`]})]}),ye.length>0&&(0,q.jsxs)(q.Fragment,{children:[(0,q.jsxs)(`div`,{style:J.visionHead,children:[(0,q.jsx)(`span`,{style:J.sourceLabel,children:`AI vision`}),(0,q.jsx)(Yi,{}),(0,q.jsx)(`span`,{style:{flex:1}}),(0,q.jsx)(`span`,{style:J.visionHint,children:`on = AI describes it (free) · off = use the text`})]}),(0,q.jsx)(`div`,{style:J.assetList,children:ye.slice(0,12).map(e=>(0,q.jsx)(Zi,{asset:e,value:R[e.id]??e.descriptor??``,visionOn:_e(e),onToggleVision:()=>ge(t=>({...t,[K(e)]:_e(e)})),onCommit:t=>z(n=>n[e.id]===t?n:{...n,[e.id]:t}),onPreview:G},e.id||e.url))})]}),we.suggestions.filter(e=>e.kind!==`cost`).map(e=>(0,q.jsx)(`div`,{style:J.note,children:e.message},e.kind)),(0,q.jsx)(`button`,{type:`button`,className:`btn btn-primary`,disabled:B||!ye.length,onClick:Ee,children:B?ee||`Building…`:`Build canvases (~${x[`canvasChat:build`]} cr)`}),k.current&&(0,q.jsx)(`button`,{type:`button`,className:`btn btn-secondary`,onClick:()=>{let e=k.current;e&&(e.abort(),k.current=null,V(!1),H(``))},children:`Cancel build`}),te?.length>0&&(0,q.jsxs)(`div`,{style:J.refine,children:[(0,q.jsx)(`input`,{style:J.editInput,placeholder:`Change something: \"make the first one bigger\", \"spread these out\"`,value:re,onChange:e=>ie(e.target.value),onKeyDown:e=>{e.key===`Enter`&&De()}}),(0,q.jsx)(`button`,{type:`button`,className:`btn btn-secondary`,\"data-compact\":!0,disabled:B||!r,onClick:De,children:`Apply`}),j.current&&(0,q.jsxs)(q.Fragment,{children:[(0,q.jsx)(`span`,{role:`status`,children:ee||`Applying edit…`}),(0,q.jsx)(`button`,{type:`button`,className:`btn btn-secondary`,onClick:()=>{let e=j.current;e&&(e.abort(),j.current=null,V(!1),H(``))},children:`Cancel edit`})]})]}),(0,q.jsx)(Ji,{asset:me,onClose:()=>G(null)})]})}function $i(e,t=[]){let n=String(e||``).toLowerCase(),r=t[0],i=/\\b(first|1st)\\b/.test(n)?t[0]:/\\b(second|2nd)\\b/.test(n)?t[1]:/\\b(third|3rd)\\b/.test(n)?t[2]:/\\b(last)\\b/.test(n)?t[t.length-1]:null,a=[];/\\bbigger|larger\\b/.test(n)&&a.push({kind:`resize`,panelId:i||r,direction:`bigger`}),/\\bsmaller\\b/.test(n)&&a.push({kind:`resize`,panelId:i||r,direction:`smaller`}),/\\bspread\\b/.test(n)&&(i?[i]:t).forEach(e=>a.push({kind:`spread`,panelId:e}));let o=n.match(/transition (?:to )?(\\w+)/);return o&&(i?[i]:t).forEach(e=>a.push({kind:`transition`,panelId:e,transition:o[1]})),a}let J={wrap:{display:`flex`,flexDirection:`column`,gap:8,padding:12,border:`1px solid var(--border)`,borderRadius:10,background:`var(--bg-secondary)`,width:`100%`,maxWidth:460,boxSizing:`border-box`},head:{fontSize:13,fontWeight:700,color:`var(--text-primary)`},intent:{minHeight:54,resize:`vertical`,fontSize:12.5,padding:8,borderRadius:8,background:`var(--bg-tertiary)`,borderWidth:1,borderStyle:`solid`,borderColor:`var(--border)`,color:`var(--text-primary)`,fontFamily:`var(--font)`},drop:{display:`block`,textAlign:`center`,padding:`12px 10px`,fontSize:12,color:`var(--text-secondary)`,background:`var(--bg-tertiary)`,borderWidth:1,borderStyle:`dashed`,borderColor:`var(--border-strong, var(--border))`,borderRadius:8,cursor:`pointer`},sources:{display:`flex`,alignItems:`center`,gap:6,flexWrap:`wrap`},numInput:{width:62,fontSize:12,padding:`4px 6px`,borderRadius:6,background:`var(--bg-tertiary)`,borderWidth:1,borderStyle:`solid`,borderColor:`var(--border)`,color:`var(--text-primary)`,fontFamily:`var(--font)`},sourceLabel:{fontSize:11.5,color:`var(--text-secondary)`},chip:{fontSize:11.5,padding:`3px 9px`,borderRadius:999,background:`var(--bg-tertiary)`,borderWidth:1,borderStyle:`solid`,borderColor:`var(--border)`,color:`var(--text-muted)`,cursor:`pointer`},chipOn:{borderColor:`var(--accent)`,color:`var(--accent)`},assetList:{display:`flex`,flexDirection:`column`,gap:4,maxHeight:190,overflowY:`auto`},assetRow:{display:`flex`,alignItems:`center`,gap:8},assetThumb:{position:`relative`,width:40,height:28,flexShrink:0,borderRadius:6,overflow:`hidden`,background:`var(--bg-elevated)`,border:`1px solid var(--border)`,display:`flex`,alignItems:`center`,justifyContent:`center`,padding:0,cursor:`pointer`},thumbImg:{width:`100%`,height:`100%`,objectFit:`cover`,display:`block`},thumbPlay:{width:0,height:0,borderStyle:`solid`,borderWidth:`5px 0 5px 8px`,borderColor:`transparent transparent transparent var(--text-secondary)`,marginLeft:2},descInput:{flex:1,minWidth:0,fontSize:12,padding:`4px 7px`,borderRadius:6,background:`var(--bg-tertiary)`,borderWidth:1,borderStyle:`solid`,borderColor:`var(--border)`,color:`var(--text-primary)`,fontFamily:`var(--font)`},note:{fontSize:11.5,lineHeight:1.45,color:`var(--text-secondary)`},refine:{display:`flex`,gap:6,alignItems:`center`},editInput:{flex:1,minWidth:0,fontSize:12,padding:`5px 8px`,borderRadius:6,background:`var(--bg-tertiary)`,borderWidth:1,borderStyle:`solid`,borderColor:`var(--border)`,color:`var(--text-primary)`,fontFamily:`var(--font)`},visionHead:{display:`flex`,alignItems:`center`,gap:6,marginTop:2},visionHint:{fontSize:10.5,color:`var(--text-muted)`},switch:{position:`relative`,width:30,height:16,flexShrink:0,borderRadius:999,background:`var(--bg-elevated)`,borderWidth:1,borderStyle:`solid`,borderColor:`var(--border)`,cursor:`pointer`,padding:0,transition:`background 0.15s, border-color 0.15s`},switchOn:{background:`var(--accent)`,borderColor:`var(--accent)`},knob:{position:`absolute`,top:1,left:1,width:12,height:12,borderRadius:`50%`,background:`var(--text-muted)`,transition:`transform 0.15s, background 0.15s`},knobOn:{transform:`translateX(14px)`,background:`var(--bg-primary, #fff)`},infoGlyph:{width:15,height:15,borderRadius:`50%`,border:`1px solid var(--border-strong, var(--border))`,background:`transparent`,color:`var(--text-muted)`,fontSize:10,fontWeight:700,lineHeight:`13px`,textAlign:`center`,cursor:`help`,padding:0,fontFamily:`Georgia, serif`,fontStyle:`italic`},infoTip:{position:`absolute`,left:`calc(100% + 8px)`,top:-4,width:250,padding:`8px 10px`,background:`var(--bg-elevated)`,border:`1px solid var(--border-strong, var(--border))`,borderRadius:8,boxShadow:`0 8px 24px rgba(0,0,0,0.4)`,fontSize:11.5,lineHeight:1.45,color:`var(--text-secondary)`,textAlign:`left`,zIndex:4001,pointerEvents:`none`}},ea=[`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`],ta={cx:12,cy:12,r:1.8},na=[`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`],ra={cx:17.5,cy:18,r:1.3};function ia(e){switch(e){case`minus`:return(0,q.jsx)(`path`,{d:`M5 12h14`});case`messageCircle`:return(0,q.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,q.jsx)(`path`,{d:`M20 12H4M11 5l-7 7 7 7`});case`link`:return(0,q.jsxs)(q.Fragment,{children:[(0,q.jsx)(`path`,{d:`M10 13a5 5 0 0 0 7 .5l3-3a5 5 0 0 0-7-7l-2 2`}),(0,q.jsx)(`path`,{d:`M14 11a5 5 0 0 0-7-.5l-3 3a5 5 0 0 0 7 7l2-2`})]});case`unlink`:return(0,q.jsxs)(q.Fragment,{children:[(0,q.jsx)(`path`,{d:`m18.8 12.3 1.7-1.7a5 5 0 0 0-7.1-7.1l-1.7 1.7`}),(0,q.jsx)(`path`,{d:`m5.2 11.7-1.7 1.7a5 5 0 0 0 7.1 7.1l1.7-1.7`}),(0,q.jsx)(`path`,{d:`M8 2v3M2 8h3M16 19v3M19 16h3`})]});case`copy`:return(0,q.jsxs)(q.Fragment,{children:[(0,q.jsx)(`rect`,{x:`9`,y:`9`,width:`12`,height:`12`,rx:`2`}),(0,q.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,q.jsx)(`path`,{d:`M12 20V4M5 11l7-7 7 7`});case`star`:return(0,q.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,q.jsx)(`path`,{d:`M7 17 17 7M8 7h9v9`});case`arrowDown`:return(0,q.jsx)(`path`,{d:`M12 4v16M5 13l7 7 7-7`});case`thumbsUp`:return(0,q.jsxs)(q.Fragment,{children:[(0,q.jsx)(`path`,{d:`M7 10v11H3V10Z`}),(0,q.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,q.jsxs)(q.Fragment,{children:[(0,q.jsx)(`path`,{d:`M7 14V3H3v11Z`}),(0,q.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,q.jsx)(`path`,{d:`M3 10h11a7 7 0 0 1 0 14M3 10l5-5M3 10l5 5`,transform:`translate(0 -3)`});case`redo`:return(0,q.jsx)(`path`,{d:`M21 7H10a7 7 0 0 0 0 14M21 7l-5-5M21 7l-5 5`});case`remix`:return(0,q.jsxs)(q.Fragment,{children:[(0,q.jsx)(`path`,{d:`M5 5h5a5 5 0 0 1 5 5v9`}),(0,q.jsx)(`path`,{d:`m11 15 4 4 4-4`}),(0,q.jsx)(`path`,{d:`M5 19h2`}),(0,q.jsx)(`circle`,{cx:`5`,cy:`5`,r:`2`}),(0,q.jsx)(`circle`,{cx:`5`,cy:`19`,r:`2`})]});case`more`:return(0,q.jsxs)(q.Fragment,{children:[(0,q.jsx)(`circle`,{cx:`5`,cy:`12`,r:`1`}),(0,q.jsx)(`circle`,{cx:`12`,cy:`12`,r:`1`}),(0,q.jsx)(`circle`,{cx:`19`,cy:`12`,r:`1`})]});case`palette`:return(0,q.jsxs)(q.Fragment,{children:[(0,q.jsx)(`circle`,{cx:`13.5`,cy:`6.5`,r:`.6`,fill:`currentColor`,stroke:`none`}),(0,q.jsx)(`circle`,{cx:`17`,cy:`11`,r:`.6`,fill:`currentColor`,stroke:`none`}),(0,q.jsx)(`circle`,{cx:`8.5`,cy:`7.5`,r:`.6`,fill:`currentColor`,stroke:`none`}),(0,q.jsx)(`circle`,{cx:`6.5`,cy:`12.5`,r:`.6`,fill:`currentColor`,stroke:`none`}),(0,q.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,q.jsxs)(q.Fragment,{children:[(0,q.jsx)(`rect`,{x:`5`,y:`11`,width:`14`,height:`10`,rx:`2`}),(0,q.jsx)(`path`,{d:`M8 11V7a4 4 0 0 1 8 0v4`})]});case`unlock`:return(0,q.jsxs)(q.Fragment,{children:[(0,q.jsx)(`rect`,{x:`5`,y:`11`,width:`14`,height:`10`,rx:`2`}),(0,q.jsx)(`path`,{d:`M8 11V7a4 4 0 0 1 7.9-1`})]});case`pushpin`:return(0,q.jsxs)(`g`,{transform:`rotate(35 12 12)`,children:[(0,q.jsx)(`path`,{d:`M8 3h8l-1 6 3 3v2H6v-2l3-3Z`}),(0,q.jsx)(`path`,{d:`M12 14v7`})]});case`pushpinFilled`:return(0,q.jsxs)(q.Fragment,{children:[(0,q.jsx)(`path`,{d:`M8 3h8l-1 6 3 3v2H6v-2l3-3Z`,fill:`currentColor`}),(0,q.jsx)(`path`,{d:`M12 14v7`})]});case`pin`:return(0,q.jsxs)(q.Fragment,{children:[(0,q.jsx)(`path`,{d:`M12 21s7-5.7 7-11a7 7 0 0 0-14 0c0 5.3 7 11 7 11Z`}),(0,q.jsx)(`circle`,{cx:`12`,cy:`10`,r:`2.5`})]});case`user`:return(0,q.jsxs)(q.Fragment,{children:[(0,q.jsx)(`circle`,{cx:`12`,cy:`8`,r:`4`}),(0,q.jsx)(`path`,{d:`M5 21a7 7 0 0 1 14 0`})]});case`image`:return(0,q.jsxs)(q.Fragment,{children:[(0,q.jsx)(`rect`,{x:`3`,y:`3`,width:`18`,height:`18`,rx:`2`}),(0,q.jsx)(`circle`,{cx:`8.5`,cy:`8.5`,r:`1.5`}),(0,q.jsx)(`path`,{d:`m21 15-5-5L5 21`})]});case`imageOff`:return(0,q.jsxs)(q.Fragment,{children:[(0,q.jsx)(`path`,{d:`M2 2l20 20`}),(0,q.jsx)(`path`,{d:`M10.41 10.41a2 2 0 1 1-2.83-2.83`}),(0,q.jsx)(`path`,{d:`M13.5 13.5 6 21`}),(0,q.jsx)(`path`,{d:`m18 12 3 3`}),(0,q.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,q.jsx)(`path`,{d:`M21 15V5a2 2 0 0 0-2-2H9`})]});case`film`:return(0,q.jsxs)(q.Fragment,{children:[(0,q.jsx)(`rect`,{x:`3`,y:`3`,width:`18`,height:`18`,rx:`2`}),(0,q.jsx)(`path`,{d:`M7 3v18M17 3v18M3 8h4M3 16h4M17 8h4M17 16h4`})]});case`folder`:return(0,q.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,q.jsx)(`path`,{d:`M9 6h12M9 12h12M9 18h12M4 6h.01M4 12h.01M4 18h.01`});case`grid`:return(0,q.jsxs)(q.Fragment,{children:[(0,q.jsx)(`rect`,{x:`3`,y:`3`,width:`7`,height:`7`,rx:`1.5`}),(0,q.jsx)(`rect`,{x:`14`,y:`3`,width:`7`,height:`7`,rx:`1.5`}),(0,q.jsx)(`rect`,{x:`3`,y:`14`,width:`7`,height:`7`,rx:`1.5`}),(0,q.jsx)(`rect`,{x:`14`,y:`14`,width:`7`,height:`7`,rx:`1.5`})]});case`zap`:return(0,q.jsx)(`path`,{d:`M13 2 4 14h7l-1 8 9-12h-7Z`});case`plug`:return(0,q.jsxs)(q.Fragment,{children:[(0,q.jsx)(`path`,{d:`M12 22v-5M9 8V2M15 8V2`}),(0,q.jsx)(`path`,{d:`M18 8v5a4 4 0 0 1-4 4h-4a4 4 0 0 1-4-4V8Z`})]});case`book`:return(0,q.jsxs)(q.Fragment,{children:[(0,q.jsx)(`path`,{d:`M4 19.5A2.5 2.5 0 0 1 6.5 17H20`}),(0,q.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,q.jsxs)(q.Fragment,{children:[(0,q.jsx)(`path`,{d:`M12 7v14`}),(0,q.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,q.jsxs)(q.Fragment,{children:[(0,q.jsx)(`path`,{d:`M15 3h4a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2h-4`}),(0,q.jsx)(`path`,{d:`m10 17 5-5-5-5`}),(0,q.jsx)(`path`,{d:`M15 12H3`})]});case`upload`:return(0,q.jsxs)(q.Fragment,{children:[(0,q.jsx)(`path`,{d:`M12 16V4M7 9l5-5 5 5`}),(0,q.jsx)(`path`,{d:`M5 20h14`})]});case`download`:return(0,q.jsxs)(q.Fragment,{children:[(0,q.jsx)(`path`,{d:`M12 4v12M7 11l5 5 5-5`}),(0,q.jsx)(`path`,{d:`M5 20h14`})]});case`save`:return(0,q.jsxs)(q.Fragment,{children:[(0,q.jsx)(`path`,{d:`M5 3h11l3 3v15H5Z`}),(0,q.jsx)(`path`,{d:`M8 3v5h7M8 21v-7h8v7`})]});case`search`:return(0,q.jsxs)(q.Fragment,{children:[(0,q.jsx)(`circle`,{cx:`11`,cy:`11`,r:`7`}),(0,q.jsx)(`path`,{d:`m20 20-3.5-3.5`})]});case`magnet`:return(0,q.jsxs)(q.Fragment,{children:[(0,q.jsx)(`path`,{d:`M6 4h4v8a2 2 0 0 0 4 0V4h4v8a6 6 0 0 1-12 0Z`}),(0,q.jsx)(`path`,{d:`M6 8h4M14 8h4`})]});case`bot`:return(0,q.jsxs)(q.Fragment,{children:[(0,q.jsx)(`rect`,{x:`4`,y:`8`,width:`16`,height:`11`,rx:`2`}),(0,q.jsx)(`path`,{d:`M12 8V4M9 13h.01M15 13h.01M9 16h6`})]});case`note`:return(0,q.jsxs)(q.Fragment,{children:[(0,q.jsx)(`rect`,{x:`4`,y:`3`,width:`16`,height:`18`,rx:`2`}),(0,q.jsx)(`path`,{d:`M8 8h8M8 12h8M8 16h5`})]});case`clock`:return(0,q.jsxs)(q.Fragment,{children:[(0,q.jsx)(`circle`,{cx:`12`,cy:`12`,r:`9`}),(0,q.jsx)(`path`,{d:`M12 7v5l3 2`})]});case`calendar`:return(0,q.jsxs)(q.Fragment,{children:[(0,q.jsx)(`rect`,{x:`3`,y:`5`,width:`18`,height:`16`,rx:`2`}),(0,q.jsx)(`path`,{d:`M16 3v4M8 3v4M3 10h18`})]});case`hourglass`:return(0,q.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,q.jsxs)(q.Fragment,{children:[(0,q.jsx)(`path`,{d:`M12 20h9`}),(0,q.jsx)(`path`,{d:`M16.5 3.5a2.1 2.1 0 0 1 3 3L7 19l-4 1 1-4Z`})]});case`music`:return(0,q.jsxs)(q.Fragment,{children:[(0,q.jsx)(`path`,{d:`M9 18V5l12-2v13`}),(0,q.jsx)(`circle`,{cx:`6`,cy:`18`,r:`3`}),(0,q.jsx)(`circle`,{cx:`18`,cy:`16`,r:`3`})]});case`mic`:return(0,q.jsxs)(q.Fragment,{children:[(0,q.jsx)(`rect`,{x:`9`,y:`2`,width:`6`,height:`13`,rx:`3`}),(0,q.jsx)(`path`,{d:`M19 10v2a7 7 0 0 1-14 0v-2`}),(0,q.jsx)(`path`,{d:`M12 19v3`})]});case`target`:return(0,q.jsxs)(q.Fragment,{children:[(0,q.jsx)(`circle`,{cx:`12`,cy:`12`,r:`9`}),(0,q.jsx)(`circle`,{cx:`12`,cy:`12`,r:`5`}),(0,q.jsx)(`circle`,{cx:`12`,cy:`12`,r:`1`,fill:`currentColor`,stroke:`none`})]});case`pointer`:return(0,q.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,q.jsxs)(q.Fragment,{children:[(0,q.jsx)(`path`,{d:`M12 21V9`}),(0,q.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,q.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,q.jsxs)(q.Fragment,{children:[(0,q.jsx)(`circle`,{cx:`6`,cy:`6`,r:`2.5`}),(0,q.jsx)(`circle`,{cx:`6`,cy:`18`,r:`2.5`}),(0,q.jsx)(`path`,{d:`M8 8l12 8M8 16 20 8`})]});case`maximize`:return(0,q.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,q.jsxs)(q.Fragment,{children:[(0,q.jsx)(`circle`,{cx:`12`,cy:`12`,r:`3`}),(0,q.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,q.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,q.jsxs)(q.Fragment,{children:[(0,q.jsx)(`rect`,{x:`3`,y:`3`,width:`18`,height:`18`,rx:`2`}),(0,q.jsx)(`path`,{d:`m8 12 3 3 5-6`})]});case`warning`:return(0,q.jsxs)(q.Fragment,{children:[(0,q.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,q.jsx)(`path`,{d:`M12 9v4M12 17h.01`})]});case`sparkle`:return(0,q.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,q.jsx)(`path`,{d:`m5 12 5 5 9-10`});case`x`:return(0,q.jsx)(`path`,{d:`M6 6 18 18M18 6 6 18`});case`plus`:return(0,q.jsx)(`path`,{d:`M12 5v14M5 12h14`});case`refresh`:return(0,q.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,q.jsx)(`path`,{d:`M7 4v16l13-8Z`});case`preview`:return(0,q.jsxs)(q.Fragment,{children:[ea.map(e=>(0,q.jsx)(`path`,{d:e},e)),(0,q.jsx)(`circle`,{...ta})]});case`listingPreview`:return(0,q.jsxs)(q.Fragment,{children:[na.map(e=>(0,q.jsx)(`path`,{d:e},e)),(0,q.jsx)(`circle`,{...ra})]});case`pause`:return(0,q.jsx)(`path`,{d:`M9 5v14M15 5v14`});case`playFilled`:return(0,q.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,q.jsxs)(q.Fragment,{children:[(0,q.jsx)(`rect`,{x:`6`,y:`4.5`,width:`4`,height:`15`,rx:`1`,fill:`currentColor`,stroke:`none`}),(0,q.jsx)(`rect`,{x:`14`,y:`4.5`,width:`4`,height:`15`,rx:`1`,fill:`currentColor`,stroke:`none`})]});case`volume2`:return(0,q.jsxs)(q.Fragment,{children:[(0,q.jsx)(`path`,{d:`M11 5 6 9H2v6h4l5 4V5Z`,fill:`currentColor`}),(0,q.jsx)(`path`,{d:`M15.5 8.5a5 5 0 0 1 0 7M19 5a10 10 0 0 1 0 14`})]});case`volumeX`:return(0,q.jsxs)(q.Fragment,{children:[(0,q.jsx)(`path`,{d:`M11 5 6 9H2v6h4l5 4V5Z`,fill:`currentColor`}),(0,q.jsx)(`path`,{d:`m22 9-6 6M16 9l6 6`})]});case`minimize`:return(0,q.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,q.jsx)(`rect`,{x:`6`,y:`6`,width:`12`,height:`12`,rx:`2`});case`chevronRight`:return(0,q.jsx)(`path`,{d:`m9 6 6 6-6 6`});case`chevronLeft`:return(0,q.jsx)(`path`,{d:`m15 6-6 6 6 6`});case`chevronDown`:return(0,q.jsx)(`path`,{d:`m6 9 6 6 6-6`});case`trash`:return(0,q.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,q.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,q.jsx)(`path`,{d:`M4 6V4h16v2M12 4v16M9 20h6`});case`home`:return(0,q.jsxs)(q.Fragment,{children:[(0,q.jsx)(`path`,{d:`M3 10.5 12 3l9 7.5`}),(0,q.jsx)(`path`,{d:`M5 9.5V20a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1V9.5`}),(0,q.jsx)(`path`,{d:`M9 21v-6h6v6`})]});case`menu`:return(0,q.jsx)(`path`,{d:`M4 6h16M4 12h16M4 18h16`});case`logout`:return(0,q.jsxs)(q.Fragment,{children:[(0,q.jsx)(`path`,{d:`M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4`}),(0,q.jsx)(`path`,{d:`M16 17l5-5-5-5`}),(0,q.jsx)(`path`,{d:`M21 12H9`})]});case`help`:return(0,q.jsxs)(q.Fragment,{children:[(0,q.jsx)(`circle`,{cx:`12`,cy:`12`,r:`9`}),(0,q.jsx)(`path`,{d:`M9.1 9a3 3 0 0 1 5.8 1c0 2-3 3-3 3`}),(0,q.jsx)(`path`,{d:`M12 17h.01`})]});case`bug`:return(0,q.jsxs)(q.Fragment,{children:[(0,q.jsx)(`path`,{d:`m8 2 1.9 1.9M14.1 3.9 16 2`}),(0,q.jsx)(`path`,{d:`M9 7.1v-1a3 3 0 1 1 6 0v1`}),(0,q.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,q.jsx)(`path`,{d:`M12 20v-9`}),(0,q.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 aa({name:e,size:t=`1em`,style:n,className:r,strokeWidth:i=1.5}){let a=ia(e);return a?(0,q.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}function oa(e){return N(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 sa=()=>Object.assign(Error(`The Canvas or account changed. Choose media again.`),{name:`AbortError`});function ca({host:e,doc:t,projectId:n,panelId:r,canEdit:i}){let a=oa(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 sa();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 sa()};f(),c.current=u;try{return await e({signal:u.signal,assertCurrent:f})}finally{c.current===u&&(c.current=null)}},actor:o}}let la={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 ua(e,t,n){let r=e.strip.find(e=>e.panelId===t);N(r?.type===`canvas`&&P(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`?N(Object.keys(n).length===2&&(i||Pe.some(e=>e.value===n.value)),`CANVAS_BACKGROUND`,`Choose a background preset or colour.`):N(Object.keys(n).length===3&&i&&Number.isSafeInteger(n.slot)&&n.slot>=0&&we(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),N(JSON.stringify(a).length<=4096,`CANVAS_BACKGROUND`,`The saved background is too large.`),{panel:r,input:a}}function da(e,{panel:t,input:n},r){let i=n.command,a=i.kind===`color`?Ee(t.background,i.slot,i.value):i.value,o={strip:[{...n.doc.strip[0],background:a,provenance:`user`}]};if(B(r),N(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 fa({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;N(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=ua(i.doc,i.panelId,r);f();let t=await c.run(la,{kind:`run`,input:e.input,signal:s.signal,timeoutMs:15e3});f();let n=da(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 pa={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:[]},ma=(e,t)=>e===void 0||t===void 0?e===t:V(e)===V(t);function ha(e,t,n){let r=e.strip.find(e=>e.panelId===t);N(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).`),N(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=P(e.pos)?{x:e.pos.x,y:e.pos.y}:e.pos),n})},aspect:n};return B(i),N(JSON.stringify(i).length<=1048576,`CANVAS_TIDY`,`This layout is too large to arrange.`),{panel:r,input:i}}function ga(e,{panel:t,input:n},r){let i=Be({...n.panel,autoArrange:!0},{aspect:n.aspect}),a={...n.panel,elements:i.elements,provenance:`user`};B(a),B(r),N(ma(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||ma(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 _a({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;N(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=ha(i.doc,i.panelId,r);f();let t=await c.run(pa,{kind:`run`,input:e.input,signal:s.signal,timeoutMs:15e3});f();let n=ga(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 va={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:[]},ya=(e,t)=>e===void 0||t===void 0?e===t:V(e)===V(t),ba=[`kind`,`appearMs`,`leaveMs`,`entrance`,`wordTimes`],xa=e=>JSON.parse(JSON.stringify(e,(e,t)=>(N(typeof t!=`number`||Number.isFinite(t),`CANVAS_CONTINUATION`,`Timing must remain finite.`),t)));function Sa(e,t,n){let r=e.strip.find(e=>e.panelId===t);N(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(ba.filter(t=>e[t]!==void 0).map(t=>[t,e[t]]))}))}:{}})),a=xa({doc:{strip:i},panelId:t,mode:n.mode,atMs:n.atMs??null,options:n.options??null});B(a),N([`continue`,`handoff`].includes(a.mode)&&JSON.stringify(a).length<=1048576,`CANVAS_CONTINUATION`,`This continuation is too large.`),a.options!==null&&N(P(a.options)&&Object.keys(a.options).every(e=>[`exit`,`arrive`].includes(e)),`CANVAS_CONTINUATION`,`Choose handoff settings.`);let o=a.options||{};return N((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 Ca(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`;N(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 xa({...e.doc,strip:e.doc.strip.flatMap((e,i)=>i===t?[{...n,durationMs:r,elements:c},u]:[e])})}function wa(e,{panel:t,input:n},r){let i=Ca(n);if(B(i),B(r),N(ya(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},ya(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)&&(ya(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 Ta({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;N(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=Sa(i.doc,i.panelId,r);f();let t=await c.run(va,{kind:`run`,input:e.input,signal:s.signal,timeoutMs:15e3});f();let n=wa(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 Ea={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:[]},Da=(e,t)=>V(e)===V(t),Oa=[`pos`,`box`,`size`,`tilt`,`weight`],ka=[`id`,`kind`,`pinned`,`appearMs`,`leaveMs`,...Oa],Aa=new Set([`src`,`poster`,`source`,`query`,`text`,`pose`,`cutout`,`durationSec`,`sfx`,`entrance`,`shadow`,`font`,`color`,`anim`,`loop`,`muted`,`trimStartSec`,`speed`,`motion`,`pinned`,`appearMs`,`leaveMs`,...Oa]),ja=(e,t)=>e===`pos`&&P(t)?{x:t.x,y:t.y}:e===`box`&&P(t)?{w:t.w,h:t.h}:t;function Ma(e,t,n,r,i){let a=e.strip.find(e=>e.panelId===t);N(a?.type===`canvas`&&Array.isArray(a.elements)&&typeof n==`string`&&P(r)&&Object.keys(r).every(e=>Aa.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]=ka.includes(e)?ja(e,t):{patchToken:e};let c={panelId:t,type:`canvas`,elements:a.elements.map((e,t)=>{let n={origin:t};for(let t of ka)e[t]!==void 0&&(n[t]=ja(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 Na(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=ut(t.template);if(i){let e=ft(n.elements,i,{aspect:r}),t=ze({...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=Be(n,{aspect:r}))}return{...e.doc,strip:[n]}}function Pa(e,{panel:t,input:n,captured:r},i){let a=Na(n);B(a),B(i),N(Da(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([...Oa,...u?Object.keys(r):[]])){let i=Object.hasOwn(l,t),a=e[t];u&&Object.hasOwn(r,t)&&!Oa.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&&!Da(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 Fa({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;N(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=Ma(s.doc,s.panelId,r,i,a);b();let t=await c.run(Ea,{kind:`run`,input:e.input,signal:f.signal,timeoutMs:15e3});b();let n=Pa(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 Ia=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 La(e){return N(e?.version===1&&Ia.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 Ra=null;function za(e){return Ra=Object.freeze(La(e)),Ra}function Ba(){if(!Ra)throw Object.assign(Error(`Shared native runtime host is unavailable.`),{code:`HOST_SERVICES`});return Ra}let Va=e=>(...t)=>Ba()[e](...t),Ha=Va(`getAllAssets`);Object.freeze({confirm:Va(`confirm`),alert:Va(`alert`)});let Ua=Object.freeze(Object.fromEntries([`success`,`error`,`info`,`warning`].map(e=>[e,(...t)=>Ba().toast[e]?.(...t)])));new Proxy({},{get:(e,t)=>typeof t==`symbol`||Reflect.has(e,t)?Reflect.get(e,t):Ba().upgradeReasons[t]});function Wa(e){let t=Ba().CanvasCommitInput;return(0,q.jsx)(t,{...e})}let Ga={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:[]},Ka=(e,t)=>V(e)===V(t);function qa(e,t){let n=e.strip.find(e=>e.panelId===t);N(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});N(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 Ja(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 Ya(e,{panel:t,input:n},r){let i=Ja(n);if(B(i),B(r),N(Ka(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&&Ka(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 Xa({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;N(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=qa(e.doc,e.panelId);i();let o=await c.run(Ga,{kind:`run`,input:a.input,signal:n.signal,timeoutMs:15e3});i();let s=Ya(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 Za={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:[]},Qa=(e,t)=>V(e)===V(t),$a=[`id`,`kind`,`pinned`,`appearMs`,`leaveMs`,`pos`,`box`,`size`,`tilt`,`weight`],eo=[`pos`,`box`,`size`,`tilt`,`weight`];function to(e,t,n){let r=e.strip.find(e=>e.panelId===t);N(r?.type===`canvas`,`CANVAS_TEMPLATE`,`This canvas is no longer available.`),N(typeof n==`string`&&(!n||ut(n)),`CANVAS_TEMPLATE`,`Choose an available canvas template.`);let i={panelId:t,elements:(r.elements||[]).map(e=>{let t={};for(let n of $a)if(e[n]!==void 0){let r=e[n];t[n]=n===`pos`&&P(r)?{x:r.x,y:r.y}:n===`box`&&P(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 no(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=ft(t.elements,null));let o=e.doc.meta.aspect===`9:16`?9/16:e.doc.meta.aspect===`1:1`?1:16/9,s=ut(n);if(s){let e=ft(a.elements,s,{aspect:o}),t=ze({...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=Be(a,{aspect:o}));return{...e.doc,strip:[a]}}function ro(e,{panel:t,input:n},r){let i=no(n);if(B(i),B(r),N(Qa(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`)||!Qa(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 eo){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&&!Qa(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 io({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;N(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=to(t.doc,t.panelId,e||``);a();let s=await c.run(Za,{kind:`run`,input:o.input,signal:r.signal,timeoutMs:15e3});a();let u=ro(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 ao={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 oo(e){return N(e?.version===1&&typeof e.insert==`function`,`HOST_SERVICES`,`Presenter insertion requires its version 1 broker.`),e}function so(e){let t=H(e),n=()=>t.actor();return Object.freeze(oo({version:1,async insert(e,r,i,a,{signal:o,assertCurrent:s}={}){let c=V({doc:e,pose:i}),l=n(),u=()=>{s?.(),N(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);N(d?.length===1&&d[0].type===`canvas`&&Array.isArray(d[0].elements)&&d[0].elements.length<=4096&&P(i)&&Number.isFinite(a),`PRESENTER_INSERTION`,`Choose a valid canvas pose and time.`),N(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),N(JSON.stringify(p).length<=16384,`PRESENTER_INSERTION`,`Pose metadata is too large.`);let m=await t.run(ao,{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),N(V(v)===V(_),`PRESENTER_INSERTION`,`The sandbox changed the selected pose, timing or placement.`),u(),await En(e,r,{...v,src:f},{host:t,signal:o,assertCurrent:u,validateDocument:Zt})}}))}let co={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:[]},lo=(e,t)=>V(e)===V(t),uo=[`atMs`,`durMs`,`ease`,`pos`,`size`];function fo(e,t,n,r,i,a,o){let s=e.strip.find(e=>e.panelId===t);N(s?.type===`canvas`,`KEYFRAME`,`This canvas is no longer available.`),N([`set`,`remove`].includes(r)&&Number.isFinite(i)&&Number.isInteger(o)&&P(a)&&Object.keys(a).every(e=>[`pos`,`size`].includes(e)),`KEYFRAME`,`The requested keyframe edit is invalid.`),a.pos!==void 0&&N(P(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&&N(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 uo)e[t]!==void 0&&(n[t]=t===`pos`&&P(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 po(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 mo(e,{panel:t,input:n},r){let i=po(n);B(i),B(r),N(lo(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(lo(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 uo)lo(e[t]??null,r[t]??null)||(a[t]=e[t],l=!0);return s&&e.origin===c&&!lo(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 ho({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;N(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=fo(a.doc,a.panelId,e,t,n,r,i);v();let d=await c.run(co,{kind:`run`,input:o.input,signal:u.signal,timeoutMs:15e3});v();let m=mo(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 go(e,t,n={}){let r=So(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 _o=.5,vo=.34,yo=.66;function bo(e,t){let n=Math.max(0,Math.min(1,e)),r,i;return n<vo?(r=1-n/vo*.5,i=.5):n<yo?(r=_o,i=.5+t*((n-vo)/.32)):(r=_o+.5*((n-yo)/.33999999999999997),i=.5+t),{outScale:r,outOff:r*(.5-i)*100,outA:1,inScale:r,inOff:r*(.5+t-i)*100,inA:1}}let xo={\"Zoom left\":[`tx`,1],\"Zoom right\":[`tx`,-1],\"Zoom up\":[`ty`,1],\"Zoom down\":[`ty`,-1]};function So(e,t){if(xo[e]){let[n,r]=xo[e],i=bo(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 Co(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 wo=(e,t,n)=>Math.min(n,Math.max(t,e)),To=e=>{let t=wo(e,0,1);return t*t*(3-2*t)};function Eo(e){let t=wo(e,0,1);return 1+2.70158*(t-1)**3+1.70158*(t-1)**2}let Do=.6,Oo=.42,ko=.18,Ao=.45;function jo(e,t){let n=Math.max(1e-4,Number(t)||0),r=wo(Number(e)||0,0,n),i=1,a=1;r<Oo&&(i=Eo(r/Oo),a=To(r/.16));let o=1;if(r>=.6&&r<=.78){let e=(r-Do)/ko;o=1-.1*Math.sin(Math.PI*e)}let s=0;if(r>=.6&&r<=1.1){let e=(r-Do)/.5;s=.35*Math.sin(e*Math.PI*4)*(1-e)}let c=1,l=1,u=0,d=n-Ao-.2;if(d>1&&r>d){let e=To((r-d)/Ao);l=1-e,c=1+.12*Math.sin(e*Math.PI),u=e*.16,a*=1-To(wo((e-.45)/.55,0,1))}return{scale:wo(i,0,2),press:o,bell:s,opacity:wo(a,0,1),foldX:c,foldY:l,foldRot:u}}function Mo(e,t){let n=Math.max(1e-4,Number(t)||0),r=wo(Number(e)||0,0,n),i=To(wo((r-.1)/.5,0,1)),a=128+(1-i)*48,o=30+(1-i)*42,s=To(wo((r-.1)/.28,0,1)),c=Math.max(.8999999999999999,n-1);s*=To(wo((c-r)/.25,0,1));let l=0;return r>=.6&&r<=.78&&(l=Math.sin((r-Do)/ko*Math.PI)),{x:a,y:o,click:l,opacity:wo(s,0,1)}}let No={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`}},Po=[`shape_sweep`,`shape_pop`],Fo=[`whip_crack`,`whip_zip`],Io=[`push_slide`,`push_thump`],Lo=Object.fromEntries(Object.entries({Swirl:[`whoosh`,`swirl_wind`],Morph:[`morph_warp`,`morph_bloom`],\"Shape wipe\":Po,Iris:Po,\"Ink splat\":Po,Slash:Po,Shred:Po,\"Whip pan\":Fo,\"Whip left\":Fo,\"Whip right\":Fo,\"Whip up\":Fo,\"Whip down\":Fo,\"Push left\":Io,\"Push right\":Io,\"Push up\":Io,\"Push down\":Io}).map(([e,t])=>[e,t[0]]));function Ro(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 zo(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 Bo(e){let t=2166136261,n=String(e||``);for(let e=0;e<n.length;e++)t^=n.charCodeAt(e),t=Math.imul(t,16777619);return t>>>0}function Y(e,t){let n=(e^Math.imul(t|0,2654435769))>>>0;return n=Math.imul(n^n>>>16,569420461)>>>0,n=Math.imul(n^n>>>15,1935289751)>>>0,n=(n^n>>>15)>>>0,n/4294967296}function Vo(e){let t=e>>>0;return function(){t=t+1831565813|0;let e=Math.imul(t^t>>>15,1|t);return e=e+Math.imul(e^e>>>7,61|e)^e,((e^e>>>14)>>>0)/4294967296}}let Ho=new Set([`shake`,`shake_flash`,`zoom_punch`,`blur_pulse`,`invert`,`rgb_split`,`chromatic`,`glitch`,`shockwave`]),Uo=new Set([`flash`,`shake_flash`,`freeze_flash`,`strobe`,`light_leak`,`scanline_hit`,`speed_lines`]),Wo=(e,t,n)=>Math.min(n,Math.max(t,e));function Go(e,t){return(Array.isArray(e)?e:[]).filter(e=>t>=(Number(e.start)||0)&&t<(Number(e.end)||0))}function Ko(e,t){return Go(e,t).filter(e=>Ho.has(e.kind))}function qo(e,t){return Go(e,t).filter(e=>Uo.has(e.kind))}function Jo(e,t){let n=Number(e.start)||0,r=Number(e.end)||0,i=Math.max(1e-4,r-n),a=Wo(Math.round(Number(e.repeat)||1),1,6),o=Wo((t-n)/i,0,.9999),s=Math.min(a-1,Math.floor(o*a));return{k:s,p:Wo(o*a-s,0,1),pAll:o,repeat:a}}function Yo(e,t,n=60){return Math.max(0,Math.floor((t-(Number(e.start)||0))*n))}let Xo=e=>Bo(e.id||e.kind||`fx`),Zo=e=>Wo(Number(e.intensity??.6),0,1),Qo=e=>(1-e)**1.5;function $o(e,t){let n=Zo(e),{p:r}=Jo(e,t),i=Yo(e,t),a=Xo(e),o=.02*n*Qo(r);return{dx:o*(2*Y(a,i*2)-1),dy:o*(2*Y(a,i*2+1)-1),rot:.5*n*Qo(r)*(2*Y(a,i*2+7)-1)}}function es(e,t){let n=Zo(e),{p:r}=Jo(e,t),i=.28*n;return{scale:r<.18?1+r/.18*i:1+i*(1-(r-.18)/.82)**2}}function ts(e,t){let{p:n}=Jo(e,t);return 14*Zo(e)*Math.sin(Math.PI*n)}function ns(e,t){return Jo(e,t).p<.4}let rs=[`#00ffd0`,`#ff2bd1`,`#2b6bff`,`#c8ff00`];function is(e,t){let n=Zo(e),r=Yo(e,t),i=Xo(e),a=.01*n*(2*Y(i,r*3)-1),o=.006*n*(2*Y(i,r*3+1)-1),s=3+Math.round(6*n),c=[];for(let e=0;e<s;e++)c.push({y:Y(i,r*31+e*3),h:.01+.05*Y(i,r*31+e*3+1),dx:(Y(i,r*31+e*3+2)-.5)*.16*n});let l=Math.round(3*n*Y(i,r*7+5)),u=[];for(let e=0;e<l;e++)u.push({x:Y(i,r*53+e*4),y:Y(i,r*53+e*4+1),w:.02+.08*Y(i,r*53+e*4+2),h:.01+.03*Y(i,r*53+e*4+3),color:rs[Math.floor(Y(i,r*53+e*4+2)*rs.length)%rs.length]});return{jx:a,jy:o,slices:c,blocks:u,invertBand:Y(i,r)<.15*n?{y:Y(i,r*11+2),h:.06+.1*Y(i,r*11+3)}:null}}function as(e,t){let n=Zo(e),{p:r}=Jo(e,t);return{cx:Number(e.cx??.5),cy:Number(e.cy??.5),r:.05+.55*r,width:.05+.05*n,ringAlpha:.3*n*(1-r),refractScale:1+.06*n*(1-r)}}function os(e,t){let n=Zo(e),{p:r}=Jo(e,t);return e.kind===`strobe`?r<.5?.85*n:0:e.kind===`freeze_flash`?n*Math.max(0,1-r*1.6)**1.2:n*Math.sin(Math.PI*Math.min(1,r))**1.5}function ss(e){return typeof e.color==`string`&&/^#[0-9a-fA-F]{6}$/.test(e.color)?e.color:`#ffffff`}function cs(e,t){let n=Zo(e),{pAll:r}=Jo(e,t);return{cx:-.25+1.5*r,cy:.3+.15*Math.sin(r*Math.PI*2),radius:.55,alpha:.5*n*Math.sin(Math.PI*r),color:ss({color:e.color})===`#ffffff`?`#ffb36b`:e.color}}function ls(e,t){let n=Zo(e),{p:r}=Jo(e,t),i=Yo(e,t),a=Xo(e);return{alpha:.5*n*Math.sin(Math.PI*r),offsetY:Math.floor(Y(a,i)*3)}}function us(e,t){let n=Zo(e),{p:r}=Jo(e,t),i=Yo(e,t,30),a=Xo(e),o=Math.sin(Math.PI*Math.min(1,r)),s=[];for(let e=0;e<24;e++)s.push({angle:e/24*Math.PI*2+.13*Y(a,e),inner:.32+.1*Y(a,i*17+e),alpha:.35*n*o*(.6+.4*Y(a,i*23+e)),width:.006+.01*Y(a,e*5+1)});return{spokes:s}}function ds(e,t){let n=0,r=0,i=0,a=1;for(let o of e)if(o.kind===`shake`||o.kind===`shake_flash`){let e=$o(o,t);n+=e.dx,r+=e.dy,i+=e.rot}else if(o.kind===`zoom_punch`)a*=es(o,t).scale;else if(o.kind===`glitch`){let e=is(o,t);n+=e.jx,r+=e.jy}else if(o.kind===`shockwave`){let e=as(o,t);a*=1+(e.refractScale-1)*.15}let o=1+2*Math.max(Math.abs(n),Math.abs(r))+Math.max(0,a>1?0:1-a);return{dx:n,dy:r,rot:i,scale:a,pad:o}}function fs(e,t,n=1){let r=[],i=0,a=!1;for(let n of e)n.kind===`blur_pulse`?i+=ts(n,t):n.kind===`invert`&&ns(n,t)&&(a=!0);return i>.05&&r.push(`blur(${(i*n).toFixed(2)}px)`),a&&r.push(`invert(1)`),r.join(` `)}let ps=(e,t,n)=>Math.min(n,Math.max(t,e));function ms(e,t){return(Array.isArray(e)?e:[]).filter(e=>t>=(Number(e.start)||0)&&t<(Number(e.end)||0))}let hs=e=>ps(Number(e.intensity??.6),0,1),gs=e=>Bo(e.id||e.kind||`overlay`),_s=(e,t,n=60)=>Math.max(0,Math.floor((t-(Number(e.start)||0))*n));function vs(e,t){let n=gs(e),r=_s(e,t,30);return 1+.05*Math.sin(2*Math.PI*13*t)+.04*(Y(n,r)-.5)}function ys(e,t){let n=hs(e),r=gs(e),i=2+ +(Y(r,1)>.5),a=[`#ffb36b`,`#ff8f5a`,`#ffd9a0`];return Array.from({length:i},(e,i)=>({cx:.5+.38*Math.sin(.13*t+i*2.1+Y(r,i)*6),cy:.5+.3*Math.cos(.09*t+i*1.7+Y(r,i+9)*6),radius:.4+.25*Y(r,i+3),alpha:.18*n*(.7+.3*Math.sin(.21*t+i)),color:a[i%a.length]}))}function bs(e){let t=hs(e);return e.kind===`rain`?Math.round(80+120*t):e.kind===`snow`?Math.round(50+90*t):Math.round(15+40*t)}function xs(e,t,n){let r=gs(e),i=Y(r,t*4),a=Y(r,t*4+1),o=Y(r,t*4+2);if(e.kind===`rain`){let e=1.4+1.2*o;return{x:(i+.04*n)%1,y:(a+e*n)%1,size:.5+o,slant:.12}}if(e.kind===`snow`){let e=.06+.05*o;return{x:(i+.02*Math.sin(.7*n+t))%1,y:(a+e*n)%1,size:1+2*o,slant:0}}return{x:(i+.01*n*(.5+o)+.01*Math.sin(.4*n+t))%1,y:(a+.006*n+.008*Math.cos(.3*n+t*2))%1,size:.8+2.2*o,slant:0}}function Ss(e,t){let n=hs(e),r=gs(e),i=_s(e,t,24),a=.085*t%1.25-.125,o=2+Math.round(2*Y(r,i)),s=Array.from({length:o},(e,t)=>({y:Y(r,i*19+t*2),h:.015+.04*Y(r,i*19+t*2+1),dx:(Y(r,i*23+t)-.5)*8*n}));return{bandY:a,bandAlpha:.22*n,wobble:s,chromaPx:1.5+2.5*n,scanAlpha:.22*n}}function Cs(e,t){return(1+1.5*hs(e))*Math.sin(.9*t)}function ws(e,t){let n=hs(e);return Array.from({length:12},(e,r)=>({y0:r/12,y1:(r+1)/12,dx:2.5*n*Math.sin(2*Math.PI*.4*t+r*.9)}))}function Ts(e,t){let n=hs(e);return{bandY:.22*t%1.15-.075,bandAlpha:.3*n*vs(e,t),washAlpha:.05*n,scanAlpha:.16*n}}function Es(e,t){return .55*hs(e)*(.75+.25*Math.sin(2*Math.PI*t/3.5))}function Ds(e,t){let n=hs(e),r=gs(e),i=_s(e,t,12),a=1+Math.round(2*Y(r,i));return{scratches:Array.from({length:a},(e,t)=>({x:Y(r,i*13+t),alpha:.12*n*Y(r,i*17+t)})),flicker:.03*n*(Y(r,i)-.5)*2}}function Os(e,t){let n=hs(e),r=gs(e),i=_s(e,t,30);return{spokes:Array.from({length:30},(e,t)=>({angle:t/30*Math.PI*2+.11*Y(r,t),inner:.3+.12*Y(r,i*17+t),alpha:.28*n*(.5+.5*Y(r,i*23+t)),width:.005+.009*Y(r,t*7+2)})),ghost:n>=.5}}let ks=(e,t,n=12)=>Math.floor(e*n)%t,As=e=>Math.round((Number(e)||0)*100)/100,js=[`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`];({...Ms()}),{...Ms()},{...Ms()},{...Ms()},{...Ms()},{...Ms()},{...Ms()},{...Ms()},{...Ms()},{...Ms()};function Ms(){return{brightness:0,contrast:0,saturation:0,temperature:0,sharpness:0,vignette:0}}As(.47),Object.entries(No);let Ns=[{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 Ps(){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 Fs(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 Is=`aivw_fav_assets`;function Ls(){try{return new Set(JSON.parse(localStorage.getItem(Is)||`[]`))}catch{return new Set}}function Rs(e){try{localStorage.setItem(Is,JSON.stringify([...e]))}catch{}}function zs({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,q.jsxs)(`div`,{ref:c,style:{...Hs.cell,...o&&s?Hs.cellSelected:{}},title:`${e.name||`Asset`}${e.sub?` · ${e.sub}`:``}`,onClick:()=>n(e),children:[l&&e.url?(0,q.jsx)(`img`,{src:e.url,alt:``,style:Hs.thumb,loading:`lazy`}):(0,q.jsx)(`div`,{style:Hs.ph}),o&&(0,q.jsx)(`div`,{style:{...Hs.checkbox,...s?Hs.checkboxOn:{}},children:s?`✓`:``}),r&&(0,q.jsx)(`button`,{type:`button`,title:i?`Unfavorite`:`Favorite`,onClick:t=>{t.stopPropagation(),a(e)},style:{...Hs.star,color:i?`var(--signal)`:`var(--fg)`,opacity:i?1:.55},children:i?`★`:`☆`}),e.name&&(0,q.jsx)(`div`,{style:Hs.cap,children:e.name})]})}function Bs({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,q.jsx)(`input`,{type:`text`,value:t,onChange:e=>n(e.target.value),placeholder:`Search prompts, names…`,\"aria-label\":`Search assets`,style:Hs.search})}function Vs({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)(()=>Ls()),[d,f]=(0,v.useState)(!1),[p,m]=(0,v.useState)(``),[h,g]=(0,v.useState)(()=>new Set),_=e=>e.url||e.id,y=Fs(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),Rs(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,jn.createPortal)((0,q.jsx)(`div`,{style:Hs.overlay,className:`nodrag nopan nowheel`,...y,children:(0,q.jsxs)(`div`,{style:Hs.panel,onClick:e=>e.stopPropagation(),children:[(0,q.jsxs)(`div`,{style:Hs.head,children:[(0,q.jsxs)(`span`,{style:Hs.title,children:[e,i?` · loading…`:``,` `,x.length?`(${x.length})`:``]}),(0,q.jsxs)(`div`,{style:{display:`flex`,alignItems:`center`,gap:8},children:[(0,q.jsx)(Bs,{onChange:m}),o&&(0,q.jsx)(`button`,{type:`button`,onClick:()=>f(e=>!e),style:{...Hs.favToggle,...d?Hs.favToggleOn:{}},children:d?`★ Favorites`:`☆ Favorites`}),(0,q.jsx)(`button`,{type:`button`,style:Hs.close,onClick:r,\"aria-label\":`Close`,\"data-icon-action\":`true`,title:`Close`,children:(0,q.jsx)(aa,{name:`x`,size:18})})]})]}),(0,q.jsx)(`div`,{ref:c,style:Hs.body,children:x.length===0?(0,q.jsx)(`div`,{style:Hs.empty,children:i?`Loading…`:o&&d?`No favorites yet — tap the star on any asset.`:a}):(0,q.jsx)(`div`,{style:Hs.grid,children:x.map(e=>(0,q.jsx)(zs,{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,q.jsxs)(`div`,{style:Hs.footer,children:[(0,q.jsxs)(`span`,{style:Hs.footerCount,children:[h.size,` selected`]}),(0,q.jsxs)(`button`,{type:`button`,style:{...Hs.addBtn,...h.size?{}:Hs.addBtnDisabled},disabled:!h.size,onClick:()=>{n?.(x.filter(e=>h.has(_(e)))),r?.()},children:[`Add `,h.size||``]})]})]})}),document.body)}let Hs={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 Us(...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 Ws({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(Us(Ha()));let e=()=>s(Us(Ha()));return window.addEventListener(`aivw-assets-changed`,e),()=>window.removeEventListener(`aivw-assets-changed`,e)},[i]),(0,q.jsxs)(q.Fragment,{children:[(0,q.jsx)(`button`,{type:`button`,style:r||Gs,className:`nodrag nopan`,onClick:()=>a(!0),children:t}),i&&(0,q.jsx)(Vs,{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 Gs={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},Ks=new Map,qs=e=>`${e.id||``}|${e.src}`;function Js(e){let t=new Map,n=[],r=r=>{let i=qs(r),a=t.get(i);if(a)return a;let o=Ks.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},Ks.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=He({...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(qs(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=Ks.get(e);if(t&&(--t.refs,t.refs<=0)){try{t.v.pause(),t.v.removeAttribute(`src`),t.v.load()}catch{}Ks.delete(e)}}t.clear()}}}let Ys=`AI-generated via fal.ai (ElevenLabs SFX) — commercial use permitted`,Xs=`fal:fal-ai/elevenlabs/sound-effects/v2`,Zs=[{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:Xs,license:Ys,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:Xs,license:Ys,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:Xs,license:Ys,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:Xs,license:Ys,generatedAt:`2026-07-20T23:47:43.702Z`,approvedBy:`owner`,approvedAt:`2026-07-21T00:00:00Z`}],Qs=[{id:`swoosh-swish`,variant:`swish`,name:`Swoosh`,character:`one fast air swish — the weighty-arrival sound`,url:`/sfx/pops/swish.wav`,durationSec:.247,source:Xs,license:Ys,generatedAt:`2026-07-21T17:19:16.426Z`,approvedBy:`owner`,approvedAt:`2026-07-21T23:30:00Z`}];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 $s=(e,t)=>typeof e==`string`&&e.trim()&&e.length<=t?e.trim():null,ec=(e,t)=>P(e)&&Object.keys(e).every(e=>t.includes(e)),tc=e=>P(e)&&$s(e.assetId,160)&&$s(e.versionId,160);function nc(e){return B(e),N(ec(e,[`schemaVersion`,`presenterId`,`sourceBlock`,`poseSheet`,`poses`,`createdAt`])&&e.schemaVersion===1&&$s(e.presenterId,160)&&tc(e.sourceBlock)&&tc(e.poseSheet)&&Array.isArray(e.poses)&&e.poses.length>=1&&e.poses.length<=64&&e.poses.every(e=>ec(e,[`name`,`assetId`,`versionId`,`crop`])&&$s(e.name,120)&&tc(e)&&P(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 rc(e,{sourceBlock:t={assetId:`sm.board-editor`,versionId:`1.0.0`},createdAt:n=new Date().toISOString()}={}){let r=$s(e?.id,160)||`presenter`,i=Array.isArray(e?.poses)?e.poses:[];N(i.length&&i.length<=64&&i.every(e=>$s(e?.label,120)&&$s(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 ee({url:e.url,vectorUrl:e.vectorUrl||null}),crop:{x:0,y:0,width:1,height:1}});return nc({schemaVersion:1,presenterId:r,sourceBlock:t,poseSheet:{assetId:`${r}:pose-set`,versionId:await ee(a)},poses:a,createdAt:n})}function ic(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 ac(e){let{loadPanelDoc:t}=Ln(e),{placePosesOnDoc:n}=Hn(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 nr({content:t,words:n},r||ir(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 rc({...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 ic(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 oc=[{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`}],X={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}},sc=Object.freeze([]);function cc({hostServices:e,projectId:t,doc:n,panelId:r,canEdit:i=!0,host:a=null,content:o=``,words:s=sc,onPick:c,onHostReady:l}){let{getLibraryItems:u,imageCost:d,getDefaultImageModel:f,getDefaultImageQuality:p,getDefaultImageResolution:m,getModelCapabilities:h,QUALITY_OPTIONS:g,ui:_}=Ln(e),{litePoses:y}=ac(e),[b,x]=(0,v.useState)(!1),[S,C]=(0,v.useState)(null),[w,T]=(0,v.useState)(!1),[E,D]=(0,v.useState)(``),[O,k]=(0,v.useState)(``),[A,j]=(0,v.useState)(``),[M,N]=(0,v.useState)(()=>f()),[P,F]=(0,v.useState)(()=>{let e=h(`image`,f()),t=p();return e.quality?.includes(t)?t:e.quality?.[0]||t}),[I,L]=(0,v.useState)(!1),R=In(e,{projectId:t,doc:n,panelId:r,canEdit:i,content:o,words:s,open:b,host:a,defName:E,defStyle:O,defDesc:A,defModel:M,defQuality:P},()=>C(null)),z=a?.poses||[],B=h(`image`,M),V=g.filter(e=>(B.quality||[]).includes(e.value)),ee=(B.quality||[]).includes(P)?P:B.quality?.[0]||P,H=(B.resolution||[]).includes(m())?m():B.resolution?.[0]||`1K`,te=d(M,2,{quality:ee,resolution:H}),ne=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,re=async t=>{let n;try{n=R.begin()}catch{return}if(n){T(!1),C({phase:`plan`});try{let r=await t(ir(e,{assertCurrent:n.check,onProgress:e=>{n.check(),C(e)},model:M,quality:ee,resolution:H}));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()}}},ie=()=>re(e=>nr({content:o,words:s,name:E.trim()||void 0,style:O.trim()||void 0,definition:A.trim()||void 0},e)),ae=e=>re(async t=>(await rr({character:e,content:o,words:s},t)).character),oe=async e=>{let t;try{if(t=R.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()}},se=u(`character`)||[],ce=u(`style`)||[],le=ne?(0,q.jsxs)(`div`,{style:{fontSize:12.5,padding:`10px 2px`},children:[ne,` `,(0,q.jsx)(`button`,{type:`button`,onClick:R.cancel,children:S?.phase===`insert`?`Cancel placement`:`Cancel setup`}),S?.phase!==`insert`&&(0,q.jsx)(`div`,{style:X.head,children:`Stops later steps. Requests already sent may still be charged.`})]}):z.length?(0,q.jsxs)(q.Fragment,{children:[(0,q.jsx)(`div`,{style:X.head,children:`Pick a pose for this board — swap or move it after.`}),(0,q.jsx)(`div`,{style:X.grid,children:z.map(e=>(0,q.jsxs)(`button`,{type:`button`,style:X.poseBtn,title:String(e.label).replace(/-/g,` `),onClick:()=>oe(e),children:[e.url&&(0,q.jsx)(`img`,{src:e.url,alt:``,style:X.poseImg,loading:`lazy`}),(0,q.jsx)(`span`,{style:X.poseLabel,children:String(e.label).replace(/-/g,` `)})]},e.label))})]}):w?(0,q.jsxs)(`div`,{children:[(0,q.jsx)(`div`,{style:X.head,children:`Use a saved character as the host (missing poses are generated):`}),se.length===0&&(0,q.jsx)(`div`,{style:{fontSize:11,color:`var(--text-muted)`},children:`No saved characters yet — create one instead.`}),(0,q.jsx)(`div`,{style:{maxHeight:220,overflowY:`auto`,display:`flex`,flexDirection:`column`,gap:2},children:se.map(e=>(0,q.jsxs)(`div`,{style:X.pickItem,onClick:()=>ae(e),onMouseEnter:e=>{e.currentTarget.style.background=`var(--bg-elevated)`},onMouseLeave:e=>{e.currentTarget.style.background=`transparent`},children:[(e.selectedImageUrl||e.imageUrl)&&(0,q.jsx)(`img`,{src:e.selectedImageUrl||e.imageUrl,alt:``,style:X.thumb}),(0,q.jsx)(`span`,{style:{fontSize:12.5,color:`var(--text-primary)`},children:e.name||`Character`})]},e.id))}),(0,q.jsx)(`button`,{type:`button`,style:{...X.btn,marginTop:8},onClick:()=>T(!1),children:`Back`})]}):(0,q.jsxs)(`div`,{style:{display:`flex`,flexDirection:`column`,gap:7},children:[(0,q.jsx)(`div`,{style:X.head,children:`No presenter yet — create one, then drop its poses on any board. Left blank, it's designed from your narration.`}),(0,q.jsx)(`span`,{style:X.label,children:`Name`}),(0,q.jsx)(`input`,{value:E,onChange:e=>D(e.target.value),placeholder:`Host name (optional)`,style:X.input}),(0,q.jsxs)(`div`,{style:{display:`flex`,alignItems:`center`,gap:8},children:[(0,q.jsx)(`span`,{style:X.label,children:`Art style`}),ce.length>0&&(0,q.jsx)(`button`,{type:`button`,style:X.linkBtn,\"aria-expanded\":I,onClick:()=>L(e=>!e),children:`Import from library`})]}),(0,q.jsx)(`input`,{value:O,onChange:e=>k(e.target.value),placeholder:`Art style (optional) — e.g. flat vector, chibi, hand-drawn, 3D clay`,style:X.input}),I&&(0,q.jsx)(`div`,{style:X.styleMenu,children:ce.map(e=>(0,q.jsxs)(`div`,{style:X.pickItem,title:e.stylePrompt||e.name,onClick:()=>{k((e.stylePrompt||e.name||``).trim()),L(!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,q.jsx)(`img`,{src:e.selectedImageUrl||e.previewUrl||e.imageUrl,alt:``,style:X.thumb}),(0,q.jsx)(`span`,{style:{fontSize:12,color:`var(--text-primary)`,overflow:`hidden`,textOverflow:`ellipsis`,whiteSpace:`nowrap`},children:e.name||`Style`})]},e.id))}),(0,q.jsx)(`span`,{style:X.label,children:`Describe your host`}),(0,q.jsx)(`textarea`,{value:A,onChange:e=>j(e.target.value),rows:2,placeholder:`Describe your host (optional) — e.g. a friendly woman in her 30s, glasses, casual blazer.`,style:{...X.input,resize:`vertical`}}),(0,q.jsx)(`span`,{style:X.label,children:`Model`}),(0,q.jsx)(`select`,{value:M,style:X.input,title:`Image model — defaults to your default in Settings`,onChange:e=>{let t=e.target.value;N(t);let n=h(`image`,t);F(e=>n.quality?.length?n.quality.includes(e)?e:n.quality[0]:e)},children:oc.map(e=>(0,q.jsxs)(`option`,{value:e.value,children:[e.label,e.value===f()?` (default)`:``]},e.value))}),V.length>0&&(0,q.jsxs)(q.Fragment,{children:[(0,q.jsx)(`span`,{style:X.label,children:`Quality`}),(0,q.jsx)(`select`,{value:ee,onChange:e=>F(e.target.value),style:X.input,title:`Output quality for this model`,children:V.map(e=>(0,q.jsxs)(`option`,{value:e.value,children:[e.label,e.value===p()?` (default)`:``]},e.value))})]}),(0,q.jsxs)(`div`,{style:{display:`flex`,gap:8,marginTop:2},children:[(0,q.jsx)(`button`,{type:`button`,style:{...X.btn,...X.primary},onClick:ie,children:A.trim()||O.trim()?`Create my host`:`Create one for me`}),(0,q.jsx)(`button`,{type:`button`,style:X.btn,onClick:()=>T(!0),children:`Use a saved character`})]}),(0,q.jsxs)(`div`,{style:X.cost,children:[`Generates `,2,` pose sheets — about `,te,` credits.`]})]});return(0,q.jsxs)(q.Fragment,{children:[(0,q.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,jn.createPortal)((0,q.jsx)(`div`,{style:X.backdrop,children:(0,q.jsxs)(`div`,{style:X.modal,role:`dialog`,\"aria-modal\":`true`,\"aria-label\":`Character pose`,children:[(0,q.jsxs)(`div`,{style:X.titleRow,children:[(0,q.jsx)(`span`,{style:X.title,children:`Character Pose`}),(0,q.jsx)(`span`,{style:X.beta,children:`BETA`}),(0,q.jsx)(`button`,{type:`button`,style:X.close,\"aria-label\":`Close`,onClick:()=>{R.cancel(),x(!1)},\"data-icon-action\":`true`,title:`Close`,children:(0,q.jsx)(aa,{name:`x`,size:18})})]}),le]})}),document.body)]})}function lc(e){return(0,q.jsx)(cc,{...e,hostServices:e.hostServices||Ba().presenterHost})}let uc=[`Hanken Grotesk`,`Georgia`,`Arial`,`Times New Roman`,`Courier New`,`Verdana`],dc={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 fc({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,q.jsxs)(`label`,{style:{display:`flex`,gap:4,alignItems:`center`,fontSize:10.5,color:`var(--text-secondary)`},children:[e,(0,q.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 Z({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,q.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 pc({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,q.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,q.jsx)(`svg`,{width:s,height:c,style:{display:`block`,borderRadius:4,background:`#fff`},children:l?(0,q.jsxs)(q.Fragment,{children:[l.slots.map((e,t)=>(0,q.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,q.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,q.jsxs)(`g`,{stroke:`#b9b09c`,strokeWidth:`1.2`,fill:`none`,children:[(0,q.jsx)(`line`,{x1:s*.15,y1:c*.26,x2:s*.85,y2:c*.74}),(0,q.jsx)(`line`,{x1:s*.85,y1:c*.26,x2:s*.15,y2:c*.74})]})}),(0,q.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 mc({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,q.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,q.jsxs)(`svg`,{width:a,height:o,style:{display:`block`,borderRadius:4,background:`#fff`},children:[(0,q.jsx)(`rect`,{x:s,y:c,width:a*.6,height:u,rx:`1.5`,fill:`#2b2a26`}),(0,q.jsx)(`rect`,{x:s,y:c+l,width:a*.68,height:u,rx:`1.5`,fill:`#2b2a26`}),(0,q.jsx)(`rect`,{x:s,y:c+2*l,width:a*.3,height:u,rx:`1.5`,fill:`#2b2a26`}),(0,q.jsx)(`rect`,{x:s+a*.33,y:c+2*l-o*.02,width:a*.02,height:o*.09,fill:`#9c937f`})]}),(0,q.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 hc(){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 gc=Math.min(2,typeof window<`u`&&window.devicePixelRatio||1),_c=typeof window<`u`&&!!window.matchMedia?.(`(pointer: coarse)`).matches;function vc({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,q.jsxs)(`div`,{style:{width:n,border:`1px solid var(--border)`,borderRadius:8,background:`var(--bg-secondary)`,overflow:`hidden`,userSelect:`none`},children:[(0,q.jsxs)(`div`,{style:{display:`flex`},children:[(0,q.jsx)(`div`,{style:{width:92,flexShrink:0,fontSize:9,color:`var(--text-muted)`,display:`flex`,alignItems:`center`,paddingLeft:8},children:`TIMELINE`}),(0,q.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,q.jsx)(`div`,{style:{position:`absolute`,left:h(t*1e3),top:0,bottom:0,width:1,background:`var(--border)`},children:(0,q.jsxs)(`span`,{style:{position:`absolute`,top:1,left:3,fontSize:8.5,color:`var(--text-muted)`},children:[t,`s`]})},t))})]}),(0,q.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,q.jsxs)(`div`,{style:{display:`flex`,height:24,alignItems:`center`,borderTop:`1px solid var(--border)`},children:[(0,q.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,q.jsx)(`img`,{src:e.src,alt:``,style:{width:22,height:15,objectFit:`cover`,borderRadius:2,flexShrink:0}}):(0,q.jsx)(`span`,{style:{fontSize:9,color:`var(--text-muted)`,flexShrink:0},children:`Aa`}),(0,q.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,q.jsx)(`div`,{style:{position:`relative`,flex:1,height:`100%`},children:(0,q.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,q.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}}),(!_c||i===e.id)&&(0,q.jsxs)(q.Fragment,{children:[(0,q.jsx)(`span`,{style:{position:`absolute`,left:_c?-5:-3,top:0,bottom:0,width:_c?14:8,cursor:`ew-resize`},onPointerDown:t=>b(t,e,`in`)}),(0,q.jsx)(`span`,{style:{position:`absolute`,right:_c?-5:-3,top:0,bottom:0,width:_c?14:8,cursor:`ew-resize`},onPointerDown:t=>b(t,e,`out`)})]})]})})]},e.id)}),(0,q.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 yc=null;function bc(){return typeof document>`u`?null:(yc||=document.createElement(`canvas`),yc.getContext(`2d`))}let xc=(e,t,n)=>Math.max(t,Math.min(n,e));function Sc({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=Ze(e,t),f={...e,pos:d.pos,...d.size==null?{}:{size:d.size}},p=$e(l.current?{...f,...l.current}:f,n,r,i,bc());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:xc(t.origPos.x+i,.02,.98),y:xc(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:et({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=xc(Math.hypot(i-t.cx,o-t.cy)/t.halfDiag,.12,8);if(t.origBox)l.current={box:{w:xc(t.origBox.w*e,.05,1),h:xc(t.origBox.h*e,.05,1)}};else{let n=b?.02:.05,r=b?.4:.95;l.current={size:xc(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,q.jsx)(`div`,{ref:s,\"data-selbox-root\":!0,style:{position:`absolute`,inset:0,pointerEvents:`none`,overflow:`visible`},children:(0,q.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,q.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,q.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,q.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,q.jsx)(`div`,{style:{position:`absolute`,left:`50%`,top:-26,width:1.5,height:26,background:`var(--accent)`,transform:`translateX(-50%)`,pointerEvents:`none`}}),(0,q.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 Cc(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)Co(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 wc=e=>e&&e!==`cut`&&e!==`Cut`&&(js.includes(e)||e===`fade`),Tc=new Map;function Ec(e,t){if(Tc.size>240){let e=Tc.keys().next().value;Tc.delete(e)}Tc.set(e,t)}let Dc=Object.freeze([]);function Oc({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 _=ca({host:e,doc:a,projectId:n,panelId:o,canEdit:i}),{imageCost:y,videoCost:b}=_.services,x=(0,v.useMemo)(()=>so(t),[t]),S=a.strip.find(e=>e.panelId===o),C=(0,v.useRef)(null),w=r||C,T=Ta({host:t,doc:a,projectId:n,panelId:o,canEdit:i,onDocChange:s,validateDocument:Zt,editLease:w}),E=ho({host:t,doc:a,projectId:n,panelId:o,canEdit:i,onDocChange:s,validateDocument:Zt,editLease:w}),D=io({host:t,doc:a,projectId:n,panelId:o,canEdit:i,onDocChange:s,validateDocument:Zt,editLease:w}),O=Xa({host:t,doc:a,projectId:n,panelId:o,canEdit:i,onDocChange:s,validateDocument:Zt,editLease:w}),k=Kr({host:t,doc:a,projectId:n,panelId:o,canEdit:i,onDocChange:s,validateDocument:Zt,editLease:w}),A=Fa({host:t,doc:a,projectId:n,panelId:o,canEdit:i,onDocChange:s,validateDocument:Zt,editLease:w}),j=Dn({host:t,doc:a,projectId:n,panelId:o,canEdit:i,onDocChange:s,validateDocument:Zt,editLease:w}),M=fa({host:t,doc:a,projectId:n,panelId:o,canEdit:i,onDocChange:s,validateDocument:Zt,editLease:w}),N=_a({host:t,doc:a,projectId:n,panelId:o,canEdit:i,onDocChange:s,validateDocument:Zt,editLease:w}),P=(0,v.useRef)(null),F=(0,v.useRef)(Tc),I=(0,v.useRef)(null),[L,R]=(0,v.useState)(0),[z,B]=(0,v.useState)(!1),V=(0,v.useRef)(null),ee=(0,v.useRef)(null);(0,v.useEffect)(()=>{d&&(R(0),B(!0))},[d]);let[H,te]=(0,v.useState)(null),ne=(0,v.useMemo)(()=>it(S),[S]),re=(0,v.useRef)(new Map),[ie,ae]=(0,v.useState)({open:!1,query:``,results:[],busy:!1,configured:null,forId:null});(0,v.useEffect)(()=>{ae(e=>e.open||e.busy?{open:!1,query:``,results:[],busy:!1,configured:null,forId:null}:e)},[a,n,o,i,e,_.actor]);let[oe,se]=(0,v.useState)(!1),[ce,le]=(0,v.useState)(!1),[ue,U]=v.useReducer(e=>e+1,0),[de,fe]=l===`9:16`?[304,540]:l===`1:1`?[460,460]:[720,405],W=hc(),pe=Math.min(de,Math.max(240,W-64)),me=Math.round(pe/de*fe),G=Math.round(pe*gc),he=Math.round(me*gc),ge=(0,v.useRef)(null);if(ge.current||=Js(()=>U()),(0,v.useEffect)(()=>()=>ge.current?.dispose(),[]),(0,v.useEffect)(()=>{let e=F.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=()=>{Ec(n,t),U()},t.onerror=()=>{let e=new Image;e.onload=()=>{Ec(n,e),U()},e.src=n},t.src=n}n.kind===`video`&&n.src&&ge.current.ensure(n)}},[S?.elements,p]),(0,v.useEffect)(()=>{if(!z)return;let e=performance.now()-L,t=L-1,n=setInterval(()=>{let n=performance.now()-e;for(let e of at(ne,t,n)){if(e.kind===`type`){let t=No.keystroke.url,n=re.current.get(t);n||(n=new Audio(t),re.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`?Qs:Zs;if(!(e.kind===`swoosh`?zo(Qs):Ro(Zs)))continue;let n=t[Math.min(Math.max(0,e.variant||0),t.length-1)],r=re.current.get(n.url);r||(r=new Audio(n.url),re.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)?(B(!1),R(S?.durationMs||0),f?.()):R(n)},33);return()=>clearInterval(n)},[z]),(0,v.useEffect)(()=>{let e=P.current;if(!e||!S)return;ge.current.sync(S,L);let t=e.getContext(`2d`),n=(e,t)=>F.current.get(e)||ge.current.lookup(e,t),r=Number(h)>0?Number(h):500;if(p&&wc(m)&&L<r){let e=Math.max(0,Math.min(1,L/r)),i=go(m===`fade`?`Fade`:m,e);V.current||(V.current=document.createElement(`canvas`),ee.current=document.createElement(`canvas`));for(let e of[V.current,ee.current])e.width=G,e.height=he;let a=V.current.getContext(`2d`);a.clearRect(0,0,G,he),ot(a,p,p.durationMs||5e3,n,G,he);let o=ee.current.getContext(`2d`);o.clearRect(0,0,G,he),ot(o,S,L,n,G,he),t.clearRect(0,0,G,he),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,G,he),Cc(t,V.current,i.out,G,he),Cc(t,ee.current,i.in,G,he),i.overlay&&i.overlay.alpha>.001&&(t.save(),t.globalAlpha=i.overlay.alpha,t.fillStyle=i.overlay.color,t.fillRect(0,0,G,he),t.restore());return}ot(t,S,L,n,G,he)},[S,L,G,he,ue,p,m,h]),!S)return null;let K=(e,t)=>A.change(e,t),_e=S.autoArrange||!!S.template,ve=(e,t)=>A.change(e,{...t,..._e?{pinned:!0}:{}},!0),ye=rt(S),be=(S.elements||[]).find(e=>e.id===H)||null,xe=e=>{I.current=null;let t=P.current.getBoundingClientRect(),n=(e.clientX-t.left)/t.width,r=(e.clientY-t.top)/t.height,i=[...(S.elements||[]).filter(e=>L>=(e.appearMs||0)&&(e.leaveMs==null||L<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){te(null);return}te(i.id),I.current={id:i.id,startX:n,startY:r,orig:i.pos||{x:.5,y:.5},rect:t,raf:0}},Ce=e=>{let t=I.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=I.current;if(!e)return;e.raf=0;let t=P.current;if(!t)return;let n={...S,elements:S.elements.map(t=>t.id===e.id?{...t,pos:e.next}:t)};ot(t.getContext(`2d`),n,L,(e,t)=>F.current.get(e)||ge.current.lookup(e,t),G,he)})},Ee=()=>{let e=I.current;I.current=null,e?.raf&&cancelAnimationFrame(e.raf),e?.next&&ve(e.id,{pos:e.next})},De=e=>{let t=P.current;t&&S&&(ge.current.sync(S,e),ot(t.getContext(`2d`),S,e,(e,t)=>F.current.get(e)||ge.current.lookup(e,t),G,he))},Oe=()=>{let e=I.current;I.current=null,e?.raf&&cancelAnimationFrame(e.raf),e&&De(L)},je=()=>R(e=>Math.min(Math.round(e)+320,S.durationMs)),Me=async()=>{await j.change({kind:`text`,text:`New text`,appearMs:Math.round(L),leaveMs:null,pos:{x:.5,y:.22},size:.07,font:uc[0],color:`#111111`,weight:800,anim:{type:`pop`,perWord:!1,speedMs:180},sfx:`none`,pinned:!!S.autoArrange})&&je()},Fe=async()=>{await j.change({kind:`image`,src:null,query:``,source:`stock`,appearMs:Math.round(L),leaveMs:null,pos:{x:.5,y:.55},size:.28,tilt:0,entrance:S.handoff?.arrive===`fade`?`fade`:`pop`,sfx:`auto`,pinned:!!S.autoArrange})&&je()},Ie=async()=>{await j.change({kind:`video`,src:null,query:``,source:`stock`,appearMs:Math.round(L),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})&&je()},Le=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(L),{signal:u.signal,assertCurrent:l});l(),c?.(),s(e=>{try{if(t?.(e),u.signal.aborted)return e}catch{return e}return n}),je()}finally{r?.removeEventListener(`abort`,d),w.current===u&&(w.current=null)}},Re=(e,{assertCurrent:t}={})=>{t?.(),s(n=>{try{t?.(n)}catch{return n}return{...n,meta:{...n.meta||{},host:e}}})},ze=(a?.meta?.canvasChat?.intent||(a?.audio?.words||[]).map(e=>typeof e==`string`?e:e?.text||``).join(` `)).slice(0,4e3),[Be,Ve]=(0,v.useState)(!1),He=a?.audio?.words?.length?jt(a,S):[],Ge=async e=>{await j.change({kind:`text`,text:e.text,appearMs:e.wordTimes[0]||0,leaveMs:null,pos:S.autoArrange?null:{x:.5,y:.2},size:.065,font:uc[0],color:`#111111`,weight:800,wordTimes:e.wordTimes,anim:{type:`word-pop`,entrance:`pop`,perWord:!0,speedMs:180},sfx:`none`,pinned:!1})&&(Ve(!1),R(Math.min((e.wordTimes[0]||0)+320,S.durationMs)))},[Ke,qe]=(0,v.useState)(!1),[Je,Ye]=(0,v.useState)(`swipe-up`),[Xe,Qe]=(0,v.useState)(`pop`),$e=async()=>{await T.change({mode:`continue`,atMs:Math.round(L),options:{exit:Je,arrive:Xe}})&&(qe(!1),Ua.success?.(`New canvas added — the voiceover continues on a clean slate`))},et=async(e,t=``,n=`photo`)=>{try{await _.run(async r=>{ae({open:!0,query:t,results:[],busy:!1,configured:null,forId:e,mediaType:n});let i=await _.services.stockStatus(r);r.assertCurrent(),ae(e=>({...e,configured:!!i.configured}))})}catch(e){e?.name!==`AbortError`&&Ua.error?.(e?.message||`Stock is unavailable`)}},tt=async e=>{ae(t=>({...t,busy:!0,query:e}));try{await _.run(async t=>{let n=await _.services.stockGrid({query:e,type:ie.mediaType||`photo`},t);t.assertCurrent(),ae(e=>({...e,busy:!1,results:n}))})}catch(e){if(e?.name===`AbortError`)return;ae(e=>({...e,busy:!1,results:[]})),e?.name!==`AbortError`&&Ua.error?.(e?.message||`Stock search failed`)}},nt=async e=>{try{await _.run(async t=>{let n=ie.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 K(ie.forId,{src:e.url,poster:e.previewUrl||e.thumb||null,source:`stock`,query:ie.query,...Number(e.durationSec)>0?{durationSec:Number(e.durationSec)}:{}}))return}else if(!await K(ie.forId,{src:e.url||e.thumb,source:`stock`,query:ie.query}))return;ae({open:!1,query:``,results:[],busy:!1,configured:null,forId:null})})}catch(e){e?.name!==`AbortError`&&Ua.error?.(e?.message||`Could not select image`)}},st=(0,v.useRef)(null),lt=(0,v.useRef)(null),dt=(0,v.useRef)(null),ft=async e=>{let t=e.target.files?.[0];e.target.value=``;let n=dt.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 K(n,{src:i,source:`upload`,poster:null})&&Ua.success?.(`Clip uploaded`)})}catch(e){e?.name!==`AbortError`&&Ua.error?.(e?.message||`Upload failed`)}},pt=async e=>{let t=e.target.files?.[0];e.target.value=``;let n=dt.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 K(n,{src:i,source:`upload`})&&Ua.success?.(`Image uploaded`)})}catch(e){e?.name!==`AbortError`&&Ua.error?.(e?.message||`Upload failed`)}},mt=(e,t)=>{t?.url&&K(e,{src:t.url,source:`library`})},ht=async e=>{let t=String(e.query||``).trim();if(!t){Ua.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 K(e.id,{src:r.url,source:`generated`,poster:null,durationSec:3})})}catch(e){e?.name!==`AbortError`&&Ua.error?.(e?.message||`Clip generation failed`)}},gt=async e=>{let t=String(e.query||ie.query||``).trim();if(!t){Ua.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 K(e.id,{src:r.url,source:`generated`})})}catch(e){e?.name!==`AbortError`&&Ua.error?.(e?.message||`Generation failed`)}};return(0,q.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,q.jsxs)(`div`,{role:`status`,style:{width:`100%`},children:[`Updating element keyframes… `,(0,q.jsx)(`button`,{type:`button`,className:`btn btn-secondary`,onClick:E.cancel,children:`Cancel keyframe edit`})]}),E.error&&(0,q.jsx)(`div`,{role:`alert`,style:{width:`100%`},children:E.error}),D.pending&&(0,q.jsxs)(`div`,{role:`status`,style:{width:`100%`},children:[`Arranging the canvas template… `,(0,q.jsx)(`button`,{type:`button`,className:`btn btn-secondary`,onClick:D.cancel,children:`Cancel template change`})]}),D.error&&(0,q.jsx)(`div`,{role:`alert`,style:{width:`100%`},children:D.error}),O.pending&&(0,q.jsxs)(`div`,{role:`status`,style:{width:`100%`},children:[`Laying out typewriter narration… `,(0,q.jsx)(`button`,{type:`button`,className:`btn btn-secondary`,onClick:O.cancel,children:`Cancel typewriter change`})]}),O.error&&(0,q.jsx)(`div`,{role:`alert`,style:{width:`100%`},children:O.error}),k.pending&&(0,q.jsxs)(`div`,{role:`status`,style:{width:`100%`},children:[`Removing the element and arranging the canvas… `,(0,q.jsx)(`button`,{type:`button`,className:`btn btn-secondary`,onClick:k.cancel,children:`Cancel element deletion`})]}),k.error&&(0,q.jsx)(`div`,{role:`alert`,style:{width:`100%`},children:k.error}),T.pending&&(0,q.jsxs)(`div`,{role:`status`,style:{width:`100%`},children:[`Updating canvas continuation… `,(0,q.jsx)(`button`,{type:`button`,className:`btn btn-secondary`,onClick:T.cancel,children:`Cancel continuation`})]}),T.error&&(0,q.jsx)(`div`,{role:`alert`,style:{width:`100%`},children:T.error}),A.pending&&(0,q.jsxs)(`div`,{role:`status`,style:{width:`100%`},children:[`Applying element settings… `,(0,q.jsx)(`button`,{type:`button`,className:`btn btn-secondary`,onClick:A.cancel,children:`Cancel element edit`})]}),A.error&&(0,q.jsx)(`div`,{role:`alert`,style:{width:`100%`},children:A.error}),j.pending&&(0,q.jsxs)(`div`,{role:`status`,style:{width:`100%`},children:[`Adding the element and arranging the canvas… `,(0,q.jsx)(`button`,{type:`button`,className:`btn btn-secondary`,onClick:j.cancel,children:`Cancel element creation`})]}),j.error&&(0,q.jsx)(`div`,{role:`alert`,style:{width:`100%`},children:j.error}),M.pending&&(0,q.jsxs)(`div`,{role:`status`,style:{width:`100%`},children:[`Updating background… `,(0,q.jsx)(`button`,{type:`button`,className:`btn btn-secondary`,onClick:M.cancel,children:`Cancel background edit`})]}),M.error&&(0,q.jsx)(`div`,{role:`alert`,style:{width:`100%`},children:M.error}),N.pending&&(0,q.jsxs)(`div`,{role:`status`,style:{width:`100%`},children:[`Arranging canvas elements… `,(0,q.jsx)(`button`,{type:`button`,className:`btn btn-secondary`,onClick:N.cancel,children:`Cancel arrangement`})]}),N.error&&(0,q.jsx)(`div`,{role:`alert`,style:{width:`100%`},children:N.error}),(0,q.jsxs)(`div`,{style:{display:`flex`,flexDirection:`column`,gap:8,minWidth:0,maxWidth:`100%`},children:[(0,q.jsxs)(`div`,{style:{display:`flex`,gap:8,alignItems:`center`,flexWrap:`wrap`},children:[(0,q.jsxs)(`strong`,{style:{fontSize:13},children:[u===`page`?`Board`:`Collage canvas`,` · `,S.panelId]}),(0,q.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,q.jsxs)(`div`,{style:{position:`relative`,width:pe,height:me,maxWidth:`100%`},children:[(0,q.jsx)(`canvas`,{ref:P,width:G,height:he,style:{display:`block`,borderRadius:10,border:`1px solid var(--border)`,cursor:`grab`,touchAction:H?`none`:`pan-y`,width:pe,height:me},onPointerDown:e=>{e.currentTarget.setPointerCapture?.(e.pointerId),xe(e)},onPointerMove:Ce,onPointerUp:Ee,onPointerCancel:Oe}),be&&!z&&(0,q.jsx)(Sc,{el:be,tMs:L,stageW:pe,stageH:me,imgLookup:(e,t)=>F.current.get(e)||ge.current.lookup(e,t),onPreview:e=>{let t=P.current;if(!t)return;let n={...S,elements:S.elements.map(t=>t.id===e.id?e:t)};ot(t.getContext(`2d`),n,L,(e,t)=>F.current.get(e)||ge.current.lookup(e,t),G,he)},onCommit:(e,t)=>{let n=Array.isArray(be.moves)&&be.moves.length>0,r=e&&(`pos`in e||`size`in e)&&!(`tilt`in e)&&!(`box`in e);if(n&&r&&t>(be.appearMs||0)+150){let n={};e.pos&&(n.pos=e.pos),`size`in e&&(n.size=e.size),E.change(be.id,`set`,Math.round(t),n)}else ve(be.id,e)}})]}),(0,q.jsxs)(`div`,{style:{display:`flex`,gap:8,alignItems:`center`},children:[(0,q.jsx)(`button`,{className:`btn btn-secondary`,\"data-compact\":!0,\"aria-label\":z?`Pause`:`Play`,title:z?`Pause`:`Play`,style:{width:36,height:30,padding:0,display:`inline-flex`,alignItems:`center`,justifyContent:`center`},onClick:()=>{!z&&L>=S.durationMs&&R(0),B(e=>!e)},children:z?(0,q.jsxs)(`svg`,{width:`12`,height:`13`,viewBox:`0 0 12 13`,\"aria-hidden\":`true`,children:[(0,q.jsx)(`rect`,{x:`1.5`,y:`1`,width:`3`,height:`11`,rx:`0.6`,fill:`currentColor`}),(0,q.jsx)(`rect`,{x:`7.5`,y:`1`,width:`3`,height:`11`,rx:`0.6`,fill:`currentColor`})]}):(0,q.jsx)(`svg`,{width:`12`,height:`13`,viewBox:`0 0 12 13`,\"aria-hidden\":`true`,children:(0,q.jsx)(`path`,{d:`M2 1.2 L11 6.5 L2 11.8 Z`,fill:`currentColor`})})}),g&&(0,q.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:()=>{B(!1),R(0),g()},\"data-icon-action\":`true`,children:(0,q.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,q.jsx)(`path`,{d:`M3 12 a9 9 0 1 0 3-6.7`}),(0,q.jsx)(`path`,{d:`M3 4 v4 h4`})]})}),(0,q.jsx)(`input`,{type:`range`,min:0,max:S.durationMs,value:Math.min(L,S.durationMs),style:{flex:1,accentColor:`var(--accent)`,touchAction:`none`},onChange:e=>{B(!1),R(Number(e.target.value))}}),(0,q.jsxs)(`span`,{style:{fontSize:11,fontVariantNumeric:`tabular-nums`,width:74,textAlign:`right`},children:[(L/1e3).toFixed(2),` / `,(S.durationMs/1e3).toFixed(2),`s`]})]}),(0,q.jsx)(`input`,{ref:st,type:`file`,accept:`video/mp4,video/webm,video/quicktime`,style:{display:`none`},onChange:ft}),(0,q.jsx)(`input`,{ref:lt,type:`file`,accept:`image/png,image/jpeg,image/webp,image/gif`,style:{display:`none`},onChange:pt}),(0,q.jsx)(`div`,{style:{maxWidth:`100%`,overflowX:`auto`},children:(0,q.jsx)(vc,{panel:S,tMs:L,width:pe,playing:z,selected:H,plan:ne,onSeek:e=>{B(!1),R(e)},onSelect:te,onCommitTiming:(e,t)=>K(e,t)})}),(0,q.jsxs)(`div`,{style:{display:`flex`,gap:6,alignItems:`center`,flexWrap:`wrap`},children:[(0,q.jsx)(`button`,{className:`btn btn-secondary`,\"data-compact\":!0,style:{fontSize:11},onClick:Fe,children:`+ Image`}),(0,q.jsx)(`button`,{className:`btn btn-secondary`,\"data-compact\":!0,style:{fontSize:11},onClick:Ie,children:`+ Video`}),(0,q.jsx)(`button`,{className:`btn btn-secondary`,\"data-compact\":!0,style:{fontSize:11},onClick:Me,children:`+ Text`}),(0,q.jsx)(lc,{projectId:n,doc:a,panelId:o,canEdit:i,host:a?.meta?.host,content:ze,words:a?.audio?.words||Dc,onPick:Le,onHostReady:Re}),He.length>0&&(0,q.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:()=>Ve(e=>!e),children:`+ VO text`}),(0,q.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:()=>qe(e=>!e),children:u===`page`?`Continue on new board`:`Continue on new canvas`}),(0,q.jsxs)(`div`,{style:{position:`relative`},children:[(0,q.jsxs)(`button`,{className:`btn btn-secondary`,\"data-compact\":!0,style:{fontSize:11,display:`flex`,gap:6,alignItems:`center`},\"aria-expanded\":ce,title:`Canvas background — solid colours or gradient looks`,onClick:()=>le(e=>!e),children:[`Background`,(0,q.jsx)(`span`,{style:{width:18,height:12,borderRadius:3,border:`1px solid var(--border)`,background:Ne(S.background||`#ffffff`)}})]}),ce&&(0,q.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=Se(S.background);return(0,q.jsx)(`div`,{style:{display:`grid`,gridTemplateColumns:`repeat(4, 1fr)`,gap:6},children:Pe.map(t=>{let n=Se(t.value),r=n&&e?n.key===e.key:S.background===t.value;return(0,q.jsx)(`button`,{type:`button`,title:t.label,disabled:!i||!!M.pending,onClick:()=>M.change({kind:`set`,value:t.value}),style:{height:38,borderRadius:6,cursor:`pointer`,background:Ne(t.value),border:r?`2px solid var(--accent)`:`1px solid var(--border)`}},t.key)})})})(),(()=>{let e=we(S.background);return e?(0,q.jsx)(`div`,{style:{display:`flex`,flexDirection:`column`,gap:6,marginTop:8},children:e.map((e,t)=>(0,q.jsxs)(`label`,{style:{display:`flex`,gap:8,alignItems:`center`,fontSize:10.5,color:`var(--text-secondary)`},children:[(0,q.jsx)(Wa,{type:`color`,value:Te(S.background,t)||e.default,disabled:!i||!!M.pending,onChange:e=>M.change({kind:`color`,slot:t,value:e.target.value})}),e.label]},e.key))}):null})(),(0,q.jsxs)(`label`,{style:{display:`flex`,gap:6,alignItems:`center`,marginTop:8,fontSize:10.5,color:`var(--text-secondary)`},children:[`Custom colour`,(0,q.jsx)(Wa,{type:`color`,value:(S.background||`#ffffff`).startsWith(`#`)?S.background:`#ffffff`,disabled:!i||!!M.pending,onChange:e=>M.change({kind:`set`,value:e.target.value})})]})]})]}),(0,q.jsx)(`button`,{className:`btn btn-secondary`,\"data-compact\":!0,style:{fontSize:11},\"aria-expanded\":oe,title:`Pick a slot layout — existing images reflow into its slots (your pinned moves stay put)`,onClick:()=>se(e=>!e),children:S.mode===`typewriter`?`Template: Typewriter`:ut(S.template)?`Template: ${ut(S.template).name}`:`Templates`}),!S.autoArrange&&!S.template&&(0,q.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||!!N.pending,onClick:()=>N.change(de/fe),children:`Tidy`}),ye.length>0&&(0,q.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:ye.map(e=>`${(e.fromMs/1e3).toFixed(1)}s → ${(e.toMs/1e3).toFixed(1)}s`).join(` · `),onClick:()=>Ua.info?.(`Static stretches: ${ye.map(e=>`${(e.fromMs/1e3).toFixed(1)}s → ${(e.toMs/1e3).toFixed(1)}s`).join(` · `)}`),children:[ye.length,` static stretch`,ye.length===1?``:`es`,` over 2.5s — add a beat (advisory)`]}),(0,q.jsx)(`span`,{style:{flex:1}}),c&&(0,q.jsx)(`button`,{className:`btn btn-primary`,\"data-compact\":!0,style:{fontSize:11},onClick:c,children:`Done`})]}),Be&&(0,q.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,q.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`}),He.map((e,t)=>(0,q.jsxs)(`button`,{type:`button`,className:`btn btn-secondary`,\"data-compact\":!0,style:{fontSize:11,textAlign:`left`,justifyContent:`flex-start`},onClick:()=>Ge(e),children:[(e.wordTimes[0]/1e3).toFixed(1),`s · `,e.text.slice(0,70)]},t))]}),Ke&&(0,q.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,q.jsxs)(`span`,{style:{fontSize:11,color:`var(--text-secondary)`},children:[`Split at `,(L/1e3).toFixed(2),`s:`]}),(0,q.jsx)(`select`,{value:Je,style:{fontSize:10.5},onChange:e=>Ye(e.target.value),children:Dt.map(e=>(0,q.jsxs)(`option`,{value:e,children:[`exit: `,e.replace(`-`,` `)]},e))}),(0,q.jsx)(`select`,{value:Xe,style:{fontSize:10.5},onChange:e=>Qe(e.target.value),children:Ot.map(e=>(0,q.jsxs)(`option`,{value:e,children:[`arrive: `,e===`fade`?`fade in`:e]},e))}),(0,q.jsx)(`button`,{className:`btn btn-primary`,\"data-compact\":!0,style:{fontSize:11},onClick:$e,children:`Add canvas`}),(0,q.jsxs)(`span`,{style:{fontSize:10,color:`var(--text-muted)`},children:[`Everything on screen `,Je===`cut`?`cuts`:`slides off together`,`; the new canvas starts blank.`]})]}),S.handoff&&(0,q.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,q.jsx)(`span`,{style:{fontSize:10.5,color:`var(--text-secondary)`},children:`Hand-off into this canvas:`}),(0,q.jsx)(`select`,{value:S.handoff.exit||`swipe-up`,style:{fontSize:10.5},onChange:e=>T.change({mode:`handoff`,options:{exit:e.target.value}}),children:Dt.map(e=>(0,q.jsx)(`option`,{value:e,children:e.replace(`-`,` `)},e))}),(0,q.jsx)(`select`,{value:S.handoff.arrive||`pop`,style:{fontSize:10.5},onChange:e=>T.change({mode:`handoff`,options:{arrive:e.target.value}}),children:Ot.map(e=>(0,q.jsx)(`option`,{value:e,children:e===`fade`?`fade in`:e},e))}),(0,q.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,q.jsx)(aa,{name:`trash`,size:18})})]}),oe&&(0,q.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,q.jsx)(pc,{name:`None`,active:!S.template,aspect:de/fe,disabled:!i||!!O.pending||!!D.pending||!!E.pending,onPick:async()=>{await D.change(null)&&se(!1)}},`none`),ct.map(e=>(0,q.jsx)(pc,{name:e.name,template:e,active:S.template===e.id&&S.mode!==`typewriter`,aspect:de/fe,disabled:!i||!!O.pending||!!D.pending||!!E.pending,onPick:async()=>{await D.change(e.id)&&se(!1)}},e.id)),(0,q.jsx)(mc,{active:S.mode===`typewriter`,aspect:de/fe,disabled:!i||!!O.pending||!!D.pending||!!E.pending,onPick:async()=>{if(!He.length){Ua.error?.(`This board has no voiceover to type — add a voiceover first.`);return}await O.change()&&se(!1)}},`typewriter`)]})]}),(0,q.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,q.jsxs)(`div`,{style:{border:`1px solid ${H===e.id?`var(--accent)`:`var(--border)`}`,borderRadius:8,padding:8,display:`flex`,flexDirection:`column`,gap:6,background:`var(--bg-secondary)`},onClick:()=>te(e.id),children:[(0,q.jsxs)(`div`,{style:{display:`flex`,gap:6,alignItems:`center`,flexWrap:`wrap`},children:[e.kind===`image`&&e.src?(0,q.jsx)(`img`,{src:e.src,alt:``,style:{width:34,height:24,objectFit:`cover`,borderRadius:4}}):null,e.kind===`text`?(0,q.jsx)(Z,{value:e.text,placeholder:`Text…`,style:{fontWeight:700},onCommit:t=>K(e.id,{text:t})}):(0,q.jsxs)(q.Fragment,{children:[(0,q.jsx)(`strong`,{style:{fontSize:11},children:e.query||e.kind}),(0,q.jsx)(`span`,{style:{flex:1}})]}),e.pinned&&S.autoArrange&&(0,q.jsx)(`span`,{style:{fontSize:9,border:`1px solid var(--border)`,borderRadius:999,padding:`0 6px`,color:`var(--text-secondary)`},children:`pinned`}),(0,q.jsx)(`button`,{className:`btn btn-secondary`,\"data-compact\":!0,style:{fontSize:10,padding:`1px 7px`},disabled:!i||!!w.current,onClick:t=>{t.stopPropagation(),k.change(e.id)},\"data-icon-action\":`true`,\"aria-label\":`Delete`,title:`Delete`,children:(0,q.jsx)(aa,{name:`trash`,size:18})})]}),(0,q.jsxs)(`div`,{style:{display:`flex`,gap:8,alignItems:`center`,flexWrap:`wrap`},children:[(0,q.jsx)(fc,{label:`in`,value:e.appearMs,onCommit:t=>K(e.id,{appearMs:Math.min(t,S.durationMs-100)})}),(0,q.jsx)(fc,{label:`out`,value:e.leaveMs??S.durationMs,onCommit:t=>K(e.id,{leaveMs:t>=S.durationMs?null:Math.max(t,(e.appearMs||0)+100)})}),(0,q.jsxs)(`label`,{style:{display:`flex`,gap:4,alignItems:`center`,fontSize:10.5,color:`var(--text-secondary)`},children:[`size`,(0,q.jsx)(Wa,{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=>ve(e.id,{size:Number(t.target.value)})})]}),(0,q.jsx)(`select`,{value:e.sfx||`auto`,style:{fontSize:10.5},onChange:t=>K(e.id,{sfx:t.target.value}),children:[`auto`,`pop`,`swoosh`,`none`].map(e=>(0,q.jsxs)(`option`,{value:e,children:[`sfx: `,e]},e))})]}),e.kind===`image`||e.kind===`video`?(0,q.jsxs)(`div`,{style:{display:`flex`,gap:6,alignItems:`center`,flexWrap:`wrap`},children:[(0,q.jsx)(`select`,{value:e.entrance||`pop`,style:{fontSize:10.5},onChange:t=>K(e.id,{entrance:t.target.value}),children:ke.map(e=>(0,q.jsxs)(`option`,{value:e,children:[`in: `,e]},e))}),e.source===`pose`&&a?.meta?.host?.poses?.length>0&&(0,q.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&&K(e.id,{src:n.url,pose:n.label,query:n.label,source:`pose`,cutout:!0})},children:a.meta.host.poses.map(e=>(0,q.jsxs)(`option`,{value:e.label,children:[`pose: `,String(e.label).replace(/-/g,` `)]},e.label))}),(0,q.jsx)(`button`,{className:`btn btn-secondary`,\"data-compact\":!0,style:{fontSize:10},onClick:t=>{t.stopPropagation(),et(e.id,e.query,e.kind===`video`?`video`:`photo`)},children:e.src?`Swap (stock)`:`Find (stock)`}),e.kind===`image`?(0,q.jsxs)(q.Fragment,{children:[(0,q.jsx)(Ws,{label:`All Assets`,style:dc,onPick:t=>mt(e.id,t)}),(0,q.jsx)(`button`,{className:`btn btn-secondary`,\"data-compact\":!0,style:{fontSize:10},onClick:t=>{t.stopPropagation(),dt.current=e.id,lt.current?.click()},children:e.src?`Upload`:`Upload local`}),(0,q.jsxs)(`button`,{className:`btn btn-secondary`,\"data-compact\":!0,style:{fontSize:10},onClick:t=>{t.stopPropagation(),gt(e)},children:[`Generate · `,y(`gpt-image-2`,1,{quality:`low`,resolution:`1K`}),` cr`]})]}):(0,q.jsxs)(q.Fragment,{children:[(0,q.jsx)(`button`,{className:`btn btn-secondary`,\"data-compact\":!0,style:{fontSize:10},onClick:t=>{t.stopPropagation(),dt.current=e.id,st.current?.click()},children:`Upload clip`}),(0,q.jsxs)(`button`,{className:`btn btn-secondary`,\"data-compact\":!0,style:{fontSize:10},onClick:t=>{t.stopPropagation(),ht(e)},children:[`Generate · `,b(`wan-2.6-flash`,3),` cr`]})]}),(0,q.jsx)(Z,{value:e.query,onCommit:t=>K(e.id,{query:t})}),e.kind===`image`&&(0,q.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,q.jsx)(Wa,{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=>ve(e.id,{shadow:Number(t.target.value)})})]})]}):(0,q.jsxs)(`div`,{style:{display:`flex`,gap:6,alignItems:`center`,flexWrap:`wrap`},children:[(0,q.jsx)(`select`,{value:e.font||uc[0],style:{fontSize:10.5},onChange:t=>K(e.id,{font:t.target.value}),children:uc.map(e=>(0,q.jsx)(`option`,{value:e,children:e},e))}),(0,q.jsx)(Wa,{disabled:!i||!!w.current,type:`color`,value:e.color||`#111111`,onChange:t=>K(e.id,{color:t.target.value})}),(0,q.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=>K(e.id,{anim:{...e.anim||{},type:t.target.value}}),children:[...Ue,...Ae.filter(e=>!Ue.includes(e))].map(e=>(0,q.jsxs)(`option`,{value:e,children:[`arrive: `,e]},e))}),e.anim?.type===`sentence-build`&&(0,q.jsx)(`select`,{value:e.anim?.entrance||`pop`,style:{fontSize:10.5},onChange:t=>K(e.id,{anim:{...e.anim||{},entrance:t.target.value}}),children:We.map(e=>(0,q.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,q.jsxs)(`label`,{style:{display:`flex`,gap:4,alignItems:`center`,fontSize:10.5,color:`var(--text-secondary)`},children:[`speed`,(0,q.jsx)(Wa,{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=>K(e.id,{anim:{...e.anim||{},speedMs:Number(t.target.value)}})})]})]}),e.kind===`video`&&(0,q.jsxs)(`div`,{style:{display:`flex`,gap:8,alignItems:`center`,flexWrap:`wrap`},children:[(0,q.jsxs)(`select`,{value:e.loop===!1?`once`:`loop`,style:{fontSize:10.5},onChange:t=>K(e.id,{loop:t.target.value===`loop`}),children:[(0,q.jsx)(`option`,{value:`loop`,children:`play: loop`}),(0,q.jsx)(`option`,{value:`once`,children:`play: once`})]}),(0,q.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,q.jsx)(`input`,{type:`checkbox`,checked:e.muted!==!1,onChange:t=>K(e.id,{muted:t.target.checked})}),`muted`]}),(0,q.jsxs)(`label`,{style:{display:`flex`,gap:4,alignItems:`center`,fontSize:10.5,color:`var(--text-secondary)`},children:[`trim in`,(0,q.jsx)(Wa,{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=>K(e.id,{trimStartSec:Math.max(0,Number(t.target.value)||0)})}),`s`]}),(0,q.jsxs)(`label`,{style:{display:`flex`,gap:4,alignItems:`center`,fontSize:10.5,color:`var(--text-secondary)`},children:[`speed`,(0,q.jsx)(Wa,{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=>K(e.id,{speed:Number(t.target.value)})}),(0,q.jsxs)(`span`,{style:{fontVariantNumeric:`tabular-nums`,fontSize:10},children:[(Number(e.speed)>0?Number(e.speed):1).toFixed(2),`x`]})]})]}),(0,q.jsxs)(`div`,{style:{display:`flex`,gap:6,alignItems:`center`,flexWrap:`wrap`},children:[(0,q.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;K(e.id,{motion:n===`none`?null:{...Ps(),...e.motion||{},type:n}})},children:Ns.map(e=>(0,q.jsxs)(`option`,{value:e.value,children:[`motion: `,e.label]},e.value))}),e.motion?.type&&e.motion.type!==`none`&&(0,q.jsxs)(q.Fragment,{children:[(0,q.jsxs)(`label`,{style:{display:`flex`,gap:4,alignItems:`center`,fontSize:10.5,color:`var(--text-secondary)`},children:[`intensity`,(0,q.jsx)(Wa,{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=>K(e.id,{motion:{...e.motion,intensity:Number(t.target.value)}})})]}),(0,q.jsx)(`select`,{value:e.motion.easing||`ease-in-out`,style:{fontSize:10.5},onChange:t=>K(e.id,{motion:{...e.motion,easing:t.target.value}}),children:[`linear`,`ease-in`,`ease-out`,`ease-in-out`].map(e=>(0,q.jsx)(`option`,{value:e,children:e},e))}),(0,q.jsxs)(`label`,{style:{display:`flex`,gap:4,alignItems:`center`,fontSize:10.5,color:`var(--text-secondary)`},children:[(0,q.jsx)(`input`,{type:`checkbox`,checked:!!e.motion.loop,onChange:t=>K(e.id,{motion:{...e.motion,loop:t.target.checked}})}),`loop`]})]})]}),H===e.id&&(0,q.jsxs)(`div`,{style:{borderTop:`1px dashed var(--border)`,paddingTop:6,display:`flex`,flexDirection:`column`,gap:5},children:[(0,q.jsxs)(`div`,{style:{display:`flex`,gap:6,alignItems:`center`,flexWrap:`wrap`},children:[(0,q.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,q.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(L),Math.round(e.appearMs||0)),r=Ze(e,n);E.change(e.id,`set`,n,{pos:r.pos,...r.size==null?{}:{size:r.size}})},children:[`+ Move at `,(Math.max(L,e.appearMs||0)/1e3).toFixed(1),`s`]}),(0,q.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(L),Math.round(e.appearMs||0)),r=Ze(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,q.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(L),Math.round(e.appearMs||0)),r=Ze(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,q.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,q.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,q.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,q.jsx)(aa,{name:`x`,size:18})})]},n))})]})]},e.id)),(S.elements||[]).length===0&&(0,q.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.`]})]}),ie.open&&(0,q.jsx)(`div`,{style:{position:`fixed`,inset:0,zIndex:1001,background:`rgba(0,0,0,0.5)`,display:`flex`,alignItems:`center`,justifyContent:`center`},onClick:()=>ae(e=>({...e,open:!1})),children:(0,q.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,q.jsxs)(`div`,{style:{display:`flex`,gap:6,alignItems:`center`,marginBottom:6,flexWrap:`wrap`},children:[(0,q.jsxs)(`strong`,{style:{fontSize:12},children:[`Stock `,ie.mediaType===`video`?`video`:`photos`]}),(0,q.jsx)(Z,{value:ie.query,onCommit:e=>tt(e)}),(0,q.jsx)(`button`,{className:`btn btn-primary`,\"data-compact\":!0,style:{fontSize:11},disabled:ie.busy,onClick:()=>tt(ie.query),children:ie.busy?`Searching…`:`Search`})]}),(0,q.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.`}),ie.configured===!1&&(0,q.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,q.jsx)(`div`,{style:{display:`grid`,gridTemplateColumns:`repeat(auto-fill, minmax(120px, 1fr))`,gap:8},children:ie.results.map((e,t)=>(0,q.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:()=>nt(e)},e.id||t))})]})})]})}let kc=e=>Math.min(100,Math.max(0,e));function Ac(e,t=60){if(e==null||e===``)return kc(t);let n=Number(e);return Number.isFinite(n)?n<=0?0:kc(n<=1?n*100:n):kc(t)}function jc(e,t=60){return Ac(e,t)/100}let Mc=(e,t)=>typeof OffscreenCanvas<`u`?new OffscreenCanvas(e,t):Object.assign(document.createElement(`canvas`),{width:e,height:t}),Nc=new Map;function Pc(e,{count:t,size:n,mono:r=!0,alpha:i=255}){if(Nc.has(e))return Nc.get(e);let a=[];for(let o=0;o<t;o++){let t=Mc(n,n),s=t.getContext(`2d`),c=s.createImageData(n,n),l=Vo(15778014+o*7919+e.length*131);for(let e=0;e<c.data.length;e+=4){let t=l()*255|0;c.data[e]=t,c.data[e+1]=r?t:l()*255|0,c.data[e+2]=r?t:l()*255|0,c.data[e+3]=i}s.putImageData(c,0,0),a.push(t)}return Nc.set(e,a),a}let Fc=null;function Ic(){if(Fc)return Fc;let e=Mc(1,3),t=e.getContext(`2d`);return t.fillStyle=`rgba(0,0,0,0.4)`,t.fillRect(0,0,1,1),Fc=e,e}let Lc=null;function Rc(){if(Lc)return Lc;let e=Mc(1,3),t=e.getContext(`2d`);return t.fillStyle=`rgba(40,255,235,0.5)`,t.fillRect(0,0,1,1),Lc=e,e}let zc=null;function Bc(e,t,n){(!zc||zc.width!==t||zc.height!==n)&&(zc=Mc(t,n));let r=zc.getContext(`2d`);return r.clearRect(0,0,t,n),r.drawImage(e.canvas,0,0),zc}let Vc=null,Q=null;function Hc(e,t,n){return e===`a`?((!Vc||Vc.width!==t||Vc.height!==n)&&(Vc=Mc(t,n)),Vc):((!Q||Q.width!==t||Q.height!==n)&&(Q=Mc(t,n)),Q)}function Uc(e,t,n,r,i){let a=e.getContext(`2d`);return a.save(),a.filter=`none`,a.globalAlpha=1,a.globalCompositeOperation=`source-over`,a.drawImage(t,0,0),a.globalCompositeOperation=`multiply`,a.fillStyle=n,a.fillRect(0,0,r,i),a.restore(),e}function Wc(e,t,n,r){if(t<=.004)return;let i=n/2,a=r/2,o=Math.hypot(n,r)/2,s=e.createRadialGradient(i,a,o*.55,i,a,o);s.addColorStop(0,`rgba(0,0,0,0)`),s.addColorStop(1,`rgba(0,0,0,${t.toFixed(3)})`),e.fillStyle=s,e.fillRect(0,0,n,r)}function Gc(e,t,n,r,i,a={}){let o=ms(t?.liveOverlays,n);if(!o.length)return;let s=i/1080,c=null,l=()=>a.noFrame?null:c||=Bc(e,r,i);for(let t of o){let a=hs(t),o=gs(t);if(e.save(),e.filter=`none`,e.globalAlpha=1,e.globalCompositeOperation=`source-over`,t.kind===`film_grain`){let s=Pc(`grain`,{count:4,size:256})[ks(n,4,12)],c=e.createPattern(s,`repeat`);if(c){let s=_s(t,n,24);e.translate(Math.floor(Y(o,s)*256),Math.floor(Y(o,s+1)*256)),e.globalAlpha=.25*a,e.globalCompositeOperation=`overlay`,e.fillStyle=c,e.fillRect(-256,-256,r+512,i+512)}}else if(t.kind===`static`){let t=Pc(`static`,{count:6,size:256})[ks(n,6,24)],o=e.createPattern(t,`repeat`);o&&(e.globalAlpha=.12+.5*a,e.scale(2,2),e.fillStyle=o,e.fillRect(0,0,r/2,i/2))}else if(t.kind===`crt`){let c=e.createPattern(Ic(),`repeat`);c&&(e.globalAlpha=.25*a*vs(t,n),e.fillStyle=c,e.fillRect(0,0,r,i));let l=_s(t,n,30);if(Y(o,l)<.07){e.globalAlpha=.5*a,e.fillStyle=`#cfe9ff`;let t=1+Math.round(2*Y(o,l+1));for(let n=0;n<t;n++){let t=Y(o,l*7+n)*i,a=Y(o,l*11+n)*r;e.fillRect(a,t,(20+60*Y(o,l*13+n))*s,2*s)}}e.globalAlpha=1,Wc(e,.25*a,r,i)}else if(t.kind===`vhs`){let o=Ss(t,n),c=l();if(c){for(let t of o.wobble){let n=t.y*i,a=Math.max(1,t.h*i);e.drawImage(c,0,n,r,a,t.dx*s,n,r,a)}let t=o.chromaPx*s,n=Uc(Hc(`a`,r,i),c,`#ff0000`,r,i),l=Uc(Hc(`b`,r,i),c,`#0000ff`,r,i);e.globalAlpha=.35*a,e.globalCompositeOperation=`screen`,e.drawImage(n,t,0),e.drawImage(l,-t,0),e.globalCompositeOperation=`source-over`,e.globalAlpha=1}let u=e.createPattern(Ic(),`repeat`);if(u&&(e.globalAlpha=o.scanAlpha,e.fillStyle=u,e.fillRect(0,0,r,i)),o.bandY>-.1&&o.bandY<1.1){let t=Pc(`static`,{count:6,size:256}),a=e.createPattern(t[ks(n,6,24)],`repeat`);a&&(e.globalAlpha=o.bandAlpha,e.fillStyle=a,e.fillRect(0,o.bandY*i,r,.045*i))}}else if(t.kind===`light_leaks`){e.globalCompositeOperation=`screen`;for(let a of ys(t,n)){let t=a.radius*Math.max(r,i),n=e.createRadialGradient(a.cx*r,a.cy*i,0,a.cx*r,a.cy*i,t);n.addColorStop(0,a.color),n.addColorStop(1,`rgba(0,0,0,0)`),e.globalAlpha=a.alpha,e.fillStyle=n,e.fillRect(0,0,r,i)}}else if(t.kind===`dust`||t.kind===`rain`||t.kind===`snow`){let a=bs(t);if(e.globalAlpha=t.kind===`dust`?.22:.4,e.fillStyle=`#ffffff`,e.strokeStyle=`rgba(255,255,255,0.5)`,e.lineWidth=1.2*s,t.kind===`rain`){e.beginPath();for(let o=0;o<a;o++){let a=xs(t,o,n),c=(10+14*a.size)*s;e.moveTo(a.x*r,a.y*i),e.lineTo(a.x*r-c*a.slant,a.y*i+c)}e.stroke()}else{e.beginPath();for(let o=0;o<a;o++){let a=xs(t,o,n),c=a.size*s*(t.kind===`snow`?1.6:1);e.moveTo(a.x*r+c,a.y*i),e.arc(a.x*r,a.y*i,c,0,Math.PI*2)}e.fill()}}else if(t.kind===`vignette_pulse`)Wc(e,Es(t,n),r,i);else if(t.kind===`heat_haze`){let o=l();if(o)for(let a of ws(t,n)){let t=a.y0*i,n=Math.max(1,(a.y1-a.y0)*i);e.drawImage(o,0,t,r,n,a.dx*s,t,r,n)}else{e.globalAlpha=.05*a,e.fillStyle=`#ffffff`;for(let a of ws(t,n))Math.abs(a.dx)>1.2&&e.fillRect(0,a.y0*i,r,1.5*s)}}else if(t.kind===`hologram`){let a=Ts(t,n),o=e.createPattern(Rc(),`repeat`);if(e.globalCompositeOperation=`screen`,o&&(e.globalAlpha=a.scanAlpha,e.fillStyle=o,e.fillRect(0,0,r,i)),e.globalAlpha=a.washAlpha,e.fillStyle=`rgb(0,255,240)`,e.fillRect(0,0,r,i),a.bandY>-.1&&a.bandY<1.1){let t=a.bandY*i,n=e.createLinearGradient(0,t-30*s,0,t+30*s);n.addColorStop(0,`rgba(0,255,240,0)`),n.addColorStop(.5,`rgba(160,255,250,${a.bandAlpha.toFixed(3)})`),n.addColorStop(1,`rgba(0,255,240,0)`),e.globalAlpha=1,e.fillStyle=n,e.fillRect(0,t-30*s,r,60*s)}}else if(t.kind===`color_wash`){let n=typeof t.color==`string`&&/^#[0-9a-fA-F]{6}$/.test(t.color)?t.color:`#6ea8ff`;e.globalCompositeOperation=`color`,e.globalAlpha=.5*a,e.fillStyle=n,e.fillRect(0,0,r,i)}else if(t.kind===`vintage`){let o=Ds(t,n);e.fillStyle=`#1a1208`;for(let t of o.scratches)e.globalAlpha=t.alpha,e.fillRect(t.x*r,0,1.2*s,i);Math.abs(o.flicker)>.002&&(e.globalAlpha=Math.abs(o.flicker),e.fillStyle=o.flicker>0?`#ffffff`:`#000000`,e.fillRect(0,0,r,i)),e.globalAlpha=1,Wc(e,.3*a,r,i)}else if(t.kind===`chromatic_drift`){let a=l();if(a){let o=Cs(t,n)*s;if(Math.abs(o)>.15){let t=Uc(Hc(`a`,r,i),a,`#ff0000`,r,i),n=Uc(Hc(`b`,r,i),a,`#0000ff`,r,i);e.globalAlpha=.5,e.globalCompositeOperation=`screen`,e.drawImage(t,o,0),e.drawImage(n,-o,0)}}}else if(t.kind===`speed_streaks`){let a=Os(t,n),o=a.ghost?l():null;if(o){e.globalCompositeOperation=`lighter`;for(let t of[1.04,1.08])e.globalAlpha=.09,e.save(),e.translate(r/2,i/2),e.scale(t,t),e.translate(-r/2,-i/2),e.drawImage(o,0,0),e.restore();e.globalCompositeOperation=`source-over`}let s=r/2,c=i/2,u=Math.hypot(r,i)/2;e.fillStyle=`#ffffff`;for(let t of a.spokes){if(t.alpha<=.004)continue;e.globalAlpha=t.alpha;let n=t.angle-t.width,r=t.angle+t.width,i=t.inner*u*2;e.beginPath(),e.moveTo(s+Math.cos(n)*i,c+Math.sin(n)*i),e.lineTo(s+Math.cos(t.angle)*u*1.5,c+Math.sin(t.angle)*u*1.5),e.lineTo(s+Math.cos(r)*i,c+Math.sin(r)*i),e.closePath(),e.fill()}}e.restore()}}let Kc=(e,t)=>typeof OffscreenCanvas<`u`?new OffscreenCanvas(e,t):Object.assign(document.createElement(`canvas`),{width:e,height:t}),qc=null;function Jc(){if(qc)return qc;let e=Kc(1,3),t=e.getContext(`2d`);return t.clearRect(0,0,1,3),t.fillStyle=`rgba(0,0,0,0.35)`,t.fillRect(0,0,1,1),qc=e,e}function Yc(e,t,n,r,i){let a=qo(t?.fxEvents,n);for(let t of a)if(t.kind===`flash`||t.kind===`strobe`||t.kind===`shake_flash`||t.kind===`freeze_flash`){let a=os(t,n);if(a<=.004)continue;e.save(),e.filter=`none`,e.globalAlpha=Math.min(1,a),e.fillStyle=ss(t),e.fillRect(0,0,r,i),e.restore()}else if(t.kind===`light_leak`){let a=cs(t,n);if(a.alpha<=.004)continue;let o=a.radius*Math.max(r,i),s=e.createRadialGradient(a.cx*r,a.cy*i,0,a.cx*r,a.cy*i,o);s.addColorStop(0,a.color),s.addColorStop(1,`rgba(0,0,0,0)`),e.save(),e.filter=`none`,e.globalCompositeOperation=`screen`,e.globalAlpha=a.alpha,e.fillStyle=s,e.fillRect(0,0,r,i),e.restore()}else if(t.kind===`scanline_hit`){let a=ls(t,n);if(a.alpha<=.004)continue;let o=e.createPattern(Jc(),`repeat`);if(!o)continue;e.save(),e.filter=`none`,e.globalAlpha=a.alpha,e.translate(0,a.offsetY),e.fillStyle=o,e.fillRect(0,-3,r,i+6),e.restore()}else if(t.kind===`speed_lines`){let{spokes:a}=us(t,n),o=r/2,s=i/2,c=Math.hypot(r,i)/2;e.save(),e.filter=`none`,e.fillStyle=`#ffffff`;for(let t of a){if(t.alpha<=.004)continue;e.globalAlpha=t.alpha;let n=t.angle-t.width,r=t.angle+t.width,i=t.inner*c*2;e.beginPath(),e.moveTo(o+Math.cos(n)*i,s+Math.sin(n)*i),e.lineTo(o+Math.cos(t.angle)*c*1.5,s+Math.sin(t.angle)*c*1.5),e.lineTo(o+Math.cos(r)*i,s+Math.sin(r)*i),e.closePath(),e.fill()}e.restore()}}let Xc=(e,t,n)=>Math.min(n,Math.max(t,e)),Zc=e=>{let t=Xc(e,0,1);return t*t*(3-2*t)};function Qc(e,t){let n=Number(e?.start)||0,r=Number(e?.end)||0;if(t<n||t>r)return 0;let i=Math.max(1e-4,r-n),a=Math.min(.35,i*.4),o=a>0?Zc((t-n)/a):1,s=a>0?Zc((r-t)/a):1,c=Xc(Number(e?.opacity??1),0,1);return Xc(Math.min(o,s),0,1)*c}function $c(e,t){return(Array.isArray(e)?e:[]).filter(e=>t>=(Number(e.start)||0)&&t<=(Number(e.end)||0))}let el=(e,t,n)=>Math.min(n,Math.max(t,e));function tl(e,t){let n=el(e,0,1);return t===`linear`?n:t===`ease-in-out`?n*n*(3-2*n):1-(1-n)**3}function nl(e,t){let n=Number(e?.start)||0,r=Number(e?.end)||0,i=Number(e?.value)||0,a=Math.max(1e-4,(r-n)*.75);return i*tl(a>0?(t-n)/a:1,e?.easing)}function rl(e,t){let n=Math.max(0,Math.min(2,Number(e?.decimals)||0));return`${e?.prefix||``}${Number(t).toFixed(n)}${e?.suffix||``}`}function il(e,t){return(Array.isArray(e)?e:[]).filter(e=>t>=(Number(e.start)||0)&&t<=(Number(e.end)||0))}let al=(e,t,n)=>Math.min(n,Math.max(t,e));function ol(e,t){let n=al(e,0,1);return t===`linear`?n:t===`ease-in-out`?n*n*(3-2*n):1-(1-n)**3}function sl(e,t){let n=Number(e?.start)||0,r=Number(e?.end)||0,i=Math.max(1e-4,(r-n)*.6);return ol(i>0?(t-n)/i:1,e?.easing)}function cl(e,t,n){let r=(Array.isArray(e?.series)?e.series:[]).filter(e=>Number.isFinite(Number(e?.value))),i=r.map(e=>Number(e.value)||0),a=Math.max(1,...i.map(e=>Math.abs(e))),{x:o,y:s,w:c,h:l}=t,u=e?.title?Math.min(30,l*.18):6,d=s+u,f=Math.max(8,l-u-22),p=e?.chart||`bar`;if(p===`donut`){let e=o+c/2,t=d+f/2,a=Math.min(c,f)/2*.92,s=i.reduce((e,t)=>e+Math.max(0,t),0)||1,l=0,u=r.map(e=>{let t=Math.max(0,Number(e.value)||0)/s,r=-Math.PI/2+l*Math.PI*2,i=r+t*Math.PI*2*n;return l+=t,{label:e.label,value:e.value,a0:r,a1:i,frac:t}});return{kind:`donut`,cx:e,cy:t,r:a,inner:a*.58,arcs:u}}let m=r.length||1;if(p===`line`){let e=r.map((e,t)=>{let n=m===1?o+c/2:o+t/(m-1)*c,r=d+f-Math.abs(Number(e.value)||0)/a*f;return{label:e.label,value:e.value,x:n,y:r,cx:n}});return{kind:`line`,pts:e,reveal:Math.max(1,Math.ceil(e.length*n)),baseY:d+f}}let h=c*.04,g=(c-h*(m+1))/m;return{kind:`bar`,bars:r.map((e,t)=>{let r=Math.abs(Number(e.value)||0)/a*f*n,i=o+h+t*(g+h);return{label:e.label,value:e.value,x:i,w:g,y:d+f-r,h:r,cx:i+g/2}}),baseY:d+f}}function ll(e,t){return(Array.isArray(e)?e:[]).filter(e=>t>=(Number(e.start)||0)&&t<=(Number(e.end)||0))}let ul=`\"Hanken Grotesk\", system-ui, sans-serif`,dl=/^#[0-9a-fA-F]{6}$/,fl={sm:.06,s:.06,m:.07,md:.07,l:.1,lg:.1,xl:.14};function pl(e,t,n,r){if(typeof t==`string`&&t.startsWith(`linear-gradient`)){let i=t.match(/#[0-9a-fA-F]{6}/g)||[`#0b0b14`,`#1a1a2e`],a=e.createLinearGradient(0,0,n,r);return a.addColorStop(0,i[0]),a.addColorStop(1,i[i.length-1]),a}return typeof t==`string`&&dl.test(t)?t:`#0b0b14`}function ml(e,t,n,r,i,a){let o=Math.max(0,Math.min(a,r/2,i/2));e.beginPath(),e.moveTo(t+o,n),e.arcTo(t+r,n,t+r,n+i,o),e.arcTo(t+r,n+i,t,n+i,o),e.arcTo(t,n+i,t,n,o),e.arcTo(t,n,t+r,n,o),e.closePath()}function hl(e){let t=Number(e)||0;return Number.isInteger(t)?String(t):t.toFixed(1)}function gl(e,t,n,r,i){for(let a of $c(t?.fullscreenFrames,n)){let t=Qc(a,n);t<=.001||(e.save(),e.filter=`none`,e.globalAlpha=t,e.fillStyle=pl(e,a.fill,r,i),e.fillRect(0,0,r,i),e.restore())}}function _l(e,t,n,r,i){for(let a of il(t?.figureSweeps,n)){let t=rl(a,nl(a,n)),o=(Number(a.x)||50)/100*r,s=(Number(a.y)||50)/100*i,c=Math.round(i*(fl[a.size]||.1));e.save(),e.filter=`none`,e.textAlign=`center`,e.textBaseline=`middle`,e.shadowColor=`rgba(0,0,0,0.5)`,e.shadowBlur=c*.18,e.shadowOffsetY=c*.04,e.fillStyle=dl.test(String(a.color))?a.color:`#ffffff`,e.font=`800 ${c}px ${ul}`,e.fillText(t,o,s),a.label&&(e.shadowBlur=c*.1,e.font=`600 ${Math.round(c*.28)}px ${ul}`,e.fillStyle=`rgba(255,255,255,0.85)`,e.fillText(a.label,o,s+c*.62)),e.restore()}}function vl(e,t,n,r,i){for(let a of ll(t?.graphs,n)){let t=a.box||{x:55,y:12,w:40,h:40},o={x:t.x/100*r,y:t.y/100*i,w:t.w/100*r,h:t.h/100*i},s=cl(a,o,sl(a,n)),c=Array.isArray(a.palette)&&a.palette.length?a.palette:[`#6ea8ff`,`#9b8cff`,`#5fd0c0`,`#ffd166`],l=Math.max(11,Math.round(o.h*.07));if(e.save(),e.filter=`none`,e.textAlign=`center`,a.title&&(e.fillStyle=`rgba(255,255,255,0.95)`,e.font=`800 ${Math.round(l*1.4)}px ${ul}`,e.textBaseline=`top`,e.fillText(String(a.title).slice(0,40),o.x+o.w/2,o.y)),e.font=`600 ${l}px ${ul}`,s.kind===`bar`)s.bars.forEach((t,n)=>{e.fillStyle=c[n%c.length],ml(e,t.x,t.y,t.w,Math.max(0,t.h),Math.min(6,t.w*.2)),e.fill(),e.fillStyle=`rgba(255,255,255,0.9)`,e.textBaseline=`top`,e.fillText(String(t.label).slice(0,8),t.cx,s.baseY+4),e.textBaseline=`bottom`,e.fillText(`${hl(t.value)}${a.unit||``}`,t.cx,t.y-2)});else if(s.kind===`line`){e.strokeStyle=c[0],e.lineWidth=Math.max(2,o.w*.012),e.lineJoin=`round`;let t=s.pts.slice(0,s.reveal);e.beginPath(),t.forEach((t,n)=>{n===0?e.moveTo(t.x,t.y):e.lineTo(t.x,t.y)}),e.stroke(),e.fillStyle=c[0],t.forEach(t=>{e.beginPath(),e.arc(t.x,t.y,e.lineWidth*1.4,0,Math.PI*2),e.fill()}),e.fillStyle=`rgba(255,255,255,0.85)`,e.textBaseline=`top`,s.pts.forEach(t=>e.fillText(String(t.label).slice(0,8),t.cx,s.baseY+4))}else s.kind===`donut`&&s.arcs.forEach((t,n)=>{t.a1<=t.a0||(e.beginPath(),e.arc(s.cx,s.cy,s.r,t.a0,t.a1),e.arc(s.cx,s.cy,s.inner,t.a1,t.a0,!0),e.closePath(),e.fillStyle=c[n%c.length],e.fill())});e.restore()}}let yl=(e,t,n)=>Math.min(n,Math.max(t,e)),bl=e=>Math.round(e),xl={brightness:0,contrast:0,saturation:0,temperature:0,sharpness:0,vignette:0};function Sl(e){return e===`Cold`?[`hue-rotate(8deg)`,`saturate(1.06)`]:e===`Warm`?[`sepia(0.16)`,`hue-rotate(-7deg)`,`saturate(1.08)`]:e===`Desaturated`?[`saturate(0.48)`]:e===`High Contrast`?[`contrast(1.34)`,`saturate(1.08)`]:e===`Filmic`?[`contrast(1.12)`,`sepia(0.07)`,`saturate(0.94)`]:e===`Teal and Orange`?[`contrast(1.08)`,`saturate(1.18)`,`hue-rotate(-4deg)`]:[]}function Cl(e,t){let n={...xl,...e||{}},r=Sl(t);if(!(n.brightness||n.contrast||n.saturation||n.temperature||n.sharpness)&&r.length===0)return``;let i=yl(n.temperature,-100,100);return[`brightness(${bl(yl(100+n.brightness*.6,10,220))}%)`,`contrast(${bl(yl(100+n.contrast*.7+Math.max(0,n.sharpness)*.18,10,230))}%)`,`saturate(${bl(yl(100+n.saturation,0,260))}%)`,i>0?`sepia(${bl(i*.0025)})`:``,i<0?`hue-rotate(${bl(Math.abs(i)*.12)}deg)`:``,...r].filter(Boolean).join(` `)}function wl({fxEvents:e,liveOverlays:t,playhead:n,frameDims:r}){let i=v.useRef(null);return v.useEffect(()=>{let r=i.current;if(!r)return;let a=r.clientWidth,o=r.clientHeight;if(!a||!o)return;r.width!==a&&(r.width=a),r.height!==o&&(r.height=o);let s=r.getContext(`2d`);s.clearRect(0,0,a,o),Gc(s,{liveOverlays:t},n,a,o,{noFrame:!0}),Yc(s,{fxEvents:e},n,a,o)},[e,t,n,r]),(0,q.jsx)(`canvas`,{ref:i,style:{position:`absolute`,inset:0,width:`100%`,height:`100%`,pointerEvents:`none`,zIndex:15}})}function Tl({editor:e,playhead:t,layer:n,frameDims:r}){let i=v.useRef(null);return v.useEffect(()=>{let r=i.current;if(!r)return;let a=r.clientWidth,o=r.clientHeight;if(!a||!o)return;r.width!==a&&(r.width=a),r.height!==o&&(r.height=o);let s=r.getContext(`2d`);s.clearRect(0,0,a,o),n===`backdrop`?gl(s,e,t,a,o):(_l(s,e,t,a,o),vl(s,e,t,a,o))},[e,t,n,r]),(0,q.jsx)(`canvas`,{ref:i,style:{position:`absolute`,inset:0,width:`100%`,height:`100%`,pointerEvents:`none`,zIndex:n===`backdrop`?14:22}})}Object.freeze({swapAnim:`pop`,emphasisMode:`off`,emphasisKeywords:[],pauseBehavior:`hold`,pauseMs:600,minWordMs:130,allCaps:!1,emphasisScale:1.28,camera:`drift`,trailCount:0,trailLayout:`stackUp`,trailOpacityMin:.25,trailScaleMin:.8,trailMute:.6,trailMuteColor:`#8e8a80`,trailExit:`fade`,reflowMs:120}),Object.freeze({hookOpening:!0,rapidList:!0,emphasisDense:!0,noStrongVisual:!0,budgetPct:.4});let El=(e,t,n)=>Math.min(n,Math.max(t,e)),Dl=e=>{let t=El(e,0,1);return t*t*(3-2*t)},Ol=(e,t,n)=>e+(t-e)*n;function kl(e,t){let n=Math.max(1e-4,Number(t)||0),r=Math.min(.35,n*.5),i=El(e?.animIn==null?r:Number(e.animIn),0,n),a=El(e?.animOut==null?r:Number(e.animOut),0,n);if(i+a>n){let e=n/(i+a);i*=e,a*=e}return{animIn:i,animOut:a}}function Al(e,t,n){let r=e?.animation||`none`,i=Math.max(1e-4,Number(n??(e?.end||0)-(e?.start||0))||0),a=El(Number(t)||0,0,i);if(r===`none`||r===`typewriter`)return{opacity:1,scale:1,tx:0,ty:0};let{animIn:o,animOut:s}=kl(e,i),c=o>0?Dl(a/o):1,l=s>0?Dl((i-a)/s):1,u=a<o,d=a>i-s,f=1,p=1,m=0;switch(r){case`fade`:f=Math.min(c,l);break;case`pop`:u?(p=Ol(.6,1,c),f=c):d&&(f=l);break;case`scale_in_out`:u?(p=Ol(1.6,1,c),f=c):d&&(p=Ol(1,1.6,1-l),f=l);break;case`slide`:u?(m=Ol(.6,0,c),f=c):d&&(m=Ol(0,.6,1-l),f=l);break;case`rise`:u?(m=Ol(.5,0,c),p=Ol(.9,1,c),f=c):d&&(f=l);break;case`word_pop`:u?(p=Ol(.3,1,c),f=c):d&&(p=Ol(1,1.2,1-l),f=l);break;case`word_sequence`:u?(m=Ol(.3,0,c),f=c):d&&(f=l);break;case`word_reveal`:f=Math.min(c,l)}return{opacity:El(f,0,1),scale:p,tx:0,ty:m}}function jl(e,t,n){if(e?.animation!==`typewriter`)return null;let r=String(e?.text||``),i=Math.max(1e-4,Number(n??(e?.end||0)-(e?.start||0))||0),a=Math.min(i,Number(e?.animIn)>0?Number(e.animIn):i*.7),o=El(Number(t)||0,0,i);return Math.round(El(a>0?o/a:1,0,1)*r.length)}function Ml(e,t){if(!Array.isArray(e)||!e.length)return-1;let n=Number(t)||0,r=-1;for(let t=0;t<e.length;t++){let i=Number(e[t].start)||0,a=Number(e[t].end)||0;if(n>=i&&n<=a)return t;if(n>=i)r=t;else break}return r}let Nl={sm:26,md:34,lg:46,xl:62},Pl=new Set,Fl=0,Il=0,Ll=0;function Rl(e){if(Fl=0,Il||=e,e-Ll>=1e3/30-.5){Ll=e;let t=(e-Il)/1e3;for(let e of Array.from(Pl))try{e(t)}catch{}}zl()}function zl(){!Fl&&Pl.size&&(typeof document<`u`&&document.hidden||(Fl=requestAnimationFrame(Rl)))}typeof document<`u`&&document.addEventListener(`visibilitychange`,()=>{document.hidden?Fl&&=(cancelAnimationFrame(Fl),0):(Il=0,Ll=0,zl())});function Bl(e,{active:t=!0}={}){let[n,r]=(0,v.useState)(0),i=Number(e)>0?Number(e):0;return(0,v.useEffect)(()=>{if(!t||!i)return;let e=e=>{let t=e%i;r(e=>Math.abs(e-t)<1e-4?e:t)};return Pl.add(e),zl(),()=>{Pl.delete(e)}},[t,i]),n}let Vl=(e,t=0)=>Number.isFinite(Number(e))?Number(e):t,Hl=e=>!!e&&e.kind!==`audio`,Ul=e=>!!e&&(e.kind===`video`||e.kind!==`vector-scene`&&e.kind!==`v2-scene`&&!!e.url);function Wl(e=[],t=0){let n=(e||[]).filter(Hl);return n.length&&(n.find(e=>t>=Vl(e.start)&&t<Vl(e.start)+Vl(e.duration,0))||n.slice().sort((e,t)=>Vl(e.start)-Vl(t.start))[0])||null}function Gl(e){let t=Vl(e.rotation);if(Number.isFinite(Number(e.x))&&Number.isFinite(Number(e.y)))return{left:`${e.x}%`,top:`${e.y}%`,transform:`translate(-50%, -50%) rotate(${t}deg)`};let n={left:`7%`,right:`7%`,width:`fit-content`,marginLeft:`auto`,marginRight:`auto`},r=e.position||`center`,i=t?` rotate(${t}deg)`:``;return r===`top`||r===`top center`?{...n,top:`14%`,transform:`translate(0, 0)${i}`}:r===`top left`?{left:`16%`,top:`14%`,transform:`translate(0, 0)${i}`}:r===`top right`?{right:`16%`,top:`14%`,transform:`translate(0, 0)${i}`}:r===`bottom`||r===`bottom center`?{...n,bottom:`14%`,transform:`translate(0, 0)${i}`}:r===`bottom left`?{left:`16%`,bottom:`14%`,transform:`translate(0, 0)${i}`}:r===`bottom right`?{right:`16%`,bottom:`14%`,transform:`translate(0, 0)${i}`}:{...n,top:`50%`,transform:`translateY(-50%)${i}`}}let Kl=(e,t)=>{let n=String(e||`#000`).replace(`#`,``),r=n.length===3?n.split(``).map(e=>e+e).join(``):n,i=parseInt(r||`000000`,16);return`rgba(${i>>16&255},${i>>8&255},${i&255},${t})`},ql=e=>jc(e.backgroundOpacity,45),Jl=e=>{let t=Number(e.size);return Number.isFinite(t)&&t>0?t:Nl[e.size]||Nl.md};function Yl({item:e,tAbs:t,scale:n}){let r=e.animation&&e.animation!==`none`,i=Array.isArray(e.words)&&e.words.length>0,a=Gl(e),o=e.background&&e.background!==`none`,s=e.text,c=null;if(r||i){let n=Vl(e.end)-Vl(e.start),r=Al(e,t-Vl(e.start),n),o=a.transform||`translate(-50%, -50%)`,l=r.scale!==1||r.tx!==0||r.ty!==0?` scale(${r.scale}) translate(${(r.tx*100).toFixed(3)}%, ${(r.ty*100).toFixed(3)}%)`:``;if(c={opacity:r.opacity,transform:`${o}${l}`},e.animation===`typewriter`){let r=jl(e,t-Vl(e.start),n);s=r==null?e.text:String(e.text||``).slice(0,r)}else if(i){let n=Ml(e.words,t),r=e.highlightColor||`#ffd400`;s=e.words.map((t,i)=>(0,q.jsxs)(`span`,{style:i===n?{color:r}:void 0,children:[t.text,i<e.words.length-1?` `:``]},i))}}let l=Vl(e.backgroundPadding,10)*n,u=Math.max(4,Vl(e.backgroundPadding,10)+4)*n;return(0,q.jsxs)(`div`,{style:{position:`absolute`,zIndex:20,pointerEvents:`none`,textAlign:`center`,textShadow:o?`none`:`0 2px 8px rgba(0,0,0,0.75)`,fontFamily:e.font||`var(--font)`,fontWeight:700,lineHeight:1.2,fontSize:Jl(e)*n,color:e.color||`#ffffff`,background:o?Kl(e.background,ql(e)):`transparent`,padding:`${l}px ${u}px`,borderRadius:Vl(e.backgroundRadius,5)*n,...a,...c||{}},children:[(0,q.jsx)(`div`,{children:s}),e.subtitle?(0,q.jsx)(`div`,{style:{fontSize:`0.62em`,fontWeight:500,opacity:.88,marginTop:2},children:e.subtitle}):null]})}function Xl({clip:e,style:t}){return e?e.kind===`video`?(0,q.jsx)(`video`,{src:e.url,muted:!0,playsInline:!0,autoPlay:!0,loop:!0,preload:`metadata`,crossOrigin:`anonymous`,style:{position:`absolute`,inset:0,width:`100%`,height:`100%`,objectFit:`cover`,display:`block`,...t}}):Ul(e)?(0,q.jsx)(`img`,{src:e.url,alt:``,crossOrigin:`anonymous`,decoding:`async`,style:{position:`absolute`,inset:0,width:`100%`,height:`100%`,objectFit:`cover`,display:`block`,...t},onError:e=>{e.currentTarget.style.opacity=`0`}}):(0,q.jsx)(Zl,{style:t}):null}function Zl({style:e,label:t}){return(0,q.jsx)(`div`,{style:{position:`absolute`,inset:0,background:`linear-gradient(135deg, #17150f 0%, #2a2519 55%, #14130f 100%)`,display:`flex`,alignItems:`center`,justifyContent:`center`,...e},children:t?(0,q.jsx)(`span`,{style:{fontSize:10,letterSpacing:`0.06em`,textTransform:`uppercase`,color:`rgba(255,255,255,0.42)`,fontFamily:`var(--font)`,padding:`0 8px`,textAlign:`center`},children:t}):null})}let Ql={animated_title:3.5,kinetic_emphasis:2.6,lower_third:4,figure_sweep:2.6,animated_graph:4.5},$l=(e,t)=>({type:e,start:0,end:Ql[e]||3.5,...t}),eu=/(\\$|€|£)?\\s*(\\d[\\d,]*(?:\\.\\d+)?)\\s*(%|x|×|k|m|b|bn|\\+|°|pts?|fps)?/i;function tu(e){let t=eu.exec(String(e||``));if(!t)return null;let n=Number(t[2].replace(/,/g,``));if(!Number.isFinite(n))return null;let r=/\\.\\d/.test(t[2])?Math.min(2,t[2].split(`.`)[1].length):0;return{value:n,prefix:t[1]||``,suffix:t[3]?t[3].toUpperCase().replace(`BN`,`B`):``,decimals:r}}function nu(e){let t=String(e||``).trim(),n=null,r=/\\blabel(?:ed|s|led)?\\b[:\\s]*(.+)$/i.exec(t);r&&(n=r[1].split(/[,/|]| and /i).map(e=>e.trim()).filter(Boolean),t=t.slice(0,r.index).trim());let i=/\\(([^)]+)\\)\\s*$/.exec(t);!n&&i&&(n=i[1].split(/[,/|]| and /i).map(e=>e.trim()).filter(Boolean),t=t.slice(0,i.index).trim());let a=t.split(/\\s*(?:,|\\/|\\||;|\\bto\\b|\\band\\b|\\bvs\\.?\\b)\\s*/i).map(e=>e.trim()).filter(Boolean),o=[];return a.forEach((e,t)=>{let r=tu(e);if(!r)return;let i=e.replace(eu,``).replace(/[:\\-–]/g,` `).trim();!i&&n&&n[o.length]&&(i=n[o.length]),o.push({label:i||n&&n[t]||``,value:r.value})}),o.length>=2?o:null}function ru(e,t){let n=e.indexOf(`:`);return n>=0?e.slice(n+1).trim():e.replace(t,``).replace(/^[\\s:\\-–]+/,``).trim()}function iu(e){let t=String(e||``).trim();if(!t)return null;let n=t.toLowerCase(),r=/\\b(bar|line|donut|doughnut|pie)\\b/.exec(n);if(r&&/\\d.*\\d/.test(t)){let e=nu(ru(t,/\\b(bar|line|donut|doughnut|pie)\\s*(chart|graph)?\\b/i));if(e){let n=r[1],i=n===`line`?`line`:n===`bar`?`bar`:`donut`,a=/%/.test(t);return{elements:[$l(`animated_graph`,{chart:i,series:e,unit:a?`%`:``,mode:`overlay`})]}}}if(/\\b(lower[\\s-]?third|name\\s?(?:bar|tag|plate)|nametag)\\b/.test(n)){let e=ru(t,/\\b(lower[\\s-]?third|name\\s?(?:bar|tag|plate)|nametag)\\b/i);if(e){let[t,...n]=e.split(/\\s*(?:,|\\||\\bas\\b|-|–|\\()\\s*/i),r=n.join(`, `).replace(/\\)\\s*$/,``).trim(),i={text:t.trim(),mode:`overlay`};return r&&(i.subtitle=r),{elements:[$l(`lower_third`,i)]}}}if(/\\b(count(?:er|\\s?up)?|figure|number|stat|tick(?:\\s?up)?)\\b/.test(n)||/^(\\$|€|£)?\\s*\\d[\\d,]*(?:\\.\\d+)?\\s*(%|x|k|m|b)?\\s*$/i.test(t)){let e=ru(t,/\\b(count(?:er|\\s?up)?(?:\\s?to)?|figure|number|stat|tick(?:\\s?up)?)\\b/i),n=tu(e||t);if(n){let r=(e||t).replace(eu,``).replace(/\\b(to|up|the|a)\\b/gi,``).replace(/[:\\-–]/g,` `).trim(),i={value:n.value,decimals:n.decimals,mode:`overlay`};return n.prefix&&(i.prefix=n.prefix),n.suffix&&(i.suffix=n.suffix),r&&(i.label=r.slice(0,80)),{elements:[$l(`figure_sweep`,i)]}}}if(/\\b(kinetic|emphasi[sz]e?|punch(?:line)?|callout|big\\s?text)\\b/.test(n)){let e=ru(t,/\\b(kinetic(?:\\stext)?|emphasi[sz]e?|punch(?:line)?|callout|big\\s?text)\\b/i);if(e)return{elements:[$l(`kinetic_emphasis`,{text:e,mode:`overlay`})]}}if(/\\b(title|chapter|heading|headline|card|section)\\b/.test(n)){let e=ru(t,/\\b(animated\\s)?(title(?:\\scard)?|chapter(?:\\scard)?|heading|headline|card|section)\\b/i);if(e){let t={text:e,style:{position:`center`,size:`lg`},animation:`reveal`,mode:`overlay`},n=/\\s[-–]\\s/.exec(e);return n&&(t.text=e.slice(0,n.index).trim(),t.subtitle=e.slice(n.index+n[0].length).trim()),{elements:[t.subtitle?{...$l(`animated_title`,t)}:$l(`animated_title`,t)]}}}return null}let au=e=>/^#[0-9a-fA-F]{6}$/.test(String(e)),ou=(e,t,n)=>{let r=Math.round(Number(e));return Number.isFinite(r)?Math.min(n,Math.max(t,r)):t},su=[`#6ea8ff`,`#9b8cff`,`#5fd0c0`,`#ffd166`,`#ff7b9c`,`#7ee787`];function cu(e,{clipsById:t={}}={}){let n=[],r=[],i=[],a=[],o=[],s=[];return(Array.isArray(e?.elements)?e.elements:[]).forEach((e,o)=>{if(!e||typeof e!=`object`)return;let c=String(e.reason||``),l=Number(e.start)||0,u=Number(e.end)||0,d=e.mode===`fullscreen`?`fullscreen`:`overlay`;switch(e.type){case`animated_title`:{let t={id:`mg-title-${o}`,trackId:`captions`,start:l,end:u,text:String(e.text||``),position:e.style?.position===`top`?`top`:e.style?.position===`bottom`?`bottom`:`center`,size:e.style?.size||`lg`,animation:e.animation||`reveal`,reason:c,polish:!0,mgTitle:!0};d===`fullscreen`&&(t.background=`#000000`,t.backgroundOpacity=34),e.subtitle&&(t.subtitle=String(e.subtitle)),n.push(t);break}case`kinetic_emphasis`:r.push({id:`mg-kinetic-${o}`,trackId:`text`,start:l,end:u,text:String(e.text||``),position:e.style?.position||`center`,size:e.style?.size||`xl`,animation:e.animation||`word_sequence`,words:Array.isArray(e.words)?e.words:null,emphasis:!0,reason:c,polish:!0});break;case`lower_third`:{let t={id:`mg-lower-${o}`,trackId:`captions`,start:l,end:u,text:String(e.text||``),position:`lower_third`,size:`m`,animation:`rise`,background:au(e.accent)?e.accent:`#111418`,backgroundOpacity:85,reason:c,polish:!0};e.subtitle&&(t.subtitle=String(e.subtitle)),n.push(t);break}case`figure_sweep`:a.push({id:`mg-figure-${o}`,trackId:`overlay`,start:l,end:u,value:Number(e.value)||0,prefix:e.prefix?String(e.prefix):``,suffix:e.suffix?String(e.suffix):``,label:e.label?String(e.label):``,decimals:ou(e.decimals,0,2),easing:e.easing||`ease-out`,x:50,y:50,size:d===`fullscreen`?`xl`:`lg`,color:`#ffffff`,reason:c,polish:!0});break;case`animated_graph`:i.push({id:`mg-graph-${o}`,trackId:`overlay`,start:l,end:u,chart:e.chart||`bar`,series:Array.isArray(e.series)?e.series.map(e=>({label:String(e?.label||``),value:Number(e?.value)||0})):[],unit:e.unit?String(e.unit):``,title:e.title?String(e.title):``,box:d===`fullscreen`?{x:12,y:16,w:76,h:66}:{x:54,y:10,w:42,h:42},palette:su,easing:e.easing||`ease-out`,reason:c,polish:!0});break;case`graphic_transition`:{let n=e.on_cut_between?.[0];if(!t[n])return;s.push({clipId:n,transition:{type:e.style||`wipe`,duration:Number(e.duration)||.5}});break}}}),{captions:n,textOverlays:r,graphs:i,figureSweeps:a,fullscreenFrames:o,clipPatches:s}}let lu=`#0C0B09`;function uu(e,t,n,r,i,a){let o=Math.max(0,Math.min(a,Math.min(r,i)/2));e.beginPath(),e.moveTo(t+o,n),e.arcTo(t+r,n,t+r,n+i,o),e.arcTo(t+r,n+i,t,n+i,o),e.arcTo(t,n+i,t,n,o),e.arcTo(t,n,t+r,n,o),e.closePath()}function du(e,t,n,r,i){let a=String(t).split(``),o=a.map(t=>e.measureText(t).width),s=n-(o.reduce((e,t)=>e+t,0)+i*(a.length-1))/2;e.textAlign=`left`;for(let t=0;t<a.length;t++)e.fillText(a[t],s,r),s+=o[t]+i;e.textAlign=`center`}function fu(e,t,n,r=`ref`){if(!(t>0)||!(n>0))return;let i=r===`b`;e.save(),e.fillStyle=lu,e.fillRect(0,0,t,n),e.strokeStyle=`rgba(255,255,255,${i?.075:.05})`,e.lineWidth=1;let a=i?.5:0;e.beginPath();for(let r=-1;r<=8;r++){let i=Math.round((r+a)/8*t)+.5;e.moveTo(i,0),e.lineTo(i,n)}for(let r=-1;r<=5;r++){let i=Math.round((r+a)/5*n)+.5;e.moveTo(0,i),e.lineTo(t,i)}e.stroke();let o=t*.56,s=n*.48,c=(t-o)/2,l=(n-s)/2;uu(e,c,l,o,s,Math.min(o,s)*.11),e.fillStyle=`rgba(255,255,255,${i?.135:.055})`,e.fill(),e.strokeStyle=`rgba(255,255,255,${i?.3:.16})`,e.lineWidth=Math.max(1,n*.004),e.stroke(),e.textBaseline=`middle`,e.textAlign=`center`,e.fillStyle=`rgba(255,255,255,${i?.66:.46})`;let u=Math.max(7,Math.round(n*.082));e.font=`700 ${u}px \"Hanken Grotesk\", system-ui, sans-serif`,du(e,`STILLMADE`,t/2,l+s*.4,u*.22),e.fillStyle=`rgba(255,255,255,${i?.24:.13})`;let d=Math.max(1,n*.014),f=l+s*.66;e.fillRect(t/2-o*.26,f,o*.52,d),e.fillRect(t/2-o*.16,f+d*2.2,o*.32,d),(r===`a`||r===`b`)&&(e.fillStyle=`rgba(255,255,255,${i?.42:.3})`,e.font=`800 ${Math.max(9,Math.round(n*.1))}px \"Hanken Grotesk\", system-ui, sans-serif`,e.textAlign=`left`,e.fillText(r.toUpperCase(),t*.055,n*.11)),e.restore()}function pu({item:e={},tLocal:t=0,dur:n=0,scale:r=1,rotation:i=0,style:a,children:o,...s}){let c=jo(t,n),l=Mo(t,n),u=c.bell*180/Math.PI,d=r*c.scale*c.press;return(0,q.jsxs)(`div`,{...s,style:{position:`absolute`,left:`50%`,top:`50%`,...a,width:190,height:52,opacity:c.opacity*Math.min(Math.max(e.opacity??.85,0),1),transform:`translate(-50%, -50%) rotate(${i+c.foldRot*180/Math.PI}deg) scale(${d*c.foldX}, ${d*c.foldY})`},children:[(0,q.jsxs)(`svg`,{viewBox:`0 0 190 52`,width:`100%`,height:`100%`,style:{display:`block`,overflow:`visible`},preserveAspectRatio:`xMidYMid meet`,children:[(0,q.jsx)(`rect`,{x:`0`,y:`0`,width:190,height:52,rx:`15`,fill:e.color||`#cc0000`}),(0,q.jsxs)(`g`,{transform:`translate(29 26) rotate(${u})`,fill:`#ffffff`,children:[(0,q.jsx)(`path`,{d:`M -8.32 7.28 Q -9.36 2.6 -7.28 -1.56 Q -6.24 -8.84 0 -9.36 Q 6.24 -8.84 7.28 -1.56 Q 9.36 2.6 8.32 7.28 Z`}),(0,q.jsx)(`circle`,{cx:`0`,cy:`10.4`,r:`2.86`}),(0,q.jsx)(`circle`,{cx:`0`,cy:`-10.92`,r:`2.08`})]}),(0,q.jsx)(`text`,{x:`53`,y:`27`,fill:`#ffffff`,fontWeight:`bold`,fontSize:`22`,fontFamily:`\"Hanken Grotesk\", sans-serif`,textAnchor:`start`,dominantBaseline:`middle`,children:e.text||`SUBSCRIBE`}),l.opacity>.01&&(0,q.jsxs)(`g`,{opacity:l.opacity,transform:`translate(${l.x} ${l.y})`,children:[l.click>.01&&(0,q.jsx)(`circle`,{cx:`0`,cy:`0`,r:3+l.click*9,fill:`none`,stroke:`#ffffff`,strokeWidth:`1.6`,opacity:l.click*.5}),(0,q.jsx)(`g`,{transform:`scale(${1.25*(1-l.click*.14)})`,children:(0,q.jsx)(`path`,{d:`M0 0 L0 17 L4.3 13 L7.1 18.7 L9.2 17.7 L6.4 12 L11.8 11.6 Z`,fill:`#ffffff`,stroke:`rgba(0,0,0,0.6)`,strokeWidth:`1.2`,strokeLinejoin:`round`})})]})]}),o]})}let mu=2.4,hu=.35,gu=1.8,_u=.6,vu={id:`pv-typing`,text:`Type your text`,size:40,position:`center`,animation:`typewriter`,start:0,end:3},yu=(e,t=0)=>Number.isFinite(Number(e))?Number(e):t;function bu({variant:e=`ref`,style:t}){let n=(0,v.useRef)(null);return(0,v.useEffect)(()=>{let t=n.current;if(!t)return;let r=()=>{let n=t.clientWidth,r=t.clientHeight;if(!n||!r)return;let i=Math.min(2,typeof window<`u`&&window.devicePixelRatio||1),a=Math.round(n*i),o=Math.round(r*i);(t.width!==a||t.height!==o)&&(t.width=a,t.height=o);let s=t.getContext(`2d`);s.setTransform(i,0,0,i,0,0),fu(s,n,r,e)};if(r(),typeof ResizeObserver>`u`)return;let i=new ResizeObserver(r);return i.observe(t),()=>i.disconnect()},[e]),(0,q.jsx)(`canvas`,{ref:n,style:{position:`absolute`,inset:0,width:`100%`,height:`100%`,display:`block`,...t}})}function xu({filter:e}){return(0,q.jsxs)(`div`,{style:{position:`absolute`,inset:0,display:`flex`,flexDirection:`column`,...e?{filter:e}:{}},children:[(0,q.jsxs)(`div`,{style:{flex:1,display:`flex`},children:[(0,q.jsx)(`div`,{style:{flex:1,background:`linear-gradient(160deg, #d9a882 0%, #b07d57 100%)`}}),(0,q.jsx)(`div`,{style:{flex:1,background:`linear-gradient(160deg, #7ea6cc 0%, #3f6c96 100%)`}}),(0,q.jsx)(`div`,{style:{flex:1,background:`linear-gradient(160deg, #4a6b4c 0%, #263a28 100%)`}})]}),(0,q.jsx)(`div`,{style:{height:`30%`,background:`linear-gradient(90deg, #0a0a0a 0%, #7d7d7d 50%, #f2f2f2 100%)`}})]})}function Su({item:e,scale:t,pulse:n,t:r=0}){let i=e.color||`var(--accent)`,a=e.shape||`circle`,o=e=>e*t;if(a===`subscribe`)return(0,q.jsx)(pu,{item:e,tLocal:yu(r),dur:4,scale:t,style:{filter:`drop-shadow(0 3px 6px rgba(0,0,0,0.35))`,pointerEvents:`none`}});let s={position:`absolute`,left:`50%`,top:`50%`,transform:`translate(-50%, -50%) scale(${n})`,opacity:yu(e.opacity,.85),pointerEvents:`none`},c=null;return c=a===`arrow`?(0,q.jsx)(`div`,{style:{width:o(80),height:0,borderTop:`${o(6)}px solid ${i}`,position:`relative`},children:(0,q.jsx)(`span`,{style:{position:`absolute`,right:o(-10),top:o(-10),width:0,height:0,borderLeft:`${o(14)}px solid ${i}`,borderTop:`${o(10)}px solid transparent`,borderBottom:`${o(10)}px solid transparent`}})}):a===`highlight`?(0,q.jsx)(`div`,{style:{width:o(120),height:o(28),background:i,opacity:.6,borderRadius:o(4)}}):a===`frame`?(0,q.jsx)(`div`,{style:{width:o(140),height:o(90),border:`${o(3)}px solid ${i}`,borderRadius:o(6)}}):a===`underline`?(0,q.jsx)(`div`,{style:{width:o(100),height:o(4),background:i,borderRadius:o(2)}}):(0,q.jsx)(`div`,{style:{width:o(80),height:o(80),borderRadius:`50%`,border:`${o(4)}px solid ${i}`}}),(0,q.jsx)(`div`,{style:s,children:c})}function Cu({type:e,t,withSound:n=!1}){let r=(0,v.useRef)(null),i=(0,v.useRef)(null),a=(0,v.useRef)(1);return(0,v.useEffect)(()=>()=>{try{i.current?.pause()}catch{}},[]),(0,v.useEffect)(()=>{let o=r.current;if(!o)return;let s=o.clientWidth,c=o.clientHeight;if(!s||!c)return;let l=Math.min(2,typeof window<`u`&&window.devicePixelRatio||1),u=Math.round(s*l),d=Math.round(c*l);(o.width!==u||o.height!==d)&&(o.width=u,o.height=d);let f=o.getContext(`2d`);f.setTransform(l,0,0,l,0,0),f.clearRect(0,0,s,c),f.fillStyle=lu,f.fillRect(0,0,s,c);let p=yu(t)%gu,m=p<hu?0:p<1.35?(p-hu)/1:1,h=n?Lo[e]:null;if(h&&a.current===0&&m>0)try{(!i.current||!i.current.src.endsWith(No[h].url))&&(i.current=new Audio(No[h].url),i.current.volume=.7),i.current.currentTime=0,i.current.play().catch(()=>{})}catch{}if(a.current=m,e===`Cut`){fu(f,s,c,m<.5?`a`:`b`);return}let g=go(e,m),_=(e,t)=>{if(e&&e.alpha>.001){if(f.save(),f.globalAlpha=Math.min(1,Math.max(0,e.alpha)),e.clip){let[t,n,r,i]=e.clip;f.beginPath(),f.rect(i/100*s,t/100*c,(100-i-n)/100*s,(100-t-r)/100*c),f.clip()}e.shape!=null&&Co(f,e,s,c),(e.tx||e.ty)&&f.translate((e.tx||0)/100*s,(e.ty||0)/100*c),(e.rot||e.scale&&e.scale!==1)&&(f.translate(s/2,c/2),e.rot&&f.rotate(e.rot*Math.PI/180),e.scale&&e.scale!==1&&f.scale(e.scale,e.scale),f.translate(-s/2,-c/2)),fu(f,s,c,t),f.restore()}};_(g.out,`a`),_(g.in,`b`),g.overlay&&g.overlay.alpha>.001&&(f.save(),f.globalAlpha=Math.min(1,g.overlay.alpha),f.fillStyle=g.overlay.color,f.fillRect(0,0,s,c),f.restore())},[e,t]),(0,q.jsx)(`canvas`,{ref:r,style:{position:`absolute`,inset:0,width:`100%`,height:`100%`,display:`block`}})}function wu(e){let t=iu(e);if(!t)return null;let n=cu(t,{clipsById:{}}),r=e=>e.position===`lower_third`?{...e,position:`bottom left`}:e;return{captions:(n.captions||[]).map(r),textOverlays:(n.textOverlays||[]).map(r),graphs:n.graphs||[],figureSweeps:n.figureSweeps||[],fullscreenFrames:n.fullscreenFrames||[]}}function Tu(e){let t=0;for(let n of[`captions`,`textOverlays`,`graphs`,`figureSweeps`,`fullscreenFrames`])for(let r of e?.[n]||[])t=Math.max(t,yu(r.end));return Math.max(1.5,t+_u)}function Eu(e,t){return e===`sticker`?t?.shape===`subscribe`?4:mu:e===`fxEvent`?2:e===`liveOverlay`?3:e===`transition`?gu:e===`textOverlay`?Math.max(1.5,yu(t?.end)-yu(t?.start)+_u):e===`motionGraphic`?Tu(wu(t?.prompt)):0}function Du({kind:e,item:t,clips:n=[],playhead:r=0,t:i,inView:a=!0,withSound:o=!1,style:s}){let c=(0,v.useRef)(null),[l,u]=(0,v.useState)(369);(0,v.useEffect)(()=>{let e=c.current;if(!e)return;let t=()=>u(e.clientHeight||369);if(t(),typeof ResizeObserver>`u`)return;let n=new ResizeObserver(t);return n.observe(e),()=>n.disconnect()},[]);let d=Number.isFinite(Number(i)),f=Bl((0,v.useMemo)(()=>Eu(e,t),[e,t]),{active:a&&!d}),p=d?Number(i):f,m=(l||369)/369,h={position:`relative`,overflow:`hidden`,background:lu,...s},g=(0,v.useMemo)(()=>e===`fxEvent`?[{id:`pv-fx-${t?.kind}`,kind:t?.kind,start:.25,end:1.45,intensity:yu(t?.intensity,.8),repeat:1}]:[],[e,t]),_=(0,v.useMemo)(()=>e===`liveOverlay`?[{id:`pv-ov-${t?.kind}`,kind:t?.kind,start:0,end:3,intensity:yu(t?.intensity,.65)}]:[],[e,t]),y=(0,v.useMemo)(()=>{if(e!==`fxEvent`)return null;let t=Ko(g,p);if(!t.length)return null;let n=ds(t,p),r=fs(t,p,l/1080);return{transform:`translate(${(n.dx*100).toFixed(3)}%, ${(n.dy*100).toFixed(3)}%) rotate(${n.rot.toFixed(3)}deg) scale(${(n.scale*n.pad).toFixed(4)})`,transformOrigin:`50% 50%`,...r?{filter:r}:{}}},[e,g,p,l]),b=(0,v.useMemo)(()=>e===`motionGraphic`?wu(t?.prompt):null,[e,t]),x=(0,v.useMemo)(()=>({fullscreenFrames:b?.fullscreenFrames||[],figureSweeps:b?.figureSweeps||[],graphs:b?.graphs||[]}),[b]);if(e===`look`){let e=Cl(t?.color,t?.lut)||void 0,i=Wl(n,r);return(0,q.jsx)(`div`,{ref:c,style:h,children:i?(0,q.jsx)(Xl,{clip:i,style:e?{filter:e}:void 0}):(0,q.jsx)(xu,{filter:e})})}if(e===`transition`)return(0,q.jsx)(`div`,{ref:c,style:h,children:a?(0,q.jsx)(Cu,{type:t?.type||t,t:p,withSound:o}):(0,q.jsx)(bu,{variant:`a`})});if(e===`sticker`){let e=t?.shape===`subscribe`?1:1+.055*Math.sin(p/mu*Math.PI*2);return(0,q.jsxs)(`div`,{ref:c,style:h,children:[(0,q.jsx)(bu,{}),(0,q.jsx)(Su,{item:t||{},scale:m,pulse:e,t:p})]})}if(e===`textOverlay`){let e=t||vu,n=p>=yu(e.start)&&p<=yu(e.end);return(0,q.jsxs)(`div`,{ref:c,style:h,children:[(0,q.jsx)(bu,{}),n?(0,q.jsx)(Yl,{item:e,tAbs:p,scale:m}):null]})}if(e===`motionGraphic`){let e=[...b?.captions||[],...b?.textOverlays||[]].filter(e=>p>=yu(e.start)&&p<=yu(e.end)),t=x.graphs.length+x.figureSweeps.length+x.fullscreenFrames.length>0;return(0,q.jsxs)(`div`,{ref:c,style:h,children:[(0,q.jsx)(bu,{}),t&&(0,q.jsx)(Tl,{editor:x,playhead:p,layer:`backdrop`,frameDims:l}),t&&(0,q.jsx)(Tl,{editor:x,playhead:p,layer:`overlay`,frameDims:l}),e.map(e=>(0,q.jsx)(Yl,{item:e,tAbs:p,scale:m},e.id))]})}return(0,q.jsxs)(`div`,{ref:c,style:h,children:[(0,q.jsx)(`div`,{style:{position:`absolute`,inset:0,...y||{}},children:(0,q.jsx)(bu,{})}),(0,q.jsx)(wl,{fxEvents:g,liveOverlays:_,playhead:p,frameDims:l})]})}let Ou={ready:`saved`,dirty:`saving`,pending:`saving`,closed:`offline`},ku=e=>e.sourceConflict||e.error?`conflict`:Ou[e.phase]||(e.pending||e.dirty?`saving`:`saved`);function Au(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:ku(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 ju=/~?\\s*(\\d{1,4}(?:,\\d{3})*)\\s*(?:cr|credits?)\\b/gi;function Mu(e){let t=0;for(let n of String(e||``).matchAll(ju))t=Math.max(t,Number(n[1].replace(/,/g,``)));return t}function Nu({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`?Mu(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,q.jsx)(`div`,{role:`status`,\"aria-live\":`polite`,style:Pu.notices,children:o.map(e=>(0,q.jsxs)(`div`,{style:{...Pu.notice,...e.tone===`error`?Pu.noticeError:{}},children:[e.text,e.tone===`error`&&(0,q.jsx)(`button`,{type:`button`,\"aria-label\":`Close`,style:Pu.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,q.jsxs)(q.Fragment,{children:[i,(0,q.jsx)(`div`,{role:`presentation`,style:Pu.backdrop,onClick:e=>{e.target===e.currentTarget&&s(r.kind===`alert`)},children:(0,q.jsxs)(`div`,{role:`dialog`,\"aria-modal\":`true`,\"aria-label\":r.title||`Message`,style:Pu.box,children:[r.title&&(0,q.jsx)(`strong`,{style:Pu.title,children:r.title}),(0,q.jsx)(`p`,{style:Pu.message,children:r.message}),(0,q.jsxs)(`div`,{style:Pu.actions,children:[r.kind===`confirm`&&(0,q.jsx)(`button`,{type:`button`,className:`btn btn-secondary`,onClick:()=>s(!1),children:r.cancelLabel}),(0,q.jsx)(`button`,{type:`button`,className:`btn btn-primary`,autoFocus:!0,onClick:()=>s(!0),children:r.confirmLabel})]})]})})]})}return{ui:d,toast:u,DialogHost:f}}let Pu={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)`}},Fu=new Set([`image`,`video`,`audio`]),Iu=e=>!!e&&typeof e==`object`&&Fu.has(e.kind)&&typeof e.url==`string`&&typeof e.assetId==`string`&&typeof e.versionId==`string`;function Lu(e,t=new Map,n=0){if(!e||typeof e!=`object`||n>12)return t;if(Iu(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))Lu(r,t,n+1);return t}function Ru(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 zu(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 Lu(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`?Ru(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 Bu=[`HTMLImageElement`,`HTMLMediaElement`,`HTMLSourceElement`];function Vu(e){let t=[],n=e=>Bu.some(t=>globalThis[t]&&e instanceof globalThis[t]),r=(t,n,r)=>typeof n!=`string`||!e.refFor(n)?(t.dataset&&delete t.dataset.stillmadeSource,!1):(t.dataset.stillmadeSource=n,e.load(n).then(e=>{t.dataset.stillmadeSource===n&&r(e)},()=>{t.dataset.stillmadeSource===n&&r(n)}),!0);for(let e of Bu){let n=globalThis[e],i=n&&Object.getOwnPropertyDescriptor(n.prototype,`src`);i?.set&&(Object.defineProperty(n.prototype,\"src\",{configurable:!0,enumerable:i.enumerable,get(){return i.get.call(this)},set(e){r(this,e,e=>i.set.call(this,e))||i.set.call(this,e)}}),t.push(()=>Object.defineProperty(n.prototype,\"src\",i)))}let i=globalThis.Element?.prototype.setAttribute;return i&&(globalThis.Element.prototype.setAttribute=function(e,t){if(!(String(e).toLowerCase()===`src`&&n(this)&&r(this,String(t),t=>i.call(this,e,t))))return i.call(this,e,t)},t.push(()=>{globalThis.Element.prototype.setAttribute=i})),()=>{for(let e of t)e()}}let Hu=Object.freeze([`auto`,`21:9`,`16:9`,`3:2`,`4:3`,`1:1`,`4:5`,`3:4`,`2:3`,`9:16`]),Uu=Object.freeze([`auto`,`21:9`,`16:9`,`4:3`,`1:1`,`3:4`,`9:16`]),Wu=Object.freeze([4,5,6,7,8,9,10,11,12,13,14,15]),Gu=(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}),Ku=(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}),qu=Object.freeze({\"nano-banana-2\":Gu(`Nano Banana 2`,{aspectRatios:Hu,resolutions:[`1K`,`2K`,`4K`],references:8,seed:!0}),\"nano-banana-2-lite\":Gu(`Nano Banana 2 Lite`,{aspectRatios:Hu,resolutions:[`1K`,`2K`,`4K`],references:8,seed:!0}),\"nano-banana-pro\":Gu(`Nano Banana Pro`,{aspectRatios:Hu,resolutions:[`1K`,`2K`,`4K`],references:8,seed:!0}),\"gpt-image-2\":Gu(`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\":Gu(`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\":Gu(`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\":Gu(`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\":Gu(`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\":Gu(`GPT-Image 1.5`,{aspectRatios:[`16:9`,`9:16`,`1:1`],qualities:[`low`,`medium`,`high`]}),\"kling-image-v3\":Gu(`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\":Gu(`Seedream 4.5`,{aspectRatios:[`16:9`,`9:16`,`1:1`,`4:3`,`3:4`],resolutions:[`2K`,`4K`],seed:!0})}),Ju=Object.freeze({\"seedance-2.0\":Ku(`Seedance 2.0`,{aspectRatios:Uu,resolutions:[`480p`,`720p`,`1080p`,`4k`],durations:Wu,lastFrame:!0,seed:!0,nativeAudio:!0}),\"seedance-2.0-fast\":Ku(`Seedance 2.0 Fast`,{aspectRatios:Uu,resolutions:[`480p`,`720p`],durations:Wu,lastFrame:!0,seed:!0,nativeAudio:!0}),\"seedance-2.0-mini\":Ku(`Seedance 2.0 Mini`,{aspectRatios:Uu,resolutions:[`480p`,`720p`],durations:Wu,lastFrame:!0,seed:!0,nativeAudio:!0}),\"kling-v3-turbo\":Ku(`Kling 3.0 Turbo`,{aspectRatios:[`16:9`,`9:16`,`1:1`],durations:[5,10]}),\"wan-2.6-flash\":Ku(`Wan 2.6 Flash`,{aspectRatios:[`16:9`,`9:16`,`1:1`],durations:[3,4,5],requiresFirstFrame:!0}),\"veo-3.1-lite\":Ku(`Veo 3.1 Lite`,{aspectRatios:[`16:9`,`9:16`],resolutions:[`720p`,`1080p`],durations:[4,6,8],lastFrame:!0,nativeAudio:!0}),\"vidu-q3-turbo\":Ku(`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\":Ku(`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 Yu=[{value:`low`,label:`Low`},{value:`medium`,label:`Medium`},{value:`high`,label:`High`}],Xu=e=>{let t=qu[e];return{value:e,label:t.label,supports:{aspectRatio:[...t.aspectRatios],resolution:[...t.resolutions],quality:[...t.qualities]}}},Zu=e=>{let t=Ju[e];return{value:e,label:t.label,supports:{aspectRatio:[...t.aspectRatios],resolution:[...t.resolutions],quality:[],duration:[...t.durations]}}},Qu=[`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(Xu),$u=[{value:`seedance-2.5`,label:`Seedance 2.5`,disabled:!0,note:`Coming Soon!`,supports:{aspectRatio:[],resolution:[],quality:[],duration:[]}},...[`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(Zu)];function ed(e,t){return(e===`video`?$u:Qu).find(e=>e.value===t)?.supports||{aspectRatio:[],resolution:[],quality:[],duration:[]}}var td=c({APP_AI_BUDGET_USD:()=>Ad,BLOCK_BUILD_BUDGET_USD:()=>Ed,CHAT_REPLY_BUDGET_USD:()=>Dd,CHAT_WEB_SEARCH_USD:()=>Od,CREDIT_VALUE_USD:()=>nd,FLAT:()=>Td,IMAGE:()=>fd,LARGEST_TEXT_CALL:()=>bd,MARKUP:()=>rd,MUSIC:()=>md,SFX:()=>hd,SPEECH:()=>pd,TEXT_MODELS:()=>gd,TEXT_MODELS_CHECKED:()=>_d,TYPICAL_TEXT_CALL:()=>yd,UNREPORTED_CALL_USD:()=>kd,VIDEO:()=>ud,VIDEO_ALIASES:()=>dd,exactCredits:()=>id,imageUsd:()=>Nd,largestTextCallUsd:()=>wd,milliCredits:()=>od,musicUsd:()=>Id,sfxUsd:()=>Ld,sizedTextCallCredits:()=>Sd,speechUsd:()=>Fd,textCallCredits:()=>xd,typicalTextCallUsd:()=>Cd,usdCoveredBy:()=>sd,videoModelId:()=>Md,videoUsd:()=>Pd,wholeCredits:()=>ad});let nd=2399/11e4,rd=Object.freeze({video:3,build:3,media:4.5,other:3,chat:2}),id=(e,t)=>Math.max(0,Number(e)||0)*rd[t]/nd,ad=(e,t)=>Math.max(1,Math.ceil(id(e,t)-1e-9)),od=(e,t=`chat`)=>Math.ceil(id(e,t)*1e3-1e-6),sd=(e,t)=>Math.max(0,Number(e)||0)*nd/rd[t],cd=`2026-11-05`,ld=`carried`,ud=Object.freeze({\"veo-3.1-lite\":{usd:.05,resolution:{\"720p\":1,\"1080p\":1.6},provider:`Atlas`,checked:cd,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:cd,source:`Atlas catalog list price (we pay $0.034)`},\"wan-2.6-flash\":{usd:.025,provider:`Atlas`,checked:cd,source:`Atlas catalog list price (we pay $0.018)`},\"wan-2.7\":{usd:.17,provider:`Higgsfield, then Atlas`,checked:ld,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:cd,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:ld,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:ld,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:ld,source:`priced as Fast, carried from the old table (Atlas lists $0.056/s)`}}),dd=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`}),fd=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:cd,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:cd,source:`fal price for a non-square image`},\"nano-banana-2\":{usd:.08,resolution:{\"1K\":1,\"2K\":1.5,\"4K\":2},provider:`fal`,checked:cd,source:`fal: $0.08 at 1K, 1.5x at 2K, 2x at 4K`},\"nano-banana-2-lite\":{usd:.048,provider:`fal`,checked:cd,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:cd,source:`fal: $0.15, 4K at double`},\"kling-image-v3\":{usd:.028,provider:`fal`,checked:cd,source:`fal: $0.028 per image`},\"seedream-v4.5\":{usd:.04,provider:`fal`,checked:cd,source:`fal: $0.04 per image`},\"flux-step\":{usd:.02,provider:`fal`,checked:ld,source:`carried from the old table`},flux:{usd:.04,provider:`fal`,checked:ld,source:`carried from the old table`},ideogram:{usd:.08,provider:`fal`,checked:ld,source:`carried from the old table`},gemini:{usd:.08,resolution:{\"1K\":1,\"2K\":1.5,\"4K\":2},provider:`fal`,checked:cd,source:`served as Nano Banana 2`}}),pd=Object.freeze({deepgram:{usdPer1kChars:.03,checked:cd,source:`Deepgram Aura-2 pay as you go`},openai:{usdPer1kChars:.015,checked:cd,source:`OpenAI tts-1, $15 per million characters`},elevenlabs:{usdPer1kChars:.04,checked:cd,source:`ElevenLabs API, Flash / Turbo`},kokoro:{usdPer1kChars:.02,checked:cd,source:`fal Kokoro`}}),md=Object.freeze({usdPerSecond:2e-4,checked:cd,source:`fal ACE-Step, per second of audio`}),hd=Object.freeze({usdPerSecond:.002,checked:cd,source:`fal ElevenLabs sound effects v2, per second`}),gd=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}}),_d=cd,vd=(e,t,n)=>{let r=gd[e];return r?(t*r.input+n*r.output)/1e6:null},yd=Object.freeze({input:2e3,output:1e3}),bd=Object.freeze({input:1e4,output:4096});function xd(e){let t=vd(e,yd.input,yd.output),n=vd(e,bd.input,bd.output);return t===null?null:Math.max(ad(t,`media`),Math.ceil(n/nd-1e-9))}function Sd(e,{inputBytes:t=0,maxTokens:n=0}={}){let r=xd(e);if(r===null)return null;if(t<=4e4&&n<=bd.output)return r;let i=vd(e,Math.ceil(t/4),Math.min(n,Math.max(yd.output,Math.ceil(n/3)))),a=vd(e,t+64,n);return Math.max(r,ad(i,`media`),Math.ceil(a/nd-1e-9))}let Cd=e=>vd(e,yd.input,yd.output),wd=e=>vd(e,bd.input,bd.output),$=(e,t,n,r,i={})=>Object.freeze({usd:e,tier:t,unit:n,source:r,checked:i.checked||ld,...i}),Td=Object.freeze({\"media:analyze\":$(.02,`media`,`call`,`the vision provider caps a call at $0.02 (VISION_MAX_INITIAL_COST)`,{checked:cd}),\"media:check\":$(.005,`media`,`call`,`four photos at most, $0.00125 each (MEDIA_CHECK_IMAGE_USD)`,{checked:cd}),\"research:search\":$(.008,`media`,`search`,`Tavily basic search`,{checked:cd}),\"research:summarize\":$(.01,`media`,`call`,`one Gemini Flash read of fetched pages`,{estimate:!0}),\"transcribe:timestamp\":$(.01,`media`,`run`,`fal Whisper word timing`,{estimate:!0}),\"transcribe:upload\":$(.01,`media`,`run`,`fal Whisper word timing`,{estimate:!0}),\"transcribe:captions\":$(.01,`media`,`run`,`fal Whisper word timing`,{estimate:!0}),\"connection:action\":$(.012,`other`,`action`,`a premium Composio tool call at the overage rate`,{checked:cd}),\"automation:app-event\":$(.003,`other`,`event`,`Composio, per trigger event`,{checked:cd}),\"automation:app-check\":$(3e-4,`other`,`check`,`Composio, per tool call`,{checked:cd}),llm:$(.01,`other`,`call`,`a Standard model call`,{estimate:!0}),vision:$(.01,`other`,`image`,`one vision read`,{estimate:!0}),\"narrative:compile\":$(.06,`other`,`script`,`about ten Gemini Flash calls`,{estimate:!0}),\"narrative:compile-research\":$(.1,`other`,`script`,`the compile plus three Tavily searches and a dossier`,{estimate:!0}),\"narrative:learn-voice\":$(.01,`other`,`call`,`one extraction call`,{estimate:!0}),\"roughcut:base\":$(.05,`other`,`run`,`segmentation and matching`,{estimate:!0}),\"roughcut:per-min\":$(.015,`other`,`footage minute`,`Gemini Flash frame reads`,{estimate:!0}),\"finaledit:base\":$(.06,`other`,`run`,`polish decisions`,{estimate:!0}),\"finaledit:per-min\":$(.02,`other`,`video minute`,`Gemini Flash scan`,{estimate:!0}),\"aomotion:base\":$(.06,`other`,`run`,`motion graphics pass`,{estimate:!0}),\"aomotion:per-min\":$(.02,`other`,`video minute`,`motion graphics pass`,{estimate:!0}),\"aomotion:base:opus\":$(.12,`other`,`run`,`motion graphics pass on Opus`,{estimate:!0}),\"aomotion:per-min:opus\":$(.04,`other`,`video minute`,`motion graphics pass on Opus`,{estimate:!0}),motiongraphic:$(.015,`other`,`graphic`,`one small call`,{estimate:!0}),\"transcript:parse\":$(.005,`other`,`1,000 characters`,`Gemini Flash word timing`,{estimate:!0}),\"vibe-edit\":$(.02,`other`,`turn`,`Flash region scan and decision`,{estimate:!0}),\"canvas:context-connect\":$(.01,`other`,`run`,`one canvas read`,{estimate:!0}),\"anim2:plan\":$(.03,`other`,`video`,`shot planning`,{estimate:!0}),\"anim2:vibe\":$(.03,`other`,`turn`,`scene vibe turn`,{estimate:!0}),\"anim2:qa\":$(.03,`other`,`frame`,`vision QA`,{estimate:!0}),\"anim2:trigger\":$(.01,`other`,`scene`,`one Haiku call`,{estimate:!0}),\"gif:plan\":$(.03,`other`,`pass`,`GIF planning`,{estimate:!0}),\"canvas:plan\":$(.03,`other`,`pass`,`collage planning`,{estimate:!0}),\"canvasChat:build\":$(.03,`other`,`build`,`canvas chat orchestration`,{estimate:!0}),\"strip:plan\":$(.05,`other`,`pass`,`strip planning`,{estimate:!0}),\"panel:qa\":$(.03,`other`,`pass`,`style-consistency vision pass`,{estimate:!0})}),Ed=Object.freeze({standard:.4,balanced:.85,reasoning:.5,premium:1.4}),Dd=.06,Od=.008,kd=Object.freeze({build:.1,chat:.005,other:.05}),Ad=.25,jd=(e,t,n)=>e&&Object.hasOwn(e,t)?t:n,Md=e=>{let t=String(e||``).toLowerCase();return ud[t]?t:dd[t]||(t.includes(`kling`)?`kling-v3-turbo`:t.includes(`seedance`)?`seedance-2.0`:`wan-2.6-flash`)};function Nd({model:e=`gpt-image-2`,quality:t,resolution:n,references:r}={}){let i=fd[e]||fd[`gpt-image-2`],a=String(n||``).toUpperCase(),o=r===void 0||Number(r)>0;if(i.quality){let e=i.quality[jd(i.quality,String(t||``).toLowerCase(),`low`)];return e[jd(e,a,`1K`)]+(o&&i.referenceUsd||0)}return i.usd*(i.resolution?.[jd(i.resolution,a,`1K`)]??1)}function Pd({model:e,seconds:t=6,resolution:n}={}){let r=ud[Md(e)],i=r.resolution||{},a=jd(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 Fd({chars:e,seconds:t,provider:n=`deepgram`}={}){return(pd[n]||pd.elevenlabs).usdPer1kChars*(Number(e)>0?Number(e):Math.max(1,Number(t)||30)*12.5)/1e3}let Id=e=>md.usdPerSecond*e,Ld=e=>hd.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,xd(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:Rd,exactCredits:zd,FLAT:Bd}=td,Vd=e=>Rd(Bd[e].usd,Bd[e].tier),Hd=e=>Rd(e,`other`),Ud=Object.freeze({LLM_CHAT_MESSAGE:Hd(.01),LLM_BIBLE_GENERATION:Hd(.05),LLM_CANVAS_GENERATION:Hd(.03),LLM_VOICEOVER_SHOT_ANALYSIS:Hd(.01),LLM_MOOD_MAP_GENERATION:Hd(.01),LLM_MUSIC_PROMPT_GENERATION:Hd(.01),LLM_AUTO_EDIT_ANALYSIS:Hd(.01),LLM_GENERIC:Hd(.01),\"project:assistant\":Math.ceil(zd(Dd,`chat`)-1e-9),\"chat:web-search\":zd(Od,`chat`),\"narrative:compile\":Vd(`narrative:compile`),\"narrative:compile-research\":Vd(`narrative:compile-research`),\"narrative:learn-voice\":Vd(`narrative:learn-voice`),VISION_EXTERNAL_VIDEO_ANALYSIS:Hd(.02),VISION_AUTO_ANALYZE_PER_IMAGE:Vd(`vision`),...Object.fromEntries(Object.keys(fd).map(e=>[`IMAGE_${e}`,Rd(Nd({model:e}),`media`)])),...Object.fromEntries(Object.keys(ud).map(e=>[`VIDEO_${e}`,zd(Pd({model:e,seconds:1}),`video`)])),VOICEOVER_PER_MINUTE:Rd(Fd({seconds:60}),`media`),\"transcribe:timestamp\":Vd(`transcribe:timestamp`),\"transcribe:upload\":Vd(`transcribe:upload`),\"transcribe:captions\":Vd(`transcribe:captions`),MUSIC_PER_MINUTE:Rd(Id(60),`media`),SFX_PER_GENERATION:Rd(Ld(4),`media`),ROUGHCUT_BASE:Vd(`roughcut:base`),ROUGHCUT_PER_MINUTE:Vd(`roughcut:per-min`),FINALEDIT_BASE:Vd(`finaledit:base`),FINALEDIT_PER_MINUTE:Vd(`finaledit:per-min`),AOMOTION_BASE:Vd(`aomotion:base`),AOMOTION_PER_MINUTE:Vd(`aomotion:per-min`),AOMOTION_BASE_OPUS:Vd(`aomotion:base:opus`),AOMOTION_PER_MINUTE_OPUS:Vd(`aomotion:per-min:opus`),MOTIONGRAPHIC:Vd(`motiongraphic`),\"transcript:parse\":Vd(`transcript:parse`),VIBE_EDIT:Vd(`vibe-edit`),RESEARCH_SEARCH:Vd(`research:search`),RESEARCH_SUMMARIZE:Vd(`research:summarize`),MEDIA_ANALYZE:Vd(`media:analyze`),MEDIA_CHECK:Vd(`media:check`),CONNECTION_ACTION:Vd(`connection:action`),\"automation:app-events\":1,\"automation:app-checks\":1,CONTEXT_CONNECT:Vd(`canvas:context-connect`),\"anim2:plan\":Vd(`anim2:plan`),\"anim2:vibe\":Vd(`anim2:vibe`),\"anim2:qa\":Vd(`anim2:qa`),\"anim2:trigger\":Vd(`anim2:trigger`),\"gif:plan\":Vd(`gif:plan`),\"canvas:plan\":Vd(`canvas:plan`),\"canvasChat:build\":Vd(`canvasChat:build`),\"strip:plan\":Vd(`strip:plan`),\"panel:qa\":Vd(`panel:qa`),IMAGE_MOTION_EFFECT:0});Ud.RESEARCH_SEARCH+Ud.RESEARCH_SUMMARIZE,Ud.RESEARCH_SUMMARIZE,Ud.CONTEXT_CONNECT,Ud[`project:assistant`],Ud[`chat:web-search`],Object.freeze(Object.fromEntries(Object.entries(Ed).map(([e,t])=>[e,Rd(t,`build`)])));function Wd(e,t=1,n={}){return Rd(Nd({model:e||`gpt-image-2.5-sunburst`,quality:n.quality,resolution:n.resolution,references:n.references})*Math.max(1,t||1),`media`)}function Gd(e,t=6,n=1,r={}){return Rd(Pd({model:e,seconds:t||6,resolution:r.resolution}),`video`)*Math.max(1,n||1)}zd(5e-4,`other`),Object.freeze({providerUsd:`0.000300`,readCredits:1,writeCredits:2}),Math.floor(nd/(Bd[`automation:app-event`].usd*rd.other)),Math.floor(nd/(Bd[`automation:app-check`].usd*rd.other));function Kd({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,q.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 qd=e=>async()=>{throw Error(`${e} is not available in this Block.`)};function Jd({HelpHint:e=()=>null,CanvasCommitInput:t=Kd,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:qd(`Final Edit`),runStructureEdit:qd(`Structure edits`),runMotionGraphics:qd(`Motion graphics`),transcribeAudio:qd(`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:qd(`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:qd(`Style from uploads`),generateReferenceSheet:async e=>s(e),useReferenceExtraction:()=>(0,v.useMemo)(()=>({status:`idle`,extract:qd(`Reference extraction`)}),[]),findExtractedViews:()=>[],addLibraryItem:(e,t)=>t,getLibraryItems:()=>[],useThumb:e=>e,cachedObjectUrlIfPresent:()=>null,runLlmText:qd(`Free text generation`),presenterHost:Object.freeze({available:!1})}}let Yd=Object.freeze({\"stillmade-internal.board-chat-build@1.0.0\":function(e){let t=5e3,n=new Set(`a.an.the.and.or.but.if.so.of.to.in.on.at.for.with.from.by.is.are.was.were.be.been.it.its.this.that.these.those.as.you.your.we.our.i.my.they.them.their.he.she.his.her.not.no.do.does.did.can.will.just.about.into.over`.split(`.`));function r(e){return String(e||``).toLowerCase().replace(/[^a-z0-9$%\\s]/g,` `).split(/\\s+/).filter(e=>e&&e.length>1&&!n.has(e))}function i(e,t){if(!e.length||!t.length)return 0;let n=new Set(t),r=0;for(let t of new Set(e))n.has(t)&&(r+=Math.min(3,1+Math.floor(t.length/4)));return r/e.length}let a=e=>Number(e?.startMs??e?.start??0)||0;function o(e,t,n){let r=Array.isArray(e)?e:[],i=Number.isFinite(t)?t:-1/0,o=Number.isFinite(n)?n:1/0;return r.map((e,t)=>({w:e,i:t,ms:a(e)})).filter(({ms:e})=>e>=i&&e<=o)}function s({assets:e=[],words:t=[],fromMs:n=0,toMs:a=null,leadMs:s=75}={}){let c=o(t,n,a),l=c.length?c[0].ms:Number(n)||0,u=c.length?c[c.length-1].ms:Number(a)||l,d=Array.isArray(e)?e:[];if(!d.length)return{placements:[],rangeStart:l,rangeEnd:u};let f=c.map((e,t)=>{let n=c.slice(t,t+8);return{entries:n,tokens:r(n.map(({w:e})=>e?.word??e?.text??``).join(` `))}}),p=d.map((e,t)=>{let n=r(e?.descriptor||e?.text||``),a=new Set(n),o=null;for(let e of f){let t=i(n,e.tokens);if(t>0&&(!o||t>o.score)){let n=e.entries.find(e=>r(e.w?.word??e.w?.text??``).some(e=>a.has(e)))||e.entries[0];o={score:t,ms:n.ms,wordIndex:n.i}}}return{asset:e,idx:t,best:o}}),m=[],h=e=>m.every(t=>Math.abs(t-e)>=450),g=[];for(let e of p.filter(e=>e.best).sort((e,t)=>t.best.score-e.best.score))h(e.best.ms)&&(m.push(e.best.ms),g.push({asset:e.asset,idx:e.idx,atMs:e.best.ms,wordIndex:e.best.wordIndex,matched:!0,score:e.best.score}));let _=p.filter(e=>!g.some(t=>t.idx===e.idx));if(_.length){let e=Math.max(0,u-l),t=_.length>1?e/_.length:0;_.forEach((e,n)=>{let r=Math.round(l+t*n+(t?t/2:0)),i=0;for(;!h(r)&&i++<40;)r+=450;m.push(r),g.push({asset:e.asset,idx:e.idx,atMs:r,wordIndex:null,matched:!1,score:0})})}return g.sort((e,t)=>e.atMs-t.atMs),{placements:g.map(e=>({...e,appearMs:Math.max(l,e.atMs-s)})),rangeStart:l,rangeEnd:u}}function c(e,n,r=t){let i=Number(e)||0,a=Math.max(i,Number(n)||i),o=a-i;if(o<=0)return[{startMs:i,endMs:i,durationMs:0}];let s=Math.max(1,Math.round(o/r)),c=o/s,l=[];for(let e=0;e<s;e++){let t=Math.round(i+c*e),n=e===s-1?a:Math.round(i+c*(e+1));l.push({startMs:t,endMs:n,durationMs:n-t})}return l}function l({sourceDurationMs:e=0,beatMs:t=0,sourceInMs:n=0}={}){let r=Math.max(0,Number(t)||0),i=Math.max(0,Number(e)||0);if(!i||!r)return{sourceInMs:0,sourceOutMs:r,loop:!1,muted:!0};let a=Math.max(0,Math.min(Number(n)||0,Math.max(0,i-1)));return i-a>=r?{sourceInMs:a,sourceOutMs:a+r,loop:!1,muted:!0}:{sourceInMs:a,sourceOutMs:i,loop:!0,muted:!0}}function u({assets:e=[],words:n=[],fromMs:r=0,toMs:i=null,texts:a=[],targetMs:o=t,sceneId:u=null,idPrefix:d=`cvb`,leadMs:f=75}={}){let{placements:p,rangeStart:m,rangeEnd:h}=s({assets:e,words:n,fromMs:r,toMs:i,leadMs:f}),g=c(m,i??h,o),_=(Array.isArray(a)?a:[]).map(e=>({text:String(e?.text||``).slice(0,80),atMs:Number(e?.atMs)||0,emphasis:e?.emphasis===`primary`?`primary`:`secondary`,perWord:!!e?.perWord})).filter(e=>e.text).map(e=>({...e,appearMs:Math.max(m,e.atMs-f)})),v=(e,t,n)=>e>=t.startMs&&(n?e<=t.endMs:e<t.endMs);return g.map((e,t)=>{let n=t===g.length-1,r=0,i=[];for(let a of p.filter(t=>v(t.appearMs,e,n))){let n=a.asset||{},o=n.type===`video`||n.kind===`video`,s=Math.max(0,a.appearMs-e.startMs),c={id:`${d}${t+1}e${++r}`,appearMs:s,leaveMs:null,pos:null,pinned:!1,entrance:`pop`,sfx:`auto`,size:a.matched&&a.score>=.5?.46:.3,descriptor:n.descriptor||``,assetId:n.id||null};if(o){let t=Math.max(600,e.endMs-(e.startMs+s)),r=l({sourceDurationMs:n.durationMs,beatMs:t,sourceInMs:n.sourceInMs});i.push({...c,kind:`video`,src:n.url||null,...r})}else i.push({...c,kind:`image`,src:n.url||null,source:n.source||`user`})}for(let a of _.filter(t=>v(t.appearMs,e,n)))i.push({id:`${d}${t+1}t${++r}`,kind:`text`,text:a.text,appearMs:Math.max(0,a.appearMs-e.startMs),leaveMs:null,pos:null,size:a.emphasis===`primary`?.085:.06,font:`Hanken Grotesk`,color:`#111111`,weight:800,anim:{type:`pop`,perWord:!!a.perWord,speedMs:180},sfx:`auto`,pinned:!1});return i.sort((e,t)=>e.appearMs-t.appearMs),{panelId:`${d}${t+1}`,type:`canvas`,sceneId:u,background:`#ffffff`,autoArrange:!0,planned:!0,builtBy:`canvas-chat`,startMs:e.startMs,durationMs:e.durationMs,transitionIn:t===0?`cut`:`swirl`,elements:i}})}return{panels:u(e.assembly)}},\"stillmade-internal.board-chat-edits@1.0.0\":function(e){function t({sourceDurationMs:e=0,beatMs:t=0,sourceInMs:n=0}={}){let r=Math.max(0,Number(t)||0),i=Math.max(0,Number(e)||0);if(!i||!r)return{sourceInMs:0,sourceOutMs:r,loop:!1,muted:!0};let a=Math.max(0,Math.min(Number(n)||0,Math.max(0,i-1)));return i-a>=r?{sourceInMs:a,sourceOutMs:a+r,loop:!1,muted:!0}:{sourceInMs:a,sourceOutMs:i,loop:!0,muted:!0}}let n=[`resize`,`move`,`swap`,`addText`,`retrim`,`spread`,`transition`,`remove`],r=.06,i=e=>Math.max(r,Math.min(.9,Number(e)||r));function a(e,t){let n=!1,r=e.elements.map(e=>{let r=t(e);return r&&r!==e?(n=!0,r):e});return n?{...e,elements:r}:e}function o(e,r){let o=Array.isArray(e)?e:[];if(!r||!n.includes(r.kind))return{panels:o,changed:!1,reason:`unknown edit: ${r?.kind??`none`}`};let s=e=>!r.panelId||e.panelId===r.panelId,c=e=>!r.elementId||e.id===r.elementId,l=!1,u=e=>(l=!0,e),d=o.map(e=>{if(!s(e))return e;switch(r.kind){case`resize`:{let t=Number(r.factor)||(r.direction===`smaller`?.7:1.4);return a(e,e=>{if(!c(e))return e;let n=i(r.size==null?(e.size??.3)*t:r.size);return n===e.size?e:u({...e,size:n})})}case`move`:return a(e,e=>{if(!c(e))return e;let t={x:Number(r.x)||0,y:Number(r.y)||0};return u({...e,pos:t,pinned:!0})});case`swap`:return a(e,e=>!c(e)||!r.url?e:u({...e,src:r.url,...r.descriptor?{descriptor:r.descriptor}:{},...r.assetId?{assetId:r.assetId}:{}}));case`retrim`:return a(e,n=>{if(!c(n)||n.kind!==`video`)return n;let i=Math.max(200,Number(r.beatMs)||e.durationMs-(n.appearMs||0)),a=t({sourceDurationMs:Number(r.sourceDurationMs)||(n.sourceOutMs??0),beatMs:i,sourceInMs:r.sourceInMs==null?n.sourceInMs:r.sourceInMs});return u({...n,...a})});case`addText`:{let t=String(r.text||``).slice(0,80);if(!t)return e;let n={id:r.elementId||`${e.panelId}t${e.elements.length+1}`,kind:`text`,text:t,appearMs:Math.max(0,Math.min(Number(r.appearMs)||0,e.durationMs)),leaveMs:null,pos:r.x!=null&&r.y!=null?{x:Number(r.x),y:Number(r.y)}:null,pinned:r.x!=null&&r.y!=null,size:r.emphasis===`primary`?.085:.06,font:`Hanken Grotesk`,color:`#111111`,weight:800,anim:{type:`pop`,perWord:!1,speedMs:180},sfx:`auto`};return u({...e,elements:[...e.elements,n].sort((e,t)=>e.appearMs-t.appearMs)})}case`remove`:{let t=e.elements.filter(e=>!c(e));return t.length===e.elements.length?e:u({...e,elements:t})}case`spread`:{let t=e.elements.length;if(t<2)return e;let n=Math.max(0,e.durationMs-200),r=Math.max(450,n/t),i=[...e.elements].sort((e,t)=>e.appearMs-t.appearMs),a=i.map((e,t)=>{let i=Math.round(Math.min(n,t*r));return i===e.appearMs?e:{...e,appearMs:i}});return a.some((e,t)=>e!==i[t])?u({...e,elements:a}):e}case`transition`:{let t=String(r.transition||``).trim();return!t||t===e.transitionIn?e:u({...e,transitionIn:t})}default:return e}});return{panels:l?d:o,changed:l,reason:l?``:`nothing matched that edit`}}function s(e,t){let n=Array.isArray(e)?e:[],r=[],i=[];for(let e of Array.isArray(t)?t:[]){let t=o(n,e);n=t.panels,(t.changed?r:i).push(e)}return{panels:n,applied:r,skipped:i}}return{result:s(e.panels,e.edits)}},\"stillmade-internal.board-descriptors@1.0.0\":function(e){let t=[`generated`,`manual`,`context`,`vision`],n=e=>String(e??``).replace(/\\s+/g,` `).trim();function r(e){return n(e).length>=3}function i(e,t=180){let r=n(e);if(!r)return``;let i=r.split(/[.;\\n]/)[0]||r,a=i.length>=12?i:r;return a.length<=t?a:`${a.slice(0,t-1).trimEnd()}…`}function a(e={},{manual:t=``,context:a=``}={}){let o=n(t)||n(e.descriptor);if(r(o))return{text:o,source:`manual`,needsVision:!1};let s=i(e.prompt);if(r(s))return{text:s,source:`generated`,needsVision:!1};let c=n(a);if(r(c))return{text:c,source:`context`,needsVision:!1};let l=n(Array.isArray(e.tags)?e.tags.join(`, `):``)||n(e.title||e.name);return e.isStock&&r(l)?{text:l,source:`context`,needsVision:!1}:{text:``,source:`vision`,needsVision:!0}}function o(e=[],{manuals:n={},contexts:r={}}={}){let i=(Array.isArray(e)?e:[]).map(e=>{let t=e?.id??e?.url;return{asset:e,key:t,...a(e,{manual:n[t],context:r[t]})}}),o=i.filter(e=>e.needsVision);return{resolved:i,needingVision:o,visionCount:o.length,freeCount:i.length-o.length,bySource:t.reduce((e,t)=>(e[t]=i.filter(e=>e.source===t).length,e),{})}}return{result:o(e.assets,{manuals:e.manuals,contexts:e.contexts})}},\"stillmade-internal.board-duration@1.0.0\":function(e){let t=e=>e;function n(e,n){let r=Math.max(1e3,Math.round(Number(n)||0)),i=e.strip.filter(e=>e.type===`canvas`);if(!i.length)return e;let a=i[i.length-1],o=Math.max(500,r-a.startMs);if(o===a.durationMs)return e;let s=e.strip.map(e=>{if(e.panelId!==a.panelId)return e;let t=e.elements;return o<e.durationMs&&(t=(e.elements||[]).filter(e=>(e.appearMs||0)<o).map(e=>e.leaveMs!=null&&e.leaveMs>o?{...e,leaveMs:null}:e)),{...e,durationMs:o,elements:t}});return t({...e,strip:s})}return{edit:n(e.doc,e.durationMs)}},\"stillmade-internal.presenter-gaps@1.0.0\":function(e){function t(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 n(e,{words:n=[],minGapMs:r=2e3,targetMs:i=5e3}={}){let a=n[n.length-1],o=a?Math.round(Number(a.endMs??a.startMs??0)):0;if(!o)return e;let s=(e?.strip||[]).filter(e=>e.type===`canvas`);if(!s.length)return e;let c=s.map(e=>[Number(e.startMs)||0,(Number(e.startMs)||0)+(Number(e.durationMs)||0)]).sort((e,t)=>e[0]-t[0]),l=[];for(let[e,t]of c){let n=l[l.length-1];n&&e<=n[1]?n[1]=Math.max(n[1],t):l.push([e,t])}let u=[],d=0;for(let[e,t]of l)e-d>=r&&u.push([d,e]),d=Math.max(d,t);if(o-d>=r&&u.push([d,o]),!u.length)return e;let f=s[0].sceneId||e?.scenes?.[0]?.sceneId||`s1`,p=(e.strip||[]).length,m=[];for(let[e,n]of u)for(let r of t(e,n,i))r.durationMs&&m.push({panelId:`hostg${p}_${m.length+1}`,type:`canvas`,sceneId:f,background:`#ffffff`,autoArrange:!0,planned:!0,builtBy:`host-gap`,startMs:r.startMs,durationMs:r.durationMs,transitionIn:`cut`,elements:[]});return m.length?{...e,strip:[...e.strip,...m]}:e}return{doc:n(e.doc,{words:e.words})}},\"stillmade-internal.presenter-insertion@1.0.0\":function(e){function t(e){return String(e||``).toLowerCase().replace(/[^a-z0-9]+/g,`-`).replace(/^-+|-+$/g,``).slice(0,40)}function n(e){let{addCanvasElement:n,removeCanvasElement:r}=e;function i(e){let t=String(e||``);return/(^|-)right/.test(t)?{x:.2,y:.64}:(/(^|-)left/.test(t),{x:.8,y:.64})}function a(e,{size:n=.3,pos:r=null}={}){let a=t(e?.label);return{kind:`image`,src:e?.url||null,source:`pose`,pose:a,cutout:!0,entrance:`pop`,pinned:!0,appearMs:0,leaveMs:null,pos:r||i(a),size:n,query:a}}let o={size:.52,pos:{x:.5,y:.62}};function s({poses:e=[],plan:n={},boards:r=[],size:i=.3}={}){let s=Array.isArray(e)?e.filter(e=>e&&e.url):[];if(!s.length)return[];let c=new Map(s.map(e=>[t(e.label),e])),l=Array.isArray(n?.poses)?n.poses:[],u=[],d=0;return(Array.isArray(r)?r:[]).forEach(e=>{if(!e?.panelId)return;let n=null;for(let r of l){if(r?.atWord==null||e.wordStart==null)continue;let i=e.wordEnd==null?1/0:e.wordEnd;if(r.atWord>=e.wordStart&&r.atWord<=i&&c.has(t(r.label))){n=c.get(t(r.label));break}}n||(n=s[d%s.length],d++),u.push({panelId:e.panelId,element:a(n,e.solo?o:{size:i})})}),u}function c(e,t=[]){let r=e;for(let{panelId:e,element:i}of t||[])e&&i&&(r=n(r,e,i));return r}function l(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 u(e,t=[],n=[]){let r=d(e),i=(r.strip||[]).filter(e=>e.type===`canvas`).map(e=>({panelId:e.panelId,wordStart:e.wordStart==null?l(n,e.startMs||0):e.wordStart,wordEnd:e.wordEnd==null?l(n,(e.startMs||0)+(e.durationMs||0)):e.wordEnd,solo:!(e.elements||[]).length}));return c(r,s({poses:t,plan:{poses:t.map(e=>({label:e.label,atWord:e.atWord})).filter(e=>e.atWord!=null)},boards:i}))}function d(e){if(!e?.strip)return e;let t=e;for(let n of e.strip)if(n?.type===`canvas`&&Array.isArray(n.elements))for(let e of n.elements)e?.source===`pose`&&(t=r(t,n.panelId,e.id));return t}return{poseSpot:i,poseElement:a,SOLO_POSE:o,planPresenterPlacement:s,applyPresenterPlacement:c,placePosesOnDoc:u,clearPresenterPoses:d}}let r=n({});return{element:{...r.poseElement(e.pose,{pos:r.poseSpot(e.pose.label)}),appearMs:Math.round(e.atMs)}}},\"stillmade-internal.presenter-placement@1.0.0\":function(e){function t(e){return String(e||``).toLowerCase().replace(/[^a-z0-9]+/g,`-`).replace(/^-+|-+$/g,``).slice(0,40)}function n(e){let{addCanvasElement:n,removeCanvasElement:r}=e;function i(e){let t=String(e||``);return/(^|-)right/.test(t)?{x:.2,y:.64}:(/(^|-)left/.test(t),{x:.8,y:.64})}function a(e,{size:n=.3,pos:r=null}={}){let a=t(e?.label);return{kind:`image`,src:e?.url||null,source:`pose`,pose:a,cutout:!0,entrance:`pop`,pinned:!0,appearMs:0,leaveMs:null,pos:r||i(a),size:n,query:a}}let o={size:.52,pos:{x:.5,y:.62}};function s({poses:e=[],plan:n={},boards:r=[],size:i=.3}={}){let s=Array.isArray(e)?e.filter(e=>e&&e.url):[];if(!s.length)return[];let c=new Map(s.map(e=>[t(e.label),e])),l=Array.isArray(n?.poses)?n.poses:[],u=[],d=0;return(Array.isArray(r)?r:[]).forEach(e=>{if(!e?.panelId)return;let n=null;for(let r of l){if(r?.atWord==null||e.wordStart==null)continue;let i=e.wordEnd==null?1/0:e.wordEnd;if(r.atWord>=e.wordStart&&r.atWord<=i&&c.has(t(r.label))){n=c.get(t(r.label));break}}n||(n=s[d%s.length],d++),u.push({panelId:e.panelId,element:a(n,e.solo?o:{size:i})})}),u}function c(e,t=[]){let r=e;for(let{panelId:e,element:i}of t||[])e&&i&&(r=n(r,e,i));return r}function l(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 u(e,t=[],n=[]){let r=d(e),i=(r.strip||[]).filter(e=>e.type===`canvas`).map(e=>({panelId:e.panelId,wordStart:e.wordStart==null?l(n,e.startMs||0):e.wordStart,wordEnd:e.wordEnd==null?l(n,(e.startMs||0)+(e.durationMs||0)):e.wordEnd,solo:!(e.elements||[]).length}));return c(r,s({poses:t,plan:{poses:t.map(e=>({label:e.label,atWord:e.atWord})).filter(e=>e.atWord!=null)},boards:i}))}function d(e){if(!e?.strip)return e;let t=e;for(let n of e.strip)if(n?.type===`canvas`&&Array.isArray(n.elements))for(let e of n.elements)e?.source===`pose`&&(t=r(t,n.panelId,e.id));return t}return{poseSpot:i,poseElement:a,SOLO_POSE:o,planPresenterPlacement:s,applyPresenterPlacement:c,placePosesOnDoc:u,clearPresenterPoses:d}}let r=[],i=n({removeCanvasElement:(e,t,n)=>(r.push({kind:`remove`,panelId:t,elementId:n}),{...e,strip:e.strip.map(e=>e.panelId===t?{...e,elements:e.elements.filter(e=>e.id!==n)}:e)}),addCanvasElement:(e,t,n)=>(r.push({kind:`add`,panelId:t,element:n}),e)});return e.mode===`clear`?i.clearPresenterPoses(e.doc):i.placePosesOnDoc(e.doc,e.poses,e.words),{commands:r}},\"stillmade-internal.board-sequence@1.0.0\":function(e){function t(e){let t=0;return(e||[]).map(e=>{if(e.type!==`canvas`)return e;let n={...e,startMs:t};return t+=Number(e.durationMs)||0,n})}function n(e,n,r){let i=e?.strip||[],a=i.map((e,t)=>e.type===`canvas`?t:-1).filter(e=>e>=0),o=i.findIndex(e=>e.panelId===n),s=a.indexOf(o),c=s+r;if(s<0||c<0||c>=a.length)return e;let l=i.slice(),u=a[c];return[l[o],l[u]]=[l[u],l[o]],{...e,strip:t(l)}}function r(e,n){return{...e,strip:t((e?.strip||[]).filter(e=>e.panelId!==n))}}return{edit:e.request.action===`move`?n(e.doc,e.request.panelId,e.request.direction):r(e.doc,e.request.panelId)}},\"stillmade-internal.board-settings@1.0.0\":function(e){function t(e,t){return t.kind===`aspect`?{...e,meta:{...e.meta,aspect:t.value}}:{...e,strip:e.strip.map(e=>e.panelId===t.panelId?{...e,[t.kind]:t.value}:e)}}return{edit:t(e.doc,e.request)}},\"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.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)}}}),Xd=globalThis.StillMade,Zd=Au(Xd),{ui:Qd,DialogHost:$d}=Nu(),ef=zu(Xd);Vu(ef);let tf={input:{},shared:{canEdit:!1,outputs:{},state:{},made:[]},inputSeen:!1},nf=new Set,rf=()=>{for(let e of nf)e()};Xd.onInput(e=>{tf.input=e,tf.inputSeen=!0,rf()}),Xd.onShared(e=>{tf.shared=e,ef.remember(e?.made),rf()});function af(){let[,e]=(0,v.useState)(0);return(0,v.useEffect)(()=>{let t=()=>e(e=>e+1);return nf.add(t),()=>nf.delete(t)},[]),tf}let of={doc:null},sf=e=>e?{...e,schemaVersion:e.schemaVersion??1}:void 0,cf=async(e,t={})=>{let n=await Xd.run({make:e,...of.doc?{board:sf(of.doc)}:{},...t});return ef.remember(n),n},lf=e=>e?.result,uf=new Set([`url`,`src`,`gifUrl`,`mp4`,`poster`,`image`,`thumb`,`audioUrl`,`videoUrl`,`previewUrl`,`voPath`,`uploadedUrl`,`href`,`lut`]),df=/^\\/(sounds|sfx)\\//,ff=e=>{try{let t=new URL(e,`https://stillmade.local`);return t.origin===`https://stillmade.local`&&!t.search&&df.test(t.pathname)&&!/[^\\w./-]/.test(t.pathname)}catch{return!1}};function pf(e,t=new Set,n=0){if(n>16||!e||typeof e!=`object`)return t;for(let[r,i]of Array.isArray(e)?e.entries():Object.entries(e))if(typeof i==`string`){let e=i.trim();(uf.has(r)&&e||/^([a-z][a-z0-9+.-]*:|\\/|\\\\|\\.)/i.test(e)||/^[\\w.%-]+[\\/\\\\][^\\s]*$/.test(e))&&!/^data:/i.test(e)&&!ff(e)&&t.add(i)}else pf(i,t,n+1);return t}let mf=e=>(Array.isArray(e)?e:[e]).filter(Boolean).map(e=>ef.refFor(e)).filter(Boolean),hf=e=>new Promise((t,n)=>{let r=new FileReader;r.onload=()=>t(r.result),r.onerror=n,r.readAsDataURL(e)}),gf=async e=>{let t=lf(await cf(`upload`,{dataUrl:e}));if(!t?.url)throw Error(`The file could not be saved.`);return t.url},_f=async e=>typeof e==`string`&&e.startsWith(`data:`)?ef.refFor(await gf(e)):ef.refFor(e),vf={list:[],notify:null},yf=e=>t=>{let n=Math.random();vf.list=[...vf.list.slice(-2),{id:n,kind:e,text:String(t?.message||t||``)}],vf.notify?.(),setTimeout(()=>{vf.list=vf.list.filter(e=>e.id!==n),vf.notify?.()},e===`error`?6e3:3500)},bf=Object.freeze({success:yf(`success`),error:yf(`error`),info:yf(`info`),warn:yf(`error`)});function xf(){let[,e]=(0,v.useState)(0);return(0,v.useEffect)(()=>(vf.notify=()=>e(e=>e+1),()=>{vf.notify=null}),[]),vf.list.length?(0,q.jsx)(`div`,{role:`status`,\"aria-live\":`polite`,style:{position:`fixed`,left:`50%`,bottom:16,transform:`translateX(-50%)`,display:`grid`,gap:6,zIndex:1100,maxWidth:`min(480px, calc(100vw - 32px))`},children:vf.list.map(e=>(0,q.jsx)(`div`,{style:{background:`var(--bg-elev-1)`,color:e.kind===`error`?`var(--danger, #c0392b)`:`var(--fg)`,border:`1px solid var(--border-tok)`,borderRadius:`var(--r-3)`,padding:`8px 12px`,fontSize:13},children:e.text},e.id))}):null}let Sf=Object.freeze({version:1,actor:()=>`frame`,async run(e,t){let n=Yd[`${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:n(structuredClone(t.input))}}}),Cf=Qu.filter(e=>!e.disabled),wf=()=>Cf[0]?.value||`nano-banana-2`,Tf=e=>{let t=lf(e);if(!t?.url)throw Error(`No picture came back. Try again.`);return{url:t.url,...t}},Ef=async e=>Tf(await cf(`image`,{request:{...e,referenceImages:void 0},references:(await Promise.all((e.referenceImages||[]).map(e=>_f(typeof e==`string`?e:e?.url)))).filter(Boolean)})),Df=async e=>{let t=await cf(`video`,{request:{...e,firstFrameUrl:void 0,lastFrameUrl:void 0},...e.firstFrameUrl?{firstFrame:await _f(e.firstFrameUrl)}:{},...e.lastFrameUrl?{lastFrame:await _f(e.lastFrameUrl)}:{}}),n=lf(t);if(!n?.url)throw Error(`No clip came back. Try again.`);return{url:n.url,...n}},Of=async(e,t)=>gf(await hf(t&&e.type===``?new Blob([e],{type:`image/${t}`}):e)),kf=Object.freeze({version:1,actor:()=>`frame`,imageCost:Wd,videoCost:Gd,stockStatus:async()=>({configured:!0,...lf(await cf(`stock-status`))||{}}),stockGrid:async e=>lf(await cf(`stock-grid`,{request:e})),stockSelect:async()=>!0,upload:(e,t)=>Of(e,t),generateImage:Ef,generateVideo:Df}),Af=new Map,jf=null;jf||=cf(`storage-get`,{key:`presenter-library`}).then(lf).then(e=>{for(let[t,n]of Object.entries(e||{}))Af.set(t,Array.isArray(n)?n:[])}).catch(()=>{});let Mf=()=>cf(`storage-set`,{key:`presenter-library`,value:Object.fromEntries(Af)}).catch(()=>{}),Nf=e=>new Promise((t,n)=>{let r=new Image;r.onload=()=>t(r),r.onerror=()=>n(Error(`The picture could not be read here.`)),r.src=e}),Pf=({assertCurrent:e}={})=>({cropCell:async(t,n)=>{e?.();let r=await Nf(ef.refFor(t)?await ef.load(t):t);e?.();let i=r.naturalWidth||r.width,a=r.naturalHeight||r.height,o=document.createElement(`canvas`);return o.width=Math.max(2,Math.round(n.w*i)),o.height=Math.max(2,Math.round(n.h*a)),o.getContext(`2d`).drawImage(r,n.x*i,n.y*a,n.w*i,n.h*a,0,0,o.width,o.height),o},processPose:async t=>{e?.();let n=t.getContext(`2d`),r=n.getImageData(0,0,t.width,t.height),i=r.data;for(let e=0;e<i.length;e+=4){let t=Math.min(i[e],i[e+1],i[e+2]);t>=244?i[e+3]=0:t>=226&&(i[e+3]=Math.round(i[e+3]*(244-t)/18))}return n.putImageData(r,0,0),{rasterDataUrl:t.toDataURL(`image/png`),svg:``,w:t.width,h:t.height}},upload:async(t,n)=>(e?.(),n===`svg`||!t?null:gf(t))}),Ff=Xr(Sf),If=Object.freeze(Ln({version:2,placementBroker:Ff,currentActor:()=>`frame`,planPresenterPoses:async e=>lf(await cf(`plan-poses`,{request:e})),generateImage:Ef,getDefaultImageModel:wf,getDefaultImageQuality:()=>`high`,getDefaultImageResolution:()=>`1K`,browserSliceDeps:Pf,addLibraryItem:(e,t)=>{let n={...t,id:t?.id||`${e}-${crypto.randomUUID()}`};return Af.set(e,[n,...(Af.get(e)||[]).filter(e=>e.id!==n.id)].slice(0,40)),Mf(),n},getLibraryItems:e=>Af.get(e)||[],imageCost:Wd,getModelCapabilities:ed,QUALITY_OPTIONS:Yu,loadPanelDoc:Zt,addCanvasElement:Rt,removeCanvasElement:zt,ui:Qd,toast:bf})),Lf=ac(If),Rf=Object.freeze(_i({version:3,planCanvasChatBuild:async e=>lf(await cf(`chat-build`,{request:e})),parseCanvasChatEdit:async e=>lf(await cf(`chat-edit`,{request:e}))||[],describeImage:async(e,t=``)=>{let n=await _f(e);if(!n)throw Error(`Save this picture to the Step first.`);return{description:String(lf(await cf(`describe`,{image:n,request:{hint:t}}))||``),stub:!1}},captureClipFrame:async(e,t)=>{if(!e?.url||!ef.refFor(e.url))return null;let n=await ef.load(e.url);return new Promise(e=>{let r=document.createElement(`video`);r.muted=!0,r.preload=`auto`,r.addEventListener(`seeked`,()=>{let t=document.createElement(`canvas`);t.width=r.videoWidth||640,t.height=r.videoHeight||360,t.getContext(`2d`).drawImage(r,0,0,t.width,t.height),e(t.toDataURL(`image/jpeg`,.85))},{once:!0}),r.addEventListener(`error`,()=>e(null),{once:!0}),r.addEventListener(`loadedmetadata`,()=>{r.currentTime=Math.max(0,Number(t)||0)},{once:!0}),r.src=n})},uploadGifBlob:(e,t)=>Of(e,t),imageCost:Wd,stockGrid:async(e,t)=>({results:lf(await cf(`stock-grid`,{request:{query:e,type:t}}))||[]}),generateHostPoses:e=>Lf.generateHostPoses(e),getDefaultImageModel:wf,toast:bf,ui:Qd,CREDIT_COSTS:Ud,PRESENTER_HOST_BETA:!0,MIN_POSE_SHEETS:2})),zf=()=>(Array.isArray(tf.shared.made)?tf.shared.made:[]).filter(e=>(e?.kind===`image`||e?.kind===`video`)&&e.url).map(e=>({id:e.assetId,url:e.url,type:e.kind,prompt:e.prompt||``,descriptor:e.descriptor||``}));function Bf(e){return(0,q.jsx)(Oc,{...e,panelEditHost:e.panelEditHost||Sf,mediaHost:e.mediaHost||kf})}function Vf(e){return(0,q.jsx)(Qi,{...e,hostServices:Rf,editHost:Sf})}function Hf(e){return(0,q.jsx)(lr,{...e,hostServices:If})}let Uf=Object.freeze(Nn({version:1,useLiveEditor:Zd,LiveEditorBadge:()=>null,CanvasEditorCore:Bf,TRANSITIONS:js,setCanvasEditorDuration:Nt,addCanvasElement:Rt,toast:bf,ui:Qd,CanvasChatPanel:Vf,HostSection:Hf,ItemPreview:Du,getAllAssets:zf}));za({...Jd({ui:Qd,toast:bf,media:ef,run:cf,upload:gf,generateImage:Ef,useIsMobileUI:()=>globalThis.innerWidth<768}),presenterHost:If,getAllAssets:zf,addLibraryItem:If.addLibraryItem,getLibraryItems:If.getLibraryItems});function Wf(e){return{words:(Array.isArray(e.narrationTiming?.words)?e.narrationTiming.words:[]).filter(e=>e&&typeof e.text==`string`&&e.text).map(e=>({text:e.text,startMs:Math.round((Number(e.start)||0)*1e3),endMs:Math.round((Number(e.end)||0)*1e3)})),voPath:typeof e.narrationAudio?.url==`string`&&e.narrationAudio.url?e.narrationAudio.url:null}}let Gf=({words:e,voPath:t})=>e.length||t?{enabled:!0,words:e.map(e=>({text:e.text,start:e.startMs/1e3,end:e.endMs/1e3,startMs:e.startMs,endMs:e.endMs})),...t?{audioUrl:t}:{}}:null;function Kf(e){if(e.board&&Array.isArray(e.board.strip)&&e.board.strip.length){let{schemaVersion:t,...n}=e.board;return Zt(n)}let{words:t,voPath:n}=Wf(e),r=t.length?t.at(-1).endMs:0;return Mt({aspect:`16:9`,durationMs:r>1500?r+400:1e4,words:t,voPath:n})}function qf(){let{input:e,shared:t}=af(),[n,r]=(0,v.useState)(null),[i,a]=(0,v.useState)(`16:9`),[o,s]=(0,v.useState)(!1);(0,v.useEffect)(()=>{!o&&tf.inputSeen&&(r(Kf(tf.input)),s(!0))},[e,t,o]);let c=JSON.stringify(Wf(e)),l=(0,v.useMemo)(()=>JSON.parse(c),[c]);(0,v.useEffect)(()=>{o&&(l.words.length||l.voPath)&&r(e=>e&&Pt(e,l))},[l,o]);let u=(0,v.useMemo)(()=>Gf(l),[l]);return of.doc=n,!o||!n?null:(0,q.jsxs)(q.Fragment,{children:[(0,q.jsx)(kr,{hostServices:Uf,editHost:Sf,presenterHostServices:If,presenterPlacementBroker:Ff,projectId:`block`,doc:n,aspect:i,nextStepLabel:`Editor`,voiceover:u,onDocChange:e=>r(t=>typeof e==`function`?e(t):e),onAspectChange:a,onContinue:async()=>{try{await cf(`use`)}catch(e){await Qd.alert(e.message||`The boards could not be saved.`,{title:`Not saved`})}},onExport:async()=>{try{let e=[...pf(of.doc)],t=e.filter(e=>!ef.refFor(e));if(t.length){await Qd.alert(`${t.length===1?`One picture or clip`:`${t.length} pictures or clips`} on the boards ${t.length===1?`is`:`are`} not saved with this project yet. Add ${t.length===1?`it`:`them`} again, then export.`,{title:`Not exported`});return}if(bf.info(`Rendering the video…`),!lf(await cf(`export`,{files:mf(e)}))?.url)throw Error(`The export did not finish. Try again.`);bf.success(`Exported. Download it from the result under the boards.`)}catch(e){await Qd.alert(e.message||`The export did not finish.`,{title:`Not exported`})}}}),(0,q.jsx)($d,{}),(0,q.jsx)(xf,{})]})}(0,_.createRoot)(document.getElementById(`root`)).render((0,q.jsx)(qf,{}))})();",
|
|
177
|
+
"runtime": "frame"
|
|
178
|
+
},
|
|
179
|
+
"tests": [
|
|
180
|
+
{
|
|
181
|
+
"name": "Gives the board and its Editor cut to the next Step",
|
|
182
|
+
"input": {
|
|
183
|
+
"make": "use",
|
|
184
|
+
"board": {
|
|
185
|
+
"schemaVersion": 1,
|
|
186
|
+
"mode": "imagePanel",
|
|
187
|
+
"meta": {
|
|
188
|
+
"title": "Canvas",
|
|
189
|
+
"aspect": "16:9"
|
|
190
|
+
},
|
|
191
|
+
"audio": {
|
|
192
|
+
"voPath": "/api/media/example/kitchen.wav",
|
|
193
|
+
"words": [
|
|
194
|
+
{
|
|
195
|
+
"text": "Hello",
|
|
196
|
+
"startMs": 0,
|
|
197
|
+
"endMs": 400
|
|
198
|
+
}
|
|
199
|
+
]
|
|
200
|
+
},
|
|
201
|
+
"styleBlock": "canvas editor",
|
|
202
|
+
"sheets": {},
|
|
203
|
+
"lineages": {},
|
|
204
|
+
"scenes": [
|
|
205
|
+
{
|
|
206
|
+
"sceneId": "s1",
|
|
207
|
+
"title": "Canvas",
|
|
208
|
+
"genre": null
|
|
209
|
+
}
|
|
210
|
+
],
|
|
211
|
+
"strip": [
|
|
212
|
+
{
|
|
213
|
+
"panelId": "cv1",
|
|
214
|
+
"type": "canvas",
|
|
215
|
+
"sceneId": "s1",
|
|
216
|
+
"background": "#ffffff",
|
|
217
|
+
"autoArrange": true,
|
|
218
|
+
"planned": false,
|
|
219
|
+
"startMs": 0,
|
|
220
|
+
"durationMs": 2000,
|
|
221
|
+
"transitionIn": "cut",
|
|
222
|
+
"provenance": "user",
|
|
223
|
+
"elements": [
|
|
224
|
+
{
|
|
225
|
+
"id": "t1",
|
|
226
|
+
"kind": "text",
|
|
227
|
+
"text": "Hello there",
|
|
228
|
+
"appearMs": 0,
|
|
229
|
+
"leaveMs": null,
|
|
230
|
+
"pos": {
|
|
231
|
+
"x": 0.5,
|
|
232
|
+
"y": 0.22
|
|
233
|
+
},
|
|
234
|
+
"size": 0.07,
|
|
235
|
+
"font": "Hanken Grotesk",
|
|
236
|
+
"color": "#111111",
|
|
237
|
+
"weight": 800,
|
|
238
|
+
"anim": {
|
|
239
|
+
"type": "pop",
|
|
240
|
+
"perWord": false,
|
|
241
|
+
"speedMs": 180
|
|
242
|
+
},
|
|
243
|
+
"sfx": "none",
|
|
244
|
+
"pinned": true
|
|
245
|
+
},
|
|
246
|
+
{
|
|
247
|
+
"id": "i1",
|
|
248
|
+
"kind": "image",
|
|
249
|
+
"src": "/api/media/example/photo-1.jpg",
|
|
250
|
+
"source": "generated",
|
|
251
|
+
"appearMs": 400,
|
|
252
|
+
"leaveMs": null,
|
|
253
|
+
"pos": {
|
|
254
|
+
"x": 0.5,
|
|
255
|
+
"y": 0.6
|
|
256
|
+
},
|
|
257
|
+
"size": 0.34,
|
|
258
|
+
"tilt": 0,
|
|
259
|
+
"entrance": "pop",
|
|
260
|
+
"sfx": "auto",
|
|
261
|
+
"pinned": true
|
|
262
|
+
}
|
|
263
|
+
]
|
|
264
|
+
}
|
|
265
|
+
]
|
|
266
|
+
},
|
|
267
|
+
"references": [
|
|
268
|
+
{
|
|
269
|
+
"kind": "image",
|
|
270
|
+
"assetId": "picture-1",
|
|
271
|
+
"versionId": "picture-1-v1",
|
|
272
|
+
"url": "/api/media/example/photo-1.jpg",
|
|
273
|
+
"mimeType": "image/jpeg",
|
|
274
|
+
"width": 1600,
|
|
275
|
+
"height": 1200
|
|
276
|
+
}
|
|
277
|
+
],
|
|
278
|
+
"narrationAudio": {
|
|
279
|
+
"kind": "audio",
|
|
280
|
+
"assetId": "narration",
|
|
281
|
+
"versionId": "narration-v1",
|
|
282
|
+
"url": "/api/media/example/kitchen.wav",
|
|
283
|
+
"mimeType": "audio/wav",
|
|
284
|
+
"duration": 2
|
|
285
|
+
},
|
|
286
|
+
"narrationTiming": {
|
|
287
|
+
"schemaVersion": 1,
|
|
288
|
+
"text": "Hello there, this is the board.",
|
|
289
|
+
"words": [
|
|
290
|
+
{
|
|
291
|
+
"text": "Hello",
|
|
292
|
+
"start": 0,
|
|
293
|
+
"end": 0.4
|
|
294
|
+
},
|
|
295
|
+
{
|
|
296
|
+
"text": "there,",
|
|
297
|
+
"start": 0.4,
|
|
298
|
+
"end": 0.8
|
|
299
|
+
},
|
|
300
|
+
{
|
|
301
|
+
"text": "this",
|
|
302
|
+
"start": 0.9,
|
|
303
|
+
"end": 1.1
|
|
304
|
+
},
|
|
305
|
+
{
|
|
306
|
+
"text": "is",
|
|
307
|
+
"start": 1.1,
|
|
308
|
+
"end": 1.2
|
|
309
|
+
},
|
|
310
|
+
{
|
|
311
|
+
"text": "the",
|
|
312
|
+
"start": 1.2,
|
|
313
|
+
"end": 1.35
|
|
314
|
+
},
|
|
315
|
+
{
|
|
316
|
+
"text": "board.",
|
|
317
|
+
"start": 1.35,
|
|
318
|
+
"end": 1.9
|
|
319
|
+
}
|
|
320
|
+
]
|
|
321
|
+
}
|
|
322
|
+
},
|
|
323
|
+
"expected": {
|
|
324
|
+
"output": {
|
|
325
|
+
"schemaVersion": 1,
|
|
326
|
+
"mode": "imagePanel",
|
|
327
|
+
"meta": {
|
|
328
|
+
"title": "Canvas",
|
|
329
|
+
"aspect": "16:9"
|
|
330
|
+
},
|
|
331
|
+
"audio": {
|
|
332
|
+
"voPath": "/api/media/example/kitchen.wav",
|
|
333
|
+
"words": [
|
|
334
|
+
{
|
|
335
|
+
"text": "Hello",
|
|
336
|
+
"startMs": 0,
|
|
337
|
+
"endMs": 400
|
|
338
|
+
}
|
|
339
|
+
]
|
|
340
|
+
},
|
|
341
|
+
"styleBlock": "canvas editor",
|
|
342
|
+
"sheets": {},
|
|
343
|
+
"lineages": {},
|
|
344
|
+
"scenes": [
|
|
345
|
+
{
|
|
346
|
+
"sceneId": "s1",
|
|
347
|
+
"title": "Canvas",
|
|
348
|
+
"genre": null
|
|
349
|
+
}
|
|
350
|
+
],
|
|
351
|
+
"strip": [
|
|
352
|
+
{
|
|
353
|
+
"panelId": "cv1",
|
|
354
|
+
"type": "canvas",
|
|
355
|
+
"sceneId": "s1",
|
|
356
|
+
"background": "#ffffff",
|
|
357
|
+
"autoArrange": true,
|
|
358
|
+
"planned": false,
|
|
359
|
+
"startMs": 0,
|
|
360
|
+
"durationMs": 2000,
|
|
361
|
+
"transitionIn": "cut",
|
|
362
|
+
"provenance": "user",
|
|
363
|
+
"elements": [
|
|
364
|
+
{
|
|
365
|
+
"id": "t1",
|
|
366
|
+
"kind": "text",
|
|
367
|
+
"text": "Hello there",
|
|
368
|
+
"appearMs": 0,
|
|
369
|
+
"leaveMs": null,
|
|
370
|
+
"pos": {
|
|
371
|
+
"x": 0.5,
|
|
372
|
+
"y": 0.22
|
|
373
|
+
},
|
|
374
|
+
"size": 0.07,
|
|
375
|
+
"font": "Hanken Grotesk",
|
|
376
|
+
"color": "#111111",
|
|
377
|
+
"weight": 800,
|
|
378
|
+
"anim": {
|
|
379
|
+
"type": "pop",
|
|
380
|
+
"perWord": false,
|
|
381
|
+
"speedMs": 180
|
|
382
|
+
},
|
|
383
|
+
"sfx": "none",
|
|
384
|
+
"pinned": true
|
|
385
|
+
},
|
|
386
|
+
{
|
|
387
|
+
"id": "i1",
|
|
388
|
+
"kind": "image",
|
|
389
|
+
"src": "/api/media/example/photo-1.jpg",
|
|
390
|
+
"source": "generated",
|
|
391
|
+
"appearMs": 400,
|
|
392
|
+
"leaveMs": null,
|
|
393
|
+
"pos": {
|
|
394
|
+
"x": 0.5,
|
|
395
|
+
"y": 0.6
|
|
396
|
+
},
|
|
397
|
+
"size": 0.34,
|
|
398
|
+
"tilt": 0,
|
|
399
|
+
"entrance": "pop",
|
|
400
|
+
"sfx": "auto",
|
|
401
|
+
"pinned": true
|
|
402
|
+
}
|
|
403
|
+
]
|
|
404
|
+
}
|
|
405
|
+
]
|
|
406
|
+
},
|
|
407
|
+
"editorTimeline": {
|
|
408
|
+
"schemaVersion": 1,
|
|
409
|
+
"activeTimelineId": "whiteboard",
|
|
410
|
+
"tracks": [
|
|
411
|
+
{
|
|
412
|
+
"id": "video",
|
|
413
|
+
"label": "Media",
|
|
414
|
+
"type": "visual"
|
|
415
|
+
},
|
|
416
|
+
{
|
|
417
|
+
"id": "text",
|
|
418
|
+
"label": "Text",
|
|
419
|
+
"type": "text"
|
|
420
|
+
},
|
|
421
|
+
{
|
|
422
|
+
"id": "captions",
|
|
423
|
+
"label": "Captions",
|
|
424
|
+
"type": "caption"
|
|
425
|
+
},
|
|
426
|
+
{
|
|
427
|
+
"id": "audio-voiceover",
|
|
428
|
+
"label": "Voiceover",
|
|
429
|
+
"type": "audio"
|
|
430
|
+
},
|
|
431
|
+
{
|
|
432
|
+
"id": "audio-sfx",
|
|
433
|
+
"label": "Sound Effects",
|
|
434
|
+
"type": "audio"
|
|
435
|
+
}
|
|
436
|
+
],
|
|
437
|
+
"clips": [
|
|
438
|
+
{
|
|
439
|
+
"id": "panel-cv1",
|
|
440
|
+
"kind": "collage",
|
|
441
|
+
"url": null,
|
|
442
|
+
"collage": {
|
|
443
|
+
"background": "#ffffff",
|
|
444
|
+
"elements": [
|
|
445
|
+
{
|
|
446
|
+
"id": "t1",
|
|
447
|
+
"kind": "text",
|
|
448
|
+
"text": "Hello there",
|
|
449
|
+
"appearMs": 0,
|
|
450
|
+
"leaveMs": null,
|
|
451
|
+
"pos": {
|
|
452
|
+
"x": 0.5,
|
|
453
|
+
"y": 0.22
|
|
454
|
+
},
|
|
455
|
+
"size": 0.07,
|
|
456
|
+
"font": "Hanken Grotesk",
|
|
457
|
+
"color": "#111111",
|
|
458
|
+
"weight": 800,
|
|
459
|
+
"anim": {
|
|
460
|
+
"type": "pop",
|
|
461
|
+
"perWord": false,
|
|
462
|
+
"speedMs": 180
|
|
463
|
+
},
|
|
464
|
+
"sfx": "none",
|
|
465
|
+
"pinned": true
|
|
466
|
+
},
|
|
467
|
+
{
|
|
468
|
+
"id": "i1",
|
|
469
|
+
"kind": "image",
|
|
470
|
+
"src": "/api/media/example/photo-1.jpg",
|
|
471
|
+
"source": "generated",
|
|
472
|
+
"appearMs": 400,
|
|
473
|
+
"leaveMs": null,
|
|
474
|
+
"pos": {
|
|
475
|
+
"x": 0.5,
|
|
476
|
+
"y": 0.6
|
|
477
|
+
},
|
|
478
|
+
"size": 0.34,
|
|
479
|
+
"tilt": 0,
|
|
480
|
+
"entrance": "pop",
|
|
481
|
+
"sfx": "auto",
|
|
482
|
+
"pinned": true
|
|
483
|
+
}
|
|
484
|
+
],
|
|
485
|
+
"durationMs": 2000,
|
|
486
|
+
"aspect": "16:9"
|
|
487
|
+
},
|
|
488
|
+
"trackId": "video",
|
|
489
|
+
"start": 0,
|
|
490
|
+
"duration": 2,
|
|
491
|
+
"sourceDuration": 2,
|
|
492
|
+
"trimStart": 0,
|
|
493
|
+
"title": "cv1 · collage canvas",
|
|
494
|
+
"panelId": "cv1",
|
|
495
|
+
"source": "canvas",
|
|
496
|
+
"opacity": 1
|
|
497
|
+
}
|
|
498
|
+
],
|
|
499
|
+
"captions": [
|
|
500
|
+
{
|
|
501
|
+
"id": "panel-caption-0",
|
|
502
|
+
"trackId": "captions",
|
|
503
|
+
"text": "Hello",
|
|
504
|
+
"words": [
|
|
505
|
+
{
|
|
506
|
+
"text": "Hello",
|
|
507
|
+
"start": 0,
|
|
508
|
+
"end": 0.4
|
|
509
|
+
}
|
|
510
|
+
],
|
|
511
|
+
"highlightColor": "#ffd400",
|
|
512
|
+
"animation": "none",
|
|
513
|
+
"font": "Hanken Grotesk",
|
|
514
|
+
"size": 24,
|
|
515
|
+
"color": "#ffffff",
|
|
516
|
+
"background": "none",
|
|
517
|
+
"backgroundOpacity": 45,
|
|
518
|
+
"backgroundPadding": 10,
|
|
519
|
+
"backgroundRadius": 6,
|
|
520
|
+
"position": "bottom center",
|
|
521
|
+
"start": 0,
|
|
522
|
+
"end": 0.4
|
|
523
|
+
}
|
|
524
|
+
],
|
|
525
|
+
"audioItems": [
|
|
526
|
+
{
|
|
527
|
+
"id": "panel-voiceover",
|
|
528
|
+
"trackId": "audio-voiceover",
|
|
529
|
+
"name": "Voiceover",
|
|
530
|
+
"url": "/api/media/example/kitchen.wav",
|
|
531
|
+
"start": 0,
|
|
532
|
+
"duration": 2,
|
|
533
|
+
"volume": 100
|
|
534
|
+
},
|
|
535
|
+
{
|
|
536
|
+
"id": "cnv-cv1-i1",
|
|
537
|
+
"scoreKey": "cnv-cv1-i1",
|
|
538
|
+
"trackId": "audio-sfx",
|
|
539
|
+
"purpose": "sfx",
|
|
540
|
+
"name": "Pop · snappy",
|
|
541
|
+
"url": "/sfx/pops/pop-snappy.wav",
|
|
542
|
+
"start": 0.4,
|
|
543
|
+
"duration": 0.092,
|
|
544
|
+
"sourceDuration": 0.092,
|
|
545
|
+
"volume": 55,
|
|
546
|
+
"source": "pop",
|
|
547
|
+
"popVariant": 0
|
|
548
|
+
}
|
|
549
|
+
],
|
|
550
|
+
"transcript": "Hello",
|
|
551
|
+
"aspect": "16:9"
|
|
552
|
+
},
|
|
553
|
+
"result": null
|
|
554
|
+
}
|
|
555
|
+
},
|
|
556
|
+
{
|
|
557
|
+
"name": "Makes a board picture from its description",
|
|
558
|
+
"input": {
|
|
559
|
+
"make": "image",
|
|
560
|
+
"board": {
|
|
561
|
+
"schemaVersion": 1,
|
|
562
|
+
"mode": "imagePanel",
|
|
563
|
+
"meta": {
|
|
564
|
+
"title": "Canvas",
|
|
565
|
+
"aspect": "16:9"
|
|
566
|
+
},
|
|
567
|
+
"audio": {
|
|
568
|
+
"voPath": "/api/media/example/kitchen.wav",
|
|
569
|
+
"words": [
|
|
570
|
+
{
|
|
571
|
+
"text": "Hello",
|
|
572
|
+
"startMs": 0,
|
|
573
|
+
"endMs": 400
|
|
574
|
+
}
|
|
575
|
+
]
|
|
576
|
+
},
|
|
577
|
+
"styleBlock": "canvas editor",
|
|
578
|
+
"sheets": {},
|
|
579
|
+
"lineages": {},
|
|
580
|
+
"scenes": [
|
|
581
|
+
{
|
|
582
|
+
"sceneId": "s1",
|
|
583
|
+
"title": "Canvas",
|
|
584
|
+
"genre": null
|
|
585
|
+
}
|
|
586
|
+
],
|
|
587
|
+
"strip": [
|
|
588
|
+
{
|
|
589
|
+
"panelId": "cv1",
|
|
590
|
+
"type": "canvas",
|
|
591
|
+
"sceneId": "s1",
|
|
592
|
+
"background": "#ffffff",
|
|
593
|
+
"autoArrange": true,
|
|
594
|
+
"planned": false,
|
|
595
|
+
"startMs": 0,
|
|
596
|
+
"durationMs": 2000,
|
|
597
|
+
"transitionIn": "cut",
|
|
598
|
+
"provenance": "user",
|
|
599
|
+
"elements": [
|
|
600
|
+
{
|
|
601
|
+
"id": "t1",
|
|
602
|
+
"kind": "text",
|
|
603
|
+
"text": "Hello there",
|
|
604
|
+
"appearMs": 0,
|
|
605
|
+
"leaveMs": null,
|
|
606
|
+
"pos": {
|
|
607
|
+
"x": 0.5,
|
|
608
|
+
"y": 0.22
|
|
609
|
+
},
|
|
610
|
+
"size": 0.07,
|
|
611
|
+
"font": "Hanken Grotesk",
|
|
612
|
+
"color": "#111111",
|
|
613
|
+
"weight": 800,
|
|
614
|
+
"anim": {
|
|
615
|
+
"type": "pop",
|
|
616
|
+
"perWord": false,
|
|
617
|
+
"speedMs": 180
|
|
618
|
+
},
|
|
619
|
+
"sfx": "none",
|
|
620
|
+
"pinned": true
|
|
621
|
+
},
|
|
622
|
+
{
|
|
623
|
+
"id": "i1",
|
|
624
|
+
"kind": "image",
|
|
625
|
+
"src": "/api/media/example/photo-1.jpg",
|
|
626
|
+
"source": "generated",
|
|
627
|
+
"appearMs": 400,
|
|
628
|
+
"leaveMs": null,
|
|
629
|
+
"pos": {
|
|
630
|
+
"x": 0.5,
|
|
631
|
+
"y": 0.6
|
|
632
|
+
},
|
|
633
|
+
"size": 0.34,
|
|
634
|
+
"tilt": 0,
|
|
635
|
+
"entrance": "pop",
|
|
636
|
+
"sfx": "auto",
|
|
637
|
+
"pinned": true
|
|
638
|
+
}
|
|
639
|
+
]
|
|
640
|
+
}
|
|
641
|
+
]
|
|
642
|
+
},
|
|
643
|
+
"request": {
|
|
644
|
+
"model": "gpt-image-2",
|
|
645
|
+
"readablePrompt": "A lighthouse at dusk",
|
|
646
|
+
"aspectRatio": "1:1"
|
|
647
|
+
}
|
|
648
|
+
},
|
|
649
|
+
"mocks": {
|
|
650
|
+
"hosted": {
|
|
651
|
+
"image.generate": {
|
|
652
|
+
"kind": "image",
|
|
653
|
+
"assetId": "made-1",
|
|
654
|
+
"versionId": "made-1-v1",
|
|
655
|
+
"url": "https://media.example/made-1.png",
|
|
656
|
+
"mimeType": "image/png",
|
|
657
|
+
"width": 1024,
|
|
658
|
+
"height": 1024,
|
|
659
|
+
"bytes": 200000
|
|
660
|
+
}
|
|
661
|
+
}
|
|
662
|
+
},
|
|
663
|
+
"expected": {
|
|
664
|
+
"output": {
|
|
665
|
+
"schemaVersion": 1,
|
|
666
|
+
"mode": "imagePanel",
|
|
667
|
+
"meta": {
|
|
668
|
+
"title": "Canvas",
|
|
669
|
+
"aspect": "16:9"
|
|
670
|
+
},
|
|
671
|
+
"audio": {
|
|
672
|
+
"voPath": "/api/media/example/kitchen.wav",
|
|
673
|
+
"words": [
|
|
674
|
+
{
|
|
675
|
+
"text": "Hello",
|
|
676
|
+
"startMs": 0,
|
|
677
|
+
"endMs": 400
|
|
678
|
+
}
|
|
679
|
+
]
|
|
680
|
+
},
|
|
681
|
+
"styleBlock": "canvas editor",
|
|
682
|
+
"sheets": {},
|
|
683
|
+
"lineages": {},
|
|
684
|
+
"scenes": [
|
|
685
|
+
{
|
|
686
|
+
"sceneId": "s1",
|
|
687
|
+
"title": "Canvas",
|
|
688
|
+
"genre": null
|
|
689
|
+
}
|
|
690
|
+
],
|
|
691
|
+
"strip": [
|
|
692
|
+
{
|
|
693
|
+
"panelId": "cv1",
|
|
694
|
+
"type": "canvas",
|
|
695
|
+
"sceneId": "s1",
|
|
696
|
+
"background": "#ffffff",
|
|
697
|
+
"autoArrange": true,
|
|
698
|
+
"planned": false,
|
|
699
|
+
"startMs": 0,
|
|
700
|
+
"durationMs": 2000,
|
|
701
|
+
"transitionIn": "cut",
|
|
702
|
+
"provenance": "user",
|
|
703
|
+
"elements": [
|
|
704
|
+
{
|
|
705
|
+
"id": "t1",
|
|
706
|
+
"kind": "text",
|
|
707
|
+
"text": "Hello there",
|
|
708
|
+
"appearMs": 0,
|
|
709
|
+
"leaveMs": null,
|
|
710
|
+
"pos": {
|
|
711
|
+
"x": 0.5,
|
|
712
|
+
"y": 0.22
|
|
713
|
+
},
|
|
714
|
+
"size": 0.07,
|
|
715
|
+
"font": "Hanken Grotesk",
|
|
716
|
+
"color": "#111111",
|
|
717
|
+
"weight": 800,
|
|
718
|
+
"anim": {
|
|
719
|
+
"type": "pop",
|
|
720
|
+
"perWord": false,
|
|
721
|
+
"speedMs": 180
|
|
722
|
+
},
|
|
723
|
+
"sfx": "none",
|
|
724
|
+
"pinned": true
|
|
725
|
+
},
|
|
726
|
+
{
|
|
727
|
+
"id": "i1",
|
|
728
|
+
"kind": "image",
|
|
729
|
+
"src": "/api/media/example/photo-1.jpg",
|
|
730
|
+
"source": "generated",
|
|
731
|
+
"appearMs": 400,
|
|
732
|
+
"leaveMs": null,
|
|
733
|
+
"pos": {
|
|
734
|
+
"x": 0.5,
|
|
735
|
+
"y": 0.6
|
|
736
|
+
},
|
|
737
|
+
"size": 0.34,
|
|
738
|
+
"tilt": 0,
|
|
739
|
+
"entrance": "pop",
|
|
740
|
+
"sfx": "auto",
|
|
741
|
+
"pinned": true
|
|
742
|
+
}
|
|
743
|
+
]
|
|
744
|
+
}
|
|
745
|
+
]
|
|
746
|
+
},
|
|
747
|
+
"editorTimeline": {
|
|
748
|
+
"schemaVersion": 1,
|
|
749
|
+
"activeTimelineId": "whiteboard",
|
|
750
|
+
"tracks": [
|
|
751
|
+
{
|
|
752
|
+
"id": "video",
|
|
753
|
+
"label": "Media",
|
|
754
|
+
"type": "visual"
|
|
755
|
+
},
|
|
756
|
+
{
|
|
757
|
+
"id": "text",
|
|
758
|
+
"label": "Text",
|
|
759
|
+
"type": "text"
|
|
760
|
+
},
|
|
761
|
+
{
|
|
762
|
+
"id": "captions",
|
|
763
|
+
"label": "Captions",
|
|
764
|
+
"type": "caption"
|
|
765
|
+
},
|
|
766
|
+
{
|
|
767
|
+
"id": "audio-voiceover",
|
|
768
|
+
"label": "Voiceover",
|
|
769
|
+
"type": "audio"
|
|
770
|
+
},
|
|
771
|
+
{
|
|
772
|
+
"id": "audio-sfx",
|
|
773
|
+
"label": "Sound Effects",
|
|
774
|
+
"type": "audio"
|
|
775
|
+
}
|
|
776
|
+
],
|
|
777
|
+
"clips": [
|
|
778
|
+
{
|
|
779
|
+
"id": "panel-cv1",
|
|
780
|
+
"kind": "collage",
|
|
781
|
+
"url": null,
|
|
782
|
+
"collage": {
|
|
783
|
+
"background": "#ffffff",
|
|
784
|
+
"elements": [
|
|
785
|
+
{
|
|
786
|
+
"id": "t1",
|
|
787
|
+
"kind": "text",
|
|
788
|
+
"text": "Hello there",
|
|
789
|
+
"appearMs": 0,
|
|
790
|
+
"leaveMs": null,
|
|
791
|
+
"pos": {
|
|
792
|
+
"x": 0.5,
|
|
793
|
+
"y": 0.22
|
|
794
|
+
},
|
|
795
|
+
"size": 0.07,
|
|
796
|
+
"font": "Hanken Grotesk",
|
|
797
|
+
"color": "#111111",
|
|
798
|
+
"weight": 800,
|
|
799
|
+
"anim": {
|
|
800
|
+
"type": "pop",
|
|
801
|
+
"perWord": false,
|
|
802
|
+
"speedMs": 180
|
|
803
|
+
},
|
|
804
|
+
"sfx": "none",
|
|
805
|
+
"pinned": true
|
|
806
|
+
},
|
|
807
|
+
{
|
|
808
|
+
"id": "i1",
|
|
809
|
+
"kind": "image",
|
|
810
|
+
"src": "/api/media/example/photo-1.jpg",
|
|
811
|
+
"source": "generated",
|
|
812
|
+
"appearMs": 400,
|
|
813
|
+
"leaveMs": null,
|
|
814
|
+
"pos": {
|
|
815
|
+
"x": 0.5,
|
|
816
|
+
"y": 0.6
|
|
817
|
+
},
|
|
818
|
+
"size": 0.34,
|
|
819
|
+
"tilt": 0,
|
|
820
|
+
"entrance": "pop",
|
|
821
|
+
"sfx": "auto",
|
|
822
|
+
"pinned": true
|
|
823
|
+
}
|
|
824
|
+
],
|
|
825
|
+
"durationMs": 2000,
|
|
826
|
+
"aspect": "16:9"
|
|
827
|
+
},
|
|
828
|
+
"trackId": "video",
|
|
829
|
+
"start": 0,
|
|
830
|
+
"duration": 2,
|
|
831
|
+
"sourceDuration": 2,
|
|
832
|
+
"trimStart": 0,
|
|
833
|
+
"title": "cv1 · collage canvas",
|
|
834
|
+
"panelId": "cv1",
|
|
835
|
+
"source": "canvas",
|
|
836
|
+
"opacity": 1
|
|
837
|
+
}
|
|
838
|
+
],
|
|
839
|
+
"captions": [
|
|
840
|
+
{
|
|
841
|
+
"id": "panel-caption-0",
|
|
842
|
+
"trackId": "captions",
|
|
843
|
+
"text": "Hello",
|
|
844
|
+
"words": [
|
|
845
|
+
{
|
|
846
|
+
"text": "Hello",
|
|
847
|
+
"start": 0,
|
|
848
|
+
"end": 0.4
|
|
849
|
+
}
|
|
850
|
+
],
|
|
851
|
+
"highlightColor": "#ffd400",
|
|
852
|
+
"animation": "none",
|
|
853
|
+
"font": "Hanken Grotesk",
|
|
854
|
+
"size": 24,
|
|
855
|
+
"color": "#ffffff",
|
|
856
|
+
"background": "none",
|
|
857
|
+
"backgroundOpacity": 45,
|
|
858
|
+
"backgroundPadding": 10,
|
|
859
|
+
"backgroundRadius": 6,
|
|
860
|
+
"position": "bottom center",
|
|
861
|
+
"start": 0,
|
|
862
|
+
"end": 0.4
|
|
863
|
+
}
|
|
864
|
+
],
|
|
865
|
+
"audioItems": [
|
|
866
|
+
{
|
|
867
|
+
"id": "panel-voiceover",
|
|
868
|
+
"trackId": "audio-voiceover",
|
|
869
|
+
"name": "Voiceover",
|
|
870
|
+
"url": "/api/media/example/kitchen.wav",
|
|
871
|
+
"start": 0,
|
|
872
|
+
"duration": 2,
|
|
873
|
+
"volume": 100
|
|
874
|
+
},
|
|
875
|
+
{
|
|
876
|
+
"id": "cnv-cv1-i1",
|
|
877
|
+
"scoreKey": "cnv-cv1-i1",
|
|
878
|
+
"trackId": "audio-sfx",
|
|
879
|
+
"purpose": "sfx",
|
|
880
|
+
"name": "Pop · snappy",
|
|
881
|
+
"url": "/sfx/pops/pop-snappy.wav",
|
|
882
|
+
"start": 0.4,
|
|
883
|
+
"duration": 0.092,
|
|
884
|
+
"sourceDuration": 0.092,
|
|
885
|
+
"volume": 55,
|
|
886
|
+
"source": "pop",
|
|
887
|
+
"popVariant": 0
|
|
888
|
+
}
|
|
889
|
+
],
|
|
890
|
+
"transcript": "Hello",
|
|
891
|
+
"aspect": "16:9"
|
|
892
|
+
},
|
|
893
|
+
"made": [
|
|
894
|
+
{
|
|
895
|
+
"kind": "image",
|
|
896
|
+
"assetId": "made-1",
|
|
897
|
+
"versionId": "made-1-v1",
|
|
898
|
+
"url": "https://media.example/made-1.png",
|
|
899
|
+
"mimeType": "image/png",
|
|
900
|
+
"width": 1024,
|
|
901
|
+
"height": 1024,
|
|
902
|
+
"bytes": 200000
|
|
903
|
+
}
|
|
904
|
+
],
|
|
905
|
+
"result": {
|
|
906
|
+
"kind": "image",
|
|
907
|
+
"assetId": "made-1",
|
|
908
|
+
"versionId": "made-1-v1",
|
|
909
|
+
"url": "https://media.example/made-1.png",
|
|
910
|
+
"mimeType": "image/png",
|
|
911
|
+
"width": 1024,
|
|
912
|
+
"height": 1024,
|
|
913
|
+
"bytes": 200000
|
|
914
|
+
}
|
|
915
|
+
}
|
|
916
|
+
}
|
|
917
|
+
],
|
|
918
|
+
"moduleSource": {
|
|
919
|
+
"main.js": "//#region packages/block-platform/image-panel-prompts.js\nlet chatCollect$2 = 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$1 = \"google/gemini-2.5-flash\";\nfunction useImagePanelTextModel(model = {}) {\n\tif (typeof model.chatCollect === \"function\") chatCollect$2 = 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$1 = model.defaultModel;\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}\nconst CANVAS_CHAT_SYSTEM = `You prepare a canvas build from a user's assets and their narration.\n\nReturn ONLY JSON:\n{\n \"intent\": \"one sentence: what the user is making\",\n \"descriptors\": { \"<assetId>\": \"what this asset shows, in the user's terms\" },\n \"texts\": [ { \"wordIndex\": 12, \"atFraction\": 0.25, \"text\": \"$5k/month\", \"emphasis\": \"primary\" } ]\n}\n\nRULES\n- descriptors: infer from the user's message + narration. Describe the asset's\n ROLE as the user means it (\"an example channel earning $5k/month\"), not a\n literal visual inventory. Only include assets you can genuinely infer; OMIT an\n asset you cannot — omitting is correct and cheap, guessing is not.\n- texts: the short phrases to POP on screen. Each <= 6 words. \"primary\" for the\n most important, \"secondary\" otherwise.\n- WITH narration (words array is non-empty): pull the phrases from the\n narration's own wording and give each a \"wordIndex\" into that array. 0-6\n total — an intro, not a caption track. Omit atFraction.\n- WITHOUT narration (words array is empty): the user wants animated WORDS as if\n a voiceover were reading — WRITE the short on-screen phrases yourself from\n their request, like a punchy intro script. Give MANY (up to 12) so the piece\n feels alive, and give EACH an \"atFraction\" (0..1) for when in the video it\n appears — spread them across the whole thing, roughly evenly. Omit wordIndex.\n- wordIndex (when used) must be a valid index into the provided words array.\n- No prose outside the JSON.`;\nfunction normalizeCanvasChatPlan(raw, { wordCount = 0, assetIds = [] } = {}) {\n\tconst allowed = new Set((assetIds || []).map(String));\n\tconst out = {\n\t\tintent: \"\",\n\t\tdescriptors: {},\n\t\ttexts: []\n\t};\n\tif (!raw || typeof raw !== \"object\") return out;\n\tout.intent = String(raw.intent || \"\").slice(0, 300);\n\tconst d = raw.descriptors && typeof raw.descriptors === \"object\" ? raw.descriptors : {};\n\tfor (const [k, v] of Object.entries(d)) {\n\t\tif (allowed.size && !allowed.has(String(k))) continue;\n\t\tconst text = String(v || \"\").replace(/\\s+/g, \" \").trim().slice(0, 200);\n\t\tif (text.length >= 3) out.descriptors[String(k)] = text;\n\t}\n\tconst seen = /* @__PURE__ */ new Set();\n\tout.texts = (Array.isArray(raw.texts) ? raw.texts : []).map((t) => {\n\t\tconst fracRaw = Number(t?.atFraction);\n\t\treturn {\n\t\t\twordIndex: Math.max(0, Math.min(Math.round(Number(t?.wordIndex) || 0), Math.max(0, wordCount - 1))),\n\t\t\tatFraction: Number.isFinite(fracRaw) ? Math.max(0, Math.min(1, fracRaw)) : null,\n\t\t\ttext: String(t?.text || \"\").replace(/\\s+/g, \" \").trim().slice(0, 80),\n\t\t\temphasis: t?.emphasis === \"primary\" ? \"primary\" : \"secondary\"\n\t\t};\n\t}).filter((t) => {\n\t\tif (!t.text) return false;\n\t\tconst k = t.text.toLowerCase();\n\t\tif (seen.has(k)) return false;\n\t\tseen.add(k);\n\t\treturn true;\n\t}).sort((a, b) => (a.atFraction ?? a.wordIndex) - (b.atFraction ?? b.wordIndex)).slice(0, 12);\n\treturn out;\n}\nasync function planCanvasChatBuild({ message, assets = [], words = [], 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})).filter((x) => x.text);\n\tconst brief = (Array.isArray(assets) ? assets : []).slice(0, 60).map((a) => ({\n\t\tid: String(a?.id || \"\").slice(0, 60),\n\t\ttype: a?.type === \"video\" ? \"video\" : \"image\",\n\t\tknown: String(a?.descriptor || a?.prompt || \"\").slice(0, 160)\n\t})).filter((a) => a.id);\n\tconst userPayload = JSON.stringify({\n\t\trequest: String(message || \"\").slice(0, 2e3),\n\t\tassets: brief,\n\t\twords: w\n\t});\n\tconst parsed = parseJson(await chatCollect$2({\n\t\tmodel,\n\t\tsystem: CANVAS_CHAT_SYSTEM,\n\t\tmax_tokens: 2e3,\n\t\ttimeoutMs: 6e4,\n\t\tbudgetMs: 9e4,\n\t\tmessages: [{\n\t\t\trole: \"user\",\n\t\t\tcontent: userPayload\n\t\t}]\n\t}));\n\tif (!parsed && model !== DEFAULT_MODEL$1) return normalizeCanvasChatPlan(parseJson(await chatCollect$2({\n\t\tmodel: DEFAULT_MODEL$1,\n\t\tsystem: CANVAS_CHAT_SYSTEM,\n\t\tmax_tokens: 2e3,\n\t\ttimeoutMs: 4e4,\n\t\tbudgetMs: 4e4,\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\tassetIds: brief.map((a) => a.id)\n\t});\n\treturn normalizeCanvasChatPlan(parsed, {\n\t\twordCount: w.length,\n\t\tassetIds: brief.map((a) => a.id)\n\t});\n}\nconst CANVAS_EDIT_SYSTEM = `You turn a user's plain-language change request into canvas edit operations.\n\nReturn ONLY JSON: { \"edits\": [ { \"kind\": ..., \"panelId\": ..., \"elementId\": ..., ... } ] }\n\nkind is one of: resize | move | swap | addText | retrim | spread | transition | remove\n- resize: direction \"bigger\"|\"smaller\" (or size 0.06-0.9)\n- move: x,y as 0-1 fractions of the canvas\n- swap: needs an elementId; url only if the user named a specific asset\n- addText: text (<= 80 chars), optional appearMs, emphasis \"primary\"|\"secondary\"\n- retrim: beatMs (how long the clip should run)\n- spread: no extra fields\n- transition: transition name (cut|swirl|morph|wipe|push)\n- remove: needs an elementId\n\nRULES\n- Use ONLY panelIds and elementIds from the provided canvases. Never invent one.\n- If the user names no target, omit panelId/elementId and the caller applies it\n to the obvious default.\n- If you cannot map the request to a listed kind, return {\"edits\": []}. An empty\n list is the correct answer for an unclear request — do not guess.\n- No prose outside the JSON.`;\nfunction normalizeCanvasEdits(raw, { panelIds = [], elementIds = [] } = {}) {\n\tconst KINDS = /* @__PURE__ */ new Set([\n\t\t\"resize\",\n\t\t\"move\",\n\t\t\"swap\",\n\t\t\"addText\",\n\t\t\"retrim\",\n\t\t\"spread\",\n\t\t\"transition\",\n\t\t\"remove\"\n\t]);\n\tconst pOk = new Set(panelIds.map(String));\n\tconst eOk = new Set(elementIds.map(String));\n\tconst list = Array.isArray(raw?.edits) ? raw.edits : [];\n\tconst out = [];\n\tfor (const e of list.slice(0, 12)) {\n\t\tconst kind = String(e?.kind || \"\");\n\t\tif (!KINDS.has(kind)) continue;\n\t\tconst panelId = e?.panelId != null ? String(e.panelId) : void 0;\n\t\tconst elementId = e?.elementId != null ? String(e.elementId) : void 0;\n\t\tif (panelId && !pOk.has(panelId)) continue;\n\t\tif (elementId && !eOk.has(elementId)) continue;\n\t\tif ((kind === \"swap\" || kind === \"remove\") && !elementId) continue;\n\t\tconst edit = {\n\t\t\tkind,\n\t\t\t...panelId ? { panelId } : {},\n\t\t\t...elementId ? { elementId } : {}\n\t\t};\n\t\tif (kind === \"resize\") {\n\t\t\tif (e.size != null) edit.size = Math.max(.06, Math.min(.9, Number(e.size) || .3));\n\t\t\telse edit.direction = e.direction === \"smaller\" ? \"smaller\" : \"bigger\";\n\t\t}\n\t\tif (kind === \"move\") {\n\t\t\tedit.x = Math.max(0, Math.min(1, Number(e.x) || 0));\n\t\t\tedit.y = Math.max(0, Math.min(1, Number(e.y) || 0));\n\t\t}\n\t\tif (kind === \"swap\" && e.url) edit.url = String(e.url).slice(0, 500);\n\t\tif (kind === \"addText\") {\n\t\t\tconst text = String(e.text || \"\").replace(/\\s+/g, \" \").trim().slice(0, 80);\n\t\t\tif (!text) continue;\n\t\t\tedit.text = text;\n\t\t\tif (e.appearMs != null) edit.appearMs = Math.max(0, Math.round(Number(e.appearMs) || 0));\n\t\t\tedit.emphasis = e.emphasis === \"primary\" ? \"primary\" : \"secondary\";\n\t\t}\n\t\tif (kind === \"retrim\") edit.beatMs = Math.max(200, Math.round(Number(e.beatMs) || 1e3));\n\t\tif (kind === \"transition\") {\n\t\t\tconst t = String(e.transition || \"\").trim().slice(0, 24);\n\t\t\tif (!t) continue;\n\t\t\tedit.transition = t;\n\t\t}\n\t\tout.push(edit);\n\t}\n\treturn out;\n}\nasync function parseCanvasChatEdit({ message, canvases = [], model } = {}) {\n\tconst brief = (Array.isArray(canvases) ? canvases : []).slice(0, 12).map((p) => ({\n\t\tpanelId: String(p?.panelId || \"\"),\n\t\tdurationMs: Number(p?.durationMs) || 0,\n\t\ttransitionIn: String(p?.transitionIn || \"\"),\n\t\telements: (p?.elements || []).slice(0, 20).map((el) => ({\n\t\t\tid: String(el?.id || \"\"),\n\t\t\tkind: String(el?.kind || \"\"),\n\t\t\ttext: el?.kind === \"text\" ? String(el.text || \"\").slice(0, 40) : void 0,\n\t\t\tdescriptor: String(el?.descriptor || \"\").slice(0, 80) || void 0\n\t\t}))\n\t})).filter((p) => p.panelId);\n\tconst panelIds = brief.map((p) => p.panelId);\n\tconst elementIds = brief.flatMap((p) => p.elements.map((e) => e.id));\n\tconst payload = JSON.stringify({\n\t\trequest: String(message || \"\").slice(0, 500),\n\t\tcanvases: brief\n\t});\n\tconst parsed = parseJson(await chatCollect$2({\n\t\tmodel,\n\t\tsystem: CANVAS_EDIT_SYSTEM,\n\t\tmax_tokens: 900,\n\t\ttimeoutMs: 4e4,\n\t\tbudgetMs: 6e4,\n\t\tmessages: [{\n\t\t\trole: \"user\",\n\t\t\tcontent: payload\n\t\t}]\n\t}));\n\tif (!parsed && model !== DEFAULT_MODEL$1) return normalizeCanvasEdits(parseJson(await chatCollect$2({\n\t\tmodel: DEFAULT_MODEL$1,\n\t\tsystem: CANVAS_EDIT_SYSTEM,\n\t\tmax_tokens: 900,\n\t\ttimeoutMs: 25e3,\n\t\tbudgetMs: 25e3,\n\t\tmessages: [{\n\t\t\trole: \"user\",\n\t\t\tcontent: payload\n\t\t}]\n\t})), {\n\t\tpanelIds,\n\t\telementIds\n\t});\n\treturn normalizeCanvasEdits(parsed, {\n\t\tpanelIds,\n\t\telementIds\n\t});\n}\n\n//#endregion\n//#region packages/block-platform/presenter-prompts.js\nlet chatCollect$1 = async () => {\n\tthrow new Error(\"No text model is connected for the presenter.\");\n};\nlet DEFAULT_MODEL = \"google/gemini-2.5-flash\";\nfunction usePresenterTextModel(model = {}) {\n\tif (typeof model.chatCollect === \"function\") chatCollect$1 = model.chatCollect;\n\tif (typeof model.defaultModel === \"string\" && model.defaultModel) DEFAULT_MODEL = model.defaultModel;\n}\nconst PRESENTER_POSE_VOCAB = [\n\t\"point-left\",\n\t\"point-right\",\n\t\"point-up\",\n\t\"point-down\",\n\t\"present\",\n\t\"explain\",\n\t\"think\",\n\t\"surprised\",\n\t\"wave\",\n\t\"idle\",\n\t\"count\",\n\t\"shrug\",\n\t\"celebrate\",\n\t\"write\",\n\t\"thumbs-up\",\n\t\"welcome\"\n];\nconst MIN_POSES = 16;\nfunction poseSlug(label) {\n\treturn String(label || \"\").toLowerCase().replace(/[^a-z0-9]+/g, \"-\").replace(/^-+|-+$/g, \"\").slice(0, 40);\n}\nfunction poseLabelText(slug) {\n\treturn String(slug || \"\").replace(/-/g, \" \").trim();\n}\nconst PRESENTER_PLAN_SYSTEM = `You are the DIRECTOR of a 2D presenter/host character for an explainer video. The CONTENT is already written — you decide what a good on-screen presenter would DO across it: which gesture/pose fits each beat (point left/right/up/down at what's being shown, present, explain, think, look surprised, count, wave, etc.).\n\nYou are given the narration/story and (optionally) word timings. Return ONLY JSON:\n{\n \"character\": { \"name\": \"<short host name>\", \"definition\": \"<one vivid sentence describing the SAME presenter to draw every time: age, build, hair, clothing, simple friendly 2D style — no background>\" },\n \"poses\": [ { \"label\": \"<short-kebab-gesture>\", \"description\": \"<what the presenter is physically doing, e.g. 'pointing to the right with one arm extended, other hand open'>\", \"atWord\": <integer word index this pose fits, or null> } ]\n}\n\nRules:\n- Choose poses from what the CONTENT needs — a range of distinct gestures, not repeats. Prefer these canonical labels when they fit: ${PRESENTER_POSE_VOCAB.join(\", \")}. Invent a kebab-case label only when none fit.\n- Each pose = full-body standing presenter, one clear readable action, friendly and simple.\n- Aim for enough poses to cover the beats (at least ${16}). One character definition, reused for every pose.\n- No text, no background, no props unless the gesture needs one. Output JSON only.`;\nfunction normalizePresenterPlan(parsed, { words = 0 } = {}) {\n\tconst wc = Number(words) || 0;\n\tconst seen = /* @__PURE__ */ new Set();\n\tconst poses = [];\n\tfor (const p of Array.isArray(parsed?.poses) ? parsed.poses : []) {\n\t\tconst label = poseSlug(p?.label);\n\t\tif (!label || seen.has(label)) continue;\n\t\tseen.add(label);\n\t\tlet atWord = Number.isFinite(Number(p?.atWord)) ? Math.round(Number(p.atWord)) : null;\n\t\tif (atWord != null && (atWord < 0 || wc && atWord >= wc)) atWord = null;\n\t\tposes.push({\n\t\t\tlabel,\n\t\t\tdescription: String(p?.description || poseLabelText(label)).slice(0, 200),\n\t\t\tatWord\n\t\t});\n\t\tif (poses.length >= 60) break;\n\t}\n\treturn {\n\t\tcharacter: {\n\t\t\tname: String(parsed?.character?.name || \"Host\").slice(0, 60),\n\t\t\tdefinition: String(parsed?.character?.definition || \"a friendly 2D presenter in simple flat style\").slice(0, 400)\n\t\t},\n\t\tposes\n\t};\n}\nfunction fallbackPresenterPlan() {\n\treturn {\n\t\tcharacter: {\n\t\t\tname: \"Host\",\n\t\t\tdefinition: \"a friendly 2D presenter with simple flat-color style, neutral clothing, no background\"\n\t\t},\n\t\tposes: PRESENTER_POSE_VOCAB.map((label) => ({\n\t\t\tlabel,\n\t\t\tdescription: `presenter ${poseLabelText(label)}`,\n\t\t\tatWord: null\n\t\t}))\n\t};\n}\nasync function planPresenterPoses({ content = \"\", words = [], model } = {}) {\n\tconst wc = Array.isArray(words) ? words.length : 0;\n\tconst userPayload = JSON.stringify({\n\t\tcontent: String(content || \"\").slice(0, 8e3),\n\t\twords: (Array.isArray(words) ? words : []).slice(0, 1200).map((w) => typeof w === \"string\" ? w : w?.text || \"\")\n\t});\n\tlet parsed = null;\n\ttry {\n\t\tconst raw = await chatCollect$1({\n\t\t\tmodel: model || DEFAULT_MODEL,\n\t\t\tsystem: PRESENTER_PLAN_SYSTEM,\n\t\t\tmax_tokens: 2e3,\n\t\t\ttimeoutMs: 6e4,\n\t\t\tbudgetMs: 9e4,\n\t\t\tmessages: [{\n\t\t\t\trole: \"user\",\n\t\t\t\tcontent: userPayload\n\t\t\t}]\n\t\t});\n\t\tparsed = parseJson(raw);\n\t} catch {\n\t\tparsed = null;\n\t}\n\tif (!parsed || !Array.isArray(parsed.poses) || !parsed.poses.length) return fallbackPresenterPlan();\n\tconst norm = normalizePresenterPlan(parsed, { words: wc });\n\treturn norm.poses.length ? norm : fallbackPresenterPlan();\n}\n\n//#endregion\n//#region packages/block-platform/describe-image-prompt.js\nconst DESCRIBE_IMAGE_SYSTEM = \"You analyze images for video production. Describe texture, color, lighting, composition, subject placement, camera feel, and visual style. Return concise production-ready text only. A user-provided hint may accompany the image — it can be a meaningless filename or a real description, so trust the image first and use the hint only when it genuinely helps.\";\n/** The question for one picture, with the optional label (a filename or the person's own words) as a hint. */\nfunction describeImageQuestion(hint = \"\") {\n\tconst clean = String(hint || \"\").trim().slice(0, 300);\n\treturn `Describe this image for reuse as a visual prompt/style reference.${clean ? `\\n\\nThe user attached this label as a hint: \"${clean}\". It may be a raw filename with NO real meaning, OR a genuine description they wrote. Use it only if it actually helps identify the subject; otherwise ignore it entirely and describe exactly what you see.` : \"\"}`;\n}\n\n//#endregion\n//#region blocks/native/shared/src/imagePanel/methods.js\nconst METHOD_IDS = [\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 METHOD_SET = new Set(METHOD_IDS);\nconst PROGRESSION_METHODS = [\n\t\"expressionSequence\",\n\t\"poseProgression\",\n\t\"accumulation\",\n\t\"progressiveReveal\",\n\t\"zoomProgression\"\n];\nconst PROGRESSION_SET = new Set(PROGRESSION_METHODS);\n\n//#endregion\n//#region blocks/native/shared/src/imagePanel/animatedBackgrounds.js\nfunction fillBase(ctx, w, h, c0, c1) {\n\tconst g = ctx.createLinearGradient(0, 0, 0, h);\n\tg.addColorStop(0, c0);\n\tg.addColorStop(1, c1);\n\tctx.fillStyle = g;\n\tctx.fillRect(0, 0, w, h);\n}\nfunction rand(n) {\n\tconst x = Math.sin(n * 127.1 + 311.7) * 43758.5453;\n\treturn x - Math.floor(x);\n}\nfunction hexToRgb(hex) {\n\tconst m = /^#?([0-9a-f]{6})$/i.exec(String(hex || \"\").trim());\n\tif (!m) return null;\n\tconst n = parseInt(m[1], 16);\n\treturn {\n\t\tr: n >> 16 & 255,\n\t\tg: n >> 8 & 255,\n\t\tb: n & 255\n\t};\n}\nfunction mixHex(a, b, t) {\n\tconst A = hexToRgb(a);\n\tconst B = hexToRgb(b);\n\tif (!A || !B) return a;\n\tconst c = (k) => Math.round(A[k] + (B[k] - A[k]) * t);\n\treturn `rgb(${c(\"r\")},${c(\"g\")},${c(\"b\")})`;\n}\nfunction rgba(hex, alpha) {\n\tconst c = hexToRgb(hex);\n\treturn c ? `rgba(${c.r},${c.g},${c.b},${alpha})` : `rgba(0,0,0,${alpha})`;\n}\nconst hasColors = (colors) => Array.isArray(colors) && colors.length > 0;\nfunction drawGrid(ctx, w, h, t, colors) {\n\tlet c0;\n\tlet c1;\n\tlet line;\n\tlet glowA;\n\tlet glowB;\n\tif (hasColors(colors)) {\n\t\tconst base = colors[0] || GRID_DEF[0];\n\t\tconst accent = colors[1] || GRID_DEF[1];\n\t\tc0 = base;\n\t\tc1 = mixHex(base, accent, .4);\n\t\tline = rgba(accent, .28);\n\t\tglowA = rgba(accent, .35);\n\t\tglowB = rgba(accent, 0);\n\t} else {\n\t\tc0 = \"#0a1a3f\";\n\t\tc1 = \"#123a8a\";\n\t\tline = \"rgba(120,170,255,0.28)\";\n\t\tglowA = \"rgba(80,140,255,0.35)\";\n\t\tglowB = \"rgba(80,140,255,0)\";\n\t}\n\tfillBase(ctx, w, h, c0, c1);\n\tconst cell = Math.max(28, Math.min(w, h) * .09);\n\tconst scroll = t * cell * .35 % cell;\n\tctx.lineWidth = Math.max(1, Math.min(w, h) * .0022);\n\tctx.strokeStyle = line;\n\tctx.beginPath();\n\tfor (let x = -cell + scroll % cell; x <= w + cell; x += cell) {\n\t\tctx.moveTo(x, 0);\n\t\tctx.lineTo(x, h);\n\t}\n\tfor (let y = -cell + scroll; y <= h + cell; y += cell) {\n\t\tctx.moveTo(0, y);\n\t\tctx.lineTo(w, y);\n\t}\n\tctx.stroke();\n\tconst glow = ctx.createRadialGradient(w / 2, h * .45, 0, w / 2, h * .45, Math.max(w, h) * .6);\n\tglow.addColorStop(0, glowA);\n\tglow.addColorStop(1, glowB);\n\tctx.fillStyle = glow;\n\tctx.fillRect(0, 0, w, h);\n}\nfunction drawAurora(ctx, w, h, t) {\n\tfillBase(ctx, w, h, \"#050716\", \"#0b1030\");\n\tconst blobs = [\n\t\t{\n\t\t\tc: \"rgba(90,220,200,0.55)\",\n\t\t\tfx: .07,\n\t\t\tfy: .05,\n\t\t\tpx: .3,\n\t\t\tpy: .35,\n\t\t\tr: .55\n\t\t},\n\t\t{\n\t\t\tc: \"rgba(140,90,240,0.5)\",\n\t\t\tfx: .05,\n\t\t\tfy: .08,\n\t\t\tpx: .7,\n\t\t\tpy: .5,\n\t\t\tr: .6\n\t\t},\n\t\t{\n\t\t\tc: \"rgba(60,140,255,0.5)\",\n\t\t\tfx: .09,\n\t\t\tfy: .06,\n\t\t\tpx: .5,\n\t\t\tpy: .7,\n\t\t\tr: .5\n\t\t},\n\t\t{\n\t\t\tc: \"rgba(240,120,190,0.4)\",\n\t\t\tfx: .06,\n\t\t\tfy: .09,\n\t\t\tpx: .4,\n\t\t\tpy: .2,\n\t\t\tr: .45\n\t\t}\n\t];\n\tctx.globalCompositeOperation = \"lighter\";\n\tfor (let i = 0; i < blobs.length; i++) {\n\t\tconst b = blobs[i];\n\t\tconst cx = w * (b.px + .18 * Math.sin(t * b.fx * Math.PI * 2 + i));\n\t\tconst cy = h * (b.py + .16 * Math.cos(t * b.fy * Math.PI * 2 + i * 1.7));\n\t\tconst rad = Math.max(w, h) * b.r;\n\t\tconst g = ctx.createRadialGradient(cx, cy, 0, cx, cy, rad);\n\t\tg.addColorStop(0, b.c);\n\t\tg.addColorStop(1, \"rgba(0,0,0,0)\");\n\t\tctx.fillStyle = g;\n\t\tctx.fillRect(0, 0, w, h);\n\t}\n\tctx.globalCompositeOperation = \"source-over\";\n}\nfunction drawMesh(ctx, w, h, t) {\n\tfillBase(ctx, w, h, \"#1a1130\", \"#2a0f3a\");\n\tconst pts = [\n\t\t{\n\t\t\tc: \"rgba(255,120,80,0.55)\",\n\t\t\tbx: .25,\n\t\t\tby: .3\n\t\t},\n\t\t{\n\t\t\tc: \"rgba(255,80,160,0.5)\",\n\t\t\tbx: .75,\n\t\t\tby: .28\n\t\t},\n\t\t{\n\t\t\tc: \"rgba(120,90,255,0.5)\",\n\t\t\tbx: .7,\n\t\t\tby: .75\n\t\t},\n\t\t{\n\t\t\tc: \"rgba(80,200,255,0.45)\",\n\t\t\tbx: .28,\n\t\t\tby: .72\n\t\t}\n\t];\n\tctx.globalCompositeOperation = \"lighter\";\n\tfor (let i = 0; i < pts.length; i++) {\n\t\tconst p = pts[i];\n\t\tconst cx = w * (p.bx + .1 * Math.sin(t * .15 * Math.PI + i * 1.3));\n\t\tconst cy = h * (p.by + .1 * Math.cos(t * .13 * Math.PI + i * .9));\n\t\tconst rad = Math.max(w, h) * (.5 + .06 * Math.sin(t * .2 + i));\n\t\tconst g = ctx.createRadialGradient(cx, cy, 0, cx, cy, rad);\n\t\tg.addColorStop(0, p.c);\n\t\tg.addColorStop(1, \"rgba(0,0,0,0)\");\n\t\tctx.fillStyle = g;\n\t\tctx.fillRect(0, 0, w, h);\n\t}\n\tctx.globalCompositeOperation = \"source-over\";\n}\nfunction drawBokeh(ctx, w, h, t, colors) {\n\tlet dotFn;\n\tif (hasColors(colors)) {\n\t\tconst base = colors[0] || BOKEH_DEF[0];\n\t\tconst dots = colors[1] || BOKEH_DEF[1];\n\t\tfillBase(ctx, w, h, base, mixHex(base, dots, .18));\n\t\tdotFn = (alpha) => rgba(dots, alpha);\n\t} else {\n\t\tfillBase(ctx, w, h, \"#0b1226\", \"#152244\");\n\t\tdotFn = (alpha) => `rgba(150,190,255,${alpha})`;\n\t}\n\tconst count = 46;\n\tconst span = h * 1.25;\n\tctx.globalCompositeOperation = \"lighter\";\n\tfor (let i = 0; i < count; i++) {\n\t\tconst speed = .4 + rand(i) * .9;\n\t\tconst size = (.01 + rand(i + 99) * .04) * Math.min(w, h);\n\t\tconst x = (rand(i + 7) + .05 * Math.sin(t * .3 + i)) * w;\n\t\tconst y = h + size - (t * speed * h * .06 + rand(i + 31) * span) % span;\n\t\tconst alpha = .15 + rand(i + 53) * .4;\n\t\tconst g = ctx.createRadialGradient(x, y, 0, x, y, size);\n\t\tg.addColorStop(0, dotFn(alpha));\n\t\tg.addColorStop(1, dotFn(0));\n\t\tctx.fillStyle = g;\n\t\tctx.beginPath();\n\t\tctx.arc(x, y, size, 0, Math.PI * 2);\n\t\tctx.fill();\n\t}\n\tctx.globalCompositeOperation = \"source-over\";\n}\nfunction drawWaves(ctx, w, h, t) {\n\tfillBase(ctx, w, h, \"#04122a\", \"#0a2e4a\");\n\tfor (const l of [\n\t\t{\n\t\t\tc: \"rgba(30,140,200,0.5)\",\n\t\t\tamp: .05,\n\t\t\tbase: .62,\n\t\t\tk: 1.3,\n\t\t\tspd: .5\n\t\t},\n\t\t{\n\t\t\tc: \"rgba(40,190,180,0.5)\",\n\t\t\tamp: .06,\n\t\t\tbase: .72,\n\t\t\tk: 1,\n\t\t\tspd: -.7\n\t\t},\n\t\t{\n\t\t\tc: \"rgba(80,110,230,0.55)\",\n\t\t\tamp: .07,\n\t\t\tbase: .82,\n\t\t\tk: .8,\n\t\t\tspd: .9\n\t\t}\n\t]) {\n\t\tctx.beginPath();\n\t\tctx.moveTo(0, h);\n\t\tconst step = Math.max(6, w / 120);\n\t\tfor (let x = 0; x <= w; x += step) {\n\t\t\tconst phase = x / w * Math.PI * 2 * l.k + t * l.spd;\n\t\t\tconst y = h * l.base + Math.sin(phase) * h * l.amp;\n\t\t\tctx.lineTo(x, y);\n\t\t}\n\t\tctx.lineTo(w, h);\n\t\tctx.closePath();\n\t\tctx.fillStyle = l.c;\n\t\tctx.fill();\n\t}\n}\nconst PAPER_STEP = .17;\nconst PAPER_CYCLE = 8;\nfunction drawPaper(ctx, w, h, t, colors) {\n\tconst custom = hasColors(colors);\n\tconst base = custom ? colors[0] || PAPER_DEF[0] : \"#e8e4da\";\n\tconst accent = custom ? colors[1] || PAPER_DEF[1] : \"#57503f\";\n\tconst seed = Math.floor(Math.max(0, Number(t) || 0) / PAPER_STEP) % PAPER_CYCLE * 977;\n\tconst S = Math.min(w, h) / 360;\n\tfillBase(ctx, w, h, base, mixHex(base, accent, .08));\n\tconst vg = ctx.createRadialGradient(w / 2, h / 2, Math.min(w, h) * .35, w / 2, h / 2, Math.max(w, h) * .75);\n\tvg.addColorStop(0, rgba(accent, 0));\n\tvg.addColorStop(1, rgba(accent, .1));\n\tctx.fillStyle = vg;\n\tctx.fillRect(0, 0, w, h);\n\tfor (let i = 0; i < 6; i++) {\n\t\tconst cx = rand(seed + 11 + i) * w;\n\t\tconst cy = rand(seed + 23 + i) * h;\n\t\tconst r = Math.max(w, h) * (.1 + .16 * rand(seed + 37 + i));\n\t\tconst g = ctx.createRadialGradient(cx, cy, 0, cx, cy, r);\n\t\tg.addColorStop(0, rgba(accent, .055));\n\t\tg.addColorStop(1, rgba(accent, 0));\n\t\tctx.fillStyle = g;\n\t\tctx.fillRect(0, 0, w, h);\n\t}\n\tconst cell = Math.max(24, Math.min(w, h) * .075);\n\tconst jx = (rand(seed + 3) - .5) * 3 * S;\n\tconst jy = (rand(seed + 4) - .5) * 3 * S;\n\tctx.lineWidth = Math.max(1, S * 1.1);\n\tctx.strokeStyle = rgba(accent, .16);\n\tctx.beginPath();\n\tfor (let x = -cell + jx; x <= w + cell; x += cell) {\n\t\tctx.moveTo(x, 0);\n\t\tctx.lineTo(x, h);\n\t}\n\tfor (let y = -cell + jy; y <= h + cell; y += cell) {\n\t\tctx.moveTo(0, y);\n\t\tctx.lineTo(w, y);\n\t}\n\tctx.stroke();\n\tctx.fillStyle = rgba(accent, .5);\n\tfor (let i = 0; i < 42; i++) {\n\t\tconst x = rand(seed + 101 + i) * w;\n\t\tconst y = rand(seed + 211 + i) * h;\n\t\tconst s2 = (.8 + 1.8 * rand(seed + 307 + i)) * S;\n\t\tctx.globalAlpha = .22 + .38 * rand(seed + 401 + i);\n\t\tctx.fillRect(x, y, s2, s2);\n\t}\n\tctx.strokeStyle = rgba(accent, .3);\n\tctx.lineWidth = Math.max(.6, S * .7);\n\tfor (let i = 0; i < 14; i++) {\n\t\tconst x = rand(seed + 503 + i) * w;\n\t\tconst y = rand(seed + 601 + i) * h;\n\t\tconst ang = rand(seed + 701 + i) * Math.PI * 2;\n\t\tconst len = (4 + 6 * rand(seed + 809 + i)) * S;\n\t\tctx.globalAlpha = .15 + .2 * rand(seed + 907 + i);\n\t\tctx.beginPath();\n\t\tctx.moveTo(x, y);\n\t\tctx.lineTo(x + Math.cos(ang) * len, y + Math.sin(ang) * len);\n\t\tctx.stroke();\n\t}\n\tfor (let i = 0; i < 160; i++) {\n\t\tconst x = rand(seed + 1103 + i) * w;\n\t\tconst y = rand(seed + 1301 + i) * h;\n\t\tconst dark = i % 2 === 0;\n\t\tctx.fillStyle = dark ? rgba(accent, 1) : \"#ffffff\";\n\t\tctx.globalAlpha = dark ? .04 + .05 * rand(seed + 1409 + i) : .05 + .07 * rand(seed + 1511 + i);\n\t\tctx.fillRect(x, y, S, S);\n\t}\n\tctx.globalAlpha = 1;\n}\nconst GRID_DEF = [\"#0a1a3f\", \"#3b7dff\"];\nconst BOKEH_DEF = [\"#0b1226\", \"#96beff\"];\nconst PAPER_DEF = [\"#e8e4da\", \"#57503f\"];\nconst ANIMATED_BACKGROUNDS = {\n\tgrid: {\n\t\tlabel: \"Blue Grid\",\n\t\tdraw: drawGrid,\n\t\tcss: \"linear-gradient(180deg, #0a1a3f, #123a8a)\",\n\t\ttunable: [{\n\t\t\tkey: \"base\",\n\t\t\tlabel: \"Background\",\n\t\t\tdefault: GRID_DEF[0]\n\t\t}, {\n\t\t\tkey: \"accent\",\n\t\t\tlabel: \"Grid & glow\",\n\t\t\tdefault: GRID_DEF[1]\n\t\t}]\n\t},\n\taurora: {\n\t\tlabel: \"Aurora\",\n\t\tdraw: drawAurora,\n\t\tcss: \"radial-gradient(circle at 35% 40%, rgba(90,220,200,0.7), rgba(140,90,240,0.5) 45%, #0b1030 80%)\"\n\t},\n\tmesh: {\n\t\tlabel: \"Mesh\",\n\t\tdraw: drawMesh,\n\t\tcss: \"radial-gradient(circle at 30% 30%, rgba(255,120,80,0.7), rgba(120,90,255,0.5) 55%, #2a0f3a 85%)\"\n\t},\n\tbokeh: {\n\t\tlabel: \"Bokeh\",\n\t\tdraw: drawBokeh,\n\t\tcss: \"radial-gradient(circle at 60% 70%, rgba(150,190,255,0.5), #152244 70%)\",\n\t\ttunable: [{\n\t\t\tkey: \"base\",\n\t\t\tlabel: \"Background\",\n\t\t\tdefault: BOKEH_DEF[0]\n\t\t}, {\n\t\t\tkey: \"accent\",\n\t\t\tlabel: \"Dots\",\n\t\t\tdefault: BOKEH_DEF[1]\n\t\t}]\n\t},\n\twaves: {\n\t\tlabel: \"Waves\",\n\t\tdraw: drawWaves,\n\t\tcss: \"linear-gradient(180deg, #0a2e4a 40%, rgba(40,190,180,0.6) 70%, #04122a)\"\n\t},\n\tpaper: {\n\t\tlabel: \"Paper\",\n\t\tdraw: drawPaper,\n\t\tcss: \"linear-gradient(180deg, #e8e4da, #ded9cd)\",\n\t\ttunable: [{\n\t\t\tkey: \"base\",\n\t\t\tlabel: \"Paper\",\n\t\t\tdefault: PAPER_DEF[0]\n\t\t}, {\n\t\t\tkey: \"accent\",\n\t\t\tlabel: \"Grid & flecks\",\n\t\t\tdefault: PAPER_DEF[1]\n\t\t}]\n\t}\n};\n\n//#endregion\n//#region blocks/native/shared/src/imagePanel/collageCanvas.js\nconst BG_PRESETS = [\n\t{\n\t\tkey: \"white\",\n\t\tlabel: \"White\",\n\t\tvalue: \"#ffffff\"\n\t},\n\t{\n\t\tkey: \"black\",\n\t\tlabel: \"Black\",\n\t\tvalue: \"#0a0a0a\"\n\t},\n\t{\n\t\tkey: \"studio\",\n\t\tlabel: \"Studio\",\n\t\tvalue: \"radial|#f4f4f4|#8d8d8d\"\n\t},\n\t{\n\t\tkey: \"spotlight\",\n\t\tlabel: \"Spotlight\",\n\t\tvalue: \"radial|#ffffff|#c9c9c9\"\n\t},\n\t{\n\t\tkey: \"charcoal\",\n\t\tlabel: \"Charcoal\",\n\t\tvalue: \"radial|#3a3a3a|#0c0c0c\"\n\t},\n\t{\n\t\tkey: \"midnight\",\n\t\tlabel: \"Midnight\",\n\t\tvalue: \"radial|#1b2a44|#070b14\"\n\t},\n\t{\n\t\tkey: \"ocean\",\n\t\tlabel: \"Ocean\",\n\t\tvalue: \"linear|135|#1e3a5f|#0a1a2f\"\n\t},\n\t{\n\t\tkey: \"sunset\",\n\t\tlabel: \"Sunset\",\n\t\tvalue: \"linear|135|#f7b267|#c0392b\"\n\t},\n\t...Object.entries(ANIMATED_BACKGROUNDS).map(([key, b]) => ({\n\t\tkey: `anim-${key}`,\n\t\tlabel: b.label,\n\t\tvalue: `anim|${key}`,\n\t\tanimated: true\n\t}))\n];\nconst CANVAS_BIG_SIZE = .42;\nconst CANVAS_BIG_AREA = .22;\nfunction canvasSfxPlan(panel) {\n\tconst els = (panel?.elements || []).slice().sort((a, b) => (a.appearMs || 0) - (b.appearMs || 0));\n\tconst out = [];\n\tlet popIdx = 0;\n\tconst dur = Number(panel?.durationMs) || Infinity;\n\tfor (let i = 0; i < els.length; i++) {\n\t\tconst el = els[i];\n\t\tif (el.sfx === \"none\") continue;\n\t\tif ((el.appearMs || 0) >= dur) continue;\n\t\tif (el.kind === \"text\" && el.anim?.type === \"typewriter\" && Array.isArray(el.wordTimes) && el.wordTimes.length) {\n\t\t\tconst times = el.wordTimes.map(Number).filter((t) => Number.isFinite(t) && t < dur).sort((a, b) => a - b);\n\t\t\tfor (let k = 0; k < times.length; k++) {\n\t\t\t\tconst nextT = k + 1 < times.length ? times[k + 1] : null;\n\t\t\t\tout.push({\n\t\t\t\t\telementId: `${el.id}:k${k}`,\n\t\t\t\t\tatMs: times[k],\n\t\t\t\t\tkind: \"type\",\n\t\t\t\t\tvariant: 0,\n\t\t\t\t\tbeatMs: nextT != null ? Math.max(40, nextT - times[k]) : null,\n\t\t\t\t\tvolume: Number.isFinite(Number(el.sfxVolume)) ? Number(el.sfxVolume) : void 0\n\t\t\t\t});\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\t\tconst big = (el.kind === \"image\" || el.kind === \"video\") && (el.box ? el.box.w * el.box.h >= .22 : (el.size || .28) >= .42);\n\t\tconst kind = el.sfx === \"pop\" || el.sfx === \"swoosh\" ? el.sfx : big ? \"swoosh\" : \"pop\";\n\t\tconst next = els[i + 1];\n\t\tout.push({\n\t\t\telementId: el.id,\n\t\t\tatMs: el.appearMs || 0,\n\t\t\tkind,\n\t\t\tvariant: kind === \"pop\" ? popIdx++ : 0,\n\t\t\tbeatMs: next ? Math.max(50, (next.appearMs || 0) - (el.appearMs || 0)) : null,\n\t\t\tvolume: Number.isFinite(Number(el.sfxVolume)) ? Number(el.sfxVolume) : void 0\n\t\t});\n\t}\n\treturn out;\n}\n\n//#endregion\n//#region blocks/native/shared/src/imagePanel/canvasTemplates.js\nconst T = (id, name, scenario, minImages, slots, textSlots, pSlots, pTextSlots) => ({\n\tid,\n\tname,\n\tscenario,\n\tminImages,\n\tslots,\n\ttextSlots,\n\tpSlots,\n\tpTextSlots\n});\nconst CANVAS_TEMPLATES = [\n\tT(\"hero-headline\", \"Hero + headline\", \"one subject, one line\", 1, [{\n\t\tx: .5,\n\t\ty: .58,\n\t\tw: .5,\n\t\th: .62\n\t}], [{\n\t\trole: \"headline\",\n\t\tx: .5,\n\t\ty: .14,\n\t\tsize: .09,\n\t\tweight: 900\n\t}], [{\n\t\tx: .5,\n\t\ty: .55,\n\t\tw: .78,\n\t\th: .5\n\t}], [{\n\t\trole: \"headline\",\n\t\tx: .5,\n\t\ty: .13,\n\t\tsize: .055,\n\t\tweight: 900\n\t}]),\n\tT(\"hero-supporting\", \"Hero + 2 supporting\", \"main subject with two details\", 3, [\n\t\t{\n\t\t\tx: .34,\n\t\t\ty: .55,\n\t\t\tw: .42,\n\t\t\th: .58\n\t\t},\n\t\t{\n\t\t\tx: .78,\n\t\t\ty: .33,\n\t\t\tw: .28,\n\t\t\th: .32\n\t\t},\n\t\t{\n\t\t\tx: .78,\n\t\t\ty: .73,\n\t\t\tw: .28,\n\t\t\th: .32\n\t\t}\n\t], [{\n\t\trole: \"headline\",\n\t\tx: .34,\n\t\ty: .13,\n\t\tsize: .08,\n\t\tweight: 900\n\t}], [\n\t\t{\n\t\t\tx: .5,\n\t\t\ty: .38,\n\t\t\tw: .78,\n\t\t\th: .32\n\t\t},\n\t\t{\n\t\t\tx: .28,\n\t\t\ty: .72,\n\t\t\tw: .4,\n\t\t\th: .2\n\t\t},\n\t\t{\n\t\t\tx: .72,\n\t\t\ty: .72,\n\t\t\tw: .4,\n\t\t\th: .2\n\t\t}\n\t], [{\n\t\trole: \"headline\",\n\t\tx: .5,\n\t\ty: .12,\n\t\tsize: .05,\n\t\tweight: 900\n\t}]),\n\tT(\"compare-2\", \"Side-by-side compare\", \"A vs B\", 2, [{\n\t\tx: .27,\n\t\ty: .5,\n\t\tw: .38,\n\t\th: .5\n\t}, {\n\t\tx: .73,\n\t\ty: .5,\n\t\tw: .38,\n\t\th: .5\n\t}], [\n\t\t{\n\t\t\trole: \"headline\",\n\t\t\tx: .5,\n\t\t\ty: .12,\n\t\t\tsize: .08,\n\t\t\tweight: 900\n\t\t},\n\t\t{\n\t\t\trole: \"label\",\n\t\t\tx: .27,\n\t\t\ty: .84,\n\t\t\tsize: .05,\n\t\t\tweight: 800\n\t\t},\n\t\t{\n\t\t\trole: \"label\",\n\t\t\tx: .73,\n\t\t\ty: .84,\n\t\t\tsize: .05,\n\t\t\tweight: 800\n\t\t}\n\t], [{\n\t\tx: .5,\n\t\ty: .35,\n\t\tw: .72,\n\t\th: .24\n\t}, {\n\t\tx: .5,\n\t\ty: .72,\n\t\tw: .72,\n\t\th: .24\n\t}], [\n\t\t{\n\t\t\trole: \"headline\",\n\t\t\tx: .5,\n\t\t\ty: .11,\n\t\t\tsize: .05,\n\t\t\tweight: 900\n\t\t},\n\t\t{\n\t\t\trole: \"label\",\n\t\t\tx: .5,\n\t\t\ty: .51,\n\t\t\tsize: .032,\n\t\t\tweight: 800\n\t\t},\n\t\t{\n\t\t\trole: \"label\",\n\t\t\tx: .5,\n\t\t\ty: .88,\n\t\t\tsize: .032,\n\t\t\tweight: 800\n\t\t}\n\t]),\n\tT(\"three-across\", \"Three across\", \"three items\", 3, [\n\t\t{\n\t\t\tx: .2,\n\t\t\ty: .5,\n\t\t\tw: .26,\n\t\t\th: .46\n\t\t},\n\t\t{\n\t\t\tx: .5,\n\t\t\ty: .5,\n\t\t\tw: .26,\n\t\t\th: .46\n\t\t},\n\t\t{\n\t\t\tx: .8,\n\t\t\ty: .5,\n\t\t\tw: .26,\n\t\t\th: .46\n\t\t}\n\t], [{\n\t\trole: \"headline\",\n\t\tx: .5,\n\t\ty: .13,\n\t\tsize: .08,\n\t\tweight: 900\n\t}, {\n\t\trole: \"caption\",\n\t\tx: .5,\n\t\ty: .86,\n\t\tsize: .045,\n\t\tweight: 600\n\t}], [\n\t\t{\n\t\t\tx: .5,\n\t\t\ty: .32,\n\t\t\tw: .64,\n\t\t\th: .2\n\t\t},\n\t\t{\n\t\t\tx: .5,\n\t\t\ty: .57,\n\t\t\tw: .64,\n\t\t\th: .2\n\t\t},\n\t\t{\n\t\t\tx: .5,\n\t\t\ty: .82,\n\t\t\tw: .64,\n\t\t\th: .2\n\t\t}\n\t], [{\n\t\trole: \"headline\",\n\t\tx: .5,\n\t\ty: .1,\n\t\tsize: .05,\n\t\tweight: 900\n\t}, {\n\t\trole: \"caption\",\n\t\tx: .5,\n\t\ty: .96,\n\t\tsize: .028,\n\t\tweight: 600\n\t}]),\n\tT(\"grid-2x2\", \"Grid of four\", \"four items\", 4, [\n\t\t{\n\t\t\tx: .3,\n\t\t\ty: .36,\n\t\t\tw: .32,\n\t\t\th: .34\n\t\t},\n\t\t{\n\t\t\tx: .7,\n\t\t\ty: .36,\n\t\t\tw: .32,\n\t\t\th: .34\n\t\t},\n\t\t{\n\t\t\tx: .3,\n\t\t\ty: .74,\n\t\t\tw: .32,\n\t\t\th: .34\n\t\t},\n\t\t{\n\t\t\tx: .7,\n\t\t\ty: .74,\n\t\t\tw: .32,\n\t\t\th: .34\n\t\t}\n\t], [{\n\t\trole: \"headline\",\n\t\tx: .5,\n\t\ty: .09,\n\t\tsize: .07,\n\t\tweight: 900\n\t}], [\n\t\t{\n\t\t\tx: .28,\n\t\t\ty: .38,\n\t\t\tw: .4,\n\t\t\th: .24\n\t\t},\n\t\t{\n\t\t\tx: .72,\n\t\t\ty: .38,\n\t\t\tw: .4,\n\t\t\th: .24\n\t\t},\n\t\t{\n\t\t\tx: .28,\n\t\t\ty: .68,\n\t\t\tw: .4,\n\t\t\th: .24\n\t\t},\n\t\t{\n\t\t\tx: .72,\n\t\t\ty: .68,\n\t\t\tw: .4,\n\t\t\th: .24\n\t\t}\n\t], [{\n\t\trole: \"headline\",\n\t\tx: .5,\n\t\ty: .12,\n\t\tsize: .05,\n\t\tweight: 900\n\t}]),\n\tT(\"grid-3x3\", \"Many small (3x3)\", \"lots of items\", 6, [\n\t\t.22,\n\t\t.5,\n\t\t.78\n\t].flatMap((x) => [\n\t\t.3,\n\t\t.56,\n\t\t.82\n\t].map((y) => ({\n\t\tx,\n\t\ty,\n\t\tw: .24,\n\t\th: .22\n\t}))), [{\n\t\trole: \"headline\",\n\t\tx: .5,\n\t\ty: .08,\n\t\tsize: .065,\n\t\tweight: 900\n\t}], [\n\t\t.2,\n\t\t.5,\n\t\t.8\n\t].flatMap((x) => [\n\t\t.34,\n\t\t.58,\n\t\t.82\n\t].map((y) => ({\n\t\tx,\n\t\ty,\n\t\tw: .27,\n\t\th: .18\n\t}))), [{\n\t\trole: \"headline\",\n\t\tx: .5,\n\t\ty: .1,\n\t\tsize: .045,\n\t\tweight: 900\n\t}]),\n\tT(\"big-left-stack-right\", \"Big lead + stack\", \"one lead, several follow-ups\", 3, [\n\t\t{\n\t\t\tx: .32,\n\t\t\ty: .54,\n\t\t\tw: .5,\n\t\t\th: .62\n\t\t},\n\t\t{\n\t\t\tx: .79,\n\t\t\ty: .3,\n\t\t\tw: .3,\n\t\t\th: .22\n\t\t},\n\t\t{\n\t\t\tx: .79,\n\t\t\ty: .56,\n\t\t\tw: .3,\n\t\t\th: .22\n\t\t},\n\t\t{\n\t\t\tx: .79,\n\t\t\ty: .82,\n\t\t\tw: .3,\n\t\t\th: .22\n\t\t}\n\t], [{\n\t\trole: \"headline\",\n\t\tx: .32,\n\t\ty: .13,\n\t\tsize: .075,\n\t\tweight: 900\n\t}], [\n\t\t{\n\t\t\tx: .5,\n\t\t\ty: .4,\n\t\t\tw: .84,\n\t\t\th: .34\n\t\t},\n\t\t{\n\t\t\tx: .2,\n\t\t\ty: .74,\n\t\t\tw: .26,\n\t\t\th: .16\n\t\t},\n\t\t{\n\t\t\tx: .5,\n\t\t\ty: .74,\n\t\t\tw: .26,\n\t\t\th: .16\n\t\t},\n\t\t{\n\t\t\tx: .8,\n\t\t\ty: .74,\n\t\t\tw: .26,\n\t\t\th: .16\n\t\t}\n\t], [{\n\t\trole: \"headline\",\n\t\tx: .5,\n\t\ty: .12,\n\t\tsize: .05,\n\t\tweight: 900\n\t}]),\n\tT(\"vertical-stack\", \"Vertical stack\", \"ordered top to bottom\", 2, [\n\t\t{\n\t\t\tx: .55,\n\t\t\ty: .29,\n\t\t\tw: .36,\n\t\t\th: .22\n\t\t},\n\t\t{\n\t\t\tx: .55,\n\t\t\ty: .55,\n\t\t\tw: .36,\n\t\t\th: .22\n\t\t},\n\t\t{\n\t\t\tx: .55,\n\t\t\ty: .81,\n\t\t\tw: .36,\n\t\t\th: .22\n\t\t}\n\t], [{\n\t\trole: \"headline\",\n\t\tx: .55,\n\t\ty: .08,\n\t\tsize: .065,\n\t\tweight: 900\n\t}, {\n\t\trole: \"label\",\n\t\tx: .16,\n\t\ty: .55,\n\t\tsize: .055,\n\t\tweight: 800\n\t}], [\n\t\t{\n\t\t\tx: .5,\n\t\t\ty: .3,\n\t\t\tw: .66,\n\t\t\th: .2\n\t\t},\n\t\t{\n\t\t\tx: .5,\n\t\t\ty: .56,\n\t\t\tw: .66,\n\t\t\th: .2\n\t\t},\n\t\t{\n\t\t\tx: .5,\n\t\t\ty: .82,\n\t\t\tw: .66,\n\t\t\th: .2\n\t\t}\n\t], [{\n\t\trole: \"headline\",\n\t\tx: .5,\n\t\ty: .09,\n\t\tsize: .05,\n\t\tweight: 900\n\t}, {\n\t\trole: \"label\",\n\t\tx: .24,\n\t\ty: .17,\n\t\tsize: .032,\n\t\tweight: 800\n\t}]),\n\tT(\"scatter\", \"Scattered collage\", \"loose, hand-thrown feel\", 3, [\n\t\t{\n\t\t\tx: .26,\n\t\t\ty: .36,\n\t\t\tw: .28,\n\t\t\th: .32,\n\t\t\ttilt: -6\n\t\t},\n\t\t{\n\t\t\tx: .68,\n\t\t\ty: .3,\n\t\t\tw: .26,\n\t\t\th: .3,\n\t\t\ttilt: 4\n\t\t},\n\t\t{\n\t\t\tx: .44,\n\t\t\ty: .66,\n\t\t\tw: .27,\n\t\t\th: .31,\n\t\t\ttilt: 3\n\t\t},\n\t\t{\n\t\t\tx: .8,\n\t\t\ty: .62,\n\t\t\tw: .25,\n\t\t\th: .29,\n\t\t\ttilt: -5\n\t\t},\n\t\t{\n\t\t\tx: .58,\n\t\t\ty: .46,\n\t\t\tw: .24,\n\t\t\th: .28,\n\t\t\ttilt: 2\n\t\t}\n\t], [{\n\t\trole: \"headline\",\n\t\tx: .5,\n\t\ty: .1,\n\t\tsize: .075,\n\t\tweight: 900\n\t}], [\n\t\t{\n\t\t\tx: .32,\n\t\t\ty: .3,\n\t\t\tw: .46,\n\t\t\th: .2,\n\t\t\ttilt: -6\n\t\t},\n\t\t{\n\t\t\tx: .7,\n\t\t\ty: .26,\n\t\t\tw: .42,\n\t\t\th: .18,\n\t\t\ttilt: 4\n\t\t},\n\t\t{\n\t\t\tx: .4,\n\t\t\ty: .56,\n\t\t\tw: .44,\n\t\t\th: .2,\n\t\t\ttilt: 3\n\t\t},\n\t\t{\n\t\t\tx: .74,\n\t\t\ty: .6,\n\t\t\tw: .4,\n\t\t\th: .18,\n\t\t\ttilt: -5\n\t\t},\n\t\t{\n\t\t\tx: .5,\n\t\t\ty: .82,\n\t\t\tw: .44,\n\t\t\th: .19,\n\t\t\ttilt: 2\n\t\t}\n\t], [{\n\t\trole: \"headline\",\n\t\tx: .5,\n\t\ty: .09,\n\t\tsize: .045,\n\t\tweight: 900\n\t}]),\n\tT(\"timeline-row\", \"Row / timeline\", \"steps in order\", 3, [\n\t\t{\n\t\t\tx: .14,\n\t\t\ty: .52,\n\t\t\tw: .2,\n\t\t\th: .38\n\t\t},\n\t\t{\n\t\t\tx: .38,\n\t\t\ty: .52,\n\t\t\tw: .2,\n\t\t\th: .38\n\t\t},\n\t\t{\n\t\t\tx: .62,\n\t\t\ty: .52,\n\t\t\tw: .2,\n\t\t\th: .38\n\t\t},\n\t\t{\n\t\t\tx: .86,\n\t\t\ty: .52,\n\t\t\tw: .2,\n\t\t\th: .38\n\t\t}\n\t], [{\n\t\trole: \"headline\",\n\t\tx: .5,\n\t\ty: .15,\n\t\tsize: .075,\n\t\tweight: 900\n\t}, {\n\t\trole: \"caption\",\n\t\tx: .5,\n\t\ty: .85,\n\t\tsize: .045,\n\t\tweight: 600\n\t}], [\n\t\t{\n\t\t\tx: .35,\n\t\t\ty: .28,\n\t\t\tw: .5,\n\t\t\th: .15\n\t\t},\n\t\t{\n\t\t\tx: .65,\n\t\t\ty: .47,\n\t\t\tw: .5,\n\t\t\th: .15\n\t\t},\n\t\t{\n\t\t\tx: .35,\n\t\t\ty: .66,\n\t\t\tw: .5,\n\t\t\th: .15\n\t\t},\n\t\t{\n\t\t\tx: .65,\n\t\t\ty: .85,\n\t\t\tw: .5,\n\t\t\th: .15\n\t\t}\n\t], [{\n\t\trole: \"headline\",\n\t\tx: .5,\n\t\ty: .12,\n\t\tsize: .05,\n\t\tweight: 900\n\t}]),\n\tT(\"center-satellites\", \"Center + satellites\", \"one core idea, orbiting parts\", 3, [\n\t\t{\n\t\t\tx: .5,\n\t\t\ty: .52,\n\t\t\tw: .34,\n\t\t\th: .42\n\t\t},\n\t\t{\n\t\t\tx: .17,\n\t\t\ty: .3,\n\t\t\tw: .2,\n\t\t\th: .26\n\t\t},\n\t\t{\n\t\t\tx: .83,\n\t\t\ty: .3,\n\t\t\tw: .2,\n\t\t\th: .26\n\t\t},\n\t\t{\n\t\t\tx: .17,\n\t\t\ty: .77,\n\t\t\tw: .2,\n\t\t\th: .26\n\t\t},\n\t\t{\n\t\t\tx: .83,\n\t\t\ty: .77,\n\t\t\tw: .2,\n\t\t\th: .26\n\t\t}\n\t], [{\n\t\trole: \"headline\",\n\t\tx: .5,\n\t\ty: .09,\n\t\tsize: .065,\n\t\tweight: 900\n\t}], [\n\t\t{\n\t\t\tx: .5,\n\t\t\ty: .52,\n\t\t\tw: .56,\n\t\t\th: .28\n\t\t},\n\t\t{\n\t\t\tx: .2,\n\t\t\ty: .28,\n\t\t\tw: .32,\n\t\t\th: .16\n\t\t},\n\t\t{\n\t\t\tx: .8,\n\t\t\ty: .28,\n\t\t\tw: .32,\n\t\t\th: .16\n\t\t},\n\t\t{\n\t\t\tx: .2,\n\t\t\ty: .78,\n\t\t\tw: .32,\n\t\t\th: .16\n\t\t},\n\t\t{\n\t\t\tx: .8,\n\t\t\ty: .78,\n\t\t\tw: .32,\n\t\t\th: .16\n\t\t}\n\t], [{\n\t\trole: \"headline\",\n\t\tx: .5,\n\t\ty: .1,\n\t\tsize: .045,\n\t\tweight: 900\n\t}]),\n\tT(\"corner-big-text\", \"Corner images, big text\", \"statement first, proof beside it\", 2, [\n\t\t{\n\t\t\tx: .72,\n\t\t\ty: .4,\n\t\t\tw: .32,\n\t\t\th: .38\n\t\t},\n\t\t{\n\t\t\tx: .52,\n\t\t\ty: .72,\n\t\t\tw: .28,\n\t\t\th: .34\n\t\t},\n\t\t{\n\t\t\tx: .85,\n\t\t\ty: .76,\n\t\t\tw: .24,\n\t\t\th: .3\n\t\t}\n\t], [{\n\t\trole: \"headline\",\n\t\tx: .26,\n\t\ty: .26,\n\t\tsize: .105,\n\t\tweight: 900\n\t}, {\n\t\trole: \"label\",\n\t\tx: .26,\n\t\ty: .42,\n\t\tsize: .05,\n\t\tweight: 600\n\t}], [\n\t\t{\n\t\t\tx: .36,\n\t\t\ty: .56,\n\t\t\tw: .5,\n\t\t\th: .22\n\t\t},\n\t\t{\n\t\t\tx: .7,\n\t\t\ty: .7,\n\t\t\tw: .44,\n\t\t\th: .2\n\t\t},\n\t\t{\n\t\t\tx: .4,\n\t\t\ty: .84,\n\t\t\tw: .4,\n\t\t\th: .18\n\t\t}\n\t], [{\n\t\trole: \"headline\",\n\t\tx: .5,\n\t\ty: .19,\n\t\tsize: .065,\n\t\tweight: 900\n\t}, {\n\t\trole: \"label\",\n\t\tx: .5,\n\t\ty: .31,\n\t\tsize: .034,\n\t\tweight: 600\n\t}]),\n\tT(\"title-top-row\", \"Title top, images below\", \"title screen with evidence\", 2, [\n\t\t{\n\t\t\tx: .22,\n\t\t\ty: .62,\n\t\t\tw: .28,\n\t\t\th: .44\n\t\t},\n\t\t{\n\t\t\tx: .5,\n\t\t\ty: .62,\n\t\t\tw: .28,\n\t\t\th: .44\n\t\t},\n\t\t{\n\t\t\tx: .78,\n\t\t\ty: .62,\n\t\t\tw: .28,\n\t\t\th: .44\n\t\t}\n\t], [{\n\t\trole: \"headline\",\n\t\tx: .5,\n\t\ty: .17,\n\t\tsize: .1,\n\t\tweight: 900\n\t}], [\n\t\t{\n\t\t\tx: .5,\n\t\t\ty: .4,\n\t\t\tw: .7,\n\t\t\th: .2\n\t\t},\n\t\t{\n\t\t\tx: .5,\n\t\t\ty: .64,\n\t\t\tw: .7,\n\t\t\th: .2\n\t\t},\n\t\t{\n\t\t\tx: .5,\n\t\t\ty: .86,\n\t\t\tw: .7,\n\t\t\th: .16\n\t\t}\n\t], [{\n\t\trole: \"headline\",\n\t\tx: .5,\n\t\ty: .15,\n\t\tsize: .06,\n\t\tweight: 900\n\t}]),\n\tT(\"large-caption\", \"One large + caption\", \"let the image speak\", 1, [{\n\t\tx: .5,\n\t\ty: .47,\n\t\tw: .56,\n\t\th: .6\n\t}], [{\n\t\trole: \"label\",\n\t\tx: .15,\n\t\ty: .1,\n\t\tsize: .045,\n\t\tweight: 800\n\t}, {\n\t\trole: \"caption\",\n\t\tx: .5,\n\t\ty: .85,\n\t\tsize: .055,\n\t\tweight: 600\n\t}], [{\n\t\tx: .5,\n\t\ty: .47,\n\t\tw: .82,\n\t\th: .44\n\t}], [{\n\t\trole: \"label\",\n\t\tx: .24,\n\t\ty: .12,\n\t\tsize: .032,\n\t\tweight: 800\n\t}, {\n\t\trole: \"caption\",\n\t\tx: .5,\n\t\ty: .78,\n\t\tsize: .034,\n\t\tweight: 600\n\t}]),\n\tT(\"staggered-diagonal\", \"Staggered diagonal\", \"progression with motion\", 3, [\n\t\t{\n\t\t\tx: .18,\n\t\t\ty: .26,\n\t\t\tw: .24,\n\t\t\th: .3,\n\t\t\ttilt: -3\n\t\t},\n\t\t{\n\t\t\tx: .42,\n\t\t\ty: .45,\n\t\t\tw: .24,\n\t\t\th: .3,\n\t\t\ttilt: 3\n\t\t},\n\t\t{\n\t\t\tx: .64,\n\t\t\ty: .62,\n\t\t\tw: .24,\n\t\t\th: .3,\n\t\t\ttilt: -3\n\t\t},\n\t\t{\n\t\t\tx: .86,\n\t\t\ty: .79,\n\t\t\tw: .24,\n\t\t\th: .3,\n\t\t\ttilt: 3\n\t\t}\n\t], [{\n\t\trole: \"headline\",\n\t\tx: .74,\n\t\ty: .16,\n\t\tsize: .075,\n\t\tweight: 900\n\t}], [\n\t\t{\n\t\t\tx: .28,\n\t\t\ty: .3,\n\t\t\tw: .42,\n\t\t\th: .18,\n\t\t\ttilt: -3\n\t\t},\n\t\t{\n\t\t\tx: .62,\n\t\t\ty: .46,\n\t\t\tw: .42,\n\t\t\th: .18,\n\t\t\ttilt: 3\n\t\t},\n\t\t{\n\t\t\tx: .36,\n\t\t\ty: .62,\n\t\t\tw: .42,\n\t\t\th: .18,\n\t\t\ttilt: -3\n\t\t},\n\t\t{\n\t\t\tx: .68,\n\t\t\ty: .78,\n\t\t\tw: .42,\n\t\t\th: .18,\n\t\t\ttilt: 3\n\t\t}\n\t], [{\n\t\trole: \"headline\",\n\t\tx: .5,\n\t\ty: .12,\n\t\tsize: .05,\n\t\tweight: 900\n\t}]),\n\tT(\"overlap-stack\", \"Overlapping stack\", \"a deliberate pile\", 2, [\n\t\t{\n\t\t\tx: .42,\n\t\t\ty: .5,\n\t\t\tw: .36,\n\t\t\th: .46,\n\t\t\ttilt: -5\n\t\t},\n\t\t{\n\t\t\tx: .54,\n\t\t\ty: .56,\n\t\t\tw: .36,\n\t\t\th: .46,\n\t\t\ttilt: 3\n\t\t},\n\t\t{\n\t\t\tx: .63,\n\t\t\ty: .46,\n\t\t\tw: .36,\n\t\t\th: .46,\n\t\t\ttilt: -2\n\t\t}\n\t], [{\n\t\trole: \"headline\",\n\t\tx: .5,\n\t\ty: .12,\n\t\tsize: .08,\n\t\tweight: 900\n\t}, {\n\t\trole: \"caption\",\n\t\tx: .5,\n\t\ty: .89,\n\t\tsize: .045,\n\t\tweight: 600\n\t}], [\n\t\t{\n\t\t\tx: .44,\n\t\t\ty: .42,\n\t\t\tw: .58,\n\t\t\th: .26,\n\t\t\ttilt: -5\n\t\t},\n\t\t{\n\t\t\tx: .58,\n\t\t\ty: .53,\n\t\t\tw: .58,\n\t\t\th: .26,\n\t\t\ttilt: 3\n\t\t},\n\t\t{\n\t\t\tx: .46,\n\t\t\ty: .64,\n\t\t\tw: .58,\n\t\t\th: .26,\n\t\t\ttilt: -2\n\t\t}\n\t], [{\n\t\trole: \"headline\",\n\t\tx: .5,\n\t\ty: .12,\n\t\tsize: .05,\n\t\tweight: 900\n\t}, {\n\t\trole: \"caption\",\n\t\tx: .5,\n\t\ty: .86,\n\t\tsize: .032,\n\t\tweight: 600\n\t}]),\n\tT(\"banner-row\", \"Wide banner + small row\", \"one wide scene, details under\", 2, [\n\t\t{\n\t\t\tx: .5,\n\t\t\ty: .36,\n\t\t\tw: .84,\n\t\t\th: .36\n\t\t},\n\t\t{\n\t\t\tx: .25,\n\t\t\ty: .77,\n\t\t\tw: .24,\n\t\t\th: .26\n\t\t},\n\t\t{\n\t\t\tx: .5,\n\t\t\ty: .77,\n\t\t\tw: .24,\n\t\t\th: .26\n\t\t},\n\t\t{\n\t\t\tx: .75,\n\t\t\ty: .77,\n\t\t\tw: .24,\n\t\t\th: .26\n\t\t}\n\t], [{\n\t\trole: \"headline\",\n\t\tx: .5,\n\t\ty: .09,\n\t\tsize: .065,\n\t\tweight: 900\n\t}], [\n\t\t{\n\t\t\tx: .5,\n\t\t\ty: .36,\n\t\t\tw: .86,\n\t\t\th: .26\n\t\t},\n\t\t{\n\t\t\tx: .22,\n\t\t\ty: .66,\n\t\t\tw: .28,\n\t\t\th: .16\n\t\t},\n\t\t{\n\t\t\tx: .5,\n\t\t\ty: .66,\n\t\t\tw: .28,\n\t\t\th: .16\n\t\t},\n\t\t{\n\t\t\tx: .78,\n\t\t\ty: .66,\n\t\t\tw: .28,\n\t\t\th: .16\n\t\t}\n\t], [{\n\t\trole: \"headline\",\n\t\tx: .5,\n\t\ty: .13,\n\t\tsize: .05,\n\t\tweight: 900\n\t}, {\n\t\trole: \"caption\",\n\t\tx: .5,\n\t\ty: .82,\n\t\tsize: .032,\n\t\tweight: 600\n\t}]),\n\tT(\"quadrant-labels\", \"Quadrants with labels\", \"four named things\", 4, [\n\t\t{\n\t\t\tx: .28,\n\t\t\ty: .3,\n\t\t\tw: .3,\n\t\t\th: .3\n\t\t},\n\t\t{\n\t\t\tx: .72,\n\t\t\ty: .3,\n\t\t\tw: .3,\n\t\t\th: .3\n\t\t},\n\t\t{\n\t\t\tx: .28,\n\t\t\ty: .71,\n\t\t\tw: .3,\n\t\t\th: .3\n\t\t},\n\t\t{\n\t\t\tx: .72,\n\t\t\ty: .71,\n\t\t\tw: .3,\n\t\t\th: .3\n\t\t}\n\t], [\n\t\t{\n\t\t\trole: \"headline\",\n\t\t\tx: .5,\n\t\t\ty: .07,\n\t\t\tsize: .06,\n\t\t\tweight: 900\n\t\t},\n\t\t{\n\t\t\trole: \"label\",\n\t\t\tx: .28,\n\t\t\ty: .49,\n\t\t\tsize: .042,\n\t\t\tweight: 800\n\t\t},\n\t\t{\n\t\t\trole: \"label\",\n\t\t\tx: .72,\n\t\t\ty: .49,\n\t\t\tsize: .042,\n\t\t\tweight: 800\n\t\t},\n\t\t{\n\t\t\trole: \"label\",\n\t\t\tx: .28,\n\t\t\ty: .9,\n\t\t\tsize: .042,\n\t\t\tweight: 800\n\t\t},\n\t\t{\n\t\t\trole: \"label\",\n\t\t\tx: .72,\n\t\t\ty: .9,\n\t\t\tsize: .042,\n\t\t\tweight: 800\n\t\t}\n\t], [\n\t\t{\n\t\t\tx: .28,\n\t\t\ty: .32,\n\t\t\tw: .38,\n\t\t\th: .2\n\t\t},\n\t\t{\n\t\t\tx: .72,\n\t\t\ty: .32,\n\t\t\tw: .38,\n\t\t\th: .2\n\t\t},\n\t\t{\n\t\t\tx: .28,\n\t\t\ty: .64,\n\t\t\tw: .38,\n\t\t\th: .2\n\t\t},\n\t\t{\n\t\t\tx: .72,\n\t\t\ty: .64,\n\t\t\tw: .38,\n\t\t\th: .2\n\t\t}\n\t], [\n\t\t{\n\t\t\trole: \"headline\",\n\t\t\tx: .5,\n\t\t\ty: .1,\n\t\t\tsize: .045,\n\t\t\tweight: 900\n\t\t},\n\t\t{\n\t\t\trole: \"label\",\n\t\t\tx: .28,\n\t\t\ty: .45,\n\t\t\tsize: .028,\n\t\t\tweight: 800\n\t\t},\n\t\t{\n\t\t\trole: \"label\",\n\t\t\tx: .72,\n\t\t\ty: .45,\n\t\t\tsize: .028,\n\t\t\tweight: 800\n\t\t},\n\t\t{\n\t\t\trole: \"label\",\n\t\t\tx: .28,\n\t\t\ty: .77,\n\t\t\tsize: .028,\n\t\t\tweight: 800\n\t\t},\n\t\t{\n\t\t\trole: \"label\",\n\t\t\tx: .72,\n\t\t\ty: .77,\n\t\t\tsize: .028,\n\t\t\tweight: 800\n\t\t}\n\t]),\n\tT(\"pyramid-3\", \"Pyramid of three\", \"one above two\", 3, [\n\t\t{\n\t\t\tx: .5,\n\t\t\ty: .32,\n\t\t\tw: .3,\n\t\t\th: .32\n\t\t},\n\t\t{\n\t\t\tx: .32,\n\t\t\ty: .71,\n\t\t\tw: .3,\n\t\t\th: .32\n\t\t},\n\t\t{\n\t\t\tx: .68,\n\t\t\ty: .71,\n\t\t\tw: .3,\n\t\t\th: .32\n\t\t}\n\t], [{\n\t\trole: \"headline\",\n\t\tx: .5,\n\t\ty: .08,\n\t\tsize: .065,\n\t\tweight: 900\n\t}, {\n\t\trole: \"caption\",\n\t\tx: .5,\n\t\ty: .92,\n\t\tsize: .04,\n\t\tweight: 600\n\t}], [\n\t\t{\n\t\t\tx: .5,\n\t\t\ty: .34,\n\t\t\tw: .5,\n\t\t\th: .22\n\t\t},\n\t\t{\n\t\t\tx: .27,\n\t\t\ty: .62,\n\t\t\tw: .42,\n\t\t\th: .18\n\t\t},\n\t\t{\n\t\t\tx: .73,\n\t\t\ty: .62,\n\t\t\tw: .42,\n\t\t\th: .18\n\t\t}\n\t], [{\n\t\trole: \"headline\",\n\t\tx: .5,\n\t\ty: .1,\n\t\tsize: .05,\n\t\tweight: 900\n\t}, {\n\t\trole: \"caption\",\n\t\tx: .5,\n\t\ty: .79,\n\t\tsize: .032,\n\t\tweight: 600\n\t}]),\n\tT(\"mosaic-dense\", \"Dense mosaic\", \"everything at once\", 5, [\n\t\t{\n\t\t\tx: .3,\n\t\t\ty: .4,\n\t\t\tw: .34,\n\t\t\th: .42\n\t\t},\n\t\t{\n\t\t\tx: .62,\n\t\t\ty: .29,\n\t\t\tw: .24,\n\t\t\th: .26\n\t\t},\n\t\t{\n\t\t\tx: .86,\n\t\t\ty: .33,\n\t\t\tw: .2,\n\t\t\th: .28\n\t\t},\n\t\t{\n\t\t\tx: .19,\n\t\t\ty: .78,\n\t\t\tw: .24,\n\t\t\th: .26\n\t\t},\n\t\t{\n\t\t\tx: .47,\n\t\t\ty: .77,\n\t\t\tw: .26,\n\t\t\th: .28\n\t\t},\n\t\t{\n\t\t\tx: .73,\n\t\t\ty: .73,\n\t\t\tw: .22,\n\t\t\th: .24\n\t\t},\n\t\t{\n\t\t\tx: .91,\n\t\t\ty: .76,\n\t\t\tw: .14,\n\t\t\th: .18\n\t\t}\n\t], [{\n\t\trole: \"headline\",\n\t\tx: .5,\n\t\ty: .09,\n\t\tsize: .06,\n\t\tweight: 900\n\t}], [\n\t\t{\n\t\t\tx: .32,\n\t\t\ty: .3,\n\t\t\tw: .5,\n\t\t\th: .2\n\t\t},\n\t\t{\n\t\t\tx: .78,\n\t\t\ty: .26,\n\t\t\tw: .36,\n\t\t\th: .16\n\t\t},\n\t\t{\n\t\t\tx: .24,\n\t\t\ty: .52,\n\t\t\tw: .4,\n\t\t\th: .16\n\t\t},\n\t\t{\n\t\t\tx: .68,\n\t\t\ty: .5,\n\t\t\tw: .44,\n\t\t\th: .18\n\t\t},\n\t\t{\n\t\t\tx: .3,\n\t\t\ty: .74,\n\t\t\tw: .42,\n\t\t\th: .16\n\t\t},\n\t\t{\n\t\t\tx: .74,\n\t\t\ty: .73,\n\t\t\tw: .4,\n\t\t\th: .16\n\t\t},\n\t\t{\n\t\t\tx: .5,\n\t\t\ty: .89,\n\t\t\tw: .5,\n\t\t\th: .1\n\t\t}\n\t], [{\n\t\trole: \"headline\",\n\t\tx: .5,\n\t\ty: .1,\n\t\tsize: .045,\n\t\tweight: 900\n\t}])\n];\nconst byId = new Map(CANVAS_TEMPLATES.map((t) => [t.id, t]));\n\n//#endregion\n//#region blocks/native/shared/src/imagePanel/stripModel.js\nconst ANIM_MODELS = [\n\t{\n\t\tid: \"vidu-q3-turbo\",\n\t\tlabel: \"Vidu Q3 Turbo\",\n\t\tdurations: [\n\t\t\t2,\n\t\t\t3,\n\t\t\t4\n\t\t],\n\t\tminSec: 1,\n\t\tmaxSec: 16,\n\t\tresolution: \"1080p\",\n\t\tresolutions: [\n\t\t\t\"540p\",\n\t\t\t\"720p\",\n\t\t\t\"1080p\"\n\t\t],\n\t\tdefault: true\n\t},\n\t{\n\t\tid: \"wan-2.7\",\n\t\tlabel: \"Wan 2.7\",\n\t\tdurations: [\n\t\t\t2,\n\t\t\t3,\n\t\t\t4\n\t\t],\n\t\tminSec: 2,\n\t\tmaxSec: 15,\n\t\tresolution: \"1080p\",\n\t\tresolutions: [\"720p\", \"1080p\"]\n\t},\n\t{\n\t\tid: \"veo-3.1-lite\",\n\t\tlabel: \"Veo 3.1 Lite\",\n\t\tdurations: [4],\n\t\tdurList: [\n\t\t\t4,\n\t\t\t6,\n\t\t\t8\n\t\t],\n\t\tresolution: \"720p\",\n\t\tresolutions: [\"720p\", \"1080p\"],\n\t\taspects: [\"16:9\", \"9:16\"]\n\t}\n];\nconst ANIM_DEFAULT_MODEL = ANIM_MODELS.find((m) => m.default)?.id || ANIM_MODELS[0].id;\nconst ANIM_FIT_EDGE_SEC = .04;\nfunction sizeForRole(role) {\n\treturn role === \"large\" ? .13 : role === \"small\" ? .04 : .07;\n}\nfunction sceneOf(doc, sceneId) {\n\treturn (doc?.scenes || []).find((s) => s.sceneId === sceneId) || null;\n}\nfunction resolvePanelImage(strip, panel) {\n\tif (panel?.type === \"giphy\") return panel.gif ?? panel.image ?? null;\n\tif (panel?.type === \"zoom\") {\n\t\tif (panel.image) return panel.image;\n\t\tconst zsrc = (strip || []).find((p) => p.panelId === panel.sourcePanelId);\n\t\treturn zsrc ? resolvePanelImage(strip, zsrc) : null;\n\t}\n\tif (panel?.kind !== \"repeat\") return panel?.image ?? null;\n\treturn (strip || []).find((p) => p.panelId === panel.repeatOf)?.image ?? null;\n}\n\n//#endregion\n//#region blocks/native/shared/src/services/exportRender/subscribeAnim.js\nconst POP = .42;\nconst SUBSCRIBE_POP_IN = POP;\n\n//#endregion\n//#region blocks/native/shared/src/editor/effects/fxSounds.js\nconst FX_SOUNDS = {\n\timpact: {\n\t\turl: \"/sounds/fx/impact.wav\",\n\t\tduration: .5,\n\t\tloop: false,\n\t\tlabel: \"Impact\"\n\t},\n\tboom: {\n\t\turl: \"/sounds/fx/boom.wav\",\n\t\tduration: .9,\n\t\tloop: false,\n\t\tlabel: \"Boom\"\n\t},\n\twhoosh: {\n\t\turl: \"/sounds/fx/whoosh.wav\",\n\t\tduration: .8,\n\t\tloop: false,\n\t\tlabel: \"Whoosh\"\n\t},\n\twhoosh_short: {\n\t\turl: \"/sounds/fx/whoosh_short.wav\",\n\t\tduration: .35,\n\t\tloop: false,\n\t\tlabel: \"Whoosh (short)\"\n\t},\n\tglitch: {\n\t\turl: \"/sounds/fx/glitch.wav\",\n\t\tduration: .45,\n\t\tloop: false,\n\t\tlabel: \"Glitch\"\n\t},\n\tkeystroke: {\n\t\turl: \"/sounds/fx/keystroke.wav\",\n\t\tduration: .07,\n\t\tloop: false,\n\t\tlabel: \"Keystroke\"\n\t},\n\ttick: {\n\t\turl: \"/sounds/fx/tick.wav\",\n\t\tduration: .06,\n\t\tloop: false,\n\t\tlabel: \"Tick\"\n\t},\n\tclick: {\n\t\turl: \"/sounds/fx/click.mp3\",\n\t\tduration: .37,\n\t\tloop: false,\n\t\tlabel: \"Click\"\n\t},\n\tcamera: {\n\t\turl: \"/sounds/fx/camera.mp3\",\n\t\tduration: .5,\n\t\tloop: false,\n\t\tlabel: \"Camera shutter\"\n\t},\n\tstinger: {\n\t\turl: \"/sounds/fx/stinger.wav\",\n\t\tduration: 1.2,\n\t\tloop: false,\n\t\tlabel: \"Stinger\"\n\t},\n\triser: {\n\t\turl: \"/sounds/fx/riser.wav\",\n\t\tduration: 1.5,\n\t\tloop: false,\n\t\tlabel: \"Riser\"\n\t},\n\tstrobe_pulse: {\n\t\turl: \"/sounds/fx/strobe_pulse.wav\",\n\t\tduration: .22,\n\t\tloop: false,\n\t\tlabel: \"Strobe pulse\"\n\t},\n\tshimmer: {\n\t\turl: \"/sounds/fx/shimmer.wav\",\n\t\tduration: 1,\n\t\tloop: false,\n\t\tlabel: \"Shimmer\"\n\t},\n\tnegative_hit: {\n\t\turl: \"/sounds/fx/negative_hit.wav\",\n\t\tduration: .35,\n\t\tloop: false,\n\t\tlabel: \"Negative hit\"\n\t},\n\tstatic_loop: {\n\t\turl: \"/sounds/fx/static_loop.wav\",\n\t\tduration: 3,\n\t\tloop: true,\n\t\tlabel: \"Static (loop)\"\n\t},\n\tcrt_hum_loop: {\n\t\turl: \"/sounds/fx/crt_hum_loop.wav\",\n\t\tduration: 3,\n\t\tloop: true,\n\t\tlabel: \"CRT hum (loop)\"\n\t},\n\tvhs_hum_loop: {\n\t\turl: \"/sounds/fx/vhs_hum_loop.wav\",\n\t\tduration: 3,\n\t\tloop: true,\n\t\tlabel: \"VHS hum (loop)\"\n\t},\n\train_loop: {\n\t\turl: \"/sounds/fx/rain_loop.wav\",\n\t\tduration: 4,\n\t\tloop: true,\n\t\tlabel: \"Rain (loop)\"\n\t},\n\twind_loop: {\n\t\turl: \"/sounds/fx/wind_loop.wav\",\n\t\tduration: 4,\n\t\tloop: true,\n\t\tlabel: \"Wind (loop)\"\n\t},\n\thologram_loop: {\n\t\turl: \"/sounds/fx/hologram_loop.wav\",\n\t\tduration: 3,\n\t\tloop: true,\n\t\tlabel: \"Hologram (loop)\"\n\t},\n\tswirl_wind: {\n\t\turl: \"/sounds/fx/swirl_wind.wav\",\n\t\tduration: .9,\n\t\tloop: false,\n\t\tlabel: \"Cyclone\"\n\t},\n\tmorph_warp: {\n\t\turl: \"/sounds/fx/morph_warp.wav\",\n\t\tduration: .7,\n\t\tloop: false,\n\t\tlabel: \"Warp\"\n\t},\n\tmorph_bloom: {\n\t\turl: \"/sounds/fx/morph_bloom.wav\",\n\t\tduration: .8,\n\t\tloop: false,\n\t\tlabel: \"Bloom\"\n\t},\n\tshape_sweep: {\n\t\turl: \"/sounds/fx/shape_sweep.wav\",\n\t\tduration: .45,\n\t\tloop: false,\n\t\tlabel: \"Sweep\"\n\t},\n\tshape_pop: {\n\t\turl: \"/sounds/fx/shape_pop.wav\",\n\t\tduration: .4,\n\t\tloop: false,\n\t\tlabel: \"Pop\"\n\t},\n\twhip_crack: {\n\t\turl: \"/sounds/fx/whip_crack.wav\",\n\t\tduration: .4,\n\t\tloop: false,\n\t\tlabel: \"Whip crack\"\n\t},\n\twhip_zip: {\n\t\turl: \"/sounds/fx/whip_zip.wav\",\n\t\tduration: .35,\n\t\tloop: false,\n\t\tlabel: \"Zip\"\n\t},\n\tpush_slide: {\n\t\turl: \"/sounds/fx/push_slide.wav\",\n\t\tduration: .6,\n\t\tloop: false,\n\t\tlabel: \"Slide\"\n\t},\n\tpush_thump: {\n\t\turl: \"/sounds/fx/push_thump.wav\",\n\t\tduration: .6,\n\t\tloop: false,\n\t\tlabel: \"Slide + thump\"\n\t}\n};\nconst SHAPED_PAIR = [\"shape_sweep\", \"shape_pop\"];\nconst WHIP_PAIR = [\"whip_crack\", \"whip_zip\"];\nconst PUSH_PAIR = [\"push_slide\", \"push_thump\"];\nconst TRANSITION_SOUND_OPTIONS = {\n\tSwirl: [\"whoosh\", \"swirl_wind\"],\n\tMorph: [\"morph_warp\", \"morph_bloom\"],\n\t\"Shape wipe\": SHAPED_PAIR,\n\tIris: SHAPED_PAIR,\n\t\"Ink splat\": SHAPED_PAIR,\n\tSlash: SHAPED_PAIR,\n\tShred: SHAPED_PAIR,\n\t\"Whip pan\": WHIP_PAIR,\n\t\"Whip left\": WHIP_PAIR,\n\t\"Whip right\": WHIP_PAIR,\n\t\"Whip up\": WHIP_PAIR,\n\t\"Whip down\": WHIP_PAIR,\n\t\"Push left\": PUSH_PAIR,\n\t\"Push right\": PUSH_PAIR,\n\t\"Push up\": PUSH_PAIR,\n\t\"Push down\": PUSH_PAIR\n};\nconst DEFAULT_SOUND_FOR_TRANSITION = Object.fromEntries(Object.entries(TRANSITION_SOUND_OPTIONS).map(([type, options]) => [type, options[0]]));\n\n//#endregion\n//#region blocks/native/shared/src/imagePanel/changeSounds.js\nconst INHERENT_SOUND_RULES = [\n\t[\n\t\t/sizzl|frying|fry\\b|saut[eé]/i,\n\t\t\"sizzle\",\n\t\t\"food sizzling in a hot pan\"\n\t],\n\t[\n\t\t/\\bcrack(s|ed|ing)?\\b|shatter|fractur/i,\n\t\t\"crack\",\n\t\t\"a sharp crack, material splitting\"\n\t],\n\t[\n\t\t/explo(de|des|ded|sion)|blast|\\bboom\\b|detonat/i,\n\t\t\"boom\",\n\t\t\"a deep explosion boom\"\n\t],\n\t[\n\t\t/\\bcoins?\\b|jackpot|cash regist|money (rains?|falls?|appears?|drops?)/i,\n\t\t\"coins\",\n\t\t\"coins clinking and dropping\"\n\t],\n\t[\n\t\t/wrong|error|\\bX mark\\b|red x\\b|incorrect|denied|rejected/i,\n\t\t\"error\",\n\t\t\"a short error buzz\"\n\t],\n\t[\n\t\t/\\blightning\\b|thunder/i,\n\t\t\"thunder\",\n\t\t\"a thunder clap\"\n\t],\n\t[\n\t\t/glass break|breaks? glass|window break/i,\n\t\t\"glass\",\n\t\t\"glass breaking\"\n\t],\n\t[\n\t\t/door (slams?|opens?|clos)|slams? (the )?door/i,\n\t\t\"door\",\n\t\t\"a door closing\"\n\t],\n\t[\n\t\t/\\brings?\\b.*(phone|bell|alarm)|(phone|bell|alarm).*\\brings?\\b|alarm (goes off|blar|sound)/i,\n\t\t\"ring\",\n\t\t\"an alarm ringing\"\n\t],\n\t[\n\t\t/knock(s|ing)?\\b/i,\n\t\t\"knock\",\n\t\t\"knocking on a door\"\n\t],\n\t[\n\t\t/pour(s|ing)?\\b|splash|water (hits|falls|spills)|spill/i,\n\t\t\"splash\",\n\t\t\"liquid pouring and splashing\"\n\t],\n\t[\n\t\t/fire (crackl|roars?|burns?)|flames? (crackl|roar)|burning/i,\n\t\t\"fire\",\n\t\t\"a fire crackling\"\n\t],\n\t[\n\t\t/wind (howls?|blows?|whips?)|gust/i,\n\t\t\"wind\",\n\t\t\"a gust of wind\"\n\t],\n\t[\n\t\t/typ(es|ing)\\b|keyboard/i,\n\t\t\"typing\",\n\t\t\"fast keyboard typing\"\n\t],\n\t[\n\t\t/footsteps|(runs?|running|sprint\\w*) (down|through|across|out|off)/i,\n\t\t\"footsteps\",\n\t\t\"quick footsteps\"\n\t],\n\t[\n\t\t/\\bengine\\b|car (starts?|revs?)|revs?\\b/i,\n\t\t\"engine\",\n\t\t\"a car engine revving\"\n\t],\n\t[\n\t\t/applau|clap(s|ping)\\b|cheer/i,\n\t\t\"applause\",\n\t\t\"a short crowd cheer\"\n\t],\n\t[\n\t\t/\\bpops?\\b.*(balloon|bubble)|(balloon|bubble).*\\bpops?\\b|bursts?\\b/i,\n\t\t\"burst\",\n\t\t\"a balloon pop burst\"\n\t],\n\t[\n\t\t/siren/i,\n\t\t\"siren\",\n\t\t\"a distant siren\"\n\t],\n\t[\n\t\t/\\bbeeps?\\b|notification|\\bping\\b/i,\n\t\t\"beep\",\n\t\t\"a short interface beep\"\n\t]\n];\nfunction inherentSoundFor(text) {\n\tconst t = String(text || \"\");\n\tif (!t.trim()) return null;\n\tfor (const [re, label, cue] of INHERENT_SOUND_RULES) if (re.test(t)) return {\n\t\tlabel,\n\t\tcue\n\t};\n\treturn null;\n}\nfunction writingSoundFor(text) {\n\tconst t = String(text || \"\");\n\tif (!t.trim()) return null;\n\tif (/circl\\w+|underlin\\w+|\\barrows?\\b|cross(es|ed)?[ -]?out|strik\\w+[ -]?through|draws? a\\b|hand-?drawn/i.test(t)) return \"stroke\";\n\tif (/handwrit\\w+|scribbl\\w+|\\bwrites?\\b|\\bwritten\\b|\\bjots?\\b|\\bpens?\\b|\\bmarker\\b|\\bchalk\\b|annotat\\w+/i.test(t)) return \"scribble\";\n\treturn null;\n}\nfunction swooshSoundFor(text) {\n\tconst t = String(text || \"\");\n\tif (!t.trim()) return null;\n\tif (/slams? (in|down|onto|into)|crash(es|ing)? (in|down|into)|drops? (in|into|down|onto)|lands? (on|in|with)|falls? into (view|place|frame)|fills? the (frame|screen)|slides? in|swoops? in|barrels? in|bursts? into (view|frame)/i.test(t)) return \"impact\";\n\tif (/\\b(huge|giant|massive|enormous|towering|large|big|full[- ]screen)\\b[^.]*\\b(appears?|arrives?|enters?|emerges?|materializ\\w+|rises?|looms?)\\b/i.test(t)) return \"impact\";\n\treturn null;\n}\nfunction swooshVariantFor(key, count = 3) {\n\tconst s = String(key || \"\");\n\tlet h = 5381;\n\tfor (let i = 0; i < s.length; i++) h = (h << 5) + h + s.charCodeAt(i) >>> 0;\n\treturn h % Math.max(1, count);\n}\nconst POP_BURST_MS = 700;\nconst POP_VOLUME = 55;\nconst POP_TRUNC_FADE_SEC = .012;\nfunction buildPopPlan(clips, doc, { burstMs = 700 } = {}) {\n\tconst strip = doc?.strip || [];\n\tconst byId = new Map(strip.map((p) => [p.panelId, p]));\n\tconst sfxAuthored = !!doc?.meta?.sfxAuthored;\n\tconst visual = (clips || []).filter((c) => (c.trackId || \"video\") === \"video\").slice().sort((a, b) => a.start - b.start);\n\tconst pops = [];\n\tconst cues = [];\n\tconst writes = [];\n\tconst swooshes = [];\n\tconst popsInScene = /* @__PURE__ */ new Map();\n\tlet prevChangeAt = -Infinity;\n\tfor (let i = 1; i < visual.length; i++) {\n\t\tconst clip = visual[i];\n\t\tconst panel = byId.get(clip.panelId);\n\t\tif (!panel) continue;\n\t\tif (panel.kind === \"repeat\" && panel.repeatOf === visual[i - 1].panelId) continue;\n\t\tif (visual[i - 1].source === \"transition\") {\n\t\t\tprevChangeAt = clip.start;\n\t\t\tcontinue;\n\t\t}\n\t\tconst isAccumulation = panel.type === \"panel\" && panel.kind === \"edit\";\n\t\tconst text = panel.type === \"giphy\" ? panel.gifQuery || panel.tone || \"\" : panel.prompt || \"\";\n\t\tconst writing = !isAccumulation || panel.type === \"diagram\" ? null : writingSoundFor(text);\n\t\tconst authoredCue = panel.sfx && String(panel.sfx).trim() ? {\n\t\t\tcue: String(panel.sfx).trim(),\n\t\t\tlabel: \"authored\",\n\t\t\tauthored: true\n\t\t} : null;\n\t\tconst specific = writing || panel.type === \"diagram\" ? null : sfxAuthored ? authoredCue : inherentSoundFor(text);\n\t\tconst t = clip.start;\n\t\tconst inBurst = (t - prevChangeAt) * 1e3 < burstMs;\n\t\tprevChangeAt = t;\n\t\tconst next = visual[i + 1];\n\t\tconst beatSec = next ? Math.max(.05, next.start - t) : Infinity;\n\t\tif (panel.type === \"zoom\") {\n\t\t\tswooshes.push({\n\t\t\t\tpanelId: clip.panelId,\n\t\t\t\tstart: t,\n\t\t\t\tbeatSec,\n\t\t\t\tvariant: swooshVariantFor(clip.panelId)\n\t\t\t});\n\t\t\tcontinue;\n\t\t}\n\t\tif (panel.type === \"canvas\") continue;\n\t\tif (writing) {\n\t\t\twrites.push({\n\t\t\t\tpanelId: clip.panelId,\n\t\t\t\tstart: t,\n\t\t\t\tbeatSec,\n\t\t\t\tkind: writing\n\t\t\t});\n\t\t\tcontinue;\n\t\t}\n\t\tif (specific) {\n\t\t\tcues.push({\n\t\t\t\ttimestamp: t,\n\t\t\t\tprompt: specific.cue,\n\t\t\t\tlabel: specific.label,\n\t\t\t\tpanelId: clip.panelId,\n\t\t\t\tbeatSec,\n\t\t\t\t...specific.authored ? { authored: true } : {}\n\t\t\t});\n\t\t\tcontinue;\n\t\t}\n\t\tif (!isAccumulation) continue;\n\t\tif (swooshSoundFor(text)) {\n\t\t\tswooshes.push({\n\t\t\t\tpanelId: clip.panelId,\n\t\t\t\tstart: t,\n\t\t\t\tbeatSec,\n\t\t\t\tvariant: swooshVariantFor(clip.panelId)\n\t\t\t});\n\t\t\tcontinue;\n\t\t}\n\t\tif (inBurst) continue;\n\t\tconst sceneKey = panel.sceneId || \"\";\n\t\tconst nth = popsInScene.get(sceneKey) || 0;\n\t\tpopsInScene.set(sceneKey, nth + 1);\n\t\tpops.push({\n\t\t\tpanelId: clip.panelId,\n\t\t\tstart: t,\n\t\t\tbeatSec,\n\t\t\tvariant: nth\n\t\t});\n\t}\n\treturn {\n\t\tpops,\n\t\tcues,\n\t\twrites,\n\t\tswooshes\n\t};\n}\nfunction popSetReady(popSet) {\n\treturn Array.isArray(popSet) && popSet.length > 0 && popSet.every((p) => p && p.url && p.license && p.source && p.approvedAt && Number(p.durationSec) > 0);\n}\nfunction popAudioItems(plan, popSet, { volume = 55 } = {}) {\n\tif (!popSetReady(popSet) || !plan?.pops?.length) return [];\n\treturn plan.pops.map((p) => {\n\t\tconst idx = Math.min(Math.max(0, p.variant || 0), popSet.length - 1);\n\t\tconst v = popSet[idx];\n\t\tconst assetSec = Number(v.durationSec) || .3;\n\t\tconst capped = assetSec > p.beatSec;\n\t\tconst duration = capped ? p.beatSec : assetSec;\n\t\treturn {\n\t\t\tid: `pop-${p.panelId}`,\n\t\t\tscoreKey: `pop-${p.panelId}`,\n\t\t\ttrackId: \"audio-sfx\",\n\t\t\tpurpose: \"sfx\",\n\t\t\tname: `Pop · ${v.variant}`,\n\t\t\turl: v.url,\n\t\t\tstart: p.start,\n\t\t\tduration,\n\t\t\tsourceDuration: assetSec,\n\t\t\tvolume,\n\t\t\tpopVariant: idx,\n\t\t\tsource: \"pop\",\n\t\t\t...capped ? { fadeOut: POP_TRUNC_FADE_SEC } : {}\n\t\t};\n\t});\n}\nfunction writingSetReady(writingSet) {\n\treturn Array.isArray(writingSet) && writingSet.length > 0 && writingSet.every((p) => p && p.url && p.license && p.source && p.approvedAt && Number(p.durationSec) > 0);\n}\nfunction writeAudioItems(plan, writingSet, { volume = 55 } = {}) {\n\tif (!writingSetReady(writingSet) || !plan?.writes?.length) return [];\n\treturn plan.writes.map((w) => {\n\t\tconst v = writingSet.find((e) => (e.role || e.variant) === w.kind) || writingSet[0];\n\t\tconst assetSec = Number(v.durationSec) || .5;\n\t\tconst capped = assetSec > w.beatSec;\n\t\tconst duration = capped ? w.beatSec : assetSec;\n\t\treturn {\n\t\t\tid: `write-${w.panelId}`,\n\t\t\tscoreKey: `write-${w.panelId}`,\n\t\t\ttrackId: \"audio-sfx\",\n\t\t\tpurpose: \"sfx\",\n\t\t\tname: v.name || `Write · ${v.variant}`,\n\t\t\turl: v.url,\n\t\t\tstart: w.start,\n\t\t\tduration,\n\t\t\tsourceDuration: assetSec,\n\t\t\tvolume,\n\t\t\tsource: \"write\",\n\t\t\t...capped ? { fadeOut: POP_TRUNC_FADE_SEC } : {}\n\t\t};\n\t});\n}\nfunction swooshSetReady(swooshSet) {\n\treturn Array.isArray(swooshSet) && swooshSet.length > 0 && swooshSet.every((p) => p && p.url && p.license && p.source && p.approvedAt && Number(p.durationSec) > 0);\n}\nfunction swooshAudioItems(plan, swooshSet, { volume = 55 } = {}) {\n\tif (!swooshSetReady(swooshSet) || !plan?.swooshes?.length) return [];\n\treturn plan.swooshes.map((s) => {\n\t\tconst v = swooshSet[s.variant % swooshSet.length];\n\t\tconst assetSec = Number(v.durationSec) || .5;\n\t\tconst capped = assetSec > s.beatSec;\n\t\tconst duration = capped ? s.beatSec : assetSec;\n\t\treturn {\n\t\t\tid: `swoosh-${s.panelId}`,\n\t\t\tscoreKey: `swoosh-${s.panelId}`,\n\t\t\ttrackId: \"audio-sfx\",\n\t\t\tpurpose: \"sfx\",\n\t\t\tname: v.name || `Swoosh · ${v.variant}`,\n\t\t\turl: v.url,\n\t\t\tstart: s.start,\n\t\t\tduration,\n\t\t\tsourceDuration: assetSec,\n\t\t\tvolume,\n\t\t\tswooshVariant: s.variant % swooshSet.length,\n\t\t\tsource: \"swoosh\",\n\t\t\t...capped ? { fadeOut: POP_TRUNC_FADE_SEC } : {}\n\t\t};\n\t});\n}\n\n//#endregion\n//#region blocks/native/shared/src/editor/editorAdds.js\nconst round = (n) => Math.round((Number(n) || 0) * 100) / 100;\nconst TRANSITIONS = [\n\t\"Cut\",\n\t\"Fade\",\n\t\"Cross dissolve\",\n\t\"Shape wipe\",\n\t\"Iris\",\n\t\"Ink splat\",\n\t\"Whip pan\",\n\t\"Slash\",\n\t\"Shred\",\n\t\"Dip to black\",\n\t\"Dip to white\",\n\t\"Push left\",\n\t\"Push right\",\n\t\"Push up\",\n\t\"Push down\",\n\t\"Zoom left\",\n\t\"Zoom right\",\n\t\"Zoom up\",\n\t\"Zoom down\"\n];\nconst EFFECT_PRESETS = [\n\t{\n\t\tname: \"Clean\",\n\t\tlut: \"None\",\n\t\tcolor: defaultColor()\n\t},\n\t{\n\t\tname: \"Filmic\",\n\t\tlut: \"Filmic\",\n\t\tcolor: {\n\t\t\t...defaultColor(),\n\t\t\tcontrast: 12,\n\t\t\tsaturation: -5,\n\t\t\tvignette: 15\n\t\t}\n\t},\n\t{\n\t\tname: \"Warm Dawn\",\n\t\tlut: \"Warm\",\n\t\tcolor: {\n\t\t\t...defaultColor(),\n\t\t\ttemperature: 28,\n\t\t\tbrightness: 5,\n\t\t\tsaturation: 8\n\t\t}\n\t},\n\t{\n\t\tname: \"Cold Night\",\n\t\tlut: \"Cold\",\n\t\tcolor: {\n\t\t\t...defaultColor(),\n\t\t\ttemperature: -34,\n\t\t\tcontrast: 8,\n\t\t\tsaturation: -8\n\t\t}\n\t},\n\t{\n\t\tname: \"Punchy\",\n\t\tlut: \"High Contrast\",\n\t\tcolor: {\n\t\t\t...defaultColor(),\n\t\t\tcontrast: 28,\n\t\t\tsaturation: 18,\n\t\t\tsharpness: 18\n\t\t}\n\t}\n];\nconst LOOKS = [\n\t{\n\t\tid: \"clean\",\n\t\tname: \"Clean\",\n\t\tlut: \"None\",\n\t\tcolor: defaultColor()\n\t},\n\t{\n\t\tid: \"cold_night\",\n\t\tname: \"Cold Night\",\n\t\tlut: \"Cold\",\n\t\tcolor: {\n\t\t\t...defaultColor(),\n\t\t\ttemperature: -34,\n\t\t\tcontrast: 8,\n\t\t\tsaturation: -8\n\t\t}\n\t},\n\t{\n\t\tid: \"warm_dawn\",\n\t\tname: \"Warm Dawn\",\n\t\tlut: \"Warm\",\n\t\tcolor: {\n\t\t\t...defaultColor(),\n\t\t\ttemperature: 28,\n\t\t\tbrightness: 5,\n\t\t\tsaturation: 8\n\t\t}\n\t},\n\t{\n\t\tid: \"desaturated\",\n\t\tname: \"Desaturated\",\n\t\tlut: \"Desaturated\",\n\t\tcolor: {\n\t\t\t...defaultColor(),\n\t\t\tsaturation: -35,\n\t\t\tcontrast: 6\n\t\t}\n\t},\n\t{\n\t\tid: \"punchy\",\n\t\tname: \"Punchy\",\n\t\tlut: \"High Contrast\",\n\t\tcolor: {\n\t\t\t...defaultColor(),\n\t\t\tcontrast: 28,\n\t\t\tsaturation: 18,\n\t\t\tsharpness: 18\n\t\t}\n\t},\n\t{\n\t\tid: \"filmic\",\n\t\tname: \"Filmic\",\n\t\tlut: \"Filmic\",\n\t\tcolor: {\n\t\t\t...defaultColor(),\n\t\t\tcontrast: 12,\n\t\t\tsaturation: -5,\n\t\t\tvignette: 15\n\t\t}\n\t},\n\t{\n\t\tid: \"teal_orange\",\n\t\tname: \"Teal & Orange\",\n\t\tlut: \"Teal and Orange\",\n\t\tcolor: {\n\t\t\t...defaultColor(),\n\t\t\ttemperature: 12,\n\t\t\tcontrast: 14,\n\t\t\tsaturation: 12,\n\t\t\tvignette: 10\n\t\t}\n\t}\n];\nconst twin = (twinKind, twinType) => ({\n\ttwin: twinKind,\n\ttwinType,\n\tnote: twinType === \"overlay\" ? \"Also available as a sustained overlay\" : \"Also available as a one-hit\"\n});\nconst EFFECT_TWINS = {\n\tlight_leak: twin(\"light_leaks\", \"overlay\"),\n\tlight_leaks: twin(\"light_leak\", \"fx\"),\n\tchromatic: twin(\"chromatic_drift\", \"overlay\"),\n\tchromatic_drift: twin(\"chromatic\", \"fx\"),\n\tspeed_lines: twin(\"speed_streaks\", \"overlay\"),\n\tspeed_streaks: twin(\"speed_lines\", \"fx\"),\n\tscanline_hit: twin(\"crt\", \"overlay\"),\n\tcrt: twin(\"scanline_hit\", \"fx\")\n};\nfunction defaultColor() {\n\treturn {\n\t\tbrightness: 0,\n\t\tcontrast: 0,\n\t\tsaturation: 0,\n\t\ttemperature: 0,\n\t\tsharpness: 0,\n\t\tvignette: 0\n\t};\n}\nconst SUBSCRIBE_REVEAL_AT = round(SUBSCRIBE_POP_IN + .05);\nconst FX_SOUND_OPTIONS = Object.entries(FX_SOUNDS);\n\n//#endregion\n//#region blocks/native/shared/src/imagePanel/titleScreens.js\nconst TITLE_TEMPLATES = {\n\tchapterCard: {\n\t\tlabel: \"Chapter card\",\n\t\tfont: {\n\t\t\tfamily: \"Georgia\",\n\t\t\tsize: 64,\n\t\t\tcolor: \"#ffffff\",\n\t\t\tweight: 700\n\t\t},\n\t\tanimation: \"fade\"\n\t},\n\tminimal: {\n\t\tlabel: \"Minimal\",\n\t\tfont: {\n\t\t\tfamily: \"Hanken Grotesk\",\n\t\t\tsize: 44,\n\t\t\tcolor: \"#ffffff\",\n\t\t\tweight: 400\n\t\t},\n\t\tanimation: \"none\"\n\t},\n\tboldPunch: {\n\t\tlabel: \"Bold punch\",\n\t\tfont: {\n\t\t\tfamily: \"Arial\",\n\t\t\tsize: 84,\n\t\t\tcolor: \"#ffffff\",\n\t\t\tweight: 800\n\t\t},\n\t\tanimation: \"rise\"\n\t}\n};\nconst TITLE_TEMPLATE_IDS = Object.keys(TITLE_TEMPLATES);\nconst TITLE_ANIMATIONS = [\n\t\"fade\",\n\t\"rise\",\n\t\"none\"\n];\nconst TITLE_DEFAULT_MS = 1500;\nfunction resolveTitleScreen(titleScreen = {}) {\n\tconst tpl = TITLE_TEMPLATES[titleScreen.template] || TITLE_TEMPLATES.chapterCard;\n\treturn {\n\t\ttemplate: TITLE_TEMPLATES[titleScreen.template] ? titleScreen.template : \"chapterCard\",\n\t\ttext: titleScreen.text || null,\n\t\tfont: {\n\t\t\t...tpl.font,\n\t\t\t...titleScreen.font || {}\n\t\t},\n\t\tanimation: TITLE_ANIMATIONS.includes(titleScreen.animation) ? titleScreen.animation : tpl.animation,\n\t\tdurationMs: Number(titleScreen.durationMs) > 0 ? Number(titleScreen.durationMs) : TITLE_DEFAULT_MS\n\t};\n}\nfunction titleScreenTextItem(entry, scene) {\n\tif (!entry || entry.type !== \"titleScreen\") return null;\n\tconst ts = resolveTitleScreen(scene?.titleScreen || {});\n\treturn {\n\t\tid: `panel-title-${entry.panelId}`,\n\t\ttrackId: \"text\",\n\t\ttype: \"title-card\",\n\t\ttext: ts.text || scene?.title || \"Chapter\",\n\t\tsubtitle: \"\",\n\t\tfont: ts.font.family,\n\t\tsize: ts.font.size,\n\t\tcolor: ts.font.color,\n\t\tbold: Number(ts.font.weight) >= 600,\n\t\tbackground: \"#000000\",\n\t\tbackgroundOpacity: 100,\n\t\tposition: \"center\",\n\t\tanimation: ts.animation,\n\t\tstart: entry.startMs / 1e3,\n\t\tend: (entry.startMs + entry.durationMs) / 1e3,\n\t\tpanelId: entry.panelId\n\t};\n}\n\n//#endregion\n//#region blocks/native/sm.editor/src/services/popSet.js\nconst LICENSE = \"AI-generated via fal.ai (ElevenLabs SFX) — commercial use permitted\";\nconst SOURCE = \"fal:fal-ai/elevenlabs/sound-effects/v2\";\nconst POP_SET = [\n\t{\n\t\tid: \"pop-snappy\",\n\t\tvariant: \"snappy\",\n\t\tname: \"Snappy pop\",\n\t\tcharacter: \"clean, snappy, precise — the first pop of every scene\",\n\t\turl: \"/sfx/pops/pop-snappy.wav\",\n\t\tdurationSec: .092,\n\t\tsource: SOURCE,\n\t\tlicense: LICENSE,\n\t\tgeneratedAt: \"2026-07-20T23:47:40.581Z\",\n\t\tapprovedBy: \"owner\",\n\t\tapprovedAt: \"2026-07-21T00:00:00Z\"\n\t},\n\t{\n\t\tid: \"pop-cheek\",\n\t\tvariant: \"cheek\",\n\t\tname: \"Cheek pop\",\n\t\tcharacter: \"hollow cheek pop, round mid-low — the scene’s second pop\",\n\t\turl: \"/sfx/pops/pop-cheek.wav\",\n\t\tdurationSec: .138,\n\t\tsource: SOURCE,\n\t\tlicense: LICENSE,\n\t\tgeneratedAt: \"2026-07-21T22:39:00Z\",\n\t\tapprovedBy: \"owner\",\n\t\tapprovedAt: \"2026-07-21T22:50:00Z\"\n\t},\n\t{\n\t\tid: \"pop-cheek2\",\n\t\tvariant: \"cheek2\",\n\t\tname: \"Cheek pop 2\",\n\t\tcharacter: \"the second hit of the cheek pop generation — the scene’s third pop\",\n\t\turl: \"/sfx/pops/pop-cheek2.wav\",\n\t\tdurationSec: .15,\n\t\tsource: SOURCE,\n\t\tlicense: LICENSE,\n\t\tgeneratedAt: \"2026-07-21T22:39:00Z\",\n\t\tapprovedBy: \"owner\",\n\t\tapprovedAt: \"2026-07-21T22:50:00Z\"\n\t},\n\t{\n\t\tid: \"pop-bright\",\n\t\tvariant: \"bright\",\n\t\tname: \"Bright pop\",\n\t\tcharacter: \"bright, light, airy — every pop after the third in a scene\",\n\t\turl: \"/sfx/pops/pop-bright.wav\",\n\t\tdurationSec: .148,\n\t\tsource: SOURCE,\n\t\tlicense: LICENSE,\n\t\tgeneratedAt: \"2026-07-20T23:47:43.702Z\",\n\t\tapprovedBy: \"owner\",\n\t\tapprovedAt: \"2026-07-21T00:00:00Z\"\n\t}\n];\nconst WRITING_SET = [{\n\tid: \"write-scribble\",\n\tvariant: \"scribble\",\n\trole: \"scribble\",\n\tname: \"Scribble\",\n\tcharacter: \"fast pen scribble, a short word being written — the main writing sound\",\n\turl: \"/sfx/pops/write-scribble.wav\",\n\tdurationSec: 1.299,\n\tsource: SOURCE,\n\tlicense: LICENSE,\n\tgeneratedAt: \"2026-07-21T00:06:03.352Z\",\n\tapprovedBy: \"owner\",\n\tapprovedAt: \"2026-07-21T00:00:00Z\"\n}, {\n\tid: \"write-pencil\",\n\tvariant: \"pencil\",\n\trole: \"scribble\",\n\tname: \"Pencil write\",\n\tcharacter: \"quick pencil handwriting, light graphite scratch\",\n\turl: \"/sfx/pops/write-pencil.wav\",\n\tdurationSec: 1.467,\n\tsource: SOURCE,\n\tlicense: LICENSE,\n\tgeneratedAt: \"2026-07-21T17:19:13.026Z\",\n\tapprovedBy: \"owner\",\n\tapprovedAt: \"2026-07-21T00:00:00Z\"\n}];\nconst SWOOSH_SET = [{\n\tid: \"swoosh-swish\",\n\tvariant: \"swish\",\n\tname: \"Swoosh\",\n\tcharacter: \"one fast air swish — the weighty-arrival sound\",\n\turl: \"/sfx/pops/swish.wav\",\n\tdurationSec: .247,\n\tsource: SOURCE,\n\tlicense: LICENSE,\n\tgeneratedAt: \"2026-07-21T17:19:16.426Z\",\n\tapprovedBy: \"owner\",\n\tapprovedAt: \"2026-07-21T23:30:00Z\"\n}];\n\n//#endregion\n//#region blocks/native/sm.editor/src/imagePanel/stripToEditor.js\nfunction captionsFromWords(words) {\n\tconst timed = (words || []).filter((w) => w && w.text && Number.isFinite(Number(w.startMs)) && Number.isFinite(Number(w.endMs))).map((w) => ({\n\t\ttext: String(w.text),\n\t\tstart: Number(w.startMs) / 1e3,\n\t\tend: Number(w.endMs) / 1e3\n\t}));\n\tif (!timed.length) return [];\n\tconst MAX_WORDS = 6, MAX_CHARS = 36, GAP = .45;\n\tconst lines = [];\n\tlet cur = [];\n\tconst flush = () => {\n\t\tif (cur.length) {\n\t\t\tlines.push(cur);\n\t\t\tcur = [];\n\t\t}\n\t};\n\tfor (let i = 0; i < timed.length; i++) {\n\t\tconst w = timed[i];\n\t\tcur.push(w);\n\t\tconst joined = cur.map((x) => x.text).join(\" \");\n\t\tconst next = timed[i + 1];\n\t\tconst gap = next ? next.start - w.end : 0;\n\t\tif (cur.length >= MAX_WORDS || joined.length >= MAX_CHARS || /[.!?…]\"?$/.test(w.text) || next && gap > GAP) flush();\n\t}\n\tflush();\n\treturn lines.map((line, idx) => {\n\t\tconst start = line[0].start;\n\t\tconst end = Math.max(line[line.length - 1].end, start + .4);\n\t\treturn {\n\t\t\tid: `panel-caption-${idx}`,\n\t\t\ttrackId: \"captions\",\n\t\t\ttext: line.map((w) => w.text).join(\" \").replace(/\\s+([,.!?…])/g, \"$1\"),\n\t\t\twords: line.map((w) => ({\n\t\t\t\ttext: w.text,\n\t\t\t\tstart: w.start,\n\t\t\t\tend: Math.min(w.end, end)\n\t\t\t})),\n\t\t\thighlightColor: \"#ffd400\",\n\t\t\tanimation: \"none\",\n\t\t\tfont: \"Hanken Grotesk\",\n\t\t\tsize: 24,\n\t\t\tcolor: \"#ffffff\",\n\t\t\tbackground: \"none\",\n\t\t\tbackgroundOpacity: 45,\n\t\t\tbackgroundPadding: 10,\n\t\t\tbackgroundRadius: 6,\n\t\t\tposition: \"bottom center\",\n\t\t\tstart,\n\t\t\tend\n\t\t};\n\t});\n}\nconst isOverlayGif = (p) => p.type === \"giphy\" && p.mode === \"overlay\";\nconst GIF_HOLD_SEC = .8;\nconst GIF_MIN_NEIGHBOR_SEC = .35;\nfunction stripToEditorState(doc) {\n\tif (!doc?.strip?.length) return null;\n\tconst panels = doc.strip.filter((p) => p.type !== \"titleScreen\");\n\tconst clips = panels.map((p, i) => {\n\t\tif (isOverlayGif(p)) return null;\n\t\tconst isLast = i === panels.length - 1;\n\t\tconst duration = Math.max(.05, p.durationMs / 1e3);\n\t\tconst nextHandoff = panels[i + 1]?.type === \"canvas\" ? panels[i + 1]?.handoff : null;\n\t\tconst HANDOFF_PUSH = {\n\t\t\t\"swipe-up\": \"Push up\",\n\t\t\t\"swipe-down\": \"Push down\",\n\t\t\t\"swipe-left\": \"Push left\",\n\t\t\t\"swipe-right\": \"Push right\"\n\t\t};\n\t\tconst nextT = !isLast ? panels[i + 1] : null;\n\t\tconst nextName = nextT?.transitionIn;\n\t\tconst namedDur = Number(nextT?.transitionMs) > 0 ? Number(nextT.transitionMs) / 1e3 : .5;\n\t\tconst named = nextName && nextName !== \"cut\" && nextName !== \"Cut\" && TRANSITIONS.includes(nextName) ? {\n\t\t\ttype: nextName,\n\t\t\tduration: namedDur\n\t\t} : nextName === \"fade\" ? {\n\t\t\ttype: \"Fade\",\n\t\t\tduration: .25\n\t\t} : null;\n\t\tconst transition = !isLast && nextHandoff && HANDOFF_PUSH[nextHandoff.exit] ? {\n\t\t\ttype: HANDOFF_PUSH[nextHandoff.exit],\n\t\t\tduration: .5,\n\t\t\tsoundOn: true\n\t\t} : named;\n\t\tif (p.type === \"giphy\") return {\n\t\t\tid: `panel-${p.panelId}`,\n\t\t\tkind: \"image\",\n\t\t\turl: resolvePanelImage(doc.strip, p),\n\t\t\ttrackId: \"video\",\n\t\t\tstart: p.startMs / 1e3,\n\t\t\tduration,\n\t\t\tsourceDuration: duration,\n\t\t\ttrimStart: 0,\n\t\t\ttitle: `${p.panelId} · GIF`,\n\t\t\tpanelId: p.panelId,\n\t\t\tsource: \"giphy\",\n\t\t\topacity: 1,\n\t\t\t...transition ? { transition } : {}\n\t\t};\n\t\tif (p.type === \"canvas\") return {\n\t\t\tid: `panel-${p.panelId}`,\n\t\t\tkind: \"collage\",\n\t\t\turl: null,\n\t\t\tcollage: {\n\t\t\t\tbackground: p.background || \"#ffffff\",\n\t\t\t\telements: p.elements || [],\n\t\t\t\tdurationMs: p.durationMs,\n\t\t\t\taspect: doc.meta?.aspect || \"16:9\",\n\t\t\t\t...p.handoff ? { handoff: p.handoff } : {}\n\t\t\t},\n\t\t\ttrackId: \"video\",\n\t\t\tstart: p.startMs / 1e3,\n\t\t\tduration,\n\t\t\tsourceDuration: duration,\n\t\t\ttrimStart: 0,\n\t\t\ttitle: `${p.panelId} · collage canvas`,\n\t\t\tpanelId: p.panelId,\n\t\t\tsource: \"canvas\",\n\t\t\topacity: 1,\n\t\t\t...transition ? { transition } : {}\n\t\t};\n\t\tif (p.type === \"zoom\") {\n\t\t\tconst zsrc = doc.strip.find((x) => x.panelId === p.sourcePanelId);\n\t\t\tconst z = p.zoom || {\n\t\t\t\tfx: 50,\n\t\t\t\tfy: 50,\n\t\t\t\tscale: 1.8\n\t\t\t};\n\t\t\treturn {\n\t\t\t\tid: `panel-${p.panelId}`,\n\t\t\t\tkind: \"image\",\n\t\t\t\turl: zsrc ? resolvePanelImage(doc.strip, zsrc) : resolvePanelImage(doc.strip, p),\n\t\t\t\ttrackId: \"video\",\n\t\t\t\tstart: p.startMs / 1e3,\n\t\t\t\tduration,\n\t\t\t\tsourceDuration: duration,\n\t\t\t\ttrimStart: 0,\n\t\t\t\tmotion: {\n\t\t\t\t\ttype: \"zoom\",\n\t\t\t\t\tzoomDirection: \"in\",\n\t\t\t\t\tzoomAmount: z.scale,\n\t\t\t\t\tzoomFocalX: z.fx,\n\t\t\t\t\tzoomFocalY: z.fy,\n\t\t\t\t\tintensity: 100,\n\t\t\t\t\trange: [0, 100],\n\t\t\t\t\teasing: \"ease-in-out\"\n\t\t\t\t},\n\t\t\t\ttitle: `${p.panelId} · zoom into ${p.sourcePanelId}`,\n\t\t\t\tpanelId: p.panelId,\n\t\t\t\tsource: \"zoom\",\n\t\t\t\topacity: 1,\n\t\t\t\t...transition ? { transition } : {}\n\t\t\t};\n\t\t}\n\t\treturn {\n\t\t\tid: `panel-${p.panelId}`,\n\t\t\tkind: \"image\",\n\t\t\turl: resolvePanelImage(doc.strip, p),\n\t\t\ttrackId: \"video\",\n\t\t\tstart: p.startMs / 1e3,\n\t\t\tduration,\n\t\t\tsourceDuration: duration,\n\t\t\ttrimStart: 0,\n\t\t\ttitle: p.type === \"diagram\" ? `${p.panelId} · diagram` : `${p.panelId} · ${p.lineageId}${p.kind === \"repeat\" ? ` (repeat of ${p.repeatOf})` : \"\"}`,\n\t\t\tpanelId: p.panelId,\n\t\t\topacity: 1,\n\t\t\t...transition ? { transition } : {}\n\t\t};\n\t}).filter(Boolean);\n\tif (clips.length) {\n\t\tconst first = clips.reduce((a, b) => (b.start || 0) < (a.start || 0) ? b : a, clips[0]);\n\t\tconst lead = first.start || 0;\n\t\tif (lead > 0) {\n\t\t\tfirst.start = 0;\n\t\t\tfirst.duration += lead;\n\t\t\tfirst.sourceDuration = first.duration;\n\t\t}\n\t}\n\tfor (let i = 0; i < clips.length; i++) {\n\t\tconst c = clips[i];\n\t\tif (c.source !== \"giphy\") continue;\n\t\tconst next = clips[i + 1];\n\t\tif (!next) {\n\t\t\tc.duration += GIF_HOLD_SEC;\n\t\t\tc.sourceDuration = c.duration;\n\t\t\tcontinue;\n\t\t}\n\t\tconst borrow = Math.abs(next.start - (c.start + c.duration)) < 1e-4 ? Math.min(GIF_HOLD_SEC, Math.max(0, next.duration - GIF_MIN_NEIGHBOR_SEC)) : 0;\n\t\tif (borrow <= 0) continue;\n\t\tc.duration += borrow;\n\t\tc.sourceDuration = c.duration;\n\t\tnext.start += borrow;\n\t\tnext.duration -= borrow;\n\t\tnext.sourceDuration = next.duration;\n\t}\n\t{\n\t\tconst ANIM_MIN_NEIGHBOR_SEC = .35;\n\t\tconst byPanel = new Map(doc.strip.map((p) => [p.panelId, p]));\n\t\tfor (let i = 0; i < clips.length - 1; i++) {\n\t\t\tconst a = clips[i];\n\t\t\tconst b = clips[i + 1];\n\t\t\tconst an = byPanel.get(a.panelId)?.animateNext;\n\t\t\tif (!an?.video) continue;\n\t\t\tif (a.source === \"giphy\" || b.source === \"giphy\") continue;\n\t\t\tif (Math.abs(b.start - (a.start + a.duration)) > 1e-4) continue;\n\t\t\tlet aTake;\n\t\t\tlet bTake;\n\t\t\tif (an.fit === true) {\n\t\t\t\taTake = Math.max(0, a.duration - ANIM_FIT_EDGE_SEC);\n\t\t\t\tbTake = Math.max(0, b.duration - ANIM_FIT_EDGE_SEC);\n\t\t\t} else {\n\t\t\t\tconst want = Math.max(.5, Math.min(16, Number(an.durationSec) || 3));\n\t\t\t\taTake = Math.min(want / 2, Math.max(0, a.duration - ANIM_MIN_NEIGHBOR_SEC));\n\t\t\t\tbTake = Math.min(want / 2, Math.max(0, b.duration - ANIM_MIN_NEIGHBOR_SEC));\n\t\t\t}\n\t\t\tconst animDur = aTake + bTake;\n\t\t\tif (animDur < .4) continue;\n\t\t\tconst gen = Number(an.genSeconds) || 4;\n\t\t\ta.duration -= aTake;\n\t\t\ta.sourceDuration = a.duration;\n\t\t\tb.start += bTake;\n\t\t\tb.duration -= bTake;\n\t\t\tb.sourceDuration = b.duration;\n\t\t\tclips.splice(i + 1, 0, {\n\t\t\t\tid: `anim-${a.panelId}`,\n\t\t\t\tkind: \"video\",\n\t\t\t\turl: an.video,\n\t\t\t\ttrackId: \"video\",\n\t\t\t\tstart: a.start + a.duration,\n\t\t\t\tduration: animDur,\n\t\t\t\tsourceDuration: gen,\n\t\t\t\ttrimStart: 0,\n\t\t\t\tspeed: Math.max(.05, gen / animDur),\n\t\t\t\tdurationLocked: true,\n\t\t\t\tclipMuted: true,\n\t\t\t\ttitle: `${a.panelId} → ${b.panelId} · animated`,\n\t\t\t\tpanelId: `anim-${a.panelId}`,\n\t\t\t\tsource: \"transition\",\n\t\t\t\topacity: 1\n\t\t\t});\n\t\t\ti++;\n\t\t}\n\t}\n\tconst titleItems = doc.strip.filter((p) => p.type === \"titleScreen\").map((p) => titleScreenTextItem(p, sceneOf(doc, p.sceneId))).filter(Boolean);\n\tconst dgScenes = new Set((doc.scenes || []).filter((s) => s.renderer === \"diagram\").map((s) => s.sceneId));\n\tconst _words = doc.audio?.words || [];\n\tconst _leadS = 75 / 1e3;\n\tconst _wordSec = (idx) => {\n\t\tconst w = _words[Math.round(Number(idx))];\n\t\tif (!w) return null;\n\t\tconst ms = Number.isFinite(Number(w.startMs)) ? Number(w.startMs) : Number.isFinite(Number(w.start)) ? Number(w.start) * 1e3 : null;\n\t\treturn ms == null ? null : ms / 1e3;\n\t};\n\tconst overlayItems = doc.strip.filter((p) => p.type === \"panel\" && !dgScenes.has(p.sceneId) && p.textOverlays?.length).flatMap((p) => {\n\t\tconst pStart = p.startMs / 1e3;\n\t\tconst pEnd = (p.startMs + p.durationMs) / 1e3;\n\t\treturn p.textOverlays.filter((o) => o.pos).map((o, i) => {\n\t\t\tconst at = o.atWord != null ? _wordSec(o.atWord) : null;\n\t\t\tconst start = at != null ? Math.min(Math.max(pStart, at - _leadS), Math.max(pStart, pEnd - .2)) : pStart;\n\t\t\treturn {\n\t\t\t\tid: `panel-text-${p.panelId}-${i}`,\n\t\t\t\ttrackId: \"text\",\n\t\t\t\ttype: \"label\",\n\t\t\t\ttext: o.text,\n\t\t\t\tfont: \"Hanken Grotesk\",\n\t\t\t\tsize: Math.round((Number(o.size) || (o.role ? sizeForRole(o.role) : .05)) * 1080),\n\t\t\t\tcolor: o.color || \"#ffffff\",\n\t\t\t\tbold: true,\n\t\t\t\tbackground: \"transparent\",\n\t\t\t\tbackgroundOpacity: 0,\n\t\t\t\tposition: \"custom\",\n\t\t\t\tx: Math.round((Number(o.pos.x) || .5) * 100),\n\t\t\t\ty: Math.round((Number(o.pos.y) || .5) * 100),\n\t\t\t\t...o.arrow?.to && Number.isFinite(Number(o.arrow.to.x)) && Number.isFinite(Number(o.arrow.to.y)) ? { arrow: { to: {\n\t\t\t\t\tx: Number(o.arrow.to.x),\n\t\t\t\t\ty: Number(o.arrow.to.y)\n\t\t\t\t} } } : {},\n\t\t\t\t...o.role ? { role: o.role } : {},\n\t\t\t\tstart,\n\t\t\t\tend: pEnd,\n\t\t\t\tpanelId: p.panelId\n\t\t\t};\n\t\t});\n\t});\n\tconst textOverlays = [...titleItems, ...overlayItems];\n\tconst gifStickerFrom = (panelId, url, startMs, durationMs, box) => ({\n\t\tid: `gif-${panelId}`,\n\t\ttrackId: \"overlay\",\n\t\tshape: \"gif\",\n\t\turl,\n\t\ttitle: \"GIF\",\n\t\tw: 0,\n\t\th: 0,\n\t\tsource: \"giphy\",\n\t\tretained: true,\n\t\tpanelId,\n\t\tstart: startMs / 1e3,\n\t\tend: (startMs + durationMs) / 1e3 + GIF_HOLD_SEC,\n\t\tx: box && Number.isFinite(Number(box.x)) ? Math.round(Number(box.x) * 100) : 50,\n\t\ty: box && Number.isFinite(Number(box.y)) ? Math.round(Number(box.y) * 100) : 50,\n\t\tscale: box && Number.isFinite(Number(box.scale)) ? Number(box.scale) : 1,\n\t\trotation: 0,\n\t\topacity: 1\n\t});\n\tconst gifOverlayItems = [...doc.strip.filter((p) => isOverlayGif(p) && String(p.gif || \"\").trim()).map((p) => gifStickerFrom(p.panelId, p.gif, p.startMs, p.durationMs)), ...doc.strip.filter((p) => p.type === \"panel\" && !dgScenes.has(p.sceneId) && p.overlayLayer && typeof p.overlayLayer === \"object\" && String(p.overlayLayer.gifUrl || \"\").trim()).map((p) => gifStickerFrom(p.panelId, p.overlayLayer.gifUrl, p.startMs, p.durationMs, p.overlayLayer.box))];\n\tconst audioItems = doc.audio?.voPath ? [{\n\t\tid: \"panel-voiceover\",\n\t\ttrackId: \"audio-voiceover\",\n\t\tname: \"Voiceover\",\n\t\turl: doc.audio.voPath,\n\t\tstart: 0,\n\t\tduration: Math.max(...doc.strip.map((p) => (p.startMs + p.durationMs) / 1e3)),\n\t\tvolume: 100\n\t}] : [];\n\tif (doc.meta?.autoPops !== false) {\n\t\tconst plan = buildPopPlan(clips, doc);\n\t\taudioItems.push(...popAudioItems(plan, POP_SET));\n\t\taudioItems.push(...writeAudioItems(plan, WRITING_SET));\n\t\tconst panelStartSec = new Map(doc.strip.map((x) => [x.panelId, (x.startMs || 0) / 1e3]));\n\t\tconst labelWrites = overlayItems.filter((o) => Number(o.start) > (panelStartSec.get(o.panelId) || 0) + .05).map((o) => ({\n\t\t\tpanelId: o.id,\n\t\t\tkind: \"scribble\",\n\t\t\tstart: Number(o.start),\n\t\t\tbeatSec: Math.max(.2, Number(o.end) - Number(o.start) || .2)\n\t\t}));\n\t\taudioItems.push(...writeAudioItems({ writes: labelWrites }, WRITING_SET));\n\t\taudioItems.push(...swooshAudioItems(plan, SWOOSH_SET));\n\t\tfor (const p of doc.strip) {\n\t\t\tif (p.type !== \"canvas\") continue;\n\t\t\tconst clip = clips.find((c) => c.panelId === p.panelId);\n\t\t\tif (!clip) continue;\n\t\t\tfor (const el of p.elements || []) {\n\t\t\t\tif (el.kind !== \"video\" || el.muted !== false || !el.src) continue;\n\t\t\t\tconst inSec = Math.min(el.appearMs || 0, p.durationMs) / 1e3;\n\t\t\t\tconst outSec = Math.min(el.leaveMs != null ? el.leaveMs : p.durationMs, p.durationMs) / 1e3;\n\t\t\t\tif (outSec - inSec < .05) continue;\n\t\t\t\taudioItems.push({\n\t\t\t\t\tid: `cnvv-${p.panelId}-${el.id}`,\n\t\t\t\t\tscoreKey: `cnvv-${p.panelId}-${el.id}`,\n\t\t\t\t\ttrackId: \"audio-sfx\",\n\t\t\t\t\tpurpose: \"sfx\",\n\t\t\t\t\tname: `Video audio · ${String(el.query || el.id).slice(0, 20)}`,\n\t\t\t\t\turl: el.src,\n\t\t\t\t\tstart: clip.start + inSec,\n\t\t\t\t\tduration: Math.max(.1, outSec - inSec),\n\t\t\t\t\tsourceOffset: Math.max(0, Number(el.trimStartSec) || 0),\n\t\t\t\t\trate: Number(el.speed) > 0 ? Number(el.speed) : 1,\n\t\t\t\t\tloop: el.loop !== false,\n\t\t\t\t\tvolume: 80,\n\t\t\t\t\tsource: \"canvas-video\"\n\t\t\t\t});\n\t\t\t}\n\t\t\tfor (const s of canvasSfxPlan(p)) {\n\t\t\t\tif (s.kind === \"type\") {\n\t\t\t\t\tconst assetSec = Number(FX_SOUNDS.keystroke.duration) || .07;\n\t\t\t\t\taudioItems.push({\n\t\t\t\t\t\tid: `cnv-${p.panelId}-${s.elementId}`,\n\t\t\t\t\t\tscoreKey: `cnv-${p.panelId}-${s.elementId}`,\n\t\t\t\t\t\ttrackId: \"audio-sfx\",\n\t\t\t\t\t\tpurpose: \"sfx\",\n\t\t\t\t\t\tname: \"Keystroke\",\n\t\t\t\t\t\turl: FX_SOUNDS.keystroke.url,\n\t\t\t\t\t\tstart: clip.start + s.atMs / 1e3,\n\t\t\t\t\t\tduration: assetSec,\n\t\t\t\t\t\tsourceDuration: assetSec,\n\t\t\t\t\t\tvolume: s.volume ?? 55,\n\t\t\t\t\t\tsource: \"fx\"\n\t\t\t\t\t});\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tconst set = s.kind === \"swoosh\" ? SWOOSH_SET : POP_SET;\n\t\t\t\tif (!(s.kind === \"swoosh\" ? swooshSetReady(SWOOSH_SET) : popSetReady(POP_SET))) continue;\n\t\t\t\tconst v = set[Math.min(Math.max(0, s.variant || 0), set.length - 1)];\n\t\t\t\tconst assetSec = Number(v.durationSec) || .3;\n\t\t\t\tconst beatSec = s.beatMs != null ? s.beatMs / 1e3 : Infinity;\n\t\t\t\tconst capped = assetSec > beatSec;\n\t\t\t\taudioItems.push({\n\t\t\t\t\tid: `cnv-${p.panelId}-${s.elementId}`,\n\t\t\t\t\tscoreKey: `cnv-${p.panelId}-${s.elementId}`,\n\t\t\t\t\ttrackId: \"audio-sfx\",\n\t\t\t\t\tpurpose: \"sfx\",\n\t\t\t\t\tname: s.kind === \"swoosh\" ? v.name || \"Swoosh\" : `Pop · ${v.variant}`,\n\t\t\t\t\turl: v.url,\n\t\t\t\t\tstart: clip.start + s.atMs / 1e3,\n\t\t\t\t\tduration: capped ? beatSec : assetSec,\n\t\t\t\t\tsourceDuration: assetSec,\n\t\t\t\t\tvolume: s.volume ?? 55,\n\t\t\t\t\tsource: s.kind === \"swoosh\" ? \"swoosh\" : \"pop\",\n\t\t\t\t\t...s.kind === \"pop\" ? { popVariant: Math.min(Math.max(0, s.variant || 0), set.length - 1) } : { swooshVariant: 0 },\n\t\t\t\t\t...capped ? { fadeOut: .012 } : {}\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}\n\tconst captions = captionsFromWords(doc.audio?.words);\n\tconst tracks = [\n\t\t{\n\t\t\tid: \"video\",\n\t\t\tlabel: \"Media\",\n\t\t\ttype: \"visual\"\n\t\t},\n\t\t...gifOverlayItems.length ? [{\n\t\t\tid: \"overlay\",\n\t\t\tlabel: \"Overlay\",\n\t\t\ttype: \"visual\"\n\t\t}] : [],\n\t\t{\n\t\t\tid: \"text\",\n\t\t\tlabel: \"Text\",\n\t\t\ttype: \"text\"\n\t\t},\n\t\t{\n\t\t\tid: \"captions\",\n\t\t\tlabel: \"Captions\",\n\t\t\ttype: \"caption\"\n\t\t},\n\t\t{\n\t\t\tid: \"audio-voiceover\",\n\t\t\tlabel: \"Voiceover\",\n\t\t\ttype: \"audio\"\n\t\t},\n\t\t{\n\t\t\tid: \"audio-sfx\",\n\t\t\tlabel: \"Sound Effects\",\n\t\t\ttype: \"audio\"\n\t\t}\n\t];\n\tconst transcript = (doc.audio?.words || []).map((w) => w.text).join(\" \").trim();\n\treturn {\n\t\ttracks,\n\t\tclips,\n\t\t...textOverlays.length ? { textOverlays } : {},\n\t\t...gifOverlayItems.length ? { stickers: gifOverlayItems } : {},\n\t\t...captions.length ? { captions } : {},\n\t\taudioItems,\n\t\t...transcript ? { transcript } : {},\n\t\taspect: doc.meta?.aspect || \"16:9\"\n\t};\n}\n\n//#endregion\n//#region packages/block-sdk/shared-work.js\nconst SHARED_WORK_OPERATIONS = Object.freeze([\n\t\"list\",\n\t\"accounts\",\n\t\"grants\",\n\t\"create\",\n\t\"bind\",\n\t\"read\",\n\t\"update\",\n\t\"creatives\",\n\t\"contribute\",\n\t\"grant\",\n\t\"revoke\",\n\t\"unlink\"\n]);\n\n//#endregion\n//#region packages/block-sdk/file-bundle.js\nconst FILE_BUNDLE_LIMITS = Object.freeze({\n\tfiles: 256,\n\ttextBytes: 3e6,\n\tpathLength: 180\n});\n\n//#endregion\n//#region packages/block-sdk/semantic-schema.js\nfunction createSchemaRuntime() {\n\tconst record = (value) => value !== null && typeof value === \"object\" && !Array.isArray(value) && [Object.prototype, null].includes(Object.getPrototypeOf(value));\n\tconst fieldType = /^(string|text|number|integer|boolean|object|json)(\\[\\])?\\??$/;\n\tconst forbidden = /* @__PURE__ */ new Set([\n\t\t\"__proto__\",\n\t\t\"prototype\",\n\t\t\"constructor\"\n\t]);\n\tfunction semanticSchemaValid(schema, depth = 0) {\n\t\tif (depth > 40) return false;\n\t\tif (typeof schema === \"string\") return fieldType.test(schema);\n\t\tif (Array.isArray(schema)) return schema.length === 1 && semanticSchemaValid(schema[0], depth + 1);\n\t\treturn record(schema) && Object.entries(schema).every(([key, value]) => !forbidden.has(key) && semanticSchemaValid(value, depth + 1));\n\t}\n\tfunction schemaMatches(value, schema, depth = 0) {\n\t\tif (depth > 40) return false;\n\t\tif (schema == null) return true;\n\t\tif (Array.isArray(schema)) return schema.length === 1 && Array.isArray(value) && value.every((item) => schemaMatches(item, schema[0], depth + 1));\n\t\tif (typeof schema === \"string\") {\n\t\t\tif (schema.endsWith(\"?\")) return value === void 0 || schemaMatches(value, schema.slice(0, -1), depth + 1);\n\t\t\tif (schema.endsWith(\"[]\")) return Array.isArray(value) && value.every((item) => schemaMatches(item, schema.slice(0, -2), depth + 1));\n\t\t\tif (schema === \"string\" || schema === \"text\") return typeof value === \"string\";\n\t\t\tif (schema === \"object\") return record(value);\n\t\t\tif (schema === \"json\") return jsonValue(value, depth + 1);\n\t\t\tif (schema === \"integer\") return Number.isSafeInteger(value);\n\t\t\tif (schema === \"number\") return typeof value === \"number\" && Number.isFinite(value);\n\t\t\treturn schema === \"boolean\" && typeof value === \"boolean\";\n\t\t}\n\t\treturn record(schema) && record(value) && Object.entries(schema).every(([key, field]) => !forbidden.has(key) && schemaMatches(Object.hasOwn(value, key) ? value[key] : void 0, field, depth + 1));\n\t}\n\tfunction jsonValue(value, depth) {\n\t\tif (depth > 40) return false;\n\t\tif (value === null || typeof value === \"string\" || typeof value === \"boolean\") return true;\n\t\tif (typeof value === \"number\") return Number.isFinite(value);\n\t\treturn (record(value) || Array.isArray(value)) && Object.entries(value).every(([key, child]) => !forbidden.has(key) && jsonValue(child, depth + 1));\n\t}\n\tconst validate = (value, schema) => {\n\t\ttry {\n\t\t\treturn semanticSchemaValid(schema) && jsonValue(value, 0) && schemaMatches(value, schema);\n\t\t} catch {\n\t\t\treturn false;\n\t\t}\n\t};\n\treturn {\n\t\tsemanticSchemaValid,\n\t\tschemaMatches,\n\t\tvalidate\n\t};\n}\nconst { semanticSchemaValid, schemaMatches } = createSchemaRuntime();\nconst REQUIREMENT_SOURCES = Object.freeze([\n\t\"upstream\",\n\t\"project\",\n\t\"adapter\",\n\t\"chat\",\n\t\"default\",\n\t\"user\",\n\t\"external\"\n]);\nconst SEMANTIC_PORT_FIELDS = Object.freeze([\n\t\"key\",\n\t\"semantic\",\n\t\"accepts\",\n\t\"schema\",\n\t\"sources\",\n\t\"sensitivity\",\n\t\"freshnessPolicy\",\n\t\"cardinality\",\n\t\"batchable\"\n]);\n\n//#endregion\n//#region packages/block-sdk/semantic-relationships.js\nconst STANDARD_SEMANTIC_RELATIONSHIPS = Object.freeze([\n\tObject.freeze({\n\t\tname: \"narration_script\",\n\t\tparents: Object.freeze([\"script\"])\n\t}),\n\tObject.freeze({\n\t\tname: \"sales_script\",\n\t\tparents: Object.freeze([\"script\"])\n\t}),\n\tObject.freeze({\n\t\tname: \"timed_transcript\",\n\t\tparents: Object.freeze([\"transcript\"])\n\t}),\n\tObject.freeze({\n\t\tname: \"product_image\",\n\t\tparents: Object.freeze([\"image\"])\n\t}),\n\tObject.freeze({\n\t\tname: \"reference_image\",\n\t\tparents: Object.freeze([\"image\"])\n\t}),\n\tObject.freeze({\n\t\tname: \"generated_image\",\n\t\tparents: Object.freeze([\"image\", \"source_image\"])\n\t}),\n\tObject.freeze({\n\t\tname: \"processed_image\",\n\t\tparents: Object.freeze([\"image\", \"source_image\"])\n\t}),\n\tObject.freeze({\n\t\tname: \"visual_description\",\n\t\tparents: Object.freeze([\"plain_text\"])\n\t}),\n\tObject.freeze({\n\t\tname: \"transcript_text\",\n\t\tparents: Object.freeze([\"plain_text\"])\n\t}),\n\tObject.freeze({\n\t\tname: \"editor_timeline\",\n\t\tparents: Object.freeze([\"timeline\"])\n\t}),\n\tObject.freeze({\n\t\tname: \"legacy.timeline.updatededitor\",\n\t\tparents: Object.freeze([\"timeline\"])\n\t}),\n\tObject.freeze({\n\t\tname: \"narration_audio\",\n\t\tparents: Object.freeze([\"source_audio\"])\n\t}),\n\tObject.freeze({\n\t\tname: \"generated_video\",\n\t\tparents: Object.freeze([\"source_video\"])\n\t}),\n\tObject.freeze({\n\t\tname: \"edited_video\",\n\t\tparents: Object.freeze([\"source_video\"])\n\t}),\n\tObject.freeze({\n\t\tname: \"rendered_video\",\n\t\tparents: Object.freeze([\"source_video\"])\n\t}),\n\tObject.freeze({\n\t\tname: \"rendered_audio\",\n\t\tparents: Object.freeze([\"source_audio\"])\n\t})\n]);\nconst parents = new Map(STANDARD_SEMANTIC_RELATIONSHIPS.map((entry) => [entry.name, entry.parents]));\n\n//#endregion\n//#region packages/block-sdk/first-party-identities.js\nconst FIRST_PARTY_SDK_IDENTITIES = Object.freeze(/* @__PURE__ */ new Set([\n\t\"sm.ai-decide@1.0.0\",\n\t\"sm.ai-write@1.0.0\",\n\t\"sm.board-editor.hosted@3.0.0\",\n\t\"sm.board-editor@2.0.0\",\n\t\"sm.board-editor@2.1.0\",\n\t\"sm.board-editor@2.2.0\",\n\t\"sm.board-editor@2.2.1\",\n\t\"sm.board-editor@2.2.10\",\n\t\"sm.board-editor@2.2.11\",\n\t\"sm.board-editor@2.2.2\",\n\t\"sm.board-editor@2.2.3\",\n\t\"sm.board-editor@2.2.4\",\n\t\"sm.board-editor@2.2.5\",\n\t\"sm.board-editor@2.2.6\",\n\t\"sm.board-editor@2.2.7\",\n\t\"sm.board-editor@2.2.8\",\n\t\"sm.board-editor@2.2.9\",\n\t\"sm.board-editor@3.0.0\",\n\t\"sm.captions@2.0.0\",\n\t\"sm.character@2.0.0\",\n\t\"sm.character@2.0.1\",\n\t\"sm.compare@2.0.0\",\n\t\"sm.compare@2.0.1\",\n\t\"sm.compare@2.0.2\",\n\t\"sm.connect-app@1.0.0\",\n\t\"sm.contact-fields@1.0.0\",\n\t\"sm.edit-assistant@2.0.0\",\n\t\"sm.edit-assistant@2.0.1\",\n\t\"sm.edit-assistant@2.0.2\",\n\t\"sm.editor.hosted@3.0.0\",\n\t\"sm.editor@2.0.0\",\n\t\"sm.editor@2.1.0\",\n\t\"sm.editor@2.2.0\",\n\t\"sm.editor@2.2.1\",\n\t\"sm.editor@2.2.10\",\n\t\"sm.editor@2.2.11\",\n\t\"sm.editor@2.2.12\",\n\t\"sm.editor@2.2.2\",\n\t\"sm.editor@2.2.3\",\n\t\"sm.editor@2.2.4\",\n\t\"sm.editor@2.2.5\",\n\t\"sm.editor@2.2.6\",\n\t\"sm.editor@2.2.7\",\n\t\"sm.editor@2.2.8\",\n\t\"sm.editor@2.2.9\",\n\t\"sm.editor@3.0.0\",\n\t\"sm.export-audio@2.0.0\",\n\t\"sm.export-timeline@2.0.0\",\n\t\"sm.export-video@2.0.0\",\n\t\"sm.export-video@2.1.0\",\n\t\"sm.final-edit@2.0.0\",\n\t\"sm.final-edit@2.0.1\",\n\t\"sm.final-edit@2.0.2\",\n\t\"sm.generate-image@2.0.0\",\n\t\"sm.generate-image@2.1.0\",\n\t\"sm.generate-video@2.0.0\",\n\t\"sm.generate-video@2.0.1\",\n\t\"sm.grade@2.0.0\",\n\t\"sm.grade@2.0.1\",\n\t\"sm.grade@2.0.2\",\n\t\"sm.import-media@2.0.0\",\n\t\"sm.import-media@2.0.1\",\n\t\"sm.import-media@2.0.2\",\n\t\"sm.location@2.0.0\",\n\t\"sm.location@2.0.1\",\n\t\"sm.meta-creative@1.0.0\",\n\t\"sm.motion-graphics@2.0.0\",\n\t\"sm.panel-strip.hosted@3.0.0\",\n\t\"sm.panel-strip@2.0.0\",\n\t\"sm.panel-strip@2.1.0\",\n\t\"sm.panel-strip@2.2.0\",\n\t\"sm.panel-strip@2.3.0\",\n\t\"sm.panel-strip@2.3.1\",\n\t\"sm.panel-strip@2.3.2\",\n\t\"sm.panel-strip@2.3.3\",\n\t\"sm.panel-strip@2.3.4\",\n\t\"sm.panel-strip@2.3.5\",\n\t\"sm.panel-strip@2.3.6\",\n\t\"sm.panel-strip@2.3.7\",\n\t\"sm.panel-strip@2.4.0\",\n\t\"sm.panel-strip@2.4.1\",\n\t\"sm.panel-strip@2.4.2\",\n\t\"sm.panel-strip@3.0.0\",\n\t\"sm.photo-editor@1.0.0\",\n\t\"sm.photo-notes@1.0.0\",\n\t\"sm.photo-notes@1.1.0\",\n\t\"sm.pipeline@2.0.0\",\n\t\"sm.pipeline@2.1.0\",\n\t\"sm.pipeline@2.2.0\",\n\t\"sm.pipeline@2.2.1\",\n\t\"sm.pipeline@2.2.2\",\n\t\"sm.pipeline@2.2.3\",\n\t\"sm.pipeline@2.2.4\",\n\t\"sm.pipeline@2.2.5\",\n\t\"sm.pipeline@2.2.6\",\n\t\"sm.rough-cut@2.0.0\",\n\t\"sm.rough-cut@2.0.1\",\n\t\"sm.rough-cut@2.0.2\",\n\t\"sm.score@2.0.0\",\n\t\"sm.style@2.0.0\",\n\t\"sm.style@2.0.1\",\n\t\"sm.transition@2.0.0\",\n\t\"sm.transition@2.0.1\",\n\t\"sm.transition@2.0.2\",\n\t\"sm.video-assets@2.0.0\",\n\t\"sm.video-assets@2.1.0\",\n\t\"sm.video-assets@2.1.1\",\n\t\"sm.video-assets@2.1.2\",\n\t\"sm.video-assets@2.1.3\",\n\t\"sm.video-assets@2.1.4\",\n\t\"sm.voiceover.hosted@3.0.0\",\n\t\"sm.voiceover@2.0.0\",\n\t\"sm.voiceover@2.1.0\",\n\t\"sm.voiceover@2.1.1\",\n\t\"sm.voiceover@2.1.2\",\n\t\"sm.voiceover@2.1.3\",\n\t\"sm.voiceover@2.1.4\",\n\t\"sm.voiceover@2.1.5\",\n\t\"sm.voiceover@2.1.6\",\n\t\"sm.voiceover@3.0.0\",\n\t\"sm.when@1.0.0\",\n\t\"sm.when@1.1.0\",\n\t\"sm.write-summary@1.0.0\",\n\t\"stillmade.generate@1.0.0\"\n]));\n\n//#endregion\n//#region packages/block-sdk/interaction-values.js\nconst TIMELINE_RANGE_MAX_MS = Number.MAX_SAFE_INTEGER;\n\n//#endregion\n//#region packages/block-sdk/state-migrations.js\nconst STATE_MIGRATION_LIMITS = Object.freeze({\n\troutes: 16,\n\toperations: 64,\n\tkeyLength: 80,\n\tdeclarationBytes: 65536\n});\n\n//#endregion\n//#region packages/block-sdk/sdk-compatibility.js\nconst versionPattern = \"(0|[1-9][0-9]{0,5})\\\\.(0|[1-9][0-9]{0,5})\\\\.(0|[1-9][0-9]{0,5})\";\nconst versionExpression = new RegExp(\"^\" + versionPattern + \"$\");\nconst comparatorExpression = new RegExp(\"^(>=|<=|>|<|=)?\" + versionPattern + \"$\");\n\n//#endregion\n//#region packages/block-sdk/workspace-edits.js\nconst WORKSPACE_EDIT_FIELDS = Object.freeze([\n\t\"blueprint\",\n\t\"shotPlan\",\n\t\"panels\",\n\t\"board\",\n\t\"canvas\",\n\t\"animation\",\n\t\"editor\"\n]);\n\n//#endregion\n//#region packages/block-sdk/transition-settings.js\nconst TRANSITION_SETTINGS = Object.freeze([\n\t{\n\t\t\"type\": \"Cut\",\n\t\t\"sounds\": []\n\t},\n\t{\n\t\t\"type\": \"Fade\",\n\t\t\"sounds\": []\n\t},\n\t{\n\t\t\"type\": \"Cross dissolve\",\n\t\t\"sounds\": []\n\t},\n\t{\n\t\t\"type\": \"Shape wipe\",\n\t\t\"sounds\": [\"shape_sweep\", \"shape_pop\"]\n\t},\n\t{\n\t\t\"type\": \"Iris\",\n\t\t\"sounds\": [\"shape_sweep\", \"shape_pop\"]\n\t},\n\t{\n\t\t\"type\": \"Ink splat\",\n\t\t\"sounds\": [\"shape_sweep\", \"shape_pop\"]\n\t},\n\t{\n\t\t\"type\": \"Swirl\",\n\t\t\"sounds\": [\"whoosh\", \"swirl_wind\"]\n\t},\n\t{\n\t\t\"type\": \"Whip left\",\n\t\t\"sounds\": [\"whip_crack\", \"whip_zip\"]\n\t},\n\t{\n\t\t\"type\": \"Whip right\",\n\t\t\"sounds\": [\"whip_crack\", \"whip_zip\"]\n\t},\n\t{\n\t\t\"type\": \"Whip up\",\n\t\t\"sounds\": [\"whip_crack\", \"whip_zip\"]\n\t},\n\t{\n\t\t\"type\": \"Whip down\",\n\t\t\"sounds\": [\"whip_crack\", \"whip_zip\"]\n\t},\n\t{\n\t\t\"type\": \"Whip pan\",\n\t\t\"sounds\": [\"whip_crack\", \"whip_zip\"]\n\t},\n\t{\n\t\t\"type\": \"Slash\",\n\t\t\"sounds\": [\"shape_sweep\", \"shape_pop\"]\n\t},\n\t{\n\t\t\"type\": \"Shred\",\n\t\t\"sounds\": [\"shape_sweep\", \"shape_pop\"]\n\t},\n\t{\n\t\t\"type\": \"Morph\",\n\t\t\"sounds\": [\"morph_warp\", \"morph_bloom\"]\n\t},\n\t{\n\t\t\"type\": \"Dip to black\",\n\t\t\"sounds\": []\n\t},\n\t{\n\t\t\"type\": \"Dip to white\",\n\t\t\"sounds\": []\n\t},\n\t{\n\t\t\"type\": \"Push left\",\n\t\t\"sounds\": [\"push_slide\", \"push_thump\"]\n\t},\n\t{\n\t\t\"type\": \"Push right\",\n\t\t\"sounds\": [\"push_slide\", \"push_thump\"]\n\t},\n\t{\n\t\t\"type\": \"Push up\",\n\t\t\"sounds\": [\"push_slide\", \"push_thump\"]\n\t},\n\t{\n\t\t\"type\": \"Push down\",\n\t\t\"sounds\": [\"push_slide\", \"push_thump\"]\n\t},\n\t{\n\t\t\"type\": \"Zoom left\",\n\t\t\"sounds\": []\n\t},\n\t{\n\t\t\"type\": \"Zoom right\",\n\t\t\"sounds\": []\n\t},\n\t{\n\t\t\"type\": \"Zoom up\",\n\t\t\"sounds\": []\n\t},\n\t{\n\t\t\"type\": \"Zoom down\",\n\t\t\"sounds\": []\n\t}\n].map((row) => Object.freeze({\n\t...row,\n\tsounds: Object.freeze(row.sounds)\n})));\n\n//#endregion\n//#region packages/block-sdk/desktop-permissions.js\nconst DESKTOP_PERMISSIONS = Object.freeze([\n\t\"screen.capture\",\n\t\"cursor.track\",\n\t\"camera.capture\",\n\t\"microphone.capture\",\n\t\"clipboard.read\",\n\t\"clipboard.write\",\n\t\"media.pick\",\n\t\"notifications.show\",\n\t\"power.keep-awake\",\n\t\"native.tools\",\n\t\"folder.read\",\n\t\"folder.write\"\n]);\n\n//#endregion\n//#region packages/block-sdk/desktop-tools.js\nconst DESKTOP_TOOL_CONTRACTS = Object.freeze({\n\t\"org.stillmade.PythonAdapter\": Object.freeze({\n\t\tid: \"org.stillmade.PythonAdapter\",\n\t\tadapterVersion: 1,\n\t\tlabel: \"Python connection\",\n\t\tactions: Object.freeze([\n\t\t\t\"adapter.import\",\n\t\t\t\"adapter.inspect\",\n\t\t\t\"adapter.execute\",\n\t\t\t\"adapter.describe\",\n\t\t\t\"adapter.call\"\n\t\t]),\n\t\tprojectExtensions: Object.freeze([\"py\"])\n\t}),\n\t\"org.natron.Natron\": Object.freeze({\n\t\tid: \"org.natron.Natron\",\n\t\tadapterVersion: 1,\n\t\tlabel: \"Natron\",\n\t\tactions: Object.freeze([\n\t\t\t\"launch\",\n\t\t\t\"project.import\",\n\t\t\t\"project.open\",\n\t\t\t\"project.render\"\n\t\t]),\n\t\tprojectExtensions: Object.freeze([\"ntp\"])\n\t})\n});\n\n//#endregion\n//#region packages/block-sdk/data-values.js\nconst DATA_VALUE_LIMITS = Object.freeze({\n\tfileName: 255,\n\tdocumentText: 1e6,\n\tdocumentTitle: 300,\n\ttableColumns: 500,\n\ttableRows: 1e5,\n\ttableCells: 5e5,\n\tcolumnName: 160,\n\tcellText: 1e5,\n\turl: 8192\n});\nconst FILE_FORMATS = Object.freeze({\n\tpdf: \"application/pdf\",\n\ttxt: \"text/plain\",\n\tcsv: \"text/csv\",\n\tmd: \"text/markdown\",\n\tjson: \"application/json\",\n\tzip: \"application/zip\"\n});\nconst FILE_MEDIA_TYPES = Object.freeze([...new Set(Object.values(FILE_FORMATS))]);\nconst DOCUMENT_FORMATS = Object.freeze([\"markdown\", \"plain\"]);\n\n//#endregion\n//#region packages/block-sdk/network.js\nconst NETWORK_LIMITS = Object.freeze({\n\torigins: 8,\n\trequestBytes: 4194304,\n\tresponseBytes: 8388608,\n\ttimeoutMs: 3e4,\n\tredirects: 3,\n\theaders: 32,\n\theaderBytes: 16384,\n\turlLength: 8192,\n\trequestsPerMinute: 120,\n\toriginRequestsPerMinute: 3e3,\n\tkeyLength: 4096\n});\nconst NETWORK_METHODS = Object.freeze([\n\t\"GET\",\n\t\"HEAD\",\n\t\"POST\",\n\t\"PUT\",\n\t\"PATCH\",\n\t\"DELETE\"\n]);\nconst NETWORK_AUTH_SCHEMES = Object.freeze([\n\t\"bearer\",\n\t\"header\",\n\t\"query\",\n\t\"oauth2\"\n]);\nconst SOCKET_LIMITS = Object.freeze({\n\tsockets: 4,\n\tmessageBytes: 1048576,\n\trunBytes: 268435456,\n\tprotocols: 8\n});\n\n//#endregion\n//#region packages/block-sdk/triggers.js\nconst BLOCK_TRIGGER_EVENTS = Object.freeze([\n\t\"media.saved\",\n\t\"schedule\",\n\t\"webhook\",\n\t\"project.completed\",\n\t\"provider\"\n]);\nconst BLOCK_TRIGGER_LIMITS = Object.freeze({\n\ttriggers: 4,\n\tlabelLength: 120,\n\tminEverySeconds: 60,\n\tmaxEverySeconds: 31536e3\n});\nconst UNATTENDED_RUNTIMES = Object.freeze([\n\t\"recipe\",\n\t\"javascript\",\n\t\"capability\"\n]);\n\n//#endregion\n//#region packages/block-sdk/feature-map.js\nconst FEATURE_MAP_LIMITS = Object.freeze({\n\tfeatures: 24,\n\tid: 48,\n\tlabel: 40,\n\tdoes: 160,\n\tasks: 8,\n\task: 80\n});\n\n//#endregion\n//#region packages/block-sdk/contracts.js\nconst PORT_FIELDS = Object.freeze([\n\t\"type\",\n\t\"required\",\n\t\"default\",\n\t\"min\",\n\t\"max\",\n\t\"description\",\n\t\"role\",\n\t\"primary\",\n\t\"context\",\n\t\"imageMode\",\n\t...SEMANTIC_PORT_FIELDS\n]);\nconst TYPES = Object.freeze([\n\t\"text\",\n\t\"number\",\n\t\"integer\",\n\t\"boolean\",\n\t\"json\",\n\t\"object\",\n\t\"image\",\n\t\"video\",\n\t\"audio\",\n\t\"asset\",\n\t\"script\",\n\t\"transcript\",\n\t\"brief\",\n\t\"bible\",\n\t\"shot-plan\",\n\t\"panel-document\",\n\t\"board-document\",\n\t\"scene-document\",\n\t\"timeline\",\n\t\"timeline-edit\",\n\t\"file-bundle\",\n\t\"workspace-edit\",\n\t\"timeline-range\",\n\t\"research\",\n\t\"character\",\n\t\"location\",\n\t\"style\",\n\t\"pipeline\",\n\t\"approval\",\n\t\"scene\",\n\t\"shot\",\n\t\"mask\",\n\t\"depth\",\n\t\"pose\",\n\t\"metadata\",\n\t\"project-context\",\n\t\"file\",\n\t\"document\",\n\t\"table\",\n\t\"url\",\n\t\"date\",\n\t\"color\"\n]);\nconst PORTABLE_ACTIONS = Object.freeze([\n\t\"final.render\",\n\t\"stock.search\",\n\t\"stock.select\",\n\t\"stock.auto\",\n\t\"gif.search\",\n\t\"gif.save\",\n\t\"presenter.generate\",\n\t\"quality.analyze\",\n\t\"image.generate\",\n\t\"image.generate.batch\",\n\t\"media.generate\",\n\t\"youtube.upload\"\n]);\nconst UI_INPUT_CONTROLS = Object.freeze([\n\t\"text\",\n\t\"number\",\n\t\"slider\",\n\t\"checkbox\",\n\t\"asset\",\n\t\"select\",\n\t\"multiselect\",\n\t\"file\",\n\t\"date\",\n\t\"color\",\n\t\"url\",\n\t\"richtext\",\n\t\"list\",\n\t\"grid\"\n]);\nconst UI_OUTPUT_PRESENTATIONS = Object.freeze([\n\t\"gallery\",\n\t\"before-after\",\n\t\"table\",\n\t\"document\",\n\t\"chart\",\n\t\"code\",\n\t\"player\",\n\t\"download\"\n]);\nconst UI_CONTROL_TYPES = Object.freeze({\n\tfile: [\"file\", \"file[]\"],\n\tdate: [\"date\"],\n\tcolor: [\"color\"],\n\turl: [\"url\"],\n\trichtext: [\"document\", \"text\"],\n\tlist: [\n\t\t\"text[]\",\n\t\t\"number[]\",\n\t\t\"integer[]\",\n\t\t\"url[]\",\n\t\t\"date[]\",\n\t\t\"color[]\"\n\t],\n\tgrid: [\"table\"]\n});\nconst UI_PRESENTATION_TYPES = Object.freeze({\n\tgallery: [\"image[]\"],\n\t\"before-after\": [\"image\"],\n\ttable: [\"table\"],\n\tdocument: [\"document\", \"text\"],\n\tchart: [\n\t\t\"table\",\n\t\t\"number[]\",\n\t\t\"integer[]\"\n\t],\n\tcode: [\n\t\t\"text\",\n\t\t\"json\",\n\t\t\"object\"\n\t],\n\tplayer: [\n\t\t\"audio\",\n\t\t\"video\",\n\t\t\"audio[]\",\n\t\t\"video[]\"\n\t],\n\tdownload: [\n\t\t\"file\",\n\t\t\"file[]\",\n\t\t\"file-bundle\"\n\t]\n});\nconst CONTEXT_TYPES = Object.freeze({\n\tscript: \"script\",\n\ttranscript: \"transcript\",\n\tshots: \"shot[]\",\n\tshotPlan: \"shot-plan\",\n\tscenes: \"scene[]\",\n\tcharacters: \"character[]\",\n\tlocations: \"location[]\",\n\tstyles: \"style[]\",\n\tassets: \"asset[]\",\n\tfiles: \"file[]\",\n\tgenerations: \"metadata[]\",\n\tversions: \"metadata[]\",\n\ttimeline: \"timeline\",\n\teditor: \"timeline\",\n\tcanvas: \"pipeline\",\n\tblueprint: \"bible\",\n\tpanels: \"panel-document\",\n\tboard: \"board-document\",\n\tanimation: \"scene-document\",\n\tmetadata: \"metadata\"\n});\nconst hostedOperation = (executor, mode, byok, summary) => Object.freeze({\n\texecutor,\n\tmode,\n\tbyok,\n\tsummary\n});\nconst HOSTED_CAPABILITY_OPERATIONS = Object.freeze({\n\t\"text.generate\": hostedOperation(\"capability-run\", \"sync\", true, \"Exact model, account BYOK or credits, and explicit run review\"),\n\t\"audio.speech\": hostedOperation(\"capability-run\", \"sync\", true, \"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\"),\n\t\"audio.transcribe\": hostedOperation(\"capability-run\", \"sync\", true, \"One owner-scoped stored audio asset to reviewed text and ordered word timings with StillMade transcription on credits, or OpenAI Whisper with your key\"),\n\t\"audio.music\": hostedOperation(\"capability-run\", \"sync\", false, \"One prompt to generated music (5–240 seconds) with StillMade credits and playback review\"),\n\t\"audio.sfx\": hostedOperation(\"capability-run\", \"sync\", false, \"One prompt to a generated sound effect (0.5–22 seconds) with StillMade credits and playback review\"),\n\t\"image.generate\": hostedOperation(\"capability-run\", \"sync\", true, \"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\"),\n\t\"video.generate\": hostedOperation(\"capability-run\", \"async\", true, \"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\"),\n\t\"image.describe\": hostedOperation(\"capability-run\", \"sync\", true, \"One to four owned images to bounded production notes; host-selected model/payment and actual description review\"),\n\t\"media.analyze\": hostedOperation(\"capability-run\", \"sync\", false, \"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\"),\n\t\"web.fetch\": hostedOperation(\"capability-run\", \"sync\", false, \"One public web page read by the host and answered against the Block's instruction, with StillMade credits; no cookies, keys or private addresses\"),\n\t\"web.research\": hostedOperation(\"capability-run\", \"sync\", false, \"One topic searched on the web and summarized with cited sources, with StillMade credits\"),\n\t\"timeline.propose\": hostedOperation(\"capability-run\", \"sync\", true, \"Bounded typed context to strict timeline-edit JSON; host-selected model/payment, stale-before checks, preview and Apply\"),\n\t\"workspace.propose\": hostedOperation(\"capability-run\", \"sync\", true, \"Bounded typed context to a strict workspace-edit proposal for one permitted workspace; preview and explicit Apply\"),\n\t\"connection.execute\": hostedOperation(\"connection\", \"sync\", false, \"One reviewed action on a connected third-party app account through the host connection service; the Block never receives account credentials\")\n});\nconst hostedOperationNames = (predicate) => Object.freeze(Object.entries(HOSTED_CAPABILITY_OPERATIONS).filter(([, operation]) => predicate(operation)).map(([name]) => name));\nconst HOSTED_OPERATION_NAMES = hostedOperationNames(() => true);\nconst CAPABILITY_RUN_OPERATIONS = hostedOperationNames((operation) => operation.executor === \"capability-run\");\nconst SYNC_CAPABILITY_RUN_OPERATIONS = hostedOperationNames((operation) => operation.executor === \"capability-run\" && operation.mode === \"sync\");\nconst BYOK_CAPABILITY_OPERATIONS = hostedOperationNames((operation) => operation.byok);\nconst SCOPES = [\n\t...Object.keys(CONTEXT_TYPES).map((field) => `context.${field}.read`),\n\t\"asset.read\",\n\t\"asset.create\",\n\t\"asset.version.append\",\n\t\"project.read\",\n\t\"project.patch\",\n\t\"timeline.read\",\n\t\"timeline.propose\",\n\t\"workspace.animation.propose\",\n\t\"workspace.canvas.propose\",\n\t\"workspace.blueprint.propose\",\n\t\"workspace.shotPlan.propose\",\n\t\"workspace.panels.propose\",\n\t\"workspace.board.propose\",\n\t\"workspace.editor.propose\",\n\t\"state.step\",\n\t\"work.shared\"\n];\n\n//#endregion\n//#region packages/block-sdk/generation-catalog.js\nconst NANO_ASPECTS = Object.freeze([\n\t\"auto\",\n\t\"21:9\",\n\t\"16:9\",\n\t\"3:2\",\n\t\"4:3\",\n\t\"1:1\",\n\t\"4:5\",\n\t\"3:4\",\n\t\"2:3\",\n\t\"9:16\"\n]);\nconst SEEDANCE_ASPECTS = Object.freeze([\n\t\"auto\",\n\t\"21:9\",\n\t\"16:9\",\n\t\"4:3\",\n\t\"1:1\",\n\t\"3:4\",\n\t\"9:16\"\n]);\nconst SEEDANCE_DURATIONS = Object.freeze([\n\t4,\n\t5,\n\t6,\n\t7,\n\t8,\n\t9,\n\t10,\n\t11,\n\t12,\n\t13,\n\t14,\n\t15\n]);\nconst image = (label, { aspectRatios, resolutions = [], qualities = [], references = 0, seed = false }) => Object.freeze({\n\tlabel,\n\taspectRatios: Object.freeze(aspectRatios),\n\tresolutions: Object.freeze(resolutions),\n\tqualities: Object.freeze(qualities),\n\treferences,\n\tseed\n});\nconst video = (label, { aspectRatios = [], resolutions = [], durations, firstFrame = true, lastFrame = false, requiresFirstFrame = false, seed = false, nativeAudio = false }) => Object.freeze({\n\tlabel,\n\taspectRatios: Object.freeze(aspectRatios),\n\tresolutions: Object.freeze(resolutions),\n\tdurations: Object.freeze(durations),\n\tfirstFrame,\n\tlastFrame,\n\trequiresFirstFrame,\n\tseed,\n\tnativeAudio\n});\nconst IMAGE_GENERATION_MODELS = Object.freeze({\n\t\"nano-banana-2\": image(\"Nano Banana 2\", {\n\t\taspectRatios: NANO_ASPECTS,\n\t\tresolutions: [\n\t\t\t\"1K\",\n\t\t\t\"2K\",\n\t\t\t\"4K\"\n\t\t],\n\t\treferences: 8,\n\t\tseed: true\n\t}),\n\t\"nano-banana-2-lite\": image(\"Nano Banana 2 Lite\", {\n\t\taspectRatios: NANO_ASPECTS,\n\t\tresolutions: [\n\t\t\t\"1K\",\n\t\t\t\"2K\",\n\t\t\t\"4K\"\n\t\t],\n\t\treferences: 8,\n\t\tseed: true\n\t}),\n\t\"nano-banana-pro\": image(\"Nano Banana Pro\", {\n\t\taspectRatios: NANO_ASPECTS,\n\t\tresolutions: [\n\t\t\t\"1K\",\n\t\t\t\"2K\",\n\t\t\t\"4K\"\n\t\t],\n\t\treferences: 8,\n\t\tseed: true\n\t}),\n\t\"gpt-image-2\": image(\"GPT Image 2\", {\n\t\taspectRatios: [\n\t\t\t\"auto\",\n\t\t\t\"16:9\",\n\t\t\t\"9:16\",\n\t\t\t\"1:1\",\n\t\t\t\"4:3\",\n\t\t\t\"3:4\"\n\t\t],\n\t\tresolutions: [\n\t\t\t\"1K\",\n\t\t\t\"2K\",\n\t\t\t\"4K\"\n\t\t],\n\t\tqualities: [\n\t\t\t\"low\",\n\t\t\t\"medium\",\n\t\t\t\"high\"\n\t\t],\n\t\treferences: 8\n\t}),\n\t\"gpt-image-2.5-flare\": image(\"GPT Image 2.5 Flare\", {\n\t\taspectRatios: [\n\t\t\t\"auto\",\n\t\t\t\"16:9\",\n\t\t\t\"9:16\",\n\t\t\t\"1:1\",\n\t\t\t\"4:3\",\n\t\t\t\"3:4\"\n\t\t],\n\t\tresolutions: [\n\t\t\t\"1K\",\n\t\t\t\"2K\",\n\t\t\t\"4K\"\n\t\t],\n\t\tqualities: [\n\t\t\t\"low\",\n\t\t\t\"medium\",\n\t\t\t\"high\"\n\t\t],\n\t\treferences: 8\n\t}),\n\t\"gpt-image-2.5-sunburst\": image(\"GPT Image 2.5 Sunburst\", {\n\t\taspectRatios: [\n\t\t\t\"auto\",\n\t\t\t\"16:9\",\n\t\t\t\"9:16\",\n\t\t\t\"1:1\",\n\t\t\t\"4:3\",\n\t\t\t\"3:4\"\n\t\t],\n\t\tresolutions: [\n\t\t\t\"1K\",\n\t\t\t\"2K\",\n\t\t\t\"4K\"\n\t\t],\n\t\tqualities: [\n\t\t\t\"low\",\n\t\t\t\"medium\",\n\t\t\t\"high\"\n\t\t],\n\t\treferences: 8\n\t}),\n\t\"gpt-image-2.6-flare\": image(\"GPT Image 2.6 Flare\", {\n\t\taspectRatios: [\n\t\t\t\"auto\",\n\t\t\t\"16:9\",\n\t\t\t\"9:16\",\n\t\t\t\"1:1\",\n\t\t\t\"4:3\",\n\t\t\t\"3:4\"\n\t\t],\n\t\tresolutions: [\n\t\t\t\"1K\",\n\t\t\t\"2K\",\n\t\t\t\"4K\"\n\t\t],\n\t\tqualities: [\n\t\t\t\"low\",\n\t\t\t\"medium\",\n\t\t\t\"high\"\n\t\t],\n\t\treferences: 8\n\t}),\n\t\"gpt-image-2.6-sunburst\": image(\"GPT Image 2.6 Sunburst\", {\n\t\taspectRatios: [\n\t\t\t\"auto\",\n\t\t\t\"16:9\",\n\t\t\t\"9:16\",\n\t\t\t\"1:1\",\n\t\t\t\"4:3\",\n\t\t\t\"3:4\"\n\t\t],\n\t\tresolutions: [\n\t\t\t\"1K\",\n\t\t\t\"2K\",\n\t\t\t\"4K\"\n\t\t],\n\t\tqualities: [\n\t\t\t\"low\",\n\t\t\t\"medium\",\n\t\t\t\"high\"\n\t\t],\n\t\treferences: 8\n\t}),\n\t\"gpt-image-1.5\": image(\"GPT-Image 1.5\", {\n\t\taspectRatios: [\n\t\t\t\"16:9\",\n\t\t\t\"9:16\",\n\t\t\t\"1:1\"\n\t\t],\n\t\tqualities: [\n\t\t\t\"low\",\n\t\t\t\"medium\",\n\t\t\t\"high\"\n\t\t]\n\t}),\n\t\"kling-image-v3\": image(\"Kling Image V3\", {\n\t\taspectRatios: [\n\t\t\t\"21:9\",\n\t\t\t\"16:9\",\n\t\t\t\"9:16\",\n\t\t\t\"1:1\",\n\t\t\t\"4:3\",\n\t\t\t\"3:4\",\n\t\t\t\"3:2\",\n\t\t\t\"2:3\"\n\t\t],\n\t\tresolutions: [\"1K\", \"2K\"]\n\t}),\n\t\"seedream-v4.5\": image(\"Seedream 4.5\", {\n\t\taspectRatios: [\n\t\t\t\"16:9\",\n\t\t\t\"9:16\",\n\t\t\t\"1:1\",\n\t\t\t\"4:3\",\n\t\t\t\"3:4\"\n\t\t],\n\t\tresolutions: [\"2K\", \"4K\"],\n\t\tseed: true\n\t})\n});\nconst VIDEO_GENERATION_MODELS = Object.freeze({\n\t\"seedance-2.0\": video(\"Seedance 2.0\", {\n\t\taspectRatios: SEEDANCE_ASPECTS,\n\t\tresolutions: [\n\t\t\t\"480p\",\n\t\t\t\"720p\",\n\t\t\t\"1080p\",\n\t\t\t\"4k\"\n\t\t],\n\t\tdurations: SEEDANCE_DURATIONS,\n\t\tlastFrame: true,\n\t\tseed: true,\n\t\tnativeAudio: true\n\t}),\n\t\"seedance-2.0-fast\": video(\"Seedance 2.0 Fast\", {\n\t\taspectRatios: SEEDANCE_ASPECTS,\n\t\tresolutions: [\"480p\", \"720p\"],\n\t\tdurations: SEEDANCE_DURATIONS,\n\t\tlastFrame: true,\n\t\tseed: true,\n\t\tnativeAudio: true\n\t}),\n\t\"seedance-2.0-mini\": video(\"Seedance 2.0 Mini\", {\n\t\taspectRatios: SEEDANCE_ASPECTS,\n\t\tresolutions: [\"480p\", \"720p\"],\n\t\tdurations: SEEDANCE_DURATIONS,\n\t\tlastFrame: true,\n\t\tseed: true,\n\t\tnativeAudio: true\n\t}),\n\t\"kling-v3-turbo\": video(\"Kling 3.0 Turbo\", {\n\t\taspectRatios: [\n\t\t\t\"16:9\",\n\t\t\t\"9:16\",\n\t\t\t\"1:1\"\n\t\t],\n\t\tdurations: [5, 10]\n\t}),\n\t\"wan-2.6-flash\": video(\"Wan 2.6 Flash\", {\n\t\taspectRatios: [\n\t\t\t\"16:9\",\n\t\t\t\"9:16\",\n\t\t\t\"1:1\"\n\t\t],\n\t\tdurations: [\n\t\t\t3,\n\t\t\t4,\n\t\t\t5\n\t\t],\n\t\trequiresFirstFrame: true\n\t}),\n\t\"veo-3.1-lite\": video(\"Veo 3.1 Lite\", {\n\t\taspectRatios: [\"16:9\", \"9:16\"],\n\t\tresolutions: [\"720p\", \"1080p\"],\n\t\tdurations: [\n\t\t\t4,\n\t\t\t6,\n\t\t\t8\n\t\t],\n\t\tlastFrame: true,\n\t\tnativeAudio: true\n\t}),\n\t\"vidu-q3-turbo\": video(\"Vidu Q3 Turbo\", {\n\t\tdurations: [\n\t\t\t1,\n\t\t\t2,\n\t\t\t3,\n\t\t\t4,\n\t\t\t5,\n\t\t\t6,\n\t\t\t7,\n\t\t\t8,\n\t\t\t9,\n\t\t\t10,\n\t\t\t11,\n\t\t\t12,\n\t\t\t13,\n\t\t\t14,\n\t\t\t15,\n\t\t\t16\n\t\t],\n\t\tlastFrame: true,\n\t\tnativeAudio: true\n\t}),\n\t\"wan-2.7\": video(\"Wan 2.7\", {\n\t\tresolutions: [\"720p\", \"1080p\"],\n\t\tdurations: [\n\t\t\t2,\n\t\t\t3,\n\t\t\t4,\n\t\t\t5,\n\t\t\t6,\n\t\t\t7,\n\t\t\t8,\n\t\t\t9,\n\t\t\t10,\n\t\t\t11,\n\t\t\t12,\n\t\t\t13,\n\t\t\t14,\n\t\t\t15\n\t\t],\n\t\tlastFrame: true,\n\t\trequiresFirstFrame: true,\n\t\tseed: true\n\t})\n});\nconst IMAGE_SETTING_KEYS = Object.freeze([\n\t\"model\",\n\t\"aspectRatio\",\n\t\"resolution\",\n\t\"quality\"\n]);\nconst VIDEO_SETTING_KEYS = Object.freeze([\n\t\"model\",\n\t\"duration\",\n\t\"resolution\",\n\t\"aspectRatio\",\n\t\"generateAudio\"\n]);\nconst GENERATION_LIMITS = Object.freeze({\n\treferences: 8,\n\tnegativePrompt: 2e3,\n\tseed: 2147483647\n});\nconst VIDEO_SHAPE_MODELS = Object.freeze([\n\t\"wan-2.6-flash\",\n\t\"veo-3.1-lite\",\n\t\"seedance-2.0-mini\",\n\t\"kling-v3-turbo\",\n\t\"seedance-2.0-fast\",\n\t\"seedance-2.0\"\n]);\nconst AUDIO_GENERATION = Object.freeze({\n\tspeech: Object.freeze({\n\t\ttext: 3800,\n\t\tdefaultVoice: \"asteria\",\n\t\tspeed: Object.freeze({\n\t\t\tmin: .25,\n\t\t\tmax: 4,\n\t\t\tdefault: 1\n\t\t})\n\t}),\n\tmusic: Object.freeze({\n\t\tmin: 5,\n\t\tmax: 240,\n\t\tdefault: 30\n\t}),\n\tsfx: Object.freeze({\n\t\tmin: .5,\n\t\tmax: 22,\n\t\tdefault: 4\n\t})\n});\n\n//#endregion\n//#region packages/block-platform/model-capabilities.js\nconst imageOption = (value) => {\n\tconst model = IMAGE_GENERATION_MODELS[value];\n\treturn {\n\t\tvalue,\n\t\tlabel: model.label,\n\t\tsupports: {\n\t\t\taspectRatio: [...model.aspectRatios],\n\t\t\tresolution: [...model.resolutions],\n\t\t\tquality: [...model.qualities]\n\t\t}\n\t};\n};\nconst videoOption = (value) => {\n\tconst model = VIDEO_GENERATION_MODELS[value];\n\treturn {\n\t\tvalue,\n\t\tlabel: model.label,\n\t\tsupports: {\n\t\t\taspectRatio: [...model.aspectRatios],\n\t\t\tresolution: [...model.resolutions],\n\t\t\tquality: [],\n\t\t\tduration: [...model.durations]\n\t\t}\n\t};\n};\nconst IMAGE_MODEL_OPTIONS = [\n\t\"nano-banana-2\",\n\t\"nano-banana-2-lite\",\n\t\"nano-banana-pro\",\n\t\"gpt-image-1.5\",\n\t\"gpt-image-2\",\n\t\"gpt-image-2.5-flare\",\n\t\"gpt-image-2.5-sunburst\",\n\t\"gpt-image-2.6-flare\",\n\t\"gpt-image-2.6-sunburst\",\n\t\"kling-image-v3\",\n\t\"seedream-v4.5\"\n].map(imageOption);\nconst VIDEO_MODEL_OPTIONS = [{\n\tvalue: \"seedance-2.5\",\n\tlabel: \"Seedance 2.5\",\n\tdisabled: true,\n\tnote: \"Coming Soon!\",\n\tsupports: {\n\t\taspectRatio: [],\n\t\tresolution: [],\n\t\tquality: [],\n\t\tduration: []\n\t}\n}, ...[\n\t\"seedance-2.0\",\n\t\"seedance-2.0-fast\",\n\t\"seedance-2.0-mini\",\n\t\"kling-v3-turbo\",\n\t\"wan-2.6-flash\",\n\t\"veo-3.1-lite\",\n\t\"vidu-q3-turbo\"\n].map(videoOption)];\nfunction getModelCapabilities(type, model) {\n\treturn (type === \"video\" ? VIDEO_MODEL_OPTIONS : IMAGE_MODEL_OPTIONS).find((option) => option.value === model)?.supports || {\n\t\taspectRatio: [],\n\t\tresolution: [],\n\t\tquality: [],\n\t\tduration: []\n\t};\n}\nfunction optionIsSupported(type, model, field, value) {\n\tif (!value || value === \"__keep\") return false;\n\treturn (getModelCapabilities(type, model)[field] || []).includes(value);\n}\n\n//#endregion\n//#region blocks/native/sm.board-editor/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 boardResult(board) {\n\tif (!plain(board) || !Array.isArray(board.strip)) return {};\n\tconst doc = {\n\t\t...board,\n\t\tschemaVersion: board.schemaVersion ?? 1\n\t};\n\tconst state = doc.strip.some((item) => plain(item) && item.type === \"canvas\") ? stripToEditorState(doc) : null;\n\treturn {\n\t\toutput: doc,\n\t\t...state ? { editorTimeline: {\n\t\t\tschemaVersion: 1,\n\t\t\tactiveTimelineId: \"whiteboard\",\n\t\t\t...state\n\t\t} } : {}\n\t};\n}\nconst OVERLAY_REF_H = 369;\nfunction renderPlan(state, aspect) {\n\tconst clips = (Array.isArray(state?.clips) ? state.clips : []).filter((clip) => plain(clip)).map((clip) => ({\n\t\t...clip,\n\t\tspeed: clip.speed ?? 1,\n\t\ttrimStart: clip.trimStart ?? 0,\n\t\topacity: clip.opacity ?? 1,\n\t\ttrackId: clip.trackId || \"video\"\n\t}));\n\tconst audio = (Array.isArray(state?.audioItems) ? state.audioItems : []).filter((item) => plain(item) && item.url && !item.muted).map((item) => ({\n\t\turl: item.url,\n\t\ttitle: item.title || item.name,\n\t\tstart: Math.max(0, item.start || 0),\n\t\tduration: Math.max(.05, Number(item.duration) || 0),\n\t\tvolume: item.volume ?? 80,\n\t\tfadeIn: item.fadeIn ?? 0,\n\t\tfadeOut: item.fadeOut ?? 0,\n\t\tsourceOffset: Math.max(0, item.sourceOffset || item.trimStart || 0),\n\t\tloop: !!item.loop,\n\t\trate: item.rate ?? 1\n\t}));\n\tconst end = (item) => (Number(item.start) || 0) + (Number(item.duration) || 0);\n\tconst targetDuration = Math.max(0, ...clips.map(end), ...audio.map(end));\n\tif (!(targetDuration > 0)) fail(\"There is nothing to export yet. Build a board first.\");\n\treturn {\n\t\tclips,\n\t\taudio,\n\t\toverlays: [...state.textOverlays || [], ...state.captions || []],\n\t\tstickers: [],\n\t\tblurs: [],\n\t\tpreviewH: OVERLAY_REF_H,\n\t\ttargetDuration,\n\t\tbackgroundColor: state.backgroundColor || \"#000000\",\n\t\ttrackOrder: (state.tracks || []).filter((track) => track.type === \"visual\").map((track) => track.id),\n\t\taspect\n\t};\n}\nlet current = null;\nconst chatCollect = async ({ system = \"\", max_tokens, messages = [] }) => {\n\tconst { stillmade } = current || fail(\"White Board Motion is not running.\");\n\tconst prompt = messages.map((message) => typeof message.content === \"string\" ? message.content : Array.isArray(message.content) ? message.content.filter((part) => typeof part.text === \"string\").map((part) => part.text).join(\"\\n\\n\") : \"\").join(\"\\n\\n\") || \"Answer.\";\n\tconst answer = await stillmade.hosted.run(\"text.generate\", {\n\t\tsystem,\n\t\tprompt,\n\t\tmaxTokens: Math.max(1, Math.min(Number(max_tokens) || 1200, 24e3))\n\t});\n\treturn typeof answer === \"string\" ? answer : JSON.stringify(answer);\n};\nuseImagePanelTextModel({\n\tready: () => true,\n\tchatCollect\n});\nusePresenterTextModel({ chatCollect });\nconst dataUrlBytes = (dataUrl) => {\n\tconst match = /^data:([a-z]+\\/[a-z0-9.+-]+);base64,(.+)$/i.exec(String(dataUrl || \"\"));\n\tif (!match) fail(\"Choose a file 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\t\"video/mp4\": \"mp4\",\n\t\"video/webm\": \"webm\",\n\t\"video/quicktime\": \"mov\"\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 = { stillmade };\n\tconst done = (result, made = []) => ({\n\t\t...boardResult(input.board),\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 \"export\": {\n\t\t\t\tconst doc = plain(input.board) ? input.board : fail(\"Build a board first.\");\n\t\t\t\tconst { editorTimeline } = boardResult(doc);\n\t\t\t\tif (!editorTimeline) fail(\"There is nothing to export yet. Build a board first.\");\n\t\t\t\tstillmade.progress(.05, \"Rendering the video\");\n\t\t\t\tconst { asset } = 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: \"final.render\",\n\t\t\t\t\tresultPort: null,\n\t\t\t\t\trequest: {\n\t\t\t\t\t\tschemaVersion: 1,\n\t\t\t\t\t\tkind: \"video\",\n\t\t\t\t\t\ttimeline: renderPlan(editorTimeline, doc.meta?.aspect || \"16:9\"),\n\t\t\t\t\t\tsettings: {\n\t\t\t\t\t\t\tfps: 30,\n\t\t\t\t\t\t\tresolution: 1080,\n\t\t\t\t\t\t\tquality: \"high\"\n\t\t\t\t\t\t},\n\t\t\t\t\t\tsource: {\n\t\t\t\t\t\t\tid: \"sm.board-editor\",\n\t\t\t\t\t\t\tversion: \"3.0.0\"\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\tconst kept = {\n\t\t\t\t\tkind: \"video\",\n\t\t\t\t\tassetId: asset.assetId,\n\t\t\t\t\tversionId: asset.versionId,\n\t\t\t\t\turl: asset.url,\n\t\t\t\t\t...asset.mimeType ? { mimeType: asset.mimeType } : {},\n\t\t\t\t\t...Number(asset.duration) > 0 ? { duration: Number(asset.duration) } : {}\n\t\t\t\t};\n\t\t\t\treturn {\n\t\t\t\t\t...done(kept, [kept]),\n\t\t\t\t\texport: kept\n\t\t\t\t};\n\t\t\t}\n\t\t\tcase \"chat-build\":\n\t\t\t\tstillmade.progress(.1, \"Planning the boards\");\n\t\t\t\treturn done(await planCanvasChatBuild({\n\t\t\t\t\tmessage: request.message,\n\t\t\t\t\tassets: request.assets,\n\t\t\t\t\twords: request.words\n\t\t\t\t}));\n\t\t\tcase \"chat-edit\": return done(await parseCanvasChatEdit({\n\t\t\t\tmessage: request.message,\n\t\t\t\tcanvases: request.canvases\n\t\t\t}));\n\t\t\tcase \"plan-poses\":\n\t\t\t\tstillmade.progress(.1, \"Planning the presenter\");\n\t\t\t\treturn done(await planPresenterPoses({\n\t\t\t\t\tcontent: request.content,\n\t\t\t\t\twords: request.words\n\t\t\t\t}));\n\t\t\tcase \"describe\": {\n\t\t\t\tif (!isImage(input.image)) fail(\"Choose the picture to describe.\");\n\t\t\t\tconst text = await stillmade.hosted.run(\"media.analyze\", {\n\t\t\t\t\tmedia: input.image,\n\t\t\t\t\tquestion: describeImageQuestion(request.hint),\n\t\t\t\t\tinstructions: DESCRIBE_IMAGE_SYSTEM,\n\t\t\t\t\treply: \"text\",\n\t\t\t\t\tmaxTokens: 700\n\t\t\t\t});\n\t\t\t\treturn done(String(text || \"\").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 model = typeof request.model === \"string\" && request.model ? request.model : null;\n\t\t\t\tconst settings = Object.fromEntries(Object.entries({\n\t\t\t\t\tmodel,\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(([key, value]) => typeof value === \"string\" && value && (key === \"model\" || !model || optionIsSupported(\"image\", model, key, 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, or an MP4, WebM or MOV clip.\");\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 \"stock-status\": return done({ configured: 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: request.type === \"video\" ? \"video\" : \"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 \"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 White Board Motion makes yet.`);\n\t} finally {\n\t\tcurrent = null;\n\t}\n}\n\n//#endregion\nexport { run as default };"
|
|
920
|
+
}
|
|
921
|
+
};
|