@gxpl/sdk 0.0.1

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 (87) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +2 -0
  3. package/dist/Client/Client.d.ts +32 -0
  4. package/dist/Client/Client.js +128 -0
  5. package/dist/Client/Client.test.d.ts +1 -0
  6. package/dist/Client/__mock__/articleMock.d.ts +2 -0
  7. package/dist/Client/__mock__/keyframesMock.d.ts +2 -0
  8. package/dist/Client/__mock__/projectMock.d.ts +2 -0
  9. package/dist/Components/ControlSlider/ControlSlider.d.ts +91 -0
  10. package/dist/Components/ControlSlider/ControlSliderComponent.d.ts +519 -0
  11. package/dist/Components/ImageRevealSlider/ControlImageRevealSliderComponent.d.ts +209 -0
  12. package/dist/Components/ImageRevealSlider/ImageRevealSlider.d.ts +39 -0
  13. package/dist/Components/components.d.ts +2 -0
  14. package/dist/Components/helpers/RichTextRenderer/RichTextRenderer.d.ts +6 -0
  15. package/dist/Components/helpers/SvgImage/SvgImage.d.ts +9 -0
  16. package/dist/Components/utils/scalingValue.d.ts +1 -0
  17. package/dist/FontFaceGenerator/FontFaceGenerator.d.ts +6 -0
  18. package/dist/FontFaceGenerator/FontFaceGenerator.test.d.ts +1 -0
  19. package/dist/ScrollPlaybackVideoManager/ScrollPlaybackVideoManager.d.ts +31 -0
  20. package/dist/VideoDecoder/VideoDecoder.d.ts +12 -0
  21. package/dist/cli.d.ts +10 -0
  22. package/dist/cli.js +64 -0
  23. package/dist/index.d.ts +23 -0
  24. package/dist/index.js +2730 -0
  25. package/dist/index.mjs +2713 -0
  26. package/dist/schemas/article/Article.schema.d.ts +328 -0
  27. package/dist/schemas/article/Article.schema.js +11 -0
  28. package/dist/schemas/article/FillLayer.schema.d.ts +186 -0
  29. package/dist/schemas/article/FillLayer.schema.js +53 -0
  30. package/dist/schemas/article/Interaction.schema.d.ts +103 -0
  31. package/dist/schemas/article/Interaction.schema.js +30 -0
  32. package/dist/schemas/article/Item.schema.d.ts +40 -0
  33. package/dist/schemas/article/Item.schema.js +242 -0
  34. package/dist/schemas/article/ItemArea.schema.d.ts +36 -0
  35. package/dist/schemas/article/ItemArea.schema.js +17 -0
  36. package/dist/schemas/article/ItemBase.schema.d.ts +137 -0
  37. package/dist/schemas/article/ItemBase.schema.js +23 -0
  38. package/dist/schemas/article/ItemState.schema.d.ts +15723 -0
  39. package/dist/schemas/article/ItemState.schema.js +75 -0
  40. package/dist/schemas/article/RichTextItem.schema.d.ts +1372 -0
  41. package/dist/schemas/article/RichTextItem.schema.js +60 -0
  42. package/dist/schemas/article/Section.schema.d.ts +176 -0
  43. package/dist/schemas/article/Section.schema.js +38 -0
  44. package/dist/schemas/keyframe/Keyframes.schema.d.ts +2000 -0
  45. package/dist/schemas/keyframe/Keyframes.schema.js +116 -0
  46. package/dist/schemas/project/Layout.schema.d.ts +17 -0
  47. package/dist/schemas/project/Layout.schema.js +10 -0
  48. package/dist/schemas/project/Project.schema.d.ts +253 -0
  49. package/dist/schemas/project/Project.schema.js +48 -0
  50. package/dist/schemas/shared/FillLayer.schema.d.ts +186 -0
  51. package/dist/sdk.css +1 -0
  52. package/dist/types/article/Article.d.ts +7 -0
  53. package/dist/types/article/Article.js +2 -0
  54. package/dist/types/article/ArticleItemType.d.ts +13 -0
  55. package/dist/types/article/ArticleItemType.js +17 -0
  56. package/dist/types/article/CompoundSettings.d.ts +6 -0
  57. package/dist/types/article/CompoundSettings.js +2 -0
  58. package/dist/types/article/FX.d.ts +23 -0
  59. package/dist/types/article/FX.js +2 -0
  60. package/dist/types/article/Interaction.d.ts +28 -0
  61. package/dist/types/article/Interaction.js +2 -0
  62. package/dist/types/article/Item.d.ts +250 -0
  63. package/dist/types/article/Item.js +3 -0
  64. package/dist/types/article/ItemArea.d.ts +36 -0
  65. package/dist/types/article/ItemArea.js +31 -0
  66. package/dist/types/article/ItemState.d.ts +78 -0
  67. package/dist/types/article/ItemState.js +3 -0
  68. package/dist/types/article/RichText.d.ts +40 -0
  69. package/dist/types/article/RichText.js +27 -0
  70. package/dist/types/article/Section.d.ts +37 -0
  71. package/dist/types/article/Section.js +8 -0
  72. package/dist/types/component/Component.d.ts +15 -0
  73. package/dist/types/keyframe/Keyframe.d.ts +86 -0
  74. package/dist/types/keyframe/Keyframe.js +21 -0
  75. package/dist/types/project/Fonts.d.ts +22 -0
  76. package/dist/types/project/Fonts.js +11 -0
  77. package/dist/types/project/Layout.d.ts +6 -0
  78. package/dist/types/project/Layout.js +2 -0
  79. package/dist/types/project/Meta.d.ts +9 -0
  80. package/dist/types/project/Meta.js +2 -0
  81. package/dist/types/project/Page.d.ts +11 -0
  82. package/dist/types/project/Page.js +2 -0
  83. package/dist/types/project/Project.d.ts +17 -0
  84. package/dist/types/project/Project.js +2 -0
  85. package/dist/utils.d.ts +3 -0
  86. package/package.json +84 -0
  87. package/resources/template.scss.ejs +50 -0
