@snowcone-app/canvas 0.15.0 → 0.17.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 (73) hide show
  1. package/dist/{CanvasStateV1-BQD8fCBU.js → CanvasStateV1-C6i6vU6p.js} +63 -63
  2. package/dist/{CanvasStateV1-BQD8fCBU.js.map → CanvasStateV1-C6i6vU6p.js.map} +1 -1
  3. package/dist/EditorCanvasImpl-DkgE5-C2.js +68 -0
  4. package/dist/EditorCanvasImpl-DkgE5-C2.js.map +1 -0
  5. package/dist/EditorContext-CyanYzo2.js +1131 -0
  6. package/dist/EditorContext-CyanYzo2.js.map +1 -0
  7. package/dist/{ImportManager-eotl7r5d.js → ElementFactory-C05JJkRp.js} +1510 -5121
  8. package/dist/ElementFactory-C05JJkRp.js.map +1 -0
  9. package/dist/{HybridHistoryManager-NL3zyEl4.js → HybridHistoryManager-Bht98XRv.js} +98 -98
  10. package/dist/{HybridHistoryManager-NL3zyEl4.js.map → HybridHistoryManager-Bht98XRv.js.map} +1 -1
  11. package/dist/ImportManager-kRYfIX-D.js +3617 -0
  12. package/dist/ImportManager-kRYfIX-D.js.map +1 -0
  13. package/dist/SnowconeCanvas-C3eZ9PP8.js +1047 -0
  14. package/dist/SnowconeCanvas-C3eZ9PP8.js.map +1 -0
  15. package/dist/ThemeContext-Rjz25x9X.js +75 -0
  16. package/dist/ThemeContext-Rjz25x9X.js.map +1 -0
  17. package/dist/UnifiedFontService-BAtqqkU4.js +1478 -0
  18. package/dist/UnifiedFontService-BAtqqkU4.js.map +1 -0
  19. package/dist/advanced.mjs +210 -207
  20. package/dist/advanced.mjs.map +1 -1
  21. package/dist/api/embed.d.ts +8 -4
  22. package/dist/api/testing.d.ts +1 -0
  23. package/dist/components/editor/EditorBuy.d.ts +49 -0
  24. package/dist/components/editor/EditorCanvas.d.ts +30 -0
  25. package/dist/components/editor/EditorCanvasImpl.d.ts +33 -0
  26. package/dist/components/editor/EditorPreview.d.ts +39 -0
  27. package/dist/components/editor/EditorRoot.d.ts +86 -0
  28. package/dist/components/editor/EditorTextField.d.ts +22 -0
  29. package/dist/components/editor/RootInternals.d.ts +77 -0
  30. package/dist/components/editor/designStateStore.d.ts +45 -0
  31. package/dist/components/editor/index.d.ts +23 -0
  32. package/dist/components/embed-realtime/RealtimeCanvas.d.ts +1 -1
  33. package/dist/components/embed-realtime/RealtimeEmbed.d.ts +5 -78
  34. package/dist/components/embed-realtime/RealtimeMockup.d.ts +5 -34
  35. package/dist/components/embed-realtime/context.d.ts +12 -2
  36. package/dist/components/embed-realtime/validateEmbed.d.ts +17 -3
  37. package/dist/contexts/EditorContext.d.ts +1 -0
  38. package/dist/design/design-builder.d.ts +81 -6
  39. package/dist/editorError-DMENTZ-3.js +19 -0
  40. package/dist/editorError-DMENTZ-3.js.map +1 -0
  41. package/dist/editorErrors-DbIEtCTt.js +29 -0
  42. package/dist/editorErrors-DbIEtCTt.js.map +1 -0
  43. package/dist/embed-Bdj4PKUA.js +737 -0
  44. package/dist/embed-Bdj4PKUA.js.map +1 -0
  45. package/dist/embed.mjs +38 -230
  46. package/dist/embed.mjs.map +1 -1
  47. package/dist/errors/editorError.d.ts +57 -0
  48. package/dist/iconify-D6eVIEy4.js +1089 -0
  49. package/dist/iconify-D6eVIEy4.js.map +1 -0
  50. package/dist/index.mjs +48 -46
  51. package/dist/index.mjs.map +1 -1
  52. package/dist/internals.mjs +105 -104
  53. package/dist/internals.mjs.map +1 -1
  54. package/dist/rendering/PieceGuideRenderer.d.ts +2 -16
  55. package/dist/template-fields-GOM4MNfq.js +643 -0
  56. package/dist/template-fields-GOM4MNfq.js.map +1 -0
  57. package/dist/testing/editorErrors.d.ts +30 -0
  58. package/dist/testing.mjs +28 -23
  59. package/dist/testing.mjs.map +1 -1
  60. package/dist/{usePieceGuideBundle-Cyl695jv.js → usePieceGuideBundle-CGERAQJl.js} +2 -2
  61. package/dist/{usePieceGuideBundle-Cyl695jv.js.map → usePieceGuideBundle-CGERAQJl.js.map} +1 -1
  62. package/dist/utils/inkLuminance.d.ts +38 -0
  63. package/dist/validation-DEd6EOCP.js +19947 -0
  64. package/dist/validation-DEd6EOCP.js.map +1 -0
  65. package/dist/workers/export-worker.bundle.string.d.ts +1 -1
  66. package/package.json +9 -4
  67. package/dist/ImportManager-eotl7r5d.js.map +0 -1
  68. package/dist/ThemeContext-Cl1JPVLZ.js +0 -1158
  69. package/dist/ThemeContext-Cl1JPVLZ.js.map +0 -1
  70. package/dist/template-fields-coO73lV3.js +0 -1632
  71. package/dist/template-fields-coO73lV3.js.map +0 -1
  72. package/dist/validation-BahKiJWj.js +0 -22973
  73. package/dist/validation-BahKiJWj.js.map +0 -1
