@vanillaskyai/video 0.8.8 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (173) hide show
  1. package/CHANGELOG.md +42 -0
  2. package/PUBLIC-API.md +5 -8
  3. package/dist/{builtin-server-CUYPIDE7.js → builtin-server-W4PLJUZ5.js} +2 -2
  4. package/dist/{catalog-types-BIhSpOWK.d.ts → catalog-types-WTbLP6Jh.d.ts} +5 -1
  5. package/dist/chapter-title-YRLIQY3V.js +7 -0
  6. package/dist/check-runtime.js +5 -14
  7. package/dist/{chunk-AITKH6QT.js → chunk-2HFO22K2.js} +15 -40
  8. package/dist/chunk-4YM2M62S.js +13 -0
  9. package/dist/chunk-4ZJLPHBV.js +684 -0
  10. package/dist/chunk-77VY4O7A.js +390 -0
  11. package/dist/{chunk-MMUXVA47.js → chunk-7M56IUUX.js} +9 -8
  12. package/dist/chunk-7NZOMTAL.js +63 -0
  13. package/dist/{chunk-2DOLF4QN.js → chunk-AUPC6MDK.js} +12 -14
  14. package/dist/{chunk-352ZZCET.js → chunk-EGVQODKU.js} +2 -2
  15. package/dist/{chunk-2USVB3CY.js → chunk-ELVOT2FQ.js} +284 -177
  16. package/dist/chunk-EWWCQFTI.js +18 -0
  17. package/dist/{chunk-KT3M7KDL.js → chunk-HKUI5BTB.js} +3 -3
  18. package/dist/chunk-IIN5M5HW.js +697 -0
  19. package/dist/{chunk-LMG3GHLL.js → chunk-IQMYK5DX.js} +29 -3
  20. package/dist/{chunk-OWBT45EN.js → chunk-IR44XKBI.js} +1 -1
  21. package/dist/{chunk-MXZSDGZQ.js → chunk-NMFDC2W2.js} +4 -6
  22. package/dist/{chunk-5SLENAJW.js → chunk-PAJ44TFW.js} +1 -2
  23. package/dist/{chunk-L7QGGKJ2.js → chunk-PDQFQIQW.js} +1 -1
  24. package/dist/{chunk-WJ6FLKNC.js → chunk-R3XAOMKP.js} +14 -0
  25. package/dist/{chunk-2OKB27TG.js → chunk-RXTN2CW6.js} +2 -2
  26. package/dist/{chunk-XWWLKRNU.js → chunk-TVIU23OM.js} +38 -49
  27. package/dist/chunk-XX4GXKTX.js +35 -0
  28. package/dist/chunk-Z67Q5KUW.js +16 -0
  29. package/dist/{chunk-3VRMKFM7.js → chunk-ZDJNFA52.js} +11 -24
  30. package/dist/cinema-media-C7OUPNSH.js +12 -0
  31. package/dist/cli.js +18 -9
  32. package/dist/comparison-GNZOR7MF.js +37 -0
  33. package/dist/compose-video-TBFTONUC.js +12 -0
  34. package/dist/editorial-timeline-EMV5335S.js +43 -0
  35. package/dist/{events-BQ6z264n.d.ts → events-B4YCc4vc.d.ts} +1 -1
  36. package/dist/index.d.ts +4 -6
  37. package/dist/index.js +3 -7
  38. package/dist/key-figure-P37VK425.js +30 -0
  39. package/dist/{kit-tQnCPMOM.d.ts → kit-DrRpdn0p.d.ts} +2 -2
  40. package/dist/mobile-message-OF7T62B7.js +50 -0
  41. package/dist/quote-T6WYLN7A.js +33 -0
  42. package/dist/react.d.ts +21 -11
  43. package/dist/react.js +585 -826
  44. package/dist/scene-video-backdrop-PCTARAAJ.js +7 -0
  45. package/dist/server.d.ts +7 -8
  46. package/dist/server.js +179 -84
  47. package/dist/{system-prompt-RRXIWDDD.js → system-prompt-SYRT5DWM.js} +1 -1
  48. package/dist/template-catalog.d.ts +392 -16
  49. package/dist/template-catalog.js +1 -1
  50. package/dist/templates.d.ts +5 -5
  51. package/dist/test.d.ts +3 -3
  52. package/dist/test.js +18 -18
  53. package/dist/text-stream-LD364KBI.js +9 -0
  54. package/dist/{types-DWFO6qca.d.ts → types-CdBmNTGD.d.ts} +1 -1
  55. package/dist/{types-CEh9eUFu.d.ts → types-DdZw4GRQ.d.ts} +17 -48
  56. package/dist/validate-4OUD2CLX.js +10 -0
  57. package/docs/architecture.md +1 -1
  58. package/docs/concepts.md +1 -1
  59. package/docs/custom-templates.md +13 -28
  60. package/docs/customization.md +11 -59
  61. package/docs/getting-started.md +2 -2
  62. package/docs/immersive-interface.md +3 -4
  63. package/docs/maintainers/cinematic-migration.md +38 -0
  64. package/docs/media-and-audio.md +14 -14
  65. package/docs/motion-and-effects.md +6 -14
  66. package/docs/persistence.md +3 -3
  67. package/docs/production.md +11 -9
  68. package/docs/provider-integration.md +9 -16
  69. package/docs/reference/design-system.html +1 -1
  70. package/docs/reference/protocol.md +14 -4
  71. package/docs/testing.md +1 -1
  72. package/package.json +6 -3
  73. package/registry/items/backgrounds.json +1 -1
  74. package/registry/items/chapterTitle.json +80 -0
  75. package/registry/items/cinemaMedia.json +136 -0
  76. package/registry/items/comparison.json +168 -0
  77. package/registry/items/editorialTimeline.json +172 -0
  78. package/registry/items/keyFigure.json +162 -0
  79. package/registry/items/mobileMessage.json +153 -0
  80. package/registry/items/quote.json +161 -0
  81. package/registry/items/template-context.json +1 -1
  82. package/registry/items/theme.json +1 -1
  83. package/starters/video-chat/README.md +24 -26
  84. package/starters/video-chat/package.json +1 -1
  85. package/starters/video-chat/providers/video.ts +6 -5
  86. package/starters/video-chat/stock.ts +35 -151
  87. package/styles/fonts/OFL.txt +93 -0
  88. package/styles/fonts/manifest.json +66 -0
  89. package/styles/fonts/roboto-v51-cyrillic-ext.woff2 +0 -0
  90. package/styles/fonts/roboto-v51-cyrillic.woff2 +0 -0
  91. package/styles/fonts/roboto-v51-greek-ext.woff2 +0 -0
  92. package/styles/fonts/roboto-v51-greek.woff2 +0 -0
  93. package/styles/fonts/roboto-v51-latin-ext.woff2 +0 -0
  94. package/styles/fonts/roboto-v51-latin.woff2 +0 -0
  95. package/styles/fonts/roboto-v51-math.woff2 +0 -0
  96. package/styles/fonts/roboto-v51-symbols.woff2 +0 -0
  97. package/styles/fonts/roboto-v51-vietnamese.woff2 +0 -0
  98. package/styles/fonts/roboto.css +91 -0
  99. package/styles/video-chat.css +30 -22
  100. package/dist/bg-confetti-HITCGLGD.js +0 -89
  101. package/dist/bg-emoji-VU4UZYZN.js +0 -150
  102. package/dist/bg-media-L34PDQXJ.js +0 -106
  103. package/dist/brand-message-FUJ4STFO.js +0 -256
  104. package/dist/chart-bar-EGPHJATL.js +0 -310
  105. package/dist/chart-counter-5FFWQNZO.js +0 -306
  106. package/dist/chart-progress-ring-JMXQLMLC.js +0 -302
  107. package/dist/chunk-4UNKZEAT.js +0 -3575
  108. package/dist/chunk-5CDAM24P.js +0 -31
  109. package/dist/chunk-AOWSXU2K.js +0 -18
  110. package/dist/chunk-CJ7F2CE6.js +0 -104
  111. package/dist/chunk-FRN6WKHA.js +0 -185
  112. package/dist/chunk-G5JPHBX7.js +0 -336
  113. package/dist/chunk-L5BTTCZV.js +0 -97
  114. package/dist/chunk-P22HHFDK.js +0 -43
  115. package/dist/chunk-PP3MCPN4.js +0 -1998
  116. package/dist/chunk-QAAO7OAY.js +0 -19
  117. package/dist/chunk-S7HFLYNN.js +0 -35
  118. package/dist/chunk-W3VDIBGR.js +0 -217
  119. package/dist/chunk-XGRA2MUV.js +0 -242
  120. package/dist/chunk-XTOXFMLM.js +0 -105
  121. package/dist/chunk-YJJC4N4D.js +0 -761
  122. package/dist/compose-video-2NFH4DZY.js +0 -13
  123. package/dist/cta-logo-YR7LYUR5.js +0 -212
  124. package/dist/cta-media-DQJBKUO2.js +0 -221
  125. package/dist/incoming-call-54KQ7O5A.js +0 -323
  126. package/dist/infographic-before-after-ROS52GOW.js +0 -460
  127. package/dist/infographic-feature-list-E7MGUDAN.js +0 -272
  128. package/dist/infographic-problem-solution-3S6NGO5N.js +0 -343
  129. package/dist/infographic-stat-row-SYB7AB7H.js +0 -247
  130. package/dist/infographic-steps-KCE6JWE2.js +0 -406
  131. package/dist/prompt-input-MHX4O42G.js +0 -239
  132. package/dist/reaction-SLEGR3BE.js +0 -122
  133. package/dist/scene-video-backdrop-XFPX4O3I.js +0 -10
  134. package/dist/showcase-code-2HLAVKBM.js +0 -357
  135. package/dist/showcase-phone-Q4HEO4LH.js +0 -278
  136. package/dist/showcase-terminal-DL45LUFG.js +0 -312
  137. package/dist/showcase-web-2QZO73FZ.js +0 -396
  138. package/dist/social-conversation-75SD2637.js +0 -695
  139. package/dist/social-milestone-GEFUQSBF.js +0 -296
  140. package/dist/social-notification-FJ5VHVLK.js +0 -247
  141. package/dist/social-review-stack-KXQCKFRP.js +0 -242
  142. package/dist/social-testimonial-JZ7CHC7S.js +0 -287
  143. package/dist/social-tweet-UCDXM25F.js +0 -298
  144. package/dist/text-stream-54LXABJW.js +0 -10
  145. package/dist/validate-T7GBU2YF.js +0 -8
  146. package/registry/items/barChart.json +0 -245
  147. package/registry/items/beforeAfter.json +0 -180
  148. package/registry/items/bigNumber.json +0 -232
  149. package/registry/items/brandMessage.json +0 -164
  150. package/registry/items/cardList.json +0 -214
  151. package/registry/items/chatMessenger.json +0 -151
  152. package/registry/items/chatWhatsapp.json +0 -151
  153. package/registry/items/codeEditor.json +0 -191
  154. package/registry/items/confetti.json +0 -107
  155. package/registry/items/ctaLogo.json +0 -167
  156. package/registry/items/ctaMedia.json +0 -200
  157. package/registry/items/emojiBurst.json +0 -101
  158. package/registry/items/incomingCall.json +0 -177
  159. package/registry/items/media.json +0 -187
  160. package/registry/items/milestone.json +0 -212
  161. package/registry/items/notification.json +0 -189
  162. package/registry/items/phoneMockup.json +0 -261
  163. package/registry/items/problemSolution.json +0 -193
  164. package/registry/items/progressRing.json +0 -206
  165. package/registry/items/promptInput.json +0 -155
  166. package/registry/items/reaction.json +0 -176
  167. package/registry/items/reviewStack.json +0 -231
  168. package/registry/items/steps.json +0 -215
  169. package/registry/items/terminal.json +0 -219
  170. package/registry/items/testimonial.json +0 -171
  171. package/registry/items/tripleStats.json +0 -235
  172. package/registry/items/tweet.json +0 -210
  173. package/registry/items/webMockup.json +0 -280
