@scaleflex/crop 2.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 (63) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +452 -0
  3. package/dist/a11y/aria.d.ts +5 -0
  4. package/dist/a11y/keyboard.d.ts +13 -0
  5. package/dist/animation/lerp.d.ts +15 -0
  6. package/dist/animation/spring.d.ts +15 -0
  7. package/dist/canvas/bleed-layer.d.ts +6 -0
  8. package/dist/canvas/crop-frame.d.ts +32 -0
  9. package/dist/canvas/grid-layer.d.ts +7 -0
  10. package/dist/canvas/hit-test.d.ts +10 -0
  11. package/dist/canvas/image-layer.d.ts +28 -0
  12. package/dist/canvas/overlay-layer.d.ts +6 -0
  13. package/dist/canvas/renderer.d.ts +34 -0
  14. package/dist/chunks/sfx-crop-1LGASewd.cjs +353 -0
  15. package/dist/chunks/sfx-crop-CEe6OfTZ.js +2030 -0
  16. package/dist/core/config.d.ts +10 -0
  17. package/dist/core/crop-controller.d.ts +65 -0
  18. package/dist/core/types.d.ts +270 -0
  19. package/dist/define.cjs +1194 -0
  20. package/dist/define.d.ts +1 -0
  21. package/dist/define.js +1746 -0
  22. package/dist/elements/base.d.ts +17 -0
  23. package/dist/elements/icons.d.ts +21 -0
  24. package/dist/elements/parse-shapes.d.ts +13 -0
  25. package/dist/elements/popover-anchor.d.ts +20 -0
  26. package/dist/elements/sfx-crop-canvas.d.ts +24 -0
  27. package/dist/elements/sfx-crop-canvas.styles.d.ts +1 -0
  28. package/dist/elements/sfx-crop-rotate.d.ts +42 -0
  29. package/dist/elements/sfx-crop-rotate.styles.d.ts +5 -0
  30. package/dist/elements/sfx-crop-shapes.d.ts +67 -0
  31. package/dist/elements/sfx-crop-shapes.styles.d.ts +6 -0
  32. package/dist/elements/sfx-crop-toolbar.d.ts +64 -0
  33. package/dist/elements/sfx-crop-toolbar.styles.d.ts +7 -0
  34. package/dist/elements/sfx-crop-zoom.d.ts +66 -0
  35. package/dist/elements/sfx-crop-zoom.styles.d.ts +7 -0
  36. package/dist/elements/sfx-crop.d.ts +134 -0
  37. package/dist/elements/sfx-crop.styles.d.ts +9 -0
  38. package/dist/export/exporter.d.ts +19 -0
  39. package/dist/index.cjs +2 -0
  40. package/dist/index.d.ts +22 -0
  41. package/dist/index.js +65 -0
  42. package/dist/interactions/drag-crop.d.ts +10 -0
  43. package/dist/interactions/pinch-zoom.d.ts +14 -0
  44. package/dist/interactions/pointer-tracker.d.ts +29 -0
  45. package/dist/interactions/resize-handles.d.ts +13 -0
  46. package/dist/interactions/wheel-zoom.d.ts +12 -0
  47. package/dist/react/define-CVJd5aYk.cjs +1545 -0
  48. package/dist/react/define-t4Z6KaLY.js +2590 -0
  49. package/dist/react/index-B-csHwK2.cjs +2 -0
  50. package/dist/react/index-CktjrogS.js +1468 -0
  51. package/dist/react/index.cjs +2 -0
  52. package/dist/react/index.d.ts +21 -0
  53. package/dist/react/index.js +10 -0
  54. package/dist/react/sfx-crop.d.ts +86 -0
  55. package/dist/react/use-sfx-crop-controller.d.ts +74 -0
  56. package/dist/react/use-sfx-crop.d.ts +31 -0
  57. package/dist/styles/shared.css.d.ts +20 -0
  58. package/dist/transforms/constrain.d.ts +68 -0
  59. package/dist/transforms/matrix.d.ts +23 -0
  60. package/dist/transforms/transform-state.d.ts +12 -0
  61. package/dist/utils/events.d.ts +16 -0
  62. package/dist/utils/math.d.ts +12 -0
  63. package/package.json +108 -0
