@codingfactory/mediables-vue 2.5.0 → 2.6.2

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 (36) hide show
  1. package/dist/{PixiFrameExporter-BrsHCMHb.cjs → PixiFrameExporter-CUqM394V.cjs} +2 -2
  2. package/dist/{PixiFrameExporter-BrsHCMHb.cjs.map → PixiFrameExporter-CUqM394V.cjs.map} +1 -1
  3. package/dist/{PixiFrameExporter-DFq2mc-y.js → PixiFrameExporter-DJsxS-v6.js} +2 -2
  4. package/dist/{PixiFrameExporter-DFq2mc-y.js.map → PixiFrameExporter-DJsxS-v6.js.map} +1 -1
  5. package/dist/components/ImageEditor/ImageEditor.vue.d.ts +1 -0
  6. package/dist/components/ImageEditorModal.vue.d.ts +2 -0
  7. package/dist/components/MediaManagementView.vue.d.ts +2 -0
  8. package/dist/composables/useFloatingPills.d.ts +4 -0
  9. package/dist/composables/useMediaDeletion.d.ts +66 -0
  10. package/dist/composables/useMediaTrash.d.ts +64 -0
  11. package/dist/editor-BTwIhrcA.cjs +2 -0
  12. package/dist/editor-BTwIhrcA.cjs.map +1 -0
  13. package/dist/{editor-2Q72CZjK.js → editor-CYj5y5bp.js} +1417 -1167
  14. package/dist/editor-CYj5y5bp.js.map +1 -0
  15. package/dist/filters/registry.d.ts +4 -0
  16. package/dist/index-BUrSZVu3.cjs +342 -0
  17. package/dist/index-BUrSZVu3.cjs.map +1 -0
  18. package/dist/{index-CaQc9GBh.js → index-CtHJav8G.js} +12112 -10236
  19. package/dist/index-CtHJav8G.js.map +1 -0
  20. package/dist/index.d.ts +6 -0
  21. package/dist/mediables-vanilla.cjs +1 -1
  22. package/dist/mediables-vanilla.mjs +1 -1
  23. package/dist/mediables-vue.cjs +1 -1
  24. package/dist/mediables-vue.mjs +69 -66
  25. package/dist/render-page/assets/{index-ZZVWF3LA.js → index-y90zwXpc.js} +713 -531
  26. package/dist/render-page/index.html +1 -1
  27. package/dist/style.css +1 -1
  28. package/dist/types/media.d.ts +26 -0
  29. package/dist/types/mediaLibraryPicker.d.ts +1 -0
  30. package/package.json +2 -2
  31. package/dist/editor-2Q72CZjK.js.map +0 -1
  32. package/dist/editor-DjvxEsss.cjs +0 -42
  33. package/dist/editor-DjvxEsss.cjs.map +0 -1
  34. package/dist/index-BTGCVCn6.cjs +0 -342
  35. package/dist/index-BTGCVCn6.cjs.map +0 -1
  36. package/dist/index-CaQc9GBh.js.map +0 -1