package/dist/index.mjs ADDED
@@ -0,0 +1,2713 @@
1
+ import fetch$1 from "isomorphic-fetch";
2
+ import { URL } from "url";
3
+ import { z } from "zod";
4
+ import UAParser from "ua-parser-js";
5
+ import * as MP4Box from "mp4box";
6
+ import { jsx, Fragment, jsxs } from "react/jsx-runtime";
7
+ import { useState, useEffect, useRef, useMemo } from "react";
8
+ import { Splide, SplideSlide } from "@splidejs/react-splide";
9
+ import cn from "classnames";
10
+ var SectionHeightMode = /* @__PURE__ */ ((SectionHeightMode2) => {
11
+ SectionHeightMode2["ControlUnits"] = "control-units";
12
+ SectionHeightMode2["ViewportHeightUnits"] = "viewport-height-units";
13
+ return SectionHeightMode2;
14
+ })(SectionHeightMode || {});
15
+ const ColorPointSchema = z.object({
16
+ id: z.string(),
17
+ value: z.string(),
18
+ position: z.number()
19
+ });
20
+ const FillLayerSchema = z.discriminatedUnion("type", [
21
+ z.object({
22
+ id: z.string(),
23
+ type: z.literal("solid"),
24
+ value: z.string(),
25
+ blendMode: z.string()
26
+ }),
27
+ z.object({
28
+ id: z.string(),
29
+ type: z.literal("linear-gradient"),
30
+ colors: z.array(ColorPointSchema),
31
+ start: z.tuple([z.number(), z.number()]),
32
+ end: z.tuple([z.number(), z.number()]),
33
+ angle: z.number(),
34
+ blendMode: z.string()
35
+ }),
36
+ z.object({
37
+ id: z.string(),
38
+ type: z.literal("radial-gradient"),
39
+ colors: z.array(ColorPointSchema),
40
+ center: z.tuple([z.number(), z.number()]),
41
+ diameter: z.number(),
42
+ angle: z.number(),
43
+ blendMode: z.string()
44
+ }),
45
+ z.object({
46
+ id: z.string(),
47
+ type: z.literal("conic-gradient"),
48
+ colors: z.array(ColorPointSchema),
49
+ center: z.tuple([z.number(), z.number()]),
50
+ angle: z.number(),
51
+ blendMode: z.string()
52
+ }),
53
+ z.object({
54
+ id: z.string(),
55
+ type: z.literal("image"),
56
+ src: z.string(),
57
+ behavior: z.string(),
58
+ backgroundSize: z.number(),
59
+ opacity: z.number(),
60
+ blendMode: z.string(),
61
+ rotation: z.number().optional()
62
+ })
63
+ ]);
64
+ const TransitionSchema = z.object({
65
+ timing: z.string(),
66
+ duration: z.number(),
67
+ delay: z.number()
68
+ });
69
+ const getStateParamsSchema = (schema) => {
70
+ return z.object({
71
+ value: schema,
72
+ in: TransitionSchema,
73
+ out: TransitionSchema
74
+ }).optional();
75
+ };
76
+ const ItemStateBaseSchema = z.object({
77
+ width: getStateParamsSchema(z.number()),
78
+ height: getStateParamsSchema(z.number()),
79
+ angle: getStateParamsSchema(z.number()),
80
+ top: getStateParamsSchema(z.number()),
81
+ left: getStateParamsSchema(z.number()),
82
+ scale: getStateParamsSchema(z.number()),
83
+ blur: getStateParamsSchema(z.number())
84
+ });
85
+ const MediaStateParamsSchema = z.object({
86
+ opacity: getStateParamsSchema(z.number()),
87
+ radius: getStateParamsSchema(z.number()),
88
+ strokeWidth: getStateParamsSchema(z.number()),
89
+ strokeFill: getStateParamsSchema(z.array(FillLayerSchema))
90
+ }).merge(ItemStateBaseSchema);
91
+ const RectangleStateParamsSchema = z.object({
92
+ strokeWidth: getStateParamsSchema(z.number()),
93
+ radius: getStateParamsSchema(z.number()),
94
+ fill: getStateParamsSchema(z.array(FillLayerSchema)),
95
+ strokeFill: getStateParamsSchema(z.array(FillLayerSchema)),
96
+ backdropBlur: getStateParamsSchema(z.number())
97
+ }).merge(ItemStateBaseSchema);
98
+ const CustomItemStateParamsSchema = ItemStateBaseSchema;
99
+ const EmbedStateParamsSchema = z.object({
100
+ radius: getStateParamsSchema(z.number()),
101
+ opacity: getStateParamsSchema(z.number().nonnegative())
102
+ }).merge(ItemStateBaseSchema);
103
+ const RichTextStateParamsSchema = z.object({
104
+ color: getStateParamsSchema(z.string()),
105
+ letterSpacing: getStateParamsSchema(z.number()),
106
+ wordSpacing: getStateParamsSchema(z.number())
107
+ }).merge(ItemStateBaseSchema);
108
+ const GroupStateParamsSchema = z.object({
109
+ opacity: getStateParamsSchema(z.number().nonnegative()),
110
+ blur: getStateParamsSchema(z.number().nonnegative())
111
+ }).merge(ItemStateBaseSchema);
112
+ const CompoundStateParamsSchema = z.object({
113
+ opacity: getStateParamsSchema(z.number().nonnegative())
114
+ }).merge(ItemStateBaseSchema);
115
+ const CodeEmbedStateParamsSchema = z.object({
116
+ opacity: getStateParamsSchema(z.number().nonnegative())
117
+ }).merge(ItemStateBaseSchema);
118
+ const ComponentStateParamsSchema = z.object({
119
+ opacity: getStateParamsSchema(z.number().nonnegative())
120
+ }).merge(ItemStateBaseSchema);
121
+ z.union([
122
+ EmbedStateParamsSchema,
123
+ MediaStateParamsSchema,
124
+ RectangleStateParamsSchema,
125
+ RichTextStateParamsSchema,
126
+ CustomItemStateParamsSchema,
127
+ GroupStateParamsSchema,
128
+ CompoundStateParamsSchema,
129
+ CodeEmbedStateParamsSchema,
130
+ ComponentStateParamsSchema
131
+ ]);
132
+ var TextAlign = /* @__PURE__ */ ((TextAlign2) => {
133
+ TextAlign2["Left"] = "left";
134
+ TextAlign2["Right"] = "right";
135
+ TextAlign2["Center"] = "center";
136
+ TextAlign2["Justify"] = "justify";
137
+ return TextAlign2;
138
+ })(TextAlign || {});
139
+ var TextTransform = /* @__PURE__ */ ((TextTransform2) => {
140
+ TextTransform2["None"] = "none";
141
+ TextTransform2["Uppercase"] = "uppercase";
142
+ TextTransform2["Lowercase"] = "lowercase";
143
+ return TextTransform2;
144
+ })(TextTransform || {});
145
+ var VerticalAlign = /* @__PURE__ */ ((VerticalAlign2) => {
146
+ VerticalAlign2["Super"] = "super";
147
+ VerticalAlign2["Sub"] = "sub";
148
+ VerticalAlign2["Unset"] = "unset";
149
+ return VerticalAlign2;
150
+ })(VerticalAlign || {});
151
+ var TextDecoration = /* @__PURE__ */ ((TextDecoration2) => {
152
+ TextDecoration2["Underline"] = "underline";
153
+ TextDecoration2["None"] = "none";
154
+ return TextDecoration2;
155
+ })(TextDecoration || {});
156
+ var AnchorSide = /* @__PURE__ */ ((AnchorSide2) => {
157
+ AnchorSide2["Top"] = "top";
158
+ AnchorSide2["Bottom"] = "bottom";
159
+ AnchorSide2["Center"] = "center";
160
+ return AnchorSide2;
161
+ })(AnchorSide || {});
162
+ var PositionType = /* @__PURE__ */ ((PositionType2) => {
163
+ PositionType2["SectionBased"] = "section-based";
164
+ PositionType2["ScreenBased"] = "screen-based";
165
+ return PositionType2;
166
+ })(PositionType || {});
167
+ var AreaAnchor = /* @__PURE__ */ ((AreaAnchor2) => {
168
+ AreaAnchor2["TopLeft"] = "top-left";
169
+ AreaAnchor2["TopCenter"] = "top-center";
170
+ AreaAnchor2["TopRight"] = "top-right";
171
+ AreaAnchor2["MiddleLeft"] = "middle-left";
172
+ AreaAnchor2["MiddleCenter"] = "middle-center";
173
+ AreaAnchor2["MiddleRight"] = "middle-right";
174
+ AreaAnchor2["BottomLeft"] = "bottom-left";
175
+ AreaAnchor2["BottomCenter"] = "bottom-center";
176
+ AreaAnchor2["BottomRight"] = "bottom-right";
177
+ return AreaAnchor2;
178
+ })(AreaAnchor || {});
179
+ var DimensionMode = /* @__PURE__ */ ((DimensionMode2) => {
180
+ DimensionMode2["ControlUnits"] = "control-units";
181
+ DimensionMode2["Relative"] = "relative";
182
+ return DimensionMode2;
183
+ })(DimensionMode || {});
184
+ const ItemAreaSchema = z.object({
185
+ top: z.number(),
186
+ left: z.number(),
187
+ width: z.number(),
188
+ height: z.number(),
189
+ zIndex: z.number(),
190
+ angle: z.number(),
191
+ anchorSide: z.nativeEnum(AnchorSide).optional(),
192
+ scale: z.number().nonnegative(),
193
+ positionType: z.nativeEnum(PositionType),
194
+ scaleAnchor: z.nativeEnum(AreaAnchor)
195
+ });
196
+ const Link = z.object({
197
+ url: z.string().min(1),
198
+ target: z.string().min(1)
199
+ });
200
+ const CompoundSettingsSchema = z.object({
201
+ positionAnchor: z.nativeEnum(AreaAnchor),
202
+ widthMode: z.nativeEnum(DimensionMode),
203
+ heightMode: z.nativeEnum(DimensionMode)
204
+ });
205
+ const ItemBaseSchema = z.object({
206
+ id: z.string().min(1),
207
+ area: z.record(ItemAreaSchema),
208
+ hidden: z.record(z.boolean()),
209
+ link: Link.optional(),
210
+ compoundSettings: z.record(CompoundSettingsSchema).optional(),
211
+ layoutParams: z.record(z.any()).optional()
212
+ });
213
+ var ArticleItemType = /* @__PURE__ */ ((ArticleItemType2) => {
214
+ ArticleItemType2["Image"] = "image";
215
+ ArticleItemType2["RichText"] = "richtext";
216
+ ArticleItemType2["Video"] = "video";
217
+ ArticleItemType2["Rectangle"] = "rectangle";
218
+ ArticleItemType2["VimeoEmbed"] = "vimeo-embed";
219
+ ArticleItemType2["YoutubeEmbed"] = "youtube-embed";
220
+ ArticleItemType2["Custom"] = "custom";
221
+ ArticleItemType2["Group"] = "group";
222
+ ArticleItemType2["CodeEmbed"] = "code-embed";
223
+ ArticleItemType2["Compound"] = "compound";
224
+ ArticleItemType2["Component"] = "component";
225
+ return ArticleItemType2;
226
+ })(ArticleItemType || {});
227
+ const pointerEvents$1 = z.enum(["never", "when_visible", "always"]).optional();
228
+ const RichTextEntitySchema = z.object({
229
+ start: z.number().nonnegative(),
230
+ end: z.number().nonnegative(),
231
+ type: z.string(),
232
+ data: z.any().optional()
233
+ });
234
+ const RichTextStyleSchema = z.object({
235
+ start: z.number().nonnegative(),
236
+ end: z.number().nonnegative(),
237
+ style: z.string().min(1),
238
+ value: z.string().optional()
239
+ });
240
+ const RichTextBlockSchema = z.lazy(() => z.object({
241
+ start: z.number().nonnegative(),
242
+ end: z.number().nonnegative(),
243
+ type: z.string().min(1),
244
+ entities: z.array(RichTextEntitySchema).optional(),
245
+ children: z.array(RichTextBlockSchema).optional(),
246
+ data: z.any().optional()
247
+ }));
248
+ const RichTextItemSchema = ItemBaseSchema.extend({
249
+ type: z.literal(ArticleItemType.RichText),
250
+ commonParams: z.object({
251
+ text: z.string(),
252
+ blocks: z.array(RichTextBlockSchema).optional(),
253
+ pointerEvents: pointerEvents$1
254
+ }),
255
+ sticky: z.record(
256
+ z.object({
257
+ from: z.number(),
258
+ to: z.number().optional()
259
+ }).nullable()
260
+ ),
261
+ layoutParams: z.record(
262
+ z.object({
263
+ rangeStyles: z.array(RichTextStyleSchema).optional(),
264
+ textAlign: z.nativeEnum(TextAlign),
265
+ sizing: z.string(),
266
+ blur: z.number(),
267
+ fontSize: z.number(),
268
+ lineHeight: z.number(),
269
+ letterSpacing: z.number(),
270
+ wordSpacing: z.number(),
271
+ textTransform: z.nativeEnum(TextTransform),
272
+ verticalAlign: z.nativeEnum(VerticalAlign),
273
+ color: z.string(),
274
+ typeFace: z.string(),
275
+ fontStyle: z.string(),
276
+ fontWeight: z.number(),
277
+ fontVariant: z.string(),
278
+ isDraggable: z.boolean().optional()
279
+ })
280
+ ),
281
+ state: z.record(RichTextStateParamsSchema)
282
+ });
283
+ const pointerEvents = z.enum(["never", "when_visible", "always"]).optional();
284
+ const FXControlSchema = z.discriminatedUnion("type", [
285
+ z.object({
286
+ type: z.literal("float"),
287
+ shaderParam: z.string(),
288
+ value: z.number()
289
+ }),
290
+ z.object({
291
+ type: z.literal("int"),
292
+ shaderParam: z.string(),
293
+ value: z.number()
294
+ }),
295
+ z.object({
296
+ type: z.literal("vec2"),
297
+ shaderParam: z.string(),
298
+ value: z.tuple([z.number(), z.number()])
299
+ })
300
+ ]);
301
+ const FXParams = z.object({
302
+ url: z.string().min(1),
303
+ hasGLEffect: z.boolean().optional(),
304
+ fragmentShader: z.string().nullable(),
305
+ FXControls: z.array(FXControlSchema).optional()
306
+ });
307
+ const ImageItemSchema = ItemBaseSchema.extend({
308
+ type: z.literal(ArticleItemType.Image),
309
+ commonParams: z.object({
310
+ pointerEvents
311
+ }).merge(FXParams),
312
+ sticky: z.record(
313
+ z.object({
314
+ from: z.number(),
315
+ to: z.number().optional()
316
+ }).nullable()
317
+ ),
318
+ layoutParams: z.record(
319
+ z.object({
320
+ opacity: z.number().nonnegative(),
321
+ radius: z.number(),
322
+ strokeWidth: z.number(),
323
+ strokeFill: z.array(FillLayerSchema),
324
+ blur: z.number(),
325
+ isDraggable: z.boolean().optional()
326
+ })
327
+ ),
328
+ state: z.record(MediaStateParamsSchema)
329
+ });
330
+ const VideoItemSchema = ItemBaseSchema.extend({
331
+ type: z.literal(ArticleItemType.Video),
332
+ commonParams: z.object({
333
+ coverUrl: z.string().nullable(),
334
+ pointerEvents
335
+ }).merge(FXParams),
336
+ sticky: z.record(
337
+ z.object({
338
+ from: z.number(),
339
+ to: z.number().optional()
340
+ }).nullable()
341
+ ),
342
+ layoutParams: z.record(
343
+ z.object({
344
+ scrollPlayback: z.object({
345
+ from: z.number(),
346
+ to: z.number()
347
+ }).nullable(),
348
+ opacity: z.number().nonnegative(),
349
+ radius: z.number(),
350
+ strokeWidth: z.number(),
351
+ strokeFill: z.array(FillLayerSchema),
352
+ blur: z.number(),
353
+ isDraggable: z.boolean().optional(),
354
+ play: z.enum(["on-hover", "on-click", "auto"]),
355
+ muted: z.boolean(),
356
+ controls: z.boolean()
357
+ })
358
+ ),
359
+ state: z.record(MediaStateParamsSchema)
360
+ });
361
+ const RectangleItemSchema = ItemBaseSchema.extend({
362
+ type: z.literal(ArticleItemType.Rectangle),
363
+ commonParams: z.object({
364
+ ratioLock: z.boolean(),
365
+ pointerEvents
366
+ }),
367
+ sticky: z.record(
368
+ z.object({
369
+ from: z.number(),
370
+ to: z.number().optional()
371
+ }).nullable()
372
+ ),
373
+ layoutParams: z.record(
374
+ z.object({
375
+ radius: z.number(),
376
+ strokeWidth: z.number(),
377
+ fill: z.array(FillLayerSchema),
378
+ strokeFill: z.array(FillLayerSchema),
379
+ blur: z.number(),
380
+ backdropBlur: z.number(),
381
+ blurMode: z.enum(["default", "backdrop"]),
382
+ isDraggable: z.boolean().optional()
383
+ })
384
+ ),
385
+ state: z.record(RectangleStateParamsSchema)
386
+ });
387
+ const CustomItemSchema = ItemBaseSchema.extend({
388
+ type: z.literal(ArticleItemType.Custom),
389
+ commonParams: z.object({
390
+ name: z.string(),
391
+ pointerEvents
392
+ }),
393
+ sticky: z.record(
394
+ z.object({
395
+ from: z.number(),
396
+ to: z.number().optional()
397
+ }).nullable()
398
+ ),
399
+ layoutParams: z.record(z.object({
400
+ isDraggable: z.boolean().optional()
401
+ })),
402
+ state: z.record(CustomItemStateParamsSchema)
403
+ });
404
+ const VimeoEmbedItemSchema = ItemBaseSchema.extend({
405
+ type: z.literal(ArticleItemType.VimeoEmbed),
406
+ commonParams: z.object({
407
+ url: z.string().min(1),
408
+ coverUrl: z.string().nullable(),
409
+ ratioLock: z.boolean(),
410
+ pointerEvents
411
+ }),
412
+ sticky: z.record(
413
+ z.object({
414
+ from: z.number(),
415
+ to: z.number().optional()
416
+ }).nullable()
417
+ ),
418
+ layoutParams: z.record(
419
+ z.object({
420
+ radius: z.number(),
421
+ blur: z.number(),
422
+ opacity: z.number().nonnegative(),
423
+ play: z.union([z.literal("on-hover"), z.literal("on-click"), z.literal("auto")]),
424
+ controls: z.boolean(),
425
+ loop: z.boolean(),
426
+ muted: z.boolean(),
427
+ pictureInPicture: z.boolean()
428
+ })
429
+ ),
430
+ state: z.record(EmbedStateParamsSchema)
431
+ });
432
+ const YoutubeEmbedItemSchema = ItemBaseSchema.extend({
433
+ type: z.literal(ArticleItemType.YoutubeEmbed),
434
+ commonParams: z.object({
435
+ url: z.string().min(1),
436
+ coverUrl: z.string().nullable(),
437
+ pointerEvents
438
+ }),
439
+ sticky: z.record(
440
+ z.object({
441
+ from: z.number(),
442
+ to: z.number().optional()
443
+ }).nullable()
444
+ ),
445
+ layoutParams: z.record(
446
+ z.object({
447
+ radius: z.number(),
448
+ blur: z.number(),
449
+ opacity: z.number().nonnegative(),
450
+ play: z.enum(["on-hover", "on-click", "auto"]),
451
+ controls: z.boolean(),
452
+ loop: z.boolean()
453
+ })
454
+ ),
455
+ state: z.record(EmbedStateParamsSchema)
456
+ });
457
+ const CodeEmbedItemSchema = ItemBaseSchema.extend({
458
+ type: z.literal(ArticleItemType.CodeEmbed),
459
+ commonParams: z.object({
460
+ html: z.string(),
461
+ scale: z.boolean(),
462
+ iframe: z.boolean(),
463
+ pointerEvents
464
+ }),
465
+ sticky: z.record(
466
+ z.object({
467
+ from: z.number(),
468
+ to: z.number().optional()
469
+ }).nullable()
470
+ ),
471
+ layoutParams: z.record(
472
+ z.object({
473
+ areaAnchor: z.nativeEnum(AreaAnchor),
474
+ opacity: z.number().nonnegative(),
475
+ blur: z.number(),
476
+ isDraggable: z.boolean().optional()
477
+ })
478
+ ),
479
+ state: z.record(CodeEmbedStateParamsSchema)
480
+ });
481
+ const ComponentItemSchema = ItemBaseSchema.extend({
482
+ type: z.literal(ArticleItemType.Component),
483
+ commonParams: z.object({
484
+ componentId: z.string(),
485
+ content: z.any().optional()
486
+ }),
487
+ sticky: z.record(
488
+ z.object({
489
+ from: z.number(),
490
+ to: z.number().optional()
491
+ }).nullable()
492
+ ),
493
+ layoutParams: z.record(z.object({
494
+ parameters: z.any().optional(),
495
+ opacity: z.number().nonnegative(),
496
+ blur: z.number()
497
+ })),
498
+ state: z.record(ComponentStateParamsSchema)
499
+ });
500
+ const ItemSchema = z.lazy(() => z.discriminatedUnion("type", [
501
+ ImageItemSchema,
502
+ VideoItemSchema,
503
+ RectangleItemSchema,
504
+ CustomItemSchema,
505
+ RichTextItemSchema,
506
+ VimeoEmbedItemSchema,
507
+ YoutubeEmbedItemSchema,
508
+ CodeEmbedItemSchema,
509
+ ComponentItemSchema,
510
+ ItemBaseSchema.extend({
511
+ type: z.literal(ArticleItemType.Group),
512
+ commonParams: z.object({
513
+ pointerEvents
514
+ }),
515
+ items: z.array(ItemSchema),
516
+ sticky: z.record(
517
+ z.object({
518
+ from: z.number(),
519
+ to: z.number().optional()
520
+ }).nullable()
521
+ ),
522
+ layoutParams: z.record(
523
+ z.object({
524
+ opacity: z.number().nonnegative(),
525
+ blur: z.number()
526
+ })
527
+ ),
528
+ state: z.record(GroupStateParamsSchema)
529
+ }),
530
+ ItemBaseSchema.extend({
531
+ type: z.literal(ArticleItemType.Compound),
532
+ commonParams: z.object({
533
+ overflow: z.enum(["hidden", "visible"]),
534
+ pointerEvents
535
+ }),
536
+ items: z.array(ItemSchema),
537
+ sticky: z.record(
538
+ z.object({
539
+ from: z.number(),
540
+ to: z.number().optional()
541
+ }).nullable()
542
+ ),
543
+ layoutParams: z.record(
544
+ z.object({
545
+ opacity: z.number().nonnegative()
546
+ })
547
+ ),
548
+ state: z.record(CompoundStateParamsSchema)
549
+ })
550
+ ]));
551
+ const SectionHeightSchema = z.object({
552
+ mode: z.nativeEnum(SectionHeightMode),
553
+ units: z.number().nonnegative(),
554
+ vhUnits: z.number().nonnegative().optional()
555
+ });
556
+ const SectionVideoSchema = z.object({
557
+ url: z.string(),
558
+ size: z.string(),
559
+ type: z.literal("video"),
560
+ play: z.enum(["on-click", "auto"]),
561
+ coverUrl: z.string().nullable(),
562
+ position: z.string(),
563
+ offsetX: z.number().nullable()
564
+ });
565
+ const SectionImageSchema = z.object({
566
+ url: z.string(),
567
+ type: z.literal("image"),
568
+ size: z.string(),
569
+ position: z.string(),
570
+ offsetX: z.number().nullable()
571
+ });
572
+ const SectionMediaSchema = z.discriminatedUnion("type", [SectionVideoSchema, SectionImageSchema]);
573
+ const SectionSchema = z.object({
574
+ id: z.string().min(1),
575
+ items: z.array(ItemSchema),
576
+ name: z.string().optional(),
577
+ height: z.record(SectionHeightSchema),
578
+ position: z.record(z.number()),
579
+ hidden: z.record(z.boolean()),
580
+ color: z.record(z.nullable(z.string())),
581
+ media: z.record(SectionMediaSchema).optional()
582
+ });
583
+ const ItemTriggerSchema = z.object({
584
+ itemId: z.string(),
585
+ type: z.enum(["hover-in", "hover-out", "click"]),
586
+ from: z.string(),
587
+ to: z.string()
588
+ });
589
+ const ScrollTriggerSchema = z.object({
590
+ position: z.number(),
591
+ from: z.string(),
592
+ to: z.string(),
593
+ isReverse: z.boolean()
594
+ });
595
+ const VideoInteractionActionSchema = z.object({
596
+ type: z.enum(["play", "pause"]),
597
+ itemId: z.string()
598
+ });
599
+ const StateSchema = z.object({
600
+ id: z.string(),
601
+ actions: z.array(VideoInteractionActionSchema).optional()
602
+ });
603
+ const InteractionSchema = z.object({
604
+ id: z.string(),
605
+ triggers: z.array(z.union([ItemTriggerSchema, ScrollTriggerSchema])),
606
+ states: z.array(StateSchema),
607
+ startStateId: z.string()
608
+ });
609
+ const ArticleSchema = z.object({
610
+ id: z.string().min(1),
611
+ sections: z.array(SectionSchema),
612
+ interactions: z.record(z.array(InteractionSchema))
613
+ });
614
+ const LayoutSchema = z.object({
615
+ id: z.string(),
616
+ title: z.string(),
617
+ startsWith: z.number().nonnegative(),
618
+ exemplary: z.number().positive()
619
+ });
620
+ var FontFileTypes = /* @__PURE__ */ ((FontFileTypes2) => {
621
+ FontFileTypes2["OTF"] = "otf";
622
+ FontFileTypes2["TTF"] = "ttf";
623
+ FontFileTypes2["WOFF"] = "woff";
624
+ FontFileTypes2["WOFF2"] = "woff2";
625
+ FontFileTypes2["EOT"] = "eot";
626
+ return FontFileTypes2;
627
+ })(FontFileTypes || {});
628
+ const ProjectSchema = z.object({
629
+ id: z.string().min(1),
630
+ html: z.object({
631
+ head: z.string(),
632
+ afterBodyOpen: z.string(),
633
+ beforeBodyClose: z.string()
634
+ }),
635
+ meta: z.object({
636
+ title: z.string().optional(),
637
+ description: z.string().optional(),
638
+ opengraphThumbnail: z.string().optional(),
639
+ keywords: z.string().optional(),
640
+ favicon: z.string().optional()
641
+ }),
642
+ layouts: z.array(LayoutSchema),
643
+ pages: z.array(z.object({
644
+ title: z.string(),
645
+ articleId: z.string().min(1),
646
+ slug: z.string(),
647
+ meta: z.object({
648
+ title: z.string().optional(),
649
+ description: z.string().optional(),
650
+ opengraphThumbnail: z.string().optional(),
651
+ keywords: z.string().optional(),
652
+ enabled: z.boolean()
653
+ }).optional(),
654
+ id: z.string().min(1)
655
+ })),
656
+ fonts: z.object({
657
+ google: z.string(),
658
+ adobe: z.string(),
659
+ custom: z.array(z.object({
660
+ name: z.string().min(1),
661
+ style: z.string().min(1),
662
+ weight: z.number(),
663
+ files: z.array(
664
+ z.object({
665
+ type: z.nativeEnum(FontFileTypes),
666
+ url: z.string()
667
+ })
668
+ )
669
+ }))
670
+ })
671
+ });
672
+ var KeyframeType = /* @__PURE__ */ ((KeyframeType2) => {
673
+ KeyframeType2["Dimensions"] = "dimensions";
674
+ KeyframeType2["Position"] = "position";
675
+ KeyframeType2["Rotation"] = "rotation";
676
+ KeyframeType2["BorderRadius"] = "border-radius";
677
+ KeyframeType2["BorderWidth"] = "border-width";
678
+ KeyframeType2["Opacity"] = "opacity";
679
+ KeyframeType2["Scale"] = "scale";
680
+ KeyframeType2["TextColor"] = "text-color";
681
+ KeyframeType2["LetterSpacing"] = "letter-spacing";
682
+ KeyframeType2["WordSpacing"] = "word-spacing";
683
+ KeyframeType2["Blur"] = "blur";
684
+ KeyframeType2["BackdropBlur"] = "backdrop-blur";
685
+ KeyframeType2["FXParams"] = "fx-params";
686
+ KeyframeType2["BorderFill"] = "border-fill";
687
+ KeyframeType2["Fill"] = "fill";
688
+ return KeyframeType2;
689
+ })(KeyframeType || {});
690
+ const KeyframesBaseSchema = z.object({
691
+ id: z.string().min(1),
692
+ layoutId: z.string().min(1),
693
+ itemId: z.string().min(1),
694
+ position: z.number()
695
+ });
696
+ const DimensionsKeyframeSchema = KeyframesBaseSchema.extend({
697
+ type: z.literal(KeyframeType.Dimensions),
698
+ value: z.object({
699
+ width: z.number().nonnegative(),
700
+ height: z.number().nonnegative()
701
+ })
702
+ });
703
+ const PositionKeyframeSchema = KeyframesBaseSchema.extend({
704
+ type: z.literal(KeyframeType.Position),
705
+ value: z.object({
706
+ top: z.number(),
707
+ left: z.number()
708
+ })
709
+ });
710
+ const RotationKeyframeSchema = KeyframesBaseSchema.extend({
711
+ type: z.literal(KeyframeType.Rotation),
712
+ value: z.object({
713
+ angle: z.number()
714
+ })
715
+ });
716
+ const BorderRadiusKeyframeSchema = KeyframesBaseSchema.extend({
717
+ type: z.literal(KeyframeType.BorderRadius),
718
+ value: z.object({
719
+ radius: z.number().nonnegative()
720
+ })
721
+ });
722
+ const BorderWidthKeyframeSchema = KeyframesBaseSchema.extend({
723
+ type: z.literal(KeyframeType.BorderWidth),
724
+ value: z.object({
725
+ borderWidth: z.number().nonnegative()
726
+ })
727
+ });
728
+ const BorderFillKeyframeSchema = KeyframesBaseSchema.extend({
729
+ type: z.literal(KeyframeType.BorderFill),
730
+ value: z.array(FillLayerSchema)
731
+ });
732
+ const OpacityKeyframeSchema = KeyframesBaseSchema.extend({
733
+ type: z.literal(KeyframeType.Opacity),
734
+ value: z.object({
735
+ opacity: z.number().nonnegative()
736
+ })
737
+ });
738
+ const ScaleKeyframeSchema = KeyframesBaseSchema.extend({
739
+ type: z.literal(KeyframeType.Scale),
740
+ value: z.object({
741
+ scale: z.number().nonnegative()
742
+ })
743
+ });
744
+ const BlurKeyframeSchema = KeyframesBaseSchema.extend({
745
+ type: z.literal(KeyframeType.Blur),
746
+ value: z.object({
747
+ blur: z.number()
748
+ })
749
+ });
750
+ const BackdropBlurKeyframeSchema = KeyframesBaseSchema.extend({
751
+ type: z.literal(KeyframeType.BackdropBlur),
752
+ value: z.object({
753
+ backdropBlur: z.number()
754
+ })
755
+ });
756
+ const TextColorKeyframeSchema = KeyframesBaseSchema.extend({
757
+ type: z.literal(KeyframeType.TextColor),
758
+ value: z.object({
759
+ color: z.string()
760
+ })
761
+ });
762
+ const LetterSpacingKeyframeSchema = KeyframesBaseSchema.extend({
763
+ type: z.literal(KeyframeType.LetterSpacing),
764
+ value: z.object({
765
+ letterSpacing: z.number()
766
+ })
767
+ });
768
+ const WordSpacingKeyframeSchema = KeyframesBaseSchema.extend({
769
+ type: z.literal(KeyframeType.WordSpacing),
770
+ value: z.object({
771
+ wordSpacing: z.number()
772
+ })
773
+ });
774
+ const FXParamsKeyframeSchema = KeyframesBaseSchema.extend({
775
+ type: z.literal(KeyframeType.FXParams),
776
+ value: z.record(z.string(), z.number())
777
+ });
778
+ const FillKeyframeSchema = KeyframesBaseSchema.extend({
779
+ type: z.literal(KeyframeType.Fill),
780
+ value: z.array(FillLayerSchema)
781
+ });
782
+ const KeyframeSchema = z.discriminatedUnion("type", [
783
+ DimensionsKeyframeSchema,
784
+ PositionKeyframeSchema,
785
+ RotationKeyframeSchema,
786
+ BorderRadiusKeyframeSchema,
787
+ BorderWidthKeyframeSchema,
788
+ BorderFillKeyframeSchema,
789
+ OpacityKeyframeSchema,
790
+ ScaleKeyframeSchema,
791
+ BlurKeyframeSchema,
792
+ BackdropBlurKeyframeSchema,
793
+ TextColorKeyframeSchema,
794
+ LetterSpacingKeyframeSchema,
795
+ WordSpacingKeyframeSchema,
796
+ FXParamsKeyframeSchema,
797
+ FillKeyframeSchema
798
+ ]);
799
+ const KeyframesSchema = z.array(KeyframeSchema);
800
+ class Client {
801
+ constructor(APIUrl, fetchImpl = fetch$1) {
802
+ this.fetchImpl = fetchImpl;
803
+ this.url = new URL(APIUrl);
804
+ if (!this.url.username) {
805
+ throw new Error("Project ID is missing in the URL.");
806
+ }
807
+ if (!this.url.password) {
808
+ throw new Error("API key is missing in the URL.");
809
+ }
810
+ }
811
+ static getPageMeta(projectMeta, pageMeta) {
812
+ return pageMeta.enabled ? {
813
+ title: pageMeta.title ? pageMeta.title : projectMeta.title ?? "",
814
+ description: pageMeta.description ? pageMeta.description : projectMeta.description ?? "",
815
+ keywords: pageMeta.keywords ? pageMeta.keywords : projectMeta.keywords ?? "",
816
+ opengraphThumbnail: pageMeta.opengraphThumbnail ? pageMeta.opengraphThumbnail : projectMeta.opengraphThumbnail ?? "",
817
+ favicon: projectMeta.favicon ?? ""
818
+ } : projectMeta;
819
+ }
820
+ async getPageData(pageSlug, buildMode = "default") {
821
+ try {
822
+ const project = await this.fetchProject(buildMode);
823
+ const articleId = this.findArticleIdByPageSlug(pageSlug, project.pages);
824
+ const { article, keyframes } = await this.fetchArticle(articleId, buildMode);
825
+ const page = project.pages.find((page2) => page2.slug === pageSlug);
826
+ const meta = Client.getPageMeta(project.meta, page == null ? void 0 : page.meta);
827
+ return {
828
+ project,
829
+ article,
830
+ keyframes,
831
+ meta
832
+ };
833
+ } catch (e) {
834
+ throw e;
835
+ }
836
+ }
837
+ async getProjectPagesPaths() {
838
+ try {
839
+ const { pages } = await this.fetchProject();
840
+ return pages.map((p) => p.slug);
841
+ } catch (e) {
842
+ throw e;
843
+ }
844
+ }
845
+ async getLayouts() {
846
+ try {
847
+ const { layouts } = await this.fetchProject();
848
+ return layouts;
849
+ } catch (e) {
850
+ throw e;
851
+ }
852
+ }
853
+ async fetchProject(buildMode = "default") {
854
+ const { username: projectId, password: apiKey, origin } = this.url;
855
+ const url = new URL(`/projects/${projectId}?buildMode=${buildMode}`, origin);
856
+ const response = await this.fetchImpl(url.href, {
857
+ headers: {
858
+ Authorization: `Bearer ${apiKey}`
859
+ }
860
+ });
861
+ if (!response.ok) {
862
+ throw new Error(`Failed to fetch project with id #${projectId}: ${response.statusText}`);
863
+ }
864
+ const data = await response.json();
865
+ const project = ProjectSchema.parse(data);
866
+ return project;
867
+ }
868
+ async fetchArticle(articleId, buildMode = "default") {
869
+ const { username: projectId, password: apiKey, origin } = this.url;
870
+ const url = new URL(`/projects/${projectId}/articles/${articleId}?buildMode=${buildMode}`, origin);
871
+ const response = await this.fetchImpl(url.href, {
872
+ headers: {
873
+ Authorization: `Bearer ${apiKey}`
874
+ }
875
+ });
876
+ if (!response.ok) {
877
+ throw new Error(`Failed to fetch article with id #${articleId}: ${response.statusText}`);
878
+ }
879
+ const data = await response.json();
880
+ const article = ArticleSchema.parse(data.article);
881
+ const keyframes = KeyframesSchema.parse(data.keyframes);
882
+ return { article, keyframes };
883
+ }
884
+ findArticleIdByPageSlug(slug, pages) {
885
+ const { username: projectId } = this.url;
886
+ const page = pages.find((page2) => page2.slug === slug);
887
+ if (!page) {
888
+ throw new Error(`Page with a slug ${slug} was not found in project with id #${projectId}`);
889
+ }
890
+ return page.articleId;
891
+ }
892
+ }
893
+ const FILE_TYPES_MAP = {
894
+ ttf: "truetype",
895
+ otf: "opentype"
896
+ };
897
+ class FontFaceGenerator {
898
+ constructor(fonts) {
899
+ this.fonts = fonts;
900
+ }
901
+ generate() {
902
+ return this.fonts.map((font) => {
903
+ const eotFile = font.files.find((file) => file.type === "eot");
904
+ const otherFiles = font.files.filter((file) => file.type !== "eot").map((file) => `url('${file.url}') format('${FILE_TYPES_MAP[file.type] || file.type}')`);
905
+ return `
906
+ @font-face {
907
+ font-family: "${font.name}";
908
+ font-weight: ${font.weight};
909
+ font-style: ${font.style};
910
+ ${eotFile ? `src: url('${eotFile.url}');
911
+ ` : ""}src: ${otherFiles.join(", ")};
912
+ }`;
913
+ }).join("\n");
914
+ }
915
+ }
916
+ function getLayoutStyles(layouts, layoutValues, mapToStyles) {
917
+ const mediaQueries = layouts.sort((a, b) => a.startsWith - b.startsWith).reduce(
918
+ (acc, layout) => {
919
+ const values = layoutValues.map((lv) => lv[layout.id]);
920
+ return `
921
+ ${acc}
922
+ ${layout.startsWith !== 0 ? `@media (min-width: ${layout.startsWith}px) {${mapToStyles(values, layout.exemplary)}}` : `${mapToStyles(values, layout.exemplary)}`}`;
923
+ },
924
+ ""
925
+ );
926
+ return mediaQueries;
927
+ }
928
+ function getLayoutMediaQuery(layoutId, layouts) {
929
+ const sorted = layouts.slice().sort((a, b) => a.startsWith - b.startsWith);
930
+ const layoutIndex = sorted.findIndex((l) => l.id === layoutId);
931
+ if (layoutIndex === -1) {
932
+ throw new Error(`No layout was found by the given id #${layoutId}`);
933
+ }
934
+ const current = sorted[layoutIndex];
935
+ const next = sorted[layoutIndex + 1];
936
+ if (!next) {
937
+ return `@media (min-width: ${current.startsWith}px)`;
938
+ }
939
+ return `@media (min-width: ${current.startsWith}px) and (max-width: ${next.startsWith - 1}px)`;
940
+ }
941
+ class Writer {
942
+ constructor(size) {
943
+ this.data = new Uint8Array(size);
944
+ this.idx = 0;
945
+ this.size = size;
946
+ }
947
+ getData() {
948
+ if (this.idx !== this.size) throw new Error("Mismatch between size reserved and sized used");
949
+ return this.data.slice(0, this.idx);
950
+ }
951
+ writeUint8(value) {
952
+ this.data.set([value], this.idx);
953
+ this.idx += 1;
954
+ }
955
+ writeUint16(value) {
956
+ const arr = new Uint16Array(1);
957
+ arr[0] = value;
958
+ const buffer = new Uint8Array(arr.buffer);
959
+ this.data.set([buffer[1], buffer[0]], this.idx);
960
+ this.idx += 2;
961
+ }
962
+ writeUint8Array(value) {
963
+ this.data.set(value, this.idx);
964
+ this.idx += value.length;
965
+ }
966
+ }
967
+ const getExtradata = (avccBox) => {
968
+ let i;
969
+ let size = 7;
970
+ for (i = 0; i < avccBox.SPS.length; i += 1) {
971
+ size += 2 + avccBox.SPS[i].length;
972
+ }
973
+ for (i = 0; i < avccBox.PPS.length; i += 1) {
974
+ size += 2 + avccBox.PPS[i].length;
975
+ }
976
+ const writer = new Writer(size);
977
+ writer.writeUint8(avccBox.configurationVersion);
978
+ writer.writeUint8(avccBox.AVCProfileIndication);
979
+ writer.writeUint8(avccBox.profile_compatibility);
980
+ writer.writeUint8(avccBox.AVCLevelIndication);
981
+ writer.writeUint8(avccBox.lengthSizeMinusOne + (63 << 2));
982
+ writer.writeUint8(avccBox.nb_SPS_nalus + (7 << 5));
983
+ for (i = 0; i < avccBox.SPS.length; i += 1) {
984
+ writer.writeUint16(avccBox.SPS[i].length);
985
+ writer.writeUint8Array(avccBox.SPS[i].nalu);
986
+ }
987
+ writer.writeUint8(avccBox.nb_PPS_nalus);
988
+ for (i = 0; i < avccBox.PPS.length; i += 1) {
989
+ writer.writeUint16(avccBox.PPS[i].length);
990
+ writer.writeUint8Array(avccBox.PPS[i].nalu);
991
+ }
992
+ return writer.getData();
993
+ };
994
+ const decodeVideo = (src, emitFrame, { VideoDecoder: VideoDecoder2, EncodedVideoChunk: EncodedVideoChunk2, debug }) => new Promise((resolve, reject) => {
995
+ if (debug) console.info("Decoding video from", src);
996
+ try {
997
+ const mp4boxfile = MP4Box.createFile();
998
+ let codec;
999
+ const decoder = new VideoDecoder2({
1000
+ output: (frame) => {
1001
+ createImageBitmap(frame, { resizeQuality: "low" }).then((bitmap) => {
1002
+ emitFrame(bitmap);
1003
+ frame.close();
1004
+ if (decoder.decodeQueueSize <= 0) {
1005
+ setTimeout(() => {
1006
+ if (decoder.state !== "closed") {
1007
+ decoder.close();
1008
+ resolve();
1009
+ }
1010
+ }, 500);
1011
+ }
1012
+ });
1013
+ },
1014
+ error: (e) => {
1015
+ console.error(e);
1016
+ reject(e);
1017
+ }
1018
+ });
1019
+ mp4boxfile.onReady = (info) => {
1020
+ if (info && info.videoTracks && info.videoTracks[0]) {
1021
+ [{ codec }] = info.videoTracks;
1022
+ if (debug) console.info("Video with codec:", codec);
1023
+ const avccBox = mp4boxfile.moov.traks[0].mdia.minf.stbl.stsd.entries[0].avcC;
1024
+ const extradata = getExtradata(avccBox);
1025
+ decoder.configure({ codec, description: extradata });
1026
+ mp4boxfile.setExtractionOptions(info.videoTracks[0].id);
1027
+ mp4boxfile.start();
1028
+ } else reject(new Error("URL provided is not a valid mp4 video file."));
1029
+ };
1030
+ mp4boxfile.onSamples = (track_id, ref, samples) => {
1031
+ for (let i = 0; i < samples.length; i += 1) {
1032
+ const sample = samples[i];
1033
+ const type = sample.is_sync ? "key" : "delta";
1034
+ const chunk = new EncodedVideoChunk2({
1035
+ type,
1036
+ timestamp: sample.cts,
1037
+ duration: sample.duration,
1038
+ data: sample.data
1039
+ });
1040
+ decoder.decode(chunk);
1041
+ }
1042
+ };
1043
+ fetch(src).then((res) => {
1044
+ const reader = res.body.getReader();
1045
+ let offset = 0;
1046
+ function appendBuffers({ done, value }) {
1047
+ if (done) {
1048
+ mp4boxfile.flush();
1049
+ return null;
1050
+ }
1051
+ const buf = value.buffer;
1052
+ buf.fileStart = offset;
1053
+ offset += buf.byteLength;
1054
+ mp4boxfile.appendBuffer(buf);
1055
+ return reader.read().then(appendBuffers);
1056
+ }
1057
+ return reader.read().then(appendBuffers);
1058
+ });
1059
+ } catch (e) {
1060
+ reject(e);
1061
+ }
1062
+ });
1063
+ const videoDecoder = (src, emitFrame, debug) => {
1064
+ if (typeof VideoDecoder === "function" && typeof EncodedVideoChunk === "function") {
1065
+ if (debug)
1066
+ console.info("WebCodecs is natively supported, using native version...");
1067
+ return decodeVideo(src, emitFrame, {
1068
+ VideoDecoder,
1069
+ EncodedVideoChunk,
1070
+ debug
1071
+ });
1072
+ }
1073
+ if (debug) console.info("WebCodecs is not available in this browser.");
1074
+ return Promise.resolve();
1075
+ };
1076
+ class ScrollPlaybackVideoManager {
1077
+ constructor(options) {
1078
+ this.currentTime = 0;
1079
+ this.targetTime = 0;
1080
+ this.canvas = null;
1081
+ this.context = null;
1082
+ this.frames = [];
1083
+ this.frameRate = 0;
1084
+ this.transitioning = false;
1085
+ this.debug = false;
1086
+ this.frameThreshold = 0.1;
1087
+ this.transitionSpeed = 10;
1088
+ this.useWebCodecs = true;
1089
+ this.resize = () => {
1090
+ if (this.debug) console.info("ScrollVideo resizing...");
1091
+ if (this.canvas) {
1092
+ this.setCoverStyle(this.canvas);
1093
+ } else if (this.video) {
1094
+ this.setCoverStyle(this.video);
1095
+ }
1096
+ this.paintCanvasFrame(Math.floor(this.currentTime * this.frameRate));
1097
+ };
1098
+ this.decodeVideo = () => {
1099
+ if (!this.video) return;
1100
+ if (this.useWebCodecs && this.video.src) {
1101
+ videoDecoder(
1102
+ this.video.src,
1103
+ (frame) => {
1104
+ this.frames.push(frame);
1105
+ },
1106
+ this.debug
1107
+ ).then(() => {
1108
+ if (!this.video || !this.container) return;
1109
+ if (this.frames.length === 0) {
1110
+ if (this.debug) console.error("No frames were received from webCodecs");
1111
+ return;
1112
+ }
1113
+ this.frameRate = this.frames.length / this.video.duration;
1114
+ if (this.debug) console.info("Received", this.frames.length, "frames");
1115
+ this.canvas = document.createElement("canvas");
1116
+ this.context = this.canvas.getContext("2d");
1117
+ this.video.style.display = "none";
1118
+ this.container.appendChild(this.canvas);
1119
+ this.paintCanvasFrame(Math.floor(this.currentTime * this.frameRate));
1120
+ }).catch(() => {
1121
+ if (this.debug) console.error("Error encountered while decoding video");
1122
+ this.frames = [];
1123
+ this.video.load();
1124
+ });
1125
+ }
1126
+ };
1127
+ this.resizeObserver = new ResizeObserver(() => {
1128
+ this.resize();
1129
+ });
1130
+ const {
1131
+ src,
1132
+ videoContainer
1133
+ } = options;
1134
+ if (typeof document !== "object") {
1135
+ console.error("ScrollVideo must be initiated in a DOM context");
1136
+ return;
1137
+ }
1138
+ if (!videoContainer) {
1139
+ console.error("scrollVideoContainer must be a valid DOM object");
1140
+ return;
1141
+ }
1142
+ if (!src) {
1143
+ console.error("Must provide valid video src to ScrollVideo");
1144
+ return;
1145
+ }
1146
+ this.container = typeof videoContainer === "string" ? document.getElementById(videoContainer) : videoContainer;
1147
+ this.resizeObserver.observe(this.container);
1148
+ this.video = document.createElement("video");
1149
+ this.video.src = src;
1150
+ this.video.preload = "auto";
1151
+ this.video.tabIndex = 0;
1152
+ this.video.playsInline = true;
1153
+ this.video.muted = true;
1154
+ this.video.pause();
1155
+ this.video.load();
1156
+ this.container.appendChild(this.video);
1157
+ const browserEngine = new UAParser().getEngine();
1158
+ this.isSafari = browserEngine.name === "WebKit";
1159
+ if (this.debug && this.isSafari) console.info("Safari browser detected");
1160
+ this.video.addEventListener("loadedmetadata", () => this.setTargetTimePercent(0, true), { once: true });
1161
+ this.video.addEventListener("progress", this.resize);
1162
+ this.decodeVideo();
1163
+ }
1164
+ setCoverStyle(el) {
1165
+ if (el && this.container) {
1166
+ el.style.position = "absolute";
1167
+ el.style.top = "50%";
1168
+ el.style.left = "50%";
1169
+ el.style.transform = "translate(-50%, -50%)";
1170
+ const { width: containerWidth, height: containerHeight } = this.container.getBoundingClientRect();
1171
+ const width = el.videoWidth || el.width;
1172
+ const height = el.videoHeight || el.height;
1173
+ if (containerWidth / containerHeight > width / height) {
1174
+ el.style.width = "100%";
1175
+ el.style.height = "auto";
1176
+ } else {
1177
+ el.style.height = "100%";
1178
+ el.style.width = "auto";
1179
+ }
1180
+ }
1181
+ }
1182
+ paintCanvasFrame(frameNum) {
1183
+ if (this.canvas) {
1184
+ const frameIdx = Math.min(frameNum, this.frames.length - 1);
1185
+ const currFrame = this.frames[frameIdx];
1186
+ if (currFrame && this.container) {
1187
+ if (this.debug) console.info("Painting frame", frameIdx);
1188
+ this.canvas.width = currFrame.width;
1189
+ this.canvas.height = currFrame.height;
1190
+ const { width, height } = this.container.getBoundingClientRect();
1191
+ this.resetCanvasDimensions(width, height, currFrame.width, currFrame.height);
1192
+ this.context.drawImage(currFrame, 0, 0, currFrame.width, currFrame.height);
1193
+ }
1194
+ }
1195
+ }
1196
+ transitionToTargetTime(jump) {
1197
+ if (!this.video) return;
1198
+ if (this.debug) console.info("Transitioning targetTime:", this.targetTime, "currentTime:", this.currentTime);
1199
+ if (isNaN(this.targetTime) || Math.abs(this.currentTime - this.targetTime) < this.frameThreshold) {
1200
+ this.video.pause();
1201
+ this.transitioning = false;
1202
+ return;
1203
+ }
1204
+ if (this.targetTime > this.video.duration) {
1205
+ this.targetTime = this.video.duration;
1206
+ }
1207
+ if (this.targetTime < 0) {
1208
+ this.targetTime = 0;
1209
+ }
1210
+ const transitionForward = this.targetTime - this.currentTime;
1211
+ if (this.canvas) {
1212
+ this.currentTime += transitionForward / (256 / this.transitionSpeed);
1213
+ if (jump) {
1214
+ this.currentTime = this.targetTime;
1215
+ }
1216
+ this.paintCanvasFrame(Math.floor(this.currentTime * this.frameRate));
1217
+ } else if (jump || this.isSafari || this.targetTime - this.currentTime < 0) {
1218
+ this.video.pause();
1219
+ this.currentTime += transitionForward / (64 / this.transitionSpeed);
1220
+ if (jump) {
1221
+ this.currentTime = this.targetTime;
1222
+ }
1223
+ this.video.currentTime = this.currentTime;
1224
+ } else {
1225
+ const playbackRate = Math.max(Math.min(transitionForward * 4, this.transitionSpeed, 16), 1);
1226
+ if (this.debug) console.info("ScrollVideo playbackRate:", playbackRate);
1227
+ if (!isNaN(playbackRate)) {
1228
+ this.video.playbackRate = playbackRate;
1229
+ this.video.play();
1230
+ }
1231
+ this.currentTime = this.video.currentTime;
1232
+ }
1233
+ if (typeof requestAnimationFrame === "function") {
1234
+ requestAnimationFrame(() => this.transitionToTargetTime(jump));
1235
+ }
1236
+ }
1237
+ resetCanvasDimensions(w, h, frameW, frameH) {
1238
+ if (!this.canvas) return;
1239
+ if (w / h > frameW / frameH) {
1240
+ this.canvas.style.width = "100%";
1241
+ this.canvas.style.height = "auto";
1242
+ } else {
1243
+ this.canvas.style.height = "100%";
1244
+ this.canvas.style.width = "auto";
1245
+ }
1246
+ }
1247
+ setTargetTimePercent(setPercentage, jump = true) {
1248
+ if (!this.video) return;
1249
+ this.targetTime = Math.max(Math.min(setPercentage, 1), 0) * (this.frames.length && this.frameRate ? this.frames.length / this.frameRate : this.video.duration);
1250
+ if (!jump && Math.abs(this.currentTime - this.targetTime) < this.frameThreshold) return;
1251
+ if (!jump && this.transitioning) return;
1252
+ if (!this.canvas && !this.video.paused) this.video.play();
1253
+ this.transitioning = true;
1254
+ this.transitionToTargetTime(jump);
1255
+ }
1256
+ destroy() {
1257
+ var _a;
1258
+ this.resizeObserver.unobserve(this.container);
1259
+ (_a = this.video) == null ? void 0 : _a.removeEventListener("progress", this.resize);
1260
+ if (this.debug) console.info("Destroying ScrollVideo");
1261
+ if (this.container) this.container.innerHTML = "";
1262
+ }
1263
+ }
1264
+ const wrapper = "ControlSlider-module__wrapper___sHEkd";
1265
+ const sliderItem = "ControlSlider-module__sliderItem___QQSkR";
1266
+ const sliderImage = "ControlSlider-module__sliderImage___9hRl-";
1267
+ const arrow = "ControlSlider-module__arrow___05ghY";
1268
+ const arrowVertical = "ControlSlider-module__arrowVertical___tBfVN";
1269
+ const nextArrow = "ControlSlider-module__nextArrow___-30Yc";
1270
+ const arrowInner = "ControlSlider-module__arrowInner___aEra3";
1271
+ const arrowIcon = "ControlSlider-module__arrowIcon___S4ztF";
1272
+ const arrowImg = "ControlSlider-module__arrowImg___2dwJW";
1273
+ const mirror = "ControlSlider-module__mirror___brd6U";
1274
+ const pagination = "ControlSlider-module__pagination___bicLF";
1275
+ const paginationInner = "ControlSlider-module__paginationInner___bT-P-";
1276
+ const paginationVertical = "ControlSlider-module__paginationVertical___zYqKw";
1277
+ const paginationItem = "ControlSlider-module__paginationItem___nTRbk";
1278
+ const dot = "ControlSlider-module__dot___p1Qun";
1279
+ const activeDot = "ControlSlider-module__activeDot___LHFaj";
1280
+ const paginationInsideBottom = "ControlSlider-module__paginationInsideBottom___R3FWn";
1281
+ const paginationInsideTop = "ControlSlider-module__paginationInsideTop___V-qb-";
1282
+ const paginationOutsideBottom = "ControlSlider-module__paginationOutsideBottom___14w8D";
1283
+ const paginationOutsideTop = "ControlSlider-module__paginationOutsideTop___SCLqB";
1284
+ const paginationInsideLeft = "ControlSlider-module__paginationInsideLeft___yOBRZ";
1285
+ const paginationInsideRight = "ControlSlider-module__paginationInsideRight___Rtt3o";
1286
+ const paginationOutsideLeft = "ControlSlider-module__paginationOutsideLeft___lahaw";
1287
+ const paginationOutsideRight = "ControlSlider-module__paginationOutsideRight___EtuQa";
1288
+ const imgWrapper = "ControlSlider-module__imgWrapper___UjEgB";
1289
+ const captionBlock = "ControlSlider-module__captionBlock___dJ6-j";
1290
+ const captionTextWrapper = "ControlSlider-module__captionTextWrapper___HFlpf";
1291
+ const captionText = "ControlSlider-module__captionText___uGBVc";
1292
+ const active = "ControlSlider-module__active___WZK4G";
1293
+ const withPointerEvents = "ControlSlider-module__withPointerEvents___t-18M";
1294
+ const topLeftAlignment = "ControlSlider-module__topLeftAlignment___zjnGM";
1295
+ const topCenterAlignment = "ControlSlider-module__topCenterAlignment___gD1xW";
1296
+ const topRightAlignment = "ControlSlider-module__topRightAlignment___NMapS";
1297
+ const middleLeftAlignment = "ControlSlider-module__middleLeftAlignment___OnUrY";
1298
+ const middleCenterAlignment = "ControlSlider-module__middleCenterAlignment___Tdkl0";
1299
+ const middleRightAlignment = "ControlSlider-module__middleRightAlignment___wEbfX";
1300
+ const bottomLeftAlignment = "ControlSlider-module__bottomLeftAlignment___cTP2-";
1301
+ const bottomCenterAlignment = "ControlSlider-module__bottomCenterAlignment___c54fB";
1302
+ const bottomRightAlignment = "ControlSlider-module__bottomRightAlignment___kEwrz";
1303
+ const clickOverlay = "ControlSlider-module__clickOverlay___DZA28";
1304
+ const contain = "ControlSlider-module__contain___pLyq7";
1305
+ const cover = "ControlSlider-module__cover___KdDat";
1306
+ const styles$3 = {
1307
+ wrapper,
1308
+ sliderItem,
1309
+ sliderImage,
1310
+ arrow,
1311
+ arrowVertical,
1312
+ nextArrow,
1313
+ arrowInner,
1314
+ arrowIcon,
1315
+ arrowImg,
1316
+ mirror,
1317
+ pagination,
1318
+ paginationInner,
1319
+ paginationVertical,
1320
+ paginationItem,
1321
+ dot,
1322
+ activeDot,
1323
+ paginationInsideBottom,
1324
+ paginationInsideTop,
1325
+ paginationOutsideBottom,
1326
+ paginationOutsideTop,
1327
+ paginationInsideLeft,
1328
+ paginationInsideRight,
1329
+ paginationOutsideLeft,
1330
+ paginationOutsideRight,
1331
+ imgWrapper,
1332
+ captionBlock,
1333
+ captionTextWrapper,
1334
+ captionText,
1335
+ active,
1336
+ withPointerEvents,
1337
+ topLeftAlignment,
1338
+ topCenterAlignment,
1339
+ topRightAlignment,
1340
+ middleLeftAlignment,
1341
+ middleCenterAlignment,
1342
+ middleRightAlignment,
1343
+ bottomLeftAlignment,
1344
+ bottomCenterAlignment,
1345
+ bottomRightAlignment,
1346
+ clickOverlay,
1347
+ contain,
1348
+ cover
1349
+ };
1350
+ const link$1 = "RichTextRenderer-module__link___BWeZ2";
1351
+ const styles$2 = {
1352
+ link: link$1
1353
+ };
1354
+ const RichTextRenderer = ({ content }) => {
1355
+ const getChildren = (children) => {
1356
+ return children.map((child, i) => {
1357
+ if (child.type === "link") {
1358
+ return /* @__PURE__ */ jsx("a", { className: styles$2.link, href: child.value, target: child.target, children: getChildren(child.children) }, i);
1359
+ }
1360
+ return /* @__PURE__ */ jsx("span", { style: getLeafCss(child), children: child.text }, i);
1361
+ });
1362
+ };
1363
+ return /* @__PURE__ */ jsx(Fragment, { children: content.map((block, i) => {
1364
+ const children = block.children;
1365
+ return /* @__PURE__ */ jsx("div", { children: getChildren(children) }, i);
1366
+ }) });
1367
+ };
1368
+ function getLeafCss(leaf) {
1369
+ return {
1370
+ ...leaf.fontWeight && { fontWeight: leaf.fontWeight },
1371
+ ...leaf.fontStyle && { fontStyle: leaf.fontStyle },
1372
+ ...leaf.textDecoration && { textDecoration: leaf.textDecoration },
1373
+ ...leaf.textTransform && { textTransform: leaf.textTransform },
1374
+ ...leaf.fontVariant && { fontVariant: leaf.fontVariant },
1375
+ ...leaf.verticalAlign && {
1376
+ verticalAlign: leaf.verticalAlign,
1377
+ lineHeight: "0px"
1378
+ }
1379
+ };
1380
+ }
1381
+ function scalingValue(value, isEditor = false) {
1382
+ return isEditor ? `calc(var(--cntrl-article-width) * ${value})` : `${value * 100}vw`;
1383
+ }
1384
+ const svg = "SvgImage-module__svg___q3xE-";
1385
+ const img = "SvgImage-module__img___VsTm-";
1386
+ const styles$1 = {
1387
+ svg,
1388
+ img
1389
+ };
1390
+ const SvgImage = ({ url, fill = "#000000", hoverFill = "#CCCCCC", className = "" }) => {
1391
+ const [supportsMask, setSupportsMask] = useState(true);
1392
+ useEffect(() => {
1393
+ if (typeof window !== "undefined" && window.CSS) {
1394
+ const supported = CSS.supports("mask-image", 'url("")') || CSS.supports("-webkit-mask-image", 'url("")');
1395
+ setSupportsMask(supported);
1396
+ }
1397
+ }, []);
1398
+ if (!url.endsWith(".svg") || !supportsMask) {
1399
+ return /* @__PURE__ */ jsx("img", { src: url, alt: "", className: cn(styles$1.img, className) });
1400
+ }
1401
+ return /* @__PURE__ */ jsx(
1402
+ "span",
1403
+ {
1404
+ "data-supports-mask": supportsMask,
1405
+ className: cn(styles$1.svg, className),
1406
+ style: {
1407
+ "--svg": `url(${url})`,
1408
+ "--fill": fill,
1409
+ "--hover-fill": hoverFill
1410
+ }
1411
+ }
1412
+ );
1413
+ };
1414
+ const alignmentClassName = {
1415
+ "top-left": styles$3.topLeftAlignment,
1416
+ "top-center": styles$3.topCenterAlignment,
1417
+ "top-right": styles$3.topRightAlignment,
1418
+ "middle-left": styles$3.middleLeftAlignment,
1419
+ "middle-center": styles$3.middleCenterAlignment,
1420
+ "middle-right": styles$3.middleRightAlignment,
1421
+ "bottom-left": styles$3.bottomLeftAlignment,
1422
+ "bottom-center": styles$3.bottomCenterAlignment,
1423
+ "bottom-right": styles$3.bottomRightAlignment
1424
+ };
1425
+ function ControlSlider({ settings, content, styles: sliderStyles, isEditor }) {
1426
+ const [sliderRef, setSliderRef] = useState(null);
1427
+ const { widthSettings, fontSettings, letterSpacing, textAlign, wordSpacing, fontSizeLineHeight, textAppearance, color } = sliderStyles.caption;
1428
+ const [sliderDimensions, setSliderDimensions] = useState(void 0);
1429
+ const [wrapperRef, setWrapperRef] = useState(null);
1430
+ const [currentSlideIndex, setCurrentSlideIndex] = useState(0);
1431
+ const [key, setKey] = useState(0);
1432
+ const { direction, transition, controls, pagination: pagination2, caption, triggers } = settings;
1433
+ const prevSliderTypeRef = useRef(transition.type);
1434
+ const { x: controlsOffsetX, y: controlsOffsetY } = settings.controls.offset;
1435
+ const handleArrowClick = (dir) => {
1436
+ if (sliderRef) {
1437
+ sliderRef.go(dir);
1438
+ }
1439
+ };
1440
+ useEffect(() => {
1441
+ if (!wrapperRef) return;
1442
+ const observer = new ResizeObserver((entries) => {
1443
+ if (!sliderRef) return;
1444
+ const [wrapper2] = entries;
1445
+ setSliderDimensions({
1446
+ width: Math.round(wrapper2.contentRect.width),
1447
+ height: Math.round(wrapper2.contentRect.height)
1448
+ });
1449
+ });
1450
+ observer.observe(wrapperRef);
1451
+ return () => observer.unobserve(wrapperRef);
1452
+ }, [wrapperRef]);
1453
+ useEffect(() => {
1454
+ if (!sliderRef || prevSliderTypeRef.current === transition.type) return;
1455
+ setKey((prev) => prev + 1);
1456
+ prevSliderTypeRef.current = transition.type;
1457
+ }, [transition.type]);
1458
+ return /* @__PURE__ */ jsx("div", { className: cn(styles$3.wrapper, { [styles$3.editor]: isEditor }), ref: setWrapperRef, children: /* @__PURE__ */ jsxs(
1459
+ "div",
1460
+ {
1461
+ className: styles$3.sliderInner,
1462
+ style: {
1463
+ width: sliderDimensions ? sliderDimensions.width : "100%",
1464
+ height: sliderDimensions ? sliderDimensions.height : "100%",
1465
+ backgroundColor: transition.backgroundColor && transition.type === "fade in" ? transition.backgroundColor : "transparent"
1466
+ },
1467
+ children: [
1468
+ settings.caption.isActive && /* @__PURE__ */ jsx(
1469
+ "div",
1470
+ {
1471
+ className: cn(styles$3.captionBlock),
1472
+ children: /* @__PURE__ */ jsx(
1473
+ "div",
1474
+ {
1475
+ className: styles$3.captionTextWrapper,
1476
+ children: content.map((item, index) => /* @__PURE__ */ jsx(
1477
+ "div",
1478
+ {
1479
+ className: cn(styles$3.captionText, alignmentClassName[caption.alignment], {
1480
+ [styles$3.withPointerEvents]: index === currentSlideIndex && isEditor,
1481
+ [styles$3.active]: index === currentSlideIndex
1482
+ }),
1483
+ style: {
1484
+ fontFamily: fontSettings.fontFamily,
1485
+ fontWeight: fontSettings.fontWeight,
1486
+ fontStyle: fontSettings.fontStyle,
1487
+ width: widthSettings.sizing === "auto" ? "max-content" : scalingValue(widthSettings.width, isEditor),
1488
+ letterSpacing: scalingValue(letterSpacing, isEditor),
1489
+ wordSpacing: scalingValue(wordSpacing, isEditor),
1490
+ textAlign,
1491
+ fontSize: scalingValue(fontSizeLineHeight.fontSize, isEditor),
1492
+ lineHeight: scalingValue(fontSizeLineHeight.lineHeight, isEditor),
1493
+ textTransform: textAppearance.textTransform ?? "none",
1494
+ textDecoration: textAppearance.textDecoration ?? "none",
1495
+ fontVariant: textAppearance.fontVariant ?? "normal",
1496
+ color,
1497
+ transitionDuration: transition.duration ? `${Math.round(parseInt(transition.duration) / 2)}ms` : "500ms"
1498
+ },
1499
+ children: /* @__PURE__ */ jsx(
1500
+ "div",
1501
+ {
1502
+ "data-styles": "caption",
1503
+ className: styles$3.captionTextInner,
1504
+ style: {
1505
+ "--link-hover-color": caption.hover,
1506
+ position: "relative",
1507
+ top: scalingValue(caption.offset.y, isEditor),
1508
+ left: scalingValue(caption.offset.x, isEditor)
1509
+ },
1510
+ children: /* @__PURE__ */ jsx(RichTextRenderer, { content: item.imageCaption })
1511
+ }
1512
+ )
1513
+ },
1514
+ index
1515
+ ))
1516
+ }
1517
+ )
1518
+ }
1519
+ ),
1520
+ /* @__PURE__ */ jsx(
1521
+ Splide,
1522
+ {
1523
+ onMove: (e) => {
1524
+ setCurrentSlideIndex(e.index);
1525
+ },
1526
+ ref: setSliderRef,
1527
+ options: {
1528
+ arrows: false,
1529
+ speed: transition.duration ? parseInt(transition.duration) : 500,
1530
+ autoplay: isEditor ? false : triggers.autoPlay !== null,
1531
+ ...triggers.autoPlay !== null && {
1532
+ interval: parseInt(triggers.autoPlay) * 1e3
1533
+ },
1534
+ direction: direction === "horiz" || transition.type === "fade in" ? "ltr" : "ttb",
1535
+ pagination: false,
1536
+ drag: triggers.triggersList.drag,
1537
+ perPage: 1,
1538
+ width: sliderDimensions ? sliderDimensions.width : "100%",
1539
+ height: sliderDimensions ? sliderDimensions.height : "100%",
1540
+ type: transition.type === "fade in" ? "fade" : "loop",
1541
+ rewind: true
1542
+ },
1543
+ children: content.map((item, index) => /* @__PURE__ */ jsx(SplideSlide, { children: /* @__PURE__ */ jsx(
1544
+ "div",
1545
+ {
1546
+ className: styles$3.sliderItem,
1547
+ children: /* @__PURE__ */ jsx(
1548
+ "div",
1549
+ {
1550
+ className: styles$3.imgWrapper,
1551
+ children: /* @__PURE__ */ jsx(
1552
+ "img",
1553
+ {
1554
+ className: cn(styles$3.sliderImage, {
1555
+ [styles$3.contain]: item.image.objectFit === "contain",
1556
+ [styles$3.cover]: item.image.objectFit === "cover"
1557
+ }),
1558
+ src: item.image.url,
1559
+ alt: item.image.name ?? ""
1560
+ }
1561
+ )
1562
+ }
1563
+ )
1564
+ }
1565
+ ) }, index))
1566
+ },
1567
+ key
1568
+ ),
1569
+ controls.isActive && /* @__PURE__ */ jsxs(Fragment, { children: [
1570
+ /* @__PURE__ */ jsx(
1571
+ "div",
1572
+ {
1573
+ className: cn(styles$3.arrow, {
1574
+ [styles$3.arrowVertical]: direction === "vert"
1575
+ }),
1576
+ style: {
1577
+ color: controls.color,
1578
+ ["--arrow-hover-color"]: controls.hover
1579
+ },
1580
+ children: /* @__PURE__ */ jsxs(
1581
+ "button",
1582
+ {
1583
+ onClick: () => {
1584
+ handleArrowClick("-1");
1585
+ },
1586
+ className: styles$3.arrowInner,
1587
+ style: {
1588
+ transform: `translate(${scalingValue(controlsOffsetX, isEditor)}, ${scalingValue(controlsOffsetY * (direction === "horiz" ? 1 : -1), isEditor)}) scale(${settings.controls.scale / 100}) rotate(${direction === "horiz" ? "0deg" : "90deg"})`
1589
+ },
1590
+ children: [
1591
+ controls.arrowsImgUrl && /* @__PURE__ */ jsx(
1592
+ SvgImage,
1593
+ {
1594
+ url: controls.arrowsImgUrl,
1595
+ fill: controls.color,
1596
+ hoverFill: controls.hover,
1597
+ className: cn(styles$3.arrowImg, styles$3.mirror)
1598
+ }
1599
+ ),
1600
+ !controls.arrowsImgUrl && /* @__PURE__ */ jsx(ArrowIcon, { color: controls.color, className: cn(styles$3.arrowIcon, styles$3.arrowImg, styles$3.mirror) })
1601
+ ]
1602
+ }
1603
+ )
1604
+ }
1605
+ ),
1606
+ /* @__PURE__ */ jsx(
1607
+ "div",
1608
+ {
1609
+ className: cn(styles$3.arrow, styles$3.nextArrow, {
1610
+ [styles$3.arrowVertical]: direction === "vert"
1611
+ }),
1612
+ style: {
1613
+ color: controls.color,
1614
+ ["--arrow-hover-color"]: controls.hover
1615
+ },
1616
+ children: /* @__PURE__ */ jsxs(
1617
+ "button",
1618
+ {
1619
+ className: styles$3.arrowInner,
1620
+ onClick: () => handleArrowClick("+1"),
1621
+ style: {
1622
+ transform: `translate(${scalingValue(controlsOffsetX * (direction === "horiz" ? -1 : 1), isEditor)}, ${scalingValue(controlsOffsetY, isEditor)}) scale(${settings.controls.scale / 100}) rotate(${direction === "horiz" ? "0deg" : "90deg"})`
1623
+ },
1624
+ children: [
1625
+ controls.arrowsImgUrl && /* @__PURE__ */ jsx(
1626
+ SvgImage,
1627
+ {
1628
+ url: controls.arrowsImgUrl,
1629
+ fill: controls.color,
1630
+ hoverFill: controls.hover,
1631
+ className: styles$3.arrowImg
1632
+ }
1633
+ ),
1634
+ !controls.arrowsImgUrl && /* @__PURE__ */ jsx(ArrowIcon, { color: controls.color, className: cn(styles$3.arrowIcon, styles$3.arrowImg) })
1635
+ ]
1636
+ }
1637
+ )
1638
+ }
1639
+ )
1640
+ ] }),
1641
+ triggers.triggersList.click && /* @__PURE__ */ jsx(
1642
+ "div",
1643
+ {
1644
+ className: styles$3.clickOverlay,
1645
+ onClick: () => {
1646
+ if (sliderRef) {
1647
+ sliderRef.go("+1");
1648
+ }
1649
+ }
1650
+ }
1651
+ ),
1652
+ pagination2.isActive && /* @__PURE__ */ jsx(
1653
+ "div",
1654
+ {
1655
+ className: cn(styles$3.pagination, {
1656
+ [styles$3.paginationInsideBottom]: pagination2.position === "inside-1" && direction === "horiz",
1657
+ [styles$3.paginationInsideTop]: pagination2.position === "inside-2" && direction === "horiz",
1658
+ [styles$3.paginationOutsideBottom]: pagination2.position === "outside-1" && direction === "horiz",
1659
+ [styles$3.paginationOutsideTop]: pagination2.position === "outside-2" && direction === "horiz",
1660
+ [styles$3.paginationInsideLeft]: pagination2.position === "inside-1" && direction === "vert",
1661
+ [styles$3.paginationInsideRight]: pagination2.position === "inside-2" && direction === "vert",
1662
+ [styles$3.paginationOutsideLeft]: pagination2.position === "outside-1" && direction === "vert",
1663
+ [styles$3.paginationOutsideRight]: pagination2.position === "outside-2" && direction === "vert",
1664
+ [styles$3.paginationVertical]: direction === "vert"
1665
+ }),
1666
+ children: /* @__PURE__ */ jsx(
1667
+ "div",
1668
+ {
1669
+ className: styles$3.paginationInner,
1670
+ style: {
1671
+ backgroundColor: pagination2.colors[2],
1672
+ transform: `scale(${pagination2.scale / 100}) translate(${scalingValue(pagination2.offset.x, isEditor)}, ${scalingValue(pagination2.offset.y, isEditor)}) rotate(${direction === "horiz" ? "0deg" : "90deg"})`
1673
+ },
1674
+ children: content.map((_, index) => /* @__PURE__ */ jsx(
1675
+ "button",
1676
+ {
1677
+ onClick: () => {
1678
+ if (sliderRef) {
1679
+ sliderRef.go(index);
1680
+ }
1681
+ },
1682
+ className: cn(styles$3.paginationItem),
1683
+ children: /* @__PURE__ */ jsx(
1684
+ "div",
1685
+ {
1686
+ className: cn(styles$3.dot, {
1687
+ [styles$3.activeDot]: index === currentSlideIndex
1688
+ }),
1689
+ style: {
1690
+ backgroundColor: index === currentSlideIndex ? pagination2.colors[0] : pagination2.colors[1],
1691
+ ["--pagination-hover-color"]: pagination2.hover
1692
+ }
1693
+ }
1694
+ )
1695
+ },
1696
+ index
1697
+ ))
1698
+ }
1699
+ )
1700
+ }
1701
+ )
1702
+ ]
1703
+ }
1704
+ ) });
1705
+ }
1706
+ function ArrowIcon({ color, className }) {
1707
+ return /* @__PURE__ */ jsx("svg", { viewBox: "0 0 10 18", className, children: /* @__PURE__ */ jsx("g", { id: "Symbols", stroke: "none", strokeWidth: "1", fillRule: "evenodd", children: /* @__PURE__ */ jsx("path", { d: "M-3.70710678,4.29289322 C-3.34662282,3.93240926 -2.77939176,3.90467972 -2.38710056,4.20970461 L-2.29289322,4.29289322 L5,11.585 L12.2928932,4.29289322 C12.6533772,3.93240926 13.2206082,3.90467972 13.6128994,4.20970461 L13.7071068,4.29289322 C14.0675907,4.65337718 14.0953203,5.22060824 13.7902954,5.61289944 L13.7071068,5.70710678 L5.70710678,13.7071068 C5.34662282,14.0675907 4.77939176,14.0953203 4.38710056,13.7902954 L4.29289322,13.7071068 L-3.70710678,5.70710678 C-4.09763107,5.31658249 -4.09763107,4.68341751 -3.70710678,4.29289322 Z", id: "Shape-Copy", fill: color, transform: "translate(5, 9) rotate(-90) translate(-5, -9)" }) }) });
1708
+ }
1709
+ const ControlSliderComponent = {
1710
+ element: ControlSlider,
1711
+ id: "control-slider",
1712
+ name: "Slider",
1713
+ preview: {
1714
+ type: "video",
1715
+ url: "https://cdn.cntrl.site/projects/01JJKT02AWY2FGN2QJ7A173RNZ/articles-assets/01K7EQ4ME6CP4KX7TJ4HPAXFEW.mp4"
1716
+ },
1717
+ defaultSize: {
1718
+ width: 400,
1719
+ height: 400
1720
+ },
1721
+ schema: {
1722
+ type: "object",
1723
+ properties: {
1724
+ settings: {
1725
+ layoutBased: true,
1726
+ type: "object",
1727
+ properties: {
1728
+ triggers: {
1729
+ name: "triggers",
1730
+ icon: "target",
1731
+ tooltip: "Triggers",
1732
+ type: "object",
1733
+ properties: {
1734
+ triggersList: {
1735
+ type: "object",
1736
+ display: {
1737
+ type: "toggle-ratio-group"
1738
+ },
1739
+ properties: {
1740
+ click: {
1741
+ type: "boolean"
1742
+ },
1743
+ drag: {
1744
+ type: "boolean"
1745
+ }
1746
+ }
1747
+ },
1748
+ autoPlay: {
1749
+ type: ["string", "null"],
1750
+ label: "Auto",
1751
+ display: {
1752
+ type: "step-selector"
1753
+ },
1754
+ enum: [null, "1s", "2s", "3s", "4s", "5s"]
1755
+ }
1756
+ }
1757
+ },
1758
+ direction: {
1759
+ name: "direction",
1760
+ icon: "horizontal-resize",
1761
+ tooltip: "Direction",
1762
+ type: "string",
1763
+ display: {
1764
+ type: "ratio-group"
1765
+ },
1766
+ enum: ["horiz", "vert"]
1767
+ },
1768
+ transition: {
1769
+ name: "transit",
1770
+ icon: "transition",
1771
+ tooltip: "Transition",
1772
+ type: "object",
1773
+ properties: {
1774
+ type: {
1775
+ type: "string",
1776
+ display: {
1777
+ type: "ratio-group"
1778
+ },
1779
+ enum: ["slide", "fade in"]
1780
+ },
1781
+ backgroundColor: {
1782
+ type: ["string", "null"],
1783
+ name: "BG Color",
1784
+ display: {
1785
+ visible: false,
1786
+ type: "settings-color-picker",
1787
+ format: "single"
1788
+ }
1789
+ },
1790
+ duration: {
1791
+ type: "string",
1792
+ label: "hourglass-icon",
1793
+ display: {
1794
+ type: "step-selector"
1795
+ },
1796
+ enum: ["100ms", "250ms", "500ms", "1000ms", "1500ms", "2000ms"]
1797
+ }
1798
+ }
1799
+ },
1800
+ controls: {
1801
+ name: "controls",
1802
+ icon: "controls",
1803
+ tooltip: "Controls",
1804
+ type: "object",
1805
+ properties: {
1806
+ isActive: {
1807
+ type: "boolean",
1808
+ display: {
1809
+ type: "setting-toggle"
1810
+ }
1811
+ },
1812
+ arrowsImgUrl: {
1813
+ type: ["string", "null"],
1814
+ display: {
1815
+ type: "settings-image-input"
1816
+ }
1817
+ },
1818
+ offset: {
1819
+ type: "object",
1820
+ display: {
1821
+ type: "offset-controls"
1822
+ },
1823
+ properties: {
1824
+ x: {
1825
+ type: "number"
1826
+ },
1827
+ y: {
1828
+ type: "number"
1829
+ }
1830
+ }
1831
+ },
1832
+ scale: {
1833
+ type: "number",
1834
+ name: "scale",
1835
+ min: 50,
1836
+ max: 600,
1837
+ display: {
1838
+ type: "range-control"
1839
+ }
1840
+ },
1841
+ color: {
1842
+ name: "color",
1843
+ type: "string",
1844
+ display: {
1845
+ type: "settings-color-picker",
1846
+ format: "single"
1847
+ }
1848
+ },
1849
+ hover: {
1850
+ name: "hover",
1851
+ type: "string",
1852
+ display: {
1853
+ type: "settings-color-picker",
1854
+ format: "single"
1855
+ }
1856
+ }
1857
+ }
1858
+ },
1859
+ pagination: {
1860
+ name: "nav",
1861
+ icon: "pagination",
1862
+ tooltip: "Navigation",
1863
+ type: "object",
1864
+ properties: {
1865
+ isActive: {
1866
+ type: "boolean",
1867
+ display: {
1868
+ type: "setting-toggle"
1869
+ }
1870
+ },
1871
+ position: {
1872
+ name: "nav position",
1873
+ display: {
1874
+ type: "socket",
1875
+ direction: "horizontal"
1876
+ },
1877
+ type: "string",
1878
+ enum: ["outside-1", "outside-2", "inside-1", "inside-2"]
1879
+ },
1880
+ offset: {
1881
+ type: "object",
1882
+ display: {
1883
+ type: "offset-controls"
1884
+ },
1885
+ properties: {
1886
+ x: {
1887
+ type: "number"
1888
+ },
1889
+ y: {
1890
+ type: "number"
1891
+ }
1892
+ }
1893
+ },
1894
+ scale: {
1895
+ type: "number",
1896
+ name: "scale",
1897
+ min: 10,
1898
+ max: 400,
1899
+ display: {
1900
+ type: "range-control"
1901
+ }
1902
+ },
1903
+ colors: {
1904
+ display: {
1905
+ type: "settings-color-picker",
1906
+ format: "multiple"
1907
+ },
1908
+ name: "color",
1909
+ type: "array",
1910
+ items: {
1911
+ type: "string"
1912
+ }
1913
+ },
1914
+ hover: {
1915
+ name: "hover",
1916
+ type: "string",
1917
+ display: {
1918
+ type: "settings-color-picker",
1919
+ format: "single"
1920
+ }
1921
+ }
1922
+ }
1923
+ },
1924
+ caption: {
1925
+ name: "Caption",
1926
+ icon: "text-icon",
1927
+ tooltip: "Caption",
1928
+ type: "object",
1929
+ properties: {
1930
+ isActive: {
1931
+ type: "boolean",
1932
+ display: {
1933
+ type: "setting-toggle"
1934
+ }
1935
+ },
1936
+ alignment: {
1937
+ name: "Alignment",
1938
+ type: "string",
1939
+ display: {
1940
+ type: "align-grid"
1941
+ },
1942
+ enum: ["top-left", "top-center", "top-right", "middle-left", "middle-center", "middle-right", "bottom-left", "bottom-center", "bottom-right"]
1943
+ },
1944
+ offset: {
1945
+ type: "object",
1946
+ display: {
1947
+ type: "offset-controls"
1948
+ },
1949
+ properties: {
1950
+ x: {
1951
+ type: "number"
1952
+ },
1953
+ y: {
1954
+ type: "number"
1955
+ }
1956
+ }
1957
+ },
1958
+ hover: {
1959
+ name: "hover",
1960
+ type: "string",
1961
+ display: {
1962
+ type: "settings-color-picker",
1963
+ format: "single"
1964
+ }
1965
+ }
1966
+ }
1967
+ }
1968
+ },
1969
+ default: {
1970
+ triggers: {
1971
+ triggersList: {
1972
+ click: false,
1973
+ drag: true
1974
+ },
1975
+ autoPlay: null
1976
+ },
1977
+ controls: {
1978
+ isActive: true,
1979
+ arrowsImgUrl: null,
1980
+ offset: {
1981
+ x: 0,
1982
+ y: 0
1983
+ },
1984
+ scale: 100,
1985
+ color: "#000000",
1986
+ hover: "#cccccc"
1987
+ },
1988
+ transition: {
1989
+ type: "slide",
1990
+ duration: "500ms",
1991
+ backgroundColor: null
1992
+ },
1993
+ pagination: {
1994
+ isActive: true,
1995
+ scale: 50,
1996
+ position: "outside-1",
1997
+ offset: {
1998
+ x: 0,
1999
+ y: 0
2000
+ },
2001
+ colors: ["#cccccc", "#cccccc", "#000000"],
2002
+ hover: "#cccccc"
2003
+ },
2004
+ direction: "horiz",
2005
+ caption: {
2006
+ offset: {
2007
+ x: 0,
2008
+ y: 0
2009
+ },
2010
+ isActive: true,
2011
+ alignment: "middle-center",
2012
+ hover: "#cccccc"
2013
+ }
2014
+ },
2015
+ displayRules: [
2016
+ {
2017
+ if: {
2018
+ name: "direction",
2019
+ value: "vert"
2020
+ },
2021
+ then: {
2022
+ name: "properties.pagination.properties.position.display.direction",
2023
+ value: "vertical"
2024
+ }
2025
+ },
2026
+ {
2027
+ if: {
2028
+ name: "transition.type",
2029
+ value: "fade in"
2030
+ },
2031
+ then: {
2032
+ name: "properties.transition.properties.backgroundColor.display.visible",
2033
+ value: true
2034
+ }
2035
+ }
2036
+ ]
2037
+ },
2038
+ content: {
2039
+ layoutBased: false,
2040
+ type: "array",
2041
+ items: {
2042
+ type: "object",
2043
+ properties: {
2044
+ image: {
2045
+ type: "object",
2046
+ display: {
2047
+ type: "media-input"
2048
+ },
2049
+ properties: {
2050
+ url: {
2051
+ type: "string"
2052
+ },
2053
+ name: {
2054
+ type: "string"
2055
+ },
2056
+ objectFit: {
2057
+ type: "string",
2058
+ enum: ["cover", "contain"]
2059
+ }
2060
+ },
2061
+ required: ["url", "name"]
2062
+ },
2063
+ imageCaption: {
2064
+ display: {
2065
+ type: "rich-text",
2066
+ placeholder: "Add Caption..."
2067
+ }
2068
+ },
2069
+ link: {
2070
+ type: "object",
2071
+ display: {
2072
+ type: "text-input",
2073
+ placeholder: "Add Caption..."
2074
+ },
2075
+ properties: {
2076
+ text: {
2077
+ type: "string"
2078
+ }
2079
+ }
2080
+ }
2081
+ },
2082
+ required: ["image"]
2083
+ },
2084
+ default: [
2085
+ {
2086
+ image: {
2087
+ objectFit: "cover",
2088
+ url: "https://cdn.cntrl.site/projects/01JJKT02AWY2FGN2QJ7A173RNZ/articles-assets/01K7ERMHNP08T27H1649S67NZV.png",
2089
+ name: "Slider-1.png"
2090
+ },
2091
+ imageCaption: [
2092
+ {
2093
+ type: "paragraph",
2094
+ children: [{ text: "" }]
2095
+ }
2096
+ ]
2097
+ },
2098
+ {
2099
+ image: {
2100
+ objectFit: "cover",
2101
+ url: "https://cdn.cntrl.site/projects/01JJKT02AWY2FGN2QJ7A173RNZ/articles-assets/01K7ERMTZA3RYMXKF0M095D6JD.png",
2102
+ name: "Slider-2.png"
2103
+ },
2104
+ imageCaption: [
2105
+ {
2106
+ type: "paragraph",
2107
+ children: [{ text: "" }]
2108
+ }
2109
+ ]
2110
+ },
2111
+ {
2112
+ image: {
2113
+ objectFit: "cover",
2114
+ url: "https://cdn.cntrl.site/projects/01JJKT02AWY2FGN2QJ7A173RNZ/articles-assets/01K7ERMVSCMPVJBG2WF5KJZYHZ.png",
2115
+ name: "Slider-3.png"
2116
+ },
2117
+ imageCaption: [
2118
+ {
2119
+ type: "paragraph",
2120
+ children: [{ text: "" }]
2121
+ }
2122
+ ]
2123
+ }
2124
+ ]
2125
+ },
2126
+ styles: {
2127
+ layoutBased: true,
2128
+ type: "object",
2129
+ properties: {
2130
+ caption: {
2131
+ dataName: "caption",
2132
+ type: "object",
2133
+ properties: {
2134
+ fontSettings: {
2135
+ type: "object",
2136
+ display: {
2137
+ type: "font-settings"
2138
+ },
2139
+ properties: {
2140
+ fontFamily: {
2141
+ type: "string"
2142
+ },
2143
+ fontWeight: {
2144
+ type: "number"
2145
+ },
2146
+ fontStyle: {
2147
+ type: "string"
2148
+ }
2149
+ }
2150
+ },
2151
+ widthSettings: {
2152
+ display: {
2153
+ type: "text-width-control"
2154
+ },
2155
+ type: "object",
2156
+ properties: {
2157
+ width: {
2158
+ type: "number"
2159
+ },
2160
+ sizing: {
2161
+ type: "string",
2162
+ enum: ["auto", "manual"]
2163
+ }
2164
+ }
2165
+ },
2166
+ fontSizeLineHeight: {
2167
+ type: "object",
2168
+ display: {
2169
+ type: "font-size-line-height"
2170
+ },
2171
+ properties: {
2172
+ fontSize: {
2173
+ type: "number"
2174
+ },
2175
+ lineHeight: {
2176
+ type: "number"
2177
+ }
2178
+ }
2179
+ },
2180
+ letterSpacing: {
2181
+ display: {
2182
+ type: "letter-spacing-input"
2183
+ },
2184
+ type: "number"
2185
+ },
2186
+ wordSpacing: {
2187
+ display: {
2188
+ type: "word-spacing-input"
2189
+ },
2190
+ type: "number"
2191
+ },
2192
+ textAlign: {
2193
+ display: {
2194
+ type: "text-align-control"
2195
+ },
2196
+ type: "string",
2197
+ enum: ["left", "center", "right", "justify"]
2198
+ },
2199
+ textAppearance: {
2200
+ display: {
2201
+ type: "text-appearance"
2202
+ },
2203
+ properties: {
2204
+ textTransform: {
2205
+ type: "string",
2206
+ enum: ["none", "uppercase", "lowercase", "capitalize"]
2207
+ },
2208
+ textDecoration: {
2209
+ type: "string",
2210
+ enum: ["none", "underline"]
2211
+ },
2212
+ fontVariant: {
2213
+ type: "string",
2214
+ enum: ["normal", "small-caps"]
2215
+ }
2216
+ }
2217
+ },
2218
+ color: {
2219
+ display: {
2220
+ type: "style-panel-color-picker"
2221
+ },
2222
+ type: "string"
2223
+ }
2224
+ }
2225
+ }
2226
+ },
2227
+ default: {
2228
+ caption: {
2229
+ widthSettings: {
2230
+ width: 0.13,
2231
+ sizing: "auto"
2232
+ },
2233
+ fontSettings: {
2234
+ fontFamily: "Arial",
2235
+ fontWeight: 400,
2236
+ fontStyle: "normal"
2237
+ },
2238
+ fontSizeLineHeight: {
2239
+ fontSize: 0.02,
2240
+ lineHeight: 0.02
2241
+ },
2242
+ letterSpacing: 0,
2243
+ wordSpacing: 0,
2244
+ textAlign: "left",
2245
+ textAppearance: {
2246
+ textTransform: "none",
2247
+ textDecoration: "none",
2248
+ fontVariant: "normal"
2249
+ },
2250
+ color: "#000000"
2251
+ }
2252
+ }
2253
+ }
2254
+ },
2255
+ required: ["settings", "content", "styles"]
2256
+ }
2257
+ };
2258
+ const imageRevealSlider = "ImageRevealSlider-module__imageRevealSlider___UE5Ob";
2259
+ const image = "ImageRevealSlider-module__image___Qjt-e";
2260
+ const link = "ImageRevealSlider-module__link___N-iLG";
2261
+ const styles = {
2262
+ imageRevealSlider,
2263
+ image,
2264
+ link
2265
+ };
2266
+ function isMouseOverImage(mouseX, mouseY, placedImages) {
2267
+ for (const img2 of placedImages) {
2268
+ const imgEl = new Image();
2269
+ imgEl.src = img2.url;
2270
+ const imgWidth = img2.width ? Number.parseFloat(img2.width) : imgEl.naturalWidth;
2271
+ const imgHeight = imgEl.naturalHeight / imgEl.naturalWidth * imgWidth;
2272
+ const halfW = imgWidth / 2;
2273
+ const halfH = imgHeight / 2;
2274
+ if (mouseX >= img2.x - halfW && mouseX <= img2.x + halfW && mouseY >= img2.y - halfH && mouseY <= img2.y + halfH) {
2275
+ return true;
2276
+ }
2277
+ }
2278
+ return false;
2279
+ }
2280
+ function getImageSize(url) {
2281
+ return new Promise((resolve) => {
2282
+ const img2 = new Image();
2283
+ img2.src = url;
2284
+ img2.onload = () => {
2285
+ resolve({ width: img2.naturalWidth, height: img2.naturalHeight });
2286
+ };
2287
+ });
2288
+ }
2289
+ async function calculateImageWidthHeight(imgUrl, sizeType, customWidth, randomRange) {
2290
+ let width;
2291
+ let height;
2292
+ if (sizeType === "custom") {
2293
+ width = customWidth;
2294
+ const size = await getImageSize(imgUrl);
2295
+ height = size.height / size.width * width;
2296
+ } else if (sizeType === "random") {
2297
+ width = Math.random() * (randomRange.max - randomRange.min) + randomRange.min;
2298
+ const size = await getImageSize(imgUrl);
2299
+ height = size.height / size.width * width;
2300
+ } else {
2301
+ const size = await getImageSize(imgUrl);
2302
+ width = size.width;
2303
+ height = size.height;
2304
+ }
2305
+ return { width, height, finalWidth: `${width}px` };
2306
+ }
2307
+ function ImageRevealSlider({ settings, content, isEditor }) {
2308
+ const divRef = useRef(null);
2309
+ const [placedImages, setPlacedImages] = useState([]);
2310
+ const [counter, setCounter] = useState(0);
2311
+ const imageIdCounter = useRef(0);
2312
+ const defaultImageCount = 1;
2313
+ const { sizeType, imageWidth: customWidth, randomRangeImageWidth: randomRange } = settings.imageSize;
2314
+ const { revealPosition, visible, target } = settings.position;
2315
+ const { cursorType, defaultCursor, hoverCursor } = settings.cursor;
2316
+ const createNewImage = async (imgData, containerWidth, containerHeight, position = {}) => {
2317
+ const { width, height, finalWidth } = await calculateImageWidthHeight(
2318
+ imgData.image.url,
2319
+ sizeType,
2320
+ customWidth,
2321
+ randomRange
2322
+ );
2323
+ let x = 0, y = 0;
2324
+ if (revealPosition === "same") {
2325
+ x = containerWidth / 2;
2326
+ y = containerHeight / 2;
2327
+ } else {
2328
+ x = position.x ?? Math.random() * containerWidth;
2329
+ y = position.y ?? Math.random() * containerHeight;
2330
+ }
2331
+ const adjustedX = Math.min(Math.max(x, width / 2), containerWidth - width / 2);
2332
+ const adjustedY = Math.min(Math.max(y, height / 2), containerHeight - height / 2);
2333
+ return {
2334
+ id: imageIdCounter.current++,
2335
+ url: imgData.image.url,
2336
+ link: imgData.link,
2337
+ name: imgData.image.name,
2338
+ x: adjustedX,
2339
+ y: adjustedY,
2340
+ width: finalWidth
2341
+ };
2342
+ };
2343
+ const defaultContentUrls = useMemo(() => {
2344
+ const defaultContentLength = Math.min(content.length, defaultImageCount);
2345
+ return content.filter((_, i) => i < defaultContentLength).map((c) => c.image.url).join("-");
2346
+ }, [content]);
2347
+ useEffect(() => {
2348
+ if (!divRef.current || content.length === 0) return;
2349
+ const rect = divRef.current.getBoundingClientRect();
2350
+ const containerWidth = rect.width;
2351
+ const containerHeight = rect.height;
2352
+ const defaultPlaced = [];
2353
+ const placeImages = async () => {
2354
+ for (let i = 0; i < defaultImageCount && i < content.length; i++) {
2355
+ const imgData = content[i];
2356
+ const newImg = await createNewImage(imgData, containerWidth, containerHeight);
2357
+ defaultPlaced.push(newImg);
2358
+ }
2359
+ setPlacedImages(defaultPlaced);
2360
+ setCounter(defaultImageCount % content.length);
2361
+ };
2362
+ placeImages();
2363
+ }, [defaultContentUrls, sizeType, customWidth, randomRange, revealPosition]);
2364
+ useEffect(() => {
2365
+ if (visible === "last One") {
2366
+ setPlacedImages((prev) => prev.length > 0 ? [prev[prev.length - 1]] : []);
2367
+ }
2368
+ }, [visible]);
2369
+ const handleClick = async (e) => {
2370
+ if (!divRef.current) return;
2371
+ const rect = divRef.current.getBoundingClientRect();
2372
+ const clickX = e.clientX - rect.left;
2373
+ const clickY = e.clientY - rect.top;
2374
+ if (target === "image" && !isMouseOverImage(clickX, clickY, placedImages)) return;
2375
+ let x = 0, y = 0;
2376
+ if (revealPosition === "on Click") {
2377
+ x = clickX;
2378
+ y = clickY;
2379
+ } else if (revealPosition === "same") {
2380
+ x = rect.width / 2;
2381
+ y = rect.height / 2;
2382
+ } else {
2383
+ x = Math.random() * rect.width;
2384
+ y = Math.random() * rect.height;
2385
+ }
2386
+ const imgData = content[counter];
2387
+ const newImage = await createNewImage(imgData, rect.width, rect.height, { x, y });
2388
+ setPlacedImages((prev) => visible === "all" ? [...prev, newImage] : [newImage]);
2389
+ setCounter((prev) => prev >= content.length - 1 ? 0 : prev + 1);
2390
+ };
2391
+ return /* @__PURE__ */ jsx(
2392
+ "div",
2393
+ {
2394
+ ref: divRef,
2395
+ onClick: handleClick,
2396
+ className: styles.imageRevealSlider,
2397
+ style: { cursor: cursorType !== "system" && defaultCursor ? `url(${target === "area" ? hoverCursor : defaultCursor}), auto` : "default" },
2398
+ children: placedImages.map((img2) => /* @__PURE__ */ jsx(
2399
+ "div",
2400
+ {
2401
+ className: styles.wrapper,
2402
+ style: {
2403
+ top: `${img2.y}px`,
2404
+ left: `${img2.x}px`,
2405
+ position: "absolute",
2406
+ transform: "translate(-50%, -50%)",
2407
+ width: img2.width ?? "auto",
2408
+ height: "auto",
2409
+ cursor: cursorType !== "system" && hoverCursor ? `url(${hoverCursor}), auto` : "default"
2410
+ },
2411
+ children: target === "area" && img2.link ? /* @__PURE__ */ jsx("a", { href: img2.link, target: "_blank", className: styles.link, children: /* @__PURE__ */ jsx(
2412
+ "img",
2413
+ {
2414
+ src: img2.url,
2415
+ alt: img2.name,
2416
+ className: styles.image
2417
+ },
2418
+ img2.id
2419
+ ) }) : /* @__PURE__ */ jsx(
2420
+ "img",
2421
+ {
2422
+ src: img2.url,
2423
+ alt: img2.name,
2424
+ className: styles.image
2425
+ },
2426
+ img2.id
2427
+ )
2428
+ },
2429
+ img2.id
2430
+ ))
2431
+ }
2432
+ );
2433
+ }
2434
+ const ControlImageRevealSliderComponent = {
2435
+ element: ImageRevealSlider,
2436
+ id: "control-image-reveal",
2437
+ name: "Click Gallery",
2438
+ preview: {
2439
+ type: "video",
2440
+ url: "https://cdn.cntrl.site/projects/01JJKT02AWY2FGN2QJ7A173RNZ/articles-assets/01K7EQ3WSW43JG5YMC8B2HTPKT.mp4"
2441
+ },
2442
+ defaultSize: {
2443
+ width: 700,
2444
+ height: 400
2445
+ },
2446
+ schema: {
2447
+ type: "object",
2448
+ properties: {
2449
+ settings: {
2450
+ layoutBased: true,
2451
+ type: "object",
2452
+ properties: {
2453
+ imageSize: {
2454
+ name: "IMG SIZE",
2455
+ icon: "size",
2456
+ tooltip: "IMG SIZE",
2457
+ type: "object",
2458
+ properties: {
2459
+ sizeType: {
2460
+ name: "sizeType",
2461
+ type: "string",
2462
+ display: {
2463
+ type: "ratio-group"
2464
+ },
2465
+ enum: ["as Is", "custom", "random"]
2466
+ },
2467
+ imageWidth: {
2468
+ type: "number",
2469
+ label: "W",
2470
+ display: {
2471
+ type: "numeric-input",
2472
+ visible: false
2473
+ }
2474
+ },
2475
+ randomRangeImageWidth: {
2476
+ type: "object",
2477
+ display: {
2478
+ type: "random-range-controls",
2479
+ visible: false
2480
+ },
2481
+ properties: {
2482
+ min: {
2483
+ type: "number"
2484
+ },
2485
+ max: {
2486
+ type: "number"
2487
+ }
2488
+ }
2489
+ }
2490
+ }
2491
+ },
2492
+ cursor: {
2493
+ name: "cursor",
2494
+ icon: "cursor",
2495
+ tooltip: "cursor",
2496
+ type: "object",
2497
+ properties: {
2498
+ cursorType: {
2499
+ name: "cursorType",
2500
+ type: "string",
2501
+ display: {
2502
+ type: "ratio-group"
2503
+ },
2504
+ enum: ["system", "custom"]
2505
+ },
2506
+ defaultCursor: {
2507
+ type: ["string", "null"],
2508
+ display: {
2509
+ type: "settings-image-input",
2510
+ title: "Default",
2511
+ visible: false
2512
+ }
2513
+ },
2514
+ hoverCursor: {
2515
+ type: ["string", "null"],
2516
+ display: {
2517
+ type: "settings-image-input",
2518
+ title: "Hover",
2519
+ visible: false
2520
+ }
2521
+ }
2522
+ }
2523
+ },
2524
+ position: {
2525
+ name: "position",
2526
+ icon: "transition",
2527
+ tooltip: "Position",
2528
+ type: "object",
2529
+ properties: {
2530
+ revealPosition: {
2531
+ type: "string",
2532
+ display: {
2533
+ type: "ratio-group"
2534
+ },
2535
+ enum: ["random", "same", "on Click"]
2536
+ },
2537
+ visible: {
2538
+ type: "string",
2539
+ display: {
2540
+ type: "ratio-group"
2541
+ },
2542
+ enum: ["all", "last One"]
2543
+ },
2544
+ target: {
2545
+ type: "string",
2546
+ display: {
2547
+ type: "ratio-group"
2548
+ },
2549
+ enum: ["area", "image"]
2550
+ }
2551
+ }
2552
+ }
2553
+ },
2554
+ default: {
2555
+ imageSize: {
2556
+ sizeType: "custom",
2557
+ imageWidth: 500,
2558
+ randomRangeImageWidth: {
2559
+ min: 100,
2560
+ max: 1e3
2561
+ }
2562
+ },
2563
+ cursor: {
2564
+ cursorType: "system",
2565
+ defaultCursor: null,
2566
+ hoverCursor: null
2567
+ },
2568
+ position: {
2569
+ revealPosition: "random",
2570
+ visible: "all",
2571
+ target: "area"
2572
+ }
2573
+ },
2574
+ displayRules: [
2575
+ {
2576
+ if: {
2577
+ name: "imageSize.sizeType",
2578
+ value: "custom"
2579
+ },
2580
+ then: {
2581
+ name: "properties.imageSize.properties.imageWidth.display.visible",
2582
+ value: true
2583
+ }
2584
+ },
2585
+ {
2586
+ if: {
2587
+ name: "imageSize.sizeType",
2588
+ value: "random"
2589
+ },
2590
+ then: {
2591
+ name: "properties.imageSize.properties.randomRangeImageWidth.display.visible",
2592
+ value: true
2593
+ }
2594
+ },
2595
+ {
2596
+ if: [
2597
+ { name: "position.target", value: "image" },
2598
+ { name: "cursor.cursorType", value: "custom" }
2599
+ ],
2600
+ then: {
2601
+ name: "properties.cursor.properties.defaultCursor.display.visible",
2602
+ value: true
2603
+ }
2604
+ },
2605
+ {
2606
+ if: {
2607
+ name: "cursor.cursorType",
2608
+ value: "custom"
2609
+ },
2610
+ then: {
2611
+ name: "properties.cursor.properties.hoverCursor.display.visible",
2612
+ value: true
2613
+ }
2614
+ }
2615
+ ]
2616
+ },
2617
+ content: {
2618
+ layoutBased: false,
2619
+ type: "array",
2620
+ items: {
2621
+ type: "object",
2622
+ properties: {
2623
+ image: {
2624
+ type: "object",
2625
+ display: {
2626
+ type: "media-input",
2627
+ isObjectFitEditable: false
2628
+ },
2629
+ properties: {
2630
+ url: {
2631
+ type: "string"
2632
+ },
2633
+ name: {
2634
+ type: "string"
2635
+ },
2636
+ objectFit: {
2637
+ type: "string",
2638
+ enum: ["cover", "contain"]
2639
+ }
2640
+ },
2641
+ required: ["url", "name"]
2642
+ },
2643
+ link: {
2644
+ type: "string",
2645
+ display: {
2646
+ type: "text-input",
2647
+ placeholder: "Enter link..."
2648
+ }
2649
+ }
2650
+ },
2651
+ required: ["image"]
2652
+ },
2653
+ default: [
2654
+ {
2655
+ image: {
2656
+ objectFit: "cover",
2657
+ url: "https://cdn.cntrl.site/projects/01JJKT02AWY2FGN2QJ7A173RNZ/articles-assets/01K7ERQK9211QXBE9W284ZNKB8.png",
2658
+ name: "Slider-1.png"
2659
+ },
2660
+ link: ""
2661
+ },
2662
+ {
2663
+ image: {
2664
+ objectFit: "cover",
2665
+ url: "https://cdn.cntrl.site/projects/01JJKT02AWY2FGN2QJ7A173RNZ/articles-assets/01K7ERQMFT72JD18WKP0Q2DVAT.png",
2666
+ name: "Slider-2.png"
2667
+ },
2668
+ link: ""
2669
+ },
2670
+ {
2671
+ image: {
2672
+ objectFit: "cover",
2673
+ url: "https://cdn.cntrl.site/projects/01JJKT02AWY2FGN2QJ7A173RNZ/articles-assets/01K7ERQNEVRXPSRX5K1YTMJQY9.png",
2674
+ name: "Slider-3.png"
2675
+ },
2676
+ link: ""
2677
+ },
2678
+ {
2679
+ image: {
2680
+ objectFit: "cover",
2681
+ url: "https://cdn.cntrl.site/projects/01JJKT02AWY2FGN2QJ7A173RNZ/articles-assets/01K7ERQP84JKRDT7WNWDQZR4Y9.png",
2682
+ name: "Slider-4.png"
2683
+ },
2684
+ link: ""
2685
+ }
2686
+ ]
2687
+ }
2688
+ }
2689
+ }
2690
+ };
2691
+ const components = [
2692
+ ControlSliderComponent,
2693
+ ControlImageRevealSliderComponent
2694
+ ];
2695
+ export {
2696
+ AnchorSide,
2697
+ AreaAnchor,
2698
+ ArticleItemType,
2699
+ Client as CntrlClient,
2700
+ DimensionMode,
2701
+ FontFaceGenerator,
2702
+ KeyframeType,
2703
+ PositionType,
2704
+ ScrollPlaybackVideoManager,
2705
+ SectionHeightMode,
2706
+ TextAlign,
2707
+ TextDecoration,
2708
+ TextTransform,
2709
+ VerticalAlign,
2710
+ components,
2711
+ getLayoutMediaQuery,
2712
+ getLayoutStyles
2713
+ };