@@ -0,0 +1,2030 @@
1
+ import { LitElement as $t, css as Z, html as vt } from "lit";
2
+ import { query as pt, property as E, state as Lt } from "lit/decorators.js";
3
+ import { classMap as Ht } from "lit/directives/class-map.js";
4
+ const _e = 80, Zt = {
5
+ src: "",
6
+ variant: "classic",
7
+ cropShape: "16:9",
8
+ initialCrop: null,
9
+ initialRotation: 0,
10
+ initialScale: 1,
11
+ customAspectRatios: [],
12
+ minCropSize: 20,
13
+ availableShapes: [
14
+ "free",
15
+ "square",
16
+ "16:9",
17
+ "4:3",
18
+ "3:2",
19
+ "5:4",
20
+ "2:1",
21
+ "9:16",
22
+ "3:4",
23
+ "2:3",
24
+ "4:5",
25
+ "1:2"
26
+ ],
27
+ minScale: 0.5,
28
+ maxScale: 5,
29
+ theme: "light",
30
+ showGrid: "interaction",
31
+ showRotateSlider: !0,
32
+ showZoomSlider: !0,
33
+ showShapeSelector: !0,
34
+ showRotateButton: !0,
35
+ showFlipButton: !0,
36
+ toolbarPosition: "top",
37
+ showToolbar: !0,
38
+ overlayColor: "rgba(0, 0, 0, 0.55)",
39
+ handleSize: 12,
40
+ handleColor: "#ffffff",
41
+ borderRadius: 20,
42
+ outputType: "image/png",
43
+ outputQuality: 0.92,
44
+ maxOutputWidth: 0,
45
+ maxOutputHeight: 0,
46
+ showBleedMargin: !1,
47
+ bleedMarginSize: 10,
48
+ bleedMarginColor: "rgba(255, 0, 0, 0.5)",
49
+ enableAnimations: !0,
50
+ animationSpeed: 1,
51
+ keyboard: !0,
52
+ pinchZoom: !0,
53
+ wheelZoom: !0
54
+ };
55
+ function zt(t) {
56
+ return { ...Zt, ...t };
57
+ }
58
+ function X(t, e, o) {
59
+ return Math.min(Math.max(t, e), o);
60
+ }
61
+ function $(t, e, o) {
62
+ return t + (e - t) * o;
63
+ }
64
+ function lt(t) {
65
+ return t * Math.PI / 180;
66
+ }
67
+ function Ut(t, e, o, i) {
68
+ const n = o - t, r = i - e;
69
+ return Math.sqrt(n * n + r * r);
70
+ }
71
+ function Yt(t) {
72
+ const e = /^(\d+(?:\.\d+)?):(\d+(?:\.\d+)?)$/.exec(t.trim());
73
+ if (!e) return null;
74
+ const o = Number(e[1]), i = Number(e[2]);
75
+ return !Number.isFinite(o) || !Number.isFinite(i) || o <= 0 || i <= 0 ? null : o / i;
76
+ }
77
+ function ft(t) {
78
+ switch (t) {
79
+ case "free":
80
+ return null;
81
+ case "rounded-rect":
82
+ return null;
83
+ case "square":
84
+ case "circle":
85
+ return 1;
86
+ // Everything else — `"16:9"`, `"4:3"`, `"7:2"`, `"2.35:1"` — goes
87
+ // through `parseRatio`. The switch intentionally doesn't enumerate
88
+ // the named ratios so the library stays a parser, not a catalog.
89
+ default:
90
+ return Yt(t);
91
+ }
92
+ }
93
+ function Gt(t, e, o, i, n, r) {
94
+ if (e === null)
95
+ return jt(t, r, i, n);
96
+ const u = i / n, l = e / u;
97
+ let { x: a, y: c, width: p, height: y } = t;
98
+ const m = o.includes("e") || o.includes("w"), d = o.includes("n") || o.includes("s");
99
+ m && !d ? y = p / l : d && !m ? p = y * l : y = p / l;
100
+ const s = t.x + t.width, f = t.y + t.height, x = t.x + t.width / 2, S = t.y + t.height / 2;
101
+ let v;
102
+ o.includes("w") ? v = s : o.includes("e") ? v = 1 - t.x : v = 2 * Math.min(x, 1 - x);
103
+ let b;
104
+ o.includes("n") ? b = f : o.includes("s") ? b = 1 - t.y : b = 2 * Math.min(S, 1 - S);
105
+ const k = Math.min(1, v / p, b / y);
106
+ k < 1 && (p *= k, y *= k);
107
+ const I = r / i, q = r / n;
108
+ return p < I && (p = I, y = p / l), y < q && (y = q, p = y * l), o.includes("w") ? a = s - p : o.includes("e") ? a = t.x : a = x - p / 2, o.includes("n") ? c = f - y : o.includes("s") ? c = t.y : c = S - y / 2, a = X(a, 0, 1 - p), c = X(c, 0, 1 - y), { x: a, y: c, width: p, height: y };
109
+ }
110
+ function jt(t, e, o, i) {
111
+ const n = e / o, r = e / i;
112
+ return {
113
+ ...t,
114
+ width: Math.max(t.width, n),
115
+ height: Math.max(t.height, r)
116
+ };
117
+ }
118
+ function Qt(t, e, o, i, n, r, u) {
119
+ const l = t.rotation * Math.PI / 180, a = Math.abs(Math.cos(l)), c = Math.abs(Math.sin(l)), p = i.width * a + i.height * c, y = i.width * c + i.height * a, m = Math.max(p / n, y / r), d = Math.min(m, u), s = X(t.scale, d, u), f = e / 2 - (i.x + i.width / 2), x = o / 2 - (i.y + i.height / 2), S = Math.max(0, (n * s - p) / 2), v = Math.max(0, (r * s - y) / 2);
120
+ return {
121
+ scale: s,
122
+ panX: X(t.panX, (-S - f) / s, (S - f) / s),
123
+ panY: X(t.panY, (-v - x) / s, (v - x) / s),
124
+ minScale: d
125
+ };
126
+ }
127
+ const _ = 0.8;
128
+ function Ot(t, e, o) {
129
+ return !e || !o ? t : t / (e / o);
130
+ }
131
+ function Pt(t = "free", e = 1, o = 1) {
132
+ const i = ft(t);
133
+ let n;
134
+ if (i !== null) {
135
+ const r = Ot(i, e, o);
136
+ let u, l;
137
+ r >= 1 ? (u = _, l = u / r, l > _ && (l = _, u = l * r)) : (l = _, u = l * r, u > _ && (u = _, l = u / r)), n = {
138
+ x: (1 - u) / 2,
139
+ y: (1 - l) / 2,
140
+ width: u,
141
+ height: l
142
+ };
143
+ } else {
144
+ const r = _;
145
+ n = { x: (1 - r) / 2, y: (1 - r) / 2, width: r, height: r };
146
+ }
147
+ return {
148
+ quarterTurns: 0,
149
+ rotation: 0,
150
+ flipH: !1,
151
+ flipV: !1,
152
+ scale: 1,
153
+ panX: 0,
154
+ panY: 0,
155
+ cropRect: n
156
+ };
157
+ }
158
+ function Jt(t) {
159
+ const e = t.quarterTurns - 90;
160
+ return {
161
+ ...t,
162
+ quarterTurns: e,
163
+ panX: 0,
164
+ panY: 0
165
+ };
166
+ }
167
+ function te(t) {
168
+ return { ...t, flipH: !t.flipH };
169
+ }
170
+ function mt(t, e) {
171
+ const o = X(e, -45, 45);
172
+ let i = t.rotationPivot;
173
+ if (o === 0)
174
+ i = void 0;
175
+ else if (!i) {
176
+ const n = t.cropRect;
177
+ i = { x: n.x + n.width / 2, y: n.y + n.height / 2 };
178
+ }
179
+ return { ...t, rotation: o, rotationPivot: i };
180
+ }
181
+ function ot(t, e, o, i) {
182
+ return {
183
+ ...t,
184
+ scale: X(e, o, i)
185
+ };
186
+ }
187
+ function et(t, e) {
188
+ return {
189
+ ...t,
190
+ cropRect: {
191
+ x: X(e.x, 0, 1 - e.width),
192
+ y: X(e.y, 0, 1 - e.height),
193
+ width: X(e.width, 0, 1),
194
+ height: X(e.height, 0, 1)
195
+ }
196
+ };
197
+ }
198
+ function gt(t, e, o = 1, i = 1) {
199
+ const n = ft(e);
200
+ let r;
201
+ if (n === null)
202
+ r = { ...t.cropRect };
203
+ else {
204
+ const u = Ot(n, o, i), { cropRect: l } = t, a = l.x + l.width / 2, c = l.y + l.height / 2;
205
+ let p, y;
206
+ u >= 1 ? (p = _, y = p / u, y > _ && (y = _, p = y * u)) : (y = _, p = y * u, p > _ && (p = _, y = p / u)), r = {
207
+ x: X(a - p / 2, 0, 1 - p),
208
+ y: X(c - y / 2, 0, 1 - y),
209
+ width: p,
210
+ height: y
211
+ };
212
+ }
213
+ return {
214
+ ...t,
215
+ cropRect: r
216
+ };
217
+ }
218
+ function Et(t, e, o) {
219
+ return {
220
+ ...t,
221
+ panX: t.panX + e,
222
+ panY: t.panY + o
223
+ };
224
+ }
225
+ function ct(t, e, o, i, n) {
226
+ const r = Math.round(n / 90) % 2 !== 0, u = r ? e : t, l = r ? t : e, a = Math.max(u / o, l / i);
227
+ return { drawW: o * a, drawH: i * a };
228
+ }
229
+ function ee(t, e, o, i, n = !1) {
230
+ const { x: r, y: u, w: l, h: a } = o, c = r + l / 2, p = u + a / 2;
231
+ t.save();
232
+ const y = r + (i.cropRect.x + i.cropRect.width / 2) * l, m = u + (i.cropRect.y + i.cropRect.height / 2) * a, d = i.rotationPivot ?? {
233
+ x: i.cropRect.x + i.cropRect.width / 2,
234
+ y: i.cropRect.y + i.cropRect.height / 2
235
+ }, s = r + d.x * l, f = u + d.y * a;
236
+ i.rotation !== 0 && (t.translate(s, f), t.rotate(lt(i.rotation)), t.translate(-s, -f)), (i.flipH !== 1 || i.flipV !== 1) && (t.translate(y, m), t.scale(i.flipH, i.flipV), t.translate(-y, -m)), t.translate(c, p), t.scale(i.scale, i.scale), t.translate(i.panX, i.panY), i.quarterTurns !== 0 && t.rotate(lt(i.quarterTurns));
237
+ let x, S;
238
+ if (n) {
239
+ const v = ct(l, a, e.naturalWidth, e.naturalHeight, i.quarterTurns);
240
+ x = v.drawW, S = v.drawH;
241
+ } else {
242
+ const b = Math.round(i.quarterTurns / 90) % 2 !== 0 ? Math.min(l, a) / Math.max(l, a) : 1;
243
+ x = l * b, S = a * b;
244
+ }
245
+ t.drawImage(e, -x / 2, -S / 2, x, S), t.restore();
246
+ }
247
+ let j = null;
248
+ function re(t, e) {
249
+ j || (j = document.createElement("canvas")), (j.width !== t || j.height !== e) && (j.width = t, j.height = e);
250
+ const o = j.getContext("2d");
251
+ return o.clearRect(0, 0, t, e), o;
252
+ }
253
+ function oe(t, e, o, i, n = "rect", r = 20, u = "rgba(0, 0, 0, 0.55)") {
254
+ const l = re(e, o);
255
+ if (l.fillStyle = u, l.fillRect(0, 0, e, o), l.globalCompositeOperation = "destination-out", l.fillStyle = "rgba(0, 0, 0, 1)", n === "circle") {
256
+ const a = i.x + i.width / 2, c = i.y + i.height / 2, p = i.width / 2, y = i.height / 2;
257
+ l.beginPath(), l.ellipse(a, c, p, y, 0, 0, Math.PI * 2), l.fill();
258
+ } else if (n === "rounded-rect") {
259
+ const { x: a, y: c, width: p, height: y } = i, m = Math.min(r, p / 2, y / 2);
260
+ l.beginPath(), l.moveTo(a + m, c), l.lineTo(a + p - m, c), l.arcTo(a + p, c, a + p, c + m, m), l.lineTo(a + p, c + y - m), l.arcTo(a + p, c + y, a + p - m, c + y, m), l.lineTo(a + m, c + y), l.arcTo(a, c + y, a, c + y - m, m), l.lineTo(a, c + m), l.arcTo(a, c, a + m, c, m), l.closePath(), l.fill();
261
+ } else
262
+ l.fillRect(i.x, i.y, i.width, i.height);
263
+ l.globalCompositeOperation = "source-over", t.drawImage(j, 0, 0);
264
+ }
265
+ const ie = 12, ne = 22, ht = 11, st = 9, ae = {
266
+ frame: "#ffffff",
267
+ frameShadow: "rgba(0, 0, 0, 0.3)",
268
+ handleFill: "#ffffff",
269
+ handleStroke: "rgba(0, 0, 0, 0.25)"
270
+ };
271
+ function se(t, e, o = "rect", i = 20, n = ae, r = !0) {
272
+ const u = o === "circle", l = o === "rounded-rect", { x: a, y: c, width: p, height: y } = e;
273
+ if (t.save(), t.strokeStyle = n.frameShadow, t.lineWidth = 1, u) {
274
+ const x = a + p / 2, S = c + y / 2, v = p / 2 - 1, b = y / 2 - 1;
275
+ t.beginPath(), t.ellipse(x, S, v, b, 0, 0, Math.PI * 2), t.stroke();
276
+ } else l ? (It(t, a + 1, c + 1, p - 2, y - 2, Math.min(i, p / 2, y / 2)), t.stroke()) : t.strokeRect(a + 1, c + 1, p - 2, y - 2);
277
+ if (t.strokeStyle = n.frame, t.lineWidth = 2, u) {
278
+ const x = a + p / 2, S = c + y / 2, v = p / 2, b = y / 2;
279
+ t.beginPath(), t.ellipse(x, S, v, b, 0, 0, Math.PI * 2), t.stroke(), t.setLineDash([4, 4]), t.strokeStyle = n.frameShadow, t.lineWidth = 1, t.beginPath(), t.ellipse(x, S, v - 1, b - 1, 0, 0, Math.PI * 2), t.stroke(), t.setLineDash([]);
280
+ } else if (l) {
281
+ const x = Math.min(i, p / 2, y / 2);
282
+ It(t, a, c, p, y, x), t.stroke();
283
+ } else
284
+ t.strokeRect(a, c, p, y);
285
+ if (!r) {
286
+ t.restore();
287
+ return;
288
+ }
289
+ t.fillStyle = n.handleFill, t.strokeStyle = n.handleStroke, t.lineWidth = 1;
290
+ const m = Math.min(ie / 2, p / 6, y / 6), d = [
291
+ { cx: a, cy: c },
292
+ { cx: a + p, cy: c },
293
+ { cx: a + p, cy: c + y },
294
+ { cx: a, cy: c + y }
295
+ ];
296
+ for (const x of d)
297
+ t.beginPath(), t.arc(x.cx, x.cy, m, 0, Math.PI * 2), t.fill(), t.stroke();
298
+ const s = a - ht, f = c - ht;
299
+ t.beginPath(), t.arc(s, f, m, 0, Math.PI * 2), t.fill(), t.stroke(), t.fillStyle = n.handleStroke, t.beginPath(), t.arc(s, f, Math.max(2, m * 0.35), 0, Math.PI * 2), t.fill(), t.restore();
300
+ }
301
+ function It(t, e, o, i, n, r) {
302
+ r = Math.min(r, i / 2, n / 2), t.beginPath(), t.moveTo(e + r, o), t.lineTo(e + i - r, o), t.arcTo(e + i, o, e + i, o + r, r), t.lineTo(e + i, o + n - r), t.arcTo(e + i, o + n, e + i - r, o + n, r), t.lineTo(e + r, o + n), t.arcTo(e, o + n, e, o + n - r, r), t.lineTo(e, o + r), t.arcTo(e, o, e + r, o, r), t.closePath();
303
+ }
304
+ function le(t) {
305
+ const { x: e, y: o, width: i, height: n } = t, r = ne;
306
+ return [
307
+ // Move-handle (NW diagonal) — checked first so it wins over the NW
308
+ // corner's hit area where they overlap.
309
+ {
310
+ target: "move-handle",
311
+ rect: {
312
+ x: e - ht - st,
313
+ y: o - ht - st,
314
+ w: st * 2,
315
+ h: st * 2
316
+ }
317
+ },
318
+ // Corner handles (highest priority — checked first)
319
+ { target: "handle-nw", rect: { x: e - r, y: o - r, w: r * 2, h: r * 2 } },
320
+ { target: "handle-ne", rect: { x: e + i - r, y: o - r, w: r * 2, h: r * 2 } },
321
+ { target: "handle-se", rect: { x: e + i - r, y: o + n - r, w: r * 2, h: r * 2 } },
322
+ { target: "handle-sw", rect: { x: e - r, y: o + n - r, w: r * 2, h: r * 2 } },
323
+ // Edge hit zones (no visual handle, but cursor + resize still work)
324
+ { target: "handle-n", rect: { x: e + r, y: o - r, w: i - r * 2, h: r * 2 } },
325
+ { target: "handle-s", rect: { x: e + r, y: o + n - r, w: i - r * 2, h: r * 2 } },
326
+ { target: "handle-e", rect: { x: e + i - r, y: o + r, w: r * 2, h: n - r * 2 } },
327
+ { target: "handle-w", rect: { x: e - r, y: o + r, w: r * 2, h: n - r * 2 } }
328
+ ];
329
+ }
330
+ function ce(t, e, o) {
331
+ const { x: i, y: n, width: r, height: u } = e;
332
+ t.save(), t.strokeStyle = `rgba(255, 255, 255, ${0.35 * o})`, t.lineWidth = 0.5;
333
+ for (let l = 1; l <= 2; l++) {
334
+ const a = i + r * l / 3;
335
+ t.beginPath(), t.moveTo(a, n), t.lineTo(a, n + u), t.stroke();
336
+ }
337
+ for (let l = 1; l <= 2; l++) {
338
+ const a = n + u * l / 3;
339
+ t.beginPath(), t.moveTo(i, a), t.lineTo(i + r, a), t.stroke();
340
+ }
341
+ t.restore();
342
+ }
343
+ function he(t, e, o, i) {
344
+ o * 2 >= e.width || o * 2 >= e.height || (t.save(), t.strokeStyle = i, t.lineWidth = 1, t.setLineDash([6, 4]), t.strokeRect(
345
+ e.x + o,
346
+ e.y + o,
347
+ e.width - o * 2,
348
+ e.height - o * 2
349
+ ), t.setLineDash([]), t.restore());
350
+ }
351
+ function ue(t, e, o, i = 20, n = !1, r) {
352
+ const u = t.getContext("2d");
353
+ if (!u) throw new Error("2D canvas context unavailable");
354
+ const l = u;
355
+ function a() {
356
+ if (r) return r;
357
+ if (t.parentElement) return t.parentElement;
358
+ let w = t.getRootNode();
359
+ for (; w && w !== document && w instanceof ShadowRoot; ) {
360
+ const H = w.host;
361
+ if (H instanceof HTMLElement) return H;
362
+ w = H.getRootNode();
363
+ }
364
+ return null;
365
+ }
366
+ let c = !0, p = null, y = !1, m = !1, d = 0;
367
+ const s = {
368
+ quarterTurns: 0,
369
+ rotation: 0,
370
+ flipH: 1,
371
+ flipV: 1,
372
+ scale: 1,
373
+ panX: 0,
374
+ panY: 0,
375
+ cropRect: { x: 0, y: 0, width: 1, height: 1 },
376
+ gridOpacity: 0,
377
+ interactive: !1
378
+ }, f = { ...s }, x = {
379
+ quarterTurns: 0,
380
+ flipH: 0,
381
+ flipV: 0
382
+ };
383
+ let S = { show: !1, size: 10, color: "rgba(255, 0, 0, 0.5)" }, v = 0, b = 0.5, k = 5, I = !1;
384
+ function q() {
385
+ if (y) return;
386
+ const w = a();
387
+ if (!w) return;
388
+ const H = window.devicePixelRatio, A = Math.min(Number.isFinite(H) && H > 0 ? H : 1, 2), O = w.getBoundingClientRect();
389
+ O.width <= 0 || O.height <= 0 || (t.width = Math.max(0, Math.floor(O.width * A)), t.height = Math.max(0, Math.floor(O.height * A)), t.style.width = `${O.width}px`, t.style.height = `${O.height}px`, l.setTransform(A, 0, 0, A, 0, 0), c = !0);
390
+ }
391
+ function N() {
392
+ const w = a();
393
+ return w ? { x: 0, y: 0, w: w.clientWidth, h: w.clientHeight } : { x: 0, y: 0, w: 0, h: 0 };
394
+ }
395
+ function Y() {
396
+ const w = N(), H = s.cropRect;
397
+ return {
398
+ x: w.x + H.x * w.w,
399
+ y: w.y + H.y * w.h,
400
+ width: H.width * w.w,
401
+ height: H.height * w.h
402
+ };
403
+ }
404
+ function U(w, H) {
405
+ return 1 - Math.pow(1 - w, H * 60);
406
+ }
407
+ function Q(w) {
408
+ if (n) {
409
+ s.quarterTurns = f.quarterTurns, s.rotation = f.rotation, s.flipH = f.flipH, s.flipV = f.flipV, s.scale = f.scale, s.panX = f.panX, s.panY = f.panY, s.cropRect = { ...f.cropRect }, s.gridOpacity = f.gridOpacity, s.interactive = f.interactive, c = !0;
410
+ return;
411
+ }
412
+ let H = !1;
413
+ if (Math.abs(s.quarterTurns - f.quarterTurns) > 0.01) {
414
+ const T = -180 * (s.quarterTurns - f.quarterTurns), B = -22 * x.quarterTurns;
415
+ x.quarterTurns += (T + B) * w, s.quarterTurns += x.quarterTurns * w, Math.abs(s.quarterTurns - f.quarterTurns) < 0.01 && Math.abs(x.quarterTurns) < 0.01 && (s.quarterTurns = f.quarterTurns, x.quarterTurns = 0), H = !0, c = !0;
416
+ }
417
+ if (Math.abs(s.flipH - f.flipH) > 0.01) {
418
+ const T = -400 * (s.flipH - f.flipH), B = -28 * x.flipH;
419
+ x.flipH += (T + B) * w, s.flipH += x.flipH * w, Math.abs(s.flipH - f.flipH) < 0.01 && Math.abs(x.flipH) < 0.01 && (s.flipH = f.flipH, x.flipH = 0), H = !0, c = !0;
420
+ }
421
+ if (Math.abs(s.flipV - f.flipV) > 0.01) {
422
+ const T = -400 * (s.flipV - f.flipV), B = -28 * x.flipV;
423
+ x.flipV += (T + B) * w, s.flipV += x.flipV * w, Math.abs(s.flipV - f.flipV) < 0.01 && Math.abs(x.flipV) < 0.01 && (s.flipV = f.flipV, x.flipV = 0), H = !0, c = !0;
424
+ }
425
+ const A = U(0.15, w), O = U(0.12, w), V = U(0.12, w);
426
+ if (Math.abs(s.rotation - f.rotation) > 0.01 && (s.rotation = $(s.rotation, f.rotation, A), H = !0, c = !0), Math.abs(s.scale - f.scale) > 1e-3 && (s.scale = $(s.scale, f.scale, A), H = !0, c = !0), !!f.interactive) {
427
+ (s.panX !== f.panX || s.panY !== f.panY) && (s.panX = f.panX, s.panY = f.panY, c = !0);
428
+ const P = f.cropRect, T = s.cropRect;
429
+ (T.x !== P.x || T.y !== P.y || T.width !== P.width || T.height !== P.height) && (s.cropRect = { ...P }, c = !0);
430
+ } else {
431
+ Math.abs(s.panX - f.panX) > 0.1 && (s.panX = $(s.panX, f.panX, A), H = !0, c = !0), Math.abs(s.panY - f.panY) > 0.1 && (s.panY = $(s.panY, f.panY, A), H = !0, c = !0);
432
+ const P = s.cropRect, T = f.cropRect;
433
+ (Math.abs(P.x - T.x) > 1e-4 || Math.abs(P.y - T.y) > 1e-4 || Math.abs(P.width - T.width) > 1e-4 || Math.abs(P.height - T.height) > 1e-4) && (s.cropRect = {
434
+ x: $(P.x, T.x, O),
435
+ y: $(P.y, T.y, O),
436
+ width: $(P.width, T.width, O),
437
+ height: $(P.height, T.height, O)
438
+ }, H = !0, c = !0);
439
+ }
440
+ if (Math.abs(s.gridOpacity - f.gridOpacity) > 0.01 && (s.gridOpacity = $(s.gridOpacity, f.gridOpacity, V), H = !0, c = !0), s.scale < b) {
441
+ const T = -400 * (s.scale - b), B = -28 * v;
442
+ v += (T + B) * w, s.scale += v * w, Math.abs(s.scale - b) < 1e-3 && Math.abs(v) < 1e-3 && (s.scale = b, v = 0), H = !0, c = !0;
443
+ } else if (s.scale > k) {
444
+ const T = -400 * (s.scale - k), B = -28 * v;
445
+ v += (T + B) * w, s.scale += v * w, Math.abs(s.scale - k) < 1e-3 && Math.abs(v) < 1e-3 && (s.scale = k, v = 0), H = !0, c = !0;
446
+ }
447
+ H || (s.rotation = f.rotation, s.scale = f.scale, s.panX = f.panX, s.panY = f.panY, s.cropRect = { ...f.cropRect }, s.gridOpacity = f.gridOpacity, s.interactive = f.interactive);
448
+ }
449
+ function G(w) {
450
+ if (y || !m) {
451
+ p = null;
452
+ return;
453
+ }
454
+ const H = typeof w == "number" ? w : performance.now(), A = d === 0 ? 1 / 60 : Math.min(0.25, Math.max(0, (H - d) / 1e3));
455
+ if (d = H, p = requestAnimationFrame(G), Q(A), !c) return;
456
+ const O = a();
457
+ if (!O) return;
458
+ const V = O.clientWidth, D = O.clientHeight;
459
+ if (V === 0 || D === 0) return;
460
+ c = !1, l.clearRect(0, 0, V, D);
461
+ const P = N();
462
+ ee(l, e, P, s, I);
463
+ const T = Y(), B = o(), dt = a() ?? t, J = (tt, at) => getComputedStyle(dt).getPropertyValue(tt).trim() || at;
464
+ if (!(I && B === "rect")) {
465
+ const tt = J("--sfx-cr-overlay-color", "rgba(0, 0, 0, 0.55)");
466
+ oe(l, V, D, T, B, i, tt);
467
+ }
468
+ I && B === "rect" || se(l, T, B, i, {
469
+ frame: J("--sfx-cr-frame-color", "#ffffff"),
470
+ frameShadow: J("--sfx-cr-frame-shadow", "rgba(0, 0, 0, 0.3)"),
471
+ handleFill: J("--sfx-cr-handle-fill", "#ffffff"),
472
+ handleStroke: J("--sfx-cr-handle-stroke", "rgba(0, 0, 0, 0.25)")
473
+ }, !I), S.show && he(l, T, S.size, S.color), s.gridOpacity > 0.01 && ce(l, T, s.gridOpacity);
474
+ }
475
+ return q(), {
476
+ markDirty() {
477
+ c = !0;
478
+ },
479
+ startLoop() {
480
+ m || y || (m = !0, d = 0, G());
481
+ },
482
+ stopLoop() {
483
+ m = !1, p !== null && (cancelAnimationFrame(p), p = null);
484
+ },
485
+ setDisplayState(w) {
486
+ Object.assign(f, w), s.rotationPivot = w.rotationPivot, c = !0;
487
+ },
488
+ getDisplayState() {
489
+ return { ...s };
490
+ },
491
+ getCanvasCropRect: Y,
492
+ setScaleBounds(w, H) {
493
+ b = w, k = H;
494
+ },
495
+ setBleedConfig(w) {
496
+ S = w, c = !0;
497
+ },
498
+ setFixedFrame(w) {
499
+ I = w, c = !0;
500
+ },
501
+ resize: q,
502
+ destroy() {
503
+ y = !0, m = !1, p !== null && (cancelAnimationFrame(p), p = null);
504
+ }
505
+ };
506
+ }
507
+ const pe = [
508
+ "nw",
509
+ "ne",
510
+ "sw",
511
+ "se",
512
+ "n",
513
+ "s",
514
+ "e",
515
+ "w"
516
+ ];
517
+ function fe(t) {
518
+ return pe.includes(t) ? t : null;
519
+ }
520
+ function de(t, e, o) {
521
+ return t >= o.x && t <= o.x + o.w && e >= o.y && e <= o.y + o.h;
522
+ }
523
+ function xt(t, e, o) {
524
+ const i = le(o);
525
+ for (const { target: n, rect: r } of i)
526
+ if (de(t, e, r)) {
527
+ if (n === "move-handle") return { type: "move-handle" };
528
+ const u = fe(n.replace("handle-", ""));
529
+ if (u) return { type: "handle", position: u };
530
+ }
531
+ return t >= o.x && t <= o.x + o.width && e >= o.y && e <= o.y + o.height ? { type: "crop-area" } : { type: "outside" };
532
+ }
533
+ function Dt(t, e) {
534
+ if (t.type === "move-handle") return "move";
535
+ switch (t.type) {
536
+ case "crop-area":
537
+ return "move";
538
+ case "outside":
539
+ return "crosshair";
540
+ case "handle":
541
+ switch (t.position) {
542
+ case "nw":
543
+ case "se":
544
+ return "nwse-resize";
545
+ case "ne":
546
+ case "sw":
547
+ return "nesw-resize";
548
+ case "n":
549
+ case "s":
550
+ return "ns-resize";
551
+ case "e":
552
+ case "w":
553
+ return "ew-resize";
554
+ default:
555
+ return "default";
556
+ }
557
+ default:
558
+ return "default";
559
+ }
560
+ }
561
+ function ye(t, e) {
562
+ const o = /* @__PURE__ */ new Map();
563
+ let i = 0, n = !1;
564
+ function r(d) {
565
+ return d === "touch" || d === "pen" ? d : "mouse";
566
+ }
567
+ function u(d) {
568
+ const s = t.getBoundingClientRect();
569
+ return {
570
+ x: d.clientX - s.left,
571
+ y: d.clientY - s.top
572
+ };
573
+ }
574
+ function l() {
575
+ return [...o.values()];
576
+ }
577
+ function a(d) {
578
+ if (d.pointerType === "mouse" && d.button !== 0) return;
579
+ try {
580
+ t.setPointerCapture(d.pointerId);
581
+ } catch {
582
+ }
583
+ const s = u(d), f = {
584
+ id: d.pointerId,
585
+ x: s.x,
586
+ y: s.y,
587
+ startX: s.x,
588
+ startY: s.y,
589
+ pressure: d.pressure,
590
+ pointerType: r(d.pointerType),
591
+ shiftKey: d.shiftKey,
592
+ altKey: d.altKey
593
+ };
594
+ o.set(d.pointerId, f), e.onPointerDown(f, l());
595
+ }
596
+ function c(d) {
597
+ const s = o.get(d.pointerId);
598
+ if (!s) {
599
+ if (e.onHover) {
600
+ const S = u(d);
601
+ e.onHover({
602
+ id: d.pointerId,
603
+ x: S.x,
604
+ y: S.y,
605
+ startX: S.x,
606
+ startY: S.y,
607
+ pressure: 0,
608
+ pointerType: r(d.pointerType),
609
+ shiftKey: d.shiftKey,
610
+ altKey: d.altKey
611
+ });
612
+ }
613
+ return;
614
+ }
615
+ const f = u(d);
616
+ s.x = f.x, s.y = f.y, s.pressure = d.pressure, s.shiftKey = d.shiftKey, s.altKey = d.altKey;
617
+ const x = l();
618
+ if (e.onPointerMove(s, x), x.length === 2 && e.onPinch) {
619
+ const [S, v] = x, b = Math.sqrt((v.x - S.x) ** 2 + (v.y - S.y) ** 2);
620
+ !n && b > 10 && (i = b, n = !0), n && e.onPinch({
621
+ centerX: (S.x + v.x) / 2,
622
+ centerY: (S.y + v.y) / 2,
623
+ scale: b / i,
624
+ distance: b
625
+ });
626
+ }
627
+ }
628
+ function p(d) {
629
+ const s = o.get(d.pointerId);
630
+ if (s) {
631
+ o.delete(d.pointerId);
632
+ try {
633
+ t.releasePointerCapture(d.pointerId);
634
+ } catch {
635
+ }
636
+ l().length < 2 && (n = !1, i = 0), e.onPointerUp(s, l());
637
+ }
638
+ }
639
+ function y(d) {
640
+ e.onWheel && e.onWheel(d);
641
+ }
642
+ t.addEventListener("pointerdown", a), t.addEventListener("pointermove", c), t.addEventListener("pointerup", p), t.addEventListener("pointercancel", p), t.addEventListener("wheel", y, { passive: !1 });
643
+ const m = (d) => d.preventDefault();
644
+ return t.addEventListener("contextmenu", m), t.style.touchAction = "none", {
645
+ destroy() {
646
+ t.removeEventListener("pointerdown", a), t.removeEventListener("pointermove", c), t.removeEventListener("pointerup", p), t.removeEventListener("pointercancel", p), t.removeEventListener("wheel", y), t.removeEventListener("contextmenu", m), t.style.touchAction = "", o.clear();
647
+ }
648
+ };
649
+ }
650
+ function me(t, e, o, i, n) {
651
+ const r = (e - t.startX) / i, u = (o - t.startY) / n, { startCrop: l } = t;
652
+ return {
653
+ x: X(l.x - r, 0, 1 - l.width),
654
+ y: X(l.y - u, 0, 1 - l.height),
655
+ width: l.width,
656
+ height: l.height
657
+ };
658
+ }
659
+ function ge(t, e, o, i) {
660
+ return {
661
+ handle: t.startsWith("handle-") ? t.slice(7) : t,
662
+ startCrop: { ...e },
663
+ startX: o,
664
+ startY: i
665
+ };
666
+ }
667
+ function xe(t, e, o, i, n, r, u, l = { shiftKey: !1, altKey: !1 }) {
668
+ const a = (e - t.startX) / i, c = (o - t.startY) / n, { startCrop: p, handle: y } = t;
669
+ let m = p.x, d = p.y, s = p.width, f = p.height;
670
+ const x = u / i, S = u / n;
671
+ if (y.includes("w")) {
672
+ const k = X(m + a, 0, m + s - x);
673
+ s = s - (k - m), m = k;
674
+ }
675
+ if (y.includes("e") && (s = X(s + a, x, 1 - m)), y.includes("n")) {
676
+ const k = X(d + c, 0, d + f - S);
677
+ f = f - (k - d), d = k;
678
+ }
679
+ if (y.includes("s") && (f = X(f + c, S, 1 - d)), s = Math.max(s, x), f = Math.max(f, S), l.altKey) {
680
+ const k = p.x + p.width / 2, I = p.y + p.height / 2, q = s / 2, N = f / 2;
681
+ m = X(k - q, 0, 1 - s), d = X(I - N, 0, 1 - f);
682
+ }
683
+ let v = { x: m, y: d, width: s, height: f }, b = ft(r);
684
+ return l.shiftKey && r === "free" && (b = p.width / p.height), b !== null && (v = Gt(v, b, y, i, n, u)), v;
685
+ }
686
+ function we(t, e) {
687
+ if (t.length < 2) return null;
688
+ const [o, i] = t, n = Ut(o.x, o.y, i.x, i.y);
689
+ return n < 10 ? null : {
690
+ initialDistance: n,
691
+ initialScale: e,
692
+ initialCenterX: (o.x + i.x) / 2,
693
+ initialCenterY: (o.y + i.y) / 2
694
+ };
695
+ }
696
+ function be(t, e, o, i, n, r, u) {
697
+ const l = 1 - t * o.sensitivity * 1e-3, a = X(e * l, o.minScale, o.maxScale);
698
+ let c = 0, p = 0;
699
+ if (i !== void 0 && r !== void 0) {
700
+ const y = 1 - a / e;
701
+ c = (i - r) * y, p = (n - u) * y;
702
+ }
703
+ return { scale: a, panDeltaX: c, panDeltaY: p };
704
+ }
705
+ function ve(t, e) {
706
+ function o(i) {
707
+ if (!((typeof i.composedPath == "function" ? i.composedPath() : []).includes(t) || t.contains(document.activeElement) || document.activeElement === t) || i.ctrlKey || i.metaKey || i.altKey) return;
708
+ const u = i.shiftKey ? 0.01 : 5e-3;
709
+ switch (i.key) {
710
+ case "ArrowLeft":
711
+ i.preventDefault(), e.onMoveCrop(-u, 0);
712
+ break;
713
+ case "ArrowRight":
714
+ i.preventDefault(), e.onMoveCrop(u, 0);
715
+ break;
716
+ case "ArrowUp":
717
+ i.preventDefault(), e.onMoveCrop(0, -u);
718
+ break;
719
+ case "ArrowDown":
720
+ i.preventDefault(), e.onMoveCrop(0, u);
721
+ break;
722
+ case "r":
723
+ case "R":
724
+ i.preventDefault(), e.onRotateLeft();
725
+ break;
726
+ case "f":
727
+ case "F":
728
+ i.preventDefault(), e.onFlipH();
729
+ break;
730
+ case "+":
731
+ case "=":
732
+ i.preventDefault(), e.onZoomIn();
733
+ break;
734
+ case "-":
735
+ case "_":
736
+ i.preventDefault(), e.onZoomOut();
737
+ break;
738
+ case "0":
739
+ i.preventDefault(), e.onResetZoom();
740
+ break;
741
+ case "[":
742
+ i.preventDefault(), e.onRotateFine(-1);
743
+ break;
744
+ case "]":
745
+ i.preventDefault(), e.onRotateFine(1);
746
+ break;
747
+ }
748
+ }
749
+ return t.addEventListener("keydown", o), {
750
+ destroy() {
751
+ t.removeEventListener("keydown", o);
752
+ }
753
+ };
754
+ }
755
+ function Se(t) {
756
+ t.setAttribute("role", "application"), t.setAttribute("aria-roledescription", "image crop tool"), t.setAttribute("aria-label", "Image crop tool — use arrow keys to move crop, R to rotate, F to flip horizontal, +/- to zoom"), t.setAttribute("tabindex", "0");
757
+ }
758
+ function wt(t, e, o = "free") {
759
+ let i = t.querySelector(".sfx-cr-sr-only[aria-live]");
760
+ i || (i = document.createElement("div"), i.className = "sfx-cr-sr-only", i.setAttribute("aria-live", "polite"), t.appendChild(i));
761
+ const n = e.quarterTurns + e.rotation, r = Math.round(e.scale * 100), u = o, l = e.flipH ? ", flipped horizontal" : "";
762
+ i.textContent = `Crop: ${u}, rotation ${n.toFixed(1)}°${l}, zoom ${r}%`;
763
+ }
764
+ function St(t) {
765
+ const e = t.getContext("2d");
766
+ if (!e) throw new Error("2D canvas context unavailable");
767
+ return e;
768
+ }
769
+ function Re(t, e, o) {
770
+ const i = t.quarterTurns + t.rotation, n = Math.round(t.cropRect.width * e), r = Math.round(t.cropRect.height * o), u = Math.round(t.quarterTurns / 90) % 2 !== 0;
771
+ return {
772
+ rotation: i,
773
+ flipH: t.flipH,
774
+ flipV: t.flipV,
775
+ scale: t.scale,
776
+ crop: {
777
+ x: Math.round(t.cropRect.x * e),
778
+ y: Math.round(t.cropRect.y * o),
779
+ width: n,
780
+ height: r
781
+ },
782
+ outputWidth: u ? r : n,
783
+ outputHeight: u ? n : r
784
+ };
785
+ }
786
+ function Me(t, e, o, i, n = "free", r = 20, u = 0, l = 0, a = "classic") {
787
+ const c = t.naturalWidth, p = t.naturalHeight, y = a === "fixed" && u > 0 && l > 0;
788
+ let m, d, s, f;
789
+ if (y) {
790
+ const O = ct(u, l, c, p, e.quarterTurns), V = Math.max(c / O.drawW, p / O.drawH);
791
+ m = Math.max(1, Math.round(u * V)), d = Math.max(1, Math.round(l * V));
792
+ const D = ct(m, d, c, p, e.quarterTurns);
793
+ s = D.drawW, f = D.drawH;
794
+ } else {
795
+ m = c, d = p;
796
+ const V = Math.round(e.quarterTurns / 90) % 2 !== 0 ? Math.min(m, d) / Math.max(m, d) : 1;
797
+ s = m * V, f = d * V;
798
+ }
799
+ const x = e.cropRect.x * m, S = e.cropRect.y * d, v = e.cropRect.width * m, b = e.cropRect.height * d;
800
+ let k = Math.max(1, Math.round(v)), I = Math.max(1, Math.round(b));
801
+ o > 0 && k > o && (I = Math.max(1, Math.round(I * (o / k))), k = o), i > 0 && I > i && (k = Math.max(1, Math.round(k * (i / I))), I = i);
802
+ const q = v > 1e-6 ? k / v : 1, N = document.createElement("canvas");
803
+ N.width = k, N.height = I;
804
+ const Y = St(N);
805
+ Y.save(), Y.scale(q, q), Y.translate(-x, -S);
806
+ const U = (e.cropRect.x + e.cropRect.width / 2) * m, Q = (e.cropRect.y + e.cropRect.height / 2) * d, G = e.rotationPivot ?? {
807
+ x: e.cropRect.x + e.cropRect.width / 2,
808
+ y: e.cropRect.y + e.cropRect.height / 2
809
+ }, w = G.x * m, H = G.y * d;
810
+ e.rotation !== 0 && (Y.translate(w, H), Y.rotate(lt(e.rotation)), Y.translate(-w, -H)), (e.flipH || e.flipV) && (Y.translate(U, Q), Y.scale(e.flipH ? -1 : 1, e.flipV ? -1 : 1), Y.translate(-U, -Q)), Y.translate(m / 2, d / 2), Y.scale(e.scale, e.scale);
811
+ const A = u > 0 ? m / u : 1;
812
+ return Y.translate(e.panX * A, e.panY * A), e.quarterTurns !== 0 && Y.rotate(lt(e.quarterTurns)), Y.drawImage(t, -s / 2, -f / 2, s, f), Y.restore(), n === "circle" ? Te(N) : n === "rounded-rect" && Ce(N, r), N;
813
+ }
814
+ function Ce(t, e) {
815
+ const o = St(t), i = t.width, n = t.height, r = Math.min(e, i / 2, n / 2);
816
+ o.globalCompositeOperation = "destination-in", o.beginPath(), o.moveTo(r, 0), o.lineTo(i - r, 0), o.arcTo(i, 0, i, r, r), o.lineTo(i, n - r), o.arcTo(i, n, i - r, n, r), o.lineTo(r, n), o.arcTo(0, n, 0, n - r, r), o.lineTo(0, r), o.arcTo(0, 0, r, 0, r), o.closePath(), o.fill(), o.globalCompositeOperation = "source-over";
817
+ }
818
+ function Te(t) {
819
+ const e = St(t), o = t.width, i = t.height;
820
+ e.globalCompositeOperation = "destination-in", e.beginPath(), e.ellipse(o / 2, i / 2, o / 2, i / 2, 0, 0, Math.PI * 2), e.fill(), e.globalCompositeOperation = "source-over";
821
+ }
822
+ async function ke(t, e, o) {
823
+ return new Promise((i, n) => {
824
+ let r = !1;
825
+ try {
826
+ t.toBlob(
827
+ (u) => {
828
+ r || (r = !0, u ? i(u) : n(new Error("Failed to create blob (canvas may be empty or tainted)")));
829
+ },
830
+ e,
831
+ o
832
+ );
833
+ } catch (u) {
834
+ r || (r = !0, n(u instanceof Error ? u : new Error(String(u))));
835
+ }
836
+ });
837
+ }
838
+ function He(t) {
839
+ const { canvas: e, host: o, layoutContainer: i, callbacks: n = {} } = t;
840
+ let r = { ...t.config }, u = r.cropShape, l = null, a = Pt(r.cropShape), c = null, p = null, y = null, m = null, d = null, s = !1, f = !1, x = 0, S = null, v = null, b = null, k = null, I = null, q = 0, N = 0, Y = 0;
841
+ r.initialCrop && (a = et(a, r.initialCrop)), r.initialRotation && (a = mt(a, r.initialRotation)), r.initialScale && r.initialScale !== 1 && (a = ot(a, r.initialScale, r.minScale, r.maxScale));
842
+ function U() {
843
+ return u === "circle" ? "circle" : u === "rounded-rect" ? "rounded-rect" : "rect";
844
+ }
845
+ function Q() {
846
+ return { ...a, cropRect: { ...a.cropRect } };
847
+ }
848
+ function G() {
849
+ if (!l) return { ...a.cropRect };
850
+ const h = l.naturalWidth, g = l.naturalHeight;
851
+ return {
852
+ x: Math.round(a.cropRect.x * h),
853
+ y: Math.round(a.cropRect.y * g),
854
+ width: Math.round(a.cropRect.width * h),
855
+ height: Math.round(a.cropRect.height * g)
856
+ };
857
+ }
858
+ const w = { x: 0, y: 0, width: 1, height: 1 };
859
+ let H = 0, A = 0;
860
+ function O() {
861
+ const h = i.clientWidth, g = i.clientHeight;
862
+ return h > 0 && g > 0 && (H = h, A = g), { w: h > 0 ? h : H, h: g > 0 ? g : A };
863
+ }
864
+ function V() {
865
+ if (!l || !c) return;
866
+ const { w: h, h: g } = O();
867
+ if (h <= 0 || g <= 0) return;
868
+ let C, F, L;
869
+ if (r.variant === "fixed") {
870
+ C = { x: 0, y: 0, width: h, height: g };
871
+ const z = ct(h, g, l.naturalWidth, l.naturalHeight, a.quarterTurns);
872
+ F = z.drawW, L = z.drawH;
873
+ } else {
874
+ if (Math.round(a.quarterTurns / 90) % 2 !== 0) {
875
+ c.setScaleBounds(r.minScale, r.maxScale);
876
+ return;
877
+ }
878
+ const z = a.cropRect;
879
+ C = { x: z.x * h, y: z.y * g, width: z.width * h, height: z.height * g }, F = h, L = g;
880
+ }
881
+ const W = Qt(a, h, g, C, F, L, r.maxScale);
882
+ a = { ...a, scale: W.scale, panX: W.panX, panY: W.panY }, c.setScaleBounds(W.minScale, r.maxScale);
883
+ }
884
+ function D() {
885
+ if (!c) return;
886
+ V();
887
+ const h = {
888
+ quarterTurns: a.quarterTurns,
889
+ rotation: a.rotation,
890
+ flipH: a.flipH ? -1 : 1,
891
+ flipV: a.flipV ? -1 : 1,
892
+ scale: a.scale,
893
+ panX: a.panX,
894
+ panY: a.panY,
895
+ cropRect: { ...a.cropRect },
896
+ rotationPivot: a.rotationPivot,
897
+ gridOpacity: f || r.showGrid === !0 ? 1 : 0,
898
+ interactive: f
899
+ };
900
+ c.setDisplayState(h);
901
+ }
902
+ function P() {
903
+ var h;
904
+ (h = n.onChange) == null || h.call(n, Q());
905
+ }
906
+ function T() {
907
+ var h;
908
+ (h = n.onCropChange) == null || h.call(n, G());
909
+ }
910
+ m = new ResizeObserver(() => {
911
+ s || (d && clearTimeout(d), d = setTimeout(() => {
912
+ d = null, !s && (c == null || c.resize(), D(), c == null || c.markDirty());
913
+ }, 16));
914
+ }), m.observe(i);
915
+ async function B(h) {
916
+ var C, F, L, W, z;
917
+ if (s) return;
918
+ const g = ++x;
919
+ (C = n.onLoadingChange) == null || C.call(n, !0, null);
920
+ try {
921
+ const K = new Image();
922
+ if (K.crossOrigin = "anonymous", await new Promise((rt, Kt) => {
923
+ K.onload = () => rt(), K.onerror = () => Kt(new Error(`Failed to load image: ${h}`)), K.src = h;
924
+ }), s || g !== x) return;
925
+ l = K, (F = n.onLoadingChange) == null || F.call(n, !1, null), (L = n.onImageLoad) == null || L.call(n, K), dt();
926
+ } catch (K) {
927
+ if (s || g !== x) return;
928
+ const rt = K.message;
929
+ (W = n.onLoadingChange) == null || W.call(n, !1, rt), (z = n.onError) == null || z.call(n, K);
930
+ }
931
+ }
932
+ function dt() {
933
+ var g, C;
934
+ if (!l) return;
935
+ r.variant === "fixed" ? a = { ...a, cropRect: { ...w } } : r.initialCrop || (a = gt(a, u, l.naturalWidth, l.naturalHeight));
936
+ const h = !r.enableAnimations || typeof window < "u" && ((g = window.matchMedia) == null ? void 0 : g.call(window, "(prefers-reduced-motion: reduce)").matches);
937
+ c = ue(
938
+ e,
939
+ l,
940
+ U,
941
+ r.borderRadius,
942
+ h,
943
+ // Pass the layout container explicitly: the canvas lives in its own
944
+ // shadow root and `canvas.parentElement` returns null there.
945
+ i
946
+ ), c.setScaleBounds(r.minScale, r.maxScale), c.setFixedFrame(r.variant === "fixed"), c.setBleedConfig({
947
+ show: r.showBleedMargin,
948
+ size: r.bleedMarginSize,
949
+ color: r.bleedMarginColor
950
+ }), D(), c.startLoop(), J(), r.keyboard && (y = ve(o, {
951
+ onRotateLeft: () => Ct(),
952
+ onFlipH: () => Tt(),
953
+ onZoomIn: () => it(a.scale + 0.1),
954
+ onZoomOut: () => it(a.scale - 0.1),
955
+ onResetZoom: () => it(1),
956
+ onMoveCrop: (F, L) => {
957
+ if (r.variant === "fixed") return;
958
+ const W = a.cropRect;
959
+ a = et(a, { x: W.x + F, y: W.y + L, width: W.width, height: W.height }), D(), P(), T();
960
+ },
961
+ onRotateFine: (F) => kt(a.rotation + F)
962
+ })), (C = n.onReady) == null || C.call(n);
963
+ }
964
+ function J() {
965
+ p = ye(e, {
966
+ onPointerDown: (h, g) => {
967
+ const C = Date.now(), F = C - q, L = Math.sqrt((h.x - N) ** 2 + (h.y - Y) ** 2);
968
+ if (F < 300 && L < 20 && g.length === 1) {
969
+ it(1), q = 0;
970
+ return;
971
+ }
972
+ if (q = C, N = h.x, Y = h.y, g.length === 2) {
973
+ I = we(g, a.scale), S = null, k = null;
974
+ return;
975
+ }
976
+ const W = c.getCanvasCropRect();
977
+ let z = xt(h.x, h.y, W);
978
+ r.variant === "fixed" && (z.type === "handle" || z.type === "move-handle") && (z = { type: "crop-area" }), f = !0, z.type === "move-handle" ? b = {
979
+ startX: h.x,
980
+ startY: h.y,
981
+ startRect: { ...a.cropRect }
982
+ } : z.type === "crop-area" ? v = { startX: h.x, startY: h.y, startPanX: a.panX, startPanY: a.panY } : z.type === "handle" && z.position && (k = ge("handle-" + z.position, a.cropRect, h.x, h.y)), D();
983
+ },
984
+ onPointerMove: (h) => {
985
+ if (!l) return;
986
+ const g = c.getCanvasCropRect();
987
+ if (b) {
988
+ const { displayW: C, displayH: F } = tt();
989
+ if (C > 0 && F > 0) {
990
+ const L = (h.x - b.startX) / C, W = (h.y - b.startY) / F;
991
+ a = et(a, {
992
+ x: b.startRect.x + L,
993
+ y: b.startRect.y + W,
994
+ width: b.startRect.width,
995
+ height: b.startRect.height
996
+ }), D(), P(), T();
997
+ }
998
+ return;
999
+ }
1000
+ if (v) {
1001
+ const C = h.x - v.startX, F = h.y - v.startY, L = a.flipH ? -1 : 1, W = a.flipV ? -1 : 1;
1002
+ a = {
1003
+ ...a,
1004
+ panX: v.startPanX + L * C / a.scale,
1005
+ panY: v.startPanY + W * F / a.scale
1006
+ }, D(), P();
1007
+ return;
1008
+ }
1009
+ if (S) {
1010
+ const { displayW: C, displayH: F } = tt(), L = me(S, h.x, h.y, C, F);
1011
+ a = et(a, L), D(), P(), T();
1012
+ return;
1013
+ }
1014
+ if (k) {
1015
+ const { displayW: C, displayH: F } = tt(), L = xe(
1016
+ k,
1017
+ h.x,
1018
+ h.y,
1019
+ C,
1020
+ F,
1021
+ u,
1022
+ r.minCropSize,
1023
+ { shiftKey: h.shiftKey, altKey: h.altKey }
1024
+ );
1025
+ a = et(a, L), D(), P(), T();
1026
+ return;
1027
+ }
1028
+ if (r.variant === "fixed")
1029
+ e.style.cursor = "grab";
1030
+ else {
1031
+ const C = xt(h.x, h.y, g);
1032
+ e.style.cursor = Dt(C);
1033
+ }
1034
+ },
1035
+ onHover: (h) => {
1036
+ if (!c) return;
1037
+ if (r.variant === "fixed") {
1038
+ e.style.cursor = "grab";
1039
+ return;
1040
+ }
1041
+ const g = c.getCanvasCropRect(), C = xt(h.x, h.y, g);
1042
+ e.style.cursor = Dt(C);
1043
+ },
1044
+ onPointerUp: (h, g) => {
1045
+ g.length < 2 && (I = null), g.length === 0 && (S = null, v = null, b = null, k = null, f = !1, N = 0, Y = 0, D());
1046
+ },
1047
+ onPinch: (h) => {
1048
+ var L;
1049
+ I || (I = { initialDistance: h.distance, initialScale: a.scale, initialCenterX: h.centerX, initialCenterY: h.centerY });
1050
+ const g = a.scale * (h.distance / I.initialDistance), C = h.centerX - I.initialCenterX, F = h.centerY - I.initialCenterY;
1051
+ a = ot(a, g, r.minScale, r.maxScale), a = Et(a, C, F), (L = n.onScaleSync) == null || L.call(n, a.scale), D(), P();
1052
+ },
1053
+ onWheel: (h) => {
1054
+ var K, rt;
1055
+ if (!r.wheelZoom) return;
1056
+ h.preventDefault();
1057
+ const g = e.getBoundingClientRect(), C = h.clientX - g.left, F = h.clientY - g.top, L = g.width / 2, W = g.height / 2, z = be(h.deltaY, a.scale, {
1058
+ minScale: r.minScale,
1059
+ maxScale: r.maxScale,
1060
+ sensitivity: 1
1061
+ }, C, F, L, W);
1062
+ a = ot(a, z.scale, r.minScale, r.maxScale), a = Et(a, z.panDeltaX, z.panDeltaY), (K = n.onScaleSync) == null || K.call(n, a.scale), (rt = n.onWheelZoomActivity) == null || rt.call(n), D(), P();
1063
+ }
1064
+ });
1065
+ }
1066
+ function tt() {
1067
+ return { displayW: i.clientWidth, displayH: i.clientHeight };
1068
+ }
1069
+ function at(h) {
1070
+ var g;
1071
+ s || u !== h && (u = h, r.variant === "fixed" ? a = { ...a, cropRect: { ...w } } : a = gt(
1072
+ a,
1073
+ h,
1074
+ (l == null ? void 0 : l.naturalWidth) ?? 1,
1075
+ (l == null ? void 0 : l.naturalHeight) ?? 1
1076
+ ), (g = n.onShapeSync) == null || g.call(n, h), D(), P(), T());
1077
+ }
1078
+ function Wt(h) {
1079
+ s || (a = et(a, h), D(), P(), T());
1080
+ }
1081
+ function Ct() {
1082
+ s || (a = Jt(a), D(), wt(o, a, u), P(), T());
1083
+ }
1084
+ function Tt() {
1085
+ s || (a = te(a), D(), wt(o, a, u), P(), T());
1086
+ }
1087
+ function kt(h) {
1088
+ var g;
1089
+ s || (a = mt(a, h), (g = n.onRotationSync) == null || g.call(n, h), D(), P());
1090
+ }
1091
+ function it(h) {
1092
+ var g;
1093
+ s || (a = ot(a, h, r.minScale, r.maxScale), (g = n.onScaleSync) == null || g.call(n, a.scale), D(), P());
1094
+ }
1095
+ function At() {
1096
+ var h, g, C;
1097
+ s || (u = r.cropShape, a = Pt(
1098
+ r.cropShape,
1099
+ (l == null ? void 0 : l.naturalWidth) ?? 1,
1100
+ (l == null ? void 0 : l.naturalHeight) ?? 1
1101
+ ), r.variant === "fixed" ? a = { ...a, cropRect: { ...w } } : r.initialCrop && (a = et(a, r.initialCrop)), r.initialRotation && (a = mt(a, r.initialRotation)), r.initialScale !== void 0 && r.initialScale !== 1 && (a = ot(a, r.initialScale, r.minScale, r.maxScale)), (h = n.onRotationSync) == null || h.call(n, a.rotation), (g = n.onShapeSync) == null || g.call(n, r.cropShape), (C = n.onScaleSync) == null || C.call(n, a.scale), D(), wt(o, a, u), P(), T());
1102
+ }
1103
+ function yt() {
1104
+ if (!l) throw new Error("No image loaded");
1105
+ const { w: h, h: g } = O();
1106
+ return Me(
1107
+ l,
1108
+ a,
1109
+ r.maxOutputWidth,
1110
+ r.maxOutputHeight,
1111
+ u,
1112
+ r.borderRadius,
1113
+ // Pan is stored in the renderer's CSS-px container space; pass the
1114
+ // container dims so the exporter can rescale pan into display space.
1115
+ // The height + variant drive the fixed variant's cover-fit export.
1116
+ h,
1117
+ g,
1118
+ r.variant
1119
+ );
1120
+ }
1121
+ async function Bt(h, g) {
1122
+ const C = yt();
1123
+ return ke(C, h || r.outputType, g ?? r.outputQuality);
1124
+ }
1125
+ function Nt(h, g) {
1126
+ try {
1127
+ return yt().toDataURL(h || r.outputType, g ?? r.outputQuality);
1128
+ } catch (C) {
1129
+ const F = C instanceof Error ? C : new Error(String(C));
1130
+ throw new Error(`Failed to export data URL: ${F.message}`);
1131
+ }
1132
+ }
1133
+ function qt() {
1134
+ if (!l) throw new Error("No image loaded");
1135
+ return Re(a, l.naturalWidth, l.naturalHeight);
1136
+ }
1137
+ function Vt(h) {
1138
+ if (s) return;
1139
+ const g = r.src, C = r.variant;
1140
+ r = zt({ ...r, ...h }), h.cropShape !== void 0 && at(h.cropShape), h.variant !== void 0 && h.variant !== C && (c == null || c.setFixedFrame(r.variant === "fixed"), r.variant === "fixed" ? a = { ...a, cropRect: { ...w } } : (c == null || c.setScaleBounds(r.minScale, r.maxScale), a = gt(a, u, (l == null ? void 0 : l.naturalWidth) ?? 1, (l == null ? void 0 : l.naturalHeight) ?? 1), a = ot({ ...a, panX: 0, panY: 0 }, r.initialScale ?? 1, r.minScale, r.maxScale)), D(), P(), T()), h.src !== void 0 && h.src !== g && B(h.src).catch(() => {
1141
+ }), (h.showBleedMargin !== void 0 || h.bleedMarginSize !== void 0 || h.bleedMarginColor !== void 0) && (c == null || c.setBleedConfig({
1142
+ show: r.showBleedMargin,
1143
+ size: r.bleedMarginSize,
1144
+ color: r.bleedMarginColor
1145
+ })), h.showGrid !== void 0 && D(), c == null || c.markDirty();
1146
+ }
1147
+ function _t() {
1148
+ s || (s = !0, x++, c == null || c.destroy(), p == null || p.destroy(), y == null || y.destroy(), m == null || m.disconnect(), d && (clearTimeout(d), d = null));
1149
+ }
1150
+ return {
1151
+ loadImage: B,
1152
+ getTransformState: Q,
1153
+ getCropRect: G,
1154
+ setCropShape: at,
1155
+ setCropRect: Wt,
1156
+ rotateLeft: Ct,
1157
+ flipHorizontal: Tt,
1158
+ setRotation: kt,
1159
+ setScale: it,
1160
+ reset: At,
1161
+ toCanvas: yt,
1162
+ toBlob: Bt,
1163
+ toDataURL: Nt,
1164
+ toTransformParams: qt,
1165
+ update: Vt,
1166
+ destroy: _t
1167
+ };
1168
+ }
1169
+ class Xt extends $t {
1170
+ }
1171
+ function Ke(t, e) {
1172
+ typeof customElements > "u" || customElements.get(t) || customElements.define(t, e);
1173
+ }
1174
+ const Pe = Z`
1175
+ :host {
1176
+ display: block;
1177
+ width: 100%;
1178
+ height: 100%;
1179
+ min-width: 0;
1180
+ min-height: 0;
1181
+ /* Single source of clipping is .sfx-cr-container (overflow:hidden +
1182
+ border-radius). Don't add a second mask here: this host is sized
1183
+ by JS to the full outer rect (displayW×displayH), which is 4px
1184
+ wider than the container's content-box, so its own border-radius
1185
+ wouldn't align with the container's effective inner radius
1186
+ (radius - border-width) and you'd see two stepped curves at the
1187
+ corner. Transparent bg lets the container surface show through
1188
+ in the rounded corner sliver. */
1189
+ background: transparent;
1190
+ }
1191
+
1192
+ canvas {
1193
+ display: block;
1194
+ width: 100%;
1195
+ height: 100%;
1196
+ outline: none;
1197
+ touch-action: none;
1198
+ }
1199
+ `;
1200
+ var Ee = Object.defineProperty, Ie = (t, e, o, i) => {
1201
+ for (var n = void 0, r = t.length - 1, u; r >= 0; r--)
1202
+ (u = t[r]) && (n = u(e, o, n) || n);
1203
+ return n && Ee(e, o, n), n;
1204
+ };
1205
+ const Rt = class Rt extends Xt {
1206
+ render() {
1207
+ return vt`<canvas part="canvas"></canvas>`;
1208
+ }
1209
+ };
1210
+ Rt.styles = [Pe];
1211
+ let ut = Rt;
1212
+ Ie([
1213
+ pt("canvas")
1214
+ ], ut.prototype, "canvasEl");
1215
+ const Ft = [
1216
+ "free",
1217
+ "square",
1218
+ // Landscape
1219
+ "16:9",
1220
+ "4:3",
1221
+ "3:2",
1222
+ "5:4",
1223
+ "2:1",
1224
+ // Portrait
1225
+ "9:16",
1226
+ "3:4",
1227
+ "2:3",
1228
+ "4:5",
1229
+ "1:2"
1230
+ ], De = [
1231
+ "free",
1232
+ "square",
1233
+ "circle",
1234
+ "rounded-rect"
1235
+ ];
1236
+ function bt(t) {
1237
+ return typeof t != "string" ? !1 : De.includes(t) ? !0 : Yt(t) !== null;
1238
+ }
1239
+ function Fe(t) {
1240
+ if (t == null) return;
1241
+ if (Array.isArray(t)) return t.filter(bt);
1242
+ if (typeof t != "string") return;
1243
+ const e = t.trim();
1244
+ if (e) {
1245
+ if (e.startsWith("["))
1246
+ try {
1247
+ const o = JSON.parse(e);
1248
+ if (Array.isArray(o)) return o.filter(bt);
1249
+ } catch {
1250
+ }
1251
+ return e.split(/[\s,]+/).filter(Boolean).filter(bt);
1252
+ }
1253
+ }
1254
+ const Le = Z`
1255
+ :host {
1256
+ /* Palette — light theme (matches ui-tw :root) */
1257
+ --sfx-cr-primary: oklch(0.578 0.198 268.129);
1258
+ --sfx-cr-primary-hover: oklch(0.5 0.198 268.129);
1259
+ --sfx-cr-primary-mid: oklch(0.62 0.198 268.129);
1260
+ --sfx-cr-primary-bg: oklch(0.578 0.198 268.129 / 0.07);
1261
+ --sfx-cr-primary-glow: oklch(0.578 0.198 268.129 / 0.18);
1262
+
1263
+ --sfx-cr-success: oklch(0.637 0.17 151.295);
1264
+ --sfx-cr-error: oklch(0.577 0.215 27.325);
1265
+
1266
+ --sfx-cr-text: oklch(0.37 0.022 248.413);
1267
+ --sfx-cr-text-secondary: oklch(53.03% 0.039 249.89);
1268
+ --sfx-cr-text-muted: oklch(0.685 0.033 249.82);
1269
+ /* Fine-tilt ruler ink + halo. The ruler floats directly over the photo,
1270
+ whose brightness is unknown, so its colour can't track the theme. We
1271
+ render a bright (near-white) core wrapped in a dark halo: the white core
1272
+ reads over dark images, the dark halo reads over bright ones — the same
1273
+ trick subtitles use to stay legible over arbitrary footage. */
1274
+ --sfx-cr-ruler-ink: oklch(1 0 0);
1275
+ --sfx-cr-ruler-halo: oklch(0 0 0 / 0.85);
1276
+
1277
+ --sfx-cr-border: oklch(92.86% 0.009 247.92);
1278
+ --sfx-cr-border-light: oklch(0.974 0.006 239.819);
1279
+
1280
+ --sfx-cr-bg: oklch(1 0 0);
1281
+ --sfx-cr-surface: oklch(0.974 0.006 239.819);
1282
+ --sfx-cr-canvas-bg: oklch(0.974 0.006 239.819);
1283
+ /* Dimming overlay for pixels outside the crop rect. Light theme uses a
1284
+ very soft, near-white tint so the whole surround stays bright; dark
1285
+ theme keeps the classic black dim for contrast against the photo. */
1286
+ --sfx-cr-overlay-color: oklch(1 0 0 / 0.52);
1287
+ /* Crop frame + handle colors, theme-aware so the rectangle reads
1288
+ against both a washed-out light background and a dimmed dark one. */
1289
+ --sfx-cr-frame-color: oklch(0.37 0.022 248.413);
1290
+ --sfx-cr-frame-shadow: oklch(1 0 0 / 0.7);
1291
+ --sfx-cr-handle-fill: oklch(0.37 0.022 248.413);
1292
+ --sfx-cr-handle-stroke: oklch(1 0 0 / 0.95);
1293
+
1294
+ --sfx-cr-ring: oklch(0.578 0.198 268.129 / 0.7);
1295
+ --sfx-cr-shadow: oklch(26.18% 0.024 256.43 / 0.1);
1296
+
1297
+ /* Derived — kept for internal reuse */
1298
+ --sfx-cr-toolbar-bg: oklch(1 0 0 / 0.85);
1299
+ --sfx-cr-toolbar-color: var(--sfx-cr-text);
1300
+ --sfx-cr-toolbar-border: oklch(92.86% 0.009 247.92 / 0.6);
1301
+ /* shadow-sm + soft primary tint */
1302
+ --sfx-cr-toolbar-shadow: 0 1px 3px 0 oklch(0 0 0 / 0.1), 0 1px 2px -1px oklch(0 0 0 / 0.1);
1303
+ --sfx-cr-btn-size: 36px;
1304
+ --sfx-cr-btn-radius: 6px;
1305
+ --sfx-cr-btn-hover-bg: var(--sfx-cr-primary-bg);
1306
+ --sfx-cr-btn-active-bg: oklch(0.578 0.198 268.129 / 0.14);
1307
+ --sfx-cr-separator-color: var(--sfx-cr-border-light);
1308
+ --sfx-cr-slider-track: var(--sfx-cr-border);
1309
+ --sfx-cr-slider-fill: var(--sfx-cr-primary);
1310
+ --sfx-cr-slider-thumb: var(--sfx-cr-primary);
1311
+ /* Translucent so the dropdown picks up whatever sits behind it
1312
+ (image, overlay) when paired with backdrop-filter. */
1313
+ --sfx-cr-dropdown-bg: oklch(0.974 0.006 239.819 / 0.8);
1314
+ --sfx-cr-dropdown-hover: var(--sfx-cr-primary-bg);
1315
+ /* shadow-md + shadow-lg blend */
1316
+ --sfx-cr-dropdown-shadow: 0 10px 15px -3px oklch(0 0 0 / 0.1), 0 4px 6px -4px oklch(0 0 0 / 0.1);
1317
+ --sfx-cr-zoom-bar-bg: oklch(1 0 0 / 0.85);
1318
+ --sfx-cr-transition: 0.15s ease;
1319
+ --sfx-cr-font: "Inter", ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
1320
+
1321
+ /* Border-radius scale — mirrors ui-tw --radius-sm/md/lg/xl */
1322
+ --sfx-cr-radius-sm: 4px;
1323
+ --sfx-cr-radius-md: 6px;
1324
+ --sfx-cr-radius-lg: 8px;
1325
+ --sfx-cr-radius-xl: 12px;
1326
+ /* Outer card (when <sfx-crop> fills the host) */
1327
+ --sfx-cr-radius: var(--sfx-cr-radius-xl);
1328
+ --sfx-cr-card-shadow: 0 28px 80px oklch(0 0 0 / 0.2), 0 4px 16px oklch(0 0 0 / 0.06);
1329
+ }
1330
+
1331
+ /* Dark variant — mirrors ui-tw :root.dark. */
1332
+ :host([theme="dark"]) {
1333
+ --sfx-cr-primary: oklch(0.6 0.2 268.129);
1334
+ --sfx-cr-primary-hover: oklch(0.55 0.2 268.129);
1335
+ --sfx-cr-primary-mid: oklch(0.65 0.2 268.129);
1336
+ --sfx-cr-primary-bg: oklch(0.6 0.2 268.129 / 0.07);
1337
+ --sfx-cr-primary-glow: oklch(0.6 0.2 268.129 / 0.22);
1338
+
1339
+ --sfx-cr-success: oklch(0.6 0.2 154.83);
1340
+ --sfx-cr-error: oklch(0.55 0.2 27.325);
1341
+
1342
+ --sfx-cr-text: oklch(0.95 0.01 264.55);
1343
+ --sfx-cr-text-secondary: oklch(0.9 0.01 264.55);
1344
+ --sfx-cr-text-muted: oklch(0.75 0.01 249.82);
1345
+ /* Ruler keeps the white core + dark halo over the photo (see light theme);
1346
+ --sfx-cr-ruler-halo is inherited from the base :host. */
1347
+ --sfx-cr-ruler-ink: oklch(1 0 0);
1348
+
1349
+ --sfx-cr-border: oklch(0.3 0.01 247.92);
1350
+ --sfx-cr-border-light: oklch(0.3 0.01 285);
1351
+
1352
+ --sfx-cr-bg: oklch(0.13 0.027 261.692);
1353
+ --sfx-cr-surface: oklch(0.25 0.01 264.55);
1354
+ --sfx-cr-canvas-bg: oklch(0.13 0.027 261.692);
1355
+ --sfx-cr-overlay-color: oklch(0 0 0 / 0.35);
1356
+ --sfx-cr-frame-color: oklch(0.95 0.01 264.55);
1357
+ --sfx-cr-frame-shadow: oklch(0 0 0 / 0.6);
1358
+ --sfx-cr-handle-fill: oklch(0.95 0.01 264.55);
1359
+ --sfx-cr-handle-stroke: oklch(0 0 0 / 0.25);
1360
+
1361
+ --sfx-cr-ring: oklch(0.6 0.2 268.129 / 0.7);
1362
+ --sfx-cr-shadow: oklch(0 0 0 / 0.2);
1363
+
1364
+ --sfx-cr-toolbar-bg: oklch(0.13 0.027 261.692 / 0.85);
1365
+ --sfx-cr-toolbar-color: oklch(0.95 0.01 264.55);
1366
+ --sfx-cr-toolbar-border: oklch(0.3 0.01 247.92 / 0.5);
1367
+ --sfx-cr-toolbar-shadow: 0 4px 20px oklch(0 0 0 / 0.4);
1368
+
1369
+ --sfx-cr-btn-hover-bg: oklch(0.6 0.2 268.129 / 0.22);
1370
+ --sfx-cr-btn-active-bg: oklch(0.6 0.2 268.129 / 0.32);
1371
+
1372
+ --sfx-cr-slider-track: oklch(0.3 0.01 247.92);
1373
+
1374
+ --sfx-cr-dropdown-bg: oklch(0.13 0.027 261.692 / 0.82);
1375
+ --sfx-cr-dropdown-hover: oklch(0.6 0.2 268.129 / 0.22);
1376
+ --sfx-cr-dropdown-shadow: 0 10px 15px -3px oklch(0 0 0 / 0.5), 0 4px 6px -4px oklch(0 0 0 / 0.3);
1377
+ --sfx-cr-zoom-bar-bg: oklch(0.13 0.027 261.692 / 0.85);
1378
+
1379
+ --sfx-cr-card-shadow: 0 28px 80px oklch(0 0 0 / 0.55), 0 4px 16px oklch(0 0 0 / 0.2);
1380
+ }
1381
+ `, ze = Z`
1382
+ .sfx-cr-sr-only {
1383
+ position: absolute;
1384
+ width: 1px;
1385
+ height: 1px;
1386
+ padding: 0;
1387
+ margin: -1px;
1388
+ overflow: hidden;
1389
+ clip: rect(0, 0, 0, 0);
1390
+ white-space: nowrap;
1391
+ border: 0;
1392
+ }
1393
+
1394
+ @media (prefers-reduced-motion: reduce) {
1395
+ :host, :host *, :host *::before, :host *::after {
1396
+ transition-duration: 0.01ms !important;
1397
+ animation-duration: 0.01ms !important;
1398
+ }
1399
+ }
1400
+ `, Ye = Z`
1401
+ @keyframes sfx-cr-spin { to { transform: rotate(360deg); } }
1402
+ `, $e = Z`
1403
+ @keyframes sfx-cr-toolbar-enter {
1404
+ from {
1405
+ opacity: 0;
1406
+ }
1407
+ to {
1408
+ opacity: 1;
1409
+ }
1410
+ }
1411
+ `;
1412
+ Z`
1413
+ @keyframes sfx-cr-zoom-enter {
1414
+ from {
1415
+ opacity: 0;
1416
+ transform: translateX(-50%) translateY(12px);
1417
+ }
1418
+ to {
1419
+ opacity: 1;
1420
+ transform: translateX(-50%) translateY(0);
1421
+ }
1422
+ }
1423
+ `;
1424
+ Z`
1425
+ @keyframes sfx-cr-card-in {
1426
+ from {
1427
+ opacity: 0;
1428
+ transform: translateY(10px) scale(0.98);
1429
+ }
1430
+ to {
1431
+ opacity: 1;
1432
+ transform: translateY(0) scale(1);
1433
+ }
1434
+ }
1435
+ `;
1436
+ Z`
1437
+ input[type="range"]::-webkit-slider-thumb {
1438
+ -webkit-appearance: none;
1439
+ width: 16px;
1440
+ height: 16px;
1441
+ border-radius: 50%;
1442
+ background: var(--sfx-cr-slider-thumb);
1443
+ cursor: pointer;
1444
+ box-shadow: 0 1px 4px var(--sfx-cr-primary-glow);
1445
+ transition: transform 150ms ease, box-shadow 150ms ease;
1446
+ }
1447
+ input[type="range"]::-webkit-slider-thumb:hover {
1448
+ transform: scale(1.15);
1449
+ box-shadow: 0 0 0 5px var(--sfx-cr-primary-glow);
1450
+ }
1451
+ input[type="range"]::-moz-range-thumb {
1452
+ width: 16px;
1453
+ height: 16px;
1454
+ border-radius: 50%;
1455
+ background: var(--sfx-cr-slider-thumb);
1456
+ border: none;
1457
+ cursor: pointer;
1458
+ box-shadow: 0 1px 4px var(--sfx-cr-primary-glow);
1459
+ }
1460
+ `;
1461
+ const Oe = Z`
1462
+ :host {
1463
+ display: block;
1464
+ position: relative;
1465
+ width: 100%;
1466
+ height: 100%;
1467
+ font-family: var(--sfx-cr-font);
1468
+ color: var(--sfx-cr-text);
1469
+ /* Establish a named inline-size container so the toolbar / shapes /
1470
+ zoom / rotate sub-elements can switch to their compact left-rail
1471
+ layout based on the editor's own width — independent of the page
1472
+ viewport. A narrow column on a wide desktop (sidebar preview,
1473
+ split view) gets the same compact UI as a phone. */
1474
+ container-type: inline-size;
1475
+ container-name: sfxcrop;
1476
+ }
1477
+
1478
+ :host([hidden]) { display: none; }
1479
+
1480
+ :host(:focus-visible) {
1481
+ outline: 2px solid var(--sfx-cr-ring);
1482
+ outline-offset: 2px;
1483
+ }
1484
+
1485
+ .sfx-cr-container {
1486
+ position: relative;
1487
+ overflow: hidden;
1488
+ width: 100%;
1489
+ height: 100%;
1490
+ background: var(--sfx-cr-bg);
1491
+ border-radius: var(--sfx-cr-radius);
1492
+ /* Editor card frame: shadow-only (no border). A border draws two
1493
+ visible curves at the corners (outer + inner padding edge),
1494
+ reading as a "double ring"; a slightly stronger shadow gives the
1495
+ same elevation feel with a single clean rounded silhouette. */
1496
+ /* shadow-xs ring + shadow-md elevation, sourced from ui-tw scale */
1497
+ box-shadow:
1498
+ 0 0 0 1px oklch(0 0 0 / 0.05),
1499
+ 0 4px 6px -1px oklch(0 0 0 / 0.1),
1500
+ 0 2px 4px -2px oklch(0 0 0 / 0.1);
1501
+ font-family: var(--sfx-cr-font);
1502
+ user-select: none;
1503
+ -webkit-user-select: none;
1504
+ }
1505
+
1506
+ /* ====== Loading ====== */
1507
+ .sfx-cr-loading {
1508
+ position: absolute;
1509
+ inset: 0;
1510
+ display: flex;
1511
+ flex-direction: column;
1512
+ align-items: center;
1513
+ justify-content: center;
1514
+ gap: 16px;
1515
+ background: var(--sfx-cr-bg);
1516
+ z-index: 10;
1517
+ transition: opacity 280ms ease;
1518
+ }
1519
+ .sfx-cr-loading--hidden {
1520
+ opacity: 0;
1521
+ pointer-events: none;
1522
+ }
1523
+
1524
+ .sfx-cr-loading-spinner {
1525
+ width: 36px;
1526
+ height: 36px;
1527
+ border: 3px solid var(--sfx-cr-border);
1528
+ border-top-color: var(--sfx-cr-primary);
1529
+ border-radius: 50%;
1530
+ animation: sfx-cr-spin 0.8s linear infinite;
1531
+ }
1532
+
1533
+ .sfx-cr-loading-text {
1534
+ font-size: 14px;
1535
+ font-weight: 500;
1536
+ color: var(--sfx-cr-text-secondary);
1537
+ letter-spacing: 0.2px;
1538
+ }
1539
+
1540
+ /* ====== Error ====== */
1541
+ .sfx-cr-error {
1542
+ position: absolute;
1543
+ inset: 0;
1544
+ display: none;
1545
+ flex-direction: column;
1546
+ align-items: center;
1547
+ justify-content: center;
1548
+ gap: 12px;
1549
+ padding: 32px;
1550
+ background: var(--sfx-cr-bg);
1551
+ z-index: 10;
1552
+ color: var(--sfx-cr-error);
1553
+ font-size: 14px;
1554
+ font-weight: 500;
1555
+ text-align: center;
1556
+ }
1557
+ .sfx-cr-error--visible { display: flex; }
1558
+ `;
1559
+ var Xe = Object.defineProperty, M = (t, e, o, i) => {
1560
+ for (var n = void 0, r = t.length - 1, u; r >= 0; r--)
1561
+ (u = t[r]) && (n = u(e, o, n) || n);
1562
+ return n && Xe(e, o, n), n;
1563
+ };
1564
+ const We = {
1565
+ fromAttribute(t) {
1566
+ return t === null ? "interaction" : t === "true" || t === "" ? !0 : t === "false" ? !1 : "interaction";
1567
+ },
1568
+ toAttribute(t) {
1569
+ return t === !0 ? "true" : t === !1 ? "false" : "interaction";
1570
+ }
1571
+ }, Mt = class Mt extends Xt {
1572
+ constructor() {
1573
+ super(...arguments), this.src = "", this.cropShape = "16:9", this.theme = "light", this.initialRotation = 0, this.initialScale = 1, this.minScale = 0.5, this.maxScale = 5, this.minCropSize = 20, this.handleSize = 12, this.borderRadius = 20, this.outputQuality = 0.92, this.maxOutputWidth = 0, this.maxOutputHeight = 0, this.bleedMarginSize = 10, this.animationSpeed = 1, this.handleColor = "#ffffff", this.overlayColor = "rgba(0, 0, 0, 0.55)", this.bleedMarginColor = "rgba(255, 0, 0, 0.5)", this.outputType = "image/png", this.toolbarPosition = "top", this.variant = "classic", this.showGrid = "interaction", this.showToolbar = !0, this.showRotateSlider = !0, this.showZoomSlider = !0, this.showShapeSelector = !0, this.showRotateButton = !0, this.showFlipButton = !0, this.showBleedMargin = !1, this.enableAnimations = !0, this.keyboard = !0, this.pinchZoom = !0, this.wheelZoom = !0, this.availableShapes = [...Ft], this.initialCrop = null, this.icons = {}, this.loading = !1, this.errorMessage = null, this.controller = null, this.currentImage = null, this.parentResizeObserver = null, this.onToolbarCommand = (e) => {
1574
+ if (!this.controller) return;
1575
+ const o = e.detail;
1576
+ switch (o.type) {
1577
+ case "reset":
1578
+ this.controller.reset();
1579
+ break;
1580
+ case "rotate-left":
1581
+ this.controller.rotateLeft();
1582
+ break;
1583
+ case "flip-h":
1584
+ this.controller.flipHorizontal();
1585
+ break;
1586
+ case "rotation":
1587
+ this.controller.setRotation(o.value);
1588
+ break;
1589
+ case "scale":
1590
+ this.controller.setScale(o.value);
1591
+ break;
1592
+ case "shape":
1593
+ this.cropShape = o.value;
1594
+ break;
1595
+ case "save":
1596
+ this.save();
1597
+ break;
1598
+ }
1599
+ };
1600
+ }
1601
+ // === Lifecycle ===
1602
+ async firstUpdated() {
1603
+ if (Se(this), !(this.canvasHost instanceof ut))
1604
+ throw new Error(
1605
+ "<sfx-crop>: custom elements not registered. Import '@scaleflex/crop/define' before using the tag."
1606
+ );
1607
+ if (await this.canvasHost.updateComplete, !this.isConnected) return;
1608
+ const e = this.canvasHost.canvasEl, o = zt(this.buildConfig());
1609
+ this.controller = He({
1610
+ canvas: e,
1611
+ host: this,
1612
+ // Pass the canvas host (which we size to the image's display rect)
1613
+ // so the controller's ResizeObserver and renderer measure the tight
1614
+ // photo box — not the outer column that also includes toolbars.
1615
+ layoutContainer: this.canvasHost,
1616
+ config: o,
1617
+ callbacks: {
1618
+ onReady: () => this.dispatch("sfx-crop-ready", { element: this }),
1619
+ onImageLoad: (n) => {
1620
+ this.currentImage = n, this.fitHostToImage(), this.dispatch("sfx-crop-image-load", { image: n });
1621
+ },
1622
+ onError: (n) => this.dispatch("sfx-crop-error", { error: n }),
1623
+ onChange: (n) => {
1624
+ this.dispatch("sfx-crop-change", n);
1625
+ },
1626
+ onCropChange: (n) => this.dispatch("sfx-crop-crop-change", n),
1627
+ onRotationSync: (n) => {
1628
+ var r;
1629
+ return (r = this.toolbarHost) == null ? void 0 : r.setRotationValue(n);
1630
+ },
1631
+ onShapeSync: (n) => {
1632
+ var r;
1633
+ this.cropShape = n, (r = this.toolbarHost) == null || r.setShapeValue(n);
1634
+ },
1635
+ onScaleSync: () => {
1636
+ },
1637
+ onLoadingChange: (n, r) => {
1638
+ this.loading = n, this.errorMessage = r;
1639
+ }
1640
+ }
1641
+ });
1642
+ const i = this.parentElement;
1643
+ i && (this.parentResizeObserver = new ResizeObserver(() => this.fitHostToImage()), this.parentResizeObserver.observe(i)), this.src && this.controller.loadImage(this.src);
1644
+ }
1645
+ /** @see LIVE_CONFIG_KEYS for the exact set forwarded to `controller.update()`. */
1646
+ updated(e) {
1647
+ if (!this.controller) return;
1648
+ const o = {};
1649
+ let i = !1;
1650
+ for (const n of Ae)
1651
+ e.has(n) && (o[n] = this[n], i = !0);
1652
+ i && this.controller.update(o), (e.has("variant") || e.has("cropShape")) && this.fitHostToImage();
1653
+ }
1654
+ disconnectedCallback() {
1655
+ var e, o;
1656
+ super.disconnectedCallback(), (e = this.parentResizeObserver) == null || e.disconnect(), this.parentResizeObserver = null, (o = this.controller) == null || o.destroy(), this.controller = null;
1657
+ }
1658
+ render() {
1659
+ return vt`
1660
+ <div class="sfx-cr-container" part="container">
1661
+ <sfx-crop-canvas part="canvas-host"></sfx-crop-canvas>
1662
+ ${this.showToolbar ? vt`
1663
+ <sfx-crop-toolbar
1664
+ part="toolbar"
1665
+ .shape=${this.cropShape}
1666
+ ?show-rotate-button=${this.showRotateButton}
1667
+ ?show-flip-button=${this.showFlipButton}
1668
+ ?show-rotate-slider=${this.showRotateSlider}
1669
+ ?show-shape-selector=${this.showShapeSelector}
1670
+ toolbar-position=${this.toolbarPosition}
1671
+ variant=${this.variant}
1672
+ .availableShapes=${this.availableShapes}
1673
+ .icons=${this.icons}
1674
+ @sfx-crop-toolbar-command=${this.onToolbarCommand}
1675
+ ></sfx-crop-toolbar>
1676
+ ` : null}
1677
+ <div class=${Ht({ "sfx-cr-loading": !0, "sfx-cr-loading--hidden": !this.loading })} part="loading">
1678
+ <div class="sfx-cr-loading-spinner"></div>
1679
+ <div class="sfx-cr-loading-text">Loading…</div>
1680
+ </div>
1681
+ <div class=${Ht({ "sfx-cr-error": !0, "sfx-cr-error--visible": !!this.errorMessage })} part="error">
1682
+ ${this.errorMessage ?? "Failed to load image"}
1683
+ </div>
1684
+ </div>
1685
+ `;
1686
+ }
1687
+ // === Public imperative API ===
1688
+ loadImage(e) {
1689
+ return this.ensure().loadImage(e);
1690
+ }
1691
+ getTransformState() {
1692
+ return this.ensure().getTransformState();
1693
+ }
1694
+ setCropShape(e) {
1695
+ this.ensure(), this.cropShape = e;
1696
+ }
1697
+ setCropRect(e) {
1698
+ this.ensure().setCropRect(e);
1699
+ }
1700
+ getCropRect() {
1701
+ return this.ensure().getCropRect();
1702
+ }
1703
+ rotateLeft() {
1704
+ this.ensure().rotateLeft();
1705
+ }
1706
+ flipHorizontal() {
1707
+ this.ensure().flipHorizontal();
1708
+ }
1709
+ setRotation(e) {
1710
+ this.ensure().setRotation(e);
1711
+ }
1712
+ setScale(e) {
1713
+ this.ensure().setScale(e);
1714
+ }
1715
+ reset() {
1716
+ this.ensure().reset();
1717
+ }
1718
+ toCanvas() {
1719
+ return this.ensure().toCanvas();
1720
+ }
1721
+ toBlob(e, o) {
1722
+ return this.ensure().toBlob(e, o);
1723
+ }
1724
+ toDataURL(e, o) {
1725
+ return this.ensure().toDataURL(e, o);
1726
+ }
1727
+ toTransformParams() {
1728
+ return this.ensure().toTransformParams();
1729
+ }
1730
+ async save(e, o) {
1731
+ const i = await this.toBlob(e, o), n = this.toDataURL(e, o), r = this.toTransformParams();
1732
+ this.dispatch("sfx-crop-save", { blob: i, dataURL: n, params: r });
1733
+ }
1734
+ cancel() {
1735
+ this.dispatch("sfx-crop-cancel", void 0);
1736
+ }
1737
+ // === Internals ===
1738
+ ensure() {
1739
+ if (!this.controller)
1740
+ throw new Error('<sfx-crop> not connected — wait for "sfx-crop-ready" or firstUpdated().');
1741
+ return this.controller;
1742
+ }
1743
+ /**
1744
+ * Size both the canvas host (to the image's display rect, no letterbox)
1745
+ * and the outer `<sfx-crop>` host (photo rect + measured toolbar stack).
1746
+ *
1747
+ * Bound order for `max-width` / `max-height`:
1748
+ * 1. Consumer-provided values on the host's own CSS / inline style.
1749
+ * 2. Parent's client rect as a fallback.
1750
+ * 3. Viewport size as a last resort.
1751
+ *
1752
+ * Called on image-load, on state changes (90° rotation swaps aspect),
1753
+ * and whenever the parent resizes.
1754
+ */
1755
+ fitHostToImage() {
1756
+ if (!this.currentImage || !this.isConnected || !this.canvasHost) return;
1757
+ const e = this.currentImage.naturalWidth, o = this.currentImage.naturalHeight, i = this.style.width, n = this.style.height;
1758
+ this.style.width = "", this.style.height = "";
1759
+ const r = (b) => {
1760
+ if (!b || b === "none") return Number.POSITIVE_INFINITY;
1761
+ const k = nt(b);
1762
+ return Number.isFinite(k) && k > 0 ? k : Number.POSITIVE_INFINITY;
1763
+ }, u = getComputedStyle(this);
1764
+ let l = r(u.maxWidth), a = r(u.maxHeight);
1765
+ const c = this.parentElement, p = c ? getComputedStyle(c) : null;
1766
+ if (c && p && (p.display === "none" || c.clientWidth === 0)) {
1767
+ this.style.width = i, this.style.height = n;
1768
+ return;
1769
+ }
1770
+ const m = (() => {
1771
+ if (!c || !p) return 0;
1772
+ const b = c.clientWidth;
1773
+ return Math.max(0, b - (nt(p.paddingLeft) || 0) - (nt(p.paddingRight) || 0));
1774
+ })();
1775
+ m > 0 ? l = Math.min(l, m) : Number.isFinite(l) || (l = window.innerWidth), Number.isFinite(a) || (a = window.innerHeight), this.style.width = i, this.style.height = n;
1776
+ const d = l, s = a;
1777
+ if (d <= 0 || s <= 0) return;
1778
+ let f, x;
1779
+ if (this.variant === "fixed") {
1780
+ const b = this.fixedFrameAspect(d / s);
1781
+ let k = d, I = d / b;
1782
+ I > s && (I = s, k = s * b), f = Math.floor(k), x = Math.floor(I);
1783
+ } else {
1784
+ const b = Math.min(d / e, s / o, 1);
1785
+ f = Math.floor(e * b), x = Math.floor(o * b);
1786
+ }
1787
+ const S = nt(i), v = nt(n);
1788
+ (Number.isNaN(S) || Math.abs(S - f) >= 1 || Math.abs(v - x) >= 1) && (this.style.width = `${f}px`, this.style.height = `${x}px`);
1789
+ }
1790
+ /**
1791
+ * Aspect ratio (W/H) of the fixed-variant editor box for the current shape.
1792
+ * `free` fills the host (uses the available-area aspect); `square` / `circle`
1793
+ * / `rounded-rect` are square; ratio shapes use their parsed ratio.
1794
+ */
1795
+ fixedFrameAspect(e) {
1796
+ const o = this.cropShape;
1797
+ if (o === "free") return e;
1798
+ if (o === "rounded-rect") return 1;
1799
+ const i = ft(o);
1800
+ return i && i > 0 ? i : e;
1801
+ }
1802
+ dispatch(e, o) {
1803
+ this.dispatchEvent(new CustomEvent(e, { detail: o, bubbles: !0, composed: !0 }));
1804
+ }
1805
+ parseInitialCrop() {
1806
+ const e = this.initialCrop;
1807
+ if (!e) return null;
1808
+ const o = typeof e == "object" ? e : Be(e);
1809
+ if (!o || typeof o != "object") return null;
1810
+ const i = o;
1811
+ return typeof i.x != "number" || typeof i.y != "number" || typeof i.width != "number" || typeof i.height != "number" ? null : { x: i.x, y: i.y, width: i.width, height: i.height };
1812
+ }
1813
+ buildConfig() {
1814
+ return {
1815
+ src: this.src,
1816
+ variant: this.variant,
1817
+ cropShape: this.cropShape,
1818
+ theme: this.theme,
1819
+ initialRotation: this.initialRotation,
1820
+ initialScale: this.initialScale,
1821
+ initialCrop: this.parseInitialCrop(),
1822
+ minScale: this.minScale,
1823
+ maxScale: this.maxScale,
1824
+ minCropSize: this.minCropSize,
1825
+ availableShapes: Fe(this.availableShapes) ?? [...Ft],
1826
+ handleSize: this.handleSize,
1827
+ handleColor: this.handleColor,
1828
+ borderRadius: this.borderRadius,
1829
+ outputType: this.outputType,
1830
+ outputQuality: this.outputQuality,
1831
+ maxOutputWidth: this.maxOutputWidth,
1832
+ maxOutputHeight: this.maxOutputHeight,
1833
+ overlayColor: this.overlayColor,
1834
+ showGrid: this.showGrid,
1835
+ showToolbar: this.showToolbar,
1836
+ showRotateSlider: this.showRotateSlider,
1837
+ showZoomSlider: this.showZoomSlider,
1838
+ showShapeSelector: this.showShapeSelector,
1839
+ showRotateButton: this.showRotateButton,
1840
+ showFlipButton: this.showFlipButton,
1841
+ toolbarPosition: this.toolbarPosition,
1842
+ showBleedMargin: this.showBleedMargin,
1843
+ bleedMarginSize: this.bleedMarginSize,
1844
+ bleedMarginColor: this.bleedMarginColor,
1845
+ enableAnimations: this.enableAnimations,
1846
+ animationSpeed: this.animationSpeed,
1847
+ keyboard: this.keyboard,
1848
+ pinchZoom: this.pinchZoom,
1849
+ wheelZoom: this.wheelZoom
1850
+ };
1851
+ }
1852
+ };
1853
+ Mt.styles = [Le, ze, Ye, Oe];
1854
+ let R = Mt;
1855
+ M([
1856
+ E({ type: String, reflect: !0 })
1857
+ ], R.prototype, "src");
1858
+ M([
1859
+ E({ type: String, attribute: "crop-shape", reflect: !0 })
1860
+ ], R.prototype, "cropShape");
1861
+ M([
1862
+ E({ type: String, reflect: !0 })
1863
+ ], R.prototype, "theme");
1864
+ M([
1865
+ E({ type: Number, attribute: "initial-rotation" })
1866
+ ], R.prototype, "initialRotation");
1867
+ M([
1868
+ E({ type: Number, attribute: "initial-scale" })
1869
+ ], R.prototype, "initialScale");
1870
+ M([
1871
+ E({ type: Number, attribute: "min-scale" })
1872
+ ], R.prototype, "minScale");
1873
+ M([
1874
+ E({ type: Number, attribute: "max-scale" })
1875
+ ], R.prototype, "maxScale");
1876
+ M([
1877
+ E({ type: Number, attribute: "min-crop-size" })
1878
+ ], R.prototype, "minCropSize");
1879
+ M([
1880
+ E({ type: Number, attribute: "handle-size" })
1881
+ ], R.prototype, "handleSize");
1882
+ M([
1883
+ E({ type: Number, attribute: "border-radius" })
1884
+ ], R.prototype, "borderRadius");
1885
+ M([
1886
+ E({ type: Number, attribute: "output-quality" })
1887
+ ], R.prototype, "outputQuality");
1888
+ M([
1889
+ E({ type: Number, attribute: "max-output-width" })
1890
+ ], R.prototype, "maxOutputWidth");
1891
+ M([
1892
+ E({ type: Number, attribute: "max-output-height" })
1893
+ ], R.prototype, "maxOutputHeight");
1894
+ M([
1895
+ E({ type: Number, attribute: "bleed-margin-size" })
1896
+ ], R.prototype, "bleedMarginSize");
1897
+ M([
1898
+ E({ type: Number, attribute: "animation-speed" })
1899
+ ], R.prototype, "animationSpeed");
1900
+ M([
1901
+ E({ type: String, attribute: "handle-color" })
1902
+ ], R.prototype, "handleColor");
1903
+ M([
1904
+ E({ type: String, attribute: "overlay-color" })
1905
+ ], R.prototype, "overlayColor");
1906
+ M([
1907
+ E({ type: String, attribute: "bleed-margin-color" })
1908
+ ], R.prototype, "bleedMarginColor");
1909
+ M([
1910
+ E({ type: String, attribute: "output-type" })
1911
+ ], R.prototype, "outputType");
1912
+ M([
1913
+ E({ type: String, attribute: "toolbar-position", reflect: !0 })
1914
+ ], R.prototype, "toolbarPosition");
1915
+ M([
1916
+ E({ type: String, reflect: !0 })
1917
+ ], R.prototype, "variant");
1918
+ M([
1919
+ E({ attribute: "show-grid", converter: We })
1920
+ ], R.prototype, "showGrid");
1921
+ M([
1922
+ E({ type: Boolean, attribute: "show-toolbar" })
1923
+ ], R.prototype, "showToolbar");
1924
+ M([
1925
+ E({ type: Boolean, attribute: "show-rotate-slider" })
1926
+ ], R.prototype, "showRotateSlider");
1927
+ M([
1928
+ E({ type: Boolean, attribute: "show-zoom-slider" })
1929
+ ], R.prototype, "showZoomSlider");
1930
+ M([
1931
+ E({ type: Boolean, attribute: "show-shape-selector" })
1932
+ ], R.prototype, "showShapeSelector");
1933
+ M([
1934
+ E({ type: Boolean, attribute: "show-rotate-button" })
1935
+ ], R.prototype, "showRotateButton");
1936
+ M([
1937
+ E({ type: Boolean, attribute: "show-flip-button" })
1938
+ ], R.prototype, "showFlipButton");
1939
+ M([
1940
+ E({ type: Boolean, attribute: "show-bleed-margin" })
1941
+ ], R.prototype, "showBleedMargin");
1942
+ M([
1943
+ E({ type: Boolean, attribute: "enable-animations" })
1944
+ ], R.prototype, "enableAnimations");
1945
+ M([
1946
+ E({ type: Boolean })
1947
+ ], R.prototype, "keyboard");
1948
+ M([
1949
+ E({ type: Boolean, attribute: "pinch-zoom" })
1950
+ ], R.prototype, "pinchZoom");
1951
+ M([
1952
+ E({ type: Boolean, attribute: "wheel-zoom" })
1953
+ ], R.prototype, "wheelZoom");
1954
+ M([
1955
+ E({ attribute: "available-shapes" })
1956
+ ], R.prototype, "availableShapes");
1957
+ M([
1958
+ E({ attribute: "initial-crop" })
1959
+ ], R.prototype, "initialCrop");
1960
+ M([
1961
+ E({ attribute: !1 })
1962
+ ], R.prototype, "icons");
1963
+ M([
1964
+ Lt()
1965
+ ], R.prototype, "loading");
1966
+ M([
1967
+ Lt()
1968
+ ], R.prototype, "errorMessage");
1969
+ M([
1970
+ pt("sfx-crop-canvas")
1971
+ ], R.prototype, "canvasHost");
1972
+ M([
1973
+ pt("sfx-crop-toolbar")
1974
+ ], R.prototype, "toolbarHost");
1975
+ M([
1976
+ pt(".sfx-cr-container")
1977
+ ], R.prototype, "containerEl");
1978
+ const Ae = [
1979
+ "src",
1980
+ "variant",
1981
+ "cropShape",
1982
+ "theme",
1983
+ "minScale",
1984
+ "maxScale",
1985
+ "minCropSize",
1986
+ "borderRadius",
1987
+ "handleSize",
1988
+ "handleColor",
1989
+ "overlayColor",
1990
+ "showGrid",
1991
+ "showBleedMargin",
1992
+ "bleedMarginSize",
1993
+ "bleedMarginColor",
1994
+ "enableAnimations",
1995
+ "animationSpeed",
1996
+ "keyboard",
1997
+ "pinchZoom",
1998
+ "wheelZoom"
1999
+ ];
2000
+ function nt(t) {
2001
+ if (!t) return NaN;
2002
+ const e = parseFloat(t);
2003
+ return Number.isFinite(e) ? /^-?\d*\.?\d+(?:px)?$/.test(t.trim()) ? e : NaN : NaN;
2004
+ }
2005
+ function Be(t) {
2006
+ try {
2007
+ return JSON.parse(t);
2008
+ } catch {
2009
+ return null;
2010
+ }
2011
+ }
2012
+ export {
2013
+ Zt as D,
2014
+ R as S,
2015
+ _e as T,
2016
+ Xt as a,
2017
+ X as b,
2018
+ He as c,
2019
+ lt as d,
2020
+ ze as e,
2021
+ Fe as f,
2022
+ ft as g,
2023
+ Ft as h,
2024
+ ut as i,
2025
+ zt as m,
2026
+ Yt as p,
2027
+ Ke as s,
2028
+ $e as t
2029
+ };
2030
+ //# sourceMappingURL=sfx-crop-CEe6OfTZ.js.map