@@ -1,1632 +0,0 @@
1
- import { c as nt, y as K, z as Oe, I as Ht, T as Pt, C as Ye } from "./HybridHistoryManager-NL3zyEl4.js";
2
- import { jsxs as Z, jsx as w, Fragment as ue } from "react/jsx-runtime";
3
- import { useCallback as P, useMemo as ot, useRef as M, useEffect as C, Component as Xe, useState as _, forwardRef as fe, useImperativeHandle as Ve } from "react";
4
- import { u as Wt, T as te, E as je, c as dt, b as At } from "./ThemeContext-Cl1JPVLZ.js";
5
- import { aq as ee, ar as re, ag as Ke, ah as ne, ad as Ge, W as qe, J as Je, K as Qe, Q as Ze, O as _e, p as tr, z as er, ab as rr, Y as oe, F as nr, q as or, G as ar, r as sr, v as ir, u as cr, g as lr, a2 as dr, V as ur, a as fr, w as hr, as as mr } from "./validation-BahKiJWj.js";
6
- import { C as Tt, E as gr } from "./ImportManager-eotl7r5d.js";
7
- import { a as pr, o as ct, b as $, n as br, l as Y, u as ae, c as yr } from "./CanvasStateV1-BQD8fCBU.js";
8
- const se = nt("useCommands");
9
- function xr() {
10
- const e = Wt(), {
11
- undo: t,
12
- redo: r,
13
- canUndo: o,
14
- canRedo: n,
15
- executeElementUpdate: a,
16
- executeAddElement: s,
17
- executeRemoveElement: i,
18
- executeReorderElement: c,
19
- executeCommandBatch: d,
20
- executeCreateArtboard: x,
21
- executeDeleteArtboard: I,
22
- executeUpdateArtboard: R
23
- } = e, k = P(() => {
24
- se.warn("[useCommands] clearHistory is not yet implemented in EditorContext");
25
- }, []), T = P((p) => {
26
- se.warn("[useCommands] clearArtboardHistory is not yet implemented in EditorContext");
27
- }, []);
28
- return {
29
- // Undo/Redo
30
- undo: t,
31
- redo: r,
32
- canUndo: o,
33
- canRedo: n,
34
- // History management
35
- clearHistory: k,
36
- clearArtboardHistory: T,
37
- // Command execution
38
- executeElementUpdate: a,
39
- executeAddElement: s,
40
- executeRemoveElement: i,
41
- executeReorderElement: c,
42
- executeCreateArtboard: x,
43
- executeDeleteArtboard: I,
44
- executeUpdateArtboard: R,
45
- // Batch execution
46
- executeCommandBatch: d
47
- };
48
- }
49
- const vr = () => {
50
- const { undo: e, redo: t, canUndo: r, canRedo: o } = xr();
51
- return /* @__PURE__ */ Z("div", { className: "sc-undo-redo", style: { display: "inline-flex", gap: 4 }, children: [
52
- /* @__PURE__ */ w(
53
- ee,
54
- {
55
- icon: re.undo,
56
- onClick: e,
57
- disabled: !r,
58
- tooltip: "Undo",
59
- "aria-label": "Undo"
60
- }
61
- ),
62
- /* @__PURE__ */ w(
63
- ee,
64
- {
65
- icon: re.redo,
66
- onClick: t,
67
- disabled: !o,
68
- tooltip: "Redo",
69
- "aria-label": "Redo"
70
- }
71
- )
72
- ] });
73
- }, he = nt("KitLayout"), lt = "canvas", Dt = 320;
74
- let ie = !1;
75
- function wr() {
76
- ie || (ie = !0, Ke({
77
- LayersPanel: qe,
78
- EffectsPanel: Je,
79
- ExportPanel: Qe,
80
- ImagePanel: Ze,
81
- GlyphPanel: _e,
82
- ArtboardTabs: tr,
83
- ContextualToolbars: er,
84
- ZoomControls: rr,
85
- MenuButton: oe,
86
- CropPanel: nr
87
- }), ne("add-element-menu", {
88
- component: oe,
89
- label: "Add Element",
90
- icon: "gravity-ui:plus",
91
- position: "topbar"
92
- }), ne("undo-redo-controls", {
93
- component: vr,
94
- label: "Undo / Redo",
95
- icon: "lucide:undo-2",
96
- position: "topbar"
97
- }));
98
- }
99
- function wt({ ids: e }) {
100
- return !e || e.length === 0 ? null : /* @__PURE__ */ w(ue, { children: e.map((t) => {
101
- var n;
102
- if (t === lt) return null;
103
- const r = Ge(t);
104
- if (!r)
105
- return typeof K < "u" && ((n = K.env) == null ? void 0 : n.NODE_ENV) === "development" && he.warn(
106
- `Kit layout references unknown section "${t}" — skipping. Register it with registerSection("${t}", { ... }).`
107
- ), null;
108
- const o = r.component;
109
- return /* @__PURE__ */ w(o, {}, t);
110
- }) });
111
- }
112
- function Er({ kit: e, canvas: t }) {
113
- var I, R, k, T;
114
- wr();
115
- const r = e.layout.slots, o = !!((I = r.topbar) != null && I.some((p) => p !== lt)), n = !!((R = r.left) != null && R.some((p) => p !== lt)), a = !!((k = r.right) != null && k.some((p) => p !== lt)), s = !!((T = r.bottombar) != null && T.some((p) => p !== lt)), i = ot(
116
- () => !o && !n && !a && !s,
117
- [o, n, a, s]
118
- ), c = M(null), d = o || n || a || s, x = M(!1);
119
- return C(() => {
120
- var b;
121
- if (typeof K > "u" || ((b = K.env) == null ? void 0 : b.NODE_ENV) !== "development" || !d) return;
122
- const p = c.current;
123
- if (!p || typeof ResizeObserver > "u") return;
124
- const N = (E) => {
125
- E > 0 && E < Dt && !x.current ? (x.current = !0, he.warn(
126
- `Kit "${e.name}" declares chrome (toolbar / panels) but its container is only ${Math.round(E)}px wide — below the ~${Dt}px needed to render it, so the toolbar / panels are suppressed and the editor looks like a bare canvas. Give the editor more container width, or pass kit="embed-only" if a chrome-less canvas is intended.`
127
- )) : E >= Dt && (x.current = !1);
128
- };
129
- N(p.getBoundingClientRect().width);
130
- const S = new ResizeObserver((E) => {
131
- for (const v of E) N(v.contentRect.width);
132
- });
133
- return S.observe(p), () => S.disconnect();
134
- }, [d, e.name]), i ? /* @__PURE__ */ w(ue, { children: t }) : /* @__PURE__ */ Z("div", { ref: c, className: "sc-kit-layout", style: { display: "flex", flexDirection: "column", height: "100%", minHeight: 0 }, children: [
135
- o && /* @__PURE__ */ w(
136
- "div",
137
- {
138
- className: "sc-kit-topbar sc-toolbar",
139
- style: { display: "flex", alignItems: "center", gap: 8, flexWrap: "wrap", flexShrink: 0 },
140
- children: /* @__PURE__ */ w(wt, { ids: r.topbar })
141
- }
142
- ),
143
- /* @__PURE__ */ Z("div", { className: "sc-kit-body", style: { display: "flex", flex: 1, minHeight: 0 }, children: [
144
- n && /* @__PURE__ */ w("div", { className: "sc-kit-left", style: { flexShrink: 0, overflow: "auto" }, children: /* @__PURE__ */ w(wt, { ids: r.left }) }),
145
- /* @__PURE__ */ w("div", { className: "sc-kit-canvas", style: { flex: 1, minWidth: 0, position: "relative" }, children: t }),
146
- a && /* @__PURE__ */ w("div", { className: "sc-kit-right", style: { flexShrink: 0, overflow: "auto" }, children: /* @__PURE__ */ w(wt, { ids: r.right }) })
147
- ] }),
148
- s && /* @__PURE__ */ w(
149
- "div",
150
- {
151
- className: "sc-kit-bottombar sc-toolbar",
152
- style: { display: "flex", alignItems: "center", gap: 8, flexShrink: 0 },
153
- children: /* @__PURE__ */ w(wt, { ids: r.bottombar })
154
- }
155
- )
156
- ] });
157
- }
158
- const Ar = nt("ErrorBoundary");
159
- class kr extends Xe {
160
- constructor(t) {
161
- super(t), this.resetError = () => {
162
- this.setState({
163
- hasError: !1,
164
- error: null
165
- });
166
- }, this.state = {
167
- hasError: !1,
168
- error: null
169
- };
170
- }
171
- static getDerivedStateFromError(t) {
172
- return {
173
- hasError: !0,
174
- error: t
175
- };
176
- }
177
- componentDidCatch(t, r) {
178
- if (Ar.error("Caught error:", t, r), this.props.onError && this.props.onError(t, r), this.props.onCanvasError) {
179
- const o = {
180
- category: "unknown",
181
- message: t.message,
182
- originalError: t,
183
- recoverable: !1
184
- };
185
- this.props.onCanvasError(o);
186
- }
187
- }
188
- render() {
189
- return this.state.hasError && this.state.error ? this.props.renderError ? this.props.renderError(this.state.error, this.resetError) : this.props.fallback ? typeof this.props.fallback == "function" ? this.props.fallback(this.state.error, this.resetError) : this.props.fallback : /* @__PURE__ */ Z(
190
- "div",
191
- {
192
- style: {
193
- padding: "24px",
194
- border: "2px solid var(--danger)",
195
- borderRadius: "8px",
196
- backgroundColor: "color-mix(in oklch, var(--danger) 10%, var(--background))",
197
- color: "var(--danger)",
198
- fontFamily: "system-ui, sans-serif"
199
- },
200
- children: [
201
- /* @__PURE__ */ w("h2", { style: { margin: "0 0 16px 0", fontSize: "18px", fontWeight: 600 }, children: "Something went wrong" }),
202
- /* @__PURE__ */ w(
203
- "pre",
204
- {
205
- style: {
206
- margin: "0 0 16px 0",
207
- padding: "12px",
208
- backgroundColor: "color-mix(in oklch, var(--danger) 15%, var(--background))",
209
- borderRadius: "4px",
210
- fontSize: "14px",
211
- overflow: "auto",
212
- maxHeight: "200px"
213
- },
214
- children: this.state.error.message
215
- }
216
- ),
217
- /* @__PURE__ */ w(
218
- "button",
219
- {
220
- onClick: this.resetError,
221
- style: {
222
- padding: "8px 16px",
223
- backgroundColor: "var(--danger)",
224
- color: "var(--danger-foreground)",
225
- border: "none",
226
- borderRadius: "4px",
227
- fontSize: "14px",
228
- fontWeight: 500,
229
- cursor: "pointer"
230
- },
231
- children: "Try again"
232
- }
233
- )
234
- ]
235
- }
236
- ) : this.props.children;
237
- }
238
- }
239
- const Sr = nt("useAutoExport");
240
- function Rr(e) {
241
- const { config: t, historyManager: r, artboards: o, elements: n, onExport: a, onExportScheduled: s, isCanvasReady: i = !1 } = e, c = M(null), d = M(!1), x = M({
242
- totalExports: 0,
243
- skippedExports: 0,
244
- lastExportTime: null,
245
- avgExportInterval: 0
246
- }), [I, R] = _(x.current), k = M(a);
247
- k.current = a, C(() => {
248
- const b = new or({
249
- ...ar,
250
- ...t
251
- });
252
- return b.onExport(async () => {
253
- try {
254
- await k.current(), x.current = b.getStats();
255
- } catch (E) {
256
- Sr.error("[useAutoExport] Export failed:", E);
257
- }
258
- }), c.current = b, () => {
259
- b.destroy();
260
- };
261
- }, []), C(() => {
262
- i && d.current && c.current && (d.current = !1, c.current.forceExport());
263
- }, [i]), C(() => {
264
- c.current && t && c.current.updateConfig(t);
265
- }, [t == null ? void 0 : t.enabled, t == null ? void 0 : t.debounceMs, t == null ? void 0 : t.maxWaitMs]), C(() => {
266
- c.current && s && c.current.onExportScheduled(s);
267
- }, [s]), C(() => {
268
- if (!r || !c.current)
269
- return;
270
- const b = r.onCommandExecuted(() => {
271
- if (c.current) {
272
- if (!i) {
273
- d.current = !0;
274
- return;
275
- }
276
- c.current.scheduleExport();
277
- }
278
- });
279
- return () => {
280
- b();
281
- };
282
- }, [r, i]), C(() => {
283
- if (c.current) {
284
- if (!i) {
285
- d.current = !0;
286
- return;
287
- }
288
- c.current.scheduleExport();
289
- }
290
- }, [n, o, i]), C(() => Oe((E) => {
291
- if (!c.current || !i) return;
292
- n.some((W) => W.id === E) && c.current.scheduleExport();
293
- }), [n, i]);
294
- const T = P((b) => {
295
- c.current && c.current.updateConfig(b);
296
- }, []), p = P(async () => {
297
- c.current && (await c.current.forceExport(), x.current = c.current.getStats(), R(x.current));
298
- }, []), N = P(() => {
299
- c.current && (c.current.resetStats(), x.current = c.current.getStats(), R(x.current));
300
- }, []), S = P(() => {
301
- c.current && c.current.resetChangeDetection();
302
- }, []);
303
- return {
304
- stats: I,
305
- updateConfig: T,
306
- forceExport: p,
307
- resetStats: N,
308
- resetChangeDetection: S
309
- };
310
- }
311
- const me = nt("useContentReady");
312
- function Cr(e) {
313
- var r;
314
- const t = /* @__PURE__ */ new Set();
315
- for (const o of e)
316
- if ("fontFamily" in o && typeof o.fontFamily == "string" && o.fontFamily && t.add(o.fontFamily), "getRichText" in o && typeof o.getRichText == "function")
317
- try {
318
- const n = o.getRichText();
319
- if (n != null && n.spans)
320
- for (const a of n.spans)
321
- (r = a.style) != null && r.fontFamily && t.add(a.style.fontFamily);
322
- } catch {
323
- }
324
- return Array.from(t);
325
- }
326
- async function Ir(e) {
327
- if (e.length === 0 || typeof document > "u" || !document.fonts) return;
328
- const t = [];
329
- for (const r of e) {
330
- const o = `16px "${r}"`;
331
- t.push(document.fonts.load(o));
332
- }
333
- await Promise.all(t), document.fonts.ready && await Promise.race([
334
- document.fonts.ready,
335
- new Promise((r) => setTimeout(r, 250))
336
- ]), me.debug(`Awaited ${t.length} font(s)`);
337
- }
338
- function Fr() {
339
- return new Promise((e) => requestAnimationFrame(() => e()));
340
- }
341
- function Mr(e) {
342
- const { isCanvasReady: t, elements: r, hasInitialElements: o, initialElementsLoaded: n } = e, [a, s] = _(!1), i = M(!1);
343
- return C(() => {
344
- if (a || !t || o && !n || o && r.length === 0 || i.current) return;
345
- i.current = !0;
346
- let c = !1;
347
- return (async () => {
348
- try {
349
- const d = Cr(r);
350
- if (d.length > 0 && (await Ir(d), c) || (await Fr(), c)) return;
351
- s(!0);
352
- } catch (d) {
353
- me.error("Error during content readiness check:", d), c || s(!0);
354
- } finally {
355
- i.current = !1;
356
- }
357
- })(), () => {
358
- c = !0, i.current = !1;
359
- };
360
- }, [t, r, o, n, a]), a;
361
- }
362
- const Tr = {
363
- // Vertical alignments (map to top/center/bottom center)
364
- "far-top": "t",
365
- top: "t",
366
- center: "c",
367
- bottom: "b",
368
- "far-bottom": "b",
369
- // Horizontal alignments (map to left/center/right middle)
370
- "far-left": "l",
371
- left: "l",
372
- right: "r",
373
- "far-right": "r",
374
- // Direct 9-point values
375
- tl: "tl",
376
- t: "t",
377
- tr: "tr",
378
- l: "l",
379
- c: "c",
380
- r: "r",
381
- bl: "bl",
382
- b: "b",
383
- br: "br"
384
- };
385
- function Dr(e) {
386
- return e && Tr[e] || "c";
387
- }
388
- function Nr(e, t) {
389
- const r = t.scaleMode || "cover", o = (r === "contain" ? t.marginTop : 0) || 0, n = (r === "contain" ? t.marginRight : 0) || 0, a = (r === "contain" ? t.marginBottom : 0) || 0, s = (r === "contain" ? t.marginLeft : 0) || 0, i = t.width - s - n, c = t.height - o - a, d = i / e.width, x = c / e.height, I = r === "contain" ? Math.min(d, x) : Math.max(d, x), R = t.scale || 1, k = I * R, T = e.width * k, p = e.height * k, N = t.align || "c";
390
- let S = 0, b = 0;
391
- const E = T - i, v = p - c;
392
- switch (N) {
393
- // Top row
394
- case "tl":
395
- S = 0, b = 0;
396
- break;
397
- case "t":
398
- S = -E / 2, b = 0;
399
- break;
400
- case "tr":
401
- S = -E, b = 0;
402
- break;
403
- // Middle row
404
- case "l":
405
- S = 0, b = -v / 2;
406
- break;
407
- case "c":
408
- // Center (default)
409
- default:
410
- S = -E / 2, b = -v / 2;
411
- break;
412
- case "r":
413
- S = -E, b = -v / 2;
414
- break;
415
- // Bottom row
416
- case "bl":
417
- S = 0, b = -v;
418
- break;
419
- case "b":
420
- S = -E / 2, b = -v;
421
- break;
422
- case "br":
423
- S = -E, b = -v;
424
- break;
425
- }
426
- S += s, b += o;
427
- const W = t.offsetX || 0, B = t.offsetY || 0, X = E, ut = v;
428
- return S += W * X, b += B * ut, S = Math.round(S), b = Math.round(b), {
429
- // Final scale to apply to artwork
430
- scale: k,
431
- // Final artwork dimensions after scaling
432
- width: Math.round(T),
433
- height: Math.round(p),
434
- // Position to draw artwork (relative to artboard origin)
435
- x: S,
436
- y: b,
437
- // Debug info
438
- debug: {
439
- coverScale: I,
440
- userScale: R,
441
- overflow: { x: E, y: v },
442
- alignment: N,
443
- appliedOffset: { x: W * X, y: B * ut }
444
- }
445
- };
446
- }
447
- const Br = {
448
- timeout: 3e4,
449
- retries: 1,
450
- retryDelay: 1e3,
451
- validateUrl: !0
452
- };
453
- function $r(e) {
454
- try {
455
- const t = new URL(e);
456
- return ["http:", "https:", "data:", "blob:"].includes(t.protocol);
457
- } catch {
458
- return !1;
459
- }
460
- }
461
- async function Hr(e, t = {}) {
462
- const r = { ...Br, ...t };
463
- if (r.validateUrl && !$r(e))
464
- return {
465
- success: !1,
466
- error: new Error(`Invalid image URL: ${e}`)
467
- };
468
- let o;
469
- for (let n = 0; n <= r.retries; n++)
470
- try {
471
- return await Pr(e, r.timeout);
472
- } catch (a) {
473
- o = a instanceof Error ? a : new Error(String(a)), n < r.retries && await Ur(r.retryDelay);
474
- }
475
- return {
476
- success: !1,
477
- error: o || new Error("Failed to load image after retries")
478
- };
479
- }
480
- function Pr(e, t) {
481
- return new Promise((r) => {
482
- const o = new Image();
483
- o.crossOrigin = "anonymous";
484
- let n = null, a = !1;
485
- const s = () => {
486
- n && (clearTimeout(n), n = null);
487
- }, i = () => {
488
- if (a) return;
489
- a = !0, s();
490
- const d = o.naturalWidth || o.width, x = o.naturalHeight || o.height;
491
- r({
492
- success: !0,
493
- element: o,
494
- width: d,
495
- height: x,
496
- aspectRatio: x > 0 ? d / x : 1
497
- });
498
- }, c = (d) => {
499
- a || (a = !0, s(), r({
500
- success: !1,
501
- error: new Error(d)
502
- }));
503
- };
504
- o.onload = i, o.onerror = () => {
505
- c(`Failed to load image: ${e}`);
506
- }, n = setTimeout(() => {
507
- c(`Image load timed out after ${t}ms: ${e}`);
508
- }, t), o.src = e;
509
- });
510
- }
511
- async function Wr(e, t, r = {}, o = {}) {
512
- var R, k, T, p, N, S, b;
513
- const n = await Hr(e, o);
514
- if (!n.success || !n.width || !n.height)
515
- return {
516
- success: !1,
517
- error: n.error || new Error("Failed to get image dimensions")
518
- };
519
- const a = {
520
- width: t.artboard.width,
521
- height: t.artboard.height,
522
- scale: t.scale,
523
- align: Dr(t.alignment),
524
- offsetX: t.offsetX,
525
- offsetY: t.offsetY,
526
- scaleMode: t.scaleMode,
527
- marginTop: t.marginTop,
528
- marginRight: t.marginRight,
529
- marginBottom: t.marginBottom,
530
- marginLeft: t.marginLeft
531
- }, s = Nr(
532
- { width: n.width, height: n.height },
533
- a
534
- ), i = t.artboard.x + s.x, c = t.artboard.y + s.y, d = i + s.width / 2, x = c + s.height / 2;
535
- return {
536
- success: !0,
537
- element: new Ht({
538
- ...r,
539
- x: d,
540
- y: x,
541
- imageUrl: e,
542
- imageAspectRatio: n.aspectRatio,
543
- preserveDimensions: !0,
544
- // Don't recalculate dimensions on image load
545
- transformData: {
546
- type: "image",
547
- width: s.width,
548
- height: s.height,
549
- cropX: ((R = r.transformData) == null ? void 0 : R.cropX) ?? 0,
550
- cropY: ((k = r.transformData) == null ? void 0 : k.cropY) ?? 0,
551
- cropWidth: ((T = r.transformData) == null ? void 0 : T.cropWidth) ?? 1,
552
- cropHeight: ((p = r.transformData) == null ? void 0 : p.cropHeight) ?? 1,
553
- flipHorizontal: ((N = r.transformData) == null ? void 0 : N.flipHorizontal) ?? !1,
554
- flipVertical: ((S = r.transformData) == null ? void 0 : S.flipVertical) ?? !1,
555
- borderRadius: ((b = r.transformData) == null ? void 0 : b.borderRadius) ?? 0
556
- }
557
- }),
558
- placement: {
559
- artworkSize: { width: n.width, height: n.height },
560
- finalSize: { width: s.width, height: s.height },
561
- position: { x: d, y: x },
562
- scale: s.scale
563
- }
564
- };
565
- }
566
- function Ur(e) {
567
- return new Promise((t) => setTimeout(t, e));
568
- }
569
- const J = nt("SnowconeCanvas");
570
- function Nt(e, t, r, o) {
571
- if (o <= 0 || !isFinite(o))
572
- return r;
573
- const n = e * r, a = t * r;
574
- if (Math.max(n, a) <= o)
575
- return r;
576
- const i = Math.max(e, t), c = o / i;
577
- return Math.min(c, r);
578
- }
579
- const ge = fe((e, t) => {
580
- const {
581
- exportConfig: r,
582
- imageConfig: o,
583
- layoutConfig: n,
584
- kit: a,
585
- artboards: s,
586
- activeArtboard: i,
587
- onArtboardChange: c,
588
- initialElements: d,
589
- onChange: x,
590
- onSelectionChange: I,
591
- autoExportInterval: R,
592
- onExport: k,
593
- onExportScheduled: T,
594
- onExportStatus: p,
595
- onExportReady: N,
596
- onImageLoad: S,
597
- onImageError: b,
598
- onError: E,
599
- onReady: v,
600
- className: W,
601
- style: B,
602
- enableShortcuts: X,
603
- overlay: ut
604
- } = e, Lt = R, at = e.autoExportConfig ?? (r == null ? void 0 : r.autoExportConfig), tt = e.autoExportFormat ?? (r == null ? void 0 : r.format) ?? "dataUrl", kt = e.autoExportAll ?? (r == null ? void 0 : r.exportAll) ?? !1, G = e.exportScale ?? (r == null ? void 0 : r.scale) ?? 2, z = e.maxExportSize ?? (r == null ? void 0 : r.maxSize) ?? 4e3, ft = e.exportImageFormat ?? (r == null ? void 0 : r.imageFormat) ?? "png", ht = e.exportImageQuality ?? (r == null ? void 0 : r.imageQuality) ?? 0.92, L = e.initialImage ?? (o == null ? void 0 : o.src), Ot = e.initialImageAlignment ?? (o == null ? void 0 : o.alignment) ?? "center", Yt = e.initialImageScale ?? (o == null ? void 0 : o.scale) ?? 1, Xt = e.initialImageScaleMode ?? (o == null ? void 0 : o.scaleMode) ?? "cover", xe = e.width ?? (n == null ? void 0 : n.width) ?? 1200, ve = e.height ?? (n == null ? void 0 : n.height) ?? 1200, we = e.viewPadding ?? (n == null ? void 0 : n.viewPadding) ?? 0.9, Ee = e.artboardBorderRadius ?? (n == null ? void 0 : n.artboardBorderRadius) ?? 0, Ae = e.fixedMargin ?? (n == null ? void 0 : n.fixedMargin), ke = e.maxHeight ?? (n == null ? void 0 : n.maxHeight), Se = e.showRotationHandle ?? (n == null ? void 0 : n.showRotationHandle) ?? !0, Re = e.hideCanvas ?? (n == null ? void 0 : n.hideCanvas) ?? !1, Vt = e.canvasWrapperClassName ?? (n == null ? void 0 : n.canvasWrapperClassName), jt = e.canvasWrapperStyle ?? (n == null ? void 0 : n.canvasWrapperStyle), Ce = e.canvasCutouts ?? (n == null ? void 0 : n.canvasCutouts), Kt = e.pieceGuides, Ie = e.pieceFocus, Fe = X ?? !0, st = ot(() => sr(a ?? "pro-studio"), [a]);
605
- C(() => {
606
- var l;
607
- if (typeof K < "u" && ((l = K.env) == null ? void 0 : l.NODE_ENV) === "development" && st) {
608
- const u = ir(st);
609
- u.valid || J.warn("Kit validation warnings:", u.errors), u.warnings.length > 0 && J.warn("Kit validation warnings:", u.warnings);
610
- }
611
- }, [st]);
612
- const mt = M(E);
613
- mt.current = E;
614
- const U = P((l) => {
615
- var u;
616
- J.error(`[${l.category}] ${l.message}`, l.originalError), (u = mt.current) == null || u.call(mt, l);
617
- }, []);
618
- C(() => (Tt.onRenderError = U, () => {
619
- Tt.onRenderError === U && (Tt.onRenderError = null);
620
- }), [U]);
621
- const {
622
- elements: q,
623
- setElements: gt,
624
- selectedId: Gt,
625
- artboardManager: F,
626
- refreshArtboards: Me,
627
- historyManager: Te,
628
- isCanvasReady: St,
629
- setCanvasReady: pt
630
- } = Wt(), { createArtboard: De, selectArtboard: Ne, artboards: H } = cr(), { exportArtboard: et, exportAllArtboards: bt, exportArtboardAsBlob: rt, exportAllArtboardsAsBlobs: yt } = lr();
631
- Ve(t, () => ({
632
- exportArtboards: async (l = {}) => {
633
- const u = l.format || tt, A = l.scale || G, f = l.all ?? !1;
634
- let m = A;
635
- if (z > 0 && isFinite(z))
636
- for (const h of H) {
637
- const y = Nt(h.width, h.height, A, z);
638
- m = Math.min(m, y);
639
- }
640
- const g = { scale: m, format: ft, quality: ht };
641
- if (f) {
642
- const h = u === "blob" ? await yt(g) : await bt(g), y = {};
643
- for (const [D, O] of Object.entries(h)) {
644
- const V = H.find((it) => it.id === D);
645
- V && (y[V.name] = O);
646
- }
647
- return y;
648
- } else {
649
- const h = F.getActiveArtboard();
650
- if (!h)
651
- throw new Error("[SnowconeCanvas] No active artboard found");
652
- if (u === "blob") {
653
- const y = await rt(h.id, g);
654
- return { [h.name]: y };
655
- } else {
656
- const y = await et(h.id, g);
657
- return { [h.name]: y };
658
- }
659
- }
660
- }
661
- }), [et, bt, rt, yt, tt, G, z, ft, ht, F, H]), C(() => {
662
- N && N(async () => {
663
- const u = F.getActiveArtboard();
664
- if (!u)
665
- throw new Error("[SnowconeCanvas] No active artboard found");
666
- const A = Nt(
667
- u.width,
668
- u.height,
669
- G,
670
- z
671
- ), f = tt === "blob" ? await rt(u.id, { scale: A }) : await et(u.id, { scale: A });
672
- return { [u.name]: f };
673
- });
674
- }, [N, et, rt, F, tt, G, z]);
675
- const [qt, xt] = _("idle"), [Jt, Rt] = _(null), Ct = M(void 0), It = M(!1), Qt = M(!1), [Be, $e] = _(!1), He = M(0), Pe = M(0), Ft = M(!1);
676
- C(() => {
677
- if (It.current) return;
678
- It.current = !0;
679
- const l = s || [{ name: "Design", width: xe, height: ve }], u = F.getAllArtboards();
680
- if (u.length > 0) {
681
- const A = l[0], f = u[0], m = Kt ? "transparent" : void 0, g = (h) => h.exportBackground ?? (!!h.backgroundColor && h.backgroundColor !== "transparent");
682
- f.name = A.name, f.width = A.width, f.height = A.height, f.clipShape = A.clipShape, f.exportBackground = g(A), A.backgroundColor ? f.backgroundColor = A.backgroundColor : m && (f.backgroundColor = m);
683
- for (let h = 1; h < l.length; h++)
684
- De(l[h].width, l[h].height, {
685
- name: l[h].name,
686
- backgroundColor: l[h].backgroundColor ?? m,
687
- exportBackground: g(l[h]),
688
- clipShape: l[h].clipShape
689
- });
690
- !i && l.length > 1 && F.setActiveArtboard(f.id);
691
- }
692
- Me();
693
- }, []), C(() => {
694
- if (!(!d || d.length === 0) && !Qt.current && It.current) {
695
- Qt.current = !0, $e(!0);
696
- try {
697
- const l = gr.createManyFromJSON(d), u = F.getAllArtboards();
698
- if (u.length > 0) {
699
- const f = new Map(u.map((m) => [m.name, m]));
700
- l.forEach((m, g) => {
701
- var D;
702
- const h = (D = d[g]) == null ? void 0 : D.artboard, y = h && f.get(h) || u[0];
703
- F.addElementToArtboard(m.id, y.id);
704
- });
705
- }
706
- gt(l);
707
- const A = /* @__PURE__ */ new Set();
708
- for (const f of l) {
709
- const m = f.fontFamily;
710
- typeof m == "string" && m.trim().length > 0 && A.add(m);
711
- }
712
- if (A.size > 0 && typeof document < "u") {
713
- const f = document.fonts ?? null, m = Array.from(A).map((g) => {
714
- const h = `font-${g.replace(/\s+/g, "-").toLowerCase()}`;
715
- let y = document.getElementById(h);
716
- return y || (y = document.createElement("link"), y.id = h, y.rel = "stylesheet", y.href = `https://fonts.googleapis.com/css2?family=${g.replace(
717
- /\s+/g,
718
- "+"
719
- )}:wght@400;700&display=swap`, document.head.appendChild(y)), new Promise((D) => {
720
- if (y.sheet) {
721
- D(g);
722
- return;
723
- }
724
- const O = () => D(g);
725
- y.addEventListener("load", O, { once: !0 }), y.addEventListener("error", O, { once: !0 }), setTimeout(O, 4e3);
726
- });
727
- });
728
- Promise.all(m).then((g) => {
729
- if (f)
730
- return Promise.all(
731
- g.flatMap((h) => [
732
- f.load(`400 16px "${h}"`).catch(() => {
733
- }),
734
- f.load(`700 16px "${h}"`).catch(() => {
735
- })
736
- ])
737
- );
738
- }).then(() => {
739
- gt((g) => g.slice());
740
- });
741
- }
742
- } catch (l) {
743
- J.error("Failed to load initial elements:", l);
744
- const u = l instanceof Error ? l : new Error(String(l));
745
- U({
746
- category: "import",
747
- message: `Failed to load initial elements: ${u.message}`,
748
- originalError: u,
749
- recoverable: !0
750
- });
751
- }
752
- }
753
- }, [d, F, gt, U]), C(() => {
754
- if (!i) {
755
- Ft.current = !0;
756
- return;
757
- }
758
- const l = H.find((u) => u.name === i);
759
- if (l) {
760
- const u = F.getActiveArtboard();
761
- (u == null ? void 0 : u.name) !== i && Ne(l.id), Ft.current = !0;
762
- }
763
- }, [i, H]), C(() => {
764
- if (!L || Ct.current === L) return;
765
- if (q.length > 0) {
766
- Ct.current = L;
767
- return;
768
- }
769
- Ct.current = L, (async () => {
770
- xt("loading"), Rt(null);
771
- try {
772
- const u = F.getAllArtboards();
773
- if (u.length === 0)
774
- throw new Error("No artboards available");
775
- const A = [];
776
- for (const f of u) {
777
- const m = s == null ? void 0 : s.find((y) => y.name === f.name), g = (m == null ? void 0 : m.scaleMode) || Xt, h = await Wr(
778
- L,
779
- {
780
- artboard: {
781
- width: f.width,
782
- height: f.height,
783
- x: f.x,
784
- y: f.y
785
- },
786
- alignment: (m == null ? void 0 : m.fitAlign) || Ot,
787
- scale: Yt,
788
- scaleMode: g,
789
- marginTop: m == null ? void 0 : m.fitMarginTop,
790
- marginRight: m == null ? void 0 : m.fitMarginRight,
791
- marginBottom: m == null ? void 0 : m.fitMarginBottom,
792
- marginLeft: m == null ? void 0 : m.fitMarginLeft
793
- }
794
- );
795
- h.success && h.element ? (F.addElementToArtboard(h.element.id, f.id), A.push(h.element)) : J.error("Failed to load image for artboard:", f.name, h.error);
796
- }
797
- if (A.length > 0)
798
- gt((f) => [...f, ...A]), xt("success"), S == null || S(L);
799
- else {
800
- const f = new Error("Failed to load image into any artboard");
801
- xt("error"), Rt(f), b == null || b(L, f), U({
802
- category: "image",
803
- message: f.message,
804
- originalError: f,
805
- recoverable: !0
806
- });
807
- }
808
- } catch (u) {
809
- const A = u instanceof Error ? u : new Error(String(u));
810
- xt("error"), Rt(A), b == null || b(L, A), U({
811
- category: "image",
812
- message: A.message,
813
- originalError: A,
814
- recoverable: !0
815
- });
816
- }
817
- })();
818
- }, [L, Ot, Yt, Xt]);
819
- const vt = M(I);
820
- vt.current = I, C(() => {
821
- var l;
822
- (l = vt.current) == null || l.call(vt, Gt);
823
- }, [Gt]);
824
- const Zt = M(x);
825
- Zt.current = x, C(() => {
826
- const l = Zt.current;
827
- if (!l) return;
828
- const u = F.getActiveArtboard(), A = {
829
- // Stamp each element with the NAME of the artboard it lives on (the
830
- // manager is the membership source of truth). Without this the public
831
- // state is flat and a multi-placement design cannot round-trip: restore
832
- // collapses everything onto the first artboard, and per-placement render
833
- // states can't be derived from onChange. Pinned by
834
- // SnowconeCanvas.artboard-membership.test.tsx.
835
- elements: q.map((f) => {
836
- const m = f.toJSON(), g = F.getArtboardForElement(f.id);
837
- return g ? { ...m, artboard: g.name } : m;
838
- }),
839
- artboards: H.map((f) => ({
840
- name: f.name,
841
- width: f.width,
842
- height: f.height,
843
- clipShape: f.clipShape,
844
- backgroundColor: f.backgroundColor,
845
- // Carried so serializeStateForServer / saved states keep an
846
- // explicitly-set background renderable (mockup matches editor).
847
- exportBackground: f.exportBackground
848
- })),
849
- activeArtboard: (u == null ? void 0 : u.name) || "Design"
850
- };
851
- l(A);
852
- }, [q, H]), C(() => {
853
- if (!c || !Ft.current) return;
854
- const l = F.getActiveArtboard();
855
- l && c(l.name);
856
- }, [F.getActiveArtboardId()]);
857
- const We = P(async () => {
858
- if (!k && !p) return;
859
- const l = ++Pe.current, u = Date.now();
860
- let A = G;
861
- if (z > 0 && isFinite(z))
862
- for (const g of H) {
863
- const h = Nt(g.width, g.height, G, z);
864
- A = Math.min(A, h);
865
- }
866
- const f = F.getActiveArtboard(), m = (f == null ? void 0 : f.id) ?? "unknown";
867
- p == null || p({ status: "rendering", artboardId: m }), He.current = u;
868
- try {
869
- let g;
870
- const h = {
871
- format: ft,
872
- scale: A,
873
- quality: ht
874
- };
875
- if (tt === "blob")
876
- if (kt) {
877
- const y = await yt(h);
878
- g = {};
879
- for (const [D, O] of Object.entries(y)) {
880
- const V = H.find((it) => it.id === D);
881
- V && (g[V.name] = O);
882
- }
883
- } else {
884
- const y = F.getActiveArtboard();
885
- if (!y) return;
886
- const D = await rt(y.id, h);
887
- g = { [y.name]: D };
888
- }
889
- else if (kt) {
890
- const y = await bt(h);
891
- g = {};
892
- for (const [D, O] of Object.entries(y)) {
893
- const V = H.find((it) => it.id === D);
894
- V && (g[V.name] = O);
895
- }
896
- } else {
897
- const y = F.getActiveArtboard();
898
- if (!y) return;
899
- const D = await et(y.id, h);
900
- g = { [y.name]: D };
901
- }
902
- k == null || k(g), p == null || p({ status: "complete", artboardId: m, result: g });
903
- } catch (g) {
904
- const h = g instanceof Error ? g.message : String(g);
905
- if (h.includes("Canvas ref not available"))
906
- return;
907
- const y = Date.now() - u;
908
- J.error("Export failed (export #" + l + "):", {
909
- duration: `${y}ms`,
910
- error: h
911
- });
912
- const D = g instanceof Error ? g : new Error(h);
913
- p == null || p({ status: "error", artboardId: m, error: D }), U({
914
- category: "export",
915
- message: D.message,
916
- originalError: D,
917
- artboardId: m,
918
- recoverable: !0
919
- });
920
- }
921
- }, [k, p, kt, tt, G, z, ft, ht, et, bt, rt, yt, H, F, q, at, U]);
922
- C(() => {
923
- Lt !== void 0 && Lt > 0 && J.warn(
924
- "autoExportInterval is deprecated and ignored. Use autoExportConfig={{ enabled: true, debounceMs: 100, maxWaitMs: 1000 }} instead."
925
- );
926
- }, []), C(() => {
927
- }, [q]);
928
- const Ue = P(() => {
929
- if (T == null || T(), p) {
930
- const l = F.getActiveArtboard();
931
- p({ status: "scheduled", artboardId: (l == null ? void 0 : l.id) ?? "unknown" });
932
- }
933
- }, [T, p, F]), ze = !!d && d.length > 0, Mt = Mr({
934
- isCanvasReady: St,
935
- elements: q,
936
- hasInitialElements: ze,
937
- initialElementsLoaded: Be
938
- }), _t = M(!1);
939
- C(() => {
940
- Mt && !_t.current && (_t.current = !0, v == null || v());
941
- }, [Mt, v]), Rr({
942
- config: at ? {
943
- enabled: at.enabled ?? !0,
944
- debounceMs: at.debounceMs ?? 100,
945
- maxWaitMs: at.maxWaitMs ?? 1e3
946
- } : {
947
- enabled: !1
948
- // Only use smart export if autoExportConfig is provided
949
- },
950
- historyManager: Te,
951
- artboards: H,
952
- elements: q,
953
- onExport: We,
954
- onExportScheduled: Ue,
955
- isCanvasReady: Mt
956
- // Gate exports until content is fully ready (fonts loaded, elements deserialized)
957
- }), C(() => {
958
- if (H.length > 0 && !St) {
959
- const l = requestAnimationFrame(() => {
960
- pt(!0);
961
- });
962
- return () => cancelAnimationFrame(l);
963
- }
964
- }, [H.length, St, pt]), C(() => () => {
965
- pt(!1);
966
- }, [pt]);
967
- const Le = P((l) => {
968
- U({
969
- category: "unknown",
970
- message: l.message,
971
- originalError: l,
972
- recoverable: !1
973
- });
974
- }, [U]);
975
- return qt === "loading" ? /* @__PURE__ */ w(
976
- "div",
977
- {
978
- className: W,
979
- style: {
980
- ...B,
981
- display: "flex",
982
- alignItems: "center",
983
- justifyContent: "center",
984
- backgroundColor: "var(--surface, #f5f5f5)"
985
- },
986
- children: /* @__PURE__ */ w(dr, { size: 48 })
987
- }
988
- ) : qt === "error" && Jt ? /* @__PURE__ */ w(
989
- "div",
990
- {
991
- className: W,
992
- style: {
993
- ...B,
994
- display: "flex",
995
- alignItems: "center",
996
- justifyContent: "center",
997
- backgroundColor: "var(--surface, #f5f5f5)",
998
- color: "var(--danger, #dc2626)",
999
- padding: "1rem"
1000
- },
1001
- children: /* @__PURE__ */ Z("div", { className: "sc:text-center", children: [
1002
- /* @__PURE__ */ w("div", { className: "sc:font-medium", children: "Failed to load image" }),
1003
- /* @__PURE__ */ w("div", { className: "sc:text-sm sc:mt-1 sc:opacity-70", children: Jt.message })
1004
- ] })
1005
- }
1006
- ) : /* @__PURE__ */ w(ur, { kit: st, children: /* @__PURE__ */ w("div", { className: `sc-root ${W || ""}`, style: { ...B, position: "relative" }, children: /* @__PURE__ */ Z(
1007
- kr,
1008
- {
1009
- onError: Le,
1010
- fallback: (l, u) => /* @__PURE__ */ Z(
1011
- "div",
1012
- {
1013
- style: {
1014
- display: "flex",
1015
- flexDirection: "column",
1016
- alignItems: "center",
1017
- justifyContent: "center",
1018
- padding: "24px",
1019
- minHeight: "200px",
1020
- backgroundColor: "var(--surface, #f5f5f5)",
1021
- color: "var(--foreground, #333)",
1022
- fontFamily: "system-ui, sans-serif",
1023
- textAlign: "center"
1024
- },
1025
- children: [
1026
- /* @__PURE__ */ w("div", { style: { fontSize: "18px", fontWeight: 600, marginBottom: "8px" }, children: "Something went wrong" }),
1027
- /* @__PURE__ */ w("div", { style: { fontSize: "14px", opacity: 0.7, marginBottom: "16px", maxWidth: "400px" }, children: l.message }),
1028
- /* @__PURE__ */ w(
1029
- "button",
1030
- {
1031
- onClick: u,
1032
- style: {
1033
- padding: "8px 20px",
1034
- backgroundColor: "var(--primary, #333)",
1035
- color: "var(--primary-foreground, #fff)",
1036
- border: "none",
1037
- borderRadius: "6px",
1038
- fontSize: "14px",
1039
- fontWeight: 500,
1040
- cursor: "pointer"
1041
- },
1042
- children: "Try again"
1043
- }
1044
- )
1045
- ]
1046
- }
1047
- ),
1048
- children: [
1049
- !Re && /* @__PURE__ */ (() => {
1050
- const l = /* @__PURE__ */ w(
1051
- hr,
1052
- {
1053
- style: { width: "100%" },
1054
- fitPadding: we,
1055
- artboardBorderRadius: Ee,
1056
- fixedMargin: Ae,
1057
- maxHeight: ke,
1058
- showRotationHandle: Se,
1059
- enableShortcuts: Fe,
1060
- canvasCutouts: Ce,
1061
- pieceGuides: Kt,
1062
- pieceFocus: Ie
1063
- }
1064
- );
1065
- return /* @__PURE__ */ w(Er, { kit: st, canvas: Vt || jt ? /* @__PURE__ */ w("div", { className: Vt, style: jt, children: l }) : l });
1066
- })(),
1067
- ut
1068
- ]
1069
- }
1070
- ) }) });
1071
- });
1072
- ge.displayName = "SnowconeCanvasInner";
1073
- const zr = fe((e, t) => {
1074
- var c;
1075
- const { inheritTheme: r, externalProvider: o, services: n } = e, a = e.viewPadding ?? ((c = e.layoutConfig) == null ? void 0 : c.viewPadding), s = /* @__PURE__ */ w(ge, { ref: t, ...e }), i = o ? /* @__PURE__ */ w(te, { defaultTheme: "light", passive: r, children: s }) : /* @__PURE__ */ w(te, { defaultTheme: "light", passive: r, children: /* @__PURE__ */ w(je, { viewPadding: a, children: s }) });
1076
- return n ? /* @__PURE__ */ w(fr, { services: n, children: i }) : i;
1077
- });
1078
- zr.displayName = "SnowconeCanvas";
1079
- function pn() {
1080
- const { selectedElement: e } = Wt();
1081
- return e ?? null;
1082
- }
1083
- const Lr = 3e3, ce = {
1084
- text: "useTextBinding",
1085
- image: "useImageBinding",
1086
- font: "useFontBinding"
1087
- }, Or = {
1088
- text: "setText",
1089
- image: "setImageUrl",
1090
- font: "setFontFamily"
1091
- }, Yr = {
1092
- text: "text",
1093
- image: "image",
1094
- font: "text"
1095
- }, Bt = /* @__PURE__ */ new Set();
1096
- function le(e) {
1097
- return e instanceof Pt ? "text" : e instanceof Ht ? "image" : "other";
1098
- }
1099
- function Xr(e, t, r) {
1100
- const o = `[${ce[e]}]`, n = `the binding is dead (isConnected: false, ${Or[e]} is a no-op)`, a = Yr[e], s = r.getAllByName(t);
1101
- if (s.length > 0) {
1102
- const d = [...new Set(s.map(le))], x = a === "text" ? "image" : "text", I = d.length === 1 && d[0] === x ? ` Bind it with ${ce[x]}("${t}") instead.` : "";
1103
- return `${o} the layer named "${t}" is ${d.join("/")}, not ${a} — ${n}.${I}`;
1104
- }
1105
- const i = r.getAll().filter((d) => d.name).map((d) => `"${d.name}" (${le(d)})`), c = i.length ? `Named layers on this canvas: ${i.join(", ")}. Check the name for a typo.` : `No element on this canvas has a name — name one via design().${a}(…, { name: '${t}' }) or the element's \`name\` property.`;
1106
- return `${o} no ${a} layer named "${t}" exists — ${n}. ${c}`;
1107
- }
1108
- function Ut(e, t, r, o) {
1109
- C(() => {
1110
- var s;
1111
- if (o || typeof K > "u" || ((s = K.env) == null ? void 0 : s.NODE_ENV) === "production") return;
1112
- const n = `${e}:${t}`;
1113
- if (Bt.has(n)) return;
1114
- const a = setTimeout(() => {
1115
- Bt.has(n) || (Bt.add(n), console.warn(Xr(e, t, r)));
1116
- }, Lr);
1117
- return () => clearTimeout(a);
1118
- }, [e, t, r, o]);
1119
- }
1120
- const Vr = () => {
1121
- }, jr = [];
1122
- function bn(e) {
1123
- const { elementStore: t } = dt(), { executeElementUpdate: r } = At(), o = ot(() => t.getAllByName(e).filter((s) => s instanceof Pt), [t, e]), n = P(
1124
- (a) => {
1125
- for (const s of o) {
1126
- const i = s.clone();
1127
- i.setText(a), r(s, i);
1128
- }
1129
- },
1130
- [o, r]
1131
- );
1132
- return Ut("text", e, t, o.length > 0), o.length === 0 ? { text: "", setText: Vr, element: null, elements: jr, isConnected: !1 } : {
1133
- text: o[0].getText(),
1134
- setText: n,
1135
- element: o[0],
1136
- elements: o,
1137
- isConnected: !0
1138
- };
1139
- }
1140
- const Kr = () => {
1141
- }, Gr = [];
1142
- function qr(e, t, r) {
1143
- const o = e / t;
1144
- if (r >= o) {
1145
- const n = t, a = n * r, s = e / a;
1146
- return {
1147
- width: a,
1148
- height: n,
1149
- cropX: (1 - s) / 2,
1150
- cropY: 0,
1151
- cropWidth: s,
1152
- cropHeight: 1
1153
- };
1154
- } else {
1155
- const n = e, a = n / r, s = t / a;
1156
- return {
1157
- width: n,
1158
- height: a,
1159
- cropX: 0,
1160
- cropY: (1 - s) / 2,
1161
- cropWidth: 1,
1162
- cropHeight: s
1163
- };
1164
- }
1165
- }
1166
- function yn(e, t) {
1167
- const r = (t == null ? void 0 : t.fit) ?? "cover", { elementStore: o, setElements: n } = dt(), { executeElementUpdate: a } = At(), s = ot(() => o.getAllByName(e).filter((k) => k instanceof Ht), [o, e]), i = M(/* @__PURE__ */ new Map());
1168
- for (const R of s)
1169
- if (!i.current.has(R.id)) {
1170
- const k = R.transformData;
1171
- i.current.set(R.id, {
1172
- width: k.width * k.cropWidth,
1173
- height: k.height * k.cropHeight
1174
- });
1175
- }
1176
- const c = M(s);
1177
- c.current = s;
1178
- const d = M(a);
1179
- d.current = a;
1180
- const x = M(n);
1181
- x.current = n;
1182
- const I = P(
1183
- (R) => {
1184
- const k = c.current, T = d.current;
1185
- for (const p of k) {
1186
- const N = i.current.get(p.id);
1187
- if (!N) continue;
1188
- const { width: S, height: b } = N, E = p.clone();
1189
- E.imageLoaded = !1, E.imageElement = null, E.isCropping = !1, E.imageUrl = R, r === "cover" ? (E.preserveDimensions = !0, E.onLoadCallback = (v) => {
1190
- const W = v.imageAspectRatio || 1, B = qr(S, b, W);
1191
- v.transformData.width = B.width, v.transformData.height = B.height, v.transformData.cropX = B.cropX, v.transformData.cropY = B.cropY, v.transformData.cropWidth = B.cropWidth, v.transformData.cropHeight = B.cropHeight, T(p, v);
1192
- }) : (E.preserveDimensions = !1, E.onLoadCallback = (v) => {
1193
- const W = v.transformData.width, B = v.transformData.height, X = Math.min(S / W, b / B, 1);
1194
- X < 1 && (v.transformData.width = W * X, v.transformData.height = B * X), v.transformData.cropX = 0, v.transformData.cropY = 0, v.transformData.cropWidth = 1, v.transformData.cropHeight = 1, T(p, v);
1195
- }), E.loadImage(R);
1196
- }
1197
- },
1198
- [r]
1199
- // Stable deps only — imageElements/executeElementUpdate/setElements accessed via refs
1200
- );
1201
- return Ut("image", e, o, s.length > 0), s.length === 0 ? { imageUrl: "", setImageUrl: Kr, element: null, elements: Gr, isConnected: !1 } : {
1202
- imageUrl: s[0].imageUrl,
1203
- setImageUrl: I,
1204
- element: s[0],
1205
- elements: s,
1206
- isConnected: !0
1207
- };
1208
- }
1209
- const Jr = [];
1210
- function Et(e) {
1211
- let t = e.trim().toUpperCase();
1212
- return t.length === 4 && t.startsWith("#") && (t = "#" + t[1] + t[1] + t[2] + t[2] + t[3] + t[3]), t;
1213
- }
1214
- function j(e, t) {
1215
- return typeof e == "string" && Et(e) === t;
1216
- }
1217
- function pe(e, t) {
1218
- var o, n, a;
1219
- const r = e;
1220
- return j(r.color, t) || j((o = r.transformData) == null ? void 0 : o.fillColor, t) || j((n = r.transformData) == null ? void 0 : n.strokeColor, t) || ((a = r.stroke) == null ? void 0 : a.enabled) === !0 && j(r.stroke.color, t);
1221
- }
1222
- function Qr(e, t, r) {
1223
- var s, i, c;
1224
- if (!pe(e, t)) return null;
1225
- const o = e.clone(), n = e, a = o;
1226
- return j(n.color, t) && (typeof a.setColor == "function" ? a.setColor(r) : a.color = r), j((s = n.transformData) == null ? void 0 : s.fillColor, t) && (a.transformData = { ...a.transformData, fillColor: r }), j((i = n.transformData) == null ? void 0 : i.strokeColor, t) && (a.transformData = { ...a.transformData, strokeColor: r }), ((c = n.stroke) == null ? void 0 : c.enabled) === !0 && j(n.stroke.color, t) && (a.stroke = { ...a.stroke, color: r }), o;
1227
- }
1228
- function xn(e) {
1229
- const { elementStore: t } = dt(), { executeElementUpdate: r } = At(), [o, n] = _(() => Et(e)), [a, s] = _(e);
1230
- e !== a && (s(e), n(Et(e)));
1231
- const i = ot(
1232
- () => t.getAll().filter((d) => pe(d, o)),
1233
- [t, o]
1234
- ), c = P(
1235
- (d) => {
1236
- const x = Et(d);
1237
- if (x !== o) {
1238
- for (const I of t.getAll()) {
1239
- const R = Qr(I, o, d);
1240
- R && r(I, R);
1241
- }
1242
- n(x);
1243
- }
1244
- },
1245
- [t, o, r]
1246
- );
1247
- return i.length === 0 ? { color: o, setColor: c, elements: Jr, isConnected: !1 } : { color: o, setColor: c, elements: i, isConnected: !0 };
1248
- }
1249
- const Zr = () => {
1250
- }, _r = [];
1251
- function vn(e) {
1252
- const { elementStore: t } = dt(), { executeElementUpdate: r } = At(), o = ot(() => t.getAllByName(e).filter((s) => s instanceof Pt), [t, e]), n = P(
1253
- (a) => {
1254
- mr.loadGoogleFontByName(a);
1255
- for (const s of o) {
1256
- if (s.fontFamily === a) continue;
1257
- Ye.clearCache(s.fontFamily);
1258
- const i = s.clone();
1259
- i.fontFamily = a, r(s, i);
1260
- }
1261
- },
1262
- [o, r]
1263
- );
1264
- return Ut("font", e, t, o.length > 0), o.length === 0 ? { fontFamily: "", setFontFamily: Zr, element: null, elements: _r, isConnected: !1 } : {
1265
- fontFamily: o[0].fontFamily,
1266
- setFontFamily: n,
1267
- element: o[0],
1268
- elements: o,
1269
- isConnected: !0
1270
- };
1271
- }
1272
- function wn(e) {
1273
- const { elementStore: t } = dt();
1274
- return e ? t.getByName(e) ?? null : null;
1275
- }
1276
- const tn = 1;
1277
- function Q(e) {
1278
- return typeof e == "number" && Number.isFinite(e) ? Math.round(e * 100) / 100 : e;
1279
- }
1280
- function be(e) {
1281
- return {
1282
- ...e,
1283
- ...e.x !== void 0 && { x: Q(e.x) },
1284
- ...e.y !== void 0 && { y: Q(e.y) },
1285
- ...e.width !== void 0 && { width: Q(e.width) },
1286
- ...e.height !== void 0 && { height: Q(e.height) },
1287
- ...e.rotation !== void 0 && { rotation: Q(e.rotation) }
1288
- };
1289
- }
1290
- function en(e) {
1291
- var o;
1292
- const t = (o = e.artboards) != null && o.length ? e.artboards : [{ name: "Front", width: 800, height: 800 }], r = t.map(() => []);
1293
- for (const n of e.elements || []) {
1294
- const a = n == null ? void 0 : n.artboard, s = typeof a == "string" ? t.findIndex((i) => (i.name || "Front") === a) : -1;
1295
- r[s >= 0 ? s : 0].push(rn(n));
1296
- }
1297
- return {
1298
- schemaVersion: tn,
1299
- artboards: t.map((n, a) => ({
1300
- id: `artboard-${a + 1}`,
1301
- name: n.name || "Front",
1302
- x: 0,
1303
- y: 0,
1304
- width: Q(n.width || 800),
1305
- height: Q(n.height || 800),
1306
- backgroundColor: n.backgroundColor || "transparent",
1307
- // Pass the artboard's flag through — the server worker only paints the
1308
- // background when this is true. Hardcoding `false` here silently dropped
1309
- // explicitly-set artboard backgrounds from every realtime mockup while
1310
- // the editor kept showing them (WYSIWYG drift).
1311
- exportBackground: n.exportBackground ?? !1,
1312
- elements: r[a],
1313
- distressTexture: n.distressTexture,
1314
- imageMask: n.imageMask
1315
- }))
1316
- };
1317
- }
1318
- function rn(e) {
1319
- const t = e.type || e.transformType;
1320
- if (t === "image")
1321
- return nn(e);
1322
- const { artboard: r, ...o } = e;
1323
- return be({
1324
- ...o,
1325
- type: t
1326
- });
1327
- }
1328
- function nn(e) {
1329
- var d;
1330
- const t = e.transformData || {}, r = e.masks && e.masks.length > 0, o = t.width || 0, n = t.height || 0, a = r ? o : o * (t.cropWidth ?? 1), s = r ? n : n * (t.cropHeight ?? 1), i = {
1331
- id: e.id,
1332
- type: "image",
1333
- x: e.x || 0,
1334
- y: e.y || 0,
1335
- width: a,
1336
- height: s,
1337
- rotation: e.rotation || 0,
1338
- imageUrl: e.imageUrl,
1339
- imageAspectRatio: e.imageAspectRatio
1340
- };
1341
- return !r && (t.cropX !== 0 || t.cropY !== 0 || t.cropWidth !== 1 || t.cropHeight !== 1) && (i.cropX = t.cropX, i.cropY = t.cropY, i.cropWidth = t.cropWidth, i.cropHeight = t.cropHeight, i.needsCropPixelConversion = !0), t.flipHorizontal && (i.flipHorizontal = t.flipHorizontal), t.flipVertical && (i.flipVertical = t.flipVertical), t.borderRadius && (i.borderRadius = t.borderRadius), e.opacity !== void 0 && (i.opacity = e.opacity), e.distressEffect && (i.distressEffect = e.distressEffect), ((d = e.masks) == null ? void 0 : d.length) > 0 && (i.masks = e.masks), e.blendMode && (i.blendMode = e.blendMode), e.knockoutParts && (i.knockoutParts = e.knockoutParts), e.stroke && (i.stroke = e.stroke), be(i);
1342
- }
1343
- const de = "center";
1344
- function on(e) {
1345
- return e === "top-left" || e === "left" || e === "bottom-left" ? "left" : e === "top-right" || e === "right" || e === "bottom-right" ? "right" : "center";
1346
- }
1347
- function an(e) {
1348
- return e === "top-left" || e === "top" || e === "top-right" ? "top" : e === "bottom-left" || e === "bottom" || e === "bottom-right" ? "bottom" : "middle";
1349
- }
1350
- function $t(e, t, r, o, n, a) {
1351
- const s = on(e), i = an(e), c = s === "left" ? t / 2 + a : s === "right" ? o - t / 2 - a : o / 2, d = i === "top" ? r / 2 + a : i === "bottom" ? n - r / 2 - a : n / 2;
1352
- return { x: c, y: d };
1353
- }
1354
- function sn(e, t, r) {
1355
- const o = t / r;
1356
- if (e >= o) {
1357
- const s = r * e, i = t / s;
1358
- return {
1359
- width: s,
1360
- height: r,
1361
- cropX: (1 - i) / 2,
1362
- cropY: 0,
1363
- cropWidth: i,
1364
- cropHeight: 1
1365
- };
1366
- }
1367
- const n = t / e, a = r / n;
1368
- return {
1369
- width: t,
1370
- height: n,
1371
- cropX: 0,
1372
- cropY: (1 - a) / 2,
1373
- cropWidth: 1,
1374
- cropHeight: a
1375
- };
1376
- }
1377
- class zt {
1378
- constructor(t) {
1379
- if (this.els = [], this.idCounter = 0, !(t.width > 0) || !(t.height > 0))
1380
- throw new Error("design(): artboard width and height must be positive numbers");
1381
- this.artboard = {
1382
- name: t.name || "Front",
1383
- width: t.width,
1384
- height: t.height,
1385
- backgroundColor: t.backgroundColor
1386
- };
1387
- }
1388
- /**
1389
- * Seed a builder from a previously saved canvas state — the editor shape
1390
- * `<SnowconeCanvas onChange>` emits (and `toJSON()` produces).
1391
- *
1392
- * This is how a saved editable template re-enters the turnkey embed path:
1393
- * load the template's state JSON, lift it back into a `DesignBuilder`, and
1394
- * hand it to `<RealtimeEmbed design={…}>`. The active artboard becomes the
1395
- * builder's artboard; elements tagged for other artboards are skipped
1396
- * (untagged elements are assumed to belong to the active one).
1397
- */
1398
- static fromState(t) {
1399
- const r = t.artboards.find((n) => n.name === t.activeArtboard) ?? t.artboards[0];
1400
- if (!r)
1401
- throw new Error("DesignBuilder.fromState(): state has no artboards");
1402
- const o = new zt({
1403
- name: r.name,
1404
- width: r.width,
1405
- height: r.height,
1406
- backgroundColor: r.backgroundColor
1407
- });
1408
- for (const n of t.elements)
1409
- n.artboard && n.artboard !== r.name || o.els.push({ ...n });
1410
- return o;
1411
- }
1412
- nextId(t) {
1413
- return `${t}-${++this.idCounter}`;
1414
- }
1415
- /** Full-bleed background image (fills the whole artboard). Cover-fit (no
1416
- * distortion) when `aspectRatio` is supplied. Inserted at the bottom of the
1417
- * stack regardless of call order. */
1418
- background(t, r = {}) {
1419
- const { width: o, height: n } = this.artboard;
1420
- let a;
1421
- if (r.aspectRatio && r.aspectRatio > 0) {
1422
- const i = sn(r.aspectRatio, o, n);
1423
- a = {
1424
- type: "image",
1425
- width: i.width,
1426
- height: i.height,
1427
- cropX: i.cropX,
1428
- cropY: i.cropY,
1429
- cropWidth: i.cropWidth,
1430
- cropHeight: i.cropHeight,
1431
- flipHorizontal: !1,
1432
- flipVertical: !1,
1433
- borderRadius: 0
1434
- };
1435
- } else
1436
- a = {
1437
- type: "image",
1438
- width: o,
1439
- height: n,
1440
- cropX: 0,
1441
- cropY: 0,
1442
- cropWidth: 1,
1443
- cropHeight: 1,
1444
- flipHorizontal: !1,
1445
- flipVertical: !1,
1446
- borderRadius: 0
1447
- };
1448
- const s = {
1449
- id: this.nextId("bg"),
1450
- transformType: "image",
1451
- x: o / 2,
1452
- y: n / 2,
1453
- rotation: 0,
1454
- opacity: r.opacity ?? 1,
1455
- imageUrl: t,
1456
- imageAspectRatio: r.aspectRatio,
1457
- transformData: a,
1458
- name: r.name ?? "Background"
1459
- };
1460
- return this.els.unshift(s), this;
1461
- }
1462
- /** An anchored image element (not full-bleed). */
1463
- image(t, r = {}) {
1464
- const { width: o, height: n } = this.artboard, a = r.width ?? Math.round(o / 3), s = r.height ?? (r.aspectRatio ? Math.round(a / r.aspectRatio) : a), { x: i, y: c } = $t(r.anchor ?? de, a, s, o, n, r.padding ?? 0), d = {
1465
- id: this.nextId("img"),
1466
- transformType: "image",
1467
- x: i,
1468
- y: c,
1469
- rotation: r.rotation ?? 0,
1470
- opacity: r.opacity ?? 1,
1471
- imageUrl: t,
1472
- imageAspectRatio: r.aspectRatio,
1473
- transformData: {
1474
- type: "image",
1475
- width: a,
1476
- height: s,
1477
- cropX: 0,
1478
- cropY: 0,
1479
- cropWidth: 1,
1480
- cropHeight: 1,
1481
- flipHorizontal: !1,
1482
- flipVertical: !1,
1483
- borderRadius: 0
1484
- },
1485
- ...r.name ? { name: r.name } : {}
1486
- };
1487
- return this.els.push(d), this;
1488
- }
1489
- /** An anchored text layer. Horizontal centring is exact (textAlign); vertical
1490
- * anchoring uses the font size as the line-height estimate. */
1491
- text(t, r = {}) {
1492
- const { width: o, height: n } = this.artboard, a = r.fontSize ?? Math.round(this.artboard.height / 12), { x: s, y: i } = $t(r.anchor ?? "top", 0, a, o, n, r.padding ?? Math.round(n / 20)), c = {
1493
- id: this.nextId("text"),
1494
- transformType: "custom",
1495
- x: s,
1496
- y: i,
1497
- rotation: r.rotation ?? 0,
1498
- text: t,
1499
- fontSize: a,
1500
- fontFamily: r.fontFamily ?? "Anton",
1501
- color: r.color ?? "#ffffff",
1502
- textAlign: r.textAlign ?? "center",
1503
- bold: r.bold ?? !1,
1504
- italic: r.italic ?? !1,
1505
- transformData: { type: "custom" },
1506
- ...r.name ? { name: r.name } : {}
1507
- };
1508
- return this.els.push(c), this;
1509
- }
1510
- /** An anchored vector shape. */
1511
- shape(t, r = {}) {
1512
- const { width: o, height: n } = this.artboard, a = r.size ?? Math.round(o / 6), s = typeof a == "number" ? a : a.width, i = typeof a == "number" ? a : a.height, { x: c, y: d } = $t(r.anchor ?? de, s, i, o, n, r.padding ?? 0), x = {
1513
- type: "shape",
1514
- shapeType: t,
1515
- width: s,
1516
- height: i,
1517
- fillColor: r.fill ?? "#000000",
1518
- fillOpacity: r.opacity ?? 1,
1519
- ...r.points !== void 0 ? { points: r.points } : {},
1520
- ...r.sides !== void 0 ? { sides: r.sides } : {}
1521
- }, I = {
1522
- id: this.nextId("shape"),
1523
- transformType: "shape",
1524
- x: c,
1525
- y: d,
1526
- rotation: r.rotation ?? 0,
1527
- transformData: x,
1528
- ...r.name ? { name: r.name } : {}
1529
- };
1530
- return this.els.push(I), this;
1531
- }
1532
- /** The composed elements, in render order (background first). Editor shape. */
1533
- get elements() {
1534
- return this.els.map((t) => ({ ...t }));
1535
- }
1536
- /** Editor-shape canvas state for `<SnowconeCanvas initialElements=… />` and
1537
- * `serializeStateForServer`. `activeArtboard` is the artboard name. */
1538
- toJSON() {
1539
- return {
1540
- elements: this.elements,
1541
- artboards: [{
1542
- name: this.artboard.name,
1543
- width: this.artboard.width,
1544
- height: this.artboard.height,
1545
- // A background set on a design is part of the design: flag it
1546
- // renderable so exports and server renders paint it, matching the
1547
- // editor (the export worker skips it without `exportBackground`).
1548
- ...this.artboard.backgroundColor ? {
1549
- backgroundColor: this.artboard.backgroundColor,
1550
- exportBackground: this.artboard.backgroundColor !== "transparent"
1551
- } : {}
1552
- }],
1553
- activeArtboard: this.artboard.name
1554
- };
1555
- }
1556
- /** Server-render payload for `RenderSession.renderState(placement, …)`.
1557
- * Equivalent to `serializeStateForServer(design.toJSON())`. */
1558
- toServerRequest() {
1559
- return en(this.toJSON());
1560
- }
1561
- }
1562
- function En(e) {
1563
- return new zt(e);
1564
- }
1565
- const ye = "personalization", cn = pr("type", [
1566
- ct({
1567
- type: Y("text"),
1568
- name: $().min(1),
1569
- label: $(),
1570
- placeholder: $().optional(),
1571
- maxLength: br().int().positive().optional(),
1572
- group: $().optional()
1573
- }),
1574
- ct({
1575
- type: Y("image"),
1576
- name: $().min(1),
1577
- label: $(),
1578
- placeholder: $().optional(),
1579
- fit: ae([Y("cover"), Y("contain")]).optional(),
1580
- group: $().optional()
1581
- }),
1582
- ct({
1583
- type: Y("color"),
1584
- color: $().min(1),
1585
- label: $(),
1586
- group: $().optional()
1587
- }),
1588
- ct({
1589
- type: Y("select"),
1590
- name: $().min(1),
1591
- label: $(),
1592
- property: ae([Y("text"), Y("imageUrl"), Y("fontFamily")]),
1593
- options: yr(ct({ label: $(), value: $() })).min(1),
1594
- group: $().optional()
1595
- })
1596
- ]);
1597
- function An(e) {
1598
- if (!e || typeof e != "object") return [];
1599
- const t = e[ye];
1600
- if (!Array.isArray(t)) return [];
1601
- const r = [];
1602
- for (const o of t) {
1603
- if (!o || typeof o != "object") continue;
1604
- const n = "type" in o ? o : { ...o, type: "text" }, a = cn.safeParse(n);
1605
- a.success && r.push(a.data);
1606
- }
1607
- return r;
1608
- }
1609
- function kn(e, t) {
1610
- return { ...e, [ye]: t };
1611
- }
1612
- export {
1613
- tn as C,
1614
- zt as D,
1615
- kr as E,
1616
- zr as S,
1617
- ye as T,
1618
- xn as a,
1619
- xr as b,
1620
- Mr as c,
1621
- En as d,
1622
- wn as e,
1623
- vn as f,
1624
- yn as g,
1625
- pn as h,
1626
- bn as i,
1627
- An as r,
1628
- en as s,
1629
- Rr as u,
1630
- kn as w
1631
- };
1632
- //# sourceMappingURL=template-fields-coO73lV3.js.map