@@ -1,10 +1,9 @@
1
- var Ce = Object.defineProperty;
2
- var we = (s, e, t) => e in s ? Ce(s, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : s[e] = t;
3
- var W = (s, e, t) => we(s, typeof e != "symbol" ? e + "" : e, t);
1
+ var Ve = Object.defineProperty;
2
+ var Ue = (s, e, t) => e in s ? Ve(s, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : s[e] = t;
3
+ var J = (s, e, t) => Ue(s, typeof e != "symbol" ? e + "" : e, t);
4
4
  import * as b from "pixi-filters";
5
- import * as w from "pixi.js";
6
- import { GlProgram as Se } from "pixi.js";
7
- class V {
5
+ import * as R from "pixi.js";
6
+ class W {
8
7
  constructor() {
9
8
  this._events = /* @__PURE__ */ new Map();
10
9
  }
@@ -34,7 +33,7 @@ class V {
34
33
  e ? this._events.delete(e) : this._events.clear();
35
34
  }
36
35
  }
37
- class ve extends V {
36
+ class je extends W {
38
37
  constructor() {
39
38
  super(), this._state = {
40
39
  // Image state
@@ -93,10 +92,10 @@ class ve extends V {
93
92
  const i = this.get(e);
94
93
  if (e.includes(".")) {
95
94
  const r = e.split("."), a = r.pop();
96
- let o = this._state;
97
- for (const n of r)
98
- o[n] === void 0 && (o[n] = {}), o = o[n];
99
- o[a] = t;
95
+ let n = this._state;
96
+ for (const o of r)
97
+ n[o] === void 0 && (n[o] = {}), n = n[o];
98
+ n[a] = t;
100
99
  } else
101
100
  this._state[e] = t;
102
101
  this.emit(`change:${e}`, { value: t, old: i }), this.emit("change", { key: e, value: t, old: i });
@@ -189,10 +188,10 @@ class ve extends V {
189
188
  this.set("isDarkMode", this._state.theme === "dark");
190
189
  }
191
190
  }
192
- function ke() {
193
- return new ve();
191
+ function qe() {
192
+ return new je();
194
193
  }
195
- class Pe extends V {
194
+ class He extends W {
196
195
  constructor() {
197
196
  super(), this.app = null, this.sprite = null, this.originalTexture = null, this.baseTexture = null, this.fitScale = 1, this.zoom = 1, this._container = null, this._mountPromise = null;
198
197
  }
@@ -210,8 +209,8 @@ class Pe extends V {
210
209
  * canvas getter which throws when renderer is undefined.
211
210
  */
212
211
  _getCssSize() {
213
- var r, a, o, n, l, c;
214
- const e = (a = (r = this.app) == null ? void 0 : r.renderer) == null ? void 0 : a.canvas, t = (e == null ? void 0 : e.clientWidth) ?? ((n = (o = this.app) == null ? void 0 : o.screen) == null ? void 0 : n.width) ?? 0, i = (e == null ? void 0 : e.clientHeight) ?? ((c = (l = this.app) == null ? void 0 : l.screen) == null ? void 0 : c.height) ?? 0;
212
+ var r, a, n, o, l, c;
213
+ const e = (a = (r = this.app) == null ? void 0 : r.renderer) == null ? void 0 : a.canvas, t = (e == null ? void 0 : e.clientWidth) ?? ((o = (n = this.app) == null ? void 0 : n.screen) == null ? void 0 : o.width) ?? 0, i = (e == null ? void 0 : e.clientHeight) ?? ((c = (l = this.app) == null ? void 0 : l.screen) == null ? void 0 : c.height) ?? 0;
215
214
  return { w: t, h: i };
216
215
  }
217
216
  /**
@@ -285,29 +284,33 @@ class Pe extends V {
285
284
  * Mount PIXI application to container
286
285
  * @param {HTMLElement} container
287
286
  * @param {number} backgroundColor
287
+ * @param {Object} [options]
288
+ * @param {number} [options.backgroundAlpha=1] - 0 makes the canvas transparent
289
+ * so a host-rendered background (e.g. CSS checkerboard) shows through.
288
290
  */
289
- async mount(e, t = 16777215) {
291
+ async mount(e, t = 16777215, i = {}) {
290
292
  if (!e) return;
291
293
  this._container = e;
292
- const i = async () => {
293
- var l;
294
- const r = window.PIXI;
295
- if (!r)
294
+ const r = async () => {
295
+ var d;
296
+ const a = window.PIXI;
297
+ if (!a)
296
298
  throw new Error("PIXI.js not found. Please ensure PIXI is loaded globally.");
297
- (l = r.Assets) != null && l.setPreferences && r.Assets.setPreferences({ crossOrigin: "anonymous" });
298
- const a = e.clientWidth || 600, o = e.clientHeight || 400;
299
- this.app = new r.Application(), await this.app.init({
300
- width: a,
299
+ (d = a.Assets) != null && d.setPreferences && a.Assets.setPreferences({ crossOrigin: "anonymous" });
300
+ const n = e.clientWidth || 600, o = e.clientHeight || 400, l = typeof i.backgroundAlpha == "number" ? i.backgroundAlpha : 1;
301
+ this.app = new a.Application(), await this.app.init({
302
+ width: n,
301
303
  height: o,
302
304
  backgroundColor: t,
305
+ backgroundAlpha: l,
303
306
  antialias: !0,
304
307
  autoDensity: !0,
305
308
  resolution: window.devicePixelRatio || 1
306
309
  }), e.appendChild(this.app.canvas);
307
- const n = this.app.canvas;
308
- n.classList.add("pixi-canvas"), n.style.width = "100%", n.style.height = "100%", n.style.transform = "translateZ(0)", n.style.willChange = "transform", n.setAttribute("role", "img"), n.setAttribute("aria-label", "Image editor canvas — use toolbar controls to edit the image"), this.emit("mounted", { width: a, height: o });
310
+ const c = this.app.canvas;
311
+ c.classList.add("pixi-canvas"), c.style.width = "100%", c.style.height = "100%", c.style.transform = "translateZ(0)", c.style.willChange = "transform", c.setAttribute("role", "img"), c.setAttribute("aria-label", "Image editor canvas — use toolbar controls to edit the image"), this.emit("mounted", { width: n, height: o });
309
312
  };
310
- this._mountPromise = i(), await this._mountPromise;
313
+ this._mountPromise = r(), await this._mountPromise;
311
314
  }
312
315
  /**
313
316
  * Load an image texture
@@ -322,72 +325,159 @@ class Pe extends V {
322
325
  if (!r)
323
326
  return !1;
324
327
  this.originalTexture = r, this.baseTexture = r, this.sprite && (this.app.stage.removeChild(this.sprite), this.sprite.destroy()), this.sprite = new t.Sprite(r), this.app.stage.addChild(this.sprite), this.fitScale = this.getFitScaleFor(r), this.zoom = 1;
325
- const { w: a, h: o } = this._getCssSize();
326
- if (this.applyViewTransform({ center: { x: a / 2, y: o / 2 } }), await this._waitForNextFrame(), !((d = this.app) != null && d.renderer)) return !1;
327
- const n = this.getFitScaleFor(r);
328
- return Math.abs(n - this.fitScale) / Math.max(1e-6, n) > 0.02 && (this.fitScale = n, this.applyViewTransform({ center: { x: a / 2, y: o / 2 } })), this.render(), this.emit("textureLoaded", { width: r.width, height: r.height }), !0;
328
+ const { w: a, h: n } = this._getCssSize();
329
+ if (this.applyViewTransform({ center: { x: a / 2, y: n / 2 } }), await this._waitForNextFrame(), !((d = this.app) != null && d.renderer)) return !1;
330
+ const o = this.getFitScaleFor(r);
331
+ return Math.abs(o - this.fitScale) / Math.max(1e-6, o) > 0.02 && (this.fitScale = o, this.applyViewTransform({ center: { x: a / 2, y: n / 2 } })), this.render(), this.emit("textureLoaded", { width: r.width, height: r.height }), !0;
329
332
  }
330
333
  /**
331
- * Export the current image with filters applied
334
+ * Export the current image with filters applied.
335
+ *
332
336
  * @param {string} format - 'png' or 'jpeg'
333
337
  * @param {number} quality - Quality for jpeg (0-1)
334
- * @param {number} maxEdge - Maximum edge size (0 for original)
338
+ * @param {number} maxEdge - Maximum edge size in pixels (0 for original)
335
339
  * @param {boolean} dontUpscale - Don't upscale smaller images
340
+ * @param {number} [maxPixels=0] - Max total pixel count (width*height). 0 disables.
341
+ * Backend API often limits payload size (blowglass caps at 8M pixels); set this
342
+ * to keep the export under that cap while preserving aspect ratio.
336
343
  * @returns {string|null} Data URL
337
344
  */
338
- exportImage(e = "png", t = 0.92, i = 0, r = !0) {
339
- var S;
340
- if (!((S = this.app) != null && S.renderer) || !this.originalTexture || !this.sprite)
345
+ exportImage(e = "png", t = 0.92, i = 0, r = !0, a = 0) {
346
+ var T;
347
+ if (!((T = this.app) != null && T.renderer) || !this.originalTexture || !this.sprite)
341
348
  return null;
342
- const a = window.PIXI, o = Math.round(this.originalTexture.width), n = Math.round(this.originalTexture.height);
343
- if (o <= 0 || n <= 0)
349
+ const n = window.PIXI, o = Math.round(this.originalTexture.width), l = Math.round(this.originalTexture.height);
350
+ if (o <= 0 || l <= 0)
344
351
  return null;
345
- let l = o, c = n;
346
- if (i > 0) {
347
- const M = Math.max(o, n);
348
- let F = i / M;
349
- r && (F = Math.min(1, F)), l = Math.round(o * F), c = Math.round(n * F);
350
- }
351
- const d = this.sprite, h = d.x, p = d.y, f = d.scale.x, _ = d.scale.y, g = d.width, y = d.height;
352
- if (g <= 0 || y <= 0)
352
+ const c = this.sprite.width, d = this.sprite.height;
353
+ if (c <= 0 || d <= 0)
353
354
  return null;
354
- const v = l / g, x = c / y;
355
+ const h = c / o, u = h > 0 ? 1 / h : 1, f = [];
356
+ if (Array.isArray(this.sprite.filters)) {
357
+ for (const y of this.sprite.filters)
358
+ if (y)
359
+ if (typeof y.createExportFilter == "function") {
360
+ const C = y.createExportFilter({ previewToNativeScale: u });
361
+ C && f.push(C);
362
+ } else
363
+ f.push(y);
364
+ }
365
+ let _ = 0;
366
+ for (const y of f) {
367
+ const C = typeof y.getExportPadding == "function" ? Number(y.getExportPadding()) || 0 : typeof y._exportPadding == "number" ? y._exportPadding : typeof y.padding == "number" ? y.padding : 0;
368
+ C > 0 && (_ += C);
369
+ }
370
+ const g = Math.max(Math.ceil(_), 64), x = (y) => {
371
+ var k, w;
372
+ const C = Math.ceil(o + 2 * y), v = Math.ceil(l + 2 * y), M = new n.Container(), F = new n.Sprite(this.originalTexture);
373
+ F.x = y, F.y = y, F.scale.set(1, 1), f.length > 0 && (F.filters = f, F.filterArea = new n.Rectangle(0, 0, o, l)), M.addChild(F);
374
+ const I = n.RenderTexture.create({
375
+ width: C,
376
+ height: v,
377
+ resolution: 1
378
+ });
379
+ try {
380
+ this.app.renderer.render({
381
+ container: M,
382
+ target: I,
383
+ clear: !0,
384
+ clearColor: [0, 0, 0, 0]
385
+ });
386
+ const S = (w = (k = this.app.renderer.extract) == null ? void 0 : k.canvas) == null ? void 0 : w.call(k, I);
387
+ return S ? { canvas: S, width: C, height: v, margin: y } : null;
388
+ } finally {
389
+ F.filters = null, M.removeChildren(), F.destroy({ children: !1, texture: !1, textureSource: !1 }), M.destroy({ children: !1 }), I.destroy(!0);
390
+ }
391
+ }, A = (y, C, v) => {
392
+ const M = typeof y.getContext == "function" ? y.getContext("2d") : null;
393
+ if (!M) return null;
394
+ let F;
395
+ try {
396
+ F = M.getImageData(0, 0, C, v).data;
397
+ } catch {
398
+ return null;
399
+ }
400
+ const I = 1;
401
+ let k = C, w = v, S = -1, Z = -1;
402
+ const ce = 4, Be = C * ce;
403
+ for (let Y = 0; Y < v; Y++) {
404
+ const De = Y * Be;
405
+ for (let L = 0; L < C; L++)
406
+ F[De + L * ce + 3] >= I && (L < k && (k = L), L > S && (S = L), Y < w && (w = Y), Y > Z && (Z = Y));
407
+ }
408
+ if (S < 0) return null;
409
+ const Ye = S - k + 1, Oe = Z - w + 1, Le = k === 0 || w === 0 || S === C - 1 || Z === v - 1;
410
+ return { x: k, y: w, width: Ye, height: Oe, touchesEdge: Le };
411
+ };
355
412
  let P = null;
356
413
  try {
357
- if (d.x = 0, d.y = 0, d.scale.x = f * v, d.scale.y = _ * x, P = a.RenderTexture.create({
358
- width: Math.ceil(l),
359
- height: Math.ceil(c),
360
- resolution: 1
361
- }), this.app.renderer.render({ container: this.app.stage, target: P }), !this.app.renderer.extract)
414
+ let y = x(g);
415
+ if (!y)
362
416
  return null;
363
- const M = this.app.renderer.extract.canvas(P);
364
- if (!M)
417
+ let C = A(y.canvas, y.width, y.height);
418
+ if (!C)
365
419
  return null;
366
- let F = null;
367
- if (typeof M.toDataURL == "function")
368
- F = M.toDataURL(`image/${e}`, t);
369
- else if (typeof M.getContext == "function") {
370
- const B = document.createElement("canvas");
371
- B.width = M.width, B.height = M.height;
372
- const U = B.getContext("2d");
373
- U && (U.drawImage(M, 0, 0), F = B.toDataURL(`image/${e}`, t));
420
+ if (C.touchesEdge && g < o && g < l) {
421
+ const k = Math.max(g * 4, 256), w = x(k);
422
+ if (w) {
423
+ const S = A(w.canvas, w.width, w.height);
424
+ S && !S.touchesEdge ? (y = w, C = S) : (y = w, C = S ?? C);
425
+ }
426
+ }
427
+ let v = C.width, M = C.height;
428
+ if (i > 0) {
429
+ const k = Math.max(v, M);
430
+ let w = i / k;
431
+ r && (w = Math.min(1, w)), v = Math.max(1, Math.round(v * w)), M = Math.max(1, Math.round(M * w));
374
432
  }
375
- return F || null;
433
+ if (a > 0 && v * M > a) {
434
+ const k = Math.sqrt(a / (v * M));
435
+ v = Math.max(1, Math.floor(v * k)), M = Math.max(1, Math.floor(M * k));
436
+ }
437
+ const F = document.createElement("canvas");
438
+ F.width = v, F.height = M;
439
+ const I = F.getContext("2d");
440
+ return I ? (I.drawImage(
441
+ y.canvas,
442
+ C.x,
443
+ C.y,
444
+ C.width,
445
+ C.height,
446
+ 0,
447
+ 0,
448
+ v,
449
+ M
450
+ ), P = F.toDataURL(`image/${e}`, t), this._lastExportDimensions = { width: v, height: M }, P || null) : null;
376
451
  } catch {
377
452
  return null;
378
- } finally {
379
- d.x = h, d.y = p, d.scale.x = f, d.scale.y = _, P && P.destroy(!0);
380
453
  }
381
454
  }
382
455
  /**
383
- * Get the actual export dimensions (texture size, not display size).
456
+ * Get the actual export dimensions at the current filter state.
457
+ *
458
+ * When an export has been performed, returns the exact trimmed dimensions
459
+ * from that export. Otherwise falls back to source texture size plus a
460
+ * rough filter-padding estimate — the real dimensions are only known for
461
+ * certain after exportImage() runs the bbox scan.
462
+ *
384
463
  * @returns {{ width: number, height: number }}
385
464
  */
386
465
  getExportDimensions() {
387
- const e = this.originalTexture;
466
+ var n;
467
+ if (this._lastExportDimensions)
468
+ return { ...this._lastExportDimensions };
469
+ const e = this.originalTexture, t = Math.round((e == null ? void 0 : e.width) || 0), i = Math.round((e == null ? void 0 : e.height) || 0);
470
+ let r = 0;
471
+ const a = (n = this.sprite) == null ? void 0 : n.filters;
472
+ if (Array.isArray(a))
473
+ for (const o of a) {
474
+ if (!o) continue;
475
+ const l = typeof o._exportPadding == "number" ? o._exportPadding : typeof o.padding == "number" ? o.padding : 0;
476
+ l > r && (r = l);
477
+ }
388
478
  return {
389
- width: Math.round((e == null ? void 0 : e.width) || 0),
390
- height: Math.round((e == null ? void 0 : e.height) || 0)
479
+ width: t + 2 * r,
480
+ height: i + 2 * r
391
481
  };
392
482
  }
393
483
  /**
@@ -399,8 +489,8 @@ class Pe extends V {
399
489
  async exportBlob(e = "png", t = 0.92) {
400
490
  const i = this.exportImage(e, t);
401
491
  if (!i) return null;
402
- const a = await (await fetch(i)).blob(), o = this.getExportDimensions();
403
- return { blob: a, width: o.width, height: o.height };
492
+ const a = await (await fetch(i)).blob(), n = this.getExportDimensions();
493
+ return { blob: a, width: n.width, height: n.height };
404
494
  }
405
495
  /**
406
496
  * Resize renderer to container
@@ -454,23 +544,64 @@ class Pe extends V {
454
544
  this.sprite = null, this.originalTexture = null, this.baseTexture = null, this._container = null, this.removeAllListeners();
455
545
  }
456
546
  }
457
- const Me = {
458
- adjust: ["adjust", "advanced"],
459
- // adjustment, adjustmentAdvanced, alpha, colorMatrix
460
- blur: ["blur"],
461
- // blur, kawaseBlur, motionBlur, radialBlur, etc.
462
- color: ["color"],
463
- // colorOverlay, grayscale, hslAdjustment, etc.
464
- effects: ["effects"],
465
- // noise, vignette, pixelate, dropShadow, etc.
466
- distortion: ["distortion"],
467
- // twist, bulgePinch, displacement, etc.
468
- light: ["light"],
469
- // bloom, glow, godray, advancedBloom
470
- stylize: ["stylize"]
471
- // ascii, crt, crossHatch, dot, emboss
472
- };
473
- class Fe extends V {
547
+ const Me = '<svg viewBox="0 0 512 512" width="20" height="20"><path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="48" d="M328 112L184 256l144 144"/></svg>', Pe = '<svg viewBox="0 0 512 512" width="20" height="20"><path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="48" d="M184 112l144 144-144 144"/></svg>', $e = '<svg viewBox="0 0 512 512" width="20" height="20"><path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="32" d="M221.09 64a157.09 157.09 0 10157.09 157.09A157.1 157.1 0 00221.09 64z"/><path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="32" d="M338.29 338.29L448 448M256 184v74m-37-37h74"/></svg>', We = '<svg viewBox="0 0 512 512" width="20" height="20"><path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="32" d="M221.09 64a157.09 157.09 0 10157.09 157.09A157.1 157.1 0 00221.09 64z"/><path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="32" d="M338.29 338.29L448 448M184 221h74"/></svg>', Ze = '<svg viewBox="0 0 512 512" width="20" height="20"><path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="32" d="M432 320v112H320M80 192V80h112M320 80h112v112M192 432H80V320"/></svg>', Ge = '<svg viewBox="0 0 512 512" width="20" height="20"><path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="32" d="M262.29 192.31a64 64 0 1057.4 57.4 64.13 64.13 0 00-57.4-57.4z"/><path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="32" d="M416.39 256a154.34 154.34 0 01-1.53 20.79l45.21 35.46a10.81 10.81 0 012.45 13.75l-42.77 74a10.81 10.81 0 01-13.14 4.59l-44.9-18.08a16.11 16.11 0 00-15.17 1.75A164.48 164.48 0 01325 400.8a15.94 15.94 0 00-8.82 12.14l-6.73 47.89a11.08 11.08 0 01-10.68 9.17h-85.54a11.11 11.11 0 01-10.69-8.87l-6.72-47.82a16.07 16.07 0 00-9-12.22 155.3 155.3 0 01-21.46-12.57 16 16 0 00-15.11-1.71l-44.89 18.07a10.81 10.81 0 01-13.14-4.58l-42.77-74a10.8 10.8 0 012.45-13.75l38.21-30a16.05 16.05 0 006-14.08c-.36-4.17-.58-8.33-.58-12.5s.21-8.27.58-12.35a16 16 0 00-6.07-13.94l-38.19-30A10.81 10.81 0 0149.48 186l42.77-74a10.81 10.81 0 0113.14-4.59l44.9 18.08a16.11 16.11 0 0015.17-1.75A164.48 164.48 0 01187 111.2a15.94 15.94 0 008.82-12.14l6.73-47.89A11.08 11.08 0 01213.23 42h85.54a11.11 11.11 0 0110.69 8.87l6.72 47.82a16.07 16.07 0 009 12.22 155.3 155.3 0 0121.46 12.57 16 16 0 0015.11 1.71l44.89-18.07a10.81 10.81 0 0113.14 4.58l42.77 74a10.8 10.8 0 01-2.45 13.75l-38.21 30a16.05 16.05 0 00-6.05 14.08c.33 4.14.55 8.3.55 12.47z"/></svg>', Ke = '<svg viewBox="0 0 512 512" width="20" height="20"><path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="32" d="M400 320c0 88.37-55.63 144-144 144s-144-55.63-144-144c0-94.83 103.23-222.85 134.89-259.88a12 12 0 0118.23 0C296.77 97.15 400 225.17 400 320z"/><path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="32" d="M344 328a72 72 0 01-72 72"/></svg>', Qe = '<svg viewBox="0 0 512 512" width="20" height="20"><path fill="none" stroke="currentColor" stroke-miterlimit="10" stroke-width="32" d="M430.11 347.9c-6.6-6.1-16.3-7.6-24.6-9-11.5-1.9-15.9-4-22.6-10-14.3-12.7-14.3-31.1 0-43.8l30.3-26.9c46.4-41 46.4-108.2 0-149.2-34.2-30.1-80.1-45-127.8-45-55.7 0-113.9 20.3-158.8 60.1-83.5 73.8-83.5 194.7 0 268.5 41.5 36.7 97.5 55 152.9 55.4h1.7c55.4 0 110-17.9 148.8-52.4 14.4-12.7 11.99-36.6.1-47.7z"/><circle cx="144" cy="208" r="32"/><circle cx="152" cy="311" r="32"/><circle cx="224" cy="144" r="32"/><circle cx="256" cy="367" r="32"/><circle cx="328" cy="144" r="32"/></svg>', Je = '<svg viewBox="0 0 512 512" width="20" height="20"><path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="32" d="M259.92 262.91L216.4 149.77a9 9 0 00-16.8 0l-43.52 113.14a9 9 0 01-5.17 5.17L37.77 311.6a9 9 0 000 16.8l113.14 43.52a9 9 0 015.17 5.17l43.52 113.14a9 9 0 0016.8 0l43.52-113.14a9 9 0 015.17-5.17l113.14-43.52a9 9 0 000-16.8l-113.14-43.52a9 9 0 01-5.17-5.17zM108 68L88 16 68 68 16 88l52 20 20 52 20-52 52-20-52-20zM426.67 117.33L400 48l-26.67 69.33L304 144l69.33 26.67L400 240l26.67-69.33L496 144l-69.33-26.67z"/></svg>', et = '<svg viewBox="0 0 512 512" width="20" height="20"><path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="32" d="M176 112l80-80 80 80M255.98 32l.02 448M176 400l80 80 80-80M400 176l80 80-80 80M112 176l-80 80 80 80M32 256h448"/></svg>', tt = '<svg viewBox="0 0 512 512" width="20" height="20"><path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="32" d="M315.27 33L96 304h128l-31.51 173.23a2.36 2.36 0 002.33 2.77h0a2.36 2.36 0 001.89-.95L416 208H288l31.66-173.25a2.45 2.45 0 00-2.44-2.75h0a2.42 2.42 0 00-1.95 1z"/></svg>', ke = '<svg viewBox="0 0 512 512" width="20" height="20"><path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="32" d="M144 48v272a48 48 0 0048 48h272"/><path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="32" d="M368 464V192a48 48 0 00-48-48H48"/></svg>', it = '<svg viewBox="0 0 512 512" width="20" height="20"><path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="32" d="M380.93 57.37A32 32 0 00358.3 48H94.22A46.21 46.21 0 0048 94.22v323.56A46.21 46.21 0 0094.22 464h323.56A46.36 46.36 0 00464 417.78V153.7a32 32 0 00-9.37-22.63zM256 416a64 64 0 1164-64 63.92 63.92 0 01-64 64zm48-224H112a16 16 0 01-16-16v-64a16 16 0 0116-16h192a16 16 0 0116 16v64a16 16 0 01-16 16z"/></svg>', oe = '<svg viewBox="0 0 512 512" width="20" height="20"><path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="32" d="M368 368L144 144M368 144L144 368"/></svg>', Fe = '<svg viewBox="0 0 512 512" width="20" height="20"><path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="32" d="M320 146s24.36-12-64-12a160 160 0 10160 160"/><path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="32" d="M256 58l80 80-80 80"/></svg>', rt = '<svg viewBox="0 0 512 512" width="20" height="20"><path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="32" d="M112 112l20 320c.95 18.49 14.4 32 32 32h184c17.67 0 30.87-13.51 32-32l20-320"/><path fill="none" stroke="currentColor" stroke-linecap="round" stroke-miterlimit="10" stroke-width="32" d="M80 112h352"/><path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="32" d="M192 112V72h0a23.93 23.93 0 0124-24h80a23.93 23.93 0 0124 24h0v40M256 176v224M184 176l8 224M328 176l-8 224"/></svg>', st = '<svg viewBox="0 0 512 512" width="20" height="20"><path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="32" d="M64 192v-72a40 40 0 0140-40h75.89a40 40 0 0122.19 6.72l27.84 18.56a40 40 0 0022.19 6.72H408a40 40 0 0140 40v40"/><path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="32" d="M479.9 226.55L463.68 392a40 40 0 01-39.93 40H88.25a40 40 0 01-39.93-40L32.1 226.55A32 32 0 0164 192h384.1a32 32 0 0131.8 34.55z"/></svg>', se = '<svg viewBox="0 0 512 512" width="20" height="20"><path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="32" d="M416 128L192 384l-96-96"/></svg>', at = '<svg viewBox="0 0 512 512" width="20" height="20"><rect x="64" y="64" width="384" height="384" rx="48" fill="none" stroke="currentColor" stroke-linejoin="round" stroke-width="32"/></svg>', nt = '<svg viewBox="0 0 512 512" width="20" height="20"><circle cx="256" cy="256" r="208" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="32"/></svg>', ot = '<svg viewBox="0 0 512 512" width="20" height="20"><path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="32" d="M80 96h64l64 320h64l64-160h96"/></svg>', he = '<svg viewBox="0 0 512 512" width="20" height="20"><path fill="none" stroke="currentColor" stroke-linecap="round" stroke-miterlimit="10" stroke-width="32" d="M256 48v48M256 416v48M403.08 108.92l-33.94 33.94M142.86 369.14l-33.94 33.94M464 256h-48M96 256H48M403.08 403.08l-33.94-33.94M142.86 142.86l-33.94-33.94"/><circle cx="256" cy="256" r="80" fill="none" stroke="currentColor" stroke-linecap="round" stroke-miterlimit="10" stroke-width="32"/></svg>', de = '<svg viewBox="0 0 512 512" width="20" height="20"><path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="32" d="M160 136c0-30.62 4.51-61.61 16-88C99.57 81.27 48 159.32 48 248c0 119.29 96.71 216 216 216 88.68 0 166.73-51.57 200-128-26.39 11.49-57.38 16-88 16-119.29 0-216-96.71-216-216z"/></svg>', lt = '<svg viewBox="0 0 512 512" width="20" height="20"><path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="32" d="M436 80H76a44.05 44.05 0 00-44 44v264a44.05 44.05 0 0044 44h360a44.05 44.05 0 0044-44V124a44.05 44.05 0 00-44-44z"/><circle cx="256" cy="256" r="80" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="32"/><path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="32" d="M220 80v56M292 80v56M220 376v56M292 376v56M80 144h56M80 224h56M80 304h56M376 144h56M376 224h56M376 304h56"/></svg>', le = [
548
+ {
549
+ id: "adjust",
550
+ name: "Adjust",
551
+ icon: Ge,
552
+ registryCategories: ["adjust", "advanced"]
553
+ // adjustment, adjustmentAdvanced, alpha, colorMatrix
554
+ },
555
+ {
556
+ id: "blur",
557
+ name: "Blur",
558
+ icon: Ke,
559
+ registryCategories: ["blur"]
560
+ },
561
+ {
562
+ id: "color",
563
+ name: "Color",
564
+ icon: Qe,
565
+ registryCategories: ["color"]
566
+ },
567
+ {
568
+ id: "effects",
569
+ name: "Effects",
570
+ icon: Je,
571
+ registryCategories: ["effects"]
572
+ },
573
+ {
574
+ id: "distortion",
575
+ name: "Distortion",
576
+ icon: et,
577
+ registryCategories: ["distortion"]
578
+ },
579
+ {
580
+ id: "light",
581
+ name: "Light",
582
+ icon: tt,
583
+ registryCategories: ["light"]
584
+ },
585
+ {
586
+ id: "stylize",
587
+ name: "Stylize",
588
+ icon: lt,
589
+ registryCategories: ["stylize"]
590
+ },
591
+ {
592
+ id: "crop",
593
+ name: "Crop",
594
+ icon: ke
595
+ }
596
+ ], ct = Object.fromEntries(
597
+ le.filter((s) => Array.isArray(s.registryCategories) && s.registryCategories.length > 0).map((s) => [s.id, s.registryCategories])
598
+ ), ht = Object.fromEntries(
599
+ le.filter((s) => Array.isArray(s.registryCategories)).flatMap((s) => s.registryCategories.map((e) => [e, s.id]))
600
+ );
601
+ function dt(s) {
602
+ return ct[s] || [s];
603
+ }
604
+ class ut extends W {
474
605
  constructor(e, t) {
475
606
  super(), this.state = e, this.renderer = t, this.instances = {}, this._filterRegistry = null;
476
607
  }
@@ -505,11 +636,11 @@ class Fe extends V {
505
636
  */
506
637
  getFiltersByCategory(e) {
507
638
  if (!this._filterRegistry) return [];
508
- const t = Me[e] || [e], i = [], r = /* @__PURE__ */ new Set();
639
+ const t = dt(e), i = [], r = /* @__PURE__ */ new Set();
509
640
  for (const a of t) {
510
- const o = this._filterRegistry.getFiltersByCategory(a) || [];
511
- for (const n of o)
512
- r.has(n.id) || (r.add(n.id), i.push(n));
641
+ const n = this._filterRegistry.getFiltersByCategory(a) || [];
642
+ for (const o of n)
643
+ r.has(o.id) || (r.add(o.id), i.push(o));
513
644
  }
514
645
  return i;
515
646
  }
@@ -521,6 +652,25 @@ class Fe extends V {
521
652
  _normalizeValue(e) {
522
653
  return Array.isArray(e) ? e.length > 0 && typeof e[0] == "object" ? e : Number(e[0] ?? 0) : typeof e == "string" ? e.startsWith("#") ? e : e.trim() === "" ? 0 : Number(e) : e;
523
654
  }
655
+ /**
656
+ * Get a deep property from an object.
657
+ * Returns undefined if any segment along the path is missing.
658
+ * @param {Object} target
659
+ * @param {string} path
660
+ * @returns {*}
661
+ */
662
+ _getDeepProp(e, t) {
663
+ if (!e || !t) return;
664
+ if (!t.includes(".") && !t.includes("["))
665
+ return e[t];
666
+ const i = t.replace(/\[(\d+)\]/g, ".$1").split(".").filter(Boolean);
667
+ let r = e;
668
+ for (const a of i) {
669
+ if (r == null) return;
670
+ r = r[a];
671
+ }
672
+ return r;
673
+ }
524
674
  /**
525
675
  * Set a deep property on an object
526
676
  * @param {Object} target
@@ -535,32 +685,45 @@ class Fe extends V {
535
685
  }
536
686
  const r = t.replace(/\[(\d+)\]/g, ".$1").split(".").filter(Boolean);
537
687
  let a = e;
538
- for (let n = 0; n < r.length - 1; n++) {
539
- const l = r[n];
688
+ for (let o = 0; o < r.length - 1; o++) {
689
+ const l = r[o];
540
690
  if (!(l in a) || (a = a[l], a == null)) return;
541
691
  }
542
- const o = r[r.length - 1];
543
- a[o] = i;
692
+ const n = r[r.length - 1];
693
+ a[n] = i;
544
694
  }
545
695
  /**
546
- * Initialize filter values from definition defaults
696
+ * Initialize filter values from definition defaults.
697
+ * Seeds BOTH defaultParams (e.g. colorStops) and control defaults so that
698
+ * filters with dynamic parameters not backed by a static control still have
699
+ * their state populated.
547
700
  * @param {string} filterId
548
701
  */
549
702
  initializeValues(e) {
550
703
  const t = this.getFilterDef(e);
551
- t && t.controls.forEach((i) => {
552
- const r = this.state.getFilterValues(e);
553
- i.id in r || this.state.setFilterValue(e, i.id, i.default);
704
+ if (!t) return;
705
+ const i = this.state.getFilterValues(e), r = new Set((t.controls || []).map((a) => a.id));
706
+ if (t.defaultParams)
707
+ for (const [a, n] of Object.entries(t.defaultParams))
708
+ !r.has(a) && !(a in i) && this.state.setFilterValue(e, a, n);
709
+ t.controls && t.controls.forEach((a) => {
710
+ a.id in i || this.state.setFilterValue(e, a.id, a.default);
554
711
  });
555
712
  }
556
713
  /**
557
- * Reset all filter values to their defaults (unconditionally)
714
+ * Reset all filter values to their defaults (unconditionally).
715
+ * Resets BOTH defaultParams and control defaults.
558
716
  * @param {string} filterId
559
717
  */
560
718
  resetValues(e) {
561
719
  const t = this.getFilterDef(e);
562
- t && t.controls.forEach((i) => {
563
- this.state.setFilterValue(e, i.id, i.default);
720
+ if (!t) return;
721
+ const i = new Set((t.controls || []).map((r) => r.id));
722
+ if (t.defaultParams)
723
+ for (const [r, a] of Object.entries(t.defaultParams))
724
+ i.has(r) || this.state.setFilterValue(e, r, a);
725
+ t.controls && t.controls.forEach((r) => {
726
+ this.state.setFilterValue(e, r.id, r.default);
564
727
  });
565
728
  }
566
729
  /**
@@ -572,21 +735,62 @@ class Fe extends V {
572
735
  this.state.toggleFilter(e, t), t ? this.initializeValues(e) : delete this.instances[e], this.applyFilters(), this.emit("filterToggled", { filterId: e, enabled: t });
573
736
  }
574
737
  /**
575
- * Update a filter control value
738
+ * Update a filter control value.
739
+ *
740
+ * The `controlId` may be either a static control id (from def.controls) or a
741
+ * dynamic path (e.g. 'colorStops[0].color') produced by a filter's
742
+ * getDynamicControls(). Static control ids are stored in state keyed by the
743
+ * control id. Dynamic paths are NOT stored as flat path keys — instead, we
744
+ * apply them to the live instance and then sync the filter's serializable
745
+ * params back into state, so recreation via applyFilters() rebuilds from
746
+ * the canonical shape (e.g. a colorStops array, not 'colorStops[0].color').
747
+ *
748
+ * Returns true when the filter was updated in-place. Returns false when the
749
+ * caller should invoke applyFilters() to recreate the filter from state —
750
+ * this happens when the property target is a method (which would be
751
+ * silently corrupted by a direct write) or when the property doesn't exist.
752
+ *
576
753
  * @param {string} filterId
577
- * @param {string} controlId
754
+ * @param {string} controlId - Static control id or dynamic property path
578
755
  * @param {*} value
579
- * @returns {boolean} True if updated in-place
756
+ * @returns {boolean} True if updated in-place, false if caller must recreate
580
757
  */
581
758
  updateValue(e, t, i) {
582
- const r = this._normalizeValue(i);
583
- this.state.setFilterValue(e, t, r);
584
- const a = this.instances[e];
585
- if (a) {
586
- const o = this.getFilterDef(e), n = o == null ? void 0 : o.controls.find((c) => c.id === t), l = (n == null ? void 0 : n.property) || t;
587
- return typeof a.updateUIParam == "function" ? (a.updateUIParam(l, r), !0) : (this._setDeepProp(a, l, r), a.uniforms && l in a.uniforms && (a.uniforms[l] = r), !0);
759
+ const r = this._normalizeValue(i), a = this.getFilterDef(e), n = a == null ? void 0 : a.controls.find((h) => h.id === t), o = !n && (t.includes("[") || t.includes("."));
760
+ o || this.state.setFilterValue(e, t, r);
761
+ const l = this.instances[e];
762
+ if (!l) return !1;
763
+ const c = (n == null ? void 0 : n.property) || t;
764
+ if (typeof l.updateUIParam == "function") {
765
+ if (l.updateUIParam(c, r), o && typeof l.getSerializableParams == "function") {
766
+ const h = l.getSerializableParams();
767
+ for (const [u, f] of Object.entries(h))
768
+ this.state.setFilterValue(e, u, f);
769
+ }
770
+ return !0;
771
+ }
772
+ const d = this._getDeepProp(l, c);
773
+ return typeof d == "function" ? !1 : l.uniforms && c in l.uniforms ? (l.uniforms[c] = r, !0) : d !== void 0 ? (this._setDeepProp(l, c, r), !0) : !1;
774
+ }
775
+ /**
776
+ * Perform a filter action (e.g. addColorStop, removeColorStop) and sync
777
+ * any resulting state changes back into State.js before recreating the
778
+ * filter. Without this sync, recreation via applyFilters() would rebuild
779
+ * from stale state and undo the action.
780
+ *
781
+ * @param {string} filterId
782
+ * @param {string} action - Action name understood by filter.updateUIParam
783
+ */
784
+ performFilterAction(e, t) {
785
+ const i = this.instances[e];
786
+ if (!(!i || typeof i.updateUIParam != "function")) {
787
+ if (i.updateUIParam(t, !0), typeof i.getSerializableParams == "function") {
788
+ const r = i.getSerializableParams();
789
+ for (const [a, n] of Object.entries(r))
790
+ this.state.setFilterValue(e, a, n);
791
+ }
792
+ this.applyFilters(), this.emit("filterActionPerformed", { filterId: e, action: t });
588
793
  }
589
- return !1;
590
794
  }
591
795
  /**
592
796
  * Apply all active filters to the sprite
@@ -602,16 +806,21 @@ class Fe extends V {
602
806
  const t = [], i = [];
603
807
  this.state.get("activeFilters").forEach((a) => {
604
808
  try {
605
- const o = this.getFilterDef(a);
606
- if (!o || !o.createFilter || typeof o.createFilter != "function")
809
+ const n = this.getFilterDef(a);
810
+ if (!n || !n.createFilter || typeof n.createFilter != "function")
607
811
  return;
608
- const n = this.state.getFilterValues(a), l = o.defaultParams ? { ...o.defaultParams } : {};
609
- o.controls && Array.isArray(o.controls) && o.controls.forEach((d) => {
610
- const h = d.property || d.id;
611
- l[h] = n[d.id] ?? d.default;
812
+ const o = this.state.getFilterValues(a), l = n.defaultParams ? { ...n.defaultParams } : {};
813
+ n.controls && Array.isArray(n.controls) && n.controls.forEach((f) => {
814
+ const _ = f.property || f.id;
815
+ l[_] = o[f.id] ?? f.default;
612
816
  });
613
- const c = o.createFilter(l);
614
- c && (t.push(c), this.instances[a] = c);
817
+ const c = new Set((n.controls || []).map((f) => f.id));
818
+ for (const [f, _] of Object.entries(o))
819
+ c.has(f) || (l[f] = _);
820
+ const d = this.renderer.sprite, h = this.renderer.originalTexture;
821
+ l._sourceWidth = Math.round((h == null ? void 0 : h.width) || (d == null ? void 0 : d.width) || 0), l._sourceHeight = Math.round((h == null ? void 0 : h.height) || (d == null ? void 0 : d.height) || 0);
822
+ const u = n.createFilter(l);
823
+ u && (t.push(u), this.instances[a] = u);
615
824
  } catch {
616
825
  i.push(a);
617
826
  }
@@ -647,7 +856,7 @@ class Fe extends V {
647
856
  return this.instances[e] || null;
648
857
  }
649
858
  }
650
- const X = class X extends V {
859
+ const U = class U extends W {
651
860
  constructor(e, t) {
652
861
  super(), this.state = e, this.renderer = t, this._overlayCanvas = null, this._isDragging = !1, this._dragStart = null, this._dragMode = null, this._startRect = null, this._hoverMode = null, this._lastAutoZoomCheck = 0, this.HANDLE_SIZE = 14, this.EDGE_HIT_PAD = 10, this._onPointerDown = this._handlePointerDown.bind(this), this._onPointerMove = this._handlePointerMove.bind(this), this._onPointerUp = this._handlePointerUp.bind(this);
653
862
  }
@@ -700,8 +909,8 @@ const X = class X extends V {
700
909
  if (!e) return;
701
910
  const t = this.renderer.sprite, i = this.renderer.app;
702
911
  if (!t || !i) return;
703
- const r = this.state.get("crop.shape"), o = r === "circle" || !!this.state.get("autoZoomOnCropOverflow") ? { x: 0, y: 0, w: i.screen.width, h: i.screen.height } : { x: t.x, y: t.y, w: t.width, h: t.height };
704
- if (e.x = Math.max(o.x, Math.min(e.x, o.x + o.w - e.width)), e.y = Math.max(o.y, Math.min(e.y, o.y + o.h - e.height)), e.width = Math.min(e.width, o.w), e.height = Math.min(e.height, o.h), r !== "free" || this.state.get("crop.aspect") === "1:1") {
912
+ const r = this.state.get("crop.shape"), a = { x: 0, y: 0, w: i.screen.width, h: i.screen.height };
913
+ if (e.x = Math.max(a.x, Math.min(e.x, a.x + a.w - e.width)), e.y = Math.max(a.y, Math.min(e.y, a.y + a.h - e.height)), e.width = Math.min(e.width, a.w), e.height = Math.min(e.height, a.h), r !== "free" || this.state.get("crop.aspect") === "1:1") {
705
914
  const n = Math.min(e.width, e.height);
706
915
  e.width = n, e.height = n;
707
916
  }
@@ -720,21 +929,21 @@ const X = class X extends V {
720
929
  * @param {number} currentZoom - Current zoom level
721
930
  * @returns {number|null} Target zoom level, or null if no zoom needed
722
931
  */
723
- static calcAutoZoom(e, t, i, r, a, o, n) {
724
- if (!e || !r || !a || !o) return null;
932
+ static calcAutoZoom(e, t, i, r, a, n, o) {
933
+ if (!e || !r || !a || !n) return null;
725
934
  const l = e.width > t, c = e.height > i;
726
935
  if (!l && !c) return null;
727
- const d = X.AUTO_ZOOM_PADDING;
728
- let h = n;
936
+ const d = U.AUTO_ZOOM_PADDING;
937
+ let h = o;
729
938
  if (l) {
730
- const p = e.width / (d * r * o);
731
- h = Math.min(h, p);
939
+ const u = e.width / (d * r * n);
940
+ h = Math.min(h, u);
732
941
  }
733
942
  if (c) {
734
- const p = e.height / (d * a * o);
735
- h = Math.min(h, p);
943
+ const u = e.height / (d * a * n);
944
+ h = Math.min(h, u);
736
945
  }
737
- return h = Math.max(0.1, h), h >= n - 0.01 ? null : h;
946
+ return h = Math.max(0.1, h), h >= o - 0.01 ? null : h;
738
947
  }
739
948
  /**
740
949
  * Check if auto-zoom is needed and apply it (throttled).
@@ -743,11 +952,11 @@ const X = class X extends V {
743
952
  _checkAutoZoom() {
744
953
  if (!this.state.get("autoZoomOnCropOverflow")) return;
745
954
  const e = Date.now();
746
- if (e - this._lastAutoZoomCheck < X.AUTO_ZOOM_THROTTLE_MS) return;
955
+ if (e - this._lastAutoZoomCheck < U.AUTO_ZOOM_THROTTLE_MS) return;
747
956
  this._lastAutoZoomCheck = e;
748
957
  const t = this.state.get("crop.rect"), i = this.renderer.sprite, r = this.renderer.originalTexture;
749
958
  if (!t || !i || !r) return;
750
- const a = X.calcAutoZoom(
959
+ const a = U.calcAutoZoom(
751
960
  t,
752
961
  i.width,
753
962
  i.height,
@@ -766,30 +975,30 @@ const X = class X extends V {
766
975
  if (!e) return;
767
976
  const t = this.renderer.app;
768
977
  if (!t) return;
769
- const i = t.canvas, r = i.clientWidth, a = i.clientHeight, o = window.devicePixelRatio || 1;
770
- (e.width !== Math.max(1, Math.floor(r * o)) || e.height !== Math.max(1, Math.floor(a * o))) && (e.width = Math.max(1, Math.floor(r * o)), e.height = Math.max(1, Math.floor(a * o)), e.style.width = r + "px", e.style.height = a + "px");
771
- const n = e.getContext("2d");
772
- if (!n) return;
773
- n.setTransform(o, 0, 0, o, 0, 0), n.clearRect(0, 0, r, a), n.fillStyle = "rgba(0, 0, 0, 0.5)", n.fillRect(0, 0, r, a);
978
+ const i = t.canvas, r = i.clientWidth, a = i.clientHeight, n = window.devicePixelRatio || 1;
979
+ (e.width !== Math.max(1, Math.floor(r * n)) || e.height !== Math.max(1, Math.floor(a * n))) && (e.width = Math.max(1, Math.floor(r * n)), e.height = Math.max(1, Math.floor(a * n)), e.style.width = r + "px", e.style.height = a + "px");
980
+ const o = e.getContext("2d");
981
+ if (!o) return;
982
+ o.setTransform(n, 0, 0, n, 0, 0), o.clearRect(0, 0, r, a), o.fillStyle = "rgba(0, 0, 0, 0.5)", o.fillRect(0, 0, r, a);
774
983
  const l = this.state.get("crop.rect");
775
984
  if (!l) return;
776
985
  const c = this.state.get("crop.shape");
777
- if (n.save(), c === "circle") {
778
- const y = l.x + l.width / 2, v = l.y + l.height / 2, x = Math.min(l.width, l.height) / 2;
779
- n.beginPath(), n.arc(y, v, x, 0, Math.PI * 2), n.clip();
986
+ if (o.save(), c === "circle") {
987
+ const x = l.x + l.width / 2, A = l.y + l.height / 2, P = Math.min(l.width, l.height) / 2;
988
+ o.beginPath(), o.arc(x, A, P, 0, Math.PI * 2), o.clip();
780
989
  } else
781
- n.beginPath(), n.rect(l.x, l.y, l.width, l.height), n.clip();
782
- n.clearRect(l.x, l.y, l.width, l.height), n.restore(), n.strokeStyle = "#ffffff", n.lineWidth = 2, n.setLineDash([5, 5]), c === "circle" ? (n.beginPath(), n.arc(
990
+ o.beginPath(), o.rect(l.x, l.y, l.width, l.height), o.clip();
991
+ o.clearRect(l.x, l.y, l.width, l.height), o.restore(), o.strokeStyle = "#ffffff", o.lineWidth = 2, o.setLineDash([5, 5]), c === "circle" ? (o.beginPath(), o.arc(
783
992
  l.x + l.width / 2,
784
993
  l.y + l.height / 2,
785
994
  Math.min(l.width, l.height) / 2,
786
995
  0,
787
996
  Math.PI * 2
788
- ), n.stroke()) : n.strokeRect(l.x, l.y, l.width, l.height), n.setLineDash([]), n.strokeStyle = "rgba(255,255,255,0.3)", n.lineWidth = 1;
997
+ ), o.stroke()) : o.strokeRect(l.x, l.y, l.width, l.height), o.setLineDash([]), o.strokeStyle = "rgba(255,255,255,0.3)", o.lineWidth = 1;
789
998
  const d = l.width / 3, h = l.height / 3;
790
- for (let y = 1; y <= 2; y++)
791
- n.beginPath(), n.moveTo(l.x + d * y, l.y), n.lineTo(l.x + d * y, l.y + l.height), n.stroke(), n.beginPath(), n.moveTo(l.x, l.y + h * y), n.lineTo(l.x + l.width, l.y + h * y), n.stroke();
792
- const p = this.HANDLE_SIZE, f = [
999
+ for (let x = 1; x <= 2; x++)
1000
+ o.beginPath(), o.moveTo(l.x + d * x, l.y), o.lineTo(l.x + d * x, l.y + l.height), o.stroke(), o.beginPath(), o.moveTo(l.x, l.y + h * x), o.lineTo(l.x + l.width, l.y + h * x), o.stroke();
1001
+ const u = this.HANDLE_SIZE, f = [
793
1002
  { x: l.x, y: l.y, m: "resize-nw" },
794
1003
  { x: l.x + l.width, y: l.y, m: "resize-ne" },
795
1004
  { x: l.x, y: l.y + l.height, m: "resize-sw" },
@@ -800,9 +1009,9 @@ const X = class X extends V {
800
1009
  { x: l.x, y: l.y + l.height / 2, m: "w" },
801
1010
  { x: l.x + l.width, y: l.y + l.height / 2, m: "e" }
802
1011
  ], g = [...f, ..._];
803
- for (const y of g) {
804
- const v = this._hoverMode === y.m, x = v ? p + 4 : p;
805
- n.beginPath(), n.rect(y.x - x / 2, y.y - x / 2, x, x), n.fillStyle = v ? "#4da3ff" : "#ffffff", n.strokeStyle = "rgba(0,0,0,0.6)", n.lineWidth = 1, n.fill(), n.stroke();
1012
+ for (const x of g) {
1013
+ const A = this._hoverMode === x.m, P = A ? u + 4 : u;
1014
+ o.beginPath(), o.rect(x.x - P / 2, x.y - P / 2, P, P), o.fillStyle = A ? "#4da3ff" : "#ffffff", o.strokeStyle = "rgba(0,0,0,0.6)", o.lineWidth = 1, o.fill(), o.stroke();
806
1015
  }
807
1016
  }
808
1017
  /**
@@ -814,7 +1023,7 @@ const X = class X extends V {
814
1023
  _hitHandle(e, t) {
815
1024
  const i = this.state.get("crop.rect");
816
1025
  if (!i) return null;
817
- const r = (a, o, n, l, c) => Math.abs(a - n) <= c && Math.abs(o - l) <= c;
1026
+ const r = (a, n, o, l, c) => Math.abs(a - o) <= c && Math.abs(n - l) <= c;
818
1027
  return r(e, t, i.x, i.y, this.HANDLE_SIZE) ? "resize-nw" : r(e, t, i.x + i.width, i.y, this.HANDLE_SIZE) ? "resize-ne" : r(e, t, i.x, i.y + i.height, this.HANDLE_SIZE) ? "resize-sw" : r(e, t, i.x + i.width, i.y + i.height, this.HANDLE_SIZE) ? "resize-se" : Math.abs(t - i.y) <= this.EDGE_HIT_PAD && e >= i.x && e <= i.x + i.width ? "n" : Math.abs(t - (i.y + i.height)) <= this.EDGE_HIT_PAD && e >= i.x && e <= i.x + i.width ? "s" : Math.abs(e - i.x) <= this.EDGE_HIT_PAD && t >= i.y && t <= i.y + i.height ? "w" : Math.abs(e - (i.x + i.width)) <= this.EDGE_HIT_PAD && t >= i.y && t <= i.y + i.height ? "e" : e >= i.x && e <= i.x + i.width && t >= i.y && t <= i.y + i.height ? "move" : null;
819
1028
  }
820
1029
  /**
@@ -840,16 +1049,16 @@ const X = class X extends V {
840
1049
  }
841
1050
  const r = this.state.get("crop.rect");
842
1051
  if (!r) return;
843
- const a = i.x - this._dragStart.x, o = i.y - this._dragStart.y;
1052
+ const a = i.x - this._dragStart.x, n = i.y - this._dragStart.y;
844
1053
  switch (this._dragMode) {
845
1054
  case "move":
846
- r.x = this._startRect.x + a, r.y = this._startRect.y + o;
1055
+ r.x = this._startRect.x + a, r.y = this._startRect.y + n;
847
1056
  break;
848
1057
  case "n":
849
- r.y = this._startRect.y + o, r.height = this._startRect.height - o;
1058
+ r.y = this._startRect.y + n, r.height = this._startRect.height - n;
850
1059
  break;
851
1060
  case "s":
852
- r.height = this._startRect.height + o;
1061
+ r.height = this._startRect.height + n;
853
1062
  break;
854
1063
  case "w":
855
1064
  r.x = this._startRect.x + a, r.width = this._startRect.width - a;
@@ -858,16 +1067,16 @@ const X = class X extends V {
858
1067
  r.width = this._startRect.width + a;
859
1068
  break;
860
1069
  case "resize-nw":
861
- r.x = this._startRect.x + a, r.y = this._startRect.y + o, r.width = this._startRect.width - a, r.height = this._startRect.height - o;
1070
+ r.x = this._startRect.x + a, r.y = this._startRect.y + n, r.width = this._startRect.width - a, r.height = this._startRect.height - n;
862
1071
  break;
863
1072
  case "resize-ne":
864
- r.y = this._startRect.y + o, r.width = this._startRect.width + a, r.height = this._startRect.height - o;
1073
+ r.y = this._startRect.y + n, r.width = this._startRect.width + a, r.height = this._startRect.height - n;
865
1074
  break;
866
1075
  case "resize-sw":
867
- r.x = this._startRect.x + a, r.width = this._startRect.width - a, r.height = this._startRect.height + o;
1076
+ r.x = this._startRect.x + a, r.width = this._startRect.width - a, r.height = this._startRect.height + n;
868
1077
  break;
869
1078
  case "resize-se":
870
- r.width = this._startRect.width + a, r.height = this._startRect.height + o;
1079
+ r.width = this._startRect.width + a, r.height = this._startRect.height + n;
871
1080
  break;
872
1081
  }
873
1082
  r.width = Math.max(50, r.width), r.height = Math.max(50, r.height), this.state.set("crop.rect", r), this.state.get("crop.shape") === "circle" && this.state.get("crop.aspect") !== "1:1" && this.state.set("crop.aspect", "1:1"), this.applyAspectRatio(), this._dragMode !== "move" && this._checkAutoZoom(), this.constrainCropRect(), this.drawOverlay();
@@ -887,17 +1096,17 @@ const X = class X extends V {
887
1096
  let i = this.state.get("crop.rect");
888
1097
  if (!i) {
889
1098
  this.state.get("crop.shape") === "circle" && this.state.set("crop.aspect", "1:1");
890
- const o = this.state.get("crop.aspect"), n = this._getAspectRatio(o);
1099
+ const n = this.state.get("crop.aspect"), o = this._getAspectRatio(n);
891
1100
  let l, c;
892
- if (n) {
893
- const p = t.width * 0.9, f = t.height * 0.9;
894
- p / f > n ? (c = f, l = c * n) : (l = p, c = l / n);
1101
+ if (o) {
1102
+ const u = t.width * 0.9, f = t.height * 0.9;
1103
+ u / f > o ? (c = f, l = c * o) : (l = u, c = l / o);
895
1104
  } else {
896
- const p = Math.min(e.screen.width, e.screen.height) * 0.7;
897
- l = p, c = p;
1105
+ const u = Math.min(e.screen.width, e.screen.height) * 0.7;
1106
+ l = u, c = u;
898
1107
  }
899
1108
  const d = t.x + (t.width - l) / 2, h = t.y + (t.height - c) / 2;
900
- i = { x: d, y: h, width: l, height: c }, this.state.set("crop.rect", i), o !== "free" && this.constrainCropRect();
1109
+ i = { x: d, y: h, width: l, height: c }, this.state.set("crop.rect", i), n !== "free" && this.constrainCropRect();
901
1110
  }
902
1111
  const r = e.stage;
903
1112
  r.eventMode = "static", r.hitArea = e.screen, r.cursor = "crosshair", r.on("pointerdown", this._onPointerDown), r.on("pointermove", this._onPointerMove), r.on("pointerup", this._onPointerUp), r.on("pointerupoutside", this._onPointerUp), this.state.set("mode", "crop"), this.drawOverlay(), this.emit("enabled");
@@ -922,34 +1131,34 @@ const X = class X extends V {
922
1131
  apply() {
923
1132
  const e = this.renderer.app, t = this.renderer.sprite, i = this.renderer.originalTexture, r = this.state.get("crop.rect");
924
1133
  if (!r || !t || !e || !i) return null;
925
- const a = window.PIXI, o = this.renderer.zoom, n = i.width / t.width, l = i.height / t.height, c = (r.x - t.x) * n, d = (r.y - t.y) * l;
926
- let h = Math.round(Math.max(1, r.width * n)), p = Math.round(Math.max(1, r.height * l)), f = Math.round(c), _ = Math.round(d);
927
- if (h <= 0 || p <= 0) return null;
928
- const g = new a.Container(), y = new a.Sprite(i);
1134
+ const a = window.PIXI, n = this.renderer.zoom, o = i.width / t.width, l = i.height / t.height, c = (r.x - t.x) * o, d = (r.y - t.y) * l;
1135
+ let h = Math.round(Math.max(1, r.width * o)), u = Math.round(Math.max(1, r.height * l)), f = Math.round(c), _ = Math.round(d);
1136
+ if (h <= 0 || u <= 0) return null;
1137
+ const g = new a.Container(), x = new a.Sprite(i);
929
1138
  if (this.state.get("crop.shape") === "circle") {
930
- const $ = Math.round(Math.max(h, p)), _e = f + h / 2, xe = _ + p / 2;
931
- f = Math.round(_e - $ / 2), _ = Math.round(xe - $ / 2), h = p = $;
932
- const R = new a.Graphics();
933
- typeof R.circle == "function" && typeof R.fill == "function" ? R.circle(h / 2, p / 2, h / 2).fill(16777215) : (R.beginFill(16777215, 1), R.drawCircle(h / 2, p / 2, h / 2), R.endFill()), y.mask = R, g.addChild(R);
1139
+ const I = Math.round(Math.max(h, u)), k = f + h / 2, w = _ + u / 2;
1140
+ f = Math.round(k - I / 2), _ = Math.round(w - I / 2), h = u = I;
1141
+ const S = new a.Graphics();
1142
+ typeof S.circle == "function" && typeof S.fill == "function" ? S.circle(h / 2, u / 2, h / 2).fill(16777215) : (S.beginFill(16777215, 1), S.drawCircle(h / 2, u / 2, h / 2), S.endFill()), x.mask = S, g.addChild(S);
934
1143
  }
935
- y.x = -f, y.y = -_, g.addChild(y);
936
- const x = a.RenderTexture.create({ width: h, height: p });
1144
+ x.x = -f, x.y = -_, g.addChild(x);
1145
+ const P = a.RenderTexture.create({ width: h, height: u });
937
1146
  e.renderer.render({
938
1147
  container: g,
939
- target: x,
1148
+ target: P,
940
1149
  clear: !0
941
1150
  }), g.destroy({ children: !0 });
942
- const P = this.renderer.originalTexture;
943
- P && P !== this.renderer.baseTexture && P.destroy(!0), this.renderer.originalTexture = x, e.stage.removeChild(t), t.destroy();
944
- const S = new a.Sprite(x);
945
- e.stage.addChild(S), this.renderer.sprite = S, this.renderer.fitScale = this.renderer.getFitScaleFor(x), this.renderer.setZoom(o, { keepCenter: !1 }), this.renderer.applyViewTransform(), this.renderer.render();
946
- const T = this.state.get("crop.appliedRect"), F = T && Number.isFinite(T.x) && Number.isFinite(T.y) && Number.isFinite(T.width) && Number.isFinite(T.height) ? {
947
- x: Math.round(T.x + f),
948
- y: Math.round(T.y + _),
1151
+ const T = this.renderer.originalTexture;
1152
+ T && T !== this.renderer.baseTexture && T.destroy(!0), this.renderer.originalTexture = P, e.stage.removeChild(t), t.destroy();
1153
+ const N = new a.Sprite(P);
1154
+ e.stage.addChild(N), this.renderer.sprite = N, this.renderer.fitScale = this.renderer.getFitScaleFor(P), this.renderer.setZoom(n, { keepCenter: !1 }), this.renderer.applyViewTransform(), this.renderer.render();
1155
+ const y = this.state.get("crop.appliedRect"), v = y && Number.isFinite(y.x) && Number.isFinite(y.y) && Number.isFinite(y.width) && Number.isFinite(y.height) ? {
1156
+ x: Math.round(y.x + f),
1157
+ y: Math.round(y.y + _),
949
1158
  width: h,
950
- height: p
951
- } : { x: f, y: _, width: h, height: p }, B = this.state.get("crop.shape") || "free", U = this.state.get("crop.aspect") || "free";
952
- return this.disable(), this.state.set("crop.appliedRect", F), this.state.set("crop.appliedShape", B), this.state.set("crop.appliedAspect", U), this.emit("applied", { width: h, height: p }), { texture: x, preservedZoom: o };
1159
+ height: u
1160
+ } : { x: f, y: _, width: h, height: u }, M = this.state.get("crop.shape") || "free", F = this.state.get("crop.aspect") || "free";
1161
+ return this.disable(), this.state.set("crop.appliedRect", v), this.state.set("crop.appliedShape", M), this.state.set("crop.appliedAspect", F), this.emit("applied", { width: h, height: u }), { texture: P, preservedZoom: n };
953
1162
  }
954
1163
  /**
955
1164
  * Apply a crop from saved texture-pixel coordinates (for state rehydration).
@@ -961,23 +1170,23 @@ const X = class X extends V {
961
1170
  applyFromPixelRect(e, t = "free") {
962
1171
  const i = this.renderer.app, r = this.renderer.sprite, a = this.renderer.originalTexture;
963
1172
  if (!e || !r || !i || !a) return null;
964
- const o = window.PIXI, n = this.renderer.zoom;
1173
+ const n = window.PIXI, o = this.renderer.zoom;
965
1174
  let l = Math.round(Math.max(1, e.width)), c = Math.round(Math.max(1, e.height)), d = Math.round(e.x), h = Math.round(e.y);
966
1175
  if (l <= 0 || c <= 0) return null;
967
- const p = new o.Container(), f = new o.Sprite(a);
1176
+ const u = new n.Container(), f = new n.Sprite(a);
968
1177
  if (t === "circle") {
969
- const v = Math.round(Math.max(l, c)), x = d + l / 2, P = h + c / 2;
970
- d = Math.round(x - v / 2), h = Math.round(P - v / 2), l = c = v;
971
- const S = new o.Graphics();
972
- typeof S.circle == "function" && typeof S.fill == "function" ? S.circle(l / 2, c / 2, l / 2).fill(16777215) : (S.beginFill(16777215, 1), S.drawCircle(l / 2, c / 2, l / 2), S.endFill()), f.mask = S, p.addChild(S);
973
- }
974
- f.x = -d, f.y = -h, p.addChild(f);
975
- const _ = o.RenderTexture.create({ width: l, height: c });
976
- i.renderer.render({ container: p, target: _, clear: !0 }), p.destroy({ children: !0 });
1178
+ const A = Math.round(Math.max(l, c)), P = d + l / 2, T = h + c / 2;
1179
+ d = Math.round(P - A / 2), h = Math.round(T - A / 2), l = c = A;
1180
+ const N = new n.Graphics();
1181
+ typeof N.circle == "function" && typeof N.fill == "function" ? N.circle(l / 2, c / 2, l / 2).fill(16777215) : (N.beginFill(16777215, 1), N.drawCircle(l / 2, c / 2, l / 2), N.endFill()), f.mask = N, u.addChild(N);
1182
+ }
1183
+ f.x = -d, f.y = -h, u.addChild(f);
1184
+ const _ = n.RenderTexture.create({ width: l, height: c });
1185
+ i.renderer.render({ container: u, target: _, clear: !0 }), u.destroy({ children: !0 });
977
1186
  const g = this.renderer.originalTexture;
978
1187
  g && g !== this.renderer.baseTexture && g.destroy(!0), this.renderer.originalTexture = _, i.stage.removeChild(r), r.destroy();
979
- const y = new o.Sprite(_);
980
- return i.stage.addChild(y), this.renderer.sprite = y, this.renderer.fitScale = this.renderer.getFitScaleFor(_), this.renderer.setZoom(n, { keepCenter: !1 }), this.renderer.applyViewTransform(), this.renderer.render(), { texture: _, preservedZoom: n };
1188
+ const x = new n.Sprite(_);
1189
+ return i.stage.addChild(x), this.renderer.sprite = x, this.renderer.fitScale = this.renderer.getFitScaleFor(_), this.renderer.setZoom(o, { keepCenter: !1 }), this.renderer.applyViewTransform(), this.renderer.render(), { texture: _, preservedZoom: o };
981
1190
  }
982
1191
  /**
983
1192
  * Cancel crop
@@ -1009,12 +1218,12 @@ const X = class X extends V {
1009
1218
  * Padding factor for auto-zoom: image will be ~91% of crop size (1/1.1).
1010
1219
  * Higher values = more aggressive zoom-out, more padding around image.
1011
1220
  */
1012
- W(X, "AUTO_ZOOM_PADDING", 1.1), /**
1221
+ J(U, "AUTO_ZOOM_PADDING", 1.1), /**
1013
1222
  * Minimum interval (ms) between auto-zoom adjustments during drag.
1014
1223
  */
1015
- W(X, "AUTO_ZOOM_THROTTLE_MS", 100);
1016
- let Q = X;
1017
- class Ae {
1224
+ J(U, "AUTO_ZOOM_THROTTLE_MS", 100);
1225
+ let ae = U;
1226
+ class pt {
1018
1227
  /**
1019
1228
  * Create a new RemoveBgManager
1020
1229
  * @param {Object} options
@@ -1039,7 +1248,7 @@ class Ae {
1039
1248
  async removeBackground(e, t = {}) {
1040
1249
  const i = typeof e == "string" ? await this._dataUrlToBlob(e) : e, r = new FormData();
1041
1250
  r.append("file", i, "image.png"), r.append("tier", t.tier || "balanced"), t.model && r.append("model", t.model), t.alpha_matting && (r.append("alpha_matting", "true"), r.append("alpha_f", String(t.alpha_f ?? 10)), r.append("alpha_fr", String(t.alpha_fr ?? 15)), r.append("alpha_erode_size", String(t.alpha_erode_size ?? 10)));
1042
- let a, o;
1251
+ let a, n;
1043
1252
  try {
1044
1253
  a = await fetch(this._endpoint, {
1045
1254
  method: "POST",
@@ -1048,7 +1257,7 @@ class Ae {
1048
1257
  // For Sanctum auth
1049
1258
  });
1050
1259
  } catch (c) {
1051
- o = c;
1260
+ n = c;
1052
1261
  }
1053
1262
  if ((!a || !a.ok) && this._fallbackEndpoint)
1054
1263
  try {
@@ -1057,10 +1266,10 @@ class Ae {
1057
1266
  body: r
1058
1267
  });
1059
1268
  } catch (c) {
1060
- o || (o = c);
1269
+ n || (n = c);
1061
1270
  }
1062
1271
  if (!a)
1063
- throw o || new Error("Network error: Unable to connect to background removal service");
1272
+ throw n || new Error("Network error: Unable to connect to background removal service");
1064
1273
  if (!a.ok) {
1065
1274
  let c = `Background removal failed (HTTP ${a.status})`;
1066
1275
  try {
@@ -1070,9 +1279,9 @@ class Ae {
1070
1279
  }
1071
1280
  throw new Error(c);
1072
1281
  }
1073
- const n = await a.blob();
1282
+ const o = await a.blob();
1074
1283
  return {
1075
- dataUrl: await this._blobToDataUrl(n),
1284
+ dataUrl: await this._blobToDataUrl(o),
1076
1285
  model: a.headers.get("X-Model-Used") || "unknown",
1077
1286
  processMs: a.headers.get("X-Process-Ms") || "0"
1078
1287
  };
@@ -1084,10 +1293,10 @@ class Ae {
1084
1293
  */
1085
1294
  async _dataUrlToBlob(e) {
1086
1295
  if (e.startsWith("data:")) {
1087
- const [i, r] = e.split(","), a = i.match(/:(.*?);/), o = a ? a[1] : "image/png", n = atob(r), l = new Uint8Array(n.length);
1088
- for (let c = 0; c < n.length; c++)
1089
- l[c] = n.charCodeAt(c);
1090
- return new Blob([l], { type: o });
1296
+ const [i, r] = e.split(","), a = i.match(/:(.*?);/), n = a ? a[1] : "image/png", o = atob(r), l = new Uint8Array(o.length);
1297
+ for (let c = 0; c < o.length; c++)
1298
+ l[c] = o.charCodeAt(c);
1299
+ return new Blob([l], { type: n });
1091
1300
  }
1092
1301
  return (await fetch(e)).blob();
1093
1302
  }
@@ -1124,7 +1333,7 @@ class Ae {
1124
1333
  }
1125
1334
  }
1126
1335
  }
1127
- function u(s, e = {}, ...t) {
1336
+ function p(s, e = {}, ...t) {
1128
1337
  const i = document.createElement(s);
1129
1338
  for (const [r, a] of Object.entries(e))
1130
1339
  if (a != null)
@@ -1133,24 +1342,24 @@ function u(s, e = {}, ...t) {
1133
1342
  else if (r === "style" && typeof a == "object")
1134
1343
  Object.assign(i.style, a);
1135
1344
  else if (r.startsWith("on") && typeof a == "function") {
1136
- const o = r.slice(2).toLowerCase();
1137
- i.addEventListener(o, a);
1345
+ const n = r.slice(2).toLowerCase();
1346
+ i.addEventListener(n, a);
1138
1347
  } else r === "dataset" && typeof a == "object" ? Object.assign(i.dataset, a) : i.setAttribute(r, a);
1139
1348
  for (const r of t)
1140
1349
  typeof r == "string" ? i.appendChild(document.createTextNode(r)) : r instanceof HTMLElement && i.appendChild(r);
1141
1350
  return i;
1142
1351
  }
1143
- function he({ id: s, label: e, min: t = 0, max: i = 1, step: r = 0.01, value: a = 0.5, onChange: o }) {
1144
- const n = s.includes("-") ? s.split("-").slice(1).join("-") : s, l = u("div", {
1352
+ function Ae({ id: s, label: e, min: t = 0, max: i = 1, step: r = 0.01, value: a = 0.5, onChange: n }) {
1353
+ const o = s.includes("-") ? s.split("-").slice(1).join("-") : s, l = p("div", {
1145
1354
  className: "slider-control slider-wrapper",
1146
- "data-control": n,
1147
- "data-testid": `slider-${n}`
1148
- }), c = u(
1355
+ "data-control": o,
1356
+ "data-testid": `slider-${o}`
1357
+ }), c = p(
1149
1358
  "div",
1150
1359
  { className: "slider-header" },
1151
- u("label", { for: s, className: "slider-label" }, e),
1152
- u("span", { className: "slider-value", id: `${s}-value` }, Z(a))
1153
- ), d = u("input", {
1360
+ p("label", { for: s, className: "slider-label" }, e),
1361
+ p("span", { className: "slider-value", id: `${s}-value` }, ee(a))
1362
+ ), d = p("input", {
1154
1363
  type: "range",
1155
1364
  id: s,
1156
1365
  className: "slider-input",
@@ -1159,110 +1368,136 @@ function he({ id: s, label: e, min: t = 0, max: i = 1, step: r = 0.01, value: a
1159
1368
  step: String(r),
1160
1369
  value: String(a),
1161
1370
  onInput: (h) => {
1162
- const p = parseFloat(h.target.value), f = l.querySelector(".slider-value");
1163
- f && (f.textContent = Z(p)), o == null || o(p);
1371
+ const u = parseFloat(h.target.value), f = l.querySelector(".slider-value");
1372
+ f && (f.textContent = ee(u)), n == null || n(u);
1164
1373
  }
1165
1374
  });
1166
1375
  return l.appendChild(c), l.appendChild(d), l.setValue = (h) => {
1167
1376
  d.value = String(h);
1168
- const p = l.querySelector(".slider-value");
1169
- p && (p.textContent = Z(h));
1377
+ const u = l.querySelector(".slider-value");
1378
+ u && (u.textContent = ee(h));
1170
1379
  }, l;
1171
1380
  }
1172
- function Z(s) {
1381
+ function ee(s) {
1173
1382
  return Number.isInteger(s) ? String(s) : s.toFixed(2);
1174
1383
  }
1175
- function de({ id: s, label: e, checked: t = !1, onChange: i }) {
1176
- const r = u("div", { className: "toggle-control" }), a = u("label", { className: "toggle-label", for: s }, e), o = u("input", {
1384
+ function ze({ id: s, label: e, checked: t = !1, onChange: i }) {
1385
+ const r = p("div", { className: "toggle-control" }), a = p("label", { className: "toggle-label", for: s }, e), n = p("input", {
1177
1386
  type: "checkbox",
1178
1387
  id: s,
1179
1388
  className: "toggle-input",
1180
1389
  checked: t ? "checked" : void 0,
1181
1390
  onChange: (c) => i == null ? void 0 : i(c.target.checked)
1182
- }), n = u("div", {
1391
+ }), o = p("div", {
1183
1392
  className: "toggle-switch",
1184
1393
  onClick: (c) => {
1185
- c.target !== o && (o.checked = !o.checked, i == null || i(o.checked));
1394
+ c.target !== n && (n.checked = !n.checked, i == null || i(n.checked));
1186
1395
  }
1187
- }), l = u("span", { className: "toggle-slider" });
1188
- return n.appendChild(o), n.appendChild(l), r.appendChild(a), r.appendChild(n), r.setChecked = (c) => {
1189
- o.checked = c;
1396
+ }), l = p("span", { className: "toggle-slider" });
1397
+ return o.appendChild(n), o.appendChild(l), r.appendChild(a), r.appendChild(o), r.setChecked = (c) => {
1398
+ n.checked = c;
1190
1399
  }, r;
1191
1400
  }
1192
- function ue({ id: s, label: e, value: t = "#000000", onChange: i }) {
1193
- const r = u("div", { className: "color-control" }), a = u("label", { className: "color-label", for: s }, e), o = u("input", {
1401
+ function Ne({ id: s, label: e, value: t = "#000000", onChange: i }) {
1402
+ const r = p("div", { className: "color-control" }), a = p("label", { className: "color-label", for: s }, e), n = p("input", {
1194
1403
  type: "color",
1195
1404
  id: s,
1196
1405
  className: "color-input",
1197
1406
  value: t,
1198
- onInput: (n) => i == null ? void 0 : i(n.target.value)
1407
+ onInput: (o) => i == null ? void 0 : i(o.target.value)
1199
1408
  });
1200
- return r.appendChild(a), r.appendChild(o), r.setValue = (n) => {
1201
- o.value = n;
1409
+ return r.appendChild(a), r.appendChild(n), r.setValue = (o) => {
1410
+ n.value = o;
1202
1411
  }, r;
1203
1412
  }
1204
- function pe({ id: s, label: e, options: t = [], value: i, onChange: r }) {
1205
- const a = u("div", { className: "select-control" }), o = u("label", { className: "select-label", for: s }, e), n = u("select", {
1413
+ function Re({ id: s, label: e, value: t = "", placeholder: i = "", onCommit: r }) {
1414
+ const a = p("div", {
1415
+ className: "text-control",
1416
+ "data-control": s,
1417
+ "data-testid": `text-${s}`
1418
+ }), n = p("label", { className: "text-label", for: s }, e);
1419
+ let o = t;
1420
+ const l = p("input", {
1421
+ type: "text",
1422
+ id: s,
1423
+ className: "text-input",
1424
+ value: t,
1425
+ placeholder: i,
1426
+ onKeyDown: (d) => {
1427
+ d.key === "Enter" && (d.preventDefault(), c(), l.blur());
1428
+ },
1429
+ onBlur: () => c()
1430
+ });
1431
+ function c() {
1432
+ const d = l.value;
1433
+ d !== o && (o = d, r == null || r(d));
1434
+ }
1435
+ return a.appendChild(n), a.appendChild(l), a.setValue = (d) => {
1436
+ const h = d == null ? "" : String(d);
1437
+ l.value = h, o = h;
1438
+ }, a;
1439
+ }
1440
+ function Te({ id: s, label: e, options: t = [], value: i, onChange: r }) {
1441
+ const a = p("div", { className: "select-control" }), n = p("label", { className: "select-label", for: s }, e), o = p("select", {
1206
1442
  id: s,
1207
1443
  className: "select-input",
1208
1444
  onChange: (l) => r == null ? void 0 : r(l.target.value)
1209
1445
  });
1210
1446
  for (const l of t) {
1211
- const c = u("option", { value: l.value }, l.label);
1212
- l.value === i && (c.selected = !0), n.appendChild(c);
1447
+ const c = p("option", { value: l.value }, l.label);
1448
+ l.value === i && (c.selected = !0), o.appendChild(c);
1213
1449
  }
1214
- return a.appendChild(o), a.appendChild(n), a.setValue = (l) => {
1215
- n.value = l;
1450
+ return a.appendChild(n), a.appendChild(o), a.setValue = (l) => {
1451
+ o.value = l;
1216
1452
  }, a;
1217
1453
  }
1218
- function N({ label: s, className: e = "", onClick: t, icon: i = null, disabled: r = !1 }) {
1219
- const a = u("button", {
1454
+ function O({ label: s, className: e = "", onClick: t, icon: i = null, disabled: r = !1 }) {
1455
+ const a = p("button", {
1220
1456
  type: "button",
1221
1457
  className: `btn ${e}`.trim(),
1222
1458
  onClick: t,
1223
1459
  disabled: r ? "disabled" : void 0
1224
1460
  });
1225
1461
  if (i) {
1226
- const o = u("span", { className: "btn-icon" });
1227
- o.innerHTML = i;
1228
- const n = o.querySelector("svg");
1229
- n && n.setAttribute("aria-hidden", "true"), a.appendChild(o);
1462
+ const n = p("span", { className: "btn-icon" });
1463
+ n.innerHTML = i;
1464
+ const o = n.querySelector("svg");
1465
+ o && o.setAttribute("aria-hidden", "true"), a.appendChild(n);
1230
1466
  }
1231
1467
  return s && a.appendChild(document.createTextNode(s)), a;
1232
1468
  }
1233
- function C({ icon: s, title: e, className: t = "", onClick: i, disabled: r = !1, testId: a = null, ariaLabel: o = null }) {
1234
- const n = {
1469
+ function z({ icon: s, title: e, className: t = "", onClick: i, disabled: r = !1, testId: a = null, ariaLabel: n = null }) {
1470
+ const o = {
1235
1471
  type: "button",
1236
1472
  className: `icon-btn ${t}`.trim(),
1237
1473
  title: e,
1238
- "aria-label": o || e,
1474
+ "aria-label": n || e,
1239
1475
  onClick: i,
1240
1476
  disabled: r ? "disabled" : void 0
1241
1477
  };
1242
- a && (n.dataset = { testid: a });
1243
- const l = u("button", n);
1478
+ a && (o.dataset = { testid: a });
1479
+ const l = p("button", o);
1244
1480
  l.innerHTML = s;
1245
1481
  const c = l.querySelector("svg");
1246
1482
  return c && c.setAttribute("aria-hidden", "true"), l;
1247
1483
  }
1248
- function J({ label: s, icon: e, active: t = !1, onClick: i }) {
1249
- const r = u("button", {
1484
+ function ne({ label: s, icon: e, active: t = !1, onClick: i }) {
1485
+ const r = p("button", {
1250
1486
  type: "button",
1251
1487
  className: `chip ${t ? "active" : ""}`.trim(),
1252
1488
  onClick: i
1253
1489
  });
1254
1490
  if (e) {
1255
- const a = u("span", { className: "chip-icon" });
1491
+ const a = p("span", { className: "chip-icon" });
1256
1492
  a.innerHTML = e;
1257
- const o = a.querySelector("svg");
1258
- o && o.setAttribute("aria-hidden", "true"), r.appendChild(a);
1493
+ const n = a.querySelector("svg");
1494
+ n && n.setAttribute("aria-hidden", "true"), r.appendChild(a);
1259
1495
  }
1260
- return r.appendChild(u("span", { className: "chip-label" }, s)), r.setActive = (a) => {
1496
+ return r.appendChild(p("span", { className: "chip-label" }, s)), r.setActive = (a) => {
1261
1497
  r.classList.toggle("active", a);
1262
1498
  }, r;
1263
1499
  }
1264
- const fe = '<svg viewBox="0 0 512 512" width="20" height="20"><path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="48" d="M328 112L184 256l144 144"/></svg>', me = '<svg viewBox="0 0 512 512" width="20" height="20"><path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="48" d="M184 112l144 144-144 144"/></svg>', ze = '<svg viewBox="0 0 512 512" width="20" height="20"><path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="32" d="M221.09 64a157.09 157.09 0 10157.09 157.09A157.1 157.1 0 00221.09 64z"/><path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="32" d="M338.29 338.29L448 448M256 184v74m-37-37h74"/></svg>', Re = '<svg viewBox="0 0 512 512" width="20" height="20"><path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="32" d="M221.09 64a157.09 157.09 0 10157.09 157.09A157.1 157.1 0 00221.09 64z"/><path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="32" d="M338.29 338.29L448 448M184 221h74"/></svg>', Ne = '<svg viewBox="0 0 512 512" width="20" height="20"><path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="32" d="M432 320v112H320M80 192V80h112M320 80h112v112M192 432H80V320"/></svg>', Te = '<svg viewBox="0 0 512 512" width="20" height="20"><path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="32" d="M262.29 192.31a64 64 0 1057.4 57.4 64.13 64.13 0 00-57.4-57.4z"/><path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="32" d="M416.39 256a154.34 154.34 0 01-1.53 20.79l45.21 35.46a10.81 10.81 0 012.45 13.75l-42.77 74a10.81 10.81 0 01-13.14 4.59l-44.9-18.08a16.11 16.11 0 00-15.17 1.75A164.48 164.48 0 01325 400.8a15.94 15.94 0 00-8.82 12.14l-6.73 47.89a11.08 11.08 0 01-10.68 9.17h-85.54a11.11 11.11 0 01-10.69-8.87l-6.72-47.82a16.07 16.07 0 00-9-12.22 155.3 155.3 0 01-21.46-12.57 16 16 0 00-15.11-1.71l-44.89 18.07a10.81 10.81 0 01-13.14-4.58l-42.77-74a10.8 10.8 0 012.45-13.75l38.21-30a16.05 16.05 0 006-14.08c-.36-4.17-.58-8.33-.58-12.5s.21-8.27.58-12.35a16 16 0 00-6.07-13.94l-38.19-30A10.81 10.81 0 0149.48 186l42.77-74a10.81 10.81 0 0113.14-4.59l44.9 18.08a16.11 16.11 0 0015.17-1.75A164.48 164.48 0 01187 111.2a15.94 15.94 0 008.82-12.14l6.73-47.89A11.08 11.08 0 01213.23 42h85.54a11.11 11.11 0 0110.69 8.87l6.72 47.82a16.07 16.07 0 009 12.22 155.3 155.3 0 0121.46 12.57 16 16 0 0015.11 1.71l44.89-18.07a10.81 10.81 0 0113.14 4.58l42.77 74a10.8 10.8 0 01-2.45 13.75l-38.21 30a16.05 16.05 0 00-6.05 14.08c.33 4.14.55 8.3.55 12.47z"/></svg>', Ie = '<svg viewBox="0 0 512 512" width="20" height="20"><path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="32" d="M400 320c0 88.37-55.63 144-144 144s-144-55.63-144-144c0-94.83 103.23-222.85 134.89-259.88a12 12 0 0118.23 0C296.77 97.15 400 225.17 400 320z"/><path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="32" d="M344 328a72 72 0 01-72 72"/></svg>', Ee = '<svg viewBox="0 0 512 512" width="20" height="20"><path fill="none" stroke="currentColor" stroke-miterlimit="10" stroke-width="32" d="M430.11 347.9c-6.6-6.1-16.3-7.6-24.6-9-11.5-1.9-15.9-4-22.6-10-14.3-12.7-14.3-31.1 0-43.8l30.3-26.9c46.4-41 46.4-108.2 0-149.2-34.2-30.1-80.1-45-127.8-45-55.7 0-113.9 20.3-158.8 60.1-83.5 73.8-83.5 194.7 0 268.5 41.5 36.7 97.5 55 152.9 55.4h1.7c55.4 0 110-17.9 148.8-52.4 14.4-12.7 11.99-36.6.1-47.7z"/><circle cx="144" cy="208" r="32"/><circle cx="152" cy="311" r="32"/><circle cx="224" cy="144" r="32"/><circle cx="256" cy="367" r="32"/><circle cx="328" cy="144" r="32"/></svg>', Xe = '<svg viewBox="0 0 512 512" width="20" height="20"><path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="32" d="M259.92 262.91L216.4 149.77a9 9 0 00-16.8 0l-43.52 113.14a9 9 0 01-5.17 5.17L37.77 311.6a9 9 0 000 16.8l113.14 43.52a9 9 0 015.17 5.17l43.52 113.14a9 9 0 0016.8 0l43.52-113.14a9 9 0 015.17-5.17l113.14-43.52a9 9 0 000-16.8l-113.14-43.52a9 9 0 01-5.17-5.17zM108 68L88 16 68 68 16 88l52 20 20 52 20-52 52-20-52-20zM426.67 117.33L400 48l-26.67 69.33L304 144l69.33 26.67L400 240l26.67-69.33L496 144l-69.33-26.67z"/></svg>', Ye = '<svg viewBox="0 0 512 512" width="20" height="20"><path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="32" d="M176 112l80-80 80 80M255.98 32l.02 448M176 400l80 80 80-80M400 176l80 80-80 80M112 176l-80 80 80 80M32 256h448"/></svg>', Be = '<svg viewBox="0 0 512 512" width="20" height="20"><path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="32" d="M315.27 33L96 304h128l-31.51 173.23a2.36 2.36 0 002.33 2.77h0a2.36 2.36 0 001.89-.95L416 208H288l31.66-173.25a2.45 2.45 0 00-2.44-2.75h0a2.42 2.42 0 00-1.95 1z"/></svg>', ge = '<svg viewBox="0 0 512 512" width="20" height="20"><path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="32" d="M144 48v272a48 48 0 0048 48h272"/><path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="32" d="M368 464V192a48 48 0 00-48-48H48"/></svg>', Oe = '<svg viewBox="0 0 512 512" width="20" height="20"><path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="32" d="M380.93 57.37A32 32 0 00358.3 48H94.22A46.21 46.21 0 0048 94.22v323.56A46.21 46.21 0 0094.22 464h323.56A46.36 46.36 0 00464 417.78V153.7a32 32 0 00-9.37-22.63zM256 416a64 64 0 1164-64 63.92 63.92 0 01-64 64zm48-224H112a16 16 0 01-16-16v-64a16 16 0 0116-16h192a16 16 0 0116 16v64a16 16 0 01-16 16z"/></svg>', te = '<svg viewBox="0 0 512 512" width="20" height="20"><path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="32" d="M368 368L144 144M368 144L144 368"/></svg>', be = '<svg viewBox="0 0 512 512" width="20" height="20"><path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="32" d="M320 146s24.36-12-64-12a160 160 0 10160 160"/><path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="32" d="M256 58l80 80-80 80"/></svg>', Le = '<svg viewBox="0 0 512 512" width="20" height="20"><path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="32" d="M112 112l20 320c.95 18.49 14.4 32 32 32h184c17.67 0 30.87-13.51 32-32l20-320"/><path fill="none" stroke="currentColor" stroke-linecap="round" stroke-miterlimit="10" stroke-width="32" d="M80 112h352"/><path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="32" d="M192 112V72h0a23.93 23.93 0 0124-24h80a23.93 23.93 0 0124 24h0v40M256 176v224M184 176l8 224M328 176l-8 224"/></svg>', De = '<svg viewBox="0 0 512 512" width="20" height="20"><path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="32" d="M64 192v-72a40 40 0 0140-40h75.89a40 40 0 0122.19 6.72l27.84 18.56a40 40 0 0022.19 6.72H408a40 40 0 0140 40v40"/><path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="32" d="M479.9 226.55L463.68 392a40 40 0 01-39.93 40H88.25a40 40 0 01-39.93-40L32.1 226.55A32 32 0 0164 192h384.1a32 32 0 0131.8 34.55z"/></svg>', ee = '<svg viewBox="0 0 512 512" width="20" height="20"><path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="32" d="M416 128L192 384l-96-96"/></svg>', Ve = '<svg viewBox="0 0 512 512" width="20" height="20"><rect x="64" y="64" width="384" height="384" rx="48" fill="none" stroke="currentColor" stroke-linejoin="round" stroke-width="32"/></svg>', Ue = '<svg viewBox="0 0 512 512" width="20" height="20"><circle cx="256" cy="256" r="208" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="32"/></svg>', je = '<svg viewBox="0 0 512 512" width="20" height="20"><path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="32" d="M80 96h64l64 320h64l64-160h96"/></svg>', ie = '<svg viewBox="0 0 512 512" width="20" height="20"><path fill="none" stroke="currentColor" stroke-linecap="round" stroke-miterlimit="10" stroke-width="32" d="M256 48v48M256 416v48M403.08 108.92l-33.94 33.94M142.86 369.14l-33.94 33.94M464 256h-48M96 256H48M403.08 403.08l-33.94-33.94M142.86 142.86l-33.94-33.94"/><circle cx="256" cy="256" r="80" fill="none" stroke="currentColor" stroke-linecap="round" stroke-miterlimit="10" stroke-width="32"/></svg>', re = '<svg viewBox="0 0 512 512" width="20" height="20"><path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="32" d="M160 136c0-30.62 4.51-61.61 16-88C99.57 81.27 48 159.32 48 248c0 119.29 96.71 216 216 216 88.68 0 166.73-51.57 200-128-26.39 11.49-57.38 16-88 16-119.29 0-216-96.71-216-216z"/></svg>', qe = '<svg viewBox="0 0 512 512" width="20" height="20"><path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="32" d="M436 80H76a44.05 44.05 0 00-44 44v264a44.05 44.05 0 0044 44h360a44.05 44.05 0 0044-44V124a44.05 44.05 0 00-44-44z"/><circle cx="256" cy="256" r="80" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="32"/><path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="32" d="M220 80v56M292 80v56M220 376v56M292 376v56M80 144h56M80 224h56M80 304h56M376 144h56M376 224h56M376 304h56"/></svg>';
1265
- class He {
1500
+ class ft {
1266
1501
  constructor(e, t) {
1267
1502
  this.state = e, this.editor = t, this.element = null, this._unsubscribers = [];
1268
1503
  }
@@ -1271,9 +1506,9 @@ class He {
1271
1506
  * @returns {HTMLElement}
1272
1507
  */
1273
1508
  render() {
1274
- this.element = u("div", { className: "editor-toolbar" });
1275
- const e = u("div", { className: "toolbar-section toolbar-left" }), t = C({
1276
- icon: De,
1509
+ this.element = p("div", { className: "editor-toolbar" });
1510
+ const e = p("div", { className: "toolbar-section toolbar-left" }), t = z({
1511
+ icon: st,
1277
1512
  title: "Open Image",
1278
1513
  className: "toolbar-btn",
1279
1514
  testId: "btn-open-image",
@@ -1281,8 +1516,8 @@ class He {
1281
1516
  onClick: () => this.editor.openFilePicker()
1282
1517
  });
1283
1518
  e.appendChild(t);
1284
- const i = u("div", { className: "toolbar-section toolbar-center" }), r = C({
1285
- icon: Re,
1519
+ const i = p("div", { className: "toolbar-section toolbar-center" }), r = z({
1520
+ icon: We,
1286
1521
  title: "Zoom Out",
1287
1522
  className: "toolbar-btn",
1288
1523
  testId: "btn-zoom-out",
@@ -1292,14 +1527,14 @@ class He {
1292
1527
  this.editor.setZoom(h - 0.25);
1293
1528
  }
1294
1529
  });
1295
- this._zoomLabel = u("span", {
1530
+ this._zoomLabel = p("span", {
1296
1531
  className: "zoom-label",
1297
1532
  "aria-live": "polite",
1298
1533
  "aria-atomic": "true",
1299
1534
  role: "status"
1300
1535
  }, "100%");
1301
- const a = C({
1302
- icon: ze,
1536
+ const a = z({
1537
+ icon: $e,
1303
1538
  title: "Zoom In",
1304
1539
  className: "toolbar-btn",
1305
1540
  testId: "btn-zoom-in",
@@ -1308,25 +1543,25 @@ class He {
1308
1543
  const h = this.state.get("zoom");
1309
1544
  this.editor.setZoom(h + 0.25);
1310
1545
  }
1311
- }), o = C({
1312
- icon: Ne,
1546
+ }), n = z({
1547
+ icon: Ze,
1313
1548
  title: "Fit to Screen",
1314
1549
  className: "toolbar-btn",
1315
1550
  testId: "btn-fit-screen",
1316
1551
  ariaLabel: "Fit to screen",
1317
1552
  onClick: () => this.editor.fitToScreen()
1318
1553
  });
1319
- i.appendChild(r), i.appendChild(this._zoomLabel), i.appendChild(a), i.appendChild(o);
1320
- const n = u("div", { className: "toolbar-section toolbar-right" });
1321
- this._themeBtn = C({
1322
- icon: this.state.get("isDarkMode") ? ie : re,
1554
+ i.appendChild(r), i.appendChild(this._zoomLabel), i.appendChild(a), i.appendChild(n);
1555
+ const o = p("div", { className: "toolbar-section toolbar-right" });
1556
+ this._themeBtn = z({
1557
+ icon: this.state.get("isDarkMode") ? he : de,
1323
1558
  title: "Toggle Theme",
1324
1559
  className: "toolbar-btn toolbar-btn-theme",
1325
1560
  testId: "btn-toggle-theme",
1326
1561
  ariaLabel: "Toggle theme",
1327
1562
  onClick: () => this.editor.toggleTheme()
1328
- }), this._cropBtn = C({
1329
- icon: ge,
1563
+ }), this._cropBtn = z({
1564
+ icon: ke,
1330
1565
  title: "Crop",
1331
1566
  className: "toolbar-btn toolbar-btn-crop",
1332
1567
  testId: "btn-crop",
@@ -1335,29 +1570,29 @@ class He {
1335
1570
  this.state.get("mode") === "crop" ? this.editor.setMode("filters") : this.editor.setMode("crop");
1336
1571
  }
1337
1572
  });
1338
- const l = C({
1339
- icon: be,
1573
+ const l = z({
1574
+ icon: Fe,
1340
1575
  title: "Reset All",
1341
1576
  className: "toolbar-btn",
1342
1577
  testId: "btn-reset-all",
1343
1578
  ariaLabel: "Reset all changes",
1344
1579
  onClick: () => this.editor.resetAll()
1345
- }), c = C({
1346
- icon: Oe,
1580
+ }), c = z({
1581
+ icon: it,
1347
1582
  title: "Save Image",
1348
1583
  className: "toolbar-btn toolbar-btn-primary",
1349
1584
  testId: "btn-save-edit",
1350
1585
  ariaLabel: "Save image",
1351
1586
  onClick: () => this.editor.save()
1352
- }), d = C({
1353
- icon: te,
1587
+ }), d = z({
1588
+ icon: oe,
1354
1589
  title: "Close",
1355
1590
  className: "toolbar-btn",
1356
1591
  testId: "btn-cancel-edit",
1357
1592
  ariaLabel: "Close editor",
1358
1593
  onClick: () => this.editor.close()
1359
1594
  });
1360
- return n.appendChild(this._themeBtn), n.appendChild(this._cropBtn), n.appendChild(l), n.appendChild(c), n.appendChild(d), this.element.appendChild(e), this.element.appendChild(i), this.element.appendChild(n), this._subscribeToState(), this.element;
1595
+ return o.appendChild(this._themeBtn), o.appendChild(this._cropBtn), o.appendChild(l), o.appendChild(c), o.appendChild(d), this.element.appendChild(e), this.element.appendChild(i), this.element.appendChild(o), this._subscribeToState(), this.element;
1361
1596
  }
1362
1597
  /**
1363
1598
  * Subscribe to state changes
@@ -1368,7 +1603,7 @@ class He {
1368
1603
  });
1369
1604
  this._unsubscribers.push(e);
1370
1605
  const t = this.state.on("change:isDarkMode", ({ value: r }) => {
1371
- this._themeBtn.innerHTML = r ? ie : re;
1606
+ this._themeBtn.innerHTML = r ? he : de;
1372
1607
  });
1373
1608
  this._unsubscribers.push(t);
1374
1609
  const i = this.state.on("change:mode", ({ value: r }) => {
@@ -1391,34 +1626,8 @@ class He {
1391
1626
  this._unsubscribers.forEach((t) => t()), this._unsubscribers = [], (e = this.element) == null || e.remove(), this.element = null;
1392
1627
  }
1393
1628
  }
1394
- const j = [
1395
- { id: "adjust", name: "Adjust", icon: Te },
1396
- // adjustment, adjustmentAdvanced, alpha
1397
- { id: "blur", name: "Blur", icon: Ie },
1398
- // blur, kawaseBlur, motionBlur, radialBlur, etc.
1399
- { id: "color", name: "Color", icon: Ee },
1400
- // colorOverlay, grayscale, hslAdjustment, etc.
1401
- { id: "effects", name: "Effects", icon: Xe },
1402
- // noise, vignette, pixelate, dropShadow, etc.
1403
- { id: "distortion", name: "Distortion", icon: Ye },
1404
- // twist, bulgePinch, displacement, etc.
1405
- { id: "light", name: "Light", icon: Be },
1406
- // bloom, glow, godray, advancedBloom
1407
- { id: "stylize", name: "Stylize", icon: qe },
1408
- // ascii, crt, crossHatch, dot, emboss
1409
- { id: "crop", name: "Crop", icon: ge }
1410
- ], $e = {
1411
- adjust: "adjust",
1412
- blur: "blur",
1413
- color: "color",
1414
- effects: "effects",
1415
- distortion: "distortion",
1416
- light: "light",
1417
- stylize: "stylize",
1418
- advanced: "adjust"
1419
- // colorMatrix goes to adjust category
1420
- };
1421
- class We {
1629
+ const G = le;
1630
+ class mt {
1422
1631
  constructor(e, t) {
1423
1632
  this.state = e, this.editor = t, this.element = null, this._chips = /* @__PURE__ */ new Map(), this._scrollIndex = 0, this._unsubscribers = [];
1424
1633
  }
@@ -1428,35 +1637,35 @@ class We {
1428
1637
  * @returns {HTMLElement}
1429
1638
  */
1430
1639
  render(e) {
1431
- this._onSelect = e, this.element = u("div", {
1640
+ this._onSelect = e, this.element = p("div", {
1432
1641
  className: "category-carousel-container",
1433
1642
  "data-testid": "category-carousel"
1434
- }), this._leftBtn = C({
1435
- icon: fe,
1643
+ }), this._leftBtn = z({
1644
+ icon: Me,
1436
1645
  title: "Previous categories",
1437
1646
  className: "carousel-nav carousel-nav-left",
1438
1647
  onClick: () => this._scrollLeft()
1439
- }), this._carousel = u("div", { className: "category-carousel" }), j.forEach((i) => {
1440
- const r = J({
1648
+ }), this._carousel = p("div", { className: "category-carousel" }), G.forEach((i) => {
1649
+ const r = ne({
1441
1650
  label: i.name,
1442
1651
  icon: i.icon,
1443
1652
  active: this.state.get("selectedCategory") === i.id,
1444
1653
  onClick: () => this._selectCategory(i.id)
1445
1654
  });
1446
1655
  r.dataset.categoryId = i.id, r.dataset.category = i.id, r.dataset.testid = `category-${i.id}`, this._chips.set(i.id, r), this._carousel.appendChild(r);
1447
- }), this._rightBtn = C({
1448
- icon: me,
1656
+ }), this._rightBtn = z({
1657
+ icon: Pe,
1449
1658
  title: "Next categories",
1450
1659
  className: "carousel-nav carousel-nav-right",
1451
1660
  onClick: () => this._scrollRight()
1452
- }), this._pagination = u("div", {
1661
+ }), this._pagination = p("div", {
1453
1662
  className: "carousel-pagination",
1454
1663
  role: "tablist",
1455
1664
  "aria-label": "Category pages"
1456
1665
  });
1457
- const t = Math.ceil(j.length / 3);
1666
+ const t = Math.ceil(G.length / 3);
1458
1667
  for (let i = 0; i < t; i++) {
1459
- const r = u("button", {
1668
+ const r = p("button", {
1460
1669
  type: "button",
1461
1670
  className: `pagination-dot ${i === 0 ? "active" : ""}`,
1462
1671
  role: "tab",
@@ -1501,7 +1710,7 @@ class We {
1501
1710
  * Scroll carousel right
1502
1711
  */
1503
1712
  _scrollRight() {
1504
- this._scrollIndex < j.length - 3 && (this._scrollIndex++, this._scrollCarousel());
1713
+ this._scrollIndex < G.length - 3 && (this._scrollIndex++, this._scrollCarousel());
1505
1714
  }
1506
1715
  /**
1507
1716
  * Scroll to a specific page
@@ -1528,7 +1737,7 @@ class We {
1528
1737
  * Update navigation button states
1529
1738
  */
1530
1739
  _updateNavButtons() {
1531
- this._leftBtn && (this._leftBtn.disabled = this._scrollIndex === 0), this._rightBtn && (this._rightBtn.disabled = this._scrollIndex >= j.length - 3);
1740
+ this._leftBtn && (this._leftBtn.disabled = this._scrollIndex === 0), this._rightBtn && (this._rightBtn.disabled = this._scrollIndex >= G.length - 3);
1532
1741
  }
1533
1742
  /**
1534
1743
  * Update pagination dot states
@@ -1557,7 +1766,7 @@ class We {
1557
1766
  this._unsubscribers.forEach((t) => t()), this._unsubscribers = [], this._chips.clear(), (e = this.element) == null || e.remove(), this.element = null;
1558
1767
  }
1559
1768
  }
1560
- class Ze {
1769
+ class gt {
1561
1770
  constructor(e, t) {
1562
1771
  this.state = e, this.filterManager = t, this.element = null, this._filterCards = /* @__PURE__ */ new Map(), this._scrollIndex = 0, this._unsubscribers = [], this._onToggle = null, this._onSelect = null;
1563
1772
  }
@@ -1567,13 +1776,13 @@ class Ze {
1567
1776
  * @returns {HTMLElement}
1568
1777
  */
1569
1778
  render({ onToggle: e, onSelect: t }) {
1570
- return this._onToggle = e, this._onSelect = t, this.element = u("div", { className: "filter-carousel-container" }), this._leftBtn = C({
1571
- icon: fe,
1779
+ return this._onToggle = e, this._onSelect = t, this.element = p("div", { className: "filter-carousel-container" }), this._leftBtn = z({
1780
+ icon: Me,
1572
1781
  title: "Previous filters",
1573
1782
  className: "carousel-nav carousel-nav-left",
1574
1783
  onClick: () => this._scrollLeft()
1575
- }), this._carousel = u("div", { className: "filter-carousel" }), this._rightBtn = C({
1576
- icon: me,
1784
+ }), this._carousel = p("div", { className: "filter-carousel" }), this._rightBtn = z({
1785
+ icon: Pe,
1577
1786
  title: "Next filters",
1578
1787
  className: "carousel-nav carousel-nav-right",
1579
1788
  onClick: () => this._scrollRight()
@@ -1605,11 +1814,11 @@ class Ze {
1605
1814
  if (e === "crop") return;
1606
1815
  const t = this.filterManager.getFiltersByCategory(e), i = this.state.get("activeFilters"), r = this.state.get("selectedFilter");
1607
1816
  t.forEach((a) => {
1608
- const o = this._createFilterCard(a, {
1817
+ const n = this._createFilterCard(a, {
1609
1818
  isActive: i.has(a.id),
1610
1819
  isSelected: r === a.id
1611
1820
  });
1612
- this._filterCards.set(a.id, o), this._carousel.appendChild(o);
1821
+ this._filterCards.set(a.id, n), this._carousel.appendChild(n);
1613
1822
  }), this._updateNavButtons();
1614
1823
  }
1615
1824
  /**
@@ -1619,23 +1828,23 @@ class Ze {
1619
1828
  * @returns {HTMLElement}
1620
1829
  */
1621
1830
  _createFilterCard(e, { isActive: t, isSelected: i }) {
1622
- const r = u("div", {
1831
+ const r = p("div", {
1623
1832
  className: `filter-card ${t ? "active" : ""} ${i ? "selected" : ""}`,
1624
1833
  "data-filter": e.id,
1625
1834
  "data-testid": `filter-${e.id}`,
1626
1835
  onClick: () => this._handleCardClick(e.id)
1627
- }), a = u("div", { className: "filter-preview" }), o = u("span", { className: "filter-preview-text" }, e.name.charAt(0));
1628
- a.appendChild(o);
1629
- const n = u("span", { className: "filter-name", title: e.name }, e.name), l = u("button", {
1836
+ }), a = p("div", { className: "filter-preview" }), n = p("span", { className: "filter-preview-text" }, e.name.charAt(0));
1837
+ a.appendChild(n);
1838
+ const o = p("span", { className: "filter-name", title: e.name }, e.name), l = p("button", {
1630
1839
  className: `filter-toggle ${t ? "active" : ""}`,
1631
1840
  onClick: (c) => {
1632
- var p;
1841
+ var u;
1633
1842
  c.stopPropagation();
1634
1843
  const h = !this.state.get("activeFilters").has(e.id);
1635
- this._handleToggle(e.id, h), h && (this.state.set("selectedFilter", e.id), (p = this._onSelect) == null || p.call(this, e.id));
1844
+ this._handleToggle(e.id, h), h && (this.state.set("selectedFilter", e.id), (u = this._onSelect) == null || u.call(this, e.id));
1636
1845
  }
1637
1846
  });
1638
- return l.innerHTML = t ? ee : "", r.appendChild(a), r.appendChild(n), r.appendChild(l), r._toggle = l, r._isActive = t, r;
1847
+ return l.innerHTML = t ? se : "", r.appendChild(a), r.appendChild(o), r.appendChild(l), r._toggle = l, r._isActive = t, r;
1639
1848
  }
1640
1849
  /**
1641
1850
  * Handle filter card click (select)
@@ -1661,7 +1870,7 @@ class Ze {
1661
1870
  const e = this.state.get("activeFilters");
1662
1871
  this._filterCards.forEach((t, i) => {
1663
1872
  const r = e.has(i);
1664
- t.classList.toggle("active", r), t._toggle.classList.toggle("active", r), t._toggle.innerHTML = r ? ee : "", t._isActive = r;
1873
+ t.classList.toggle("active", r), t._toggle.classList.toggle("active", r), t._toggle.innerHTML = r ? se : "", t._isActive = r;
1665
1874
  });
1666
1875
  }
1667
1876
  /**
@@ -1714,7 +1923,7 @@ class Ze {
1714
1923
  this._unsubscribers.forEach((t) => t()), this._unsubscribers = [], this._filterCards.clear(), (e = this.element) == null || e.remove(), this.element = null;
1715
1924
  }
1716
1925
  }
1717
- class Ge {
1926
+ class bt {
1718
1927
  constructor(e, t) {
1719
1928
  this.state = e, this.filterManager = t, this.element = null, this._controls = /* @__PURE__ */ new Map(), this._onChange = null, this._onReset = null, this._onAction = null, this._unsubscribers = [];
1720
1929
  }
@@ -1724,7 +1933,7 @@ class Ge {
1724
1933
  * @returns {HTMLElement}
1725
1934
  */
1726
1935
  render({ onChange: e, onReset: t, onAction: i }) {
1727
- return this._onChange = e, this._onReset = t, this._onAction = i, this.element = u("div", { className: "filter-adjustments" }), this._subscribeToState(), this._renderControls(), this.element;
1936
+ return this._onChange = e, this._onReset = t, this._onAction = i, this.element = p("div", { className: "filter-adjustments" }), this._subscribeToState(), this._renderControls(), this.element;
1728
1937
  }
1729
1938
  /**
1730
1939
  * Subscribe to state changes
@@ -1740,38 +1949,62 @@ class Ge {
1740
1949
  this._unsubscribers.push(t);
1741
1950
  }
1742
1951
  /**
1743
- * Render controls for the selected filter
1952
+ * Render controls for the selected filter.
1953
+ *
1954
+ * Renders both the static controls from def.controls and any dynamic
1955
+ * controls the filter instance exposes via getDynamicControls() (e.g.
1956
+ * per-stop color/offset/alpha rows for Color Gradient).
1744
1957
  */
1745
1958
  _renderControls() {
1746
1959
  this.element.innerHTML = "", this._controls.clear();
1747
1960
  const e = this.state.get("selectedFilter");
1748
1961
  if (!e) {
1749
1962
  this.element.appendChild(
1750
- u("div", { className: "no-filter-selected" }, "Select a filter to adjust")
1963
+ p("div", { className: "no-filter-selected" }, "Select a filter to adjust")
1751
1964
  );
1752
1965
  return;
1753
1966
  }
1754
1967
  const t = this.filterManager.getFilterDef(e);
1755
1968
  if (!t) {
1756
1969
  this.element.appendChild(
1757
- u("div", { className: "no-filter-selected" }, "Filter not found")
1970
+ p("div", { className: "no-filter-selected" }, "Filter not found")
1758
1971
  );
1759
1972
  return;
1760
1973
  }
1761
- const i = u("div", { className: "adjustments-header" });
1762
- i.appendChild(u("span", { className: "adjustments-title" }, t.name)), i.appendChild(N({
1974
+ const i = p("div", { className: "adjustments-header" });
1975
+ i.appendChild(p("span", { className: "adjustments-title" }, t.name)), i.appendChild(O({
1763
1976
  label: "Reset",
1764
1977
  className: "btn-text",
1765
1978
  onClick: () => this._handleReset(e)
1766
1979
  })), this.element.appendChild(i);
1767
- const r = u("div", { className: "adjustments-grid" }), a = this.state.getFilterValues(e);
1768
- t.controls.forEach((o) => {
1769
- const n = this._createControl(e, o, a[o.id] ?? o.default);
1770
- n && (this._controls.set(o.id, n), r.appendChild(n));
1771
- }), this.element.appendChild(r);
1980
+ const r = p("div", { className: "adjustments-grid" }), a = this.state.getFilterValues(e);
1981
+ (t.controls || []).forEach((o) => {
1982
+ const l = a[o.id] ?? o.default, c = this._createControl(e, o, l);
1983
+ c && (this._controls.set(o.id, c), r.appendChild(c));
1984
+ });
1985
+ const n = this.filterManager.getInstance(e);
1986
+ if (n && typeof n.getDynamicControls == "function") {
1987
+ let o = [];
1988
+ try {
1989
+ o = n.getDynamicControls() || [];
1990
+ } catch {
1991
+ }
1992
+ o.forEach((l) => {
1993
+ const c = l.property || l.id, d = a[c] ?? l.default, h = this._createControl(e, l, d);
1994
+ h && (this._controls.set(l.id, h), r.appendChild(h));
1995
+ });
1996
+ }
1997
+ this.element.appendChild(r);
1772
1998
  }
1773
1999
  /**
1774
- * Create a control element based on type
2000
+ * Create a control element based on type.
2001
+ *
2002
+ * The update key passed to _handleChange is `ctl.property || ctl.id`.
2003
+ * Dynamic controls (e.g. from getDynamicControls) use their property
2004
+ * path (e.g. 'colorStops[0].color') so FilterManager.updateValue can
2005
+ * route the write correctly. Static controls without a property fall
2006
+ * back to the control id, matching the legacy contract.
2007
+ *
1775
2008
  * @param {string} filterId
1776
2009
  * @param {Object} ctl - Control definition
1777
2010
  * @param {*} value - Current value
@@ -1779,48 +2012,56 @@ class Ge {
1779
2012
  */
1780
2013
  _createControl(e, t, i) {
1781
2014
  if (t.hidden) return null;
1782
- const r = t.label || t.id;
1783
- switch (this._normalizeControlType(t.type)) {
2015
+ const r = t.label || t.id, a = this._normalizeControlType(t.type), n = t.property || t.id;
2016
+ switch (a) {
1784
2017
  case "slider":
1785
- return he({
2018
+ return Ae({
1786
2019
  id: `${e}-${t.id}`,
1787
2020
  label: r,
1788
2021
  min: t.min ?? 0,
1789
2022
  max: t.max ?? 1,
1790
2023
  step: t.step ?? 0.01,
1791
2024
  value: typeof i == "number" ? i : t.default ?? 0,
1792
- onChange: (l) => this._handleChange(e, t.id, l)
2025
+ onChange: (c) => this._handleChange(e, n, c)
1793
2026
  });
1794
2027
  case "toggle":
1795
- return de({
2028
+ return ze({
1796
2029
  id: `${e}-${t.id}`,
1797
2030
  label: r,
1798
2031
  checked: !!i,
1799
- onChange: (l) => this._handleChange(e, t.id, l)
2032
+ onChange: (c) => this._handleChange(e, n, c)
1800
2033
  });
1801
2034
  case "color":
1802
- return ue({
2035
+ return Ne({
1803
2036
  id: `${e}-${t.id}`,
1804
2037
  label: r,
1805
2038
  value: typeof i == "string" && i.startsWith("#") ? i : t.default || "#000000",
1806
- onChange: (l) => this._handleChange(e, t.id, l)
2039
+ onChange: (c) => this._handleChange(e, n, c)
1807
2040
  });
1808
2041
  case "select":
1809
2042
  const o = this._normalizeOptions(t.options);
1810
- return pe({
2043
+ return Te({
1811
2044
  id: `${e}-${t.id}`,
1812
2045
  label: r,
1813
2046
  options: o,
1814
2047
  value: i ?? t.default,
1815
- onChange: (l) => this._handleChange(e, t.id, l)
2048
+ onChange: (c) => this._handleChange(e, n, c)
2049
+ });
2050
+ case "text":
2051
+ return Re({
2052
+ id: `${e}-${t.id}`,
2053
+ label: r,
2054
+ value: typeof i == "string" ? i : t.default ?? "",
2055
+ placeholder: t.placeholder || "",
2056
+ onCommit: (c) => this._handleChange(e, n, c)
1816
2057
  });
1817
2058
  case "button":
1818
- const n = u("div", { className: "button-control" });
1819
- return n.appendChild(N({
2059
+ const l = p("div", { className: "button-control" });
2060
+ return l.appendChild(O({
1820
2061
  label: r,
1821
2062
  className: "btn-secondary",
1822
2063
  onClick: () => this._handleAction(e, t.action || t.id)
1823
- })), n;
2064
+ })), l;
1824
2065
  default:
1825
2066
  return null;
1826
2067
  }
@@ -1834,17 +2075,13 @@ class Ge {
1834
2075
  return {
1835
2076
  slider: "slider",
1836
2077
  range: "slider",
1837
- // 'range' is an alias for 'slider'
1838
2078
  toggle: "toggle",
1839
2079
  checkbox: "toggle",
1840
- // 'checkbox' is an alias for 'toggle'
1841
2080
  color: "color",
1842
2081
  select: "select",
1843
2082
  dropdown: "select",
1844
- // 'dropdown' is an alias for 'select'
1845
2083
  button: "button",
1846
- text: "slider"
1847
- // 'text' fallback to slider for numeric inputs
2084
+ text: "text"
1848
2085
  }[e] || e;
1849
2086
  }
1850
2087
  /**
@@ -1874,13 +2111,16 @@ class Ge {
1874
2111
  (t = this._onReset) == null || t.call(this, e), this._renderControls();
1875
2112
  }
1876
2113
  /**
1877
- * Handle button action
2114
+ * Handle button action. Dynamic controls (e.g. color stop rows) depend on
2115
+ * filter state that can change as a result of the action (add/remove stop),
2116
+ * so re-render after the action completes.
2117
+ *
1878
2118
  * @param {string} filterId
1879
2119
  * @param {string} action
1880
2120
  */
1881
2121
  _handleAction(e, t) {
1882
2122
  var i;
1883
- (i = this._onAction) == null || i.call(this, e, t);
2123
+ (i = this._onAction) == null || i.call(this, e, t), this._renderControls();
1884
2124
  }
1885
2125
  /**
1886
2126
  * Update control values from state
@@ -1892,8 +2132,8 @@ class Ge {
1892
2132
  i && i.controls.forEach((r) => {
1893
2133
  const a = this._controls.get(r.id);
1894
2134
  if (a && typeof a.setValue == "function") {
1895
- const o = t[r.id] ?? r.default;
1896
- a.setValue(o);
2135
+ const n = t[r.id] ?? r.default;
2136
+ a.setValue(n);
1897
2137
  }
1898
2138
  });
1899
2139
  }
@@ -1917,7 +2157,7 @@ class Ge {
1917
2157
  this._unsubscribers.forEach((t) => t()), this._unsubscribers = [], this._controls.clear(), (e = this.element) == null || e.remove(), this.element = null;
1918
2158
  }
1919
2159
  }
1920
- class Ke {
2160
+ class yt {
1921
2161
  constructor(e, t) {
1922
2162
  this.state = e, this.filterManager = t, this._drawer = null, this._body = null, this._titleEl = null, this._isOpen = !1, this._currentFilterId = null, this._controls = /* @__PURE__ */ new Map(), this._onChange = null, this._onReset = null, this._onRemove = null, this._onAction = null, this._container = null;
1923
2163
  }
@@ -1927,31 +2167,31 @@ class Ke {
1927
2167
  * @param {Object} callbacks - { onChange, onReset, onRemove, onAction }
1928
2168
  */
1929
2169
  build(e, { onChange: t, onReset: i, onRemove: r, onAction: a }) {
1930
- this._onChange = t, this._onReset = i, this._onRemove = r, this._onAction = a, this._container = e, this._drawer = u("div", { className: "mobile-filter-drawer" });
1931
- const o = u("div", { className: "drawer-header" });
1932
- this._titleEl = u("span", { className: "drawer-title" }, "Filter");
1933
- const n = u("div", { className: "drawer-header-actions" }), l = N({
2170
+ this._onChange = t, this._onReset = i, this._onRemove = r, this._onAction = a, this._container = e, this._drawer = p("div", { className: "mobile-filter-drawer" });
2171
+ const n = p("div", { className: "drawer-header" });
2172
+ this._titleEl = p("span", { className: "drawer-title" }, "Filter");
2173
+ const o = p("div", { className: "drawer-header-actions" }), l = O({
1934
2174
  label: "Reset",
1935
2175
  className: "btn-text",
1936
2176
  onClick: () => {
1937
2177
  var h;
1938
2178
  this._currentFilterId && ((h = this._onReset) == null || h.call(this, this._currentFilterId), this._renderControls());
1939
2179
  }
1940
- }), c = N({
2180
+ }), c = O({
1941
2181
  label: "Remove",
1942
2182
  className: "btn-text btn-danger",
1943
2183
  onClick: () => {
1944
2184
  var h;
1945
2185
  this._currentFilterId && ((h = this._onRemove) == null || h.call(this, this._currentFilterId), this.close());
1946
2186
  }
1947
- }), d = C({
1948
- icon: te,
2187
+ }), d = z({
2188
+ icon: oe,
1949
2189
  title: "Close",
1950
2190
  className: "btn-icon-sm",
1951
2191
  ariaLabel: "Close drawer",
1952
2192
  onClick: () => this.close()
1953
2193
  });
1954
- n.appendChild(l), n.appendChild(c), n.appendChild(d), o.appendChild(this._titleEl), o.appendChild(n), this._drawer.appendChild(o), this._body = u("div", { className: "drawer-body" }), this._drawer.appendChild(this._body), e.appendChild(this._drawer);
2194
+ o.appendChild(l), o.appendChild(c), o.appendChild(d), n.appendChild(this._titleEl), n.appendChild(o), this._drawer.appendChild(n), this._body = p("div", { className: "drawer-body" }), this._drawer.appendChild(this._body), e.appendChild(this._drawer);
1955
2195
  }
1956
2196
  /**
1957
2197
  * Open the drawer for a specific filter
@@ -1994,32 +2234,49 @@ class Ke {
1994
2234
  this._drawer.style.transition = "transform 0.2s cubic-bezier(0.32, 0, 0.67, 0)", this._drawer.style.transform = "translateY(100%)";
1995
2235
  }
1996
2236
  /**
1997
- * Render controls for the current filter
2237
+ * Render controls for the current filter.
2238
+ * Renders both static (def.controls) and dynamic (instance.getDynamicControls)
2239
+ * controls so filters like Color Gradient show per-stop rows.
1998
2240
  */
1999
2241
  _renderControls() {
2000
2242
  if (this._body.innerHTML = "", this._controls.clear(), !this._currentFilterId) return;
2001
2243
  const e = this.filterManager.getFilterDef(this._currentFilterId);
2002
2244
  if (!e) return;
2003
2245
  this._titleEl.textContent = e.name;
2004
- const t = u("div", { className: "adjustments-grid" }), i = this.state.getFilterValues(this._currentFilterId);
2005
- e.controls.forEach((r) => {
2006
- if (r.hidden) return;
2007
- const a = this._createControl(this._currentFilterId, r, i[r.id] ?? r.default);
2008
- a && (this._controls.set(r.id, a), t.appendChild(a));
2009
- }), this._body.appendChild(t);
2246
+ const t = p("div", { className: "adjustments-grid" }), i = this.state.getFilterValues(this._currentFilterId);
2247
+ (e.controls || []).forEach((a) => {
2248
+ if (a.hidden) return;
2249
+ const n = this._createControl(this._currentFilterId, a, i[a.id] ?? a.default);
2250
+ n && (this._controls.set(a.id, n), t.appendChild(n));
2251
+ });
2252
+ const r = this.filterManager.getInstance(this._currentFilterId);
2253
+ if (r && typeof r.getDynamicControls == "function") {
2254
+ let a = [];
2255
+ try {
2256
+ a = r.getDynamicControls() || [];
2257
+ } catch {
2258
+ }
2259
+ a.forEach((n) => {
2260
+ const o = n.property || n.id, l = i[o] ?? n.default, c = this._createControl(this._currentFilterId, n, l);
2261
+ c && (this._controls.set(n.id, c), t.appendChild(c));
2262
+ });
2263
+ }
2264
+ this._body.appendChild(t);
2010
2265
  }
2011
2266
  /**
2012
- * Create a control element based on type
2267
+ * Create a control element based on type. See FilterAdjustments._createControl
2268
+ * for the update-key contract (property path for dynamic controls, id for static).
2013
2269
  * @param {string} filterId
2014
2270
  * @param {Object} ctl
2015
2271
  * @param {*} value
2016
2272
  * @returns {HTMLElement|null}
2017
2273
  */
2018
2274
  _createControl(e, t, i) {
2019
- const r = t.label || t.id;
2020
- switch (this._normalizeControlType(t.type)) {
2275
+ if (t.hidden) return null;
2276
+ const r = t.label || t.id, a = this._normalizeControlType(t.type), n = t.property || t.id;
2277
+ switch (a) {
2021
2278
  case "slider":
2022
- return he({
2279
+ return Ae({
2023
2280
  id: `drawer-${e}-${t.id}`,
2024
2281
  label: r,
2025
2282
  min: t.min ?? 0,
@@ -2027,51 +2284,62 @@ class Ke {
2027
2284
  step: t.step ?? 0.01,
2028
2285
  value: typeof i == "number" ? i : t.default ?? 0,
2029
2286
  onChange: (o) => {
2030
- var n;
2031
- return (n = this._onChange) == null ? void 0 : n.call(this, e, t.id, o);
2287
+ var l;
2288
+ return (l = this._onChange) == null ? void 0 : l.call(this, e, n, o);
2032
2289
  }
2033
2290
  });
2034
2291
  case "toggle":
2035
- return de({
2292
+ return ze({
2036
2293
  id: `drawer-${e}-${t.id}`,
2037
2294
  label: r,
2038
2295
  checked: !!i,
2039
2296
  onChange: (o) => {
2040
- var n;
2041
- return (n = this._onChange) == null ? void 0 : n.call(this, e, t.id, o);
2297
+ var l;
2298
+ return (l = this._onChange) == null ? void 0 : l.call(this, e, n, o);
2042
2299
  }
2043
2300
  });
2044
2301
  case "color":
2045
- return ue({
2302
+ return Ne({
2046
2303
  id: `drawer-${e}-${t.id}`,
2047
2304
  label: r,
2048
2305
  value: typeof i == "string" && i.startsWith("#") ? i : t.default || "#000000",
2049
2306
  onChange: (o) => {
2050
- var n;
2051
- return (n = this._onChange) == null ? void 0 : n.call(this, e, t.id, o);
2307
+ var l;
2308
+ return (l = this._onChange) == null ? void 0 : l.call(this, e, n, o);
2052
2309
  }
2053
2310
  });
2054
2311
  case "select": {
2055
2312
  const o = this._normalizeOptions(t.options);
2056
- return pe({
2313
+ return Te({
2057
2314
  id: `drawer-${e}-${t.id}`,
2058
2315
  label: r,
2059
2316
  options: o,
2060
2317
  value: i ?? t.default,
2061
- onChange: (n) => {
2062
- var l;
2063
- return (l = this._onChange) == null ? void 0 : l.call(this, e, t.id, n);
2318
+ onChange: (l) => {
2319
+ var c;
2320
+ return (c = this._onChange) == null ? void 0 : c.call(this, e, n, l);
2064
2321
  }
2065
2322
  });
2066
2323
  }
2324
+ case "text":
2325
+ return Re({
2326
+ id: `drawer-${e}-${t.id}`,
2327
+ label: r,
2328
+ value: typeof i == "string" ? i : t.default ?? "",
2329
+ placeholder: t.placeholder || "",
2330
+ onCommit: (o) => {
2331
+ var l;
2332
+ return (l = this._onChange) == null ? void 0 : l.call(this, e, n, o);
2333
+ }
2334
+ });
2067
2335
  case "button": {
2068
- const o = u("div", { className: "button-control" });
2069
- return o.appendChild(N({
2336
+ const o = p("div", { className: "button-control" });
2337
+ return o.appendChild(O({
2070
2338
  label: r,
2071
2339
  className: "btn-secondary",
2072
2340
  onClick: () => {
2073
- var n;
2074
- return (n = this._onAction) == null ? void 0 : n.call(this, e, t.action || t.id);
2341
+ var l;
2342
+ (l = this._onAction) == null || l.call(this, e, t.action || t.id), this._renderControls();
2075
2343
  }
2076
2344
  })), o;
2077
2345
  }
@@ -2094,7 +2362,7 @@ class Ke {
2094
2362
  select: "select",
2095
2363
  dropdown: "select",
2096
2364
  button: "button",
2097
- text: "slider"
2365
+ text: "text"
2098
2366
  }[e] || e;
2099
2367
  }
2100
2368
  /**
@@ -2113,7 +2381,7 @@ class Ke {
2113
2381
  this._controls.clear(), (e = this._drawer) == null || e.remove(), this._drawer = null, this._isOpen = !1, this._currentFilterId = null, this._container = null;
2114
2382
  }
2115
2383
  }
2116
- class Qe {
2384
+ class _t {
2117
2385
  constructor(e, t) {
2118
2386
  this.state = e, this.filterManager = t, this.element = null, this._scrollContainer = null, this._chips = /* @__PURE__ */ new Map(), this._unsubscribers = [], this._onToggle = null, this._onSelect = null;
2119
2387
  }
@@ -2122,10 +2390,10 @@ class Qe {
2122
2390
  * @returns {HTMLElement}
2123
2391
  */
2124
2392
  render({ onToggle: e, onSelect: t }) {
2125
- return this._onToggle = e, this._onSelect = t, this.element = u("div", {
2393
+ return this._onToggle = e, this._onSelect = t, this.element = p("div", {
2126
2394
  className: "mobile-active-filters",
2127
2395
  "data-testid": "mobile-active-filters"
2128
- }), this._scrollContainer = u("div", { className: "mobile-active-filters-scroll" }), this.element.appendChild(this._scrollContainer), this._subscribeToState(), this._renderChips(), this.element;
2396
+ }), this._scrollContainer = p("div", { className: "mobile-active-filters-scroll" }), this.element.appendChild(this._scrollContainer), this._subscribeToState(), this._renderChips(), this.element;
2129
2397
  }
2130
2398
  _subscribeToState() {
2131
2399
  const e = this.state.on("change:activeFilters", () => {
@@ -2141,7 +2409,7 @@ class Qe {
2141
2409
  this._scrollContainer.innerHTML = "", this._chips.clear();
2142
2410
  const e = this.state.get("activeFilters");
2143
2411
  if (!e || e.size === 0) {
2144
- const t = u("div", {
2412
+ const t = p("div", {
2145
2413
  className: "active-filter-placeholder"
2146
2414
  }, "No active filters");
2147
2415
  this._scrollContainer.appendChild(t);
@@ -2155,22 +2423,22 @@ class Qe {
2155
2423
  }), this._updateSelectedState();
2156
2424
  }
2157
2425
  _createChip(e, t) {
2158
- const i = u("div", {
2426
+ const i = p("div", {
2159
2427
  className: "active-filter-chip",
2160
2428
  "data-filter-id": e,
2161
2429
  "data-testid": `active-chip-${e}`
2162
- }), r = u("span", {
2430
+ }), r = p("span", {
2163
2431
  className: "active-filter-chip-label",
2164
- onClick: (o) => {
2165
- var n;
2166
- o.stopPropagation(), (n = this._onSelect) == null || n.call(this, e);
2432
+ onClick: (n) => {
2433
+ var o;
2434
+ n.stopPropagation(), (o = this._onSelect) == null || o.call(this, e);
2167
2435
  }
2168
- }, t.name), a = u("button", {
2436
+ }, t.name), a = p("button", {
2169
2437
  className: "active-filter-chip-check",
2170
2438
  "aria-label": `Remove ${t.name} filter`,
2171
- onClick: (o) => {
2172
- var n;
2173
- o.stopPropagation(), (n = this._onToggle) == null || n.call(this, e, !1);
2439
+ onClick: (n) => {
2440
+ var o;
2441
+ n.stopPropagation(), (o = this._onToggle) == null || o.call(this, e, !1);
2174
2442
  }
2175
2443
  });
2176
2444
  return a.innerHTML = '<svg width="10" height="10" viewBox="0 0 12 12"><path d="M2 6l3 3 5-5" stroke="currentColor" stroke-width="2" fill="none" stroke-linecap="round" stroke-linejoin="round"/></svg>', i.appendChild(r), i.appendChild(a), i;
@@ -2186,11 +2454,11 @@ class Qe {
2186
2454
  this._unsubscribers.forEach((t) => t()), this._unsubscribers = [], this._chips.clear(), (e = this.element) == null || e.remove(), this.element = null;
2187
2455
  }
2188
2456
  }
2189
- const Je = [
2190
- { id: "free", name: "Free", icon: je },
2191
- { id: "square", name: "Square", icon: Ve },
2192
- { id: "circle", name: "Circle", icon: Ue }
2193
- ], et = [
2457
+ const xt = [
2458
+ { id: "free", name: "Free", icon: ot },
2459
+ { id: "square", name: "Square", icon: at },
2460
+ { id: "circle", name: "Circle", icon: nt }
2461
+ ], Ct = [
2194
2462
  { id: "free", name: "Free" },
2195
2463
  { id: "1:1", name: "1:1" },
2196
2464
  { id: "4:3", name: "4:3" },
@@ -2198,7 +2466,7 @@ const Je = [
2198
2466
  { id: "3:2", name: "3:2" },
2199
2467
  { id: "2:3", name: "2:3" }
2200
2468
  ];
2201
- class tt {
2469
+ class wt {
2202
2470
  constructor(e, t) {
2203
2471
  this.state = e, this.cropManager = t, this.element = null, this._shapeChips = /* @__PURE__ */ new Map(), this._aspectChips = /* @__PURE__ */ new Map(), this._unsubscribers = [];
2204
2472
  }
@@ -2215,45 +2483,45 @@ class tt {
2215
2483
  * @returns {HTMLElement}
2216
2484
  */
2217
2485
  render() {
2218
- this.element = u("div", {
2486
+ this.element = p("div", {
2219
2487
  className: "crop-controls",
2220
2488
  "data-testid": "crop-controls"
2221
2489
  });
2222
- const e = u("div", { className: "crop-section" });
2223
- e.appendChild(u("label", { className: "section-label" }, "Shape"));
2224
- const t = u("div", { className: "chip-row" }), i = this.state.get("crop.shape");
2225
- Je.forEach((c) => {
2226
- const d = J({
2490
+ const e = p("div", { className: "crop-section" });
2491
+ e.appendChild(p("label", { className: "section-label" }, "Shape"));
2492
+ const t = p("div", { className: "chip-row" }), i = this.state.get("crop.shape");
2493
+ xt.forEach((c) => {
2494
+ const d = ne({
2227
2495
  label: c.name,
2228
2496
  icon: c.icon,
2229
2497
  active: i === c.id,
2230
2498
  onClick: () => this._selectShape(c.id)
2231
2499
  });
2232
2500
  d.dataset.shape = c.id, d.dataset.testid = `crop-shape-${c.id}`, this._shapeChips.set(c.id, d), t.appendChild(d);
2233
- }), e.appendChild(t), this.element.appendChild(e), this.state.get("lockCropShape") && (e.style.display = "none"), this._shapeSection = e, this._aspectSection = u("div", { className: "crop-section" }), this._aspectSection.appendChild(u("label", { className: "section-label" }, "Aspect Ratio"));
2234
- const r = u("div", { className: "chip-row aspect-row" }), a = this.state.get("crop.aspect");
2235
- et.forEach((c) => {
2236
- const d = J({
2501
+ }), e.appendChild(t), this.element.appendChild(e), this.state.get("lockCropShape") && (e.style.display = "none"), this._shapeSection = e, this._aspectSection = p("div", { className: "crop-section" }), this._aspectSection.appendChild(p("label", { className: "section-label" }, "Aspect Ratio"));
2502
+ const r = p("div", { className: "chip-row aspect-row" }), a = this.state.get("crop.aspect");
2503
+ Ct.forEach((c) => {
2504
+ const d = ne({
2237
2505
  label: c.name,
2238
2506
  active: a === c.id,
2239
2507
  onClick: () => this._selectAspect(c.id)
2240
2508
  });
2241
2509
  d.dataset.ratio = c.id, d.dataset.testid = `crop-ratio-${c.id}`, this._aspectChips.set(c.id, d), r.appendChild(d);
2242
2510
  }), this._aspectSection.appendChild(r), this.element.appendChild(this._aspectSection), this._updateAspectVisibility();
2243
- const o = u("div", { className: "crop-actions" }), n = N({
2511
+ const n = p("div", { className: "crop-actions" }), o = O({
2244
2512
  label: "Cancel",
2245
2513
  className: "btn-secondary crop-cancel-btn",
2246
- icon: te,
2514
+ icon: oe,
2247
2515
  onClick: () => this.cropManager.cancel()
2248
2516
  });
2249
- n.dataset.testid = "cancel-crop";
2250
- const l = N({
2517
+ o.dataset.testid = "cancel-crop";
2518
+ const l = O({
2251
2519
  label: "Apply Crop",
2252
2520
  className: "btn-primary crop-apply-btn",
2253
- icon: ee,
2521
+ icon: se,
2254
2522
  onClick: () => this._applyCropAndReturnToFilters()
2255
2523
  });
2256
- return l.dataset.testid = "apply-crop", o.appendChild(n), o.appendChild(l), this.element.appendChild(o), this._subscribeToState(), this.element;
2524
+ return l.dataset.testid = "apply-crop", n.appendChild(o), n.appendChild(l), this.element.appendChild(n), this._subscribeToState(), this.element;
2257
2525
  }
2258
2526
  /**
2259
2527
  * Subscribe to state changes
@@ -2313,7 +2581,7 @@ class tt {
2313
2581
  this._unsubscribers.forEach((t) => t()), this._unsubscribers = [], this._shapeChips.clear(), this._aspectChips.clear(), (e = this.element) == null || e.remove(), this.element = null;
2314
2582
  }
2315
2583
  }
2316
- class it {
2584
+ class St {
2317
2585
  constructor(e, t) {
2318
2586
  this.state = e, this.filterManager = t, this.element = null, this._filterItems = /* @__PURE__ */ new Map(), this._unsubscribers = [], this._onRemove = null, this._onReset = null, this._onClearAll = null, this._onUpdateValue = null, this._onSelect = null;
2319
2587
  }
@@ -2323,18 +2591,18 @@ class it {
2323
2591
  * @returns {HTMLElement}
2324
2592
  */
2325
2593
  render({ onRemove: e, onReset: t, onClearAll: i, onUpdateValue: r, onSelect: a }) {
2326
- this._onRemove = e, this._onReset = t, this._onClearAll = i, this._onUpdateValue = r, this._onSelect = a, this.element = u("div", {
2594
+ this._onRemove = e, this._onReset = t, this._onClearAll = i, this._onUpdateValue = r, this._onSelect = a, this.element = p("div", {
2327
2595
  className: "active-filters-panel",
2328
2596
  "data-testid": "active-filters-panel"
2329
2597
  });
2330
- const o = u("div", { className: "panel-header" });
2331
- o.appendChild(u("h3", { className: "panel-title" }, "Active Filters"));
2332
- const n = N({
2598
+ const n = p("div", { className: "panel-header" });
2599
+ n.appendChild(p("h3", { className: "panel-title" }, "Active Filters"));
2600
+ const o = O({
2333
2601
  label: "Clear All",
2334
2602
  className: "btn-text btn-danger",
2335
2603
  onClick: () => this._handleClearAll()
2336
2604
  });
2337
- return n.dataset.testid = "clear-all-filters", o.appendChild(n), this.element.appendChild(o), this._listContainer = u("div", { className: "active-filters-list" }), this.element.appendChild(this._listContainer), this._subscribeToState(), this._renderFilterList(), this.element;
2605
+ return o.dataset.testid = "clear-all-filters", n.appendChild(o), this.element.appendChild(n), this._listContainer = p("div", { className: "active-filters-list" }), this.element.appendChild(this._listContainer), this._subscribeToState(), this._renderFilterList(), this.element;
2338
2606
  }
2339
2607
  /**
2340
2608
  * Subscribe to state changes
@@ -2370,7 +2638,7 @@ class it {
2370
2638
  const e = this.state.get("activeFilters");
2371
2639
  if (e.size === 0) {
2372
2640
  this._listContainer.appendChild(
2373
- u("div", { className: "no-filters-message" }, "No filters active")
2641
+ p("div", { className: "no-filters-message" }, "No filters active")
2374
2642
  );
2375
2643
  return;
2376
2644
  }
@@ -2388,27 +2656,27 @@ class it {
2388
2656
  * @returns {HTMLElement}
2389
2657
  */
2390
2658
  _createFilterItem(e, t) {
2391
- const r = this.state.get("selectedFilter") === e, a = u("div", {
2659
+ const r = this.state.get("selectedFilter") === e, a = p("div", {
2392
2660
  className: `active-filter-item ${r ? "selected" : ""}`,
2393
2661
  "data-active-filter": e,
2394
2662
  "data-testid": `active-filter-${e}`,
2395
2663
  onClick: (f) => {
2396
2664
  f.target.closest(".filter-item-actions") || this._handleSelect(e);
2397
2665
  }
2398
- }), o = u("div", { className: "filter-item-header" }), n = u("span", { className: "filter-item-name" }, t.name), l = u("div", { className: "filter-item-actions" }), c = C({
2399
- icon: be,
2666
+ }), n = p("div", { className: "filter-item-header" }), o = p("span", { className: "filter-item-name" }, t.name), l = p("div", { className: "filter-item-actions" }), c = z({
2667
+ icon: Fe,
2400
2668
  title: "Reset filter",
2401
2669
  className: "btn-icon-sm",
2402
2670
  onClick: () => this._handleReset(e)
2403
- }), d = C({
2404
- icon: Le,
2671
+ }), d = z({
2672
+ icon: rt,
2405
2673
  title: "Remove filter",
2406
2674
  className: "btn-icon-sm btn-danger",
2407
2675
  onClick: () => this._handleRemove(e)
2408
2676
  });
2409
- l.appendChild(c), l.appendChild(d), o.appendChild(n), o.appendChild(l), a.appendChild(o);
2410
- const h = this.state.getFilterValues(e), p = u("div", { className: "filter-item-summary" });
2411
- return p.textContent = this._getValuesSummary(t, h), a.appendChild(p), a._summaryEl = p, a;
2677
+ l.appendChild(c), l.appendChild(d), n.appendChild(o), n.appendChild(l), a.appendChild(n);
2678
+ const h = this.state.getFilterValues(e), u = p("div", { className: "filter-item-summary" });
2679
+ return u.textContent = this._getValuesSummary(t, h), a.appendChild(u), a._summaryEl = u, a;
2412
2680
  }
2413
2681
  /**
2414
2682
  * Normalize control type (handle aliases)
@@ -2440,8 +2708,8 @@ class it {
2440
2708
  return e.controls.forEach((r) => {
2441
2709
  const a = this._normalizeControlType(r.type);
2442
2710
  if (a === "button") return;
2443
- const o = r.label || r.id, n = t[r.id] ?? r.default;
2444
- n !== r.default && (a === "slider" ? i.push(`${o}: ${this._formatValue(n)}`) : a === "toggle" ? n && i.push(o) : a === "color" ? i.push(`${o}: ${n}`) : a === "select" && i.push(`${o}: ${n}`));
2711
+ const n = r.label || r.id, o = t[r.id] ?? r.default;
2712
+ o !== r.default && (a === "slider" ? i.push(`${n}: ${this._formatValue(o)}`) : a === "toggle" ? o && i.push(n) : a === "color" ? i.push(`${n}: ${o}`) : a === "select" && i.push(`${n}: ${o}`));
2445
2713
  }), i.length > 0 ? i.join(", ") : "Default values";
2446
2714
  }
2447
2715
  /**
@@ -2514,7 +2782,7 @@ class it {
2514
2782
  this._unsubscribers.forEach((t) => t()), this._unsubscribers = [], this._filterItems.clear(), (e = this.element) == null || e.remove(), this.element = null;
2515
2783
  }
2516
2784
  }
2517
- const L = {
2785
+ const H = {
2518
2786
  name: "free",
2519
2787
  initialMode: "filters",
2520
2788
  cropShape: "free",
@@ -2526,12 +2794,12 @@ const L = {
2526
2794
  showCropControls: !0,
2527
2795
  maxExportWidth: void 0,
2528
2796
  maxExportHeight: void 0
2529
- }, G = {
2797
+ }, te = {
2530
2798
  free: {
2531
- ...L
2799
+ ...H
2532
2800
  },
2533
2801
  avatar: {
2534
- ...L,
2802
+ ...H,
2535
2803
  name: "avatar",
2536
2804
  initialMode: "crop",
2537
2805
  cropShape: "circle",
@@ -2541,7 +2809,7 @@ const L = {
2541
2809
  lockAspectRatio: !0
2542
2810
  },
2543
2811
  banner: {
2544
- ...L,
2812
+ ...H,
2545
2813
  name: "banner",
2546
2814
  initialMode: "crop",
2547
2815
  cropShape: "square",
@@ -2551,7 +2819,7 @@ const L = {
2551
2819
  lockAspectRatio: !0
2552
2820
  },
2553
2821
  cover: {
2554
- ...L,
2822
+ ...H,
2555
2823
  name: "cover",
2556
2824
  initialMode: "crop",
2557
2825
  cropShape: "free",
@@ -2561,7 +2829,7 @@ const L = {
2561
2829
  lockAspectRatio: !0
2562
2830
  },
2563
2831
  product: {
2564
- ...L,
2832
+ ...H,
2565
2833
  name: "product",
2566
2834
  initialMode: "filters",
2567
2835
  cropShape: "square",
@@ -2571,26 +2839,26 @@ const L = {
2571
2839
  lockAspectRatio: !1
2572
2840
  }
2573
2841
  };
2574
- function rt(s) {
2842
+ function vt(s) {
2575
2843
  if (!s)
2576
- return { ...G.free };
2844
+ return { ...te.free };
2577
2845
  if (typeof s == "object" && s !== null)
2578
- return { ...L, ...s };
2579
- const e = G[s];
2580
- return e ? { ...e } : { ...G.free };
2846
+ return { ...H, ...s };
2847
+ const e = te[s];
2848
+ return e ? { ...e } : { ...te.free };
2581
2849
  }
2582
- class ri extends V {
2850
+ class Si extends W {
2583
2851
  /**
2584
2852
  * Create a new VanillaImageEditor
2585
2853
  * @param {HTMLElement} container - Container element to mount the editor
2586
2854
  * @param {Object} options - Configuration options
2587
2855
  */
2588
2856
  constructor(e, t = {}) {
2589
- var a, o, n;
2857
+ var a, n, o;
2590
2858
  if (super(), !e)
2591
2859
  throw new Error("VanillaImageEditor: container element is required");
2592
2860
  this._container = e, this._destroyed = !1, this._loadVersion = 0, this._objectUrls = /* @__PURE__ */ new Set();
2593
- const i = t.preset ? rt(t.preset) : null, r = i ? {
2861
+ const i = t.preset ? vt(t.preset) : null, r = i ? {
2594
2862
  initialMode: i.initialMode === "crop" ? "crop" : "adjust",
2595
2863
  cropShape: i.cropShape,
2596
2864
  initialAspectRatio: i.aspectRatio
@@ -2608,9 +2876,9 @@ class ri extends V {
2608
2876
  },
2609
2877
  ...r,
2610
2878
  ...t
2611
- }, this._preset = i, this._state = ke(), this._state.set("theme", this._options.theme), this._state.set("crop.shape", this._options.cropShape), this._state.set("crop.aspect", this._options.initialAspectRatio), this._preset && (this._state.set("lockCropShape", !!this._preset.lockCropShape), this._state.set("lockAspectRatio", !!this._preset.lockAspectRatio), this._state.set("showFilters", this._preset.showFilters !== !1), this._state.set("showCropControls", this._preset.showCropControls !== !1), this._state.set("autoZoomOnCropOverflow", !!this._preset.autoZoomOnCropOverflow)), this._renderer = new Pe(), this._filterManager = new Fe(this._state, this._renderer), this._cropManager = new Q(this._state, this._renderer), this._removeBgManager = null, ((a = this._options.backgroundRemoval) == null ? void 0 : a.enabled) !== !1 && (this._removeBgManager = new Ae({
2612
- endpoint: (o = this._options.backgroundRemoval) == null ? void 0 : o.endpoint,
2613
- fallbackEndpoint: (n = this._options.backgroundRemoval) == null ? void 0 : n.fallbackEndpoint
2879
+ }, this._preset = i, this._state = qe(), this._state.set("theme", this._options.theme), this._state.set("crop.shape", this._options.cropShape), this._state.set("crop.aspect", this._options.initialAspectRatio), this._preset && (this._state.set("lockCropShape", !!this._preset.lockCropShape), this._state.set("lockAspectRatio", !!this._preset.lockAspectRatio), this._state.set("showFilters", this._preset.showFilters !== !1), this._state.set("showCropControls", this._preset.showCropControls !== !1), this._state.set("autoZoomOnCropOverflow", !!this._preset.autoZoomOnCropOverflow)), this._renderer = new He(), this._filterManager = new ut(this._state, this._renderer), this._cropManager = new ae(this._state, this._renderer), this._removeBgManager = null, ((a = this._options.backgroundRemoval) == null ? void 0 : a.enabled) !== !1 && (this._removeBgManager = new pt({
2880
+ endpoint: (n = this._options.backgroundRemoval) == null ? void 0 : n.endpoint,
2881
+ fallbackEndpoint: (o = this._options.backgroundRemoval) == null ? void 0 : o.fallbackEndpoint
2614
2882
  })), this._loadingOverlay = null, this._isMobile = typeof window < "u" ? window.innerWidth <= 768 : !1, this._toolbar = null, this._categoryCarousel = null, this._filterCarousel = null, this._filterAdjustments = null, this._mobileFilterDrawer = null, this._mobileActiveFilters = null, this._cropControls = null, this._activeFiltersPanel = null, this._editorEl = null, this._canvasContainer = null, this._cropOverlay = null, this._controlsSection = null, this._filterControlsEl = null, this._fileInput = null, this._resizeObserver = null, this._init();
2615
2883
  }
2616
2884
  /**
@@ -2626,13 +2894,13 @@ class ri extends V {
2626
2894
  * Build DOM structure
2627
2895
  */
2628
2896
  _buildDOM() {
2629
- this._container.innerHTML = "", this._editorEl = u("div", {
2897
+ this._container.innerHTML = "", this._editorEl = p("div", {
2630
2898
  className: `vanilla-image-editor ${this._state.get("isDarkMode") ? "dark" : "light"}`
2631
2899
  });
2632
- const e = u("div", { className: "editor-toolbar-container" });
2900
+ const e = p("div", { className: "editor-toolbar-container" });
2633
2901
  this._editorEl.appendChild(e), this._toolbarContainer = e;
2634
- const t = u("div", { className: "editor-content" }), i = u("div", { className: "canvas-section" });
2635
- this._canvasContainer = u("div", { className: "canvas-container" }), this._cropOverlay = u("canvas", { className: "crop-overlay", "aria-hidden": "true" }), i.appendChild(this._canvasContainer), i.appendChild(this._cropOverlay), t.appendChild(i), this._controlsSection = u("div", { className: "controls-section" }), t.appendChild(this._controlsSection), this._editorEl.appendChild(t), this._fileInput = u("input", {
2902
+ const t = p("div", { className: "editor-content" }), i = p("div", { className: "canvas-section" });
2903
+ this._canvasContainer = p("div", { className: "canvas-container" }), this._cropOverlay = p("canvas", { className: "crop-overlay", "aria-hidden": "true" }), i.appendChild(this._canvasContainer), i.appendChild(this._cropOverlay), t.appendChild(i), this._controlsSection = p("div", { className: "controls-section" }), t.appendChild(this._controlsSection), this._editorEl.appendChild(t), this._fileInput = p("input", {
2636
2904
  type: "file",
2637
2905
  accept: "image/*",
2638
2906
  className: "hidden-file-input",
@@ -2644,32 +2912,32 @@ class ri extends V {
2644
2912
  * Initialize UI components
2645
2913
  */
2646
2914
  _initUI() {
2647
- this._toolbar = new He(this._state, this), this._toolbarContainer.appendChild(this._toolbar.render()), this._filterControlsEl = u("div", { className: "filter-controls-container" }), this._categoryCarousel = new We(this._state, this), this._filterControlsEl.appendChild(this._categoryCarousel.render((r) => {
2915
+ this._toolbar = new ft(this._state, this), this._toolbarContainer.appendChild(this._toolbar.render()), this._filterControlsEl = p("div", { className: "filter-controls-container" }), this._categoryCarousel = new mt(this._state, this), this._filterControlsEl.appendChild(this._categoryCarousel.render((r) => {
2648
2916
  }));
2649
- const e = u("div", { className: "filter-layout" }), t = u("div", { className: "filter-left-column" });
2650
- this._filterCarousel = new Ze(this._state, this._filterManager), t.appendChild(this._filterCarousel.render({
2917
+ const e = p("div", { className: "filter-layout" }), t = p("div", { className: "filter-left-column" });
2918
+ this._filterCarousel = new gt(this._state, this._filterManager), t.appendChild(this._filterCarousel.render({
2651
2919
  onToggle: (r, a) => this._handleFilterToggle(r, a),
2652
2920
  onSelect: (r) => {
2653
2921
  this._handleFilterSelect(r), this._isMobile && this._mobileFilterDrawer && this._mobileFilterDrawer.open(r);
2654
2922
  }
2655
- })), this._filterAdjustments = new Ge(this._state, this._filterManager), t.appendChild(this._filterAdjustments.render({
2656
- onChange: (r, a, o) => this._handleFilterChange(r, a, o),
2923
+ })), this._filterAdjustments = new bt(this._state, this._filterManager), t.appendChild(this._filterAdjustments.render({
2924
+ onChange: (r, a, n) => this._handleFilterChange(r, a, n),
2657
2925
  onReset: (r) => this._handleFilterReset(r),
2658
2926
  onAction: (r, a) => this._handleFilterAction(r, a)
2659
2927
  })), e.appendChild(t);
2660
- const i = u("div", { className: "filter-right-column" });
2661
- this._activeFiltersPanel = new it(this._state, this._filterManager), i.appendChild(this._activeFiltersPanel.render({
2928
+ const i = p("div", { className: "filter-right-column" });
2929
+ this._activeFiltersPanel = new St(this._state, this._filterManager), i.appendChild(this._activeFiltersPanel.render({
2662
2930
  onRemove: (r) => this._handleFilterToggle(r, !1),
2663
2931
  onReset: (r) => this._handleFilterReset(r),
2664
2932
  onClearAll: () => this.resetAll(),
2665
2933
  onSelect: (r) => this._handleFilterSelect(r)
2666
- })), e.appendChild(i), this._filterControlsEl.appendChild(e), this._mobileActiveFilters = new Qe(this._state, this._filterManager), this._filterControlsEl.appendChild(this._mobileActiveFilters.render({
2934
+ })), e.appendChild(i), this._filterControlsEl.appendChild(e), this._mobileActiveFilters = new _t(this._state, this._filterManager), this._filterControlsEl.appendChild(this._mobileActiveFilters.render({
2667
2935
  onToggle: (r, a) => this._handleFilterToggle(r, a),
2668
2936
  onSelect: (r) => {
2669
2937
  this._handleFilterSelect(r), this._isMobile && this._mobileFilterDrawer && this._mobileFilterDrawer.open(r);
2670
2938
  }
2671
- })), this._cropControls = new tt(this._state, this._cropManager), this._cropControlsEl = this._cropControls.render(), this._cropControlsEl.style.display = "none", this._controlsSection.appendChild(this._filterControlsEl), this._controlsSection.appendChild(this._cropControlsEl), this._mobileFilterDrawer = new Ke(this._state, this._filterManager), this._mobileFilterDrawer.build(this._controlsSection, {
2672
- onChange: (r, a, o) => this._handleFilterChange(r, a, o),
2939
+ })), this._cropControls = new wt(this._state, this._cropManager), this._cropControlsEl = this._cropControls.render(), this._cropControlsEl.style.display = "none", this._controlsSection.appendChild(this._filterControlsEl), this._controlsSection.appendChild(this._cropControlsEl), this._mobileFilterDrawer = new yt(this._state, this._filterManager), this._mobileFilterDrawer.build(this._controlsSection, {
2940
+ onChange: (r, a, n) => this._handleFilterChange(r, a, n),
2673
2941
  onReset: (r) => this._handleFilterReset(r),
2674
2942
  onRemove: (r) => {
2675
2943
  this._handleFilterToggle(r, !1), this._state.set("selectedFilter", null);
@@ -2764,13 +3032,14 @@ class ri extends V {
2764
3032
  this._filterManager.resetValues(e), this._filterManager.applyFilters();
2765
3033
  }
2766
3034
  /**
2767
- * Handle filter action (button click)
3035
+ * Handle filter action (button click).
3036
+ * Delegates to FilterManager.performFilterAction which syncs state after
3037
+ * the action so the result survives filter recreation.
2768
3038
  * @param {string} filterId
2769
3039
  * @param {string} action
2770
3040
  */
2771
3041
  _handleFilterAction(e, t) {
2772
- const i = this._filterManager.getInstance(e);
2773
- i && typeof i.updateUIParam == "function" && (i.updateUIParam(t, !0), this._filterManager.applyFilters());
3042
+ this._filterManager.performFilterAction(e, t);
2774
3043
  }
2775
3044
  // ==================== Public API ====================
2776
3045
  /**
@@ -2829,7 +3098,7 @@ class ri extends V {
2829
3098
  this._state.set("selectedFilter", t);
2830
3099
  const i = this._filterManager.getFilterDef(t);
2831
3100
  if (typeof (i == null ? void 0 : i.category) == "string") {
2832
- const r = $e[i.category] ?? i.category;
3101
+ const r = ht[i.category] ?? i.category;
2833
3102
  this._state.set("selectedCategory", r);
2834
3103
  }
2835
3104
  }
@@ -2845,13 +3114,23 @@ class ri extends V {
2845
3114
  (e = this._fileInput) == null || e.click();
2846
3115
  }
2847
3116
  /**
2848
- * Export the current image
3117
+ * Export the current image.
3118
+ *
2849
3119
  * @param {string} format - 'png' or 'jpeg'
2850
3120
  * @param {number} quality - Quality for jpeg (0-1)
3121
+ * @param {Object} [options]
3122
+ * @param {number} [options.maxEdge] - Cap the longest edge to this pixel count
3123
+ * @param {number} [options.maxPixels] - Cap total pixel count (width*height)
2851
3124
  * @returns {string|null} Data URL
2852
3125
  */
2853
- exportImage(e = "png", t = 0.92) {
2854
- return this._state.get("crop.rect") && !this._cropManager.apply() ? null : this._renderer.exportImage(e, t);
3126
+ exportImage(e = "png", t = 0.92, i = {}) {
3127
+ return this._state.get("crop.rect") && !this._cropManager.apply() ? null : this._renderer.exportImage(
3128
+ e,
3129
+ t,
3130
+ i.maxEdge ?? 0,
3131
+ i.dontUpscale !== !1,
3132
+ i.maxPixels ?? 0
3133
+ );
2855
3134
  }
2856
3135
  /**
2857
3136
  * Save the image (triggers download and emits 'save' event)
@@ -2882,12 +3161,12 @@ class ri extends V {
2882
3161
  getSerializableState() {
2883
3162
  const e = this._state.get("activeFilters"), t = [];
2884
3163
  if (e)
2885
- for (const o of e) {
2886
- const n = this._state.getFilterValues(o);
3164
+ for (const n of e) {
3165
+ const o = this._state.getFilterValues(n);
2887
3166
  t.push({
2888
- id: o,
3167
+ id: n,
2889
3168
  enabled: !0,
2890
- values: { ...n }
3169
+ values: { ...o }
2891
3170
  });
2892
3171
  }
2893
3172
  const i = this._state.get("crop.appliedRect"), r = this._state.get("crop.rect"), a = i || r;
@@ -3002,9 +3281,9 @@ class ri extends V {
3002
3281
  _showLoadingOverlay(e) {
3003
3282
  var i;
3004
3283
  if (!this._loadingOverlay)
3005
- this._loadingOverlay = u("div", { className: "editor-loading-overlay" }, [
3006
- u("div", { className: "editor-loading-spinner" }),
3007
- u("div", { className: "editor-loading-text" }, e)
3284
+ this._loadingOverlay = p("div", { className: "editor-loading-overlay" }, [
3285
+ p("div", { className: "editor-loading-spinner" }),
3286
+ p("div", { className: "editor-loading-text" }, e)
3008
3287
  ]);
3009
3288
  else {
3010
3289
  const r = this._loadingOverlay.querySelector(".editor-loading-text");
@@ -3024,36 +3303,36 @@ class ri extends V {
3024
3303
  * Destroy the editor and clean up
3025
3304
  */
3026
3305
  destroy() {
3027
- var e, t, i, r, a, o, n, l, c, d;
3306
+ var e, t, i, r, a, n, o, l, c, d;
3028
3307
  this._destroyed = !0;
3029
3308
  for (const h of this._objectUrls)
3030
3309
  try {
3031
3310
  URL.revokeObjectURL(h);
3032
3311
  } catch {
3033
3312
  }
3034
- this._objectUrls.clear(), (e = this._resizeObserver) == null || e.disconnect(), this._renderer.destroy(), this._cropManager.disable(), this._handleWindowResize && window.removeEventListener("resize", this._handleWindowResize), (t = this._toolbar) == null || t.destroy(), (i = this._categoryCarousel) == null || i.destroy(), (r = this._filterCarousel) == null || r.destroy(), (a = this._filterAdjustments) == null || a.destroy(), (o = this._mobileFilterDrawer) == null || o.destroy(), (n = this._mobileActiveFilters) == null || n.destroy(), (l = this._cropControls) == null || l.destroy(), (c = this._activeFiltersPanel) == null || c.destroy(), (d = this._editorEl) == null || d.remove(), this._container = null, this._state = null, this.emit("destroyed"), this.removeAllListeners();
3313
+ this._objectUrls.clear(), (e = this._resizeObserver) == null || e.disconnect(), this._renderer.destroy(), this._cropManager.disable(), this._handleWindowResize && window.removeEventListener("resize", this._handleWindowResize), (t = this._toolbar) == null || t.destroy(), (i = this._categoryCarousel) == null || i.destroy(), (r = this._filterCarousel) == null || r.destroy(), (a = this._filterAdjustments) == null || a.destroy(), (n = this._mobileFilterDrawer) == null || n.destroy(), (o = this._mobileActiveFilters) == null || o.destroy(), (l = this._cropControls) == null || l.destroy(), (c = this._activeFiltersPanel) == null || c.destroy(), (d = this._editorEl) == null || d.remove(), this._container = null, this._state = null, this.emit("destroyed"), this.removeAllListeners();
3035
3314
  }
3036
3315
  }
3037
- const k = /* @__PURE__ */ new Map(), Y = /* @__PURE__ */ new Map();
3038
- function st(s, e) {
3316
+ const E = /* @__PURE__ */ new Map(), j = /* @__PURE__ */ new Map();
3317
+ function Mt(s, e) {
3039
3318
  return !Array.isArray(s.mediaTargets) || s.mediaTargets.length === 0 ? !0 : s.mediaTargets.includes(e);
3040
3319
  }
3041
3320
  function m(s) {
3042
3321
  var e;
3043
- return k.has(s.id), k.set(s.id, s), Y.has(s.category) || Y.set(s.category, []), (e = Y.get(s.category)) == null || e.push(s.id), s;
3322
+ return E.has(s.id), E.set(s.id, s), j.has(s.category) || j.set(s.category, []), (e = j.get(s.category)) == null || e.push(s.id), s;
3044
3323
  }
3045
- function at(s) {
3046
- return k.get(s);
3324
+ function Pt(s) {
3325
+ return E.get(s);
3047
3326
  }
3048
- function H() {
3049
- return Array.from(k.values());
3327
+ function Q() {
3328
+ return Array.from(E.values());
3050
3329
  }
3051
- function ot() {
3052
- H().map((t) => t.id), Object.entries(b).filter(
3330
+ function kt() {
3331
+ Q().map((t) => t.id), Object.entries(b).filter(
3053
3332
  (t) => /Filter$/.test(t[0]) && typeof t[1] == "function"
3054
3333
  ).forEach(([t, i]) => {
3055
3334
  const r = t.replace(/Filter$/, "").replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase();
3056
- k.has(r) || m({
3335
+ E.has(r) || m({
3057
3336
  id: r,
3058
3337
  name: t.replace(/Filter$/, ""),
3059
3338
  category: "unlisted",
@@ -3072,33 +3351,33 @@ function ot() {
3072
3351
  });
3073
3352
  });
3074
3353
  }
3075
- function nt(s) {
3076
- return (Y.get(s) || []).map((t) => k.get(t)).filter(Boolean);
3354
+ function Ft(s) {
3355
+ return (j.get(s) || []).map((t) => E.get(t)).filter(Boolean);
3077
3356
  }
3078
- function lt() {
3079
- return Array.from(Y.keys());
3357
+ function At() {
3358
+ return Array.from(j.keys());
3080
3359
  }
3081
- function si(s) {
3082
- return k.has(s);
3360
+ function vi(s) {
3361
+ return E.has(s);
3083
3362
  }
3084
- function ct(s) {
3085
- const e = k.get(s);
3363
+ function zt(s) {
3364
+ const e = E.get(s);
3086
3365
  if (!e)
3087
3366
  return !1;
3088
- k.delete(s);
3089
- const t = Y.get(e.category);
3367
+ E.delete(s);
3368
+ const t = j.get(e.category);
3090
3369
  if (t) {
3091
3370
  const i = t.indexOf(s);
3092
- i !== -1 && t.splice(i, 1), t.length === 0 && Y.delete(e.category);
3371
+ i !== -1 && t.splice(i, 1), t.length === 0 && j.delete(e.category);
3093
3372
  }
3094
3373
  return !0;
3095
3374
  }
3096
- function ai(s, e) {
3097
- const t = k.get(s);
3098
- return t ? st(t, e) : !1;
3375
+ function Mi(s, e) {
3376
+ const t = E.get(s);
3377
+ return t ? Mt(t, e) : !1;
3099
3378
  }
3100
- function ht() {
3101
- return Array.from(k.values()).map((s) => ({
3379
+ function Nt() {
3380
+ return Array.from(E.values()).map((s) => ({
3102
3381
  id: s.id,
3103
3382
  name: s.name,
3104
3383
  category: s.category,
@@ -3106,17 +3385,17 @@ function ht() {
3106
3385
  }));
3107
3386
  }
3108
3387
  if (typeof window < "u") {
3109
- window.__DEBUG_FILTERS_LIST = Array.from(k.keys()), window.getAllFilters = H, window.getFilter = at, window.getFiltersByCategory = nt, window.getRegisteredFilters = ht;
3388
+ window.__DEBUG_FILTERS_LIST = Array.from(E.keys()), window.getAllFilters = Q, window.getFilter = Pt, window.getFiltersByCategory = Ft, window.getRegisteredFilters = Nt;
3110
3389
  const s = m;
3111
3390
  window.registerFilter = (e) => {
3112
3391
  const t = s(e);
3113
- return window.__DEBUG_FILTERS_LIST = Array.from(k.keys()), t;
3392
+ return window.__DEBUG_FILTERS_LIST = Array.from(E.keys()), t;
3114
3393
  };
3115
3394
  }
3116
3395
  typeof window < "u" && (window.initializeFilterRegistry = window.initializeFilterRegistry || function() {
3117
3396
  return [];
3118
3397
  });
3119
- const { AdjustmentFilter: dt } = b, { ColorMatrixFilter: ut } = w, A = {
3398
+ const { AdjustmentFilter: Rt } = b, { ColorMatrixFilter: Tt } = R, X = {
3120
3399
  gamma: 1,
3121
3400
  saturation: 1,
3122
3401
  contrast: 1,
@@ -3125,7 +3404,7 @@ const { AdjustmentFilter: dt } = b, { ColorMatrixFilter: ut } = w, A = {
3125
3404
  green: 1,
3126
3405
  blue: 1,
3127
3406
  alpha: 1
3128
- }, pt = /* @__PURE__ */ new Set([
3407
+ }, Et = /* @__PURE__ */ new Set([
3129
3408
  "gamma",
3130
3409
  "saturation",
3131
3410
  "contrast",
@@ -3135,7 +3414,7 @@ const { AdjustmentFilter: dt } = b, { ColorMatrixFilter: ut } = w, A = {
3135
3414
  "blue",
3136
3415
  "alpha"
3137
3416
  ]);
3138
- function z(s, e) {
3417
+ function B(s, e) {
3139
3418
  if (typeof s == "number" && Number.isFinite(s))
3140
3419
  return s;
3141
3420
  if (typeof s == "string") {
@@ -3145,22 +3424,22 @@ function z(s, e) {
3145
3424
  }
3146
3425
  return e;
3147
3426
  }
3148
- function se(s) {
3149
- return pt.has(s);
3427
+ function ue(s) {
3428
+ return Et.has(s);
3150
3429
  }
3151
- function ft(s) {
3430
+ function It(s) {
3152
3431
  return {
3153
- gamma: z(s.gamma, A.gamma),
3154
- saturation: z(s.saturation, A.saturation),
3155
- contrast: z(s.contrast, A.contrast),
3156
- brightness: z(s.brightness, A.brightness),
3157
- red: z(s.red, A.red),
3158
- green: z(s.green, A.green),
3159
- blue: z(s.blue, A.blue),
3160
- alpha: z(s.alpha, A.alpha)
3432
+ gamma: B(s.gamma, X.gamma),
3433
+ saturation: B(s.saturation, X.saturation),
3434
+ contrast: B(s.contrast, X.contrast),
3435
+ brightness: B(s.brightness, X.brightness),
3436
+ red: B(s.red, X.red),
3437
+ green: B(s.green, X.green),
3438
+ blue: B(s.blue, X.blue),
3439
+ alpha: B(s.alpha, X.alpha)
3161
3440
  };
3162
3441
  }
3163
- function ae(s, e) {
3442
+ function pe(s, e) {
3164
3443
  s.reset(), s.brightness(e.brightness, !0), s.contrast(e.contrast, !0), s.saturate(e.saturation, !0);
3165
3444
  }
3166
3445
  m({
@@ -3171,28 +3450,28 @@ m({
3171
3450
  // Create an instance of the AdjustmentFilter with the provided parameters
3172
3451
  createFilter: (s) => {
3173
3452
  try {
3174
- const e = ft(s ?? {}), t = { ...e };
3453
+ const e = It(s ?? {}), t = { ...e };
3175
3454
  try {
3176
- const i = new dt(t), r = i;
3177
- return r._customParams = { ...e }, r.updateUIParam = function(o, n) {
3455
+ const i = new Rt(t), r = i;
3456
+ return r._customParams = { ...e }, r.updateUIParam = function(n, o) {
3178
3457
  try {
3179
- if (!se(o))
3458
+ if (!ue(n))
3180
3459
  return;
3181
- const l = this._customParams ?? { ...A }, c = z(n, l[o]);
3182
- l[o] = c, this._customParams = l;
3460
+ const l = this._customParams ?? { ...X }, c = B(o, l[n]);
3461
+ l[n] = c, this._customParams = l;
3183
3462
  const d = this;
3184
- o in d && (d[o] = c);
3463
+ n in d && (d[n] = c);
3185
3464
  } catch {
3186
3465
  }
3187
3466
  }, i;
3188
3467
  } catch {
3189
- const r = new ut(), a = r;
3190
- return a._customParams = { ...e }, ae(r, e), a.updateUIParam = function(n, l) {
3468
+ const r = new Tt(), a = r;
3469
+ return a._customParams = { ...e }, pe(r, e), a.updateUIParam = function(o, l) {
3191
3470
  try {
3192
- if (!se(n))
3471
+ if (!ue(o))
3193
3472
  return;
3194
- const c = this._customParams ?? { ...A }, d = z(l, c[n]);
3195
- c[n] = d, this._customParams = c, ae(this, c);
3473
+ const c = this._customParams ?? { ...X }, d = B(l, c[o]);
3474
+ c[o] = d, this._customParams = c, pe(this, c);
3196
3475
  } catch {
3197
3476
  }
3198
3477
  }, r;
@@ -3296,14 +3575,14 @@ m({
3296
3575
  }
3297
3576
  ]
3298
3577
  });
3299
- const { ColorMatrixFilter: mt } = w, E = {
3578
+ const { ColorMatrixFilter: Xt } = R, V = {
3300
3579
  brightness: 1,
3301
3580
  contrast: 1,
3302
3581
  saturation: 1,
3303
3582
  hue: 0,
3304
3583
  sepia: 0,
3305
3584
  negative: !1
3306
- }, gt = /* @__PURE__ */ new Set([
3585
+ }, Bt = /* @__PURE__ */ new Set([
3307
3586
  "brightness",
3308
3587
  "contrast",
3309
3588
  "saturation",
@@ -3311,10 +3590,10 @@ const { ColorMatrixFilter: mt } = w, E = {
3311
3590
  "sepia",
3312
3591
  "negative"
3313
3592
  ]);
3314
- function bt(s) {
3315
- return gt.has(s);
3593
+ function Yt(s) {
3594
+ return Bt.has(s);
3316
3595
  }
3317
- function D(s, e) {
3596
+ function $(s, e) {
3318
3597
  if (typeof s == "number" && Number.isFinite(s))
3319
3598
  return s;
3320
3599
  if (typeof s == "string") {
@@ -3324,7 +3603,7 @@ function D(s, e) {
3324
3603
  }
3325
3604
  return e;
3326
3605
  }
3327
- function ye(s, e) {
3606
+ function Ee(s, e) {
3328
3607
  if (typeof s == "boolean")
3329
3608
  return s;
3330
3609
  if (typeof s == "string") {
@@ -3335,17 +3614,17 @@ function ye(s, e) {
3335
3614
  }
3336
3615
  return e;
3337
3616
  }
3338
- function yt(s) {
3617
+ function Ot(s) {
3339
3618
  return {
3340
- brightness: D(s.brightness, E.brightness),
3341
- contrast: D(s.contrast, E.contrast),
3342
- saturation: D(s.saturation, E.saturation),
3343
- hue: D(s.hue, E.hue),
3344
- sepia: D(s.sepia, E.sepia),
3345
- negative: ye(s.negative, E.negative)
3619
+ brightness: $(s.brightness, V.brightness),
3620
+ contrast: $(s.contrast, V.contrast),
3621
+ saturation: $(s.saturation, V.saturation),
3622
+ hue: $(s.hue, V.hue),
3623
+ sepia: $(s.sepia, V.sepia),
3624
+ negative: Ee(s.negative, V.negative)
3346
3625
  };
3347
3626
  }
3348
- function oe(s, e) {
3627
+ function fe(s, e) {
3349
3628
  s.reset(), e.brightness !== 1 && s.brightness(e.brightness, !0), e.contrast !== 1 && s.contrast(e.contrast, !0), e.saturation !== 1 && s.saturate(e.saturation, !0), e.hue !== 0 && s.hue(e.hue, !0), e.sepia > 0 && s.sepia(!0), e.negative && s.negative(!0);
3350
3629
  }
3351
3630
  m({
@@ -3356,19 +3635,19 @@ m({
3356
3635
  // Create an instance of the ColorMatrixFilter with the provided parameters
3357
3636
  createFilter: (s) => {
3358
3637
  try {
3359
- const e = yt(s ?? {}), t = new mt(), i = t;
3360
- return i._customParams = { ...e }, oe(t, e), i.updateUIParam = function(a, o) {
3638
+ const e = Ot(s ?? {}), t = new Xt(), i = t;
3639
+ return i._customParams = { ...e }, fe(t, e), i.updateUIParam = function(a, n) {
3361
3640
  try {
3362
- if (!bt(a))
3641
+ if (!Yt(a))
3363
3642
  return;
3364
- const n = this._customParams ?? { ...E };
3643
+ const o = this._customParams ?? { ...V };
3365
3644
  if (a === "negative")
3366
- n.negative = ye(o, n.negative);
3645
+ o.negative = Ee(n, o.negative);
3367
3646
  else {
3368
3647
  const l = a;
3369
- n[l] = D(o, n[l]);
3648
+ o[l] = $(n, o[l]);
3370
3649
  }
3371
- this._customParams = n, oe(this, n);
3650
+ this._customParams = o, fe(this, o);
3372
3651
  } catch {
3373
3652
  }
3374
3653
  }, t;
@@ -3446,42 +3725,26 @@ m({
3446
3725
  }
3447
3726
  ]
3448
3727
  });
3728
+ const me = (s) => Math.max(0, Math.min(1, s));
3449
3729
  m({
3450
3730
  id: "alpha",
3451
3731
  name: "Alpha",
3452
3732
  category: "adjust",
3453
- description: "Adjust the transparency of the image",
3454
- // Create an instance of the ColorMatrixFilter with alpha adjustment
3733
+ description: "Adjust the opacity of the image",
3455
3734
  createFilter: (s) => {
3456
- try {
3457
- const e = s.alpha !== void 0 ? s.alpha : 1, t = new w.ColorMatrixFilter();
3458
- return t.alpha = e, t._customParams = {
3459
- alpha: e
3460
- }, t.updateUIParam = function(i, r) {
3461
- try {
3462
- const a = this._customParams || {};
3463
- if (this._customParams = a, i === "alpha") {
3464
- const o = Number(r);
3465
- this.alpha = o, a.alpha = o;
3466
- } else
3467
- i in this && (this[i] = r);
3468
- } catch {
3469
- }
3470
- }, t;
3471
- } catch {
3472
- return null;
3473
- }
3735
+ const e = me(s.alpha !== void 0 ? Number(s.alpha) : 1), t = new R.AlphaFilter(e);
3736
+ return t.updateUIParam = function(i, r) {
3737
+ i === "alpha" && (this.alpha = me(Number(r)));
3738
+ }, t;
3474
3739
  },
3475
- // Default parameter values
3476
3740
  defaultParams: {
3477
3741
  alpha: 1
3478
3742
  },
3479
- // UI controls for the filter
3480
3743
  controls: [
3481
3744
  {
3482
3745
  id: "alpha",
3483
3746
  type: "slider",
3484
- label: "Transparency",
3747
+ label: "Opacity",
3485
3748
  property: "alpha",
3486
3749
  min: 0,
3487
3750
  max: 1,
@@ -3501,7 +3764,7 @@ m({
3501
3764
  */
3502
3765
  createFilter: (s) => {
3503
3766
  try {
3504
- const e = new w.BlurFilter({
3767
+ const e = new R.BlurFilter({
3505
3768
  strength: s.blur || 8,
3506
3769
  quality: s.quality || 4
3507
3770
  });
@@ -3553,33 +3816,55 @@ m({
3553
3816
  }
3554
3817
  ]
3555
3818
  });
3819
+ function ge(s, e) {
3820
+ typeof s.reset == "function" && s.reset(), e.brightness !== 1 && s.brightness(e.brightness, !1), e.contrast !== 1 && s.contrast(e.contrast, !1), e.saturation !== 1 && s.saturate(e.saturation, !1), e.hue !== 0 && s.hue(e.hue, !1), e.sepia && s.sepia(!1), e.negative && s.negative(!1);
3821
+ }
3822
+ function be(s) {
3823
+ return {
3824
+ brightness: Number(s.brightness ?? 1),
3825
+ contrast: Number(s.contrast ?? 1),
3826
+ saturation: Number(s.saturation ?? 1),
3827
+ hue: Number(s.hue ?? 0),
3828
+ sepia: !!s.sepia,
3829
+ negative: !!s.negative
3830
+ };
3831
+ }
3556
3832
  m({
3557
3833
  id: "color-matrix",
3558
3834
  name: "Color Matrix",
3559
3835
  category: "advanced",
3560
- description: "Advanced color adjustments including sepia, hue rotation, and more",
3561
- // Create an instance of the ColorMatrixFilter with the provided parameters
3836
+ description: "Advanced color adjustments including sepia, hue rotation, and negative",
3562
3837
  createFilter: (s) => {
3563
- const e = w.ColorMatrixFilter;
3564
- if (!e)
3565
- return null;
3566
- const t = new e();
3567
- try {
3568
- return typeof t.reset == "function" && t.reset(), s.brightness !== 1 && typeof t.brightness == "function" && t.brightness(s.brightness, !1), s.contrast !== 1 && typeof t.contrast == "function" && t.contrast(s.contrast, !1), s.saturation !== 1 && typeof t.saturate == "function" && t.saturate(s.saturation, !1), s.hue !== 0 && typeof t.hue == "function" && t.hue(s.hue, !1), s.sepia > 0 && typeof t.sepia == "function" && t.sepia(s.sepia), s.negative && typeof t.negative == "function" && t.negative(!1), t;
3569
- } catch {
3570
- return t;
3571
- }
3838
+ const e = R.ColorMatrixFilter;
3839
+ if (!e) return null;
3840
+ const t = new e(), i = be(s);
3841
+ return t._customParams = { ...i }, ge(t, i), t.updateUIParam = function(r, a) {
3842
+ const n = this._customParams ?? be({});
3843
+ switch (r) {
3844
+ case "brightness":
3845
+ case "contrast":
3846
+ case "saturation":
3847
+ case "hue":
3848
+ n[r] = Number(a);
3849
+ break;
3850
+ case "sepia":
3851
+ case "negative":
3852
+ n[r] = !!a;
3853
+ break;
3854
+ default:
3855
+ return;
3856
+ }
3857
+ this._customParams = n, ge(this, n);
3858
+ }, t;
3572
3859
  },
3573
- // Default parameter values
3574
3860
  defaultParams: {
3575
3861
  brightness: 1,
3576
3862
  contrast: 1,
3577
3863
  saturation: 1,
3578
3864
  hue: 0,
3579
- sepia: 0,
3865
+ sepia: !1,
3580
3866
  negative: !1
3581
3867
  },
3582
- // UI controls for the filter
3583
3868
  controls: [
3584
3869
  {
3585
3870
  id: "brightness",
@@ -3621,15 +3906,14 @@ m({
3621
3906
  step: 1,
3622
3907
  default: 0
3623
3908
  },
3909
+ // Sepia is a toggle in phase 1 — PIXI v8's ColorMatrixFilter.sepia()
3910
+ // doesn't accept a smooth intensity, so a slider here would be misleading.
3624
3911
  {
3625
3912
  id: "sepia",
3626
- type: "slider",
3913
+ type: "toggle",
3627
3914
  label: "Sepia",
3628
3915
  property: "sepia",
3629
- min: 0,
3630
- max: 1,
3631
- step: 0.01,
3632
- default: 0
3916
+ default: !1
3633
3917
  },
3634
3918
  {
3635
3919
  id: "negative",
@@ -3640,7 +3924,7 @@ m({
3640
3924
  }
3641
3925
  ]
3642
3926
  });
3643
- const { ColorOverlayFilter: _t } = b;
3927
+ const { ColorOverlayFilter: Lt } = b;
3644
3928
  m({
3645
3929
  id: "colorOverlay",
3646
3930
  name: "Color Overlay",
@@ -3655,7 +3939,7 @@ m({
3655
3939
  try {
3656
3940
  let e = 16711680;
3657
3941
  s.color && (typeof s.color == "string" ? e = parseInt(s.color.replace("#", "0x"), 16) : typeof s.color == "number" && (e = s.color));
3658
- const t = new _t({
3942
+ const t = new Lt({
3659
3943
  color: e,
3660
3944
  alpha: s.alpha || 0.5
3661
3945
  });
@@ -3663,8 +3947,8 @@ m({
3663
3947
  const a = this._customParams || {};
3664
3948
  switch (this._customParams = a, a[i] = r, i) {
3665
3949
  case "color":
3666
- let o;
3667
- typeof r == "string" ? o = parseInt(r.replace("#", "0x"), 16) : o = Number(r), this.color = o, this.uniforms && (this.uniforms.uColor = o);
3950
+ let n;
3951
+ typeof r == "string" ? n = parseInt(r.replace("#", "0x"), 16) : n = Number(r), this.color = n, this.uniforms && (this.uniforms.uColor = n);
3668
3952
  break;
3669
3953
  case "alpha":
3670
3954
  this.alpha = Number(r), this.uniforms && (this.uniforms.uAlpha = Number(r));
@@ -3716,73 +4000,104 @@ m({
3716
4000
  */
3717
4001
  createFilter: (s) => {
3718
4002
  try {
3719
- const e = s.color ? s.color.replace("#", "0x") : "0x000000", t = s.distance !== void 0 ? s.distance : 5, i = s.angle !== void 0 ? s.angle : 90, r = {
4003
+ const e = s.color ? s.color.replace("#", "0x") : "0x000000", t = s.distance !== void 0 ? s.distance : 5, i = s.angle !== void 0 ? s.angle : 90, r = s.blur !== void 0 ? s.blur : 2, a = s.quality !== void 0 ? s.quality : 3, n = {
3720
4004
  x: t * Math.cos(i * Math.PI / 180),
3721
4005
  y: t * Math.sin(i * Math.PI / 180)
3722
- }, a = new b.DropShadowFilter({
3723
- offset: r,
4006
+ }, o = new b.DropShadowFilter({
4007
+ offset: n,
3724
4008
  color: parseInt(e, 16),
3725
4009
  alpha: s.alpha !== void 0 ? s.alpha : 0.5,
3726
- blur: s.blur !== void 0 ? s.blur : 2,
3727
- quality: s.quality !== void 0 ? s.quality : 3,
4010
+ blur: r,
4011
+ quality: a,
3728
4012
  shadowOnly: s.shadowOnly !== void 0 ? s.shadowOnly : !1,
3729
4013
  pixelSize: {
3730
4014
  x: s.pixelSizeX !== void 0 ? s.pixelSizeX : 1,
3731
4015
  y: s.pixelSizeY !== void 0 ? s.pixelSizeY : 1
3732
4016
  }
3733
- });
3734
- return a._customParams = {
4017
+ }), l = (h, u, f, _) => {
4018
+ const g = h * u * 2, x = Math.sqrt(f * f + _ * _);
4019
+ return Math.ceil(g + x + 2);
4020
+ };
4021
+ o._exportPadding = l(r, a, n.x, n.y), o.padding = Math.max(o.padding ?? 0, o._exportPadding), o._customParams = {
3735
4022
  ...s,
3736
4023
  // Also store the calculated offset for use in updateUIParam
3737
- _offset: r,
4024
+ _offset: n,
3738
4025
  _distance: t,
3739
4026
  _angle: i
3740
- }, a.updateUIParam = function(o, n) {
4027
+ };
4028
+ const c = (h, u) => {
4029
+ const f = Number(h._distance ?? h.distance ?? 5) * u, _ = Number(h._angle ?? h.angle ?? 90), g = Number(h.blur ?? 2) * u, x = Number(h.quality ?? 3), A = {
4030
+ x: f * Math.cos(_ * Math.PI / 180),
4031
+ y: f * Math.sin(_ * Math.PI / 180)
4032
+ }, P = h.color ? String(h.color).replace("#", "0x") : "0x000000", T = new b.DropShadowFilter({
4033
+ offset: A,
4034
+ color: parseInt(P, 16),
4035
+ alpha: h.alpha !== void 0 ? Number(h.alpha) : 0.5,
4036
+ blur: g,
4037
+ quality: x,
4038
+ shadowOnly: h.shadowOnly !== void 0 ? !!h.shadowOnly : !1,
4039
+ pixelSize: {
4040
+ x: h.pixelSizeX !== void 0 ? Number(h.pixelSizeX) : 1,
4041
+ y: h.pixelSizeY !== void 0 ? Number(h.pixelSizeY) : 1
4042
+ }
4043
+ }), N = l(g, x, A.x, A.y);
4044
+ return T._exportPadding = N, T.padding = Math.max(T.padding ?? 0, N), T;
4045
+ };
4046
+ o.createExportFilter = function(h = {}) {
4047
+ const u = Number.isFinite(h.previewToNativeScale) ? Math.max(1, Number(h.previewToNativeScale)) : 1, f = this._customParams || s;
4048
+ return c(f, u);
4049
+ }, o.getExportPadding = function() {
4050
+ return Number(this._exportPadding || this.padding || 0);
4051
+ };
4052
+ const d = (h) => {
4053
+ var x;
4054
+ const u = ((x = h._customParams) == null ? void 0 : x._offset) ?? { x: 0, y: 0 }, f = Number(h.blur ?? 0), _ = Number(h.quality ?? 1), g = l(f, _, u.x, u.y);
4055
+ h._exportPadding = g, h.padding = Math.max(h.padding ?? 0, g);
4056
+ };
4057
+ return o.updateUIParam = function(h, u) {
3741
4058
  try {
3742
- const l = this._customParams || {};
3743
- switch (this._customParams = l, l[o] = n, o) {
4059
+ const f = this._customParams || {};
4060
+ switch (this._customParams = f, f[h] = u, h) {
3744
4061
  case "color":
3745
- if (typeof n == "string") {
3746
- const d = parseInt(n.replace("#", "0x"), 16);
3747
- this.color = d;
3748
- }
4062
+ typeof u == "string" && (this.color = parseInt(u.replace("#", "0x"), 16));
3749
4063
  break;
3750
4064
  case "alpha":
3751
- this.alpha = Number(n);
4065
+ this.alpha = Number(u);
3752
4066
  break;
3753
4067
  case "blur":
3754
- this.blur = Number(n);
4068
+ this.blur = Number(u), d(this);
3755
4069
  break;
3756
4070
  case "quality":
3757
- this.quality = Number(n);
4071
+ this.quality = Number(u), d(this);
3758
4072
  break;
3759
4073
  case "shadowOnly":
3760
- this.shadowOnly = !!n;
4074
+ this.shadowOnly = !!u;
3761
4075
  break;
3762
4076
  case "pixelSizeX":
3763
- this.pixelSizeX = Number(n), l.pixelSizeX = Number(n);
4077
+ this.pixelSizeX = Number(u), f.pixelSizeX = Number(u);
3764
4078
  break;
3765
4079
  case "pixelSizeY":
3766
- this.pixelSizeY = Number(n), l.pixelSizeY = Number(n);
4080
+ this.pixelSizeY = Number(u), f.pixelSizeY = Number(u);
3767
4081
  break;
3768
4082
  case "distance":
3769
- case "angle":
3770
- o === "distance" ? l._distance = Number(n) : l._angle = Number(n);
3771
- const c = {
3772
- x: l._distance * Math.cos(l._angle * Math.PI / 180),
3773
- y: l._distance * Math.sin(l._angle * Math.PI / 180)
4083
+ case "angle": {
4084
+ h === "distance" ? (f._distance = Number(u), f.distance = Number(u)) : (f._angle = Number(u), f.angle = Number(u));
4085
+ const _ = {
4086
+ x: f._distance * Math.cos(f._angle * Math.PI / 180),
4087
+ y: f._distance * Math.sin(f._angle * Math.PI / 180)
3774
4088
  };
3775
- l._offset = c, this.offset = c;
4089
+ f._offset = _, this.offset = _, d(this);
3776
4090
  break;
4091
+ }
3777
4092
  default:
3778
- o in this && (this[o] = n);
4093
+ h in this && (this[h] = u);
3779
4094
  break;
3780
4095
  }
3781
4096
  return !0;
3782
4097
  } catch {
3783
- return this._customParams && (this._customParams[o] = n), !1;
4098
+ return this._customParams && (this._customParams[h] = u), !1;
3784
4099
  }
3785
- }, a;
4100
+ }, o;
3786
4101
  } catch {
3787
4102
  return null;
3788
4103
  }
@@ -3887,7 +4202,7 @@ m({
3887
4202
  }
3888
4203
  ]
3889
4204
  });
3890
- const { ColorMatrixFilter: xt } = w;
4205
+ const { ColorMatrixFilter: Dt } = R;
3891
4206
  m({
3892
4207
  id: "grayscale",
3893
4208
  name: "Grayscale",
@@ -3900,14 +4215,14 @@ m({
3900
4215
  */
3901
4216
  createFilter: (s) => {
3902
4217
  try {
3903
- const e = new xt();
4218
+ const e = new Dt();
3904
4219
  e._customParams = { ...s };
3905
4220
  const t = s.intensity !== void 0 ? s.intensity : 1;
3906
- return ne(e, t), e.updateUIParam = function(i, r) {
4221
+ return ye(e, t), e.updateUIParam = function(i, r) {
3907
4222
  const a = this._customParams || {};
3908
4223
  switch (this._customParams = a, a[i] = r, i) {
3909
4224
  case "intensity":
3910
- ne(this, r);
4225
+ ye(this, r);
3911
4226
  break;
3912
4227
  default:
3913
4228
  i in this && (this[i] = r);
@@ -3937,10 +4252,10 @@ m({
3937
4252
  }
3938
4253
  ]
3939
4254
  });
3940
- function ne(s, e) {
4255
+ function ye(s, e) {
3941
4256
  s.reset(), s.greyscale(e);
3942
4257
  }
3943
- const { HslAdjustmentFilter: Ct } = b;
4258
+ const { HslAdjustmentFilter: Vt } = b;
3944
4259
  m({
3945
4260
  id: "hsl-adjustment",
3946
4261
  name: "HSL Adjustment",
@@ -3952,7 +4267,7 @@ m({
3952
4267
  */
3953
4268
  createFilter: (s) => {
3954
4269
  try {
3955
- const e = new Ct({
4270
+ const e = new Vt({
3956
4271
  hue: s.hue !== void 0 ? s.hue : 0,
3957
4272
  saturation: s.saturation !== void 0 ? s.saturation : 0,
3958
4273
  lightness: s.lightness !== void 0 ? s.lightness : 0,
@@ -4050,7 +4365,7 @@ m({
4050
4365
  }
4051
4366
  ]
4052
4367
  });
4053
- const { KawaseBlurFilter: wt } = b;
4368
+ const { KawaseBlurFilter: Ut } = b;
4054
4369
  m({
4055
4370
  id: "kawase-blur",
4056
4371
  name: "Kawase Blur",
@@ -4063,7 +4378,7 @@ m({
4063
4378
  */
4064
4379
  createFilter: (s) => {
4065
4380
  try {
4066
- const e = new wt({
4381
+ const e = new Ut({
4067
4382
  strength: s.strength || 4,
4068
4383
  quality: s.quality || 3,
4069
4384
  clamp: s.clamp || !1,
@@ -4168,7 +4483,7 @@ m({
4168
4483
  }
4169
4484
  ]
4170
4485
  });
4171
- const { MotionBlurFilter: St } = b;
4486
+ const { MotionBlurFilter: jt } = b;
4172
4487
  m({
4173
4488
  id: "motion-blur",
4174
4489
  name: "Motion Blur",
@@ -4181,7 +4496,7 @@ m({
4181
4496
  */
4182
4497
  createFilter: (s) => {
4183
4498
  try {
4184
- const e = new St({
4499
+ const e = new jt({
4185
4500
  velocity: {
4186
4501
  x: s.velocityX !== void 0 ? s.velocityX : 0,
4187
4502
  y: s.velocityY !== void 0 ? s.velocityY : 0
@@ -4276,7 +4591,7 @@ m({
4276
4591
  }
4277
4592
  ]
4278
4593
  });
4279
- const { RadialBlurFilter: vt } = b;
4594
+ const { RadialBlurFilter: qt } = b;
4280
4595
  m({
4281
4596
  id: "radial-blur",
4282
4597
  name: "Radial Blur",
@@ -4285,7 +4600,7 @@ m({
4285
4600
  // Create an instance of the RadialBlurFilter with the provided parameters
4286
4601
  createFilter: (s) => {
4287
4602
  try {
4288
- const e = new vt({
4603
+ const e = new qt({
4289
4604
  angle: s.angle ?? 20,
4290
4605
  center: { x: s.centerX ?? 0, y: s.centerY ?? 0 },
4291
4606
  kernelSize: s.kernelSize ?? 15,
@@ -4400,7 +4715,7 @@ m({
4400
4715
  }
4401
4716
  ]
4402
4717
  });
4403
- const { TiltShiftFilter: kt } = b;
4718
+ const { TiltShiftFilter: Ht } = b;
4404
4719
  m({
4405
4720
  id: "tilt-shift",
4406
4721
  name: "Tilt Shift",
@@ -4409,20 +4724,20 @@ m({
4409
4724
  // Create an instance of the TiltShiftFilter with the provided parameters
4410
4725
  createFilter: (s) => {
4411
4726
  try {
4412
- const e = typeof s.blur == "number" ? s.blur : 100, t = typeof s.gradientBlur == "number" ? s.gradientBlur : 600, i = typeof s.startX == "number" ? s.startX : 0, r = typeof s.startY == "number" ? s.startY : 0.5, a = typeof s.endX == "number" ? s.endX : 1, o = typeof s.endY == "number" ? s.endY : 0.5, n = new kt({
4727
+ const e = typeof s.blur == "number" ? s.blur : 100, t = typeof s.gradientBlur == "number" ? s.gradientBlur : 600, i = typeof s.startX == "number" ? s.startX : 0, r = typeof s.startY == "number" ? s.startY : 0.5, a = typeof s.endX == "number" ? s.endX : 1, n = typeof s.endY == "number" ? s.endY : 0.5, o = new Ht({
4413
4728
  blur: Number(e),
4414
4729
  gradientBlur: Number(t),
4415
4730
  start: { x: Number(i), y: Number(r) },
4416
- end: { x: Number(a), y: Number(o) }
4731
+ end: { x: Number(a), y: Number(n) }
4417
4732
  });
4418
- return n._customParams = {
4733
+ return o._customParams = {
4419
4734
  blur: e,
4420
4735
  gradientBlur: t,
4421
4736
  startX: i,
4422
4737
  startY: r,
4423
4738
  endX: a,
4424
- endY: o
4425
- }, n.updateUIParam = function(l, c) {
4739
+ endY: n
4740
+ }, o.updateUIParam = function(l, c) {
4426
4741
  try {
4427
4742
  const d = Number(c), h = this._customParams || {};
4428
4743
  switch (this._customParams = h, h[l] = d, l) {
@@ -4450,7 +4765,7 @@ m({
4450
4765
  }
4451
4766
  } catch {
4452
4767
  }
4453
- }, n;
4768
+ }, o;
4454
4769
  } catch {
4455
4770
  return null;
4456
4771
  }
@@ -4528,7 +4843,7 @@ m({
4528
4843
  }
4529
4844
  ]
4530
4845
  });
4531
- const { ZoomBlurFilter: Pt } = b;
4846
+ const { ZoomBlurFilter: $t } = b;
4532
4847
  m({
4533
4848
  id: "zoom-blur",
4534
4849
  name: "Zoom Blur",
@@ -4541,7 +4856,7 @@ m({
4541
4856
  */
4542
4857
  createFilter: (s) => {
4543
4858
  try {
4544
- const e = new Pt({
4859
+ const e = new $t({
4545
4860
  strength: s.strength || 0.1,
4546
4861
  center: {
4547
4862
  x: s.centerX !== void 0 ? s.centerX : 0.5,
@@ -4655,178 +4970,163 @@ m({
4655
4970
  }
4656
4971
  ]
4657
4972
  });
4658
- const { ColorGradientFilter: le } = b;
4973
+ const { ColorGradientFilter: _e } = b;
4974
+ function Ie(s) {
4975
+ return parseInt(s.replace("#", "0x"), 16);
4976
+ }
4977
+ function Wt(s) {
4978
+ return "#" + s.toString(16).padStart(6, "0");
4979
+ }
4980
+ function xe(s) {
4981
+ return {
4982
+ offset: Number(s.offset),
4983
+ color: typeof s.color == "string" ? Ie(s.color) : Number(s.color),
4984
+ alpha: Number(s.alpha)
4985
+ };
4986
+ }
4987
+ function Ce(s) {
4988
+ return {
4989
+ offset: s.offset,
4990
+ color: typeof s.color == "number" ? Wt(s.color) : s.color,
4991
+ alpha: s.alpha
4992
+ };
4993
+ }
4659
4994
  m({
4660
4995
  id: "color-gradient",
4661
4996
  name: "Color Gradient",
4662
4997
  category: "color",
4663
4998
  description: "Applies a linear, radial or conic color gradient over the image with multiple color stops",
4664
- /**
4665
- * Create an instance of the ColorGradientFilter with the provided parameters
4666
- * This implementation supports unlimited color stops like the PixiJS example app
4667
- */
4668
4999
  createFilter: (s) => {
4669
- try {
4670
- let e = [];
4671
- e = (s.colorStops || [
4672
- { offset: 0, color: "#ff0000", alpha: 1 },
4673
- { offset: 1, color: "#0000ff", alpha: 1 }
4674
- ]).map((i) => ({
4675
- offset: i.offset,
4676
- color: typeof i.color == "string" ? parseInt(i.color.replace("#", "0x")) : i.color,
4677
- alpha: i.alpha
4678
- })), e.length < 2 && (e = [
4679
- { offset: 0, color: 16711680, alpha: 1 },
4680
- { offset: 1, color: 255, alpha: 1 }
4681
- ]), e.sort((i, r) => i.offset - r.offset);
4682
- const t = new le({
4683
- type: s.gradientType,
4684
- // 0: linear, 1: radial, 2: conic
4685
- stops: e,
4686
- angle: s.angle,
4687
- alpha: s.alpha,
4688
- maxColors: s.maxColors || 0,
4689
- replace: s.replace
4690
- });
4691
- return t._customParams = { ...s }, t.getColorStopsForUI = function() {
4692
- return !this.stops || !Array.isArray(this.stops) ? [] : this.stops.map((r) => ({
4693
- offset: r.offset,
4694
- color: typeof r.color == "number" ? "#" + r.color.toString(16).padStart(6, "0") : r.color,
4695
- alpha: r.alpha
4696
- }));
4697
- }, t.getDynamicControls = function() {
4698
- const i = this.getColorStopsForUI(), r = [];
4699
- return i.forEach((a, o) => {
4700
- r.push({
4701
- id: `colorStop-${o}-color`,
4702
- type: "color",
4703
- label: `Stop ${o + 1} Color`,
4704
- property: `colorStops[${o}].color`,
4705
- default: a.color
4706
- }), r.push({
4707
- id: `colorStop-${o}-offset`,
4708
- type: "slider",
4709
- label: `Stop ${o + 1} Position`,
4710
- property: `colorStops[${o}].offset`,
4711
- min: 0,
4712
- max: 1,
4713
- step: 0.01,
4714
- default: a.offset
4715
- }), r.push({
4716
- id: `colorStop-${o}-alpha`,
4717
- type: "slider",
4718
- label: `Stop ${o + 1} Alpha`,
4719
- property: `colorStops[${o}].alpha`,
4720
- min: 0,
4721
- max: 1,
4722
- step: 0.01,
4723
- default: a.alpha
4724
- });
4725
- }), r;
4726
- }, t.handleButtonAction = function(i) {
4727
- (i === "addColorStop" || i === "removeColorStop") && this.updateUIParam(i, !0);
4728
- }, t.updateUIParam = function(i, r) {
4729
- const a = this._customParams || {};
4730
- switch (this._customParams = a, a[i] = r, i) {
4731
- case "gradientType":
4732
- this.type = r;
4733
- break;
4734
- case "angle":
4735
- case "alpha":
4736
- case "maxColors":
4737
- case "replace":
4738
- i in this && (this[i] = r);
4739
- break;
4740
- case "addColorStop":
4741
- const o = [...this.stops], c = {
4742
- offset: 1,
4743
- // Will be adjusted later
4744
- alpha: 1,
4745
- color: (() => {
4746
- const h = Math.floor(Math.random() * 255), p = Math.floor(Math.random() * 255), f = Math.floor(Math.random() * 255);
4747
- return h << 16 | p << 8 | f;
4748
- })()
4749
- };
4750
- if (o.length > 0) {
4751
- for (let p = 0; p < o.length; p++)
4752
- o[p].offset *= 0.8;
4753
- c.offset = 1;
4754
- }
4755
- o.push(c), this.stops = o, a.colorStops = this.stops.map((h) => ({
4756
- offset: h.offset,
4757
- color: typeof h.color == "number" ? "#" + h.color.toString(16).padStart(6, "0") : h.color,
4758
- alpha: h.alpha
4759
- }));
4760
- break;
4761
- case "removeColorStop":
4762
- const d = [...this.stops];
4763
- d.length > 2 && (d.pop(), this.stops = d, a.colorStops = this.stops.map((h) => ({
4764
- offset: h.offset,
4765
- color: typeof h.color == "number" ? "#" + h.color.toString(16).padStart(6, "0") : h.color,
4766
- alpha: h.alpha
4767
- })));
4768
- break;
4769
- case "cssGradient":
4770
- if (r && typeof r == "string" && r.trim() !== "")
4771
- try {
4772
- const h = new le({ css: r });
4773
- this.type = h.type, this.angle = h.angle, this.stops = [...h.stops], a.colorStops = this.stops.map((p) => ({
4774
- offset: p.offset,
4775
- color: typeof p.color == "number" ? "#" + p.color.toString(16).padStart(6, "0") : p.color,
4776
- alpha: p.alpha
4777
- }));
4778
- } catch {
4779
- }
4780
- break;
4781
- case "colorStops":
4782
- if (Array.isArray(r)) {
4783
- const h = r.map((p) => ({
4784
- offset: p.offset,
4785
- color: typeof p.color == "string" ? parseInt(p.color.replace("#", "0x")) : p.color,
4786
- alpha: p.alpha
4787
- }));
4788
- h.sort((p, f) => p.offset - f.offset), this.stops = h;
4789
- }
4790
- break;
4791
- default:
4792
- if (/colorStops\[\d+\]\..*/.test(i)) {
4793
- const h = i.match(/colorStops\[(\d+)\]\.(.*)/);
4794
- if (h) {
4795
- const [p, f, _] = h, g = parseInt(f), y = [...this.stops];
4796
- if (g >= 0 && g < y.length)
4797
- return _ === "color" && typeof r == "string" ? y[g].color = parseInt(r.replace("#", "0x")) : (_ === "offset" || _ === "alpha") && (y[g][_] = r), this.stops = y, this.stops.sort((v, x) => v.offset - x.offset), a.colorStops = this.getColorStopsForUI(), !0;
4798
- }
4799
- } else i in this && (this[i] = r);
4800
- break;
5000
+ let t = (s.colorStops || [
5001
+ { offset: 0, color: "#ff0000", alpha: 1 },
5002
+ { offset: 1, color: "#0000ff", alpha: 1 }
5003
+ ]).map(xe);
5004
+ t.length < 2 && (t = [
5005
+ { offset: 0, color: 16711680, alpha: 1 },
5006
+ { offset: 1, color: 255, alpha: 1 }
5007
+ ]), t.sort((r, a) => r.offset - a.offset);
5008
+ const i = new _e({
5009
+ type: s.gradientType,
5010
+ stops: t,
5011
+ angle: s.angle,
5012
+ alpha: s.alpha,
5013
+ maxColors: s.maxColors || 0,
5014
+ replace: s.replace
5015
+ });
5016
+ return i._customParams = {
5017
+ cssGradient: s.cssGradient || ""
5018
+ }, i.getSerializableParams = function() {
5019
+ var a;
5020
+ const r = Array.isArray(this.stops) ? this.stops.map(Ce) : [];
5021
+ return {
5022
+ gradientType: this.type,
5023
+ colorStops: r,
5024
+ angle: this.angle,
5025
+ alpha: this.alpha,
5026
+ maxColors: this.maxColors,
5027
+ replace: this.replace,
5028
+ cssGradient: ((a = this._customParams) == null ? void 0 : a.cssGradient) ?? ""
5029
+ };
5030
+ }, i.getColorStopsForUI = function() {
5031
+ return Array.isArray(this.stops) ? this.stops.map(Ce) : [];
5032
+ }, i.getDynamicControls = function() {
5033
+ const r = this.getColorStopsForUI(), a = [];
5034
+ return r.forEach((n, o) => {
5035
+ a.push({
5036
+ id: `colorStop-${o}-color`,
5037
+ type: "color",
5038
+ label: `Stop ${o + 1} Color`,
5039
+ property: `colorStops[${o}].color`,
5040
+ default: n.color
5041
+ }), a.push({
5042
+ id: `colorStop-${o}-offset`,
5043
+ type: "slider",
5044
+ label: `Stop ${o + 1} Position`,
5045
+ property: `colorStops[${o}].offset`,
5046
+ min: 0,
5047
+ max: 1,
5048
+ step: 0.01,
5049
+ default: n.offset
5050
+ }), a.push({
5051
+ id: `colorStop-${o}-alpha`,
5052
+ type: "slider",
5053
+ label: `Stop ${o + 1} Alpha`,
5054
+ property: `colorStops[${o}].alpha`,
5055
+ min: 0,
5056
+ max: 1,
5057
+ step: 0.01,
5058
+ default: n.alpha
5059
+ });
5060
+ }), a;
5061
+ }, i.handleButtonAction = function(r) {
5062
+ (r === "addColorStop" || r === "removeColorStop") && this.updateUIParam(r, !0);
5063
+ }, i.updateUIParam = function(r, a) {
5064
+ const n = this._customParams ?? {};
5065
+ switch (this._customParams = n, r) {
5066
+ case "gradientType":
5067
+ this.type = Number(a);
5068
+ return;
5069
+ case "angle":
5070
+ case "alpha":
5071
+ case "maxColors":
5072
+ this[r] = Number(a);
5073
+ return;
5074
+ case "replace":
5075
+ this.replace = !!a;
5076
+ return;
5077
+ case "addColorStop": {
5078
+ const o = Array.isArray(this.stops) ? [...this.stops] : [], l = Math.floor(Math.random() * 255) << 16 | Math.floor(Math.random() * 255) << 8 | Math.floor(Math.random() * 255);
5079
+ if (o.length > 0)
5080
+ for (const d of o)
5081
+ d.offset *= 0.8;
5082
+ o.push({ offset: 1, color: l, alpha: 1 }), o.sort((c, d) => c.offset - d.offset), this.stops = o;
5083
+ return;
4801
5084
  }
4802
- }, t;
4803
- } catch {
4804
- return null;
4805
- }
5085
+ case "removeColorStop": {
5086
+ const o = Array.isArray(this.stops) ? [...this.stops] : [];
5087
+ o.length > 2 && (o.pop(), this.stops = o);
5088
+ return;
5089
+ }
5090
+ case "cssGradient": {
5091
+ const o = typeof a == "string" ? a.trim() : "";
5092
+ if (n.cssGradient = o, !o) return;
5093
+ try {
5094
+ const l = new _e({ css: o });
5095
+ this.type = l.type, this.angle = l.angle, this.stops = [...l.stops];
5096
+ } catch {
5097
+ }
5098
+ return;
5099
+ }
5100
+ case "colorStops": {
5101
+ if (!Array.isArray(a)) return;
5102
+ const o = a.map(xe);
5103
+ o.sort((l, c) => l.offset - c.offset), this.stops = o;
5104
+ return;
5105
+ }
5106
+ default: {
5107
+ const o = /^colorStops\[(\d+)\]\.(offset|color|alpha)$/.exec(r);
5108
+ if (o) {
5109
+ const [, l, c] = o, d = Number(l), h = Array.isArray(this.stops) ? [...this.stops] : [];
5110
+ if (d < 0 || d >= h.length) return;
5111
+ c === "color" ? h[d].color = typeof a == "string" ? Ie(a) : Number(a) : (c === "offset" || c === "alpha") && (h[d][c] = Number(a)), this.stops = h;
5112
+ }
5113
+ }
5114
+ }
5115
+ }, i;
4806
5116
  },
4807
- // Default parameter values - matching the example app
4808
5117
  defaultParams: {
4809
5118
  gradientType: 0,
4810
- // 0: linear, 1: radial, 2: conic
4811
5119
  colorStops: [
4812
5120
  { offset: 0, color: "#ff0000", alpha: 1 },
4813
5121
  { offset: 1, color: "#0000ff", alpha: 1 }
4814
5122
  ],
4815
- // Controls for adding/removing stops
4816
- addColorStop: !1,
4817
- // Button trigger for adding a color stop
4818
- removeColorStop: !1,
4819
- // Button trigger for removing a color stop
4820
5123
  cssGradient: "",
4821
- // CSS gradient string input
4822
5124
  angle: 90,
4823
5125
  alpha: 0.75,
4824
5126
  maxColors: 0,
4825
5127
  replace: !1
4826
5128
  },
4827
- // UI controls for the filter
4828
5129
  controls: [
4829
- // Basic gradient controls
4830
5130
  {
4831
5131
  id: "gradientType",
4832
5132
  type: "select",
@@ -4876,7 +5176,6 @@ m({
4876
5176
  property: "replace",
4877
5177
  default: !1
4878
5178
  },
4879
- // Advanced color stop management - simpler approach
4880
5179
  {
4881
5180
  id: "addColorStop",
4882
5181
  type: "button",
@@ -4895,7 +5194,7 @@ m({
4895
5194
  label: "CSS Gradient",
4896
5195
  property: "cssGradient",
4897
5196
  default: "",
4898
- tooltip: 'Enter a CSS gradient like "linear-gradient(to right, red, blue)"'
5197
+ placeholder: "e.g. linear-gradient(to right, red, blue)"
4899
5198
  }
4900
5199
  ]
4901
5200
  });
@@ -4911,17 +5210,17 @@ m({
4911
5210
  if (!e)
4912
5211
  return null;
4913
5212
  let t = null;
4914
- s.texturePath ? t = w.Texture.from(s.texturePath) : t = w.Texture.from("/examples/filters-main/examples/images/colormap.png");
5213
+ s.texturePath ? t = R.Texture.from(s.texturePath) : t = R.Texture.from("/examples/filters-main/examples/images/colormap.png");
4915
5214
  const i = new e({
4916
5215
  colorMap: t,
4917
5216
  nearest: s.nearest,
4918
5217
  mix: s.mix
4919
5218
  });
4920
5219
  return i._customParams = { ...s }, i.updateUIParam = function(r, a) {
4921
- const o = this._customParams || {};
4922
- switch (this._customParams = o, o[r] = a, r) {
5220
+ const n = this._customParams || {};
5221
+ switch (this._customParams = n, n[r] = a, r) {
4923
5222
  case "texturePath":
4924
- a && (this.colorMap = w.Texture.from(a));
5223
+ a && (this.colorMap = R.Texture.from(a));
4925
5224
  break;
4926
5225
  case "mix":
4927
5226
  this.mix = a;
@@ -4982,7 +5281,7 @@ m({
4982
5281
  }
4983
5282
  ]
4984
5283
  });
4985
- const Mt = b.ColorReplaceFilter;
5284
+ const Zt = b.ColorReplaceFilter;
4986
5285
  m({
4987
5286
  id: "color-replace",
4988
5287
  name: "Color Replace",
@@ -4999,14 +5298,14 @@ m({
4999
5298
  s.originalColor && (typeof s.originalColor == "string" ? e = parseInt(s.originalColor.replace("#", "0x"), 16) : typeof s.originalColor == "number" && (e = s.originalColor));
5000
5299
  let t = 255;
5001
5300
  s.targetColor && (typeof s.targetColor == "string" ? t = parseInt(s.targetColor.replace("#", "0x"), 16) : typeof s.targetColor == "number" && (t = s.targetColor));
5002
- const i = new Mt({
5301
+ const i = new Zt({
5003
5302
  originalColor: e,
5004
5303
  targetColor: t,
5005
5304
  tolerance: s.tolerance || 0.4
5006
5305
  });
5007
5306
  return i._customParams = { ...s }, i.updateUIParam = function(r, a) {
5008
- const o = this._customParams || {};
5009
- switch (this._customParams = o, o[r] = a, r) {
5307
+ const n = this._customParams || {};
5308
+ switch (this._customParams = n, n[r] = a, r) {
5010
5309
  case "originalColor":
5011
5310
  typeof a == "string" ? this.originalColor = parseInt(a.replace("#", "0x"), 16) : typeof a == "number" && (this.originalColor = a);
5012
5311
  break;
@@ -5063,7 +5362,7 @@ m({
5063
5362
  }
5064
5363
  ]
5065
5364
  });
5066
- const Ft = b.MultiColorReplaceFilter;
5365
+ const Gt = b.MultiColorReplaceFilter;
5067
5366
  m({
5068
5367
  id: "multi-color-replace",
5069
5368
  name: "Multi-Color Replace",
@@ -5089,7 +5388,7 @@ m({
5089
5388
  const i = typeof s.originalColor3 == "string" ? parseInt(s.originalColor3.replace("#", "0x"), 16) : s.originalColor3, r = typeof s.targetColor3 == "string" ? parseInt(s.targetColor3.replace("#", "0x"), 16) : s.targetColor3;
5090
5389
  e.push([i, r]);
5091
5390
  }
5092
- const t = new Ft(
5391
+ const t = new Gt(
5093
5392
  e,
5094
5393
  s.tolerance || 0.05,
5095
5394
  3
@@ -5098,20 +5397,20 @@ m({
5098
5397
  return t._customParams = { ...s }, t.updateUIParam = function(i, r) {
5099
5398
  const a = this._customParams || {};
5100
5399
  if (this._customParams = a, a[i] = r, i === "originalColor1" || i === "targetColor1" || i === "originalColor2" || i === "targetColor2" || i === "originalColor3" || i === "targetColor3" || i === "enableThirdPair") {
5101
- const o = [];
5400
+ const n = [];
5102
5401
  if (a.originalColor1 && a.targetColor1) {
5103
- const n = typeof a.originalColor1 == "string" ? parseInt(a.originalColor1.replace("#", "0x"), 16) : a.originalColor1, l = typeof a.targetColor1 == "string" ? parseInt(a.targetColor1.replace("#", "0x"), 16) : a.targetColor1;
5104
- o.push([n, l]);
5402
+ const o = typeof a.originalColor1 == "string" ? parseInt(a.originalColor1.replace("#", "0x"), 16) : a.originalColor1, l = typeof a.targetColor1 == "string" ? parseInt(a.targetColor1.replace("#", "0x"), 16) : a.targetColor1;
5403
+ n.push([o, l]);
5105
5404
  }
5106
5405
  if (a.originalColor2 && a.targetColor2) {
5107
- const n = typeof a.originalColor2 == "string" ? parseInt(a.originalColor2.replace("#", "0x"), 16) : a.originalColor2, l = typeof a.targetColor2 == "string" ? parseInt(a.targetColor2.replace("#", "0x"), 16) : a.targetColor2;
5108
- o.push([n, l]);
5406
+ const o = typeof a.originalColor2 == "string" ? parseInt(a.originalColor2.replace("#", "0x"), 16) : a.originalColor2, l = typeof a.targetColor2 == "string" ? parseInt(a.targetColor2.replace("#", "0x"), 16) : a.targetColor2;
5407
+ n.push([o, l]);
5109
5408
  }
5110
5409
  if (a.enableThirdPair && a.originalColor3 && a.targetColor3) {
5111
- const n = typeof a.originalColor3 == "string" ? parseInt(a.originalColor3.replace("#", "0x"), 16) : a.originalColor3, l = typeof a.targetColor3 == "string" ? parseInt(a.targetColor3.replace("#", "0x"), 16) : a.targetColor3;
5112
- o.push([n, l]);
5410
+ const o = typeof a.originalColor3 == "string" ? parseInt(a.originalColor3.replace("#", "0x"), 16) : a.originalColor3, l = typeof a.targetColor3 == "string" ? parseInt(a.targetColor3.replace("#", "0x"), 16) : a.targetColor3;
5411
+ n.push([o, l]);
5113
5412
  }
5114
- this.replacements = o, this.refresh();
5413
+ this.replacements = n, this.refresh();
5115
5414
  } else i === "tolerance" ? this.tolerance = r : i in this && (this[i] = r);
5116
5415
  return !0;
5117
5416
  }, t;
@@ -5200,7 +5499,7 @@ m({
5200
5499
  }
5201
5500
  ]
5202
5501
  });
5203
- const { RGBSplitFilter: At } = b;
5502
+ const { RGBSplitFilter: Kt } = b;
5204
5503
  m({
5205
5504
  id: "rgb-split",
5206
5505
  name: "RGB Split",
@@ -5221,40 +5520,40 @@ m({
5221
5520
  }, i = {
5222
5521
  x: s.blueX !== void 0 ? s.blueX : 0,
5223
5522
  y: s.blueY !== void 0 ? s.blueY : 0
5224
- }, r = new At({
5523
+ }, r = new Kt({
5225
5524
  red: e,
5226
5525
  green: t,
5227
5526
  blue: i
5228
5527
  });
5229
- return r._customParams = { ...s }, r.updateUIParam = function(a, o) {
5528
+ return r._customParams = { ...s }, r.updateUIParam = function(a, n) {
5230
5529
  try {
5231
- const n = this._customParams || {};
5232
- switch (this._customParams = n, n[a] = o, a) {
5530
+ const o = this._customParams || {};
5531
+ switch (this._customParams = o, o[a] = n, a) {
5233
5532
  case "redX":
5234
- this.redX = Number(o);
5533
+ this.redX = Number(n);
5235
5534
  break;
5236
5535
  case "redY":
5237
- this.redY = Number(o);
5536
+ this.redY = Number(n);
5238
5537
  break;
5239
5538
  case "greenX":
5240
- this.greenX = Number(o);
5539
+ this.greenX = Number(n);
5241
5540
  break;
5242
5541
  case "greenY":
5243
- this.greenY = Number(o);
5542
+ this.greenY = Number(n);
5244
5543
  break;
5245
5544
  case "blueX":
5246
- this.blueX = Number(o);
5545
+ this.blueX = Number(n);
5247
5546
  break;
5248
5547
  case "blueY":
5249
- this.blueY = Number(o);
5548
+ this.blueY = Number(n);
5250
5549
  break;
5251
5550
  default:
5252
- a in this && (this[a] = o);
5551
+ a in this && (this[a] = n);
5253
5552
  break;
5254
5553
  }
5255
5554
  return !0;
5256
5555
  } catch {
5257
- return this._customParams && (this._customParams[a] = o), !1;
5556
+ return this._customParams && (this._customParams[a] = n), !1;
5258
5557
  }
5259
5558
  }, r;
5260
5559
  } catch {
@@ -5334,7 +5633,7 @@ m({
5334
5633
  }
5335
5634
  ]
5336
5635
  });
5337
- const { AdvancedBloomFilter: zt } = b;
5636
+ const { AdvancedBloomFilter: Qt } = b;
5338
5637
  m({
5339
5638
  id: "advanced-bloom",
5340
5639
  name: "Advanced Bloom",
@@ -5343,7 +5642,7 @@ m({
5343
5642
  // Create an instance of the AdvancedBloomFilter with the provided parameters
5344
5643
  createFilter: (s) => {
5345
5644
  try {
5346
- const e = new zt({
5645
+ const e = new Qt({
5347
5646
  threshold: s.threshold || 0.5,
5348
5647
  bloomScale: s.bloomScale || 1,
5349
5648
  brightness: s.brightness || 1,
@@ -5490,7 +5789,7 @@ m({
5490
5789
  }
5491
5790
  ]
5492
5791
  });
5493
- const Rt = b.AsciiFilter;
5792
+ const Jt = b.AsciiFilter;
5494
5793
  m({
5495
5794
  id: "ascii",
5496
5795
  name: "ASCII",
@@ -5502,7 +5801,7 @@ m({
5502
5801
  const e = typeof s.size == "number" ? s.size : 8;
5503
5802
  let t = s.color;
5504
5803
  typeof t == "string" && t.startsWith("#") && (t = parseInt(t.replace("#", "0x"), 16));
5505
- const i = s.replaceColor === !0, r = new Rt({
5804
+ const i = s.replaceColor === !0, r = new Jt({
5506
5805
  size: e,
5507
5806
  color: t,
5508
5807
  replaceColor: i
@@ -5511,21 +5810,21 @@ m({
5511
5810
  size: e,
5512
5811
  color: t,
5513
5812
  replaceColor: i
5514
- }, r.updateUIParam = function(a, o) {
5813
+ }, r.updateUIParam = function(a, n) {
5515
5814
  try {
5516
- const n = this._customParams || {};
5517
- switch (this._customParams = n, n[a] = o, a) {
5815
+ const o = this._customParams || {};
5816
+ switch (this._customParams = o, o[a] = n, a) {
5518
5817
  case "size":
5519
- this.size = Number(o);
5818
+ this.size = Number(n);
5520
5819
  break;
5521
5820
  case "color":
5522
- typeof o == "string" && o.startsWith("#") ? (n.color = o, this.color = parseInt(o.replace("#", "0x"), 16)) : this.color = o;
5821
+ typeof n == "string" && n.startsWith("#") ? (o.color = n, this.color = parseInt(n.replace("#", "0x"), 16)) : this.color = n;
5523
5822
  break;
5524
5823
  case "replaceColor":
5525
- this.replaceColor = !!o;
5824
+ this.replaceColor = !!n;
5526
5825
  break;
5527
5826
  default:
5528
- a in this && (this[a] = o);
5827
+ a in this && (this[a] = n);
5529
5828
  break;
5530
5829
  }
5531
5830
  } catch {
@@ -5569,7 +5868,7 @@ m({
5569
5868
  }
5570
5869
  ]
5571
5870
  });
5572
- const Nt = b.BackdropBlurFilter;
5871
+ const ei = b.BackdropBlurFilter;
5573
5872
  m({
5574
5873
  id: "backdrop-blur",
5575
5874
  name: "Backdrop Blur",
@@ -5578,7 +5877,7 @@ m({
5578
5877
  // Create an instance of the BackdropBlurFilter with the provided parameters
5579
5878
  createFilter: (s) => {
5580
5879
  try {
5581
- const e = new Nt({
5880
+ const e = new ei({
5582
5881
  // Higher strength values (20-50) make the effect more noticeable
5583
5882
  strength: s.strength || 20,
5584
5883
  quality: s.quality || 4,
@@ -5676,7 +5975,7 @@ m({
5676
5975
  }
5677
5976
  ]
5678
5977
  });
5679
- const { BevelFilter: Tt } = b;
5978
+ const { BevelFilter: ti } = b;
5680
5979
  m({
5681
5980
  id: "bevel",
5682
5981
  name: "Bevel",
@@ -5688,7 +5987,7 @@ m({
5688
5987
  */
5689
5988
  createFilter: (s) => {
5690
5989
  try {
5691
- const e = s.lightColor ? s.lightColor.replace("#", "0x") : "0xffffff", t = s.shadowColor ? s.shadowColor.replace("#", "0x") : "0x000000", i = new Tt({
5990
+ const e = s.lightColor ? s.lightColor.replace("#", "0x") : "0xffffff", t = s.shadowColor ? s.shadowColor.replace("#", "0x") : "0x000000", i = new ti({
5692
5991
  rotation: s.rotation !== void 0 ? s.rotation : 45,
5693
5992
  thickness: s.thickness !== void 0 ? s.thickness : 2,
5694
5993
  lightColor: parseInt(e, 16),
@@ -5698,8 +5997,8 @@ m({
5698
5997
  });
5699
5998
  return i._customParams = { ...s }, i.updateUIParam = function(r, a) {
5700
5999
  try {
5701
- const o = this._customParams || {};
5702
- switch (this._customParams = o, o[r] = a, r) {
6000
+ const n = this._customParams || {};
6001
+ switch (this._customParams = n, n[r] = a, r) {
5703
6002
  case "rotation":
5704
6003
  this.rotation = Number(a);
5705
6004
  break;
@@ -5708,8 +6007,8 @@ m({
5708
6007
  break;
5709
6008
  case "lightColor":
5710
6009
  if (typeof a == "string") {
5711
- const n = parseInt(a.replace("#", "0x"), 16);
5712
- this.lightColor = n;
6010
+ const o = parseInt(a.replace("#", "0x"), 16);
6011
+ this.lightColor = o;
5713
6012
  }
5714
6013
  break;
5715
6014
  case "lightAlpha":
@@ -5717,8 +6016,8 @@ m({
5717
6016
  break;
5718
6017
  case "shadowColor":
5719
6018
  if (typeof a == "string") {
5720
- const n = parseInt(a.replace("#", "0x"), 16);
5721
- this.shadowColor = n;
6019
+ const o = parseInt(a.replace("#", "0x"), 16);
6020
+ this.shadowColor = o;
5722
6021
  }
5723
6022
  break;
5724
6023
  case "shadowAlpha":
@@ -5804,7 +6103,7 @@ m({
5804
6103
  }
5805
6104
  ]
5806
6105
  });
5807
- const { BloomFilter: It } = b;
6106
+ const { BloomFilter: ii } = b;
5808
6107
  m({
5809
6108
  id: "bloom",
5810
6109
  name: "Bloom/Glow",
@@ -5813,7 +6112,7 @@ m({
5813
6112
  // Create an instance of the BloomFilter with the provided parameters
5814
6113
  createFilter: (s) => {
5815
6114
  try {
5816
- const e = typeof s.strengthX == "number" ? s.strengthX : 2, t = typeof s.strengthY == "number" ? s.strengthY : 2, i = typeof s.quality == "number" ? s.quality : 4, r = typeof s.resolution == "number" ? s.resolution : 1, a = typeof s.kernelSize == "number" ? s.kernelSize : 5, o = new It({
6115
+ const e = typeof s.strengthX == "number" ? s.strengthX : 2, t = typeof s.strengthY == "number" ? s.strengthY : 2, i = typeof s.quality == "number" ? s.quality : 4, r = typeof s.resolution == "number" ? s.resolution : 1, a = typeof s.kernelSize == "number" ? s.kernelSize : 5, n = new ii({
5817
6116
  strength: {
5818
6117
  x: Number(e),
5819
6118
  y: Number(t)
@@ -5822,17 +6121,17 @@ m({
5822
6121
  resolution: Number(r),
5823
6122
  kernelSize: Number(a)
5824
6123
  });
5825
- return o._customParams = {
6124
+ return n._customParams = {
5826
6125
  strengthX: e,
5827
6126
  strengthY: t,
5828
6127
  quality: i,
5829
6128
  resolution: r,
5830
6129
  kernelSize: a
5831
- }, o.updateUIParam = function(n, l) {
6130
+ }, n.updateUIParam = function(o, l) {
5832
6131
  var c, d;
5833
6132
  try {
5834
- const h = Number(l), p = this._customParams || {};
5835
- switch (this._customParams = p, p[n] = h, n) {
6133
+ const h = Number(l), u = this._customParams || {};
6134
+ switch (this._customParams = u, u[o] = h, o) {
5836
6135
  case "strengthX":
5837
6136
  this.strength && typeof this.strength == "object" && (this.strength.x = h, (c = this._updateStrength) == null || c.call(this));
5838
6137
  break;
@@ -5849,12 +6148,12 @@ m({
5849
6148
  this.kernelSize = h;
5850
6149
  break;
5851
6150
  default:
5852
- n in this && (this[n] = h);
6151
+ o in this && (this[o] = h);
5853
6152
  break;
5854
6153
  }
5855
6154
  } catch {
5856
6155
  }
5857
- }, o;
6156
+ }, n;
5858
6157
  } catch {
5859
6158
  return null;
5860
6159
  }
@@ -5916,55 +6215,71 @@ m({
5916
6215
  }
5917
6216
  ]
5918
6217
  });
5919
- const { BulgePinchFilter: Et } = b;
6218
+ const { BulgePinchFilter: we } = b, ie = (s) => {
6219
+ const e = Math.max(0, Number(s) || 0);
6220
+ return Math.ceil(e + 2);
6221
+ };
5920
6222
  m({
5921
6223
  id: "bulge-pinch",
5922
- // ID must match what the application expects
5923
6224
  name: "Bulge/Pinch",
5924
6225
  category: "distortion",
5925
6226
  description: "Creates a bulge or pinch effect in a circular area",
5926
- // Create an instance of the BulgePinchFilter with the provided parameters
5927
6227
  createFilter: (s) => {
5928
6228
  try {
5929
- const e = s.centerX ?? 0.5, t = s.centerY ?? 0.5, i = s.radius ?? 100, r = s.strength ?? 1, a = new Et({
5930
- center: {
5931
- x: e,
5932
- y: t
5933
- },
6229
+ const e = s.centerX ?? 0.5, t = s.centerY ?? 0.5, i = s.radius ?? 100, r = s.strength ?? 1, a = new we({
6230
+ center: { x: e, y: t },
5934
6231
  radius: i,
5935
6232
  strength: r
5936
- });
5937
- return a._customParams = { ...s }, a.updateUIParam = function(o, n) {
5938
- const l = this._customParams || {};
5939
- switch (this._customParams = l, l[o] = n, o) {
6233
+ }), n = ie(i);
6234
+ a.padding = Math.max(a.padding ?? 0, n), a._exportPadding = n, a._customParams = { ...s };
6235
+ const o = (l) => {
6236
+ var h;
6237
+ const c = Number(((h = l._customParams) == null ? void 0 : h.radius) ?? l.radius ?? 0), d = ie(c);
6238
+ l._exportPadding = d, l.padding = Math.max(l.padding ?? 0, d);
6239
+ };
6240
+ return a.updateUIParam = function(l, c) {
6241
+ const d = this._customParams || {};
6242
+ switch (this._customParams = d, d[l] = c, l) {
5940
6243
  case "centerX":
5941
- this.center || (this.center = { x: 0.5, y: 0.5 }), this.center.x = n;
6244
+ this.center || (this.center = { x: 0.5, y: 0.5 }), this.center.x = c;
5942
6245
  break;
5943
6246
  case "centerY":
5944
- this.center || (this.center = { x: 0.5, y: 0.5 }), this.center.y = n;
6247
+ this.center || (this.center = { x: 0.5, y: 0.5 }), this.center.y = c;
5945
6248
  break;
5946
6249
  case "radius":
6250
+ this.radius = Number(c), o(this);
6251
+ break;
5947
6252
  case "strength":
5948
- this[o] = n;
6253
+ this.strength = Number(c);
5949
6254
  break;
5950
6255
  default:
5951
- o in this && (this[o] = n);
6256
+ l in this && (this[l] = c);
5952
6257
  break;
5953
6258
  }
5954
6259
  return !0;
6260
+ }, a.createExportFilter = function(l = {}) {
6261
+ const c = Number.isFinite(l.previewToNativeScale) ? Math.max(1, Number(l.previewToNativeScale)) : 1, d = this._customParams || s, h = Number(d.radius ?? 100) * c, u = new we({
6262
+ center: {
6263
+ x: Number(d.centerX ?? 0.5),
6264
+ y: Number(d.centerY ?? 0.5)
6265
+ },
6266
+ radius: h,
6267
+ strength: Number(d.strength ?? 1)
6268
+ }), f = ie(h);
6269
+ return u._exportPadding = f, u.padding = Math.max(u.padding ?? 0, f), u;
6270
+ }, a.getExportPadding = function() {
6271
+ return Number(this._exportPadding || this.padding || 0);
5955
6272
  }, a;
5956
6273
  } catch {
5957
6274
  return null;
5958
6275
  }
5959
6276
  },
5960
- // Default parameter values
5961
6277
  defaultParams: {
5962
6278
  centerX: 0.5,
5963
6279
  centerY: 0.5,
5964
6280
  radius: 100,
5965
6281
  strength: 1
5966
6282
  },
5967
- // UI controls for the filter
5968
6283
  controls: [
5969
6284
  {
5970
6285
  id: "centerX",
@@ -6008,7 +6323,7 @@ m({
6008
6323
  }
6009
6324
  ]
6010
6325
  });
6011
- const { ConvolutionFilter: Xt } = b, O = {
6326
+ const { ConvolutionFilter: ri } = b, q = {
6012
6327
  normal: [0, 0, 0, 0, 1, 0, 0, 0, 0],
6013
6328
  gaussianBlur: [0.045, 0.122, 0.045, 0.122, 0.332, 0.122, 0.045, 0.122, 0.045],
6014
6329
  boxBlur: [1 / 9, 1 / 9, 1 / 9, 1 / 9, 1 / 9, 1 / 9, 1 / 9, 1 / 9, 1 / 9],
@@ -6041,25 +6356,25 @@ m({
6041
6356
  ];
6042
6357
  else {
6043
6358
  const i = s.preset;
6044
- e = O[i] || O.normal;
6359
+ e = q[i] || q.normal;
6045
6360
  }
6046
- const t = new Xt(e, s.width || 200, s.height || 200);
6361
+ const t = new ri(e, s.width || 200, s.height || 200);
6047
6362
  return t._customParams = { ...s }, t.updateUIParam = function(i, r) {
6048
6363
  const a = this._customParams || {};
6049
6364
  switch (this._customParams = a, a[i] = r, i) {
6050
6365
  case "preset":
6051
6366
  if (!a.customMatrix) {
6052
- const o = r;
6053
- O[o] && (this.matrix = O[o]);
6367
+ const n = r;
6368
+ q[n] && (this.matrix = q[n]);
6054
6369
  }
6055
6370
  break;
6056
6371
  case "customMatrix":
6057
6372
  if (r) {
6058
- const o = this.matrix;
6059
- a.m00 = o[0], a.m01 = o[1], a.m02 = o[2], a.m10 = o[3], a.m11 = o[4], a.m12 = o[5], a.m20 = o[6], a.m21 = o[7], a.m22 = o[8];
6373
+ const n = this.matrix;
6374
+ a.m00 = n[0], a.m01 = n[1], a.m02 = n[2], a.m10 = n[3], a.m11 = n[4], a.m12 = n[5], a.m20 = n[6], a.m21 = n[7], a.m22 = n[8];
6060
6375
  } else {
6061
- const o = a.preset;
6062
- this.matrix = O[o] || O.normal;
6376
+ const n = a.preset;
6377
+ this.matrix = q[n] || q.normal;
6063
6378
  }
6064
6379
  break;
6065
6380
  case "m00":
@@ -6072,7 +6387,7 @@ m({
6072
6387
  case "m21":
6073
6388
  case "m22":
6074
6389
  if (a.customMatrix) {
6075
- const o = [...this.matrix], l = {
6390
+ const n = [...this.matrix], l = {
6076
6391
  m00: 0,
6077
6392
  m01: 1,
6078
6393
  m02: 2,
@@ -6083,7 +6398,7 @@ m({
6083
6398
  m21: 7,
6084
6399
  m22: 8
6085
6400
  }[i];
6086
- l !== void 0 && (o[l] = r, this.matrix = o);
6401
+ l !== void 0 && (n[l] = r, this.matrix = n);
6087
6402
  }
6088
6403
  break;
6089
6404
  case "width":
@@ -6254,7 +6569,7 @@ m({
6254
6569
  }
6255
6570
  ]
6256
6571
  });
6257
- const { CrossHatchFilter: Yt } = b;
6572
+ const { CrossHatchFilter: si } = b;
6258
6573
  m({
6259
6574
  id: "cross-hatch",
6260
6575
  name: "Cross Hatch",
@@ -6264,7 +6579,7 @@ m({
6264
6579
  // Note: CrossHatchFilter has NO parameters according to PixiJS examples
6265
6580
  createFilter: (s) => {
6266
6581
  try {
6267
- const e = new Yt();
6582
+ const e = new si();
6268
6583
  return e.updateUIParam = function(t, i) {
6269
6584
  return !0;
6270
6585
  }, e;
@@ -6461,7 +6776,7 @@ m({
6461
6776
  }
6462
6777
  ]
6463
6778
  });
6464
- const Bt = w.DisplacementFilter, Ot = w.Sprite, K = w.Texture;
6779
+ const ai = R.DisplacementFilter, ni = R.Sprite, re = R.Texture;
6465
6780
  m({
6466
6781
  id: "displacement",
6467
6782
  // ID must match what the application expects
@@ -6474,41 +6789,41 @@ m({
6474
6789
  const e = s.mapTexture || "/assets/images/displacement_map.png";
6475
6790
  let t;
6476
6791
  try {
6477
- t = K.from(e), t.source.addressMode = "repeat";
6792
+ t = re.from(e), t.source.addressMode = "repeat";
6478
6793
  } catch {
6479
- const o = document.createElement("canvas");
6480
- o.width = 256, o.height = 256;
6481
- const n = o.getContext("2d");
6482
- if (n) {
6483
- n.fillStyle = "#ffffff", n.fillRect(0, 0, o.width, o.height), n.fillStyle = "#000000";
6794
+ const n = document.createElement("canvas");
6795
+ n.width = 256, n.height = 256;
6796
+ const o = n.getContext("2d");
6797
+ if (o) {
6798
+ o.fillStyle = "#ffffff", o.fillRect(0, 0, n.width, n.height), o.fillStyle = "#000000";
6484
6799
  for (let l = 0; l < 10; l++)
6485
6800
  for (let c = 0; c < 10; c++)
6486
- (l + c) % 2 === 0 && n.fillRect(l * 25, c * 25, 25, 25);
6801
+ (l + c) % 2 === 0 && o.fillRect(l * 25, c * 25, 25, 25);
6487
6802
  }
6488
- t = K.from(o);
6803
+ t = re.from(n);
6489
6804
  }
6490
- const i = new Ot(t), r = new Bt(i, s.scale || 50);
6491
- return r.scale.x = s.scaleX || 50, r.scale.y = s.scaleY || 50, r._customParams = { ...s }, r._displacementSprite = i, r.updateUIParam = function(a, o) {
6492
- const n = this._customParams || {};
6493
- switch (this._customParams = n, n[a] = o, a) {
6805
+ const i = new ni(t), r = new ai(i, s.scale || 50);
6806
+ return r.scale.x = s.scaleX || 50, r.scale.y = s.scaleY || 50, r._customParams = { ...s }, r._displacementSprite = i, r.updateUIParam = function(a, n) {
6807
+ const o = this._customParams || {};
6808
+ switch (this._customParams = o, o[a] = n, a) {
6494
6809
  case "scaleX":
6495
- this.scale.x = o;
6810
+ this.scale.x = n;
6496
6811
  break;
6497
6812
  case "scaleY":
6498
- this.scale.y = o;
6813
+ this.scale.y = n;
6499
6814
  break;
6500
6815
  case "mapTexture":
6501
6816
  try {
6502
6817
  const l = this._displacementSprite;
6503
6818
  if (l) {
6504
- const c = K.from(o);
6819
+ const c = re.from(n);
6505
6820
  c.source.addressMode = "repeat", l.texture = c;
6506
6821
  }
6507
6822
  } catch {
6508
6823
  }
6509
6824
  break;
6510
6825
  default:
6511
- a in this ? this[a] = o : a in this.scale && (this.scale[a] = o);
6826
+ a in this ? this[a] = n : a in this.scale && (this.scale[a] = n);
6512
6827
  break;
6513
6828
  }
6514
6829
  return !0;
@@ -6634,7 +6949,7 @@ m({
6634
6949
  }
6635
6950
  ]
6636
6951
  });
6637
- const { EmbossFilter: Lt } = b;
6952
+ const { EmbossFilter: oi } = b;
6638
6953
  m({
6639
6954
  id: "emboss",
6640
6955
  name: "Emboss",
@@ -6643,7 +6958,7 @@ m({
6643
6958
  // Create an instance of the Emboss filter with the provided parameters
6644
6959
  createFilter: (s) => {
6645
6960
  try {
6646
- const e = typeof s.strength == "number" ? s.strength : 5, t = new Lt(e);
6961
+ const e = typeof s.strength == "number" ? s.strength : 5, t = new oi(e);
6647
6962
  return t._customParams = {
6648
6963
  strength: e
6649
6964
  }, t.updateUIParam = function(i, r) {
@@ -6651,8 +6966,8 @@ m({
6651
6966
  const a = this._customParams || {};
6652
6967
  switch (this._customParams = a, a[i] = r, i) {
6653
6968
  case "strength":
6654
- const o = Number(r);
6655
- a.strength = o, this.strength = o;
6969
+ const n = Number(r);
6970
+ a.strength = n, this.strength = n;
6656
6971
  break;
6657
6972
  default:
6658
6973
  i in this && (this[i] = r);
@@ -6683,7 +6998,7 @@ m({
6683
6998
  }
6684
6999
  ]
6685
7000
  });
6686
- const { GlitchFilter: Dt } = b, I = {
7001
+ const { GlitchFilter: li } = b, D = {
6687
7002
  TRANSPARENT: 0,
6688
7003
  ORIGINAL: 1,
6689
7004
  LOOP: 2,
@@ -6697,7 +7012,7 @@ m({
6697
7012
  description: "Apply digital distortion and glitch effects",
6698
7013
  createFilter: (s) => {
6699
7014
  try {
6700
- const e = { x: s.redX, y: s.redY }, t = { x: s.greenX, y: s.greenY }, i = { x: s.blueX, y: s.blueY }, r = new Dt({
7015
+ const e = { x: s.redX, y: s.redY }, t = { x: s.greenX, y: s.greenY }, i = { x: s.blueX, y: s.blueY }, r = new li({
6701
7016
  slices: s.slices,
6702
7017
  offset: s.offset,
6703
7018
  direction: s.direction,
@@ -6712,16 +7027,16 @@ m({
6712
7027
  });
6713
7028
  r.animating = s.animating || !1, r._customParams = { ...s }, typeof r.refresh == "function" && r.refresh();
6714
7029
  let a = null;
6715
- const o = () => {
6716
- r.animating && (r.seed = Math.random()), a = requestAnimationFrame(o);
7030
+ const n = () => {
7031
+ r.animating && (r.seed = Math.random()), a = requestAnimationFrame(n);
6717
7032
  };
6718
- return r.animating && (a = requestAnimationFrame(o)), r._stopAnimation = () => {
7033
+ return r.animating && (a = requestAnimationFrame(n)), r._stopAnimation = () => {
6719
7034
  a !== null && (cancelAnimationFrame(a), a = null);
6720
- }, r.updateUIParam = function(n, l) {
7035
+ }, r.updateUIParam = function(o, l) {
6721
7036
  const c = this._customParams || {};
6722
- switch (this._customParams = c, c[n] = l, n) {
7037
+ switch (this._customParams = c, c[o] = l, o) {
6723
7038
  case "animating":
6724
- this.animating = l, l && !a && (a = requestAnimationFrame(o));
7039
+ this.animating = l, l && !a && (a = requestAnimationFrame(n));
6725
7040
  break;
6726
7041
  case "slices":
6727
7042
  this.slices = Math.round(l);
@@ -6729,17 +7044,17 @@ m({
6729
7044
  case "redX":
6730
7045
  case "redY":
6731
7046
  const d = this.red;
6732
- n === "redX" ? d.x = l : d.y = l, this.red = d;
7047
+ o === "redX" ? d.x = l : d.y = l, this.red = d;
6733
7048
  break;
6734
7049
  case "greenX":
6735
7050
  case "greenY":
6736
7051
  const h = this.green;
6737
- n === "greenX" ? h.x = l : h.y = l, this.green = h;
7052
+ o === "greenX" ? h.x = l : h.y = l, this.green = h;
6738
7053
  break;
6739
7054
  case "blueX":
6740
7055
  case "blueY":
6741
- const p = this.blue;
6742
- n === "blueX" ? p.x = l : p.y = l, this.blue = p;
7056
+ const u = this.blue;
7057
+ o === "blueX" ? u.x = l : u.y = l, this.blue = u;
6743
7058
  break;
6744
7059
  case "seed":
6745
7060
  this.animating || (this.seed = l);
@@ -6760,10 +7075,10 @@ m({
6760
7075
  case "average":
6761
7076
  case "minSize":
6762
7077
  case "sampleSize":
6763
- n in this && (this[n] = l);
7078
+ o in this && (this[o] = l);
6764
7079
  break;
6765
7080
  default:
6766
- n in this && (this[n] = l);
7081
+ o in this && (this[o] = l);
6767
7082
  break;
6768
7083
  }
6769
7084
  }, r;
@@ -6775,7 +7090,7 @@ m({
6775
7090
  slices: 10,
6776
7091
  offset: 100,
6777
7092
  direction: 0,
6778
- fillMode: I.LOOP,
7093
+ fillMode: D.LOOP,
6779
7094
  // LOOP mode looks better for the demo
6780
7095
  seed: 0.5,
6781
7096
  average: !1,
@@ -6838,13 +7153,13 @@ m({
6838
7153
  label: "Fill Mode",
6839
7154
  property: "fillMode",
6840
7155
  options: [
6841
- { value: I.TRANSPARENT, label: "Transparent" },
6842
- { value: I.ORIGINAL, label: "Original" },
6843
- { value: I.LOOP, label: "Loop" },
6844
- { value: I.CLAMP, label: "Clamp" },
6845
- { value: I.MIRROR, label: "Mirror" }
7156
+ { value: D.TRANSPARENT, label: "Transparent" },
7157
+ { value: D.ORIGINAL, label: "Original" },
7158
+ { value: D.LOOP, label: "Loop" },
7159
+ { value: D.CLAMP, label: "Clamp" },
7160
+ { value: D.MIRROR, label: "Mirror" }
6846
7161
  ],
6847
- default: I.LOOP
7162
+ default: D.LOOP
6848
7163
  },
6849
7164
  {
6850
7165
  id: "seed",
@@ -6938,7 +7253,7 @@ m({
6938
7253
  }
6939
7254
  ]
6940
7255
  });
6941
- const { GlowFilter: Vt } = b;
7256
+ const { GlowFilter: ci } = b;
6942
7257
  m({
6943
7258
  id: "glow",
6944
7259
  name: "Glow",
@@ -6947,7 +7262,7 @@ m({
6947
7262
  // Create an instance of the GlowFilter with the provided parameters
6948
7263
  createFilter: (s) => {
6949
7264
  try {
6950
- const e = parseInt(s.color.replace("#", "0x"), 16), t = new Vt({
7265
+ const e = parseInt(s.color.replace("#", "0x"), 16), t = new ci({
6951
7266
  distance: s.distance || 10,
6952
7267
  outerStrength: s.outerStrength || 4,
6953
7268
  innerStrength: s.innerStrength || 0,
@@ -7073,7 +7388,7 @@ m({
7073
7388
  }
7074
7389
  ]
7075
7390
  });
7076
- const { GodrayFilter: Ut } = b;
7391
+ const { GodrayFilter: hi } = b;
7077
7392
  m({
7078
7393
  id: "godray",
7079
7394
  name: "Godray",
@@ -7082,7 +7397,7 @@ m({
7082
7397
  // Create an instance of the GodrayFilter with the provided parameters
7083
7398
  createFilter: (s) => {
7084
7399
  try {
7085
- const e = new Ut({
7400
+ const e = new hi({
7086
7401
  angle: s.angle || 30,
7087
7402
  parallel: s.parallel ?? !0,
7088
7403
  center: {
@@ -7235,7 +7550,7 @@ m({
7235
7550
  }
7236
7551
  ]
7237
7552
  });
7238
- const jt = b.SimpleLightmapFilter, ce = w.Texture;
7553
+ const di = b.SimpleLightmapFilter, Se = R.Texture;
7239
7554
  m({
7240
7555
  id: "lightmap",
7241
7556
  name: "Lightmap",
@@ -7260,14 +7575,14 @@ m({
7260
7575
  const c = a.createRadialGradient(128, 128, 10, 128, 128, 160);
7261
7576
  c.addColorStop(0, "white"), c.addColorStop(0.3, "rgba(220, 220, 220, 1)"), c.addColorStop(0.6, "rgba(150, 150, 150, 1)"), c.addColorStop(1, "black"), a.fillStyle = c, a.fillRect(0, 0, 256, 256);
7262
7577
  }
7263
- const o = ce.from(r);
7264
- let n;
7578
+ const n = Se.from(r);
7579
+ let o;
7265
7580
  try {
7266
- typeof t == "string" && t.startsWith("#") ? n = parseInt(t.replace("#", "0x"), 16) : n = 0;
7581
+ typeof t == "string" && t.startsWith("#") ? o = parseInt(t.replace("#", "0x"), 16) : o = 0;
7267
7582
  } catch {
7268
- n = 0;
7583
+ o = 0;
7269
7584
  }
7270
- const l = new jt(o, n, i);
7585
+ const l = new di(n, o, i);
7271
7586
  return l._customParams = {
7272
7587
  textureType: e,
7273
7588
  color: t,
@@ -7278,9 +7593,9 @@ m({
7278
7593
  switch (this._customParams = h, h[c] = d, c) {
7279
7594
  case "textureType":
7280
7595
  h.textureType = d;
7281
- const p = document.createElement("canvas");
7282
- p.width = 256, p.height = 256;
7283
- const f = p.getContext("2d");
7596
+ const u = document.createElement("canvas");
7597
+ u.width = 256, u.height = 256;
7598
+ const f = u.getContext("2d");
7284
7599
  if (f) {
7285
7600
  if (d === "spotlight") {
7286
7601
  f.fillStyle = "black", f.fillRect(0, 0, 256, 256);
@@ -7293,7 +7608,7 @@ m({
7293
7608
  const g = f.createRadialGradient(128, 128, 10, 128, 128, 160);
7294
7609
  g.addColorStop(0, "white"), g.addColorStop(0.3, "rgba(220, 220, 220, 1)"), g.addColorStop(0.6, "rgba(150, 150, 150, 1)"), g.addColorStop(1, "black"), f.fillStyle = g, f.fillRect(0, 0, 256, 256);
7295
7610
  }
7296
- const _ = ce.from(p);
7611
+ const _ = Se.from(u);
7297
7612
  if (this.lightMap = _, this.enabled !== void 0) {
7298
7613
  const g = this.enabled;
7299
7614
  this.enabled = !1, setTimeout(() => {
@@ -7366,7 +7681,7 @@ m({
7366
7681
  }
7367
7682
  ]
7368
7683
  });
7369
- const { NoiseFilter: qt } = w;
7684
+ const { NoiseFilter: ui } = R;
7370
7685
  m({
7371
7686
  id: "noise",
7372
7687
  name: "Noise",
@@ -7374,7 +7689,7 @@ m({
7374
7689
  description: "Add random noise to the image",
7375
7690
  createFilter: (s) => {
7376
7691
  try {
7377
- const e = new qt({
7692
+ const e = new ui({
7378
7693
  noise: s.noise || 0.5,
7379
7694
  seed: s.seed || Math.random()
7380
7695
  });
@@ -7386,8 +7701,8 @@ m({
7386
7701
  return e.animating && (t = requestAnimationFrame(i)), e._stopAnimation = () => {
7387
7702
  t !== null && (cancelAnimationFrame(t), t = null);
7388
7703
  }, e.updateUIParam = function(r, a) {
7389
- const o = this._customParams || {};
7390
- switch (this._customParams = o, o[r] = a, r) {
7704
+ const n = this._customParams || {};
7705
+ switch (this._customParams = n, n[r] = a, r) {
7391
7706
  case "animating":
7392
7707
  this.animating = a, a && !t && (t = requestAnimationFrame(i));
7393
7708
  break;
@@ -7451,7 +7766,7 @@ m({
7451
7766
  }
7452
7767
  ]
7453
7768
  });
7454
- const { OldFilmFilter: Ht } = b;
7769
+ const { OldFilmFilter: pi } = b;
7455
7770
  m({
7456
7771
  id: "old-film",
7457
7772
  name: "Old Film",
@@ -7459,7 +7774,7 @@ m({
7459
7774
  description: "Apply a vintage film effect with scratches and grain",
7460
7775
  createFilter: (s) => {
7461
7776
  try {
7462
- const e = new Ht({
7777
+ const e = new pi({
7463
7778
  sepia: s.sepia,
7464
7779
  noise: s.noise,
7465
7780
  noiseSize: s.noiseSize,
@@ -7479,8 +7794,8 @@ m({
7479
7794
  return e.animating && (t = requestAnimationFrame(i)), e._stopAnimation = () => {
7480
7795
  t !== null && (cancelAnimationFrame(t), t = null);
7481
7796
  }, e.updateUIParam = function(r, a) {
7482
- const o = this._customParams || {};
7483
- switch (this._customParams = o, o[r] = a, r) {
7797
+ const n = this._customParams || {};
7798
+ switch (this._customParams = n, n[r] = a, r) {
7484
7799
  case "animating":
7485
7800
  this.animating = a, a && !t && (t = requestAnimationFrame(i));
7486
7801
  break;
@@ -7640,7 +7955,7 @@ m({
7640
7955
  }
7641
7956
  ]
7642
7957
  });
7643
- const { OutlineFilter: $t } = b;
7958
+ const { OutlineFilter: fi } = b;
7644
7959
  m({
7645
7960
  id: "outline",
7646
7961
  name: "Outline",
@@ -7650,7 +7965,7 @@ m({
7650
7965
  try {
7651
7966
  let e = s.color;
7652
7967
  typeof e == "string" && (e = parseInt(e.replace("#", "0x"), 16));
7653
- const t = new $t({
7968
+ const t = new fi({
7654
7969
  thickness: s.thickness || 4,
7655
7970
  color: e,
7656
7971
  alpha: s.alpha || 1,
@@ -7740,7 +8055,7 @@ m({
7740
8055
  }
7741
8056
  ]
7742
8057
  });
7743
- const { PixelateFilter: Wt } = b;
8058
+ const { PixelateFilter: mi } = b;
7744
8059
  m({
7745
8060
  id: "pixelate",
7746
8061
  name: "Pixelate",
@@ -7748,7 +8063,7 @@ m({
7748
8063
  description: "Create a pixelated or mosaic effect",
7749
8064
  createFilter: (s) => {
7750
8065
  try {
7751
- const e = new Wt(
8066
+ const e = new mi(
7752
8067
  s.useUniform ? Math.max(4, s.size || 10) : [Math.max(4, s.sizeX || 10), Math.max(4, s.sizeY || 10)]
7753
8068
  );
7754
8069
  return e._customParams = { ...s }, e.updateUIParam = function(t, i) {
@@ -7831,7 +8146,7 @@ m({
7831
8146
  }
7832
8147
  ]
7833
8148
  });
7834
- const { ReflectionFilter: Zt } = b;
8149
+ const { ReflectionFilter: gi } = b;
7835
8150
  m({
7836
8151
  id: "reflection",
7837
8152
  // ID must match what the application expects
@@ -7848,7 +8163,7 @@ m({
7848
8163
  waveLength: new Float32Array([s.wavelengthStart ?? 30, s.wavelengthEnd ?? 100]),
7849
8164
  alpha: new Float32Array([s.alphaStart ?? 1, s.alphaEnd ?? 1]),
7850
8165
  time: s.time ?? 0
7851
- }, t = new Zt(e);
8166
+ }, t = new gi(e);
7852
8167
  return t._customParams = { ...s }, t.animating = s.animating ?? !1, t.updateUIParam = function(i, r) {
7853
8168
  const a = this._customParams || {};
7854
8169
  switch (this._customParams = a, a[i] = r, i) {
@@ -7999,7 +8314,7 @@ m({
7999
8314
  }
8000
8315
  ]
8001
8316
  });
8002
- const { ShockwaveFilter: Gt } = b;
8317
+ const { ShockwaveFilter: bi } = b;
8003
8318
  m({
8004
8319
  id: "shockwave",
8005
8320
  // ID must match what the application expects
@@ -8009,23 +8324,23 @@ m({
8009
8324
  // Create an instance of the ShockwaveFilter with the provided parameters
8010
8325
  createFilter: (s) => {
8011
8326
  try {
8012
- const e = s.centerX ?? 0.5, t = s.centerY ?? 0.5, i = { x: e, y: t }, r = s.amplitude ?? 30, a = s.wavelength ?? 160, o = s.speed ?? 500, n = s.brightness ?? 1, l = s.radius ?? -1, c = s.time ?? 0, d = new Gt({
8327
+ const e = s.centerX ?? 0.5, t = s.centerY ?? 0.5, i = { x: e, y: t }, r = s.amplitude ?? 30, a = s.wavelength ?? 160, n = s.speed ?? 500, o = s.brightness ?? 1, l = s.radius ?? -1, c = s.time ?? 0, d = new bi({
8013
8328
  center: i,
8014
8329
  amplitude: r,
8015
8330
  wavelength: a,
8016
- speed: o,
8017
- brightness: n,
8331
+ speed: n,
8332
+ brightness: o,
8018
8333
  radius: l,
8019
8334
  time: c
8020
8335
  });
8021
- return d._customParams = { ...s }, d.animating = s.animating ?? !1, d.updateUIParam = function(h, p) {
8336
+ return d._customParams = { ...s }, d.animating = s.animating ?? !1, d.updateUIParam = function(h, u) {
8022
8337
  const f = this._customParams || {};
8023
- switch (this._customParams = f, f[h] = p, h) {
8338
+ switch (this._customParams = f, f[h] = u, h) {
8024
8339
  case "centerX":
8025
- this.center || (this.center = { x: 0.5, y: 0.5 }), this.center.x = p;
8340
+ this.center || (this.center = { x: 0.5, y: 0.5 }), this.center.x = u;
8026
8341
  break;
8027
8342
  case "centerY":
8028
- this.center || (this.center = { x: 0.5, y: 0.5 }), this.center.y = p;
8343
+ this.center || (this.center = { x: 0.5, y: 0.5 }), this.center.y = u;
8029
8344
  break;
8030
8345
  case "amplitude":
8031
8346
  case "wavelength":
@@ -8033,13 +8348,13 @@ m({
8033
8348
  case "brightness":
8034
8349
  case "radius":
8035
8350
  case "time":
8036
- this[h] = p;
8351
+ this[h] = u;
8037
8352
  break;
8038
8353
  case "animating":
8039
- this.animating = p;
8354
+ this.animating = u;
8040
8355
  break;
8041
8356
  default:
8042
- h in this && (this[h] = p);
8357
+ h in this && (this[h] = u);
8043
8358
  break;
8044
8359
  }
8045
8360
  return !0;
@@ -8151,7 +8466,7 @@ m({
8151
8466
  }
8152
8467
  ]
8153
8468
  });
8154
- const { SimplexNoiseFilter: Kt } = b;
8469
+ const { SimplexNoiseFilter: yi } = b;
8155
8470
  m({
8156
8471
  id: "simplex-noise",
8157
8472
  name: "Simplex Noise",
@@ -8159,7 +8474,7 @@ m({
8159
8474
  description: "Apply procedural noise to create texture effects",
8160
8475
  createFilter: (s) => {
8161
8476
  try {
8162
- const e = s.animating ? 0 : s.offsetZ || 0, t = new Kt({
8477
+ const e = s.animating ? 0 : s.offsetZ || 0, t = new yi({
8163
8478
  strength: s.strength,
8164
8479
  noiseScale: s.noiseScale,
8165
8480
  offsetX: s.offsetX,
@@ -8174,20 +8489,20 @@ m({
8174
8489
  };
8175
8490
  return t.animating && (i = requestAnimationFrame(a)), t._stopAnimation = () => {
8176
8491
  i !== null && (cancelAnimationFrame(i), i = null);
8177
- }, t.updateUIParam = function(o, n) {
8492
+ }, t.updateUIParam = function(n, o) {
8178
8493
  const l = this._customParams || {};
8179
- switch (this._customParams = l, l[o] = n, o) {
8494
+ switch (this._customParams = l, l[n] = o, n) {
8180
8495
  case "animating":
8181
- this.animating = n, n && !i && (i = requestAnimationFrame(a));
8496
+ this.animating = o, o && !i && (i = requestAnimationFrame(a));
8182
8497
  break;
8183
8498
  case "animationSpeed":
8184
- this.animationSpeed = n;
8499
+ this.animationSpeed = o;
8185
8500
  break;
8186
8501
  case "offsetZ":
8187
- this.animating || (this.offsetZ = n);
8502
+ this.animating || (this.offsetZ = o);
8188
8503
  break;
8189
8504
  case "randomizeSeed":
8190
- if (n) {
8505
+ if (o) {
8191
8506
  const c = () => Math.random() * 100 - 50;
8192
8507
  this.offsetX = c(), this.offsetY = c(), this.offsetZ = c(), l.offsetX = this.offsetX, l.offsetY = this.offsetY, l.offsetZ = this.offsetZ;
8193
8508
  }
@@ -8197,10 +8512,10 @@ m({
8197
8512
  case "offsetX":
8198
8513
  case "offsetY":
8199
8514
  case "step":
8200
- o in this && (this[o] = n);
8515
+ n in this && (this[n] = o);
8201
8516
  break;
8202
8517
  default:
8203
- o in this && (this[o] = n);
8518
+ n in this && (this[n] = o);
8204
8519
  break;
8205
8520
  }
8206
8521
  }, t;
@@ -8306,110 +8621,14 @@ m({
8306
8621
  }
8307
8622
  ]
8308
8623
  });
8309
- class Qt extends w.Filter {
8310
- constructor(e) {
8311
- const t = Se.from({
8312
- vertex: `
8313
- attribute vec2 aPosition;
8314
- varying vec2 vTextureCoord;
8315
- uniform mat3 projectionMatrix;
8316
-
8317
- void main() {
8318
- vTextureCoord = aPosition;
8319
- gl_Position = vec4((projectionMatrix * vec3(aPosition, 1.0)).xy, 0.0, 1.0);
8320
- }
8321
- `,
8322
- fragment: `
8323
- precision mediump float;
8324
-
8325
- varying vec2 vTextureCoord;
8326
- uniform sampler2D uSampler;
8327
-
8328
- uniform vec2 uCenter;
8329
- uniform float uRadius;
8330
- uniform float uAngle;
8331
-
8332
- void main() {
8333
- vec2 coord = vTextureCoord;
8334
- vec2 dir = coord - uCenter;
8335
- float dist = length(dir);
8336
-
8337
- if (dist < uRadius) {
8338
- float percent = (uRadius - dist) / uRadius;
8339
- float theta = percent * percent * uAngle;
8340
- float s = sin(theta);
8341
- float c = cos(theta);
8342
-
8343
- dir = vec2(
8344
- dir.x * c - dir.y * s,
8345
- dir.x * s + dir.y * c
8346
- );
8347
-
8348
- coord = dir + uCenter;
8349
- }
8350
-
8351
- gl_FragColor = texture2D(uSampler, coord);
8352
- }
8353
- `
8354
- });
8355
- super({
8356
- glProgram: t,
8357
- resources: {
8358
- twistUniforms: {
8359
- uCenter: { type: "vec2<f32>", value: [0.5, 0.5] },
8360
- uRadius: { type: "f32", value: 0.25 },
8361
- uAngle: { type: "f32", value: 4 }
8362
- }
8363
- }
8364
- }), this._centerX = 0.5, this._centerY = 0.5, this._radius = 0.25, this._angle = 4, e && (e.centerX !== void 0 && (this._centerX = e.centerX), e.centerY !== void 0 && (this._centerY = e.centerY), e.radius !== void 0 && (this._radius = e.radius), e.angle !== void 0 && (this._angle = e.angle)), this._updateUniforms();
8365
- }
8366
- _updateUniforms() {
8367
- this.uniforms && (this.uniforms.uCenter = [this._centerX, this._centerY], this.uniforms.uRadius = this._radius, this.uniforms.uAngle = this._angle);
8368
- }
8369
- get centerX() {
8370
- return this._centerX;
8371
- }
8372
- set centerX(e) {
8373
- this._centerX = e, this._updateUniforms();
8374
- }
8375
- get centerY() {
8376
- return this._centerY;
8377
- }
8378
- set centerY(e) {
8379
- this._centerY = e, this._updateUniforms();
8380
- }
8381
- get radius() {
8382
- return this._radius;
8383
- }
8384
- set radius(e) {
8385
- this._radius = e, this._updateUniforms();
8386
- }
8387
- get angle() {
8388
- return this._angle;
8389
- }
8390
- set angle(e) {
8391
- this._angle = e, this._updateUniforms();
8392
- }
8393
- /**
8394
- * Handle UI parameter updates
8395
- */
8396
- updateUIParam(e, t) {
8397
- switch (e) {
8398
- case "centerX":
8399
- this.centerX = t;
8400
- break;
8401
- case "centerY":
8402
- this.centerY = t;
8403
- break;
8404
- case "radius":
8405
- this.radius = t;
8406
- break;
8407
- case "angle":
8408
- this.angle = t;
8409
- break;
8410
- }
8411
- }
8412
- }
8624
+ const { TwistFilter: _i } = b, Xe = (s) => Math.ceil(Math.max(0, Number(s) || 0) + 2), ve = (s, e = 1) => {
8625
+ const t = Math.max(1, Number(s._sourceWidth ?? 0)), i = Math.max(1, Number(s._sourceHeight ?? 0)), r = Math.min(t, i), a = Number(s.centerX ?? 0.5), n = Number(s.centerY ?? 0.5), o = Number(s.radius ?? 0.25), l = Number(s.angle ?? 4), c = a * t * e, d = n * i * e, h = o * r * e, u = new _i({
8626
+ offset: { x: c, y: d },
8627
+ radius: h,
8628
+ angle: l
8629
+ }), f = Xe(h);
8630
+ return u.padding = Math.max(u.padding ?? 0, f), u._exportPadding = f, u;
8631
+ };
8413
8632
  m({
8414
8633
  id: "twist",
8415
8634
  name: "Twist",
@@ -8417,29 +8636,38 @@ m({
8417
8636
  description: "Creates a twisting distortion effect around a central point",
8418
8637
  createFilter: (s) => {
8419
8638
  try {
8420
- const e = new Qt({
8639
+ const e = {
8421
8640
  centerX: s.centerX ?? 0.5,
8422
8641
  centerY: s.centerY ?? 0.5,
8423
8642
  radius: s.radius ?? 0.25,
8424
- angle: s.angle ?? 4
8425
- });
8426
- return e._customParams = { ...s }, e;
8643
+ angle: s.angle ?? 4,
8644
+ _sourceWidth: s._sourceWidth,
8645
+ _sourceHeight: s._sourceHeight
8646
+ }, t = ve(e, 1);
8647
+ return t._customParams = { ...e }, t.updateUIParam = function(i, r) {
8648
+ const a = this._customParams || {};
8649
+ this._customParams = a, a[i] = r;
8650
+ const n = Math.max(1, Number(a._sourceWidth ?? 0)), o = Math.max(1, Number(a._sourceHeight ?? 0)), l = Math.min(n, o), c = Number(a.centerX ?? 0.5), d = Number(a.centerY ?? 0.5), h = Number(a.radius ?? 0.25), u = Number(a.angle ?? 4);
8651
+ this.offset && (this.offset.x = c * n, this.offset.y = d * o), this.radius = h * l, this.angle = u;
8652
+ const f = Xe(this.radius);
8653
+ return this._exportPadding = f, this.padding = Math.max(this.padding ?? 0, f), !0;
8654
+ }, t.createExportFilter = function(i = {}) {
8655
+ const r = Number.isFinite(i.previewToNativeScale) ? Math.max(1, Number(i.previewToNativeScale)) : 1, a = this._customParams || e;
8656
+ return ve(a, r);
8657
+ }, t.getExportPadding = function() {
8658
+ return Number(this._exportPadding || this.padding || 0);
8659
+ }, t;
8427
8660
  } catch {
8428
8661
  return null;
8429
8662
  }
8430
8663
  },
8431
- // Default parameter values - all normalized (0-1) for intuitive slider use
8664
+ // Default parameter values normalized (0-1) for intuitive slider use.
8432
8665
  defaultParams: {
8433
8666
  centerX: 0.5,
8434
- // Center of image
8435
8667
  centerY: 0.5,
8436
- // Center of image
8437
8668
  radius: 0.25,
8438
- // 25% of image size
8439
8669
  angle: 4
8440
- // Twist amount in radians
8441
8670
  },
8442
- // UI controls for the filter
8443
8671
  controls: [
8444
8672
  {
8445
8673
  id: "angle",
@@ -8461,7 +8689,7 @@ m({
8461
8689
  max: 0.75,
8462
8690
  step: 0.01,
8463
8691
  default: 0.25,
8464
- tooltip: "Size of the twist effect (0-1, relative to image)"
8692
+ tooltip: "Size of the twist effect (relative to image)"
8465
8693
  },
8466
8694
  {
8467
8695
  id: "centerX",
@@ -8487,8 +8715,8 @@ m({
8487
8715
  }
8488
8716
  ]
8489
8717
  });
8490
- const { AdjustmentFilter: Jt } = b;
8491
- function q(s) {
8718
+ const { AdjustmentFilter: xi } = b;
8719
+ function K(s) {
8492
8720
  const e = typeof s == "string" ? parseInt(s.replace("#", "0x"), 16) : s;
8493
8721
  return [
8494
8722
  (e >> 16 & 255) / 255,
@@ -8496,14 +8724,14 @@ function q(s) {
8496
8724
  (e & 255) / 255
8497
8725
  ];
8498
8726
  }
8499
- class ei extends Jt {
8727
+ class Ci extends xi {
8500
8728
  constructor(e = {}) {
8501
8729
  super({
8502
8730
  brightness: 1,
8503
8731
  contrast: 1,
8504
8732
  saturation: 1,
8505
8733
  alpha: 1
8506
- }), this._radius = 0.8, this._strength = 1, this._colorRgb = [0, 0, 0], this._colorValue = "#000000", this._radius = e.radius ?? 0.8, this._strength = e.strength ?? 1, e.color !== void 0 && (typeof e.color == "string" ? (this._colorValue = e.color, this._colorRgb = q(e.color)) : (this._colorValue = "#" + e.color.toString(16).padStart(6, "0"), this._colorRgb = q(e.color))), this.updateVignette();
8734
+ }), this._radius = 0.8, this._strength = 1, this._colorRgb = [0, 0, 0], this._colorValue = "#000000", this._radius = e.radius ?? 0.8, this._strength = e.strength ?? 1, e.color !== void 0 && (typeof e.color == "string" ? (this._colorValue = e.color, this._colorRgb = K(e.color)) : (this._colorValue = "#" + e.color.toString(16).padStart(6, "0"), this._colorRgb = K(e.color))), this.updateVignette();
8507
8735
  }
8508
8736
  /**
8509
8737
  * Updates the filter parameters to simulate a vignette effect
@@ -8529,7 +8757,7 @@ class ei extends Jt {
8529
8757
  return this._colorValue;
8530
8758
  }
8531
8759
  set color(e) {
8532
- typeof e == "string" ? (this._colorValue = e, this._colorRgb = q(e)) : (this._colorValue = "#" + e.toString(16).padStart(6, "0"), this._colorRgb = q(e)), this.updateVignette();
8760
+ typeof e == "string" ? (this._colorValue = e, this._colorRgb = K(e)) : (this._colorValue = "#" + e.toString(16).padStart(6, "0"), this._colorRgb = K(e)), this.updateVignette();
8533
8761
  }
8534
8762
  }
8535
8763
  m({
@@ -8539,7 +8767,7 @@ m({
8539
8767
  description: "Add a classic darkened border effect to the image",
8540
8768
  createFilter: (s) => {
8541
8769
  try {
8542
- const e = new ei({
8770
+ const e = new Ci({
8543
8771
  radius: s.radius || 0.8,
8544
8772
  strength: s.strength || 1,
8545
8773
  color: s.color || "#000000"
@@ -8603,22 +8831,22 @@ m({
8603
8831
  }
8604
8832
  ]
8605
8833
  });
8606
- function oi(s) {
8834
+ function Pi(s) {
8607
8835
  try {
8608
8836
  let e = [], t = [];
8609
8837
  try {
8610
- e = H(), e.length === 0 && ot();
8838
+ e = Q(), e.length === 0 && kt();
8611
8839
  } catch {
8612
8840
  }
8613
8841
  const i = s == null ? void 0 : s.disabled;
8614
8842
  if (Array.isArray(i) && i.length > 0) {
8615
8843
  let r = 0;
8616
8844
  for (const a of i)
8617
- ct(a) && r++;
8845
+ zt(a) && r++;
8618
8846
  r > 0;
8619
8847
  }
8620
8848
  try {
8621
- e = H(), t = lt();
8849
+ e = Q(), t = At();
8622
8850
  } catch {
8623
8851
  e || (e = []), t || (t = []);
8624
8852
  }
@@ -8628,16 +8856,38 @@ function oi(s) {
8628
8856
  }
8629
8857
  }
8630
8858
  export {
8631
- ri as V,
8632
- at as a,
8633
- nt as b,
8634
- lt as c,
8635
- ot as d,
8636
- ai as e,
8637
- ht as f,
8638
- H as g,
8639
- si as h,
8640
- oi as i,
8641
- m as r
8859
+ ae as C,
8860
+ le as E,
8861
+ ut as F,
8862
+ He as P,
8863
+ pt as R,
8864
+ ft as T,
8865
+ Si as V,
8866
+ Pt as a,
8867
+ Ft as b,
8868
+ At as c,
8869
+ se as d,
8870
+ p as e,
8871
+ Pe as f,
8872
+ Q as g,
8873
+ vi as h,
8874
+ Pi as i,
8875
+ O as j,
8876
+ Re as k,
8877
+ Te as l,
8878
+ Ne as m,
8879
+ ze as n,
8880
+ Ae as o,
8881
+ oe as p,
8882
+ Me as q,
8883
+ m as r,
8884
+ W as s,
8885
+ vt as t,
8886
+ qe as u,
8887
+ wt as v,
8888
+ ht as w,
8889
+ kt as x,
8890
+ Mi as y,
8891
+ Nt as z
8642
8892
  };
8643
- //# sourceMappingURL=editor-2Q72CZjK.js.map
8893
+ //# sourceMappingURL=editor-CYj5y5bp.js.map