@@ -1,106 +0,0 @@
1
- import {
2
- ConfettiLayer
3
- } from "./chunk-CJ7F2CE6.js";
4
- import "./chunk-QAAO7OAY.js";
5
- import {
6
- SceneBackground,
7
- getMediaBackgroundProps
8
- } from "./chunk-MXZSDGZQ.js";
9
- import {
10
- TemplateText
11
- } from "./chunk-YJJC4N4D.js";
12
- import "./chunk-L5BTTCZV.js";
13
- import "./chunk-FRN6WKHA.js";
14
- import "./chunk-W3VDIBGR.js";
15
- import "./chunk-XTOXFMLM.js";
16
- import {
17
- hasSceneMedia
18
- } from "./chunk-224QNWRA.js";
19
- import "./chunk-5CDAM24P.js";
20
- import {
21
- resolveTokens
22
- } from "./chunk-XWWLKRNU.js";
23
-
24
- // src/visual-system/scene-templates/bg-media.tsx
25
- import { jsx, jsxs } from "react/jsx-runtime";
26
- var BgMediaTemplate = ({
27
- variables,
28
- style,
29
- progress,
30
- motionProgress = progress,
31
- beatIntensity,
32
- width,
33
- height,
34
- textArchetype,
35
- backgroundEffect,
36
- safeZone,
37
- sceneDuration,
38
- isPlaying = true
39
- }) => {
40
- const { font, foreground, background } = resolveTokens(style);
41
- const text = foreground;
42
- return /* @__PURE__ */ jsxs(
43
- "div",
44
- {
45
- style: {
46
- width,
47
- height,
48
- backgroundColor: "var(--vanillasky-template-surface, #000)",
49
- position: "relative",
50
- overflow: "hidden",
51
- fontFamily: font
52
- },
53
- children: [
54
- /* @__PURE__ */ jsx(
55
- SceneBackground,
56
- {
57
- style,
58
- progress,
59
- sceneDuration,
60
- width,
61
- height,
62
- ...getMediaBackgroundProps(variables),
63
- textAnchor: "center",
64
- backgroundEffect,
65
- seed: String(variables.texts || ""),
66
- isPlaying,
67
- beatIntensity
68
- }
69
- ),
70
- variables.confetti === true && /* @__PURE__ */ jsx(
71
- ConfettiLayer,
72
- {
73
- progress: motionProgress,
74
- width,
75
- height,
76
- beatIntensity,
77
- bgColor: String(variables.mediaUrl || "").trim() === "" ? background.type === "solid" ? background.color : background.colors[1] : void 0
78
- }
79
- ),
80
- /* @__PURE__ */ jsx(
81
- TemplateText,
82
- {
83
- overMedia: hasSceneMedia(variables),
84
- motionProgress,
85
- typeTreatment: resolveTokens(style).preset.type,
86
- archetype: textArchetype ?? "subtle",
87
- text: String(variables.texts ?? ""),
88
- progress,
89
- sceneDuration: sceneDuration ?? 3,
90
- width,
91
- height,
92
- position: "center",
93
- sizeRole: "headline",
94
- safeZone,
95
- font,
96
- color: text,
97
- beatIntensity
98
- }
99
- )
100
- ]
101
- }
102
- );
103
- };
104
- export {
105
- BgMediaTemplate
106
- };
@@ -1,256 +0,0 @@
1
- import {
2
- stripPipe
3
- } from "./chunk-S7HFLYNN.js";
4
- import {
5
- SceneBackground,
6
- getMediaBackgroundProps
7
- } from "./chunk-MXZSDGZQ.js";
8
- import {
9
- renderWithEmoji
10
- } from "./chunk-L5BTTCZV.js";
11
- import "./chunk-FRN6WKHA.js";
12
- import "./chunk-W3VDIBGR.js";
13
- import {
14
- interpolate
15
- } from "./chunk-XTOXFMLM.js";
16
- import "./chunk-224QNWRA.js";
17
- import "./chunk-5CDAM24P.js";
18
- import "./chunk-XWWLKRNU.js";
19
-
20
- // src/visual-system/primitives/typography/BrandMessageBubble.tsx
21
- import { Fragment, jsx, jsxs } from "react/jsx-runtime";
22
- var CLAMP = { extrapolateLeft: "clamp", extrapolateRight: "clamp" };
23
- var BUBBLE_BG = "rgba(245,242,238,0.92)";
24
- var BUBBLE_TEXT = "#1c1c1e";
25
- var DOT_COLOR = "#8C8C92";
26
- function easeOutBack(t) {
27
- const c1 = 1.70158;
28
- const c3 = c1 + 1;
29
- return 1 + c3 * Math.pow(t - 1, 3) + c1 * Math.pow(t - 1, 2);
30
- }
31
- var TAIL_WITH_EMOJI = /(\S+)(\s+)([\p{Extended_Pictographic}\p{Emoji_Modifier}\u{FE0E}\u{FE0F}\u{200D}]+)\s*$/u;
32
- function renderMessageWithEmojiTail(text, fontSizePx) {
33
- const match = TAIL_WITH_EMOJI.exec(text);
34
- if (!match || match.index === void 0) {
35
- return renderWithEmoji(text, fontSizePx);
36
- }
37
- const [, lastWord, space, emoji] = match;
38
- const leading = text.slice(0, match.index);
39
- return /* @__PURE__ */ jsxs(Fragment, { children: [
40
- renderWithEmoji(leading, fontSizePx),
41
- /* @__PURE__ */ jsxs("span", { style: { whiteSpace: "nowrap" }, children: [
42
- lastWord,
43
- space,
44
- renderWithEmoji(emoji, fontSizePx)
45
- ] })
46
- ] });
47
- }
48
- function popIn(t, start, dur = 0.4) {
49
- if (t <= start) return 0;
50
- if (t >= start + dur) return 1;
51
- return easeOutBack((t - start) / dur);
52
- }
53
- var BrandMessageBubble = ({
54
- progress,
55
- sceneDuration,
56
- brandName: rawBrandName,
57
- message: rawMessage,
58
- width,
59
- height,
60
- safeZone
61
- }) => {
62
- const isLandscape = width > height;
63
- const s = isLandscape ? Math.min(width, height) / 534 * 1.3 : width / 534;
64
- const brandName = stripPipe(rawBrandName);
65
- const message = stripPipe(rawMessage);
66
- const realTimeSeconds = progress * sceneDuration;
67
- const typingStart = 0.1;
68
- const bubbleStart = 0.38;
69
- const typingPop = popIn(progress, typingStart, 0.1);
70
- const typingFade = interpolate(progress, [bubbleStart - 0.06, bubbleStart], [1, 0], CLAMP);
71
- const showTyping = progress >= typingStart && progress < bubbleStart;
72
- const bubblePop = popIn(progress, bubbleStart, 0.18);
73
- const showBubble = progress >= bubbleStart;
74
- const topPad = Math.max(safeZone.top, height * 0.25);
75
- const sidePad = Math.max(safeZone.left, width * 0.06);
76
- return /* @__PURE__ */ jsxs(
77
- "div",
78
- {
79
- style: {
80
- position: "absolute",
81
- top: topPad,
82
- left: sidePad,
83
- right: sidePad,
84
- display: "flex",
85
- justifyContent: "flex-end"
86
- },
87
- children: [
88
- showTyping && /* @__PURE__ */ jsx(
89
- "div",
90
- {
91
- style: {
92
- opacity: typingPop * typingFade,
93
- transform: `translateY(${(1 - typingPop) * 8 * s}px)`,
94
- background: BUBBLE_BG,
95
- borderRadius: 18 * s,
96
- padding: `${12 * s}px ${16 * s}px`,
97
- display: "flex",
98
- gap: 5 * s,
99
- alignItems: "center",
100
- boxShadow: `0 ${1 * s}px ${4 * s}px rgba(0,0,0,0.10)`
101
- },
102
- children: [0, 1, 2].map((j) => {
103
- const phase = (realTimeSeconds * 1.6 + j * 0.2) % 1;
104
- const y = Math.sin(phase * Math.PI * 2) * 2.5 * s;
105
- const op = 0.45 + 0.55 * Math.max(0, Math.sin(phase * Math.PI));
106
- return /* @__PURE__ */ jsx(
107
- "div",
108
- {
109
- style: {
110
- width: 7 * s,
111
- height: 7 * s,
112
- borderRadius: 3.5 * s,
113
- background: DOT_COLOR,
114
- transform: `translateY(${-y}px)`,
115
- opacity: op
116
- }
117
- },
118
- j
119
- );
120
- })
121
- }
122
- ),
123
- showBubble && /* @__PURE__ */ jsxs(
124
- "div",
125
- {
126
- style: {
127
- // `width: max-content` forces the bubble to size to its
128
- // natural one-line content width up to `maxWidth`. Without
129
- // this, modern-screenshot's foreignObject text shaping (the
130
- // export path) was using an intrinsic width well below
131
- // `maxWidth`, breaking text that would have fit on one line
132
- // in the live DOM — even after the NBSP fix glued the
133
- // trailing emoji to the last word. With `max-content` +
134
- // `maxWidth`, the bubble grows up to the cap on a single
135
- // line, then wraps naturally inside the cap for genuinely
136
- // long messages.
137
- width: "max-content",
138
- maxWidth: width * 0.86,
139
- // Render with native system fonts in BOTH paths. The export
140
- // pipeline turns the iframe DOM into an SVG and loads it via
141
- // <img src="data:image/svg+xml,…">, and SVG-as-image is a
142
- // sandboxed graphics context that does NOT load @font-face
143
- // resources (data: or otherwise — this is a browser security
144
- // model, not a CSP issue). Inter therefore never resolves in
145
- // the export; the SVG falls back to Helvetica/Helvetica Neue,
146
- // which is wider at the same point size, and "We built this
147
- // for you ❤️" wraps inside the pinned bubble box even though
148
- // the iframe's Inter rendering fit on one line. Naming the
149
- // system font explicitly here makes the iframe ALSO use that
150
- // same OS-native font, so preview and export compute identical
151
- // widths and both fit on one line. See PRs #598/#599/#604 for
152
- // the months of font-embed work that this finally closes out.
153
- fontFamily: '"Helvetica Neue", Helvetica, Arial, sans-serif',
154
- background: BUBBLE_BG,
155
- color: BUBBLE_TEXT,
156
- borderRadius: `${22 * s}px ${22 * s}px 0 ${22 * s}px`,
157
- padding: `${14 * s}px ${18 * s}px ${12 * s}px`,
158
- fontSize: 23 * s,
159
- lineHeight: `${29 * s}px`,
160
- fontWeight: 400,
161
- opacity: bubblePop,
162
- transform: `translateY(${(1 - bubblePop) * 8 * s}px) scale(${0.96 + 0.04 * bubblePop})`,
163
- transformOrigin: "right top",
164
- boxShadow: `0 ${2 * s}px ${10 * s}px rgba(0,0,0,0.14)`
165
- },
166
- children: [
167
- /* @__PURE__ */ jsx(
168
- "div",
169
- {
170
- style: {
171
- fontSize: 14 * s,
172
- fontStyle: "italic",
173
- fontWeight: 400,
174
- color: "rgba(0,0,0,0.45)",
175
- lineHeight: 1.2,
176
- marginBottom: 6 * s
177
- },
178
- children: brandName
179
- }
180
- ),
181
- renderMessageWithEmojiTail(message, 23 * s)
182
- ]
183
- }
184
- )
185
- ]
186
- }
187
- );
188
- };
189
-
190
- // src/visual-system/scene-templates/brand-message.tsx
191
- import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
192
- var BrandMessageTemplate = ({
193
- variables,
194
- style,
195
- progress,
196
- beatIntensity,
197
- width,
198
- height,
199
- sceneDuration,
200
- isPlaying = true,
201
- safeZone,
202
- backgroundEffect
203
- }) => {
204
- const brandName = stripPipe(style.brand.name ?? "Your brand");
205
- const message = stripPipe(String(variables.message || ""));
206
- const seed = (brandName + message).split("").reduce((acc, c) => acc + c.charCodeAt(0), 0);
207
- return /* @__PURE__ */ jsxs2(
208
- "div",
209
- {
210
- style: {
211
- width,
212
- height,
213
- backgroundColor: "var(--vanillasky-template-surface, #000)",
214
- position: "relative",
215
- overflow: "hidden",
216
- // System fonts only — see BrandMessageBubble for the why
217
- // (SVG-as-image can't load @font-face data: URLs, so the only
218
- // way to get preview/export parity is to use a font the OS
219
- // already has natively).
220
- fontFamily: '"Helvetica Neue", Helvetica, Arial, sans-serif'
221
- },
222
- children: [
223
- /* @__PURE__ */ jsx2(
224
- SceneBackground,
225
- {
226
- style,
227
- progress,
228
- sceneDuration,
229
- width,
230
- height,
231
- ...getMediaBackgroundProps(variables),
232
- backgroundEffect,
233
- seed,
234
- isPlaying,
235
- beatIntensity
236
- }
237
- ),
238
- /* @__PURE__ */ jsx2(
239
- BrandMessageBubble,
240
- {
241
- progress,
242
- sceneDuration: sceneDuration ?? 4,
243
- brandName,
244
- message,
245
- width,
246
- height,
247
- safeZone
248
- }
249
- )
250
- ]
251
- }
252
- );
253
- };
254
- export {
255
- BrandMessageTemplate
256
- };
@@ -1,310 +0,0 @@
1
- import {
2
- SceneBackground,
3
- getMediaBackgroundProps
4
- } from "./chunk-MXZSDGZQ.js";
5
- import {
6
- TemplateText
7
- } from "./chunk-YJJC4N4D.js";
8
- import "./chunk-L5BTTCZV.js";
9
- import "./chunk-FRN6WKHA.js";
10
- import {
11
- TOP_TEXT_AREA_RATIO,
12
- withOpacity
13
- } from "./chunk-W3VDIBGR.js";
14
- import {
15
- SPRING_SNAPPY,
16
- interpolate,
17
- spring
18
- } from "./chunk-XTOXFMLM.js";
19
- import {
20
- hasSceneMedia
21
- } from "./chunk-224QNWRA.js";
22
- import "./chunk-5CDAM24P.js";
23
- import {
24
- resolveTokens
25
- } from "./chunk-XWWLKRNU.js";
26
-
27
- // src/visual-system/primitives/charts/BarChart.tsx
28
- import { Fragment, jsx, jsxs } from "react/jsx-runtime";
29
- var MAX_BAR_ITEMS = 6;
30
- function exactValue(value) {
31
- return String(value);
32
- }
33
- var BarChart = ({
34
- progress,
35
- data,
36
- width,
37
- height,
38
- chartColor = "#ffffff",
39
- textColor = "#ffffff",
40
- beatIntensity = 0
41
- }) => {
42
- const values = data.filter(({ value }) => Number.isFinite(value)).slice(0, MAX_BAR_ITEMS);
43
- const s = Math.min(width, height) / 1080;
44
- const portrait = height > width;
45
- const chartWidth = width * (portrait ? 0.88 : 0.84);
46
- const chartHeight = height * (portrait ? 0.56 : 0.52);
47
- const bottom = (portrait ? 112 : 60) * s;
48
- const labelHeight = (portrait ? 94 : 66) * s;
49
- const valueReserve = (portrait ? 52 : 44) * s;
50
- const maxBarHeight = chartHeight - labelHeight - valueReserve;
51
- const gap = (portrait ? 14 : 20) * s;
52
- const barCount = Math.max(values.length, 1);
53
- const itemWidth = (chartWidth - gap * (barCount - 1)) / barCount;
54
- const barWidth = Math.max(itemWidth * 0.68, 2 * s);
55
- const maxValue = Math.max(1, ...values.map(({ value }) => Math.max(0, value)));
56
- const beatScale = 1 + beatIntensity * 0.03;
57
- return /* @__PURE__ */ jsxs(Fragment, { children: [
58
- /* @__PURE__ */ jsx(
59
- "div",
60
- {
61
- role: "img",
62
- "aria-label": values.map(({ label, value }) => `${label || "Value"}: ${exactValue(value)}`).join(", "),
63
- style: {
64
- position: "absolute",
65
- bottom,
66
- left: (width - chartWidth) / 2,
67
- width: chartWidth,
68
- height: chartHeight,
69
- display: "flex",
70
- alignItems: "flex-end",
71
- gap
72
- },
73
- children: values.map(({ label, value }, index) => {
74
- const barStart = 0.06 + index * 0.05;
75
- const barProgress = interpolate(progress, [barStart, barStart + 0.34], [0, 1], {
76
- extrapolateLeft: "clamp",
77
- extrapolateRight: "clamp"
78
- });
79
- const springValue = spring(barProgress, SPRING_SNAPPY);
80
- const targetHeight = Math.max(0, value) / maxValue * maxBarHeight;
81
- return /* @__PURE__ */ jsxs(
82
- "div",
83
- {
84
- "data-bar-chart-item": "true",
85
- style: {
86
- width: itemWidth,
87
- height: chartHeight,
88
- display: "flex",
89
- flexDirection: "column",
90
- justifyContent: "flex-end",
91
- alignItems: "center",
92
- minWidth: 0
93
- },
94
- children: [
95
- /* @__PURE__ */ jsx(
96
- "div",
97
- {
98
- style: {
99
- width: "100%",
100
- height: maxBarHeight + valueReserve,
101
- display: "flex",
102
- alignItems: "flex-end",
103
- justifyContent: "center"
104
- },
105
- children: /* @__PURE__ */ jsx(
106
- "div",
107
- {
108
- style: {
109
- position: "relative",
110
- width: barWidth,
111
- height: springValue * targetHeight,
112
- background: `linear-gradient(to top, ${withOpacity(chartColor, 0.82)}, ${withOpacity(chartColor, 0.42)})`,
113
- border: `1px solid ${withOpacity(chartColor, 0.7)}`,
114
- borderRadius: `${10 * s}px ${10 * s}px 0 0`,
115
- boxShadow: `0 0 ${24 * s}px ${withOpacity(chartColor, 0.18)}`,
116
- transform: `scaleY(${beatScale})`,
117
- transformOrigin: "bottom"
118
- },
119
- children: /* @__PURE__ */ jsx(
120
- "div",
121
- {
122
- "data-bar-chart-value": "true",
123
- style: {
124
- position: "absolute",
125
- bottom: "100%",
126
- left: "50%",
127
- transform: `translate(-50%, ${-10 * s}px)`,
128
- color: textColor,
129
- fontSize: (portrait ? 34 : 30) * s,
130
- lineHeight: 1,
131
- fontWeight: 750,
132
- fontVariantNumeric: "tabular-nums",
133
- whiteSpace: "nowrap",
134
- opacity: barProgress,
135
- textShadow: `0 ${2 * s}px ${8 * s}px rgba(0,0,0,0.55)`
136
- },
137
- children: exactValue(value)
138
- }
139
- )
140
- }
141
- )
142
- }
143
- ),
144
- /* @__PURE__ */ jsx(
145
- "div",
146
- {
147
- "data-bar-chart-label": "true",
148
- style: {
149
- width: "100%",
150
- height: labelHeight,
151
- paddingTop: 14 * s,
152
- boxSizing: "border-box",
153
- color: withOpacity(textColor, 0.9),
154
- fontSize: (portrait ? 24 : 22) * s,
155
- lineHeight: 1.15,
156
- fontWeight: 650,
157
- textAlign: "center",
158
- overflow: "hidden",
159
- overflowWrap: "anywhere",
160
- opacity: barProgress
161
- },
162
- children: label
163
- }
164
- )
165
- ]
166
- },
167
- `${label}-${index}`
168
- );
169
- })
170
- }
171
- ),
172
- /* @__PURE__ */ jsx(
173
- "div",
174
- {
175
- style: {
176
- position: "absolute",
177
- bottom: 0,
178
- left: 0,
179
- right: 0,
180
- height: chartHeight * 0.7,
181
- background: `linear-gradient(to top, ${withOpacity(chartColor, 0.07)}, transparent)`,
182
- pointerEvents: "none"
183
- }
184
- }
185
- )
186
- ] });
187
- };
188
-
189
- // src/visual-system/scene-templates/chart-bar.tsx
190
- import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
191
- function parseBarDatum(value) {
192
- if (typeof value === "number") {
193
- return Number.isFinite(value) ? { label: "", value } : void 0;
194
- }
195
- if (typeof value === "object" && value !== null) {
196
- const datum = value;
197
- const numberValue2 = Number(datum.value);
198
- if (!Number.isFinite(numberValue2)) return void 0;
199
- return { label: String(datum.label ?? "").trim(), value: numberValue2 };
200
- }
201
- if (typeof value !== "string") return void 0;
202
- const trimmed = value.trim();
203
- if (!trimmed) return void 0;
204
- const separator = trimmed.lastIndexOf(":");
205
- const label = separator >= 0 ? trimmed.slice(0, separator).trim() : "";
206
- const numberValue = Number(separator >= 0 ? trimmed.slice(separator + 1).trim() : trimmed);
207
- return Number.isFinite(numberValue) ? { label, value: numberValue } : void 0;
208
- }
209
- function parseBarData(value) {
210
- let items;
211
- if (Array.isArray(value)) {
212
- items = value;
213
- } else if (typeof value === "string") {
214
- const trimmed = value.trim();
215
- if (!trimmed) return [];
216
- try {
217
- const parsed = JSON.parse(trimmed);
218
- items = Array.isArray(parsed) ? parsed : [trimmed];
219
- } catch {
220
- items = trimmed.split(",");
221
- }
222
- } else {
223
- items = [value];
224
- }
225
- return items.map(parseBarDatum).filter((datum) => datum !== void 0);
226
- }
227
- var ChartBarTemplate = ({
228
- variables,
229
- style,
230
- progress,
231
- motionProgress = progress,
232
- beatIntensity,
233
- width,
234
- height,
235
- safeZone,
236
- sceneDuration,
237
- backgroundEffect,
238
- isPlaying = true
239
- }) => {
240
- const { primary, foreground, font } = resolveTokens(style);
241
- const chartColor = primary;
242
- const textColor = foreground;
243
- const textsRaw = String(variables.texts || "");
244
- const data = parseBarData(variables.bars);
245
- return /* @__PURE__ */ jsxs2(
246
- "div",
247
- {
248
- style: {
249
- width,
250
- height,
251
- backgroundColor: "var(--vanillasky-template-surface, #000)",
252
- position: "relative",
253
- overflow: "hidden",
254
- fontFamily: font
255
- },
256
- children: [
257
- /* @__PURE__ */ jsx2(
258
- SceneBackground,
259
- {
260
- style,
261
- progress,
262
- sceneDuration,
263
- width,
264
- height,
265
- ...getMediaBackgroundProps(variables),
266
- backgroundEffect,
267
- seed: textsRaw,
268
- isPlaying,
269
- beatIntensity
270
- }
271
- ),
272
- /* @__PURE__ */ jsx2(
273
- BarChart,
274
- {
275
- progress,
276
- data,
277
- width,
278
- height,
279
- chartColor,
280
- textColor,
281
- beatIntensity
282
- }
283
- ),
284
- /* @__PURE__ */ jsx2("div", { style: { position: "absolute", top: 0, left: 0, right: 0, height: height * TOP_TEXT_AREA_RATIO, overflow: "visible" }, children: /* @__PURE__ */ jsx2(
285
- TemplateText,
286
- {
287
- overMedia: hasSceneMedia(variables),
288
- motionProgress,
289
- typeTreatment: resolveTokens(style).preset.type,
290
- archetype: "subtle",
291
- text: String(variables.texts ?? ""),
292
- progress,
293
- sceneDuration: sceneDuration ?? 3,
294
- width,
295
- height,
296
- position: "top",
297
- sizeRole: "headline",
298
- safeZone,
299
- font,
300
- color: textColor,
301
- beatIntensity
302
- }
303
- ) })
304
- ]
305
- }
306
- );
307
- };
308
- export {
309
- ChartBarTemplate
310
- };