@codingfactory/mediables-vue 2.3.6 → 2.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (30) hide show
  1. package/dist/{PixiFrameExporter-DM4yaigy.cjs → PixiFrameExporter-8_WF3thr.cjs} +2 -2
  2. package/dist/{PixiFrameExporter-DM4yaigy.cjs.map → PixiFrameExporter-8_WF3thr.cjs.map} +1 -1
  3. package/dist/{PixiFrameExporter-BAZtrvGS.js → PixiFrameExporter-vXYgP3wU.js} +2 -2
  4. package/dist/{PixiFrameExporter-BAZtrvGS.js.map → PixiFrameExporter-vXYgP3wU.js.map} +1 -1
  5. package/dist/components/ImageEditorModal.vue.d.ts +4 -2
  6. package/dist/composables/useImageEditorModal.d.ts +288 -16
  7. package/dist/composables/useRadialMenu.d.ts +1 -1
  8. package/dist/editor-Bl0mzqgX.cjs +42 -0
  9. package/dist/editor-Bl0mzqgX.cjs.map +1 -0
  10. package/dist/{editor-BWpslm--.js → editor-DiiyShiW.js} +419 -303
  11. package/dist/editor-DiiyShiW.js.map +1 -0
  12. package/dist/{index-CMOpozRS.js → index-B42SSGjg.js} +7717 -7554
  13. package/dist/index-B42SSGjg.js.map +1 -0
  14. package/dist/index-CT0VqMgf.cjs +342 -0
  15. package/dist/index-CT0VqMgf.cjs.map +1 -0
  16. package/dist/index.d.ts +3 -0
  17. package/dist/mediables-vanilla.cjs +1 -1
  18. package/dist/mediables-vanilla.mjs +1 -1
  19. package/dist/mediables-vue.cjs +1 -1
  20. package/dist/mediables-vue.mjs +59 -52
  21. package/dist/style.css +1 -1
  22. package/dist/types/editor.d.ts +87 -2
  23. package/dist/utils/imageEditorState.d.ts +26 -0
  24. package/package.json +1 -1
  25. package/dist/editor-BWpslm--.js.map +0 -1
  26. package/dist/editor-D_dX1XkE.cjs +0 -42
  27. package/dist/editor-D_dX1XkE.cjs.map +0 -1
  28. package/dist/index-6-ArBBEQ.cjs +0 -342
  29. package/dist/index-6-ArBBEQ.cjs.map +0 -1
  30. package/dist/index-CMOpozRS.js.map +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"file":"editor-BWpslm--.js","sources":["../resources/js/vanilla-editor/core/EventEmitter.js","../resources/js/vanilla-editor/core/State.js","../resources/js/vanilla-editor/renderer/PixiRenderer.js","../resources/js/vanilla-editor/renderer/FilterManager.js","../resources/js/vanilla-editor/renderer/CropManager.js","../resources/js/vanilla-editor/renderer/RemoveBgManager.js","../resources/js/vanilla-editor/ui/UIBuilder.js","../resources/js/vanilla-editor/icons/icons.js","../resources/js/vanilla-editor/ui/Toolbar.js","../resources/js/vanilla-editor/ui/CategoryCarousel.js","../resources/js/vanilla-editor/ui/FilterCarousel.js","../resources/js/vanilla-editor/ui/FilterAdjustments.js","../resources/js/vanilla-editor/ui/MobileFilterDrawer.js","../resources/js/vanilla-editor/ui/MobileActiveFilters.js","../resources/js/vanilla-editor/ui/CropControls.js","../resources/js/vanilla-editor/ui/ActiveFiltersPanel.js","../resources/js/vanilla-editor/presets/index.js","../resources/js/vanilla-editor/VanillaImageEditor.js","../resources/js/filters/registry.ts","../resources/js/filters/definitions/adjustment.ts","../resources/js/filters/definitions/adjustmentAdvanced.ts","../resources/js/filters/definitions/alpha.ts","../resources/js/filters/definitions/blur.ts","../resources/js/filters/definitions/colorMatrix.ts","../resources/js/filters/definitions/colorOverlay.ts","../resources/js/filters/definitions/dropShadow.ts","../resources/js/filters/definitions/grayscale.ts","../resources/js/filters/definitions/hslAdjustment.ts","../resources/js/filters/definitions/kawaseBlur.ts","../resources/js/filters/definitions/motionBlur.ts","../resources/js/filters/definitions/radialBlur.ts","../resources/js/filters/definitions/tiltShift.ts","../resources/js/filters/definitions/zoomBlur.ts","../resources/js/filters/definitions/colorGradient.ts","../resources/js/filters/definitions/colorMap.ts","../resources/js/filters/definitions/colorReplace.ts","../resources/js/filters/definitions/multiColorReplace.ts","../resources/js/filters/definitions/rgbSplit.ts","../resources/js/filters/definitions/advancedBloom.ts","../resources/js/filters/definitions/ascii.ts","../resources/js/filters/definitions/backdropBlur.ts","../resources/js/filters/definitions/bevel.ts","../resources/js/filters/definitions/bloom.ts","../resources/js/filters/definitions/bulgePinch.ts","../resources/js/filters/definitions/convolution.ts","../resources/js/filters/definitions/crossHatch.ts","../resources/js/filters/definitions/crt.ts","../resources/js/filters/definitions/displacement.ts","../resources/js/filters/definitions/dot.ts","../resources/js/filters/definitions/emboss.ts","../resources/js/filters/definitions/glitch.ts","../resources/js/filters/definitions/glow.ts","../resources/js/filters/definitions/godray.ts","../resources/js/filters/definitions/lightmap.ts","../resources/js/filters/definitions/noise.ts","../resources/js/filters/definitions/oldFilm.ts","../resources/js/filters/definitions/outline.ts","../resources/js/filters/definitions/pixelate.ts","../resources/js/filters/definitions/reflection.ts","../resources/js/filters/definitions/shockwave.ts","../resources/js/filters/definitions/simplexNoise.ts","../resources/js/filters/definitions/twist.ts","../resources/js/filters/definitions/vignette.ts","../resources/js/filters/index.ts"],"sourcesContent":["/**\n * Simple EventEmitter for vanilla JS\n * Provides pub/sub functionality without external dependencies\n */\nexport class EventEmitter {\n constructor() {\n this._events = new Map()\n }\n\n on(event, callback) {\n if (!this._events.has(event)) {\n this._events.set(event, new Set())\n }\n this._events.get(event).add(callback)\n return () => this.off(event, callback)\n }\n\n off(event, callback) {\n const listeners = this._events.get(event)\n if (listeners) {\n listeners.delete(callback)\n }\n }\n\n emit(event, ...args) {\n const listeners = this._events.get(event)\n if (listeners) {\n listeners.forEach(callback => {\n try {\n callback(...args)\n } catch (e) {\n console.error(`Error in event listener for ${event}:`, e)\n }\n })\n }\n }\n\n once(event, callback) {\n const wrapper = (...args) => {\n this.off(event, wrapper)\n callback(...args)\n }\n return this.on(event, wrapper)\n }\n\n removeAllListeners(event) {\n if (event) {\n this._events.delete(event)\n } else {\n this._events.clear()\n }\n }\n}\n","/**\n * Central state management for the vanilla image editor\n * Replaces Vue's reactivity system with a simple observable pattern\n */\nimport { EventEmitter } from './EventEmitter.js'\n\nexport class State extends EventEmitter {\n constructor() {\n super()\n this._state = {\n // Image state\n hasImage: false,\n imageUrl: null,\n\n // Mode state\n mode: 'filters', // 'filters' | 'crop'\n\n // View state\n zoom: 1,\n fitScale: 1,\n\n // Filter state\n activeFilters: new Set(),\n filterValues: {},\n selectedFilter: null,\n selectedCategory: 'adjust',\n\n // Crop state\n crop: {\n shape: 'free', // 'free' | 'square' | 'circle'\n aspect: 'free', // 'free' | '1:1' | '4:3' | '16:9' | '3:2' | '2:3'\n rect: null // { x, y, width, height }\n },\n\n // UI state\n theme: 'auto', // 'light' | 'dark' | 'auto'\n isDarkMode: false,\n isSaving: false\n }\n }\n\n /**\n * Get a state value\n * @param {string} key - State key (supports dot notation: 'crop.shape')\n * @returns {*} The state value\n */\n get(key) {\n if (key.includes('.')) {\n const parts = key.split('.')\n let value = this._state\n for (const part of parts) {\n if (value === undefined || value === null) return undefined\n value = value[part]\n }\n return value\n }\n return this._state[key]\n }\n\n /**\n * Set a state value and emit change event\n * @param {string} key - State key (supports dot notation: 'crop.shape')\n * @param {*} value - New value\n */\n set(key, value) {\n const old = this.get(key)\n\n if (key.includes('.')) {\n const parts = key.split('.')\n const lastKey = parts.pop()\n let target = this._state\n for (const part of parts) {\n if (target[part] === undefined) target[part] = {}\n target = target[part]\n }\n target[lastKey] = value\n } else {\n this._state[key] = value\n }\n\n this.emit(`change:${key}`, { value, old })\n this.emit('change', { key, value, old })\n }\n\n /**\n * Get the entire state object (for debugging)\n */\n getAll() {\n return { ...this._state }\n }\n\n /**\n * Toggle a filter in the active filters set\n * @param {string} filterId\n * @param {boolean} enabled\n */\n toggleFilter(filterId, enabled) {\n const filters = new Set(this._state.activeFilters)\n if (enabled) {\n filters.add(filterId)\n } else {\n filters.delete(filterId)\n delete this._state.filterValues[filterId]\n }\n this.set('activeFilters', filters)\n }\n\n /**\n * Update a filter's control value\n * @param {string} filterId\n * @param {string} controlId\n * @param {*} value\n */\n setFilterValue(filterId, controlId, value) {\n if (!this._state.filterValues[filterId]) {\n this._state.filterValues[filterId] = {}\n }\n this._state.filterValues[filterId][controlId] = value\n this.emit('change:filterValue', { filterId, controlId, value })\n this.emit('change:filterValues', this._state.filterValues)\n }\n\n /**\n * Get a filter's control values\n * @param {string} filterId\n * @returns {Object} Filter values\n */\n getFilterValues(filterId) {\n return this._state.filterValues[filterId] || {}\n }\n\n /**\n * Initialize filter values from definition defaults\n * @param {string} filterId\n * @param {Array} controls - Control definitions with defaults\n */\n initFilterValues(filterId, controls) {\n if (!this._state.filterValues[filterId]) {\n this._state.filterValues[filterId] = {}\n }\n controls.forEach(ctl => {\n if (!(ctl.id in this._state.filterValues[filterId])) {\n this._state.filterValues[filterId][ctl.id] = ctl.default\n }\n })\n this.emit('change:filterValues', this._state.filterValues)\n }\n\n /**\n * Reset all filters\n */\n resetFilters() {\n this._state.activeFilters = new Set()\n this._state.filterValues = {}\n this._state.selectedFilter = null\n this.emit('change:activeFilters', { value: this._state.activeFilters })\n this.emit('change:filterValues', this._state.filterValues)\n this.emit('change:selectedFilter', { value: null })\n this.emit('filtersReset')\n }\n\n /**\n * Detect and set dark mode based on preference\n */\n detectTheme() {\n if (this._state.theme === 'auto') {\n const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches\n this.set('isDarkMode', prefersDark)\n } else {\n this.set('isDarkMode', this._state.theme === 'dark')\n }\n }\n}\n\n// Singleton instance\nlet instance = null\n\nexport function getState() {\n if (!instance) {\n instance = new State()\n }\n return instance\n}\n\nexport function createState() {\n return new State()\n}\n","/**\n * PIXI.js v8 Renderer for the vanilla image editor\n * Handles canvas lifecycle, image loading, zoom, and export\n */\nimport { EventEmitter } from '../core/EventEmitter.js'\n\nexport class PixiRenderer extends EventEmitter {\n constructor() {\n super()\n this.app = null\n this.sprite = null\n this.originalTexture = null\n this.baseTexture = null\n this.fitScale = 1\n this.zoom = 1\n this._container = null\n /** @type {Promise<void>|null} Resolves when mount() finishes */\n this._mountPromise = null\n }\n\n /**\n * Whether the renderer is fully initialized and ready for use.\n * @returns {boolean}\n */\n get isReady() {\n return !!(this.app?.renderer)\n }\n\n /**\n * Get CSS size of the canvas (for proper coordinate mapping).\n * Accesses renderer.canvas directly to avoid PIXI Application's\n * canvas getter which throws when renderer is undefined.\n */\n _getCssSize() {\n const canvas = this.app?.renderer?.canvas\n const w = canvas?.clientWidth ?? this.app?.screen?.width ?? 0\n const h = canvas?.clientHeight ?? this.app?.screen?.height ?? 0\n return { w, h }\n }\n\n /**\n * Force render the stage\n */\n render() {\n try {\n if (this.app?.renderer && this.app?.stage) {\n this.app.renderer.render(this.app.stage)\n }\n } catch (e) {\n console.warn('[PixiRenderer] render error:', e)\n }\n }\n\n /**\n * Calculate fit scale for a texture\n * @param {PIXI.Texture} tex\n * @returns {number}\n */\n getFitScaleFor(tex) {\n if (!this.app || !tex) return 1\n const { w, h } = this._getCssSize()\n if (w <= 1 || h <= 1) return 1\n let scale = Math.min(w / tex.width, h / tex.height) * 0.9\n if (!Number.isFinite(scale) || scale <= 0) scale = 1\n return scale\n }\n\n /**\n * Apply view transform (position and scale) to sprite\n */\n applyViewTransform(opts = {}) {\n if (!this.app || !this.sprite || !this.originalTexture) return\n\n const s = this.fitScale * this.zoom\n const { w, h } = this._getCssSize()\n\n const desired = opts.keepCenter\n ? { x: this.sprite.x + this.sprite.width / 2, y: this.sprite.y + this.sprite.height / 2 }\n : (opts.center ?? { x: w / 2, y: h / 2 })\n\n this.sprite.width = this.originalTexture.width * s\n this.sprite.height = this.originalTexture.height * s\n this.sprite.x = desired.x - this.sprite.width / 2\n this.sprite.y = desired.y - this.sprite.height / 2\n\n this.render()\n }\n\n /**\n * Set zoom level\n * @param {number} z - Zoom level (0.1 to 8)\n * @param {Object} opts - Options\n */\n setZoom(z, opts = {}) {\n this.zoom = Math.max(0.1, Math.min(8, z))\n this.applyViewTransform({ keepCenter: opts.keepCenter ?? true })\n this.emit('zoomChange', this.zoom)\n }\n\n /**\n * Fit image to screen\n */\n fitToScreen() {\n if (this.originalTexture) {\n this.fitScale = this.getFitScaleFor(this.originalTexture)\n this.setZoom(1, { keepCenter: false })\n }\n }\n\n /**\n * Mount PIXI application to container\n * @param {HTMLElement} container\n * @param {number} backgroundColor\n */\n async mount(container, backgroundColor = 0xffffff) {\n if (!container) return\n this._container = container\n\n const doMount = async () => {\n const PIXI = window.PIXI\n if (!PIXI) {\n throw new Error('PIXI.js not found. Please ensure PIXI is loaded globally.')\n }\n\n // Enable CORS for cross-origin image loading (e.g. S3 presigned URLs)\n if (PIXI.Assets?.setPreferences) {\n PIXI.Assets.setPreferences({ crossOrigin: 'anonymous' })\n }\n\n const width = container.clientWidth || 600\n const height = container.clientHeight || 400\n\n this.app = new PIXI.Application()\n await this.app.init({\n width,\n height,\n backgroundColor,\n antialias: true,\n autoDensity: true,\n resolution: window.devicePixelRatio || 1\n })\n\n container.appendChild(this.app.canvas)\n\n // Style the canvas\n const canvas = this.app.canvas\n canvas.classList.add('pixi-canvas')\n canvas.style.width = '100%'\n canvas.style.height = '100%'\n canvas.style.transform = 'translateZ(0)'\n canvas.style.willChange = 'transform'\n\n // Accessibility: label the canvas for screen readers\n canvas.setAttribute('role', 'img')\n canvas.setAttribute('aria-label', 'Image editor canvas — use toolbar controls to edit the image')\n\n this.emit('mounted', { width, height })\n }\n\n this._mountPromise = doMount()\n await this._mountPromise\n }\n\n /**\n * Load an image texture\n * @param {string} imageUrl - URL, data URL, or blob URL of the image\n */\n async loadTexture(imageUrl) {\n // Wait for mount() to finish if it's still in progress\n if (this._mountPromise) {\n await this._mountPromise\n }\n\n if (!this.app?.renderer) return\n\n const PIXI = window.PIXI\n\n // Load image via HTMLImageElement then create texture directly.\n // Bypasses PIXI.Assets.load() which can't handle blob: or data: URLs.\n const img = await this._loadImageElement(imageUrl)\n if (!img) {\n console.error('[PixiRenderer.loadTexture] Failed to load image from', imageUrl)\n return\n }\n\n // Re-check after async — renderer may have been destroyed\n if (!this.app?.renderer) return\n\n const tex = PIXI.Texture.from(img)\n\n if (!tex) {\n console.error('[PixiRenderer.loadTexture] Failed to create texture from image')\n return\n }\n\n this.originalTexture = tex\n this.baseTexture = tex\n\n // Remove old sprite\n if (this.sprite) {\n this.app.stage.removeChild(this.sprite)\n this.sprite.destroy()\n }\n\n // Create new sprite\n this.sprite = new PIXI.Sprite(tex)\n this.app.stage.addChild(this.sprite)\n\n // Calculate fit scale and apply\n this.fitScale = this.getFitScaleFor(tex)\n this.zoom = 1\n\n const { w, h } = this._getCssSize()\n this.applyViewTransform({ center: { x: w / 2, y: h / 2 } })\n\n // Re-fit after a frame to handle layout settling\n await new Promise(requestAnimationFrame)\n\n // Re-check after async — renderer may have been destroyed during frame\n if (!this.app?.renderer) return\n\n const settledScale = this.getFitScaleFor(tex)\n if (Math.abs(settledScale - this.fitScale) / Math.max(1e-6, settledScale) > 0.02) {\n this.fitScale = settledScale\n this.applyViewTransform({ center: { x: w / 2, y: h / 2 } })\n }\n\n this.render()\n this.emit('textureLoaded', { width: tex.width, height: tex.height })\n }\n\n /**\n * Export the current image with filters applied\n * @param {string} format - 'png' or 'jpeg'\n * @param {number} quality - Quality for jpeg (0-1)\n * @param {number} maxEdge - Maximum edge size (0 for original)\n * @param {boolean} dontUpscale - Don't upscale smaller images\n * @returns {string|null} Data URL\n */\n exportImage(format = 'png', quality = 0.92, maxEdge = 0, dontUpscale = true) {\n if (!this.app?.renderer || !this.originalTexture || !this.sprite) {\n console.error('[PixiRenderer.exportImage] Missing app/renderer, texture, or sprite', {\n hasApp: !!this.app,\n hasRenderer: !!this.app?.renderer,\n hasTexture: !!this.originalTexture,\n hasSprite: !!this.sprite\n })\n return null\n }\n\n const PIXI = window.PIXI\n const srcW = Math.round(this.originalTexture.width)\n const srcH = Math.round(this.originalTexture.height)\n\n if (srcW <= 0 || srcH <= 0) {\n console.error('[PixiRenderer.exportImage] Invalid texture dimensions', { srcW, srcH })\n return null\n }\n\n let targetW = srcW\n let targetH = srcH\n\n if (maxEdge > 0) {\n const edge = Math.max(srcW, srcH)\n let s = maxEdge / edge\n if (dontUpscale) s = Math.min(1, s)\n targetW = Math.round(srcW * s)\n targetH = Math.round(srcH * s)\n }\n\n // FILTER PARITY: Keep the sprite at its current on-screen scale so that\n // resolution-dependent filters (CRT scanlines, twist radius, vignette,\n // etc.) produce identical results in the export. We use the RenderTexture's\n // `resolution` multiplier to get full-pixel-count output while the filter\n // pipeline sees the same logical dimensions as the preview.\n //\n // Also keep the sprite ON THE STAGE — reparenting to a temp Container\n // breaks pixi-filters' custom shader GPU context.\n const sprite = this.sprite\n const origX = sprite.x\n const origY = sprite.y\n\n // The sprite's current on-screen size (fitScale * zoom applied)\n const previewW = sprite.width\n const previewH = sprite.height\n\n if (previewW <= 0 || previewH <= 0) {\n console.error('[PixiRenderer.exportImage] Sprite has zero dimensions')\n return null\n }\n\n // Resolution multiplier: filter sees previewW×previewH logical pixels,\n // but the RenderTexture outputs targetW×targetH actual pixels.\n const resMultiplier = targetW / previewW\n\n let rt = null\n try {\n // Move sprite to origin — DON'T change scale (filter parity)\n sprite.x = 0\n sprite.y = 0\n\n rt = PIXI.RenderTexture.create({\n width: Math.ceil(previewW),\n height: Math.ceil(previewH),\n resolution: resMultiplier\n })\n // Render the stage directly — preserves the exact filter pipeline\n // context that was working during on-screen rendering\n this.app.renderer.render({ container: this.app.stage, target: rt })\n\n if (!this.app.renderer.extract) {\n console.error('[PixiRenderer.exportImage] Extract system not available')\n return null\n }\n\n const canvas = this.app.renderer.extract.canvas(rt)\n\n if (!canvas) {\n console.error('[PixiRenderer.exportImage] extract.canvas() returned null')\n return null\n }\n\n // HTMLCanvasElement has toDataURL; OffscreenCanvas does not\n let dataUrl = null\n if (typeof canvas.toDataURL === 'function') {\n dataUrl = canvas.toDataURL(`image/${format}`, quality)\n } else if (typeof canvas.getContext === 'function') {\n // Fallback: draw onto a standard HTMLCanvasElement\n const fallback = document.createElement('canvas')\n fallback.width = canvas.width\n fallback.height = canvas.height\n const ctx = fallback.getContext('2d')\n if (ctx) {\n ctx.drawImage(canvas, 0, 0)\n dataUrl = fallback.toDataURL(`image/${format}`, quality)\n }\n }\n\n return dataUrl || null\n } catch (e) {\n console.error('[PixiRenderer.exportImage] Export failed:', e)\n return null\n } finally {\n // Restore sprite position (scale was never changed)\n sprite.x = origX\n sprite.y = origY\n\n if (rt) rt.destroy(true)\n }\n }\n\n /**\n * Resize renderer to container\n * @param {HTMLElement} container\n */\n resizeTo(container) {\n if (!this.app?.renderer || !container) return\n\n const w = container.clientWidth\n const h = container.clientHeight\n\n // Skip if dimensions haven't changed (prevents ResizeObserver loop)\n if (w === Math.round(this.app.screen.width) && h === Math.round(this.app.screen.height)) return\n // Skip zero-size containers (modal not yet laid out)\n if (w <= 0 || h <= 0) return\n\n this.app.renderer.resize(w, h)\n\n if (this.originalTexture && this.sprite) {\n const prevCenter = {\n x: this.sprite.x + this.sprite.width / 2,\n y: this.sprite.y + this.sprite.height / 2\n }\n this.fitScale = this.getFitScaleFor(this.originalTexture)\n this.applyViewTransform({ center: prevCenter })\n }\n }\n\n /**\n * Set background color\n * @param {number} color - Hex color\n */\n setBackgroundColor(color) {\n if (this.app?.renderer?.background) {\n this.app.renderer.background.color = color\n }\n }\n\n /**\n * Load an image URL into an HTMLImageElement.\n * Handles blob:, data:, and http(s): URLs.\n * @param {string} url\n * @returns {Promise<HTMLImageElement|null>}\n */\n _loadImageElement(url) {\n return new Promise((resolve) => {\n const img = new Image()\n // Set crossOrigin for http(s) URLs to avoid tainted canvas on export\n if (typeof url === 'string' && /^https?:\\/\\//.test(url)) {\n img.crossOrigin = 'anonymous'\n }\n img.onload = () => resolve(img)\n img.onerror = () => {\n console.error('[PixiRenderer] Image load failed:', url?.substring(0, 100))\n resolve(null)\n }\n img.src = url\n })\n }\n\n /**\n * Clean up and destroy\n */\n destroy() {\n this._mountPromise = null\n if (this.app) {\n try {\n this.app.destroy(true, { children: true, texture: true })\n } catch (_e) {\n // PIXI may throw if textures were already released during export.\n // Safe to ignore — we're destroying the renderer anyway.\n }\n this.app = null\n }\n this.sprite = null\n this.originalTexture = null\n this.baseTexture = null\n this._container = null\n this.removeAllListeners()\n }\n}\n","/**\n * Filter Manager for the vanilla image editor\n * Manages filter creation, application, and state\n */\nimport { EventEmitter } from '../core/EventEmitter.js'\n\n// Category mapping from UI categories to filter registry categories\n// These match the actual categories used in filter definitions\nconst REGISTRY_CATEGORY_MAP = {\n 'adjust': ['adjust', 'advanced'], // adjustment, adjustmentAdvanced, alpha, colorMatrix\n 'blur': ['blur'], // blur, kawaseBlur, motionBlur, radialBlur, etc.\n 'color': ['color'], // colorOverlay, grayscale, hslAdjustment, etc.\n 'effects': ['effects'], // noise, vignette, pixelate, dropShadow, etc.\n 'distortion': ['distortion'], // twist, bulgePinch, displacement, etc.\n 'light': ['light'], // bloom, glow, godray, advancedBloom\n 'stylize': ['stylize'] // ascii, crt, crossHatch, dot, emboss\n}\n\nexport class FilterManager extends EventEmitter {\n constructor(state, pixiRenderer) {\n super()\n this.state = state\n this.renderer = pixiRenderer\n this.instances = {} // Filter instances by ID\n this._filterRegistry = null\n }\n\n /**\n * Set the filter registry (from mediables/filters)\n * @param {Object} registry - { getFilter, getAllFilters, getFiltersByCategory }\n */\n setRegistry(registry) {\n this._filterRegistry = registry\n }\n\n /**\n * Get filter definition by ID\n * @param {string} filterId\n * @returns {Object|null}\n */\n getFilterDef(filterId) {\n if (!this._filterRegistry) {\n console.warn('[FilterManager] No filter registry set')\n return null\n }\n return this._filterRegistry.getFilter(filterId)\n }\n\n /**\n * Get all filters\n * @returns {Array}\n */\n getAllFilters() {\n return this._filterRegistry?.getAllFilters() || []\n }\n\n /**\n * Get filters by category\n * Maps UI category names to registry category names\n * @param {string} category - UI category ID\n * @returns {Array}\n */\n getFiltersByCategory(category) {\n if (!this._filterRegistry) return []\n\n // Get the list of registry categories that map to this UI category\n const registryCategories = REGISTRY_CATEGORY_MAP[category] || [category]\n\n // Collect filters from all matching registry categories\n const filters = []\n const seenIds = new Set()\n\n for (const registryCat of registryCategories) {\n const catFilters = this._filterRegistry.getFiltersByCategory(registryCat) || []\n for (const filter of catFilters) {\n // Avoid duplicates\n if (!seenIds.has(filter.id)) {\n seenIds.add(filter.id)\n filters.push(filter)\n }\n }\n }\n\n return filters\n }\n\n /**\n * Normalize UI values from various input types\n * @param {*} value\n * @returns {*}\n */\n _normalizeValue(value) {\n if (Array.isArray(value)) {\n // Array of objects (like colorStops) - keep as-is\n if (value.length > 0 && typeof value[0] === 'object') return value\n // Range value - take first number\n return Number(value[0] ?? 0)\n }\n if (typeof value === 'string') {\n // Hex color - keep as string\n if (value.startsWith('#')) return value\n // Numeric string\n return value.trim() === '' ? 0 : Number(value)\n }\n return value\n }\n\n /**\n * Set a deep property on an object\n * @param {Object} target\n * @param {string} path\n * @param {*} value\n */\n _setDeepProp(target, path, value) {\n if (!target || !path) return\n\n if (!path.includes('.') && !path.includes('[')) {\n target[path] = value\n return\n }\n\n const tokens = path.replace(/\\[(\\d+)\\]/g, '.$1').split('.').filter(Boolean)\n let obj = target\n for (let i = 0; i < tokens.length - 1; i++) {\n const key = tokens[i]\n if (!(key in obj)) return\n obj = obj[key]\n if (obj == null) return\n }\n const last = tokens[tokens.length - 1]\n obj[last] = value\n }\n\n /**\n * Initialize filter values from definition defaults\n * @param {string} filterId\n */\n initializeValues(filterId) {\n const def = this.getFilterDef(filterId)\n if (!def) return\n\n def.controls.forEach(ctl => {\n const values = this.state.getFilterValues(filterId)\n if (!(ctl.id in values)) {\n this.state.setFilterValue(filterId, ctl.id, ctl.default)\n }\n })\n }\n\n /**\n * Reset all filter values to their defaults (unconditionally)\n * @param {string} filterId\n */\n resetValues(filterId) {\n const def = this.getFilterDef(filterId)\n if (!def) return\n\n def.controls.forEach(ctl => {\n this.state.setFilterValue(filterId, ctl.id, ctl.default)\n })\n }\n\n /**\n * Toggle a filter on/off\n * @param {string} filterId\n * @param {boolean} enabled\n */\n toggle(filterId, enabled) {\n this.state.toggleFilter(filterId, enabled)\n\n if (enabled) {\n this.initializeValues(filterId)\n } else {\n delete this.instances[filterId]\n }\n\n this.applyFilters()\n this.emit('filterToggled', { filterId, enabled })\n }\n\n /**\n * Update a filter control value\n * @param {string} filterId\n * @param {string} controlId\n * @param {*} value\n * @returns {boolean} True if updated in-place\n */\n updateValue(filterId, controlId, value) {\n const normalized = this._normalizeValue(value)\n this.state.setFilterValue(filterId, controlId, normalized)\n\n const inst = this.instances[filterId]\n if (inst) {\n const def = this.getFilterDef(filterId)\n const ctl = def?.controls.find(c => c.id === controlId)\n const path = ctl?.property || controlId\n\n if (typeof inst.updateUIParam === 'function') {\n inst.updateUIParam(path, normalized)\n return true\n } else {\n this._setDeepProp(inst, path, normalized)\n if (inst.uniforms && path in inst.uniforms) {\n inst.uniforms[path] = normalized\n }\n return true\n }\n }\n return false\n }\n\n /**\n * Apply all active filters to the sprite\n *\n * This method recreates all filter instances on each call to ensure\n * PIXI v8's filter pipeline correctly processes changes.\n */\n applyFilters() {\n const sprite = this.renderer.sprite\n if (!sprite) return\n\n // Clear old instances (matches Vue version behavior)\n // PIXI v8 requires fresh instances for reliable filter pipeline processing\n for (const key in this.instances) {\n delete this.instances[key]\n }\n\n const filters = []\n const failedFilters = []\n const activeFilters = this.state.get('activeFilters')\n\n activeFilters.forEach(id => {\n try {\n const def = this.getFilterDef(id)\n if (!def) {\n console.warn(`[FilterManager] Filter definition not found: ${id}`)\n return\n }\n\n if (!def.createFilter || typeof def.createFilter !== 'function') {\n console.warn(`[FilterManager] Filter has no createFilter method: ${id}`)\n return\n }\n\n const values = this.state.getFilterValues(id)\n\n // Start with defaultParams (lowest priority)\n const params = def.defaultParams ? { ...def.defaultParams } : {}\n\n // Overlay with control values and user-set values (higher priority)\n if (def.controls && Array.isArray(def.controls)) {\n def.controls.forEach(c => {\n const key = c.property || c.id\n // User values from state take precedence over defaults\n params[key] = values[c.id] ?? c.default\n })\n }\n\n // Create the filter instance\n const f = def.createFilter(params)\n if (f) {\n filters.push(f)\n this.instances[id] = f\n }\n } catch (error) {\n console.error(`[FilterManager] Error creating filter ${id}:`, error)\n failedFilters.push(id)\n }\n })\n\n // CRITICAL FIX: Clear filters first for PIXI v8 compatibility\n // IMPORTANT: PIXI v8 doesn't recognize filter changes unless we clear first.\n // This forces PIXI to re-process the filter pipeline on the next render.\n try {\n sprite.filters = null\n sprite.filters = filters.length ? filters : null\n this.renderer.render()\n this.emit('filtersApplied', { count: filters.length, failed: failedFilters })\n } catch (error) {\n console.error('[FilterManager] Error applying filters to sprite:', error)\n\n // Try to recover by removing all filters\n try {\n sprite.filters = null\n this.renderer.render()\n } catch (recoveryError) {\n console.error('[FilterManager] Recovery failed:', recoveryError)\n }\n\n this.emit('filtersError', { error, failedFilters })\n }\n\n // Notify about failed filters\n if (failedFilters.length > 0) {\n console.warn(`[FilterManager] ${failedFilters.length} filter(s) failed to create:`, failedFilters)\n }\n }\n\n /**\n * Reset all filters\n */\n resetAll() {\n // Clear instances\n for (const key in this.instances) {\n delete this.instances[key]\n }\n\n // Reset state\n this.state.resetFilters()\n\n // Clear sprite filters\n if (this.renderer.sprite) {\n this.renderer.sprite.filters = null\n }\n\n // Reset to base texture if needed\n if (this.renderer.baseTexture &&\n this.renderer.originalTexture !== this.renderer.baseTexture &&\n this.renderer.sprite &&\n this.renderer.app) {\n\n const PIXI = window.PIXI\n this.renderer.originalTexture = this.renderer.baseTexture\n this.renderer.app.stage.removeChild(this.renderer.sprite)\n this.renderer.sprite.destroy()\n\n const newSprite = new PIXI.Sprite(this.renderer.originalTexture)\n this.renderer.app.stage.addChild(newSprite)\n this.renderer.sprite = newSprite\n\n this.renderer.fitScale = this.renderer.getFitScaleFor(this.renderer.originalTexture)\n this.renderer.setZoom(1, { keepCenter: false })\n this.renderer.applyViewTransform()\n }\n\n this.renderer.render()\n this.emit('filtersReset')\n }\n\n /**\n * Get a filter instance\n * @param {string} filterId\n * @returns {Object|null}\n */\n getInstance(filterId) {\n return this.instances[filterId] || null\n }\n}\n","/**\n * Crop Manager for the vanilla image editor\n * Handles crop mode, overlay rendering, and crop application\n */\nimport { EventEmitter } from '../core/EventEmitter.js'\n\nexport class CropManager extends EventEmitter {\n /**\n * Padding factor for auto-zoom: image will be ~91% of crop size (1/1.1).\n * Higher values = more aggressive zoom-out, more padding around image.\n */\n static AUTO_ZOOM_PADDING = 1.1\n\n /**\n * Minimum interval (ms) between auto-zoom adjustments during drag.\n */\n static AUTO_ZOOM_THROTTLE_MS = 100\n\n constructor(state, pixiRenderer) {\n super()\n this.state = state\n this.renderer = pixiRenderer\n\n // Internal state\n this._overlayCanvas = null\n this._isDragging = false\n this._dragStart = null\n this._dragMode = null\n this._startRect = null\n this._hoverMode = null\n\n // Auto-zoom throttle timestamp\n this._lastAutoZoomCheck = 0\n\n // UI constants\n this.HANDLE_SIZE = 14\n this.EDGE_HIT_PAD = 10\n\n // Bound handlers\n this._onPointerDown = this._handlePointerDown.bind(this)\n this._onPointerMove = this._handlePointerMove.bind(this)\n this._onPointerUp = this._handlePointerUp.bind(this)\n }\n\n /**\n * Set the overlay canvas element\n * @param {HTMLCanvasElement} canvas\n */\n setOverlayCanvas(canvas) {\n this._overlayCanvas = canvas\n }\n\n /**\n * Get aspect ratio value from string\n * @param {string} aspect\n * @returns {number|null}\n */\n _getAspectRatio(aspect) {\n if (!aspect || aspect === 'free') return null\n\n const aspectMap = {\n '1:1': 1,\n '4:3': 4/3,\n '16:9': 16/9,\n '3:2': 3/2,\n '2:3': 2/3\n }\n\n if (aspectMap[aspect] !== undefined) return aspectMap[aspect]\n\n // Parse custom ratio strings like '3:1', '21:9'\n const parts = aspect.split(':')\n if (parts.length === 2) {\n const w = parseFloat(parts[0])\n const h = parseFloat(parts[1])\n if (Number.isFinite(w) && Number.isFinite(h) && h > 0) {\n return w / h\n }\n }\n\n return null\n }\n\n /**\n * Apply aspect ratio constraint to crop rect\n */\n applyAspectRatio() {\n const rect = this.state.get('crop.rect')\n const aspect = this.state.get('crop.aspect')\n\n if (!rect || aspect === 'free') return\n\n const targetAspect = this._getAspectRatio(aspect)\n if (!targetAspect) return\n\n const currentAspect = rect.width / rect.height\n if (Math.abs(currentAspect - targetAspect) < 0.01) return\n\n if (currentAspect > targetAspect) {\n rect.width = rect.height * targetAspect\n } else {\n rect.height = rect.width / targetAspect\n }\n\n this.state.set('crop.rect', rect)\n }\n\n /**\n * Constrain crop rect to bounds\n */\n constrainCropRect() {\n const rect = this.state.get('crop.rect')\n if (!rect) return\n\n const sprite = this.renderer.sprite\n const app = this.renderer.app\n if (!sprite || !app) return\n\n const shape = this.state.get('crop.shape')\n const useScreen = shape === 'circle' || !!this.state.get('autoZoomOnCropOverflow')\n\n const bounds = useScreen\n ? { x: 0, y: 0, w: app.screen.width, h: app.screen.height }\n : { x: sprite.x, y: sprite.y, w: sprite.width, h: sprite.height }\n\n rect.x = Math.max(bounds.x, Math.min(rect.x, bounds.x + bounds.w - rect.width))\n rect.y = Math.max(bounds.y, Math.min(rect.y, bounds.y + bounds.h - rect.height))\n rect.width = Math.min(rect.width, bounds.w)\n rect.height = Math.min(rect.height, bounds.h)\n\n // Keep circle/square 1:1\n if (shape !== 'free' || this.state.get('crop.aspect') === '1:1') {\n const side = Math.min(rect.width, rect.height)\n rect.width = side\n rect.height = side\n }\n\n this.state.set('crop.rect', rect)\n }\n\n /**\n * Calculate the target zoom level for auto-zoom when crop exceeds image bounds.\n * Pure function — returns the new zoom level, or null if no adjustment is needed.\n *\n * @param {{ width: number, height: number }} cropRect - Current crop dimensions\n * @param {number} spriteWidth - Current sprite width on screen\n * @param {number} spriteHeight - Current sprite height on screen\n * @param {number} texWidth - Original texture width (pixels)\n * @param {number} texHeight - Original texture height (pixels)\n * @param {number} fitScale - Current fit-to-screen scale\n * @param {number} currentZoom - Current zoom level\n * @returns {number|null} Target zoom level, or null if no zoom needed\n */\n static calcAutoZoom(cropRect, spriteWidth, spriteHeight, texWidth, texHeight, fitScale, currentZoom) {\n if (!cropRect || !texWidth || !texHeight || !fitScale) return null\n\n const overflowW = cropRect.width > spriteWidth\n const overflowH = cropRect.height > spriteHeight\n\n if (!overflowW && !overflowH) return null\n\n const pad = CropManager.AUTO_ZOOM_PADDING\n let targetZoom = currentZoom\n\n // Only zoom out for the dimension(s) where overflow occurs\n if (overflowW) {\n const zoomForW = cropRect.width / (pad * texWidth * fitScale)\n targetZoom = Math.min(targetZoom, zoomForW)\n }\n if (overflowH) {\n const zoomForH = cropRect.height / (pad * texHeight * fitScale)\n targetZoom = Math.min(targetZoom, zoomForH)\n }\n\n // Clamp to minimum zoom\n targetZoom = Math.max(0.1, targetZoom)\n\n // Only return if this would actually zoom out (threshold avoids micro-adjustments)\n if (targetZoom >= currentZoom - 0.01) return null\n\n return targetZoom\n }\n\n /**\n * Check if auto-zoom is needed and apply it (throttled).\n * Called during crop resize drags when autoZoomOnCropOverflow is enabled.\n */\n _checkAutoZoom() {\n if (!this.state.get('autoZoomOnCropOverflow')) return\n\n // Throttle to avoid excessive zoom adjustments during drag\n const now = Date.now()\n if (now - this._lastAutoZoomCheck < CropManager.AUTO_ZOOM_THROTTLE_MS) return\n this._lastAutoZoomCheck = now\n\n const rect = this.state.get('crop.rect')\n const sprite = this.renderer.sprite\n const tex = this.renderer.originalTexture\n if (!rect || !sprite || !tex) return\n\n const targetZoom = CropManager.calcAutoZoom(\n rect,\n sprite.width,\n sprite.height,\n tex.width,\n tex.height,\n this.renderer.fitScale,\n this.renderer.zoom\n )\n\n if (targetZoom !== null) {\n this.renderer.setZoom(targetZoom, { keepCenter: true })\n }\n }\n\n /**\n * Draw crop overlay on canvas\n */\n drawOverlay() {\n const overlay = this._overlayCanvas\n if (!overlay) return\n\n const app = this.renderer.app\n if (!app) return\n\n const cv = app.canvas\n const cssW = cv.clientWidth\n const cssH = cv.clientHeight\n const dpr = window.devicePixelRatio || 1\n\n // DPR-aware canvas sizing\n if (overlay.width !== Math.max(1, Math.floor(cssW * dpr)) ||\n overlay.height !== Math.max(1, Math.floor(cssH * dpr))) {\n overlay.width = Math.max(1, Math.floor(cssW * dpr))\n overlay.height = Math.max(1, Math.floor(cssH * dpr))\n overlay.style.width = cssW + 'px'\n overlay.style.height = cssH + 'px'\n }\n\n const ctx = overlay.getContext('2d')\n if (!ctx) return\n\n ctx.setTransform(dpr, 0, 0, dpr, 0, 0)\n ctx.clearRect(0, 0, cssW, cssH)\n\n // Dark overlay\n ctx.fillStyle = 'rgba(0, 0, 0, 0.5)'\n ctx.fillRect(0, 0, cssW, cssH)\n\n const rect = this.state.get('crop.rect')\n if (!rect) return\n\n const shape = this.state.get('crop.shape')\n\n // Clear crop area\n ctx.save()\n if (shape === 'circle') {\n const centerX = rect.x + rect.width / 2\n const centerY = rect.y + rect.height / 2\n const radius = Math.min(rect.width, rect.height) / 2\n ctx.beginPath()\n ctx.arc(centerX, centerY, radius, 0, Math.PI * 2)\n ctx.clip()\n } else {\n ctx.beginPath()\n ctx.rect(rect.x, rect.y, rect.width, rect.height)\n ctx.clip()\n }\n ctx.clearRect(rect.x, rect.y, rect.width, rect.height)\n ctx.restore()\n\n // Draw border\n ctx.strokeStyle = '#ffffff'\n ctx.lineWidth = 2\n ctx.setLineDash([5, 5])\n\n if (shape === 'circle') {\n ctx.beginPath()\n ctx.arc(\n rect.x + rect.width / 2,\n rect.y + rect.height / 2,\n Math.min(rect.width, rect.height) / 2,\n 0,\n Math.PI * 2\n )\n ctx.stroke()\n } else {\n ctx.strokeRect(rect.x, rect.y, rect.width, rect.height)\n }\n\n // Grid (rule-of-thirds)\n ctx.setLineDash([])\n ctx.strokeStyle = 'rgba(255,255,255,0.3)'\n ctx.lineWidth = 1\n const thirdW = rect.width / 3\n const thirdH = rect.height / 3\n\n for (let i = 1; i <= 2; i++) {\n ctx.beginPath()\n ctx.moveTo(rect.x + thirdW * i, rect.y)\n ctx.lineTo(rect.x + thirdW * i, rect.y + rect.height)\n ctx.stroke()\n\n ctx.beginPath()\n ctx.moveTo(rect.x, rect.y + thirdH * i)\n ctx.lineTo(rect.x + rect.width, rect.y + thirdH * i)\n ctx.stroke()\n }\n\n // Draw 8 resize handles\n const hs = this.HANDLE_SIZE\n const corners = [\n { x: rect.x, y: rect.y, m: 'resize-nw' },\n { x: rect.x + rect.width, y: rect.y, m: 'resize-ne' },\n { x: rect.x, y: rect.y + rect.height, m: 'resize-sw' },\n { x: rect.x + rect.width, y: rect.y + rect.height, m: 'resize-se' }\n ]\n const edges = [\n { x: rect.x + rect.width/2, y: rect.y, m: 'n' },\n { x: rect.x + rect.width/2, y: rect.y + rect.height, m: 's' },\n { x: rect.x, y: rect.y + rect.height/2, m: 'w' },\n { x: rect.x + rect.width, y: rect.y + rect.height/2, m: 'e' }\n ]\n\n const all = [...corners, ...edges]\n for (const h of all) {\n const hover = this._hoverMode === h.m\n const size = hover ? hs + 4 : hs\n ctx.beginPath()\n ctx.rect(h.x - size/2, h.y - size/2, size, size)\n ctx.fillStyle = hover ? '#4da3ff' : '#ffffff'\n ctx.strokeStyle = 'rgba(0,0,0,0.6)'\n ctx.lineWidth = 1\n ctx.fill()\n ctx.stroke()\n }\n }\n\n /**\n * Hit test for handles\n * @param {number} px\n * @param {number} py\n * @returns {string|null}\n */\n _hitHandle(px, py) {\n const rect = this.state.get('crop.rect')\n if (!rect) return null\n\n const near = (ax, ay, bx, by, pad) =>\n Math.abs(ax - bx) <= pad && Math.abs(ay - by) <= pad\n\n // Corners\n if (near(px, py, rect.x, rect.y, this.HANDLE_SIZE)) return 'resize-nw'\n if (near(px, py, rect.x + rect.width, rect.y, this.HANDLE_SIZE)) return 'resize-ne'\n if (near(px, py, rect.x, rect.y + rect.height, this.HANDLE_SIZE)) return 'resize-sw'\n if (near(px, py, rect.x + rect.width, rect.y + rect.height, this.HANDLE_SIZE)) return 'resize-se'\n\n // Edges\n if (Math.abs(py - rect.y) <= this.EDGE_HIT_PAD && px >= rect.x && px <= rect.x + rect.width) return 'n'\n if (Math.abs(py - (rect.y + rect.height)) <= this.EDGE_HIT_PAD && px >= rect.x && px <= rect.x + rect.width) return 's'\n if (Math.abs(px - rect.x) <= this.EDGE_HIT_PAD && py >= rect.y && py <= rect.y + rect.height) return 'w'\n if (Math.abs(px - (rect.x + rect.width)) <= this.EDGE_HIT_PAD && py >= rect.y && py <= rect.y + rect.height) return 'e'\n\n // Interior = move\n if (px >= rect.x && px <= rect.x + rect.width && py >= rect.y && py <= rect.y + rect.height) return 'move'\n\n return null\n }\n\n /**\n * Handle pointer down event\n */\n _handlePointerDown(event) {\n const rect = this.state.get('crop.rect')\n if (!rect) return\n\n const pos = event.global\n this._dragMode = this._hitHandle(pos.x, pos.y)\n\n if (this._dragMode) {\n this._isDragging = true\n this._dragStart = { x: pos.x, y: pos.y }\n this._startRect = { ...rect }\n // Reset auto-zoom throttle so first check in new drag is immediate\n this._lastAutoZoomCheck = 0\n }\n }\n\n /**\n * Handle pointer move event\n */\n _handlePointerMove(event) {\n const app = this.renderer.app\n if (!app) return\n\n const pos = event.global\n\n // Hover feedback when not dragging\n if (!this._isDragging || !this._dragStart || !this._startRect) {\n this._hoverMode = this._hitHandle(pos.x, pos.y)\n app.stage.cursor =\n this._hoverMode === 'move' ? 'move' :\n this._hoverMode === 'n' || this._hoverMode === 's' ? 'ns-resize' :\n this._hoverMode === 'e' || this._hoverMode === 'w' ? 'ew-resize' :\n this._hoverMode?.endsWith('nw') || this._hoverMode?.endsWith('se') ? 'nwse-resize' :\n this._hoverMode?.endsWith('ne') || this._hoverMode?.endsWith('sw') ? 'nesw-resize' :\n 'crosshair'\n this.drawOverlay()\n return\n }\n\n const rect = this.state.get('crop.rect')\n if (!rect) return\n\n const dx = pos.x - this._dragStart.x\n const dy = pos.y - this._dragStart.y\n\n switch (this._dragMode) {\n case 'move':\n rect.x = this._startRect.x + dx\n rect.y = this._startRect.y + dy\n break\n case 'n':\n rect.y = this._startRect.y + dy\n rect.height = this._startRect.height - dy\n break\n case 's':\n rect.height = this._startRect.height + dy\n break\n case 'w':\n rect.x = this._startRect.x + dx\n rect.width = this._startRect.width - dx\n break\n case 'e':\n rect.width = this._startRect.width + dx\n break\n case 'resize-nw':\n rect.x = this._startRect.x + dx\n rect.y = this._startRect.y + dy\n rect.width = this._startRect.width - dx\n rect.height = this._startRect.height - dy\n break\n case 'resize-ne':\n rect.y = this._startRect.y + dy\n rect.width = this._startRect.width + dx\n rect.height = this._startRect.height - dy\n break\n case 'resize-sw':\n rect.x = this._startRect.x + dx\n rect.width = this._startRect.width - dx\n rect.height = this._startRect.height + dy\n break\n case 'resize-se':\n rect.width = this._startRect.width + dx\n rect.height = this._startRect.height + dy\n break\n }\n\n // Minimum size\n rect.width = Math.max(50, rect.width)\n rect.height = Math.max(50, rect.height)\n\n this.state.set('crop.rect', rect)\n\n // Enforce circle to 1:1\n const shape = this.state.get('crop.shape')\n if (shape === 'circle' && this.state.get('crop.aspect') !== '1:1') {\n this.state.set('crop.aspect', '1:1')\n }\n\n this.applyAspectRatio()\n\n // Auto-zoom when crop exceeds image bounds (only for resize, not move)\n if (this._dragMode !== 'move') {\n this._checkAutoZoom()\n }\n\n this.constrainCropRect()\n this.drawOverlay()\n }\n\n /**\n * Handle pointer up event\n */\n _handlePointerUp() {\n this._isDragging = false\n this._dragMode = null\n this._dragStart = null\n this._startRect = null\n }\n\n /**\n * Enable crop mode\n */\n enable() {\n const app = this.renderer.app\n const sprite = this.renderer.sprite\n if (!app || !sprite) return\n\n // Initialize crop rect if needed\n let rect = this.state.get('crop.rect')\n if (!rect) {\n const size = Math.min(app.screen.width, app.screen.height) * 0.7\n const x = sprite.x + (sprite.width - size) / 2\n const y = sprite.y + (sprite.height - size) / 2\n\n rect = { x, y, width: size, height: size }\n this.state.set('crop.rect', rect)\n\n const shape = this.state.get('crop.shape')\n if (shape === 'circle') {\n this.state.set('crop.aspect', '1:1')\n }\n\n if (this.state.get('crop.aspect') !== 'free') {\n this.applyAspectRatio()\n this.constrainCropRect()\n }\n }\n\n // Make stage interactive\n const stage = app.stage\n stage.eventMode = 'static'\n stage.hitArea = app.screen\n stage.cursor = 'crosshair'\n\n // Attach handlers\n stage.on('pointerdown', this._onPointerDown)\n stage.on('pointermove', this._onPointerMove)\n stage.on('pointerup', this._onPointerUp)\n stage.on('pointerupoutside', this._onPointerUp)\n\n this.state.set('mode', 'crop')\n this.drawOverlay()\n this.emit('enabled')\n }\n\n /**\n * Disable crop mode\n */\n disable() {\n const app = this.renderer.app\n if (!app) return\n\n const stage = app.stage\n stage.off('pointerdown', this._onPointerDown)\n stage.off('pointermove', this._onPointerMove)\n stage.off('pointerup', this._onPointerUp)\n stage.off('pointerupoutside', this._onPointerUp)\n\n stage.eventMode = 'auto'\n stage.cursor = 'default'\n\n this.state.set('crop.rect', null)\n\n // Clear overlay\n if (this._overlayCanvas) {\n const ctx = this._overlayCanvas.getContext('2d')\n ctx?.clearRect(0, 0, this._overlayCanvas.width, this._overlayCanvas.height)\n }\n\n this.state.set('mode', 'filters')\n this.emit('disabled')\n }\n\n /**\n * Apply the crop\n * @returns {{ texture: PIXI.Texture, preservedZoom: number }|null}\n */\n apply() {\n const app = this.renderer.app\n const sprite = this.renderer.sprite\n const tex = this.renderer.originalTexture\n const rect = this.state.get('crop.rect')\n\n if (!rect || !sprite || !app || !tex) return null\n\n const PIXI = window.PIXI\n const prevZoom = this.renderer.zoom\n\n // Map view rect to output pixels\n const scaleX = tex.width / sprite.width\n const scaleY = tex.height / sprite.height\n const rawTx = (rect.x - sprite.x) * scaleX\n const rawTy = (rect.y - sprite.y) * scaleY\n\n let outW = Math.round(Math.max(1, rect.width * scaleX))\n let outH = Math.round(Math.max(1, rect.height * scaleY))\n let offsetX = Math.round(rawTx)\n let offsetY = Math.round(rawTy)\n\n if (outW <= 0 || outH <= 0) return null\n\n // Build off-screen container for crop\n const container = new PIXI.Container()\n const src = new PIXI.Sprite(tex)\n\n // Handle circle crop\n const shape = this.state.get('crop.shape')\n if (shape === 'circle') {\n const side = Math.round(Math.max(outW, outH))\n const cx = offsetX + outW / 2\n const cy = offsetY + outH / 2\n offsetX = Math.round(cx - side / 2)\n offsetY = Math.round(cy - side / 2)\n outW = outH = side\n\n const g = new PIXI.Graphics()\n if (typeof g.circle === 'function' && typeof g.fill === 'function') {\n g.circle(outW / 2, outH / 2, outW / 2).fill(0xffffff)\n } else {\n g.beginFill(0xffffff, 1)\n g.drawCircle(outW / 2, outH / 2, outW / 2)\n g.endFill()\n }\n src.mask = g\n container.addChild(g)\n }\n\n src.x = -offsetX\n src.y = -offsetY\n container.addChild(src)\n\n const rt = PIXI.RenderTexture.create({ width: outW, height: outH })\n app.renderer.render({\n container,\n target: rt,\n clear: true\n })\n\n container.destroy({ children: true })\n\n // Update textures\n this.renderer.originalTexture = rt\n\n // Replace sprite\n app.stage.removeChild(sprite)\n sprite.destroy()\n\n const newSprite = new PIXI.Sprite(rt)\n app.stage.addChild(newSprite)\n this.renderer.sprite = newSprite\n\n // Recalculate fit and apply transform\n this.renderer.fitScale = this.renderer.getFitScaleFor(rt)\n this.renderer.setZoom(prevZoom, { keepCenter: false })\n this.renderer.applyViewTransform()\n this.renderer.render()\n\n // Disable crop mode\n this.disable()\n\n this.emit('applied', { width: outW, height: outH })\n return { texture: rt, preservedZoom: prevZoom }\n }\n\n /**\n * Cancel crop\n */\n cancel() {\n this.disable()\n this.emit('cancelled')\n }\n\n /**\n * Set crop shape\n * @param {'free'|'square'|'circle'} shape\n */\n setShape(shape) {\n // Respect lockCropShape from preset — ignore shape changes when locked\n if (this.state.get('lockCropShape')) return\n\n this.state.set('crop.shape', shape)\n if (shape === 'circle' || shape === 'square') {\n this.state.set('crop.aspect', '1:1')\n }\n this.applyAspectRatio()\n this.constrainCropRect()\n this.drawOverlay()\n }\n\n /**\n * Set aspect ratio\n * @param {'free'|'1:1'|'4:3'|'16:9'|'3:2'|'2:3'|string} aspect\n */\n setAspect(aspect) {\n // Respect lockAspectRatio from preset — ignore changes when locked\n if (this.state.get('lockAspectRatio')) return\n\n this.state.set('crop.aspect', aspect)\n this.applyAspectRatio()\n this.constrainCropRect()\n this.drawOverlay()\n }\n}\n","/**\n * Background Removal Manager for the vanilla image editor\n * Handles communication with the background removal service\n */\n\nexport class RemoveBgManager {\n /**\n * Create a new RemoveBgManager\n * @param {Object} options\n * @param {string} [options.endpoint] - API endpoint for background removal\n * @param {string} [options.fallbackEndpoint] - Fallback endpoint if primary fails\n */\n constructor(options = {}) {\n this._endpoint = options.endpoint || '/api/v1/media/remove-bg'\n this._fallbackEndpoint = options.fallbackEndpoint || null\n }\n\n /**\n * Remove background from an image\n * @param {string} imageData - Data URL or Blob of the image\n * @param {Object} options\n * @param {string} [options.tier='balanced'] - Quality tier: 'fast', 'balanced', 'best'\n * @param {string} [options.model] - Explicit model name (overrides tier)\n * @param {boolean} [options.alpha_matting=false] - Enable alpha matting for edge refinement\n * @param {number} [options.alpha_f=10] - Alpha matting foreground threshold\n * @param {number} [options.alpha_fr=15] - Alpha matting foreground radius\n * @param {number} [options.alpha_erode_size=10] - Alpha matting erode size\n * @returns {Promise<{dataUrl: string, model: string, processMs: string}>}\n */\n async removeBackground(imageData, options = {}) {\n const blob = typeof imageData === 'string'\n ? await this._dataUrlToBlob(imageData)\n : imageData\n\n const formData = new FormData()\n formData.append('file', blob, 'image.png')\n formData.append('tier', options.tier || 'balanced')\n\n if (options.model) {\n formData.append('model', options.model)\n }\n\n if (options.alpha_matting) {\n formData.append('alpha_matting', 'true')\n formData.append('alpha_f', String(options.alpha_f ?? 10))\n formData.append('alpha_fr', String(options.alpha_fr ?? 15))\n formData.append('alpha_erode_size', String(options.alpha_erode_size ?? 10))\n }\n\n let response\n let error\n\n // Try primary endpoint\n try {\n response = await fetch(this._endpoint, {\n method: 'POST',\n body: formData,\n credentials: 'include' // For Sanctum auth\n })\n } catch (e) {\n error = e\n }\n\n // Try fallback if primary failed\n if ((!response || !response.ok) && this._fallbackEndpoint) {\n try {\n response = await fetch(this._fallbackEndpoint, {\n method: 'POST',\n body: formData\n })\n } catch (e) {\n // Keep original error if fallback also fails\n if (!error) error = e\n }\n }\n\n // Check for network error\n if (!response) {\n throw error || new Error('Network error: Unable to connect to background removal service')\n }\n\n // Check for HTTP error\n if (!response.ok) {\n let errorMessage = `Background removal failed (HTTP ${response.status})`\n try {\n const errorText = await response.text()\n if (errorText) errorMessage += `: ${errorText}`\n } catch (_) {}\n throw new Error(errorMessage)\n }\n\n // Read response\n const resultBlob = await response.blob()\n const dataUrl = await this._blobToDataUrl(resultBlob)\n\n return {\n dataUrl,\n model: response.headers.get('X-Model-Used') || 'unknown',\n processMs: response.headers.get('X-Process-Ms') || '0'\n }\n }\n\n /**\n * Convert a data URL to a Blob\n * @param {string} dataUrl\n * @returns {Promise<Blob>}\n */\n async _dataUrlToBlob(dataUrl) {\n // Handle both fetch-able URLs and data URLs\n if (dataUrl.startsWith('data:')) {\n const [header, data] = dataUrl.split(',')\n const mimeMatch = header.match(/:(.*?);/)\n const mime = mimeMatch ? mimeMatch[1] : 'image/png'\n const binary = atob(data)\n const array = new Uint8Array(binary.length)\n for (let i = 0; i < binary.length; i++) {\n array[i] = binary.charCodeAt(i)\n }\n return new Blob([array], { type: mime })\n }\n\n // Fetch URL and convert to blob\n const response = await fetch(dataUrl)\n return response.blob()\n }\n\n /**\n * Convert a Blob to a data URL\n * @param {Blob} blob\n * @returns {Promise<string>}\n */\n _blobToDataUrl(blob) {\n return new Promise((resolve, reject) => {\n const reader = new FileReader()\n reader.onload = () => resolve(reader.result)\n reader.onerror = () => reject(new Error('Failed to read blob as data URL'))\n reader.readAsDataURL(blob)\n })\n }\n\n /**\n * Check if the background removal service is available\n * @returns {Promise<boolean>}\n */\n async isAvailable() {\n try {\n const response = await fetch(this._endpoint, {\n method: 'OPTIONS',\n credentials: 'include'\n })\n return response.ok\n } catch (_) {\n // Try fallback\n if (this._fallbackEndpoint) {\n try {\n const response = await fetch(this._fallbackEndpoint, {\n method: 'OPTIONS'\n })\n return response.ok\n } catch (_) {}\n }\n return false\n }\n }\n}\n","/**\n * UI Builder - DOM helpers and component factories\n * Creates UI elements without external dependencies\n */\n\n/**\n * Create an element with attributes and children\n * @param {string} tag - HTML tag name\n * @param {Object} attrs - Attributes and properties\n * @param {...(string|HTMLElement)} children - Child elements or text\n * @returns {HTMLElement}\n */\nexport function el(tag, attrs = {}, ...children) {\n const element = document.createElement(tag)\n\n for (const [key, value] of Object.entries(attrs)) {\n // Skip undefined and null values\n if (value === undefined || value === null) continue\n\n if (key === 'className') {\n element.className = value\n } else if (key === 'style' && typeof value === 'object') {\n Object.assign(element.style, value)\n } else if (key.startsWith('on') && typeof value === 'function') {\n const event = key.slice(2).toLowerCase()\n element.addEventListener(event, value)\n } else if (key === 'dataset' && typeof value === 'object') {\n Object.assign(element.dataset, value)\n } else {\n element.setAttribute(key, value)\n }\n }\n\n for (const child of children) {\n if (typeof child === 'string') {\n element.appendChild(document.createTextNode(child))\n } else if (child instanceof HTMLElement) {\n element.appendChild(child)\n }\n }\n\n return element\n}\n\n/**\n * Create a slider with label and value display\n * @param {Object} options\n * @returns {HTMLElement}\n */\nexport function createSlider({ id, label, min = 0, max = 1, step = 0.01, value = 0.5, onChange }) {\n // Extract control ID from the id (format: \"filterId-controlId\")\n const controlId = id.includes('-') ? id.split('-').slice(1).join('-') : id\n const wrapper = el('div', {\n className: 'slider-control slider-wrapper',\n 'data-control': controlId,\n 'data-testid': `slider-${controlId}`\n })\n\n const header = el('div', { className: 'slider-header' },\n el('label', { for: id, className: 'slider-label' }, label),\n el('span', { className: 'slider-value', id: `${id}-value` }, formatValue(value))\n )\n\n const input = el('input', {\n type: 'range',\n id,\n className: 'slider-input',\n min: String(min),\n max: String(max),\n step: String(step),\n value: String(value),\n onInput: (e) => {\n const val = parseFloat(e.target.value)\n const display = wrapper.querySelector('.slider-value')\n if (display) display.textContent = formatValue(val)\n onChange?.(val)\n }\n })\n\n wrapper.appendChild(header)\n wrapper.appendChild(input)\n\n // Method to update value programmatically\n wrapper.setValue = (val) => {\n input.value = String(val)\n const display = wrapper.querySelector('.slider-value')\n if (display) display.textContent = formatValue(val)\n }\n\n return wrapper\n}\n\n/**\n * Format a numeric value for display\n */\nfunction formatValue(val) {\n if (Number.isInteger(val)) return String(val)\n return val.toFixed(2)\n}\n\n/**\n * Create a toggle switch\n * @param {Object} options\n * @returns {HTMLElement}\n */\nexport function createToggle({ id, label, checked = false, onChange }) {\n const wrapper = el('div', { className: 'toggle-control' })\n\n const labelEl = el('label', { className: 'toggle-label', for: id }, label)\n\n const input = el('input', {\n type: 'checkbox',\n id,\n className: 'toggle-input',\n checked: checked ? 'checked' : undefined,\n onChange: (e) => onChange?.(e.target.checked)\n })\n\n // Click handler for the visual toggle element\n const toggle = el('div', {\n className: 'toggle-switch',\n onClick: (e) => {\n // Prevent double-triggering if clicking directly on the input\n if (e.target === input) return\n input.checked = !input.checked\n onChange?.(input.checked)\n }\n })\n\n const slider = el('span', { className: 'toggle-slider' })\n toggle.appendChild(input)\n toggle.appendChild(slider)\n\n wrapper.appendChild(labelEl)\n wrapper.appendChild(toggle)\n\n wrapper.setChecked = (val) => {\n input.checked = val\n }\n\n return wrapper\n}\n\n/**\n * Create a color picker\n * @param {Object} options\n * @returns {HTMLElement}\n */\nexport function createColorPicker({ id, label, value = '#000000', onChange }) {\n const wrapper = el('div', { className: 'color-control' })\n\n const labelEl = el('label', { className: 'color-label', for: id }, label)\n\n const input = el('input', {\n type: 'color',\n id,\n className: 'color-input',\n value,\n onInput: (e) => onChange?.(e.target.value)\n })\n\n wrapper.appendChild(labelEl)\n wrapper.appendChild(input)\n\n wrapper.setValue = (val) => {\n input.value = val\n }\n\n return wrapper\n}\n\n/**\n * Create a select dropdown\n * @param {Object} options\n * @returns {HTMLElement}\n */\nexport function createSelect({ id, label, options = [], value, onChange }) {\n const wrapper = el('div', { className: 'select-control' })\n\n const labelEl = el('label', { className: 'select-label', for: id }, label)\n\n const select = el('select', {\n id,\n className: 'select-input',\n onChange: (e) => onChange?.(e.target.value)\n })\n\n for (const opt of options) {\n const option = el('option', { value: opt.value }, opt.label)\n if (opt.value === value) option.selected = true\n select.appendChild(option)\n }\n\n wrapper.appendChild(labelEl)\n wrapper.appendChild(select)\n\n wrapper.setValue = (val) => {\n select.value = val\n }\n\n return wrapper\n}\n\n/**\n * Create a button\n * @param {Object} options\n * @returns {HTMLElement}\n */\nexport function createButton({ label, className = '', onClick, icon = null, disabled = false }) {\n const button = el('button', {\n type: 'button',\n className: `btn ${className}`.trim(),\n onClick,\n disabled: disabled ? 'disabled' : undefined\n })\n\n if (icon) {\n const iconEl = el('span', { className: 'btn-icon' })\n iconEl.innerHTML = icon\n // Mark decorative icon SVG as hidden from screen readers\n const svg = iconEl.querySelector('svg')\n if (svg) svg.setAttribute('aria-hidden', 'true')\n button.appendChild(iconEl)\n }\n\n if (label) {\n button.appendChild(document.createTextNode(label))\n }\n\n return button\n}\n\n/**\n * Create an icon button\n * @param {Object} options\n * @returns {HTMLElement}\n */\nexport function createIconButton({ icon, title, className = '', onClick, disabled = false, testId = null, ariaLabel = null }) {\n const attrs = {\n type: 'button',\n className: `icon-btn ${className}`.trim(),\n title,\n 'aria-label': ariaLabel || title,\n onClick,\n disabled: disabled ? 'disabled' : undefined\n }\n\n if (testId) {\n attrs.dataset = { testid: testId }\n }\n\n const button = el('button', attrs)\n\n button.innerHTML = icon\n // Mark decorative icon SVG as hidden from screen readers\n const svg = button.querySelector('svg')\n if (svg) svg.setAttribute('aria-hidden', 'true')\n return button\n}\n\n/**\n * Create a chip/tag\n * @param {Object} options\n * @returns {HTMLElement}\n */\nexport function createChip({ label, icon, active = false, onClick }) {\n const chip = el('button', {\n type: 'button',\n className: `chip ${active ? 'active' : ''}`.trim(),\n onClick\n })\n\n if (icon) {\n const iconEl = el('span', { className: 'chip-icon' })\n iconEl.innerHTML = icon\n // Mark decorative icon SVG as hidden from screen readers\n const svg = iconEl.querySelector('svg')\n if (svg) svg.setAttribute('aria-hidden', 'true')\n chip.appendChild(iconEl)\n }\n\n chip.appendChild(el('span', { className: 'chip-label' }, label))\n\n chip.setActive = (isActive) => {\n chip.classList.toggle('active', isActive)\n }\n\n return chip\n}\n\n/**\n * Create a card component\n * @param {Object} options\n * @returns {HTMLElement}\n */\nexport function createCard({ className = '', children = [] }) {\n const card = el('div', { className: `card ${className}`.trim() })\n\n for (const child of children) {\n card.appendChild(child)\n }\n\n return card\n}\n\n/**\n * Create scrollable container\n * @param {Object} options\n * @returns {HTMLElement}\n */\nexport function createScrollContainer({ className = '', horizontal = false, children = [] }) {\n const container = el('div', {\n className: `scroll-container ${horizontal ? 'horizontal' : 'vertical'} ${className}`.trim()\n })\n\n for (const child of children) {\n container.appendChild(child)\n }\n\n return container\n}\n","/**\n * SVG Icons for the vanilla image editor\n * Uses inline SVG for zero dependencies\n */\n\n// Navigation icons\nexport const chevronLeft = `<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>`\n\nexport const chevronRight = `<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>`\n\n// Zoom icons\nexport const zoomIn = `<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>`\n\nexport const zoomOut = `<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>`\n\nexport const expand = `<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>`\n\n// Editor mode icons\nexport const settings = `<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>`\n\nexport const water = `<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>`\n\nexport const colorPalette = `<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>`\n\nexport const sparkles = `<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>`\n\nexport const move = `<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>`\n\nexport const brush = `<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=\"M452.37 59.63h0a40.49 40.49 0 00-57.26 0L184 294.74c23.08 4.7 46.12 27.29 49.26 49.26l219.11-227.11a40.49 40.49 0 000-57.26z\"/><path fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"32\" d=\"M138 336c-29.88 0-54 24.5-54 54.86 0 23.95-20.67 36.57-34 44.78 15.08 8.08 32.23 12.36 50 12.36 48.49 0 88-38.89 88-88 0-30.36-24.12-54-50-54z\"/></svg>`\n\nexport const flash = `<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>`\n\nexport const crop = `<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>`\n\n// Action icons\nexport const save = `<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>`\n\nexport const close = `<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>`\n\nexport const refresh = `<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>`\n\nexport const trash = `<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>`\n\nexport const openFolder = `<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>`\n\nexport const checkmark = `<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>`\n\n// Shape icons\nexport const square = `<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>`\n\nexport const circle = `<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>`\n\nexport const freeform = `<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>`\n\n// Theme icons\nexport const sunny = `<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>`\n\nexport const moon = `<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>`\n\n// Category-specific icons\nexport const film = `<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>`\n\nexport const contrast = `<svg viewBox=\"0 0 512 512\" width=\"20\" height=\"20\"><circle cx=\"256\" cy=\"256\" r=\"208\" fill=\"none\" stroke=\"currentColor\" stroke-linejoin=\"round\" stroke-width=\"32\"/><path fill=\"currentColor\" d=\"M256 464c-114.88 0-208-93.12-208-208S141.12 48 256 48z\"/></svg>`\n\n// Filter mode icon (for toolbar)\nexport const filter = `<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=\"M32 144h448M112 256h288M208 368h96\"/></svg>`\n\n// Person/portrait icon (for background removal)\nexport const personOutline = `<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=\"M344 144c-3.92 52.87-44 96-88 96s-84.15-43.12-88-96c-4-55 35-96 88-96s92 42 88 96z\"/><path fill=\"none\" stroke=\"currentColor\" stroke-miterlimit=\"10\" stroke-width=\"32\" d=\"M256 304c-87 0-175.3 48-191.64 138.6C62.39 453.52 68.57 464 80 464h352c11.44 0 17.62-10.48 15.65-21.4C431.3 352 343 304 256 304z\"/></svg>`\n","/**\n * Toolbar component for the vanilla image editor\n * Provides zoom controls, mode switching, and action buttons\n */\nimport { el, createIconButton } from './UIBuilder.js'\nimport * as icons from '../icons/icons.js'\n\nexport class Toolbar {\n constructor(state, editor) {\n this.state = state\n this.editor = editor\n this.element = null\n this._unsubscribers = []\n }\n\n /**\n * Create and render the toolbar\n * @returns {HTMLElement}\n */\n render() {\n this.element = el('div', { className: 'editor-toolbar' })\n\n // Left section - Open image\n const leftSection = el('div', { className: 'toolbar-section toolbar-left' })\n\n const openBtn = createIconButton({\n icon: icons.openFolder,\n title: 'Open Image',\n className: 'toolbar-btn',\n testId: 'btn-open-image',\n ariaLabel: 'Open image file',\n onClick: () => this.editor.openFilePicker()\n })\n leftSection.appendChild(openBtn)\n\n // Center section - Zoom controls\n const centerSection = el('div', { className: 'toolbar-section toolbar-center' })\n\n const zoomOutBtn = createIconButton({\n icon: icons.zoomOut,\n title: 'Zoom Out',\n className: 'toolbar-btn',\n testId: 'btn-zoom-out',\n ariaLabel: 'Zoom out',\n onClick: () => {\n const current = this.state.get('zoom')\n this.editor.setZoom(current - 0.25)\n }\n })\n\n this._zoomLabel = el('span', {\n className: 'zoom-label',\n 'aria-live': 'polite',\n 'aria-atomic': 'true',\n role: 'status'\n }, '100%')\n\n const zoomInBtn = createIconButton({\n icon: icons.zoomIn,\n title: 'Zoom In',\n className: 'toolbar-btn',\n testId: 'btn-zoom-in',\n ariaLabel: 'Zoom in',\n onClick: () => {\n const current = this.state.get('zoom')\n this.editor.setZoom(current + 0.25)\n }\n })\n\n const fitBtn = createIconButton({\n icon: icons.expand,\n title: 'Fit to Screen',\n className: 'toolbar-btn',\n testId: 'btn-fit-screen',\n ariaLabel: 'Fit to screen',\n onClick: () => this.editor.fitToScreen()\n })\n\n centerSection.appendChild(zoomOutBtn)\n centerSection.appendChild(this._zoomLabel)\n centerSection.appendChild(zoomInBtn)\n centerSection.appendChild(fitBtn)\n\n // Right section - Theme toggle, Reset, Save, Close\n const rightSection = el('div', { className: 'toolbar-section toolbar-right' })\n\n this._themeBtn = createIconButton({\n icon: this.state.get('isDarkMode') ? icons.sunny : icons.moon,\n title: 'Toggle Theme',\n className: 'toolbar-btn toolbar-btn-theme',\n testId: 'btn-toggle-theme',\n ariaLabel: 'Toggle theme',\n onClick: () => this.editor.toggleTheme()\n })\n\n // Crop button (mobile only — hidden via CSS on desktop)\n this._cropBtn = createIconButton({\n icon: icons.crop,\n title: 'Crop',\n className: 'toolbar-btn toolbar-btn-crop',\n testId: 'btn-crop',\n ariaLabel: 'Crop image',\n onClick: () => {\n const currentMode = this.state.get('mode')\n if (currentMode === 'crop') {\n this.editor.setMode('filters')\n } else {\n this.editor.setMode('crop')\n }\n }\n })\n\n const resetBtn = createIconButton({\n icon: icons.refresh,\n title: 'Reset All',\n className: 'toolbar-btn',\n testId: 'btn-reset-all',\n ariaLabel: 'Reset all changes',\n onClick: () => this.editor.resetAll()\n })\n\n const saveBtn = createIconButton({\n icon: icons.save,\n title: 'Save Image',\n className: 'toolbar-btn toolbar-btn-primary',\n testId: 'btn-save-edit',\n ariaLabel: 'Save image',\n onClick: () => this.editor.save()\n })\n\n const closeBtn = createIconButton({\n icon: icons.close,\n title: 'Close',\n className: 'toolbar-btn',\n testId: 'btn-cancel-edit',\n ariaLabel: 'Close editor',\n onClick: () => this.editor.close()\n })\n\n rightSection.appendChild(this._themeBtn)\n rightSection.appendChild(this._cropBtn)\n rightSection.appendChild(resetBtn)\n rightSection.appendChild(saveBtn)\n rightSection.appendChild(closeBtn)\n\n // Assemble toolbar\n this.element.appendChild(leftSection)\n this.element.appendChild(centerSection)\n this.element.appendChild(rightSection)\n\n // Subscribe to state changes\n this._subscribeToState()\n\n return this.element\n }\n\n /**\n * Subscribe to state changes\n */\n _subscribeToState() {\n // Zoom changes\n const unsubZoom = this.state.on('change:zoom', ({ value }) => {\n this._zoomLabel.textContent = `${Math.round(value * 100)}%`\n })\n this._unsubscribers.push(unsubZoom)\n\n // Theme changes\n const unsubTheme = this.state.on('change:isDarkMode', ({ value }) => {\n this._themeBtn.innerHTML = value ? icons.sunny : icons.moon\n })\n this._unsubscribers.push(unsubTheme)\n\n // Mode changes — update crop button active state\n const unsubMode = this.state.on('change:mode', ({ value }) => {\n if (this._cropBtn) {\n this._cropBtn.classList.toggle('toolbar-btn-primary', value === 'crop')\n }\n })\n this._unsubscribers.push(unsubMode)\n }\n\n /**\n * Update zoom display\n * @param {number} zoom\n */\n updateZoom(zoom) {\n if (this._zoomLabel) {\n this._zoomLabel.textContent = `${Math.round(zoom * 100)}%`\n }\n }\n\n /**\n * Clean up\n */\n destroy() {\n this._unsubscribers.forEach(unsub => unsub())\n this._unsubscribers = []\n this.element?.remove()\n this.element = null\n }\n}\n","/**\n * Category Carousel component for the vanilla image editor\n * Displays filter categories as scrollable chips\n */\nimport { el, createIconButton, createChip } from './UIBuilder.js'\nimport * as icons from '../icons/icons.js'\n\n// Match categories from the filter registry (resources/js/filters/registry.ts)\n// These are the ACTUAL categories used by filter definitions\nconst CATEGORIES = [\n { id: 'adjust', name: 'Adjust', icon: icons.settings }, // adjustment, adjustmentAdvanced, alpha\n { id: 'blur', name: 'Blur', icon: icons.water }, // blur, kawaseBlur, motionBlur, radialBlur, etc.\n { id: 'color', name: 'Color', icon: icons.colorPalette }, // colorOverlay, grayscale, hslAdjustment, etc.\n { id: 'effects', name: 'Effects', icon: icons.sparkles }, // noise, vignette, pixelate, dropShadow, etc.\n { id: 'distortion', name: 'Distortion', icon: icons.move }, // twist, bulgePinch, displacement, etc.\n { id: 'light', name: 'Light', icon: icons.flash }, // bloom, glow, godray, advancedBloom\n { id: 'stylize', name: 'Stylize', icon: icons.film }, // ascii, crt, crossHatch, dot, emboss\n { id: 'crop', name: 'Crop', icon: icons.crop }\n]\n\n// Category ID mapping from UI categories to filter registry categories\nconst CATEGORY_MAP = {\n 'adjust': 'adjust',\n 'blur': 'blur',\n 'color': 'color',\n 'effects': 'effects',\n 'distortion': 'distortion',\n 'light': 'light',\n 'stylize': 'stylize'\n}\n\n// Reverse mapping for finding category by filter's category property\nconst REGISTRY_CATEGORY_MAP = {\n 'adjust': 'adjust',\n 'blur': 'blur',\n 'color': 'color',\n 'effects': 'effects',\n 'distortion': 'distortion',\n 'light': 'light',\n 'stylize': 'stylize',\n 'advanced': 'adjust' // colorMatrix goes to adjust category\n}\n\nexport { CATEGORY_MAP, REGISTRY_CATEGORY_MAP }\n\nexport class CategoryCarousel {\n constructor(state, editor) {\n this.state = state\n this.editor = editor\n this.element = null\n this._chips = new Map()\n this._scrollIndex = 0\n this._unsubscribers = []\n }\n\n /**\n * Create and render the category carousel\n * @param {Function} onSelect - Callback when category is selected\n * @returns {HTMLElement}\n */\n render(onSelect) {\n this._onSelect = onSelect\n this.element = el('div', {\n className: 'category-carousel-container',\n 'data-testid': 'category-carousel'\n })\n\n // Left navigation button\n this._leftBtn = createIconButton({\n icon: icons.chevronLeft,\n title: 'Previous categories',\n className: 'carousel-nav carousel-nav-left',\n onClick: () => this._scrollLeft()\n })\n\n // Carousel container\n this._carousel = el('div', { className: 'category-carousel' })\n\n // Create category chips\n CATEGORIES.forEach(cat => {\n const chip = createChip({\n label: cat.name,\n icon: cat.icon,\n active: this.state.get('selectedCategory') === cat.id,\n onClick: () => this._selectCategory(cat.id)\n })\n chip.dataset.categoryId = cat.id\n chip.dataset.category = cat.id\n chip.dataset.testid = `category-${cat.id}`\n this._chips.set(cat.id, chip)\n this._carousel.appendChild(chip)\n })\n\n // Right navigation button\n this._rightBtn = createIconButton({\n icon: icons.chevronRight,\n title: 'Next categories',\n className: 'carousel-nav carousel-nav-right',\n onClick: () => this._scrollRight()\n })\n\n // Pagination dots\n this._pagination = el('div', {\n className: 'carousel-pagination',\n role: 'tablist',\n 'aria-label': 'Category pages'\n })\n const pageCount = Math.ceil(CATEGORIES.length / 3)\n for (let i = 0; i < pageCount; i++) {\n const dot = el('button', {\n type: 'button',\n className: `pagination-dot ${i === 0 ? 'active' : ''}`,\n role: 'tab',\n 'aria-label': `Page ${i + 1} of ${pageCount}`,\n 'aria-selected': i === 0 ? 'true' : 'false',\n onClick: () => this._scrollToPage(i)\n })\n this._pagination.appendChild(dot)\n }\n\n // Assemble\n this.element.appendChild(this._leftBtn)\n this.element.appendChild(this._carousel)\n this.element.appendChild(this._rightBtn)\n this.element.appendChild(this._pagination)\n\n // Subscribe to state changes\n this._subscribeToState()\n\n // Update button states\n this._updateNavButtons()\n\n return this.element\n }\n\n /**\n * Subscribe to state changes\n */\n _subscribeToState() {\n const unsub = this.state.on('change:selectedCategory', ({ value }) => {\n this._chips.forEach((chip, id) => {\n chip.setActive(id === value)\n })\n })\n this._unsubscribers.push(unsub)\n }\n\n /**\n * Select a category\n * @param {string} categoryId\n */\n _selectCategory(categoryId) {\n this.state.set('selectedCategory', categoryId)\n\n // Handle crop mode\n if (categoryId === 'crop') {\n this.editor.setMode('crop')\n } else {\n this.editor.setMode('filters')\n }\n\n this._onSelect?.(categoryId)\n }\n\n /**\n * Scroll carousel left\n */\n _scrollLeft() {\n if (this._scrollIndex > 0) {\n this._scrollIndex--\n this._scrollCarousel()\n }\n }\n\n /**\n * Scroll carousel right\n */\n _scrollRight() {\n if (this._scrollIndex < CATEGORIES.length - 3) {\n this._scrollIndex++\n this._scrollCarousel()\n }\n }\n\n /**\n * Scroll to a specific page\n * @param {number} pageIndex\n */\n _scrollToPage(pageIndex) {\n this._scrollIndex = pageIndex * 3\n this._scrollCarousel()\n }\n\n /**\n * Animate carousel scroll\n */\n _scrollCarousel() {\n if (this._carousel) {\n const chip = this._carousel.querySelector('.chip')\n const itemWidth = chip?.clientWidth || 100\n this._carousel.scrollTo({\n left: this._scrollIndex * (itemWidth + 8), // 8px gap\n behavior: 'smooth'\n })\n }\n this._updateNavButtons()\n this._updatePagination()\n }\n\n /**\n * Update navigation button states\n */\n _updateNavButtons() {\n if (this._leftBtn) {\n this._leftBtn.disabled = this._scrollIndex === 0\n }\n if (this._rightBtn) {\n this._rightBtn.disabled = this._scrollIndex >= CATEGORIES.length - 3\n }\n }\n\n /**\n * Update pagination dot states\n */\n _updatePagination() {\n if (this._pagination) {\n const dots = this._pagination.querySelectorAll('.pagination-dot')\n const activePage = Math.floor(this._scrollIndex / 3)\n dots.forEach((dot, i) => {\n const isActive = i === activePage\n dot.classList.toggle('active', isActive)\n dot.setAttribute('aria-selected', isActive ? 'true' : 'false')\n })\n }\n }\n\n /**\n * Set the selected category\n * @param {string} categoryId\n */\n setSelected(categoryId) {\n this._selectCategory(categoryId)\n }\n\n /**\n * Clean up\n */\n destroy() {\n this._unsubscribers.forEach(unsub => unsub())\n this._unsubscribers = []\n this._chips.clear()\n this.element?.remove()\n this.element = null\n }\n}\n","/**\n * Filter Carousel component for the vanilla image editor\n * Displays filters in the current category as scrollable cards\n */\nimport { el, createIconButton } from './UIBuilder.js'\nimport * as icons from '../icons/icons.js'\n\nexport class FilterCarousel {\n constructor(state, filterManager) {\n this.state = state\n this.filterManager = filterManager\n this.element = null\n this._filterCards = new Map()\n this._scrollIndex = 0\n this._unsubscribers = []\n this._onToggle = null\n this._onSelect = null\n }\n\n /**\n * Create and render the filter carousel\n * @param {Object} options - { onToggle, onSelect }\n * @returns {HTMLElement}\n */\n render({ onToggle, onSelect }) {\n this._onToggle = onToggle\n this._onSelect = onSelect\n\n this.element = el('div', { className: 'filter-carousel-container' })\n\n // Left navigation button\n this._leftBtn = createIconButton({\n icon: icons.chevronLeft,\n title: 'Previous filters',\n className: 'carousel-nav carousel-nav-left',\n onClick: () => this._scrollLeft()\n })\n\n // Carousel container\n this._carousel = el('div', { className: 'filter-carousel' })\n\n // Right navigation button\n this._rightBtn = createIconButton({\n icon: icons.chevronRight,\n title: 'Next filters',\n className: 'carousel-nav carousel-nav-right',\n onClick: () => this._scrollRight()\n })\n\n // Assemble\n this.element.appendChild(this._leftBtn)\n this.element.appendChild(this._carousel)\n this.element.appendChild(this._rightBtn)\n\n // Subscribe to state changes\n this._subscribeToState()\n\n // Initial render\n this._renderFilters()\n\n return this.element\n }\n\n /**\n * Subscribe to state changes\n */\n _subscribeToState() {\n // Re-render when category changes\n const unsubCat = this.state.on('change:selectedCategory', () => {\n this._renderFilters()\n })\n this._unsubscribers.push(unsubCat)\n\n // Update active states\n const unsubActive = this.state.on('change:activeFilters', () => {\n this._updateActiveStates()\n })\n this._unsubscribers.push(unsubActive)\n\n // Update selected state\n const unsubSelected = this.state.on('change:selectedFilter', () => {\n this._updateSelectedState()\n })\n this._unsubscribers.push(unsubSelected)\n }\n\n /**\n * Render filters for current category\n */\n _renderFilters() {\n // Clear existing\n this._carousel.innerHTML = ''\n this._filterCards.clear()\n this._scrollIndex = 0\n\n const category = this.state.get('selectedCategory')\n if (category === 'crop') return\n\n const filters = this.filterManager.getFiltersByCategory(category)\n const activeFilters = this.state.get('activeFilters')\n const selectedFilter = this.state.get('selectedFilter')\n\n filters.forEach(filter => {\n const card = this._createFilterCard(filter, {\n isActive: activeFilters.has(filter.id),\n isSelected: selectedFilter === filter.id\n })\n this._filterCards.set(filter.id, card)\n this._carousel.appendChild(card)\n })\n\n this._updateNavButtons()\n }\n\n /**\n * Create a filter card\n * @param {Object} filter\n * @param {Object} options\n * @returns {HTMLElement}\n */\n _createFilterCard(filter, { isActive, isSelected }) {\n const card = el('div', {\n className: `filter-card ${isActive ? 'active' : ''} ${isSelected ? 'selected' : ''}`,\n 'data-filter': filter.id,\n 'data-testid': `filter-${filter.id}`,\n onClick: () => this._handleCardClick(filter.id)\n })\n\n // Thumbnail/preview area\n const preview = el('div', { className: 'filter-preview' })\n const previewText = el('span', { className: 'filter-preview-text' }, filter.name.charAt(0))\n preview.appendChild(previewText)\n\n // Filter name\n const name = el('span', { className: 'filter-name', title: filter.name }, filter.name)\n\n // Toggle button (checkbox visual)\n const toggle = el('button', {\n className: `filter-toggle ${isActive ? 'active' : ''}`,\n onClick: (e) => {\n e.stopPropagation()\n // Check current state at click time, not creation time\n const currentlyActive = this.state.get('activeFilters').has(filter.id)\n const willBeActive = !currentlyActive\n this._handleToggle(filter.id, willBeActive)\n\n // UX improvement: When toggling a filter ON, also select it to show settings\n if (willBeActive) {\n this.state.set('selectedFilter', filter.id)\n this._onSelect?.(filter.id)\n }\n }\n })\n toggle.innerHTML = isActive ? icons.checkmark : ''\n\n card.appendChild(preview)\n card.appendChild(name)\n card.appendChild(toggle)\n\n // Store references for updates\n card._toggle = toggle\n card._isActive = isActive\n\n return card\n }\n\n /**\n * Handle filter card click (select)\n * @param {string} filterId\n */\n _handleCardClick(filterId) {\n const activeFilters = this.state.get('activeFilters')\n\n // If not active, toggle it on first\n if (!activeFilters.has(filterId)) {\n this._handleToggle(filterId, true)\n }\n\n this.state.set('selectedFilter', filterId)\n this._onSelect?.(filterId)\n }\n\n /**\n * Handle filter toggle\n * @param {string} filterId\n * @param {boolean} enabled\n */\n _handleToggle(filterId, enabled) {\n this._onToggle?.(filterId, enabled)\n }\n\n /**\n * Update active states based on state\n */\n _updateActiveStates() {\n const activeFilters = this.state.get('activeFilters')\n\n this._filterCards.forEach((card, filterId) => {\n const isActive = activeFilters.has(filterId)\n card.classList.toggle('active', isActive)\n card._toggle.classList.toggle('active', isActive)\n card._toggle.innerHTML = isActive ? icons.checkmark : ''\n card._isActive = isActive\n })\n }\n\n /**\n * Update selected state based on state\n */\n _updateSelectedState() {\n const selectedFilter = this.state.get('selectedFilter')\n\n this._filterCards.forEach((card, filterId) => {\n card.classList.toggle('selected', filterId === selectedFilter)\n })\n }\n\n /**\n * Scroll carousel left\n */\n _scrollLeft() {\n if (this._scrollIndex > 0) {\n this._scrollIndex--\n this._scrollCarousel()\n }\n }\n\n /**\n * Scroll carousel right\n */\n _scrollRight() {\n const maxIndex = Math.max(0, this._filterCards.size - 3)\n if (this._scrollIndex < maxIndex) {\n this._scrollIndex++\n this._scrollCarousel()\n }\n }\n\n /**\n * Animate carousel scroll\n */\n _scrollCarousel() {\n if (this._carousel) {\n const card = this._carousel.querySelector('.filter-card')\n const itemWidth = card?.clientWidth || 120\n this._carousel.scrollTo({\n left: this._scrollIndex * (itemWidth + 8),\n behavior: 'smooth'\n })\n }\n this._updateNavButtons()\n }\n\n /**\n * Update navigation button states\n */\n _updateNavButtons() {\n const maxIndex = Math.max(0, this._filterCards.size - 3)\n if (this._leftBtn) {\n this._leftBtn.disabled = this._scrollIndex === 0\n }\n if (this._rightBtn) {\n this._rightBtn.disabled = this._scrollIndex >= maxIndex\n }\n }\n\n /**\n * Clean up\n */\n destroy() {\n this._unsubscribers.forEach(unsub => unsub())\n this._unsubscribers = []\n this._filterCards.clear()\n this.element?.remove()\n this.element = null\n }\n}\n","/**\n * Filter Adjustments component for the vanilla image editor\n * Dynamic slider controls for the selected filter\n */\nimport { el, createSlider, createToggle, createColorPicker, createSelect, createButton } from './UIBuilder.js'\n\nexport class FilterAdjustments {\n constructor(state, filterManager) {\n this.state = state\n this.filterManager = filterManager\n this.element = null\n this._controls = new Map()\n this._onChange = null\n this._onReset = null\n this._onAction = null\n this._unsubscribers = []\n }\n\n /**\n * Create and render the filter adjustments panel\n * @param {Object} options - { onChange, onReset, onAction }\n * @returns {HTMLElement}\n */\n render({ onChange, onReset, onAction }) {\n this._onChange = onChange\n this._onReset = onReset\n this._onAction = onAction\n\n this.element = el('div', { className: 'filter-adjustments' })\n\n // Subscribe to state changes\n this._subscribeToState()\n\n // Initial render\n this._renderControls()\n\n return this.element\n }\n\n /**\n * Subscribe to state changes\n */\n _subscribeToState() {\n // Re-render when selected filter changes\n const unsubSelected = this.state.on('change:selectedFilter', () => {\n this._renderControls()\n })\n this._unsubscribers.push(unsubSelected)\n\n // Update values when filter values change\n const unsubValues = this.state.on('change:filterValues', () => {\n this._updateValues()\n })\n this._unsubscribers.push(unsubValues)\n }\n\n /**\n * Render controls for the selected filter\n */\n _renderControls() {\n this.element.innerHTML = ''\n this._controls.clear()\n\n const filterId = this.state.get('selectedFilter')\n if (!filterId) {\n this.element.appendChild(\n el('div', { className: 'no-filter-selected' }, 'Select a filter to adjust')\n )\n return\n }\n\n const def = this.filterManager.getFilterDef(filterId)\n if (!def) {\n this.element.appendChild(\n el('div', { className: 'no-filter-selected' }, 'Filter not found')\n )\n return\n }\n\n // Header with filter name and reset button\n const header = el('div', { className: 'adjustments-header' })\n header.appendChild(el('span', { className: 'adjustments-title' }, def.name))\n header.appendChild(createButton({\n label: 'Reset',\n className: 'btn-text',\n onClick: () => this._handleReset(filterId)\n }))\n this.element.appendChild(header)\n\n // Controls grid\n const grid = el('div', { className: 'adjustments-grid' })\n\n // Get filter values\n const values = this.state.getFilterValues(filterId)\n\n // Create controls based on definition\n def.controls.forEach(ctl => {\n const controlEl = this._createControl(filterId, ctl, values[ctl.id] ?? ctl.default)\n if (controlEl) {\n this._controls.set(ctl.id, controlEl)\n grid.appendChild(controlEl)\n }\n })\n\n this.element.appendChild(grid)\n }\n\n /**\n * Create a control element based on type\n * @param {string} filterId\n * @param {Object} ctl - Control definition\n * @param {*} value - Current value\n * @returns {HTMLElement|null}\n */\n _createControl(filterId, ctl, value) {\n // Skip hidden controls\n if (ctl.hidden) return null\n\n // Get the control label (prefer label, fallback to id)\n const label = ctl.label || ctl.id\n\n // Normalize control type (handle aliases)\n const controlType = this._normalizeControlType(ctl.type)\n\n switch (controlType) {\n case 'slider':\n return createSlider({\n id: `${filterId}-${ctl.id}`,\n label: label,\n min: ctl.min ?? 0,\n max: ctl.max ?? 1,\n step: ctl.step ?? 0.01,\n value: typeof value === 'number' ? value : (ctl.default ?? 0),\n onChange: (val) => this._handleChange(filterId, ctl.id, val)\n })\n\n case 'toggle':\n return createToggle({\n id: `${filterId}-${ctl.id}`,\n label: label,\n checked: !!value,\n onChange: (val) => this._handleChange(filterId, ctl.id, val)\n })\n\n case 'color':\n return createColorPicker({\n id: `${filterId}-${ctl.id}`,\n label: label,\n value: typeof value === 'string' && value.startsWith('#') ? value : (ctl.default || '#000000'),\n onChange: (val) => this._handleChange(filterId, ctl.id, val)\n })\n\n case 'select':\n // Normalize options format\n const options = this._normalizeOptions(ctl.options)\n return createSelect({\n id: `${filterId}-${ctl.id}`,\n label: label,\n options: options,\n value: value ?? ctl.default,\n onChange: (val) => this._handleChange(filterId, ctl.id, val)\n })\n\n case 'button':\n const wrapper = el('div', { className: 'button-control' })\n wrapper.appendChild(createButton({\n label: label,\n className: 'btn-secondary',\n onClick: () => this._handleAction(filterId, ctl.action || ctl.id)\n }))\n return wrapper\n\n default:\n console.warn(`[FilterAdjustments] Unknown control type: ${ctl.type}`)\n return null\n }\n }\n\n /**\n * Normalize control type (handle aliases)\n * @param {string} type\n * @returns {string}\n */\n _normalizeControlType(type) {\n const typeMap = {\n 'slider': 'slider',\n 'range': 'slider', // 'range' is an alias for 'slider'\n 'toggle': 'toggle',\n 'checkbox': 'toggle', // 'checkbox' is an alias for 'toggle'\n 'color': 'color',\n 'select': 'select',\n 'dropdown': 'select', // 'dropdown' is an alias for 'select'\n 'button': 'button',\n 'text': 'slider' // 'text' fallback to slider for numeric inputs\n }\n return typeMap[type] || type\n }\n\n /**\n * Normalize options array format\n * @param {Array} options\n * @returns {Array}\n */\n _normalizeOptions(options) {\n if (!options || !Array.isArray(options)) return []\n\n return options.map(opt => {\n // Already in { value, label } format\n if (typeof opt === 'object' && opt.value !== undefined) {\n return { value: opt.value, label: opt.label || String(opt.value) }\n }\n // Simple string value\n if (typeof opt === 'string') {\n return { value: opt, label: opt }\n }\n // Number value\n if (typeof opt === 'number') {\n return { value: opt, label: String(opt) }\n }\n return { value: opt, label: String(opt) }\n })\n }\n\n /**\n * Handle control value change\n * @param {string} filterId\n * @param {string} controlId\n * @param {*} value\n */\n _handleChange(filterId, controlId, value) {\n this._onChange?.(filterId, controlId, value)\n }\n\n /**\n * Handle reset button\n * @param {string} filterId\n */\n _handleReset(filterId) {\n this._onReset?.(filterId)\n this._renderControls() // Re-render to show default values\n }\n\n /**\n * Handle button action\n * @param {string} filterId\n * @param {string} action\n */\n _handleAction(filterId, action) {\n this._onAction?.(filterId, action)\n }\n\n /**\n * Update control values from state\n */\n _updateValues() {\n const filterId = this.state.get('selectedFilter')\n if (!filterId) return\n\n const values = this.state.getFilterValues(filterId)\n const def = this.filterManager.getFilterDef(filterId)\n if (!def) return\n\n def.controls.forEach(ctl => {\n const controlEl = this._controls.get(ctl.id)\n if (controlEl && typeof controlEl.setValue === 'function') {\n const value = values[ctl.id] ?? ctl.default\n controlEl.setValue(value)\n }\n })\n }\n\n /**\n * Show panel\n */\n show() {\n if (this.element) {\n this.element.style.display = ''\n }\n }\n\n /**\n * Hide panel\n */\n hide() {\n if (this.element) {\n this.element.style.display = 'none'\n }\n }\n\n /**\n * Clean up\n */\n destroy() {\n this._unsubscribers.forEach(unsub => unsub())\n this._unsubscribers = []\n this._controls.clear()\n this.element?.remove()\n this.element = null\n }\n}\n","/**\n * Mobile Filter Drawer - Inline panel that replaces carousels for filter adjustments\n * Sized to match the controls section height, scrollable within that space\n */\nimport { el, createSlider, createToggle, createColorPicker, createSelect, createButton, createIconButton } from './UIBuilder.js'\nimport * as icons from '../icons/icons.js'\n\nexport class MobileFilterDrawer {\n constructor(state, filterManager) {\n this.state = state\n this.filterManager = filterManager\n this._drawer = null\n this._body = null\n this._titleEl = null\n this._isOpen = false\n this._currentFilterId = null\n this._controls = new Map()\n this._onChange = null\n this._onReset = null\n this._onRemove = null\n this._onAction = null\n this._container = null\n }\n\n /**\n * Build the drawer DOM and append to container (should be the controls section)\n * @param {HTMLElement} container - Parent element (controls-section)\n * @param {Object} callbacks - { onChange, onReset, onRemove, onAction }\n */\n build(container, { onChange, onReset, onRemove, onAction }) {\n this._onChange = onChange\n this._onReset = onReset\n this._onRemove = onRemove\n this._onAction = onAction\n this._container = container\n\n // Drawer panel — absolutely positioned within controls section\n this._drawer = el('div', { className: 'mobile-filter-drawer' })\n\n // Header — compact: filter name + reset + close\n const header = el('div', { className: 'drawer-header' })\n this._titleEl = el('span', { className: 'drawer-title' }, 'Filter')\n\n const headerActions = el('div', { className: 'drawer-header-actions' })\n\n const resetBtn = createButton({\n label: 'Reset',\n className: 'btn-text',\n onClick: () => {\n if (this._currentFilterId) {\n this._onReset?.(this._currentFilterId)\n this._renderControls()\n }\n }\n })\n\n const removeBtn = createButton({\n label: 'Remove',\n className: 'btn-text btn-danger',\n onClick: () => {\n if (this._currentFilterId) {\n this._onRemove?.(this._currentFilterId)\n this.close()\n }\n }\n })\n\n const closeBtn = createIconButton({\n icon: icons.close,\n title: 'Close',\n className: 'btn-icon-sm',\n ariaLabel: 'Close drawer',\n onClick: () => this.close()\n })\n\n headerActions.appendChild(resetBtn)\n headerActions.appendChild(removeBtn)\n headerActions.appendChild(closeBtn)\n header.appendChild(this._titleEl)\n header.appendChild(headerActions)\n this._drawer.appendChild(header)\n\n // Body (scrollable controls area)\n this._body = el('div', { className: 'drawer-body' })\n this._drawer.appendChild(this._body)\n\n // Append to container\n container.appendChild(this._drawer)\n }\n\n /**\n * Open the drawer for a specific filter\n * @param {string} filterId\n */\n open(filterId) {\n if (this._isOpen && this._currentFilterId === filterId) return\n\n this._currentFilterId = filterId\n this._renderControls()\n\n if (!this._isOpen) {\n this._isOpen = true\n this._sizeToContainer()\n this._animateOpen()\n }\n }\n\n /**\n * Close the drawer\n */\n close() {\n if (!this._isOpen) return\n this._isOpen = false\n this._animateClose()\n this._currentFilterId = null\n }\n\n /**\n * Check if drawer is open\n * @returns {boolean}\n */\n get isOpen() {\n return this._isOpen\n }\n\n /**\n * Size the drawer to match the container (controls section) height\n */\n _sizeToContainer() {\n if (!this._container || !this._drawer) return\n const h = this._container.offsetHeight\n if (h > 0) {\n this._drawer.style.height = h + 'px'\n }\n }\n\n /**\n * Animate drawer open (CSS transition)\n */\n _animateOpen() {\n this._drawer.style.transition = 'none'\n this._drawer.style.transform = 'translateY(100%)'\n this._drawer.offsetHeight // force reflow\n this._drawer.style.transition = 'transform 0.25s cubic-bezier(0.33, 1, 0.68, 1)'\n this._drawer.style.transform = 'translateY(0)'\n }\n\n /**\n * Animate drawer close (CSS transition)\n */\n _animateClose() {\n this._drawer.style.transition = 'transform 0.2s cubic-bezier(0.32, 0, 0.67, 0)'\n this._drawer.style.transform = 'translateY(100%)'\n }\n\n /**\n * Render controls for the current filter\n */\n _renderControls() {\n this._body.innerHTML = ''\n this._controls.clear()\n\n if (!this._currentFilterId) return\n\n const def = this.filterManager.getFilterDef(this._currentFilterId)\n if (!def) return\n\n // Update title\n this._titleEl.textContent = def.name\n\n // Controls grid\n const grid = el('div', { className: 'adjustments-grid' })\n const values = this.state.getFilterValues(this._currentFilterId)\n\n def.controls.forEach(ctl => {\n if (ctl.hidden) return\n\n const controlEl = this._createControl(this._currentFilterId, ctl, values[ctl.id] ?? ctl.default)\n if (controlEl) {\n this._controls.set(ctl.id, controlEl)\n grid.appendChild(controlEl)\n }\n })\n\n this._body.appendChild(grid)\n }\n\n /**\n * Create a control element based on type\n * @param {string} filterId\n * @param {Object} ctl\n * @param {*} value\n * @returns {HTMLElement|null}\n */\n _createControl(filterId, ctl, value) {\n const label = ctl.label || ctl.id\n const controlType = this._normalizeControlType(ctl.type)\n\n switch (controlType) {\n case 'slider':\n return createSlider({\n id: `drawer-${filterId}-${ctl.id}`,\n label,\n min: ctl.min ?? 0,\n max: ctl.max ?? 1,\n step: ctl.step ?? 0.01,\n value: typeof value === 'number' ? value : (ctl.default ?? 0),\n onChange: (val) => this._onChange?.(filterId, ctl.id, val)\n })\n\n case 'toggle':\n return createToggle({\n id: `drawer-${filterId}-${ctl.id}`,\n label,\n checked: !!value,\n onChange: (val) => this._onChange?.(filterId, ctl.id, val)\n })\n\n case 'color':\n return createColorPicker({\n id: `drawer-${filterId}-${ctl.id}`,\n label,\n value: typeof value === 'string' && value.startsWith('#') ? value : (ctl.default || '#000000'),\n onChange: (val) => this._onChange?.(filterId, ctl.id, val)\n })\n\n case 'select': {\n const options = this._normalizeOptions(ctl.options)\n return createSelect({\n id: `drawer-${filterId}-${ctl.id}`,\n label,\n options,\n value: value ?? ctl.default,\n onChange: (val) => this._onChange?.(filterId, ctl.id, val)\n })\n }\n\n case 'button': {\n const wrapper = el('div', { className: 'button-control' })\n wrapper.appendChild(createButton({\n label,\n className: 'btn-secondary',\n onClick: () => this._onAction?.(filterId, ctl.action || ctl.id)\n }))\n return wrapper\n }\n\n default:\n return null\n }\n }\n\n /**\n * Normalize control type\n * @param {string} type\n * @returns {string}\n */\n _normalizeControlType(type) {\n const typeMap = {\n 'slider': 'slider',\n 'range': 'slider',\n 'toggle': 'toggle',\n 'checkbox': 'toggle',\n 'color': 'color',\n 'select': 'select',\n 'dropdown': 'select',\n 'button': 'button',\n 'text': 'slider'\n }\n return typeMap[type] || type\n }\n\n /**\n * Normalize options array\n * @param {Array} options\n * @returns {Array}\n */\n _normalizeOptions(options) {\n if (!options || !Array.isArray(options)) return []\n return options.map(opt => {\n if (typeof opt === 'object' && opt.value !== undefined) {\n return { value: opt.value, label: opt.label || String(opt.value) }\n }\n if (typeof opt === 'string') return { value: opt, label: opt }\n if (typeof opt === 'number') return { value: opt, label: String(opt) }\n return { value: opt, label: String(opt) }\n })\n }\n\n /**\n * Clean up\n */\n destroy() {\n this._controls.clear()\n this._drawer?.remove()\n this._drawer = null\n this._isOpen = false\n this._currentFilterId = null\n this._container = null\n }\n}\n","/**\n * Mobile Active Filters Carousel\n * Horizontal scrollable row of active filter chips with checkmark toggles.\n * Shown below the filter carousel on mobile only.\n */\nimport { el } from './UIBuilder.js'\n\nexport class MobileActiveFilters {\n constructor(state, filterManager) {\n this.state = state\n this.filterManager = filterManager\n this.element = null\n this._scrollContainer = null\n this._chips = new Map()\n this._unsubscribers = []\n this._onToggle = null\n this._onSelect = null\n }\n\n /**\n * @param {Object} callbacks - { onToggle(filterId, enabled), onSelect(filterId) }\n * @returns {HTMLElement}\n */\n render({ onToggle, onSelect }) {\n this._onToggle = onToggle\n this._onSelect = onSelect\n\n this.element = el('div', {\n className: 'mobile-active-filters',\n 'data-testid': 'mobile-active-filters'\n })\n\n this._scrollContainer = el('div', { className: 'mobile-active-filters-scroll' })\n this.element.appendChild(this._scrollContainer)\n\n this._subscribeToState()\n this._renderChips()\n\n return this.element\n }\n\n _subscribeToState() {\n const unsubActive = this.state.on('change:activeFilters', () => {\n this._renderChips()\n })\n this._unsubscribers.push(unsubActive)\n\n const unsubSelected = this.state.on('change:selectedFilter', () => {\n this._updateSelectedState()\n })\n this._unsubscribers.push(unsubSelected)\n }\n\n _renderChips() {\n this._scrollContainer.innerHTML = ''\n this._chips.clear()\n\n const activeFilters = this.state.get('activeFilters')\n\n if (!activeFilters || activeFilters.size === 0) {\n const placeholder = el('div', {\n className: 'active-filter-placeholder'\n }, 'No active filters')\n this._scrollContainer.appendChild(placeholder)\n return\n }\n\n activeFilters.forEach(filterId => {\n const def = this.filterManager.getFilterDef(filterId)\n if (!def) return\n\n const chip = this._createChip(filterId, def)\n this._chips.set(filterId, chip)\n this._scrollContainer.appendChild(chip)\n })\n\n this._updateSelectedState()\n }\n\n _createChip(filterId, def) {\n const chip = el('div', {\n className: 'active-filter-chip',\n 'data-filter-id': filterId,\n 'data-testid': `active-chip-${filterId}`\n })\n\n // Filter name — tap to open drawer\n const label = el('span', {\n className: 'active-filter-chip-label',\n onClick: (e) => {\n e.stopPropagation()\n this._onSelect?.(filterId)\n }\n }, def.name)\n\n // Checkmark toggle — tap to remove filter\n const check = el('button', {\n className: 'active-filter-chip-check',\n 'aria-label': `Remove ${def.name} filter`,\n onClick: (e) => {\n e.stopPropagation()\n this._onToggle?.(filterId, false)\n }\n })\n check.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>'\n\n chip.appendChild(label)\n chip.appendChild(check)\n\n return chip\n }\n\n _updateSelectedState() {\n const selectedFilter = this.state.get('selectedFilter')\n this._chips.forEach((chip, filterId) => {\n chip.classList.toggle('selected', filterId === selectedFilter)\n })\n }\n\n destroy() {\n this._unsubscribers.forEach(unsub => unsub())\n this._unsubscribers = []\n this._chips.clear()\n this.element?.remove()\n this.element = null\n }\n}\n","/**\n * Crop Controls component for the vanilla image editor\n * Provides shape selection and aspect ratio controls\n */\nimport { el, createButton, createChip } from './UIBuilder.js'\nimport * as icons from '../icons/icons.js'\n\nconst SHAPES = [\n { id: 'free', name: 'Free', icon: icons.freeform },\n { id: 'square', name: 'Square', icon: icons.square },\n { id: 'circle', name: 'Circle', icon: icons.circle }\n]\n\nconst ASPECT_RATIOS = [\n { id: 'free', name: 'Free' },\n { id: '1:1', name: '1:1' },\n { id: '4:3', name: '4:3' },\n { id: '16:9', name: '16:9' },\n { id: '3:2', name: '3:2' },\n { id: '2:3', name: '2:3' }\n]\n\nexport class CropControls {\n constructor(state, cropManager) {\n this.state = state\n this.cropManager = cropManager\n this.element = null\n this._shapeChips = new Map()\n this._aspectChips = new Map()\n this._unsubscribers = []\n }\n\n /**\n * Create and render the crop controls\n * @returns {HTMLElement}\n */\n render() {\n this.element = el('div', {\n className: 'crop-controls',\n 'data-testid': 'crop-controls'\n })\n\n // Shape selection section\n const shapeSection = el('div', { className: 'crop-section' })\n shapeSection.appendChild(el('label', { className: 'section-label' }, 'Shape'))\n\n const shapeRow = el('div', { className: 'chip-row' })\n const currentShape = this.state.get('crop.shape')\n\n SHAPES.forEach(shape => {\n const chip = createChip({\n label: shape.name,\n icon: shape.icon,\n active: currentShape === shape.id,\n onClick: () => this._selectShape(shape.id)\n })\n chip.dataset.shape = shape.id\n chip.dataset.testid = `crop-shape-${shape.id}`\n this._shapeChips.set(shape.id, chip)\n shapeRow.appendChild(chip)\n })\n\n shapeSection.appendChild(shapeRow)\n this.element.appendChild(shapeSection)\n\n // Hide shape section when shape is locked (preset enforces a specific shape)\n if (this.state.get('lockCropShape')) {\n shapeSection.style.display = 'none'\n }\n this._shapeSection = shapeSection\n\n // Aspect ratio section (only for free shape)\n this._aspectSection = el('div', { className: 'crop-section' })\n this._aspectSection.appendChild(el('label', { className: 'section-label' }, 'Aspect Ratio'))\n\n const aspectRow = el('div', { className: 'chip-row aspect-row' })\n const currentAspect = this.state.get('crop.aspect')\n\n ASPECT_RATIOS.forEach(aspect => {\n const chip = createChip({\n label: aspect.name,\n active: currentAspect === aspect.id,\n onClick: () => this._selectAspect(aspect.id)\n })\n chip.dataset.ratio = aspect.id\n chip.dataset.testid = `crop-ratio-${aspect.id}`\n this._aspectChips.set(aspect.id, chip)\n aspectRow.appendChild(chip)\n })\n\n this._aspectSection.appendChild(aspectRow)\n this.element.appendChild(this._aspectSection)\n\n // Show/hide aspect ratios based on shape\n this._updateAspectVisibility()\n\n // Action buttons\n const actionRow = el('div', { className: 'crop-actions' })\n\n const cancelBtn = createButton({\n label: 'Cancel',\n className: 'btn-secondary crop-cancel-btn',\n icon: icons.close,\n onClick: () => this.cropManager.cancel()\n })\n cancelBtn.dataset.testid = 'cancel-crop'\n\n const applyBtn = createButton({\n label: 'Apply Crop',\n className: 'btn-primary crop-apply-btn',\n icon: icons.checkmark,\n onClick: () => this.cropManager.apply()\n })\n applyBtn.dataset.testid = 'apply-crop'\n\n actionRow.appendChild(cancelBtn)\n actionRow.appendChild(applyBtn)\n this.element.appendChild(actionRow)\n\n // Subscribe to state changes\n this._subscribeToState()\n\n return this.element\n }\n\n /**\n * Subscribe to state changes\n */\n _subscribeToState() {\n // Shape changes\n const unsubShape = this.state.on('change:crop.shape', ({ value }) => {\n this._shapeChips.forEach((chip, id) => {\n chip.setActive(id === value)\n })\n this._updateAspectVisibility()\n })\n this._unsubscribers.push(unsubShape)\n\n // Aspect changes\n const unsubAspect = this.state.on('change:crop.aspect', ({ value }) => {\n this._aspectChips.forEach((chip, id) => {\n chip.setActive(id === value)\n })\n })\n this._unsubscribers.push(unsubAspect)\n }\n\n /**\n * Select a crop shape\n * @param {string} shapeId\n */\n _selectShape(shapeId) {\n this.cropManager.setShape(shapeId)\n }\n\n /**\n * Select an aspect ratio\n * @param {string} aspectId\n */\n _selectAspect(aspectId) {\n this.cropManager.setAspect(aspectId)\n }\n\n /**\n * Update aspect ratio section visibility\n */\n _updateAspectVisibility() {\n const shape = this.state.get('crop.shape')\n const lockAspect = this.state.get('lockAspectRatio')\n // Hide aspect ratios when: shape is not free (circle/square are always 1:1),\n // OR aspect ratio is locked by preset\n if (this._aspectSection) {\n this._aspectSection.style.display = (shape === 'free' && !lockAspect) ? '' : 'none'\n }\n }\n\n /**\n * Show controls\n */\n show() {\n if (this.element) {\n this.element.style.display = ''\n }\n }\n\n /**\n * Hide controls\n */\n hide() {\n if (this.element) {\n this.element.style.display = 'none'\n }\n }\n\n /**\n * Clean up\n */\n destroy() {\n this._unsubscribers.forEach(unsub => unsub())\n this._unsubscribers = []\n this._shapeChips.clear()\n this._aspectChips.clear()\n this.element?.remove()\n this.element = null\n }\n}\n","/**\n * Active Filters Panel component for the vanilla image editor\n * Displays currently active filters with quick controls\n */\nimport { el, createButton, createIconButton } from './UIBuilder.js'\nimport * as icons from '../icons/icons.js'\n\nexport class ActiveFiltersPanel {\n constructor(state, filterManager) {\n this.state = state\n this.filterManager = filterManager\n this.element = null\n this._filterItems = new Map()\n this._unsubscribers = []\n this._onRemove = null\n this._onReset = null\n this._onClearAll = null\n this._onUpdateValue = null\n this._onSelect = null\n }\n\n /**\n * Create and render the active filters panel\n * @param {Object} options - { onRemove, onReset, onClearAll, onUpdateValue, onSelect }\n * @returns {HTMLElement}\n */\n render({ onRemove, onReset, onClearAll, onUpdateValue, onSelect }) {\n this._onRemove = onRemove\n this._onReset = onReset\n this._onClearAll = onClearAll\n this._onUpdateValue = onUpdateValue\n this._onSelect = onSelect\n\n this.element = el('div', {\n className: 'active-filters-panel',\n 'data-testid': 'active-filters-panel'\n })\n\n // Header\n const header = el('div', { className: 'panel-header' })\n header.appendChild(el('h3', { className: 'panel-title' }, 'Active Filters'))\n const clearAllBtn = createButton({\n label: 'Clear All',\n className: 'btn-text btn-danger',\n onClick: () => this._handleClearAll()\n })\n clearAllBtn.dataset.testid = 'clear-all-filters'\n header.appendChild(clearAllBtn)\n this.element.appendChild(header)\n\n // Filter list container\n this._listContainer = el('div', { className: 'active-filters-list' })\n this.element.appendChild(this._listContainer)\n\n // Subscribe to state changes\n this._subscribeToState()\n\n // Initial render\n this._renderFilterList()\n\n return this.element\n }\n\n /**\n * Subscribe to state changes\n */\n _subscribeToState() {\n // Re-render when active filters change\n const unsubActive = this.state.on('change:activeFilters', () => {\n this._renderFilterList()\n })\n this._unsubscribers.push(unsubActive)\n\n // Update values display\n const unsubValues = this.state.on('change:filterValues', () => {\n this._updateValuesDisplay()\n })\n this._unsubscribers.push(unsubValues)\n\n // Update selected state\n const unsubSelected = this.state.on('change:selectedFilter', () => {\n this._updateSelectedState()\n })\n this._unsubscribers.push(unsubSelected)\n }\n\n /**\n * Update selected state for all items\n */\n _updateSelectedState() {\n const selectedFilter = this.state.get('selectedFilter')\n this._filterItems.forEach((item, filterId) => {\n item.classList.toggle('selected', filterId === selectedFilter)\n })\n }\n\n /**\n * Render the filter list\n */\n _renderFilterList() {\n this._listContainer.innerHTML = ''\n this._filterItems.clear()\n\n const activeFilters = this.state.get('activeFilters')\n\n if (activeFilters.size === 0) {\n this._listContainer.appendChild(\n el('div', { className: 'no-filters-message' }, 'No filters active')\n )\n return\n }\n\n activeFilters.forEach(filterId => {\n const def = this.filterManager.getFilterDef(filterId)\n if (!def) return\n\n const item = this._createFilterItem(filterId, def)\n this._filterItems.set(filterId, item)\n this._listContainer.appendChild(item)\n })\n }\n\n /**\n * Create a filter item\n * @param {string} filterId\n * @param {Object} def - Filter definition\n * @returns {HTMLElement}\n */\n _createFilterItem(filterId, def) {\n const selectedFilter = this.state.get('selectedFilter')\n const isSelected = selectedFilter === filterId\n\n const item = el('div', {\n className: `active-filter-item ${isSelected ? 'selected' : ''}`,\n 'data-active-filter': filterId,\n 'data-testid': `active-filter-${filterId}`,\n onClick: (e) => {\n // Don't select if clicking on action buttons\n if (e.target.closest('.filter-item-actions')) return\n this._handleSelect(filterId)\n }\n })\n\n // Header row with name and actions\n const headerRow = el('div', { className: 'filter-item-header' })\n\n const name = el('span', { className: 'filter-item-name' }, def.name)\n\n const actions = el('div', { className: 'filter-item-actions' })\n\n const resetBtn = createIconButton({\n icon: icons.refresh,\n title: 'Reset filter',\n className: 'btn-icon-sm',\n onClick: () => this._handleReset(filterId)\n })\n\n const removeBtn = createIconButton({\n icon: icons.trash,\n title: 'Remove filter',\n className: 'btn-icon-sm btn-danger',\n onClick: () => this._handleRemove(filterId)\n })\n\n actions.appendChild(resetBtn)\n actions.appendChild(removeBtn)\n\n headerRow.appendChild(name)\n headerRow.appendChild(actions)\n item.appendChild(headerRow)\n\n // Values summary\n const values = this.state.getFilterValues(filterId)\n const summaryEl = el('div', { className: 'filter-item-summary' })\n summaryEl.textContent = this._getValuesSummary(def, values)\n item.appendChild(summaryEl)\n item._summaryEl = summaryEl\n\n return item\n }\n\n /**\n * Normalize control type (handle aliases)\n * @param {string} type\n * @returns {string}\n */\n _normalizeControlType(type) {\n const typeMap = {\n 'slider': 'slider',\n 'range': 'slider',\n 'toggle': 'toggle',\n 'checkbox': 'toggle',\n 'color': 'color',\n 'select': 'select',\n 'dropdown': 'select',\n 'button': 'button'\n }\n return typeMap[type] || type\n }\n\n /**\n * Get a summary of filter values\n * @param {Object} def - Filter definition\n * @param {Object} values - Current values\n * @returns {string}\n */\n _getValuesSummary(def, values) {\n if (!def.controls || !Array.isArray(def.controls)) {\n return 'Default values'\n }\n\n const parts = []\n def.controls.forEach(ctl => {\n const controlType = this._normalizeControlType(ctl.type)\n if (controlType === 'button') return\n\n const label = ctl.label || ctl.id\n const value = values[ctl.id] ?? ctl.default\n if (value === ctl.default) return // Skip default values\n\n if (controlType === 'slider') {\n parts.push(`${label}: ${this._formatValue(value)}`)\n } else if (controlType === 'toggle') {\n if (value) parts.push(label)\n } else if (controlType === 'color') {\n parts.push(`${label}: ${value}`)\n } else if (controlType === 'select') {\n parts.push(`${label}: ${value}`)\n }\n })\n\n return parts.length > 0 ? parts.join(', ') : 'Default values'\n }\n\n /**\n * Format a numeric value for display\n * @param {number} value\n * @returns {string}\n */\n _formatValue(value) {\n if (typeof value !== 'number') return String(value)\n if (Number.isInteger(value)) return String(value)\n return value.toFixed(2)\n }\n\n /**\n * Update values display for all items\n */\n _updateValuesDisplay() {\n this._filterItems.forEach((item, filterId) => {\n const def = this.filterManager.getFilterDef(filterId)\n if (!def || !item._summaryEl) return\n\n const values = this.state.getFilterValues(filterId)\n item._summaryEl.textContent = this._getValuesSummary(def, values)\n })\n }\n\n /**\n * Handle filter removal\n * @param {string} filterId\n */\n _handleRemove(filterId) {\n this._onRemove?.(filterId)\n }\n\n /**\n * Handle filter reset\n * @param {string} filterId\n */\n _handleReset(filterId) {\n this._onReset?.(filterId)\n }\n\n /**\n * Handle clear all\n */\n _handleClearAll() {\n this._onClearAll?.()\n }\n\n /**\n * Handle filter selection\n * @param {string} filterId\n */\n _handleSelect(filterId) {\n this.state.set('selectedFilter', filterId)\n this._onSelect?.(filterId)\n }\n\n /**\n * Show panel\n */\n show() {\n if (this.element) {\n this.element.style.display = ''\n }\n }\n\n /**\n * Hide panel\n */\n hide() {\n if (this.element) {\n this.element.style.display = 'none'\n }\n }\n\n /**\n * Clean up\n */\n destroy() {\n this._unsubscribers.forEach(unsub => unsub())\n this._unsubscribers = []\n this._filterItems.clear()\n this.element?.remove()\n this.element = null\n }\n}\n","/**\n * Editor Preset System\n *\n * Presets configure the image editor for specific use cases (avatars, banners, etc.).\n * Each preset defines initial tool state, crop shape, aspect ratio, and control visibility.\n *\n * @example\n * import { getPreset, PRESETS } from './presets/index.js'\n *\n * // Get a built-in preset by name\n * const avatarPreset = getPreset('avatar')\n *\n * // Use directly\n * const editor = new VanillaImageEditor(container, { preset: avatarPreset })\n *\n * // Or pass by name (resolved later)\n * const editor = new VanillaImageEditor(container, { preset: 'avatar' })\n */\n\n/**\n * @typedef {Object} EditorPreset\n * @property {string} name - Preset identifier (e.g., 'avatar', 'banner', 'product')\n * @property {'crop'|'filters'} initialMode - Which tool is active when editor opens\n * @property {'free'|'square'|'circle'} cropShape - Default crop shape\n * @property {string} aspectRatio - Aspect ratio: 'free', '1:1', '4:3', '16:9', '3:2', '2:3', or custom like '3:1'\n * @property {boolean} autoZoomOnCropOverflow - Smart zoom-out when crop exceeds image bounds\n * @property {boolean} lockCropShape - Prevent user from changing crop shape\n * @property {boolean} lockAspectRatio - Prevent user from changing aspect ratio\n * @property {boolean} showFilters - Whether filter panel is available\n * @property {boolean} showCropControls - Whether crop controls are available\n * @property {number} [maxExportWidth] - Optional max output width in pixels\n * @property {number} [maxExportHeight] - Optional max output height in pixels\n */\n\n/**\n * Default values for an EditorPreset. Used as the base when merging.\n * @type {EditorPreset}\n */\nconst DEFAULT_PRESET = {\n name: 'free',\n initialMode: 'filters',\n cropShape: 'free',\n aspectRatio: 'free',\n autoZoomOnCropOverflow: false,\n lockCropShape: false,\n lockAspectRatio: false,\n showFilters: true,\n showCropControls: true,\n maxExportWidth: undefined,\n maxExportHeight: undefined\n}\n\n/**\n * Built-in presets.\n * @type {Record<string, EditorPreset>}\n */\nexport const PRESETS = {\n free: {\n ...DEFAULT_PRESET\n },\n\n avatar: {\n ...DEFAULT_PRESET,\n name: 'avatar',\n initialMode: 'crop',\n cropShape: 'circle',\n aspectRatio: '1:1',\n autoZoomOnCropOverflow: true,\n lockCropShape: true,\n lockAspectRatio: true\n },\n\n banner: {\n ...DEFAULT_PRESET,\n name: 'banner',\n initialMode: 'crop',\n cropShape: 'square',\n aspectRatio: '16:9',\n autoZoomOnCropOverflow: false,\n lockCropShape: false,\n lockAspectRatio: true\n },\n\n product: {\n ...DEFAULT_PRESET,\n name: 'product',\n initialMode: 'filters',\n cropShape: 'square',\n aspectRatio: '1:1',\n autoZoomOnCropOverflow: false,\n lockCropShape: false,\n lockAspectRatio: false\n }\n}\n\n/**\n * Resolve a preset by name or return a custom preset object as-is.\n * Falls back to the 'free' preset if the name is not recognized.\n *\n * @param {string|EditorPreset} preset - Preset name or custom preset object\n * @returns {EditorPreset} Resolved preset\n */\nexport function getPreset(preset) {\n if (!preset) {\n return { ...PRESETS.free }\n }\n\n // If it's already an object, merge with defaults to fill missing fields\n if (typeof preset === 'object' && preset !== null) {\n return { ...DEFAULT_PRESET, ...preset }\n }\n\n // Look up by name, fallback to 'free'\n const found = PRESETS[preset]\n if (found) {\n return { ...found }\n }\n\n return { ...PRESETS.free }\n}\n\n/**\n * Merge a preset with explicit option overrides.\n * Options take precedence over preset values.\n *\n * @param {EditorPreset} preset - Base preset\n * @param {Partial<EditorPreset>} overrides - Explicit overrides\n * @returns {EditorPreset} Merged result\n */\nexport function mergePresetWithOverrides(preset, overrides) {\n if (!overrides || Object.keys(overrides).length === 0) {\n return { ...preset }\n }\n\n const merged = { ...preset }\n\n // Only apply overrides that are explicitly defined (not undefined)\n for (const key of Object.keys(overrides)) {\n if (overrides[key] !== undefined) {\n merged[key] = overrides[key]\n }\n }\n\n return merged\n}\n\n/**\n * Parse an aspect ratio string into a numeric value.\n * Handles standard ratios ('1:1', '16:9', etc.) and custom strings ('3:1', '21:9').\n * Returns null for 'free' or invalid values.\n *\n * @param {string} ratio - Aspect ratio string\n * @returns {number|null} Numeric ratio (width / height), or null for 'free'\n */\nexport function parseAspectRatio(ratio) {\n if (!ratio || ratio === 'free') {\n return null\n }\n\n const parts = ratio.split(':')\n if (parts.length === 2) {\n const w = parseFloat(parts[0])\n const h = parseFloat(parts[1])\n if (Number.isFinite(w) && Number.isFinite(h) && h > 0) {\n return w / h\n }\n }\n\n return null\n}\n\nexport { DEFAULT_PRESET }\n","/**\n * VanillaImageEditor - Main orchestrator class\n * Framework-agnostic image editor using vanilla JavaScript\n */\nimport { EventEmitter } from './core/EventEmitter.js'\nimport { createState } from './core/State.js'\nimport { PixiRenderer } from './renderer/PixiRenderer.js'\nimport { FilterManager } from './renderer/FilterManager.js'\nimport { CropManager } from './renderer/CropManager.js'\nimport { RemoveBgManager } from './renderer/RemoveBgManager.js'\nimport { Toolbar } from './ui/Toolbar.js'\nimport { CategoryCarousel } from './ui/CategoryCarousel.js'\nimport { FilterCarousel } from './ui/FilterCarousel.js'\nimport { FilterAdjustments } from './ui/FilterAdjustments.js'\nimport { MobileFilterDrawer } from './ui/MobileFilterDrawer.js'\nimport { MobileActiveFilters } from './ui/MobileActiveFilters.js'\nimport { CropControls } from './ui/CropControls.js'\nimport { ActiveFiltersPanel } from './ui/ActiveFiltersPanel.js'\nimport { el } from './ui/UIBuilder.js'\nimport { getPreset, mergePresetWithOverrides } from './presets/index.js'\n\nexport class VanillaImageEditor extends EventEmitter {\n /**\n * Create a new VanillaImageEditor\n * @param {HTMLElement} container - Container element to mount the editor\n * @param {Object} options - Configuration options\n */\n constructor(container, options = {}) {\n super()\n\n if (!container) {\n throw new Error('VanillaImageEditor: container element is required')\n }\n\n this._container = container\n\n // Resolve preset: if a preset name or object is provided, resolve it\n // then merge with any explicit option overrides (options win over preset)\n const resolvedPreset = options.preset\n ? getPreset(options.preset)\n : null\n\n // Build effective options: defaults ← preset ← explicit options\n const presetOverrides = resolvedPreset ? {\n initialMode: resolvedPreset.initialMode === 'crop' ? 'crop' : 'adjust',\n cropShape: resolvedPreset.cropShape,\n initialAspectRatio: resolvedPreset.aspectRatio\n } : {}\n\n this._options = {\n theme: 'auto',\n initialImage: null,\n initialMode: 'adjust',\n cropShape: 'free',\n initialAspectRatio: 'free',\n backgroundRemoval: {\n enabled: true,\n endpoint: '/api/v1/media/remove-bg',\n fallbackEndpoint: null\n },\n ...presetOverrides,\n ...options\n }\n\n // Store the resolved preset for state flags and later use\n this._preset = resolvedPreset\n\n // Initialize state\n this._state = createState()\n\n // Set initial state from options\n this._state.set('theme', this._options.theme)\n this._state.set('crop.shape', this._options.cropShape)\n this._state.set('crop.aspect', this._options.initialAspectRatio)\n\n // Apply preset state flags\n if (this._preset) {\n this._state.set('lockCropShape', !!this._preset.lockCropShape)\n this._state.set('lockAspectRatio', !!this._preset.lockAspectRatio)\n this._state.set('showFilters', this._preset.showFilters !== false)\n this._state.set('showCropControls', this._preset.showCropControls !== false)\n this._state.set('autoZoomOnCropOverflow', !!this._preset.autoZoomOnCropOverflow)\n }\n\n // Initialize managers\n this._renderer = new PixiRenderer()\n this._filterManager = new FilterManager(this._state, this._renderer)\n this._cropManager = new CropManager(this._state, this._renderer)\n\n // Background removal manager (optional)\n this._removeBgManager = null\n if (this._options.backgroundRemoval?.enabled !== false) {\n this._removeBgManager = new RemoveBgManager({\n endpoint: this._options.backgroundRemoval?.endpoint,\n fallbackEndpoint: this._options.backgroundRemoval?.fallbackEndpoint\n })\n }\n\n // Loading overlay element\n this._loadingOverlay = null\n\n // Mobile detection\n this._isMobile = typeof window !== 'undefined' ? window.innerWidth <= 768 : false\n\n // UI components\n this._toolbar = null\n this._categoryCarousel = null\n this._filterCarousel = null\n this._filterAdjustments = null\n this._mobileFilterDrawer = null\n this._mobileActiveFilters = null\n this._cropControls = null\n this._activeFiltersPanel = null\n\n // DOM elements\n this._editorEl = null\n this._canvasContainer = null\n this._cropOverlay = null\n this._controlsSection = null\n this._filterControlsEl = null\n this._fileInput = null\n\n // Resize observer\n this._resizeObserver = null\n\n // Initialize\n this._init()\n }\n\n /**\n * Initialize the editor\n */\n async _init() {\n // Detect theme\n this._state.detectTheme()\n\n // Build DOM structure\n this._buildDOM()\n\n // Mount PIXI renderer\n await this._renderer.mount(\n this._canvasContainer,\n this._state.get('isDarkMode') ? 0x0a0a0a : 0xffffff\n )\n\n // Set crop overlay canvas\n this._cropManager.setOverlayCanvas(this._cropOverlay)\n\n // Initialize UI components\n this._initUI()\n\n // Set up resize handling\n this._setupResizeObserver()\n this._setupWindowResize()\n\n // Subscribe to state changes\n this._subscribeToState()\n\n // Load initial image if provided\n if (this._options.initialImage) {\n await this.loadImage(this._options.initialImage)\n }\n\n this.emit('ready')\n }\n\n /**\n * Build DOM structure\n */\n _buildDOM() {\n // Clear container\n this._container.innerHTML = ''\n\n // Main editor element\n this._editorEl = el('div', {\n className: `vanilla-image-editor ${this._state.get('isDarkMode') ? 'dark' : 'light'}`\n })\n\n // Toolbar\n const toolbarContainer = el('div', { className: 'editor-toolbar-container' })\n this._editorEl.appendChild(toolbarContainer)\n this._toolbarContainer = toolbarContainer\n\n // Content area (canvas + controls)\n const content = el('div', { className: 'editor-content' })\n\n // Canvas section\n const canvasSection = el('div', { className: 'canvas-section' })\n this._canvasContainer = el('div', { className: 'canvas-container' })\n\n // Crop overlay canvas (decorative — hidden from screen readers)\n this._cropOverlay = el('canvas', { className: 'crop-overlay', 'aria-hidden': 'true' })\n\n canvasSection.appendChild(this._canvasContainer)\n canvasSection.appendChild(this._cropOverlay)\n content.appendChild(canvasSection)\n\n // Controls section\n this._controlsSection = el('div', { className: 'controls-section' })\n content.appendChild(this._controlsSection)\n\n this._editorEl.appendChild(content)\n\n // Hidden file input\n this._fileInput = el('input', {\n type: 'file',\n accept: 'image/*',\n className: 'hidden-file-input',\n 'aria-label': 'Choose image file to edit',\n onChange: (e) => this._handleFileSelect(e)\n })\n this._editorEl.appendChild(this._fileInput)\n\n this._container.appendChild(this._editorEl)\n }\n\n /**\n * Initialize UI components\n */\n _initUI() {\n // Toolbar\n this._toolbar = new Toolbar(this._state, this)\n this._toolbarContainer.appendChild(this._toolbar.render())\n\n // Build filter controls container\n this._filterControlsEl = el('div', { className: 'filter-controls-container' })\n\n // Category carousel\n this._categoryCarousel = new CategoryCarousel(this._state, this)\n this._filterControlsEl.appendChild(this._categoryCarousel.render((categoryId) => {\n // Category selected\n }))\n\n // Two-column layout for filters\n const filterLayout = el('div', { className: 'filter-layout' })\n\n // Left column\n const leftColumn = el('div', { className: 'filter-left-column' })\n\n // Filter carousel\n this._filterCarousel = new FilterCarousel(this._state, this._filterManager)\n leftColumn.appendChild(this._filterCarousel.render({\n onToggle: (filterId, enabled) => this._handleFilterToggle(filterId, enabled),\n onSelect: (filterId) => {\n this._handleFilterSelect(filterId)\n // On mobile, open the drawer instead of inline adjustments\n if (this._isMobile && this._mobileFilterDrawer) {\n this._mobileFilterDrawer.open(filterId)\n }\n }\n }))\n\n // Filter adjustments\n this._filterAdjustments = new FilterAdjustments(this._state, this._filterManager)\n leftColumn.appendChild(this._filterAdjustments.render({\n onChange: (filterId, controlId, value) => this._handleFilterChange(filterId, controlId, value),\n onReset: (filterId) => this._handleFilterReset(filterId),\n onAction: (filterId, action) => this._handleFilterAction(filterId, action)\n }))\n\n filterLayout.appendChild(leftColumn)\n\n // Right column - Active filters panel\n const rightColumn = el('div', { className: 'filter-right-column' })\n this._activeFiltersPanel = new ActiveFiltersPanel(this._state, this._filterManager)\n rightColumn.appendChild(this._activeFiltersPanel.render({\n onRemove: (filterId) => this._handleFilterToggle(filterId, false),\n onReset: (filterId) => this._handleFilterReset(filterId),\n onClearAll: () => this.resetAll(),\n onSelect: (filterId) => this._handleFilterSelect(filterId)\n }))\n filterLayout.appendChild(rightColumn)\n\n this._filterControlsEl.appendChild(filterLayout)\n\n // Mobile active filters carousel (shown below filter carousel on mobile)\n this._mobileActiveFilters = new MobileActiveFilters(this._state, this._filterManager)\n this._filterControlsEl.appendChild(this._mobileActiveFilters.render({\n onToggle: (filterId, enabled) => this._handleFilterToggle(filterId, enabled),\n onSelect: (filterId) => {\n this._handleFilterSelect(filterId)\n if (this._isMobile && this._mobileFilterDrawer) {\n this._mobileFilterDrawer.open(filterId)\n }\n }\n }))\n\n // Crop controls\n this._cropControls = new CropControls(this._state, this._cropManager)\n this._cropControlsEl = this._cropControls.render()\n this._cropControlsEl.style.display = 'none'\n\n // Add to controls section\n this._controlsSection.appendChild(this._filterControlsEl)\n this._controlsSection.appendChild(this._cropControlsEl)\n\n // Mobile filter drawer (appended to controls section — sized to match it)\n this._mobileFilterDrawer = new MobileFilterDrawer(this._state, this._filterManager)\n this._mobileFilterDrawer.build(this._controlsSection, {\n onChange: (filterId, controlId, value) => this._handleFilterChange(filterId, controlId, value),\n onReset: (filterId) => this._handleFilterReset(filterId),\n onRemove: (filterId) => {\n this._handleFilterToggle(filterId, false)\n this._state.set('selectedFilter', null)\n },\n onAction: (filterId, action) => this._handleFilterAction(filterId, action)\n })\n }\n\n /**\n * Set up resize observer with debounce to prevent infinite loops.\n * Without debounce, PIXI renderer.resize() changes the canvas buffer\n * which triggers another ResizeObserver notification, causing a loop\n * that floods the console with \"ResizeObserver loop completed\" errors\n * and prevents the image from rendering (gray canvas).\n */\n _setupResizeObserver() {\n let resizeTimer = null\n this._resizeObserver = new ResizeObserver(() => {\n clearTimeout(resizeTimer)\n resizeTimer = setTimeout(() => {\n if (this._canvasContainer) {\n this._renderer.resizeTo(this._canvasContainer)\n if (this._state.get('mode') === 'crop') {\n this._cropManager.drawOverlay()\n }\n }\n }, 50)\n })\n this._resizeObserver.observe(this._canvasContainer)\n }\n\n /**\n * Set up window resize listener for mobile detection\n */\n _setupWindowResize() {\n this._handleWindowResize = () => {\n this._isMobile = window.innerWidth <= 768\n // Close drawer if switching to desktop\n if (!this._isMobile && this._mobileFilterDrawer?.isOpen) {\n this._mobileFilterDrawer.close()\n }\n }\n window.addEventListener('resize', this._handleWindowResize)\n }\n\n /**\n * Subscribe to state changes\n */\n _subscribeToState() {\n // Mode changes\n this._state.on('change:mode', ({ value }) => {\n this._updateModeUI(value)\n // Re-apply filters when returning from crop mode — crop may replace the sprite\n if (value === 'filters') {\n this._filterManager.applyFilters()\n }\n })\n\n // Theme changes\n this._state.on('change:isDarkMode', ({ value }) => {\n this._editorEl.classList.toggle('dark', value)\n this._editorEl.classList.toggle('light', !value)\n this._renderer.setBackgroundColor(value ? 0x0a0a0a : 0xffffff)\n })\n\n // Has image changes\n this._state.on('change:hasImage', ({ value }) => {\n this._editorEl.classList.toggle('has-image', value)\n })\n\n // Zoom changes from renderer\n this._renderer.on('zoomChange', (zoom) => {\n this._state.set('zoom', zoom)\n })\n }\n\n /**\n * Update UI based on mode\n * @param {string} mode\n */\n _updateModeUI(mode) {\n if (mode === 'crop') {\n this._filterControlsEl.style.display = 'none'\n this._cropControlsEl.style.display = ''\n // Close mobile drawer when entering crop mode\n if (this._mobileFilterDrawer?.isOpen) {\n this._mobileFilterDrawer.close()\n }\n } else {\n this._filterControlsEl.style.display = ''\n this._cropControlsEl.style.display = 'none'\n }\n }\n\n /**\n * Handle file selection\n * @param {Event} event\n */\n async _handleFileSelect(event) {\n const file = event.target.files?.[0]\n if (file) {\n await this.loadImage(file)\n }\n // Reset input\n this._fileInput.value = ''\n }\n\n /**\n * Handle filter toggle\n * @param {string} filterId\n * @param {boolean} enabled\n */\n _handleFilterToggle(filterId, enabled) {\n this._filterManager.toggle(filterId, enabled)\n }\n\n /**\n * Handle filter select\n * @param {string} filterId\n */\n _handleFilterSelect(filterId) {\n this._state.set('selectedFilter', filterId)\n }\n\n /**\n * Handle filter value change\n * @param {string} filterId\n * @param {string} controlId\n * @param {*} value\n */\n _handleFilterChange(filterId, controlId, value) {\n const inPlace = this._filterManager.updateValue(filterId, controlId, value)\n if (!inPlace) {\n this._filterManager.applyFilters()\n }\n this._renderer.render()\n }\n\n /**\n * Handle filter reset\n * @param {string} filterId\n */\n _handleFilterReset(filterId) {\n this._filterManager.resetValues(filterId)\n this._filterManager.applyFilters()\n }\n\n /**\n * Handle filter action (button click)\n * @param {string} filterId\n * @param {string} action\n */\n _handleFilterAction(filterId, action) {\n const instance = this._filterManager.getInstance(filterId)\n if (instance && typeof instance.updateUIParam === 'function') {\n instance.updateUIParam(action, true)\n this._filterManager.applyFilters()\n }\n }\n\n // ==================== Public API ====================\n\n /**\n * Set the filter registry (from mediables/filters)\n * @param {Object} registry - { getFilter, getAllFilters, getFiltersByCategory }\n */\n setFilterRegistry(registry) {\n this._filterManager.setRegistry(registry)\n }\n\n /**\n * Load an image into the editor\n * @param {string|File} imageSource - URL, data URL, or File object\n */\n async loadImage(imageSource) {\n let url = imageSource\n\n if (imageSource instanceof File) {\n url = await this._fileToDataUrl(imageSource)\n }\n\n await this._renderer.loadTexture(url)\n this._state.set('hasImage', true)\n this._state.set('imageUrl', url)\n\n // Apply initial mode from preset/options after image loads\n // Crop mode requires an image to be loaded first\n if (this._options.initialMode === 'crop') {\n this.setMode('crop')\n }\n\n this.emit('imageLoaded', { url })\n }\n\n /**\n * Convert a File to data URL\n * @param {File} file\n * @returns {Promise<string>}\n */\n _fileToDataUrl(file) {\n return new Promise((resolve, reject) => {\n const reader = new FileReader()\n reader.onload = () => resolve(reader.result)\n reader.onerror = reject\n reader.readAsDataURL(file)\n })\n }\n\n /**\n * Open the file picker dialog\n */\n openFilePicker() {\n this._fileInput?.click()\n }\n\n /**\n * Export the current image\n * @param {string} format - 'png' or 'jpeg'\n * @param {number} quality - Quality for jpeg (0-1)\n * @returns {string|null} Data URL\n */\n exportImage(format = 'png', quality = 0.92) {\n return this._renderer.exportImage(format, quality)\n }\n\n /**\n * Save the image (triggers download and emits 'save' event)\n */\n save() {\n if (!this._state.get('hasImage')) return\n\n this._state.set('isSaving', true)\n\n try {\n const dataUrl = this.exportImage('png', 0.92)\n if (!dataUrl) throw new Error('Failed to export image')\n\n const dimensions = {\n width: Math.round(this._renderer.sprite?.width || 0),\n height: Math.round(this._renderer.sprite?.height || 0)\n }\n\n // Trigger download\n const link = document.createElement('a')\n link.href = dataUrl\n link.download = `edited-image-${Date.now()}.png`\n document.body.appendChild(link)\n link.click()\n document.body.removeChild(link)\n\n this.emit('save', { imageData: dataUrl, dimensions })\n } catch (error) {\n this.emit('error', { error })\n } finally {\n this._state.set('isSaving', false)\n }\n }\n\n /**\n * Close the editor (emits 'cancel' event)\n */\n close() {\n this.emit('cancel')\n }\n\n /**\n * Set zoom level\n * @param {number} zoom\n */\n setZoom(zoom) {\n this._renderer.setZoom(zoom)\n }\n\n /**\n * Fit image to screen\n */\n fitToScreen() {\n this._renderer.fitToScreen()\n }\n\n /**\n * Reset all filters\n */\n resetAll() {\n this._filterManager.resetAll()\n }\n\n /**\n * Toggle theme\n */\n toggleTheme() {\n const isDark = this._state.get('isDarkMode')\n this._state.set('isDarkMode', !isDark)\n }\n\n /**\n * Set theme\n * @param {'light'|'dark'|'auto'} theme\n */\n setTheme(theme) {\n this._state.set('theme', theme)\n this._state.detectTheme()\n }\n\n /**\n * Set editor mode\n * @param {'filters'|'crop'} mode\n */\n setMode(mode) {\n if (mode === 'crop') {\n this._cropManager.enable()\n } else {\n this._cropManager.disable()\n }\n this._state.set('mode', mode)\n }\n\n /**\n * Get current state (for debugging)\n * @returns {Object}\n */\n getState() {\n return this._state.getAll()\n }\n\n // ==================== Background Removal ====================\n\n /**\n * Remove the background from the current image\n * @param {Object} options\n * @param {string} [options.tier='balanced'] - Quality tier: 'fast', 'balanced', 'best'\n * @param {string} [options.model] - Explicit model name (overrides tier)\n * @param {boolean} [options.alpha_matting=false] - Enable alpha matting for edge refinement\n * @returns {Promise<{model: string, processMs: string}>}\n */\n async removeBackground(options = {}) {\n if (!this._removeBgManager) {\n throw new Error('Background removal is not enabled')\n }\n\n if (!this._state.get('hasImage')) {\n throw new Error('No image loaded')\n }\n\n this._state.set('isProcessing', true)\n this._showLoadingOverlay('Removing background...')\n\n try {\n // Export current image state\n const imageData = this.exportImage('png')\n if (!imageData) {\n throw new Error('Failed to export image for background removal')\n }\n\n // Send to background removal service\n const result = await this._removeBgManager.removeBackground(imageData, options)\n\n // Load the result back into the editor\n await this.loadImage(result.dataUrl)\n\n this.emit('background-removed', {\n model: result.model,\n processMs: result.processMs\n })\n\n return {\n model: result.model,\n processMs: result.processMs\n }\n } catch (error) {\n this.emit('error', { error, context: 'background-removal' })\n throw error\n } finally {\n this._state.set('isProcessing', false)\n this._hideLoadingOverlay()\n }\n }\n\n /**\n * Check if background removal is available\n * @returns {Promise<boolean>}\n */\n async isBackgroundRemovalAvailable() {\n if (!this._removeBgManager) return false\n return this._removeBgManager.isAvailable()\n }\n\n // ==================== Loading Overlay ====================\n\n /**\n * Show the loading overlay\n * @param {string} message - Message to display\n */\n _showLoadingOverlay(message) {\n if (!this._loadingOverlay) {\n this._loadingOverlay = el('div', { className: 'editor-loading-overlay' }, [\n el('div', { className: 'editor-loading-spinner' }),\n el('div', { className: 'editor-loading-text' }, message)\n ])\n } else {\n const textEl = this._loadingOverlay.querySelector('.editor-loading-text')\n if (textEl) textEl.textContent = message\n }\n\n // Append to canvas section (above canvas)\n const canvasSection = this._canvasContainer?.parentElement\n if (canvasSection && !this._loadingOverlay.parentElement) {\n canvasSection.appendChild(this._loadingOverlay)\n }\n }\n\n /**\n * Hide the loading overlay\n */\n _hideLoadingOverlay() {\n this._loadingOverlay?.remove()\n }\n\n /**\n * Destroy the editor and clean up\n */\n destroy() {\n // Clean up resize observer\n this._resizeObserver?.disconnect()\n\n // Clean up managers\n this._renderer.destroy()\n this._cropManager.disable()\n\n // Clean up window resize listener\n if (this._handleWindowResize) {\n window.removeEventListener('resize', this._handleWindowResize)\n }\n\n // Clean up UI components\n this._toolbar?.destroy()\n this._categoryCarousel?.destroy()\n this._filterCarousel?.destroy()\n this._filterAdjustments?.destroy()\n this._mobileFilterDrawer?.destroy()\n this._mobileActiveFilters?.destroy()\n this._cropControls?.destroy()\n this._activeFiltersPanel?.destroy()\n\n // Remove DOM\n this._editorEl?.remove()\n\n // Clear references\n this._container = null\n this._state = null\n\n this.emit('destroyed')\n this.removeAllListeners()\n }\n}\n","/**\n * Filter Registry System\n * Centralized storage and management for filter definitions\n */\n// Since we can't directly import Filter, use any for now\n// and let the type system infer from usage\ntype Filter = any;\n\n/**\n * Interface for a filter control definition \n * Defines the UI representation of a filter parameter\n */\nexport interface ControlDefinition {\n id: string;\n type: 'slider' | 'toggle' | 'color' | 'select' | 'range' | 'button' | 'text';\n label: string;\n property?: string;\n action?: string;\n min?: number;\n max?: number;\n step?: number;\n default?: number | boolean | string;\n options?: Array<{ label: string; value: string | number }>;\n tooltip?: string;\n}\n\nexport type FilterMediaTarget = 'image' | 'video';\n\n/**\n * Interface for a filter definition\n * Contains all metadata needed to create and manage a filter\n */\nexport interface FilterDefinition {\n id: string;\n name: string;\n category: string;\n description?: string;\n thumbnail?: string;\n /**\n * Optional media compatibility tags.\n * Omitted means compatible with both image and video pipelines.\n */\n mediaTargets?: FilterMediaTarget[];\n createFilter: (params: Record<string, any>) => Filter;\n defaultParams: Record<string, any>;\n controls: ControlDefinition[];\n}\n\n// Filter registry storage\nconst filters = new Map<string, FilterDefinition>();\n\n// Category registry storage\nconst categories = new Map<string, string[]>();\n\nfunction isMediaCompatible(\n definition: FilterDefinition,\n target: FilterMediaTarget\n): boolean {\n if (!Array.isArray(definition.mediaTargets) || definition.mediaTargets.length === 0) {\n return true;\n }\n\n return definition.mediaTargets.includes(target);\n}\n\n/**\n * Register a filter in the global registry\n * @param definition The filter definition to register\n * @returns The provided filter definition (for chaining)\n */\nexport function registerFilter(definition: FilterDefinition): FilterDefinition {\n // Ensure the filter has a unique ID\n if (filters.has(definition.id)) {\n console.warn(`Filter with ID ${definition.id} already exists. Overwriting.`);\n }\n \n // Store the filter definition\n filters.set(definition.id, definition);\n \n // Add to category registry\n if (!categories.has(definition.category)) {\n categories.set(definition.category, []);\n }\n categories.get(definition.category)?.push(definition.id);\n \n return definition;\n}\n\n/**\n * Get a filter definition by ID\n * @param id The ID of the filter to retrieve\n * @returns The filter definition or undefined if not found\n */\nexport function getFilter(id: string): FilterDefinition | undefined {\n return filters.get(id);\n}\n\n/**\n * Get all registered filter definitions\n * @returns Array of all registered filter definitions\n */\nexport function getAllFilters(): FilterDefinition[] {\n return Array.from(filters.values());\n}\n\n/**\n * NEW: Bulk-register all classes re-exported by the `pixi-filters` bundle.\n * – Keeps bundle size reasonable (tree-shaken in prod)\n * – Lets you use *any* filter without first writing boilerplate\n */\nimport * as PixiFilters from 'pixi-filters';\n\n/**\n * Register all core PixiJS filters if they don't already have custom definitions,\n * but only using the actual custom definitions from their respective files.\n */\nexport function registerCorePixiFilters(): void {\n // Get the filters that are already loaded\n const customFilterIds = getAllFilters().map(f => f.id);\n \n // Get all available PixiJS filters from the pixi-filters package\n type FilterConstructor = new (...args: unknown[]) => unknown\n\n const pixiFilterEntries = Object.entries(PixiFilters) as Array<[string, unknown]>\n\n const pixiFilterClasses = pixiFilterEntries.filter(\n (entry): entry is [string, FilterConstructor] => /Filter$/.test(entry[0]) && typeof entry[1] === 'function'\n );\n \n // Reduce logging in production\n if (import.meta.env.DEV) {\n // Only log filter count, not the entire list\n console.log(`Found ${customFilterIds.length} custom filters and ${pixiFilterClasses.length} PixiJS filters`);\n }\n \n // We'll ONLY register core filters where we DON'T have a custom definition\n // This is intentionally minimalist to ensure we prioritize custom definitions\n let newlyRegisteredCount = 0;\n \n pixiFilterClasses.forEach(([exportName, FilterClass]) => {\n const id = exportName\n .replace(/Filter$/, '')\n .replace(/([a-z0-9])([A-Z])/g, '$1-$2')\n .toLowerCase();\n \n // Skip if this filter already has a custom definition\n if (filters.has(id)) {\n return;\n }\n \n // For remaining filters without custom definitions, just provide a minimal registration\n // that just allows the filter to be created but doesn't provide any controls\n // Reduce verbose logging in production\n if (import.meta.env.DEV) {\n console.debug(`Registering minimal entry for ${exportName}`);\n }\n newlyRegisteredCount++;\n \n // Register with minimal information - these won't appear in the UI properly\n // but will be available for debugging or programmatic use\n registerFilter({\n id,\n name: exportName.replace(/Filter$/, ''),\n category: 'unlisted', // Put in a category that won't be shown in UI\n mediaTargets: ['image'],\n defaultParams: {},\n controls: [], // No controls - we don't want to add generic controls\n createFilter: (params = {}) => {\n try {\n // Simply create the filter with params\n return new FilterClass(params);\n } catch (error) {\n console.error(`Error creating filter ${id}:`, error);\n return null;\n }\n },\n });\n });\n \n // Only log in development environment\n if (import.meta.env.DEV && newlyRegisteredCount > 0) {\n console.log(`Registered ${newlyRegisteredCount} additional filters`);\n }\n}\n\n// We will NOT auto-register at module load. \n// Instead, custom filter definitions will be loaded first, then we'll only register missing ones.\n// The actual registration happens when initializeFilterRegistry is called.\n\n/**\n * Get all filters in a specific category\n * @param category The category to retrieve filters for\n * @returns Array of filter definitions in the requested category\n */\nexport function getFiltersByCategory(category: string): FilterDefinition[] {\n const filterIds = categories.get(category) || [];\n return filterIds.map(id => filters.get(id)).filter(Boolean) as FilterDefinition[];\n}\n\n/**\n * Get all filter categories\n * @returns Array of category names\n */\nexport function getAllCategories(): string[] {\n return Array.from(categories.keys());\n}\n\n/**\n * Check if a filter is registered\n * @param id The ID of the filter to check\n * @returns True if the filter is registered, false otherwise\n */\nexport function hasFilter(id: string): boolean {\n return filters.has(id);\n}\n\n/**\n * Remove a filter from the registry.\n * @param id The ID of the filter to remove\n * @returns True if the filter was found and removed\n */\nexport function unregisterFilter(id: string): boolean {\n const definition = filters.get(id);\n if (!definition) {\n return false;\n }\n\n filters.delete(id);\n\n // Remove from category index\n const categoryIds = categories.get(definition.category);\n if (categoryIds) {\n const idx = categoryIds.indexOf(id);\n if (idx !== -1) {\n categoryIds.splice(idx, 1);\n }\n if (categoryIds.length === 0) {\n categories.delete(definition.category);\n }\n }\n\n return true;\n}\n\n/**\n * Check whether a registered filter is compatible with a media target.\n * Unknown filters are treated as incompatible.\n */\nexport function isFilterCompatibleWithMedia(\n id: string,\n target: FilterMediaTarget\n): boolean {\n const definition = filters.get(id);\n if (!definition) {\n return false;\n }\n\n return isMediaCompatible(definition, target);\n}\n\n/**\n * Return all registered filters compatible with the given media target.\n */\nexport function getFiltersByMedia(target: FilterMediaTarget): FilterDefinition[] {\n return Array.from(filters.values()).filter((definition) => isMediaCompatible(definition, target));\n}\n\n/**\n * Get all registered filters with simplified format for UI\n * @returns Array of filter definitions with only UI-relevant properties\n */\nexport function getRegisteredFilters(): Array<{\n id: string;\n name: string;\n category: string;\n controls: ControlDefinition[];\n}> {\n return Array.from(filters.values()).map(filter => ({\n id: filter.id,\n name: filter.name,\n category: filter.category,\n controls: filter.controls\n }));\n}\n\n// Add a debug function to expose filter registry in window\nif (typeof window !== 'undefined') {\n // Store filter list in window for debugging\n (window as any).__DEBUG_FILTERS_LIST = Array.from(filters.keys());\n \n // Expose registry functions for debugging\n (window as any).getAllFilters = getAllFilters;\n (window as any).getFilter = getFilter;\n (window as any).getFiltersByCategory = getFiltersByCategory;\n (window as any).getRegisteredFilters = getRegisteredFilters;\n \n // Update the debug list whenever a new filter is registered\n const originalRegisterFilter = registerFilter;\n (window as any).registerFilter = (definition: FilterDefinition) => {\n const result = originalRegisterFilter(definition);\n (window as any).__DEBUG_FILTERS_LIST = Array.from(filters.keys());\n console.log(`Filter \"${definition.id}\" registered. Total filters: ${filters.size}`);\n return result;\n };\n \n // Remove this console log - it's causing duplicate logging\n // if (process.env.NODE_ENV !== 'production') {\n // console.log(`Registry initialized with ${filters.size} filters`);\n // }\n}\n\n// Add a safety check for initializeFilterRegistry in case it's not working\n// This is a fallback in case the main implementation is facing issues\nif (typeof window !== 'undefined') {\n (window as any).initializeFilterRegistry = (window as any).initializeFilterRegistry || function() {\n console.warn('Using fallback window.initializeFilterRegistry');\n return [];\n };\n}\n","/**\n * Adjustment Filter Definition\n * Controls basic image adjustments like brightness, contrast, saturation, etc.\n */\nimport { registerFilter } from '../registry';\n// Import the AdjustmentFilter directly from the pixi-filters package\nimport * as PixiFilters from 'pixi-filters';\n// Access AdjustmentFilter from the pixi-filters package\nconst { AdjustmentFilter } = PixiFilters;\n\n// Import ColorMatrixFilter as fallback\nimport * as PIXI from 'pixi.js';\n// Access ColorMatrixFilter from pixi.js package\nconst { ColorMatrixFilter } = PIXI;\n\ninterface AdjustmentParams {\n gamma: number;\n saturation: number;\n contrast: number;\n brightness: number;\n red: number;\n green: number;\n blue: number;\n alpha: number;\n}\n\ntype AdjustmentParamKey = keyof AdjustmentParams;\n\nconst DEFAULT_ADJUSTMENT_PARAMS: AdjustmentParams = {\n gamma: 1,\n saturation: 1,\n contrast: 1,\n brightness: 1,\n red: 1,\n green: 1,\n blue: 1,\n alpha: 1,\n};\n\nconst ADJUSTMENT_PARAM_KEYS = new Set<AdjustmentParamKey>([\n 'gamma',\n 'saturation',\n 'contrast',\n 'brightness',\n 'red',\n 'green',\n 'blue',\n 'alpha',\n]);\n\nfunction toFiniteNumber(value: unknown, fallback: number): number {\n if (typeof value === 'number' && Number.isFinite(value)) {\n return value;\n }\n\n if (typeof value === 'string') {\n const parsed = Number(value);\n if (Number.isFinite(parsed)) {\n return parsed;\n }\n }\n\n return fallback;\n}\n\nfunction isAdjustmentParamKey(key: string): key is AdjustmentParamKey {\n return ADJUSTMENT_PARAM_KEYS.has(key as AdjustmentParamKey);\n}\n\nfunction normalizeAdjustmentParams(params: Record<string, unknown>): AdjustmentParams {\n return {\n gamma: toFiniteNumber(params.gamma, DEFAULT_ADJUSTMENT_PARAMS.gamma),\n saturation: toFiniteNumber(params.saturation, DEFAULT_ADJUSTMENT_PARAMS.saturation),\n contrast: toFiniteNumber(params.contrast, DEFAULT_ADJUSTMENT_PARAMS.contrast),\n brightness: toFiniteNumber(params.brightness, DEFAULT_ADJUSTMENT_PARAMS.brightness),\n red: toFiniteNumber(params.red, DEFAULT_ADJUSTMENT_PARAMS.red),\n green: toFiniteNumber(params.green, DEFAULT_ADJUSTMENT_PARAMS.green),\n blue: toFiniteNumber(params.blue, DEFAULT_ADJUSTMENT_PARAMS.blue),\n alpha: toFiniteNumber(params.alpha, DEFAULT_ADJUSTMENT_PARAMS.alpha),\n };\n}\n\nfunction applyColorMatrixAdjustments(filter: PIXI.ColorMatrixFilter, params: AdjustmentParams): void {\n filter.reset();\n\n // ColorMatrixFilter operations must be multiplied to compose adjustments.\n filter.brightness(params.brightness, true);\n filter.contrast(params.contrast, true);\n filter.saturate(params.saturation, true);\n}\n\n// Register the adjustment filter\nexport default registerFilter({\n id: 'adjustment',\n name: 'Adjustment',\n category: 'adjust',\n description: 'Adjust basic image properties like brightness, contrast, and saturation',\n \n // Create an instance of the AdjustmentFilter with the provided parameters\n createFilter: (params) => {\n try {\n const normalizedParams = normalizeAdjustmentParams((params ?? {}) as Record<string, unknown>);\n console.log('Creating AdjustmentFilter with params:', normalizedParams);\n \n // Create options object for filter parameters\n const options = { ...normalizedParams };\n \n // Attempt to create AdjustmentFilter first (preferred)\n try {\n const filter = new AdjustmentFilter(options);\n\n type AdjustmentFilterWithUI = typeof filter & {\n _customParams?: AdjustmentParams;\n updateUIParam?: (key: string, value: unknown) => void;\n };\n const filterWithUI = filter as AdjustmentFilterWithUI;\n\n // Add custom updateUIParam method for dynamic updates\n filterWithUI._customParams = { ...normalizedParams };\n filterWithUI.updateUIParam = function updateUIParam(key: string, value: unknown): void {\n try {\n if (!isAdjustmentParamKey(key)) {\n return;\n }\n\n const customParams = this._customParams ?? { ...DEFAULT_ADJUSTMENT_PARAMS };\n const numericValue = toFiniteNumber(value, customParams[key]);\n customParams[key] = numericValue;\n this._customParams = customParams;\n\n const target = this as unknown as Record<string, unknown>;\n if (key in target) {\n target[key] = numericValue;\n }\n } catch (error) {\n console.error(`Error updating AdjustmentFilter parameter ${key}:`, error);\n }\n };\n \n console.log('AdjustmentFilter created successfully');\n return filter;\n } catch (error) {\n console.warn('Failed to create AdjustmentFilter, falling back to ColorMatrixFilter:', error);\n \n // Fall back to ColorMatrixFilter if AdjustmentFilter fails\n const filter = new ColorMatrixFilter();\n\n type ColorMatrixWithUI = typeof filter & {\n _customParams?: AdjustmentParams;\n updateUIParam?: (key: string, value: unknown) => void;\n };\n const filterWithUI = filter as ColorMatrixWithUI;\n\n // Store original parameters\n filterWithUI._customParams = { ...normalizedParams };\n\n // Apply initial adjustments as a composed matrix.\n applyColorMatrixAdjustments(filter, normalizedParams);\n \n // Add custom update method\n filterWithUI.updateUIParam = function updateUIParam(key: string, value: unknown): void {\n try {\n if (!isAdjustmentParamKey(key)) {\n return;\n }\n\n const customParams = this._customParams ?? { ...DEFAULT_ADJUSTMENT_PARAMS };\n const numericValue = toFiniteNumber(value, customParams[key]);\n customParams[key] = numericValue;\n this._customParams = customParams;\n\n applyColorMatrixAdjustments(this, customParams);\n } catch (error) {\n console.error(`Error updating ColorMatrixFilter parameter ${key}:`, error);\n }\n };\n \n console.log('ColorMatrixFilter created as fallback');\n return filter;\n }\n } catch (error) {\n console.error('Failed to create any adjustment filter:', error);\n return null;\n }\n },\n \n // Default parameter values\n defaultParams: {\n gamma: 1,\n saturation: 1,\n contrast: 1,\n brightness: 1,\n red: 1,\n green: 1,\n blue: 1,\n alpha: 1,\n },\n \n // UI controls for the filter\n controls: [\n {\n id: 'brightness',\n type: 'slider',\n label: 'Brightness',\n property: 'brightness',\n min: 0,\n max: 5,\n step: 0.01,\n default: 1,\n },\n {\n id: 'contrast',\n type: 'slider',\n label: 'Contrast',\n property: 'contrast',\n min: 0,\n max: 5,\n step: 0.01,\n default: 1,\n },\n {\n id: 'saturation',\n type: 'slider',\n label: 'Saturation',\n property: 'saturation',\n min: 0,\n max: 5,\n step: 0.01,\n default: 1,\n },\n {\n id: 'gamma',\n type: 'slider',\n label: 'Gamma',\n property: 'gamma',\n min: 0,\n max: 5,\n step: 0.01,\n default: 1,\n },\n {\n id: 'red',\n type: 'slider',\n label: 'Red',\n property: 'red',\n min: 0,\n max: 5,\n step: 0.01,\n default: 1,\n },\n {\n id: 'green',\n type: 'slider',\n label: 'Green',\n property: 'green',\n min: 0,\n max: 5,\n step: 0.01,\n default: 1,\n },\n {\n id: 'blue',\n type: 'slider',\n label: 'Blue',\n property: 'blue',\n min: 0,\n max: 5,\n step: 0.01,\n default: 1,\n },\n {\n id: 'alpha',\n type: 'slider',\n label: 'Alpha',\n property: 'alpha',\n min: 0,\n max: 1,\n step: 0.01,\n default: 1,\n },\n ],\n});\n","/**\n * Advanced Adjustment Filter Definition\n * Provides advanced image adjustment options with a single filter\n */\nimport { registerFilter } from '../registry';\n// Import ColorMatrixFilter directly\nimport * as PIXI from 'pixi.js';\n// Access ColorMatrixFilter class\nconst { ColorMatrixFilter } = PIXI;\n\ninterface AdvancedAdjustmentParams {\n brightness: number;\n contrast: number;\n saturation: number;\n hue: number;\n sepia: number;\n negative: boolean;\n}\n\ntype AdvancedAdjustmentParamKey = keyof AdvancedAdjustmentParams;\n\nconst DEFAULT_ADVANCED_ADJUSTMENT_PARAMS: AdvancedAdjustmentParams = {\n brightness: 1,\n contrast: 1,\n saturation: 1,\n hue: 0,\n sepia: 0,\n negative: false,\n};\n\nconst ADVANCED_ADJUSTMENT_PARAM_KEYS = new Set<AdvancedAdjustmentParamKey>([\n 'brightness',\n 'contrast',\n 'saturation',\n 'hue',\n 'sepia',\n 'negative',\n]);\n\nfunction isAdvancedAdjustmentParamKey(key: string): key is AdvancedAdjustmentParamKey {\n return ADVANCED_ADJUSTMENT_PARAM_KEYS.has(key as AdvancedAdjustmentParamKey);\n}\n\nfunction toFiniteNumber(value: unknown, fallback: number): number {\n if (typeof value === 'number' && Number.isFinite(value)) {\n return value;\n }\n\n if (typeof value === 'string') {\n const parsed = Number(value);\n if (Number.isFinite(parsed)) {\n return parsed;\n }\n }\n\n return fallback;\n}\n\nfunction toBoolean(value: unknown, fallback: boolean): boolean {\n if (typeof value === 'boolean') {\n return value;\n }\n\n if (typeof value === 'string') {\n if (value === 'true') {\n return true;\n }\n if (value === 'false') {\n return false;\n }\n }\n\n return fallback;\n}\n\nfunction normalizeAdvancedAdjustmentParams(params: Record<string, unknown>): AdvancedAdjustmentParams {\n return {\n brightness: toFiniteNumber(params.brightness, DEFAULT_ADVANCED_ADJUSTMENT_PARAMS.brightness),\n contrast: toFiniteNumber(params.contrast, DEFAULT_ADVANCED_ADJUSTMENT_PARAMS.contrast),\n saturation: toFiniteNumber(params.saturation, DEFAULT_ADVANCED_ADJUSTMENT_PARAMS.saturation),\n hue: toFiniteNumber(params.hue, DEFAULT_ADVANCED_ADJUSTMENT_PARAMS.hue),\n sepia: toFiniteNumber(params.sepia, DEFAULT_ADVANCED_ADJUSTMENT_PARAMS.sepia),\n negative: toBoolean(params.negative, DEFAULT_ADVANCED_ADJUSTMENT_PARAMS.negative),\n };\n}\n\nfunction applyAdvancedAdjustments(filter: PIXI.ColorMatrixFilter, params: AdvancedAdjustmentParams): void {\n // Reset first so we always apply from a clean identity matrix.\n filter.reset();\n\n if (params.brightness !== 1) {\n filter.brightness(params.brightness, true);\n }\n\n if (params.contrast !== 1) {\n filter.contrast(params.contrast, true);\n }\n\n if (params.saturation !== 1) {\n filter.saturate(params.saturation, true);\n }\n\n if (params.hue !== 0) {\n filter.hue(params.hue, true);\n }\n\n if (params.sepia > 0) {\n filter.sepia(true);\n }\n\n if (params.negative) {\n filter.negative(true);\n }\n}\n\n// Register the advanced adjustment filter\nexport default registerFilter({\n id: 'adjustment-advanced',\n name: 'Advanced Adjustment',\n category: 'adjust',\n description: 'Comprehensive image adjustments including brightness, contrast, saturation, hue, and more',\n \n // Create an instance of the ColorMatrixFilter with the provided parameters\n createFilter: (params) => {\n try {\n const normalizedParams = normalizeAdvancedAdjustmentParams((params ?? {}) as Record<string, unknown>);\n console.log('Creating Advanced Adjustment filter with params:', normalizedParams);\n \n // Create filter instance\n const filter = new ColorMatrixFilter();\n\n type AdvancedFilterWithUI = typeof filter & {\n _customParams?: AdvancedAdjustmentParams;\n updateUIParam?: (key: string, value: unknown) => void;\n };\n const filterWithUI = filter as AdvancedFilterWithUI;\n\n // Store custom parameters for later reference\n filterWithUI._customParams = { ...normalizedParams };\n\n // Apply initial adjustments from full parameter set.\n applyAdvancedAdjustments(filter, normalizedParams);\n \n // Add custom updateUIParam method for dynamic updates\n filterWithUI.updateUIParam = function updateUIParam(key: string, value: unknown): void {\n try {\n if (!isAdvancedAdjustmentParamKey(key)) {\n return;\n }\n\n const customParams = this._customParams ?? { ...DEFAULT_ADVANCED_ADJUSTMENT_PARAMS };\n if (key === 'negative') {\n customParams.negative = toBoolean(value, customParams.negative);\n } else {\n const numericKey = key as Exclude<AdvancedAdjustmentParamKey, 'negative'>;\n customParams[numericKey] = toFiniteNumber(value, customParams[numericKey]);\n }\n\n this._customParams = customParams;\n applyAdvancedAdjustments(this, customParams);\n } catch (error) {\n console.error(`Error updating Advanced Adjustment parameter ${key}:`, error);\n }\n };\n \n console.log('Advanced Adjustment filter created successfully');\n return filter;\n } catch (error) {\n console.error('Failed to create Advanced Adjustment filter:', error);\n return null;\n }\n },\n \n // Default parameter values\n defaultParams: {\n brightness: 1,\n contrast: 1,\n saturation: 1,\n hue: 0,\n sepia: 0,\n negative: false\n },\n \n // UI controls for the filter\n controls: [\n {\n id: 'brightness',\n type: 'slider',\n label: 'Brightness',\n property: 'brightness',\n min: 0,\n max: 2,\n step: 0.01,\n default: 1,\n },\n {\n id: 'contrast',\n type: 'slider',\n label: 'Contrast',\n property: 'contrast',\n min: 0,\n max: 2,\n step: 0.01,\n default: 1,\n },\n {\n id: 'saturation',\n type: 'slider',\n label: 'Saturation',\n property: 'saturation',\n min: 0,\n max: 2,\n step: 0.01,\n default: 1,\n },\n {\n id: 'hue',\n type: 'slider',\n label: 'Hue Rotation',\n property: 'hue',\n min: 0,\n max: 360,\n step: 1,\n default: 0,\n },\n {\n id: 'sepia',\n type: 'slider',\n label: 'Sepia',\n property: 'sepia',\n min: 0,\n max: 1,\n step: 0.01,\n default: 0,\n },\n {\n id: 'negative',\n type: 'toggle',\n label: 'Negative',\n property: 'negative',\n default: false,\n },\n ],\n});\n","/**\n * Alpha Filter Definition\n * Adjusts the transparency of the image using ColorMatrixFilter\n */\nimport { registerFilter } from '../registry';\nimport * as PIXI from 'pixi.js';\n\n// Register the alpha filter (uses the ColorMatrixFilter behind the scenes)\nexport default registerFilter({\n id: 'alpha',\n name: 'Alpha',\n category: 'adjust',\n description: 'Adjust the transparency of the image',\n \n // Create an instance of the ColorMatrixFilter with alpha adjustment\n createFilter: (params) => {\n try {\n console.log('Creating Alpha filter with params:', params);\n \n // The alpha value from the parameters\n const alpha = params.alpha !== undefined ? params.alpha : 1.0;\n \n // Create a ColorMatrixFilter which has built-in alpha control\n const filter = new PIXI.ColorMatrixFilter();\n filter.alpha = alpha;\n \n // Store custom parameters for reference\n (filter as any)._customParams = {\n alpha: alpha\n };\n \n // Add custom updateUIParam method for dynamic updates\n (filter as any).updateUIParam = function(key: string, value: any) {\n try {\n console.log(`Alpha filter updateUIParam called: ${key} = ${value}`);\n \n // Store UI parameters for reference\n const customParams = (this as any)._customParams || {};\n (this as any)._customParams = customParams;\n \n // Handle alpha parameter specifically\n if (key === 'alpha') {\n const numValue = Number(value);\n \n // Set alpha through the ColorMatrixFilter's built-in method\n this.alpha = numValue;\n customParams.alpha = numValue;\n \n console.log(`Updated alpha to ${numValue}`);\n } else {\n // For any other properties, try direct assignment\n if (key in this) {\n (this as any)[key] = value;\n console.log(`Updated ${key} to ${value}`);\n } else {\n console.warn(`Unknown parameter for Alpha filter: ${key}`);\n }\n }\n } catch (error) {\n console.error(`Error updating Alpha filter parameter ${key}:`, error);\n }\n };\n \n console.log('Alpha filter created successfully');\n return filter;\n } catch (error) {\n console.error('Failed to create Alpha filter:', error);\n return null;\n }\n },\n \n // Default parameter values\n defaultParams: {\n alpha: 1.0\n },\n \n // UI controls for the filter\n controls: [\n {\n id: 'alpha',\n type: 'slider',\n label: 'Transparency',\n property: 'alpha',\n min: 0,\n max: 1,\n step: 0.01,\n default: 1.0,\n }\n ],\n});","/**\n * Blur Filter Definition\n * Applies a Gaussian blur effect to the image\n * \n * This implementation uses the proper BlurFilter from pixi.js\n * which is compatible with PixiJS v8\n */\nimport { registerFilter } from '../registry';\n// Import PIXI namespace\nimport * as PIXI from 'pixi.js';\n\n// Register the blur filter\nexport default registerFilter({\n id: 'blur',\n name: 'Blur',\n category: 'blur',\n description: 'Apply a smooth blur effect to the entire image',\n \n /**\n * Create an instance of the BlurFilter from pixi.js package\n * This implementation matches the PixiJS example exactly, using 'blur' and 'quality' parameters\n */\n createFilter: (params) => {\n try {\n console.log('Creating BlurFilter with params:', params);\n \n // Create filter with proper options object for v8\n const filter = new PIXI.BlurFilter({\n strength: params.blur || 8,\n quality: params.quality || 4\n });\n \n // Store custom parameters for later reference\n (filter as any)._customParams = { ...params };\n \n /**\n * Add a custom updateUIParam method to handle UI parameter updates\n * This is called by PixiApplication.updateFilter when UI controls change\n * and provides consistent parameter handling across all filters.\n * \n * @param key The UI parameter name\n * @param value The new value for the parameter\n */\n (filter as any).updateUIParam = function(key: string, value: any) {\n // Store UI parameters for later reference\n const customParams = (this as any)._customParams || {};\n (this as any)._customParams = customParams;\n \n // Update the stored params value\n customParams[key] = value;\n \n // Handle parameter updates based on key\n switch (key) {\n case 'blur':\n this.strength = value; // PixiJS BlurFilter uses 'strength' internally\n console.log(`Updated blur to ${this.strength}`);\n break;\n \n case 'quality':\n this.quality = value;\n console.log(`Updated quality to ${this.quality}`);\n break;\n \n // For any other properties, try direct assignment \n default:\n if (key in this) {\n (this as any)[key] = value;\n console.log(`Updated ${key} to ${value}`);\n } else {\n console.warn(`Attempted to update unknown property ${key}`);\n }\n break;\n }\n \n return true;\n };\n \n console.log('BlurFilter created successfully with updateUIParam method');\n return filter;\n } catch (error) {\n console.error('Failed to create BlurFilter:', error);\n return null;\n }\n },\n \n // Default parameter values\n defaultParams: {\n blur: 8,\n quality: 4,\n },\n \n // UI controls for the filter - matching PixiJS example exactly\n controls: [\n {\n id: 'blur',\n type: 'slider',\n label: 'Blur',\n property: 'blur',\n min: 0,\n max: 100,\n step: 0.1,\n default: 8,\n },\n {\n id: 'quality',\n type: 'slider',\n label: 'Quality',\n property: 'quality',\n min: 1,\n max: 10,\n step: 1,\n default: 4,\n },\n ],\n});","/**\n * Color Matrix Filter Definition\n * Applies various color transformations using a color matrix\n */\nimport * as PIXI from 'pixi.js';\nimport { registerFilter } from '../registry';\n\n// Register the color matrix filter\nexport default registerFilter({\n id: 'color-matrix',\n name: 'Color Matrix',\n category: 'advanced',\n description: 'Advanced color adjustments including sepia, hue rotation, and more',\n \n // Create an instance of the ColorMatrixFilter with the provided parameters\n createFilter: (params) => {\n // ColorMatrixFilter is available directly from PIXI in v8+\n const MatrixFilterClass = PIXI.ColorMatrixFilter;\n \n if (!MatrixFilterClass) {\n console.error('ColorMatrixFilter not available in PIXI');\n return null;\n }\n \n const filter = new MatrixFilterClass();\n \n try {\n // Reset the matrix first\n if (typeof filter.reset === 'function') {\n filter.reset();\n }\n \n // Apply color adjustments based on parameters\n // ColorMatrixFilter methods take two parameters: value and multiply (false for direct setting)\n if (params.brightness !== 1 && typeof filter.brightness === 'function') {\n filter.brightness(params.brightness, false);\n }\n \n if (params.contrast !== 1 && typeof filter.contrast === 'function') {\n filter.contrast(params.contrast, false);\n }\n \n if (params.saturation !== 1 && typeof filter.saturate === 'function') {\n filter.saturate(params.saturation, false);\n }\n \n if (params.hue !== 0 && typeof filter.hue === 'function') {\n filter.hue(params.hue, false);\n }\n \n if (params.sepia > 0 && typeof filter.sepia === 'function') {\n filter.sepia(params.sepia);\n }\n \n if (params.negative && typeof filter.negative === 'function') {\n filter.negative(false);\n }\n \n return filter;\n } catch (error) {\n console.error('Error configuring ColorMatrixFilter:', error);\n return filter; // Return basic filter if methods are missing\n }\n },\n \n // Default parameter values\n defaultParams: {\n brightness: 1,\n contrast: 1,\n saturation: 1,\n hue: 0,\n sepia: 0,\n negative: false\n },\n \n // UI controls for the filter\n controls: [\n {\n id: 'brightness',\n type: 'slider',\n label: 'Brightness',\n property: 'brightness',\n min: 0,\n max: 5,\n step: 0.1,\n default: 1,\n },\n {\n id: 'contrast',\n type: 'slider',\n label: 'Contrast',\n property: 'contrast',\n min: 0,\n max: 5,\n step: 0.1,\n default: 1,\n },\n {\n id: 'saturation',\n type: 'slider',\n label: 'Saturation',\n property: 'saturation',\n min: 0,\n max: 5,\n step: 0.1,\n default: 1,\n },\n {\n id: 'hue',\n type: 'slider',\n label: 'Hue Rotation',\n property: 'hue',\n min: -180,\n max: 180,\n step: 1,\n default: 0,\n },\n {\n id: 'sepia',\n type: 'slider',\n label: 'Sepia',\n property: 'sepia',\n min: 0,\n max: 1,\n step: 0.01,\n default: 0,\n },\n {\n id: 'negative',\n type: 'toggle',\n label: 'Negative',\n property: 'negative',\n default: false,\n },\n ],\n});","/**\n * Color Overlay Filter Definition\n * Applies a colored overlay to the entire image\n * \n * This implementation uses the proper ColorOverlayFilter from pixi-filters\n * which is compatible with PixiJS v8\n */\nimport { registerFilter } from '../registry';\n// Import from the central package for pixi filters\nimport * as PixiFilters from 'pixi-filters';\n// Access ColorOverlayFilter from the pixi-filters package\nconst { ColorOverlayFilter } = PixiFilters;\n\n// Register the color overlay filter\nexport default registerFilter({\n id: 'colorOverlay',\n name: 'Color Overlay',\n category: 'color',\n description: 'Apply a colored tint or overlay to the entire image',\n \n /**\n * Create an instance of ColorOverlayFilter from pixi-filters package\n * This implementation follows the pattern from ColorGradientFilter, adding\n * proper parameter handling with an updateUIParam method\n */\n createFilter: (params) => {\n try {\n console.log('Creating ColorOverlayFilter with params:', params);\n \n // Parse color string to number if needed\n let colorValue = 0xff0000; // Default red\n if (params.color) {\n if (typeof params.color === 'string') {\n colorValue = parseInt(params.color.replace('#', '0x'), 16);\n } else if (typeof params.color === 'number') {\n colorValue = params.color;\n }\n }\n \n // Create filter with the ColorOverlayFilter from pixi-filters\n // Using the options object syntax for v6+\n console.log('Creating ColorOverlayFilter with options object:', {\n color: colorValue,\n alpha: params.alpha || 0.5\n });\n \n const filter = new ColorOverlayFilter({\n color: colorValue,\n alpha: params.alpha || 0.5\n });\n \n // Store custom parameters for later reference\n (filter as any)._customParams = { ...params };\n \n /**\n * Add a custom updateUIParam method to handle UI parameter updates\n * This is called by PixiApplication.updateFilter when UI controls change\n * and provides consistent parameter handling across all filters.\n * \n * @param key The UI parameter name\n * @param value The new value for the parameter\n */\n (filter as any).updateUIParam = function(key: string, value: any) {\n // Store UI parameters for later reference\n const customParams = (this as any)._customParams || {};\n (this as any)._customParams = customParams;\n \n // Update the stored params value\n customParams[key] = value;\n \n // Handle parameter updates based on key\n // IMPORTANT: Must update BOTH the JS property AND the shader uniform\n // The JS property is used for state tracking, but the shader uses uniforms for rendering\n switch (key) {\n case 'color':\n // Convert hex string to number for the color property\n let colorNum: number;\n if (typeof value === 'string') {\n colorNum = parseInt(value.replace('#', '0x'), 16);\n } else {\n colorNum = Number(value);\n }\n this.color = colorNum;\n if (this.uniforms) this.uniforms.uColor = colorNum;\n console.log(`Updated color to ${colorNum}`);\n break;\n\n case 'alpha':\n // Direct alpha update\n this.alpha = Number(value);\n if (this.uniforms) this.uniforms.uAlpha = Number(value);\n console.log(`Updated alpha to ${this.alpha}`);\n break;\n\n // For any other properties, try direct assignment\n default:\n if (key in this) {\n (this as any)[key] = value;\n console.log(`Updated ${key} to ${value}`);\n } else {\n console.warn(`Attempted to update unknown property ${key}`);\n }\n break;\n }\n \n return true;\n };\n \n console.log('ColorOverlayFilter created successfully with updateUIParam method');\n return filter;\n } catch (error) {\n console.error('Failed to create ColorOverlayFilter:', error);\n return null;\n }\n },\n \n // Default parameter values\n defaultParams: {\n color: '#ff0000',\n alpha: 0.5,\n },\n \n // UI controls for the filter\n controls: [\n {\n id: 'color',\n type: 'color',\n label: 'Color',\n property: 'color',\n default: '#ff0000',\n },\n {\n id: 'alpha',\n type: 'slider',\n label: 'Opacity',\n property: 'alpha',\n min: 0,\n max: 1,\n step: 0.01,\n default: 0.5,\n },\n ],\n});","/**\n * Drop Shadow Filter Definition\n * Applies a drop shadow effect to the image\n */\nimport { registerFilter } from '../registry';\nimport * as filters from 'pixi-filters';\n\n// Register the drop shadow filter\nexport default registerFilter({\n id: 'drop-shadow',\n name: 'Drop Shadow',\n category: 'effects',\n description: 'Add a soft drop shadow to the image',\n \n /**\n * Create an instance of the DropShadowFilter with the provided parameters\n * Using the official pixi-filters implementation\n */\n createFilter: (params) => {\n try {\n console.log('Creating Drop Shadow filter with params:', params);\n \n // Parse color from hex string\n const color = params.color ? params.color.replace('#', '0x') : '0x000000';\n \n // Create offset object based on distance and angle\n const distance = params.distance !== undefined ? params.distance : 5;\n const angle = params.angle !== undefined ? params.angle : 90;\n const offset = {\n x: distance * Math.cos(angle * Math.PI / 180),\n y: distance * Math.sin(angle * Math.PI / 180)\n };\n \n // Create the filter with the official pixi-filters package\n const filter = new filters.DropShadowFilter({\n offset: offset,\n color: parseInt(color, 16),\n alpha: params.alpha !== undefined ? params.alpha : 0.5,\n blur: params.blur !== undefined ? params.blur : 2,\n quality: params.quality !== undefined ? params.quality : 3,\n shadowOnly: params.shadowOnly !== undefined ? params.shadowOnly : false,\n pixelSize: { \n x: params.pixelSizeX !== undefined ? params.pixelSizeX : 1, \n y: params.pixelSizeY !== undefined ? params.pixelSizeY : 1 \n }\n });\n \n // Store custom parameters for later reference\n (filter as any)._customParams = { \n ...params,\n // Also store the calculated offset for use in updateUIParam\n _offset: offset,\n _distance: distance,\n _angle: angle\n };\n \n /**\n * Add a custom updateUIParam method to handle UI parameter updates\n * Following the pattern from the fix_filters.md document\n */\n (filter as any).updateUIParam = function(key: string, value: any) {\n try {\n // Store UI parameters for later reference\n const customParams = (this as any)._customParams || {};\n (this as any)._customParams = customParams;\n \n // Update the stored params value\n customParams[key] = value;\n \n // Handle parameter updates based on key\n switch (key) {\n case 'color':\n // Convert hex string to number for the color property\n if (typeof value === 'string') {\n const colorNum = parseInt(value.replace('#', '0x'), 16);\n this.color = colorNum;\n console.log(`Updated color to ${value} (${colorNum})`);\n }\n break;\n \n case 'alpha':\n this.alpha = Number(value);\n console.log(`Updated alpha to ${value}`);\n break;\n \n case 'blur':\n this.blur = Number(value);\n console.log(`Updated blur to ${value}`);\n break;\n \n case 'quality':\n this.quality = Number(value);\n console.log(`Updated quality to ${value}`);\n break;\n \n case 'shadowOnly':\n this.shadowOnly = Boolean(value);\n console.log(`Updated shadowOnly to ${value}`);\n break;\n \n case 'pixelSizeX':\n this.pixelSizeX = Number(value);\n customParams.pixelSizeX = Number(value);\n console.log(`Updated pixelSizeX to ${value}`);\n break;\n \n case 'pixelSizeY':\n this.pixelSizeY = Number(value);\n customParams.pixelSizeY = Number(value);\n console.log(`Updated pixelSizeY to ${value}`);\n break;\n \n // For distance and angle, we need to recalculate the offset\n case 'distance':\n case 'angle':\n // Update the stored values\n if (key === 'distance') {\n customParams._distance = Number(value);\n } else {\n customParams._angle = Number(value);\n }\n \n // Recalculate the offset based on new distance/angle\n const newOffset = {\n x: customParams._distance * Math.cos(customParams._angle * Math.PI / 180),\n y: customParams._distance * Math.sin(customParams._angle * Math.PI / 180)\n };\n \n // Store the new offset\n customParams._offset = newOffset;\n \n // Update the filter's offset property\n this.offset = newOffset;\n console.log(`Updated offset to (${newOffset.x}, ${newOffset.y}) from ${key}=${value}`);\n break;\n \n // For any other properties, try direct assignment \n default:\n if (key in this) {\n this[key] = value;\n console.log(`Updated ${key} to ${value}`);\n } else {\n console.warn(`Attempted to update unknown property ${key}`);\n }\n break;\n }\n \n return true;\n } catch (error) {\n console.error(`Failed to update parameter ${key} using updateUIParam:`, error);\n \n // Still store the value in customParams even if setting it failed\n if ((this as any)._customParams) {\n (this as any)._customParams[key] = value;\n }\n \n return false;\n }\n };\n \n console.log('Drop Shadow filter created successfully');\n return filter;\n } catch (error) {\n console.error('Failed to create Drop Shadow filter:', error);\n return null;\n }\n },\n \n // Default parameter values\n defaultParams: {\n alpha: 0.5,\n blur: 2,\n color: '#000000',\n distance: 5,\n angle: 90,\n quality: 3,\n shadowOnly: false,\n pixelSizeX: 1,\n pixelSizeY: 1\n },\n \n // UI controls for the filter\n controls: [\n {\n id: 'alpha',\n type: 'slider',\n label: 'Opacity',\n property: 'alpha',\n min: 0,\n max: 1,\n step: 0.01,\n default: 0.5,\n },\n {\n id: 'blur',\n type: 'slider',\n label: 'Blur',\n property: 'blur',\n min: 0,\n max: 20,\n step: 0.1,\n default: 2,\n },\n {\n id: 'color',\n type: 'color',\n label: 'Color',\n property: 'color',\n default: '#000000',\n },\n {\n id: 'distance',\n type: 'slider',\n label: 'Distance',\n property: 'distance',\n min: 0,\n max: 50,\n step: 1,\n default: 5,\n },\n {\n id: 'angle',\n type: 'slider',\n label: 'Angle',\n property: 'angle',\n min: 0,\n max: 360,\n step: 1,\n default: 90,\n },\n {\n id: 'quality',\n type: 'slider',\n label: 'Quality',\n property: 'quality',\n min: 0,\n max: 20,\n step: 1,\n default: 3,\n },\n {\n id: 'shadowOnly',\n type: 'toggle',\n label: 'Shadow Only',\n property: 'shadowOnly',\n default: false,\n },\n {\n id: 'pixelSizeX',\n type: 'slider',\n label: 'Pixel Size X',\n property: 'pixelSizeX',\n min: 0.5,\n max: 8,\n step: 0.5,\n default: 1,\n },\n {\n id: 'pixelSizeY',\n type: 'slider',\n label: 'Pixel Size Y',\n property: 'pixelSizeY',\n min: 0.5,\n max: 8,\n step: 0.5,\n default: 1,\n }\n ],\n});","/**\n * Grayscale Filter Definition\n * Converts image to grayscale with customizable intensity\n * \n * This implementation uses the ColorMatrixFilter from pixi.js\n * to provide a grayscale effect with adjustable intensity.\n */\nimport { registerFilter } from '../registry';\n// Import from pixi.js with namespace\nimport * as PIXI from 'pixi.js';\n// @ts-ignore - Module structure doesn't match TypeScript definitions\nconst { ColorMatrixFilter } = PIXI;;\n\n// Register the grayscale filter\nexport default registerFilter({\n id: 'grayscale',\n name: 'Grayscale',\n category: 'color',\n description: 'Convert the image to black and white with adjustable intensity',\n \n /**\n * Create a ColorMatrixFilter instance configured for grayscale effect with adjustable intensity\n * This implementation follows the pattern from ColorGradientFilter, adding\n * proper parameter handling with an updateUIParam method\n */\n createFilter: (params) => {\n try {\n console.log('Creating grayscale filter with params:', params);\n \n // Create a new ColorMatrixFilter\n const filter = new ColorMatrixFilter();\n \n // Store custom parameters for later reference\n (filter as any)._customParams = { ...params };\n \n // Apply the initial grayscale effect based on intensity\n const intensity = params.intensity !== undefined ? params.intensity : 1.0;\n applyGrayscaleEffect(filter as any, intensity);\n \n /**\n * Add a custom updateUIParam method to handle UI parameter updates\n * This follows the same pattern as ColorOverlayFilter and ColorGradientFilter\n * \n * @param key The UI parameter name\n * @param value The new value for the parameter\n */\n (filter as any).updateUIParam = function(key: string, value: any) {\n // Store UI parameters for later reference\n const customParams = (this as any)._customParams || {};\n (this as any)._customParams = customParams;\n \n // Update the stored params value\n customParams[key] = value;\n \n // Handle parameter updates based on key\n switch (key) {\n case 'intensity':\n // Apply grayscale effect with the new intensity\n applyGrayscaleEffect(this, value);\n console.log(`Updated grayscale intensity to ${value}`);\n break;\n \n // For any other properties, try direct assignment \n default:\n if (key in this) {\n this[key] = value;\n console.log(`Updated ${key} to ${value}`);\n } else {\n console.warn(`Attempted to update unknown property ${key}`);\n }\n break;\n }\n \n return true;\n };\n \n console.log('Grayscale filter created successfully');\n return filter;\n } catch (error) {\n console.error('Failed to create grayscale filter:', error);\n return null;\n }\n },\n \n // Default parameter values\n defaultParams: {\n intensity: 0.35,\n },\n \n // UI controls for the filter\n controls: [\n {\n id: 'intensity',\n type: 'slider',\n label: 'Intensity',\n property: 'intensity',\n min: 0,\n max: 1,\n step: 0.01,\n default: 0.35,\n },\n ],\n});\n\n/**\n * Helper function to apply grayscale effect with a specific intensity\n * @param filter The ColorMatrixFilter instance\n * @param intensity The intensity of the grayscale effect (0-1)\n */\nfunction applyGrayscaleEffect(filter: any, intensity: number): void {\n // Reset the matrix to identity (no effect)\n filter.reset();\n\n // Apply grayscale with the specified intensity\n // The greyscale method takes a single parameter for intensity (0-1)\n filter.greyscale(intensity);\n}","/**\n * HSL Adjustment Filter Definition\n * Adjusts hue, saturation, and lightness with fine control\n */\nimport { registerFilter } from '../registry';\n// Import from pixi-filters with wildcard and destructuring pattern\nimport * as PixiFilters from 'pixi-filters';\n// @ts-ignore - Module lacks TypeScript definitions\nconst { HslAdjustmentFilter } = PixiFilters;;\n\n// Register the HSL adjustment filter\nexport default registerFilter({\n id: 'hsl-adjustment',\n name: 'HSL Adjustment',\n category: 'color',\n description: 'Control hue, saturation, and lightness independently',\n \n /**\n * Create an instance of the HslAdjustmentFilter with the provided parameters\n * Using the official pixi-filters implementation instead of a custom one\n */\n createFilter: (params) => {\n try {\n console.log('Creating HSL Adjustment filter with params:', params);\n \n // Create a new HslAdjustmentFilter instance from the pixi-filters package\n const filter = new HslAdjustmentFilter({\n hue: params.hue !== undefined ? params.hue : 0,\n saturation: params.saturation !== undefined ? params.saturation : 0,\n lightness: params.lightness !== undefined ? params.lightness : 0, \n colorize: params.colorize !== undefined ? params.colorize : false,\n alpha: params.alpha !== undefined ? params.alpha : 1.0\n });\n \n // Store custom parameters for later reference\n (filter as any)._customParams = { ...params };\n \n /**\n * Add a custom updateUIParam method to handle UI parameter updates\n * Following the pattern from the fix_filters.md document\n * \n * @param key The UI parameter name\n * @param value The new value for the parameter\n */\n (filter as any).updateUIParam = function(key: string, value: any) {\n try {\n // Store UI parameters for later reference\n const customParams = (this as any)._customParams || {};\n (this as any)._customParams = customParams;\n \n // Update the stored params value\n customParams[key] = value;\n \n // Handle parameter updates based on key\n // IMPORTANT: Must update BOTH the JS property AND the shader uniform\n // The JS property is used for state tracking, but the shader uses uniforms for rendering\n switch (key) {\n case 'hue':\n // The filter handles the degrees to radians conversion internally\n this.hue = Number(value);\n if (this.uniforms) this.uniforms.uHue = Number(value);\n console.log(`Updated hue to ${value}`);\n break;\n\n case 'saturation':\n this.saturation = Number(value);\n if (this.uniforms) this.uniforms.uSaturation = Number(value);\n console.log(`Updated saturation to ${value}`);\n break;\n\n case 'lightness':\n this.lightness = Number(value);\n if (this.uniforms) this.uniforms.uLightness = Number(value);\n console.log(`Updated lightness to ${value}`);\n break;\n\n case 'colorize':\n this.colorize = Boolean(value);\n if (this.uniforms) this.uniforms.uColorize = value ? 1 : 0;\n console.log(`Updated colorize to ${value}`);\n break;\n\n case 'alpha':\n this.alpha = Number(value);\n if (this.uniforms) this.uniforms.uAlpha = Number(value);\n console.log(`Updated alpha to ${value}`);\n break;\n\n // For any other properties, try direct assignment\n default:\n if (key in this) {\n this[key] = value;\n console.log(`Updated ${key} to ${value}`);\n } else {\n console.warn(`Attempted to update unknown property ${key}`);\n }\n break;\n }\n \n return true;\n } catch (error) {\n console.error(`Failed to update parameter ${key} using updateUIParam:`, error);\n \n // Still store the value in customParams even if setting it failed\n if ((this as any)._customParams) {\n (this as any)._customParams[key] = value;\n }\n \n return false;\n }\n };\n \n console.log('HSL Adjustment filter created successfully');\n return filter;\n } catch (error) {\n console.error('Failed to create HSL Adjustment filter:', error);\n return null;\n }\n },\n \n // Default parameter values\n defaultParams: {\n hue: 0,\n saturation: 0,\n lightness: 0,\n colorize: false,\n alpha: 1.0\n },\n \n // UI controls for the filter\n controls: [\n {\n id: 'hue',\n type: 'slider',\n label: 'Hue',\n property: 'hue',\n min: -180,\n max: 180,\n step: 1,\n default: 0,\n },\n {\n id: 'saturation',\n type: 'slider',\n label: 'Saturation',\n property: 'saturation',\n min: -1,\n max: 1,\n step: 0.01,\n default: 0,\n },\n {\n id: 'lightness',\n type: 'slider',\n label: 'Lightness',\n property: 'lightness',\n min: -1,\n max: 1,\n step: 0.01,\n default: 0,\n },\n {\n id: 'colorize',\n type: 'toggle',\n label: 'Colorize',\n property: 'colorize',\n default: false,\n },\n {\n id: 'alpha',\n type: 'slider',\n label: 'Alpha',\n property: 'alpha',\n min: 0,\n max: 1,\n step: 0.01,\n default: 1.0,\n },\n ],\n});","/**\n * Kawase Blur Filter Definition\n * A much faster blur than Gaussian blur, with similar quality\n * \n * This implementation uses the proper KawaseBlurFilter from pixi-filters\n * which is compatible with PixiJS v8\n */\nimport { registerFilter } from '../registry';\n// Import KawaseBlurFilter directly from pixi-filters\n// Import from pixi-filters with wildcard and destructuring pattern\nimport * as PixiFilters from 'pixi-filters';\n// @ts-ignore - Module lacks TypeScript definitions\nconst { KawaseBlurFilter } = PixiFilters;;\n\n// Register the kawase blur filter\nexport default registerFilter({\n id: 'kawase-blur',\n name: 'Kawase Blur',\n category: 'blur',\n description: 'A more optimized blur algorithm that is faster than standard blur',\n \n /**\n * Create an instance of the KawaseBlurFilter from pixi-filters package\n * This implementation follows the pattern from ColorGradientFilter, adding\n * proper parameter handling with an updateUIParam method\n */\n createFilter: (params) => {\n try {\n console.log('Creating KawaseBlurFilter with params:', params);\n \n // Create filter with proper options object for v6+\n const filter = new KawaseBlurFilter({\n strength: params.strength || 4,\n quality: params.quality || 3,\n clamp: params.clamp || false,\n pixelSize: params.pixelSize || 1\n });\n \n // Store custom parameters for later reference\n (filter as any)._customParams = { ...params };\n \n /**\n * Add a custom updateUIParam method to handle UI parameter updates\n * This is called by PixiApplication.updateFilter when UI controls change\n * and provides consistent parameter handling across all filters.\n * \n * @param key The UI parameter name\n * @param value The new value for the parameter\n */\n (filter as any).updateUIParam = function(key: string, value: any) {\n // Store UI parameters for later reference\n const customParams = (this as any)._customParams || {};\n (this as any)._customParams = customParams;\n \n // Update the stored params value\n customParams[key] = value;\n \n // Handle parameter updates based on key\n switch (key) {\n case 'strength':\n this.strength = value;\n console.log(`Updated strength to ${this.strength}`);\n break;\n \n case 'quality':\n this.quality = value;\n console.log(`Updated quality to ${this.quality}`);\n break;\n \n case 'clamp':\n this.clamp = value;\n console.log(`Updated clamp to ${this.clamp}`);\n break;\n \n case 'pixelSize':\n // pixelSize can be set as a single number or as an object with x and y\n if (typeof value === 'number') {\n this.pixelSize = value;\n } else if (typeof value === 'object' && value !== null) {\n if ('x' in value && 'y' in value) {\n this.pixelSize = value;\n }\n }\n console.log(`Updated pixelSize to ${JSON.stringify(this.pixelSize)}`);\n break;\n\n case 'pixelSizeX':\n this.pixelSizeX = value;\n console.log(`Updated pixelSizeX to ${this.pixelSizeX}`);\n break;\n \n case 'pixelSizeY':\n this.pixelSizeY = value;\n console.log(`Updated pixelSizeY to ${this.pixelSizeY}`);\n break;\n \n // For any other properties, try direct assignment \n default:\n if (key in this) {\n (this as any)[key] = value;\n console.log(`Updated ${key} to ${value}`);\n } else {\n console.warn(`Attempted to update unknown property ${key}`);\n }\n break;\n }\n \n return true;\n };\n \n console.log('KawaseBlurFilter created successfully with updateUIParam method');\n return filter;\n } catch (error) {\n console.error('Failed to create KawaseBlurFilter:', error);\n return null;\n }\n },\n \n // Default parameter values\n defaultParams: {\n strength: 4,\n quality: 3,\n clamp: false,\n pixelSize: 1\n },\n \n // UI controls for the filter\n controls: [\n {\n id: 'strength',\n type: 'slider',\n label: 'Strength',\n property: 'strength',\n min: 0,\n max: 20,\n step: 0.1,\n default: 4,\n },\n {\n id: 'quality',\n type: 'slider',\n label: 'Quality',\n property: 'quality',\n min: 1,\n max: 20,\n step: 1,\n default: 3,\n },\n {\n id: 'clamp',\n type: 'toggle',\n label: 'Clamp Edges',\n property: 'clamp',\n default: false,\n },\n {\n id: 'pixelSize',\n type: 'slider',\n label: 'Pixel Size',\n property: 'pixelSize',\n min: 0.5,\n max: 10,\n step: 0.5,\n default: 1,\n },\n {\n id: 'pixelSizeX',\n type: 'slider',\n label: 'Pixel Size X',\n property: 'pixelSizeX',\n min: 0,\n max: 10,\n step: 0.1,\n default: 1,\n },\n {\n id: 'pixelSizeY',\n type: 'slider',\n label: 'Pixel Size Y',\n property: 'pixelSizeY',\n min: 0,\n max: 10,\n step: 0.1,\n default: 1,\n },\n ],\n});","/**\n * Motion Blur Filter Definition\n * Applies a directional motion blur effect to the image\n * \n * This implementation uses the proper MotionBlurFilter from pixi-filters\n * which is compatible with PixiJS v8\n */\nimport { registerFilter } from '../registry';\n// Import MotionBlurFilter directly from pixi-filters\n// Import from pixi-filters with wildcard and destructuring pattern\nimport * as PixiFilters from 'pixi-filters';\n// @ts-ignore - Module lacks TypeScript definitions\nconst { MotionBlurFilter } = PixiFilters;;\n\n// Register the motion blur filter\nexport default registerFilter({\n id: 'motion-blur',\n name: 'Motion Blur',\n category: 'blur',\n description: 'Creates a directional blur effect simulating motion',\n \n /**\n * Create an instance of the MotionBlurFilter from pixi-filters package\n * This implementation follows the pattern from ColorGradientFilter, adding\n * proper parameter handling with an updateUIParam method\n */\n createFilter: (params) => {\n try {\n console.log('Creating MotionBlurFilter with params:', params);\n \n // Create filter with proper options object for v6+\n const filter = new MotionBlurFilter({\n velocity: { \n x: params.velocityX !== undefined ? params.velocityX : 0, \n y: params.velocityY !== undefined ? params.velocityY : 0 \n },\n kernelSize: params.kernelSize || 5,\n offset: params.offset !== undefined ? params.offset : 0\n });\n \n // Store custom parameters for later reference\n (filter as any)._customParams = { ...params };\n \n /**\n * Add a custom updateUIParam method to handle UI parameter updates\n * This is called by PixiApplication.updateFilter when UI controls change\n * and provides consistent parameter handling across all filters.\n * \n * @param key The UI parameter name\n * @param value The new value for the parameter\n */\n (filter as any).updateUIParam = function(key: string, value: any) {\n // Store UI parameters for later reference\n const customParams = (this as any)._customParams || {};\n (this as any)._customParams = customParams;\n \n // Update the stored params value\n customParams[key] = value;\n \n // Handle parameter updates based on key\n switch (key) {\n case 'velocityX':\n // Update just the X component of the velocity\n this.velocityX = value;\n console.log(`Updated velocityX to ${this.velocityX}`);\n break;\n \n case 'velocityY':\n // Update just the Y component of the velocity\n this.velocityY = value;\n console.log(`Updated velocityY to ${this.velocityY}`);\n break;\n \n case 'kernelSize':\n this.kernelSize = value;\n console.log(`Updated kernelSize to ${this.kernelSize}`);\n break;\n \n case 'offset':\n this.offset = value;\n console.log(`Updated offset to ${this.offset}`);\n break;\n \n // For any other properties, try direct assignment \n default:\n if (key in this) {\n (this as any)[key] = value;\n console.log(`Updated ${key} to ${value}`);\n } else {\n console.warn(`Attempted to update unknown property ${key}`);\n }\n break;\n }\n \n return true;\n };\n \n console.log('MotionBlurFilter created successfully with updateUIParam method');\n return filter;\n } catch (error) {\n console.error('Failed to create MotionBlurFilter:', error);\n return null;\n }\n },\n \n // Default parameter values\n defaultParams: {\n velocityX: 0,\n velocityY: 0,\n kernelSize: 5,\n offset: 0\n },\n \n // UI controls for the filter\n controls: [\n {\n id: 'velocityX',\n type: 'slider',\n label: 'Velocity X',\n property: 'velocityX',\n min: -90,\n max: 90,\n step: 1,\n default: 0,\n },\n {\n id: 'velocityY',\n type: 'slider',\n label: 'Velocity Y',\n property: 'velocityY',\n min: -90,\n max: 90,\n step: 1,\n default: 0,\n },\n {\n id: 'kernelSize',\n type: 'select',\n label: 'Kernel Size',\n property: 'kernelSize',\n options: [\n { label: '3', value: 3 },\n { label: '5', value: 5 },\n { label: '7', value: 7 },\n { label: '9', value: 9 },\n { label: '11', value: 11 },\n { label: '13', value: 13 },\n { label: '15', value: 15 },\n { label: '17', value: 17 },\n { label: '19', value: 19 },\n { label: '21', value: 21 },\n { label: '23', value: 23 },\n { label: '25', value: 25 },\n ],\n default: 5,\n },\n {\n id: 'offset',\n type: 'slider',\n label: 'Offset',\n property: 'offset',\n min: -150,\n max: 150,\n step: 1,\n default: 0,\n },\n ],\n});","/**\n * Radial Blur Filter Definition\n * Applies a radial motion blur effect that emanates from a center point\n */\nimport { registerFilter } from '../registry';\n// Import from pixi-filters with wildcard and destructuring pattern\nimport * as PixiFilters from 'pixi-filters';\n// @ts-ignore - Module lacks TypeScript definitions\nconst { RadialBlurFilter } = PixiFilters;;\n\n// Register the radial blur filter\nexport default registerFilter({\n id: 'radial-blur',\n name: 'Radial Blur',\n category: 'blur',\n description: 'Creates a circular blur effect emanating from a center point',\n \n // Create an instance of the RadialBlurFilter with the provided parameters\n createFilter: (params) => {\n try {\n // Create filter with options object\n const filter = new RadialBlurFilter({\n angle: params.angle ?? 20,\n center: { x: params.centerX ?? 0, y: params.centerY ?? 0 },\n kernelSize: params.kernelSize ?? 15,\n radius: params.radius ?? 300\n });\n\n // Store custom params for reference\n (filter as any)._customParams = {\n centerX: params.centerX ?? 0,\n centerY: params.centerY ?? 0\n };\n \n // Add custom updateUIParam method for dynamic updates\n (filter as any).updateUIParam = function(key: string, value: any) {\n try {\n switch (key) {\n case 'angle':\n this.angle = Number(value);\n break;\n case 'centerX':\n (this as any)._customParams.centerX = Number(value);\n this.center = { \n x: Number(value), \n y: (this as any)._customParams.centerY \n };\n break;\n case 'centerY':\n (this as any)._customParams.centerY = Number(value);\n this.center = { \n x: (this as any)._customParams.centerX, \n y: Number(value) \n };\n break;\n case 'kernelSize':\n this.kernelSize = Number(value);\n break;\n case 'radius':\n this.radius = Number(value);\n break;\n default:\n console.warn(`Unknown parameter for RadialBlurFilter: ${key}`);\n }\n } catch (error) {\n console.error(`Error updating RadialBlurFilter parameter ${key}:`, error);\n }\n };\n \n return filter;\n } catch (error) {\n console.error('Failed to create RadialBlurFilter:', error);\n return null;\n }\n },\n \n // Default parameter values\n defaultParams: {\n angle: 20,\n centerX: 0,\n centerY: 0,\n kernelSize: 15,\n radius: 300\n },\n \n // UI controls for the filter\n controls: [\n {\n id: 'angle',\n type: 'slider',\n label: 'Angle',\n property: 'angle',\n min: -180,\n max: 180,\n step: 1,\n default: 20,\n },\n {\n id: 'centerX',\n type: 'slider',\n label: 'Center X',\n property: 'centerX',\n min: -1,\n max: 1,\n step: 0.01,\n default: 0,\n },\n {\n id: 'centerY',\n type: 'slider',\n label: 'Center Y',\n property: 'centerY',\n min: -1,\n max: 1,\n step: 0.01,\n default: 0,\n },\n {\n id: 'kernelSize',\n type: 'select',\n label: 'Kernel Size',\n property: 'kernelSize',\n options: [\n { label: '3', value: 3 },\n { label: '5', value: 5 },\n { label: '7', value: 7 },\n { label: '9', value: 9 },\n { label: '11', value: 11 },\n { label: '13', value: 13 },\n { label: '15', value: 15 },\n { label: '17', value: 17 },\n { label: '19', value: 19 },\n { label: '21', value: 21 },\n { label: '23', value: 23 },\n { label: '25', value: 25 },\n ],\n default: 15,\n },\n {\n id: 'radius',\n type: 'slider',\n label: 'Radius',\n property: 'radius',\n min: -1,\n max: 1000,\n step: 10,\n default: 300,\n },\n ],\n});","/**\n * Tilt Shift Filter Definition\n * Creates a depth-of-field effect like a miniature model\n */\nimport { registerFilter } from '../registry';\nimport * as PixiFilters from 'pixi-filters';\n// @ts-ignore - Module lacks TypeScript definitions\nconst { TiltShiftFilter } = PixiFilters;\n\n// Register the tilt shift filter\nexport default registerFilter({\n id: 'tilt-shift',\n name: 'Tilt Shift',\n category: 'blur',\n description: 'Creates a depth-of-field effect simulating miniature photography',\n \n // Create an instance of the TiltShiftFilter with the provided parameters\n createFilter: (params) => {\n try {\n console.log('Creating TiltShiftFilter with params:', params);\n \n // Ensure parameters have default values if missing\n const blur = typeof params.blur === 'number' ? params.blur : 100;\n const gradientBlur = typeof params.gradientBlur === 'number' ? params.gradientBlur : 600;\n const startX = typeof params.startX === 'number' ? params.startX : 0;\n const startY = typeof params.startY === 'number' ? params.startY : 0.5;\n const endX = typeof params.endX === 'number' ? params.endX : 1;\n const endY = typeof params.endY === 'number' ? params.endY : 0.5;\n \n // Create the filter with proper options\n const filter = new TiltShiftFilter({\n blur: Number(blur),\n gradientBlur: Number(gradientBlur),\n start: { x: Number(startX), y: Number(startY) },\n end: { x: Number(endX), y: Number(endY) }\n });\n \n // Log the actual filter object to see its properties\n console.log('Created TiltShiftFilter instance with properties:', {\n blur: filter.blur,\n gradientBlur: filter.gradientBlur,\n start: filter.start,\n end: filter.end\n });\n \n // Store custom parameters for reference\n (filter as any)._customParams = {\n blur: blur,\n gradientBlur: gradientBlur,\n startX: startX,\n startY: startY,\n endX: endX,\n endY: endY\n };\n \n // Add updateUIParam method for dynamic parameter updates\n (filter as any).updateUIParam = function(key: string, value: any) {\n try {\n console.log(`TiltShiftFilter.updateUIParam called: ${key} = ${value}`);\n \n // Force numeric conversion\n const numValue = Number(value);\n \n // Store UI parameters for reference\n const customParams = (this as any)._customParams || {};\n (this as any)._customParams = customParams;\n \n // Update stored params\n customParams[key] = numValue;\n \n // Handle parameter updates based on key\n switch (key) {\n case 'blur':\n this.blur = numValue;\n console.log(`Updated blur to ${this.blur}`);\n break;\n \n case 'gradientBlur':\n this.gradientBlur = numValue;\n console.log(`Updated gradientBlur to ${this.gradientBlur}`);\n break;\n \n case 'startX':\n if (this.start && typeof this.start === 'object') {\n this.start.x = numValue;\n console.log(`Updated startX to ${numValue}`, this.start);\n }\n break;\n \n case 'startY':\n if (this.start && typeof this.start === 'object') {\n this.start.y = numValue;\n console.log(`Updated startY to ${numValue}`, this.start);\n }\n break;\n \n case 'endX':\n if (this.end && typeof this.end === 'object') {\n this.end.x = numValue;\n console.log(`Updated endX to ${numValue}`, this.end);\n }\n break;\n \n case 'endY':\n if (this.end && typeof this.end === 'object') {\n this.end.y = numValue;\n console.log(`Updated endY to ${numValue}`, this.end);\n }\n break;\n \n // For any other properties, try direct assignment\n default:\n if (key in this) {\n (this as any)[key] = numValue;\n console.log(`Updated ${key} to ${numValue}`);\n } else {\n console.warn(`Unknown parameter for TiltShiftFilter: ${key}`);\n }\n break;\n }\n \n // Log the current state after updates\n console.log('TiltShiftFilter state after update:', {\n blur: this.blur,\n gradientBlur: this.gradientBlur,\n start: this.start,\n end: this.end\n });\n } catch (error) {\n console.error(`Error updating TiltShiftFilter parameter ${key}:`, error);\n }\n };\n \n console.log('TiltShiftFilter created successfully');\n return filter;\n } catch (error) {\n console.error('Failed to create TiltShiftFilter:', error);\n return null;\n }\n },\n \n // Default parameter values\n defaultParams: {\n blur: 100,\n gradientBlur: 600,\n startX: 0,\n startY: 0.5,\n endX: 1,\n endY: 0.5\n },\n \n // UI controls for the filter\n controls: [\n {\n id: 'blur',\n type: 'slider',\n label: 'Blur Strength',\n property: 'blur',\n min: 0,\n max: 200,\n step: 1,\n default: 100,\n },\n {\n id: 'gradientBlur',\n type: 'slider',\n label: 'Gradient Width',\n property: 'gradientBlur',\n min: 0,\n max: 1000,\n step: 10,\n default: 600,\n },\n {\n id: 'startX',\n type: 'slider',\n label: 'Start X',\n property: 'startX',\n min: 0,\n max: 1,\n step: 0.01,\n default: 0,\n },\n {\n id: 'startY',\n type: 'slider',\n label: 'Start Y',\n property: 'startY',\n min: 0,\n max: 1,\n step: 0.01,\n default: 0.5,\n },\n {\n id: 'endX',\n type: 'slider',\n label: 'End X',\n property: 'endX',\n min: 0,\n max: 1,\n step: 0.01,\n default: 1,\n },\n {\n id: 'endY',\n type: 'slider',\n label: 'End Y',\n property: 'endY',\n min: 0,\n max: 1,\n step: 0.01,\n default: 0.5,\n },\n ],\n});","/**\n * Zoom Blur Filter Definition\n * Creates a radial blur that simulates a camera zoom effect\n * \n * This implementation uses the proper ZoomBlurFilter from pixi-filters\n * which is compatible with PixiJS v8\n */\nimport { registerFilter } from '../registry';\n// Import ZoomBlurFilter directly from pixi-filters\n// Import from pixi-filters with wildcard and destructuring pattern\nimport * as PixiFilters from 'pixi-filters';\n// @ts-ignore - Module lacks TypeScript definitions\nconst { ZoomBlurFilter } = PixiFilters;;\n\n// Register the zoom blur filter\nexport default registerFilter({\n id: 'zoom-blur',\n name: 'Zoom Blur',\n category: 'blur',\n description: 'Creates a zoom blur effect from a center point',\n \n /**\n * Create an instance of the ZoomBlurFilter from pixi-filters package\n * This implementation follows the pattern from ColorGradientFilter, adding\n * proper parameter handling with an updateUIParam method\n */\n createFilter: (params) => {\n try {\n console.log('Creating ZoomBlurFilter with params:', params);\n \n // Create filter with proper options object for v6+\n const filter = new ZoomBlurFilter({\n strength: params.strength || 0.1,\n center: { \n x: params.centerX !== undefined ? params.centerX : 0.5, \n y: params.centerY !== undefined ? params.centerY : 0.5 \n },\n innerRadius: params.innerRadius || 80,\n radius: params.radius !== undefined ? params.radius : -1,\n maxKernelSize: params.maxKernelSize || 32\n });\n \n // Store custom parameters for later reference\n (filter as any)._customParams = { ...params };\n \n /**\n * Add a custom updateUIParam method to handle UI parameter updates\n * This is called by PixiApplication.updateFilter when UI controls change\n * and provides consistent parameter handling across all filters.\n * \n * @param key The UI parameter name\n * @param value The new value for the parameter\n */\n (filter as any).updateUIParam = function(key: string, value: any) {\n // Store UI parameters for later reference\n const customParams = (this as any)._customParams || {};\n (this as any)._customParams = customParams;\n \n // Update the stored params value\n customParams[key] = value;\n \n // Handle parameter updates based on key\n switch (key) {\n case 'strength':\n this.strength = value;\n console.log(`Updated strength to ${this.strength}`);\n break;\n \n case 'centerX':\n // Update just the X component of the center point\n this.centerX = value;\n console.log(`Updated centerX to ${this.centerX}`);\n break;\n \n case 'centerY':\n // Update just the Y component of the center point\n this.centerY = value;\n console.log(`Updated centerY to ${this.centerY}`);\n break;\n \n case 'innerRadius':\n this.innerRadius = value;\n console.log(`Updated innerRadius to ${this.innerRadius}`);\n break;\n \n case 'radius':\n this.radius = value;\n console.log(`Updated radius to ${this.radius}`);\n break;\n \n // For any other properties, try direct assignment \n default:\n if (key in this) {\n (this as any)[key] = value;\n console.log(`Updated ${key} to ${value}`);\n } else {\n console.warn(`Attempted to update unknown property ${key}`);\n }\n break;\n }\n \n return true;\n };\n \n console.log('ZoomBlurFilter created successfully with updateUIParam method');\n return filter;\n } catch (error) {\n console.error('Failed to create ZoomBlurFilter:', error);\n return null;\n }\n },\n \n // Default parameter values\n defaultParams: {\n strength: 0.1,\n centerX: 0.5,\n centerY: 0.5,\n innerRadius: 80,\n radius: -1,\n maxKernelSize: 32\n },\n \n // UI controls for the filter\n controls: [\n {\n id: 'strength',\n type: 'slider',\n label: 'Strength',\n property: 'strength',\n min: 0,\n max: 0.5,\n step: 0.01,\n default: 0.1,\n },\n {\n id: 'centerX',\n type: 'slider',\n label: 'Center X',\n property: 'centerX',\n min: 0,\n max: 1,\n step: 0.01,\n default: 0.5,\n },\n {\n id: 'centerY',\n type: 'slider',\n label: 'Center Y',\n property: 'centerY',\n min: 0,\n max: 1,\n step: 0.01,\n default: 0.5,\n },\n {\n id: 'innerRadius',\n type: 'slider',\n label: 'Inner Radius',\n property: 'innerRadius',\n min: 0,\n max: 1000,\n step: 1,\n default: 80,\n },\n {\n id: 'radius',\n type: 'slider',\n label: 'Outer Radius',\n property: 'radius',\n min: -1,\n max: 1000,\n step: 10,\n default: -1,\n },\n {\n id: 'maxKernelSize',\n type: 'select',\n label: 'Quality',\n property: 'maxKernelSize',\n options: [\n { label: 'Low', value: 16 },\n { label: 'Medium', value: 32 },\n { label: 'High', value: 48 },\n { label: 'Very High', value: 64 },\n ],\n default: 32,\n },\n ],\n});","/**\n * Color Gradient Filter Definition\n * Applies a color gradient over the image\n * \n * This implementation directly matches the PixiJS filters example app\n * using the ColorGradientFilter from pixi-filters.\n * \n * Features:\n * - Multiple gradient types (linear, radial, conic)\n * - Unlimited color stops with customizable positions, colors, and alpha values\n * - CSS gradient string parsing\n * - Runtime color stop management\n * \n * @see /docs/filters/color-gradient/README.md for detailed documentation\n */\nimport { registerFilter } from '../registry';\n// Import from the central package for pixi filters\nimport * as PixiFilters from 'pixi-filters';\n// Access ColorGradientFilter from the pixi-filters package\nconst { ColorGradientFilter } = PixiFilters;\n\n// Register the color gradient filter\nexport default registerFilter({\n id: 'color-gradient',\n name: 'Color Gradient',\n category: 'color',\n description: 'Applies a linear, radial or conic color gradient over the image with multiple color stops',\n \n /**\n * Create an instance of the ColorGradientFilter with the provided parameters\n * This implementation supports unlimited color stops like the PixiJS example app\n */\n createFilter: (params) => {\n try {\n console.log('Creating ColorGradientFilter with params:', params);\n \n // Create stops array - use colorStops array\n let stops = [];\n \n // Convert colorStops array to the format expected by the filter\n stops = (params.colorStops || [\n { offset: 0, color: '#ff0000', alpha: 1 },\n { offset: 1, color: '#0000ff', alpha: 1 }\n ]).map((stop: { offset: number; color: string | number; alpha: number }) => ({\n offset: stop.offset,\n color: typeof stop.color === 'string' ? parseInt(stop.color.replace('#', '0x')) : stop.color,\n alpha: stop.alpha\n }));\n \n // Ensure we have at least 2 stops\n if (stops.length < 2) {\n console.warn('ColorGradientFilter requires at least 2 stops, adding default stops');\n stops = [\n { offset: 0, color: 0xff0000, alpha: 1 },\n { offset: 1, color: 0x0000ff, alpha: 1 }\n ];\n }\n \n // Sort the stops by offset\n stops.sort((a: { offset: number }, b: { offset: number }) => a.offset - b.offset);\n \n // Create the filter with the ColorGradientFilter constructor options\n const filter = new ColorGradientFilter({\n type: params.gradientType, // 0: linear, 1: radial, 2: conic\n stops: stops,\n angle: params.angle,\n alpha: params.alpha,\n maxColors: params.maxColors || 0,\n replace: params.replace\n });\n \n // Special property to track our UI-specific properties\n (filter as any)._customParams = { ...params };\n \n /**\n * Custom method to handle UI parameter updates\n * This is called by PixiApplication.updateFilter when UI controls change\n * and allows filter-specific parameter handling logic.\n * \n * @param key The UI parameter name\n * @param value The new value for the parameter\n */\n \n /**\n * Method to get formatted color stops for the UI\n * Our UI system can call this method to get the current stops for rendering controls\n * \n * @returns Array of color stops with colors formatted as hex strings\n */\n (filter as any).getColorStopsForUI = function() {\n console.log('FILTER getColorStopsForUI - Called', {\n hasStops: !!this.stops,\n stopsLength: this.stops ? this.stops.length : 0,\n firstStop: this.stops && this.stops.length > 0 ? this.stops[0] : null\n });\n \n if (!this.stops || !Array.isArray(this.stops)) {\n console.error('FILTER getColorStopsForUI - No stops array found on filter instance!');\n return [];\n }\n \n const result = this.stops.map((stop: { offset: number; color: number | string; alpha: number }) => ({\n offset: stop.offset,\n color: typeof stop.color === 'number' ? \n '#' + stop.color.toString(16).padStart(6, '0') : stop.color,\n alpha: stop.alpha\n }));\n \n console.log('FILTER getColorStopsForUI - Returning formatted stops:', result);\n return result;\n };\n \n /**\n * Generates dynamic controls for each color stop\n * This method is called by UI components to create controls for each color stop\n * \n * @returns Array of filter controls for each color stop\n */\n (filter as any).getDynamicControls = function() {\n console.log('FILTER getDynamicControls - Called on filter instance', this);\n \n // Get current color stops\n const colorStops = this.getColorStopsForUI();\n console.log('FILTER getDynamicControls - Retrieved colorStops:', colorStops);\n \n // Typed array for controls\n const controls: Array<{\n id: string;\n type: string;\n label: string;\n property: string;\n default: any;\n min?: number;\n max?: number;\n step?: number;\n }> = [];\n \n // For each color stop, create a group of controls\n colorStops.forEach((stop: { offset: number; color: string; alpha: number }, index: number) => {\n console.log(`FILTER getDynamicControls - Creating controls for stop ${index}:`, stop);\n \n controls.push({\n id: `colorStop-${index}-color`,\n type: 'color',\n label: `Stop ${index + 1} Color`,\n property: `colorStops[${index}].color`,\n default: stop.color\n });\n \n controls.push({\n id: `colorStop-${index}-offset`,\n type: 'slider',\n label: `Stop ${index + 1} Position`,\n property: `colorStops[${index}].offset`,\n min: 0,\n max: 1,\n step: 0.01,\n default: stop.offset\n });\n \n controls.push({\n id: `colorStop-${index}-alpha`,\n type: 'slider',\n label: `Stop ${index + 1} Alpha`,\n property: `colorStops[${index}].alpha`,\n min: 0,\n max: 1,\n step: 0.01,\n default: stop.alpha\n });\n });\n \n console.log('FILTER getDynamicControls - Returning controls array:', controls.length, 'items');\n return controls;\n };\n \n /**\n * Handle direct button actions\n * This method is called when a button control is clicked\n * \n * @param action The action to perform\n */\n (filter as any).handleButtonAction = function(action: string) {\n console.log(`Handling button action: ${action}`);\n \n // Call updateUIParam with the action as the key\n if (action === 'addColorStop' || action === 'removeColorStop') {\n this.updateUIParam(action, true);\n }\n };\n (filter as any).updateUIParam = function(key: string, value: any) {\n // Store UI parameters for later reference\n const customParams = (this as any)._customParams || {};\n (this as any)._customParams = customParams;\n \n // Update the stored params value\n customParams[key] = value;\n \n // Handle parameter updates based on key\n // This keeps all filter-specific logic in this filter definition\n switch (key) {\n // Handle direct filter properties\n case 'gradientType':\n this.type = value;\n break;\n \n case 'angle':\n case 'alpha':\n case 'maxColors':\n case 'replace':\n if (key in this) {\n (this as any)[key] = value;\n }\n break;\n \n // Command buttons for color stop management\n case 'addColorStop':\n // For a command button, just execute the action regardless of value\n console.log('Add color stop command received');\n // Get current stops\n const currentStopsForAdd = [...this.stops];\n \n // Create new random color stop\n const getRandomColor = () => {\n const r = Math.floor(Math.random() * 255);\n const g = Math.floor(Math.random() * 255);\n const b = Math.floor(Math.random() * 255);\n return (r << 16) | (g << 8) | b;\n };\n \n // Create random color\n const randomColor = getRandomColor();\n \n const newColorStop = {\n offset: 1.0, // Will be adjusted later\n alpha: 1.0,\n color: randomColor\n };\n \n // Calculate more appropriate offset if adding to existing stops\n if (currentStopsForAdd.length > 0) {\n // For a natural placement, add it at the end and rescale offsets\n // to maintain relative positions\n const scaleFactor = 0.8; // Scale existing stops to 80% of range\n \n for (let i = 0; i < currentStopsForAdd.length; i++) {\n currentStopsForAdd[i].offset *= scaleFactor;\n }\n \n newColorStop.offset = 1.0; // New stop at the end\n }\n \n // Add the new stop and apply\n currentStopsForAdd.push(newColorStop);\n this.stops = currentStopsForAdd;\n \n // Update the stored custom parameter for UI\n customParams.colorStops = this.stops.map((stop: { offset: number; color: number | string; alpha: number }) => ({\n offset: stop.offset,\n color: typeof stop.color === 'number' ? \n '#' + stop.color.toString(16).padStart(6, '0') : stop.color,\n alpha: stop.alpha\n }));\n \n console.log('Added new color stop, total stops:', this.stops.length, 'Updated colorStops:', customParams.colorStops);\n break;\n \n case 'removeColorStop':\n // Handle command button for removing a stop\n console.log('Remove color stop command received');\n // Get current stops\n const currentStopsForRemove = [...this.stops];\n \n // Only remove if we have more than 2 stops (minimum required)\n if (currentStopsForRemove.length > 2) {\n // Remove the last stop\n currentStopsForRemove.pop();\n this.stops = currentStopsForRemove;\n \n // Update the stored custom parameter for UI\n customParams.colorStops = this.stops.map((stop: { offset: number; color: number | string; alpha: number }) => ({\n offset: stop.offset,\n color: typeof stop.color === 'number' ? \n '#' + stop.color.toString(16).padStart(6, '0') : stop.color,\n alpha: stop.alpha\n }));\n \n console.log('Removed last color stop, remaining stops:', this.stops.length, 'Updated colorStops:', customParams.colorStops);\n } else {\n console.warn('Cannot remove stop - minimum of 2 stops required');\n }\n break;\n \n case 'cssGradient':\n if (value && typeof value === 'string' && value.trim() !== '') {\n try {\n // Create a new filter with the CSS gradient\n const tempFilter = new ColorGradientFilter({ css: value });\n \n // Copy properties from the temp filter to this filter\n this.type = tempFilter.type;\n this.angle = tempFilter.angle;\n this.stops = [...tempFilter.stops];\n \n // Update the stored custom parameter for UI\n customParams.colorStops = this.stops.map((stop: { offset: number; color: number | string; alpha: number }) => ({\n offset: stop.offset,\n color: typeof stop.color === 'number' ? \n '#' + stop.color.toString(16).padStart(6, '0') : stop.color,\n alpha: stop.alpha\n }));\n \n console.log('Applied CSS gradient, new stops:', this.stops.length, 'Updated colorStops:', customParams.colorStops);\n } catch (error) {\n console.error('Failed to parse CSS gradient:', error);\n }\n }\n break;\n\n // Handle direct stop modifications (from dynamic UI)\n case 'colorStops':\n if (Array.isArray(value)) {\n // Convert each stop's color from hex string to number if needed\n const processedStops = value.map(stop => ({\n offset: stop.offset,\n color: typeof stop.color === 'string' \n ? parseInt(stop.color.replace('#', '0x')) \n : stop.color,\n alpha: stop.alpha\n }));\n \n // Sort by offset and apply\n processedStops.sort((a: { offset: number }, b: { offset: number }) => a.offset - b.offset);\n this.stops = processedStops;\n }\n break;\n \n // Handle all other cases\n default:\n // Check if it's a color stop property using regex pattern matching\n if (/colorStops\\[\\d+\\]\\..*/.test(key)) {\n // Extract index and property from key (e.g., colorStops[0].color)\n const match = key.match(/colorStops\\[(\\d+)\\]\\.(.*)/)\n if (match) {\n const [_, indexStr, prop] = match;\n const index = parseInt(indexStr);\n \n // Make a copy of the stops array\n const updatedStops = [...this.stops];\n \n if (index >= 0 && index < updatedStops.length) {\n // Update the specific property of the stop at index\n if (prop === 'color' && typeof value === 'string') {\n // Convert hex color to number\n updatedStops[index].color = parseInt(value.replace('#', '0x'));\n console.log(`Converting color ${value} to ${updatedStops[index].color}`);\n } else if (prop === 'offset' || prop === 'alpha') {\n updatedStops[index][prop] = value;\n }\n \n // Apply the updated stops\n this.stops = updatedStops;\n \n // Re-sort by offset\n this.stops.sort((a: { offset: number }, b: { offset: number }) => a.offset - b.offset);\n \n // Update the stored custom parameter for UI\n customParams.colorStops = this.getColorStopsForUI();\n \n console.log(`Updated color stop ${index}.${prop} to ${value}`);\n console.log('New stops array:', this.stops);\n console.log('New colorStops for UI:', customParams.colorStops);\n return true;\n } else {\n console.warn(`Color stop index out of range: ${index}, stops length: ${updatedStops.length}`);\n }\n }\n }\n // For any other properties, try direct assignment \n else if (key in this) {\n (this as any)[key] = value;\n }\n break;\n }\n };\n \n console.log('Enhanced ColorGradientFilter created successfully');\n return filter;\n } catch (error) {\n console.error('Failed to create ColorGradientFilter:', error);\n return null;\n }\n },\n \n // Default parameter values - matching the example app\n defaultParams: {\n gradientType: 0, // 0: linear, 1: radial, 2: conic\n colorStops: [\n { offset: 0, color: '#ff0000', alpha: 1 },\n { offset: 1, color: '#0000ff', alpha: 1 }\n ],\n // Controls for adding/removing stops\n addColorStop: false, // Button trigger for adding a color stop\n removeColorStop: false, // Button trigger for removing a color stop\n cssGradient: '', // CSS gradient string input\n angle: 90,\n alpha: 0.75,\n maxColors: 0,\n replace: false\n },\n \n // UI controls for the filter\n controls: [\n // Basic gradient controls\n {\n id: 'gradientType',\n type: 'select',\n label: 'Gradient Type',\n property: 'gradientType',\n options: [\n { label: 'Linear', value: 0 },\n { label: 'Radial', value: 1 },\n { label: 'Conic', value: 2 }\n ],\n default: 0,\n },\n {\n id: 'angle',\n type: 'slider',\n label: 'Angle',\n property: 'angle',\n min: 0,\n max: 360,\n step: 1,\n default: 90,\n },\n {\n id: 'alpha',\n type: 'slider',\n label: 'Overall Alpha',\n property: 'alpha',\n min: 0,\n max: 1,\n step: 0.01,\n default: 0.75,\n },\n {\n id: 'maxColors',\n type: 'slider',\n label: 'Max Colors',\n property: 'maxColors',\n min: 0,\n max: 24,\n step: 1,\n default: 0\n },\n {\n id: 'replace',\n type: 'toggle',\n label: 'Replace Original Colors',\n property: 'replace',\n default: false,\n },\n \n // Advanced color stop management - simpler approach\n {\n id: 'addColorStop',\n type: 'button',\n label: 'Add New Color Stop',\n action: 'addColorStop',\n },\n {\n id: 'removeColorStop',\n type: 'button',\n label: 'Remove Last Color Stop',\n action: 'removeColorStop',\n },\n {\n id: 'cssGradient',\n type: 'text',\n label: 'CSS Gradient',\n property: 'cssGradient',\n default: '',\n tooltip: 'Enter a CSS gradient like \"linear-gradient(to right, red, blue)\"'\n }\n ]\n});","/**\n * Color Map Filter Definition\n * Applies a color transformation based on a reference texture\n */\nimport { registerFilter } from '../registry';\n// Import from the central package for pixi filters\nimport * as PixiFilters from 'pixi-filters';\nimport * as PIXI from 'pixi.js';\n\n// Register the Color Map filter\nexport default registerFilter({\n id: 'color-map',\n name: 'Color Map',\n category: 'color',\n description: 'Maps colors using a reference texture as a lookup table',\n \n // Create an instance of the ColorMapFilter with the provided parameters\n createFilter: (params) => {\n try {\n // Access filter class via direct indexing with type casting to avoid TypeScript errors \n // @ts-ignore - Runtime access of property that TypeScript doesn't know about\n const ColorMapFilterClass = PixiFilters['ColorMapFilter'];\n \n if (!ColorMapFilterClass) {\n console.error('ColorMapFilter not found in pixi-filters package');\n return null;\n }\n \n console.log('Creating ColorMapFilter with params:', params);\n \n // Get the color map texture\n let colorMapTexture = null;\n \n // If texture path is provided, create a new texture\n if (params.texturePath) {\n colorMapTexture = PIXI.Texture.from(params.texturePath);\n } else {\n // Use a default colormap texture\n // This is just a fallback - ideally user should provide their own\n colorMapTexture = PIXI.Texture.from('/examples/filters-main/examples/images/colormap.png');\n }\n \n // Create filter with proper options object\n const filter = new ColorMapFilterClass({\n colorMap: colorMapTexture,\n nearest: params.nearest,\n mix: params.mix\n });\n \n // Store custom parameters for later reference\n (filter as any)._customParams = { ...params };\n \n /**\n * Add a custom updateUIParam method to handle UI parameter updates\n * This is called by PixiApplication.updateFilter when UI controls change\n */\n (filter as any).updateUIParam = function(key: string, value: any) {\n // Store UI parameters for later reference\n const customParams = (this as any)._customParams || {};\n (this as any)._customParams = customParams;\n \n // Update the stored params value\n customParams[key] = value;\n \n // Handle parameter updates based on key\n switch (key) {\n case 'texturePath':\n // Update the color map texture\n if (value) {\n this.colorMap = PIXI.Texture.from(value);\n console.log(`Updated colorMap texture to ${value}`);\n }\n break;\n \n case 'mix':\n // Direct mix update\n this.mix = value;\n console.log(`Updated mix to ${this.mix}`);\n break;\n \n case 'nearest':\n // Direct nearest update\n this.nearest = value;\n console.log(`Updated nearest to ${this.nearest}`);\n break;\n \n // For any other properties, try direct assignment \n default:\n if (key in this) {\n (this as any)[key] = value;\n console.log(`Updated ${key} to ${value}`);\n } else {\n console.warn(`Attempted to update unknown property ${key}`);\n }\n break;\n }\n \n return true;\n };\n \n console.log('ColorMapFilter created successfully with updateUIParam method');\n return filter;\n } catch (error) {\n console.error('Failed to create ColorMapFilter:', error);\n return null;\n }\n },\n \n // Default parameter values\n defaultParams: {\n texturePath: '', // User should provide a texture path\n mix: 1, // Mix between original and mapped colors (0-1)\n nearest: false // Whether to use nearest-neighbor sampling for the texture\n },\n \n // UI controls for the filter\n controls: [\n {\n id: 'texturePath',\n type: 'select',\n label: 'Color Map',\n property: 'texturePath',\n options: [\n { label: 'Default', value: '/examples/filters-main/examples/images/colormap.png' },\n { label: 'Grayscale', value: '/examples/filters-main/examples/images/colormap-grayscale.png' },\n { label: 'Sepia', value: '/examples/filters-main/examples/images/colormap-sepia.png' },\n // Add more options as needed\n ],\n default: '/examples/filters-main/examples/images/colormap.png',\n },\n {\n id: 'mix',\n type: 'slider',\n label: 'Mix',\n property: 'mix',\n min: 0,\n max: 1,\n step: 0.01,\n default: 1,\n },\n {\n id: 'nearest',\n type: 'toggle',\n label: 'Nearest Neighbor Sampling',\n property: 'nearest',\n default: false,\n }\n ],\n});","/**\n * Color Replace Filter Definition\n * Replaces a specific color in the image with another color\n * \n * This implementation uses the proper ColorReplaceFilter from pixi-filters\n * which is compatible with PixiJS v8\n */\nimport { registerFilter } from '../registry';\n// Import from the central package for pixi filters\nimport * as PixiFilters from 'pixi-filters';\n\n// Access filter class via direct indexing with type casting to avoid TypeScript errors \n// @ts-ignore - Runtime access of property that TypeScript doesn't know about\nconst ColorReplaceFilter = PixiFilters['ColorReplaceFilter'];\n\n// Register the Color Replace filter\nexport default registerFilter({\n id: 'color-replace',\n name: 'Color Replace',\n category: 'color',\n description: 'Replaces a specific color in the image with another color',\n \n /**\n * Create an instance of ColorReplaceFilter from pixi-filters package\n * This implementation follows the pattern from ColorGradientFilter, adding\n * proper parameter handling with an updateUIParam method\n */\n createFilter: (params) => {\n try {\n console.log('Creating ColorReplaceFilter with params:', params);\n \n // Parse hex colors to numbers if they're strings\n let originalColorValue = 0xff0000; // Default red\n if (params.originalColor) {\n if (typeof params.originalColor === 'string') {\n originalColorValue = parseInt(params.originalColor.replace('#', '0x'), 16);\n } else if (typeof params.originalColor === 'number') {\n originalColorValue = params.originalColor;\n }\n }\n \n let targetColorValue = 0x0000ff; // Default blue\n if (params.targetColor) {\n if (typeof params.targetColor === 'string') {\n targetColorValue = parseInt(params.targetColor.replace('#', '0x'), 16);\n } else if (typeof params.targetColor === 'number') {\n targetColorValue = params.targetColor;\n }\n }\n \n // Create filter with proper options object for v6+\n const filter = new ColorReplaceFilter({\n originalColor: originalColorValue,\n targetColor: targetColorValue,\n tolerance: params.tolerance || 0.4\n });\n \n // Store custom parameters for later reference\n (filter as any)._customParams = { ...params };\n \n /**\n * Add a custom updateUIParam method to handle UI parameter updates\n * This is called by PixiApplication.updateFilter when UI controls change\n * and provides consistent parameter handling across all filters.\n * \n * @param key The UI parameter name\n * @param value The new value for the parameter\n */\n (filter as any).updateUIParam = function(key: string, value: any) {\n // Store UI parameters for later reference\n const customParams = (this as any)._customParams || {};\n (this as any)._customParams = customParams;\n \n // Update the stored params value\n customParams[key] = value;\n \n // Handle parameter updates based on key\n switch (key) {\n case 'originalColor':\n // Convert hex string to number for the originalColor property\n if (typeof value === 'string') {\n this.originalColor = parseInt(value.replace('#', '0x'), 16);\n console.log(`Updated originalColor to ${this.originalColor} from ${value}`);\n } else if (typeof value === 'number') {\n this.originalColor = value;\n console.log(`Updated originalColor to ${this.originalColor}`);\n }\n break;\n \n case 'targetColor':\n // Convert hex string to number for the targetColor property\n if (typeof value === 'string') {\n this.targetColor = parseInt(value.replace('#', '0x'), 16);\n console.log(`Updated targetColor to ${this.targetColor} from ${value}`);\n } else if (typeof value === 'number') {\n this.targetColor = value;\n console.log(`Updated targetColor to ${this.targetColor}`);\n }\n break;\n \n case 'tolerance':\n // Direct tolerance update\n this.tolerance = value;\n console.log(`Updated tolerance to ${this.tolerance}`);\n break;\n \n // For any other properties, try direct assignment \n default:\n if (key in this) {\n (this as any)[key] = value;\n console.log(`Updated ${key} to ${value}`);\n } else {\n console.warn(`Attempted to update unknown property ${key}`);\n }\n break;\n }\n \n return true;\n };\n \n console.log('ColorReplaceFilter created successfully with updateUIParam method');\n return filter;\n } catch (error) {\n console.error('Failed to create ColorReplaceFilter:', error);\n return null;\n }\n },\n \n // Default parameter values\n defaultParams: {\n originalColor: '#ff0000', // Red\n targetColor: '#0000ff', // Blue\n tolerance: 0.4 // Match sensitivity\n },\n \n // UI controls for the filter\n controls: [\n {\n id: 'originalColor',\n type: 'color',\n label: 'Original Color',\n property: 'originalColor',\n default: '#ff0000',\n },\n {\n id: 'targetColor',\n type: 'color',\n label: 'Target Color',\n property: 'targetColor',\n default: '#0000ff',\n },\n {\n id: 'tolerance',\n type: 'slider',\n label: 'Tolerance',\n property: 'tolerance',\n min: 0,\n max: 1,\n step: 0.01,\n default: 0.4,\n }\n ],\n});","/**\n * Multi-Color Replace Filter Definition\n * Replaces multiple colors in the image with different target colors\n * \n * This implementation uses the proper MultiColorReplaceFilter from pixi-filters\n * which is compatible with PixiJS v8\n */\nimport { registerFilter } from '../registry';\n// Import from the central package for pixi filters\nimport * as PixiFilters from 'pixi-filters';\n\n// Access filter class via direct indexing with type casting to avoid TypeScript errors \n// @ts-ignore - Runtime access of property that TypeScript doesn't know about\nconst MultiColorReplaceFilter = PixiFilters['MultiColorReplaceFilter'];\n\n// Register the Multi-Color Replace filter\nexport default registerFilter({\n id: 'multi-color-replace',\n name: 'Multi-Color Replace',\n category: 'color',\n description: 'Replaces multiple colors in the image with different target colors',\n \n /**\n * Create an instance of MultiColorReplaceFilter from pixi-filters package\n * This implementation follows the pattern from ColorGradientFilter, adding\n * proper parameter handling with an updateUIParam method\n */\n createFilter: (params) => {\n try {\n console.log('Creating MultiColorReplaceFilter with params:', params);\n \n // Prepare the replacements array with proper color value conversion\n const replacements = [];\n \n // Add first replacement pair\n if (params.originalColor1 && params.targetColor1) {\n const original = typeof params.originalColor1 === 'string' \n ? parseInt(params.originalColor1.replace('#', '0x'), 16)\n : params.originalColor1;\n const target = typeof params.targetColor1 === 'string'\n ? parseInt(params.targetColor1.replace('#', '0x'), 16)\n : params.targetColor1;\n \n replacements.push([original, target]);\n }\n \n // Add second replacement pair\n if (params.originalColor2 && params.targetColor2) {\n const original = typeof params.originalColor2 === 'string'\n ? parseInt(params.originalColor2.replace('#', '0x'), 16)\n : params.originalColor2;\n const target = typeof params.targetColor2 === 'string'\n ? parseInt(params.targetColor2.replace('#', '0x'), 16)\n : params.targetColor2;\n \n replacements.push([original, target]);\n }\n \n // Add third replacement pair if enabled\n if (params.enableThirdPair && params.originalColor3 && params.targetColor3) {\n const original = typeof params.originalColor3 === 'string'\n ? parseInt(params.originalColor3.replace('#', '0x'), 16)\n : params.originalColor3;\n const target = typeof params.targetColor3 === 'string'\n ? parseInt(params.targetColor3.replace('#', '0x'), 16)\n : params.targetColor3;\n \n replacements.push([original, target]);\n }\n \n // Create filter with PIXI v8 API (constructor takes replacements, epsilon, maxColors)\n const filter = new MultiColorReplaceFilter(\n replacements as any,\n params.tolerance || 0.05,\n 3 // Allow up to 3 color pairs\n );\n \n // Store custom parameters for later reference\n (filter as any)._customParams = { ...params };\n \n /**\n * Add a custom updateUIParam method to handle UI parameter updates\n * This is called by PixiApplication.updateFilter when UI controls change\n * and provides consistent parameter handling across all filters.\n * \n * @param key The UI parameter name\n * @param value The new value for the parameter\n */\n (filter as any).updateUIParam = function(key: string, value: any) {\n // Store UI parameters for later reference\n const customParams = (this as any)._customParams || {};\n (this as any)._customParams = customParams;\n \n // Update the stored params value\n customParams[key] = value;\n \n // Create new replacements array if needed\n \n // Process standard color pair updates\n if (key === 'originalColor1' || key === 'targetColor1' || \n key === 'originalColor2' || key === 'targetColor2' ||\n key === 'originalColor3' || key === 'targetColor3' ||\n key === 'enableThirdPair') {\n \n // Create a new replacements array based on current params\n const newReplacements = [];\n \n // Add first replacement pair\n if (customParams.originalColor1 && customParams.targetColor1) {\n const original = typeof customParams.originalColor1 === 'string' \n ? parseInt(customParams.originalColor1.replace('#', '0x'), 16)\n : customParams.originalColor1;\n const target = typeof customParams.targetColor1 === 'string'\n ? parseInt(customParams.targetColor1.replace('#', '0x'), 16)\n : customParams.targetColor1;\n \n newReplacements.push([original, target]);\n }\n \n // Add second replacement pair\n if (customParams.originalColor2 && customParams.targetColor2) {\n const original = typeof customParams.originalColor2 === 'string'\n ? parseInt(customParams.originalColor2.replace('#', '0x'), 16)\n : customParams.originalColor2;\n const target = typeof customParams.targetColor2 === 'string'\n ? parseInt(customParams.targetColor2.replace('#', '0x'), 16)\n : customParams.targetColor2;\n \n newReplacements.push([original, target]);\n }\n \n // Add third replacement pair if enabled\n if (customParams.enableThirdPair && customParams.originalColor3 && customParams.targetColor3) {\n const original = typeof customParams.originalColor3 === 'string'\n ? parseInt(customParams.originalColor3.replace('#', '0x'), 16)\n : customParams.originalColor3;\n const target = typeof customParams.targetColor3 === 'string'\n ? parseInt(customParams.targetColor3.replace('#', '0x'), 16)\n : customParams.targetColor3;\n \n newReplacements.push([original, target]);\n }\n \n // Update the replacements and refresh\n this.replacements = newReplacements;\n this.refresh(); // Apply the changes\n console.log(`Updated replacements for ${key}:`, newReplacements);\n } \n // Handle tolerance updates directly\n else if (key === 'tolerance') {\n this.tolerance = value;\n console.log(`Updated tolerance to ${this.tolerance}`);\n } \n // For any other properties, try direct assignment\n else if (key in this) {\n (this as any)[key] = value;\n console.log(`Updated ${key} to ${value}`);\n } else {\n console.warn(`Attempted to update unknown property ${key}`);\n }\n \n return true;\n };\n \n console.log('MultiColorReplaceFilter created successfully with updateUIParam method');\n return filter;\n } catch (error) {\n console.error('Failed to create MultiColorReplaceFilter:', error);\n return null;\n }\n },\n \n // Default parameter values\n defaultParams: {\n originalColor1: '#ff0000', // Red\n targetColor1: '#0000ff', // Blue\n originalColor2: '#00ff00', // Green\n targetColor2: '#ffff00', // Yellow\n enableThirdPair: false,\n originalColor3: '#ff00ff', // Magenta\n targetColor3: '#00ffff', // Cyan\n tolerance: 0.05 // Match sensitivity\n },\n \n // UI controls for the filter\n controls: [\n {\n id: 'originalColor1',\n type: 'color',\n label: 'Original Color 1',\n property: 'originalColor1',\n default: '#ff0000',\n },\n {\n id: 'targetColor1',\n type: 'color',\n label: 'Target Color 1',\n property: 'targetColor1',\n default: '#0000ff',\n },\n {\n id: 'originalColor2',\n type: 'color',\n label: 'Original Color 2',\n property: 'originalColor2',\n default: '#00ff00',\n },\n {\n id: 'targetColor2',\n type: 'color',\n label: 'Target Color 2',\n property: 'targetColor2',\n default: '#ffff00',\n },\n {\n id: 'enableThirdPair',\n type: 'toggle',\n label: 'Enable Third Color Pair',\n property: 'enableThirdPair',\n default: false,\n },\n {\n id: 'originalColor3',\n type: 'color',\n label: 'Original Color 3',\n property: 'originalColor3',\n default: '#ff00ff',\n },\n {\n id: 'targetColor3',\n type: 'color',\n label: 'Target Color 3',\n property: 'targetColor3',\n default: '#00ffff',\n },\n {\n id: 'tolerance',\n type: 'slider',\n label: 'Tolerance',\n property: 'tolerance',\n min: 0,\n max: 0.5,\n step: 0.01,\n default: 0.05,\n }\n ],\n});","/**\n * RGB Split Filter Definition\n * Displaces the red, green, and blue channels separately to create a glitch or 3D effect\n */\nimport { registerFilter } from '../registry';\n// Import from pixi-filters with wildcard and destructuring pattern\nimport * as PixiFilters from 'pixi-filters';\n// @ts-ignore - Module lacks TypeScript definitions\nconst { RGBSplitFilter } = PixiFilters;;\n\n// Register the RGB Split filter\nexport default registerFilter({\n id: 'rgb-split',\n name: 'RGB Split',\n category: 'color',\n description: 'Shifts the red, green, and blue channels to create a retro 3D or glitch effect',\n \n /**\n * Create an instance of the RGBSplitFilter with the provided parameters\n * Using the official pixi-filters implementation\n */\n createFilter: (params) => {\n try {\n console.log('Creating RGB Split filter with params:', params);\n \n // Create point objects for each channel from the params\n const red = { \n x: params.redX !== undefined ? params.redX : -10, \n y: params.redY !== undefined ? params.redY : 0 \n };\n const green = { \n x: params.greenX !== undefined ? params.greenX : 0, \n y: params.greenY !== undefined ? params.greenY : 10 \n };\n const blue = { \n x: params.blueX !== undefined ? params.blueX : 0, \n y: params.blueY !== undefined ? params.blueY : 0 \n };\n \n // Create the filter with the official pixi-filters package\n const filter = new RGBSplitFilter({\n red,\n green,\n blue\n });\n \n // Store custom parameters for later reference\n (filter as any)._customParams = { ...params };\n \n /**\n * Add a custom updateUIParam method to handle UI parameter updates\n * Following the pattern from the fix_filters.md document\n */\n (filter as any).updateUIParam = function(key: string, value: any) {\n try {\n // Store UI parameters for later reference\n const customParams = (this as any)._customParams || {};\n (this as any)._customParams = customParams;\n \n // Update the stored params value\n customParams[key] = value;\n \n // Handle parameter updates based on key\n switch (key) {\n case 'redX':\n this.redX = Number(value);\n console.log(`Updated redX to ${value}`);\n break;\n \n case 'redY':\n this.redY = Number(value);\n console.log(`Updated redY to ${value}`);\n break;\n \n case 'greenX':\n this.greenX = Number(value);\n console.log(`Updated greenX to ${value}`);\n break;\n \n case 'greenY':\n this.greenY = Number(value);\n console.log(`Updated greenY to ${value}`);\n break;\n \n case 'blueX':\n this.blueX = Number(value);\n console.log(`Updated blueX to ${value}`);\n break;\n \n case 'blueY':\n this.blueY = Number(value);\n console.log(`Updated blueY to ${value}`);\n break;\n \n // For any other properties, try direct assignment \n default:\n if (key in this) {\n this[key] = value;\n console.log(`Updated ${key} to ${value}`);\n } else {\n console.warn(`Attempted to update unknown property ${key}`);\n }\n break;\n }\n \n return true;\n } catch (error) {\n console.error(`Failed to update parameter ${key} using updateUIParam:`, error);\n \n // Still store the value in customParams even if setting it failed\n if ((this as any)._customParams) {\n (this as any)._customParams[key] = value;\n }\n \n return false;\n }\n };\n \n console.log('RGB Split filter created successfully');\n return filter;\n } catch (error) {\n console.error('Failed to create RGB Split filter:', error);\n return null;\n }\n },\n \n // Default parameter values\n defaultParams: {\n redX: -10,\n redY: 0,\n greenX: 0,\n greenY: 10,\n blueX: 0,\n blueY: 0\n },\n \n // UI controls for the filter\n controls: [\n {\n id: 'redX',\n type: 'slider',\n label: 'Red X Offset',\n property: 'redX',\n min: -20,\n max: 20,\n step: 1,\n default: -10,\n },\n {\n id: 'redY',\n type: 'slider',\n label: 'Red Y Offset',\n property: 'redY',\n min: -20,\n max: 20,\n step: 1,\n default: 0,\n },\n {\n id: 'greenX',\n type: 'slider',\n label: 'Green X Offset',\n property: 'greenX',\n min: -20,\n max: 20,\n step: 1,\n default: 0,\n },\n {\n id: 'greenY',\n type: 'slider',\n label: 'Green Y Offset',\n property: 'greenY',\n min: -20,\n max: 20,\n step: 1,\n default: 10,\n },\n {\n id: 'blueX',\n type: 'slider',\n label: 'Blue X Offset',\n property: 'blueX',\n min: -20,\n max: 20,\n step: 1,\n default: 0,\n },\n {\n id: 'blueY',\n type: 'slider',\n label: 'Blue Y Offset',\n property: 'blueY',\n min: -20,\n max: 20,\n step: 1,\n default: 0,\n }\n ],\n});","/**\n * Advanced Bloom Filter Definition\n * Applies a sophisticated bloom effect with fine-grained control over parameters\n */\nimport { registerFilter } from '../registry';\n// Import from the central package for pixi filters\nimport * as PixiFilters from 'pixi-filters';\n// Access AdvancedBloomFilter from the pixi-filters package\nconst { AdvancedBloomFilter } = PixiFilters;\n\n// Register the Advanced Bloom filter\nexport default registerFilter({\n id: 'advanced-bloom',\n name: 'Advanced Bloom',\n category: 'light',\n description: 'Adds a sophisticated bloom/glow effect with fine-grained control',\n \n // Create an instance of the AdvancedBloomFilter with the provided parameters\n createFilter: (params) => {\n try {\n console.log('Creating AdvancedBloomFilter with params:', params);\n \n // Using PixiJS v8 style options object\n const filter = new AdvancedBloomFilter({\n threshold: params.threshold || 0.5,\n bloomScale: params.bloomScale || 1.0,\n brightness: params.brightness || 1.0,\n blur: params.blur || 8,\n quality: params.quality || 4,\n pixelSize: { \n x: params.pixelSizeX || 1, \n y: params.pixelSizeY || 1 \n }\n });\n \n // Store custom params for reference\n (filter as any)._customParams = {\n pixelSizeX: params.pixelSizeX || 1,\n pixelSizeY: params.pixelSizeY || 1\n };\n \n // Add custom updateUIParam method for dynamic updates\n (filter as any).updateUIParam = function(key: string, value: any) {\n try {\n // Store UI parameters for reference\n const customParams = (this as any)._customParams || {};\n (this as any)._customParams = customParams;\n \n // Update stored params\n customParams[key] = value;\n \n switch (key) {\n case 'threshold':\n this.threshold = Number(value);\n console.log(`Updated threshold to ${this.threshold}`);\n break;\n \n case 'bloomScale':\n this.bloomScale = Number(value);\n console.log(`Updated bloomScale to ${this.bloomScale}`);\n break;\n \n case 'brightness':\n this.brightness = Number(value);\n console.log(`Updated brightness to ${this.brightness}`);\n break;\n \n case 'blur':\n this.blur = Number(value);\n console.log(`Updated blur to ${this.blur}`);\n break;\n \n case 'quality':\n this.quality = Number(value);\n console.log(`Updated quality to ${this.quality}`);\n break;\n \n case 'pixelSizeX':\n customParams.pixelSizeX = Number(value);\n // Need to update the entire pixelSize object\n this.pixelSize = { \n x: Number(value), \n y: customParams.pixelSizeY \n };\n console.log(`Updated pixelSizeX to ${value}`);\n break;\n \n case 'pixelSizeY':\n customParams.pixelSizeY = Number(value);\n // Need to update the entire pixelSize object\n this.pixelSize = { \n x: customParams.pixelSizeX, \n y: Number(value) \n };\n console.log(`Updated pixelSizeY to ${value}`);\n break;\n \n default:\n if (key in this) {\n (this as any)[key] = value;\n console.log(`Updated ${key} to ${value}`);\n } else {\n console.warn(`Unknown parameter for AdvancedBloomFilter: ${key}`);\n }\n break;\n }\n } catch (error) {\n console.error(`Error updating AdvancedBloomFilter parameter ${key}:`, error);\n }\n };\n \n console.log('AdvancedBloomFilter created successfully');\n return filter;\n } catch (error) {\n console.error('Failed to create AdvancedBloomFilter:', error);\n return null;\n }\n },\n \n // Default parameter values\n defaultParams: {\n threshold: 0.5, // Brightness threshold\n bloomScale: 1.0, // Intensity of the bloom effect\n brightness: 1.0, // Overall brightness\n blur: 8, // Blur strength\n quality: 4, // Quality of the blur (higher = better but slower)\n pixelSizeX: 1, // Horizontal pixel size\n pixelSizeY: 1 // Vertical pixel size\n },\n \n // UI controls for the filter\n controls: [\n {\n id: 'threshold',\n type: 'slider',\n label: 'Threshold',\n property: 'threshold',\n min: 0,\n max: 1,\n step: 0.01,\n default: 0.5,\n },\n {\n id: 'bloomScale',\n type: 'slider',\n label: 'Bloom Intensity',\n property: 'bloomScale',\n min: 0,\n max: 3,\n step: 0.1,\n default: 1.0,\n },\n {\n id: 'brightness',\n type: 'slider',\n label: 'Brightness',\n property: 'brightness',\n min: 0,\n max: 3,\n step: 0.1,\n default: 1.0,\n },\n {\n id: 'blur',\n type: 'slider',\n label: 'Blur Strength',\n property: 'blur',\n min: 0,\n max: 20,\n step: 1,\n default: 8,\n },\n {\n id: 'quality',\n type: 'slider',\n label: 'Quality',\n property: 'quality',\n min: 1,\n max: 10,\n step: 1,\n default: 4,\n },\n {\n id: 'pixelSizeX',\n type: 'slider',\n label: 'Pixel Size X',\n property: 'pixelSizeX',\n min: 0.5,\n max: 10,\n step: 0.5,\n default: 1,\n },\n {\n id: 'pixelSizeY',\n type: 'slider',\n label: 'Pixel Size Y',\n property: 'pixelSizeY',\n min: 0.5,\n max: 10,\n step: 0.5,\n default: 1,\n }\n ],\n});","/**\n * ASCII Filter Definition\n * Applies an ASCII art effect to the image\n */\nimport { registerFilter } from '../registry';\n// Import from the central PixiFilters export\nimport * as PixiFilters from 'pixi-filters';\n// Define AsciiFilter as a variable to allow fallback implementation\nconst AsciiFilter = (PixiFilters as any).AsciiFilter;\n\n// Register the ASCII filter\nexport default registerFilter({\n id: 'ascii',\n name: 'ASCII',\n category: 'stylize',\n description: 'Convert image to ASCII text characters',\n \n // Create an instance of the AsciiFilter with the provided parameters\n createFilter: (params) => {\n try {\n console.log('Creating AsciiFilter with params:', params);\n \n // Ensure parameters have default values if missing\n const size = typeof params.size === 'number' ? params.size : 8;\n \n // Convert color string to number if needed\n let color = params.color;\n if (typeof color === 'string' && color.startsWith('#')) {\n color = parseInt(color.replace('#', '0x'), 16);\n }\n \n const replaceColor = params.replaceColor === true;\n \n // Create the filter with proper options\n const filter = new AsciiFilter({\n size: size,\n color: color,\n replaceColor: replaceColor\n });\n \n // Store custom parameters for reference\n (filter as any)._customParams = {\n size: size,\n color: color,\n replaceColor: replaceColor\n };\n \n // Add custom updateUIParam method for dynamic parameter updates\n (filter as any).updateUIParam = function(key: string, value: any) {\n try {\n console.log(`AsciiFilter.updateUIParam called: ${key} = ${value}`);\n \n // Store UI parameters for reference\n const customParams = (this as any)._customParams || {};\n (this as any)._customParams = customParams;\n \n // Update stored params\n customParams[key] = value;\n \n // Handle parameter updates based on key\n switch (key) {\n case 'size':\n this.size = Number(value);\n console.log(`Updated size to ${this.size}`);\n break;\n \n case 'color':\n // Convert color string to number if needed\n if (typeof value === 'string' && value.startsWith('#')) {\n customParams.color = value;\n this.color = parseInt(value.replace('#', '0x'), 16);\n } else {\n this.color = value;\n }\n console.log(`Updated color to ${this.color}`);\n break;\n \n case 'replaceColor':\n this.replaceColor = Boolean(value);\n console.log(`Updated replaceColor to ${this.replaceColor}`);\n break;\n \n // For any other properties, try direct assignment\n default:\n if (key in this) {\n (this as any)[key] = value;\n console.log(`Updated ${key} to ${value}`);\n } else {\n console.warn(`Unknown parameter for AsciiFilter: ${key}`);\n }\n break;\n }\n } catch (error) {\n console.error(`Error updating AsciiFilter parameter ${key}:`, error);\n }\n };\n \n console.log('AsciiFilter created successfully');\n return filter;\n } catch (error) {\n console.error('Failed to create AsciiFilter:', error);\n return null;\n }\n },\n \n // Default parameter values\n defaultParams: {\n size: 8,\n color: '#ffffff',\n replaceColor: false\n },\n \n // UI controls for the filter\n controls: [\n {\n id: 'size',\n type: 'slider',\n label: 'Character Size',\n property: 'size',\n min: 2,\n max: 20,\n step: 1,\n default: 8,\n },\n {\n id: 'color',\n type: 'color',\n label: 'Character Color',\n property: 'color',\n default: '#ffffff',\n },\n {\n id: 'replaceColor',\n type: 'toggle',\n label: 'Replace Original Colors',\n property: 'replaceColor',\n default: false,\n }\n ],\n});","/**\n * Backdrop Blur Filter Definition\n * Applies a blur effect to the background behind an object\n * \n * IMPORTANT: This filter requires setting useBackBuffer: true in the renderer options,\n * which has been added to the PixiApplication.ts file. It's a special filter that\n * applies a blur to what's behind the objects rather than to the objects themselves.\n */\nimport { registerFilter } from '../registry';\n// Import from the central PixiFilters export\nimport * as PixiFilters from 'pixi-filters';\n// Define BackdropBlurFilter as a variable to allow fallback implementation\nconst BackdropBlurFilter = (PixiFilters as any).BackdropBlurFilter;\n\n// Register the backdrop blur filter\nexport default registerFilter({\n id: 'backdrop-blur',\n name: 'Backdrop Blur',\n category: 'blur',\n description: 'Blurs what is behind the object, creating a glass-like effect',\n \n // Create an instance of the BackdropBlurFilter with the provided parameters\n createFilter: (params) => {\n try {\n console.log('Creating BackdropBlurFilter with params:', params);\n \n // Create filter with options object\n // This is a special filter - it inherits from BlurFilter but adds a blend pass\n // to apply the blur only to what's behind the object\n const filter = new BackdropBlurFilter({\n // Higher strength values (20-50) make the effect more noticeable\n strength: params.strength || 20, \n quality: params.quality || 4,\n // Lower resolution values (0.2-0.5) can make the effect more visible but less sharp\n resolution: params.resolution || 0.5,\n kernelSize: params.kernelSize || 9\n });\n \n // Store custom params for reference\n (filter as any)._customParams = { ...params };\n \n // Add custom updateUIParam method for dynamic updates\n (filter as any).updateUIParam = function(key: string, value: any) {\n try {\n // Store UI parameters for reference\n const customParams = (this as any)._customParams || {};\n (this as any)._customParams = customParams;\n \n // Update stored params\n customParams[key] = value;\n \n // Handle all supported parameters\n switch (key) {\n case 'strength':\n // Higher strength values will make the effect more visible\n this.strength = Number(value);\n // For this filter, we can also update blur, which is a deprecated alias\n // but might be used internally\n this.blur = Number(value) / 4; // Scale down for blur property\n console.log(`Updated strength to ${this.strength}`);\n break;\n \n case 'quality':\n this.quality = Number(value);\n console.log(`Updated quality to ${this.quality}`);\n break;\n \n case 'resolution':\n // Lower resolution values make the effect more pronounced\n this.resolution = Number(value);\n console.log(`Updated resolution to ${this.resolution}`);\n break;\n \n case 'kernelSize':\n // Larger kernel sizes increase the blur radius and quality\n const kernelSize = Number(value);\n \n // Update both the X and Y kernel sizes\n if (this.blurXFilter && this.blurYFilter) {\n this.blurXFilter.kernelSize = kernelSize;\n this.blurYFilter.kernelSize = kernelSize;\n } else {\n // Fallback for older versions\n (this as any).kernelSize = kernelSize;\n }\n \n console.log(`Updated kernelSize to ${kernelSize}`);\n break;\n \n // For any other properties that might exist directly on the filter\n default:\n if (key in this) {\n (this as any)[key] = value;\n console.log(`Updated ${key} to ${value}`);\n } else {\n console.warn(`Unknown parameter for BackdropBlurFilter: ${key}`);\n }\n break;\n }\n } catch (error) {\n console.error(`Error updating BackdropBlurFilter parameter ${key}:`, error);\n }\n };\n \n // Log successful creation\n console.log('BackdropBlurFilter created successfully');\n \n return filter;\n } catch (error) {\n console.error('Failed to create BackdropBlurFilter:', error);\n return null;\n }\n },\n \n // Default parameter values - optimized for better visibility\n defaultParams: {\n strength: 20, // Higher value for stronger effect\n quality: 4, // Moderate quality for performance\n resolution: 0.5, // Lower resolution makes effect more visible\n kernelSize: 9 // Larger kernel for wider blur\n },\n \n // UI controls for the filter\n controls: [\n {\n id: 'strength',\n type: 'slider',\n label: 'Strength',\n property: 'strength',\n min: 0,\n max: 50, // Increased max to allow stronger effects\n step: 1,\n default: 20,\n },\n {\n id: 'quality',\n type: 'slider',\n label: 'Quality',\n property: 'quality',\n min: 1,\n max: 10,\n step: 1,\n default: 4,\n },\n {\n id: 'resolution',\n type: 'slider',\n label: 'Resolution',\n property: 'resolution',\n min: 0.1,\n max: 1, // Reduced max to focus on lower values that show effect better\n step: 0.1,\n default: 0.5,\n },\n {\n id: 'kernelSize',\n type: 'select',\n label: 'Kernel Size',\n property: 'kernelSize',\n options: [\n { label: '5', value: 5 },\n { label: '7', value: 7 },\n { label: '9', value: 9 },\n { label: '11', value: 11 },\n { label: '13', value: 13 },\n { label: '15', value: 15 },\n ],\n default: 9,\n },\n ],\n});","/**\n * Bevel Filter Definition\n * Applies a beveled edge effect to the image\n */\nimport { registerFilter } from '../registry';\n// Import from the central package for pixi filters\nimport * as PixiFilters from 'pixi-filters';\n// Access BevelFilter from the pixi-filters package\nconst { BevelFilter } = PixiFilters;\n\n// Register the Bevel filter\nexport default registerFilter({\n id: 'bevel',\n name: 'Bevel',\n category: 'effects',\n description: 'Add a 3D-like beveled edge effect to the image',\n \n /**\n * Create an instance of the BevelFilter with the provided parameters\n * Using the official pixi-filters implementation\n */\n createFilter: (params) => {\n try {\n console.log('Creating Bevel filter with params:', params);\n \n // Parse colors from hex strings\n const lightColor = params.lightColor ? params.lightColor.replace('#', '0x') : '0xffffff';\n const shadowColor = params.shadowColor ? params.shadowColor.replace('#', '0x') : '0x000000';\n \n // Create the filter with the official pixi-filters package\n const filter = new BevelFilter({\n rotation: params.rotation !== undefined ? params.rotation : 45,\n thickness: params.thickness !== undefined ? params.thickness : 2,\n lightColor: parseInt(lightColor, 16),\n lightAlpha: params.lightAlpha !== undefined ? params.lightAlpha : 0.7,\n shadowColor: parseInt(shadowColor, 16),\n shadowAlpha: params.shadowAlpha !== undefined ? params.shadowAlpha : 0.7\n });\n \n // Store custom parameters for later reference\n (filter as any)._customParams = { ...params };\n \n /**\n * Add a custom updateUIParam method to handle UI parameter updates\n * Following the pattern from the fix_filters.md document\n */\n (filter as any).updateUIParam = function(key: string, value: any) {\n try {\n // Store UI parameters for later reference\n const customParams = (this as any)._customParams || {};\n (this as any)._customParams = customParams;\n \n // Update the stored params value\n customParams[key] = value;\n \n // Handle parameter updates based on key\n switch (key) {\n case 'rotation':\n this.rotation = Number(value);\n console.log(`Updated rotation to ${value}`);\n break;\n \n case 'thickness':\n this.thickness = Number(value);\n console.log(`Updated thickness to ${value}`);\n break;\n \n case 'lightColor':\n // Convert hex string to number for the lightColor property\n if (typeof value === 'string') {\n const colorNum = parseInt(value.replace('#', '0x'), 16);\n this.lightColor = colorNum;\n console.log(`Updated lightColor to ${value} (${colorNum})`);\n }\n break;\n \n case 'lightAlpha':\n this.lightAlpha = Number(value);\n console.log(`Updated lightAlpha to ${value}`);\n break;\n \n case 'shadowColor':\n // Convert hex string to number for the shadowColor property\n if (typeof value === 'string') {\n const colorNum = parseInt(value.replace('#', '0x'), 16);\n this.shadowColor = colorNum;\n console.log(`Updated shadowColor to ${value} (${colorNum})`);\n }\n break;\n \n case 'shadowAlpha':\n this.shadowAlpha = Number(value);\n console.log(`Updated shadowAlpha to ${value}`);\n break;\n \n // For any other properties, try direct assignment \n default:\n if (key in this) {\n this[key] = value;\n console.log(`Updated ${key} to ${value}`);\n } else {\n console.warn(`Attempted to update unknown property ${key}`);\n }\n break;\n }\n \n return true;\n } catch (error) {\n console.error(`Failed to update parameter ${key} using updateUIParam:`, error);\n \n // Still store the value in customParams even if setting it failed\n if ((this as any)._customParams) {\n (this as any)._customParams[key] = value;\n }\n \n return false;\n }\n };\n \n console.log('Bevel filter created successfully');\n return filter;\n } catch (error) {\n console.error('Failed to create Bevel filter:', error);\n return null;\n }\n },\n \n // Default parameter values\n defaultParams: {\n rotation: 45,\n thickness: 2,\n lightColor: '#ffffff',\n lightAlpha: 0.7,\n shadowColor: '#000000',\n shadowAlpha: 0.7\n },\n \n // UI controls for the filter\n controls: [\n {\n id: 'rotation',\n type: 'slider',\n label: 'Angle',\n property: 'rotation',\n min: 0,\n max: 360,\n step: 1,\n default: 45,\n },\n {\n id: 'thickness',\n type: 'slider',\n label: 'Thickness',\n property: 'thickness',\n min: 0,\n max: 10,\n step: 0.1,\n default: 2,\n },\n {\n id: 'lightColor',\n type: 'color',\n label: 'Light Color',\n property: 'lightColor',\n default: '#ffffff',\n },\n {\n id: 'lightAlpha',\n type: 'slider',\n label: 'Light Opacity',\n property: 'lightAlpha',\n min: 0,\n max: 1,\n step: 0.01,\n default: 0.7,\n },\n {\n id: 'shadowColor',\n type: 'color',\n label: 'Shadow Color',\n property: 'shadowColor',\n default: '#000000',\n },\n {\n id: 'shadowAlpha',\n type: 'slider',\n label: 'Shadow Opacity',\n property: 'shadowAlpha',\n min: 0,\n max: 1,\n step: 0.01,\n default: 0.7,\n }\n ],\n});","/**\n * Bloom Filter Definition\n * Creates a glowing effect by emphasizing bright areas\n */\nimport { registerFilter } from '../registry';\nimport * as PixiFilters from 'pixi-filters';\n// @ts-ignore - Module lacks TypeScript definitions\nconst { BloomFilter } = PixiFilters;\n\n// Register the bloom filter\nexport default registerFilter({\n id: 'bloom',\n name: 'Bloom/Glow',\n category: 'light',\n description: 'Add a subtle glow effect to bright areas of the image',\n \n // Create an instance of the BloomFilter with the provided parameters\n createFilter: (params) => {\n try {\n console.log('Creating BloomFilter with params:', params);\n \n // Ensure parameters have default values if missing\n const strengthX = typeof params.strengthX === 'number' ? params.strengthX : 2;\n const strengthY = typeof params.strengthY === 'number' ? params.strengthY : 2;\n const quality = typeof params.quality === 'number' ? params.quality : 4;\n const resolution = typeof params.resolution === 'number' ? params.resolution : 1;\n const kernelSize = typeof params.kernelSize === 'number' ? params.kernelSize : 5;\n \n // Create the filter with proper options - force cast types to numbers\n const filter = new BloomFilter({\n strength: { \n x: Number(strengthX), \n y: Number(strengthY)\n },\n quality: Number(quality),\n resolution: Number(resolution),\n kernelSize: Number(kernelSize)\n });\n \n // Log the actual filter object to see its properties\n console.log('Created BloomFilter instance with properties:', {\n strength: filter.strength,\n quality: (filter as any).quality,\n resolution: filter.resolution,\n kernelSize: (filter as any).kernelSize\n });\n \n // Store custom parameters for reference\n (filter as any)._customParams = {\n strengthX: strengthX,\n strengthY: strengthY,\n quality: quality,\n resolution: resolution,\n kernelSize: kernelSize\n };\n \n // Add a more direct approach to updateUIParam method for dynamic parameter updates\n (filter as any).updateUIParam = function(key: string, value: any) {\n try {\n console.log(`BloomFilter.updateUIParam called: ${key} = ${value}`);\n \n // Force numeric conversion\n const numValue = Number(value);\n \n // Store UI parameters for reference\n const customParams = (this as any)._customParams || {};\n (this as any)._customParams = customParams;\n \n // Update stored params\n customParams[key] = numValue;\n \n // Handle parameter updates based on key\n switch (key) {\n case 'strengthX':\n // Direct property access to ensure the update happens\n if (this.strength && typeof this.strength === 'object') {\n this.strength.x = numValue;\n // Force a refresh of the internal filters\n this._updateStrength?.();\n console.log(`Updated strengthX to ${numValue}`, this.strength);\n } else {\n console.warn('Filter strength property not found or not an object');\n }\n break;\n \n case 'strengthY':\n // Direct property access to ensure the update happens\n if (this.strength && typeof this.strength === 'object') {\n this.strength.y = numValue;\n // Force a refresh of the internal filters\n this._updateStrength?.();\n console.log(`Updated strengthY to ${numValue}`, this.strength);\n } else {\n console.warn('Filter strength property not found or not an object');\n }\n break;\n \n case 'quality':\n (this as any).quality = numValue;\n console.log(`Updated quality to ${(this as any).quality}`);\n break;\n\n case 'resolution':\n this.resolution = numValue;\n console.log(`Updated resolution to ${this.resolution}`);\n break;\n\n case 'kernelSize':\n (this as any).kernelSize = numValue;\n console.log(`Updated kernelSize to ${(this as any).kernelSize}`);\n break;\n \n // For any other properties, try direct assignment\n default:\n if (key in this) {\n (this as any)[key] = numValue;\n console.log(`Updated ${key} to ${numValue}`);\n } else {\n console.warn(`Unknown parameter for BloomFilter: ${key}`);\n }\n break;\n }\n \n // Log the current state after updates\n console.log('BloomFilter state after update:', {\n strength: this.strength,\n quality: (this as any).quality,\n resolution: this.resolution,\n kernelSize: (this as any).kernelSize\n });\n } catch (error) {\n console.error(`Error updating BloomFilter parameter ${key}:`, error);\n }\n };\n \n console.log('BloomFilter created successfully');\n return filter;\n } catch (error) {\n console.error('Failed to create BloomFilter:', error);\n return null;\n }\n },\n \n // Default parameter values\n defaultParams: {\n strengthX: 2,\n strengthY: 2,\n quality: 4,\n resolution: 1,\n kernelSize: 5\n },\n \n // UI controls for the filter\n controls: [\n {\n id: 'strengthX',\n type: 'slider',\n label: 'Horizontal Strength',\n property: 'strengthX',\n min: 0,\n max: 20,\n step: 0.1,\n default: 2,\n },\n {\n id: 'strengthY',\n type: 'slider',\n label: 'Vertical Strength',\n property: 'strengthY',\n min: 0,\n max: 20,\n step: 0.1,\n default: 2,\n },\n {\n id: 'quality',\n type: 'slider',\n label: 'Quality',\n property: 'quality',\n min: 1,\n max: 10,\n step: 1,\n default: 4,\n },\n {\n id: 'kernelSize',\n type: 'select',\n label: 'Kernel Size',\n property: 'kernelSize',\n options: [\n { label: '5', value: 5 },\n { label: '7', value: 7 },\n { label: '9', value: 9 },\n { label: '11', value: 11 },\n { label: '13', value: 13 },\n { label: '15', value: 15 }\n ],\n default: 5,\n }\n ],\n});","/**\n * Bulge Pinch Filter Definition\n * Creates a bulge or pinch effect in a circular area\n */\nimport { registerFilter } from '../registry';\n// Import the BulgePinchFilter using wildcard import pattern\nimport * as PixiFilters from 'pixi-filters';\n// @ts-ignore - Module lacks TypeScript definitions\nconst { BulgePinchFilter } = PixiFilters;\n\n// Register the Bulge Pinch filter\nexport default registerFilter({\n id: 'bulge-pinch', // ID must match what the application expects\n name: 'Bulge/Pinch',\n category: 'distortion',\n description: 'Creates a bulge or pinch effect in a circular area',\n \n // Create an instance of the BulgePinchFilter with the provided parameters\n createFilter: (params) => {\n try {\n console.log('Creating BulgePinchFilter with params:', params);\n \n // Extract parameters with defaults\n const centerX = params.centerX ?? 0.5;\n const centerY = params.centerY ?? 0.5;\n const radius = params.radius ?? 100;\n const strength = params.strength ?? 1;\n \n // Create the filter with PixiJS v8 style options object\n const filter = new BulgePinchFilter({\n center: {\n x: centerX,\n y: centerY\n },\n radius: radius,\n strength: strength\n });\n \n // Store custom parameters for later reference\n (filter as any)._customParams = { ...params };\n \n /**\n * Custom method to handle UI parameter updates\n * This is called by PixiApplication.updateFilter when UI controls change\n */\n (filter as any).updateUIParam = function(key: string, value: any) {\n // Store UI parameters for later reference\n const customParams = (this as any)._customParams || {};\n (this as any)._customParams = customParams;\n \n // Update the stored params value\n customParams[key] = value;\n \n // Handle parameter updates based on key\n switch (key) {\n case 'centerX':\n if (!this.center) this.center = { x: 0.5, y: 0.5 };\n this.center.x = value;\n console.log(`Updated center.x to ${value}`);\n break;\n \n case 'centerY':\n if (!this.center) this.center = { x: 0.5, y: 0.5 };\n this.center.y = value;\n console.log(`Updated center.y to ${value}`);\n break;\n \n case 'radius':\n case 'strength':\n this[key] = value;\n console.log(`Updated ${key} to ${value}`);\n break;\n \n // For any other properties, try direct assignment \n default:\n if (key in this) {\n (this as any)[key] = value;\n console.log(`Updated ${key} to ${value}`);\n } else {\n console.warn(`Attempted to update unknown property ${key}`);\n }\n break;\n }\n \n return true;\n };\n \n console.log('BulgePinchFilter created successfully with updateUIParam method');\n return filter;\n } catch (error) {\n console.error('Failed to create BulgePinchFilter:', error);\n return null;\n }\n },\n \n // Default parameter values\n defaultParams: {\n centerX: 0.5,\n centerY: 0.5,\n radius: 100,\n strength: 1\n },\n \n // UI controls for the filter\n controls: [\n {\n id: 'centerX',\n type: 'slider',\n label: 'Center X',\n property: 'centerX',\n min: 0,\n max: 1,\n step: 0.01,\n default: 0.5,\n },\n {\n id: 'centerY',\n type: 'slider',\n label: 'Center Y',\n property: 'centerY',\n min: 0,\n max: 1,\n step: 0.01,\n default: 0.5,\n },\n {\n id: 'radius',\n type: 'slider',\n label: 'Radius',\n property: 'radius',\n min: 0,\n max: 1000,\n step: 1,\n default: 100,\n },\n {\n id: 'strength',\n type: 'slider',\n label: 'Strength',\n property: 'strength',\n min: -1,\n max: 1,\n step: 0.01,\n default: 1,\n }\n ],\n});","/**\n * Convolution Matrix Filter Definition\n * Applies a matrix convolution filter for effects like blur, sharpen, edge detection\n */\nimport { registerFilter } from '../registry';\n// Import from the central package for pixi filters\nimport * as PixiFilters from 'pixi-filters';\n// Access ConvolutionFilter from the pixi-filters package\nconst { ConvolutionFilter } = PixiFilters;\n\n// Predefined convolution matrices for common effects\nconst MATRICES = {\n normal: [0, 0, 0, 0, 1, 0, 0, 0, 0],\n gaussianBlur: [0.045, 0.122, 0.045, 0.122, 0.332, 0.122, 0.045, 0.122, 0.045],\n boxBlur: [1/9, 1/9, 1/9, 1/9, 1/9, 1/9, 1/9, 1/9, 1/9],\n edgeDetection: [-1, -1, -1, -1, 8, -1, -1, -1, -1],\n edgeEnhance: [0, 0, 0, -1, 1, 0, 0, 0, 0],\n emboss: [-2, -1, 0, -1, 1, 1, 0, 1, 2],\n sharpen: [0, -1, 0, -1, 5, -1, 0, -1, 0],\n sobelHorizontal: [1, 2, 1, 0, 0, 0, -1, -2, -1],\n sobelVertical: [1, 0, -1, 2, 0, -2, 1, 0, -1],\n};\n\nexport default registerFilter({\n id: 'convolution',\n name: 'Convolution Matrix',\n category: 'effects',\n description: 'Apply custom image effects using matrix convolution',\n \n createFilter: (params) => {\n try {\n console.log('Creating ConvolutionFilter with params:', params);\n \n // Get the appropriate matrix based on the selected preset or use custom values\n let matrix;\n \n if (params.customMatrix) {\n // Create matrix from individual matrix element values\n matrix = [\n params.m00, params.m01, params.m02,\n params.m10, params.m11, params.m12,\n params.m20, params.m21, params.m22\n ];\n } else {\n // Use preset matrix with type safety\n const presetKey = params.preset as keyof typeof MATRICES;\n matrix = MATRICES[presetKey] || MATRICES.normal;\n }\n \n // Create the filter with direct constructor call (PIXI v8 API)\n const filter = new ConvolutionFilter(matrix as any, params.width || 200, params.height || 200);\n\n // Store custom params for UI updates\n (filter as any)._customParams = { ...params };\n \n // Add custom updateUIParam method for UI parameter handling\n (filter as any).updateUIParam = function(key: string, value: any) {\n // Store the updated parameter\n const customParams = (this as any)._customParams || {};\n (this as any)._customParams = customParams;\n customParams[key] = value;\n \n switch (key) {\n case 'preset':\n // Update matrix from preset\n if (!customParams.customMatrix) {\n const presetKey = value as keyof typeof MATRICES;\n if (MATRICES[presetKey]) {\n this.matrix = MATRICES[presetKey];\n }\n }\n break;\n \n case 'customMatrix':\n // Toggle between preset and custom matrix\n if (value) {\n // Switch to custom matrix - copy current values to individual parameters\n const currentMatrix = this.matrix;\n customParams.m00 = currentMatrix[0];\n customParams.m01 = currentMatrix[1];\n customParams.m02 = currentMatrix[2];\n customParams.m10 = currentMatrix[3];\n customParams.m11 = currentMatrix[4];\n customParams.m12 = currentMatrix[5];\n customParams.m20 = currentMatrix[6];\n customParams.m21 = currentMatrix[7];\n customParams.m22 = currentMatrix[8];\n } else {\n // Switch back to preset\n const presetKey = customParams.preset as keyof typeof MATRICES;\n this.matrix = MATRICES[presetKey] || MATRICES.normal;\n }\n break;\n \n // Handle individual matrix element updates\n case 'm00': case 'm01': case 'm02':\n case 'm10': case 'm11': case 'm12':\n case 'm20': case 'm21': case 'm22':\n if (customParams.customMatrix) {\n // Update the matrix if in custom matrix mode\n const newMatrix = [...this.matrix];\n \n // Map UI parameter to matrix index\n const indices: Record<string, number> = {\n 'm00': 0, 'm01': 1, 'm02': 2,\n 'm10': 3, 'm11': 4, 'm12': 5,\n 'm20': 6, 'm21': 7, 'm22': 8\n };\n \n const idx = indices[key];\n if (idx !== undefined) {\n newMatrix[idx] = value;\n this.matrix = newMatrix;\n }\n }\n break;\n \n case 'width':\n this.width = value;\n break;\n \n case 'height':\n this.height = value;\n break;\n \n default:\n // For any other parameters that might exist directly on the filter\n if (key in this) {\n (this as any)[key] = value;\n }\n break;\n }\n };\n \n return filter;\n } catch (error) {\n console.error('Failed to create ConvolutionFilter:', error);\n return null;\n }\n },\n \n defaultParams: {\n preset: 'normal',\n customMatrix: false,\n m00: 0, m01: 0, m02: 0,\n m10: 0, m11: 1, m12: 0,\n m20: 0, m21: 0, m22: 0,\n width: 200,\n height: 200\n },\n \n controls: [\n {\n id: 'preset',\n type: 'select',\n label: 'Effect Preset',\n property: 'preset',\n options: [\n { value: 'normal', label: 'Normal' },\n { value: 'gaussianBlur', label: 'Gaussian Blur' },\n { value: 'boxBlur', label: 'Box Blur' },\n { value: 'edgeDetection', label: 'Edge Detection' },\n { value: 'edgeEnhance', label: 'Edge Enhance' },\n { value: 'emboss', label: 'Emboss' },\n { value: 'sharpen', label: 'Sharpen' },\n { value: 'sobelHorizontal', label: 'Sobel Horizontal' },\n { value: 'sobelVertical', label: 'Sobel Vertical' }\n ],\n default: 'normal'\n },\n {\n id: 'customMatrix',\n type: 'toggle',\n label: 'Use Custom Matrix',\n property: 'customMatrix',\n default: false\n },\n {\n id: 'width',\n type: 'slider',\n label: 'Width',\n property: 'width',\n min: 50,\n max: 500,\n step: 10,\n default: 200\n },\n {\n id: 'height',\n type: 'slider',\n label: 'Height',\n property: 'height',\n min: 50,\n max: 500,\n step: 10,\n default: 200\n },\n {\n id: 'm00',\n type: 'slider',\n label: 'Matrix [0,0]',\n property: 'm00',\n min: -5,\n max: 5,\n step: 0.1,\n default: 0\n },\n {\n id: 'm01',\n type: 'slider',\n label: 'Matrix [0,1]',\n property: 'm01',\n min: -5,\n max: 5,\n step: 0.1,\n default: 0\n },\n {\n id: 'm02',\n type: 'slider',\n label: 'Matrix [0,2]',\n property: 'm02',\n min: -5,\n max: 5,\n step: 0.1,\n default: 0\n },\n {\n id: 'm10',\n type: 'slider',\n label: 'Matrix [1,0]',\n property: 'm10',\n min: -5,\n max: 5,\n step: 0.1,\n default: 0\n },\n {\n id: 'm11',\n type: 'slider',\n label: 'Matrix [1,1]',\n property: 'm11',\n min: -5,\n max: 5,\n step: 0.1,\n default: 1\n },\n {\n id: 'm12',\n type: 'slider',\n label: 'Matrix [1,2]',\n property: 'm12',\n min: -5,\n max: 5,\n step: 0.1,\n default: 0\n },\n {\n id: 'm20',\n type: 'slider',\n label: 'Matrix [2,0]',\n property: 'm20',\n min: -5,\n max: 5,\n step: 0.1,\n default: 0\n },\n {\n id: 'm21',\n type: 'slider',\n label: 'Matrix [2,1]',\n property: 'm21',\n min: -5,\n max: 5,\n step: 0.1,\n default: 0\n },\n {\n id: 'm22',\n type: 'slider',\n label: 'Matrix [2,2]',\n property: 'm22',\n min: -5,\n max: 5,\n step: 0.1,\n default: 0\n }\n ]\n});","/**\n * Cross Hatch Filter Definition\n * Creates a crosshatching effect like in a pencil drawing\n */\nimport { registerFilter } from '../registry';\n// Import from pixi-filters with wildcard and destructuring pattern\nimport * as PixiFilters from 'pixi-filters';\n// @ts-ignore - Module lacks TypeScript definitions\nconst { CrossHatchFilter } = PixiFilters;\n\n// Register the CrossHatch filter\nexport default registerFilter({\n id: 'cross-hatch',\n name: 'Cross Hatch',\n category: 'stylize',\n description: 'Creates a crosshatching effect like in a pencil drawing',\n \n // Create an instance of the CrossHatchFilter\n // Note: CrossHatchFilter has NO parameters according to PixiJS examples\n createFilter: (_params) => {\n try {\n console.log('Creating CrossHatchFilter');\n \n // Create the filter - CrossHatchFilter has no constructor parameters\n const filter = new CrossHatchFilter();\n \n // Add a minimal updateUIParam method for consistency\n // Even though CrossHatchFilter has no parameters to update\n (filter as any).updateUIParam = function(key: string, value: any) {\n console.log(`CrossHatchFilter has no configurable parameters. Ignoring: ${key} = ${value}`);\n return true;\n };\n \n console.log('CrossHatchFilter created successfully');\n return filter;\n } catch (error) {\n console.error('Failed to create CrossHatchFilter:', error);\n return null;\n }\n },\n \n // No parameters for this filter\n defaultParams: {},\n \n // No UI controls since CrossHatchFilter has no parameters\n controls: [],\n});","/**\n * CRT Screen Filter Definition\n * Simulates an old CRT screen with scan lines and noise\n */\nimport { registerFilter } from '../registry';\nimport * as filters from 'pixi-filters';\n\n// Register the CRT filter\nexport default registerFilter({\n id: 'crt',\n name: 'CRT Screen',\n category: 'stylize',\n description: 'Simulates an old CRT screen with scan lines and noise',\n \n // Create an instance of the CRTFilter with the provided parameters\n createFilter: (params) => {\n try {\n console.log('Creating CRTFilter with params:', params);\n \n // Ensure parameters have default values\n const options = {\n lineWidth: typeof params.lineWidth === 'number' ? params.lineWidth : 1.0,\n noise: typeof params.noise === 'number' ? params.noise : 0.3,\n curvature: typeof params.curvature === 'number' ? params.curvature : 1.0,\n lineContrast: typeof params.lineContrast === 'number' ? params.lineContrast : 0.25,\n verticalLine: params.verticalLine === true,\n noiseSize: typeof params.noiseSize === 'number' ? params.noiseSize : 1.0,\n vignetting: typeof params.vignetting === 'number' ? params.vignetting : 0.3,\n vignettingAlpha: typeof params.vignettingAlpha === 'number' ? params.vignettingAlpha : 1.0,\n vignettingBlur: typeof params.vignettingBlur === 'number' ? params.vignettingBlur : 0.3,\n time: typeof params.time === 'number' ? params.time : 0.0,\n seed: typeof params.seed === 'number' ? params.seed : Math.random()\n };\n \n // Create the filter with proper options\n const filter = new filters.CRTFilter(options);\n \n // Store custom parameters for reference\n (filter as any)._customParams = { ...options };\n \n // Add custom updateUIParam method for dynamic parameter updates\n (filter as any).updateUIParam = function(key: string, value: any) {\n try {\n console.log(`CRTFilter.updateUIParam called: ${key} = ${value}`);\n \n // Store UI parameters for reference\n const customParams = (this as any)._customParams || {};\n (this as any)._customParams = customParams;\n \n // Update stored params\n customParams[key] = value;\n \n // Handle parameter updates based on key with proper type conversion\n switch (key) {\n case 'lineWidth':\n this.lineWidth = Number(value);\n console.log(`Updated lineWidth to ${this.lineWidth}`);\n break;\n \n case 'noise':\n this.noise = Number(value);\n console.log(`Updated noise to ${this.noise}`);\n break;\n \n case 'curvature':\n this.curvature = Number(value);\n console.log(`Updated curvature to ${this.curvature}`);\n break;\n \n case 'lineContrast':\n this.lineContrast = Number(value);\n console.log(`Updated lineContrast to ${this.lineContrast}`);\n break;\n \n case 'verticalLine':\n this.verticalLine = Boolean(value);\n console.log(`Updated verticalLine to ${this.verticalLine}`);\n break;\n \n case 'noiseSize':\n this.noiseSize = Number(value);\n console.log(`Updated noiseSize to ${this.noiseSize}`);\n break;\n \n case 'vignetting':\n this.vignetting = Number(value);\n console.log(`Updated vignetting to ${this.vignetting}`);\n break;\n \n case 'vignettingAlpha':\n this.vignettingAlpha = Number(value);\n console.log(`Updated vignettingAlpha to ${this.vignettingAlpha}`);\n break;\n \n case 'vignettingBlur':\n this.vignettingBlur = Number(value);\n console.log(`Updated vignettingBlur to ${this.vignettingBlur}`);\n break;\n \n case 'time':\n this.time = Number(value);\n console.log(`Updated time to ${this.time}`);\n break;\n \n case 'seed':\n this.seed = Number(value);\n console.log(`Updated seed to ${this.seed}`);\n break;\n \n // For any other properties, try direct assignment\n default:\n if (key in this) {\n (this as any)[key] = value;\n console.log(`Updated ${key} to ${value}`);\n } else {\n console.warn(`Unknown parameter for CRTFilter: ${key}`);\n }\n break;\n }\n \n // Log current state\n console.log('CRTFilter state:', {\n lineWidth: this.lineWidth,\n noise: this.noise,\n curvature: this.curvature,\n verticalLine: this.verticalLine,\n time: this.time\n });\n } catch (error) {\n console.error(`Error updating CRTFilter parameter ${key}:`, error);\n }\n };\n \n console.log('CRTFilter created successfully');\n return filter;\n } catch (error) {\n console.error('Failed to create CRTFilter:', error);\n return null;\n }\n },\n \n // Default parameter values\n defaultParams: {\n lineWidth: 1.0,\n noise: 0.3,\n curvature: 1.0,\n lineContrast: 0.25,\n verticalLine: false,\n noiseSize: 1.0,\n vignetting: 0.3,\n vignettingAlpha: 1.0,\n vignettingBlur: 0.3,\n time: 0.0,\n seed: 1.0\n },\n \n // UI controls for the filter\n controls: [\n {\n id: 'lineWidth',\n type: 'slider',\n label: 'Scan Line Width',\n property: 'lineWidth',\n min: 0,\n max: 5,\n step: 0.1,\n default: 1.0,\n },\n {\n id: 'noise',\n type: 'slider',\n label: 'Noise Amount',\n property: 'noise',\n min: 0,\n max: 1,\n step: 0.01,\n default: 0.3,\n },\n {\n id: 'curvature',\n type: 'slider',\n label: 'Screen Curvature',\n property: 'curvature',\n min: 0,\n max: 10,\n step: 0.1,\n default: 1.0,\n },\n {\n id: 'lineContrast',\n type: 'slider',\n label: 'Line Contrast',\n property: 'lineContrast',\n min: 0,\n max: 1,\n step: 0.01,\n default: 0.25,\n },\n {\n id: 'verticalLine',\n type: 'toggle',\n label: 'Vertical Lines',\n property: 'verticalLine',\n default: false,\n },\n {\n id: 'noiseSize',\n type: 'slider',\n label: 'Noise Size',\n property: 'noiseSize',\n min: 0.5,\n max: 5,\n step: 0.1,\n default: 1.0,\n },\n {\n id: 'vignetting',\n type: 'slider',\n label: 'Vignette Size',\n property: 'vignetting',\n min: 0,\n max: 1,\n step: 0.01,\n default: 0.3,\n },\n {\n id: 'vignettingAlpha',\n type: 'slider',\n label: 'Vignette Opacity',\n property: 'vignettingAlpha',\n min: 0,\n max: 1,\n step: 0.01,\n default: 1.0,\n },\n {\n id: 'vignettingBlur',\n type: 'slider',\n label: 'Vignette Blur',\n property: 'vignettingBlur',\n min: 0,\n max: 1,\n step: 0.01,\n default: 0.3,\n },\n {\n id: 'time',\n type: 'slider',\n label: 'Animation Time',\n property: 'time',\n min: 0,\n max: 10,\n step: 0.1,\n default: 0.0,\n }\n ],\n});","/**\n * Displacement Filter Definition\n * Applies a displacement map effect to distort the image\n */\nimport { registerFilter } from '../registry';\n// Import PIXI namespace\nimport * as PIXI from 'pixi.js';\n\n// Access classes via direct indexing\n// @ts-ignore - Runtime access of property that TypeScript doesn't know about\nconst DisplacementFilter = PIXI['DisplacementFilter']; \n// @ts-ignore - Runtime access of property that TypeScript doesn't know about\nconst Sprite = PIXI['Sprite'];\n// @ts-ignore - Runtime access of property that TypeScript doesn't know about\nconst Texture = PIXI['Texture'];\n\n// Register the Displacement filter\nexport default registerFilter({\n id: 'displacement', // ID must match what the application expects\n name: 'Displacement Map',\n category: 'distortion',\n description: 'Distorts the image using a displacement map texture',\n \n // Create an instance of the DisplacementFilter with the provided parameters\n createFilter: (params) => {\n try {\n console.log('Creating DisplacementFilter with params:', params);\n \n // The displacement map texture URL (default or from params)\n const mapUrl = params.mapTexture || '/assets/images/displacement_map.png';\n \n // Create a texture from the map URL\n let mapTexture;\n try {\n mapTexture = Texture.from(mapUrl);\n // Set the texture to repeat\n mapTexture.source.addressMode = 'repeat';\n } catch (error) {\n console.error('Failed to load displacement map texture:', error);\n // Create a fallback texture\n const canvas = document.createElement('canvas');\n canvas.width = 256;\n canvas.height = 256;\n const ctx = canvas.getContext('2d');\n if (ctx) {\n // Draw a simple pattern\n ctx.fillStyle = '#ffffff';\n ctx.fillRect(0, 0, canvas.width, canvas.height);\n ctx.fillStyle = '#000000';\n for (let i = 0; i < 10; i++) {\n for (let j = 0; j < 10; j++) {\n if ((i + j) % 2 === 0) {\n ctx.fillRect(i * 25, j * 25, 25, 25);\n }\n }\n }\n }\n mapTexture = Texture.from(canvas);\n }\n \n // Create sprite for the displacement map\n const displacementSprite = new Sprite(mapTexture);\n \n // Create the filter with the sprite and scale\n const filter = new DisplacementFilter(displacementSprite, params.scale || 50);\n \n // Set individual scale components\n filter.scale.x = params.scaleX || 50;\n filter.scale.y = params.scaleY || 50;\n \n // Store custom parameters for later reference\n (filter as any)._customParams = { ...params };\n (filter as any)._displacementSprite = displacementSprite;\n \n /**\n * Custom method to handle UI parameter updates\n * This is called by PixiApplication.updateFilter when UI controls change\n */\n (filter as any).updateUIParam = function(key: string, value: any) {\n // Store UI parameters for later reference\n const customParams = (this as any)._customParams || {};\n (this as any)._customParams = customParams;\n \n // Update the stored params value\n customParams[key] = value;\n \n // Handle parameter updates based on key\n switch (key) {\n case 'scaleX':\n this.scale.x = value;\n console.log(`Updated scale.x to ${value}`);\n break;\n \n case 'scaleY':\n this.scale.y = value;\n console.log(`Updated scale.y to ${value}`);\n break;\n \n case 'mapTexture':\n try {\n // Try to update the sprite's texture\n const sprite = (this as any)._displacementSprite;\n if (sprite) {\n const newTexture = Texture.from(value);\n newTexture.source.addressMode = 'repeat';\n sprite.texture = newTexture;\n console.log(`Updated displacement map texture to ${value}`);\n }\n } catch (error) {\n console.error('Failed to update displacement map texture:', error);\n }\n break;\n \n // For any other properties, try direct assignment \n default:\n if (key in this) {\n (this as any)[key] = value;\n console.log(`Updated ${key} to ${value}`);\n } else if (key in this.scale) {\n this.scale[key] = value;\n console.log(`Updated scale.${key} to ${value}`);\n } else {\n console.warn(`Attempted to update unknown property ${key}`);\n }\n break;\n }\n \n return true;\n };\n \n console.log('DisplacementFilter created successfully with updateUIParam method');\n return filter;\n } catch (error) {\n console.error('Failed to create DisplacementFilter:', error);\n return null;\n }\n },\n \n // Default parameter values\n defaultParams: {\n mapTexture: '/assets/images/displacement_map.png',\n scale: 50,\n scaleX: 50,\n scaleY: 50\n },\n \n // UI controls for the filter\n controls: [\n {\n id: 'mapTexture',\n type: 'select',\n label: 'Displacement Map',\n property: 'mapTexture',\n options: [\n { label: 'Default', value: '/assets/images/displacement_map.png' },\n { label: 'Clouds', value: '/assets/images/clouds.png' },\n { label: 'Ripple', value: '/assets/images/ripple.png' }\n ],\n default: '/assets/images/displacement_map.png',\n },\n {\n id: 'scaleX',\n type: 'slider',\n label: 'Scale X',\n property: 'scaleX',\n min: 1,\n max: 200,\n step: 1,\n default: 50,\n },\n {\n id: 'scaleY',\n type: 'slider',\n label: 'Scale Y',\n property: 'scaleY',\n min: 1,\n max: 200,\n step: 1,\n default: 50,\n }\n ],\n});","/**\n * Dot Screen Filter Definition\n * Simulates a halftone printing pattern with dots\n */\nimport { registerFilter } from '../registry';\nimport * as filters from 'pixi-filters';\n\n// Register the Dot Screen filter\nexport default registerFilter({\n id: 'dot',\n name: 'Dot Screen',\n category: 'stylize',\n description: 'Simulates a halftone printing pattern with dots',\n \n // Create an instance of the DotFilter with the provided parameters\n createFilter: (params) => {\n try {\n console.log('Creating DotFilter with params:', params);\n \n // Ensure parameters have default values\n const options = {\n scale: typeof params.scale === 'number' ? params.scale : 1,\n angle: typeof params.angle === 'number' ? params.angle : 5,\n grayscale: params.grayscale === true\n };\n \n // Create the filter with proper options\n const filter = new filters.DotFilter(options);\n \n // Store custom parameters for reference\n (filter as any)._customParams = { ...options };\n \n // Add custom updateUIParam method for dynamic parameter updates\n (filter as any).updateUIParam = function(key: string, value: any) {\n try {\n console.log(`DotFilter.updateUIParam called: ${key} = ${value}`);\n \n // Store UI parameters for reference\n const customParams = (this as any)._customParams || {};\n (this as any)._customParams = customParams;\n \n // Update stored params\n customParams[key] = value;\n \n // Handle parameter updates based on key with proper type conversion\n switch (key) {\n case 'scale':\n this.scale = Number(value);\n console.log(`Updated scale to ${this.scale}`);\n break;\n \n case 'angle':\n this.angle = Number(value);\n console.log(`Updated angle to ${this.angle}`);\n break;\n \n case 'grayscale':\n this.grayscale = Boolean(value);\n console.log(`Updated grayscale to ${this.grayscale}`);\n break;\n \n // For any other properties, try direct assignment\n default:\n if (key in this) {\n (this as any)[key] = value;\n console.log(`Updated ${key} to ${value}`);\n } else {\n console.warn(`Unknown parameter for DotFilter: ${key}`);\n }\n break;\n }\n \n // Log current state\n console.log('DotFilter state:', {\n scale: this.scale,\n angle: this.angle,\n grayscale: this.grayscale\n });\n } catch (error) {\n console.error(`Error updating DotFilter parameter ${key}:`, error);\n }\n };\n \n console.log('DotFilter created successfully');\n return filter;\n } catch (error) {\n console.error('Failed to create DotFilter:', error);\n return null;\n }\n },\n \n // Default parameter values\n defaultParams: {\n scale: 1,\n angle: 5,\n grayscale: true\n },\n \n // UI controls for the filter\n controls: [\n {\n id: 'scale',\n type: 'slider',\n label: 'Dot Scale',\n property: 'scale',\n min: 0.5,\n max: 10,\n step: 0.1,\n default: 1,\n },\n {\n id: 'angle',\n type: 'slider',\n label: 'Dot Angle',\n property: 'angle',\n min: 0,\n max: 10,\n step: 0.1,\n default: 5,\n },\n {\n id: 'grayscale',\n type: 'toggle',\n label: 'Grayscale',\n property: 'grayscale',\n default: true,\n }\n ],\n});","/**\n * Emboss Filter Definition\n * Creates an embossed relief effect using the proper EmbossFilter from pixi-filters\n */\nimport { registerFilter } from '../registry';\n// Import EmbossFilter from pixi-filters\nimport * as PixiFilters from 'pixi-filters';\n// @ts-ignore - Module lacks TypeScript definitions\nconst { EmbossFilter } = PixiFilters;\n\n// Register the Emboss filter\nexport default registerFilter({\n id: 'emboss',\n name: 'Emboss',\n category: 'stylize',\n description: 'Creates an embossed relief effect',\n \n // Create an instance of the Emboss filter with the provided parameters\n createFilter: (params) => {\n try {\n console.log('Creating Emboss filter with params:', params);\n \n // Ensure parameters have default values\n const strength = typeof params.strength === 'number' ? params.strength : 5;\n \n // Use the proper EmbossFilter from pixi-filters\n const filter = new EmbossFilter(strength);\n \n console.log('Created emboss effect with EmbossFilter, strength:', strength);\n \n // Store custom parameters for reference\n (filter as any)._customParams = {\n strength: strength\n };\n \n // Add custom updateUIParam method for dynamic parameter updates\n (filter as any).updateUIParam = function(key: string, value: any) {\n try {\n console.log(`Emboss filter updateUIParam called: ${key} = ${value}`);\n \n // Store UI parameters for reference\n const customParams = (this as any)._customParams || {};\n (this as any)._customParams = customParams;\n \n // Update stored params\n customParams[key] = value;\n \n // Handle parameter updates\n switch (key) {\n case 'strength':\n const numValue = Number(value);\n customParams.strength = numValue;\n \n // For EmbossFilter, set the strength property directly\n this.strength = numValue;\n \n console.log(`Updated EmbossFilter strength to ${numValue}`);\n break;\n \n // For any other properties, try direct assignment\n default:\n if (key in this) {\n (this as any)[key] = value;\n console.log(`Updated ${key} to ${value}`);\n } else {\n console.warn(`Unknown parameter for EmbossFilter: ${key}`);\n }\n break;\n }\n } catch (error) {\n console.error(`Error updating emboss filter parameter ${key}:`, error);\n }\n };\n \n console.log('Emboss filter created successfully');\n return filter;\n } catch (error) {\n console.error('Failed to create emboss filter:', error);\n return null;\n }\n },\n \n // Default parameter values\n defaultParams: {\n strength: 5\n },\n \n // UI controls for the filter\n controls: [\n {\n id: 'strength',\n type: 'slider',\n label: 'Strength',\n property: 'strength',\n min: 0,\n max: 20,\n step: 0.5,\n default: 5,\n }\n ],\n});","/**\n * Glitch Filter Definition\n * Applies digital distortion and glitch effects to images\n */\nimport { registerFilter } from '../registry';\n// Import the GlitchFilter directly from pixi-filters package\n// Import from pixi-filters with wildcard and destructuring pattern\nimport * as PixiFilters from 'pixi-filters';\n// @ts-ignore - Module lacks TypeScript definitions\nconst { GlitchFilter } = PixiFilters;;\n\n// Define constants for fill modes\nconst FILL_MODES = {\n TRANSPARENT: 0,\n ORIGINAL: 1,\n LOOP: 2,\n CLAMP: 3,\n MIRROR: 4\n};\n\nexport default registerFilter({\n id: 'glitch',\n name: 'Glitch',\n category: 'effects',\n description: 'Apply digital distortion and glitch effects',\n \n createFilter: (params) => {\n try {\n console.log('Creating GlitchFilter with params:', params);\n \n // Create color offset objects from individual components\n const redOffset = { x: params.redX, y: params.redY };\n const greenOffset = { x: params.greenX, y: params.greenY };\n const blueOffset = { x: params.blueX, y: params.blueY };\n \n // Create the filter with options\n const filter = new GlitchFilter({\n slices: params.slices,\n offset: params.offset,\n direction: params.direction,\n fillMode: params.fillMode,\n seed: params.seed,\n average: params.average,\n minSize: params.minSize,\n sampleSize: params.sampleSize,\n red: redOffset,\n green: greenOffset,\n blue: blueOffset\n });\n \n // Store animation state\n (filter as any).animating = params.animating || false;\n \n // Store custom params for UI updates\n (filter as any)._customParams = { ...params };\n \n // Trigger a refresh to ensure the filter initializes correctly\n if (typeof filter.refresh === 'function') {\n filter.refresh();\n }\n \n // Set up an animation loop for the filter if it's animating\n let animationFrameId: number | null = null;\n \n const animate = () => {\n if ((filter as any).animating) {\n // Update the seed with a random value for animation\n filter.seed = Math.random();\n }\n // Continue the animation loop\n animationFrameId = requestAnimationFrame(animate);\n };\n \n // Start animation if needed\n if ((filter as any).animating) {\n animationFrameId = requestAnimationFrame(animate);\n }\n \n // Method to clean up animation when filter is destroyed\n (filter as any)._stopAnimation = () => {\n if (animationFrameId !== null) {\n cancelAnimationFrame(animationFrameId);\n animationFrameId = null;\n }\n };\n \n /**\n * Add custom updateUIParam method for dynamic UI parameter handling\n */\n (filter as any).updateUIParam = function(key: string, value: any) {\n // Store the updated parameter\n const customParams = (this as any)._customParams || {};\n (this as any)._customParams = customParams;\n customParams[key] = value;\n \n switch (key) {\n case 'animating':\n // Toggle animation state\n (this as any).animating = value;\n if (value && !animationFrameId) {\n // Start animation if it's not running\n animationFrameId = requestAnimationFrame(animate);\n }\n break;\n \n case 'slices':\n // Ensure slices is an integer\n this.slices = Math.round(value);\n break;\n \n case 'redX':\n case 'redY':\n // Update red offset\n const red = this.red;\n if (key === 'redX') red.x = value;\n else red.y = value;\n this.red = red;\n break;\n \n case 'greenX':\n case 'greenY':\n // Update green offset\n const green = this.green;\n if (key === 'greenX') green.x = value;\n else green.y = value;\n this.green = green;\n break;\n \n case 'blueX':\n case 'blueY':\n // Update blue offset\n const blue = this.blue;\n if (key === 'blueX') blue.x = value;\n else blue.y = value;\n this.blue = blue;\n break;\n \n case 'seed':\n // Only update seed manually if not animating\n if (!(this as any).animating) {\n this.seed = value;\n }\n break;\n \n case 'randomizeSeed':\n // Action button to randomize seed\n if (value && !customParams.animating) {\n this.seed = Math.random();\n }\n break;\n \n case 'refresh':\n // Action button to refresh the filter\n if (value) {\n try {\n this.refresh();\n } catch (e) {\n console.warn('Error refreshing GlitchFilter:', e);\n }\n }\n break;\n \n // Handle direct properties\n case 'offset':\n case 'direction':\n case 'fillMode':\n case 'average':\n case 'minSize':\n case 'sampleSize':\n if (key in this) {\n (this as any)[key] = value;\n }\n break;\n \n default:\n // For any other properties that might exist directly on the filter\n if (key in this) {\n (this as any)[key] = value;\n }\n break;\n }\n };\n \n return filter;\n } catch (error) {\n console.error('Failed to create GlitchFilter:', error);\n return null;\n }\n },\n \n defaultParams: {\n slices: 10,\n offset: 100,\n direction: 0,\n fillMode: FILL_MODES.LOOP, // LOOP mode looks better for the demo\n seed: 0.5,\n average: false,\n minSize: 8,\n sampleSize: 512,\n redX: 2,\n redY: 2,\n greenX: -10,\n greenY: 4,\n blueX: 10,\n blueY: -4,\n animating: false, // Control for automatic animation\n randomizeSeed: false, // Button trigger for randomizing seed\n refresh: false, // Button trigger for refreshing the filter\n },\n \n controls: [\n {\n id: 'animating',\n type: 'toggle',\n label: 'Animate Automatically',\n property: 'animating',\n default: false\n },\n {\n id: 'slices',\n type: 'slider',\n label: 'Slices',\n property: 'slices',\n min: 2,\n max: 20,\n step: 1,\n default: 10\n },\n {\n id: 'offset',\n type: 'slider',\n label: 'Offset Amount',\n property: 'offset',\n min: -400,\n max: 400,\n step: 1,\n default: 100\n },\n {\n id: 'direction',\n type: 'slider',\n label: 'Direction',\n property: 'direction',\n min: -180,\n max: 180,\n step: 1,\n default: 0\n },\n {\n id: 'fillMode',\n type: 'select',\n label: 'Fill Mode',\n property: 'fillMode',\n options: [\n { value: FILL_MODES.TRANSPARENT, label: 'Transparent' },\n { value: FILL_MODES.ORIGINAL, label: 'Original' },\n { value: FILL_MODES.LOOP, label: 'Loop' },\n { value: FILL_MODES.CLAMP, label: 'Clamp' },\n { value: FILL_MODES.MIRROR, label: 'Mirror' }\n ],\n default: FILL_MODES.LOOP\n },\n {\n id: 'seed',\n type: 'slider',\n label: 'Seed',\n property: 'seed',\n min: 0,\n max: 1,\n step: 0.01,\n default: 0.5\n },\n {\n id: 'randomizeSeed',\n type: 'button',\n label: 'Randomize Seed',\n action: 'randomizeSeed'\n },\n {\n id: 'refresh',\n type: 'button',\n label: 'Refresh Filter',\n action: 'refresh'\n },\n {\n id: 'average',\n type: 'toggle',\n label: 'Average Slices',\n property: 'average',\n default: false\n },\n // Color channel offsets\n {\n id: 'redX',\n type: 'slider',\n label: 'Red X Offset',\n property: 'redX',\n min: -50,\n max: 50,\n step: 0.5,\n default: 2\n },\n {\n id: 'redY',\n type: 'slider',\n label: 'Red Y Offset',\n property: 'redY',\n min: -50,\n max: 50,\n step: 0.5,\n default: 2\n },\n {\n id: 'greenX',\n type: 'slider',\n label: 'Green X Offset',\n property: 'greenX',\n min: -50,\n max: 50,\n step: 0.5,\n default: -10\n },\n {\n id: 'greenY',\n type: 'slider',\n label: 'Green Y Offset',\n property: 'greenY',\n min: -50,\n max: 50,\n step: 0.5,\n default: 4\n },\n {\n id: 'blueX',\n type: 'slider',\n label: 'Blue X Offset',\n property: 'blueX',\n min: -50,\n max: 50,\n step: 0.5,\n default: 10\n },\n {\n id: 'blueY',\n type: 'slider',\n label: 'Blue Y Offset',\n property: 'blueY',\n min: -50,\n max: 50,\n step: 0.5,\n default: -4\n }\n ]\n});","/**\n * Glow Filter Definition\n * Applies a customizable glow effect around the image\n */\nimport { registerFilter } from '../registry';\n// Import from pixi-filters with wildcard and destructuring pattern\nimport * as PixiFilters from 'pixi-filters';\n// @ts-ignore - Module lacks TypeScript definitions\nconst { GlowFilter } = PixiFilters;;\n\n// Register the Glow filter\nexport default registerFilter({\n id: 'glow',\n name: 'Glow',\n category: 'light',\n description: 'Adds a customizable glow effect around the image',\n \n // Create an instance of the GlowFilter with the provided parameters\n createFilter: (params) => {\n try {\n console.log('Creating GlowFilter with params:', params);\n \n // Parse color from hex string\n const color = parseInt(params.color.replace('#', '0x'), 16);\n \n // Create filter with proper options\n const filter = new GlowFilter({\n distance: params.distance || 10,\n outerStrength: params.outerStrength || 4,\n innerStrength: params.innerStrength || 0,\n color: color,\n alpha: params.alpha ?? 1,\n quality: params.quality || 0.1,\n knockout: params.knockout || false\n });\n \n // Store custom parameters for reference\n (filter as any)._customParams = { \n color: params.color || '#ffffff', \n ...params \n };\n \n // Add custom updateUIParam method for dynamic updates\n (filter as any).updateUIParam = function(key: string, value: any) {\n try {\n // Store UI parameters for reference\n const customParams = (this as any)._customParams || {};\n (this as any)._customParams = customParams;\n \n // Update stored params\n customParams[key] = value;\n \n // Handle parameter updates based on key\n switch (key) {\n case 'distance':\n this.distance = Number(value);\n console.log(`Updated distance to ${this.distance}`);\n break;\n \n case 'outerStrength':\n this.outerStrength = Number(value);\n console.log(`Updated outerStrength to ${this.outerStrength}`);\n break;\n \n case 'innerStrength':\n this.innerStrength = Number(value);\n console.log(`Updated innerStrength to ${this.innerStrength}`);\n break;\n \n case 'color':\n // Store the hex color for reference\n customParams.color = value;\n // Convert hex color string to number for the filter\n this.color = parseInt(value.replace('#', '0x'), 16);\n console.log(`Updated color to ${value} (${this.color})`);\n break;\n \n case 'alpha':\n this.alpha = Number(value);\n console.log(`Updated alpha to ${this.alpha}`);\n break;\n \n case 'quality':\n this.quality = Number(value);\n console.log(`Updated quality to ${this.quality}`);\n break;\n \n case 'knockout':\n this.knockout = Boolean(value);\n console.log(`Updated knockout to ${this.knockout}`);\n break;\n \n // For any other properties, try direct assignment\n default:\n if (key in this) {\n (this as any)[key] = value;\n console.log(`Updated ${key} to ${value}`);\n } else {\n console.warn(`Unknown parameter for GlowFilter: ${key}`);\n }\n break;\n }\n } catch (error) {\n console.error(`Error updating GlowFilter parameter ${key}:`, error);\n }\n };\n \n console.log('GlowFilter created successfully');\n return filter;\n } catch (error) {\n console.error('Failed to create GlowFilter:', error);\n return null;\n }\n },\n \n // Default parameter values\n defaultParams: {\n distance: 10,\n outerStrength: 4,\n innerStrength: 0,\n color: '#ffffff',\n alpha: 1,\n quality: 0.1,\n knockout: false\n },\n \n // UI controls for the filter\n controls: [\n {\n id: 'distance',\n type: 'slider',\n label: 'Distance',\n property: 'distance',\n min: 0,\n max: 20,\n step: 1,\n default: 10,\n },\n {\n id: 'outerStrength',\n type: 'slider',\n label: 'Outer Strength',\n property: 'outerStrength',\n min: 0,\n max: 20,\n step: 0.1,\n default: 4,\n },\n {\n id: 'innerStrength',\n type: 'slider',\n label: 'Inner Strength',\n property: 'innerStrength',\n min: 0,\n max: 20,\n step: 0.1,\n default: 0,\n },\n {\n id: 'color',\n type: 'color',\n label: 'Color',\n property: 'color',\n default: '#ffffff',\n },\n {\n id: 'alpha',\n type: 'slider',\n label: 'Alpha',\n property: 'alpha',\n min: 0,\n max: 1,\n step: 0.01,\n default: 1,\n },\n {\n id: 'quality',\n type: 'slider',\n label: 'Quality',\n property: 'quality',\n min: 0.01,\n max: 1,\n step: 0.01,\n default: 0.1,\n },\n {\n id: 'knockout',\n type: 'toggle',\n label: 'Show Glow Only',\n property: 'knockout',\n default: false,\n }\n ],\n});","/**\n * Godray Filter Definition\n * Creates volumetric light-ray effects\n */\nimport { registerFilter } from '../registry';\n// Import from pixi-filters with wildcard and destructuring pattern\nimport * as PixiFilters from 'pixi-filters';\n// @ts-ignore - Module lacks TypeScript definitions\nconst { GodrayFilter } = PixiFilters;;\n\n// Register the Godray filter\nexport default registerFilter({\n id: 'godray',\n name: 'Godray',\n category: 'light',\n description: 'Creates volumetric light-ray effects (crepuscular rays)',\n \n // Create an instance of the GodrayFilter with the provided parameters\n createFilter: (params) => {\n try {\n console.log('Creating GodrayFilter with params:', params);\n \n // Create filter with proper options\n const filter = new GodrayFilter({\n angle: params.angle || 30,\n parallel: params.parallel ?? true,\n center: { \n x: params.centerX || 0, \n y: params.centerY || 0 \n },\n gain: params.gain || 0.5,\n lacunarity: params.lacunarity || 2.5,\n time: params.time || 0,\n alpha: params.alpha || 1\n });\n \n // Store custom parameters for reference\n (filter as any)._customParams = { \n centerX: params.centerX || 0,\n centerY: params.centerY || 0,\n ...params \n };\n \n // Add custom updateUIParam method for dynamic updates\n (filter as any).updateUIParam = function(key: string, value: any) {\n try {\n // Store UI parameters for reference\n const customParams = (this as any)._customParams || {};\n (this as any)._customParams = customParams;\n \n // Update stored params\n customParams[key] = value;\n \n // Handle parameter updates based on key\n switch (key) {\n case 'angle':\n this.angle = Number(value);\n console.log(`Updated angle to ${this.angle}`);\n break;\n \n case 'parallel':\n this.parallel = Boolean(value);\n console.log(`Updated parallel to ${this.parallel}`);\n break;\n \n case 'centerX':\n customParams.centerX = Number(value);\n // Need to update the entire center object\n this.center = { \n x: Number(value), \n y: customParams.centerY \n };\n console.log(`Updated centerX to ${value}`);\n break;\n \n case 'centerY':\n customParams.centerY = Number(value);\n // Need to update the entire center object\n this.center = { \n x: customParams.centerX, \n y: Number(value) \n };\n console.log(`Updated centerY to ${value}`);\n break;\n \n case 'gain':\n this.gain = Number(value);\n console.log(`Updated gain to ${this.gain}`);\n break;\n \n case 'lacunarity':\n this.lacunarity = Number(value);\n console.log(`Updated lacunarity to ${this.lacunarity}`);\n break;\n \n case 'time':\n this.time = Number(value);\n console.log(`Updated time to ${this.time}`);\n break;\n \n case 'alpha':\n this.alpha = Number(value);\n console.log(`Updated alpha to ${this.alpha}`);\n break;\n \n // For any other properties, try direct assignment\n default:\n if (key in this) {\n (this as any)[key] = value;\n console.log(`Updated ${key} to ${value}`);\n } else {\n console.warn(`Unknown parameter for GodrayFilter: ${key}`);\n }\n break;\n }\n } catch (error) {\n console.error(`Error updating GodrayFilter parameter ${key}:`, error);\n }\n };\n \n console.log('GodrayFilter created successfully');\n return filter;\n } catch (error) {\n console.error('Failed to create GodrayFilter:', error);\n return null;\n }\n },\n \n // Default parameter values\n defaultParams: {\n angle: 30,\n parallel: true,\n centerX: 0,\n centerY: 0,\n gain: 0.5,\n lacunarity: 2.5,\n time: 0,\n alpha: 1\n },\n \n // UI controls for the filter\n controls: [\n {\n id: 'angle',\n type: 'slider',\n label: 'Angle',\n property: 'angle',\n min: 0,\n max: 360,\n step: 1,\n default: 30,\n },\n {\n id: 'parallel',\n type: 'toggle',\n label: 'Parallel Rays',\n property: 'parallel',\n default: true,\n },\n {\n id: 'centerX',\n type: 'slider',\n label: 'Light Source X',\n property: 'centerX',\n min: -1,\n max: 1,\n step: 0.01,\n default: 0,\n },\n {\n id: 'centerY',\n type: 'slider',\n label: 'Light Source Y',\n property: 'centerY',\n min: -1,\n max: 1,\n step: 0.01,\n default: 0,\n },\n {\n id: 'gain',\n type: 'slider',\n label: 'Gain/Intensity',\n property: 'gain',\n min: 0,\n max: 1,\n step: 0.01,\n default: 0.5,\n },\n {\n id: 'lacunarity',\n type: 'slider',\n label: 'Density',\n property: 'lacunarity',\n min: 0.1,\n max: 10,\n step: 0.1,\n default: 2.5,\n },\n {\n id: 'time',\n type: 'slider',\n label: 'Time',\n property: 'time',\n min: 0,\n max: 10,\n step: 0.1,\n default: 0,\n },\n {\n id: 'alpha',\n type: 'slider',\n label: 'Alpha',\n property: 'alpha',\n min: 0,\n max: 1,\n step: 0.01,\n default: 1,\n }\n ],\n});","/**\n * Lightmap Filter Definition\n * Applies a lighting effect using a reference texture as a light map\n */\nimport { registerFilter } from '../registry';\n// Import packages\nimport * as PixiFilters from 'pixi-filters';\nimport * as PIXI from 'pixi.js';\n\n// Access classes via direct indexing\n// @ts-ignore - Runtime access of property that TypeScript doesn't know about\nconst SimpleLightmapFilter = PixiFilters['SimpleLightmapFilter'];\n// @ts-ignore - Runtime access of property that TypeScript doesn't know about\nconst Texture = PIXI['Texture'];\n\n// Register the Lightmap filter\nexport default registerFilter({\n id: 'lightmap',\n name: 'Lightmap',\n category: 'light',\n description: 'Applies lighting effects using a reference texture as a light map',\n \n // Create an instance of the SimpleLightmapFilter with the provided parameters\n createFilter: (params) => {\n try {\n console.log('Creating SimpleLightmapFilter with params:', params);\n \n // Ensure we have default values\n const textureType = params.textureType || 'default';\n const colorValue = params.color || '#000000';\n const alphaValue = typeof params.alpha === 'number' ? params.alpha : 1;\n \n // Create canvas for texture generation\n const canvas = document.createElement('canvas');\n canvas.width = 256;\n canvas.height = 256;\n const ctx = canvas.getContext('2d');\n \n if (!ctx) {\n console.error('Could not get 2D context for canvas');\n throw new Error('Canvas 2D context not available');\n }\n \n // Generate a texture based on the selected type\n if (textureType === 'spotlight') {\n // Create a stronger spotlight effect\n ctx.fillStyle = 'black';\n ctx.fillRect(0, 0, 256, 256);\n \n const gradient = ctx.createRadialGradient(128, 128, 5, 128, 128, 80);\n gradient.addColorStop(0, 'white');\n gradient.addColorStop(0.5, 'rgba(255, 255, 255, 0.5)'); // Stronger middle\n gradient.addColorStop(1, 'rgba(0, 0, 0, 0)');\n \n ctx.fillStyle = gradient;\n ctx.beginPath();\n ctx.arc(128, 128, 100, 0, Math.PI * 2);\n ctx.fill();\n \n console.log('Generated spotlight texture with stronger center');\n } else if (textureType === 'softlight') {\n // Create a more pronounced soft light effect\n const gradient = ctx.createLinearGradient(0, 0, 256, 256);\n gradient.addColorStop(0, 'white');\n gradient.addColorStop(0.3, 'rgba(220, 220, 220, 1)');\n gradient.addColorStop(0.7, 'rgba(150, 150, 150, 1)');\n gradient.addColorStop(1, 'rgba(80, 80, 80, 1)');\n \n ctx.fillStyle = gradient;\n ctx.fillRect(0, 0, 256, 256);\n \n console.log('Generated enhanced softlight texture');\n } else {\n // Default - create a more pronounced radial gradient\n const gradient = ctx.createRadialGradient(128, 128, 10, 128, 128, 160);\n gradient.addColorStop(0, 'white');\n gradient.addColorStop(0.3, 'rgba(220, 220, 220, 1)');\n gradient.addColorStop(0.6, 'rgba(150, 150, 150, 1)');\n gradient.addColorStop(1, 'black');\n \n ctx.fillStyle = gradient;\n ctx.fillRect(0, 0, 256, 256);\n \n console.log('Generated enhanced default texture');\n }\n \n // Create a texture from the canvas\n const lightMapTexture = Texture.from(canvas);\n console.log('Created lightmap texture from canvas');\n \n // Parse color from hex string with safer parsing\n let color;\n try {\n // Handle potential bad color input\n if (typeof colorValue === 'string' && colorValue.startsWith('#')) {\n color = parseInt(colorValue.replace('#', '0x'), 16);\n } else {\n color = 0x000000; // Default black\n }\n } catch (e) {\n console.warn('Error parsing color, using default black');\n color = 0x000000;\n }\n \n // Create filter with proper options\n const filter = new SimpleLightmapFilter(lightMapTexture, color, alphaValue);\n \n // Store custom parameters for reference\n (filter as any)._customParams = {\n textureType: textureType,\n color: colorValue,\n alpha: alphaValue\n };\n \n // Add custom updateUIParam method with improved parameter handling\n (filter as any).updateUIParam = function(key: string, value: any) {\n try {\n console.log(`SimpleLightmapFilter.updateUIParam called: ${key} = ${value}`);\n \n // Store UI parameters for reference\n const customParams = (this as any)._customParams || {};\n (this as any)._customParams = customParams;\n \n // Update stored params\n customParams[key] = value;\n \n // Handle parameter updates based on key\n switch (key) {\n case 'textureType':\n customParams.textureType = value;\n \n // Create a new canvas with the selected texture type\n const updateCanvas = document.createElement('canvas');\n updateCanvas.width = 256;\n updateCanvas.height = 256;\n const updateCtx = updateCanvas.getContext('2d');\n \n if (updateCtx) {\n // Generate texture based on type with stronger effects\n if (value === 'spotlight') {\n updateCtx.fillStyle = 'black';\n updateCtx.fillRect(0, 0, 256, 256);\n \n const gradient = updateCtx.createRadialGradient(128, 128, 5, 128, 128, 80);\n gradient.addColorStop(0, 'white');\n gradient.addColorStop(0.5, 'rgba(255, 255, 255, 0.5)');\n gradient.addColorStop(1, 'rgba(0, 0, 0, 0)');\n \n updateCtx.fillStyle = gradient;\n updateCtx.beginPath();\n updateCtx.arc(128, 128, 100, 0, Math.PI * 2);\n updateCtx.fill();\n } else if (value === 'softlight') {\n const gradient = updateCtx.createLinearGradient(0, 0, 256, 256);\n gradient.addColorStop(0, 'white');\n gradient.addColorStop(0.3, 'rgba(220, 220, 220, 1)');\n gradient.addColorStop(0.7, 'rgba(150, 150, 150, 1)');\n gradient.addColorStop(1, 'rgba(80, 80, 80, 1)');\n \n updateCtx.fillStyle = gradient;\n updateCtx.fillRect(0, 0, 256, 256);\n } else {\n const gradient = updateCtx.createRadialGradient(128, 128, 10, 128, 128, 160);\n gradient.addColorStop(0, 'white');\n gradient.addColorStop(0.3, 'rgba(220, 220, 220, 1)');\n gradient.addColorStop(0.6, 'rgba(150, 150, 150, 1)');\n gradient.addColorStop(1, 'black');\n \n updateCtx.fillStyle = gradient;\n updateCtx.fillRect(0, 0, 256, 256);\n }\n \n // Create a new texture\n const newTexture = Texture.from(updateCanvas);\n \n // Update the filter - directly access the property\n this.lightMap = newTexture;\n \n // Force the filter to redraw by invalidating the transform\n if (this.enabled !== undefined) {\n // Toggle enabled to force a redraw\n const wasEnabled = this.enabled;\n this.enabled = false;\n setTimeout(() => {\n this.enabled = wasEnabled;\n }, 0);\n }\n \n console.log(`Updated lightMap texture to ${value} type`);\n }\n break;\n \n case 'color':\n // Store the hex color for reference\n customParams.color = value;\n // Convert hex color string to number for the filter with safe parsing\n try {\n if (typeof value === 'string' && value.startsWith('#')) {\n this.color = parseInt(value.replace('#', '0x'), 16);\n } else {\n this.color = 0x000000; // Default black\n }\n } catch (e) {\n this.color = 0x000000;\n }\n console.log(`Updated color to ${value} (${this.color})`);\n break;\n \n case 'alpha':\n // Directly set the alpha value - this is the intensity of the effect\n this.alpha = Number(value);\n \n // Log the actual value for debugging\n console.log(`Updated alpha to ${this.alpha}, actual filter:`, {\n alpha: this.alpha,\n color: this.color,\n hasLightmap: !!this.lightMap\n });\n break;\n \n // For any other properties, try direct assignment\n default:\n if (key in this) {\n (this as any)[key] = value;\n console.log(`Updated ${key} to ${value}`);\n } else {\n console.warn(`Unknown parameter for SimpleLightmapFilter: ${key}`);\n }\n break;\n }\n } catch (error) {\n console.error(`Error updating SimpleLightmapFilter parameter ${key}:`, error);\n }\n };\n \n // Log the created filter properties for debugging\n console.log('SimpleLightmapFilter created successfully:', {\n alpha: filter.alpha,\n color: filter.color,\n hasLightmap: !!filter.lightMap\n });\n \n return filter;\n } catch (error) {\n console.error('Failed to create SimpleLightmapFilter:', error);\n return null;\n }\n },\n \n // Default parameter values\n defaultParams: {\n textureType: 'default',\n color: '#000000', // Ambient color (black typically)\n alpha: 1 // Coefficient for alpha multiplication\n },\n \n // UI controls for the filter\n controls: [\n {\n id: 'textureType',\n type: 'select',\n label: 'Light Map Type',\n property: 'textureType',\n options: [\n { label: 'Default', value: 'default' },\n { label: 'Spotlight', value: 'spotlight' },\n { label: 'Soft Light', value: 'softlight' }\n ],\n default: 'default',\n },\n {\n id: 'color',\n type: 'color',\n label: 'Ambient Color',\n property: 'color',\n default: '#000000',\n },\n {\n id: 'alpha',\n type: 'slider',\n label: 'Intensity', // Renamed from Alpha to Intensity for clarity\n property: 'alpha',\n min: 0,\n max: 1,\n step: 0.01,\n default: 1,\n }\n ],\n});","/**\n * Noise Filter Definition\n * Adds random noise to the image\n */\nimport { registerFilter } from '../registry';\n// Import directly from PixiJS (not pixi-filters) as this is a built-in filter\n// Import from pixi.js with namespace\nimport * as PIXI from 'pixi.js';\n// @ts-ignore - Module structure doesn't match TypeScript definitions\nconst { NoiseFilter } = PIXI;;\n\nexport default registerFilter({\n id: 'noise',\n name: 'Noise',\n category: 'effects',\n description: 'Add random noise to the image',\n \n createFilter: (params) => {\n try {\n console.log('Creating NoiseFilter with params:', params);\n \n // Create the filter with direct options\n const filter = new NoiseFilter({\n noise: params.noise || 0.5,\n seed: params.seed || Math.random()\n });\n \n // Store animation state\n (filter as any).animating = params.animating || false;\n \n // Store custom params for UI updates\n (filter as any)._customParams = { ...params };\n \n // Set up animation loop for randomizing seed if animation is enabled\n let animationFrameId: number | null = null;\n \n const animate = () => {\n if ((filter as any).animating) {\n // Update with a new random seed for animation\n filter.seed = Math.random();\n }\n animationFrameId = requestAnimationFrame(animate);\n };\n \n // Start animation if enabled\n if ((filter as any).animating) {\n animationFrameId = requestAnimationFrame(animate);\n }\n \n // Method to clean up animation when filter is destroyed\n (filter as any)._stopAnimation = () => {\n if (animationFrameId !== null) {\n cancelAnimationFrame(animationFrameId);\n animationFrameId = null;\n }\n };\n \n /**\n * Add custom updateUIParam method for UI parameter handling\n */\n (filter as any).updateUIParam = function(key: string, value: any) {\n // Store the updated parameter\n const customParams = (this as any)._customParams || {};\n (this as any)._customParams = customParams;\n customParams[key] = value;\n \n switch (key) {\n case 'animating':\n // Toggle animation state\n (this as any).animating = value;\n if (value && !animationFrameId) {\n // Start animation if not already running\n animationFrameId = requestAnimationFrame(animate);\n }\n break;\n \n case 'noise':\n // Update noise amount (with validation) - PIXI NoiseFilter expects 0-1 range\n this.noise = Math.max(0, Math.min(1, value));\n break;\n \n case 'seed':\n // Only update seed manually if not animating\n if (!(this as any).animating) {\n this.seed = value;\n }\n break;\n \n case 'randomizeSeed':\n // Button action to randomize seed\n if (value) {\n this.seed = Math.random();\n }\n break;\n \n default:\n // For any other properties that might exist directly on the filter\n if (key in this) {\n (this as any)[key] = value;\n }\n break;\n }\n };\n \n return filter;\n } catch (error) {\n console.error('Failed to create NoiseFilter:', error);\n return null;\n }\n },\n \n defaultParams: {\n noise: 0.5,\n seed: 0.5,\n animating: false,\n randomizeSeed: false\n },\n \n controls: [\n {\n id: 'animating',\n type: 'toggle',\n label: 'Animate Noise',\n property: 'animating',\n default: false\n },\n {\n id: 'noise',\n type: 'slider',\n label: 'Noise Amount',\n property: 'noise',\n min: 0,\n max: 1,\n step: 0.01,\n default: 0.5\n },\n {\n id: 'seed',\n type: 'slider',\n label: 'Random Seed',\n property: 'seed',\n min: 0,\n max: 1,\n step: 0.01,\n default: 0.5\n },\n {\n id: 'randomizeSeed',\n type: 'button',\n label: 'Randomize Seed',\n action: 'randomizeSeed'\n }\n ]\n});","/**\n * Old Film Filter Definition\n * Applies a vintage film effect with sepia tone, scratches, grain, and vignetting\n */\nimport { registerFilter } from '../registry';\n// Import the OldFilmFilter directly from pixi-filters package\n// Import from pixi-filters with wildcard and destructuring pattern\nimport * as PixiFilters from 'pixi-filters';\n// @ts-ignore - Module lacks TypeScript definitions\nconst { OldFilmFilter } = PixiFilters;;\n\nexport default registerFilter({\n id: 'old-film',\n name: 'Old Film',\n category: 'effects',\n description: 'Apply a vintage film effect with scratches and grain',\n \n createFilter: (params) => {\n try {\n console.log('Creating OldFilmFilter with params:', params);\n \n // Create the filter with direct options\n const filter = new OldFilmFilter({\n sepia: params.sepia,\n noise: params.noise,\n noiseSize: params.noiseSize,\n scratch: params.scratch,\n scratchDensity: params.scratchDensity,\n scratchWidth: params.scratchWidth,\n vignetting: params.vignetting,\n vignettingAlpha: params.vignettingAlpha,\n vignettingBlur: params.vignettingBlur,\n seed: params.seed || Math.random()\n });\n \n // Store animation state\n (filter as any).animating = params.animating || false;\n \n // Store custom params for UI updates\n (filter as any)._customParams = { ...params };\n \n // Set up animation loop for randomizing seed if animation is enabled\n let animationFrameId: number | null = null;\n \n const animate = () => {\n if ((filter as any).animating) {\n // Update with a new random seed for animation\n filter.seed = Math.random();\n }\n animationFrameId = requestAnimationFrame(animate);\n };\n \n // Start animation if enabled\n if ((filter as any).animating) {\n animationFrameId = requestAnimationFrame(animate);\n }\n \n // Method to clean up animation when filter is destroyed\n (filter as any)._stopAnimation = () => {\n if (animationFrameId !== null) {\n cancelAnimationFrame(animationFrameId);\n animationFrameId = null;\n }\n };\n \n /**\n * Add custom updateUIParam method for UI parameter handling\n */\n (filter as any).updateUIParam = function(key: string, value: any) {\n // Store the updated parameter\n const customParams = (this as any)._customParams || {};\n (this as any)._customParams = customParams;\n customParams[key] = value;\n \n switch (key) {\n case 'animating':\n // Toggle animation state\n (this as any).animating = value;\n if (value && !animationFrameId) {\n // Start animation if not already running\n animationFrameId = requestAnimationFrame(animate);\n }\n break;\n \n case 'seed':\n // Only update seed manually if not animating\n if (!(this as any).animating) {\n this.seed = value;\n }\n break;\n \n case 'randomizeSeed':\n // Button action to randomize seed\n if (value) {\n this.seed = Math.random();\n }\n break;\n \n // Direct properties that are part of the OldFilmFilter\n case 'sepia':\n case 'noise':\n case 'noiseSize':\n case 'scratch':\n case 'scratchDensity':\n case 'scratchWidth':\n case 'vignetting':\n case 'vignettingAlpha':\n case 'vignettingBlur':\n // Apply with validation if needed\n if (key in this) {\n (this as any)[key] = value;\n }\n break;\n \n default:\n // For any other properties that might exist directly on the filter\n if (key in this) {\n (this as any)[key] = value;\n }\n break;\n }\n };\n \n return filter;\n } catch (error) {\n console.error('Failed to create OldFilmFilter:', error);\n return null;\n }\n },\n \n defaultParams: {\n sepia: 0.3,\n noise: 0.3,\n noiseSize: 1,\n scratch: 0.5,\n scratchDensity: 0.3,\n scratchWidth: 1,\n vignetting: 0.3,\n vignettingAlpha: 1,\n vignettingBlur: 0.3,\n seed: 0.5,\n animating: false,\n randomizeSeed: false\n },\n \n controls: [\n {\n id: 'animating',\n type: 'toggle',\n label: 'Animate Film',\n property: 'animating',\n default: false\n },\n {\n id: 'sepia',\n type: 'slider',\n label: 'Sepia Tone',\n property: 'sepia',\n min: 0,\n max: 1,\n step: 0.01,\n default: 0.3\n },\n {\n id: 'noise',\n type: 'slider',\n label: 'Noise Amount',\n property: 'noise',\n min: 0,\n max: 1,\n step: 0.01,\n default: 0.3\n },\n {\n id: 'noiseSize',\n type: 'slider',\n label: 'Noise Size',\n property: 'noiseSize',\n min: 1,\n max: 10,\n step: 0.1,\n default: 1\n },\n {\n id: 'scratch',\n type: 'slider',\n label: 'Scratch Amount',\n property: 'scratch',\n min: -1,\n max: 1,\n step: 0.01,\n default: 0.5\n },\n {\n id: 'scratchDensity',\n type: 'slider',\n label: 'Scratch Density',\n property: 'scratchDensity',\n min: 0,\n max: 1,\n step: 0.01,\n default: 0.3\n },\n {\n id: 'scratchWidth',\n type: 'slider',\n label: 'Scratch Width',\n property: 'scratchWidth',\n min: 1,\n max: 20,\n step: 1,\n default: 1\n },\n {\n id: 'vignetting',\n type: 'slider',\n label: 'Vignette Size',\n property: 'vignetting',\n min: 0,\n max: 1,\n step: 0.01,\n default: 0.3\n },\n {\n id: 'vignettingAlpha',\n type: 'slider',\n label: 'Vignette Opacity',\n property: 'vignettingAlpha',\n min: 0,\n max: 1,\n step: 0.01,\n default: 1\n },\n {\n id: 'vignettingBlur',\n type: 'slider',\n label: 'Vignette Blur',\n property: 'vignettingBlur',\n min: 0,\n max: 1,\n step: 0.01,\n default: 0.3\n },\n {\n id: 'seed',\n type: 'slider',\n label: 'Random Seed',\n property: 'seed',\n min: 0,\n max: 1,\n step: 0.01,\n default: 0.5\n },\n {\n id: 'randomizeSeed',\n type: 'button',\n label: 'Randomize Seed',\n action: 'randomizeSeed'\n }\n ]\n});","/**\n * Outline Filter Definition\n * Adds an outline/stroke around the image\n */\nimport { registerFilter } from '../registry';\n// Import the OutlineFilter directly from pixi-filters package\n// Import from pixi-filters with wildcard and destructuring pattern\nimport * as PixiFilters from 'pixi-filters';\n// @ts-ignore - Module lacks TypeScript definitions\nconst { OutlineFilter } = PixiFilters;;\n\nexport default registerFilter({\n id: 'outline',\n name: 'Outline',\n category: 'effects',\n description: 'Add an outline or stroke around the image',\n \n createFilter: (params) => {\n try {\n console.log('Creating OutlineFilter with params:', params);\n \n // Parse color from hex string if needed\n let color = params.color;\n if (typeof color === 'string') {\n color = parseInt(color.replace('#', '0x'), 16);\n }\n \n // Create the filter with direct options\n const filter = new OutlineFilter({\n thickness: params.thickness || 4,\n color: color,\n alpha: params.alpha || 1,\n quality: params.quality || 0.1,\n knockout: params.knockout || false\n });\n \n // Store custom params for UI updates\n (filter as any)._customParams = { ...params };\n \n // Add custom updateUIParam method for UI parameter handling\n (filter as any).updateUIParam = function(key: string, value: any) {\n // Store the updated parameter\n const customParams = (this as any)._customParams || {};\n (this as any)._customParams = customParams;\n customParams[key] = value;\n \n switch (key) {\n case 'thickness':\n // Apply with validation (non-negative)\n this.thickness = Math.max(0, value);\n break;\n \n case 'color':\n // Handle color in different formats\n if (typeof value === 'string') {\n // Convert hex string to number\n this.color = parseInt(value.replace('#', '0x'), 16);\n customParams.color = value; // Store the string version for UI\n } else {\n // Direct numeric assignment\n this.color = value;\n }\n break;\n \n case 'alpha':\n // Apply with validation (0-1 range)\n this.alpha = Math.max(0, Math.min(1, value));\n break;\n \n case 'quality':\n // Apply with validation (0.01-1 range for performance reasons)\n this.quality = Math.max(0.01, Math.min(1, value));\n break;\n \n case 'knockout':\n // Boolean toggle\n this.knockout = !!value;\n break;\n \n default:\n // For any other properties that might exist directly on the filter\n if (key in this) {\n (this as any)[key] = value;\n }\n break;\n }\n };\n \n return filter;\n } catch (error) {\n console.error('Failed to create OutlineFilter:', error);\n return null;\n }\n },\n \n defaultParams: {\n thickness: 4,\n color: '#000000',\n alpha: 1,\n quality: 0.1,\n knockout: false\n },\n \n controls: [\n {\n id: 'thickness',\n type: 'slider',\n label: 'Thickness',\n property: 'thickness',\n min: 0,\n max: 20,\n step: 0.1,\n default: 4\n },\n {\n id: 'color',\n type: 'color',\n label: 'Color',\n property: 'color',\n default: '#000000'\n },\n {\n id: 'alpha',\n type: 'slider',\n label: 'Alpha',\n property: 'alpha',\n min: 0,\n max: 1,\n step: 0.01,\n default: 1\n },\n {\n id: 'quality',\n type: 'slider',\n label: 'Quality',\n property: 'quality',\n min: 0.01,\n max: 1,\n step: 0.01,\n default: 0.1,\n tooltip: 'Higher values give better quality but slower performance'\n },\n {\n id: 'knockout',\n type: 'toggle',\n label: 'Outline Only',\n property: 'knockout',\n default: false,\n tooltip: 'Only show the outline, not the image content'\n }\n ]\n});","/**\n * Pixelate Filter Definition\n * Creates a pixelated mosaic effect by reducing the resolution in specific areas\n */\nimport { registerFilter } from '../registry';\n// Import the PixelateFilter directly from pixi-filters package\n// Import from pixi-filters with wildcard and destructuring pattern\nimport * as PixiFilters from 'pixi-filters';\n// @ts-ignore - Module lacks TypeScript definitions\nconst { PixelateFilter } = PixiFilters;;\n\nexport default registerFilter({\n id: 'pixelate',\n name: 'Pixelate',\n category: 'effects',\n description: 'Create a pixelated or mosaic effect',\n \n createFilter: (params) => {\n try {\n console.log('Creating PixelateFilter with params:', params);\n \n // Create the filter with correct parameters\n // If separate X and Y values are provided, use them\n // Otherwise, use a single size value for both dimensions\n const filter = new PixelateFilter(\n params.useUniform \n ? Math.max(4, params.size || 10) \n : [Math.max(4, params.sizeX || 10), Math.max(4, params.sizeY || 10)]\n );\n \n // Store custom params for UI updates\n (filter as any)._customParams = { ...params };\n \n /**\n * Add custom updateUIParam method for UI parameter handling\n */\n (filter as any).updateUIParam = function(key: string, value: any) {\n // Store the updated parameter\n const customParams = (this as any)._customParams || {};\n (this as any)._customParams = customParams;\n customParams[key] = value;\n \n switch (key) {\n case 'useUniform':\n // Toggle between uniform (single value) or separate x/y values\n customParams.useUniform = value;\n if (value) {\n // Switch to uniform size - use average of X and Y\n const avgSize = Math.round((this.sizeX + this.sizeY) / 2);\n this.size = Math.max(4, avgSize);\n customParams.size = avgSize;\n } else {\n // Switch to separate values - use current size for both\n const currentSize = Array.isArray(this.size) ? this.size[0] : this.size;\n this.sizeX = Math.max(4, currentSize);\n this.sizeY = Math.max(4, currentSize);\n customParams.sizeX = this.sizeX;\n customParams.sizeY = this.sizeY;\n }\n break;\n \n case 'size':\n // Update uniform size (both X and Y the same)\n if (customParams.useUniform) {\n this.size = Math.max(4, value);\n }\n break;\n \n case 'sizeX':\n // Update only X dimension\n if (!customParams.useUniform) {\n this.sizeX = Math.max(4, value);\n }\n break;\n \n case 'sizeY':\n // Update only Y dimension\n if (!customParams.useUniform) {\n this.sizeY = Math.max(4, value);\n }\n break;\n \n default:\n // For any other properties that might exist on the filter\n if (key in this) {\n (this as any)[key] = value;\n }\n break;\n }\n };\n \n return filter;\n } catch (error) {\n console.error('Failed to create PixelateFilter:', error);\n return null;\n }\n },\n \n defaultParams: {\n useUniform: true,\n size: 10,\n sizeX: 10,\n sizeY: 10\n },\n \n controls: [\n {\n id: 'useUniform',\n type: 'toggle',\n label: 'Uniform Pixels',\n property: 'useUniform',\n default: true,\n tooltip: 'Use the same size for both X and Y dimensions'\n },\n {\n id: 'size',\n type: 'slider',\n label: 'Pixel Size',\n property: 'size',\n min: 4,\n max: 40,\n step: 1,\n default: 10,\n tooltip: 'Size of the pixels in both dimensions'\n },\n {\n id: 'sizeX',\n type: 'slider',\n label: 'Horizontal Size',\n property: 'sizeX',\n min: 4,\n max: 40,\n step: 1,\n default: 10,\n tooltip: 'Size of the pixels in the horizontal direction'\n },\n {\n id: 'sizeY',\n type: 'slider',\n label: 'Vertical Size',\n property: 'sizeY',\n min: 4,\n max: 40,\n step: 1,\n default: 10,\n tooltip: 'Size of the pixels in the vertical direction'\n }\n ]\n});","/**\n * Reflection Filter Definition\n * Creates a water reflection effect with configurable waves\n */\nimport { registerFilter } from '../registry';\n// Import the ReflectionFilter directly from pixi-filters package\n// Import from pixi-filters with wildcard and destructuring pattern\nimport * as PixiFilters from 'pixi-filters';\n// @ts-ignore - Module lacks TypeScript definitions\nconst { ReflectionFilter } = PixiFilters;;\n\n// Register the Reflection filter\nexport default registerFilter({\n id: 'reflection', // ID must match what the application expects\n name: 'Reflection',\n category: 'distortion',\n description: 'Creates a water reflection effect with configurable waves',\n \n // Create an instance of the ReflectionFilter with the provided parameters\n createFilter: (params) => {\n try {\n console.log('Creating ReflectionFilter with params:', params);\n \n // Extract parameters with defaults\n const options = {\n mirror: params.mirror ?? true,\n boundary: params.boundary ?? 0.5,\n amplitude: new Float32Array([params.amplitudeStart ?? 0, params.amplitudeEnd ?? 20]),\n waveLength: new Float32Array([params.wavelengthStart ?? 30, params.wavelengthEnd ?? 100]),\n alpha: new Float32Array([params.alphaStart ?? 1, params.alphaEnd ?? 1]),\n time: params.time ?? 0\n };\n\n // Create the filter with PixiJS v8 style options object\n const filter = new ReflectionFilter(options as any);\n \n // Store custom parameters for later reference\n (filter as any)._customParams = { ...params };\n \n // Add an animating flag for potential animation support\n (filter as any).animating = params.animating ?? false;\n \n /**\n * Custom method to handle UI parameter updates\n * This is called by PixiApplication.updateFilter when UI controls change\n */\n (filter as any).updateUIParam = function(key: string, value: any) {\n // Store UI parameters for later reference\n const customParams = (this as any)._customParams || {};\n (this as any)._customParams = customParams;\n \n // Update the stored params value\n customParams[key] = value;\n \n // Handle parameter updates based on key\n switch (key) {\n case 'mirror':\n case 'boundary':\n case 'time':\n this[key] = value;\n console.log(`Updated ${key} to ${value}`);\n break;\n \n case 'amplitudeStart':\n if (!Array.isArray(this.amplitude)) {\n this.amplitude = [0, this._customParams.amplitudeEnd || 20];\n }\n this.amplitude[0] = value;\n console.log(`Updated amplitude[0] to ${value}`);\n break;\n \n case 'amplitudeEnd':\n if (!Array.isArray(this.amplitude)) {\n this.amplitude = [this._customParams.amplitudeStart || 0, 20];\n }\n this.amplitude[1] = value;\n console.log(`Updated amplitude[1] to ${value}`);\n break;\n \n case 'wavelengthStart':\n if (!Array.isArray(this.waveLength)) {\n this.waveLength = [30, this._customParams.wavelengthEnd || 100];\n }\n this.waveLength[0] = value;\n console.log(`Updated waveLength[0] to ${value}`);\n break;\n \n case 'wavelengthEnd':\n if (!Array.isArray(this.waveLength)) {\n this.waveLength = [this._customParams.wavelengthStart || 30, 100];\n }\n this.waveLength[1] = value;\n console.log(`Updated waveLength[1] to ${value}`);\n break;\n \n case 'alphaStart':\n if (!Array.isArray(this.alpha)) {\n this.alpha = [1, this._customParams.alphaEnd || 1];\n }\n this.alpha[0] = value;\n console.log(`Updated alpha[0] to ${value}`);\n break;\n \n case 'alphaEnd':\n if (!Array.isArray(this.alpha)) {\n this.alpha = [this._customParams.alphaStart || 1, 1];\n }\n this.alpha[1] = value;\n console.log(`Updated alpha[1] to ${value}`);\n break;\n \n case 'animating':\n (this as any).animating = value;\n console.log(`Updated animating to ${value}`);\n break;\n \n // For any other properties, try direct assignment \n default:\n if (key in this) {\n (this as any)[key] = value;\n console.log(`Updated ${key} to ${value}`);\n } else {\n console.warn(`Attempted to update unknown property ${key}`);\n }\n break;\n }\n \n return true;\n };\n \n console.log('ReflectionFilter created successfully with updateUIParam method');\n return filter;\n } catch (error) {\n console.error('Failed to create ReflectionFilter:', error);\n return null;\n }\n },\n \n // Default parameter values\n defaultParams: {\n mirror: true,\n boundary: 0.5,\n amplitudeStart: 0,\n amplitudeEnd: 20,\n wavelengthStart: 30,\n wavelengthEnd: 100,\n alphaStart: 1,\n alphaEnd: 1,\n time: 0,\n animating: false\n },\n \n // UI controls for the filter\n controls: [\n {\n id: 'mirror',\n type: 'toggle',\n label: 'Mirror Image',\n property: 'mirror',\n default: true,\n },\n {\n id: 'boundary',\n type: 'slider',\n label: 'Boundary Line',\n property: 'boundary',\n min: 0,\n max: 1,\n step: 0.01,\n default: 0.5,\n },\n {\n id: 'amplitudeStart',\n type: 'slider',\n label: 'Wave Height (Start)',\n property: 'amplitudeStart',\n min: 0,\n max: 50,\n step: 1,\n default: 0,\n },\n {\n id: 'amplitudeEnd',\n type: 'slider',\n label: 'Wave Height (End)',\n property: 'amplitudeEnd',\n min: 0,\n max: 50,\n step: 1,\n default: 20,\n },\n {\n id: 'wavelengthStart',\n type: 'slider',\n label: 'Wave Length (Start)',\n property: 'wavelengthStart',\n min: 10,\n max: 200,\n step: 1,\n default: 30,\n },\n {\n id: 'wavelengthEnd',\n type: 'slider',\n label: 'Wave Length (End)',\n property: 'wavelengthEnd',\n min: 10,\n max: 200,\n step: 1,\n default: 100,\n },\n {\n id: 'alphaStart',\n type: 'slider',\n label: 'Opacity (Start)',\n property: 'alphaStart',\n min: 0,\n max: 1,\n step: 0.01,\n default: 1,\n },\n {\n id: 'alphaEnd',\n type: 'slider',\n label: 'Opacity (End)',\n property: 'alphaEnd',\n min: 0,\n max: 1,\n step: 0.01,\n default: 1,\n },\n {\n id: 'time',\n type: 'slider',\n label: 'Animation Time',\n property: 'time',\n min: 0,\n max: 10,\n step: 0.1,\n default: 0,\n },\n {\n id: 'animating',\n type: 'toggle',\n label: 'Auto Animate',\n property: 'animating',\n default: false,\n }\n ],\n});","/**\n * Shockwave Filter Definition\n * Creates a rippling shockwave effect\n */\nimport { registerFilter } from '../registry';\n// Import the ShockwaveFilter directly from pixi-filters package\n// Import from pixi-filters with wildcard and destructuring pattern\nimport * as PixiFilters from 'pixi-filters';\n// @ts-ignore - Module lacks TypeScript definitions\nconst { ShockwaveFilter } = PixiFilters;;\n\n// Register the Shockwave filter\nexport default registerFilter({\n id: 'shockwave', // ID must match what the application expects\n name: 'Shockwave',\n category: 'distortion',\n description: 'Creates a rippling shockwave or blast wave effect',\n \n // Create an instance of the ShockwaveFilter with the provided parameters\n createFilter: (params) => {\n try {\n console.log('Creating ShockwaveFilter with params:', params);\n \n // Extract parameters with defaults\n const centerX = params.centerX ?? 0.5;\n const centerY = params.centerY ?? 0.5;\n const center = { x: centerX, y: centerY };\n const amplitude = params.amplitude ?? 30;\n const wavelength = params.wavelength ?? 160;\n const speed = params.speed ?? 500;\n const brightness = params.brightness ?? 1;\n const radius = params.radius ?? -1;\n const time = params.time ?? 0;\n \n // Create the filter with PixiJS v8 style options object\n const filter = new ShockwaveFilter({\n center,\n amplitude,\n wavelength,\n speed,\n brightness,\n radius,\n time\n });\n \n // Store custom parameters for later reference\n (filter as any)._customParams = { ...params };\n \n // Add an animating flag for potential animation support\n (filter as any).animating = params.animating ?? false;\n \n /**\n * Custom method to handle UI parameter updates\n * This is called by PixiApplication.updateFilter when UI controls change\n */\n (filter as any).updateUIParam = function(key: string, value: any) {\n // Store UI parameters for later reference\n const customParams = (this as any)._customParams || {};\n (this as any)._customParams = customParams;\n \n // Update the stored params value\n customParams[key] = value;\n \n // Handle parameter updates based on key\n switch (key) {\n case 'centerX':\n if (!this.center) this.center = { x: 0.5, y: 0.5 };\n this.center.x = value;\n console.log(`Updated center.x to ${value}`);\n break;\n \n case 'centerY':\n if (!this.center) this.center = { x: 0.5, y: 0.5 };\n this.center.y = value;\n console.log(`Updated center.y to ${value}`);\n break;\n \n case 'amplitude':\n case 'wavelength':\n case 'speed':\n case 'brightness':\n case 'radius':\n case 'time':\n this[key] = value;\n console.log(`Updated ${key} to ${value}`);\n break;\n \n case 'animating':\n (this as any).animating = value;\n console.log(`Updated animating to ${value}`);\n break;\n \n // For any other properties, try direct assignment \n default:\n if (key in this) {\n (this as any)[key] = value;\n console.log(`Updated ${key} to ${value}`);\n } else {\n console.warn(`Attempted to update unknown property ${key}`);\n }\n break;\n }\n \n return true;\n };\n \n console.log('ShockwaveFilter created successfully with updateUIParam method');\n return filter;\n } catch (error) {\n console.error('Failed to create ShockwaveFilter:', error);\n return null;\n }\n },\n \n // Default parameter values\n defaultParams: {\n centerX: 0.5,\n centerY: 0.5,\n amplitude: 30,\n wavelength: 160,\n speed: 500,\n brightness: 1,\n radius: -1,\n time: 0,\n animating: false\n },\n \n // UI controls for the filter\n controls: [\n {\n id: 'centerX',\n type: 'slider',\n label: 'Center X',\n property: 'centerX',\n min: 0,\n max: 1,\n step: 0.01,\n default: 0.5,\n },\n {\n id: 'centerY',\n type: 'slider',\n label: 'Center Y',\n property: 'centerY',\n min: 0,\n max: 1,\n step: 0.01,\n default: 0.5,\n },\n {\n id: 'amplitude',\n type: 'slider',\n label: 'Amplitude',\n property: 'amplitude',\n min: 0,\n max: 100,\n step: 1,\n default: 30,\n },\n {\n id: 'wavelength',\n type: 'slider',\n label: 'Wavelength',\n property: 'wavelength',\n min: 10,\n max: 500,\n step: 1,\n default: 160,\n },\n {\n id: 'speed',\n type: 'slider',\n label: 'Speed',\n property: 'speed',\n min: 1,\n max: 1000,\n step: 10,\n default: 500,\n },\n {\n id: 'brightness',\n type: 'slider',\n label: 'Brightness',\n property: 'brightness',\n min: 0,\n max: 5,\n step: 0.1,\n default: 1,\n },\n {\n id: 'radius',\n type: 'slider',\n label: 'Max Radius',\n property: 'radius',\n min: -1,\n max: 1000,\n step: 10,\n default: -1,\n },\n {\n id: 'time',\n type: 'slider',\n label: 'Time',\n property: 'time',\n min: 0,\n max: 5,\n step: 0.1,\n default: 0,\n },\n {\n id: 'animating',\n type: 'toggle',\n label: 'Auto Animate',\n property: 'animating',\n default: false,\n }\n ],\n});","/**\n * Simplex Noise Filter Definition\n * Applies procedural noise to create various texture effects\n */\nimport { registerFilter } from '../registry';\n// Import the SimplexNoiseFilter directly from pixi-filters package\n// Import from pixi-filters with wildcard and destructuring pattern\nimport * as PixiFilters from 'pixi-filters';\n// @ts-ignore - Module lacks TypeScript definitions\nconst { SimplexNoiseFilter } = PixiFilters;;\n\nexport default registerFilter({\n id: 'simplex-noise',\n name: 'Simplex Noise',\n category: 'effects',\n description: 'Apply procedural noise to create texture effects',\n \n createFilter: (params) => {\n try {\n console.log('Creating SimplexNoiseFilter with params:', params);\n \n // Use params.time for animation if this is enabled\n const zOffset = params.animating ? 0 : (params.offsetZ || 0);\n \n // Create the filter with direct options\n const filter = new SimplexNoiseFilter({\n strength: params.strength,\n noiseScale: params.noiseScale,\n offsetX: params.offsetX,\n offsetY: params.offsetY,\n offsetZ: zOffset,\n step: params.step\n });\n \n // Store animation state\n (filter as any).animating = params.animating || false;\n (filter as any).animationSpeed = params.animationSpeed || 0.01;\n \n // Store custom params for UI updates\n (filter as any)._customParams = { ...params };\n \n // Set up animation loop for changing the Z offset over time\n let animationFrameId: number | null = null;\n let currentTime = 0;\n \n const animate = () => {\n if ((filter as any).animating) {\n // Update the Z offset over time for animation\n currentTime += (filter as any).animationSpeed;\n filter.offsetZ = currentTime;\n }\n animationFrameId = requestAnimationFrame(animate);\n };\n \n // Start animation if enabled\n if ((filter as any).animating) {\n animationFrameId = requestAnimationFrame(animate);\n }\n \n // Method to clean up animation when filter is destroyed\n (filter as any)._stopAnimation = () => {\n if (animationFrameId !== null) {\n cancelAnimationFrame(animationFrameId);\n animationFrameId = null;\n }\n };\n \n /**\n * Add custom updateUIParam method for UI parameter handling\n */\n (filter as any).updateUIParam = function(key: string, value: any) {\n // Store the updated parameter\n const customParams = (this as any)._customParams || {};\n (this as any)._customParams = customParams;\n customParams[key] = value;\n \n switch (key) {\n case 'animating':\n // Toggle animation state\n (this as any).animating = value;\n if (value && !animationFrameId) {\n // Start animation if not already running\n animationFrameId = requestAnimationFrame(animate);\n }\n break;\n \n case 'animationSpeed':\n // Update animation speed\n (this as any).animationSpeed = value;\n break;\n \n case 'offsetZ':\n // Only update Z offset manually if not animating\n if (!(this as any).animating) {\n this.offsetZ = value;\n }\n break;\n \n case 'randomizeSeed':\n // Randomize all offsets for a new pattern\n if (value) {\n const randomValue = () => Math.random() * 100 - 50;\n this.offsetX = randomValue();\n this.offsetY = randomValue();\n this.offsetZ = randomValue();\n \n // Update stored values\n customParams.offsetX = this.offsetX;\n customParams.offsetY = this.offsetY;\n customParams.offsetZ = this.offsetZ;\n }\n break;\n \n // Direct properties that exist on the filter\n case 'strength':\n case 'noiseScale':\n case 'offsetX':\n case 'offsetY':\n case 'step':\n // Apply with any needed validation\n if (key in this) {\n (this as any)[key] = value;\n }\n break;\n \n default:\n // For any other properties that might exist on the filter\n if (key in this) {\n (this as any)[key] = value;\n }\n break;\n }\n };\n \n return filter;\n } catch (error) {\n console.error('Failed to create SimplexNoiseFilter:', error);\n return null;\n }\n },\n \n defaultParams: {\n strength: 0.5,\n noiseScale: 10.0,\n offsetX: 0,\n offsetY: 0,\n offsetZ: 0,\n step: -1,\n animating: false,\n animationSpeed: 0.01,\n randomizeSeed: false\n },\n \n controls: [\n {\n id: 'strength',\n type: 'slider',\n label: 'Noise Strength',\n property: 'strength',\n min: 0,\n max: 1,\n step: 0.01,\n default: 0.5\n },\n {\n id: 'noiseScale',\n type: 'slider',\n label: 'Noise Scale',\n property: 'noiseScale',\n min: 1,\n max: 50,\n step: 0.5,\n default: 10.0\n },\n {\n id: 'offsetX',\n type: 'slider',\n label: 'X Offset',\n property: 'offsetX',\n min: -50,\n max: 50,\n step: 0.5,\n default: 0\n },\n {\n id: 'offsetY',\n type: 'slider',\n label: 'Y Offset',\n property: 'offsetY',\n min: -50,\n max: 50,\n step: 0.5,\n default: 0\n },\n {\n id: 'offsetZ',\n type: 'slider',\n label: 'Z Offset',\n property: 'offsetZ',\n min: -50,\n max: 50,\n step: 0.5,\n default: 0\n },\n {\n id: 'step',\n type: 'slider',\n label: 'Step Threshold',\n property: 'step',\n min: -1,\n max: 1,\n step: 0.01,\n default: -1,\n tooltip: 'Values above 0 create a blocky effect'\n },\n {\n id: 'animating',\n type: 'toggle',\n label: 'Animate Noise',\n property: 'animating',\n default: false\n },\n {\n id: 'animationSpeed',\n type: 'slider',\n label: 'Animation Speed',\n property: 'animationSpeed',\n min: 0.001,\n max: 0.05,\n step: 0.001,\n default: 0.01\n },\n {\n id: 'randomizeSeed',\n type: 'button',\n label: 'Randomize Pattern',\n action: 'randomizeSeed'\n }\n ]\n});","/**\n * Twist Filter Definition\n * Creates a twisting distortion effect\n *\n * Uses a custom shader implementation that properly handles normalized\n * coordinates (0-1) for center position, making it intuitive to use\n * with sliders.\n */\nimport { registerFilter } from '../registry';\nimport * as PIXI from 'pixi.js';\nimport { GlProgram } from 'pixi.js';\n\n/**\n * Custom Twist Filter with normalized coordinate support\n *\n * Unlike pixi-filters' TwistFilter which expects pixel coordinates,\n * this implementation uses normalized 0-1 coordinates for the center\n * position, making it easier to use with UI sliders.\n */\nclass NormalizedTwistFilter extends PIXI.Filter {\n private _centerX: number = 0.5;\n private _centerY: number = 0.5;\n private _radius: number = 0.25; // Normalized radius (0.25 = 25% of image)\n private _angle: number = 4;\n\n constructor(params?: {\n centerX?: number;\n centerY?: number;\n radius?: number;\n angle?: number;\n }) {\n const glProgram = GlProgram.from({\n vertex: `\n attribute vec2 aPosition;\n varying vec2 vTextureCoord;\n uniform mat3 projectionMatrix;\n\n void main() {\n vTextureCoord = aPosition;\n gl_Position = vec4((projectionMatrix * vec3(aPosition, 1.0)).xy, 0.0, 1.0);\n }\n `,\n fragment: `\n precision mediump float;\n\n varying vec2 vTextureCoord;\n uniform sampler2D uSampler;\n\n uniform vec2 uCenter;\n uniform float uRadius;\n uniform float uAngle;\n\n void main() {\n vec2 coord = vTextureCoord;\n vec2 dir = coord - uCenter;\n float dist = length(dir);\n\n if (dist < uRadius) {\n float percent = (uRadius - dist) / uRadius;\n float theta = percent * percent * uAngle;\n float s = sin(theta);\n float c = cos(theta);\n\n dir = vec2(\n dir.x * c - dir.y * s,\n dir.x * s + dir.y * c\n );\n\n coord = dir + uCenter;\n }\n\n gl_FragColor = texture2D(uSampler, coord);\n }\n `\n });\n\n super({\n glProgram,\n resources: {\n twistUniforms: {\n uCenter: { type: 'vec2<f32>', value: [0.5, 0.5] },\n uRadius: { type: 'f32', value: 0.25 },\n uAngle: { type: 'f32', value: 4 }\n }\n }\n });\n\n // Apply initial parameters\n if (params) {\n if (params.centerX !== undefined) this._centerX = params.centerX;\n if (params.centerY !== undefined) this._centerY = params.centerY;\n if (params.radius !== undefined) this._radius = params.radius;\n if (params.angle !== undefined) this._angle = params.angle;\n }\n\n this._updateUniforms();\n }\n\n private _updateUniforms(): void {\n // @ts-ignore - uniforms access\n if (this.uniforms) {\n // @ts-ignore\n this.uniforms.uCenter = [this._centerX, this._centerY];\n // @ts-ignore\n this.uniforms.uRadius = this._radius;\n // @ts-ignore\n this.uniforms.uAngle = this._angle;\n }\n }\n\n get centerX(): number { return this._centerX; }\n set centerX(value: number) {\n this._centerX = value;\n this._updateUniforms();\n }\n\n get centerY(): number { return this._centerY; }\n set centerY(value: number) {\n this._centerY = value;\n this._updateUniforms();\n }\n\n get radius(): number { return this._radius; }\n set radius(value: number) {\n this._radius = value;\n this._updateUniforms();\n }\n\n get angle(): number { return this._angle; }\n set angle(value: number) {\n this._angle = value;\n this._updateUniforms();\n }\n\n /**\n * Handle UI parameter updates\n */\n updateUIParam(key: string, value: number): void {\n switch (key) {\n case 'centerX':\n this.centerX = value;\n break;\n case 'centerY':\n this.centerY = value;\n break;\n case 'radius':\n this.radius = value;\n break;\n case 'angle':\n this.angle = value;\n break;\n default:\n console.warn(`Unknown parameter '${key}' for TwistFilter`);\n }\n }\n}\n\n// Register the Twist filter\nexport default registerFilter({\n id: 'twist',\n name: 'Twist',\n category: 'distortion',\n description: 'Creates a twisting distortion effect around a central point',\n\n createFilter: (params) => {\n try {\n console.log('Creating TwistFilter with params:', params);\n\n const filter = new NormalizedTwistFilter({\n centerX: params.centerX ?? 0.5,\n centerY: params.centerY ?? 0.5,\n radius: params.radius ?? 0.25,\n angle: params.angle ?? 4\n });\n\n // Store custom parameters for later reference\n (filter as any)._customParams = { ...params };\n\n console.log('TwistFilter created successfully');\n return filter;\n } catch (error) {\n console.error('Failed to create TwistFilter:', error);\n return null;\n }\n },\n\n // Default parameter values - all normalized (0-1) for intuitive slider use\n defaultParams: {\n centerX: 0.5, // Center of image\n centerY: 0.5, // Center of image\n radius: 0.25, // 25% of image size\n angle: 4 // Twist amount in radians\n },\n\n // UI controls for the filter\n controls: [\n {\n id: 'angle',\n type: 'slider',\n label: 'Angle',\n property: 'angle',\n min: -10,\n max: 10,\n step: 0.1,\n default: 4,\n tooltip: 'Amount of twisting (positive is clockwise)'\n },\n {\n id: 'radius',\n type: 'slider',\n label: 'Radius',\n property: 'radius',\n min: 0.05,\n max: 0.75,\n step: 0.01,\n default: 0.25,\n tooltip: 'Size of the twist effect (0-1, relative to image)'\n },\n {\n id: 'centerX',\n type: 'slider',\n label: 'Center X',\n property: 'centerX',\n min: 0,\n max: 1,\n step: 0.01,\n default: 0.5,\n tooltip: 'Horizontal position of twist center'\n },\n {\n id: 'centerY',\n type: 'slider',\n label: 'Center Y',\n property: 'centerY',\n min: 0,\n max: 1,\n step: 0.01,\n default: 0.5,\n tooltip: 'Vertical position of twist center'\n }\n ],\n});\n","/**\n * Vignette Filter Definition\n * Adds a classic darkened border effect to the image\n * \n * NOTE: This is a CUSTOM implementation as pixi-filters does not provide a VignetteFilter.\n * It uses AdjustmentFilter to simulate a vignette effect by manipulating brightness/contrast.\n * This is not a true radial gradient vignette but provides a similar visual effect.\n */\nimport { registerFilter } from '../registry';\n// Import from pixi-filters with wildcard and destructuring pattern\nimport * as PixiFilters from 'pixi-filters';\n// @ts-ignore - Module lacks TypeScript definitions\nconst { AdjustmentFilter } = PixiFilters;;\n\n/**\n * Helper to convert a hex color value to RGB array\n */\nfunction hexToRgb(hex: number | string): number[] {\n const parsedHex = typeof hex === 'string' ? parseInt(hex.replace('#', '0x'), 16) : hex;\n return [\n ((parsedHex >> 16) & 0xFF) / 255,\n ((parsedHex >> 8) & 0xFF) / 255,\n (parsedHex & 0xFF) / 255\n ];\n}\n\n/**\n * Simple Vignette implementation using AdjustmentFilter\n * \n * This approach simulates a vignette effect by manipulating\n * brightness, contrast and color tint - it's not a true vignette\n * but provides a similar visual effect using stable filter mechanisms.\n */\nclass VignetteFilter extends AdjustmentFilter {\n private _radius: number = 0.8;\n private _strength: number = 1.0;\n private _colorRgb: number[] = [0, 0, 0];\n private _colorValue: string = '#000000';\n\n constructor(options: { radius?: number; strength?: number; color?: number | string } = {}) {\n // Initialize with default adjustment values\n super({\n brightness: 1.0,\n contrast: 1.0,\n saturation: 1.0,\n alpha: 1.0\n });\n \n this._radius = options.radius ?? 0.8;\n this._strength = options.strength ?? 1.0;\n \n // Parse color\n if (options.color !== undefined) {\n if (typeof options.color === 'string') {\n this._colorValue = options.color;\n this._colorRgb = hexToRgb(options.color);\n } else {\n this._colorValue = '#' + options.color.toString(16).padStart(6, '0');\n this._colorRgb = hexToRgb(options.color);\n }\n }\n \n // Apply the initial vignette effect\n this.updateVignette();\n }\n \n /**\n * Updates the filter parameters to simulate a vignette effect\n */\n private updateVignette(): void {\n // Calculate effect intensity based on radius and strength\n // Radius inversely affects strength (higher radius = less effect)\n const radiusFactor = 1 - (this._radius / 2); // Normalize to 0.5-1 range\n const effectiveStrength = this._strength * radiusFactor;\n \n // Darker with higher strength (0.5-1.0 range to avoid making everything black)\n this.brightness = Math.max(0.5, 1.0 - effectiveStrength * 0.5);\n \n // Increase contrast slightly with strength to emphasize the vignette\n this.contrast = 1.0 + (effectiveStrength * 0.2);\n \n // Apply a slight tint in the color direction\n if (this._colorRgb[0] > 0 || this._colorRgb[1] > 0 || this._colorRgb[2] > 0) {\n // Tint RGB based on color and strength\n // Since AdjustmentFilter doesn't have direct tint properties,\n // we can't apply a true color tint, but we can adjust\n // saturation to hint at the color\n this.saturation = 1.0 - (effectiveStrength * 0.3);\n }\n }\n\n // Properties with getters/setters\n get radius(): number { return this._radius; }\n set radius(value: number) { \n this._radius = Math.max(0.1, Math.min(1.5, value));\n this.updateVignette();\n }\n\n get strength(): number { return this._strength; }\n set strength(value: number) { \n this._strength = Math.max(0, Math.min(2, value));\n this.updateVignette();\n }\n\n get color(): string { return this._colorValue; }\n set color(value: number | string) { \n if (typeof value === 'string') {\n this._colorValue = value;\n this._colorRgb = hexToRgb(value);\n } else {\n this._colorValue = '#' + value.toString(16).padStart(6, '0');\n this._colorRgb = hexToRgb(value);\n }\n this.updateVignette();\n }\n}\n\nexport default registerFilter({\n id: 'vignette',\n name: 'Vignette',\n category: 'effects',\n description: 'Add a classic darkened border effect to the image',\n \n createFilter: (params) => {\n try {\n console.log('Creating VignetteFilter with params:', params);\n \n // Create the custom VignetteFilter implementation\n const filter = new VignetteFilter({\n radius: params.radius || 0.8,\n strength: params.strength || 1.0,\n color: params.color || '#000000'\n });\n \n // Store custom params for UI updates\n (filter as any)._customParams = { ...params };\n \n // Add custom updateUIParam method for UI parameter handling\n (filter as any).updateUIParam = function(key: string, value: any) {\n // Store the updated parameter\n const customParams = (this as any)._customParams || {};\n (this as any)._customParams = customParams;\n customParams[key] = value;\n \n switch (key) {\n case 'radius':\n // Apply with validation (0.1-1.5 range for visual quality)\n this.radius = Math.max(0.1, Math.min(1.5, value));\n break;\n \n case 'strength':\n // Apply with validation (non-negative)\n this.strength = Math.max(0, value);\n break;\n \n case 'color':\n // Handle color in different formats\n this.color = value;\n // Store the string version for UI if it's a string\n if (typeof value === 'string') {\n customParams.color = value;\n }\n break;\n \n default:\n // For any other properties that might exist directly on the filter\n if (key in this) {\n (this as any)[key] = value;\n }\n break;\n }\n };\n \n return filter;\n } catch (error) {\n console.error('Failed to create VignetteFilter:', error);\n return null;\n }\n },\n \n defaultParams: {\n radius: 0.8,\n strength: 1.0,\n color: '#000000'\n },\n \n controls: [\n {\n id: 'radius',\n type: 'slider',\n label: 'Radius',\n property: 'radius',\n min: 0.1,\n max: 1.5,\n step: 0.01,\n default: 0.8,\n tooltip: 'Size of the vignette effect (larger values create a smaller vignette)'\n },\n {\n id: 'strength',\n type: 'slider',\n label: 'Strength',\n property: 'strength',\n min: 0,\n max: 2,\n step: 0.01,\n default: 1.0,\n tooltip: 'Intensity of the vignette effect'\n },\n {\n id: 'color',\n type: 'color',\n label: 'Color',\n property: 'color',\n default: '#000000',\n tooltip: 'Color of the vignette (usually black)'\n }\n ]\n});","/**\n * Filters Module Index\n * Exports all filter-related functionality\n */\n\n// First import the functions so they exist in this module's scope\nimport {\n registerFilter,\n getFilter,\n getAllFilters,\n getFiltersByCategory,\n getAllCategories,\n hasFilter,\n unregisterFilter,\n getFiltersByMedia,\n isFilterCompatibleWithMedia,\n getRegisteredFilters,\n registerCorePixiFilters,\n} from './registry';\n\n// Then re-export them for downstream consumers\nexport {\n registerFilter,\n getFilter,\n getAllFilters,\n getFiltersByCategory,\n getAllCategories,\n hasFilter,\n unregisterFilter,\n getFiltersByMedia,\n isFilterCompatibleWithMedia,\n getRegisteredFilters,\n registerCorePixiFilters,\n};\nexport type { FilterDefinition, ControlDefinition, FilterMediaTarget } from './registry';\n\n// Re-export from factory\nexport {\n createFilterInstance,\n createFilterInstances,\n updateFilterParams,\n} from './factory';\nexport type { FilterInstanceConfig } from './factory';\n\n// Re-export from controlMapping\nexport {\n mapControlTypeToComponent,\n validateControlValue,\n generateDefaultParams,\n convertControlValue,\n} from './controlMapping';\n\n// Import and re-export all filter definitions\n// This ensures all filters are registered when this module is imported\n\n// Basic adjustments\nimport './definitions/adjustment';\nimport './definitions/adjustmentAdvanced';\nimport './definitions/alpha';\nimport './definitions/blur';\nimport './definitions/colorMatrix';\nimport './definitions/colorOverlay';\nimport './definitions/dropShadow';\nimport './definitions/grayscale';\nimport './definitions/hslAdjustment';\n\n// Blur effects\nimport './definitions/kawaseBlur';\nimport './definitions/motionBlur';\nimport './definitions/radialBlur';\nimport './definitions/tiltShift';\nimport './definitions/zoomBlur';\n\n// Color effects\nimport './definitions/colorGradient';\nimport './definitions/colorMap';\nimport './definitions/colorReplace';\nimport './definitions/multiColorReplace';\nimport './definitions/rgbSplit';\n\n// Stylistic effects\nimport './definitions/advancedBloom';\nimport './definitions/ascii';\nimport './definitions/backdropBlur';\nimport './definitions/bevel';\nimport './definitions/bloom';\nimport './definitions/bulgePinch';\nimport './definitions/convolution';\nimport './definitions/crossHatch';\nimport './definitions/crt';\nimport './definitions/displacement';\nimport './definitions/dot';\nimport './definitions/emboss';\nimport './definitions/glitch';\nimport './definitions/glow';\nimport './definitions/godray';\nimport './definitions/lightmap';\nimport './definitions/noise';\nimport './definitions/oldFilm';\nimport './definitions/outline';\nimport './definitions/pixelate';\nimport './definitions/reflection';\nimport './definitions/shockwave';\nimport './definitions/simplexNoise';\nimport './definitions/twist';\nimport './definitions/vignette';\n\n/**\n * Options for initializeFilterRegistry.\n * @property disabled - Filter IDs to remove from the registry after initialization.\n */\ninterface FilterRegistryOptions {\n disabled?: string[];\n}\n\n/**\n * Initialize the filter registry with all available filters.\n *\n * @param options.disabled - Array of filter IDs to remove after registration\n * (e.g., fetched from the server's mediables.pixi_filters.disabled config).\n */\nexport function initializeFilterRegistry(options?: FilterRegistryOptions) {\n try {\n // Just verify functions exist (they should because of proper imports)\n verifyFilterRegistryFunctions();\n\n // Add explicit type annotations to fix TS7034 errors\n let filters: any[] = [];\n let categories: any[] = [];\n\n // First, try to register core filters\n try {\n // Check if any filters have already been registered\n filters = getAllFilters(); // Now we know this function exists\n\n if (filters.length === 0) {\n // Register core filters if none are registered yet\n console.log('No filters found, registering core filters');\n registerCorePixiFilters(); // Now we know this function exists\n }\n } catch (e) {\n console.warn('Error registering core filters:', e);\n }\n\n // Remove disabled filters from the registry\n const disabled = options?.disabled;\n if (Array.isArray(disabled) && disabled.length > 0) {\n let removedCount = 0;\n for (const id of disabled) {\n if (unregisterFilter(id)) {\n removedCount++;\n }\n }\n if (removedCount > 0) {\n console.log(`Removed ${removedCount} disabled filter(s) from registry`);\n }\n }\n\n // Try to get the filters again after registration\n try {\n filters = getAllFilters();\n categories = getAllCategories(); // Now we know this function exists\n } catch (e) {\n console.warn('Error getting filters or categories:', e);\n // Ensure we have valid defaults even after an error\n if (!filters) filters = [] as any[];\n if (!categories) categories = [] as any[];\n }\n\n // Log the initialization status\n console.log(`Filter registry initialized with ${filters.length} filters in ${categories.length} categories`);\n\n // If we have no filters, log a warning\n if (filters.length === 0) {\n console.warn('No filters found in registry. Filter functionality may be limited.');\n }\n\n return filters as any[];\n } catch (error) {\n // Log the error but don't crash\n console.error('Error initializing filter registry:', error);\n\n // Return an empty array to avoid further errors\n return [];\n }\n}\n\n/**\n * Verify that the required filter registry functions exist\n * This is now just for debugging/validation since we're properly importing the functions\n */\nfunction verifyFilterRegistryFunctions() {\n // Just verify functions exist - they should because of the imports\n const missingFunctions = [];\n \n if (typeof getAllFilters !== 'function') missingFunctions.push('getAllFilters');\n if (typeof getAllCategories !== 'function') missingFunctions.push('getAllCategories');\n if (typeof registerCorePixiFilters !== 'function') missingFunctions.push('registerCorePixiFilters');\n \n if (missingFunctions.length > 0) {\n console.warn(`Warning: Some registry functions are still missing: ${missingFunctions.join(', ')}`);\n }\n}\n\n/**\n * Alternative initialization function with a minimal approach\n * Use this if the main initializeFilterRegistry function is having issues\n */\nexport function safeInitializeFilterRegistry() {\n console.warn('Using minimal safeInitializeFilterRegistry implementation');\n \n try {\n // Verify functions exist but don't create fallbacks\n verifyFilterRegistryFunctions();\n \n // Try to use the getAllFilters function to get any existing filters\n const existingFilters = getAllFilters();\n \n if (existingFilters && existingFilters.length > 0) {\n console.log(`Found ${existingFilters.length} existing filters`);\n return Promise.resolve(existingFilters);\n }\n \n // If no existing filters, try one more attempt with registerCorePixiFilters\n try {\n registerCorePixiFilters();\n const registeredFilters = getAllFilters();\n console.log(`Registered ${registeredFilters.length} core filters`);\n return Promise.resolve(registeredFilters);\n } catch (e) {\n console.warn('Error registering core filters:', e);\n }\n \n // If all else fails, return empty array\n console.warn('Filter functionality will be limited');\n return Promise.resolve([]);\n } catch (e) {\n console.error('Error in safeInitializeFilterRegistry:', e);\n return Promise.resolve([]);\n }\n}\n\n/**\n * Simplified factory for creating a minimal filter\n * Returns a no-op filter that won't cause errors but doesn't do anything\n */\nexport function createMinimalFilter(id: string) {\n console.warn(`Creating minimal placeholder filter for: ${id}`);\n \n // Create a more complete filter stub that matches the expected interface\n return {\n id,\n name: id,\n enabled: true,\n // Basic filter methods\n apply: () => {/* No-op */},\n // Properties needed by the UI\n uniforms: {},\n // Custom interface properties\n updateUIParam: (param: string, value: any) => {\n console.log(`Minimal filter ${id} updateUIParam called with ${param}=${value}`);\n return true;\n },\n handleButtonAction: (action: string) => {\n console.log(`Minimal filter ${id} handleButtonAction called with ${action}`);\n return true;\n },\n // Add any other expected properties based on your filter interface\n // This ensures the minimal filter can be used in place of a real filter\n // without causing errors\n reset: () => {/* No-op */},\n // Clone method for deep copying\n clone: () => createMinimalFilter(id),\n // Allow property access with indexing\n [Symbol.toPrimitive]: () => `[Minimal Filter ${id}]`\n };\n}\n"],"names":["EventEmitter","event","callback","listeners","args","wrapper","State","key","parts","value","part","old","lastKey","target","filterId","enabled","filters","controlId","controls","ctl","prefersDark","createState","PixiRenderer","_a","canvas","_b","w","_d","_c","h","_f","_e","tex","scale","opts","s","desired","z","container","backgroundColor","doMount","PIXI","width","height","imageUrl","img","settledScale","format","quality","maxEdge","dontUpscale","srcW","srcH","targetW","edge","sprite","origX","origY","previewW","previewH","resMultiplier","rt","dataUrl","fallback","ctx","prevCenter","color","url","resolve","REGISTRY_CATEGORY_MAP","FilterManager","state","pixiRenderer","registry","category","registryCategories","seenIds","registryCat","catFilters","filter","path","tokens","obj","i","last","def","values","normalized","inst","failedFilters","id","params","c","f","error","newSprite","_CropManager","aspect","aspectMap","rect","targetAspect","currentAspect","app","shape","bounds","side","cropRect","spriteWidth","spriteHeight","texWidth","texHeight","fitScale","currentZoom","overflowW","overflowH","pad","targetZoom","zoomForW","zoomForH","now","overlay","cv","cssW","cssH","dpr","centerX","centerY","radius","thirdW","thirdH","hs","corners","edges","all","hover","size","px","py","near","ax","ay","bx","by","pos","dx","dy","x","y","stage","prevZoom","scaleX","scaleY","rawTx","rawTy","outW","outH","offsetX","offsetY","src","cx","cy","g","__publicField","CropManager","RemoveBgManager","options","imageData","blob","formData","response","e","errorMessage","errorText","resultBlob","header","data","mimeMatch","mime","binary","array","reject","reader","el","tag","attrs","children","element","child","createSlider","label","min","max","step","onChange","formatValue","input","val","display","createToggle","checked","labelEl","toggle","slider","createColorPicker","createSelect","select","opt","option","createButton","className","onClick","icon","disabled","button","iconEl","svg","createIconButton","title","testId","ariaLabel","createChip","active","chip","isActive","chevronLeft","chevronRight","zoomIn","zoomOut","expand","settings","water","colorPalette","sparkles","move","flash","crop","save","close","refresh","trash","openFolder","checkmark","square","circle","freeform","sunny","moon","film","Toolbar","editor","leftSection","openBtn","icons.openFolder","centerSection","zoomOutBtn","icons.zoomOut","current","zoomInBtn","icons.zoomIn","fitBtn","icons.expand","rightSection","icons.sunny","icons.moon","icons.crop","resetBtn","icons.refresh","saveBtn","icons.save","closeBtn","icons.close","unsubZoom","unsubTheme","unsubMode","zoom","unsub","CATEGORIES","icons.settings","icons.water","icons.colorPalette","icons.sparkles","icons.move","icons.flash","icons.film","CategoryCarousel","onSelect","icons.chevronLeft","cat","icons.chevronRight","pageCount","dot","categoryId","pageIndex","itemWidth","dots","activePage","FilterCarousel","filterManager","onToggle","unsubCat","unsubActive","unsubSelected","activeFilters","selectedFilter","card","isSelected","preview","previewText","name","willBeActive","icons.checkmark","maxIndex","FilterAdjustments","onReset","onAction","unsubValues","grid","controlEl","type","action","MobileFilterDrawer","onRemove","headerActions","removeBtn","MobileActiveFilters","placeholder","check","SHAPES","icons.freeform","icons.square","icons.circle","ASPECT_RATIOS","CropControls","cropManager","shapeSection","shapeRow","currentShape","aspectRow","actionRow","cancelBtn","applyBtn","unsubShape","unsubAspect","shapeId","aspectId","lockAspect","ActiveFiltersPanel","onClearAll","onUpdateValue","clearAllBtn","item","headerRow","actions","icons.trash","summaryEl","controlType","DEFAULT_PRESET","PRESETS","getPreset","preset","found","VanillaImageEditor","resolvedPreset","presetOverrides","toolbarContainer","content","canvasSection","filterLayout","leftColumn","rightColumn","resizeTimer","mode","file","instance","imageSource","dimensions","link","isDark","theme","result","message","textEl","_g","_h","_i","_j","categories","isMediaCompatible","definition","registerFilter","getFilter","getAllFilters","registerCorePixiFilters","PixiFilters","entry","exportName","FilterClass","getFiltersByCategory","getAllCategories","hasFilter","unregisterFilter","categoryIds","idx","isFilterCompatibleWithMedia","getRegisteredFilters","originalRegisterFilter","AdjustmentFilter","ColorMatrixFilter","DEFAULT_ADJUSTMENT_PARAMS","ADJUSTMENT_PARAM_KEYS","toFiniteNumber","parsed","isAdjustmentParamKey","normalizeAdjustmentParams","applyColorMatrixAdjustments","normalizedParams","filterWithUI","customParams","numericValue","DEFAULT_ADVANCED_ADJUSTMENT_PARAMS","ADVANCED_ADJUSTMENT_PARAM_KEYS","isAdvancedAdjustmentParamKey","toBoolean","normalizeAdvancedAdjustmentParams","applyAdvancedAdjustments","numericKey","alpha","numValue","MatrixFilterClass","ColorOverlayFilter","colorValue","colorNum","distance","angle","offset","newOffset","intensity","applyGrayscaleEffect","HslAdjustmentFilter","KawaseBlurFilter","MotionBlurFilter","RadialBlurFilter","TiltShiftFilter","blur","gradientBlur","startX","startY","endX","endY","ZoomBlurFilter","ColorGradientFilter","stops","stop","a","b","colorStops","index","currentStopsForAdd","newColorStop","r","currentStopsForRemove","tempFilter","processedStops","match","_","indexStr","prop","updatedStops","ColorMapFilterClass","colorMapTexture","ColorReplaceFilter","originalColorValue","targetColorValue","MultiColorReplaceFilter","replacements","original","newReplacements","RGBSplitFilter","red","green","blue","AdvancedBloomFilter","AsciiFilter","replaceColor","BackdropBlurFilter","kernelSize","BevelFilter","lightColor","shadowColor","BloomFilter","strengthX","strengthY","resolution","BulgePinchFilter","strength","ConvolutionFilter","MATRICES","matrix","presetKey","currentMatrix","newMatrix","CrossHatchFilter","_params","DisplacementFilter","Sprite","Texture","mapUrl","mapTexture","j","displacementSprite","newTexture","EmbossFilter","GlitchFilter","FILL_MODES","redOffset","greenOffset","blueOffset","animationFrameId","animate","GlowFilter","GodrayFilter","SimpleLightmapFilter","textureType","alphaValue","gradient","lightMapTexture","updateCanvas","updateCtx","wasEnabled","NoiseFilter","OldFilmFilter","OutlineFilter","PixelateFilter","avgSize","currentSize","ReflectionFilter","ShockwaveFilter","center","amplitude","wavelength","speed","brightness","time","SimplexNoiseFilter","zOffset","currentTime","randomValue","NormalizedTwistFilter","glProgram","GlProgram","hexToRgb","hex","parsedHex","VignetteFilter","radiusFactor","effectiveStrength","initializeFilterRegistry","removedCount"],"mappings":"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"}