@vanillaskyai/video 0.8.8 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (175) hide show
  1. package/CHANGELOG.md +30 -0
  2. package/PUBLIC-API.md +5 -8
  3. package/dist/{builtin-server-CUYPIDE7.js → builtin-server-HW6HGXCZ.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 +6 -15
  7. package/dist/{chunk-2USVB3CY.js → chunk-3ZTEFJIR.js} +285 -178
  8. package/dist/chunk-4YM2M62S.js +13 -0
  9. package/dist/chunk-77VY4O7A.js +390 -0
  10. package/dist/{chunk-MMUXVA47.js → chunk-7M56IUUX.js} +9 -8
  11. package/dist/chunk-7NZOMTAL.js +63 -0
  12. package/dist/{chunk-2DOLF4QN.js → chunk-AUPC6MDK.js} +12 -14
  13. package/dist/{chunk-352ZZCET.js → chunk-EGVQODKU.js} +2 -2
  14. package/dist/chunk-EWWCQFTI.js +18 -0
  15. package/dist/{chunk-MXZSDGZQ.js → chunk-G7IZBBWF.js} +14 -9
  16. package/dist/{chunk-KT3M7KDL.js → chunk-HKUI5BTB.js} +3 -3
  17. package/dist/{chunk-LMG3GHLL.js → chunk-IQMYK5DX.js} +29 -3
  18. package/dist/chunk-LH4BPALA.js +564 -0
  19. package/dist/{chunk-OWBT45EN.js → chunk-MQILEEXC.js} +1 -1
  20. package/dist/chunk-MXEYPK7M.js +552 -0
  21. package/dist/{chunk-AITKH6QT.js → chunk-OR52UMSF.js} +13 -39
  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-224QNWRA.js → chunk-UDIODEDK.js} +1 -5
  28. package/dist/{chunk-3VRMKFM7.js → chunk-ZDJNFA52.js} +11 -24
  29. package/dist/cinema-media-YQHSIFDA.js +11 -0
  30. package/dist/cli.js +18 -9
  31. package/dist/comparison-RZMMHZR2.js +27 -0
  32. package/dist/compose-video-TBFTONUC.js +12 -0
  33. package/dist/editorial-timeline-OZX7OS6G.js +36 -0
  34. package/dist/{events-BQ6z264n.d.ts → events-B4YCc4vc.d.ts} +1 -1
  35. package/dist/focus-cards-TJ72BT7U.js +20 -0
  36. package/dist/index.d.ts +4 -6
  37. package/dist/index.js +3 -7
  38. package/dist/key-figure-GYENXKH3.js +20 -0
  39. package/dist/{kit-tQnCPMOM.d.ts → kit-DrRpdn0p.d.ts} +2 -2
  40. package/dist/mobile-message-UZUPIKHD.js +49 -0
  41. package/dist/{preload-media-LJXWKTWG.js → preload-media-CFTZIMZL.js} +1 -1
  42. package/dist/quote-EW5HQA6H.js +23 -0
  43. package/dist/react.d.ts +21 -11
  44. package/dist/react.js +590 -833
  45. package/dist/scene-video-backdrop-PCTARAAJ.js +7 -0
  46. package/dist/server.d.ts +7 -8
  47. package/dist/server.js +91 -74
  48. package/dist/{system-prompt-RRXIWDDD.js → system-prompt-SYRT5DWM.js} +1 -1
  49. package/dist/template-catalog.d.ts +257 -16
  50. package/dist/template-catalog.js +1 -1
  51. package/dist/templates.d.ts +5 -5
  52. package/dist/test.d.ts +3 -3
  53. package/dist/test.js +18 -18
  54. package/dist/text-stream-LD364KBI.js +9 -0
  55. package/dist/{types-DWFO6qca.d.ts → types-CdBmNTGD.d.ts} +1 -1
  56. package/dist/{types-CEh9eUFu.d.ts → types-DdZw4GRQ.d.ts} +17 -48
  57. package/dist/validate-4OUD2CLX.js +10 -0
  58. package/docs/architecture.md +1 -1
  59. package/docs/concepts.md +1 -1
  60. package/docs/custom-templates.md +13 -28
  61. package/docs/customization.md +11 -59
  62. package/docs/getting-started.md +2 -2
  63. package/docs/immersive-interface.md +3 -4
  64. package/docs/maintainers/cinematic-migration.md +34 -0
  65. package/docs/media-and-audio.md +14 -14
  66. package/docs/motion-and-effects.md +6 -14
  67. package/docs/persistence.md +3 -3
  68. package/docs/production.md +11 -9
  69. package/docs/provider-integration.md +9 -16
  70. package/docs/reference/design-system.html +1 -1
  71. package/docs/reference/protocol.md +14 -4
  72. package/docs/testing.md +1 -1
  73. package/package.json +6 -3
  74. package/registry/items/backgrounds.json +1 -1
  75. package/registry/items/chapterTitle.json +80 -0
  76. package/registry/items/cinemaMedia.json +136 -0
  77. package/registry/items/comparison.json +101 -0
  78. package/registry/items/editorialTimeline.json +105 -0
  79. package/registry/items/focusCards.json +90 -0
  80. package/registry/items/keyFigure.json +97 -0
  81. package/registry/items/mobileMessage.json +153 -0
  82. package/registry/items/quote.json +94 -0
  83. package/registry/items/template-context.json +1 -1
  84. package/registry/items/theme.json +1 -1
  85. package/starters/video-chat/README.md +24 -26
  86. package/starters/video-chat/package.json +1 -1
  87. package/starters/video-chat/providers/video.ts +6 -5
  88. package/starters/video-chat/stock.ts +35 -151
  89. package/styles/fonts/OFL.txt +93 -0
  90. package/styles/fonts/manifest.json +66 -0
  91. package/styles/fonts/roboto-v51-cyrillic-ext.woff2 +0 -0
  92. package/styles/fonts/roboto-v51-cyrillic.woff2 +0 -0
  93. package/styles/fonts/roboto-v51-greek-ext.woff2 +0 -0
  94. package/styles/fonts/roboto-v51-greek.woff2 +0 -0
  95. package/styles/fonts/roboto-v51-latin-ext.woff2 +0 -0
  96. package/styles/fonts/roboto-v51-latin.woff2 +0 -0
  97. package/styles/fonts/roboto-v51-math.woff2 +0 -0
  98. package/styles/fonts/roboto-v51-symbols.woff2 +0 -0
  99. package/styles/fonts/roboto-v51-vietnamese.woff2 +0 -0
  100. package/styles/fonts/roboto.css +91 -0
  101. package/styles/video-chat.css +30 -22
  102. package/dist/bg-confetti-HITCGLGD.js +0 -89
  103. package/dist/bg-emoji-VU4UZYZN.js +0 -150
  104. package/dist/bg-media-L34PDQXJ.js +0 -106
  105. package/dist/brand-message-FUJ4STFO.js +0 -256
  106. package/dist/chart-bar-EGPHJATL.js +0 -310
  107. package/dist/chart-counter-5FFWQNZO.js +0 -306
  108. package/dist/chart-progress-ring-JMXQLMLC.js +0 -302
  109. package/dist/chunk-4UNKZEAT.js +0 -3575
  110. package/dist/chunk-5CDAM24P.js +0 -31
  111. package/dist/chunk-AOWSXU2K.js +0 -18
  112. package/dist/chunk-CJ7F2CE6.js +0 -104
  113. package/dist/chunk-FRN6WKHA.js +0 -185
  114. package/dist/chunk-G5JPHBX7.js +0 -336
  115. package/dist/chunk-L5BTTCZV.js +0 -97
  116. package/dist/chunk-P22HHFDK.js +0 -43
  117. package/dist/chunk-PP3MCPN4.js +0 -1998
  118. package/dist/chunk-QAAO7OAY.js +0 -19
  119. package/dist/chunk-S7HFLYNN.js +0 -35
  120. package/dist/chunk-W3VDIBGR.js +0 -217
  121. package/dist/chunk-XGRA2MUV.js +0 -242
  122. package/dist/chunk-XTOXFMLM.js +0 -105
  123. package/dist/chunk-YJJC4N4D.js +0 -761
  124. package/dist/compose-video-2NFH4DZY.js +0 -13
  125. package/dist/cta-logo-YR7LYUR5.js +0 -212
  126. package/dist/cta-media-DQJBKUO2.js +0 -221
  127. package/dist/incoming-call-54KQ7O5A.js +0 -323
  128. package/dist/infographic-before-after-ROS52GOW.js +0 -460
  129. package/dist/infographic-feature-list-E7MGUDAN.js +0 -272
  130. package/dist/infographic-problem-solution-3S6NGO5N.js +0 -343
  131. package/dist/infographic-stat-row-SYB7AB7H.js +0 -247
  132. package/dist/infographic-steps-KCE6JWE2.js +0 -406
  133. package/dist/prompt-input-MHX4O42G.js +0 -239
  134. package/dist/reaction-SLEGR3BE.js +0 -122
  135. package/dist/scene-video-backdrop-XFPX4O3I.js +0 -10
  136. package/dist/showcase-code-2HLAVKBM.js +0 -357
  137. package/dist/showcase-phone-Q4HEO4LH.js +0 -278
  138. package/dist/showcase-terminal-DL45LUFG.js +0 -312
  139. package/dist/showcase-web-2QZO73FZ.js +0 -396
  140. package/dist/social-conversation-75SD2637.js +0 -695
  141. package/dist/social-milestone-GEFUQSBF.js +0 -296
  142. package/dist/social-notification-FJ5VHVLK.js +0 -247
  143. package/dist/social-review-stack-KXQCKFRP.js +0 -242
  144. package/dist/social-testimonial-JZ7CHC7S.js +0 -287
  145. package/dist/social-tweet-UCDXM25F.js +0 -298
  146. package/dist/text-stream-54LXABJW.js +0 -10
  147. package/dist/validate-T7GBU2YF.js +0 -8
  148. package/registry/items/barChart.json +0 -245
  149. package/registry/items/beforeAfter.json +0 -180
  150. package/registry/items/bigNumber.json +0 -232
  151. package/registry/items/brandMessage.json +0 -164
  152. package/registry/items/cardList.json +0 -214
  153. package/registry/items/chatMessenger.json +0 -151
  154. package/registry/items/chatWhatsapp.json +0 -151
  155. package/registry/items/codeEditor.json +0 -191
  156. package/registry/items/confetti.json +0 -107
  157. package/registry/items/ctaLogo.json +0 -167
  158. package/registry/items/ctaMedia.json +0 -200
  159. package/registry/items/emojiBurst.json +0 -101
  160. package/registry/items/incomingCall.json +0 -177
  161. package/registry/items/media.json +0 -187
  162. package/registry/items/milestone.json +0 -212
  163. package/registry/items/notification.json +0 -189
  164. package/registry/items/phoneMockup.json +0 -261
  165. package/registry/items/problemSolution.json +0 -193
  166. package/registry/items/progressRing.json +0 -206
  167. package/registry/items/promptInput.json +0 -155
  168. package/registry/items/reaction.json +0 -176
  169. package/registry/items/reviewStack.json +0 -231
  170. package/registry/items/steps.json +0 -215
  171. package/registry/items/terminal.json +0 -219
  172. package/registry/items/testimonial.json +0 -171
  173. package/registry/items/tripleStats.json +0 -235
  174. package/registry/items/tweet.json +0 -210
  175. package/registry/items/webMockup.json +0 -280
@@ -1,695 +0,0 @@
1
- import {
2
- stripPipe
3
- } from "./chunk-S7HFLYNN.js";
4
- import {
5
- renderWithEmoji
6
- } from "./chunk-L5BTTCZV.js";
7
- import {
8
- interpolate
9
- } from "./chunk-XTOXFMLM.js";
10
-
11
- // src/visual-system/scene-templates/normalize-var.ts
12
- function normalizeTextVar(raw) {
13
- if (typeof raw === "string") {
14
- const trimmed = raw.trim();
15
- if (trimmed.startsWith("{")) {
16
- try {
17
- const obj = JSON.parse(trimmed);
18
- if (typeof obj === "object" && obj !== null) {
19
- return extractTextFromObject(obj);
20
- }
21
- } catch {
22
- }
23
- }
24
- return raw;
25
- }
26
- if (typeof raw === "object" && raw !== null) {
27
- return extractTextFromObject(raw);
28
- }
29
- return String(raw || "");
30
- }
31
- function extractTextFromObject(obj) {
32
- const text = String(
33
- obj.text || obj.message || obj.body || obj.content || ""
34
- );
35
- const side = String(obj.side || obj.direction || "").toLowerCase();
36
- if (side === "in" || side === "left" || side === "incoming" || side === "received") {
37
- return text + "|in";
38
- }
39
- if (side === "out" || side === "right" || side === "outgoing" || side === "sent") {
40
- return text + "|out";
41
- }
42
- return text;
43
- }
44
-
45
- // src/visual-system/primitives/social/ConversationThread.tsx
46
- import * as React from "react";
47
- import { jsx, jsxs } from "react/jsx-runtime";
48
- var CLAMP = {
49
- extrapolateLeft: "clamp",
50
- extrapolateRight: "clamp"
51
- };
52
- var REF_DURATION = 16;
53
- function easeOutBack(t) {
54
- const c1 = 1.70158;
55
- const c3 = c1 + 1;
56
- return 1 + c3 * Math.pow(t - 1, 3) + c1 * Math.pow(t - 1, 2);
57
- }
58
- var WA = {
59
- bg: "#EFE7DC",
60
- incomingBubble: "#FFFFFF",
61
- outgoingBubble: "#D9F4C7",
62
- text: "#0E0E0E",
63
- textMuted: "#6E6E73",
64
- accent: "#0A8F76",
65
- chipBg: "#F1E9D8",
66
- chipText: "#3C342A",
67
- navBg: "#F1E9DA",
68
- inputBg: "#FFFFFF",
69
- inputBorder: "rgba(0,0,0,0.06)",
70
- outgoingTime: "#5C6B4E"
71
- };
72
- var IM = {
73
- bg: "#ffffff",
74
- bubbleOut: "#007AFF",
75
- bubbleIn: "#E9E9EB",
76
- textOut: "#ffffff",
77
- textIn: "#000000",
78
- dotsColor: "#8E8E93"
79
- };
80
- var WA_TIMING_5 = [
81
- { typingStart: 0.6, bubbleStart: 1.4, time: "21:54" },
82
- { typingStart: 2.2, bubbleStart: 3, time: "21:55" },
83
- { typingStart: 3.8, bubbleStart: 4.8, time: "21:56" },
84
- { typingStart: 6.2, bubbleStart: 7.2, time: "12:35" },
85
- { typingStart: 10, bubbleStart: 11, time: "11:17" }
86
- ];
87
- function timingForCount(count) {
88
- if (count >= 5) return WA_TIMING_5.slice(0, count);
89
- const slot = 12 / count;
90
- const out = [];
91
- for (let i = 0; i < count; i++) {
92
- const start = 0.6 + i * slot;
93
- out.push({
94
- typingStart: start,
95
- bubbleStart: start + slot * 0.5,
96
- time: WA_TIMING_5[Math.min(i, 4)].time
97
- });
98
- }
99
- return out;
100
- }
101
- function tickStateAt(refTimeSinceSent) {
102
- if (refTimeSinceSent < 0.5) return "clock";
103
- if (refTimeSinceSent < 1.1) return "sent";
104
- if (refTimeSinceSent < 1.8) return "delivered";
105
- return "read";
106
- }
107
- var ClockIcon = ({ s }) => /* @__PURE__ */ jsxs("svg", { width: 12 * s, height: 12 * s, viewBox: "0 0 12 12", style: { marginLeft: 4 * s }, children: [
108
- /* @__PURE__ */ jsx("circle", { cx: "6", cy: "6", r: "5", fill: "none", stroke: "#8C8C92", strokeWidth: "1.2" }),
109
- /* @__PURE__ */ jsx("path", { d: "M6 3 v3.5 l2 1", stroke: "#8C8C92", strokeWidth: "1.2", fill: "none", strokeLinecap: "round" })
110
- ] });
111
- var Ticks = ({ state, s }) => {
112
- if (state === "clock") return /* @__PURE__ */ jsx(ClockIcon, { s });
113
- const color = state === "read" ? "#53BDEB" : "#8C8C92";
114
- return /* @__PURE__ */ jsxs("svg", { width: 16 * s, height: 11 * s, viewBox: "0 0 16 11", style: { marginLeft: 4 * s }, children: [
115
- /* @__PURE__ */ jsx(
116
- "path",
117
- {
118
- d: "M1 6 l3 3 l6 -7",
119
- stroke: color,
120
- strokeWidth: 1.3,
121
- fill: "none",
122
- strokeLinecap: "round",
123
- strokeLinejoin: "round",
124
- opacity: state === "sent" ? 0 : 1
125
- }
126
- ),
127
- /* @__PURE__ */ jsx(
128
- "path",
129
- {
130
- d: "M5 6 l3 3 l7 -8",
131
- stroke: color,
132
- strokeWidth: 1.3,
133
- fill: "none",
134
- strokeLinecap: "round",
135
- strokeLinejoin: "round"
136
- }
137
- )
138
- ] });
139
- };
140
- var ComposeBar = ({ s }) => {
141
- const stroke = "#1A1A1A";
142
- return /* @__PURE__ */ jsxs(
143
- "div",
144
- {
145
- style: {
146
- background: WA.navBg,
147
- borderTop: "1px solid rgba(0,0,0,0.05)",
148
- padding: `${10 * s}px ${14 * s}px ${12 * s}px`,
149
- display: "flex",
150
- alignItems: "center",
151
- gap: 14 * s
152
- },
153
- children: [
154
- /* @__PURE__ */ jsx("svg", { width: 30 * s, height: 30 * s, viewBox: "0 0 30 30", style: { flexShrink: 0 }, children: /* @__PURE__ */ jsx("path", { d: "M15 5 v20 M5 15 h20", stroke, strokeWidth: "1.8", strokeLinecap: "round" }) }),
155
- /* @__PURE__ */ jsx(
156
- "div",
157
- {
158
- style: {
159
- flex: 1,
160
- height: 40 * s,
161
- background: WA.inputBg,
162
- borderRadius: 22 * s,
163
- position: "relative",
164
- border: `0.5px solid ${WA.inputBorder}`
165
- },
166
- children: /* @__PURE__ */ jsx(
167
- "div",
168
- {
169
- style: {
170
- position: "absolute",
171
- right: 12 * s,
172
- top: "50%",
173
- transform: "translateY(-50%)",
174
- display: "flex",
175
- alignItems: "center",
176
- justifyContent: "center"
177
- },
178
- children: /* @__PURE__ */ jsx("svg", { width: 28 * s, height: 28 * s, viewBox: "0 0 24 24", fill: "none", style: { display: "block" }, children: /* @__PURE__ */ jsx(
179
- "path",
180
- {
181
- d: "M3 5 a2 2 0 0 1 2 -2 h10 a2 2 0 0 1 2 2 v6 l-6 6 h-6 a2 2 0 0 1 -2 -2 z M17 11 a4 4 0 0 0 -4 4 v2",
182
- stroke: "#555",
183
- strokeWidth: "1.5",
184
- fill: "none",
185
- strokeLinejoin: "round",
186
- strokeLinecap: "round"
187
- }
188
- ) })
189
- }
190
- )
191
- }
192
- ),
193
- /* @__PURE__ */ jsxs("svg", { width: 28 * s, height: 24 * s, viewBox: "0 0 28 24", fill: "none", style: { flexShrink: 0 }, children: [
194
- /* @__PURE__ */ jsx(
195
- "path",
196
- {
197
- d: "M3 6 h5 l2 -3 h8 l2 3 h5 a1 1 0 0 1 1 1 v14 a1 1 0 0 1 -1 1 h-22 a1 1 0 0 1 -1 -1 v-14 a1 1 0 0 1 1 -1 z",
198
- stroke,
199
- strokeWidth: "1.6",
200
- fill: "none",
201
- strokeLinejoin: "round"
202
- }
203
- ),
204
- /* @__PURE__ */ jsx("circle", { cx: "14", cy: "14", r: "4.5", stroke, strokeWidth: "1.6", fill: "none" })
205
- ] }),
206
- /* @__PURE__ */ jsxs("svg", { width: 20 * s, height: 26 * s, viewBox: "0 0 20 26", fill: "none", style: { flexShrink: 0 }, children: [
207
- /* @__PURE__ */ jsx("rect", { x: "7", y: "2", width: "6", height: "13", rx: "3", stroke, strokeWidth: "1.6", fill: "none" }),
208
- /* @__PURE__ */ jsx(
209
- "path",
210
- {
211
- d: "M3 12 a7 7 0 0 0 14 0 M10 19 v4 M7 23 h6",
212
- stroke,
213
- strokeWidth: "1.6",
214
- fill: "none",
215
- strokeLinecap: "round"
216
- }
217
- )
218
- ] })
219
- ]
220
- }
221
- );
222
- };
223
- var TypingBubble = ({ side, pop, realTimeSeconds, s, theme }) => {
224
- if (pop <= 0) return null;
225
- const isOut = side === "right";
226
- const isWA = theme === "whatsapp";
227
- const dotColor = isWA ? isOut ? "#6B8A55" : "#8C8C92" : IM.dotsColor;
228
- const bg = isWA ? isOut ? WA.outgoingBubble : WA.incomingBubble : isOut ? IM.bubbleOut : IM.bubbleIn;
229
- return /* @__PURE__ */ jsx(
230
- "div",
231
- {
232
- style: {
233
- display: "flex",
234
- justifyContent: isOut ? "flex-end" : "flex-start",
235
- padding: `${2 * s}px ${(isWA ? 10 : 14) * s}px`,
236
- opacity: pop,
237
- transform: `scale(${0.9 + 0.1 * pop})`,
238
- transformOrigin: isOut ? "right bottom" : "left bottom"
239
- },
240
- children: /* @__PURE__ */ jsx(
241
- "div",
242
- {
243
- style: {
244
- background: bg,
245
- borderRadius: (isWA ? 14 : 18) * s,
246
- ...isWA ? {
247
- borderTopLeftRadius: isOut ? 14 * s : 2 * s,
248
- borderTopRightRadius: isOut ? 2 * s : 14 * s
249
- } : {},
250
- padding: `${(isWA ? 10 : 12) * s}px ${(isWA ? 12 : 16) * s}px`,
251
- display: "flex",
252
- gap: 5 * s,
253
- alignItems: "center",
254
- ...isWA ? { boxShadow: `0 ${1 * s}px ${1 * s}px rgba(0,0,0,0.06)` } : {}
255
- },
256
- children: [0, 1, 2].map((i) => {
257
- const phase = (realTimeSeconds * 1.6 + i * 0.2) % 1;
258
- const y = Math.sin(phase * Math.PI * 2) * 2.5 * s;
259
- const op = 0.45 + 0.55 * Math.max(0, Math.sin(phase * Math.PI));
260
- const dotSize = isWA ? 6 * s : 7 * s;
261
- return /* @__PURE__ */ jsx(
262
- "div",
263
- {
264
- style: {
265
- width: dotSize,
266
- height: dotSize,
267
- borderRadius: dotSize / 2,
268
- background: dotColor,
269
- transform: `translateY(${-y}px)`,
270
- opacity: op
271
- }
272
- },
273
- i
274
- );
275
- })
276
- }
277
- )
278
- }
279
- );
280
- };
281
- var DateChip = ({
282
- label,
283
- chipProgress,
284
- s
285
- }) => {
286
- if (chipProgress <= 0) return null;
287
- return /* @__PURE__ */ jsx(
288
- "div",
289
- {
290
- style: {
291
- display: "flex",
292
- justifyContent: "center",
293
- margin: `${12 * s}px 0 ${8 * s}px`,
294
- opacity: chipProgress,
295
- transform: `scale(${0.88 + 0.12 * chipProgress})`
296
- },
297
- children: /* @__PURE__ */ jsx(
298
- "div",
299
- {
300
- style: {
301
- background: WA.chipBg,
302
- color: WA.chipText,
303
- padding: `${7 * s}px ${16 * s}px`,
304
- borderRadius: 9 * s,
305
- fontSize: 17 * s,
306
- fontWeight: 600,
307
- boxShadow: `0 ${1 * s}px ${1.5 * s}px rgba(0,0,0,0.05)`
308
- },
309
- children: label
310
- }
311
- )
312
- }
313
- );
314
- };
315
- var IncomingBubble = ({ children, time, pop, s }) => /* @__PURE__ */ jsx(
316
- "div",
317
- {
318
- style: {
319
- display: "flex",
320
- justifyContent: "flex-start",
321
- padding: `${2 * s}px ${10 * s}px`,
322
- opacity: pop,
323
- transform: `translateY(${(1 - pop) * 6 * s}px) scale(${0.97 + 0.03 * pop})`,
324
- transformOrigin: "left bottom"
325
- },
326
- children: /* @__PURE__ */ jsxs(
327
- "div",
328
- {
329
- style: {
330
- maxWidth: "82%",
331
- background: WA.incomingBubble,
332
- borderRadius: 10 * s,
333
- borderTopLeftRadius: 2 * s,
334
- padding: `${12 * s}px ${16 * s}px ${11 * s}px`,
335
- fontSize: 23 * s,
336
- lineHeight: `${29 * s}px`,
337
- color: WA.text,
338
- boxShadow: `0 ${1 * s}px ${1 * s}px rgba(0,0,0,0.06)`,
339
- position: "relative"
340
- },
341
- children: [
342
- /* @__PURE__ */ jsx("div", { style: { paddingRight: 64 * s }, children }),
343
- /* @__PURE__ */ jsx(
344
- "div",
345
- {
346
- style: {
347
- position: "absolute",
348
- right: 14 * s,
349
- bottom: 8 * s,
350
- fontSize: 15 * s,
351
- color: WA.textMuted
352
- },
353
- children: time
354
- }
355
- )
356
- ]
357
- }
358
- )
359
- }
360
- );
361
- var OutgoingBubble = ({ children, time, tickState, pop, s }) => /* @__PURE__ */ jsx(
362
- "div",
363
- {
364
- style: {
365
- display: "flex",
366
- justifyContent: "flex-end",
367
- padding: `${2 * s}px ${10 * s}px`,
368
- opacity: pop,
369
- transform: `translateY(${(1 - pop) * 8 * s}px) scale(${0.96 + 0.04 * pop})`,
370
- transformOrigin: "right bottom"
371
- },
372
- children: /* @__PURE__ */ jsxs(
373
- "div",
374
- {
375
- style: {
376
- maxWidth: "82%",
377
- background: WA.outgoingBubble,
378
- borderRadius: 10 * s,
379
- borderTopRightRadius: 2 * s,
380
- padding: `${12 * s}px ${16 * s}px ${11 * s}px`,
381
- fontSize: 23 * s,
382
- lineHeight: `${29 * s}px`,
383
- color: WA.text,
384
- boxShadow: `0 ${1 * s}px ${1 * s}px rgba(0,0,0,0.06)`,
385
- position: "relative"
386
- },
387
- children: [
388
- /* @__PURE__ */ jsx("div", { style: { paddingRight: 88 * s }, children }),
389
- /* @__PURE__ */ jsxs(
390
- "div",
391
- {
392
- style: {
393
- position: "absolute",
394
- right: 14 * s,
395
- bottom: 8 * s,
396
- fontSize: 15 * s,
397
- color: WA.outgoingTime,
398
- display: "flex",
399
- alignItems: "center"
400
- },
401
- children: [
402
- time,
403
- /* @__PURE__ */ jsx(Ticks, { state: tickState, s })
404
- ]
405
- }
406
- )
407
- ]
408
- }
409
- )
410
- }
411
- );
412
- var CHIP_TIMING = {
413
- monday: { start: 5.8, end: 6.2 },
414
- yesterday: { start: 9.6, end: 10 }
415
- };
416
- var ConversationThread = ({
417
- progress,
418
- width,
419
- height,
420
- sceneDuration,
421
- messages: rawMessages,
422
- theme = "whatsapp",
423
- dateChip1 = "",
424
- dateChip2 = "",
425
- safeZoneTop
426
- }) => {
427
- const isLandscape = width > height;
428
- const colWidth = isLandscape ? width * 0.72 : width;
429
- const colLeft = (width - colWidth) / 2;
430
- const s = Math.min(width, height) / 534;
431
- const isWhatsApp = theme === "whatsapp";
432
- const sanitized = rawMessages.map((m) => ({ ...m, text: stripPipe(m.text || "").trim() })).filter((m) => m.text.length > 0);
433
- const timing = timingForCount(Math.max(1, sanitized.length));
434
- const messages = sanitized.map((m, i) => ({
435
- side: m.side,
436
- text: m.text,
437
- author: m.author,
438
- typingStart: timing[i].typingStart,
439
- bubbleStart: timing[i].bubbleStart,
440
- time: timing[i].time
441
- }));
442
- const realTimeSeconds = progress * sceneDuration;
443
- const refT = progress * REF_DURATION;
444
- const topPad = safeZoneTop != null ? safeZoneTop : height * 0.08;
445
- const chip1Label = stripPipe(dateChip1 || "").trim();
446
- const chip2Label = stripPipe(dateChip2 || "").trim();
447
- const popIn = (t, start, dur = 0.4) => {
448
- if (t <= start) return 0;
449
- if (t >= start + dur) return 1;
450
- return easeOutBack((t - start) / dur);
451
- };
452
- const ramp = (t, start, end) => {
453
- if (t <= start) return 0;
454
- if (t >= end) return 1;
455
- return (t - start) / (end - start);
456
- };
457
- if (isWhatsApp) {
458
- return /* @__PURE__ */ jsx(
459
- "div",
460
- {
461
- style: {
462
- position: "absolute",
463
- inset: 0,
464
- background: WA.bg,
465
- overflow: "hidden",
466
- fontFamily: '-apple-system, "SF Pro Text", system-ui'
467
- },
468
- children: /* @__PURE__ */ jsxs(
469
- "div",
470
- {
471
- style: {
472
- position: "absolute",
473
- left: colLeft,
474
- width: colWidth,
475
- top: 0,
476
- height,
477
- display: "flex",
478
- flexDirection: "column"
479
- },
480
- children: [
481
- /* @__PURE__ */ jsx("div", { style: { flex: 1, position: "relative", overflow: "hidden" }, children: /* @__PURE__ */ jsxs(
482
- "div",
483
- {
484
- style: {
485
- position: "absolute",
486
- left: 0,
487
- right: 0,
488
- top: 0,
489
- display: "flex",
490
- flexDirection: "column",
491
- gap: 2 * s,
492
- padding: `${topPad}px 0 ${10 * s}px`
493
- },
494
- children: [
495
- messages.map((msg, i) => {
496
- const typingPop = popIn(refT, msg.typingStart, 0.25);
497
- const typingFade = interpolate(
498
- refT,
499
- [msg.bubbleStart - 0.1, msg.bubbleStart],
500
- [1, 0],
501
- CLAMP
502
- );
503
- const showTyping = refT >= msg.typingStart && refT < msg.bubbleStart;
504
- const bubblePop = popIn(refT, msg.bubbleStart, 0.4);
505
- const showBubble = refT >= msg.bubbleStart;
506
- const isOut = msg.side === "right";
507
- const refSinceSent = refT - msg.bubbleStart - 0.4;
508
- const tickState = isOut ? tickStateAt(Math.max(0, refSinceSent)) : "read";
509
- const chipBeforeThis = (() => {
510
- if (i === 3 && chip1Label) {
511
- return {
512
- label: chip1Label,
513
- progress: ramp(refT, CHIP_TIMING.monday.start, CHIP_TIMING.monday.end)
514
- };
515
- }
516
- if (i === 4 && chip2Label) {
517
- return {
518
- label: chip2Label,
519
- progress: ramp(refT, CHIP_TIMING.yesterday.start, CHIP_TIMING.yesterday.end)
520
- };
521
- }
522
- return null;
523
- })();
524
- return /* @__PURE__ */ jsxs(React.Fragment, { children: [
525
- chipBeforeThis && /* @__PURE__ */ jsx(
526
- DateChip,
527
- {
528
- label: chipBeforeThis.label,
529
- chipProgress: chipBeforeThis.progress,
530
- s
531
- }
532
- ),
533
- showTyping && /* @__PURE__ */ jsx("div", { style: { opacity: typingPop * typingFade }, children: /* @__PURE__ */ jsx(
534
- TypingBubble,
535
- {
536
- side: msg.side,
537
- pop: typingPop,
538
- realTimeSeconds,
539
- s,
540
- theme: "whatsapp"
541
- }
542
- ) }),
543
- showBubble && (isOut ? /* @__PURE__ */ jsx(OutgoingBubble, { pop: bubblePop, time: msg.time, tickState, s, children: renderWithEmoji(msg.text, 23 * s) }) : /* @__PURE__ */ jsx(IncomingBubble, { pop: bubblePop, time: msg.time, s, children: renderWithEmoji(msg.text, 23 * s) }))
544
- ] }, i);
545
- }),
546
- /* @__PURE__ */ jsx("div", { style: { height: 12 * s } })
547
- ]
548
- }
549
- ) }),
550
- /* @__PURE__ */ jsx(ComposeBar, { s })
551
- ]
552
- }
553
- )
554
- }
555
- );
556
- }
557
- return /* @__PURE__ */ jsx(
558
- "div",
559
- {
560
- style: {
561
- position: "absolute",
562
- inset: 0,
563
- background: IM.bg,
564
- overflow: "hidden",
565
- fontFamily: "-apple-system, 'SF Pro', 'Helvetica Neue', Helvetica, Arial, sans-serif"
566
- },
567
- children: /* @__PURE__ */ jsx(
568
- "div",
569
- {
570
- style: {
571
- position: "absolute",
572
- left: colLeft,
573
- width: colWidth,
574
- top: 0,
575
- height,
576
- padding: `${topPad}px 0 ${20 * s}px`,
577
- display: "flex",
578
- flexDirection: "column",
579
- gap: 4 * s
580
- },
581
- children: messages.map((msg, i) => {
582
- const typingPop = popIn(refT, msg.typingStart, 0.25);
583
- const typingFade = interpolate(
584
- refT,
585
- [msg.bubbleStart - 0.1, msg.bubbleStart],
586
- [1, 0],
587
- CLAMP
588
- );
589
- const showTyping = refT >= msg.typingStart && refT < msg.bubbleStart;
590
- const bubblePop = popIn(refT, msg.bubbleStart, 0.4);
591
- const showBubble = refT >= msg.bubbleStart;
592
- const isOut = msg.side === "right";
593
- return /* @__PURE__ */ jsxs(React.Fragment, { children: [
594
- showTyping && /* @__PURE__ */ jsx("div", { style: { opacity: typingPop * typingFade }, children: /* @__PURE__ */ jsx(
595
- TypingBubble,
596
- {
597
- side: msg.side,
598
- pop: typingPop,
599
- realTimeSeconds,
600
- s,
601
- theme: "messenger"
602
- }
603
- ) }),
604
- showBubble && /* @__PURE__ */ jsx(
605
- "div",
606
- {
607
- style: {
608
- display: "flex",
609
- justifyContent: isOut ? "flex-end" : "flex-start",
610
- padding: `${2 * s}px ${14 * s}px`,
611
- opacity: bubblePop,
612
- transform: `translateY(${(1 - bubblePop) * 8 * s}px) scale(${0.96 + 0.04 * bubblePop})`,
613
- transformOrigin: isOut ? "right bottom" : "left bottom"
614
- },
615
- children: /* @__PURE__ */ jsx(
616
- "div",
617
- {
618
- style: {
619
- maxWidth: "75%",
620
- background: isOut ? IM.bubbleOut : IM.bubbleIn,
621
- color: isOut ? IM.textOut : IM.textIn,
622
- borderRadius: 22 * s,
623
- padding: `${12 * s}px ${18 * s}px`,
624
- fontSize: 23 * s,
625
- lineHeight: `${29 * s}px`
626
- },
627
- children: renderWithEmoji(msg.text, 23 * s)
628
- }
629
- )
630
- }
631
- )
632
- ] }, i);
633
- })
634
- }
635
- )
636
- }
637
- );
638
- };
639
-
640
- // src/visual-system/scene-templates/social-conversation.tsx
641
- import { jsx as jsx2 } from "react/jsx-runtime";
642
- var DEFAULT_SIDES = {
643
- 1: "left",
644
- 2: "right",
645
- 3: "left",
646
- 4: "right",
647
- 5: "right"
648
- };
649
- function buildConversationMessages(variables) {
650
- const messages = [];
651
- for (let index = 1; index <= 5; index += 1) {
652
- let text = normalizeTextVar(variables[`msg${index}`]).trim();
653
- if (!text) continue;
654
- let side = DEFAULT_SIDES[index] ?? (index % 2 === 1 ? "left" : "right");
655
- if (text.endsWith("|in")) {
656
- side = "left";
657
- text = text.slice(0, -3).trim();
658
- } else if (text.endsWith("|out")) {
659
- side = "right";
660
- text = text.slice(0, -4).trim();
661
- }
662
- messages.push({ author: side === "left" ? "Customer" : "You", text, side });
663
- }
664
- return messages;
665
- }
666
- var SocialConversationTemplate = ({
667
- variables,
668
- progress,
669
- beatIntensity,
670
- width,
671
- height,
672
- sceneDuration,
673
- safeZone
674
- }) => {
675
- const theme = String(variables.theme || "messenger").toLowerCase() === "whatsapp" ? "whatsapp" : "messenger";
676
- return /* @__PURE__ */ jsx2("div", { style: { width, height, position: "relative", overflow: "hidden", backgroundColor: theme === "whatsapp" ? "#EFE7DC" : "#ffffff" }, children: /* @__PURE__ */ jsx2(
677
- ConversationThread,
678
- {
679
- progress,
680
- width,
681
- height,
682
- sceneDuration: sceneDuration ?? 8,
683
- messages: buildConversationMessages(variables),
684
- theme,
685
- dateChip1: String(variables.dateChip1 || ""),
686
- dateChip2: String(variables.dateChip2 || ""),
687
- safeZoneTop: Math.max(safeZone.top, height * 0.08),
688
- beatIntensity
689
- }
690
- ) });
691
- };
692
- export {
693
- SocialConversationTemplate,
694
- buildConversationMessages
695
- };